@excalidraw/excalidraw 0.12.0-5598-9f325a6 → 0.12.0-5598-d731a64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2029,7 +2029,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2029
2029
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2030
2030
 
2031
2031
  "use strict";
2032
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nvar _a, _b;\nconst trackEvent = typeof process !== \"undefined\" &&\n ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.REACT_APP_GOOGLE_ANALYTICS_ID) &&\n typeof window !== \"undefined\" &&\n window.gtag\n ? (category, action, label, value) => {\n try {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n catch (error) {\n console.error(\"error logging to ga\", error);\n }\n }\n : typeof process !== \"undefined\" && ((_b = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _b === void 0 ? void 0 : _b.JEST_WORKER_ID)\n ? (category, action, label, value) => { }\n : (category, action, label, value) => {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQU8sTUFBTSxVQUFVLEdBQ3JCLE9BQU8sT0FBTyxLQUFLLFdBQVc7S0FDOUIsczRCQUFXLDBDQUFFLDZCQUE2QjtJQUMxQyxPQUFPLE1BQU0sS0FBSyxXQUFXO0lBQzdCLE1BQU0sQ0FBQyxJQUFJO0lBQ1QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFO1FBQ25FLElBQUk7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzdDO0lBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxPQUFPLE9BQU8sS0FBSyxXQUFXLEtBQUksczRCQUFXLDBDQUFFLGNBQWM7UUFDL0QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFLEdBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQyxRQUFnQixFQUFFLE1BQWMsRUFBRSxLQUFjLEVBQUUsS0FBYyxFQUFFLEVBQUU7WUFDbkUsMkNBQTJDO1lBQzNDLGtFQUFrRTtRQUNwRSxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vYW5hbHl0aWNzLnRzPzVmMGMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHRyYWNrRXZlbnQgPVxuICB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICBwcm9jZXNzLmVudj8uUkVBQ1RfQVBQX0dPT0dMRV9BTkFMWVRJQ1NfSUQgJiZcbiAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICB3aW5kb3cuZ3RhZ1xuICAgID8gKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB3aW5kb3cuZ3RhZyhcImV2ZW50XCIsIGFjdGlvbiwge1xuICAgICAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgZXZlbnRfbGFiZWw6IGxhYmVsLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIGxvZ2dpbmcgdG8gZ2FcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgOiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudj8uSkVTVF9XT1JLRVJfSURcbiAgICA/IChjYXRlZ29yeTogc3RyaW5nLCBhY3Rpb246IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHZhbHVlPzogbnVtYmVyKSA9PiB7fVxuICAgIDogKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRyYWNrIEV2ZW50XCIsIHsgY2F0ZWdvcnksIGFjdGlvbiwgbGFiZWwsIHZhbHVlIH0pO1xuICAgICAgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2032
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"trackEvent\": () => (/* binding */ trackEvent)\n/* harmony export */ });\nvar _a, _b;\nconst trackEvent = typeof process !== \"undefined\" &&\n ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.REACT_APP_GOOGLE_ANALYTICS_ID) &&\n typeof window !== \"undefined\" &&\n window.gtag\n ? (category, action, label, value) => {\n try {\n window.gtag(\"event\", action, {\n event_category: category,\n event_label: label,\n value,\n });\n }\n catch (error) {\n console.error(\"error logging to ga\", error);\n }\n }\n : typeof process !== \"undefined\" && ((_b = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _b === void 0 ? void 0 : _b.JEST_WORKER_ID)\n ? (category, action, label, value) => { }\n : (category, action, label, value) => {\n // Uncomment the next line to track locally\n // console.log(\"Track Event\", { category, action, label, value });\n };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vYW5hbHl0aWNzLnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQU8sTUFBTSxVQUFVLEdBQ3JCLE9BQU8sT0FBTyxLQUFLLFdBQVc7S0FDOUIsczRCQUFXLDBDQUFFLDZCQUE2QjtJQUMxQyxPQUFPLE1BQU0sS0FBSyxXQUFXO0lBQzdCLE1BQU0sQ0FBQyxJQUFJO0lBQ1QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFO1FBQ25FLElBQUk7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7Z0JBQzNCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixXQUFXLEVBQUUsS0FBSztnQkFDbEIsS0FBSzthQUNOLENBQUMsQ0FBQztTQUNKO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzdDO0lBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxPQUFPLE9BQU8sS0FBSyxXQUFXLEtBQUksczRCQUFXLDBDQUFFLGNBQWM7UUFDL0QsQ0FBQyxDQUFDLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxFQUFFLEdBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQyxRQUFnQixFQUFFLE1BQWMsRUFBRSxLQUFjLEVBQUUsS0FBYyxFQUFFLEVBQUU7WUFDbkUsMkNBQTJDO1lBQzNDLGtFQUFrRTtRQUNwRSxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vYW5hbHl0aWNzLnRzPzVmMGMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHRyYWNrRXZlbnQgPVxuICB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICBwcm9jZXNzLmVudj8uUkVBQ1RfQVBQX0dPT0dMRV9BTkFMWVRJQ1NfSUQgJiZcbiAgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICB3aW5kb3cuZ3RhZ1xuICAgID8gKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB3aW5kb3cuZ3RhZyhcImV2ZW50XCIsIGFjdGlvbiwge1xuICAgICAgICAgICAgZXZlbnRfY2F0ZWdvcnk6IGNhdGVnb3J5LFxuICAgICAgICAgICAgZXZlbnRfbGFiZWw6IGxhYmVsLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIGxvZ2dpbmcgdG8gZ2FcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgOiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudj8uSkVTVF9XT1JLRVJfSURcbiAgICA/IChjYXRlZ29yeTogc3RyaW5nLCBhY3Rpb246IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHZhbHVlPzogbnVtYmVyKSA9PiB7fVxuICAgIDogKGNhdGVnb3J5OiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nLCBsYWJlbD86IHN0cmluZywgdmFsdWU/OiBudW1iZXIpID0+IHtcbiAgICAgICAgLy8gVW5jb21tZW50IHRoZSBuZXh0IGxpbmUgdG8gdHJhY2sgbG9jYWxseVxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRyYWNrIEV2ZW50XCIsIHsgY2F0ZWdvcnksIGFjdGlvbiwgbGFiZWwsIHZhbHVlIH0pO1xuICAgICAgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../analytics.ts\n");
2033
2033
 
2034
2034
  /***/ }),
2035
2035
 
@@ -2117,7 +2117,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2117
2117
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2118
2118
 
2119
2119
  "use strict";
2120
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../renderer/renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet cursorX = 0;\nlet cursorY = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = { horizontal: null, vertical: null };\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n// remove this hack when we can sync render & resizeObserver (state update)\n// to rAF. See #5439\nlet THROTTLE_NEXT_RENDER = true;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null,\n};\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n super(props);\n this.canvas = null;\n this.rc = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.lastPointerDown = null;\n this.lastPointerUp = null;\n this.contextMenuOpen = false;\n this.lastScenePointer = null;\n this.__renderUI = true;\n this.focusContainer = () => {\n var _a;\n if (this.props.autoFocus) {\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n }\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f;\n // Since context menu closes when action triggered so setting to false\n this.contextMenuOpen = false;\n if (this.unmounted || actionResult === false) {\n return;\n }\n let editingElement = null;\n if (actionResult.elements) {\n actionResult.elements.forEach((element) => {\n var _a;\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\n this.state.editingElement !== element &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n if (actionResult.files) {\n this.files = actionResult.replaceFiles\n ? actionResult.files\n : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n if (actionResult.appState || editingElement) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n let theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n if (typeof this.props.theme !== \"undefined\") {\n theme = this.props.theme;\n }\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n this.setState((state) => {\n var _a;\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n });\n // Lifecycle\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({ isBindingEnabled: true });\n });\n this.onUnload = () => {\n this.onBlur();\n };\n this.disableEvent = (event) => {\n event.preventDefault();\n };\n this.onFontLoaded = () => {\n this.scene.getElementsIncludingDeleted().forEach((element) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.onSceneUpdated();\n };\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\n * Resets scene & history.\n * ! Do not use to clear scene user action !\n */\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\n this.scene.replaceAllElements([]);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\n this.resetHistory();\n });\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\n var _b;\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\n if (!launchParams.files.length) {\n return;\n }\n const fileHandle = launchParams.files[0];\n const blob = yield fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", { type: blob.type }), fileHandle);\n }));\n }\n if (!this.state.isLoading) {\n this.setState({ isLoading: true });\n }\n let initialData = null;\n try {\n initialData = (yield this.props.initialData) || null;\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library\n .updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true,\n })\n .catch((error) => {\n console.error(error);\n });\n }\n }\n catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message ||\n \"Encountered an error during importing or restoring scene data\",\n },\n };\n }\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\n scene.appState = Object.assign(Object.assign({}, scene.appState), { \n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n isLibraryOpen: ((_b = initialData === null || initialData === void 0 ? void 0 : initialData.appState) === null || _b === void 0 ? void 0 : _b.isLibraryOpen) || this.state.isLibraryOpen, activeTool: scene.appState.activeTool.type === \"image\"\n ? Object.assign(Object.assign({}, scene.appState.activeTool), { type: \"selection\" }) : scene.appState.activeTool, isLoading: false, toast: this.state.toast });\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), { width: this.state.width, height: this.state.height, offsetTop: this.state.offsetTop, offsetLeft: this.state.offsetLeft }), null));\n }\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\n });\n this.refreshDeviceState = (container) => {\n const { width, height } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT ||\n (height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint,\n });\n };\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n this.scene\n .getElementsIncludingDeleted()\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\n this.setState({});\n });\n this.renderScene = () => {\n const cursorButton = {};\n const pointerViewportCoords = {};\n const remoteSelectedElementIds = {};\n const pointerUsernames = {};\n const pointerUserStates = {};\n this.state.collaborators.forEach((user, socketId) => {\n if (user.selectedElementIds) {\n for (const id of Object.keys(user.selectedElementIds)) {\n if (!(id in remoteSelectedElementIds)) {\n remoteSelectedElementIds[id] = [];\n }\n remoteSelectedElementIds[id].push(socketId);\n }\n }\n if (!user.pointer) {\n return;\n }\n if (user.username) {\n pointerUsernames[socketId] = user.username;\n }\n if (user.userState) {\n pointerUserStates[socketId] = user.userState;\n }\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: user.pointer.x,\n sceneY: user.pointer.y,\n }, this.state);\n cursorButton[socketId] = user.button;\n });\n const renderingElements = this.scene\n .getNonDeletedElements()\n .filter((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\n if (\n // not placed on canvas yet (but in elements array)\n this.state.pendingImageElementId === element.id) {\n return false;\n }\n }\n // don't render text element that's being currently edited (it's\n // rendered on remote only)\n return (!this.state.editingElement ||\n this.state.editingElement.type !== \"text\" ||\n element.id !== this.state.editingElement.id);\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)({\n elements: renderingElements,\n appState: this.state,\n scale: window.devicePixelRatio,\n rc: this.rc,\n canvas: this.canvas,\n renderConfig: {\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n viewBackgroundColor: this.state.viewBackgroundColor,\n zoom: this.state.zoom,\n remotePointerViewportCoords: pointerViewportCoords,\n remotePointerButton: cursorButton,\n remoteSelectedElementIds,\n remotePointerUsernames: pointerUsernames,\n remotePointerUserStates: pointerUserStates,\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\n theme: this.state.theme,\n imageCache: this.imageCache,\n isExporting: false,\n renderScrollbars: !this.device.isMobile,\n },\n callback: ({ atLeastOneVisibleElement, scrollBars }) => {\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n const scrolledOutside = \n // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? false\n : !atLeastOneVisibleElement && renderingElements.length > 0;\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({ scrolledOutside });\n }\n this.scheduleImageRefresh();\n },\n }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\n };\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\n this.setState((state) => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n return { offsetTop, offsetLeft };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT);\n // Copy/paste\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n this.onTapStart = (event) => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_keys__WEBPACK_IMPORTED_MODULE_26__.isAndroid) {\n event.preventDefault();\n }\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n }\n // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n if (didTapTwice && event.touches.length === 1) {\n const [touch] = event.touches;\n // @ts-ignore\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY,\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n if (_keys__WEBPACK_IMPORTED_MODULE_26__.isAndroid) {\n event.preventDefault();\n }\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: {},\n });\n }\n };\n this.onTapEnd = (event) => {\n this.resetContextMenuTimer();\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n else {\n gesture.pointers.clear();\n }\n };\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\n var _c, _d;\n // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (!isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\n // thus these checks don't make sense\n event &&\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\n return;\n }\n // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n let file = (_d = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _d === void 0 ? void 0 : _d.files[0];\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event);\n if (!file && data.text) {\n const string = data.text.trim();\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n // prefer spreadsheet data over image file (MS Office/Libre Office)\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n if (this.props.onPaste) {\n try {\n if ((yield this.props.onPaste(data, event)) === false) {\n return;\n }\n }\n catch (error) {\n console.error(error);\n }\n }\n if (data.errorMessage) {\n this.setState({ errorMessage: data.errorMessage });\n }\n else if (data.spreadsheet) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text);\n }\n this.setActiveTool({ type: \"selection\" });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n }));\n this.addElementsFromPasteOrLibrary = (opts) => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\"\n ? opts.position.clientX\n : opts.position === \"cursor\"\n ? cursorX\n : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\"\n ? opts.position.clientY\n : opts.position === \"cursor\"\n ? cursorY\n : this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const groupIdMap = new Map();\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const oldIdToDuplicatedId = new Map();\n const newElements = elements.map((element) => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n return newElement;\n });\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.scene.replaceAllElements(nextElements);\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: this.state.isLibraryOpen && this.device.canDeviceFitSidebar\n ? this.state.isLibraryMenuDocked\n : false, selectedElementIds: newElements.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n return acc;\n }, {}), selectedGroupIds: {} }), this.scene.getNonDeletedElements()), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({ type: \"selection\" });\n };\n // Collaboration\n this.setAppState = (obj) => {\n this.setState(obj);\n };\n this.removePointer = (event) => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n gesture.pointers.delete(event.pointerId);\n };\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setState((prevState) => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, prevState.activeTool.locked\n ? { type: \"selection\" }\n : prevState.activeTool)), { locked: !prevState.activeTool.locked }),\n };\n });\n };\n this.togglePenMode = () => {\n this.setState((prevState) => {\n return {\n penMode: !prevState.penMode,\n };\n });\n };\n this.scrollToContent = (target = this.scene.getNonDeletedElements()) => {\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\n };\n this.setToast = (toast) => {\n this.setState({ toast });\n };\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\n try {\n const webShareTargetCache = yield caches.open(\"web-share-target\");\n const response = yield webShareTargetCache.match(\"shared-file\");\n if (response) {\n const blob = yield response.blob();\n const file = new File([blob], blob.name || \"\", { type: blob.type });\n this.loadFileToCanvas(file, null);\n yield webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n });\n /** adds supplied files to existing files in the appState */\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n });\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n if (sceneData.collaborators) {\n this.setState({ collaborators: sceneData.collaborators });\n }\n });\n this.onSceneUpdated = () => {\n this.setState({});\n };\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n cursorX = event.clientX;\n cursorY = event.clientY;\n });\n // Input handling\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window &&\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n return prop === \"key\"\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey\n ? ev.key.toUpperCase()\n : ev.key.toLowerCase()\n : value;\n },\n });\n }\n // prevent browser zoom in input fields\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n }\n // bail if\n if (\n // inside an input\n ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) &&\n // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\n // or unless using arrows (to move between buttons)\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n showHelpDialog: true,\n });\n }\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n if (this.state.viewModeEnabled) {\n return;\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: false });\n }\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\n const nextState = !this.state.isLibraryOpen;\n this.setState({ isLibraryOpen: nextState });\n // track only openings\n if (nextState) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"library\", \"toggleLibrary (open)\", `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = (this.state.gridSize &&\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT\n : this.state.gridSize)) ||\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\n let offsetX = 0;\n let offsetY = 0;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n selectedElements.forEach((element) => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY,\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements,\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !==\n selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n }\n }\n else {\n const selectedElement = selectedElements[0];\n this.startTextEditing({\n sceneX: selectedElement.x + selectedElement.width / 2,\n sceneY: selectedElement.y + selectedElement.height / 2,\n shouldBind: true,\n });\n event.preventDefault();\n return;\n }\n }\n }\n else if (!event.ctrlKey &&\n !event.altKey &&\n !event.metaKey &&\n this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setActiveTool({ type: shape });\n event.stopPropagation();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n event.preventDefault();\n }\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) &&\n !event.altKey &&\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (this.state.activeTool.type === \"selection\" &&\n !selectedElements.length) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.activeTool.type) ||\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\n this.setState({ openPopup: \"backgroundColorPicker\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"strokeColorPicker\" });\n event.stopPropagation();\n }\n }\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (this.state.activeTool.type === \"selection\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n isHoldingSpace = false;\n }\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: true });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({ suggestedBindings: [] });\n }\n });\n this.setActiveTool = (tool) => {\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, tool);\n if (!isHoldingSpace) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({ suggestedBindings: [] });\n }\n if (nextActiveTool.type === \"image\") {\n this.onImageAction();\n }\n if (nextActiveTool.type !== \"selection\") {\n this.setState({\n activeTool: nextActiveTool,\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n else {\n this.setState({ activeTool: nextActiveTool });\n }\n };\n this.setCursor = (cursor) => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, cursor);\n };\n this.resetCursor = () => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n };\n /**\n * returns whether user is making a gesture with >= 2 fingers (points)\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\n * GestureEvent is standardized.\n */\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n };\n // fires only on Safari\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: {},\n });\n }\n gesture.initialScale = this.state.zoom.value;\n });\n // fires only on Safari\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n const initialScale = gesture.initialScale;\n if (initialScale) {\n this.setState((state) => (Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale),\n }, state))));\n }\n });\n // fires only on Safari\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // reselect elements only on touch screens (see onGestureStart)\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n gesture.initialScale = null;\n });\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\n var _a, _b;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n let existingTextElement = null;\n let container = null;\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(selectedElements[0], false)) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n // bind to container when shouldBind is true or\n // clicked on center of container\n if (!container &&\n !existingTextElement &&\n (shouldBind || parentCenterPosition)) {\n container = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getNonDeletedElements()\n .filter((ele) => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(ele, false) && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(ele)), sceneX, sceneY);\n }\n if (!existingTextElement && container) {\n const fontString = {\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n }\n }\n const element = existingTextElement\n ? existingTextElement\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition\n ? parentCenterPosition.elementCenterX\n : sceneX,\n y: parentCenterPosition\n ? parentCenterPosition.elementCenterY\n : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n text: \"\",\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: parentCenterPosition\n ? \"center\"\n : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE\n : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\n groupIds: (_b = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _b !== void 0 ? _b : [],\n locked: false,\n });\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n // case: creating new text not centered to parent element → offset Y\n // so that the text is centered to cursor position\n if (!parentCenterPosition) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n y: element.y - element.baseline / 2,\n });\n }\n }\n this.setState({\n editingElement: element,\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement,\n });\n };\n this.handleCanvasDoubleClick = (event) => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n // we should only be able to double click when mode is selection\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n }\n return;\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n if (selectedGroupId) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { editingGroupId: selectedGroupId, selectedElementIds: { [hitElement.id]: true }, selectedGroupIds: {} }), this.scene.getNonDeletedElements()));\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\n if (canBindText) {\n sceneX = selectedElement.x + selectedElement.width / 2;\n sceneY = selectedElement.y + selectedElement.height / 2;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\n });\n }\n };\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n return (element.link &&\n index <= hitElementIndex &&\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile));\n });\n };\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (!this.hitLinkElement ||\n // For touch screen allow dragging threshold else strict check\n (isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) ||\n (!isTouchScreen && draggedDistance !== 0)) {\n return;\n }\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerDown, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerUp, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n const url = this.hitLinkElement.link;\n if (url) {\n let customEvent;\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(this.hitLinkElement, customEvent);\n }\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target);\n // https://mathiasbynens.github.io/rel-noopener/\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.normalizeLink)(url);\n }\n }\n }\n }\n };\n this.handleCanvasPointerMove = (event) => {\n var _a;\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n }\n const initialScale = gesture.initialScale;\n if (gesture.pointers.size === 2 &&\n gesture.lastCenter &&\n initialScale &&\n gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = this.state.activeTool.type === \"freedraw\" && this.state.penMode\n ? 1\n : distance / gesture.initialDistance;\n const nextZoom = scaleFactor\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor)\n : this.state.zoom.value;\n this.setState((state) => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom,\n }, state);\n return {\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true,\n };\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n }\n else {\n gesture.lastCenter =\n gesture.initialDistance =\n gesture.initialScale =\n null;\n }\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\n return;\n }\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\n if (editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({ editingLinearElement });\n });\n }\n if (editingLinearElement.lastUncommittedPoint != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n this.setState({ suggestedBindings: [] });\n }\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const { draggingElement } = this.state;\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n }\n else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n const { x: rx, y: ry } = multiElement;\n const { points, lastCommittedPoint } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\n });\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n }\n else if (points.length > 2 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1),\n });\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(scenePointerX, scenePointerY, this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({ width: dxFromLastCommitted, height: dyFromLastCommitted } =\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(\n // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, \n // cursor-grid coordinate\n gridX, gridY));\n }\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n // update last uncommitted point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [\n ...points.slice(0, -1),\n [\n lastCommittedX + dxFromLastCommitted,\n lastCommittedY + dyFromLastCommitted,\n ],\n ],\n });\n }\n return;\n }\n const hasDeselectedButton = Boolean(event.buttons);\n if (hasDeselectedButton ||\n (this.state.activeTool.type !== \"selection\" &&\n this.state.activeTool.type !== \"text\" &&\n this.state.activeTool.type !== \"eraser\")) {\n return;\n }\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 &&\n !isOverScrollBar &&\n !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType &&\n elementWithTransformHandleType.transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n }\n else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType,\n }));\n return;\n }\n }\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n }\n else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.hideHyperlinkToolip)();\n if (hitElement &&\n hitElement.link &&\n this.state.selectedElementIds[hitElement.id] &&\n !this.contextMenuOpen &&\n !this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: \"info\" });\n }\n else if (this.state.activeTool.type === \"text\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n else if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n }\n else if (\n // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (hitElement ||\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) &&\n !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = (elements) => {\n elements.forEach((element) => {\n if (element.locked) {\n return;\n }\n idsToUpdate.push(element.id);\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] &&\n pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n }\n else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity,\n };\n }\n });\n };\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements);\n // Exit since we reached current point\n if (samplingInterval === distance) {\n break;\n }\n // Calculate next point in the line at a distance of sampling interval\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId)\n ? ele.containerId\n : ele.id;\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] &&\n pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity,\n });\n }\n }\n else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY,\n });\n }\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n };\n // set touch moving for mobile context menu\n this.handleTouchMove = (event) => {\n invalidateContextMenu = true;\n };\n this.handleCanvasPointerDown = (event) => {\n var _a, _b;\n // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n const selection = document.getSelection();\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event);\n //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState((prevState) => {\n return {\n penMode: true,\n penDetected: true,\n };\n });\n }\n if (!this.device.isTouchScreen &&\n [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, { isTouchScreen: true });\n }\n if (isPanning) {\n return;\n }\n this.lastPointerDown = event;\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\",\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n this.updateGestureOnPointerDown(event);\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n // only handle left mouse button or touch\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN &&\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n }\n // don't select while panning\n if (gesture.pointers.size > 1) {\n return;\n }\n // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n const pointerDownState = this.initialPointerDownState(event);\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n // Since context menu closes on pointer down so setting to false\n this.contextMenuOpen = false;\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n const allowOnPointerDown = !this.state.penMode ||\n event.pointerType !== \"touch\" ||\n this.state.activeTool.type === \"selection\" ||\n this.state.activeTool.type === \"text\" ||\n this.state.activeTool.type === \"image\";\n if (!allowOnPointerDown) {\n return;\n }\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n }\n else if (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n // retrieve the latest element as the state may be stale\n const pendingImageElement = this.state.pendingImageElementId &&\n this.scene.getElement(this.state.pendingImageElementId);\n if (!pendingImageElement) {\n return;\n }\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null,\n });\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y,\n });\n }\n else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"custom\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.activeTool.type !== \"eraser\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n if (!this.state.viewModeEnabled) {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n this.handleCanvasPointerUp = (event) => {\n this.lastPointerUp = event;\n if (this.device.isTouchScreen) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: event.clientX, clientY: event.clientY }, this.state);\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n this.removePointer(event);\n };\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n }\n else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n };\n // Returns whether the event is a panning\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\n if (!(gesture.pointers.size <= 1 &&\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL ||\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\n this.state.viewModeEnabled)) ||\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let { clientX: lastX, clientY: lastY } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\n * Prevent paste event if we move while middle clicking on Linux.\n * See issue #1383.\n */\n if (isLinux &&\n !nextPastePrevented &&\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n const preventNextPaste = (event) => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\n * Reenable next paste in case of disabled middle click paste for\n * any reason:\n * - right click paste\n * - empty clipboard\n */\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n this.setState({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n }));\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true,\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n };\n /**\n * @returns whether the pointer event has been completely handled\n */\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element,\n });\n pointerDownState.resize.handleType =\n elementWithTransformHandleType.transformHandleType;\n }\n }\n else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n if (pointerDownState.resize.handleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType: pointerDownState.resize.handleType,\n }));\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n if (selectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\n selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n }\n else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n if (ret.linearElementEditor) {\n this.setState({ selectedLinearElement: ret.linearElementEditor });\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: ret.linearElementEditor });\n }\n }\n if (ret.didAddPoint && !ret.isMidPoint) {\n return true;\n }\n }\n // hitElement may already be set above, so check first\n pointerDownState.hit.element =\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y,\n }, pointerDownState.hit.element);\n if (hitLinkElement) {\n return false;\n }\n }\n // For overlapped elements one position may hit\n // multiple elements\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n if ((hitElement === null || !someHitElementIsSelected) &&\n !event.shiftKey &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: {\n [this.state.editingLinearElement.elementId]: true,\n },\n });\n // If we click on something\n }\n else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\n // mark as not completely handled so as to allow dragging etc.\n return false;\n }\n // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId &&\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n if (!someHitElementIsSelected &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState((prevState) => {\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }), showHyperlinkPopup: hitElement.link ? \"info\" : false }), this.scene.getNonDeletedElements());\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n }\n return false;\n };\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true,\n });\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\n if (canBindText) {\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n };\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n simulatePressure: event.pressure === 0.5,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n const pressures = element.simulatePressure\n ? element.pressures\n : [...element.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures,\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n };\n this.createImageElement = ({ sceneX, sceneY, }) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n locked: false,\n });\n return element;\n };\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n // finalize if completing a loop\n if (multiElement.type === \"line\" &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\n // clicking inside commit zone → finalize arrow\n if (multiElement.points.length > 1 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\n }));\n // clicking outside commit zone → update reference for last committed\n // point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\n an arrow, we want it to be null for both. Otherwise, we want it to use the\n values from appState. */\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\n : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n startArrowhead,\n endArrowhead,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]],\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n }\n };\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n locked: false,\n });\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element,\n });\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element,\n });\n }\n };\n this.restoreReadyToEraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity,\n });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity,\n });\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n this.eraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\n var _e, _f, _g, _h;\n // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n const mimeType = imageFile.type;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(yield imageFile.text()), imageFile.name);\n }\n catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n }\n // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n const fileId = yield (((_f = (_e = this.props).generateIdForFile) === null || _f === void 0 ? void 0 : _f.call(_e, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n const existingFileData = this.files[fileId];\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\n });\n }\n catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\n }));\n }\n }\n if (showCursorImagePreview) {\n const dataURL = (_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL;\n // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n const dataURL = ((_h = this.files[fileId]) === null || _h === void 0 ? void 0 : _h.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId,\n }, false);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n var _j;\n try {\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n } });\n const cachedImageData = this.imageCache.get(fileId);\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n yield this.updateImageCache([imageElement]);\n }\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n yield cachedImageData.image;\n }\n if (this.state.pendingImageElementId !== imageElement.id &&\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n resolve(imageElement);\n }\n catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n }\n finally {\n if (!showCursorImagePreview) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n }\n }));\n });\n /**\n * inserts image into elements array and rerenders\n */\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n imageElement,\n ]);\n try {\n yield this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview,\n });\n }\n catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true,\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\n });\n }\n });\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx,\n });\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview);\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n if (this.state.pendingImageElementId) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\n }\n });\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y,\n });\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: { [imageElement.id]: true },\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n else {\n this.setState({\n pendingImageElementId: imageElement.id,\n }, () => {\n this.insertImageElement(imageElement, imageFile, \n /* showCursorImagePreview */ true);\n });\n }\n }\n catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n }\n else {\n console.warn(error);\n }\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n });\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize,\n });\n }\n return;\n }\n if (forceNaturalSize ||\n // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\n const minHeight = Math.max(this.state.height - 120, 160);\n // max 65% of canvas height, clamped to <300px, vh - 120px>\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight);\n // add current imageElement width/height to account for previous centering\n // of the placeholder image\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\n to error for images that fail during <img> element creation */\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map((element) => element.fileId),\n files,\n });\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n }\n }\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\",\n });\n }\n return element;\n }));\n }\n return { updatedFiles, erroredFiles };\n });\n /** adds new images to imageCache and re-renders if needed */\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\n if (uncachedImageElements.length) {\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n });\n /** generally you should use `addNewImagesToImageCache()` directly if you need\n * to render new images. This is just a failsafe */\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n this.updateBindingEnabledOnPointerMove = (event) => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({ isBindingEnabled: shouldEnableBinding });\n }\n };\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\n });\n };\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \n /** scene coords */\n pointerCoords, \n // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n if (hoveredBindableElement != null &&\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n return acc;\n }, []);\n this.setState({ suggestedBindings });\n };\n this.handleCanvasRef = (canvas) => {\n var _a, _b, _c;\n // canvas is null when unmounting\n if (canvas !== null) {\n this.canvas = canvas;\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel, {\n passive: false,\n });\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n else {\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n };\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\n // must be retrieved first, in the same frame\n const { file, fileHandle } = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n return;\n }\n catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n }\n // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n }\n catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message,\n });\n }\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null,\n });\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n return;\n }\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n yield this.loadFileToCanvas(file, fileHandle);\n }\n });\n this.loadFileToCanvas = (file, fileHandle) => __awaiter(this, void 0, void 0, function* () {\n file = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n try {\n const ret = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({ isLoading: true });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), { appState: Object.assign(Object.assign({}, (ret.data.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n }\n else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n yield this.library\n .updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true,\n })\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\") });\n });\n }\n }\n catch (error) {\n this.setState({ isLoading: false, errorMessage: error.message });\n }\n });\n this.handleCanvasContextMenu = (event) => {\n event.preventDefault();\n if ((event.nativeEvent.pointerType === \"touch\" ||\n (event.nativeEvent.pointerType === \"pen\" &&\n // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY)) &&\n this.state.activeTool.type !== \"selection\") {\n return;\n }\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true,\n });\n const type = element ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n if (element && !this.state.selectedElementIds[element.id]) {\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { selectedElementIds: { [element.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element)\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene)\n : null }), this.scene.getNonDeletedElements()), () => {\n this._openContextMenu({ top, left }, type);\n });\n }\n else {\n this._openContextMenu({ top, left }, type);\n }\n };\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a;\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"selection\" &&\n this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise)\n ? image.width / image.height\n : null;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\n this.maybeSuggestBindingForAll([draggingElement]);\n }\n };\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const transformHandleType = pointerDownState.resize.handleType;\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n });\n const pointerCoords = pointerDownState.lastCoords;\n const [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, this.state.gridSize);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0])\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\n this.maybeSuggestBindingForAll(selectedElements);\n return true;\n }\n return false;\n };\n /** @private use this.handleCanvasContextMenu */\n this._openContextMenu = ({ left, top, }, type) => {\n if (this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n this.contextMenuOpen = true;\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowUnbinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowBinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const separator = \"separator\";\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const options = [];\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng);\n }\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n }\n if (type === \"element\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText.contextItemPredicate(elements, this.state) &&\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n }\n if (type === \"canvas\") {\n const viewModeOptions = [\n ...options,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: viewModeOptions,\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile &&\n navigator.clipboard && {\n trackEvent: false,\n name: \"paste\",\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && navigator.clipboard && separator,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n selectedElements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n ((_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) ||\n (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0)) &&\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n separator,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n else if (type === \"element\") {\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n this.device.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n this.device.isMobile &&\n navigator.clipboard && {\n name: \"paste\",\n trackEvent: false,\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && separator,\n ...options,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n separator,\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n mayBeAllowUnbinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n mayBeAllowBinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n (maybeGroupAction || maybeUngroupAction) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront,\n separator,\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink.contextItemPredicate(elements, this.state) && _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLock,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n };\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n if (isPanning) {\n return;\n }\n const { deltaX, deltaY } = event;\n // note that event.ctrlKey is necessary to handle pinch zooming\n if (event.metaKey || event.ctrlKey) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = 10;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n let newZoom = this.state.zoom.value - delta / 100;\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\n newZoom +=\n Math.log10(Math.max(1, this.state.zoom.value)) *\n -sign *\n // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom),\n }, state)), { shouldCacheIgnoreZoom: true })));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n }\n // scroll horizontally when shift pressed\n if (event.shiftKey) {\n this.setState(({ zoom, scrollX }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\n }));\n return;\n }\n this.setState(({ zoom, scrollX, scrollY }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value,\n }));\n });\n this.savePointer = (x, y, button) => {\n var _a, _b;\n if (!x || !y) {\n return;\n }\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\n // sometimes the pointer goes off screen\n }\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers,\n });\n };\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({ shouldCacheIgnoreZoom: false });\n }\n }, 300);\n this.updateDOMRect = (cb) => {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\n if (width === currentWidth &&\n height === currentHeight &&\n offsetLeft === currentOffsetLeft &&\n offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n return;\n }\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop,\n }, () => {\n cb && cb();\n });\n }\n };\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight, showHyperlinkPopup: false, isLibraryMenuDocked: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_47__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n if (excalidrawRef) {\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory,\n },\n scrollToContent: this.scrollToContent,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n id: this.id,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n };\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n }\n else {\n excalidrawRef.current = api;\n }\n readyPromise.resolve(api);\n }\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id,\n };\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n renderCanvas() {\n const canvasScale = window.devicePixelRatio;\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\n const canvasWidth = canvasDOMWidth * canvasScale;\n const canvasHeight = canvasDOMHeight * canvasScale;\n if (viewModeEnabled) {\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n render() {\n var _a, _b;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile,\n }), ref: this.excalidrawContainerRef, onDrop: this.handleAppOnDrop, tabIndex: 0, onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: [this.__renderUI && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], { canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n }), langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\n this.props.UIOptions.canvasActions.theme, libraryReturnUrl: this.props.libraryReturnUrl, UIOptions: this.props.UIOptions, focusContainer: this.focusContainer, library: this.library, id: this.id, onImageAction: this.onImageAction })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }), selectedElement.length === 1 && this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], appState: this.state, setAppState: this.setAppState, onLinkOpen: this.props.onLinkOpen }, selectedElement[0].id)), this.state.toast !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, { message: this.state.toast.message, onClose: () => this.setToast(null), duration: this.state.toast.duration, closable: this.state.toast.closable })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() })] })) })) })));\n }\n componentDidMount() {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n this.unmounted = false;\n this.excalidrawContainerValue.container =\n this.excalidrawContainerRef.current;\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT ||\n ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_VERCEL_ENV === \"preview\") {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n },\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n },\n },\n app: {\n configurable: true,\n value: this,\n },\n history: {\n configurable: true,\n value: this.history,\n },\n });\n }\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n if (this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n if (this.excalidrawContainerRef.current &&\n // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n \"development\" !== \"test\") {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n THROTTLE_NEXT_RENDER = false;\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n // refresh offsets\n // ---------------------------------------------------------------------\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n }\n else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${\n // NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches,\n });\n };\n mdScreenQuery.addListener(handler);\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n }\n else {\n this.updateDOMRect(this.initializeScene);\n }\n });\n }\n componentWillUnmount() {\n var _a;\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.call(this);\n }\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n this.removeEventListeners();\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, { passive: false });\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, { passive: true });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\n // rerender text elements on font load to fix #637 && #1553\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", this.onFontLoaded);\n // Safari-only desktop pinch zoom\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n if (this.state.viewModeEnabled) {\n return;\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e;\n if (this.excalidrawContainerRef.current &&\n prevProps.UIOptions.dockedSidebarBreakpoint !==\n this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (prevState.scrollX !== this.state.scrollX ||\n prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n if (Object.keys(this.state.selectedElementIds).length &&\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n if (this.state.activeTool.type === \"eraser\" &&\n prevState.theme !== this.state.theme) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setEraserCursor)(this.canvas, this.state.theme);\n }\n // Hide hyperlink popup if shown when element type is not selection\n if (prevState.activeTool.type === \"selection\" &&\n this.state.activeTool.type !== \"selection\" &&\n this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\n }\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\n }\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n });\n }\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name,\n });\n }\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n if (this.state.editingLinearElement &&\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n if (this.state.selectedLinearElement &&\n !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({ selectedLinearElement: null });\n }\n const { multiElement } = prevState;\n if (prevState.activeTool !== this.state.activeTool &&\n multiElement != null &&\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n this.renderScene();\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\n // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n if (!this.state.isLoading) {\n (_e = (_d = this.props).onChange) === null || _e === void 0 ? void 0 : _e.call(_d, this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false,\n });\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({ selectedElementIds: { [element.id]: true } });\n this.history.resumeRecording();\n }\n handleTextWysiwyg(element, { isExistingElement = false, }) {\n const updateElement = (text, originalText, isDeleted) => {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n });\n }\n return _element;\n }),\n ]);\n };\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y,\n }, this.state);\n return [\n viewportX - this.state.offsetLeft,\n viewportY - this.state.offsetTop,\n ];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\n updateElement(text, text, false);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\n const isDeleted = !text.trim();\n updateElement(text, originalText, isDeleted);\n // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId\n ? element.containerId\n : element.id;\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\n }));\n }\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [\n element,\n ]);\n }\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n this.setState({\n draggingElement: null,\n editingElement: null,\n });\n if (this.state.activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this,\n });\n // deselect all other elements when inserting text\n this.deselectElements();\n // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n updateElement(element.text, element.originalText, false);\n }\n deselectElements() {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true,\n });\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n return null;\n }\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\n // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\n ? allHitElements[allHitElements.length - 2]\n : elementWithHighestZIndex;\n }\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n return null;\n }\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements\n ? this.scene.getNonDeletedElements()\n : this.scene\n .getNonDeletedElements()\n .filter((element) => (includeLockedElements || !element.locked) &&\n (includeBoundTextElement ||\n !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\n }\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let midPointHovered = false;\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\n scenePointerX,\n scenePointerY,\n ])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n midPointHovered = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.isHittingMidPoint(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state);\n if (hoverPointIndex >= 0 || midPointHovered) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_46__.shouldShowBoundingBox)([element], this.state) &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\n });\n }\n if (this.state.selectedLinearElement.midPointHovered !== midPointHovered) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { midPointHovered }),\n });\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene\n .getNonDeletedElements()\n .reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: { x: 0, y: 0 },\n arrowDirection: \"origin\",\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\n },\n drag: {\n hasOccurred: false,\n offset: null,\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null,\n },\n boxSelection: {\n hasOccurred: false,\n },\n elementIdsToErase: {},\n };\n }\n // Returns whether the event is a dragging a scrollbar\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n }\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return (point.x > x1 - threshold &&\n point.x < x2 + threshold &&\n point.y > y1 - threshold &&\n point.y < y2 + threshold);\n }\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n var _a;\n // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n if (!pointerDownState.drag.hasOccurred &&\n (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { isDragging: true }),\n });\n }\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { isDragging: true }),\n });\n }\n return;\n }\n }\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement &&\n event.shiftKey &&\n this.state.editingLinearElement.elementId ===\n ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n !isSelectingPointsInLineEditor) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.every((element) => element.locked)) {\n return;\n }\n // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n pointerDownState.drag.hasOccurred = true;\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\n const [dragX, dragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.drag.offset.x, pointerCoords.y - pointerDownState.drag.offset.y, this.state.gridSize);\n const [dragDistanceX, dragDistanceY] = [\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\n ];\n // We only drag in one direction if shift is pressed\n const lockDirection = event.shiftKey;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY, this.state);\n this.maybeSuggestBindingForAll(selectedElements);\n // We duplicate the selected element if alt is pressed on pointer move\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const elements = this.scene.getElementsIncludingDeleted();\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\n for (const element of elements) {\n if (selectedElementIds.includes(element.id) ||\n // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n pointerDownState.hit.wasAddedToSelection)) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const [originDragX, originDragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x - pointerDownState.drag.offset.x, pointerDownState.origin.y - pointerDownState.drag.offset.y, this.state.gridSize);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: duplicatedElement.x + (originDragX - dragX),\n y: duplicatedElement.y + (originDragY - dragY),\n });\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n }\n else {\n nextElements.push(element);\n }\n }\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n this.scene.replaceAllElements(nextSceneElements);\n }\n return;\n }\n }\n // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n const draggingElement = this.state.draggingElement;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n if (!discardPoint) {\n const pressures = draggingElement.simulatePressure\n ? draggingElement.pressures\n : [...draggingElement.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n });\n }\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n });\n }\n else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]],\n });\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n }\n else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements();\n if (!event.shiftKey &&\n // allows for box-selecting points (without shift)\n !this.state.editingLinearElement &&\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\n [pointerDownState.hit.element.id]: true,\n } }), this.scene.getNonDeletedElements()));\n }\n else {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n }\n // box-select line editor points\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\n // regular box-select\n }\n else {\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign(Object.assign({}, prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {})), (pointerDownState.hit.element\n ? {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\n }\n : null)), showHyperlinkPopup: elementsWithinSelection.length === 1 &&\n elementsWithinSelection[0].link\n ? \"info\"\n : false, \n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene)\n : null }), this.scene.getNonDeletedElements()));\n }\n }\n });\n }\n // Returns whether the pointer move happened over either scrollbar\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.setState({\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.setState({\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n return false;\n }\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\n var _a, _b, _c, _d, _e, _f;\n const { draggingElement, resizingElement, multiElement, activeTool, isResizing, isRotating, } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? this.state.editingElement\n : null,\n });\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred &&\n ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\n this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: [],\n });\n }\n }\n }\n else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !==\n this.state.selectedLinearElement.elementId) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n if (selectedELements.length > 1) {\n this.setState({ selectedLinearElement: null });\n }\n }\n else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const { startBindingElement, endBindingElement } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), { selectedPointsIndices: null }),\n suggestedBindings: [],\n });\n }\n }\n }\n lastPointerUp = null;\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n if (this.state.pendingImageElementId) {\n this.setState({ pendingImageElementId: null });\n }\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y;\n // Allows dots to avoid being flagged as infinitely small\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n const pressures = draggingElement.simulatePressure\n ? []\n : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n if (!pointerDownState.drag.hasOccurred &&\n draggingElement &&\n !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [\n ...draggingElement.points,\n [\n pointerCoords.x - draggingElement.x,\n pointerCoords.y - draggingElement.y,\n ],\n ],\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement,\n });\n }\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n this.setState({ suggestedBindings: [], startBoundElement: null });\n if (!activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState((prevState) => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, {\n type: \"selection\",\n }),\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene),\n }));\n }\n else {\n this.setState((prevState) => ({\n draggingElement: null,\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n }\n return;\n }\n if (activeTool.type !== \"selection\" &&\n draggingElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\n this.setState({\n draggingElement: null,\n });\n return;\n }\n if (draggingElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n if (resizingElement) {\n this.history.resumeRecording();\n }\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== resizingElement.id));\n }\n // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n const hitElement = pointerDownState.hit.element;\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement when no other element selected except\n // the one we've hit\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene),\n });\n }\n }\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUp.clientX,\n clientY: this.lastPointerUp.clientY,\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach((hitElement) => (pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity,\n }));\n }\n this.eraseElements(pointerDownState);\n return;\n }\n else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n if (hitElement &&\n !pointerDownState.drag.hasOccurred &&\n !pointerDownState.hit.wasAddedToSelection &&\n // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n (!this.state.editingLinearElement ||\n !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))\n .map((element) => ({ [element.id]: false }))\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\n this.setState((_prevState) => ({\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\n .map((gId) => ({ [gId]: false }))\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\n }));\n // if not gragging a linear element point (outside editor)\n }\n else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState((prevState) => {\n const newSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false });\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds }));\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds, \n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements());\n });\n }\n }\n else {\n // add element to selection while\n // keeping prev elements selected\n this.setState((_prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\n }));\n }\n }\n else {\n this.setState((prevState) => {\n var _a;\n return (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) &&\n // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements())));\n });\n }\n }\n if (!pointerDownState.drag.hasOccurred &&\n !this.state.isResizing &&\n ((hitElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\n (!hitElement &&\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: null });\n }\n else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n return;\n }\n if (!activeTool.locked &&\n activeTool.type !== \"freedraw\" &&\n draggingElement) {\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n if (activeTool.type !== \"selection\" ||\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state));\n }\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n else {\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n });\n }\n });\n }\n maybeSuggestBindingForAll(selectedElements) {\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({ suggestedBindings });\n }\n clearSelection(hitElement) {\n this.setState((prevState) => ({\n selectedElementIds: {},\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId &&\n hitElement != null &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\n ? prevState.editingGroupId\n : null,\n }));\n this.setState({\n selectedElementIds: {},\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getElementsIncludingDeleted()\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\n if (elementClickedInside) {\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n if (isSnappedToCenter) {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\n return { viewportX, viewportY, elementCenterX, elementCenterY };\n }\n }\n }\n getCanvasOffsets() {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { left, top } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top,\n };\n }\n return {\n offsetLeft: 0,\n offsetTop: 0,\n };\n }\n updateLanguage() {\n return __awaiter(this, void 0, void 0, function* () {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n });\n }\n}\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS,\n};\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT ||\n ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_VERCEL_ENV === \"preview\") {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n get() {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n set(elements) {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n },\n },\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vY29tcG9uZW50cy9BcHAudHN4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBMEM7QUFDSjtBQUdBO0FBQ2Q7QUFDUTtBQThCWjtBQUMwRDtBQUMzQjtBQUNMO0FBRUo7QUFDdUI7QUFLM0M7QUE4QkE7QUFDaUI7QUFDdUM7QUFDbkI7QUEwQnZDO0FBY1E7QUFDeUM7QUFDSTtBQUNHO0FBVzdDO0FBZXFCO0FBU2pDO0FBQ2M7QUFDNkM7QUFTN0Q7QUFDK0M7QUFDVjtBQUNnQjtBQVdwRDtBQUNpQjtBQUVhO0FBQ0c7QUFxQ2pDO0FBQzZDO0FBQy9CO0FBQ0E7QUFDdUM7QUFZakQ7QUFNSTtBQUNhO0FBQ3lCO0FBTWhDO0FBQ2lEO0FBUW5EO0FBQ3NDO0FBRXBFLE1BQU0seUJBQXlCLEdBQUc7SUFDaEMsVUFBVSxFQUFFLEtBQUs7SUFDakIsUUFBUSxFQUFFLEtBQUs7SUFDZixhQUFhLEVBQUUsS0FBSztJQUNwQixtQkFBbUIsRUFBRSxLQUFLO0NBQzNCLENBQUM7QUFDRixNQUFNLGFBQWEsR0FBRywwREFBbUIsQ0FBUyx5QkFBeUIsQ0FBQyxDQUFDO0FBQ3RFLE1BQU0sU0FBUyxHQUFHLEdBQUcsRUFBRSxDQUFDLGlEQUFVLENBQVMsYUFBYSxDQUFDLENBQUM7QUFDakUsTUFBTSwwQkFBMEIsR0FBRywwREFBbUIsQ0FHbkQsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzNCLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxFQUFFLENBQ3pDLGlEQUFVLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUV6QyxJQUFJLFdBQVcsR0FBWSxLQUFLLENBQUM7QUFDakMsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDekIsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNoQixJQUFJLGNBQWMsR0FBWSxLQUFLLENBQUM7QUFDcEMsSUFBSSxTQUFTLEdBQVksS0FBSyxDQUFDO0FBQy9CLElBQUksbUJBQW1CLEdBQVksS0FBSyxDQUFDO0FBQ3pDLElBQUksaUJBQWlCLEdBQWUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUN6RSxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDckIsSUFBSSxxQkFBcUIsR0FBRyxLQUFLLENBQUM7QUFFbEMsMkVBQTJFO0FBQzNFLG9CQUFvQjtBQUNwQixJQUFJLG9CQUFvQixHQUFHLElBQUksQ0FBQztBQUVoQyxJQUFJLGFBQWEsR0FBa0MsSUFBSSxDQUFDO0FBQ3hELE1BQU0sT0FBTyxHQUFZO0lBQ3ZCLFFBQVEsRUFBRSxJQUFJLEdBQUcsRUFBRTtJQUNuQixVQUFVLEVBQUUsSUFBSTtJQUNoQixlQUFlLEVBQUUsSUFBSTtJQUNyQixZQUFZLEVBQUUsSUFBSTtDQUNuQixDQUFDO0FBRUYsTUFBTSxHQUFJLFNBQVEsd0RBQW1DO0lBb0NuRCxZQUFZLEtBQWU7O1FBQ3pCLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQXBDZixXQUFNLEdBQWlDLElBQUksQ0FBQztRQUM1QyxPQUFFLEdBQXVCLElBQUksQ0FBQztRQUM5QixjQUFTLEdBQVksS0FBSyxDQUFDO1FBRTNCLFdBQU0sR0FBVyx5QkFBeUIsQ0FBQztRQUduQywyQkFBc0IsR0FBRyxzREFBZSxFQUFrQixDQUFDO1FBbUI1RCxVQUFLLEdBQWdCLEVBQUUsQ0FBQztRQUN4QixlQUFVLEdBQXFDLElBQUksR0FBRyxFQUFFLENBQUM7UUFHaEUsb0JBQWUsR0FBaUQsSUFBSSxDQUFDO1FBQ3JFLGtCQUFhLEdBQTBELElBQUksQ0FBQztRQUM1RSxvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxxQkFBZ0IsR0FBb0MsSUFBSSxDQUFDO1FBNElqRCxlQUFVLEdBQUcsSUFBSSxDQUFDO1FBZ0duQixtQkFBYyxHQUF5QyxHQUFHLEVBQUU7O1lBQ2pFLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7Z0JBQ3hCLFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLEtBQUssRUFBRSxDQUFDO2FBQzlDO1FBQ0gsQ0FBQyxDQUFDO1FBRUsscUNBQWdDLEdBQUcsR0FBRyxFQUFFO1lBQzdDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1FBQ2xELENBQUMsQ0FBQztRQUVLLHFCQUFnQixHQUFHLEdBQUcsRUFBRTtZQUM3QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUM1QyxDQUFDLENBQUM7UUFFTSxxQkFBZ0IsR0FBRywyREFBa0IsQ0FDM0MsQ0FBQyxZQUEwQixFQUFFLEVBQUU7O1lBQzdCLHNFQUFzRTtZQUN0RSxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUM3QixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksWUFBWSxLQUFLLEtBQUssRUFBRTtnQkFDNUMsT0FBTzthQUNSO1lBRUQsSUFBSSxjQUFjLEdBQXNDLElBQUksQ0FBQztZQUM3RCxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUU7Z0JBQ3pCLFlBQVksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7O29CQUN4QyxJQUNFLFdBQUksQ0FBQyxLQUFLLENBQUMsY0FBYywwQ0FBRSxFQUFFLE1BQUssT0FBTyxDQUFDLEVBQUU7d0JBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxLQUFLLE9BQU87d0JBQ3JDLDhEQUFtQixDQUFDLE9BQU8sQ0FBQyxFQUM1Qjt3QkFDQSxjQUFjLEdBQUcsT0FBTyxDQUFDO3FCQUMxQjtnQkFDSCxDQUFDLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDckQsSUFBSSxZQUFZLENBQUMsZUFBZSxFQUFFO29CQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2lCQUNoQzthQUNGO1lBRUQsSUFBSSxZQUFZLENBQUMsS0FBSyxFQUFFO2dCQUN0QixJQUFJLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxZQUFZO29CQUNwQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUs7b0JBQ3BCLENBQUMsaUNBQU0sSUFBSSxDQUFDLEtBQUssR0FBSyxZQUFZLENBQUMsS0FBSyxDQUFFLENBQUM7Z0JBQzdDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2FBQ2pDO1lBRUQsSUFBSSxZQUFZLENBQUMsUUFBUSxJQUFJLGNBQWMsRUFBRTtnQkFDM0MsSUFBSSxZQUFZLENBQUMsZUFBZSxFQUFFO29CQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2lCQUNoQztnQkFFRCxJQUFJLGVBQWUsR0FBRyxtQkFBWSxhQUFaLFlBQVksdUJBQVosWUFBWSxDQUFFLFFBQVEsMENBQUUsZUFBZSxLQUFJLEtBQUssQ0FBQztnQkFDdkUsSUFBSSxjQUFjLEdBQUcsbUJBQVksYUFBWixZQUFZLHVCQUFaLFlBQVksQ0FBRSxRQUFRLDBDQUFFLGNBQWMsS0FBSSxLQUFLLENBQUM7Z0JBQ3JFLElBQUksUUFBUSxHQUFHLG1CQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsUUFBUSwwQ0FBRSxRQUFRLEtBQUksSUFBSSxDQUFDO2dCQUN4RCxJQUFJLEtBQUssR0FBRyxtQkFBWSxhQUFaLFlBQVksdUJBQVosWUFBWSxDQUFFLFFBQVEsMENBQUUsS0FBSyxLQUFJLG9EQUFXLENBQUM7Z0JBQ3pELElBQUksSUFBSSxHQUFHLHdCQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsUUFBUSwwQ0FBRSxJQUFJLG1DQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUMzRCxJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssV0FBVyxFQUFFO29CQUNyRCxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUM7aUJBQzlDO2dCQUVELElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsS0FBSyxXQUFXLEVBQUU7b0JBQ3BELGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztpQkFDNUM7Z0JBRUQsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLFdBQVcsRUFBRTtvQkFDckQsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxrREFBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7aUJBQzFEO2dCQUVELElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxXQUFXLEVBQUU7b0JBQzNDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztpQkFDMUI7Z0JBRUQsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRTtvQkFDMUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO2lCQUN4QjtnQkFDRCxJQUFJLENBQUMsUUFBUSxDQUNYLENBQUMsS0FBSyxFQUFFLEVBQUU7O29CQUNSLCtEQUErRDtvQkFDL0QsMkRBQTJEO29CQUMzRCxzREFBc0Q7b0JBQ3RELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxJQUFJLEVBQUUsRUFBRTt3QkFDaEQsY0FBYyxFQUNaLGNBQWMsS0FBSSxrQkFBWSxDQUFDLFFBQVEsMENBQUUsY0FBYyxLQUFJLElBQUk7d0JBQ2pFLGVBQWU7d0JBQ2YsY0FBYzt3QkFDZCxRQUFRO3dCQUNSLEtBQUs7d0JBQ0wsSUFBSTtxQkFDTCxDQUFDLENBQUM7Z0JBQ0wsQ0FBQyxFQUNELEdBQUcsRUFBRTtvQkFDSCxJQUFJLFlBQVksQ0FBQyxXQUFXLEVBQUU7d0JBQzVCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUMxQixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FDekMsQ0FBQztxQkFDSDtnQkFDSCxDQUFDLENBQ0YsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUNGLENBQUM7UUFFRixZQUFZO1FBRUosV0FBTSxHQUFHLDJEQUFrQixDQUFDLEdBQUcsRUFBRTtZQUN2QyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO1FBRUssYUFBUSxHQUFHLEdBQUcsRUFBRTtZQUN0QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQyxDQUFDO1FBRU0saUJBQVksR0FBa0IsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM5QyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFDO1FBRU0saUJBQVksR0FBRyxHQUFHLEVBQUU7WUFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUMzRCxJQUFJLHdEQUFhLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQzFCLG1GQUF5QixDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUNwQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FBQztRQUVNLGlCQUFZLEdBQUcsR0FBRyxFQUFFO1lBQzFCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkIsQ0FBQyxDQUFDO1FBRUY7OztXQUdHO1FBQ0ssZUFBVSxHQUFHLDJEQUFrQixDQUNyQyxDQUFDLElBQXFDLEVBQUUsRUFBRTtZQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGlDQUNwQiw4REFBa0IsRUFBRSxLQUN2QixTQUFTLEVBQUUsS0FBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLGlCQUFpQixFQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzVELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssSUFDdkIsQ0FBQyxDQUFDO1lBQ0osSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RCLENBQUMsQ0FDRixDQUFDO1FBRU0sb0JBQWUsR0FBRyxHQUFTLEVBQUU7O1lBQ25DLElBQUksYUFBYSxJQUFJLE1BQU0sSUFBSSxjQUFjLElBQUksTUFBTSxFQUFFO2dCQUN0RCxNQUFjLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FDckMsQ0FBTyxZQUE4QixFQUFFLEVBQUU7b0JBQ3ZDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDOUIsT0FBTztxQkFDUjtvQkFDRCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN6QyxNQUFNLElBQUksR0FBUyxNQUFNLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDOUMsSUFBSSxDQUFDLGdCQUFnQixDQUNuQixJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUN0RCxVQUFVLENBQ1gsQ0FBQztnQkFDSixDQUFDLEVBQ0YsQ0FBQzthQUNIO1lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO2dCQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDcEM7WUFDRCxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUM7WUFDdkIsSUFBSTtnQkFDRixXQUFXLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDO2dCQUNyRCxJQUFJLFdBQVcsYUFBWCxXQUFXLHVCQUFYLFdBQVcsQ0FBRSxZQUFZLEVBQUU7b0JBQzdCLElBQUksQ0FBQyxPQUFPO3lCQUNULGFBQWEsQ0FBQzt3QkFDYixZQUFZLEVBQUUsV0FBVyxDQUFDLFlBQVk7d0JBQ3RDLEtBQUssRUFBRSxJQUFJO3FCQUNaLENBQUM7eUJBQ0QsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7d0JBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDdkIsQ0FBQyxDQUFDLENBQUM7aUJBQ047YUFDRjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQixXQUFXLEdBQUc7b0JBQ1osUUFBUSxFQUFFO3dCQUNSLFlBQVksRUFDVixLQUFLLENBQUMsT0FBTzs0QkFDYiwrREFBK0Q7cUJBQ2xFO2lCQUNGLENBQUM7YUFDSDtZQUNELE1BQU0sS0FBSyxHQUFHLHVEQUFPLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMvQyxLQUFLLENBQUMsUUFBUSxtQ0FDVCxLQUFLLENBQUMsUUFBUTtnQkFDakIsK0RBQStEO2dCQUMvRCx5REFBeUQ7Z0JBQ3pELHFFQUFxRTtnQkFDckUsbUVBQW1FO2dCQUNuRSxhQUFhLEVBQ1gsa0JBQVcsYUFBWCxXQUFXLHVCQUFYLFdBQVcsQ0FBRSxRQUFRLDBDQUFFLGFBQWEsS0FBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFDbEUsVUFBVSxFQUNSLEtBQUssQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPO29CQUN4QyxDQUFDLGlDQUFNLEtBQUssQ0FBQyxRQUFRLENBQUMsVUFBVSxLQUFFLElBQUksRUFBRSxXQUFXLElBQ25ELENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFDL0IsU0FBUyxFQUFFLEtBQUssRUFDaEIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUN4QixDQUFDO1lBQ0YsSUFBSSxXQUFXLGFBQVgsV0FBVyx1QkFBWCxXQUFXLENBQUUsZUFBZSxFQUFFO2dCQUNoQyxLQUFLLENBQUMsUUFBUSxtQ0FDVCxLQUFLLENBQUMsUUFBUSxHQUNkLDhEQUFxQixDQUN0QixLQUFLLENBQUMsUUFBUSxrQ0FFVCxLQUFLLENBQUMsUUFBUSxLQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFDekIsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMvQixVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBRW5DLElBQUksQ0FDTCxDQUNGLENBQUM7YUFDSDtZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsZ0JBQWdCLGlDQUNoQixLQUFLLEtBQ1IsZUFBZSxFQUFFLElBQUksSUFDckIsQ0FBQztRQUNMLENBQUMsRUFBQztRQUVNLHVCQUFrQixHQUFHLENBQUMsU0FBeUIsRUFBRSxFQUFFO1lBQ3pELE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDNUQsTUFBTSxpQkFBaUIsR0FDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsdUJBQXVCLElBQUksSUFBSTtnQkFDbEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLHVCQUF1QjtnQkFDOUMsQ0FBQyxDQUFDLG1FQUEwQixDQUFDO1lBQ2pDLElBQUksQ0FBQyxNQUFNLEdBQUcscURBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUN0QyxVQUFVLEVBQUUsS0FBSyxHQUFHLHdEQUFlO2dCQUNuQyxRQUFRLEVBQ04sS0FBSyxHQUFHLDhEQUFxQjtvQkFDN0IsQ0FBQyxNQUFNLEdBQUcsZ0VBQXVCLElBQUksS0FBSyxHQUFHLCtEQUFzQixDQUFDO2dCQUN0RSxtQkFBbUIsRUFBRSxLQUFLLEdBQUcsaUJBQWlCO2FBQy9DLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQW1ITSxhQUFRLEdBQUcsMkRBQWtCLENBQUMsR0FBRyxFQUFFO1lBQ3pDLElBQUksQ0FBQyxLQUFLO2lCQUNQLDJCQUEyQixFQUFFO2lCQUM3QixPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLG1GQUF5QixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FBQztRQTJQSyxnQkFBVyxHQUFHLEdBQUcsRUFBRTtZQUN6QixNQUFNLFlBQVksR0FFZCxFQUFFLENBQUM7WUFDUCxNQUFNLHFCQUFxQixHQUN6QixFQUFFLENBQUM7WUFDTCxNQUFNLHdCQUF3QixHQUM1QixFQUFFLENBQUM7WUFDTCxNQUFNLGdCQUFnQixHQUE2QixFQUFFLENBQUM7WUFDdEQsTUFBTSxpQkFBaUIsR0FBNkIsRUFBRSxDQUFDO1lBQ3ZELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7b0JBQzNCLEtBQUssTUFBTSxFQUFFLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRTt3QkFDckQsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLHdCQUF3QixDQUFDLEVBQUU7NEJBQ3JDLHdCQUF3QixDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt5QkFDbkM7d0JBQ0Qsd0JBQXdCLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3FCQUM3QztpQkFDRjtnQkFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDakIsT0FBTztpQkFDUjtnQkFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7b0JBQ2pCLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7aUJBQzVDO2dCQUNELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtvQkFDbEIsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztpQkFDOUM7Z0JBQ0QscUJBQXFCLENBQUMsUUFBUSxDQUFDLEdBQUcsb0VBQTJCLENBQzNEO29CQUNFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3RCLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQ3ZCLEVBQ0QsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUNGLFlBQVksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsS0FBSztpQkFDakMscUJBQXFCLEVBQUU7aUJBQ3ZCLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNsQixJQUFJLG9FQUFjLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQzNCO29CQUNFLG1EQUFtRDtvQkFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxPQUFPLENBQUMsRUFBRSxFQUMvQzt3QkFDQSxPQUFPLEtBQUssQ0FBQztxQkFDZDtpQkFDRjtnQkFDRCxnRUFBZ0U7Z0JBQ2hFLDJCQUEyQjtnQkFDM0IsT0FBTyxDQUNMLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjO29CQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEtBQUssTUFBTTtvQkFDekMsT0FBTyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQzVDLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUVMLG1FQUFXLENBQ1Q7Z0JBQ0UsUUFBUSxFQUFFLGlCQUFpQjtnQkFDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLO2dCQUNwQixLQUFLLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtnQkFDOUIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFHO2dCQUNaLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTztnQkFDcEIsWUFBWSxFQUFFO29CQUNaLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87b0JBQzNCLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87b0JBQzNCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CO29CQUNuRCxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO29CQUNyQiwyQkFBMkIsRUFBRSxxQkFBcUI7b0JBQ2xELG1CQUFtQixFQUFFLFlBQVk7b0JBQ2pDLHdCQUF3QjtvQkFDeEIsc0JBQXNCLEVBQUUsZ0JBQWdCO29CQUN4Qyx1QkFBdUIsRUFBRSxpQkFBaUI7b0JBQzFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO29CQUN2RCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLO29CQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7b0JBQzNCLFdBQVcsRUFBRSxLQUFLO29CQUNsQixnQkFBZ0IsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUTtpQkFDeEM7Z0JBQ0QsUUFBUSxFQUFFLENBQUMsRUFBRSx3QkFBd0IsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFO29CQUNyRCxJQUFJLFVBQVUsRUFBRTt3QkFDZCxpQkFBaUIsR0FBRyxVQUFVLENBQUM7cUJBQ2hDO29CQUNELE1BQU0sZUFBZTtvQkFDbkIseUJBQXlCO29CQUN6Qix3REFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO3dCQUN0QyxDQUFDLENBQUMsS0FBSzt3QkFDUCxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNoRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLGVBQWUsRUFBRTt3QkFDbEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7cUJBQ3BDO29CQUVELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2dCQUM5QixDQUFDO2FBQ0YsRUFDRCxvQkFBb0IsSUFBSSxNQUFNLENBQUMsMEJBQTBCLEtBQUssSUFBSSxDQUNuRSxDQUFDO1lBRUYsSUFBSSxDQUFDLG9CQUFvQixFQUFFO2dCQUN6QixvQkFBb0IsR0FBRyxJQUFJLENBQUM7YUFDN0I7UUFDSCxDQUFDLENBQUM7UUFFTSxhQUFRLEdBQUcsaURBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDL0IsTUFBTSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxRCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ3RCLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxVQUFVLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUU7b0JBQ3BFLE9BQU8sSUFBSSxDQUFDO2lCQUNiO2dCQUNELE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDbkMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUUsdURBQWMsQ0FBQyxDQUFDO1FBRW5CLGFBQWE7UUFFTCxVQUFLLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFxQixFQUFFLEVBQUU7O1lBQzNELE1BQU0sa0JBQWtCLEdBQUcsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsUUFBUSxDQUN0RSxRQUFRLENBQUMsYUFBYSxDQUN2QixDQUFDO1lBQ0YsSUFBSSxDQUFDLGtCQUFrQixJQUFJLDBEQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDMUQsT0FBTzthQUNSO1lBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVLLFdBQU0sR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQXFCLEVBQUUsRUFBRTs7WUFDNUQsTUFBTSxrQkFBa0IsR0FBRyxVQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTywwQ0FBRSxRQUFRLENBQ3RFLFFBQVEsQ0FBQyxhQUFhLENBQ3ZCLENBQUM7WUFDRixJQUFJLENBQUMsa0JBQWtCLElBQUksMERBQWlCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMxRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdkIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUssV0FBTSxHQUFHLEdBQUcsRUFBRTtZQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQywrQ0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQztRQUVNLFlBQU8sR0FBRyxHQUFHLEVBQUU7WUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsZ0RBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUM7UUFNTSxlQUFVLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDekMsZ0NBQWdDO1lBQ2hDLHlFQUF5RTtZQUN6RSxJQUFJLENBQUMsNkNBQVMsRUFBRTtnQkFDZCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7WUFFRCxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNoQixXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUNuQixZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDL0IsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FDbEMsR0FBRyxDQUFDLGFBQWEsRUFDakIsMERBQWlCLENBQ2xCLENBQUM7Z0JBQ0YsT0FBTzthQUNSO1lBQ0QsMkRBQTJEO1lBQzNELGtGQUFrRjtZQUNsRixJQUFJLFdBQVcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQzdDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUM5QixhQUFhO2dCQUNiLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztvQkFDM0IsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUN0QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87aUJBQ3ZCLENBQUMsQ0FBQztnQkFDSCxXQUFXLEdBQUcsS0FBSyxDQUFDO2dCQUNwQixZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQzthQUNoQztZQUNELElBQUksNkNBQVMsRUFBRTtnQkFDYixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7WUFFRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixrQkFBa0IsRUFBRSxFQUFFO2lCQUN2QixDQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQztRQUVNLGFBQVEsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUN2QyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUM3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWiwwQkFBMEIsRUFBRSxFQUFFO29CQUM5QixrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDBCQUEwQjtpQkFDMUQsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUMxQjtRQUNILENBQUMsQ0FBQztRQUVNLHVCQUFrQixHQUFHLDJEQUFrQixDQUM3QyxDQUFPLEtBQTRCLEVBQUUsRUFBRTs7WUFDckMsT0FBTztZQUNQLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUM7WUFDdEMsTUFBTSxrQkFBa0IsR0FDdEIsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxrQkFBa0IsRUFBRTtnQkFDdkIsT0FBTzthQUNSO1lBRUQsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZFO1lBQ0Usc0VBQXNFO1lBQ3RFLHFDQUFxQztZQUNyQyxLQUFLO2dCQUNMLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixZQUFZLGlCQUFpQixDQUFDO29CQUNqRCwwREFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUM1QjtnQkFDQSxPQUFPO2FBQ1I7WUFFRCx5RUFBeUU7WUFDekUsZ0VBQWdFO1lBQ2hFLGlDQUFpQztZQUNqQyxJQUFJLElBQUksR0FBRyxXQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsYUFBYSwwQ0FBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFMUMsTUFBTSxJQUFJLEdBQUcsTUFBTSwyREFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDdEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUU7b0JBQzFELHNFQUFzRTtvQkFDdEUsaUJBQWlCO29CQUNqQixJQUFJLEdBQUcsNERBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDaEM7YUFDRjtZQUVELG1FQUFtRTtZQUNuRSxJQUFJLGlFQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDbkQsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLG9FQUEyQixDQUMxRCxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUN0QyxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzVDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUVuRSxPQUFPO2FBQ1I7WUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFO2dCQUN0QixJQUFJO29CQUNGLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRTt3QkFDckQsT0FBTztxQkFDUjtpQkFDRjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDdEI7YUFDRjtZQUNELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQzthQUNwRDtpQkFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQzNCLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osV0FBVyxFQUFFO3dCQUNYLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVzt3QkFDdEIsS0FBSyxFQUFFLElBQUk7cUJBQ1o7aUJBQ0YsQ0FBQyxDQUFDO2FBQ0o7aUJBQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUN4QixJQUFJLENBQUMsNkJBQTZCLENBQUM7b0JBQ2pDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtvQkFDdkIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSTtvQkFDekIsUUFBUSxFQUFFLFFBQVE7aUJBQ25CLENBQUMsQ0FBQzthQUNKO2lCQUFNLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDcEIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNsQztZQUNELElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUMxQyxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsY0FBYyxFQUFFLENBQUM7UUFDMUIsQ0FBQyxFQUNGLENBQUM7UUFFTSxrQ0FBNkIsR0FBRyxDQUFDLElBSXhDLEVBQUUsRUFBRTtZQUNILE1BQU0sUUFBUSxHQUFHLCtEQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsMERBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUzRCxNQUFNLGVBQWUsR0FBRyxpREFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakQsTUFBTSxlQUFlLEdBQUcsaURBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWpELE1BQU0sT0FBTyxHQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO2dCQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO29CQUM1QixDQUFDLENBQUMsT0FBTztvQkFDVCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1lBQ25ELE1BQU0sT0FBTyxHQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO2dCQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO29CQUM1QixDQUFDLENBQUMsT0FBTztvQkFDVCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBRW5ELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsb0VBQTJCLENBQzFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUNwQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFFRixNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsZUFBZSxDQUFDO1lBQy9CLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUM7WUFDL0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUU3QixNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWpFLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN0QyxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQzNDLE1BQU0sVUFBVSxHQUFHLDJEQUFnQixDQUNqQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFDekIsVUFBVSxFQUNWLE9BQU8sRUFDUDtvQkFDRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSTtvQkFDM0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUk7aUJBQzVCLENBQ0YsQ0FBQztnQkFDRixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ25ELE9BQU8sVUFBVSxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsc0ZBQStCLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQzVFLE1BQU0sWUFBWSxHQUFHO2dCQUNuQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUU7Z0JBQzNDLEdBQUcsV0FBVzthQUNmLENBQUM7WUFDRiw4RUFBMkIsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLG1CQUFtQixDQUFDLENBQUM7WUFFekUsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNkLElBQUksQ0FBQyxLQUFLLG1DQUFRLElBQUksQ0FBQyxLQUFLLEdBQUssSUFBSSxDQUFDLEtBQUssQ0FBRSxDQUFDO2FBQy9DO1lBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRS9CLElBQUksQ0FBQyxRQUFRLENBQ1gseUVBQStCLGlDQUV4QixJQUFJLENBQUMsS0FBSyxLQUNiLGFBQWEsRUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQjtvQkFDekQsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CO29CQUNoQyxDQUFDLENBQUMsS0FBSyxFQUNYLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQ3BDLENBQUMsR0FBMEMsRUFBRSxPQUFPLEVBQUUsRUFBRTtvQkFDdEQsSUFBSSxDQUFDLHdFQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFO3dCQUNoQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztxQkFDeEI7b0JBQ0QsT0FBTyxHQUFHLENBQUM7Z0JBQ2IsQ0FBQyxFQUNELEVBQUUsQ0FDSCxFQUNELGdCQUFnQixFQUFFLEVBQUUsS0FFdEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUNuQyxFQUNELEdBQUcsRUFBRTtnQkFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7b0JBQ2QsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7aUJBQ2pDO1lBQ0gsQ0FBQyxDQUNGLENBQUM7WUFDRixJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDO1FBbUNGLGdCQUFnQjtRQUVoQixnQkFBVyxHQUFHLENBQUMsR0FBUSxFQUFFLEVBQUU7WUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQixDQUFDLENBQUM7UUFFRixrQkFBYSxHQUFHLENBQUMsS0FBcUQsRUFBRSxFQUFFO1lBQ3hFLElBQUksWUFBWSxFQUFFO2dCQUNoQixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQzthQUM5QjtZQUVELE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUM7UUFFRixlQUFVLEdBQUcsQ0FBQyxTQUE0QixJQUFJLEVBQUUsRUFBRTtZQUNoRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFO2dCQUNqQyxzREFBVSxDQUNSLFNBQVMsRUFDVCxZQUFZLEVBQ1osR0FBRyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQzdELENBQUM7YUFDSDtZQUNELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtnQkFDMUIsT0FBTztvQkFDTCxVQUFVLGdEQUNMLFNBQVMsQ0FBQyxVQUFVLEdBQ3BCLHlEQUFnQixDQUNqQixJQUFJLENBQUMsS0FBSyxFQUNWLFNBQVMsQ0FBQyxVQUFVLENBQUMsTUFBTTt3QkFDekIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTt3QkFDdkIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQ3pCLEtBQ0QsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQ3JDO2lCQUNGLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGLGtCQUFhLEdBQUcsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtnQkFDMUIsT0FBTztvQkFDTCxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTztpQkFDNUIsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsb0JBQWUsR0FBRyxDQUNoQixTQUVtQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ3JFLEVBQUU7WUFDRixJQUFJLENBQUMsUUFBUSxtQkFDUiw4REFBcUIsQ0FDdEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUN6QyxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxNQUFNLENBQ1osRUFDRCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsYUFBUSxHQUFHLENBQ1QsS0FJUSxFQUNSLEVBQUU7WUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUM7UUFFRix5QkFBb0IsR0FBRyxHQUFTLEVBQUU7WUFDaEMsSUFBSTtnQkFDRixNQUFNLG1CQUFtQixHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUVsRSxNQUFNLFFBQVEsR0FBRyxNQUFNLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDaEUsSUFBSSxRQUFRLEVBQUU7b0JBQ1osTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ25DLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQ3BFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQ2xDLE1BQU0sbUJBQW1CLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUNoRCxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsaURBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUN2RTthQUNGO1lBQUMsT0FBTyxLQUFVLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDaEQ7UUFDSCxDQUFDLEVBQUM7UUFFRiw0REFBNEQ7UUFDckQsYUFBUSxHQUF3QywyREFBa0IsQ0FDdkUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNSLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLEVBQUU7Z0JBQzlDLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDL0IsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQUUsSUFBSSxHQUFHLEVBQTBCLENBQUMsQ0FBQztZQUV0QyxJQUFJLENBQUMsS0FBSyxtQ0FBUSxJQUFJLENBQUMsS0FBSyxHQUFLLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUUsQ0FBQztZQUVoRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3JELElBQ0UsK0VBQXlCLENBQUMsT0FBTyxDQUFDO29CQUNsQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFDNUI7b0JBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN2QyxtRkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDcEM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFNUIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDbEMsQ0FBQyxDQUNGLENBQUM7UUFFSyxnQkFBVyxHQUFHLDJEQUFrQixDQUNyQyxDQUEyQixTQUsxQixFQUFFLEVBQUU7WUFDSCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDaEM7WUFFRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3RCLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ25DO1lBRUQsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFO2dCQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNuRDtZQUVELElBQUksU0FBUyxDQUFDLGFBQWEsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQzthQUMzRDtRQUNILENBQUMsQ0FDRixDQUFDO1FBRU0sbUJBQWMsR0FBRyxHQUFHLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUM7UUFFTSxnQ0FBMkIsR0FBRywyREFBa0IsQ0FDdEQsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDcEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDeEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDMUIsQ0FBQyxDQUNGLENBQUM7UUFFRixpQkFBaUI7UUFFVCxjQUFTLEdBQUcsMkRBQWtCLENBQ3BDLENBQUMsS0FBMEMsRUFBRSxFQUFFO1lBQzdDLHVEQUF1RDtZQUV2RCxJQUNFLE9BQU8sSUFBSSxNQUFNO2dCQUNqQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUM3QyxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUNoRDtnQkFDQSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO29CQUN2QixHQUFHLENBQUMsRUFBTyxFQUFFLElBQUk7d0JBQ2YsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN2QixJQUFJLE9BQU8sS0FBSyxLQUFLLFVBQVUsRUFBRTs0QkFDL0IsbUNBQW1DOzRCQUNuQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7eUJBQ3ZCO3dCQUNELE9BQU8sSUFBSSxLQUFLLEtBQUs7NEJBQ25CLENBQUMsQ0FBQywrREFBK0Q7Z0NBQy9ELFVBQVU7Z0NBQ1YsS0FBSyxDQUFDLFFBQVE7b0NBQ2QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFO29DQUN0QixDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUU7NEJBQ3hCLENBQUMsQ0FBQyxLQUFLLENBQUM7b0JBQ1osQ0FBQztpQkFDRixDQUFDLENBQUM7YUFDSjtZQUVELHVDQUF1QztZQUN2QyxJQUFJLEtBQUssQ0FBQyxvREFBZ0IsQ0FBQyxJQUFJLDBEQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDOUQsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLCtDQUFXLElBQUksS0FBSyxDQUFDLElBQUksS0FBSywrQ0FBVyxFQUFFO29CQUM1RCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3ZCLE9BQU87aUJBQ1I7YUFDRjtZQUVELFVBQVU7WUFDVjtZQUNFLGtCQUFrQjtZQUNsQixDQUFDLDBEQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7Z0JBQzlCLDJDQUEyQztnQkFDM0MsS0FBSyxDQUFDLEdBQUcsS0FBSywrQ0FBVyxDQUFDO2dCQUM1QixtREFBbUQ7Z0JBQ25ELENBQUMsa0RBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksb0RBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDcEQ7Z0JBQ0EsT0FBTzthQUNSO1lBRUQsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLHNEQUFrQixFQUFFO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGNBQWMsRUFBRSxJQUFJO2lCQUNyQixDQUFDLENBQUM7YUFDSjtZQUVELElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzNDLE9BQU87YUFDUjtZQUVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7Z0JBQzlCLE9BQU87YUFDUjtZQUVELElBQUksS0FBSyxDQUFDLG9EQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDNUM7WUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssOENBQVUsRUFBRTtnQkFDN0IsTUFBTSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztnQkFDNUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QyxzQkFBc0I7Z0JBQ3RCLElBQUksU0FBUyxFQUFFO29CQUNiLHNEQUFVLENBQ1IsU0FBUyxFQUNULHNCQUFzQixFQUN0QixhQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUM1RCxDQUFDO2lCQUNIO2FBQ0Y7WUFFRCxJQUFJLGtEQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUN6QixNQUFNLElBQUksR0FDUixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUTtvQkFDbEIsQ0FBQyxLQUFLLENBQUMsUUFBUTt3QkFDYixDQUFDLENBQUMsaUVBQXdCO3dCQUMxQixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDM0IsQ0FBQyxLQUFLLENBQUMsUUFBUTt3QkFDYixDQUFDLENBQUMsdUVBQThCO3dCQUNoQyxDQUFDLENBQUMsaUVBQXdCLENBQUMsQ0FBQztnQkFFaEMsTUFBTSxnQkFBZ0IsR0FBRyw0REFBbUIsQ0FDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxFQUNsQyxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FDTCxDQUFDO2dCQUVGLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztnQkFDaEIsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO2dCQUVoQixJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssbURBQWUsRUFBRTtvQkFDakMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO2lCQUNqQjtxQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssb0RBQWdCLEVBQUU7b0JBQ3pDLE9BQU8sR0FBRyxJQUFJLENBQUM7aUJBQ2hCO3FCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxpREFBYSxFQUFFO29CQUN0QyxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7aUJBQ2pCO3FCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxtREFBZSxFQUFFO29CQUN4QyxPQUFPLEdBQUcsSUFBSSxDQUFDO2lCQUNoQjtnQkFFRCxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtvQkFDbkMsc0VBQWEsQ0FBQyxPQUFPLEVBQUU7d0JBQ3JCLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU87d0JBQ3RCLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU87cUJBQ3ZCLENBQUMsQ0FBQztvQkFFSCxzRUFBbUIsQ0FBQyxPQUFPLEVBQUU7d0JBQzNCLHFCQUFxQixFQUFFLGdCQUFnQjtxQkFDeEMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUVILElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUVqRCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7aUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLDhDQUFVLEVBQUU7Z0JBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUVGLElBQUksZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDakMsSUFBSSxxRUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7d0JBQ3hDLElBQ0UsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjs0QkFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTO2dDQUN2QyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQ3hCOzRCQUNBLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7NEJBQy9CLElBQUksQ0FBQyxRQUFRLENBQUM7Z0NBQ1osb0JBQW9CLEVBQUUsSUFBSSw4RUFBbUIsQ0FDM0MsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQ25CLElBQUksQ0FBQyxLQUFLLENBQ1g7NkJBQ0YsQ0FBQyxDQUFDO3lCQUNKO3FCQUNGO3lCQUFNO3dCQUNMLE1BQU0sZUFBZSxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUU1QyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7NEJBQ3BCLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQzs0QkFDckQsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDOzRCQUN0RCxVQUFVLEVBQUUsSUFBSTt5QkFDakIsQ0FBQyxDQUFDO3dCQUNILEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQzt3QkFDdkIsT0FBTztxQkFDUjtpQkFDRjthQUNGO2lCQUFNLElBQ0wsQ0FBQyxLQUFLLENBQUMsT0FBTztnQkFDZCxDQUFDLEtBQUssQ0FBQyxNQUFNO2dCQUNiLENBQUMsS0FBSyxDQUFDLE9BQU87Z0JBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssSUFBSSxFQUNuQztnQkFDQSxNQUFNLEtBQUssR0FBRyx3REFBYyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDeEMsSUFBSSxLQUFLLEVBQUU7b0JBQ1QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFO3dCQUN4QyxzREFBVSxDQUNSLFNBQVMsRUFDVCxLQUFLLEVBQ0wsYUFBYSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FDNUQsQ0FBQztxQkFDSDtvQkFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7b0JBQ3BDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDekI7cUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLDBDQUFNLEVBQUU7b0JBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQzVCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDekI7YUFDRjtZQUNELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyw4Q0FBVSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtnQkFDM0QsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDdEIsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDZEQUFvQixDQUFDLENBQUM7Z0JBQzdDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN4QjtZQUVELElBQ0UsQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLDBDQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSywwQ0FBTSxDQUFDO2dCQUM5QyxDQUFDLEtBQUssQ0FBQyxNQUFNO2dCQUNiLENBQUMsS0FBSyxDQUFDLG9EQUFnQixDQUFDLEVBQ3hCO2dCQUNBLE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUNGLElBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLFdBQVc7b0JBQzFDLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUN4QjtvQkFDQSxPQUFPO2lCQUNSO2dCQUVELElBQ0UsS0FBSyxDQUFDLEdBQUcsS0FBSywwQ0FBTTtvQkFDcEIsQ0FBQyxzREFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQzt3QkFDeEMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxzREFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ2xFO29CQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDO29CQUN0RCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7aUJBQ3pCO2dCQUNELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSywwQ0FBTSxFQUFFO29CQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQztvQkFDbEQsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO2lCQUN6QjthQUNGO1FBQ0gsQ0FBQyxDQUNGLENBQUM7UUFFTSxZQUFPLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDekQsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLFlBQVksaUJBQWlCLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFO2dCQUNqRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVLLFlBQU8sR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQW9CLEVBQUUsRUFBRTtZQUM1RCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssOENBQVUsRUFBRTtnQkFDNUIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtvQkFDOUIsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlEQUFnQixDQUFDLENBQUM7aUJBQzFDO3FCQUFNLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRTtvQkFDckQsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQzFCO3FCQUFNO29CQUNMLDBEQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDO3dCQUNaLGtCQUFrQixFQUFFLEVBQUU7d0JBQ3RCLGdCQUFnQixFQUFFLEVBQUU7d0JBQ3BCLGNBQWMsRUFBRSxJQUFJO3FCQUNyQixDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsY0FBYyxHQUFHLEtBQUssQ0FBQzthQUN4QjtZQUNELElBQUksQ0FBQyxLQUFLLENBQUMsb0RBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxrREFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDekIsTUFBTSxnQkFBZ0IsR0FBRyw0REFBbUIsQ0FDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxFQUNsQyxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDMUIsQ0FBQyxDQUFDLCtFQUE0QixDQUFDLGdCQUFnQixDQUFDO29CQUNoRCxDQUFDLENBQUMsdUVBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDM0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDMUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVLLGtCQUFhLEdBQUcsQ0FDdEIsSUFFMEMsRUFDMUMsRUFBRTtZQUNGLE1BQU0sY0FBYyxHQUFHLHlEQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLGNBQWMsRUFBRTtnQkFDbkIsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDNUM7WUFDRCxJQUFJLG1EQUFVLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUN0QyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdkI7WUFDRCxJQUFJLENBQUMseUVBQW1CLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUMxQztZQUNELElBQUksY0FBYyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUN0QjtZQUNELElBQUksY0FBYyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osVUFBVSxFQUFFLGNBQWM7b0JBQzFCLGtCQUFrQixFQUFFLEVBQUU7b0JBQ3RCLGdCQUFnQixFQUFFLEVBQUU7b0JBQ3BCLGNBQWMsRUFBRSxJQUFJO2lCQUNyQixDQUFDLENBQUM7YUFDSjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7YUFDL0M7UUFDSCxDQUFDLENBQUM7UUFFTSxjQUFTLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRTtZQUNyQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDO1FBRU0sZ0JBQVcsR0FBRyxHQUFHLEVBQUU7WUFDekIsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDO1FBQ0Y7Ozs7O1dBS0c7UUFDSyxtQ0FBOEIsR0FBRyxHQUFHLEVBQUU7WUFDNUMsMEVBQTBFO1lBQzFFLDJFQUEyRTtZQUMzRSxjQUFjO1lBQ2QsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDO1FBRUYsdUJBQXVCO1FBQ2YsbUJBQWMsR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQW1CLEVBQUUsRUFBRTtZQUNsRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFdkIsMkVBQTJFO1lBQzNFLG9DQUFvQztZQUNwQyxJQUFJLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxFQUFFO2dCQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGtCQUFrQixFQUFFLEVBQUU7aUJBQ3ZCLENBQUMsQ0FBQzthQUNKO1lBQ0QsT0FBTyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCx1QkFBdUI7UUFDZixvQkFBZSxHQUFHLDJEQUFrQixDQUFDLENBQUMsS0FBbUIsRUFBRSxFQUFFO1lBQ25FLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUV2QiwyREFBMkQ7WUFDM0QscUVBQXFFO1lBQ3JFLHlEQUF5RDtZQUN6RCw2QkFBNkI7WUFDN0IsRUFBRTtZQUNGLHlFQUF5RTtZQUN6RSw0QkFBNEI7WUFDNUIsRUFBRTtZQUNGLG9EQUFvRDtZQUNwRCxJQUFJLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxFQUFFO2dCQUN6QyxPQUFPO2FBQ1I7WUFFRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO1lBQzFDLElBQUksWUFBWSxFQUFFO2dCQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxtQkFDcEIsNkRBQWUsQ0FDaEI7b0JBQ0UsU0FBUyxFQUFFLE9BQU87b0JBQ2xCLFNBQVMsRUFBRSxPQUFPO29CQUNsQixRQUFRLEVBQUUsMERBQWlCLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7aUJBQ3hELEVBQ0QsS0FBSyxDQUNOLEVBQ0QsQ0FBQyxDQUFDO2FBQ0w7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILHVCQUF1QjtRQUNmLGlCQUFZLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFtQixFQUFFLEVBQUU7WUFDaEUsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLCtEQUErRDtZQUMvRCxJQUFJLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxFQUFFO2dCQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLDBCQUEwQixFQUFFLEVBQUU7b0JBQzlCLGtCQUFrQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsMEJBQTBCO2lCQUMxRCxDQUFDLENBQUM7YUFDSjtZQUNELE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO1FBMkxLLHFCQUFnQixHQUFHLENBQUMsRUFDMUIsTUFBTSxFQUNOLE1BQU0sRUFDTixVQUFVLEVBQ1Ysb0JBQW9CLEdBQUcsSUFBSSxHQVM1QixFQUFFLEVBQUU7O1lBQ0gsSUFBSSxvQkFBb0IsR0FDdEIsb0JBQW9CO2dCQUNwQixJQUFJLENBQUMscUNBQXFDLENBQ3hDLE1BQU0sRUFDTixNQUFNLEVBQ04sSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsTUFBTSxFQUNYLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FDeEIsQ0FBQztZQUVKLElBQUksbUJBQW1CLEdBQTZDLElBQUksQ0FBQztZQUN6RSxJQUFJLFNBQVMsR0FBbUMsSUFBSSxDQUFDO1lBRXJELE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1lBRUYsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUNqQyxJQUFJLHdEQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDdEMsbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQzNDO3FCQUFNLElBQUksNkVBQXVCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQzlELG1CQUFtQixHQUFHLDBFQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2hFO3FCQUFNO29CQUNMLG1CQUFtQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7aUJBQ3JFO2FBQ0Y7aUJBQU07Z0JBQ0wsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQzthQUNyRTtZQUVELCtDQUErQztZQUMvQyxpQ0FBaUM7WUFDakMsSUFDRSxDQUFDLFNBQVM7Z0JBQ1YsQ0FBQyxtQkFBbUI7Z0JBQ3BCLENBQUMsVUFBVSxJQUFJLG9CQUFvQixDQUFDLEVBQ3BDO2dCQUNBLFNBQVMsR0FBRywyRUFBa0MsQ0FDNUMsSUFBSSxDQUFDLEtBQUs7cUJBQ1AscUJBQXFCLEVBQUU7cUJBQ3ZCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQ04sNkVBQXVCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsMEVBQW1CLENBQUMsR0FBRyxDQUFDLENBQ25FLEVBQ0gsTUFBTSxFQUNOLE1BQU0sQ0FDUCxDQUFDO2FBQ0g7WUFFRCxJQUFJLENBQUMsbUJBQW1CLElBQUksU0FBUyxFQUFFO2dCQUNyQyxNQUFNLFVBQVUsR0FBRztvQkFDakIsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CO29CQUN4QyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUI7aUJBQzdDLENBQUM7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsNEVBQXFCLENBQUMsc0RBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxNQUFNLFNBQVMsR0FBRyw2RUFBc0IsQ0FBQyxzREFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNyRCxzRUFBYSxDQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFFBQVEsR0FBRyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JDLElBQUksb0JBQW9CLEVBQUU7b0JBQ3hCLG9CQUFvQixHQUFHLElBQUksQ0FBQyxxQ0FBcUMsQ0FDL0QsTUFBTSxFQUNOLE1BQU0sRUFDTixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxNQUFNLEVBQ1gsTUFBTSxDQUFDLGdCQUFnQixDQUN4QixDQUFDO2lCQUNIO2FBQ0Y7WUFFRCxNQUFNLE9BQU8sR0FBRyxtQkFBbUI7Z0JBQ2pDLENBQUMsQ0FBQyxtQkFBbUI7Z0JBQ3JCLENBQUMsQ0FBQyx5REFBYyxDQUFDO29CQUNiLENBQUMsRUFBRSxvQkFBb0I7d0JBQ3JCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjO3dCQUNyQyxDQUFDLENBQUMsTUFBTTtvQkFDVixDQUFDLEVBQUUsb0JBQW9CO3dCQUNyQixDQUFDLENBQUMsb0JBQW9CLENBQUMsY0FBYzt3QkFDckMsQ0FBQyxDQUFDLE1BQU07b0JBQ1YsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7b0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7b0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO29CQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7b0JBQ3RELElBQUksRUFBRSxFQUFFO29CQUNSLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtvQkFDeEMsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO29CQUM1QyxTQUFTLEVBQUUsb0JBQW9CO3dCQUM3QixDQUFDLENBQUMsUUFBUTt3QkFDVixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7b0JBQ25DLGFBQWEsRUFBRSxvQkFBb0I7d0JBQ2pDLENBQUMsQ0FBQyw4REFBcUI7d0JBQ3ZCLENBQUMsQ0FBQywrREFBc0I7b0JBQzFCLFdBQVcsRUFBRSxlQUFTLGFBQVQsU0FBUyx1QkFBVCxTQUFTLENBQUUsRUFBRSxtQ0FBSSxTQUFTO29CQUN2QyxRQUFRLEVBQUUsZUFBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLFFBQVEsbUNBQUksRUFBRTtvQkFDbkMsTUFBTSxFQUFFLEtBQUs7aUJBQ2QsQ0FBQyxDQUFDO1lBRVAsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBRTNDLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtnQkFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztvQkFDNUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFO29CQUMzQyxPQUFPO2lCQUNSLENBQUMsQ0FBQztnQkFFSCxvRUFBb0U7Z0JBQ3BFLGtEQUFrRDtnQkFDbEQsSUFBSSxDQUFDLG9CQUFvQixFQUFFO29CQUN6QixzRUFBYSxDQUFDLE9BQU8sRUFBRTt3QkFDckIsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDO3FCQUNwQyxDQUFDLENBQUM7aUJBQ0o7YUFDRjtZQUVELElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1osY0FBYyxFQUFFLE9BQU87YUFDeEIsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRTtnQkFDOUIsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLG1CQUFtQjthQUN6QyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFFTSw0QkFBdUIsR0FBRyxDQUNoQyxLQUEwQyxFQUMxQyxFQUFFO1lBQ0Ysd0VBQXdFO1lBQ3hFLG1DQUFtQztZQUNuQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO2dCQUMzQixPQUFPO2FBQ1I7WUFDRCxnRUFBZ0U7WUFDaEUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFO2dCQUM5QyxPQUFPO2FBQ1I7WUFFRCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUVGLElBQUksZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxxRUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pFLElBQ0UsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLEtBQUssZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUNwRTtvQkFDQSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO29CQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDO3dCQUNaLG9CQUFvQixFQUFFLElBQUksOEVBQW1CLENBQzNDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxFQUNuQixJQUFJLENBQUMsS0FBSyxDQUNYO3FCQUNGLENBQUMsQ0FBQztpQkFDSjtnQkFDRCxPQUFPO2FBQ1I7WUFFRCxvREFBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUV6QixJQUFJLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsb0VBQTJCLENBQ3hELEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFFRixNQUFNLGdCQUFnQixHQUFHLDZEQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV6RCxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQy9CLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBRTdELE1BQU0sZUFBZSxHQUNuQixVQUFVO29CQUNWLHNFQUE0QixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBRXhFLElBQUksZUFBZSxFQUFFO29CQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FDMUIseUVBQStCLGlDQUV4QixTQUFTLEtBQ1osY0FBYyxFQUFFLGVBQWUsRUFDL0Isa0JBQWtCLEVBQUUsRUFBRSxDQUFDLFVBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFDOUMsZ0JBQWdCLEVBQUUsRUFBRSxLQUV0QixJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQ25DLENBQ0YsQ0FBQztvQkFDRixPQUFPO2lCQUNSO2FBQ0Y7WUFFRCxvREFBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLG9EQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtnQkFDM0QsTUFBTSxnQkFBZ0IsR0FBRyw0REFBbUIsQ0FDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxFQUNsQyxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNqQyxNQUFNLGVBQWUsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTSxXQUFXLEdBQUcseUVBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ3pELElBQUksV0FBVyxFQUFFO3dCQUNmLE1BQU0sR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO3dCQUN2RCxNQUFNLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztxQkFDekQ7aUJBQ0Y7Z0JBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDO29CQUNwQixNQUFNO29CQUNOLE1BQU07b0JBQ04sVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLG9CQUFvQixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU07aUJBQ3BDLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sNkJBQXdCLEdBQUcsQ0FDakMsWUFBZ0QsRUFDaEQsVUFBOEMsRUFDZixFQUFFO1lBQ2pDLDREQUE0RDtZQUM1RCxhQUFhO1lBQ2IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RFLElBQUksZUFBZSxHQUFHLFFBQVEsQ0FBQztZQUUvQixPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ3RDLElBQUksVUFBVSxJQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssVUFBVSxDQUFDLEVBQUUsRUFBRTtvQkFDOUMsZUFBZSxHQUFHLEtBQUssQ0FBQztpQkFDekI7Z0JBQ0QsT0FBTyxDQUNMLE9BQU8sQ0FBQyxJQUFJO29CQUNaLEtBQUssSUFBSSxlQUFlO29CQUN4QiwyRUFBc0IsQ0FDcEIsT0FBTyxFQUNQLElBQUksQ0FBQyxLQUFLLEVBQ1YsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFDaEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQ3JCLENBQ0YsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRU0sbUJBQWMsR0FBRyxDQUN2QixLQUE0QyxFQUM1QyxhQUFzQixFQUN0QixFQUFFO1lBQ0YsTUFBTSxlQUFlLEdBQUcsa0RBQVUsQ0FDaEMsSUFBSSxDQUFDLGVBQWdCLENBQUMsT0FBTyxFQUM3QixJQUFJLENBQUMsZUFBZ0IsQ0FBQyxPQUFPLEVBQzdCLElBQUksQ0FBQyxhQUFjLENBQUMsT0FBTyxFQUMzQixJQUFJLENBQUMsYUFBYyxDQUFDLE9BQU8sQ0FDNUIsQ0FBQztZQUNGLElBQ0UsQ0FBQyxJQUFJLENBQUMsY0FBYztnQkFDcEIsOERBQThEO2dCQUM5RCxDQUFDLGFBQWEsSUFBSSxlQUFlLEdBQUcsMkRBQWtCLENBQUM7Z0JBQ3ZELENBQUMsQ0FBQyxhQUFhLElBQUksZUFBZSxLQUFLLENBQUMsQ0FBQyxFQUN6QztnQkFDQSxPQUFPO2FBQ1I7WUFDRCxNQUFNLHFCQUFxQixHQUFHLG9FQUEyQixDQUN2RCxJQUFJLENBQUMsZUFBZ0IsRUFDckIsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1lBQ0YsTUFBTSw4QkFBOEIsR0FBRywyRUFBc0IsQ0FDM0QsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLEtBQUssRUFDVixDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQ3JCLENBQUM7WUFDRixNQUFNLG1CQUFtQixHQUFHLG9FQUEyQixDQUNyRCxJQUFJLENBQUMsYUFBYyxFQUNuQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFDRixNQUFNLDRCQUE0QixHQUFHLDJFQUFzQixDQUN6RCxJQUFJLENBQUMsY0FBYyxFQUNuQixJQUFJLENBQUMsS0FBSyxFQUNWLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxFQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FDckIsQ0FBQztZQUNGLElBQUksOEJBQThCLElBQUksNEJBQTRCLEVBQUU7Z0JBQ2xFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDO2dCQUNyQyxJQUFJLEdBQUcsRUFBRTtvQkFDUCxJQUFJLFdBQVcsQ0FBQztvQkFDaEIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRTt3QkFDekIsV0FBVyxHQUFHLGtEQUFTLENBQUMsOERBQXFCLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO3dCQUNsRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLFdBQVcsQ0FBQyxDQUFDO3FCQUN6RDtvQkFDRCxJQUFJLENBQUMsWUFBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLGdCQUFnQixHQUFFO3dCQUNsQyxNQUFNLE1BQU0sR0FBRyxnRUFBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQzt3QkFDckQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7d0JBQ2pELGdEQUFnRDt3QkFDaEQsSUFBSSxTQUFTLEVBQUU7NEJBQ2IsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7NEJBQ3hCLFNBQVMsQ0FBQyxRQUFRLEdBQUcsa0VBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQzt5QkFDekM7cUJBQ0Y7aUJBQ0Y7YUFDRjtRQUNILENBQUMsQ0FBQztRQUVNLDRCQUF1QixHQUFHLENBQ2hDLEtBQTRDLEVBQzVDLEVBQUU7O1lBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN4RSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDekMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTtvQkFDcEMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUNoQixDQUFDLEVBQUUsS0FBSyxDQUFDLE9BQU87aUJBQ2pCLENBQUMsQ0FBQzthQUNKO1lBRUQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztZQUMxQyxJQUNFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxVQUFVO2dCQUNsQixZQUFZO2dCQUNaLE9BQU8sQ0FBQyxlQUFlLEVBQ3ZCO2dCQUNBLE1BQU0sTUFBTSxHQUFHLG9EQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMzQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxPQUFPLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztnQkFFNUIsTUFBTSxRQUFRLEdBQUcsc0RBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNwRSxNQUFNLFdBQVcsR0FDZixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTztvQkFDN0QsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsQ0FBQyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO2dCQUV6QyxNQUFNLFFBQVEsR0FBRyxXQUFXO29CQUMxQixDQUFDLENBQUMsMERBQWlCLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztvQkFDL0MsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFFMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUN0QixNQUFNLFNBQVMsR0FBRyw2REFBZSxDQUMvQjt3QkFDRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7d0JBQ25CLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQzt3QkFDbkIsUUFBUTtxQkFDVCxFQUNELEtBQUssQ0FDTixDQUFDO29CQUVGLE9BQU87d0JBQ0wsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO3dCQUNwQixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsUUFBUTt3QkFDOUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPLEdBQUcsTUFBTSxHQUFHLFFBQVE7d0JBQzlDLHFCQUFxQixFQUFFLElBQUk7cUJBQzVCLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLG1DQUFtQyxFQUFFLENBQUM7YUFDNUM7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLFVBQVU7b0JBQ2hCLE9BQU8sQ0FBQyxlQUFlO3dCQUN2QixPQUFPLENBQUMsWUFBWTs0QkFDbEIsSUFBSSxDQUFDO2FBQ1Y7WUFFRCxJQUFJLGNBQWMsSUFBSSxTQUFTLElBQUksbUJBQW1CLEVBQUU7Z0JBQ3RELE9BQU87YUFDUjtZQUVELE1BQU0sdUJBQXVCLEdBQUcseURBQWdCLENBQzlDLGlCQUFpQixFQUNqQixLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUNyQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUNyQyxDQUFDO1lBQ0YsTUFBTSxlQUFlLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO2dCQUMzRCxJQUFJLGVBQWUsRUFBRTtvQkFDbkIsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQzFCO3FCQUFNO29CQUNMLDBEQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUM1QzthQUNGO1lBRUQsTUFBTSxZQUFZLEdBQUcsb0VBQTJCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEdBQUcsWUFBWSxDQUFDO1lBRTVELElBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQy9CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQzNDO2dCQUNBLE1BQU0sb0JBQW9CLEdBQUcsZ0dBQXFDLENBQ2hFLEtBQUssRUFDTCxhQUFhLEVBQ2IsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQy9CLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO2dCQUNGLElBQUksb0JBQW9CLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTtvQkFDNUQsc0VBQXNFO29CQUN0RSx5RUFBeUU7b0JBQ3pFLCtGQUErRjtvQkFDL0Ysb0RBQVMsQ0FBQyxHQUFHLEVBQUU7d0JBQ2IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLG9CQUFvQixFQUFFLENBQUMsQ0FBQztvQkFDMUMsQ0FBQyxDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsSUFBSSxvQkFBb0IsQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLEVBQUU7b0JBQ3JELElBQUksQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDaEQ7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7aUJBQzFDO2FBQ0Y7WUFFRCxJQUFJLDBFQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNwRCx5RUFBeUU7Z0JBQ3pFLFlBQVk7Z0JBQ1osTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3ZDLElBQUksc0VBQWdCLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUM1QyxJQUFJLENBQUMsNENBQTRDLENBQy9DLGVBQWUsRUFDZixDQUFDLFlBQVksQ0FBQyxFQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQzdCLENBQUM7aUJBQ0g7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUNoRDthQUNGO1lBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRTtnQkFDM0IsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3BDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxZQUFZLENBQUM7Z0JBRXRDLE1BQU0sRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsR0FBRyxZQUFZLENBQUM7Z0JBQ3BELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUU1QywwREFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFM0MsSUFBSSxTQUFTLEtBQUssa0JBQWtCLEVBQUU7b0JBQ3BDLHNFQUFzRTtvQkFDdEUseUJBQXlCO29CQUN6QixJQUNFLGtEQUFVLENBQ1IsYUFBYSxHQUFHLEVBQUUsRUFDbEIsYUFBYSxHQUFHLEVBQUUsRUFDbEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUNaLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FDYixJQUFJLCtEQUFzQixFQUMzQjt3QkFDQSxzRUFBYSxDQUFDLFlBQVksRUFBRTs0QkFDMUIsTUFBTSxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxhQUFhLEdBQUcsRUFBRSxFQUFFLGFBQWEsR0FBRyxFQUFFLENBQUMsQ0FBQzt5QkFDOUQsQ0FBQyxDQUFDO3FCQUNKO3lCQUFNO3dCQUNMLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO3dCQUM1QyxtRUFBbUU7d0JBQ25FLDJEQUEyRDtxQkFDNUQ7aUJBQ0Y7cUJBQU0sSUFDTCxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7b0JBQ2pCLGtCQUFrQjtvQkFDbEIsa0RBQVUsQ0FDUixhQUFhLEdBQUcsRUFBRSxFQUNsQixhQUFhLEdBQUcsRUFBRSxFQUNsQixrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFDckIsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQ3RCLEdBQUcsK0RBQXNCLEVBQzFCO29CQUNBLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO29CQUM1QyxzRUFBYSxDQUFDLFlBQVksRUFBRTt3QkFDMUIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUM1QixDQUFDLENBQUM7aUJBQ0o7cUJBQU07b0JBQ0wsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxhQUFhLEVBQ2IsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO29CQUVGLE1BQU0sQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDLEdBQ3BDLGtCQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsa0JBQWtCLG1DQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUU3QyxJQUFJLG1CQUFtQixHQUFHLEtBQUssR0FBRyxFQUFFLEdBQUcsY0FBYyxDQUFDO29CQUN0RCxJQUFJLG1CQUFtQixHQUFHLEtBQUssR0FBRyxFQUFFLEdBQUcsY0FBYyxDQUFDO29CQUV0RCxJQUFJLHFFQUE2QixDQUFDLEtBQUssQ0FBQyxFQUFFO3dCQUN4QyxDQUFDLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRTs0QkFDMUQseUVBQThCOzRCQUM1QixnREFBZ0Q7NEJBQ2hELGNBQWMsR0FBRyxFQUFFLEVBQ25CLGNBQWMsR0FBRyxFQUFFOzRCQUNuQix5QkFBeUI7NEJBQ3pCLEtBQUssRUFDTCxLQUFLLENBQ04sQ0FBQyxDQUFDO3FCQUNOO29CQUVELElBQUksbURBQVcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7d0JBQzlDLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO3FCQUM3QztvQkFDRCxnQ0FBZ0M7b0JBQ2hDLHNFQUFhLENBQUMsWUFBWSxFQUFFO3dCQUMxQixNQUFNLEVBQUU7NEJBQ04sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs0QkFDdEI7Z0NBQ0UsY0FBYyxHQUFHLG1CQUFtQjtnQ0FDcEMsY0FBYyxHQUFHLG1CQUFtQjs2QkFDckM7eUJBQ0Y7cUJBQ0YsQ0FBQyxDQUFDO2lCQUNKO2dCQUVELE9BQU87YUFDUjtZQUVELE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuRCxJQUNFLG1CQUFtQjtnQkFDbkIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssV0FBVztvQkFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLE1BQU07b0JBQ3JDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsRUFDMUM7Z0JBQ0EsT0FBTzthQUNSO1lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBRXBELE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNuRSxJQUNFLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUM3QixDQUFDLGVBQWU7Z0JBQ2hCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFDaEM7Z0JBQ0EsTUFBTSw4QkFBOEIsR0FBRyw0RUFBaUMsQ0FDdEUsUUFBUSxFQUNSLElBQUksQ0FBQyxLQUFLLEVBQ1YsYUFBYSxFQUNiLGFBQWEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFDZixLQUFLLENBQUMsV0FBVyxDQUNsQixDQUFDO2dCQUNGLElBQ0UsOEJBQThCO29CQUM5Qiw4QkFBOEIsQ0FBQyxtQkFBbUIsRUFDbEQ7b0JBQ0Esa0RBQVMsQ0FDUCxJQUFJLENBQUMsTUFBTSxFQUNYLHNFQUEyQixDQUFDLDhCQUE4QixDQUFDLENBQzVELENBQUM7b0JBQ0YsT0FBTztpQkFDUjthQUNGO2lCQUFNLElBQUksZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDMUQsTUFBTSxtQkFBbUIsR0FBRywyRUFBZ0MsQ0FDMUQsMERBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUNqQyxhQUFhLEVBQ2IsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNmLEtBQUssQ0FBQyxXQUFXLENBQ2xCLENBQUM7Z0JBQ0YsSUFBSSxtQkFBbUIsRUFBRTtvQkFDdkIsa0RBQVMsQ0FDUCxJQUFJLENBQUMsTUFBTSxFQUNYLHNFQUEyQixDQUFDO3dCQUMxQixtQkFBbUI7cUJBQ3BCLENBQUMsQ0FDSCxDQUFDO29CQUNGLE9BQU87aUJBQ1I7YUFDRjtZQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FDMUMsWUFBWSxDQUFDLENBQUMsRUFDZCxZQUFZLENBQUMsQ0FBQyxDQUNmLENBQUM7WUFDRixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FDakQsWUFBWSxFQUNaLFVBQVUsQ0FDWCxDQUFDO1lBQ0YsSUFBSSwwREFBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDOUIsT0FBTzthQUNSO1lBQ0QsSUFDRSxJQUFJLENBQUMsY0FBYztnQkFDbkIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQ3REO2dCQUNBLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO2dCQUM1Qyx5RUFBb0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN2RDtpQkFBTTtnQkFDTCx3RUFBbUIsRUFBRSxDQUFDO2dCQUN0QixJQUNFLFVBQVU7b0JBQ1YsVUFBVSxDQUFDLElBQUk7b0JBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUM1QyxDQUFDLElBQUksQ0FBQyxlQUFlO29CQUNyQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQzlCO29CQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUMvQztxQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7b0JBQ2hELGtEQUFTLENBQ1AsSUFBSSxDQUFDLE1BQU0sRUFDWCx3REFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyx5REFBZ0IsQ0FBQyxDQUFDLENBQUMsOERBQXFCLENBQ3JFLENBQUM7aUJBQ0g7cUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtvQkFDckMsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlEQUFnQixDQUFDLENBQUM7aUJBQzFDO3FCQUFNLElBQUksZUFBZSxFQUFFO29CQUMxQixrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQztpQkFDMUM7cUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFO29CQUMzQyxJQUFJLENBQUMsZ0NBQWdDLENBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQ2hDLGFBQWEsRUFDYixhQUFhLENBQ2QsQ0FBQztpQkFDSDtxQkFBTTtnQkFDTCx3Q0FBd0M7Z0JBQ3hDLENBQUMsS0FBSyxDQUFDLG9EQUFnQixDQUFDO29CQUN4QixDQUFDLFVBQVU7d0JBQ1QsSUFBSSxDQUFDLDRDQUE0QyxDQUMvQyxZQUFZLEVBQ1osZ0JBQWdCLENBQ2pCLENBQUM7b0JBQ0osQ0FBQyxXQUFVLGFBQVYsVUFBVSx1QkFBVixVQUFVLENBQUUsTUFBTSxHQUNuQjtvQkFDQSxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQztpQkFDMUM7cUJBQU07b0JBQ0wsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlEQUFnQixDQUFDLENBQUM7aUJBQzFDO2FBQ0Y7UUFDSCxDQUFDLENBQUM7UUFFTSxpQkFBWSxHQUFHLENBQ3JCLEtBQW1CLEVBQ25CLGdCQUFrQyxFQUNsQyxZQUFzQyxFQUN0QyxFQUFFO1lBQ0YsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQTZCLEVBQUUsRUFBRTtnQkFDekQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO29CQUMzQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7d0JBQ2xCLE9BQU87cUJBQ1I7b0JBRUQsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQzdCLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDaEIsSUFDRSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDOzRCQUM5QyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUNwRDs0QkFDQSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQzt5QkFDOUQ7cUJBQ0Y7eUJBQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTt3QkFDMUQsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHOzRCQUMvQyxLQUFLLEVBQUUsSUFBSTs0QkFDWCxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87eUJBQ3pCLENBQUM7cUJBQ0g7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUM7WUFFRixNQUFNLFdBQVcsR0FBa0IsRUFBRSxDQUFDO1lBRXRDLE1BQU0sUUFBUSxHQUFHLGtEQUFVLENBQ3pCLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQzdCLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQzdCLFlBQVksQ0FBQyxDQUFDLEVBQ2QsWUFBWSxDQUFDLENBQUMsQ0FDZixDQUFDO1lBQ0YsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM3QyxNQUFNLEtBQUsscUJBQVEsZ0JBQWdCLENBQUMsVUFBVSxDQUFFLENBQUM7WUFDakQsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFDekIsT0FBTyxnQkFBZ0IsSUFBSSxRQUFRLEVBQUU7Z0JBQ25DLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakUsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBRTlCLHNDQUFzQztnQkFDdEMsSUFBSSxnQkFBZ0IsS0FBSyxRQUFRLEVBQUU7b0JBQ2pDLE1BQU07aUJBQ1A7Z0JBRUQsc0VBQXNFO2dCQUN0RSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFFcEUsTUFBTSxhQUFhLEdBQUcsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO2dCQUNsRCxNQUFNLEtBQUssR0FDVCxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLGFBQWEsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNqRSxNQUFNLEtBQUssR0FDVCxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLGFBQWEsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNqRSxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztnQkFDaEIsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7YUFDakI7WUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ3BFLE1BQU0sRUFBRSxHQUNOLHdFQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztvQkFDOUQsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXO29CQUNqQixDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDYixJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUU7b0JBQzVCLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDaEIsSUFDRSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7NEJBQ3RDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQ3REOzRCQUNBLE9BQU8sdUVBQWMsQ0FBQyxHQUFHLEVBQUU7Z0NBQ3pCLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPOzZCQUN4RCxDQUFDLENBQUM7eUJBQ0o7cUJBQ0Y7eUJBQU07d0JBQ0wsT0FBTyx1RUFBYyxDQUFDLEdBQUcsRUFBRTs0QkFDekIsT0FBTyxFQUFFLHVFQUE4Qjt5QkFDeEMsQ0FBQyxDQUFDO3FCQUNKO2lCQUNGO2dCQUNELE9BQU8sR0FBRyxDQUFDO1lBQ2IsQ0FBQyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXhDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUMvQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDO1FBQ0YsMkNBQTJDO1FBQ25DLG9CQUFlLEdBQUcsQ0FBQyxLQUEwQyxFQUFFLEVBQUU7WUFDdkUscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUMsQ0FBQztRQTZFTSw0QkFBdUIsR0FBRyxDQUNoQyxLQUE0QyxFQUM1QyxFQUFFOztZQUNGLG9FQUFvRTtZQUNwRSx3RUFBd0U7WUFDeEUsOENBQThDO1lBQzlDLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMxQyxJQUFJLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxVQUFVLEVBQUU7Z0JBQ3pCLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQzthQUM3QjtZQUNELElBQUksQ0FBQyxrREFBa0QsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsaUNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFOUMseURBQXlEO1lBQ3pELDBEQUEwRDtZQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUU7Z0JBQzFELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtvQkFDMUIsT0FBTzt3QkFDTCxPQUFPLEVBQUUsSUFBSTt3QkFDYixXQUFXLEVBQUUsSUFBSTtxQkFDbEIsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQzthQUNKO1lBRUQsSUFDRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYTtnQkFDMUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFDNUM7Z0JBQ0EsSUFBSSxDQUFDLE1BQU0sR0FBRyxxREFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUNsRTtZQUVELElBQUksU0FBUyxFQUFFO2dCQUNiLE9BQU87YUFDUjtZQUVELElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1lBQzdCLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1osbUJBQW1CLEVBQUUsS0FBSyxDQUFDLFdBQVc7Z0JBQ3RDLFlBQVksRUFBRSxNQUFNO2FBQ3JCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRXZELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2QyxJQUFJLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDcEQsT0FBTzthQUNSO1lBRUQseUNBQXlDO1lBQ3pDLElBQ0UsS0FBSyxDQUFDLE1BQU0sS0FBSyw0REFBbUI7Z0JBQ3BDLEtBQUssQ0FBQyxNQUFNLEtBQUssNkRBQW9CLEVBQ3JDO2dCQUNBLE9BQU87YUFDUjtZQUVELDZCQUE2QjtZQUM3QixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRTtnQkFDN0IsT0FBTzthQUNSO1lBRUQsdUVBQXVFO1lBQ3ZFLDBFQUEwRTtZQUMxRSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU3RCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsRUFBRTtnQkFDekQsT0FBTzthQUNSO1lBRUQsZ0VBQWdFO1lBQ2hFLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1lBQzdCLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU5QyxJQUFJLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsRUFBRTtnQkFDOUQsT0FBTzthQUNSO1lBRUQsTUFBTSxrQkFBa0IsR0FDdEIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87Z0JBQ25CLEtBQUssQ0FBQyxXQUFXLEtBQUssT0FBTztnQkFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLFdBQVc7Z0JBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxNQUFNO2dCQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDO1lBRXpDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtnQkFDdkIsT0FBTzthQUNSO1lBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFO2dCQUN6QyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3RELE9BQU87YUFDUjtpQkFBTSxJQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPO2dCQUN0QyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUNyQztnQkFDQSxJQUFJLENBQUMsZ0NBQWdDLENBQ25DLEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQzFCLGdCQUFnQixDQUNqQixDQUFDO2FBQ0g7aUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFO2dCQUNqRCxxQ0FBcUM7Z0JBQ3JDLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw4REFBcUIsQ0FBQyxDQUFDO2dCQUU5Qyx3REFBd0Q7Z0JBQ3hELE1BQU0sbUJBQW1CLEdBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO29CQUNoQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBRTFELElBQUksQ0FBQyxtQkFBbUIsRUFBRTtvQkFDeEIsT0FBTztpQkFDUjtnQkFFRCxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGVBQWUsRUFBRSxtQkFBbUI7b0JBQ3BDLGNBQWMsRUFBRSxtQkFBbUI7b0JBQ25DLHFCQUFxQixFQUFFLElBQUk7b0JBQzNCLFlBQVksRUFBRSxJQUFJO2lCQUNuQixDQUFDLENBQUM7Z0JBRUgsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxvRUFBMkIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoRSxzRUFBYSxDQUFDLG1CQUFtQixFQUFFO29CQUNqQyxDQUFDO29CQUNELENBQUM7aUJBQ0YsQ0FBQyxDQUFDO2FBQ0o7aUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO2dCQUNwRCxJQUFJLENBQUMsa0NBQWtDLENBQ3JDLEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQzFCLGdCQUFnQixDQUNqQixDQUFDO2FBQ0g7aUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUNsRCxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQzthQUMxQztpQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7Z0JBQ2xELElBQUksQ0FBQyxpQ0FBaUMsQ0FDcEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUMxQixnQkFBZ0IsQ0FDakIsQ0FBQzthQUNIO1lBRUQsZ0JBQUksQ0FBQyxLQUFLLDBDQUFFLGFBQWEsbURBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUVyRSxNQUFNLGFBQWEsR0FDakIsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFN0QsTUFBTSxXQUFXLEdBQ2YsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLCtCQUErQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDekUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFckUsYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUU1QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7Z0JBQy9CLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQywyREFBa0IsRUFBRSxhQUFhLENBQUMsQ0FBQztnQkFDM0QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUN2RCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsc0RBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDbEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLG9EQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzlDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsYUFBYSxDQUFDO2dCQUN2RCxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQztnQkFDbkQsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7Z0JBQ2xELGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2FBQ3ZEO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sMEJBQXFCLEdBQUcsQ0FDOUIsS0FBNEMsRUFDNUMsRUFBRTtZQUNGLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzNCLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUU7Z0JBQzdCLE1BQU0sWUFBWSxHQUFHLG9FQUEyQixDQUM5QyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQ2xELElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFDRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQzFDLFlBQVksQ0FBQyxDQUFDLEVBQ2QsWUFBWSxDQUFDLENBQUMsQ0FDZixDQUFDO2dCQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUNqRCxZQUFZLEVBQ1osVUFBVSxDQUNYLENBQUM7YUFDSDtZQUNELElBQ0UsSUFBSSxDQUFDLGNBQWM7Z0JBQ25CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUN0RDtnQkFDQSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2FBQ3ZEO1lBRUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUM7UUFFTSx1REFBa0QsR0FBRyxDQUMzRCxLQUE0QyxFQUN0QyxFQUFFO1lBQ1Isa0RBQWtEO1lBQ2xELElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxPQUFPLEVBQUU7Z0JBQ2pDLHFCQUFxQixHQUFHLEtBQUssQ0FBQztnQkFFOUIsSUFBSSxZQUFZLEVBQUU7b0JBQ2hCLHFFQUFxRTtvQkFDckUsc0VBQXNFO29CQUN0RSxnQkFBZ0I7b0JBQ2hCLHFCQUFxQixHQUFHLElBQUksQ0FBQztpQkFDOUI7cUJBQU07b0JBQ0wsbUVBQW1FO29CQUNuRSw2QkFBNkI7b0JBQzdCLFlBQVksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTt3QkFDcEMsWUFBWSxHQUFHLENBQUMsQ0FBQzt3QkFDakIsSUFBSSxDQUFDLHFCQUFxQixFQUFFOzRCQUMxQixJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7eUJBQ3JDO29CQUNILENBQUMsRUFBRSwrREFBc0IsQ0FBQyxDQUFDO2lCQUM1QjthQUNGO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sMEJBQXFCLEdBQUcsR0FBRyxFQUFFO1lBQ25DLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMzQixZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLHFCQUFxQixHQUFHLEtBQUssQ0FBQztRQUNoQyxDQUFDLENBQUM7UUFhRix5Q0FBeUM7UUFDakMseUNBQW9DLEdBQUcsQ0FDN0MsS0FBNEMsRUFDbkMsRUFBRTtZQUNYLElBQ0UsQ0FBQyxDQUNDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUM7Z0JBQzFCLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyw2REFBb0I7b0JBQ3BDLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyw0REFBbUIsSUFBSSxjQUFjLENBQUM7b0JBQ3hELElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQzlCO2dCQUNELHdEQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFDeEM7Z0JBQ0EsT0FBTyxLQUFLLENBQUM7YUFDZDtZQUNELFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDakIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRXZCLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1lBQy9CLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUV4RCxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsNkRBQW9CLENBQUMsQ0FBQztZQUM3QyxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsS0FBSyxDQUFDO1lBQy9DLE1BQU0sYUFBYSxHQUFHLG9FQUEyQixDQUFDLENBQUMsS0FBbUIsRUFBRSxFQUFFO2dCQUN4RSxNQUFNLE1BQU0sR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztnQkFDckMsTUFBTSxNQUFNLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7Z0JBQ3JDLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUN0QixLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztnQkFFdEI7OzttQkFHRztnQkFDSCxJQUNFLE9BQU87b0JBQ1AsQ0FBQyxrQkFBa0I7b0JBQ25CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDOUM7b0JBQ0Esa0JBQWtCLEdBQUcsSUFBSSxDQUFDO29CQUUxQixrQ0FBa0M7b0JBQ2xDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFxQixFQUFFLEVBQUU7d0JBQ2pELFFBQVEsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsb0RBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO3dCQUNqRSxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQzFCLENBQUMsQ0FBQztvQkFFRjs7Ozs7dUJBS0c7b0JBQ0gsTUFBTSxlQUFlLEdBQUcsR0FBRyxFQUFFO3dCQUMzQixVQUFVLENBQUMsR0FBRyxFQUFFOzRCQUNkLFFBQVEsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsb0RBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDOzRCQUNqRSxNQUFNLENBQUMsbUJBQW1CLENBQUMseURBQWdCLEVBQUUsZUFBZSxDQUFDLENBQUM7d0JBQ2hFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDVixDQUFDLENBQUM7b0JBRUYsUUFBUSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7b0JBQzlELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx5REFBZ0IsRUFBRSxlQUFlLENBQUMsQ0FBQztpQkFDNUQ7Z0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUs7b0JBQzVELE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSztpQkFDN0QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRywyREFBa0IsQ0FDakMsQ0FBQyxhQUFhLEdBQUcsR0FBRyxFQUFFO2dCQUNwQixhQUFhLEdBQUcsSUFBSSxDQUFDO2dCQUNyQixTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUNsQixJQUFJLENBQUMsY0FBYyxFQUFFO29CQUNuQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO3dCQUM5QixrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQztxQkFDMUM7eUJBQU07d0JBQ0wsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQzVDO2lCQUNGO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osWUFBWSxFQUFFLElBQUk7aUJBQ25CLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDckQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLDJEQUFrQixFQUFFLGFBQWEsQ0FBQyxDQUFDO2dCQUM5RCxNQUFNLENBQUMsbUJBQW1CLENBQUMseURBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxtREFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNqRCxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDeEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztZQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxtREFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQywyREFBa0IsRUFBRSxhQUFhLEVBQUU7Z0JBQ3pELE9BQU8sRUFBRSxJQUFJO2FBQ2QsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDO1FBNkhNLHNDQUFpQyxHQUFHLEdBQVMsRUFBRTtZQUNyRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQzlDLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osa0JBQWtCLEVBQUUsRUFBRTtvQkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtvQkFDcEIsY0FBYyxFQUFFLElBQUk7aUJBQ3JCLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRUY7O1dBRUc7UUFDSyxpQ0FBNEIsR0FBRyxDQUNyQyxLQUE0QyxFQUM1QyxnQkFBa0MsRUFDekIsRUFBRTs7WUFDWCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQzlDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQkFDcEQsTUFBTSxnQkFBZ0IsR0FBRyw0REFBbUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNuRSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUNyRSxNQUFNLDhCQUE4QixHQUNsQyw0RUFBaUMsQ0FDL0IsUUFBUSxFQUNSLElBQUksQ0FBQyxLQUFLLEVBQ1YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQ2YsS0FBSyxDQUFDLFdBQVcsQ0FDbEIsQ0FBQztvQkFDSixJQUFJLDhCQUE4QixJQUFJLElBQUksRUFBRTt3QkFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixlQUFlLEVBQUUsOEJBQThCLENBQUMsT0FBTzt5QkFDeEQsQ0FBQyxDQUFDO3dCQUNILGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVOzRCQUNoQyw4QkFBOEIsQ0FBQyxtQkFBbUIsQ0FBQztxQkFDdEQ7aUJBQ0Y7cUJBQU0sSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUN0QyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLDJFQUFnQyxDQUNuRSwwREFBZSxDQUFDLGdCQUFnQixDQUFDLEVBQ2pDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNmLEtBQUssQ0FBQyxXQUFXLENBQ2xCLENBQUM7aUJBQ0g7Z0JBQ0QsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO29CQUN0QyxrREFBUyxDQUNQLElBQUksQ0FBQyxNQUFNLEVBQ1gsc0VBQTJCLENBQUM7d0JBQzFCLG1CQUFtQixFQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVO3FCQUN4RCxDQUFDLENBQ0gsQ0FBQztvQkFDRixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztvQkFDMUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxxREFBWSxDQUMzQyw0REFBaUIsQ0FDZixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUNsQyxnQkFBZ0IsRUFDaEIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsQ0FDRixDQUFDO29CQUNGLElBQ0UsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7d0JBQzdCLHFFQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3BDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUN2Qzt3QkFDQSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLGtFQUF1QixDQUM5RCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUNsQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FDcEIsQ0FBQztxQkFDSDtpQkFDRjtxQkFBTTtvQkFDTCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUU7d0JBQ3BDLE1BQU0sbUJBQW1CLEdBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQzt3QkFDdEUsTUFBTSxHQUFHLEdBQUcsZ0dBQXFDLENBQy9DLEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxPQUFPLEVBQ1osZ0JBQWdCLENBQUMsTUFBTSxFQUN2QixtQkFBbUIsQ0FDcEIsQ0FBQzt3QkFDRixJQUFJLEdBQUcsQ0FBQyxVQUFVLEVBQUU7NEJBQ2xCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQzt5QkFDL0M7d0JBQ0QsSUFBSSxHQUFHLENBQUMsbUJBQW1CLEVBQUU7NEJBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxxQkFBcUIsRUFBRSxHQUFHLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDOzRCQUVsRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7Z0NBQ25DLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxHQUFHLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDOzZCQUNsRTt5QkFDRjt3QkFDRCxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFOzRCQUN0QyxPQUFPLElBQUksQ0FBQzt5QkFDYjtxQkFDRjtvQkFDRCxzREFBc0Q7b0JBQ3RELGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPO3dCQUMxQixzQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxtQ0FDNUIsSUFBSSxDQUFDLG9CQUFvQixDQUN2QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUMxQixDQUFDO29CQUVKLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRTt3QkFDaEMsK0NBQStDO3dCQUMvQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQ2xEOzRCQUNFLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQzs0QkFDNUIsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUM3QixFQUNELGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQzdCLENBQUM7d0JBQ0YsSUFBSSxjQUFjLEVBQUU7NEJBQ2xCLE9BQU8sS0FBSyxDQUFDO3lCQUNkO3FCQUNGO29CQUVELCtDQUErQztvQkFDL0Msb0JBQW9CO29CQUNwQixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FDOUQsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsQ0FBQztvQkFFRixNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO29CQUNoRCxNQUFNLHdCQUF3QixHQUM1QixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQ25ELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FDakMsQ0FBQztvQkFDSixJQUNFLENBQUMsVUFBVSxLQUFLLElBQUksSUFBSSxDQUFDLHdCQUF3QixDQUFDO3dCQUNsRCxDQUFDLEtBQUssQ0FBQyxRQUFRO3dCQUNmLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxFQUMvRDt3QkFDQSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO3FCQUNqQztvQkFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7d0JBQ25DLElBQUksQ0FBQyxRQUFRLENBQUM7NEJBQ1osa0JBQWtCLEVBQUU7Z0NBQ2xCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJOzZCQUNsRDt5QkFDRixDQUFDLENBQUM7d0JBQ0gsMkJBQTJCO3FCQUM1Qjt5QkFBTSxJQUFJLFVBQVUsSUFBSSxJQUFJLEVBQUU7d0JBQzdCLG1FQUFtRTt3QkFDbkUsSUFBSSxLQUFLLENBQUMsb0RBQWdCLENBQUMsRUFBRTs0QkFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dDQUNqRCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDOzZCQUNqRDs0QkFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxpQ0FDeEIscUVBQTJCLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxLQUNyRCwwQkFBMEIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixJQUN6RCxDQUFDLENBQUM7NEJBQ0osOERBQThEOzRCQUM5RCxPQUFPLEtBQUssQ0FBQzt5QkFDZDt3QkFFRCwrQkFBK0I7d0JBQy9CLHdEQUF3RDt3QkFDeEQsd0RBQXdEO3dCQUN4RCxtQkFBbUI7d0JBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRTs0QkFDakQsb0ZBQW9GOzRCQUNwRixJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYztnQ0FDekIsQ0FBQywwREFBZ0IsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFDeEQ7Z0NBQ0EsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQ0FDWixrQkFBa0IsRUFBRSxFQUFFO29DQUN0QixnQkFBZ0IsRUFBRSxFQUFFO29DQUNwQixjQUFjLEVBQUUsSUFBSTtpQ0FDckIsQ0FBQyxDQUFDOzZCQUNKOzRCQUVELG1FQUFtRTs0QkFDbkUsaUVBQWlFOzRCQUNqRSwyREFBMkQ7NEJBQzNELElBQ0UsQ0FBQyx3QkFBd0I7Z0NBQ3pCLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxFQUMvRDtnQ0FDQSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7b0NBQzFCLE9BQU8seUVBQStCLGlDQUUvQixTQUFTLEtBQ1osa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxLQUV2QixrQkFBa0IsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FFdEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUNuQyxDQUFDO2dDQUNKLENBQUMsQ0FBQyxDQUFDO2dDQUNILGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7NkJBQ2pEO3lCQUNGO3FCQUNGO29CQUVELElBQUksQ0FBQyxRQUFRLENBQUM7d0JBQ1osMEJBQTBCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0I7cUJBQzFELENBQUMsQ0FBQztpQkFDSjthQUNGO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLENBQUM7UUF5Qk0sNEJBQXVCLEdBQUcsQ0FDaEMsS0FBNEMsRUFDNUMsZ0JBQWtDLEVBQzVCLEVBQUU7WUFDUiwwREFBMEQ7WUFDMUQsNERBQTREO1lBQzVELDhCQUE4QjtZQUM5QixJQUFJLHdEQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRTtnQkFDNUMsT0FBTzthQUNSO1lBQ0QsSUFBSSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFJLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBRXZDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFO2dCQUN4RCx1QkFBdUIsRUFBRSxJQUFJO2FBQzlCLENBQUMsQ0FBQztZQUVILE1BQU0sV0FBVyxHQUFHLHlFQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pELElBQUksV0FBVyxFQUFFO2dCQUNmLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUN6QztZQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDcEIsTUFBTTtnQkFDTixNQUFNO2dCQUNOLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixvQkFBb0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNO2FBQ3BDLENBQUMsQ0FBQztZQUVILG9EQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osVUFBVSxFQUFFLHlEQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7aUJBQ2hFLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sdUNBQWtDLEdBQUcsQ0FDM0MsS0FBNEMsRUFDNUMsV0FBOEMsRUFDOUMsZ0JBQWtDLEVBQ2xDLEVBQUU7WUFDRixnRUFBZ0U7WUFDaEUsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixJQUFJLENBQ0wsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLHdFQUFrQixDQUFDO2dCQUNqQyxJQUFJLEVBQUUsV0FBVztnQkFDakIsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7Z0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7Z0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO2dCQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0M7Z0JBQzVELGdCQUFnQixFQUFFLEtBQUssQ0FBQyxRQUFRLEtBQUssR0FBRztnQkFDeEMsTUFBTSxFQUFFLEtBQUs7YUFDZCxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM1QixrQkFBa0Isa0NBQ2IsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEdBQ3BCO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsZ0JBQWdCO2dCQUN4QyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVM7Z0JBQ25CLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFM0Msc0VBQWEsQ0FBQyxPQUFPLEVBQUU7Z0JBQ3JCLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNoQixTQUFTO2FBQ1YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxZQUFZLEdBQUcsOEVBQTJCLENBQzlDLGdCQUFnQixDQUFDLE1BQU0sRUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1lBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFDNUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFO2dCQUMzQyxPQUFPO2FBQ1IsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixlQUFlLEVBQUUsT0FBTztnQkFDeEIsY0FBYyxFQUFFLE9BQU87Z0JBQ3ZCLGlCQUFpQixFQUFFLFlBQVk7Z0JBQy9CLGlCQUFpQixFQUFFLEVBQUU7YUFDdEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRU0sdUJBQWtCLEdBQUcsQ0FBQyxFQUM1QixNQUFNLEVBQ04sTUFBTSxHQUlQLEVBQUUsRUFBRTtZQUNILE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsb0RBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFekUsTUFBTSxPQUFPLEdBQUcsMERBQWUsQ0FBQztnQkFDOUIsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7Z0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7Z0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO2dCQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0M7Z0JBQzVELE1BQU0sRUFBRSxLQUFLO2FBQ2QsQ0FBQyxDQUFDO1lBRUgsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQyxDQUFDO1FBRU0scUNBQWdDLEdBQUcsQ0FDekMsS0FBNEMsRUFDNUMsV0FBNEMsRUFDNUMsZ0JBQWtDLEVBQzVCLEVBQUU7WUFDUixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO2dCQUMzQixNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFFcEMsZ0NBQWdDO2dCQUNoQyxJQUNFLFlBQVksQ0FBQyxJQUFJLEtBQUssTUFBTTtvQkFDNUIsbURBQVcsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUN2RDtvQkFDQSxzRUFBYSxDQUFDLFlBQVksRUFBRTt3QkFDMUIsa0JBQWtCLEVBQ2hCLFlBQVksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO3FCQUN0RCxDQUFDLENBQUM7b0JBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO29CQUNqRCxPQUFPO2lCQUNSO2dCQUVELE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsa0JBQWtCLEVBQUUsR0FBRyxZQUFZLENBQUM7Z0JBRTFELCtDQUErQztnQkFDL0MsSUFDRSxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDO29CQUM5QixrQkFBa0I7b0JBQ2xCLGtEQUFVLENBQ1IsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQzlCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUM5QixrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFDckIsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQ3RCLEdBQUcsK0RBQXNCLEVBQzFCO29CQUNBLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztvQkFDakQsT0FBTztpQkFDUjtnQkFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM1QixrQkFBa0Isa0NBQ2IsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEdBQ3hCO2lCQUNGLENBQUMsQ0FBQyxDQUFDO2dCQUNKLHFFQUFxRTtnQkFDckUsUUFBUTtnQkFDUixzRUFBYSxDQUFDLFlBQVksRUFBRTtvQkFDMUIsa0JBQWtCLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7aUJBQ3hFLENBQUMsQ0FBQztnQkFDSCxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsNERBQW1CLENBQUMsQ0FBQzthQUM3QztpQkFBTTtnQkFDTCxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQ2pDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO2dCQUVGOzs7d0NBR3dCO2dCQUV4QixNQUFNLEVBQUUseUJBQXlCLEVBQUUsdUJBQXVCLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUMxRSxNQUFNLENBQUMsY0FBYyxFQUFFLFlBQVksQ0FBQyxHQUNsQyxXQUFXLEtBQUssT0FBTztvQkFDckIsQ0FBQyxDQUFDLENBQUMseUJBQXlCLEVBQUUsdUJBQXVCLENBQUM7b0JBQ3RELENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFbkIsTUFBTSxPQUFPLEdBQUcsMkRBQWdCLENBQUM7b0JBQy9CLElBQUksRUFBRSxXQUFXO29CQUNqQixDQUFDLEVBQUUsS0FBSztvQkFDUixDQUFDLEVBQUUsS0FBSztvQkFDUixXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7b0JBQzlDLGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDBCQUEwQjtvQkFDdEQsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO29CQUMxQyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7b0JBQzlDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtvQkFDOUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO29CQUMxQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0I7b0JBQ3RDLGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGdDQUFnQztvQkFDNUQsY0FBYztvQkFDZCxZQUFZO29CQUNaLE1BQU0sRUFBRSxLQUFLO2lCQUNkLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM1QixrQkFBa0Isa0NBQ2IsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEdBQ3BCO2lCQUNGLENBQUMsQ0FBQyxDQUFDO2dCQUNKLHNFQUFhLENBQUMsT0FBTyxFQUFFO29CQUNyQixNQUFNLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ3BDLENBQUMsQ0FBQztnQkFDSCxNQUFNLFlBQVksR0FBRyw4RUFBMkIsQ0FDOUMsZ0JBQWdCLENBQUMsTUFBTSxFQUN2QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztvQkFDNUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFO29CQUMzQyxPQUFPO2lCQUNSLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGVBQWUsRUFBRSxPQUFPO29CQUN4QixjQUFjLEVBQUUsT0FBTztvQkFDdkIsaUJBQWlCLEVBQUUsWUFBWTtvQkFDL0IsaUJBQWlCLEVBQUUsRUFBRTtpQkFDdEIsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUM7UUFFTSxzQ0FBaUMsR0FBRyxDQUMxQyxXQUE2QyxFQUM3QyxnQkFBa0MsRUFDNUIsRUFBRTtZQUNSLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsb0RBQVksQ0FDakMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQ3BCLENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRyxxREFBVSxDQUFDO2dCQUN6QixJQUFJLEVBQUUsV0FBVztnQkFDakIsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsQ0FBQyxFQUFFLEtBQUs7Z0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7Z0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7Z0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO2dCQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7Z0JBQ3RELE1BQU0sRUFBRSxLQUFLO2FBQ2QsQ0FBQyxDQUFDO1lBRUgsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRTtnQkFDaEMsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixnQkFBZ0IsRUFBRSxPQUFPO29CQUN6QixlQUFlLEVBQUUsT0FBTztpQkFDekIsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztvQkFDNUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFO29CQUMzQyxPQUFPO2lCQUNSLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLFlBQVksRUFBRSxJQUFJO29CQUNsQixlQUFlLEVBQUUsT0FBTztvQkFDeEIsY0FBYyxFQUFFLE9BQU87aUJBQ3hCLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBeTZCTSxnQ0FBMkIsR0FBRyxDQUNwQyxnQkFBa0MsRUFDbEMsRUFBRTtZQUNGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDcEUsSUFDRSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUMxQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUNoRDtvQkFDQSxPQUFPLHVFQUFjLENBQUMsR0FBRyxFQUFFO3dCQUN6QixPQUFPLEVBQUUsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU87cUJBQzVELENBQUMsQ0FBQztpQkFDSjtxQkFBTSxJQUNMLHdFQUFrQixDQUFDLEdBQUcsQ0FBQztvQkFDdkIsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztvQkFDbkQsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEtBQUssRUFDekQ7b0JBQ0EsT0FBTyx1RUFBYyxDQUFDLEdBQUcsRUFBRTt3QkFDekIsT0FBTyxFQUFFLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPO3FCQUNyRSxDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBRU0sa0JBQWEsR0FBRyxDQUFDLGdCQUFrQyxFQUFFLEVBQUU7WUFDN0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNwRSxJQUNFLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQzFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQ2hEO29CQUNBLE9BQU8sdUVBQWMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDakQ7cUJBQU0sSUFDTCx3RUFBa0IsQ0FBQyxHQUFHLENBQUM7b0JBQ3ZCLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7b0JBQ25ELGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLEVBQ3pEO29CQUNBLE9BQU8sdUVBQWMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDakQ7Z0JBQ0QsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUM7UUFFTSxvQkFBZSxHQUFHLENBQU8sRUFDL0IsU0FBUyxFQUNULFlBQVksRUFBRSxhQUFhLEVBQzNCLHNCQUFzQixHQUFHLEtBQUssR0FLL0IsRUFBRSxFQUFFOztZQUNILDJFQUEyRTtZQUMzRSw4QkFBOEI7WUFDOUIsSUFBSSxDQUFDLGlFQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFO2dCQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLHlDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxDQUFDO2FBQ2xEO1lBQ0QsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztZQUVoQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFL0IsSUFBSSxRQUFRLEtBQUssdURBQWMsRUFBRTtnQkFDL0IsSUFBSTtvQkFDRixTQUFTLEdBQUcsNERBQWUsQ0FDekIsTUFBTSw2REFBWSxDQUFDLE1BQU0sU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQzFDLFNBQVMsQ0FBQyxJQUFJLENBQ2YsQ0FBQztpQkFDSDtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQztpQkFDbEQ7YUFDRjtZQUVELDREQUE0RDtZQUM1RCw0REFBNEQ7WUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsZ0JBQUksQ0FBQyxLQUFLLEVBQUMsaUJBQWlCLG1EQUNqRCxTQUFTLENBQ1UsS0FBSSwrREFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBRXhELElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ1gsT0FBTyxDQUFDLElBQUksQ0FDVixzRkFBc0YsQ0FDdkYsQ0FBQztnQkFDRixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUFDLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDO2FBQy9DO1lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxpQkFBZ0IsYUFBaEIsZ0JBQWdCLHVCQUFoQixnQkFBZ0IsQ0FBRSxPQUFPLEdBQUU7Z0JBQzlCLElBQUk7b0JBQ0YsU0FBUyxHQUFHLE1BQU0sNERBQWUsQ0FBQyxTQUFTLEVBQUU7d0JBQzNDLGdCQUFnQixFQUFFLDBFQUFpQztxQkFDcEQsQ0FBQyxDQUFDO2lCQUNKO2dCQUFDLE9BQU8sS0FBVSxFQUFFO29CQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLGdEQUFnRCxFQUFFLEtBQUssQ0FBQyxDQUFDO2lCQUN4RTtnQkFFRCxJQUFJLFNBQVMsQ0FBQyxJQUFJLEdBQUcsK0RBQXNCLEVBQUU7b0JBQzNDLE1BQU0sSUFBSSxLQUFLLENBQ2IseUNBQUMsQ0FBQyxtQkFBbUIsRUFBRTt3QkFDckIsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywrREFBc0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUk7cUJBQ2pFLENBQUMsQ0FDSCxDQUFDO2lCQUNIO2FBQ0Y7WUFFRCxJQUFJLHNCQUFzQixFQUFFO2dCQUMxQixNQUFNLE9BQU8sR0FBRyxVQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQywwQ0FBRSxPQUFPLENBQUM7Z0JBQzVDLGtFQUFrRTtnQkFDbEUsb0NBQW9DO2dCQUNwQyw0REFBNEQ7Z0JBQzVELE1BQU0sV0FBVyxHQUFHLE9BQU8sSUFBSSwwREFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUV0RCxJQUFJLENBQUMscUJBQXFCLENBQUMsV0FBVyxJQUFJLFNBQVMsQ0FBQyxDQUFDO2FBQ3REO1lBRUQsTUFBTSxPQUFPLEdBQ1gsV0FBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsMENBQUUsT0FBTyxLQUFJLENBQUMsTUFBTSx1REFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFFL0QsTUFBTSxZQUFZLEdBQUcsc0VBQWEsQ0FDaEMsYUFBYSxFQUNiO2dCQUNFLE1BQU07YUFDUCxFQUNELEtBQUssQ0FDMkMsQ0FBQztZQUVuRCxPQUFPLElBQUksT0FBTyxDQUNoQixDQUFPLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTs7Z0JBQ3hCLElBQUk7b0JBQ0YsSUFBSSxDQUFDLEtBQUssbUNBQ0wsSUFBSSxDQUFDLEtBQUssS0FDYixDQUFDLE1BQU0sQ0FBQyxFQUFFOzRCQUNSLFFBQVE7NEJBQ1IsRUFBRSxFQUFFLE1BQU07NEJBQ1YsT0FBTzs0QkFDUCxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTt5QkFDcEIsR0FDRixDQUFDO29CQUNGLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNwRCxJQUFJLENBQUMsZUFBZSxFQUFFO3dCQUNwQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQzt3QkFDaEMsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO3FCQUM3QztvQkFDRCxJQUFJLGdCQUFlLGFBQWYsZUFBZSx1QkFBZixlQUFlLENBQUUsS0FBSyxhQUFZLE9BQU8sRUFBRTt3QkFDN0MsTUFBTSxlQUFlLENBQUMsS0FBSyxDQUFDO3FCQUM3QjtvQkFDRCxJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEtBQUssWUFBWSxDQUFDLEVBQUU7d0JBQ3BELFdBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSwwQ0FBRSxFQUFFLE1BQUssWUFBWSxDQUFDLEVBQUUsRUFDbEQ7d0JBQ0EsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztxQkFDcEQ7b0JBQ0QsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN2QjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDckIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHlDQUFDLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2pEO3dCQUFTO29CQUNSLElBQUksQ0FBQyxzQkFBc0IsRUFBRTt3QkFDM0Isb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7cUJBQzFCO2lCQUNGO1lBQ0gsQ0FBQyxFQUNGLENBQUM7UUFDSixDQUFDLEVBQUM7UUFFRjs7V0FFRztRQUNLLHVCQUFrQixHQUFHLENBQzNCLFlBQW9DLEVBQ3BDLFNBQWUsRUFDZixzQkFBZ0MsRUFDaEMsRUFBRTtZQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtnQkFDM0MsWUFBWTthQUNiLENBQUMsQ0FBQztZQUVILElBQUk7Z0JBQ0YsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDO29CQUN6QixTQUFTO29CQUNULFlBQVk7b0JBQ1osc0JBQXNCO2lCQUN2QixDQUFDLENBQUM7YUFDSjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixzRUFBYSxDQUFDLFlBQVksRUFBRTtvQkFDMUIsU0FBUyxFQUFFLElBQUk7aUJBQ2hCLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPLElBQUkseUNBQUMsQ0FBQyx5QkFBeUIsQ0FBQztpQkFDNUQsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLEVBQUM7UUFFTSwwQkFBcUIsR0FBRyxDQUFPLFNBQWUsRUFBRSxFQUFFO1lBQ3hELGdDQUFnQztZQUNoQyxxSEFBcUg7WUFDckgsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7WUFFN0IsTUFBTSxZQUFZLEdBQUcsTUFBTSw0REFBZSxDQUFDLFNBQVMsRUFBRTtnQkFDcEQsZ0JBQWdCLEVBQUUsaUJBQWlCO2FBQ3BDLENBQUMsQ0FBQztZQUVILElBQUksY0FBYyxHQUFHLE1BQU0sdURBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUVwRCwyRUFBMkU7WUFDM0UsaUJBQWlCO1lBQ2pCLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyx1REFBYyxFQUFFO2dCQUNyQyxNQUFNLEdBQUcsR0FBRyxNQUFNLHFFQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUV2RCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztnQkFDckQsSUFBSSxLQUFLLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBRTlDLElBQUksS0FBSyxHQUFHLGlCQUFpQixFQUFFO29CQUM3QixLQUFLLEdBQUcsaUJBQWlCLENBQUM7b0JBQzFCLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDM0M7Z0JBRUQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Z0JBQ3ZCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBRSxDQUFDO2dCQUV6QyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFFNUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsdURBQWMsQ0FBWSxDQUFDO2FBQzlEO1lBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFO2dCQUNwQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxjQUFjLGFBQWEsQ0FBQyxDQUFDO2FBQzVEO1FBQ0gsQ0FBQyxFQUFDO1FBRU0sa0JBQWEsR0FBRyxDQUN0QixFQUFFLHNCQUFzQixFQUFFLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSxLQUFLLEVBQUUsRUFDOUQsRUFBRTtZQUNGLElBQUk7Z0JBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO2dCQUM3RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7Z0JBRTdELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsb0VBQTJCLENBQzFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUNwQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsTUFBTSxTQUFTLEdBQUcsTUFBTSwyREFBUSxDQUFDO29CQUMvQixXQUFXLEVBQUUsT0FBTztvQkFDcEIsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO2lCQUN6QyxDQUFDLENBQUM7Z0JBRUgsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUMzQyxNQUFNLEVBQUUsQ0FBQztvQkFDVCxNQUFNLEVBQUUsQ0FBQztpQkFDVixDQUFDLENBQUM7Z0JBRUgsSUFBSSxzQkFBc0IsRUFBRTtvQkFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDakQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUNYO3dCQUNFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFO3FCQUNoRCxFQUNELEdBQUcsRUFBRTt3QkFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7b0JBQ25ELENBQUMsQ0FDRixDQUFDO2lCQUNIO3FCQUFNO29CQUNMLElBQUksQ0FBQyxRQUFRLENBQ1g7d0JBQ0UscUJBQXFCLEVBQUUsWUFBWSxDQUFDLEVBQUU7cUJBQ3ZDLEVBQ0QsR0FBRyxFQUFFO3dCQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FDckIsWUFBWSxFQUNaLFNBQVM7d0JBQ1QsNEJBQTRCLENBQUMsSUFBSSxDQUNsQyxDQUFDO29CQUNKLENBQUMsQ0FDRixDQUFDO2lCQUNIO2FBQ0Y7WUFBQyxPQUFPLEtBQVUsRUFBRTtnQkFDbkIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFlBQVksRUFBRTtvQkFDL0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDdEI7cUJBQU07b0JBQ0wsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDckI7Z0JBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FDWDtvQkFDRSxxQkFBcUIsRUFBRSxJQUFJO29CQUMzQixjQUFjLEVBQUUsSUFBSTtvQkFDcEIsVUFBVSxFQUFFLHlEQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7aUJBQ2hFLEVBQ0QsR0FBRyxFQUFFO29CQUNILElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztnQkFDbkQsQ0FBQyxDQUNGLENBQUM7YUFDSDtRQUNILENBQUMsRUFBQztRQUVNLDhCQUF5QixHQUFHLENBQ2xDLFlBQW9DLEVBQ3BDLGdCQUFnQixHQUFHLEtBQUssRUFDeEIsRUFBRTs7WUFDRixNQUFNLEtBQUssR0FDVCwrRUFBeUIsQ0FBQyxZQUFZLENBQUM7aUJBQ3ZDLFVBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsMENBQUUsS0FBSyxFQUFDO1lBRWxELElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxZQUFZLE9BQU8sRUFBRTtnQkFDdEMsSUFDRSxZQUFZLENBQUMsS0FBSyxHQUFHLDJEQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUs7b0JBQy9ELFlBQVksQ0FBQyxNQUFNLEdBQUcsMkRBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUNoRTtvQkFDQSxNQUFNLGVBQWUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUNwRCxzRUFBYSxDQUFDLFlBQVksRUFBRTt3QkFDMUIsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLEdBQUcsZUFBZSxHQUFHLENBQUM7d0JBQ3ZDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxHQUFHLGVBQWUsR0FBRyxDQUFDO3dCQUN2QyxLQUFLLEVBQUUsZUFBZTt3QkFDdEIsTUFBTSxFQUFFLGVBQWU7cUJBQ3hCLENBQUMsQ0FBQztpQkFDSjtnQkFFRCxPQUFPO2FBQ1I7WUFFRCxJQUNFLGdCQUFnQjtnQkFDaEIsOERBQThEO2dCQUM5RCw4REFBOEQ7Z0JBQzlELGlCQUFpQjtnQkFDakIsQ0FBQyxZQUFZLENBQUMsS0FBSyxHQUFHLDJEQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUs7b0JBQzlELFlBQVksQ0FBQyxNQUFNLEdBQUcsMkRBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQ25FO2dCQUNBLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUN6RCwyREFBMkQ7Z0JBQzNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQ3hCLFNBQVMsRUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FDNUQsQ0FBQztnQkFFRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ3hELE1BQU0sS0FBSyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUVsRSwwRUFBMEU7Z0JBQzFFLDJCQUEyQjtnQkFDM0IsTUFBTSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUM5RCxNQUFNLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBRWhFLHNFQUFhLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQzthQUN0RDtRQUNILENBQUMsQ0FBQztRQUVGOzBFQUNrRTtRQUMxRCxxQkFBZ0IsR0FBRyxDQUN6QixRQUFzRCxFQUN0RCxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFDbEIsRUFBRTtZQUNGLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLEdBQUcsTUFBTSxpRUFBaUIsQ0FBQztnQkFDN0QsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUMzQixPQUFPLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDbEQsS0FBSzthQUNOLENBQUMsQ0FBQztZQUNILElBQUksWUFBWSxDQUFDLElBQUksSUFBSSxZQUFZLENBQUMsSUFBSSxFQUFFO2dCQUMxQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRTtvQkFDOUIsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTt3QkFDcEMsbUZBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ3BDO2lCQUNGO2FBQ0Y7WUFDRCxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtvQkFDdkQsSUFDRSwrRUFBeUIsQ0FBQyxPQUFPLENBQUM7d0JBQ2xDLFlBQVksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUNoQzt3QkFDQSxPQUFPLHVFQUFjLENBQUMsT0FBTyxFQUFFOzRCQUM3QixNQUFNLEVBQUUsT0FBTzt5QkFDaEIsQ0FBQyxDQUFDO3FCQUNKO29CQUNELE9BQU8sT0FBTyxDQUFDO2dCQUNqQixDQUFDLENBQUMsQ0FDSCxDQUFDO2FBQ0g7WUFFRCxPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxDQUFDO1FBQ3hDLENBQUMsRUFBQztRQUVGLDZEQUE2RDtRQUNyRCw2QkFBd0IsR0FBRyxDQUNqQyxnQkFBcUQsNEVBQTJCLENBQzlFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FDbkMsRUFDRCxRQUFxQixJQUFJLENBQUMsS0FBSyxFQUMvQixFQUFFO1lBQ0YsTUFBTSxxQkFBcUIsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUNoRCxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUN4RSxDQUFDO1lBRUYsSUFBSSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2hDLE1BQU0sRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDbEQscUJBQXFCLEVBQ3JCLEtBQUssQ0FDTixDQUFDO2dCQUNGLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtvQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztpQkFDN0I7YUFDRjtRQUNILENBQUMsRUFBQztRQUVGOzZEQUNxRDtRQUM3Qyx5QkFBb0IsR0FBRyx1REFBUSxDQUFDLEdBQUcsRUFBRTtZQUMzQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUNsQyxDQUFDLEVBQUUsNkRBQW9CLENBQUMsQ0FBQztRQUVqQixzQ0FBaUMsR0FBRyxDQUMxQyxLQUE0QyxFQUM1QyxFQUFFO1lBQ0YsTUFBTSxtQkFBbUIsR0FBRyxxRkFBa0MsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEtBQUssbUJBQW1CLEVBQUU7Z0JBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7YUFDMUQ7UUFDSCxDQUFDLENBQUM7UUFFTSxnQ0FBMkIsR0FBRyxDQUFDLGFBR3RDLEVBQVEsRUFBRTtZQUNULE1BQU0sc0JBQXNCLEdBQUcsOEVBQTJCLENBQ3hELGFBQWEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFDRixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLGlCQUFpQixFQUNmLHNCQUFzQixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2FBQ2pFLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVNLGlEQUE0QyxHQUFHLENBQ3JELGFBQWtEO1FBQ2xELG1CQUFtQjtRQUNuQixhQUdHO1FBQ0gsaUVBQWlFO1FBQ2pFLHVCQUF1QjtRQUN2QiwyQkFBOEQsRUFDeEQsRUFBRTtZQUNSLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFO2dCQUN6QixPQUFPO2FBQ1I7WUFFRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQzVDLENBQUMsR0FBNEMsRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDdkQsTUFBTSxzQkFBc0IsR0FBRyw4RUFBMkIsQ0FDeEQsTUFBTSxFQUNOLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFDRixJQUNFLHNCQUFzQixJQUFJLElBQUk7b0JBQzlCLENBQUMsdUZBQW9DLENBQ25DLGFBQWEsRUFDYiwyQkFBMkIsYUFBM0IsMkJBQTJCLHVCQUEzQiwyQkFBMkIsQ0FBRSxFQUFFLEVBQy9CLHNCQUFzQixDQUN2QixFQUNEO29CQUNBLEdBQUcsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztpQkFDbEM7Z0JBQ0QsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQ0QsRUFBRSxDQUNILENBQUM7WUFFRixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQztRQTRCTSxvQkFBZSxHQUFHLENBQUMsTUFBeUIsRUFBRSxFQUFFOztZQUN0RCxpQ0FBaUM7WUFDakMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO2dCQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztnQkFDckIsSUFBSSxDQUFDLEVBQUUsR0FBRyxnRUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFFcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQzFELE9BQU8sRUFBRSxLQUFLO2lCQUNmLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLDBEQUFpQixFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDakUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx3REFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5RDtpQkFBTTtnQkFDTCxVQUFJLENBQUMsTUFBTSwwQ0FBRSxtQkFBbUIsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDaEUsVUFBSSxDQUFDLE1BQU0sMENBQUUsbUJBQW1CLENBQUMsMERBQWlCLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUNyRSxVQUFJLENBQUMsTUFBTSwwQ0FBRSxtQkFBbUIsQ0FBQyx3REFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNsRTtRQUNILENBQUMsQ0FBQztRQUVNLG9CQUFlLEdBQUcsQ0FBTyxLQUFzQyxFQUFFLEVBQUU7WUFDekUsNkNBQTZDO1lBQzdDLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSw2REFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUzRCxJQUFJO2dCQUNGLElBQUksaUVBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzlCLGdFQUFnRTtvQkFDaEUsd0VBQXdFO29CQUV4RSxJQUFJLEtBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxJQUFJLE1BQUssdURBQWMsSUFBSSxLQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxNQUFLLHVEQUFjLEVBQUU7d0JBQ2xFLElBQUk7NEJBQ0YsTUFBTSxLQUFLLEdBQUcsTUFBTSxvREFBWSxDQUM5QixJQUFJLEVBQ0osSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLEVBQ3hDLFVBQVUsQ0FDWCxDQUFDOzRCQUNGLElBQUksQ0FBQyxnQkFBZ0IsaUNBQ2hCLEtBQUssS0FDUixRQUFRLGtDQUNILENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQ2pDLFNBQVMsRUFBRSxLQUFLLEtBRWxCLFlBQVksRUFBRSxJQUFJLEVBQ2xCLGVBQWUsRUFBRSxJQUFJLElBQ3JCLENBQUM7NEJBQ0gsT0FBTzt5QkFDUjt3QkFBQyxPQUFPLEtBQVUsRUFBRTs0QkFDbkIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGVBQWUsRUFBRTtnQ0FDbEMsTUFBTSxLQUFLLENBQUM7NkJBQ2I7eUJBQ0Y7cUJBQ0Y7b0JBRUQsb0VBQW9FO29CQUNwRSxnQ0FBZ0M7b0JBQ2hDLHdFQUF3RTtvQkFFeEUsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLG9FQUEyQixDQUMxRCxLQUFLLEVBQ0wsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO29CQUVGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUNqRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUM1QyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQzdDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFFbkUsT0FBTztpQkFDUjthQUNGO1lBQUMsT0FBTyxLQUFVLEVBQUU7Z0JBQ25CLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDbkIsU0FBUyxFQUFFLEtBQUs7b0JBQ2hCLFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTztpQkFDNUIsQ0FBQyxDQUFDO2FBQ0o7WUFFRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxpRUFBd0IsQ0FBQyxDQUFDO1lBQ3pFLElBQUksV0FBVyxJQUFJLE9BQU8sV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEQsSUFBSTtvQkFDRixNQUFNLFlBQVksR0FBRyw2REFBZ0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDbkQsSUFBSSxDQUFDLDZCQUE2QixDQUFDO3dCQUNqQyxRQUFRLEVBQUUsa0ZBQWtDLENBQUMsWUFBWSxDQUFDO3dCQUMxRCxRQUFRLEVBQUUsS0FBSzt3QkFDZixLQUFLLEVBQUUsSUFBSTtxQkFDWixDQUFDLENBQUM7aUJBQ0o7Z0JBQUMsT0FBTyxLQUFVLEVBQUU7b0JBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7aUJBQ2hEO2dCQUNELE9BQU87YUFDUjtZQUVELElBQUksSUFBSSxFQUFFO2dCQUNSLG9EQUFvRDtnQkFDcEQsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQy9DO1FBQ0gsQ0FBQyxFQUFDO1FBRUYscUJBQWdCLEdBQUcsQ0FDakIsSUFBVSxFQUNWLFVBQW1DLEVBQ25DLEVBQUU7WUFDRixJQUFJLEdBQUcsTUFBTSwwREFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pDLElBQUk7Z0JBQ0YsTUFBTSxHQUFHLEdBQUcsTUFBTSx1RUFBMEIsQ0FDMUMsSUFBSSxFQUNKLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxFQUN4QyxVQUFVLENBQ1gsQ0FBQztnQkFDRixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssOERBQXFCLEVBQUU7b0JBQ3RDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDbkMsSUFBSSxDQUFDLGdCQUFnQixpQ0FDaEIsR0FBRyxDQUFDLElBQUksS0FDWCxRQUFRLGtDQUNILENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUNwQyxTQUFTLEVBQUUsS0FBSyxLQUVsQixZQUFZLEVBQUUsSUFBSSxFQUNsQixlQUFlLEVBQUUsSUFBSSxJQUNyQixDQUFDO2lCQUNKO3FCQUFNLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxpRUFBd0IsRUFBRTtvQkFDaEQsTUFBTSxJQUFJLENBQUMsT0FBTzt5QkFDZixhQUFhLENBQUM7d0JBQ2IsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLEtBQUssRUFBRSxJQUFJO3dCQUNYLGVBQWUsRUFBRSxJQUFJO3FCQUN0QixDQUFDO3lCQUNELEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO3dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLEVBQUUseUNBQUMsQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDbEUsQ0FBQyxDQUFDLENBQUM7aUJBQ047YUFDRjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDbEU7UUFDSCxDQUFDLEVBQUM7UUFFTSw0QkFBdUIsR0FBRyxDQUNoQyxLQUE0QyxFQUM1QyxFQUFFO1lBQ0YsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRXZCLElBQ0UsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFdBQVcsS0FBSyxPQUFPO2dCQUN4QyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsV0FBVyxLQUFLLEtBQUs7b0JBQ3RDLG1EQUFtRDtvQkFDbkQsS0FBSyxDQUFDLE1BQU0sS0FBSyxpRUFBd0IsQ0FBQyxDQUFDO2dCQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUMxQztnQkFDQSxPQUFPO2FBQ1I7WUFFRCxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLG9FQUEyQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQzlDLGNBQWMsRUFBRSxJQUFJO2dCQUNwQixxQkFBcUIsRUFBRSxJQUFJO2FBQzVCLENBQUMsQ0FBQztZQUVILE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7WUFFNUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVEsQ0FBQztZQUN2RCxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQ3hDLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDO1lBQ3hDLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDO1lBRXRDLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxRQUFRLENBQ1gseUVBQStCLGlDQUV4QixJQUFJLENBQUMsS0FBSyxLQUNiLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQzFDLHFCQUFxQixFQUFFLHFFQUFlLENBQUMsT0FBTyxDQUFDO3dCQUM3QyxDQUFDLENBQUMsSUFBSSw4RUFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQzt3QkFDOUMsQ0FBQyxDQUFDLElBQUksS0FFVixJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQ25DLEVBQ0QsR0FBRyxFQUFFO29CQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDN0MsQ0FBQyxDQUNGLENBQUM7YUFDSDtpQkFBTTtnQkFDTCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDNUM7UUFDSCxDQUFDLENBQUM7UUFFTSwrQkFBMEIsR0FBRyxDQUNuQyxnQkFBa0MsRUFDbEMsS0FBaUMsRUFDM0IsRUFBRTs7WUFDUixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUNuRCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7WUFDbEQsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDcEIsT0FBTzthQUNSO1lBQ0QsSUFDRSxlQUFlLENBQUMsSUFBSSxLQUFLLFdBQVc7Z0JBQ3BDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQ3ZDO2dCQUNBLHlEQUFjLENBQ1osZUFBZSxFQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFDMUIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsYUFBYSxDQUFDLENBQUMsRUFDZixhQUFhLENBQUMsQ0FBQyxFQUNmLGlEQUFRLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQ3BELGlEQUFRLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQ3BELGlFQUF5QixDQUFDLEtBQUssQ0FBQyxFQUNoQyw4REFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FDOUIsQ0FBQzthQUNIO2lCQUFNO2dCQUNMLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsb0RBQVksQ0FDakMsYUFBYSxDQUFDLENBQUMsRUFDZixhQUFhLENBQUMsQ0FBQyxFQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO2dCQUVGLE1BQU0sS0FBSyxHQUNULCtFQUF5QixDQUFDLGVBQWUsQ0FBQztxQkFDMUMsVUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQywwQ0FBRSxLQUFLLEVBQUM7Z0JBQ3JELE1BQU0sV0FBVyxHQUNmLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZLE9BQU8sQ0FBQztvQkFDbEMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU07b0JBQzVCLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBRVgseURBQWMsQ0FDWixlQUFlLEVBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUMxQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUMvQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUMvQixLQUFLLEVBQ0wsS0FBSyxFQUNMLGlEQUFRLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFDaEQsaURBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUNoRCxvRUFBYyxDQUFDLGVBQWUsQ0FBQztvQkFDN0IsQ0FBQyxDQUFDLENBQUMsaUVBQXlCLENBQUMsS0FBSyxDQUFDO29CQUNuQyxDQUFDLENBQUMsaUVBQXlCLENBQUMsS0FBSyxDQUFDLEVBQ3BDLDhEQUFzQixDQUFDLEtBQUssQ0FBQyxFQUM3QixXQUFXLENBQ1osQ0FBQztnQkFFRixJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO2FBQ25EO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sc0JBQWlCLEdBQUcsQ0FDMUIsZ0JBQWtDLEVBQ2xDLEtBQWlDLEVBQ3hCLEVBQUU7WUFDWCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUNGLE1BQU0sbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUMvRCxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLDhEQUE4RDtnQkFDOUQsOERBQThEO2dCQUM5RCxXQUFXO2dCQUNYLFVBQVUsRUFBRSxtQkFBbUIsSUFBSSxtQkFBbUIsS0FBSyxVQUFVO2dCQUNyRSxVQUFVLEVBQUUsbUJBQW1CLEtBQUssVUFBVTthQUMvQyxDQUFDLENBQUM7WUFDSCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7WUFDbEQsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxvREFBWSxDQUNyQyxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNsRCxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNsRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztZQUNGLElBQ0UsNERBQWlCLENBQ2YsZ0JBQWdCLEVBQ2hCLG1CQUFtQixFQUNuQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFDdEMscUVBQTZCLENBQUMsS0FBSyxDQUFDLEVBQ3BDLDhEQUFzQixDQUFDLEtBQUssQ0FBQyxFQUM3QixnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLG9FQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xFLENBQUMsQ0FBQyxDQUFDLGlFQUF5QixDQUFDLEtBQUssQ0FBQztnQkFDbkMsQ0FBQyxDQUFDLGlFQUF5QixDQUFDLEtBQUssQ0FBQyxFQUNwQyxPQUFPLEVBQ1AsT0FBTyxFQUNQLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNoQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDakMsRUFDRDtnQkFDQSxJQUFJLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDakQsT0FBTyxJQUFJLENBQUM7YUFDYjtZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDO1FBRUYsZ0RBQWdEO1FBQ3hDLHFCQUFnQixHQUFHLENBQ3pCLEVBQ0UsSUFBSSxFQUNKLEdBQUcsR0FJSixFQUNELElBQTBCLEVBQzFCLEVBQUU7WUFDRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2FBQzlDO1lBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDNUIsTUFBTSxnQkFBZ0IsR0FBRyxzRUFBaUMsQ0FDeEQsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxrQkFBa0IsR0FBRyx3RUFBbUMsQ0FDNUQsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxtQkFBbUIsR0FBRywrRUFBMEMsQ0FDcEUsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxpQkFBaUIsR0FBRyw2RUFBd0MsQ0FDaEUsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxtQkFBbUIsR0FBRywyRUFBcUMsQ0FDL0QsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxpQkFBaUIsR0FBRyx5RUFBbUMsQ0FDM0QsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDO1lBRTlCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUVwRCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUF3QixFQUFFLENBQUM7WUFDeEMsSUFBSSxzRUFBNkIsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDeEQsT0FBTyxDQUFDLElBQUksQ0FBQyxxREFBZSxDQUFDLENBQUM7YUFDL0I7WUFFRCxJQUFJLDJFQUFrQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUM3RCxPQUFPLENBQUMsSUFBSSxDQUFDLHFEQUFlLENBQUMsQ0FBQzthQUMvQjtZQUVELElBQ0UsSUFBSSxLQUFLLFNBQVM7Z0JBQ2xCLG1FQUE2QixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUNuRCwyRUFBa0MsRUFDbEM7Z0JBQ0EsT0FBTyxDQUFDLElBQUksQ0FBQyw4Q0FBUSxDQUFDLENBQUM7YUFDeEI7WUFDRCxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUU7Z0JBQ3JCLE1BQU0sZUFBZSxHQUFHO29CQUN0QixHQUFHLE9BQU87b0JBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxXQUFXO3dCQUMvQywwREFBb0I7b0JBQ3RCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEtBQUssV0FBVyxJQUFJLHlEQUFtQjtvQkFDdkUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxXQUFXO3dCQUMvQyxnRkFBb0I7b0JBQ3RCLHVEQUFpQjtpQkFDbEIsQ0FBQztnQkFFRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO29CQUM5QiwwREFBZ0IsQ0FBQzt3QkFDZixPQUFPLEVBQUUsZUFBZTt3QkFDeEIsR0FBRzt3QkFDSCxJQUFJO3dCQUNKLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTt3QkFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLO3dCQUNwQixTQUFTLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVE7d0JBQy9DLFFBQVE7cUJBQ1QsQ0FBQyxDQUFDO2lCQUNKO3FCQUFNO29CQUNMLDBEQUFnQixDQUFDO3dCQUNmLE9BQU8sRUFBRTs0QkFDUCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVE7Z0NBQ2xCLFNBQVMsQ0FBQyxTQUFTLElBQUk7Z0NBQ3JCLFVBQVUsRUFBRSxLQUFLO2dDQUNqQixJQUFJLEVBQUUsT0FBTztnQ0FDYixPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEVBQUU7b0NBQy9CLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQ0FDOUIsT0FBTzt3Q0FDTCxlQUFlLEVBQUUsS0FBSztxQ0FDdkIsQ0FBQztnQ0FDSixDQUFDO2dDQUNELGdCQUFnQixFQUFFLGNBQWM7NkJBQ2pDOzRCQUNILElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxTQUFTLElBQUksU0FBUzs0QkFDeEQsc0VBQTZCO2dDQUMzQixRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7Z0NBQ25CLHFEQUFlOzRCQUNqQiwyRUFBa0M7Z0NBQ2hDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQ0FDbkIscURBQWU7NEJBQ2pCLDJFQUFrQztnQ0FDaEMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUM7Z0NBQzNCLDhDQUFROzRCQUNWLENBQUMsQ0FBQyxzRUFBNkIsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztnQ0FDckQsQ0FBQywyRUFBa0MsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dDQUM1RCxTQUFTOzRCQUNYLHFEQUFlOzRCQUNmLFNBQVM7NEJBQ1QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxXQUFXO2dDQUMvQywwREFBb0I7NEJBQ3RCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEtBQUssV0FBVztnQ0FDOUMseURBQW1COzRCQUNyQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLFdBQVc7Z0NBQy9DLGdGQUFvQjs0QkFDdEIsdURBQWlCO3lCQUNsQjt3QkFDRCxHQUFHO3dCQUNILElBQUk7d0JBQ0osYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO3dCQUNqQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUs7d0JBQ3BCLFNBQVMsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUTt3QkFDL0MsUUFBUTtxQkFDVCxDQUFDLENBQUM7aUJBQ0o7YUFDRjtpQkFBTSxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7Z0JBQzdCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7b0JBQzlCLDBEQUFnQixDQUFDO3dCQUNmLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxTQUFTLElBQUksZ0RBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQzt3QkFDeEQsR0FBRzt3QkFDSCxJQUFJO3dCQUNKLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTt3QkFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLO3dCQUNwQixTQUFTLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVE7d0JBQy9DLFFBQVE7cUJBQ1QsQ0FBQyxDQUFDO2lCQUNKO3FCQUFNO29CQUNMLDBEQUFnQixDQUFDO3dCQUNmLE9BQU8sRUFBRTs0QkFDUCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSwrQ0FBUzs0QkFDakMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLFNBQVMsSUFBSSxnREFBVTs0QkFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO2dDQUNsQixTQUFTLENBQUMsU0FBUyxJQUFJO2dDQUNyQixJQUFJLEVBQUUsT0FBTztnQ0FDYixVQUFVLEVBQUUsS0FBSztnQ0FDakIsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxFQUFFO29DQUMvQixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7b0NBQzlCLE9BQU87d0NBQ0wsZUFBZSxFQUFFLEtBQUs7cUNBQ3ZCLENBQUM7Z0NBQ0osQ0FBQztnQ0FDRCxnQkFBZ0IsRUFBRSxjQUFjOzZCQUNqQzs0QkFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxTQUFTOzRCQUNqQyxHQUFHLE9BQU87NEJBQ1YsU0FBUzs0QkFDVCxzREFBZ0I7NEJBQ2hCLHVEQUFpQjs0QkFDakIsU0FBUzs0QkFDVCxnQkFBZ0IsSUFBSSxpREFBVzs0QkFDL0IsbUJBQW1CLElBQUksc0RBQWdCOzRCQUN2QyxpQkFBaUIsSUFBSSxvREFBYzs0QkFDbkMsa0JBQWtCLElBQUksbURBQWE7NEJBQ25DLENBQUMsZ0JBQWdCLElBQUksa0JBQWtCLENBQUMsSUFBSSxTQUFTOzRCQUNyRCx3REFBa0I7NEJBQ2xCLFNBQVM7NEJBQ1Qsd0RBQWtCOzRCQUNsQix3REFBa0I7NEJBQ2xCLHNEQUFnQjs0QkFDaEIsd0RBQWtCOzRCQUNsQixTQUFTOzRCQUNULG1CQUFtQixJQUFJLDBEQUFvQjs0QkFDM0MsaUJBQWlCLElBQUksd0RBQWtCOzRCQUN2QyxDQUFDLG1CQUFtQixJQUFJLGlCQUFpQixDQUFDLElBQUksU0FBUzs0QkFDdkQscUVBQStCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxnREFBVTs0QkFDbkUsOERBQXdCOzRCQUN4QixzREFBZ0I7NEJBQ2hCLFNBQVM7NEJBQ1QsMERBQW9CO3lCQUNyQjt3QkFDRCxHQUFHO3dCQUNILElBQUk7d0JBQ0osYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO3dCQUNqQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUs7d0JBQ3BCLFNBQVMsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUTt3QkFDL0MsUUFBUTtxQkFDVCxDQUFDLENBQUM7aUJBQ0o7YUFDRjtRQUNILENBQUMsQ0FBQztRQUVNLGdCQUFXLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDN0QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksU0FBUyxFQUFFO2dCQUNiLE9BQU87YUFDUjtZQUVELE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDO1lBQ2pDLCtEQUErRDtZQUMvRCxJQUFJLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtnQkFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDL0IsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO2dCQUNwQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNsQyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUM7Z0JBQ25CLElBQUksUUFBUSxHQUFHLFFBQVEsRUFBRTtvQkFDdkIsS0FBSyxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUM7aUJBQ3pCO2dCQUVELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO2dCQUNsRCx3RUFBd0U7Z0JBQ3hFLE9BQU87b0JBQ0wsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDOUMsQ0FBQyxJQUFJO3dCQUNMLHlFQUF5RTt3QkFDekUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxHQUFHLEVBQUUsQ0FBQyxDQUFDO2dCQUU3QixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxpQ0FDcEIsNkRBQWUsQ0FDaEI7b0JBQ0UsU0FBUyxFQUFFLE9BQU87b0JBQ2xCLFNBQVMsRUFBRSxPQUFPO29CQUNsQixRQUFRLEVBQUUsMERBQWlCLENBQUMsT0FBTyxDQUFDO2lCQUNyQyxFQUNELEtBQUssQ0FDTixLQUNELHFCQUFxQixFQUFFLElBQUksSUFDM0IsQ0FBQyxDQUFDO2dCQUNKLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDO2dCQUMzQyxPQUFPO2FBQ1I7WUFFRCx5Q0FBeUM7WUFDekMsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFO2dCQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQ3BDLGdEQUFnRDtvQkFDaEQsT0FBTyxFQUFFLE9BQU8sR0FBRyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSztpQkFDbkQsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osT0FBTzthQUNSO1lBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDN0MsT0FBTyxFQUFFLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUs7Z0JBQ3RDLE9BQU8sRUFBRSxPQUFPLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLO2FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFxQ0ssZ0JBQVcsR0FBRyxDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsTUFBcUIsRUFBRSxFQUFFOztZQUNwRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO2dCQUNaLE9BQU87YUFDUjtZQUNELE1BQU0sT0FBTyxHQUFHLG9FQUEyQixDQUN6QyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUMxQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFFRixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDeEMsd0NBQXdDO2FBQ3pDO1lBRUQsZ0JBQUksQ0FBQyxLQUFLLEVBQUMsZUFBZSxtREFBRztnQkFDM0IsT0FBTztnQkFDUCxNQUFNO2dCQUNOLFdBQVcsRUFBRSxPQUFPLENBQUMsUUFBUTthQUM5QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFFTSx3Q0FBbUMsR0FBRyxpREFBUSxDQUFDLEdBQUcsRUFBRTtZQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLHFCQUFxQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDakQ7UUFDSCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFQSxrQkFBYSxHQUFHLENBQUMsRUFBZSxFQUFFLEVBQUU7O1lBQzFDLElBQUksVUFBSSxDQUFDLHNCQUFzQiwwQ0FBRSxPQUFPLEVBQUU7Z0JBQ3hDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQztnQkFDaEUsTUFBTSxFQUNKLEtBQUssRUFDTCxNQUFNLEVBQ04sSUFBSSxFQUFFLFVBQVUsRUFDaEIsR0FBRyxFQUFFLFNBQVMsR0FDZixHQUFHLG1CQUFtQixDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0JBQ2hELE1BQU0sRUFDSixLQUFLLEVBQUUsWUFBWSxFQUNuQixNQUFNLEVBQUUsYUFBYSxFQUNyQixTQUFTLEVBQUUsZ0JBQWdCLEVBQzNCLFVBQVUsRUFBRSxpQkFBaUIsR0FDOUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUVmLElBQ0UsS0FBSyxLQUFLLFlBQVk7b0JBQ3RCLE1BQU0sS0FBSyxhQUFhO29CQUN4QixVQUFVLEtBQUssaUJBQWlCO29CQUNoQyxTQUFTLEtBQUssZ0JBQWdCLEVBQzlCO29CQUNBLElBQUksRUFBRSxFQUFFO3dCQUNOLEVBQUUsRUFBRSxDQUFDO3FCQUNOO29CQUNELE9BQU87aUJBQ1I7Z0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FDWDtvQkFDRSxLQUFLO29CQUNMLE1BQU07b0JBQ04sVUFBVTtvQkFDVixTQUFTO2lCQUNWLEVBQ0QsR0FBRyxFQUFFO29CQUNILEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDYixDQUFDLENBQ0YsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUFDO1FBRUssWUFBTyxHQUFHLEdBQUcsRUFBRTtZQUNwQixJQUFJLENBQUMsUUFBUSxtQkFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRyxDQUFDO1FBQ2hELENBQUMsQ0FBQztRQWhzTEEsTUFBTSxlQUFlLEdBQUcsOERBQWtCLEVBQUUsQ0FBQztRQUM3QyxNQUFNLEVBQ0osYUFBYSxFQUNiLGVBQWUsR0FBRyxLQUFLLEVBQ3ZCLGNBQWMsR0FBRyxLQUFLLEVBQ3RCLGVBQWUsR0FBRyxLQUFLLEVBQ3ZCLEtBQUssR0FBRyxlQUFlLENBQUMsS0FBSyxFQUM3QixJQUFJLEdBQUcsZUFBZSxDQUFDLElBQUksR0FDNUIsR0FBRyxLQUFLLENBQUM7UUFDVixJQUFJLENBQUMsS0FBSywrREFDTCxlQUFlLEtBQ2xCLEtBQUssRUFDTCxTQUFTLEVBQUUsSUFBSSxLQUNaLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxLQUMxQixlQUFlO1lBQ2YsY0FBYyxFQUNkLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLGtEQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksRUFDNUMsSUFBSSxFQUNKLEtBQUssRUFBRSxNQUFNLENBQUMsVUFBVSxFQUN4QixNQUFNLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFDMUIsa0JBQWtCLEVBQUUsS0FBSyxFQUN6QixtQkFBbUIsRUFBRSxLQUFLLEdBQzNCLENBQUM7UUFFRixJQUFJLENBQUMsRUFBRSxHQUFHLCtDQUFNLEVBQUUsQ0FBQztRQUVuQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksc0RBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLGFBQWEsRUFBRTtZQUNqQixNQUFNLFlBQVksR0FDaEIsQ0FBQyxTQUFTLElBQUksYUFBYSxLQUFJLG1CQUFhLENBQUMsT0FBTywwQ0FBRSxZQUFZLEVBQUM7Z0JBQ25FLDBEQUFpQixFQUEyQixDQUFDO1lBRS9DLE1BQU0sR0FBRyxHQUE0QjtnQkFDbkMsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsWUFBWTtnQkFDWixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7Z0JBQ3pDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUMzQixnQ0FBZ0MsRUFBRSxJQUFJLENBQUMsZ0NBQWdDO2dCQUN2RSxPQUFPLEVBQUU7b0JBQ1AsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZO2lCQUN6QjtnQkFDRCxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7Z0JBQ3JDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQ3ZDLFdBQVcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSztnQkFDN0IsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLO2dCQUMxQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87Z0JBQ3JCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtnQkFDakMsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUN6QixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7YUFDckIsQ0FBQztZQUNYLElBQUksT0FBTyxhQUFhLEtBQUssVUFBVSxFQUFFO2dCQUN2QyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDcEI7aUJBQU07Z0JBQ0wsYUFBYSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7YUFDN0I7WUFDRCxZQUFZLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQzNCO1FBRUQsSUFBSSxDQUFDLHdCQUF3QixHQUFHO1lBQzlCLFNBQVMsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTztZQUM5QyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7U0FDWixDQUFDO1FBRUYsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLHFEQUFLLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksaURBQU8sRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSwyREFBYSxDQUNwQyxJQUFJLENBQUMsZ0JBQWdCLEVBQ3JCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQ2hCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsRUFDOUMsSUFBSSxDQUNMLENBQUM7UUFDRixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxzREFBTyxDQUFDLENBQUM7UUFFeEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsd0VBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsd0VBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVPLFlBQVk7UUFDbEIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBQzVDLE1BQU0sRUFDSixLQUFLLEVBQUUsY0FBYyxFQUNyQixNQUFNLEVBQUUsZUFBZSxFQUN2QixlQUFlLEdBQ2hCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNmLE1BQU0sV0FBVyxHQUFHLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDakQsTUFBTSxZQUFZLEdBQUcsZUFBZSxHQUFHLFdBQVcsQ0FBQztRQUNuRCxJQUFJLGVBQWUsRUFBRTtZQUNuQixPQUFPLENBQ0wsaUZBQ0UsU0FBUyxFQUFDLG9CQUFvQixFQUM5QixLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLGNBQWM7b0JBQ3JCLE1BQU0sRUFBRSxlQUFlO29CQUN2QixNQUFNLEVBQUUseURBQWdCO2lCQUN6QixFQUNELEtBQUssRUFBRSxXQUFXLEVBQ2xCLE1BQU0sRUFBRSxZQUFZLEVBQ3BCLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxXQUFXLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixFQUN2QyxlQUFlLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQ2pDLGFBQWEsRUFBRSxJQUFJLENBQUMsdUJBQXVCLGdCQUUxQyx5Q0FBQyxDQUFDLHNCQUFzQixDQUFDLElBQ25CLENBQ1YsQ0FBQztTQUNIO1FBQ0QsT0FBTyxDQUNMLGlGQUNFLFNBQVMsRUFBQyxvQkFBb0IsRUFDOUIsS0FBSyxFQUFFO2dCQUNMLEtBQUssRUFBRSxjQUFjO2dCQUNyQixNQUFNLEVBQUUsZUFBZTthQUN4QixFQUNELEtBQUssRUFBRSxXQUFXLEVBQ2xCLE1BQU0sRUFBRSxZQUFZLEVBQ3BCLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxXQUFXLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixFQUN2QyxlQUFlLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLGdCQUVoQyx5Q0FBQyxDQUFDLHNCQUFzQixDQUFDLElBQ25CLENBQ1YsQ0FBQztJQUNKLENBQUM7SUFJTSxNQUFNOztRQUNYLE1BQU0sZUFBZSxHQUFHLDREQUFtQixDQUN6QyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztRQUNGLE1BQU0sRUFDSixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWixpQkFBaUIsR0FDbEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBRWYsT0FBTyxDQUNMLDhFQUNFLFNBQVMsRUFBRSxnREFBSSxDQUFDLGlDQUFpQyxFQUFFO2dCQUNqRCx1QkFBdUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWU7Z0JBQ25ELG9CQUFvQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUTthQUMzQyxDQUFDLEVBQ0YsR0FBRyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsRUFDaEMsTUFBTSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQzVCLFFBQVEsRUFBRSxDQUFDLEVBQ1gsU0FBUyxFQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsZ0JBR2hFLHVEQUFDLDBCQUEwQixDQUFDLFFBQVEsa0JBQ2xDLEtBQUssRUFBRSxJQUFJLENBQUMsd0JBQXdCLGdCQUVwQyx3REFBQyxhQUFhLENBQUMsUUFBUSxrQkFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0saUJBQ3ZDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FDbEIsdURBQUMsaURBQU8sSUFDTixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFDbkIsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQ3BCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUNqQixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFDN0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQ2pDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQzVDLG1CQUFtQixFQUFFLG1CQUFtQixFQUN4QyxZQUFZLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFDN0IsZUFBZSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQ25DLGdCQUFnQixFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDN0IsSUFBSSxDQUFDLDZCQUE2QixDQUFDO2dDQUNqQyxRQUFRO2dDQUNSLFFBQVEsRUFBRSxRQUFRO2dDQUNsQixLQUFLLEVBQUUsSUFBSTs2QkFDWixDQUFDLEVBRUosUUFBUSxFQUFFLG1EQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQzVCLGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFDM0MsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLGtCQUFrQixFQUFFLFlBQVksRUFDaEMsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQ3BDLGtCQUFrQixFQUNoQixPQUFPLFdBQUksQ0FBQyxLQUFLLDBDQUFFLGNBQWMsTUFBSyxXQUFXO2dDQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFFM0IsWUFBWSxFQUNWLE9BQU8sV0FBSSxDQUFDLEtBQUssMENBQUUsS0FBSyxNQUFLLFdBQVc7Z0NBQ3hDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBRTFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQzdDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFDL0IsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQ25DLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUNyQixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFDWCxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsR0FDakMsQ0FDSCxFQUNELGdFQUFLLFNBQVMsRUFBQyxnQ0FBZ0MsR0FBRyxFQUNsRCxnRUFBSyxTQUFTLEVBQUMsaUNBQWlDLEdBQUcsRUFDbEQsZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxDQUNoRSx1REFBQywwREFBUyxJQUVSLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQzNCLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUNwQixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFDN0IsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUo1QixlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUsxQixDQUNILEVBQ0EsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQzVCLHVEQUFDLDBDQUFLLElBQ0osT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFDakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQ2xDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQ25DLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQ25DLENBQ0gsRUFDRCwyRUFBTyxJQUFJLENBQUMsWUFBWSxFQUFFLEdBQVEsS0FDWCxJQUNXLElBQ2xDLENBQ1AsQ0FBQztJQUNKLENBQUM7SUF1UFksaUJBQWlCOzs7WUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7WUFDdkIsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFNBQVM7Z0JBQ3JDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUM7WUFFdEMsSUFDRSxhQUFvQixLQUFLLGlEQUFRO2dCQUNqQyxhQUFvQixLQUFLLHdEQUFlO2dCQUN4QyxnNEJBQVcsQ0FBQyxvQkFBb0IsS0FBSyxTQUFTLEVBQzlDO2dCQUNBLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMxQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtvQkFDaEMsS0FBSyxFQUFFO3dCQUNMLFlBQVksRUFBRSxJQUFJO3dCQUNsQixHQUFHLEVBQUUsR0FBRyxFQUFFOzRCQUNSLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQzt3QkFDcEIsQ0FBQztxQkFDRjtvQkFDRCxRQUFRLEVBQUU7d0JBQ1IsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLEtBQUssRUFBRSxDQUFDLEdBQUcsSUFBaUMsRUFBRSxFQUFFOzRCQUM5QyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQzt3QkFDaEMsQ0FBQztxQkFDRjtvQkFDRCxHQUFHLEVBQUU7d0JBQ0gsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLEtBQUssRUFBRSxJQUFJO3FCQUNaO29CQUNELE9BQU8sRUFBRTt3QkFDUCxZQUFZLEVBQUUsSUFBSTt3QkFDbEIsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPO3FCQUNwQjtpQkFDRixDQUFDLENBQUM7YUFDSjtZQUVELElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUV6QixJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN2QjtZQUVELElBQ0UsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU87Z0JBQ25DLGlEQUFpRDtnQkFDakQsK0RBQStEO2dCQUMvRCxnRUFBZ0U7Z0JBQ2hFLGFBQW9CLEtBQUssTUFBTSxFQUMvQjtnQkFDQSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQzlEO1lBRUQsSUFBSSxnQkFBZ0IsSUFBSSxNQUFNLEtBQUksVUFBSSxDQUFDLHNCQUFzQiwwQ0FBRSxPQUFPLEdBQUU7Z0JBQ3RFLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUMsR0FBRyxFQUFFO29CQUM1QyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7b0JBQzdCLG9DQUFvQztvQkFDcEMsd0VBQXdFO29CQUN4RSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVEsQ0FBQyxDQUFDO29CQUM5RCxrQkFBa0I7b0JBQ2xCLHdFQUF3RTtvQkFDeEUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixDQUFDLENBQUMsQ0FBQztnQkFDSCxVQUFJLENBQUMsY0FBYywwQ0FBRSxPQUFPLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ25FO2lCQUFNLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRTtnQkFDNUIsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FDckMsZUFBZSw4REFBcUIscUJBQXFCLGdFQUF1Qix1QkFBdUIsK0RBQXNCLEtBQUssQ0FDbkksQ0FBQztnQkFDRixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUNyQyxlQUFlLHdEQUFlLEtBQUssQ0FDcEMsQ0FBQztnQkFDRixNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQ3JELGVBQWU7Z0JBQ2IsK0RBQStEO2dCQUMvRCxjQUFjO2dCQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLHVCQUF1QixJQUFJLElBQUk7b0JBQ2xELENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUI7b0JBQzlDLENBQUMsQ0FBQyxtRUFDTixLQUFLLENBQ04sQ0FBQztnQkFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUU7b0JBQ25CLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFRLENBQUMscUJBQXFCLEVBQUUsQ0FBQztvQkFDN0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxxREFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7d0JBQ3RDLFVBQVUsRUFBRSxhQUFhLENBQUMsT0FBTzt3QkFDakMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxPQUFPO3dCQUMvQixtQkFBbUIsRUFBRSw2QkFBNkIsQ0FBQyxPQUFPO3FCQUMzRCxDQUFDLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2dCQUNGLGFBQWEsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxHQUFHLEVBQUUsQ0FDbEMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN6QztZQUVELE1BQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTFFLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO2dCQUN4Qyw4REFBOEQ7Z0JBQzlELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2FBQzdCO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2FBQzFDOztLQUNGO0lBRU0sb0JBQW9COztRQUN6QixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLFVBQUksQ0FBQyxjQUFjLDBDQUFFLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckIsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzNCLFlBQVksR0FBRyxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQVNPLG9CQUFvQjs7UUFDMUIsUUFBUSxDQUFDLG1CQUFtQixDQUFDLHlEQUFnQixFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRSxRQUFRLENBQUMsbUJBQW1CLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEQsUUFBUSxDQUFDLG1CQUFtQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbkUsUUFBUSxDQUFDLG1CQUFtQixDQUFDLGtEQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BELFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLG1CQUFtQixDQUN0RCxvREFBVyxFQUNYLElBQUksQ0FBQyxPQUFPLENBQ2IsQ0FBQztRQUNGLFVBQUksQ0FBQywwQkFBMEIsMENBQUUsbUJBQW1CLENBQ2xELHFEQUFZLEVBQ1osSUFBSSxDQUFDLFFBQVEsQ0FDZCxDQUFDO1FBQ0YsUUFBUSxDQUFDLG1CQUFtQixDQUFDLHNEQUFhLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuRSxRQUFRLENBQUMsbUJBQW1CLENBQzFCLHlEQUFnQixFQUNoQixJQUFJLENBQUMsMkJBQTJCLEVBQ2hDLEtBQUssQ0FDTixDQUFDO1FBQ0YsUUFBUSxDQUFDLG1CQUFtQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxxREFBWSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLG1CQUFtQixDQUFDLHFEQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsbUJBQW1CLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNELFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLG1CQUFtQixDQUN0RCx3REFBZSxFQUNmLElBQUksQ0FBQyxZQUFZLEVBQ2pCLEtBQUssQ0FDTixDQUFDO1FBQ0YsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsbUJBQW1CLENBQ3RELG1EQUFVLEVBQ1YsSUFBSSxDQUFDLFlBQVksRUFDakIsS0FBSyxDQUNOLENBQUM7UUFFRixRQUFRLENBQUMsbUJBQW1CLENBQzFCLDREQUFtQixFQUNuQixJQUFJLENBQUMsY0FBcUIsRUFDMUIsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsbUJBQW1CLENBQzFCLDZEQUFvQixFQUNwQixJQUFJLENBQUMsZUFBc0IsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsbUJBQW1CLENBQzFCLDBEQUFpQixFQUNqQixJQUFJLENBQUMsWUFBbUIsRUFDeEIsS0FBSyxDQUNOLENBQUM7UUFFRixVQUFJLENBQUMsdUJBQXVCLG9EQUFJLENBQUM7SUFDbkMsQ0FBQztJQUVPLGlCQUFpQjs7UUFDdkIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsUUFBUSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFFBQVE7UUFDekUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLG1EQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLGdCQUFnQixDQUNuRCxvREFBVyxFQUNYLElBQUksQ0FBQyxPQUFPLEVBQ1osRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQ25CLENBQUM7UUFFRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEVBQUU7WUFDckMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLHNEQUFhLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUNqRTtRQUNELFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RSxRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLHlEQUFnQixFQUNoQixJQUFJLENBQUMsMkJBQTJCLENBQ2pDLENBQUM7UUFDRiwyREFBMkQ7UUFDM0Qsb0JBQVEsQ0FBQyxLQUFLLDBDQUFFLGdCQUFnQixtREFBRyxhQUFhLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3JFLGlDQUFpQztRQUNqQyxRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLDREQUFtQixFQUNuQixJQUFJLENBQUMsY0FBcUIsRUFDMUIsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLDZEQUFvQixFQUNwQixJQUFJLENBQUMsZUFBc0IsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLDBEQUFpQixFQUNqQixJQUFJLENBQUMsWUFBbUIsRUFDeEIsS0FBSyxDQUNOLENBQUM7UUFDRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQzlCLE9BQU87U0FDUjtRQUVELFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hFLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxrREFBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO1lBQzNCLElBQUksQ0FBQywwQkFBMEIsR0FBRyxzRUFBNkIsQ0FDN0QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVEsQ0FDckMsQ0FBQztZQUNGLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxnQkFBZ0IsQ0FDOUMscURBQVksRUFDWixJQUFJLENBQUMsUUFBUSxDQUNkLENBQUM7U0FDSDtRQUNELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxxREFBWSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHFEQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hELFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLGdCQUFnQixDQUNuRCx3REFBZSxFQUNmLElBQUksQ0FBQyxZQUFZLEVBQ2pCLEtBQUssQ0FDTixDQUFDO1FBQ0YsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsZ0JBQWdCLENBQ25ELG1EQUFVLEVBQ1YsSUFBSSxDQUFDLFlBQVksRUFDakIsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRUQsa0JBQWtCLENBQUMsU0FBbUIsRUFBRSxTQUFtQjs7UUFDekQsSUFDRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTztZQUNuQyxTQUFTLENBQUMsU0FBUyxDQUFDLHVCQUF1QjtnQkFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQzlDO1lBQ0EsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUM5RDtRQUVELElBQ0UsU0FBUyxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87WUFDeEMsU0FBUyxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFDeEM7WUFDQSxnQkFBSSxDQUFDLEtBQUssMENBQUUsY0FBYyxtREFBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3RFO1FBRUQsSUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxNQUFNO1lBQ2pELDBEQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUMxQjtZQUNBLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1osVUFBVSxFQUFFLHlEQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7YUFDaEUsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRO1lBQ3ZDLFNBQVMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQ3BDO1lBQ0Esd0RBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDaEQ7UUFDRCxtRUFBbUU7UUFDbkUsSUFDRSxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXO1lBQ3pDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXO1lBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQzdCO1lBQ0EsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDOUM7UUFDRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDOUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxTQUFTLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztTQUNsRTtRQUVELElBQUksU0FBUyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtZQUM1RCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtRQUVELElBQUksU0FBUyxDQUFDLGNBQWMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRTtZQUMxRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7U0FDaEU7UUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDNUM7UUFFRCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLGtEQUFTLENBQUMsQ0FBQyxDQUFDLElBQUk7YUFDeEQsQ0FBQyxDQUFDO1NBQ0o7UUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO2FBQ3RCLENBQUMsQ0FBQztTQUNKO1FBRUQsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsU0FBUyxDQUFDLE1BQU0sQ0FDbkQsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FDNUIsQ0FBQztRQUVGLElBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7WUFDL0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQ3pFO1lBQ0Esd0VBQXdFO1lBQ3hFLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1NBQ0o7UUFFRCxJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO1lBQ2hDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxFQUMxRTtZQUNBLG1IQUFtSDtZQUNuSCxzREFBc0Q7WUFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLHFCQUFxQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7U0FDaEQ7UUFFRCxNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQ25DLElBQ0UsU0FBUyxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVU7WUFDOUMsWUFBWSxJQUFJLElBQUk7WUFDcEIsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM1QixzRUFBZ0IsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLEVBQ3JDO1lBQ0EseUVBQXNCLENBQ3BCLFlBQVksRUFDWixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxLQUFLLEVBQ1YscURBQVksQ0FDViwrR0FBb0QsQ0FDbEQsWUFBWSxFQUNaLENBQUMsQ0FBQyxDQUNILENBQ0YsQ0FDRixDQUFDO1NBQ0g7UUFDRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQztRQUUxRSx3RUFBd0U7UUFDeEUseUVBQXlFO1FBQ3pFLDJFQUEyRTtRQUMzRSxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ3pCLGdCQUFJLENBQUMsS0FBSyxFQUFDLFFBQVEsbURBQ2pCLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsRUFDeEMsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7U0FDSDtJQUNILENBQUM7SUF1Sk8sTUFBTSxDQUFDLGFBQWE7UUFDMUIsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBc09PLGdCQUFnQixDQUFDLElBQVM7UUFDaEMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxvRUFBMkIsQ0FDMUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFDdEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQUcseURBQWMsQ0FBQztZQUM3QixDQUFDO1lBQ0QsQ0FBQztZQUNELFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtZQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7WUFDdEQsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtZQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7WUFDOUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtZQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7WUFDdEQsSUFBSTtZQUNKLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtZQUN4QyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUI7WUFDNUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLGFBQWEsRUFBRSwrREFBc0I7WUFDckMsTUFBTSxFQUFFLEtBQUs7U0FDZCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1lBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtZQUMzQyxPQUFPO1NBQ1IsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDakMsQ0FBQztJQWlnQk8saUJBQWlCLENBQ3ZCLE9BQThCLEVBQzlCLEVBQ0UsaUJBQWlCLEdBQUcsS0FBSyxHQUcxQjtRQUVELE1BQU0sYUFBYSxHQUFHLENBQ3BCLElBQVksRUFDWixZQUFvQixFQUNwQixTQUFrQixFQUNsQixFQUFFO1lBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFDNUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQzNELElBQUksUUFBUSxDQUFDLEVBQUUsS0FBSyxPQUFPLENBQUMsRUFBRSxJQUFJLHdEQUFhLENBQUMsUUFBUSxDQUFDLEVBQUU7d0JBQ3pELE9BQU8sNERBQWlCLENBQUMsUUFBUSxFQUFFOzRCQUNqQyxJQUFJOzRCQUNKLFNBQVM7NEJBQ1QsWUFBWTt5QkFDYixDQUFDLENBQUM7cUJBQ0o7b0JBQ0QsT0FBTyxRQUFRLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQzthQUNILENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGLHNEQUFXLENBQUM7WUFDVixFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDZCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzFCLE1BQU0sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxvRUFBMkIsQ0FDaEU7b0JBQ0UsTUFBTSxFQUFFLENBQUM7b0JBQ1QsTUFBTSxFQUFFLENBQUM7aUJBQ1YsRUFDRCxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsT0FBTztvQkFDTCxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVO29CQUNqQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO2lCQUNqQyxDQUFDO1lBQ0osQ0FBQztZQUNELFFBQVEsRUFBRSwyREFBa0IsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNwQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDakMsSUFBSSw4REFBbUIsQ0FBQyxPQUFPLENBQUMsRUFBRTtvQkFDaEMsc0VBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQzlCO1lBQ0gsQ0FBQyxDQUFDO1lBQ0YsUUFBUSxFQUFFLDJEQUFrQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUU7Z0JBQ25FLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUMvQixhQUFhLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDN0Msa0VBQWtFO2dCQUNsRSxrRUFBa0U7Z0JBQ2xFLElBQUksQ0FBQyxTQUFTLElBQUksV0FBVyxFQUFFO29CQUM3QixNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxXQUFXO3dCQUMzQyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVc7d0JBQ3JCLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7d0JBQzVCLGtCQUFrQixrQ0FDYixTQUFTLENBQUMsa0JBQWtCLEtBQy9CLENBQUMsaUJBQWlCLENBQUMsRUFBRSxJQUFJLEdBQzFCO3FCQUNGLENBQUMsQ0FBQyxDQUFDO2lCQUNMO2dCQUNELElBQUksU0FBUyxFQUFFO29CQUNiLDJFQUF3QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFBRTt3QkFDM0QsT0FBTztxQkFDUixDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsSUFBSSxDQUFDLFNBQVMsSUFBSSxpQkFBaUIsRUFBRTtvQkFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDaEM7Z0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsSUFBSTtvQkFDckIsY0FBYyxFQUFFLElBQUk7aUJBQ3JCLENBQUMsQ0FBQztnQkFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTtvQkFDaEMsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQzVDO2dCQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixDQUFDLENBQUM7WUFDRixPQUFPO1lBQ1AsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU87WUFDeEQsR0FBRyxFQUFFLElBQUk7U0FDVixDQUFDLENBQUM7UUFDSCxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsdUVBQXVFO1FBQ3ZFLHVFQUF1RTtRQUN2RSxhQUFhLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUNaLGtCQUFrQixFQUFFLEVBQUU7WUFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtZQUNwQixjQUFjLEVBQUUsSUFBSTtTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sd0JBQXdCLENBQzlCLENBQVMsRUFDVCxDQUFTO1FBRVQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDOUMsdUJBQXVCLEVBQUUsSUFBSTtTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sSUFBSSx3REFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRTtZQUMzRCxPQUFPLE9BQU8sQ0FBQztTQUNoQjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLG9CQUFvQixDQUMxQixDQUFTLEVBQ1QsQ0FBUyxFQUNULElBTUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQy9DLENBQUMsRUFDRCxDQUFDLEVBQ0QsSUFBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLHVCQUF1QixFQUM3QixJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUscUJBQXFCLENBQzVCLENBQUM7UUFDRixJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLElBQUksSUFBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLGNBQWMsRUFBRTtnQkFDeEIsS0FBSyxJQUFJLEtBQUssR0FBRyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUU7b0JBQy9ELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7d0JBQzNELE9BQU8sY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUM5QjtpQkFDRjthQUNGO1lBQ0QsTUFBTSx3QkFBd0IsR0FDNUIsY0FBYyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDNUMseUVBQXlFO1lBQ3pFLDRFQUE0RTtZQUM1RSxPQUFPLDJGQUFnRCxDQUNyRCx3QkFBd0IsRUFDeEIsSUFBSSxDQUFDLEtBQUssRUFDVixDQUFDLEVBQ0QsQ0FBQyxDQUNGO2dCQUNDLENBQUMsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQzNDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQztTQUM5QjtRQUNELElBQUksY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDL0IsT0FBTyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDMUI7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxxQkFBcUIsQ0FDM0IsQ0FBUyxFQUNULENBQVMsRUFDVCwwQkFBbUMsS0FBSyxFQUN4Qyx3QkFBaUMsS0FBSztRQUV0QyxNQUFNLFFBQVEsR0FDWix1QkFBdUIsSUFBSSxxQkFBcUI7WUFDOUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUU7WUFDcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLO2lCQUNQLHFCQUFxQixFQUFFO2lCQUN2QixNQUFNLENBQ0wsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNWLENBQUMscUJBQXFCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUMxQyxDQUFDLHVCQUF1QjtvQkFDdEIsQ0FBQyxDQUFDLHdEQUFhLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQ3RELENBQUM7UUFFVixPQUFPLDhEQUFxQixDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQ2pELGtEQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUNuQyxDQUFDO0lBQ0osQ0FBQztJQTR0QkQsZ0NBQWdDLENBQzlCLG1CQUF3QyxFQUN4QyxhQUFxQixFQUNyQixhQUFxQjtRQUVyQixNQUFNLE9BQU8sR0FBRyx5RkFBOEIsQ0FDNUMsbUJBQW1CLENBQUMsU0FBUyxDQUM5QixDQUFDO1FBRUYsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNaLE9BQU87U0FDUjtRQUNELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRTtZQUNwQyxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN6QixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDNUIsSUFDRSw4RkFBeUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDN0QsYUFBYTtnQkFDYixhQUFhO2FBQ2QsQ0FBQyxFQUNGO2dCQUNBLGVBQWUsR0FBRyx1R0FBNEMsQ0FDNUQsT0FBTyxFQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNmLGFBQWEsRUFDYixhQUFhLENBQ2QsQ0FBQztnQkFDRixlQUFlLEdBQUcsZ0dBQXFDLENBQ3JELG1CQUFtQixFQUNuQixFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxFQUN0QyxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsSUFBSSxlQUFlLElBQUksQ0FBQyxJQUFJLGVBQWUsRUFBRTtvQkFDM0Msa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDREQUFtQixDQUFDLENBQUM7aUJBQzdDO3FCQUFNO29CQUNMLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5REFBZ0IsQ0FBQyxDQUFDO2lCQUMxQzthQUNGO2lCQUFNLElBQ0wsaUZBQXFCLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDO2dCQUM1QywyRkFBZ0QsQ0FDOUMsT0FBTyxFQUNQLElBQUksQ0FBQyxLQUFLLEVBQ1YsYUFBYSxFQUNiLGFBQWEsQ0FDZCxFQUNEO2dCQUNBLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5REFBZ0IsQ0FBQyxDQUFDO2FBQzFDO1lBRUQsSUFDRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLGVBQWUsS0FBSyxlQUFlLEVBQ3BFO2dCQUNBLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1oscUJBQXFCLGtDQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixLQUNuQyxlQUFlLEdBQ2hCO2lCQUNGLENBQUMsQ0FBQzthQUNKO1lBRUQsSUFDRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLGVBQWUsS0FBSyxlQUFlLEVBQ3BFO2dCQUNBLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1oscUJBQXFCLGtDQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixLQUNuQyxlQUFlLEdBQ2hCO2lCQUNGLENBQUMsQ0FBQzthQUNKO1NBQ0Y7YUFBTTtZQUNMLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5REFBZ0IsQ0FBQyxDQUFDO1NBQzFDO0lBQ0gsQ0FBQztJQWtPTyxpQ0FBaUMsQ0FDdkMsS0FBNEM7UUFFNUMsSUFBSSxhQUFhLEtBQUssSUFBSSxFQUFFO1lBQzFCLHlFQUF5RTtZQUN6RSxrRkFBa0Y7WUFDbEYsOERBQThEO1lBQzlELGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0QjtJQUNILENBQUM7SUFtR08sMEJBQTBCLENBQ2hDLEtBQTRDO1FBRTVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7WUFDcEMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ2hCLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTztTQUNqQixDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtZQUMvQixPQUFPLENBQUMsVUFBVSxHQUFHLG9EQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pELE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzdDLE9BQU8sQ0FBQyxlQUFlLEdBQUcsc0RBQVcsQ0FDbkMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQ3RDLENBQUM7U0FDSDtJQUNILENBQUM7SUFFTyx1QkFBdUIsQ0FDN0IsS0FBNEM7UUFFNUMsTUFBTSxNQUFNLEdBQUcsb0VBQTJCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5RCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztRQUNGLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRywwREFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFbkUsT0FBTztZQUNMLE1BQU07WUFDTixhQUFhLEVBQUUsS0FBSyxDQUFDLG9EQUFnQixDQUFDO1lBQ3RDLFlBQVksRUFBRSxxREFBWSxDQUN4QixvREFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUN0RDtZQUNELFVBQVUsRUFBRSx5REFBZ0IsQ0FDMUIsaUJBQWlCLEVBQ2pCLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQ3JDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQ3JDO1lBQ0QsNERBQTREO1lBQzVELFVBQVUsb0JBQU8sTUFBTSxDQUFFO1lBQ3pCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLO2lCQUN6QixxQkFBcUIsRUFBRTtpQkFDdkIsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFO2dCQUN2QixHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUscUVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBMEMsQ0FBQztZQUN2RCxNQUFNLEVBQUU7Z0JBQ04sVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQ3RCLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7YUFDdkQ7WUFDRCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsY0FBYyxFQUFFLEVBQUU7Z0JBQ2xCLG1CQUFtQixFQUFFLEtBQUs7Z0JBQzFCLGlCQUFpQixFQUFFLEtBQUs7Z0JBQ3hCLHlDQUF5QyxFQUN2QyxJQUFJLENBQUMsNENBQTRDLENBQy9DLE1BQU0sRUFDTixnQkFBZ0IsQ0FDakI7YUFDSjtZQUNELElBQUksRUFBRTtnQkFDSixXQUFXLEVBQUUsS0FBSztnQkFDbEIsTUFBTSxFQUFFLElBQUk7YUFDYjtZQUNELGNBQWMsRUFBRTtnQkFDZCxNQUFNLEVBQUUsSUFBSTtnQkFDWixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUUsSUFBSTtnQkFDYixTQUFTLEVBQUUsSUFBSTthQUNoQjtZQUNELFlBQVksRUFBRTtnQkFDWixXQUFXLEVBQUUsS0FBSzthQUNuQjtZQUNELGlCQUFpQixFQUFFLEVBQUU7U0FDdEIsQ0FBQztJQUNKLENBQUM7SUFFRCxzREFBc0Q7SUFDOUMsdUJBQXVCLENBQzdCLEtBQTRDLEVBQzVDLGdCQUFrQztRQUVsQyxJQUNFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFDdkU7WUFDQSxPQUFPLEtBQUssQ0FBQztTQUNkO1FBQ0QsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQzNCLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM5QyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDOUMsTUFBTSxhQUFhLEdBQUcsb0VBQTJCLENBQUMsQ0FBQyxLQUFtQixFQUFFLEVBQUU7WUFDeEUsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUM1QixJQUFJLENBQUMsQ0FBQyxNQUFNLFlBQVksV0FBVyxDQUFDLEVBQUU7Z0JBQ3BDLE9BQU87YUFDUjtZQUVELElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxHQUFHLDJEQUFrQixDQUFDLEdBQUcsRUFBRTtZQUMxQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7WUFDNUIsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0MsYUFBYSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLFlBQVksRUFBRSxJQUFJO2FBQ25CLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3JELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQywyREFBa0IsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsbUJBQW1CLENBQUMseURBQWdCLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDMUQsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO1FBRUgsYUFBYSxHQUFHLFdBQVcsQ0FBQztRQUU1QixNQUFNLENBQUMsZ0JBQWdCLENBQUMsMkRBQWtCLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDM0QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQW9OTyxrQkFBa0IsQ0FBQyxVQUFvQztRQUM3RCxPQUFPLFVBQVUsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVPLDRDQUE0QyxDQUNsRCxLQUF5QyxFQUN6QyxnQkFBOEM7UUFFOUMsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQy9CLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxpRUFBaUU7UUFDakUsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUM3QyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsMERBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzNELE9BQU8sQ0FDTCxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTO1lBQ3hCLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVM7WUFDeEIsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUztZQUN4QixLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQ3pCLENBQUM7SUFDSixDQUFDO0lBc1JPLCtCQUErQixDQUNyQyxnQkFBa0M7UUFFbEMsT0FBTywyREFBa0IsQ0FBQyxDQUFDLEtBQW9CLEVBQUUsRUFBRTtZQUNqRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDbkQsT0FBTzthQUNSO1lBQ0QsSUFBSSxDQUFDLDBCQUEwQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLDZCQUE2QixDQUNuQyxnQkFBa0M7UUFFbEMsT0FBTywyREFBa0IsQ0FBQyxDQUFDLEtBQW9CLEVBQUUsRUFBRTtZQUNqRCw4Q0FBOEM7WUFDOUMsS0FBSyxDQUFDLEdBQUcsS0FBSyw0Q0FBUSxJQUFJLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNqRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDbkQsT0FBTzthQUNSO1lBQ0QsSUFBSSxDQUFDLDBCQUEwQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLG1DQUFtQyxDQUN6QyxnQkFBa0M7UUFFbEMsT0FBTyxvRUFBMkIsQ0FBQyxDQUFDLEtBQW1CLEVBQUUsRUFBRTs7WUFDekQsOERBQThEO1lBQzlELDBFQUEwRTtZQUMxRSxtRUFBbUU7WUFDbkUscUJBQXFCO1lBQ3JCLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLEVBQUU7Z0JBQ3pDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcscURBQVksQ0FDekMsMERBQWUsQ0FDYiw0REFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUNuRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUMxQixDQUNGLENBQUM7YUFDSDtZQUNELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDNUIsSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFZLFdBQVcsQ0FBQyxFQUFFO2dCQUNwQyxPQUFPO2FBQ1I7WUFFRCxJQUFJLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsRUFBRTtnQkFDakUsT0FBTzthQUNSO1lBRUQsTUFBTSxhQUFhLEdBQUcsb0VBQTJCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVyRSxJQUFJLDBEQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUM5QixJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLENBQUMsQ0FBQztnQkFDMUQsT0FBTzthQUNSO1lBRUQsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxhQUFhLENBQUMsQ0FBQyxFQUNmLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQ3BCLENBQUM7WUFFRixpRUFBaUU7WUFDakUsNERBQTREO1lBQzVELDREQUE0RDtZQUM1RCwwQkFBMEI7WUFFMUIsSUFDRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXO2dCQUNsQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPO29CQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEVBQ3hDO2dCQUNBLElBQ0Usa0RBQVUsQ0FDUixhQUFhLENBQUMsQ0FBQyxFQUNmLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsR0FBRywyREFBa0IsRUFDdEI7b0JBQ0EsT0FBTztpQkFDUjthQUNGO1lBQ0QsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO2dCQUN0QyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQ25ELE9BQU8sSUFBSSxDQUFDO2lCQUNiO2FBQ0Y7WUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUU7Z0JBQ3BDLE1BQU0sbUJBQW1CLEdBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQztnQkFDdEUsTUFBTSxPQUFPLEdBQUcsa0dBQXVDLENBQ3JELEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxFQUNWLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsYUFBYSxDQUFDLENBQUMsRUFDZixDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxFQUFFO29CQUM3QixJQUFJLENBQUMsNENBQTRDLENBQy9DLE9BQU8sRUFDUCxpQkFBaUIsQ0FDbEIsQ0FBQztnQkFDSixDQUFDLEVBQ0QsbUJBQW1CLENBQ3BCLENBQUM7Z0JBQ0YsSUFBSSxPQUFPLEVBQUU7b0JBQ1gsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO29CQUNoRCxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7b0JBQ2hELGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO29CQUN6QyxJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO3dCQUMvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsVUFBVSxFQUMzQzt3QkFDQSxJQUFJLENBQUMsUUFBUSxDQUFDOzRCQUNaLG9CQUFvQixrQ0FDZixJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixLQUNsQyxVQUFVLEVBQUUsSUFBSSxHQUNqQjt5QkFDRixDQUFDLENBQUM7cUJBQ0o7b0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsVUFBVSxFQUFFO3dCQUNoRCxJQUFJLENBQUMsUUFBUSxDQUFDOzRCQUNaLHFCQUFxQixrQ0FDaEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsS0FDbkMsVUFBVSxFQUFFLElBQUksR0FDakI7eUJBQ0YsQ0FBQyxDQUFDO3FCQUNKO29CQUNELE9BQU87aUJBQ1I7YUFDRjtZQUVELE1BQU0sc0JBQXNCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQ3JFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQzlDLENBQUM7WUFFRixNQUFNLDZCQUE2QixHQUNqQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDL0IsS0FBSyxDQUFDLFFBQVE7Z0JBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTO3FCQUN2QyxzQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTywwQ0FBRSxFQUFFLEVBQUM7WUFDckMsSUFDRSxDQUFDLHNCQUFzQjtnQkFDckIsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxDQUFDO2dCQUNqRSxDQUFDLDZCQUE2QixFQUM5QjtnQkFDQSxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFDRixJQUFJLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO29CQUN2RCxPQUFPO2lCQUNSO2dCQUNELG9EQUFvRDtnQkFDcEQsZ0RBQWdEO2dCQUNoRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztnQkFDekMsc0VBQXNFO2dCQUN0RSxrRUFBa0U7Z0JBQ2xFLElBQUksZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRTtvQkFDbEUsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNoRCxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztvQkFFRixNQUFNLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxHQUFHO3dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzt3QkFDckQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7cUJBQ3RELENBQUM7b0JBRUYsb0RBQW9EO29CQUNwRCxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO29CQUNyQywrREFBb0IsQ0FDbEIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixLQUFLLEVBQ0wsS0FBSyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztvQkFDRixJQUFJLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFFakQsc0VBQXNFO29CQUN0RSxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUU7d0JBQzNELDRFQUE0RTt3QkFDNUUsNkRBQTZEO3dCQUM3RCxnREFBZ0Q7d0JBRWhELGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7d0JBRTlDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQzt3QkFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7d0JBQzVCLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7d0JBQzdCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQzt3QkFDdEMsTUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQzt3QkFDaEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO3dCQUMxRCxNQUFNLGtCQUFrQixHQUN0Qiw0REFBbUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQ2pELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUN4QixDQUFDO3dCQUVKLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFOzRCQUM5QixJQUNFLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dDQUN2Qyx5REFBeUQ7Z0NBQ3pELHdEQUF3RDtnQ0FDeEQsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFLLFVBQVUsYUFBVixVQUFVLHVCQUFWLFVBQVUsQ0FBRSxFQUFFO29DQUM1QixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsRUFDM0M7Z0NBQ0EsTUFBTSxpQkFBaUIsR0FBRywyREFBZ0IsQ0FDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQ3pCLFVBQVUsRUFDVixPQUFPLENBQ1IsQ0FBQztnQ0FDRixNQUFNLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxHQUFHLG9EQUFZLENBQzdDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQzFELGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO2dDQUNGLHNFQUFhLENBQUMsaUJBQWlCLEVBQUU7b0NBQy9CLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO29DQUM5QyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztpQ0FDL0MsQ0FBQyxDQUFDO2dDQUNILFlBQVksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQ0FDckMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dDQUMvQixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQzs2QkFDM0Q7aUNBQU07Z0NBQ0wsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzs2QkFDNUI7eUJBQ0Y7d0JBQ0QsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEdBQUcsWUFBWSxFQUFFLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQzt3QkFDakUsc0ZBQStCLENBQzdCLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsbUJBQW1CLENBQ3BCLENBQUM7d0JBQ0YsOEVBQTJCLENBQ3pCLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsbUJBQW1CLEVBQ25CLHNCQUFzQixDQUN2QixDQUFDO3dCQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztxQkFDbEQ7b0JBQ0QsT0FBTztpQkFDUjthQUNGO1lBRUQsa0VBQWtFO1lBQ2xFLHVDQUF1QztZQUN2QyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUNuRCxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUNwQixPQUFPO2FBQ1I7WUFFRCxJQUFJLGVBQWUsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO2dCQUN2QyxNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDO2dCQUN0QyxNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBQy9DLE1BQU0sRUFBRSxHQUFHLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFFL0MsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pFLE1BQU0sWUFBWSxHQUNoQixTQUFTLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUUxRCxJQUFJLENBQUMsWUFBWSxFQUFFO29CQUNqQixNQUFNLFNBQVMsR0FBRyxlQUFlLENBQUMsZ0JBQWdCO3dCQUNoRCxDQUFDLENBQUMsZUFBZSxDQUFDLFNBQVM7d0JBQzNCLENBQUMsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBRW5ELHNFQUFhLENBQUMsZUFBZSxFQUFFO3dCQUM3QixNQUFNLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDN0IsU0FBUztxQkFDVixDQUFDLENBQUM7aUJBQ0o7YUFDRjtpQkFBTSxJQUFJLHFFQUFlLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQzNDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUN6QyxNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDO2dCQUN0QyxJQUFJLEVBQUUsR0FBRyxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxFQUFFLEdBQUcsS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBRW5DLElBQUkscUVBQTZCLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7b0JBQy9ELENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyx5RUFBOEIsQ0FDekQsZUFBZSxDQUFDLENBQUMsRUFDakIsZUFBZSxDQUFDLENBQUMsRUFDakIsYUFBYSxDQUFDLENBQUMsRUFDZixhQUFhLENBQUMsQ0FBQyxDQUNoQixDQUFDLENBQUM7aUJBQ0o7Z0JBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDdkIsc0VBQWEsQ0FBQyxlQUFlLEVBQUU7d0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUM5QixDQUFDLENBQUM7aUJBQ0o7cUJBQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDOUIsc0VBQWEsQ0FBQyxlQUFlLEVBQUU7d0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztxQkFDM0MsQ0FBQyxDQUFDO2lCQUNKO2dCQUVELElBQUksc0VBQWdCLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUM1Qyw2Q0FBNkM7b0JBQzdDLElBQUksQ0FBQyw0Q0FBNEMsQ0FDL0MsZUFBZSxFQUNmLENBQUMsYUFBYSxDQUFDLEVBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsQ0FBQztpQkFDSDthQUNGO2lCQUFNO2dCQUNMLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDaEQsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsMEJBQTBCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDMUQ7WUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQzlDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUVqRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0JBQ3BELElBQ0UsQ0FBQyxLQUFLLENBQUMsUUFBUTtvQkFDZixrREFBa0Q7b0JBQ2xELENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7b0JBQ2hDLDhEQUFxQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQzNDO29CQUNBLElBQUksZ0JBQWdCLENBQUMsYUFBYSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUU7d0JBQ2xFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUMxQix5RUFBK0IsaUNBRXhCLFNBQVMsS0FDWixrQkFBa0IsRUFBRTtnQ0FDbEIsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUk7NkJBQ3pDLEtBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUNuQyxDQUNGLENBQUM7cUJBQ0g7eUJBQU07d0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixrQkFBa0IsRUFBRSxFQUFFOzRCQUN0QixnQkFBZ0IsRUFBRSxFQUFFOzRCQUNwQixjQUFjLEVBQUUsSUFBSTt5QkFDckIsQ0FBQyxDQUFDO3FCQUNKO2lCQUNGO2dCQUNELGdDQUFnQztnQkFDaEMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUNuQyxpR0FBc0MsQ0FDcEMsS0FBSyxFQUNMLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ3pCLENBQUM7b0JBQ0YscUJBQXFCO2lCQUN0QjtxQkFBTTtvQkFDTCxNQUFNLHVCQUF1QixHQUFHLG1FQUEwQixDQUN4RCxRQUFRLEVBQ1IsZUFBZSxDQUNoQixDQUFDO29CQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUMxQix5RUFBK0IsaUNBRXhCLFNBQVMsS0FDWixrQkFBa0IsZ0RBQ2IsU0FBUyxDQUFDLGtCQUFrQixHQUM1Qix1QkFBdUIsQ0FBQyxNQUFNLENBQy9CLENBQUMsR0FBMEMsRUFBRSxPQUFPLEVBQUUsRUFBRTs0QkFDdEQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7NEJBQ3ZCLE9BQU8sR0FBRyxDQUFDO3dCQUNiLENBQUMsRUFDRCxFQUFFLENBQ0gsR0FDRSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPOzRCQUM5QixDQUFDLENBQUM7Z0NBQ0Usc0RBQXNEO2dDQUN0RCxxQ0FBcUM7Z0NBQ3JDLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFDL0IsQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNOzZCQUNsQzs0QkFDSCxDQUFDLENBQUMsSUFBSSxDQUFDLEdBRVgsa0JBQWtCLEVBQ2hCLHVCQUF1QixDQUFDLE1BQU0sS0FBSyxDQUFDOzRCQUNwQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJOzRCQUM3QixDQUFDLENBQUMsTUFBTTs0QkFDUixDQUFDLENBQUMsS0FBSzt3QkFDWCx3RUFBd0U7d0JBQ3hFLHFCQUFxQixFQUNuQix1QkFBdUIsQ0FBQyxNQUFNLEtBQUssQ0FBQzs0QkFDcEMscUVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDekMsQ0FBQyxDQUFDLElBQUksOEVBQW1CLENBQ3JCLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxFQUMxQixJQUFJLENBQUMsS0FBSyxDQUNYOzRCQUNILENBQUMsQ0FBQyxJQUFJLEtBRVosSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxDQUNuQyxDQUNGLENBQUM7aUJBQ0g7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtFQUFrRTtJQUMxRCwrQkFBK0IsQ0FDckMsS0FBbUIsRUFDbkIsZ0JBQWtDO1FBRWxDLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFO1lBQ2hELE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUs7YUFDekQsQ0FBQyxDQUFDO1lBQ0gsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEMsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRTtZQUM5QyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQ3hCLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1osT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLO2FBQ3pELENBQUMsQ0FBQztZQUNILGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTyxpQ0FBaUMsQ0FDdkMsZ0JBQWtDO1FBRWxDLE9BQU8sMkRBQWtCLENBQUMsQ0FBQyxVQUF3QixFQUFFLEVBQUU7O1lBQ3JELE1BQU0sRUFDSixlQUFlLEVBQ2YsZUFBZSxFQUNmLFlBQVksRUFDWixVQUFVLEVBQ1YsVUFBVSxFQUNWLFVBQVUsR0FDWCxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDZixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixVQUFVLEVBQUUsS0FBSztnQkFDakIsZUFBZSxFQUFFLElBQUk7Z0JBQ3JCLGdCQUFnQixFQUFFLElBQUk7Z0JBQ3RCLFlBQVksRUFBRSxJQUFJO2dCQUNsQixrRUFBa0U7Z0JBQ2xFLG9DQUFvQztnQkFDcEMsY0FBYyxFQUNaLFlBQVksSUFBSSx3REFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO29CQUN0RCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjO29CQUMzQixDQUFDLENBQUMsSUFBSTthQUNYLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRS9ELHlFQUF5RTtZQUN6RSwyQkFBMkI7WUFDM0IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO2dCQUNuQyxJQUNFLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLFdBQVc7b0JBQzFDLDZCQUFnQixDQUFDLEdBQUcsMENBQUUsT0FBTywwQ0FBRSxFQUFFO3dCQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFDM0M7b0JBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO2lCQUNsRDtxQkFBTTtvQkFDTCxNQUFNLG9CQUFvQixHQUFHLDhGQUFtQyxDQUM5RCxVQUFVLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO29CQUNGLElBQUksb0JBQW9CLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTt3QkFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixvQkFBb0I7NEJBQ3BCLGlCQUFpQixFQUFFLEVBQUU7eUJBQ3RCLENBQUMsQ0FBQztxQkFDSjtpQkFDRjthQUNGO2lCQUFNLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRTtnQkFDM0MsSUFDRSw2QkFBZ0IsQ0FBQyxHQUFHLDBDQUFFLE9BQU8sMENBQUUsRUFBRTtvQkFDakMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLEVBQzFDO29CQUNBLE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO29CQUNGLGtJQUFrSTtvQkFDbEksSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO3dCQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDaEQ7aUJBQ0Y7cUJBQU07b0JBQ0wsTUFBTSxtQkFBbUIsR0FBRyw4RkFBbUMsQ0FDN0QsVUFBVSxFQUNWLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQ2hDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztvQkFFRixNQUFNLEVBQUUsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsR0FDOUMsbUJBQW1CLENBQUM7b0JBQ3RCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNyRSxJQUFJLHNFQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFO3dCQUM3Qiw0RUFBeUIsQ0FDdkIsT0FBTyxFQUNQLG1CQUFtQixFQUNuQixpQkFBaUIsQ0FDbEIsQ0FBQztxQkFDSDtvQkFFRCxJQUFJLG1CQUFtQixLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUU7d0JBQzVELElBQUksQ0FBQyxRQUFRLENBQUM7NEJBQ1oscUJBQXFCLGtDQUNoQixtQkFBbUIsS0FDdEIscUJBQXFCLEVBQUUsSUFBSSxHQUM1Qjs0QkFDRCxpQkFBaUIsRUFBRSxFQUFFO3lCQUN0QixDQUFDLENBQUM7cUJBQ0o7aUJBQ0Y7YUFDRjtZQUVELGFBQWEsR0FBRyxJQUFJLENBQUM7WUFFckIsSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFO2dCQUMxQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ2hEO1lBRUQsTUFBTSxDQUFDLG1CQUFtQixDQUN4QiwyREFBa0IsRUFDbEIsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLE1BQU8sQ0FDeEMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDeEIseURBQWdCLEVBQ2hCLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxJQUFLLENBQ3RDLENBQUM7WUFDRixNQUFNLENBQUMsbUJBQW1CLENBQ3hCLHNEQUFhLEVBQ2IsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLFNBQVUsQ0FDM0MsQ0FBQztZQUNGLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDeEIsb0RBQVcsRUFDWCxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsT0FBUSxDQUN6QyxDQUFDO1lBRUYsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUNoRDtZQUVELElBQUksZ0JBQWUsYUFBZixlQUFlLHVCQUFmLGVBQWUsQ0FBRSxJQUFJLE1BQUssVUFBVSxFQUFFO2dCQUN4QyxNQUFNLGFBQWEsR0FBRyxvRUFBMkIsQ0FDL0MsVUFBVSxFQUNWLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFFRixNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDO2dCQUN0QyxJQUFJLEVBQUUsR0FBRyxhQUFhLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLElBQUksRUFBRSxHQUFHLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFFN0MseURBQXlEO2dCQUN6RCxJQUFJLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDOUMsRUFBRSxJQUFJLE1BQU0sQ0FBQztvQkFDYixFQUFFLElBQUksTUFBTSxDQUFDO2lCQUNkO2dCQUVELE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxnQkFBZ0I7b0JBQ2hELENBQUMsQ0FBQyxFQUFFO29CQUNKLENBQUMsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRXhELHNFQUFhLENBQUMsZUFBZSxFQUFFO29CQUM3QixNQUFNLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDN0IsU0FBUztvQkFDVCxrQkFBa0IsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7aUJBQzdCLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7Z0JBRWpELE9BQU87YUFDUjtZQUNELElBQUksb0VBQWMsQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDbkMsTUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDO2dCQUNyQyxJQUFJO29CQUNGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FDWCxFQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFDbkQsR0FBRyxFQUFFO3dCQUNILElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztvQkFDbkQsQ0FBQyxDQUNGLENBQUM7aUJBQ0g7Z0JBQUMsT0FBTyxLQUFVLEVBQUU7b0JBQ25CLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQzNCLElBQUksQ0FBQyxLQUFLO3lCQUNQLDJCQUEyQixFQUFFO3lCQUM3QixNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUM3QyxDQUFDO29CQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztpQkFDbEQ7Z0JBQ0QsT0FBTzthQUNSO1lBRUQsSUFBSSxxRUFBZSxDQUFDLGVBQWUsQ0FBQyxFQUFFO2dCQUNwQyxJQUFJLGVBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7aUJBQ2hDO2dCQUNELE1BQU0sYUFBYSxHQUFHLG9FQUEyQixDQUMvQyxVQUFVLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUVGLElBQ0UsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVztvQkFDbEMsZUFBZTtvQkFDZixDQUFDLFlBQVksRUFDYjtvQkFDQSxzRUFBYSxDQUFDLGVBQWUsRUFBRTt3QkFDN0IsTUFBTSxFQUFFOzRCQUNOLEdBQUcsZUFBZSxDQUFDLE1BQU07NEJBQ3pCO2dDQUNFLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUM7Z0NBQ25DLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUM7NkJBQ3BDO3lCQUNGO3FCQUNGLENBQUMsQ0FBQztvQkFDSCxJQUFJLENBQUMsUUFBUSxDQUFDO3dCQUNaLFlBQVksRUFBRSxlQUFlO3dCQUM3QixjQUFjLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlO3FCQUMzQyxDQUFDLENBQUM7aUJBQ0o7cUJBQU0sSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsWUFBWSxFQUFFO29CQUM3RCxJQUNFLG1FQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7d0JBQzVCLHNFQUFnQixDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsRUFDeEM7d0JBQ0EseUVBQXNCLENBQ3BCLGVBQWUsRUFDZixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxLQUFLLEVBQ1YsYUFBYSxDQUNkLENBQUM7cUJBQ0g7b0JBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUNsRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRTt3QkFDdEIsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7d0JBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7NEJBQzVCLGVBQWUsRUFBRSxJQUFJOzRCQUNyQixVQUFVLEVBQUUseURBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtnQ0FDdkMsSUFBSSxFQUFFLFdBQVc7NkJBQ2xCLENBQUM7NEJBQ0Ysa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUMzQjs0QkFDRCxxQkFBcUIsRUFBRSxJQUFJLDhFQUFtQixDQUM1QyxlQUFlLEVBQ2YsSUFBSSxDQUFDLEtBQUssQ0FDWDt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDt5QkFBTTt3QkFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDOzRCQUM1QixlQUFlLEVBQUUsSUFBSTs0QkFDckIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUMzQjt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDtpQkFDRjtnQkFDRCxPQUFPO2FBQ1I7WUFFRCxJQUNFLFVBQVUsQ0FBQyxJQUFJLEtBQUssV0FBVztnQkFDL0IsZUFBZTtnQkFDZixrRUFBdUIsQ0FBQyxlQUFlLENBQUMsRUFDeEM7Z0JBQ0EsNERBQTREO2dCQUM1RCxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUN0RCxDQUFDO2dCQUNGLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osZUFBZSxFQUFFLElBQUk7aUJBQ3RCLENBQUMsQ0FBQztnQkFDSCxPQUFPO2FBQ1I7WUFFRCxJQUFJLGVBQWUsRUFBRTtnQkFDbkIsc0VBQWEsQ0FDWCxlQUFlLEVBQ2Ysa0VBQXVCLENBQUMsZUFBZSxDQUFDLENBQ3pDLENBQUM7YUFDSDtZQUVELElBQUksZUFBZSxFQUFFO2dCQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQ2hDO1lBRUQsSUFBSSxlQUFlLElBQUksa0VBQXVCLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQy9ELElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQzNCLElBQUksQ0FBQyxLQUFLO3FCQUNQLDJCQUEyQixFQUFFO3FCQUM3QixNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUNoRCxDQUFDO2FBQ0g7WUFFRCx1REFBdUQ7WUFDdkQsb0RBQW9EO1lBQ3BELE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFDaEQsSUFDRSxXQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQiwwQ0FBRSxTQUFTLE9BQUssVUFBVSxhQUFWLFVBQVUsdUJBQVYsVUFBVSxDQUFFLEVBQUU7Z0JBQzlELHFFQUFlLENBQUMsVUFBVSxDQUFDLEVBQzNCO2dCQUNBLE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUNGLGtFQUFrRTtnQkFDbEUsb0JBQW9CO2dCQUNwQixJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7b0JBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUM7d0JBQ1oscUJBQXFCLEVBQUUsSUFBSSw4RUFBbUIsQ0FDNUMsVUFBVSxFQUNWLElBQUksQ0FBQyxLQUFLLENBQ1g7cUJBQ0YsQ0FBQyxDQUFDO2lCQUNKO2FBQ0Y7WUFDRCxJQUFJLDBEQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUM5QixNQUFNLGVBQWUsR0FBRyxrREFBVSxDQUNoQyxJQUFJLENBQUMsZUFBZ0IsQ0FBQyxPQUFPLEVBQzdCLElBQUksQ0FBQyxlQUFnQixDQUFDLE9BQU8sRUFDN0IsSUFBSSxDQUFDLGFBQWMsQ0FBQyxPQUFPLEVBQzNCLElBQUksQ0FBQyxhQUFjLENBQUMsT0FBTyxDQUM1QixDQUFDO2dCQUVGLElBQUksZUFBZSxLQUFLLENBQUMsRUFBRTtvQkFDekIsTUFBTSxZQUFZLEdBQUcsb0VBQTJCLENBQzlDO3dCQUNFLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYyxDQUFDLE9BQU87d0JBQ3BDLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYyxDQUFDLE9BQU87cUJBQ3JDLEVBQ0QsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO29CQUNGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FDNUMsWUFBWSxDQUFDLENBQUMsRUFDZCxZQUFZLENBQUMsQ0FBQyxDQUNmLENBQUM7b0JBQ0YsV0FBVyxDQUFDLE9BQU8sQ0FDakIsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUNiLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxHQUFHO3dCQUNuRCxLQUFLLEVBQUUsSUFBSTt3QkFDWCxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87cUJBQzVCLENBQUMsQ0FDTCxDQUFDO2lCQUNIO2dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDckMsT0FBTzthQUNSO2lCQUFNLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sRUFBRTtnQkFDakUsSUFBSSxDQUFDLDJCQUEyQixDQUFDLGdCQUFnQixDQUFDLENBQUM7YUFDcEQ7WUFFRCxJQUNFLFVBQVU7Z0JBQ1YsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVztnQkFDbEMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CO2dCQUN6QyxtRUFBbUU7Z0JBQ25FLGVBQWU7Z0JBQ2YsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO29CQUMvQixDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFDN0M7Z0JBQ0Esd0RBQXdEO2dCQUN4RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUMzRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO3dCQUNoRCxJQUFJLDREQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLEVBQUU7NEJBQzlDLHVEQUF1RDs0QkFDdkQsc0RBQXNEOzRCQUN0RCx3QkFBd0I7NEJBQ3hCLE1BQU0sb0NBQW9DLEdBQUcsVUFBVSxDQUFDLFFBQVE7aUNBQzdELE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQ25CLDREQUFrQixDQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQ2xDLE9BQU8sQ0FDUixDQUNGO2lDQUNBLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7aUNBQzNDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLGlDQUFNLE1BQU0sR0FBSyxHQUFHLEVBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQzs0QkFFeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQ0FDN0IsZ0JBQWdCLGtDQUNYLFVBQVUsQ0FBQyxrQkFBa0IsR0FDN0IsVUFBVSxDQUFDLFFBQVE7cUNBQ25CLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztxQ0FDaEMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsaUNBQU0sSUFBSSxHQUFLLEdBQUcsRUFBRyxFQUFFLEVBQUUsQ0FBQyxDQUNwRDtnQ0FDRCxrQkFBa0Isa0NBQ2IsVUFBVSxDQUFDLGtCQUFrQixHQUM3QixvQ0FBb0MsQ0FDeEM7NkJBQ0YsQ0FBQyxDQUFDLENBQUM7NEJBQ0osMERBQTBEO3lCQUMzRDs2QkFBTSxJQUFJLENBQUMsV0FBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsMENBQUUsVUFBVSxHQUFFOzRCQUN4RCxzQ0FBc0M7NEJBQ3RDLGlDQUFpQzs0QkFFakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO2dDQUMxQixNQUFNLHFCQUFxQixtQ0FDdEIsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLFVBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEdBQ3hCLENBQUM7Z0NBQ0YsTUFBTSxtQkFBbUIsR0FBRyw0REFBbUIsQ0FDN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRSxrQ0FDN0IsU0FBUyxLQUFFLGtCQUFrQixFQUFFLHFCQUFxQixJQUMxRCxDQUFDO2dDQUVGLE9BQU8seUVBQStCLGlDQUUvQixTQUFTLEtBQ1osa0JBQWtCLEVBQUUscUJBQXFCO29DQUN6QyxvRUFBb0U7b0NBQ3BFLHFCQUFxQixFQUNuQixtQkFBbUIsQ0FBQyxNQUFNLEtBQUssQ0FBQzt3Q0FDaEMscUVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3Q0FDckMsQ0FBQyxDQUFDLElBQUksOEVBQW1CLENBQ3JCLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxFQUN0QixJQUFJLENBQUMsS0FBSyxDQUNYO3dDQUNILENBQUMsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEtBRXZDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FDbkMsQ0FBQzs0QkFDSixDQUFDLENBQUMsQ0FBQzt5QkFDSjtxQkFDRjt5QkFBTTt3QkFDTCxpQ0FBaUM7d0JBQ2pDLGlDQUFpQzt3QkFDakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQzs0QkFDN0Isa0JBQWtCLGtDQUNiLFVBQVUsQ0FBQyxrQkFBa0IsS0FDaEMsQ0FBQyxVQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUN2Qjt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDtpQkFDRjtxQkFBTTtvQkFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7O3dCQUFDLDBCQUN4Qix5RUFBK0IsaUNBRTNCLFNBQVMsS0FDWixrQkFBa0IsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUM3QyxxQkFBcUIsRUFDbkIscUVBQWUsQ0FBQyxVQUFVLENBQUM7Z0NBQzNCLG9JQUFvSTtnQ0FDcEkseUdBQXlHO2dDQUN6RyxnQkFBUyxDQUFDLHFCQUFxQiwwQ0FBRSxTQUFTLE1BQUssVUFBVSxDQUFDLEVBQUU7Z0NBQzFELENBQUMsQ0FBQyxJQUFJLDhFQUFtQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDO2dDQUNqRCxDQUFDLENBQUMsU0FBUyxDQUFDLHFCQUFxQixLQUV2QyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQ25DLEVBQ0Q7cUJBQUEsQ0FBQyxDQUFDO2lCQUNMO2FBQ0Y7WUFFRCxJQUNFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVc7Z0JBQ2xDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVO2dCQUN0QixDQUFDLENBQUMsVUFBVTtvQkFDViwyRkFBZ0QsQ0FDOUMsVUFBVSxFQUNWLElBQUksQ0FBQyxLQUFLLEVBQ1YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsQ0FBQztvQkFDRixDQUFDLENBQUMsVUFBVTt3QkFDVixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMseUNBQXlDLENBQUMsQ0FBQyxFQUNwRTtnQkFDQSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7b0JBQ25DLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2lCQUMvQztxQkFBTTtvQkFDTCw2QkFBNkI7b0JBQzdCLElBQUksQ0FBQyxRQUFRLENBQUM7d0JBQ1osa0JBQWtCLEVBQUUsRUFBRTt3QkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTt3QkFDcEIsY0FBYyxFQUFFLElBQUk7cUJBQ3JCLENBQUMsQ0FBQztpQkFDSjtnQkFDRCxPQUFPO2FBQ1I7WUFFRCxJQUNFLENBQUMsVUFBVSxDQUFDLE1BQU07Z0JBQ2xCLFVBQVUsQ0FBQyxJQUFJLEtBQUssVUFBVTtnQkFDOUIsZUFBZSxFQUNmO2dCQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzVCLGtCQUFrQixrQ0FDYixTQUFTLENBQUMsa0JBQWtCLEtBQy9CLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksR0FDM0I7aUJBQ0YsQ0FBQyxDQUFDLENBQUM7YUFDTDtZQUVELElBQ0UsVUFBVSxDQUFDLElBQUksS0FBSyxXQUFXO2dCQUMvQiw4REFBcUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUNyRTtnQkFDQSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQ2hDO1lBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLFVBQVUsSUFBSSxVQUFVLEVBQUU7Z0JBQ2pFLENBQUMsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDM0IsQ0FBQyxDQUFDLDJFQUE0QjtvQkFDOUIsQ0FBQyxDQUFDLG1FQUFvQixDQUFDLENBQ3ZCLDREQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQ3BFLENBQUM7YUFDSDtZQUVELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO2dCQUN4RCxvREFBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsSUFBSTtvQkFDckIsaUJBQWlCLEVBQUUsRUFBRTtvQkFDckIsVUFBVSxFQUFFLHlEQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7aUJBQ2hFLENBQUMsQ0FBQzthQUNKO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osZUFBZSxFQUFFLElBQUk7b0JBQ3JCLGlCQUFpQixFQUFFLEVBQUU7aUJBQ3RCLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBcWVPLHlCQUF5QixDQUMvQixnQkFBaUQ7UUFFakQsTUFBTSxpQkFBaUIsR0FBRyxnRkFBNkIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVPLGNBQWMsQ0FBQyxVQUFvQztRQUN6RCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzVCLGtCQUFrQixFQUFFLEVBQUU7WUFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtZQUNwQixtRUFBbUU7WUFDbkUsa0JBQWtCO1lBQ2xCLGNBQWMsRUFDWixTQUFTLENBQUMsY0FBYztnQkFDeEIsVUFBVSxJQUFJLElBQUk7Z0JBQ2xCLDBEQUFnQixDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsY0FBYyxDQUFDO2dCQUNwRCxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWM7Z0JBQzFCLENBQUMsQ0FBQyxJQUFJO1NBQ1gsQ0FBQyxDQUFDLENBQUM7UUFDSixJQUFJLENBQUMsUUFBUSxDQUFDO1lBQ1osa0JBQWtCLEVBQUUsRUFBRTtZQUN0QiwwQkFBMEIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtTQUMxRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBdWlCTyxxQ0FBcUMsQ0FDM0MsQ0FBUyxFQUNULENBQVMsRUFDVCxRQUFrQixFQUNsQixNQUFnQyxFQUNoQyxLQUFhO1FBRWIsTUFBTSxvQkFBb0IsR0FBRywyRUFBa0MsQ0FDN0QsSUFBSSxDQUFDLEtBQUs7YUFDUCwyQkFBMkIsRUFBRTthQUM3QixNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsd0RBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUMvQyxDQUFDLEVBQ0QsQ0FBQyxDQUNGLENBQUM7UUFDRixJQUFJLG9CQUFvQixFQUFFO1lBQ3hCLE1BQU0sY0FBYyxHQUNsQixvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsb0JBQW9CLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUMxRCxNQUFNLGNBQWMsR0FDbEIsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDM0QsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUNqQyxDQUFDLEdBQUcsY0FBYyxFQUNsQixDQUFDLEdBQUcsY0FBYyxDQUNuQixDQUFDO1lBQ0YsTUFBTSxpQkFBaUIsR0FDckIsZ0JBQWdCLEdBQUcsc0VBQTZCLENBQUM7WUFDbkQsSUFBSSxpQkFBaUIsRUFBRTtnQkFDckIsTUFBTSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLG9FQUEyQixDQUNoRSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxFQUNsRCxRQUFRLENBQ1QsQ0FBQztnQkFDRixPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLENBQUM7YUFDakU7U0FDRjtJQUNILENBQUM7SUEwRU8sZ0JBQWdCOztRQUN0QixJQUFJLFVBQUksQ0FBQyxzQkFBc0IsMENBQUUsT0FBTyxFQUFFO1lBQ3hDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQztZQUNoRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDbEUsT0FBTztnQkFDTCxVQUFVLEVBQUUsSUFBSTtnQkFDaEIsU0FBUyxFQUFFLEdBQUc7YUFDZixDQUFDO1NBQ0g7UUFDRCxPQUFPO1lBQ0wsVUFBVSxFQUFFLENBQUM7WUFDYixTQUFTLEVBQUUsQ0FBQztTQUNiLENBQUM7SUFDSixDQUFDO0lBRWEsY0FBYzs7WUFDMUIsTUFBTSxXQUFXLEdBQ2Ysa0RBQWMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztnQkFDM0QsK0NBQVcsQ0FBQztZQUNkLE1BQU0sbURBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7S0FBQTs7QUFudkxhLGdCQUFZLEdBQXNCO0lBQzlDLHNFQUFzRTtJQUN0RSxTQUFTLEVBQUUsMkRBQWtCO0NBQzlCLENBQUM7QUFtd0xKLElBQ0UsYUFBb0IsS0FBSyxpREFBUTtJQUNqQyxhQUFvQixLQUFLLHdEQUFlO0lBQ3hDLGc0QkFBVyxDQUFDLG9CQUFvQixLQUFLLFNBQVMsRUFDOUM7SUFDQSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUssRUFBa0IsQ0FBQztJQUUzQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtRQUNoQyxRQUFRLEVBQUU7WUFDUixZQUFZLEVBQUUsSUFBSTtZQUNsQixHQUFHOztnQkFDRCxPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBQ3ZELENBQUM7WUFDRCxHQUFHLENBQUMsUUFBNkI7O2dCQUMvQixPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0RCxDQUFDO1NBQ0Y7S0FDRixDQUFDLENBQUM7Q0FDSjtBQUVELGlFQUFlLEdBQUcsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9jb21wb25lbnRzL0FwcC50c3g/MDA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgZmx1c2hTeW5jIH0gZnJvbSBcInJlYWN0LWRvbVwiO1xuXG5pbXBvcnQgeyBSb3VnaENhbnZhcyB9IGZyb20gXCJyb3VnaGpzL2Jpbi9jYW52YXNcIjtcbmltcG9ydCByb3VnaCBmcm9tIFwicm91Z2hqcy9iaW4vcm91Z2hcIjtcbmltcG9ydCBjbHN4IGZyb20gXCJjbHN4XCI7XG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tIFwibmFub2lkXCI7XG5cbmltcG9ydCB7XG4gIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgYWN0aW9uQnJpbmdGb3J3YXJkLFxuICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gIGFjdGlvbkNvcHksXG4gIGFjdGlvbkNvcHlBc1BuZyxcbiAgYWN0aW9uQ29weUFzU3ZnLFxuICBjb3B5VGV4dCxcbiAgYWN0aW9uQ29weVN0eWxlcyxcbiAgYWN0aW9uQ3V0LFxuICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICBhY3Rpb25GaW5hbGl6ZSxcbiAgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgYWN0aW9uR3JvdXAsXG4gIGFjdGlvblBhc3RlU3R5bGVzLFxuICBhY3Rpb25TZWxlY3RBbGwsXG4gIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgYWN0aW9uU2VuZFRvQmFjayxcbiAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gIGFjdGlvblRvZ2dsZVN0YXRzLFxuICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICBhY3Rpb25VbmJpbmRUZXh0LFxuICBhY3Rpb25CaW5kVGV4dCxcbiAgYWN0aW9uVW5ncm91cCxcbiAgYWN0aW9uTGluayxcbiAgYWN0aW9uVG9nZ2xlTG9jayxcbn0gZnJvbSBcIi4uL2FjdGlvbnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZG9BY3Rpb24sIGNyZWF0ZVVuZG9BY3Rpb24gfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25IaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb25NYW5hZ2VyIH0gZnJvbSBcIi4uL2FjdGlvbnMvbWFuYWdlclwiO1xuaW1wb3J0IHsgYWN0aW9ucyB9IGZyb20gXCIuLi9hY3Rpb25zL3JlZ2lzdGVyXCI7XG5pbXBvcnQgeyBBY3Rpb25SZXN1bHQgfSBmcm9tIFwiLi4vYWN0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgdHJhY2tFdmVudCB9IGZyb20gXCIuLi9hbmFseXRpY3NcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSwgaXNFcmFzZXJBY3RpdmUgfSBmcm9tIFwiLi4vYXBwU3RhdGVcIjtcbmltcG9ydCB7XG4gIHBhcnNlQ2xpcGJvYXJkLFxuICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYixcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCxcbn0gZnJvbSBcIi4uL2NsaXBib2FyZFwiO1xuaW1wb3J0IHtcbiAgQVBQX05BTUUsXG4gIENVUlNPUl9UWVBFLFxuICBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gIERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgRFJBR0dJTkdfVEhSRVNIT0xELFxuICBFTEVNRU5UX1JFQURZX1RPX0VSQVNFX09QQUNJVFksXG4gIEVMRU1FTlRfU0hJRlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTlYsXG4gIEVWRU5ULFxuICBHUklEX1NJWkUsXG4gIElNQUdFX1JFTkRFUl9USU1FT1VULFxuICBMSU5FX0NPTkZJUk1fVEhSRVNIT0xELFxuICBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTLFxuICBNSU1FX1RZUEVTLFxuICBNUV9NQVhfSEVJR0hUX0xBTkRTQ0FQRSxcbiAgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSxcbiAgTVFfTUFYX1dJRFRIX1BPUlRSQUlULFxuICBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSCxcbiAgTVFfU01fTUFYX1dJRFRILFxuICBQT0lOVEVSX0JVVFRPTixcbiAgU0NST0xMX1RJTUVPVVQsXG4gIFRBUF9UV0lDRV9USU1FT1VULFxuICBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRCxcbiAgVEhFTUUsXG4gIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQsXG4gIFZFUlRJQ0FMX0FMSUdOLFxufSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBsb2FkRnJvbUJsb2IgfSBmcm9tIFwiLi4vZGF0YVwiO1xuaW1wb3J0IExpYnJhcnksIHsgZGlzdHJpYnV0ZUxpYnJhcnlJdGVtc09uU3F1YXJlR3JpZCB9IGZyb20gXCIuLi9kYXRhL2xpYnJhcnlcIjtcbmltcG9ydCB7IHJlc3RvcmUsIHJlc3RvcmVFbGVtZW50cyB9IGZyb20gXCIuLi9kYXRhL3Jlc3RvcmVcIjtcbmltcG9ydCB7XG4gIGRyYWdOZXdFbGVtZW50LFxuICBkcmFnU2VsZWN0ZWRFbGVtZW50cyxcbiAgZHVwbGljYXRlRWxlbWVudCxcbiAgZ2V0Q29tbW9uQm91bmRzLFxuICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQsXG4gIGdldERyYWdPZmZzZXRYWSxcbiAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLFxuICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyxcbiAgZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24sXG4gIGdldFJlc2l6ZU9mZnNldFhZLFxuICBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUsXG4gIGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzLFxuICBoaXRUZXN0LFxuICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQsXG4gIGlzSW52aXNpYmx5U21hbGxFbGVtZW50LFxuICBpc05vbkRlbGV0ZWRFbGVtZW50LFxuICBpc1RleHRFbGVtZW50LFxuICBuZXdFbGVtZW50LFxuICBuZXdMaW5lYXJFbGVtZW50LFxuICBuZXdUZXh0RWxlbWVudCxcbiAgbmV3SW1hZ2VFbGVtZW50LFxuICB0ZXh0V3lzaXd5ZyxcbiAgdHJhbnNmb3JtRWxlbWVudHMsXG4gIHVwZGF0ZVRleHRFbGVtZW50LFxufSBmcm9tIFwiLi4vZWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgYmluZE9yVW5iaW5kTGluZWFyRWxlbWVudCxcbiAgYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50cyxcbiAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uLFxuICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24sXG4gIGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nLFxuICBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcsXG4gIGlzQmluZGluZ0VuYWJsZWQsXG4gIGlzTGluZWFyRWxlbWVudFNpbXBsZUFuZEFscmVhZHlCb3VuZCxcbiAgbWF5YmVCaW5kTGluZWFyRWxlbWVudCxcbiAgc2hvdWxkRW5hYmxlQmluZGluZ0ZvclBvaW50ZXJFdmVudCxcbiAgdW5iaW5kTGluZWFyRWxlbWVudHMsXG4gIHVwZGF0ZUJvdW5kRWxlbWVudHMsXG59IGZyb20gXCIuLi9lbGVtZW50L2JpbmRpbmdcIjtcbmltcG9ydCB7IExpbmVhckVsZW1lbnRFZGl0b3IgfSBmcm9tIFwiLi4vZWxlbWVudC9saW5lYXJFbGVtZW50RWRpdG9yXCI7XG5pbXBvcnQgeyBtdXRhdGVFbGVtZW50LCBuZXdFbGVtZW50V2l0aCB9IGZyb20gXCIuLi9lbGVtZW50L211dGF0ZUVsZW1lbnRcIjtcbmltcG9ydCB7IGRlZXBDb3B5RWxlbWVudCwgbmV3RnJlZURyYXdFbGVtZW50IH0gZnJvbSBcIi4uL2VsZW1lbnQvbmV3RWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgaGFzQm91bmRUZXh0RWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudFR5cGUsXG4gIGlzQm91bmRUb0NvbnRhaW5lcixcbiAgaXNJbWFnZUVsZW1lbnQsXG4gIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50VHlwZSxcbiAgaXNUZXh0QmluZGFibGVDb250YWluZXIsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVDaGVja3NcIjtcbmltcG9ydCB7XG4gIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gIE5vbkRlbGV0ZWQsXG4gIEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRmlsZUlkLFxuICBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q2VudGVyLCBnZXREaXN0YW5jZSB9IGZyb20gXCIuLi9nZXN0dXJlXCI7XG5pbXBvcnQge1xuICBlZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQsXG4gIGdldEVsZW1lbnRzSW5Hcm91cCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkRm9yRWxlbWVudCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkcyxcbiAgaXNFbGVtZW50SW5Hcm91cCxcbiAgaXNTZWxlY3RlZFZpYUdyb3VwLFxuICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZ3JvdXBzXCI7XG5pbXBvcnQgSGlzdG9yeSBmcm9tIFwiLi4vaGlzdG9yeVwiO1xuaW1wb3J0IHsgZGVmYXVsdExhbmcsIGdldExhbmd1YWdlLCBsYW5ndWFnZXMsIHNldExhbmd1YWdlLCB0IH0gZnJvbSBcIi4uL2kxOG5cIjtcbmltcG9ydCB7XG4gIENPREVTLFxuICBzaG91bGRSZXNpemVGcm9tQ2VudGVyLFxuICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvLFxuICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZSxcbiAgaXNBcnJvd0tleSxcbiAgS0VZUyxcbiAgaXNBbmRyb2lkLFxufSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHsgZGlzdGFuY2UyZCwgZ2V0R3JpZFBvaW50LCBpc1BhdGhBTG9vcCB9IGZyb20gXCIuLi9tYXRoXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJTY2VuZVwiO1xuaW1wb3J0IHsgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudCB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJFbGVtZW50XCI7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVTY3JvbGxDZW50ZXIsXG4gIGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24sXG4gIGdldEVsZW1lbnRzQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24sXG4gIGdldE5vcm1hbGl6ZWRab29tLFxuICBnZXRTZWxlY3RlZEVsZW1lbnRzLFxuICBoYXNCYWNrZ3JvdW5kLFxuICBpc092ZXJTY3JvbGxCYXJzLFxuICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQsXG59IGZyb20gXCIuLi9zY2VuZVwiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgUmVuZGVyQ29uZmlnLCBTY3JvbGxCYXJzIH0gZnJvbSBcIi4uL3NjZW5lL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRTdGF0ZUZvclpvb20gfSBmcm9tIFwiLi4vc2NlbmUvem9vbVwiO1xuaW1wb3J0IHsgZmluZFNoYXBlQnlLZXksIFNIQVBFUyB9IGZyb20gXCIuLi9zaGFwZXNcIjtcbmltcG9ydCB7XG4gIEFwcENsYXNzUHJvcGVydGllcyxcbiAgQXBwUHJvcHMsXG4gIEFwcFN0YXRlLFxuICBCaW5hcnlGaWxlRGF0YSxcbiAgRGF0YVVSTCxcbiAgRXhjYWxpZHJhd0ltcGVyYXRpdmVBUEksXG4gIEJpbmFyeUZpbGVzLFxuICBHZXN0dXJlLFxuICBHZXN0dXJlRXZlbnQsXG4gIExpYnJhcnlJdGVtcyxcbiAgUG9pbnRlckRvd25TdGF0ZSxcbiAgU2NlbmVEYXRhLFxuICBEZXZpY2UsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZGVib3VuY2UsXG4gIGRpc3RhbmNlLFxuICBnZXRGb250U3RyaW5nLFxuICBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcixcbiAgaXNJbnB1dExpa2UsXG4gIGlzVG9vbEljb24sXG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICByZXNldEN1cnNvcixcbiAgcmVzb2x2YWJsZVByb21pc2UsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyxcbiAgc2V0Q3Vyc29yLFxuICBzZXRDdXJzb3JGb3JTaGFwZSxcbiAgdHVwbGVUb0Nvb3JzLFxuICB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMsXG4gIHdpdGhCYXRjaGVkVXBkYXRlcyxcbiAgd3JhcEV2ZW50LFxuICB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQsXG4gIHVwZGF0ZU9iamVjdCxcbiAgc2V0RXJhc2VyQ3Vyc29yLFxuICB1cGRhdGVBY3RpdmVUb29sLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCBDb250ZXh0TWVudSwgeyBDb250ZXh0TWVudU9wdGlvbiB9IGZyb20gXCIuL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgTGF5ZXJVSSBmcm9tIFwiLi9MYXllclVJXCI7XG5pbXBvcnQgeyBUb2FzdCB9IGZyb20gXCIuL1RvYXN0XCI7XG5pbXBvcnQgeyBhY3Rpb25Ub2dnbGVWaWV3TW9kZSB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvblRvZ2dsZVZpZXdNb2RlXCI7XG5pbXBvcnQge1xuICBkYXRhVVJMVG9GaWxlLFxuICBnZW5lcmF0ZUlkRnJvbUZpbGUsXG4gIGdldERhdGFVUkwsXG4gIGdldEZpbGVGcm9tRXZlbnQsXG4gIGlzU3VwcG9ydGVkSW1hZ2VGaWxlLFxuICBsb2FkU2NlbmVPckxpYnJhcnlGcm9tQmxvYixcbiAgbm9ybWFsaXplRmlsZSxcbiAgcGFyc2VMaWJyYXJ5SlNPTixcbiAgcmVzaXplSW1hZ2VGaWxlLFxuICBTVkdTdHJpbmdUb0ZpbGUsXG59IGZyb20gXCIuLi9kYXRhL2Jsb2JcIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgbG9hZEhUTUxJbWFnZUVsZW1lbnQsXG4gIG5vcm1hbGl6ZVNWRyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSBhcyBfdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB0aHJvdHRsZSBmcm9tIFwibG9kYXNoLnRocm90dGxlXCI7XG5pbXBvcnQgeyBmaWxlT3BlbiwgRmlsZVN5c3RlbUhhbmRsZSB9IGZyb20gXCIuLi9kYXRhL2ZpbGVzeXN0ZW1cIjtcbmltcG9ydCB7XG4gIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24sXG4gIGdldEFwcHJveE1pbkxpbmVIZWlnaHQsXG4gIGdldEFwcHJveE1pbkxpbmVXaWR0aCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdGV4dEVsZW1lbnRcIjtcbmltcG9ydCB7IGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94IH0gZnJvbSBcIi4uL2VsZW1lbnQvY29sbGlzaW9uXCI7XG5pbXBvcnQge1xuICBub3JtYWxpemVMaW5rLFxuICBzaG93SHlwZXJsaW5rVG9vbHRpcCxcbiAgaGlkZUh5cGVybGlua1Rvb2xpcCxcbiAgSHlwZXJsaW5rLFxuICBpc1BvaW50SGl0dGluZ0xpbmtJY29uLFxuICBpc0xvY2FsTGluayxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvSHlwZXJsaW5rXCI7XG5pbXBvcnQgeyBzaG91bGRTaG93Qm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC90cmFuc2Zvcm1IYW5kbGVzXCI7XG5cbmNvbnN0IGRldmljZUNvbnRleHRJbml0aWFsVmFsdWUgPSB7XG4gIGlzU21TY3JlZW46IGZhbHNlLFxuICBpc01vYmlsZTogZmFsc2UsXG4gIGlzVG91Y2hTY3JlZW46IGZhbHNlLFxuICBjYW5EZXZpY2VGaXRTaWRlYmFyOiBmYWxzZSxcbn07XG5jb25zdCBEZXZpY2VDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxEZXZpY2U+KGRldmljZUNvbnRleHRJbml0aWFsVmFsdWUpO1xuZXhwb3J0IGNvbnN0IHVzZURldmljZSA9ICgpID0+IHVzZUNvbnRleHQ8RGV2aWNlPihEZXZpY2VDb250ZXh0KTtcbmNvbnN0IEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDx7XG4gIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICBpZDogc3RyaW5nIHwgbnVsbDtcbn0+KHsgY29udGFpbmVyOiBudWxsLCBpZDogbnVsbCB9KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3Q29udGFpbmVyID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCk7XG5cbmxldCBkaWRUYXBUd2ljZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IHRhcHBlZFR3aWNlVGltZXIgPSAwO1xubGV0IGN1cnNvclggPSAwO1xubGV0IGN1cnNvclkgPSAwO1xubGV0IGlzSG9sZGluZ1NwYWNlOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNQYW5uaW5nOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNEcmFnZ2luZ1Njcm9sbEJhcjogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGN1cnJlbnRTY3JvbGxCYXJzOiBTY3JvbGxCYXJzID0geyBob3Jpem9udGFsOiBudWxsLCB2ZXJ0aWNhbDogbnVsbCB9O1xubGV0IHRvdWNoVGltZW91dCA9IDA7XG5sZXQgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbi8vIHJlbW92ZSB0aGlzIGhhY2sgd2hlbiB3ZSBjYW4gc3luYyByZW5kZXIgJiByZXNpemVPYnNlcnZlciAoc3RhdGUgdXBkYXRlKVxuLy8gdG8gckFGLiBTZWUgIzU0MzlcbmxldCBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IHRydWU7XG5cbmxldCBsYXN0UG9pbnRlclVwOiAoKGV2ZW50OiBhbnkpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5jb25zdCBnZXN0dXJlOiBHZXN0dXJlID0ge1xuICBwb2ludGVyczogbmV3IE1hcCgpLFxuICBsYXN0Q2VudGVyOiBudWxsLFxuICBpbml0aWFsRGlzdGFuY2U6IG51bGwsXG4gIGluaXRpYWxTY2FsZTogbnVsbCxcbn07XG5cbmNsYXNzIEFwcCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxBcHBQcm9wcywgQXBwU3RhdGU+IHtcbiAgY2FudmFzOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJjYW52YXNcIl0gPSBudWxsO1xuICByYzogUm91Z2hDYW52YXMgfCBudWxsID0gbnVsbDtcbiAgdW5tb3VudGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGlvbk1hbmFnZXI6IEFjdGlvbk1hbmFnZXI7XG4gIGRldmljZTogRGV2aWNlID0gZGV2aWNlQ29udGV4dEluaXRpYWxWYWx1ZTtcbiAgZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXI/OiAoKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclJlZiA9IFJlYWN0LmNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcblxuICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wczogUGFydGlhbDxBcHBQcm9wcz4gPSB7XG4gICAgLy8gbmVlZGVkIGZvciB0ZXN0cyB0byBwYXNzIHNpbmNlIHdlIGRpcmVjdGx5IHJlbmRlciBBcHAgaW4gbWFueSB0ZXN0c1xuICAgIFVJT3B0aW9uczogREVGQVVMVF9VSV9PUFRJT05TLFxuICB9O1xuXG4gIHB1YmxpYyBzY2VuZTogU2NlbmU7XG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IERvY3VtZW50IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgbGlicmFyeTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wibGlicmFyeVwiXTtcbiAgcHVibGljIGxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlOiBMaWJyYXJ5SXRlbXMgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBoaXN0b3J5OiBIaXN0b3J5O1xuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZToge1xuICAgIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICAgIGlkOiBzdHJpbmc7XG4gIH07XG5cbiAgcHVibGljIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHt9O1xuICBwdWJsaWMgaW1hZ2VDYWNoZTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiaW1hZ2VDYWNoZVwiXSA9IG5ldyBNYXAoKTtcblxuICBoaXRMaW5rRWxlbWVudD86IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudDtcbiAgbGFzdFBvaW50ZXJEb3duOiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+IHwgbnVsbCA9IG51bGw7XG4gIGxhc3RQb2ludGVyVXA6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MRWxlbWVudD4gfCBQb2ludGVyRXZlbnQgfCBudWxsID0gbnVsbDtcbiAgY29udGV4dE1lbnVPcGVuOiBib29sZWFuID0gZmFsc2U7XG4gIGxhc3RTY2VuZVBvaW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBBcHBQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICBjb25zdCBkZWZhdWx0QXBwU3RhdGUgPSBnZXREZWZhdWx0QXBwU3RhdGUoKTtcbiAgICBjb25zdCB7XG4gICAgICBleGNhbGlkcmF3UmVmLFxuICAgICAgdmlld01vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgZ3JpZE1vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB0aGVtZSA9IGRlZmF1bHRBcHBTdGF0ZS50aGVtZSxcbiAgICAgIG5hbWUgPSBkZWZhdWx0QXBwU3RhdGUubmFtZSxcbiAgICB9ID0gcHJvcHM7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLmRlZmF1bHRBcHBTdGF0ZSxcbiAgICAgIHRoZW1lLFxuICAgICAgaXNMb2FkaW5nOiB0cnVlLFxuICAgICAgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCksXG4gICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgIGdyaWRTaXplOiBncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsLFxuICAgICAgbmFtZSxcbiAgICAgIHdpZHRoOiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0LFxuICAgICAgc2hvd0h5cGVybGlua1BvcHVwOiBmYWxzZSxcbiAgICAgIGlzTGlicmFyeU1lbnVEb2NrZWQ6IGZhbHNlLFxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gbmFub2lkKCk7XG5cbiAgICB0aGlzLmxpYnJhcnkgPSBuZXcgTGlicmFyeSh0aGlzKTtcbiAgICBpZiAoZXhjYWxpZHJhd1JlZikge1xuICAgICAgY29uc3QgcmVhZHlQcm9taXNlID1cbiAgICAgICAgKFwiY3VycmVudFwiIGluIGV4Y2FsaWRyYXdSZWYgJiYgZXhjYWxpZHJhd1JlZi5jdXJyZW50Py5yZWFkeVByb21pc2UpIHx8XG4gICAgICAgIHJlc29sdmFibGVQcm9taXNlPEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJPigpO1xuXG4gICAgICBjb25zdCBhcGk6IEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJID0ge1xuICAgICAgICByZWFkeTogdHJ1ZSxcbiAgICAgICAgcmVhZHlQcm9taXNlLFxuICAgICAgICB1cGRhdGVTY2VuZTogdGhpcy51cGRhdGVTY2VuZSxcbiAgICAgICAgdXBkYXRlTGlicmFyeTogdGhpcy5saWJyYXJ5LnVwZGF0ZUxpYnJhcnksXG4gICAgICAgIGFkZEZpbGVzOiB0aGlzLmFkZEZpbGVzLFxuICAgICAgICByZXNldFNjZW5lOiB0aGlzLnJlc2V0U2NlbmUsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkOiB0aGlzLmdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkLFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY2xlYXI6IHRoaXMucmVzZXRIaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgICBzY3JvbGxUb0NvbnRlbnQ6IHRoaXMuc2Nyb2xsVG9Db250ZW50LFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzOiB0aGlzLmdldFNjZW5lRWxlbWVudHMsXG4gICAgICAgIGdldEFwcFN0YXRlOiAoKSA9PiB0aGlzLnN0YXRlLFxuICAgICAgICBnZXRGaWxlczogKCkgPT4gdGhpcy5maWxlcyxcbiAgICAgICAgcmVmcmVzaDogdGhpcy5yZWZyZXNoLFxuICAgICAgICBzZXRUb2FzdDogdGhpcy5zZXRUb2FzdCxcbiAgICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICAgIHNldEFjdGl2ZVRvb2w6IHRoaXMuc2V0QWN0aXZlVG9vbCxcbiAgICAgICAgc2V0Q3Vyc29yOiB0aGlzLnNldEN1cnNvcixcbiAgICAgICAgcmVzZXRDdXJzb3I6IHRoaXMucmVzZXRDdXJzb3IsXG4gICAgICB9IGFzIGNvbnN0O1xuICAgICAgaWYgKHR5cGVvZiBleGNhbGlkcmF3UmVmID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZXhjYWxpZHJhd1JlZihhcGkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhjYWxpZHJhd1JlZi5jdXJyZW50ID0gYXBpO1xuICAgICAgfVxuICAgICAgcmVhZHlQcm9taXNlLnJlc29sdmUoYXBpKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZSA9IHtcbiAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQsXG4gICAgICBpZDogdGhpcy5pZCxcbiAgICB9O1xuXG4gICAgdGhpcy5zY2VuZSA9IG5ldyBTY2VuZSgpO1xuICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBIaXN0b3J5KCk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyID0gbmV3IEFjdGlvbk1hbmFnZXIoXG4gICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQsXG4gICAgICAoKSA9PiB0aGlzLnN0YXRlLFxuICAgICAgKCkgPT4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMsXG4gICAgKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIucmVnaXN0ZXJBbGwoYWN0aW9ucyk7XG5cbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIucmVnaXN0ZXJBY3Rpb24oY3JlYXRlVW5kb0FjdGlvbih0aGlzLmhpc3RvcnkpKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIucmVnaXN0ZXJBY3Rpb24oY3JlYXRlUmVkb0FjdGlvbih0aGlzLmhpc3RvcnkpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ2FudmFzKCkge1xuICAgIGNvbnN0IGNhbnZhc1NjYWxlID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgfSA9IHRoaXMuc3RhdGU7XG4gICAgY29uc3QgY2FudmFzV2lkdGggPSBjYW52YXNET01XaWR0aCAqIGNhbnZhc1NjYWxlO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNhbnZhc0RPTUhlaWdodCAqIGNhbnZhc1NjYWxlO1xuICAgIGlmICh2aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxjYW52YXNcbiAgICAgICAgICBjbGFzc05hbWU9XCJleGNhbGlkcmF3X19jYW52YXNcIlxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgICAgICAgIGN1cnNvcjogQ1VSU09SX1RZUEUuR1JBQixcbiAgICAgICAgICB9fVxuICAgICAgICAgIHdpZHRoPXtjYW52YXNXaWR0aH1cbiAgICAgICAgICBoZWlnaHQ9e2NhbnZhc0hlaWdodH1cbiAgICAgICAgICByZWY9e3RoaXMuaGFuZGxlQ2FudmFzUmVmfVxuICAgICAgICAgIG9uQ29udGV4dE1lbnU9e3RoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnV9XG4gICAgICAgICAgb25Qb2ludGVyTW92ZT17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyTW92ZX1cbiAgICAgICAgICBvblBvaW50ZXJVcD17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyVXB9XG4gICAgICAgICAgb25Qb2ludGVyQ2FuY2VsPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgID5cbiAgICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgICA8L2NhbnZhcz5cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICA8Y2FudmFzXG4gICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICB9fVxuICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICByZWY9e3RoaXMuaGFuZGxlQ2FudmFzUmVmfVxuICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICBvbkRvdWJsZUNsaWNrPXt0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrfVxuICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICBvblBvaW50ZXJVcD17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyVXB9XG4gICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICA+XG4gICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICA8L2NhbnZhcz5cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfX3JlbmRlclVJID0gdHJ1ZTtcblxuICBwdWJsaWMgcmVuZGVyKCkge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IHtcbiAgICAgIG9uQ29sbGFiQnV0dG9uQ2xpY2ssXG4gICAgICByZW5kZXJUb3BSaWdodFVJLFxuICAgICAgcmVuZGVyRm9vdGVyLFxuICAgICAgcmVuZGVyQ3VzdG9tU3RhdHMsXG4gICAgfSA9IHRoaXMucHJvcHM7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9e2Nsc3goXCJleGNhbGlkcmF3IGV4Y2FsaWRyYXctY29udGFpbmVyXCIsIHtcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLXZpZXctbW9kZVwiOiB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLW1vYmlsZVwiOiB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICAgICAgfSl9XG4gICAgICAgIHJlZj17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmfVxuICAgICAgICBvbkRyb3A9e3RoaXMuaGFuZGxlQXBwT25Ecm9wfVxuICAgICAgICB0YWJJbmRleD17MH1cbiAgICAgICAgb25LZXlEb3duPXtcbiAgICAgICAgICB0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkgPyB1bmRlZmluZWQgOiB0aGlzLm9uS2V5RG93blxuICAgICAgICB9XG4gICAgICA+XG4gICAgICAgIDxFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlclxuICAgICAgICAgIHZhbHVlPXt0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZX1cbiAgICAgICAgPlxuICAgICAgICAgIDxEZXZpY2VDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLmRldmljZX0+XG4gICAgICAgICAgICB7dGhpcy5fX3JlbmRlclVJICYmIChcbiAgICAgICAgICAgICAgPExheWVyVUlcbiAgICAgICAgICAgICAgICBjYW52YXM9e3RoaXMuY2FudmFzfVxuICAgICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICAgIGZpbGVzPXt0aGlzLmZpbGVzfVxuICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgIGFjdGlvbk1hbmFnZXI9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgICBlbGVtZW50cz17dGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKX1cbiAgICAgICAgICAgICAgICBvbkNvbGxhYkJ1dHRvbkNsaWNrPXtvbkNvbGxhYkJ1dHRvbkNsaWNrfVxuICAgICAgICAgICAgICAgIG9uTG9ja1RvZ2dsZT17dGhpcy50b2dnbGVMb2NrfVxuICAgICAgICAgICAgICAgIG9uUGVuTW9kZVRvZ2dsZT17dGhpcy50b2dnbGVQZW5Nb2RlfVxuICAgICAgICAgICAgICAgIG9uSW5zZXJ0RWxlbWVudHM9eyhlbGVtZW50cykgPT5cbiAgICAgICAgICAgICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiY2VudGVyXCIsXG4gICAgICAgICAgICAgICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFuZ0NvZGU9e2dldExhbmd1YWdlKCkuY29kZX1cbiAgICAgICAgICAgICAgICBpc0NvbGxhYm9yYXRpbmc9e3RoaXMucHJvcHMuaXNDb2xsYWJvcmF0aW5nfVxuICAgICAgICAgICAgICAgIHJlbmRlclRvcFJpZ2h0VUk9e3JlbmRlclRvcFJpZ2h0VUl9XG4gICAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tRm9vdGVyPXtyZW5kZXJGb290ZXJ9XG4gICAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tU3RhdHM9e3JlbmRlckN1c3RvbVN0YXRzfVxuICAgICAgICAgICAgICAgIHNob3dFeGl0WmVuTW9kZUJ0bj17XG4gICAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8uemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuemVuTW9kZUVuYWJsZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2hvd1RoZW1lQnRuPXtcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy50aGVtZSA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuY2FudmFzQWN0aW9ucy50aGVtZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaWJyYXJ5UmV0dXJuVXJsPXt0aGlzLnByb3BzLmxpYnJhcnlSZXR1cm5Vcmx9XG4gICAgICAgICAgICAgICAgVUlPcHRpb25zPXt0aGlzLnByb3BzLlVJT3B0aW9uc31cbiAgICAgICAgICAgICAgICBmb2N1c0NvbnRhaW5lcj17dGhpcy5mb2N1c0NvbnRhaW5lcn1cbiAgICAgICAgICAgICAgICBsaWJyYXJ5PXt0aGlzLmxpYnJhcnl9XG4gICAgICAgICAgICAgICAgaWQ9e3RoaXMuaWR9XG4gICAgICAgICAgICAgICAgb25JbWFnZUFjdGlvbj17dGhpcy5vbkltYWdlQWN0aW9ufVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy1jb250ZXh0TWVudUNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICB7c2VsZWN0ZWRFbGVtZW50Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cCAmJiAoXG4gICAgICAgICAgICAgIDxIeXBlcmxpbmtcbiAgICAgICAgICAgICAgICBrZXk9e3NlbGVjdGVkRWxlbWVudFswXS5pZH1cbiAgICAgICAgICAgICAgICBlbGVtZW50PXtzZWxlY3RlZEVsZW1lbnRbMF19XG4gICAgICAgICAgICAgICAgYXBwU3RhdGU9e3RoaXMuc3RhdGV9XG4gICAgICAgICAgICAgICAgc2V0QXBwU3RhdGU9e3RoaXMuc2V0QXBwU3RhdGV9XG4gICAgICAgICAgICAgICAgb25MaW5rT3Blbj17dGhpcy5wcm9wcy5vbkxpbmtPcGVufVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnRvYXN0ICE9PSBudWxsICYmIChcbiAgICAgICAgICAgICAgPFRvYXN0XG4gICAgICAgICAgICAgICAgbWVzc2FnZT17dGhpcy5zdGF0ZS50b2FzdC5tZXNzYWdlfVxuICAgICAgICAgICAgICAgIG9uQ2xvc2U9eygpID0+IHRoaXMuc2V0VG9hc3QobnVsbCl9XG4gICAgICAgICAgICAgICAgZHVyYXRpb249e3RoaXMuc3RhdGUudG9hc3QuZHVyYXRpb259XG4gICAgICAgICAgICAgICAgY2xvc2FibGU9e3RoaXMuc3RhdGUudG9hc3QuY2xvc2FibGV9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAgPG1haW4+e3RoaXMucmVuZGVyQ2FudmFzKCl9PC9tYWluPlxuICAgICAgICAgIDwvRGV2aWNlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgPC9FeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZm9jdXNDb250YWluZXI6IEFwcENsYXNzUHJvcGVydGllc1tcImZvY3VzQ29udGFpbmVyXCJdID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50cyA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcbiAgfTtcblxuICBwcml2YXRlIHN5bmNBY3Rpb25SZXN1bHQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGFjdGlvblJlc3VsdDogQWN0aW9uUmVzdWx0KSA9PiB7XG4gICAgICAvLyBTaW5jZSBjb250ZXh0IG1lbnUgY2xvc2VzIHdoZW4gYWN0aW9uIHRyaWdnZXJlZCBzbyBzZXR0aW5nIHRvIGZhbHNlXG4gICAgICB0aGlzLmNvbnRleHRNZW51T3BlbiA9IGZhbHNlO1xuICAgICAgaWYgKHRoaXMudW5tb3VudGVkIHx8IGFjdGlvblJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgZWRpdGluZ0VsZW1lbnQ6IEFwcFN0YXRlW1wiZWRpdGluZ0VsZW1lbnRcIl0gfCBudWxsID0gbnVsbDtcbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZWxlbWVudHMpIHtcbiAgICAgICAgYWN0aW9uUmVzdWx0LmVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50Py5pZCA9PT0gZWxlbWVudC5pZCAmJlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCAhPT0gZWxlbWVudCAmJlxuICAgICAgICAgICAgaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGFjdGlvblJlc3VsdC5lbGVtZW50cyk7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuZmlsZXMpIHtcbiAgICAgICAgdGhpcy5maWxlcyA9IGFjdGlvblJlc3VsdC5yZXBsYWNlRmlsZXNcbiAgICAgICAgICA/IGFjdGlvblJlc3VsdC5maWxlc1xuICAgICAgICAgIDogeyAuLi50aGlzLmZpbGVzLCAuLi5hY3Rpb25SZXN1bHQuZmlsZXMgfTtcbiAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCBlZGl0aW5nRWxlbWVudCkge1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB2aWV3TW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy52aWV3TW9kZUVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGxldCB6ZW5Nb2RlRW5hYmxlZCA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/Lnplbk1vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgZ3JpZFNpemUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy5ncmlkU2l6ZSB8fCBudWxsO1xuICAgICAgICBsZXQgdGhlbWUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy50aGVtZSB8fCBUSEVNRS5MSUdIVDtcbiAgICAgICAgbGV0IG5hbWUgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy5uYW1lID8/IHRoaXMuc3RhdGUubmFtZTtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgemVuTW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIGdyaWRTaXplID0gdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLnRoZW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdGhlbWUgPSB0aGlzLnByb3BzLnRoZW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByb3BzLm5hbWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBuYW1lID0gdGhpcy5wcm9wcy5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgICAvLyB1c2luZyBPYmplY3QuYXNzaWduIGluc3RlYWQgb2Ygc3ByZWFkIHRvIGZvb2wgVFMgNC4yLjIrIGludG9cbiAgICAgICAgICAgIC8vIHJlZ2FyZGluZyB0aGUgcmVzdWx0aW5nIHR5cGUgYXMgbm90IGNvbnRhaW5pbmcgdW5kZWZpbmVkXG4gICAgICAgICAgICAvLyAod2hpY2ggdGhlIGZvbGxvd2luZyBleHByZXNzaW9uIHdpbGwgbmV2ZXIgY29udGFpbilcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGFjdGlvblJlc3VsdC5hcHBTdGF0ZSB8fCB7fSwge1xuICAgICAgICAgICAgICBlZGl0aW5nRWxlbWVudDpcbiAgICAgICAgICAgICAgICBlZGl0aW5nRWxlbWVudCB8fCBhY3Rpb25SZXN1bHQuYXBwU3RhdGU/LmVkaXRpbmdFbGVtZW50IHx8IG51bGwsXG4gICAgICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIGdyaWRTaXplLFxuICAgICAgICAgICAgICB0aGVtZSxcbiAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5zeW5jSGlzdG9yeSkge1xuICAgICAgICAgICAgICB0aGlzLmhpc3Rvcnkuc2V0Q3VycmVudFN0YXRlKFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgLy8gTGlmZWN5Y2xlXG5cbiAgcHJpdmF0ZSBvbkJsdXIgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25VbmxvYWQgPSAoKSA9PiB7XG4gICAgdGhpcy5vbkJsdXIoKTtcbiAgfTtcblxuICBwcml2YXRlIGRpc2FibGVFdmVudDogRXZlbnRMaXN0ZW5lciA9IChldmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBvbkZvbnRMb2FkZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoaXNUZXh0RWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMub25TY2VuZVVwZGF0ZWQoKTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0SGlzdG9yeSA9ICgpID0+IHtcbiAgICB0aGlzLmhpc3RvcnkuY2xlYXIoKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXRzIHNjZW5lICYgaGlzdG9yeS5cbiAgICogISBEbyBub3QgdXNlIHRvIGNsZWFyIHNjZW5lIHVzZXIgYWN0aW9uICFcbiAgICovXG4gIHByaXZhdGUgcmVzZXRTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAob3B0cz86IHsgcmVzZXRMb2FkaW5nU3RhdGU6IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW10pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICAgICAgICBpc0xvYWRpbmc6IG9wdHM/LnJlc2V0TG9hZGluZ1N0YXRlID8gZmFsc2UgOiBzdGF0ZS5pc0xvYWRpbmcsXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVNjZW5lID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChcImxhdW5jaFF1ZXVlXCIgaW4gd2luZG93ICYmIFwiTGF1bmNoUGFyYW1zXCIgaW4gd2luZG93KSB7XG4gICAgICAod2luZG93IGFzIGFueSkubGF1bmNoUXVldWUuc2V0Q29uc3VtZXIoXG4gICAgICAgIGFzeW5jIChsYXVuY2hQYXJhbXM6IHsgZmlsZXM6IGFueVtdIH0pID0+IHtcbiAgICAgICAgICBpZiAoIWxhdW5jaFBhcmFtcy5maWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlsZUhhbmRsZSA9IGxhdW5jaFBhcmFtcy5maWxlc1swXTtcbiAgICAgICAgICBjb25zdCBibG9iOiBCbG9iID0gYXdhaXQgZmlsZUhhbmRsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKFxuICAgICAgICAgICAgbmV3IEZpbGUoW2Jsb2JdLCBibG9iLm5hbWUgfHwgXCJcIiwgeyB0eXBlOiBibG9iLnR5cGUgfSksXG4gICAgICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgfVxuICAgIGxldCBpbml0aWFsRGF0YSA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGluaXRpYWxEYXRhID0gKGF3YWl0IHRoaXMucHJvcHMuaW5pdGlhbERhdGEpIHx8IG51bGw7XG4gICAgICBpZiAoaW5pdGlhbERhdGE/LmxpYnJhcnlJdGVtcykge1xuICAgICAgICB0aGlzLmxpYnJhcnlcbiAgICAgICAgICAudXBkYXRlTGlicmFyeSh7XG4gICAgICAgICAgICBsaWJyYXJ5SXRlbXM6IGluaXRpYWxEYXRhLmxpYnJhcnlJdGVtcyxcbiAgICAgICAgICAgIG1lcmdlOiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICBpbml0aWFsRGF0YSA9IHtcbiAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2U6XG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8XG4gICAgICAgICAgICBcIkVuY291bnRlcmVkIGFuIGVycm9yIGR1cmluZyBpbXBvcnRpbmcgb3IgcmVzdG9yaW5nIHNjZW5lIGRhdGFcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHNjZW5lID0gcmVzdG9yZShpbml0aWFsRGF0YSwgbnVsbCwgbnVsbCk7XG4gICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgIC8vIHdlJ3JlIGZhbGxpbmcgYmFjayB0byBjdXJyZW50IChwcmUtaW5pdCkgc3RhdGUgd2hlbiBkZWNpZGluZ1xuICAgICAgLy8gd2hldGhlciB0byBvcGVuIHRoZSBsaWJyYXJ5LCB0byBoYW5kbGUgYSBjYXNlIHdoZXJlIHdlXG4gICAgICAvLyB1cGRhdGUgdGhlIHN0YXRlIG91dHNpZGUgb2YgaW5pdGlhbERhdGEgKGUuZy4gd2hlbiBsb2FkaW5nIHRoZSBhcHBcbiAgICAgIC8vIHdpdGggYSBsaWJyYXJ5IGluc3RhbGwgbGluaywgd2hpY2ggc2hvdWxkIGF1dG8tb3BlbiB0aGUgbGlicmFyeSlcbiAgICAgIGlzTGlicmFyeU9wZW46XG4gICAgICAgIGluaXRpYWxEYXRhPy5hcHBTdGF0ZT8uaXNMaWJyYXJ5T3BlbiB8fCB0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4sXG4gICAgICBhY3RpdmVUb29sOlxuICAgICAgICBzY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIlxuICAgICAgICAgID8geyAuLi5zY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLCB0eXBlOiBcInNlbGVjdGlvblwiIH1cbiAgICAgICAgICA6IHNjZW5lLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgdG9hc3Q6IHRoaXMuc3RhdGUudG9hc3QsXG4gICAgfTtcbiAgICBpZiAoaW5pdGlhbERhdGE/LnNjcm9sbFRvQ29udGVudCkge1xuICAgICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgICAgc2NlbmUuZWxlbWVudHMsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5zdGF0ZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5zdGF0ZS5oZWlnaHQsXG4gICAgICAgICAgICBvZmZzZXRUb3A6IHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICAgICAgb2Zmc2V0TGVmdDogdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgLi4uc2NlbmUsXG4gICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWZyZXNoRGV2aWNlU3RhdGUgPSAoY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCkgPT4ge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNpZGViYXJCcmVha3BvaW50ID1cbiAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9IG51bGxcbiAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICA6IE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRIO1xuICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICBpc1NtU2NyZWVuOiB3aWR0aCA8IE1RX1NNX01BWF9XSURUSCxcbiAgICAgIGlzTW9iaWxlOlxuICAgICAgICB3aWR0aCA8IE1RX01BWF9XSURUSF9QT1JUUkFJVCB8fFxuICAgICAgICAoaGVpZ2h0IDwgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUgJiYgd2lkdGggPCBNUV9NQVhfV0lEVEhfTEFORFNDQVBFKSxcbiAgICAgIGNhbkRldmljZUZpdFNpZGViYXI6IHdpZHRoID4gc2lkZWJhckJyZWFrcG9pbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHVibGljIGFzeW5jIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIHRoaXMudW5tb3VudGVkID0gZmFsc2U7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUuY29udGFpbmVyID1cbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UIHx8XG4gICAgICBwcm9jZXNzLmVudi5SRUFDVF9BUFBfVkVSQ0VMX0VOViA9PT0gXCJwcmV2aWV3XCJcbiAgICApIHtcbiAgICAgIGNvbnN0IHNldFN0YXRlID0gdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICAgICAgc3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBzZXRTdGF0ZToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogKC4uLmFyZ3M6IFBhcmFtZXRlcnM8dHlwZW9mIHNldFN0YXRlPikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoLi4uYXJncyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYXBwOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLFxuICAgICAgICB9LFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLmhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLmFkZENhbGxiYWNrKHRoaXMub25TY2VuZVVwZGF0ZWQpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcblxuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ICYmXG4gICAgICAvLyBib3VuZGluZyByZWN0cyBkb24ndCB3b3JrIGluIHRlc3RzIHNvIHVwZGF0aW5nXG4gICAgICAvLyB0aGUgc3RhdGUgb24gaW5pdCB3b3VsZCByZXN1bHQgaW4gbWFraW5nIHRoZSB0ZXN0IGVudmlybyBydW5cbiAgICAgIC8vIGluIG1vYmlsZSBicmVha3BvaW50ICgwIHdpZHRoL2hlaWdodCksIG1ha2luZyBldmVyeXRoaW5nIGZhaWxcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInRlc3RcIlxuICAgICkge1xuICAgICAgdGhpcy5yZWZyZXNoRGV2aWNlU3RhdGUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH1cblxuICAgIGlmIChcIlJlc2l6ZU9ic2VydmVyXCIgaW4gd2luZG93ICYmIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgIFRIUk9UVExFX05FWFRfUkVOREVSID0gZmFsc2U7XG4gICAgICAgIC8vIHJlY29tcHV0ZSBkZXZpY2UgZGltZW5zaW9ucyBzdGF0ZVxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5yZWZyZXNoRGV2aWNlU3RhdGUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhKTtcbiAgICAgICAgLy8gcmVmcmVzaCBvZmZzZXRzXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnVwZGF0ZURPTVJlY3QoKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlcj8ub2JzZXJ2ZSh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCk7XG4gICAgfSBlbHNlIGlmICh3aW5kb3cubWF0Y2hNZWRpYSkge1xuICAgICAgY29uc3QgbWRTY3JlZW5RdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1heC13aWR0aDogJHtNUV9NQVhfV0lEVEhfUE9SVFJBSVR9cHgpLCAobWF4LWhlaWdodDogJHtNUV9NQVhfSEVJR0hUX0xBTkRTQ0FQRX1weCkgYW5kIChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX0xBTkRTQ0FQRX1weClgLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNtU2NyZWVuUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfU01fTUFYX1dJRFRIfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3QgY2FuRGV2aWNlRml0U2lkZWJhck1lZGlhUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtaW4td2lkdGg6ICR7XG4gICAgICAgICAgLy8gTk9URSB0aGlzIHdvbid0IHVwZGF0ZSBpZiBhIGRpZmZlcmVudCBicmVha3BvaW50IGlzIHN1cHBsaWVkXG4gICAgICAgICAgLy8gYWZ0ZXIgbW91bnRcbiAgICAgICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPSBudWxsXG4gICAgICAgICAgICA/IHRoaXMucHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50XG4gICAgICAgICAgICA6IE1RX1JJR0hUX1NJREVCQVJfTUlOX1dJRFRIXG4gICAgICAgIH1weClgLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50IS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgdGhpcy5kZXZpY2UgPSB1cGRhdGVPYmplY3QodGhpcy5kZXZpY2UsIHtcbiAgICAgICAgICBpc1NtU2NyZWVuOiBzbVNjcmVlblF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgICAgaXNNb2JpbGU6IG1kU2NyZWVuUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgICBjYW5EZXZpY2VGaXRTaWRlYmFyOiBjYW5EZXZpY2VGaXRTaWRlYmFyTWVkaWFRdWVyeS5tYXRjaGVzLFxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBtZFNjcmVlblF1ZXJ5LmFkZExpc3RlbmVyKGhhbmRsZXIpO1xuICAgICAgdGhpcy5kZXRhY2hJc01vYmlsZU1xSGFuZGxlciA9ICgpID0+XG4gICAgICAgIG1kU2NyZWVuUXVlcnkucmVtb3ZlTGlzdGVuZXIoaGFuZGxlcik7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoLnNsaWNlKDEpKTtcblxuICAgIGlmIChzZWFyY2hQYXJhbXMuaGFzKFwid2ViLXNoYXJlLXRhcmdldFwiKSkge1xuICAgICAgLy8gT2J0YWluIGEgZmlsZSB0aGF0IHdhcyBzaGFyZWQgdmlhIHRoZSBXZWIgU2hhcmUgVGFyZ2V0IEFQSS5cbiAgICAgIHRoaXMucmVzdG9yZUZpbGVGcm9tU2hhcmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVET01SZWN0KHRoaXMuaW5pdGlhbGl6ZVNjZW5lKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgdGhpcy5maWxlcyA9IHt9O1xuICAgIHRoaXMuaW1hZ2VDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLnVubW91bnRlZCA9IHRydWU7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgIHRoaXMuc2NlbmUuZGVzdHJveSgpO1xuICAgIGNsZWFyVGltZW91dCh0b3VjaFRpbWVvdXQpO1xuICAgIHRvdWNoVGltZW91dCA9IDA7XG4gIH1cblxuICBwcml2YXRlIG9uUmVzaXplID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICB0aGlzLnNjZW5lXG4gICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgIC5mb3JFYWNoKChlbGVtZW50KSA9PiBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpKTtcbiAgICB0aGlzLnNldFN0YXRlKHt9KTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSByZW1vdmVFdmVudExpc3RlbmVycygpIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRoaXMucmVtb3ZlUG9pbnRlcik7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5DT1BZLCB0aGlzLm9uQ29weSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ1VULCB0aGlzLm9uQ3V0KTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULldIRUVMLFxuICAgICAgdGhpcy5vbldoZWVsLFxuICAgICk7XG4gICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcj8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuRFJBR19PVkVSLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuRFJPUCxcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcblxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcblxuICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXI/LigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpOyAvLyAjMzU1M1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuV0hFRUwsXG4gICAgICB0aGlzLm9uV2hlZWwsXG4gICAgICB7IHBhc3NpdmU6IGZhbHNlIH0sXG4gICAgKTtcblxuICAgIGlmICh0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgdGhpcy5vbktleURvd24sIGZhbHNlKTtcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwLCB7IHBhc3NpdmU6IHRydWUgfSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICApO1xuICAgIC8vIHJlcmVuZGVyIHRleHQgZWxlbWVudHMgb24gZm9udCBsb2FkIHRvIGZpeCAjNjM3ICYmICMxNTUzXG4gICAgZG9jdW1lbnQuZm9udHM/LmFkZEV2ZW50TGlzdGVuZXI/LihcImxvYWRpbmdkb25lXCIsIHRoaXMub25Gb250TG9hZGVkKTtcbiAgICAvLyBTYWZhcmktb25seSBkZXNrdG9wIHBpbmNoIHpvb21cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ1VULCB0aGlzLm9uQ3V0KTtcbiAgICBpZiAodGhpcy5wcm9wcy5kZXRlY3RTY3JvbGwpIHtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIgPSBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcihcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgKTtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICAgKTtcbiAgICB9XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRSQUdfT1ZFUixcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRST1AsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gIH1cblxuICBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzOiBBcHBQcm9wcywgcHJldlN0YXRlOiBBcHBTdGF0ZSkge1xuICAgIGlmIChcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ICYmXG4gICAgICBwcmV2UHJvcHMuVUlPcHRpb25zLmRvY2tlZFNpZGViYXJCcmVha3BvaW50ICE9PVxuICAgICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICkge1xuICAgICAgdGhpcy5yZWZyZXNoRGV2aWNlU3RhdGUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHByZXZTdGF0ZS5zY3JvbGxYICE9PSB0aGlzLnN0YXRlLnNjcm9sbFggfHxcbiAgICAgIHByZXZTdGF0ZS5zY3JvbGxZICE9PSB0aGlzLnN0YXRlLnNjcm9sbFlcbiAgICApIHtcbiAgICAgIHRoaXMucHJvcHM/Lm9uU2Nyb2xsQ2hhbmdlPy4odGhpcy5zdGF0ZS5zY3JvbGxYLCB0aGlzLnN0YXRlLnNjcm9sbFkpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzKS5sZW5ndGggJiZcbiAgICAgIGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpXG4gICAgKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZXJhc2VyXCIgJiZcbiAgICAgIHByZXZTdGF0ZS50aGVtZSAhPT0gdGhpcy5zdGF0ZS50aGVtZVxuICAgICkge1xuICAgICAgc2V0RXJhc2VyQ3Vyc29yKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLnRoZW1lKTtcbiAgICB9XG4gICAgLy8gSGlkZSBoeXBlcmxpbmsgcG9wdXAgaWYgc2hvd24gd2hlbiBlbGVtZW50IHR5cGUgaXMgbm90IHNlbGVjdGlvblxuICAgIGlmIChcbiAgICAgIHByZXZTdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cFxuICAgICkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UgfSk7XG4gICAgfVxuICAgIGlmIChwcmV2UHJvcHMubGFuZ0NvZGUgIT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHtcbiAgICAgIHRoaXMudXBkYXRlTGFuZ3VhZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAocHJldlByb3BzLnZpZXdNb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB2aWV3TW9kZUVuYWJsZWQ6ICEhdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZTdGF0ZS52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgICB0aGlzLmRlc2VsZWN0RWxlbWVudHMoKTtcbiAgICB9XG5cbiAgICBpZiAocHJldlByb3BzLnplbk1vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgemVuTW9kZUVuYWJsZWQ6ICEhdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlByb3BzLnRoZW1lICE9PSB0aGlzLnByb3BzLnRoZW1lICYmIHRoaXMucHJvcHMudGhlbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB0aGVtZTogdGhpcy5wcm9wcy50aGVtZSB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlByb3BzLmdyaWRNb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBncmlkU2l6ZTogdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvcHMubmFtZSAmJiBwcmV2UHJvcHMubmFtZSAhPT0gdGhpcy5wcm9wcy5uYW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgbmFtZTogdGhpcy5wcm9wcy5uYW1lLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNsYXNzTGlzdC50b2dnbGUoXG4gICAgICBcInRoZW1lLS1kYXJrXCIsXG4gICAgICB0aGlzLnN0YXRlLnRoZW1lID09PSBcImRhcmtcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkXVxuICAgICkge1xuICAgICAgLy8gZGVmZXIgc28gdGhhdCB0aGUgY29tbWl0VG9IaXN0b3J5IGZsYWcgaXNuJ3QgcmVzZXQgdmlhIGN1cnJlbnQgdXBkYXRlXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBUbyBtYWtlIHN1cmUgYHNlbGVjdGVkTGluZWFyRWxlbWVudGAgaXMgaW4gc3luYyB3aXRoIGBzZWxlY3RlZEVsZW1lbnRJZHNgLCBob3dldmVyIHRoaXMgc2hvdWxkbid0IGJlIG5lZWRlZCBvbmNlXG4gICAgICAvLyB3ZSBoYXZlIGEgc2luZ2xlIEFQSSB0byB1cGRhdGUgYHNlbGVjdGVkRWxlbWVudElkc2BcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG51bGwgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHByZXZTdGF0ZTtcbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbCAhPT0gdGhpcy5zdGF0ZS5hY3RpdmVUb29sICYmXG4gICAgICBtdWx0aUVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKSAmJlxuICAgICAgaXNCaW5kaW5nRWxlbWVudChtdWx0aUVsZW1lbnQsIGZhbHNlKVxuICAgICkge1xuICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgICAgIC0xLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlclNjZW5lKCk7XG4gICAgdGhpcy5oaXN0b3J5LnJlY29yZCh0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKTtcblxuICAgIC8vIERvIG5vdCBub3RpZnkgY29uc3VtZXJzIGlmIHdlJ3JlIHN0aWxsIGxvYWRpbmcgdGhlIHNjZW5lLiBBbW9uZyBvdGhlclxuICAgIC8vIHBvdGVudGlhbCBpc3N1ZXMsIHRoaXMgZml4ZXMgYSBjYXNlIHdoZXJlIHRoZSB0YWIgaXNuJ3QgZm9jdXNlZCBkdXJpbmdcbiAgICAvLyBpbml0LCB3aGljaCB3b3VsZCB0cmlnZ2VyIG9uQ2hhbmdlIHdpdGggZW1wdHkgZWxlbWVudHMsIHdoaWNoIHdvdWxkIHRoZW5cbiAgICAvLyBvdmVycmlkZSB3aGF0ZXZlciBpcyBpbiBsb2NhbFN0b3JhZ2UgY3VycmVudGx5LlxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMucHJvcHMub25DaGFuZ2U/LihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTY2VuZSA9ICgpID0+IHtcbiAgICBjb25zdCBjdXJzb3JCdXR0b246IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVmlld3BvcnRDb29yZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlcm5hbWVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlclN0YXRlczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgdGhpcy5zdGF0ZS5jb2xsYWJvcmF0b3JzLmZvckVhY2goKHVzZXIsIHNvY2tldElkKSA9PiB7XG4gICAgICBpZiAodXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICBpZiAoIShpZCBpbiByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0ucHVzaChzb2NrZXRJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdXNlci5wb2ludGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICAgIHBvaW50ZXJVc2VybmFtZXNbc29ja2V0SWRdID0gdXNlci51c2VybmFtZTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJTdGF0ZSkge1xuICAgICAgICBwb2ludGVyVXNlclN0YXRlc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHBvaW50ZXJWaWV3cG9ydENvb3Jkc1tzb2NrZXRJZF0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgIHtcbiAgICAgICAgICBzY2VuZVg6IHVzZXIucG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lWTogdXNlci5wb2ludGVyLnksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY3Vyc29yQnV0dG9uW3NvY2tldElkXSA9IHVzZXIuYnV0dG9uO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVuZGVyaW5nRWxlbWVudHMgPSB0aGlzLnNjZW5lXG4gICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgLy8gbm90IHBsYWNlZCBvbiBjYW52YXMgeWV0IChidXQgaW4gZWxlbWVudHMgYXJyYXkpXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCA9PT0gZWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBkb24ndCByZW5kZXIgdGV4dCBlbGVtZW50IHRoYXQncyBiZWluZyBjdXJyZW50bHkgZWRpdGVkIChpdCdzXG4gICAgICAgIC8vIHJlbmRlcmVkIG9uIHJlbW90ZSBvbmx5KVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC50eXBlICE9PSBcInRleHRcIiB8fFxuICAgICAgICAgIGVsZW1lbnQuaWQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQuaWRcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgcmVuZGVyU2NlbmUoXG4gICAgICB7XG4gICAgICAgIGVsZW1lbnRzOiByZW5kZXJpbmdFbGVtZW50cyxcbiAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgIHNjYWxlOiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgcmM6IHRoaXMucmMhLFxuICAgICAgICBjYW52YXM6IHRoaXMuY2FudmFzISxcbiAgICAgICAgcmVuZGVyQ29uZmlnOiB7XG4gICAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYLFxuICAgICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSxcbiAgICAgICAgICB2aWV3QmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgem9vbTogdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3JkczogcG9pbnRlclZpZXdwb3J0Q29vcmRzLFxuICAgICAgICAgIHJlbW90ZVBvaW50ZXJCdXR0b246IGN1cnNvckJ1dHRvbixcbiAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJuYW1lczogcG9pbnRlclVzZXJuYW1lcyxcbiAgICAgICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczogcG9pbnRlclVzZXJTdGF0ZXMsXG4gICAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0aGlzLnN0YXRlLnNob3VsZENhY2hlSWdub3JlWm9vbSxcbiAgICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICAgICAgaXNFeHBvcnRpbmc6IGZhbHNlLFxuICAgICAgICAgIHJlbmRlclNjcm9sbGJhcnM6ICF0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICAgICAgfSxcbiAgICAgICAgY2FsbGJhY2s6ICh7IGF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCwgc2Nyb2xsQmFycyB9KSA9PiB7XG4gICAgICAgICAgaWYgKHNjcm9sbEJhcnMpIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY3JvbGxCYXJzID0gc2Nyb2xsQmFycztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgc2Nyb2xsZWRPdXRzaWRlID1cbiAgICAgICAgICAgIC8vIGhpZGUgd2hlbiBlZGl0aW5nIHRleHRcbiAgICAgICAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgICAgPyBmYWxzZVxuICAgICAgICAgICAgICA6ICFhdExlYXN0T25lVmlzaWJsZUVsZW1lbnQgJiYgcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoID4gMDtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zY3JvbGxlZE91dHNpZGUgIT09IHNjcm9sbGVkT3V0c2lkZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbGVkT3V0c2lkZSB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnNjaGVkdWxlSW1hZ2VSZWZyZXNoKCk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgJiYgd2luZG93LkVYQ0FMSURSQVdfVEhST1RUTEVfUkVOREVSID09PSB0cnVlLFxuICAgICk7XG5cbiAgICBpZiAoIVRIUk9UVExFX05FWFRfUkVOREVSKSB7XG4gICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IHRydWU7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25TY3JvbGwgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgY29uc3QgeyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfSA9IHRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpO1xuICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiB7XG4gICAgICBpZiAoc3RhdGUub2Zmc2V0TGVmdCA9PT0gb2Zmc2V0TGVmdCAmJiBzdGF0ZS5vZmZzZXRUb3AgPT09IG9mZnNldFRvcCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9O1xuICAgIH0pO1xuICB9LCBTQ1JPTExfVElNRU9VVCk7XG5cbiAgLy8gQ29weS9wYXN0ZVxuXG4gIHByaXZhdGUgb25DdXQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyhcbiAgICAgIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoIWlzRXhjYWxpZHJhd0FjdGl2ZSB8fCBpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3V0QWxsKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbkNvcHkgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyhcbiAgICAgIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoIWlzRXhjYWxpZHJhd0FjdGl2ZSB8fCBpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY29weUFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgY3V0QWxsID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkN1dCwgXCJrZXlib2FyZFwiKTtcbiAgfTtcblxuICBwcml2YXRlIGNvcHlBbGwgPSAoKSA9PiB7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uQ29weSwgXCJrZXlib2FyZFwiKTtcbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyByZXNldFRhcFR3aWNlKCkge1xuICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uVGFwU3RhcnQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICAvLyBmaXggZm9yIEFwcGxlIFBlbmNpbCBTY3JpYmJsZVxuICAgIC8vIE9uIEFuZHJvaWQsIHByZXZlbnRpbmcgdGhlIGV2ZW50IHdvdWxkIGRpc2FibGUgY29udGV4dE1lbnUgb24gdGFwLWhvbGRcbiAgICBpZiAoIWlzQW5kcm9pZCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBpZiAoIWRpZFRhcFR3aWNlKSB7XG4gICAgICBkaWRUYXBUd2ljZSA9IHRydWU7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgICB0YXBwZWRUd2ljZVRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoXG4gICAgICAgIEFwcC5yZXNldFRhcFR3aWNlLFxuICAgICAgICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGluc2VydCB0ZXh0IG9ubHkgaWYgd2UgdGFwcGVkIHR3aWNlIHdpdGggYSBzaW5nbGUgZmluZ2VyXG4gICAgLy8gZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEgd2lsbCBhbHNvIHByZXZlbnQgaW5zZXJ0aW5nIHRleHQgd2hlbiB1c2VyJ3Mgem9vbWluZ1xuICAgIGlmIChkaWRUYXBUd2ljZSAmJiBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgW3RvdWNoXSA9IGV2ZW50LnRvdWNoZXM7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrKHtcbiAgICAgICAgY2xpZW50WDogdG91Y2guY2xpZW50WCxcbiAgICAgICAgY2xpZW50WTogdG91Y2guY2xpZW50WSxcbiAgICAgIH0pO1xuICAgICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICB9XG4gICAgaWYgKGlzQW5kcm9pZCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25UYXBFbmQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICB0aGlzLnJlc2V0Q29udGV4dE1lbnVUaW1lcigpO1xuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLmNsZWFyKCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgcGFzdGVGcm9tQ2xpcGJvYXJkID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIGFzeW5jIChldmVudDogQ2xpcGJvYXJkRXZlbnQgfCBudWxsKSA9PiB7XG4gICAgICAvLyAjNjg2XG4gICAgICBjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID1cbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKHRhcmdldCk7XG4gICAgICBpZiAoIWlzRXhjYWxpZHJhd0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVsZW1lbnRVbmRlckN1cnNvciA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoY3Vyc29yWCwgY3Vyc29yWSk7XG4gICAgICBpZiAoXG4gICAgICAgIC8vIGlmIG5vIENsaXBib2FyZEV2ZW50IHN1cHBsaWVkLCBhc3N1bWUgd2UncmUgcGFzdGluZyB2aWEgY29udGV4dE1lbnVcbiAgICAgICAgLy8gdGh1cyB0aGVzZSBjaGVja3MgZG9uJ3QgbWFrZSBzZW5zZVxuICAgICAgICBldmVudCAmJlxuICAgICAgICAoIShlbGVtZW50VW5kZXJDdXJzb3IgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkgfHxcbiAgICAgICAgICBpc1dyaXRhYmxlRWxlbWVudCh0YXJnZXQpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gbXVzdCBiZSBjYWxsZWQgaW4gdGhlIHNhbWUgZnJhbWUgKHRodXMgYmVmb3JlIGFueSBhd2FpdHMpIGFzIHRoZSBwYXN0ZVxuICAgICAgLy8gZXZlbnQgZWxzZSBzb21lIGJyb3dzZXJzIChGRi4uLikgd2lsbCBjbGVhciB0aGUgY2xpcGJvYXJkRGF0YVxuICAgICAgLy8gKHNvbWV0aGluZyBzb21ldGhpbmcgc2VjdXJpdHkpXG4gICAgICBsZXQgZmlsZSA9IGV2ZW50Py5jbGlwYm9hcmREYXRhPy5maWxlc1swXTtcblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHBhcnNlQ2xpcGJvYXJkKGV2ZW50KTtcblxuICAgICAgaWYgKCFmaWxlICYmIGRhdGEudGV4dCkge1xuICAgICAgICBjb25zdCBzdHJpbmcgPSBkYXRhLnRleHQudHJpbSgpO1xuICAgICAgICBpZiAoc3RyaW5nLnN0YXJ0c1dpdGgoXCI8c3ZnXCIpICYmIHN0cmluZy5lbmRzV2l0aChcIjwvc3ZnPlwiKSkge1xuICAgICAgICAgIC8vIGlnbm9yZSBTVkcgdmFsaWRhdGlvbi9ub3JtYWxpemF0aW9uIHdoaWNoIHdpbGwgYmUgZG9uZSBkdXJpbmcgaW1hZ2VcbiAgICAgICAgICAvLyBpbml0aWFsaXphdGlvblxuICAgICAgICAgIGZpbGUgPSBTVkdTdHJpbmdUb0ZpbGUoc3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBwcmVmZXIgc3ByZWFkc2hlZXQgZGF0YSBvdmVyIGltYWdlIGZpbGUgKE1TIE9mZmljZS9MaWJyZSBPZmZpY2UpXG4gICAgICBpZiAoaXNTdXBwb3J0ZWRJbWFnZUZpbGUoZmlsZSkgJiYgIWRhdGEuc3ByZWFkc2hlZXQpIHtcbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIHsgY2xpZW50WDogY3Vyc29yWCwgY2xpZW50WTogY3Vyc29yWSB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnByb3BzLm9uUGFzdGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoKGF3YWl0IHRoaXMucHJvcHMub25QYXN0ZShkYXRhLCBldmVudCkpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5lcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZGF0YS5lcnJvck1lc3NhZ2UgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuc3ByZWFkc2hlZXQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcGFzdGVEaWFsb2c6IHtcbiAgICAgICAgICAgIGRhdGE6IGRhdGEuc3ByZWFkc2hlZXQsXG4gICAgICAgICAgICBzaG93bjogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5lbGVtZW50cykge1xuICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICBlbGVtZW50czogZGF0YS5lbGVtZW50cyxcbiAgICAgICAgICBmaWxlczogZGF0YS5maWxlcyB8fCBudWxsLFxuICAgICAgICAgIHBvc2l0aW9uOiBcImN1cnNvclwiLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS50ZXh0KSB7XG4gICAgICAgIHRoaXMuYWRkVGV4dEZyb21QYXN0ZShkYXRhLnRleHQpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KTtcbiAgICAgIGV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBhZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSA9IChvcHRzOiB7XG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzIHwgbnVsbDtcbiAgICBwb3NpdGlvbjogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHwgXCJjdXJzb3JcIiB8IFwiY2VudGVyXCI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHJlc3RvcmVFbGVtZW50cyhvcHRzLmVsZW1lbnRzLCBudWxsKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoZWxlbWVudHMpO1xuXG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJYID0gZGlzdGFuY2UobWluWCwgbWF4WCkgLyAyO1xuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWSA9IGRpc3RhbmNlKG1pblksIG1heFkpIC8gMjtcblxuICAgIGNvbnN0IGNsaWVudFggPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFhcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWFxuICAgICAgICA6IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgIGNvbnN0IGNsaWVudFkgPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFlcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWVxuICAgICAgICA6IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGR4ID0geCAtIGVsZW1lbnRzQ2VudGVyWDtcbiAgICBjb25zdCBkeSA9IHkgLSBlbGVtZW50c0NlbnRlclk7XG4gICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcblxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KGR4LCBkeSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnRzID0gZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBuZXdFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCxcbiAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCArIGdyaWRYIC0gbWluWCxcbiAgICAgICAgICB5OiBlbGVtZW50LnkgKyBncmlkWSAtIG1pblksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgbmV3RWxlbWVudC5pZCk7XG4gICAgICByZXR1cm4gbmV3RWxlbWVudDtcbiAgICB9KTtcbiAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKG5ld0VsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG4gICAgY29uc3QgbmV4dEVsZW1lbnRzID0gW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIC4uLm5ld0VsZW1lbnRzLFxuICAgIF07XG4gICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKG5leHRFbGVtZW50cywgZWxlbWVudHMsIG9sZElkVG9EdXBsaWNhdGVkSWQpO1xuXG4gICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLm9wdHMuZmlsZXMgfTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0RWxlbWVudHMpO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB7XG4gICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICBpc0xpYnJhcnlPcGVuOlxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuICYmIHRoaXMuZGV2aWNlLmNhbkRldmljZUZpdFNpZGViYXJcbiAgICAgICAgICAgICAgPyB0aGlzLnN0YXRlLmlzTGlicmFyeU1lbnVEb2NrZWRcbiAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld0VsZW1lbnRzLnJlZHVjZShcbiAgICAgICAgICAgIChhY2M6IFJlY29yZDxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdLCB0cnVlPiwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzQm91bmRUb0NvbnRhaW5lcihlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIGFjY1tlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgKSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5zZXRBY3RpdmVUb29sKHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KTtcbiAgfTtcblxuICBwcml2YXRlIGFkZFRleHRGcm9tUGFzdGUodGV4dDogYW55KSB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdUZXh0RWxlbWVudCh7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgdGV4dCxcbiAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIHRleHRBbGlnbjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgIHZlcnRpY2FsQWxpZ246IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGVsZW1lbnQsXG4gICAgXSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSB9KTtcbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gIH1cblxuICAvLyBDb2xsYWJvcmF0aW9uXG5cbiAgc2V0QXBwU3RhdGUgPSAob2JqOiBhbnkpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKG9iaik7XG4gIH07XG5cbiAgcmVtb3ZlUG9pbnRlciA9IChldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgIHRoaXMucmVzZXRDb250ZXh0TWVudVRpbWVyKCk7XG4gICAgfVxuXG4gICAgZ2VzdHVyZS5wb2ludGVycy5kZWxldGUoZXZlbnQucG9pbnRlcklkKTtcbiAgfTtcblxuICB0b2dnbGVMb2NrID0gKHNvdXJjZTogXCJrZXlib2FyZFwiIHwgXCJ1aVwiID0gXCJ1aVwiKSA9PiB7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICB0cmFja0V2ZW50KFxuICAgICAgICBcInRvb2xiYXJcIixcbiAgICAgICAgXCJ0b2dnbGVMb2NrXCIsXG4gICAgICAgIGAke3NvdXJjZX0gKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFjdGl2ZVRvb2w6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuYWN0aXZlVG9vbCxcbiAgICAgICAgICAuLi51cGRhdGVBY3RpdmVUb29sKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHByZXZTdGF0ZS5hY3RpdmVUb29sLmxvY2tlZFxuICAgICAgICAgICAgICA/IHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9XG4gICAgICAgICAgICAgIDogcHJldlN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBsb2NrZWQ6ICFwcmV2U3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIHRvZ2dsZVBlbk1vZGUgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwZW5Nb2RlOiAhcHJldlN0YXRlLnBlbk1vZGUsXG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIHNjcm9sbFRvQ29udGVudCA9IChcbiAgICB0YXJnZXQ6XG4gICAgICB8IEV4Y2FsaWRyYXdFbGVtZW50XG4gICAgICB8IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10gPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC4uLmNhbGN1bGF0ZVNjcm9sbENlbnRlcihcbiAgICAgICAgQXJyYXkuaXNBcnJheSh0YXJnZXQpID8gdGFyZ2V0IDogW3RhcmdldF0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgKSxcbiAgICB9KTtcbiAgfTtcblxuICBzZXRUb2FzdCA9IChcbiAgICB0b2FzdDoge1xuICAgICAgbWVzc2FnZTogc3RyaW5nO1xuICAgICAgY2xvc2FibGU/OiBib29sZWFuO1xuICAgICAgZHVyYXRpb24/OiBudW1iZXI7XG4gICAgfSB8IG51bGwsXG4gICkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyB0b2FzdCB9KTtcbiAgfTtcblxuICByZXN0b3JlRmlsZUZyb21TaGFyZSA9IGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgd2ViU2hhcmVUYXJnZXRDYWNoZSA9IGF3YWl0IGNhY2hlcy5vcGVuKFwid2ViLXNoYXJlLXRhcmdldFwiKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLm1hdGNoKFwic2hhcmVkLWZpbGVcIik7XG4gICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IHJlc3BvbnNlLmJsb2IoKTtcbiAgICAgICAgY29uc3QgZmlsZSA9IG5ldyBGaWxlKFtibG9iXSwgYmxvYi5uYW1lIHx8IFwiXCIsIHsgdHlwZTogYmxvYi50eXBlIH0pO1xuICAgICAgICB0aGlzLmxvYWRGaWxlVG9DYW52YXMoZmlsZSwgbnVsbCk7XG4gICAgICAgIGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUuZGVsZXRlKFwic2hhcmVkLWZpbGVcIik7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBBUFBfTkFNRSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKiogYWRkcyBzdXBwbGllZCBmaWxlcyB0byBleGlzdGluZyBmaWxlcyBpbiB0aGUgYXBwU3RhdGUgKi9cbiAgcHVibGljIGFkZEZpbGVzOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSVtcImFkZEZpbGVzXCJdID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChmaWxlcykgPT4ge1xuICAgICAgY29uc3QgZmlsZXNNYXAgPSBmaWxlcy5yZWR1Y2UoKGFjYywgZmlsZURhdGEpID0+IHtcbiAgICAgICAgYWNjLnNldChmaWxlRGF0YS5pZCwgZmlsZURhdGEpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcDxGaWxlSWQsIEJpbmFyeUZpbGVEYXRhPigpKTtcblxuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4uT2JqZWN0LmZyb21FbnRyaWVzKGZpbGVzTWFwKSB9O1xuXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZWxlbWVudCkgJiZcbiAgICAgICAgICBmaWxlc01hcC5oYXMoZWxlbWVudC5maWxlSWQpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuaW1hZ2VDYWNoZS5kZWxldGUoZWxlbWVudC5maWxlSWQpO1xuICAgICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5zY2VuZS5pbmZvcm1NdXRhdGlvbigpO1xuXG4gICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHVibGljIHVwZGF0ZVNjZW5lID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIDxLIGV4dGVuZHMga2V5b2YgQXBwU3RhdGU+KHNjZW5lRGF0YToge1xuICAgICAgZWxlbWVudHM/OiBTY2VuZURhdGFbXCJlbGVtZW50c1wiXTtcbiAgICAgIGFwcFN0YXRlPzogUGljazxBcHBTdGF0ZSwgSz4gfCBudWxsO1xuICAgICAgY29sbGFib3JhdG9ycz86IFNjZW5lRGF0YVtcImNvbGxhYm9yYXRvcnNcIl07XG4gICAgICBjb21taXRUb0hpc3Rvcnk/OiBTY2VuZURhdGFbXCJjb21taXRUb0hpc3RvcnlcIl07XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKHNjZW5lRGF0YS5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmFwcFN0YXRlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoc2NlbmVEYXRhLmFwcFN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5lbGVtZW50cykge1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhzY2VuZURhdGEuZWxlbWVudHMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmNvbGxhYm9yYXRvcnMpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvbGxhYm9yYXRvcnM6IHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBvblNjZW5lVXBkYXRlZCA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHt9KTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbiA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGN1cnNvclggPSBldmVudC5jbGllbnRYO1xuICAgICAgY3Vyc29yWSA9IGV2ZW50LmNsaWVudFk7XG4gICAgfSxcbiAgKTtcblxuICAvLyBJbnB1dCBoYW5kbGluZ1xuXG4gIHByaXZhdGUgb25LZXlEb3duID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudCB8IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIC8vIG5vcm1hbGl6ZSBgZXZlbnQua2V5YCB3aGVuIENhcHNMb2NrIGlzIHByZXNzZWQgIzIzNzJcblxuICAgICAgaWYgKFxuICAgICAgICBcIlByb3h5XCIgaW4gd2luZG93ICYmXG4gICAgICAgICgoIWV2ZW50LnNoaWZ0S2V5ICYmIC9eW0EtWl0kLy50ZXN0KGV2ZW50LmtleSkpIHx8XG4gICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5ICYmIC9eW2Etel0kLy50ZXN0KGV2ZW50LmtleSkpKVxuICAgICAgKSB7XG4gICAgICAgIGV2ZW50ID0gbmV3IFByb3h5KGV2ZW50LCB7XG4gICAgICAgICAgZ2V0KGV2OiBhbnksIHByb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXZbcHJvcF07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgLy8gZml4IGZvciBQcm94aWVzIGhpamFja2luZyBgdGhpc2BcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmJpbmQoZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb3AgPT09IFwia2V5XCJcbiAgICAgICAgICAgICAgPyAvLyBDYXBzTG9jayBpbnZlcnRzIGNhcGl0YWxpemF0aW9uIGJhc2VkIG9uIFNoaWZ0S2V5LCBzbyBpbnZlcnRcbiAgICAgICAgICAgICAgICAvLyBpdCBiYWNrXG4gICAgICAgICAgICAgICAgZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgICA/IGV2LmtleS50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICAgICAgOiBldi5rZXkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICA6IHZhbHVlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBwcmV2ZW50IGJyb3dzZXIgem9vbSBpbiBpbnB1dCBmaWVsZHNcbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiBpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpKSB7XG4gICAgICAgIGlmIChldmVudC5jb2RlID09PSBDT0RFUy5NSU5VUyB8fCBldmVudC5jb2RlID09PSBDT0RFUy5FUVVBTCkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGJhaWwgaWZcbiAgICAgIGlmIChcbiAgICAgICAgLy8gaW5zaWRlIGFuIGlucHV0XG4gICAgICAgIChpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpICYmXG4gICAgICAgICAgLy8gdW5sZXNzIHByZXNzaW5nIGVzY2FwZSAoZmluYWxpemUgYWN0aW9uKVxuICAgICAgICAgIGV2ZW50LmtleSAhPT0gS0VZUy5FU0NBUEUpIHx8XG4gICAgICAgIC8vIG9yIHVubGVzcyB1c2luZyBhcnJvd3MgKHRvIG1vdmUgYmV0d2VlbiBidXR0b25zKVxuICAgICAgICAoaXNBcnJvd0tleShldmVudC5rZXkpICYmIGlzSW5wdXRMaWtlKGV2ZW50LnRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlFVRVNUSU9OX01BUkspIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2hvd0hlbHBEaWFsb2c6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hY3Rpb25NYW5hZ2VyLmhhbmRsZUtleURvd24oZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5jb2RlID09PSBDT0RFUy5aRVJPKSB7XG4gICAgICAgIGNvbnN0IG5leHRTdGF0ZSA9ICF0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW47XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiBuZXh0U3RhdGUgfSk7XG4gICAgICAgIC8vIHRyYWNrIG9ubHkgb3BlbmluZ3NcbiAgICAgICAgaWYgKG5leHRTdGF0ZSkge1xuICAgICAgICAgIHRyYWNrRXZlbnQoXG4gICAgICAgICAgICBcImxpYnJhcnlcIixcbiAgICAgICAgICAgIFwidG9nZ2xlTGlicmFyeSAob3BlbilcIixcbiAgICAgICAgICAgIGBrZXlib2FyZCAoJHt0aGlzLmRldmljZS5pc01vYmlsZSA/IFwibW9iaWxlXCIgOiBcImRlc2t0b3BcIn0pYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9XG4gICAgICAgICAgKHRoaXMuc3RhdGUuZ3JpZFNpemUgJiZcbiAgICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICA/IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVFxuICAgICAgICAgICAgICA6IHRoaXMuc3RhdGUuZ3JpZFNpemUpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgPyBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgIDogRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5UKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgb2Zmc2V0WCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0xFRlQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1JJR0hUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IHN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1VQKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19ET1dOKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IHN0ZXA7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHg6IGVsZW1lbnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBlbGVtZW50LnkgKyBvZmZzZXRZLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50LCB7XG4gICAgICAgICAgICBzaW11bHRhbmVvdXNseVVwZGF0ZWQ6IHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuRU5URVIpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIGlmIChpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgIT09XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG5cbiAgICAgICAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgICAgICAgIHNjZW5lWDogc2VsZWN0ZWRFbGVtZW50LnggKyBzZWxlY3RlZEVsZW1lbnQud2lkdGggLyAyLFxuICAgICAgICAgICAgICBzY2VuZVk6IHNlbGVjdGVkRWxlbWVudC55ICsgc2VsZWN0ZWRFbGVtZW50LmhlaWdodCAvIDIsXG4gICAgICAgICAgICAgIHNob3VsZEJpbmQ6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAhZXZlbnQuY3RybEtleSAmJlxuICAgICAgICAhZXZlbnQuYWx0S2V5ICYmXG4gICAgICAgICFldmVudC5tZXRhS2V5ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ID09PSBudWxsXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBmaW5kU2hhcGVCeUtleShldmVudC5rZXkpO1xuICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IHNoYXBlKSB7XG4gICAgICAgICAgICB0cmFja0V2ZW50KFxuICAgICAgICAgICAgICBcInRvb2xiYXJcIixcbiAgICAgICAgICAgICAgc2hhcGUsXG4gICAgICAgICAgICAgIGBrZXlib2FyZCAoJHt0aGlzLmRldmljZS5pc01vYmlsZSA/IFwibW9iaWxlXCIgOiBcImRlc2t0b3BcIn0pYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IHNoYXBlIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5RKSB7XG4gICAgICAgICAgdGhpcy50b2dnbGVMb2NrKFwia2V5Ym9hcmRcIik7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuU1BBQ0UgJiYgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAwKSB7XG4gICAgICAgIGlzSG9sZGluZ1NwYWNlID0gdHJ1ZTtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCQklORyk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgKGV2ZW50LmtleSA9PT0gS0VZUy5HIHx8IGV2ZW50LmtleSA9PT0gS0VZUy5TKSAmJlxuICAgICAgICAhZXZlbnQuYWx0S2V5ICYmXG4gICAgICAgICFldmVudFtLRVlTLkNUUkxfT1JfQ01EXVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgICAgIXNlbGVjdGVkRWxlbWVudHMubGVuZ3RoXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBldmVudC5rZXkgPT09IEtFWVMuRyAmJlxuICAgICAgICAgIChoYXNCYWNrZ3JvdW5kKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlKSB8fFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PiBoYXNCYWNrZ3JvdW5kKGVsZW1lbnQudHlwZSkpKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcImJhY2tncm91bmRDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUykge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwic3Ryb2tlQ29sb3JQaWNrZXJcIiB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBvbldoZWVsID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogV2hlZWxFdmVudCkgPT4ge1xuICAgIC8vIHByZXZlbnQgYnJvd3NlciBwaW5jaCB6b29tIG9uIERPTSBlbGVtZW50c1xuICAgIGlmICghKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSAmJiBldmVudC5jdHJsS2V5KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbktleVVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuU1BBQ0UpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaXNIb2xkaW5nU3BhY2UgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiAhdGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogdHJ1ZSB9KTtcbiAgICB9XG4gICAgaWYgKGlzQXJyb3dLZXkoZXZlbnQua2V5KSkge1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICA/IGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cylcbiAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICB9KTtcblxuICBwcml2YXRlIHNldEFjdGl2ZVRvb2wgPSAoXG4gICAgdG9vbDpcbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfVxuICAgICAgfCB7IHR5cGU6IFwiY3VzdG9tXCI7IGN1c3RvbVR5cGU6IHN0cmluZyB9LFxuICApID0+IHtcbiAgICBjb25zdCBuZXh0QWN0aXZlVG9vbCA9IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgdG9vbCk7XG4gICAgaWYgKCFpc0hvbGRpbmdTcGFjZSkge1xuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgIH1cbiAgICBpZiAoaXNUb29sSWNvbihkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cbiAgICBpZiAoIWlzTGluZWFyRWxlbWVudFR5cGUobmV4dEFjdGl2ZVRvb2wudHlwZSkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICAgIGlmIChuZXh0QWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgIHRoaXMub25JbWFnZUFjdGlvbigpO1xuICAgIH1cbiAgICBpZiAobmV4dEFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGFjdGl2ZVRvb2w6IG5leHRBY3RpdmVUb29sLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFjdGl2ZVRvb2w6IG5leHRBY3RpdmVUb29sIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHNldEN1cnNvciA9IChjdXJzb3I6IHN0cmluZykgPT4ge1xuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgY3Vyc29yKTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0Q3Vyc29yID0gKCkgPT4ge1xuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgfTtcbiAgLyoqXG4gICAqIHJldHVybnMgd2hldGhlciB1c2VyIGlzIG1ha2luZyBhIGdlc3R1cmUgd2l0aCA+PSAyIGZpbmdlcnMgKHBvaW50cylcbiAgICogb24gbyB0b3VjaCBzY3JlZW4gKG5vdCBvbiBhIHRyYWNrcGFkKS4gQ3VycmVudGx5IG9ubHkgcmVsYXRlcyB0byBEYXJ3aW5cbiAgICogKGlPUy9pUGFkT1MsTWFjT1MpLCBidXQgbWF5IHdvcmsgb24gb3RoZXIgZGV2aWNlcyBpbiB0aGUgZnV0dXJlIGlmXG4gICAqIEdlc3R1cmVFdmVudCBpcyBzdGFuZGFyZGl6ZWQuXG4gICAqL1xuICBwcml2YXRlIGlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSA9ICgpID0+IHtcbiAgICAvLyB3ZSBkb24ndCB3YW50IHRvIGRlc2VsZWN0IHdoZW4gdXNpbmcgdHJhY2twYWQsIGFuZCBtdWx0aS1wb2ludCBnZXN0dXJlc1xuICAgIC8vIG9ubHkgd29yayBvbiB0b3VjaCBzY3JlZW5zLCBzbyBjaGVja2luZyBmb3IgPj0gcG9pbnRlcnMgbWVhbnMgd2UncmUgb24gYVxuICAgIC8vIHRvdWNoc2NyZWVuXG4gICAgcmV0dXJuIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+PSAyO1xuICB9O1xuXG4gIC8vIGZpcmVzIG9ubHkgb24gU2FmYXJpXG4gIHByaXZhdGUgb25HZXN0dXJlU3RhcnQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gd2Ugb25seSB3YW50IHRvIGRlc2VsZWN0IG9uIHRvdWNoIHNjcmVlbnMgYmVjYXVzZSB1c2VyIG1heSBoYXZlIHNlbGVjdGVkXG4gICAgLy8gZWxlbWVudHMgYnkgbWlzdGFrZSB3aGlsZSB6b29taW5nXG4gICAgaWYgKHRoaXMuaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlKCkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgfSk7XG4gICAgfVxuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICB9KTtcblxuICAvLyBmaXJlcyBvbmx5IG9uIFNhZmFyaVxuICBwcml2YXRlIG9uR2VzdHVyZUNoYW5nZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAvLyBvbkdlc3R1cmVDaGFuZ2Ugb25seSBoYXMgem9vbSBmYWN0b3IgYnV0IG5vdCB0aGUgY2VudGVyLlxuICAgIC8vIElmIHdlJ3JlIG9uIGlQYWQgb3IgaVBob25lLCB0aGVuIHdlIHJlY29nbml6ZSBtdWx0aS10b3VjaCBhbmQgd2lsbFxuICAgIC8vIHpvb20gaW4gYXQgdGhlIHJpZ2h0IGxvY2F0aW9uIGluIHRoZSB0b3VjaG1vdmUgaGFuZGxlclxuICAgIC8vIChoYW5kbGVDYW52YXNQb2ludGVyTW92ZSkuXG4gICAgLy9cbiAgICAvLyBPbiBNYWNib29rIHRyYWNrcGFkLCB3ZSBkb24ndCBoYXZlIHRob3NlIGV2ZW50cyBzbyB3aWxsIHpvb20gaW4gYXQgdGhlXG4gICAgLy8gY3VycmVudCBsb2NhdGlvbiBpbnN0ZWFkLlxuICAgIC8vXG4gICAgLy8gQXMgc3VjaCwgYmFpbCBmcm9tIHRoaXMgaGFuZGxlciBvbiB0b3VjaCBkZXZpY2VzLlxuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbFNjYWxlID0gZ2VzdHVyZS5pbml0aWFsU2NhbGU7XG4gICAgaWYgKGluaXRpYWxTY2FsZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGN1cnNvclgsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGN1cnNvclksXG4gICAgICAgICAgICBuZXh0Wm9vbTogZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogZXZlbnQuc2NhbGUpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICksXG4gICAgICB9KSk7XG4gICAgfVxuICB9KTtcblxuICAvLyBmaXJlcyBvbmx5IG9uIFNhZmFyaVxuICBwcml2YXRlIG9uR2VzdHVyZUVuZCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gcmVzZWxlY3QgZWxlbWVudHMgb25seSBvbiB0b3VjaCBzY3JlZW5zIChzZWUgb25HZXN0dXJlU3RhcnQpXG4gICAgaWYgKHRoaXMuaXNUb3VjaFNjcmVlbk11bHRpVG91Y2hHZXN0dXJlKCkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IG51bGw7XG4gIH0pO1xuXG4gIHByaXZhdGUgaGFuZGxlVGV4dFd5c2l3eWcoXG4gICAgZWxlbWVudDogRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICAgIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50ID0gZmFsc2UsXG4gICAgfToge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnQgPSAoXG4gICAgICB0ZXh0OiBzdHJpbmcsXG4gICAgICBvcmlnaW5hbFRleHQ6IHN0cmluZyxcbiAgICAgIGlzRGVsZXRlZDogYm9vbGVhbixcbiAgICApID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKF9lbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKF9lbGVtZW50LmlkID09PSBlbGVtZW50LmlkICYmIGlzVGV4dEVsZW1lbnQoX2VsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlVGV4dEVsZW1lbnQoX2VsZW1lbnQsIHtcbiAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgaXNEZWxldGVkLFxuICAgICAgICAgICAgICBvcmlnaW5hbFRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIF9lbGVtZW50O1xuICAgICAgICB9KSxcbiAgICAgIF0pO1xuICAgIH07XG5cbiAgICB0ZXh0V3lzaXd5Zyh7XG4gICAgICBpZDogZWxlbWVudC5pZCxcbiAgICAgIGNhbnZhczogdGhpcy5jYW52YXMsXG4gICAgICBnZXRWaWV3cG9ydENvb3JkczogKHgsIHkpID0+IHtcbiAgICAgICAgY29uc3QgeyB4OiB2aWV3cG9ydFgsIHk6IHZpZXdwb3J0WSB9ID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgICAgIHNjZW5lWTogeSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgdmlld3BvcnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICAgIHZpZXdwb3J0WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICBdO1xuICAgICAgfSxcbiAgICAgIG9uQ2hhbmdlOiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHRleHQpID0+IHtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCB0ZXh0LCBmYWxzZSk7XG4gICAgICAgIGlmIChpc05vbkRlbGV0ZWRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBvblN1Ym1pdDogd2l0aEJhdGNoZWRVcGRhdGVzKCh7IHRleHQsIHZpYUtleWJvYXJkLCBvcmlnaW5hbFRleHQgfSkgPT4ge1xuICAgICAgICBjb25zdCBpc0RlbGV0ZWQgPSAhdGV4dC50cmltKCk7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgb3JpZ2luYWxUZXh0LCBpc0RlbGV0ZWQpO1xuICAgICAgICAvLyBzZWxlY3QgdGhlIGNyZWF0ZWQgdGV4dCBlbGVtZW50IG9ubHkgaWYgc3VibWl0dGluZyB2aWEga2V5Ym9hcmRcbiAgICAgICAgLy8gKHdoZW4gc3VibWl0dGluZyB2aWEgY2xpY2sgaXQgc2hvdWxkIGFjdCBhcyBzaWduYWwgdG8gZGVzZWxlY3QpXG4gICAgICAgIGlmICghaXNEZWxldGVkICYmIHZpYUtleWJvYXJkKSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudElkVG9TZWxlY3QgPSBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA/IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgIDogZWxlbWVudC5pZDtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgW2VsZW1lbnRJZFRvU2VsZWN0XTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RlbGV0ZWQpIHtcbiAgICAgICAgICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24odGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgW1xuICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICBdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCB8fCBpc0V4aXN0aW5nRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBlZGl0aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgICAgfSksXG4gICAgICBlbGVtZW50LFxuICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQsXG4gICAgICBhcHA6IHRoaXMsXG4gICAgfSk7XG4gICAgLy8gZGVzZWxlY3QgYWxsIG90aGVyIGVsZW1lbnRzIHdoZW4gaW5zZXJ0aW5nIHRleHRcbiAgICB0aGlzLmRlc2VsZWN0RWxlbWVudHMoKTtcblxuICAgIC8vIGRvIGFuIGluaXRpYWwgdXBkYXRlIHRvIHJlLWluaXRpYWxpemUgZWxlbWVudCBwb3NpdGlvbiBzaW5jZSB3ZSB3ZXJlXG4gICAgLy8gbW9kaWZ5aW5nIGVsZW1lbnQncyB4L3kgZm9yIHNha2Ugb2YgZWRpdG9yIChjYXNlOiBzeW5jaW5nIHRvIHJlbW90ZSlcbiAgICB1cGRhdGVFbGVtZW50KGVsZW1lbnQudGV4dCwgZWxlbWVudC5vcmlnaW5hbFRleHQsIGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzZWxlY3RFbGVtZW50cygpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3VGV4dEVsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oeCwgeSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBpZiAoZWxlbWVudCAmJiBpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmICFlbGVtZW50LmlzRGVsZXRlZCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIG9wdHM/OiB7XG4gICAgICAvKiogaWYgdHJ1ZSwgcmV0dXJucyB0aGUgZmlyc3Qgc2VsZWN0ZWQgZWxlbWVudCAod2l0aCBoaWdoZXN0IHotaW5kZXgpXG4gICAgICAgIG9mIGFsbCBoaXQgZWxlbWVudHMgKi9cbiAgICAgIHByZWZlclNlbGVjdGVkPzogYm9vbGVhbjtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50PzogYm9vbGVhbjtcbiAgICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50cz86IGJvb2xlYW47XG4gICAgfSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBhbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBvcHRzPy5pbmNsdWRlQm91bmRUZXh0RWxlbWVudCxcbiAgICAgIG9wdHM/LmluY2x1ZGVMb2NrZWRFbGVtZW50cyxcbiAgICApO1xuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICBpZiAob3B0cz8ucHJlZmVyU2VsZWN0ZWQpIHtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSBhbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxOyBpbmRleCA+IC0xOyBpbmRleC0tKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2FsbEhpdEVsZW1lbnRzW2luZGV4XS5pZF0pIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1tpbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXggPVxuICAgICAgICBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxXTtcbiAgICAgIC8vIElmIHdlJ3JlIGhpdHRpbmcgZWxlbWVudCB3aXRoIGhpZ2hlc3Qgei1pbmRleCBvbmx5IG9uIGl0cyBib3VuZGluZyBib3hcbiAgICAgIC8vIHdoaWxlIGFsc28gaGl0dGluZyBvdGhlciBlbGVtZW50IGZpZ3VyZSwgdGhlIGxhdHRlciBzaG91bGQgYmUgY29uc2lkZXJlZC5cbiAgICAgIHJldHVybiBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgIGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIClcbiAgICAgICAgPyBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAyXVxuICAgICAgICA6IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleDtcbiAgICB9XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzWzBdO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBpbmNsdWRlTG9ja2VkRWxlbWVudHM6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSB7XG4gICAgY29uc3QgZWxlbWVudHMgPVxuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQgJiYgaW5jbHVkZUxvY2tlZEVsZW1lbnRzXG4gICAgICAgID8gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICA6IHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgICAgICAgKGluY2x1ZGVMb2NrZWRFbGVtZW50cyB8fCAhZWxlbWVudC5sb2NrZWQpICYmXG4gICAgICAgICAgICAgICAgKGluY2x1ZGVCb3VuZFRleHRFbGVtZW50IHx8XG4gICAgICAgICAgICAgICAgICAhKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgZWxlbWVudC5jb250YWluZXJJZCkpLFxuICAgICAgICAgICAgKTtcblxuICAgIHJldHVybiBnZXRFbGVtZW50c0F0UG9zaXRpb24oZWxlbWVudHMsIChlbGVtZW50KSA9PlxuICAgICAgaGl0VGVzdChlbGVtZW50LCB0aGlzLnN0YXRlLCB4LCB5KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFRleHRFZGl0aW5nID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICAgIHNob3VsZEJpbmQsXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgPSB0cnVlLFxuICB9OiB7XG4gICAgLyoqIFggcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVg6IG51bWJlcjtcbiAgICAvKiogWSBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICAgIHNob3VsZEJpbmQ6IGJvb2xlYW47XG4gICAgLyoqIHdoZXRoZXIgdG8gYXR0ZW1wdCB0byBpbnNlcnQgYXQgZWxlbWVudCBjZW50ZXIgaWYgYXBwbGljYWJsZSAqL1xuICAgIGluc2VydEF0UGFyZW50Q2VudGVyPzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIGxldCBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9XG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlciAmJlxuICAgICAgdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgKTtcblxuICAgIGxldCBleGlzdGluZ1RleHRFbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdUZXh0RWxlbWVudD4gfCBudWxsID0gbnVsbDtcbiAgICBsZXQgY29udGFpbmVyOiBFeGNhbGlkcmF3VGV4dENvbnRhaW5lciB8IG51bGwgPSBudWxsO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBpZiAoaXNUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSkge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgIH0gZWxzZSBpZiAoaXNUZXh0QmluZGFibGVDb250YWluZXIoc2VsZWN0ZWRFbGVtZW50c1swXSwgZmFsc2UpKSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSBnZXRCb3VuZFRleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcbiAgICB9XG5cbiAgICAvLyBiaW5kIHRvIGNvbnRhaW5lciB3aGVuIHNob3VsZEJpbmQgaXMgdHJ1ZSBvclxuICAgIC8vIGNsaWNrZWQgb24gY2VudGVyIG9mIGNvbnRhaW5lclxuICAgIGlmIChcbiAgICAgICFjb250YWluZXIgJiZcbiAgICAgICFleGlzdGluZ1RleHRFbGVtZW50ICYmXG4gICAgICAoc2hvdWxkQmluZCB8fCBwYXJlbnRDZW50ZXJQb3NpdGlvbilcbiAgICApIHtcbiAgICAgIGNvbnRhaW5lciA9IGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24oXG4gICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgKGVsZSkgPT5cbiAgICAgICAgICAgICAgaXNUZXh0QmluZGFibGVDb250YWluZXIoZWxlLCBmYWxzZSkgJiYgIWdldEJvdW5kVGV4dEVsZW1lbnQoZWxlKSxcbiAgICAgICAgICApLFxuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFleGlzdGluZ1RleHRFbGVtZW50ICYmIGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgZm9udFN0cmluZyA9IHtcbiAgICAgICAgZm9udFNpemU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZSxcbiAgICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB9O1xuICAgICAgY29uc3QgbWluV2lkdGggPSBnZXRBcHByb3hNaW5MaW5lV2lkdGgoZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSk7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBnZXRBcHByb3hNaW5MaW5lSGVpZ2h0KGdldEZvbnRTdHJpbmcoZm9udFN0cmluZykpO1xuICAgICAgY29uc3QgbmV3SGVpZ2h0ID0gTWF0aC5tYXgoY29udGFpbmVyLmhlaWdodCwgbWluSGVpZ2h0KTtcbiAgICAgIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5tYXgoY29udGFpbmVyLndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IG5ld0hlaWdodCwgd2lkdGg6IG5ld1dpZHRoIH0pO1xuICAgICAgc2NlbmVYID0gY29udGFpbmVyLnggKyBuZXdXaWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBjb250YWluZXIueSArIG5ld0hlaWdodCAvIDI7XG4gICAgICBpZiAocGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgcGFyZW50Q2VudGVyUG9zaXRpb24gPSB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgICAgc2NlbmVYLFxuICAgICAgICAgIHNjZW5lWSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnQgPSBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA/IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgIDogbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgICAgIHg6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJYXG4gICAgICAgICAgICA6IHNjZW5lWCxcbiAgICAgICAgICB5OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWVxuICAgICAgICAgICAgOiBzY2VuZVksXG4gICAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgICAgIHRleHQ6IFwiXCIsXG4gICAgICAgICAgZm9udFNpemU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250U2l6ZSxcbiAgICAgICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgICAgICB0ZXh0QWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFwiY2VudGVyXCJcbiAgICAgICAgICAgIDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBWRVJUSUNBTF9BTElHTi5NSURETEVcbiAgICAgICAgICAgIDogREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgICAgICAgICBjb250YWluZXJJZDogY29udGFpbmVyPy5pZCA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgZ3JvdXBJZHM6IGNvbnRhaW5lcj8uZ3JvdXBJZHMgPz8gW10sXG4gICAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBjYXNlOiBjcmVhdGluZyBuZXcgdGV4dCBub3QgY2VudGVyZWQgdG8gcGFyZW50IGVsZW1lbnQg4oaSIG9mZnNldCBZXG4gICAgICAvLyBzbyB0aGF0IHRoZSB0ZXh0IGlzIGNlbnRlcmVkIHRvIGN1cnNvciBwb3NpdGlvblxuICAgICAgaWYgKCFwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICB5OiBlbGVtZW50LnkgLSBlbGVtZW50LmJhc2VsaW5lIC8gMixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlVGV4dFd5c2l3eWcoZWxlbWVudCwge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ6ICEhZXhpc3RpbmdUZXh0RWxlbWVudCxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Nb3VzZUV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gY2FzZTogZG91YmxlLWNsaWNraW5nIHdpdGggYXJyb3cvbGluZSB0b29sIHNlbGVjdGVkIHdvdWxkIGJvdGggY3JlYXRlXG4gICAgLy8gdGV4dCBhbmQgZW50ZXIgbXVsdGlFbGVtZW50IG1vZGVcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gd2Ugc2hvdWxkIG9ubHkgYmUgYWJsZSB0byBkb3VibGUgY2xpY2sgd2hlbiBtb2RlIGlzIHNlbGVjdGlvblxuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgIT09IHNlbGVjdGVkRWxlbWVudHNbMF0uaWRcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcblxuICAgIGxldCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICBldmVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkR3JvdXBJZHMgPSBnZXRTZWxlY3RlZEdyb3VwSWRzKHRoaXMuc3RhdGUpO1xuXG4gICAgaWYgKHNlbGVjdGVkR3JvdXBJZHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuXG4gICAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWQgPVxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQoaGl0RWxlbWVudCwgdGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwSWRzKTtcblxuICAgICAgaWYgKHNlbGVjdGVkR3JvdXBJZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogc2VsZWN0ZWRHcm91cElkLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2hpdEVsZW1lbnQhLmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiAhdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuICAgICAgICBjb25zdCBjYW5CaW5kVGV4dCA9IGhhc0JvdW5kVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50KTtcbiAgICAgICAgaWYgKGNhbkJpbmRUZXh0KSB7XG4gICAgICAgICAgc2NlbmVYID0gc2VsZWN0ZWRFbGVtZW50LnggKyBzZWxlY3RlZEVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgICAgIHNjZW5lWSA9IHNlbGVjdGVkRWxlbWVudC55ICsgc2VsZWN0ZWRFbGVtZW50LmhlaWdodCAvIDI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICBzaG91bGRCaW5kOiBmYWxzZSxcbiAgICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRFbGVtZW50TGlua0F0UG9zaXRpb24gPSAoXG4gICAgc2NlbmVQb2ludGVyOiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIGhpdEVsZW1lbnQ6IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwsXG4gICk6IEV4Y2FsaWRyYXdFbGVtZW50IHwgdW5kZWZpbmVkID0+IHtcbiAgICAvLyBSZXZlcnNpbmcgc28gd2UgdHJhdmVyc2UgdGhlIGVsZW1lbnRzIGluIGRlY3JlYXNpbmcgb3JkZXJcbiAgICAvLyBvZiB6LWluZGV4XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIGxldCBoaXRFbGVtZW50SW5kZXggPSBJbmZpbml0eTtcblxuICAgIHJldHVybiBlbGVtZW50cy5maW5kKChlbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGhpdEVsZW1lbnQgJiYgZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudC5pZCkge1xuICAgICAgICBoaXRFbGVtZW50SW5kZXggPSBpbmRleDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoXG4gICAgICAgIGVsZW1lbnQubGluayAmJlxuICAgICAgICBpbmRleCA8PSBoaXRFbGVtZW50SW5kZXggJiZcbiAgICAgICAgaXNQb2ludEhpdHRpbmdMaW5rSWNvbihcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgW3NjZW5lUG9pbnRlci54LCBzY2VuZVBvaW50ZXIueV0sXG4gICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWRpcmVjdFRvTGluayA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBpc1RvdWNoU2NyZWVuOiBib29sZWFuLFxuICApID0+IHtcbiAgICBjb25zdCBkcmFnZ2VkRGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFgsXG4gICAgICB0aGlzLmxhc3RQb2ludGVyRG93biEuY2xpZW50WSxcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WCxcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgICF0aGlzLmhpdExpbmtFbGVtZW50IHx8XG4gICAgICAvLyBGb3IgdG91Y2ggc2NyZWVuIGFsbG93IGRyYWdnaW5nIHRocmVzaG9sZCBlbHNlIHN0cmljdCBjaGVja1xuICAgICAgKGlzVG91Y2hTY3JlZW4gJiYgZHJhZ2dlZERpc3RhbmNlID4gRFJBR0dJTkdfVEhSRVNIT0xEKSB8fFxuICAgICAgKCFpc1RvdWNoU2NyZWVuICYmIGRyYWdnZWREaXN0YW5jZSAhPT0gMClcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGFzdFBvaW50ZXJEb3duQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IGxhc3RQb2ludGVyRG93bkhpdHRpbmdMaW5rSWNvbiA9IGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIFtsYXN0UG9pbnRlckRvd25Db29yZHMueCwgbGFzdFBvaW50ZXJEb3duQ29vcmRzLnldLFxuICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlclVwQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgdGhpcy5sYXN0UG9pbnRlclVwISxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlclVwSGl0dGluZ0xpbmtJY29uID0gaXNQb2ludEhpdHRpbmdMaW5rSWNvbihcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICAgW2xhc3RQb2ludGVyVXBDb29yZHMueCwgbGFzdFBvaW50ZXJVcENvb3Jkcy55XSxcbiAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICk7XG4gICAgaWYgKGxhc3RQb2ludGVyRG93bkhpdHRpbmdMaW5rSWNvbiAmJiBsYXN0UG9pbnRlclVwSGl0dGluZ0xpbmtJY29uKSB7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmhpdExpbmtFbGVtZW50Lmxpbms7XG4gICAgICBpZiAodXJsKSB7XG4gICAgICAgIGxldCBjdXN0b21FdmVudDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25MaW5rT3Blbikge1xuICAgICAgICAgIGN1c3RvbUV2ZW50ID0gd3JhcEV2ZW50KEVWRU5ULkVYQ0FMSURSQVdfTElOSywgZXZlbnQubmF0aXZlRXZlbnQpO1xuICAgICAgICAgIHRoaXMucHJvcHMub25MaW5rT3Blbih0aGlzLmhpdExpbmtFbGVtZW50LCBjdXN0b21FdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjdXN0b21FdmVudD8uZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGlzTG9jYWxMaW5rKHVybCkgPyBcIl9zZWxmXCIgOiBcIl9ibGFua1wiO1xuICAgICAgICAgIGNvbnN0IG5ld1dpbmRvdyA9IHdpbmRvdy5vcGVuKHVuZGVmaW5lZCwgdGFyZ2V0KTtcbiAgICAgICAgICAvLyBodHRwczovL21hdGhpYXNieW5lbnMuZ2l0aHViLmlvL3JlbC1ub29wZW5lci9cbiAgICAgICAgICBpZiAobmV3V2luZG93KSB7XG4gICAgICAgICAgICBuZXdXaW5kb3cub3BlbmVyID0gbnVsbDtcbiAgICAgICAgICAgIG5ld1dpbmRvdy5sb2NhdGlvbiA9IG5vcm1hbGl6ZUxpbmsodXJsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCB0aGlzLnN0YXRlLmN1cnNvckJ1dHRvbik7XG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuaGFzKGV2ZW50LnBvaW50ZXJJZCkpIHtcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbFNjYWxlID0gZ2VzdHVyZS5pbml0aWFsU2NhbGU7XG4gICAgaWYgKFxuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyICYmXG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgJiZcbiAgICAgIGluaXRpYWxTY2FsZSAmJlxuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2VcbiAgICApIHtcbiAgICAgIGNvbnN0IGNlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGNlbnRlci54IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLng7XG4gICAgICBjb25zdCBkZWx0YVkgPSBjZW50ZXIueSAtIGdlc3R1cmUubGFzdENlbnRlci55O1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gY2VudGVyO1xuXG4gICAgICBjb25zdCBkaXN0YW5jZSA9IGdldERpc3RhbmNlKEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSkpO1xuICAgICAgY29uc3Qgc2NhbGVGYWN0b3IgPVxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJmcmVlZHJhd1wiICYmIHRoaXMuc3RhdGUucGVuTW9kZVxuICAgICAgICAgID8gMVxuICAgICAgICAgIDogZGlzdGFuY2UgLyBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZTtcblxuICAgICAgY29uc3QgbmV4dFpvb20gPSBzY2FsZUZhY3RvclxuICAgICAgICA/IGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIHNjYWxlRmFjdG9yKVxuICAgICAgICA6IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgICAgY29uc3Qgem9vbVN0YXRlID0gZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY2VudGVyLngsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGNlbnRlci55LFxuICAgICAgICAgICAgbmV4dFpvb20sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHpvb206IHpvb21TdGF0ZS56b29tLFxuICAgICAgICAgIHNjcm9sbFg6IHpvb21TdGF0ZS5zY3JvbGxYICsgZGVsdGFYIC8gbmV4dFpvb20sXG4gICAgICAgICAgc2Nyb2xsWTogem9vbVN0YXRlLnNjcm9sbFkgKyBkZWx0YVkgLyBuZXh0Wm9vbSxcbiAgICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoaXNIb2xkaW5nU3BhY2UgfHwgaXNQYW5uaW5nIHx8IGlzRHJhZ2dpbmdTY3JvbGxCYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycyA9IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgKTtcbiAgICBjb25zdCBpc092ZXJTY3JvbGxCYXIgPSBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycy5pc092ZXJFaXRoZXI7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgeyB4OiBzY2VuZVBvaW50ZXJYLCB5OiBzY2VuZVBvaW50ZXJZIH0gPSBzY2VuZVBvaW50ZXI7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nXG4gICAgKSB7XG4gICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlck1vdmUoXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgcmVhZGluZyBmcm9tIHByZXZpb3VzIHN0YXRlIHdoaWNoIGlzIG5vdCBwb3NzaWJsZSB3aXRoXG4gICAgICAgIC8vIGF1dG9tYXRpYyBiYXRjaGluZyBpbiBSZWFjdCAxOCBoZW5jZSB1c2luZyBmbHVzaCBzeW5jIHRvIHN5bmNocm9ub3VzbHlcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBzdGF0ZS4gQ2hlY2sgaHR0cHM6Ly9naXRodWIuY29tL2V4Y2FsaWRyYXcvZXhjYWxpZHJhdy9wdWxsLzU1MDggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgZmx1c2hTeW5jKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0xpbmVhckVsZW1lbnQgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50Lmxhc3RVbmNvbW1pdHRlZFBvaW50ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3Ioc2NlbmVQb2ludGVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzQmluZGluZ0VsZW1lbnRUeXBlKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlKSkge1xuICAgICAgLy8gSG92ZXJpbmcgd2l0aCBhIHNlbGVjdGVkIHRvb2wgb3IgY3JlYXRpbmcgbmV3IGxpbmVhciBlbGVtZW50IHZpYSBjbGlja1xuICAgICAgLy8gYW5kIHBvaW50XG4gICAgICBjb25zdCB7IGRyYWdnaW5nRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXJdLFxuICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICBjb25zdCB7IHBvaW50cywgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG4gICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG5cbiAgICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RDb21taXR0ZWRQb2ludCkge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlbid0IHlldCBjcmVhdGVkIGEgdGVtcCBwb2ludCBhbmQgd2UncmUgYmV5b25kIGNvbW1pdC16b25lXG4gICAgICAgIC8vIHRocmVzaG9sZCwgYWRkIGEgcG9pbnRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgICBsYXN0UG9pbnRbMF0sXG4gICAgICAgICAgICBsYXN0UG9pbnRbMV0sXG4gICAgICAgICAgKSA+PSBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgICAgLy8gaW4gdGhpcyBicmFuY2gsIHdlJ3JlIGluc2lkZSB0aGUgY29tbWl0IHpvbmUsIGFuZCBubyB1bmNvbW1pdHRlZFxuICAgICAgICAgIC8vIHBvaW50IGV4aXN0cy4gVGh1cyBkbyBub3RoaW5nIChkb24ndCBhZGQvcmVtb3ZlIHBvaW50cykuXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHBvaW50cy5sZW5ndGggPiAyICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogcG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBbbGFzdENvbW1pdHRlZFgsIGxhc3RDb21taXR0ZWRZXSA9XG4gICAgICAgICAgbXVsdGlFbGVtZW50Py5sYXN0Q29tbWl0dGVkUG9pbnQgPz8gWzAsIDBdO1xuXG4gICAgICAgIGxldCBkeEZyb21MYXN0Q29tbWl0dGVkID0gZ3JpZFggLSByeCAtIGxhc3RDb21taXR0ZWRYO1xuICAgICAgICBsZXQgZHlGcm9tTGFzdENvbW1pdHRlZCA9IGdyaWRZIC0gcnkgLSBsYXN0Q29tbWl0dGVkWTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4RnJvbUxhc3RDb21taXR0ZWQsIGhlaWdodDogZHlGcm9tTGFzdENvbW1pdHRlZCB9ID1cbiAgICAgICAgICAgIGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZShcbiAgICAgICAgICAgICAgLy8gYWN0dWFsIGNvb3JkaW5hdGUgb2YgdGhlIGxhc3QgY29tbWl0dGVkIHBvaW50XG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRYICsgcngsXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRZICsgcnksXG4gICAgICAgICAgICAgIC8vIGN1cnNvci1ncmlkIGNvb3JkaW5hdGVcbiAgICAgICAgICAgICAgZ3JpZFgsXG4gICAgICAgICAgICAgIGdyaWRZLFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNQYXRoQUxvb3AocG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB1cGRhdGUgbGFzdCB1bmNvbW1pdHRlZCBwb2ludFxuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFggKyBkeEZyb21MYXN0Q29tbWl0dGVkLFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWSArIGR5RnJvbUxhc3RDb21taXR0ZWQsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGFzRGVzZWxlY3RlZEJ1dHRvbiA9IEJvb2xlYW4oZXZlbnQuYnV0dG9ucyk7XG4gICAgaWYgKFxuICAgICAgaGFzRGVzZWxlY3RlZEJ1dHRvbiB8fFxuICAgICAgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInRleHRcIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIilcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgaWYgKFxuICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICFpc092ZXJTY3JvbGxCYXIgJiZcbiAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50XG4gICAgKSB7XG4gICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICYmXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUpLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEgJiYgIWlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKHRyYW5zZm9ybUhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICk7XG4gICAgdGhpcy5oaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgaGl0RWxlbWVudCxcbiAgICApO1xuICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5oaXRMaW5rRWxlbWVudC5pZF1cbiAgICApIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICBzaG93SHlwZXJsaW5rVG9vbHRpcCh0aGlzLmhpdExpbmtFbGVtZW50LCB0aGlzLnN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlkZUh5cGVybGlua1Rvb2xpcCgpO1xuICAgICAgaWYgKFxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgIGhpdEVsZW1lbnQubGluayAmJlxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSAmJlxuICAgICAgICAhdGhpcy5jb250ZXh0TWVudU9wZW4gJiZcbiAgICAgICAgIXRoaXMuc3RhdGUuc2hvd0h5cGVybGlua1BvcHVwXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dIeXBlcmxpbmtQb3B1cDogXCJpbmZvXCIgfSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInRleHRcIikge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgaXNUZXh0RWxlbWVudChoaXRFbGVtZW50KSA/IENVUlNPUl9UWVBFLlRFWFQgOiBDVVJTT1JfVFlQRS5DUk9TU0hBSVIsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICB9IGVsc2UgaWYgKGlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICB0aGlzLmhhbmRsZUhvdmVyU2VsZWN0ZWRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIC8vIGlmIHVzaW5nIGNtZC9jdHJsLCB3ZSdyZSBub3QgZHJhZ2dpbmdcbiAgICAgICAgIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAgIChoaXRFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgKSkgJiZcbiAgICAgICAgIWhpdEVsZW1lbnQ/LmxvY2tlZFxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUVyYXNlciA9IChcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgc2NlbmVQb2ludGVyOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0sXG4gICkgPT4ge1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnRJZHMgPSAoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pID0+IHtcbiAgICAgIGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgaWYgKGVsZW1lbnQubG9ja2VkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWRzVG9VcGRhdGUucHVzaChlbGVtZW50LmlkKTtcbiAgICAgICAgaWYgKGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0gJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0uZXJhc2VcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0uZXJhc2UgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIXBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlbWVudC5pZF0pIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdID0ge1xuICAgICAgICAgICAgZXJhc2U6IHRydWUsXG4gICAgICAgICAgICBvcGFjaXR5OiBlbGVtZW50Lm9wYWNpdHksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGlkc1RvVXBkYXRlOiBBcnJheTxzdHJpbmc+ID0gW107XG5cbiAgICBjb25zdCBkaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55LFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IHBvaW50ID0geyAuLi5wb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMgfTtcbiAgICBsZXQgc2FtcGxpbmdJbnRlcnZhbCA9IDA7XG4gICAgd2hpbGUgKHNhbXBsaW5nSW50ZXJ2YWwgPD0gZGlzdGFuY2UpIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24ocG9pbnQueCwgcG9pbnQueSk7XG4gICAgICB1cGRhdGVFbGVtZW50SWRzKGhpdEVsZW1lbnRzKTtcblxuICAgICAgLy8gRXhpdCBzaW5jZSB3ZSByZWFjaGVkIGN1cnJlbnQgcG9pbnRcbiAgICAgIGlmIChzYW1wbGluZ0ludGVydmFsID09PSBkaXN0YW5jZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gQ2FsY3VsYXRlIG5leHQgcG9pbnQgaW4gdGhlIGxpbmUgYXQgYSBkaXN0YW5jZSBvZiBzYW1wbGluZyBpbnRlcnZhbFxuICAgICAgc2FtcGxpbmdJbnRlcnZhbCA9IE1hdGgubWluKHNhbXBsaW5nSW50ZXJ2YWwgKyB0aHJlc2hvbGQsIGRpc3RhbmNlKTtcblxuICAgICAgY29uc3QgZGlzdGFuY2VSYXRpbyA9IHNhbXBsaW5nSW50ZXJ2YWwgLyBkaXN0YW5jZTtcbiAgICAgIGNvbnN0IG5leHRYID1cbiAgICAgICAgKDEgLSBkaXN0YW5jZVJhdGlvKSAqIHBvaW50LnggKyBkaXN0YW5jZVJhdGlvICogc2NlbmVQb2ludGVyLng7XG4gICAgICBjb25zdCBuZXh0WSA9XG4gICAgICAgICgxIC0gZGlzdGFuY2VSYXRpbykgKiBwb2ludC55ICsgZGlzdGFuY2VSYXRpbyAqIHNjZW5lUG9pbnRlci55O1xuICAgICAgcG9pbnQueCA9IG5leHRYO1xuICAgICAgcG9pbnQueSA9IG5leHRZO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZSkgPT4ge1xuICAgICAgY29uc3QgaWQgPVxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJiBpZHNUb1VwZGF0ZS5pbmNsdWRlcyhlbGUuY29udGFpbmVySWQpXG4gICAgICAgICAgPyBlbGUuY29udGFpbmVySWRcbiAgICAgICAgICA6IGVsZS5pZDtcbiAgICAgIGlmIChpZHNUb1VwZGF0ZS5pbmNsdWRlcyhpZCkpIHtcbiAgICAgICAgaWYgKGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXS5lcmFzZSA9PT0gZmFsc2VcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICAgICAgb3BhY2l0eTogcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0ub3BhY2l0eSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgICBvcGFjaXR5OiBFTEVNRU5UX1JFQURZX1RPX0VSQVNFX09QQUNJVFksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG5cbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHNjZW5lUG9pbnRlci54O1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gc2NlbmVQb2ludGVyLnk7XG4gIH07XG4gIC8vIHNldCB0b3VjaCBtb3ZpbmcgZm9yIG1vYmlsZSBjb250ZXh0IG1lbnVcbiAgcHJpdmF0ZSBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQ6IFJlYWN0LlRvdWNoRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+KSA9PiB7XG4gICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgfTtcblxuICBoYW5kbGVIb3ZlclNlbGVjdGVkTGluZWFyRWxlbWVudChcbiAgICBsaW5lYXJFbGVtZW50RWRpdG9yOiBMaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgIHNjZW5lUG9pbnRlclg6IG51bWJlcixcbiAgICBzY2VuZVBvaW50ZXJZOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldEVsZW1lbnQoXG4gICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLmVsZW1lbnRJZCxcbiAgICApO1xuXG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgbGV0IGhvdmVyUG9pbnRJbmRleCA9IC0xO1xuICAgICAgbGV0IG1pZFBvaW50SG92ZXJlZCA9IGZhbHNlO1xuICAgICAgaWYgKFxuICAgICAgICBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveChlbGVtZW50LCB0aGlzLnN0YXRlLCBbXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICBdKVxuICAgICAgKSB7XG4gICAgICAgIGhvdmVyUG9pbnRJbmRleCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRJbmRleFVuZGVyQ3Vyc29yKFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgKTtcbiAgICAgICAgbWlkUG9pbnRIb3ZlcmVkID0gTGluZWFyRWxlbWVudEVkaXRvci5pc0hpdHRpbmdNaWRQb2ludChcbiAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgIHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGhvdmVyUG9pbnRJbmRleCA+PSAwIHx8IG1pZFBvaW50SG92ZXJlZCkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgc2hvdWxkU2hvd0JvdW5kaW5nQm94KFtlbGVtZW50XSwgdGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LmhvdmVyUG9pbnRJbmRleCAhPT0gaG92ZXJQb2ludEluZGV4XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIGhvdmVyUG9pbnRJbmRleCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5taWRQb2ludEhvdmVyZWQgIT09IG1pZFBvaW50SG92ZXJlZFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBtaWRQb2ludEhvdmVyZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIHJlbW92ZSBhbnkgYWN0aXZlIHNlbGVjdGlvbiB3aGVuIHdlIHN0YXJ0IHRvIGludGVyYWN0IHdpdGggY2FudmFzXG4gICAgLy8gKG1haW5seSwgd2UgY2FyZSBhYm91dCByZW1vdmluZyBzZWxlY3Rpb24gb3V0c2lkZSB0aGUgY29tcG9uZW50IHdoaWNoXG4gICAgLy8gIHdvdWxkIHByZXZlbnQgb3VyIGNvcHkgaGFuZGxpbmcgb3RoZXJ3aXNlKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24/LmFuY2hvck5vZGUpIHtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICB9XG4gICAgdGhpcy5tYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyhldmVudCk7XG4gICAgdGhpcy5tYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoZXZlbnQpO1xuXG4gICAgLy9maXJlcyBvbmx5IG9uY2UsIGlmIHBlbiBpcyBkZXRlY3RlZCwgcGVuTW9kZSBpcyBlbmFibGVkXG4gICAgLy90aGUgdXNlciBjYW4gZGlzYWJsZSB0aGlzIGJ5IHRvZ2dsaW5nIHRoZSBwZW5Nb2RlIGJ1dHRvblxuICAgIGlmICghdGhpcy5zdGF0ZS5wZW5EZXRlY3RlZCAmJiBldmVudC5wb2ludGVyVHlwZSA9PT0gXCJwZW5cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGVuTW9kZTogdHJ1ZSxcbiAgICAgICAgICBwZW5EZXRlY3RlZDogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICF0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuICYmXG4gICAgICBbXCJwZW5cIiwgXCJ0b3VjaFwiXS5pbmNsdWRlcyhldmVudC5wb2ludGVyVHlwZSlcbiAgICApIHtcbiAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7IGlzVG91Y2hTY3JlZW46IHRydWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubGFzdFBvaW50ZXJEb3duID0gZXZlbnQ7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBsYXN0UG9pbnRlckRvd25XaXRoOiBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgIGN1cnNvckJ1dHRvbjogXCJkb3duXCIsXG4gICAgfSk7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcImRvd25cIik7XG5cbiAgICB0aGlzLnVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyhldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBsZWZ0IG1vdXNlIGJ1dHRvbiBvciB0b3VjaFxuICAgIGlmIChcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJlxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5UT1VDSFxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRvbid0IHNlbGVjdCB3aGlsZSBwYW5uaW5nXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGF0ZSBmb3IgdGhlIGR1cmF0aW9uIG9mIGEgcG9pbnRlciBpbnRlcmFjdGlvbiwgd2hpY2ggc3RhcnRzIHdpdGggYVxuICAgIC8vIHBvaW50ZXJEb3duIGV2ZW50LCBlbmRzIHdpdGggYSBwb2ludGVyVXAgZXZlbnQgKG9yIGFub3RoZXIgcG9pbnRlckRvd24pXG4gICAgY29uc3QgcG9pbnRlckRvd25TdGF0ZSA9IHRoaXMuaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2luY2UgY29udGV4dCBtZW51IGNsb3NlcyBvbiBwb2ludGVyIGRvd24gc28gc2V0dGluZyB0byBmYWxzZVxuICAgIHRoaXMuY29udGV4dE1lbnVPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFsbG93T25Qb2ludGVyRG93biA9XG4gICAgICAhdGhpcy5zdGF0ZS5wZW5Nb2RlIHx8XG4gICAgICBldmVudC5wb2ludGVyVHlwZSAhPT0gXCJ0b3VjaFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiIHx8XG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiO1xuXG4gICAgaWYgKCFhbGxvd09uUG9pbnRlckRvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICB0aGlzLmhhbmRsZVRleHRPblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwibGluZVwiXG4gICAgKSB7XG4gICAgICB0aGlzLmhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgLy8gcmVzZXQgaW1hZ2UgcHJldmlldyBvbiBwb2ludGVyZG93blxuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5DUk9TU0hBSVIpO1xuXG4gICAgICAvLyByZXRyaWV2ZSB0aGUgbGF0ZXN0IGVsZW1lbnQgYXMgdGhlIHN0YXRlIG1heSBiZSBzdGFsZVxuICAgICAgY29uc3QgcGVuZGluZ0ltYWdlRWxlbWVudCA9XG4gICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICYmXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudCh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCk7XG5cbiAgICAgIGlmICghcGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IHBlbmRpbmdJbWFnZUVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBwZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwsXG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgICBtdXRhdGVFbGVtZW50KHBlbmRpbmdJbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgdGhpcy5oYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiY3VzdG9tXCIpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIikge1xuICAgICAgdGhpcy5jcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb3BzPy5vblBvaW50ZXJEb3duPy4odGhpcy5zdGF0ZS5hY3RpdmVUb29sLCBwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPVxuICAgICAgdGhpcy5vblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID1cbiAgICAgIHRoaXMub25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25LZXlEb3duID0gdGhpcy5vbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIGNvbnN0IG9uS2V5VXAgPSB0aGlzLm9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIG9uS2V5RG93bik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgb25LZXlVcCk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSA9IG9uUG9pbnRlck1vdmU7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAgPSBvblBvaW50ZXJVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCA9IG9uS2V5VXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biA9IG9uS2V5RG93bjtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyVXAgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMubGFzdFBvaW50ZXJVcCA9IGV2ZW50O1xuICAgIGlmICh0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuKSB7XG4gICAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WDogZXZlbnQuY2xpZW50WCwgY2xpZW50WTogZXZlbnQuY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICApO1xuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5oaXRMaW5rRWxlbWVudC5pZF1cbiAgICApIHtcbiAgICAgIHRoaXMucmVkaXJlY3RUb0xpbmsoZXZlbnQsIHRoaXMuZGV2aWNlLmlzVG91Y2hTY3JlZW4pO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihldmVudCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCA9PiB7XG4gICAgLy8gZGVhbCB3aXRoIG9wZW5pbmcgY29udGV4dCBtZW51IG9uIHRvdWNoIGRldmljZXNcbiAgICBpZiAoZXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIikge1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbiAgICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBhbHJlYWR5IGEgdG91Y2hUaW1lb3V0LCB0aGlzIG1lYW5zIHRoYXQgdGhlcmUncyBhbm90aGVyXG4gICAgICAgIC8vIHRvdWNoIGRvd24gYW5kIHdlIGFyZSBkb2luZyBhbm90aGVyIHRvdWNoLCBzbyB3ZSBzaG91bGRuJ3Qgb3BlbiB0aGVcbiAgICAgICAgLy8gY29udGV4dCBtZW51LlxuICAgICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb3BlbiB0aGUgY29udGV4dCBtZW51IHdpdGggdGhlIGZpcnN0IHRvdWNoJ3MgY2xpZW50WCBhbmQgY2xpZW50WVxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggaXMgbm90IG1vdmluZ1xuICAgICAgICB0b3VjaFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICAgICAgICBpZiAoIWludmFsaWRhdGVDb250ZXh0TWVudSkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudShldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBUT1VDSF9DVFhfTUVOVV9USU1FT1VUKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldENvbnRleHRNZW51VGltZXIgPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgaWYgKGxhc3RQb2ludGVyVXAgIT09IG51bGwpIHtcbiAgICAgIC8vIFVuZm9ydHVuYXRlbHksIHNvbWV0aW1lcyB3ZSBkb24ndCBnZXQgYSBwb2ludGVydXAgYWZ0ZXIgYSBwb2ludGVyZG93bixcbiAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29udGV4dHVhbCBtZW51IG9yIGFsZXJ0IGlzIHRyaWdnZXJlZC4gSW4gb3JkZXIgdG8gYXZvaWRcbiAgICAgIC8vIGJlaW5nIGluIGEgd2VpcmQgc3RhdGUsIHdlIGNsZWFuIHVwIG9uIHRoZSBuZXh0IHBvaW50ZXJkb3duXG4gICAgICBsYXN0UG9pbnRlclVwKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgcGFubmluZ1xuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKFxuICAgICAgIShcbiAgICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplIDw9IDEgJiZcbiAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uV0hFRUwgfHxcbiAgICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmIGlzSG9sZGluZ1NwYWNlKSB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKVxuICAgICAgKSB8fFxuICAgICAgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBsZXQgbmV4dFBhc3RlUHJldmVudGVkID0gZmFsc2U7XG4gICAgY29uc3QgaXNMaW51eCA9IC9MaW51eC8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtKTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgIGxldCB7IGNsaWVudFg6IGxhc3RYLCBjbGllbnRZOiBsYXN0WSB9ID0gZXZlbnQ7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgZGVsdGFYID0gbGFzdFggLSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZGVsdGFZID0gbGFzdFkgLSBldmVudC5jbGllbnRZO1xuICAgICAgbGFzdFggPSBldmVudC5jbGllbnRYO1xuICAgICAgbGFzdFkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgICAvKlxuICAgICAgICogUHJldmVudCBwYXN0ZSBldmVudCBpZiB3ZSBtb3ZlIHdoaWxlIG1pZGRsZSBjbGlja2luZyBvbiBMaW51eC5cbiAgICAgICAqIFNlZSBpc3N1ZSAjMTM4My5cbiAgICAgICAqL1xuICAgICAgaWYgKFxuICAgICAgICBpc0xpbnV4ICYmXG4gICAgICAgICFuZXh0UGFzdGVQcmV2ZW50ZWQgJiZcbiAgICAgICAgKE1hdGguYWJzKGRlbHRhWCkgPiAxIHx8IE1hdGguYWJzKGRlbHRhWSkgPiAxKVxuICAgICAgKSB7XG4gICAgICAgIG5leHRQYXN0ZVByZXZlbnRlZCA9IHRydWU7XG5cbiAgICAgICAgLyogUHJldmVudCB0aGUgbmV4dCBwYXN0ZSBldmVudCAqL1xuICAgICAgICBjb25zdCBwcmV2ZW50TmV4dFBhc3RlID0gKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLypcbiAgICAgICAgICogUmVlbmFibGUgbmV4dCBwYXN0ZSBpbiBjYXNlIG9mIGRpc2FibGVkIG1pZGRsZSBjbGljayBwYXN0ZSBmb3JcbiAgICAgICAgICogYW55IHJlYXNvbjpcbiAgICAgICAgICogLSByaWdodCBjbGljayBwYXN0ZVxuICAgICAgICAgKiAtIGVtcHR5IGNsaXBib2FyZFxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZW5hYmxlTmV4dFBhc3RlID0gKCkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZGVsdGFYIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFkgLSBkZWx0YVkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBjb25zdCB0ZWFyZG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAgIChsYXN0UG9pbnRlclVwID0gKCkgPT4ge1xuICAgICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgICAgaXNQYW5uaW5nID0gZmFsc2U7XG4gICAgICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgICAgICBvblBvaW50ZXJNb3ZlLmZsdXNoKCk7XG4gICAgICB9KSxcbiAgICApO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUsIHtcbiAgICAgIHBhc3NpdmU6IHRydWUsXG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGVhcmRvd24pO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQge1xuICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgIHk6IGV2ZW50LmNsaWVudFksXG4gICAgfSk7XG5cbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyKSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID0gZ2V0RGlzdGFuY2UoXG4gICAgICAgIEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IFBvaW50ZXJEb3duU3RhdGUge1xuICAgIGNvbnN0IG9yaWdpbiA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBvcmlnaW4sXG4gICAgICB3aXRoQ21kT3JDdHJsOiBldmVudFtLRVlTLkNUUkxfT1JfQ01EXSxcbiAgICAgIG9yaWdpbkluR3JpZDogdHVwbGVUb0Nvb3JzKFxuICAgICAgICBnZXRHcmlkUG9pbnQob3JpZ2luLngsIG9yaWdpbi55LCB0aGlzLnN0YXRlLmdyaWRTaXplKSxcbiAgICAgICksXG4gICAgICBzY3JvbGxiYXJzOiBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgICAgZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgKSxcbiAgICAgIC8vIHdlIG5lZWQgdG8gZHVwbGljYXRlIGJlY2F1c2Ugd2UnbGwgYmUgdXBkYXRpbmcgdGhpcyBzdGF0ZVxuICAgICAgbGFzdENvb3JkczogeyAuLi5vcmlnaW4gfSxcbiAgICAgIG9yaWdpbmFsRWxlbWVudHM6IHRoaXMuc2NlbmVcbiAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgIC5yZWR1Y2UoKGFjYywgZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGFjYy5zZXQoZWxlbWVudC5pZCwgZGVlcENvcHlFbGVtZW50KGVsZW1lbnQpKTtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCBuZXcgTWFwKCkgYXMgUG9pbnRlckRvd25TdGF0ZVtcIm9yaWdpbmFsRWxlbWVudHNcIl0pLFxuICAgICAgcmVzaXplOiB7XG4gICAgICAgIGhhbmRsZVR5cGU6IGZhbHNlLFxuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgYXJyb3dEaXJlY3Rpb246IFwib3JpZ2luXCIsXG4gICAgICAgIGNlbnRlcjogeyB4OiAobWF4WCArIG1pblgpIC8gMiwgeTogKG1heFkgKyBtaW5ZKSAvIDIgfSxcbiAgICAgIH0sXG4gICAgICBoaXQ6IHtcbiAgICAgICAgZWxlbWVudDogbnVsbCxcbiAgICAgICAgYWxsSGl0RWxlbWVudHM6IFtdLFxuICAgICAgICB3YXNBZGRlZFRvU2VsZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgaGFzQmVlbkR1cGxpY2F0ZWQ6IGZhbHNlLFxuICAgICAgICBoYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50czpcbiAgICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICApLFxuICAgICAgfSxcbiAgICAgIGRyYWc6IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgICBvZmZzZXQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZXZlbnRMaXN0ZW5lcnM6IHtcbiAgICAgICAgb25Nb3ZlOiBudWxsLFxuICAgICAgICBvblVwOiBudWxsLFxuICAgICAgICBvbktleVVwOiBudWxsLFxuICAgICAgICBvbktleURvd246IG51bGwsXG4gICAgICB9LFxuICAgICAgYm94U2VsZWN0aW9uOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBlbGVtZW50SWRzVG9FcmFzZToge30sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBkcmFnZ2luZyBhIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChcbiAgICAgICEocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlckVpdGhlciAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSB0cnVlO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gZXZlbnQuY2xpZW50WDtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IGV2ZW50LmNsaWVudFk7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlc1Rocm90dGxlZCgoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICAgIGlzRHJhZ2dpbmdTY3JvbGxCYXIgPSBmYWxzZTtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgICAgb25Qb2ludGVyTW92ZS5mbHVzaCgpO1xuICAgIH0pO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uSWZOb3RVc2luZ1NlbGVjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgZXZlbnQgaGFzIGJlZW4gY29tcGxldGVseSBoYW5kbGVkXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbk9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID1cbiAgICAgICAgICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUoXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgcmVzaXppbmdFbGVtZW50OiBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUuZWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID1cbiAgICAgICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS50cmFuc2Zvcm1IYW5kbGVUeXBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGU6IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcgPSB0cnVlO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0UmVzaXplT2Zmc2V0WFkoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgIGlzTGluZWFyRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKSAmJlxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0ucG9pbnRzLmxlbmd0aCA9PT0gMlxuICAgICAgICApIHtcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbiA9IGdldFJlc2l6ZUFycm93RGlyZWN0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50O1xuICAgICAgICAgIGNvbnN0IHJldCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlckRvd24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocmV0LmhpdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPSByZXQuaGl0RWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5saW5lYXJFbGVtZW50RWRpdG9yKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiByZXQubGluZWFyRWxlbWVudEVkaXRvciB9KTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50OiByZXQubGluZWFyRWxlbWVudEVkaXRvciB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5kaWRBZGRQb2ludCAmJiAhcmV0LmlzTWlkUG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoaXRFbGVtZW50IG1heSBhbHJlYWR5IGJlIHNldCBhYm92ZSwgc28gY2hlY2sgZmlyc3RcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA/P1xuICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApO1xuXG4gICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgLy8gRWFybHkgcmV0dXJuIGlmIHBvaW50ZXIgaXMgaGl0dGluZyBsaW5rIGljb25cbiAgICAgICAgICBjb25zdCBoaXRMaW5rRWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB4OiBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgICB5OiBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoaGl0TGlua0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igb3ZlcmxhcHBlZCBlbGVtZW50cyBvbmUgcG9zaXRpb24gbWF5IGhpdFxuICAgICAgICAvLyBtdWx0aXBsZSBlbGVtZW50c1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgY29uc3Qgc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PlxuICAgICAgICAgICAgdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChoaXRFbGVtZW50ID09PSBudWxsIHx8ICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQpICYmXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIElmIHdlIGNsaWNrIG9uIHNvbWV0aGluZ1xuICAgICAgICB9IGVsc2UgaWYgKGhpdEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgIC8vIG9uIENNRC9DVFJMLCBkcmlsbCBkb3duIHRvIGhpdCBlbGVtZW50IHJlZ2FyZGxlc3Mgb2YgZ3JvdXBzIGV0Yy5cbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIC4uLmVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudChwcmV2U3RhdGUsIGhpdEVsZW1lbnQpLFxuICAgICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAvLyBtYXJrIGFzIG5vdCBjb21wbGV0ZWx5IGhhbmRsZWQgc28gYXMgdG8gYWxsb3cgZHJhZ2dpbmcgZXRjLlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlc2VsZWN0IGlmIGl0ZW0gaXMgc2VsZWN0ZWRcbiAgICAgICAgICAvLyBpZiBzaGlmdCBpcyBub3QgY2xpY2tlZCwgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgaXQgd2lsbCB0cmlnZ2VyIHNlbGVjdGlvbiBiYXNlZCBvbiBjdXJyZW50XG4gICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGJveFxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBjdXJyZW50bHkgZWRpdGluZyBhIGdyb3VwLCBleGl0aW5nIGVkaXRpbmcgbW9kZSBhbmQgZGVzZWxlY3QgdGhlIGdyb3VwLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgICAgICAgICFpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBoaXQgZWxlbWVudCB0byBzZWxlY3Rpb24uIEF0IHRoaXMgcG9pbnQgaWYgd2UncmUgbm90IGhvbGRpbmdcbiAgICAgICAgICAgIC8vIFNISUZUIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQocykgd2VyZSBkZXNlbGVjdGVkIGFib3ZlXG4gICAgICAgICAgICAvLyAobWFrZSBzdXJlIHlvdSB1c2Ugc2V0U3RhdGUgdXBkYXRlciB0byB1c2UgbGF0ZXN0IHN0YXRlKVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkICYmXG4gICAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6IGhpdEVsZW1lbnQubGluayA/IFwiaW5mb1wiIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgaXNBU2VsZWN0ZWRFbGVtZW50KGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBoaXRFbGVtZW50ICE9IG51bGwgJiYgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF07XG4gIH1cblxuICBwcml2YXRlIGlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgIHBvaW50OiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIb3cgbWFueSBwaXhlbHMgb2ZmIHRoZSBzaGFwZSBib3VuZGFyeSB3ZSBzdGlsbCBjb25zaWRlciBhIGhpdFxuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvaW50LnggPiB4MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueCA8IHgyICsgdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55ID4geTEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPCB5MiArIHRocmVzaG9sZFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRleHRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGlmIHdlJ3JlIGN1cnJlbnRseSBzdGlsbCBlZGl0aW5nIHRleHQsIGNsaWNraW5nIG91dHNpZGVcbiAgICAvLyBzaG91bGQgb25seSBmaW5hbGl6ZSBpdCwgbm90IGNyZWF0ZSBhbm90aGVyIChpcnJlc3BlY3RpdmVcbiAgICAvLyBvZiBzdGF0ZS5hY3RpdmVUb29sLmxvY2tlZClcbiAgICBpZiAoaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgc2NlbmVYID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueDtcbiAgICBsZXQgc2NlbmVZID0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZLCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChlbGVtZW50KTtcbiAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgIHNjZW5lWCA9IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgc2NlbmVYLFxuICAgICAgc2NlbmVZLFxuICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICB9KTtcblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIXRoaXMuc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHsgdHlwZTogXCJzZWxlY3Rpb25cIiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkgPT4ge1xuICAgIC8vIEJlZ2luIGEgbWFyayBjYXB0dXJlLiBUaGlzIGRvZXMgbm90IGhhdmUgdG8gdXBkYXRlIHN0YXRlIHlldC5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgbnVsbCxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ZyZWVEcmF3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHNpbXVsYXRlUHJlc3N1cmU6IGV2ZW50LnByZXNzdXJlID09PSAwLjUsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHByZXNzdXJlcyA9IGVsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgPyBlbGVtZW50LnByZXNzdXJlc1xuICAgICAgOiBbLi4uZWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgcG9pbnRzOiBbWzAsIDBdXSxcbiAgICAgIHByZXNzdXJlcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VFbGVtZW50ID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICB9OiB7XG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgc2NlbmVZOiBudW1iZXI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChzY2VuZVgsIHNjZW5lWSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3SW1hZ2VFbGVtZW50KHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUxpbmVhckVsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3TGluZWFyRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgLy8gZmluYWxpemUgaWYgY29tcGxldGluZyBhIGxvb3BcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnR5cGUgPT09IFwibGluZVwiICYmXG4gICAgICAgIGlzUGF0aEFMb29wKG11bHRpRWxlbWVudC5wb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDpcbiAgICAgICAgICAgIG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSwgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIC8vIGNsaWNraW5nIGluc2lkZSBjb21taXQgem9uZSDihpIgZmluYWxpemUgYXJyb3dcbiAgICAgIGlmIChcbiAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggPiAxICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSByeCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFttdWx0aUVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgLy8gY2xpY2tpbmcgb3V0c2lkZSBjb21taXQgem9uZSDihpIgdXBkYXRlIHJlZmVyZW5jZSBmb3IgbGFzdCBjb21taXR0ZWRcbiAgICAgIC8vIHBvaW50XG4gICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IG11bHRpRWxlbWVudC5wb2ludHNbbXVsdGlFbGVtZW50LnBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIH0pO1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvKiBJZiBhcnJvdyBpcyBwcmUtYXJyb3doZWFkcywgaXQgd2lsbCBoYXZlIHVuZGVmaW5lZCBmb3IgYm90aCBzdGFydCBhbmQgZW5kIGFycm93aGVhZHMuXG4gICAgICBJZiBzbywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBzdGFydCBhbmQgXCJhcnJvd1wiIGZvciBlbmQuIElmIHRoZSBsaW5lYXIgaXRlbSBpcyBub3RcbiAgICAgIGFuIGFycm93LCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIGJvdGguIE90aGVyd2lzZSwgd2Ugd2FudCBpdCB0byB1c2UgdGhlXG4gICAgICB2YWx1ZXMgZnJvbSBhcHBTdGF0ZS4gKi9cblxuICAgICAgY29uc3QgeyBjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IFtzdGFydEFycm93aGVhZCwgZW5kQXJyb3doZWFkXSA9XG4gICAgICAgIGVsZW1lbnRUeXBlID09PSBcImFycm93XCJcbiAgICAgICAgICA/IFtjdXJyZW50SXRlbVN0YXJ0QXJyb3doZWFkLCBjdXJyZW50SXRlbUVuZEFycm93aGVhZF1cbiAgICAgICAgICA6IFtudWxsLCBudWxsXTtcblxuICAgICAgY29uc3QgZWxlbWVudCA9IG5ld0xpbmVhckVsZW1lbnQoe1xuICAgICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgICAgeDogZ3JpZFgsXG4gICAgICAgIHk6IGdyaWRZLFxuICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtTGluZWFyU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgICBzdGFydEFycm93aGVhZCxcbiAgICAgICAgZW5kQXJyb3doZWFkLFxuICAgICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgW2VsZW1lbnQuaWRdOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICBwb2ludHM6IFsuLi5lbGVtZW50LnBvaW50cywgWzAsIDBdXSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYm91bmRFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICk7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBjcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudFtcInR5cGVcIl0sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgKTtcbiAgICBjb25zdCBlbGVtZW50ID0gbmV3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBpZiAoZWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBQcmV2ZW50cyBmb2N1cyBmcm9tIGVzY2FwaW5nIGV4Y2FsaWRyYXcgdGFiXG4gICAgICBldmVudC5rZXkgPT09IEtFWVMuQUxUICYmIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gaW5pdGlhbGl6ZSBkcmFnT2Zmc2V0WFkgb25seSBhZnRlciB3ZSd2ZSB1cGRhdGVkXG4gICAgICAvLyBgc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzYCBvbiBwb2ludGVyRG93bi4gRG9pbmcgaXQgaGVyZSBpbiBwb2ludGVyTW92ZVxuICAgICAgLy8gZXZlbnQgaGFuZGxlciBzaG91bGQgaG9wZWZ1bGx5IGVuc3VyZSB3ZSdyZSBhbHJlYWR5IHdvcmtpbmcgd2l0aFxuICAgICAgLy8gdGhlIHVwZGF0ZWQgc3RhdGUuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9PT0gbnVsbCkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldERyYWdPZmZzZXRYWShcbiAgICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcblxuICAgICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlRXJhc2VyKGV2ZW50LCBwb2ludGVyRG93blN0YXRlLCBwb2ludGVyQ29vcmRzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICAvLyBmb3IgYXJyb3dzL2xpbmVzLCBkb24ndCBzdGFydCBkcmFnZ2luZyB1bnRpbCBhIGdpdmVuIHRocmVzaG9sZFxuICAgICAgLy8gdG8gZW5zdXJlIHdlIGRvbid0IGNyZWF0ZSBhIDItcG9pbnQgYXJyb3cgYnkgbWlzdGFrZSB3aGVuXG4gICAgICAvLyB1c2VyIGNsaWNrcyBtb3VzZSBpbiBhIHdheSB0aGF0IGl0IG1vdmVzIGEgdGlueSBiaXQgKHRodXNcbiAgICAgIC8vIHRyaWdnZXJpbmcgcG9pbnRlcm1vdmUpXG5cbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImxpbmVcIilcbiAgICAgICkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkgPCBEUkFHR0lOR19USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZykge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID1cbiAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50O1xuICAgICAgICBjb25zdCBkaWREcmFnID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludERyYWdnaW5nKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAoZWxlbWVudCwgcG9pbnRzU2NlbmVDb29yZHMpID0+IHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHBvaW50c1NjZW5lQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChkaWREcmFnKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgaGFzSGl0QVNlbGVjdGVkRWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmFsbEhpdEVsZW1lbnRzLnNvbWUoXG4gICAgICAgIChlbGVtZW50KSA9PiB0aGlzLmlzQVNlbGVjdGVkRWxlbWVudChlbGVtZW50KSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGlzU2VsZWN0aW5nUG9pbnRzSW5MaW5lRWRpdG9yID1cbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICBldmVudC5zaGlmdEtleSAmJlxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCA9PT1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50Py5pZDtcbiAgICAgIGlmIChcbiAgICAgICAgKGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgfHxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cykgJiZcbiAgICAgICAgIWlzU2VsZWN0aW5nUG9pbnRzSW5MaW5lRWRpdG9yXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5ldmVyeSgoZWxlbWVudCkgPT4gZWxlbWVudC5sb2NrZWQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIE1hcmtpbmcgdGhhdCBjbGljayB3YXMgdXNlZCBmb3IgZHJhZ2dpbmcgdG8gY2hlY2tcbiAgICAgICAgLy8gaWYgZWxlbWVudHMgc2hvdWxkIGJlIGRlc2VsZWN0ZWQgb24gcG9pbnRlcnVwXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIC8vIHByZXZlbnQgZHJhZ2dpbmcgZXZlbiBpZiB3ZSdyZSBubyBsb25nZXIgaG9sZGluZyBjbWQvY3RybCBvdGhlcndpc2VcbiAgICAgICAgLy8gaXQgd291bGQgaGF2ZSB3ZWlyZCByZXN1bHRzIChzdHVmZiBqdW1waW5nIGFsbCBvdmVyIHRoZSBzY3JlZW4pXG4gICAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDAgJiYgIXBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCkge1xuICAgICAgICAgIGNvbnN0IFtkcmFnWCwgZHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgW2RyYWdEaXN0YW5jZVgsIGRyYWdEaXN0YW5jZVldID0gW1xuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy54IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCksXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55KSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgLy8gV2Ugb25seSBkcmFnIGluIG9uZSBkaXJlY3Rpb24gaWYgc2hpZnQgaXMgcHJlc3NlZFxuICAgICAgICAgIGNvbnN0IGxvY2tEaXJlY3Rpb24gPSBldmVudC5zaGlmdEtleTtcbiAgICAgICAgICBkcmFnU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ1gsXG4gICAgICAgICAgICBkcmFnWSxcbiAgICAgICAgICAgIGxvY2tEaXJlY3Rpb24sXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VYLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgICAvLyBXZSBkdXBsaWNhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQgaWYgYWx0IGlzIHByZXNzZWQgb24gcG9pbnRlciBtb3ZlXG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQpIHtcbiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBlbGVtZW50cyB0byB0aGUgdG9wIG9mIHRoZSB6IGluZGV4IHN0YWNrLCBhbmRcbiAgICAgICAgICAgIC8vIHB1dCB0aGUgZHVwbGljYXRlcyB3aGVyZSB0aGUgc2VsZWN0ZWQgZWxlbWVudHMgdXNlZCB0byBiZS5cbiAgICAgICAgICAgIC8vICh0aGUgb3JpZ2luIHBvaW50IHdoZXJlIHRoZSBkcmFnZ2luZyBzdGFydGVkKVxuXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHNUb0FwcGVuZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudElkczogQXJyYXk8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXT4gPVxuICAgICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlLCB0cnVlKS5tYXAoXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQpID0+IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzLmluY2x1ZGVzKGVsZW1lbnQuaWQpIHx8XG4gICAgICAgICAgICAgICAgLy8gY2FzZTogdGhlIHN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyBtaWdodCBub3QgaGF2ZSBiZWVuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlZCB5ZXQgYnkgdGhlIHRpbWUgdGhpcyBtb3VzZW1vdmUgZXZlbnQgaXMgZmlyZWRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24pXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZWRFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgICAgICAgICAgICBncm91cElkTWFwLFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvcmlnaW5EcmFnWCwgb3JpZ2luRHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChkdXBsaWNhdGVkRWxlbWVudCwge1xuICAgICAgICAgICAgICAgICAgeDogZHVwbGljYXRlZEVsZW1lbnQueCArIChvcmlnaW5EcmFnWCAtIGRyYWdYKSxcbiAgICAgICAgICAgICAgICAgIHk6IGR1cGxpY2F0ZWRFbGVtZW50LnkgKyAob3JpZ2luRHJhZ1kgLSBkcmFnWSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZHVwbGljYXRlZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBkdXBsaWNhdGVkRWxlbWVudC5pZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5leHRTY2VuZUVsZW1lbnRzID0gWy4uLm5leHRFbGVtZW50cywgLi4uZWxlbWVudHNUb0FwcGVuZF07XG4gICAgICAgICAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0RWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICAgXCJkdXBsaWNhdGVzU2VydmVBc09sZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRTY2VuZUVsZW1lbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIHJlYWQgdGhpcy5zdGF0ZSB3aXRoaW4gZWFjaCBtb3ZlIGV2ZW50LFxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIHdvdWxkIHJlYWQgYSBzdGFsZSBvbmUhXG4gICAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgY29uc3QgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgY29uc3QgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHMubGVuZ3RoID4gMCAmJiBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCBkaXNjYXJkUG9pbnQgPVxuICAgICAgICAgIGxhc3RQb2ludCAmJiBsYXN0UG9pbnRbMF0gPT09IGR4ICYmIGxhc3RQb2ludFsxXSA9PT0gZHk7XG5cbiAgICAgICAgaWYgKCFkaXNjYXJkUG9pbnQpIHtcbiAgICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgICAgPyBkcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzXG4gICAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gZ3JpZFggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gZ3JpZFkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpICYmIHBvaW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHgsIGhlaWdodDogZHkgfSA9IGdldExvY2tlZExpbmVhckN1cnNvckFsaWduU2l6ZShcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudC54LFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cy5zbGljZSgwLCAtMSksIFtkeCwgZHldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpKSB7XG4gICAgICAgICAgLy8gV2hlbiBjcmVhdGluZyBhIGxpbmVhciBlbGVtZW50IGJ5IGRyYWdnaW5nXG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIFtwb2ludGVyQ29vcmRzXSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgICAvLyBhbGxvd3MgZm9yIGJveC1zZWxlY3RpbmcgcG9pbnRzICh3aXRob3V0IHNoaWZ0KVxuICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKGVsZW1lbnRzLCB0aGlzLnN0YXRlKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsICYmIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBib3gtc2VsZWN0IGxpbmUgZWRpdG9yIHBvaW50c1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlQm94U2VsZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gcmVndWxhciBib3gtc2VsZWN0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24gPSBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbihcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5lbGVtZW50c1dpdGhpblNlbGVjdGlvbi5yZWR1Y2UoXG4gICAgICAgICAgICAgICAgICAgIChhY2M6IFJlY29yZDxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdLCB0cnVlPiwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGFjY1tlbGVtZW50LmlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgLi4uKHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB1c2luZyBjdHJsL2NtZCwgc2VsZWN0IHRoZSBoaXRFbGVtZW50IG9ubHkgaWYgd2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LmlkXTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIWVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaG93SHlwZXJsaW5rUG9wdXA6XG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdLmxpbmtcbiAgICAgICAgICAgICAgICAgICAgPyBcImluZm9cIlxuICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIC8vIHNlbGVjdCBsaW5lYXIgZWxlbWVudCBvbmx5IHdoZW4gd2UgaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgbW92ZSBoYXBwZW5lZCBvdmVyIGVpdGhlciBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJIb3Jpem9udGFsKSB7XG4gICAgICBjb25zdCB4ID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGR4ID0geCAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGR4IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHg7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3ZlclZlcnRpY2FsKSB7XG4gICAgICBjb25zdCB5ID0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGNvbnN0IGR5ID0geSAtIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55O1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSAtIGR5IC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGNoaWxkRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudCxcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICBhY3RpdmVUb29sLFxuICAgICAgICBpc1Jlc2l6aW5nLFxuICAgICAgICBpc1JvdGF0aW5nLFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIGlzUm90YXRpbmc6IGZhbHNlLFxuICAgICAgICByZXNpemluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICAvLyB0ZXh0IGVsZW1lbnRzIGFyZSByZXNldCBvbiBmaW5hbGl6ZSwgYW5kIHJlc2V0dGluZyBvbiBwb2ludGVydXBcbiAgICAgICAgLy8gbWF5IGNhdXNlIGlzc3VlcyB3aXRoIGRvdWJsZSB0YXBzXG4gICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgIG11bHRpRWxlbWVudCB8fCBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnRcbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnNhdmVQb2ludGVyKGNoaWxkRXZlbnQuY2xpZW50WCwgY2hpbGRFdmVudC5jbGllbnRZLCBcInVwXCIpO1xuXG4gICAgICAvLyBIYW5kbGUgZW5kIG9mIGRyYWdnaW5nIGEgcG9pbnQgb2YgYSBsaW5lYXIgZWxlbWVudCwgbWlnaHQgY2xvc2UgYSBsb29wXG4gICAgICAvLyBhbmQgc2V0cyBiaW5kaW5nIGVsZW1lbnRcbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJVcChcbiAgICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Py5lbGVtZW50Py5pZCAhPT1cbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5lbGVtZW50SWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFTGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHNldCBzZWxlY3RlZExpbmVhckVsZW1lbnQgdG8gbnVsbCBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGVsZW1lbnQgc2VsZWN0ZWQgc2luY2Ugd2UgZG9uJ3Qgd2FudCB0byBzaG93IGxpbmVhciBlbGVtZW50IGhhbmRsZXNcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRFTGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBsaW5lYXJFbGVtZW50RWRpdG9yID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyVXAoXG4gICAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCB7IHN0YXJ0QmluZGluZ0VsZW1lbnQsIGVuZEJpbmRpbmdFbGVtZW50IH0gPVxuICAgICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcjtcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50KGxpbmVhckVsZW1lbnRFZGl0b3IuZWxlbWVudElkKTtcbiAgICAgICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgICAgYmluZE9yVW5iaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgc3RhcnRCaW5kaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgZW5kQmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChsaW5lYXJFbGVtZW50RWRpdG9yICE9PSB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLmxpbmVhckVsZW1lbnRFZGl0b3IsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRQb2ludHNJbmRpY2VzOiBudWxsLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSkge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZS5mbHVzaCgpO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9NT1ZFLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWURPV04sXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCEsXG4gICAgICApO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogbnVsbCB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudD8udHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICAvLyBBbGxvd3MgZG90cyB0byBhdm9pZCBiZWluZyBmbGFnZ2VkIGFzIGluZmluaXRlbHkgc21hbGxcbiAgICAgICAgaWYgKGR4ID09PSBwb2ludHNbMF1bMF0gJiYgZHkgPT09IHBvaW50c1swXVsxXSkge1xuICAgICAgICAgIGR5ICs9IDAuMDAwMTtcbiAgICAgICAgICBkeCArPSAwLjAwMDE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBjaGlsZEV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IFtkeCwgZHldLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICB7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBpbWFnZUVsZW1lbnQuaWQpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQhLnBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgICAgIW11bHRpRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgIC4uLmRyYWdnaW5nRWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQ6IGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiYgIW11bHRpRWxlbWVudCkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCBmYWxzZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10sIHN0YXJ0Qm91bmRFbGVtZW50OiBudWxsIH0pO1xuICAgICAgICAgIGlmICghYWN0aXZlVG9vbC5sb2NrZWQpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sOiB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICkge1xuICAgICAgICAvLyByZW1vdmUgaW52aXNpYmxlIGVsZW1lbnQgd2hpY2ggd2FzIGFkZGVkIGluIG9uUG9pbnRlckRvd25cbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5zbGljZSgwLCAtMSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyhkcmFnZ2luZ0VsZW1lbnQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCAmJiBpc0ludmlzaWJseVNtYWxsRWxlbWVudChyZXNpemluZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSByZXNpemluZ0VsZW1lbnQuaWQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb2RlIGJlbG93IGhhbmRsZXMgc2VsZWN0aW9uIHdoZW4gZWxlbWVudChzKSB3ZXJlbid0XG4gICAgICAvLyBkcmFnIG9yIGFkZGVkIHRvIHNlbGVjdGlvbiBvbiBwb2ludGVyIGRvd24gcGhhc2UuXG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgaXNMaW5lYXJFbGVtZW50KGhpdEVsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFTGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHdoZW4gbm8gb3RoZXIgZWxlbWVudCBzZWxlY3RlZCBleGNlcHRcbiAgICAgICAgLy8gdGhlIG9uZSB3ZSd2ZSBoaXRcbiAgICAgICAgaWYgKHNlbGVjdGVkRUxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzRXJhc2VyQWN0aXZlKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgIGNvbnN0IGRyYWdnZWREaXN0YW5jZSA9IGRpc3RhbmNlMmQoXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFgsXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICAgICAgdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZHJhZ2dlZERpc3RhbmNlID09PSAwKSB7XG4gICAgICAgICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjbGllbnRYOiB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICAgICAgICAgIGNsaWVudFk6IHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgaGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBoaXRFbGVtZW50cy5mb3JFYWNoKFxuICAgICAgICAgICAgKGhpdEVsZW1lbnQpID0+XG4gICAgICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2hpdEVsZW1lbnQuaWRdID0ge1xuICAgICAgICAgICAgICAgIGVyYXNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IGhpdEVsZW1lbnQub3BhY2l0eSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVyYXNlRWxlbWVudHMocG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXMocG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZSkubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucmVzdG9yZVJlYWR5VG9FcmFzZUVsZW1lbnRzKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGhpdEVsZW1lbnQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiAmJlxuICAgICAgICAvLyBpZiB3ZSdyZSBlZGl0aW5nIGEgbGluZSwgcG9pbnRlcnVwIHNob3VsZG4ndCBzd2l0Y2ggc2VsZWN0aW9uIGlmXG4gICAgICAgIC8vIGJveCBzZWxlY3RlZFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQpXG4gICAgICApIHtcbiAgICAgICAgLy8gd2hlbiBpbnNpZGUgbGluZSBlZGl0b3IsIHNoaWZ0IHNlbGVjdHMgcG9pbnRzIGluc3RlYWRcbiAgICAgICAgaWYgKGNoaWxkRXZlbnQuc2hpZnRLZXkgJiYgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIGlmIChpc1NlbGVjdGVkVmlhR3JvdXAodGhpcy5zdGF0ZSwgaGl0RWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugd2FudCB0byB1bnNlbGVjdCBhbGwgZ3JvdXBzIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICAvLyBhcyB3ZWxsIGFzIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBncm91cHNcbiAgICAgICAgICAgICAgLy8gaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIGNvbnN0IGlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyA9IGhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAuZmxhdE1hcCgoZ3JvdXBJZCkgPT5cbiAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRzSW5Hcm91cChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5tYXAoKGVsZW1lbnQpID0+ICh7IFtlbGVtZW50LmlkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldklkLCBhY2MpID0+ICh7IC4uLnByZXZJZCwgLi4uYWNjIH0pLCB7fSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZ0lkKSA9PiAoeyBbZ0lkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGFjYykgPT4gKHsgLi4ucHJldiwgLi4uYWNjIH0pLCB7fSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgLy8gaWYgbm90IGdyYWdnaW5nIGEgbGluZWFyIGVsZW1lbnQgcG9pbnQgKG91dHNpZGUgZWRpdG9yKVxuICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgLy8gcmVtb3ZlIGVsZW1lbnQgZnJvbSBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2VsZWN0ZWRFbGVtZW50SWRzID0ge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IGZhbHNlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICAgeyAuLi5wcmV2U3RhdGUsIHNlbGVjdGVkRWxlbWVudElkczogbmV3U2VsZWN0ZWRFbGVtZW50SWRzIH0sXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogbmV3U2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IG9ubHkgaWYgdGhhdHMgdGhlIG9ubHkgZWxlbWVudCBzZWxlY3RlZFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICAgICAgbmV3U2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQobmV3U2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYWRkIGVsZW1lbnQgdG8gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAvLyBrZWVwaW5nIHByZXYgZWxlbWVudHMgc2VsZWN0ZWRcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIC4uLnNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDpcbiAgICAgICAgICAgICAgICAgIGlzTGluZWFyRWxlbWVudChoaXRFbGVtZW50KSAmJlxuICAgICAgICAgICAgICAgICAgLy8gRG9uJ3Qgc2V0IGBzZWxlY3RlZExpbmVhckVsZW1lbnRgIGlmIGl0cyBzYW1lIGFzIHRoZSBoaXRFbGVtZW50LCB0aGlzIGlzIG1haW5seSB0byBwcmV2ZW50IHJlc2V0dGluZyB0aGUgYGhvdmVyUG9pbnRJbmRleGAgdG8gLTEuXG4gICAgICAgICAgICAgICAgICAvLyBGdXR1cmUgd2Ugc2hvdWxkIHVwZGF0ZSB0aGUgQVBJIHRvIHRha2UgY2FyZSBvZiBzZXR0aW5nIHRoZSBjb3JyZWN0IGBob3ZlclBvaW50SW5kZXhgIHdoZW4gaW5pdGlhbGl6ZWRcbiAgICAgICAgICAgICAgICAgIHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT0gaGl0RWxlbWVudC5pZFxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKGhpdEVsZW1lbnQsIHRoaXMuc2NlbmUpXG4gICAgICAgICAgICAgICAgICAgIDogcHJldlN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAhdGhpcy5zdGF0ZS5pc1Jlc2l6aW5nICYmXG4gICAgICAgICgoaGl0RWxlbWVudCAmJlxuICAgICAgICAgIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgICAgIGhpdEVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSkgfHxcbiAgICAgICAgICAoIWhpdEVsZW1lbnQgJiZcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSlcbiAgICAgICkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXNlbGVjdCBzZWxlY3RlZCBlbGVtZW50c1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFhY3RpdmVUb29sLmxvY2tlZCAmJlxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIiAmJlxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnRcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQodGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgfHwgaXNSZXNpemluZyB8fCBpc1JvdGF0aW5nKSB7XG4gICAgICAgIChpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cykoXG4gICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhY3RpdmVUb29sLmxvY2tlZCAmJiBhY3RpdmVUb29sLnR5cGUgIT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVSZWFkeVRvRXJhc2VFbGVtZW50cyA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0ub3BhY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBpc0JvdW5kVG9Db250YWluZXIoZWxlKSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0gJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdLmVyYXNlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5vcGFjaXR5LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBlcmFzZUVsZW1lbnRzID0gKHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUpID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHsgaXNEZWxldGVkOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZTtcbiAgICB9KTtcblxuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2UgPSBhc3luYyAoe1xuICAgIGltYWdlRmlsZSxcbiAgICBpbWFnZUVsZW1lbnQ6IF9pbWFnZUVsZW1lbnQsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldyA9IGZhbHNlLFxuICB9OiB7XG4gICAgaW1hZ2VGaWxlOiBGaWxlO1xuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudDtcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3PzogYm9vbGVhbjtcbiAgfSkgPT4ge1xuICAgIC8vIGF0IHRoaXMgcG9pbnQgdGhpcyBzaG91bGQgYmUgZ3VhcmFudGVlZCBpbWFnZSBmaWxlLCBidXQgd2UgZG8gdGhpcyBjaGVja1xuICAgIC8vIHRvIHNhdGlzZnkgVFMgZG93biB0aGUgbGluZVxuICAgIGlmICghaXNTdXBwb3J0ZWRJbWFnZUZpbGUoaW1hZ2VGaWxlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMudW5zdXBwb3J0ZWRGaWxlVHlwZVwiKSk7XG4gICAgfVxuICAgIGNvbnN0IG1pbWVUeXBlID0gaW1hZ2VGaWxlLnR5cGU7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIFwid2FpdFwiKTtcblxuICAgIGlmIChtaW1lVHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IFNWR1N0cmluZ1RvRmlsZShcbiAgICAgICAgICBhd2FpdCBub3JtYWxpemVTVkcoYXdhaXQgaW1hZ2VGaWxlLnRleHQoKSksXG4gICAgICAgICAgaW1hZ2VGaWxlLm5hbWUsXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnN2Z0ltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGdlbmVyYXRlIGltYWdlIGlkIChieSBkZWZhdWx0IHRoZSBmaWxlIGRpZ2VzdCkgYmVmb3JlIGFueVxuICAgIC8vIHJlc2l6aW5nL2NvbXByZXNzaW9uIHRha2VzIHBsYWNlIHRvIGtlZXAgaXQgbW9yZSBwb3J0YWJsZVxuICAgIGNvbnN0IGZpbGVJZCA9IGF3YWl0ICgodGhpcy5wcm9wcy5nZW5lcmF0ZUlkRm9yRmlsZT8uKFxuICAgICAgaW1hZ2VGaWxlLFxuICAgICkgYXMgUHJvbWlzZTxGaWxlSWQ+KSB8fCBnZW5lcmF0ZUlkRnJvbUZpbGUoaW1hZ2VGaWxlKSk7XG5cbiAgICBpZiAoIWZpbGVJZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkNvdWxkbid0IGdlbmVyYXRlIGZpbGUgaWQgb3IgdGhlIHN1cHBsaWVkIGBnZW5lcmF0ZUlkRm9yRmlsZWAgZGlkbid0IHJlc29sdmUgdG8gb25lLlwiLFxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nRmlsZURhdGEgPSB0aGlzLmZpbGVzW2ZpbGVJZF07XG4gICAgaWYgKCFleGlzdGluZ0ZpbGVEYXRhPy5kYXRhVVJMKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBhd2FpdCByZXNpemVJbWFnZUZpbGUoaW1hZ2VGaWxlLCB7XG4gICAgICAgICAgbWF4V2lkdGhPckhlaWdodDogREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcImVycm9yIHRyeWluZyB0byByZXNpbmcgaW1hZ2UgZmlsZSBvbiBpbnNlcnRpb25cIiwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW1hZ2VGaWxlLnNpemUgPiBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICB0KFwiZXJyb3JzLmZpbGVUb29CaWdcIiwge1xuICAgICAgICAgICAgbWF4U2l6ZTogYCR7TWF0aC50cnVuYyhNQVhfQUxMT1dFRF9GSUxFX0JZVEVTIC8gMTAyNCAvIDEwMjQpfU1CYCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvd0N1cnNvckltYWdlUHJldmlldykge1xuICAgICAgY29uc3QgZGF0YVVSTCA9IHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTDtcbiAgICAgIC8vIG9wdGltaXphdGlvbiBzbyB0aGF0IHdlIGRvbid0IHVubmVjZXNzYXJpbHkgcmVzaXplIHRoZSBvcmlnaW5hbFxuICAgICAgLy8gZnVsbC1zaXplIGZpbGUgZm9yIGN1cnNvciBwcmV2aWV3XG4gICAgICAvLyAoaXQncyBtdWNoIGZhc3RlciB0byBjb252ZXJ0IHRoZSByZXNpemVkIGRhdGFVUkwgdG8gRmlsZSlcbiAgICAgIGNvbnN0IHJlc2l6ZWRGaWxlID0gZGF0YVVSTCAmJiBkYXRhVVJMVG9GaWxlKGRhdGFVUkwpO1xuXG4gICAgICB0aGlzLnNldEltYWdlUHJldmlld0N1cnNvcihyZXNpemVkRmlsZSB8fCBpbWFnZUZpbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFVUkwgPVxuICAgICAgdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMIHx8IChhd2FpdCBnZXREYXRhVVJMKGltYWdlRmlsZSkpO1xuXG4gICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gbXV0YXRlRWxlbWVudChcbiAgICAgIF9pbWFnZUVsZW1lbnQsXG4gICAgICB7XG4gICAgICAgIGZpbGVJZCxcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApIGFzIE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50PjtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD4+KFxuICAgICAgYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuZmlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmZpbGVzLFxuICAgICAgICAgICAgW2ZpbGVJZF06IHtcbiAgICAgICAgICAgICAgbWltZVR5cGUsXG4gICAgICAgICAgICAgIGlkOiBmaWxlSWQsXG4gICAgICAgICAgICAgIGRhdGFVUkwsXG4gICAgICAgICAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY2FjaGVkSW1hZ2VEYXRhID0gdGhpcy5pbWFnZUNhY2hlLmdldChmaWxlSWQpO1xuICAgICAgICAgIGlmICghY2FjaGVkSW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFtpbWFnZUVsZW1lbnRdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNhY2hlZEltYWdlRGF0YT8uaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBhd2FpdCBjYWNoZWRJbWFnZURhdGEuaW1hZ2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkICE9PSBpbWFnZUVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50LCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShpbWFnZUVsZW1lbnQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoIXNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogaW5zZXJ0cyBpbWFnZSBpbnRvIGVsZW1lbnRzIGFycmF5IGFuZCByZXJlbmRlcnNcbiAgICovXG4gIHByaXZhdGUgaW5zZXJ0SW1hZ2VFbGVtZW50ID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBpbWFnZUZpbGU6IEZpbGUsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBpbWFnZUVsZW1lbnQsXG4gICAgXSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplSW1hZ2Uoe1xuICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgc2hvd0N1cnNvckltYWdlUHJldmlldyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIGlzRGVsZXRlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB8fCB0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRJbWFnZVByZXZpZXdDdXJzb3IgPSBhc3luYyAoaW1hZ2VGaWxlOiBGaWxlKSA9PiB7XG4gICAgLy8gbXVzdG4ndCBiZSBsYXJnZXIgdGhhbiAxMjggcHhcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX0Jhc2ljX1VzZXJfSW50ZXJmYWNlL1VzaW5nX1VSTF92YWx1ZXNfZm9yX3RoZV9jdXJzb3JfcHJvcGVydHlcbiAgICBjb25zdCBjdXJzb3JJbWFnZVNpemVQeCA9IDk2O1xuXG4gICAgY29uc3QgaW1hZ2VQcmV2aWV3ID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgbWF4V2lkdGhPckhlaWdodDogY3Vyc29ySW1hZ2VTaXplUHgsXG4gICAgfSk7XG5cbiAgICBsZXQgcHJldmlld0RhdGFVUkwgPSBhd2FpdCBnZXREYXRhVVJMKGltYWdlUHJldmlldyk7XG5cbiAgICAvLyBTVkcgY2Fubm90IGJlIHJlc2l6ZWQgdmlhIGByZXNpemVJbWFnZUZpbGVgIHNvIHdlIHJlc2l6ZSBieSByZW5kZXJpbmcgdG9cbiAgICAvLyBhIHNtYWxsIGNhbnZhc1xuICAgIGlmIChpbWFnZUZpbGUudHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIGNvbnN0IGltZyA9IGF3YWl0IGxvYWRIVE1MSW1hZ2VFbGVtZW50KHByZXZpZXdEYXRhVVJMKTtcblxuICAgICAgbGV0IGhlaWdodCA9IE1hdGgubWluKGltZy5oZWlnaHQsIGN1cnNvckltYWdlU2l6ZVB4KTtcbiAgICAgIGxldCB3aWR0aCA9IGhlaWdodCAqIChpbWcud2lkdGggLyBpbWcuaGVpZ2h0KTtcblxuICAgICAgaWYgKHdpZHRoID4gY3Vyc29ySW1hZ2VTaXplUHgpIHtcbiAgICAgICAgd2lkdGggPSBjdXJzb3JJbWFnZVNpemVQeDtcbiAgICAgICAgaGVpZ2h0ID0gd2lkdGggKiAoaW1nLmhlaWdodCAvIGltZy53aWR0aCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSE7XG5cbiAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIHByZXZpZXdEYXRhVVJMID0gY2FudmFzLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgYHVybCgke3ByZXZpZXdEYXRhVVJMfSkgNCA0LCBhdXRvYCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25JbWFnZUFjdGlvbiA9IGFzeW5jIChcbiAgICB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHkgfSA9IHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseTogZmFsc2UgfSxcbiAgKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNsaWVudFggPSB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICAgIGNvbnN0IGNsaWVudFkgPSB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2VGaWxlID0gYXdhaXQgZmlsZU9wZW4oe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJbWFnZVwiLFxuICAgICAgICBleHRlbnNpb25zOiBbXCJqcGdcIiwgXCJwbmdcIiwgXCJzdmdcIiwgXCJnaWZcIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoe1xuICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgIHNjZW5lWTogeSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaW5zZXJ0T25DYW52YXNEaXJlY3RseSkge1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGltYWdlRmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnRJZDogaW1hZ2VFbGVtZW50LmlkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoXG4gICAgICAgICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICAgICAgICAvKiBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ICovIHRydWUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiQWJvcnRFcnJvclwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMgPSAoXG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICAgIGZvcmNlTmF0dXJhbFNpemUgPSBmYWxzZSxcbiAgKSA9PiB7XG4gICAgY29uc3QgaW1hZ2UgPVxuICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQpICYmXG4gICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGltYWdlRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcblxuICAgIGlmICghaW1hZ2UgfHwgaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgcGxhY2Vob2xkZXJTaXplID0gMTAwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICAgIHg6IGltYWdlRWxlbWVudC54IC0gcGxhY2Vob2xkZXJTaXplIC8gMixcbiAgICAgICAgICB5OiBpbWFnZUVsZW1lbnQueSAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgd2lkdGg6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgICBoZWlnaHQ6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBmb3JjZU5hdHVyYWxTaXplIHx8XG4gICAgICAvLyBpZiB1c2VyLWNyZWF0ZWQgYm91bmRpbmcgYm94IGlzIGJlbG93IHRocmVzaG9sZCwgYXNzdW1lIHRoZVxuICAgICAgLy8gaW50ZW50aW9uIHdhcyB0byBjbGljayBpbnN0ZWFkIG9mIGRyYWcsIGFuZCB1c2UgdGhlIGltYWdlJ3NcbiAgICAgIC8vIGludHJpbnNpYyBzaXplXG4gICAgICAoaW1hZ2VFbGVtZW50LndpZHRoIDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlICYmXG4gICAgICAgIGltYWdlRWxlbWVudC5oZWlnaHQgPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgKSB7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBNYXRoLm1heCh0aGlzLnN0YXRlLmhlaWdodCAtIDEyMCwgMTYwKTtcbiAgICAgIC8vIG1heCA2NSUgb2YgY2FudmFzIGhlaWdodCwgY2xhbXBlZCB0byA8MzAwcHgsIHZoIC0gMTIwcHg+XG4gICAgICBjb25zdCBtYXhIZWlnaHQgPSBNYXRoLm1pbihcbiAgICAgICAgbWluSGVpZ2h0LFxuICAgICAgICBNYXRoLmZsb29yKHRoaXMuc3RhdGUuaGVpZ2h0ICogMC41KSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGhlaWdodCA9IE1hdGgubWluKGltYWdlLm5hdHVyYWxIZWlnaHQsIG1heEhlaWdodCk7XG4gICAgICBjb25zdCB3aWR0aCA9IGhlaWdodCAqIChpbWFnZS5uYXR1cmFsV2lkdGggLyBpbWFnZS5uYXR1cmFsSGVpZ2h0KTtcblxuICAgICAgLy8gYWRkIGN1cnJlbnQgaW1hZ2VFbGVtZW50IHdpZHRoL2hlaWdodCB0byBhY2NvdW50IGZvciBwcmV2aW91cyBjZW50ZXJpbmdcbiAgICAgIC8vIG9mIHRoZSBwbGFjZWhvbGRlciBpbWFnZVxuICAgICAgY29uc3QgeCA9IGltYWdlRWxlbWVudC54ICsgaW1hZ2VFbGVtZW50LndpZHRoIC8gMiAtIHdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHkgPSBpbWFnZUVsZW1lbnQueSArIGltYWdlRWxlbWVudC5oZWlnaHQgLyAyIC0gaGVpZ2h0IC8gMjtcblxuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHsgeCwgeSwgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIHVwZGF0ZXMgaW1hZ2UgY2FjaGUsIHJlZnJlc2hpbmcgdXBkYXRlZCBlbGVtZW50cyBhbmQvb3Igc2V0dGluZyBzdGF0dXNcbiAgICAgIHRvIGVycm9yIGZvciBpbWFnZXMgdGhhdCBmYWlsIGR1cmluZyA8aW1nPiBlbGVtZW50IGNyZWF0aW9uICovXG4gIHByaXZhdGUgdXBkYXRlSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBlbGVtZW50czogcmVhZG9ubHkgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10sXG4gICAgZmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH0gPSBhd2FpdCBfdXBkYXRlSW1hZ2VDYWNoZSh7XG4gICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICBmaWxlSWRzOiBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZmlsZUlkKSxcbiAgICAgIGZpbGVzLFxuICAgIH0pO1xuICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSB8fCBlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgIGlmICh1cGRhdGVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKSkge1xuICAgICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgICBlcnJvcmVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9O1xuICB9O1xuXG4gIC8qKiBhZGRzIG5ldyBpbWFnZXMgdG8gaW1hZ2VDYWNoZSBhbmQgcmUtcmVuZGVycyBpZiBuZWVkZWQgKi9cbiAgcHJpdmF0ZSBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50czogSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10gPSBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICksXG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgdW5jYWNoZWRJbWFnZUVsZW1lbnRzID0gaW1hZ2VFbGVtZW50cy5maWx0ZXIoXG4gICAgICAoZWxlbWVudCkgPT4gIWVsZW1lbnQuaXNEZWxldGVkICYmICF0aGlzLmltYWdlQ2FjaGUuaGFzKGVsZW1lbnQuZmlsZUlkKSxcbiAgICApO1xuXG4gICAgaWYgKHVuY2FjaGVkSW1hZ2VFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHsgdXBkYXRlZEZpbGVzIH0gPSBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoXG4gICAgICAgIHVuY2FjaGVkSW1hZ2VFbGVtZW50cyxcbiAgICAgICAgZmlsZXMsXG4gICAgICApO1xuICAgICAgaWYgKHVwZGF0ZWRGaWxlcy5zaXplKSB7XG4gICAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqIGdlbmVyYWxseSB5b3Ugc2hvdWxkIHVzZSBgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKClgIGRpcmVjdGx5IGlmIHlvdSBuZWVkXG4gICAqICB0byByZW5kZXIgbmV3IGltYWdlcy4gVGhpcyBpcyBqdXN0IGEgZmFpbHNhZmUgICovXG4gIHByaXZhdGUgc2NoZWR1bGVJbWFnZVJlZnJlc2ggPSB0aHJvdHRsZSgoKSA9PiB7XG4gICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgfSwgSU1BR0VfUkVOREVSX1RJTUVPVVQpO1xuXG4gIHByaXZhdGUgdXBkYXRlQmluZGluZ0VuYWJsZWRPblBvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBjb25zdCBzaG91bGRFbmFibGVCaW5kaW5nID0gc2hvdWxkRW5hYmxlQmluZGluZ0ZvclBvaW50ZXJFdmVudChldmVudCk7XG4gICAgaWYgKHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCAhPT0gc2hvdWxkRW5hYmxlQmluZGluZykge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHNob3VsZEVuYWJsZUJpbmRpbmcgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yID0gKHBvaW50ZXJDb29yZHM6IHtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xuICB9KTogdm9pZCA9PiB7XG4gICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICB0aGlzLnNjZW5lLFxuICAgICk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzdWdnZXN0ZWRCaW5kaW5nczpcbiAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsID8gW2hvdmVyZWRCaW5kYWJsZUVsZW1lbnRdIDogW10sXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyA9IChcbiAgICBsaW5lYXJFbGVtZW50OiBOb25EZWxldGVkPEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50PixcbiAgICAvKiogc2NlbmUgY29vcmRzICovXG4gICAgcG9pbnRlckNvb3Jkczoge1xuICAgICAgeDogbnVtYmVyO1xuICAgICAgeTogbnVtYmVyO1xuICAgIH1bXSxcbiAgICAvLyBEdXJpbmcgbGluZSBjcmVhdGlvbiB0aGUgc3RhcnQgYmluZGluZyBoYXNuJ3QgYmVlbiB3cml0dGVuIHlldFxuICAgIC8vIGludG8gYGxpbmVhckVsZW1lbnRgXG4gICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50PzogRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCB8IG51bGwsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICghcG9pbnRlckNvb3Jkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IHBvaW50ZXJDb29yZHMucmVkdWNlKFxuICAgICAgKGFjYzogTm9uRGVsZXRlZDxFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50PltdLCBjb29yZHMpID0+IHtcbiAgICAgICAgY29uc3QgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgICBjb29yZHMsXG4gICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICAgICFpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQoXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgb3Bwb3NpdGVCaW5kaW5nQm91bmRFbGVtZW50Py5pZCxcbiAgICAgICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQsXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2MucHVzaChob3ZlcmVkQmluZGFibGVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdLFxuICAgICk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbihoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAvLyBDb250aW51ZSBlZGl0aW5nIHRoZSBzYW1lIGdyb3VwIGlmIHRoZSB1c2VyIHNlbGVjdGVkIGEgZGlmZmVyZW50XG4gICAgICAvLyBlbGVtZW50IGZyb20gaXRcbiAgICAgIGVkaXRpbmdHcm91cElkOlxuICAgICAgICBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQgJiZcbiAgICAgICAgaGl0RWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgIGlzRWxlbWVudEluR3JvdXAoaGl0RWxlbWVudCwgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgID8gcHJldlN0YXRlLmVkaXRpbmdHcm91cElkXG4gICAgICAgICAgOiBudWxsLFxuICAgIH0pKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1JlZiA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB7XG4gICAgLy8gY2FudmFzIGlzIG51bGwgd2hlbiB1bm1vdW50aW5nXG4gICAgaWYgKGNhbnZhcyAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XG4gICAgICB0aGlzLnJjID0gcm91Z2guY2FudmFzKHRoaXMuY2FudmFzKTtcblxuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCwge1xuICAgICAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUFwcE9uRHJvcCA9IGFzeW5jIChldmVudDogUmVhY3QuRHJhZ0V2ZW50PEhUTUxEaXZFbGVtZW50PikgPT4ge1xuICAgIC8vIG11c3QgYmUgcmV0cmlldmVkIGZpcnN0LCBpbiB0aGUgc2FtZSBmcmFtZVxuICAgIGNvbnN0IHsgZmlsZSwgZmlsZUhhbmRsZSB9ID0gYXdhaXQgZ2V0RmlsZUZyb21FdmVudChldmVudCk7XG5cbiAgICB0cnkge1xuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpKSB7XG4gICAgICAgIC8vIGZpcnN0IGF0dGVtcHQgdG8gZGVjb2RlIHNjZW5lIGZyb20gdGhlIGltYWdlIGlmIGl0J3MgZW1iZWRkZWRcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgaWYgKGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMucG5nIHx8IGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHNjZW5lID0gYXdhaXQgbG9hZEZyb21CbG9iKFxuICAgICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgICAgIC4uLnNjZW5lLFxuICAgICAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkVuY29kaW5nRXJyb3JcIikge1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBubyBzY2VuZSBpcyBlbWJlZGRlZCBvciB3ZSBmYWlsIGZvciB3aGF0ZXZlciByZWFzb24sIGZhbGwgYmFja1xuICAgICAgICAvLyB0byBpbXBvcnRpbmcgYXMgcmVndWxhciBpbWFnZVxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGxpYnJhcnlKU09OID0gZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliKTtcbiAgICBpZiAobGlicmFyeUpTT04gJiYgdHlwZW9mIGxpYnJhcnlKU09OID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsaWJyYXJ5SXRlbXMgPSBwYXJzZUxpYnJhcnlKU09OKGxpYnJhcnlKU09OKTtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRpc3RyaWJ1dGVMaWJyYXJ5SXRlbXNPblNxdWFyZUdyaWQobGlicmFyeUl0ZW1zKSxcbiAgICAgICAgICBwb3NpdGlvbjogZXZlbnQsXG4gICAgICAgICAgZmlsZXM6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChmaWxlKSB7XG4gICAgICAvLyBhdGV0bXB0IHRvIHBhcnNlIGFuIGV4Y2FsaWRyYXcvZXhjYWxpZHJhd2xpYiBmaWxlXG4gICAgICBhd2FpdCB0aGlzLmxvYWRGaWxlVG9DYW52YXMoZmlsZSwgZmlsZUhhbmRsZSk7XG4gICAgfVxuICB9O1xuXG4gIGxvYWRGaWxlVG9DYW52YXMgPSBhc3luYyAoXG4gICAgZmlsZTogRmlsZSxcbiAgICBmaWxlSGFuZGxlOiBGaWxlU3lzdGVtSGFuZGxlIHwgbnVsbCxcbiAgKSA9PiB7XG4gICAgZmlsZSA9IGF3YWl0IG5vcm1hbGl6ZUZpbGUoZmlsZSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJldCA9IGF3YWl0IGxvYWRTY2VuZU9yTGlicmFyeUZyb21CbG9iKFxuICAgICAgICBmaWxlLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBmaWxlSGFuZGxlLFxuICAgICAgKTtcbiAgICAgIGlmIChyZXQudHlwZSA9PT0gTUlNRV9UWVBFUy5leGNhbGlkcmF3KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgLi4ucmV0LmRhdGEsXG4gICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgIC4uLihyZXQuZGF0YS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocmV0LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYikge1xuICAgICAgICBhd2FpdCB0aGlzLmxpYnJhcnlcbiAgICAgICAgICAudXBkYXRlTGlicmFyeSh7XG4gICAgICAgICAgICBsaWJyYXJ5SXRlbXM6IGZpbGUsXG4gICAgICAgICAgICBtZXJnZTogdHJ1ZSxcbiAgICAgICAgICAgIG9wZW5MaWJyYXJ5TWVudTogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogdChcImVycm9ycy5pbXBvcnRMaWJyYXJ5RXJyb3JcIikgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNDb250ZXh0TWVudSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmIChcbiAgICAgIChldmVudC5uYXRpdmVFdmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiIHx8XG4gICAgICAgIChldmVudC5uYXRpdmVFdmVudC5wb2ludGVyVHlwZSA9PT0gXCJwZW5cIiAmJlxuICAgICAgICAgIC8vIGFsd2F5cyBhbGxvdyBpZiB1c2VyIHVzZXMgYSBwZW4gc2Vjb25kYXJ5IGJ1dHRvblxuICAgICAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uU0VDT05EQVJZKSkgJiZcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIHByZWZlclNlbGVjdGVkOiB0cnVlLFxuICAgICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdHlwZSA9IGVsZW1lbnQgPyBcImVsZW1lbnRcIiA6IFwiY2FudmFzXCI7XG5cbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCE7XG4gICAgY29uc3QgeyB0b3A6IG9mZnNldFRvcCwgbGVmdDogb2Zmc2V0TGVmdCB9ID1cbiAgICAgIGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBsZWZ0ID0gZXZlbnQuY2xpZW50WCAtIG9mZnNldExlZnQ7XG4gICAgY29uc3QgdG9wID0gZXZlbnQuY2xpZW50WSAtIG9mZnNldFRvcDtcblxuICAgIGlmIChlbGVtZW50ICYmICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1tlbGVtZW50LmlkXSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBpc0xpbmVhckVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihlbGVtZW50LCB0aGlzLnNjZW5lKVxuICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICApLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50ID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJlcmFzZXJcIlxuICAgICkge1xuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyQ29vcmRzLngpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LCBwb2ludGVyQ29vcmRzLnkpLFxuICAgICAgICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZSA9XG4gICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSAmJlxuICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGRyYWdnaW5nRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcbiAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID1cbiAgICAgICAgaW1hZ2UgJiYgIShpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICAgICAgPyBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodFxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksXG4gICAgICAgIGdyaWRYLFxuICAgICAgICBncmlkWSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCwgZ3JpZFgpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LCBncmlkWSksXG4gICAgICAgIGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChbZHJhZ2dpbmdFbGVtZW50XSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVIYW5kbGVSZXNpemUgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgICBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIFRPRE86IHJlbmFtZSB0aGlzIHN0YXRlIGZpZWxkIHRvIFwiaXNTY2FsaW5nXCIgdG8gZGlzdGluZ3Vpc2hcbiAgICAgIC8vIGl0IGZyb20gdGhlIGdlbmVyaWMgXCJpc1Jlc2l6aW5nXCIgd2hpY2ggaW5jbHVkZXMgc2NhbGluZyBhbmRcbiAgICAgIC8vIHJvdGF0aW5nXG4gICAgICBpc1Jlc2l6aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlICYmIHRyYW5zZm9ybUhhbmRsZVR5cGUgIT09IFwicm90YXRpb25cIixcbiAgICAgIGlzUm90YXRpbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgPT09IFwicm90YXRpb25cIixcbiAgICB9KTtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGNvbnN0IFtyZXNpemVYLCByZXNpemVZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC54LFxuICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uLFxuICAgICAgICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0ltYWdlRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgcmVzaXplWCxcbiAgICAgICAgcmVzaXplWSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci55LFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKiogQHByaXZhdGUgdXNlIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgKi9cbiAgcHJpdmF0ZSBfb3BlbkNvbnRleHRNZW51ID0gKFxuICAgIHtcbiAgICAgIGxlZnQsXG4gICAgICB0b3AsXG4gICAgfToge1xuICAgICAgbGVmdDogbnVtYmVyO1xuICAgICAgdG9wOiBudW1iZXI7XG4gICAgfSxcbiAgICB0eXBlOiBcImNhbnZhc1wiIHwgXCJlbGVtZW50XCIsXG4gICkgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UgfSk7XG4gICAgfVxuICAgIHRoaXMuY29udGV4dE1lbnVPcGVuID0gdHJ1ZTtcbiAgICBjb25zdCBtYXliZUdyb3VwQWN0aW9uID0gYWN0aW9uR3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlVW5ncm91cEFjdGlvbiA9IGFjdGlvblVuZ3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcEhvcml6b250YWwgPSBhY3Rpb25GbGlwSG9yaXpvbnRhbC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVGbGlwVmVydGljYWwgPSBhY3Rpb25GbGlwVmVydGljYWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heUJlQWxsb3dVbmJpbmRpbmcgPSBhY3Rpb25VbmJpbmRUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heUJlQWxsb3dCaW5kaW5nID0gYWN0aW9uQmluZFRleHQuY29udGV4dEl0ZW1QcmVkaWNhdGUoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3Qgc2VwYXJhdG9yID0gXCJzZXBhcmF0b3JcIjtcblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IG9wdGlvbnM6IENvbnRleHRNZW51T3B0aW9uW10gPSBbXTtcbiAgICBpZiAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1BuZyk7XG4gICAgfVxuXG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1N2Zyk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZSA9PT0gXCJlbGVtZW50XCIgJiZcbiAgICAgIGNvcHlUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKGVsZW1lbnRzLCB0aGlzLnN0YXRlKSAmJlxuICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dFxuICAgICkge1xuICAgICAgb3B0aW9ucy5wdXNoKGNvcHlUZXh0KTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwiY2FudmFzXCIpIHtcbiAgICAgIGNvbnN0IHZpZXdNb2RlT3B0aW9ucyA9IFtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgIF07XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiB2aWV3TW9kZU9wdGlvbnMsXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIHRyYWNrRXZlbnQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmXG4gICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgYWN0aW9uQ29weUFzUG5nLFxuICAgICAgICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1N2ZyxcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiZcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGNvcHlUZXh0LFxuICAgICAgICAgICAgKChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB8fFxuICAgICAgICAgICAgICAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSkgJiZcbiAgICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uU2VsZWN0QWxsLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZWxlbWVudFwiKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW25hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSwgLi4ub3B0aW9uc10sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmIGFjdGlvbkN1dCxcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSxcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICB0cmFja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uQ29weVN0eWxlcyxcbiAgICAgICAgICAgIGFjdGlvblBhc3RlU3R5bGVzLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVHcm91cEFjdGlvbiAmJiBhY3Rpb25Hcm91cCxcbiAgICAgICAgICAgIG1heUJlQWxsb3dVbmJpbmRpbmcgJiYgYWN0aW9uVW5iaW5kVGV4dCxcbiAgICAgICAgICAgIG1heUJlQWxsb3dCaW5kaW5nICYmIGFjdGlvbkJpbmRUZXh0LFxuICAgICAgICAgICAgbWF5YmVVbmdyb3VwQWN0aW9uICYmIGFjdGlvblVuZ3JvdXAsXG4gICAgICAgICAgICAobWF5YmVHcm91cEFjdGlvbiB8fCBtYXliZVVuZ3JvdXBBY3Rpb24pICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgICAgICAgICAgIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgICAgICAgICAgIGFjdGlvblNlbmRUb0JhY2ssXG4gICAgICAgICAgICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUZsaXBIb3Jpem9udGFsICYmIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICAgICAgICAgICAgbWF5YmVGbGlwVmVydGljYWwgJiYgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICAgICAgICAgICAgKG1heWJlRmxpcEhvcml6b250YWwgfHwgbWF5YmVGbGlwVmVydGljYWwpICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkxpbmsuY29udGV4dEl0ZW1QcmVkaWNhdGUoZWxlbWVudHMsIHRoaXMuc3RhdGUpICYmIGFjdGlvbkxpbmssXG4gICAgICAgICAgICBhY3Rpb25EdXBsaWNhdGVTZWxlY3Rpb24sXG4gICAgICAgICAgICBhY3Rpb25Ub2dnbGVMb2NrLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVdoZWVsID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogV2hlZWxFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVsdGFYLCBkZWx0YVkgfSA9IGV2ZW50O1xuICAgIC8vIG5vdGUgdGhhdCBldmVudC5jdHJsS2V5IGlzIG5lY2Vzc2FyeSB0byBoYW5kbGUgcGluY2ggem9vbWluZ1xuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIGNvbnN0IHNpZ24gPSBNYXRoLnNpZ24oZGVsdGFZKTtcbiAgICAgIGNvbnN0IE1BWF9TVEVQID0gMTA7XG4gICAgICBjb25zdCBhYnNEZWx0YSA9IE1hdGguYWJzKGRlbHRhWSk7XG4gICAgICBsZXQgZGVsdGEgPSBkZWx0YVk7XG4gICAgICBpZiAoYWJzRGVsdGEgPiBNQVhfU1RFUCkge1xuICAgICAgICBkZWx0YSA9IE1BWF9TVEVQICogc2lnbjtcbiAgICAgIH1cblxuICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnN0YXRlLnpvb20udmFsdWUgLSBkZWx0YSAvIDEwMDtcbiAgICAgIC8vIGluY3JlYXNlIHpvb20gc3RlcHMgdGhlIG1vcmUgem9vbWVkLWluIHdlIGFyZSAoYXBwbGllcyB0byA+MTAwJSBvbmx5KVxuICAgICAgbmV3Wm9vbSArPVxuICAgICAgICBNYXRoLmxvZzEwKE1hdGgubWF4KDEsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpICpcbiAgICAgICAgLXNpZ24gKlxuICAgICAgICAvLyByZWR1Y2VkIGFtcGxpZmljYXRpb24gZm9yIHNtYWxsIGRlbHRhcyAoc21hbGwgbW92ZW1lbnRzIG9uIGEgdHJhY2twYWQpXG4gICAgICAgIE1hdGgubWluKDEsIGFic0RlbHRhIC8gMjApO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4gKHtcbiAgICAgICAgLi4uZ2V0U3RhdGVGb3Jab29tKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZpZXdwb3J0WDogY3Vyc29yWCxcbiAgICAgICAgICAgIHZpZXdwb3J0WTogY3Vyc29yWSxcbiAgICAgICAgICAgIG5leHRab29tOiBnZXROb3JtYWxpemVkWm9vbShuZXdab29tKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2Nyb2xsIGhvcml6b250YWxseSB3aGVuIHNoaWZ0IHByZXNzZWRcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCB9KSA9PiAoe1xuICAgICAgICAvLyBvbiBNYWMsIHNoaWZ0K3doZWVsIHRlbmRzIHRvIHJlc3VsdCBpbiBkZWx0YVhcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIChkZWx0YVkgfHwgZGVsdGFYKSAvIHpvb20udmFsdWUsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZIH0pID0+ICh7XG4gICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgIHNjcm9sbFk6IHNjcm9sbFkgLSBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBnZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICAgIHNjYWxlOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnRDbGlja2VkSW5zaWRlID0gZ2V0VGV4dEJpbmRhYmxlQ29udGFpbmVyQXRQb3NpdGlvbihcbiAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+ICFpc1RleHRFbGVtZW50KGVsZW1lbnQpKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICk7XG4gICAgaWYgKGVsZW1lbnRDbGlja2VkSW5zaWRlKSB7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWCA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnggKyBlbGVtZW50Q2xpY2tlZEluc2lkZS53aWR0aCAvIDI7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWSA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnkgKyBlbGVtZW50Q2xpY2tlZEluc2lkZS5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgZGlzdGFuY2VUb0NlbnRlciA9IE1hdGguaHlwb3QoXG4gICAgICAgIHggLSBlbGVtZW50Q2VudGVyWCxcbiAgICAgICAgeSAtIGVsZW1lbnRDZW50ZXJZLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzU25hcHBlZFRvQ2VudGVyID1cbiAgICAgICAgZGlzdGFuY2VUb0NlbnRlciA8IFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xEO1xuICAgICAgaWYgKGlzU25hcHBlZFRvQ2VudGVyKSB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7IHNjZW5lWDogZWxlbWVudENlbnRlclgsIHNjZW5lWTogZWxlbWVudENlbnRlclkgfSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgdmlld3BvcnRYLCB2aWV3cG9ydFksIGVsZW1lbnRDZW50ZXJYLCBlbGVtZW50Q2VudGVyWSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZVBvaW50ZXIgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIGJ1dHRvbjogXCJ1cFwiIHwgXCJkb3duXCIpID0+IHtcbiAgICBpZiAoIXggfHwgIXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKGlzTmFOKHBvaW50ZXIueCkgfHwgaXNOYU4ocG9pbnRlci55KSkge1xuICAgICAgLy8gc29tZXRpbWVzIHRoZSBwb2ludGVyIGdvZXMgb2ZmIHNjcmVlblxuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25Qb2ludGVyVXBkYXRlPy4oe1xuICAgICAgcG9pbnRlcixcbiAgICAgIGJ1dHRvbixcbiAgICAgIHBvaW50ZXJzTWFwOiBnZXN0dXJlLnBvaW50ZXJzLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnVubW91bnRlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3VsZENhY2hlSWdub3JlWm9vbTogZmFsc2UgfSk7XG4gICAgfVxuICB9LCAzMDApO1xuXG4gIHByaXZhdGUgdXBkYXRlRE9NUmVjdCA9IChjYj86ICgpID0+IHZvaWQpID0+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IG9mZnNldExlZnQsXG4gICAgICAgIHRvcDogb2Zmc2V0VG9wLFxuICAgICAgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoOiBjdXJyZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogY3VycmVudEhlaWdodCxcbiAgICAgICAgb2Zmc2V0VG9wOiBjdXJyZW50T2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBjdXJyZW50T2Zmc2V0TGVmdCxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHdpZHRoID09PSBjdXJyZW50V2lkdGggJiZcbiAgICAgICAgaGVpZ2h0ID09PSBjdXJyZW50SGVpZ2h0ICYmXG4gICAgICAgIG9mZnNldExlZnQgPT09IGN1cnJlbnRPZmZzZXRMZWZ0ICYmXG4gICAgICAgIG9mZnNldFRvcCA9PT0gY3VycmVudE9mZnNldFRvcFxuICAgICAgKSB7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIG9mZnNldExlZnQsXG4gICAgICAgICAgb2Zmc2V0VG9wLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2IgJiYgY2IoKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyByZWZyZXNoID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSB9KTtcbiAgfTtcblxuICBwcml2YXRlIGdldENhbnZhc09mZnNldHMoKTogUGljazxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXRMZWZ0OiBsZWZ0LFxuICAgICAgICBvZmZzZXRUb3A6IHRvcCxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgb2Zmc2V0VG9wOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUxhbmd1YWdlKCkge1xuICAgIGNvbnN0IGN1cnJlbnRMYW5nID1cbiAgICAgIGxhbmd1YWdlcy5maW5kKChsYW5nKSA9PiBsYW5nLmNvZGUgPT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHx8XG4gICAgICBkZWZhdWx0TGFuZztcbiAgICBhd2FpdCBzZXRMYW5ndWFnZShjdXJyZW50TGFuZyk7XG4gICAgdGhpcy5zZXRBcHBTdGF0ZSh7fSk7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRFU1QgSE9PS1Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgaDoge1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgICBzdGF0ZTogQXBwU3RhdGU7XG4gICAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl07XG4gICAgICBhcHA6IEluc3RhbmNlVHlwZTx0eXBlb2YgQXBwPjtcbiAgICAgIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gICAgfTtcbiAgfVxufVxuXG5pZiAoXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UIHx8XG4gIHByb2Nlc3MuZW52LlJFQUNUX0FQUF9WRVJDRUxfRU5WID09PSBcInByZXZpZXdcIlxuKSB7XG4gIHdpbmRvdy5oID0gd2luZG93LmggfHwgKHt9IGFzIFdpbmRvd1tcImhcIl0pO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgZWxlbWVudHM6IHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwPy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2120
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"useDevice\": () => (/* binding */ useDevice),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer)\n/* harmony export */ });\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-runtime */ \"../../../node_modules/react/jsx-runtime.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.browser.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_library__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../data/library */ \"../../data/library.ts\");\n/* harmony import */ var _data_restore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../data/restore */ \"../../data/restore.ts\");\n/* harmony import */ var _element__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../element */ \"../../element/index.ts\");\n/* harmony import */ var _element_binding__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../element/binding */ \"../../element/binding.ts\");\n/* harmony import */ var _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../element/linearElementEditor */ \"../../element/linearElementEditor.ts\");\n/* harmony import */ var _element_mutateElement__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../element/mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _element_newElement__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../element/newElement */ \"../../element/newElement.ts\");\n/* harmony import */ var _element_typeChecks__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../element/typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _gesture__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../gesture */ \"../../gesture.ts\");\n/* harmony import */ var _groups__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../groups */ \"../../groups.ts\");\n/* harmony import */ var _history__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../history */ \"../../history.ts\");\n/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../i18n */ \"../../i18n.ts\");\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../math */ \"../../math.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../renderer/renderElement */ \"../../renderer/renderElement.ts\");\n/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../scene */ \"../../scene/index.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _scene_zoom__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../scene/zoom */ \"../../scene/zoom.ts\");\n/* harmony import */ var _shapes__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../shapes */ \"../../shapes.tsx\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./ContextMenu */ \"../../components/ContextMenu.tsx\");\n/* harmony import */ var _LayerUI__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LayerUI */ \"../../components/LayerUI.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_41__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\n/* harmony import */ var _element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/Hyperlink */ \"../../element/Hyperlink.tsx\");\n/* harmony import */ var _element_transformHandles__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ../element/transformHandles */ \"../../element/transformHandles.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst TIMES_AGGR = {};\nconst TIMES_AVG = {};\nwindow.DEBUG_LOG_TIMES = true;\nsetInterval(() => {\n if (window.DEBUG_LOG_TIMES) {\n for (const [name, { t, times }] of Object.entries(TIMES_AGGR)) {\n if (times.length) {\n console.info(name, times.reduce((a, b) => a + b), times.sort((a, b) => a - b));\n TIMES_AGGR[name] = { t, times: [] };\n }\n }\n for (const [name, { times }] of Object.entries(TIMES_AVG)) {\n if (times.length) {\n console.info(name, parseFloat((times.reduce((a, b) => a + b) / times.length).toPrecision(5)), times.sort((a, b) => a - b));\n TIMES_AVG[name] = { times: [] };\n }\n }\n }\n}, 1000);\nwindow.logTime = (name, time) => {\n const { t, times } = (TIMES_AGGR[name] = TIMES_AGGR[name] || {\n t: 0,\n times: [],\n });\n if (t) {\n times.push(time != null ? time : Date.now() - t);\n }\n TIMES_AGGR[name].t = Date.now();\n};\nwindow.logTimeAverage = (name, time) => {\n const { times } = (TIMES_AVG[name] = TIMES_AVG[name] || { times: [] });\n times.push(time);\n};\nconst deviceContextInitialValue = {\n isSmScreen: false,\n isMobile: false,\n isTouchScreen: false,\n canDeviceFitSidebar: false,\n};\nconst DeviceContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(deviceContextInitialValue);\nconst useDevice = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(DeviceContext);\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\nlet didTapTwice = false;\nlet tappedTwiceTimer = 0;\nlet cursorX = 0;\nlet cursorY = 0;\nlet isHoldingSpace = false;\nlet isPanning = false;\nlet isDraggingScrollBar = false;\nlet currentScrollBars = { horizontal: null, vertical: null };\nlet touchTimeout = 0;\nlet invalidateContextMenu = false;\n// remove this hack when we can sync render & resizeObserver (state update)\n// to rAF. See #5439\nlet THROTTLE_NEXT_RENDER = true;\nlet lastPointerUp = null;\nconst gesture = {\n pointers: new Map(),\n lastCenter: null,\n initialDistance: null,\n initialScale: null,\n};\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\n constructor(props) {\n var _a;\n super(props);\n this.canvas = null;\n this.rc = null;\n this.unmounted = false;\n this.device = deviceContextInitialValue;\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\n this.files = {};\n this.imageCache = new Map();\n this.lastPointerDown = null;\n this.lastPointerUp = null;\n this.contextMenuOpen = false;\n this.lastScenePointer = null;\n this.__renderUI = true;\n this.focusContainer = () => {\n var _a;\n if (this.props.autoFocus) {\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n }\n };\n this.getSceneElementsIncludingDeleted = () => {\n return this.scene.getElementsIncludingDeleted();\n };\n this.getSceneElements = () => {\n return this.scene.getNonDeletedElements();\n };\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\n var _a, _b, _c, _d, _e, _f;\n // Since context menu closes when action triggered so setting to false\n this.contextMenuOpen = false;\n if (this.unmounted || actionResult === false) {\n return;\n }\n let editingElement = null;\n if (actionResult.elements) {\n actionResult.elements.forEach((element) => {\n var _a;\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\n this.state.editingElement !== element &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n editingElement = element;\n }\n });\n this.scene.replaceAllElements(actionResult.elements);\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n }\n if (actionResult.files) {\n this.files = actionResult.replaceFiles\n ? actionResult.files\n : Object.assign(Object.assign({}, this.files), actionResult.files);\n this.addNewImagesToImageCache();\n }\n if (actionResult.appState || editingElement) {\n if (actionResult.commitToHistory) {\n this.history.resumeRecording();\n }\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\n let theme = ((_d = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _d === void 0 ? void 0 : _d.theme) || _constants__WEBPACK_IMPORTED_MODULE_12__.THEME.LIGHT;\n let name = (_f = (_e = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : this.state.name;\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\n viewModeEnabled = this.props.viewModeEnabled;\n }\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\n zenModeEnabled = this.props.zenModeEnabled;\n }\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null;\n }\n if (typeof this.props.theme !== \"undefined\") {\n theme = this.props.theme;\n }\n if (typeof this.props.name !== \"undefined\") {\n name = this.props.name;\n }\n this.setState((state) => {\n var _a;\n // using Object.assign instead of spread to fool TS 4.2.2+ into\n // regarding the resulting type as not containing undefined\n // (which the following expression will never contain)\n return Object.assign(actionResult.appState || {}, {\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\n viewModeEnabled,\n zenModeEnabled,\n gridSize,\n theme,\n name,\n });\n }, () => {\n if (actionResult.syncHistory) {\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\n }\n });\n }\n });\n // Lifecycle\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isHoldingSpace = false;\n this.setState({ isBindingEnabled: true });\n });\n this.onUnload = () => {\n this.onBlur();\n };\n this.disableEvent = (event) => {\n event.preventDefault();\n };\n this.onFontLoaded = () => {\n this.scene.getElementsIncludingDeleted().forEach((element) => {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.onSceneUpdated();\n };\n this.resetHistory = () => {\n this.history.clear();\n };\n /**\n * Resets scene & history.\n * ! Do not use to clear scene user action !\n */\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\n this.scene.replaceAllElements([]);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\n this.resetHistory();\n });\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\n var _b;\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\n if (!launchParams.files.length) {\n return;\n }\n const fileHandle = launchParams.files[0];\n const blob = yield fileHandle.getFile();\n this.loadFileToCanvas(new File([blob], blob.name || \"\", { type: blob.type }), fileHandle);\n }));\n }\n if (!this.state.isLoading) {\n this.setState({ isLoading: true });\n }\n let initialData = null;\n try {\n initialData = (yield this.props.initialData) || null;\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\n this.library\n .updateLibrary({\n libraryItems: initialData.libraryItems,\n merge: true,\n })\n .catch((error) => {\n console.error(error);\n });\n }\n }\n catch (error) {\n console.error(error);\n initialData = {\n appState: {\n errorMessage: error.message ||\n \"Encountered an error during importing or restoring scene data\",\n },\n };\n }\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\n scene.appState = Object.assign(Object.assign({}, scene.appState), { \n // we're falling back to current (pre-init) state when deciding\n // whether to open the library, to handle a case where we\n // update the state outside of initialData (e.g. when loading the app\n // with a library install link, which should auto-open the library)\n isLibraryOpen: ((_b = initialData === null || initialData === void 0 ? void 0 : initialData.appState) === null || _b === void 0 ? void 0 : _b.isLibraryOpen) || this.state.isLibraryOpen, activeTool: scene.appState.activeTool.type === \"image\"\n ? Object.assign(Object.assign({}, scene.appState.activeTool), { type: \"selection\" }) : scene.appState.activeTool, isLoading: false, toast: this.state.toast });\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\n scene.appState = Object.assign(Object.assign({}, scene.appState), (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(scene.elements, Object.assign(Object.assign({}, scene.appState), { width: this.state.width, height: this.state.height, offsetTop: this.state.offsetTop, offsetLeft: this.state.offsetLeft }), null));\n }\n this.resetHistory();\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\n });\n this.refreshDeviceState = (container) => {\n const { width, height } = container.getBoundingClientRect();\n const sidebarBreakpoint = this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH;\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH,\n isMobile: width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT ||\n (height < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE),\n canDeviceFitSidebar: width > sidebarBreakpoint,\n });\n };\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n this.scene\n .getElementsIncludingDeleted()\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\n this.setState({});\n });\n this.renderScene = () => {\n const cursorButton = {};\n const pointerViewportCoords = {};\n const remoteSelectedElementIds = {};\n const pointerUsernames = {};\n const pointerUserStates = {};\n this.state.collaborators.forEach((user, socketId) => {\n if (user.selectedElementIds) {\n for (const id of Object.keys(user.selectedElementIds)) {\n if (!(id in remoteSelectedElementIds)) {\n remoteSelectedElementIds[id] = [];\n }\n remoteSelectedElementIds[id].push(socketId);\n }\n }\n if (!user.pointer) {\n return;\n }\n if (user.username) {\n pointerUsernames[socketId] = user.username;\n }\n if (user.userState) {\n pointerUserStates[socketId] = user.userState;\n }\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: user.pointer.x,\n sceneY: user.pointer.y,\n }, this.state);\n cursorButton[socketId] = user.button;\n });\n const renderingElements = this.scene\n .getNonDeletedElements()\n .filter((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\n if (\n // not placed on canvas yet (but in elements array)\n this.state.pendingImageElementId === element.id) {\n return false;\n }\n }\n // don't render text element that's being currently edited (it's\n // rendered on remote only)\n return (!this.state.editingElement ||\n this.state.editingElement.type !== \"text\" ||\n element.id !== this.state.editingElement.id);\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_28__.renderScene)({\n elements: renderingElements,\n appState: this.state,\n scale: window.devicePixelRatio,\n rc: this.rc,\n canvas: this.canvas,\n renderConfig: {\n scrollX: this.state.scrollX,\n scrollY: this.state.scrollY,\n viewBackgroundColor: this.state.viewBackgroundColor,\n zoom: this.state.zoom,\n remotePointerViewportCoords: pointerViewportCoords,\n remotePointerButton: cursorButton,\n remoteSelectedElementIds,\n remotePointerUsernames: pointerUsernames,\n remotePointerUserStates: pointerUserStates,\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\n theme: this.state.theme,\n imageCache: this.imageCache,\n isExporting: false,\n renderScrollbars: !this.device.isMobile,\n },\n callback: ({ atLeastOneVisibleElement, scrollBars }) => {\n if (scrollBars) {\n currentScrollBars = scrollBars;\n }\n const scrolledOutside = \n // hide when editing text\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? false\n : !atLeastOneVisibleElement && renderingElements.length > 0;\n if (this.state.scrolledOutside !== scrolledOutside) {\n this.setState({ scrolledOutside });\n }\n this.scheduleImageRefresh();\n },\n }, THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true);\n if (!THROTTLE_NEXT_RENDER) {\n THROTTLE_NEXT_RENDER = true;\n }\n };\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\n this.setState((state) => {\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\n return null;\n }\n return { offsetTop, offsetLeft };\n });\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.SCROLL_TIMEOUT);\n // Copy/paste\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.cutAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n var _a;\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n return;\n }\n this.copyAll();\n event.preventDefault();\n event.stopPropagation();\n });\n this.cutAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCut, \"keyboard\");\n };\n this.copyAll = () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, \"keyboard\");\n };\n this.onTapStart = (event) => {\n // fix for Apple Pencil Scribble\n // On Android, preventing the event would disable contextMenu on tap-hold\n if (!_keys__WEBPACK_IMPORTED_MODULE_26__.isAndroid) {\n event.preventDefault();\n }\n if (!didTapTwice) {\n didTapTwice = true;\n clearTimeout(tappedTwiceTimer);\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_12__.TAP_TWICE_TIMEOUT);\n return;\n }\n // insert text only if we tapped twice with a single finger\n // event.touches.length === 1 will also prevent inserting text when user's zooming\n if (didTapTwice && event.touches.length === 1) {\n const [touch] = event.touches;\n // @ts-ignore\n this.handleCanvasDoubleClick({\n clientX: touch.clientX,\n clientY: touch.clientY,\n });\n didTapTwice = false;\n clearTimeout(tappedTwiceTimer);\n }\n if (_keys__WEBPACK_IMPORTED_MODULE_26__.isAndroid) {\n event.preventDefault();\n }\n if (event.touches.length === 2) {\n this.setState({\n selectedElementIds: {},\n });\n }\n };\n this.onTapEnd = (event) => {\n this.resetContextMenuTimer();\n if (event.touches.length > 0) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n else {\n gesture.pointers.clear();\n }\n };\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\n var _c, _d;\n // #686\n const target = document.activeElement;\n const isExcalidrawActive = (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);\n if (!isExcalidrawActive) {\n return;\n }\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\n if (\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\n // thus these checks don't make sense\n event &&\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\n return;\n }\n // must be called in the same frame (thus before any awaits) as the paste\n // event else some browsers (FF...) will clear the clipboardData\n // (something something security)\n let file = (_d = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _d === void 0 ? void 0 : _d.files[0];\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_11__.parseClipboard)(event);\n if (!file && data.text) {\n const string = data.text.trim();\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\n // ignore SVG validation/normalization which will be done during image\n // initialization\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(string);\n }\n }\n // prefer spreadsheet data over image file (MS Office/Libre Office)\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file) && !data.spreadsheet) {\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n if (this.props.onPaste) {\n try {\n if ((yield this.props.onPaste(data, event)) === false) {\n return;\n }\n }\n catch (error) {\n console.error(error);\n }\n }\n if (data.errorMessage) {\n this.setState({ errorMessage: data.errorMessage });\n }\n else if (data.spreadsheet) {\n this.setState({\n pasteDialog: {\n data: data.spreadsheet,\n shown: true,\n },\n });\n }\n else if (data.elements) {\n this.addElementsFromPasteOrLibrary({\n elements: data.elements,\n files: data.files || null,\n position: \"cursor\",\n });\n }\n else if (data.text) {\n this.addTextFromPaste(data.text);\n }\n this.setActiveTool({ type: \"selection\" });\n event === null || event === void 0 ? void 0 : event.preventDefault();\n }));\n this.addElementsFromPasteOrLibrary = (opts) => {\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\n const clientX = typeof opts.position === \"object\"\n ? opts.position.clientX\n : opts.position === \"cursor\"\n ? cursorX\n : this.state.width / 2 + this.state.offsetLeft;\n const clientY = typeof opts.position === \"object\"\n ? opts.position.clientY\n : opts.position === \"cursor\"\n ? cursorY\n : this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const dx = x - elementsCenterX;\n const dy = y - elementsCenterY;\n const groupIdMap = new Map();\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\n const oldIdToDuplicatedId = new Map();\n const newElements = elements.map((element) => {\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\n x: element.x + gridX - minX,\n y: element.y + gridY - minY,\n });\n oldIdToDuplicatedId.set(element.id, newElement.id);\n return newElement;\n });\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\n const nextElements = [\n ...this.scene.getElementsIncludingDeleted(),\n ...newElements,\n ];\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\n if (opts.files) {\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\n }\n this.scene.replaceAllElements(nextElements);\n this.history.resumeRecording();\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: this.state.isLibraryOpen && this.device.canDeviceFitSidebar\n ? this.state.isLibraryMenuDocked\n : false, selectedElementIds: newElements.reduce((acc, element) => {\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(element)) {\n acc[element.id] = true;\n }\n return acc;\n }, {}), selectedGroupIds: {} }), this.scene.getNonDeletedElements()), () => {\n if (opts.files) {\n this.addNewImagesToImageCache();\n }\n });\n this.setActiveTool({ type: \"selection\" });\n };\n // Collaboration\n this.setAppState = (obj) => {\n this.setState(obj);\n };\n this.removePointer = (event) => {\n if (touchTimeout) {\n this.resetContextMenuTimer();\n }\n gesture.pointers.delete(event.pointerId);\n };\n this.toggleLock = (source = \"ui\") => {\n if (!this.state.activeTool.locked) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", \"toggleLock\", `${source} (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setState((prevState) => {\n return {\n activeTool: Object.assign(Object.assign(Object.assign({}, prevState.activeTool), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, prevState.activeTool.locked\n ? { type: \"selection\" }\n : prevState.activeTool)), { locked: !prevState.activeTool.locked }),\n };\n });\n };\n this.togglePenMode = () => {\n this.setState((prevState) => {\n return {\n penMode: !prevState.penMode,\n };\n });\n };\n this.scrollToContent = (target = this.scene.getNonDeletedElements()) => {\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\n };\n this.setToast = (toast) => {\n this.setState({ toast });\n };\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\n try {\n const webShareTargetCache = yield caches.open(\"web-share-target\");\n const response = yield webShareTargetCache.match(\"shared-file\");\n if (response) {\n const blob = yield response.blob();\n const file = new File([blob], blob.name || \"\", { type: blob.type });\n this.loadFileToCanvas(file, null);\n yield webShareTargetCache.delete(\"shared-file\");\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_12__.APP_NAME, window.location.pathname);\n }\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n });\n /** adds supplied files to existing files in the appState */\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\n const filesMap = files.reduce((acc, fileData) => {\n acc.set(fileData.id, fileData);\n return acc;\n }, new Map());\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\n this.scene.getNonDeletedElements().forEach((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n filesMap.has(element.fileId)) {\n this.imageCache.delete(element.fileId);\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n });\n this.scene.informMutation();\n this.addNewImagesToImageCache();\n });\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\n if (sceneData.commitToHistory) {\n this.history.resumeRecording();\n }\n if (sceneData.appState) {\n this.setState(sceneData.appState);\n }\n if (sceneData.elements) {\n this.scene.replaceAllElements(sceneData.elements);\n }\n if (sceneData.collaborators) {\n this.setState({ collaborators: sceneData.collaborators });\n }\n });\n this.onSceneUpdated = () => {\n this.setState({});\n };\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n cursorX = event.clientX;\n cursorY = event.clientY;\n });\n // Input handling\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // normalize `event.key` when CapsLock is pressed #2372\n if (\"Proxy\" in window &&\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\n event = new Proxy(event, {\n get(ev, prop) {\n const value = ev[prop];\n if (typeof value === \"function\") {\n // fix for Proxies hijacking `this`\n return value.bind(ev);\n }\n return prop === \"key\"\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\n // it back\n event.shiftKey\n ? ev.key.toUpperCase()\n : ev.key.toLowerCase()\n : value;\n },\n });\n }\n // prevent browser zoom in input fields\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.MINUS || event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.EQUAL) {\n event.preventDefault();\n return;\n }\n }\n // bail if\n if (\n // inside an input\n ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) &&\n // unless pressing escape (finalize action)\n event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\n // or unless using arrows (to move between buttons)\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\n this.setState({\n showHelpDialog: true,\n });\n }\n if (this.actionManager.handleKeyDown(event)) {\n return;\n }\n if (this.state.viewModeEnabled) {\n return;\n }\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: false });\n }\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\n const nextState = !this.state.isLibraryOpen;\n this.setState({ isLibraryOpen: nextState });\n // track only openings\n if (nextState) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"library\", \"toggleLibrary (open)\", `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const step = (this.state.gridSize &&\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT\n : this.state.gridSize)) ||\n (event.shiftKey\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\n : _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_TRANSLATE_AMOUNT);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state, true);\n let offsetX = 0;\n let offsetY = 0;\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\n offsetX = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\n offsetX = step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\n offsetY = -step;\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\n offsetY = step;\n }\n selectedElements.forEach((element) => {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n x: element.x + offsetX,\n y: element.y + offsetY,\n });\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\n simultaneouslyUpdated: selectedElements,\n });\n });\n this.maybeSuggestBindingForAll(selectedElements);\n event.preventDefault();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !==\n selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n }\n }\n else {\n const selectedElement = selectedElements[0];\n this.startTextEditing({\n sceneX: selectedElement.x + selectedElement.width / 2,\n sceneY: selectedElement.y + selectedElement.height / 2,\n shouldBind: true,\n });\n event.preventDefault();\n return;\n }\n }\n }\n else if (!event.ctrlKey &&\n !event.altKey &&\n !event.metaKey &&\n this.state.draggingElement === null) {\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\n if (shape) {\n if (this.state.activeTool.type !== shape) {\n (0,_analytics__WEBPACK_IMPORTED_MODULE_9__.trackEvent)(\"toolbar\", shape, `keyboard (${this.device.isMobile ? \"mobile\" : \"desktop\"})`);\n }\n this.setActiveTool({ type: shape });\n event.stopPropagation();\n }\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\n this.toggleLock(\"keyboard\");\n event.stopPropagation();\n }\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\n isHoldingSpace = true;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n event.preventDefault();\n }\n if ((event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) &&\n !event.altKey &&\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (this.state.activeTool.type === \"selection\" &&\n !selectedElements.length) {\n return;\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.activeTool.type) ||\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\n this.setState({ openPopup: \"backgroundColorPicker\" });\n event.stopPropagation();\n }\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\n this.setState({ openPopup: \"strokeColorPicker\" });\n event.stopPropagation();\n }\n }\n });\n this.onWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // prevent browser pinch zoom on DOM elements\n if (!(event.target instanceof HTMLCanvasElement) && event.ctrlKey) {\n event.preventDefault();\n }\n });\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (this.state.activeTool.type === \"selection\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n isHoldingSpace = false;\n }\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\n this.setState({ isBindingEnabled: true });\n }\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\n this.setState({ suggestedBindings: [] });\n }\n });\n this.setActiveTool = (tool) => {\n const nextActiveTool = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, tool);\n if (!isHoldingSpace) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\n this.focusContainer();\n }\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(nextActiveTool.type)) {\n this.setState({ suggestedBindings: [] });\n }\n if (nextActiveTool.type === \"image\") {\n this.onImageAction();\n }\n if (nextActiveTool.type !== \"selection\") {\n this.setState({\n activeTool: nextActiveTool,\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n else {\n this.setState({ activeTool: nextActiveTool });\n }\n };\n this.setCursor = (cursor) => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, cursor);\n };\n this.resetCursor = () => {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n };\n /**\n * returns whether user is making a gesture with >= 2 fingers (points)\n * on o touch screen (not on a trackpad). Currently only relates to Darwin\n * (iOS/iPadOS,MacOS), but may work on other devices in the future if\n * GestureEvent is standardized.\n */\n this.isTouchScreenMultiTouchGesture = () => {\n // we don't want to deselect when using trackpad, and multi-point gestures\n // only work on touch screens, so checking for >= pointers means we're on a\n // touchscreen\n return gesture.pointers.size >= 2;\n };\n // fires only on Safari\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // we only want to deselect on touch screens because user may have selected\n // elements by mistake while zooming\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n selectedElementIds: {},\n });\n }\n gesture.initialScale = this.state.zoom.value;\n });\n // fires only on Safari\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // onGestureChange only has zoom factor but not the center.\n // If we're on iPad or iPhone, then we recognize multi-touch and will\n // zoom in at the right location in the touchmove handler\n // (handleCanvasPointerMove).\n //\n // On Macbook trackpad, we don't have those events so will zoom in at the\n // current location instead.\n //\n // As such, bail from this handler on touch devices.\n if (this.isTouchScreenMultiTouchGesture()) {\n return;\n }\n const initialScale = gesture.initialScale;\n if (initialScale) {\n this.setState((state) => (Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale),\n }, state))));\n }\n });\n // fires only on Safari\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n // reselect elements only on touch screens (see onGestureStart)\n if (this.isTouchScreenMultiTouchGesture()) {\n this.setState({\n previousSelectedElementIds: {},\n selectedElementIds: this.state.previousSelectedElementIds,\n });\n }\n gesture.initialScale = null;\n });\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\n var _a, _b;\n let parentCenterPosition = insertAtParentCenter &&\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n let existingTextElement = null;\n let container = null;\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(selectedElements[0])) {\n existingTextElement = selectedElements[0];\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(selectedElements[0], false)) {\n existingTextElement = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(selectedElements[0]);\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n }\n else {\n existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\n }\n // bind to container when shouldBind is true or\n // clicked on center of container\n if (!container &&\n !existingTextElement &&\n (shouldBind || parentCenterPosition)) {\n container = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getNonDeletedElements()\n .filter((ele) => (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isTextBindableContainer)(ele, false) && !(0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getBoundTextElement)(ele)), sceneX, sceneY);\n }\n if (!existingTextElement && container) {\n const fontString = {\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n };\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\n const newHeight = Math.max(container.height, minHeight);\n const newWidth = Math.max(container.width, minWidth);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\n sceneX = container.x + newWidth / 2;\n sceneY = container.y + newHeight / 2;\n if (parentCenterPosition) {\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\n }\n }\n const element = existingTextElement\n ? existingTextElement\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x: parentCenterPosition\n ? parentCenterPosition.elementCenterX\n : sceneX,\n y: parentCenterPosition\n ? parentCenterPosition.elementCenterY\n : sceneY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n text: \"\",\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: parentCenterPosition\n ? \"center\"\n : this.state.currentItemTextAlign,\n verticalAlign: parentCenterPosition\n ? _constants__WEBPACK_IMPORTED_MODULE_12__.VERTICAL_ALIGN.MIDDLE\n : _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\n groupIds: (_b = container === null || container === void 0 ? void 0 : container.groupIds) !== null && _b !== void 0 ? _b : [],\n locked: false,\n });\n this.setState({ editingElement: element });\n if (!existingTextElement) {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n // case: creating new text not centered to parent element → offset Y\n // so that the text is centered to cursor position\n if (!parentCenterPosition) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n y: element.y - element.baseline / 2,\n });\n }\n }\n this.setState({\n editingElement: element,\n });\n this.handleTextWysiwyg(element, {\n isExistingElement: !!existingTextElement,\n });\n };\n this.handleCanvasDoubleClick = (event) => {\n // case: double-clicking with arrow/line tool selected would both create\n // text and enter multiElement mode\n if (this.state.multiElement) {\n return;\n }\n // we should only be able to double click when mode is selection\n if (this.state.activeTool.type !== \"selection\") {\n return;\n }\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\n if (!this.state.editingLinearElement ||\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\n this.history.resumeRecording();\n this.setState({\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\n });\n }\n return;\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\n if (selectedGroupIds.length > 0) {\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\n const selectedGroupId = hitElement &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\n if (selectedGroupId) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { editingGroupId: selectedGroupId, selectedElementIds: { [hitElement.id]: true }, selectedGroupIds: {} }), this.scene.getNonDeletedElements()));\n return;\n }\n }\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.length === 1) {\n const selectedElement = selectedElements[0];\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\n if (canBindText) {\n sceneX = selectedElement.x + selectedElement.width / 2;\n sceneY = selectedElement.y + selectedElement.height / 2;\n }\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\n });\n }\n };\n this.getElementLinkAtPosition = (scenePointer, hitElement) => {\n // Reversing so we traverse the elements in decreasing order\n // of z-index\n const elements = this.scene.getNonDeletedElements().slice().reverse();\n let hitElementIndex = Infinity;\n return elements.find((element, index) => {\n if (hitElement && element.id === hitElement.id) {\n hitElementIndex = index;\n }\n return (element.link &&\n index <= hitElementIndex &&\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(element, this.state, [scenePointer.x, scenePointer.y], this.device.isMobile));\n });\n };\n this.redirectToLink = (event, isTouchScreen) => {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (!this.hitLinkElement ||\n // For touch screen allow dragging threshold else strict check\n (isTouchScreen && draggedDistance > _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) ||\n (!isTouchScreen && draggedDistance !== 0)) {\n return;\n }\n const lastPointerDownCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerDown, this.state);\n const lastPointerDownHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerDownCoords.x, lastPointerDownCoords.y], this.device.isMobile);\n const lastPointerUpCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(this.lastPointerUp, this.state);\n const lastPointerUpHittingLinkIcon = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isPointHittingLinkIcon)(this.hitLinkElement, this.state, [lastPointerUpCoords.x, lastPointerUpCoords.y], this.device.isMobile);\n if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {\n const url = this.hitLinkElement.link;\n if (url) {\n let customEvent;\n if (this.props.onLinkOpen) {\n customEvent = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.wrapEvent)(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.EXCALIDRAW_LINK, event.nativeEvent);\n this.props.onLinkOpen(this.hitLinkElement, customEvent);\n }\n if (!(customEvent === null || customEvent === void 0 ? void 0 : customEvent.defaultPrevented)) {\n const target = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.isLocalLink)(url) ? \"_self\" : \"_blank\";\n const newWindow = window.open(undefined, target);\n // https://mathiasbynens.github.io/rel-noopener/\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location = (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.normalizeLink)(url);\n }\n }\n }\n }\n };\n this.handleCanvasPointerMove = (event) => {\n var _a;\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\n if (gesture.pointers.has(event.pointerId)) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n }\n const initialScale = gesture.initialScale;\n if (gesture.pointers.size === 2 &&\n gesture.lastCenter &&\n initialScale &&\n gesture.initialDistance) {\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n const deltaX = center.x - gesture.lastCenter.x;\n const deltaY = center.y - gesture.lastCenter.y;\n gesture.lastCenter = center;\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n const scaleFactor = this.state.activeTool.type === \"freedraw\" && this.state.penMode\n ? 1\n : distance / gesture.initialDistance;\n const nextZoom = scaleFactor\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor)\n : this.state.zoom.value;\n this.setState((state) => {\n const zoomState = (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: center.x,\n viewportY: center.y,\n nextZoom,\n }, state);\n return {\n zoom: zoomState.zoom,\n scrollX: zoomState.scrollX + deltaX / nextZoom,\n scrollY: zoomState.scrollY + deltaY / nextZoom,\n shouldCacheIgnoreZoom: true,\n };\n });\n this.resetShouldCacheIgnoreZoomDebounced();\n }\n else {\n gesture.lastCenter =\n gesture.initialDistance =\n gesture.initialScale =\n null;\n }\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\n return;\n }\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\n if (!this.state.draggingElement && !this.state.multiElement) {\n if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\n if (editingLinearElement !== this.state.editingLinearElement) {\n // Since we are reading from previous state which is not possible with\n // automatic batching in React 18 hence using flush sync to synchronously\n // update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.\n (0,react_dom__WEBPACK_IMPORTED_MODULE_2__.flushSync)(() => {\n this.setState({ editingLinearElement });\n });\n }\n if (editingLinearElement.lastUncommittedPoint != null) {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n else {\n this.setState({ suggestedBindings: [] });\n }\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.activeTool.type)) {\n // Hovering with a selected tool or creating new linear element via click\n // and point\n const { draggingElement } = this.state;\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\n }\n else {\n this.maybeSuggestBindingAtCursor(scenePointer);\n }\n }\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n const { x: rx, y: ry } = multiElement;\n const { points, lastCommittedPoint } = multiElement;\n const lastPoint = points[points.length - 1];\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n if (lastPoint === lastCommittedPoint) {\n // if we haven't yet created a temp point and we're beyond commit-zone\n // threshold, add a point\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\n });\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n // in this branch, we're inside the commit zone, and no uncommitted\n // point exists. Thus do nothing (don't add/remove points).\n }\n }\n else if (points.length > 2 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: points.slice(0, -1),\n });\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(scenePointerX, scenePointerY, this.state.gridSize);\n const [lastCommittedX, lastCommittedY] = (_a = multiElement === null || multiElement === void 0 ? void 0 : multiElement.lastCommittedPoint) !== null && _a !== void 0 ? _a : [0, 0];\n let dxFromLastCommitted = gridX - rx - lastCommittedX;\n let dyFromLastCommitted = gridY - ry - lastCommittedY;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event)) {\n ({ width: dxFromLastCommitted, height: dyFromLastCommitted } =\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(\n // actual coordinate of the last committed point\n lastCommittedX + rx, lastCommittedY + ry, \n // cursor-grid coordinate\n gridX, gridY));\n }\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n // update last uncommitted point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n points: [\n ...points.slice(0, -1),\n [\n lastCommittedX + dxFromLastCommitted,\n lastCommittedY + dyFromLastCommitted,\n ],\n ],\n });\n }\n return;\n }\n const hasDeselectedButton = Boolean(event.buttons);\n if (hasDeselectedButton ||\n (this.state.activeTool.type !== \"selection\" &&\n this.state.activeTool.type !== \"text\" &&\n this.state.activeTool.type !== \"eraser\")) {\n return;\n }\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 &&\n !isOverScrollBar &&\n !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType &&\n elementWithTransformHandleType.transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\n return;\n }\n }\n else if (selectedElements.length > 1 && !isOverScrollBar) {\n const transformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\n if (transformHandleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType,\n }));\n return;\n }\n }\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n return;\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.showHyperlinkTooltip)(this.hitLinkElement, this.state);\n }\n else {\n (0,_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.hideHyperlinkToolip)();\n if (hitElement &&\n hitElement.link &&\n this.state.selectedElementIds[hitElement.id] &&\n !this.contextMenuOpen &&\n !this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: \"info\" });\n }\n else if (this.state.activeTool.type === \"text\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n }\n else if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else if (isOverScrollBar) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.selectedLinearElement) {\n this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);\n }\n else if (\n // if using cmd/ctrl, we're not dragging\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\n (hitElement ||\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements)) &&\n !(hitElement === null || hitElement === void 0 ? void 0 : hitElement.locked)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n };\n this.handleEraser = (event, pointerDownState, scenePointer) => {\n const updateElementIds = (elements) => {\n elements.forEach((element) => {\n if (element.locked) {\n return;\n }\n idsToUpdate.push(element.id);\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[element.id] &&\n pointerDownState.elementIdsToErase[element.id].erase) {\n pointerDownState.elementIdsToErase[element.id].erase = false;\n }\n }\n else if (!pointerDownState.elementIdsToErase[element.id]) {\n pointerDownState.elementIdsToErase[element.id] = {\n erase: true,\n opacity: element.opacity,\n };\n }\n });\n };\n const idsToUpdate = [];\n const distance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);\n const threshold = 10 / this.state.zoom.value;\n const point = Object.assign({}, pointerDownState.lastCoords);\n let samplingInterval = 0;\n while (samplingInterval <= distance) {\n const hitElements = this.getElementsAtPosition(point.x, point.y);\n updateElementIds(hitElements);\n // Exit since we reached current point\n if (samplingInterval === distance) {\n break;\n }\n // Calculate next point in the line at a distance of sampling interval\n samplingInterval = Math.min(samplingInterval + threshold, distance);\n const distanceRatio = samplingInterval / distance;\n const nextX = (1 - distanceRatio) * point.x + distanceRatio * scenePointer.x;\n const nextY = (1 - distanceRatio) * point.y + distanceRatio * scenePointer.y;\n point.x = nextX;\n point.y = nextY;\n }\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n const id = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) && idsToUpdate.includes(ele.containerId)\n ? ele.containerId\n : ele.id;\n if (idsToUpdate.includes(id)) {\n if (event.altKey) {\n if (pointerDownState.elementIdsToErase[id] &&\n pointerDownState.elementIdsToErase[id].erase === false) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[id].opacity,\n });\n }\n }\n else {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: _constants__WEBPACK_IMPORTED_MODULE_12__.ELEMENT_READY_TO_ERASE_OPACITY,\n });\n }\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n pointerDownState.lastCoords.x = scenePointer.x;\n pointerDownState.lastCoords.y = scenePointer.y;\n };\n // set touch moving for mobile context menu\n this.handleTouchMove = (event) => {\n invalidateContextMenu = true;\n };\n this.handleCanvasPointerDown = (event) => {\n var _a, _b;\n // remove any active selection when we start to interact with canvas\n // (mainly, we care about removing selection outside the component which\n // would prevent our copy handling otherwise)\n const selection = document.getSelection();\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\n selection.removeAllRanges();\n }\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\n this.maybeCleanupAfterMissingPointerUp(event);\n //fires only once, if pen is detected, penMode is enabled\n //the user can disable this by toggling the penMode button\n if (!this.state.penDetected && event.pointerType === \"pen\") {\n this.setState((prevState) => {\n return {\n penMode: true,\n penDetected: true,\n };\n });\n }\n if (!this.device.isTouchScreen &&\n [\"pen\", \"touch\"].includes(event.pointerType)) {\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, { isTouchScreen: true });\n }\n if (isPanning) {\n return;\n }\n this.lastPointerDown = event;\n this.setState({\n lastPointerDownWith: event.pointerType,\n cursorButton: \"down\",\n });\n this.savePointer(event.clientX, event.clientY, \"down\");\n this.updateGestureOnPointerDown(event);\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\n return;\n }\n // only handle left mouse button or touch\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN &&\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.TOUCH) {\n return;\n }\n // don't select while panning\n if (gesture.pointers.size > 1) {\n return;\n }\n // State for the duration of a pointer interaction, which starts with a\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\n const pointerDownState = this.initialPointerDownState(event);\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\n return;\n }\n // Since context menu closes on pointer down so setting to false\n this.contextMenuOpen = false;\n this.clearSelectionIfNotUsingSelection();\n this.updateBindingEnabledOnPointerMove(event);\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\n return;\n }\n const allowOnPointerDown = !this.state.penMode ||\n event.pointerType !== \"touch\" ||\n this.state.activeTool.type === \"selection\" ||\n this.state.activeTool.type === \"text\" ||\n this.state.activeTool.type === \"image\";\n if (!allowOnPointerDown) {\n return;\n }\n if (this.state.activeTool.type === \"text\") {\n this.handleTextOnPointerDown(event, pointerDownState);\n return;\n }\n else if (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\") {\n this.handleLinearElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"image\") {\n // reset image preview on pointerdown\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.CROSSHAIR);\n // retrieve the latest element as the state may be stale\n const pendingImageElement = this.state.pendingImageElementId &&\n this.scene.getElement(this.state.pendingImageElementId);\n if (!pendingImageElement) {\n return;\n }\n this.setState({\n draggingElement: pendingImageElement,\n editingElement: pendingImageElement,\n pendingImageElementId: null,\n multiElement: null,\n });\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(pendingImageElement, {\n x,\n y,\n });\n }\n else if (this.state.activeTool.type === \"freedraw\") {\n this.handleFreeDrawElementOnPointerDown(event, this.state.activeTool.type, pointerDownState);\n }\n else if (this.state.activeTool.type === \"custom\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n else if (this.state.activeTool.type !== \"eraser\") {\n this.createGenericElementOnPointerDown(this.state.activeTool.type, pointerDownState);\n }\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onPointerDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.activeTool, pointerDownState);\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\n lastPointerUp = onPointerUp;\n if (!this.state.viewModeEnabled) {\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, onKeyDown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, onKeyUp);\n pointerDownState.eventListeners.onMove = onPointerMove;\n pointerDownState.eventListeners.onUp = onPointerUp;\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\n }\n };\n this.handleCanvasPointerUp = (event) => {\n this.lastPointerUp = event;\n if (this.device.isTouchScreen) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: event.clientX, clientY: event.clientY }, this.state);\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\n this.hitLinkElement = this.getElementLinkAtPosition(scenePointer, hitElement);\n }\n if (this.hitLinkElement &&\n !this.state.selectedElementIds[this.hitLinkElement.id]) {\n this.redirectToLink(event, this.device.isTouchScreen);\n }\n this.removePointer(event);\n };\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\n // deal with opening context menu on touch devices\n if (event.pointerType === \"touch\") {\n invalidateContextMenu = false;\n if (touchTimeout) {\n // If there's already a touchTimeout, this means that there's another\n // touch down and we are doing another touch, so we shouldn't open the\n // context menu.\n invalidateContextMenu = true;\n }\n else {\n // open the context menu with the first touch's clientX and clientY\n // if the touch is not moving\n touchTimeout = window.setTimeout(() => {\n touchTimeout = 0;\n if (!invalidateContextMenu) {\n this.handleCanvasContextMenu(event);\n }\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.TOUCH_CTX_MENU_TIMEOUT);\n }\n }\n };\n this.resetContextMenuTimer = () => {\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n invalidateContextMenu = false;\n };\n // Returns whether the event is a panning\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\n if (!(gesture.pointers.size <= 1 &&\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.WHEEL ||\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\n this.state.viewModeEnabled)) ||\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return false;\n }\n isPanning = true;\n event.preventDefault();\n let nextPastePrevented = false;\n const isLinux = /Linux/.test(window.navigator.platform);\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRABBING);\n let { clientX: lastX, clientY: lastY } = event;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const deltaX = lastX - event.clientX;\n const deltaY = lastY - event.clientY;\n lastX = event.clientX;\n lastY = event.clientY;\n /*\n * Prevent paste event if we move while middle clicking on Linux.\n * See issue #1383.\n */\n if (isLinux &&\n !nextPastePrevented &&\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\n nextPastePrevented = true;\n /* Prevent the next paste event */\n const preventNextPaste = (event) => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n event.stopPropagation();\n };\n /*\n * Reenable next paste in case of disabled middle click paste for\n * any reason:\n * - right click paste\n * - empty clipboard\n */\n const enableNextPaste = () => {\n setTimeout(() => {\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }, 100);\n };\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, preventNextPaste);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, enableNextPaste);\n }\n this.setState({\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\n });\n });\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\n lastPointerUp = null;\n isPanning = false;\n if (!isHoldingSpace) {\n if (this.state.viewModeEnabled) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n }\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n onPointerMove.flush();\n }));\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, teardown);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove, {\n passive: true,\n });\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, teardown);\n return true;\n };\n this.clearSelectionIfNotUsingSelection = () => {\n if (this.state.activeTool.type !== \"selection\") {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n };\n /**\n * @returns whether the pointer event has been completely handled\n */\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\n var _a;\n if (this.state.activeTool.type === \"selection\") {\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n if (elementWithTransformHandleType != null) {\n this.setState({\n resizingElement: elementWithTransformHandleType.element,\n });\n pointerDownState.resize.handleType =\n elementWithTransformHandleType.transformHandleType;\n }\n }\n else if (selectedElements.length > 1) {\n pointerDownState.resize.handleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getTransformHandleTypeFromCoords)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\n }\n if (pointerDownState.resize.handleType) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\n transformHandleType: pointerDownState.resize.handleType,\n }));\n pointerDownState.resize.isResizing = true;\n pointerDownState.resize.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeOffsetXY)(pointerDownState.resize.handleType, selectedElements, pointerDownState.origin.x, pointerDownState.origin.y));\n if (selectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\n selectedElements[0].points.length === 2) {\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\n }\n }\n else {\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, this.history, pointerDownState.origin, linearElementEditor);\n if (ret.hitElement) {\n pointerDownState.hit.element = ret.hitElement;\n }\n if (ret.linearElementEditor) {\n this.setState({ selectedLinearElement: ret.linearElementEditor });\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: ret.linearElementEditor });\n }\n }\n if (ret.didAddPoint && !ret.isMidPoint) {\n return true;\n }\n }\n // hitElement may already be set above, so check first\n pointerDownState.hit.element =\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n if (pointerDownState.hit.element) {\n // Early return if pointer is hitting link icon\n const hitLinkElement = this.getElementLinkAtPosition({\n x: pointerDownState.origin.x,\n y: pointerDownState.origin.y,\n }, pointerDownState.hit.element);\n if (hitLinkElement) {\n return false;\n }\n }\n // For overlapped elements one position may hit\n // multiple elements\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\n const hitElement = pointerDownState.hit.element;\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n if ((hitElement === null || !someHitElementIsSelected) &&\n !event.shiftKey &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.clearSelection(hitElement);\n }\n if (this.state.editingLinearElement) {\n this.setState({\n selectedElementIds: {\n [this.state.editingLinearElement.elementId]: true,\n },\n });\n // If we click on something\n }\n else if (hitElement != null) {\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\n if (!this.state.selectedElementIds[hitElement.id]) {\n pointerDownState.hit.wasAddedToSelection = true;\n }\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\n // mark as not completely handled so as to allow dragging etc.\n return false;\n }\n // deselect if item is selected\n // if shift is not clicked, this will always return true\n // otherwise, it will trigger selection based on current\n // state of the box\n if (!this.state.selectedElementIds[hitElement.id]) {\n // if we are currently editing a group, exiting editing mode and deselect the group.\n if (this.state.editingGroupId &&\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n // Add hit element to selection. At this point if we're not holding\n // SHIFT the previously selected element(s) were deselected above\n // (make sure you use setState updater to use latest state)\n if (!someHitElementIsSelected &&\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\n this.setState((prevState) => {\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }), showHyperlinkPopup: hitElement.link ? \"info\" : false }), this.scene.getNonDeletedElements());\n });\n pointerDownState.hit.wasAddedToSelection = true;\n }\n }\n }\n this.setState({\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n }\n return false;\n };\n this.handleTextOnPointerDown = (event, pointerDownState) => {\n // if we're currently still editing text, clicking outside\n // should only finalize it, not create another (irrespective\n // of state.activeTool.locked)\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\n return;\n }\n let sceneX = pointerDownState.origin.x;\n let sceneY = pointerDownState.origin.y;\n const element = this.getElementAtPosition(sceneX, sceneY, {\n includeBoundTextElement: true,\n });\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\n if (canBindText) {\n sceneX = element.x + element.width / 2;\n sceneY = element.y + element.height / 2;\n }\n this.startTextEditing({\n sceneX,\n sceneY,\n shouldBind: false,\n insertAtParentCenter: !event.altKey,\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n if (!this.state.activeTool.locked) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n };\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\n // Begin a mark capture. This does not have to update state yet.\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n simulatePressure: event.pressure === 0.5,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n const pressures = element.simulatePressure\n ? element.pressures\n : [...element.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [[0, 0]],\n pressures,\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n };\n this.createImageElement = ({ sceneX, sceneY, }) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\n type: \"image\",\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n locked: false,\n });\n return element;\n };\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\n if (this.state.multiElement) {\n const { multiElement } = this.state;\n // finalize if completing a loop\n if (multiElement.type === \"line\" &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\n // clicking inside commit zone → finalize arrow\n if (multiElement.points.length > 1 &&\n lastCommittedPoint &&\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_12__.LINE_CONFIRM_THRESHOLD) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\n }));\n // clicking outside commit zone → update reference for last committed\n // point\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\n });\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\n an arrow, we want it to be null for both. Otherwise, we want it to use the\n values from appState. */\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\n : [null, null];\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\n startArrowhead,\n endArrowhead,\n locked: false,\n });\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\n }));\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\n points: [...element.points, [0, 0]],\n });\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n draggingElement: element,\n editingElement: element,\n startBoundElement: boundElement,\n suggestedBindings: [],\n });\n }\n };\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\n type: elementType,\n x: gridX,\n y: gridY,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n locked: false,\n });\n if (element.type === \"selection\") {\n this.setState({\n selectionElement: element,\n draggingElement: element,\n });\n }\n else {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({\n multiElement: null,\n draggingElement: element,\n editingElement: element,\n });\n }\n };\n this.restoreReadyToEraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.id].opacity,\n });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, {\n opacity: pointerDownState.elementIdsToErase[ele.containerId].opacity,\n });\n }\n return ele;\n });\n this.scene.replaceAllElements(elements);\n };\n this.eraseElements = (pointerDownState) => {\n const elements = this.scene.getElementsIncludingDeleted().map((ele) => {\n if (pointerDownState.elementIdsToErase[ele.id] &&\n pointerDownState.elementIdsToErase[ele.id].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBoundToContainer)(ele) &&\n pointerDownState.elementIdsToErase[ele.containerId] &&\n pointerDownState.elementIdsToErase[ele.containerId].erase) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(ele, { isDeleted: true });\n }\n return ele;\n });\n this.history.resumeRecording();\n this.scene.replaceAllElements(elements);\n };\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\n var _e, _f, _g, _h;\n // at this point this should be guaranteed image file, but we do this check\n // to satisfy TS down the line\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(imageFile)) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\n }\n const mimeType = imageFile.type;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.normalizeSVG)(yield imageFile.text()), imageFile.name);\n }\n catch (error) {\n console.warn(error);\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\n }\n }\n // generate image id (by default the file digest) before any\n // resizing/compression takes place to keep it more portable\n const fileId = yield (((_f = (_e = this.props).generateIdForFile) === null || _f === void 0 ? void 0 : _f.call(_e, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.generateIdFromFile)(imageFile));\n if (!fileId) {\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\n }\n const existingFileData = this.files[fileId];\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\n try {\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\n });\n }\n catch (error) {\n console.error(\"error trying to resing image file on insertion\", error);\n }\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES) {\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_12__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\n }));\n }\n }\n if (showCursorImagePreview) {\n const dataURL = (_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL;\n // optimization so that we don't unnecessarily resize the original\n // full-size file for cursor preview\n // (it's much faster to convert the resized dataURL to File)\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.dataURLToFile)(dataURL);\n this.setImagePreviewCursor(resizedFile || imageFile);\n }\n const dataURL = ((_h = this.files[fileId]) === null || _h === void 0 ? void 0 : _h.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imageFile));\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\n fileId,\n }, false);\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n var _j;\n try {\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\n mimeType,\n id: fileId,\n dataURL,\n created: Date.now(),\n } });\n const cachedImageData = this.imageCache.get(fileId);\n if (!cachedImageData) {\n this.addNewImagesToImageCache();\n yield this.updateImageCache([imageElement]);\n }\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\n yield cachedImageData.image;\n }\n if (this.state.pendingImageElementId !== imageElement.id &&\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\n this.initializeImageDimensions(imageElement, true);\n }\n resolve(imageElement);\n }\n catch (error) {\n console.error(error);\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\n }\n finally {\n if (!showCursorImagePreview) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n }\n }\n }));\n });\n /**\n * inserts image into elements array and rerenders\n */\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n imageElement,\n ]);\n try {\n yield this.initializeImage({\n imageFile,\n imageElement,\n showCursorImagePreview,\n });\n }\n catch (error) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n isDeleted: true,\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n this.setState({\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\n });\n }\n });\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\n // mustn't be larger than 128 px\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\n const cursorImageSizePx = 96;\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.resizeImageFile)(imageFile, {\n maxWidthOrHeight: cursorImageSizePx,\n });\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getDataURL)(imagePreview);\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\n // a small canvas\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.loadHTMLImageElement)(previewDataURL);\n let height = Math.min(img.height, cursorImageSizePx);\n let width = height * (img.width / img.height);\n if (width > cursorImageSizePx) {\n width = cursorImageSizePx;\n height = width * (img.height / img.width);\n }\n const canvas = document.createElement(\"canvas\");\n canvas.height = height;\n canvas.width = width;\n const context = canvas.getContext(\"2d\");\n context.drawImage(img, 0, 0, width, height);\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg);\n }\n if (this.state.pendingImageElementId) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\n }\n });\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\n try {\n const clientX = this.state.width / 2 + this.state.offsetLeft;\n const clientY = this.state.height / 2 + this.state.offsetTop;\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_42__.fileOpen)({\n description: \"Image\",\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\n });\n const imageElement = this.createImageElement({\n sceneX: x,\n sceneY: y,\n });\n if (insertOnCanvasDirectly) {\n this.insertImageElement(imageElement, imageFile);\n this.initializeImageDimensions(imageElement);\n this.setState({\n selectedElementIds: { [imageElement.id]: true },\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n else {\n this.setState({\n pendingImageElementId: imageElement.id,\n }, () => {\n this.insertImageElement(imageElement, imageFile, \n /* showCursorImagePreview */ true);\n });\n }\n }\n catch (error) {\n if (error.name !== \"AbortError\") {\n console.error(error);\n }\n else {\n console.warn(error);\n }\n this.setState({\n pendingImageElementId: null,\n editingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n });\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\n var _a;\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n if (!image || image instanceof Promise) {\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value) {\n const placeholderSize = 100 / this.state.zoom.value;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\n x: imageElement.x - placeholderSize / 2,\n y: imageElement.y - placeholderSize / 2,\n width: placeholderSize,\n height: placeholderSize,\n });\n }\n return;\n }\n if (forceNaturalSize ||\n // if user-created bounding box is below threshold, assume the\n // intention was to click instead of drag, and use the image's\n // intrinsic size\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value &&\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\n const minHeight = Math.max(this.state.height - 120, 160);\n // max 65% of canvas height, clamped to <300px, vh - 120px>\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\n const height = Math.min(image.naturalHeight, maxHeight);\n const width = height * (image.naturalWidth / image.naturalHeight);\n // add current imageElement width/height to account for previous centering\n // of the placeholder image\n const x = imageElement.x + imageElement.width / 2 - width / 2;\n const y = imageElement.y + imageElement.height / 2 - height / 2;\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\n }\n };\n /** updates image cache, refreshing updated elements and/or setting status\n to error for images that fail during <img> element creation */\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.updateImageCache)({\n imageCache: this.imageCache,\n fileIds: elements.map((element) => element.fileId),\n files,\n });\n if (updatedFiles.size || erroredFiles.size) {\n for (const element of elements) {\n if (updatedFiles.has(element.fileId)) {\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\n }\n }\n }\n if (erroredFiles.size) {\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\n erroredFiles.has(element.fileId)) {\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\n status: \"error\",\n });\n }\n return element;\n }));\n }\n return { updatedFiles, erroredFiles };\n });\n /** adds new images to imageCache and re-renders if needed */\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_40__.getInitializedImageElements)(this.scene.getNonDeletedElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\n if (uncachedImageElements.length) {\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\n if (updatedFiles.size) {\n this.scene.informMutation();\n }\n }\n });\n /** generally you should use `addNewImagesToImageCache()` directly if you need\n * to render new images. This is just a failsafe */\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_41___default()(() => {\n this.addNewImagesToImageCache();\n }, _constants__WEBPACK_IMPORTED_MODULE_12__.IMAGE_RENDER_TIMEOUT);\n this.updateBindingEnabledOnPointerMove = (event) => {\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\n this.setState({ isBindingEnabled: shouldEnableBinding });\n }\n };\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\n this.setState({\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\n });\n };\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \n /** scene coords */\n pointerCoords, \n // During line creation the start binding hasn't been written yet\n // into `linearElement`\n oppositeBindingBoundElement) => {\n if (!pointerCoords.length) {\n return;\n }\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\n if (hoveredBindableElement != null &&\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\n acc.push(hoveredBindableElement);\n }\n return acc;\n }, []);\n this.setState({ suggestedBindings });\n };\n this.handleCanvasRef = (canvas) => {\n var _a, _b, _c;\n // canvas is null when unmounting\n if (canvas !== null) {\n this.canvas = canvas;\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_3__[\"default\"].canvas(this.canvas);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel, {\n passive: false,\n });\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n else {\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.handleWheel);\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_START, this.onTapStart);\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.TOUCH_END, this.onTapEnd);\n }\n };\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\n // must be retrieved first, in the same frame\n const { file, fileHandle } = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.getFileFromEvent)(event);\n try {\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.isSupportedImageFile)(file)) {\n // first attempt to decode scene from the image if it's embedded\n // ---------------------------------------------------------------------\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.svg) {\n try {\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_13__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n return;\n }\n catch (error) {\n if (error.name !== \"EncodingError\") {\n throw error;\n }\n }\n }\n // if no scene is embedded or we fail for whatever reason, fall back\n // to importing as regular image\n // ---------------------------------------------------------------------\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const imageElement = this.createImageElement({ sceneX, sceneY });\n this.insertImageElement(imageElement, file);\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\n return;\n }\n }\n catch (error) {\n return this.setState({\n isLoading: false,\n errorMessage: error.message,\n });\n }\n const libraryJSON = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib);\n if (libraryJSON && typeof libraryJSON === \"string\") {\n try {\n const libraryItems = (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.parseLibraryJSON)(libraryJSON);\n this.addElementsFromPasteOrLibrary({\n elements: (0,_data_library__WEBPACK_IMPORTED_MODULE_14__.distributeLibraryItemsOnSquareGrid)(libraryItems),\n position: event,\n files: null,\n });\n }\n catch (error) {\n this.setState({ errorMessage: error.message });\n }\n return;\n }\n if (file) {\n // atetmpt to parse an excalidraw/excalidrawlib file\n yield this.loadFileToCanvas(file, fileHandle);\n }\n });\n this.loadFileToCanvas = (file, fileHandle) => __awaiter(this, void 0, void 0, function* () {\n file = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.normalizeFile)(file);\n try {\n const ret = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_39__.loadSceneOrLibraryFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted(), fileHandle);\n if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidraw) {\n this.setState({ isLoading: true });\n this.syncActionResult(Object.assign(Object.assign({}, ret.data), { appState: Object.assign(Object.assign({}, (ret.data.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\n }\n else if (ret.type === _constants__WEBPACK_IMPORTED_MODULE_12__.MIME_TYPES.excalidrawlib) {\n yield this.library\n .updateLibrary({\n libraryItems: file,\n merge: true,\n openLibraryMenu: true,\n })\n .catch((error) => {\n console.error(error);\n this.setState({ errorMessage: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.importLibraryError\") });\n });\n }\n }\n catch (error) {\n this.setState({ isLoading: false, errorMessage: error.message });\n }\n });\n this.handleCanvasContextMenu = (event) => {\n event.preventDefault();\n if ((event.nativeEvent.pointerType === \"touch\" ||\n (event.nativeEvent.pointerType === \"pen\" &&\n // always allow if user uses a pen secondary button\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_12__.POINTER_BUTTON.SECONDARY)) &&\n this.state.activeTool.type !== \"selection\") {\n return;\n }\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const element = this.getElementAtPosition(x, y, {\n preferSelected: true,\n includeLockedElements: true,\n });\n const type = element ? \"element\" : \"canvas\";\n const container = this.excalidrawContainerRef.current;\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\n const left = event.clientX - offsetLeft;\n const top = event.clientY - offsetTop;\n if (element && !this.state.selectedElementIds[element.id]) {\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { selectedElementIds: { [element.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(element)\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(element, this.scene)\n : null }), this.scene.getNonDeletedElements()), () => {\n this._openContextMenu({ top, left }, type);\n });\n }\n else {\n this._openContextMenu({ top, left }, type);\n }\n };\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\n var _a;\n const draggingElement = this.state.draggingElement;\n const pointerCoords = pointerDownState.lastCoords;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"selection\" &&\n this.state.activeTool.type !== \"eraser\") {\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.origin.x, pointerDownState.origin.y, pointerCoords.x, pointerCoords.y, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.x, pointerCoords.x), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.origin.y, pointerCoords.y), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event));\n }\n else {\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\n const aspectRatio = image && !(image instanceof Promise)\n ? image.width / image.height\n : null;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.x, gridX), (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(pointerDownState.originInGrid.y, gridY), (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\n this.maybeSuggestBindingForAll([draggingElement]);\n }\n };\n this.maybeHandleResize = (pointerDownState, event) => {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const transformHandleType = pointerDownState.resize.handleType;\n this.setState({\n // TODO: rename this state field to \"isScaling\" to distinguish\n // it from the generic \"isResizing\" which includes scaling and\n // rotating\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\n isRotating: transformHandleType === \"rotation\",\n });\n const pointerCoords = pointerDownState.lastCoords;\n const [resizeX, resizeY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.y - pointerDownState.resize.offset.y, this.state.gridSize);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.transformElements)(pointerDownState, transformHandleType, selectedElements, pointerDownState.resize.arrowDirection, (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(selectedElements[0])\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\n this.maybeSuggestBindingForAll(selectedElements);\n return true;\n }\n return false;\n };\n /** @private use this.handleCanvasContextMenu */\n this._openContextMenu = ({ left, top, }, type) => {\n if (this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n this.contextMenuOpen = true;\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowUnbinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const mayBeAllowBinding = _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\n const separator = \"separator\";\n const elements = this.scene.getNonDeletedElements();\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const options = [];\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng);\n }\n if (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg);\n }\n if (type === \"element\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText.contextItemPredicate(elements, this.state) &&\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText) {\n options.push(_actions__WEBPACK_IMPORTED_MODULE_5__.copyText);\n }\n if (type === \"canvas\") {\n const viewModeOptions = [\n ...options,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ];\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: viewModeOptions,\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile &&\n navigator.clipboard && {\n trackEvent: false,\n name: \"paste\",\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && navigator.clipboard && separator,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsPng,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n elements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyAsSvg,\n _clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText &&\n selectedElements.length > 0 &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.copyText,\n ((_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardBlob && elements.length > 0) ||\n (_clipboard__WEBPACK_IMPORTED_MODULE_11__.probablySupportsClipboardWriteText && elements.length > 0)) &&\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSelectAll,\n separator,\n typeof this.props.gridModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleGridMode,\n typeof this.props.zenModeEnabled === \"undefined\" &&\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleZenMode,\n typeof this.props.viewModeEnabled === \"undefined\" &&\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_38__.actionToggleViewMode,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleStats,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n else if (type === \"element\") {\n if (this.state.viewModeEnabled) {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy, ...options],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n else {\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\n options: [\n this.device.isMobile && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCut,\n this.device.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopy,\n this.device.isMobile &&\n navigator.clipboard && {\n name: \"paste\",\n trackEvent: false,\n perform: (elements, appStates) => {\n this.pasteFromClipboard(null);\n return {\n commitToHistory: false,\n };\n },\n contextItemLabel: \"labels.paste\",\n },\n this.device.isMobile && separator,\n ...options,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionCopyStyles,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionPasteStyles,\n separator,\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionGroup,\n mayBeAllowUnbinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUnbindText,\n mayBeAllowBinding && _actions__WEBPACK_IMPORTED_MODULE_5__.actionBindText,\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_5__.actionUngroup,\n (maybeGroupAction || maybeUngroupAction) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionAddToLibrary,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendBackward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringForward,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionSendToBack,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionBringToFront,\n separator,\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipHorizontal,\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_5__.actionFlipVertical,\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink.contextItemPredicate(elements, this.state) && _actions__WEBPACK_IMPORTED_MODULE_5__.actionLink,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDuplicateSelection,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionToggleLock,\n separator,\n _actions__WEBPACK_IMPORTED_MODULE_5__.actionDeleteSelected,\n ],\n top,\n left,\n actionManager: this.actionManager,\n appState: this.state,\n container: this.excalidrawContainerRef.current,\n elements,\n });\n }\n }\n };\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n event.preventDefault();\n if (isPanning) {\n return;\n }\n const { deltaX, deltaY } = event;\n // note that event.ctrlKey is necessary to handle pinch zooming\n if (event.metaKey || event.ctrlKey) {\n const sign = Math.sign(deltaY);\n const MAX_STEP = 10;\n const absDelta = Math.abs(deltaY);\n let delta = deltaY;\n if (absDelta > MAX_STEP) {\n delta = MAX_STEP * sign;\n }\n let newZoom = this.state.zoom.value - delta / 100;\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\n newZoom +=\n Math.log10(Math.max(1, this.state.zoom.value)) *\n -sign *\n // reduced amplification for small deltas (small movements on a trackpad)\n Math.min(1, absDelta / 20);\n this.setState((state) => (Object.assign(Object.assign({}, (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getStateForZoom)({\n viewportX: cursorX,\n viewportY: cursorY,\n nextZoom: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom),\n }, state)), { shouldCacheIgnoreZoom: true })));\n this.resetShouldCacheIgnoreZoomDebounced();\n return;\n }\n // scroll horizontally when shift pressed\n if (event.shiftKey) {\n this.setState(({ zoom, scrollX }) => ({\n // on Mac, shift+wheel tends to result in deltaX\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\n }));\n return;\n }\n this.setState(({ zoom, scrollX, scrollY }) => ({\n scrollX: scrollX - deltaX / zoom.value,\n scrollY: scrollY - deltaY / zoom.value,\n }));\n });\n this.savePointer = (x, y, button) => {\n var _a, _b;\n if (!x || !y) {\n return;\n }\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\n // sometimes the pointer goes off screen\n }\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\n pointer,\n button,\n pointersMap: gesture.pointers,\n });\n };\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\n if (!this.unmounted) {\n this.setState({ shouldCacheIgnoreZoom: false });\n }\n }, 300);\n this.updateDOMRect = (cb) => {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\n if (width === currentWidth &&\n height === currentHeight &&\n offsetLeft === currentOffsetLeft &&\n offsetTop === currentOffsetTop) {\n if (cb) {\n cb();\n }\n return;\n }\n this.setState({\n width,\n height,\n offsetLeft,\n offsetTop,\n }, () => {\n cb && cb();\n });\n }\n };\n this.refresh = () => {\n this.setState(Object.assign({}, this.getCanvasOffsets()));\n };\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_10__.getDefaultAppState)();\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight, showHyperlinkPopup: false, isLibraryMenuDocked: false });\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_47__.nanoid)();\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\n if (excalidrawRef) {\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\n const api = {\n ready: true,\n readyPromise,\n updateScene: this.updateScene,\n updateLibrary: this.library.updateLibrary,\n addFiles: this.addFiles,\n resetScene: this.resetScene,\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\n history: {\n clear: this.resetHistory,\n },\n scrollToContent: this.scrollToContent,\n getSceneElements: this.getSceneElements,\n getAppState: () => this.state,\n getFiles: () => this.files,\n refresh: this.refresh,\n setToast: this.setToast,\n id: this.id,\n setActiveTool: this.setActiveTool,\n setCursor: this.setCursor,\n resetCursor: this.resetCursor,\n };\n if (typeof excalidrawRef === \"function\") {\n excalidrawRef(api);\n }\n else {\n excalidrawRef.current = api;\n }\n readyPromise.resolve(api);\n }\n this.excalidrawContainerValue = {\n container: this.excalidrawContainerRef.current,\n id: this.id,\n };\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_7__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_8__.actions);\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createUndoAction)(this.history));\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_6__.createRedoAction)(this.history));\n }\n renderCanvas() {\n const canvasScale = window.devicePixelRatio;\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\n const canvasWidth = canvasDOMWidth * canvasScale;\n const canvasHeight = canvasDOMHeight * canvasScale;\n if (viewModeEnabled) {\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n cursor: _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.GRAB,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\n width: canvasDOMWidth,\n height: canvasDOMHeight,\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") })));\n }\n render() {\n var _a, _b;\n const selectedElement = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(\"excalidraw excalidraw-container\", {\n \"excalidraw--view-mode\": this.state.viewModeEnabled,\n \"excalidraw--mobile\": this.device.isMobile,\n }), ref: this.excalidrawContainerRef, onDrop: this.handleAppOnDrop, tabIndex: 0, onKeyDown: this.props.handleKeyboardGlobally ? undefined : this.onKeyDown }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ExcalidrawContainerContext.Provider, Object.assign({ value: this.excalidrawContainerValue }, { children: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(DeviceContext.Provider, Object.assign({ value: this.device }, { children: [this.__renderUI && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_LayerUI__WEBPACK_IMPORTED_MODULE_36__[\"default\"], { canvas: this.canvas, appState: this.state, files: this.files, setAppState: this.setAppState, actionManager: this.actionManager, elements: this.scene.getNonDeletedElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onPenModeToggle: this.togglePenMode, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\n elements,\n position: \"center\",\n files: null,\n }), langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, renderCustomStats: renderCustomStats, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\n this.state.zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\n this.props.UIOptions.canvasActions.theme, libraryReturnUrl: this.props.libraryReturnUrl, UIOptions: this.props.UIOptions, focusContainer: this.focusContainer, library: this.library, id: this.id, onImageAction: this.onImageAction })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }), selectedElement.length === 1 && this.state.showHyperlinkPopup && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_element_Hyperlink__WEBPACK_IMPORTED_MODULE_45__.Hyperlink, { element: selectedElement[0], appState: this.state, setAppState: this.setAppState, onLinkOpen: this.props.onLinkOpen }, selectedElement[0].id)), this.state.toast !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_37__.Toast, { message: this.state.toast.message, onClose: () => this.setToast(null), duration: this.state.toast.duration, closable: this.state.toast.closable })), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() })] })) })) })));\n }\n componentDidMount() {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n this.unmounted = false;\n this.excalidrawContainerValue.container =\n this.excalidrawContainerRef.current;\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT ||\n ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_VERCEL_ENV === \"preview\") {\n const setState = this.setState.bind(this);\n Object.defineProperties(window.h, {\n state: {\n configurable: true,\n get: () => {\n return this.state;\n },\n },\n setState: {\n configurable: true,\n value: (...args) => {\n return this.setState(...args);\n },\n },\n app: {\n configurable: true,\n value: this,\n },\n history: {\n configurable: true,\n value: this.history,\n },\n });\n }\n this.scene.addCallback(this.onSceneUpdated);\n this.addEventListeners();\n if (this.excalidrawContainerRef.current) {\n this.focusContainer();\n }\n if (this.excalidrawContainerRef.current &&\n // bounding rects don't work in tests so updating\n // the state on init would result in making the test enviro run\n // in mobile breakpoint (0 width/height), making everything fail\n \"development\" !== \"test\") {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\n this.resizeObserver = new ResizeObserver(() => {\n THROTTLE_NEXT_RENDER = false;\n // recompute device dimensions state\n // ---------------------------------------------------------------------\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n // refresh offsets\n // ---------------------------------------------------------------------\n this.updateDOMRect();\n });\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\n }\n else if (window.matchMedia) {\n const mdScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\n const smScreenQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_12__.MQ_SM_MAX_WIDTH}px)`);\n const canDeviceFitSidebarMediaQuery = window.matchMedia(`(min-width: ${\n // NOTE this won't update if a different breakpoint is supplied\n // after mount\n this.props.UIOptions.dockedSidebarBreakpoint != null\n ? this.props.UIOptions.dockedSidebarBreakpoint\n : _constants__WEBPACK_IMPORTED_MODULE_12__.MQ_RIGHT_SIDEBAR_MIN_WIDTH}px)`);\n const handler = () => {\n this.excalidrawContainerRef.current.getBoundingClientRect();\n this.device = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateObject)(this.device, {\n isSmScreen: smScreenQuery.matches,\n isMobile: mdScreenQuery.matches,\n canDeviceFitSidebar: canDeviceFitSidebarMediaQuery.matches,\n });\n };\n mdScreenQuery.addListener(handler);\n this.detachIsMobileMqHandler = () => mdScreenQuery.removeListener(handler);\n }\n const searchParams = new URLSearchParams(window.location.search.slice(1));\n if (searchParams.has(\"web-share-target\")) {\n // Obtain a file that was shared via the Web Share Target API.\n this.restoreFileFromShare();\n }\n else {\n this.updateDOMRect(this.initializeScene);\n }\n });\n }\n componentWillUnmount() {\n var _a;\n this.files = {};\n this.imageCache.clear();\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n this.unmounted = true;\n this.removeEventListeners();\n this.scene.destroy();\n clearTimeout(touchTimeout);\n touchTimeout = 0;\n }\n removeEventListeners() {\n var _a, _b, _c, _d, _e;\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel);\n (_b = this.nearestScrollableContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n (_e = this.detachIsMobileMqHandler) === null || _e === void 0 ? void 0 : _e.call(this);\n }\n addEventListeners() {\n var _a, _b, _c, _d, _e;\n this.removeEventListeners();\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, this.removePointer); // #3553\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.COPY, this.onCopy);\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.WHEEL, this.onWheel, { passive: false });\n if (this.props.handleKeyboardGlobally) {\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, this.onKeyDown, false);\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, this.onKeyUp, { passive: true });\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\n // rerender text elements on font load to fix #637 && #1553\n (_c = (_b = document.fonts) === null || _b === void 0 ? void 0 : _b.addEventListener) === null || _c === void 0 ? void 0 : _c.call(_b, \"loadingdone\", this.onFontLoaded);\n // Safari-only desktop pinch zoom\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_START, this.onGestureStart, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.GESTURE_END, this.onGestureEnd, false);\n if (this.state.viewModeEnabled) {\n return;\n }\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.PASTE, this.pasteFromClipboard);\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.CUT, this.onCut);\n if (this.props.detectScroll) {\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.SCROLL, this.onScroll);\n }\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.RESIZE, this.onResize, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.UNLOAD, this.onUnload, false);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.BLUR, this.onBlur, false);\n (_d = this.excalidrawContainerRef.current) === null || _d === void 0 ? void 0 : _d.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DRAG_OVER, this.disableEvent, false);\n (_e = this.excalidrawContainerRef.current) === null || _e === void 0 ? void 0 : _e.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.DROP, this.disableEvent, false);\n }\n componentDidUpdate(prevProps, prevState) {\n var _a, _b, _c, _d, _e;\n if (this.excalidrawContainerRef.current &&\n prevProps.UIOptions.dockedSidebarBreakpoint !==\n this.props.UIOptions.dockedSidebarBreakpoint) {\n this.refreshDeviceState(this.excalidrawContainerRef.current);\n }\n if (prevState.scrollX !== this.state.scrollX ||\n prevState.scrollY !== this.state.scrollY) {\n (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.onScrollChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.scrollX, this.state.scrollY);\n }\n if (Object.keys(this.state.selectedElementIds).length &&\n (0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.setState({\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n if (this.state.activeTool.type === \"eraser\" &&\n prevState.theme !== this.state.theme) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setEraserCursor)(this.canvas, this.state.theme);\n }\n // Hide hyperlink popup if shown when element type is not selection\n if (prevState.activeTool.type === \"selection\" &&\n this.state.activeTool.type !== \"selection\" &&\n this.state.showHyperlinkPopup) {\n this.setState({ showHyperlinkPopup: false });\n }\n if (prevProps.langCode !== this.props.langCode) {\n this.updateLanguage();\n }\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\n }\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\n this.addEventListeners();\n this.deselectElements();\n }\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\n }\n if (prevProps.theme !== this.props.theme && this.props.theme) {\n this.setState({ theme: this.props.theme });\n }\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\n this.setState({\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_12__.GRID_SIZE : null,\n });\n }\n if (this.props.name && prevProps.name !== this.props.name) {\n this.setState({\n name: this.props.name,\n });\n }\n (_c = this.excalidrawContainerRef.current) === null || _c === void 0 ? void 0 : _c.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\n if (this.state.editingLinearElement &&\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\n // defer so that the commitToHistory flag isn't reset via current update\n setTimeout(() => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n if (this.state.selectedLinearElement &&\n !this.state.selectedElementIds[this.state.selectedLinearElement.elementId]) {\n // To make sure `selectedLinearElement` is in sync with `selectedElementIds`, however this shouldn't be needed once\n // we have a single API to update `selectedElementIds`\n this.setState({ selectedLinearElement: null });\n }\n const { multiElement } = prevState;\n if (prevState.activeTool !== this.state.activeTool &&\n multiElement != null &&\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(multiElement, this.state, this.scene, (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)(_element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1)));\n }\n this.renderScene();\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\n // Do not notify consumers if we're still loading the scene. Among other\n // potential issues, this fixes a case where the tab isn't focused during\n // init, which would trigger onChange with empty elements, which would then\n // override whatever is in localStorage currently.\n if (!this.state.isLoading) {\n (_e = (_d = this.props).onChange) === null || _e === void 0 ? void 0 : _e.call(_d, this.scene.getElementsIncludingDeleted(), this.state, this.files);\n }\n }\n static resetTapTwice() {\n didTapTwice = false;\n }\n addTextFromPaste(text) {\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\n x,\n y,\n strokeColor: this.state.currentItemStrokeColor,\n backgroundColor: this.state.currentItemBackgroundColor,\n fillStyle: this.state.currentItemFillStyle,\n strokeWidth: this.state.currentItemStrokeWidth,\n strokeStyle: this.state.currentItemStrokeStyle,\n roughness: this.state.currentItemRoughness,\n opacity: this.state.currentItemOpacity,\n strokeSharpness: this.state.currentItemStrokeSharpness,\n text,\n fontSize: this.state.currentItemFontSize,\n fontFamily: this.state.currentItemFontFamily,\n textAlign: this.state.currentItemTextAlign,\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_VERTICAL_ALIGN,\n locked: false,\n });\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted(),\n element,\n ]);\n this.setState({ selectedElementIds: { [element.id]: true } });\n this.history.resumeRecording();\n }\n handleTextWysiwyg(element, { isExistingElement = false, }) {\n const updateElement = (text, originalText, isDeleted) => {\n this.scene.replaceAllElements([\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\n text,\n isDeleted,\n originalText,\n });\n }\n return _element;\n }),\n ]);\n };\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\n id: element.id,\n canvas: this.canvas,\n getViewportCoords: (x, y) => {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\n sceneX: x,\n sceneY: y,\n }, this.state);\n return [\n viewportX - this.state.offsetLeft,\n viewportY - this.state.offsetTop,\n ];\n },\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\n updateElement(text, text, false);\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\n }\n }),\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\n const isDeleted = !text.trim();\n updateElement(text, originalText, isDeleted);\n // select the created text element only if submitting via keyboard\n // (when submitting via click it should act as signal to deselect)\n if (!isDeleted && viaKeyboard) {\n const elementIdToSelect = element.containerId\n ? element.containerId\n : element.id;\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\n }));\n }\n if (isDeleted) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getNonDeletedElements(), [\n element,\n ]);\n }\n if (!isDeleted || isExistingElement) {\n this.history.resumeRecording();\n }\n this.setState({\n draggingElement: null,\n editingElement: null,\n });\n if (this.state.activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n }\n this.focusContainer();\n }),\n element,\n excalidrawContainer: this.excalidrawContainerRef.current,\n app: this,\n });\n // deselect all other elements when inserting text\n this.deselectElements();\n // do an initial update to re-initialize element position since we were\n // modifying element's x/y for sake of editor (case: syncing to remote)\n updateElement(element.text, element.originalText, false);\n }\n deselectElements() {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n getTextElementAtPosition(x, y) {\n const element = this.getElementAtPosition(x, y, {\n includeBoundTextElement: true,\n });\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\n return element;\n }\n return null;\n }\n getElementAtPosition(x, y, opts) {\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement, opts === null || opts === void 0 ? void 0 : opts.includeLockedElements);\n if (allHitElements.length > 1) {\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\n for (let index = allHitElements.length - 1; index > -1; index--) {\n if (this.state.selectedElementIds[allHitElements[index].id]) {\n return allHitElements[index];\n }\n }\n }\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\n // If we're hitting element with highest z-index only on its bounding box\n // while also hitting other element figure, the latter should be considered.\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\n ? allHitElements[allHitElements.length - 2]\n : elementWithHighestZIndex;\n }\n if (allHitElements.length === 1) {\n return allHitElements[0];\n }\n return null;\n }\n getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {\n const elements = includeBoundTextElement && includeLockedElements\n ? this.scene.getNonDeletedElements()\n : this.scene\n .getNonDeletedElements()\n .filter((element) => (includeLockedElements || !element.locked) &&\n (includeBoundTextElement ||\n !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId)));\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\n }\n handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(linearElementEditor.elementId);\n if (!element) {\n return;\n }\n if (this.state.selectedLinearElement) {\n let hoverPointIndex = -1;\n let midPointHovered = false;\n if ((0,_element_collision__WEBPACK_IMPORTED_MODULE_44__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\n scenePointerX,\n scenePointerY,\n ])) {\n hoverPointIndex = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getPointIndexUnderCursor(element, this.state.zoom, scenePointerX, scenePointerY);\n midPointHovered = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.isHittingMidPoint(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state);\n if (hoverPointIndex >= 0 || midPointHovered) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.POINTER);\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n }\n else if ((0,_element_transformHandles__WEBPACK_IMPORTED_MODULE_46__.shouldShowBoundingBox)([element], this.state) &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(element, this.state, scenePointerX, scenePointerY)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.MOVE);\n }\n if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { hoverPointIndex }),\n });\n }\n if (this.state.selectedLinearElement.midPointHovered !== midPointHovered) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { midPointHovered }),\n });\n }\n }\n else {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_12__.CURSOR_TYPE.AUTO);\n }\n }\n maybeCleanupAfterMissingPointerUp(event) {\n if (lastPointerUp !== null) {\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\n // this can happen when a contextual menu or alert is triggered. In order to avoid\n // being in a weird state, we clean up on the next pointerdown\n lastPointerUp(event);\n }\n }\n updateGestureOnPointerDown(event) {\n gesture.pointers.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n if (gesture.pointers.size === 2) {\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\n gesture.initialScale = this.state.zoom.value;\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\n }\n }\n initialPointerDownState(event) {\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return {\n origin,\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\n // we need to duplicate because we'll be updating this state\n lastCoords: Object.assign({}, origin),\n originalElements: this.scene\n .getNonDeletedElements()\n .reduce((acc, element) => {\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\n return acc;\n }, new Map()),\n resize: {\n handleType: false,\n isResizing: false,\n offset: { x: 0, y: 0 },\n arrowDirection: \"origin\",\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\n },\n hit: {\n element: null,\n allHitElements: [],\n wasAddedToSelection: false,\n hasBeenDuplicated: false,\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\n },\n drag: {\n hasOccurred: false,\n offset: null,\n },\n eventListeners: {\n onMove: null,\n onUp: null,\n onKeyUp: null,\n onKeyDown: null,\n },\n boxSelection: {\n hasOccurred: false,\n },\n elementIdsToErase: {},\n };\n }\n // Returns whether the event is a dragging a scrollbar\n handleDraggingScrollBar(event, pointerDownState) {\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\n return false;\n }\n isDraggingScrollBar = true;\n pointerDownState.lastCoords.x = event.clientX;\n pointerDownState.lastCoords.y = event.clientY;\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\n });\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\n isDraggingScrollBar = false;\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state);\n lastPointerUp = null;\n this.setState({\n cursorButton: \"up\",\n });\n this.savePointer(event.clientX, event.clientY, \"up\");\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n onPointerMove.flush();\n });\n lastPointerUp = onPointerUp;\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, onPointerMove);\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, onPointerUp);\n return true;\n }\n isASelectedElement(hitElement) {\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\n }\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\n if (selectedElements.length < 2) {\n return false;\n }\n // How many pixels off the shape boundary we still consider a hit\n const threshold = 10 / this.state.zoom.value;\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\n return (point.x > x1 - threshold &&\n point.x < x2 + threshold &&\n point.y > y1 - threshold &&\n point.y < y2 + threshold);\n }\n onKeyDownFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onKeyUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\n // Prevents focus from escaping excalidraw tab\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\n if (this.maybeHandleResize(pointerDownState, event)) {\n return;\n }\n this.maybeDragNewGenericElement(pointerDownState, event);\n });\n }\n onPointerMoveFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdatesThrottled)((event) => {\n var _a;\n // We need to initialize dragOffsetXY only after we've updated\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\n // event handler should hopefully ensure we're already working with\n // the updated state.\n if (pointerDownState.drag.offset === null) {\n pointerDownState.drag.offset = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_element__WEBPACK_IMPORTED_MODULE_16__.getDragOffsetXY)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\n }\n const target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\n return;\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n this.handleEraser(event, pointerDownState, pointerCoords);\n return;\n }\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\n // for arrows/lines, don't start dragging until a given threshold\n // to ensure we don't create a 2-point arrow by mistake when\n // user clicks mouse in a way that it moves a tiny bit (thus\n // triggering pointermove)\n if (!pointerDownState.drag.hasOccurred &&\n (this.state.activeTool.type === \"arrow\" ||\n this.state.activeTool.type === \"line\")) {\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_12__.DRAGGING_THRESHOLD) {\n return;\n }\n }\n if (pointerDownState.resize.isResizing) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n if (this.maybeHandleResize(pointerDownState, event)) {\n return true;\n }\n }\n if (this.state.selectedLinearElement) {\n const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\n }, linearElementEditor);\n if (didDrag) {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n pointerDownState.drag.hasOccurred = true;\n if (this.state.editingLinearElement &&\n !this.state.editingLinearElement.isDragging) {\n this.setState({\n editingLinearElement: Object.assign(Object.assign({}, this.state.editingLinearElement), { isDragging: true }),\n });\n }\n if (!this.state.selectedLinearElement.isDragging) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, this.state.selectedLinearElement), { isDragging: true }),\n });\n }\n return;\n }\n }\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\n const isSelectingPointsInLineEditor = this.state.editingLinearElement &&\n event.shiftKey &&\n this.state.editingLinearElement.elementId ===\n ((_a = pointerDownState.hit.element) === null || _a === void 0 ? void 0 : _a.id);\n if ((hasHitASelectedElement ||\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\n !isSelectingPointsInLineEditor) {\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n if (selectedElements.every((element) => element.locked)) {\n return;\n }\n // Marking that click was used for dragging to check\n // if elements should be deselected on pointerup\n pointerDownState.drag.hasOccurred = true;\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\n // it would have weird results (stuff jumping all over the screen)\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\n const [dragX, dragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x - pointerDownState.drag.offset.x, pointerCoords.y - pointerDownState.drag.offset.y, this.state.gridSize);\n const [dragDistanceX, dragDistanceY] = [\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\n ];\n // We only drag in one direction if shift is pressed\n const lockDirection = event.shiftKey;\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY, this.state);\n this.maybeSuggestBindingForAll(selectedElements);\n // We duplicate the selected element if alt is pressed on pointer move\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\n // Move the currently selected elements to the top of the z index stack, and\n // put the duplicates where the selected elements used to be.\n // (the origin point where the dragging started)\n pointerDownState.hit.hasBeenDuplicated = true;\n const nextElements = [];\n const elementsToAppend = [];\n const groupIdMap = new Map();\n const oldIdToDuplicatedId = new Map();\n const hitElement = pointerDownState.hit.element;\n const elements = this.scene.getElementsIncludingDeleted();\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\n for (const element of elements) {\n if (selectedElementIds.includes(element.id) ||\n // case: the state.selectedElementIds might not have been\n // updated yet by the time this mousemove event is fired\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n pointerDownState.hit.wasAddedToSelection)) {\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\n const [originDragX, originDragY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x - pointerDownState.drag.offset.x, pointerDownState.origin.y - pointerDownState.drag.offset.y, this.state.gridSize);\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\n x: duplicatedElement.x + (originDragX - dragX),\n y: duplicatedElement.y + (originDragY - dragY),\n });\n nextElements.push(duplicatedElement);\n elementsToAppend.push(element);\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\n }\n else {\n nextElements.push(element);\n }\n }\n const nextSceneElements = [...nextElements, ...elementsToAppend];\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_43__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\n this.scene.replaceAllElements(nextSceneElements);\n }\n return;\n }\n }\n // It is very important to read this.state within each move event,\n // otherwise we would read a stale one!\n const draggingElement = this.state.draggingElement;\n if (!draggingElement) {\n return;\n }\n if (draggingElement.type === \"freedraw\") {\n const points = draggingElement.points;\n const dx = pointerCoords.x - draggingElement.x;\n const dy = pointerCoords.y - draggingElement.y;\n const lastPoint = points.length > 0 && points[points.length - 1];\n const discardPoint = lastPoint && lastPoint[0] === dx && lastPoint[1] === dy;\n if (!discardPoint) {\n const pressures = draggingElement.simulatePressure\n ? draggingElement.pressures\n : [...draggingElement.pressures, event.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n });\n }\n }\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n pointerDownState.drag.hasOccurred = true;\n const points = draggingElement.points;\n let dx = gridX - draggingElement.x;\n let dy = gridY - draggingElement.y;\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getLockedLinearCursorAlignSize)(draggingElement.x, draggingElement.y, pointerCoords.x, pointerCoords.y));\n }\n if (points.length === 1) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n });\n }\n else if (points.length === 2) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points.slice(0, -1), [dx, dy]],\n });\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n // When creating a linear element by dragging\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\n }\n }\n else {\n pointerDownState.lastCoords.x = pointerCoords.x;\n pointerDownState.lastCoords.y = pointerCoords.y;\n this.maybeDragNewGenericElement(pointerDownState, event);\n }\n if (this.state.activeTool.type === \"selection\") {\n pointerDownState.boxSelection.hasOccurred = true;\n const elements = this.scene.getNonDeletedElements();\n if (!event.shiftKey &&\n // allows for box-selecting points (without shift)\n !this.state.editingLinearElement &&\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\n [pointerDownState.hit.element.id]: true,\n } }), this.scene.getNonDeletedElements()));\n }\n else {\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n }\n // box-select line editor points\n if (this.state.editingLinearElement) {\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\n // regular box-select\n }\n else {\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign(Object.assign({}, prevState.selectedElementIds), elementsWithinSelection.reduce((acc, element) => {\n acc[element.id] = true;\n return acc;\n }, {})), (pointerDownState.hit.element\n ? {\n // if using ctrl/cmd, select the hitElement only if we\n // haven't box-selected anything else\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\n }\n : null)), showHyperlinkPopup: elementsWithinSelection.length === 1 &&\n elementsWithinSelection[0].link\n ? \"info\"\n : false, \n // select linear element only when we haven't box-selected anything else\n selectedLinearElement: elementsWithinSelection.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(elementsWithinSelection[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(elementsWithinSelection[0], this.scene)\n : null }), this.scene.getNonDeletedElements()));\n }\n }\n });\n }\n // Returns whether the pointer move happened over either scrollbar\n handlePointerMoveOverScrollbars(event, pointerDownState) {\n if (pointerDownState.scrollbars.isOverHorizontal) {\n const x = event.clientX;\n const dx = x - pointerDownState.lastCoords.x;\n this.setState({\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\n });\n pointerDownState.lastCoords.x = x;\n return true;\n }\n if (pointerDownState.scrollbars.isOverVertical) {\n const y = event.clientY;\n const dy = y - pointerDownState.lastCoords.y;\n this.setState({\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\n });\n pointerDownState.lastCoords.y = y;\n return true;\n }\n return false;\n }\n onPointerUpFromPointerDownHandler(pointerDownState) {\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\n var _a, _b, _c, _d, _e, _f;\n const { draggingElement, resizingElement, multiElement, activeTool, isResizing, isRotating, } = this.state;\n this.setState({\n isResizing: false,\n isRotating: false,\n resizingElement: null,\n selectionElement: null,\n cursorButton: \"up\",\n // text elements are reset on finalize, and resetting on pointerup\n // may cause issues with double taps\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\n ? this.state.editingElement\n : null,\n });\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\n // Handle end of dragging a point of a linear element, might close a loop\n // and sets binding element\n if (this.state.editingLinearElement) {\n if (!pointerDownState.boxSelection.hasOccurred &&\n ((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\n this.state.editingLinearElement.elementId) {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n else {\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\n if (editingLinearElement !== this.state.editingLinearElement) {\n this.setState({\n editingLinearElement,\n suggestedBindings: [],\n });\n }\n }\n }\n else if (this.state.selectedLinearElement) {\n if (((_d = (_c = pointerDownState.hit) === null || _c === void 0 ? void 0 : _c.element) === null || _d === void 0 ? void 0 : _d.id) !==\n this.state.selectedLinearElement.elementId) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement to null if there is more than one element selected since we don't want to show linear element handles\n if (selectedELements.length > 1) {\n this.setState({ selectedLinearElement: null });\n }\n }\n else {\n const linearElementEditor = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state);\n const { startBindingElement, endBindingElement } = linearElementEditor;\n const element = this.scene.getElement(linearElementEditor.elementId);\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(element)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindLinearElement)(element, startBindingElement, endBindingElement);\n }\n if (linearElementEditor !== this.state.selectedLinearElement) {\n this.setState({\n selectedLinearElement: Object.assign(Object.assign({}, linearElementEditor), { selectedPointsIndices: null }),\n suggestedBindings: [],\n });\n }\n }\n }\n lastPointerUp = null;\n if (pointerDownState.eventListeners.onMove) {\n pointerDownState.eventListeners.onMove.flush();\n }\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_12__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\n if (this.state.pendingImageElementId) {\n this.setState({ pendingImageElementId: null });\n }\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n const points = draggingElement.points;\n let dx = pointerCoords.x - draggingElement.x;\n let dy = pointerCoords.y - draggingElement.y;\n // Allows dots to avoid being flagged as infinitely small\n if (dx === points[0][0] && dy === points[0][1]) {\n dy += 0.0001;\n dx += 0.0001;\n }\n const pressures = draggingElement.simulatePressure\n ? []\n : [...draggingElement.pressures, childEvent.pressure];\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [...points, [dx, dy]],\n pressures,\n lastCommittedPoint: [dx, dy],\n });\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\n const imageElement = draggingElement;\n try {\n this.initializeImageDimensions(imageElement);\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n });\n }\n catch (error) {\n console.error(error);\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== imageElement.id));\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_5__.actionFinalize);\n }\n return;\n }\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\n if (draggingElement.points.length > 1) {\n this.history.resumeRecording();\n }\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\n if (!pointerDownState.drag.hasOccurred &&\n draggingElement &&\n !multiElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\n points: [\n ...draggingElement.points,\n [\n pointerCoords.x - draggingElement.x,\n pointerCoords.y - draggingElement.y,\n ],\n ],\n });\n this.setState({\n multiElement: draggingElement,\n editingElement: this.state.draggingElement,\n });\n }\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement, false)) {\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\n }\n this.setState({ suggestedBindings: [], startBoundElement: null });\n if (!activeTool.locked) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState((prevState) => ({\n draggingElement: null,\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, {\n type: \"selection\",\n }),\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(draggingElement, this.scene),\n }));\n }\n else {\n this.setState((prevState) => ({\n draggingElement: null,\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n }\n return;\n }\n if (activeTool.type !== \"selection\" &&\n draggingElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\n // remove invisible element which was added in onPointerDown\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\n this.setState({\n draggingElement: null,\n });\n return;\n }\n if (draggingElement) {\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\n }\n if (resizingElement) {\n this.history.resumeRecording();\n }\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\n this.scene.replaceAllElements(this.scene\n .getElementsIncludingDeleted()\n .filter((el) => el.id !== resizingElement.id));\n }\n // Code below handles selection when element(s) weren't\n // drag or added to selection on pointer down phase.\n const hitElement = pointerDownState.hit.element;\n if (((_e = this.state.selectedLinearElement) === null || _e === void 0 ? void 0 : _e.elementId) !== (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement)) {\n const selectedELements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state);\n // set selectedLinearElement when no other element selected except\n // the one we've hit\n if (selectedELements.length === 1) {\n this.setState({\n selectedLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene),\n });\n }\n }\n if ((0,_appState__WEBPACK_IMPORTED_MODULE_10__.isEraserActive)(this.state)) {\n const draggedDistance = (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(this.lastPointerDown.clientX, this.lastPointerDown.clientY, this.lastPointerUp.clientX, this.lastPointerUp.clientY);\n if (draggedDistance === 0) {\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({\n clientX: this.lastPointerUp.clientX,\n clientY: this.lastPointerUp.clientY,\n }, this.state);\n const hitElements = this.getElementsAtPosition(scenePointer.x, scenePointer.y);\n hitElements.forEach((hitElement) => (pointerDownState.elementIdsToErase[hitElement.id] = {\n erase: true,\n opacity: hitElement.opacity,\n }));\n }\n this.eraseElements(pointerDownState);\n return;\n }\n else if (Object.keys(pointerDownState.elementIdsToErase).length) {\n this.restoreReadyToEraseElements(pointerDownState);\n }\n if (hitElement &&\n !pointerDownState.drag.hasOccurred &&\n !pointerDownState.hit.wasAddedToSelection &&\n // if we're editing a line, pointerup shouldn't switch selection if\n // box selected\n (!this.state.editingLinearElement ||\n !pointerDownState.boxSelection.hasOccurred)) {\n // when inside line editor, shift selects points instead\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\n if (this.state.selectedElementIds[hitElement.id]) {\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\n // We want to unselect all groups hitElement is part of\n // as well as all elements that are part of the groups\n // hitElement is part of\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getNonDeletedElements(), groupId))\n .map((element) => ({ [element.id]: false }))\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\n this.setState((_prevState) => ({\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\n .map((gId) => ({ [gId]: false }))\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\n }));\n // if not gragging a linear element point (outside editor)\n }\n else if (!((_f = this.state.selectedLinearElement) === null || _f === void 0 ? void 0 : _f.isDragging)) {\n // remove element from selection while\n // keeping prev elements selected\n this.setState((prevState) => {\n const newSelectedElementIds = Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false });\n const newSelectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds }));\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: newSelectedElementIds, \n // set selectedLinearElement only if thats the only element selected\n selectedLinearElement: newSelectedElements.length === 1 &&\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(newSelectedElements[0])\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(newSelectedElements[0], this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements());\n });\n }\n }\n else {\n // add element to selection while\n // keeping prev elements selected\n this.setState((_prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\n }));\n }\n }\n else {\n this.setState((prevState) => {\n var _a;\n return (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true }, selectedLinearElement: (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(hitElement) &&\n // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.\n // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized\n ((_a = prevState.selectedLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !== hitElement.id\n ? new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(hitElement, this.scene)\n : prevState.selectedLinearElement }), this.scene.getNonDeletedElements())));\n });\n }\n }\n if (!pointerDownState.drag.hasOccurred &&\n !this.state.isResizing &&\n ((hitElement &&\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\n (!hitElement &&\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\n if (this.state.editingLinearElement) {\n this.setState({ editingLinearElement: null });\n }\n else {\n // Deselect selected elements\n this.setState({\n selectedElementIds: {},\n selectedGroupIds: {},\n editingGroupId: null,\n });\n }\n return;\n }\n if (!activeTool.locked &&\n activeTool.type !== \"freedraw\" &&\n draggingElement) {\n this.setState((prevState) => ({\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\n }));\n }\n if (activeTool.type !== \"selection\" ||\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getNonDeletedElements(), this.state)) {\n this.history.resumeRecording();\n }\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getNonDeletedElements(), this.state));\n }\n if (!activeTool.locked && activeTool.type !== \"freedraw\") {\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n activeTool: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.updateActiveTool)(this.state, { type: \"selection\" }),\n });\n }\n else {\n this.setState({\n draggingElement: null,\n suggestedBindings: [],\n });\n }\n });\n }\n maybeSuggestBindingForAll(selectedElements) {\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\n this.setState({ suggestedBindings });\n }\n clearSelection(hitElement) {\n this.setState((prevState) => ({\n selectedElementIds: {},\n selectedGroupIds: {},\n // Continue editing the same group if the user selected a different\n // element from it\n editingGroupId: prevState.editingGroupId &&\n hitElement != null &&\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\n ? prevState.editingGroupId\n : null,\n }));\n this.setState({\n selectedElementIds: {},\n previousSelectedElementIds: this.state.selectedElementIds,\n });\n }\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getTextBindableContainerAtPosition)(this.scene\n .getElementsIncludingDeleted()\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\n if (elementClickedInside) {\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_12__.TEXT_TO_CENTER_SNAP_THRESHOLD;\n if (isSnappedToCenter) {\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\n return { viewportX, viewportY, elementCenterX, elementCenterY };\n }\n }\n }\n getCanvasOffsets() {\n var _a;\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\n const excalidrawContainer = this.excalidrawContainerRef.current;\n const { left, top } = excalidrawContainer.getBoundingClientRect();\n return {\n offsetLeft: left,\n offsetTop: top,\n };\n }\n return {\n offsetLeft: 0,\n offsetTop: 0,\n };\n }\n updateLanguage() {\n return __awaiter(this, void 0, void 0, function* () {\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\n this.setAppState({});\n });\n }\n}\nApp.defaultProps = {\n // needed for tests to pass since we directly render App in many tests\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_12__.DEFAULT_UI_OPTIONS,\n};\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.TEST ||\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_12__.ENV.DEVELOPMENT ||\n ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true}).REACT_APP_VERCEL_ENV === \"preview\") {\n window.h = window.h || {};\n Object.defineProperties(window.h, {\n elements: {\n configurable: true,\n get() {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.getElementsIncludingDeleted();\n },\n set(elements) {\n var _a;\n return (_a = this.app) === null || _a === void 0 ? void 0 : _a.scene.replaceAllElements(elements);\n },\n },\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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RUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztnQkFDM0QsK0NBQVcsQ0FBQztZQUNkLE1BQU0sbURBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7S0FBQTs7QUFudkxhLGdCQUFZLEdBQXNCO0lBQzlDLHNFQUFzRTtJQUN0RSxTQUFTLEVBQUUsMkRBQWtCO0NBQzlCLENBQUM7QUFtd0xKLElBQ0UsYUFBb0IsS0FBSyxpREFBUTtJQUNqQyxhQUFvQixLQUFLLHdEQUFlO0lBQ3hDLGc0QkFBVyxDQUFDLG9CQUFvQixLQUFLLFNBQVMsRUFDOUM7SUFDQSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUssRUFBa0IsQ0FBQztJQUUzQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtRQUNoQyxRQUFRLEVBQUU7WUFDUixZQUFZLEVBQUUsSUFBSTtZQUNsQixHQUFHOztnQkFDRCxPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBQ3ZELENBQUM7WUFDRCxHQUFHLENBQUMsUUFBNkI7O2dCQUMvQixPQUFPLFVBQUksQ0FBQyxHQUFHLDBDQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0RCxDQUFDO1NBQ0Y7S0FDRixDQUFDLENBQUM7Q0FDSjtBQUVELGlFQUFlLEdBQUcsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9jb21wb25lbnRzL0FwcC50c3g/MDA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgZmx1c2hTeW5jIH0gZnJvbSBcInJlYWN0LWRvbVwiO1xuXG5pbXBvcnQgeyBSb3VnaENhbnZhcyB9IGZyb20gXCJyb3VnaGpzL2Jpbi9jYW52YXNcIjtcbmltcG9ydCByb3VnaCBmcm9tIFwicm91Z2hqcy9iaW4vcm91Z2hcIjtcbmltcG9ydCBjbHN4IGZyb20gXCJjbHN4XCI7XG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tIFwibmFub2lkXCI7XG5cbmltcG9ydCB7XG4gIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgYWN0aW9uQnJpbmdGb3J3YXJkLFxuICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gIGFjdGlvbkNvcHksXG4gIGFjdGlvbkNvcHlBc1BuZyxcbiAgYWN0aW9uQ29weUFzU3ZnLFxuICBjb3B5VGV4dCxcbiAgYWN0aW9uQ29weVN0eWxlcyxcbiAgYWN0aW9uQ3V0LFxuICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICBhY3Rpb25GaW5hbGl6ZSxcbiAgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgYWN0aW9uR3JvdXAsXG4gIGFjdGlvblBhc3RlU3R5bGVzLFxuICBhY3Rpb25TZWxlY3RBbGwsXG4gIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgYWN0aW9uU2VuZFRvQmFjayxcbiAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gIGFjdGlvblRvZ2dsZVN0YXRzLFxuICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICBhY3Rpb25VbmJpbmRUZXh0LFxuICBhY3Rpb25CaW5kVGV4dCxcbiAgYWN0aW9uVW5ncm91cCxcbiAgYWN0aW9uTGluayxcbiAgYWN0aW9uVG9nZ2xlTG9jayxcbn0gZnJvbSBcIi4uL2FjdGlvbnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZG9BY3Rpb24sIGNyZWF0ZVVuZG9BY3Rpb24gfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25IaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb25NYW5hZ2VyIH0gZnJvbSBcIi4uL2FjdGlvbnMvbWFuYWdlclwiO1xuaW1wb3J0IHsgYWN0aW9ucyB9IGZyb20gXCIuLi9hY3Rpb25zL3JlZ2lzdGVyXCI7XG5pbXBvcnQgeyBBY3Rpb25SZXN1bHQgfSBmcm9tIFwiLi4vYWN0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgdHJhY2tFdmVudCB9IGZyb20gXCIuLi9hbmFseXRpY3NcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSwgaXNFcmFzZXJBY3RpdmUgfSBmcm9tIFwiLi4vYXBwU3RhdGVcIjtcbmltcG9ydCB7XG4gIHBhcnNlQ2xpcGJvYXJkLFxuICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYixcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCxcbn0gZnJvbSBcIi4uL2NsaXBib2FyZFwiO1xuaW1wb3J0IHtcbiAgQVBQX05BTUUsXG4gIENVUlNPUl9UWVBFLFxuICBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gIERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgRFJBR0dJTkdfVEhSRVNIT0xELFxuICBFTEVNRU5UX1JFQURZX1RPX0VSQVNFX09QQUNJVFksXG4gIEVMRU1FTlRfU0hJRlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTlYsXG4gIEVWRU5ULFxuICBHUklEX1NJWkUsXG4gIElNQUdFX1JFTkRFUl9USU1FT1VULFxuICBMSU5FX0NPTkZJUk1fVEhSRVNIT0xELFxuICBNQVhfQUxMT1dFRF9GSUxFX0JZVEVTLFxuICBNSU1FX1RZUEVTLFxuICBNUV9NQVhfSEVJR0hUX0xBTkRTQ0FQRSxcbiAgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSxcbiAgTVFfTUFYX1dJRFRIX1BPUlRSQUlULFxuICBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSCxcbiAgTVFfU01fTUFYX1dJRFRILFxuICBQT0lOVEVSX0JVVFRPTixcbiAgU0NST0xMX1RJTUVPVVQsXG4gIFRBUF9UV0lDRV9USU1FT1VULFxuICBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRCxcbiAgVEhFTUUsXG4gIFRPVUNIX0NUWF9NRU5VX1RJTUVPVVQsXG4gIFZFUlRJQ0FMX0FMSUdOLFxufSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBsb2FkRnJvbUJsb2IgfSBmcm9tIFwiLi4vZGF0YVwiO1xuaW1wb3J0IExpYnJhcnksIHsgZGlzdHJpYnV0ZUxpYnJhcnlJdGVtc09uU3F1YXJlR3JpZCB9IGZyb20gXCIuLi9kYXRhL2xpYnJhcnlcIjtcbmltcG9ydCB7IHJlc3RvcmUsIHJlc3RvcmVFbGVtZW50cyB9IGZyb20gXCIuLi9kYXRhL3Jlc3RvcmVcIjtcbmltcG9ydCB7XG4gIGRyYWdOZXdFbGVtZW50LFxuICBkcmFnU2VsZWN0ZWRFbGVtZW50cyxcbiAgZHVwbGljYXRlRWxlbWVudCxcbiAgZ2V0Q29tbW9uQm91bmRzLFxuICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQsXG4gIGdldERyYWdPZmZzZXRYWSxcbiAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLFxuICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyxcbiAgZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24sXG4gIGdldFJlc2l6ZU9mZnNldFhZLFxuICBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUsXG4gIGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzLFxuICBoaXRUZXN0LFxuICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQsXG4gIGlzSW52aXNpYmx5U21hbGxFbGVtZW50LFxuICBpc05vbkRlbGV0ZWRFbGVtZW50LFxuICBpc1RleHRFbGVtZW50LFxuICBuZXdFbGVtZW50LFxuICBuZXdMaW5lYXJFbGVtZW50LFxuICBuZXdUZXh0RWxlbWVudCxcbiAgbmV3SW1hZ2VFbGVtZW50LFxuICB0ZXh0V3lzaXd5ZyxcbiAgdHJhbnNmb3JtRWxlbWVudHMsXG4gIHVwZGF0ZVRleHRFbGVtZW50LFxufSBmcm9tIFwiLi4vZWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgYmluZE9yVW5iaW5kTGluZWFyRWxlbWVudCxcbiAgYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50cyxcbiAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uLFxuICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24sXG4gIGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nLFxuICBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcsXG4gIGlzQmluZGluZ0VuYWJsZWQsXG4gIGlzTGluZWFyRWxlbWVudFNpbXBsZUFuZEFscmVhZHlCb3VuZCxcbiAgbWF5YmVCaW5kTGluZWFyRWxlbWVudCxcbiAgc2hvdWxkRW5hYmxlQmluZGluZ0ZvclBvaW50ZXJFdmVudCxcbiAgdW5iaW5kTGluZWFyRWxlbWVudHMsXG4gIHVwZGF0ZUJvdW5kRWxlbWVudHMsXG59IGZyb20gXCIuLi9lbGVtZW50L2JpbmRpbmdcIjtcbmltcG9ydCB7IExpbmVhckVsZW1lbnRFZGl0b3IgfSBmcm9tIFwiLi4vZWxlbWVudC9saW5lYXJFbGVtZW50RWRpdG9yXCI7XG5pbXBvcnQgeyBtdXRhdGVFbGVtZW50LCBuZXdFbGVtZW50V2l0aCB9IGZyb20gXCIuLi9lbGVtZW50L211dGF0ZUVsZW1lbnRcIjtcbmltcG9ydCB7IGRlZXBDb3B5RWxlbWVudCwgbmV3RnJlZURyYXdFbGVtZW50IH0gZnJvbSBcIi4uL2VsZW1lbnQvbmV3RWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgaGFzQm91bmRUZXh0RWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudCxcbiAgaXNCaW5kaW5nRWxlbWVudFR5cGUsXG4gIGlzQm91bmRUb0NvbnRhaW5lcixcbiAgaXNJbWFnZUVsZW1lbnQsXG4gIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50VHlwZSxcbiAgaXNUZXh0QmluZGFibGVDb250YWluZXIsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVDaGVja3NcIjtcbmltcG9ydCB7XG4gIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50LFxuICBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50LFxuICBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gIE5vbkRlbGV0ZWQsXG4gIEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgRmlsZUlkLFxuICBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0Q29udGFpbmVyLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q2VudGVyLCBnZXREaXN0YW5jZSB9IGZyb20gXCIuLi9nZXN0dXJlXCI7XG5pbXBvcnQge1xuICBlZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQsXG4gIGdldEVsZW1lbnRzSW5Hcm91cCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkRm9yRWxlbWVudCxcbiAgZ2V0U2VsZWN0ZWRHcm91cElkcyxcbiAgaXNFbGVtZW50SW5Hcm91cCxcbiAgaXNTZWxlY3RlZFZpYUdyb3VwLFxuICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZ3JvdXBzXCI7XG5pbXBvcnQgSGlzdG9yeSBmcm9tIFwiLi4vaGlzdG9yeVwiO1xuaW1wb3J0IHsgZGVmYXVsdExhbmcsIGdldExhbmd1YWdlLCBsYW5ndWFnZXMsIHNldExhbmd1YWdlLCB0IH0gZnJvbSBcIi4uL2kxOG5cIjtcbmltcG9ydCB7XG4gIENPREVTLFxuICBzaG91bGRSZXNpemVGcm9tQ2VudGVyLFxuICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvLFxuICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZSxcbiAgaXNBcnJvd0tleSxcbiAgS0VZUyxcbiAgaXNBbmRyb2lkLFxufSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHsgZGlzdGFuY2UyZCwgZ2V0R3JpZFBvaW50LCBpc1BhdGhBTG9vcCB9IGZyb20gXCIuLi9tYXRoXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJTY2VuZVwiO1xuaW1wb3J0IHsgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudCB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJFbGVtZW50XCI7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVTY3JvbGxDZW50ZXIsXG4gIGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24sXG4gIGdldEVsZW1lbnRzQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24sXG4gIGdldE5vcm1hbGl6ZWRab29tLFxuICBnZXRTZWxlY3RlZEVsZW1lbnRzLFxuICBoYXNCYWNrZ3JvdW5kLFxuICBpc092ZXJTY3JvbGxCYXJzLFxuICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQsXG59IGZyb20gXCIuLi9zY2VuZVwiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgUmVuZGVyQ29uZmlnLCBTY3JvbGxCYXJzIH0gZnJvbSBcIi4uL3NjZW5lL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRTdGF0ZUZvclpvb20gfSBmcm9tIFwiLi4vc2NlbmUvem9vbVwiO1xuaW1wb3J0IHsgZmluZFNoYXBlQnlLZXksIFNIQVBFUyB9IGZyb20gXCIuLi9zaGFwZXNcIjtcbmltcG9ydCB7XG4gIEFwcENsYXNzUHJvcGVydGllcyxcbiAgQXBwUHJvcHMsXG4gIEFwcFN0YXRlLFxuICBCaW5hcnlGaWxlRGF0YSxcbiAgRGF0YVVSTCxcbiAgRXhjYWxpZHJhd0ltcGVyYXRpdmVBUEksXG4gIEJpbmFyeUZpbGVzLFxuICBHZXN0dXJlLFxuICBHZXN0dXJlRXZlbnQsXG4gIExpYnJhcnlJdGVtcyxcbiAgUG9pbnRlckRvd25TdGF0ZSxcbiAgU2NlbmVEYXRhLFxuICBEZXZpY2UsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZGVib3VuY2UsXG4gIGRpc3RhbmNlLFxuICBnZXRGb250U3RyaW5nLFxuICBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcixcbiAgaXNJbnB1dExpa2UsXG4gIGlzVG9vbEljb24sXG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICByZXNldEN1cnNvcixcbiAgcmVzb2x2YWJsZVByb21pc2UsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyxcbiAgc2V0Q3Vyc29yLFxuICBzZXRDdXJzb3JGb3JTaGFwZSxcbiAgdHVwbGVUb0Nvb3JzLFxuICB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMsXG4gIHdpdGhCYXRjaGVkVXBkYXRlcyxcbiAgd3JhcEV2ZW50LFxuICB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQsXG4gIHVwZGF0ZU9iamVjdCxcbiAgc2V0RXJhc2VyQ3Vyc29yLFxuICB1cGRhdGVBY3RpdmVUb29sLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCBDb250ZXh0TWVudSwgeyBDb250ZXh0TWVudU9wdGlvbiB9IGZyb20gXCIuL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgTGF5ZXJVSSBmcm9tIFwiLi9MYXllclVJXCI7XG5pbXBvcnQgeyBUb2FzdCB9IGZyb20gXCIuL1RvYXN0XCI7XG5pbXBvcnQgeyBhY3Rpb25Ub2dnbGVWaWV3TW9kZSB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvblRvZ2dsZVZpZXdNb2RlXCI7XG5pbXBvcnQge1xuICBkYXRhVVJMVG9GaWxlLFxuICBnZW5lcmF0ZUlkRnJvbUZpbGUsXG4gIGdldERhdGFVUkwsXG4gIGdldEZpbGVGcm9tRXZlbnQsXG4gIGlzU3VwcG9ydGVkSW1hZ2VGaWxlLFxuICBsb2FkU2NlbmVPckxpYnJhcnlGcm9tQmxvYixcbiAgbm9ybWFsaXplRmlsZSxcbiAgcGFyc2VMaWJyYXJ5SlNPTixcbiAgcmVzaXplSW1hZ2VGaWxlLFxuICBTVkdTdHJpbmdUb0ZpbGUsXG59IGZyb20gXCIuLi9kYXRhL2Jsb2JcIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgbG9hZEhUTUxJbWFnZUVsZW1lbnQsXG4gIG5vcm1hbGl6ZVNWRyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSBhcyBfdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB0aHJvdHRsZSBmcm9tIFwibG9kYXNoLnRocm90dGxlXCI7XG5pbXBvcnQgeyBmaWxlT3BlbiwgRmlsZVN5c3RlbUhhbmRsZSB9IGZyb20gXCIuLi9kYXRhL2ZpbGVzeXN0ZW1cIjtcbmltcG9ydCB7XG4gIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24sXG4gIGdldEFwcHJveE1pbkxpbmVIZWlnaHQsXG4gIGdldEFwcHJveE1pbkxpbmVXaWR0aCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdGV4dEVsZW1lbnRcIjtcbmltcG9ydCB7IGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94IH0gZnJvbSBcIi4uL2VsZW1lbnQvY29sbGlzaW9uXCI7XG5pbXBvcnQge1xuICBub3JtYWxpemVMaW5rLFxuICBzaG93SHlwZXJsaW5rVG9vbHRpcCxcbiAgaGlkZUh5cGVybGlua1Rvb2xpcCxcbiAgSHlwZXJsaW5rLFxuICBpc1BvaW50SGl0dGluZ0xpbmtJY29uLFxuICBpc0xvY2FsTGluayxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvSHlwZXJsaW5rXCI7XG5pbXBvcnQgeyBzaG91bGRTaG93Qm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC90cmFuc2Zvcm1IYW5kbGVzXCI7XG5cbmNvbnN0IFRJTUVTX0FHR1I6IFJlY29yZDxzdHJpbmcsIHsgdDogbnVtYmVyOyB0aW1lczogbnVtYmVyW10gfT4gPSB7fTtcbmNvbnN0IFRJTUVTX0FWRzogUmVjb3JkPHN0cmluZywgeyB0aW1lczogbnVtYmVyW10gfT4gPSB7fTtcblxud2luZG93LkRFQlVHX0xPR19USU1FUyA9IHRydWU7XG5cbnNldEludGVydmFsKCgpID0+IHtcbiAgaWYgKHdpbmRvdy5ERUJVR19MT0dfVElNRVMpIHtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCB7IHQsIHRpbWVzIH1dIG9mIE9iamVjdC5lbnRyaWVzKFRJTUVTX0FHR1IpKSB7XG4gICAgICBpZiAodGltZXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHRpbWVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpLFxuICAgICAgICAgIHRpbWVzLnNvcnQoKGEsIGIpID0+IGEgLSBiKSxcbiAgICAgICAgKTtcbiAgICAgICAgVElNRVNfQUdHUltuYW1lXSA9IHsgdCwgdGltZXM6IFtdIH07XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgW25hbWUsIHsgdGltZXMgfV0gb2YgT2JqZWN0LmVudHJpZXMoVElNRVNfQVZHKSkge1xuICAgICAgaWYgKHRpbWVzLmxlbmd0aCkge1xuICAgICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBwYXJzZUZsb2F0KFxuICAgICAgICAgICAgKHRpbWVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpIC8gdGltZXMubGVuZ3RoKS50b1ByZWNpc2lvbig1KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHRpbWVzLnNvcnQoKGEsIGIpID0+IGEgLSBiKSxcbiAgICAgICAgKTtcbiAgICAgICAgVElNRVNfQVZHW25hbWVdID0geyB0aW1lczogW10gfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0sIDEwMDApO1xuXG53aW5kb3cubG9nVGltZSA9IChuYW1lOiBzdHJpbmcsIHRpbWU/OiBudW1iZXIpID0+IHtcbiAgY29uc3QgeyB0LCB0aW1lcyB9ID0gKFRJTUVTX0FHR1JbbmFtZV0gPSBUSU1FU19BR0dSW25hbWVdIHx8IHtcbiAgICB0OiAwLFxuICAgIHRpbWVzOiBbXSxcbiAgfSk7XG4gIGlmICh0KSB7XG4gICAgdGltZXMucHVzaCh0aW1lICE9IG51bGwgPyB0aW1lIDogRGF0ZS5ub3coKSAtIHQpO1xuICB9XG4gIFRJTUVTX0FHR1JbbmFtZV0udCA9IERhdGUubm93KCk7XG59O1xud2luZG93LmxvZ1RpbWVBdmVyYWdlID0gKG5hbWU6IHN0cmluZywgdGltZTogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHsgdGltZXMgfSA9IChUSU1FU19BVkdbbmFtZV0gPSBUSU1FU19BVkdbbmFtZV0gfHwgeyB0aW1lczogW10gfSk7XG4gIHRpbWVzLnB1c2godGltZSk7XG59O1xuXG5jb25zdCBkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlID0ge1xuICBpc1NtU2NyZWVuOiBmYWxzZSxcbiAgaXNNb2JpbGU6IGZhbHNlLFxuICBpc1RvdWNoU2NyZWVuOiBmYWxzZSxcbiAgY2FuRGV2aWNlRml0U2lkZWJhcjogZmFsc2UsXG59O1xuY29uc3QgRGV2aWNlQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8RGV2aWNlPihkZXZpY2VDb250ZXh0SW5pdGlhbFZhbHVlKTtcbmV4cG9ydCBjb25zdCB1c2VEZXZpY2UgPSAoKSA9PiB1c2VDb250ZXh0PERldmljZT4oRGV2aWNlQ29udGV4dCk7XG5jb25zdCBFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8e1xuICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgaWQ6IHN0cmluZyB8IG51bGw7XG59Pih7IGNvbnRhaW5lcjogbnVsbCwgaWQ6IG51bGwgfSk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0NvbnRhaW5lciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQpO1xuXG5sZXQgZGlkVGFwVHdpY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCB0YXBwZWRUd2ljZVRpbWVyID0gMDtcbmxldCBjdXJzb3JYID0gMDtcbmxldCBjdXJzb3JZID0gMDtcbmxldCBpc0hvbGRpbmdTcGFjZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzUGFubmluZzogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzRHJhZ2dpbmdTY3JvbGxCYXI6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBjdXJyZW50U2Nyb2xsQmFyczogU2Nyb2xsQmFycyA9IHsgaG9yaXpvbnRhbDogbnVsbCwgdmVydGljYWw6IG51bGwgfTtcbmxldCB0b3VjaFRpbWVvdXQgPSAwO1xubGV0IGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4vLyByZW1vdmUgdGhpcyBoYWNrIHdoZW4gd2UgY2FuIHN5bmMgcmVuZGVyICYgcmVzaXplT2JzZXJ2ZXIgKHN0YXRlIHVwZGF0ZSlcbi8vIHRvIHJBRi4gU2VlICM1NDM5XG5sZXQgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSB0cnVlO1xuXG5sZXQgbGFzdFBvaW50ZXJVcDogKChldmVudDogYW55KSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuY29uc3QgZ2VzdHVyZTogR2VzdHVyZSA9IHtcbiAgcG9pbnRlcnM6IG5ldyBNYXAoKSxcbiAgbGFzdENlbnRlcjogbnVsbCxcbiAgaW5pdGlhbERpc3RhbmNlOiBudWxsLFxuICBpbml0aWFsU2NhbGU6IG51bGwsXG59O1xuXG5jbGFzcyBBcHAgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8QXBwUHJvcHMsIEFwcFN0YXRlPiB7XG4gIGNhbnZhczogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiY2FudmFzXCJdID0gbnVsbDtcbiAgcmM6IFJvdWdoQ2FudmFzIHwgbnVsbCA9IG51bGw7XG4gIHVubW91bnRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBhY3Rpb25NYW5hZ2VyOiBBY3Rpb25NYW5hZ2VyO1xuICBkZXZpY2U6IERldmljZSA9IGRldmljZUNvbnRleHRJbml0aWFsVmFsdWU7XG4gIGRldGFjaElzTW9iaWxlTXFIYW5kbGVyPzogKCkgPT4gdm9pZDtcblxuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJSZWYgPSBSZWFjdC5jcmVhdGVSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHM6IFBhcnRpYWw8QXBwUHJvcHM+ID0ge1xuICAgIC8vIG5lZWRlZCBmb3IgdGVzdHMgdG8gcGFzcyBzaW5jZSB3ZSBkaXJlY3RseSByZW5kZXIgQXBwIGluIG1hbnkgdGVzdHNcbiAgICBVSU9wdGlvbnM6IERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgfTtcblxuICBwdWJsaWMgc2NlbmU6IFNjZW5lO1xuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBuZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBEb2N1bWVudCB8IHVuZGVmaW5lZDtcbiAgcHVibGljIGxpYnJhcnk6IEFwcENsYXNzUHJvcGVydGllc1tcImxpYnJhcnlcIl07XG4gIHB1YmxpYyBsaWJyYXJ5SXRlbXNGcm9tU3RvcmFnZTogTGlicmFyeUl0ZW1zIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gIHByaXZhdGUgaGlzdG9yeTogSGlzdG9yeTtcbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyVmFsdWU6IHtcbiAgICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgICBpZDogc3RyaW5nO1xuICB9O1xuXG4gIHB1YmxpYyBmaWxlczogQmluYXJ5RmlsZXMgPSB7fTtcbiAgcHVibGljIGltYWdlQ2FjaGU6IEFwcENsYXNzUHJvcGVydGllc1tcImltYWdlQ2FjaGVcIl0gPSBuZXcgTWFwKCk7XG5cbiAgaGl0TGlua0VsZW1lbnQ/OiBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQ7XG4gIGxhc3RQb2ludGVyRG93bjogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PiB8IG51bGwgPSBudWxsO1xuICBsYXN0UG9pbnRlclVwOiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTEVsZW1lbnQ+IHwgUG9pbnRlckV2ZW50IHwgbnVsbCA9IG51bGw7XG4gIGNvbnRleHRNZW51T3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuICBsYXN0U2NlbmVQb2ludGVyOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXBwUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG4gICAgY29uc3Qge1xuICAgICAgZXhjYWxpZHJhd1JlZixcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgemVuTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIGdyaWRNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgdGhlbWUgPSBkZWZhdWx0QXBwU3RhdGUudGhlbWUsXG4gICAgICBuYW1lID0gZGVmYXVsdEFwcFN0YXRlLm5hbWUsXG4gICAgfSA9IHByb3BzO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi5kZWZhdWx0QXBwU3RhdGUsXG4gICAgICB0aGVtZSxcbiAgICAgIGlzTG9hZGluZzogdHJ1ZSxcbiAgICAgIC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpLFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICBncmlkU2l6ZTogZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIG5hbWUsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICAgIHNob3dIeXBlcmxpbmtQb3B1cDogZmFsc2UsXG4gICAgICBpc0xpYnJhcnlNZW51RG9ja2VkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgdGhpcy5pZCA9IG5hbm9pZCgpO1xuXG4gICAgdGhpcy5saWJyYXJ5ID0gbmV3IExpYnJhcnkodGhpcyk7XG4gICAgaWYgKGV4Y2FsaWRyYXdSZWYpIHtcbiAgICAgIGNvbnN0IHJlYWR5UHJvbWlzZSA9XG4gICAgICAgIChcImN1cnJlbnRcIiBpbiBleGNhbGlkcmF3UmVmICYmIGV4Y2FsaWRyYXdSZWYuY3VycmVudD8ucmVhZHlQcm9taXNlKSB8fFxuICAgICAgICByZXNvbHZhYmxlUHJvbWlzZTxFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQST4oKTtcblxuICAgICAgY29uc3QgYXBpOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSA9IHtcbiAgICAgICAgcmVhZHk6IHRydWUsXG4gICAgICAgIHJlYWR5UHJvbWlzZSxcbiAgICAgICAgdXBkYXRlU2NlbmU6IHRoaXMudXBkYXRlU2NlbmUsXG4gICAgICAgIHVwZGF0ZUxpYnJhcnk6IHRoaXMubGlicmFyeS51cGRhdGVMaWJyYXJ5LFxuICAgICAgICBhZGRGaWxlczogdGhpcy5hZGRGaWxlcyxcbiAgICAgICAgcmVzZXRTY2VuZTogdGhpcy5yZXNldFNjZW5lLFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZDogdGhpcy5nZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNsZWFyOiB0aGlzLnJlc2V0SGlzdG9yeSxcbiAgICAgICAgfSxcbiAgICAgICAgc2Nyb2xsVG9Db250ZW50OiB0aGlzLnNjcm9sbFRvQ29udGVudCxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50czogdGhpcy5nZXRTY2VuZUVsZW1lbnRzLFxuICAgICAgICBnZXRBcHBTdGF0ZTogKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICAgZ2V0RmlsZXM6ICgpID0+IHRoaXMuZmlsZXMsXG4gICAgICAgIHJlZnJlc2g6IHRoaXMucmVmcmVzaCxcbiAgICAgICAgc2V0VG9hc3Q6IHRoaXMuc2V0VG9hc3QsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBzZXRBY3RpdmVUb29sOiB0aGlzLnNldEFjdGl2ZVRvb2wsXG4gICAgICAgIHNldEN1cnNvcjogdGhpcy5zZXRDdXJzb3IsXG4gICAgICAgIHJlc2V0Q3Vyc29yOiB0aGlzLnJlc2V0Q3Vyc29yLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICAgIGlmICh0eXBlb2YgZXhjYWxpZHJhd1JlZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYoYXBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYuY3VycmVudCA9IGFwaTtcbiAgICAgIH1cbiAgICAgIHJlYWR5UHJvbWlzZS5yZXNvbHZlKGFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUgPSB7XG4gICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgfTtcblxuICAgIHRoaXMuc2NlbmUgPSBuZXcgU2NlbmUoKTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSgpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlciA9IG5ldyBBY3Rpb25NYW5hZ2VyKFxuICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0LFxuICAgICAgKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICgpID0+IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLFxuICAgICk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWxsKGFjdGlvbnMpO1xuXG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVVuZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVJlZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNTY2FsZSA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY2FudmFzRE9NV2lkdGggKiBjYW52YXNTY2FsZTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXNET01IZWlnaHQgKiBjYW52YXNTY2FsZTtcbiAgICBpZiAodmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Y2FudmFzXG4gICAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgICAgICBjdXJzb3I6IENVUlNPUl9UWVBFLkdSQUIsXG4gICAgICAgICAgfX1cbiAgICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICAgIG9uVG91Y2hNb3ZlPXt0aGlzLmhhbmRsZVRvdWNoTW92ZX1cbiAgICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICA+XG4gICAgICAgICAge3QoXCJsYWJlbHMuZHJhd2luZ0NhbnZhc1wiKX1cbiAgICAgICAgPC9jYW52YXM+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGNhbnZhc1xuICAgICAgICBjbGFzc05hbWU9XCJleGNhbGlkcmF3X19jYW52YXNcIlxuICAgICAgICBzdHlsZT17e1xuICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgICAgfX1cbiAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICBoZWlnaHQ9e2NhbnZhc0hlaWdodH1cbiAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgb25Eb3VibGVDbGljaz17dGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGlja31cbiAgICAgICAgb25Qb2ludGVyTW92ZT17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyTW92ZX1cbiAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlclVwfVxuICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgPlxuICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgPC9jYW52YXM+XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX19yZW5kZXJVSSA9IHRydWU7XG5cbiAgcHVibGljIHJlbmRlcigpIHtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCB7XG4gICAgICBvbkNvbGxhYkJ1dHRvbkNsaWNrLFxuICAgICAgcmVuZGVyVG9wUmlnaHRVSSxcbiAgICAgIHJlbmRlckZvb3RlcixcbiAgICAgIHJlbmRlckN1c3RvbVN0YXRzLFxuICAgIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3NOYW1lPXtjbHN4KFwiZXhjYWxpZHJhdyBleGNhbGlkcmF3LWNvbnRhaW5lclwiLCB7XG4gICAgICAgICAgXCJleGNhbGlkcmF3LS12aWV3LW1vZGVcIjogdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgXCJleGNhbGlkcmF3LS1tb2JpbGVcIjogdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIH0pfVxuICAgICAgICByZWY9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZn1cbiAgICAgICAgb25Ecm9wPXt0aGlzLmhhbmRsZUFwcE9uRHJvcH1cbiAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgIG9uS2V5RG93bj17XG4gICAgICAgICAgdGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5ID8gdW5kZWZpbmVkIDogdGhpcy5vbktleURvd25cbiAgICAgICAgfVxuICAgICAgPlxuICAgICAgICA8RXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICB2YWx1ZT17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWV9XG4gICAgICAgID5cbiAgICAgICAgICA8RGV2aWNlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpcy5kZXZpY2V9PlxuICAgICAgICAgICAge3RoaXMuX19yZW5kZXJVSSAmJiAoXG4gICAgICAgICAgICAgIDxMYXllclVJXG4gICAgICAgICAgICAgICAgY2FudmFzPXt0aGlzLmNhbnZhc31cbiAgICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgICBmaWxlcz17dGhpcy5maWxlc31cbiAgICAgICAgICAgICAgICBzZXRBcHBTdGF0ZT17dGhpcy5zZXRBcHBTdGF0ZX1cbiAgICAgICAgICAgICAgICBhY3Rpb25NYW5hZ2VyPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgICAgZWxlbWVudHM9e3RoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgICAgb25Db2xsYWJCdXR0b25DbGljaz17b25Db2xsYWJCdXR0b25DbGlja31cbiAgICAgICAgICAgICAgICBvbkxvY2tUb2dnbGU9e3RoaXMudG9nZ2xlTG9ja31cbiAgICAgICAgICAgICAgICBvblBlbk1vZGVUb2dnbGU9e3RoaXMudG9nZ2xlUGVuTW9kZX1cbiAgICAgICAgICAgICAgICBvbkluc2VydEVsZW1lbnRzPXsoZWxlbWVudHMpID0+XG4gICAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxhbmdDb2RlPXtnZXRMYW5ndWFnZSgpLmNvZGV9XG4gICAgICAgICAgICAgICAgaXNDb2xsYWJvcmF0aW5nPXt0aGlzLnByb3BzLmlzQ29sbGFib3JhdGluZ31cbiAgICAgICAgICAgICAgICByZW5kZXJUb3BSaWdodFVJPXtyZW5kZXJUb3BSaWdodFVJfVxuICAgICAgICAgICAgICAgIHJlbmRlckN1c3RvbUZvb3Rlcj17cmVuZGVyRm9vdGVyfVxuICAgICAgICAgICAgICAgIHJlbmRlckN1c3RvbVN0YXRzPXtyZW5kZXJDdXN0b21TdGF0c31cbiAgICAgICAgICAgICAgICBzaG93RXhpdFplbk1vZGVCdG49e1xuICAgICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHM/Lnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnplbk1vZGVFbmFibGVkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNob3dUaGVtZUJ0bj17XG4gICAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8udGhlbWUgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmNhbnZhc0FjdGlvbnMudGhlbWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGlicmFyeVJldHVyblVybD17dGhpcy5wcm9wcy5saWJyYXJ5UmV0dXJuVXJsfVxuICAgICAgICAgICAgICAgIFVJT3B0aW9ucz17dGhpcy5wcm9wcy5VSU9wdGlvbnN9XG4gICAgICAgICAgICAgICAgZm9jdXNDb250YWluZXI9e3RoaXMuZm9jdXNDb250YWluZXJ9XG4gICAgICAgICAgICAgICAgbGlicmFyeT17dGhpcy5saWJyYXJ5fVxuICAgICAgICAgICAgICAgIGlkPXt0aGlzLmlkfVxuICAgICAgICAgICAgICAgIG9uSW1hZ2VBY3Rpb249e3RoaXMub25JbWFnZUFjdGlvbn1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImV4Y2FsaWRyYXctdGV4dEVkaXRvckNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImV4Y2FsaWRyYXctY29udGV4dE1lbnVDb250YWluZXJcIiAvPlxuICAgICAgICAgICAge3NlbGVjdGVkRWxlbWVudC5sZW5ndGggPT09IDEgJiYgdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXAgJiYgKFxuICAgICAgICAgICAgICA8SHlwZXJsaW5rXG4gICAgICAgICAgICAgICAga2V5PXtzZWxlY3RlZEVsZW1lbnRbMF0uaWR9XG4gICAgICAgICAgICAgICAgZWxlbWVudD17c2VsZWN0ZWRFbGVtZW50WzBdfVxuICAgICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgIG9uTGlua09wZW49e3RoaXMucHJvcHMub25MaW5rT3Blbn1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS50b2FzdCAhPT0gbnVsbCAmJiAoXG4gICAgICAgICAgICAgIDxUb2FzdFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U9e3RoaXMuc3RhdGUudG9hc3QubWVzc2FnZX1cbiAgICAgICAgICAgICAgICBvbkNsb3NlPXsoKSA9PiB0aGlzLnNldFRvYXN0KG51bGwpfVxuICAgICAgICAgICAgICAgIGR1cmF0aW9uPXt0aGlzLnN0YXRlLnRvYXN0LmR1cmF0aW9ufVxuICAgICAgICAgICAgICAgIGNsb3NhYmxlPXt0aGlzLnN0YXRlLnRvYXN0LmNsb3NhYmxlfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxtYWluPnt0aGlzLnJlbmRlckNhbnZhcygpfTwvbWFpbj5cbiAgICAgICAgICA8L0RldmljZUNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGZvY3VzQ29udGFpbmVyOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJmb2N1c0NvbnRhaW5lclwiXSA9ICgpID0+IHtcbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gIH07XG5cbiAgcHVibGljIGdldFNjZW5lRWxlbWVudHMgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBzeW5jQWN0aW9uUmVzdWx0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChhY3Rpb25SZXN1bHQ6IEFjdGlvblJlc3VsdCkgPT4ge1xuICAgICAgLy8gU2luY2UgY29udGV4dCBtZW51IGNsb3NlcyB3aGVuIGFjdGlvbiB0cmlnZ2VyZWQgc28gc2V0dGluZyB0byBmYWxzZVxuICAgICAgdGhpcy5jb250ZXh0TWVudU9wZW4gPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLnVubW91bnRlZCB8fCBhY3Rpb25SZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGVkaXRpbmdFbGVtZW50OiBBcHBTdGF0ZVtcImVkaXRpbmdFbGVtZW50XCJdIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKSB7XG4gICAgICAgIGFjdGlvblJlc3VsdC5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudD8uaWQgPT09IGVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgIT09IGVsZW1lbnQgJiZcbiAgICAgICAgICAgIGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhhY3Rpb25SZXN1bHQuZWxlbWVudHMpO1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmZpbGVzKSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBhY3Rpb25SZXN1bHQucmVwbGFjZUZpbGVzXG4gICAgICAgICAgPyBhY3Rpb25SZXN1bHQuZmlsZXNcbiAgICAgICAgICA6IHsgLi4udGhpcy5maWxlcywgLi4uYWN0aW9uUmVzdWx0LmZpbGVzIH07XG4gICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwgZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlld01vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udmlld01vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgemVuTW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy56ZW5Nb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IGdyaWRTaXplID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZ3JpZFNpemUgfHwgbnVsbDtcbiAgICAgICAgbGV0IHRoZW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udGhlbWUgfHwgVEhFTUUuTElHSFQ7XG4gICAgICAgIGxldCBuYW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8ubmFtZSA/PyB0aGlzLnN0YXRlLm5hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHplbk1vZGVFbmFibGVkID0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBncmlkU2l6ZSA9IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy50aGVtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHRoZW1lID0gdGhpcy5wcm9wcy50aGVtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5uYW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgbmFtZSA9IHRoaXMucHJvcHMubmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgLy8gdXNpbmcgT2JqZWN0LmFzc2lnbiBpbnN0ZWFkIG9mIHNwcmVhZCB0byBmb29sIFRTIDQuMi4yKyBpbnRvXG4gICAgICAgICAgICAvLyByZWdhcmRpbmcgdGhlIHJlc3VsdGluZyB0eXBlIGFzIG5vdCBjb250YWluaW5nIHVuZGVmaW5lZFxuICAgICAgICAgICAgLy8gKHdoaWNoIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiB3aWxsIG5ldmVyIGNvbnRhaW4pXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwge30sIHtcbiAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgfHwgYWN0aW9uUmVzdWx0LmFwcFN0YXRlPy5lZGl0aW5nRWxlbWVudCB8fCBudWxsLFxuICAgICAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgICAgICAgICBncmlkU2l6ZSxcbiAgICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb25SZXN1bHQuc3luY0hpc3RvcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnNldEN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIC8vIExpZmVjeWNsZVxuXG4gIHByaXZhdGUgb25CbHVyID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBwcml2YXRlIG9uVW5sb2FkID0gKCkgPT4ge1xuICAgIHRoaXMub25CbHVyKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRXZlbnQ6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIHByaXZhdGUgb25Gb250TG9hZGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uU2NlbmVVcGRhdGVkKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEhpc3RvcnkgPSAoKSA9PiB7XG4gICAgdGhpcy5oaXN0b3J5LmNsZWFyKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBzY2VuZSAmIGhpc3RvcnkuXG4gICAqICEgRG8gbm90IHVzZSB0byBjbGVhciBzY2VuZSB1c2VyIGFjdGlvbiAhXG4gICAqL1xuICBwcml2YXRlIHJlc2V0U2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKG9wdHM/OiB7IHJlc2V0TG9hZGluZ1N0YXRlOiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgICAgICAgaXNMb2FkaW5nOiBvcHRzPy5yZXNldExvYWRpbmdTdGF0ZSA/IGZhbHNlIDogc3RhdGUuaXNMb2FkaW5nLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGluaXRpYWxpemVTY2VuZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAoXCJsYXVuY2hRdWV1ZVwiIGluIHdpbmRvdyAmJiBcIkxhdW5jaFBhcmFtc1wiIGluIHdpbmRvdykge1xuICAgICAgKHdpbmRvdyBhcyBhbnkpLmxhdW5jaFF1ZXVlLnNldENvbnN1bWVyKFxuICAgICAgICBhc3luYyAobGF1bmNoUGFyYW1zOiB7IGZpbGVzOiBhbnlbXSB9KSA9PiB7XG4gICAgICAgICAgaWYgKCFsYXVuY2hQYXJhbXMuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbGVIYW5kbGUgPSBsYXVuY2hQYXJhbXMuZmlsZXNbMF07XG4gICAgICAgICAgY29uc3QgYmxvYjogQmxvYiA9IGF3YWl0IGZpbGVIYW5kbGUuZ2V0RmlsZSgpO1xuICAgICAgICAgIHRoaXMubG9hZEZpbGVUb0NhbnZhcyhcbiAgICAgICAgICAgIG5ldyBGaWxlKFtibG9iXSwgYmxvYi5uYW1lIHx8IFwiXCIsIHsgdHlwZTogYmxvYi50eXBlIH0pLFxuICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgIH1cbiAgICBsZXQgaW5pdGlhbERhdGEgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBpbml0aWFsRGF0YSA9IChhd2FpdCB0aGlzLnByb3BzLmluaXRpYWxEYXRhKSB8fCBudWxsO1xuICAgICAgaWYgKGluaXRpYWxEYXRhPy5saWJyYXJ5SXRlbXMpIHtcbiAgICAgICAgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBpbml0aWFsRGF0YS5saWJyYXJ5SXRlbXMsXG4gICAgICAgICAgICBtZXJnZTogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgaW5pdGlhbERhdGEgPSB7XG4gICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgZXJyb3JNZXNzYWdlOlxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSB8fFxuICAgICAgICAgICAgXCJFbmNvdW50ZXJlZCBhbiBlcnJvciBkdXJpbmcgaW1wb3J0aW5nIG9yIHJlc3RvcmluZyBzY2VuZSBkYXRhXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBzY2VuZSA9IHJlc3RvcmUoaW5pdGlhbERhdGEsIG51bGwsIG51bGwpO1xuICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAvLyB3ZSdyZSBmYWxsaW5nIGJhY2sgdG8gY3VycmVudCAocHJlLWluaXQpIHN0YXRlIHdoZW4gZGVjaWRpbmdcbiAgICAgIC8vIHdoZXRoZXIgdG8gb3BlbiB0aGUgbGlicmFyeSwgdG8gaGFuZGxlIGEgY2FzZSB3aGVyZSB3ZVxuICAgICAgLy8gdXBkYXRlIHRoZSBzdGF0ZSBvdXRzaWRlIG9mIGluaXRpYWxEYXRhIChlLmcuIHdoZW4gbG9hZGluZyB0aGUgYXBwXG4gICAgICAvLyB3aXRoIGEgbGlicmFyeSBpbnN0YWxsIGxpbmssIHdoaWNoIHNob3VsZCBhdXRvLW9wZW4gdGhlIGxpYnJhcnkpXG4gICAgICBpc0xpYnJhcnlPcGVuOlxuICAgICAgICBpbml0aWFsRGF0YT8uYXBwU3RhdGU/LmlzTGlicmFyeU9wZW4gfHwgdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuLFxuICAgICAgYWN0aXZlVG9vbDpcbiAgICAgICAgc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCJcbiAgICAgICAgICA/IHsgLi4uc2NlbmUuYXBwU3RhdGUuYWN0aXZlVG9vbCwgdHlwZTogXCJzZWxlY3Rpb25cIiB9XG4gICAgICAgICAgOiBzY2VuZS5hcHBTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgIHRvYXN0OiB0aGlzLnN0YXRlLnRvYXN0LFxuICAgIH07XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxUb0NvbnRlbnQpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICAgIHNjZW5lLmVsZW1lbnRzLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaGVpZ2h0LFxuICAgICAgICAgICAgb2Zmc2V0VG9wOiB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICAgIG9mZnNldExlZnQ6IHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgIC4uLnNjZW5lLFxuICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVmcmVzaERldmljZVN0YXRlID0gKGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQpID0+IHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzaWRlYmFyQnJlYWtwb2ludCA9XG4gICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPSBudWxsXG4gICAgICAgID8gdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSDtcbiAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwge1xuICAgICAgaXNTbVNjcmVlbjogd2lkdGggPCBNUV9TTV9NQVhfV0lEVEgsXG4gICAgICBpc01vYmlsZTpcbiAgICAgICAgd2lkdGggPCBNUV9NQVhfV0lEVEhfUE9SVFJBSVQgfHxcbiAgICAgICAgKGhlaWdodCA8IE1RX01BWF9IRUlHSFRfTEFORFNDQVBFICYmIHdpZHRoIDwgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSksXG4gICAgICBjYW5EZXZpY2VGaXRTaWRlYmFyOiB3aWR0aCA+IHNpZGViYXJCcmVha3BvaW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICB0aGlzLnVubW91bnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlLmNvbnRhaW5lciA9XG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcblxuICAgIGlmIChcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVCB8fFxuICAgICAgcHJvY2Vzcy5lbnYuUkVBQ1RfQVBQX1ZFUkNFTF9FTlYgPT09IFwicHJldmlld1wiXG4gICAgKSB7XG4gICAgICBjb25zdCBzZXRTdGF0ZSA9IHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0U3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBzZXRTdGF0ZT4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKC4uLmFyZ3MpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFwcDoge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcyxcbiAgICAgICAgfSxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5oaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5hZGRDYWxsYmFjayh0aGlzLm9uU2NlbmVVcGRhdGVkKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgLy8gYm91bmRpbmcgcmVjdHMgZG9uJ3Qgd29yayBpbiB0ZXN0cyBzbyB1cGRhdGluZ1xuICAgICAgLy8gdGhlIHN0YXRlIG9uIGluaXQgd291bGQgcmVzdWx0IGluIG1ha2luZyB0aGUgdGVzdCBlbnZpcm8gcnVuXG4gICAgICAvLyBpbiBtb2JpbGUgYnJlYWtwb2ludCAoMCB3aWR0aC9oZWlnaHQpLCBtYWtpbmcgZXZlcnl0aGluZyBmYWlsXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCJcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdyAmJiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICBUSFJPVFRMRV9ORVhUX1JFTkRFUiA9IGZhbHNlO1xuICAgICAgICAvLyByZWNvbXB1dGUgZGV2aWNlIGRpbWVuc2lvbnMgc3RhdGVcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISk7XG4gICAgICAgIC8vIHJlZnJlc2ggb2Zmc2V0c1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy51cGRhdGVET01SZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/Lm9ic2VydmUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH0gZWxzZSBpZiAod2luZG93Lm1hdGNoTWVkaWEpIHtcbiAgICAgIGNvbnN0IG1kU2NyZWVuUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX1BPUlRSQUlUfXB4KSwgKG1heC1oZWlnaHQ6ICR7TVFfTUFYX0hFSUdIVF9MQU5EU0NBUEV9cHgpIGFuZCAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9MQU5EU0NBUEV9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBzbVNjcmVlblF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX1NNX01BWF9XSURUSH1weClgLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNhbkRldmljZUZpdFNpZGViYXJNZWRpYVF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWluLXdpZHRoOiAke1xuICAgICAgICAgIC8vIE5PVEUgdGhpcyB3b24ndCB1cGRhdGUgaWYgYSBkaWZmZXJlbnQgYnJlYWtwb2ludCBpcyBzdXBwbGllZFxuICAgICAgICAgIC8vIGFmdGVyIG1vdW50XG4gICAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnQgIT0gbnVsbFxuICAgICAgICAgICAgPyB0aGlzLnByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludFxuICAgICAgICAgICAgOiBNUV9SSUdIVF9TSURFQkFSX01JTl9XSURUSFxuICAgICAgICB9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gdXBkYXRlT2JqZWN0KHRoaXMuZGV2aWNlLCB7XG4gICAgICAgICAgaXNTbVNjcmVlbjogc21TY3JlZW5RdWVyeS5tYXRjaGVzLFxuICAgICAgICAgIGlzTW9iaWxlOiBtZFNjcmVlblF1ZXJ5Lm1hdGNoZXMsXG4gICAgICAgICAgY2FuRGV2aWNlRml0U2lkZWJhcjogY2FuRGV2aWNlRml0U2lkZWJhck1lZGlhUXVlcnkubWF0Y2hlcyxcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgbWRTY3JlZW5RdWVyeS5hZGRMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXIgPSAoKSA9PlxuICAgICAgICBtZFNjcmVlblF1ZXJ5LnJlbW92ZUxpc3RlbmVyKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG5cbiAgICBpZiAoc2VhcmNoUGFyYW1zLmhhcyhcIndlYi1zaGFyZS10YXJnZXRcIikpIHtcbiAgICAgIC8vIE9idGFpbiBhIGZpbGUgdGhhdCB3YXMgc2hhcmVkIHZpYSB0aGUgV2ViIFNoYXJlIFRhcmdldCBBUEkuXG4gICAgICB0aGlzLnJlc3RvcmVGaWxlRnJvbVNoYXJlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCh0aGlzLmluaXRpYWxpemVTY2VuZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIHRoaXMuZmlsZXMgPSB7fTtcbiAgICB0aGlzLmltYWdlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy51bm1vdW50ZWQgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNjZW5lLmRlc3Ryb3koKTtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblJlc2l6ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgdGhpcy5zY2VuZVxuICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5XSEVFTCxcbiAgICAgIHRoaXMub25XaGVlbCxcbiAgICApO1xuICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRSQUdfT1ZFUixcbiAgICAgIHRoaXMuZGlzYWJsZUV2ZW50LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkRST1AsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG5cbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG5cbiAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyPy4oKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTsgLy8gIzM1NTNcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULldIRUVMLFxuICAgICAgdGhpcy5vbldoZWVsLFxuICAgICAgeyBwYXNzaXZlOiBmYWxzZSB9LFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5KSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgfVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgKTtcbiAgICAvLyByZXJlbmRlciB0ZXh0IGVsZW1lbnRzIG9uIGZvbnQgbG9hZCB0byBmaXggIzYzNyAmJiAjMTU1M1xuICAgIGRvY3VtZW50LmZvbnRzPy5hZGRFdmVudExpc3RlbmVyPy4oXCJsb2FkaW5nZG9uZVwiLCB0aGlzLm9uRm9udExvYWRlZCk7XG4gICAgLy8gU2FmYXJpLW9ubHkgZGVza3RvcCBwaW5jaCB6b29tXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgaWYgKHRoaXMucHJvcHMuZGV0ZWN0U2Nyb2xsKSB7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gZ2V0TmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIoXG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICk7XG4gICAgICB0aGlzLm5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICAgICk7XG4gICAgfVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlJFU0laRSwgdGhpcy5vblJlc2l6ZSwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlVOTE9BRCwgdGhpcy5vblVubG9hZCwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRoaXMub25CbHVyLCBmYWxzZSk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUkFHX09WRVIsXG4gICAgICB0aGlzLmRpc2FibGVFdmVudCxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5EUk9QLFxuICAgICAgdGhpcy5kaXNhYmxlRXZlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogQXBwUHJvcHMsIHByZXZTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCAmJlxuICAgICAgcHJldlByb3BzLlVJT3B0aW9ucy5kb2NrZWRTaWRlYmFyQnJlYWtwb2ludCAhPT1cbiAgICAgICAgdGhpcy5wcm9wcy5VSU9wdGlvbnMuZG9ja2VkU2lkZWJhckJyZWFrcG9pbnRcbiAgICApIHtcbiAgICAgIHRoaXMucmVmcmVzaERldmljZVN0YXRlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWCAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxYIHx8XG4gICAgICBwcmV2U3RhdGUuc2Nyb2xsWSAhPT0gdGhpcy5zdGF0ZS5zY3JvbGxZXG4gICAgKSB7XG4gICAgICB0aGlzLnByb3BzPy5vblNjcm9sbENoYW5nZT8uKHRoaXMuc3RhdGUuc2Nyb2xsWCwgdGhpcy5zdGF0ZS5zY3JvbGxZKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBPYmplY3Qua2V5cyh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcykubGVuZ3RoICYmXG4gICAgICBpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKVxuICAgICkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiICYmXG4gICAgICBwcmV2U3RhdGUudGhlbWUgIT09IHRoaXMuc3RhdGUudGhlbWVcbiAgICApIHtcbiAgICAgIHNldEVyYXNlckN1cnNvcih0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS50aGVtZSk7XG4gICAgfVxuICAgIC8vIEhpZGUgaHlwZXJsaW5rIHBvcHVwIGlmIHNob3duIHdoZW4gZWxlbWVudCB0eXBlIGlzIG5vdCBzZWxlY3Rpb25cbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXBcbiAgICApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlIH0pO1xuICAgIH1cbiAgICBpZiAocHJldlByb3BzLmxhbmdDb2RlICE9PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxhbmd1YWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlld01vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMudmlld01vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2U3RhdGUudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHplbk1vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy50aGVtZSAhPT0gdGhpcy5wcm9wcy50aGVtZSAmJiB0aGlzLnByb3BzLnRoZW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdGhlbWU6IHRoaXMucHJvcHMudGhlbWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZ3JpZFNpemU6IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLm5hbWUgJiYgcHJldlByb3BzLm5hbWUgIT09IHRoaXMucHJvcHMubmFtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG5hbWU6IHRoaXMucHJvcHMubmFtZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jbGFzc0xpc3QudG9nZ2xlKFxuICAgICAgXCJ0aGVtZS0tZGFya1wiLFxuICAgICAgdGhpcy5zdGF0ZS50aGVtZSA9PT0gXCJkYXJrXCIsXG4gICAgKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF1cbiAgICApIHtcbiAgICAgIC8vIGRlZmVyIHNvIHRoYXQgdGhlIGNvbW1pdFRvSGlzdG9yeSBmbGFnIGlzbid0IHJlc2V0IHZpYSBjdXJyZW50IHVwZGF0ZVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuZWxlbWVudElkXVxuICAgICkge1xuICAgICAgLy8gVG8gbWFrZSBzdXJlIGBzZWxlY3RlZExpbmVhckVsZW1lbnRgIGlzIGluIHN5bmMgd2l0aCBgc2VsZWN0ZWRFbGVtZW50SWRzYCwgaG93ZXZlciB0aGlzIHNob3VsZG4ndCBiZSBuZWVkZWQgb25jZVxuICAgICAgLy8gd2UgaGF2ZSBhIHNpbmdsZSBBUEkgdG8gdXBkYXRlIGBzZWxlY3RlZEVsZW1lbnRJZHNgXG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBudWxsIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSBwcmV2U3RhdGU7XG4gICAgaWYgKFxuICAgICAgcHJldlN0YXRlLmFjdGl2ZVRvb2wgIT09IHRoaXMuc3RhdGUuYWN0aXZlVG9vbCAmJlxuICAgICAgbXVsdGlFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgIGlzQmluZGluZ0VsZW1lbnQobXVsdGlFbGVtZW50LCBmYWxzZSlcbiAgICApIHtcbiAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXJTY2VuZSgpO1xuICAgIHRoaXMuaGlzdG9yeS5yZWNvcmQodGhpcy5zdGF0ZSwgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSk7XG5cbiAgICAvLyBEbyBub3Qgbm90aWZ5IGNvbnN1bWVycyBpZiB3ZSdyZSBzdGlsbCBsb2FkaW5nIHRoZSBzY2VuZS4gQW1vbmcgb3RoZXJcbiAgICAvLyBwb3RlbnRpYWwgaXNzdWVzLCB0aGlzIGZpeGVzIGEgY2FzZSB3aGVyZSB0aGUgdGFiIGlzbid0IGZvY3VzZWQgZHVyaW5nXG4gICAgLy8gaW5pdCwgd2hpY2ggd291bGQgdHJpZ2dlciBvbkNoYW5nZSB3aXRoIGVtcHR5IGVsZW1lbnRzLCB3aGljaCB3b3VsZCB0aGVuXG4gICAgLy8gb3ZlcnJpZGUgd2hhdGV2ZXIgaXMgaW4gbG9jYWxTdG9yYWdlIGN1cnJlbnRseS5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnByb3BzLm9uQ2hhbmdlPy4oXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuZmlsZXMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyU2NlbmUgPSAoKSA9PiB7XG4gICAgY29uc3QgY3Vyc29yQnV0dG9uOiB7XG4gICAgICBbaWQ6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICB9ID0ge307XG4gICAgY29uc3QgcG9pbnRlclZpZXdwb3J0Q29vcmRzOiBSZW5kZXJDb25maWdbXCJyZW1vdGVQb2ludGVyVmlld3BvcnRDb29yZHNcIl0gPVxuICAgICAge307XG4gICAgY29uc3QgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzOiBSZW5kZXJDb25maWdbXCJyZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNcIl0gPVxuICAgICAge307XG4gICAgY29uc3QgcG9pbnRlclVzZXJuYW1lczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgY29uc3QgcG9pbnRlclVzZXJTdGF0ZXM6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIHRoaXMuc3RhdGUuY29sbGFib3JhdG9ycy5mb3JFYWNoKCh1c2VyLCBzb2NrZXRJZCkgPT4ge1xuICAgICAgaWYgKHVzZXIuc2VsZWN0ZWRFbGVtZW50SWRzKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgT2JqZWN0LmtleXModXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgaWYgKCEoaWQgaW4gcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzKSkge1xuICAgICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzW2lkXSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdLnB1c2goc29ja2V0SWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXIucG9pbnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodXNlci51c2VybmFtZSkge1xuICAgICAgICBwb2ludGVyVXNlcm5hbWVzW3NvY2tldElkXSA9IHVzZXIudXNlcm5hbWU7XG4gICAgICB9XG4gICAgICBpZiAodXNlci51c2VyU3RhdGUpIHtcbiAgICAgICAgcG9pbnRlclVzZXJTdGF0ZXNbc29ja2V0SWRdID0gdXNlci51c2VyU3RhdGU7XG4gICAgICB9XG4gICAgICBwb2ludGVyVmlld3BvcnRDb29yZHNbc29ja2V0SWRdID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICB7XG4gICAgICAgICAgc2NlbmVYOiB1c2VyLnBvaW50ZXIueCxcbiAgICAgICAgICBzY2VuZVk6IHVzZXIucG9pbnRlci55LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGN1cnNvckJ1dHRvbltzb2NrZXRJZF0gPSB1c2VyLmJ1dHRvbjtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gdGhpcy5zY2VuZVxuICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAuZmlsdGVyKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChpc0ltYWdlRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIC8vIG5vdCBwbGFjZWQgb24gY2FudmFzIHlldCAoYnV0IGluIGVsZW1lbnRzIGFycmF5KVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQgPT09IGVsZW1lbnQuaWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZG9uJ3QgcmVuZGVyIHRleHQgZWxlbWVudCB0aGF0J3MgYmVpbmcgY3VycmVudGx5IGVkaXRlZCAoaXQnc1xuICAgICAgICAvLyByZW5kZXJlZCBvbiByZW1vdGUgb25seSlcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQudHlwZSAhPT0gXCJ0ZXh0XCIgfHxcbiAgICAgICAgICBlbGVtZW50LmlkICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LmlkXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgIHJlbmRlclNjZW5lKFxuICAgICAge1xuICAgICAgICBlbGVtZW50czogcmVuZGVyaW5nRWxlbWVudHMsXG4gICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICBzY2FsZTogd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgIHJjOiB0aGlzLnJjISxcbiAgICAgICAgY2FudmFzOiB0aGlzLmNhbnZhcyEsXG4gICAgICAgIHJlbmRlckNvbmZpZzoge1xuICAgICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCxcbiAgICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFksXG4gICAgICAgICAgdmlld0JhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgIHpvb206IHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICByZW1vdGVQb2ludGVyVmlld3BvcnRDb29yZHM6IHBvaW50ZXJWaWV3cG9ydENvb3JkcyxcbiAgICAgICAgICByZW1vdGVQb2ludGVyQnV0dG9uOiBjdXJzb3JCdXR0b24sXG4gICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIHJlbW90ZVBvaW50ZXJVc2VybmFtZXM6IHBvaW50ZXJVc2VybmFtZXMsXG4gICAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHBvaW50ZXJVc2VyU3RhdGVzLFxuICAgICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdGhpcy5zdGF0ZS5zaG91bGRDYWNoZUlnbm9yZVpvb20sXG4gICAgICAgICAgdGhlbWU6IHRoaXMuc3RhdGUudGhlbWUsXG4gICAgICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgICAgIGlzRXhwb3J0aW5nOiBmYWxzZSxcbiAgICAgICAgICByZW5kZXJTY3JvbGxiYXJzOiAhdGhpcy5kZXZpY2UuaXNNb2JpbGUsXG4gICAgICAgIH0sXG4gICAgICAgIGNhbGxiYWNrOiAoeyBhdExlYXN0T25lVmlzaWJsZUVsZW1lbnQsIHNjcm9sbEJhcnMgfSkgPT4ge1xuICAgICAgICAgIGlmIChzY3JvbGxCYXJzKSB7XG4gICAgICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyA9IHNjcm9sbEJhcnM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHNjcm9sbGVkT3V0c2lkZSA9XG4gICAgICAgICAgICAvLyBoaWRlIHdoZW4gZWRpdGluZyB0ZXh0XG4gICAgICAgICAgICBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICAgICAgOiAhYXRMZWFzdE9uZVZpc2libGVFbGVtZW50ICYmIHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCA+IDA7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2Nyb2xsZWRPdXRzaWRlICE9PSBzY3JvbGxlZE91dHNpZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzY3JvbGxlZE91dHNpZGUgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5zY2hlZHVsZUltYWdlUmVmcmVzaCgpO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIFRIUk9UVExFX05FWFRfUkVOREVSICYmIHdpbmRvdy5FWENBTElEUkFXX1RIUk9UVExFX1JFTkRFUiA9PT0gdHJ1ZSxcbiAgICApO1xuXG4gICAgaWYgKCFUSFJPVFRMRV9ORVhUX1JFTkRFUikge1xuICAgICAgVEhST1RUTEVfTkVYVF9SRU5ERVIgPSB0cnVlO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uU2Nyb2xsID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGNvbnN0IHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSB0aGlzLmdldENhbnZhc09mZnNldHMoKTtcbiAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgaWYgKHN0YXRlLm9mZnNldExlZnQgPT09IG9mZnNldExlZnQgJiYgc3RhdGUub2Zmc2V0VG9wID09PSBvZmZzZXRUb3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfTtcbiAgICB9KTtcbiAgfSwgU0NST0xMX1RJTUVPVVQpO1xuXG4gIC8vIENvcHkvcGFzdGVcblxuICBwcml2YXRlIG9uQ3V0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1dEFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25Db3B5ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICBwcml2YXRlIGN1dEFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25DdXQsIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb3B5QWxsID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkNvcHksIFwia2V5Ym9hcmRcIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVzZXRUYXBUd2ljZSgpIHtcbiAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBvblRhcFN0YXJ0ID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgLy8gZml4IGZvciBBcHBsZSBQZW5jaWwgU2NyaWJibGVcbiAgICAvLyBPbiBBbmRyb2lkLCBwcmV2ZW50aW5nIHRoZSBldmVudCB3b3VsZCBkaXNhYmxlIGNvbnRleHRNZW51IG9uIHRhcC1ob2xkXG4gICAgaWYgKCFpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFkaWRUYXBUd2ljZSkge1xuICAgICAgZGlkVGFwVHdpY2UgPSB0cnVlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgICAgdGFwcGVkVHdpY2VUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KFxuICAgICAgICBBcHAucmVzZXRUYXBUd2ljZSxcbiAgICAgICAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpbnNlcnQgdGV4dCBvbmx5IGlmIHdlIHRhcHBlZCB0d2ljZSB3aXRoIGEgc2luZ2xlIGZpbmdlclxuICAgIC8vIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxIHdpbGwgYWxzbyBwcmV2ZW50IGluc2VydGluZyB0ZXh0IHdoZW4gdXNlcidzIHpvb21pbmdcbiAgICBpZiAoZGlkVGFwVHdpY2UgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGNvbnN0IFt0b3VjaF0gPSBldmVudC50b3VjaGVzO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5oYW5kbGVDYW52YXNEb3VibGVDbGljayh7XG4gICAgICAgIGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG4gICAgICAgIGNsaWVudFk6IHRvdWNoLmNsaWVudFksXG4gICAgICB9KTtcbiAgICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgfVxuICAgIGlmIChpc0FuZHJvaWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uVGFwRW5kID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XG4gICAgdGhpcy5yZXNldENvbnRleHRNZW51VGltZXIoKTtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5wb2ludGVycy5jbGVhcigpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHBhc3RlRnJvbUNsaXBib2FyZCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4ge1xuICAgICAgLy8gIzY4NlxuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9XG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyh0YXJnZXQpO1xuICAgICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBlbGVtZW50VW5kZXJDdXJzb3IgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGN1cnNvclgsIGN1cnNvclkpO1xuICAgICAgaWYgKFxuICAgICAgICAvLyBpZiBubyBDbGlwYm9hcmRFdmVudCBzdXBwbGllZCwgYXNzdW1lIHdlJ3JlIHBhc3RpbmcgdmlhIGNvbnRleHRNZW51XG4gICAgICAgIC8vIHRodXMgdGhlc2UgY2hlY2tzIGRvbid0IG1ha2Ugc2Vuc2VcbiAgICAgICAgZXZlbnQgJiZcbiAgICAgICAgKCEoZWxlbWVudFVuZGVyQ3Vyc29yIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHx8XG4gICAgICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG11c3QgYmUgY2FsbGVkIGluIHRoZSBzYW1lIGZyYW1lICh0aHVzIGJlZm9yZSBhbnkgYXdhaXRzKSBhcyB0aGUgcGFzdGVcbiAgICAgIC8vIGV2ZW50IGVsc2Ugc29tZSBicm93c2VycyAoRkYuLi4pIHdpbGwgY2xlYXIgdGhlIGNsaXBib2FyZERhdGFcbiAgICAgIC8vIChzb21ldGhpbmcgc29tZXRoaW5nIHNlY3VyaXR5KVxuICAgICAgbGV0IGZpbGUgPSBldmVudD8uY2xpcGJvYXJkRGF0YT8uZmlsZXNbMF07XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwYXJzZUNsaXBib2FyZChldmVudCk7XG5cbiAgICAgIGlmICghZmlsZSAmJiBkYXRhLnRleHQpIHtcbiAgICAgICAgY29uc3Qgc3RyaW5nID0gZGF0YS50ZXh0LnRyaW0oKTtcbiAgICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKFwiPHN2Z1wiKSAmJiBzdHJpbmcuZW5kc1dpdGgoXCI8L3N2Zz5cIikpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgU1ZHIHZhbGlkYXRpb24vbm9ybWFsaXphdGlvbiB3aGljaCB3aWxsIGJlIGRvbmUgZHVyaW5nIGltYWdlXG4gICAgICAgICAgLy8gaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICBmaWxlID0gU1ZHU3RyaW5nVG9GaWxlKHN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcHJlZmVyIHNwcmVhZHNoZWV0IGRhdGEgb3ZlciBpbWFnZSBmaWxlIChNUyBPZmZpY2UvTGlicmUgT2ZmaWNlKVxuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpICYmICFkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wcm9wcy5vblBhc3RlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3BzLm9uUGFzdGUoZGF0YSwgZXZlbnQpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRhdGEuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGRhdGEuZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhc3RlRGlhbG9nOiB7XG4gICAgICAgICAgICBkYXRhOiBkYXRhLnNwcmVhZHNoZWV0LFxuICAgICAgICAgICAgc2hvd246IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRhdGEuZWxlbWVudHMsXG4gICAgICAgICAgZmlsZXM6IGRhdGEuZmlsZXMgfHwgbnVsbCxcbiAgICAgICAgICBwb3NpdGlvbjogXCJjdXJzb3JcIixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEudGV4dCkge1xuICAgICAgICB0aGlzLmFkZFRleHRGcm9tUGFzdGUoZGF0YS50ZXh0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSk7XG4gICAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkgPSAob3B0czoge1xuICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyB8IG51bGw7XG4gICAgcG9zaXRpb246IHsgY2xpZW50WDogbnVtYmVyOyBjbGllbnRZOiBudW1iZXIgfSB8IFwiY3Vyc29yXCIgfCBcImNlbnRlclwiO1xuICB9KSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSByZXN0b3JlRWxlbWVudHMob3B0cy5lbGVtZW50cywgbnVsbCk7XG4gICAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcblxuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWCA9IGRpc3RhbmNlKG1pblgsIG1heFgpIC8gMjtcbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclkgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSAvIDI7XG5cbiAgICBjb25zdCBjbGllbnRYID1cbiAgICAgIHR5cGVvZiBvcHRzLnBvc2l0aW9uID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gb3B0cy5wb3NpdGlvbi5jbGllbnRYXG4gICAgICAgIDogb3B0cy5wb3NpdGlvbiA9PT0gXCJjdXJzb3JcIlxuICAgICAgICA/IGN1cnNvclhcbiAgICAgICAgOiB0aGlzLnN0YXRlLndpZHRoIC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0TGVmdDtcbiAgICBjb25zdCBjbGllbnRZID1cbiAgICAgIHR5cGVvZiBvcHRzLnBvc2l0aW9uID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gb3B0cy5wb3NpdGlvbi5jbGllbnRZXG4gICAgICAgIDogb3B0cy5wb3NpdGlvbiA9PT0gXCJjdXJzb3JcIlxuICAgICAgICA/IGN1cnNvcllcbiAgICAgICAgOiB0aGlzLnN0YXRlLmhlaWdodCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldFRvcDtcblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYLCBjbGllbnRZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBkeCA9IHggLSBlbGVtZW50c0NlbnRlclg7XG4gICAgY29uc3QgZHkgPSB5IC0gZWxlbWVudHNDZW50ZXJZO1xuICAgIGNvbnN0IGdyb3VwSWRNYXAgPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChkeCwgZHksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3Qgb2xkSWRUb0R1cGxpY2F0ZWRJZCA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBuZXdFbGVtZW50cyA9IGVsZW1lbnRzLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgbmV3RWxlbWVudCA9IGR1cGxpY2F0ZUVsZW1lbnQoXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgIGdyb3VwSWRNYXAsXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHtcbiAgICAgICAgICB4OiBlbGVtZW50LnggKyBncmlkWCAtIG1pblgsXG4gICAgICAgICAgeTogZWxlbWVudC55ICsgZ3JpZFkgLSBtaW5ZLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQuc2V0KGVsZW1lbnQuaWQsIG5ld0VsZW1lbnQuaWQpO1xuICAgICAgcmV0dXJuIG5ld0VsZW1lbnQ7XG4gICAgfSk7XG4gICAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbihuZXdFbGVtZW50cywgZWxlbWVudHMsIG9sZElkVG9EdXBsaWNhdGVkSWQpO1xuICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAuLi5uZXdFbGVtZW50cyxcbiAgICBdO1xuICAgIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbihuZXh0RWxlbWVudHMsIGVsZW1lbnRzLCBvbGRJZFRvRHVwbGljYXRlZElkKTtcblxuICAgIGlmIChvcHRzLmZpbGVzKSB7XG4gICAgICB0aGlzLmZpbGVzID0geyAuLi50aGlzLmZpbGVzLCAuLi5vcHRzLmZpbGVzIH07XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMobmV4dEVsZW1lbnRzKTtcbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG5cbiAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgICAgaXNMaWJyYXJ5T3BlbjpcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuaXNMaWJyYXJ5T3BlbiAmJiB0aGlzLmRldmljZS5jYW5EZXZpY2VGaXRTaWRlYmFyXG4gICAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5pc0xpYnJhcnlNZW51RG9ja2VkXG4gICAgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdFbGVtZW50cy5yZWR1Y2UoXG4gICAgICAgICAgICAoYWNjOiBSZWNvcmQ8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXSwgdHJ1ZT4sIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICBhY2NbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge30sXG4gICAgICAgICAgKSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICksXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGlmIChvcHRzLmZpbGVzKSB7XG4gICAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICAgIHRoaXMuc2V0QWN0aXZlVG9vbCh7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBhZGRUZXh0RnJvbVBhc3RlKHRleHQ6IGFueSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHRleHQsXG4gICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB0ZXh0QWxpZ246IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2VsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICB9XG5cbiAgLy8gQ29sbGFib3JhdGlvblxuXG4gIHNldEFwcFN0YXRlID0gKG9iajogYW55KSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZShvYmopO1xuICB9O1xuXG4gIHJlbW92ZVBvaW50ZXIgPSAoZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MRWxlbWVudD4gfCBQb2ludGVyRXZlbnQpID0+IHtcbiAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICB0aGlzLnJlc2V0Q29udGV4dE1lbnVUaW1lcigpO1xuICAgIH1cblxuICAgIGdlc3R1cmUucG9pbnRlcnMuZGVsZXRlKGV2ZW50LnBvaW50ZXJJZCk7XG4gIH07XG5cbiAgdG9nZ2xlTG9jayA9IChzb3VyY2U6IFwia2V5Ym9hcmRcIiB8IFwidWlcIiA9IFwidWlcIikgPT4ge1xuICAgIGlmICghdGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgXCJ0b29sYmFyXCIsXG4gICAgICAgIFwidG9nZ2xlTG9ja1wiLFxuICAgICAgICBgJHtzb3VyY2V9ICgke3RoaXMuZGV2aWNlLmlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwifSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhY3RpdmVUb29sOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICAgICAgLi4udXBkYXRlQWN0aXZlVG9vbChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwcmV2U3RhdGUuYWN0aXZlVG9vbC5sb2NrZWRcbiAgICAgICAgICAgICAgPyB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfVxuICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5hY3RpdmVUb29sLFxuICAgICAgICAgICksXG4gICAgICAgICAgbG9ja2VkOiAhcHJldlN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICB0b2dnbGVQZW5Nb2RlID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGVuTW9kZTogIXByZXZTdGF0ZS5wZW5Nb2RlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICBzY3JvbGxUb0NvbnRlbnQgPSAoXG4gICAgdGFyZ2V0OlxuICAgICAgfCBFeGNhbGlkcmF3RWxlbWVudFxuICAgICAgfCByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgIEFycmF5LmlzQXJyYXkodGFyZ2V0KSA/IHRhcmdldCA6IFt0YXJnZXRdLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICksXG4gICAgfSk7XG4gIH07XG5cbiAgc2V0VG9hc3QgPSAoXG4gICAgdG9hc3Q6IHtcbiAgICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICAgIGNsb3NhYmxlPzogYm9vbGVhbjtcbiAgICAgIGR1cmF0aW9uPzogbnVtYmVyO1xuICAgIH0gfCBudWxsLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgdG9hc3QgfSk7XG4gIH07XG5cbiAgcmVzdG9yZUZpbGVGcm9tU2hhcmUgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUgPSBhd2FpdCBjYWNoZXMub3BlbihcIndlYi1zaGFyZS10YXJnZXRcIik7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5tYXRjaChcInNoYXJlZC1maWxlXCIpO1xuICAgICAgaWYgKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCByZXNwb25zZS5ibG9iKCk7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBuZXcgRmlsZShbYmxvYl0sIGJsb2IubmFtZSB8fCBcIlwiLCB7IHR5cGU6IGJsb2IudHlwZSB9KTtcbiAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIG51bGwpO1xuICAgICAgICBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLmRlbGV0ZShcInNoYXJlZC1maWxlXCIpO1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgQVBQX05BTUUsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIGFkZHMgc3VwcGxpZWQgZmlsZXMgdG8gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIGFwcFN0YXRlICovXG4gIHB1YmxpYyBhZGRGaWxlczogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUElbXCJhZGRGaWxlc1wiXSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZmlsZXMpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVzTWFwID0gZmlsZXMucmVkdWNlKChhY2MsIGZpbGVEYXRhKSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZmlsZURhdGEuaWQsIGZpbGVEYXRhKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXA8RmlsZUlkLCBCaW5hcnlGaWxlRGF0YT4oKSk7XG5cbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLk9iamVjdC5mcm9tRW50cmllcyhmaWxlc01hcCkgfTtcblxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgZmlsZXNNYXAuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZGVsZXRlKGVsZW1lbnQuZmlsZUlkKTtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcblxuICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICB9LFxuICApO1xuXG4gIHB1YmxpYyB1cGRhdGVTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICA8SyBleHRlbmRzIGtleW9mIEFwcFN0YXRlPihzY2VuZURhdGE6IHtcbiAgICAgIGVsZW1lbnRzPzogU2NlbmVEYXRhW1wiZWxlbWVudHNcIl07XG4gICAgICBhcHBTdGF0ZT86IFBpY2s8QXBwU3RhdGUsIEs+IHwgbnVsbDtcbiAgICAgIGNvbGxhYm9yYXRvcnM/OiBTY2VuZURhdGFbXCJjb2xsYWJvcmF0b3JzXCJdO1xuICAgICAgY29tbWl0VG9IaXN0b3J5PzogU2NlbmVEYXRhW1wiY29tbWl0VG9IaXN0b3J5XCJdO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChzY2VuZURhdGEuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5hcHBTdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHNjZW5lRGF0YS5hcHBTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoc2NlbmVEYXRhLmVsZW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb2xsYWJvcmF0b3JzOiBzY2VuZURhdGEuY29sbGFib3JhdG9ycyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25TY2VuZVVwZGF0ZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjdXJzb3JYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGN1cnNvclkgPSBldmVudC5jbGllbnRZO1xuICAgIH0sXG4gICk7XG5cbiAgLy8gSW5wdXQgaGFuZGxpbmdcblxuICBwcml2YXRlIG9uS2V5RG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IFJlYWN0LktleWJvYXJkRXZlbnQgfCBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgYGV2ZW50LmtleWAgd2hlbiBDYXBzTG9jayBpcyBwcmVzc2VkICMyMzcyXG5cbiAgICAgIGlmIChcbiAgICAgICAgXCJQcm94eVwiIGluIHdpbmRvdyAmJlxuICAgICAgICAoKCFldmVudC5zaGlmdEtleSAmJiAvXltBLVpdJC8udGVzdChldmVudC5rZXkpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleSAmJiAvXlthLXpdJC8udGVzdChldmVudC5rZXkpKSlcbiAgICAgICkge1xuICAgICAgICBldmVudCA9IG5ldyBQcm94eShldmVudCwge1xuICAgICAgICAgIGdldChldjogYW55LCBwcm9wKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV2W3Byb3BdO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgIC8vIGZpeCBmb3IgUHJveGllcyBoaWphY2tpbmcgYHRoaXNgXG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5iaW5kKGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwcm9wID09PSBcImtleVwiXG4gICAgICAgICAgICAgID8gLy8gQ2Fwc0xvY2sgaW52ZXJ0cyBjYXBpdGFsaXphdGlvbiBiYXNlZCBvbiBTaGlmdEtleSwgc28gaW52ZXJ0XG4gICAgICAgICAgICAgICAgLy8gaXQgYmFja1xuICAgICAgICAgICAgICAgIGV2ZW50LnNoaWZ0S2V5XG4gICAgICAgICAgICAgICAgPyBldi5rZXkudG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgICAgIDogZXYua2V5LnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gcHJldmVudCBicm93c2VyIHpvb20gaW4gaW5wdXQgZmllbGRzXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gQ09ERVMuTUlOVVMgfHwgZXZlbnQuY29kZSA9PT0gQ09ERVMuRVFVQUwpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBiYWlsIGlmXG4gICAgICBpZiAoXG4gICAgICAgIC8vIGluc2lkZSBhbiBpbnB1dFxuICAgICAgICAoaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJlxuICAgICAgICAgIC8vIHVubGVzcyBwcmVzc2luZyBlc2NhcGUgKGZpbmFsaXplIGFjdGlvbilcbiAgICAgICAgICBldmVudC5rZXkgIT09IEtFWVMuRVNDQVBFKSB8fFxuICAgICAgICAvLyBvciB1bmxlc3MgdXNpbmcgYXJyb3dzICh0byBtb3ZlIGJldHdlZW4gYnV0dG9ucylcbiAgICAgICAgKGlzQXJyb3dLZXkoZXZlbnQua2V5KSAmJiBpc0lucHV0TGlrZShldmVudC50YXJnZXQpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5RVUVTVElPTl9NQVJLKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNob3dIZWxwRGlhbG9nOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYWN0aW9uTWFuYWdlci5oYW5kbGVLZXlEb3duKGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiB0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IGZhbHNlIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQuY29kZSA9PT0gQ09ERVMuWkVSTykge1xuICAgICAgICBjb25zdCBuZXh0U3RhdGUgPSAhdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogbmV4dFN0YXRlIH0pO1xuICAgICAgICAvLyB0cmFjayBvbmx5IG9wZW5pbmdzXG4gICAgICAgIGlmIChuZXh0U3RhdGUpIHtcbiAgICAgICAgICB0cmFja0V2ZW50KFxuICAgICAgICAgICAgXCJsaWJyYXJ5XCIsXG4gICAgICAgICAgICBcInRvZ2dsZUxpYnJhcnkgKG9wZW4pXCIsXG4gICAgICAgICAgICBga2V5Ym9hcmQgKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAgICh0aGlzLnN0YXRlLmdyaWRTaXplICYmXG4gICAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgPyBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmdyaWRTaXplKSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgID8gRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICA6IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IG9mZnNldFggPSAwO1xuICAgICAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19MRUZUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19SSUdIVCkge1xuICAgICAgICAgIG9mZnNldFggPSBzdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19VUCkge1xuICAgICAgICAgIG9mZnNldFkgPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfRE9XTikge1xuICAgICAgICAgIG9mZnNldFkgPSBzdGVwO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgICB4OiBlbGVtZW50LnggKyBvZmZzZXRYLFxuICAgICAgICAgICAgeTogZWxlbWVudC55ICsgb2Zmc2V0WSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCwge1xuICAgICAgICAgICAgc2ltdWx0YW5lb3VzbHlVcGRhdGVkOiBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVOVEVSKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBpZiAoaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0uaWRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnQgPSBzZWxlY3RlZEVsZW1lbnRzWzBdO1xuXG4gICAgICAgICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICAgICAgICBzY2VuZVg6IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMixcbiAgICAgICAgICAgICAgc2NlbmVZOiBzZWxlY3RlZEVsZW1lbnQueSArIHNlbGVjdGVkRWxlbWVudC5oZWlnaHQgLyAyLFxuICAgICAgICAgICAgICBzaG91bGRCaW5kOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgIWV2ZW50LmN0cmxLZXkgJiZcbiAgICAgICAgIWV2ZW50LmFsdEtleSAmJlxuICAgICAgICAhZXZlbnQubWV0YUtleSAmJlxuICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCA9PT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gZmluZFNoYXBlQnlLZXkoZXZlbnQua2V5KTtcbiAgICAgICAgaWYgKHNoYXBlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBzaGFwZSkge1xuICAgICAgICAgICAgdHJhY2tFdmVudChcbiAgICAgICAgICAgICAgXCJ0b29sYmFyXCIsXG4gICAgICAgICAgICAgIHNoYXBlLFxuICAgICAgICAgICAgICBga2V5Ym9hcmQgKCR7dGhpcy5kZXZpY2UuaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCJ9KWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldEFjdGl2ZVRvb2woeyB0eXBlOiBzaGFwZSB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuUSkge1xuICAgICAgICAgIHRoaXMudG9nZ2xlTG9jayhcImtleWJvYXJkXCIpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFICYmIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBpc0hvbGRpbmdTcGFjZSA9IHRydWU7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIChldmVudC5rZXkgPT09IEtFWVMuRyB8fCBldmVudC5rZXkgPT09IEtFWVMuUykgJiZcbiAgICAgICAgIWV2ZW50LmFsdEtleSAmJlxuICAgICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF1cbiAgICAgICkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkcgJiZcbiAgICAgICAgICAoaGFzQmFja2dyb3VuZCh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSkgfHxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT4gaGFzQmFja2dyb3VuZChlbGVtZW50LnR5cGUpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJiYWNrZ3JvdW5kQ29sb3JQaWNrZXJcIiB9KTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlMpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcInN0cm9rZUNvbG9yUGlja2VyXCIgfSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25XaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICAvLyBwcmV2ZW50IGJyb3dzZXIgcGluY2ggem9vbSBvbiBET00gZWxlbWVudHNcbiAgICBpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkgJiYgZXZlbnQuY3RybEtleSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgb25LZXlVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5HUkFCKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpXG4gICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBzZXRBY3RpdmVUb29sID0gKFxuICAgIHRvb2w6XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIFNIQVBFU1tudW1iZXJdW1widmFsdWVcIl0gfCBcImVyYXNlclwiIH1cbiAgICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfSxcbiAgKSA9PiB7XG4gICAgY29uc3QgbmV4dEFjdGl2ZVRvb2wgPSB1cGRhdGVBY3RpdmVUb29sKHRoaXMuc3RhdGUsIHRvb2wpO1xuICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICB9XG4gICAgaWYgKGlzVG9vbEljb24oZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG4gICAgaWYgKCFpc0xpbmVhckVsZW1lbnRUeXBlKG5leHRBY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgICBpZiAobmV4dEFjdGl2ZVRvb2wudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICB0aGlzLm9uSW1hZ2VBY3Rpb24oKTtcbiAgICB9XG4gICAgaWYgKG5leHRBY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBhY3RpdmVUb29sOiBuZXh0QWN0aXZlVG9vbCB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRDdXJzb3IgPSAoY3Vyc29yOiBzdHJpbmcpID0+IHtcbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGN1cnNvcik7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEN1cnNvciA9ICgpID0+IHtcbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gIH07XG4gIC8qKlxuICAgKiByZXR1cm5zIHdoZXRoZXIgdXNlciBpcyBtYWtpbmcgYSBnZXN0dXJlIHdpdGggPj0gMiBmaW5nZXJzIChwb2ludHMpXG4gICAqIG9uIG8gdG91Y2ggc2NyZWVuIChub3Qgb24gYSB0cmFja3BhZCkuIEN1cnJlbnRseSBvbmx5IHJlbGF0ZXMgdG8gRGFyd2luXG4gICAqIChpT1MvaVBhZE9TLE1hY09TKSwgYnV0IG1heSB3b3JrIG9uIG90aGVyIGRldmljZXMgaW4gdGhlIGZ1dHVyZSBpZlxuICAgKiBHZXN0dXJlRXZlbnQgaXMgc3RhbmRhcmRpemVkLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUgPSAoKSA9PiB7XG4gICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBkZXNlbGVjdCB3aGVuIHVzaW5nIHRyYWNrcGFkLCBhbmQgbXVsdGktcG9pbnQgZ2VzdHVyZXNcbiAgICAvLyBvbmx5IHdvcmsgb24gdG91Y2ggc2NyZWVucywgc28gY2hlY2tpbmcgZm9yID49IHBvaW50ZXJzIG1lYW5zIHdlJ3JlIG9uIGFcbiAgICAvLyB0b3VjaHNjcmVlblxuICAgIHJldHVybiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPj0gMjtcbiAgfTtcblxuICAvLyBmaXJlcyBvbmx5IG9uIFNhZmFyaVxuICBwcml2YXRlIG9uR2VzdHVyZVN0YXJ0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIHdlIG9ubHkgd2FudCB0byBkZXNlbGVjdCBvbiB0b3VjaCBzY3JlZW5zIGJlY2F1c2UgdXNlciBtYXkgaGF2ZSBzZWxlY3RlZFxuICAgIC8vIGVsZW1lbnRzIGJ5IG1pc3Rha2Ugd2hpbGUgem9vbWluZ1xuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVDaGFuZ2UgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gb25HZXN0dXJlQ2hhbmdlIG9ubHkgaGFzIHpvb20gZmFjdG9yIGJ1dCBub3QgdGhlIGNlbnRlci5cbiAgICAvLyBJZiB3ZSdyZSBvbiBpUGFkIG9yIGlQaG9uZSwgdGhlbiB3ZSByZWNvZ25pemUgbXVsdGktdG91Y2ggYW5kIHdpbGxcbiAgICAvLyB6b29tIGluIGF0IHRoZSByaWdodCBsb2NhdGlvbiBpbiB0aGUgdG91Y2htb3ZlIGhhbmRsZXJcbiAgICAvLyAoaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUpLlxuICAgIC8vXG4gICAgLy8gT24gTWFjYm9vayB0cmFja3BhZCwgd2UgZG9uJ3QgaGF2ZSB0aG9zZSBldmVudHMgc28gd2lsbCB6b29tIGluIGF0IHRoZVxuICAgIC8vIGN1cnJlbnQgbG9jYXRpb24gaW5zdGVhZC5cbiAgICAvL1xuICAgIC8vIEFzIHN1Y2gsIGJhaWwgZnJvbSB0aGlzIGhhbmRsZXIgb24gdG91Y2ggZGV2aWNlcy5cbiAgICBpZiAodGhpcy5pc1RvdWNoU2NyZWVuTXVsdGlUb3VjaEdlc3R1cmUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChpbml0aWFsU2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXRTdGF0ZUZvclpvb20oXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmlld3BvcnRYOiBjdXJzb3JYLFxuICAgICAgICAgICAgdmlld3BvcnRZOiBjdXJzb3JZLFxuICAgICAgICAgICAgbmV4dFpvb206IGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIGV2ZW50LnNjYWxlKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlLFxuICAgICAgICApLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZmlyZXMgb25seSBvbiBTYWZhcmlcbiAgcHJpdmF0ZSBvbkdlc3R1cmVFbmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIHJlc2VsZWN0IGVsZW1lbnRzIG9ubHkgb24gdG91Y2ggc2NyZWVucyAoc2VlIG9uR2VzdHVyZVN0YXJ0KVxuICAgIGlmICh0aGlzLmlzVG91Y2hTY3JlZW5NdWx0aVRvdWNoR2VzdHVyZSgpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSBudWxsO1xuICB9KTtcblxuICBwcml2YXRlIGhhbmRsZVRleHRXeXNpd3lnKFxuICAgIGVsZW1lbnQ6IEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgICB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudCA9IGZhbHNlLFxuICAgIH06IHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApIHtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50ID0gKFxuICAgICAgdGV4dDogc3RyaW5nLFxuICAgICAgb3JpZ2luYWxUZXh0OiBzdHJpbmcsXG4gICAgICBpc0RlbGV0ZWQ6IGJvb2xlYW4sXG4gICAgKSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChfZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChfZWxlbWVudC5pZCA9PT0gZWxlbWVudC5pZCAmJiBpc1RleHRFbGVtZW50KF9lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVRleHRFbGVtZW50KF9lbGVtZW50LCB7XG4gICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgIGlzRGVsZXRlZCxcbiAgICAgICAgICAgICAgb3JpZ2luYWxUZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICBdKTtcbiAgICB9O1xuXG4gICAgdGV4dFd5c2l3eWcoe1xuICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICBjYW52YXM6IHRoaXMuY2FudmFzLFxuICAgICAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4LCB5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgICAgICBzY2VuZVk6IHksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHZpZXdwb3J0WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB2aWV3cG9ydFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgXTtcbiAgICAgIH0sXG4gICAgICBvbkNoYW5nZTogd2l0aEJhdGNoZWRVcGRhdGVzKCh0ZXh0KSA9PiB7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgdGV4dCwgZmFsc2UpO1xuICAgICAgICBpZiAoaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgb25TdWJtaXQ6IHdpdGhCYXRjaGVkVXBkYXRlcygoeyB0ZXh0LCB2aWFLZXlib2FyZCwgb3JpZ2luYWxUZXh0IH0pID0+IHtcbiAgICAgICAgY29uc3QgaXNEZWxldGVkID0gIXRleHQudHJpbSgpO1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIG9yaWdpbmFsVGV4dCwgaXNEZWxldGVkKTtcbiAgICAgICAgLy8gc2VsZWN0IHRoZSBjcmVhdGVkIHRleHQgZWxlbWVudCBvbmx5IGlmIHN1Ym1pdHRpbmcgdmlhIGtleWJvYXJkXG4gICAgICAgIC8vICh3aGVuIHN1Ym1pdHRpbmcgdmlhIGNsaWNrIGl0IHNob3VsZCBhY3QgYXMgc2lnbmFsIHRvIGRlc2VsZWN0KVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCAmJiB2aWFLZXlib2FyZCkge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRJZFRvU2VsZWN0ID0gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgPyBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA6IGVsZW1lbnQuaWQ7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgIFtlbGVtZW50SWRUb1NlbGVjdF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWxldGVkKSB7XG4gICAgICAgICAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIFtcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgfHwgaXNFeGlzdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLmxvY2tlZCkge1xuICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICAgIH0pLFxuICAgICAgZWxlbWVudCxcbiAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgYXBwOiB0aGlzLFxuICAgIH0pO1xuICAgIC8vIGRlc2VsZWN0IGFsbCBvdGhlciBlbGVtZW50cyB3aGVuIGluc2VydGluZyB0ZXh0XG4gICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG5cbiAgICAvLyBkbyBhbiBpbml0aWFsIHVwZGF0ZSB0byByZS1pbml0aWFsaXplIGVsZW1lbnQgcG9zaXRpb24gc2luY2Ugd2Ugd2VyZVxuICAgIC8vIG1vZGlmeWluZyBlbGVtZW50J3MgeC95IGZvciBzYWtlIG9mIGVkaXRvciAoY2FzZTogc3luY2luZyB0byByZW1vdGUpXG4gICAgdXBkYXRlRWxlbWVudChlbGVtZW50LnRleHQsIGVsZW1lbnQub3JpZ2luYWxUZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIGRlc2VsZWN0RWxlbWVudHMoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiAhZWxlbWVudC5pc0RlbGV0ZWQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBvcHRzPzoge1xuICAgICAgLyoqIGlmIHRydWUsIHJldHVybnMgdGhlIGZpcnN0IHNlbGVjdGVkIGVsZW1lbnQgKHdpdGggaGlnaGVzdCB6LWluZGV4KVxuICAgICAgICBvZiBhbGwgaGl0IGVsZW1lbnRzICovXG4gICAgICBwcmVmZXJTZWxlY3RlZD86IGJvb2xlYW47XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudD86IGJvb2xlYW47XG4gICAgICBpbmNsdWRlTG9ja2VkRWxlbWVudHM/OiBib29sZWFuO1xuICAgIH0sXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgb3B0cz8uaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQsXG4gICAgICBvcHRzPy5pbmNsdWRlTG9ja2VkRWxlbWVudHMsXG4gICAgKTtcbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKG9wdHM/LnByZWZlclNlbGVjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMTsgaW5kZXggPiAtMTsgaW5kZXgtLSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1thbGxIaXRFbGVtZW50c1tpbmRleF0uaWRdKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbaW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4ID1cbiAgICAgICAgYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMV07XG4gICAgICAvLyBJZiB3ZSdyZSBoaXR0aW5nIGVsZW1lbnQgd2l0aCBoaWdoZXN0IHotaW5kZXggb25seSBvbiBpdHMgYm91bmRpbmcgYm94XG4gICAgICAvLyB3aGlsZSBhbHNvIGhpdHRpbmcgb3RoZXIgZWxlbWVudCBmaWd1cmUsIHRoZSBsYXR0ZXIgc2hvdWxkIGJlIGNvbnNpZGVyZWQuXG4gICAgICByZXR1cm4gaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXgsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICApXG4gICAgICAgID8gYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMl1cbiAgICAgICAgOiBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXg7XG4gICAgfVxuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1swXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgaW5jbHVkZUxvY2tlZEVsZW1lbnRzOiBib29sZWFuID0gZmFsc2UsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10ge1xuICAgIGNvbnN0IGVsZW1lbnRzID1cbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50ICYmIGluY2x1ZGVMb2NrZWRFbGVtZW50c1xuICAgICAgICA/IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgOiB0aGlzLnNjZW5lXG4gICAgICAgICAgICAuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKClcbiAgICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAgIChlbGVtZW50KSA9PlxuICAgICAgICAgICAgICAgIChpbmNsdWRlTG9ja2VkRWxlbWVudHMgfHwgIWVsZW1lbnQubG9ja2VkKSAmJlxuICAgICAgICAgICAgICAgIChpbmNsdWRlQm91bmRUZXh0RWxlbWVudCB8fFxuICAgICAgICAgICAgICAgICAgIShpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmIGVsZW1lbnQuY29udGFpbmVySWQpKSxcbiAgICAgICAgICAgICk7XG5cbiAgICByZXR1cm4gZ2V0RWxlbWVudHNBdFBvc2l0aW9uKGVsZW1lbnRzLCAoZWxlbWVudCkgPT5cbiAgICAgIGhpdFRlc3QoZWxlbWVudCwgdGhpcy5zdGF0ZSwgeCwgeSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUZXh0RWRpdGluZyA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgICBzaG91bGRCaW5kLFxuICAgIGluc2VydEF0UGFyZW50Q2VudGVyID0gdHJ1ZSxcbiAgfToge1xuICAgIC8qKiBYIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgLyoqIFkgcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVk6IG51bWJlcjtcbiAgICBzaG91bGRCaW5kOiBib29sZWFuO1xuICAgIC8qKiB3aGV0aGVyIHRvIGF0dGVtcHQgdG8gaW5zZXJ0IGF0IGVsZW1lbnQgY2VudGVyIGlmIGFwcGxpY2FibGUgKi9cbiAgICBpbnNlcnRBdFBhcmVudENlbnRlcj86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICBsZXQgcGFyZW50Q2VudGVyUG9zaXRpb24gPVxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgJiZcbiAgICAgIHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICk7XG5cbiAgICBsZXQgZXhpc3RpbmdUZXh0RWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3VGV4dEVsZW1lbnQ+IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGNvbnRhaW5lcjogRXhjYWxpZHJhd1RleHRDb250YWluZXIgfCBudWxsID0gbnVsbDtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG4gICAgICB9IGVsc2UgaWYgKGlzVGV4dEJpbmRhYmxlQ29udGFpbmVyKHNlbGVjdGVkRWxlbWVudHNbMF0sIGZhbHNlKSkge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gZ2V0Qm91bmRUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLmdldFRleHRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLmdldFRleHRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG4gICAgfVxuXG4gICAgLy8gYmluZCB0byBjb250YWluZXIgd2hlbiBzaG91bGRCaW5kIGlzIHRydWUgb3JcbiAgICAvLyBjbGlja2VkIG9uIGNlbnRlciBvZiBjb250YWluZXJcbiAgICBpZiAoXG4gICAgICAhY29udGFpbmVyICYmXG4gICAgICAhZXhpc3RpbmdUZXh0RWxlbWVudCAmJlxuICAgICAgKHNob3VsZEJpbmQgfHwgcGFyZW50Q2VudGVyUG9zaXRpb24pXG4gICAgKSB7XG4gICAgICBjb250YWluZXIgPSBnZXRUZXh0QmluZGFibGVDb250YWluZXJBdFBvc2l0aW9uKFxuICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChlbGUpID0+XG4gICAgICAgICAgICAgIGlzVGV4dEJpbmRhYmxlQ29udGFpbmVyKGVsZSwgZmFsc2UpICYmICFnZXRCb3VuZFRleHRFbGVtZW50KGVsZSksXG4gICAgICAgICAgKSxcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCAmJiBjb250YWluZXIpIHtcbiAgICAgIGNvbnN0IGZvbnRTdHJpbmcgPSB7XG4gICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1pbldpZHRoID0gZ2V0QXBwcm94TWluTGluZVdpZHRoKGdldEZvbnRTdHJpbmcoZm9udFN0cmluZykpO1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gZ2V0QXBwcm94TWluTGluZUhlaWdodChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KGNvbnRhaW5lci5oZWlnaHQsIG1pbkhlaWdodCk7XG4gICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KGNvbnRhaW5lci53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBuZXdIZWlnaHQsIHdpZHRoOiBuZXdXaWR0aCB9KTtcbiAgICAgIHNjZW5lWCA9IGNvbnRhaW5lci54ICsgbmV3V2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gY29udGFpbmVyLnkgKyBuZXdIZWlnaHQgLyAyO1xuICAgICAgaWYgKHBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIHBhcmVudENlbnRlclBvc2l0aW9uID0gdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgPyBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA6IG5ld1RleHRFbGVtZW50KHtcbiAgICAgICAgICB4OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWFxuICAgICAgICAgICAgOiBzY2VuZVgsXG4gICAgICAgICAgeTogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlcllcbiAgICAgICAgICAgIDogc2NlbmVZLFxuICAgICAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgICB0ZXh0OiBcIlwiLFxuICAgICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICAgICAgdGV4dEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBcImNlbnRlclwiXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICAgICAgdmVydGljYWxBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gVkVSVElDQUxfQUxJR04uTUlERExFXG4gICAgICAgICAgICA6IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgICAgICAgY29udGFpbmVySWQ6IGNvbnRhaW5lcj8uaWQgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgIGdyb3VwSWRzOiBjb250YWluZXI/Lmdyb3VwSWRzID8/IFtdLFxuICAgICAgICAgIGxvY2tlZDogZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdFbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gICAgaWYgKCFleGlzdGluZ1RleHRFbGVtZW50KSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcblxuICAgICAgLy8gY2FzZTogY3JlYXRpbmcgbmV3IHRleHQgbm90IGNlbnRlcmVkIHRvIHBhcmVudCBlbGVtZW50IOKGkiBvZmZzZXQgWVxuICAgICAgLy8gc28gdGhhdCB0aGUgdGV4dCBpcyBjZW50ZXJlZCB0byBjdXJzb3IgcG9zaXRpb25cbiAgICAgIGlmICghcGFyZW50Q2VudGVyUG9zaXRpb24pIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgICAgeTogZWxlbWVudC55IC0gZWxlbWVudC5iYXNlbGluZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmhhbmRsZVRleHRXeXNpd3lnKGVsZW1lbnQsIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50OiAhIWV4aXN0aW5nVGV4dEVsZW1lbnQsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNEb3VibGVDbGljayA9IChcbiAgICBldmVudDogUmVhY3QuTW91c2VFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIGNhc2U6IGRvdWJsZS1jbGlja2luZyB3aXRoIGFycm93L2xpbmUgdG9vbCBzZWxlY3RlZCB3b3VsZCBib3RoIGNyZWF0ZVxuICAgIC8vIHRleHQgYW5kIGVudGVyIG11bHRpRWxlbWVudCBtb2RlXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHdlIHNob3VsZCBvbmx5IGJlIGFibGUgdG8gZG91YmxlIGNsaWNrIHdoZW4gbW9kZSBpcyBzZWxlY3Rpb25cbiAgICBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG5cbiAgICBsZXQgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgZXZlbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWRzID0gZ2V0U2VsZWN0ZWRHcm91cElkcyh0aGlzLnN0YXRlKTtcblxuICAgIGlmIChzZWxlY3RlZEdyb3VwSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkID1cbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50KGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cElkcyk7XG5cbiAgICAgIGlmIChzZWxlY3RlZEdyb3VwSWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IHNlbGVjdGVkR3JvdXBJZCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50IS5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgICAgY29uc3QgY2FuQmluZFRleHQgPSBoYXNCb3VuZFRleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudCk7XG4gICAgICAgIGlmIChjYW5CaW5kVGV4dCkge1xuICAgICAgICAgIHNjZW5lWCA9IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMjtcbiAgICAgICAgICBzY2VuZVkgPSBzZWxlY3RlZEVsZW1lbnQueSArIHNlbGVjdGVkRWxlbWVudC5oZWlnaHQgLyAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZ2V0RWxlbWVudExpbmtBdFBvc2l0aW9uID0gKFxuICAgIHNjZW5lUG9pbnRlcjogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBoaXRFbGVtZW50OiBOb25EZWxldGVkRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsLFxuICApOiBFeGNhbGlkcmF3RWxlbWVudCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgLy8gUmV2ZXJzaW5nIHNvIHdlIHRyYXZlcnNlIHRoZSBlbGVtZW50cyBpbiBkZWNyZWFzaW5nIG9yZGVyXG4gICAgLy8gb2Ygei1pbmRleFxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICBsZXQgaGl0RWxlbWVudEluZGV4ID0gSW5maW5pdHk7XG5cbiAgICByZXR1cm4gZWxlbWVudHMuZmluZCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChoaXRFbGVtZW50ICYmIGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQuaWQpIHtcbiAgICAgICAgaGl0RWxlbWVudEluZGV4ID0gaW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gKFxuICAgICAgICBlbGVtZW50LmxpbmsgJiZcbiAgICAgICAgaW5kZXggPD0gaGl0RWxlbWVudEluZGV4ICYmXG4gICAgICAgIGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXIueCwgc2NlbmVQb2ludGVyLnldLFxuICAgICAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVkaXJlY3RUb0xpbmsgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgaXNUb3VjaFNjcmVlbjogYm9vbGVhbixcbiAgKSA9PiB7XG4gICAgY29uc3QgZHJhZ2dlZERpc3RhbmNlID0gZGlzdGFuY2UyZChcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRYLFxuICAgICAgdGhpcy5sYXN0UG9pbnRlckRvd24hLmNsaWVudFksXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFgsXG4gICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5oaXRMaW5rRWxlbWVudCB8fFxuICAgICAgLy8gRm9yIHRvdWNoIHNjcmVlbiBhbGxvdyBkcmFnZ2luZyB0aHJlc2hvbGQgZWxzZSBzdHJpY3QgY2hlY2tcbiAgICAgIChpc1RvdWNoU2NyZWVuICYmIGRyYWdnZWREaXN0YW5jZSA+IERSQUdHSU5HX1RIUkVTSE9MRCkgfHxcbiAgICAgICghaXNUb3VjaFNjcmVlbiAmJiBkcmFnZ2VkRGlzdGFuY2UgIT09IDApXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhc3RQb2ludGVyRG93bkNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duISxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gPSBpc1BvaW50SGl0dGluZ0xpbmtJY29uKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICBbbGFzdFBvaW50ZXJEb3duQ29vcmRzLngsIGxhc3RQb2ludGVyRG93bkNvb3Jkcy55XSxcbiAgICAgIHRoaXMuZGV2aWNlLmlzTW9iaWxlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcENvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbiA9IGlzUG9pbnRIaXR0aW5nTGlua0ljb24oXG4gICAgICB0aGlzLmhpdExpbmtFbGVtZW50LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIFtsYXN0UG9pbnRlclVwQ29vcmRzLngsIGxhc3RQb2ludGVyVXBDb29yZHMueV0sXG4gICAgICB0aGlzLmRldmljZS5pc01vYmlsZSxcbiAgICApO1xuICAgIGlmIChsYXN0UG9pbnRlckRvd25IaXR0aW5nTGlua0ljb24gJiYgbGFzdFBvaW50ZXJVcEhpdHRpbmdMaW5rSWNvbikge1xuICAgICAgY29uc3QgdXJsID0gdGhpcy5oaXRMaW5rRWxlbWVudC5saW5rO1xuICAgICAgaWYgKHVybCkge1xuICAgICAgICBsZXQgY3VzdG9tRXZlbnQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTGlua09wZW4pIHtcbiAgICAgICAgICBjdXN0b21FdmVudCA9IHdyYXBFdmVudChFVkVOVC5FWENBTElEUkFXX0xJTkssIGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgICAgICB0aGlzLnByb3BzLm9uTGlua09wZW4odGhpcy5oaXRMaW5rRWxlbWVudCwgY3VzdG9tRXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY3VzdG9tRXZlbnQ/LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBpc0xvY2FsTGluayh1cmwpID8gXCJfc2VsZlwiIDogXCJfYmxhbmtcIjtcbiAgICAgICAgICBjb25zdCBuZXdXaW5kb3cgPSB3aW5kb3cub3Blbih1bmRlZmluZWQsIHRhcmdldCk7XG4gICAgICAgICAgLy8gaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmdpdGh1Yi5pby9yZWwtbm9vcGVuZXIvXG4gICAgICAgICAgaWYgKG5ld1dpbmRvdykge1xuICAgICAgICAgICAgbmV3V2luZG93Lm9wZW5lciA9IG51bGw7XG4gICAgICAgICAgICBuZXdXaW5kb3cubG9jYXRpb24gPSBub3JtYWxpemVMaW5rKHVybCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgdGhpcy5zdGF0ZS5jdXJzb3JCdXR0b24pO1xuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLmhhcyhldmVudC5wb2ludGVySWQpKSB7XG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMiAmJlxuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyICYmXG4gICAgICBpbml0aWFsU2NhbGUgJiZcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlXG4gICAgKSB7XG4gICAgICBjb25zdCBjZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBjb25zdCBkZWx0YVggPSBjZW50ZXIueCAtIGdlc3R1cmUubGFzdENlbnRlci54O1xuICAgICAgY29uc3QgZGVsdGFZID0gY2VudGVyLnkgLSBnZXN0dXJlLmxhc3RDZW50ZXIueTtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGNlbnRlcjtcblxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBnZXREaXN0YW5jZShBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpKTtcbiAgICAgIGNvbnN0IHNjYWxlRmFjdG9yID1cbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiZnJlZWRyYXdcIiAmJiB0aGlzLnN0YXRlLnBlbk1vZGVcbiAgICAgICAgICA/IDFcbiAgICAgICAgICA6IGRpc3RhbmNlIC8gZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2U7XG5cbiAgICAgIGNvbnN0IG5leHRab29tID0gc2NhbGVGYWN0b3JcbiAgICAgICAgPyBnZXROb3JtYWxpemVkWm9vbShpbml0aWFsU2NhbGUgKiBzY2FsZUZhY3RvcilcbiAgICAgICAgOiB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiB7XG4gICAgICAgIGNvbnN0IHpvb21TdGF0ZSA9IGdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGNlbnRlci54LFxuICAgICAgICAgICAgdmlld3BvcnRZOiBjZW50ZXIueSxcbiAgICAgICAgICAgIG5leHRab29tLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB6b29tOiB6b29tU3RhdGUuem9vbSxcbiAgICAgICAgICBzY3JvbGxYOiB6b29tU3RhdGUuc2Nyb2xsWCArIGRlbHRhWCAvIG5leHRab29tLFxuICAgICAgICAgIHNjcm9sbFk6IHpvb21TdGF0ZS5zY3JvbGxZICsgZGVsdGFZIC8gbmV4dFpvb20sXG4gICAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPVxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGlzSG9sZGluZ1NwYWNlIHx8IGlzUGFubmluZyB8fCBpc0RyYWdnaW5nU2Nyb2xsQmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMgPSBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICBldmVudC5jbGllbnRYIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICk7XG4gICAgY29uc3QgaXNPdmVyU2Nyb2xsQmFyID0gaXNQb2ludGVyT3ZlclNjcm9sbEJhcnMuaXNPdmVyRWl0aGVyO1xuICAgIGlmICghdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZVBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHsgeDogc2NlbmVQb2ludGVyWCwgeTogc2NlbmVQb2ludGVyWSB9ID0gc2NlbmVQb2ludGVyO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICkge1xuICAgICAgY29uc3QgZWRpdGluZ0xpbmVhckVsZW1lbnQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJNb3ZlKFxuICAgICAgICBldmVudCxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgLy8gU2luY2Ugd2UgYXJlIHJlYWRpbmcgZnJvbSBwcmV2aW91cyBzdGF0ZSB3aGljaCBpcyBub3QgcG9zc2libGUgd2l0aFxuICAgICAgICAvLyBhdXRvbWF0aWMgYmF0Y2hpbmcgaW4gUmVhY3QgMTggaGVuY2UgdXNpbmcgZmx1c2ggc3luYyB0byBzeW5jaHJvbm91c2x5XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGUuIENoZWNrIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC81NTA4IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdMaW5lYXJFbGVtZW50IH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudC5sYXN0VW5jb21taXR0ZWRQb2ludCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0JpbmRpbmdFbGVtZW50VHlwZSh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSkpIHtcbiAgICAgIC8vIEhvdmVyaW5nIHdpdGggYSBzZWxlY3RlZCB0b29sIG9yIGNyZWF0aW5nIG5ldyBsaW5lYXIgZWxlbWVudCB2aWEgY2xpY2tcbiAgICAgIC8vIGFuZCBwb2ludFxuICAgICAgY29uc3QgeyBkcmFnZ2luZ0VsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIGZhbHNlKSkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBbc2NlbmVQb2ludGVyXSxcbiAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3Ioc2NlbmVQb2ludGVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnkgfSA9IG11bHRpRWxlbWVudDtcblxuICAgICAgY29uc3QgeyBwb2ludHMsIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuICAgICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcblxuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUpO1xuXG4gICAgICBpZiAobGFzdFBvaW50ID09PSBsYXN0Q29tbWl0dGVkUG9pbnQpIHtcbiAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCB5ZXQgY3JlYXRlZCBhIHRlbXAgcG9pbnQgYW5kIHdlJ3JlIGJleW9uZCBjb21taXQtem9uZVxuICAgICAgICAvLyB0aHJlc2hvbGQsIGFkZCBhIHBvaW50XG4gICAgICAgIGlmIChcbiAgICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgICAgbGFzdFBvaW50WzBdLFxuICAgICAgICAgICAgbGFzdFBvaW50WzFdLFxuICAgICAgICAgICkgPj0gTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbc2NlbmVQb2ludGVyWCAtIHJ4LCBzY2VuZVBvaW50ZXJZIC0gcnldXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICAgIC8vIGluIHRoaXMgYnJhbmNoLCB3ZSdyZSBpbnNpZGUgdGhlIGNvbW1pdCB6b25lLCBhbmQgbm8gdW5jb21taXR0ZWRcbiAgICAgICAgICAvLyBwb2ludCBleGlzdHMuIFRodXMgZG8gbm90aGluZyAoZG9uJ3QgYWRkL3JlbW92ZSBwb2ludHMpLlxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwb2ludHMubGVuZ3RoID4gMiAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IHBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgW2xhc3RDb21taXR0ZWRYLCBsYXN0Q29tbWl0dGVkWV0gPVxuICAgICAgICAgIG11bHRpRWxlbWVudD8ubGFzdENvbW1pdHRlZFBvaW50ID8/IFswLCAwXTtcblxuICAgICAgICBsZXQgZHhGcm9tTGFzdENvbW1pdHRlZCA9IGdyaWRYIC0gcnggLSBsYXN0Q29tbWl0dGVkWDtcbiAgICAgICAgbGV0IGR5RnJvbUxhc3RDb21taXR0ZWQgPSBncmlkWSAtIHJ5IC0gbGFzdENvbW1pdHRlZFk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSkge1xuICAgICAgICAgICh7IHdpZHRoOiBkeEZyb21MYXN0Q29tbWl0dGVkLCBoZWlnaHQ6IGR5RnJvbUxhc3RDb21taXR0ZWQgfSA9XG4gICAgICAgICAgICBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUoXG4gICAgICAgICAgICAgIC8vIGFjdHVhbCBjb29yZGluYXRlIG9mIHRoZSBsYXN0IGNvbW1pdHRlZCBwb2ludFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWCArIHJ4LFxuICAgICAgICAgICAgICBsYXN0Q29tbWl0dGVkWSArIHJ5LFxuICAgICAgICAgICAgICAvLyBjdXJzb3ItZ3JpZCBjb29yZGluYXRlXG4gICAgICAgICAgICAgIGdyaWRYLFxuICAgICAgICAgICAgICBncmlkWSxcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzUGF0aEFMb29wKHBvaW50cywgdGhpcy5zdGF0ZS56b29tLnZhbHVlKSkge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXBkYXRlIGxhc3QgdW5jb21taXR0ZWQgcG9pbnRcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgIC4uLnBvaW50cy5zbGljZSgwLCAtMSksXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgIGxhc3RDb21taXR0ZWRYICsgZHhGcm9tTGFzdENvbW1pdHRlZCxcbiAgICAgICAgICAgICAgbGFzdENvbW1pdHRlZFkgKyBkeUZyb21MYXN0Q29tbWl0dGVkLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhc0Rlc2VsZWN0ZWRCdXR0b24gPSBCb29sZWFuKGV2ZW50LmJ1dHRvbnMpO1xuICAgIGlmIChcbiAgICAgIGhhc0Rlc2VsZWN0ZWRCdXR0b24gfHxcbiAgICAgICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJ0ZXh0XCIgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiZXJhc2VyXCIpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgIGlmIChcbiAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAhaXNPdmVyU2Nyb2xsQmFyICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudFxuICAgICkge1xuICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAmJlxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxICYmICFpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmICh0cmFuc2Zvcm1IYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgIGhpdEVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoaXNFcmFzZXJBY3RpdmUodGhpcy5zdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuaGl0TGlua0VsZW1lbnQuaWRdXG4gICAgKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgc2hvd0h5cGVybGlua1Rvb2x0aXAodGhpcy5oaXRMaW5rRWxlbWVudCwgdGhpcy5zdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVIeXBlcmxpbmtUb29saXAoKTtcbiAgICAgIGlmIChcbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBoaXRFbGVtZW50LmxpbmsgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0gJiZcbiAgICAgICAgIXRoaXMuY29udGV4dE1lbnVPcGVuICYmXG4gICAgICAgICF0aGlzLnN0YXRlLnNob3dIeXBlcmxpbmtQb3B1cFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IFwiaW5mb1wiIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGlzVGV4dEVsZW1lbnQoaGl0RWxlbWVudCkgPyBDVVJTT1JfVFlQRS5URVhUIDogQ1VSU09SX1RZUEUuQ1JPU1NIQUlSLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVIb3ZlclNlbGVjdGVkTGluZWFyRWxlbWVudChcbiAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAvLyBpZiB1c2luZyBjbWQvY3RybCwgd2UncmUgbm90IGRyYWdnaW5nXG4gICAgICAgICFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJlxuICAgICAgICAoaGl0RWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXIsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICkpICYmXG4gICAgICAgICFoaXRFbGVtZW50Py5sb2NrZWRcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVFcmFzZXIgPSAoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIHNjZW5lUG9pbnRlcjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LFxuICApID0+IHtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50SWRzID0gKGVsZW1lbnRzOiBFeGNhbGlkcmF3RWxlbWVudFtdKSA9PiB7XG4gICAgICBlbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChlbGVtZW50LmxvY2tlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlkc1RvVXBkYXRlLnB1c2goZWxlbWVudC5pZCk7XG4gICAgICAgIGlmIChldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdLmVyYXNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdLmVyYXNlID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGVtZW50LmlkXSA9IHtcbiAgICAgICAgICAgIGVyYXNlOiB0cnVlLFxuICAgICAgICAgICAgb3BhY2l0eTogZWxlbWVudC5vcGFjaXR5LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBjb25zdCBpZHNUb1VwZGF0ZTogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXG4gICAgY29uc3QgZGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSxcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBwb2ludCA9IHsgLi4ucG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzIH07XG4gICAgbGV0IHNhbXBsaW5nSW50ZXJ2YWwgPSAwO1xuICAgIHdoaWxlIChzYW1wbGluZ0ludGVydmFsIDw9IGRpc3RhbmNlKSB7XG4gICAgICBjb25zdCBoaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKHBvaW50LngsIHBvaW50LnkpO1xuICAgICAgdXBkYXRlRWxlbWVudElkcyhoaXRFbGVtZW50cyk7XG5cbiAgICAgIC8vIEV4aXQgc2luY2Ugd2UgcmVhY2hlZCBjdXJyZW50IHBvaW50XG4gICAgICBpZiAoc2FtcGxpbmdJbnRlcnZhbCA9PT0gZGlzdGFuY2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBuZXh0IHBvaW50IGluIHRoZSBsaW5lIGF0IGEgZGlzdGFuY2Ugb2Ygc2FtcGxpbmcgaW50ZXJ2YWxcbiAgICAgIHNhbXBsaW5nSW50ZXJ2YWwgPSBNYXRoLm1pbihzYW1wbGluZ0ludGVydmFsICsgdGhyZXNob2xkLCBkaXN0YW5jZSk7XG5cbiAgICAgIGNvbnN0IGRpc3RhbmNlUmF0aW8gPSBzYW1wbGluZ0ludGVydmFsIC8gZGlzdGFuY2U7XG4gICAgICBjb25zdCBuZXh0WCA9XG4gICAgICAgICgxIC0gZGlzdGFuY2VSYXRpbykgKiBwb2ludC54ICsgZGlzdGFuY2VSYXRpbyAqIHNjZW5lUG9pbnRlci54O1xuICAgICAgY29uc3QgbmV4dFkgPVxuICAgICAgICAoMSAtIGRpc3RhbmNlUmF0aW8pICogcG9pbnQueSArIGRpc3RhbmNlUmF0aW8gKiBzY2VuZVBvaW50ZXIueTtcbiAgICAgIHBvaW50LnggPSBuZXh0WDtcbiAgICAgIHBvaW50LnkgPSBuZXh0WTtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGUpID0+IHtcbiAgICAgIGNvbnN0IGlkID1cbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiYgaWRzVG9VcGRhdGUuaW5jbHVkZXMoZWxlLmNvbnRhaW5lcklkKVxuICAgICAgICAgID8gZWxlLmNvbnRhaW5lcklkXG4gICAgICAgICAgOiBlbGUuaWQ7XG4gICAgICBpZiAoaWRzVG9VcGRhdGUuaW5jbHVkZXMoaWQpKSB7XG4gICAgICAgIGlmIChldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2lkXSAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtpZF0uZXJhc2UgPT09IGZhbHNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgICAgIG9wYWNpdHk6IHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbaWRdLm9wYWNpdHksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZSwge1xuICAgICAgICAgICAgb3BhY2l0eTogRUxFTUVOVF9SRUFEWV9UT19FUkFTRV9PUEFDSVRZLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuXG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBzY2VuZVBvaW50ZXIueDtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHNjZW5lUG9pbnRlci55O1xuICB9O1xuICAvLyBzZXQgdG91Y2ggbW92aW5nIGZvciBtb2JpbGUgY29udGV4dCBtZW51XG4gIHByaXZhdGUgaGFuZGxlVG91Y2hNb3ZlID0gKGV2ZW50OiBSZWFjdC5Ub3VjaEV2ZW50PEhUTUxDYW52YXNFbGVtZW50PikgPT4ge1xuICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gIH07XG5cbiAgaGFuZGxlSG92ZXJTZWxlY3RlZExpbmVhckVsZW1lbnQoXG4gICAgbGluZWFyRWxlbWVudEVkaXRvcjogTGluZWFyRWxlbWVudEVkaXRvcixcbiAgICBzY2VuZVBvaW50ZXJYOiBudW1iZXIsXG4gICAgc2NlbmVQb2ludGVyWTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KFxuICAgICAgbGluZWFyRWxlbWVudEVkaXRvci5lbGVtZW50SWQsXG4gICAgKTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgIGxldCBob3ZlclBvaW50SW5kZXggPSAtMTtcbiAgICAgIGxldCBtaWRQb2ludEhvdmVyZWQgPSBmYWxzZTtcbiAgICAgIGlmIChcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goZWxlbWVudCwgdGhpcy5zdGF0ZSwgW1xuICAgICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgXSlcbiAgICAgICkge1xuICAgICAgICBob3ZlclBvaW50SW5kZXggPSBMaW5lYXJFbGVtZW50RWRpdG9yLmdldFBvaW50SW5kZXhVbmRlckN1cnNvcihcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgICk7XG4gICAgICAgIG1pZFBvaW50SG92ZXJlZCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaXNIaXR0aW5nTWlkUG9pbnQoXG4gICAgICAgICAgbGluZWFyRWxlbWVudEVkaXRvcixcbiAgICAgICAgICB7IHg6IHNjZW5lUG9pbnRlclgsIHk6IHNjZW5lUG9pbnRlclkgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChob3ZlclBvaW50SW5kZXggPj0gMCB8fCBtaWRQb2ludEhvdmVyZWQpIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHNob3VsZFNob3dCb3VuZGluZ0JveChbZWxlbWVudF0sIHRoaXMuc3RhdGUpICYmXG4gICAgICAgIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudChcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudC5ob3ZlclBvaW50SW5kZXggIT09IGhvdmVyUG9pbnRJbmRleFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBob3ZlclBvaW50SW5kZXgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQubWlkUG9pbnRIb3ZlcmVkICE9PSBtaWRQb2ludEhvdmVyZWRcbiAgICAgICkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgbWlkUG9pbnRIb3ZlcmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICAvLyByZW1vdmUgYW55IGFjdGl2ZSBzZWxlY3Rpb24gd2hlbiB3ZSBzdGFydCB0byBpbnRlcmFjdCB3aXRoIGNhbnZhc1xuICAgIC8vIChtYWlubHksIHdlIGNhcmUgYWJvdXQgcmVtb3Zpbmcgc2VsZWN0aW9uIG91dHNpZGUgdGhlIGNvbXBvbmVudCB3aGljaFxuICAgIC8vICB3b3VsZCBwcmV2ZW50IG91ciBjb3B5IGhhbmRsaW5nIG90aGVyd2lzZSlcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsZWN0aW9uPy5hbmNob3JOb2RlKSB7XG4gICAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgfVxuICAgIHRoaXMubWF5YmVPcGVuQ29udGV4dE1lbnVBZnRlclBvaW50ZXJEb3duT25Ub3VjaERldmljZXMoZXZlbnQpO1xuICAgIHRoaXMubWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKGV2ZW50KTtcblxuICAgIC8vZmlyZXMgb25seSBvbmNlLCBpZiBwZW4gaXMgZGV0ZWN0ZWQsIHBlbk1vZGUgaXMgZW5hYmxlZFxuICAgIC8vdGhlIHVzZXIgY2FuIGRpc2FibGUgdGhpcyBieSB0b2dnbGluZyB0aGUgcGVuTW9kZSBidXR0b25cbiAgICBpZiAoIXRoaXMuc3RhdGUucGVuRGV0ZWN0ZWQgJiYgZXZlbnQucG9pbnRlclR5cGUgPT09IFwicGVuXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHBlbk1vZGU6IHRydWUsXG4gICAgICAgICAgcGVuRGV0ZWN0ZWQ6IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAhdGhpcy5kZXZpY2UuaXNUb3VjaFNjcmVlbiAmJlxuICAgICAgW1wicGVuXCIsIFwidG91Y2hcIl0uaW5jbHVkZXMoZXZlbnQucG9pbnRlclR5cGUpXG4gICAgKSB7XG4gICAgICB0aGlzLmRldmljZSA9IHVwZGF0ZU9iamVjdCh0aGlzLmRldmljZSwgeyBpc1RvdWNoU2NyZWVuOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxhc3RQb2ludGVyRG93biA9IGV2ZW50O1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgbGFzdFBvaW50ZXJEb3duV2l0aDogZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICBjdXJzb3JCdXR0b246IFwiZG93blwiLFxuICAgIH0pO1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJkb3duXCIpO1xuXG4gICAgdGhpcy51cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBoYW5kbGUgbGVmdCBtb3VzZSBidXR0b24gb3IgdG91Y2hcbiAgICBpZiAoXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiZcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uVE9VQ0hcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkb24ndCBzZWxlY3Qgd2hpbGUgcGFubmluZ1xuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPiAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3RhdGUgZm9yIHRoZSBkdXJhdGlvbiBvZiBhIHBvaW50ZXIgaW50ZXJhY3Rpb24sIHdoaWNoIHN0YXJ0cyB3aXRoIGFcbiAgICAvLyBwb2ludGVyRG93biBldmVudCwgZW5kcyB3aXRoIGEgcG9pbnRlclVwIGV2ZW50IChvciBhbm90aGVyIHBvaW50ZXJEb3duKVxuICAgIGNvbnN0IHBvaW50ZXJEb3duU3RhdGUgPSB0aGlzLmluaXRpYWxQb2ludGVyRG93blN0YXRlKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZURyYWdnaW5nU2Nyb2xsQmFyKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNpbmNlIGNvbnRleHQgbWVudSBjbG9zZXMgb24gcG9pbnRlciBkb3duIHNvIHNldHRpbmcgdG8gZmFsc2VcbiAgICB0aGlzLmNvbnRleHRNZW51T3BlbiA9IGZhbHNlO1xuICAgIHRoaXMuY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uKCk7XG4gICAgdGhpcy51cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlU2VsZWN0aW9uT25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhbGxvd09uUG9pbnRlckRvd24gPVxuICAgICAgIXRoaXMuc3RhdGUucGVuTW9kZSB8fFxuICAgICAgZXZlbnQucG9pbnRlclR5cGUgIT09IFwidG91Y2hcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInRleHRcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgPT09IFwiaW1hZ2VcIjtcblxuICAgIGlmICghYWxsb3dPblBvaW50ZXJEb3duKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcInRleHRcIikge1xuICAgICAgdGhpcy5oYW5kbGVUZXh0T25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImFycm93XCIgfHxcbiAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImxpbmVcIlxuICAgICkge1xuICAgICAgdGhpcy5oYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgIC8vIHJlc2V0IGltYWdlIHByZXZpZXcgb24gcG9pbnRlcmRvd25cbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQ1JPU1NIQUlSKTtcblxuICAgICAgLy8gcmV0cmlldmUgdGhlIGxhdGVzdCBlbGVtZW50IGFzIHRoZSBzdGF0ZSBtYXkgYmUgc3RhbGVcbiAgICAgIGNvbnN0IHBlbmRpbmdJbWFnZUVsZW1lbnQgPVxuICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCAmJlxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnQodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50SWQpO1xuXG4gICAgICBpZiAoIXBlbmRpbmdJbWFnZUVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBwZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogcGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsLFxuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgICAgbXV0YXRlRWxlbWVudChwZW5kaW5nSW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgIHRoaXMuaGFuZGxlRnJlZURyYXdFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiZXJhc2VyXCIpIHtcbiAgICAgIHRoaXMuY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm9wcz8ub25Qb2ludGVyRG93bj8uKHRoaXMuc3RhdGUuYWN0aXZlVG9vbCwgcG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID1cbiAgICAgIHRoaXMub25Qb2ludGVyTW92ZUZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9XG4gICAgICB0aGlzLm9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uS2V5RG93biA9IHRoaXMub25LZXlEb3duRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcbiAgICBjb25zdCBvbktleVVwID0gdGhpcy5vbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIGlmICghdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCBvbktleURvd24pO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIG9uS2V5VXApO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUgPSBvblBvaW50ZXJNb3ZlO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vblVwID0gb25Qb2ludGVyVXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAgPSBvbktleVVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleURvd24gPSBvbktleURvd247XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlclVwID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICB0aGlzLmxhc3RQb2ludGVyVXAgPSBldmVudDtcbiAgICBpZiAodGhpcy5kZXZpY2UuaXNUb3VjaFNjcmVlbikge1xuICAgICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICB7IGNsaWVudFg6IGV2ZW50LmNsaWVudFgsIGNsaWVudFk6IGV2ZW50LmNsaWVudFkgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICAgKTtcbiAgICAgIHRoaXMuaGl0TGlua0VsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbihcbiAgICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5oaXRMaW5rRWxlbWVudCAmJlxuICAgICAgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW3RoaXMuaGl0TGlua0VsZW1lbnQuaWRdXG4gICAgKSB7XG4gICAgICB0aGlzLnJlZGlyZWN0VG9MaW5rKGV2ZW50LCB0aGlzLmRldmljZS5pc1RvdWNoU2NyZWVuKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlbW92ZVBvaW50ZXIoZXZlbnQpO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVPcGVuQ29udGV4dE1lbnVBZnRlclBvaW50ZXJEb3duT25Ub3VjaERldmljZXMgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGRlYWwgd2l0aCBvcGVuaW5nIGNvbnRleHQgbWVudSBvbiB0b3VjaCBkZXZpY2VzXG4gICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIpIHtcbiAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4gICAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgYWxyZWFkeSBhIHRvdWNoVGltZW91dCwgdGhpcyBtZWFucyB0aGF0IHRoZXJlJ3MgYW5vdGhlclxuICAgICAgICAvLyB0b3VjaCBkb3duIGFuZCB3ZSBhcmUgZG9pbmcgYW5vdGhlciB0b3VjaCwgc28gd2Ugc2hvdWxkbid0IG9wZW4gdGhlXG4gICAgICAgIC8vIGNvbnRleHQgbWVudS5cbiAgICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9wZW4gdGhlIGNvbnRleHQgbWVudSB3aXRoIHRoZSBmaXJzdCB0b3VjaCdzIGNsaWVudFggYW5kIGNsaWVudFlcbiAgICAgICAgLy8gaWYgdGhlIHRvdWNoIGlzIG5vdCBtb3ZpbmdcbiAgICAgICAgdG91Y2hUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgICAgICAgaWYgKCFpbnZhbGlkYXRlQ29udGV4dE1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRDb250ZXh0TWVudVRpbWVyID0gKCkgPT4ge1xuICAgIGNsZWFyVGltZW91dCh0b3VjaFRpbWVvdXQpO1xuICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQge1xuICAgIGlmIChsYXN0UG9pbnRlclVwICE9PSBudWxsKSB7XG4gICAgICAvLyBVbmZvcnR1bmF0ZWx5LCBzb21ldGltZXMgd2UgZG9uJ3QgZ2V0IGEgcG9pbnRlcnVwIGFmdGVyIGEgcG9pbnRlcmRvd24sXG4gICAgICAvLyB0aGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbnRleHR1YWwgbWVudSBvciBhbGVydCBpcyB0cmlnZ2VyZWQuIEluIG9yZGVyIHRvIGF2b2lkXG4gICAgICAvLyBiZWluZyBpbiBhIHdlaXJkIHN0YXRlLCB3ZSBjbGVhbiB1cCBvbiB0aGUgbmV4dCBwb2ludGVyZG93blxuICAgICAgbGFzdFBvaW50ZXJVcChldmVudCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBldmVudCBpcyBhIHBhbm5pbmdcbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmIChcbiAgICAgICEoXG4gICAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA8PSAxICYmXG4gICAgICAgIChldmVudC5idXR0b24gPT09IFBPSU5URVJfQlVUVE9OLldIRUVMIHx8XG4gICAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJiBpc0hvbGRpbmdTcGFjZSkgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZClcbiAgICAgICkgfHxcbiAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNQYW5uaW5nID0gdHJ1ZTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgbGV0IG5leHRQYXN0ZVByZXZlbnRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGlzTGludXggPSAvTGludXgvLnRlc3Qod2luZG93Lm5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICBsZXQgeyBjbGllbnRYOiBsYXN0WCwgY2xpZW50WTogbGFzdFkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGxhc3RYIC0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGxhc3RZIC0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGxhc3RYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGxhc3RZID0gZXZlbnQuY2xpZW50WTtcblxuICAgICAgLypcbiAgICAgICAqIFByZXZlbnQgcGFzdGUgZXZlbnQgaWYgd2UgbW92ZSB3aGlsZSBtaWRkbGUgY2xpY2tpbmcgb24gTGludXguXG4gICAgICAgKiBTZWUgaXNzdWUgIzEzODMuXG4gICAgICAgKi9cbiAgICAgIGlmIChcbiAgICAgICAgaXNMaW51eCAmJlxuICAgICAgICAhbmV4dFBhc3RlUHJldmVudGVkICYmXG4gICAgICAgIChNYXRoLmFicyhkZWx0YVgpID4gMSB8fCBNYXRoLmFicyhkZWx0YVkpID4gMSlcbiAgICAgICkge1xuICAgICAgICBuZXh0UGFzdGVQcmV2ZW50ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8qIFByZXZlbnQgdGhlIG5leHQgcGFzdGUgZXZlbnQgKi9cbiAgICAgICAgY29uc3QgcHJldmVudE5leHRQYXN0ZSA9IChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIFJlZW5hYmxlIG5leHQgcGFzdGUgaW4gY2FzZSBvZiBkaXNhYmxlZCBtaWRkbGUgY2xpY2sgcGFzdGUgZm9yXG4gICAgICAgICAqIGFueSByZWFzb246XG4gICAgICAgICAqIC0gcmlnaHQgY2xpY2sgcGFzdGVcbiAgICAgICAgICogLSBlbXB0eSBjbGlwYm9hcmRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGVuYWJsZU5leHRQYXN0ZSA9ICgpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGRlbHRhWCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZGVsdGFZIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgdGVhcmRvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgICAobGFzdFBvaW50ZXJVcCA9ICgpID0+IHtcbiAgICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICAgICAgb25Qb2ludGVyTW92ZS5mbHVzaCgpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlLCB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgIH0pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgIH0pO1xuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMikge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9IGdldERpc3RhbmNlKFxuICAgICAgICBBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxQb2ludGVyRG93blN0YXRlKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBQb2ludGVyRG93blN0YXRlIHtcbiAgICBjb25zdCBvcmlnaW4gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3JpZ2luLFxuICAgICAgd2l0aENtZE9yQ3RybDogZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0sXG4gICAgICBvcmlnaW5JbkdyaWQ6IHR1cGxlVG9Db29ycyhcbiAgICAgICAgZ2V0R3JpZFBvaW50KG9yaWdpbi54LCBvcmlnaW4ueSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSksXG4gICAgICApLFxuICAgICAgc2Nyb2xsYmFyczogaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICksXG4gICAgICAvLyB3ZSBuZWVkIHRvIGR1cGxpY2F0ZSBiZWNhdXNlIHdlJ2xsIGJlIHVwZGF0aW5nIHRoaXMgc3RhdGVcbiAgICAgIGxhc3RDb29yZHM6IHsgLi4ub3JpZ2luIH0sXG4gICAgICBvcmlnaW5hbEVsZW1lbnRzOiB0aGlzLnNjZW5lXG4gICAgICAgIC5nZXROb25EZWxldGVkRWxlbWVudHMoKVxuICAgICAgICAucmVkdWNlKChhY2MsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBhY2Muc2V0KGVsZW1lbnQuaWQsIGRlZXBDb3B5RWxlbWVudChlbGVtZW50KSk7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwgbmV3IE1hcCgpIGFzIFBvaW50ZXJEb3duU3RhdGVbXCJvcmlnaW5hbEVsZW1lbnRzXCJdKSxcbiAgICAgIHJlc2l6ZToge1xuICAgICAgICBoYW5kbGVUeXBlOiBmYWxzZSxcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIG9mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgIGFycm93RGlyZWN0aW9uOiBcIm9yaWdpblwiLFxuICAgICAgICBjZW50ZXI6IHsgeDogKG1heFggKyBtaW5YKSAvIDIsIHk6IChtYXhZICsgbWluWSkgLyAyIH0sXG4gICAgICB9LFxuICAgICAgaGl0OiB7XG4gICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGFsbEhpdEVsZW1lbnRzOiBbXSxcbiAgICAgICAgd2FzQWRkZWRUb1NlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGhhc0JlZW5EdXBsaWNhdGVkOiBmYWxzZSxcbiAgICAgICAgaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHM6XG4gICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgICBkcmFnOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGV2ZW50TGlzdGVuZXJzOiB7XG4gICAgICAgIG9uTW92ZTogbnVsbCxcbiAgICAgICAgb25VcDogbnVsbCxcbiAgICAgICAgb25LZXlVcDogbnVsbCxcbiAgICAgICAgb25LZXlEb3duOiBudWxsLFxuICAgICAgfSxcbiAgICAgIGJveFNlbGVjdGlvbjoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZWxlbWVudElkc1RvRXJhc2U6IHt9LFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgZHJhZ2dpbmcgYSBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoXG4gICAgICAhKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJFaXRoZXIgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gdHJ1ZTtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IGV2ZW50LmNsaWVudFg7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gZmFsc2U7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZSk7XG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIG9uUG9pbnRlck1vdmUuZmx1c2goKTtcbiAgICB9KTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24gPSAoKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIGV2ZW50IGhhcyBiZWVuIGNvbXBsZXRlbHkgaGFuZGxlZFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9XG4gICAgICAgICAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICBpZiAoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHJlc2l6aW5nRWxlbWVudDogZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLmVsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9XG4gICAgICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlOiBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nID0gdHJ1ZTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldFJlc2l6ZU9mZnNldFhZKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkgJiZcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLnBvaW50cy5sZW5ndGggPT09IDJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24gPSBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IGxpbmVhckVsZW1lbnRFZGl0b3IgPVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudDtcbiAgICAgICAgICBjb25zdCByZXQgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50ZXJEb3duKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJldC5oaXRFbGVtZW50KSB7XG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50ID0gcmV0LmhpdEVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQubGluZWFyRWxlbWVudEVkaXRvcikge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudDogcmV0LmxpbmVhckVsZW1lbnRFZGl0b3IgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXQuZGlkQWRkUG9pbnQgJiYgIXJldC5pc01pZFBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaGl0RWxlbWVudCBtYXkgYWxyZWFkeSBiZSBzZXQgYWJvdmUsIHNvIGNoZWNrIGZpcnN0XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPz9cbiAgICAgICAgICB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKTtcblxuICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgIC8vIEVhcmx5IHJldHVybiBpZiBwb2ludGVyIGlzIGhpdHRpbmcgbGluayBpY29uXG4gICAgICAgICAgY29uc3QgaGl0TGlua0VsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRMaW5rQXRQb3NpdGlvbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgeDogcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgICAgeTogcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGhpdExpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG92ZXJsYXBwZWQgZWxlbWVudHMgb25lIHBvc2l0aW9uIG1heSBoaXRcbiAgICAgICAgLy8gbXVsdGlwbGUgZWxlbWVudHNcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT5cbiAgICAgICAgICAgIHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoaGl0RWxlbWVudCA9PT0gbnVsbCB8fCAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkKSAmJlxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBJZiB3ZSBjbGljayBvbiBzb21ldGhpbmdcbiAgICAgICAgfSBlbHNlIGlmIChoaXRFbGVtZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAvLyBvbiBDTUQvQ1RSTCwgZHJpbGwgZG93biB0byBoaXQgZWxlbWVudCByZWdhcmRsZXNzIG9mIGdyb3VwcyBldGMuXG4gICAgICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5lZGl0R3JvdXBGb3JTZWxlY3RlZEVsZW1lbnQocHJldlN0YXRlLCBoaXRFbGVtZW50KSxcbiAgICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgLy8gbWFyayBhcyBub3QgY29tcGxldGVseSBoYW5kbGVkIHNvIGFzIHRvIGFsbG93IGRyYWdnaW5nIGV0Yy5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkZXNlbGVjdCBpZiBpdGVtIGlzIHNlbGVjdGVkXG4gICAgICAgICAgLy8gaWYgc2hpZnQgaXMgbm90IGNsaWNrZWQsIHRoaXMgd2lsbCBhbHdheXMgcmV0dXJuIHRydWVcbiAgICAgICAgICAvLyBvdGhlcndpc2UsIGl0IHdpbGwgdHJpZ2dlciBzZWxlY3Rpb24gYmFzZWQgb24gY3VycmVudFxuICAgICAgICAgIC8vIHN0YXRlIG9mIHRoZSBib3hcbiAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgY3VycmVudGx5IGVkaXRpbmcgYSBncm91cCwgZXhpdGluZyBlZGl0aW5nIG1vZGUgYW5kIGRlc2VsZWN0IHRoZSBncm91cC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICAgICAgICAhaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgaGl0IGVsZW1lbnQgdG8gc2VsZWN0aW9uLiBBdCB0aGlzIHBvaW50IGlmIHdlJ3JlIG5vdCBob2xkaW5nXG4gICAgICAgICAgICAvLyBTSElGVCB0aGUgcHJldmlvdXNseSBzZWxlY3RlZCBlbGVtZW50KHMpIHdlcmUgZGVzZWxlY3RlZCBhYm92ZVxuICAgICAgICAgICAgLy8gKG1ha2Ugc3VyZSB5b3UgdXNlIHNldFN0YXRlIHVwZGF0ZXIgdG8gdXNlIGxhdGVzdCBzdGF0ZSlcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgIXNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCAmJlxuICAgICAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOiBoaXRFbGVtZW50LmxpbmsgPyBcImluZm9cIiA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBwcml2YXRlIGlzQVNlbGVjdGVkRWxlbWVudChoaXRFbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGl0RWxlbWVudCAhPSBudWxsICYmIHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICBwb2ludDogUmVhZG9ubHk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PixcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSG93IG1hbnkgcGl4ZWxzIG9mZiB0aGUgc2hhcGUgYm91bmRhcnkgd2Ugc3RpbGwgY29uc2lkZXIgYSBoaXRcbiAgICBjb25zdCB0aHJlc2hvbGQgPSAxMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICBjb25zdCBbeDEsIHkxLCB4MiwgeTJdID0gZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHJldHVybiAoXG4gICAgICBwb2ludC54ID4geDEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnggPCB4MiArIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueSA+IHkxIC0gdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55IDwgeTIgKyB0aHJlc2hvbGRcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICAvLyBpZiB3ZSdyZSBjdXJyZW50bHkgc3RpbGwgZWRpdGluZyB0ZXh0LCBjbGlja2luZyBvdXRzaWRlXG4gICAgLy8gc2hvdWxkIG9ubHkgZmluYWxpemUgaXQsIG5vdCBjcmVhdGUgYW5vdGhlciAoaXJyZXNwZWN0aXZlXG4gICAgLy8gb2Ygc3RhdGUuYWN0aXZlVG9vbC5sb2NrZWQpXG4gICAgaWYgKGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHNjZW5lWCA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLng7XG4gICAgbGV0IHNjZW5lWSA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYW5CaW5kVGV4dCA9IGhhc0JvdW5kVGV4dEVsZW1lbnQoZWxlbWVudCk7XG4gICAgaWYgKGNhbkJpbmRUZXh0KSB7XG4gICAgICBzY2VuZVggPSBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICB9XG4gICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgIHNjZW5lWCxcbiAgICAgIHNjZW5lWSxcbiAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgfSk7XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7IHR5cGU6IFwic2VsZWN0aW9uXCIgfSksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICAvLyBCZWdpbiBhIG1hcmsgY2FwdHVyZS4gVGhpcyBkb2VzIG5vdCBoYXZlIHRvIHVwZGF0ZSBzdGF0ZSB5ZXQuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdGcmVlRHJhd0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBzaW11bGF0ZVByZXNzdXJlOiBldmVudC5wcmVzc3VyZSA9PT0gMC41LFxuICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBwcmVzc3VyZXMgPSBlbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgID8gZWxlbWVudC5wcmVzc3VyZXNcbiAgICAgIDogWy4uLmVsZW1lbnQucHJlc3N1cmVzLCBldmVudC5wcmVzc3VyZV07XG5cbiAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgIHBvaW50czogW1swLCAwXV0sXG4gICAgICBwcmVzc3VyZXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUltYWdlRWxlbWVudCA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgfToge1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIHNjZW5lWTogbnVtYmVyO1xuICB9KSA9PiB7XG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoc2NlbmVYLCBzY2VuZVksIHRoaXMuc3RhdGUuZ3JpZFNpemUpO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ltYWdlRWxlbWVudCh7XG4gICAgICB0eXBlOiBcImltYWdlXCIsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0xpbmVhckVsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIC8vIGZpbmFsaXplIGlmIGNvbXBsZXRpbmcgYSBsb29wXG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC50eXBlID09PSBcImxpbmVcIiAmJlxuICAgICAgICBpc1BhdGhBTG9vcChtdWx0aUVsZW1lbnQucG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgICApIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnksIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICAvLyBjbGlja2luZyBpbnNpZGUgY29tbWl0IHpvbmUg4oaSIGZpbmFsaXplIGFycm93XG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoID4gMSAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbbXVsdGlFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIC8vIGNsaWNraW5nIG91dHNpZGUgY29tbWl0IHpvbmUg4oaSIHVwZGF0ZSByZWZlcmVuY2UgZm9yIGxhc3QgY29tbWl0dGVkXG4gICAgICAvLyBwb2ludFxuICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICB9KTtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLyogSWYgYXJyb3cgaXMgcHJlLWFycm93aGVhZHMsIGl0IHdpbGwgaGF2ZSB1bmRlZmluZWQgZm9yIGJvdGggc3RhcnQgYW5kIGVuZCBhcnJvd2hlYWRzLlxuICAgICAgSWYgc28sIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3Igc3RhcnQgYW5kIFwiYXJyb3dcIiBmb3IgZW5kLiBJZiB0aGUgbGluZWFyIGl0ZW0gaXMgbm90XG4gICAgICBhbiBhcnJvdywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBib3RoLiBPdGhlcndpc2UsIHdlIHdhbnQgaXQgdG8gdXNlIHRoZVxuICAgICAgdmFsdWVzIGZyb20gYXBwU3RhdGUuICovXG5cbiAgICAgIGNvbnN0IHsgY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCBbc3RhcnRBcnJvd2hlYWQsIGVuZEFycm93aGVhZF0gPVxuICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiXG4gICAgICAgICAgPyBbY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWRdXG4gICAgICAgICAgOiBbbnVsbCwgbnVsbF07XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdMaW5lYXJFbGVtZW50KHtcbiAgICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICAgIHg6IGdyaWRYLFxuICAgICAgICB5OiBncmlkWSxcbiAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgc3RhcnRBcnJvd2hlYWQsXG4gICAgICAgIGVuZEFycm93aGVhZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgcG9pbnRzOiBbLi4uZWxlbWVudC5wb2ludHMsIFswLCAwXV0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICApO1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gUHJldmVudHMgZm9jdXMgZnJvbSBlc2NhcGluZyBleGNhbGlkcmF3IHRhYlxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkFMVCAmJiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzVGhyb3R0bGVkKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGluaXRpYWxpemUgZHJhZ09mZnNldFhZIG9ubHkgYWZ0ZXIgd2UndmUgdXBkYXRlZFxuICAgICAgLy8gYHN0YXRlLnNlbGVjdGVkRWxlbWVudElkc2Agb24gcG9pbnRlckRvd24uIERvaW5nIGl0IGhlcmUgaW4gcG9pbnRlck1vdmVcbiAgICAgIC8vIGV2ZW50IGhhbmRsZXIgc2hvdWxkIGhvcGVmdWxseSBlbnN1cmUgd2UncmUgYWxyZWFkeSB3b3JraW5nIHdpdGhcbiAgICAgIC8vIHRoZSB1cGRhdGVkIHN0YXRlLlxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPT09IG51bGwpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXREcmFnT2Zmc2V0WFkoXG4gICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG5cbiAgICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgICB0aGlzLmhhbmRsZUVyYXNlcihldmVudCwgcG9pbnRlckRvd25TdGF0ZSwgcG9pbnRlckNvb3Jkcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLy8gZm9yIGFycm93cy9saW5lcywgZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcgdW50aWwgYSBnaXZlbiB0aHJlc2hvbGRcbiAgICAgIC8vIHRvIGVuc3VyZSB3ZSBkb24ndCBjcmVhdGUgYSAyLXBvaW50IGFycm93IGJ5IG1pc3Rha2Ugd2hlblxuICAgICAgLy8gdXNlciBjbGlja3MgbW91c2UgaW4gYSB3YXkgdGhhdCBpdCBtb3ZlcyBhIHRpbnkgYml0ICh0aHVzXG4gICAgICAvLyB0cmlnZ2VyaW5nIHBvaW50ZXJtb3ZlKVxuXG4gICAgICBpZiAoXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgKHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImFycm93XCIgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJsaW5lXCIpXG4gICAgICApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApIDwgRFJBR0dJTkdfVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmlzUmVzaXppbmcpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fCB0aGlzLnN0YXRlLnNlbGVjdGVkTGluZWFyRWxlbWVudDtcbiAgICAgICAgY29uc3QgZGlkRHJhZyA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnREcmFnZ2luZyhcbiAgICAgICAgICBldmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKGVsZW1lbnQsIHBvaW50c1NjZW5lQ29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBwb2ludHNTY2VuZUNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsaW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICApO1xuICAgICAgICBpZiAoZGlkRHJhZykge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuaXNEcmFnZ2luZ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKFxuICAgICAgICAoZWxlbWVudCkgPT4gdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpc1NlbGVjdGluZ1BvaW50c0luTGluZUVkaXRvciA9XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgPT09XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudD8uaWQ7XG4gICAgICBpZiAoXG4gICAgICAgIChoYXNIaXRBU2VsZWN0ZWRFbGVtZW50IHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpICYmXG4gICAgICAgICFpc1NlbGVjdGluZ1BvaW50c0luTGluZUVkaXRvclxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMuZXZlcnkoKGVsZW1lbnQpID0+IGVsZW1lbnQubG9ja2VkKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBNYXJraW5nIHRoYXQgY2xpY2sgd2FzIHVzZWQgZm9yIGRyYWdnaW5nIHRvIGNoZWNrXG4gICAgICAgIC8vIGlmIGVsZW1lbnRzIHNob3VsZCBiZSBkZXNlbGVjdGVkIG9uIHBvaW50ZXJ1cFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICAvLyBwcmV2ZW50IGRyYWdnaW5nIGV2ZW4gaWYgd2UncmUgbm8gbG9uZ2VyIGhvbGRpbmcgY21kL2N0cmwgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGl0IHdvdWxkIGhhdmUgd2VpcmQgcmVzdWx0cyAoc3R1ZmYganVtcGluZyBhbGwgb3ZlciB0aGUgc2NyZWVuKVxuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAwICYmICFwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwpIHtcbiAgICAgICAgICBjb25zdCBbZHJhZ1gsIGRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IFtkcmFnRGlzdGFuY2VYLCBkcmFnRGlzdGFuY2VZXSA9IFtcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngpLFxuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSksXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIC8vIFdlIG9ubHkgZHJhZyBpbiBvbmUgZGlyZWN0aW9uIGlmIHNoaWZ0IGlzIHByZXNzZWRcbiAgICAgICAgICBjb25zdCBsb2NrRGlyZWN0aW9uID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgZHJhZ1NlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdYLFxuICAgICAgICAgICAgZHJhZ1ksXG4gICAgICAgICAgICBsb2NrRGlyZWN0aW9uLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWCxcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgICAgLy8gV2UgZHVwbGljYXRlIHRoZSBzZWxlY3RlZCBlbGVtZW50IGlmIGFsdCBpcyBwcmVzc2VkIG9uIHBvaW50ZXIgbW92ZVxuICAgICAgICAgIGlmIChldmVudC5hbHRLZXkgJiYgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0JlZW5EdXBsaWNhdGVkKSB7XG4gICAgICAgICAgICAvLyBNb3ZlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZWxlbWVudHMgdG8gdGhlIHRvcCBvZiB0aGUgeiBpbmRleCBzdGFjaywgYW5kXG4gICAgICAgICAgICAvLyBwdXQgdGhlIGR1cGxpY2F0ZXMgd2hlcmUgdGhlIHNlbGVjdGVkIGVsZW1lbnRzIHVzZWQgdG8gYmUuXG4gICAgICAgICAgICAvLyAodGhlIG9yaWdpbiBwb2ludCB3aGVyZSB0aGUgZHJhZ2dpbmcgc3RhcnRlZClcblxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzVG9BcHBlbmQgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwSWRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRJZHM6IEFycmF5PEV4Y2FsaWRyYXdFbGVtZW50W1wiaWRcIl0+ID1cbiAgICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyhlbGVtZW50cywgdGhpcy5zdGF0ZSwgdHJ1ZSkubWFwKFxuICAgICAgICAgICAgICAgIChlbGVtZW50KSA9PiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkcy5pbmNsdWRlcyhlbGVtZW50LmlkKSB8fFxuICAgICAgICAgICAgICAgIC8vIGNhc2U6IHRoZSBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMgbWlnaHQgbm90IGhhdmUgYmVlblxuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZWQgeWV0IGJ5IHRoZSB0aW1lIHRoaXMgbW91c2Vtb3ZlIGV2ZW50IGlzIGZpcmVkXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQuaWQgPT09IGhpdEVsZW1lbnQ/LmlkICYmXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXBsaWNhdGVkRWxlbWVudCA9IGR1cGxpY2F0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICAgICAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3JpZ2luRHJhZ1gsIG9yaWdpbkRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC55LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHVwbGljYXRlZEVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgIHg6IGR1cGxpY2F0ZWRFbGVtZW50LnggKyAob3JpZ2luRHJhZ1ggLSBkcmFnWCksXG4gICAgICAgICAgICAgICAgICB5OiBkdXBsaWNhdGVkRWxlbWVudC55ICsgKG9yaWdpbkRyYWdZIC0gZHJhZ1kpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGR1cGxpY2F0ZWRFbGVtZW50KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgZHVwbGljYXRlZEVsZW1lbnQuaWQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5leHRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuZXh0U2NlbmVFbGVtZW50cyA9IFsuLi5uZXh0RWxlbWVudHMsIC4uLmVsZW1lbnRzVG9BcHBlbmRdO1xuICAgICAgICAgICAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLFxuICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLFxuICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbihcbiAgICAgICAgICAgICAgbmV4dFNjZW5lRWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICAgIFwiZHVwbGljYXRlc1NlcnZlQXNPbGRcIixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0U2NlbmVFbGVtZW50cyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJdCBpcyB2ZXJ5IGltcG9ydGFudCB0byByZWFkIHRoaXMuc3RhdGUgd2l0aGluIGVhY2ggbW92ZSBldmVudCxcbiAgICAgIC8vIG90aGVyd2lzZSB3ZSB3b3VsZCByZWFkIGEgc3RhbGUgb25lIVxuICAgICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGNvbnN0IGR4ID0gcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGNvbnN0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzLmxlbmd0aCA+IDAgJiYgcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgZGlzY2FyZFBvaW50ID1cbiAgICAgICAgICBsYXN0UG9pbnQgJiYgbGFzdFBvaW50WzBdID09PSBkeCAmJiBsYXN0UG9pbnRbMV0gPT09IGR5O1xuXG4gICAgICAgIGlmICghZGlzY2FyZFBvaW50KSB7XG4gICAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICAgID8gZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlc1xuICAgICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgZXZlbnQucHJlc3N1cmVdO1xuXG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgICAgcHJlc3N1cmVzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IGdyaWRYIC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IGdyaWRZIC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSAmJiBwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4LCBoZWlnaHQ6IGR5IH0gPSBnZXRMb2NrZWRMaW5lYXJDdXJzb3JBbGlnblNpemUoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudC55LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMuc2xpY2UoMCwgLTEpLCBbZHgsIGR5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIGZhbHNlKSkge1xuICAgICAgICAgIC8vIFdoZW4gY3JlYXRpbmcgYSBsaW5lYXIgZWxlbWVudCBieSBkcmFnZ2luZ1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBbcG9pbnRlckNvb3Jkc10sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldE5vbkRlbGV0ZWRFbGVtZW50cygpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgLy8gYWxsb3dzIGZvciBib3gtc2VsZWN0aW5nIHBvaW50cyAod2l0aG91dCBzaGlmdClcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgIGlzU29tZUVsZW1lbnRTZWxlY3RlZChlbGVtZW50cywgdGhpcy5zdGF0ZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCAmJiBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYm94LXNlbGVjdCBsaW5lIGVkaXRvciBwb2ludHNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZUJveFNlbGVjdGlvbihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHJlZ3VsYXIgYm94LXNlbGVjdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uID0gZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24oXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ucmVkdWNlKFxuICAgICAgICAgICAgICAgICAgICAoYWNjOiBSZWNvcmQ8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXSwgdHJ1ZT4sIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICBhY2NbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgIC4uLihwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50XG4gICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdXNpbmcgY3RybC9jbWQsIHNlbGVjdCB0aGUgaGl0RWxlbWVudCBvbmx5IGlmIHdlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBoYXZlbid0IGJveC1zZWxlY3RlZCBhbnl0aGluZyBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudC5pZF06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICFlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA6IG51bGwpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2hvd0h5cGVybGlua1BvcHVwOlxuICAgICAgICAgICAgICAgICAgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvblswXS5saW5rXG4gICAgICAgICAgICAgICAgICAgID8gXCJpbmZvXCJcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAvLyBzZWxlY3QgbGluZWFyIGVsZW1lbnQgb25seSB3aGVuIHdlIGhhdmVuJ3QgYm94LXNlbGVjdGVkIGFueXRoaW5nIGVsc2VcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICBlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgICAgIGlzTGluZWFyRWxlbWVudChlbGVtZW50c1dpdGhpblNlbGVjdGlvblswXSlcbiAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIG1vdmUgaGFwcGVuZWQgb3ZlciBlaXRoZXIgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVySG9yaXpvbnRhbCkge1xuICAgICAgY29uc3QgeCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBkeCA9IHggLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkeCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSB4O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJWZXJ0aWNhbCkge1xuICAgICAgY29uc3QgeSA9IGV2ZW50LmNsaWVudFk7XG4gICAgICBjb25zdCBkeSA9IHkgLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFkgLSBkeSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSB5O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogUG9pbnRlckV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChjaGlsZEV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICByZXNpemluZ0VsZW1lbnQsXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgYWN0aXZlVG9vbCxcbiAgICAgICAgaXNSZXNpemluZyxcbiAgICAgICAgaXNSb3RhdGluZyxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGlzUmVzaXppbmc6IGZhbHNlLFxuICAgICAgICBpc1JvdGF0aW5nOiBmYWxzZSxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50OiBudWxsLFxuICAgICAgICBzZWxlY3Rpb25FbGVtZW50OiBudWxsLFxuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgICAgLy8gdGV4dCBlbGVtZW50cyBhcmUgcmVzZXQgb24gZmluYWxpemUsIGFuZCByZXNldHRpbmcgb24gcG9pbnRlcnVwXG4gICAgICAgIC8vIG1heSBjYXVzZSBpc3N1ZXMgd2l0aCBkb3VibGUgdGFwc1xuICAgICAgICBlZGl0aW5nRWxlbWVudDpcbiAgICAgICAgICBtdWx0aUVsZW1lbnQgfHwgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICAgICAgICAgPyB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5zYXZlUG9pbnRlcihjaGlsZEV2ZW50LmNsaWVudFgsIGNoaWxkRXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcblxuICAgICAgLy8gSGFuZGxlIGVuZCBvZiBkcmFnZ2luZyBhIHBvaW50IG9mIGEgbGluZWFyIGVsZW1lbnQsIG1pZ2h0IGNsb3NlIGEgbG9vcFxuICAgICAgLy8gYW5kIHNldHMgYmluZGluZyBlbGVtZW50XG4gICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQ/LmVsZW1lbnQ/LmlkICE9PVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVkaXRpbmdMaW5lYXJFbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyVXAoXG4gICAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQuZWxlbWVudElkXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRUxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyBzZXQgc2VsZWN0ZWRMaW5lYXJFbGVtZW50IHRvIG51bGwgaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBlbGVtZW50IHNlbGVjdGVkIHNpbmNlIHdlIGRvbid0IHdhbnQgdG8gc2hvdyBsaW5lYXIgZWxlbWVudCBoYW5kbGVzXG4gICAgICAgICAgaWYgKHNlbGVjdGVkRUxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkTGluZWFyRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbGluZWFyRWxlbWVudEVkaXRvciA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgeyBzdGFydEJpbmRpbmdFbGVtZW50LCBlbmRCaW5kaW5nRWxlbWVudCB9ID1cbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnRFZGl0b3I7XG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudChsaW5lYXJFbGVtZW50RWRpdG9yLmVsZW1lbnRJZCk7XG4gICAgICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGJpbmRPclVuYmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHN0YXJ0QmluZGluZ0VsZW1lbnQsXG4gICAgICAgICAgICAgIGVuZEJpbmRpbmdFbGVtZW50LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobGluZWFyRWxlbWVudEVkaXRvciAhPT0gdGhpcy5zdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi5saW5lYXJFbGVtZW50RWRpdG9yLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkUG9pbnRzSW5kaWNlczogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUuZmx1c2goKTtcbiAgICAgIH1cblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfTU9WRSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX1VQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlET1dOLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWVVQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAhLFxuICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IG51bGwgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQ/LnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBsZXQgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgLy8gQWxsb3dzIGRvdHMgdG8gYXZvaWQgYmVpbmcgZmxhZ2dlZCBhcyBpbmZpbml0ZWx5IHNtYWxsXG4gICAgICAgIGlmIChkeCA9PT0gcG9pbnRzWzBdWzBdICYmIGR5ID09PSBwb2ludHNbMF1bMV0pIHtcbiAgICAgICAgICBkeSArPSAwLjAwMDE7XG4gICAgICAgICAgZHggKz0gMC4wMDAxO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJlc3N1cmVzID0gZHJhZ2dpbmdFbGVtZW50LnNpbXVsYXRlUHJlc3N1cmVcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgY2hpbGRFdmVudC5wcmVzc3VyZV07XG5cbiAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSxcbiAgICAgICAgICBwcmVzc3VyZXMsXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBbZHgsIGR5XSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IGRyYWdnaW5nRWxlbWVudDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgICAgeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0xpbmVhckVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50IS5wb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGNoaWxkRXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICAgICFtdWx0aUVsZW1lbnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgICAuLi5kcmFnZ2luZ0VsZW1lbnQucG9pbnRzLFxuICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50LngsXG4gICAgICAgICAgICAgICAgcG9pbnRlckNvb3Jkcy55IC0gZHJhZ2dpbmdFbGVtZW50LnksXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbXVsdGlFbGVtZW50OiBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudDogdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmICFtdWx0aUVsZW1lbnQpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICAgICAgICBpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgZmFsc2UpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBtYXliZUJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLCBzdGFydEJvdW5kRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgICBpZiAoIWFjdGl2ZVRvb2wubG9ja2VkKSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgICAgYWN0aXZlVG9vbDogdXBkYXRlQWN0aXZlVG9vbCh0aGlzLnN0YXRlLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW2RyYWdnaW5nRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgYWN0aXZlVG9vbC50eXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCAmJlxuICAgICAgICBpc0ludmlzaWJseVNtYWxsRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgLy8gcmVtb3ZlIGludmlzaWJsZSBlbGVtZW50IHdoaWNoIHdhcyBhZGRlZCBpbiBvblBvaW50ZXJEb3duXG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuc2xpY2UoMCwgLTEpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMoZHJhZ2dpbmdFbGVtZW50KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNpemluZ0VsZW1lbnQgJiYgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQocmVzaXppbmdFbGVtZW50KSkge1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiBlbC5pZCAhPT0gcmVzaXppbmdFbGVtZW50LmlkKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29kZSBiZWxvdyBoYW5kbGVzIHNlbGVjdGlvbiB3aGVuIGVsZW1lbnQocykgd2VyZW4ndFxuICAgICAgLy8gZHJhZyBvciBhZGRlZCB0byBzZWxlY3Rpb24gb24gcG9pbnRlciBkb3duIHBoYXNlLlxuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09IGhpdEVsZW1lbnQ/LmlkICYmXG4gICAgICAgIGlzTGluZWFyRWxlbWVudChoaXRFbGVtZW50KVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRUxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCB3aGVuIG5vIG90aGVyIGVsZW1lbnQgc2VsZWN0ZWQgZXhjZXB0XG4gICAgICAgIC8vIHRoZSBvbmUgd2UndmUgaGl0XG4gICAgICAgIGlmIChzZWxlY3RlZEVMZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc0VyYXNlckFjdGl2ZSh0aGlzLnN0YXRlKSkge1xuICAgICAgICBjb25zdCBkcmFnZ2VkRGlzdGFuY2UgPSBkaXN0YW5jZTJkKFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRYLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJEb3duIS5jbGllbnRZLFxuICAgICAgICAgIHRoaXMubGFzdFBvaW50ZXJVcCEuY2xpZW50WCxcbiAgICAgICAgICB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRyYWdnZWREaXN0YW5jZSA9PT0gMCkge1xuICAgICAgICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2xpZW50WDogdGhpcy5sYXN0UG9pbnRlclVwIS5jbGllbnRYLFxuICAgICAgICAgICAgICBjbGllbnRZOiB0aGlzLmxhc3RQb2ludGVyVXAhLmNsaWVudFksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICAgICAgICk7XG4gICAgICAgICAgaGl0RWxlbWVudHMuZm9yRWFjaChcbiAgICAgICAgICAgIChoaXRFbGVtZW50KSA9PlxuICAgICAgICAgICAgICAocG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtoaXRFbGVtZW50LmlkXSA9IHtcbiAgICAgICAgICAgICAgICBlcmFzZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBoaXRFbGVtZW50Lm9wYWNpdHksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lcmFzZUVsZW1lbnRzKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2UpLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnJlc3RvcmVSZWFkeVRvRXJhc2VFbGVtZW50cyhwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gJiZcbiAgICAgICAgLy8gaWYgd2UncmUgZWRpdGluZyBhIGxpbmUsIHBvaW50ZXJ1cCBzaG91bGRuJ3Qgc3dpdGNoIHNlbGVjdGlvbiBpZlxuICAgICAgICAvLyBib3ggc2VsZWN0ZWRcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHdoZW4gaW5zaWRlIGxpbmUgZWRpdG9yLCBzaGlmdCBzZWxlY3RzIHBvaW50cyBpbnN0ZWFkXG4gICAgICAgIGlmIChjaGlsZEV2ZW50LnNoaWZ0S2V5ICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICBpZiAoaXNTZWxlY3RlZFZpYUdyb3VwKHRoaXMuc3RhdGUsIGhpdEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gdW5zZWxlY3QgYWxsIGdyb3VwcyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgLy8gYXMgd2VsbCBhcyBhbGwgZWxlbWVudHMgdGhhdCBhcmUgcGFydCBvZiB0aGUgZ3JvdXBzXG4gICAgICAgICAgICAgIC8vIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICBjb25zdCBpZHNPZlNlbGVjdGVkRWxlbWVudHNUaGF0QXJlSW5Hcm91cHMgPSBoaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgLmZsYXRNYXAoKGdyb3VwSWQpID0+XG4gICAgICAgICAgICAgICAgICBnZXRFbGVtZW50c0luR3JvdXAoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwSWQsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAubWFwKChlbGVtZW50KSA9PiAoeyBbZWxlbWVudC5pZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXZJZCwgYWNjKSA9PiAoeyAuLi5wcmV2SWQsIC4uLmFjYyB9KSwge30pO1xuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge1xuICAgICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5oaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGdJZCkgPT4gKHsgW2dJZF06IGZhbHNlIH0pKVxuICAgICAgICAgICAgICAgICAgICAucmVkdWNlKChwcmV2LCBhY2MpID0+ICh7IC4uLnByZXYsIC4uLmFjYyB9KSwge30pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmlkc09mU2VsZWN0ZWRFbGVtZW50c1RoYXRBcmVJbkdyb3VwcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgIC8vIGlmIG5vdCBncmFnZ2luZyBhIGxpbmVhciBlbGVtZW50IHBvaW50IChvdXRzaWRlIGVkaXRvcilcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudElkcyA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICAgIHsgLi4ucHJldlN0YXRlLCBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyB9LFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHNlbGVjdGVkTGluZWFyRWxlbWVudCBvbmx5IGlmIHRoYXRzIHRoZSBvbmx5IGVsZW1lbnQgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRMaW5lYXJFbGVtZW50OlxuICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgICAgICAgICAgaXNMaW5lYXJFbGVtZW50KG5ld1NlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFkZCBlbGVtZW50IHRvIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAuLi5zZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpbmVhckVsZW1lbnQ6XG4gICAgICAgICAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoaGl0RWxlbWVudCkgJiZcbiAgICAgICAgICAgICAgICAgIC8vIERvbid0IHNldCBgc2VsZWN0ZWRMaW5lYXJFbGVtZW50YCBpZiBpdHMgc2FtZSBhcyB0aGUgaGl0RWxlbWVudCwgdGhpcyBpcyBtYWlubHkgdG8gcHJldmVudCByZXNldHRpbmcgdGhlIGBob3ZlclBvaW50SW5kZXhgIHRvIC0xLlxuICAgICAgICAgICAgICAgICAgLy8gRnV0dXJlIHdlIHNob3VsZCB1cGRhdGUgdGhlIEFQSSB0byB0YWtlIGNhcmUgb2Ygc2V0dGluZyB0aGUgY29ycmVjdCBgaG92ZXJQb2ludEluZGV4YCB3aGVuIGluaXRpYWxpemVkXG4gICAgICAgICAgICAgICAgICBwcmV2U3RhdGUuc2VsZWN0ZWRMaW5lYXJFbGVtZW50Py5lbGVtZW50SWQgIT09IGhpdEVsZW1lbnQuaWRcbiAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihoaXRFbGVtZW50LCB0aGlzLnNjZW5lKVxuICAgICAgICAgICAgICAgICAgICA6IHByZXZTdGF0ZS5zZWxlY3RlZExpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXRoaXMuc3RhdGUuaXNSZXNpemluZyAmJlxuICAgICAgICAoKGhpdEVsZW1lbnQgJiZcbiAgICAgICAgICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkpIHx8XG4gICAgICAgICAgKCFoaXRFbGVtZW50ICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cykpXG4gICAgICApIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRGVzZWxlY3Qgc2VsZWN0ZWQgZWxlbWVudHNcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhYWN0aXZlVG9vbC5sb2NrZWQgJiZcbiAgICAgICAgYWN0aXZlVG9vbC50eXBlICE9PSBcImZyZWVkcmF3XCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50XG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBhY3RpdmVUb29sLnR5cGUgIT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkIHx8IGlzUmVzaXppbmcgfHwgaXNSb3RhdGluZykge1xuICAgICAgICAoaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICAgID8gYmluZE9yVW5iaW5kU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMpKFxuICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHModGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICghYWN0aXZlVG9vbC5sb2NrZWQgJiYgYWN0aXZlVG9vbC50eXBlICE9PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZXN0b3JlUmVhZHlUb0VyYXNlRWxlbWVudHMgPSAoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7XG4gICAgICAgICAgb3BhY2l0eTogcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuaWRdLm9wYWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgaXNCb3VuZFRvQ29udGFpbmVyKGVsZSkgJiZcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5lbGVtZW50SWRzVG9FcmFzZVtlbGUuY29udGFpbmVySWRdICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXS5lcmFzZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGUsIHtcbiAgICAgICAgICBvcGFjaXR5OiBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0ub3BhY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICB9O1xuXG4gIHByaXZhdGUgZXJhc2VFbGVtZW50cyA9IChwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlKSA9PiB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmlkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5pZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7IGlzRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGlzQm91bmRUb0NvbnRhaW5lcihlbGUpICYmXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZWxlbWVudElkc1RvRXJhc2VbZWxlLmNvbnRhaW5lcklkXSAmJlxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmVsZW1lbnRJZHNUb0VyYXNlW2VsZS5jb250YWluZXJJZF0uZXJhc2VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlLCB7IGlzRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICB9O1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUltYWdlID0gYXN5bmMgKHtcbiAgICBpbWFnZUZpbGUsXG4gICAgaW1hZ2VFbGVtZW50OiBfaW1hZ2VFbGVtZW50LFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcgPSBmYWxzZSxcbiAgfToge1xuICAgIGltYWdlRmlsZTogRmlsZTtcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ7XG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICAvLyBhdCB0aGlzIHBvaW50IHRoaXMgc2hvdWxkIGJlIGd1YXJhbnRlZWQgaW1hZ2UgZmlsZSwgYnV0IHdlIGRvIHRoaXMgY2hlY2tcbiAgICAvLyB0byBzYXRpc2Z5IFRTIGRvd24gdGhlIGxpbmVcbiAgICBpZiAoIWlzU3VwcG9ydGVkSW1hZ2VGaWxlKGltYWdlRmlsZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnVuc3VwcG9ydGVkRmlsZVR5cGVcIikpO1xuICAgIH1cbiAgICBjb25zdCBtaW1lVHlwZSA9IGltYWdlRmlsZS50eXBlO1xuXG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBcIndhaXRcIik7XG5cbiAgICBpZiAobWltZVR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBTVkdTdHJpbmdUb0ZpbGUoXG4gICAgICAgICAgYXdhaXQgbm9ybWFsaXplU1ZHKGF3YWl0IGltYWdlRmlsZS50ZXh0KCkpLFxuICAgICAgICAgIGltYWdlRmlsZS5uYW1lLFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5zdmdJbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBnZW5lcmF0ZSBpbWFnZSBpZCAoYnkgZGVmYXVsdCB0aGUgZmlsZSBkaWdlc3QpIGJlZm9yZSBhbnlcbiAgICAvLyByZXNpemluZy9jb21wcmVzc2lvbiB0YWtlcyBwbGFjZSB0byBrZWVwIGl0IG1vcmUgcG9ydGFibGVcbiAgICBjb25zdCBmaWxlSWQgPSBhd2FpdCAoKHRoaXMucHJvcHMuZ2VuZXJhdGVJZEZvckZpbGU/LihcbiAgICAgIGltYWdlRmlsZSxcbiAgICApIGFzIFByb21pc2U8RmlsZUlkPikgfHwgZ2VuZXJhdGVJZEZyb21GaWxlKGltYWdlRmlsZSkpO1xuXG4gICAgaWYgKCFmaWxlSWQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJDb3VsZG4ndCBnZW5lcmF0ZSBmaWxlIGlkIG9yIHRoZSBzdXBwbGllZCBgZ2VuZXJhdGVJZEZvckZpbGVgIGRpZG4ndCByZXNvbHZlIHRvIG9uZS5cIixcbiAgICAgICk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZ0ZpbGVEYXRhID0gdGhpcy5maWxlc1tmaWxlSWRdO1xuICAgIGlmICghZXhpc3RpbmdGaWxlRGF0YT8uZGF0YVVSTCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IERFRkFVTFRfTUFYX0lNQUdFX1dJRFRIX09SX0hFSUdIVCxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJlcnJvciB0cnlpbmcgdG8gcmVzaW5nIGltYWdlIGZpbGUgb24gaW5zZXJ0aW9uXCIsIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGltYWdlRmlsZS5zaXplID4gTUFYX0FMTE9XRURfRklMRV9CWVRFUykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgdChcImVycm9ycy5maWxlVG9vQmlnXCIsIHtcbiAgICAgICAgICAgIG1heFNpemU6IGAke01hdGgudHJ1bmMoTUFYX0FMTE9XRURfRklMRV9CWVRFUyAvIDEwMjQgLyAxMDI0KX1NQmAsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgIGNvbnN0IGRhdGFVUkwgPSB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkw7XG4gICAgICAvLyBvcHRpbWl6YXRpb24gc28gdGhhdCB3ZSBkb24ndCB1bm5lY2Vzc2FyaWx5IHJlc2l6ZSB0aGUgb3JpZ2luYWxcbiAgICAgIC8vIGZ1bGwtc2l6ZSBmaWxlIGZvciBjdXJzb3IgcHJldmlld1xuICAgICAgLy8gKGl0J3MgbXVjaCBmYXN0ZXIgdG8gY29udmVydCB0aGUgcmVzaXplZCBkYXRhVVJMIHRvIEZpbGUpXG4gICAgICBjb25zdCByZXNpemVkRmlsZSA9IGRhdGFVUkwgJiYgZGF0YVVSTFRvRmlsZShkYXRhVVJMKTtcblxuICAgICAgdGhpcy5zZXRJbWFnZVByZXZpZXdDdXJzb3IocmVzaXplZEZpbGUgfHwgaW1hZ2VGaWxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhVVJMID1cbiAgICAgIHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTCB8fCAoYXdhaXQgZ2V0RGF0YVVSTChpbWFnZUZpbGUpKTtcblxuICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IG11dGF0ZUVsZW1lbnQoXG4gICAgICBfaW1hZ2VFbGVtZW50LFxuICAgICAge1xuICAgICAgICBmaWxlSWQsXG4gICAgICB9LFxuICAgICAgZmFsc2UsXG4gICAgKSBhcyBOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD47XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8Tm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+PihcbiAgICAgIGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmZpbGVzID0ge1xuICAgICAgICAgICAgLi4udGhpcy5maWxlcyxcbiAgICAgICAgICAgIFtmaWxlSWRdOiB7XG4gICAgICAgICAgICAgIG1pbWVUeXBlLFxuICAgICAgICAgICAgICBpZDogZmlsZUlkLFxuICAgICAgICAgICAgICBkYXRhVVJMLFxuICAgICAgICAgICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNhY2hlZEltYWdlRGF0YSA9IHRoaXMuaW1hZ2VDYWNoZS5nZXQoZmlsZUlkKTtcbiAgICAgICAgICBpZiAoIWNhY2hlZEltYWdlRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShbaW1hZ2VFbGVtZW50XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjYWNoZWRJbWFnZURhdGE/LmltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgYXdhaXQgY2FjaGVkSW1hZ2VEYXRhLmltYWdlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnRJZCAhPT0gaW1hZ2VFbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudD8uaWQgIT09IGltYWdlRWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKCFzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGluc2VydHMgaW1hZ2UgaW50byBlbGVtZW50cyBhcnJheSBhbmQgcmVyZW5kZXJzXG4gICAqL1xuICBwcml2YXRlIGluc2VydEltYWdlRWxlbWVudCA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgaW1hZ2VGaWxlOiBGaWxlLFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuLFxuICApID0+IHtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgaW1hZ2VFbGVtZW50LFxuICAgIF0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUltYWdlKHtcbiAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICBpc0RlbGV0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfHwgdChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yID0gYXN5bmMgKGltYWdlRmlsZTogRmlsZSkgPT4ge1xuICAgIC8vIG11c3RuJ3QgYmUgbGFyZ2VyIHRoYW4gMTI4IHB4XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19CYXNpY19Vc2VyX0ludGVyZmFjZS9Vc2luZ19VUkxfdmFsdWVzX2Zvcl90aGVfY3Vyc29yX3Byb3BlcnR5XG4gICAgY29uc3QgY3Vyc29ySW1hZ2VTaXplUHggPSA5NjtcblxuICAgIGNvbnN0IGltYWdlUHJldmlldyA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IGN1cnNvckltYWdlU2l6ZVB4LFxuICAgIH0pO1xuXG4gICAgbGV0IHByZXZpZXdEYXRhVVJMID0gYXdhaXQgZ2V0RGF0YVVSTChpbWFnZVByZXZpZXcpO1xuXG4gICAgLy8gU1ZHIGNhbm5vdCBiZSByZXNpemVkIHZpYSBgcmVzaXplSW1hZ2VGaWxlYCBzbyB3ZSByZXNpemUgYnkgcmVuZGVyaW5nIHRvXG4gICAgLy8gYSBzbWFsbCBjYW52YXNcbiAgICBpZiAoaW1hZ2VGaWxlLnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICBjb25zdCBpbWcgPSBhd2FpdCBsb2FkSFRNTEltYWdlRWxlbWVudChwcmV2aWV3RGF0YVVSTCk7XG5cbiAgICAgIGxldCBoZWlnaHQgPSBNYXRoLm1pbihpbWcuaGVpZ2h0LCBjdXJzb3JJbWFnZVNpemVQeCk7XG4gICAgICBsZXQgd2lkdGggPSBoZWlnaHQgKiAoaW1nLndpZHRoIC8gaW1nLmhlaWdodCk7XG5cbiAgICAgIGlmICh3aWR0aCA+IGN1cnNvckltYWdlU2l6ZVB4KSB7XG4gICAgICAgIHdpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgICAgIGhlaWdodCA9IHdpZHRoICogKGltZy5oZWlnaHQgLyBpbWcud2lkdGgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuXG4gICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBwcmV2aWV3RGF0YVVSTCA9IGNhbnZhcy50b0RhdGFVUkwoTUlNRV9UWVBFUy5zdmcpIGFzIERhdGFVUkw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudElkKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pIDQgNCwgYXV0b2ApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uSW1hZ2VBY3Rpb24gPSBhc3luYyAoXG4gICAgeyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5IH0gPSB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHk6IGZhbHNlIH0sXG4gICkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbGllbnRYID0gdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgICBjb25zdCBjbGllbnRZID0gdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGltYWdlRmlsZSA9IGF3YWl0IGZpbGVPcGVuKHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiSW1hZ2VcIixcbiAgICAgICAgZXh0ZW5zaW9uczogW1wianBnXCIsIFwicG5nXCIsIFwic3ZnXCIsIFwiZ2lmXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHtcbiAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICBzY2VuZVk6IHksXG4gICAgICB9KTtcblxuICAgICAgaWYgKGluc2VydE9uQ2FudmFzRGlyZWN0bHkpIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBpbWFnZUZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50SWQ6IGltYWdlRWxlbWVudC5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KFxuICAgICAgICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgICAgICAgIGltYWdlRmlsZSxcbiAgICAgICAgICAgICAgLyogc2hvd0N1cnNvckltYWdlUHJldmlldyAqLyB0cnVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkFib3J0RXJyb3JcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudElkOiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IHVwZGF0ZUFjdGl2ZVRvb2wodGhpcy5zdGF0ZSwgeyB0eXBlOiBcInNlbGVjdGlvblwiIH0pLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zID0gKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBmb3JjZU5hdHVyYWxTaXplID0gZmFsc2UsXG4gICkgPT4ge1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50KSAmJlxuICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChpbWFnZUVsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG5cbiAgICBpZiAoIWltYWdlIHx8IGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyU2l6ZSA9IDEwMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgICB4OiBpbWFnZUVsZW1lbnQueCAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgeTogaW1hZ2VFbGVtZW50LnkgLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgICAgaGVpZ2h0OiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgZm9yY2VOYXR1cmFsU2l6ZSB8fFxuICAgICAgLy8gaWYgdXNlci1jcmVhdGVkIGJvdW5kaW5nIGJveCBpcyBiZWxvdyB0aHJlc2hvbGQsIGFzc3VtZSB0aGVcbiAgICAgIC8vIGludGVudGlvbiB3YXMgdG8gY2xpY2sgaW5zdGVhZCBvZiBkcmFnLCBhbmQgdXNlIHRoZSBpbWFnZSdzXG4gICAgICAvLyBpbnRyaW5zaWMgc2l6ZVxuICAgICAgKGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5oZWlnaHQgLSAxMjAsIDE2MCk7XG4gICAgICAvLyBtYXggNjUlIG9mIGNhbnZhcyBoZWlnaHQsIGNsYW1wZWQgdG8gPDMwMHB4LCB2aCAtIDEyMHB4PlxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICAgIG1pbkhlaWdodCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnN0YXRlLmhlaWdodCAqIDAuNSkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihpbWFnZS5uYXR1cmFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBoZWlnaHQgKiAoaW1hZ2UubmF0dXJhbFdpZHRoIC8gaW1hZ2UubmF0dXJhbEhlaWdodCk7XG5cbiAgICAgIC8vIGFkZCBjdXJyZW50IGltYWdlRWxlbWVudCB3aWR0aC9oZWlnaHQgdG8gYWNjb3VudCBmb3IgcHJldmlvdXMgY2VudGVyaW5nXG4gICAgICAvLyBvZiB0aGUgcGxhY2Vob2xkZXIgaW1hZ2VcbiAgICAgIGNvbnN0IHggPSBpbWFnZUVsZW1lbnQueCArIGltYWdlRWxlbWVudC53aWR0aCAvIDIgLSB3aWR0aCAvIDI7XG4gICAgICBjb25zdCB5ID0gaW1hZ2VFbGVtZW50LnkgKyBpbWFnZUVsZW1lbnQuaGVpZ2h0IC8gMiAtIGhlaWdodCAvIDI7XG5cbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiB1cGRhdGVzIGltYWdlIGNhY2hlLCByZWZyZXNoaW5nIHVwZGF0ZWQgZWxlbWVudHMgYW5kL29yIHNldHRpbmcgc3RhdHVzXG4gICAgICB0byBlcnJvciBmb3IgaW1hZ2VzIHRoYXQgZmFpbCBkdXJpbmcgPGltZz4gZWxlbWVudCBjcmVhdGlvbiAqL1xuICBwcml2YXRlIHVwZGF0ZUltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdLFxuICAgIGZpbGVzID0gdGhpcy5maWxlcyxcbiAgKSA9PiB7XG4gICAgY29uc3QgeyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9ID0gYXdhaXQgX3VwZGF0ZUltYWdlQ2FjaGUoe1xuICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgZmlsZUlkczogZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCksXG4gICAgICBmaWxlcyxcbiAgICB9KTtcbiAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUgfHwgZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICBpZiAodXBkYXRlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZCkpIHtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgICAgZXJyb3JlZEZpbGVzLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdFbGVtZW50V2l0aChlbGVtZW50LCB7XG4gICAgICAgICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfTtcbiAgfTtcblxuICAvKiogYWRkcyBuZXcgaW1hZ2VzIHRvIGltYWdlQ2FjaGUgYW5kIHJlLXJlbmRlcnMgaWYgbmVlZGVkICovXG4gIHByaXZhdGUgYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudHM6IEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudFtdID0gZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICApLFxuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHVuY2FjaGVkSW1hZ2VFbGVtZW50cyA9IGltYWdlRWxlbWVudHMuZmlsdGVyKFxuICAgICAgKGVsZW1lbnQpID0+ICFlbGVtZW50LmlzRGVsZXRlZCAmJiAhdGhpcy5pbWFnZUNhY2hlLmhhcyhlbGVtZW50LmZpbGVJZCksXG4gICAgKTtcblxuICAgIGlmICh1bmNhY2hlZEltYWdlRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcyB9ID0gYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFxuICAgICAgICB1bmNhY2hlZEltYWdlRWxlbWVudHMsXG4gICAgICAgIGZpbGVzLFxuICAgICAgKTtcbiAgICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSkge1xuICAgICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKiBnZW5lcmFsbHkgeW91IHNob3VsZCB1c2UgYGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpYCBkaXJlY3RseSBpZiB5b3UgbmVlZFxuICAgKiAgdG8gcmVuZGVyIG5ldyBpbWFnZXMuIFRoaXMgaXMganVzdCBhIGZhaWxzYWZlICAqL1xuICBwcml2YXRlIHNjaGVkdWxlSW1hZ2VSZWZyZXNoID0gdGhyb3R0bGUoKCkgPT4ge1xuICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gIH0sIElNQUdFX1JFTkRFUl9USU1FT1VUKTtcblxuICBwcml2YXRlIHVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgY29uc3Qgc2hvdWxkRW5hYmxlQmluZGluZyA9IHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQgIT09IHNob3VsZEVuYWJsZUJpbmRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBzaG91bGRFbmFibGVCaW5kaW5nIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvciA9IChwb2ludGVyQ29vcmRzOiB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgfSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6XG4gICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCA/IFtob3ZlcmVkQmluZGFibGVFbGVtZW50XSA6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMgPSAoXG4gICAgbGluZWFyRWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICAgIHBvaW50ZXJDb29yZHM6IHtcbiAgICAgIHg6IG51bWJlcjtcbiAgICAgIHk6IG51bWJlcjtcbiAgICB9W10sXG4gICAgLy8gRHVyaW5nIGxpbmUgY3JlYXRpb24gdGhlIHN0YXJ0IGJpbmRpbmcgaGFzbid0IGJlZW4gd3JpdHRlbiB5ZXRcbiAgICAvLyBpbnRvIGBsaW5lYXJFbGVtZW50YFxuICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD86IEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQgfCBudWxsLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAoIXBvaW50ZXJDb29yZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBwb2ludGVyQ29vcmRzLnJlZHVjZShcbiAgICAgIChhY2M6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudD5bXSwgY29vcmRzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgY29vcmRzLFxuICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kKFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD8uaWQsXG4gICAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50LFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjLnB1c2goaG92ZXJlZEJpbmRhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgLy8gQ29udGludWUgZWRpdGluZyB0aGUgc2FtZSBncm91cCBpZiB0aGUgdXNlciBzZWxlY3RlZCBhIGRpZmZlcmVudFxuICAgICAgLy8gZWxlbWVudCBmcm9tIGl0XG4gICAgICBlZGl0aW5nR3JvdXBJZDpcbiAgICAgICAgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgIGhpdEVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICBpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZClcbiAgICAgICAgICA/IHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZFxuICAgICAgICAgIDogbnVsbCxcbiAgICB9KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNSZWYgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4ge1xuICAgIC8vIGNhbnZhcyBpcyBudWxsIHdoZW4gdW5tb3VudGluZ1xuICAgIGlmIChjYW52YXMgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgdGhpcy5yYyA9IHJvdWdoLmNhbnZhcyh0aGlzLmNhbnZhcyk7XG5cbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwsIHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsKTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVBcHBPbkRyb3AgPSBhc3luYyAoZXZlbnQ6IFJlYWN0LkRyYWdFdmVudDxIVE1MRGl2RWxlbWVudD4pID0+IHtcbiAgICAvLyBtdXN0IGJlIHJldHJpZXZlZCBmaXJzdCwgaW4gdGhlIHNhbWUgZnJhbWVcbiAgICBjb25zdCB7IGZpbGUsIGZpbGVIYW5kbGUgfSA9IGF3YWl0IGdldEZpbGVGcm9tRXZlbnQoZXZlbnQpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGRlY29kZSBzY2VuZSBmcm9tIHRoZSBpbWFnZSBpZiBpdCdzIGVtYmVkZGVkXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGlmIChmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnBuZyB8fCBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzY2VuZSA9IGF3YWl0IGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJFbmNvZGluZ0Vycm9yXCIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm8gc2NlbmUgaXMgZW1iZWRkZWQgb3Igd2UgZmFpbCBmb3Igd2hhdGV2ZXIgcmVhc29uLCBmYWxsIGJhY2tcbiAgICAgICAgLy8gdG8gaW1wb3J0aW5nIGFzIHJlZ3VsYXIgaW1hZ2VcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsaWJyYXJ5SlNPTiA9IGV2ZW50LmRhdGFUcmFuc2Zlci5nZXREYXRhKE1JTUVfVFlQRVMuZXhjYWxpZHJhd2xpYik7XG4gICAgaWYgKGxpYnJhcnlKU09OICYmIHR5cGVvZiBsaWJyYXJ5SlNPTiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbGlicmFyeUl0ZW1zID0gcGFyc2VMaWJyYXJ5SlNPTihsaWJyYXJ5SlNPTik7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkaXN0cmlidXRlTGlicmFyeUl0ZW1zT25TcXVhcmVHcmlkKGxpYnJhcnlJdGVtcyksXG4gICAgICAgICAgcG9zaXRpb246IGV2ZW50LFxuICAgICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZmlsZSkge1xuICAgICAgLy8gYXRldG1wdCB0byBwYXJzZSBhbiBleGNhbGlkcmF3L2V4Y2FsaWRyYXdsaWIgZmlsZVxuICAgICAgYXdhaXQgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGZpbGUsIGZpbGVIYW5kbGUpO1xuICAgIH1cbiAgfTtcblxuICBsb2FkRmlsZVRvQ2FudmFzID0gYXN5bmMgKFxuICAgIGZpbGU6IEZpbGUsXG4gICAgZmlsZUhhbmRsZTogRmlsZVN5c3RlbUhhbmRsZSB8IG51bGwsXG4gICkgPT4ge1xuICAgIGZpbGUgPSBhd2FpdCBub3JtYWxpemVGaWxlKGZpbGUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXQgPSBhd2FpdCBsb2FkU2NlbmVPckxpYnJhcnlGcm9tQmxvYihcbiAgICAgICAgZmlsZSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZmlsZUhhbmRsZSxcbiAgICAgICk7XG4gICAgICBpZiAocmV0LnR5cGUgPT09IE1JTUVfVFlQRVMuZXhjYWxpZHJhdykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgIC4uLnJldC5kYXRhLFxuICAgICAgICAgIGFwcFN0YXRlOiB7XG4gICAgICAgICAgICAuLi4ocmV0LmRhdGEuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHJldC50eXBlID09PSBNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5saWJyYXJ5XG4gICAgICAgICAgLnVwZGF0ZUxpYnJhcnkoe1xuICAgICAgICAgICAgbGlicmFyeUl0ZW1zOiBmaWxlLFxuICAgICAgICAgICAgbWVyZ2U6IHRydWUsXG4gICAgICAgICAgICBvcGVuTGlicmFyeU1lbnU6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IHQoXCJlcnJvcnMuaW1wb3J0TGlicmFyeUVycm9yXCIpIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAoXG4gICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIiB8fFxuICAgICAgICAoZXZlbnQubmF0aXZlRXZlbnQucG9pbnRlclR5cGUgPT09IFwicGVuXCIgJiZcbiAgICAgICAgICAvLyBhbHdheXMgYWxsb3cgaWYgdXNlciB1c2VzIGEgcGVuIHNlY29uZGFyeSBidXR0b25cbiAgICAgICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLlNFQ09OREFSWSkpICYmXG4gICAgICB0aGlzLnN0YXRlLmFjdGl2ZVRvb2wudHlwZSAhPT0gXCJzZWxlY3Rpb25cIlxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBwcmVmZXJTZWxlY3RlZDogdHJ1ZSxcbiAgICAgIGluY2x1ZGVMb2NrZWRFbGVtZW50czogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHR5cGUgPSBlbGVtZW50ID8gXCJlbGVtZW50XCIgOiBcImNhbnZhc1wiO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhO1xuICAgIGNvbnN0IHsgdG9wOiBvZmZzZXRUb3AsIGxlZnQ6IG9mZnNldExlZnQgfSA9XG4gICAgICBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgbGVmdCA9IGV2ZW50LmNsaWVudFggLSBvZmZzZXRMZWZ0O1xuICAgIGNvbnN0IHRvcCA9IGV2ZW50LmNsaWVudFkgLSBvZmZzZXRUb3A7XG5cbiAgICBpZiAoZWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbZWxlbWVudC5pZF0pIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgIHNlbGVjdGVkTGluZWFyRWxlbWVudDogaXNMaW5lYXJFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgICAgID8gbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoZWxlbWVudCwgdGhpcy5zY2VuZSlcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXROb25EZWxldGVkRWxlbWVudHMoKSxcbiAgICAgICAgKSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZURyYWdOZXdHZW5lcmljRWxlbWVudCA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgdGhpcy5zdGF0ZS5hY3RpdmVUb29sLnR5cGUgIT09IFwiZXJhc2VyXCJcbiAgICApIHtcbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCwgcG9pbnRlckNvb3Jkcy54KSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSwgcG9pbnRlckNvb3Jkcy55KSxcbiAgICAgICAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1hZ2UgPVxuICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkgJiZcbiAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChkcmFnZ2luZ0VsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG4gICAgICBjb25zdCBhc3BlY3RSYXRpbyA9XG4gICAgICAgIGltYWdlICYmICEoaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICAgID8gaW1hZ2Uud2lkdGggLyBpbWFnZS5oZWlnaHRcbiAgICAgICAgICA6IG51bGw7XG5cbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuYWN0aXZlVG9vbC50eXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LFxuICAgICAgICBncmlkWCxcbiAgICAgICAgZ3JpZFksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsIGdyaWRYKSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSwgZ3JpZFkpLFxuICAgICAgICBpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICAgICAgPyAhc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudClcbiAgICAgICAgICA6IHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgYXNwZWN0UmF0aW8sXG4gICAgICApO1xuXG4gICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoW2RyYWdnaW5nRWxlbWVudF0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlSGFuZGxlUmVzaXplID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGU7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAvLyBUT0RPOiByZW5hbWUgdGhpcyBzdGF0ZSBmaWVsZCB0byBcImlzU2NhbGluZ1wiIHRvIGRpc3Rpbmd1aXNoXG4gICAgICAvLyBpdCBmcm9tIHRoZSBnZW5lcmljIFwiaXNSZXNpemluZ1wiIHdoaWNoIGluY2x1ZGVzIHNjYWxpbmcgYW5kXG4gICAgICAvLyByb3RhdGluZ1xuICAgICAgaXNSZXNpemluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSAmJiB0cmFuc2Zvcm1IYW5kbGVUeXBlICE9PSBcInJvdGF0aW9uXCIsXG4gICAgICBpc1JvdGF0aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlID09PSBcInJvdGF0aW9uXCIsXG4gICAgfSk7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBjb25zdCBbcmVzaXplWCwgcmVzaXplWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueCxcbiAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgIHRyYW5zZm9ybUVsZW1lbnRzKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbixcbiAgICAgICAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNJbWFnZUVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHJlc2l6ZVgsXG4gICAgICAgIHJlc2l6ZVksXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqIEBwcml2YXRlIHVzZSB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51ICovXG4gIHByaXZhdGUgX29wZW5Db250ZXh0TWVudSA9IChcbiAgICB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wLFxuICAgIH06IHtcbiAgICAgIGxlZnQ6IG51bWJlcjtcbiAgICAgIHRvcDogbnVtYmVyO1xuICAgIH0sXG4gICAgdHlwZTogXCJjYW52YXNcIiB8IFwiZWxlbWVudFwiLFxuICApID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5zaG93SHlwZXJsaW5rUG9wdXApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93SHlwZXJsaW5rUG9wdXA6IGZhbHNlIH0pO1xuICAgIH1cbiAgICB0aGlzLmNvbnRleHRNZW51T3BlbiA9IHRydWU7XG4gICAgY29uc3QgbWF5YmVHcm91cEFjdGlvbiA9IGFjdGlvbkdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZVVuZ3JvdXBBY3Rpb24gPSBhY3Rpb25Vbmdyb3VwLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZUZsaXBIb3Jpem9udGFsID0gYWN0aW9uRmxpcEhvcml6b250YWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcFZlcnRpY2FsID0gYWN0aW9uRmxpcFZlcnRpY2FsLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXlCZUFsbG93VW5iaW5kaW5nID0gYWN0aW9uVW5iaW5kVGV4dC5jb250ZXh0SXRlbVByZWRpY2F0ZShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXlCZUFsbG93QmluZGluZyA9IGFjdGlvbkJpbmRUZXh0LmNvbnRleHRJdGVtUHJlZGljYXRlKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IHNlcGFyYXRvciA9IFwic2VwYXJhdG9yXCI7XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0Tm9uRGVsZXRlZEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBvcHRpb25zOiBDb250ZXh0TWVudU9wdGlvbltdID0gW107XG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNQbmcpO1xuICAgIH1cblxuICAgIGlmIChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIG9wdGlvbnMucHVzaChhY3Rpb25Db3B5QXNTdmcpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHR5cGUgPT09IFwiZWxlbWVudFwiICYmXG4gICAgICBjb3B5VGV4dC5jb250ZXh0SXRlbVByZWRpY2F0ZShlbGVtZW50cywgdGhpcy5zdGF0ZSkgJiZcbiAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHRcbiAgICApIHtcbiAgICAgIG9wdGlvbnMucHVzaChjb3B5VGV4dCk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSBcImNhbnZhc1wiKSB7XG4gICAgICBjb25zdCB2aWV3TW9kZU9wdGlvbnMgPSBbXG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gICAgICBdO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogdmlld01vZGVPcHRpb25zLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICB0cmFja0V2ZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUgJiYgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1BuZyxcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiZcbiAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBhY3Rpb25Db3B5QXNTdmcsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBjb3B5VGV4dCxcbiAgICAgICAgICAgICgocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkgfHxcbiAgICAgICAgICAgICAgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkpICYmXG4gICAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbGVjdEFsbCxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVHcmlkTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlVmlld01vZGUsXG4gICAgICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImVsZW1lbnRcIikge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksIC4uLm9wdGlvbnNdLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBhY3Rpb25DdXQsXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksXG4gICAgICAgICAgICB0aGlzLmRldmljZS5pc01vYmlsZSAmJlxuICAgICAgICAgICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInBhc3RlXCIsXG4gICAgICAgICAgICAgICAgdHJhY2tFdmVudDogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGVyZm9ybTogKGVsZW1lbnRzLCBhcHBTdGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKG51bGwpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZXh0SXRlbUxhYmVsOiBcImxhYmVscy5wYXN0ZVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5kZXZpY2UuaXNNb2JpbGUgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkNvcHlTdHlsZXMsXG4gICAgICAgICAgICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIG1heWJlR3JvdXBBY3Rpb24gJiYgYWN0aW9uR3JvdXAsXG4gICAgICAgICAgICBtYXlCZUFsbG93VW5iaW5kaW5nICYmIGFjdGlvblVuYmluZFRleHQsXG4gICAgICAgICAgICBtYXlCZUFsbG93QmluZGluZyAmJiBhY3Rpb25CaW5kVGV4dCxcbiAgICAgICAgICAgIG1heWJlVW5ncm91cEFjdGlvbiAmJiBhY3Rpb25Vbmdyb3VwLFxuICAgICAgICAgICAgKG1heWJlR3JvdXBBY3Rpb24gfHwgbWF5YmVVbmdyb3VwQWN0aW9uKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gICAgICAgICAgICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gICAgICAgICAgICBhY3Rpb25TZW5kVG9CYWNrLFxuICAgICAgICAgICAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgbWF5YmVGbGlwSG9yaXpvbnRhbCAmJiBhY3Rpb25GbGlwSG9yaXpvbnRhbCxcbiAgICAgICAgICAgIG1heWJlRmxpcFZlcnRpY2FsICYmIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgICAgICAgICAgIChtYXliZUZsaXBIb3Jpem9udGFsIHx8IG1heWJlRmxpcFZlcnRpY2FsKSAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25MaW5rLmNvbnRleHRJdGVtUHJlZGljYXRlKGVsZW1lbnRzLCB0aGlzLnN0YXRlKSAmJiBhY3Rpb25MaW5rLFxuICAgICAgICAgICAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICAgICAgICAgICAgYWN0aW9uVG9nZ2xlTG9jayxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVXaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlbHRhWCwgZGVsdGFZIH0gPSBldmVudDtcbiAgICAvLyBub3RlIHRoYXQgZXZlbnQuY3RybEtleSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIHBpbmNoIHpvb21pbmdcbiAgICBpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5KSB7XG4gICAgICBjb25zdCBzaWduID0gTWF0aC5zaWduKGRlbHRhWSk7XG4gICAgICBjb25zdCBNQVhfU1RFUCA9IDEwO1xuICAgICAgY29uc3QgYWJzRGVsdGEgPSBNYXRoLmFicyhkZWx0YVkpO1xuICAgICAgbGV0IGRlbHRhID0gZGVsdGFZO1xuICAgICAgaWYgKGFic0RlbHRhID4gTUFYX1NURVApIHtcbiAgICAgICAgZGVsdGEgPSBNQVhfU1RFUCAqIHNpZ247XG4gICAgICB9XG5cbiAgICAgIGxldCBuZXdab29tID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlIC0gZGVsdGEgLyAxMDA7XG4gICAgICAvLyBpbmNyZWFzZSB6b29tIHN0ZXBzIHRoZSBtb3JlIHpvb21lZC1pbiB3ZSBhcmUgKGFwcGxpZXMgdG8gPjEwMCUgb25seSlcbiAgICAgIG5ld1pvb20gKz1cbiAgICAgICAgTWF0aC5sb2cxMChNYXRoLm1heCgxLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSAqXG4gICAgICAgIC1zaWduICpcbiAgICAgICAgLy8gcmVkdWNlZCBhbXBsaWZpY2F0aW9uIGZvciBzbWFsbCBkZWx0YXMgKHNtYWxsIG1vdmVtZW50cyBvbiBhIHRyYWNrcGFkKVxuICAgICAgICBNYXRoLm1pbigxLCBhYnNEZWx0YSAvIDIwKTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldFN0YXRlRm9yWm9vbShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2aWV3cG9ydFg6IGN1cnNvclgsXG4gICAgICAgICAgICB2aWV3cG9ydFk6IGN1cnNvclksXG4gICAgICAgICAgICBuZXh0Wm9vbTogZ2V0Tm9ybWFsaXplZFpvb20obmV3Wm9vbSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgKSxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgd2hlbiBzaGlmdCBwcmVzc2VkXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIHNjcm9sbFggfSkgPT4gKHtcbiAgICAgICAgLy8gb24gTWFjLCBzaGlmdCt3aGVlbCB0ZW5kcyB0byByZXN1bHQgaW4gZGVsdGFYXG4gICAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSAoZGVsdGFZIHx8IGRlbHRhWCkgLyB6b29tLnZhbHVlLFxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCwgc2Nyb2xsWSB9KSA9PiAoe1xuICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIGRlbHRhWCAvIHpvb20udmFsdWUsXG4gICAgICBzY3JvbGxZOiBzY3JvbGxZIC0gZGVsdGFZIC8gem9vbS52YWx1ZSxcbiAgICB9KSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCxcbiAgICBzY2FsZTogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBlbGVtZW50Q2xpY2tlZEluc2lkZSA9IGdldFRleHRCaW5kYWJsZUNvbnRhaW5lckF0UG9zaXRpb24oXG4gICAgICB0aGlzLnNjZW5lXG4gICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAuZmlsdGVyKChlbGVtZW50KSA9PiAhaXNUZXh0RWxlbWVudChlbGVtZW50KSksXG4gICAgICB4LFxuICAgICAgeSxcbiAgICApO1xuICAgIGlmIChlbGVtZW50Q2xpY2tlZEluc2lkZSkge1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclggPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS54ICsgZWxlbWVudENsaWNrZWRJbnNpZGUud2lkdGggLyAyO1xuICAgICAgY29uc3QgZWxlbWVudENlbnRlclkgPVxuICAgICAgICBlbGVtZW50Q2xpY2tlZEluc2lkZS55ICsgZWxlbWVudENsaWNrZWRJbnNpZGUuaGVpZ2h0IC8gMjtcbiAgICAgIGNvbnN0IGRpc3RhbmNlVG9DZW50ZXIgPSBNYXRoLmh5cG90KFxuICAgICAgICB4IC0gZWxlbWVudENlbnRlclgsXG4gICAgICAgIHkgLSBlbGVtZW50Q2VudGVyWSxcbiAgICAgICk7XG4gICAgICBjb25zdCBpc1NuYXBwZWRUb0NlbnRlciA9XG4gICAgICAgIGRpc3RhbmNlVG9DZW50ZXIgPCBURVhUX1RPX0NFTlRFUl9TTkFQX1RIUkVTSE9MRDtcbiAgICAgIGlmIChpc1NuYXBwZWRUb0NlbnRlcikge1xuICAgICAgICBjb25zdCB7IHg6IHZpZXdwb3J0WCwgeTogdmlld3BvcnRZIH0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgICAgeyBzY2VuZVg6IGVsZW1lbnRDZW50ZXJYLCBzY2VuZVk6IGVsZW1lbnRDZW50ZXJZIH0sXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IHZpZXdwb3J0WCwgdmlld3BvcnRZLCBlbGVtZW50Q2VudGVyWCwgZWxlbWVudENlbnRlclkgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNhdmVQb2ludGVyID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBidXR0b246IFwidXBcIiB8IFwiZG93blwiKSA9PiB7XG4gICAgaWYgKCF4IHx8ICF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBvaW50ZXIgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IHgsIGNsaWVudFk6IHkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChpc05hTihwb2ludGVyLngpIHx8IGlzTmFOKHBvaW50ZXIueSkpIHtcbiAgICAgIC8vIHNvbWV0aW1lcyB0aGUgcG9pbnRlciBnb2VzIG9mZiBzY3JlZW5cbiAgICB9XG5cbiAgICB0aGlzLnByb3BzLm9uUG9pbnRlclVwZGF0ZT8uKHtcbiAgICAgIHBvaW50ZXIsXG4gICAgICBidXR0b24sXG4gICAgICBwb2ludGVyc01hcDogZ2VzdHVyZS5wb2ludGVycyxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGlmICghdGhpcy51bm1vdW50ZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlIH0pO1xuICAgIH1cbiAgfSwgMzAwKTtcblxuICBwcml2YXRlIHVwZGF0ZURPTVJlY3QgPSAoY2I/OiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0LFxuICAgICAgICB0b3A6IG9mZnNldFRvcCxcbiAgICAgIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qge1xuICAgICAgICB3aWR0aDogY3VycmVudFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGN1cnJlbnRIZWlnaHQsXG4gICAgICAgIG9mZnNldFRvcDogY3VycmVudE9mZnNldFRvcCxcbiAgICAgICAgb2Zmc2V0TGVmdDogY3VycmVudE9mZnNldExlZnQsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgaWYgKFxuICAgICAgICB3aWR0aCA9PT0gY3VycmVudFdpZHRoICYmXG4gICAgICAgIGhlaWdodCA9PT0gY3VycmVudEhlaWdodCAmJlxuICAgICAgICBvZmZzZXRMZWZ0ID09PSBjdXJyZW50T2Zmc2V0TGVmdCAmJlxuICAgICAgICBvZmZzZXRUb3AgPT09IGN1cnJlbnRPZmZzZXRUb3BcbiAgICAgICkge1xuICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICBjYigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICBvZmZzZXRMZWZ0LFxuICAgICAgICAgIG9mZnNldFRvcCxcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNiICYmIGNiKCk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgcmVmcmVzaCA9ICgpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCkgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRDYW52YXNPZmZzZXRzKCk6IFBpY2s8QXBwU3RhdGUsIFwib2Zmc2V0VG9wXCIgfCBcIm9mZnNldExlZnRcIj4ge1xuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGV4Y2FsaWRyYXdDb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBleGNhbGlkcmF3Q29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2Zmc2V0TGVmdDogbGVmdCxcbiAgICAgICAgb2Zmc2V0VG9wOiB0b3AsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0TGVmdDogMCxcbiAgICAgIG9mZnNldFRvcDogMCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVMYW5ndWFnZSgpIHtcbiAgICBjb25zdCBjdXJyZW50TGFuZyA9XG4gICAgICBsYW5ndWFnZXMuZmluZCgobGFuZykgPT4gbGFuZy5jb2RlID09PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB8fFxuICAgICAgZGVmYXVsdExhbmc7XG4gICAgYXdhaXQgc2V0TGFuZ3VhZ2UoY3VycmVudExhbmcpO1xuICAgIHRoaXMuc2V0QXBwU3RhdGUoe30pO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBURVNUIEhPT0tTXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBXaW5kb3cge1xuICAgIGg6IHtcbiAgICAgIGVsZW1lbnRzOiByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdO1xuICAgICAgc3RhdGU6IEFwcFN0YXRlO1xuICAgICAgc2V0U3RhdGU6IFJlYWN0LkNvbXBvbmVudDxhbnksIEFwcFN0YXRlPltcInNldFN0YXRlXCJdO1xuICAgICAgYXBwOiBJbnN0YW5jZVR5cGU8dHlwZW9mIEFwcD47XG4gICAgICBoaXN0b3J5OiBIaXN0b3J5O1xuICAgIH07XG4gIH1cbn1cblxuaWYgKFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5ERVZFTE9QTUVOVCB8fFxuICBwcm9jZXNzLmVudi5SRUFDVF9BUFBfVkVSQ0VMX0VOViA9PT0gXCJwcmV2aWV3XCJcbikge1xuICB3aW5kb3cuaCA9IHdpbmRvdy5oIHx8ICh7fSBhcyBXaW5kb3dbXCJoXCJdKTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3cuaCwge1xuICAgIGVsZW1lbnRzOiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcD8uc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICB9LFxuICAgICAgc2V0KGVsZW1lbnRzOiBFeGNhbGlkcmF3RWxlbWVudFtdKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcD8uc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKGVsZW1lbnRzKTtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFwcDtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
2121
2121
 
2122
2122
  /***/ }),
2123
2123
 
@@ -3151,7 +3151,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3151
3151
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3152
3152
 
3153
3153
  "use strict";
3154
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n /* global __webpack_public_path__:writable */\n __webpack_require__.p =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@excalidraw/excalidraw\"}@${\"0.12.0-5598-9f325a6\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLHdCQUFvQixJQUFJLHFCQUF1QixRQUFRLENBQUM7Q0FDaEYiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWNQYXRoLmpzP2E4N2QiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5WIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBFTlYuVEVTVCkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAvKiBnbG9iYWwgX193ZWJwYWNrX3B1YmxpY19wYXRoX186d3JpdGFibGUgKi9cbiAgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPVxuICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICBgaHR0cHM6Ly91bnBrZy5jb20vJHtwcm9jZXNzLmVudi5QS0dfTkFNRX1AJHtwcm9jZXNzLmVudi5QS0dfVkVSU0lPTn0vZGlzdC9gO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./publicPath.js\n");
3154
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../constants */ \"../../constants.ts\");\n\nif (\"development\" !== _constants__WEBPACK_IMPORTED_MODULE_0__.ENV.TEST) {\n /* eslint-disable */\n /* global __webpack_public_path__:writable */\n __webpack_require__.p =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@excalidraw/excalidraw\"}@${\"0.12.0-5598-d731a64\"}/dist/`;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9wdWJsaWNQYXRoLmpzLmpzIiwibWFwcGluZ3MiOiI7O0FBQXNDO0FBQ3RDLElBQUksYUFBb0IsS0FBSyxnREFBUSxFQUFFO0lBQ3JDLG9CQUFvQjtJQUNwQiw2Q0FBNkM7SUFDN0MscUJBQXVCO1FBQ3JCLE1BQU0sQ0FBQyxxQkFBcUI7WUFDNUIscUJBQXFCLHdCQUFvQixJQUFJLHFCQUF1QixRQUFRLENBQUM7Q0FDaEYiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWNQYXRoLmpzP2E4N2QiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5WIH0gZnJvbSBcIi4uLy4uL2NvbnN0YW50c1wiO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBFTlYuVEVTVCkge1xuICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAvKiBnbG9iYWwgX193ZWJwYWNrX3B1YmxpY19wYXRoX186d3JpdGFibGUgKi9cbiAgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPVxuICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICBgaHR0cHM6Ly91bnBrZy5jb20vJHtwcm9jZXNzLmVudi5QS0dfTkFNRX1AJHtwcm9jZXNzLmVudi5QS0dfVkVSU0lPTn0vZGlzdC9gO1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./publicPath.js\n");
3155
3155
 
3156
3156
  /***/ }),
3157
3157
 
@@ -3261,7 +3261,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3261
3261
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3262
3262
 
3263
3263
  "use strict";
3264
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SVG_EXPORT_TAG\": () => (/* binding */ SVG_EXPORT_TAG),\n/* harmony export */ \"exportToCanvas\": () => (/* binding */ exportToCanvas),\n/* harmony export */ \"exportToSvg\": () => (/* binding */ exportToSvg),\n/* harmony export */ \"getExportSize\": () => (/* binding */ getExportSize)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\nconst SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;\nconst exportToCanvas = (elements, appState, files, { exportBackground, exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, }, createCanvas = (width, height) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width * appState.exportScale;\n canvas.height = height * appState.exportScale;\n return { canvas, scale: appState.exportScale };\n}) => __awaiter(void 0, void 0, void 0, function* () {\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n const { canvas, scale = 1 } = createCanvas(width, height);\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_5__.getDefaultAppState)();\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files,\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)({\n elements,\n appState,\n scale,\n rc: roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas),\n canvas,\n renderConfig: {\n viewBackgroundColor: exportBackground ? viewBackgroundColor : null,\n scrollX: -minX + exportPadding,\n scrollY: -minY + exportPadding,\n zoom: defaultAppState.zoom,\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: appState.exportWithDarkMode ? \"dark\" : \"light\",\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n },\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files) => __awaiter(void 0, void 0, void 0, function* () {\n const { exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, exportScale = 1, exportEmbedScene, } = appState;\n let metadata = \"\";\n if (exportEmbedScene) {\n try {\n metadata = yield (yield Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../../src/data/image */ \"../../data/image.ts\"))).encodeSvgMetadata({\n text: (0,_data_json__WEBPACK_IMPORTED_MODULE_6__.serializeAsJSON)(elements, appState, files || {}, \"local\"),\n });\n }\n catch (error) {\n console.error(error);\n }\n }\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n // initialize SVG root\n const svgRoot = document.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"svg\");\n svgRoot.setAttribute(\"version\", \"1.1\");\n svgRoot.setAttribute(\"xmlns\", _constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS);\n svgRoot.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svgRoot.setAttribute(\"width\", `${width * exportScale}`);\n svgRoot.setAttribute(\"height\", `${height * exportScale}`);\n if (appState.exportWithDarkMode) {\n svgRoot.setAttribute(\"filter\", _constants__WEBPACK_IMPORTED_MODULE_4__.THEME_FILTER);\n }\n let assetPath = \"https://excalidraw.com/\";\n // Asset path needs to be determined only when using package\n if (true) {\n assetPath =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@excalidraw/excalidraw\"}@${\"0.12.0-5598-9f325a6\"}`;\n if (assetPath === null || assetPath === void 0 ? void 0 : assetPath.startsWith(\"/\")) {\n assetPath = assetPath.replace(\"/\", `${window.location.origin}/`);\n }\n assetPath = `${assetPath}/dist/excalidraw-assets/`;\n }\n svgRoot.innerHTML = `\n ${SVG_EXPORT_TAG}\n ${metadata}\n <defs>\n <style>\n @font-face {\n font-family: \"Virgil\";\n src: url(\"${assetPath}Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"${assetPath}Cascadia.woff2\");\n }\n </style>\n </defs>\n `;\n // render background rect\n if (appState.exportBackground && viewBackgroundColor) {\n const rect = svgRoot.ownerDocument.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", `${width}`);\n rect.setAttribute(\"height\", `${height}`);\n rect.setAttribute(\"fill\", viewBackgroundColor);\n svgRoot.appendChild(rect);\n }\n const rsvg = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].svg(svgRoot);\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderSceneToSvg)(elements, rsvg, svgRoot, files || {}, {\n offsetX: -minX + exportPadding,\n offsetY: -minY + exportPadding,\n exportWithDarkMode: appState.exportWithDarkMode,\n });\n return svgRoot;\n});\n// calculate smallest area to fit the contents in\nconst getCanvasSize = (elements, exportPadding) => {\n const [minX, minY, maxX, maxY] = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n const width = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minX, maxX) + exportPadding * 2;\n const height = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minY, maxY) + exportPadding + exportPadding;\n return [minX, minY, width, height];\n};\nconst getExportSize = (elements, exportPadding, scale) => {\n const [, , width, height] = getCanvasSize(elements, exportPadding).map((dimension) => Math.trunc(dimension * scale));\n return [width, height];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vc2NlbmUvZXhwb3J0LnRzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFzQztBQUVjO0FBQ29CO0FBQ3BDO0FBRXdDO0FBQzNCO0FBQ0Y7QUFJckI7QUFFbkIsTUFBTSxjQUFjLEdBQUcsZ0NBQWdDLENBQUM7QUFFeEQsTUFBTSxjQUFjLEdBQUcsQ0FDNUIsUUFBZ0QsRUFDaEQsUUFBa0IsRUFDbEIsS0FBa0IsRUFDbEIsRUFDRSxnQkFBZ0IsRUFDaEIsYUFBYSxHQUFHLDhEQUFzQixFQUN0QyxtQkFBbUIsR0FLcEIsRUFDRCxlQUdvRCxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRTtJQUNwRSxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7SUFDNUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQztJQUM5QyxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDakQsQ0FBQyxFQUNELEVBQUU7SUFDRixNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUUzRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRTFELE1BQU0sZUFBZSxHQUFHLDZEQUFrQixFQUFFLENBQUM7SUFFN0MsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sZ0VBQWdCLENBQUM7UUFDNUMsVUFBVSxFQUFFLElBQUksR0FBRyxFQUFFO1FBQ3JCLE9BQU8sRUFBRSwyRUFBMkIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQ2hELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUM1QjtRQUNELEtBQUs7S0FDTixDQUFDLENBQUM7SUFFSCxrRUFBVyxDQUFDO1FBQ1YsUUFBUTtRQUNSLFFBQVE7UUFDUixLQUFLO1FBQ0wsRUFBRSxFQUFFLGdFQUFZLENBQUMsTUFBTSxDQUFDO1FBQ3hCLE1BQU07UUFDTixZQUFZLEVBQUU7WUFDWixtQkFBbUIsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDbEUsT0FBTyxFQUFFLENBQUMsSUFBSSxHQUFHLGFBQWE7WUFDOUIsT0FBTyxFQUFFLENBQUMsSUFBSSxHQUFHLGFBQWE7WUFDOUIsSUFBSSxFQUFFLGVBQWUsQ0FBQyxJQUFJO1lBQzFCLDJCQUEyQixFQUFFLEVBQUU7WUFDL0Isd0JBQXdCLEVBQUUsRUFBRTtZQUM1QixxQkFBcUIsRUFBRSxLQUFLO1lBQzVCLHNCQUFzQixFQUFFLEVBQUU7WUFDMUIsdUJBQXVCLEVBQUUsRUFBRTtZQUMzQixLQUFLLEVBQUUsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU87WUFDckQsVUFBVTtZQUNWLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsZUFBZSxFQUFFLEtBQUs7WUFDdEIsVUFBVSxFQUFFLEtBQUs7WUFDakIsV0FBVyxFQUFFLElBQUk7U0FDbEI7S0FDRixDQUFDLENBQUM7SUFFSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDLEVBQUM7QUFFSyxNQUFNLFdBQVcsR0FBRyxDQUN6QixRQUFnRCxFQUNoRCxRQU9DLEVBQ0QsS0FBeUIsRUFDRCxFQUFFO0lBQzFCLE1BQU0sRUFDSixhQUFhLEdBQUcsOERBQXNCLEVBQ3RDLG1CQUFtQixFQUNuQixXQUFXLEdBQUcsQ0FBQyxFQUNmLGdCQUFnQixHQUNqQixHQUFHLFFBQVEsQ0FBQztJQUNiLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNsQixJQUFJLGdCQUFnQixFQUFFO1FBQ3BCLElBQUk7WUFDRixRQUFRLEdBQUcsTUFBTSxDQUNmLE1BQU0sdUlBQThELENBQ3JFLENBQUMsaUJBQWlCLENBQUM7Z0JBQ2xCLElBQUksRUFBRSwyREFBZSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxJQUFJLEVBQUUsRUFBRSxPQUFPLENBQUM7YUFDaEUsQ0FBQyxDQUFDO1NBQ0o7UUFBQyxPQUFPLEtBQVUsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3RCO0tBQ0Y7SUFDRCxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUUzRSxzQkFBc0I7SUFDdEIsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyw4Q0FBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hELE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLDhDQUFNLENBQUMsQ0FBQztJQUN0QyxPQUFPLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxPQUFPLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFELE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsS0FBSyxHQUFHLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDeEQsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsR0FBRyxNQUFNLEdBQUcsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUMxRCxJQUFJLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvQixPQUFPLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxvREFBWSxDQUFDLENBQUM7S0FDOUM7SUFFRCxJQUFJLFNBQVMsR0FBRyx5QkFBeUIsQ0FBQztJQUUxQyw0REFBNEQ7SUFDNUQsSUFBSSxJQUFxQyxFQUFFO1FBQ3pDLFNBQVM7WUFDUCxNQUFNLENBQUMscUJBQXFCO2dCQUM1QixxQkFBcUIsd0JBQW9CLElBQUkscUJBQXVCLEVBQUUsQ0FBQztRQUV6RSxJQUFJLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDOUIsU0FBUyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1NBQ2xFO1FBQ0QsU0FBUyxHQUFHLEdBQUcsU0FBUywwQkFBMEIsQ0FBQztLQUNwRDtJQUNELE9BQU8sQ0FBQyxTQUFTLEdBQUc7SUFDbEIsY0FBYztJQUNkLFFBQVE7Ozs7O29CQUtRLFNBQVM7Ozs7b0JBSVQsU0FBUzs7OztHQUkxQixDQUFDO0lBQ0YseUJBQXlCO0lBQ3pCLElBQUksUUFBUSxDQUFDLGdCQUFnQixJQUFJLG1CQUFtQixFQUFFO1FBQ3BELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxhQUFjLENBQUMsZUFBZSxDQUFDLDhDQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDM0I7SUFFRCxNQUFNLElBQUksR0FBRyw2REFBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLHVFQUFnQixDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFLEVBQUU7UUFDckQsT0FBTyxFQUFFLENBQUMsSUFBSSxHQUFHLGFBQWE7UUFDOUIsT0FBTyxFQUFFLENBQUMsSUFBSSxHQUFHLGFBQWE7UUFDOUIsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLGtCQUFrQjtLQUNoRCxDQUFDLENBQUM7SUFFSCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDLEVBQUM7QUFFRixpREFBaUQ7QUFDakQsTUFBTSxhQUFhLEdBQUcsQ0FDcEIsUUFBZ0QsRUFDaEQsYUFBcUIsRUFDYSxFQUFFO0lBQ3BDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxnRUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzNELE1BQU0sS0FBSyxHQUFHLGdEQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFDdkQsTUFBTSxNQUFNLEdBQUcsZ0RBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsYUFBYSxHQUFHLGFBQWEsQ0FBQztJQUVwRSxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDckMsQ0FBQyxDQUFDO0FBRUssTUFBTSxhQUFhLEdBQUcsQ0FDM0IsUUFBZ0QsRUFDaEQsYUFBcUIsRUFDckIsS0FBYSxFQUNLLEVBQUU7SUFDcEIsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQ3BFLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FDN0MsQ0FBQztJQUVGLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDekIsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3NjZW5lL2V4cG9ydC50cz85YmY3Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByb3VnaCBmcm9tIFwicm91Z2hqcy9iaW4vcm91Z2hcIjtcbmltcG9ydCB7IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDb21tb25Cb3VuZHMgfSBmcm9tIFwiLi4vZWxlbWVudC9ib3VuZHNcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lLCByZW5kZXJTY2VuZVRvU3ZnIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUsIEJpbmFyeUZpbGVzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VYUE9SVF9QQURESU5HLCBTVkdfTlMsIFRIRU1FX0ZJTFRFUiB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSB9IGZyb20gXCIuLi9hcHBTdGF0ZVwiO1xuaW1wb3J0IHsgc2VyaWFsaXplQXNKU09OIH0gZnJvbSBcIi4uL2RhdGEvanNvblwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICB1cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuXG5leHBvcnQgY29uc3QgU1ZHX0VYUE9SVF9UQUcgPSBgPCEtLSBzdmctc291cmNlOmV4Y2FsaWRyYXcgLS0+YDtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvQ2FudmFzID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgZmlsZXM6IEJpbmFyeUZpbGVzLFxuICB7XG4gICAgZXhwb3J0QmFja2dyb3VuZCxcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICB9OiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgfSxcbiAgY3JlYXRlQ2FudmFzOiAoXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgKSA9PiB7IGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7IHNjYWxlOiBudW1iZXIgfSA9ICh3aWR0aCwgaGVpZ2h0KSA9PiB7XG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjYW52YXMud2lkdGggPSB3aWR0aCAqIGFwcFN0YXRlLmV4cG9ydFNjYWxlO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQgKiBhcHBTdGF0ZS5leHBvcnRTY2FsZTtcbiAgICByZXR1cm4geyBjYW52YXMsIHNjYWxlOiBhcHBTdGF0ZS5leHBvcnRTY2FsZSB9O1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpO1xuXG4gIGNvbnN0IHsgY2FudmFzLCBzY2FsZSA9IDEgfSA9IGNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KTtcblxuICBjb25zdCBkZWZhdWx0QXBwU3RhdGUgPSBnZXREZWZhdWx0QXBwU3RhdGUoKTtcblxuICBjb25zdCB7IGltYWdlQ2FjaGUgfSA9IGF3YWl0IHVwZGF0ZUltYWdlQ2FjaGUoe1xuICAgIGltYWdlQ2FjaGU6IG5ldyBNYXAoKSxcbiAgICBmaWxlSWRzOiBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoZWxlbWVudHMpLm1hcChcbiAgICAgIChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCxcbiAgICApLFxuICAgIGZpbGVzLFxuICB9KTtcblxuICByZW5kZXJTY2VuZSh7XG4gICAgZWxlbWVudHMsXG4gICAgYXBwU3RhdGUsXG4gICAgc2NhbGUsXG4gICAgcmM6IHJvdWdoLmNhbnZhcyhjYW52YXMpLFxuICAgIGNhbnZhcyxcbiAgICByZW5kZXJDb25maWc6IHtcbiAgICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IGV4cG9ydEJhY2tncm91bmQgPyB2aWV3QmFja2dyb3VuZENvbG9yIDogbnVsbCxcbiAgICAgIHNjcm9sbFg6IC1taW5YICsgZXhwb3J0UGFkZGluZyxcbiAgICAgIHNjcm9sbFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICAgIHpvb206IGRlZmF1bHRBcHBTdGF0ZS56b29tLFxuICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiB7fSxcbiAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlLFxuICAgICAgcmVtb3RlUG9pbnRlclVzZXJuYW1lczoge30sXG4gICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczoge30sXG4gICAgICB0aGVtZTogYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlID8gXCJkYXJrXCIgOiBcImxpZ2h0XCIsXG4gICAgICBpbWFnZUNhY2hlLFxuICAgICAgcmVuZGVyU2Nyb2xsYmFyczogZmFsc2UsXG4gICAgICByZW5kZXJTZWxlY3Rpb246IGZhbHNlLFxuICAgICAgcmVuZGVyR3JpZDogZmFsc2UsXG4gICAgICBpc0V4cG9ydGluZzogdHJ1ZSxcbiAgICB9LFxuICB9KTtcblxuICByZXR1cm4gY2FudmFzO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvU3ZnID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIGV4cG9ydFNjYWxlPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgICBleHBvcnRXaXRoRGFya01vZGU/OiBib29sZWFuO1xuICAgIGV4cG9ydEVtYmVkU2NlbmU/OiBib29sZWFuO1xuICB9LFxuICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsLFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBzZXJpYWxpemVBc0pTT04oZWxlbWVudHMsIGFwcFN0YXRlLCBmaWxlcyB8fCB7fSwgXCJsb2NhbFwiKSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICAvLyBpbml0aWFsaXplIFNWRyByb290XG4gIGNvbnN0IHN2Z1Jvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCBcInN2Z1wiKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2ZXJzaW9uXCIsIFwiMS4xXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInhtbG5zXCIsIFNWR19OUyk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwidmlld0JveFwiLCBgMCAwICR7d2lkdGh9ICR7aGVpZ2h0fWApO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRoICogZXhwb3J0U2NhbGV9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodCAqIGV4cG9ydFNjYWxlfWApO1xuICBpZiAoYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlKSB7XG4gICAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJmaWx0ZXJcIiwgVEhFTUVfRklMVEVSKTtcbiAgfVxuXG4gIGxldCBhc3NldFBhdGggPSBcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vXCI7XG5cbiAgLy8gQXNzZXQgcGF0aCBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIG9ubHkgd2hlbiB1c2luZyBwYWNrYWdlXG4gIGlmIChwcm9jZXNzLmVudi5JU19FWENBTElEUkFXX05QTV9QQUNLQUdFKSB7XG4gICAgYXNzZXRQYXRoID1cbiAgICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfWA7XG5cbiAgICBpZiAoYXNzZXRQYXRoPy5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgYXNzZXRQYXRoID0gYXNzZXRQYXRoLnJlcGxhY2UoXCIvXCIsIGAke3dpbmRvdy5sb2NhdGlvbi5vcmlnaW59L2ApO1xuICAgIH1cbiAgICBhc3NldFBhdGggPSBgJHthc3NldFBhdGh9L2Rpc3QvZXhjYWxpZHJhdy1hc3NldHMvYDtcbiAgfVxuICBzdmdSb290LmlubmVySFRNTCA9IGBcbiAgJHtTVkdfRVhQT1JUX1RBR31cbiAgJHttZXRhZGF0YX1cbiAgPGRlZnM+XG4gICAgPHN0eWxlPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofVZpcmdpbC53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICAgIEBmb250LWZhY2Uge1xuICAgICAgICBmb250LWZhbWlseTogXCJDYXNjYWRpYVwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofUNhc2NhZGlhLndvZmYyXCIpO1xuICAgICAgfVxuICAgIDwvc3R5bGU+XG4gIDwvZGVmcz5cbiAgYDtcbiAgLy8gcmVuZGVyIGJhY2tncm91bmQgcmVjdFxuICBpZiAoYXBwU3RhdGUuZXhwb3J0QmFja2dyb3VuZCAmJiB2aWV3QmFja2dyb3VuZENvbG9yKSB7XG4gICAgY29uc3QgcmVjdCA9IHN2Z1Jvb3Qub3duZXJEb2N1bWVudCEuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgXCJyZWN0XCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofWApO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdmlld0JhY2tncm91bmRDb2xvcik7XG4gICAgc3ZnUm9vdC5hcHBlbmRDaGlsZChyZWN0KTtcbiAgfVxuXG4gIGNvbnN0IHJzdmcgPSByb3VnaC5zdmcoc3ZnUm9vdCk7XG4gIHJlbmRlclNjZW5lVG9TdmcoZWxlbWVudHMsIHJzdmcsIHN2Z1Jvb3QsIGZpbGVzIHx8IHt9LCB7XG4gICAgb2Zmc2V0WDogLW1pblggKyBleHBvcnRQYWRkaW5nLFxuICAgIG9mZnNldFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICBleHBvcnRXaXRoRGFya01vZGU6IGFwcFN0YXRlLmV4cG9ydFdpdGhEYXJrTW9kZSxcbiAgfSk7XG5cbiAgcmV0dXJuIHN2Z1Jvb3Q7XG59O1xuXG4vLyBjYWxjdWxhdGUgc21hbGxlc3QgYXJlYSB0byBmaXQgdGhlIGNvbnRlbnRzIGluXG5jb25zdCBnZXRDYW52YXNTaXplID0gKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGV4cG9ydFBhZGRpbmc6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcbiAgY29uc3Qgd2lkdGggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSArIGV4cG9ydFBhZGRpbmcgKiAyO1xuICBjb25zdCBoZWlnaHQgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSArIGV4cG9ydFBhZGRpbmcgKyBleHBvcnRQYWRkaW5nO1xuXG4gIHJldHVybiBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RXhwb3J0U2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4gIHNjYWxlOiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgWywgLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpLm1hcChcbiAgICAoZGltZW5zaW9uKSA9PiBNYXRoLnRydW5jKGRpbWVuc2lvbiAqIHNjYWxlKSxcbiAgKTtcblxuICByZXR1cm4gW3dpZHRoLCBoZWlnaHRdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
3264
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SVG_EXPORT_TAG\": () => (/* binding */ SVG_EXPORT_TAG),\n/* harmony export */ \"exportToCanvas\": () => (/* binding */ exportToCanvas),\n/* harmony export */ \"exportToSvg\": () => (/* binding */ exportToSvg),\n/* harmony export */ \"getExportSize\": () => (/* binding */ getExportSize)\n/* harmony export */ });\n/* harmony import */ var roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var _element_bounds__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../element/bounds */ \"../../element/bounds.ts\");\n/* harmony import */ var _renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../renderer/renderScene */ \"../../renderer/renderScene.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../data/json */ \"../../data/json.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\n\n\n\n\nconst SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;\nconst exportToCanvas = (elements, appState, files, { exportBackground, exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, }, createCanvas = (width, height) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width * appState.exportScale;\n canvas.height = height * appState.exportScale;\n return { canvas, scale: appState.exportScale };\n}) => __awaiter(void 0, void 0, void 0, function* () {\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n const { canvas, scale = 1 } = createCanvas(width, height);\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_5__.getDefaultAppState)();\n const { imageCache } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.updateImageCache)({\n imageCache: new Map(),\n fileIds: (0,_element_image__WEBPACK_IMPORTED_MODULE_7__.getInitializedImageElements)(elements).map((element) => element.fileId),\n files,\n });\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderScene)({\n elements,\n appState,\n scale,\n rc: roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].canvas(canvas),\n canvas,\n renderConfig: {\n viewBackgroundColor: exportBackground ? viewBackgroundColor : null,\n scrollX: -minX + exportPadding,\n scrollY: -minY + exportPadding,\n zoom: defaultAppState.zoom,\n remotePointerViewportCoords: {},\n remoteSelectedElementIds: {},\n shouldCacheIgnoreZoom: false,\n remotePointerUsernames: {},\n remotePointerUserStates: {},\n theme: appState.exportWithDarkMode ? \"dark\" : \"light\",\n imageCache,\n renderScrollbars: false,\n renderSelection: false,\n renderGrid: false,\n isExporting: true,\n },\n });\n return canvas;\n});\nconst exportToSvg = (elements, appState, files) => __awaiter(void 0, void 0, void 0, function* () {\n const { exportPadding = _constants__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_EXPORT_PADDING, viewBackgroundColor, exportScale = 1, exportEmbedScene, } = appState;\n let metadata = \"\";\n if (exportEmbedScene) {\n try {\n metadata = yield (yield Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../../src/data/image */ \"../../data/image.ts\"))).encodeSvgMetadata({\n text: (0,_data_json__WEBPACK_IMPORTED_MODULE_6__.serializeAsJSON)(elements, appState, files || {}, \"local\"),\n });\n }\n catch (error) {\n console.error(error);\n }\n }\n const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);\n // initialize SVG root\n const svgRoot = document.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"svg\");\n svgRoot.setAttribute(\"version\", \"1.1\");\n svgRoot.setAttribute(\"xmlns\", _constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS);\n svgRoot.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svgRoot.setAttribute(\"width\", `${width * exportScale}`);\n svgRoot.setAttribute(\"height\", `${height * exportScale}`);\n if (appState.exportWithDarkMode) {\n svgRoot.setAttribute(\"filter\", _constants__WEBPACK_IMPORTED_MODULE_4__.THEME_FILTER);\n }\n let assetPath = \"https://excalidraw.com/\";\n // Asset path needs to be determined only when using package\n if (true) {\n assetPath =\n window.EXCALIDRAW_ASSET_PATH ||\n `https://unpkg.com/${\"@excalidraw/excalidraw\"}@${\"0.12.0-5598-d731a64\"}`;\n if (assetPath === null || assetPath === void 0 ? void 0 : assetPath.startsWith(\"/\")) {\n assetPath = assetPath.replace(\"/\", `${window.location.origin}/`);\n }\n assetPath = `${assetPath}/dist/excalidraw-assets/`;\n }\n svgRoot.innerHTML = `\n ${SVG_EXPORT_TAG}\n ${metadata}\n <defs>\n <style>\n @font-face {\n font-family: \"Virgil\";\n src: url(\"${assetPath}Virgil.woff2\");\n }\n @font-face {\n font-family: \"Cascadia\";\n src: url(\"${assetPath}Cascadia.woff2\");\n }\n </style>\n </defs>\n `;\n // render background rect\n if (appState.exportBackground && viewBackgroundColor) {\n const rect = svgRoot.ownerDocument.createElementNS(_constants__WEBPACK_IMPORTED_MODULE_4__.SVG_NS, \"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", `${width}`);\n rect.setAttribute(\"height\", `${height}`);\n rect.setAttribute(\"fill\", viewBackgroundColor);\n svgRoot.appendChild(rect);\n }\n const rsvg = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_0__[\"default\"].svg(svgRoot);\n (0,_renderer_renderScene__WEBPACK_IMPORTED_MODULE_2__.renderSceneToSvg)(elements, rsvg, svgRoot, files || {}, {\n offsetX: -minX + exportPadding,\n offsetY: -minY + exportPadding,\n exportWithDarkMode: appState.exportWithDarkMode,\n });\n return svgRoot;\n});\n// calculate smallest area to fit the contents in\nconst getCanvasSize = (elements, exportPadding) => {\n const [minX, minY, maxX, maxY] = (0,_element_bounds__WEBPACK_IMPORTED_MODULE_1__.getCommonBounds)(elements);\n const width = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minX, maxX) + exportPadding * 2;\n const height = (0,_utils__WEBPACK_IMPORTED_MODULE_3__.distance)(minY, maxY) + exportPadding + exportPadding;\n return [minX, minY, width, height];\n};\nconst getExportSize = (elements, exportPadding, scale) => {\n const [, , width, height] = getCanvasSize(elements, exportPadding).map((dimension) => Math.trunc(dimension * scale));\n return [width, height];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Iiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3NjZW5lL2V4cG9ydC50cz85YmY3Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByb3VnaCBmcm9tIFwicm91Z2hqcy9iaW4vcm91Z2hcIjtcbmltcG9ydCB7IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDb21tb25Cb3VuZHMgfSBmcm9tIFwiLi4vZWxlbWVudC9ib3VuZHNcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lLCByZW5kZXJTY2VuZVRvU3ZnIH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlclNjZW5lXCI7XG5pbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUsIEJpbmFyeUZpbGVzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VYUE9SVF9QQURESU5HLCBTVkdfTlMsIFRIRU1FX0ZJTFRFUiB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSB9IGZyb20gXCIuLi9hcHBTdGF0ZVwiO1xuaW1wb3J0IHsgc2VyaWFsaXplQXNKU09OIH0gZnJvbSBcIi4uL2RhdGEvanNvblwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICB1cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuXG5leHBvcnQgY29uc3QgU1ZHX0VYUE9SVF9UQUcgPSBgPCEtLSBzdmctc291cmNlOmV4Y2FsaWRyYXcgLS0+YDtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvQ2FudmFzID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgZmlsZXM6IEJpbmFyeUZpbGVzLFxuICB7XG4gICAgZXhwb3J0QmFja2dyb3VuZCxcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICB9OiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgfSxcbiAgY3JlYXRlQ2FudmFzOiAoXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgKSA9PiB7IGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7IHNjYWxlOiBudW1iZXIgfSA9ICh3aWR0aCwgaGVpZ2h0KSA9PiB7XG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjYW52YXMud2lkdGggPSB3aWR0aCAqIGFwcFN0YXRlLmV4cG9ydFNjYWxlO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQgKiBhcHBTdGF0ZS5leHBvcnRTY2FsZTtcbiAgICByZXR1cm4geyBjYW52YXMsIHNjYWxlOiBhcHBTdGF0ZS5leHBvcnRTY2FsZSB9O1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IFttaW5YLCBtaW5ZLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpO1xuXG4gIGNvbnN0IHsgY2FudmFzLCBzY2FsZSA9IDEgfSA9IGNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KTtcblxuICBjb25zdCBkZWZhdWx0QXBwU3RhdGUgPSBnZXREZWZhdWx0QXBwU3RhdGUoKTtcblxuICBjb25zdCB7IGltYWdlQ2FjaGUgfSA9IGF3YWl0IHVwZGF0ZUltYWdlQ2FjaGUoe1xuICAgIGltYWdlQ2FjaGU6IG5ldyBNYXAoKSxcbiAgICBmaWxlSWRzOiBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoZWxlbWVudHMpLm1hcChcbiAgICAgIChlbGVtZW50KSA9PiBlbGVtZW50LmZpbGVJZCxcbiAgICApLFxuICAgIGZpbGVzLFxuICB9KTtcblxuICByZW5kZXJTY2VuZSh7XG4gICAgZWxlbWVudHMsXG4gICAgYXBwU3RhdGUsXG4gICAgc2NhbGUsXG4gICAgcmM6IHJvdWdoLmNhbnZhcyhjYW52YXMpLFxuICAgIGNhbnZhcyxcbiAgICByZW5kZXJDb25maWc6IHtcbiAgICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IGV4cG9ydEJhY2tncm91bmQgPyB2aWV3QmFja2dyb3VuZENvbG9yIDogbnVsbCxcbiAgICAgIHNjcm9sbFg6IC1taW5YICsgZXhwb3J0UGFkZGluZyxcbiAgICAgIHNjcm9sbFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICAgIHpvb206IGRlZmF1bHRBcHBTdGF0ZS56b29tLFxuICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiB7fSxcbiAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IGZhbHNlLFxuICAgICAgcmVtb3RlUG9pbnRlclVzZXJuYW1lczoge30sXG4gICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczoge30sXG4gICAgICB0aGVtZTogYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlID8gXCJkYXJrXCIgOiBcImxpZ2h0XCIsXG4gICAgICBpbWFnZUNhY2hlLFxuICAgICAgcmVuZGVyU2Nyb2xsYmFyczogZmFsc2UsXG4gICAgICByZW5kZXJTZWxlY3Rpb246IGZhbHNlLFxuICAgICAgcmVuZGVyR3JpZDogZmFsc2UsXG4gICAgICBpc0V4cG9ydGluZzogdHJ1ZSxcbiAgICB9LFxuICB9KTtcblxuICByZXR1cm4gY2FudmFzO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFRvU3ZnID0gYXN5bmMgKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGFwcFN0YXRlOiB7XG4gICAgZXhwb3J0QmFja2dyb3VuZDogYm9vbGVhbjtcbiAgICBleHBvcnRQYWRkaW5nPzogbnVtYmVyO1xuICAgIGV4cG9ydFNjYWxlPzogbnVtYmVyO1xuICAgIHZpZXdCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgICBleHBvcnRXaXRoRGFya01vZGU/OiBib29sZWFuO1xuICAgIGV4cG9ydEVtYmVkU2NlbmU/OiBib29sZWFuO1xuICB9LFxuICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsLFxuKTogUHJvbWlzZTxTVkdTVkdFbGVtZW50PiA9PiB7XG4gIGNvbnN0IHtcbiAgICBleHBvcnRQYWRkaW5nID0gREVGQVVMVF9FWFBPUlRfUEFERElORyxcbiAgICB2aWV3QmFja2dyb3VuZENvbG9yLFxuICAgIGV4cG9ydFNjYWxlID0gMSxcbiAgICBleHBvcnRFbWJlZFNjZW5lLFxuICB9ID0gYXBwU3RhdGU7XG4gIGxldCBtZXRhZGF0YSA9IFwiXCI7XG4gIGlmIChleHBvcnRFbWJlZFNjZW5lKSB7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoLyogd2VicGFja0NodW5rTmFtZTogXCJpbWFnZVwiICovIFwiLi4vLi4vc3JjL2RhdGEvaW1hZ2VcIilcbiAgICAgICkuZW5jb2RlU3ZnTWV0YWRhdGEoe1xuICAgICAgICB0ZXh0OiBzZXJpYWxpemVBc0pTT04oZWxlbWVudHMsIGFwcFN0YXRlLCBmaWxlcyB8fCB7fSwgXCJsb2NhbFwiKSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuICBjb25zdCBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF0gPSBnZXRDYW52YXNTaXplKGVsZW1lbnRzLCBleHBvcnRQYWRkaW5nKTtcblxuICAvLyBpbml0aWFsaXplIFNWRyByb290XG4gIGNvbnN0IHN2Z1Jvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCBcInN2Z1wiKTtcbiAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJ2ZXJzaW9uXCIsIFwiMS4xXCIpO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcInhtbG5zXCIsIFNWR19OUyk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwidmlld0JveFwiLCBgMCAwICR7d2lkdGh9ICR7aGVpZ2h0fWApO1xuICBzdmdSb290LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRoICogZXhwb3J0U2NhbGV9YCk7XG4gIHN2Z1Jvb3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodCAqIGV4cG9ydFNjYWxlfWApO1xuICBpZiAoYXBwU3RhdGUuZXhwb3J0V2l0aERhcmtNb2RlKSB7XG4gICAgc3ZnUm9vdC5zZXRBdHRyaWJ1dGUoXCJmaWx0ZXJcIiwgVEhFTUVfRklMVEVSKTtcbiAgfVxuXG4gIGxldCBhc3NldFBhdGggPSBcImh0dHBzOi8vZXhjYWxpZHJhdy5jb20vXCI7XG5cbiAgLy8gQXNzZXQgcGF0aCBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIG9ubHkgd2hlbiB1c2luZyBwYWNrYWdlXG4gIGlmIChwcm9jZXNzLmVudi5JU19FWENBTElEUkFXX05QTV9QQUNLQUdFKSB7XG4gICAgYXNzZXRQYXRoID1cbiAgICAgIHdpbmRvdy5FWENBTElEUkFXX0FTU0VUX1BBVEggfHxcbiAgICAgIGBodHRwczovL3VucGtnLmNvbS8ke3Byb2Nlc3MuZW52LlBLR19OQU1FfUAke3Byb2Nlc3MuZW52LlBLR19WRVJTSU9OfWA7XG5cbiAgICBpZiAoYXNzZXRQYXRoPy5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgYXNzZXRQYXRoID0gYXNzZXRQYXRoLnJlcGxhY2UoXCIvXCIsIGAke3dpbmRvdy5sb2NhdGlvbi5vcmlnaW59L2ApO1xuICAgIH1cbiAgICBhc3NldFBhdGggPSBgJHthc3NldFBhdGh9L2Rpc3QvZXhjYWxpZHJhdy1hc3NldHMvYDtcbiAgfVxuICBzdmdSb290LmlubmVySFRNTCA9IGBcbiAgJHtTVkdfRVhQT1JUX1RBR31cbiAgJHttZXRhZGF0YX1cbiAgPGRlZnM+XG4gICAgPHN0eWxlPlxuICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgIGZvbnQtZmFtaWx5OiBcIlZpcmdpbFwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofVZpcmdpbC53b2ZmMlwiKTtcbiAgICAgIH1cbiAgICAgIEBmb250LWZhY2Uge1xuICAgICAgICBmb250LWZhbWlseTogXCJDYXNjYWRpYVwiO1xuICAgICAgICBzcmM6IHVybChcIiR7YXNzZXRQYXRofUNhc2NhZGlhLndvZmYyXCIpO1xuICAgICAgfVxuICAgIDwvc3R5bGU+XG4gIDwvZGVmcz5cbiAgYDtcbiAgLy8gcmVuZGVyIGJhY2tncm91bmQgcmVjdFxuICBpZiAoYXBwU3RhdGUuZXhwb3J0QmFja2dyb3VuZCAmJiB2aWV3QmFja2dyb3VuZENvbG9yKSB7XG4gICAgY29uc3QgcmVjdCA9IHN2Z1Jvb3Qub3duZXJEb2N1bWVudCEuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgXCJyZWN0XCIpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofWApO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2hlaWdodH1gKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZShcImZpbGxcIiwgdmlld0JhY2tncm91bmRDb2xvcik7XG4gICAgc3ZnUm9vdC5hcHBlbmRDaGlsZChyZWN0KTtcbiAgfVxuXG4gIGNvbnN0IHJzdmcgPSByb3VnaC5zdmcoc3ZnUm9vdCk7XG4gIHJlbmRlclNjZW5lVG9TdmcoZWxlbWVudHMsIHJzdmcsIHN2Z1Jvb3QsIGZpbGVzIHx8IHt9LCB7XG4gICAgb2Zmc2V0WDogLW1pblggKyBleHBvcnRQYWRkaW5nLFxuICAgIG9mZnNldFk6IC1taW5ZICsgZXhwb3J0UGFkZGluZyxcbiAgICBleHBvcnRXaXRoRGFya01vZGU6IGFwcFN0YXRlLmV4cG9ydFdpdGhEYXJrTW9kZSxcbiAgfSk7XG5cbiAgcmV0dXJuIHN2Z1Jvb3Q7XG59O1xuXG4vLyBjYWxjdWxhdGUgc21hbGxlc3QgYXJlYSB0byBmaXQgdGhlIGNvbnRlbnRzIGluXG5jb25zdCBnZXRDYW52YXNTaXplID0gKFxuICBlbGVtZW50czogcmVhZG9ubHkgTm9uRGVsZXRlZEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gIGV4cG9ydFBhZGRpbmc6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgW21pblgsIG1pblksIG1heFgsIG1heFldID0gZ2V0Q29tbW9uQm91bmRzKGVsZW1lbnRzKTtcbiAgY29uc3Qgd2lkdGggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSArIGV4cG9ydFBhZGRpbmcgKiAyO1xuICBjb25zdCBoZWlnaHQgPSBkaXN0YW5jZShtaW5ZLCBtYXhZKSArIGV4cG9ydFBhZGRpbmcgKyBleHBvcnRQYWRkaW5nO1xuXG4gIHJldHVybiBbbWluWCwgbWluWSwgd2lkdGgsIGhlaWdodF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RXhwb3J0U2l6ZSA9IChcbiAgZWxlbWVudHM6IHJlYWRvbmx5IE5vbkRlbGV0ZWRFeGNhbGlkcmF3RWxlbWVudFtdLFxuICBleHBvcnRQYWRkaW5nOiBudW1iZXIsXG4gIHNjYWxlOiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgWywgLCB3aWR0aCwgaGVpZ2h0XSA9IGdldENhbnZhc1NpemUoZWxlbWVudHMsIGV4cG9ydFBhZGRpbmcpLm1hcChcbiAgICAoZGltZW5zaW9uKSA9PiBNYXRoLnRydW5jKGRpbWVuc2lvbiAqIHNjYWxlKSxcbiAgKTtcblxuICByZXR1cm4gW3dpZHRoLCBoZWlnaHRdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../scene/export.ts\n");
3265
3265
 
3266
3266
  /***/ }),
3267
3267
 
@@ -3349,7 +3349,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3349
3349
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3350
3350
 
3351
3351
  "use strict";
3352
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"allowFullScreen\": () => (/* binding */ allowFullScreen),\n/* harmony export */ \"arrayToMap\": () => (/* binding */ arrayToMap),\n/* harmony export */ \"bytesToHexString\": () => (/* binding */ bytesToHexString),\n/* harmony export */ \"capitalizeString\": () => (/* binding */ capitalizeString),\n/* harmony export */ \"chunk\": () => (/* binding */ chunk),\n/* harmony export */ \"debounce\": () => (/* binding */ debounce),\n/* harmony export */ \"distance\": () => (/* binding */ distance),\n/* harmony export */ \"exitFullScreen\": () => (/* binding */ exitFullScreen),\n/* harmony export */ \"findIndex\": () => (/* binding */ findIndex),\n/* harmony export */ \"findLastIndex\": () => (/* binding */ findLastIndex),\n/* harmony export */ \"focusNearestParent\": () => (/* binding */ focusNearestParent),\n/* harmony export */ \"getDateTime\": () => (/* binding */ getDateTime),\n/* harmony export */ \"getFontFamilyString\": () => (/* binding */ getFontFamilyString),\n/* harmony export */ \"getFontString\": () => (/* binding */ getFontString),\n/* harmony export */ \"getFrame\": () => (/* binding */ getFrame),\n/* harmony export */ \"getGlobalCSSVariable\": () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ \"getNearestScrollableContainer\": () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ \"getShortcutKey\": () => (/* binding */ getShortcutKey),\n/* harmony export */ \"getUpdatedTimestamp\": () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ \"getVersion\": () => (/* binding */ getVersion),\n/* harmony export */ \"isFullScreen\": () => (/* binding */ isFullScreen),\n/* harmony export */ \"isInputLike\": () => (/* binding */ isInputLike),\n/* harmony export */ \"isPrimitive\": () => (/* binding */ isPrimitive),\n/* harmony export */ \"isProdEnv\": () => (/* binding */ isProdEnv),\n/* harmony export */ \"isPromiseLike\": () => (/* binding */ isPromiseLike),\n/* harmony export */ \"isRTL\": () => (/* binding */ isRTL),\n/* harmony export */ \"isTestEnv\": () => (/* binding */ isTestEnv),\n/* harmony export */ \"isToolIcon\": () => (/* binding */ isToolIcon),\n/* harmony export */ \"isTransparent\": () => (/* binding */ isTransparent),\n/* harmony export */ \"isWritableElement\": () => (/* binding */ isWritableElement),\n/* harmony export */ \"muteFSAbortError\": () => (/* binding */ muteFSAbortError),\n/* harmony export */ \"nFormatter\": () => (/* binding */ nFormatter),\n/* harmony export */ \"preventUnload\": () => (/* binding */ preventUnload),\n/* harmony export */ \"queryFocusableElements\": () => (/* binding */ queryFocusableElements),\n/* harmony export */ \"removeSelection\": () => (/* binding */ removeSelection),\n/* harmony export */ \"resetCursor\": () => (/* binding */ resetCursor),\n/* harmony export */ \"resolvablePromise\": () => (/* binding */ resolvablePromise),\n/* harmony export */ \"sceneCoordsToViewportCoords\": () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ \"selectNode\": () => (/* binding */ selectNode),\n/* harmony export */ \"setCursor\": () => (/* binding */ setCursor),\n/* harmony export */ \"setCursorForShape\": () => (/* binding */ setCursorForShape),\n/* harmony export */ \"setDateTimeForTests\": () => (/* binding */ setDateTimeForTests),\n/* harmony export */ \"setEraserCursor\": () => (/* binding */ setEraserCursor),\n/* harmony export */ \"supportsEmoji\": () => (/* binding */ supportsEmoji),\n/* harmony export */ \"throttleRAF\": () => (/* binding */ throttleRAF),\n/* harmony export */ \"tupleToCoors\": () => (/* binding */ tupleToCoors),\n/* harmony export */ \"updateActiveTool\": () => (/* binding */ updateActiveTool),\n/* harmony export */ \"updateObject\": () => (/* binding */ updateObject),\n/* harmony export */ \"viewportCoordsToSceneCoords\": () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ \"withBatchedUpdates\": () => (/* binding */ withBatchedUpdates),\n/* harmony export */ \"withBatchedUpdatesThrottled\": () => (/* binding */ withBatchedUpdatesThrottled),\n/* harmony export */ \"wrapEvent\": () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../../constants.ts\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./keys */ \"../../keys.ts\");\n\n\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = (dateTime) => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = (target) => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement;\nconst isWritableElement = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLTextAreaElement ||\n (target instanceof HTMLInputElement &&\n (target.type === \"text\" || target.type === \"number\"));\nconst getFontFamilyString = ({ fontFamily, }) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}, ${_constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT}`;\n }\n }\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\nconst getFontString = ({ fontSize, fontFamily, }) => {\n return `${fontSize}px ${getFontFamilyString({ fontFamily })}`;\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n ret.flush = () => {\n clearTimeout(handle);\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n return ret;\n};\n// throttle callback to execute once per animation frame\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n const scheduleFunc = (args) => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n const ret = (...args) => {\n if (false) {}\n lastArgs = args;\n if (timerId === null) {\n scheduleFunc(lastArgs);\n }\n else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n return ret;\n};\n// https://github.com/lodash/lodash/blob/es/chunk.js\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n while (index < array.length) {\n result[resIndex++] = array.slice(index, (index += size));\n }\n return result;\n};\nconst selectNode = (node) => {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst updateActiveTool = (appState, data) => {\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), { type: \"custom\", customType: data.customType });\n }\n return Object.assign(Object.assign({}, appState.activeTool), { lastActiveToolBeforeEraser: data.lastActiveToolBeforeEraser === undefined\n ? appState.activeTool.lastActiveToolBeforeEraser\n : data.lastActiveToolBeforeEraser, type: data.type, customType: null });\n};\nconst resetCursor = (canvas) => {\n if (canvas) {\n canvas.style.cursor = \"\";\n }\n};\nconst setCursor = (canvas, cursor) => {\n if (canvas) {\n canvas.style.cursor = cursor;\n }\n};\nlet eraserCanvasCache;\nlet previewDataURL;\nconst setEraserCursor = (canvas, theme) => {\n const cursorImageSizePx = 20;\n const drawCanvas = () => {\n const isDarkTheme = theme === _constants__WEBPACK_IMPORTED_MODULE_2__.THEME.DARK;\n eraserCanvasCache = document.createElement(\"canvas\");\n eraserCanvasCache.theme = theme;\n eraserCanvasCache.height = cursorImageSizePx;\n eraserCanvasCache.width = cursorImageSizePx;\n const context = eraserCanvasCache.getContext(\"2d\");\n context.lineWidth = 1;\n context.beginPath();\n context.arc(eraserCanvasCache.width / 2, eraserCanvasCache.height / 2, 5, 0, 2 * Math.PI);\n context.fillStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.black : open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.fill();\n context.strokeStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.white : open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.stroke();\n previewDataURL = eraserCanvasCache.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_2__.MIME_TYPES.svg);\n };\n if (!eraserCanvasCache || eraserCanvasCache.theme !== theme) {\n drawCanvas();\n }\n setCursor(canvas, `url(${previewDataURL}) ${cursorImageSizePx / 2} ${cursorImageSizePx / 2}, auto`);\n};\nconst setCursorForShape = (canvas, appState) => {\n if (!canvas) {\n return;\n }\n if (appState.activeTool.type === \"selection\") {\n resetCursor(canvas);\n }\n else if (appState.activeTool.type === \"eraser\") {\n setEraserCursor(canvas, appState.theme);\n // do nothing if image tool is selected which suggests there's\n // a image-preview set as the cursor\n // Ignore custom type as well and let host decide\n }\n else if (![\"image\", \"custom\"].includes(appState.activeTool.type)) {\n canvas.style.cursor = _constants__WEBPACK_IMPORTED_MODULE_2__.CURSOR_TYPE.CROSSHAIR;\n }\n};\nconst isFullScreen = () => { var _a; return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\"; };\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst getShortcutKey = (shortcut) => {\n shortcut = shortcut\n .replace(/\\bAlt\\b/i, \"Alt\")\n .replace(/\\bShift\\b/i, \"Shift\")\n .replace(/\\b(Enter|Return)\\b/i, \"Enter\")\n .replace(/\\bDel\\b/i, \"Delete\");\n if (_keys__WEBPACK_IMPORTED_MODULE_4__.isDarwin) {\n return shortcut\n .replace(/\\bCtrlOrCmd\\b/i, \"Cmd\")\n .replace(/\\bAlt\\b/i, \"Option\");\n }\n return shortcut.replace(/\\bCtrlOrCmd\\b/i, \"Ctrl\");\n};\nconst viewportCoordsToSceneCoords = ({ clientX, clientY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const invScale = 1 / zoom.value;\n const x = (clientX - offsetLeft) * invScale - scrollX;\n const y = (clientY - offsetTop) * invScale - scrollY;\n return { x, y };\n};\nconst sceneCoordsToViewportCoords = ({ sceneX, sceneY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return { x, y };\n};\nconst getGlobalCSSVariable = (name) => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" +\n \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\n * Checks whether first directional character is RTL. Meaning whether it starts\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\n * RTL.\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\n */\nconst isRTL = (text) => RE_RTL_CHECK.test(text);\nconst tupleToCoors = (xyTuple) => {\n const [x, y] = xyTuple;\n return { x, y };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\nconst muteFSAbortError = (error) => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst isTransparent = (color) => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return (isRGBTransparent ||\n isRRGGBBTransparent ||\n color === _colors__WEBPACK_IMPORTED_MODULE_1__[\"default\"].elementBackground[0]);\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n};\n/**\n * @param func handler taking at most single parameter (event).\n */\nconst withBatchedUpdates = (func) => ((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n});\n/**\n * barches React state updates and throttles the calls to a single call per\n * animation frame\n */\nconst withBatchedUpdatesThrottled = (func) => {\n // @ts-ignore\n return throttleRAF(((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n }));\n};\n//https://stackoverflow.com/a/9462382/8418\nconst nFormatter = (num, digits) => {\n const si = [\n { value: 1, symbol: \"b\" },\n { value: 1e3, symbol: \"k\" },\n { value: 1e6, symbol: \"M\" },\n { value: 1e9, symbol: \"G\" },\n ];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n return ((num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol);\n};\nconst getVersion = () => {\n var _a;\n return (((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) ||\n _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION);\n};\n// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return false;\n }\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\";\n // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n const { overflowY } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n if (hasScrollableContent &&\n (overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n overflowY === \"overlay\")) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return document;\n};\nconst focusNearestParent = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n parent = parent.parentElement;\n }\n};\nconst preventUnload = (event) => {\n event.preventDefault();\n // NOTE: modern browsers no longer allow showing a custom message here\n event.returnValue = \"\";\n};\nconst bytesToHexString = (bytes) => {\n return Array.from(bytes)\n .map((byte) => `0${byte.toString(16)}`.slice(-2))\n .join(\"\");\n};\nconst getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());\n/**\n * Transforms array of objects containing `id` attribute,\n * or array of ids (strings), into a Map, keyd by `id`.\n */\nconst arrayToMap = (items) => {\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst isTestEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"test\"; };\nconst isProdEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-9f325a6\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"production\"; };\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent,\n },\n cancelable: true,\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n for (const key in updates) {\n const value = updates[key];\n if (typeof value !== \"undefined\") {\n if (obj[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)) {\n continue;\n }\n didChange = true;\n }\n }\n if (!didChange) {\n return obj;\n }\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = (val) => {\n const type = typeof val;\n return val == null || (type !== \"object\" && type !== \"function\");\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n }\n catch (error) {\n return \"iframe\";\n }\n};\nconst isPromiseLike = (value) => {\n return (!!value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n \"catch\" in value &&\n \"finally\" in value);\n};\nconst queryFocusableElements = (container) => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements\n ? Array.from(focusableElements).filter((element) => element.tabIndex > -1 && !element.disabled)\n : [];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFFBQVEsSUFBSSxJQUFJLEtBQUssVUFBVSxDQUFDLENBQUM7QUFDbkUsQ0FBQyxDQUFDO0FBRUssTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUk7UUFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7S0FDdEQ7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNkLE9BQU8sUUFBUSxDQUFDO0tBQ2pCO0FBQ0gsQ0FBQyxDQUFDO0FBRUssTUFBTSxhQUFhLEdBQUcsQ0FDM0IsS0FBVSxFQUNzQyxFQUFFO0lBQ2xELE9BQU8sQ0FDTCxDQUFDLENBQUMsS0FBSztRQUNQLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFDekIsTUFBTSxJQUFJLEtBQUs7UUFDZixPQUFPLElBQUksS0FBSztRQUNoQixTQUFTLElBQUksS0FBSyxDQUNuQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUssTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFNBQTZCLEVBQUUsRUFBRTtJQUN0RSxNQUFNLGlCQUFpQixHQUFHLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxnQkFBZ0IsQ0FDbkQsb0VBQW9FLENBQ3JFLENBQUM7SUFFRixPQUFPLGlCQUFpQjtRQUN0QixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FDbEMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNWLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBRSxPQUE0QixDQUFDLFFBQVEsQ0FDbkU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ1QsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3V0aWxzLnRzPzc2M2EiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9jIGZyb20gXCJvcGVuLWNvbG9yXCI7XG5cbmltcG9ydCBjb2xvcnMgZnJvbSBcIi4vY29sb3JzXCI7XG5pbXBvcnQge1xuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9WRVJTSU9OLFxuICBFVkVOVCxcbiAgRk9OVF9GQU1JTFksXG4gIE1JTUVfVFlQRVMsXG4gIFRIRU1FLFxuICBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRm9udEZhbWlseVZhbHVlcywgRm9udFN0cmluZyB9IGZyb20gXCIuL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBEYXRhVVJMLCBMYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlciwgWm9vbSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyB1bnN0YWJsZV9iYXRjaGVkVXBkYXRlcyB9IGZyb20gXCJyZWFjdC1kb21cIjtcbmltcG9ydCB7IGlzRGFyd2luIH0gZnJvbSBcIi4va2V5c1wiO1xuaW1wb3J0IHsgU0hBUEVTIH0gZnJvbSBcIi4vc2hhcGVzXCI7XG5cbmxldCBtb2NrRGF0ZVRpbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgY29uc3Qgc2V0RGF0ZVRpbWVGb3JUZXN0cyA9IChkYXRlVGltZTogc3RyaW5nKSA9PiB7XG4gIG1vY2tEYXRlVGltZSA9IGRhdGVUaW1lO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERhdGVUaW1lID0gKCkgPT4ge1xuICBpZiAobW9ja0RhdGVUaW1lKSB7XG4gICAgcmV0dXJuIG1vY2tEYXRlVGltZTtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICBjb25zdCBtb250aCA9IGAke2RhdGUuZ2V0TW9udGgoKSArIDF9YC5wYWRTdGFydCgyLCBcIjBcIik7XG4gIGNvbnN0IGRheSA9IGAke2RhdGUuZ2V0RGF0ZSgpfWAucGFkU3RhcnQoMiwgXCIwXCIpO1xuICBjb25zdCBociA9IGAke2RhdGUuZ2V0SG91cnMoKX1gLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgY29uc3QgbWluID0gYCR7ZGF0ZS5nZXRNaW51dGVzKCl9YC5wYWRTdGFydCgyLCBcIjBcIik7XG5cbiAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fS0ke2hyfSR7bWlufWA7XG59O1xuXG5leHBvcnQgY29uc3QgY2FwaXRhbGl6ZVN0cmluZyA9IChzdHI6IHN0cmluZykgPT5cbiAgc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuXG5leHBvcnQgY29uc3QgaXNUb29sSWNvbiA9IChcbiAgdGFyZ2V0OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQgfCBudWxsLFxuKTogdGFyZ2V0IGlzIEhUTUxFbGVtZW50ID0+XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIHRhcmdldC5jbGFzc05hbWUuaW5jbHVkZXMoXCJUb29sSWNvblwiKTtcblxuZXhwb3J0IGNvbnN0IGlzSW5wdXRMaWtlID0gKFxuICB0YXJnZXQ6IEVsZW1lbnQgfCBFdmVudFRhcmdldCB8IG51bGwsXG4pOiB0YXJnZXQgaXNcbiAgfCBIVE1MSW5wdXRFbGVtZW50XG4gIHwgSFRNTFRleHRBcmVhRWxlbWVudFxuICB8IEhUTUxTZWxlY3RFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fFxuICB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50IHx8XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50O1xuXG5leHBvcnQgY29uc3QgaXNXcml0YWJsZUVsZW1lbnQgPSAoXG4gIHRhcmdldDogRWxlbWVudCB8IEV2ZW50VGFyZ2V0IHwgbnVsbCxcbik6IHRhcmdldCBpc1xuICB8IEhUTUxJbnB1dEVsZW1lbnRcbiAgfCBIVE1MVGV4dEFyZWFFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fFxuICAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICh0YXJnZXQudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgdGFyZ2V0LnR5cGUgPT09IFwibnVtYmVyXCIpKTtcblxuZXhwb3J0IGNvbnN0IGdldEZvbnRGYW1pbHlTdHJpbmcgPSAoe1xuICBmb250RmFtaWx5LFxufToge1xuICBmb250RmFtaWx5OiBGb250RmFtaWx5VmFsdWVzO1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IFtmb250RmFtaWx5U3RyaW5nLCBpZF0gb2YgT2JqZWN0LmVudHJpZXMoRk9OVF9GQU1JTFkpKSB7XG4gICAgaWYgKGlkID09PSBmb250RmFtaWx5KSB7XG4gICAgICByZXR1cm4gYCR7Zm9udEZhbWlseVN0cmluZ30sICR7V0lORE9XU19FTU9KSV9GQUxMQkFDS19GT05UfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQ7XG59O1xuXG4vKiogcmV0dXJucyBmb250U2l6ZStmb250RmFtaWx5IHN0cmluZyBmb3IgYXNzaWdubWVudCB0byBET00gZWxlbWVudHMgKi9cbmV4cG9ydCBjb25zdCBnZXRGb250U3RyaW5nID0gKHtcbiAgZm9udFNpemUsXG4gIGZvbnRGYW1pbHksXG59OiB7XG4gIGZvbnRTaXplOiBudW1iZXI7XG4gIGZvbnRGYW1pbHk6IEZvbnRGYW1pbHlWYWx1ZXM7XG59KSA9PiB7XG4gIHJldHVybiBgJHtmb250U2l6ZX1weCAke2dldEZvbnRGYW1pbHlTdHJpbmcoeyBmb250RmFtaWx5IH0pfWAgYXMgRm9udFN0cmluZztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWJvdW5jZSA9IDxUIGV4dGVuZHMgYW55W10+KFxuICBmbjogKC4uLmFyZ3M6IFQpID0+IHZvaWQsXG4gIHRpbWVvdXQ6IG51bWJlcixcbikgPT4ge1xuICBsZXQgaGFuZGxlID0gMDtcbiAgbGV0IGxhc3RBcmdzOiBUIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHJldCA9ICguLi5hcmdzOiBUKSA9PiB7XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGNsZWFyVGltZW91dChoYW5kbGUpO1xuICAgIGhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLmFyZ3MpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9O1xuICByZXQuZmx1c2ggPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KGhhbmRsZSk7XG4gICAgaWYgKGxhc3RBcmdzKSB7XG4gICAgICBjb25zdCBfbGFzdEFyZ3MgPSBsYXN0QXJncztcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLl9sYXN0QXJncyk7XG4gICAgfVxuICB9O1xuICByZXQuY2FuY2VsID0gKCkgPT4ge1xuICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICBjbGVhclRpbWVvdXQoaGFuZGxlKTtcbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIHRocm90dGxlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lXG5leHBvcnQgY29uc3QgdGhyb3R0bGVSQUYgPSA8VCBleHRlbmRzIGFueVtdPihcbiAgZm46ICguLi5hcmdzOiBUKSA9PiB2b2lkLFxuICBvcHRzPzogeyB0cmFpbGluZz86IGJvb2xlYW4gfSxcbikgPT4ge1xuICBsZXQgdGltZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGxldCBsYXN0QXJnczogVCB8IG51bGwgPSBudWxsO1xuICBsZXQgbGFzdEFyZ3NUcmFpbGluZzogVCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHNjaGVkdWxlRnVuYyA9IChhcmdzOiBUKSA9PiB7XG4gICAgdGltZXJJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGltZXJJZCA9IG51bGw7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGlmIChsYXN0QXJnc1RyYWlsaW5nKSB7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdEFyZ3NUcmFpbGluZztcbiAgICAgICAgbGFzdEFyZ3NUcmFpbGluZyA9IG51bGw7XG4gICAgICAgIHNjaGVkdWxlRnVuYyhsYXN0QXJncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgcmV0ID0gKC4uLmFyZ3M6IFQpID0+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGlmICh0aW1lcklkID09PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZUZ1bmMobGFzdEFyZ3MpO1xuICAgIH0gZWxzZSBpZiAob3B0cz8udHJhaWxpbmcpIHtcbiAgICAgIGxhc3RBcmdzVHJhaWxpbmcgPSBhcmdzO1xuICAgIH1cbiAgfTtcbiAgcmV0LmZsdXNoID0gKCkgPT4ge1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGFzdEFyZ3MpIHtcbiAgICAgIGZuKC4uLihsYXN0QXJnc1RyYWlsaW5nIHx8IGxhc3RBcmdzKSk7XG4gICAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0LmNhbmNlbCA9ICgpID0+IHtcbiAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2Jsb2IvZXMvY2h1bmsuanNcbmV4cG9ydCBjb25zdCBjaHVuayA9IDxUIGV4dGVuZHMgYW55PihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgc2l6ZTogbnVtYmVyLFxuKTogVFtdW10gPT4ge1xuICBpZiAoIWFycmF5Lmxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgcmVzSW5kZXggPSAwO1xuICBjb25zdCByZXN1bHQgPSBBcnJheShNYXRoLmNlaWwoYXJyYXkubGVuZ3RoIC8gc2l6ZSkpO1xuICB3aGlsZSAoaW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBhcnJheS5zbGljZShpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGUgPSAobm9kZTogRWxlbWVudCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlU2VsZWN0aW9uID0gKCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZSA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gTWF0aC5hYnMoeCAtIHkpO1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQWN0aXZlVG9vbCA9IChcbiAgYXBwU3RhdGU6IFBpY2s8QXBwU3RhdGUsIFwiYWN0aXZlVG9vbFwiPixcbiAgZGF0YTogKFxuICAgIHwgeyB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfVxuICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfVxuICApICYgeyBsYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcj86IExhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyIH0sXG4pOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0gPT4ge1xuICBpZiAoZGF0YS50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgY3VzdG9tVHlwZTogZGF0YS5jdXN0b21UeXBlLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgbGFzdEFjdGl2ZVRvb2xCZWZvcmVFcmFzZXI6XG4gICAgICBkYXRhLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyID09PSB1bmRlZmluZWRcbiAgICAgICAgPyBhcHBTdGF0ZS5hY3RpdmVUb29sLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyXG4gICAgICAgIDogZGF0YS5sYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcixcbiAgICB0eXBlOiBkYXRhLnR5cGUsXG4gICAgY3VzdG9tVHlwZTogbnVsbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZXNldEN1cnNvciA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBpZiAoY2FudmFzKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IFwiXCI7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRDdXJzb3IgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsIGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gIGlmIChjYW52YXMpIHtcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xuICB9XG59O1xuXG5sZXQgZXJhc2VyQ2FudmFzQ2FjaGU6IGFueTtcbmxldCBwcmV2aWV3RGF0YVVSTDogc3RyaW5nO1xuZXhwb3J0IGNvbnN0IHNldEVyYXNlckN1cnNvciA9IChcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsXG4gIHRoZW1lOiBBcHBTdGF0ZVtcInRoZW1lXCJdLFxuKSA9PiB7XG4gIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gMjA7XG5cbiAgY29uc3QgZHJhd0NhbnZhcyA9ICgpID0+IHtcbiAgICBjb25zdCBpc0RhcmtUaGVtZSA9IHRoZW1lID09PSBUSEVNRS5EQVJLO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSA9IHRoZW1lO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLmhlaWdodCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLndpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgY29uc3QgY29udGV4dCA9IGVyYXNlckNhbnZhc0NhY2hlLmdldENvbnRleHQoXCIyZFwiKSE7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAxO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5hcmMoXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS53aWR0aCAvIDIsXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS5oZWlnaHQgLyAyLFxuICAgICAgNSxcbiAgICAgIDAsXG4gICAgICAyICogTWF0aC5QSSxcbiAgICApO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gaXNEYXJrVGhlbWUgPyBvYy5ibGFjayA6IG9jLndoaXRlO1xuICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBpc0RhcmtUaGVtZSA/IG9jLndoaXRlIDogb2MuYmxhY2s7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgICBwcmV2aWV3RGF0YVVSTCA9IGVyYXNlckNhbnZhc0NhY2hlLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgfTtcbiAgaWYgKCFlcmFzZXJDYW52YXNDYWNoZSB8fCBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSAhPT0gdGhlbWUpIHtcbiAgICBkcmF3Q2FudmFzKCk7XG4gIH1cblxuICBzZXRDdXJzb3IoXG4gICAgY2FudmFzLFxuICAgIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pICR7Y3Vyc29ySW1hZ2VTaXplUHggLyAyfSAke1xuICAgICAgY3Vyc29ySW1hZ2VTaXplUHggLyAyXG4gICAgfSwgYXV0b2AsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0Q3Vyc29yRm9yU2hhcGUgPSAoXG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4pID0+IHtcbiAgaWYgKCFjYW52YXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGFwcFN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgIHJlc2V0Q3Vyc29yKGNhbnZhcyk7XG4gIH0gZWxzZSBpZiAoYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiKSB7XG4gICAgc2V0RXJhc2VyQ3Vyc29yKGNhbnZhcywgYXBwU3RhdGUudGhlbWUpO1xuICAgIC8vIGRvIG5vdGhpbmcgaWYgaW1hZ2UgdG9vbCBpcyBzZWxlY3RlZCB3aGljaCBzdWdnZXN0cyB0aGVyZSdzXG4gICAgLy8gYSBpbWFnZS1wcmV2aWV3IHNldCBhcyB0aGUgY3Vyc29yXG4gICAgLy8gSWdub3JlIGN1c3RvbSB0eXBlIGFzIHdlbGwgYW5kIGxldCBob3N0IGRlY2lkZVxuICB9IGVsc2UgaWYgKCFbXCJpbWFnZVwiLCBcImN1c3RvbVwiXS5pbmNsdWRlcyhhcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IENVUlNPUl9UWVBFLkNST1NTSEFJUjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGlzRnVsbFNjcmVlbiA9ICgpID0+XG4gIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50Py5ub2RlTmFtZSA9PT0gXCJIVE1MXCI7XG5cbmV4cG9ydCBjb25zdCBhbGxvd0Z1bGxTY3JlZW4gPSAoKSA9PlxuICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGV4aXRGdWxsU2NyZWVuID0gKCkgPT4gZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGdldFNob3J0Y3V0S2V5ID0gKHNob3J0Y3V0OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBzaG9ydGN1dCA9IHNob3J0Y3V0XG4gICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIkFsdFwiKVxuICAgIC5yZXBsYWNlKC9cXGJTaGlmdFxcYi9pLCBcIlNoaWZ0XCIpXG4gICAgLnJlcGxhY2UoL1xcYihFbnRlcnxSZXR1cm4pXFxiL2ksIFwiRW50ZXJcIilcbiAgICAucmVwbGFjZSgvXFxiRGVsXFxiL2ksIFwiRGVsZXRlXCIpO1xuXG4gIGlmIChpc0Rhcndpbikge1xuICAgIHJldHVybiBzaG9ydGN1dFxuICAgICAgLnJlcGxhY2UoL1xcYkN0cmxPckNtZFxcYi9pLCBcIkNtZFwiKVxuICAgICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIk9wdGlvblwiKTtcbiAgfVxuICByZXR1cm4gc2hvcnRjdXQucmVwbGFjZSgvXFxiQ3RybE9yQ21kXFxiL2ksIFwiQ3RybFwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMgPSAoXG4gIHsgY2xpZW50WCwgY2xpZW50WSB9OiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0sXG4gIHtcbiAgICB6b29tLFxuICAgIG9mZnNldExlZnQsXG4gICAgb2Zmc2V0VG9wLFxuICAgIHNjcm9sbFgsXG4gICAgc2Nyb2xsWSxcbiAgfToge1xuICAgIHpvb206IFpvb207XG4gICAgb2Zmc2V0TGVmdDogbnVtYmVyO1xuICAgIG9mZnNldFRvcDogbnVtYmVyO1xuICAgIHNjcm9sbFg6IG51bWJlcjtcbiAgICBzY3JvbGxZOiBudW1iZXI7XG4gIH0sXG4pID0+IHtcbiAgY29uc3QgaW52U2NhbGUgPSAxIC8gem9vbS52YWx1ZTtcbiAgY29uc3QgeCA9IChjbGllbnRYIC0gb2Zmc2V0TGVmdCkgKiBpbnZTY2FsZSAtIHNjcm9sbFg7XG4gIGNvbnN0IHkgPSAoY2xpZW50WSAtIG9mZnNldFRvcCkgKiBpbnZTY2FsZSAtIHNjcm9sbFk7XG5cbiAgcmV0dXJuIHsgeCwgeSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyA9IChcbiAgeyBzY2VuZVgsIHNjZW5lWSB9OiB7IHNjZW5lWDogbnVtYmVyOyBzY2VuZVk6IG51bWJlciB9LFxuICB7XG4gICAgem9vbSxcbiAgICBvZmZzZXRMZWZ0LFxuICAgIG9mZnNldFRvcCxcbiAgICBzY3JvbGxYLFxuICAgIHNjcm9sbFksXG4gIH06IHtcbiAgICB6b29tOiBab29tO1xuICAgIG9mZnNldExlZnQ6IG51bWJlcjtcbiAgICBvZmZzZXRUb3A6IG51bWJlcjtcbiAgICBzY3JvbGxYOiBudW1iZXI7XG4gICAgc2Nyb2xsWTogbnVtYmVyO1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IHggPSAoc2NlbmVYICsgc2Nyb2xsWCkgKiB6b29tLnZhbHVlICsgb2Zmc2V0TGVmdDtcbiAgY29uc3QgeSA9IChzY2VuZVkgKyBzY3JvbGxZKSAqIHpvb20udmFsdWUgKyBvZmZzZXRUb3A7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRHbG9iYWxDU1NWYXJpYWJsZSA9IChuYW1lOiBzdHJpbmcpID0+XG4gIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKGAtLSR7bmFtZX1gKTtcblxuY29uc3QgUlNfTFRSX0NIQVJTID1cbiAgXCJBLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyQjhcXHUwMzAwLVxcdTA1OTBcXHUwODAwLVxcdTFGRkZcIiArXG4gIFwiXFx1MkMwMC1cXHVGQjFDXFx1RkRGRS1cXHVGRTZGXFx1RkVGRC1cXHVGRkZGXCI7XG5jb25zdCBSU19SVExfQ0hBUlMgPSBcIlxcdTA1OTEtXFx1MDdGRlxcdUZCMUQtXFx1RkRGRFxcdUZFNzAtXFx1RkVGQ1wiO1xuY29uc3QgUkVfUlRMX0NIRUNLID0gbmV3IFJlZ0V4cChgXlteJHtSU19MVFJfQ0hBUlN9XSpbJHtSU19SVExfQ0hBUlN9XWApO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBmaXJzdCBkaXJlY3Rpb25hbCBjaGFyYWN0ZXIgaXMgUlRMLiBNZWFuaW5nIHdoZXRoZXIgaXQgc3RhcnRzXG4gKiAgd2l0aCBSVEwgY2hhcmFjdGVycywgb3IgaW5kZXRlcm1pbmF0ZSAobnVtYmVycyBldGMuKSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5XG4gKiAgUlRMLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC8xNzIyI2Rpc2N1c3Npb25fcjQzNjM0MDE3MVxuICovXG5leHBvcnQgY29uc3QgaXNSVEwgPSAodGV4dDogc3RyaW5nKSA9PiBSRV9SVExfQ0hFQ0sudGVzdCh0ZXh0KTtcblxuZXhwb3J0IGNvbnN0IHR1cGxlVG9Db29ycyA9IChcbiAgeHlUdXBsZTogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXSxcbik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XG4gIGNvbnN0IFt4LCB5XSA9IHh5VHVwbGU7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbi8qKiB1c2UgYXMgYSByZWplY3Rpb25IYW5kbGVyIHRvIG11dGUgZmlsZXN5c3RlbSBBYm9ydCBlcnJvcnMgKi9cbmV4cG9ydCBjb25zdCBtdXRlRlNBYm9ydEVycm9yID0gKGVycm9yPzogRXJyb3IpID0+IHtcbiAgaWYgKGVycm9yPy5uYW1lID09PSBcIkFib3J0RXJyb3JcIikge1xuICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRocm93IGVycm9yO1xufTtcblxuZXhwb3J0IGNvbnN0IGZpbmRJbmRleCA9IDxUPihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgY2I6IChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyLCBhcnJheTogcmVhZG9ubHkgVFtdKSA9PiBib29sZWFuLFxuICBmcm9tSW5kZXg6IG51bWJlciA9IDAsXG4pID0+IHtcbiAgaWYgKGZyb21JbmRleCA8IDApIHtcbiAgICBmcm9tSW5kZXggPSBhcnJheS5sZW5ndGggKyBmcm9tSW5kZXg7XG4gIH1cbiAgZnJvbUluZGV4ID0gTWF0aC5taW4oYXJyYXkubGVuZ3RoLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4IC0gMTtcbiAgd2hpbGUgKCsraW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICBpZiAoY2IoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbmV4cG9ydCBjb25zdCBmaW5kTGFzdEluZGV4ID0gPFQ+KFxuICBhcnJheTogcmVhZG9ubHkgVFtdLFxuICBjYjogKGVsZW1lbnQ6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiByZWFkb25seSBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleDogbnVtYmVyID0gYXJyYXkubGVuZ3RoIC0gMSxcbikgPT4ge1xuICBpZiAoZnJvbUluZGV4IDwgMCkge1xuICAgIGZyb21JbmRleCA9IGFycmF5Lmxlbmd0aCArIGZyb21JbmRleDtcbiAgfVxuICBmcm9tSW5kZXggPSBNYXRoLm1pbihhcnJheS5sZW5ndGggLSAxLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4ICsgMTtcbiAgd2hpbGUgKC0taW5kZXggPiAtMSkge1xuICAgIGlmIChjYihhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzVHJhbnNwYXJlbnQgPSAoY29sb3I6IHN0cmluZykgPT4ge1xuICBjb25zdCBpc1JHQlRyYW5zcGFyZW50ID0gY29sb3IubGVuZ3RoID09PSA1ICYmIGNvbG9yLnN1YnN0cig0LCAxKSA9PT0gXCIwXCI7XG4gIGNvbnN0IGlzUlJHR0JCVHJhbnNwYXJlbnQgPSBjb2xvci5sZW5ndGggPT09IDkgJiYgY29sb3Iuc3Vic3RyKDcsIDIpID09PSBcIjAwXCI7XG4gIHJldHVybiAoXG4gICAgaXNSR0JUcmFuc3BhcmVudCB8fFxuICAgIGlzUlJHR0JCVHJhbnNwYXJlbnQgfHxcbiAgICBjb2xvciA9PT0gY29sb3JzLmVsZW1lbnRCYWNrZ3JvdW5kWzBdXG4gICk7XG59O1xuXG5leHBvcnQgdHlwZSBSZXNvbHZhYmxlUHJvbWlzZTxUPiA9IFByb21pc2U8VD4gJiB7XG4gIHJlc29sdmU6IFtUXSBleHRlbmRzIFt1bmRlZmluZWRdID8gKHZhbHVlPzogVCkgPT4gdm9pZCA6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufTtcbmV4cG9ydCBjb25zdCByZXNvbHZhYmxlUHJvbWlzZSA9IDxUPigpID0+IHtcbiAgbGV0IHJlc29sdmUhOiBhbnk7XG4gIGxldCByZWplY3QhOiBhbnk7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgcmVqZWN0ID0gX3JlamVjdDtcbiAgfSk7XG4gIChwcm9taXNlIGFzIGFueSkucmVzb2x2ZSA9IHJlc29sdmU7XG4gIChwcm9taXNlIGFzIGFueSkucmVqZWN0ID0gcmVqZWN0O1xuICByZXR1cm4gcHJvbWlzZSBhcyBSZXNvbHZhYmxlUHJvbWlzZTxUPjtcbn07XG5cbi8qKlxuICogQHBhcmFtIGZ1bmMgaGFuZGxlciB0YWtpbmcgYXQgbW9zdCBzaW5nbGUgcGFyYW1ldGVyIChldmVudCkuXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXMgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PlxuICAoKGV2ZW50KSA9PiB7XG4gICAgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMoZnVuYyBhcyBURnVuY3Rpb24sIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uO1xuXG4vKipcbiAqIGJhcmNoZXMgUmVhY3Qgc3RhdGUgdXBkYXRlcyBhbmQgdGhyb3R0bGVzIHRoZSBjYWxscyB0byBhIHNpbmdsZSBjYWxsIHBlclxuICogYW5pbWF0aW9uIGZyYW1lXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PiB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIHRocm90dGxlUkFGPFBhcmFtZXRlcnM8VEZ1bmN0aW9uPj4oKChldmVudCkgPT4ge1xuICAgIHVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzKGZ1bmMsIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uKTtcbn07XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzk0NjIzODIvODQxOFxuZXhwb3J0IGNvbnN0IG5Gb3JtYXR0ZXIgPSAobnVtOiBudW1iZXIsIGRpZ2l0czogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2kgPSBbXG4gICAgeyB2YWx1ZTogMSwgc3ltYm9sOiBcImJcIiB9LFxuICAgIHsgdmFsdWU6IDFlMywgc3ltYm9sOiBcImtcIiB9LFxuICAgIHsgdmFsdWU6IDFlNiwgc3ltYm9sOiBcIk1cIiB9LFxuICAgIHsgdmFsdWU6IDFlOSwgc3ltYm9sOiBcIkdcIiB9LFxuICBdO1xuICBjb25zdCByeCA9IC9cXC4wKyR8KFxcLlswLTldKlsxLTldKTArJC87XG4gIGxldCBpbmRleDtcbiAgZm9yIChpbmRleCA9IHNpLmxlbmd0aCAtIDE7IGluZGV4ID4gMDsgaW5kZXgtLSkge1xuICAgIGlmIChudW0gPj0gc2lbaW5kZXhdLnZhbHVlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChcbiAgICAobnVtIC8gc2lbaW5kZXhdLnZhbHVlKS50b0ZpeGVkKGRpZ2l0cykucmVwbGFjZShyeCwgXCIkMVwiKSArIHNpW2luZGV4XS5zeW1ib2xcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRWZXJzaW9uID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTE1ldGFFbGVtZW50PignbWV0YVtuYW1lPVwidmVyc2lvblwiXScpPy5jb250ZW50IHx8XG4gICAgREVGQVVMVF9WRVJTSU9OXG4gICk7XG59O1xuXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2Vtb2ppLmpzXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNFbW9qaSA9ICgpID0+IHtcbiAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgaWYgKCFjdHgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgb2Zmc2V0ID0gMTI7XG4gIGN0eC5maWxsU3R5bGUgPSBcIiNmMDBcIjtcbiAgY3R4LnRleHRCYXNlbGluZSA9IFwidG9wXCI7XG4gIGN0eC5mb250ID0gXCIzMnB4IEFyaWFsXCI7XG4gIC8vIE1vZGVybml6ciB1c2VkIPCfkKgsIGJ1dCBpdCBpcyBzb3J0IG9mIHN1cHBvcnRlZCBvbiBXaW5kb3dzIDcuXG4gIC8vIEx1Y2tpbHkg8J+YgCBpc24ndCBzdXBwb3J0ZWQuXG4gIGN0eC5maWxsVGV4dChcIvCfmIBcIiwgMCwgMCk7XG4gIHJldHVybiBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldCwgb2Zmc2V0LCAxLCAxKS5kYXRhWzBdICE9PSAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbik6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgcmV0dXJuIGRvY3VtZW50O1xuICAgIH1cbiAgICBjb25zdCB7IG92ZXJmbG93WSB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcbiAgICBjb25zdCBoYXNTY3JvbGxhYmxlQ29udGVudCA9IHBhcmVudC5zY3JvbGxIZWlnaHQgPiBwYXJlbnQuY2xpZW50SGVpZ2h0O1xuICAgIGlmIChcbiAgICAgIGhhc1Njcm9sbGFibGVDb250ZW50ICYmXG4gICAgICAob3ZlcmZsb3dZID09PSBcImF1dG9cIiB8fFxuICAgICAgICBvdmVyZmxvd1kgPT09IFwic2Nyb2xsXCIgfHxcbiAgICAgICAgb3ZlcmZsb3dZID09PSBcIm92ZXJsYXlcIilcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudDtcbn07XG5cbmV4cG9ydCBjb25zdCBmb2N1c05lYXJlc3RQYXJlbnQgPSAoZWxlbWVudDogSFRNTElucHV0RWxlbWVudCkgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC50YWJJbmRleCA+IC0xKSB7XG4gICAgICBwYXJlbnQuZm9jdXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwcmV2ZW50VW5sb2FkID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4ge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAvLyBOT1RFOiBtb2Rlcm4gYnJvd3NlcnMgbm8gbG9uZ2VyIGFsbG93IHNob3dpbmcgYSBjdXN0b20gbWVzc2FnZSBoZXJlXG4gIGV2ZW50LnJldHVyblZhbHVlID0gXCJcIjtcbn07XG5cbmV4cG9ydCBjb25zdCBieXRlc1RvSGV4U3RyaW5nID0gKGJ5dGVzOiBVaW50OEFycmF5KSA9PiB7XG4gIHJldHVybiBBcnJheS5mcm9tKGJ5dGVzKVxuICAgIC5tYXAoKGJ5dGUpID0+IGAwJHtieXRlLnRvU3RyaW5nKDE2KX1gLnNsaWNlKC0yKSlcbiAgICAuam9pbihcIlwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVcGRhdGVkVGltZXN0YW1wID0gKCkgPT4gKGlzVGVzdEVudigpID8gMSA6IERhdGUubm93KCkpO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIGBpZGAgYXR0cmlidXRlLFxuICogb3IgYXJyYXkgb2YgaWRzIChzdHJpbmdzKSwgaW50byBhIE1hcCwga2V5ZCBieSBgaWRgLlxuICovXG5leHBvcnQgY29uc3QgYXJyYXlUb01hcCA9IDxUIGV4dGVuZHMgeyBpZDogc3RyaW5nIH0gfCBzdHJpbmc+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuKSA9PiB7XG4gIHJldHVybiBpdGVtcy5yZWR1Y2UoKGFjYzogTWFwPHN0cmluZywgVD4sIGVsZW1lbnQpID0+IHtcbiAgICBhY2Muc2V0KHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiID8gZWxlbWVudCA6IGVsZW1lbnQuaWQsIGVsZW1lbnQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIG5ldyBNYXAoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgaXNUZXN0RW52ID0gKCkgPT5cbiAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy5lbnY/Lk5PREVfRU5WID09PSBcInRlc3RcIjtcblxuZXhwb3J0IGNvbnN0IGlzUHJvZEVudiA9ICgpID0+XG4gIHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52Py5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCI7XG5cbmV4cG9ydCBjb25zdCB3cmFwRXZlbnQgPSA8VCBleHRlbmRzIEV2ZW50PihuYW1lOiBFVkVOVCwgbmF0aXZlRXZlbnQ6IFQpID0+IHtcbiAgcmV0dXJuIG5ldyBDdXN0b21FdmVudChuYW1lLCB7XG4gICAgZGV0YWlsOiB7XG4gICAgICBuYXRpdmVFdmVudCxcbiAgICB9LFxuICAgIGNhbmNlbGFibGU6IHRydWUsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZU9iamVjdCA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIG9iajogVCxcbiAgdXBkYXRlczogUGFydGlhbDxUPixcbik6IFQgPT4ge1xuICBsZXQgZGlkQ2hhbmdlID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9ICh1cGRhdGVzIGFzIGFueSlba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvYmogYXMgYW55KVtrZXldID09PSB2YWx1ZSAmJlxuICAgICAgICAvLyBpZiBvYmplY3QsIGFsd2F5cyB1cGRhdGUgYmVjYXVzZSBpdHMgYXR0cnMgY291bGQgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgdmFsdWUgPT09IG51bGwpXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4ub2JqLFxuICAgIC4uLnVwZGF0ZXMsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcmltaXRpdmUgPSAodmFsOiBhbnkpID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCAodHlwZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlICE9PSBcImZ1bmN0aW9uXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEZyYW1lID0gKCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuc2VsZiA9PT0gd2luZG93LnRvcCA/IFwidG9wXCIgOiBcImlmcmFtZVwiO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBcImlmcmFtZVwiO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcm9taXNlTGlrZSA9IChcbiAgdmFsdWU6IGFueSxcbik6IHZhbHVlIGlzIFByb21pc2U8UmVzb2x1dGlvblR5cGU8dHlwZW9mIHZhbHVlPj4gPT4ge1xuICByZXR1cm4gKFxuICAgICEhdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcInRoZW5cIiBpbiB2YWx1ZSAmJlxuICAgIFwiY2F0Y2hcIiBpbiB2YWx1ZSAmJlxuICAgIFwiZmluYWxseVwiIGluIHZhbHVlXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcXVlcnlGb2N1c2FibGVFbGVtZW50cyA9IChjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oXG4gICAgXCJidXR0b24sIGEsIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBkaXZbdGFiaW5kZXhdLCBsYWJlbFt0YWJpbmRleF1cIixcbiAgKTtcblxuICByZXR1cm4gZm9jdXNhYmxlRWxlbWVudHNcbiAgICA/IEFycmF5LmZyb20oZm9jdXNhYmxlRWxlbWVudHMpLmZpbHRlcihcbiAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgZWxlbWVudC50YWJJbmRleCA+IC0xICYmICEoZWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50KS5kaXNhYmxlZCxcbiAgICAgIClcbiAgICA6IFtdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../utils.ts\n");
3352
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"allowFullScreen\": () => (/* binding */ allowFullScreen),\n/* harmony export */ \"arrayToMap\": () => (/* binding */ arrayToMap),\n/* harmony export */ \"bytesToHexString\": () => (/* binding */ bytesToHexString),\n/* harmony export */ \"capitalizeString\": () => (/* binding */ capitalizeString),\n/* harmony export */ \"chunk\": () => (/* binding */ chunk),\n/* harmony export */ \"debounce\": () => (/* binding */ debounce),\n/* harmony export */ \"distance\": () => (/* binding */ distance),\n/* harmony export */ \"exitFullScreen\": () => (/* binding */ exitFullScreen),\n/* harmony export */ \"findIndex\": () => (/* binding */ findIndex),\n/* harmony export */ \"findLastIndex\": () => (/* binding */ findLastIndex),\n/* harmony export */ \"focusNearestParent\": () => (/* binding */ focusNearestParent),\n/* harmony export */ \"getDateTime\": () => (/* binding */ getDateTime),\n/* harmony export */ \"getFontFamilyString\": () => (/* binding */ getFontFamilyString),\n/* harmony export */ \"getFontString\": () => (/* binding */ getFontString),\n/* harmony export */ \"getFrame\": () => (/* binding */ getFrame),\n/* harmony export */ \"getGlobalCSSVariable\": () => (/* binding */ getGlobalCSSVariable),\n/* harmony export */ \"getNearestScrollableContainer\": () => (/* binding */ getNearestScrollableContainer),\n/* harmony export */ \"getShortcutKey\": () => (/* binding */ getShortcutKey),\n/* harmony export */ \"getUpdatedTimestamp\": () => (/* binding */ getUpdatedTimestamp),\n/* harmony export */ \"getVersion\": () => (/* binding */ getVersion),\n/* harmony export */ \"isFullScreen\": () => (/* binding */ isFullScreen),\n/* harmony export */ \"isInputLike\": () => (/* binding */ isInputLike),\n/* harmony export */ \"isPrimitive\": () => (/* binding */ isPrimitive),\n/* harmony export */ \"isProdEnv\": () => (/* binding */ isProdEnv),\n/* harmony export */ \"isPromiseLike\": () => (/* binding */ isPromiseLike),\n/* harmony export */ \"isRTL\": () => (/* binding */ isRTL),\n/* harmony export */ \"isTestEnv\": () => (/* binding */ isTestEnv),\n/* harmony export */ \"isToolIcon\": () => (/* binding */ isToolIcon),\n/* harmony export */ \"isTransparent\": () => (/* binding */ isTransparent),\n/* harmony export */ \"isWritableElement\": () => (/* binding */ isWritableElement),\n/* harmony export */ \"muteFSAbortError\": () => (/* binding */ muteFSAbortError),\n/* harmony export */ \"nFormatter\": () => (/* binding */ nFormatter),\n/* harmony export */ \"preventUnload\": () => (/* binding */ preventUnload),\n/* harmony export */ \"queryFocusableElements\": () => (/* binding */ queryFocusableElements),\n/* harmony export */ \"removeSelection\": () => (/* binding */ removeSelection),\n/* harmony export */ \"resetCursor\": () => (/* binding */ resetCursor),\n/* harmony export */ \"resolvablePromise\": () => (/* binding */ resolvablePromise),\n/* harmony export */ \"sceneCoordsToViewportCoords\": () => (/* binding */ sceneCoordsToViewportCoords),\n/* harmony export */ \"selectNode\": () => (/* binding */ selectNode),\n/* harmony export */ \"setCursor\": () => (/* binding */ setCursor),\n/* harmony export */ \"setCursorForShape\": () => (/* binding */ setCursorForShape),\n/* harmony export */ \"setDateTimeForTests\": () => (/* binding */ setDateTimeForTests),\n/* harmony export */ \"setEraserCursor\": () => (/* binding */ setEraserCursor),\n/* harmony export */ \"supportsEmoji\": () => (/* binding */ supportsEmoji),\n/* harmony export */ \"throttleRAF\": () => (/* binding */ throttleRAF),\n/* harmony export */ \"tupleToCoors\": () => (/* binding */ tupleToCoors),\n/* harmony export */ \"updateActiveTool\": () => (/* binding */ updateActiveTool),\n/* harmony export */ \"updateObject\": () => (/* binding */ updateObject),\n/* harmony export */ \"viewportCoordsToSceneCoords\": () => (/* binding */ viewportCoordsToSceneCoords),\n/* harmony export */ \"withBatchedUpdates\": () => (/* binding */ withBatchedUpdates),\n/* harmony export */ \"withBatchedUpdatesThrottled\": () => (/* binding */ withBatchedUpdatesThrottled),\n/* harmony export */ \"wrapEvent\": () => (/* binding */ wrapEvent)\n/* harmony export */ });\n/* harmony import */ var open_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! open-color */ \"../../../node_modules/open-color/open-color.json\");\n/* harmony import */ var _colors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colors */ \"../../colors.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ \"../../constants.ts\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-dom */ \"react-dom\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./keys */ \"../../keys.ts\");\n\n\n\n\n\nlet mockDateTime = null;\nconst setDateTimeForTests = (dateTime) => {\n mockDateTime = dateTime;\n};\nconst getDateTime = () => {\n if (mockDateTime) {\n return mockDateTime;\n }\n const date = new Date();\n const year = date.getFullYear();\n const month = `${date.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${date.getDate()}`.padStart(2, \"0\");\n const hr = `${date.getHours()}`.padStart(2, \"0\");\n const min = `${date.getMinutes()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}-${hr}${min}`;\n};\nconst capitalizeString = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst isToolIcon = (target) => target instanceof HTMLElement && target.className.includes(\"ToolIcon\");\nconst isInputLike = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement;\nconst isWritableElement = (target) => (target instanceof HTMLElement && target.dataset.type === \"wysiwyg\") ||\n target instanceof HTMLBRElement || // newline in wysiwyg\n target instanceof HTMLTextAreaElement ||\n (target instanceof HTMLInputElement &&\n (target.type === \"text\" || target.type === \"number\"));\nconst getFontFamilyString = ({ fontFamily, }) => {\n for (const [fontFamilyString, id] of Object.entries(_constants__WEBPACK_IMPORTED_MODULE_2__.FONT_FAMILY)) {\n if (id === fontFamily) {\n return `${fontFamilyString}, ${_constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT}`;\n }\n }\n return _constants__WEBPACK_IMPORTED_MODULE_2__.WINDOWS_EMOJI_FALLBACK_FONT;\n};\n/** returns fontSize+fontFamily string for assignment to DOM elements */\nconst getFontString = ({ fontSize, fontFamily, }) => {\n return `${fontSize}px ${getFontFamilyString({ fontFamily })}`;\n};\nconst debounce = (fn, timeout) => {\n let handle = 0;\n let lastArgs = null;\n const ret = (...args) => {\n lastArgs = args;\n clearTimeout(handle);\n handle = window.setTimeout(() => {\n lastArgs = null;\n fn(...args);\n }, timeout);\n };\n ret.flush = () => {\n clearTimeout(handle);\n if (lastArgs) {\n const _lastArgs = lastArgs;\n lastArgs = null;\n fn(..._lastArgs);\n }\n };\n ret.cancel = () => {\n lastArgs = null;\n clearTimeout(handle);\n };\n return ret;\n};\n// throttle callback to execute once per animation frame\nconst throttleRAF = (fn, opts) => {\n let timerId = null;\n let lastArgs = null;\n let lastArgsTrailing = null;\n const scheduleFunc = (args) => {\n timerId = window.requestAnimationFrame(() => {\n timerId = null;\n fn(...args);\n lastArgs = null;\n if (lastArgsTrailing) {\n lastArgs = lastArgsTrailing;\n lastArgsTrailing = null;\n scheduleFunc(lastArgs);\n }\n });\n };\n const ret = (...args) => {\n if (false) {}\n lastArgs = args;\n if (timerId === null) {\n scheduleFunc(lastArgs);\n }\n else if (opts === null || opts === void 0 ? void 0 : opts.trailing) {\n lastArgsTrailing = args;\n }\n };\n ret.flush = () => {\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n if (lastArgs) {\n fn(...(lastArgsTrailing || lastArgs));\n lastArgs = lastArgsTrailing = null;\n }\n };\n ret.cancel = () => {\n lastArgs = lastArgsTrailing = null;\n if (timerId !== null) {\n cancelAnimationFrame(timerId);\n timerId = null;\n }\n };\n return ret;\n};\n// https://github.com/lodash/lodash/blob/es/chunk.js\nconst chunk = (array, size) => {\n if (!array.length || size < 1) {\n return [];\n }\n let index = 0;\n let resIndex = 0;\n const result = Array(Math.ceil(array.length / size));\n while (index < array.length) {\n result[resIndex++] = array.slice(index, (index += size));\n }\n return result;\n};\nconst selectNode = (node) => {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(node);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n};\nconst removeSelection = () => {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n }\n};\nconst distance = (x, y) => Math.abs(x - y);\nconst updateActiveTool = (appState, data) => {\n if (data.type === \"custom\") {\n return Object.assign(Object.assign({}, appState.activeTool), { type: \"custom\", customType: data.customType });\n }\n return Object.assign(Object.assign({}, appState.activeTool), { lastActiveToolBeforeEraser: data.lastActiveToolBeforeEraser === undefined\n ? appState.activeTool.lastActiveToolBeforeEraser\n : data.lastActiveToolBeforeEraser, type: data.type, customType: null });\n};\nconst resetCursor = (canvas) => {\n if (canvas) {\n canvas.style.cursor = \"\";\n }\n};\nconst setCursor = (canvas, cursor) => {\n if (canvas) {\n canvas.style.cursor = cursor;\n }\n};\nlet eraserCanvasCache;\nlet previewDataURL;\nconst setEraserCursor = (canvas, theme) => {\n const cursorImageSizePx = 20;\n const drawCanvas = () => {\n const isDarkTheme = theme === _constants__WEBPACK_IMPORTED_MODULE_2__.THEME.DARK;\n eraserCanvasCache = document.createElement(\"canvas\");\n eraserCanvasCache.theme = theme;\n eraserCanvasCache.height = cursorImageSizePx;\n eraserCanvasCache.width = cursorImageSizePx;\n const context = eraserCanvasCache.getContext(\"2d\");\n context.lineWidth = 1;\n context.beginPath();\n context.arc(eraserCanvasCache.width / 2, eraserCanvasCache.height / 2, 5, 0, 2 * Math.PI);\n context.fillStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.black : open_color__WEBPACK_IMPORTED_MODULE_0__.white;\n context.fill();\n context.strokeStyle = isDarkTheme ? open_color__WEBPACK_IMPORTED_MODULE_0__.white : open_color__WEBPACK_IMPORTED_MODULE_0__.black;\n context.stroke();\n previewDataURL = eraserCanvasCache.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_2__.MIME_TYPES.svg);\n };\n if (!eraserCanvasCache || eraserCanvasCache.theme !== theme) {\n drawCanvas();\n }\n setCursor(canvas, `url(${previewDataURL}) ${cursorImageSizePx / 2} ${cursorImageSizePx / 2}, auto`);\n};\nconst setCursorForShape = (canvas, appState) => {\n if (!canvas) {\n return;\n }\n if (appState.activeTool.type === \"selection\") {\n resetCursor(canvas);\n }\n else if (appState.activeTool.type === \"eraser\") {\n setEraserCursor(canvas, appState.theme);\n // do nothing if image tool is selected which suggests there's\n // a image-preview set as the cursor\n // Ignore custom type as well and let host decide\n }\n else if (![\"image\", \"custom\"].includes(appState.activeTool.type)) {\n canvas.style.cursor = _constants__WEBPACK_IMPORTED_MODULE_2__.CURSOR_TYPE.CROSSHAIR;\n }\n};\nconst isFullScreen = () => { var _a; return ((_a = document.fullscreenElement) === null || _a === void 0 ? void 0 : _a.nodeName) === \"HTML\"; };\nconst allowFullScreen = () => document.documentElement.requestFullscreen();\nconst exitFullScreen = () => document.exitFullscreen();\nconst getShortcutKey = (shortcut) => {\n shortcut = shortcut\n .replace(/\\bAlt\\b/i, \"Alt\")\n .replace(/\\bShift\\b/i, \"Shift\")\n .replace(/\\b(Enter|Return)\\b/i, \"Enter\")\n .replace(/\\bDel\\b/i, \"Delete\");\n if (_keys__WEBPACK_IMPORTED_MODULE_4__.isDarwin) {\n return shortcut\n .replace(/\\bCtrlOrCmd\\b/i, \"Cmd\")\n .replace(/\\bAlt\\b/i, \"Option\");\n }\n return shortcut.replace(/\\bCtrlOrCmd\\b/i, \"Ctrl\");\n};\nconst viewportCoordsToSceneCoords = ({ clientX, clientY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const invScale = 1 / zoom.value;\n const x = (clientX - offsetLeft) * invScale - scrollX;\n const y = (clientY - offsetTop) * invScale - scrollY;\n return { x, y };\n};\nconst sceneCoordsToViewportCoords = ({ sceneX, sceneY }, { zoom, offsetLeft, offsetTop, scrollX, scrollY, }) => {\n const x = (sceneX + scrollX) * zoom.value + offsetLeft;\n const y = (sceneY + scrollY) * zoom.value + offsetTop;\n return { x, y };\n};\nconst getGlobalCSSVariable = (name) => getComputedStyle(document.documentElement).getPropertyValue(`--${name}`);\nconst RS_LTR_CHARS = \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\" +\n \"\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF\";\nconst RS_RTL_CHARS = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst RE_RTL_CHECK = new RegExp(`^[^${RS_LTR_CHARS}]*[${RS_RTL_CHARS}]`);\n/**\n * Checks whether first directional character is RTL. Meaning whether it starts\n * with RTL characters, or indeterminate (numbers etc.) characters followed by\n * RTL.\n * See https://github.com/excalidraw/excalidraw/pull/1722#discussion_r436340171\n */\nconst isRTL = (text) => RE_RTL_CHECK.test(text);\nconst tupleToCoors = (xyTuple) => {\n const [x, y] = xyTuple;\n return { x, y };\n};\n/** use as a rejectionHandler to mute filesystem Abort errors */\nconst muteFSAbortError = (error) => {\n if ((error === null || error === void 0 ? void 0 : error.name) === \"AbortError\") {\n console.warn(error);\n return;\n }\n throw error;\n};\nconst findIndex = (array, cb, fromIndex = 0) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length, Math.max(fromIndex, 0));\n let index = fromIndex - 1;\n while (++index < array.length) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst findLastIndex = (array, cb, fromIndex = array.length - 1) => {\n if (fromIndex < 0) {\n fromIndex = array.length + fromIndex;\n }\n fromIndex = Math.min(array.length - 1, Math.max(fromIndex, 0));\n let index = fromIndex + 1;\n while (--index > -1) {\n if (cb(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\nconst isTransparent = (color) => {\n const isRGBTransparent = color.length === 5 && color.substr(4, 1) === \"0\";\n const isRRGGBBTransparent = color.length === 9 && color.substr(7, 2) === \"00\";\n return (isRGBTransparent ||\n isRRGGBBTransparent ||\n color === _colors__WEBPACK_IMPORTED_MODULE_1__[\"default\"].elementBackground[0]);\n};\nconst resolvablePromise = () => {\n let resolve;\n let reject;\n const promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n promise.resolve = resolve;\n promise.reject = reject;\n return promise;\n};\n/**\n * @param func handler taking at most single parameter (event).\n */\nconst withBatchedUpdates = (func) => ((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n});\n/**\n * barches React state updates and throttles the calls to a single call per\n * animation frame\n */\nconst withBatchedUpdatesThrottled = (func) => {\n // @ts-ignore\n return throttleRAF(((event) => {\n (0,react_dom__WEBPACK_IMPORTED_MODULE_3__.unstable_batchedUpdates)(func, event);\n }));\n};\n//https://stackoverflow.com/a/9462382/8418\nconst nFormatter = (num, digits) => {\n const si = [\n { value: 1, symbol: \"b\" },\n { value: 1e3, symbol: \"k\" },\n { value: 1e6, symbol: \"M\" },\n { value: 1e9, symbol: \"G\" },\n ];\n const rx = /\\.0+$|(\\.[0-9]*[1-9])0+$/;\n let index;\n for (index = si.length - 1; index > 0; index--) {\n if (num >= si[index].value) {\n break;\n }\n }\n return ((num / si[index].value).toFixed(digits).replace(rx, \"$1\") + si[index].symbol);\n};\nconst getVersion = () => {\n var _a;\n return (((_a = document.querySelector('meta[name=\"version\"]')) === null || _a === void 0 ? void 0 : _a.content) ||\n _constants__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_VERSION);\n};\n// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js\nconst supportsEmoji = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return false;\n }\n const offset = 12;\n ctx.fillStyle = \"#f00\";\n ctx.textBaseline = \"top\";\n ctx.font = \"32px Arial\";\n // Modernizr used 🐨, but it is sort of supported on Windows 7.\n // Luckily 😀 isn't supported.\n ctx.fillText(\"😀\", 0, 0);\n return ctx.getImageData(offset, offset, 1, 1).data[0] !== 0;\n};\nconst getNearestScrollableContainer = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent === document.body) {\n return document;\n }\n const { overflowY } = window.getComputedStyle(parent);\n const hasScrollableContent = parent.scrollHeight > parent.clientHeight;\n if (hasScrollableContent &&\n (overflowY === \"auto\" ||\n overflowY === \"scroll\" ||\n overflowY === \"overlay\")) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return document;\n};\nconst focusNearestParent = (element) => {\n let parent = element.parentElement;\n while (parent) {\n if (parent.tabIndex > -1) {\n parent.focus();\n return;\n }\n parent = parent.parentElement;\n }\n};\nconst preventUnload = (event) => {\n event.preventDefault();\n // NOTE: modern browsers no longer allow showing a custom message here\n event.returnValue = \"\";\n};\nconst bytesToHexString = (bytes) => {\n return Array.from(bytes)\n .map((byte) => `0${byte.toString(16)}`.slice(-2))\n .join(\"\");\n};\nconst getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());\n/**\n * Transforms array of objects containing `id` attribute,\n * or array of ids (strings), into a Map, keyd by `id`.\n */\nconst arrayToMap = (items) => {\n return items.reduce((acc, element) => {\n acc.set(typeof element === \"string\" ? element : element.id, element);\n return acc;\n }, new Map());\n};\nconst isTestEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"test\"; };\nconst isProdEnv = () => { var _a; return typeof process !== \"undefined\" && ((_a = ({\"REACT_APP_BACKEND_V2_GET_URL\":\"https://json-dev.excalidraw.com/api/v2/\",\"REACT_APP_BACKEND_V2_POST_URL\":\"https://json-dev.excalidraw.com/api/v2/post/\",\"REACT_APP_LIBRARY_URL\":\"https://libraries.excalidraw.com\",\"REACT_APP_LIBRARY_BACKEND\":\"https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries\",\"REACT_APP_WS_SERVER_URL\":\"http://localhost:3002\",\"REACT_APP_PORTAL_URL\":\"\",\"REACT_APP_FIREBASE_CONFIG\":\"{\\\"apiKey\\\":\\\"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8\\\",\\\"authDomain\\\":\\\"excalidraw-oss-dev.firebaseapp.com\\\",\\\"projectId\\\":\\\"excalidraw-oss-dev\\\",\\\"storageBucket\\\":\\\"excalidraw-oss-dev.appspot.com\\\",\\\"messagingSenderId\\\":\\\"664559512677\\\",\\\"appId\\\":\\\"1:664559512677:web:a385181f2928d328a7aa8c\\\"}\",\"REACT_APP_DEV_ENABLE_SW\":\"\",\"REACT_APP_DEV_DISABLE_LIVE_RELOAD\":\"\",\"PKG_NAME\":\"@excalidraw/excalidraw\",\"PKG_VERSION\":\"0.12.0-5598-d731a64\",\"IS_EXCALIDRAW_NPM_PACKAGE\":true})) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === \"production\"; };\nconst wrapEvent = (name, nativeEvent) => {\n return new CustomEvent(name, {\n detail: {\n nativeEvent,\n },\n cancelable: true,\n });\n};\nconst updateObject = (obj, updates) => {\n let didChange = false;\n for (const key in updates) {\n const value = updates[key];\n if (typeof value !== \"undefined\") {\n if (obj[key] === value &&\n // if object, always update because its attrs could have changed\n (typeof value !== \"object\" || value === null)) {\n continue;\n }\n didChange = true;\n }\n }\n if (!didChange) {\n return obj;\n }\n return Object.assign(Object.assign({}, obj), updates);\n};\nconst isPrimitive = (val) => {\n const type = typeof val;\n return val == null || (type !== \"object\" && type !== \"function\");\n};\nconst getFrame = () => {\n try {\n return window.self === window.top ? \"top\" : \"iframe\";\n }\n catch (error) {\n return \"iframe\";\n }\n};\nconst isPromiseLike = (value) => {\n return (!!value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n \"catch\" in value &&\n \"finally\" in value);\n};\nconst queryFocusableElements = (container) => {\n const focusableElements = container === null || container === void 0 ? void 0 : container.querySelectorAll(\"button, a, input, select, textarea, div[tabindex], label[tabindex]\");\n return focusableElements\n ? Array.from(focusableElements).filter((element) => element.tabIndex > -1 && !element.disabled)\n : [];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFFBQVEsSUFBSSxJQUFJLEtBQUssVUFBVSxDQUFDLENBQUM7QUFDbkUsQ0FBQyxDQUFDO0FBRUssTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUk7UUFDRixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7S0FDdEQ7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNkLE9BQU8sUUFBUSxDQUFDO0tBQ2pCO0FBQ0gsQ0FBQyxDQUFDO0FBRUssTUFBTSxhQUFhLEdBQUcsQ0FDM0IsS0FBVSxFQUNzQyxFQUFFO0lBQ2xELE9BQU8sQ0FDTCxDQUFDLENBQUMsS0FBSztRQUNQLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFDekIsTUFBTSxJQUFJLEtBQUs7UUFDZixPQUFPLElBQUksS0FBSztRQUNoQixTQUFTLElBQUksS0FBSyxDQUNuQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUssTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFNBQTZCLEVBQUUsRUFBRTtJQUN0RSxNQUFNLGlCQUFpQixHQUFHLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxnQkFBZ0IsQ0FDbkQsb0VBQW9FLENBQ3JFLENBQUM7SUFFRixPQUFPLGlCQUFpQjtRQUN0QixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FDbEMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNWLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBRSxPQUE0QixDQUFDLFFBQVEsQ0FDbkU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ1QsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL3V0aWxzLnRzPzc2M2EiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9jIGZyb20gXCJvcGVuLWNvbG9yXCI7XG5cbmltcG9ydCBjb2xvcnMgZnJvbSBcIi4vY29sb3JzXCI7XG5pbXBvcnQge1xuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9WRVJTSU9OLFxuICBFVkVOVCxcbiAgRk9OVF9GQU1JTFksXG4gIE1JTUVfVFlQRVMsXG4gIFRIRU1FLFxuICBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRm9udEZhbWlseVZhbHVlcywgRm9udFN0cmluZyB9IGZyb20gXCIuL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlLCBEYXRhVVJMLCBMYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlciwgWm9vbSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyB1bnN0YWJsZV9iYXRjaGVkVXBkYXRlcyB9IGZyb20gXCJyZWFjdC1kb21cIjtcbmltcG9ydCB7IGlzRGFyd2luIH0gZnJvbSBcIi4va2V5c1wiO1xuaW1wb3J0IHsgU0hBUEVTIH0gZnJvbSBcIi4vc2hhcGVzXCI7XG5cbmxldCBtb2NrRGF0ZVRpbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgY29uc3Qgc2V0RGF0ZVRpbWVGb3JUZXN0cyA9IChkYXRlVGltZTogc3RyaW5nKSA9PiB7XG4gIG1vY2tEYXRlVGltZSA9IGRhdGVUaW1lO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldERhdGVUaW1lID0gKCkgPT4ge1xuICBpZiAobW9ja0RhdGVUaW1lKSB7XG4gICAgcmV0dXJuIG1vY2tEYXRlVGltZTtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICBjb25zdCBtb250aCA9IGAke2RhdGUuZ2V0TW9udGgoKSArIDF9YC5wYWRTdGFydCgyLCBcIjBcIik7XG4gIGNvbnN0IGRheSA9IGAke2RhdGUuZ2V0RGF0ZSgpfWAucGFkU3RhcnQoMiwgXCIwXCIpO1xuICBjb25zdCBociA9IGAke2RhdGUuZ2V0SG91cnMoKX1gLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgY29uc3QgbWluID0gYCR7ZGF0ZS5nZXRNaW51dGVzKCl9YC5wYWRTdGFydCgyLCBcIjBcIik7XG5cbiAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fS0ke2hyfSR7bWlufWA7XG59O1xuXG5leHBvcnQgY29uc3QgY2FwaXRhbGl6ZVN0cmluZyA9IChzdHI6IHN0cmluZykgPT5cbiAgc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuXG5leHBvcnQgY29uc3QgaXNUb29sSWNvbiA9IChcbiAgdGFyZ2V0OiBFbGVtZW50IHwgRXZlbnRUYXJnZXQgfCBudWxsLFxuKTogdGFyZ2V0IGlzIEhUTUxFbGVtZW50ID0+XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIHRhcmdldC5jbGFzc05hbWUuaW5jbHVkZXMoXCJUb29sSWNvblwiKTtcblxuZXhwb3J0IGNvbnN0IGlzSW5wdXRMaWtlID0gKFxuICB0YXJnZXQ6IEVsZW1lbnQgfCBFdmVudFRhcmdldCB8IG51bGwsXG4pOiB0YXJnZXQgaXNcbiAgfCBIVE1MSW5wdXRFbGVtZW50XG4gIHwgSFRNTFRleHRBcmVhRWxlbWVudFxuICB8IEhUTUxTZWxlY3RFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCB8fFxuICB0YXJnZXQgaW5zdGFuY2VvZiBIVE1MVGV4dEFyZWFFbGVtZW50IHx8XG4gIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50O1xuXG5leHBvcnQgY29uc3QgaXNXcml0YWJsZUVsZW1lbnQgPSAoXG4gIHRhcmdldDogRWxlbWVudCB8IEV2ZW50VGFyZ2V0IHwgbnVsbCxcbik6IHRhcmdldCBpc1xuICB8IEhUTUxJbnB1dEVsZW1lbnRcbiAgfCBIVE1MVGV4dEFyZWFFbGVtZW50XG4gIHwgSFRNTEJSRWxlbWVudFxuICB8IEhUTUxEaXZFbGVtZW50ID0+XG4gICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiB0YXJnZXQuZGF0YXNldC50eXBlID09PSBcInd5c2l3eWdcIikgfHxcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTEJSRWxlbWVudCB8fCAvLyBuZXdsaW5lIGluIHd5c2l3eWdcbiAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudCB8fFxuICAodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICh0YXJnZXQudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgdGFyZ2V0LnR5cGUgPT09IFwibnVtYmVyXCIpKTtcblxuZXhwb3J0IGNvbnN0IGdldEZvbnRGYW1pbHlTdHJpbmcgPSAoe1xuICBmb250RmFtaWx5LFxufToge1xuICBmb250RmFtaWx5OiBGb250RmFtaWx5VmFsdWVzO1xufSkgPT4ge1xuICBmb3IgKGNvbnN0IFtmb250RmFtaWx5U3RyaW5nLCBpZF0gb2YgT2JqZWN0LmVudHJpZXMoRk9OVF9GQU1JTFkpKSB7XG4gICAgaWYgKGlkID09PSBmb250RmFtaWx5KSB7XG4gICAgICByZXR1cm4gYCR7Zm9udEZhbWlseVN0cmluZ30sICR7V0lORE9XU19FTU9KSV9GQUxMQkFDS19GT05UfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiBXSU5ET1dTX0VNT0pJX0ZBTExCQUNLX0ZPTlQ7XG59O1xuXG4vKiogcmV0dXJucyBmb250U2l6ZStmb250RmFtaWx5IHN0cmluZyBmb3IgYXNzaWdubWVudCB0byBET00gZWxlbWVudHMgKi9cbmV4cG9ydCBjb25zdCBnZXRGb250U3RyaW5nID0gKHtcbiAgZm9udFNpemUsXG4gIGZvbnRGYW1pbHksXG59OiB7XG4gIGZvbnRTaXplOiBudW1iZXI7XG4gIGZvbnRGYW1pbHk6IEZvbnRGYW1pbHlWYWx1ZXM7XG59KSA9PiB7XG4gIHJldHVybiBgJHtmb250U2l6ZX1weCAke2dldEZvbnRGYW1pbHlTdHJpbmcoeyBmb250RmFtaWx5IH0pfWAgYXMgRm9udFN0cmluZztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWJvdW5jZSA9IDxUIGV4dGVuZHMgYW55W10+KFxuICBmbjogKC4uLmFyZ3M6IFQpID0+IHZvaWQsXG4gIHRpbWVvdXQ6IG51bWJlcixcbikgPT4ge1xuICBsZXQgaGFuZGxlID0gMDtcbiAgbGV0IGxhc3RBcmdzOiBUIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHJldCA9ICguLi5hcmdzOiBUKSA9PiB7XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGNsZWFyVGltZW91dChoYW5kbGUpO1xuICAgIGhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLmFyZ3MpO1xuICAgIH0sIHRpbWVvdXQpO1xuICB9O1xuICByZXQuZmx1c2ggPSAoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KGhhbmRsZSk7XG4gICAgaWYgKGxhc3RBcmdzKSB7XG4gICAgICBjb25zdCBfbGFzdEFyZ3MgPSBsYXN0QXJncztcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGZuKC4uLl9sYXN0QXJncyk7XG4gICAgfVxuICB9O1xuICByZXQuY2FuY2VsID0gKCkgPT4ge1xuICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICBjbGVhclRpbWVvdXQoaGFuZGxlKTtcbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIHRocm90dGxlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lXG5leHBvcnQgY29uc3QgdGhyb3R0bGVSQUYgPSA8VCBleHRlbmRzIGFueVtdPihcbiAgZm46ICguLi5hcmdzOiBUKSA9PiB2b2lkLFxuICBvcHRzPzogeyB0cmFpbGluZz86IGJvb2xlYW4gfSxcbikgPT4ge1xuICBsZXQgdGltZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGxldCBsYXN0QXJnczogVCB8IG51bGwgPSBudWxsO1xuICBsZXQgbGFzdEFyZ3NUcmFpbGluZzogVCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHNjaGVkdWxlRnVuYyA9IChhcmdzOiBUKSA9PiB7XG4gICAgdGltZXJJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGltZXJJZCA9IG51bGw7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIGxhc3RBcmdzID0gbnVsbDtcbiAgICAgIGlmIChsYXN0QXJnc1RyYWlsaW5nKSB7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdEFyZ3NUcmFpbGluZztcbiAgICAgICAgbGFzdEFyZ3NUcmFpbGluZyA9IG51bGw7XG4gICAgICAgIHNjaGVkdWxlRnVuYyhsYXN0QXJncyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgcmV0ID0gKC4uLmFyZ3M6IFQpID0+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICBmbiguLi5hcmdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGlmICh0aW1lcklkID09PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZUZ1bmMobGFzdEFyZ3MpO1xuICAgIH0gZWxzZSBpZiAob3B0cz8udHJhaWxpbmcpIHtcbiAgICAgIGxhc3RBcmdzVHJhaWxpbmcgPSBhcmdzO1xuICAgIH1cbiAgfTtcbiAgcmV0LmZsdXNoID0gKCkgPT4ge1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGFzdEFyZ3MpIHtcbiAgICAgIGZuKC4uLihsYXN0QXJnc1RyYWlsaW5nIHx8IGxhc3RBcmdzKSk7XG4gICAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0LmNhbmNlbCA9ICgpID0+IHtcbiAgICBsYXN0QXJncyA9IGxhc3RBcmdzVHJhaWxpbmcgPSBudWxsO1xuICAgIGlmICh0aW1lcklkICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKTtcbiAgICAgIHRpbWVySWQgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9sb2Rhc2gvbG9kYXNoL2Jsb2IvZXMvY2h1bmsuanNcbmV4cG9ydCBjb25zdCBjaHVuayA9IDxUIGV4dGVuZHMgYW55PihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgc2l6ZTogbnVtYmVyLFxuKTogVFtdW10gPT4ge1xuICBpZiAoIWFycmF5Lmxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgcmVzSW5kZXggPSAwO1xuICBjb25zdCByZXN1bHQgPSBBcnJheShNYXRoLmNlaWwoYXJyYXkubGVuZ3RoIC8gc2l6ZSkpO1xuICB3aGlsZSAoaW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBhcnJheS5zbGljZShpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGUgPSAobm9kZTogRWxlbWVudCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVtb3ZlU2VsZWN0aW9uID0gKCkgPT4ge1xuICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIGlmIChzZWxlY3Rpb24pIHtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZSA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gTWF0aC5hYnMoeCAtIHkpO1xuXG5leHBvcnQgY29uc3QgdXBkYXRlQWN0aXZlVG9vbCA9IChcbiAgYXBwU3RhdGU6IFBpY2s8QXBwU3RhdGUsIFwiYWN0aXZlVG9vbFwiPixcbiAgZGF0YTogKFxuICAgIHwgeyB0eXBlOiB0eXBlb2YgU0hBUEVTW251bWJlcl1bXCJ2YWx1ZVwiXSB8IFwiZXJhc2VyXCIgfVxuICAgIHwgeyB0eXBlOiBcImN1c3RvbVwiOyBjdXN0b21UeXBlOiBzdHJpbmcgfVxuICApICYgeyBsYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcj86IExhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyIH0sXG4pOiBBcHBTdGF0ZVtcImFjdGl2ZVRvb2xcIl0gPT4ge1xuICBpZiAoZGF0YS50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgY3VzdG9tVHlwZTogZGF0YS5jdXN0b21UeXBlLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLmFwcFN0YXRlLmFjdGl2ZVRvb2wsXG4gICAgbGFzdEFjdGl2ZVRvb2xCZWZvcmVFcmFzZXI6XG4gICAgICBkYXRhLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyID09PSB1bmRlZmluZWRcbiAgICAgICAgPyBhcHBTdGF0ZS5hY3RpdmVUb29sLmxhc3RBY3RpdmVUb29sQmVmb3JlRXJhc2VyXG4gICAgICAgIDogZGF0YS5sYXN0QWN0aXZlVG9vbEJlZm9yZUVyYXNlcixcbiAgICB0eXBlOiBkYXRhLnR5cGUsXG4gICAgY3VzdG9tVHlwZTogbnVsbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByZXNldEN1cnNvciA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBpZiAoY2FudmFzKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IFwiXCI7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRDdXJzb3IgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsIGN1cnNvcjogc3RyaW5nKSA9PiB7XG4gIGlmIChjYW52YXMpIHtcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xuICB9XG59O1xuXG5sZXQgZXJhc2VyQ2FudmFzQ2FjaGU6IGFueTtcbmxldCBwcmV2aWV3RGF0YVVSTDogc3RyaW5nO1xuZXhwb3J0IGNvbnN0IHNldEVyYXNlckN1cnNvciA9IChcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsXG4gIHRoZW1lOiBBcHBTdGF0ZVtcInRoZW1lXCJdLFxuKSA9PiB7XG4gIGNvbnN0IGN1cnNvckltYWdlU2l6ZVB4ID0gMjA7XG5cbiAgY29uc3QgZHJhd0NhbnZhcyA9ICgpID0+IHtcbiAgICBjb25zdCBpc0RhcmtUaGVtZSA9IHRoZW1lID09PSBUSEVNRS5EQVJLO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSA9IHRoZW1lO1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLmhlaWdodCA9IGN1cnNvckltYWdlU2l6ZVB4O1xuICAgIGVyYXNlckNhbnZhc0NhY2hlLndpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgY29uc3QgY29udGV4dCA9IGVyYXNlckNhbnZhc0NhY2hlLmdldENvbnRleHQoXCIyZFwiKSE7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAxO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5hcmMoXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS53aWR0aCAvIDIsXG4gICAgICBlcmFzZXJDYW52YXNDYWNoZS5oZWlnaHQgLyAyLFxuICAgICAgNSxcbiAgICAgIDAsXG4gICAgICAyICogTWF0aC5QSSxcbiAgICApO1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gaXNEYXJrVGhlbWUgPyBvYy5ibGFjayA6IG9jLndoaXRlO1xuICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBpc0RhcmtUaGVtZSA/IG9jLndoaXRlIDogb2MuYmxhY2s7XG4gICAgY29udGV4dC5zdHJva2UoKTtcbiAgICBwcmV2aWV3RGF0YVVSTCA9IGVyYXNlckNhbnZhc0NhY2hlLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgfTtcbiAgaWYgKCFlcmFzZXJDYW52YXNDYWNoZSB8fCBlcmFzZXJDYW52YXNDYWNoZS50aGVtZSAhPT0gdGhlbWUpIHtcbiAgICBkcmF3Q2FudmFzKCk7XG4gIH1cblxuICBzZXRDdXJzb3IoXG4gICAgY2FudmFzLFxuICAgIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pICR7Y3Vyc29ySW1hZ2VTaXplUHggLyAyfSAke1xuICAgICAgY3Vyc29ySW1hZ2VTaXplUHggLyAyXG4gICAgfSwgYXV0b2AsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0Q3Vyc29yRm9yU2hhcGUgPSAoXG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4pID0+IHtcbiAgaWYgKCFjYW52YXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGFwcFN0YXRlLmFjdGl2ZVRvb2wudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgIHJlc2V0Q3Vyc29yKGNhbnZhcyk7XG4gIH0gZWxzZSBpZiAoYXBwU3RhdGUuYWN0aXZlVG9vbC50eXBlID09PSBcImVyYXNlclwiKSB7XG4gICAgc2V0RXJhc2VyQ3Vyc29yKGNhbnZhcywgYXBwU3RhdGUudGhlbWUpO1xuICAgIC8vIGRvIG5vdGhpbmcgaWYgaW1hZ2UgdG9vbCBpcyBzZWxlY3RlZCB3aGljaCBzdWdnZXN0cyB0aGVyZSdzXG4gICAgLy8gYSBpbWFnZS1wcmV2aWV3IHNldCBhcyB0aGUgY3Vyc29yXG4gICAgLy8gSWdub3JlIGN1c3RvbSB0eXBlIGFzIHdlbGwgYW5kIGxldCBob3N0IGRlY2lkZVxuICB9IGVsc2UgaWYgKCFbXCJpbWFnZVwiLCBcImN1c3RvbVwiXS5pbmNsdWRlcyhhcHBTdGF0ZS5hY3RpdmVUb29sLnR5cGUpKSB7XG4gICAgY2FudmFzLnN0eWxlLmN1cnNvciA9IENVUlNPUl9UWVBFLkNST1NTSEFJUjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGlzRnVsbFNjcmVlbiA9ICgpID0+XG4gIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50Py5ub2RlTmFtZSA9PT0gXCJIVE1MXCI7XG5cbmV4cG9ydCBjb25zdCBhbGxvd0Z1bGxTY3JlZW4gPSAoKSA9PlxuICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGV4aXRGdWxsU2NyZWVuID0gKCkgPT4gZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcblxuZXhwb3J0IGNvbnN0IGdldFNob3J0Y3V0S2V5ID0gKHNob3J0Y3V0OiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBzaG9ydGN1dCA9IHNob3J0Y3V0XG4gICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIkFsdFwiKVxuICAgIC5yZXBsYWNlKC9cXGJTaGlmdFxcYi9pLCBcIlNoaWZ0XCIpXG4gICAgLnJlcGxhY2UoL1xcYihFbnRlcnxSZXR1cm4pXFxiL2ksIFwiRW50ZXJcIilcbiAgICAucmVwbGFjZSgvXFxiRGVsXFxiL2ksIFwiRGVsZXRlXCIpO1xuXG4gIGlmIChpc0Rhcndpbikge1xuICAgIHJldHVybiBzaG9ydGN1dFxuICAgICAgLnJlcGxhY2UoL1xcYkN0cmxPckNtZFxcYi9pLCBcIkNtZFwiKVxuICAgICAgLnJlcGxhY2UoL1xcYkFsdFxcYi9pLCBcIk9wdGlvblwiKTtcbiAgfVxuICByZXR1cm4gc2hvcnRjdXQucmVwbGFjZSgvXFxiQ3RybE9yQ21kXFxiL2ksIFwiQ3RybFwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMgPSAoXG4gIHsgY2xpZW50WCwgY2xpZW50WSB9OiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0sXG4gIHtcbiAgICB6b29tLFxuICAgIG9mZnNldExlZnQsXG4gICAgb2Zmc2V0VG9wLFxuICAgIHNjcm9sbFgsXG4gICAgc2Nyb2xsWSxcbiAgfToge1xuICAgIHpvb206IFpvb207XG4gICAgb2Zmc2V0TGVmdDogbnVtYmVyO1xuICAgIG9mZnNldFRvcDogbnVtYmVyO1xuICAgIHNjcm9sbFg6IG51bWJlcjtcbiAgICBzY3JvbGxZOiBudW1iZXI7XG4gIH0sXG4pID0+IHtcbiAgY29uc3QgaW52U2NhbGUgPSAxIC8gem9vbS52YWx1ZTtcbiAgY29uc3QgeCA9IChjbGllbnRYIC0gb2Zmc2V0TGVmdCkgKiBpbnZTY2FsZSAtIHNjcm9sbFg7XG4gIGNvbnN0IHkgPSAoY2xpZW50WSAtIG9mZnNldFRvcCkgKiBpbnZTY2FsZSAtIHNjcm9sbFk7XG5cbiAgcmV0dXJuIHsgeCwgeSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyA9IChcbiAgeyBzY2VuZVgsIHNjZW5lWSB9OiB7IHNjZW5lWDogbnVtYmVyOyBzY2VuZVk6IG51bWJlciB9LFxuICB7XG4gICAgem9vbSxcbiAgICBvZmZzZXRMZWZ0LFxuICAgIG9mZnNldFRvcCxcbiAgICBzY3JvbGxYLFxuICAgIHNjcm9sbFksXG4gIH06IHtcbiAgICB6b29tOiBab29tO1xuICAgIG9mZnNldExlZnQ6IG51bWJlcjtcbiAgICBvZmZzZXRUb3A6IG51bWJlcjtcbiAgICBzY3JvbGxYOiBudW1iZXI7XG4gICAgc2Nyb2xsWTogbnVtYmVyO1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IHggPSAoc2NlbmVYICsgc2Nyb2xsWCkgKiB6b29tLnZhbHVlICsgb2Zmc2V0TGVmdDtcbiAgY29uc3QgeSA9IChzY2VuZVkgKyBzY3JvbGxZKSAqIHpvb20udmFsdWUgKyBvZmZzZXRUb3A7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRHbG9iYWxDU1NWYXJpYWJsZSA9IChuYW1lOiBzdHJpbmcpID0+XG4gIGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKGAtLSR7bmFtZX1gKTtcblxuY29uc3QgUlNfTFRSX0NIQVJTID1cbiAgXCJBLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyQjhcXHUwMzAwLVxcdTA1OTBcXHUwODAwLVxcdTFGRkZcIiArXG4gIFwiXFx1MkMwMC1cXHVGQjFDXFx1RkRGRS1cXHVGRTZGXFx1RkVGRC1cXHVGRkZGXCI7XG5jb25zdCBSU19SVExfQ0hBUlMgPSBcIlxcdTA1OTEtXFx1MDdGRlxcdUZCMUQtXFx1RkRGRFxcdUZFNzAtXFx1RkVGQ1wiO1xuY29uc3QgUkVfUlRMX0NIRUNLID0gbmV3IFJlZ0V4cChgXlteJHtSU19MVFJfQ0hBUlN9XSpbJHtSU19SVExfQ0hBUlN9XWApO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBmaXJzdCBkaXJlY3Rpb25hbCBjaGFyYWN0ZXIgaXMgUlRMLiBNZWFuaW5nIHdoZXRoZXIgaXQgc3RhcnRzXG4gKiAgd2l0aCBSVEwgY2hhcmFjdGVycywgb3IgaW5kZXRlcm1pbmF0ZSAobnVtYmVycyBldGMuKSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5XG4gKiAgUlRMLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9leGNhbGlkcmF3L2V4Y2FsaWRyYXcvcHVsbC8xNzIyI2Rpc2N1c3Npb25fcjQzNjM0MDE3MVxuICovXG5leHBvcnQgY29uc3QgaXNSVEwgPSAodGV4dDogc3RyaW5nKSA9PiBSRV9SVExfQ0hFQ0sudGVzdCh0ZXh0KTtcblxuZXhwb3J0IGNvbnN0IHR1cGxlVG9Db29ycyA9IChcbiAgeHlUdXBsZTogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXSxcbik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XG4gIGNvbnN0IFt4LCB5XSA9IHh5VHVwbGU7XG4gIHJldHVybiB7IHgsIHkgfTtcbn07XG5cbi8qKiB1c2UgYXMgYSByZWplY3Rpb25IYW5kbGVyIHRvIG11dGUgZmlsZXN5c3RlbSBBYm9ydCBlcnJvcnMgKi9cbmV4cG9ydCBjb25zdCBtdXRlRlNBYm9ydEVycm9yID0gKGVycm9yPzogRXJyb3IpID0+IHtcbiAgaWYgKGVycm9yPy5uYW1lID09PSBcIkFib3J0RXJyb3JcIikge1xuICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRocm93IGVycm9yO1xufTtcblxuZXhwb3J0IGNvbnN0IGZpbmRJbmRleCA9IDxUPihcbiAgYXJyYXk6IHJlYWRvbmx5IFRbXSxcbiAgY2I6IChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyLCBhcnJheTogcmVhZG9ubHkgVFtdKSA9PiBib29sZWFuLFxuICBmcm9tSW5kZXg6IG51bWJlciA9IDAsXG4pID0+IHtcbiAgaWYgKGZyb21JbmRleCA8IDApIHtcbiAgICBmcm9tSW5kZXggPSBhcnJheS5sZW5ndGggKyBmcm9tSW5kZXg7XG4gIH1cbiAgZnJvbUluZGV4ID0gTWF0aC5taW4oYXJyYXkubGVuZ3RoLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4IC0gMTtcbiAgd2hpbGUgKCsraW5kZXggPCBhcnJheS5sZW5ndGgpIHtcbiAgICBpZiAoY2IoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbmV4cG9ydCBjb25zdCBmaW5kTGFzdEluZGV4ID0gPFQ+KFxuICBhcnJheTogcmVhZG9ubHkgVFtdLFxuICBjYjogKGVsZW1lbnQ6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiByZWFkb25seSBUW10pID0+IGJvb2xlYW4sXG4gIGZyb21JbmRleDogbnVtYmVyID0gYXJyYXkubGVuZ3RoIC0gMSxcbikgPT4ge1xuICBpZiAoZnJvbUluZGV4IDwgMCkge1xuICAgIGZyb21JbmRleCA9IGFycmF5Lmxlbmd0aCArIGZyb21JbmRleDtcbiAgfVxuICBmcm9tSW5kZXggPSBNYXRoLm1pbihhcnJheS5sZW5ndGggLSAxLCBNYXRoLm1heChmcm9tSW5kZXgsIDApKTtcbiAgbGV0IGluZGV4ID0gZnJvbUluZGV4ICsgMTtcbiAgd2hpbGUgKC0taW5kZXggPiAtMSkge1xuICAgIGlmIChjYihhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzVHJhbnNwYXJlbnQgPSAoY29sb3I6IHN0cmluZykgPT4ge1xuICBjb25zdCBpc1JHQlRyYW5zcGFyZW50ID0gY29sb3IubGVuZ3RoID09PSA1ICYmIGNvbG9yLnN1YnN0cig0LCAxKSA9PT0gXCIwXCI7XG4gIGNvbnN0IGlzUlJHR0JCVHJhbnNwYXJlbnQgPSBjb2xvci5sZW5ndGggPT09IDkgJiYgY29sb3Iuc3Vic3RyKDcsIDIpID09PSBcIjAwXCI7XG4gIHJldHVybiAoXG4gICAgaXNSR0JUcmFuc3BhcmVudCB8fFxuICAgIGlzUlJHR0JCVHJhbnNwYXJlbnQgfHxcbiAgICBjb2xvciA9PT0gY29sb3JzLmVsZW1lbnRCYWNrZ3JvdW5kWzBdXG4gICk7XG59O1xuXG5leHBvcnQgdHlwZSBSZXNvbHZhYmxlUHJvbWlzZTxUPiA9IFByb21pc2U8VD4gJiB7XG4gIHJlc29sdmU6IFtUXSBleHRlbmRzIFt1bmRlZmluZWRdID8gKHZhbHVlPzogVCkgPT4gdm9pZCA6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufTtcbmV4cG9ydCBjb25zdCByZXNvbHZhYmxlUHJvbWlzZSA9IDxUPigpID0+IHtcbiAgbGV0IHJlc29sdmUhOiBhbnk7XG4gIGxldCByZWplY3QhOiBhbnk7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgcmVqZWN0ID0gX3JlamVjdDtcbiAgfSk7XG4gIChwcm9taXNlIGFzIGFueSkucmVzb2x2ZSA9IHJlc29sdmU7XG4gIChwcm9taXNlIGFzIGFueSkucmVqZWN0ID0gcmVqZWN0O1xuICByZXR1cm4gcHJvbWlzZSBhcyBSZXNvbHZhYmxlUHJvbWlzZTxUPjtcbn07XG5cbi8qKlxuICogQHBhcmFtIGZ1bmMgaGFuZGxlciB0YWtpbmcgYXQgbW9zdCBzaW5nbGUgcGFyYW1ldGVyIChldmVudCkuXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXMgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PlxuICAoKGV2ZW50KSA9PiB7XG4gICAgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMoZnVuYyBhcyBURnVuY3Rpb24sIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uO1xuXG4vKipcbiAqIGJhcmNoZXMgUmVhY3Qgc3RhdGUgdXBkYXRlcyBhbmQgdGhyb3R0bGVzIHRoZSBjYWxscyB0byBhIHNpbmdsZSBjYWxsIHBlclxuICogYW5pbWF0aW9uIGZyYW1lXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoQmF0Y2hlZFVwZGF0ZXNUaHJvdHRsZWQgPSA8XG4gIFRGdW5jdGlvbiBleHRlbmRzICgoZXZlbnQ6IGFueSkgPT4gdm9pZCkgfCAoKCkgPT4gdm9pZCksXG4+KFxuICBmdW5jOiBQYXJhbWV0ZXJzPFRGdW5jdGlvbj5bXCJsZW5ndGhcIl0gZXh0ZW5kcyAwIHwgMSA/IFRGdW5jdGlvbiA6IG5ldmVyLFxuKSA9PiB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIHRocm90dGxlUkFGPFBhcmFtZXRlcnM8VEZ1bmN0aW9uPj4oKChldmVudCkgPT4ge1xuICAgIHVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzKGZ1bmMsIGV2ZW50KTtcbiAgfSkgYXMgVEZ1bmN0aW9uKTtcbn07XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzk0NjIzODIvODQxOFxuZXhwb3J0IGNvbnN0IG5Gb3JtYXR0ZXIgPSAobnVtOiBudW1iZXIsIGRpZ2l0czogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2kgPSBbXG4gICAgeyB2YWx1ZTogMSwgc3ltYm9sOiBcImJcIiB9LFxuICAgIHsgdmFsdWU6IDFlMywgc3ltYm9sOiBcImtcIiB9LFxuICAgIHsgdmFsdWU6IDFlNiwgc3ltYm9sOiBcIk1cIiB9LFxuICAgIHsgdmFsdWU6IDFlOSwgc3ltYm9sOiBcIkdcIiB9LFxuICBdO1xuICBjb25zdCByeCA9IC9cXC4wKyR8KFxcLlswLTldKlsxLTldKTArJC87XG4gIGxldCBpbmRleDtcbiAgZm9yIChpbmRleCA9IHNpLmxlbmd0aCAtIDE7IGluZGV4ID4gMDsgaW5kZXgtLSkge1xuICAgIGlmIChudW0gPj0gc2lbaW5kZXhdLnZhbHVlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChcbiAgICAobnVtIC8gc2lbaW5kZXhdLnZhbHVlKS50b0ZpeGVkKGRpZ2l0cykucmVwbGFjZShyeCwgXCIkMVwiKSArIHNpW2luZGV4XS5zeW1ib2xcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRWZXJzaW9uID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTE1ldGFFbGVtZW50PignbWV0YVtuYW1lPVwidmVyc2lvblwiXScpPy5jb250ZW50IHx8XG4gICAgREVGQVVMVF9WRVJTSU9OXG4gICk7XG59O1xuXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2Vtb2ppLmpzXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNFbW9qaSA9ICgpID0+IHtcbiAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgaWYgKCFjdHgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgb2Zmc2V0ID0gMTI7XG4gIGN0eC5maWxsU3R5bGUgPSBcIiNmMDBcIjtcbiAgY3R4LnRleHRCYXNlbGluZSA9IFwidG9wXCI7XG4gIGN0eC5mb250ID0gXCIzMnB4IEFyaWFsXCI7XG4gIC8vIE1vZGVybml6ciB1c2VkIPCfkKgsIGJ1dCBpdCBpcyBzb3J0IG9mIHN1cHBvcnRlZCBvbiBXaW5kb3dzIDcuXG4gIC8vIEx1Y2tpbHkg8J+YgCBpc24ndCBzdXBwb3J0ZWQuXG4gIGN0eC5maWxsVGV4dChcIvCfmIBcIiwgMCwgMCk7XG4gIHJldHVybiBjdHguZ2V0SW1hZ2VEYXRhKG9mZnNldCwgb2Zmc2V0LCAxLCAxKS5kYXRhWzBdICE9PSAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbik6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgcmV0dXJuIGRvY3VtZW50O1xuICAgIH1cbiAgICBjb25zdCB7IG92ZXJmbG93WSB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcbiAgICBjb25zdCBoYXNTY3JvbGxhYmxlQ29udGVudCA9IHBhcmVudC5zY3JvbGxIZWlnaHQgPiBwYXJlbnQuY2xpZW50SGVpZ2h0O1xuICAgIGlmIChcbiAgICAgIGhhc1Njcm9sbGFibGVDb250ZW50ICYmXG4gICAgICAob3ZlcmZsb3dZID09PSBcImF1dG9cIiB8fFxuICAgICAgICBvdmVyZmxvd1kgPT09IFwic2Nyb2xsXCIgfHxcbiAgICAgICAgb3ZlcmZsb3dZID09PSBcIm92ZXJsYXlcIilcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xuICB9XG4gIHJldHVybiBkb2N1bWVudDtcbn07XG5cbmV4cG9ydCBjb25zdCBmb2N1c05lYXJlc3RQYXJlbnQgPSAoZWxlbWVudDogSFRNTElucHV0RWxlbWVudCkgPT4ge1xuICBsZXQgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC50YWJJbmRleCA+IC0xKSB7XG4gICAgICBwYXJlbnQuZm9jdXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwcmV2ZW50VW5sb2FkID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4ge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAvLyBOT1RFOiBtb2Rlcm4gYnJvd3NlcnMgbm8gbG9uZ2VyIGFsbG93IHNob3dpbmcgYSBjdXN0b20gbWVzc2FnZSBoZXJlXG4gIGV2ZW50LnJldHVyblZhbHVlID0gXCJcIjtcbn07XG5cbmV4cG9ydCBjb25zdCBieXRlc1RvSGV4U3RyaW5nID0gKGJ5dGVzOiBVaW50OEFycmF5KSA9PiB7XG4gIHJldHVybiBBcnJheS5mcm9tKGJ5dGVzKVxuICAgIC5tYXAoKGJ5dGUpID0+IGAwJHtieXRlLnRvU3RyaW5nKDE2KX1gLnNsaWNlKC0yKSlcbiAgICAuam9pbihcIlwiKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVcGRhdGVkVGltZXN0YW1wID0gKCkgPT4gKGlzVGVzdEVudigpID8gMSA6IERhdGUubm93KCkpO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIGBpZGAgYXR0cmlidXRlLFxuICogb3IgYXJyYXkgb2YgaWRzIChzdHJpbmdzKSwgaW50byBhIE1hcCwga2V5ZCBieSBgaWRgLlxuICovXG5leHBvcnQgY29uc3QgYXJyYXlUb01hcCA9IDxUIGV4dGVuZHMgeyBpZDogc3RyaW5nIH0gfCBzdHJpbmc+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuKSA9PiB7XG4gIHJldHVybiBpdGVtcy5yZWR1Y2UoKGFjYzogTWFwPHN0cmluZywgVD4sIGVsZW1lbnQpID0+IHtcbiAgICBhY2Muc2V0KHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiID8gZWxlbWVudCA6IGVsZW1lbnQuaWQsIGVsZW1lbnQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIG5ldyBNYXAoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgaXNUZXN0RW52ID0gKCkgPT5cbiAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy5lbnY/Lk5PREVfRU5WID09PSBcInRlc3RcIjtcblxuZXhwb3J0IGNvbnN0IGlzUHJvZEVudiA9ICgpID0+XG4gIHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MuZW52Py5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCI7XG5cbmV4cG9ydCBjb25zdCB3cmFwRXZlbnQgPSA8VCBleHRlbmRzIEV2ZW50PihuYW1lOiBFVkVOVCwgbmF0aXZlRXZlbnQ6IFQpID0+IHtcbiAgcmV0dXJuIG5ldyBDdXN0b21FdmVudChuYW1lLCB7XG4gICAgZGV0YWlsOiB7XG4gICAgICBuYXRpdmVFdmVudCxcbiAgICB9LFxuICAgIGNhbmNlbGFibGU6IHRydWUsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZU9iamVjdCA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIG9iajogVCxcbiAgdXBkYXRlczogUGFydGlhbDxUPixcbik6IFQgPT4ge1xuICBsZXQgZGlkQ2hhbmdlID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9ICh1cGRhdGVzIGFzIGFueSlba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvYmogYXMgYW55KVtrZXldID09PSB2YWx1ZSAmJlxuICAgICAgICAvLyBpZiBvYmplY3QsIGFsd2F5cyB1cGRhdGUgYmVjYXVzZSBpdHMgYXR0cnMgY291bGQgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgdmFsdWUgPT09IG51bGwpXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4ub2JqLFxuICAgIC4uLnVwZGF0ZXMsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcmltaXRpdmUgPSAodmFsOiBhbnkpID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCAodHlwZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlICE9PSBcImZ1bmN0aW9uXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEZyYW1lID0gKCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuc2VsZiA9PT0gd2luZG93LnRvcCA/IFwidG9wXCIgOiBcImlmcmFtZVwiO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBcImlmcmFtZVwiO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaXNQcm9taXNlTGlrZSA9IChcbiAgdmFsdWU6IGFueSxcbik6IHZhbHVlIGlzIFByb21pc2U8UmVzb2x1dGlvblR5cGU8dHlwZW9mIHZhbHVlPj4gPT4ge1xuICByZXR1cm4gKFxuICAgICEhdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcInRoZW5cIiBpbiB2YWx1ZSAmJlxuICAgIFwiY2F0Y2hcIiBpbiB2YWx1ZSAmJlxuICAgIFwiZmluYWxseVwiIGluIHZhbHVlXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcXVlcnlGb2N1c2FibGVFbGVtZW50cyA9IChjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4ge1xuICBjb25zdCBmb2N1c2FibGVFbGVtZW50cyA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oXG4gICAgXCJidXR0b24sIGEsIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBkaXZbdGFiaW5kZXhdLCBsYWJlbFt0YWJpbmRleF1cIixcbiAgKTtcblxuICByZXR1cm4gZm9jdXNhYmxlRWxlbWVudHNcbiAgICA/IEFycmF5LmZyb20oZm9jdXNhYmxlRWxlbWVudHMpLmZpbHRlcihcbiAgICAgICAgKGVsZW1lbnQpID0+XG4gICAgICAgICAgZWxlbWVudC50YWJJbmRleCA+IC0xICYmICEoZWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50KS5kaXNhYmxlZCxcbiAgICAgIClcbiAgICA6IFtdO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../utils.ts\n");
3353
3353
 
3354
3354
  /***/ }),
3355
3355