@zsviczian/excalidraw 0.10.0-textfix-16 → 0.10.0-textfix-17

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.
@@ -1783,7 +1783,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
1783
1783
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1784
1784
 
1785
1785
  "use strict";
1786
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"useIsMobile\": () => (/* binding */ useIsMobile),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\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 roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.dev.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data/json */ \"../../data/json.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__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer */ \"../../renderer/index.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 _Stats__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_42__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst IsMobileContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(false);\r\nconst useIsMobile = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(IsMobileContext);\r\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\r\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\r\nlet didTapTwice = false;\r\nlet tappedTwiceTimer = 0;\r\nlet cursorX = 0;\r\nlet cursorY = 0;\r\nlet isHoldingSpace = false;\r\nlet isPanning = false;\r\nlet isDraggingScrollBar = false;\r\nlet currentScrollBars = { horizontal: null, vertical: null };\r\nlet touchTimeout = 0;\r\nlet invalidateContextMenu = false;\r\nlet lastPointerUp = null;\r\nconst gesture = {\r\n pointers: new Map(),\r\n lastCenter: null,\r\n initialDistance: null,\r\n initialScale: null,\r\n};\r\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\r\n constructor(props) {\r\n var _a;\r\n super(props);\r\n this.canvas = null;\r\n this.rc = null;\r\n this.unmounted = false;\r\n this.isMobile = false;\r\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\r\n this.files = {};\r\n this.imageCache = new Map();\r\n this.focusContainer = () => {\r\n var _a;\r\n if (this.props.autoFocus) {\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\r\n }\r\n };\r\n this.getSceneElementsIncludingDeleted = () => {\r\n return this.scene.getElementsIncludingDeleted();\r\n };\r\n this.getSceneElements = () => {\r\n return this.scene.getElements();\r\n };\r\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\r\n var _a, _b, _c, _d, _e, _f;\r\n if (this.unmounted || actionResult === false) {\r\n return;\r\n }\r\n let editingElement = null;\r\n if (actionResult.elements) {\r\n actionResult.elements.forEach((element) => {\r\n var _a;\r\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\r\n this.state.editingElement !== element &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n editingElement = element;\r\n }\r\n });\r\n this.scene.replaceAllElements(actionResult.elements);\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n }\r\n if (actionResult.files) {\r\n this.files = actionResult.replaceFiles\r\n ? actionResult.files\r\n : Object.assign(Object.assign({}, this.files), actionResult.files);\r\n this.addNewImagesToImageCache();\r\n }\r\n if (actionResult.appState || editingElement) {\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\r\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\r\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\r\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_11__.THEME.LIGHT;\r\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;\r\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\r\n viewModeEnabled = this.props.viewModeEnabled;\r\n }\r\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\r\n zenModeEnabled = this.props.zenModeEnabled;\r\n }\r\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\r\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null;\r\n }\r\n if (typeof this.props.theme !== \"undefined\") {\r\n theme = this.props.theme;\r\n }\r\n if (typeof this.props.name !== \"undefined\") {\r\n name = this.props.name;\r\n }\r\n this.setState((state) => {\r\n var _a;\r\n // using Object.assign instead of spread to fool TS 4.2.2+ into\r\n // regarding the resulting type as not containing undefined\r\n // (which the following expression will never contain)\r\n return Object.assign(actionResult.appState || {}, {\r\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\r\n viewModeEnabled,\r\n zenModeEnabled,\r\n gridSize,\r\n theme,\r\n name,\r\n });\r\n }, () => {\r\n if (actionResult.syncHistory) {\r\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\r\n }\r\n });\r\n }\r\n });\r\n // Lifecycle\r\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isHoldingSpace = false;\r\n this.setState({ isBindingEnabled: true });\r\n });\r\n this.onUnload = () => {\r\n this.onBlur();\r\n };\r\n this.disableEvent = (event) => {\r\n event.preventDefault();\r\n };\r\n this.onFontLoaded = () => {\r\n this.scene.getElementsIncludingDeleted().forEach((element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n });\r\n this.onSceneUpdated();\r\n };\r\n this.importLibraryFromUrl = (url, token) => __awaiter(this, void 0, void 0, function* () {\r\n if (window.location.hash.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary)) {\r\n const hash = new URLSearchParams(window.location.hash.slice(1));\r\n hash.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `#${hash.toString()}`);\r\n }\r\n else if (window.location.search.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary)) {\r\n const query = new URLSearchParams(window.location.search);\r\n query.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `?${query.toString()}`);\r\n }\r\n try {\r\n const request = yield fetch(decodeURIComponent(url));\r\n const blob = yield request.blob();\r\n const json = JSON.parse(yield blob.text());\r\n if (!(0,_data_json__WEBPACK_IMPORTED_MODULE_13__.isValidLibrary)(json)) {\r\n throw new Error();\r\n }\r\n if (token === this.id ||\r\n window.confirm((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.confirmAddLibrary\", {\r\n numShapes: (json.libraryItems || json.library || []).length,\r\n }))) {\r\n yield this.library.importLibrary(blob, \"published\");\r\n // hack to rerender the library items after import\r\n if (this.state.isLibraryOpen) {\r\n this.setState({ isLibraryOpen: false });\r\n }\r\n this.setState({ isLibraryOpen: true });\r\n }\r\n }\r\n catch (error) {\r\n window.alert((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.errorLoadingLibrary\"));\r\n console.error(error);\r\n }\r\n finally {\r\n this.focusContainer();\r\n }\r\n });\r\n this.resetHistory = () => {\r\n this.history.clear();\r\n };\r\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\r\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\r\n this.scene.replaceAllElements([]);\r\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\r\n this.resetHistory();\r\n });\r\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\r\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\r\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\r\n if (!launchParams.files.length) {\r\n return;\r\n }\r\n const fileHandle = launchParams.files[0];\r\n const blob = yield fileHandle.getFile();\r\n blob.handle = fileHandle;\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(blob, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n }));\r\n }\r\n if (!this.state.isLoading) {\r\n this.setState({ isLoading: true });\r\n }\r\n let initialData = null;\r\n try {\r\n initialData = (yield this.props.initialData) || null;\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\r\n this.libraryItemsFromStorage = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreLibraryItems)(initialData.libraryItems, \"unpublished\");\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n initialData = {\r\n appState: {\r\n errorMessage: error.message ||\r\n \"Encountered an error during importing or restoring scene data\",\r\n },\r\n };\r\n }\r\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\r\n scene.appState = Object.assign(Object.assign({}, scene.appState), { elementType: scene.appState.elementType === \"image\"\r\n ? \"selection\"\r\n : scene.appState.elementType, isLoading: false });\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\r\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));\r\n }\r\n this.resetHistory();\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\r\n const libraryUrl = \r\n // current\r\n new URLSearchParams(window.location.hash.slice(1)).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary) ||\r\n // legacy, kept for compat reasons\r\n new URLSearchParams(window.location.search).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n if (libraryUrl) {\r\n yield this.importLibraryFromUrl(libraryUrl);\r\n }\r\n });\r\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n this.scene\r\n .getElementsIncludingDeleted()\r\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\r\n this.setState({});\r\n });\r\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\r\n this.setState((state) => {\r\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\r\n return null;\r\n }\r\n return { offsetTop, offsetLeft };\r\n });\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.SCROLL_TIMEOUT);\r\n // Copy/paste\r\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.cutAll();\r\n event.preventDefault();\r\n });\r\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.copyAll();\r\n event.preventDefault();\r\n });\r\n this.cutAll = () => {\r\n this.copyAll();\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected);\r\n };\r\n this.copyAll = () => {\r\n (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.copyToClipboard)(this.scene.getElements(), this.state, this.files);\r\n };\r\n this.onTapStart = (event) => {\r\n if (!didTapTwice) {\r\n didTapTwice = true;\r\n clearTimeout(tappedTwiceTimer);\r\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_11__.TAP_TWICE_TIMEOUT);\r\n return;\r\n }\r\n // insert text only if we tapped twice with a single finger\r\n // event.touches.length === 1 will also prevent inserting text when user's zooming\r\n if (didTapTwice && event.touches.length === 1) {\r\n const [touch] = event.touches;\r\n // @ts-ignore\r\n this.handleCanvasDoubleClick({\r\n clientX: touch.clientX,\r\n clientY: touch.clientY,\r\n });\r\n didTapTwice = false;\r\n clearTimeout(tappedTwiceTimer);\r\n }\r\n event.preventDefault();\r\n if (event.touches.length === 2) {\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n }\r\n };\r\n this.onTapEnd = (event) => {\r\n if (event.touches.length > 0) {\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n }\r\n };\r\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\r\n var _b, _c;\r\n // #686\r\n const target = document.activeElement;\r\n const isExcalidrawActive = (_b = this.excalidrawContainerRef.current) === null || _b === void 0 ? void 0 : _b.contains(target);\r\n if (!isExcalidrawActive) {\r\n return;\r\n }\r\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\r\n if (\r\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\r\n // thus these checks don't make sense\r\n event &&\r\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\r\n return;\r\n }\r\n // must be called in the same frame (thus before any awaits) as the paste\r\n // event else some browsers (FF...) will clear the clipboardData\r\n // (something something security)\r\n let file = (_c = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _c === void 0 ? void 0 : _c.files[0];\r\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.parseClipboard)(event);\r\n if (!file && data.text) {\r\n const string = data.text.trim();\r\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\r\n // ignore SVG validation/normalization which will be done during image\r\n // initialization\r\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(string);\r\n }\r\n }\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n if (this.props.onPaste) {\r\n try {\r\n if ((yield this.props.onPaste(data, event)) === false) {\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n if (data.errorMessage) {\r\n this.setState({ errorMessage: data.errorMessage });\r\n }\r\n else if (data.spreadsheet) {\r\n this.setState({\r\n pasteDialog: {\r\n data: data.spreadsheet,\r\n shown: true,\r\n },\r\n });\r\n }\r\n else if (data.elements) {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: data.elements,\r\n files: data.files || null,\r\n position: \"cursor\",\r\n });\r\n }\r\n else if (data.text) {\r\n this.addTextFromPaste(data.text);\r\n }\r\n this.selectShapeTool(\"selection\");\r\n event === null || event === void 0 ? void 0 : event.preventDefault();\r\n }));\r\n this.addElementsFromPasteOrLibrary = (opts) => {\r\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\r\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\r\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\r\n const clientX = typeof opts.position === \"object\"\r\n ? opts.position.clientX\r\n : opts.position === \"cursor\"\r\n ? cursorX\r\n : this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = typeof opts.position === \"object\"\r\n ? opts.position.clientY\r\n : opts.position === \"cursor\"\r\n ? cursorY\r\n : this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const dx = x - elementsCenterX;\r\n const dy = y - elementsCenterY;\r\n const groupIdMap = new Map();\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\r\n const oldIdToDuplicatedId = new Map();\r\n const newElements = elements.map((element) => {\r\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\r\n x: element.x + gridX - minX,\r\n y: element.y + gridY - minY,\r\n });\r\n oldIdToDuplicatedId.set(element.id, newElement.id);\r\n return newElement;\r\n });\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\r\n const nextElements = [\r\n ...this.scene.getElementsIncludingDeleted(),\r\n ...newElements,\r\n ];\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\r\n if (opts.files) {\r\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\r\n }\r\n this.scene.replaceAllElements(nextElements);\r\n this.history.resumeRecording();\r\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: false, selectedElementIds: newElements.reduce((map, element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.containerId) {\r\n map[element.id] = true;\r\n }\r\n return map;\r\n }, {}), selectedGroupIds: {} }), this.scene.getElements()), () => {\r\n if (opts.files) {\r\n this.addNewImagesToImageCache();\r\n }\r\n });\r\n this.selectShapeTool(\"selection\");\r\n };\r\n // Collaboration\r\n this.setAppState = (obj) => {\r\n this.setState(obj);\r\n };\r\n this.removePointer = (event) => {\r\n // remove touch handler for context menu on touch devices\r\n if (event.pointerType === \"touch\" && touchTimeout) {\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n invalidateContextMenu = false;\r\n }\r\n gesture.pointers.delete(event.pointerId);\r\n };\r\n this.toggleLock = () => {\r\n this.setState((prevState) => {\r\n return {\r\n elementLocked: !prevState.elementLocked,\r\n elementType: prevState.elementLocked\r\n ? \"selection\"\r\n : prevState.elementType,\r\n };\r\n });\r\n };\r\n this.toggleZenMode = () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode);\r\n };\r\n this.toggleStats = () => {\r\n if (!this.state.showStats) {\r\n (0,_analytics__WEBPACK_IMPORTED_MODULE_8__.trackEvent)(\"dialog\", \"stats\");\r\n }\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\r\n };\r\n this.scrollToContent = (target = this.scene.getElements()) => {\r\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\r\n };\r\n this.clearToast = () => {\r\n this.setState({ toastMessage: null });\r\n };\r\n this.setToastMessage = (toastMessage) => {\r\n this.setState({ toastMessage });\r\n };\r\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const webShareTargetCache = yield caches.open(\"web-share-target\");\r\n const file = yield webShareTargetCache.match(\"shared-file\");\r\n if (file) {\r\n const blob = yield file.blob();\r\n this.loadFileToCanvas(blob);\r\n yield webShareTargetCache.delete(\"shared-file\");\r\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, window.location.pathname);\r\n }\r\n }\r\n catch (error) {\r\n this.setState({ errorMessage: error.message });\r\n }\r\n });\r\n /** adds supplied files to existing files in the appState */\r\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\r\n const filesMap = files.reduce((acc, fileData) => {\r\n acc.set(fileData.id, fileData);\r\n return acc;\r\n }, new Map());\r\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\r\n // bump versions for elements that reference added files so that\r\n // we/host apps can detect the change, and invalidate the image & shape\r\n // cache\r\n this.scene.getElements().forEach((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n filesMap.has(element.fileId)) {\r\n this.imageCache.delete(element.fileId);\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.bumpVersion)(element);\r\n }\r\n });\r\n this.scene.informMutation();\r\n this.addNewImagesToImageCache();\r\n });\r\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\r\n if (sceneData.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n if (sceneData.appState) {\r\n this.setState(sceneData.appState);\r\n }\r\n if (sceneData.elements) {\r\n this.scene.replaceAllElements(sceneData.elements);\r\n }\r\n if (sceneData.collaborators) {\r\n this.setState({ collaborators: sceneData.collaborators });\r\n }\r\n });\r\n this.onSceneUpdated = () => {\r\n this.setState({});\r\n };\r\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n cursorX = event.clientX;\r\n cursorY = event.clientY;\r\n });\r\n // Input handling\r\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // normalize `event.key` when CapsLock is pressed #2372\r\n if (\"Proxy\" in window &&\r\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\r\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\r\n event = new Proxy(event, {\r\n get(ev, prop) {\r\n const value = ev[prop];\r\n if (typeof value === \"function\") {\r\n // fix for Proxies hijacking `this`\r\n return value.bind(ev);\r\n }\r\n return prop === \"key\"\r\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\r\n // it back\r\n event.shiftKey\r\n ? ev.key.toUpperCase()\r\n : ev.key.toLowerCase()\r\n : value;\r\n },\r\n });\r\n }\r\n if (((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) && event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\r\n // case: using arrows to move between buttons\r\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\r\n this.setState({\r\n showHelpDialog: true,\r\n });\r\n }\r\n if (this.actionManager.handleKeyDown(event)) {\r\n return;\r\n }\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: false });\r\n }\r\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\r\n this.setState({ isLibraryOpen: !this.state.isLibraryOpen });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const step = (this.state.gridSize &&\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT\r\n : this.state.gridSize)) ||\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT);\r\n const selectedElements = this.scene\r\n .getElements()\r\n .filter((element) => this.state.selectedElementIds[element.id]);\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\r\n offsetX = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\r\n offsetX = step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\r\n offsetY = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\r\n offsetY = step;\r\n }\r\n selectedElements.forEach((element) => {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n x: element.x + offsetX,\r\n y: element.y + offsetY,\r\n });\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\r\n simultaneouslyUpdated: selectedElements,\r\n });\r\n });\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n event.preventDefault();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n }\r\n else if (selectedElements.length === 1 &&\r\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n const selectedElement = selectedElements[0];\r\n this.startTextEditing({\r\n sceneX: selectedElement.x + selectedElement.width / 2,\r\n sceneY: selectedElement.y + selectedElement.height / 2,\r\n shouldBind: true,\r\n });\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n else if (!event.ctrlKey &&\r\n !event.altKey &&\r\n !event.metaKey &&\r\n this.state.draggingElement === null) {\r\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\r\n if (shape) {\r\n this.selectShapeTool(shape);\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\r\n this.toggleLock();\r\n }\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\r\n isHoldingSpace = true;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (this.state.elementType === \"selection\" &&\r\n !selectedElements.length) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\r\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.elementType) ||\r\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\r\n this.setState({ openPopup: \"backgroundColorPicker\" });\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n this.setState({ openPopup: \"strokeColorPicker\" });\r\n }\r\n }\r\n });\r\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (this.state.elementType === \"selection\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n isHoldingSpace = false;\r\n }\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: true });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\r\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n });\r\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n gesture.initialScale = this.state.zoom.value;\r\n });\r\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n // onGestureChange only has zoom factor but not the center.\r\n // If we're on iPad or iPhone, then we recognize multi-touch and will\r\n // zoom in at the right location on the touchMove handler already.\r\n // On Macbook, we don't have those events so will zoom in at the\r\n // current location instead.\r\n if (gesture.pointers.size === 2) {\r\n return;\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (initialScale) {\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale), zoom, { left: offsetLeft, top: offsetTop }, { x: cursorX, y: cursorY }),\r\n }));\r\n }\r\n });\r\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n gesture.initialScale = null;\r\n });\r\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\r\n var _a;\r\n let parentCenterPosition = insertAtParentCenter &&\r\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n // bind to container when shouldBind is true or\r\n // clicked on center of container\r\n const container = shouldBind || parentCenterPosition\r\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene.getElements(), sceneX, sceneY, \"text\")\r\n : null;\r\n let existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\r\n // consider bounded text element if container present\r\n if (container) {\r\n const boundTextElementId = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getBoundTextElementId)(container);\r\n if (boundTextElementId) {\r\n existingTextElement = this.scene.getElement(boundTextElementId);\r\n }\r\n }\r\n if (!existingTextElement && container) {\r\n const fontString = {\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n };\r\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const newHeight = Math.max(container.height, minHeight);\r\n const newWidth = Math.max(container.width, minWidth);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\r\n sceneX = container.x + newWidth / 2;\r\n sceneY = container.y + newHeight / 2;\r\n if (parentCenterPosition) {\r\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n }\r\n }\r\n const element = existingTextElement\r\n ? existingTextElement\r\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x: parentCenterPosition\r\n ? parentCenterPosition.elementCenterX\r\n : sceneX,\r\n y: parentCenterPosition\r\n ? parentCenterPosition.elementCenterY\r\n : sceneY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text: \"\",\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: parentCenterPosition\r\n ? \"center\"\r\n : this.state.currentItemTextAlign,\r\n verticalAlign: parentCenterPosition\r\n ? \"middle\"\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\r\n });\r\n this.setState({ editingElement: element });\r\n if (existingTextElement) {\r\n // if text element is no longer centered to a container, reset\r\n // verticalAlign to default because it's currently internal-only\r\n if (!parentCenterPosition || element.textAlign !== \"center\") {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, { verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN });\r\n }\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n // case: creating new text not centered to parent elemenent → offset Y\r\n // so that the text is centered to cursor position\r\n if (!parentCenterPosition) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n y: element.y - element.baseline / 2,\r\n });\r\n }\r\n }\r\n this.setState({\r\n editingElement: element,\r\n });\r\n this.handleTextWysiwyg(element, {\r\n isExistingElement: !!existingTextElement,\r\n });\r\n };\r\n this.handleCanvasDoubleClick = (event) => {\r\n // case: double-clicking with arrow/line tool selected would both create\r\n // text and enter multiElement mode\r\n if (this.state.multiElement) {\r\n return;\r\n }\r\n // we should only be able to double click when mode is selection\r\n if (this.state.elementType !== \"selection\") {\r\n return;\r\n }\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n return;\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\r\n if (selectedGroupIds.length > 0) {\r\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\r\n const selectedGroupId = hitElement &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\r\n if (selectedGroupId) {\r\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.getElements()));\r\n return;\r\n }\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1) {\r\n const selectedElement = selectedElements[0];\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\r\n if (canBindText) {\r\n sceneX = selectedElement.x + selectedElement.width / 2;\r\n sceneY = selectedElement.y + selectedElement.height / 2;\r\n }\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n }\r\n };\r\n this.handleCanvasPointerMove = (event) => {\r\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\r\n if (gesture.pointers.has(event.pointerId)) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (gesture.pointers.size === 2 &&\r\n gesture.lastCenter &&\r\n initialScale &&\r\n gesture.initialDistance) {\r\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n const deltaX = center.x - gesture.lastCenter.x;\r\n const deltaY = center.y - gesture.lastCenter.y;\r\n gesture.lastCenter = center;\r\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n const scaleFactor = distance / gesture.initialDistance;\r\n this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({\r\n scrollX: scrollX + deltaX / zoom.value,\r\n scrollY: scrollY + deltaY / zoom.value,\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor), zoom, { left: offsetLeft, top: offsetTop }, center),\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n }\r\n else {\r\n gesture.lastCenter =\r\n gesture.initialDistance =\r\n gesture.initialScale =\r\n null;\r\n }\r\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\r\n return;\r\n }\r\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\r\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\r\n if (!this.state.draggingElement && !this.state.multiElement) {\r\n if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\r\n if (this.state.editingLinearElement &&\r\n !this.state.editingLinearElement.isDragging) {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({ editingLinearElement });\r\n }\r\n if (editingLinearElement.lastUncommittedPoint != null) {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n else {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.elementType)) {\r\n // Hovering with a selected tool or creating new linear element via click\r\n // and point\r\n const { draggingElement } = this.state;\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\r\n }\r\n else {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n }\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n const { x: rx, y: ry } = multiElement;\r\n const { points, lastCommittedPoint } = multiElement;\r\n const lastPoint = points[points.length - 1];\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n if (lastPoint === lastCommittedPoint) {\r\n // if we haven't yet created a temp point and we're beyond commit-zone\r\n // threshold, add a point\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\r\n });\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n // in this branch, we're inside the commit zone, and no uncommitted\r\n // point exists. Thus do nothing (don't add/remove points).\r\n }\r\n }\r\n else if (points.length > 2 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: points.slice(0, -1),\r\n });\r\n }\r\n else {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n // update last uncommitted point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [\r\n ...points.slice(0, -1),\r\n [scenePointerX - rx, scenePointerY - ry],\r\n ],\r\n });\r\n }\r\n return;\r\n }\r\n const hasDeselectedButton = Boolean(event.buttons);\r\n if (hasDeselectedButton ||\r\n (this.state.elementType !== \"selection\" &&\r\n this.state.elementType !== \"text\")) {\r\n return;\r\n }\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 &&\r\n !isOverScrollBar &&\r\n !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType &&\r\n elementWithTransformHandleType.transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\r\n return;\r\n }\r\n }\r\n else if (selectedElements.length > 1 && !isOverScrollBar) {\r\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);\r\n if (transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType,\r\n }));\r\n return;\r\n }\r\n }\r\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\r\n if (this.state.elementType === \"text\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n }\r\n else if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n else if (this.state.editingLinearElement) {\r\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(this.state.editingLinearElement.elementId);\r\n if (element &&\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\r\n scenePointer.x,\r\n scenePointer.y,\r\n ])) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n }\r\n else if (\r\n // if using cmd/ctrl, we're not dragging\r\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\r\n (hitElement ||\r\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements))) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n };\r\n // set touch moving for mobile context menu\r\n this.handleTouchMove = (event) => {\r\n invalidateContextMenu = true;\r\n };\r\n this.handleCanvasPointerDown = (event) => {\r\n // remove any active selection when we start to interact with canvas\r\n // (mainly, we care about removing selection outside the component which\r\n // would prevent our copy handling otherwise)\r\n const selection = document.getSelection();\r\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\r\n selection.removeAllRanges();\r\n }\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\r\n this.maybeCleanupAfterMissingPointerUp(event);\r\n if (isPanning) {\r\n return;\r\n }\r\n this.setState({\r\n lastPointerDownWith: event.pointerType,\r\n cursorButton: \"down\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"down\");\r\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\r\n return;\r\n }\r\n // only handle left mouse button or touch\r\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN &&\r\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.TOUCH) {\r\n return;\r\n }\r\n this.updateGestureOnPointerDown(event);\r\n // don't select while panning\r\n if (gesture.pointers.size > 1) {\r\n return;\r\n }\r\n // State for the duration of a pointer interaction, which starts with a\r\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\r\n const pointerDownState = this.initialPointerDownState(event);\r\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\r\n return;\r\n }\r\n this.clearSelectionIfNotUsingSelection();\r\n this.updateBindingEnabledOnPointerMove(event);\r\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\r\n return;\r\n }\r\n if (this.state.elementType === \"text\") {\r\n this.handleTextOnPointerDown(event, pointerDownState);\r\n return;\r\n }\r\n else if (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\") {\r\n this.handleLinearElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else if (this.state.elementType === \"image\") {\r\n // reset image preview on pointerdown\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n if (!this.state.pendingImageElement) {\r\n return;\r\n }\r\n this.setState({\r\n draggingElement: this.state.pendingImageElement,\r\n editingElement: this.state.pendingImageElement,\r\n pendingImageElement: null,\r\n multiElement: null,\r\n });\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(this.state.pendingImageElement, {\r\n x,\r\n y,\r\n });\r\n }\r\n else if (this.state.elementType === \"freedraw\") {\r\n this.handleFreeDrawElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else {\r\n this.createGenericElementOnPointerDown(this.state.elementType, pointerDownState);\r\n }\r\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\r\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\r\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\r\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\r\n lastPointerUp = onPointerUp;\r\n if (!this.state.viewModeEnabled) {\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, onKeyDown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, onKeyUp);\r\n pointerDownState.eventListeners.onMove = onPointerMove;\r\n pointerDownState.eventListeners.onUp = onPointerUp;\r\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\r\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\r\n }\r\n };\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\r\n // deal with opening context menu on touch devices\r\n if (event.pointerType === \"touch\") {\r\n invalidateContextMenu = false;\r\n if (touchTimeout) {\r\n // If there's already a touchTimeout, this means that there's another\r\n // touch down and we are doing another touch, so we shouldn't open the\r\n // context menu.\r\n invalidateContextMenu = true;\r\n }\r\n else {\r\n // open the context menu with the first touch's clientX and clientY\r\n // if the touch is not moving\r\n touchTimeout = window.setTimeout(() => {\r\n touchTimeout = 0;\r\n if (!invalidateContextMenu) {\r\n this.handleCanvasContextMenu(event);\r\n }\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.TOUCH_CTX_MENU_TIMEOUT);\r\n }\r\n }\r\n };\r\n // Returns whether the event is a panning\r\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\r\n if (!(gesture.pointers.size === 0 &&\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.WHEEL ||\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\r\n this.state.viewModeEnabled))) {\r\n return false;\r\n }\r\n isPanning = true;\r\n let nextPastePrevented = false;\r\n const isLinux = /Linux/.test(window.navigator.platform);\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n let { clientX: lastX, clientY: lastY } = event;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const deltaX = lastX - event.clientX;\r\n const deltaY = lastY - event.clientY;\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\r\n if (isLinux &&\r\n !nextPastePrevented &&\r\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\r\n nextPastePrevented = true;\r\n /* Prevent the next paste event */\r\n const preventNextPaste = (event) => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n event.stopPropagation();\r\n };\r\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - rigth click paste\r\n * - empty clipboard\r\n */\r\n const enableNextPaste = () => {\r\n setTimeout(() => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }, 100);\r\n };\r\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }\r\n this.setState({\r\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\r\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\r\n });\r\n });\r\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\r\n lastPointerUp = null;\r\n isPanning = false;\r\n if (!isHoldingSpace) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n }));\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove, {\r\n passive: true,\r\n });\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n return true;\r\n };\r\n this.clearSelectionIfNotUsingSelection = () => {\r\n if (this.state.elementType !== \"selection\") {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n };\r\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\r\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\r\n var _a;\r\n if (this.state.elementType === \"selection\") {\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType != null) {\r\n this.setState({\r\n resizingElement: elementWithTransformHandleType.element,\r\n });\r\n pointerDownState.resize.handleType =\r\n elementWithTransformHandleType.transformHandleType;\r\n }\r\n }\r\n else if (selectedElements.length > 1) {\r\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);\r\n }\r\n if (pointerDownState.resize.handleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType: pointerDownState.resize.handleType,\r\n }));\r\n pointerDownState.resize.isResizing = true;\r\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));\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\r\n selectedElements[0].points.length === 2) {\r\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\r\n }\r\n }\r\n else {\r\n if (this.state.editingLinearElement) {\r\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, (appState) => this.setState(appState), this.history, pointerDownState.origin);\r\n if (ret.hitElement) {\r\n pointerDownState.hit.element = ret.hitElement;\r\n }\r\n if (ret.didAddPoint) {\r\n return true;\r\n }\r\n }\r\n // hitElement may already be set above, so check first\r\n pointerDownState.hit.element =\r\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n if (pointerDownState.hit.element) {\r\n pointerDownState.hit.hasHitElementInside =\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\r\n }\r\n // For overlapped elements one position may hit\r\n // multiple elements\r\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n const hitElement = pointerDownState.hit.element;\r\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hitElement === null || !someHitElementIsSelected) &&\r\n !event.shiftKey &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.clearSelection(hitElement);\r\n }\r\n if (this.state.editingLinearElement) {\r\n this.setState({\r\n selectedElementIds: {\r\n [this.state.editingLinearElement.elementId]: true,\r\n },\r\n });\r\n // If we click on something\r\n }\r\n else if (hitElement != null) {\r\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\r\n // mark as not completely handled so as to allow dragging etc.\r\n return false;\r\n }\r\n // deselect if item is selected\r\n // if shift is not clicked, this will always return true\r\n // otherwise, it will trigger selection based on current\r\n // state of the box\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n // if we are currently editing a group, exiting editing mode and deselect the group.\r\n if (this.state.editingGroupId &&\r\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n // Add hit element to selection. At this point if we're not holding\r\n // SHIFT the previously selected element(s) were deselected above\r\n // (make sure you use setState updater to use latest state)\r\n if (!someHitElementIsSelected &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.setState((prevState) => {\r\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }) }), this.scene.getElements());\r\n });\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n }\r\n }\r\n this.setState({\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n }\r\n return false;\r\n };\r\n this.handleTextOnPointerDown = (event, pointerDownState) => {\r\n // if we're currently still editing text, clicking outside\r\n // should only finalize it, not create another (irrespective\r\n // of state.elementLocked)\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\r\n return;\r\n }\r\n let sceneX = pointerDownState.origin.x;\r\n let sceneY = pointerDownState.origin.y;\r\n const element = this.getElementAtPosition(sceneX, sceneY, {\r\n includeBoundTextElement: true,\r\n });\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\r\n if (canBindText) {\r\n sceneX = element.x + element.width / 2;\r\n sceneY = element.y + element.height / 2;\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!this.state.elementLocked) {\r\n this.setState({\r\n elementType: \"selection\",\r\n });\r\n }\r\n };\r\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n // Begin a mark capture. This does not have to update state yet.\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\r\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n simulatePressure: event.pressure === 0.5,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n const pressures = element.simulatePressure\r\n ? element.pressures\r\n : [...element.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [[0, 0]],\r\n pressures,\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n };\r\n this.createImageElement = ({ sceneX, sceneY, }) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\r\n type: \"image\",\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n });\r\n return element;\r\n };\r\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n // finalize if completing a loop\r\n if (multiElement.type === \"line\" &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\r\n // clicking inside commit zone → finalize arrow\r\n if (multiElement.points.length > 1 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\r\n }));\r\n // clicking outside commit zone → update reference for last committed\r\n // point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\r\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\r\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\r\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\r\n : [null, null];\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n startArrowhead,\r\n endArrowhead,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [...element.points, [0, 0]],\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n };\r\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n });\r\n if (element.type === \"selection\") {\r\n this.setState({\r\n selectionElement: element,\r\n draggingElement: element,\r\n });\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n multiElement: null,\r\n draggingElement: element,\r\n editingElement: element,\r\n });\r\n }\r\n };\r\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\r\n var _d, _e, _f, _g;\r\n // at this point this should be guaranteed image file, but we do this check\r\n // to satisfy TS down the line\r\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(imageFile)) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\r\n }\r\n const mimeType = imageFile.type;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\r\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.normalizeSVG)(yield imageFile.text()), imageFile.name);\r\n }\r\n catch (error) {\r\n console.warn(error);\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\r\n }\r\n }\r\n // generate image id (by default the file digest) before any\r\n // resizing/compression takes place to keep it more portable\r\n const fileId = yield (((_e = (_d = this.props).generateIdForFile) === null || _e === void 0 ? void 0 : _e.call(_d, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.generateIdFromFile)(imageFile));\r\n if (!fileId) {\r\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\r\n }\r\n const existingFileData = this.files[fileId];\r\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\r\n try {\r\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\r\n });\r\n }\r\n catch (error) {\r\n console.error(\"error trying to resing image file on insertion\", error);\r\n }\r\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\r\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\r\n }));\r\n }\r\n }\r\n if (showCursorImagePreview) {\r\n const dataURL = (_f = this.files[fileId]) === null || _f === void 0 ? void 0 : _f.dataURL;\r\n // optimization so that we don't unnecessarily resize the original\r\n // full-size file for cursor preview\r\n // (it's much faster to convert the resized dataURL to File)\r\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.dataURLToFile)(dataURL);\r\n this.setImagePreviewCursor(resizedFile || imageFile);\r\n }\r\n const dataURL = ((_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imageFile));\r\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\r\n fileId,\r\n }, false);\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var _h, _j;\r\n try {\r\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\r\n mimeType,\r\n id: fileId,\r\n dataURL,\r\n created: Date.now(),\r\n } });\r\n const cachedImageData = this.imageCache.get(fileId);\r\n if (!cachedImageData) {\r\n this.addNewImagesToImageCache();\r\n yield this.updateImageCache([imageElement]);\r\n }\r\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\r\n yield cachedImageData.image;\r\n }\r\n if (((_h = this.state.pendingImageElement) === null || _h === void 0 ? void 0 : _h.id) !== imageElement.id &&\r\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\r\n this.initializeImageDimensions(imageElement, true);\r\n }\r\n resolve(imageElement);\r\n }\r\n catch (error) {\r\n console.error(error);\r\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\r\n }\r\n finally {\r\n if (!showCursorImagePreview) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n }\r\n }));\r\n });\r\n /**\r\n * inserts image into elements array and rerenders\r\n */\r\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n imageElement,\r\n ]);\r\n try {\r\n yield this.initializeImage({\r\n imageFile,\r\n imageElement,\r\n showCursorImagePreview,\r\n });\r\n }\r\n catch (error) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n isDeleted: true,\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n this.setState({\r\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\r\n });\r\n }\r\n });\r\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\r\n // mustn't be larger than 128 px\r\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\r\n const cursorImageSizePx = 96;\r\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: cursorImageSizePx,\r\n });\r\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imagePreview);\r\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\r\n // a small canvas\r\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.loadHTMLImageElement)(previewDataURL);\r\n let height = Math.min(img.height, cursorImageSizePx);\r\n let width = height * (img.width / img.height);\r\n if (width > cursorImageSizePx) {\r\n width = cursorImageSizePx;\r\n height = width * (img.height / img.width);\r\n }\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.height = height;\r\n canvas.width = width;\r\n const context = canvas.getContext(\"2d\");\r\n context.drawImage(img, 0, 0, width, height);\r\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg);\r\n }\r\n if (this.state.pendingImageElement) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\r\n }\r\n });\r\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const clientX = this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.fileOpen)({\r\n description: \"Image\",\r\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\r\n });\r\n const imageElement = this.createImageElement({\r\n sceneX: x,\r\n sceneY: y,\r\n });\r\n if (insertOnCanvasDirectly) {\r\n this.insertImageElement(imageElement, imageFile);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({\r\n selectedElementIds: { [imageElement.id]: true },\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n else {\r\n this.setState({\r\n pendingImageElement: imageElement,\r\n }, () => {\r\n this.insertImageElement(imageElement, imageFile, \r\n /* showCursorImagePreview */ true);\r\n });\r\n }\r\n }\r\n catch (error) {\r\n if (error.name !== \"AbortError\") {\r\n console.error(error);\r\n }\r\n else {\r\n console.warn(error);\r\n }\r\n this.setState({\r\n pendingImageElement: null,\r\n editingElement: null,\r\n elementType: \"selection\",\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n });\r\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\r\n var _a;\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\r\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n if (!image || image instanceof Promise) {\r\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value) {\r\n const placeholderSize = 100 / this.state.zoom.value;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n x: imageElement.x - placeholderSize / 2,\r\n y: imageElement.y - placeholderSize / 2,\r\n width: placeholderSize,\r\n height: placeholderSize,\r\n });\r\n }\r\n return;\r\n }\r\n if (forceNaturalSize ||\r\n // if user-created bounding box is below threshold, assume the\r\n // intention was to click instead of drag, and use the image's\r\n // intrinsic size\r\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\r\n const minHeight = Math.max(this.state.height - 120, 160);\r\n // max 65% of canvas height, clamped to <300px, vh - 120px>\r\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\r\n const height = Math.min(image.naturalHeight, maxHeight);\r\n const width = height * (image.naturalWidth / image.naturalHeight);\r\n // add current imageElement width/height to account for previous centering\r\n // of the placholder image\r\n const x = imageElement.x + imageElement.width / 2 - width / 2;\r\n const y = imageElement.y + imageElement.height / 2 - height / 2;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\r\n }\r\n };\r\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\r\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.updateImageCache)({\r\n imageCache: this.imageCache,\r\n fileIds: elements.map((element) => element.fileId),\r\n files,\r\n });\r\n if (updatedFiles.size || erroredFiles.size) {\r\n for (const element of elements) {\r\n if (updatedFiles.has(element.fileId)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n }\r\n }\r\n if (erroredFiles.size) {\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n erroredFiles.has(element.fileId)) {\r\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\r\n status: \"error\",\r\n });\r\n }\r\n return element;\r\n }));\r\n }\r\n return { updatedFiles, erroredFiles };\r\n });\r\n /** adds new images to imageCache and re-renders if needed */\r\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.getInitializedImageElements)(this.scene.getElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\r\n if (uncachedImageElements.length) {\r\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\r\n if (updatedFiles.size) {\r\n this.scene.informMutation();\r\n }\r\n }\r\n });\r\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\r\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default()(() => {\r\n this.addNewImagesToImageCache();\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.IMAGE_RENDER_TIMEOUT);\r\n this.updateBindingEnabledOnPointerMove = (event) => {\r\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\r\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\r\n this.setState({ isBindingEnabled: shouldEnableBinding });\r\n }\r\n };\r\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\r\n this.setState({\r\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\r\n });\r\n };\r\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \r\n /** scene coords */\r\n pointerCoords, \r\n // During line creation the start binding hasn't been written yet\r\n // into `linearElement`\r\n oppositeBindingBoundElement) => {\r\n if (!pointerCoords.length) {\r\n return;\r\n }\r\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\r\n if (hoveredBindableElement != null &&\r\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\r\n acc.push(hoveredBindableElement);\r\n }\r\n return acc;\r\n }, []);\r\n this.setState({ suggestedBindings });\r\n };\r\n this.handleCanvasRef = (canvas) => {\r\n var _a, _b, _c;\r\n // canvas is null when unmounting\r\n if (canvas !== null) {\r\n this.canvas = canvas;\r\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__[\"default\"].canvas(this.canvas);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel, {\r\n passive: false,\r\n });\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n else {\r\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel);\r\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n };\r\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\r\n var _k, _l;\r\n try {\r\n const file = event.dataTransfer.files[0];\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n // first attempt to decode scene from the image if it's embedded\r\n // ---------------------------------------------------------------------\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted());\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n return;\r\n }\r\n catch (error) {\r\n if (error.name !== \"EncodingError\") {\r\n throw error;\r\n }\r\n }\r\n }\r\n // if no scene is embedded or we fail for whatever reason, fall back\r\n // to importing as regular image\r\n // ---------------------------------------------------------------------\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n return this.setState({\r\n isLoading: false,\r\n errorMessage: error.message,\r\n });\r\n }\r\n const libraryShapes = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib);\r\n if (libraryShapes !== \"\") {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: JSON.parse(libraryShapes),\r\n position: event,\r\n files: null,\r\n });\r\n return;\r\n }\r\n const file = (_k = event.dataTransfer) === null || _k === void 0 ? void 0 : _k.files[0];\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib ||\r\n ((_l = file === null || file === void 0 ? void 0 : file.name) === null || _l === void 0 ? void 0 : _l.endsWith(\".excalidrawlib\"))) {\r\n this.library\r\n .importLibrary(file)\r\n .then(() => {\r\n // Close and then open to get the libraries updated\r\n this.setState({ isLibraryOpen: false });\r\n this.setState({ isLibraryOpen: true });\r\n })\r\n .catch((error) => this.setState({ isLoading: false, errorMessage: error.message }));\r\n // default: assume an Excalidraw file regardless of extension/MimeType\r\n }\r\n else {\r\n this.setState({ isLoading: true });\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n yield this.loadFileToCanvas(file);\r\n }\r\n });\r\n this.loadFileToCanvas = (file) => {\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n };\r\n this.handleCanvasContextMenu = (event) => {\r\n event.preventDefault();\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const element = this.getElementAtPosition(x, y, { preferSelected: true });\r\n const type = element ? \"element\" : \"canvas\";\r\n const container = this.excalidrawContainerRef.current;\r\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\r\n const left = event.clientX - offsetLeft;\r\n const top = event.clientY - offsetTop;\r\n if (element && !this.state.selectedElementIds[element.id]) {\r\n this.setState({ selectedElementIds: { [element.id]: true } }, () => {\r\n this._openContextMenu({ top, left }, type);\r\n });\r\n }\r\n else {\r\n this._openContextMenu({ top, left }, type);\r\n }\r\n };\r\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\r\n var _a;\r\n const draggingElement = this.state.draggingElement;\r\n const pointerCoords = pointerDownState.lastCoords;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"selection\") {\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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));\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\r\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n const aspectRatio = image && !(image instanceof Promise)\r\n ? image.width / image.height\r\n : null;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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)\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\r\n this.maybeSuggestBindingForAll([draggingElement]);\r\n }\r\n };\r\n this.maybeHandleResize = (pointerDownState, event) => {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const transformHandleType = pointerDownState.resize.handleType;\r\n this.setState({\r\n // TODO: rename this state field to \"isScaling\" to distinguish\r\n // it from the generic \"isResizing\" which includes scaling and\r\n // rotating\r\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\r\n isRotating: transformHandleType === \"rotation\",\r\n });\r\n const pointerCoords = pointerDownState.lastCoords;\r\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);\r\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])\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n return true;\r\n }\r\n return false;\r\n };\r\n /** @private use this.handleCanvasContextMenu */\r\n this._openContextMenu = ({ left, top, }, type) => {\r\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const separator = \"separator\";\r\n const elements = this.scene.getElements();\r\n const options = [];\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng);\r\n }\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg);\r\n }\r\n if (type === \"canvas\") {\r\n const viewModeOptions = [\r\n ...options,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ];\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: viewModeOptions,\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && navigator.clipboard && separator,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg,\r\n ((_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) ||\r\n (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0)) &&\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSelectAll,\r\n separator,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n else if (type === \"element\") {\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy, ...options],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCut,\r\n this.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy,\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && separator,\r\n ...options,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyStyles,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionPasteStyles,\r\n separator,\r\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup,\r\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup,\r\n (maybeGroupAction || maybeUngroupAction) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionAddToLibrary,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendBackward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringForward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendToBack,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringToFront,\r\n separator,\r\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal,\r\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical,\r\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDuplicateSelection,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n };\r\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n if (isPanning) {\r\n return;\r\n }\r\n const { deltaX, deltaY } = event;\r\n const { selectedElementIds, previousSelectedElementIds } = this.state;\r\n // note that event.ctrlKey is necessary to handle pinch zooming\r\n if (event.metaKey || event.ctrlKey) {\r\n const sign = Math.sign(deltaY);\r\n const MAX_STEP = 10;\r\n let delta = Math.abs(deltaY);\r\n if (delta > MAX_STEP) {\r\n delta = MAX_STEP;\r\n }\r\n delta *= sign;\r\n if (Object.keys(previousSelectedElementIds).length !== 0) {\r\n setTimeout(() => {\r\n this.setState({\r\n selectedElementIds: previousSelectedElementIds,\r\n previousSelectedElementIds: {},\r\n });\r\n }, 1000);\r\n }\r\n let newZoom = this.state.zoom.value - delta / 100;\r\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\r\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign;\r\n // round to nearest step\r\n newZoom = Math.round(newZoom * _constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100) / (_constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100);\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom), zoom, { left: offsetLeft, top: offsetTop }, {\r\n x: cursorX,\r\n y: cursorY,\r\n }),\r\n selectedElementIds: {},\r\n previousSelectedElementIds: Object.keys(selectedElementIds).length !== 0\r\n ? selectedElementIds\r\n : previousSelectedElementIds,\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n return;\r\n }\r\n // scroll horizontally when shift pressed\r\n if (event.shiftKey) {\r\n this.setState(({ zoom, scrollX }) => ({\r\n // on Mac, shift+wheel tends to result in deltaX\r\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\r\n }));\r\n return;\r\n }\r\n this.setState(({ zoom, scrollX, scrollY }) => ({\r\n scrollX: scrollX - deltaX / zoom.value,\r\n scrollY: scrollY - deltaY / zoom.value,\r\n }));\r\n });\r\n this.savePointer = (x, y, button) => {\r\n var _a, _b;\r\n if (!x || !y) {\r\n return;\r\n }\r\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\r\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\r\n // sometimes the pointer goes off screen\r\n }\r\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\r\n pointer,\r\n button,\r\n pointersMap: gesture.pointers,\r\n });\r\n };\r\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n if (!this.unmounted) {\r\n this.setState({ shouldCacheIgnoreZoom: false });\r\n }\r\n }, 300);\r\n this.updateDOMRect = (cb) => {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\r\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\r\n if (width === currentWidth &&\r\n height === currentHeight &&\r\n offsetLeft === currentOffsetLeft &&\r\n offsetTop === currentOffsetTop) {\r\n if (cb) {\r\n cb();\r\n }\r\n return;\r\n }\r\n this.setState({\r\n width,\r\n height,\r\n offsetLeft,\r\n offsetTop,\r\n }, () => {\r\n cb && cb();\r\n });\r\n }\r\n };\r\n this.refresh = () => {\r\n this.setState(Object.assign({}, this.getCanvasOffsets()));\r\n };\r\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)();\r\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\r\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\r\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight });\r\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.nanoid)();\r\n if (excalidrawRef) {\r\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\r\n const api = {\r\n ready: true,\r\n readyPromise,\r\n updateScene: this.updateScene,\r\n addFiles: this.addFiles,\r\n resetScene: this.resetScene,\r\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\r\n history: {\r\n clear: this.resetHistory,\r\n },\r\n scrollToContent: this.scrollToContent,\r\n getSceneElements: this.getSceneElements,\r\n getAppState: () => this.state,\r\n getFiles: () => this.files,\r\n refresh: this.refresh,\r\n importLibrary: this.importLibraryFromUrl,\r\n setToastMessage: this.setToastMessage,\r\n id: this.id,\r\n };\r\n if (typeof excalidrawRef === \"function\") {\r\n excalidrawRef(api);\r\n }\r\n else {\r\n excalidrawRef.current = api;\r\n }\r\n readyPromise.resolve(api);\r\n }\r\n this.excalidrawContainerValue = {\r\n container: this.excalidrawContainerRef.current,\r\n id: this.id,\r\n };\r\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\r\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\r\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\r\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_6__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\r\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_7__.actions);\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createUndoAction)(this.history));\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createRedoAction)(this.history));\r\n }\r\n renderCanvas() {\r\n const canvasScale = window.devicePixelRatio;\r\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\r\n const canvasWidth = canvasDOMWidth * canvasScale;\r\n const canvasHeight = canvasDOMHeight * canvasScale;\r\n if (viewModeEnabled) {\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n cursor: _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n render() {\r\n var _a, _b;\r\n const { zenModeEnabled, viewModeEnabled } = this.state;\r\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\"excalidraw excalidraw-container\", {\r\n \"excalidraw--view-mode\": viewModeEnabled,\r\n \"excalidraw--mobile\": this.isMobile,\r\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)(IsMobileContext.Provider, Object.assign({ value: this.isMobile }, { children: [(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.getElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\r\n elements,\r\n position: \"center\",\r\n files: null,\r\n }), zenModeEnabled: zenModeEnabled, toggleZenMode: this.toggleZenMode, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating || false, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, viewModeEnabled: viewModeEnabled, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\r\n zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\r\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 }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }, void 0), this.state.showStats && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_37__.Stats, { appState: this.state, setAppState: this.setAppState, elements: this.scene.getElements(), onClose: this.toggleStats, renderCustomStats: renderCustomStats }, void 0)), this.state.toastMessage !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_38__.Toast, { message: this.state.toastMessage, clearToast: this.clearToast }, void 0)), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() }, void 0)] }), void 0) }), void 0) }), void 0));\r\n }\r\n componentDidMount() {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function* () {\r\n this.excalidrawContainerValue.container =\r\n this.excalidrawContainerRef.current;\r\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n const setState = this.setState.bind(this);\r\n Object.defineProperties(window.h, {\r\n state: {\r\n configurable: true,\r\n get: () => {\r\n return this.state;\r\n },\r\n },\r\n setState: {\r\n configurable: true,\r\n value: (...args) => {\r\n return this.setState(...args);\r\n },\r\n },\r\n app: {\r\n configurable: true,\r\n value: this,\r\n },\r\n history: {\r\n configurable: true,\r\n value: this.history,\r\n },\r\n });\r\n }\r\n this.scene.addCallback(this.onSceneUpdated);\r\n this.addEventListeners();\r\n if (this.excalidrawContainerRef.current) {\r\n this.focusContainer();\r\n }\r\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n // compute isMobile state\r\n // ---------------------------------------------------------------------\r\n const { width, height } = this.excalidrawContainerRef.current.getBoundingClientRect();\r\n this.isMobile =\r\n width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT ||\r\n (height < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE);\r\n // refresh offsets\r\n // ---------------------------------------------------------------------\r\n this.updateDOMRect();\r\n });\r\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\r\n }\r\n else if (window.matchMedia) {\r\n const mediaQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\r\n const handler = () => (this.isMobile = mediaQuery.matches);\r\n mediaQuery.addListener(handler);\r\n this.detachIsMobileMqHandler = () => mediaQuery.removeListener(handler);\r\n }\r\n const searchParams = new URLSearchParams(window.location.search.slice(1));\r\n if (searchParams.has(\"web-share-target\")) {\r\n // Obtain a file that was shared via the Web Share Target API.\r\n this.restoreFileFromShare();\r\n }\r\n else {\r\n this.updateDOMRect(this.initializeScene);\r\n }\r\n });\r\n }\r\n componentWillUnmount() {\r\n var _a;\r\n this.files = {};\r\n this.imageCache.clear();\r\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\r\n this.unmounted = true;\r\n this.removeEventListeners();\r\n this.scene.destroy();\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n }\r\n removeEventListeners() {\r\n var _a, _b;\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n (_a = this.nearestScrollableContainer) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n (_b = this.detachIsMobileMqHandler) === null || _b === void 0 ? void 0 : _b.call(this);\r\n }\r\n addEventListeners() {\r\n var _a, _b;\r\n this.removeEventListeners();\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer); // #3553\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n if (this.props.handleKeyboardGlobally) {\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp, { passive: true });\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\r\n // rerender text elements on font load to fix #637 && #1553\r\n (_b = (_a = document.fonts) === null || _a === void 0 ? void 0 : _a.addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, \"loadingdone\", this.onFontLoaded);\r\n // Safari-only desktop pinch zoom\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n if (this.props.detectScroll) {\r\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\r\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n }\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n }\r\n componentDidUpdate(prevProps, prevState) {\r\n var _a, _b, _c;\r\n if (prevProps.langCode !== this.props.langCode) {\r\n this.updateLanguage();\r\n }\r\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\r\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\r\n }\r\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\r\n this.addEventListeners();\r\n this.deselectElements();\r\n }\r\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\r\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\r\n }\r\n if (prevProps.theme !== this.props.theme && this.props.theme) {\r\n this.setState({ theme: this.props.theme });\r\n }\r\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\r\n this.setState({\r\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null,\r\n });\r\n }\r\n if (this.props.name && prevProps.name !== this.props.name) {\r\n this.setState({\r\n name: this.props.name,\r\n });\r\n }\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\r\n if (this.state.editingLinearElement &&\r\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\r\n // defer so that the commitToHistory flag isn't reset via current update\r\n setTimeout(() => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n const { multiElement } = prevState;\r\n if (prevState.elementType !== this.state.elementType &&\r\n multiElement != null &&\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement)) {\r\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)));\r\n }\r\n const cursorButton = {};\r\n const pointerViewportCoords = {};\r\n const remoteSelectedElementIds = {};\r\n const pointerUsernames = {};\r\n const pointerUserStates = {};\r\n this.state.collaborators.forEach((user, socketId) => {\r\n if (user.selectedElementIds) {\r\n for (const id of Object.keys(user.selectedElementIds)) {\r\n if (!(id in remoteSelectedElementIds)) {\r\n remoteSelectedElementIds[id] = [];\r\n }\r\n remoteSelectedElementIds[id].push(socketId);\r\n }\r\n }\r\n if (!user.pointer) {\r\n return;\r\n }\r\n if (user.username) {\r\n pointerUsernames[socketId] = user.username;\r\n }\r\n if (user.userState) {\r\n pointerUserStates[socketId] = user.userState;\r\n }\r\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: user.pointer.x,\r\n sceneY: user.pointer.y,\r\n }, this.state);\r\n cursorButton[socketId] = user.button;\r\n });\r\n const renderingElements = this.scene.getElements().filter((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\r\n if (\r\n // not placed on canvas yet (but in elements array)\r\n this.state.pendingImageElement &&\r\n element.id === this.state.pendingImageElement.id) {\r\n return false;\r\n }\r\n }\r\n // don't render text element that's being currently edited (it's\r\n // rendered on remote only)\r\n return (!this.state.editingElement ||\r\n this.state.editingElement.type !== \"text\" ||\r\n element.id !== this.state.editingElement.id);\r\n });\r\n const { atLeastOneVisibleElement, scrollBars } = (0,_renderer__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\r\n scrollX: this.state.scrollX,\r\n scrollY: this.state.scrollY,\r\n viewBackgroundColor: this.state.viewBackgroundColor,\r\n zoom: this.state.zoom,\r\n remotePointerViewportCoords: pointerViewportCoords,\r\n remotePointerButton: cursorButton,\r\n remoteSelectedElementIds,\r\n remotePointerUsernames: pointerUsernames,\r\n remotePointerUserStates: pointerUserStates,\r\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\r\n theme: this.state.theme,\r\n imageCache: this.imageCache,\r\n isExporting: false,\r\n renderScrollbars: !this.isMobile,\r\n });\r\n if (scrollBars) {\r\n currentScrollBars = scrollBars;\r\n }\r\n const scrolledOutside = \r\n // hide when editing text\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? false\r\n : !atLeastOneVisibleElement && renderingElements.length > 0;\r\n if (this.state.scrolledOutside !== scrolledOutside) {\r\n this.setState({ scrolledOutside });\r\n }\r\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\r\n this.scheduleImageRefresh();\r\n // Do not notify consumers if we're still loading the scene. Among other\r\n // potential issues, this fixes a case where the tab isn't focused during\r\n // init, which would trigger onChange with empty elements, which would then\r\n // override whatever is in localStorage currently.\r\n if (!this.state.isLoading) {\r\n (_c = (_b = this.props).onChange) === null || _c === void 0 ? void 0 : _c.call(_b, this.scene.getElementsIncludingDeleted(), this.state, this.files);\r\n }\r\n }\r\n static resetTapTwice() {\r\n didTapTwice = false;\r\n }\r\n addTextFromPaste(text) {\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x,\r\n y,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text,\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: this.state.currentItemTextAlign,\r\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n });\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({ selectedElementIds: { [element.id]: true } });\r\n this.history.resumeRecording();\r\n }\r\n selectShapeTool(elementType) {\r\n if (!isHoldingSpace) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, elementType);\r\n }\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\r\n this.focusContainer();\r\n }\r\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(elementType)) {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n if (elementType === \"image\") {\r\n this.onImageAction();\r\n }\r\n if (elementType !== \"selection\") {\r\n this.setState({\r\n elementType,\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n else {\r\n this.setState({ elementType });\r\n }\r\n }\r\n handleTextWysiwyg(element, { isExistingElement = false, }) {\r\n const updateElement = (text, originalText, isDeleted = false, updateDimensions = false) => {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\r\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\r\n text,\r\n isDeleted,\r\n originalText,\r\n }, updateDimensions);\r\n }\r\n return _element;\r\n }),\r\n ]);\r\n };\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\r\n id: element.id,\r\n appState: this.state,\r\n canvas: this.canvas,\r\n getViewportCoords: (x, y) => {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: x,\r\n sceneY: y,\r\n }, this.state);\r\n return [\r\n viewportX - this.state.offsetLeft,\r\n viewportY - this.state.offsetTop, //* (2 - this.state.zoom.value),\r\n ];\r\n },\r\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\r\n updateElement(text, text, false, !element.containerId);\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\r\n }\r\n }),\r\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\r\n const isDeleted = !text.trim();\r\n updateElement(text, originalText, isDeleted, true);\r\n // select the created text element only if submitting via keyboard\r\n // (when submitting via click it should act as signal to deselect)\r\n if (!isDeleted && viaKeyboard) {\r\n const elementIdToSelect = element.containerId\r\n ? element.containerId\r\n : element.id;\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\r\n }));\r\n }\r\n if (isDeleted) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getElements(), [element]);\r\n }\r\n if (!isDeleted || isExistingElement) {\r\n this.history.resumeRecording();\r\n }\r\n this.setState({\r\n draggingElement: null,\r\n editingElement: null,\r\n });\r\n if (this.state.elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n this.focusContainer();\r\n }),\r\n element,\r\n excalidrawContainer: this.excalidrawContainerRef.current,\r\n });\r\n // deselect all other elements when inserting text\r\n this.deselectElements();\r\n // do an initial update to re-initialize element position since we were\r\n // modifying element's x/y for sake of editor (case: syncing to remote)\r\n updateElement(element.text, element.originalText);\r\n }\r\n deselectElements() {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n getTextElementAtPosition(x, y) {\r\n const element = this.getElementAtPosition(x, y, {\r\n includeBoundTextElement: true,\r\n });\r\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\r\n return element;\r\n }\r\n return null;\r\n }\r\n getElementAtPosition(x, y, opts) {\r\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement);\r\n if (allHitElements.length > 1) {\r\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\r\n for (let index = allHitElements.length - 1; index > -1; index--) {\r\n if (this.state.selectedElementIds[allHitElements[index].id]) {\r\n return allHitElements[index];\r\n }\r\n }\r\n }\r\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\r\n // If we're hitting element with highest z-index only on its bounding box\r\n // while also hitting other element figure, the latter should be considered.\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\r\n ? allHitElements[allHitElements.length - 2]\r\n : elementWithHighestZIndex;\r\n }\r\n if (allHitElements.length === 1) {\r\n return allHitElements[0];\r\n }\r\n return null;\r\n }\r\n getElementsAtPosition(x, y, includeBoundTextElement = false) {\r\n const elements = includeBoundTextElement\r\n ? this.scene.getElements()\r\n : this.scene\r\n .getElements()\r\n .filter((element) => !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId));\r\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\r\n }\r\n maybeCleanupAfterMissingPointerUp(event) {\r\n if (lastPointerUp !== null) {\r\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\r\n // this can happen when a contextual menu or alert is triggered. In order to avoid\r\n // being in a weird state, we clean up on the next pointerdown\r\n lastPointerUp(event);\r\n }\r\n }\r\n updateGestureOnPointerDown(event) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n if (gesture.pointers.size === 2) {\r\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n gesture.initialScale = this.state.zoom.value;\r\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n }\r\n }\r\n initialPointerDownState(event) {\r\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return {\r\n origin,\r\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\r\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\r\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\r\n // we need to duplicate because we'll be updating this state\r\n lastCoords: Object.assign({}, origin),\r\n originalElements: this.scene.getElements().reduce((acc, element) => {\r\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\r\n return acc;\r\n }, new Map()),\r\n resize: {\r\n handleType: false,\r\n isResizing: false,\r\n offset: { x: 0, y: 0 },\r\n arrowDirection: \"origin\",\r\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\r\n },\r\n hit: {\r\n element: null,\r\n allHitElements: [],\r\n wasAddedToSelection: false,\r\n hasBeenDuplicated: false,\r\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\r\n hasHitElementInside: false,\r\n },\r\n drag: {\r\n hasOccurred: false,\r\n offset: null,\r\n },\r\n eventListeners: {\r\n onMove: null,\r\n onUp: null,\r\n onKeyUp: null,\r\n onKeyDown: null,\r\n },\r\n boxSelection: {\r\n hasOccurred: false,\r\n },\r\n };\r\n }\r\n // Returns whether the event is a dragging a scrollbar\r\n handleDraggingScrollBar(event, pointerDownState) {\r\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\r\n return false;\r\n }\r\n isDraggingScrollBar = true;\r\n pointerDownState.lastCoords.x = event.clientX;\r\n pointerDownState.lastCoords.y = event.clientY;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\r\n });\r\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isDraggingScrollBar = false;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n lastPointerUp = null;\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n });\r\n lastPointerUp = onPointerUp;\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n return true;\r\n }\r\n isASelectedElement(hitElement) {\r\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\r\n }\r\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\r\n if (selectedElements.length < 2) {\r\n return false;\r\n }\r\n // How many pixels off the shape boundary we still consider a hit\r\n const threshold = 10 / this.state.zoom.value;\r\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return (point.x > x1 - threshold &&\r\n point.x < x2 + threshold &&\r\n point.y > y1 - threshold &&\r\n point.y < y2 + threshold);\r\n }\r\n onKeyDownFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onKeyUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // Prevents focus from escaping excalidraw tab\r\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onPointerMoveFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a, _b;\r\n // We need to initialize dragOffsetXY only after we've updated\r\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\r\n // event handler should hopefully ensure we're already working with\r\n // the updated state.\r\n if (pointerDownState.drag.offset === null) {\r\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.getElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\r\n }\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\r\n return;\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n // for arrows/lines, don't start dragging until a given threshold\r\n // to ensure we don't create a 2-point arrow by mistake when\r\n // user clicks mouse in a way that it moves a tiny bit (thus\r\n // triggering pointermove)\r\n if (!pointerDownState.drag.hasOccurred &&\r\n (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\")) {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD) {\r\n return;\r\n }\r\n }\r\n if (pointerDownState.resize.isResizing) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return true;\r\n }\r\n }\r\n if (this.state.editingLinearElement) {\r\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(this.state, (appState) => this.setState(appState), pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\r\n });\r\n if (didDrag) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n return;\r\n }\r\n }\r\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hasHitASelectedElement ||\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\r\n // this allows for box-selecting points when clicking inside the\r\n // line's bounding box\r\n (!this.state.editingLinearElement || !event.shiftKey) &&\r\n // box-selecting without shift when editing line, not clicking on a line\r\n (!this.state.editingLinearElement ||\r\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\r\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\r\n pointerDownState.hit.hasHitElementInside)) {\r\n // Marking that click was used for dragging to check\r\n // if elements should be deselected on pointerup\r\n pointerDownState.drag.hasOccurred = true;\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\r\n // it would have weird results (stuff jumping all over the screen)\r\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\r\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);\r\n const [dragDistanceX, dragDistanceY] = [\r\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\r\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\r\n ];\r\n // We only drag in one direction if shift is pressed\r\n const lockDirection = event.shiftKey;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY);\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n // We duplicate the selected element if alt is pressed on pointer move\r\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\r\n // Move the currently selected elements to the top of the z index stack, and\r\n // put the duplicates where the selected elements used to be.\r\n // (the origin point where the dragging started)\r\n pointerDownState.hit.hasBeenDuplicated = true;\r\n const nextElements = [];\r\n const elementsToAppend = [];\r\n const groupIdMap = new Map();\r\n const oldIdToDuplicatedId = new Map();\r\n const hitElement = pointerDownState.hit.element;\r\n const elements = this.scene.getElementsIncludingDeleted();\r\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\r\n for (const element of elements) {\r\n if (selectedElementIds.includes(element.id) ||\r\n // case: the state.selectedElementIds might not have been\r\n // updated yet by the time this mousemove event is fired\r\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\r\n pointerDownState.hit.wasAddedToSelection)) {\r\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\r\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);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\r\n x: duplicatedElement.x + (originDragX - dragX),\r\n y: duplicatedElement.y + (originDragY - dragY),\r\n });\r\n nextElements.push(duplicatedElement);\r\n elementsToAppend.push(element);\r\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\r\n }\r\n else {\r\n nextElements.push(element);\r\n }\r\n }\r\n const nextSceneElements = [...nextElements, ...elementsToAppend];\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\r\n this.scene.replaceAllElements(nextSceneElements);\r\n }\r\n return;\r\n }\r\n }\r\n // It is very important to read this.state within each move event,\r\n // otherwise we would read a stale one!\r\n const draggingElement = this.state.draggingElement;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"freedraw\") {\r\n const points = draggingElement.points;\r\n const dx = pointerCoords.x - draggingElement.x;\r\n const dy = pointerCoords.y - draggingElement.y;\r\n const pressures = draggingElement.simulatePressure\r\n ? draggingElement.pressures\r\n : [...draggingElement.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n });\r\n }\r\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n pointerDownState.drag.hasOccurred = true;\r\n const points = draggingElement.points;\r\n let dx = gridX - draggingElement.x;\r\n let dy = gridY - draggingElement.y;\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\r\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getPerfectElementSize)(this.state.elementType, dx, dy));\r\n }\r\n if (points.length === 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, { points: [...points, [dx, dy]] });\r\n }\r\n else if (points.length > 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points.slice(0, -1), [dx, dy]],\r\n });\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n // When creating a linear element by dragging\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\r\n }\r\n }\r\n else {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n }\r\n if (this.state.elementType === \"selection\") {\r\n pointerDownState.boxSelection.hasOccurred = true;\r\n const elements = this.scene.getElements();\r\n if (!event.shiftKey &&\r\n // allows for box-selecting points (without shift)\r\n !this.state.editingLinearElement &&\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\r\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\r\n [pointerDownState.hit.element.id]: true,\r\n } }), this.scene.getElements()));\r\n }\r\n else {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n }\r\n // box-select line editor points\r\n if (this.state.editingLinearElement) {\r\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\r\n // regular box-select\r\n }\r\n else {\r\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\r\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((map, element) => {\r\n map[element.id] = true;\r\n return map;\r\n }, {})), (pointerDownState.hit.element\r\n ? {\r\n // if using ctrl/cmd, select the hitElement only if we\r\n // haven't box-selected anything else\r\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\r\n }\r\n : null)) }), this.scene.getElements()));\r\n }\r\n }\r\n });\r\n }\r\n // Returns whether the pointer move happened over either scrollbar\r\n handlePointerMoveOverScrollbars(event, pointerDownState) {\r\n if (pointerDownState.scrollbars.isOverHorizontal) {\r\n const x = event.clientX;\r\n const dx = x - pointerDownState.lastCoords.x;\r\n this.setState({\r\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.x = x;\r\n return true;\r\n }\r\n if (pointerDownState.scrollbars.isOverVertical) {\r\n const y = event.clientY;\r\n const dy = y - pointerDownState.lastCoords.y;\r\n this.setState({\r\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.y = y;\r\n return true;\r\n }\r\n return false;\r\n }\r\n onPointerUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\r\n var _a, _b;\r\n const { draggingElement, resizingElement, multiElement, elementType, elementLocked, isResizing, isRotating, } = this.state;\r\n this.setState({\r\n isResizing: false,\r\n isRotating: false,\r\n resizingElement: null,\r\n selectionElement: null,\r\n cursorButton: \"up\",\r\n // text elements are reset on finalize, and resetting on pointerup\r\n // may cause issues with double taps\r\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? this.state.editingElement\r\n : null,\r\n });\r\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\r\n // Handle end of dragging a point of a linear element, might close a loop\r\n // and sets binding element\r\n if (this.state.editingLinearElement) {\r\n if (!pointerDownState.boxSelection.hasOccurred &&\r\n (((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\r\n this.state.editingLinearElement.elementId ||\r\n !pointerDownState.hit.hasHitElementInside)) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n else {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({\r\n editingLinearElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n }\r\n }\r\n lastPointerUp = null;\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\r\n if (this.state.pendingImageElement) {\r\n this.setState({ pendingImageElement: null });\r\n }\r\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n const points = draggingElement.points;\r\n let dx = pointerCoords.x - draggingElement.x;\r\n let dy = pointerCoords.y - draggingElement.y;\r\n // Allows dots to avoid being flagged as infinitely small\r\n if (dx === points[0][0] && dy === points[0][1]) {\r\n dy += 0.0001;\r\n dx += 0.0001;\r\n }\r\n const pressures = draggingElement.simulatePressure\r\n ? []\r\n : [...draggingElement.pressures, childEvent.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n lastCommittedPoint: [dx, dy],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\r\n const imageElement = draggingElement;\r\n try {\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n catch (error) {\r\n console.error(error);\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== imageElement.id));\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n if (draggingElement.points.length > 1) {\r\n this.history.resumeRecording();\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n if (!pointerDownState.drag.hasOccurred &&\r\n draggingElement &&\r\n !multiElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [\r\n ...draggingElement.points,\r\n [\r\n pointerCoords.x - draggingElement.x,\r\n pointerCoords.y - draggingElement.y,\r\n ],\r\n ],\r\n });\r\n this.setState({\r\n multiElement: draggingElement,\r\n editingElement: this.state.draggingElement,\r\n });\r\n }\r\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\r\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\r\n }\r\n this.setState({ suggestedBindings: [], startBoundElement: null });\r\n if (!elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n elementType: \"selection\",\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n else {\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n }\r\n return;\r\n }\r\n if (elementType !== \"selection\" &&\r\n draggingElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\r\n // remove invisible element which was added in onPointerDown\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\r\n this.setState({\r\n draggingElement: null,\r\n });\r\n return;\r\n }\r\n if (draggingElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\r\n }\r\n if (resizingElement) {\r\n this.history.resumeRecording();\r\n }\r\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== resizingElement.id));\r\n }\r\n // Code below handles selection when element(s) weren't\r\n // drag or added to selection on pointer down phase.\r\n const hitElement = pointerDownState.hit.element;\r\n if (hitElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !pointerDownState.hit.wasAddedToSelection &&\r\n // if we're editing a line, pointerup shouldn't switch selection if\r\n // box selected\r\n (!this.state.editingLinearElement ||\r\n !pointerDownState.boxSelection.hasOccurred)) {\r\n // when inside line editor, shift selects points instead\r\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\r\n if (this.state.selectedElementIds[hitElement.id]) {\r\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\r\n // We want to unselect all groups hitElement is part of\r\n // as well as all elements that are part of the groups\r\n // hitElement is part of\r\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\r\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getElements(), groupId))\r\n .map((element) => ({ [element.id]: false }))\r\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\r\n this.setState((_prevState) => ({\r\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\r\n .map((gId) => ({ [gId]: false }))\r\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\r\n }));\r\n }\r\n else {\r\n // remove element from selection while\r\n // keeping prev elements selected\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false }) }), this.scene.getElements()));\r\n }\r\n }\r\n else {\r\n // add element to selection while\r\n // keeping prev elements selected\r\n this.setState((_prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\r\n }));\r\n }\r\n }\r\n else {\r\n this.setState((prevState) => (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true } }), this.scene.getElements()))));\r\n }\r\n }\r\n if (!this.state.editingLinearElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !this.state.isResizing &&\r\n ((hitElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\r\n (!hitElement &&\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\r\n // Deselect selected elements\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n return;\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\" && draggingElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\r\n }));\r\n }\r\n if (elementType !== \"selection\" ||\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getElements(), this.state)) {\r\n this.history.resumeRecording();\r\n }\r\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\r\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\r\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state));\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n elementType: \"selection\",\r\n });\r\n }\r\n else {\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n });\r\n }\r\n });\r\n }\r\n maybeSuggestBindingForAll(selectedElements) {\r\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\r\n this.setState({ suggestedBindings });\r\n }\r\n clearSelection(hitElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n // Continue editing the same group if the user selected a different\r\n // element from it\r\n editingGroupId: prevState.editingGroupId &&\r\n hitElement != null &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\r\n ? prevState.editingGroupId\r\n : null,\r\n }));\r\n this.setState({\r\n selectedElementIds: {},\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\r\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\r\n if (elementClickedInside) {\r\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\r\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\r\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\r\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_11__.TEXT_TO_CENTER_SNAP_THRESHOLD;\r\n if (isSnappedToCenter) {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\r\n return { viewportX, viewportY, elementCenterX, elementCenterY };\r\n }\r\n }\r\n }\r\n getCanvasOffsets() {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { left, top } = excalidrawContainer.getBoundingClientRect();\r\n return {\r\n offsetLeft: left,\r\n offsetTop: top,\r\n };\r\n }\r\n return {\r\n offsetLeft: 0,\r\n offsetTop: 0,\r\n };\r\n }\r\n updateLanguage() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\r\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\r\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\r\n this.setAppState({});\r\n });\r\n }\r\n}\r\nApp.defaultProps = {\r\n // needed for tests to pass since we directly render App in many tests\r\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_UI_OPTIONS,\r\n};\r\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n window.h = window.h || {};\r\n Object.defineProperties(window.h, {\r\n elements: {\r\n configurable: true,\r\n get() {\r\n return this.app.scene.getElementsIncludingDeleted();\r\n },\r\n set(elements) {\r\n return this.app.scene.replaceAllElements(elements);\r\n },\r\n },\r\n });\r\n}\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vY29tcG9uZW50cy9BcHAudHN4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQTBDO0FBRUo7QUFDZDtBQUNRO0FBeUJaO0FBQzBEO0FBQzNCO0FBQ0w7QUFFSjtBQUNPO0FBTTNCO0FBNkJBO0FBQ2lCO0FBQ087QUFDUjtBQUMwQztBQTBCNUQ7QUFhUTtBQUN5QztBQUtuQztBQUMwQztBQVM3QztBQWFxQjtBQVNqQztBQUNjO0FBQzZDO0FBUTdEO0FBQytDO0FBQ3RCO0FBQzRCO0FBV3BEO0FBQ2lCO0FBRVE7QUFDQTtBQStCekI7QUFDNkM7QUFDL0I7QUFDQTtBQUNBO0FBQ3VDO0FBUWpEO0FBTUk7QUFDYTtBQUNrQztBQU16QztBQUNpRDtBQUVqRixNQUFNLGVBQWUsR0FBRywwREFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM1QyxNQUFNLFdBQVcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxpREFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQzdELE1BQU0sMEJBQTBCLEdBQUcsMERBQW1CLENBR25ELEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUMzQixNQUFNLHNCQUFzQixHQUFHLEdBQUcsRUFBRSxDQUN6QyxpREFBVSxDQUFDLDBCQUEwQixDQUFDLENBQUM7QUFFekMsSUFBSSxXQUFXLEdBQVksS0FBSyxDQUFDO0FBQ2pDLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNoQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDaEIsSUFBSSxjQUFjLEdBQVksS0FBSyxDQUFDO0FBQ3BDLElBQUksU0FBUyxHQUFZLEtBQUssQ0FBQztBQUMvQixJQUFJLG1CQUFtQixHQUFZLEtBQUssQ0FBQztBQUN6QyxJQUFJLGlCQUFpQixHQUFlLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDekUsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLElBQUkscUJBQXFCLEdBQUcsS0FBSyxDQUFDO0FBRWxDLElBQUksYUFBYSxHQUFrQyxJQUFJLENBQUM7QUFDeEQsTUFBTSxPQUFPLEdBQVk7SUFDdkIsUUFBUSxFQUFFLElBQUksR0FBRyxFQUFFO0lBQ25CLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLGVBQWUsRUFBRSxJQUFJO0lBQ3JCLFlBQVksRUFBRSxJQUFJO0NBQ25CLENBQUM7QUFFRixNQUFNLEdBQUksU0FBUSx3REFBbUM7SUE4Qm5ELFlBQVksS0FBZTs7UUFDekIsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBOUJmLFdBQU0sR0FBaUMsSUFBSSxDQUFDO1FBQzVDLE9BQUUsR0FBdUIsSUFBSSxDQUFDO1FBQzlCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFFM0IsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUdULDJCQUFzQixHQUFHLHNEQUFlLEVBQWtCLENBQUM7UUFtQjVELFVBQUssR0FBZ0IsRUFBRSxDQUFDO1FBQ3hCLGVBQVUsR0FBcUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQWdPekQsbUJBQWMsR0FBeUMsR0FBRyxFQUFFOztZQUNqRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO2dCQUN4QixVQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTywwQ0FBRSxLQUFLLEVBQUUsQ0FBQzthQUM5QztRQUNILENBQUMsQ0FBQztRQUVLLHFDQUFnQyxHQUFHLEdBQUcsRUFBRTtZQUM3QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUM7UUFFSyxxQkFBZ0IsR0FBRyxHQUFHLEVBQUU7WUFDN0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2xDLENBQUMsQ0FBQztRQUVNLHFCQUFnQixHQUFHLDJEQUFrQixDQUMzQyxDQUFDLFlBQTBCLEVBQUUsRUFBRTs7WUFDN0IsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLFlBQVksS0FBSyxLQUFLLEVBQUU7Z0JBQzVDLE9BQU87YUFDUjtZQUVELElBQUksY0FBYyxHQUFzQyxJQUFJLENBQUM7WUFDN0QsSUFBSSxZQUFZLENBQUMsUUFBUSxFQUFFO2dCQUN6QixZQUFZLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFOztvQkFDeEMsSUFDRSxXQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsMENBQUUsRUFBRSxNQUFLLE9BQU8sQ0FBQyxFQUFFO3dCQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsS0FBSyxPQUFPO3dCQUNyQyw4REFBbUIsQ0FBQyxPQUFPLENBQUMsRUFDNUI7d0JBQ0EsY0FBYyxHQUFHLE9BQU8sQ0FBQztxQkFDMUI7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3JELElBQUksWUFBWSxDQUFDLGVBQWUsRUFBRTtvQkFDaEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDaEM7YUFDRjtZQUVELElBQUksWUFBWSxDQUFDLEtBQUssRUFBRTtnQkFDdEIsSUFBSSxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUMsWUFBWTtvQkFDcEMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLO29CQUNwQixDQUFDLGlDQUFNLElBQUksQ0FBQyxLQUFLLEdBQUssWUFBWSxDQUFDLEtBQUssQ0FBRSxDQUFDO2dCQUM3QyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQzthQUNqQztZQUVELElBQUksWUFBWSxDQUFDLFFBQVEsSUFBSSxjQUFjLEVBQUU7Z0JBQzNDLElBQUksWUFBWSxDQUFDLGVBQWUsRUFBRTtvQkFDaEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDaEM7Z0JBRUQsSUFBSSxlQUFlLEdBQUcsbUJBQVksYUFBWixZQUFZLHVCQUFaLFlBQVksQ0FBRSxRQUFRLDBDQUFFLGVBQWUsS0FBSSxLQUFLLENBQUM7Z0JBQ3ZFLElBQUksY0FBYyxHQUFHLG1CQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsUUFBUSwwQ0FBRSxjQUFjLEtBQUksS0FBSyxDQUFDO2dCQUNyRSxJQUFJLFFBQVEsR0FBRyxtQkFBWSxhQUFaLFlBQVksdUJBQVosWUFBWSxDQUFFLFFBQVEsMENBQUUsUUFBUSxLQUFJLElBQUksQ0FBQztnQkFDeEQsSUFBSSxLQUFLLEdBQUcsbUJBQVksYUFBWixZQUFZLHVCQUFaLFlBQVksQ0FBRSxRQUFRLDBDQUFFLEtBQUssS0FBSSxvREFBVyxDQUFDO2dCQUN6RCxJQUFJLElBQUksR0FBRyx3QkFBWSxhQUFaLFlBQVksdUJBQVosWUFBWSxDQUFFLFFBQVEsMENBQUUsSUFBSSxtQ0FBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDM0QsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLFdBQVcsRUFBRTtvQkFDckQsZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO2lCQUM5QztnQkFFRCxJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEtBQUssV0FBVyxFQUFFO29CQUNwRCxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7aUJBQzVDO2dCQUVELElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxXQUFXLEVBQUU7b0JBQ3JELFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsa0RBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2lCQUMxRDtnQkFFRCxJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUssV0FBVyxFQUFFO29CQUMzQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7aUJBQzFCO2dCQUVELElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7b0JBQzFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztpQkFDeEI7Z0JBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FDWCxDQUFDLEtBQUssRUFBRSxFQUFFOztvQkFDUiwrREFBK0Q7b0JBQy9ELDJEQUEyRDtvQkFDM0Qsc0RBQXNEO29CQUN0RCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsSUFBSSxFQUFFLEVBQUU7d0JBQ2hELGNBQWMsRUFDWixjQUFjLEtBQUksa0JBQVksQ0FBQyxRQUFRLDBDQUFFLGNBQWMsS0FBSSxJQUFJO3dCQUNqRSxlQUFlO3dCQUNmLGNBQWM7d0JBQ2QsUUFBUTt3QkFDUixLQUFLO3dCQUNMLElBQUk7cUJBQ0wsQ0FBQyxDQUFDO2dCQUNMLENBQUMsRUFDRCxHQUFHLEVBQUU7b0JBQ0gsSUFBSSxZQUFZLENBQUMsV0FBVyxFQUFFO3dCQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FDMUIsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQ3pDLENBQUM7cUJBQ0g7Z0JBQ0gsQ0FBQyxDQUNGLENBQUM7YUFDSDtRQUNILENBQUMsQ0FDRixDQUFDO1FBRUYsWUFBWTtRQUVKLFdBQU0sR0FBRywyREFBa0IsQ0FBQyxHQUFHLEVBQUU7WUFDdkMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVLLGFBQVEsR0FBRyxHQUFHLEVBQUU7WUFDdEIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUMsQ0FBQztRQUVNLGlCQUFZLEdBQWtCLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDOUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQztRQUVNLGlCQUFZLEdBQUcsR0FBRyxFQUFFO1lBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDM0QsSUFBSSx3REFBYSxDQUFDLE9BQU8sQ0FBQyxFQUFFO29CQUMxQixtRkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDcEM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUM7UUFFTSx5QkFBb0IsR0FBRyxDQUFPLEdBQVcsRUFBRSxLQUFxQixFQUFFLEVBQUU7WUFDMUUsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsaUVBQXdCLENBQUMsRUFBRTtnQkFDM0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxlQUFlLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hFLElBQUksQ0FBQyxNQUFNLENBQUMsaUVBQXdCLENBQUMsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLGlEQUFRLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ2xFO2lCQUFNLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGtFQUF5QixDQUFDLEVBQUU7Z0JBQ3JFLE1BQU0sS0FBSyxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzFELEtBQUssQ0FBQyxNQUFNLENBQUMsa0VBQXlCLENBQUMsQ0FBQztnQkFDeEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLGlEQUFRLEVBQUUsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ25FO1lBRUQsSUFBSTtnQkFDRixNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNyRCxNQUFNLElBQUksR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsMkRBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDekIsTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO2lCQUNuQjtnQkFDRCxJQUNFLEtBQUssS0FBSyxJQUFJLENBQUMsRUFBRTtvQkFDakIsTUFBTSxDQUFDLE9BQU8sQ0FDWix5Q0FBQyxDQUFDLDBCQUEwQixFQUFFO3dCQUM1QixTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTTtxQkFDNUQsQ0FBQyxDQUNILEVBQ0Q7b0JBQ0EsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7b0JBQ3BELGtEQUFrRDtvQkFDbEQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTt3QkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO3FCQUN6QztvQkFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7aUJBQ3hDO2FBQ0Y7WUFBQyxPQUFPLEtBQVUsRUFBRTtnQkFDbkIsTUFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQztnQkFDOUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN0QjtvQkFBUztnQkFDUixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdkI7UUFDSCxDQUFDLEVBQUM7UUFFTSxpQkFBWSxHQUFHLEdBQUcsRUFBRTtZQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQztRQUVGOzs7V0FHRztRQUNLLGVBQVUsR0FBRywyREFBa0IsQ0FDckMsQ0FBQyxJQUFxQyxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxpQ0FDcEIsNkRBQWtCLEVBQUUsS0FDdkIsU0FBUyxFQUFFLEtBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxpQkFBaUIsRUFBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUM1RCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQ3ZCLENBQUMsQ0FBQztZQUNKLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDLENBQ0YsQ0FBQztRQUVNLG9CQUFlLEdBQUcsR0FBUyxFQUFFO1lBQ25DLElBQUksYUFBYSxJQUFJLE1BQU0sSUFBSSxjQUFjLElBQUksTUFBTSxFQUFFO2dCQUN0RCxNQUFjLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FDckMsQ0FBTyxZQUE4QixFQUFFLEVBQUU7b0JBQ3ZDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTt3QkFDOUIsT0FBTztxQkFDUjtvQkFDRCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN6QyxNQUFNLElBQUksR0FBUyxNQUFNLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUM7b0JBQ3pCLG9EQUFZLENBQ1YsSUFBSSxFQUNKLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUN6Qzt5QkFDRSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTt3QkFDZCxJQUFJLENBQUMsZ0JBQWdCLGlDQUNoQixLQUFLLEtBQ1IsUUFBUSxrQ0FDSCxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUNqQyxTQUFTLEVBQUUsS0FBSyxLQUVsQixlQUFlLEVBQUUsSUFBSSxJQUNyQixDQUFDO29CQUNMLENBQUMsQ0FBQzt5QkFDRCxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTt3QkFDZixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7b0JBQ25FLENBQUMsQ0FBQyxDQUFDO2dCQUNQLENBQUMsRUFDRixDQUFDO2FBQ0g7WUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7Z0JBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUNwQztZQUNELElBQUksV0FBVyxHQUFHLElBQUksQ0FBQztZQUN2QixJQUFJO2dCQUNGLFdBQVcsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUM7Z0JBQ3JELElBQUksV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLFlBQVksRUFBRTtvQkFDN0IsSUFBSSxDQUFDLHVCQUF1QixHQUFHLG1FQUFtQixDQUNoRCxXQUFXLENBQUMsWUFBWSxFQUN4QixhQUFhLENBQ0UsQ0FBQztpQkFDbkI7YUFDRjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQixXQUFXLEdBQUc7b0JBQ1osUUFBUSxFQUFFO3dCQUNSLFlBQVksRUFDVixLQUFLLENBQUMsT0FBTzs0QkFDYiwrREFBK0Q7cUJBQ2xFO2lCQUNGLENBQUM7YUFDSDtZQUVELE1BQU0sS0FBSyxHQUFHLHVEQUFPLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUUvQyxLQUFLLENBQUMsUUFBUSxtQ0FDVCxLQUFLLENBQUMsUUFBUSxLQUNqQixXQUFXLEVBQ1QsS0FBSyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEtBQUssT0FBTztvQkFDcEMsQ0FBQyxDQUFDLFdBQVc7b0JBQ2IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUNoQyxTQUFTLEVBQUUsS0FBSyxHQUNqQixDQUFDO1lBQ0YsSUFBSSxXQUFXLGFBQVgsV0FBVyx1QkFBWCxXQUFXLENBQUUsZUFBZSxFQUFFO2dCQUNoQyxLQUFLLENBQUMsUUFBUSxtQ0FDVCxLQUFLLENBQUMsUUFBUSxHQUNkLDhEQUFxQixDQUN0QixLQUFLLENBQUMsUUFBUSxrQ0FFVCxLQUFLLENBQUMsUUFBUSxLQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQ3ZCLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFDekIsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMvQixVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBRW5DLElBQUksQ0FDTCxDQUNGLENBQUM7YUFDSDtZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsZ0JBQWdCLGlDQUNoQixLQUFLLEtBQ1IsZUFBZSxFQUFFLElBQUksSUFDckIsQ0FBQztZQUVILE1BQU0sVUFBVTtZQUNkLFVBQVU7WUFDVixJQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQ3BELGlFQUF3QixDQUN6QjtnQkFDRCxrQ0FBa0M7Z0JBQ2xDLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUM3QyxrRUFBeUIsQ0FDMUIsQ0FBQztZQUVKLElBQUksVUFBVSxFQUFFO2dCQUNkLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzdDO1FBQ0gsQ0FBQyxFQUFDO1FBc0ZNLGFBQVEsR0FBRywyREFBa0IsQ0FBQyxHQUFHLEVBQUU7WUFDekMsSUFBSSxDQUFDLEtBQUs7aUJBQ1AsMkJBQTJCLEVBQUU7aUJBQzdCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsbUZBQXlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUM1RCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxDQUFDO1FBOFFLLGFBQVEsR0FBRyxpREFBUSxDQUFDLEdBQUcsRUFBRTtZQUMvQixNQUFNLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDdEIsSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLFVBQVUsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtvQkFDcEUsT0FBTyxJQUFJLENBQUM7aUJBQ2I7Z0JBQ0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBRSx1REFBYyxDQUFDLENBQUM7UUFFbkIsYUFBYTtRQUVMLFVBQUssR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQXFCLEVBQUUsRUFBRTs7WUFDM0QsTUFBTSxrQkFBa0IsR0FBRyxVQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTywwQ0FBRSxRQUFRLENBQ3RFLFFBQVEsQ0FBQyxhQUFhLENBQ3ZCLENBQUM7WUFDRixJQUFJLENBQUMsa0JBQWtCLElBQUksMERBQWlCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMxRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7UUFFSyxXQUFNLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFxQixFQUFFLEVBQUU7O1lBQzVELE1BQU0sa0JBQWtCLEdBQUcsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsUUFBUSxDQUN0RSxRQUFRLENBQUMsYUFBYSxDQUN2QixDQUFDO1lBQ0YsSUFBSSxDQUFDLGtCQUFrQixJQUFJLDBEQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDMUQsT0FBTzthQUNSO1lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBRUssV0FBTSxHQUFHLEdBQUcsRUFBRTtZQUNwQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQywwREFBb0IsQ0FBQyxDQUFDO1FBQ3pELENBQUMsQ0FBQztRQUVNLFlBQU8sR0FBRyxHQUFHLEVBQUU7WUFDckIsNERBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BFLENBQUMsQ0FBQztRQU1NLGVBQVUsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUN6QyxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNoQixXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUNuQixZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDL0IsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FDbEMsR0FBRyxDQUFDLGFBQWEsRUFDakIsMERBQWlCLENBQ2xCLENBQUM7Z0JBQ0YsT0FBTzthQUNSO1lBQ0QsMkRBQTJEO1lBQzNELGtGQUFrRjtZQUNsRixJQUFJLFdBQVcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQzdDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUM5QixhQUFhO2dCQUNiLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztvQkFDM0IsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUN0QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87aUJBQ3ZCLENBQUMsQ0FBQztnQkFDSCxXQUFXLEdBQUcsS0FBSyxDQUFDO2dCQUNwQixZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQzthQUNoQztZQUNELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixrQkFBa0IsRUFBRSxFQUFFO2lCQUN2QixDQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQztRQUVNLGFBQVEsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtZQUN2QyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWiwwQkFBMEIsRUFBRSxFQUFFO29CQUM5QixrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDBCQUEwQjtpQkFDMUQsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUM7UUFFTSx1QkFBa0IsR0FBRywyREFBa0IsQ0FDN0MsQ0FBTyxLQUE0QixFQUFFLEVBQUU7O1lBQ3JDLE9BQU87WUFDUCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDO1lBQ3RDLE1BQU0sa0JBQWtCLEdBQ3RCLFVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLDBDQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ3ZCLE9BQU87YUFDUjtZQUVELE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN2RTtZQUNFLHNFQUFzRTtZQUN0RSxxQ0FBcUM7WUFDckMsS0FBSztnQkFDTCxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsWUFBWSxpQkFBaUIsQ0FBQztvQkFDakQsMERBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDNUI7Z0JBQ0EsT0FBTzthQUNSO1lBRUQseUVBQXlFO1lBQ3pFLGdFQUFnRTtZQUNoRSxpQ0FBaUM7WUFDakMsSUFBSSxJQUFJLEdBQUcsV0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGFBQWEsMENBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTFDLE1BQU0sSUFBSSxHQUFHLE1BQU0sMkRBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV6QyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ3RCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hDLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFO29CQUMxRCxzRUFBc0U7b0JBQ3RFLGlCQUFpQjtvQkFDakIsSUFBSSxHQUFHLDREQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQ2hDO2FBQ0Y7WUFFRCxJQUFJLGlFQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUM5QixNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsb0VBQTJCLENBQzFELEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQ3RDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFFRixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDakUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDNUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBRW5FLE9BQU87YUFDUjtZQUVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUU7Z0JBQ3RCLElBQUk7b0JBQ0YsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFO3dCQUNyRCxPQUFPO3FCQUNSO2lCQUNGO2dCQUFDLE9BQU8sS0FBVSxFQUFFO29CQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUN0QjthQUNGO1lBQ0QsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO2FBQ3BEO2lCQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixXQUFXLEVBQUU7d0JBQ1gsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXO3dCQUN0QixLQUFLLEVBQUUsSUFBSTtxQkFDWjtpQkFDRixDQUFDLENBQUM7YUFDSjtpQkFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyw2QkFBNkIsQ0FBQztvQkFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO29CQUN2QixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJO29CQUN6QixRQUFRLEVBQUUsUUFBUTtpQkFDbkIsQ0FBQyxDQUFDO2FBQ0o7aUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNwQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2xDO1lBQ0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNsQyxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsY0FBYyxFQUFFLENBQUM7UUFDMUIsQ0FBQyxFQUNGLENBQUM7UUFFTSxrQ0FBNkIsR0FBRyxDQUFDLElBSXhDLEVBQUUsRUFBRTtZQUNILE1BQU0sUUFBUSxHQUFHLCtEQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsMERBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUzRCxNQUFNLGVBQWUsR0FBRyxpREFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakQsTUFBTSxlQUFlLEdBQUcsaURBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWpELE1BQU0sT0FBTyxHQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO2dCQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO29CQUM1QixDQUFDLENBQUMsT0FBTztvQkFDVCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1lBQ25ELE1BQU0sT0FBTyxHQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO2dCQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO29CQUM1QixDQUFDLENBQUMsT0FBTztvQkFDVCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBRW5ELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsb0VBQTJCLENBQzFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUNwQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFFRixNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsZUFBZSxDQUFDO1lBQy9CLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUM7WUFDL0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUU3QixNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWpFLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN0QyxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQzNDLE1BQU0sVUFBVSxHQUFHLDJEQUFnQixDQUNqQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFDekIsVUFBVSxFQUNWLE9BQU8sRUFDUDtvQkFDRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSTtvQkFDM0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUk7aUJBQzVCLENBQ0YsQ0FBQztnQkFDRixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ25ELE9BQU8sVUFBVSxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsc0ZBQStCLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQzVFLE1BQU0sWUFBWSxHQUFHO2dCQUNuQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUU7Z0JBQzNDLEdBQUcsV0FBVzthQUNmLENBQUM7WUFDRiw4RUFBMkIsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLG1CQUFtQixDQUFDLENBQUM7WUFFekUsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNkLElBQUksQ0FBQyxLQUFLLG1DQUFRLElBQUksQ0FBQyxLQUFLLEdBQUssSUFBSSxDQUFDLEtBQUssQ0FBRSxDQUFDO2FBQy9DO1lBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQ1gseUVBQStCLGlDQUV4QixJQUFJLENBQUMsS0FBSyxLQUNiLGFBQWEsRUFBRSxLQUFLLEVBQ3BCLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUU7b0JBQ3RELElBQUksd0RBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUU7d0JBQ2xELEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO3FCQUN4QjtvQkFDRCxPQUFPLEdBQUcsQ0FBQztnQkFDYixDQUFDLEVBQUUsRUFBUyxDQUFDLEVBQ2IsZ0JBQWdCLEVBQUUsRUFBRSxLQUV0QixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUN6QixFQUNELEdBQUcsRUFBRTtnQkFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7b0JBQ2QsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7aUJBQ2pDO1lBQ0gsQ0FBQyxDQUNGLENBQUM7WUFDRixJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQztRQWtDRixnQkFBZ0I7UUFFaEIsZ0JBQVcsR0FBRyxDQUFDLEdBQVEsRUFBRSxFQUFFO1lBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckIsQ0FBQyxDQUFDO1FBRUYsa0JBQWEsR0FBRyxDQUFDLEtBQXFELEVBQUUsRUFBRTtZQUN4RSx5REFBeUQ7WUFDekQsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLE9BQU8sSUFBSSxZQUFZLEVBQUU7Z0JBQ2pELFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDM0IsWUFBWSxHQUFHLENBQUMsQ0FBQztnQkFDakIscUJBQXFCLEdBQUcsS0FBSyxDQUFDO2FBQy9CO1lBRUQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQztRQUVGLGVBQVUsR0FBRyxHQUFHLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO2dCQUMxQixPQUFPO29CQUNMLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQyxhQUFhO29CQUN2QyxXQUFXLEVBQUUsU0FBUyxDQUFDLGFBQWE7d0JBQ2xDLENBQUMsQ0FBQyxXQUFXO3dCQUNiLENBQUMsQ0FBQyxTQUFTLENBQUMsV0FBVztpQkFDMUIsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsa0JBQWEsR0FBRyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMseURBQW1CLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUM7UUFFRixnQkFBVyxHQUFHLEdBQUcsRUFBRTtZQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7Z0JBQ3pCLHNEQUFVLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQy9CO1lBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsdURBQWlCLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUM7UUFFRixvQkFBZSxHQUFHLENBQ2hCLFNBRW1DLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQzNELEVBQUU7WUFDRixJQUFJLENBQUMsUUFBUSxtQkFDUiw4REFBcUIsQ0FDdEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUN6QyxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxNQUFNLENBQ1osRUFDRCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsZUFBVSxHQUFHLEdBQUcsRUFBRTtZQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDO1FBRUYsb0JBQWUsR0FBRyxDQUFDLFlBQW9CLEVBQUUsRUFBRTtZQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUM7UUFFRix5QkFBb0IsR0FBRyxHQUFTLEVBQUU7WUFDaEMsSUFBSTtnQkFDRixNQUFNLG1CQUFtQixHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUVsRSxNQUFNLElBQUksR0FBRyxNQUFNLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDNUQsSUFBSSxJQUFJLEVBQUU7b0JBQ1IsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQy9CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDNUIsTUFBTSxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQ2hELE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxpREFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ3ZFO2FBQ0Y7WUFBQyxPQUFPLEtBQVUsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQzthQUNoRDtRQUNILENBQUMsRUFBQztRQUVGLDREQUE0RDtRQUNyRCxhQUFRLEdBQXdDLDJEQUFrQixDQUN2RSxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ1IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsRUFBRTtnQkFDOUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUMvQixPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBMEIsQ0FBQyxDQUFDO1lBRXRDLElBQUksQ0FBQyxLQUFLLG1DQUFRLElBQUksQ0FBQyxLQUFLLEdBQUssTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBRSxDQUFDO1lBRWhFLGdFQUFnRTtZQUNoRSx1RUFBdUU7WUFDdkUsUUFBUTtZQUNSLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQzNDLElBQ0UsK0VBQXlCLENBQUMsT0FBTyxDQUFDO29CQUNsQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFDNUI7b0JBQ0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN2QyxtRkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkMsb0VBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDdEI7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFNUIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDbEMsQ0FBQyxDQUNGLENBQUM7UUFFSyxnQkFBVyxHQUFHLDJEQUFrQixDQUNyQyxDQUEyQixTQUsxQixFQUFFLEVBQUU7WUFDSCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDaEM7WUFFRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3RCLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ25DO1lBRUQsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFO2dCQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNuRDtZQUVELElBQUksU0FBUyxDQUFDLGFBQWEsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQzthQUMzRDtRQUNILENBQUMsQ0FDRixDQUFDO1FBRU0sbUJBQWMsR0FBRyxHQUFHLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUM7UUFFTSxnQ0FBMkIsR0FBRywyREFBa0IsQ0FDdEQsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDcEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDeEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDMUIsQ0FBQyxDQUNGLENBQUM7UUFFRixpQkFBaUI7UUFFVCxjQUFTLEdBQUcsMkRBQWtCLENBQ3BDLENBQUMsS0FBMEMsRUFBRSxFQUFFO1lBQzdDLHVEQUF1RDtZQUN2RCxJQUNFLE9BQU8sSUFBSSxNQUFNO2dCQUNqQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUM3QyxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUNoRDtnQkFDQSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO29CQUN2QixHQUFHLENBQUMsRUFBTyxFQUFFLElBQUk7d0JBQ2YsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN2QixJQUFJLE9BQU8sS0FBSyxLQUFLLFVBQVUsRUFBRTs0QkFDL0IsbUNBQW1DOzRCQUNuQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7eUJBQ3ZCO3dCQUNELE9BQU8sSUFBSSxLQUFLLEtBQUs7NEJBQ25CLENBQUMsQ0FBQywrREFBK0Q7Z0NBQy9ELFVBQVU7Z0NBQ1YsS0FBSyxDQUFDLFFBQVE7b0NBQ2QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFO29DQUN0QixDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUU7NEJBQ3hCLENBQUMsQ0FBQyxLQUFLLENBQUM7b0JBQ1osQ0FBQztpQkFDRixDQUFDLENBQUM7YUFDSjtZQUVELElBQ0UsQ0FBQywwREFBaUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSywrQ0FBVyxDQUFDO2dCQUM5RCw2Q0FBNkM7Z0JBQzdDLENBQUMsa0RBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksb0RBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDcEQ7Z0JBQ0EsT0FBTzthQUNSO1lBRUQsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLHNEQUFrQixFQUFFO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGNBQWMsRUFBRSxJQUFJO2lCQUNyQixDQUFDLENBQUM7YUFDSjtZQUVELElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzNDLE9BQU87YUFDUjtZQUVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7Z0JBQzlCLE9BQU87YUFDUjtZQUVELElBQUksS0FBSyxDQUFDLG9EQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDNUM7WUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssOENBQVUsRUFBRTtnQkFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQzthQUM3RDtZQUVELElBQUksa0RBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ3pCLE1BQU0sSUFBSSxHQUNSLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO29CQUNsQixDQUFDLEtBQUssQ0FBQyxRQUFRO3dCQUNiLENBQUMsQ0FBQyxpRUFBd0I7d0JBQzFCLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMzQixDQUFDLEtBQUssQ0FBQyxRQUFRO3dCQUNiLENBQUMsQ0FBQyx1RUFBOEI7d0JBQ2hDLENBQUMsQ0FBQyxpRUFBd0IsQ0FBQyxDQUFDO2dCQUVoQyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLO3FCQUNoQyxXQUFXLEVBQUU7cUJBQ2IsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUVsRSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7Z0JBQ2hCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztnQkFFaEIsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLG1EQUFlLEVBQUU7b0JBQ2pDLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQztpQkFDakI7cUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLG9EQUFnQixFQUFFO29CQUN6QyxPQUFPLEdBQUcsSUFBSSxDQUFDO2lCQUNoQjtxQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssaURBQWEsRUFBRTtvQkFDdEMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO2lCQUNqQjtxQkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssbURBQWUsRUFBRTtvQkFDeEMsT0FBTyxHQUFHLElBQUksQ0FBQztpQkFDaEI7Z0JBRUQsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7b0JBQ25DLHNFQUFhLENBQUMsT0FBTyxFQUFFO3dCQUNyQixDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPO3dCQUN0QixDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPO3FCQUN2QixDQUFDLENBQUM7b0JBRUgsc0VBQW1CLENBQUMsT0FBTyxFQUFFO3dCQUMzQixxQkFBcUIsRUFBRSxnQkFBZ0I7cUJBQ3hDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFFakQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ3hCO2lCQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyw4Q0FBVSxFQUFFO2dCQUNuQyxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsSUFDRSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDN0IscUVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNwQztvQkFDQSxJQUNFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7d0JBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsU0FBUyxLQUFLLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFDcEU7d0JBQ0EsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQzt3QkFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixvQkFBb0IsRUFBRSxJQUFJLDhFQUFtQixDQUMzQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFDbkIsSUFBSSxDQUFDLEtBQUssQ0FDWDt5QkFDRixDQUFDLENBQUM7cUJBQ0o7aUJBQ0Y7cUJBQU0sSUFDTCxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDN0IsQ0FBQyxxRUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3JDO29CQUNBLE1BQU0sZUFBZSxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUU1QyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7d0JBQ3BCLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQzt3QkFDckQsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDO3dCQUN0RCxVQUFVLEVBQUUsSUFBSTtxQkFDakIsQ0FBQyxDQUFDO29CQUNILEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDdkIsT0FBTztpQkFDUjthQUNGO2lCQUFNLElBQ0wsQ0FBQyxLQUFLLENBQUMsT0FBTztnQkFDZCxDQUFDLEtBQUssQ0FBQyxNQUFNO2dCQUNiLENBQUMsS0FBSyxDQUFDLE9BQU87Z0JBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssSUFBSSxFQUNuQztnQkFDQSxNQUFNLEtBQUssR0FBRyx3REFBYyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDeEMsSUFBSSxLQUFLLEVBQUU7b0JBQ1QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDN0I7cUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLDBDQUFNLEVBQUU7b0JBQy9CLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztpQkFDbkI7YUFDRjtZQUNELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyw4Q0FBVSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtnQkFDM0QsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDdEIsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDZEQUFvQixDQUFDLENBQUM7YUFDOUM7WUFFRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssMENBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLDBDQUFNLEVBQUU7Z0JBQ2hELE1BQU0sZ0JBQWdCLEdBQUcsNERBQW1CLENBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQ3hCLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFDRixJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxLQUFLLFdBQVc7b0JBQ3RDLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUN4QjtvQkFDQSxPQUFPO2lCQUNSO2dCQUVELElBQ0UsS0FBSyxDQUFDLEdBQUcsS0FBSywwQ0FBTTtvQkFDcEIsQ0FBQyxzREFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO3dCQUNwQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLHNEQUFhLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDbEU7b0JBQ0EsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUM7aUJBQ3ZEO2dCQUNELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSywwQ0FBTSxFQUFFO29CQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQztpQkFDbkQ7YUFDRjtRQUNILENBQUMsQ0FDRixDQUFDO1FBRU0sWUFBTyxHQUFHLDJEQUFrQixDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFO1lBQzVELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyw4Q0FBVSxFQUFFO2dCQUM1QixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO29CQUM5QixrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQztpQkFDMUM7cUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxXQUFXLEVBQUU7b0JBQ2pELG9EQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUMxQjtxQkFBTTtvQkFDTCwwREFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUM7d0JBQ1osa0JBQWtCLEVBQUUsRUFBRTt3QkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTt3QkFDcEIsY0FBYyxFQUFFLElBQUk7cUJBQ3JCLENBQUMsQ0FBQztpQkFDSjtnQkFDRCxjQUFjLEdBQUcsS0FBSyxDQUFDO2FBQ3hCO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxvREFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDM0M7WUFDRCxJQUFJLGtEQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUN6QixNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDMUIsQ0FBQyxDQUFDLCtFQUE0QixDQUFDLGdCQUFnQixDQUFDO29CQUNoRCxDQUFDLENBQUMsdUVBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDM0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDMUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQTJCSyxtQkFBYyxHQUFHLDJEQUFrQixDQUFDLENBQUMsS0FBbUIsRUFBRSxFQUFFO1lBQ2xFLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLGtCQUFrQixFQUFFLEVBQUU7YUFDdkIsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSyxvQkFBZSxHQUFHLDJEQUFrQixDQUFDLENBQUMsS0FBbUIsRUFBRSxFQUFFO1lBQ25FLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUV2QiwyREFBMkQ7WUFDM0QscUVBQXFFO1lBQ3JFLGtFQUFrRTtZQUNsRSxnRUFBZ0U7WUFDaEUsNEJBQTRCO1lBQzVCLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO2dCQUMvQixPQUFPO2FBQ1I7WUFFRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO1lBQzFDLElBQUksWUFBWSxFQUFFO2dCQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUNsRCxJQUFJLEVBQUUsd0RBQVUsQ0FDZCwwREFBaUIsQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUM3QyxJQUFJLEVBQ0osRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsRUFDcEMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FDM0I7aUJBQ0YsQ0FBQyxDQUFDLENBQUM7YUFDTDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUssaUJBQVksR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQW1CLEVBQUUsRUFBRTtZQUNoRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWiwwQkFBMEIsRUFBRSxFQUFFO2dCQUM5QixrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDBCQUEwQjthQUMxRCxDQUFDLENBQUM7WUFDSCxPQUFPLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQztRQXNMSyxxQkFBZ0IsR0FBRyxDQUFDLEVBQzFCLE1BQU0sRUFDTixNQUFNLEVBQ04sVUFBVSxFQUNWLG9CQUFvQixHQUFHLElBQUksR0FTNUIsRUFBRSxFQUFFOztZQUNILElBQUksb0JBQW9CLEdBQ3RCLG9CQUFvQjtnQkFDcEIsSUFBSSxDQUFDLHFDQUFxQyxDQUN4QyxNQUFNLEVBQ04sTUFBTSxFQUNOLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLE1BQU0sRUFDWCxNQUFNLENBQUMsZ0JBQWdCLENBQ3hCLENBQUM7WUFFSiwrQ0FBK0M7WUFDL0MsaUNBQWlDO1lBQ2pDLE1BQU0sU0FBUyxHQUNiLFVBQVUsSUFBSSxvQkFBb0I7Z0JBQ2hDLENBQUMsQ0FBQyxxRUFBNEIsQ0FDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFDeEIsTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLENBQ1A7Z0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUVYLElBQUksbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUV4RSxxREFBcUQ7WUFDckQsSUFBSSxTQUFTLEVBQUU7Z0JBQ2IsTUFBTSxrQkFBa0IsR0FBRyw0RUFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDNUQsSUFBSSxrQkFBa0IsRUFBRTtvQkFDdEIsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQ3pDLGtCQUFrQixDQUNNLENBQUM7aUJBQzVCO2FBQ0Y7WUFDRCxJQUFJLENBQUMsbUJBQW1CLElBQUksU0FBUyxFQUFFO2dCQUNyQyxNQUFNLFVBQVUsR0FBRztvQkFDakIsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CO29CQUN4QyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUI7aUJBQzdDLENBQUM7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsNEVBQXFCLENBQUMsc0RBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxNQUFNLFNBQVMsR0FBRyw2RUFBc0IsQ0FBQyxzREFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNyRCxzRUFBYSxDQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFFBQVEsR0FBRyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JDLElBQUksb0JBQW9CLEVBQUU7b0JBQ3hCLG9CQUFvQixHQUFHLElBQUksQ0FBQyxxQ0FBcUMsQ0FDL0QsTUFBTSxFQUNOLE1BQU0sRUFDTixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxNQUFNLEVBQ1gsTUFBTSxDQUFDLGdCQUFnQixDQUN4QixDQUFDO2lCQUNIO2FBQ0Y7WUFFRCxNQUFNLE9BQU8sR0FBRyxtQkFBbUI7Z0JBQ2pDLENBQUMsQ0FBQyxtQkFBbUI7Z0JBQ3JCLENBQUMsQ0FBQyx5REFBYyxDQUFDO29CQUNiLENBQUMsRUFBRSxvQkFBb0I7d0JBQ3JCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjO3dCQUNyQyxDQUFDLENBQUMsTUFBTTtvQkFDVixDQUFDLEVBQUUsb0JBQW9CO3dCQUNyQixDQUFDLENBQUMsb0JBQW9CLENBQUMsY0FBYzt3QkFDckMsQ0FBQyxDQUFDLE1BQU07b0JBQ1YsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7b0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7b0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO29CQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7b0JBQ3RELElBQUksRUFBRSxFQUFFO29CQUNSLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtvQkFDeEMsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO29CQUM1QyxTQUFTLEVBQUUsb0JBQW9CO3dCQUM3QixDQUFDLENBQUMsUUFBUTt3QkFDVixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7b0JBQ25DLGFBQWEsRUFBRSxvQkFBb0I7d0JBQ2pDLENBQUMsQ0FBQyxRQUFRO3dCQUNWLENBQUMsQ0FBQywrREFBc0I7b0JBQzFCLFdBQVcsRUFBRSxlQUFTLGFBQVQsU0FBUyx1QkFBVCxTQUFTLENBQUUsRUFBRSxtQ0FBSSxTQUFTO2lCQUN4QyxDQUFDLENBQUM7WUFFUCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFFM0MsSUFBSSxtQkFBbUIsRUFBRTtnQkFDdkIsOERBQThEO2dCQUM5RCxnRUFBZ0U7Z0JBQ2hFLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxPQUFPLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRTtvQkFDM0Qsc0VBQWEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxhQUFhLEVBQUUsK0RBQXNCLEVBQUUsQ0FBQyxDQUFDO2lCQUNuRTthQUNGO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7b0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtvQkFDM0MsT0FBTztpQkFDUixDQUFDLENBQUM7Z0JBRUgsc0VBQXNFO2dCQUN0RSxrREFBa0Q7Z0JBQ2xELElBQUksQ0FBQyxvQkFBb0IsRUFBRTtvQkFDekIsc0VBQWEsQ0FBQyxPQUFPLEVBQUU7d0JBQ3JCLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQztxQkFDcEMsQ0FBQyxDQUFDO2lCQUNKO2FBQ0Y7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLGNBQWMsRUFBRSxPQUFPO2FBQ3hCLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUU7Z0JBQzlCLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxtQkFBbUI7YUFDekMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRU0sNEJBQXVCLEdBQUcsQ0FDaEMsS0FBMEMsRUFDMUMsRUFBRTtZQUNGLHdFQUF3RTtZQUN4RSxtQ0FBbUM7WUFDbkMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRTtnQkFDM0IsT0FBTzthQUNSO1lBQ0QsZ0VBQWdFO1lBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssV0FBVyxFQUFFO2dCQUMxQyxPQUFPO2FBQ1I7WUFFRCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFFRixJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUkscUVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN6RSxJQUNFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7b0JBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsU0FBUyxLQUFLLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFDcEU7b0JBQ0EsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQzt3QkFDWixvQkFBb0IsRUFBRSxJQUFJLDhFQUFtQixDQUMzQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFDbkIsSUFBSSxDQUFDLEtBQUssQ0FDWDtxQkFDRixDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsT0FBTzthQUNSO1lBRUQsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFekIsSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLG9FQUEyQixDQUN4RCxLQUFLLEVBQ0wsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1lBRUYsTUFBTSxnQkFBZ0IsR0FBRyw2REFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekQsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUMvQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUU3RCxNQUFNLGVBQWUsR0FDbkIsVUFBVTtvQkFDVixzRUFBNEIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUV4RSxJQUFJLGVBQWUsRUFBRTtvQkFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQzFCLHlFQUErQixpQ0FFeEIsU0FBUyxLQUNaLGNBQWMsRUFBRSxlQUFlLEVBQy9CLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxVQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQzlDLGdCQUFnQixFQUFFLEVBQUUsS0FFdEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FDekIsQ0FDRixDQUFDO29CQUNGLE9BQU87aUJBQ1I7YUFDRjtZQUVELG9EQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsb0RBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO2dCQUMzRCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNqQyxNQUFNLGVBQWUsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTSxXQUFXLEdBQUcseUVBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ3pELElBQUksV0FBVyxFQUFFO3dCQUNmLE1BQU0sR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO3dCQUN2RCxNQUFNLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztxQkFDekQ7aUJBQ0Y7Z0JBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDO29CQUNwQixNQUFNO29CQUNOLE1BQU07b0JBQ04sVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLG9CQUFvQixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU07aUJBQ3BDLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sNEJBQXVCLEdBQUcsQ0FDaEMsS0FBNEMsRUFDNUMsRUFBRTtZQUNGLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFeEUsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQ3pDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7b0JBQ3BDLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDaEIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPO2lCQUNqQixDQUFDLENBQUM7YUFDSjtZQUVELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7WUFDMUMsSUFDRSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxDQUFDO2dCQUMzQixPQUFPLENBQUMsVUFBVTtnQkFDbEIsWUFBWTtnQkFDWixPQUFPLENBQUMsZUFBZSxFQUN2QjtnQkFDQSxNQUFNLE1BQU0sR0FBRyxvREFBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDM0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDL0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDL0MsT0FBTyxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUM7Z0JBRTVCLE1BQU0sUUFBUSxHQUFHLHNEQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDcEUsTUFBTSxXQUFXLEdBQUcsUUFBUSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7Z0JBRXZELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDcEUsT0FBTyxFQUFFLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUs7b0JBQ3RDLE9BQU8sRUFBRSxPQUFPLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLO29CQUN0QyxJQUFJLEVBQUUsd0RBQVUsQ0FDZCwwREFBaUIsQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDLEVBQzdDLElBQUksRUFDSixFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxFQUNwQyxNQUFNLENBQ1A7b0JBQ0QscUJBQXFCLEVBQUUsSUFBSTtpQkFDNUIsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osSUFBSSxDQUFDLG1DQUFtQyxFQUFFLENBQUM7YUFDNUM7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLFVBQVU7b0JBQ2hCLE9BQU8sQ0FBQyxlQUFlO3dCQUN2QixPQUFPLENBQUMsWUFBWTs0QkFDbEIsSUFBSSxDQUFDO2FBQ1Y7WUFFRCxJQUFJLGNBQWMsSUFBSSxTQUFTLElBQUksbUJBQW1CLEVBQUU7Z0JBQ3RELE9BQU87YUFDUjtZQUVELE1BQU0sdUJBQXVCLEdBQUcseURBQWdCLENBQzlDLGlCQUFpQixFQUNqQixLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUNyQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUNyQyxDQUFDO1lBQ0YsTUFBTSxlQUFlLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO2dCQUMzRCxJQUFJLGVBQWUsRUFBRTtvQkFDbkIsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQzFCO3FCQUFNO29CQUNMLDBEQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztpQkFDeEQ7YUFDRjtZQUVELE1BQU0sWUFBWSxHQUFHLG9FQUEyQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEUsTUFBTSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxHQUFHLFlBQVksQ0FBQztZQUU1RCxJQUNFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO2dCQUMvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsVUFBVSxFQUMzQztnQkFDQSxNQUFNLG9CQUFvQixHQUFHLGdHQUFxQyxDQUNoRSxLQUFLLEVBQ0wsYUFBYSxFQUNiLGFBQWEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztnQkFDRixJQUFJLG9CQUFvQixLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7b0JBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUM7aUJBQ3pDO2dCQUNELElBQUksb0JBQW9CLENBQUMsb0JBQW9CLElBQUksSUFBSSxFQUFFO29CQUNyRCxJQUFJLENBQUMsMkJBQTJCLENBQUMsWUFBWSxDQUFDLENBQUM7aUJBQ2hEO3FCQUFNO29CQUNMLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2lCQUMxQzthQUNGO1lBRUQsSUFBSSwwRUFBb0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUNoRCx5RUFBeUU7Z0JBQ3pFLFlBQVk7Z0JBQ1osTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3ZDLElBQUksc0VBQWdCLENBQUMsZUFBZSxDQUFDLEVBQUU7b0JBQ3JDLElBQUksQ0FBQyw0Q0FBNEMsQ0FDL0MsZUFBZSxFQUNmLENBQUMsWUFBWSxDQUFDLEVBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsQ0FBQztpQkFDSDtxQkFBTTtvQkFDTCxJQUFJLENBQUMsMkJBQTJCLENBQUMsWUFBWSxDQUFDLENBQUM7aUJBQ2hEO2FBQ0Y7WUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO2dCQUMzQixNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDcEMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLFlBQVksQ0FBQztnQkFFdEMsTUFBTSxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxHQUFHLFlBQVksQ0FBQztnQkFDcEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBRTVDLDBEQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFFdkQsSUFBSSxTQUFTLEtBQUssa0JBQWtCLEVBQUU7b0JBQ3BDLHNFQUFzRTtvQkFDdEUseUJBQXlCO29CQUN6QixJQUNFLGtEQUFVLENBQ1IsYUFBYSxHQUFHLEVBQUUsRUFDbEIsYUFBYSxHQUFHLEVBQUUsRUFDbEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUNaLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FDYixJQUFJLCtEQUFzQixFQUMzQjt3QkFDQSxzRUFBYSxDQUFDLFlBQVksRUFBRTs0QkFDMUIsTUFBTSxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxhQUFhLEdBQUcsRUFBRSxFQUFFLGFBQWEsR0FBRyxFQUFFLENBQUMsQ0FBQzt5QkFDOUQsQ0FBQyxDQUFDO3FCQUNKO3lCQUFNO3dCQUNMLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO3dCQUM1QyxtRUFBbUU7d0JBQ25FLDJEQUEyRDtxQkFDNUQ7aUJBQ0Y7cUJBQU0sSUFDTCxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7b0JBQ2pCLGtCQUFrQjtvQkFDbEIsa0RBQVUsQ0FDUixhQUFhLEdBQUcsRUFBRSxFQUNsQixhQUFhLEdBQUcsRUFBRSxFQUNsQixrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFDckIsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQ3RCLEdBQUcsK0RBQXNCLEVBQzFCO29CQUNBLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0REFBbUIsQ0FBQyxDQUFDO29CQUM1QyxzRUFBYSxDQUFDLFlBQVksRUFBRTt3QkFDMUIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUM1QixDQUFDLENBQUM7aUJBQ0o7cUJBQU07b0JBQ0wsSUFBSSxtREFBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTt3QkFDOUMsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDREQUFtQixDQUFDLENBQUM7cUJBQzdDO29CQUNELGdDQUFnQztvQkFDaEMsc0VBQWEsQ0FBQyxZQUFZLEVBQUU7d0JBQzFCLE1BQU0sRUFBRTs0QkFDTixHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDOzRCQUN0QixDQUFDLGFBQWEsR0FBRyxFQUFFLEVBQUUsYUFBYSxHQUFHLEVBQUUsQ0FBQzt5QkFDekM7cUJBQ0YsQ0FBQyxDQUFDO2lCQUNKO2dCQUVELE9BQU87YUFDUjtZQUVELE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuRCxJQUNFLG1CQUFtQjtnQkFDbkIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxXQUFXO29CQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxNQUFNLENBQUMsRUFDcEM7Z0JBQ0EsT0FBTzthQUNSO1lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUUxQyxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkUsSUFDRSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFDN0IsQ0FBQyxlQUFlO2dCQUNoQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQ2hDO2dCQUNBLE1BQU0sOEJBQThCLEdBQUcsNEVBQWlDLENBQ3RFLFFBQVEsRUFDUixJQUFJLENBQUMsS0FBSyxFQUNWLGFBQWEsRUFDYixhQUFhLEVBQ2IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQ2YsS0FBSyxDQUFDLFdBQVcsQ0FDbEIsQ0FBQztnQkFDRixJQUNFLDhCQUE4QjtvQkFDOUIsOEJBQThCLENBQUMsbUJBQW1CLEVBQ2xEO29CQUNBLGtEQUFTLENBQ1AsSUFBSSxDQUFDLE1BQU0sRUFDWCxzRUFBMkIsQ0FBQyw4QkFBOEIsQ0FBQyxDQUM1RCxDQUFDO29CQUNGLE9BQU87aUJBQ1I7YUFDRjtpQkFBTSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQzFELE1BQU0sbUJBQW1CLEdBQUcsMkVBQWdDLENBQzFELDBEQUFlLENBQUMsZ0JBQWdCLENBQUMsRUFDakMsYUFBYSxFQUNiLGFBQWEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFDZixLQUFLLENBQUMsV0FBVyxDQUNsQixDQUFDO2dCQUNGLElBQUksbUJBQW1CLEVBQUU7b0JBQ3ZCLGtEQUFTLENBQ1AsSUFBSSxDQUFDLE1BQU0sRUFDWCxzRUFBMkIsQ0FBQzt3QkFDMUIsbUJBQW1CO3FCQUNwQixDQUFDLENBQ0gsQ0FBQztvQkFDRixPQUFPO2lCQUNSO2FBQ0Y7WUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQzFDLFlBQVksQ0FBQyxDQUFDLEVBQ2QsWUFBWSxDQUFDLENBQUMsQ0FDZixDQUFDO1lBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxNQUFNLEVBQUU7Z0JBQ3JDLGtEQUFTLENBQ1AsSUFBSSxDQUFDLE1BQU0sRUFDWCx3REFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyx5REFBZ0IsQ0FBQyxDQUFDLENBQUMsOERBQXFCLENBQ3JFLENBQUM7YUFDSDtpQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO2dCQUNyQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQzthQUMxQztpQkFBTSxJQUFJLGVBQWUsRUFBRTtnQkFDMUIsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlEQUFnQixDQUFDLENBQUM7YUFDMUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO2dCQUMxQyxNQUFNLE9BQU8sR0FBRyx5RkFBOEIsQ0FDNUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQzFDLENBQUM7Z0JBQ0YsSUFDRSxPQUFPO29CQUNQLDhGQUF5QyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFO3dCQUM3RCxZQUFZLENBQUMsQ0FBQzt3QkFDZCxZQUFZLENBQUMsQ0FBQztxQkFDZixDQUFDLEVBQ0Y7b0JBQ0Esa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHlEQUFnQixDQUFDLENBQUM7aUJBQzFDO3FCQUFNO29CQUNMLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5REFBZ0IsQ0FBQyxDQUFDO2lCQUMxQzthQUNGO2lCQUFNO1lBQ0wsd0NBQXdDO1lBQ3hDLENBQUMsS0FBSyxDQUFDLG9EQUFnQixDQUFDO2dCQUN4QixDQUFDLFVBQVU7b0JBQ1QsSUFBSSxDQUFDLDRDQUE0QyxDQUMvQyxZQUFZLEVBQ1osZ0JBQWdCLENBQ2pCLENBQUMsRUFDSjtnQkFDQSxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQzthQUMxQztpQkFBTTtnQkFDTCxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUseURBQWdCLENBQUMsQ0FBQzthQUMxQztRQUNILENBQUMsQ0FBQztRQUVGLDJDQUEyQztRQUNuQyxvQkFBZSxHQUFHLENBQUMsS0FBMEMsRUFBRSxFQUFFO1lBQ3ZFLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUMvQixDQUFDLENBQUM7UUFFTSw0QkFBdUIsR0FBRyxDQUNoQyxLQUE0QyxFQUM1QyxFQUFFO1lBQ0Ysb0VBQW9FO1lBQ3BFLHdFQUF3RTtZQUN4RSw4Q0FBOEM7WUFDOUMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzFDLElBQUksU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLFVBQVUsRUFBRTtnQkFDekIsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQzdCO1lBRUQsSUFBSSxDQUFDLGtEQUFrRCxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU5QyxJQUFJLFNBQVMsRUFBRTtnQkFDYixPQUFPO2FBQ1I7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxXQUFXO2dCQUN0QyxZQUFZLEVBQUUsTUFBTTthQUNyQixDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUV2RCxJQUFJLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDcEQsT0FBTzthQUNSO1lBRUQseUNBQXlDO1lBQ3pDLElBQ0UsS0FBSyxDQUFDLE1BQU0sS0FBSyw0REFBbUI7Z0JBQ3BDLEtBQUssQ0FBQyxNQUFNLEtBQUssNkRBQW9CLEVBQ3JDO2dCQUNBLE9BQU87YUFDUjtZQUVELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2Qyw2QkFBNkI7WUFDN0IsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUU7Z0JBQzdCLE9BQU87YUFDUjtZQUVELHVFQUF1RTtZQUN2RSwwRUFBMEU7WUFDMUUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFN0QsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLEVBQUU7Z0JBQ3pELE9BQU87YUFDUjtZQUVELElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU5QyxJQUFJLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsRUFBRTtnQkFDOUQsT0FBTzthQUNSO1lBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxNQUFNLEVBQUU7Z0JBQ3JDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdEQsT0FBTzthQUNSO2lCQUFNLElBQ0wsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssT0FBTztnQkFDbEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssTUFBTSxFQUNqQztnQkFDQSxJQUFJLENBQUMsZ0NBQWdDLENBQ25DLEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFDdEIsZ0JBQWdCLENBQ2pCLENBQUM7YUFDSDtpQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxLQUFLLE9BQU8sRUFBRTtnQkFDN0MscUNBQXFDO2dCQUNyQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsOERBQXFCLENBQUMsQ0FBQztnQkFFOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUU7b0JBQ25DLE9BQU87aUJBQ1I7Z0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUI7b0JBQy9DLGNBQWMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtvQkFDOUMsbUJBQW1CLEVBQUUsSUFBSTtvQkFDekIsWUFBWSxFQUFFLElBQUk7aUJBQ25CLENBQUMsQ0FBQztnQkFFSCxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLG9FQUEyQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hFLHNFQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRTtvQkFDNUMsQ0FBQztvQkFDRCxDQUFDO2lCQUNGLENBQUMsQ0FBQzthQUNKO2lCQUFNLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssVUFBVSxFQUFFO2dCQUNoRCxJQUFJLENBQUMsa0NBQWtDLENBQ3JDLEtBQUssRUFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFDdEIsZ0JBQWdCLENBQ2pCLENBQUM7YUFDSDtpQkFBTTtnQkFDTCxJQUFJLENBQUMsaUNBQWlDLENBQ3BDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUN0QixnQkFBZ0IsQ0FDakIsQ0FBQzthQUNIO1lBRUQsTUFBTSxhQUFhLEdBQ2pCLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTdELE1BQU0sV0FBVyxHQUNmLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRXJFLGFBQWEsR0FBRyxXQUFXLENBQUM7WUFFNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO2dCQUMvQixNQUFNLENBQUMsZ0JBQWdCLENBQUMsMkRBQWtCLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQzNELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx5REFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDdkQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHNEQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ2xELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM5QyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQztnQkFDdkQsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7Z0JBQ25ELGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO2dCQUNsRCxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQzthQUN2RDtRQUNILENBQUMsQ0FBQztRQUVNLHVEQUFrRCxHQUFHLENBQzNELEtBQTRDLEVBQ3RDLEVBQUU7WUFDUixrREFBa0Q7WUFDbEQsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLE9BQU8sRUFBRTtnQkFDakMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO2dCQUU5QixJQUFJLFlBQVksRUFBRTtvQkFDaEIscUVBQXFFO29CQUNyRSxzRUFBc0U7b0JBQ3RFLGdCQUFnQjtvQkFDaEIscUJBQXFCLEdBQUcsSUFBSSxDQUFDO2lCQUM5QjtxQkFBTTtvQkFDTCxtRUFBbUU7b0JBQ25FLDZCQUE2QjtvQkFDN0IsWUFBWSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNwQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO3dCQUNqQixJQUFJLENBQUMscUJBQXFCLEVBQUU7NEJBQzFCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzt5QkFDckM7b0JBQ0gsQ0FBQyxFQUFFLCtEQUFzQixDQUFDLENBQUM7aUJBQzVCO2FBQ0Y7UUFDSCxDQUFDLENBQUM7UUFhRix5Q0FBeUM7UUFDakMseUNBQW9DLEdBQUcsQ0FDN0MsS0FBNEMsRUFDbkMsRUFBRTtZQUNYLElBQ0UsQ0FBQyxDQUNDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUM7Z0JBQzNCLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyw2REFBb0I7b0JBQ3BDLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyw0REFBbUIsSUFBSSxjQUFjLENBQUM7b0JBQ3hELElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQzlCLEVBQ0Q7Z0JBQ0EsT0FBTyxLQUFLLENBQUM7YUFDZDtZQUNELFNBQVMsR0FBRyxJQUFJLENBQUM7WUFFakIsSUFBSSxrQkFBa0IsR0FBRyxLQUFLLENBQUM7WUFDL0IsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXhELGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw2REFBb0IsQ0FBQyxDQUFDO1lBQzdDLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxLQUFLLENBQUM7WUFDL0MsTUFBTSxhQUFhLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFtQixFQUFFLEVBQUU7Z0JBQy9ELE1BQU0sTUFBTSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUNyQyxNQUFNLE1BQU0sR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztnQkFDckMsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7Z0JBQ3RCLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUV0Qjs7O21CQUdHO2dCQUNILElBQ0UsT0FBTztvQkFDUCxDQUFDLGtCQUFrQjtvQkFDbkIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUM5QztvQkFDQSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7b0JBRTFCLGtDQUFrQztvQkFDbEMsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQXFCLEVBQUUsRUFBRTt3QkFDakQsUUFBUSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxvREFBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7d0JBQ2pFLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDMUIsQ0FBQyxDQUFDO29CQUVGOzs7Ozt1QkFLRztvQkFDSCxNQUFNLGVBQWUsR0FBRyxHQUFHLEVBQUU7d0JBQzNCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7NEJBQ2QsUUFBUSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxvREFBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7NEJBQ2pFLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyx5REFBZ0IsRUFBRSxlQUFlLENBQUMsQ0FBQzt3QkFDaEUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUNWLENBQUMsQ0FBQztvQkFFRixRQUFRLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG9EQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztvQkFDOUQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLGVBQWUsQ0FBQyxDQUFDO2lCQUM1RDtnQkFFRCxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSztvQkFDNUQsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLO2lCQUM3RCxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLDJEQUFrQixDQUNqQyxDQUFDLGFBQWEsR0FBRyxHQUFHLEVBQUU7Z0JBQ3BCLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQ3JCLFNBQVMsR0FBRyxLQUFLLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxjQUFjLEVBQUU7b0JBQ25CLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7d0JBQzlCLGtEQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx5REFBZ0IsQ0FBQyxDQUFDO3FCQUMxQzt5QkFBTTt3QkFDTCwwREFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7cUJBQ3hEO2lCQUNGO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osWUFBWSxFQUFFLElBQUk7aUJBQ25CLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDckQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLDJEQUFrQixFQUFFLGFBQWEsQ0FBQyxDQUFDO2dCQUM5RCxNQUFNLENBQUMsbUJBQW1CLENBQUMseURBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxtREFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUNILENBQUM7WUFDRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsbURBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM5QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsMkRBQWtCLEVBQUUsYUFBYSxFQUFFO2dCQUN6RCxPQUFPLEVBQUUsSUFBSTthQUNkLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx5REFBZ0IsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNwRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQztRQTBITSxzQ0FBaUMsR0FBRyxHQUFTLEVBQUU7WUFDckQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxXQUFXLEVBQUU7Z0JBQzFDLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osa0JBQWtCLEVBQUUsRUFBRTtvQkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtvQkFDcEIsY0FBYyxFQUFFLElBQUk7aUJBQ3JCLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRUY7O1dBRUc7UUFDSyxpQ0FBNEIsR0FBRyxDQUNyQyxLQUE0QyxFQUM1QyxnQkFBa0MsRUFDekIsRUFBRTs7WUFDWCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxLQUFLLFdBQVcsRUFBRTtnQkFDMUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDMUMsTUFBTSxnQkFBZ0IsR0FBRyw0REFBbUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNuRSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUNyRSxNQUFNLDhCQUE4QixHQUNsQyw0RUFBaUMsQ0FDL0IsUUFBUSxFQUNSLElBQUksQ0FBQyxLQUFLLEVBQ1YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQ2YsS0FBSyxDQUFDLFdBQVcsQ0FDbEIsQ0FBQztvQkFDSixJQUFJLDhCQUE4QixJQUFJLElBQUksRUFBRTt3QkFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixlQUFlLEVBQUUsOEJBQThCLENBQUMsT0FBTzt5QkFDeEQsQ0FBQyxDQUFDO3dCQUNILGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVOzRCQUNoQyw4QkFBOEIsQ0FBQyxtQkFBbUIsQ0FBQztxQkFDdEQ7aUJBQ0Y7cUJBQU0sSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUN0QyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLDJFQUFnQyxDQUNuRSwwREFBZSxDQUFDLGdCQUFnQixDQUFDLEVBQ2pDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNmLEtBQUssQ0FBQyxXQUFXLENBQ2xCLENBQUM7aUJBQ0g7Z0JBQ0QsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO29CQUN0QyxrREFBUyxDQUNQLElBQUksQ0FBQyxNQUFNLEVBQ1gsc0VBQTJCLENBQUM7d0JBQzFCLG1CQUFtQixFQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVO3FCQUN4RCxDQUFDLENBQ0gsQ0FBQztvQkFDRixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztvQkFDMUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxxREFBWSxDQUMzQyw0REFBaUIsQ0FDZixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUNsQyxnQkFBZ0IsRUFDaEIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsQ0FDRixDQUFDO29CQUNGLElBQ0UsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7d0JBQzdCLHFFQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3BDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUN2Qzt3QkFDQSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLGtFQUF1QixDQUM5RCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUNsQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FDcEIsQ0FBQztxQkFDSDtpQkFDRjtxQkFBTTtvQkFDTCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7d0JBQ25DLE1BQU0sR0FBRyxHQUFHLGdHQUFxQyxDQUMvQyxLQUFLLEVBQ0wsSUFBSSxDQUFDLEtBQUssRUFDVixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFDckMsSUFBSSxDQUFDLE9BQU8sRUFDWixnQkFBZ0IsQ0FBQyxNQUFNLENBQ3hCLENBQUM7d0JBQ0YsSUFBSSxHQUFHLENBQUMsVUFBVSxFQUFFOzRCQUNsQixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUM7eUJBQy9DO3dCQUNELElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRTs0QkFDbkIsT0FBTyxJQUFJLENBQUM7eUJBQ2I7cUJBQ0Y7b0JBRUQsc0RBQXNEO29CQUN0RCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTzt3QkFDMUIsc0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sbUNBQzVCLElBQUksQ0FBQyxvQkFBb0IsQ0FDdkIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsQ0FBQztvQkFFSixJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUU7d0JBQ2hDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxtQkFBbUI7NEJBQ3RDLDhGQUF5QyxDQUN2QyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUM1QixJQUFJLENBQUMsS0FBSyxFQUNWLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQ3ZELENBQUM7cUJBQ0w7b0JBRUQsK0NBQStDO29CQUMvQyxvQkFBb0I7b0JBQ3BCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUM5RCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUMxQixDQUFDO29CQUVGLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7b0JBQ2hELE1BQU0sd0JBQXdCLEdBQzVCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDbkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUNqQyxDQUFDO29CQUNKLElBQ0UsQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLENBQUMsd0JBQXdCLENBQUM7d0JBQ2xELENBQUMsS0FBSyxDQUFDLFFBQVE7d0JBQ2YsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMseUNBQXlDLEVBQy9EO3dCQUNBLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7cUJBQ2pDO29CQUVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTt3QkFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixrQkFBa0IsRUFBRTtnQ0FDbEIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUk7NkJBQ2xEO3lCQUNGLENBQUMsQ0FBQzt3QkFDSCwyQkFBMkI7cUJBQzVCO3lCQUFNLElBQUksVUFBVSxJQUFJLElBQUksRUFBRTt3QkFDN0IsbUVBQW1FO3dCQUNuRSxJQUFJLEtBQUssQ0FBQyxvREFBZ0IsQ0FBQyxFQUFFOzRCQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0NBQ2pELGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7NkJBQ2pEOzRCQUNELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLGlDQUN4QixxRUFBMkIsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEtBQ3JELDBCQUEwQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLElBQ3pELENBQUMsQ0FBQzs0QkFDSiw4REFBOEQ7NEJBQzlELE9BQU8sS0FBSyxDQUFDO3lCQUNkO3dCQUVELCtCQUErQjt3QkFDL0Isd0RBQXdEO3dCQUN4RCx3REFBd0Q7d0JBQ3hELG1CQUFtQjt3QkFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFOzRCQUNqRCxvRkFBb0Y7NEJBQ3BGLElBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjO2dDQUN6QixDQUFDLDBEQUFnQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUN4RDtnQ0FDQSxJQUFJLENBQUMsUUFBUSxDQUFDO29DQUNaLGtCQUFrQixFQUFFLEVBQUU7b0NBQ3RCLGdCQUFnQixFQUFFLEVBQUU7b0NBQ3BCLGNBQWMsRUFBRSxJQUFJO2lDQUNyQixDQUFDLENBQUM7NkJBQ0o7NEJBRUQsbUVBQW1FOzRCQUNuRSxpRUFBaUU7NEJBQ2pFLDJEQUEyRDs0QkFDM0QsSUFDRSxDQUFDLHdCQUF3QjtnQ0FDekIsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMseUNBQXlDLEVBQy9EO2dDQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtvQ0FDMUIsT0FBTyx5RUFBK0IsaUNBRS9CLFNBQVMsS0FDWixrQkFBa0Isa0NBQ2IsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLFFBR3pCLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQ3pCLENBQUM7Z0NBQ0osQ0FBQyxDQUFDLENBQUM7Z0NBQ0gsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQzs2QkFDakQ7eUJBQ0Y7cUJBQ0Y7b0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQzt3QkFDWiwwQkFBMEIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtxQkFDMUQsQ0FBQyxDQUFDO2lCQUNKO2FBQ0Y7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FBQztRQXlCTSw0QkFBdUIsR0FBRyxDQUNoQyxLQUE0QyxFQUM1QyxnQkFBa0MsRUFDNUIsRUFBRTtZQUNSLDBEQUEwRDtZQUMxRCw0REFBNEQ7WUFDNUQsMEJBQTBCO1lBQzFCLElBQUksd0RBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUFFO2dCQUM1QyxPQUFPO2FBQ1I7WUFDRCxJQUFJLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksTUFBTSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFFdkMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUU7Z0JBQ3hELHVCQUF1QixFQUFFLElBQUk7YUFDOUIsQ0FBQyxDQUFDO1lBRUgsTUFBTSxXQUFXLEdBQUcseUVBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakQsSUFBSSxXQUFXLEVBQUU7Z0JBQ2YsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQ3ZDLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2FBQ3pDO1lBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDO2dCQUNwQixNQUFNO2dCQUNOLE1BQU07Z0JBQ04sVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLG9CQUFvQixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU07YUFDcEMsQ0FBQyxDQUFDO1lBRUgsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFO2dCQUM3QixJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLFdBQVcsRUFBRSxXQUFXO2lCQUN6QixDQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQztRQUVNLHVDQUFrQyxHQUFHLENBQzNDLEtBQTRDLEVBQzVDLFdBQThDLEVBQzlDLGdCQUFrQyxFQUNsQyxFQUFFO1lBQ0YsZ0VBQWdFO1lBQ2hFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsb0RBQVksQ0FDakMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsSUFBSSxDQUNMLENBQUM7WUFFRixNQUFNLE9BQU8sR0FBRyx3RUFBa0IsQ0FBQztnQkFDakMsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLENBQUMsRUFBRSxLQUFLO2dCQUNSLENBQUMsRUFBRSxLQUFLO2dCQUNSLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsMEJBQTBCO2dCQUN0RCxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtnQkFDdEMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQWdDO2dCQUM1RCxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsUUFBUSxLQUFLLEdBQUc7YUFDekMsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDNUIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxHQUNwQjthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLGdCQUFnQjtnQkFDeEMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTO2dCQUNuQixDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRTNDLHNFQUFhLENBQUMsT0FBTyxFQUFFO2dCQUNyQixNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDaEIsU0FBUzthQUNWLENBQUMsQ0FBQztZQUVILE1BQU0sWUFBWSxHQUFHLDhFQUEyQixDQUM5QyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtnQkFDM0MsT0FBTzthQUNSLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1osZUFBZSxFQUFFLE9BQU87Z0JBQ3hCLGNBQWMsRUFBRSxPQUFPO2dCQUN2QixpQkFBaUIsRUFBRSxZQUFZO2dCQUMvQixpQkFBaUIsRUFBRSxFQUFFO2FBQ3RCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVNLHVCQUFrQixHQUFHLENBQUMsRUFDNUIsTUFBTSxFQUNOLE1BQU0sR0FJUCxFQUFFLEVBQUU7WUFDSCxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXpFLE1BQU0sT0FBTyxHQUFHLDBEQUFlLENBQUM7Z0JBQzlCLElBQUksRUFBRSxPQUFPO2dCQUNiLENBQUMsRUFBRSxLQUFLO2dCQUNSLENBQUMsRUFBRSxLQUFLO2dCQUNSLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsMEJBQTBCO2dCQUN0RCxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtnQkFDdEMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQWdDO2FBQzdELENBQUMsQ0FBQztZQUVILE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUMsQ0FBQztRQUVNLHFDQUFnQyxHQUFHLENBQ3pDLEtBQTRDLEVBQzVDLFdBQTRDLEVBQzVDLGdCQUFrQyxFQUM1QixFQUFFO1lBQ1IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRTtnQkFDM0IsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBRXBDLGdDQUFnQztnQkFDaEMsSUFDRSxZQUFZLENBQUMsSUFBSSxLQUFLLE1BQU07b0JBQzVCLG1EQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFDdkQ7b0JBQ0Esc0VBQWEsQ0FBQyxZQUFZLEVBQUU7d0JBQzFCLGtCQUFrQixFQUNoQixZQUFZLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztxQkFDdEQsQ0FBQyxDQUFDO29CQUNILElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztvQkFDakQsT0FBTztpQkFDUjtnQkFFRCxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLGtCQUFrQixFQUFFLEdBQUcsWUFBWSxDQUFDO2dCQUUxRCwrQ0FBK0M7Z0JBQy9DLElBQ0UsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztvQkFDOUIsa0JBQWtCO29CQUNsQixrREFBVSxDQUNSLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUM5QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFDOUIsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEVBQ3JCLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUN0QixHQUFHLCtEQUFzQixFQUMxQjtvQkFDQSxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7b0JBQ2pELE9BQU87aUJBQ1I7Z0JBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDNUIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUN4QjtpQkFDRixDQUFDLENBQUMsQ0FBQztnQkFDSixxRUFBcUU7Z0JBQ3JFLFFBQVE7Z0JBQ1Isc0VBQWEsQ0FBQyxZQUFZLEVBQUU7b0JBQzFCLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2lCQUN4RSxDQUFDLENBQUM7Z0JBQ0gsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDREQUFtQixDQUFDLENBQUM7YUFDN0M7aUJBQU07Z0JBQ0wsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztnQkFFRjs7O3dDQUd3QjtnQkFFeEIsTUFBTSxFQUFFLHlCQUF5QixFQUFFLHVCQUF1QixFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDMUUsTUFBTSxDQUFDLGNBQWMsRUFBRSxZQUFZLENBQUMsR0FDbEMsV0FBVyxLQUFLLE9BQU87b0JBQ3JCLENBQUMsQ0FBQyxDQUFDLHlCQUF5QixFQUFFLHVCQUF1QixDQUFDO29CQUN0RCxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRW5CLE1BQU0sT0FBTyxHQUFHLDJEQUFnQixDQUFDO29CQUMvQixJQUFJLEVBQUUsV0FBVztvQkFDakIsQ0FBQyxFQUFFLEtBQUs7b0JBQ1IsQ0FBQyxFQUFFLEtBQUs7b0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7b0JBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO29CQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7b0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO29CQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0M7b0JBQzVELGNBQWM7b0JBQ2QsWUFBWTtpQkFDYixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDNUIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxHQUNwQjtpQkFDRixDQUFDLENBQUMsQ0FBQztnQkFDSixzRUFBYSxDQUFDLE9BQU8sRUFBRTtvQkFDckIsTUFBTSxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNwQyxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxZQUFZLEdBQUcsOEVBQTJCLENBQzlDLGdCQUFnQixDQUFDLE1BQU0sRUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7b0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtvQkFDM0MsT0FBTztpQkFDUixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsT0FBTztvQkFDeEIsY0FBYyxFQUFFLE9BQU87b0JBQ3ZCLGlCQUFpQixFQUFFLFlBQVk7b0JBQy9CLGlCQUFpQixFQUFFLEVBQUU7aUJBQ3RCLENBQUMsQ0FBQzthQUNKO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sc0NBQWlDLEdBQUcsQ0FDMUMsV0FBNkMsRUFDN0MsZ0JBQWtDLEVBQzVCLEVBQUU7WUFDUixNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQ2pDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNwQixDQUFDO1lBQ0YsTUFBTSxPQUFPLEdBQUcscURBQVUsQ0FBQztnQkFDekIsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLENBQUMsRUFBRSxLQUFLO2dCQUNSLENBQUMsRUFBRSxLQUFLO2dCQUNSLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsMEJBQTBCO2dCQUN0RCxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtnQkFDOUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO2dCQUM5QyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7Z0JBQzFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtnQkFDdEMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsMEJBQTBCO2FBQ3ZELENBQUMsQ0FBQztZQUVILElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQ2hDLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osZ0JBQWdCLEVBQUUsT0FBTztvQkFDekIsZUFBZSxFQUFFLE9BQU87aUJBQ3pCLENBQUMsQ0FBQzthQUNKO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7b0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtvQkFDM0MsT0FBTztpQkFDUixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixZQUFZLEVBQUUsSUFBSTtvQkFDbEIsZUFBZSxFQUFFLE9BQU87b0JBQ3hCLGNBQWMsRUFBRSxPQUFPO2lCQUN4QixDQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQztRQTh1Qk0sb0JBQWUsR0FBRyxDQUFPLEVBQy9CLFNBQVMsRUFDVCxZQUFZLEVBQUUsYUFBYSxFQUMzQixzQkFBc0IsR0FBRyxLQUFLLEdBSy9CLEVBQUUsRUFBRTs7WUFDSCwyRUFBMkU7WUFDM0UsOEJBQThCO1lBQzlCLElBQUksQ0FBQyxpRUFBb0IsQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQzthQUNsRDtZQUNELE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFFaEMsa0RBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRS9CLElBQUksUUFBUSxLQUFLLHVEQUFjLEVBQUU7Z0JBQy9CLElBQUk7b0JBQ0YsU0FBUyxHQUFHLDREQUFlLENBQ3pCLE1BQU0sNkRBQVksQ0FBQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUMxQyxTQUFTLENBQUMsSUFBSSxDQUNmLENBQUM7aUJBQ0g7Z0JBQUMsT0FBTyxLQUFVLEVBQUU7b0JBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLENBQUM7aUJBQ2xEO2FBQ0Y7WUFFRCw0REFBNEQ7WUFDNUQsNERBQTREO1lBQzVELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLGdCQUFJLENBQUMsS0FBSyxFQUFDLGlCQUFpQixtREFDakQsU0FBUyxDQUNVLEtBQUksK0RBQWtCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUV4RCxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNYLE9BQU8sQ0FBQyxJQUFJLENBQ1Ysc0ZBQXNGLENBQ3ZGLENBQUM7Z0JBQ0YsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBQyxDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQzthQUMvQztZQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsaUJBQWdCLGFBQWhCLGdCQUFnQix1QkFBaEIsZ0JBQWdCLENBQUUsT0FBTyxHQUFFO2dCQUM5QixJQUFJO29CQUNGLFNBQVMsR0FBRyxNQUFNLDREQUFlLENBQUMsU0FBUyxFQUFFO3dCQUMzQyxnQkFBZ0IsRUFBRSwwRUFBaUM7cUJBQ3BELENBQUMsQ0FBQztpQkFDSjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFDeEU7Z0JBRUQsSUFBSSxTQUFTLENBQUMsSUFBSSxHQUFHLCtEQUFzQixFQUFFO29CQUMzQyxNQUFNLElBQUksS0FBSyxDQUNiLHlDQUFDLENBQUMsbUJBQW1CLEVBQUU7d0JBQ3JCLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsK0RBQXNCLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJO3FCQUNqRSxDQUFDLENBQ0gsQ0FBQztpQkFDSDthQUNGO1lBRUQsSUFBSSxzQkFBc0IsRUFBRTtnQkFDMUIsTUFBTSxPQUFPLEdBQUcsVUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsMENBQUUsT0FBTyxDQUFDO2dCQUM1QyxrRUFBa0U7Z0JBQ2xFLG9DQUFvQztnQkFDcEMsNERBQTREO2dCQUM1RCxNQUFNLFdBQVcsR0FBRyxPQUFPLElBQUksMERBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFdEQsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsSUFBSSxTQUFTLENBQUMsQ0FBQzthQUN0RDtZQUVELE1BQU0sT0FBTyxHQUNYLFdBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLDBDQUFFLE9BQU8sS0FBSSxDQUFDLE1BQU0sdURBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBRS9ELE1BQU0sWUFBWSxHQUFHLHNFQUFhLENBQ2hDLGFBQWEsRUFDYjtnQkFDRSxNQUFNO2FBQ1AsRUFDRCxLQUFLLENBQzJDLENBQUM7WUFFbkQsT0FBTyxJQUFJLE9BQU8sQ0FDaEIsQ0FBTyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7O2dCQUN4QixJQUFJO29CQUNGLElBQUksQ0FBQyxLQUFLLG1DQUNMLElBQUksQ0FBQyxLQUFLLEtBQ2IsQ0FBQyxNQUFNLENBQUMsRUFBRTs0QkFDUixRQUFROzRCQUNSLEVBQUUsRUFBRSxNQUFNOzRCQUNWLE9BQU87NEJBQ1AsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7eUJBQ3BCLEdBQ0YsQ0FBQztvQkFDRixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDcEQsSUFBSSxDQUFDLGVBQWUsRUFBRTt3QkFDcEIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7d0JBQ2hDLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztxQkFDN0M7b0JBQ0QsSUFBSSxnQkFBZSxhQUFmLGVBQWUsdUJBQWYsZUFBZSxDQUFFLEtBQUssYUFBWSxPQUFPLEVBQUU7d0JBQzdDLE1BQU0sZUFBZSxDQUFDLEtBQUssQ0FBQztxQkFDN0I7b0JBQ0QsSUFDRSxXQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQiwwQ0FBRSxFQUFFLE1BQUssWUFBWSxDQUFDLEVBQUU7d0JBQ3RELFdBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSwwQ0FBRSxFQUFFLE1BQUssWUFBWSxDQUFDLEVBQUUsRUFDbEQ7d0JBQ0EsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztxQkFDcEQ7b0JBQ0QsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN2QjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDckIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHlDQUFDLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2pEO3dCQUFTO29CQUNSLElBQUksQ0FBQyxzQkFBc0IsRUFBRTt3QkFDM0Isb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7cUJBQzFCO2lCQUNGO1lBQ0gsQ0FBQyxFQUNGLENBQUM7UUFDSixDQUFDLEVBQUM7UUFFRjs7V0FFRztRQUNLLHVCQUFrQixHQUFHLENBQzNCLFlBQW9DLEVBQ3BDLFNBQWUsRUFDZixzQkFBZ0MsRUFDaEMsRUFBRTtZQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRTtnQkFDM0MsWUFBWTthQUNiLENBQUMsQ0FBQztZQUVILElBQUk7Z0JBQ0YsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDO29CQUN6QixTQUFTO29CQUNULFlBQVk7b0JBQ1osc0JBQXNCO2lCQUN2QixDQUFDLENBQUM7YUFDSjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixzRUFBYSxDQUFDLFlBQVksRUFBRTtvQkFDMUIsU0FBUyxFQUFFLElBQUk7aUJBQ2hCLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPLElBQUkseUNBQUMsQ0FBQyx5QkFBeUIsQ0FBQztpQkFDNUQsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLEVBQUM7UUFFTSwwQkFBcUIsR0FBRyxDQUFPLFNBQWUsRUFBRSxFQUFFO1lBQ3hELGdDQUFnQztZQUNoQyxxSEFBcUg7WUFDckgsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7WUFFN0IsTUFBTSxZQUFZLEdBQUcsTUFBTSw0REFBZSxDQUFDLFNBQVMsRUFBRTtnQkFDcEQsZ0JBQWdCLEVBQUUsaUJBQWlCO2FBQ3BDLENBQUMsQ0FBQztZQUVILElBQUksY0FBYyxHQUFHLE1BQU0sdURBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUVwRCwyRUFBMkU7WUFDM0UsaUJBQWlCO1lBQ2pCLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyx1REFBYyxFQUFFO2dCQUNyQyxNQUFNLEdBQUcsR0FBRyxNQUFNLHFFQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUV2RCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztnQkFDckQsSUFBSSxLQUFLLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBRTlDLElBQUksS0FBSyxHQUFHLGlCQUFpQixFQUFFO29CQUM3QixLQUFLLEdBQUcsaUJBQWlCLENBQUM7b0JBQzFCLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDM0M7Z0JBRUQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Z0JBQ3ZCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBRSxDQUFDO2dCQUV6QyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFFNUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsdURBQWMsQ0FBWSxDQUFDO2FBQzlEO1lBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFO2dCQUNsQyxrREFBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxjQUFjLGFBQWEsQ0FBQyxDQUFDO2FBQzVEO1FBQ0gsQ0FBQyxFQUFDO1FBRU0sa0JBQWEsR0FBRyxDQUN0QixFQUFFLHNCQUFzQixFQUFFLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSxLQUFLLEVBQUUsRUFDOUQsRUFBRTtZQUNGLElBQUk7Z0JBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO2dCQUM3RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7Z0JBRTdELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsb0VBQTJCLENBQzFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUNwQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsTUFBTSxTQUFTLEdBQUcsTUFBTSwyREFBUSxDQUFDO29CQUMvQixXQUFXLEVBQUUsT0FBTztvQkFDcEIsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO2lCQUN6QyxDQUFDLENBQUM7Z0JBRUgsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUMzQyxNQUFNLEVBQUUsQ0FBQztvQkFDVCxNQUFNLEVBQUUsQ0FBQztpQkFDVixDQUFDLENBQUM7Z0JBRUgsSUFBSSxzQkFBc0IsRUFBRTtvQkFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDakQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUNYO3dCQUNFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFO3FCQUNoRCxFQUNELEdBQUcsRUFBRTt3QkFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxvREFBYyxDQUFDLENBQUM7b0JBQ25ELENBQUMsQ0FDRixDQUFDO2lCQUNIO3FCQUFNO29CQUNMLElBQUksQ0FBQyxRQUFRLENBQ1g7d0JBQ0UsbUJBQW1CLEVBQUUsWUFBWTtxQkFDbEMsRUFDRCxHQUFHLEVBQUU7d0JBQ0gsSUFBSSxDQUFDLGtCQUFrQixDQUNyQixZQUFZLEVBQ1osU0FBUzt3QkFDVCw0QkFBNEIsQ0FBQyxJQUFJLENBQ2xDLENBQUM7b0JBQ0osQ0FBQyxDQUNGLENBQUM7aUJBQ0g7YUFDRjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO29CQUMvQixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUN0QjtxQkFBTTtvQkFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNyQjtnQkFDRCxJQUFJLENBQUMsUUFBUSxDQUNYO29CQUNFLG1CQUFtQixFQUFFLElBQUk7b0JBQ3pCLGNBQWMsRUFBRSxJQUFJO29CQUNwQixXQUFXLEVBQUUsV0FBVztpQkFDekIsRUFDRCxHQUFHLEVBQUU7b0JBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO2dCQUNuRCxDQUFDLENBQ0YsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxFQUFDO1FBRU0sOEJBQXlCLEdBQUcsQ0FDbEMsWUFBb0MsRUFDcEMsZ0JBQWdCLEdBQUcsS0FBSyxFQUN4QixFQUFFOztZQUNGLE1BQU0sS0FBSyxHQUNULCtFQUF5QixDQUFDLFlBQVksQ0FBQztpQkFDdkMsVUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQywwQ0FBRSxLQUFLLEVBQUM7WUFFbEQsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLFlBQVksT0FBTyxFQUFFO2dCQUN0QyxJQUNFLFlBQVksQ0FBQyxLQUFLLEdBQUcsMkRBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSztvQkFDL0QsWUFBWSxDQUFDLE1BQU0sR0FBRywyREFBa0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQ2hFO29CQUNBLE1BQU0sZUFBZSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ3BELHNFQUFhLENBQUMsWUFBWSxFQUFFO3dCQUMxQixDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsR0FBRyxlQUFlLEdBQUcsQ0FBQzt3QkFDdkMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLEdBQUcsZUFBZSxHQUFHLENBQUM7d0JBQ3ZDLEtBQUssRUFBRSxlQUFlO3dCQUN0QixNQUFNLEVBQUUsZUFBZTtxQkFDeEIsQ0FBQyxDQUFDO2lCQUNKO2dCQUVELE9BQU87YUFDUjtZQUVELElBQ0UsZ0JBQWdCO2dCQUNoQiw4REFBOEQ7Z0JBQzlELDhEQUE4RDtnQkFDOUQsaUJBQWlCO2dCQUNqQixDQUFDLFlBQVksQ0FBQyxLQUFLLEdBQUcsMkRBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSztvQkFDOUQsWUFBWSxDQUFDLE1BQU0sR0FBRywyREFBa0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFDbkU7Z0JBQ0EsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3pELDJEQUEyRDtnQkFDM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FDeEIsU0FBUyxFQUNULElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUM1RCxDQUFDO2dCQUVGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBRWxFLDBFQUEwRTtnQkFDMUUsMEJBQTBCO2dCQUMxQixNQUFNLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQzlELE1BQU0sQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFFaEUsc0VBQWEsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2FBQ3REO1FBQ0gsQ0FBQyxDQUFDO1FBRUY7MEVBQ2tFO1FBQzFELHFCQUFnQixHQUFHLENBQ3pCLFFBQXNELEVBQ3RELEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUNsQixFQUFFO1lBQ0YsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLGlFQUFpQixDQUFDO2dCQUM3RCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQzNCLE9BQU8sRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUNsRCxLQUFLO2FBQ04sQ0FBQyxDQUFDO1lBQ0gsSUFBSSxZQUFZLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUU7Z0JBQzFDLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFO29CQUM5QixJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO3dCQUNwQyxtRkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDcEM7aUJBQ0Y7YUFDRjtZQUNELElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtnQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO29CQUN2RCxJQUNFLCtFQUF5QixDQUFDLE9BQU8sQ0FBQzt3QkFDbEMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQ2hDO3dCQUNBLE9BQU8sdUVBQWMsQ0FBQyxPQUFPLEVBQUU7NEJBQzdCLE1BQU0sRUFBRSxPQUFPO3lCQUNoQixDQUFDLENBQUM7cUJBQ0o7b0JBQ0QsT0FBTyxPQUFPLENBQUM7Z0JBQ2pCLENBQUMsQ0FBQyxDQUNILENBQUM7YUFDSDtZQUVELE9BQU8sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLENBQUM7UUFDeEMsQ0FBQyxFQUFDO1FBRUYsNkRBQTZEO1FBQ3JELDZCQUF3QixHQUFHLENBQ2pDLGdCQUFxRCw0RUFBMkIsQ0FDOUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FDekIsRUFDRCxRQUFxQixJQUFJLENBQUMsS0FBSyxFQUMvQixFQUFFO1lBQ0YsTUFBTSxxQkFBcUIsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUNoRCxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUN4RSxDQUFDO1lBRUYsSUFBSSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2hDLE1BQU0sRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDbEQscUJBQXFCLEVBQ3JCLEtBQUssQ0FDTixDQUFDO2dCQUNGLElBQUksWUFBWSxDQUFDLElBQUksRUFBRTtvQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztpQkFDN0I7YUFDRjtRQUNILENBQUMsRUFBQztRQUVGOzZEQUNxRDtRQUM3Qyx5QkFBb0IsR0FBRyx1REFBUSxDQUFDLEdBQUcsRUFBRTtZQUMzQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUNsQyxDQUFDLEVBQUUsNkRBQW9CLENBQUMsQ0FBQztRQUVqQixzQ0FBaUMsR0FBRyxDQUMxQyxLQUE0QyxFQUM1QyxFQUFFO1lBQ0YsTUFBTSxtQkFBbUIsR0FBRyxxRkFBa0MsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEtBQUssbUJBQW1CLEVBQUU7Z0JBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7YUFDMUQ7UUFDSCxDQUFDLENBQUM7UUFFTSxnQ0FBMkIsR0FBRyxDQUFDLGFBR3RDLEVBQVEsRUFBRTtZQUNULE1BQU0sc0JBQXNCLEdBQUcsOEVBQTJCLENBQ3hELGFBQWEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFDRixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLGlCQUFpQixFQUNmLHNCQUFzQixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2FBQ2pFLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVNLGlEQUE0QyxHQUFHLENBQ3JELGFBQWtEO1FBQ2xELG1CQUFtQjtRQUNuQixhQUdHO1FBQ0gsaUVBQWlFO1FBQ2pFLHVCQUF1QjtRQUN2QiwyQkFBOEQsRUFDeEQsRUFBRTtZQUNSLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFO2dCQUN6QixPQUFPO2FBQ1I7WUFFRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQzVDLENBQUMsR0FBNEMsRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDdkQsTUFBTSxzQkFBc0IsR0FBRyw4RUFBMkIsQ0FDeEQsTUFBTSxFQUNOLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztnQkFDRixJQUNFLHNCQUFzQixJQUFJLElBQUk7b0JBQzlCLENBQUMsdUZBQW9DLENBQ25DLGFBQWEsRUFDYiwyQkFBMkIsYUFBM0IsMkJBQTJCLHVCQUEzQiwyQkFBMkIsQ0FBRSxFQUFFLEVBQy9CLHNCQUFzQixDQUN2QixFQUNEO29CQUNBLEdBQUcsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztpQkFDbEM7Z0JBQ0QsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQ0QsRUFBRSxDQUNILENBQUM7WUFFRixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQztRQTRCTSxvQkFBZSxHQUFHLENBQUMsTUFBeUIsRUFBRSxFQUFFOztZQUN0RCxpQ0FBaUM7WUFDakMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO2dCQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztnQkFDckIsSUFBSSxDQUFDLEVBQUUsR0FBRyxnRUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFFcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQzFELE9BQU8sRUFBRSxLQUFLO2lCQUNmLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLDBEQUFpQixFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDakUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyx3REFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5RDtpQkFBTTtnQkFDTCxVQUFJLENBQUMsTUFBTSwwQ0FBRSxtQkFBbUIsQ0FBQyxvREFBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDaEUsVUFBSSxDQUFDLE1BQU0sMENBQUUsbUJBQW1CLENBQUMsMERBQWlCLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUNyRSxVQUFJLENBQUMsTUFBTSwwQ0FBRSxtQkFBbUIsQ0FBQyx3REFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNsRTtRQUNILENBQUMsQ0FBQztRQUVNLG9CQUFlLEdBQUcsQ0FBTyxLQUFzQyxFQUFFLEVBQUU7O1lBQ3pFLElBQUk7Z0JBQ0YsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRXpDLElBQUksaUVBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzlCLGdFQUFnRTtvQkFDaEUsd0VBQXdFO29CQUV4RSxJQUFJLEtBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxJQUFJLE1BQUssdURBQWMsSUFBSSxLQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxNQUFLLHVEQUFjLEVBQUU7d0JBQ2xFLElBQUk7NEJBQ0YsSUFBSSx3RUFBeUIsRUFBRTtnQ0FDN0IsSUFBSTtvQ0FDRix1Q0FBdUM7b0NBQ3ZDLCtDQUErQztvQ0FDL0MsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0NBQ3hDLElBQVksQ0FBQyxNQUFNLEdBQUcsTUFDckIsSUFDRCxDQUFDLHFCQUFxQixFQUFFLENBQUM7aUNBQzNCO2dDQUFDLE9BQU8sS0FBVSxFQUFFO29DQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lDQUN6Qzs2QkFDRjs0QkFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLG9EQUFZLENBQzlCLElBQUksRUFDSixJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FDekMsQ0FBQzs0QkFDRixJQUFJLENBQUMsZ0JBQWdCLGlDQUNoQixLQUFLLEtBQ1IsUUFBUSxrQ0FDSCxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUNqQyxTQUFTLEVBQUUsS0FBSyxLQUVsQixZQUFZLEVBQUUsSUFBSSxFQUNsQixlQUFlLEVBQUUsSUFBSSxJQUNyQixDQUFDOzRCQUNILE9BQU87eUJBQ1I7d0JBQUMsT0FBTyxLQUFVLEVBQUU7NEJBQ25CLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxlQUFlLEVBQUU7Z0NBQ2xDLE1BQU0sS0FBSyxDQUFDOzZCQUNiO3lCQUNGO3FCQUNGO29CQUVELG9FQUFvRTtvQkFDcEUsZ0NBQWdDO29CQUNoQyx3RUFBd0U7b0JBRXhFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxvRUFBMkIsQ0FDMUQsS0FBSyxFQUNMLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztvQkFFRixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDakUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDNUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBRW5FLE9BQU87aUJBQ1I7YUFDRjtZQUFDLE9BQU8sS0FBVSxFQUFFO2dCQUNuQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ25CLFNBQVMsRUFBRSxLQUFLO29CQUNoQixZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU87aUJBQzVCLENBQUMsQ0FBQzthQUNKO1lBRUQsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsaUVBQXdCLENBQUMsQ0FBQztZQUMzRSxJQUFJLGFBQWEsS0FBSyxFQUFFLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyw2QkFBNkIsQ0FBQztvQkFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO29CQUNuQyxRQUFRLEVBQUUsS0FBSztvQkFDZixLQUFLLEVBQUUsSUFBSTtpQkFDWixDQUFDLENBQUM7Z0JBQ0gsT0FBTzthQUNSO1lBRUQsTUFBTSxJQUFJLEdBQUcsV0FBSyxDQUFDLFlBQVksMENBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFDLElBQ0UsS0FBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLElBQUksTUFBSyxpRUFBd0I7aUJBQ3ZDLFVBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxJQUFJLDBDQUFFLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUN0QztnQkFDQSxJQUFJLENBQUMsT0FBTztxQkFDVCxhQUFhLENBQUMsSUFBSSxDQUFDO3FCQUNuQixJQUFJLENBQUMsR0FBRyxFQUFFO29CQUNULG1EQUFtRDtvQkFDbkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUN4QyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3pDLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FDakUsQ0FBQztnQkFDSixzRUFBc0U7YUFDdkU7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLHdFQUF5QixFQUFFO29CQUM3QixJQUFJO3dCQUNGLHVDQUF1Qzt3QkFDdkMsK0NBQStDO3dCQUMvQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDeEMsSUFBWSxDQUFDLE1BQU0sR0FBRyxNQUFPLElBQVksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO3FCQUNwRTtvQkFBQyxPQUFPLEtBQVUsRUFBRTt3QkFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDekM7aUJBQ0Y7Z0JBQ0QsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDbkM7UUFDSCxDQUFDLEVBQUM7UUFFRixxQkFBZ0IsR0FBRyxDQUFDLElBQVUsRUFBRSxFQUFFO1lBQ2hDLG9EQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO2lCQUNyRSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDZCxJQUFJLENBQUMsZ0JBQWdCLGlDQUNoQixLQUFLLEtBQ1IsUUFBUSxrQ0FDSCxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUNqQyxTQUFTLEVBQUUsS0FBSyxLQUVsQixZQUFZLEVBQUUsSUFBSSxFQUNsQixlQUFlLEVBQUUsSUFBSSxJQUNyQixDQUFDO1lBQ0wsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNuRSxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQztRQUVNLDRCQUF1QixHQUFHLENBQ2hDLEtBQTRDLEVBQzVDLEVBQUU7WUFDRixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFdkIsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxvRUFBMkIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFFMUUsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUU1QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUSxDQUFDO1lBQ3ZELE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FDeEMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUM7WUFDeEMsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7WUFFdEMsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUU7b0JBQ2pFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDN0MsQ0FBQyxDQUFDLENBQUM7YUFDSjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDNUM7UUFDSCxDQUFDLENBQUM7UUFFTSwrQkFBMEIsR0FBRyxDQUNuQyxnQkFBa0MsRUFDbEMsS0FBaUMsRUFDM0IsRUFBRTs7WUFDUixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUNuRCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7WUFDbEQsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDcEIsT0FBTzthQUNSO1lBQ0QsSUFBSSxlQUFlLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRTtnQkFDeEMseURBQWMsQ0FDWixlQUFlLEVBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQ3RCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3pCLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsYUFBYSxDQUFDLENBQUMsRUFDZixpREFBUSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUNwRCxpREFBUSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUNwRCxpRUFBeUIsQ0FBQyxLQUFLLENBQUMsRUFDaEMsOERBQXNCLENBQUMsS0FBSyxDQUFDLENBQzlCLENBQUM7YUFDSDtpQkFBTTtnQkFDTCxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQ2pDLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsYUFBYSxDQUFDLENBQUMsRUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztnQkFFRixNQUFNLEtBQUssR0FDVCwrRUFBeUIsQ0FBQyxlQUFlLENBQUM7cUJBQzFDLFVBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsMENBQUUsS0FBSyxFQUFDO2dCQUNyRCxNQUFNLFdBQVcsR0FDZixLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxPQUFPLENBQUM7b0JBQ2xDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNO29CQUM1QixDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUVYLHlEQUFjLENBQ1osZUFBZSxFQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUN0QixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUMvQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUMvQixLQUFLLEVBQ0wsS0FBSyxFQUNMLGlEQUFRLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFDaEQsaURBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUNoRCxvRUFBYyxDQUFDLGVBQWUsQ0FBQztvQkFDN0IsQ0FBQyxDQUFDLENBQUMsaUVBQXlCLENBQUMsS0FBSyxDQUFDO29CQUNuQyxDQUFDLENBQUMsaUVBQXlCLENBQUMsS0FBSyxDQUFDLEVBQ3BDLDhEQUFzQixDQUFDLEtBQUssQ0FBQyxFQUM3QixXQUFXLENBQ1osQ0FBQztnQkFFRixJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO2FBQ25EO1FBQ0gsQ0FBQyxDQUFDO1FBRU0sc0JBQWlCLEdBQUcsQ0FDMUIsZ0JBQWtDLEVBQ2xDLEtBQWlDLEVBQ3hCLEVBQUU7WUFDWCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7WUFDRixNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDL0QsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWiw4REFBOEQ7Z0JBQzlELDhEQUE4RDtnQkFDOUQsV0FBVztnQkFDWCxVQUFVLEVBQUUsbUJBQW1CLElBQUksbUJBQW1CLEtBQUssVUFBVTtnQkFDckUsVUFBVSxFQUFFLG1CQUFtQixLQUFLLFVBQVU7YUFDL0MsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDO1lBQ2xELE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsb0RBQVksQ0FDckMsYUFBYSxDQUFDLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDbEQsYUFBYSxDQUFDLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDbEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQ3BCLENBQUM7WUFDRixJQUNFLDREQUFpQixDQUNmLGdCQUFnQixFQUNoQixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQ3RDLHFFQUE2QixDQUFDLEtBQUssQ0FBQyxFQUNwQyw4REFBc0IsQ0FBQyxLQUFLLENBQUMsRUFDN0IsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxvRUFBYyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxDQUFDLENBQUMsQ0FBQyxpRUFBeUIsQ0FBQyxLQUFLLENBQUM7Z0JBQ25DLENBQUMsQ0FBQyxpRUFBeUIsQ0FBQyxLQUFLLENBQUMsRUFDcEMsT0FBTyxFQUNQLE9BQU8sRUFDUCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDaEMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQ2pDLEVBQ0Q7Z0JBQ0EsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ2pELE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FBQztRQUVGLGdEQUFnRDtRQUN4QyxxQkFBZ0IsR0FBRyxDQUN6QixFQUNFLElBQUksRUFDSixHQUFHLEdBSUosRUFDRCxJQUEwQixFQUMxQixFQUFFO1lBQ0YsTUFBTSxnQkFBZ0IsR0FBRyxzRUFBaUMsQ0FDeEQsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxrQkFBa0IsR0FBRyx3RUFBbUMsQ0FDNUQsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxtQkFBbUIsR0FBRywrRUFBMEMsQ0FDcEUsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxpQkFBaUIsR0FBRyw2RUFBd0MsQ0FDaEUsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsRUFBRSxFQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO1lBRUYsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDO1lBRTlCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFFMUMsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztZQUN4QyxJQUFJLHNFQUE2QixJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUN4RCxPQUFPLENBQUMsSUFBSSxDQUFDLHFEQUFlLENBQUMsQ0FBQzthQUMvQjtZQUVELElBQUksMkVBQWtDLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzdELE9BQU8sQ0FBQyxJQUFJLENBQUMscURBQWUsQ0FBQyxDQUFDO2FBQy9CO1lBQ0QsSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUNyQixNQUFNLGVBQWUsR0FBRztvQkFDdEIsR0FBRyxPQUFPO29CQUNWLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssV0FBVzt3QkFDL0MsMERBQW9CO29CQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxLQUFLLFdBQVcsSUFBSSx5REFBbUI7b0JBQ3ZFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssV0FBVzt3QkFDL0MsZ0ZBQW9CO29CQUN0Qix1REFBaUI7aUJBQ2xCLENBQUM7Z0JBRUYsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtvQkFDOUIsMERBQWdCLENBQUM7d0JBQ2YsT0FBTyxFQUFFLGVBQWU7d0JBQ3hCLEdBQUc7d0JBQ0gsSUFBSTt3QkFDSixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7d0JBQ2pDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSzt3QkFDcEIsU0FBUyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFRO3FCQUNoRCxDQUFDLENBQUM7aUJBQ0o7cUJBQU07b0JBQ0wsMERBQWdCLENBQUM7d0JBQ2YsT0FBTyxFQUFFOzRCQUNQLElBQUksQ0FBQyxRQUFRO2dDQUNYLFNBQVMsQ0FBQyxTQUFTLElBQUk7Z0NBQ3JCLElBQUksRUFBRSxPQUFPO2dDQUNiLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsRUFBRTtvQ0FDL0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO29DQUM5QixPQUFPO3dDQUNMLGVBQWUsRUFBRSxLQUFLO3FDQUN2QixDQUFDO2dDQUNKLENBQUM7Z0NBQ0QsZ0JBQWdCLEVBQUUsY0FBYzs2QkFDakM7NEJBQ0gsSUFBSSxDQUFDLFFBQVEsSUFBSSxTQUFTLENBQUMsU0FBUyxJQUFJLFNBQVM7NEJBQ2pELHNFQUE2QjtnQ0FDM0IsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDO2dDQUNuQixxREFBZTs0QkFDakIsMkVBQWtDO2dDQUNoQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7Z0NBQ25CLHFEQUFlOzRCQUNqQixDQUFDLENBQUMsc0VBQTZCLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0NBQ3JELENBQUMsMkVBQWtDLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztnQ0FDNUQsU0FBUzs0QkFDWCxxREFBZTs0QkFDZixTQUFTOzRCQUNULE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssV0FBVztnQ0FDL0MsMERBQW9COzRCQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxLQUFLLFdBQVc7Z0NBQzlDLHlEQUFtQjs0QkFDckIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxXQUFXO2dDQUMvQyxnRkFBb0I7NEJBQ3RCLHVEQUFpQjt5QkFDbEI7d0JBQ0QsR0FBRzt3QkFDSCxJQUFJO3dCQUNKLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTt3QkFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLO3dCQUNwQixTQUFTLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQVE7cUJBQ2hELENBQUMsQ0FBQztpQkFDSjthQUNGO2lCQUFNLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtnQkFDN0IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtvQkFDOUIsMERBQWdCLENBQUM7d0JBQ2YsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsSUFBSSxnREFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDO3dCQUN4RCxHQUFHO3dCQUNILElBQUk7d0JBQ0osYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO3dCQUNqQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUs7d0JBQ3BCLFNBQVMsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUTtxQkFDaEQsQ0FBQyxDQUFDO2lCQUNKO3FCQUFNO29CQUNMLDBEQUFnQixDQUFDO3dCQUNmLE9BQU8sRUFBRTs0QkFDUCxJQUFJLENBQUMsUUFBUSxJQUFJLCtDQUFTOzRCQUMxQixJQUFJLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxTQUFTLElBQUksZ0RBQVU7NEJBQ2xELElBQUksQ0FBQyxRQUFRO2dDQUNYLFNBQVMsQ0FBQyxTQUFTLElBQUk7Z0NBQ3JCLElBQUksRUFBRSxPQUFPO2dDQUNiLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsRUFBRTtvQ0FDL0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO29DQUM5QixPQUFPO3dDQUNMLGVBQWUsRUFBRSxLQUFLO3FDQUN2QixDQUFDO2dDQUNKLENBQUM7Z0NBQ0QsZ0JBQWdCLEVBQUUsY0FBYzs2QkFDakM7NEJBQ0gsSUFBSSxDQUFDLFFBQVEsSUFBSSxTQUFTOzRCQUMxQixHQUFHLE9BQU87NEJBQ1YsU0FBUzs0QkFDVCxzREFBZ0I7NEJBQ2hCLHVEQUFpQjs0QkFDakIsU0FBUzs0QkFDVCxnQkFBZ0IsSUFBSSxpREFBVzs0QkFDL0Isa0JBQWtCLElBQUksbURBQWE7NEJBQ25DLENBQUMsZ0JBQWdCLElBQUksa0JBQWtCLENBQUMsSUFBSSxTQUFTOzRCQUNyRCx3REFBa0I7NEJBQ2xCLFNBQVM7NEJBQ1Qsd0RBQWtCOzRCQUNsQix3REFBa0I7NEJBQ2xCLHNEQUFnQjs0QkFDaEIsd0RBQWtCOzRCQUNsQixTQUFTOzRCQUNULG1CQUFtQixJQUFJLDBEQUFvQjs0QkFDM0MsaUJBQWlCLElBQUksd0RBQWtCOzRCQUN2QyxDQUFDLG1CQUFtQixJQUFJLGlCQUFpQixDQUFDLElBQUksU0FBUzs0QkFDdkQsOERBQXdCOzRCQUN4QiwwREFBb0I7eUJBQ3JCO3dCQUNELEdBQUc7d0JBQ0gsSUFBSTt3QkFDSixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7d0JBQ2pDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSzt3QkFDcEIsU0FBUyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFRO3FCQUNoRCxDQUFDLENBQUM7aUJBQ0o7YUFDRjtRQUNILENBQUMsQ0FBQztRQUVNLGdCQUFXLEdBQUcsMkRBQWtCLENBQUMsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDN0QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRXZCLElBQUksU0FBUyxFQUFFO2dCQUNiLE9BQU87YUFDUjtZQUVELE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDO1lBQ2pDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSwwQkFBMEIsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDdEUsK0RBQStEO1lBQy9ELElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFO2dCQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMvQixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7Z0JBQ3BCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzdCLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRTtvQkFDcEIsS0FBSyxHQUFHLFFBQVEsQ0FBQztpQkFDbEI7Z0JBQ0QsS0FBSyxJQUFJLElBQUksQ0FBQztnQkFDZCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUN4RCxVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNkLElBQUksQ0FBQyxRQUFRLENBQUM7NEJBQ1osa0JBQWtCLEVBQUUsMEJBQTBCOzRCQUM5QywwQkFBMEIsRUFBRSxFQUFFO3lCQUMvQixDQUFDLENBQUM7b0JBQ0wsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUNWO2dCQUVELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO2dCQUNsRCx3RUFBd0U7Z0JBQ3hFLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xFLHdCQUF3QjtnQkFDeEIsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLGtEQUFTLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrREFBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUVwRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUNsRCxJQUFJLEVBQUUsd0RBQVUsQ0FDZCwwREFBaUIsQ0FBQyxPQUFPLENBQUMsRUFDMUIsSUFBSSxFQUNKLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEVBQ3BDO3dCQUNFLENBQUMsRUFBRSxPQUFPO3dCQUNWLENBQUMsRUFBRSxPQUFPO3FCQUNYLENBQ0Y7b0JBQ0Qsa0JBQWtCLEVBQUUsRUFBRTtvQkFDdEIsMEJBQTBCLEVBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQzt3QkFDMUMsQ0FBQyxDQUFDLGtCQUFrQjt3QkFDcEIsQ0FBQyxDQUFDLDBCQUEwQjtvQkFDaEMscUJBQXFCLEVBQUUsSUFBSTtpQkFDNUIsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osSUFBSSxDQUFDLG1DQUFtQyxFQUFFLENBQUM7Z0JBQzNDLE9BQU87YUFDUjtZQUVELHlDQUF5QztZQUN6QyxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDcEMsZ0RBQWdEO29CQUNoRCxPQUFPLEVBQUUsT0FBTyxHQUFHLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLO2lCQUNuRCxDQUFDLENBQUMsQ0FBQztnQkFDSixPQUFPO2FBQ1I7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM3QyxPQUFPLEVBQUUsT0FBTyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSztnQkFDdEMsT0FBTyxFQUFFLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUs7YUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQXFDSyxnQkFBVyxHQUFHLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxNQUFxQixFQUFFLEVBQUU7O1lBQ3BFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7Z0JBQ1osT0FBTzthQUNSO1lBQ0QsTUFBTSxPQUFPLEdBQUcsb0VBQTJCLENBQ3pDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQzFCLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUVGLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN4Qyx3Q0FBd0M7YUFDekM7WUFFRCxnQkFBSSxDQUFDLEtBQUssRUFBQyxlQUFlLG1EQUFHO2dCQUMzQixPQUFPO2dCQUNQLE1BQU07Z0JBQ04sV0FBVyxFQUFFLE9BQU8sQ0FBQyxRQUFRO2FBQzlCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVNLHdDQUFtQyxHQUFHLGlEQUFRLENBQUMsR0FBRyxFQUFFO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUscUJBQXFCLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzthQUNqRDtRQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVBLGtCQUFhLEdBQUcsQ0FBQyxFQUFlLEVBQUUsRUFBRTs7WUFDMUMsSUFBSSxVQUFJLENBQUMsc0JBQXNCLDBDQUFFLE9BQU8sRUFBRTtnQkFDeEMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDO2dCQUNoRSxNQUFNLEVBQ0osS0FBSyxFQUNMLE1BQU0sRUFDTixJQUFJLEVBQUUsVUFBVSxFQUNoQixHQUFHLEVBQUUsU0FBUyxHQUNmLEdBQUcsbUJBQW1CLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQkFDaEQsTUFBTSxFQUNKLEtBQUssRUFBRSxZQUFZLEVBQ25CLE1BQU0sRUFBRSxhQUFhLEVBQ3JCLFNBQVMsRUFBRSxnQkFBZ0IsRUFDM0IsVUFBVSxFQUFFLGlCQUFpQixHQUM5QixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBRWYsSUFDRSxLQUFLLEtBQUssWUFBWTtvQkFDdEIsTUFBTSxLQUFLLGFBQWE7b0JBQ3hCLFVBQVUsS0FBSyxpQkFBaUI7b0JBQ2hDLFNBQVMsS0FBSyxnQkFBZ0IsRUFDOUI7b0JBQ0EsSUFBSSxFQUFFLEVBQUU7d0JBQ04sRUFBRSxFQUFFLENBQUM7cUJBQ047b0JBQ0QsT0FBTztpQkFDUjtnQkFFRCxJQUFJLENBQUMsUUFBUSxDQUNYO29CQUNFLEtBQUs7b0JBQ0wsTUFBTTtvQkFDTixVQUFVO29CQUNWLFNBQVM7aUJBQ1YsRUFDRCxHQUFHLEVBQUU7b0JBQ0gsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNiLENBQUMsQ0FDRixDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUM7UUFFSyxZQUFPLEdBQUcsR0FBRyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxRQUFRLG1CQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFHLENBQUM7UUFDaEQsQ0FBQyxDQUFDO1FBM3pKQSxNQUFNLGVBQWUsR0FBRyw2REFBa0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sRUFDSixhQUFhLEVBQ2IsZUFBZSxHQUFHLEtBQUssRUFDdkIsY0FBYyxHQUFHLEtBQUssRUFDdEIsZUFBZSxHQUFHLEtBQUssRUFDdkIsS0FBSyxHQUFHLGVBQWUsQ0FBQyxLQUFLLEVBQzdCLElBQUksR0FBRyxlQUFlLENBQUMsSUFBSSxHQUM1QixHQUFHLEtBQUssQ0FBQztRQUNWLElBQUksQ0FBQyxLQUFLLCtEQUNMLGVBQWUsS0FDbEIsS0FBSyxFQUNMLFNBQVMsRUFBRSxJQUFJLEtBQ1osSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQzFCLGVBQWU7WUFDZixjQUFjLEVBQ2QsUUFBUSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsa0RBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUM1QyxJQUFJLEVBQ0osS0FBSyxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQ3hCLE1BQU0sRUFBRSxNQUFNLENBQUMsV0FBVyxHQUMzQixDQUFDO1FBRUYsSUFBSSxDQUFDLEVBQUUsR0FBRywrQ0FBTSxFQUFFLENBQUM7UUFFbkIsSUFBSSxhQUFhLEVBQUU7WUFDakIsTUFBTSxZQUFZLEdBQ2hCLENBQUMsU0FBUyxJQUFJLGFBQWEsS0FBSSxtQkFBYSxDQUFDLE9BQU8sMENBQUUsWUFBWSxFQUFDO2dCQUNuRSwwREFBaUIsRUFBMkIsQ0FBQztZQUUvQyxNQUFNLEdBQUcsR0FBNEI7Z0JBQ25DLEtBQUssRUFBRSxJQUFJO2dCQUNYLFlBQVk7Z0JBQ1osV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM3QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDM0IsZ0NBQWdDLEVBQUUsSUFBSSxDQUFDLGdDQUFnQztnQkFDdkUsT0FBTyxFQUFFO29CQUNQLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWTtpQkFDekI7Z0JBQ0QsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO2dCQUNyQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2dCQUN2QyxXQUFXLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUs7Z0JBQzdCLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSztnQkFDMUIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO2dCQUNyQixhQUFhLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtnQkFDeEMsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO2dCQUNyQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7YUFDSCxDQUFDO1lBQ1gsSUFBSSxPQUFPLGFBQWEsS0FBSyxVQUFVLEVBQUU7Z0JBQ3ZDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNwQjtpQkFBTTtnQkFDTCxhQUFhLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQzthQUM3QjtZQUNELFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDM0I7UUFFRCxJQUFJLENBQUMsd0JBQXdCLEdBQUc7WUFDOUIsU0FBUyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPO1lBQzlDLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtTQUNaLENBQUM7UUFFRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUkscURBQUssRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxzREFBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxpREFBTyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDJEQUFhLENBQ3BDLElBQUksQ0FBQyxnQkFBZ0IsRUFDckIsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFDaEIsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxFQUM5QyxJQUFJLENBQ0wsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLHNEQUFPLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyx3RUFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyx3RUFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRU8sWUFBWTtRQUNsQixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7UUFDNUMsTUFBTSxFQUNKLEtBQUssRUFBRSxjQUFjLEVBQ3JCLE1BQU0sRUFBRSxlQUFlLEVBQ3ZCLGVBQWUsR0FDaEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ2YsTUFBTSxXQUFXLEdBQUcsY0FBYyxHQUFHLFdBQVcsQ0FBQztRQUNqRCxNQUFNLFlBQVksR0FBRyxlQUFlLEdBQUcsV0FBVyxDQUFDO1FBQ25ELElBQUksZUFBZSxFQUFFO1lBQ25CLE9BQU8sQ0FDTCxpRkFDRSxTQUFTLEVBQUMsb0JBQW9CLEVBQzlCLEtBQUssRUFBRTtvQkFDTCxLQUFLLEVBQUUsY0FBYztvQkFDckIsTUFBTSxFQUFFLGVBQWU7b0JBQ3ZCLE1BQU0sRUFBRSx5REFBZ0I7aUJBQ3pCLEVBQ0QsS0FBSyxFQUFFLFdBQVcsRUFDbEIsTUFBTSxFQUFFLFlBQVksRUFDcEIsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQ3pCLGFBQWEsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQzNDLGFBQWEsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQzNDLFdBQVcsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUMvQixlQUFlLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQ2pDLGFBQWEsRUFBRSxJQUFJLENBQUMsdUJBQXVCLGdCQUUxQyx5Q0FBQyxDQUFDLHNCQUFzQixDQUFDLFlBQ25CLENBQ1YsQ0FBQztTQUNIO1FBQ0QsT0FBTyxDQUNMLGlGQUNFLFNBQVMsRUFBQyxvQkFBb0IsRUFDOUIsS0FBSyxFQUFFO2dCQUNMLEtBQUssRUFBRSxjQUFjO2dCQUNyQixNQUFNLEVBQUUsZUFBZTthQUN4QixFQUNELEtBQUssRUFBRSxXQUFXLEVBQ2xCLE1BQU0sRUFBRSxZQUFZLEVBQ3BCLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxhQUFhLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUMzQyxXQUFXLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFDL0IsZUFBZSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQ25DLFdBQVcsRUFBRSxJQUFJLENBQUMsZUFBZSxnQkFFaEMseUNBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxZQUNuQixDQUNWLENBQUM7SUFDSixDQUFDO0lBRU0sTUFBTTs7UUFDWCxNQUFNLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFdkQsTUFBTSxFQUNKLG1CQUFtQixFQUNuQixnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLGlCQUFpQixHQUNsQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFZixPQUFPLENBQ0wsOEVBQ0UsU0FBUyxFQUFFLGdEQUFJLENBQUMsaUNBQWlDLEVBQUU7Z0JBQ2pELHVCQUF1QixFQUFFLGVBQWU7Z0JBQ3hDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxRQUFRO2FBQ3BDLENBQUMsRUFDRixHQUFHLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixFQUNoQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFDNUIsUUFBUSxFQUFFLENBQUMsRUFDWCxTQUFTLEVBQ1AsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxnQkFHaEUsdURBQUMsMEJBQTBCLENBQUMsUUFBUSxrQkFDbEMsS0FBSyxFQUFFLElBQUksQ0FBQyx3QkFBd0IsZ0JBRXBDLHdEQUFDLGVBQWUsQ0FBQyxRQUFRLGtCQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxpQkFDNUMsdURBQUMsaURBQU8sSUFDTixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFDbkIsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQ3BCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUNqQixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFDN0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQ2pDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUNsQyxtQkFBbUIsRUFBRSxtQkFBbUIsRUFDeEMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQzdCLGdCQUFnQixFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDN0IsSUFBSSxDQUFDLDZCQUE2QixDQUFDO2dDQUNqQyxRQUFRO2dDQUNSLFFBQVEsRUFBRSxRQUFRO2dDQUNsQixLQUFLLEVBQUUsSUFBSTs2QkFDWixDQUFDLEVBRUosY0FBYyxFQUFFLGNBQWMsRUFDOUIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQ2pDLFFBQVEsRUFBRSxtREFBVyxFQUFFLENBQUMsSUFBSSxFQUM1QixlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksS0FBSyxFQUNwRCxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFDbEMsa0JBQWtCLEVBQUUsWUFBWSxFQUNoQyxlQUFlLEVBQUUsZUFBZSxFQUNoQyxrQkFBa0IsRUFDaEIsT0FBTyxXQUFJLENBQUMsS0FBSywwQ0FBRSxjQUFjLE1BQUssV0FBVztnQ0FDakQsY0FBYyxFQUVoQixZQUFZLEVBQ1YsT0FBTyxXQUFJLENBQUMsS0FBSywwQ0FBRSxLQUFLLE1BQUssV0FBVztnQ0FDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUssRUFFMUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDN0MsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMvQixjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFDbkMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQ3JCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUNYLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxXQUNqQyxFQUNGLGdFQUFLLFNBQVMsRUFBQyxnQ0FBZ0MsV0FBRyxFQUNsRCxnRUFBSyxTQUFTLEVBQUMsaUNBQWlDLFdBQUcsRUFDbEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FDdkIsdURBQUMsMENBQUssSUFDSixRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFDcEIsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUNsQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFDekIsaUJBQWlCLEVBQUUsaUJBQWlCLFdBQ3BDLENBQ0gsRUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksS0FBSyxJQUFJLElBQUksQ0FDbkMsdURBQUMsMENBQUssSUFDSixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQ2hDLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxXQUMzQixDQUNILEVBQ0QsMkVBQU8sSUFBSSxDQUFDLFlBQVksRUFBRSxXQUFRLGFBQ1QsWUFDUyxZQUNsQyxDQUNQLENBQUM7SUFDSixDQUFDO0lBbVNZLGlCQUFpQjs7O1lBQzVCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTO2dCQUNyQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDO1lBRXRDLElBQ0UsYUFBb0IsS0FBSyxpREFBUTtnQkFDakMsYUFBb0IsS0FBSyx3REFBZSxFQUN4QztnQkFDQSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDMUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7b0JBQ2hDLEtBQUssRUFBRTt3QkFDTCxZQUFZLEVBQUUsSUFBSTt3QkFDbEIsR0FBRyxFQUFFLEdBQUcsRUFBRTs0QkFDUixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7d0JBQ3BCLENBQUM7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFO3dCQUNSLFlBQVksRUFBRSxJQUFJO3dCQUNsQixLQUFLLEVBQUUsQ0FBQyxHQUFHLElBQWlDLEVBQUUsRUFBRTs0QkFDOUMsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7d0JBQ2hDLENBQUM7cUJBQ0Y7b0JBQ0QsR0FBRyxFQUFFO3dCQUNILFlBQVksRUFBRSxJQUFJO3dCQUNsQixLQUFLLEVBQUUsSUFBSTtxQkFDWjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTztxQkFDcEI7aUJBQ0YsQ0FBQyxDQUFDO2FBQ0o7WUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFFekIsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxFQUFFO2dCQUN2QyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdkI7WUFFRCxJQUFJLGdCQUFnQixJQUFJLE1BQU0sS0FBSSxVQUFJLENBQUMsc0JBQXNCLDBDQUFFLE9BQU8sR0FBRTtnQkFDdEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxHQUFHLEVBQUU7b0JBQzVDLHlCQUF5QjtvQkFDekIsd0VBQXdFO29CQUN4RSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUNyQixJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUSxDQUFDLHFCQUFxQixFQUFFLENBQUM7b0JBQy9ELElBQUksQ0FBQyxRQUFRO3dCQUNYLEtBQUssR0FBRyw4REFBcUI7NEJBQzdCLENBQUMsTUFBTSxHQUFHLGdFQUF1QixJQUFJLEtBQUssR0FBRywrREFBc0IsQ0FBQyxDQUFDO29CQUN2RSxrQkFBa0I7b0JBQ2xCLHdFQUF3RTtvQkFDeEUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixDQUFDLENBQUMsQ0FBQztnQkFDSCxVQUFJLENBQUMsY0FBYywwQ0FBRSxPQUFPLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ25FO2lCQUFNLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRTtnQkFDNUIsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FDbEMsZUFBZSw4REFBcUIscUJBQXFCLGdFQUF1Qix1QkFBdUIsK0RBQXNCLEtBQUssQ0FDbkksQ0FBQztnQkFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMzRCxVQUFVLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN6RTtZQUVELE1BQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTFFLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO2dCQUN4Qyw4REFBOEQ7Z0JBQzlELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2FBQzdCO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2FBQzFDOztLQUNGO0lBRU0sb0JBQW9COztRQUN6QixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLFVBQUksQ0FBQyxjQUFjLDBDQUFFLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckIsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzNCLFlBQVksR0FBRyxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQVNPLG9CQUFvQjs7UUFDMUIsUUFBUSxDQUFDLG1CQUFtQixDQUFDLHlEQUFnQixFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRSxRQUFRLENBQUMsbUJBQW1CLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEQsUUFBUSxDQUFDLG1CQUFtQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbkUsUUFBUSxDQUFDLG1CQUFtQixDQUFDLGtEQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BELFVBQUksQ0FBQywwQkFBMEIsMENBQUUsbUJBQW1CLENBQ2xELHFEQUFZLEVBQ1osSUFBSSxDQUFDLFFBQVEsQ0FDZCxDQUFDO1FBQ0YsUUFBUSxDQUFDLG1CQUFtQixDQUFDLHNEQUFhLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuRSxRQUFRLENBQUMsbUJBQW1CLENBQzFCLHlEQUFnQixFQUNoQixJQUFJLENBQUMsMkJBQTJCLEVBQ2hDLEtBQUssQ0FDTixDQUFDO1FBQ0YsUUFBUSxDQUFDLG1CQUFtQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxxREFBWSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLG1CQUFtQixDQUFDLHFEQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsbUJBQW1CLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyx3REFBZSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEUsTUFBTSxDQUFDLG1CQUFtQixDQUFDLG1EQUFVLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVqRSxRQUFRLENBQUMsbUJBQW1CLENBQzFCLDREQUFtQixFQUNuQixJQUFJLENBQUMsY0FBcUIsRUFDMUIsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsbUJBQW1CLENBQzFCLDZEQUFvQixFQUNwQixJQUFJLENBQUMsZUFBc0IsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFDRixRQUFRLENBQUMsbUJBQW1CLENBQzFCLDBEQUFpQixFQUNqQixJQUFJLENBQUMsWUFBbUIsRUFDeEIsS0FBSyxDQUNOLENBQUM7UUFFRixVQUFJLENBQUMsdUJBQXVCLCtDQUE1QixJQUFJLENBQTRCLENBQUM7SUFDbkMsQ0FBQztJQUVPLGlCQUFpQjs7UUFDdkIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsUUFBUSxDQUFDLGdCQUFnQixDQUFDLHlEQUFnQixFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFFBQVE7UUFDekUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLG1EQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsRUFBRTtZQUNyQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsc0RBQWEsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ2pFO1FBQ0QsUUFBUSxDQUFDLGdCQUFnQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FDdkIseURBQWdCLEVBQ2hCLElBQUksQ0FBQywyQkFBMkIsQ0FDakMsQ0FBQztRQUNGLDJEQUEyRDtRQUMzRCxvQkFBUSxDQUFDLEtBQUssMENBQUUsZ0JBQWdCLG1EQUFHLGFBQWEsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDckUsaUNBQWlDO1FBQ2pDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FDdkIsNERBQW1CLEVBQ25CLElBQUksQ0FBQyxjQUFxQixFQUMxQixLQUFLLENBQ04sQ0FBQztRQUNGLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FDdkIsNkRBQW9CLEVBQ3BCLElBQUksQ0FBQyxlQUFzQixFQUMzQixLQUFLLENBQ04sQ0FBQztRQUNGLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FDdkIsMERBQWlCLEVBQ2pCLElBQUksQ0FBQyxZQUFtQixFQUN4QixLQUFLLENBQ04sQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7WUFDOUIsT0FBTztTQUNSO1FBRUQsUUFBUSxDQUFDLGdCQUFnQixDQUFDLG9EQUFXLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDaEUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGtEQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUU7WUFDM0IsSUFBSSxDQUFDLDBCQUEwQixHQUFHLHNFQUE2QixDQUM3RCxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBUSxDQUNyQyxDQUFDO1lBQ0YsSUFBSSxDQUFDLDBCQUEwQixDQUFDLGdCQUFnQixDQUM5QyxxREFBWSxFQUNaLElBQUksQ0FBQyxRQUFRLENBQ2QsQ0FBQztTQUNIO1FBQ0QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHFEQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RCxNQUFNLENBQUMsZ0JBQWdCLENBQUMscURBQVksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxtREFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLHdEQUFlLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuRSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsbURBQVUsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxTQUFtQixFQUFFLFNBQW1COztRQUN6RCxJQUFJLFNBQVMsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDOUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxTQUFTLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztTQUNsRTtRQUVELElBQUksU0FBUyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRTtZQUM1RCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtRQUVELElBQUksU0FBUyxDQUFDLGNBQWMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRTtZQUMxRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7U0FDaEU7UUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUU7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDNUM7UUFFRCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUU7WUFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLGtEQUFTLENBQUMsQ0FBQyxDQUFDLElBQUk7YUFDeEQsQ0FBQyxDQUFDO1NBQ0o7UUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO2FBQ3RCLENBQUMsQ0FBQztTQUNKO1FBRUQsVUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sMENBQUUsU0FBUyxDQUFDLE1BQU0sQ0FDbkQsYUFBYSxFQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FDNUIsQ0FBQztRQUVGLElBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7WUFDL0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQ3pFO1lBQ0Esd0VBQXdFO1lBQ3hFLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQ25DLElBQ0UsU0FBUyxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVc7WUFDaEQsWUFBWSxJQUFJLElBQUk7WUFDcEIsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM1QixzRUFBZ0IsQ0FBQyxZQUFZLENBQUMsRUFDOUI7WUFDQSx5RUFBc0IsQ0FDcEIsWUFBWSxFQUNaLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLEtBQUssRUFDVixxREFBWSxDQUNWLCtHQUFvRCxDQUNsRCxZQUFZLEVBQ1osQ0FBQyxDQUFDLENBQ0gsQ0FDRixDQUNGLENBQUM7U0FDSDtRQUVELE1BQU0sWUFBWSxHQUVkLEVBQUUsQ0FBQztRQUNQLE1BQU0scUJBQXFCLEdBQ3pCLEVBQUUsQ0FBQztRQUNMLE1BQU0sd0JBQXdCLEdBQzVCLEVBQUUsQ0FBQztRQUNMLE1BQU0sZ0JBQWdCLEdBQTZCLEVBQUUsQ0FBQztRQUN0RCxNQUFNLGlCQUFpQixHQUE2QixFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2xELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUMzQixLQUFLLE1BQU0sRUFBRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUU7b0JBQ3JELElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSx3QkFBd0IsQ0FBQyxFQUFFO3dCQUNyQyx3QkFBd0IsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7cUJBQ25DO29CQUNELHdCQUF3QixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztpQkFDN0M7YUFDRjtZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUNqQixPQUFPO2FBQ1I7WUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2pCLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7YUFDNUM7WUFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2xCLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7YUFDOUM7WUFDRCxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxvRUFBMkIsQ0FDM0Q7Z0JBQ0UsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdEIsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN2QixFQUNELElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztZQUNGLFlBQVksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3BFLElBQUksb0VBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDM0I7Z0JBQ0UsbURBQW1EO2dCQUNuRCxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtvQkFDOUIsT0FBTyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLEVBQUUsRUFDaEQ7b0JBQ0EsT0FBTyxLQUFLLENBQUM7aUJBQ2Q7YUFDRjtZQUNELGdFQUFnRTtZQUNoRSwyQkFBMkI7WUFDM0IsT0FBTyxDQUNMLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjO2dCQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEtBQUssTUFBTTtnQkFDekMsT0FBTyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQzVDLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxVQUFVLEVBQUUsR0FBRyx1REFBVyxDQUMxRCxpQkFBaUIsRUFDakIsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUMzQixNQUFNLENBQUMsZ0JBQWdCLEVBQ3ZCLElBQUksQ0FBQyxFQUFHLEVBQ1IsSUFBSSxDQUFDLE1BQU8sRUFDWjtZQUNFLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU87WUFDM0IsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTztZQUMzQixtQkFBbUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtZQUNuRCxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQ3JCLDJCQUEyQixFQUFFLHFCQUFxQjtZQUNsRCxtQkFBbUIsRUFBRSxZQUFZO1lBQ2pDLHdCQUF3QjtZQUN4QixzQkFBc0IsRUFBRSxnQkFBZ0I7WUFDeEMsdUJBQXVCLEVBQUUsaUJBQWlCO1lBQzFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCO1lBQ3ZELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUs7WUFDdkIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFdBQVcsRUFBRSxLQUFLO1lBQ2xCLGdCQUFnQixFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVE7U0FDakMsQ0FDRixDQUFDO1FBQ0YsSUFBSSxVQUFVLEVBQUU7WUFDZCxpQkFBaUIsR0FBRyxVQUFVLENBQUM7U0FDaEM7UUFDRCxNQUFNLGVBQWU7UUFDbkIseUJBQXlCO1FBQ3pCLHdEQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7WUFDdEMsQ0FBQyxDQUFDLEtBQUs7WUFDUCxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssZUFBZSxFQUFFO1lBQ2xELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQztRQUUxRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUU1Qix3RUFBd0U7UUFDeEUseUVBQXlFO1FBQ3pFLDJFQUEyRTtRQUMzRSxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ3pCLGdCQUFJLENBQUMsS0FBSyxFQUFDLFFBQVEsbURBQ2pCLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsRUFDeEMsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7U0FDSDtJQUNILENBQUM7SUE2Q08sTUFBTSxDQUFDLGFBQWE7UUFDMUIsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBa05PLGdCQUFnQixDQUFDLElBQVM7UUFDaEMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxvRUFBMkIsQ0FDMUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFDdEMsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQUcseURBQWMsQ0FBQztZQUM3QixDQUFDO1lBQ0QsQ0FBQztZQUNELFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtZQUM5QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7WUFDdEQsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQjtZQUM5QyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0I7WUFDOUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQjtZQUN0QyxlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEI7WUFDdEQsSUFBSTtZQUNKLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQjtZQUN4QyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUI7WUFDNUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO1lBQzFDLGFBQWEsRUFBRSwrREFBc0I7U0FDdEMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUM1QixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUU7WUFDM0MsT0FBTztTQUNSLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFrV08sZUFBZSxDQUFDLFdBQW9DO1FBQzFELElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDbkIsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztTQUM3QztRQUNELElBQUksbURBQVUsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDdEMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsSUFBSSxDQUFDLHlFQUFtQixDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ3JDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsSUFBSSxXQUFXLEtBQUssT0FBTyxFQUFFO1lBQzNCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUN0QjtRQUNELElBQUksV0FBVyxLQUFLLFdBQVcsRUFBRTtZQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLFdBQVc7Z0JBQ1gsa0JBQWtCLEVBQUUsRUFBRTtnQkFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtnQkFDcEIsY0FBYyxFQUFFLElBQUk7YUFDckIsQ0FBQyxDQUFDO1NBQ0o7YUFBTTtZQUNMLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1NBQ2hDO0lBQ0gsQ0FBQztJQTRDTyxpQkFBaUIsQ0FDdkIsT0FBOEIsRUFDOUIsRUFDRSxpQkFBaUIsR0FBRyxLQUFLLEdBRzFCO1FBRUQsTUFBTSxhQUFhLEdBQUcsQ0FDcEIsSUFBWSxFQUNaLFlBQW9CLEVBQ3BCLFNBQVMsR0FBRyxLQUFLLEVBQ2pCLGdCQUFnQixHQUFHLEtBQUssRUFDeEIsRUFBRTtZQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQzVCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO29CQUMzRCxJQUFJLFFBQVEsQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsSUFBSSx3REFBYSxDQUFDLFFBQVEsQ0FBQyxFQUFFO3dCQUN6RCxPQUFPLDREQUFpQixDQUN0QixRQUFRLEVBQ1I7NEJBQ0UsSUFBSTs0QkFDSixTQUFTOzRCQUNULFlBQVk7eUJBQ2IsRUFDRCxnQkFBZ0IsQ0FDakIsQ0FBQztxQkFDSDtvQkFDRCxPQUFPLFFBQVEsQ0FBQztnQkFDbEIsQ0FBQyxDQUFDO2FBQ0gsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsc0RBQVcsQ0FBQztZQUNWLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRTtZQUNkLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSztZQUNwQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzFCLE1BQU0sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxvRUFBMkIsQ0FDaEU7b0JBQ0UsTUFBTSxFQUFFLENBQUM7b0JBQ1QsTUFBTSxFQUFFLENBQUM7aUJBQ1YsRUFDRCxJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0YsT0FBTztvQkFDTCxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVO29CQUNqQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsZ0NBQWdDO2lCQUNuRSxDQUFDO1lBQ0osQ0FBQztZQUNELFFBQVEsRUFBRSwyREFBa0IsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNwQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ3ZELElBQUksOERBQW1CLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ2hDLHNFQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUM5QjtZQUNILENBQUMsQ0FBQztZQUNGLFFBQVEsRUFBRSwyREFBa0IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFO2dCQUNuRSxNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDL0IsYUFBYSxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNuRCxrRUFBa0U7Z0JBQ2xFLGtFQUFrRTtnQkFDbEUsSUFBSSxDQUFDLFNBQVMsSUFBSSxXQUFXLEVBQUU7b0JBQzdCLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLFdBQVc7d0JBQzNDLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVzt3QkFDckIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDNUIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLElBQUksR0FDMUI7cUJBQ0YsQ0FBQyxDQUFDLENBQUM7aUJBQ0w7Z0JBQ0QsSUFBSSxTQUFTLEVBQUU7b0JBQ2IsMkVBQXdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7aUJBQy9EO2dCQUNELElBQUksQ0FBQyxTQUFTLElBQUksaUJBQWlCLEVBQUU7b0JBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7aUJBQ2hDO2dCQUVELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1osZUFBZSxFQUFFLElBQUk7b0JBQ3JCLGNBQWMsRUFBRSxJQUFJO2lCQUNyQixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtvQkFDNUIsMERBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2lCQUN4RDtnQkFFRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEIsQ0FBQyxDQUFDO1lBQ0YsT0FBTztZQUNQLG1CQUFtQixFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPO1NBQ3pELENBQUMsQ0FBQztRQUNILGtEQUFrRDtRQUNsRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUV4Qix1RUFBdUU7UUFDdkUsdUVBQXVFO1FBQ3ZFLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDWixrQkFBa0IsRUFBRSxFQUFFO1lBQ3RCLGdCQUFnQixFQUFFLEVBQUU7WUFDcEIsY0FBYyxFQUFFLElBQUk7U0FDckIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHdCQUF3QixDQUM5QixDQUFTLEVBQ1QsQ0FBUztRQUVULE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQzlDLHVCQUF1QixFQUFFLElBQUk7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxPQUFPLElBQUksd0RBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDM0QsT0FBTyxPQUFPLENBQUM7U0FDaEI7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxvQkFBb0IsQ0FDMUIsQ0FBUyxFQUNULENBQVMsRUFDVCxJQUtDO1FBRUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUMvQyxDQUFDLEVBQ0QsQ0FBQyxFQUNELElBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSx1QkFBdUIsQ0FDOUIsQ0FBQztRQUNGLElBQUksY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0IsSUFBSSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsY0FBYyxFQUFFO2dCQUN4QixLQUFLLElBQUksS0FBSyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtvQkFDL0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTt3QkFDM0QsT0FBTyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQzlCO2lCQUNGO2FBQ0Y7WUFDRCxNQUFNLHdCQUF3QixHQUM1QixjQUFjLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUM1Qyx5RUFBeUU7WUFDekUsNEVBQTRFO1lBQzVFLE9BQU8sMkZBQWdELENBQ3JELHdCQUF3QixFQUN4QixJQUFJLENBQUMsS0FBSyxFQUNWLENBQUMsRUFDRCxDQUFDLENBQ0Y7Z0JBQ0MsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFDM0MsQ0FBQyxDQUFDLHdCQUF3QixDQUFDO1NBQzlCO1FBQ0QsSUFBSSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUMvQixPQUFPLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxQjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLHFCQUFxQixDQUMzQixDQUFTLEVBQ1QsQ0FBUyxFQUNULDBCQUFtQyxLQUFLO1FBRXhDLE1BQU0sUUFBUSxHQUFHLHVCQUF1QjtZQUN0QyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDMUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLO2lCQUNQLFdBQVcsRUFBRTtpQkFDYixNQUFNLENBQ0wsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyx3REFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FDOUQsQ0FBQztRQUNSLE9BQU8sOERBQXFCLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDakQsa0RBQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQ25DLENBQUM7SUFDSixDQUFDO0lBNG5CTyxpQ0FBaUMsQ0FDdkMsS0FBNEM7UUFFNUMsSUFBSSxhQUFhLEtBQUssSUFBSSxFQUFFO1lBQzFCLHlFQUF5RTtZQUN6RSxrRkFBa0Y7WUFDbEYsOERBQThEO1lBQzlELGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0QjtJQUNILENBQUM7SUFnR08sMEJBQTBCLENBQ2hDLEtBQTRDO1FBRTVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7WUFDcEMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ2hCLENBQUMsRUFBRSxLQUFLLENBQUMsT0FBTztTQUNqQixDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtZQUMvQixPQUFPLENBQUMsVUFBVSxHQUFHLG9EQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pELE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzdDLE9BQU8sQ0FBQyxlQUFlLEdBQUcsc0RBQVcsQ0FDbkMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQ3RDLENBQUM7U0FDSDtJQUNILENBQUM7SUFFTyx1QkFBdUIsQ0FDN0IsS0FBNEM7UUFFNUMsTUFBTSxNQUFNLEdBQUcsb0VBQTJCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5RCxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7UUFDRixNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsMERBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRW5FLE9BQU87WUFDTCxNQUFNO1lBQ04sYUFBYSxFQUFFLEtBQUssQ0FBQyxvREFBZ0IsQ0FBQztZQUN0QyxZQUFZLEVBQUUscURBQVksQ0FDeEIsb0RBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FDdEQ7WUFDRCxVQUFVLEVBQUUseURBQWdCLENBQzFCLGlCQUFpQixFQUNqQixLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUNyQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUNyQztZQUNELDREQUE0RDtZQUM1RCxVQUFVLG9CQUFPLE1BQU0sQ0FBRTtZQUN6QixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsRUFBRTtnQkFDakUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLHFFQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDOUMsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQUUsSUFBSSxHQUFHLEVBQTBDLENBQUM7WUFDckQsTUFBTSxFQUFFO2dCQUNOLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixVQUFVLEVBQUUsS0FBSztnQkFDakIsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUN0QixjQUFjLEVBQUUsUUFBUTtnQkFDeEIsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2FBQ3ZEO1lBQ0QsR0FBRyxFQUFFO2dCQUNILE9BQU8sRUFBRSxJQUFJO2dCQUNiLGNBQWMsRUFBRSxFQUFFO2dCQUNsQixtQkFBbUIsRUFBRSxLQUFLO2dCQUMxQixpQkFBaUIsRUFBRSxLQUFLO2dCQUN4Qix5Q0FBeUMsRUFDdkMsSUFBSSxDQUFDLDRDQUE0QyxDQUMvQyxNQUFNLEVBQ04sZ0JBQWdCLENBQ2pCO2dCQUNILG1CQUFtQixFQUFFLEtBQUs7YUFDM0I7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osV0FBVyxFQUFFLEtBQUs7Z0JBQ2xCLE1BQU0sRUFBRSxJQUFJO2FBQ2I7WUFDRCxjQUFjLEVBQUU7Z0JBQ2QsTUFBTSxFQUFFLElBQUk7Z0JBQ1osSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsU0FBUyxFQUFFLElBQUk7YUFDaEI7WUFDRCxZQUFZLEVBQUU7Z0JBQ1osV0FBVyxFQUFFLEtBQUs7YUFDbkI7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELHNEQUFzRDtJQUM5Qyx1QkFBdUIsQ0FDN0IsS0FBNEMsRUFDNUMsZ0JBQWtDO1FBRWxDLElBQ0UsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUN2RTtZQUNBLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFDRCxtQkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDM0IsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzlDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM5QyxNQUFNLGFBQWEsR0FBRywyREFBa0IsQ0FBQyxDQUFDLEtBQW1CLEVBQUUsRUFBRTtZQUMvRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQzVCLElBQUksQ0FBQyxDQUFDLE1BQU0sWUFBWSxXQUFXLENBQUMsRUFBRTtnQkFDcEMsT0FBTzthQUNSO1lBRUQsSUFBSSxDQUFDLCtCQUErQixDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxXQUFXLEdBQUcsMkRBQWtCLENBQUMsR0FBRyxFQUFFO1lBQzFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztZQUM1QiwwREFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDdkQsYUFBYSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLFlBQVksRUFBRSxJQUFJO2FBQ25CLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3JELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQywyREFBa0IsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsbUJBQW1CLENBQUMseURBQWdCLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxhQUFhLEdBQUcsV0FBVyxDQUFDO1FBRTVCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQywyREFBa0IsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMzRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMseURBQWdCLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDdkQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBc01PLGtCQUFrQixDQUFDLFVBQW9DO1FBQzdELE9BQU8sVUFBVSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRU8sNENBQTRDLENBQ2xELEtBQXlDLEVBQ3pDLGdCQUE4QztRQUU5QyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDL0IsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUVELGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzdDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRywwREFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDM0QsT0FBTyxDQUNMLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVM7WUFDeEIsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUztZQUN4QixLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTO1lBQ3hCLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FDekIsQ0FBQztJQUNKLENBQUM7SUFrUk8sK0JBQStCLENBQ3JDLGdCQUFrQztRQUVsQyxPQUFPLDJEQUFrQixDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFO1lBQ2pELElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUNuRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLENBQUMsMEJBQTBCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sNkJBQTZCLENBQ25DLGdCQUFrQztRQUVsQyxPQUFPLDJEQUFrQixDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFO1lBQ2pELDhDQUE4QztZQUM5QyxLQUFLLENBQUMsR0FBRyxLQUFLLDRDQUFRLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ2pELElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUNuRCxPQUFPO2FBQ1I7WUFDRCxJQUFJLENBQUMsMEJBQTBCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sbUNBQW1DLENBQ3pDLGdCQUFrQztRQUVsQyxPQUFPLDJEQUFrQixDQUFDLENBQUMsS0FBbUIsRUFBRSxFQUFFOztZQUNoRCw4REFBOEQ7WUFDOUQsMEVBQTBFO1lBQzFFLG1FQUFtRTtZQUNuRSxxQkFBcUI7WUFDckIsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRTtnQkFDekMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxxREFBWSxDQUN6QywwREFBZSxDQUNiLDREQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUN6RCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUMxQixDQUNGLENBQUM7YUFDSDtZQUVELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDNUIsSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFZLFdBQVcsQ0FBQyxFQUFFO2dCQUNwQyxPQUFPO2FBQ1I7WUFFRCxJQUFJLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsRUFBRTtnQkFDakUsT0FBTzthQUNSO1lBRUQsTUFBTSxhQUFhLEdBQUcsb0VBQTJCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRSxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLG9EQUFZLENBQ2pDLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsYUFBYSxDQUFDLENBQUMsRUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztZQUVGLGlFQUFpRTtZQUNqRSw0REFBNEQ7WUFDNUQsNERBQTREO1lBQzVELDBCQUEwQjtZQUMxQixJQUNFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVc7Z0JBQ2xDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssT0FBTztvQkFDakMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssTUFBTSxDQUFDLEVBQ3BDO2dCQUNBLElBQ0Usa0RBQVUsQ0FDUixhQUFhLENBQUMsQ0FBQyxFQUNmLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDekIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDMUIsR0FBRywyREFBa0IsRUFDdEI7b0JBQ0EsT0FBTztpQkFDUjthQUNGO1lBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO2dCQUN0QyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLEVBQUU7b0JBQ25ELE9BQU8sSUFBSSxDQUFDO2lCQUNiO2FBQ0Y7WUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7Z0JBQ25DLE1BQU0sT0FBTyxHQUFHLGtHQUF1QyxDQUNyRCxJQUFJLENBQUMsS0FBSyxFQUNWLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUNyQyxhQUFhLENBQUMsQ0FBQyxFQUNmLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsRUFBRTtvQkFDN0IsSUFBSSxDQUFDLDRDQUE0QyxDQUMvQyxPQUFPLEVBQ1AsaUJBQWlCLENBQ2xCLENBQUM7Z0JBQ0osQ0FBQyxDQUNGLENBQUM7Z0JBRUYsSUFBSSxPQUFPLEVBQUU7b0JBQ1gsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO29CQUNoRCxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7b0JBQ2hELE9BQU87aUJBQ1I7YUFDRjtZQUVELE1BQU0sc0JBQXNCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQ3JFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQzlDLENBQUM7WUFFRixJQUNFLENBQUMsc0JBQXNCO2dCQUNyQixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMseUNBQXlDLENBQUM7Z0JBQ2pFLGdFQUFnRTtnQkFDaEUsc0JBQXNCO2dCQUN0QixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7Z0JBQ3JELHdFQUF3RTtnQkFDeEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO29CQUMvQixXQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQiwwQ0FBRSxTQUFTO3lCQUN4QyxzQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTywwQ0FBRSxFQUFFO29CQUNsQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsRUFDM0M7Z0JBQ0Esb0RBQW9EO2dCQUNwRCxnREFBZ0Q7Z0JBQ2hELGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUN6QyxNQUFNLGdCQUFnQixHQUFHLDREQUFtQixDQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUN4QixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBQ0Ysc0VBQXNFO2dCQUN0RSxrRUFBa0U7Z0JBQ2xFLElBQUksZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRTtvQkFDbEUsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxvREFBWSxDQUNqQyxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNoRCxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztvQkFFRixNQUFNLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxHQUFHO3dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzt3QkFDckQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7cUJBQ3RELENBQUM7b0JBRUYsb0RBQW9EO29CQUNwRCxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO29CQUVyQywrREFBb0IsQ0FDbEIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixLQUFLLEVBQ0wsS0FBSyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsYUFBYSxDQUNkLENBQUM7b0JBQ0YsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixDQUFDLENBQUM7b0JBRWpELHNFQUFzRTtvQkFDdEUsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFO3dCQUMzRCw0RUFBNEU7d0JBQzVFLDZEQUE2RDt3QkFDN0QsZ0RBQWdEO3dCQUVoRCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO3dCQUU5QyxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7d0JBQ3hCLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO3dCQUM1QixNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO3dCQUM3QixNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7d0JBQ3RDLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7d0JBQ2hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQzt3QkFDMUQsTUFBTSxrQkFBa0IsR0FDdEIsNERBQW1CLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUNqRCxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FDeEIsQ0FBQzt3QkFFSixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRTs0QkFDOUIsSUFDRSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQ0FDdkMseURBQXlEO2dDQUN6RCx3REFBd0Q7Z0NBQ3hELENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBSyxVQUFVLGFBQVYsVUFBVSx1QkFBVixVQUFVLENBQUUsRUFBRTtvQ0FDNUIsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLEVBQzNDO2dDQUNBLE1BQU0saUJBQWlCLEdBQUcsMkRBQWdCLENBQ3hDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUN6QixVQUFVLEVBQ1YsT0FBTyxDQUNSLENBQUM7Z0NBQ0YsTUFBTSxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsR0FBRyxvREFBWSxDQUM3QyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUMxRCxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUMxRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDcEIsQ0FBQztnQ0FDRixzRUFBYSxDQUFDLGlCQUFpQixFQUFFO29DQUMvQixDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztvQ0FDOUMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7aUNBQy9DLENBQUMsQ0FBQztnQ0FDSCxZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0NBQ3JDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQ0FDL0IsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUM7NkJBQzNEO2lDQUFNO2dDQUNMLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7NkJBQzVCO3lCQUNGO3dCQUNELE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxHQUFHLFlBQVksRUFBRSxHQUFHLGdCQUFnQixDQUFDLENBQUM7d0JBQ2pFLHNGQUErQixDQUM3QixZQUFZLEVBQ1osZ0JBQWdCLEVBQ2hCLG1CQUFtQixDQUNwQixDQUFDO3dCQUNGLDhFQUEyQixDQUN6QixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLG1CQUFtQixFQUNuQixzQkFBc0IsQ0FDdkIsQ0FBQzt3QkFDRixJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLGlCQUFpQixDQUFDLENBQUM7cUJBQ2xEO29CQUNELE9BQU87aUJBQ1I7YUFDRjtZQUVELGtFQUFrRTtZQUNsRSx1Q0FBdUM7WUFDdkMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUM7WUFDbkQsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDcEIsT0FBTzthQUNSO1lBRUQsSUFBSSxlQUFlLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRTtnQkFDdkMsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQztnQkFDdEMsTUFBTSxFQUFFLEdBQUcsYUFBYSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBRS9DLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxnQkFBZ0I7b0JBQ2hELENBQUMsQ0FBQyxlQUFlLENBQUMsU0FBUztvQkFDM0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFbkQsc0VBQWEsQ0FBQyxlQUFlLEVBQUU7b0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM3QixTQUFTO2lCQUNWLENBQUMsQ0FBQzthQUNKO2lCQUFNLElBQUkscUVBQWUsQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDM0MsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7Z0JBQ3pDLE1BQU0sTUFBTSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUM7Z0JBQ3RDLElBQUksRUFBRSxHQUFHLEtBQUssR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLEVBQUUsR0FBRyxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFFbkMsSUFBSSxxRUFBNkIsQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDL0QsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLGdFQUFxQixDQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFDdEIsRUFBRSxFQUNGLEVBQUUsQ0FDSCxDQUFDLENBQUM7aUJBQ0o7Z0JBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDdkIsc0VBQWEsQ0FBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDbkU7cUJBQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDNUIsc0VBQWEsQ0FBQyxlQUFlLEVBQUU7d0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztxQkFDM0MsQ0FBQyxDQUFDO2lCQUNKO2dCQUVELElBQUksc0VBQWdCLENBQUMsZUFBZSxDQUFDLEVBQUU7b0JBQ3JDLDZDQUE2QztvQkFDN0MsSUFBSSxDQUFDLDRDQUE0QyxDQUMvQyxlQUFlLEVBQ2YsQ0FBQyxhQUFhLENBQUMsRUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUM3QixDQUFDO2lCQUNIO2FBQ0Y7aUJBQU07Z0JBQ0wsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUMxRDtZQUVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssV0FBVyxFQUFFO2dCQUMxQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztnQkFFakQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDMUMsSUFDRSxDQUFDLEtBQUssQ0FBQyxRQUFRO29CQUNmLGtEQUFrRDtvQkFDbEQsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtvQkFDaEMsOERBQXFCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFDM0M7b0JBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxhQUFhLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRTt3QkFDbEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQzFCLHlFQUErQixpQ0FFeEIsU0FBUyxLQUNaLGtCQUFrQixFQUFFO2dDQUNsQixDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSTs2QkFDekMsS0FFSCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUN6QixDQUNGLENBQUM7cUJBQ0g7eUJBQU07d0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixrQkFBa0IsRUFBRSxFQUFFOzRCQUN0QixnQkFBZ0IsRUFBRSxFQUFFOzRCQUNwQixjQUFjLEVBQUUsSUFBSTt5QkFDckIsQ0FBQyxDQUFDO3FCQUNKO2lCQUNGO2dCQUNELGdDQUFnQztnQkFDaEMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUNuQyxpR0FBc0MsQ0FDcEMsS0FBSyxFQUNMLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ3pCLENBQUM7b0JBQ0YscUJBQXFCO2lCQUN0QjtxQkFBTTtvQkFDTCxNQUFNLHVCQUF1QixHQUFHLG1FQUEwQixDQUN4RCxRQUFRLEVBQ1IsZUFBZSxDQUNoQixDQUFDO29CQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUMxQix5RUFBK0IsaUNBRXhCLFNBQVMsS0FDWixrQkFBa0IsZ0RBQ2IsU0FBUyxDQUFDLGtCQUFrQixHQUM1Qix1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUU7NEJBQ2pELEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDOzRCQUN2QixPQUFPLEdBQUcsQ0FBQzt3QkFDYixDQUFDLEVBQUUsRUFBUyxDQUFDLEdBQ1YsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTzs0QkFDOUIsQ0FBQyxDQUFDO2dDQUNFLHNEQUFzRDtnQ0FDdEQscUNBQXFDO2dDQUNyQyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQy9CLENBQUMsdUJBQXVCLENBQUMsTUFBTTs2QkFDbEM7NEJBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUdiLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQ3pCLENBQ0YsQ0FBQztpQkFDSDthQUNGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0VBQWtFO0lBQzFELCtCQUErQixDQUNyQyxLQUFtQixFQUNuQixnQkFBa0M7UUFFbEMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEQsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUN4QixNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSzthQUN6RCxDQUFDLENBQUM7WUFDSCxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNsQyxPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFO1lBQzlDLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUs7YUFDekQsQ0FBQyxDQUFDO1lBQ0gsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEMsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVPLGlDQUFpQyxDQUN2QyxnQkFBa0M7UUFFbEMsT0FBTywyREFBa0IsQ0FBQyxDQUFDLFVBQXdCLEVBQUUsRUFBRTs7WUFDckQsTUFBTSxFQUNKLGVBQWUsRUFDZixlQUFlLEVBQ2YsWUFBWSxFQUNaLFdBQVcsRUFDWCxhQUFhLEVBQ2IsVUFBVSxFQUNWLFVBQVUsR0FDWCxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFFZixJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixVQUFVLEVBQUUsS0FBSztnQkFDakIsZUFBZSxFQUFFLElBQUk7Z0JBQ3JCLGdCQUFnQixFQUFFLElBQUk7Z0JBQ3RCLFlBQVksRUFBRSxJQUFJO2dCQUNsQixrRUFBa0U7Z0JBQ2xFLG9DQUFvQztnQkFDcEMsY0FBYyxFQUNaLFlBQVksSUFBSSx3REFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO29CQUN0RCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjO29CQUMzQixDQUFDLENBQUMsSUFBSTthQUNYLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRS9ELHlFQUF5RTtZQUN6RSwyQkFBMkI7WUFDM0IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO2dCQUNuQyxJQUNFLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLFdBQVc7b0JBQzFDLENBQUMsNkJBQWdCLENBQUMsR0FBRywwQ0FBRSxPQUFPLDBDQUFFLEVBQUU7d0JBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsU0FBUzt3QkFDekMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsRUFDNUM7b0JBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO2lCQUNsRDtxQkFBTTtvQkFDTCxNQUFNLG9CQUFvQixHQUFHLDhGQUFtQyxDQUM5RCxVQUFVLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO29CQUNGLElBQUksb0JBQW9CLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTt3QkFDNUQsSUFBSSxDQUFDLFFBQVEsQ0FBQzs0QkFDWixvQkFBb0I7NEJBQ3BCLGlCQUFpQixFQUFFLEVBQUU7eUJBQ3RCLENBQUMsQ0FBQztxQkFDSjtpQkFDRjthQUNGO1lBRUQsYUFBYSxHQUFHLElBQUksQ0FBQztZQUVyQixNQUFNLENBQUMsbUJBQW1CLENBQ3hCLDJEQUFrQixFQUNsQixnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsTUFBTyxDQUN4QyxDQUFDO1lBQ0YsTUFBTSxDQUFDLG1CQUFtQixDQUN4Qix5REFBZ0IsRUFDaEIsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLElBQUssQ0FDdEMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDeEIsc0RBQWEsRUFDYixnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsU0FBVSxDQUMzQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLG1CQUFtQixDQUN4QixvREFBVyxFQUNYLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxPQUFRLENBQ3pDLENBQUM7WUFFRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUU7Z0JBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQzlDO1lBRUQsSUFBSSxnQkFBZSxhQUFmLGVBQWUsdUJBQWYsZUFBZSxDQUFFLElBQUksTUFBSyxVQUFVLEVBQUU7Z0JBQ3hDLE1BQU0sYUFBYSxHQUFHLG9FQUEyQixDQUMvQyxVQUFVLEVBQ1YsSUFBSSxDQUFDLEtBQUssQ0FDWCxDQUFDO2dCQUVGLE1BQU0sTUFBTSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUM7Z0JBQ3RDLElBQUksRUFBRSxHQUFHLGFBQWEsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFDN0MsSUFBSSxFQUFFLEdBQUcsYUFBYSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUU3Qyx5REFBeUQ7Z0JBQ3pELElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUM5QyxFQUFFLElBQUksTUFBTSxDQUFDO29CQUNiLEVBQUUsSUFBSSxNQUFNLENBQUM7aUJBQ2Q7Z0JBRUQsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLGdCQUFnQjtvQkFDaEQsQ0FBQyxDQUFDLEVBQUU7b0JBQ0osQ0FBQyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFeEQsc0VBQWEsQ0FBQyxlQUFlLEVBQUU7b0JBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM3QixTQUFTO29CQUNULGtCQUFrQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQztpQkFDN0IsQ0FBQyxDQUFDO2dCQUVILElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLG9EQUFjLENBQUMsQ0FBQztnQkFFakQsT0FBTzthQUNSO1lBQ0QsSUFBSSxvRUFBYyxDQUFDLGVBQWUsQ0FBQyxFQUFFO2dCQUNuQyxNQUFNLFlBQVksR0FBRyxlQUFlLENBQUM7Z0JBQ3JDLElBQUk7b0JBQ0YsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUNYLEVBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUNuRCxHQUFHLEVBQUU7d0JBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO29CQUNuRCxDQUFDLENBQ0YsQ0FBQztpQkFDSDtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FDM0IsSUFBSSxDQUFDLEtBQUs7eUJBQ1AsMkJBQTJCLEVBQUU7eUJBQzdCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQzdDLENBQUM7b0JBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsb0RBQWMsQ0FBQyxDQUFDO2lCQUNsRDtnQkFDRCxPQUFPO2FBQ1I7WUFFRCxJQUFJLHFFQUFlLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQ3BDLElBQUksZUFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztpQkFDaEM7Z0JBQ0QsTUFBTSxhQUFhLEdBQUcsb0VBQTJCLENBQy9DLFVBQVUsRUFDVixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7Z0JBRUYsSUFDRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXO29CQUNsQyxlQUFlO29CQUNmLENBQUMsWUFBWSxFQUNiO29CQUNBLHNFQUFhLENBQUMsZUFBZSxFQUFFO3dCQUM3QixNQUFNLEVBQUU7NEJBQ04sR0FBRyxlQUFlLENBQUMsTUFBTTs0QkFDekI7Z0NBQ0UsYUFBYSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQztnQ0FDbkMsYUFBYSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQzs2QkFDcEM7eUJBQ0Y7cUJBQ0YsQ0FBQyxDQUFDO29CQUNILElBQUksQ0FBQyxRQUFRLENBQUM7d0JBQ1osWUFBWSxFQUFFLGVBQWU7d0JBQzdCLGNBQWMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWU7cUJBQzNDLENBQUMsQ0FBQztpQkFDSjtxQkFBTSxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxZQUFZLEVBQUU7b0JBQzdELElBQ0UsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzt3QkFDNUIsc0VBQWdCLENBQUMsZUFBZSxDQUFDLEVBQ2pDO3dCQUNBLHlFQUFzQixDQUNwQixlQUFlLEVBQ2YsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsS0FBSyxFQUNWLGFBQWEsQ0FDZCxDQUFDO3FCQUNIO29CQUNELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDbEUsSUFBSSxDQUFDLGFBQWEsRUFBRTt3QkFDbEIsb0RBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7d0JBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7NEJBQzVCLGVBQWUsRUFBRSxJQUFJOzRCQUNyQixXQUFXLEVBQUUsV0FBVzs0QkFDeEIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWdCLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUN2Qzt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDt5QkFBTTt3QkFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDOzRCQUM1QixlQUFlLEVBQUUsSUFBSTs0QkFDckIsa0JBQWtCLGtDQUNiLFNBQVMsQ0FBQyxrQkFBa0IsS0FDL0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWdCLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUN2Qzt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDtpQkFDRjtnQkFDRCxPQUFPO2FBQ1I7WUFFRCxJQUNFLFdBQVcsS0FBSyxXQUFXO2dCQUMzQixlQUFlO2dCQUNmLGtFQUF1QixDQUFDLGVBQWUsQ0FBQyxFQUN4QztnQkFDQSw0REFBNEQ7Z0JBQzVELElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQ3RELENBQUM7Z0JBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsSUFBSTtpQkFDdEIsQ0FBQyxDQUFDO2dCQUNILE9BQU87YUFDUjtZQUVELElBQUksZUFBZSxFQUFFO2dCQUNuQixzRUFBYSxDQUNYLGVBQWUsRUFDZixrRUFBdUIsQ0FBQyxlQUFlLENBQUMsQ0FDekMsQ0FBQzthQUNIO1lBRUQsSUFBSSxlQUFlLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDaEM7WUFFRCxJQUFJLGVBQWUsSUFBSSxrRUFBdUIsQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDL0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FDM0IsSUFBSSxDQUFDLEtBQUs7cUJBQ1AsMkJBQTJCLEVBQUU7cUJBQzdCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQ2hELENBQUM7YUFDSDtZQUVELHVEQUF1RDtZQUN2RCxvREFBb0Q7WUFDcEQsTUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUNoRCxJQUNFLFVBQVU7Z0JBQ1YsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVztnQkFDbEMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsbUJBQW1CO2dCQUN6QyxtRUFBbUU7Z0JBQ25FLGVBQWU7Z0JBQ2YsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CO29CQUMvQixDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFDN0M7Z0JBQ0Esd0RBQXdEO2dCQUN4RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFO29CQUMzRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO3dCQUNoRCxJQUFJLDREQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLEVBQUU7NEJBQzlDLHVEQUF1RDs0QkFDdkQsc0RBQXNEOzRCQUN0RCx3QkFBd0I7NEJBQ3hCLE1BQU0sb0NBQW9DLEdBQUcsVUFBVSxDQUFDLFFBQVE7aUNBQzdELE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQ25CLDREQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQ3REO2lDQUNBLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7aUNBQzNDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLGlDQUFNLE1BQU0sR0FBSyxHQUFHLEVBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQzs0QkFFeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQ0FDN0IsZ0JBQWdCLGtDQUNYLFVBQVUsQ0FBQyxrQkFBa0IsR0FDN0IsVUFBVSxDQUFDLFFBQVE7cUNBQ25CLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztxQ0FDaEMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsaUNBQU0sSUFBSSxHQUFLLEdBQUcsRUFBRyxFQUFFLEVBQUUsQ0FBQyxDQUNwRDtnQ0FDRCxrQkFBa0Isa0NBQ2IsVUFBVSxDQUFDLGtCQUFrQixHQUM3QixvQ0FBb0MsQ0FDeEM7NkJBQ0YsQ0FBQyxDQUFDLENBQUM7eUJBQ0w7NkJBQU07NEJBQ0wsc0NBQXNDOzRCQUN0QyxpQ0FBaUM7NEJBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUMxQix5RUFBK0IsaUNBRXhCLFNBQVMsS0FDWixrQkFBa0Isa0NBQ2IsU0FBUyxDQUFDLGtCQUFrQixLQUMvQixDQUFDLFVBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLFFBRzNCLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQ3pCLENBQ0YsQ0FBQzt5QkFDSDtxQkFDRjt5QkFBTTt3QkFDTCxpQ0FBaUM7d0JBQ2pDLGlDQUFpQzt3QkFFakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQzs0QkFDN0Isa0JBQWtCLGtDQUNiLFVBQVUsQ0FBQyxrQkFBa0IsS0FDaEMsQ0FBQyxVQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUN2Qjt5QkFDRixDQUFDLENBQUMsQ0FBQztxQkFDTDtpQkFDRjtxQkFBTTtvQkFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxtQkFDeEIseUVBQStCLGlDQUUzQixTQUFTLEtBQ1osa0JBQWtCLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FFL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FDekIsRUFDRCxDQUFDLENBQUM7aUJBQ0w7YUFDRjtZQUVELElBQ0UsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtnQkFDaEMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVztnQkFDbEMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVU7Z0JBQ3RCLENBQUMsQ0FBQyxVQUFVO29CQUNWLDJGQUFnRCxDQUM5QyxVQUFVLEVBQ1YsSUFBSSxDQUFDLEtBQUssRUFDVixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUN6QixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUMxQixDQUFDO29CQUNGLENBQUMsQ0FBQyxVQUFVO3dCQUNWLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLEVBQ3BFO2dCQUNBLDZCQUE2QjtnQkFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixrQkFBa0IsRUFBRSxFQUFFO29CQUN0QixnQkFBZ0IsRUFBRSxFQUFFO29CQUNwQixjQUFjLEVBQUUsSUFBSTtpQkFDckIsQ0FBQyxDQUFDO2dCQUVILE9BQU87YUFDUjtZQUVELElBQUksQ0FBQyxhQUFhLElBQUksV0FBVyxLQUFLLFVBQVUsSUFBSSxlQUFlLEVBQUU7Z0JBQ25FLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzVCLGtCQUFrQixrQ0FDYixTQUFTLENBQUMsa0JBQWtCLEtBQy9CLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksR0FDM0I7aUJBQ0YsQ0FBQyxDQUFDLENBQUM7YUFDTDtZQUVELElBQ0UsV0FBVyxLQUFLLFdBQVc7Z0JBQzNCLDhEQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUMzRDtnQkFDQSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQ2hDO1lBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLFVBQVUsSUFBSSxVQUFVLEVBQUU7Z0JBQ2pFLENBQUMsbUVBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDM0IsQ0FBQyxDQUFDLDJFQUE0QjtvQkFDOUIsQ0FBQyxDQUFDLG1FQUFvQixDQUFDLENBQ3ZCLDREQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUMxRCxDQUFDO2FBQ0g7WUFFRCxJQUFJLENBQUMsYUFBYSxJQUFJLFdBQVcsS0FBSyxVQUFVLEVBQUU7Z0JBQ2hELG9EQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNaLGVBQWUsRUFBRSxJQUFJO29CQUNyQixpQkFBaUIsRUFBRSxFQUFFO29CQUNyQixXQUFXLEVBQUUsV0FBVztpQkFDekIsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFDWixlQUFlLEVBQUUsSUFBSTtvQkFDckIsaUJBQWlCLEVBQUUsRUFBRTtpQkFDdEIsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFzYk8seUJBQXlCLENBQy9CLGdCQUFpRDtRQUVqRCxNQUFNLGlCQUFpQixHQUFHLGdGQUE2QixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRU8sY0FBYyxDQUFDLFVBQW9DO1FBQ3pELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDNUIsa0JBQWtCLEVBQUUsRUFBRTtZQUN0QixnQkFBZ0IsRUFBRSxFQUFFO1lBQ3BCLG1FQUFtRTtZQUNuRSxrQkFBa0I7WUFDbEIsY0FBYyxFQUNaLFNBQVMsQ0FBQyxjQUFjO2dCQUN4QixVQUFVLElBQUksSUFBSTtnQkFDbEIsMERBQWdCLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUM7Z0JBQ3BELENBQUMsQ0FBQyxTQUFTLENBQUMsY0FBYztnQkFDMUIsQ0FBQyxDQUFDLElBQUk7U0FDWCxDQUFDLENBQUMsQ0FBQztRQUNKLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDWixrQkFBa0IsRUFBRSxFQUFFO1lBQ3RCLDBCQUEwQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO1NBQzFELENBQUMsQ0FBQztJQUNMLENBQUM7SUEwZk8scUNBQXFDLENBQzNDLENBQVMsRUFDVCxDQUFTLEVBQ1QsUUFBa0IsRUFDbEIsTUFBZ0MsRUFDaEMsS0FBYTtRQUViLE1BQU0sb0JBQW9CLEdBQUcscUVBQTRCLENBQ3ZELElBQUksQ0FBQyxLQUFLO2FBQ1AsMkJBQTJCLEVBQUU7YUFDN0IsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLHdEQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsRUFDL0MsQ0FBQyxFQUNELENBQUMsQ0FDRixDQUFDO1FBQ0YsSUFBSSxvQkFBb0IsRUFBRTtZQUN4QixNQUFNLGNBQWMsR0FDbEIsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7WUFDMUQsTUFBTSxjQUFjLEdBQ2xCLG9CQUFvQixDQUFDLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQzNELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDakMsQ0FBQyxHQUFHLGNBQWMsRUFDbEIsQ0FBQyxHQUFHLGNBQWMsQ0FDbkIsQ0FBQztZQUNGLE1BQU0saUJBQWlCLEdBQ3JCLGdCQUFnQixHQUFHLHNFQUE2QixDQUFDO1lBQ25ELElBQUksaUJBQWlCLEVBQUU7Z0JBQ3JCLE1BQU0sRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxvRUFBMkIsQ0FDaEUsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsRUFDbEQsUUFBUSxDQUNULENBQUM7Z0JBQ0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxDQUFDO2FBQ2pFO1NBQ0Y7SUFDSCxDQUFDO0lBMEVPLGdCQUFnQjs7UUFDdEIsSUFBSSxVQUFJLENBQUMsc0JBQXNCLDBDQUFFLE9BQU8sRUFBRTtZQUN4QyxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUM7WUFDaEUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ2xFLE9BQU87Z0JBQ0wsVUFBVSxFQUFFLElBQUk7Z0JBQ2hCLFNBQVMsRUFBRSxHQUFHO2FBQ2YsQ0FBQztTQUNIO1FBQ0QsT0FBTztZQUNMLFVBQVUsRUFBRSxDQUFDO1lBQ2IsU0FBUyxFQUFFLENBQUM7U0FDYixDQUFDO0lBQ0osQ0FBQztJQUVhLGNBQWM7O1lBQzFCLE1BQU0sV0FBVyxHQUNmLGtEQUFjLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7Z0JBQzNELCtDQUFXLENBQUM7WUFDZCxNQUFNLG1EQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2QixDQUFDO0tBQUE7O0FBeDJKYSxnQkFBWSxHQUFzQjtJQUM5QyxzRUFBc0U7SUFDdEUsU0FBUyxFQUFFLDJEQUFrQjtDQUM5QixDQUFDO0FBdzNKSixJQUNFLGFBQW9CLEtBQUssaURBQVE7SUFDakMsYUFBb0IsS0FBSyx3REFBZSxFQUN4QztJQUNBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsSUFBSyxFQUFrQixDQUFDO0lBRTNDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFO1FBQ2hDLFFBQVEsRUFBRTtZQUNSLFlBQVksRUFBRSxJQUFJO1lBQ2xCLEdBQUc7Z0JBQ0QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBQ3RELENBQUM7WUFDRCxHQUFHLENBQUMsUUFBNkI7Z0JBQy9CLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckQsQ0FBQztTQUNGO0tBQ0YsQ0FBQyxDQUFDO0NBQ0o7QUFDRCxpRUFBZSxHQUFHLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vY29tcG9uZW50cy9BcHAudHN4PzAwNzAiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHVzZUNvbnRleHQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IFJvdWdoQ2FudmFzIH0gZnJvbSBcInJvdWdoanMvYmluL2NhbnZhc1wiO1xuaW1wb3J0IHJvdWdoIGZyb20gXCJyb3VnaGpzL2Jpbi9yb3VnaFwiO1xuaW1wb3J0IGNsc3ggZnJvbSBcImNsc3hcIjtcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gXCJuYW5vaWRcIjtcblxuaW1wb3J0IHtcbiAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICBhY3Rpb25CcmluZ0ZvcndhcmQsXG4gIGFjdGlvbkJyaW5nVG9Gcm9udCxcbiAgYWN0aW9uQ29weSxcbiAgYWN0aW9uQ29weUFzUG5nLFxuICBhY3Rpb25Db3B5QXNTdmcsXG4gIGFjdGlvbkNvcHlTdHlsZXMsXG4gIGFjdGlvbkN1dCxcbiAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgYWN0aW9uRmluYWxpemUsXG4gIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICBhY3Rpb25GbGlwVmVydGljYWwsXG4gIGFjdGlvbkdyb3VwLFxuICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgYWN0aW9uU2VsZWN0QWxsLFxuICBhY3Rpb25TZW5kQmFja3dhcmQsXG4gIGFjdGlvblNlbmRUb0JhY2ssXG4gIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgYWN0aW9uVW5ncm91cCxcbn0gZnJvbSBcIi4uL2FjdGlvbnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlZG9BY3Rpb24sIGNyZWF0ZVVuZG9BY3Rpb24gfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25IaXN0b3J5XCI7XG5pbXBvcnQgeyBBY3Rpb25NYW5hZ2VyIH0gZnJvbSBcIi4uL2FjdGlvbnMvbWFuYWdlclwiO1xuaW1wb3J0IHsgYWN0aW9ucyB9IGZyb20gXCIuLi9hY3Rpb25zL3JlZ2lzdGVyXCI7XG5pbXBvcnQgeyBBY3Rpb25SZXN1bHQgfSBmcm9tIFwiLi4vYWN0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgdHJhY2tFdmVudCB9IGZyb20gXCIuLi9hbmFseXRpY3NcIjtcbmltcG9ydCB7IGdldERlZmF1bHRBcHBTdGF0ZSB9IGZyb20gXCIuLi9hcHBTdGF0ZVwiO1xuaW1wb3J0IHtcbiAgY29weVRvQ2xpcGJvYXJkLFxuICBwYXJzZUNsaXBib2FyZCxcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IsXG4gIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQsXG59IGZyb20gXCIuLi9jbGlwYm9hcmRcIjtcbmltcG9ydCB7XG4gIEFQUF9OQU1FLFxuICBDVVJTT1JfVFlQRSxcbiAgREVGQVVMVF9NQVhfSU1BR0VfV0lEVEhfT1JfSEVJR0hULFxuICBERUZBVUxUX1VJX09QVElPTlMsXG4gIERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gIERSQUdHSU5HX1RIUkVTSE9MRCxcbiAgRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5ULFxuICBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVOVixcbiAgRVZFTlQsXG4gIEdSSURfU0laRSxcbiAgSU1BR0VfUkVOREVSX1RJTUVPVVQsXG4gIExJTkVfQ09ORklSTV9USFJFU0hPTEQsXG4gIE1BWF9BTExPV0VEX0ZJTEVfQllURVMsXG4gIE1JTUVfVFlQRVMsXG4gIE1RX01BWF9IRUlHSFRfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfTEFORFNDQVBFLFxuICBNUV9NQVhfV0lEVEhfUE9SVFJBSVQsXG4gIFBPSU5URVJfQlVUVE9OLFxuICBTQ1JPTExfVElNRU9VVCxcbiAgVEFQX1RXSUNFX1RJTUVPVVQsXG4gIFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xELFxuICBUSEVNRSxcbiAgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCxcbiAgVVJMX0hBU0hfS0VZUyxcbiAgVVJMX1FVRVJZX0tFWVMsXG4gIFpPT01fU1RFUCxcbn0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgbG9hZEZyb21CbG9iIH0gZnJvbSBcIi4uL2RhdGFcIjtcbmltcG9ydCB7IGlzVmFsaWRMaWJyYXJ5IH0gZnJvbSBcIi4uL2RhdGEvanNvblwiO1xuaW1wb3J0IExpYnJhcnkgZnJvbSBcIi4uL2RhdGEvbGlicmFyeVwiO1xuaW1wb3J0IHsgcmVzdG9yZSwgcmVzdG9yZUVsZW1lbnRzLCByZXN0b3JlTGlicmFyeUl0ZW1zIH0gZnJvbSBcIi4uL2RhdGEvcmVzdG9yZVwiO1xuaW1wb3J0IHtcbiAgZHJhZ05ld0VsZW1lbnQsXG4gIGRyYWdTZWxlY3RlZEVsZW1lbnRzLFxuICBkdXBsaWNhdGVFbGVtZW50LFxuICBnZXRDb21tb25Cb3VuZHMsXG4gIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCxcbiAgZ2V0RHJhZ09mZnNldFhZLFxuICBnZXRFbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zLFxuICBnZXRQZXJmZWN0RWxlbWVudFNpemUsXG4gIGdldFJlc2l6ZUFycm93RGlyZWN0aW9uLFxuICBnZXRSZXNpemVPZmZzZXRYWSxcbiAgZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMsXG4gIGhpdFRlc3QsXG4gIGlzSGl0dGluZ0VsZW1lbnRCb3VuZGluZ0JveFdpdGhvdXRIaXR0aW5nRWxlbWVudCxcbiAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQsXG4gIGlzTm9uRGVsZXRlZEVsZW1lbnQsXG4gIGlzVGV4dEVsZW1lbnQsXG4gIG5ld0VsZW1lbnQsXG4gIG5ld0xpbmVhckVsZW1lbnQsXG4gIG5ld1RleHRFbGVtZW50LFxuICBuZXdJbWFnZUVsZW1lbnQsXG4gIHRleHRXeXNpd3lnLFxuICB0cmFuc2Zvcm1FbGVtZW50cyxcbiAgdXBkYXRlVGV4dEVsZW1lbnQsXG59IGZyb20gXCIuLi9lbGVtZW50XCI7XG5pbXBvcnQge1xuICBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzLFxuICBmaXhCaW5kaW5nc0FmdGVyRGVsZXRpb24sXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0RWxpZ2libGVFbGVtZW50c0ZvckJpbmRpbmcsXG4gIGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyxcbiAgaXNCaW5kaW5nRW5hYmxlZCxcbiAgaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kLFxuICBtYXliZUJpbmRMaW5lYXJFbGVtZW50LFxuICBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50LFxuICB1bmJpbmRMaW5lYXJFbGVtZW50cyxcbiAgdXBkYXRlQm91bmRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvYmluZGluZ1wiO1xuaW1wb3J0IHsgTGluZWFyRWxlbWVudEVkaXRvciB9IGZyb20gXCIuLi9lbGVtZW50L2xpbmVhckVsZW1lbnRFZGl0b3JcIjtcbmltcG9ydCB7XG4gIGJ1bXBWZXJzaW9uLFxuICBtdXRhdGVFbGVtZW50LFxuICBuZXdFbGVtZW50V2l0aCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHsgZGVlcENvcHlFbGVtZW50LCBuZXdGcmVlRHJhd0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudC9uZXdFbGVtZW50XCI7XG5pbXBvcnQge1xuICBoYXNCb3VuZFRleHRFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50LFxuICBpc0JpbmRpbmdFbGVtZW50VHlwZSxcbiAgaXNJbWFnZUVsZW1lbnQsXG4gIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQsXG4gIGlzTGluZWFyRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50VHlwZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZUNoZWNrc1wiO1xuaW1wb3J0IHtcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdHZW5lcmljRWxlbWVudCxcbiAgRXhjYWxpZHJhd0xpbmVhckVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbiAgTm9uRGVsZXRlZCxcbiAgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICBGaWxlSWQsXG59IGZyb20gXCIuLi9lbGVtZW50L3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRDZW50ZXIsIGdldERpc3RhbmNlIH0gZnJvbSBcIi4uL2dlc3R1cmVcIjtcbmltcG9ydCB7XG4gIGVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudCxcbiAgZ2V0RWxlbWVudHNJbkdyb3VwLFxuICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50LFxuICBnZXRTZWxlY3RlZEdyb3VwSWRzLFxuICBpc0VsZW1lbnRJbkdyb3VwLFxuICBpc1NlbGVjdGVkVmlhR3JvdXAsXG4gIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMsXG59IGZyb20gXCIuLi9ncm91cHNcIjtcbmltcG9ydCBIaXN0b3J5IGZyb20gXCIuLi9oaXN0b3J5XCI7XG5pbXBvcnQgeyBkZWZhdWx0TGFuZywgZ2V0TGFuZ3VhZ2UsIGxhbmd1YWdlcywgc2V0TGFuZ3VhZ2UsIHQgfSBmcm9tIFwiLi4vaTE4blwiO1xuaW1wb3J0IHtcbiAgQ09ERVMsXG4gIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIsXG4gIHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8sXG4gIHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlLFxuICBpc0Fycm93S2V5LFxuICBLRVlTLFxufSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHsgZGlzdGFuY2UyZCwgZ2V0R3JpZFBvaW50LCBpc1BhdGhBTG9vcCB9IGZyb20gXCIuLi9tYXRoXCI7XG5pbXBvcnQgeyByZW5kZXJTY2VuZSB9IGZyb20gXCIuLi9yZW5kZXJlclwiO1xuaW1wb3J0IHsgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudCB9IGZyb20gXCIuLi9yZW5kZXJlci9yZW5kZXJFbGVtZW50XCI7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVTY3JvbGxDZW50ZXIsXG4gIGdldEVsZW1lbnRDb250YWluaW5nUG9zaXRpb24sXG4gIGdldEVsZW1lbnRzQXRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24sXG4gIGdldE5vcm1hbGl6ZWRab29tLFxuICBnZXRTZWxlY3RlZEVsZW1lbnRzLFxuICBoYXNCYWNrZ3JvdW5kLFxuICBpc092ZXJTY3JvbGxCYXJzLFxuICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQsXG59IGZyb20gXCIuLi9zY2VuZVwiO1xuaW1wb3J0IFNjZW5lIGZyb20gXCIuLi9zY2VuZS9TY2VuZVwiO1xuaW1wb3J0IHsgUmVuZGVyQ29uZmlnLCBTY3JvbGxCYXJzIH0gZnJvbSBcIi4uL3NjZW5lL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXROZXdab29tIH0gZnJvbSBcIi4uL3NjZW5lL3pvb21cIjtcbmltcG9ydCB7IGZpbmRTaGFwZUJ5S2V5IH0gZnJvbSBcIi4uL3NoYXBlc1wiO1xuaW1wb3J0IHtcbiAgQXBwQ2xhc3NQcm9wZXJ0aWVzLFxuICBBcHBQcm9wcyxcbiAgQXBwU3RhdGUsXG4gIEJpbmFyeUZpbGVEYXRhLFxuICBEYXRhVVJMLFxuICBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSxcbiAgQmluYXJ5RmlsZXMsXG4gIEdlc3R1cmUsXG4gIEdlc3R1cmVFdmVudCxcbiAgTGlicmFyeUl0ZW1zLFxuICBQb2ludGVyRG93blN0YXRlLFxuICBTY2VuZURhdGEsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZGVib3VuY2UsXG4gIGRpc3RhbmNlLFxuICBnZXRGb250U3RyaW5nLFxuICBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcixcbiAgaXNJbnB1dExpa2UsXG4gIGlzVG9vbEljb24sXG4gIGlzV3JpdGFibGVFbGVtZW50LFxuICByZXNldEN1cnNvcixcbiAgcmVzb2x2YWJsZVByb21pc2UsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyxcbiAgc2V0Q3Vyc29yLFxuICBzZXRDdXJzb3JGb3JTaGFwZSxcbiAgdHVwbGVUb0Nvb3JzLFxuICB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMsXG4gIHdpdGhCYXRjaGVkVXBkYXRlcyxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQ29udGV4dE1lbnUsIHsgQ29udGV4dE1lbnVPcHRpb24gfSBmcm9tIFwiLi9Db250ZXh0TWVudVwiO1xuaW1wb3J0IExheWVyVUkgZnJvbSBcIi4vTGF5ZXJVSVwiO1xuaW1wb3J0IHsgU3RhdHMgfSBmcm9tIFwiLi9TdGF0c1wiO1xuaW1wb3J0IHsgVG9hc3QgfSBmcm9tIFwiLi9Ub2FzdFwiO1xuaW1wb3J0IHsgYWN0aW9uVG9nZ2xlVmlld01vZGUgfSBmcm9tIFwiLi4vYWN0aW9ucy9hY3Rpb25Ub2dnbGVWaWV3TW9kZVwiO1xuaW1wb3J0IHtcbiAgZGF0YVVSTFRvRmlsZSxcbiAgZ2VuZXJhdGVJZEZyb21GaWxlLFxuICBnZXREYXRhVVJMLFxuICBpc1N1cHBvcnRlZEltYWdlRmlsZSxcbiAgcmVzaXplSW1hZ2VGaWxlLFxuICBTVkdTdHJpbmdUb0ZpbGUsXG59IGZyb20gXCIuLi9kYXRhL2Jsb2JcIjtcbmltcG9ydCB7XG4gIGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyxcbiAgbG9hZEhUTUxJbWFnZUVsZW1lbnQsXG4gIG5vcm1hbGl6ZVNWRyxcbiAgdXBkYXRlSW1hZ2VDYWNoZSBhcyBfdXBkYXRlSW1hZ2VDYWNoZSxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvaW1hZ2VcIjtcbmltcG9ydCB0aHJvdHRsZSBmcm9tIFwibG9kYXNoLnRocm90dGxlXCI7XG5pbXBvcnQgeyBmaWxlT3BlbiwgbmF0aXZlRmlsZVN5c3RlbVN1cHBvcnRlZCB9IGZyb20gXCIuLi9kYXRhL2ZpbGVzeXN0ZW1cIjtcbmltcG9ydCB7XG4gIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24sXG4gIGdldEFwcHJveE1pbkxpbmVIZWlnaHQsXG4gIGdldEFwcHJveE1pbkxpbmVXaWR0aCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudElkLFxufSBmcm9tIFwiLi4vZWxlbWVudC90ZXh0RWxlbWVudFwiO1xuaW1wb3J0IHsgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3ggfSBmcm9tIFwiLi4vZWxlbWVudC9jb2xsaXNpb25cIjtcblxuY29uc3QgSXNNb2JpbGVDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dChmYWxzZSk7XG5leHBvcnQgY29uc3QgdXNlSXNNb2JpbGUgPSAoKSA9PiB1c2VDb250ZXh0KElzTW9iaWxlQ29udGV4dCk7XG5jb25zdCBFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8e1xuICBjb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbiAgaWQ6IHN0cmluZyB8IG51bGw7XG59Pih7IGNvbnRhaW5lcjogbnVsbCwgaWQ6IG51bGwgfSk7XG5leHBvcnQgY29uc3QgdXNlRXhjYWxpZHJhd0NvbnRhaW5lciA9ICgpID0+XG4gIHVzZUNvbnRleHQoRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQpO1xuXG5sZXQgZGlkVGFwVHdpY2U6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCB0YXBwZWRUd2ljZVRpbWVyID0gMDtcbmxldCBjdXJzb3JYID0gMDtcbmxldCBjdXJzb3JZID0gMDtcbmxldCBpc0hvbGRpbmdTcGFjZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzUGFubmluZzogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGlzRHJhZ2dpbmdTY3JvbGxCYXI6IGJvb2xlYW4gPSBmYWxzZTtcbmxldCBjdXJyZW50U2Nyb2xsQmFyczogU2Nyb2xsQmFycyA9IHsgaG9yaXpvbnRhbDogbnVsbCwgdmVydGljYWw6IG51bGwgfTtcbmxldCB0b3VjaFRpbWVvdXQgPSAwO1xubGV0IGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG5sZXQgbGFzdFBvaW50ZXJVcDogKChldmVudDogYW55KSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuY29uc3QgZ2VzdHVyZTogR2VzdHVyZSA9IHtcbiAgcG9pbnRlcnM6IG5ldyBNYXAoKSxcbiAgbGFzdENlbnRlcjogbnVsbCxcbiAgaW5pdGlhbERpc3RhbmNlOiBudWxsLFxuICBpbml0aWFsU2NhbGU6IG51bGwsXG59O1xuXG5jbGFzcyBBcHAgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8QXBwUHJvcHMsIEFwcFN0YXRlPiB7XG4gIGNhbnZhczogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiY2FudmFzXCJdID0gbnVsbDtcbiAgcmM6IFJvdWdoQ2FudmFzIHwgbnVsbCA9IG51bGw7XG4gIHVubW91bnRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBhY3Rpb25NYW5hZ2VyOiBBY3Rpb25NYW5hZ2VyO1xuICBpc01vYmlsZSA9IGZhbHNlO1xuICBkZXRhY2hJc01vYmlsZU1xSGFuZGxlcj86ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBleGNhbGlkcmF3Q29udGFpbmVyUmVmID0gUmVhY3QuY3JlYXRlUmVmPEhUTUxEaXZFbGVtZW50PigpO1xuXG4gIHB1YmxpYyBzdGF0aWMgZGVmYXVsdFByb3BzOiBQYXJ0aWFsPEFwcFByb3BzPiA9IHtcbiAgICAvLyBuZWVkZWQgZm9yIHRlc3RzIHRvIHBhc3Mgc2luY2Ugd2UgZGlyZWN0bHkgcmVuZGVyIEFwcCBpbiBtYW55IHRlc3RzXG4gICAgVUlPcHRpb25zOiBERUZBVUxUX1VJX09QVElPTlMsXG4gIH07XG5cbiAgcHJpdmF0ZSBzY2VuZTogU2NlbmU7XG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyOiBIVE1MRWxlbWVudCB8IERvY3VtZW50IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgbGlicmFyeTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wibGlicmFyeVwiXTtcbiAgcHVibGljIGxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlOiBMaWJyYXJ5SXRlbXMgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBoaXN0b3J5OiBIaXN0b3J5O1xuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZToge1xuICAgIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICAgIGlkOiBzdHJpbmc7XG4gIH07XG5cbiAgcHVibGljIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHt9O1xuICBwdWJsaWMgaW1hZ2VDYWNoZTogQXBwQ2xhc3NQcm9wZXJ0aWVzW1wiaW1hZ2VDYWNoZVwiXSA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQXBwUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgY29uc3QgZGVmYXVsdEFwcFN0YXRlID0gZ2V0RGVmYXVsdEFwcFN0YXRlKCk7XG4gICAgY29uc3Qge1xuICAgICAgZXhjYWxpZHJhd1JlZixcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgemVuTW9kZUVuYWJsZWQgPSBmYWxzZSxcbiAgICAgIGdyaWRNb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgdGhlbWUgPSBkZWZhdWx0QXBwU3RhdGUudGhlbWUsXG4gICAgICBuYW1lID0gZGVmYXVsdEFwcFN0YXRlLm5hbWUsXG4gICAgfSA9IHByb3BzO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi5kZWZhdWx0QXBwU3RhdGUsXG4gICAgICB0aGVtZSxcbiAgICAgIGlzTG9hZGluZzogdHJ1ZSxcbiAgICAgIC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpLFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgemVuTW9kZUVuYWJsZWQsXG4gICAgICBncmlkU2l6ZTogZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIG5hbWUsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICB9O1xuXG4gICAgdGhpcy5pZCA9IG5hbm9pZCgpO1xuXG4gICAgaWYgKGV4Y2FsaWRyYXdSZWYpIHtcbiAgICAgIGNvbnN0IHJlYWR5UHJvbWlzZSA9XG4gICAgICAgIChcImN1cnJlbnRcIiBpbiBleGNhbGlkcmF3UmVmICYmIGV4Y2FsaWRyYXdSZWYuY3VycmVudD8ucmVhZHlQcm9taXNlKSB8fFxuICAgICAgICByZXNvbHZhYmxlUHJvbWlzZTxFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQST4oKTtcblxuICAgICAgY29uc3QgYXBpOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSSA9IHtcbiAgICAgICAgcmVhZHk6IHRydWUsXG4gICAgICAgIHJlYWR5UHJvbWlzZSxcbiAgICAgICAgdXBkYXRlU2NlbmU6IHRoaXMudXBkYXRlU2NlbmUsXG4gICAgICAgIGFkZEZpbGVzOiB0aGlzLmFkZEZpbGVzLFxuICAgICAgICByZXNldFNjZW5lOiB0aGlzLnJlc2V0U2NlbmUsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkOiB0aGlzLmdldFNjZW5lRWxlbWVudHNJbmNsdWRpbmdEZWxldGVkLFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY2xlYXI6IHRoaXMucmVzZXRIaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgICBzY3JvbGxUb0NvbnRlbnQ6IHRoaXMuc2Nyb2xsVG9Db250ZW50LFxuICAgICAgICBnZXRTY2VuZUVsZW1lbnRzOiB0aGlzLmdldFNjZW5lRWxlbWVudHMsXG4gICAgICAgIGdldEFwcFN0YXRlOiAoKSA9PiB0aGlzLnN0YXRlLFxuICAgICAgICBnZXRGaWxlczogKCkgPT4gdGhpcy5maWxlcyxcbiAgICAgICAgcmVmcmVzaDogdGhpcy5yZWZyZXNoLFxuICAgICAgICBpbXBvcnRMaWJyYXJ5OiB0aGlzLmltcG9ydExpYnJhcnlGcm9tVXJsLFxuICAgICAgICBzZXRUb2FzdE1lc3NhZ2U6IHRoaXMuc2V0VG9hc3RNZXNzYWdlLFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgIH0gYXMgY29uc3Q7XG4gICAgICBpZiAodHlwZW9mIGV4Y2FsaWRyYXdSZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBleGNhbGlkcmF3UmVmKGFwaSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGNhbGlkcmF3UmVmLmN1cnJlbnQgPSBhcGk7XG4gICAgICB9XG4gICAgICByZWFkeVByb21pc2UucmVzb2x2ZShhcGkpO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlID0ge1xuICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgIH07XG5cbiAgICB0aGlzLnNjZW5lID0gbmV3IFNjZW5lKCk7XG4gICAgdGhpcy5saWJyYXJ5ID0gbmV3IExpYnJhcnkodGhpcyk7XG4gICAgdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIgPSBuZXcgQWN0aW9uTWFuYWdlcihcbiAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCxcbiAgICAgICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAoKSA9PiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcyxcbiAgICApO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFsbChhY3Rpb25zKTtcblxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVVbmRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5yZWdpc3RlckFjdGlvbihjcmVhdGVSZWRvQWN0aW9uKHRoaXMuaGlzdG9yeSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDYW52YXMoKSB7XG4gICAgY29uc3QgY2FudmFzU2NhbGUgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhbnZhc0RPTUhlaWdodCxcbiAgICAgIHZpZXdNb2RlRW5hYmxlZCxcbiAgICB9ID0gdGhpcy5zdGF0ZTtcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhc0RPTVdpZHRoICogY2FudmFzU2NhbGU7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY2FudmFzRE9NSGVpZ2h0ICogY2FudmFzU2NhbGU7XG4gICAgaWYgKHZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGNhbnZhc1xuICAgICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICAgICAgY3Vyc29yOiBDVVJTT1JfVFlQRS5HUkFCLFxuICAgICAgICAgIH19XG4gICAgICAgICAgd2lkdGg9e2NhbnZhc1dpZHRofVxuICAgICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudX1cbiAgICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgICAgb25Qb2ludGVyQ2FuY2VsPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgID5cbiAgICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgICA8L2NhbnZhcz5cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICA8Y2FudmFzXG4gICAgICAgIGNsYXNzTmFtZT1cImV4Y2FsaWRyYXdfX2NhbnZhc1wiXG4gICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgICB9fVxuICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgIGhlaWdodD17Y2FudmFzSGVpZ2h0fVxuICAgICAgICByZWY9e3RoaXMuaGFuZGxlQ2FudmFzUmVmfVxuICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICBvblBvaW50ZXJEb3duPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJEb3dufVxuICAgICAgICBvbkRvdWJsZUNsaWNrPXt0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrfVxuICAgICAgICBvblBvaW50ZXJNb3ZlPXt0aGlzLmhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlfVxuICAgICAgICBvblBvaW50ZXJVcD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgb25Ub3VjaE1vdmU9e3RoaXMuaGFuZGxlVG91Y2hNb3ZlfVxuICAgICAgPlxuICAgICAgICB7dChcImxhYmVscy5kcmF3aW5nQ2FudmFzXCIpfVxuICAgICAgPC9jYW52YXM+XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5kZXIoKSB7XG4gICAgY29uc3QgeyB6ZW5Nb2RlRW5hYmxlZCwgdmlld01vZGVFbmFibGVkIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgY29uc3Qge1xuICAgICAgb25Db2xsYWJCdXR0b25DbGljayxcbiAgICAgIHJlbmRlclRvcFJpZ2h0VUksXG4gICAgICByZW5kZXJGb290ZXIsXG4gICAgICByZW5kZXJDdXN0b21TdGF0cyxcbiAgICB9ID0gdGhpcy5wcm9wcztcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17Y2xzeChcImV4Y2FsaWRyYXcgZXhjYWxpZHJhdy1jb250YWluZXJcIiwge1xuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tdmlldy1tb2RlXCI6IHZpZXdNb2RlRW5hYmxlZCxcbiAgICAgICAgICBcImV4Y2FsaWRyYXctLW1vYmlsZVwiOiB0aGlzLmlzTW9iaWxlLFxuICAgICAgICB9KX1cbiAgICAgICAgcmVmPXt0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWZ9XG4gICAgICAgIG9uRHJvcD17dGhpcy5oYW5kbGVBcHBPbkRyb3B9XG4gICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICBvbktleURvd249e1xuICAgICAgICAgIHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSA/IHVuZGVmaW5lZCA6IHRoaXMub25LZXlEb3duXG4gICAgICAgIH1cbiAgICAgID5cbiAgICAgICAgPEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0LlByb3ZpZGVyXG4gICAgICAgICAgdmFsdWU9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlfVxuICAgICAgICA+XG4gICAgICAgICAgPElzTW9iaWxlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dGhpcy5pc01vYmlsZX0+XG4gICAgICAgICAgICA8TGF5ZXJVSVxuICAgICAgICAgICAgICBjYW52YXM9e3RoaXMuY2FudmFzfVxuICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgZmlsZXM9e3RoaXMuZmlsZXN9XG4gICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICBhY3Rpb25NYW5hZ2VyPXt0aGlzLmFjdGlvbk1hbmFnZXJ9XG4gICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgIG9uQ29sbGFiQnV0dG9uQ2xpY2s9e29uQ29sbGFiQnV0dG9uQ2xpY2t9XG4gICAgICAgICAgICAgIG9uTG9ja1RvZ2dsZT17dGhpcy50b2dnbGVMb2NrfVxuICAgICAgICAgICAgICBvbkluc2VydEVsZW1lbnRzPXsoZWxlbWVudHMpID0+XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgICAgICAgZmlsZXM6IG51bGwsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZD17emVuTW9kZUVuYWJsZWR9XG4gICAgICAgICAgICAgIHRvZ2dsZVplbk1vZGU9e3RoaXMudG9nZ2xlWmVuTW9kZX1cbiAgICAgICAgICAgICAgbGFuZ0NvZGU9e2dldExhbmd1YWdlKCkuY29kZX1cbiAgICAgICAgICAgICAgaXNDb2xsYWJvcmF0aW5nPXt0aGlzLnByb3BzLmlzQ29sbGFib3JhdGluZyB8fCBmYWxzZX1cbiAgICAgICAgICAgICAgcmVuZGVyVG9wUmlnaHRVST17cmVuZGVyVG9wUmlnaHRVSX1cbiAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tRm9vdGVyPXtyZW5kZXJGb290ZXJ9XG4gICAgICAgICAgICAgIHZpZXdNb2RlRW5hYmxlZD17dmlld01vZGVFbmFibGVkfVxuICAgICAgICAgICAgICBzaG93RXhpdFplbk1vZGVCdG49e1xuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2hvd1RoZW1lQnRuPXtcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcz8udGhlbWUgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLlVJT3B0aW9ucy5jYW52YXNBY3Rpb25zLnRoZW1lXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGlicmFyeVJldHVyblVybD17dGhpcy5wcm9wcy5saWJyYXJ5UmV0dXJuVXJsfVxuICAgICAgICAgICAgICBVSU9wdGlvbnM9e3RoaXMucHJvcHMuVUlPcHRpb25zfVxuICAgICAgICAgICAgICBmb2N1c0NvbnRhaW5lcj17dGhpcy5mb2N1c0NvbnRhaW5lcn1cbiAgICAgICAgICAgICAgbGlicmFyeT17dGhpcy5saWJyYXJ5fVxuICAgICAgICAgICAgICBpZD17dGhpcy5pZH1cbiAgICAgICAgICAgICAgb25JbWFnZUFjdGlvbj17dGhpcy5vbkltYWdlQWN0aW9ufVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZXhjYWxpZHJhdy1jb250ZXh0TWVudUNvbnRhaW5lclwiIC8+XG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS5zaG93U3RhdHMgJiYgKFxuICAgICAgICAgICAgICA8U3RhdHNcbiAgICAgICAgICAgICAgICBhcHBTdGF0ZT17dGhpcy5zdGF0ZX1cbiAgICAgICAgICAgICAgICBzZXRBcHBTdGF0ZT17dGhpcy5zZXRBcHBTdGF0ZX1cbiAgICAgICAgICAgICAgICBlbGVtZW50cz17dGhpcy5zY2VuZS5nZXRFbGVtZW50cygpfVxuICAgICAgICAgICAgICAgIG9uQ2xvc2U9e3RoaXMudG9nZ2xlU3RhdHN9XG4gICAgICAgICAgICAgICAgcmVuZGVyQ3VzdG9tU3RhdHM9e3JlbmRlckN1c3RvbVN0YXRzfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnRvYXN0TWVzc2FnZSAhPT0gbnVsbCAmJiAoXG4gICAgICAgICAgICAgIDxUb2FzdFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U9e3RoaXMuc3RhdGUudG9hc3RNZXNzYWdlfVxuICAgICAgICAgICAgICAgIGNsZWFyVG9hc3Q9e3RoaXMuY2xlYXJUb2FzdH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8bWFpbj57dGhpcy5yZW5kZXJDYW52YXMoKX08L21haW4+XG4gICAgICAgICAgPC9Jc01vYmlsZUNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvRXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGZvY3VzQ29udGFpbmVyOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJmb2N1c0NvbnRhaW5lclwiXSA9ICgpID0+IHtcbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gIH07XG5cbiAgcHVibGljIGdldFNjZW5lRWxlbWVudHMgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgfTtcblxuICBwcml2YXRlIHN5bmNBY3Rpb25SZXN1bHQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGFjdGlvblJlc3VsdDogQWN0aW9uUmVzdWx0KSA9PiB7XG4gICAgICBpZiAodGhpcy51bm1vdW50ZWQgfHwgYWN0aW9uUmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBlZGl0aW5nRWxlbWVudDogQXBwU3RhdGVbXCJlZGl0aW5nRWxlbWVudFwiXSB8IG51bGwgPSBudWxsO1xuICAgICAgaWYgKGFjdGlvblJlc3VsdC5lbGVtZW50cykge1xuICAgICAgICBhY3Rpb25SZXN1bHQuZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQ/LmlkID09PSBlbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50ICE9PSBlbGVtZW50ICYmXG4gICAgICAgICAgICBpc05vbkRlbGV0ZWRFbGVtZW50KGVsZW1lbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBlZGl0aW5nRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKTtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGFjdGlvblJlc3VsdC5maWxlcykge1xuICAgICAgICB0aGlzLmZpbGVzID0gYWN0aW9uUmVzdWx0LnJlcGxhY2VGaWxlc1xuICAgICAgICAgID8gYWN0aW9uUmVzdWx0LmZpbGVzXG4gICAgICAgICAgOiB7IC4uLnRoaXMuZmlsZXMsIC4uLmFjdGlvblJlc3VsdC5maWxlcyB9O1xuICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IGVkaXRpbmdFbGVtZW50KSB7XG4gICAgICAgIGlmIChhY3Rpb25SZXN1bHQuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZpZXdNb2RlRW5hYmxlZCA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnZpZXdNb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IHplbk1vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uemVuTW9kZUVuYWJsZWQgfHwgZmFsc2U7XG4gICAgICAgIGxldCBncmlkU2l6ZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LmdyaWRTaXplIHx8IG51bGw7XG4gICAgICAgIGxldCB0aGVtZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/LnRoZW1lIHx8IFRIRU1FLkxJR0hUO1xuICAgICAgICBsZXQgbmFtZSA9IGFjdGlvblJlc3VsdD8uYXBwU3RhdGU/Lm5hbWUgPz8gdGhpcy5zdGF0ZS5uYW1lO1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdmlld01vZGVFbmFibGVkID0gdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCA9IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgZ3JpZFNpemUgPSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMudGhlbWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB0aGVtZSA9IHRoaXMucHJvcHMudGhlbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJvcHMubmFtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIG5hbWUgPSB0aGlzLnByb3BzLm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIC8vIHVzaW5nIE9iamVjdC5hc3NpZ24gaW5zdGVhZCBvZiBzcHJlYWQgdG8gZm9vbCBUUyA0LjIuMisgaW50b1xuICAgICAgICAgICAgLy8gcmVnYXJkaW5nIHRoZSByZXN1bHRpbmcgdHlwZSBhcyBub3QgY29udGFpbmluZyB1bmRlZmluZWRcbiAgICAgICAgICAgIC8vICh3aGljaCB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb24gd2lsbCBuZXZlciBjb250YWluKVxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oYWN0aW9uUmVzdWx0LmFwcFN0YXRlIHx8IHt9LCB7XG4gICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OlxuICAgICAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50IHx8IGFjdGlvblJlc3VsdC5hcHBTdGF0ZT8uZWRpdGluZ0VsZW1lbnQgfHwgbnVsbCxcbiAgICAgICAgICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgICAgICAgICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgICAgICAgICAgZ3JpZFNpemUsXG4gICAgICAgICAgICAgIHRoZW1lLFxuICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LnN5bmNIaXN0b3J5KSB7XG4gICAgICAgICAgICAgIHRoaXMuaGlzdG9yeS5zZXRDdXJyZW50U3RhdGUoXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICAvLyBMaWZlY3ljbGVcblxuICBwcml2YXRlIG9uQmx1ciA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgaXNIb2xkaW5nU3BhY2UgPSBmYWxzZTtcbiAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogdHJ1ZSB9KTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBvblVubG9hZCA9ICgpID0+IHtcbiAgICB0aGlzLm9uQmx1cigpO1xuICB9O1xuXG4gIHByaXZhdGUgZGlzYWJsZUV2ZW50OiBFdmVudExpc3RlbmVyID0gKGV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfTtcblxuICBwcml2YXRlIG9uRm9udExvYWRlZCA9ICgpID0+IHtcbiAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChpc1RleHRFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vblNjZW5lVXBkYXRlZCgpO1xuICB9O1xuXG4gIHByaXZhdGUgaW1wb3J0TGlicmFyeUZyb21VcmwgPSBhc3luYyAodXJsOiBzdHJpbmcsIHRva2VuPzogc3RyaW5nIHwgbnVsbCkgPT4ge1xuICAgIGlmICh3aW5kb3cubG9jYXRpb24uaGFzaC5pbmNsdWRlcyhVUkxfSEFTSF9LRVlTLmFkZExpYnJhcnkpKSB7XG4gICAgICBjb25zdCBoYXNoID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uaGFzaC5zbGljZSgxKSk7XG4gICAgICBoYXNoLmRlbGV0ZShVUkxfSEFTSF9LRVlTLmFkZExpYnJhcnkpO1xuICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCBBUFBfTkFNRSwgYCMke2hhc2gudG9TdHJpbmcoKX1gKTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5jbHVkZXMoVVJMX1FVRVJZX0tFWVMuYWRkTGlicmFyeSkpIHtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcbiAgICAgIHF1ZXJ5LmRlbGV0ZShVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5KTtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwgQVBQX05BTUUsIGA/JHtxdWVyeS50b1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gYXdhaXQgZmV0Y2goZGVjb2RlVVJJQ29tcG9uZW50KHVybCkpO1xuICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IHJlcXVlc3QuYmxvYigpO1xuICAgICAgY29uc3QganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgYmxvYi50ZXh0KCkpO1xuICAgICAgaWYgKCFpc1ZhbGlkTGlicmFyeShqc29uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdG9rZW4gPT09IHRoaXMuaWQgfHxcbiAgICAgICAgd2luZG93LmNvbmZpcm0oXG4gICAgICAgICAgdChcImFsZXJ0cy5jb25maXJtQWRkTGlicmFyeVwiLCB7XG4gICAgICAgICAgICBudW1TaGFwZXM6IChqc29uLmxpYnJhcnlJdGVtcyB8fCBqc29uLmxpYnJhcnkgfHwgW10pLmxlbmd0aCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubGlicmFyeS5pbXBvcnRMaWJyYXJ5KGJsb2IsIFwicHVibGlzaGVkXCIpO1xuICAgICAgICAvLyBoYWNrIHRvIHJlcmVuZGVyIHRoZSBsaWJyYXJ5IGl0ZW1zIGFmdGVyIGltcG9ydFxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIHdpbmRvdy5hbGVydCh0KFwiYWxlcnRzLmVycm9yTG9hZGluZ0xpYnJhcnlcIikpO1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldEhpc3RvcnkgPSAoKSA9PiB7XG4gICAgdGhpcy5oaXN0b3J5LmNsZWFyKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBzY2VuZSAmIGhpc3RvcnkuXG4gICAqICEgRG8gbm90IHVzZSB0byBjbGVhciBzY2VuZSB1c2VyIGFjdGlvbiAhXG4gICAqL1xuICBwcml2YXRlIHJlc2V0U2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKG9wdHM/OiB7IHJlc2V0TG9hZGluZ1N0YXRlOiBib29sZWFuIH0pID0+IHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAuLi5nZXREZWZhdWx0QXBwU3RhdGUoKSxcbiAgICAgICAgaXNMb2FkaW5nOiBvcHRzPy5yZXNldExvYWRpbmdTdGF0ZSA/IGZhbHNlIDogc3RhdGUuaXNMb2FkaW5nLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGluaXRpYWxpemVTY2VuZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAoXCJsYXVuY2hRdWV1ZVwiIGluIHdpbmRvdyAmJiBcIkxhdW5jaFBhcmFtc1wiIGluIHdpbmRvdykge1xuICAgICAgKHdpbmRvdyBhcyBhbnkpLmxhdW5jaFF1ZXVlLnNldENvbnN1bWVyKFxuICAgICAgICBhc3luYyAobGF1bmNoUGFyYW1zOiB7IGZpbGVzOiBhbnlbXSB9KSA9PiB7XG4gICAgICAgICAgaWYgKCFsYXVuY2hQYXJhbXMuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbGVIYW5kbGUgPSBsYXVuY2hQYXJhbXMuZmlsZXNbMF07XG4gICAgICAgICAgY29uc3QgYmxvYjogQmxvYiA9IGF3YWl0IGZpbGVIYW5kbGUuZ2V0RmlsZSgpO1xuICAgICAgICAgIGJsb2IuaGFuZGxlID0gZmlsZUhhbmRsZTtcbiAgICAgICAgICBsb2FkRnJvbUJsb2IoXG4gICAgICAgICAgICBibG9iLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHNjZW5lKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgIH1cbiAgICBsZXQgaW5pdGlhbERhdGEgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBpbml0aWFsRGF0YSA9IChhd2FpdCB0aGlzLnByb3BzLmluaXRpYWxEYXRhKSB8fCBudWxsO1xuICAgICAgaWYgKGluaXRpYWxEYXRhPy5saWJyYXJ5SXRlbXMpIHtcbiAgICAgICAgdGhpcy5saWJyYXJ5SXRlbXNGcm9tU3RvcmFnZSA9IHJlc3RvcmVMaWJyYXJ5SXRlbXMoXG4gICAgICAgICAgaW5pdGlhbERhdGEubGlicmFyeUl0ZW1zLFxuICAgICAgICAgIFwidW5wdWJsaXNoZWRcIixcbiAgICAgICAgKSBhcyBMaWJyYXJ5SXRlbXM7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICBpbml0aWFsRGF0YSA9IHtcbiAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2U6XG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8XG4gICAgICAgICAgICBcIkVuY291bnRlcmVkIGFuIGVycm9yIGR1cmluZyBpbXBvcnRpbmcgb3IgcmVzdG9yaW5nIHNjZW5lIGRhdGFcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc2NlbmUgPSByZXN0b3JlKGluaXRpYWxEYXRhLCBudWxsLCBudWxsKTtcblxuICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICBlbGVtZW50VHlwZTpcbiAgICAgICAgc2NlbmUuYXBwU3RhdGUuZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIlxuICAgICAgICAgID8gXCJzZWxlY3Rpb25cIlxuICAgICAgICAgIDogc2NlbmUuYXBwU3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gICAgaWYgKGluaXRpYWxEYXRhPy5zY3JvbGxUb0NvbnRlbnQpIHtcbiAgICAgIHNjZW5lLmFwcFN0YXRlID0ge1xuICAgICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICAgIHNjZW5lLmVsZW1lbnRzLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaGVpZ2h0LFxuICAgICAgICAgICAgb2Zmc2V0VG9wOiB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgICAgIG9mZnNldExlZnQ6IHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgIC4uLnNjZW5lLFxuICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbGlicmFyeVVybCA9XG4gICAgICAvLyBjdXJyZW50XG4gICAgICBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpKS5nZXQoXG4gICAgICAgIFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSxcbiAgICAgICkgfHxcbiAgICAgIC8vIGxlZ2FjeSwga2VwdCBmb3IgY29tcGF0IHJlYXNvbnNcbiAgICAgIG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KFxuICAgICAgICBVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5LFxuICAgICAgKTtcblxuICAgIGlmIChsaWJyYXJ5VXJsKSB7XG4gICAgICBhd2FpdCB0aGlzLmltcG9ydExpYnJhcnlGcm9tVXJsKGxpYnJhcnlVcmwpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgYXN5bmMgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUuY29udGFpbmVyID1cbiAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4gICAgKSB7XG4gICAgICBjb25zdCBzZXRTdGF0ZSA9IHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdy5oLCB7XG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2V0U3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgdmFsdWU6ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBzZXRTdGF0ZT4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFN0YXRlKC4uLmFyZ3MpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFwcDoge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcyxcbiAgICAgICAgfSxcbiAgICAgICAgaGlzdG9yeToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5oaXN0b3J5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zY2VuZS5hZGRDYWxsYmFjayh0aGlzLm9uU2NlbmVVcGRhdGVkKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXNDb250YWluZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdyAmJiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAvLyBjb21wdXRlIGlzTW9iaWxlIHN0YXRlXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9XG4gICAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB0aGlzLmlzTW9iaWxlID1cbiAgICAgICAgICB3aWR0aCA8IE1RX01BWF9XSURUSF9QT1JUUkFJVCB8fFxuICAgICAgICAgIChoZWlnaHQgPCBNUV9NQVhfSEVJR0hUX0xBTkRTQ0FQRSAmJiB3aWR0aCA8IE1RX01BWF9XSURUSF9MQU5EU0NBUEUpO1xuICAgICAgICAvLyByZWZyZXNoIG9mZnNldHNcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5vYnNlcnZlKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50KTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICBjb25zdCBtZWRpYVF1ZXJ5ID0gd2luZG93Lm1hdGNoTWVkaWEoXG4gICAgICAgIGAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9QT1JUUkFJVH1weCksIChtYXgtaGVpZ2h0OiAke01RX01BWF9IRUlHSFRfTEFORFNDQVBFfXB4KSBhbmQgKG1heC13aWR0aDogJHtNUV9NQVhfV0lEVEhfTEFORFNDQVBFfXB4KWAsXG4gICAgICApO1xuICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+ICh0aGlzLmlzTW9iaWxlID0gbWVkaWFRdWVyeS5tYXRjaGVzKTtcbiAgICAgIG1lZGlhUXVlcnkuYWRkTGlzdGVuZXIoaGFuZGxlcik7XG4gICAgICB0aGlzLmRldGFjaElzTW9iaWxlTXFIYW5kbGVyID0gKCkgPT4gbWVkaWFRdWVyeS5yZW1vdmVMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc2xpY2UoMSkpO1xuXG4gICAgaWYgKHNlYXJjaFBhcmFtcy5oYXMoXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpKSB7XG4gICAgICAvLyBPYnRhaW4gYSBmaWxlIHRoYXQgd2FzIHNoYXJlZCB2aWEgdGhlIFdlYiBTaGFyZSBUYXJnZXQgQVBJLlxuICAgICAgdGhpcy5yZXN0b3JlRmlsZUZyb21TaGFyZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURPTVJlY3QodGhpcy5pbml0aWFsaXplU2NlbmUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLmZpbGVzID0ge307XG4gICAgdGhpcy5pbWFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMudW5tb3VudGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zY2VuZS5kZXN0cm95KCk7XG4gICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgfVxuXG4gIHByaXZhdGUgb25SZXNpemUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgIHRoaXMuc2NlbmVcbiAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9KTtcblxuICBwcml2YXRlIHJlbW92ZUV2ZW50TGlzdGVuZXJzKCkge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgdGhpcy5yZW1vdmVQb2ludGVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNPUFksIHRoaXMub25Db3B5KTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5NT1VTRV9NT1ZFLFxuICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIHRoaXMub25LZXlVcCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5EUkFHX09WRVIsIHRoaXMuZGlzYWJsZUV2ZW50LCBmYWxzZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuRFJPUCwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcblxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcblxuICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXI/LigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpOyAvLyAjMzU1M1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGlmICh0aGlzLnByb3BzLmhhbmRsZUtleWJvYXJkR2xvYmFsbHkpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZRE9XTiwgdGhpcy5vbktleURvd24sIGZhbHNlKTtcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwLCB7IHBhc3NpdmU6IHRydWUgfSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICApO1xuICAgIC8vIHJlcmVuZGVyIHRleHQgZWxlbWVudHMgb24gZm9udCBsb2FkIHRvIGZpeCAjNjM3ICYmICMxNTUzXG4gICAgZG9jdW1lbnQuZm9udHM/LmFkZEV2ZW50TGlzdGVuZXI/LihcImxvYWRpbmdkb25lXCIsIHRoaXMub25Gb250TG9hZGVkKTtcbiAgICAvLyBTYWZhcmktb25seSBkZXNrdG9wIHBpbmNoIHpvb21cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9TVEFSVCxcbiAgICAgIHRoaXMub25HZXN0dXJlU3RhcnQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9DSEFOR0UsXG4gICAgICB0aGlzLm9uR2VzdHVyZUNoYW5nZSBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0VORCxcbiAgICAgIHRoaXMub25HZXN0dXJlRW5kIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQ1VULCB0aGlzLm9uQ3V0KTtcbiAgICBpZiAodGhpcy5wcm9wcy5kZXRlY3RTY3JvbGwpIHtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIgPSBnZXROZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcihcbiAgICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgKTtcbiAgICAgIHRoaXMubmVhcmVzdFNjcm9sbGFibGVDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuU0NST0xMLFxuICAgICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICAgKTtcbiAgICB9XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUkVTSVpFLCB0aGlzLm9uUmVzaXplLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVU5MT0FELCB0aGlzLm9uVW5sb2FkLCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGhpcy5vbkJsdXIsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5EUkFHX09WRVIsIHRoaXMuZGlzYWJsZUV2ZW50LCBmYWxzZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuRFJPUCwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgfVxuXG4gIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IEFwcFByb3BzLCBwcmV2U3RhdGU6IEFwcFN0YXRlKSB7XG4gICAgaWYgKHByZXZQcm9wcy5sYW5nQ29kZSAhPT0gdGhpcy5wcm9wcy5sYW5nQ29kZSkge1xuICAgICAgdGhpcy51cGRhdGVMYW5ndWFnZSgpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZpZXdNb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCB9KTtcbiAgICB9XG5cbiAgICBpZiAocHJldlN0YXRlLnZpZXdNb2RlRW5hYmxlZCAhPT0gdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuemVuTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyB6ZW5Nb2RlRW5hYmxlZDogISF0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMudGhlbWUgIT09IHRoaXMucHJvcHMudGhlbWUgJiYgdGhpcy5wcm9wcy50aGVtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRoZW1lOiB0aGlzLnByb3BzLnRoZW1lIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2UHJvcHMuZ3JpZE1vZGVFbmFibGVkICE9PSB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGdyaWRTaXplOiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA/IEdSSURfU0laRSA6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy5uYW1lICYmIHByZXZQcm9wcy5uYW1lICE9PSB0aGlzLnByb3BzLm5hbWUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBuYW1lOiB0aGlzLnByb3BzLm5hbWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY2xhc3NMaXN0LnRvZ2dsZShcbiAgICAgIFwidGhlbWUtLWRhcmtcIixcbiAgICAgIHRoaXMuc3RhdGUudGhlbWUgPT09IFwiZGFya1wiLFxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWRdXG4gICAgKSB7XG4gICAgICAvLyBkZWZlciBzbyB0aGF0IHRoZSBjb21taXRUb0hpc3RvcnkgZmxhZyBpc24ndCByZXNldCB2aWEgY3VycmVudCB1cGRhdGVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHByZXZTdGF0ZTtcbiAgICBpZiAoXG4gICAgICBwcmV2U3RhdGUuZWxlbWVudFR5cGUgIT09IHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgJiZcbiAgICAgIG11bHRpRWxlbWVudCAhPSBudWxsICYmXG4gICAgICBpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpICYmXG4gICAgICBpc0JpbmRpbmdFbGVtZW50KG11bHRpRWxlbWVudClcbiAgICApIHtcbiAgICAgIG1heWJlQmluZExpbmVhckVsZW1lbnQoXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0UG9pbnRBdEluZGV4R2xvYmFsQ29vcmRpbmF0ZXMoXG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgICAgICAtMSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJzb3JCdXR0b246IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVmlld3BvcnRDb29yZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3Jkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHM6IFJlbmRlckNvbmZpZ1tcInJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1wiXSA9XG4gICAgICB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlcm5hbWVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBjb25zdCBwb2ludGVyVXNlclN0YXRlczogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgdGhpcy5zdGF0ZS5jb2xsYWJvcmF0b3JzLmZvckVhY2goKHVzZXIsIHNvY2tldElkKSA9PiB7XG4gICAgICBpZiAodXNlci5zZWxlY3RlZEVsZW1lbnRJZHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICBpZiAoIShpZCBpbiByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHMpKSB7XG4gICAgICAgICAgICByZW1vdGVTZWxlY3RlZEVsZW1lbnRJZHNbaWRdID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0ucHVzaChzb2NrZXRJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdXNlci5wb2ludGVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICAgIHBvaW50ZXJVc2VybmFtZXNbc29ja2V0SWRdID0gdXNlci51c2VybmFtZTtcbiAgICAgIH1cbiAgICAgIGlmICh1c2VyLnVzZXJTdGF0ZSkge1xuICAgICAgICBwb2ludGVyVXNlclN0YXRlc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHBvaW50ZXJWaWV3cG9ydENvb3Jkc1tzb2NrZXRJZF0gPSBzY2VuZUNvb3Jkc1RvVmlld3BvcnRDb29yZHMoXG4gICAgICAgIHtcbiAgICAgICAgICBzY2VuZVg6IHVzZXIucG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lWTogdXNlci5wb2ludGVyLnksXG4gICAgICAgIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgY3Vyc29yQnV0dG9uW3NvY2tldElkXSA9IHVzZXIuYnV0dG9uO1xuICAgIH0pO1xuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAvLyBub3QgcGxhY2VkIG9uIGNhbnZhcyB5ZXQgKGJ1dCBpbiBlbGVtZW50cyBhcnJheSlcbiAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQgJiZcbiAgICAgICAgICBlbGVtZW50LmlkID09PSB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQuaWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBkb24ndCByZW5kZXIgdGV4dCBlbGVtZW50IHRoYXQncyBiZWluZyBjdXJyZW50bHkgZWRpdGVkIChpdCdzXG4gICAgICAvLyByZW5kZXJlZCBvbiByZW1vdGUgb25seSlcbiAgICAgIHJldHVybiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQudHlwZSAhPT0gXCJ0ZXh0XCIgfHxcbiAgICAgICAgZWxlbWVudC5pZCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC5pZFxuICAgICAgKTtcbiAgICB9KTtcbiAgICBjb25zdCB7IGF0TGVhc3RPbmVWaXNpYmxlRWxlbWVudCwgc2Nyb2xsQmFycyB9ID0gcmVuZGVyU2NlbmUoXG4gICAgICByZW5kZXJpbmdFbGVtZW50cyxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgICB0aGlzLnN0YXRlLnNlbGVjdGlvbkVsZW1lbnQsXG4gICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgIHRoaXMucmMhLFxuICAgICAgdGhpcy5jYW52YXMhLFxuICAgICAge1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFgsXG4gICAgICAgIHNjcm9sbFk6IHRoaXMuc3RhdGUuc2Nyb2xsWSxcbiAgICAgICAgdmlld0JhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS52aWV3QmFja2dyb3VuZENvbG9yLFxuICAgICAgICB6b29tOiB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIHJlbW90ZVBvaW50ZXJWaWV3cG9ydENvb3JkczogcG9pbnRlclZpZXdwb3J0Q29vcmRzLFxuICAgICAgICByZW1vdGVQb2ludGVyQnV0dG9uOiBjdXJzb3JCdXR0b24sXG4gICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJuYW1lczogcG9pbnRlclVzZXJuYW1lcyxcbiAgICAgICAgcmVtb3RlUG9pbnRlclVzZXJTdGF0ZXM6IHBvaW50ZXJVc2VyU3RhdGVzLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRoaXMuc3RhdGUuc2hvdWxkQ2FjaGVJZ25vcmVab29tLFxuICAgICAgICB0aGVtZTogdGhpcy5zdGF0ZS50aGVtZSxcbiAgICAgICAgaW1hZ2VDYWNoZTogdGhpcy5pbWFnZUNhY2hlLFxuICAgICAgICBpc0V4cG9ydGluZzogZmFsc2UsXG4gICAgICAgIHJlbmRlclNjcm9sbGJhcnM6ICF0aGlzLmlzTW9iaWxlLFxuICAgICAgfSxcbiAgICApO1xuICAgIGlmIChzY3JvbGxCYXJzKSB7XG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyA9IHNjcm9sbEJhcnM7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbGVkT3V0c2lkZSA9XG4gICAgICAvLyBoaWRlIHdoZW4gZWRpdGluZyB0ZXh0XG4gICAgICBpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpXG4gICAgICAgID8gZmFsc2VcbiAgICAgICAgOiAhYXRMZWFzdE9uZVZpc2libGVFbGVtZW50ICYmIHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCA+IDA7XG4gICAgaWYgKHRoaXMuc3RhdGUuc2Nyb2xsZWRPdXRzaWRlICE9PSBzY3JvbGxlZE91dHNpZGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzY3JvbGxlZE91dHNpZGUgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5oaXN0b3J5LnJlY29yZCh0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKTtcblxuICAgIHRoaXMuc2NoZWR1bGVJbWFnZVJlZnJlc2goKTtcblxuICAgIC8vIERvIG5vdCBub3RpZnkgY29uc3VtZXJzIGlmIHdlJ3JlIHN0aWxsIGxvYWRpbmcgdGhlIHNjZW5lLiBBbW9uZyBvdGhlclxuICAgIC8vIHBvdGVudGlhbCBpc3N1ZXMsIHRoaXMgZml4ZXMgYSBjYXNlIHdoZXJlIHRoZSB0YWIgaXNuJ3QgZm9jdXNlZCBkdXJpbmdcbiAgICAvLyBpbml0LCB3aGljaCB3b3VsZCB0cmlnZ2VyIG9uQ2hhbmdlIHdpdGggZW1wdHkgZWxlbWVudHMsIHdoaWNoIHdvdWxkIHRoZW5cbiAgICAvLyBvdmVycmlkZSB3aGF0ZXZlciBpcyBpbiBsb2NhbFN0b3JhZ2UgY3VycmVudGx5LlxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMucHJvcHMub25DaGFuZ2U/LihcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5maWxlcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblNjcm9sbCA9IGRlYm91bmNlKCgpID0+IHtcbiAgICBjb25zdCB7IG9mZnNldFRvcCwgb2Zmc2V0TGVmdCB9ID0gdGhpcy5nZXRDYW52YXNPZmZzZXRzKCk7XG4gICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+IHtcbiAgICAgIGlmIChzdGF0ZS5vZmZzZXRMZWZ0ID09PSBvZmZzZXRMZWZ0ICYmIHN0YXRlLm9mZnNldFRvcCA9PT0gb2Zmc2V0VG9wKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH07XG4gICAgfSk7XG4gIH0sIFNDUk9MTF9USU1FT1VUKTtcblxuICAvLyBDb3B5L3Bhc3RlXG5cbiAgcHJpdmF0ZSBvbkN1dCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXRBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9KTtcblxuICBwcml2YXRlIG9uQ29weSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNFeGNhbGlkcmF3QWN0aXZlID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmNvbnRhaW5zKFxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICApO1xuICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlIHx8IGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBjdXRBbGwgPSAoKSA9PiB7XG4gICAgdGhpcy5jb3B5QWxsKCk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRGVsZXRlU2VsZWN0ZWQpO1xuICB9O1xuXG4gIHByaXZhdGUgY29weUFsbCA9ICgpID0+IHtcbiAgICBjb3B5VG9DbGlwYm9hcmQodGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCB0aGlzLnN0YXRlLCB0aGlzLmZpbGVzKTtcbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyByZXNldFRhcFR3aWNlKCkge1xuICAgIGRpZFRhcFR3aWNlID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uVGFwU3RhcnQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICBpZiAoIWRpZFRhcFR3aWNlKSB7XG4gICAgICBkaWRUYXBUd2ljZSA9IHRydWU7XG4gICAgICBjbGVhclRpbWVvdXQodGFwcGVkVHdpY2VUaW1lcik7XG4gICAgICB0YXBwZWRUd2ljZVRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoXG4gICAgICAgIEFwcC5yZXNldFRhcFR3aWNlLFxuICAgICAgICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGluc2VydCB0ZXh0IG9ubHkgaWYgd2UgdGFwcGVkIHR3aWNlIHdpdGggYSBzaW5nbGUgZmluZ2VyXG4gICAgLy8gZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEgd2lsbCBhbHNvIHByZXZlbnQgaW5zZXJ0aW5nIHRleHQgd2hlbiB1c2VyJ3Mgem9vbWluZ1xuICAgIGlmIChkaWRUYXBUd2ljZSAmJiBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgW3RvdWNoXSA9IGV2ZW50LnRvdWNoZXM7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrKHtcbiAgICAgICAgY2xpZW50WDogdG91Y2guY2xpZW50WCxcbiAgICAgICAgY2xpZW50WTogdG91Y2guY2xpZW50WSxcbiAgICAgIH0pO1xuICAgICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgb25UYXBFbmQgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUucHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBwYXN0ZUZyb21DbGlwYm9hcmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgYXN5bmMgKGV2ZW50OiBDbGlwYm9hcmRFdmVudCB8IG51bGwpID0+IHtcbiAgICAgIC8vICM2ODZcbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPVxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnModGFyZ2V0KTtcbiAgICAgIGlmICghaXNFeGNhbGlkcmF3QWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxlbWVudFVuZGVyQ3Vyc29yID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChjdXJzb3JYLCBjdXJzb3JZKTtcbiAgICAgIGlmIChcbiAgICAgICAgLy8gaWYgbm8gQ2xpcGJvYXJkRXZlbnQgc3VwcGxpZWQsIGFzc3VtZSB3ZSdyZSBwYXN0aW5nIHZpYSBjb250ZXh0TWVudVxuICAgICAgICAvLyB0aHVzIHRoZXNlIGNoZWNrcyBkb24ndCBtYWtlIHNlbnNlXG4gICAgICAgIGV2ZW50ICYmXG4gICAgICAgICghKGVsZW1lbnRVbmRlckN1cnNvciBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB8fFxuICAgICAgICAgIGlzV3JpdGFibGVFbGVtZW50KHRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgc2FtZSBmcmFtZSAodGh1cyBiZWZvcmUgYW55IGF3YWl0cykgYXMgdGhlIHBhc3RlXG4gICAgICAvLyBldmVudCBlbHNlIHNvbWUgYnJvd3NlcnMgKEZGLi4uKSB3aWxsIGNsZWFyIHRoZSBjbGlwYm9hcmREYXRhXG4gICAgICAvLyAoc29tZXRoaW5nIHNvbWV0aGluZyBzZWN1cml0eSlcbiAgICAgIGxldCBmaWxlID0gZXZlbnQ/LmNsaXBib2FyZERhdGE/LmZpbGVzWzBdO1xuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcGFyc2VDbGlwYm9hcmQoZXZlbnQpO1xuXG4gICAgICBpZiAoIWZpbGUgJiYgZGF0YS50ZXh0KSB7XG4gICAgICAgIGNvbnN0IHN0cmluZyA9IGRhdGEudGV4dC50cmltKCk7XG4gICAgICAgIGlmIChzdHJpbmcuc3RhcnRzV2l0aChcIjxzdmdcIikgJiYgc3RyaW5nLmVuZHNXaXRoKFwiPC9zdmc+XCIpKSB7XG4gICAgICAgICAgLy8gaWdub3JlIFNWRyB2YWxpZGF0aW9uL25vcm1hbGl6YXRpb24gd2hpY2ggd2lsbCBiZSBkb25lIGR1cmluZyBpbWFnZVxuICAgICAgICAgIC8vIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAgZmlsZSA9IFNWR1N0cmluZ1RvRmlsZShzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucHJvcHMub25QYXN0ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICgoYXdhaXQgdGhpcy5wcm9wcy5vblBhc3RlKGRhdGEsIGV2ZW50KSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkYXRhLmVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBkYXRhLmVycm9yTWVzc2FnZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS5zcHJlYWRzaGVldCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBwYXN0ZURpYWxvZzoge1xuICAgICAgICAgICAgZGF0YTogZGF0YS5zcHJlYWRzaGVldCxcbiAgICAgICAgICAgIHNob3duOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHNGcm9tUGFzdGVPckxpYnJhcnkoe1xuICAgICAgICAgIGVsZW1lbnRzOiBkYXRhLmVsZW1lbnRzLFxuICAgICAgICAgIGZpbGVzOiBkYXRhLmZpbGVzIHx8IG51bGwsXG4gICAgICAgICAgcG9zaXRpb246IFwiY3Vyc29yXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnRleHQpIHtcbiAgICAgICAgdGhpcy5hZGRUZXh0RnJvbVBhc3RlKGRhdGEudGV4dCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChcInNlbGVjdGlvblwiKTtcbiAgICAgIGV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBhZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSA9IChvcHRzOiB7XG4gICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgZmlsZXM6IEJpbmFyeUZpbGVzIHwgbnVsbDtcbiAgICBwb3NpdGlvbjogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHwgXCJjdXJzb3JcIiB8IFwiY2VudGVyXCI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHJlc3RvcmVFbGVtZW50cyhvcHRzLmVsZW1lbnRzLCBudWxsKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoZWxlbWVudHMpO1xuXG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJYID0gZGlzdGFuY2UobWluWCwgbWF4WCkgLyAyO1xuICAgIGNvbnN0IGVsZW1lbnRzQ2VudGVyWSA9IGRpc3RhbmNlKG1pblksIG1heFkpIC8gMjtcblxuICAgIGNvbnN0IGNsaWVudFggPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFhcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWFxuICAgICAgICA6IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgIGNvbnN0IGNsaWVudFkgPVxuICAgICAgdHlwZW9mIG9wdHMucG9zaXRpb24gPT09IFwib2JqZWN0XCJcbiAgICAgICAgPyBvcHRzLnBvc2l0aW9uLmNsaWVudFlcbiAgICAgICAgOiBvcHRzLnBvc2l0aW9uID09PSBcImN1cnNvclwiXG4gICAgICAgID8gY3Vyc29yWVxuICAgICAgICA6IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGR4ID0geCAtIGVsZW1lbnRzQ2VudGVyWDtcbiAgICBjb25zdCBkeSA9IHkgLSBlbGVtZW50c0NlbnRlclk7XG4gICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcblxuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KGR4LCBkeSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBvbGRJZFRvRHVwbGljYXRlZElkID0gbmV3IE1hcCgpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnRzID0gZWxlbWVudHMubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBuZXdFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCxcbiAgICAgICAgZ3JvdXBJZE1hcCxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCArIGdyaWRYIC0gbWluWCxcbiAgICAgICAgICB5OiBlbGVtZW50LnkgKyBncmlkWSAtIG1pblksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZC5zZXQoZWxlbWVudC5pZCwgbmV3RWxlbWVudC5pZCk7XG4gICAgICByZXR1cm4gbmV3RWxlbWVudDtcbiAgICB9KTtcbiAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKG5ld0VsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG4gICAgY29uc3QgbmV4dEVsZW1lbnRzID0gW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIC4uLm5ld0VsZW1lbnRzLFxuICAgIF07XG4gICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKG5leHRFbGVtZW50cywgZWxlbWVudHMsIG9sZElkVG9EdXBsaWNhdGVkSWQpO1xuXG4gICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLm9wdHMuZmlsZXMgfTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhuZXh0RWxlbWVudHMpO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAge1xuICAgICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgICAgaXNMaWJyYXJ5T3BlbjogZmFsc2UsXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiBuZXdFbGVtZW50cy5yZWR1Y2UoKG1hcCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuY29udGFpbmVySWQpIHtcbiAgICAgICAgICAgICAgbWFwW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXA7XG4gICAgICAgICAgfSwge30gYXMgYW55KSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgKSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKG9wdHMuZmlsZXMpIHtcbiAgICAgICAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gICAgdGhpcy5zZWxlY3RTaGFwZVRvb2woXCJzZWxlY3Rpb25cIik7XG4gIH07XG5cbiAgcHJpdmF0ZSBhZGRUZXh0RnJvbVBhc3RlKHRleHQ6IGFueSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiBjdXJzb3JYLCBjbGllbnRZOiBjdXJzb3JZIH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3VGV4dEVsZW1lbnQoe1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHRleHQsXG4gICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICB0ZXh0QWxpZ246IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGVsZW1lbnQsXG4gICAgXSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbZWxlbWVudC5pZF06IHRydWUgfSB9KTtcbiAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gIH1cblxuICAvLyBDb2xsYWJvcmF0aW9uXG5cbiAgc2V0QXBwU3RhdGUgPSAob2JqOiBhbnkpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKG9iaik7XG4gIH07XG5cbiAgcmVtb3ZlUG9pbnRlciA9IChldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxFbGVtZW50PiB8IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgIC8vIHJlbW92ZSB0b3VjaCBoYW5kbGVyIGZvciBjb250ZXh0IG1lbnUgb24gdG91Y2ggZGV2aWNlc1xuICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiICYmIHRvdWNoVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRvdWNoVGltZW91dCk7XG4gICAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZ2VzdHVyZS5wb2ludGVycy5kZWxldGUoZXZlbnQucG9pbnRlcklkKTtcbiAgfTtcblxuICB0b2dnbGVMb2NrID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWxlbWVudExvY2tlZDogIXByZXZTdGF0ZS5lbGVtZW50TG9ja2VkLFxuICAgICAgICBlbGVtZW50VHlwZTogcHJldlN0YXRlLmVsZW1lbnRMb2NrZWRcbiAgICAgICAgICA/IFwic2VsZWN0aW9uXCJcbiAgICAgICAgICA6IHByZXZTdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH07XG5cbiAgdG9nZ2xlWmVuTW9kZSA9ICgpID0+IHtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25Ub2dnbGVaZW5Nb2RlKTtcbiAgfTtcblxuICB0b2dnbGVTdGF0cyA9ICgpID0+IHtcbiAgICBpZiAoIXRoaXMuc3RhdGUuc2hvd1N0YXRzKSB7XG4gICAgICB0cmFja0V2ZW50KFwiZGlhbG9nXCIsIFwic3RhdHNcIik7XG4gICAgfVxuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvblRvZ2dsZVN0YXRzKTtcbiAgfTtcblxuICBzY3JvbGxUb0NvbnRlbnQgPSAoXG4gICAgdGFyZ2V0OlxuICAgICAgfCBFeGNhbGlkcmF3RWxlbWVudFxuICAgICAgfCByZWFkb25seSBFeGNhbGlkcmF3RWxlbWVudFtdID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICApID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC4uLmNhbGN1bGF0ZVNjcm9sbENlbnRlcihcbiAgICAgICAgQXJyYXkuaXNBcnJheSh0YXJnZXQpID8gdGFyZ2V0IDogW3RhcmdldF0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgKSxcbiAgICB9KTtcbiAgfTtcblxuICBjbGVhclRvYXN0ID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyB0b2FzdE1lc3NhZ2U6IG51bGwgfSk7XG4gIH07XG5cbiAgc2V0VG9hc3RNZXNzYWdlID0gKHRvYXN0TWVzc2FnZTogc3RyaW5nKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0TWVzc2FnZSB9KTtcbiAgfTtcblxuICByZXN0b3JlRmlsZUZyb21TaGFyZSA9IGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgd2ViU2hhcmVUYXJnZXRDYWNoZSA9IGF3YWl0IGNhY2hlcy5vcGVuKFwid2ViLXNoYXJlLXRhcmdldFwiKTtcblxuICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUubWF0Y2goXCJzaGFyZWQtZmlsZVwiKTtcbiAgICAgIGlmIChmaWxlKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCBmaWxlLmJsb2IoKTtcbiAgICAgICAgdGhpcy5sb2FkRmlsZVRvQ2FudmFzKGJsb2IpO1xuICAgICAgICBhd2FpdCB3ZWJTaGFyZVRhcmdldENhY2hlLmRlbGV0ZShcInNoYXJlZC1maWxlXCIpO1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgQVBQX05BTUUsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIGFkZHMgc3VwcGxpZWQgZmlsZXMgdG8gZXhpc3RpbmcgZmlsZXMgaW4gdGhlIGFwcFN0YXRlICovXG4gIHB1YmxpYyBhZGRGaWxlczogRXhjYWxpZHJhd0ltcGVyYXRpdmVBUElbXCJhZGRGaWxlc1wiXSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZmlsZXMpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVzTWFwID0gZmlsZXMucmVkdWNlKChhY2MsIGZpbGVEYXRhKSA9PiB7XG4gICAgICAgIGFjYy5zZXQoZmlsZURhdGEuaWQsIGZpbGVEYXRhKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIG5ldyBNYXA8RmlsZUlkLCBCaW5hcnlGaWxlRGF0YT4oKSk7XG5cbiAgICAgIHRoaXMuZmlsZXMgPSB7IC4uLnRoaXMuZmlsZXMsIC4uLk9iamVjdC5mcm9tRW50cmllcyhmaWxlc01hcCkgfTtcblxuICAgICAgLy8gYnVtcCB2ZXJzaW9ucyBmb3IgZWxlbWVudHMgdGhhdCByZWZlcmVuY2UgYWRkZWQgZmlsZXMgc28gdGhhdFxuICAgICAgLy8gd2UvaG9zdCBhcHBzIGNhbiBkZXRlY3QgdGhlIGNoYW5nZSwgYW5kIGludmFsaWRhdGUgdGhlIGltYWdlICYgc2hhcGVcbiAgICAgIC8vIGNhY2hlXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChlbGVtZW50KSAmJlxuICAgICAgICAgIGZpbGVzTWFwLmhhcyhlbGVtZW50LmZpbGVJZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5pbWFnZUNhY2hlLmRlbGV0ZShlbGVtZW50LmZpbGVJZCk7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICBidW1wVmVyc2lvbihlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG5cbiAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgfSxcbiAgKTtcblxuICBwdWJsaWMgdXBkYXRlU2NlbmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgPEsgZXh0ZW5kcyBrZXlvZiBBcHBTdGF0ZT4oc2NlbmVEYXRhOiB7XG4gICAgICBlbGVtZW50cz86IFNjZW5lRGF0YVtcImVsZW1lbnRzXCJdO1xuICAgICAgYXBwU3RhdGU/OiBQaWNrPEFwcFN0YXRlLCBLPiB8IG51bGw7XG4gICAgICBjb2xsYWJvcmF0b3JzPzogU2NlbmVEYXRhW1wiY29sbGFib3JhdG9yc1wiXTtcbiAgICAgIGNvbW1pdFRvSGlzdG9yeT86IFNjZW5lRGF0YVtcImNvbW1pdFRvSGlzdG9yeVwiXTtcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoc2NlbmVEYXRhLmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuYXBwU3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShzY2VuZURhdGEuYXBwU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NlbmVEYXRhLmVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKHNjZW5lRGF0YS5lbGVtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuY29sbGFib3JhdG9ycykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29sbGFib3JhdG9yczogc2NlbmVEYXRhLmNvbGxhYm9yYXRvcnMgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uU2NlbmVVcGRhdGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe30pO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgY3Vyc29yWCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjdXJzb3JZID0gZXZlbnQuY2xpZW50WTtcbiAgICB9LFxuICApO1xuXG4gIC8vIElucHV0IGhhbmRsaW5nXG5cbiAgcHJpdmF0ZSBvbktleURvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBSZWFjdC5LZXlib2FyZEV2ZW50IHwgS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gbm9ybWFsaXplIGBldmVudC5rZXlgIHdoZW4gQ2Fwc0xvY2sgaXMgcHJlc3NlZCAjMjM3MlxuICAgICAgaWYgKFxuICAgICAgICBcIlByb3h5XCIgaW4gd2luZG93ICYmXG4gICAgICAgICgoIWV2ZW50LnNoaWZ0S2V5ICYmIC9eW0EtWl0kLy50ZXN0KGV2ZW50LmtleSkpIHx8XG4gICAgICAgICAgKGV2ZW50LnNoaWZ0S2V5ICYmIC9eW2Etel0kLy50ZXN0KGV2ZW50LmtleSkpKVxuICAgICAgKSB7XG4gICAgICAgIGV2ZW50ID0gbmV3IFByb3h5KGV2ZW50LCB7XG4gICAgICAgICAgZ2V0KGV2OiBhbnksIHByb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXZbcHJvcF07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgLy8gZml4IGZvciBQcm94aWVzIGhpamFja2luZyBgdGhpc2BcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmJpbmQoZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb3AgPT09IFwia2V5XCJcbiAgICAgICAgICAgICAgPyAvLyBDYXBzTG9jayBpbnZlcnRzIGNhcGl0YWxpemF0aW9uIGJhc2VkIG9uIFNoaWZ0S2V5LCBzbyBpbnZlcnRcbiAgICAgICAgICAgICAgICAvLyBpdCBiYWNrXG4gICAgICAgICAgICAgICAgZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgICA/IGV2LmtleS50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICAgICAgOiBldi5rZXkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICA6IHZhbHVlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIChpc1dyaXRhYmxlRWxlbWVudChldmVudC50YXJnZXQpICYmIGV2ZW50LmtleSAhPT0gS0VZUy5FU0NBUEUpIHx8XG4gICAgICAgIC8vIGNhc2U6IHVzaW5nIGFycm93cyB0byBtb3ZlIGJldHdlZW4gYnV0dG9uc1xuICAgICAgICAoaXNBcnJvd0tleShldmVudC5rZXkpICYmIGlzSW5wdXRMaWtlKGV2ZW50LnRhcmdldCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlFVRVNUSU9OX01BUkspIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2hvd0hlbHBEaWFsb2c6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hY3Rpb25NYW5hZ2VyLmhhbmRsZUtleURvd24oZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmIHRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5jb2RlID09PSBDT0RFUy5aRVJPKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiAhdGhpcy5zdGF0ZS5pc0xpYnJhcnlPcGVuIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAgICh0aGlzLnN0YXRlLmdyaWRTaXplICYmXG4gICAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgICAgPyBFTEVNRU5UX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmdyaWRTaXplKSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXlcbiAgICAgICAgICAgID8gRUxFTUVOVF9TSElGVF9UUkFOU0xBVEVfQU1PVU5UXG4gICAgICAgICAgICA6IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IHRoaXMuc2NlbmVcbiAgICAgICAgICAuZ2V0RWxlbWVudHMoKVxuICAgICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2VsZW1lbnQuaWRdKTtcblxuICAgICAgICBsZXQgb2Zmc2V0WCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXRZID0gMDtcblxuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0xFRlQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1JJR0hUKSB7XG4gICAgICAgICAgb2Zmc2V0WCA9IHN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX1VQKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IC1zdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5BUlJPV19ET1dOKSB7XG4gICAgICAgICAgb2Zmc2V0WSA9IHN0ZXA7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHg6IGVsZW1lbnQueCArIG9mZnNldFgsXG4gICAgICAgICAgICB5OiBlbGVtZW50LnkgKyBvZmZzZXRZLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdXBkYXRlQm91bmRFbGVtZW50cyhlbGVtZW50LCB7XG4gICAgICAgICAgICBzaW11bHRhbmVvdXNseVVwZGF0ZWQ6IHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuRU5URVIpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCAhPT0gc2VsZWN0ZWRFbGVtZW50c1swXS5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG5cbiAgICAgICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICAgICAgc2NlbmVYOiBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDIsXG4gICAgICAgICAgICBzY2VuZVk6IHNlbGVjdGVkRWxlbWVudC55ICsgc2VsZWN0ZWRFbGVtZW50LmhlaWdodCAvIDIsXG4gICAgICAgICAgICBzaG91bGRCaW5kOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAhZXZlbnQuY3RybEtleSAmJlxuICAgICAgICAhZXZlbnQuYWx0S2V5ICYmXG4gICAgICAgICFldmVudC5tZXRhS2V5ICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ID09PSBudWxsXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBmaW5kU2hhcGVCeUtleShldmVudC5rZXkpO1xuICAgICAgICBpZiAoc2hhcGUpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChzaGFwZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlEpIHtcbiAgICAgICAgICB0aGlzLnRvZ2dsZUxvY2soKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSAmJiBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgaXNIb2xkaW5nU3BhY2UgPSB0cnVlO1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5HIHx8IGV2ZW50LmtleSA9PT0gS0VZUy5TKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICAgICFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkcgJiZcbiAgICAgICAgICAoaGFzQmFja2dyb3VuZCh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKSB8fFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PiBoYXNCYWNrZ3JvdW5kKGVsZW1lbnQudHlwZSkpKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgb3BlblBvcHVwOiBcImJhY2tncm91bmRDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUykge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwic3Ryb2tlQ29sb3JQaWNrZXJcIiB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICk7XG5cbiAgcHJpdmF0ZSBvbktleVVwID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuU1BBQ0UpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIH1cbiAgICBpZiAoaXNBcnJvd0tleShldmVudC5rZXkpKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgKTtcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzKHNlbGVjdGVkRWxlbWVudHMpXG4gICAgICAgIDogdW5iaW5kTGluZWFyRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBzZWxlY3RTaGFwZVRvb2woZWxlbWVudFR5cGU6IEFwcFN0YXRlW1wiZWxlbWVudFR5cGVcIl0pIHtcbiAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgZWxlbWVudFR5cGUpO1xuICAgIH1cbiAgICBpZiAoaXNUb29sSWNvbihkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cbiAgICBpZiAoIWlzTGluZWFyRWxlbWVudFR5cGUoZWxlbWVudFR5cGUpKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgdGhpcy5vbkltYWdlQWN0aW9uKCk7XG4gICAgfVxuICAgIGlmIChlbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVsZW1lbnRUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVsZW1lbnRUeXBlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25HZXN0dXJlU3RhcnQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICB9KTtcbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVDaGFuZ2UgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gb25HZXN0dXJlQ2hhbmdlIG9ubHkgaGFzIHpvb20gZmFjdG9yIGJ1dCBub3QgdGhlIGNlbnRlci5cbiAgICAvLyBJZiB3ZSdyZSBvbiBpUGFkIG9yIGlQaG9uZSwgdGhlbiB3ZSByZWNvZ25pemUgbXVsdGktdG91Y2ggYW5kIHdpbGxcbiAgICAvLyB6b29tIGluIGF0IHRoZSByaWdodCBsb2NhdGlvbiBvbiB0aGUgdG91Y2hNb3ZlIGhhbmRsZXIgYWxyZWFkeS5cbiAgICAvLyBPbiBNYWNib29rLCB3ZSBkb24ndCBoYXZlIHRob3NlIGV2ZW50cyBzbyB3aWxsIHpvb20gaW4gYXQgdGhlXG4gICAgLy8gY3VycmVudCBsb2NhdGlvbiBpbnN0ZWFkLlxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsU2NhbGUgPSBnZXN0dXJlLmluaXRpYWxTY2FsZTtcbiAgICBpZiAoaW5pdGlhbFNjYWxlKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIG9mZnNldExlZnQsIG9mZnNldFRvcCB9KSA9PiAoe1xuICAgICAgICB6b29tOiBnZXROZXdab29tKFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIGV2ZW50LnNjYWxlKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIHsgbGVmdDogb2Zmc2V0TGVmdCwgdG9wOiBvZmZzZXRUb3AgfSxcbiAgICAgICAgICB7IHg6IGN1cnNvclgsIHk6IGN1cnNvclkgfSxcbiAgICAgICAgKSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0pO1xuXG4gIHByaXZhdGUgb25HZXN0dXJlRW5kID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogR2VzdHVyZUV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICB9KTtcbiAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9IG51bGw7XG4gIH0pO1xuXG4gIHByaXZhdGUgaGFuZGxlVGV4dFd5c2l3eWcoXG4gICAgZWxlbWVudDogRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICAgIHtcbiAgICAgIGlzRXhpc3RpbmdFbGVtZW50ID0gZmFsc2UsXG4gICAgfToge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZUVsZW1lbnQgPSAoXG4gICAgICB0ZXh0OiBzdHJpbmcsXG4gICAgICBvcmlnaW5hbFRleHQ6IHN0cmluZyxcbiAgICAgIGlzRGVsZXRlZCA9IGZhbHNlLFxuICAgICAgdXBkYXRlRGltZW5zaW9ucyA9IGZhbHNlLFxuICAgICkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoX2VsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoX2VsZW1lbnQuaWQgPT09IGVsZW1lbnQuaWQgJiYgaXNUZXh0RWxlbWVudChfZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVUZXh0RWxlbWVudChcbiAgICAgICAgICAgICAgX2VsZW1lbnQsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIGlzRGVsZXRlZCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbFRleHQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHVwZGF0ZURpbWVuc2lvbnMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgfTtcblxuICAgIHRleHRXeXNpd3lnKHtcbiAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICBjYW52YXM6IHRoaXMuY2FudmFzLFxuICAgICAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4LCB5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzY2VuZVg6IHgsXG4gICAgICAgICAgICBzY2VuZVk6IHksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHZpZXdwb3J0WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCwgLy8qICgyIC0gdGhpcy5zdGF0ZS56b29tLnZhbHVlKSxcbiAgICAgICAgICB2aWV3cG9ydFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCwgLy8qICgyIC0gdGhpcy5zdGF0ZS56b29tLnZhbHVlKSxcbiAgICAgICAgXTtcbiAgICAgIH0sXG4gICAgICBvbkNoYW5nZTogd2l0aEJhdGNoZWRVcGRhdGVzKCh0ZXh0KSA9PiB7XG4gICAgICAgIHVwZGF0ZUVsZW1lbnQodGV4dCwgdGV4dCwgZmFsc2UsICFlbGVtZW50LmNvbnRhaW5lcklkKTtcbiAgICAgICAgaWYgKGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIG9uU3VibWl0OiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHsgdGV4dCwgdmlhS2V5Ym9hcmQsIG9yaWdpbmFsVGV4dCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzRGVsZXRlZCA9ICF0ZXh0LnRyaW0oKTtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCBvcmlnaW5hbFRleHQsIGlzRGVsZXRlZCwgdHJ1ZSk7XG4gICAgICAgIC8vIHNlbGVjdCB0aGUgY3JlYXRlZCB0ZXh0IGVsZW1lbnQgb25seSBpZiBzdWJtaXR0aW5nIHZpYSBrZXlib2FyZFxuICAgICAgICAvLyAod2hlbiBzdWJtaXR0aW5nIHZpYSBjbGljayBpdCBzaG91bGQgYWN0IGFzIHNpZ25hbCB0byBkZXNlbGVjdClcbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgJiYgdmlhS2V5Ym9hcmQpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50SWRUb1NlbGVjdCA9IGVsZW1lbnQuY29udGFpbmVySWRcbiAgICAgICAgICAgID8gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgOiBlbGVtZW50LmlkO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICBbZWxlbWVudElkVG9TZWxlY3RdOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVsZXRlZCkge1xuICAgICAgICAgIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbih0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIFtlbGVtZW50XSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0RlbGV0ZWQgfHwgaXNFeGlzdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50TG9ja2VkKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgICAgfSksXG4gICAgICBlbGVtZW50LFxuICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQsXG4gICAgfSk7XG4gICAgLy8gZGVzZWxlY3QgYWxsIG90aGVyIGVsZW1lbnRzIHdoZW4gaW5zZXJ0aW5nIHRleHRcbiAgICB0aGlzLmRlc2VsZWN0RWxlbWVudHMoKTtcblxuICAgIC8vIGRvIGFuIGluaXRpYWwgdXBkYXRlIHRvIHJlLWluaXRpYWxpemUgZWxlbWVudCBwb3NpdGlvbiBzaW5jZSB3ZSB3ZXJlXG4gICAgLy8gbW9kaWZ5aW5nIGVsZW1lbnQncyB4L3kgZm9yIHNha2Ugb2YgZWRpdG9yIChjYXNlOiBzeW5jaW5nIHRvIHJlbW90ZSlcbiAgICB1cGRhdGVFbGVtZW50KGVsZW1lbnQudGV4dCwgZWxlbWVudC5vcmlnaW5hbFRleHQpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXNlbGVjdEVsZW1lbnRzKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRFbGVtZW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICApOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdUZXh0RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbih4LCB5LCB7XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGlmIChlbGVtZW50ICYmIGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgIWVsZW1lbnQuaXNEZWxldGVkKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgb3B0cz86IHtcbiAgICAgIC8qKiBpZiB0cnVlLCByZXR1cm5zIHRoZSBmaXJzdCBzZWxlY3RlZCBlbGVtZW50ICh3aXRoIGhpZ2hlc3Qgei1pbmRleClcbiAgICAgICAgb2YgYWxsIGhpdCBlbGVtZW50cyAqL1xuICAgICAgcHJlZmVyU2VsZWN0ZWQ/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+IHwgbnVsbCB7XG4gICAgY29uc3QgYWxsSGl0RWxlbWVudHMgPSB0aGlzLmdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgb3B0cz8uaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQsXG4gICAgKTtcbiAgICBpZiAoYWxsSGl0RWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKG9wdHM/LnByZWZlclNlbGVjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMTsgaW5kZXggPiAtMTsgaW5kZXgtLSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1thbGxIaXRFbGVtZW50c1tpbmRleF0uaWRdKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxsSGl0RWxlbWVudHNbaW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZWxlbWVudFdpdGhIaWdoZXN0WkluZGV4ID1cbiAgICAgICAgYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMV07XG4gICAgICAvLyBJZiB3ZSdyZSBoaXR0aW5nIGVsZW1lbnQgd2l0aCBoaWdoZXN0IHotaW5kZXggb25seSBvbiBpdHMgYm91bmRpbmcgYm94XG4gICAgICAvLyB3aGlsZSBhbHNvIGhpdHRpbmcgb3RoZXIgZWxlbWVudCBmaWd1cmUsIHRoZSBsYXR0ZXIgc2hvdWxkIGJlIGNvbnNpZGVyZWQuXG4gICAgICByZXR1cm4gaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXgsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICApXG4gICAgICAgID8gYWxsSGl0RWxlbWVudHNbYWxsSGl0RWxlbWVudHMubGVuZ3RoIC0gMl1cbiAgICAgICAgOiBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXg7XG4gICAgfVxuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1swXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRzQXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiBib29sZWFuID0gZmFsc2UsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0VsZW1lbnQ+W10ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnRcbiAgICAgID8gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpXG4gICAgICA6IHRoaXMuc2NlbmVcbiAgICAgICAgICAuZ2V0RWxlbWVudHMoKVxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZWxlbWVudCkgPT4gIShpc1RleHRFbGVtZW50KGVsZW1lbnQpICYmIGVsZW1lbnQuY29udGFpbmVySWQpLFxuICAgICAgICAgICk7XG4gICAgcmV0dXJuIGdldEVsZW1lbnRzQXRQb3NpdGlvbihlbGVtZW50cywgKGVsZW1lbnQpID0+XG4gICAgICBoaXRUZXN0KGVsZW1lbnQsIHRoaXMuc3RhdGUsIHgsIHkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VGV4dEVkaXRpbmcgPSAoe1xuICAgIHNjZW5lWCxcbiAgICBzY2VuZVksXG4gICAgc2hvdWxkQmluZCxcbiAgICBpbnNlcnRBdFBhcmVudENlbnRlciA9IHRydWUsXG4gIH06IHtcbiAgICAvKiogWCBwb3NpdGlvbiB0byBpbnNlcnQgdGV4dCBhdCAqL1xuICAgIHNjZW5lWDogbnVtYmVyO1xuICAgIC8qKiBZIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVZOiBudW1iZXI7XG4gICAgc2hvdWxkQmluZDogYm9vbGVhbjtcbiAgICAvKiogd2hldGhlciB0byBhdHRlbXB0IHRvIGluc2VydCBhdCBlbGVtZW50IGNlbnRlciBpZiBhcHBsaWNhYmxlICovXG4gICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgbGV0IHBhcmVudENlbnRlclBvc2l0aW9uID1cbiAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyICYmXG4gICAgICB0aGlzLmdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgICAgIHNjZW5lWCxcbiAgICAgICAgc2NlbmVZLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICApO1xuXG4gICAgLy8gYmluZCB0byBjb250YWluZXIgd2hlbiBzaG91bGRCaW5kIGlzIHRydWUgb3JcbiAgICAvLyBjbGlja2VkIG9uIGNlbnRlciBvZiBjb250YWluZXJcbiAgICBjb25zdCBjb250YWluZXIgPVxuICAgICAgc2hvdWxkQmluZCB8fCBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICA/IGdldEVsZW1lbnRDb250YWluaW5nUG9zaXRpb24oXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgICBcInRleHRcIixcbiAgICAgICAgICApXG4gICAgICAgIDogbnVsbDtcblxuICAgIGxldCBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5nZXRUZXh0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuXG4gICAgLy8gY29uc2lkZXIgYm91bmRlZCB0ZXh0IGVsZW1lbnQgaWYgY29udGFpbmVyIHByZXNlbnRcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb25zdCBib3VuZFRleHRFbGVtZW50SWQgPSBnZXRCb3VuZFRleHRFbGVtZW50SWQoY29udGFpbmVyKTtcbiAgICAgIGlmIChib3VuZFRleHRFbGVtZW50SWQpIHtcbiAgICAgICAgZXhpc3RpbmdUZXh0RWxlbWVudCA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudChcbiAgICAgICAgICBib3VuZFRleHRFbGVtZW50SWQsXG4gICAgICAgICkgYXMgRXhjYWxpZHJhd1RleHRFbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWV4aXN0aW5nVGV4dEVsZW1lbnQgJiYgY29udGFpbmVyKSB7XG4gICAgICBjb25zdCBmb250U3RyaW5nID0ge1xuICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIH07XG4gICAgICBjb25zdCBtaW5XaWR0aCA9IGdldEFwcHJveE1pbkxpbmVXaWR0aChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG1pbkhlaWdodCA9IGdldEFwcHJveE1pbkxpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyhmb250U3RyaW5nKSk7XG4gICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heChjb250YWluZXIuaGVpZ2h0LCBtaW5IZWlnaHQpO1xuICAgICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChjb250YWluZXIud2lkdGgsIG1pbldpZHRoKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogbmV3SGVpZ2h0LCB3aWR0aDogbmV3V2lkdGggfSk7XG4gICAgICBzY2VuZVggPSBjb250YWluZXIueCArIG5ld1dpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGNvbnRhaW5lci55ICsgbmV3SGVpZ2h0IC8gMjtcbiAgICAgIGlmIChwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBwYXJlbnRDZW50ZXJQb3NpdGlvbiA9IHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgICBzY2VuZVgsXG4gICAgICAgICAgc2NlbmVZLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IGV4aXN0aW5nVGV4dEVsZW1lbnRcbiAgICAgID8gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgOiBuZXdUZXh0RWxlbWVudCh7XG4gICAgICAgICAgeDogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlclhcbiAgICAgICAgICAgIDogc2NlbmVYLFxuICAgICAgICAgIHk6IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IHBhcmVudENlbnRlclBvc2l0aW9uLmVsZW1lbnRDZW50ZXJZXG4gICAgICAgICAgICA6IHNjZW5lWSxcbiAgICAgICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgICAgICAgdGV4dDogXCJcIixcbiAgICAgICAgICBmb250U2l6ZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRTaXplLFxuICAgICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgICAgIHRleHRBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gXCJjZW50ZXJcIlxuICAgICAgICAgICAgOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtVGV4dEFsaWduLFxuICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgICAgICA/IFwibWlkZGxlXCJcbiAgICAgICAgICAgIDogREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgICAgICAgICBjb250YWluZXJJZDogY29udGFpbmVyPy5pZCA/PyB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRpbmdFbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gICAgaWYgKGV4aXN0aW5nVGV4dEVsZW1lbnQpIHtcbiAgICAgIC8vIGlmIHRleHQgZWxlbWVudCBpcyBubyBsb25nZXIgY2VudGVyZWQgdG8gYSBjb250YWluZXIsIHJlc2V0XG4gICAgICAvLyB2ZXJ0aWNhbEFsaWduIHRvIGRlZmF1bHQgYmVjYXVzZSBpdCdzIGN1cnJlbnRseSBpbnRlcm5hbC1vbmx5XG4gICAgICBpZiAoIXBhcmVudENlbnRlclBvc2l0aW9uIHx8IGVsZW1lbnQudGV4dEFsaWduICE9PSBcImNlbnRlclwiKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwgeyB2ZXJ0aWNhbEFsaWduOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcblxuICAgICAgLy8gY2FzZTogY3JlYXRpbmcgbmV3IHRleHQgbm90IGNlbnRlcmVkIHRvIHBhcmVudCBlbGVtZW5lbnQg4oaSIG9mZnNldCBZXG4gICAgICAvLyBzbyB0aGF0IHRoZSB0ZXh0IGlzIGNlbnRlcmVkIHRvIGN1cnNvciBwb3NpdGlvblxuICAgICAgaWYgKCFwYXJlbnRDZW50ZXJQb3NpdGlvbikge1xuICAgICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgICB5OiBlbGVtZW50LnkgLSBlbGVtZW50LmJhc2VsaW5lIC8gMixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlVGV4dFd5c2l3eWcoZWxlbWVudCwge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQ6ICEhZXhpc3RpbmdUZXh0RWxlbWVudCxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0RvdWJsZUNsaWNrID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Nb3VzZUV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gY2FzZTogZG91YmxlLWNsaWNraW5nIHdpdGggYXJyb3cvbGluZSB0b29sIHNlbGVjdGVkIHdvdWxkIGJvdGggY3JlYXRlXG4gICAgLy8gdGV4dCBhbmQgZW50ZXIgbXVsdGlFbGVtZW50IG1vZGVcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gd2Ugc2hvdWxkIG9ubHkgYmUgYWJsZSB0byBkb3VibGUgY2xpY2sgd2hlbiBtb2RlIGlzIHNlbGVjdGlvblxuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudDogbmV3IExpbmVhckVsZW1lbnRFZGl0b3IoXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG5cbiAgICBsZXQgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgZXZlbnQsXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWRzID0gZ2V0U2VsZWN0ZWRHcm91cElkcyh0aGlzLnN0YXRlKTtcblxuICAgIGlmIChzZWxlY3RlZEdyb3VwSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHNjZW5lWCwgc2NlbmVZKTtcblxuICAgICAgY29uc3Qgc2VsZWN0ZWRHcm91cElkID1cbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICBnZXRTZWxlY3RlZEdyb3VwSWRGb3JFbGVtZW50KGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cElkcyk7XG5cbiAgICAgIGlmIChzZWxlY3RlZEdyb3VwSWQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IHNlbGVjdGVkR3JvdXBJZCxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50IS5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCFldmVudFtLRVlTLkNUUkxfT1JfQ01EXSAmJiAhdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHNbMF07XG4gICAgICAgIGNvbnN0IGNhbkJpbmRUZXh0ID0gaGFzQm91bmRUZXh0RWxlbWVudChzZWxlY3RlZEVsZW1lbnQpO1xuICAgICAgICBpZiAoY2FuQmluZFRleHQpIHtcbiAgICAgICAgICBzY2VuZVggPSBzZWxlY3RlZEVsZW1lbnQueCArIHNlbGVjdGVkRWxlbWVudC53aWR0aCAvIDI7XG4gICAgICAgICAgc2NlbmVZID0gc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgICBpbnNlcnRBdFBhcmVudENlbnRlcjogIWV2ZW50LmFsdEtleSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc1BvaW50ZXJNb3ZlID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIHRoaXMuc3RhdGUuY3Vyc29yQnV0dG9uKTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLmhhcyhldmVudC5wb2ludGVySWQpKSB7XG4gICAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgICAgeDogZXZlbnQuY2xpZW50WCxcbiAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMiAmJlxuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyICYmXG4gICAgICBpbml0aWFsU2NhbGUgJiZcbiAgICAgIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlXG4gICAgKSB7XG4gICAgICBjb25zdCBjZW50ZXIgPSBnZXRDZW50ZXIoZ2VzdHVyZS5wb2ludGVycyk7XG4gICAgICBjb25zdCBkZWx0YVggPSBjZW50ZXIueCAtIGdlc3R1cmUubGFzdENlbnRlci54O1xuICAgICAgY29uc3QgZGVsdGFZID0gY2VudGVyLnkgLSBnZXN0dXJlLmxhc3RDZW50ZXIueTtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGNlbnRlcjtcblxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBnZXREaXN0YW5jZShBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpKTtcbiAgICAgIGNvbnN0IHNjYWxlRmFjdG9yID0gZGlzdGFuY2UgLyBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZLCBvZmZzZXRMZWZ0LCBvZmZzZXRUb3AgfSkgPT4gKHtcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCArIGRlbHRhWCAvIHpvb20udmFsdWUsXG4gICAgICAgIHNjcm9sbFk6IHNjcm9sbFkgKyBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgICAgICB6b29tOiBnZXROZXdab29tKFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWRab29tKGluaXRpYWxTY2FsZSAqIHNjYWxlRmFjdG9yKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIHsgbGVmdDogb2Zmc2V0TGVmdCwgdG9wOiBvZmZzZXRUb3AgfSxcbiAgICAgICAgICBjZW50ZXIsXG4gICAgICAgICksXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID1cbiAgICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxTY2FsZSA9XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoaXNIb2xkaW5nU3BhY2UgfHwgaXNQYW5uaW5nIHx8IGlzRHJhZ2dpbmdTY3JvbGxCYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycyA9IGlzT3ZlclNjcm9sbEJhcnMoXG4gICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICBldmVudC5jbGllbnRZIC0gdGhpcy5zdGF0ZS5vZmZzZXRUb3AsXG4gICAgKTtcbiAgICBjb25zdCBpc092ZXJTY3JvbGxCYXIgPSBpc1BvaW50ZXJPdmVyU2Nyb2xsQmFycy5pc092ZXJFaXRoZXI7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjZW5lUG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgeyB4OiBzY2VuZVBvaW50ZXJYLCB5OiBzY2VuZVBvaW50ZXJZIH0gPSBzY2VuZVBvaW50ZXI7XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5pc0RyYWdnaW5nXG4gICAgKSB7XG4gICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlck1vdmUoXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudCAhPT0gdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0xpbmVhckVsZW1lbnQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQubGFzdFVuY29tbWl0dGVkUG9pbnQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNCaW5kaW5nRWxlbWVudFR5cGUodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSkpIHtcbiAgICAgIC8vIEhvdmVyaW5nIHdpdGggYSBzZWxlY3RlZCB0b29sIG9yIGNyZWF0aW5nIG5ldyBsaW5lYXIgZWxlbWVudCB2aWEgY2xpY2tcbiAgICAgIC8vIGFuZCBwb2ludFxuICAgICAgY29uc3QgeyBkcmFnZ2luZ0VsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIFtzY2VuZVBvaW50ZXJdLFxuICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvcihzY2VuZVBvaW50ZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCB7IHg6IHJ4LCB5OiByeSB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICBjb25zdCB7IHBvaW50cywgbGFzdENvbW1pdHRlZFBvaW50IH0gPSBtdWx0aUVsZW1lbnQ7XG4gICAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG5cbiAgICAgIGlmIChsYXN0UG9pbnQgPT09IGxhc3RDb21taXR0ZWRQb2ludCkge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlbid0IHlldCBjcmVhdGVkIGEgdGVtcCBwb2ludCBhbmQgd2UncmUgYmV5b25kIGNvbW1pdC16b25lXG4gICAgICAgIC8vIHRocmVzaG9sZCwgYWRkIGEgcG9pbnRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJYIC0gcngsXG4gICAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgICBsYXN0UG9pbnRbMF0sXG4gICAgICAgICAgICBsYXN0UG9pbnRbMV0sXG4gICAgICAgICAgKSA+PSBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMsIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgICAgLy8gaW4gdGhpcyBicmFuY2gsIHdlJ3JlIGluc2lkZSB0aGUgY29tbWl0IHpvbmUsIGFuZCBubyB1bmNvbW1pdHRlZFxuICAgICAgICAgIC8vIHBvaW50IGV4aXN0cy4gVGh1cyBkbyBub3RoaW5nIChkb24ndCBhZGQvcmVtb3ZlIHBvaW50cykuXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHBvaW50cy5sZW5ndGggPiAyICYmXG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludCAmJlxuICAgICAgICBkaXN0YW5jZTJkKFxuICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXJZIC0gcnksXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzBdLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFsxXSxcbiAgICAgICAgKSA8IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogcG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNQYXRoQUxvb3AocG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpKSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB1cGRhdGUgbGFzdCB1bmNvbW1pdHRlZCBwb2ludFxuICAgICAgICBtdXRhdGVFbGVtZW50KG11bHRpRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogW1xuICAgICAgICAgICAgLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgICAgIFtzY2VuZVBvaW50ZXJYIC0gcngsIHNjZW5lUG9pbnRlclkgLSByeV0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZXNlbGVjdGVkQnV0dG9uID0gQm9vbGVhbihldmVudC5idXR0b25zKTtcbiAgICBpZiAoXG4gICAgICBoYXNEZXNlbGVjdGVkQnV0dG9uIHx8XG4gICAgICAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInRleHRcIilcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICBpZiAoXG4gICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgIWlzT3ZlclNjcm9sbEJhciAmJlxuICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnRcbiAgICApIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9IGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgJiZcbiAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGVcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMSAmJiAhaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0VHJhbnNmb3JtSGFuZGxlVHlwZUZyb21Db29yZHMoXG4gICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAodHJhbnNmb3JtSGFuZGxlVHlwZSkge1xuICAgICAgICBzZXRDdXJzb3IoXG4gICAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBoaXRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihcbiAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgc2NlbmVQb2ludGVyLnksXG4gICAgKTtcbiAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgIHNldEN1cnNvcihcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgIGlzVGV4dEVsZW1lbnQoaGl0RWxlbWVudCkgPyBDVVJTT1JfVFlQRS5URVhUIDogQ1VSU09SX1RZUEUuQ1JPU1NIQUlSLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgIH0gZWxzZSBpZiAoaXNPdmVyU2Nyb2xsQmFyKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuZ2V0RWxlbWVudChcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQsXG4gICAgICApO1xuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50ICYmXG4gICAgICAgIGlzSGl0dGluZ0VsZW1lbnROb3RDb25zaWRlcmluZ0JvdW5kaW5nQm94KGVsZW1lbnQsIHRoaXMuc3RhdGUsIFtcbiAgICAgICAgICBzY2VuZVBvaW50ZXIueCxcbiAgICAgICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICAgICAgXSlcbiAgICAgICkge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgLy8gaWYgdXNpbmcgY21kL2N0cmwsIHdlJ3JlIG5vdCBkcmFnZ2luZ1xuICAgICAgIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAoaGl0RWxlbWVudCB8fFxuICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHNjZW5lUG9pbnRlcixcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICApKVxuICAgICkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5NT1ZFKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5BVVRPKTtcbiAgICB9XG4gIH07XG5cbiAgLy8gc2V0IHRvdWNoIG1vdmluZyBmb3IgbW9iaWxlIGNvbnRleHQgbWVudVxuICBwcml2YXRlIGhhbmRsZVRvdWNoTW92ZSA9IChldmVudDogUmVhY3QuVG91Y2hFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4pID0+IHtcbiAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIC8vIHJlbW92ZSBhbnkgYWN0aXZlIHNlbGVjdGlvbiB3aGVuIHdlIHN0YXJ0IHRvIGludGVyYWN0IHdpdGggY2FudmFzXG4gICAgLy8gKG1haW5seSwgd2UgY2FyZSBhYm91dCByZW1vdmluZyBzZWxlY3Rpb24gb3V0c2lkZSB0aGUgY29tcG9uZW50IHdoaWNoXG4gICAgLy8gIHdvdWxkIHByZXZlbnQgb3VyIGNvcHkgaGFuZGxpbmcgb3RoZXJ3aXNlKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24/LmFuY2hvck5vZGUpIHtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICB9XG5cbiAgICB0aGlzLm1heWJlT3BlbkNvbnRleHRNZW51QWZ0ZXJQb2ludGVyRG93bk9uVG91Y2hEZXZpY2VzKGV2ZW50KTtcbiAgICB0aGlzLm1heWJlQ2xlYW51cEFmdGVyTWlzc2luZ1BvaW50ZXJVcChldmVudCk7XG5cbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBsYXN0UG9pbnRlckRvd25XaXRoOiBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgIGN1cnNvckJ1dHRvbjogXCJkb3duXCIsXG4gICAgfSk7XG4gICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcImRvd25cIik7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBoYW5kbGUgbGVmdCBtb3VzZSBidXR0b24gb3IgdG91Y2hcbiAgICBpZiAoXG4gICAgICBldmVudC5idXR0b24gIT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiZcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uVE9VQ0hcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKGV2ZW50KTtcblxuICAgIC8vIGRvbid0IHNlbGVjdCB3aGlsZSBwYW5uaW5nXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA+IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGF0ZSBmb3IgdGhlIGR1cmF0aW9uIG9mIGEgcG9pbnRlciBpbnRlcmFjdGlvbiwgd2hpY2ggc3RhcnRzIHdpdGggYVxuICAgIC8vIHBvaW50ZXJEb3duIGV2ZW50LCBlbmRzIHdpdGggYSBwb2ludGVyVXAgZXZlbnQgKG9yIGFub3RoZXIgcG9pbnRlckRvd24pXG4gICAgY29uc3QgcG9pbnRlckRvd25TdGF0ZSA9IHRoaXMuaW5pdGlhbFBvaW50ZXJEb3duU3RhdGUoZXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInRleHRcIikge1xuICAgICAgdGhpcy5oYW5kbGVUZXh0T25Qb2ludGVyRG93bihldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIiB8fFxuICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJsaW5lXCJcbiAgICApIHtcbiAgICAgIHRoaXMuaGFuZGxlTGluZWFyRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIGV2ZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgLy8gcmVzZXQgaW1hZ2UgcHJldmlldyBvbiBwb2ludGVyZG93blxuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5DUk9TU0hBSVIpO1xuXG4gICAgICBpZiAoIXRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCxcbiAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudDogbnVsbCxcbiAgICAgICAgbXVsdGlFbGVtZW50OiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgIG11dGF0ZUVsZW1lbnQodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgdGhpcy5oYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICBldmVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duKFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID1cbiAgICAgIHRoaXMub25Qb2ludGVyTW92ZUZyb21Qb2ludGVyRG93bkhhbmRsZXIocG9pbnRlckRvd25TdGF0ZSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9XG4gICAgICB0aGlzLm9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uS2V5RG93biA9IHRoaXMub25LZXlEb3duRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcbiAgICBjb25zdCBvbktleVVwID0gdGhpcy5vbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIGlmICghdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCBvbktleURvd24pO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuS0VZVVAsIG9uS2V5VXApO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUgPSBvblBvaW50ZXJNb3ZlO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vblVwID0gb25Qb2ludGVyVXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAgPSBvbktleVVwO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbktleURvd24gPSBvbktleURvd247XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVPcGVuQ29udGV4dE1lbnVBZnRlclBvaW50ZXJEb3duT25Ub3VjaERldmljZXMgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGRlYWwgd2l0aCBvcGVuaW5nIGNvbnRleHQgbWVudSBvbiB0b3VjaCBkZXZpY2VzXG4gICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIpIHtcbiAgICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IGZhbHNlO1xuXG4gICAgICBpZiAodG91Y2hUaW1lb3V0KSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgYWxyZWFkeSBhIHRvdWNoVGltZW91dCwgdGhpcyBtZWFucyB0aGF0IHRoZXJlJ3MgYW5vdGhlclxuICAgICAgICAvLyB0b3VjaCBkb3duIGFuZCB3ZSBhcmUgZG9pbmcgYW5vdGhlciB0b3VjaCwgc28gd2Ugc2hvdWxkbid0IG9wZW4gdGhlXG4gICAgICAgIC8vIGNvbnRleHQgbWVudS5cbiAgICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9wZW4gdGhlIGNvbnRleHQgbWVudSB3aXRoIHRoZSBmaXJzdCB0b3VjaCdzIGNsaWVudFggYW5kIGNsaWVudFlcbiAgICAgICAgLy8gaWYgdGhlIHRvdWNoIGlzIG5vdCBtb3ZpbmdcbiAgICAgICAgdG91Y2hUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgICAgICAgaWYgKCFpbnZhbGlkYXRlQ29udGV4dE1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUoZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgVE9VQ0hfQ1RYX01FTlVfVElNRU9VVCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBpZiAobGFzdFBvaW50ZXJVcCAhPT0gbnVsbCkge1xuICAgICAgLy8gVW5mb3J0dW5hdGVseSwgc29tZXRpbWVzIHdlIGRvbid0IGdldCBhIHBvaW50ZXJ1cCBhZnRlciBhIHBvaW50ZXJkb3duLFxuICAgICAgLy8gdGhpcyBjYW4gaGFwcGVuIHdoZW4gYSBjb250ZXh0dWFsIG1lbnUgb3IgYWxlcnQgaXMgdHJpZ2dlcmVkLiBJbiBvcmRlciB0byBhdm9pZFxuICAgICAgLy8gYmVpbmcgaW4gYSB3ZWlyZCBzdGF0ZSwgd2UgY2xlYW4gdXAgb24gdGhlIG5leHQgcG9pbnRlcmRvd25cbiAgICAgIGxhc3RQb2ludGVyVXAoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgZXZlbnQgaXMgYSBwYW5uaW5nXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUGFuVXNpbmdXaGVlbE9yU3BhY2VEcmFnID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAoXG4gICAgICAhKFxuICAgICAgICBnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDAgJiZcbiAgICAgICAgKGV2ZW50LmJ1dHRvbiA9PT0gUE9JTlRFUl9CVVRUT04uV0hFRUwgfHxcbiAgICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5NQUlOICYmIGlzSG9sZGluZ1NwYWNlKSB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKVxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuXG4gICAgbGV0IG5leHRQYXN0ZVByZXZlbnRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGlzTGludXggPSAvTGludXgvLnRlc3Qod2luZG93Lm5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUJCSU5HKTtcbiAgICBsZXQgeyBjbGllbnRYOiBsYXN0WCwgY2xpZW50WTogbGFzdFkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGxhc3RYIC0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGNvbnN0IGRlbHRhWSA9IGxhc3RZIC0gZXZlbnQuY2xpZW50WTtcbiAgICAgIGxhc3RYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGxhc3RZID0gZXZlbnQuY2xpZW50WTtcblxuICAgICAgLypcbiAgICAgICAqIFByZXZlbnQgcGFzdGUgZXZlbnQgaWYgd2UgbW92ZSB3aGlsZSBtaWRkbGUgY2xpY2tpbmcgb24gTGludXguXG4gICAgICAgKiBTZWUgaXNzdWUgIzEzODMuXG4gICAgICAgKi9cbiAgICAgIGlmIChcbiAgICAgICAgaXNMaW51eCAmJlxuICAgICAgICAhbmV4dFBhc3RlUHJldmVudGVkICYmXG4gICAgICAgIChNYXRoLmFicyhkZWx0YVgpID4gMSB8fCBNYXRoLmFicyhkZWx0YVkpID4gMSlcbiAgICAgICkge1xuICAgICAgICBuZXh0UGFzdGVQcmV2ZW50ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8qIFByZXZlbnQgdGhlIG5leHQgcGFzdGUgZXZlbnQgKi9cbiAgICAgICAgY29uc3QgcHJldmVudE5leHRQYXN0ZSA9IChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIFJlZW5hYmxlIG5leHQgcGFzdGUgaW4gY2FzZSBvZiBkaXNhYmxlZCBtaWRkbGUgY2xpY2sgcGFzdGUgZm9yXG4gICAgICAgICAqIGFueSByZWFzb246XG4gICAgICAgICAqIC0gcmlndGggY2xpY2sgcGFzdGVcbiAgICAgICAgICogLSBlbXB0eSBjbGlwYm9hcmRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGVuYWJsZU5leHRQYXN0ZSA9ICgpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgZW5hYmxlTmV4dFBhc3RlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCAtIGRlbHRhWCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZGVsdGFZIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgdGVhcmRvd24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgICAobGFzdFBvaW50ZXJVcCA9ICgpID0+IHtcbiAgICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoIWlzSG9sZGluZ1NwYWNlKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkdSQUIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGN1cnNvckJ1dHRvbjogXCJ1cFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkJMVVIsIHRlYXJkb3duKTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSwge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0ZWFyZG93bik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVHZXN0dXJlT25Qb2ludGVyRG93bihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCB7XG4gICAgZ2VzdHVyZS5wb2ludGVycy5zZXQoZXZlbnQucG9pbnRlcklkLCB7XG4gICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICB9KTtcblxuICAgIGlmIChnZXN0dXJlLnBvaW50ZXJzLnNpemUgPT09IDIpIHtcbiAgICAgIGdlc3R1cmUubGFzdENlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2UgPSBnZXREaXN0YW5jZShcbiAgICAgICAgQXJyYXkuZnJvbShnZXN0dXJlLnBvaW50ZXJzLnZhbHVlcygpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsUG9pbnRlckRvd25TdGF0ZShcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogUG9pbnRlckRvd25TdGF0ZSB7XG4gICAgY29uc3Qgb3JpZ2luID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3JpZ2luLFxuICAgICAgd2l0aENtZE9yQ3RybDogZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0sXG4gICAgICBvcmlnaW5JbkdyaWQ6IHR1cGxlVG9Db29ycyhcbiAgICAgICAgZ2V0R3JpZFBvaW50KG9yaWdpbi54LCBvcmlnaW4ueSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSksXG4gICAgICApLFxuICAgICAgc2Nyb2xsYmFyczogaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgICAgY3VycmVudFNjcm9sbEJhcnMsXG4gICAgICAgIGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXRlLm9mZnNldExlZnQsXG4gICAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICAgICksXG4gICAgICAvLyB3ZSBuZWVkIHRvIGR1cGxpY2F0ZSBiZWNhdXNlIHdlJ2xsIGJlIHVwZGF0aW5nIHRoaXMgc3RhdGVcbiAgICAgIGxhc3RDb29yZHM6IHsgLi4ub3JpZ2luIH0sXG4gICAgICBvcmlnaW5hbEVsZW1lbnRzOiB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkucmVkdWNlKChhY2MsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgYWNjLnNldChlbGVtZW50LmlkLCBkZWVwQ29weUVsZW1lbnQoZWxlbWVudCkpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcCgpIGFzIFBvaW50ZXJEb3duU3RhdGVbXCJvcmlnaW5hbEVsZW1lbnRzXCJdKSxcbiAgICAgIHJlc2l6ZToge1xuICAgICAgICBoYW5kbGVUeXBlOiBmYWxzZSxcbiAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgIG9mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgIGFycm93RGlyZWN0aW9uOiBcIm9yaWdpblwiLFxuICAgICAgICBjZW50ZXI6IHsgeDogKG1heFggKyBtaW5YKSAvIDIsIHk6IChtYXhZICsgbWluWSkgLyAyIH0sXG4gICAgICB9LFxuICAgICAgaGl0OiB7XG4gICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGFsbEhpdEVsZW1lbnRzOiBbXSxcbiAgICAgICAgd2FzQWRkZWRUb1NlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGhhc0JlZW5EdXBsaWNhdGVkOiBmYWxzZSxcbiAgICAgICAgaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHM6XG4gICAgICAgICAgdGhpcy5pc0hpdHRpbmdDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgKSxcbiAgICAgICAgaGFzSGl0RWxlbWVudEluc2lkZTogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZHJhZzoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICAgIG9mZnNldDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBldmVudExpc3RlbmVyczoge1xuICAgICAgICBvbk1vdmU6IG51bGwsXG4gICAgICAgIG9uVXA6IG51bGwsXG4gICAgICAgIG9uS2V5VXA6IG51bGwsXG4gICAgICAgIG9uS2V5RG93bjogbnVsbCxcbiAgICAgIH0sXG4gICAgICBib3hTZWxlY3Rpb246IHtcbiAgICAgICAgaGFzT2NjdXJyZWQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBldmVudCBpcyBhIGRyYWdnaW5nIGEgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ2dpbmdTY3JvbGxCYXIoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKFxuICAgICAgIShwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyRWl0aGVyICYmICF0aGlzLnN0YXRlLm11bHRpRWxlbWVudClcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IHRydWU7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBldmVudC5jbGllbnRYO1xuICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gZXZlbnQuY2xpZW50WTtcbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb25Qb2ludGVyVXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgICAgaXNEcmFnZ2luZ1Njcm9sbEJhciA9IGZhbHNlO1xuICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgbGFzdFBvaW50ZXJVcCA9IG51bGw7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBvblBvaW50ZXJVcCk7XG4gICAgfSk7XG5cbiAgICBsYXN0UG9pbnRlclVwID0gb25Qb2ludGVyVXA7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX01PVkUsIG9uUG9pbnRlck1vdmUpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb25JZk5vdFVzaW5nU2VsZWN0aW9uID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIGV2ZW50IGhhcyBiZWVuIGNvbXBsZXRlbHkgaGFuZGxlZFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVTZWxlY3Rpb25PblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlKTtcbiAgICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUgPVxuICAgICAgICAgIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZShcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgICAgZXZlbnQucG9pbnRlclR5cGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICByZXNpemluZ0VsZW1lbnQ6IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZS5lbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPVxuICAgICAgICAgICAgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLnRyYW5zZm9ybUhhbmRsZVR5cGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgICBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyksXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgIHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZTogcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXRSZXNpemVPZmZzZXRYWShcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgaXNMaW5lYXJFbGVtZW50KHNlbGVjdGVkRWxlbWVudHNbMF0pICYmXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXS5wb2ludHMubGVuZ3RoID09PSAyXG4gICAgICAgICkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uID0gZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1swXSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IHJldCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlckRvd24oXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAoYXBwU3RhdGUpID0+IHRoaXMuc2V0U3RhdGUoYXBwU3RhdGUpLFxuICAgICAgICAgICAgdGhpcy5oaXN0b3J5LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocmV0LmhpdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPSByZXQuaGl0RWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJldC5kaWRBZGRQb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGl0RWxlbWVudCBtYXkgYWxyZWFkeSBiZSBzZXQgYWJvdmUsIHNvIGNoZWNrIGZpcnN0XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQgPz9cbiAgICAgICAgICB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKTtcblxuICAgICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUgPVxuICAgICAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goXG4gICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55XSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igb3ZlcmxhcHBlZCBlbGVtZW50cyBvbmUgcG9zaXRpb24gbWF5IGhpdFxuICAgICAgICAvLyBtdWx0aXBsZSBlbGVtZW50c1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgY29uc3Qgc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkID1cbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKChlbGVtZW50KSA9PlxuICAgICAgICAgICAgdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChoaXRFbGVtZW50ID09PSBudWxsIHx8ICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQpICYmXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIElmIHdlIGNsaWNrIG9uIHNvbWV0aGluZ1xuICAgICAgICB9IGVsc2UgaWYgKGhpdEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgIC8vIG9uIENNRC9DVFJMLCBkcmlsbCBkb3duIHRvIGhpdCBlbGVtZW50IHJlZ2FyZGxlc3Mgb2YgZ3JvdXBzIGV0Yy5cbiAgICAgICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIC4uLmVkaXRHcm91cEZvclNlbGVjdGVkRWxlbWVudChwcmV2U3RhdGUsIGhpdEVsZW1lbnQpLFxuICAgICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAvLyBtYXJrIGFzIG5vdCBjb21wbGV0ZWx5IGhhbmRsZWQgc28gYXMgdG8gYWxsb3cgZHJhZ2dpbmcgZXRjLlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlc2VsZWN0IGlmIGl0ZW0gaXMgc2VsZWN0ZWRcbiAgICAgICAgICAvLyBpZiBzaGlmdCBpcyBub3QgY2xpY2tlZCwgdGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gdHJ1ZVxuICAgICAgICAgIC8vIG90aGVyd2lzZSwgaXQgd2lsbCB0cmlnZ2VyIHNlbGVjdGlvbiBiYXNlZCBvbiBjdXJyZW50XG4gICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGJveFxuICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF0pIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBjdXJyZW50bHkgZWRpdGluZyBhIGdyb3VwLCBleGl0aW5nIGVkaXRpbmcgbW9kZSBhbmQgZGVzZWxlY3QgdGhlIGdyb3VwLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgICAgICAgICFpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBoaXQgZWxlbWVudCB0byBzZWxlY3Rpb24uIEF0IHRoaXMgcG9pbnQgaWYgd2UncmUgbm90IGhvbGRpbmdcbiAgICAgICAgICAgIC8vIFNISUZUIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQocykgd2VyZSBkZXNlbGVjdGVkIGFib3ZlXG4gICAgICAgICAgICAvLyAobWFrZSBzdXJlIHlvdSB1c2Ugc2V0U3RhdGUgdXBkYXRlciB0byB1c2UgbGF0ZXN0IHN0YXRlKVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhc29tZUhpdEVsZW1lbnRJc1NlbGVjdGVkICYmXG4gICAgICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIHByaXZhdGUgaXNBU2VsZWN0ZWRFbGVtZW50KGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBoaXRFbGVtZW50ICE9IG51bGwgJiYgdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbaGl0RWxlbWVudC5pZF07XG4gIH1cblxuICBwcml2YXRlIGlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgIHBvaW50OiBSZWFkb25seTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+LFxuICAgIHNlbGVjdGVkRWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10sXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIb3cgbWFueSBwaXhlbHMgb2ZmIHRoZSBzaGFwZSBib3VuZGFyeSB3ZSBzdGlsbCBjb25zaWRlciBhIGhpdFxuICAgIGNvbnN0IHRocmVzaG9sZCA9IDEwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgIGNvbnN0IFt4MSwgeTEsIHgyLCB5Ml0gPSBnZXRDb21tb25Cb3VuZHMoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvaW50LnggPiB4MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueCA8IHgyICsgdGhyZXNob2xkICYmXG4gICAgICBwb2ludC55ID4geTEgLSB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPCB5MiArIHRocmVzaG9sZFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRleHRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIC8vIGlmIHdlJ3JlIGN1cnJlbnRseSBzdGlsbCBlZGl0aW5nIHRleHQsIGNsaWNraW5nIG91dHNpZGVcbiAgICAvLyBzaG91bGQgb25seSBmaW5hbGl6ZSBpdCwgbm90IGNyZWF0ZSBhbm90aGVyIChpcnJlc3BlY3RpdmVcbiAgICAvLyBvZiBzdGF0ZS5lbGVtZW50TG9ja2VkKVxuICAgIGlmIChpc1RleHRFbGVtZW50KHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBzY2VuZVggPSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54O1xuICAgIGxldCBzY2VuZVkgPSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55O1xuXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY2FuQmluZFRleHQgPSBoYXNCb3VuZFRleHRFbGVtZW50KGVsZW1lbnQpO1xuICAgIGlmIChjYW5CaW5kVGV4dCkge1xuICAgICAgc2NlbmVYID0gZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCAvIDI7XG4gICAgICBzY2VuZVkgPSBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCAvIDI7XG4gICAgfVxuICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICBzY2VuZVgsXG4gICAgICBzY2VuZVksXG4gICAgICBzaG91bGRCaW5kOiBmYWxzZSxcbiAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgIH0pO1xuXG4gICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgIGlmICghdGhpcy5zdGF0ZS5lbGVtZW50TG9ja2VkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVGcmVlRHJhd0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3RnJlZURyYXdFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApID0+IHtcbiAgICAvLyBCZWdpbiBhIG1hcmsgY2FwdHVyZS4gVGhpcyBkb2VzIG5vdCBoYXZlIHRvIHVwZGF0ZSBzdGF0ZSB5ZXQuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgIG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdGcmVlRHJhd0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICBzaW11bGF0ZVByZXNzdXJlOiBldmVudC5wcmVzc3VyZSA9PT0gMC41LFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHByZXNzdXJlcyA9IGVsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgPyBlbGVtZW50LnByZXNzdXJlc1xuICAgICAgOiBbLi4uZWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgcG9pbnRzOiBbWzAsIDBdXSxcbiAgICAgIHByZXNzdXJlcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBlbGVtZW50LFxuICAgIF0pO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBzdGFydEJvdW5kRWxlbWVudDogYm91bmRFbGVtZW50LFxuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2VFbGVtZW50ID0gKHtcbiAgICBzY2VuZVgsXG4gICAgc2NlbmVZLFxuICB9OiB7XG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgc2NlbmVZOiBudW1iZXI7XG4gIH0pID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChzY2VuZVgsIHNjZW5lWSwgdGhpcy5zdGF0ZS5ncmlkU2l6ZSk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gbmV3SW1hZ2VFbGVtZW50KHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlTGluZWFyRWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdMaW5lYXJFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aUVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHsgbXVsdGlFbGVtZW50IH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICAvLyBmaW5hbGl6ZSBpZiBjb21wbGV0aW5nIGEgbG9vcFxuICAgICAgaWYgKFxuICAgICAgICBtdWx0aUVsZW1lbnQudHlwZSA9PT0gXCJsaW5lXCIgJiZcbiAgICAgICAgaXNQYXRoQUxvb3AobXVsdGlFbGVtZW50LnBvaW50cywgdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICAgKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OlxuICAgICAgICAgICAgbXVsdGlFbGVtZW50LnBvaW50c1ttdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgeDogcngsIHk6IHJ5LCBsYXN0Q29tbWl0dGVkUG9pbnQgfSA9IG11bHRpRWxlbWVudDtcblxuICAgICAgLy8gY2xpY2tpbmcgaW5zaWRlIGNvbW1pdCB6b25lIOKGkiBmaW5hbGl6ZSBhcnJvd1xuICAgICAgaWYgKFxuICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCA+IDEgJiZcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50ICYmXG4gICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHJ4LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSByeSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMF0sXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgICApIDwgTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgW211bHRpRWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICAvLyBjbGlja2luZyBvdXRzaWRlIGNvbW1pdCB6b25lIOKGkiB1cGRhdGUgcmVmZXJlbmNlIGZvciBsYXN0IGNvbW1pdHRlZFxuICAgICAgLy8gcG9pbnRcbiAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDogbXVsdGlFbGVtZW50LnBvaW50c1ttdWx0aUVsZW1lbnQucG9pbnRzLmxlbmd0aCAtIDFdLFxuICAgICAgfSk7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIC8qIElmIGFycm93IGlzIHByZS1hcnJvd2hlYWRzLCBpdCB3aWxsIGhhdmUgdW5kZWZpbmVkIGZvciBib3RoIHN0YXJ0IGFuZCBlbmQgYXJyb3doZWFkcy5cbiAgICAgIElmIHNvLCB3ZSB3YW50IGl0IHRvIGJlIG51bGwgZm9yIHN0YXJ0IGFuZCBcImFycm93XCIgZm9yIGVuZC4gSWYgdGhlIGxpbmVhciBpdGVtIGlzIG5vdFxuICAgICAgYW4gYXJyb3csIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3IgYm90aC4gT3RoZXJ3aXNlLCB3ZSB3YW50IGl0IHRvIHVzZSB0aGVcbiAgICAgIHZhbHVlcyBmcm9tIGFwcFN0YXRlLiAqL1xuXG4gICAgICBjb25zdCB7IGN1cnJlbnRJdGVtU3RhcnRBcnJvd2hlYWQsIGN1cnJlbnRJdGVtRW5kQXJyb3doZWFkIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgY29uc3QgW3N0YXJ0QXJyb3doZWFkLCBlbmRBcnJvd2hlYWRdID1cbiAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiYXJyb3dcIlxuICAgICAgICAgID8gW2N1cnJlbnRJdGVtU3RhcnRBcnJvd2hlYWQsIGN1cnJlbnRJdGVtRW5kQXJyb3doZWFkXVxuICAgICAgICAgIDogW251bGwsIG51bGxdO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID0gbmV3TGluZWFyRWxlbWVudCh7XG4gICAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgICB4OiBncmlkWCxcbiAgICAgICAgeTogZ3JpZFksXG4gICAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1MaW5lYXJTdHJva2VTaGFycG5lc3MsXG4gICAgICAgIHN0YXJ0QXJyb3doZWFkLFxuICAgICAgICBlbmRBcnJvd2hlYWQsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbZWxlbWVudC5pZF06IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSkpO1xuICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICAgIHBvaW50czogWy4uLmVsZW1lbnQucG9pbnRzLCBbMCwgMF1dLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBib3VuZEVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgKTtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIHN0YXJ0Qm91bmRFbGVtZW50OiBib3VuZEVsZW1lbnQsXG4gICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGNyZWF0ZUdlbmVyaWNFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50W1widHlwZVwiXSxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdFbGVtZW50KHtcbiAgICAgIHR5cGU6IGVsZW1lbnRUeXBlLFxuICAgICAgeDogZ3JpZFgsXG4gICAgICB5OiBncmlkWSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGlvbkVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICBdKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcEZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgLy8gUHJldmVudHMgZm9jdXMgZnJvbSBlc2NhcGluZyBleGNhbGlkcmF3IHRhYlxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLkFMVCAmJiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgLy8gV2UgbmVlZCB0byBpbml0aWFsaXplIGRyYWdPZmZzZXRYWSBvbmx5IGFmdGVyIHdlJ3ZlIHVwZGF0ZWRcbiAgICAgIC8vIGBzdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNgIG9uIHBvaW50ZXJEb3duLiBEb2luZyBpdCBoZXJlIGluIHBvaW50ZXJNb3ZlXG4gICAgICAvLyBldmVudCBoYW5kbGVyIHNob3VsZCBob3BlZnVsbHkgZW5zdXJlIHdlJ3JlIGFscmVhZHkgd29ya2luZyB3aXRoXG4gICAgICAvLyB0aGUgdXBkYXRlZCBzdGF0ZS5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0ID09PSBudWxsKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPSB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgZ2V0RHJhZ09mZnNldFhZKFxuICAgICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIC8vIGZvciBhcnJvd3MvbGluZXMsIGRvbid0IHN0YXJ0IGRyYWdnaW5nIHVudGlsIGEgZ2l2ZW4gdGhyZXNob2xkXG4gICAgICAvLyB0byBlbnN1cmUgd2UgZG9uJ3QgY3JlYXRlIGEgMi1wb2ludCBhcnJvdyBieSBtaXN0YWtlIHdoZW5cbiAgICAgIC8vIHVzZXIgY2xpY2tzIG1vdXNlIGluIGEgd2F5IHRoYXQgaXQgbW92ZXMgYSB0aW55IGJpdCAodGh1c1xuICAgICAgLy8gdHJpZ2dlcmluZyBwb2ludGVybW92ZSlcbiAgICAgIGlmIChcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJsaW5lXCIpXG4gICAgICApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApIDwgRFJBR0dJTkdfVEhSRVNIT0xEXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaXNSZXNpemluZykge1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IHBvaW50ZXJDb29yZHMueDtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgIGlmICh0aGlzLm1heWJlSGFuZGxlUmVzaXplKHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRpZERyYWcgPSBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZVBvaW50RHJhZ2dpbmcoXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAoYXBwU3RhdGUpID0+IHRoaXMuc2V0U3RhdGUoYXBwU3RhdGUpLFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgICAgKGVsZW1lbnQsIHBvaW50c1NjZW5lQ29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzKFxuICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICBwb2ludHNTY2VuZUNvb3JkcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZGlkRHJhZykge1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBoYXNIaXRBU2VsZWN0ZWRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuYWxsSGl0RWxlbWVudHMuc29tZShcbiAgICAgICAgKGVsZW1lbnQpID0+IHRoaXMuaXNBU2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpLFxuICAgICAgKTtcblxuICAgICAgaWYgKFxuICAgICAgICAoaGFzSGl0QVNlbGVjdGVkRWxlbWVudCB8fFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKSAmJlxuICAgICAgICAvLyB0aGlzIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgd2hlbiBjbGlja2luZyBpbnNpZGUgdGhlXG4gICAgICAgIC8vIGxpbmUncyBib3VuZGluZyBib3hcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8ICFldmVudC5zaGlmdEtleSkgJiZcbiAgICAgICAgLy8gYm94LXNlbGVjdGluZyB3aXRob3V0IHNoaWZ0IHdoZW4gZWRpdGluZyBsaW5lLCBub3QgY2xpY2tpbmcgb24gYSBsaW5lXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQ/LmVsZW1lbnRJZCAhPT1cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQ/LmlkIHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSlcbiAgICAgICkge1xuICAgICAgICAvLyBNYXJraW5nIHRoYXQgY2xpY2sgd2FzIHVzZWQgZm9yIGRyYWdnaW5nIHRvIGNoZWNrXG4gICAgICAgIC8vIGlmIGVsZW1lbnRzIHNob3VsZCBiZSBkZXNlbGVjdGVkIG9uIHBvaW50ZXJ1cFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgLy8gcHJldmVudCBkcmFnZ2luZyBldmVuIGlmIHdlJ3JlIG5vIGxvbmdlciBob2xkaW5nIGNtZC9jdHJsIG90aGVyd2lzZVxuICAgICAgICAvLyBpdCB3b3VsZCBoYXZlIHdlaXJkIHJlc3VsdHMgKHN0dWZmIGp1bXBpbmcgYWxsIG92ZXIgdGhlIHNjcmVlbilcbiAgICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID4gMCAmJiAhcG9pbnRlckRvd25TdGF0ZS53aXRoQ21kT3JDdHJsKSB7XG4gICAgICAgICAgY29uc3QgW2RyYWdYLCBkcmFnWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LngsXG4gICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBbZHJhZ0Rpc3RhbmNlWCwgZHJhZ0Rpc3RhbmNlWV0gPSBbXG4gICAgICAgICAgICBNYXRoLmFicyhwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54KSxcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkpLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICAvLyBXZSBvbmx5IGRyYWcgaW4gb25lIGRpcmVjdGlvbiBpZiBzaGlmdCBpcyBwcmVzc2VkXG4gICAgICAgICAgY29uc3QgbG9ja0RpcmVjdGlvbiA9IGV2ZW50LnNoaWZ0S2V5O1xuXG4gICAgICAgICAgZHJhZ1NlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdYLFxuICAgICAgICAgICAgZHJhZ1ksXG4gICAgICAgICAgICBsb2NrRGlyZWN0aW9uLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWCxcbiAgICAgICAgICAgIGRyYWdEaXN0YW5jZVksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoc2VsZWN0ZWRFbGVtZW50cyk7XG5cbiAgICAgICAgICAvLyBXZSBkdXBsaWNhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQgaWYgYWx0IGlzIHByZXNzZWQgb24gcG9pbnRlciBtb3ZlXG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzQmVlbkR1cGxpY2F0ZWQpIHtcbiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBlbGVtZW50cyB0byB0aGUgdG9wIG9mIHRoZSB6IGluZGV4IHN0YWNrLCBhbmRcbiAgICAgICAgICAgIC8vIHB1dCB0aGUgZHVwbGljYXRlcyB3aGVyZSB0aGUgc2VsZWN0ZWQgZWxlbWVudHMgdXNlZCB0byBiZS5cbiAgICAgICAgICAgIC8vICh0aGUgb3JpZ2luIHBvaW50IHdoZXJlIHRoZSBkcmFnZ2luZyBzdGFydGVkKVxuXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IG5leHRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHNUb0FwcGVuZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBJZE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudElkczogQXJyYXk8RXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXT4gPVxuICAgICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKGVsZW1lbnRzLCB0aGlzLnN0YXRlLCB0cnVlKS5tYXAoXG4gICAgICAgICAgICAgICAgKGVsZW1lbnQpID0+IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzLmluY2x1ZGVzKGVsZW1lbnQuaWQpIHx8XG4gICAgICAgICAgICAgICAgLy8gY2FzZTogdGhlIHN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyBtaWdodCBub3QgaGF2ZSBiZWVuXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlZCB5ZXQgYnkgdGhlIHRpbWUgdGhpcyBtb3VzZW1vdmUgZXZlbnQgaXMgZmlyZWRcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5pZCA9PT0gaGl0RWxlbWVudD8uaWQgJiZcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24pXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZWRFbGVtZW50ID0gZHVwbGljYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQsXG4gICAgICAgICAgICAgICAgICBncm91cElkTWFwLFxuICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvcmlnaW5EcmFnWCwgb3JpZ2luRHJhZ1ldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnkgLSBwb2ludGVyRG93blN0YXRlLmRyYWcub2Zmc2V0LnksXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChkdXBsaWNhdGVkRWxlbWVudCwge1xuICAgICAgICAgICAgICAgICAgeDogZHVwbGljYXRlZEVsZW1lbnQueCArIChvcmlnaW5EcmFnWCAtIGRyYWdYKSxcbiAgICAgICAgICAgICAgICAgIHk6IGR1cGxpY2F0ZWRFbGVtZW50LnkgKyAob3JpZ2luRHJhZ1kgLSBkcmFnWSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZHVwbGljYXRlZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBkdXBsaWNhdGVkRWxlbWVudC5pZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5leHRTY2VuZUVsZW1lbnRzID0gWy4uLm5leHRFbGVtZW50cywgLi4uZWxlbWVudHNUb0FwcGVuZF07XG4gICAgICAgICAgICBiaW5kVGV4dFRvU2hhcGVBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0RWxlbWVudHMsXG4gICAgICAgICAgICAgIGVsZW1lbnRzVG9BcHBlbmQsXG4gICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uKFxuICAgICAgICAgICAgICBuZXh0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICAgXCJkdXBsaWNhdGVzU2VydmVBc09sZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRTY2VuZUVsZW1lbnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIHJlYWQgdGhpcy5zdGF0ZSB3aXRoaW4gZWFjaCBtb3ZlIGV2ZW50LFxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIHdvdWxkIHJlYWQgYSBzdGFsZSBvbmUhXG4gICAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudC50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgY29uc3QgZHggPSBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgY29uc3QgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlc1xuICAgICAgICAgIDogWy4uLmRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXMsIGV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IGdyaWRYIC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IGdyaWRZIC0gZHJhZ2dpbmdFbGVtZW50Lnk7XG5cbiAgICAgICAgaWYgKHNob3VsZFJvdGF0ZVdpdGhEaXNjcmV0ZUFuZ2xlKGV2ZW50KSAmJiBwb2ludHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgKHsgd2lkdGg6IGR4LCBoZWlnaHQ6IGR5IH0gPSBnZXRQZXJmZWN0RWxlbWVudFNpemUoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICAgICAgZHgsXG4gICAgICAgICAgICBkeSxcbiAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQsIHsgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0gfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLnNsaWNlKDAsIC0xKSwgW2R4LCBkeV1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICAgIC8vIFdoZW4gY3JlYXRpbmcgYSBsaW5lYXIgZWxlbWVudCBieSBkcmFnZ2luZ1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBbcG9pbnRlckNvb3Jkc10sXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnN0YXJ0Qm91bmRFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFldmVudC5zaGlmdEtleSAmJlxuICAgICAgICAgIC8vIGFsbG93cyBmb3IgYm94LXNlbGVjdGluZyBwb2ludHMgKHdpdGhvdXQgc2hpZnQpXG4gICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQoZWxlbWVudHMsIHRoaXMuc3RhdGUpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwgJiYgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYm94LXNlbGVjdCBsaW5lIGVkaXRvciBwb2ludHNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICBMaW5lYXJFbGVtZW50RWRpdG9yLmhhbmRsZUJveFNlbGVjdGlvbihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUuYmluZCh0aGlzKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHJlZ3VsYXIgYm94LXNlbGVjdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzV2l0aGluU2VsZWN0aW9uID0gZ2V0RWxlbWVudHNXaXRoaW5TZWxlY3Rpb24oXG4gICAgICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ucmVkdWNlKChtYXAsIGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbWFwW2VsZW1lbnQuaWRdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgICAgICAgICAgICAgIH0sIHt9IGFzIGFueSksXG4gICAgICAgICAgICAgICAgICAuLi4ocG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHVzaW5nIGN0cmwvY21kLCBzZWxlY3QgdGhlIGhpdEVsZW1lbnQgb25seSBpZiB3ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGF2ZW4ndCBib3gtc2VsZWN0ZWQgYW55dGhpbmcgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUuaGl0LmVsZW1lbnQuaWRdOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAhZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgOiBudWxsKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgd2hldGhlciB0aGUgcG9pbnRlciBtb3ZlIGhhcHBlbmVkIG92ZXIgZWl0aGVyIHNjcm9sbGJhclxuICBwcml2YXRlIGhhbmRsZVBvaW50ZXJNb3ZlT3ZlclNjcm9sbGJhcnMoXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAocG9pbnRlckRvd25TdGF0ZS5zY3JvbGxiYXJzLmlzT3Zlckhvcml6b250YWwpIHtcbiAgICAgIGNvbnN0IHggPSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZHggPSB4IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLng7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZHggLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0geDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVyVmVydGljYWwpIHtcbiAgICAgIGNvbnN0IHkgPSBldmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgZHkgPSB5IC0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZIC0gZHkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0geTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlclVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4gdm9pZCB7XG4gICAgcmV0dXJuIHdpdGhCYXRjaGVkVXBkYXRlcygoY2hpbGRFdmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50LFxuICAgICAgICBtdWx0aUVsZW1lbnQsXG4gICAgICAgIGVsZW1lbnRUeXBlLFxuICAgICAgICBlbGVtZW50TG9ja2VkLFxuICAgICAgICBpc1Jlc2l6aW5nLFxuICAgICAgICBpc1JvdGF0aW5nLFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgaXNSb3RhdGluZzogZmFsc2UsXG4gICAgICAgIHJlc2l6aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogbnVsbCxcbiAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIC8vIHRleHQgZWxlbWVudHMgYXJlIHJlc2V0IG9uIGZpbmFsaXplLCBhbmQgcmVzZXR0aW5nIG9uIHBvaW50ZXJ1cFxuICAgICAgICAvLyBtYXkgY2F1c2UgaXNzdWVzIHdpdGggZG91YmxlIHRhcHNcbiAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgbXVsdGlFbGVtZW50IHx8IGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgICAgID8gdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudFxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2F2ZVBvaW50ZXIoY2hpbGRFdmVudC5jbGllbnRYLCBjaGlsZEV2ZW50LmNsaWVudFksIFwidXBcIik7XG5cbiAgICAgIC8vIEhhbmRsZSBlbmQgb2YgZHJhZ2dpbmcgYSBwb2ludCBvZiBhIGxpbmVhciBlbGVtZW50LCBtaWdodCBjbG9zZSBhIGxvb3BcbiAgICAgIC8vIGFuZCBzZXRzIGJpbmRpbmcgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZCAmJlxuICAgICAgICAgIChwb2ludGVyRG93blN0YXRlLmhpdD8uZWxlbWVudD8uaWQgIT09XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCB8fFxuICAgICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdEVsZW1lbnRJbnNpZGUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlZGl0aW5nTGluZWFyRWxlbWVudCA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnRlclVwKFxuICAgICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfTU9WRSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ldmVudExpc3RlbmVycy5vbk1vdmUhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5QT0lOVEVSX1VQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAhLFxuICAgICAgKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5LRVlET1dOLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWVVQLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5VXAhLFxuICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgcGVuZGluZ0ltYWdlRWxlbWVudDogbnVsbCB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudD8udHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IGRyYWdnaW5nRWxlbWVudC5wb2ludHM7XG4gICAgICAgIGxldCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBsZXQgZHkgPSBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICAvLyBBbGxvd3MgZG90cyB0byBhdm9pZCBiZWluZyBmbGFnZ2VkIGFzIGluZmluaXRlbHkgc21hbGxcbiAgICAgICAgaWYgKGR4ID09PSBwb2ludHNbMF1bMF0gJiYgZHkgPT09IHBvaW50c1swXVsxXSkge1xuICAgICAgICAgIGR5ICs9IDAuMDAwMTtcbiAgICAgICAgICBkeCArPSAwLjAwMDE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzc3VyZXMgPSBkcmFnZ2luZ0VsZW1lbnQuc2ltdWxhdGVQcmVzc3VyZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IFsuLi5kcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzLCBjaGlsZEV2ZW50LnByZXNzdXJlXTtcblxuICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW2R4LCBkeV1dLFxuICAgICAgICAgIHByZXNzdXJlcyxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6IFtkeCwgZHldLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGlzSW1hZ2VFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICB7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSBpbWFnZUVsZW1lbnQuaWQpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGluZWFyRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQhLnBvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgY2hpbGRFdmVudCxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgICAgIW11bHRpRWxlbWVudFxuICAgICAgICApIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwge1xuICAgICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAgIC4uLmRyYWdnaW5nRWxlbWVudC5wb2ludHMsXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnggLSBkcmFnZ2luZ0VsZW1lbnQueCxcbiAgICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLnkgLSBkcmFnZ2luZ0VsZW1lbnQueSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQ6IGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiYgIW11bHRpRWxlbWVudCkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgICAgICAgIGlzQmluZGluZ0VsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSwgc3RhcnRCb3VuZEVsZW1lbnQ6IG51bGwgfSk7XG4gICAgICAgICAgaWYgKCFlbGVtZW50TG9ja2VkKSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW3RoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFt0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIgJiZcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50ICYmXG4gICAgICAgIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KGRyYWdnaW5nRWxlbWVudClcbiAgICAgICkge1xuICAgICAgICAvLyByZW1vdmUgaW52aXNpYmxlIGVsZW1lbnQgd2hpY2ggd2FzIGFkZGVkIGluIG9uUG9pbnRlckRvd25cbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5zbGljZSgwLCAtMSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgICBtdXRhdGVFbGVtZW50KFxuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICBnZXROb3JtYWxpemVkRGltZW5zaW9ucyhkcmFnZ2luZ0VsZW1lbnQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc2l6aW5nRWxlbWVudCAmJiBpc0ludmlzaWJseVNtYWxsRWxlbWVudChyZXNpemluZ0VsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgLmZpbHRlcigoZWwpID0+IGVsLmlkICE9PSByZXNpemluZ0VsZW1lbnQuaWQpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb2RlIGJlbG93IGhhbmRsZXMgc2VsZWN0aW9uIHdoZW4gZWxlbWVudChzKSB3ZXJlbid0XG4gICAgICAvLyBkcmFnIG9yIGFkZGVkIHRvIHNlbGVjdGlvbiBvbiBwb2ludGVyIGRvd24gcGhhc2UuXG4gICAgICBjb25zdCBoaXRFbGVtZW50ID0gcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudDtcbiAgICAgIGlmIChcbiAgICAgICAgaGl0RWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uICYmXG4gICAgICAgIC8vIGlmIHdlJ3JlIGVkaXRpbmcgYSBsaW5lLCBwb2ludGVydXAgc2hvdWxkbid0IHN3aXRjaCBzZWxlY3Rpb24gaWZcbiAgICAgICAgLy8gYm94IHNlbGVjdGVkXG4gICAgICAgICghdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCB8fFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmJveFNlbGVjdGlvbi5oYXNPY2N1cnJlZClcbiAgICAgICkge1xuICAgICAgICAvLyB3aGVuIGluc2lkZSBsaW5lIGVkaXRvciwgc2hpZnQgc2VsZWN0cyBwb2ludHMgaW5zdGVhZFxuICAgICAgICBpZiAoY2hpbGRFdmVudC5zaGlmdEtleSAmJiAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSkge1xuICAgICAgICAgICAgaWYgKGlzU2VsZWN0ZWRWaWFHcm91cCh0aGlzLnN0YXRlLCBoaXRFbGVtZW50KSkge1xuICAgICAgICAgICAgICAvLyBXZSB3YW50IHRvIHVuc2VsZWN0IGFsbCBncm91cHMgaGl0RWxlbWVudCBpcyBwYXJ0IG9mXG4gICAgICAgICAgICAgIC8vIGFzIHdlbGwgYXMgYWxsIGVsZW1lbnRzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGdyb3Vwc1xuICAgICAgICAgICAgICAvLyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgY29uc3QgaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzID0gaGl0RWxlbWVudC5ncm91cElkc1xuICAgICAgICAgICAgICAgIC5mbGF0TWFwKChncm91cElkKSA9PlxuICAgICAgICAgICAgICAgICAgZ2V0RWxlbWVudHNJbkdyb3VwKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgZ3JvdXBJZCksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5tYXAoKGVsZW1lbnQpID0+ICh7IFtlbGVtZW50LmlkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldklkLCBhY2MpID0+ICh7IC4uLnByZXZJZCwgLi4uYWNjIH0pLCB7fSk7XG5cbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgoX3ByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgIC4uLmhpdEVsZW1lbnQuZ3JvdXBJZHNcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZ0lkKSA9PiAoeyBbZ0lkXTogZmFsc2UgfSkpXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoKHByZXYsIGFjYykgPT4gKHsgLi4ucHJldiwgLi4uYWNjIH0pLCB7fSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaWRzT2ZTZWxlY3RlZEVsZW1lbnRzVGhhdEFyZUluR3JvdXBzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHdoaWxlXG4gICAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBhZGQgZWxlbWVudCB0byBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgIC8vIGtlZXBpbmcgcHJldiBlbGVtZW50cyBzZWxlY3RlZFxuXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAuLi5fcHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbaGl0RWxlbWVudCEuaWRdOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAuLi5zZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogeyBbaGl0RWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICF0aGlzLnN0YXRlLmlzUmVzaXppbmcgJiZcbiAgICAgICAgKChoaXRFbGVtZW50ICYmXG4gICAgICAgICAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50KFxuICAgICAgICAgICAgaGl0RWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApKSB8fFxuICAgICAgICAgICghaGl0RWxlbWVudCAmJlxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpKVxuICAgICAgKSB7XG4gICAgICAgIC8vIERlc2VsZWN0IHNlbGVjdGVkIGVsZW1lbnRzXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50TG9ja2VkICYmIGVsZW1lbnRUeXBlICE9PSBcImZyZWVkcmF3XCIgJiYgZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICBbZHJhZ2dpbmdFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIgfHxcbiAgICAgICAgaXNTb21lRWxlbWVudFNlbGVjdGVkKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgdGhpcy5zdGF0ZSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgfHwgaXNSZXNpemluZyB8fCBpc1JvdGF0aW5nKSB7XG4gICAgICAgIChpc0JpbmRpbmdFbmFibGVkKHRoaXMuc3RhdGUpXG4gICAgICAgICAgPyBiaW5kT3JVbmJpbmRTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cykoXG4gICAgICAgICAgZ2V0U2VsZWN0ZWRFbGVtZW50cyh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnRMb2NrZWQgJiYgZWxlbWVudFR5cGUgIT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZSA9IGFzeW5jICh7XG4gICAgaW1hZ2VGaWxlLFxuICAgIGltYWdlRWxlbWVudDogX2ltYWdlRWxlbWVudCxcbiAgICBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ID0gZmFsc2UsXG4gIH06IHtcbiAgICBpbWFnZUZpbGU6IEZpbGU7XG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50O1xuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgLy8gYXQgdGhpcyBwb2ludCB0aGlzIHNob3VsZCBiZSBndWFyYW50ZWVkIGltYWdlIGZpbGUsIGJ1dCB3ZSBkbyB0aGlzIGNoZWNrXG4gICAgLy8gdG8gc2F0aXNmeSBUUyBkb3duIHRoZSBsaW5lXG4gICAgaWYgKCFpc1N1cHBvcnRlZEltYWdlRmlsZShpbWFnZUZpbGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy51bnN1cHBvcnRlZEZpbGVUeXBlXCIpKTtcbiAgICB9XG4gICAgY29uc3QgbWltZVR5cGUgPSBpbWFnZUZpbGUudHlwZTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgXCJ3YWl0XCIpO1xuXG4gICAgaWYgKG1pbWVUeXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gU1ZHU3RyaW5nVG9GaWxlKFxuICAgICAgICAgIGF3YWl0IG5vcm1hbGl6ZVNWRyhhd2FpdCBpbWFnZUZpbGUudGV4dCgpKSxcbiAgICAgICAgICBpbWFnZUZpbGUubmFtZSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuc3ZnSW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZ2VuZXJhdGUgaW1hZ2UgaWQgKGJ5IGRlZmF1bHQgdGhlIGZpbGUgZGlnZXN0KSBiZWZvcmUgYW55XG4gICAgLy8gcmVzaXppbmcvY29tcHJlc3Npb24gdGFrZXMgcGxhY2UgdG8ga2VlcCBpdCBtb3JlIHBvcnRhYmxlXG4gICAgY29uc3QgZmlsZUlkID0gYXdhaXQgKCh0aGlzLnByb3BzLmdlbmVyYXRlSWRGb3JGaWxlPy4oXG4gICAgICBpbWFnZUZpbGUsXG4gICAgKSBhcyBQcm9taXNlPEZpbGVJZD4pIHx8IGdlbmVyYXRlSWRGcm9tRmlsZShpbWFnZUZpbGUpKTtcblxuICAgIGlmICghZmlsZUlkKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiQ291bGRuJ3QgZ2VuZXJhdGUgZmlsZSBpZCBvciB0aGUgc3VwcGxpZWQgYGdlbmVyYXRlSWRGb3JGaWxlYCBkaWRuJ3QgcmVzb2x2ZSB0byBvbmUuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoXCJlcnJvcnMuaW1hZ2VJbnNlcnRFcnJvclwiKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdGaWxlRGF0YSA9IHRoaXMuZmlsZXNbZmlsZUlkXTtcbiAgICBpZiAoIWV4aXN0aW5nRmlsZURhdGE/LmRhdGFVUkwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGltYWdlRmlsZSA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgICAgICBtYXhXaWR0aE9ySGVpZ2h0OiBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiZXJyb3IgdHJ5aW5nIHRvIHJlc2luZyBpbWFnZSBmaWxlIG9uIGluc2VydGlvblwiLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZUZpbGUuc2l6ZSA+IE1BWF9BTExPV0VEX0ZJTEVfQllURVMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIHQoXCJlcnJvcnMuZmlsZVRvb0JpZ1wiLCB7XG4gICAgICAgICAgICBtYXhTaXplOiBgJHtNYXRoLnRydW5jKE1BWF9BTExPV0VEX0ZJTEVfQllURVMgLyAxMDI0IC8gMTAyNCl9TUJgLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICBjb25zdCBkYXRhVVJMID0gdGhpcy5maWxlc1tmaWxlSWRdPy5kYXRhVVJMO1xuICAgICAgLy8gb3B0aW1pemF0aW9uIHNvIHRoYXQgd2UgZG9uJ3QgdW5uZWNlc3NhcmlseSByZXNpemUgdGhlIG9yaWdpbmFsXG4gICAgICAvLyBmdWxsLXNpemUgZmlsZSBmb3IgY3Vyc29yIHByZXZpZXdcbiAgICAgIC8vIChpdCdzIG11Y2ggZmFzdGVyIHRvIGNvbnZlcnQgdGhlIHJlc2l6ZWQgZGF0YVVSTCB0byBGaWxlKVxuICAgICAgY29uc3QgcmVzaXplZEZpbGUgPSBkYXRhVVJMICYmIGRhdGFVUkxUb0ZpbGUoZGF0YVVSTCk7XG5cbiAgICAgIHRoaXMuc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yKHJlc2l6ZWRGaWxlIHx8IGltYWdlRmlsZSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YVVSTCA9XG4gICAgICB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkwgfHwgKGF3YWl0IGdldERhdGFVUkwoaW1hZ2VGaWxlKSk7XG5cbiAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSBtdXRhdGVFbGVtZW50KFxuICAgICAgX2ltYWdlRWxlbWVudCxcbiAgICAgIHtcbiAgICAgICAgZmlsZUlkLFxuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICkgYXMgTm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+O1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE5vbkRlbGV0ZWQ8SW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50Pj4oXG4gICAgICBhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5maWxlcyA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMuZmlsZXMsXG4gICAgICAgICAgICBbZmlsZUlkXToge1xuICAgICAgICAgICAgICBtaW1lVHlwZSxcbiAgICAgICAgICAgICAgaWQ6IGZpbGVJZCxcbiAgICAgICAgICAgICAgZGF0YVVSTCxcbiAgICAgICAgICAgICAgY3JlYXRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjYWNoZWRJbWFnZURhdGEgPSB0aGlzLmltYWdlQ2FjaGUuZ2V0KGZpbGVJZCk7XG4gICAgICAgICAgaWYgKCFjYWNoZWRJbWFnZURhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUltYWdlQ2FjaGUoW2ltYWdlRWxlbWVudF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2FjaGVkSW1hZ2VEYXRhPy5pbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIGF3YWl0IGNhY2hlZEltYWdlRGF0YS5pbWFnZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudD8uaWQgIT09IGltYWdlRWxlbWVudC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgaWYgKCFzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3KSB7XG4gICAgICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGluc2VydHMgaW1hZ2UgaW50byBlbGVtZW50cyBhcnJheSBhbmQgcmVyZW5kZXJzXG4gICAqL1xuICBwcml2YXRlIGluc2VydEltYWdlRWxlbWVudCA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gICAgaW1hZ2VGaWxlOiBGaWxlLFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXc/OiBib29sZWFuLFxuICApID0+IHtcbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgaW1hZ2VFbGVtZW50LFxuICAgIF0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUltYWdlKHtcbiAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICBpbWFnZUVsZW1lbnQsXG4gICAgICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICBpc0RlbGV0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfHwgdChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc2V0SW1hZ2VQcmV2aWV3Q3Vyc29yID0gYXN5bmMgKGltYWdlRmlsZTogRmlsZSkgPT4ge1xuICAgIC8vIG11c3RuJ3QgYmUgbGFyZ2VyIHRoYW4gMTI4IHB4XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19CYXNpY19Vc2VyX0ludGVyZmFjZS9Vc2luZ19VUkxfdmFsdWVzX2Zvcl90aGVfY3Vyc29yX3Byb3BlcnR5XG4gICAgY29uc3QgY3Vyc29ySW1hZ2VTaXplUHggPSA5NjtcblxuICAgIGNvbnN0IGltYWdlUHJldmlldyA9IGF3YWl0IHJlc2l6ZUltYWdlRmlsZShpbWFnZUZpbGUsIHtcbiAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IGN1cnNvckltYWdlU2l6ZVB4LFxuICAgIH0pO1xuXG4gICAgbGV0IHByZXZpZXdEYXRhVVJMID0gYXdhaXQgZ2V0RGF0YVVSTChpbWFnZVByZXZpZXcpO1xuXG4gICAgLy8gU1ZHIGNhbm5vdCBiZSByZXNpemVkIHZpYSBgcmVzaXplSW1hZ2VGaWxlYCBzbyB3ZSByZXNpemUgYnkgcmVuZGVyaW5nIHRvXG4gICAgLy8gYSBzbWFsbCBjYW52YXNcbiAgICBpZiAoaW1hZ2VGaWxlLnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICBjb25zdCBpbWcgPSBhd2FpdCBsb2FkSFRNTEltYWdlRWxlbWVudChwcmV2aWV3RGF0YVVSTCk7XG5cbiAgICAgIGxldCBoZWlnaHQgPSBNYXRoLm1pbihpbWcuaGVpZ2h0LCBjdXJzb3JJbWFnZVNpemVQeCk7XG4gICAgICBsZXQgd2lkdGggPSBoZWlnaHQgKiAoaW1nLndpZHRoIC8gaW1nLmhlaWdodCk7XG5cbiAgICAgIGlmICh3aWR0aCA+IGN1cnNvckltYWdlU2l6ZVB4KSB7XG4gICAgICAgIHdpZHRoID0gY3Vyc29ySW1hZ2VTaXplUHg7XG4gICAgICAgIGhlaWdodCA9IHdpZHRoICogKGltZy5oZWlnaHQgLyBpbWcud2lkdGgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuXG4gICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBwcmV2aWV3RGF0YVVSTCA9IGNhbnZhcy50b0RhdGFVUkwoTUlNRV9UWVBFUy5zdmcpIGFzIERhdGFVUkw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCkge1xuICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBgdXJsKCR7cHJldmlld0RhdGFVUkx9KSA0IDQsIGF1dG9gKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvbkltYWdlQWN0aW9uID0gYXN5bmMgKFxuICAgIHsgaW5zZXJ0T25DYW52YXNEaXJlY3RseSB9ID0geyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5OiBmYWxzZSB9LFxuICApID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY2xpZW50WCA9IHRoaXMuc3RhdGUud2lkdGggLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0O1xuICAgICAgY29uc3QgY2xpZW50WSA9IHRoaXMuc3RhdGUuaGVpZ2h0IC8gMiArIHRoaXMuc3RhdGUub2Zmc2V0VG9wO1xuXG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgeyBjbGllbnRYLCBjbGllbnRZIH0sXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZUZpbGUgPSBhd2FpdCBmaWxlT3Blbih7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkltYWdlXCIsXG4gICAgICAgIGV4dGVuc2lvbnM6IFtcImpwZ1wiLCBcInBuZ1wiLCBcInN2Z1wiLCBcImdpZlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7XG4gICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgc2NlbmVZOiB5LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChpbnNlcnRPbkNhbnZhc0RpcmVjdGx5KSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgaW1hZ2VGaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgcGVuZGluZ0ltYWdlRWxlbWVudDogaW1hZ2VFbGVtZW50LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoXG4gICAgICAgICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgICAgICAgaW1hZ2VGaWxlLFxuICAgICAgICAgICAgICAvKiBzaG93Q3Vyc29ySW1hZ2VQcmV2aWV3ICovIHRydWUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgaWYgKGVycm9yLm5hbWUgIT09IFwiQWJvcnRFcnJvclwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVkaXRpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zID0gKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBmb3JjZU5hdHVyYWxTaXplID0gZmFsc2UsXG4gICkgPT4ge1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50KSAmJlxuICAgICAgdGhpcy5pbWFnZUNhY2hlLmdldChpbWFnZUVsZW1lbnQuZmlsZUlkKT8uaW1hZ2U7XG5cbiAgICBpZiAoIWltYWdlIHx8IGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpbWFnZUVsZW1lbnQud2lkdGggPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUgJiZcbiAgICAgICAgaW1hZ2VFbGVtZW50LmhlaWdodCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyU2l6ZSA9IDEwMCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZTtcbiAgICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgICB4OiBpbWFnZUVsZW1lbnQueCAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgeTogaW1hZ2VFbGVtZW50LnkgLSBwbGFjZWhvbGRlclNpemUgLyAyLFxuICAgICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgICAgaGVpZ2h0OiBwbGFjZWhvbGRlclNpemUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgZm9yY2VOYXR1cmFsU2l6ZSB8fFxuICAgICAgLy8gaWYgdXNlci1jcmVhdGVkIGJvdW5kaW5nIGJveCBpcyBiZWxvdyB0aHJlc2hvbGQsIGFzc3VtZSB0aGVcbiAgICAgIC8vIGludGVudGlvbiB3YXMgdG8gY2xpY2sgaW5zdGVhZCBvZiBkcmFnLCBhbmQgdXNlIHRoZSBpbWFnZSdzXG4gICAgICAvLyBpbnRyaW5zaWMgc2l6ZVxuICAgICAgKGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5oZWlnaHQgLSAxMjAsIDE2MCk7XG4gICAgICAvLyBtYXggNjUlIG9mIGNhbnZhcyBoZWlnaHQsIGNsYW1wZWQgdG8gPDMwMHB4LCB2aCAtIDEyMHB4PlxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICAgIG1pbkhlaWdodCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnN0YXRlLmhlaWdodCAqIDAuNSkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihpbWFnZS5uYXR1cmFsSGVpZ2h0LCBtYXhIZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBoZWlnaHQgKiAoaW1hZ2UubmF0dXJhbFdpZHRoIC8gaW1hZ2UubmF0dXJhbEhlaWdodCk7XG5cbiAgICAgIC8vIGFkZCBjdXJyZW50IGltYWdlRWxlbWVudCB3aWR0aC9oZWlnaHQgdG8gYWNjb3VudCBmb3IgcHJldmlvdXMgY2VudGVyaW5nXG4gICAgICAvLyBvZiB0aGUgcGxhY2hvbGRlciBpbWFnZVxuICAgICAgY29uc3QgeCA9IGltYWdlRWxlbWVudC54ICsgaW1hZ2VFbGVtZW50LndpZHRoIC8gMiAtIHdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHkgPSBpbWFnZUVsZW1lbnQueSArIGltYWdlRWxlbWVudC5oZWlnaHQgLyAyIC0gaGVpZ2h0IC8gMjtcblxuICAgICAgbXV0YXRlRWxlbWVudChpbWFnZUVsZW1lbnQsIHsgeCwgeSwgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIHVwZGF0ZXMgaW1hZ2UgY2FjaGUsIHJlZnJlc2hpbmcgdXBkYXRlZCBlbGVtZW50cyBhbmQvb3Igc2V0dGluZyBzdGF0dXNcbiAgICAgIHRvIGVycm9yIGZvciBpbWFnZXMgdGhhdCBmYWlsIGR1cmluZyA8aW1nPiBlbGVtZW50IGNyZWF0aW9uICovXG4gIHByaXZhdGUgdXBkYXRlSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBlbGVtZW50czogcmVhZG9ubHkgSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10sXG4gICAgZmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH0gPSBhd2FpdCBfdXBkYXRlSW1hZ2VDYWNoZSh7XG4gICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICBmaWxlSWRzOiBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IGVsZW1lbnQuZmlsZUlkKSxcbiAgICAgIGZpbGVzLFxuICAgIH0pO1xuICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSB8fCBlcnJvcmVkRmlsZXMuc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgIGlmICh1cGRhdGVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKSkge1xuICAgICAgICAgIGludmFsaWRhdGVTaGFwZUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKS5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgICBlcnJvcmVkRmlsZXMuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld0VsZW1lbnRXaXRoKGVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB1cGRhdGVkRmlsZXMsIGVycm9yZWRGaWxlcyB9O1xuICB9O1xuXG4gIC8qKiBhZGRzIG5ldyBpbWFnZXMgdG8gaW1hZ2VDYWNoZSBhbmQgcmUtcmVuZGVycyBpZiBuZWVkZWQgKi9cbiAgcHJpdmF0ZSBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUgPSBhc3luYyAoXG4gICAgaW1hZ2VFbGVtZW50czogSW5pdGlhbGl6ZWRFeGNhbGlkcmF3SW1hZ2VFbGVtZW50W10gPSBnZXRJbml0aWFsaXplZEltYWdlRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgKSxcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgPSB0aGlzLmZpbGVzLFxuICApID0+IHtcbiAgICBjb25zdCB1bmNhY2hlZEltYWdlRWxlbWVudHMgPSBpbWFnZUVsZW1lbnRzLmZpbHRlcihcbiAgICAgIChlbGVtZW50KSA9PiAhZWxlbWVudC5pc0RlbGV0ZWQgJiYgIXRoaXMuaW1hZ2VDYWNoZS5oYXMoZWxlbWVudC5maWxlSWQpLFxuICAgICk7XG5cbiAgICBpZiAodW5jYWNoZWRJbWFnZUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29uc3QgeyB1cGRhdGVkRmlsZXMgfSA9IGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShcbiAgICAgICAgdW5jYWNoZWRJbWFnZUVsZW1lbnRzLFxuICAgICAgICBmaWxlcyxcbiAgICAgICk7XG4gICAgICBpZiAodXBkYXRlZEZpbGVzLnNpemUpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5pbmZvcm1NdXRhdGlvbigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKiogZ2VuZXJhbGx5IHlvdSBzaG91bGQgdXNlIGBhZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKWAgZGlyZWN0bHkgaWYgeW91IG5lZWRcbiAgICogIHRvIHJlbmRlciBuZXcgaW1hZ2VzLiBUaGlzIGlzIGp1c3QgYSBmYWlsc2FmZSAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZUltYWdlUmVmcmVzaCA9IHRocm90dGxlKCgpID0+IHtcbiAgICB0aGlzLmFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpO1xuICB9LCBJTUFHRV9SRU5ERVJfVElNRU9VVCk7XG5cbiAgcHJpdmF0ZSB1cGRhdGVCaW5kaW5nRW5hYmxlZE9uUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGNvbnN0IHNob3VsZEVuYWJsZUJpbmRpbmcgPSBzaG91bGRFbmFibGVCaW5kaW5nRm9yUG9pbnRlckV2ZW50KGV2ZW50KTtcbiAgICBpZiAodGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkICE9PSBzaG91bGRFbmFibGVCaW5kaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNCaW5kaW5nRW5hYmxlZDogc2hvdWxkRW5hYmxlQmluZGluZyB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZVN1Z2dlc3RCaW5kaW5nQXRDdXJzb3IgPSAocG9pbnRlckNvb3Jkczoge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gIH0pOiB2b2lkID0+IHtcbiAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgcG9pbnRlckNvb3JkcyxcbiAgICAgIHRoaXMuc2NlbmUsXG4gICAgKTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOlxuICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgPyBbaG92ZXJlZEJpbmRhYmxlRWxlbWVudF0gOiBbXSxcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdzRm9yTGluZWFyRWxlbWVudEF0Q29vcmRzID0gKFxuICAgIGxpbmVhckVsZW1lbnQ6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0xpbmVhckVsZW1lbnQ+LFxuICAgIC8qKiBzY2VuZSBjb29yZHMgKi9cbiAgICBwb2ludGVyQ29vcmRzOiB7XG4gICAgICB4OiBudW1iZXI7XG4gICAgICB5OiBudW1iZXI7XG4gICAgfVtdLFxuICAgIC8vIER1cmluZyBsaW5lIGNyZWF0aW9uIHRoZSBzdGFydCBiaW5kaW5nIGhhc24ndCBiZWVuIHdyaXR0ZW4geWV0XG4gICAgLy8gaW50byBgbGluZWFyRWxlbWVudGBcbiAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/OiBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50IHwgbnVsbCxcbiAgKTogdm9pZCA9PiB7XG4gICAgaWYgKCFwb2ludGVyQ29vcmRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN1Z2dlc3RlZEJpbmRpbmdzID0gcG9pbnRlckNvb3Jkcy5yZWR1Y2UoXG4gICAgICAoYWNjOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQ+W10sIGNvb3JkcykgPT4ge1xuICAgICAgICBjb25zdCBob3ZlcmVkQmluZGFibGVFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgICAgIGNvb3JkcyxcbiAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCAhPSBudWxsICYmXG4gICAgICAgICAgIWlzTGluZWFyRWxlbWVudFNpbXBsZUFuZEFscmVhZHlCb3VuZChcbiAgICAgICAgICAgIGxpbmVhckVsZW1lbnQsXG4gICAgICAgICAgICBvcHBvc2l0ZUJpbmRpbmdCb3VuZEVsZW1lbnQ/LmlkLFxuICAgICAgICAgICAgaG92ZXJlZEJpbmRhYmxlRWxlbWVudCxcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIGFjYy5wdXNoKGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoXG4gICAgc2VsZWN0ZWRFbGVtZW50czogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3MgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyU2VsZWN0aW9uKGhpdEVsZW1lbnQ6IEV4Y2FsaWRyYXdFbGVtZW50IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgIC8vIENvbnRpbnVlIGVkaXRpbmcgdGhlIHNhbWUgZ3JvdXAgaWYgdGhlIHVzZXIgc2VsZWN0ZWQgYSBkaWZmZXJlbnRcbiAgICAgIC8vIGVsZW1lbnQgZnJvbSBpdFxuICAgICAgZWRpdGluZ0dyb3VwSWQ6XG4gICAgICAgIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZCAmJlxuICAgICAgICBoaXRFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgaXNFbGVtZW50SW5Hcm91cChoaXRFbGVtZW50LCBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWQpXG4gICAgICAgICAgPyBwcmV2U3RhdGUuZWRpdGluZ0dyb3VwSWRcbiAgICAgICAgICA6IG51bGwsXG4gICAgfSkpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUmVmID0gKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQpID0+IHtcbiAgICAvLyBjYW52YXMgaXMgbnVsbCB3aGVuIHVubW91bnRpbmdcbiAgICBpZiAoY2FudmFzICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICAgIHRoaXMucmMgPSByb3VnaC5jYW52YXModGhpcy5jYW52YXMpO1xuXG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsLCB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9FTkQsIHRoaXMub25UYXBFbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5XSEVFTCwgdGhpcy5oYW5kbGVXaGVlbCk7XG4gICAgICB0aGlzLmNhbnZhcz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5UT1VDSF9TVEFSVCwgdGhpcy5vblRhcFN0YXJ0KTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQXBwT25Ecm9wID0gYXN5bmMgKGV2ZW50OiBSZWFjdC5EcmFnRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZpbGUgPSBldmVudC5kYXRhVHJhbnNmZXIuZmlsZXNbMF07XG5cbiAgICAgIGlmIChpc1N1cHBvcnRlZEltYWdlRmlsZShmaWxlKSkge1xuICAgICAgICAvLyBmaXJzdCBhdHRlbXB0IHRvIGRlY29kZSBzY2VuZSBmcm9tIHRoZSBpbWFnZSBpZiBpdCdzIGVtYmVkZGVkXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgICAgIGlmIChmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnBuZyB8fCBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLnN2Zykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlRmlsZVN5c3RlbVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IHdvcmsgYXMgb2YgQ2hyb21lIDg2LFxuICAgICAgICAgICAgICAgIC8vIGJ1dCBjYW4gYmUgc2FmZWx5IGlnbm9yZWQgb24gb2xkZXIgcmVsZWFzZXMuXG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5pdGVtc1swXTtcbiAgICAgICAgICAgICAgICAoZmlsZSBhcyBhbnkpLmhhbmRsZSA9IGF3YWl0IChcbiAgICAgICAgICAgICAgICAgIGl0ZW0gYXMgYW55XG4gICAgICAgICAgICAgICAgKS5nZXRBc0ZpbGVTeXN0ZW1IYW5kbGUoKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvci5uYW1lLCBlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzY2VuZSA9IGF3YWl0IGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgICAgICAuLi4oc2NlbmUuYXBwU3RhdGUgfHwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVwbGFjZUZpbGVzOiB0cnVlLFxuICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJFbmNvZGluZ0Vycm9yXCIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm8gc2NlbmUgaXMgZW1iZWRkZWQgb3Igd2UgZmFpbCBmb3Igd2hhdGV2ZXIgcmVhc29uLCBmYWxsIGJhY2tcbiAgICAgICAgLy8gdG8gaW1wb3J0aW5nIGFzIHJlZ3VsYXIgaW1hZ2VcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgY29uc3QgeyB4OiBzY2VuZVgsIHk6IHNjZW5lWSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaW1hZ2VFbGVtZW50ID0gdGhpcy5jcmVhdGVJbWFnZUVsZW1lbnQoeyBzY2VuZVgsIHNjZW5lWSB9KTtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBmaWxlKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSB9KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsaWJyYXJ5U2hhcGVzID0gZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliKTtcbiAgICBpZiAobGlicmFyeVNoYXBlcyAhPT0gXCJcIikge1xuICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgIGVsZW1lbnRzOiBKU09OLnBhcnNlKGxpYnJhcnlTaGFwZXMpLFxuICAgICAgICBwb3NpdGlvbjogZXZlbnQsXG4gICAgICAgIGZpbGVzOiBudWxsLFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZSA9IGV2ZW50LmRhdGFUcmFuc2Zlcj8uZmlsZXNbMF07XG4gICAgaWYgKFxuICAgICAgZmlsZT8udHlwZSA9PT0gTUlNRV9UWVBFUy5leGNhbGlkcmF3bGliIHx8XG4gICAgICBmaWxlPy5uYW1lPy5lbmRzV2l0aChcIi5leGNhbGlkcmF3bGliXCIpXG4gICAgKSB7XG4gICAgICB0aGlzLmxpYnJhcnlcbiAgICAgICAgLmltcG9ydExpYnJhcnkoZmlsZSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIENsb3NlIGFuZCB0aGVuIG9wZW4gdG8gZ2V0IHRoZSBsaWJyYXJpZXMgdXBkYXRlZFxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiBmYWxzZSB9KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogdHJ1ZSB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT5cbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pLFxuICAgICAgICApO1xuICAgICAgLy8gZGVmYXVsdDogYXNzdW1lIGFuIEV4Y2FsaWRyYXcgZmlsZSByZWdhcmRsZXNzIG9mIGV4dGVuc2lvbi9NaW1lVHlwZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgaWYgKG5hdGl2ZUZpbGVTeXN0ZW1TdXBwb3J0ZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUaGlzIHdpbGwgb25seSB3b3JrIGFzIG9mIENocm9tZSA4NixcbiAgICAgICAgICAvLyBidXQgY2FuIGJlIHNhZmVseSBpZ25vcmVkIG9uIG9sZGVyIHJlbGVhc2VzLlxuICAgICAgICAgIGNvbnN0IGl0ZW0gPSBldmVudC5kYXRhVHJhbnNmZXIuaXRlbXNbMF07XG4gICAgICAgICAgKGZpbGUgYXMgYW55KS5oYW5kbGUgPSBhd2FpdCAoaXRlbSBhcyBhbnkpLmdldEFzRmlsZVN5c3RlbUhhbmRsZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm5hbWUsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmxvYWRGaWxlVG9DYW52YXMoZmlsZSk7XG4gICAgfVxuICB9O1xuXG4gIGxvYWRGaWxlVG9DYW52YXMgPSAoZmlsZTogQmxvYikgPT4ge1xuICAgIGxvYWRGcm9tQmxvYihmaWxlLCB0aGlzLnN0YXRlLCB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpKVxuICAgICAgLnRoZW4oKHNjZW5lKSA9PiB7XG4gICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgLi4uc2NlbmUsXG4gICAgICAgICAgYXBwU3RhdGU6IHtcbiAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgY29tbWl0VG9IaXN0b3J5OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUNhbnZhc0NvbnRleHRNZW51ID0gKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHsgcHJlZmVyU2VsZWN0ZWQ6IHRydWUgfSk7XG5cbiAgICBjb25zdCB0eXBlID0gZWxlbWVudCA/IFwiZWxlbWVudFwiIDogXCJjYW52YXNcIjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ITtcbiAgICBjb25zdCB7IHRvcDogb2Zmc2V0VG9wLCBsZWZ0OiBvZmZzZXRMZWZ0IH0gPVxuICAgICAgY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGxlZnQgPSBldmVudC5jbGllbnRYIC0gb2Zmc2V0TGVmdDtcbiAgICBjb25zdCB0b3AgPSBldmVudC5jbGllbnRZIC0gb2Zmc2V0VG9wO1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgIXRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2VsZW1lbnQuaWRdKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9IH0sICgpID0+IHtcbiAgICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX29wZW5Db250ZXh0TWVudSh7IHRvcCwgbGVmdCB9LCB0eXBlKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZURyYWdOZXdHZW5lcmljRWxlbWVudCA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgZHJhZ2dpbmdFbGVtZW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQ7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBpZiAoIWRyYWdnaW5nRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIGRyYWdOZXdFbGVtZW50KFxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LCBwb2ludGVyQ29vcmRzLngpLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LCBwb2ludGVyQ29vcmRzLnkpLFxuICAgICAgICBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpbWFnZSA9XG4gICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSAmJlxuICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGRyYWdnaW5nRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcbiAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID1cbiAgICAgICAgaW1hZ2UgJiYgIShpbWFnZSBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICAgICAgPyBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodFxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSxcbiAgICAgICAgZ3JpZFgsXG4gICAgICAgIGdyaWRZLFxuICAgICAgICBkaXN0YW5jZShwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LCBncmlkWCksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLnksIGdyaWRZKSxcbiAgICAgICAgaXNJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcihldmVudCksXG4gICAgICAgIGFzcGVjdFJhdGlvLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKFtkcmFnZ2luZ0VsZW1lbnRdKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZUhhbmRsZVJlc2l6ZSA9IChcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG4gICAgY29uc3QgdHJhbnNmb3JtSGFuZGxlVHlwZSA9IHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGU7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAvLyBUT0RPOiByZW5hbWUgdGhpcyBzdGF0ZSBmaWVsZCB0byBcImlzU2NhbGluZ1wiIHRvIGRpc3Rpbmd1aXNoXG4gICAgICAvLyBpdCBmcm9tIHRoZSBnZW5lcmljIFwiaXNSZXNpemluZ1wiIHdoaWNoIGluY2x1ZGVzIHNjYWxpbmcgYW5kXG4gICAgICAvLyByb3RhdGluZ1xuICAgICAgaXNSZXNpemluZzogdHJhbnNmb3JtSGFuZGxlVHlwZSAmJiB0cmFuc2Zvcm1IYW5kbGVUeXBlICE9PSBcInJvdGF0aW9uXCIsXG4gICAgICBpc1JvdGF0aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlID09PSBcInJvdGF0aW9uXCIsXG4gICAgfSk7XG4gICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3JkcztcbiAgICBjb25zdCBbcmVzaXplWCwgcmVzaXplWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICBwb2ludGVyQ29vcmRzLnggLSBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5vZmZzZXQueCxcbiAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC55LFxuICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICApO1xuICAgIGlmIChcbiAgICAgIHRyYW5zZm9ybUVsZW1lbnRzKFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5hcnJvd0RpcmVjdGlvbixcbiAgICAgICAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiYgaXNJbWFnZUVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgICA/ICFzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KVxuICAgICAgICAgIDogc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudCksXG4gICAgICAgIHJlc2l6ZVgsXG4gICAgICAgIHJlc2l6ZVksXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5jZW50ZXIueSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgLyoqIEBwcml2YXRlIHVzZSB0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51ICovXG4gIHByaXZhdGUgX29wZW5Db250ZXh0TWVudSA9IChcbiAgICB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wLFxuICAgIH06IHtcbiAgICAgIGxlZnQ6IG51bWJlcjtcbiAgICAgIHRvcDogbnVtYmVyO1xuICAgIH0sXG4gICAgdHlwZTogXCJjYW52YXNcIiB8IFwiZWxlbWVudFwiLFxuICApID0+IHtcbiAgICBjb25zdCBtYXliZUdyb3VwQWN0aW9uID0gYWN0aW9uR3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlVW5ncm91cEFjdGlvbiA9IGFjdGlvblVuZ3JvdXAuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG1heWJlRmxpcEhvcml6b250YWwgPSBhY3Rpb25GbGlwSG9yaXpvbnRhbC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVGbGlwVmVydGljYWwgPSBhY3Rpb25GbGlwVmVydGljYWwuY29udGV4dEl0ZW1QcmVkaWNhdGUhKFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmdldEFwcFN0YXRlKCksXG4gICAgKTtcblxuICAgIGNvbnN0IHNlcGFyYXRvciA9IFwic2VwYXJhdG9yXCI7XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKTtcblxuICAgIGNvbnN0IG9wdGlvbnM6IENvbnRleHRNZW51T3B0aW9uW10gPSBbXTtcbiAgICBpZiAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1BuZyk7XG4gICAgfVxuXG4gICAgaWYgKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGFjdGlvbkNvcHlBc1N2Zyk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSBcImNhbnZhc1wiKSB7XG4gICAgICBjb25zdCB2aWV3TW9kZU9wdGlvbnMgPSBbXG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmdyaWRNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gICAgICBdO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogdmlld01vZGVPcHRpb25zLFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIGFjdGlvbk1hbmFnZXI6IHRoaXMuYWN0aW9uTWFuYWdlcixcbiAgICAgICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50ISxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZEJsb2IgJiZcbiAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBhY3Rpb25Db3B5QXNQbmcsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmXG4gICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgYWN0aW9uQ29weUFzU3ZnLFxuICAgICAgICAgICAgKChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB8fFxuICAgICAgICAgICAgICAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSkgJiZcbiAgICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uU2VsZWN0QWxsLFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZUdyaWRNb2RlLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlWmVuTW9kZSxcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVWaWV3TW9kZSxcbiAgICAgICAgICAgIGFjdGlvblRvZ2dsZVN0YXRzLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZWxlbWVudFwiKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW25hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSwgLi4ub3B0aW9uc10sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiYgYWN0aW9uQ3V0LFxuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkICYmIGFjdGlvbkNvcHksXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmXG4gICAgICAgICAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwicGFzdGVcIixcbiAgICAgICAgICAgICAgICBwZXJmb3JtOiAoZWxlbWVudHMsIGFwcFN0YXRlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wYXN0ZUZyb21DbGlwYm9hcmQobnVsbCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbnRleHRJdGVtTGFiZWw6IFwibGFiZWxzLnBhc3RlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25Db3B5U3R5bGVzLFxuICAgICAgICAgICAgYWN0aW9uUGFzdGVTdHlsZXMsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUdyb3VwQWN0aW9uICYmIGFjdGlvbkdyb3VwLFxuICAgICAgICAgICAgbWF5YmVVbmdyb3VwQWN0aW9uICYmIGFjdGlvblVuZ3JvdXAsXG4gICAgICAgICAgICAobWF5YmVHcm91cEFjdGlvbiB8fCBtYXliZVVuZ3JvdXBBY3Rpb24pICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkFkZFRvTGlicmFyeSxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgICAgICAgICAgIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgICAgICAgICAgIGFjdGlvblNlbmRUb0JhY2ssXG4gICAgICAgICAgICBhY3Rpb25CcmluZ1RvRnJvbnQsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBtYXliZUZsaXBIb3Jpem9udGFsICYmIGFjdGlvbkZsaXBIb3Jpem9udGFsLFxuICAgICAgICAgICAgbWF5YmVGbGlwVmVydGljYWwgJiYgYWN0aW9uRmxpcFZlcnRpY2FsLFxuICAgICAgICAgICAgKG1heWJlRmxpcEhvcml6b250YWwgfHwgbWF5YmVGbGlwVmVydGljYWwpICYmIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkR1cGxpY2F0ZVNlbGVjdGlvbixcbiAgICAgICAgICAgIGFjdGlvbkRlbGV0ZVNlbGVjdGVkLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVXaGVlbCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFdoZWVsRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKGlzUGFubmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVsdGFYLCBkZWx0YVkgfSA9IGV2ZW50O1xuICAgIGNvbnN0IHsgc2VsZWN0ZWRFbGVtZW50SWRzLCBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyB9ID0gdGhpcy5zdGF0ZTtcbiAgICAvLyBub3RlIHRoYXQgZXZlbnQuY3RybEtleSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIHBpbmNoIHpvb21pbmdcbiAgICBpZiAoZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5KSB7XG4gICAgICBjb25zdCBzaWduID0gTWF0aC5zaWduKGRlbHRhWSk7XG4gICAgICBjb25zdCBNQVhfU1RFUCA9IDEwO1xuICAgICAgbGV0IGRlbHRhID0gTWF0aC5hYnMoZGVsdGFZKTtcbiAgICAgIGlmIChkZWx0YSA+IE1BWF9TVEVQKSB7XG4gICAgICAgIGRlbHRhID0gTUFYX1NURVA7XG4gICAgICB9XG4gICAgICBkZWx0YSAqPSBzaWduO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCAxMDAwKTtcbiAgICAgIH1cblxuICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnN0YXRlLnpvb20udmFsdWUgLSBkZWx0YSAvIDEwMDtcbiAgICAgIC8vIGluY3JlYXNlIHpvb20gc3RlcHMgdGhlIG1vcmUgem9vbWVkLWluIHdlIGFyZSAoYXBwbGllcyB0byA+MTAwJSBvbmx5KVxuICAgICAgbmV3Wm9vbSArPSBNYXRoLmxvZzEwKE1hdGgubWF4KDEsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpICogLXNpZ247XG4gICAgICAvLyByb3VuZCB0byBuZWFyZXN0IHN0ZXBcbiAgICAgIG5ld1pvb20gPSBNYXRoLnJvdW5kKG5ld1pvb20gKiBaT09NX1NURVAgKiAxMDApIC8gKFpPT01fU1RFUCAqIDEwMCk7XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pID0+ICh7XG4gICAgICAgIHpvb206IGdldE5ld1pvb20oXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZFpvb20obmV3Wm9vbSksXG4gICAgICAgICAgem9vbSxcbiAgICAgICAgICB7IGxlZnQ6IG9mZnNldExlZnQsIHRvcDogb2Zmc2V0VG9wIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgeDogY3Vyc29yWCxcbiAgICAgICAgICAgIHk6IGN1cnNvclksXG4gICAgICAgICAgfSxcbiAgICAgICAgKSxcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6XG4gICAgICAgICAgT2JqZWN0LmtleXMoc2VsZWN0ZWRFbGVtZW50SWRzKS5sZW5ndGggIT09IDBcbiAgICAgICAgICAgID8gc2VsZWN0ZWRFbGVtZW50SWRzXG4gICAgICAgICAgICA6IHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICBzaG91bGRDYWNoZUlnbm9yZVpvb206IHRydWUsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLnJlc2V0U2hvdWxkQ2FjaGVJZ25vcmVab29tRGVib3VuY2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2Nyb2xsIGhvcml6b250YWxseSB3aGVuIHNoaWZ0IHByZXNzZWRcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgc2Nyb2xsWCB9KSA9PiAoe1xuICAgICAgICAvLyBvbiBNYWMsIHNoaWZ0K3doZWVsIHRlbmRzIHRvIHJlc3VsdCBpbiBkZWx0YVhcbiAgICAgICAgc2Nyb2xsWDogc2Nyb2xsWCAtIChkZWx0YVkgfHwgZGVsdGFYKSAvIHpvb20udmFsdWUsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYLCBzY3JvbGxZIH0pID0+ICh7XG4gICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgIHNjcm9sbFk6IHNjcm9sbFkgLSBkZWx0YVkgLyB6b29tLnZhbHVlLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBnZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgYXBwU3RhdGU6IEFwcFN0YXRlLFxuICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsLFxuICAgIHNjYWxlOiBudW1iZXIsXG4gICkge1xuICAgIGNvbnN0IGVsZW1lbnRDbGlja2VkSW5zaWRlID0gZ2V0RWxlbWVudENvbnRhaW5pbmdQb3NpdGlvbihcbiAgICAgIHRoaXMuc2NlbmVcbiAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgIC5maWx0ZXIoKGVsZW1lbnQpID0+ICFpc1RleHRFbGVtZW50KGVsZW1lbnQpKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICk7XG4gICAgaWYgKGVsZW1lbnRDbGlja2VkSW5zaWRlKSB7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWCA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnggKyBlbGVtZW50Q2xpY2tlZEluc2lkZS53aWR0aCAvIDI7XG4gICAgICBjb25zdCBlbGVtZW50Q2VudGVyWSA9XG4gICAgICAgIGVsZW1lbnRDbGlja2VkSW5zaWRlLnkgKyBlbGVtZW50Q2xpY2tlZEluc2lkZS5oZWlnaHQgLyAyO1xuICAgICAgY29uc3QgZGlzdGFuY2VUb0NlbnRlciA9IE1hdGguaHlwb3QoXG4gICAgICAgIHggLSBlbGVtZW50Q2VudGVyWCxcbiAgICAgICAgeSAtIGVsZW1lbnRDZW50ZXJZLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzU25hcHBlZFRvQ2VudGVyID1cbiAgICAgICAgZGlzdGFuY2VUb0NlbnRlciA8IFRFWFRfVE9fQ0VOVEVSX1NOQVBfVEhSRVNIT0xEO1xuICAgICAgaWYgKGlzU25hcHBlZFRvQ2VudGVyKSB7XG4gICAgICAgIGNvbnN0IHsgeDogdmlld3BvcnRYLCB5OiB2aWV3cG9ydFkgfSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAgICB7IHNjZW5lWDogZWxlbWVudENlbnRlclgsIHNjZW5lWTogZWxlbWVudENlbnRlclkgfSxcbiAgICAgICAgICBhcHBTdGF0ZSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgdmlld3BvcnRYLCB2aWV3cG9ydFksIGVsZW1lbnRDZW50ZXJYLCBlbGVtZW50Q2VudGVyWSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZVBvaW50ZXIgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIGJ1dHRvbjogXCJ1cFwiIHwgXCJkb3duXCIpID0+IHtcbiAgICBpZiAoIXggfHwgIXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9pbnRlciA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgaWYgKGlzTmFOKHBvaW50ZXIueCkgfHwgaXNOYU4ocG9pbnRlci55KSkge1xuICAgICAgLy8gc29tZXRpbWVzIHRoZSBwb2ludGVyIGdvZXMgb2ZmIHNjcmVlblxuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25Qb2ludGVyVXBkYXRlPy4oe1xuICAgICAgcG9pbnRlcixcbiAgICAgIGJ1dHRvbixcbiAgICAgIHBvaW50ZXJzTWFwOiBnZXN0dXJlLnBvaW50ZXJzLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgcmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLnVubW91bnRlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3VsZENhY2hlSWdub3JlWm9vbTogZmFsc2UgfSk7XG4gICAgfVxuICB9LCAzMDApO1xuXG4gIHByaXZhdGUgdXBkYXRlRE9NUmVjdCA9IChjYj86ICgpID0+IHZvaWQpID0+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGxlZnQ6IG9mZnNldExlZnQsXG4gICAgICAgIHRvcDogb2Zmc2V0VG9wLFxuICAgICAgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHdpZHRoOiBjdXJyZW50V2lkdGgsXG4gICAgICAgIGhlaWdodDogY3VycmVudEhlaWdodCxcbiAgICAgICAgb2Zmc2V0VG9wOiBjdXJyZW50T2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBjdXJyZW50T2Zmc2V0TGVmdCxcbiAgICAgIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHdpZHRoID09PSBjdXJyZW50V2lkdGggJiZcbiAgICAgICAgaGVpZ2h0ID09PSBjdXJyZW50SGVpZ2h0ICYmXG4gICAgICAgIG9mZnNldExlZnQgPT09IGN1cnJlbnRPZmZzZXRMZWZ0ICYmXG4gICAgICAgIG9mZnNldFRvcCA9PT0gY3VycmVudE9mZnNldFRvcFxuICAgICAgKSB7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIG9mZnNldExlZnQsXG4gICAgICAgICAgb2Zmc2V0VG9wLFxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2IgJiYgY2IoKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyByZWZyZXNoID0gKCkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLmdldENhbnZhc09mZnNldHMoKSB9KTtcbiAgfTtcblxuICBwcml2YXRlIGdldENhbnZhc09mZnNldHMoKTogUGljazxBcHBTdGF0ZSwgXCJvZmZzZXRUb3BcIiB8IFwib2Zmc2V0TGVmdFwiPiB7XG4gICAgaWYgKHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgY29uc3QgZXhjYWxpZHJhd0NvbnRhaW5lciA9IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGV4Y2FsaWRyYXdDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXRMZWZ0OiBsZWZ0LFxuICAgICAgICBvZmZzZXRUb3A6IHRvcCxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgb2Zmc2V0VG9wOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUxhbmd1YWdlKCkge1xuICAgIGNvbnN0IGN1cnJlbnRMYW5nID1cbiAgICAgIGxhbmd1YWdlcy5maW5kKChsYW5nKSA9PiBsYW5nLmNvZGUgPT09IHRoaXMucHJvcHMubGFuZ0NvZGUpIHx8XG4gICAgICBkZWZhdWx0TGFuZztcbiAgICBhd2FpdCBzZXRMYW5ndWFnZShjdXJyZW50TGFuZyk7XG4gICAgdGhpcy5zZXRBcHBTdGF0ZSh7fSk7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRFU1QgSE9PS1Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgaDoge1xuICAgICAgZWxlbWVudHM6IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W107XG4gICAgICBzdGF0ZTogQXBwU3RhdGU7XG4gICAgICBzZXRTdGF0ZTogUmVhY3QuQ29tcG9uZW50PGFueSwgQXBwU3RhdGU+W1wic2V0U3RhdGVcIl07XG4gICAgICBhcHA6IEluc3RhbmNlVHlwZTx0eXBlb2YgQXBwPjtcbiAgICAgIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gICAgfTtcbiAgfVxufVxuXG5pZiAoXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuVEVTVCB8fFxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLkRFVkVMT1BNRU5UXG4pIHtcbiAgd2luZG93LmggPSB3aW5kb3cuaCB8fCAoe30gYXMgV2luZG93W1wiaFwiXSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICBlbGVtZW50czoge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHAuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCk7XG4gICAgICB9LFxuICAgICAgc2V0KGVsZW1lbnRzOiBFeGNhbGlkcmF3RWxlbWVudFtdKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcC5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cbmV4cG9ydCBkZWZhdWx0IEFwcDtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
1786
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"useIsMobile\": () => (/* binding */ useIsMobile),\n/* harmony export */ \"useExcalidrawContainer\": () => (/* binding */ useExcalidrawContainer),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\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 roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! roughjs/bin/rough */ \"../../../node_modules/roughjs/bin/rough.js\");\n/* harmony import */ var clsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! clsx */ \"../../../node_modules/clsx/dist/clsx.m.js\");\n/* harmony import */ var nanoid__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! nanoid */ \"../../../node_modules/nanoid/index.dev.js\");\n/* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../actions */ \"../../actions/index.ts\");\n/* harmony import */ var _actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../actions/actionHistory */ \"../../actions/actionHistory.tsx\");\n/* harmony import */ var _actions_manager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../actions/manager */ \"../../actions/manager.tsx\");\n/* harmony import */ var _actions_register__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../actions/register */ \"../../actions/register.ts\");\n/* harmony import */ var _analytics__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../analytics */ \"../../analytics.ts\");\n/* harmony import */ var _appState__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../appState */ \"../../appState.ts\");\n/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../clipboard */ \"../../clipboard.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _data__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../data */ \"../../data/index.ts\");\n/* harmony import */ var _data_json__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../data/json */ \"../../data/json.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__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../renderer */ \"../../renderer/index.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 _Stats__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Stats */ \"../../components/Stats.tsx\");\n/* harmony import */ var _Toast__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./Toast */ \"../../components/Toast.tsx\");\n/* harmony import */ var _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../actions/actionToggleViewMode */ \"../../actions/actionToggleViewMode.tsx\");\n/* harmony import */ var _data_blob__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../data/blob */ \"../../data/blob.ts\");\n/* harmony import */ var _element_image__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ../element/image */ \"../../element/image.ts\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! lodash.throttle */ \"../../../node_modules/lodash.throttle/index.js\");\n/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_42__);\n/* harmony import */ var _data_filesystem__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ../data/filesystem */ \"../../data/filesystem.ts\");\n/* harmony import */ var _element_textElement__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ../element/textElement */ \"../../element/textElement.ts\");\n/* harmony import */ var _element_collision__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ../element/collision */ \"../../element/collision.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst IsMobileContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext(false);\r\nconst useIsMobile = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(IsMobileContext);\r\nconst ExcalidrawContainerContext = react__WEBPACK_IMPORTED_MODULE_1___default().createContext({ container: null, id: null });\r\nconst useExcalidrawContainer = () => (0,react__WEBPACK_IMPORTED_MODULE_1__.useContext)(ExcalidrawContainerContext);\r\nlet didTapTwice = false;\r\nlet tappedTwiceTimer = 0;\r\nlet cursorX = 0;\r\nlet cursorY = 0;\r\nlet isHoldingSpace = false;\r\nlet isPanning = false;\r\nlet isDraggingScrollBar = false;\r\nlet currentScrollBars = { horizontal: null, vertical: null };\r\nlet touchTimeout = 0;\r\nlet invalidateContextMenu = false;\r\nlet lastPointerUp = null;\r\nconst gesture = {\r\n pointers: new Map(),\r\n lastCenter: null,\r\n initialDistance: null,\r\n initialScale: null,\r\n};\r\nclass App extends (react__WEBPACK_IMPORTED_MODULE_1___default().Component) {\r\n constructor(props) {\r\n var _a;\r\n super(props);\r\n this.canvas = null;\r\n this.rc = null;\r\n this.unmounted = false;\r\n this.isMobile = false;\r\n this.excalidrawContainerRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();\r\n this.files = {};\r\n this.imageCache = new Map();\r\n this.focusContainer = () => {\r\n var _a;\r\n if (this.props.autoFocus) {\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();\r\n }\r\n };\r\n this.getSceneElementsIncludingDeleted = () => {\r\n return this.scene.getElementsIncludingDeleted();\r\n };\r\n this.getSceneElements = () => {\r\n return this.scene.getElements();\r\n };\r\n this.syncActionResult = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((actionResult) => {\r\n var _a, _b, _c, _d, _e, _f;\r\n if (this.unmounted || actionResult === false) {\r\n return;\r\n }\r\n let editingElement = null;\r\n if (actionResult.elements) {\r\n actionResult.elements.forEach((element) => {\r\n var _a;\r\n if (((_a = this.state.editingElement) === null || _a === void 0 ? void 0 : _a.id) === element.id &&\r\n this.state.editingElement !== element &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n editingElement = element;\r\n }\r\n });\r\n this.scene.replaceAllElements(actionResult.elements);\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n }\r\n if (actionResult.files) {\r\n this.files = actionResult.replaceFiles\r\n ? actionResult.files\r\n : Object.assign(Object.assign({}, this.files), actionResult.files);\r\n this.addNewImagesToImageCache();\r\n }\r\n if (actionResult.appState || editingElement) {\r\n if (actionResult.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n let viewModeEnabled = ((_a = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _a === void 0 ? void 0 : _a.viewModeEnabled) || false;\r\n let zenModeEnabled = ((_b = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _b === void 0 ? void 0 : _b.zenModeEnabled) || false;\r\n let gridSize = ((_c = actionResult === null || actionResult === void 0 ? void 0 : actionResult.appState) === null || _c === void 0 ? void 0 : _c.gridSize) || null;\r\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_11__.THEME.LIGHT;\r\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;\r\n if (typeof this.props.viewModeEnabled !== \"undefined\") {\r\n viewModeEnabled = this.props.viewModeEnabled;\r\n }\r\n if (typeof this.props.zenModeEnabled !== \"undefined\") {\r\n zenModeEnabled = this.props.zenModeEnabled;\r\n }\r\n if (typeof this.props.gridModeEnabled !== \"undefined\") {\r\n gridSize = this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null;\r\n }\r\n if (typeof this.props.theme !== \"undefined\") {\r\n theme = this.props.theme;\r\n }\r\n if (typeof this.props.name !== \"undefined\") {\r\n name = this.props.name;\r\n }\r\n this.setState((state) => {\r\n var _a;\r\n // using Object.assign instead of spread to fool TS 4.2.2+ into\r\n // regarding the resulting type as not containing undefined\r\n // (which the following expression will never contain)\r\n return Object.assign(actionResult.appState || {}, {\r\n editingElement: editingElement || ((_a = actionResult.appState) === null || _a === void 0 ? void 0 : _a.editingElement) || null,\r\n viewModeEnabled,\r\n zenModeEnabled,\r\n gridSize,\r\n theme,\r\n name,\r\n });\r\n }, () => {\r\n if (actionResult.syncHistory) {\r\n this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());\r\n }\r\n });\r\n }\r\n });\r\n // Lifecycle\r\n this.onBlur = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isHoldingSpace = false;\r\n this.setState({ isBindingEnabled: true });\r\n });\r\n this.onUnload = () => {\r\n this.onBlur();\r\n };\r\n this.disableEvent = (event) => {\r\n event.preventDefault();\r\n };\r\n this.onFontLoaded = () => {\r\n this.scene.getElementsIncludingDeleted().forEach((element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n });\r\n this.onSceneUpdated();\r\n };\r\n this.importLibraryFromUrl = (url, token) => __awaiter(this, void 0, void 0, function* () {\r\n if (window.location.hash.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary)) {\r\n const hash = new URLSearchParams(window.location.hash.slice(1));\r\n hash.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `#${hash.toString()}`);\r\n }\r\n else if (window.location.search.includes(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary)) {\r\n const query = new URLSearchParams(window.location.search);\r\n query.delete(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n window.history.replaceState({}, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, `?${query.toString()}`);\r\n }\r\n try {\r\n const request = yield fetch(decodeURIComponent(url));\r\n const blob = yield request.blob();\r\n const json = JSON.parse(yield blob.text());\r\n if (!(0,_data_json__WEBPACK_IMPORTED_MODULE_13__.isValidLibrary)(json)) {\r\n throw new Error();\r\n }\r\n if (token === this.id ||\r\n window.confirm((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.confirmAddLibrary\", {\r\n numShapes: (json.libraryItems || json.library || []).length,\r\n }))) {\r\n yield this.library.importLibrary(blob, \"published\");\r\n // hack to rerender the library items after import\r\n if (this.state.isLibraryOpen) {\r\n this.setState({ isLibraryOpen: false });\r\n }\r\n this.setState({ isLibraryOpen: true });\r\n }\r\n }\r\n catch (error) {\r\n window.alert((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"alerts.errorLoadingLibrary\"));\r\n console.error(error);\r\n }\r\n finally {\r\n this.focusContainer();\r\n }\r\n });\r\n this.resetHistory = () => {\r\n this.history.clear();\r\n };\r\n /**\r\n * Resets scene & history.\r\n * ! Do not use to clear scene user action !\r\n */\r\n this.resetScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((opts) => {\r\n this.scene.replaceAllElements([]);\r\n this.setState((state) => (Object.assign(Object.assign({}, (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)()), { isLoading: (opts === null || opts === void 0 ? void 0 : opts.resetLoadingState) ? false : state.isLoading, theme: this.state.theme })));\r\n this.resetHistory();\r\n });\r\n this.initializeScene = () => __awaiter(this, void 0, void 0, function* () {\r\n if (\"launchQueue\" in window && \"LaunchParams\" in window) {\r\n window.launchQueue.setConsumer((launchParams) => __awaiter(this, void 0, void 0, function* () {\r\n if (!launchParams.files.length) {\r\n return;\r\n }\r\n const fileHandle = launchParams.files[0];\r\n const blob = yield fileHandle.getFile();\r\n blob.handle = fileHandle;\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(blob, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n }));\r\n }\r\n if (!this.state.isLoading) {\r\n this.setState({ isLoading: true });\r\n }\r\n let initialData = null;\r\n try {\r\n initialData = (yield this.props.initialData) || null;\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.libraryItems) {\r\n this.libraryItemsFromStorage = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreLibraryItems)(initialData.libraryItems, \"unpublished\");\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n initialData = {\r\n appState: {\r\n errorMessage: error.message ||\r\n \"Encountered an error during importing or restoring scene data\",\r\n },\r\n };\r\n }\r\n const scene = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restore)(initialData, null, null);\r\n scene.appState = Object.assign(Object.assign({}, scene.appState), { elementType: scene.appState.elementType === \"image\"\r\n ? \"selection\"\r\n : scene.appState.elementType, isLoading: false });\r\n if (initialData === null || initialData === void 0 ? void 0 : initialData.scrollToContent) {\r\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));\r\n }\r\n this.resetHistory();\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { commitToHistory: true }));\r\n const libraryUrl = \r\n // current\r\n new URLSearchParams(window.location.hash.slice(1)).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_HASH_KEYS.addLibrary) ||\r\n // legacy, kept for compat reasons\r\n new URLSearchParams(window.location.search).get(_constants__WEBPACK_IMPORTED_MODULE_11__.URL_QUERY_KEYS.addLibrary);\r\n if (libraryUrl) {\r\n yield this.importLibraryFromUrl(libraryUrl);\r\n }\r\n });\r\n this.onResize = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n this.scene\r\n .getElementsIncludingDeleted()\r\n .forEach((element) => (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element));\r\n this.setState({});\r\n });\r\n this.onScroll = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n const { offsetTop, offsetLeft } = this.getCanvasOffsets();\r\n this.setState((state) => {\r\n if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {\r\n return null;\r\n }\r\n return { offsetTop, offsetLeft };\r\n });\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.SCROLL_TIMEOUT);\r\n // Copy/paste\r\n this.onCut = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.cutAll();\r\n event.preventDefault();\r\n });\r\n this.onCopy = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a;\r\n const isExcalidrawActive = (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement);\r\n if (!isExcalidrawActive || (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target)) {\r\n return;\r\n }\r\n this.copyAll();\r\n event.preventDefault();\r\n });\r\n this.cutAll = () => {\r\n this.copyAll();\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected);\r\n };\r\n this.copyAll = () => {\r\n (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.copyToClipboard)(this.scene.getElements(), this.state, this.files);\r\n };\r\n this.onTapStart = (event) => {\r\n if (!didTapTwice) {\r\n didTapTwice = true;\r\n clearTimeout(tappedTwiceTimer);\r\n tappedTwiceTimer = window.setTimeout(App.resetTapTwice, _constants__WEBPACK_IMPORTED_MODULE_11__.TAP_TWICE_TIMEOUT);\r\n return;\r\n }\r\n // insert text only if we tapped twice with a single finger\r\n // event.touches.length === 1 will also prevent inserting text when user's zooming\r\n if (didTapTwice && event.touches.length === 1) {\r\n const [touch] = event.touches;\r\n // @ts-ignore\r\n this.handleCanvasDoubleClick({\r\n clientX: touch.clientX,\r\n clientY: touch.clientY,\r\n });\r\n didTapTwice = false;\r\n clearTimeout(tappedTwiceTimer);\r\n }\r\n event.preventDefault();\r\n if (event.touches.length === 2) {\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n }\r\n };\r\n this.onTapEnd = (event) => {\r\n if (event.touches.length > 0) {\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n }\r\n };\r\n this.pasteFromClipboard = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => __awaiter(this, void 0, void 0, function* () {\r\n var _b, _c;\r\n // #686\r\n const target = document.activeElement;\r\n const isExcalidrawActive = (_b = this.excalidrawContainerRef.current) === null || _b === void 0 ? void 0 : _b.contains(target);\r\n if (!isExcalidrawActive) {\r\n return;\r\n }\r\n const elementUnderCursor = document.elementFromPoint(cursorX, cursorY);\r\n if (\r\n // if no ClipboardEvent supplied, assume we're pasting via contextMenu\r\n // thus these checks don't make sense\r\n event &&\r\n (!(elementUnderCursor instanceof HTMLCanvasElement) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(target))) {\r\n return;\r\n }\r\n // must be called in the same frame (thus before any awaits) as the paste\r\n // event else some browsers (FF...) will clear the clipboardData\r\n // (something something security)\r\n let file = (_c = event === null || event === void 0 ? void 0 : event.clipboardData) === null || _c === void 0 ? void 0 : _c.files[0];\r\n const data = yield (0,_clipboard__WEBPACK_IMPORTED_MODULE_10__.parseClipboard)(event);\r\n if (!file && data.text) {\r\n const string = data.text.trim();\r\n if (string.startsWith(\"<svg\") && string.endsWith(\"</svg>\")) {\r\n // ignore SVG validation/normalization which will be done during image\r\n // initialization\r\n file = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(string);\r\n }\r\n }\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n if (this.props.onPaste) {\r\n try {\r\n if ((yield this.props.onPaste(data, event)) === false) {\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n console.error(error);\r\n }\r\n }\r\n if (data.errorMessage) {\r\n this.setState({ errorMessage: data.errorMessage });\r\n }\r\n else if (data.spreadsheet) {\r\n this.setState({\r\n pasteDialog: {\r\n data: data.spreadsheet,\r\n shown: true,\r\n },\r\n });\r\n }\r\n else if (data.elements) {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: data.elements,\r\n files: data.files || null,\r\n position: \"cursor\",\r\n });\r\n }\r\n else if (data.text) {\r\n this.addTextFromPaste(data.text);\r\n }\r\n this.selectShapeTool(\"selection\");\r\n event === null || event === void 0 ? void 0 : event.preventDefault();\r\n }));\r\n this.addElementsFromPasteOrLibrary = (opts) => {\r\n const elements = (0,_data_restore__WEBPACK_IMPORTED_MODULE_15__.restoreElements)(opts.elements, null);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(elements);\r\n const elementsCenterX = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minX, maxX) / 2;\r\n const elementsCenterY = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.distance)(minY, maxY) / 2;\r\n const clientX = typeof opts.position === \"object\"\r\n ? opts.position.clientX\r\n : opts.position === \"cursor\"\r\n ? cursorX\r\n : this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = typeof opts.position === \"object\"\r\n ? opts.position.clientY\r\n : opts.position === \"cursor\"\r\n ? cursorY\r\n : this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const dx = x - elementsCenterX;\r\n const dy = y - elementsCenterY;\r\n const groupIdMap = new Map();\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(dx, dy, this.state.gridSize);\r\n const oldIdToDuplicatedId = new Map();\r\n const newElements = elements.map((element) => {\r\n const newElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element, {\r\n x: element.x + gridX - minX,\r\n y: element.y + gridY - minY,\r\n });\r\n oldIdToDuplicatedId.set(element.id, newElement.id);\r\n return newElement;\r\n });\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(newElements, elements, oldIdToDuplicatedId);\r\n const nextElements = [\r\n ...this.scene.getElementsIncludingDeleted(),\r\n ...newElements,\r\n ];\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextElements, elements, oldIdToDuplicatedId);\r\n if (opts.files) {\r\n this.files = Object.assign(Object.assign({}, this.files), opts.files);\r\n }\r\n this.scene.replaceAllElements(nextElements);\r\n this.history.resumeRecording();\r\n this.setState((0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, this.state), { isLibraryOpen: false, selectedElementIds: newElements.reduce((map, element) => {\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.containerId) {\r\n map[element.id] = true;\r\n }\r\n return map;\r\n }, {}), selectedGroupIds: {} }), this.scene.getElements()), () => {\r\n if (opts.files) {\r\n this.addNewImagesToImageCache();\r\n }\r\n });\r\n this.selectShapeTool(\"selection\");\r\n };\r\n // Collaboration\r\n this.setAppState = (obj) => {\r\n this.setState(obj);\r\n };\r\n this.removePointer = (event) => {\r\n // remove touch handler for context menu on touch devices\r\n if (event.pointerType === \"touch\" && touchTimeout) {\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n invalidateContextMenu = false;\r\n }\r\n gesture.pointers.delete(event.pointerId);\r\n };\r\n this.toggleLock = () => {\r\n this.setState((prevState) => {\r\n return {\r\n elementLocked: !prevState.elementLocked,\r\n elementType: prevState.elementLocked\r\n ? \"selection\"\r\n : prevState.elementType,\r\n };\r\n });\r\n };\r\n this.toggleZenMode = () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode);\r\n };\r\n this.toggleStats = () => {\r\n if (!this.state.showStats) {\r\n (0,_analytics__WEBPACK_IMPORTED_MODULE_8__.trackEvent)(\"dialog\", \"stats\");\r\n }\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats);\r\n };\r\n this.scrollToContent = (target = this.scene.getElements()) => {\r\n this.setState(Object.assign({}, (0,_scene__WEBPACK_IMPORTED_MODULE_30__.calculateScrollCenter)(Array.isArray(target) ? target : [target], this.state, this.canvas)));\r\n };\r\n this.clearToast = () => {\r\n this.setState({ toastMessage: null });\r\n };\r\n this.setToastMessage = (toastMessage) => {\r\n this.setState({ toastMessage });\r\n };\r\n this.restoreFileFromShare = () => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const webShareTargetCache = yield caches.open(\"web-share-target\");\r\n const file = yield webShareTargetCache.match(\"shared-file\");\r\n if (file) {\r\n const blob = yield file.blob();\r\n this.loadFileToCanvas(blob);\r\n yield webShareTargetCache.delete(\"shared-file\");\r\n window.history.replaceState(null, _constants__WEBPACK_IMPORTED_MODULE_11__.APP_NAME, window.location.pathname);\r\n }\r\n }\r\n catch (error) {\r\n this.setState({ errorMessage: error.message });\r\n }\r\n });\r\n /** adds supplied files to existing files in the appState */\r\n this.addFiles = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((files) => {\r\n const filesMap = files.reduce((acc, fileData) => {\r\n acc.set(fileData.id, fileData);\r\n return acc;\r\n }, new Map());\r\n this.files = Object.assign(Object.assign({}, this.files), Object.fromEntries(filesMap));\r\n // bump versions for elements that reference added files so that\r\n // we/host apps can detect the change, and invalidate the image & shape\r\n // cache\r\n this.scene.getElements().forEach((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n filesMap.has(element.fileId)) {\r\n this.imageCache.delete(element.fileId);\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.bumpVersion)(element);\r\n }\r\n });\r\n this.scene.informMutation();\r\n this.addNewImagesToImageCache();\r\n });\r\n this.updateScene = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((sceneData) => {\r\n if (sceneData.commitToHistory) {\r\n this.history.resumeRecording();\r\n }\r\n if (sceneData.appState) {\r\n this.setState(sceneData.appState);\r\n }\r\n if (sceneData.elements) {\r\n this.scene.replaceAllElements(sceneData.elements);\r\n }\r\n if (sceneData.collaborators) {\r\n this.setState({ collaborators: sceneData.collaborators });\r\n }\r\n });\r\n this.onSceneUpdated = () => {\r\n this.setState({});\r\n };\r\n this.updateCurrentCursorPosition = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n cursorX = event.clientX;\r\n cursorY = event.clientY;\r\n });\r\n // Input handling\r\n this.onKeyDown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // normalize `event.key` when CapsLock is pressed #2372\r\n if (\"Proxy\" in window &&\r\n ((!event.shiftKey && /^[A-Z]$/.test(event.key)) ||\r\n (event.shiftKey && /^[a-z]$/.test(event.key)))) {\r\n event = new Proxy(event, {\r\n get(ev, prop) {\r\n const value = ev[prop];\r\n if (typeof value === \"function\") {\r\n // fix for Proxies hijacking `this`\r\n return value.bind(ev);\r\n }\r\n return prop === \"key\"\r\n ? // CapsLock inverts capitalization based on ShiftKey, so invert\r\n // it back\r\n event.shiftKey\r\n ? ev.key.toUpperCase()\r\n : ev.key.toLowerCase()\r\n : value;\r\n },\r\n });\r\n }\r\n if (((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isWritableElement)(event.target) && event.key !== _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ESCAPE) ||\r\n // case: using arrows to move between buttons\r\n ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key) && (0,_utils__WEBPACK_IMPORTED_MODULE_34__.isInputLike)(event.target))) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.QUESTION_MARK) {\r\n this.setState({\r\n showHelpDialog: true,\r\n });\r\n }\r\n if (this.actionManager.handleKeyDown(event)) {\r\n return;\r\n }\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: false });\r\n }\r\n if (event.code === _keys__WEBPACK_IMPORTED_MODULE_26__.CODES.ZERO) {\r\n this.setState({ isLibraryOpen: !this.state.isLibraryOpen });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const step = (this.state.gridSize &&\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT\r\n : this.state.gridSize)) ||\r\n (event.shiftKey\r\n ? _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_SHIFT_TRANSLATE_AMOUNT\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.ELEMENT_TRANSLATE_AMOUNT);\r\n const selectedElements = this.scene\r\n .getElements()\r\n .filter((element) => this.state.selectedElementIds[element.id]);\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_LEFT) {\r\n offsetX = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_RIGHT) {\r\n offsetX = step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_UP) {\r\n offsetY = -step;\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ARROW_DOWN) {\r\n offsetY = step;\r\n }\r\n selectedElements.forEach((element) => {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n x: element.x + offsetX,\r\n y: element.y + offsetY,\r\n });\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element, {\r\n simultaneouslyUpdated: selectedElements,\r\n });\r\n });\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n event.preventDefault();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ENTER) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n }\r\n else if (selectedElements.length === 1 &&\r\n !(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n const selectedElement = selectedElements[0];\r\n this.startTextEditing({\r\n sceneX: selectedElement.x + selectedElement.width / 2,\r\n sceneY: selectedElement.y + selectedElement.height / 2,\r\n shouldBind: true,\r\n });\r\n event.preventDefault();\r\n return;\r\n }\r\n }\r\n else if (!event.ctrlKey &&\r\n !event.altKey &&\r\n !event.metaKey &&\r\n this.state.draggingElement === null) {\r\n const shape = (0,_shapes__WEBPACK_IMPORTED_MODULE_33__.findShapeByKey)(event.key);\r\n if (shape) {\r\n this.selectShapeTool(shape);\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.Q) {\r\n this.toggleLock();\r\n }\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE && gesture.pointers.size === 0) {\r\n isHoldingSpace = true;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G || event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (this.state.elementType === \"selection\" &&\r\n !selectedElements.length) {\r\n return;\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.G &&\r\n ((0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(this.state.elementType) ||\r\n selectedElements.some((element) => (0,_scene__WEBPACK_IMPORTED_MODULE_30__.hasBackground)(element.type)))) {\r\n this.setState({ openPopup: \"backgroundColorPicker\" });\r\n }\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.S) {\r\n this.setState({ openPopup: \"strokeColorPicker\" });\r\n }\r\n }\r\n });\r\n this.onKeyUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.SPACE) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (this.state.elementType === \"selection\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n isHoldingSpace = false;\r\n }\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.isBindingEnabled) {\r\n this.setState({ isBindingEnabled: true });\r\n }\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.isArrowKey)(event.key)) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements)(selectedElements)\r\n : (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)(selectedElements);\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n });\r\n this.onGestureStart = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n selectedElementIds: {},\r\n });\r\n gesture.initialScale = this.state.zoom.value;\r\n });\r\n this.onGestureChange = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n // onGestureChange only has zoom factor but not the center.\r\n // If we're on iPad or iPhone, then we recognize multi-touch and will\r\n // zoom in at the right location on the touchMove handler already.\r\n // On Macbook, we don't have those events so will zoom in at the\r\n // current location instead.\r\n if (gesture.pointers.size === 2) {\r\n return;\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (initialScale) {\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * event.scale), zoom, { left: offsetLeft, top: offsetTop }, { x: cursorX, y: cursorY }),\r\n }));\r\n }\r\n });\r\n this.onGestureEnd = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n this.setState({\r\n previousSelectedElementIds: {},\r\n selectedElementIds: this.state.previousSelectedElementIds,\r\n });\r\n gesture.initialScale = null;\r\n });\r\n this.startTextEditing = ({ sceneX, sceneY, shouldBind, insertAtParentCenter = true, }) => {\r\n var _a;\r\n let parentCenterPosition = insertAtParentCenter &&\r\n this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n // bind to container when shouldBind is true or\r\n // clicked on center of container\r\n const container = shouldBind || parentCenterPosition\r\n ? (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene.getElements(), sceneX, sceneY, \"text\")\r\n : null;\r\n let existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);\r\n // consider bounded text element if container present\r\n if (container) {\r\n const boundTextElementId = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getBoundTextElementId)(container);\r\n if (boundTextElementId) {\r\n existingTextElement = this.scene.getElement(boundTextElementId);\r\n }\r\n }\r\n if (!existingTextElement && container) {\r\n const fontString = {\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n };\r\n const minWidth = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineWidth)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const minHeight = (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.getApproxMinLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_34__.getFontString)(fontString));\r\n const newHeight = Math.max(container.height, minHeight);\r\n const newWidth = Math.max(container.width, minWidth);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(container, { height: newHeight, width: newWidth });\r\n sceneX = container.x + newWidth / 2;\r\n sceneY = container.y + newHeight / 2;\r\n if (parentCenterPosition) {\r\n parentCenterPosition = this.getTextWysiwygSnappedToCenterPosition(sceneX, sceneY, this.state, this.canvas, window.devicePixelRatio);\r\n }\r\n }\r\n const element = existingTextElement\r\n ? existingTextElement\r\n : (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x: parentCenterPosition\r\n ? parentCenterPosition.elementCenterX\r\n : sceneX,\r\n y: parentCenterPosition\r\n ? parentCenterPosition.elementCenterY\r\n : sceneY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text: \"\",\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: parentCenterPosition\r\n ? \"center\"\r\n : this.state.currentItemTextAlign,\r\n verticalAlign: parentCenterPosition\r\n ? \"middle\"\r\n : _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n containerId: (_a = container === null || container === void 0 ? void 0 : container.id) !== null && _a !== void 0 ? _a : undefined,\r\n });\r\n this.setState({ editingElement: element });\r\n if (existingTextElement) {\r\n // if text element is no longer centered to a container, reset\r\n // verticalAlign to default because it's currently internal-only\r\n if (!parentCenterPosition || element.textAlign !== \"center\") {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, { verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN });\r\n }\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n // case: creating new text not centered to parent elemenent → offset Y\r\n // so that the text is centered to cursor position\r\n if (!parentCenterPosition) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n y: element.y - element.baseline / 2,\r\n });\r\n }\r\n }\r\n this.setState({\r\n editingElement: element,\r\n });\r\n this.handleTextWysiwyg(element, {\r\n isExistingElement: !!existingTextElement,\r\n });\r\n };\r\n this.handleCanvasDoubleClick = (event) => {\r\n // case: double-clicking with arrow/line tool selected would both create\r\n // text and enter multiElement mode\r\n if (this.state.multiElement) {\r\n return;\r\n }\r\n // we should only be able to double click when mode is selection\r\n if (this.state.elementType !== \"selection\") {\r\n return;\r\n }\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1 && (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0])) {\r\n if (!this.state.editingLinearElement ||\r\n this.state.editingLinearElement.elementId !== selectedElements[0].id) {\r\n this.history.resumeRecording();\r\n this.setState({\r\n editingLinearElement: new _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor(selectedElements[0], this.scene),\r\n });\r\n }\r\n return;\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n let { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedGroupIds = (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIds)(this.state);\r\n if (selectedGroupIds.length > 0) {\r\n const hitElement = this.getElementAtPosition(sceneX, sceneY);\r\n const selectedGroupId = hitElement &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getSelectedGroupIdForElement)(hitElement, this.state.selectedGroupIds);\r\n if (selectedGroupId) {\r\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.getElements()));\r\n return;\r\n }\r\n }\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] && !this.state.viewModeEnabled) {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n if (selectedElements.length === 1) {\r\n const selectedElement = selectedElements[0];\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(selectedElement);\r\n if (canBindText) {\r\n sceneX = selectedElement.x + selectedElement.width / 2;\r\n sceneY = selectedElement.y + selectedElement.height / 2;\r\n }\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n }\r\n };\r\n this.handleCanvasPointerMove = (event) => {\r\n this.savePointer(event.clientX, event.clientY, this.state.cursorButton);\r\n if (gesture.pointers.has(event.pointerId)) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n }\r\n const initialScale = gesture.initialScale;\r\n if (gesture.pointers.size === 2 &&\r\n gesture.lastCenter &&\r\n initialScale &&\r\n gesture.initialDistance) {\r\n const center = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n const deltaX = center.x - gesture.lastCenter.x;\r\n const deltaY = center.y - gesture.lastCenter.y;\r\n gesture.lastCenter = center;\r\n const distance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n const scaleFactor = distance / gesture.initialDistance;\r\n this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({\r\n scrollX: scrollX + deltaX / zoom.value,\r\n scrollY: scrollY + deltaY / zoom.value,\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(initialScale * scaleFactor), zoom, { left: offsetLeft, top: offsetTop }, center),\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n }\r\n else {\r\n gesture.lastCenter =\r\n gesture.initialDistance =\r\n gesture.initialScale =\r\n null;\r\n }\r\n if (isHoldingSpace || isPanning || isDraggingScrollBar) {\r\n return;\r\n }\r\n const isPointerOverScrollBars = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop);\r\n const isOverScrollBar = isPointerOverScrollBars.isOverEither;\r\n if (!this.state.draggingElement && !this.state.multiElement) {\r\n if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n const scenePointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const { x: scenePointerX, y: scenePointerY } = scenePointer;\r\n if (this.state.editingLinearElement &&\r\n !this.state.editingLinearElement.isDragging) {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state.editingLinearElement, this.state.gridSize);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({ editingLinearElement });\r\n }\r\n if (editingLinearElement.lastUncommittedPoint != null) {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n else {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElementType)(this.state.elementType)) {\r\n // Hovering with a selected tool or creating new linear element via click\r\n // and point\r\n const { draggingElement } = this.state;\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [scenePointer], this.state.startBoundElement);\r\n }\r\n else {\r\n this.maybeSuggestBindingAtCursor(scenePointer);\r\n }\r\n }\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n const { x: rx, y: ry } = multiElement;\r\n const { points, lastCommittedPoint } = multiElement;\r\n const lastPoint = points[points.length - 1];\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n if (lastPoint === lastCommittedPoint) {\r\n // if we haven't yet created a temp point and we're beyond commit-zone\r\n // threshold, add a point\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastPoint[0], lastPoint[1]) >= _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [...points, [scenePointerX - rx, scenePointerY - ry]],\r\n });\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n // in this branch, we're inside the commit zone, and no uncommitted\r\n // point exists. Thus do nothing (don't add/remove points).\r\n }\r\n }\r\n else if (points.length > 2 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(scenePointerX - rx, scenePointerY - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: points.slice(0, -1),\r\n });\r\n }\r\n else {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(points, this.state.zoom.value)) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n // update last uncommitted point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n points: [\r\n ...points.slice(0, -1),\r\n [scenePointerX - rx, scenePointerY - ry],\r\n ],\r\n });\r\n }\r\n return;\r\n }\r\n const hasDeselectedButton = Boolean(event.buttons);\r\n if (hasDeselectedButton ||\r\n (this.state.elementType !== \"selection\" &&\r\n this.state.elementType !== \"text\")) {\r\n return;\r\n }\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 &&\r\n !isOverScrollBar &&\r\n !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType &&\r\n elementWithTransformHandleType.transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)(elementWithTransformHandleType));\r\n return;\r\n }\r\n }\r\n else if (selectedElements.length > 1 && !isOverScrollBar) {\r\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);\r\n if (transformHandleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType,\r\n }));\r\n return;\r\n }\r\n }\r\n const hitElement = this.getElementAtPosition(scenePointer.x, scenePointer.y);\r\n if (this.state.elementType === \"text\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(hitElement) ? _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.TEXT : _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n }\r\n else if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else if (isOverScrollBar) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n else if (this.state.editingLinearElement) {\r\n const element = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.getElement(this.state.editingLinearElement.elementId);\r\n if (element &&\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(element, this.state, [\r\n scenePointer.x,\r\n scenePointer.y,\r\n ])) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n }\r\n else if (\r\n // if using cmd/ctrl, we're not dragging\r\n !event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD] &&\r\n (hitElement ||\r\n this.isHittingCommonBoundingBoxOfSelectedElements(scenePointer, selectedElements))) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.MOVE);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.AUTO);\r\n }\r\n };\r\n // set touch moving for mobile context menu\r\n this.handleTouchMove = (event) => {\r\n invalidateContextMenu = true;\r\n };\r\n this.handleCanvasPointerDown = (event) => {\r\n // remove any active selection when we start to interact with canvas\r\n // (mainly, we care about removing selection outside the component which\r\n // would prevent our copy handling otherwise)\r\n const selection = document.getSelection();\r\n if (selection === null || selection === void 0 ? void 0 : selection.anchorNode) {\r\n selection.removeAllRanges();\r\n }\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);\r\n this.maybeCleanupAfterMissingPointerUp(event);\r\n if (isPanning) {\r\n return;\r\n }\r\n this.setState({\r\n lastPointerDownWith: event.pointerType,\r\n cursorButton: \"down\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"down\");\r\n if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {\r\n return;\r\n }\r\n // only handle left mouse button or touch\r\n if (event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN &&\r\n event.button !== _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.TOUCH) {\r\n return;\r\n }\r\n this.updateGestureOnPointerDown(event);\r\n // don't select while panning\r\n if (gesture.pointers.size > 1) {\r\n return;\r\n }\r\n // State for the duration of a pointer interaction, which starts with a\r\n // pointerDown event, ends with a pointerUp event (or another pointerDown)\r\n const pointerDownState = this.initialPointerDownState(event);\r\n if (this.handleDraggingScrollBar(event, pointerDownState)) {\r\n return;\r\n }\r\n this.clearSelectionIfNotUsingSelection();\r\n this.updateBindingEnabledOnPointerMove(event);\r\n if (this.handleSelectionOnPointerDown(event, pointerDownState)) {\r\n return;\r\n }\r\n if (this.state.elementType === \"text\") {\r\n this.handleTextOnPointerDown(event, pointerDownState);\r\n return;\r\n }\r\n else if (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\") {\r\n this.handleLinearElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else if (this.state.elementType === \"image\") {\r\n // reset image preview on pointerdown\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.CROSSHAIR);\r\n if (!this.state.pendingImageElement) {\r\n return;\r\n }\r\n this.setState({\r\n draggingElement: this.state.pendingImageElement,\r\n editingElement: this.state.pendingImageElement,\r\n pendingImageElement: null,\r\n multiElement: null,\r\n });\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(this.state.pendingImageElement, {\r\n x,\r\n y,\r\n });\r\n }\r\n else if (this.state.elementType === \"freedraw\") {\r\n this.handleFreeDrawElementOnPointerDown(event, this.state.elementType, pointerDownState);\r\n }\r\n else {\r\n this.createGenericElementOnPointerDown(this.state.elementType, pointerDownState);\r\n }\r\n const onPointerMove = this.onPointerMoveFromPointerDownHandler(pointerDownState);\r\n const onPointerUp = this.onPointerUpFromPointerDownHandler(pointerDownState);\r\n const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);\r\n const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);\r\n lastPointerUp = onPointerUp;\r\n if (!this.state.viewModeEnabled) {\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, onKeyDown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, onKeyUp);\r\n pointerDownState.eventListeners.onMove = onPointerMove;\r\n pointerDownState.eventListeners.onUp = onPointerUp;\r\n pointerDownState.eventListeners.onKeyUp = onKeyUp;\r\n pointerDownState.eventListeners.onKeyDown = onKeyDown;\r\n }\r\n };\r\n this.maybeOpenContextMenuAfterPointerDownOnTouchDevices = (event) => {\r\n // deal with opening context menu on touch devices\r\n if (event.pointerType === \"touch\") {\r\n invalidateContextMenu = false;\r\n if (touchTimeout) {\r\n // If there's already a touchTimeout, this means that there's another\r\n // touch down and we are doing another touch, so we shouldn't open the\r\n // context menu.\r\n invalidateContextMenu = true;\r\n }\r\n else {\r\n // open the context menu with the first touch's clientX and clientY\r\n // if the touch is not moving\r\n touchTimeout = window.setTimeout(() => {\r\n touchTimeout = 0;\r\n if (!invalidateContextMenu) {\r\n this.handleCanvasContextMenu(event);\r\n }\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.TOUCH_CTX_MENU_TIMEOUT);\r\n }\r\n }\r\n };\r\n // Returns whether the event is a panning\r\n this.handleCanvasPanUsingWheelOrSpaceDrag = (event) => {\r\n if (!(gesture.pointers.size === 0 &&\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.WHEEL ||\r\n (event.button === _constants__WEBPACK_IMPORTED_MODULE_11__.POINTER_BUTTON.MAIN && isHoldingSpace) ||\r\n this.state.viewModeEnabled))) {\r\n return false;\r\n }\r\n isPanning = true;\r\n let nextPastePrevented = false;\r\n const isLinux = /Linux/.test(window.navigator.platform);\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRABBING);\r\n let { clientX: lastX, clientY: lastY } = event;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const deltaX = lastX - event.clientX;\r\n const deltaY = lastY - event.clientY;\r\n lastX = event.clientX;\r\n lastY = event.clientY;\r\n /*\r\n * Prevent paste event if we move while middle clicking on Linux.\r\n * See issue #1383.\r\n */\r\n if (isLinux &&\r\n !nextPastePrevented &&\r\n (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1)) {\r\n nextPastePrevented = true;\r\n /* Prevent the next paste event */\r\n const preventNextPaste = (event) => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n event.stopPropagation();\r\n };\r\n /*\r\n * Reenable next paste in case of disabled middle click paste for\r\n * any reason:\r\n * - rigth click paste\r\n * - empty clipboard\r\n */\r\n const enableNextPaste = () => {\r\n setTimeout(() => {\r\n document.body.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }, 100);\r\n };\r\n document.body.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, preventNextPaste);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, enableNextPaste);\r\n }\r\n this.setState({\r\n scrollX: this.state.scrollX - deltaX / this.state.zoom.value,\r\n scrollY: this.state.scrollY - deltaY / this.state.zoom.value,\r\n });\r\n });\r\n const teardown = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((lastPointerUp = () => {\r\n lastPointerUp = null;\r\n isPanning = false;\r\n if (!isHoldingSpace) {\r\n if (this.state.viewModeEnabled) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB);\r\n }\r\n else {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n }\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n }));\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, teardown);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove, {\r\n passive: true,\r\n });\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, teardown);\r\n return true;\r\n };\r\n this.clearSelectionIfNotUsingSelection = () => {\r\n if (this.state.elementType !== \"selection\") {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n };\r\n /**\r\n * @returns whether the pointer event has been completely handled\r\n */\r\n this.handleSelectionOnPointerDown = (event, pointerDownState) => {\r\n var _a;\r\n if (this.state.elementType === \"selection\") {\r\n const elements = this.scene.getElements();\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state);\r\n if (selectedElements.length === 1 && !this.state.editingLinearElement) {\r\n const elementWithTransformHandleType = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getElementWithTransformHandleType)(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);\r\n if (elementWithTransformHandleType != null) {\r\n this.setState({\r\n resizingElement: elementWithTransformHandleType.element,\r\n });\r\n pointerDownState.resize.handleType =\r\n elementWithTransformHandleType.transformHandleType;\r\n }\r\n }\r\n else if (selectedElements.length > 1) {\r\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);\r\n }\r\n if (pointerDownState.resize.handleType) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCursorForResizingElement)({\r\n transformHandleType: pointerDownState.resize.handleType,\r\n }));\r\n pointerDownState.resize.isResizing = true;\r\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));\r\n if (selectedElements.length === 1 &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(selectedElements[0]) &&\r\n selectedElements[0].points.length === 2) {\r\n pointerDownState.resize.arrowDirection = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getResizeArrowDirection)(pointerDownState.resize.handleType, selectedElements[0]);\r\n }\r\n }\r\n else {\r\n if (this.state.editingLinearElement) {\r\n const ret = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerDown(event, this.state, (appState) => this.setState(appState), this.history, pointerDownState.origin);\r\n if (ret.hitElement) {\r\n pointerDownState.hit.element = ret.hitElement;\r\n }\r\n if (ret.didAddPoint) {\r\n return true;\r\n }\r\n }\r\n // hitElement may already be set above, so check first\r\n pointerDownState.hit.element =\r\n (_a = pointerDownState.hit.element) !== null && _a !== void 0 ? _a : this.getElementAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n if (pointerDownState.hit.element) {\r\n pointerDownState.hit.hasHitElementInside =\r\n (0,_element_collision__WEBPACK_IMPORTED_MODULE_45__.isHittingElementNotConsideringBoundingBox)(pointerDownState.hit.element, this.state, [pointerDownState.origin.x, pointerDownState.origin.y]);\r\n }\r\n // For overlapped elements one position may hit\r\n // multiple elements\r\n pointerDownState.hit.allHitElements = this.getElementsAtPosition(pointerDownState.origin.x, pointerDownState.origin.y);\r\n const hitElement = pointerDownState.hit.element;\r\n const someHitElementIsSelected = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hitElement === null || !someHitElementIsSelected) &&\r\n !event.shiftKey &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.clearSelection(hitElement);\r\n }\r\n if (this.state.editingLinearElement) {\r\n this.setState({\r\n selectedElementIds: {\r\n [this.state.editingLinearElement.elementId]: true,\r\n },\r\n });\r\n // If we click on something\r\n }\r\n else if (hitElement != null) {\r\n // on CMD/CTRL, drill down to hit element regardless of groups etc.\r\n if (event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD]) {\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n this.setState((prevState) => (Object.assign(Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.editGroupForSelectedElement)(prevState, hitElement)), { previousSelectedElementIds: this.state.selectedElementIds })));\r\n // mark as not completely handled so as to allow dragging etc.\r\n return false;\r\n }\r\n // deselect if item is selected\r\n // if shift is not clicked, this will always return true\r\n // otherwise, it will trigger selection based on current\r\n // state of the box\r\n if (!this.state.selectedElementIds[hitElement.id]) {\r\n // if we are currently editing a group, exiting editing mode and deselect the group.\r\n if (this.state.editingGroupId &&\r\n !(0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, this.state.editingGroupId)) {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n // Add hit element to selection. At this point if we're not holding\r\n // SHIFT the previously selected element(s) were deselected above\r\n // (make sure you use setState updater to use latest state)\r\n if (!someHitElementIsSelected &&\r\n !pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) {\r\n this.setState((prevState) => {\r\n return (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: true }) }), this.scene.getElements());\r\n });\r\n pointerDownState.hit.wasAddedToSelection = true;\r\n }\r\n }\r\n }\r\n this.setState({\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n }\r\n return false;\r\n };\r\n this.handleTextOnPointerDown = (event, pointerDownState) => {\r\n // if we're currently still editing text, clicking outside\r\n // should only finalize it, not create another (irrespective\r\n // of state.elementLocked)\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)) {\r\n return;\r\n }\r\n let sceneX = pointerDownState.origin.x;\r\n let sceneY = pointerDownState.origin.y;\r\n const element = this.getElementAtPosition(sceneX, sceneY, {\r\n includeBoundTextElement: true,\r\n });\r\n const canBindText = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.hasBoundTextElement)(element);\r\n if (canBindText) {\r\n sceneX = element.x + element.width / 2;\r\n sceneY = element.y + element.height / 2;\r\n }\r\n this.startTextEditing({\r\n sceneX,\r\n sceneY,\r\n shouldBind: false,\r\n insertAtParentCenter: !event.altKey,\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n if (!this.state.elementLocked) {\r\n this.setState({\r\n elementType: \"selection\",\r\n });\r\n }\r\n };\r\n this.handleFreeDrawElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n // Begin a mark capture. This does not have to update state yet.\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, null);\r\n const element = (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.newFreeDrawElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n simulatePressure: event.pressure === 0.5,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n const pressures = element.simulatePressure\r\n ? element.pressures\r\n : [...element.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [[0, 0]],\r\n pressures,\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n };\r\n this.createImageElement = ({ sceneX, sceneY, }) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(sceneX, sceneY, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newImageElement)({\r\n type: \"image\",\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n });\r\n return element;\r\n };\r\n this.handleLinearElementOnPointerDown = (event, elementType, pointerDownState) => {\r\n if (this.state.multiElement) {\r\n const { multiElement } = this.state;\r\n // finalize if completing a loop\r\n if (multiElement.type === \"line\" &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.isPathALoop)(multiElement.points, this.state.zoom.value)) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n const { x: rx, y: ry, lastCommittedPoint } = multiElement;\r\n // clicking inside commit zone → finalize arrow\r\n if (multiElement.points.length > 1 &&\r\n lastCommittedPoint &&\r\n (0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerDownState.origin.x - rx, pointerDownState.origin.y - ry, lastCommittedPoint[0], lastCommittedPoint[1]) < _constants__WEBPACK_IMPORTED_MODULE_11__.LINE_CONFIRM_THRESHOLD) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [multiElement.id]: true }),\r\n }));\r\n // clicking outside commit zone → update reference for last committed\r\n // point\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(multiElement, {\r\n lastCommittedPoint: multiElement.points[multiElement.points.length - 1],\r\n });\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.POINTER);\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.\r\n If so, we want it to be null for start and \"arrow\" for end. If the linear item is not\r\n an arrow, we want it to be null for both. Otherwise, we want it to use the\r\n values from appState. */\r\n const { currentItemStartArrowhead, currentItemEndArrowhead } = this.state;\r\n const [startArrowhead, endArrowhead] = elementType === \"arrow\"\r\n ? [currentItemStartArrowhead, currentItemEndArrowhead]\r\n : [null, null];\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newLinearElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemLinearStrokeSharpness,\r\n startArrowhead,\r\n endArrowhead,\r\n });\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [element.id]: false }),\r\n }));\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(element, {\r\n points: [...element.points, [0, 0]],\r\n });\r\n const boundElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerDownState.origin, this.scene);\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n draggingElement: element,\r\n editingElement: element,\r\n startBoundElement: boundElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n };\r\n this.createGenericElementOnPointerDown = (elementType, pointerDownState) => {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerDownState.origin.x, pointerDownState.origin.y, this.state.gridSize);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newElement)({\r\n type: elementType,\r\n x: gridX,\r\n y: gridY,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n });\r\n if (element.type === \"selection\") {\r\n this.setState({\r\n selectionElement: element,\r\n draggingElement: element,\r\n });\r\n }\r\n else {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({\r\n multiElement: null,\r\n draggingElement: element,\r\n editingElement: element,\r\n });\r\n }\r\n };\r\n this.initializeImage = ({ imageFile, imageElement: _imageElement, showCursorImagePreview = false, }) => __awaiter(this, void 0, void 0, function* () {\r\n var _d, _e, _f, _g;\r\n // at this point this should be guaranteed image file, but we do this check\r\n // to satisfy TS down the line\r\n if (!(0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(imageFile)) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.unsupportedFileType\"));\r\n }\r\n const mimeType = imageFile.type;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, \"wait\");\r\n if (mimeType === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n imageFile = (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.SVGStringToFile)(yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.normalizeSVG)(yield imageFile.text()), imageFile.name);\r\n }\r\n catch (error) {\r\n console.warn(error);\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.svgImageInsertError\"));\r\n }\r\n }\r\n // generate image id (by default the file digest) before any\r\n // resizing/compression takes place to keep it more portable\r\n const fileId = yield (((_e = (_d = this.props).generateIdForFile) === null || _e === void 0 ? void 0 : _e.call(_d, imageFile)) || (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.generateIdFromFile)(imageFile));\r\n if (!fileId) {\r\n console.warn(\"Couldn't generate file id or the supplied `generateIdForFile` didn't resolve to one.\");\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"));\r\n }\r\n const existingFileData = this.files[fileId];\r\n if (!(existingFileData === null || existingFileData === void 0 ? void 0 : existingFileData.dataURL)) {\r\n try {\r\n imageFile = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT,\r\n });\r\n }\r\n catch (error) {\r\n console.error(\"error trying to resing image file on insertion\", error);\r\n }\r\n if (imageFile.size > _constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES) {\r\n throw new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.fileTooBig\", {\r\n maxSize: `${Math.trunc(_constants__WEBPACK_IMPORTED_MODULE_11__.MAX_ALLOWED_FILE_BYTES / 1024 / 1024)}MB`,\r\n }));\r\n }\r\n }\r\n if (showCursorImagePreview) {\r\n const dataURL = (_f = this.files[fileId]) === null || _f === void 0 ? void 0 : _f.dataURL;\r\n // optimization so that we don't unnecessarily resize the original\r\n // full-size file for cursor preview\r\n // (it's much faster to convert the resized dataURL to File)\r\n const resizedFile = dataURL && (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.dataURLToFile)(dataURL);\r\n this.setImagePreviewCursor(resizedFile || imageFile);\r\n }\r\n const dataURL = ((_g = this.files[fileId]) === null || _g === void 0 ? void 0 : _g.dataURL) || (yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imageFile));\r\n const imageElement = (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(_imageElement, {\r\n fileId,\r\n }, false);\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var _h, _j;\r\n try {\r\n this.files = Object.assign(Object.assign({}, this.files), { [fileId]: {\r\n mimeType,\r\n id: fileId,\r\n dataURL,\r\n created: Date.now(),\r\n } });\r\n const cachedImageData = this.imageCache.get(fileId);\r\n if (!cachedImageData) {\r\n this.addNewImagesToImageCache();\r\n yield this.updateImageCache([imageElement]);\r\n }\r\n if ((cachedImageData === null || cachedImageData === void 0 ? void 0 : cachedImageData.image) instanceof Promise) {\r\n yield cachedImageData.image;\r\n }\r\n if (((_h = this.state.pendingImageElement) === null || _h === void 0 ? void 0 : _h.id) !== imageElement.id &&\r\n ((_j = this.state.draggingElement) === null || _j === void 0 ? void 0 : _j.id) !== imageElement.id) {\r\n this.initializeImageDimensions(imageElement, true);\r\n }\r\n resolve(imageElement);\r\n }\r\n catch (error) {\r\n console.error(error);\r\n reject(new Error((0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\")));\r\n }\r\n finally {\r\n if (!showCursorImagePreview) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n }\r\n }\r\n }));\r\n });\r\n /**\r\n * inserts image into elements array and rerenders\r\n */\r\n this.insertImageElement = (imageElement, imageFile, showCursorImagePreview) => __awaiter(this, void 0, void 0, function* () {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n imageElement,\r\n ]);\r\n try {\r\n yield this.initializeImage({\r\n imageFile,\r\n imageElement,\r\n showCursorImagePreview,\r\n });\r\n }\r\n catch (error) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n isDeleted: true,\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n this.setState({\r\n errorMessage: error.message || (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"errors.imageInsertError\"),\r\n });\r\n }\r\n });\r\n this.setImagePreviewCursor = (imageFile) => __awaiter(this, void 0, void 0, function* () {\r\n // mustn't be larger than 128 px\r\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property\r\n const cursorImageSizePx = 96;\r\n const imagePreview = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.resizeImageFile)(imageFile, {\r\n maxWidthOrHeight: cursorImageSizePx,\r\n });\r\n let previewDataURL = yield (0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.getDataURL)(imagePreview);\r\n // SVG cannot be resized via `resizeImageFile` so we resize by rendering to\r\n // a small canvas\r\n if (imageFile.type === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n const img = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.loadHTMLImageElement)(previewDataURL);\r\n let height = Math.min(img.height, cursorImageSizePx);\r\n let width = height * (img.width / img.height);\r\n if (width > cursorImageSizePx) {\r\n width = cursorImageSizePx;\r\n height = width * (img.height / img.width);\r\n }\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.height = height;\r\n canvas.width = width;\r\n const context = canvas.getContext(\"2d\");\r\n context.drawImage(img, 0, 0, width, height);\r\n previewDataURL = canvas.toDataURL(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg);\r\n }\r\n if (this.state.pendingImageElement) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursor)(this.canvas, `url(${previewDataURL}) 4 4, auto`);\r\n }\r\n });\r\n this.onImageAction = ({ insertOnCanvasDirectly } = { insertOnCanvasDirectly: false }) => __awaiter(this, void 0, void 0, function* () {\r\n try {\r\n const clientX = this.state.width / 2 + this.state.offsetLeft;\r\n const clientY = this.state.height / 2 + this.state.offsetTop;\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX, clientY }, this.state);\r\n const imageFile = yield (0,_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.fileOpen)({\r\n description: \"Image\",\r\n extensions: [\"jpg\", \"png\", \"svg\", \"gif\"],\r\n });\r\n const imageElement = this.createImageElement({\r\n sceneX: x,\r\n sceneY: y,\r\n });\r\n if (insertOnCanvasDirectly) {\r\n this.insertImageElement(imageElement, imageFile);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({\r\n selectedElementIds: { [imageElement.id]: true },\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n else {\r\n this.setState({\r\n pendingImageElement: imageElement,\r\n }, () => {\r\n this.insertImageElement(imageElement, imageFile, \r\n /* showCursorImagePreview */ true);\r\n });\r\n }\r\n }\r\n catch (error) {\r\n if (error.name !== \"AbortError\") {\r\n console.error(error);\r\n }\r\n else {\r\n console.warn(error);\r\n }\r\n this.setState({\r\n pendingImageElement: null,\r\n editingElement: null,\r\n elementType: \"selection\",\r\n }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n });\r\n this.initializeImageDimensions = (imageElement, forceNaturalSize = false) => {\r\n var _a;\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(imageElement) &&\r\n ((_a = this.imageCache.get(imageElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n if (!image || image instanceof Promise) {\r\n if (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value) {\r\n const placeholderSize = 100 / this.state.zoom.value;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, {\r\n x: imageElement.x - placeholderSize / 2,\r\n y: imageElement.y - placeholderSize / 2,\r\n width: placeholderSize,\r\n height: placeholderSize,\r\n });\r\n }\r\n return;\r\n }\r\n if (forceNaturalSize ||\r\n // if user-created bounding box is below threshold, assume the\r\n // intention was to click instead of drag, and use the image's\r\n // intrinsic size\r\n (imageElement.width < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value &&\r\n imageElement.height < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD / this.state.zoom.value)) {\r\n const minHeight = Math.max(this.state.height - 120, 160);\r\n // max 65% of canvas height, clamped to <300px, vh - 120px>\r\n const maxHeight = Math.min(minHeight, Math.floor(this.state.height * 0.5) / this.state.zoom.value);\r\n const height = Math.min(image.naturalHeight, maxHeight);\r\n const width = height * (image.naturalWidth / image.naturalHeight);\r\n // add current imageElement width/height to account for previous centering\r\n // of the placholder image\r\n const x = imageElement.x + imageElement.width / 2 - width / 2;\r\n const y = imageElement.y + imageElement.height / 2 - height / 2;\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(imageElement, { x, y, width, height });\r\n }\r\n };\r\n /** updates image cache, refreshing updated elements and/or setting status\r\n to error for images that fail during <img> element creation */\r\n this.updateImageCache = (elements, files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const { updatedFiles, erroredFiles } = yield (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.updateImageCache)({\r\n imageCache: this.imageCache,\r\n fileIds: elements.map((element) => element.fileId),\r\n files,\r\n });\r\n if (updatedFiles.size || erroredFiles.size) {\r\n for (const element of elements) {\r\n if (updatedFiles.has(element.fileId)) {\r\n (0,_renderer_renderElement__WEBPACK_IMPORTED_MODULE_29__.invalidateShapeForElement)(element);\r\n }\r\n }\r\n }\r\n if (erroredFiles.size) {\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().map((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(element) &&\r\n erroredFiles.has(element.fileId)) {\r\n return (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.newElementWith)(element, {\r\n status: \"error\",\r\n });\r\n }\r\n return element;\r\n }));\r\n }\r\n return { updatedFiles, erroredFiles };\r\n });\r\n /** adds new images to imageCache and re-renders if needed */\r\n this.addNewImagesToImageCache = (imageElements = (0,_element_image__WEBPACK_IMPORTED_MODULE_41__.getInitializedImageElements)(this.scene.getElements()), files = this.files) => __awaiter(this, void 0, void 0, function* () {\r\n const uncachedImageElements = imageElements.filter((element) => !element.isDeleted && !this.imageCache.has(element.fileId));\r\n if (uncachedImageElements.length) {\r\n const { updatedFiles } = yield this.updateImageCache(uncachedImageElements, files);\r\n if (updatedFiles.size) {\r\n this.scene.informMutation();\r\n }\r\n }\r\n });\r\n /** generally you should use `addNewImagesToImageCache()` directly if you need\r\n * to render new images. This is just a failsafe */\r\n this.scheduleImageRefresh = lodash_throttle__WEBPACK_IMPORTED_MODULE_42___default()(() => {\r\n this.addNewImagesToImageCache();\r\n }, _constants__WEBPACK_IMPORTED_MODULE_11__.IMAGE_RENDER_TIMEOUT);\r\n this.updateBindingEnabledOnPointerMove = (event) => {\r\n const shouldEnableBinding = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.shouldEnableBindingForPointerEvent)(event);\r\n if (this.state.isBindingEnabled !== shouldEnableBinding) {\r\n this.setState({ isBindingEnabled: shouldEnableBinding });\r\n }\r\n };\r\n this.maybeSuggestBindingAtCursor = (pointerCoords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(pointerCoords, this.scene);\r\n this.setState({\r\n suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],\r\n });\r\n };\r\n this.maybeSuggestBindingsForLinearElementAtCoords = (linearElement, \r\n /** scene coords */\r\n pointerCoords, \r\n // During line creation the start binding hasn't been written yet\r\n // into `linearElement`\r\n oppositeBindingBoundElement) => {\r\n if (!pointerCoords.length) {\r\n return;\r\n }\r\n const suggestedBindings = pointerCoords.reduce((acc, coords) => {\r\n const hoveredBindableElement = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getHoveredElementForBinding)(coords, this.scene);\r\n if (hoveredBindableElement != null &&\r\n !(0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isLinearElementSimpleAndAlreadyBound)(linearElement, oppositeBindingBoundElement === null || oppositeBindingBoundElement === void 0 ? void 0 : oppositeBindingBoundElement.id, hoveredBindableElement)) {\r\n acc.push(hoveredBindableElement);\r\n }\r\n return acc;\r\n }, []);\r\n this.setState({ suggestedBindings });\r\n };\r\n this.handleCanvasRef = (canvas) => {\r\n var _a, _b, _c;\r\n // canvas is null when unmounting\r\n if (canvas !== null) {\r\n this.canvas = canvas;\r\n this.rc = roughjs_bin_rough__WEBPACK_IMPORTED_MODULE_2__[\"default\"].canvas(this.canvas);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel, {\r\n passive: false,\r\n });\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n this.canvas.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n else {\r\n (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.WHEEL, this.handleWheel);\r\n (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_START, this.onTapStart);\r\n (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.TOUCH_END, this.onTapEnd);\r\n }\r\n };\r\n this.handleAppOnDrop = (event) => __awaiter(this, void 0, void 0, function* () {\r\n var _k, _l;\r\n try {\r\n const file = event.dataTransfer.files[0];\r\n if ((0,_data_blob__WEBPACK_IMPORTED_MODULE_40__.isSupportedImageFile)(file)) {\r\n // first attempt to decode scene from the image if it's embedded\r\n // ---------------------------------------------------------------------\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.png || (file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.svg) {\r\n try {\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n const scene = yield (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted());\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n return;\r\n }\r\n catch (error) {\r\n if (error.name !== \"EncodingError\") {\r\n throw error;\r\n }\r\n }\r\n }\r\n // if no scene is embedded or we fail for whatever reason, fall back\r\n // to importing as regular image\r\n // ---------------------------------------------------------------------\r\n const { x: sceneX, y: sceneY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const imageElement = this.createImageElement({ sceneX, sceneY });\r\n this.insertImageElement(imageElement, file);\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } });\r\n return;\r\n }\r\n }\r\n catch (error) {\r\n return this.setState({\r\n isLoading: false,\r\n errorMessage: error.message,\r\n });\r\n }\r\n const libraryShapes = event.dataTransfer.getData(_constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib);\r\n if (libraryShapes !== \"\") {\r\n this.addElementsFromPasteOrLibrary({\r\n elements: JSON.parse(libraryShapes),\r\n position: event,\r\n files: null,\r\n });\r\n return;\r\n }\r\n const file = (_k = event.dataTransfer) === null || _k === void 0 ? void 0 : _k.files[0];\r\n if ((file === null || file === void 0 ? void 0 : file.type) === _constants__WEBPACK_IMPORTED_MODULE_11__.MIME_TYPES.excalidrawlib ||\r\n ((_l = file === null || file === void 0 ? void 0 : file.name) === null || _l === void 0 ? void 0 : _l.endsWith(\".excalidrawlib\"))) {\r\n this.library\r\n .importLibrary(file)\r\n .then(() => {\r\n // Close and then open to get the libraries updated\r\n this.setState({ isLibraryOpen: false });\r\n this.setState({ isLibraryOpen: true });\r\n })\r\n .catch((error) => this.setState({ isLoading: false, errorMessage: error.message }));\r\n // default: assume an Excalidraw file regardless of extension/MimeType\r\n }\r\n else {\r\n this.setState({ isLoading: true });\r\n if (_data_filesystem__WEBPACK_IMPORTED_MODULE_43__.nativeFileSystemSupported) {\r\n try {\r\n // This will only work as of Chrome 86,\r\n // but can be safely ignored on older releases.\r\n const item = event.dataTransfer.items[0];\r\n file.handle = yield item.getAsFileSystemHandle();\r\n }\r\n catch (error) {\r\n console.warn(error.name, error.message);\r\n }\r\n }\r\n yield this.loadFileToCanvas(file);\r\n }\r\n });\r\n this.loadFileToCanvas = (file) => {\r\n (0,_data__WEBPACK_IMPORTED_MODULE_12__.loadFromBlob)(file, this.state, this.scene.getElementsIncludingDeleted())\r\n .then((scene) => {\r\n this.syncActionResult(Object.assign(Object.assign({}, scene), { appState: Object.assign(Object.assign({}, (scene.appState || this.state)), { isLoading: false }), replaceFiles: true, commitToHistory: true }));\r\n })\r\n .catch((error) => {\r\n this.setState({ isLoading: false, errorMessage: error.message });\r\n });\r\n };\r\n this.handleCanvasContextMenu = (event) => {\r\n event.preventDefault();\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const element = this.getElementAtPosition(x, y, { preferSelected: true });\r\n const type = element ? \"element\" : \"canvas\";\r\n const container = this.excalidrawContainerRef.current;\r\n const { top: offsetTop, left: offsetLeft } = container.getBoundingClientRect();\r\n const left = event.clientX - offsetLeft;\r\n const top = event.clientY - offsetTop;\r\n if (element && !this.state.selectedElementIds[element.id]) {\r\n this.setState({ selectedElementIds: { [element.id]: true } }, () => {\r\n this._openContextMenu({ top, left }, type);\r\n });\r\n }\r\n else {\r\n this._openContextMenu({ top, left }, type);\r\n }\r\n };\r\n this.maybeDragNewGenericElement = (pointerDownState, event) => {\r\n var _a;\r\n const draggingElement = this.state.draggingElement;\r\n const pointerCoords = pointerDownState.lastCoords;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"selection\") {\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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));\r\n }\r\n else {\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n const image = (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isInitializedImageElement)(draggingElement) &&\r\n ((_a = this.imageCache.get(draggingElement.fileId)) === null || _a === void 0 ? void 0 : _a.image);\r\n const aspectRatio = image && !(image instanceof Promise)\r\n ? image.width / image.height\r\n : null;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragNewElement)(draggingElement, this.state.elementType, 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)\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldResizeFromCenter)(event), aspectRatio);\r\n this.maybeSuggestBindingForAll([draggingElement]);\r\n }\r\n };\r\n this.maybeHandleResize = (pointerDownState, event) => {\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const transformHandleType = pointerDownState.resize.handleType;\r\n this.setState({\r\n // TODO: rename this state field to \"isScaling\" to distinguish\r\n // it from the generic \"isResizing\" which includes scaling and\r\n // rotating\r\n isResizing: transformHandleType && transformHandleType !== \"rotation\",\r\n isRotating: transformHandleType === \"rotation\",\r\n });\r\n const pointerCoords = pointerDownState.lastCoords;\r\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);\r\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])\r\n ? !(0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event)\r\n : (0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldMaintainAspectRatio)(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n return true;\r\n }\r\n return false;\r\n };\r\n /** @private use this.handleCanvasContextMenu */\r\n this._openContextMenu = ({ left, top, }, type) => {\r\n const maybeGroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeUngroupAction = _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipHorizontal = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const maybeFlipVertical = _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical.contextItemPredicate(this.actionManager.getElementsIncludingDeleted(), this.actionManager.getAppState());\r\n const separator = \"separator\";\r\n const elements = this.scene.getElements();\r\n const options = [];\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng);\r\n }\r\n if (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0) {\r\n options.push(_actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg);\r\n }\r\n if (type === \"canvas\") {\r\n const viewModeOptions = [\r\n ...options,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" && _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ];\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: viewModeOptions,\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && navigator.clipboard && separator,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsPng,\r\n _clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText &&\r\n elements.length > 0 &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyAsSvg,\r\n ((_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardBlob && elements.length > 0) ||\r\n (_clipboard__WEBPACK_IMPORTED_MODULE_10__.probablySupportsClipboardWriteText && elements.length > 0)) &&\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSelectAll,\r\n separator,\r\n typeof this.props.gridModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleGridMode,\r\n typeof this.props.zenModeEnabled === \"undefined\" &&\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleZenMode,\r\n typeof this.props.viewModeEnabled === \"undefined\" &&\r\n _actions_actionToggleViewMode__WEBPACK_IMPORTED_MODULE_39__.actionToggleViewMode,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionToggleStats,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n else if (type === \"element\") {\r\n if (this.state.viewModeEnabled) {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy, ...options],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n else {\r\n _ContextMenu__WEBPACK_IMPORTED_MODULE_35__[\"default\"].push({\r\n options: [\r\n this.isMobile && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCut,\r\n this.isMobile && navigator.clipboard && _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopy,\r\n this.isMobile &&\r\n navigator.clipboard && {\r\n name: \"paste\",\r\n perform: (elements, appStates) => {\r\n this.pasteFromClipboard(null);\r\n return {\r\n commitToHistory: false,\r\n };\r\n },\r\n contextItemLabel: \"labels.paste\",\r\n },\r\n this.isMobile && separator,\r\n ...options,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionCopyStyles,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionPasteStyles,\r\n separator,\r\n maybeGroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionGroup,\r\n maybeUngroupAction && _actions__WEBPACK_IMPORTED_MODULE_4__.actionUngroup,\r\n (maybeGroupAction || maybeUngroupAction) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionAddToLibrary,\r\n separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendBackward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringForward,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionSendToBack,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionBringToFront,\r\n separator,\r\n maybeFlipHorizontal && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipHorizontal,\r\n maybeFlipVertical && _actions__WEBPACK_IMPORTED_MODULE_4__.actionFlipVertical,\r\n (maybeFlipHorizontal || maybeFlipVertical) && separator,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDuplicateSelection,\r\n _actions__WEBPACK_IMPORTED_MODULE_4__.actionDeleteSelected,\r\n ],\r\n top,\r\n left,\r\n actionManager: this.actionManager,\r\n appState: this.state,\r\n container: this.excalidrawContainerRef.current,\r\n });\r\n }\r\n }\r\n };\r\n this.handleWheel = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n event.preventDefault();\r\n if (isPanning) {\r\n return;\r\n }\r\n const { deltaX, deltaY } = event;\r\n const { selectedElementIds, previousSelectedElementIds } = this.state;\r\n // note that event.ctrlKey is necessary to handle pinch zooming\r\n if (event.metaKey || event.ctrlKey) {\r\n const sign = Math.sign(deltaY);\r\n const MAX_STEP = 10;\r\n let delta = Math.abs(deltaY);\r\n if (delta > MAX_STEP) {\r\n delta = MAX_STEP;\r\n }\r\n delta *= sign;\r\n if (Object.keys(previousSelectedElementIds).length !== 0) {\r\n setTimeout(() => {\r\n this.setState({\r\n selectedElementIds: previousSelectedElementIds,\r\n previousSelectedElementIds: {},\r\n });\r\n }, 1000);\r\n }\r\n let newZoom = this.state.zoom.value - delta / 100;\r\n // increase zoom steps the more zoomed-in we are (applies to >100% only)\r\n newZoom += Math.log10(Math.max(1, this.state.zoom.value)) * -sign;\r\n // round to nearest step\r\n newZoom = Math.round(newZoom * _constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100) / (_constants__WEBPACK_IMPORTED_MODULE_11__.ZOOM_STEP * 100);\r\n this.setState(({ zoom, offsetLeft, offsetTop }) => ({\r\n zoom: (0,_scene_zoom__WEBPACK_IMPORTED_MODULE_32__.getNewZoom)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getNormalizedZoom)(newZoom), zoom, { left: offsetLeft, top: offsetTop }, {\r\n x: cursorX,\r\n y: cursorY,\r\n }),\r\n selectedElementIds: {},\r\n previousSelectedElementIds: Object.keys(selectedElementIds).length !== 0\r\n ? selectedElementIds\r\n : previousSelectedElementIds,\r\n shouldCacheIgnoreZoom: true,\r\n }));\r\n this.resetShouldCacheIgnoreZoomDebounced();\r\n return;\r\n }\r\n // scroll horizontally when shift pressed\r\n if (event.shiftKey) {\r\n this.setState(({ zoom, scrollX }) => ({\r\n // on Mac, shift+wheel tends to result in deltaX\r\n scrollX: scrollX - (deltaY || deltaX) / zoom.value,\r\n }));\r\n return;\r\n }\r\n this.setState(({ zoom, scrollX, scrollY }) => ({\r\n scrollX: scrollX - deltaX / zoom.value,\r\n scrollY: scrollY - deltaY / zoom.value,\r\n }));\r\n });\r\n this.savePointer = (x, y, button) => {\r\n var _a, _b;\r\n if (!x || !y) {\r\n return;\r\n }\r\n const pointer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: x, clientY: y }, this.state);\r\n if (isNaN(pointer.x) || isNaN(pointer.y)) {\r\n // sometimes the pointer goes off screen\r\n }\r\n (_b = (_a = this.props).onPointerUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, {\r\n pointer,\r\n button,\r\n pointersMap: gesture.pointers,\r\n });\r\n };\r\n this.resetShouldCacheIgnoreZoomDebounced = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.debounce)(() => {\r\n if (!this.unmounted) {\r\n this.setState({ shouldCacheIgnoreZoom: false });\r\n }\r\n }, 300);\r\n this.updateDOMRect = (cb) => {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { width, height, left: offsetLeft, top: offsetTop, } = excalidrawContainer.getBoundingClientRect();\r\n const { width: currentWidth, height: currentHeight, offsetTop: currentOffsetTop, offsetLeft: currentOffsetLeft, } = this.state;\r\n if (width === currentWidth &&\r\n height === currentHeight &&\r\n offsetLeft === currentOffsetLeft &&\r\n offsetTop === currentOffsetTop) {\r\n if (cb) {\r\n cb();\r\n }\r\n return;\r\n }\r\n this.setState({\r\n width,\r\n height,\r\n offsetLeft,\r\n offsetTop,\r\n }, () => {\r\n cb && cb();\r\n });\r\n }\r\n };\r\n this.refresh = () => {\r\n this.setState(Object.assign({}, this.getCanvasOffsets()));\r\n };\r\n const defaultAppState = (0,_appState__WEBPACK_IMPORTED_MODULE_9__.getDefaultAppState)();\r\n const { excalidrawRef, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, theme = defaultAppState.theme, name = defaultAppState.name, } = props;\r\n this.state = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultAppState), { theme, isLoading: true }), this.getCanvasOffsets()), { viewModeEnabled,\r\n zenModeEnabled, gridSize: gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null, name, width: window.innerWidth, height: window.innerHeight });\r\n this.id = (0,nanoid__WEBPACK_IMPORTED_MODULE_46__.nanoid)();\r\n if (excalidrawRef) {\r\n const readyPromise = (\"current\" in excalidrawRef && ((_a = excalidrawRef.current) === null || _a === void 0 ? void 0 : _a.readyPromise)) ||\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resolvablePromise)();\r\n const api = {\r\n ready: true,\r\n readyPromise,\r\n updateScene: this.updateScene,\r\n addFiles: this.addFiles,\r\n resetScene: this.resetScene,\r\n getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,\r\n history: {\r\n clear: this.resetHistory,\r\n },\r\n scrollToContent: this.scrollToContent,\r\n getSceneElements: this.getSceneElements,\r\n getAppState: () => this.state,\r\n getFiles: () => this.files,\r\n refresh: this.refresh,\r\n importLibrary: this.importLibraryFromUrl,\r\n setToastMessage: this.setToastMessage,\r\n id: this.id,\r\n };\r\n if (typeof excalidrawRef === \"function\") {\r\n excalidrawRef(api);\r\n }\r\n else {\r\n excalidrawRef.current = api;\r\n }\r\n readyPromise.resolve(api);\r\n }\r\n this.excalidrawContainerValue = {\r\n container: this.excalidrawContainerRef.current,\r\n id: this.id,\r\n };\r\n this.scene = new _scene_Scene__WEBPACK_IMPORTED_MODULE_31__[\"default\"]();\r\n this.library = new _data_library__WEBPACK_IMPORTED_MODULE_14__[\"default\"](this);\r\n this.history = new _history__WEBPACK_IMPORTED_MODULE_24__[\"default\"]();\r\n this.actionManager = new _actions_manager__WEBPACK_IMPORTED_MODULE_6__.ActionManager(this.syncActionResult, () => this.state, () => this.scene.getElementsIncludingDeleted(), this);\r\n this.actionManager.registerAll(_actions_register__WEBPACK_IMPORTED_MODULE_7__.actions);\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createUndoAction)(this.history));\r\n this.actionManager.registerAction((0,_actions_actionHistory__WEBPACK_IMPORTED_MODULE_5__.createRedoAction)(this.history));\r\n }\r\n renderCanvas() {\r\n const canvasScale = window.devicePixelRatio;\r\n const { width: canvasDOMWidth, height: canvasDOMHeight, viewModeEnabled, } = this.state;\r\n const canvasWidth = canvasDOMWidth * canvasScale;\r\n const canvasHeight = canvasDOMHeight * canvasScale;\r\n if (viewModeEnabled) {\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n cursor: _constants__WEBPACK_IMPORTED_MODULE_11__.CURSOR_TYPE.GRAB,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"canvas\", Object.assign({ className: \"excalidraw__canvas\", style: {\r\n width: canvasDOMWidth,\r\n height: canvasDOMHeight,\r\n }, width: canvasWidth, height: canvasHeight, ref: this.handleCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.removePointer, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove }, { children: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.t)(\"labels.drawingCanvas\") }), void 0));\r\n }\r\n render() {\r\n var _a, _b;\r\n const { zenModeEnabled, viewModeEnabled } = this.state;\r\n const { onCollabButtonClick, renderTopRightUI, renderFooter, renderCustomStats, } = this.props;\r\n return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", Object.assign({ className: (0,clsx__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(\"excalidraw excalidraw-container\", {\r\n \"excalidraw--view-mode\": viewModeEnabled,\r\n \"excalidraw--mobile\": this.isMobile,\r\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)(IsMobileContext.Provider, Object.assign({ value: this.isMobile }, { children: [(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.getElements(), onCollabButtonClick: onCollabButtonClick, onLockToggle: this.toggleLock, onInsertElements: (elements) => this.addElementsFromPasteOrLibrary({\r\n elements,\r\n position: \"center\",\r\n files: null,\r\n }), zenModeEnabled: zenModeEnabled, toggleZenMode: this.toggleZenMode, langCode: (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.getLanguage)().code, isCollaborating: this.props.isCollaborating || false, renderTopRightUI: renderTopRightUI, renderCustomFooter: renderFooter, viewModeEnabled: viewModeEnabled, showExitZenModeBtn: typeof ((_a = this.props) === null || _a === void 0 ? void 0 : _a.zenModeEnabled) === \"undefined\" &&\r\n zenModeEnabled, showThemeBtn: typeof ((_b = this.props) === null || _b === void 0 ? void 0 : _b.theme) === \"undefined\" &&\r\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 }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-textEditorContainer\" }, void 0), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", { className: \"excalidraw-contextMenuContainer\" }, void 0), this.state.showStats && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Stats__WEBPACK_IMPORTED_MODULE_37__.Stats, { appState: this.state, setAppState: this.setAppState, elements: this.scene.getElements(), onClose: this.toggleStats, renderCustomStats: renderCustomStats }, void 0)), this.state.toastMessage !== null && ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_Toast__WEBPACK_IMPORTED_MODULE_38__.Toast, { message: this.state.toastMessage, clearToast: this.clearToast }, void 0)), (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"main\", { children: this.renderCanvas() }, void 0)] }), void 0) }), void 0) }), void 0));\r\n }\r\n componentDidMount() {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function* () {\r\n this.excalidrawContainerValue.container =\r\n this.excalidrawContainerRef.current;\r\n if (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n const setState = this.setState.bind(this);\r\n Object.defineProperties(window.h, {\r\n state: {\r\n configurable: true,\r\n get: () => {\r\n return this.state;\r\n },\r\n },\r\n setState: {\r\n configurable: true,\r\n value: (...args) => {\r\n return this.setState(...args);\r\n },\r\n },\r\n app: {\r\n configurable: true,\r\n value: this,\r\n },\r\n history: {\r\n configurable: true,\r\n value: this.history,\r\n },\r\n });\r\n }\r\n this.scene.addCallback(this.onSceneUpdated);\r\n this.addEventListeners();\r\n if (this.excalidrawContainerRef.current) {\r\n this.focusContainer();\r\n }\r\n if (\"ResizeObserver\" in window && ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current)) {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n // compute isMobile state\r\n // ---------------------------------------------------------------------\r\n const { width, height } = this.excalidrawContainerRef.current.getBoundingClientRect();\r\n this.isMobile =\r\n width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT ||\r\n (height < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE && width < _constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE);\r\n // refresh offsets\r\n // ---------------------------------------------------------------------\r\n this.updateDOMRect();\r\n });\r\n (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.excalidrawContainerRef.current);\r\n }\r\n else if (window.matchMedia) {\r\n const mediaQuery = window.matchMedia(`(max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${_constants__WEBPACK_IMPORTED_MODULE_11__.MQ_MAX_WIDTH_LANDSCAPE}px)`);\r\n const handler = () => (this.isMobile = mediaQuery.matches);\r\n mediaQuery.addListener(handler);\r\n this.detachIsMobileMqHandler = () => mediaQuery.removeListener(handler);\r\n }\r\n const searchParams = new URLSearchParams(window.location.search.slice(1));\r\n if (searchParams.has(\"web-share-target\")) {\r\n // Obtain a file that was shared via the Web Share Target API.\r\n this.restoreFileFromShare();\r\n }\r\n else {\r\n this.updateDOMRect(this.initializeScene);\r\n }\r\n });\r\n }\r\n componentWillUnmount() {\r\n var _a;\r\n this.files = {};\r\n this.imageCache.clear();\r\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\r\n this.unmounted = true;\r\n this.removeEventListeners();\r\n this.scene.destroy();\r\n clearTimeout(touchTimeout);\r\n touchTimeout = 0;\r\n }\r\n removeEventListeners() {\r\n var _a, _b;\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n (_a = this.nearestScrollableContainer) === null || _a === void 0 ? void 0 : _a.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n (_b = this.detachIsMobileMqHandler) === null || _b === void 0 ? void 0 : _b.call(this);\r\n }\r\n addEventListeners() {\r\n var _a, _b;\r\n this.removeEventListeners();\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, this.removePointer); // #3553\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.COPY, this.onCopy);\r\n if (this.props.handleKeyboardGlobally) {\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, this.onKeyDown, false);\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, this.onKeyUp, { passive: true });\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.MOUSE_MOVE, this.updateCurrentCursorPosition);\r\n // rerender text elements on font load to fix #637 && #1553\r\n (_b = (_a = document.fonts) === null || _a === void 0 ? void 0 : _a.addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, \"loadingdone\", this.onFontLoaded);\r\n // Safari-only desktop pinch zoom\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_START, this.onGestureStart, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_CHANGE, this.onGestureChange, false);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.GESTURE_END, this.onGestureEnd, false);\r\n if (this.state.viewModeEnabled) {\r\n return;\r\n }\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.PASTE, this.pasteFromClipboard);\r\n document.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.CUT, this.onCut);\r\n if (this.props.detectScroll) {\r\n this.nearestScrollableContainer = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.getNearestScrollableContainer)(this.excalidrawContainerRef.current);\r\n this.nearestScrollableContainer.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.SCROLL, this.onScroll);\r\n }\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.RESIZE, this.onResize, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.UNLOAD, this.onUnload, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.BLUR, this.onBlur, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DRAG_OVER, this.disableEvent, false);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.DROP, this.disableEvent, false);\r\n }\r\n componentDidUpdate(prevProps, prevState) {\r\n var _a, _b, _c;\r\n if (prevProps.langCode !== this.props.langCode) {\r\n this.updateLanguage();\r\n }\r\n if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {\r\n this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });\r\n }\r\n if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {\r\n this.addEventListeners();\r\n this.deselectElements();\r\n }\r\n if (prevProps.zenModeEnabled !== this.props.zenModeEnabled) {\r\n this.setState({ zenModeEnabled: !!this.props.zenModeEnabled });\r\n }\r\n if (prevProps.theme !== this.props.theme && this.props.theme) {\r\n this.setState({ theme: this.props.theme });\r\n }\r\n if (prevProps.gridModeEnabled !== this.props.gridModeEnabled) {\r\n this.setState({\r\n gridSize: this.props.gridModeEnabled ? _constants__WEBPACK_IMPORTED_MODULE_11__.GRID_SIZE : null,\r\n });\r\n }\r\n if (this.props.name && prevProps.name !== this.props.name) {\r\n this.setState({\r\n name: this.props.name,\r\n });\r\n }\r\n (_a = this.excalidrawContainerRef.current) === null || _a === void 0 ? void 0 : _a.classList.toggle(\"theme--dark\", this.state.theme === \"dark\");\r\n if (this.state.editingLinearElement &&\r\n !this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {\r\n // defer so that the commitToHistory flag isn't reset via current update\r\n setTimeout(() => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n const { multiElement } = prevState;\r\n if (prevState.elementType !== this.state.elementType &&\r\n multiElement != null &&\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(multiElement)) {\r\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)));\r\n }\r\n const cursorButton = {};\r\n const pointerViewportCoords = {};\r\n const remoteSelectedElementIds = {};\r\n const pointerUsernames = {};\r\n const pointerUserStates = {};\r\n this.state.collaborators.forEach((user, socketId) => {\r\n if (user.selectedElementIds) {\r\n for (const id of Object.keys(user.selectedElementIds)) {\r\n if (!(id in remoteSelectedElementIds)) {\r\n remoteSelectedElementIds[id] = [];\r\n }\r\n remoteSelectedElementIds[id].push(socketId);\r\n }\r\n }\r\n if (!user.pointer) {\r\n return;\r\n }\r\n if (user.username) {\r\n pointerUsernames[socketId] = user.username;\r\n }\r\n if (user.userState) {\r\n pointerUserStates[socketId] = user.userState;\r\n }\r\n pointerViewportCoords[socketId] = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: user.pointer.x,\r\n sceneY: user.pointer.y,\r\n }, this.state);\r\n cursorButton[socketId] = user.button;\r\n });\r\n const renderingElements = this.scene.getElements().filter((element) => {\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(element)) {\r\n if (\r\n // not placed on canvas yet (but in elements array)\r\n this.state.pendingImageElement &&\r\n element.id === this.state.pendingImageElement.id) {\r\n return false;\r\n }\r\n }\r\n // don't render text element that's being currently edited (it's\r\n // rendered on remote only)\r\n return (!this.state.editingElement ||\r\n this.state.editingElement.type !== \"text\" ||\r\n element.id !== this.state.editingElement.id);\r\n });\r\n const { atLeastOneVisibleElement, scrollBars } = (0,_renderer__WEBPACK_IMPORTED_MODULE_28__.renderScene)(renderingElements, this.state, this.state.selectionElement, window.devicePixelRatio, this.rc, this.canvas, {\r\n scrollX: this.state.scrollX,\r\n scrollY: this.state.scrollY,\r\n viewBackgroundColor: this.state.viewBackgroundColor,\r\n zoom: this.state.zoom,\r\n remotePointerViewportCoords: pointerViewportCoords,\r\n remotePointerButton: cursorButton,\r\n remoteSelectedElementIds,\r\n remotePointerUsernames: pointerUsernames,\r\n remotePointerUserStates: pointerUserStates,\r\n shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,\r\n theme: this.state.theme,\r\n imageCache: this.imageCache,\r\n isExporting: false,\r\n renderScrollbars: !this.isMobile,\r\n });\r\n if (scrollBars) {\r\n currentScrollBars = scrollBars;\r\n }\r\n const scrolledOutside = \r\n // hide when editing text\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? false\r\n : !atLeastOneVisibleElement && renderingElements.length > 0;\r\n if (this.state.scrolledOutside !== scrolledOutside) {\r\n this.setState({ scrolledOutside });\r\n }\r\n this.history.record(this.state, this.scene.getElementsIncludingDeleted());\r\n this.scheduleImageRefresh();\r\n // Do not notify consumers if we're still loading the scene. Among other\r\n // potential issues, this fixes a case where the tab isn't focused during\r\n // init, which would trigger onChange with empty elements, which would then\r\n // override whatever is in localStorage currently.\r\n if (!this.state.isLoading) {\r\n (_c = (_b = this.props).onChange) === null || _c === void 0 ? void 0 : _c.call(_b, this.scene.getElementsIncludingDeleted(), this.state, this.files);\r\n }\r\n }\r\n static resetTapTwice() {\r\n didTapTwice = false;\r\n }\r\n addTextFromPaste(text) {\r\n const { x, y } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)({ clientX: cursorX, clientY: cursorY }, this.state);\r\n const element = (0,_element__WEBPACK_IMPORTED_MODULE_16__.newTextElement)({\r\n x,\r\n y,\r\n strokeColor: this.state.currentItemStrokeColor,\r\n backgroundColor: this.state.currentItemBackgroundColor,\r\n fillStyle: this.state.currentItemFillStyle,\r\n strokeWidth: this.state.currentItemStrokeWidth,\r\n strokeStyle: this.state.currentItemStrokeStyle,\r\n roughness: this.state.currentItemRoughness,\r\n opacity: this.state.currentItemOpacity,\r\n strokeSharpness: this.state.currentItemStrokeSharpness,\r\n text,\r\n fontSize: this.state.currentItemFontSize,\r\n fontFamily: this.state.currentItemFontFamily,\r\n textAlign: this.state.currentItemTextAlign,\r\n verticalAlign: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_VERTICAL_ALIGN,\r\n });\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted(),\r\n element,\r\n ]);\r\n this.setState({ selectedElementIds: { [element.id]: true } });\r\n this.history.resumeRecording();\r\n }\r\n selectShapeTool(elementType) {\r\n if (!isHoldingSpace) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, elementType);\r\n }\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_34__.isToolIcon)(document.activeElement)) {\r\n this.focusContainer();\r\n }\r\n if (!(0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElementType)(elementType)) {\r\n this.setState({ suggestedBindings: [] });\r\n }\r\n if (elementType === \"image\") {\r\n this.onImageAction();\r\n }\r\n if (elementType !== \"selection\") {\r\n this.setState({\r\n elementType,\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n else {\r\n this.setState({ elementType });\r\n }\r\n }\r\n handleTextWysiwyg(element, { isExistingElement = false, }) {\r\n const updateElement = (text, originalText, isDeleted = false, updateDimensions = false) => {\r\n this.scene.replaceAllElements([\r\n ...this.scene.getElementsIncludingDeleted().map((_element) => {\r\n if (_element.id === element.id && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(_element)) {\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.updateTextElement)(_element, {\r\n text,\r\n isDeleted,\r\n originalText,\r\n }, updateDimensions);\r\n }\r\n return _element;\r\n }),\r\n ]);\r\n };\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.textWysiwyg)({\r\n id: element.id,\r\n appState: this.state,\r\n canvas: this.canvas,\r\n getViewportCoords: (x, y) => {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({\r\n sceneX: x,\r\n sceneY: y,\r\n }, this.state);\r\n return [\r\n viewportX,\r\n viewportY, // - this.state.offsetTop, //* (2 - this.state.zoom.value),\r\n ];\r\n },\r\n onChange: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((text) => {\r\n updateElement(text, text, false, !element.containerId);\r\n if ((0,_element__WEBPACK_IMPORTED_MODULE_16__.isNonDeletedElement)(element)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.updateBoundElements)(element);\r\n }\r\n }),\r\n onSubmit: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(({ text, viaKeyboard, originalText }) => {\r\n const isDeleted = !text.trim();\r\n updateElement(text, originalText, isDeleted, true);\r\n // select the created text element only if submitting via keyboard\r\n // (when submitting via click it should act as signal to deselect)\r\n if (!isDeleted && viaKeyboard) {\r\n const elementIdToSelect = element.containerId\r\n ? element.containerId\r\n : element.id;\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [elementIdToSelect]: true }),\r\n }));\r\n }\r\n if (isDeleted) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDeletion)(this.scene.getElements(), [element]);\r\n }\r\n if (!isDeleted || isExistingElement) {\r\n this.history.resumeRecording();\r\n }\r\n this.setState({\r\n draggingElement: null,\r\n editingElement: null,\r\n });\r\n if (this.state.elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n }\r\n this.focusContainer();\r\n }),\r\n element,\r\n excalidrawContainer: this.excalidrawContainerRef.current,\r\n });\r\n // deselect all other elements when inserting text\r\n this.deselectElements();\r\n // do an initial update to re-initialize element position since we were\r\n // modifying element's x/y for sake of editor (case: syncing to remote)\r\n updateElement(element.text, element.originalText);\r\n }\r\n deselectElements() {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n getTextElementAtPosition(x, y) {\r\n const element = this.getElementAtPosition(x, y, {\r\n includeBoundTextElement: true,\r\n });\r\n if (element && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && !element.isDeleted) {\r\n return element;\r\n }\r\n return null;\r\n }\r\n getElementAtPosition(x, y, opts) {\r\n const allHitElements = this.getElementsAtPosition(x, y, opts === null || opts === void 0 ? void 0 : opts.includeBoundTextElement);\r\n if (allHitElements.length > 1) {\r\n if (opts === null || opts === void 0 ? void 0 : opts.preferSelected) {\r\n for (let index = allHitElements.length - 1; index > -1; index--) {\r\n if (this.state.selectedElementIds[allHitElements[index].id]) {\r\n return allHitElements[index];\r\n }\r\n }\r\n }\r\n const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];\r\n // If we're hitting element with highest z-index only on its bounding box\r\n // while also hitting other element figure, the latter should be considered.\r\n return (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(elementWithHighestZIndex, this.state, x, y)\r\n ? allHitElements[allHitElements.length - 2]\r\n : elementWithHighestZIndex;\r\n }\r\n if (allHitElements.length === 1) {\r\n return allHitElements[0];\r\n }\r\n return null;\r\n }\r\n getElementsAtPosition(x, y, includeBoundTextElement = false) {\r\n const elements = includeBoundTextElement\r\n ? this.scene.getElements()\r\n : this.scene\r\n .getElements()\r\n .filter((element) => !((0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element) && element.containerId));\r\n return (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsAtPosition)(elements, (element) => (0,_element__WEBPACK_IMPORTED_MODULE_16__.hitTest)(element, this.state, x, y));\r\n }\r\n maybeCleanupAfterMissingPointerUp(event) {\r\n if (lastPointerUp !== null) {\r\n // Unfortunately, sometimes we don't get a pointerup after a pointerdown,\r\n // this can happen when a contextual menu or alert is triggered. In order to avoid\r\n // being in a weird state, we clean up on the next pointerdown\r\n lastPointerUp(event);\r\n }\r\n }\r\n updateGestureOnPointerDown(event) {\r\n gesture.pointers.set(event.pointerId, {\r\n x: event.clientX,\r\n y: event.clientY,\r\n });\r\n if (gesture.pointers.size === 2) {\r\n gesture.lastCenter = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getCenter)(gesture.pointers);\r\n gesture.initialScale = this.state.zoom.value;\r\n gesture.initialDistance = (0,_gesture__WEBPACK_IMPORTED_MODULE_22__.getDistance)(Array.from(gesture.pointers.values()));\r\n }\r\n }\r\n initialPointerDownState(event) {\r\n const origin = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n const [minX, minY, maxX, maxY] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return {\r\n origin,\r\n withCmdOrCtrl: event[_keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.CTRL_OR_CMD],\r\n originInGrid: (0,_utils__WEBPACK_IMPORTED_MODULE_34__.tupleToCoors)((0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(origin.x, origin.y, this.state.gridSize)),\r\n scrollbars: (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isOverScrollBars)(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),\r\n // we need to duplicate because we'll be updating this state\r\n lastCoords: Object.assign({}, origin),\r\n originalElements: this.scene.getElements().reduce((acc, element) => {\r\n acc.set(element.id, (0,_element_newElement__WEBPACK_IMPORTED_MODULE_20__.deepCopyElement)(element));\r\n return acc;\r\n }, new Map()),\r\n resize: {\r\n handleType: false,\r\n isResizing: false,\r\n offset: { x: 0, y: 0 },\r\n arrowDirection: \"origin\",\r\n center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },\r\n },\r\n hit: {\r\n element: null,\r\n allHitElements: [],\r\n wasAddedToSelection: false,\r\n hasBeenDuplicated: false,\r\n hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements(origin, selectedElements),\r\n hasHitElementInside: false,\r\n },\r\n drag: {\r\n hasOccurred: false,\r\n offset: null,\r\n },\r\n eventListeners: {\r\n onMove: null,\r\n onUp: null,\r\n onKeyUp: null,\r\n onKeyDown: null,\r\n },\r\n boxSelection: {\r\n hasOccurred: false,\r\n },\r\n };\r\n }\r\n // Returns whether the event is a dragging a scrollbar\r\n handleDraggingScrollBar(event, pointerDownState) {\r\n if (!(pointerDownState.scrollbars.isOverEither && !this.state.multiElement)) {\r\n return false;\r\n }\r\n isDraggingScrollBar = true;\r\n pointerDownState.lastCoords.x = event.clientX;\r\n pointerDownState.lastCoords.y = event.clientY;\r\n const onPointerMove = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n this.handlePointerMoveOverScrollbars(event, pointerDownState);\r\n });\r\n const onPointerUp = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)(() => {\r\n isDraggingScrollBar = false;\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.setCursorForShape)(this.canvas, this.state.elementType);\r\n lastPointerUp = null;\r\n this.setState({\r\n cursorButton: \"up\",\r\n });\r\n this.savePointer(event.clientX, event.clientY, \"up\");\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n });\r\n lastPointerUp = onPointerUp;\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, onPointerMove);\r\n window.addEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, onPointerUp);\r\n return true;\r\n }\r\n isASelectedElement(hitElement) {\r\n return hitElement != null && this.state.selectedElementIds[hitElement.id];\r\n }\r\n isHittingCommonBoundingBoxOfSelectedElements(point, selectedElements) {\r\n if (selectedElements.length < 2) {\r\n return false;\r\n }\r\n // How many pixels off the shape boundary we still consider a hit\r\n const threshold = 10 / this.state.zoom.value;\r\n const [x1, y1, x2, y2] = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getCommonBounds)(selectedElements);\r\n return (point.x > x1 - threshold &&\r\n point.x < x2 + threshold &&\r\n point.y > y1 - threshold &&\r\n point.y < y2 + threshold);\r\n }\r\n onKeyDownFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onKeyUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n // Prevents focus from escaping excalidraw tab\r\n event.key === _keys__WEBPACK_IMPORTED_MODULE_26__.KEYS.ALT && event.preventDefault();\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return;\r\n }\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n });\r\n }\r\n onPointerMoveFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((event) => {\r\n var _a, _b;\r\n // We need to initialize dragOffsetXY only after we've updated\r\n // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove\r\n // event handler should hopefully ensure we're already working with\r\n // the updated state.\r\n if (pointerDownState.drag.offset === null) {\r\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.getElements(), this.state), pointerDownState.origin.x, pointerDownState.origin.y));\r\n }\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) {\r\n return;\r\n }\r\n if (this.handlePointerMoveOverScrollbars(event, pointerDownState)) {\r\n return;\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(event, this.state);\r\n const [gridX, gridY] = (0,_math__WEBPACK_IMPORTED_MODULE_27__.getGridPoint)(pointerCoords.x, pointerCoords.y, this.state.gridSize);\r\n // for arrows/lines, don't start dragging until a given threshold\r\n // to ensure we don't create a 2-point arrow by mistake when\r\n // user clicks mouse in a way that it moves a tiny bit (thus\r\n // triggering pointermove)\r\n if (!pointerDownState.drag.hasOccurred &&\r\n (this.state.elementType === \"arrow\" ||\r\n this.state.elementType === \"line\")) {\r\n if ((0,_math__WEBPACK_IMPORTED_MODULE_27__.distance2d)(pointerCoords.x, pointerCoords.y, pointerDownState.origin.x, pointerDownState.origin.y) < _constants__WEBPACK_IMPORTED_MODULE_11__.DRAGGING_THRESHOLD) {\r\n return;\r\n }\r\n }\r\n if (pointerDownState.resize.isResizing) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n if (this.maybeHandleResize(pointerDownState, event)) {\r\n return true;\r\n }\r\n }\r\n if (this.state.editingLinearElement) {\r\n const didDrag = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointDragging(this.state, (appState) => this.setState(appState), pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {\r\n this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);\r\n });\r\n if (didDrag) {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n return;\r\n }\r\n }\r\n const hasHitASelectedElement = pointerDownState.hit.allHitElements.some((element) => this.isASelectedElement(element));\r\n if ((hasHitASelectedElement ||\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&\r\n // this allows for box-selecting points when clicking inside the\r\n // line's bounding box\r\n (!this.state.editingLinearElement || !event.shiftKey) &&\r\n // box-selecting without shift when editing line, not clicking on a line\r\n (!this.state.editingLinearElement ||\r\n ((_a = this.state.editingLinearElement) === null || _a === void 0 ? void 0 : _a.elementId) !==\r\n ((_b = pointerDownState.hit.element) === null || _b === void 0 ? void 0 : _b.id) ||\r\n pointerDownState.hit.hasHitElementInside)) {\r\n // Marking that click was used for dragging to check\r\n // if elements should be deselected on pointerup\r\n pointerDownState.drag.hasOccurred = true;\r\n const selectedElements = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state);\r\n // prevent dragging even if we're no longer holding cmd/ctrl otherwise\r\n // it would have weird results (stuff jumping all over the screen)\r\n if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) {\r\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);\r\n const [dragDistanceX, dragDistanceY] = [\r\n Math.abs(pointerCoords.x - pointerDownState.origin.x),\r\n Math.abs(pointerCoords.y - pointerDownState.origin.y),\r\n ];\r\n // We only drag in one direction if shift is pressed\r\n const lockDirection = event.shiftKey;\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.dragSelectedElements)(pointerDownState, selectedElements, dragX, dragY, lockDirection, dragDistanceX, dragDistanceY);\r\n this.maybeSuggestBindingForAll(selectedElements);\r\n // We duplicate the selected element if alt is pressed on pointer move\r\n if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {\r\n // Move the currently selected elements to the top of the z index stack, and\r\n // put the duplicates where the selected elements used to be.\r\n // (the origin point where the dragging started)\r\n pointerDownState.hit.hasBeenDuplicated = true;\r\n const nextElements = [];\r\n const elementsToAppend = [];\r\n const groupIdMap = new Map();\r\n const oldIdToDuplicatedId = new Map();\r\n const hitElement = pointerDownState.hit.element;\r\n const elements = this.scene.getElementsIncludingDeleted();\r\n const selectedElementIds = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(elements, this.state, true).map((element) => element.id);\r\n for (const element of elements) {\r\n if (selectedElementIds.includes(element.id) ||\r\n // case: the state.selectedElementIds might not have been\r\n // updated yet by the time this mousemove event is fired\r\n (element.id === (hitElement === null || hitElement === void 0 ? void 0 : hitElement.id) &&\r\n pointerDownState.hit.wasAddedToSelection)) {\r\n const duplicatedElement = (0,_element__WEBPACK_IMPORTED_MODULE_16__.duplicateElement)(this.state.editingGroupId, groupIdMap, element);\r\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);\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(duplicatedElement, {\r\n x: duplicatedElement.x + (originDragX - dragX),\r\n y: duplicatedElement.y + (originDragY - dragY),\r\n });\r\n nextElements.push(duplicatedElement);\r\n elementsToAppend.push(element);\r\n oldIdToDuplicatedId.set(element.id, duplicatedElement.id);\r\n }\r\n else {\r\n nextElements.push(element);\r\n }\r\n }\r\n const nextSceneElements = [...nextElements, ...elementsToAppend];\r\n (0,_element_textElement__WEBPACK_IMPORTED_MODULE_44__.bindTextToShapeAfterDuplication)(nextElements, elementsToAppend, oldIdToDuplicatedId);\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.fixBindingsAfterDuplication)(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, \"duplicatesServeAsOld\");\r\n this.scene.replaceAllElements(nextSceneElements);\r\n }\r\n return;\r\n }\r\n }\r\n // It is very important to read this.state within each move event,\r\n // otherwise we would read a stale one!\r\n const draggingElement = this.state.draggingElement;\r\n if (!draggingElement) {\r\n return;\r\n }\r\n if (draggingElement.type === \"freedraw\") {\r\n const points = draggingElement.points;\r\n const dx = pointerCoords.x - draggingElement.x;\r\n const dy = pointerCoords.y - draggingElement.y;\r\n const pressures = draggingElement.simulatePressure\r\n ? draggingElement.pressures\r\n : [...draggingElement.pressures, event.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n });\r\n }\r\n else if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n pointerDownState.drag.hasOccurred = true;\r\n const points = draggingElement.points;\r\n let dx = gridX - draggingElement.x;\r\n let dy = gridY - draggingElement.y;\r\n if ((0,_keys__WEBPACK_IMPORTED_MODULE_26__.shouldRotateWithDiscreteAngle)(event) && points.length === 2) {\r\n ({ width: dx, height: dy } = (0,_element__WEBPACK_IMPORTED_MODULE_16__.getPerfectElementSize)(this.state.elementType, dx, dy));\r\n }\r\n if (points.length === 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, { points: [...points, [dx, dy]] });\r\n }\r\n else if (points.length > 1) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points.slice(0, -1), [dx, dy]],\r\n });\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n // When creating a linear element by dragging\r\n this.maybeSuggestBindingsForLinearElementAtCoords(draggingElement, [pointerCoords], this.state.startBoundElement);\r\n }\r\n }\r\n else {\r\n pointerDownState.lastCoords.x = pointerCoords.x;\r\n pointerDownState.lastCoords.y = pointerCoords.y;\r\n this.maybeDragNewGenericElement(pointerDownState, event);\r\n }\r\n if (this.state.elementType === \"selection\") {\r\n pointerDownState.boxSelection.hasOccurred = true;\r\n const elements = this.scene.getElements();\r\n if (!event.shiftKey &&\r\n // allows for box-selecting points (without shift)\r\n !this.state.editingLinearElement &&\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(elements, this.state)) {\r\n if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: {\r\n [pointerDownState.hit.element.id]: true,\r\n } }), this.scene.getElements()));\r\n }\r\n else {\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n }\r\n }\r\n // box-select line editor points\r\n if (this.state.editingLinearElement) {\r\n _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handleBoxSelection(event, this.state, this.setState.bind(this));\r\n // regular box-select\r\n }\r\n else {\r\n const elementsWithinSelection = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementsWithinSelection)(elements, draggingElement);\r\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((map, element) => {\r\n map[element.id] = true;\r\n return map;\r\n }, {})), (pointerDownState.hit.element\r\n ? {\r\n // if using ctrl/cmd, select the hitElement only if we\r\n // haven't box-selected anything else\r\n [pointerDownState.hit.element.id]: !elementsWithinSelection.length,\r\n }\r\n : null)) }), this.scene.getElements()));\r\n }\r\n }\r\n });\r\n }\r\n // Returns whether the pointer move happened over either scrollbar\r\n handlePointerMoveOverScrollbars(event, pointerDownState) {\r\n if (pointerDownState.scrollbars.isOverHorizontal) {\r\n const x = event.clientX;\r\n const dx = x - pointerDownState.lastCoords.x;\r\n this.setState({\r\n scrollX: this.state.scrollX - dx / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.x = x;\r\n return true;\r\n }\r\n if (pointerDownState.scrollbars.isOverVertical) {\r\n const y = event.clientY;\r\n const dy = y - pointerDownState.lastCoords.y;\r\n this.setState({\r\n scrollY: this.state.scrollY - dy / this.state.zoom.value,\r\n });\r\n pointerDownState.lastCoords.y = y;\r\n return true;\r\n }\r\n return false;\r\n }\r\n onPointerUpFromPointerDownHandler(pointerDownState) {\r\n return (0,_utils__WEBPACK_IMPORTED_MODULE_34__.withBatchedUpdates)((childEvent) => {\r\n var _a, _b;\r\n const { draggingElement, resizingElement, multiElement, elementType, elementLocked, isResizing, isRotating, } = this.state;\r\n this.setState({\r\n isResizing: false,\r\n isRotating: false,\r\n resizingElement: null,\r\n selectionElement: null,\r\n cursorButton: \"up\",\r\n // text elements are reset on finalize, and resetting on pointerup\r\n // may cause issues with double taps\r\n editingElement: multiElement || (0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(this.state.editingElement)\r\n ? this.state.editingElement\r\n : null,\r\n });\r\n this.savePointer(childEvent.clientX, childEvent.clientY, \"up\");\r\n // Handle end of dragging a point of a linear element, might close a loop\r\n // and sets binding element\r\n if (this.state.editingLinearElement) {\r\n if (!pointerDownState.boxSelection.hasOccurred &&\r\n (((_b = (_a = pointerDownState.hit) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.id) !==\r\n this.state.editingLinearElement.elementId ||\r\n !pointerDownState.hit.hasHitElementInside)) {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n else {\r\n const editingLinearElement = _element_linearElementEditor__WEBPACK_IMPORTED_MODULE_18__.LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state);\r\n if (editingLinearElement !== this.state.editingLinearElement) {\r\n this.setState({\r\n editingLinearElement,\r\n suggestedBindings: [],\r\n });\r\n }\r\n }\r\n }\r\n lastPointerUp = null;\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_MOVE, pointerDownState.eventListeners.onMove);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.POINTER_UP, pointerDownState.eventListeners.onUp);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYDOWN, pointerDownState.eventListeners.onKeyDown);\r\n window.removeEventListener(_constants__WEBPACK_IMPORTED_MODULE_11__.EVENT.KEYUP, pointerDownState.eventListeners.onKeyUp);\r\n if (this.state.pendingImageElement) {\r\n this.setState({ pendingImageElement: null });\r\n }\r\n if ((draggingElement === null || draggingElement === void 0 ? void 0 : draggingElement.type) === \"freedraw\") {\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n const points = draggingElement.points;\r\n let dx = pointerCoords.x - draggingElement.x;\r\n let dy = pointerCoords.y - draggingElement.y;\r\n // Allows dots to avoid being flagged as infinitely small\r\n if (dx === points[0][0] && dy === points[0][1]) {\r\n dy += 0.0001;\r\n dx += 0.0001;\r\n }\r\n const pressures = draggingElement.simulatePressure\r\n ? []\r\n : [...draggingElement.pressures, childEvent.pressure];\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [...points, [dx, dy]],\r\n pressures,\r\n lastCommittedPoint: [dx, dy],\r\n });\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isImageElement)(draggingElement)) {\r\n const imageElement = draggingElement;\r\n try {\r\n this.initializeImageDimensions(imageElement);\r\n this.setState({ selectedElementIds: { [imageElement.id]: true } }, () => {\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n });\r\n }\r\n catch (error) {\r\n console.error(error);\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== imageElement.id));\r\n this.actionManager.executeAction(_actions__WEBPACK_IMPORTED_MODULE_4__.actionFinalize);\r\n }\r\n return;\r\n }\r\n if ((0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isLinearElement)(draggingElement)) {\r\n if (draggingElement.points.length > 1) {\r\n this.history.resumeRecording();\r\n }\r\n const pointerCoords = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.viewportCoordsToSceneCoords)(childEvent, this.state);\r\n if (!pointerDownState.drag.hasOccurred &&\r\n draggingElement &&\r\n !multiElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, {\r\n points: [\r\n ...draggingElement.points,\r\n [\r\n pointerCoords.x - draggingElement.x,\r\n pointerCoords.y - draggingElement.y,\r\n ],\r\n ],\r\n });\r\n this.setState({\r\n multiElement: draggingElement,\r\n editingElement: this.state.draggingElement,\r\n });\r\n }\r\n else if (pointerDownState.drag.hasOccurred && !multiElement) {\r\n if ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state) &&\r\n (0,_element_typeChecks__WEBPACK_IMPORTED_MODULE_21__.isBindingElement)(draggingElement)) {\r\n (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.maybeBindLinearElement)(draggingElement, this.state, this.scene, pointerCoords);\r\n }\r\n this.setState({ suggestedBindings: [], startBoundElement: null });\r\n if (!elementLocked) {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n elementType: \"selection\",\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n else {\r\n this.setState((prevState) => ({\r\n draggingElement: null,\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [this.state.draggingElement.id]: true }),\r\n }));\r\n }\r\n }\r\n return;\r\n }\r\n if (elementType !== \"selection\" &&\r\n draggingElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(draggingElement)) {\r\n // remove invisible element which was added in onPointerDown\r\n this.scene.replaceAllElements(this.scene.getElementsIncludingDeleted().slice(0, -1));\r\n this.setState({\r\n draggingElement: null,\r\n });\r\n return;\r\n }\r\n if (draggingElement) {\r\n (0,_element_mutateElement__WEBPACK_IMPORTED_MODULE_19__.mutateElement)(draggingElement, (0,_element__WEBPACK_IMPORTED_MODULE_16__.getNormalizedDimensions)(draggingElement));\r\n }\r\n if (resizingElement) {\r\n this.history.resumeRecording();\r\n }\r\n if (resizingElement && (0,_element__WEBPACK_IMPORTED_MODULE_16__.isInvisiblySmallElement)(resizingElement)) {\r\n this.scene.replaceAllElements(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((el) => el.id !== resizingElement.id));\r\n }\r\n // Code below handles selection when element(s) weren't\r\n // drag or added to selection on pointer down phase.\r\n const hitElement = pointerDownState.hit.element;\r\n if (hitElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !pointerDownState.hit.wasAddedToSelection &&\r\n // if we're editing a line, pointerup shouldn't switch selection if\r\n // box selected\r\n (!this.state.editingLinearElement ||\r\n !pointerDownState.boxSelection.hasOccurred)) {\r\n // when inside line editor, shift selects points instead\r\n if (childEvent.shiftKey && !this.state.editingLinearElement) {\r\n if (this.state.selectedElementIds[hitElement.id]) {\r\n if ((0,_groups__WEBPACK_IMPORTED_MODULE_23__.isSelectedViaGroup)(this.state, hitElement)) {\r\n // We want to unselect all groups hitElement is part of\r\n // as well as all elements that are part of the groups\r\n // hitElement is part of\r\n const idsOfSelectedElementsThatAreInGroups = hitElement.groupIds\r\n .flatMap((groupId) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.getElementsInGroup)(this.scene.getElements(), groupId))\r\n .map((element) => ({ [element.id]: false }))\r\n .reduce((prevId, acc) => (Object.assign(Object.assign({}, prevId), acc)), {});\r\n this.setState((_prevState) => ({\r\n selectedGroupIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), hitElement.groupIds\r\n .map((gId) => ({ [gId]: false }))\r\n .reduce((prev, acc) => (Object.assign(Object.assign({}, prev), acc)), {})),\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), idsOfSelectedElementsThatAreInGroups),\r\n }));\r\n }\r\n else {\r\n // remove element from selection while\r\n // keeping prev elements selected\r\n this.setState((prevState) => (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [hitElement.id]: false }) }), this.scene.getElements()));\r\n }\r\n }\r\n else {\r\n // add element to selection while\r\n // keeping prev elements selected\r\n this.setState((_prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, _prevState.selectedElementIds), { [hitElement.id]: true }),\r\n }));\r\n }\r\n }\r\n else {\r\n this.setState((prevState) => (Object.assign({}, (0,_groups__WEBPACK_IMPORTED_MODULE_23__.selectGroupsForSelectedElements)(Object.assign(Object.assign({}, prevState), { selectedElementIds: { [hitElement.id]: true } }), this.scene.getElements()))));\r\n }\r\n }\r\n if (!this.state.editingLinearElement &&\r\n !pointerDownState.drag.hasOccurred &&\r\n !this.state.isResizing &&\r\n ((hitElement &&\r\n (0,_element__WEBPACK_IMPORTED_MODULE_16__.isHittingElementBoundingBoxWithoutHittingElement)(hitElement, this.state, pointerDownState.origin.x, pointerDownState.origin.y)) ||\r\n (!hitElement &&\r\n pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {\r\n // Deselect selected elements\r\n this.setState({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n editingGroupId: null,\r\n });\r\n return;\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\" && draggingElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: Object.assign(Object.assign({}, prevState.selectedElementIds), { [draggingElement.id]: true }),\r\n }));\r\n }\r\n if (elementType !== \"selection\" ||\r\n (0,_scene__WEBPACK_IMPORTED_MODULE_30__.isSomeElementSelected)(this.scene.getElements(), this.state)) {\r\n this.history.resumeRecording();\r\n }\r\n if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {\r\n ((0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.isBindingEnabled)(this.state)\r\n ? _element_binding__WEBPACK_IMPORTED_MODULE_17__.bindOrUnbindSelectedElements\r\n : _element_binding__WEBPACK_IMPORTED_MODULE_17__.unbindLinearElements)((0,_scene__WEBPACK_IMPORTED_MODULE_30__.getSelectedElements)(this.scene.getElements(), this.state));\r\n }\r\n if (!elementLocked && elementType !== \"freedraw\") {\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_34__.resetCursor)(this.canvas);\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n elementType: \"selection\",\r\n });\r\n }\r\n else {\r\n this.setState({\r\n draggingElement: null,\r\n suggestedBindings: [],\r\n });\r\n }\r\n });\r\n }\r\n maybeSuggestBindingForAll(selectedElements) {\r\n const suggestedBindings = (0,_element_binding__WEBPACK_IMPORTED_MODULE_17__.getEligibleElementsForBinding)(selectedElements);\r\n this.setState({ suggestedBindings });\r\n }\r\n clearSelection(hitElement) {\r\n this.setState((prevState) => ({\r\n selectedElementIds: {},\r\n selectedGroupIds: {},\r\n // Continue editing the same group if the user selected a different\r\n // element from it\r\n editingGroupId: prevState.editingGroupId &&\r\n hitElement != null &&\r\n (0,_groups__WEBPACK_IMPORTED_MODULE_23__.isElementInGroup)(hitElement, prevState.editingGroupId)\r\n ? prevState.editingGroupId\r\n : null,\r\n }));\r\n this.setState({\r\n selectedElementIds: {},\r\n previousSelectedElementIds: this.state.selectedElementIds,\r\n });\r\n }\r\n getTextWysiwygSnappedToCenterPosition(x, y, appState, canvas, scale) {\r\n const elementClickedInside = (0,_scene__WEBPACK_IMPORTED_MODULE_30__.getElementContainingPosition)(this.scene\r\n .getElementsIncludingDeleted()\r\n .filter((element) => !(0,_element__WEBPACK_IMPORTED_MODULE_16__.isTextElement)(element)), x, y);\r\n if (elementClickedInside) {\r\n const elementCenterX = elementClickedInside.x + elementClickedInside.width / 2;\r\n const elementCenterY = elementClickedInside.y + elementClickedInside.height / 2;\r\n const distanceToCenter = Math.hypot(x - elementCenterX, y - elementCenterY);\r\n const isSnappedToCenter = distanceToCenter < _constants__WEBPACK_IMPORTED_MODULE_11__.TEXT_TO_CENTER_SNAP_THRESHOLD;\r\n if (isSnappedToCenter) {\r\n const { x: viewportX, y: viewportY } = (0,_utils__WEBPACK_IMPORTED_MODULE_34__.sceneCoordsToViewportCoords)({ sceneX: elementCenterX, sceneY: elementCenterY }, appState);\r\n return { viewportX, viewportY, elementCenterX, elementCenterY };\r\n }\r\n }\r\n }\r\n getCanvasOffsets() {\r\n var _a;\r\n if ((_a = this.excalidrawContainerRef) === null || _a === void 0 ? void 0 : _a.current) {\r\n const excalidrawContainer = this.excalidrawContainerRef.current;\r\n const { left, top } = excalidrawContainer.getBoundingClientRect();\r\n return {\r\n offsetLeft: left,\r\n offsetTop: top,\r\n };\r\n }\r\n return {\r\n offsetLeft: 0,\r\n offsetTop: 0,\r\n };\r\n }\r\n updateLanguage() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n const currentLang = _i18n__WEBPACK_IMPORTED_MODULE_25__.languages.find((lang) => lang.code === this.props.langCode) ||\r\n _i18n__WEBPACK_IMPORTED_MODULE_25__.defaultLang;\r\n yield (0,_i18n__WEBPACK_IMPORTED_MODULE_25__.setLanguage)(currentLang);\r\n this.setAppState({});\r\n });\r\n }\r\n}\r\nApp.defaultProps = {\r\n // needed for tests to pass since we directly render App in many tests\r\n UIOptions: _constants__WEBPACK_IMPORTED_MODULE_11__.DEFAULT_UI_OPTIONS,\r\n};\r\nif (\"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.TEST ||\r\n \"development\" === _constants__WEBPACK_IMPORTED_MODULE_11__.ENV.DEVELOPMENT) {\r\n window.h = window.h || {};\r\n Object.defineProperties(window.h, {\r\n elements: {\r\n configurable: true,\r\n get() {\r\n return this.app.scene.getElementsIncludingDeleted();\r\n },\r\n set(elements) {\r\n return this.app.scene.replaceAllElements(elements);\r\n },\r\n },\r\n });\r\n}\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QyxRQUFRLENBQUMsQ0FBQztZQUNyRCxDQUFDO1NBQ0Y7S0FDRixDQUFDLENBQUM7Q0FDSjtBQUNELGlFQUFlLEdBQUcsRUFBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi9jb21wb25lbnRzL0FwcC50c3g/MDA3MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgUm91Z2hDYW52YXMgfSBmcm9tIFwicm91Z2hqcy9iaW4vY2FudmFzXCI7XG5pbXBvcnQgcm91Z2ggZnJvbSBcInJvdWdoanMvYmluL3JvdWdoXCI7XG5pbXBvcnQgY2xzeCBmcm9tIFwiY2xzeFwiO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSBcIm5hbm9pZFwiO1xuXG5pbXBvcnQge1xuICBhY3Rpb25BZGRUb0xpYnJhcnksXG4gIGFjdGlvbkJyaW5nRm9yd2FyZCxcbiAgYWN0aW9uQnJpbmdUb0Zyb250LFxuICBhY3Rpb25Db3B5LFxuICBhY3Rpb25Db3B5QXNQbmcsXG4gIGFjdGlvbkNvcHlBc1N2ZyxcbiAgYWN0aW9uQ29weVN0eWxlcyxcbiAgYWN0aW9uQ3V0LFxuICBhY3Rpb25EZWxldGVTZWxlY3RlZCxcbiAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICBhY3Rpb25GaW5hbGl6ZSxcbiAgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gIGFjdGlvbkZsaXBWZXJ0aWNhbCxcbiAgYWN0aW9uR3JvdXAsXG4gIGFjdGlvblBhc3RlU3R5bGVzLFxuICBhY3Rpb25TZWxlY3RBbGwsXG4gIGFjdGlvblNlbmRCYWNrd2FyZCxcbiAgYWN0aW9uU2VuZFRvQmFjayxcbiAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gIGFjdGlvblRvZ2dsZVN0YXRzLFxuICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICBhY3Rpb25Vbmdyb3VwLFxufSBmcm9tIFwiLi4vYWN0aW9uc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVkb0FjdGlvbiwgY3JlYXRlVW5kb0FjdGlvbiB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvbkhpc3RvcnlcIjtcbmltcG9ydCB7IEFjdGlvbk1hbmFnZXIgfSBmcm9tIFwiLi4vYWN0aW9ucy9tYW5hZ2VyXCI7XG5pbXBvcnQgeyBhY3Rpb25zIH0gZnJvbSBcIi4uL2FjdGlvbnMvcmVnaXN0ZXJcIjtcbmltcG9ydCB7IEFjdGlvblJlc3VsdCB9IGZyb20gXCIuLi9hY3Rpb25zL3R5cGVzXCI7XG5pbXBvcnQgeyB0cmFja0V2ZW50IH0gZnJvbSBcIi4uL2FuYWx5dGljc1wiO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEFwcFN0YXRlIH0gZnJvbSBcIi4uL2FwcFN0YXRlXCI7XG5pbXBvcnQge1xuICBjb3B5VG9DbGlwYm9hcmQsXG4gIHBhcnNlQ2xpcGJvYXJkLFxuICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYixcbiAgcHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCxcbn0gZnJvbSBcIi4uL2NsaXBib2FyZFwiO1xuaW1wb3J0IHtcbiAgQVBQX05BTUUsXG4gIENVUlNPUl9UWVBFLFxuICBERUZBVUxUX01BWF9JTUFHRV9XSURUSF9PUl9IRUlHSFQsXG4gIERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgREVGQVVMVF9WRVJUSUNBTF9BTElHTixcbiAgRFJBR0dJTkdfVEhSRVNIT0xELFxuICBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlQsXG4gIEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVCxcbiAgRU5WLFxuICBFVkVOVCxcbiAgR1JJRF9TSVpFLFxuICBJTUFHRV9SRU5ERVJfVElNRU9VVCxcbiAgTElORV9DT05GSVJNX1RIUkVTSE9MRCxcbiAgTUFYX0FMTE9XRURfRklMRV9CWVRFUyxcbiAgTUlNRV9UWVBFUyxcbiAgTVFfTUFYX0hFSUdIVF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9MQU5EU0NBUEUsXG4gIE1RX01BWF9XSURUSF9QT1JUUkFJVCxcbiAgUE9JTlRFUl9CVVRUT04sXG4gIFNDUk9MTF9USU1FT1VULFxuICBUQVBfVFdJQ0VfVElNRU9VVCxcbiAgVEVYVF9UT19DRU5URVJfU05BUF9USFJFU0hPTEQsXG4gIFRIRU1FLFxuICBUT1VDSF9DVFhfTUVOVV9USU1FT1VULFxuICBVUkxfSEFTSF9LRVlTLFxuICBVUkxfUVVFUllfS0VZUyxcbiAgWk9PTV9TVEVQLFxufSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBsb2FkRnJvbUJsb2IgfSBmcm9tIFwiLi4vZGF0YVwiO1xuaW1wb3J0IHsgaXNWYWxpZExpYnJhcnkgfSBmcm9tIFwiLi4vZGF0YS9qc29uXCI7XG5pbXBvcnQgTGlicmFyeSBmcm9tIFwiLi4vZGF0YS9saWJyYXJ5XCI7XG5pbXBvcnQgeyByZXN0b3JlLCByZXN0b3JlRWxlbWVudHMsIHJlc3RvcmVMaWJyYXJ5SXRlbXMgfSBmcm9tIFwiLi4vZGF0YS9yZXN0b3JlXCI7XG5pbXBvcnQge1xuICBkcmFnTmV3RWxlbWVudCxcbiAgZHJhZ1NlbGVjdGVkRWxlbWVudHMsXG4gIGR1cGxpY2F0ZUVsZW1lbnQsXG4gIGdldENvbW1vbkJvdW5kcyxcbiAgZ2V0Q3Vyc29yRm9yUmVzaXppbmdFbGVtZW50LFxuICBnZXREcmFnT2Zmc2V0WFksXG4gIGdldEVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgZ2V0Tm9ybWFsaXplZERpbWVuc2lvbnMsXG4gIGdldFBlcmZlY3RFbGVtZW50U2l6ZSxcbiAgZ2V0UmVzaXplQXJyb3dEaXJlY3Rpb24sXG4gIGdldFJlc2l6ZU9mZnNldFhZLFxuICBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyxcbiAgaGl0VGVzdCxcbiAgaXNIaXR0aW5nRWxlbWVudEJvdW5kaW5nQm94V2l0aG91dEhpdHRpbmdFbGVtZW50LFxuICBpc0ludmlzaWJseVNtYWxsRWxlbWVudCxcbiAgaXNOb25EZWxldGVkRWxlbWVudCxcbiAgaXNUZXh0RWxlbWVudCxcbiAgbmV3RWxlbWVudCxcbiAgbmV3TGluZWFyRWxlbWVudCxcbiAgbmV3VGV4dEVsZW1lbnQsXG4gIG5ld0ltYWdlRWxlbWVudCxcbiAgdGV4dFd5c2l3eWcsXG4gIHRyYW5zZm9ybUVsZW1lbnRzLFxuICB1cGRhdGVUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4uL2VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMsXG4gIGZpeEJpbmRpbmdzQWZ0ZXJEZWxldGlvbixcbiAgZml4QmluZGluZ3NBZnRlckR1cGxpY2F0aW9uLFxuICBnZXRFbGlnaWJsZUVsZW1lbnRzRm9yQmluZGluZyxcbiAgZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nLFxuICBpc0JpbmRpbmdFbmFibGVkLFxuICBpc0xpbmVhckVsZW1lbnRTaW1wbGVBbmRBbHJlYWR5Qm91bmQsXG4gIG1heWJlQmluZExpbmVhckVsZW1lbnQsXG4gIHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQsXG4gIHVuYmluZExpbmVhckVsZW1lbnRzLFxuICB1cGRhdGVCb3VuZEVsZW1lbnRzLFxufSBmcm9tIFwiLi4vZWxlbWVudC9iaW5kaW5nXCI7XG5pbXBvcnQgeyBMaW5lYXJFbGVtZW50RWRpdG9yIH0gZnJvbSBcIi4uL2VsZW1lbnQvbGluZWFyRWxlbWVudEVkaXRvclwiO1xuaW1wb3J0IHtcbiAgYnVtcFZlcnNpb24sXG4gIG11dGF0ZUVsZW1lbnQsXG4gIG5ld0VsZW1lbnRXaXRoLFxufSBmcm9tIFwiLi4vZWxlbWVudC9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQgeyBkZWVwQ29weUVsZW1lbnQsIG5ld0ZyZWVEcmF3RWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50L25ld0VsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGhhc0JvdW5kVGV4dEVsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnQsXG4gIGlzQmluZGluZ0VsZW1lbnRUeXBlLFxuICBpc0ltYWdlRWxlbWVudCxcbiAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudCxcbiAgaXNMaW5lYXJFbGVtZW50LFxuICBpc0xpbmVhckVsZW1lbnRUeXBlLFxufSBmcm9tIFwiLi4vZWxlbWVudC90eXBlQ2hlY2tzXCI7XG5pbXBvcnQge1xuICBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50LFxuICBFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0ZyZWVEcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd0dlbmVyaWNFbGVtZW50LFxuICBFeGNhbGlkcmF3TGluZWFyRWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICBOb25EZWxldGVkLFxuICBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQsXG4gIEZpbGVJZCxcbn0gZnJvbSBcIi4uL2VsZW1lbnQvdHlwZXNcIjtcbmltcG9ydCB7IGdldENlbnRlciwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi4vZ2VzdHVyZVwiO1xuaW1wb3J0IHtcbiAgZWRpdEdyb3VwRm9yU2VsZWN0ZWRFbGVtZW50LFxuICBnZXRFbGVtZW50c0luR3JvdXAsXG4gIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQsXG4gIGdldFNlbGVjdGVkR3JvdXBJZHMsXG4gIGlzRWxlbWVudEluR3JvdXAsXG4gIGlzU2VsZWN0ZWRWaWFHcm91cCxcbiAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyxcbn0gZnJvbSBcIi4uL2dyb3Vwc1wiO1xuaW1wb3J0IEhpc3RvcnkgZnJvbSBcIi4uL2hpc3RvcnlcIjtcbmltcG9ydCB7IGRlZmF1bHRMYW5nLCBnZXRMYW5ndWFnZSwgbGFuZ3VhZ2VzLCBzZXRMYW5ndWFnZSwgdCB9IGZyb20gXCIuLi9pMThuXCI7XG5pbXBvcnQge1xuICBDT0RFUyxcbiAgc2hvdWxkUmVzaXplRnJvbUNlbnRlcixcbiAgc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyxcbiAgc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUsXG4gIGlzQXJyb3dLZXksXG4gIEtFWVMsXG59IGZyb20gXCIuLi9rZXlzXCI7XG5pbXBvcnQgeyBkaXN0YW5jZTJkLCBnZXRHcmlkUG9pbnQsIGlzUGF0aEFMb29wIH0gZnJvbSBcIi4uL21hdGhcIjtcbmltcG9ydCB7IHJlbmRlclNjZW5lIH0gZnJvbSBcIi4uL3JlbmRlcmVyXCI7XG5pbXBvcnQgeyBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50IH0gZnJvbSBcIi4uL3JlbmRlcmVyL3JlbmRlckVsZW1lbnRcIjtcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZVNjcm9sbENlbnRlcixcbiAgZ2V0RWxlbWVudENvbnRhaW5pbmdQb3NpdGlvbixcbiAgZ2V0RWxlbWVudHNBdFBvc2l0aW9uLFxuICBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbixcbiAgZ2V0Tm9ybWFsaXplZFpvb20sXG4gIGdldFNlbGVjdGVkRWxlbWVudHMsXG4gIGhhc0JhY2tncm91bmQsXG4gIGlzT3ZlclNjcm9sbEJhcnMsXG4gIGlzU29tZUVsZW1lbnRTZWxlY3RlZCxcbn0gZnJvbSBcIi4uL3NjZW5lXCI7XG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQgeyBSZW5kZXJDb25maWcsIFNjcm9sbEJhcnMgfSBmcm9tIFwiLi4vc2NlbmUvdHlwZXNcIjtcbmltcG9ydCB7IGdldE5ld1pvb20gfSBmcm9tIFwiLi4vc2NlbmUvem9vbVwiO1xuaW1wb3J0IHsgZmluZFNoYXBlQnlLZXkgfSBmcm9tIFwiLi4vc2hhcGVzXCI7XG5pbXBvcnQge1xuICBBcHBDbGFzc1Byb3BlcnRpZXMsXG4gIEFwcFByb3BzLFxuICBBcHBTdGF0ZSxcbiAgQmluYXJ5RmlsZURhdGEsXG4gIERhdGFVUkwsXG4gIEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJLFxuICBCaW5hcnlGaWxlcyxcbiAgR2VzdHVyZSxcbiAgR2VzdHVyZUV2ZW50LFxuICBMaWJyYXJ5SXRlbXMsXG4gIFBvaW50ZXJEb3duU3RhdGUsXG4gIFNjZW5lRGF0YSxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQge1xuICBkZWJvdW5jZSxcbiAgZGlzdGFuY2UsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyLFxuICBpc0lucHV0TGlrZSxcbiAgaXNUb29sSWNvbixcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIHJlc2V0Q3Vyc29yLFxuICByZXNvbHZhYmxlUHJvbWlzZSxcbiAgc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzLFxuICBzZXRDdXJzb3IsXG4gIHNldEN1cnNvckZvclNoYXBlLFxuICB0dXBsZVRvQ29vcnMsXG4gIHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyxcbiAgd2l0aEJhdGNoZWRVcGRhdGVzLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCBDb250ZXh0TWVudSwgeyBDb250ZXh0TWVudU9wdGlvbiB9IGZyb20gXCIuL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgTGF5ZXJVSSBmcm9tIFwiLi9MYXllclVJXCI7XG5pbXBvcnQgeyBTdGF0cyB9IGZyb20gXCIuL1N0YXRzXCI7XG5pbXBvcnQgeyBUb2FzdCB9IGZyb20gXCIuL1RvYXN0XCI7XG5pbXBvcnQgeyBhY3Rpb25Ub2dnbGVWaWV3TW9kZSB9IGZyb20gXCIuLi9hY3Rpb25zL2FjdGlvblRvZ2dsZVZpZXdNb2RlXCI7XG5pbXBvcnQge1xuICBkYXRhVVJMVG9GaWxlLFxuICBnZW5lcmF0ZUlkRnJvbUZpbGUsXG4gIGdldERhdGFVUkwsXG4gIGlzU3VwcG9ydGVkSW1hZ2VGaWxlLFxuICByZXNpemVJbWFnZUZpbGUsXG4gIFNWR1N0cmluZ1RvRmlsZSxcbn0gZnJvbSBcIi4uL2RhdGEvYmxvYlwiO1xuaW1wb3J0IHtcbiAgZ2V0SW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnRzLFxuICBsb2FkSFRNTEltYWdlRWxlbWVudCxcbiAgbm9ybWFsaXplU1ZHLFxuICB1cGRhdGVJbWFnZUNhY2hlIGFzIF91cGRhdGVJbWFnZUNhY2hlLFxufSBmcm9tIFwiLi4vZWxlbWVudC9pbWFnZVwiO1xuaW1wb3J0IHRocm90dGxlIGZyb20gXCJsb2Rhc2gudGhyb3R0bGVcIjtcbmltcG9ydCB7IGZpbGVPcGVuLCBuYXRpdmVGaWxlU3lzdGVtU3VwcG9ydGVkIH0gZnJvbSBcIi4uL2RhdGEvZmlsZXN5c3RlbVwiO1xuaW1wb3J0IHtcbiAgYmluZFRleHRUb1NoYXBlQWZ0ZXJEdXBsaWNhdGlvbixcbiAgZ2V0QXBwcm94TWluTGluZUhlaWdodCxcbiAgZ2V0QXBwcm94TWluTGluZVdpZHRoLFxuICBnZXRCb3VuZFRleHRFbGVtZW50SWQsXG59IGZyb20gXCIuLi9lbGVtZW50L3RleHRFbGVtZW50XCI7XG5pbXBvcnQgeyBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveCB9IGZyb20gXCIuLi9lbGVtZW50L2NvbGxpc2lvblwiO1xuXG5jb25zdCBJc01vYmlsZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0KGZhbHNlKTtcbmV4cG9ydCBjb25zdCB1c2VJc01vYmlsZSA9ICgpID0+IHVzZUNvbnRleHQoSXNNb2JpbGVDb250ZXh0KTtcbmNvbnN0IEV4Y2FsaWRyYXdDb250YWluZXJDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDx7XG4gIGNvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgfCBudWxsO1xuICBpZDogc3RyaW5nIHwgbnVsbDtcbn0+KHsgY29udGFpbmVyOiBudWxsLCBpZDogbnVsbCB9KTtcbmV4cG9ydCBjb25zdCB1c2VFeGNhbGlkcmF3Q29udGFpbmVyID0gKCkgPT5cbiAgdXNlQ29udGV4dChFeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dCk7XG5cbmxldCBkaWRUYXBUd2ljZTogYm9vbGVhbiA9IGZhbHNlO1xubGV0IHRhcHBlZFR3aWNlVGltZXIgPSAwO1xubGV0IGN1cnNvclggPSAwO1xubGV0IGN1cnNvclkgPSAwO1xubGV0IGlzSG9sZGluZ1NwYWNlOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNQYW5uaW5nOiBib29sZWFuID0gZmFsc2U7XG5sZXQgaXNEcmFnZ2luZ1Njcm9sbEJhcjogYm9vbGVhbiA9IGZhbHNlO1xubGV0IGN1cnJlbnRTY3JvbGxCYXJzOiBTY3JvbGxCYXJzID0geyBob3Jpem9udGFsOiBudWxsLCB2ZXJ0aWNhbDogbnVsbCB9O1xubGV0IHRvdWNoVGltZW91dCA9IDA7XG5sZXQgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbmxldCBsYXN0UG9pbnRlclVwOiAoKGV2ZW50OiBhbnkpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5jb25zdCBnZXN0dXJlOiBHZXN0dXJlID0ge1xuICBwb2ludGVyczogbmV3IE1hcCgpLFxuICBsYXN0Q2VudGVyOiBudWxsLFxuICBpbml0aWFsRGlzdGFuY2U6IG51bGwsXG4gIGluaXRpYWxTY2FsZTogbnVsbCxcbn07XG5cbmNsYXNzIEFwcCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxBcHBQcm9wcywgQXBwU3RhdGU+IHtcbiAgY2FudmFzOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJjYW52YXNcIl0gPSBudWxsO1xuICByYzogUm91Z2hDYW52YXMgfCBudWxsID0gbnVsbDtcbiAgdW5tb3VudGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGlvbk1hbmFnZXI6IEFjdGlvbk1hbmFnZXI7XG4gIGlzTW9iaWxlID0gZmFsc2U7XG4gIGRldGFjaElzTW9iaWxlTXFIYW5kbGVyPzogKCkgPT4gdm9pZDtcblxuICBwcml2YXRlIGV4Y2FsaWRyYXdDb250YWluZXJSZWYgPSBSZWFjdC5jcmVhdGVSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHM6IFBhcnRpYWw8QXBwUHJvcHM+ID0ge1xuICAgIC8vIG5lZWRlZCBmb3IgdGVzdHMgdG8gcGFzcyBzaW5jZSB3ZSBkaXJlY3RseSByZW5kZXIgQXBwIGluIG1hbnkgdGVzdHNcbiAgICBVSU9wdGlvbnM6IERFRkFVTFRfVUlfT1BUSU9OUyxcbiAgfTtcblxuICBwcml2YXRlIHNjZW5lOiBTY2VuZTtcbiAgcHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbmVhcmVzdFNjcm9sbGFibGVDb250YWluZXI6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyBsaWJyYXJ5OiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJsaWJyYXJ5XCJdO1xuICBwdWJsaWMgbGlicmFyeUl0ZW1zRnJvbVN0b3JhZ2U6IExpYnJhcnlJdGVtcyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICBwcml2YXRlIGhpc3Rvcnk6IEhpc3Rvcnk7XG4gIHByaXZhdGUgZXhjYWxpZHJhd0NvbnRhaW5lclZhbHVlOiB7XG4gICAgY29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG4gICAgaWQ6IHN0cmluZztcbiAgfTtcblxuICBwdWJsaWMgZmlsZXM6IEJpbmFyeUZpbGVzID0ge307XG4gIHB1YmxpYyBpbWFnZUNhY2hlOiBBcHBDbGFzc1Byb3BlcnRpZXNbXCJpbWFnZUNhY2hlXCJdID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBBcHBQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICBjb25zdCBkZWZhdWx0QXBwU3RhdGUgPSBnZXREZWZhdWx0QXBwU3RhdGUoKTtcbiAgICBjb25zdCB7XG4gICAgICBleGNhbGlkcmF3UmVmLFxuICAgICAgdmlld01vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCA9IGZhbHNlLFxuICAgICAgZ3JpZE1vZGVFbmFibGVkID0gZmFsc2UsXG4gICAgICB0aGVtZSA9IGRlZmF1bHRBcHBTdGF0ZS50aGVtZSxcbiAgICAgIG5hbWUgPSBkZWZhdWx0QXBwU3RhdGUubmFtZSxcbiAgICB9ID0gcHJvcHM7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLmRlZmF1bHRBcHBTdGF0ZSxcbiAgICAgIHRoZW1lLFxuICAgICAgaXNMb2FkaW5nOiB0cnVlLFxuICAgICAgLi4udGhpcy5nZXRDYW52YXNPZmZzZXRzKCksXG4gICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICB6ZW5Nb2RlRW5hYmxlZCxcbiAgICAgIGdyaWRTaXplOiBncmlkTW9kZUVuYWJsZWQgPyBHUklEX1NJWkUgOiBudWxsLFxuICAgICAgbmFtZSxcbiAgICAgIHdpZHRoOiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0LFxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gbmFub2lkKCk7XG5cbiAgICBpZiAoZXhjYWxpZHJhd1JlZikge1xuICAgICAgY29uc3QgcmVhZHlQcm9taXNlID1cbiAgICAgICAgKFwiY3VycmVudFwiIGluIGV4Y2FsaWRyYXdSZWYgJiYgZXhjYWxpZHJhd1JlZi5jdXJyZW50Py5yZWFkeVByb21pc2UpIHx8XG4gICAgICAgIHJlc29sdmFibGVQcm9taXNlPEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJPigpO1xuXG4gICAgICBjb25zdCBhcGk6IEV4Y2FsaWRyYXdJbXBlcmF0aXZlQVBJID0ge1xuICAgICAgICByZWFkeTogdHJ1ZSxcbiAgICAgICAgcmVhZHlQcm9taXNlLFxuICAgICAgICB1cGRhdGVTY2VuZTogdGhpcy51cGRhdGVTY2VuZSxcbiAgICAgICAgYWRkRmlsZXM6IHRoaXMuYWRkRmlsZXMsXG4gICAgICAgIHJlc2V0U2NlbmU6IHRoaXMucmVzZXRTY2VuZSxcbiAgICAgICAgZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQ6IHRoaXMuZ2V0U2NlbmVFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQsXG4gICAgICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgICBjbGVhcjogdGhpcy5yZXNldEhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICAgIHNjcm9sbFRvQ29udGVudDogdGhpcy5zY3JvbGxUb0NvbnRlbnQsXG4gICAgICAgIGdldFNjZW5lRWxlbWVudHM6IHRoaXMuZ2V0U2NlbmVFbGVtZW50cyxcbiAgICAgICAgZ2V0QXBwU3RhdGU6ICgpID0+IHRoaXMuc3RhdGUsXG4gICAgICAgIGdldEZpbGVzOiAoKSA9PiB0aGlzLmZpbGVzLFxuICAgICAgICByZWZyZXNoOiB0aGlzLnJlZnJlc2gsXG4gICAgICAgIGltcG9ydExpYnJhcnk6IHRoaXMuaW1wb3J0TGlicmFyeUZyb21VcmwsXG4gICAgICAgIHNldFRvYXN0TWVzc2FnZTogdGhpcy5zZXRUb2FzdE1lc3NhZ2UsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICAgIGlmICh0eXBlb2YgZXhjYWxpZHJhd1JlZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYoYXBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4Y2FsaWRyYXdSZWYuY3VycmVudCA9IGFwaTtcbiAgICAgIH1cbiAgICAgIHJlYWR5UHJvbWlzZS5yZXNvbHZlKGFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWUgPSB7XG4gICAgICBjb250YWluZXI6IHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50LFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgfTtcblxuICAgIHRoaXMuc2NlbmUgPSBuZXcgU2NlbmUoKTtcbiAgICB0aGlzLmxpYnJhcnkgPSBuZXcgTGlicmFyeSh0aGlzKTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSgpO1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlciA9IG5ldyBBY3Rpb25NYW5hZ2VyKFxuICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0LFxuICAgICAgKCkgPT4gdGhpcy5zdGF0ZSxcbiAgICAgICgpID0+IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLFxuICAgICk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWxsKGFjdGlvbnMpO1xuXG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVVuZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLnJlZ2lzdGVyQWN0aW9uKGNyZWF0ZVJlZG9BY3Rpb24odGhpcy5oaXN0b3J5KSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNTY2FsZSA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoOiBjYW52YXNET01XaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzRE9NSGVpZ2h0LFxuICAgICAgdmlld01vZGVFbmFibGVkLFxuICAgIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY2FudmFzRE9NV2lkdGggKiBjYW52YXNTY2FsZTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXNET01IZWlnaHQgKiBjYW52YXNTY2FsZTtcbiAgICBpZiAodmlld01vZGVFbmFibGVkKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Y2FudmFzXG4gICAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgd2lkdGg6IGNhbnZhc0RPTVdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgICAgICBjdXJzb3I6IENVUlNPUl9UWVBFLkdSQUIsXG4gICAgICAgICAgfX1cbiAgICAgICAgICB3aWR0aD17Y2FudmFzV2lkdGh9XG4gICAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgICAgcmVmPXt0aGlzLmhhbmRsZUNhbnZhc1JlZn1cbiAgICAgICAgICBvbkNvbnRleHRNZW51PXt0aGlzLmhhbmRsZUNhbnZhc0NvbnRleHRNZW51fVxuICAgICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyVXA9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblBvaW50ZXJDYW5jZWw9e3RoaXMucmVtb3ZlUG9pbnRlcn1cbiAgICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICAgICAgb25Qb2ludGVyRG93bj17dGhpcy5oYW5kbGVDYW52YXNQb2ludGVyRG93bn1cbiAgICAgICAgPlxuICAgICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICAgIDwvY2FudmFzPlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxjYW52YXNcbiAgICAgICAgY2xhc3NOYW1lPVwiZXhjYWxpZHJhd19fY2FudmFzXCJcbiAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICB3aWR0aDogY2FudmFzRE9NV2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBjYW52YXNET01IZWlnaHQsXG4gICAgICAgIH19XG4gICAgICAgIHdpZHRoPXtjYW52YXNXaWR0aH1cbiAgICAgICAgaGVpZ2h0PXtjYW52YXNIZWlnaHR9XG4gICAgICAgIHJlZj17dGhpcy5oYW5kbGVDYW52YXNSZWZ9XG4gICAgICAgIG9uQ29udGV4dE1lbnU9e3RoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnV9XG4gICAgICAgIG9uUG9pbnRlckRvd249e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlckRvd259XG4gICAgICAgIG9uRG91YmxlQ2xpY2s9e3RoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2t9XG4gICAgICAgIG9uUG9pbnRlck1vdmU9e3RoaXMuaGFuZGxlQ2FudmFzUG9pbnRlck1vdmV9XG4gICAgICAgIG9uUG9pbnRlclVwPXt0aGlzLnJlbW92ZVBvaW50ZXJ9XG4gICAgICAgIG9uUG9pbnRlckNhbmNlbD17dGhpcy5yZW1vdmVQb2ludGVyfVxuICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmV9XG4gICAgICA+XG4gICAgICAgIHt0KFwibGFiZWxzLmRyYXdpbmdDYW52YXNcIil9XG4gICAgICA8L2NhbnZhcz5cbiAgICApO1xuICB9XG5cbiAgcHVibGljIHJlbmRlcigpIHtcbiAgICBjb25zdCB7IHplbk1vZGVFbmFibGVkLCB2aWV3TW9kZUVuYWJsZWQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICBjb25zdCB7XG4gICAgICBvbkNvbGxhYkJ1dHRvbkNsaWNrLFxuICAgICAgcmVuZGVyVG9wUmlnaHRVSSxcbiAgICAgIHJlbmRlckZvb3RlcixcbiAgICAgIHJlbmRlckN1c3RvbVN0YXRzLFxuICAgIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3NOYW1lPXtjbHN4KFwiZXhjYWxpZHJhdyBleGNhbGlkcmF3LWNvbnRhaW5lclwiLCB7XG4gICAgICAgICAgXCJleGNhbGlkcmF3LS12aWV3LW1vZGVcIjogdmlld01vZGVFbmFibGVkLFxuICAgICAgICAgIFwiZXhjYWxpZHJhdy0tbW9iaWxlXCI6IHRoaXMuaXNNb2JpbGUsXG4gICAgICAgIH0pfVxuICAgICAgICByZWY9e3RoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZn1cbiAgICAgICAgb25Ecm9wPXt0aGlzLmhhbmRsZUFwcE9uRHJvcH1cbiAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgIG9uS2V5RG93bj17XG4gICAgICAgICAgdGhpcy5wcm9wcy5oYW5kbGVLZXlib2FyZEdsb2JhbGx5ID8gdW5kZWZpbmVkIDogdGhpcy5vbktleURvd25cbiAgICAgICAgfVxuICAgICAgPlxuICAgICAgICA8RXhjYWxpZHJhd0NvbnRhaW5lckNvbnRleHQuUHJvdmlkZXJcbiAgICAgICAgICB2YWx1ZT17dGhpcy5leGNhbGlkcmF3Q29udGFpbmVyVmFsdWV9XG4gICAgICAgID5cbiAgICAgICAgICA8SXNNb2JpbGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0aGlzLmlzTW9iaWxlfT5cbiAgICAgICAgICAgIDxMYXllclVJXG4gICAgICAgICAgICAgIGNhbnZhcz17dGhpcy5jYW52YXN9XG4gICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICBmaWxlcz17dGhpcy5maWxlc31cbiAgICAgICAgICAgICAgc2V0QXBwU3RhdGU9e3RoaXMuc2V0QXBwU3RhdGV9XG4gICAgICAgICAgICAgIGFjdGlvbk1hbmFnZXI9e3RoaXMuYWN0aW9uTWFuYWdlcn1cbiAgICAgICAgICAgICAgZWxlbWVudHM9e3RoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKX1cbiAgICAgICAgICAgICAgb25Db2xsYWJCdXR0b25DbGljaz17b25Db2xsYWJCdXR0b25DbGlja31cbiAgICAgICAgICAgICAgb25Mb2NrVG9nZ2xlPXt0aGlzLnRvZ2dsZUxvY2t9XG4gICAgICAgICAgICAgIG9uSW5zZXJ0RWxlbWVudHM9eyhlbGVtZW50cykgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiY2VudGVyXCIsXG4gICAgICAgICAgICAgICAgICBmaWxlczogbnVsbCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkPXt6ZW5Nb2RlRW5hYmxlZH1cbiAgICAgICAgICAgICAgdG9nZ2xlWmVuTW9kZT17dGhpcy50b2dnbGVaZW5Nb2RlfVxuICAgICAgICAgICAgICBsYW5nQ29kZT17Z2V0TGFuZ3VhZ2UoKS5jb2RlfVxuICAgICAgICAgICAgICBpc0NvbGxhYm9yYXRpbmc9e3RoaXMucHJvcHMuaXNDb2xsYWJvcmF0aW5nIHx8IGZhbHNlfVxuICAgICAgICAgICAgICByZW5kZXJUb3BSaWdodFVJPXtyZW5kZXJUb3BSaWdodFVJfVxuICAgICAgICAgICAgICByZW5kZXJDdXN0b21Gb290ZXI9e3JlbmRlckZvb3Rlcn1cbiAgICAgICAgICAgICAgdmlld01vZGVFbmFibGVkPXt2aWV3TW9kZUVuYWJsZWR9XG4gICAgICAgICAgICAgIHNob3dFeGl0WmVuTW9kZUJ0bj17XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHM/Lnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgemVuTW9kZUVuYWJsZWRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzaG93VGhlbWVCdG49e1xuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzPy50aGVtZSA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuVUlPcHRpb25zLmNhbnZhc0FjdGlvbnMudGhlbWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsaWJyYXJ5UmV0dXJuVXJsPXt0aGlzLnByb3BzLmxpYnJhcnlSZXR1cm5Vcmx9XG4gICAgICAgICAgICAgIFVJT3B0aW9ucz17dGhpcy5wcm9wcy5VSU9wdGlvbnN9XG4gICAgICAgICAgICAgIGZvY3VzQ29udGFpbmVyPXt0aGlzLmZvY3VzQ29udGFpbmVyfVxuICAgICAgICAgICAgICBsaWJyYXJ5PXt0aGlzLmxpYnJhcnl9XG4gICAgICAgICAgICAgIGlkPXt0aGlzLmlkfVxuICAgICAgICAgICAgICBvbkltYWdlQWN0aW9uPXt0aGlzLm9uSW1hZ2VBY3Rpb259XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LXRleHRFZGl0b3JDb250YWluZXJcIiAvPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJleGNhbGlkcmF3LWNvbnRleHRNZW51Q29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLnNob3dTdGF0cyAmJiAoXG4gICAgICAgICAgICAgIDxTdGF0c1xuICAgICAgICAgICAgICAgIGFwcFN0YXRlPXt0aGlzLnN0YXRlfVxuICAgICAgICAgICAgICAgIHNldEFwcFN0YXRlPXt0aGlzLnNldEFwcFN0YXRlfVxuICAgICAgICAgICAgICAgIGVsZW1lbnRzPXt0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCl9XG4gICAgICAgICAgICAgICAgb25DbG9zZT17dGhpcy50b2dnbGVTdGF0c31cbiAgICAgICAgICAgICAgICByZW5kZXJDdXN0b21TdGF0cz17cmVuZGVyQ3VzdG9tU3RhdHN9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3RoaXMuc3RhdGUudG9hc3RNZXNzYWdlICE9PSBudWxsICYmIChcbiAgICAgICAgICAgICAgPFRvYXN0XG4gICAgICAgICAgICAgICAgbWVzc2FnZT17dGhpcy5zdGF0ZS50b2FzdE1lc3NhZ2V9XG4gICAgICAgICAgICAgICAgY2xlYXJUb2FzdD17dGhpcy5jbGVhclRvYXN0fVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxtYWluPnt0aGlzLnJlbmRlckNhbnZhcygpfTwvbWFpbj5cbiAgICAgICAgICA8L0lzTW9iaWxlQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgPC9FeGNhbGlkcmF3Q29udGFpbmVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZm9jdXNDb250YWluZXI6IEFwcENsYXNzUHJvcGVydGllc1tcImZvY3VzQ29udGFpbmVyXCJdID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBnZXRTY2VuZUVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgfTtcblxuICBwdWJsaWMgZ2V0U2NlbmVFbGVtZW50cyA9ICgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuICB9O1xuXG4gIHByaXZhdGUgc3luY0FjdGlvblJlc3VsdCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoYWN0aW9uUmVzdWx0OiBBY3Rpb25SZXN1bHQpID0+IHtcbiAgICAgIGlmICh0aGlzLnVubW91bnRlZCB8fCBhY3Rpb25SZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGVkaXRpbmdFbGVtZW50OiBBcHBTdGF0ZVtcImVkaXRpbmdFbGVtZW50XCJdIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmVsZW1lbnRzKSB7XG4gICAgICAgIGFjdGlvblJlc3VsdC5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudD8uaWQgPT09IGVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgIT09IGVsZW1lbnQgJiZcbiAgICAgICAgICAgIGlzTm9uRGVsZXRlZEVsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGVkaXRpbmdFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhhY3Rpb25SZXN1bHQuZWxlbWVudHMpO1xuICAgICAgICBpZiAoYWN0aW9uUmVzdWx0LmNvbW1pdFRvSGlzdG9yeSkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aW9uUmVzdWx0LmZpbGVzKSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSBhY3Rpb25SZXN1bHQucmVwbGFjZUZpbGVzXG4gICAgICAgICAgPyBhY3Rpb25SZXN1bHQuZmlsZXNcbiAgICAgICAgICA6IHsgLi4udGhpcy5maWxlcywgLi4uYWN0aW9uUmVzdWx0LmZpbGVzIH07XG4gICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwgZWRpdGluZ0VsZW1lbnQpIHtcbiAgICAgICAgaWYgKGFjdGlvblJlc3VsdC5jb21taXRUb0hpc3RvcnkpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmlld01vZGVFbmFibGVkID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udmlld01vZGVFbmFibGVkIHx8IGZhbHNlO1xuICAgICAgICBsZXQgemVuTW9kZUVuYWJsZWQgPSBhY3Rpb25SZXN1bHQ/LmFwcFN0YXRlPy56ZW5Nb2RlRW5hYmxlZCB8fCBmYWxzZTtcbiAgICAgICAgbGV0IGdyaWRTaXplID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8uZ3JpZFNpemUgfHwgbnVsbDtcbiAgICAgICAgbGV0IHRoZW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8udGhlbWUgfHwgVEhFTUUuTElHSFQ7XG4gICAgICAgIGxldCBuYW1lID0gYWN0aW9uUmVzdWx0Py5hcHBTdGF0ZT8ubmFtZSA/PyB0aGlzLnN0YXRlLm5hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQgPSB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHplbk1vZGVFbmFibGVkID0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBncmlkU2l6ZSA9IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy50aGVtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIHRoZW1lID0gdGhpcy5wcm9wcy50aGVtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcm9wcy5uYW1lICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgbmFtZSA9IHRoaXMucHJvcHMubmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKFxuICAgICAgICAgIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgLy8gdXNpbmcgT2JqZWN0LmFzc2lnbiBpbnN0ZWFkIG9mIHNwcmVhZCB0byBmb29sIFRTIDQuMi4yKyBpbnRvXG4gICAgICAgICAgICAvLyByZWdhcmRpbmcgdGhlIHJlc3VsdGluZyB0eXBlIGFzIG5vdCBjb250YWluaW5nIHVuZGVmaW5lZFxuICAgICAgICAgICAgLy8gKHdoaWNoIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiB3aWxsIG5ldmVyIGNvbnRhaW4pXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhY3Rpb25SZXN1bHQuYXBwU3RhdGUgfHwge30sIHtcbiAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6XG4gICAgICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQgfHwgYWN0aW9uUmVzdWx0LmFwcFN0YXRlPy5lZGl0aW5nRWxlbWVudCB8fCBudWxsLFxuICAgICAgICAgICAgICB2aWV3TW9kZUVuYWJsZWQsXG4gICAgICAgICAgICAgIHplbk1vZGVFbmFibGVkLFxuICAgICAgICAgICAgICBncmlkU2l6ZSxcbiAgICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb25SZXN1bHQuc3luY0hpc3RvcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5LnNldEN1cnJlbnRTdGF0ZShcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIC8vIExpZmVjeWNsZVxuXG4gIHByaXZhdGUgb25CbHVyID0gd2l0aEJhdGNoZWRVcGRhdGVzKCgpID0+IHtcbiAgICBpc0hvbGRpbmdTcGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBwcml2YXRlIG9uVW5sb2FkID0gKCkgPT4ge1xuICAgIHRoaXMub25CbHVyKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRXZlbnQ6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIHByaXZhdGUgb25Gb250TG9hZGVkID0gKCkgPT4ge1xuICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLm9uU2NlbmVVcGRhdGVkKCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpbXBvcnRMaWJyYXJ5RnJvbVVybCA9IGFzeW5jICh1cmw6IHN0cmluZywgdG9rZW4/OiBzdHJpbmcgfCBudWxsKSA9PiB7XG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoLmluY2x1ZGVzKFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSkpIHtcbiAgICAgIGNvbnN0IGhhc2ggPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpKTtcbiAgICAgIGhhc2guZGVsZXRlKFVSTF9IQVNIX0tFWVMuYWRkTGlicmFyeSk7XG4gICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIEFQUF9OQU1FLCBgIyR7aGFzaC50b1N0cmluZygpfWApO1xuICAgIH0gZWxzZSBpZiAod2luZG93LmxvY2F0aW9uLnNlYXJjaC5pbmNsdWRlcyhVUkxfUVVFUllfS0VZUy5hZGRMaWJyYXJ5KSkge1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpO1xuICAgICAgcXVlcnkuZGVsZXRlKFVSTF9RVUVSWV9LRVlTLmFkZExpYnJhcnkpO1xuICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCBBUFBfTkFNRSwgYD8ke3F1ZXJ5LnRvU3RyaW5nKCl9YCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBhd2FpdCBmZXRjaChkZWNvZGVVUklDb21wb25lbnQodXJsKSk7XG4gICAgICBjb25zdCBibG9iID0gYXdhaXQgcmVxdWVzdC5ibG9iKCk7XG4gICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCBibG9iLnRleHQoKSk7XG4gICAgICBpZiAoIWlzVmFsaWRMaWJyYXJ5KGpzb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICB0b2tlbiA9PT0gdGhpcy5pZCB8fFxuICAgICAgICB3aW5kb3cuY29uZmlybShcbiAgICAgICAgICB0KFwiYWxlcnRzLmNvbmZpcm1BZGRMaWJyYXJ5XCIsIHtcbiAgICAgICAgICAgIG51bVNoYXBlczogKGpzb24ubGlicmFyeUl0ZW1zIHx8IGpzb24ubGlicmFyeSB8fCBbXSkubGVuZ3RoLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5saWJyYXJ5LmltcG9ydExpYnJhcnkoYmxvYiwgXCJwdWJsaXNoZWRcIik7XG4gICAgICAgIC8vIGhhY2sgdG8gcmVyZW5kZXIgdGhlIGxpYnJhcnkgaXRlbXMgYWZ0ZXIgaW1wb3J0XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4pIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMaWJyYXJ5T3BlbjogZmFsc2UgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IHRydWUgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgd2luZG93LmFsZXJ0KHQoXCJhbGVydHMuZXJyb3JMb2FkaW5nTGlicmFyeVwiKSk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHJlc2V0SGlzdG9yeSA9ICgpID0+IHtcbiAgICB0aGlzLmhpc3RvcnkuY2xlYXIoKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXRzIHNjZW5lICYgaGlzdG9yeS5cbiAgICogISBEbyBub3QgdXNlIHRvIGNsZWFyIHNjZW5lIHVzZXIgYWN0aW9uICFcbiAgICovXG4gIHByaXZhdGUgcmVzZXRTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAob3B0cz86IHsgcmVzZXRMb2FkaW5nU3RhdGU6IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW10pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoc3RhdGUpID0+ICh7XG4gICAgICAgIC4uLmdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICAgICAgICBpc0xvYWRpbmc6IG9wdHM/LnJlc2V0TG9hZGluZ1N0YXRlID8gZmFsc2UgOiBzdGF0ZS5pc0xvYWRpbmcsXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVNjZW5lID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChcImxhdW5jaFF1ZXVlXCIgaW4gd2luZG93ICYmIFwiTGF1bmNoUGFyYW1zXCIgaW4gd2luZG93KSB7XG4gICAgICAod2luZG93IGFzIGFueSkubGF1bmNoUXVldWUuc2V0Q29uc3VtZXIoXG4gICAgICAgIGFzeW5jIChsYXVuY2hQYXJhbXM6IHsgZmlsZXM6IGFueVtdIH0pID0+IHtcbiAgICAgICAgICBpZiAoIWxhdW5jaFBhcmFtcy5maWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlsZUhhbmRsZSA9IGxhdW5jaFBhcmFtcy5maWxlc1swXTtcbiAgICAgICAgICBjb25zdCBibG9iOiBCbG9iID0gYXdhaXQgZmlsZUhhbmRsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgYmxvYi5oYW5kbGUgPSBmaWxlSGFuZGxlO1xuICAgICAgICAgIGxvYWRGcm9tQmxvYihcbiAgICAgICAgICAgIGJsb2IsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoc2NlbmUpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgICAgICAgLi4uKHNjZW5lLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaXNMb2FkaW5nOiBmYWxzZSwgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0xvYWRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgfVxuICAgIGxldCBpbml0aWFsRGF0YSA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGluaXRpYWxEYXRhID0gKGF3YWl0IHRoaXMucHJvcHMuaW5pdGlhbERhdGEpIHx8IG51bGw7XG4gICAgICBpZiAoaW5pdGlhbERhdGE/LmxpYnJhcnlJdGVtcykge1xuICAgICAgICB0aGlzLmxpYnJhcnlJdGVtc0Zyb21TdG9yYWdlID0gcmVzdG9yZUxpYnJhcnlJdGVtcyhcbiAgICAgICAgICBpbml0aWFsRGF0YS5saWJyYXJ5SXRlbXMsXG4gICAgICAgICAgXCJ1bnB1Ymxpc2hlZFwiLFxuICAgICAgICApIGFzIExpYnJhcnlJdGVtcztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIGluaXRpYWxEYXRhID0ge1xuICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgIGVycm9yTWVzc2FnZTpcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHxcbiAgICAgICAgICAgIFwiRW5jb3VudGVyZWQgYW4gZXJyb3IgZHVyaW5nIGltcG9ydGluZyBvciByZXN0b3Jpbmcgc2NlbmUgZGF0YVwiLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBzY2VuZSA9IHJlc3RvcmUoaW5pdGlhbERhdGEsIG51bGwsIG51bGwpO1xuXG4gICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAuLi5zY2VuZS5hcHBTdGF0ZSxcbiAgICAgIGVsZW1lbnRUeXBlOlxuICAgICAgICBzY2VuZS5hcHBTdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJpbWFnZVwiXG4gICAgICAgICAgPyBcInNlbGVjdGlvblwiXG4gICAgICAgICAgOiBzY2VuZS5hcHBTdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgfTtcbiAgICBpZiAoaW5pdGlhbERhdGE/LnNjcm9sbFRvQ29udGVudCkge1xuICAgICAgc2NlbmUuYXBwU3RhdGUgPSB7XG4gICAgICAgIC4uLnNjZW5lLmFwcFN0YXRlLFxuICAgICAgICAuLi5jYWxjdWxhdGVTY3JvbGxDZW50ZXIoXG4gICAgICAgICAgc2NlbmUuZWxlbWVudHMsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uc2NlbmUuYXBwU3RhdGUsXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5zdGF0ZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5zdGF0ZS5oZWlnaHQsXG4gICAgICAgICAgICBvZmZzZXRUb3A6IHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICAgICAgb2Zmc2V0TGVmdDogdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yZXNldEhpc3RvcnkoKTtcbiAgICB0aGlzLnN5bmNBY3Rpb25SZXN1bHQoe1xuICAgICAgLi4uc2NlbmUsXG4gICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBsaWJyYXJ5VXJsID1cbiAgICAgIC8vIGN1cnJlbnRcbiAgICAgIG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLmhhc2guc2xpY2UoMSkpLmdldChcbiAgICAgICAgVVJMX0hBU0hfS0VZUy5hZGRMaWJyYXJ5LFxuICAgICAgKSB8fFxuICAgICAgLy8gbGVnYWN5LCBrZXB0IGZvciBjb21wYXQgcmVhc29uc1xuICAgICAgbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKS5nZXQoXG4gICAgICAgIFVSTF9RVUVSWV9LRVlTLmFkZExpYnJhcnksXG4gICAgICApO1xuXG4gICAgaWYgKGxpYnJhcnlVcmwpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW1wb3J0TGlicmFyeUZyb21VcmwobGlicmFyeVVybCk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJWYWx1ZS5jb250YWluZXIgPVxuICAgICAgdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG5cbiAgICBpZiAoXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gRU5WLlRFU1QgfHxcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuREVWRUxPUE1FTlRcbiAgICApIHtcbiAgICAgIGNvbnN0IHNldFN0YXRlID0gdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LmgsIHtcbiAgICAgICAgc3RhdGU6IHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBzZXRTdGF0ZToge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB2YWx1ZTogKC4uLmFyZ3M6IFBhcmFtZXRlcnM8dHlwZW9mIHNldFN0YXRlPikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0U3RhdGUoLi4uYXJncyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYXBwOiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLFxuICAgICAgICB9LFxuICAgICAgICBoaXN0b3J5OiB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLmhpc3RvcnksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNjZW5lLmFkZENhbGxiYWNrKHRoaXMub25TY2VuZVVwZGF0ZWQpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcblxuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCkge1xuICAgICAgdGhpcy5mb2N1c0NvbnRhaW5lcigpO1xuICAgIH1cblxuICAgIGlmIChcIlJlc2l6ZU9ic2VydmVyXCIgaW4gd2luZG93ICYmIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZj8uY3VycmVudCkge1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICAgIC8vIGNvbXB1dGUgaXNNb2JpbGUgc3RhdGVcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID1cbiAgICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMuaXNNb2JpbGUgPVxuICAgICAgICAgIHdpZHRoIDwgTVFfTUFYX1dJRFRIX1BPUlRSQUlUIHx8XG4gICAgICAgICAgKGhlaWdodCA8IE1RX01BWF9IRUlHSFRfTEFORFNDQVBFICYmIHdpZHRoIDwgTVFfTUFYX1dJRFRIX0xBTkRTQ0FQRSk7XG4gICAgICAgIC8vIHJlZnJlc2ggb2Zmc2V0c1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy51cGRhdGVET01SZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/Lm9ic2VydmUodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQpO1xuICAgIH0gZWxzZSBpZiAod2luZG93Lm1hdGNoTWVkaWEpIHtcbiAgICAgIGNvbnN0IG1lZGlhUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYShcbiAgICAgICAgYChtYXgtd2lkdGg6ICR7TVFfTUFYX1dJRFRIX1BPUlRSQUlUfXB4KSwgKG1heC1oZWlnaHQ6ICR7TVFfTUFYX0hFSUdIVF9MQU5EU0NBUEV9cHgpIGFuZCAobWF4LXdpZHRoOiAke01RX01BWF9XSURUSF9MQU5EU0NBUEV9cHgpYCxcbiAgICAgICk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4gKHRoaXMuaXNNb2JpbGUgPSBtZWRpYVF1ZXJ5Lm1hdGNoZXMpO1xuICAgICAgbWVkaWFRdWVyeS5hZGRMaXN0ZW5lcihoYW5kbGVyKTtcbiAgICAgIHRoaXMuZGV0YWNoSXNNb2JpbGVNcUhhbmRsZXIgPSAoKSA9PiBtZWRpYVF1ZXJ5LnJlbW92ZUxpc3RlbmVyKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG5cbiAgICBpZiAoc2VhcmNoUGFyYW1zLmhhcyhcIndlYi1zaGFyZS10YXJnZXRcIikpIHtcbiAgICAgIC8vIE9idGFpbiBhIGZpbGUgdGhhdCB3YXMgc2hhcmVkIHZpYSB0aGUgV2ViIFNoYXJlIFRhcmdldCBBUEkuXG4gICAgICB0aGlzLnJlc3RvcmVGaWxlRnJvbVNoYXJlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRE9NUmVjdCh0aGlzLmluaXRpYWxpemVTY2VuZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIHRoaXMuZmlsZXMgPSB7fTtcbiAgICB0aGlzLmltYWdlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy51bm1vdW50ZWQgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNjZW5lLmRlc3Ryb3koKTtcbiAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICB0b3VjaFRpbWVvdXQgPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblJlc2l6ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgdGhpcy5zY2VuZVxuICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH0pO1xuXG4gIHByaXZhdGUgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCB0aGlzLnJlbW92ZVBvaW50ZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQ09QWSwgdGhpcy5vbkNvcHkpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHRoaXMucGFzdGVGcm9tQ2xpcGJvYXJkKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkNVVCwgdGhpcy5vbkN1dCk7XG4gICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lcj8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULlNDUk9MTCxcbiAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIHRoaXMub25LZXlEb3duLCBmYWxzZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULk1PVVNFX01PVkUsXG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDdXJzb3JQb3NpdGlvbixcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgdGhpcy5vbktleVVwKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULkRSQUdfT1ZFUiwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5EUk9QLCB0aGlzLmRpc2FibGVFdmVudCwgZmFsc2UpO1xuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfU1RBUlQsXG4gICAgICB0aGlzLm9uR2VzdHVyZVN0YXJ0IGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfQ0hBTkdFLFxuICAgICAgdGhpcy5vbkdlc3R1cmVDaGFuZ2UgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuR0VTVFVSRV9FTkQsXG4gICAgICB0aGlzLm9uR2VzdHVyZUVuZCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgdGhpcy5kZXRhY2hJc01vYmlsZU1xSGFuZGxlcj8uKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRoaXMucmVtb3ZlUG9pbnRlcik7IC8vICMzNTUzXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DT1BZLCB0aGlzLm9uQ29weSk7XG4gICAgaWYgKHRoaXMucHJvcHMuaGFuZGxlS2V5Ym9hcmRHbG9iYWxseSkge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlET1dOLCB0aGlzLm9uS2V5RG93biwgZmFsc2UpO1xuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWVVQLCB0aGlzLm9uS2V5VXAsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgRVZFTlQuTU9VU0VfTU9WRSxcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudEN1cnNvclBvc2l0aW9uLFxuICAgICk7XG4gICAgLy8gcmVyZW5kZXIgdGV4dCBlbGVtZW50cyBvbiBmb250IGxvYWQgdG8gZml4ICM2MzcgJiYgIzE1NTNcbiAgICBkb2N1bWVudC5mb250cz8uYWRkRXZlbnRMaXN0ZW5lcj8uKFwibG9hZGluZ2RvbmVcIiwgdGhpcy5vbkZvbnRMb2FkZWQpO1xuICAgIC8vIFNhZmFyaS1vbmx5IGRlc2t0b3AgcGluY2ggem9vbVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX1NUQVJULFxuICAgICAgdGhpcy5vbkdlc3R1cmVTdGFydCBhcyBhbnksXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBFVkVOVC5HRVNUVVJFX0NIQU5HRSxcbiAgICAgIHRoaXMub25HZXN0dXJlQ2hhbmdlIGFzIGFueSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgIEVWRU5ULkdFU1RVUkVfRU5ELFxuICAgICAgdGhpcy5vbkdlc3R1cmVFbmQgYXMgYW55LFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5DVVQsIHRoaXMub25DdXQpO1xuICAgIGlmICh0aGlzLnByb3BzLmRldGVjdFNjcm9sbCkge1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lciA9IGdldE5lYXJlc3RTY3JvbGxhYmxlQ29udGFpbmVyKFxuICAgICAgICB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICApO1xuICAgICAgdGhpcy5uZWFyZXN0U2Nyb2xsYWJsZUNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICBFVkVOVC5TQ1JPTEwsXG4gICAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgICApO1xuICAgIH1cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5SRVNJWkUsIHRoaXMub25SZXNpemUsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5VTkxPQUQsIHRoaXMub25VbmxvYWQsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0aGlzLm9uQmx1ciwgZmFsc2UpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULkRSQUdfT1ZFUiwgdGhpcy5kaXNhYmxlRXZlbnQsIGZhbHNlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5EUk9QLCB0aGlzLmRpc2FibGVFdmVudCwgZmFsc2UpO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogQXBwUHJvcHMsIHByZXZTdGF0ZTogQXBwU3RhdGUpIHtcbiAgICBpZiAocHJldlByb3BzLmxhbmdDb2RlICE9PSB0aGlzLnByb3BzLmxhbmdDb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxhbmd1YWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy52aWV3TW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlld01vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMudmlld01vZGVFbmFibGVkIH0pO1xuICAgIH1cblxuICAgIGlmIChwcmV2U3RhdGUudmlld01vZGVFbmFibGVkICE9PSB0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgdGhpcy5kZXNlbGVjdEVsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy56ZW5Nb2RlRW5hYmxlZCAhPT0gdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHplbk1vZGVFbmFibGVkOiAhIXRoaXMucHJvcHMuemVuTW9kZUVuYWJsZWQgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy50aGVtZSAhPT0gdGhpcy5wcm9wcy50aGVtZSAmJiB0aGlzLnByb3BzLnRoZW1lKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdGhlbWU6IHRoaXMucHJvcHMudGhlbWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZQcm9wcy5ncmlkTW9kZUVuYWJsZWQgIT09IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZ3JpZFNpemU6IHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID8gR1JJRF9TSVpFIDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLm5hbWUgJiYgcHJldlByb3BzLm5hbWUgIT09IHRoaXMucHJvcHMubmFtZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG5hbWU6IHRoaXMucHJvcHMubmFtZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jbGFzc0xpc3QudG9nZ2xlKFxuICAgICAgXCJ0aGVtZS0tZGFya1wiLFxuICAgICAgdGhpcy5zdGF0ZS50aGVtZSA9PT0gXCJkYXJrXCIsXG4gICAgKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1t0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZF1cbiAgICApIHtcbiAgICAgIC8vIGRlZmVyIHNvIHRoYXQgdGhlIGNvbW1pdFRvSGlzdG9yeSBmbGFnIGlzbid0IHJlc2V0IHZpYSBjdXJyZW50IHVwZGF0ZVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gcHJldlN0YXRlO1xuICAgIGlmIChcbiAgICAgIHByZXZTdGF0ZS5lbGVtZW50VHlwZSAhPT0gdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSAmJlxuICAgICAgbXVsdGlFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgIGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSkgJiZcbiAgICAgIGlzQmluZGluZ0VsZW1lbnQobXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgbWF5YmVCaW5kTGluZWFyRWxlbWVudChcbiAgICAgICAgbXVsdGlFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICB0dXBsZVRvQ29vcnMoXG4gICAgICAgICAgTGluZWFyRWxlbWVudEVkaXRvci5nZXRQb2ludEF0SW5kZXhHbG9iYWxDb29yZGluYXRlcyhcbiAgICAgICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgICAgIC0xLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnNvckJ1dHRvbjoge1xuICAgICAgW2lkOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJWaWV3cG9ydENvb3JkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHJlbW90ZVNlbGVjdGVkRWxlbWVudElkczogUmVuZGVyQ29uZmlnW1wicmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzXCJdID1cbiAgICAgIHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VybmFtZXM6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGNvbnN0IHBvaW50ZXJVc2VyU3RhdGVzOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICB0aGlzLnN0YXRlLmNvbGxhYm9yYXRvcnMuZm9yRWFjaCgodXNlciwgc29ja2V0SWQpID0+IHtcbiAgICAgIGlmICh1c2VyLnNlbGVjdGVkRWxlbWVudElkcykge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIE9iamVjdC5rZXlzKHVzZXIuc2VsZWN0ZWRFbGVtZW50SWRzKSkge1xuICAgICAgICAgIGlmICghKGlkIGluIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkcykpIHtcbiAgICAgICAgICAgIHJlbW90ZVNlbGVjdGVkRWxlbWVudElkc1tpZF0gPSBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzW2lkXS5wdXNoKHNvY2tldElkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCF1c2VyLnBvaW50ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlcm5hbWUpIHtcbiAgICAgICAgcG9pbnRlclVzZXJuYW1lc1tzb2NrZXRJZF0gPSB1c2VyLnVzZXJuYW1lO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXIudXNlclN0YXRlKSB7XG4gICAgICAgIHBvaW50ZXJVc2VyU3RhdGVzW3NvY2tldElkXSA9IHVzZXIudXNlclN0YXRlO1xuICAgICAgfVxuICAgICAgcG9pbnRlclZpZXdwb3J0Q29vcmRzW3NvY2tldElkXSA9IHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3JkcyhcbiAgICAgICAge1xuICAgICAgICAgIHNjZW5lWDogdXNlci5wb2ludGVyLngsXG4gICAgICAgICAgc2NlbmVZOiB1c2VyLnBvaW50ZXIueSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBjdXJzb3JCdXR0b25bc29ja2V0SWRdID0gdXNlci5idXR0b247XG4gICAgfSk7XG4gICAgY29uc3QgcmVuZGVyaW5nRWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCkuZmlsdGVyKChlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIC8vIG5vdCBwbGFjZWQgb24gY2FudmFzIHlldCAoYnV0IGluIGVsZW1lbnRzIGFycmF5KVxuICAgICAgICAgIHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudCAmJlxuICAgICAgICAgIGVsZW1lbnQuaWQgPT09IHRoaXMuc3RhdGUucGVuZGluZ0ltYWdlRWxlbWVudC5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGRvbid0IHJlbmRlciB0ZXh0IGVsZW1lbnQgdGhhdCdzIGJlaW5nIGN1cnJlbnRseSBlZGl0ZWQgKGl0J3NcbiAgICAgIC8vIHJlbmRlcmVkIG9uIHJlbW90ZSBvbmx5KVxuICAgICAgcmV0dXJuIChcbiAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0VsZW1lbnQgfHxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudC50eXBlICE9PSBcInRleHRcIiB8fFxuICAgICAgICBlbGVtZW50LmlkICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50LmlkXG4gICAgICApO1xuICAgIH0pO1xuICAgIGNvbnN0IHsgYXRMZWFzdE9uZVZpc2libGVFbGVtZW50LCBzY3JvbGxCYXJzIH0gPSByZW5kZXJTY2VuZShcbiAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgIHRoaXMuc3RhdGUuc2VsZWN0aW9uRWxlbWVudCxcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgdGhpcy5yYyEsXG4gICAgICB0aGlzLmNhbnZhcyEsXG4gICAgICB7XG4gICAgICAgIHNjcm9sbFg6IHRoaXMuc3RhdGUuc2Nyb2xsWCxcbiAgICAgICAgc2Nyb2xsWTogdGhpcy5zdGF0ZS5zY3JvbGxZLFxuICAgICAgICB2aWV3QmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLnZpZXdCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgIHpvb206IHRoaXMuc3RhdGUuem9vbSxcbiAgICAgICAgcmVtb3RlUG9pbnRlclZpZXdwb3J0Q29vcmRzOiBwb2ludGVyVmlld3BvcnRDb29yZHMsXG4gICAgICAgIHJlbW90ZVBvaW50ZXJCdXR0b246IGN1cnNvckJ1dHRvbixcbiAgICAgICAgcmVtb3RlU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlcm5hbWVzOiBwb2ludGVyVXNlcm5hbWVzLFxuICAgICAgICByZW1vdGVQb2ludGVyVXNlclN0YXRlczogcG9pbnRlclVzZXJTdGF0ZXMsXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdGhpcy5zdGF0ZS5zaG91bGRDYWNoZUlnbm9yZVpvb20sXG4gICAgICAgIHRoZW1lOiB0aGlzLnN0YXRlLnRoZW1lLFxuICAgICAgICBpbWFnZUNhY2hlOiB0aGlzLmltYWdlQ2FjaGUsXG4gICAgICAgIGlzRXhwb3J0aW5nOiBmYWxzZSxcbiAgICAgICAgcmVuZGVyU2Nyb2xsYmFyczogIXRoaXMuaXNNb2JpbGUsXG4gICAgICB9LFxuICAgICk7XG4gICAgaWYgKHNjcm9sbEJhcnMpIHtcbiAgICAgIGN1cnJlbnRTY3JvbGxCYXJzID0gc2Nyb2xsQmFycztcbiAgICB9XG4gICAgY29uc3Qgc2Nyb2xsZWRPdXRzaWRlID1cbiAgICAgIC8vIGhpZGUgd2hlbiBlZGl0aW5nIHRleHRcbiAgICAgIGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudClcbiAgICAgICAgPyBmYWxzZVxuICAgICAgICA6ICFhdExlYXN0T25lVmlzaWJsZUVsZW1lbnQgJiYgcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoID4gMDtcbiAgICBpZiAodGhpcy5zdGF0ZS5zY3JvbGxlZE91dHNpZGUgIT09IHNjcm9sbGVkT3V0c2lkZSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNjcm9sbGVkT3V0c2lkZSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmhpc3RvcnkucmVjb3JkKHRoaXMuc3RhdGUsIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkpO1xuXG4gICAgdGhpcy5zY2hlZHVsZUltYWdlUmVmcmVzaCgpO1xuXG4gICAgLy8gRG8gbm90IG5vdGlmeSBjb25zdW1lcnMgaWYgd2UncmUgc3RpbGwgbG9hZGluZyB0aGUgc2NlbmUuIEFtb25nIG90aGVyXG4gICAgLy8gcG90ZW50aWFsIGlzc3VlcywgdGhpcyBmaXhlcyBhIGNhc2Ugd2hlcmUgdGhlIHRhYiBpc24ndCBmb2N1c2VkIGR1cmluZ1xuICAgIC8vIGluaXQsIHdoaWNoIHdvdWxkIHRyaWdnZXIgb25DaGFuZ2Ugd2l0aCBlbXB0eSBlbGVtZW50cywgd2hpY2ggd291bGQgdGhlblxuICAgIC8vIG92ZXJyaWRlIHdoYXRldmVyIGlzIGluIGxvY2FsU3RvcmFnZSBjdXJyZW50bHkuXG4gICAgaWYgKCF0aGlzLnN0YXRlLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZT8uKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICB0aGlzLmZpbGVzLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uU2Nyb2xsID0gZGVib3VuY2UoKCkgPT4ge1xuICAgIGNvbnN0IHsgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSB0aGlzLmdldENhbnZhc09mZnNldHMoKTtcbiAgICB0aGlzLnNldFN0YXRlKChzdGF0ZSkgPT4ge1xuICAgICAgaWYgKHN0YXRlLm9mZnNldExlZnQgPT09IG9mZnNldExlZnQgJiYgc3RhdGUub2Zmc2V0VG9wID09PSBvZmZzZXRUb3ApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBvZmZzZXRUb3AsIG9mZnNldExlZnQgfTtcbiAgICB9KTtcbiAgfSwgU0NST0xMX1RJTUVPVVQpO1xuXG4gIC8vIENvcHkvcGFzdGVcblxuICBwcml2YXRlIG9uQ3V0ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1dEFsbCgpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH0pO1xuXG4gIHByaXZhdGUgb25Db3B5ID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc0V4Y2FsaWRyYXdBY3RpdmUgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudD8uY29udGFpbnMoXG4gICAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50LFxuICAgICk7XG4gICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUgfHwgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9KTtcblxuICBwcml2YXRlIGN1dEFsbCA9ICgpID0+IHtcbiAgICB0aGlzLmNvcHlBbGwoKTtcbiAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25EZWxldGVTZWxlY3RlZCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb3B5QWxsID0gKCkgPT4ge1xuICAgIGNvcHlUb0NsaXBib2FyZCh0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksIHRoaXMuc3RhdGUsIHRoaXMuZmlsZXMpO1xuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIHJlc2V0VGFwVHdpY2UoKSB7XG4gICAgZGlkVGFwVHdpY2UgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25UYXBTdGFydCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmICghZGlkVGFwVHdpY2UpIHtcbiAgICAgIGRpZFRhcFR3aWNlID0gdHJ1ZTtcbiAgICAgIGNsZWFyVGltZW91dCh0YXBwZWRUd2ljZVRpbWVyKTtcbiAgICAgIHRhcHBlZFR3aWNlVGltZXIgPSB3aW5kb3cuc2V0VGltZW91dChcbiAgICAgICAgQXBwLnJlc2V0VGFwVHdpY2UsXG4gICAgICAgIFRBUF9UV0lDRV9USU1FT1VULFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaW5zZXJ0IHRleHQgb25seSBpZiB3ZSB0YXBwZWQgdHdpY2Ugd2l0aCBhIHNpbmdsZSBmaW5nZXJcbiAgICAvLyBldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSB3aWxsIGFsc28gcHJldmVudCBpbnNlcnRpbmcgdGV4dCB3aGVuIHVzZXIncyB6b29taW5nXG4gICAgaWYgKGRpZFRhcFR3aWNlICYmIGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBbdG91Y2hdID0gZXZlbnQudG91Y2hlcztcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2soe1xuICAgICAgICBjbGllbnRYOiB0b3VjaC5jbGllbnRYLFxuICAgICAgICBjbGllbnRZOiB0b3VjaC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgICBkaWRUYXBUd2ljZSA9IGZhbHNlO1xuICAgICAgY2xlYXJUaW1lb3V0KHRhcHBlZFR3aWNlVGltZXIpO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBvblRhcEVuZCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5wcmV2aW91c1NlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHBhc3RlRnJvbUNsaXBib2FyZCA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICBhc3luYyAoZXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4ge1xuICAgICAgLy8gIzY4NlxuICAgICAgY29uc3QgdGFyZ2V0ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGlzRXhjYWxpZHJhd0FjdGl2ZSA9XG4gICAgICAgIHRoaXMuZXhjYWxpZHJhd0NvbnRhaW5lclJlZi5jdXJyZW50Py5jb250YWlucyh0YXJnZXQpO1xuICAgICAgaWYgKCFpc0V4Y2FsaWRyYXdBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBlbGVtZW50VW5kZXJDdXJzb3IgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGN1cnNvclgsIGN1cnNvclkpO1xuICAgICAgaWYgKFxuICAgICAgICAvLyBpZiBubyBDbGlwYm9hcmRFdmVudCBzdXBwbGllZCwgYXNzdW1lIHdlJ3JlIHBhc3RpbmcgdmlhIGNvbnRleHRNZW51XG4gICAgICAgIC8vIHRodXMgdGhlc2UgY2hlY2tzIGRvbid0IG1ha2Ugc2Vuc2VcbiAgICAgICAgZXZlbnQgJiZcbiAgICAgICAgKCEoZWxlbWVudFVuZGVyQ3Vyc29yIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHx8XG4gICAgICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG11c3QgYmUgY2FsbGVkIGluIHRoZSBzYW1lIGZyYW1lICh0aHVzIGJlZm9yZSBhbnkgYXdhaXRzKSBhcyB0aGUgcGFzdGVcbiAgICAgIC8vIGV2ZW50IGVsc2Ugc29tZSBicm93c2VycyAoRkYuLi4pIHdpbGwgY2xlYXIgdGhlIGNsaXBib2FyZERhdGFcbiAgICAgIC8vIChzb21ldGhpbmcgc29tZXRoaW5nIHNlY3VyaXR5KVxuICAgICAgbGV0IGZpbGUgPSBldmVudD8uY2xpcGJvYXJkRGF0YT8uZmlsZXNbMF07XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBwYXJzZUNsaXBib2FyZChldmVudCk7XG5cbiAgICAgIGlmICghZmlsZSAmJiBkYXRhLnRleHQpIHtcbiAgICAgICAgY29uc3Qgc3RyaW5nID0gZGF0YS50ZXh0LnRyaW0oKTtcbiAgICAgICAgaWYgKHN0cmluZy5zdGFydHNXaXRoKFwiPHN2Z1wiKSAmJiBzdHJpbmcuZW5kc1dpdGgoXCI8L3N2Zz5cIikpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgU1ZHIHZhbGlkYXRpb24vbm9ybWFsaXphdGlvbiB3aGljaCB3aWxsIGJlIGRvbmUgZHVyaW5nIGltYWdlXG4gICAgICAgICAgLy8gaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICBmaWxlID0gU1ZHU3RyaW5nVG9GaWxlKHN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpKSB7XG4gICAgICAgIGNvbnN0IHsgeDogc2NlbmVYLCB5OiBzY2VuZVkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHsgc2NlbmVYLCBzY2VuZVkgfSk7XG4gICAgICAgIHRoaXMuaW5zZXJ0SW1hZ2VFbGVtZW50KGltYWdlRWxlbWVudCwgZmlsZSk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUltYWdlRGltZW5zaW9ucyhpbWFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wcm9wcy5vblBhc3RlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3BzLm9uUGFzdGUoZGF0YSwgZXZlbnQpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRhdGEuZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvck1lc3NhZ2U6IGRhdGEuZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIGlmIChkYXRhLnNwcmVhZHNoZWV0KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhc3RlRGlhbG9nOiB7XG4gICAgICAgICAgICBkYXRhOiBkYXRhLnNwcmVhZHNoZWV0LFxuICAgICAgICAgICAgc2hvd246IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50c0Zyb21QYXN0ZU9yTGlicmFyeSh7XG4gICAgICAgICAgZWxlbWVudHM6IGRhdGEuZWxlbWVudHMsXG4gICAgICAgICAgZmlsZXM6IGRhdGEuZmlsZXMgfHwgbnVsbCxcbiAgICAgICAgICBwb3NpdGlvbjogXCJjdXJzb3JcIixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEudGV4dCkge1xuICAgICAgICB0aGlzLmFkZFRleHRGcm9tUGFzdGUoZGF0YS50ZXh0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VsZWN0U2hhcGVUb29sKFwic2VsZWN0aW9uXCIpO1xuICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIGFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5ID0gKG9wdHM6IHtcbiAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXTtcbiAgICBmaWxlczogQmluYXJ5RmlsZXMgfCBudWxsO1xuICAgIHBvc2l0aW9uOiB7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH0gfCBcImN1cnNvclwiIHwgXCJjZW50ZXJcIjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gcmVzdG9yZUVsZW1lbnRzKG9wdHMuZWxlbWVudHMsIG51bGwpO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhlbGVtZW50cyk7XG5cbiAgICBjb25zdCBlbGVtZW50c0NlbnRlclggPSBkaXN0YW5jZShtaW5YLCBtYXhYKSAvIDI7XG4gICAgY29uc3QgZWxlbWVudHNDZW50ZXJZID0gZGlzdGFuY2UobWluWSwgbWF4WSkgLyAyO1xuXG4gICAgY29uc3QgY2xpZW50WCA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WFxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JYXG4gICAgICAgIDogdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgY29uc3QgY2xpZW50WSA9XG4gICAgICB0eXBlb2Ygb3B0cy5wb3NpdGlvbiA9PT0gXCJvYmplY3RcIlxuICAgICAgICA/IG9wdHMucG9zaXRpb24uY2xpZW50WVxuICAgICAgICA6IG9wdHMucG9zaXRpb24gPT09IFwiY3Vyc29yXCJcbiAgICAgICAgPyBjdXJzb3JZXG4gICAgICAgIDogdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgIHsgY2xpZW50WCwgY2xpZW50WSB9LFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZHggPSB4IC0gZWxlbWVudHNDZW50ZXJYO1xuICAgIGNvbnN0IGR5ID0geSAtIGVsZW1lbnRzQ2VudGVyWTtcbiAgICBjb25zdCBncm91cElkTWFwID0gbmV3IE1hcCgpO1xuXG4gICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoZHgsIGR5LCB0aGlzLnN0YXRlLmdyaWRTaXplKTtcblxuICAgIGNvbnN0IG9sZElkVG9EdXBsaWNhdGVkSWQgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgbmV3RWxlbWVudHMgPSBlbGVtZW50cy5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkdXBsaWNhdGVFbGVtZW50KFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdHcm91cElkLFxuICAgICAgICBncm91cElkTWFwLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICB7XG4gICAgICAgICAgeDogZWxlbWVudC54ICsgZ3JpZFggLSBtaW5YLFxuICAgICAgICAgIHk6IGVsZW1lbnQueSArIGdyaWRZIC0gbWluWSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBvbGRJZFRvRHVwbGljYXRlZElkLnNldChlbGVtZW50LmlkLCBuZXdFbGVtZW50LmlkKTtcbiAgICAgIHJldHVybiBuZXdFbGVtZW50O1xuICAgIH0pO1xuICAgIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24obmV3RWxlbWVudHMsIGVsZW1lbnRzLCBvbGRJZFRvRHVwbGljYXRlZElkKTtcbiAgICBjb25zdCBuZXh0RWxlbWVudHMgPSBbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgLi4ubmV3RWxlbWVudHMsXG4gICAgXTtcbiAgICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24obmV4dEVsZW1lbnRzLCBlbGVtZW50cywgb2xkSWRUb0R1cGxpY2F0ZWRJZCk7XG5cbiAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4ub3B0cy5maWxlcyB9O1xuICAgIH1cblxuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKG5leHRFbGVtZW50cyk7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB7XG4gICAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgICBpc0xpYnJhcnlPcGVuOiBmYWxzZSxcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IG5ld0VsZW1lbnRzLnJlZHVjZSgobWFwLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiAhZWxlbWVudC5jb250YWluZXJJZCkge1xuICAgICAgICAgICAgICBtYXBbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgICAgICB9LCB7fSBhcyBhbnkpLFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICApLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAob3B0cy5maWxlcykge1xuICAgICAgICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLnNlbGVjdFNoYXBlVG9vbChcInNlbGVjdGlvblwiKTtcbiAgfTtcblxuICBwcml2YXRlIGFkZFRleHRGcm9tUGFzdGUodGV4dDogYW55KSB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICB7IGNsaWVudFg6IGN1cnNvclgsIGNsaWVudFk6IGN1cnNvclkgfSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdUZXh0RWxlbWVudCh7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU2hhcnBuZXNzLFxuICAgICAgdGV4dCxcbiAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICBmb250RmFtaWx5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udEZhbWlseSxcbiAgICAgIHRleHRBbGlnbjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVRleHRBbGlnbixcbiAgICAgIHZlcnRpY2FsQWxpZ246IERFRkFVTFRfVkVSVElDQUxfQUxJR04sXG4gICAgfSk7XG5cbiAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgZWxlbWVudCxcbiAgICBdKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtlbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgfVxuXG4gIC8vIENvbGxhYm9yYXRpb25cblxuICBzZXRBcHBTdGF0ZSA9IChvYmo6IGFueSkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUob2JqKTtcbiAgfTtcblxuICByZW1vdmVQb2ludGVyID0gKGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTEVsZW1lbnQ+IHwgUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgLy8gcmVtb3ZlIHRvdWNoIGhhbmRsZXIgZm9yIGNvbnRleHQgbWVudSBvbiB0b3VjaCBkZXZpY2VzXG4gICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIgJiYgdG91Y2hUaW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQodG91Y2hUaW1lb3V0KTtcbiAgICAgIHRvdWNoVGltZW91dCA9IDA7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXN0dXJlLnBvaW50ZXJzLmRlbGV0ZShldmVudC5wb2ludGVySWQpO1xuICB9O1xuXG4gIHRvZ2dsZUxvY2sgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbGVtZW50TG9ja2VkOiAhcHJldlN0YXRlLmVsZW1lbnRMb2NrZWQsXG4gICAgICAgIGVsZW1lbnRUeXBlOiBwcmV2U3RhdGUuZWxlbWVudExvY2tlZFxuICAgICAgICAgID8gXCJzZWxlY3Rpb25cIlxuICAgICAgICAgIDogcHJldlN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICB0b2dnbGVaZW5Nb2RlID0gKCkgPT4ge1xuICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvblRvZ2dsZVplbk1vZGUpO1xuICB9O1xuXG4gIHRvZ2dsZVN0YXRzID0gKCkgPT4ge1xuICAgIGlmICghdGhpcy5zdGF0ZS5zaG93U3RhdHMpIHtcbiAgICAgIHRyYWNrRXZlbnQoXCJkaWFsb2dcIiwgXCJzdGF0c1wiKTtcbiAgICB9XG4gICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uVG9nZ2xlU3RhdHMpO1xuICB9O1xuXG4gIHNjcm9sbFRvQ29udGVudCA9IChcbiAgICB0YXJnZXQ6XG4gICAgICB8IEV4Y2FsaWRyYXdFbGVtZW50XG4gICAgICB8IHJlYWRvbmx5IEV4Y2FsaWRyYXdFbGVtZW50W10gPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICkgPT4ge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgLi4uY2FsY3VsYXRlU2Nyb2xsQ2VudGVyKFxuICAgICAgICBBcnJheS5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQgOiBbdGFyZ2V0XSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICApLFxuICAgIH0pO1xuICB9O1xuXG4gIGNsZWFyVG9hc3QgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHRvYXN0TWVzc2FnZTogbnVsbCB9KTtcbiAgfTtcblxuICBzZXRUb2FzdE1lc3NhZ2UgPSAodG9hc3RNZXNzYWdlOiBzdHJpbmcpID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgdG9hc3RNZXNzYWdlIH0pO1xuICB9O1xuXG4gIHJlc3RvcmVGaWxlRnJvbVNoYXJlID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB3ZWJTaGFyZVRhcmdldENhY2hlID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJ3ZWItc2hhcmUtdGFyZ2V0XCIpO1xuXG4gICAgICBjb25zdCBmaWxlID0gYXdhaXQgd2ViU2hhcmVUYXJnZXRDYWNoZS5tYXRjaChcInNoYXJlZC1maWxlXCIpO1xuICAgICAgaWYgKGZpbGUpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IGZpbGUuYmxvYigpO1xuICAgICAgICB0aGlzLmxvYWRGaWxlVG9DYW52YXMoYmxvYik7XG4gICAgICAgIGF3YWl0IHdlYlNoYXJlVGFyZ2V0Q2FjaGUuZGVsZXRlKFwic2hhcmVkLWZpbGVcIik7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBBUFBfTkFNRSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JNZXNzYWdlOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKiogYWRkcyBzdXBwbGllZCBmaWxlcyB0byBleGlzdGluZyBmaWxlcyBpbiB0aGUgYXBwU3RhdGUgKi9cbiAgcHVibGljIGFkZEZpbGVzOiBFeGNhbGlkcmF3SW1wZXJhdGl2ZUFQSVtcImFkZEZpbGVzXCJdID0gd2l0aEJhdGNoZWRVcGRhdGVzKFxuICAgIChmaWxlcykgPT4ge1xuICAgICAgY29uc3QgZmlsZXNNYXAgPSBmaWxlcy5yZWR1Y2UoKGFjYywgZmlsZURhdGEpID0+IHtcbiAgICAgICAgYWNjLnNldChmaWxlRGF0YS5pZCwgZmlsZURhdGEpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcDxGaWxlSWQsIEJpbmFyeUZpbGVEYXRhPigpKTtcblxuICAgICAgdGhpcy5maWxlcyA9IHsgLi4udGhpcy5maWxlcywgLi4uT2JqZWN0LmZyb21FbnRyaWVzKGZpbGVzTWFwKSB9O1xuXG4gICAgICAvLyBidW1wIHZlcnNpb25zIGZvciBlbGVtZW50cyB0aGF0IHJlZmVyZW5jZSBhZGRlZCBmaWxlcyBzbyB0aGF0XG4gICAgICAvLyB3ZS9ob3N0IGFwcHMgY2FuIGRldGVjdCB0aGUgY2hhbmdlLCBhbmQgaW52YWxpZGF0ZSB0aGUgaW1hZ2UgJiBzaGFwZVxuICAgICAgLy8gY2FjaGVcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0luaXRpYWxpemVkSW1hZ2VFbGVtZW50KGVsZW1lbnQpICYmXG4gICAgICAgICAgZmlsZXNNYXAuaGFzKGVsZW1lbnQuZmlsZUlkKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmltYWdlQ2FjaGUuZGVsZXRlKGVsZW1lbnQuZmlsZUlkKTtcbiAgICAgICAgICBpbnZhbGlkYXRlU2hhcGVGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgIGJ1bXBWZXJzaW9uKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2NlbmUuaW5mb3JtTXV0YXRpb24oKTtcblxuICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICB9LFxuICApO1xuXG4gIHB1YmxpYyB1cGRhdGVTY2VuZSA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICA8SyBleHRlbmRzIGtleW9mIEFwcFN0YXRlPihzY2VuZURhdGE6IHtcbiAgICAgIGVsZW1lbnRzPzogU2NlbmVEYXRhW1wiZWxlbWVudHNcIl07XG4gICAgICBhcHBTdGF0ZT86IFBpY2s8QXBwU3RhdGUsIEs+IHwgbnVsbDtcbiAgICAgIGNvbGxhYm9yYXRvcnM/OiBTY2VuZURhdGFbXCJjb2xsYWJvcmF0b3JzXCJdO1xuICAgICAgY29tbWl0VG9IaXN0b3J5PzogU2NlbmVEYXRhW1wiY29tbWl0VG9IaXN0b3J5XCJdO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChzY2VuZURhdGEuY29tbWl0VG9IaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5hcHBTdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHNjZW5lRGF0YS5hcHBTdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2VuZURhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoc2NlbmVEYXRhLmVsZW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjZW5lRGF0YS5jb2xsYWJvcmF0b3JzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb2xsYWJvcmF0b3JzOiBzY2VuZURhdGEuY29sbGFib3JhdG9ycyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICApO1xuXG4gIHByaXZhdGUgb25TY2VuZVVwZGF0ZWQgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7fSk7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDdXJyZW50Q3Vyc29yUG9zaXRpb24gPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoXG4gICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjdXJzb3JYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgIGN1cnNvclkgPSBldmVudC5jbGllbnRZO1xuICAgIH0sXG4gICk7XG5cbiAgLy8gSW5wdXQgaGFuZGxpbmdcblxuICBwcml2YXRlIG9uS2V5RG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAoZXZlbnQ6IFJlYWN0LktleWJvYXJkRXZlbnQgfCBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBub3JtYWxpemUgYGV2ZW50LmtleWAgd2hlbiBDYXBzTG9jayBpcyBwcmVzc2VkICMyMzcyXG4gICAgICBpZiAoXG4gICAgICAgIFwiUHJveHlcIiBpbiB3aW5kb3cgJiZcbiAgICAgICAgKCghZXZlbnQuc2hpZnRLZXkgJiYgL15bQS1aXSQvLnRlc3QoZXZlbnQua2V5KSkgfHxcbiAgICAgICAgICAoZXZlbnQuc2hpZnRLZXkgJiYgL15bYS16XSQvLnRlc3QoZXZlbnQua2V5KSkpXG4gICAgICApIHtcbiAgICAgICAgZXZlbnQgPSBuZXcgUHJveHkoZXZlbnQsIHtcbiAgICAgICAgICBnZXQoZXY6IGFueSwgcHJvcCkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBldltwcm9wXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAvLyBmaXggZm9yIFByb3hpZXMgaGlqYWNraW5nIGB0aGlzYFxuICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYmluZChldik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvcCA9PT0gXCJrZXlcIlxuICAgICAgICAgICAgICA/IC8vIENhcHNMb2NrIGludmVydHMgY2FwaXRhbGl6YXRpb24gYmFzZWQgb24gU2hpZnRLZXksIHNvIGludmVydFxuICAgICAgICAgICAgICAgIC8vIGl0IGJhY2tcbiAgICAgICAgICAgICAgICBldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICAgID8gZXYua2V5LnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgICAgICA6IGV2LmtleS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgIDogdmFsdWU7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgKGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkgJiYgZXZlbnQua2V5ICE9PSBLRVlTLkVTQ0FQRSkgfHxcbiAgICAgICAgLy8gY2FzZTogdXNpbmcgYXJyb3dzIHRvIG1vdmUgYmV0d2VlbiBidXR0b25zXG4gICAgICAgIChpc0Fycm93S2V5KGV2ZW50LmtleSkgJiYgaXNJbnB1dExpa2UoZXZlbnQudGFyZ2V0KSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuUVVFU1RJT05fTUFSSykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzaG93SGVscERpYWxvZzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFjdGlvbk1hbmFnZXIuaGFuZGxlS2V5RG93bihldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgdGhpcy5zdGF0ZS5pc0JpbmRpbmdFbmFibGVkKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmNvZGUgPT09IENPREVTLlpFUk8pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46ICF0aGlzLnN0YXRlLmlzTGlicmFyeU9wZW4gfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9XG4gICAgICAgICAgKHRoaXMuc3RhdGUuZ3JpZFNpemUgJiZcbiAgICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgICA/IEVMRU1FTlRfVFJBTlNMQVRFX0FNT1VOVFxuICAgICAgICAgICAgICA6IHRoaXMuc3RhdGUuZ3JpZFNpemUpKSB8fFxuICAgICAgICAgIChldmVudC5zaGlmdEtleVxuICAgICAgICAgICAgPyBFTEVNRU5UX1NISUZUX1RSQU5TTEFURV9BTU9VTlRcbiAgICAgICAgICAgIDogRUxFTUVOVF9UUkFOU0xBVEVfQU1PVU5UKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gdGhpcy5zY2VuZVxuICAgICAgICAgIC5nZXRFbGVtZW50cygpXG4gICAgICAgICAgLmZpbHRlcigoZWxlbWVudCkgPT4gdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbZWxlbWVudC5pZF0pO1xuXG4gICAgICAgIGxldCBvZmZzZXRYID0gMDtcbiAgICAgICAgbGV0IG9mZnNldFkgPSAwO1xuXG4gICAgICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfTEVGVCkge1xuICAgICAgICAgIG9mZnNldFggPSAtc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfUklHSFQpIHtcbiAgICAgICAgICBvZmZzZXRYID0gc3RlcDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuQVJST1dfVVApIHtcbiAgICAgICAgICBvZmZzZXRZID0gLXN0ZXA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkFSUk9XX0RPV04pIHtcbiAgICAgICAgICBvZmZzZXRZID0gc3RlcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgICAgeDogZWxlbWVudC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgIHk6IGVsZW1lbnQueSArIG9mZnNldFksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB1cGRhdGVCb3VuZEVsZW1lbnRzKGVsZW1lbnQsIHtcbiAgICAgICAgICAgIHNpbXVsdGFuZW91c2x5VXBkYXRlZDogc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5FTlRFUikge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkICE9PSBzZWxlY3RlZEVsZW1lbnRzWzBdLmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgZWRpdGluZ0xpbmVhckVsZW1lbnQ6IG5ldyBMaW5lYXJFbGVtZW50RWRpdG9yKFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICFpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcblxuICAgICAgICAgIHRoaXMuc3RhcnRUZXh0RWRpdGluZyh7XG4gICAgICAgICAgICBzY2VuZVg6IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMixcbiAgICAgICAgICAgIHNjZW5lWTogc2VsZWN0ZWRFbGVtZW50LnkgKyBzZWxlY3RlZEVsZW1lbnQuaGVpZ2h0IC8gMixcbiAgICAgICAgICAgIHNob3VsZEJpbmQ6IHRydWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICFldmVudC5jdHJsS2V5ICYmXG4gICAgICAgICFldmVudC5hbHRLZXkgJiZcbiAgICAgICAgIWV2ZW50Lm1ldGFLZXkgJiZcbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQgPT09IG51bGxcbiAgICAgICkge1xuICAgICAgICBjb25zdCBzaGFwZSA9IGZpbmRTaGFwZUJ5S2V5KGV2ZW50LmtleSk7XG4gICAgICAgIGlmIChzaGFwZSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0U2hhcGVUb29sKHNoYXBlKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuUSkge1xuICAgICAgICAgIHRoaXMudG9nZ2xlTG9jaygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLlNQQUNFICYmIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBpc0hvbGRpbmdTcGFjZSA9IHRydWU7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkcgfHwgZXZlbnQua2V5ID09PSBLRVlTLlMpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgICAgIXNlbGVjdGVkRWxlbWVudHMubGVuZ3RoXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBldmVudC5rZXkgPT09IEtFWVMuRyAmJlxuICAgICAgICAgIChoYXNCYWNrZ3JvdW5kKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpIHx8XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+IGhhc0JhY2tncm91bmQoZWxlbWVudC50eXBlKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBvcGVuUG9wdXA6IFwiYmFja2dyb3VuZENvbG9yUGlja2VyXCIgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG9wZW5Qb3B1cDogXCJzdHJva2VDb2xvclBpY2tlclwiIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgKTtcblxuICBwcml2YXRlIG9uS2V5VXAgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gS0VZUy5TUEFDRSkge1xuICAgICAgaWYgKHRoaXMuc3RhdGUudmlld01vZGVFbmFibGVkKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcmVzZXRDdXJzb3IodGhpcy5jYW52YXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Q3Vyc29yRm9yU2hhcGUodGhpcy5jYW52YXMsIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlzSG9sZGluZ1NwYWNlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiYgIXRoaXMuc3RhdGUuaXNCaW5kaW5nRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzQmluZGluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gICAgfVxuICAgIGlmIChpc0Fycm93S2V5KGV2ZW50LmtleSkpIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICApO1xuICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKVxuICAgICAgICA/IGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cylcbiAgICAgICAgOiB1bmJpbmRMaW5lYXJFbGVtZW50cyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICB9KTtcblxuICBwcml2YXRlIHNlbGVjdFNoYXBlVG9vbChlbGVtZW50VHlwZTogQXBwU3RhdGVbXCJlbGVtZW50VHlwZVwiXSkge1xuICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCBlbGVtZW50VHlwZSk7XG4gICAgfVxuICAgIGlmIChpc1Rvb2xJY29uKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgfVxuICAgIGlmICghaXNMaW5lYXJFbGVtZW50VHlwZShlbGVtZW50VHlwZSkpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5nczogW10gfSk7XG4gICAgfVxuICAgIGlmIChlbGVtZW50VHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICB0aGlzLm9uSW1hZ2VBY3Rpb24oKTtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZWxlbWVudFR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgZWxlbWVudFR5cGUgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVTdGFydCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgIH0pO1xuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICB9KTtcblxuICBwcml2YXRlIG9uR2VzdHVyZUNoYW5nZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IEdlc3R1cmVFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAvLyBvbkdlc3R1cmVDaGFuZ2Ugb25seSBoYXMgem9vbSBmYWN0b3IgYnV0IG5vdCB0aGUgY2VudGVyLlxuICAgIC8vIElmIHdlJ3JlIG9uIGlQYWQgb3IgaVBob25lLCB0aGVuIHdlIHJlY29nbml6ZSBtdWx0aS10b3VjaCBhbmQgd2lsbFxuICAgIC8vIHpvb20gaW4gYXQgdGhlIHJpZ2h0IGxvY2F0aW9uIG9uIHRoZSB0b3VjaE1vdmUgaGFuZGxlciBhbHJlYWR5LlxuICAgIC8vIE9uIE1hY2Jvb2ssIHdlIGRvbid0IGhhdmUgdGhvc2UgZXZlbnRzIHNvIHdpbGwgem9vbSBpbiBhdCB0aGVcbiAgICAvLyBjdXJyZW50IGxvY2F0aW9uIGluc3RlYWQuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYWxTY2FsZSA9IGdlc3R1cmUuaW5pdGlhbFNjYWxlO1xuICAgIGlmIChpbml0aWFsU2NhbGUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoKHsgem9vbSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0pID0+ICh7XG4gICAgICAgIHpvb206IGdldE5ld1pvb20oXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogZXZlbnQuc2NhbGUpLFxuICAgICAgICAgIHpvb20sXG4gICAgICAgICAgeyBsZWZ0OiBvZmZzZXRMZWZ0LCB0b3A6IG9mZnNldFRvcCB9LFxuICAgICAgICAgIHsgeDogY3Vyc29yWCwgeTogY3Vyc29yWSB9LFxuICAgICAgICApLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJpdmF0ZSBvbkdlc3R1cmVFbmQgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBHZXN0dXJlRXZlbnQpID0+IHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID0gbnVsbDtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXh0V3lzaXd5ZyhcbiAgICBlbGVtZW50OiBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gICAge1xuICAgICAgaXNFeGlzdGluZ0VsZW1lbnQgPSBmYWxzZSxcbiAgICB9OiB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IChcbiAgICAgIHRleHQ6IHN0cmluZyxcbiAgICAgIG9yaWdpbmFsVGV4dDogc3RyaW5nLFxuICAgICAgaXNEZWxldGVkID0gZmFsc2UsXG4gICAgICB1cGRhdGVEaW1lbnNpb25zID0gZmFsc2UsXG4gICAgKSA9PiB7XG4gICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhbXG4gICAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkubWFwKChfZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChfZWxlbWVudC5pZCA9PT0gZWxlbWVudC5pZCAmJiBpc1RleHRFbGVtZW50KF9lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVRleHRFbGVtZW50KFxuICAgICAgICAgICAgICBfZWxlbWVudCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgICAgaXNEZWxldGVkLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsVGV4dCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdXBkYXRlRGltZW5zaW9ucyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBfZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICBdKTtcbiAgICB9O1xuXG4gICAgdGV4dFd5c2l3eWcoe1xuICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICBhcHBTdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgIGNhbnZhczogdGhpcy5jYW52YXMsXG4gICAgICBnZXRWaWV3cG9ydENvb3JkczogKHgsIHkpID0+IHtcbiAgICAgICAgY29uc3QgeyB4OiB2aWV3cG9ydFgsIHk6IHZpZXdwb3J0WSB9ID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNjZW5lWDogeCxcbiAgICAgICAgICAgIHNjZW5lWTogeSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgdmlld3BvcnRYLC8vIC0gdGhpcy5zdGF0ZS5vZmZzZXRMZWZ0LCAvLyogKDIgLSB0aGlzLnN0YXRlLnpvb20udmFsdWUpLFxuICAgICAgICAgIHZpZXdwb3J0WSwvLyAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLCAvLyogKDIgLSB0aGlzLnN0YXRlLnpvb20udmFsdWUpLFxuICAgICAgICBdO1xuICAgICAgfSxcbiAgICAgIG9uQ2hhbmdlOiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKHRleHQpID0+IHtcbiAgICAgICAgdXBkYXRlRWxlbWVudCh0ZXh0LCB0ZXh0LCBmYWxzZSwgIWVsZW1lbnQuY29udGFpbmVySWQpO1xuICAgICAgICBpZiAoaXNOb25EZWxldGVkRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgIHVwZGF0ZUJvdW5kRWxlbWVudHMoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgb25TdWJtaXQ6IHdpdGhCYXRjaGVkVXBkYXRlcygoeyB0ZXh0LCB2aWFLZXlib2FyZCwgb3JpZ2luYWxUZXh0IH0pID0+IHtcbiAgICAgICAgY29uc3QgaXNEZWxldGVkID0gIXRleHQudHJpbSgpO1xuICAgICAgICB1cGRhdGVFbGVtZW50KHRleHQsIG9yaWdpbmFsVGV4dCwgaXNEZWxldGVkLCB0cnVlKTtcbiAgICAgICAgLy8gc2VsZWN0IHRoZSBjcmVhdGVkIHRleHQgZWxlbWVudCBvbmx5IGlmIHN1Ym1pdHRpbmcgdmlhIGtleWJvYXJkXG4gICAgICAgIC8vICh3aGVuIHN1Ym1pdHRpbmcgdmlhIGNsaWNrIGl0IHNob3VsZCBhY3QgYXMgc2lnbmFsIHRvIGRlc2VsZWN0KVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCAmJiB2aWFLZXlib2FyZCkge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRJZFRvU2VsZWN0ID0gZWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICAgICAgPyBlbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgICAgICA6IGVsZW1lbnQuaWQ7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgIFtlbGVtZW50SWRUb1NlbGVjdF06IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWxldGVkKSB7XG4gICAgICAgICAgZml4QmluZGluZ3NBZnRlckRlbGV0aW9uKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgW2VsZW1lbnRdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzRGVsZXRlZCB8fCBpc0V4aXN0aW5nRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGRyYWdnaW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgICBlZGl0aW5nRWxlbWVudDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRMb2NrZWQpIHtcbiAgICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvY3VzQ29udGFpbmVyKCk7XG4gICAgICB9KSxcbiAgICAgIGVsZW1lbnQsXG4gICAgICBleGNhbGlkcmF3Q29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCxcbiAgICB9KTtcbiAgICAvLyBkZXNlbGVjdCBhbGwgb3RoZXIgZWxlbWVudHMgd2hlbiBpbnNlcnRpbmcgdGV4dFxuICAgIHRoaXMuZGVzZWxlY3RFbGVtZW50cygpO1xuXG4gICAgLy8gZG8gYW4gaW5pdGlhbCB1cGRhdGUgdG8gcmUtaW5pdGlhbGl6ZSBlbGVtZW50IHBvc2l0aW9uIHNpbmNlIHdlIHdlcmVcbiAgICAvLyBtb2RpZnlpbmcgZWxlbWVudCdzIHgveSBmb3Igc2FrZSBvZiBlZGl0b3IgKGNhc2U6IHN5bmNpbmcgdG8gcmVtb3RlKVxuICAgIHVwZGF0ZUVsZW1lbnQoZWxlbWVudC50ZXh0LCBlbGVtZW50Lm9yaWdpbmFsVGV4dCk7XG4gIH1cblxuICBwcml2YXRlIGRlc2VsZWN0RWxlbWVudHMoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgc2VsZWN0ZWRHcm91cElkczoge30sXG4gICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICk6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd1RleHRFbGVtZW50PiB8IG51bGwge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKHgsIHksIHtcbiAgICAgIGluY2x1ZGVCb3VuZFRleHRFbGVtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgaXNUZXh0RWxlbWVudChlbGVtZW50KSAmJiAhZWxlbWVudC5pc0RlbGV0ZWQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBvcHRzPzoge1xuICAgICAgLyoqIGlmIHRydWUsIHJldHVybnMgdGhlIGZpcnN0IHNlbGVjdGVkIGVsZW1lbnQgKHdpdGggaGlnaGVzdCB6LWluZGV4KVxuICAgICAgICBvZiBhbGwgaGl0IGVsZW1lbnRzICovXG4gICAgICBwcmVmZXJTZWxlY3RlZD86IGJvb2xlYW47XG4gICAgICBpbmNsdWRlQm91bmRUZXh0RWxlbWVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD4gfCBudWxsIHtcbiAgICBjb25zdCBhbGxIaXRFbGVtZW50cyA9IHRoaXMuZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBvcHRzPy5pbmNsdWRlQm91bmRUZXh0RWxlbWVudCxcbiAgICApO1xuICAgIGlmIChhbGxIaXRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICBpZiAob3B0cz8ucHJlZmVyU2VsZWN0ZWQpIHtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSBhbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxOyBpbmRleCA+IC0xOyBpbmRleC0tKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2FsbEhpdEVsZW1lbnRzW2luZGV4XS5pZF0pIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxIaXRFbGVtZW50c1tpbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBlbGVtZW50V2l0aEhpZ2hlc3RaSW5kZXggPVxuICAgICAgICBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAxXTtcbiAgICAgIC8vIElmIHdlJ3JlIGhpdHRpbmcgZWxlbWVudCB3aXRoIGhpZ2hlc3Qgei1pbmRleCBvbmx5IG9uIGl0cyBib3VuZGluZyBib3hcbiAgICAgIC8vIHdoaWxlIGFsc28gaGl0dGluZyBvdGhlciBlbGVtZW50IGZpZ3VyZSwgdGhlIGxhdHRlciBzaG91bGQgYmUgY29uc2lkZXJlZC5cbiAgICAgIHJldHVybiBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgIGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleCxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIClcbiAgICAgICAgPyBhbGxIaXRFbGVtZW50c1thbGxIaXRFbGVtZW50cy5sZW5ndGggLSAyXVxuICAgICAgICA6IGVsZW1lbnRXaXRoSGlnaGVzdFpJbmRleDtcbiAgICB9XG4gICAgaWYgKGFsbEhpdEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGFsbEhpdEVsZW1lbnRzWzBdO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RWxlbWVudHNBdFBvc2l0aW9uKFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKTogTm9uRGVsZXRlZDxFeGNhbGlkcmF3RWxlbWVudD5bXSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBpbmNsdWRlQm91bmRUZXh0RWxlbWVudFxuICAgICAgPyB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKClcbiAgICAgIDogdGhpcy5zY2VuZVxuICAgICAgICAgIC5nZXRFbGVtZW50cygpXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChlbGVtZW50KSA9PiAhKGlzVGV4dEVsZW1lbnQoZWxlbWVudCkgJiYgZWxlbWVudC5jb250YWluZXJJZCksXG4gICAgICAgICAgKTtcbiAgICByZXR1cm4gZ2V0RWxlbWVudHNBdFBvc2l0aW9uKGVsZW1lbnRzLCAoZWxlbWVudCkgPT5cbiAgICAgIGhpdFRlc3QoZWxlbWVudCwgdGhpcy5zdGF0ZSwgeCwgeSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUZXh0RWRpdGluZyA9ICh7XG4gICAgc2NlbmVYLFxuICAgIHNjZW5lWSxcbiAgICBzaG91bGRCaW5kLFxuICAgIGluc2VydEF0UGFyZW50Q2VudGVyID0gdHJ1ZSxcbiAgfToge1xuICAgIC8qKiBYIHBvc2l0aW9uIHRvIGluc2VydCB0ZXh0IGF0ICovXG4gICAgc2NlbmVYOiBudW1iZXI7XG4gICAgLyoqIFkgcG9zaXRpb24gdG8gaW5zZXJ0IHRleHQgYXQgKi9cbiAgICBzY2VuZVk6IG51bWJlcjtcbiAgICBzaG91bGRCaW5kOiBib29sZWFuO1xuICAgIC8qKiB3aGV0aGVyIHRvIGF0dGVtcHQgdG8gaW5zZXJ0IGF0IGVsZW1lbnQgY2VudGVyIGlmIGFwcGxpY2FibGUgKi9cbiAgICBpbnNlcnRBdFBhcmVudENlbnRlcj86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICBsZXQgcGFyZW50Q2VudGVyUG9zaXRpb24gPVxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXIgJiZcbiAgICAgIHRoaXMuZ2V0VGV4dFd5c2l3eWdTbmFwcGVkVG9DZW50ZXJQb3NpdGlvbihcbiAgICAgICAgc2NlbmVYLFxuICAgICAgICBzY2VuZVksXG4gICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICk7XG5cbiAgICAvLyBiaW5kIHRvIGNvbnRhaW5lciB3aGVuIHNob3VsZEJpbmQgaXMgdHJ1ZSBvclxuICAgIC8vIGNsaWNrZWQgb24gY2VudGVyIG9mIGNvbnRhaW5lclxuICAgIGNvbnN0IGNvbnRhaW5lciA9XG4gICAgICBzaG91bGRCaW5kIHx8IHBhcmVudENlbnRlclBvc2l0aW9uXG4gICAgICAgID8gZ2V0RWxlbWVudENvbnRhaW5pbmdQb3NpdGlvbihcbiAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICAgIHNjZW5lWSxcbiAgICAgICAgICAgIFwidGV4dFwiLFxuICAgICAgICAgIClcbiAgICAgICAgOiBudWxsO1xuXG4gICAgbGV0IGV4aXN0aW5nVGV4dEVsZW1lbnQgPSB0aGlzLmdldFRleHRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSk7XG5cbiAgICAvLyBjb25zaWRlciBib3VuZGVkIHRleHQgZWxlbWVudCBpZiBjb250YWluZXIgcHJlc2VudFxuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGNvbnN0IGJvdW5kVGV4dEVsZW1lbnRJZCA9IGdldEJvdW5kVGV4dEVsZW1lbnRJZChjb250YWluZXIpO1xuICAgICAgaWYgKGJvdW5kVGV4dEVsZW1lbnRJZCkge1xuICAgICAgICBleGlzdGluZ1RleHRFbGVtZW50ID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50KFxuICAgICAgICAgIGJvdW5kVGV4dEVsZW1lbnRJZCxcbiAgICAgICAgKSBhcyBFeGNhbGlkcmF3VGV4dEVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghZXhpc3RpbmdUZXh0RWxlbWVudCAmJiBjb250YWluZXIpIHtcbiAgICAgIGNvbnN0IGZvbnRTdHJpbmcgPSB7XG4gICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgIGZvbnRGYW1pbHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Gb250RmFtaWx5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1pbldpZHRoID0gZ2V0QXBwcm94TWluTGluZVdpZHRoKGdldEZvbnRTdHJpbmcoZm9udFN0cmluZykpO1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gZ2V0QXBwcm94TWluTGluZUhlaWdodChnZXRGb250U3RyaW5nKGZvbnRTdHJpbmcpKTtcbiAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KGNvbnRhaW5lci5oZWlnaHQsIG1pbkhlaWdodCk7XG4gICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KGNvbnRhaW5lci53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBuZXdIZWlnaHQsIHdpZHRoOiBuZXdXaWR0aCB9KTtcbiAgICAgIHNjZW5lWCA9IGNvbnRhaW5lci54ICsgbmV3V2lkdGggLyAyO1xuICAgICAgc2NlbmVZID0gY29udGFpbmVyLnkgKyBuZXdIZWlnaHQgLyAyO1xuICAgICAgaWYgKHBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIHBhcmVudENlbnRlclBvc2l0aW9uID0gdGhpcy5nZXRUZXh0V3lzaXd5Z1NuYXBwZWRUb0NlbnRlclBvc2l0aW9uKFxuICAgICAgICAgIHNjZW5lWCxcbiAgICAgICAgICBzY2VuZVksXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gZXhpc3RpbmdUZXh0RWxlbWVudFxuICAgICAgPyBleGlzdGluZ1RleHRFbGVtZW50XG4gICAgICA6IG5ld1RleHRFbGVtZW50KHtcbiAgICAgICAgICB4OiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBwYXJlbnRDZW50ZXJQb3NpdGlvbi5lbGVtZW50Q2VudGVyWFxuICAgICAgICAgICAgOiBzY2VuZVgsXG4gICAgICAgICAgeTogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gcGFyZW50Q2VudGVyUG9zaXRpb24uZWxlbWVudENlbnRlcllcbiAgICAgICAgICAgIDogc2NlbmVZLFxuICAgICAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgICB0ZXh0OiBcIlwiLFxuICAgICAgICAgIGZvbnRTaXplOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRm9udFNpemUsXG4gICAgICAgICAgZm9udEZhbWlseTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZvbnRGYW1pbHksXG4gICAgICAgICAgdGV4dEFsaWduOiBwYXJlbnRDZW50ZXJQb3NpdGlvblxuICAgICAgICAgICAgPyBcImNlbnRlclwiXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1UZXh0QWxpZ24sXG4gICAgICAgICAgdmVydGljYWxBbGlnbjogcGFyZW50Q2VudGVyUG9zaXRpb25cbiAgICAgICAgICAgID8gXCJtaWRkbGVcIlxuICAgICAgICAgICAgOiBERUZBVUxUX1ZFUlRJQ0FMX0FMSUdOLFxuICAgICAgICAgIGNvbnRhaW5lcklkOiBjb250YWluZXI/LmlkID8/IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHsgZWRpdGluZ0VsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgICBpZiAoZXhpc3RpbmdUZXh0RWxlbWVudCkge1xuICAgICAgLy8gaWYgdGV4dCBlbGVtZW50IGlzIG5vIGxvbmdlciBjZW50ZXJlZCB0byBhIGNvbnRhaW5lciwgcmVzZXRcbiAgICAgIC8vIHZlcnRpY2FsQWxpZ24gdG8gZGVmYXVsdCBiZWNhdXNlIGl0J3MgY3VycmVudGx5IGludGVybmFsLW9ubHlcbiAgICAgIGlmICghcGFyZW50Q2VudGVyUG9zaXRpb24gfHwgZWxlbWVudC50ZXh0QWxpZ24gIT09IFwiY2VudGVyXCIpIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7IHZlcnRpY2FsQWxpZ246IERFRkFVTFRfVkVSVElDQUxfQUxJR04gfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBjYXNlOiBjcmVhdGluZyBuZXcgdGV4dCBub3QgY2VudGVyZWQgdG8gcGFyZW50IGVsZW1lbmVudCDihpIgb2Zmc2V0IFlcbiAgICAgIC8vIHNvIHRoYXQgdGhlIHRleHQgaXMgY2VudGVyZWQgdG8gY3Vyc29yIHBvc2l0aW9uXG4gICAgICBpZiAoIXBhcmVudENlbnRlclBvc2l0aW9uKSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZWxlbWVudCwge1xuICAgICAgICAgIHk6IGVsZW1lbnQueSAtIGVsZW1lbnQuYmFzZWxpbmUgLyAyLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGVkaXRpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgIH0pO1xuXG4gICAgdGhpcy5oYW5kbGVUZXh0V3lzaXd5ZyhlbGVtZW50LCB7XG4gICAgICBpc0V4aXN0aW5nRWxlbWVudDogISFleGlzdGluZ1RleHRFbGVtZW50LFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzRG91YmxlQ2xpY2sgPSAoXG4gICAgZXZlbnQ6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApID0+IHtcbiAgICAvLyBjYXNlOiBkb3VibGUtY2xpY2tpbmcgd2l0aCBhcnJvdy9saW5lIHRvb2wgc2VsZWN0ZWQgd291bGQgYm90aCBjcmVhdGVcbiAgICAvLyB0ZXh0IGFuZCBlbnRlciBtdWx0aUVsZW1lbnQgbW9kZVxuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyB3ZSBzaG91bGQgb25seSBiZSBhYmxlIHRvIGRvdWJsZSBjbGljayB3aGVuIG1vZGUgaXMgc2VsZWN0aW9uXG4gICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHxcbiAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudC5lbGVtZW50SWQgIT09IHNlbGVjdGVkRWxlbWVudHNbMF0uaWRcbiAgICAgICkge1xuICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGVkaXRpbmdMaW5lYXJFbGVtZW50OiBuZXcgTGluZWFyRWxlbWVudEVkaXRvcihcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHNbMF0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLFxuICAgICAgICAgICksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcblxuICAgIGxldCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICBldmVudCxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcblxuICAgIGNvbnN0IHNlbGVjdGVkR3JvdXBJZHMgPSBnZXRTZWxlY3RlZEdyb3VwSWRzKHRoaXMuc3RhdGUpO1xuXG4gICAgaWYgKHNlbGVjdGVkR3JvdXBJZHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaGl0RWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oc2NlbmVYLCBzY2VuZVkpO1xuXG4gICAgICBjb25zdCBzZWxlY3RlZEdyb3VwSWQgPVxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgIGdldFNlbGVjdGVkR3JvdXBJZEZvckVsZW1lbnQoaGl0RWxlbWVudCwgdGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwSWRzKTtcblxuICAgICAgaWYgKHNlbGVjdGVkR3JvdXBJZCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogc2VsZWN0ZWRHcm91cElkLFxuICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2hpdEVsZW1lbnQhLmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICBpZiAoIWV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmICF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG4gICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50ID0gc2VsZWN0ZWRFbGVtZW50c1swXTtcbiAgICAgICAgY29uc3QgY2FuQmluZFRleHQgPSBoYXNCb3VuZFRleHRFbGVtZW50KHNlbGVjdGVkRWxlbWVudCk7XG4gICAgICAgIGlmIChjYW5CaW5kVGV4dCkge1xuICAgICAgICAgIHNjZW5lWCA9IHNlbGVjdGVkRWxlbWVudC54ICsgc2VsZWN0ZWRFbGVtZW50LndpZHRoIC8gMjtcbiAgICAgICAgICBzY2VuZVkgPSBzZWxlY3RlZEVsZW1lbnQueSArIHNlbGVjdGVkRWxlbWVudC5oZWlnaHQgLyAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0VGV4dEVkaXRpbmcoe1xuICAgICAgICBzY2VuZVgsXG4gICAgICAgIHNjZW5lWSxcbiAgICAgICAgc2hvdWxkQmluZDogZmFsc2UsXG4gICAgICAgIGluc2VydEF0UGFyZW50Q2VudGVyOiAhZXZlbnQuYWx0S2V5LFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzUG9pbnRlck1vdmUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2F2ZVBvaW50ZXIoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgdGhpcy5zdGF0ZS5jdXJzb3JCdXR0b24pO1xuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuaGFzKGV2ZW50LnBvaW50ZXJJZCkpIHtcbiAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2V0KGV2ZW50LnBvaW50ZXJJZCwge1xuICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbFNjYWxlID0gZ2VzdHVyZS5pbml0aWFsU2NhbGU7XG4gICAgaWYgKFxuICAgICAgZ2VzdHVyZS5wb2ludGVycy5zaXplID09PSAyICYmXG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgJiZcbiAgICAgIGluaXRpYWxTY2FsZSAmJlxuICAgICAgZ2VzdHVyZS5pbml0aWFsRGlzdGFuY2VcbiAgICApIHtcbiAgICAgIGNvbnN0IGNlbnRlciA9IGdldENlbnRlcihnZXN0dXJlLnBvaW50ZXJzKTtcbiAgICAgIGNvbnN0IGRlbHRhWCA9IGNlbnRlci54IC0gZ2VzdHVyZS5sYXN0Q2VudGVyLng7XG4gICAgICBjb25zdCBkZWx0YVkgPSBjZW50ZXIueSAtIGdlc3R1cmUubGFzdENlbnRlci55O1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gY2VudGVyO1xuXG4gICAgICBjb25zdCBkaXN0YW5jZSA9IGdldERpc3RhbmNlKEFycmF5LmZyb20oZ2VzdHVyZS5wb2ludGVycy52YWx1ZXMoKSkpO1xuICAgICAgY29uc3Qgc2NhbGVGYWN0b3IgPSBkaXN0YW5jZSAvIGdlc3R1cmUuaW5pdGlhbERpc3RhbmNlO1xuXG4gICAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIHNjcm9sbFgsIHNjcm9sbFksIG9mZnNldExlZnQsIG9mZnNldFRvcCB9KSA9PiAoe1xuICAgICAgICBzY3JvbGxYOiBzY3JvbGxYICsgZGVsdGFYIC8gem9vbS52YWx1ZSxcbiAgICAgICAgc2Nyb2xsWTogc2Nyb2xsWSArIGRlbHRhWSAvIHpvb20udmFsdWUsXG4gICAgICAgIHpvb206IGdldE5ld1pvb20oXG4gICAgICAgICAgZ2V0Tm9ybWFsaXplZFpvb20oaW5pdGlhbFNjYWxlICogc2NhbGVGYWN0b3IpLFxuICAgICAgICAgIHpvb20sXG4gICAgICAgICAgeyBsZWZ0OiBvZmZzZXRMZWZ0LCB0b3A6IG9mZnNldFRvcCB9LFxuICAgICAgICAgIGNlbnRlcixcbiAgICAgICAgKSxcbiAgICAgICAgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiB0cnVlLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5yZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXN0dXJlLmxhc3RDZW50ZXIgPVxuICAgICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9XG4gICAgICAgIGdlc3R1cmUuaW5pdGlhbFNjYWxlID1cbiAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIGlmIChpc0hvbGRpbmdTcGFjZSB8fCBpc1Bhbm5pbmcgfHwgaXNEcmFnZ2luZ1Njcm9sbEJhcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzUG9pbnRlck92ZXJTY3JvbGxCYXJzID0gaXNPdmVyU2Nyb2xsQmFycyhcbiAgICAgIGN1cnJlbnRTY3JvbGxCYXJzLFxuICAgICAgZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgIGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXRlLm9mZnNldFRvcCxcbiAgICApO1xuICAgIGNvbnN0IGlzT3ZlclNjcm9sbEJhciA9IGlzUG9pbnRlck92ZXJTY3JvbGxCYXJzLmlzT3ZlckVpdGhlcjtcbiAgICBpZiAoIXRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50ICYmICF0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgaWYgKGlzT3ZlclNjcm9sbEJhcikge1xuICAgICAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2NlbmVQb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKGV2ZW50LCB0aGlzLnN0YXRlKTtcbiAgICBjb25zdCB7IHg6IHNjZW5lUG9pbnRlclgsIHk6IHNjZW5lUG9pbnRlclkgfSA9IHNjZW5lUG9pbnRlcjtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgJiZcbiAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmlzRHJhZ2dpbmdcbiAgICApIHtcbiAgICAgIGNvbnN0IGVkaXRpbmdMaW5lYXJFbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyTW92ZShcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHNjZW5lUG9pbnRlclgsXG4gICAgICAgIHNjZW5lUG9pbnRlclksXG4gICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICApO1xuICAgICAgaWYgKGVkaXRpbmdMaW5lYXJFbGVtZW50ICE9PSB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0aW5nTGluZWFyRWxlbWVudCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlZGl0aW5nTGluZWFyRWxlbWVudC5sYXN0VW5jb21taXR0ZWRQb2ludCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0JpbmRpbmdFbGVtZW50VHlwZSh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKSkge1xuICAgICAgLy8gSG92ZXJpbmcgd2l0aCBhIHNlbGVjdGVkIHRvb2wgb3IgY3JlYXRpbmcgbmV3IGxpbmVhciBlbGVtZW50IHZpYSBjbGlja1xuICAgICAgLy8gYW5kIHBvaW50XG4gICAgICBjb25zdCB7IGRyYWdnaW5nRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGlmIChpc0JpbmRpbmdFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgW3NjZW5lUG9pbnRlcl0sXG4gICAgICAgICAgdGhpcy5zdGF0ZS5zdGFydEJvdW5kRWxlbWVudCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0F0Q3Vyc29yKHNjZW5lUG9pbnRlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUubXVsdGlFbGVtZW50KSB7XG4gICAgICBjb25zdCB7IG11bHRpRWxlbWVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IHsgeDogcngsIHk6IHJ5IH0gPSBtdWx0aUVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IHsgcG9pbnRzLCBsYXN0Q29tbWl0dGVkUG9pbnQgfSA9IG11bHRpRWxlbWVudDtcbiAgICAgIGNvbnN0IGxhc3RQb2ludCA9IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV07XG5cbiAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcblxuICAgICAgaWYgKGxhc3RQb2ludCA9PT0gbGFzdENvbW1pdHRlZFBvaW50KSB7XG4gICAgICAgIC8vIGlmIHdlIGhhdmVuJ3QgeWV0IGNyZWF0ZWQgYSB0ZW1wIHBvaW50IGFuZCB3ZSdyZSBiZXlvbmQgY29tbWl0LXpvbmVcbiAgICAgICAgLy8gdGhyZXNob2xkLCBhZGQgYSBwb2ludFxuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclggLSByeCxcbiAgICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICAgIGxhc3RQb2ludFswXSxcbiAgICAgICAgICAgIGxhc3RQb2ludFsxXSxcbiAgICAgICAgICApID49IExJTkVfQ09ORklSTV9USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICAgIHBvaW50czogWy4uLnBvaW50cywgW3NjZW5lUG9pbnRlclggLSByeCwgc2NlbmVQb2ludGVyWSAtIHJ5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBDVVJTT1JfVFlQRS5QT0lOVEVSKTtcbiAgICAgICAgICAvLyBpbiB0aGlzIGJyYW5jaCwgd2UncmUgaW5zaWRlIHRoZSBjb21taXQgem9uZSwgYW5kIG5vIHVuY29tbWl0dGVkXG4gICAgICAgICAgLy8gcG9pbnQgZXhpc3RzLiBUaHVzIGRvIG5vdGhpbmcgKGRvbid0IGFkZC9yZW1vdmUgcG9pbnRzKS5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgcG9pbnRzLmxlbmd0aCA+IDIgJiZcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50ICYmXG4gICAgICAgIGRpc3RhbmNlMmQoXG4gICAgICAgICAgc2NlbmVQb2ludGVyWCAtIHJ4LFxuICAgICAgICAgIHNjZW5lUG9pbnRlclkgLSByeSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMF0sXG4gICAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50WzFdLFxuICAgICAgICApIDwgTElORV9DT05GSVJNX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBwb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc1BhdGhBTG9vcChwb2ludHMsIHRoaXMuc3RhdGUuem9vbS52YWx1ZSkpIHtcbiAgICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLlBPSU5URVIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSBsYXN0IHVuY29tbWl0dGVkIHBvaW50XG4gICAgICAgIG11dGF0ZUVsZW1lbnQobXVsdGlFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbXG4gICAgICAgICAgICAuLi5wb2ludHMuc2xpY2UoMCwgLTEpLFxuICAgICAgICAgICAgW3NjZW5lUG9pbnRlclggLSByeCwgc2NlbmVQb2ludGVyWSAtIHJ5XSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhc0Rlc2VsZWN0ZWRCdXR0b24gPSBCb29sZWFuKGV2ZW50LmJ1dHRvbnMpO1xuICAgIGlmIChcbiAgICAgIGhhc0Rlc2VsZWN0ZWRCdXR0b24gfHxcbiAgICAgICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlICE9PSBcInNlbGVjdGlvblwiICYmXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgIT09IFwidGV4dFwiKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgIGlmIChcbiAgICAgIHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAhaXNPdmVyU2Nyb2xsQmFyICYmXG4gICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudFxuICAgICkge1xuICAgICAgY29uc3QgZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlID0gZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICBlbGVtZW50cyxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgc2NlbmVQb2ludGVyWCxcbiAgICAgICAgc2NlbmVQb2ludGVyWSxcbiAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICk7XG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSAmJlxuICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAxICYmICFpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybUhhbmRsZVR5cGUgPSBnZXRUcmFuc2Zvcm1IYW5kbGVUeXBlRnJvbUNvb3JkcyhcbiAgICAgICAgZ2V0Q29tbW9uQm91bmRzKHNlbGVjdGVkRWxlbWVudHMpLFxuICAgICAgICBzY2VuZVBvaW50ZXJYLFxuICAgICAgICBzY2VuZVBvaW50ZXJZLFxuICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgKTtcbiAgICAgIGlmICh0cmFuc2Zvcm1IYW5kbGVUeXBlKSB7XG4gICAgICAgIHNldEN1cnNvcihcbiAgICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgICBnZXRDdXJzb3JGb3JSZXNpemluZ0VsZW1lbnQoe1xuICAgICAgICAgICAgdHJhbnNmb3JtSGFuZGxlVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhpdEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnRBdFBvc2l0aW9uKFxuICAgICAgc2NlbmVQb2ludGVyLngsXG4gICAgICBzY2VuZVBvaW50ZXIueSxcbiAgICApO1xuICAgIGlmICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcInRleHRcIikge1xuICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgaXNUZXh0RWxlbWVudChoaXRFbGVtZW50KSA/IENVUlNPUl9UWVBFLlRFWFQgOiBDVVJTT1JfVFlQRS5DUk9TU0hBSVIsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgfSBlbHNlIGlmIChpc092ZXJTY3JvbGxCYXIpIHtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuQVVUTyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5nZXRFbGVtZW50KFxuICAgICAgICB0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50LmVsZW1lbnRJZCxcbiAgICAgICk7XG4gICAgICBpZiAoXG4gICAgICAgIGVsZW1lbnQgJiZcbiAgICAgICAgaXNIaXR0aW5nRWxlbWVudE5vdENvbnNpZGVyaW5nQm91bmRpbmdCb3goZWxlbWVudCwgdGhpcy5zdGF0ZSwgW1xuICAgICAgICAgIHNjZW5lUG9pbnRlci54LFxuICAgICAgICAgIHNjZW5lUG9pbnRlci55LFxuICAgICAgICBdKVxuICAgICAgKSB7XG4gICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuTU9WRSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAvLyBpZiB1c2luZyBjbWQvY3RybCwgd2UncmUgbm90IGRyYWdnaW5nXG4gICAgICAhZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiZcbiAgICAgIChoaXRFbGVtZW50IHx8XG4gICAgICAgIHRoaXMuaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgc2NlbmVQb2ludGVyLFxuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICkpXG4gICAgKSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLk1PVkUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkFVVE8pO1xuICAgIH1cbiAgfTtcblxuICAvLyBzZXQgdG91Y2ggbW92aW5nIGZvciBtb2JpbGUgY29udGV4dCBtZW51XG4gIHByaXZhdGUgaGFuZGxlVG91Y2hNb3ZlID0gKGV2ZW50OiBSZWFjdC5Ub3VjaEV2ZW50PEhUTUxDYW52YXNFbGVtZW50PikgPT4ge1xuICAgIGludmFsaWRhdGVDb250ZXh0TWVudSA9IHRydWU7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgLy8gcmVtb3ZlIGFueSBhY3RpdmUgc2VsZWN0aW9uIHdoZW4gd2Ugc3RhcnQgdG8gaW50ZXJhY3Qgd2l0aCBjYW52YXNcbiAgICAvLyAobWFpbmx5LCB3ZSBjYXJlIGFib3V0IHJlbW92aW5nIHNlbGVjdGlvbiBvdXRzaWRlIHRoZSBjb21wb25lbnQgd2hpY2hcbiAgICAvLyAgd291bGQgcHJldmVudCBvdXIgY29weSBoYW5kbGluZyBvdGhlcndpc2UpXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKHNlbGVjdGlvbj8uYW5jaG9yTm9kZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIH1cblxuICAgIHRoaXMubWF5YmVPcGVuQ29udGV4dE1lbnVBZnRlclBvaW50ZXJEb3duT25Ub3VjaERldmljZXMoZXZlbnQpO1xuICAgIHRoaXMubWF5YmVDbGVhbnVwQWZ0ZXJNaXNzaW5nUG9pbnRlclVwKGV2ZW50KTtcblxuICAgIGlmIChpc1Bhbm5pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGxhc3RQb2ludGVyRG93bldpdGg6IGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgY3Vyc29yQnV0dG9uOiBcImRvd25cIixcbiAgICB9KTtcbiAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwiZG93blwiKTtcblxuICAgIGlmICh0aGlzLmhhbmRsZUNhbnZhc1BhblVzaW5nV2hlZWxPclNwYWNlRHJhZyhldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBsZWZ0IG1vdXNlIGJ1dHRvbiBvciB0b3VjaFxuICAgIGlmIChcbiAgICAgIGV2ZW50LmJ1dHRvbiAhPT0gUE9JTlRFUl9CVVRUT04uTUFJTiAmJlxuICAgICAgZXZlbnQuYnV0dG9uICE9PSBQT0lOVEVSX0JVVFRPTi5UT1VDSFxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlR2VzdHVyZU9uUG9pbnRlckRvd24oZXZlbnQpO1xuXG4gICAgLy8gZG9uJ3Qgc2VsZWN0IHdoaWxlIHBhbm5pbmdcbiAgICBpZiAoZ2VzdHVyZS5wb2ludGVycy5zaXplID4gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFN0YXRlIGZvciB0aGUgZHVyYXRpb24gb2YgYSBwb2ludGVyIGludGVyYWN0aW9uLCB3aGljaCBzdGFydHMgd2l0aCBhXG4gICAgLy8gcG9pbnRlckRvd24gZXZlbnQsIGVuZHMgd2l0aCBhIHBvaW50ZXJVcCBldmVudCAob3IgYW5vdGhlciBwb2ludGVyRG93bilcbiAgICBjb25zdCBwb2ludGVyRG93blN0YXRlID0gdGhpcy5pbml0aWFsUG9pbnRlckRvd25TdGF0ZShldmVudCk7XG5cbiAgICBpZiAodGhpcy5oYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihldmVudCwgcG9pbnRlckRvd25TdGF0ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNsZWFyU2VsZWN0aW9uSWZOb3RVc2luZ1NlbGVjdGlvbigpO1xuICAgIHRoaXMudXBkYXRlQmluZGluZ0VuYWJsZWRPblBvaW50ZXJNb3ZlKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsZVNlbGVjdGlvbk9uUG9pbnRlckRvd24oZXZlbnQsIHBvaW50ZXJEb3duU3RhdGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwidGV4dFwiKSB7XG4gICAgICB0aGlzLmhhbmRsZVRleHRPblBvaW50ZXJEb3duKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiIHx8XG4gICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImxpbmVcIlxuICAgICkge1xuICAgICAgdGhpcy5oYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93bihcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICAvLyByZXNldCBpbWFnZSBwcmV2aWV3IG9uIHBvaW50ZXJkb3duXG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIENVUlNPUl9UWVBFLkNST1NTSEFJUik7XG5cbiAgICAgIGlmICghdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGRyYWdnaW5nRWxlbWVudDogdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogdGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50LFxuICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50OiBudWxsLFxuICAgICAgICBtdWx0aUVsZW1lbnQ6IG51bGwsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgICAgbXV0YXRlRWxlbWVudCh0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQsIHtcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5lbGVtZW50VHlwZSA9PT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICB0aGlzLmhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIGV2ZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jcmVhdGVHZW5lcmljRWxlbWVudE9uUG9pbnRlckRvd24oXG4gICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPVxuICAgICAgdGhpcy5vblBvaW50ZXJNb3ZlRnJvbVBvaW50ZXJEb3duSGFuZGxlcihwb2ludGVyRG93blN0YXRlKTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID1cbiAgICAgIHRoaXMub25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgY29uc3Qgb25LZXlEb3duID0gdGhpcy5vbktleURvd25Gcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuICAgIGNvbnN0IG9uS2V5VXAgPSB0aGlzLm9uS2V5VXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKHBvaW50ZXJEb3duU3RhdGUpO1xuXG4gICAgbGFzdFBvaW50ZXJVcCA9IG9uUG9pbnRlclVwO1xuXG4gICAgaWYgKCF0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULktFWURPV04sIG9uS2V5RG93bik7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5LRVlVUCwgb25LZXlVcCk7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSA9IG9uUG9pbnRlck1vdmU7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uVXAgPSBvblBvaW50ZXJVcDtcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCA9IG9uS2V5VXA7XG4gICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uS2V5RG93biA9IG9uS2V5RG93bjtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZU9wZW5Db250ZXh0TWVudUFmdGVyUG9pbnRlckRvd25PblRvdWNoRGV2aWNlcyA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKTogdm9pZCA9PiB7XG4gICAgLy8gZGVhbCB3aXRoIG9wZW5pbmcgY29udGV4dCBtZW51IG9uIHRvdWNoIGRldmljZXNcbiAgICBpZiAoZXZlbnQucG9pbnRlclR5cGUgPT09IFwidG91Y2hcIikge1xuICAgICAgaW52YWxpZGF0ZUNvbnRleHRNZW51ID0gZmFsc2U7XG5cbiAgICAgIGlmICh0b3VjaFRpbWVvdXQpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBhbHJlYWR5IGEgdG91Y2hUaW1lb3V0LCB0aGlzIG1lYW5zIHRoYXQgdGhlcmUncyBhbm90aGVyXG4gICAgICAgIC8vIHRvdWNoIGRvd24gYW5kIHdlIGFyZSBkb2luZyBhbm90aGVyIHRvdWNoLCBzbyB3ZSBzaG91bGRuJ3Qgb3BlbiB0aGVcbiAgICAgICAgLy8gY29udGV4dCBtZW51LlxuICAgICAgICBpbnZhbGlkYXRlQ29udGV4dE1lbnUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb3BlbiB0aGUgY29udGV4dCBtZW51IHdpdGggdGhlIGZpcnN0IHRvdWNoJ3MgY2xpZW50WCBhbmQgY2xpZW50WVxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggaXMgbm90IG1vdmluZ1xuICAgICAgICB0b3VjaFRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdG91Y2hUaW1lb3V0ID0gMDtcbiAgICAgICAgICBpZiAoIWludmFsaWRhdGVDb250ZXh0TWVudSkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDYW52YXNDb250ZXh0TWVudShldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBUT1VDSF9DVFhfTUVOVV9USU1FT1VUKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBtYXliZUNsZWFudXBBZnRlck1pc3NpbmdQb2ludGVyVXAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IHZvaWQge1xuICAgIGlmIChsYXN0UG9pbnRlclVwICE9PSBudWxsKSB7XG4gICAgICAvLyBVbmZvcnR1bmF0ZWx5LCBzb21ldGltZXMgd2UgZG9uJ3QgZ2V0IGEgcG9pbnRlcnVwIGFmdGVyIGEgcG9pbnRlcmRvd24sXG4gICAgICAvLyB0aGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbnRleHR1YWwgbWVudSBvciBhbGVydCBpcyB0cmlnZ2VyZWQuIEluIG9yZGVyIHRvIGF2b2lkXG4gICAgICAvLyBiZWluZyBpbiBhIHdlaXJkIHN0YXRlLCB3ZSBjbGVhbiB1cCBvbiB0aGUgbmV4dCBwb2ludGVyZG93blxuICAgICAgbGFzdFBvaW50ZXJVcChldmVudCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBldmVudCBpcyBhIHBhbm5pbmdcbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNQYW5Vc2luZ1doZWVsT3JTcGFjZURyYWcgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICk6IGJvb2xlYW4gPT4ge1xuICAgIGlmIChcbiAgICAgICEoXG4gICAgICAgIGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMCAmJlxuICAgICAgICAoZXZlbnQuYnV0dG9uID09PSBQT0lOVEVSX0JVVFRPTi5XSEVFTCB8fFxuICAgICAgICAgIChldmVudC5idXR0b24gPT09IFBPSU5URVJfQlVUVE9OLk1BSU4gJiYgaXNIb2xkaW5nU3BhY2UpIHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpXG4gICAgICApXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlzUGFubmluZyA9IHRydWU7XG5cbiAgICBsZXQgbmV4dFBhc3RlUHJldmVudGVkID0gZmFsc2U7XG4gICAgY29uc3QgaXNMaW51eCA9IC9MaW51eC8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtKTtcblxuICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQkJJTkcpO1xuICAgIGxldCB7IGNsaWVudFg6IGxhc3RYLCBjbGllbnRZOiBsYXN0WSB9ID0gZXZlbnQ7XG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IHdpdGhCYXRjaGVkVXBkYXRlcygoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgZGVsdGFYID0gbGFzdFggLSBldmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgZGVsdGFZID0gbGFzdFkgLSBldmVudC5jbGllbnRZO1xuICAgICAgbGFzdFggPSBldmVudC5jbGllbnRYO1xuICAgICAgbGFzdFkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgICAvKlxuICAgICAgICogUHJldmVudCBwYXN0ZSBldmVudCBpZiB3ZSBtb3ZlIHdoaWxlIG1pZGRsZSBjbGlja2luZyBvbiBMaW51eC5cbiAgICAgICAqIFNlZSBpc3N1ZSAjMTM4My5cbiAgICAgICAqL1xuICAgICAgaWYgKFxuICAgICAgICBpc0xpbnV4ICYmXG4gICAgICAgICFuZXh0UGFzdGVQcmV2ZW50ZWQgJiZcbiAgICAgICAgKE1hdGguYWJzKGRlbHRhWCkgPiAxIHx8IE1hdGguYWJzKGRlbHRhWSkgPiAxKVxuICAgICAgKSB7XG4gICAgICAgIG5leHRQYXN0ZVByZXZlbnRlZCA9IHRydWU7XG5cbiAgICAgICAgLyogUHJldmVudCB0aGUgbmV4dCBwYXN0ZSBldmVudCAqL1xuICAgICAgICBjb25zdCBwcmV2ZW50TmV4dFBhc3RlID0gKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcihFVkVOVC5QQVNURSwgcHJldmVudE5leHRQYXN0ZSk7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLypcbiAgICAgICAgICogUmVlbmFibGUgbmV4dCBwYXN0ZSBpbiBjYXNlIG9mIGRpc2FibGVkIG1pZGRsZSBjbGljayBwYXN0ZSBmb3JcbiAgICAgICAgICogYW55IHJlYXNvbjpcbiAgICAgICAgICogLSByaWd0aCBjbGljayBwYXN0ZVxuICAgICAgICAgKiAtIGVtcHR5IGNsaXBib2FyZFxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZW5hYmxlTmV4dFBhc3RlID0gKCkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBBU1RFLCBwcmV2ZW50TmV4dFBhc3RlKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIGVuYWJsZU5leHRQYXN0ZSk7XG4gICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUEFTVEUsIHByZXZlbnROZXh0UGFzdGUpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5QT0lOVEVSX1VQLCBlbmFibGVOZXh0UGFzdGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2Nyb2xsWDogdGhpcy5zdGF0ZS5zY3JvbGxYIC0gZGVsdGFYIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlLFxuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFkgLSBkZWx0YVkgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBjb25zdCB0ZWFyZG93biA9IHdpdGhCYXRjaGVkVXBkYXRlcyhcbiAgICAgIChsYXN0UG9pbnRlclVwID0gKCkgPT4ge1xuICAgICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgICAgaXNQYW5uaW5nID0gZmFsc2U7XG4gICAgICAgIGlmICghaXNIb2xkaW5nU3BhY2UpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0ZS52aWV3TW9kZUVuYWJsZWQpIHtcbiAgICAgICAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuR1JBQik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldEN1cnNvckZvclNoYXBlKHRoaXMuY2FudmFzLCB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY3Vyc29yQnV0dG9uOiBcInVwXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNhdmVQb2ludGVyKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFksIFwidXBcIik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuQkxVUiwgdGVhcmRvd24pO1xuICAgICAgfSksXG4gICAgKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFVkVOVC5CTFVSLCB0ZWFyZG93bik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlLCB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgIH0pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIHRlYXJkb3duKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUdlc3R1cmVPblBvaW50ZXJEb3duKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiB2b2lkIHtcbiAgICBnZXN0dXJlLnBvaW50ZXJzLnNldChldmVudC5wb2ludGVySWQsIHtcbiAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgIH0pO1xuXG4gICAgaWYgKGdlc3R1cmUucG9pbnRlcnMuc2l6ZSA9PT0gMikge1xuICAgICAgZ2VzdHVyZS5sYXN0Q2VudGVyID0gZ2V0Q2VudGVyKGdlc3R1cmUucG9pbnRlcnMpO1xuICAgICAgZ2VzdHVyZS5pbml0aWFsU2NhbGUgPSB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgICBnZXN0dXJlLmluaXRpYWxEaXN0YW5jZSA9IGdldERpc3RhbmNlKFxuICAgICAgICBBcnJheS5mcm9tKGdlc3R1cmUucG9pbnRlcnMudmFsdWVzKCkpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxQb2ludGVyRG93blN0YXRlKFxuICAgIGV2ZW50OiBSZWFjdC5Qb2ludGVyRXZlbnQ8SFRNTENhbnZhc0VsZW1lbnQ+LFxuICApOiBQb2ludGVyRG93blN0YXRlIHtcbiAgICBjb25zdCBvcmlnaW4gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgdGhpcy5zdGF0ZSxcbiAgICApO1xuICAgIGNvbnN0IFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXSA9IGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBvcmlnaW4sXG4gICAgICB3aXRoQ21kT3JDdHJsOiBldmVudFtLRVlTLkNUUkxfT1JfQ01EXSxcbiAgICAgIG9yaWdpbkluR3JpZDogdHVwbGVUb0Nvb3JzKFxuICAgICAgICBnZXRHcmlkUG9pbnQob3JpZ2luLngsIG9yaWdpbi55LCB0aGlzLnN0YXRlLmdyaWRTaXplKSxcbiAgICAgICksXG4gICAgICBzY3JvbGxiYXJzOiBpc092ZXJTY3JvbGxCYXJzKFxuICAgICAgICBjdXJyZW50U2Nyb2xsQmFycyxcbiAgICAgICAgZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhdGUub2Zmc2V0VG9wLFxuICAgICAgKSxcbiAgICAgIC8vIHdlIG5lZWQgdG8gZHVwbGljYXRlIGJlY2F1c2Ugd2UnbGwgYmUgdXBkYXRpbmcgdGhpcyBzdGF0ZVxuICAgICAgbGFzdENvb3JkczogeyAuLi5vcmlnaW4gfSxcbiAgICAgIG9yaWdpbmFsRWxlbWVudHM6IHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKS5yZWR1Y2UoKGFjYywgZWxlbWVudCkgPT4ge1xuICAgICAgICBhY2Muc2V0KGVsZW1lbnQuaWQsIGRlZXBDb3B5RWxlbWVudChlbGVtZW50KSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCBuZXcgTWFwKCkgYXMgUG9pbnRlckRvd25TdGF0ZVtcIm9yaWdpbmFsRWxlbWVudHNcIl0pLFxuICAgICAgcmVzaXplOiB7XG4gICAgICAgIGhhbmRsZVR5cGU6IGZhbHNlLFxuICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgYXJyb3dEaXJlY3Rpb246IFwib3JpZ2luXCIsXG4gICAgICAgIGNlbnRlcjogeyB4OiAobWF4WCArIG1pblgpIC8gMiwgeTogKG1heFkgKyBtaW5ZKSAvIDIgfSxcbiAgICAgIH0sXG4gICAgICBoaXQ6IHtcbiAgICAgICAgZWxlbWVudDogbnVsbCxcbiAgICAgICAgYWxsSGl0RWxlbWVudHM6IFtdLFxuICAgICAgICB3YXNBZGRlZFRvU2VsZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgaGFzQmVlbkR1cGxpY2F0ZWQ6IGZhbHNlLFxuICAgICAgICBoYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50czpcbiAgICAgICAgICB0aGlzLmlzSGl0dGluZ0NvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cyxcbiAgICAgICAgICApLFxuICAgICAgICBoYXNIaXRFbGVtZW50SW5zaWRlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBkcmFnOiB7XG4gICAgICAgIGhhc09jY3VycmVkOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGV2ZW50TGlzdGVuZXJzOiB7XG4gICAgICAgIG9uTW92ZTogbnVsbCxcbiAgICAgICAgb25VcDogbnVsbCxcbiAgICAgICAgb25LZXlVcDogbnVsbCxcbiAgICAgICAgb25LZXlEb3duOiBudWxsLFxuICAgICAgfSxcbiAgICAgIGJveFNlbGVjdGlvbjoge1xuICAgICAgICBoYXNPY2N1cnJlZDogZmFsc2UsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIGV2ZW50IGlzIGEgZHJhZ2dpbmcgYSBzY3JvbGxiYXJcbiAgcHJpdmF0ZSBoYW5kbGVEcmFnZ2luZ1Njcm9sbEJhcihcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoXG4gICAgICAhKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJFaXRoZXIgJiYgIXRoaXMuc3RhdGUubXVsdGlFbGVtZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gdHJ1ZTtcbiAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueCA9IGV2ZW50LmNsaWVudFg7XG4gICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IG9uUG9pbnRlck1vdmUgPSB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhldmVudCwgcG9pbnRlckRvd25TdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvblBvaW50ZXJVcCA9IHdpdGhCYXRjaGVkVXBkYXRlcygoKSA9PiB7XG4gICAgICBpc0RyYWdnaW5nU2Nyb2xsQmFyID0gZmFsc2U7XG4gICAgICBzZXRDdXJzb3JGb3JTaGFwZSh0aGlzLmNhbnZhcywgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSk7XG4gICAgICBsYXN0UG9pbnRlclVwID0gbnVsbDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zYXZlUG9pbnRlcihldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBcInVwXCIpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9NT1ZFLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfVVAsIG9uUG9pbnRlclVwKTtcbiAgICB9KTtcblxuICAgIGxhc3RQb2ludGVyVXAgPSBvblBvaW50ZXJVcDtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlBPSU5URVJfTU9WRSwgb25Qb2ludGVyTW92ZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuUE9JTlRFUl9VUCwgb25Qb2ludGVyVXApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNlbGVjdGlvbklmTm90VXNpbmdTZWxlY3Rpb24gPSAoKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgIT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgZWRpdGluZ0dyb3VwSWQ6IG51bGwsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIHBvaW50ZXIgZXZlbnQgaGFzIGJlZW4gY29tcGxldGVseSBoYW5kbGVkXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbk9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50cyA9IGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUpO1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoID09PSAxICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRXaXRoVHJhbnNmb3JtSGFuZGxlVHlwZSA9XG4gICAgICAgICAgZ2V0RWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlKFxuICAgICAgICAgICAgZWxlbWVudHMsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnpvb20sXG4gICAgICAgICAgICBldmVudC5wb2ludGVyVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICBpZiAoZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHJlc2l6aW5nRWxlbWVudDogZWxlbWVudFdpdGhUcmFuc2Zvcm1IYW5kbGVUeXBlLmVsZW1lbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9XG4gICAgICAgICAgICBlbGVtZW50V2l0aFRyYW5zZm9ybUhhbmRsZVR5cGUudHJhbnNmb3JtSGFuZGxlVHlwZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSA9IGdldFRyYW5zZm9ybUhhbmRsZVR5cGVGcm9tQ29vcmRzKFxuICAgICAgICAgIGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKSxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICAgICAgdGhpcy5zdGF0ZS56b29tLFxuICAgICAgICAgIGV2ZW50LnBvaW50ZXJUeXBlLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUpIHtcbiAgICAgICAgc2V0Q3Vyc29yKFxuICAgICAgICAgIHRoaXMuY2FudmFzLFxuICAgICAgICAgIGdldEN1cnNvckZvclJlc2l6aW5nRWxlbWVudCh7XG4gICAgICAgICAgICB0cmFuc2Zvcm1IYW5kbGVUeXBlOiBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5oYW5kbGVUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nID0gdHJ1ZTtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0ID0gdHVwbGVUb0Nvb3JzKFxuICAgICAgICAgIGdldFJlc2l6ZU9mZnNldFhZKFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBpc0xpbmVhckVsZW1lbnQoc2VsZWN0ZWRFbGVtZW50c1swXSkgJiZcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLnBvaW50cy5sZW5ndGggPT09IDJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuYXJyb3dEaXJlY3Rpb24gPSBnZXRSZXNpemVBcnJvd0RpcmVjdGlvbihcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmhhbmRsZVR5cGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzWzBdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgcmV0ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyRG93bihcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIChhcHBTdGF0ZSkgPT4gdGhpcy5zZXRTdGF0ZShhcHBTdGF0ZSksXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbixcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChyZXQuaGl0RWxlbWVudCkge1xuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9IHJldC5oaXRFbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmV0LmRpZEFkZFBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBoaXRFbGVtZW50IG1heSBhbHJlYWR5IGJlIHNldCBhYm92ZSwgc28gY2hlY2sgZmlyc3RcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA9XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCA/P1xuICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApO1xuXG4gICAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSA9XG4gICAgICAgICAgICBpc0hpdHRpbmdFbGVtZW50Tm90Q29uc2lkZXJpbmdCb3VuZGluZ0JveChcbiAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudCxcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgICAgW3BvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnldLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvciBvdmVybGFwcGVkIGVsZW1lbnRzIG9uZSBwb3NpdGlvbiBtYXkgaGl0XG4gICAgICAgIC8vIG11bHRpcGxlIGVsZW1lbnRzXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmFsbEhpdEVsZW1lbnRzID0gdGhpcy5nZXRFbGVtZW50c0F0UG9zaXRpb24oXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50O1xuICAgICAgICBjb25zdCBzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQgPVxuICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0LmFsbEhpdEVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+XG4gICAgICAgICAgICB0aGlzLmlzQVNlbGVjdGVkRWxlbWVudChlbGVtZW50KSxcbiAgICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGhpdEVsZW1lbnQgPT09IG51bGwgfHwgIXNvbWVIaXRFbGVtZW50SXNTZWxlY3RlZCkgJiZcbiAgICAgICAgICAhZXZlbnQuc2hpZnRLZXkgJiZcbiAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbihoaXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgW3RoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkXTogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gSWYgd2UgY2xpY2sgb24gc29tZXRoaW5nXG4gICAgICAgIH0gZWxzZSBpZiAoaGl0RWxlbWVudCAhPSBudWxsKSB7XG4gICAgICAgICAgLy8gb24gQ01EL0NUUkwsIGRyaWxsIGRvd24gdG8gaGl0IGVsZW1lbnQgcmVnYXJkbGVzcyBvZiBncm91cHMgZXRjLlxuICAgICAgICAgIGlmIChldmVudFtLRVlTLkNUUkxfT1JfQ01EXSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSkge1xuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgLi4uZWRpdEdyb3VwRm9yU2VsZWN0ZWRFbGVtZW50KHByZXZTdGF0ZSwgaGl0RWxlbWVudCksXG4gICAgICAgICAgICAgIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzOiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIC8vIG1hcmsgYXMgbm90IGNvbXBsZXRlbHkgaGFuZGxlZCBzbyBhcyB0byBhbGxvdyBkcmFnZ2luZyBldGMuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gZGVzZWxlY3QgaWYgaXRlbSBpcyBzZWxlY3RlZFxuICAgICAgICAgIC8vIGlmIHNoaWZ0IGlzIG5vdCBjbGlja2VkLCB0aGlzIHdpbGwgYWx3YXlzIHJldHVybiB0cnVlXG4gICAgICAgICAgLy8gb3RoZXJ3aXNlLCBpdCB3aWxsIHRyaWdnZXIgc2VsZWN0aW9uIGJhc2VkIG9uIGN1cnJlbnRcbiAgICAgICAgICAvLyBzdGF0ZSBvZiB0aGUgYm94XG4gICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXSkge1xuICAgICAgICAgICAgLy8gaWYgd2UgYXJlIGN1cnJlbnRseSBlZGl0aW5nIGEgZ3JvdXAsIGV4aXRpbmcgZWRpdGluZyBtb2RlIGFuZCBkZXNlbGVjdCB0aGUgZ3JvdXAuXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0dyb3VwSWQgJiZcbiAgICAgICAgICAgICAgIWlzRWxlbWVudEluR3JvdXAoaGl0RWxlbWVudCwgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgICAgIGVkaXRpbmdHcm91cElkOiBudWxsLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWRkIGhpdCBlbGVtZW50IHRvIHNlbGVjdGlvbi4gQXQgdGhpcyBwb2ludCBpZiB3ZSdyZSBub3QgaG9sZGluZ1xuICAgICAgICAgICAgLy8gU0hJRlQgdGhlIHByZXZpb3VzbHkgc2VsZWN0ZWQgZWxlbWVudChzKSB3ZXJlIGRlc2VsZWN0ZWQgYWJvdmVcbiAgICAgICAgICAgIC8vIChtYWtlIHN1cmUgeW91IHVzZSBzZXRTdGF0ZSB1cGRhdGVyIHRvIHVzZSBsYXRlc3Qgc3RhdGUpXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICFzb21lSGl0RWxlbWVudElzU2VsZWN0ZWQgJiZcbiAgICAgICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0hpdENvbW1vbkJvdW5kaW5nQm94T2ZTZWxlY3RlZEVsZW1lbnRzXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICAgICAgICBbaGl0RWxlbWVudC5pZF06IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC53YXNBZGRlZFRvU2VsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczogdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgcHJpdmF0ZSBpc0FTZWxlY3RlZEVsZW1lbnQoaGl0RWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGhpdEVsZW1lbnQgIT0gbnVsbCAmJiB0aGlzLnN0YXRlLnNlbGVjdGVkRWxlbWVudElkc1toaXRFbGVtZW50LmlkXTtcbiAgfVxuXG4gIHByaXZhdGUgaXNIaXR0aW5nQ29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMoXG4gICAgcG9pbnQ6IFJlYWRvbmx5PHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfT4sXG4gICAgc2VsZWN0ZWRFbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHNlbGVjdGVkRWxlbWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEhvdyBtYW55IHBpeGVscyBvZmYgdGhlIHNoYXBlIGJvdW5kYXJ5IHdlIHN0aWxsIGNvbnNpZGVyIGEgaGl0XG4gICAgY29uc3QgdGhyZXNob2xkID0gMTAgLyB0aGlzLnN0YXRlLnpvb20udmFsdWU7XG4gICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGdldENvbW1vbkJvdW5kcyhzZWxlY3RlZEVsZW1lbnRzKTtcbiAgICByZXR1cm4gKFxuICAgICAgcG9pbnQueCA+IHgxIC0gdGhyZXNob2xkICYmXG4gICAgICBwb2ludC54IDwgeDIgKyB0aHJlc2hvbGQgJiZcbiAgICAgIHBvaW50LnkgPiB5MSAtIHRocmVzaG9sZCAmJlxuICAgICAgcG9pbnQueSA8IHkyICsgdGhyZXNob2xkXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVGV4dE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogdm9pZCA9PiB7XG4gICAgLy8gaWYgd2UncmUgY3VycmVudGx5IHN0aWxsIGVkaXRpbmcgdGV4dCwgY2xpY2tpbmcgb3V0c2lkZVxuICAgIC8vIHNob3VsZCBvbmx5IGZpbmFsaXplIGl0LCBub3QgY3JlYXRlIGFub3RoZXIgKGlycmVzcGVjdGl2ZVxuICAgIC8vIG9mIHN0YXRlLmVsZW1lbnRMb2NrZWQpXG4gICAgaWYgKGlzVGV4dEVsZW1lbnQodGhpcy5zdGF0ZS5lZGl0aW5nRWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHNjZW5lWCA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLng7XG4gICAgbGV0IHNjZW5lWSA9IHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50QXRQb3NpdGlvbihzY2VuZVgsIHNjZW5lWSwge1xuICAgICAgaW5jbHVkZUJvdW5kVGV4dEVsZW1lbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYW5CaW5kVGV4dCA9IGhhc0JvdW5kVGV4dEVsZW1lbnQoZWxlbWVudCk7XG4gICAgaWYgKGNhbkJpbmRUZXh0KSB7XG4gICAgICBzY2VuZVggPSBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoIC8gMjtcbiAgICAgIHNjZW5lWSA9IGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgICB9XG4gICAgdGhpcy5zdGFydFRleHRFZGl0aW5nKHtcbiAgICAgIHNjZW5lWCxcbiAgICAgIHNjZW5lWSxcbiAgICAgIHNob3VsZEJpbmQ6IGZhbHNlLFxuICAgICAgaW5zZXJ0QXRQYXJlbnRDZW50ZXI6ICFldmVudC5hbHRLZXksXG4gICAgfSk7XG5cbiAgICByZXNldEN1cnNvcih0aGlzLmNhbnZhcyk7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmVsZW1lbnRMb2NrZWQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBlbGVtZW50VHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZUZyZWVEcmF3RWxlbWVudE9uUG9pbnRlckRvd24gPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICAgZWxlbWVudFR5cGU6IEV4Y2FsaWRyYXdGcmVlRHJhd0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICkgPT4ge1xuICAgIC8vIEJlZ2luIGEgbWFyayBjYXB0dXJlLiBUaGlzIGRvZXMgbm90IGhhdmUgdG8gdXBkYXRlIHN0YXRlIHlldC5cbiAgICBjb25zdCBbZ3JpZFgsIGdyaWRZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgbnVsbCxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0ZyZWVEcmF3RWxlbWVudCh7XG4gICAgICB0eXBlOiBlbGVtZW50VHlwZSxcbiAgICAgIHg6IGdyaWRYLFxuICAgICAgeTogZ3JpZFksXG4gICAgICBzdHJva2VDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZUNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgZmlsbFN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtRmlsbFN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VXaWR0aCxcbiAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICByb3VnaG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1Sb3VnaG5lc3MsXG4gICAgICBvcGFjaXR5OiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtT3BhY2l0eSxcbiAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgIHNpbXVsYXRlUHJlc3N1cmU6IGV2ZW50LnByZXNzdXJlID09PSAwLjUsXG4gICAgfSk7XG5cbiAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+ICh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgW2VsZW1lbnQuaWRdOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSkpO1xuXG4gICAgY29uc3QgcHJlc3N1cmVzID0gZWxlbWVudC5zaW11bGF0ZVByZXNzdXJlXG4gICAgICA/IGVsZW1lbnQucHJlc3N1cmVzXG4gICAgICA6IFsuLi5lbGVtZW50LnByZXNzdXJlcywgZXZlbnQucHJlc3N1cmVdO1xuXG4gICAgbXV0YXRlRWxlbWVudChlbGVtZW50LCB7XG4gICAgICBwb2ludHM6IFtbMCwgMF1dLFxuICAgICAgcHJlc3N1cmVzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYm91bmRFbGVtZW50ID0gZ2V0SG92ZXJlZEVsZW1lbnRGb3JCaW5kaW5nKFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICB0aGlzLnNjZW5lLFxuICAgICk7XG4gICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIGVsZW1lbnQsXG4gICAgXSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBkcmFnZ2luZ0VsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIHN0YXJ0Qm91bmRFbGVtZW50OiBib3VuZEVsZW1lbnQsXG4gICAgICBzdWdnZXN0ZWRCaW5kaW5nczogW10sXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBjcmVhdGVJbWFnZUVsZW1lbnQgPSAoe1xuICAgIHNjZW5lWCxcbiAgICBzY2VuZVksXG4gIH06IHtcbiAgICBzY2VuZVg6IG51bWJlcjtcbiAgICBzY2VuZVk6IG51bWJlcjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KHNjZW5lWCwgc2NlbmVZLCB0aGlzLnN0YXRlLmdyaWRTaXplKTtcblxuICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdJbWFnZUVsZW1lbnQoe1xuICAgICAgdHlwZTogXCJpbWFnZVwiLFxuICAgICAgeDogZ3JpZFgsXG4gICAgICB5OiBncmlkWSxcbiAgICAgIHN0cm9rZUNvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1CYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICBzdHJva2VXaWR0aDogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVdpZHRoLFxuICAgICAgc3Ryb2tlU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTdHlsZSxcbiAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1PcGFjaXR5LFxuICAgICAgc3Ryb2tlU2hhcnBuZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtTGluZWFyU3Ryb2tlU2hhcnBuZXNzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVMaW5lYXJFbGVtZW50T25Qb2ludGVyRG93biA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgICBlbGVtZW50VHlwZTogRXhjYWxpZHJhd0xpbmVhckVsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLnN0YXRlLm11bHRpRWxlbWVudCkge1xuICAgICAgY29uc3QgeyBtdWx0aUVsZW1lbnQgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIC8vIGZpbmFsaXplIGlmIGNvbXBsZXRpbmcgYSBsb29wXG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC50eXBlID09PSBcImxpbmVcIiAmJlxuICAgICAgICBpc1BhdGhBTG9vcChtdWx0aUVsZW1lbnQucG9pbnRzLCB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgICApIHtcbiAgICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQ6XG4gICAgICAgICAgICBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB4OiByeCwgeTogcnksIGxhc3RDb21taXR0ZWRQb2ludCB9ID0gbXVsdGlFbGVtZW50O1xuXG4gICAgICAvLyBjbGlja2luZyBpbnNpZGUgY29tbWl0IHpvbmUg4oaSIGZpbmFsaXplIGFycm93XG4gICAgICBpZiAoXG4gICAgICAgIG11bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoID4gMSAmJlxuICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnQgJiZcbiAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcngsXG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHJ5LFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludFswXSxcbiAgICAgICAgICBsYXN0Q29tbWl0dGVkUG9pbnRbMV0sXG4gICAgICAgICkgPCBMSU5FX0NPTkZJUk1fVEhSRVNIT0xEXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICBbbXVsdGlFbGVtZW50LmlkXTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICAgIC8vIGNsaWNraW5nIG91dHNpZGUgY29tbWl0IHpvbmUg4oaSIHVwZGF0ZSByZWZlcmVuY2UgZm9yIGxhc3QgY29tbWl0dGVkXG4gICAgICAvLyBwb2ludFxuICAgICAgbXV0YXRlRWxlbWVudChtdWx0aUVsZW1lbnQsIHtcbiAgICAgICAgbGFzdENvbW1pdHRlZFBvaW50OiBtdWx0aUVsZW1lbnQucG9pbnRzW211bHRpRWxlbWVudC5wb2ludHMubGVuZ3RoIC0gMV0sXG4gICAgICB9KTtcbiAgICAgIHNldEN1cnNvcih0aGlzLmNhbnZhcywgQ1VSU09SX1RZUEUuUE9JTlRFUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLyogSWYgYXJyb3cgaXMgcHJlLWFycm93aGVhZHMsIGl0IHdpbGwgaGF2ZSB1bmRlZmluZWQgZm9yIGJvdGggc3RhcnQgYW5kIGVuZCBhcnJvd2hlYWRzLlxuICAgICAgSWYgc28sIHdlIHdhbnQgaXQgdG8gYmUgbnVsbCBmb3Igc3RhcnQgYW5kIFwiYXJyb3dcIiBmb3IgZW5kLiBJZiB0aGUgbGluZWFyIGl0ZW0gaXMgbm90XG4gICAgICBhbiBhcnJvdywgd2Ugd2FudCBpdCB0byBiZSBudWxsIGZvciBib3RoLiBPdGhlcndpc2UsIHdlIHdhbnQgaXQgdG8gdXNlIHRoZVxuICAgICAgdmFsdWVzIGZyb20gYXBwU3RhdGUuICovXG5cbiAgICAgIGNvbnN0IHsgY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWQgfSA9IHRoaXMuc3RhdGU7XG4gICAgICBjb25zdCBbc3RhcnRBcnJvd2hlYWQsIGVuZEFycm93aGVhZF0gPVxuICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJhcnJvd1wiXG4gICAgICAgICAgPyBbY3VycmVudEl0ZW1TdGFydEFycm93aGVhZCwgY3VycmVudEl0ZW1FbmRBcnJvd2hlYWRdXG4gICAgICAgICAgOiBbbnVsbCwgbnVsbF07XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBuZXdMaW5lYXJFbGVtZW50KHtcbiAgICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICAgIHg6IGdyaWRYLFxuICAgICAgICB5OiBncmlkWSxcbiAgICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtQmFja2dyb3VuZENvbG9yLFxuICAgICAgICBmaWxsU3R5bGU6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1GaWxsU3R5bGUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICAgIHN0cm9rZVN0eWxlOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlU3R5bGUsXG4gICAgICAgIHJvdWdobmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVJvdWdobmVzcyxcbiAgICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICAgIHN0cm9rZVNoYXJwbmVzczogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUxpbmVhclN0cm9rZVNoYXJwbmVzcyxcbiAgICAgICAgc3RhcnRBcnJvd2hlYWQsXG4gICAgICAgIGVuZEFycm93aGVhZCxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAuLi5wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgIFtlbGVtZW50LmlkXTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgICBtdXRhdGVFbGVtZW50KGVsZW1lbnQsIHtcbiAgICAgICAgcG9pbnRzOiBbLi4uZWxlbWVudC5wb2ludHMsIFswLCAwXV0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvdW5kRWxlbWVudCA9IGdldEhvdmVyZWRFbGVtZW50Rm9yQmluZGluZyhcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4sXG4gICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICApO1xuICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoW1xuICAgICAgICAuLi50aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICBlbGVtZW50LFxuICAgICAgXSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgc3RhcnRCb3VuZEVsZW1lbnQ6IGJvdW5kRWxlbWVudCxcbiAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJpY0VsZW1lbnRPblBvaW50ZXJEb3duID0gKFxuICAgIGVsZW1lbnRUeXBlOiBFeGNhbGlkcmF3R2VuZXJpY0VsZW1lbnRbXCJ0eXBlXCJdLFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudCA9IG5ld0VsZW1lbnQoe1xuICAgICAgdHlwZTogZWxlbWVudFR5cGUsXG4gICAgICB4OiBncmlkWCxcbiAgICAgIHk6IGdyaWRZLFxuICAgICAgc3Ryb2tlQ29sb3I6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUJhY2tncm91bmRDb2xvcixcbiAgICAgIGZpbGxTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbUZpbGxTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtU3Ryb2tlV2lkdGgsXG4gICAgICBzdHJva2VTdHlsZTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbVN0cm9rZVN0eWxlLFxuICAgICAgcm91Z2huZXNzOiB0aGlzLnN0YXRlLmN1cnJlbnRJdGVtUm91Z2huZXNzLFxuICAgICAgb3BhY2l0eTogdGhpcy5zdGF0ZS5jdXJyZW50SXRlbU9wYWNpdHksXG4gICAgICBzdHJva2VTaGFycG5lc3M6IHRoaXMuc3RhdGUuY3VycmVudEl0ZW1TdHJva2VTaGFycG5lc3MsXG4gICAgfSk7XG5cbiAgICBpZiAoZWxlbWVudC50eXBlID09PSBcInNlbGVjdGlvblwiKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VsZWN0aW9uRWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgICAgLi4udGhpcy5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgICAgZWxlbWVudCxcbiAgICAgIF0pO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG11bHRpRWxlbWVudDogbnVsbCxcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBlZGl0aW5nRWxlbWVudDogZWxlbWVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uS2V5RG93bkZyb21Qb2ludGVyRG93bkhhbmRsZXIoXG4gICAgcG9pbnRlckRvd25TdGF0ZTogUG9pbnRlckRvd25TdGF0ZSxcbiAgKTogKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVEcmFnTmV3R2VuZXJpY0VsZW1lbnQocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvbktleVVwRnJvbVBvaW50ZXJEb3duSGFuZGxlcihcbiAgICBwb2ludGVyRG93blN0YXRlOiBQb2ludGVyRG93blN0YXRlLFxuICApOiAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHZvaWQge1xuICAgIHJldHVybiB3aXRoQmF0Y2hlZFVwZGF0ZXMoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAvLyBQcmV2ZW50cyBmb2N1cyBmcm9tIGVzY2FwaW5nIGV4Y2FsaWRyYXcgdGFiXG4gICAgICBldmVudC5rZXkgPT09IEtFWVMuQUxUICYmIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAodGhpcy5tYXliZUhhbmRsZVJlc2l6ZShwb2ludGVyRG93blN0YXRlLCBldmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZURyYWdOZXdHZW5lcmljRWxlbWVudChwb2ludGVyRG93blN0YXRlLCBldmVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlck1vdmVGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogUG9pbnRlckV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGluaXRpYWxpemUgZHJhZ09mZnNldFhZIG9ubHkgYWZ0ZXIgd2UndmUgdXBkYXRlZFxuICAgICAgLy8gYHN0YXRlLnNlbGVjdGVkRWxlbWVudElkc2Agb24gcG9pbnRlckRvd24uIERvaW5nIGl0IGhlcmUgaW4gcG9pbnRlck1vdmVcbiAgICAgIC8vIGV2ZW50IGhhbmRsZXIgc2hvdWxkIGhvcGVmdWxseSBlbnN1cmUgd2UncmUgYWxyZWFkeSB3b3JraW5nIHdpdGhcbiAgICAgIC8vIHRoZSB1cGRhdGVkIHN0YXRlLlxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQgPT09IG51bGwpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldCA9IHR1cGxlVG9Db29ycyhcbiAgICAgICAgICBnZXREcmFnT2Zmc2V0WFkoXG4gICAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54LFxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5oYW5kbGVQb2ludGVyTW92ZU92ZXJTY3JvbGxiYXJzKGV2ZW50LCBwb2ludGVyRG93blN0YXRlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvaW50ZXJDb29yZHMgPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoZXZlbnQsIHRoaXMuc3RhdGUpO1xuICAgICAgY29uc3QgW2dyaWRYLCBncmlkWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy55LFxuICAgICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICAgKTtcblxuICAgICAgLy8gZm9yIGFycm93cy9saW5lcywgZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcgdW50aWwgYSBnaXZlbiB0aHJlc2hvbGRcbiAgICAgIC8vIHRvIGVuc3VyZSB3ZSBkb24ndCBjcmVhdGUgYSAyLXBvaW50IGFycm93IGJ5IG1pc3Rha2Ugd2hlblxuICAgICAgLy8gdXNlciBjbGlja3MgbW91c2UgaW4gYSB3YXkgdGhhdCBpdCBtb3ZlcyBhIHRpbnkgYml0ICh0aHVzXG4gICAgICAvLyB0cmlnZ2VyaW5nIHBvaW50ZXJtb3ZlKVxuICAgICAgaWYgKFxuICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkICYmXG4gICAgICAgICh0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImFycm93XCIgfHxcbiAgICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlID09PSBcImxpbmVcIilcbiAgICAgICkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZGlzdGFuY2UyZChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkgPCBEUkFHR0lOR19USFJFU0hPTERcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChwb2ludGVyRG93blN0YXRlLnJlc2l6ZS5pc1Jlc2l6aW5nKSB7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy54ID0gcG9pbnRlckNvb3Jkcy54O1xuICAgICAgICBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueSA9IHBvaW50ZXJDb29yZHMueTtcbiAgICAgICAgaWYgKHRoaXMubWF5YmVIYW5kbGVSZXNpemUocG9pbnRlckRvd25TdGF0ZSwgZXZlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZGlkRHJhZyA9IExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlUG9pbnREcmFnZ2luZyhcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgIChhcHBTdGF0ZSkgPT4gdGhpcy5zZXRTdGF0ZShhcHBTdGF0ZSksXG4gICAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgICAoZWxlbWVudCwgcG9pbnRzU2NlbmVDb29yZHMpID0+IHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMoXG4gICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgIHBvaW50c1NjZW5lQ29vcmRzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChkaWREcmFnKSB7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSBwb2ludGVyQ29vcmRzLnk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0hpdEFTZWxlY3RlZEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5hbGxIaXRFbGVtZW50cy5zb21lKFxuICAgICAgICAoZWxlbWVudCkgPT4gdGhpcy5pc0FTZWxlY3RlZEVsZW1lbnQoZWxlbWVudCksXG4gICAgICApO1xuXG4gICAgICBpZiAoXG4gICAgICAgIChoYXNIaXRBU2VsZWN0ZWRFbGVtZW50IHx8XG4gICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0Q29tbW9uQm91bmRpbmdCb3hPZlNlbGVjdGVkRWxlbWVudHMpICYmXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIGZvciBib3gtc2VsZWN0aW5nIHBvaW50cyB3aGVuIGNsaWNraW5nIGluc2lkZSB0aGVcbiAgICAgICAgLy8gbGluZSdzIGJvdW5kaW5nIGJveFxuICAgICAgICAoIXRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQgfHwgIWV2ZW50LnNoaWZ0S2V5KSAmJlxuICAgICAgICAvLyBib3gtc2VsZWN0aW5nIHdpdGhvdXQgc2hpZnQgd2hlbiBlZGl0aW5nIGxpbmUsIG5vdCBjbGlja2luZyBvbiBhIGxpbmVcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudD8uZWxlbWVudElkICE9PVxuICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudD8uaWQgfHxcbiAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRFbGVtZW50SW5zaWRlKVxuICAgICAgKSB7XG4gICAgICAgIC8vIE1hcmtpbmcgdGhhdCBjbGljayB3YXMgdXNlZCBmb3IgZHJhZ2dpbmcgdG8gY2hlY2tcbiAgICAgICAgLy8gaWYgZWxlbWVudHMgc2hvdWxkIGJlIGRlc2VsZWN0ZWQgb24gcG9pbnRlcnVwXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRWxlbWVudHMgPSBnZXRTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICApO1xuICAgICAgICAvLyBwcmV2ZW50IGRyYWdnaW5nIGV2ZW4gaWYgd2UncmUgbm8gbG9uZ2VyIGhvbGRpbmcgY21kL2N0cmwgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGl0IHdvdWxkIGhhdmUgd2VpcmQgcmVzdWx0cyAoc3R1ZmYganVtcGluZyBhbGwgb3ZlciB0aGUgc2NyZWVuKVxuICAgICAgICBpZiAoc2VsZWN0ZWRFbGVtZW50cy5sZW5ndGggPiAwICYmICFwb2ludGVyRG93blN0YXRlLndpdGhDbWRPckN0cmwpIHtcbiAgICAgICAgICBjb25zdCBbZHJhZ1gsIGRyYWdZXSA9IGdldEdyaWRQb2ludChcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueCxcbiAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IFtkcmFnRGlzdGFuY2VYLCBkcmFnRGlzdGFuY2VZXSA9IFtcbiAgICAgICAgICAgIE1hdGguYWJzKHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngpLFxuICAgICAgICAgICAgTWF0aC5hYnMocG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSksXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIC8vIFdlIG9ubHkgZHJhZyBpbiBvbmUgZGlyZWN0aW9uIGlmIHNoaWZ0IGlzIHByZXNzZWRcbiAgICAgICAgICBjb25zdCBsb2NrRGlyZWN0aW9uID0gZXZlbnQuc2hpZnRLZXk7XG5cbiAgICAgICAgICBkcmFnU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ1gsXG4gICAgICAgICAgICBkcmFnWSxcbiAgICAgICAgICAgIGxvY2tEaXJlY3Rpb24sXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2VYLFxuICAgICAgICAgICAgZHJhZ0Rpc3RhbmNlWSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMubWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChzZWxlY3RlZEVsZW1lbnRzKTtcblxuICAgICAgICAgIC8vIFdlIGR1cGxpY2F0ZSB0aGUgc2VsZWN0ZWQgZWxlbWVudCBpZiBhbHQgaXMgcHJlc3NlZCBvbiBwb2ludGVyIG1vdmVcbiAgICAgICAgICBpZiAoZXZlbnQuYWx0S2V5ICYmICFwb2ludGVyRG93blN0YXRlLmhpdC5oYXNCZWVuRHVwbGljYXRlZCkge1xuICAgICAgICAgICAgLy8gTW92ZSB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGVsZW1lbnRzIHRvIHRoZSB0b3Agb2YgdGhlIHogaW5kZXggc3RhY2ssIGFuZFxuICAgICAgICAgICAgLy8gcHV0IHRoZSBkdXBsaWNhdGVzIHdoZXJlIHRoZSBzZWxlY3RlZCBlbGVtZW50cyB1c2VkIHRvIGJlLlxuICAgICAgICAgICAgLy8gKHRoZSBvcmlnaW4gcG9pbnQgd2hlcmUgdGhlIGRyYWdnaW5nIHN0YXJ0ZWQpXG5cbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUuaGl0Lmhhc0JlZW5EdXBsaWNhdGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgbmV4dEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50c1RvQXBwZW5kID0gW107XG4gICAgICAgICAgICBjb25zdCBncm91cElkTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3Qgb2xkSWRUb0R1cGxpY2F0ZWRJZCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50O1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpO1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRFbGVtZW50SWRzOiBBcnJheTxFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdPiA9XG4gICAgICAgICAgICAgIGdldFNlbGVjdGVkRWxlbWVudHMoZWxlbWVudHMsIHRoaXMuc3RhdGUsIHRydWUpLm1hcChcbiAgICAgICAgICAgICAgICAoZWxlbWVudCkgPT4gZWxlbWVudC5pZCxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHMuaW5jbHVkZXMoZWxlbWVudC5pZCkgfHxcbiAgICAgICAgICAgICAgICAvLyBjYXNlOiB0aGUgc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzIG1pZ2h0IG5vdCBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyB1cGRhdGVkIHlldCBieSB0aGUgdGltZSB0aGlzIG1vdXNlbW92ZSBldmVudCBpcyBmaXJlZFxuICAgICAgICAgICAgICAgIChlbGVtZW50LmlkID09PSBoaXRFbGVtZW50Py5pZCAmJlxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5oaXQud2FzQWRkZWRUb1NlbGVjdGlvbilcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZHVwbGljYXRlZEVsZW1lbnQgPSBkdXBsaWNhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nR3JvdXBJZCxcbiAgICAgICAgICAgICAgICAgIGdyb3VwSWRNYXAsXG4gICAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgW29yaWdpbkRyYWdYLCBvcmlnaW5EcmFnWV0gPSBnZXRHcmlkUG9pbnQoXG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi54IC0gcG9pbnRlckRvd25TdGF0ZS5kcmFnLm9mZnNldC54LFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSAtIHBvaW50ZXJEb3duU3RhdGUuZHJhZy5vZmZzZXQueSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZ3JpZFNpemUsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBtdXRhdGVFbGVtZW50KGR1cGxpY2F0ZWRFbGVtZW50LCB7XG4gICAgICAgICAgICAgICAgICB4OiBkdXBsaWNhdGVkRWxlbWVudC54ICsgKG9yaWdpbkRyYWdYIC0gZHJhZ1gpLFxuICAgICAgICAgICAgICAgICAgeTogZHVwbGljYXRlZEVsZW1lbnQueSArIChvcmlnaW5EcmFnWSAtIGRyYWdZKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBuZXh0RWxlbWVudHMucHVzaChkdXBsaWNhdGVkRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZC5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIG9sZElkVG9EdXBsaWNhdGVkSWQuc2V0KGVsZW1lbnQuaWQsIGR1cGxpY2F0ZWRFbGVtZW50LmlkKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXh0RWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmV4dFNjZW5lRWxlbWVudHMgPSBbLi4ubmV4dEVsZW1lbnRzLCAuLi5lbGVtZW50c1RvQXBwZW5kXTtcbiAgICAgICAgICAgIGJpbmRUZXh0VG9TaGFwZUFmdGVyRHVwbGljYXRpb24oXG4gICAgICAgICAgICAgIG5leHRFbGVtZW50cyxcbiAgICAgICAgICAgICAgZWxlbWVudHNUb0FwcGVuZCxcbiAgICAgICAgICAgICAgb2xkSWRUb0R1cGxpY2F0ZWRJZCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBmaXhCaW5kaW5nc0FmdGVyRHVwbGljYXRpb24oXG4gICAgICAgICAgICAgIG5leHRTY2VuZUVsZW1lbnRzLFxuICAgICAgICAgICAgICBlbGVtZW50c1RvQXBwZW5kLFxuICAgICAgICAgICAgICBvbGRJZFRvRHVwbGljYXRlZElkLFxuICAgICAgICAgICAgICBcImR1cGxpY2F0ZXNTZXJ2ZUFzT2xkXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMobmV4dFNjZW5lRWxlbWVudHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSXQgaXMgdmVyeSBpbXBvcnRhbnQgdG8gcmVhZCB0aGlzLnN0YXRlIHdpdGhpbiBlYWNoIG1vdmUgZXZlbnQsXG4gICAgICAvLyBvdGhlcndpc2Ugd2Ugd291bGQgcmVhZCBhIHN0YWxlIG9uZSFcbiAgICAgIGNvbnN0IGRyYWdnaW5nRWxlbWVudCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50O1xuICAgICAgaWYgKCFkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50LnR5cGUgPT09IFwiZnJlZWRyYXdcIikge1xuICAgICAgICBjb25zdCBwb2ludHMgPSBkcmFnZ2luZ0VsZW1lbnQucG9pbnRzO1xuICAgICAgICBjb25zdCBkeCA9IHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54O1xuICAgICAgICBjb25zdCBkeSA9IHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIGNvbnN0IHByZXNzdXJlcyA9IGRyYWdnaW5nRWxlbWVudC5zaW11bGF0ZVByZXNzdXJlXG4gICAgICAgICAgPyBkcmFnZ2luZ0VsZW1lbnQucHJlc3N1cmVzXG4gICAgICAgICAgOiBbLi4uZHJhZ2dpbmdFbGVtZW50LnByZXNzdXJlcywgZXZlbnQucHJlc3N1cmVdO1xuXG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgcHJlc3N1cmVzLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5kcmFnLmhhc09jY3VycmVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gZ3JpZFggLSBkcmFnZ2luZ0VsZW1lbnQueDtcbiAgICAgICAgbGV0IGR5ID0gZ3JpZFkgLSBkcmFnZ2luZ0VsZW1lbnQueTtcblxuICAgICAgICBpZiAoc2hvdWxkUm90YXRlV2l0aERpc2NyZXRlQW5nbGUoZXZlbnQpICYmIHBvaW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAoeyB3aWR0aDogZHgsIGhlaWdodDogZHkgfSA9IGdldFBlcmZlY3RFbGVtZW50U2l6ZShcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWxlbWVudFR5cGUsXG4gICAgICAgICAgICBkeCxcbiAgICAgICAgICAgIGR5LFxuICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGRyYWdnaW5nRWxlbWVudCwgeyBwb2ludHM6IFsuLi5wb2ludHMsIFtkeCwgZHldXSB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChwb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFsuLi5wb2ludHMuc2xpY2UoMCwgLTEpLCBbZHgsIGR5XV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpKSB7XG4gICAgICAgICAgLy8gV2hlbiBjcmVhdGluZyBhIGxpbmVhciBlbGVtZW50IGJ5IGRyYWdnaW5nXG4gICAgICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nc0ZvckxpbmVhckVsZW1lbnRBdENvb3JkcyhcbiAgICAgICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgICAgIFtwb2ludGVyQ29vcmRzXSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc3RhcnRCb3VuZEVsZW1lbnQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSBwb2ludGVyQ29vcmRzLng7XG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUubGFzdENvb3Jkcy55ID0gcG9pbnRlckNvb3Jkcy55O1xuICAgICAgICB0aGlzLm1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50KHBvaW50ZXJEb3duU3RhdGUsIGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudFR5cGUgPT09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5ib3hTZWxlY3Rpb24uaGFzT2NjdXJyZWQgPSB0cnVlO1xuXG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgICAgICAgLy8gYWxsb3dzIGZvciBib3gtc2VsZWN0aW5nIHBvaW50cyAod2l0aG91dCBzaGlmdClcbiAgICAgICAgICAhdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCAmJlxuICAgICAgICAgIGlzU29tZUVsZW1lbnRTZWxlY3RlZChlbGVtZW50cywgdGhpcy5zdGF0ZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUud2l0aENtZE9yQ3RybCAmJiBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKChwcmV2U3RhdGUpID0+XG4gICAgICAgICAgICAgIHNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgICAgIFtwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBib3gtc2VsZWN0IGxpbmUgZWRpdG9yIHBvaW50c1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICAgIExpbmVhckVsZW1lbnRFZGl0b3IuaGFuZGxlQm94U2VsZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gcmVndWxhciBib3gtc2VsZWN0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoaW5TZWxlY3Rpb24gPSBnZXRFbGVtZW50c1dpdGhpblNlbGVjdGlvbihcbiAgICAgICAgICAgIGVsZW1lbnRzLFxuICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PlxuICAgICAgICAgICAgc2VsZWN0R3JvdXBzRm9yU2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5lbGVtZW50c1dpdGhpblNlbGVjdGlvbi5yZWR1Y2UoKG1hcCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBtYXBbZWxlbWVudC5pZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgICAgICAgICAgICAgfSwge30gYXMgYW55KSxcbiAgICAgICAgICAgICAgICAgIC4uLihwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50XG4gICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdXNpbmcgY3RybC9jbWQsIHNlbGVjdCB0aGUgaGl0RWxlbWVudCBvbmx5IGlmIHdlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBoYXZlbid0IGJveC1zZWxlY3RlZCBhbnl0aGluZyBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBbcG9pbnRlckRvd25TdGF0ZS5oaXQuZWxlbWVudC5pZF06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICFlbGVtZW50c1dpdGhpblNlbGVjdGlvbi5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA6IG51bGwpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBwb2ludGVyIG1vdmUgaGFwcGVuZWQgb3ZlciBlaXRoZXIgc2Nyb2xsYmFyXG4gIHByaXZhdGUgaGFuZGxlUG9pbnRlck1vdmVPdmVyU2Nyb2xsYmFycyhcbiAgICBldmVudDogUG9pbnRlckV2ZW50LFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChwb2ludGVyRG93blN0YXRlLnNjcm9sbGJhcnMuaXNPdmVySG9yaXpvbnRhbCkge1xuICAgICAgY29uc3QgeCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBkeCA9IHggLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueDtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxYOiB0aGlzLnN0YXRlLnNjcm9sbFggLSBkeCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnggPSB4O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuc2Nyb2xsYmFycy5pc092ZXJWZXJ0aWNhbCkge1xuICAgICAgY29uc3QgeSA9IGV2ZW50LmNsaWVudFk7XG4gICAgICBjb25zdCBkeSA9IHkgLSBwb2ludGVyRG93blN0YXRlLmxhc3RDb29yZHMueTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzY3JvbGxZOiB0aGlzLnN0YXRlLnNjcm9sbFkgLSBkeSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzLnkgPSB5O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyVXBGcm9tUG9pbnRlckRvd25IYW5kbGVyKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICk6IChldmVudDogUG9pbnRlckV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gd2l0aEJhdGNoZWRVcGRhdGVzKChjaGlsZEV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICByZXNpemluZ0VsZW1lbnQsXG4gICAgICAgIG11bHRpRWxlbWVudCxcbiAgICAgICAgZWxlbWVudFR5cGUsXG4gICAgICAgIGVsZW1lbnRMb2NrZWQsXG4gICAgICAgIGlzUmVzaXppbmcsXG4gICAgICAgIGlzUm90YXRpbmcsXG4gICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGlzUmVzaXppbmc6IGZhbHNlLFxuICAgICAgICBpc1JvdGF0aW5nOiBmYWxzZSxcbiAgICAgICAgcmVzaXppbmdFbGVtZW50OiBudWxsLFxuICAgICAgICBzZWxlY3Rpb25FbGVtZW50OiBudWxsLFxuICAgICAgICBjdXJzb3JCdXR0b246IFwidXBcIixcbiAgICAgICAgLy8gdGV4dCBlbGVtZW50cyBhcmUgcmVzZXQgb24gZmluYWxpemUsIGFuZCByZXNldHRpbmcgb24gcG9pbnRlcnVwXG4gICAgICAgIC8vIG1heSBjYXVzZSBpc3N1ZXMgd2l0aCBkb3VibGUgdGFwc1xuICAgICAgICBlZGl0aW5nRWxlbWVudDpcbiAgICAgICAgICBtdWx0aUVsZW1lbnQgfHwgaXNUZXh0RWxlbWVudCh0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50KVxuICAgICAgICAgICAgPyB0aGlzLnN0YXRlLmVkaXRpbmdFbGVtZW50XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5zYXZlUG9pbnRlcihjaGlsZEV2ZW50LmNsaWVudFgsIGNoaWxkRXZlbnQuY2xpZW50WSwgXCJ1cFwiKTtcblxuICAgICAgLy8gSGFuZGxlIGVuZCBvZiBkcmFnZ2luZyBhIHBvaW50IG9mIGEgbGluZWFyIGVsZW1lbnQsIG1pZ2h0IGNsb3NlIGEgbG9vcFxuICAgICAgLy8gYW5kIHNldHMgYmluZGluZyBlbGVtZW50XG4gICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkICYmXG4gICAgICAgICAgKHBvaW50ZXJEb3duU3RhdGUuaGl0Py5lbGVtZW50Py5pZCAhPT1cbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQuZWxlbWVudElkIHx8XG4gICAgICAgICAgICAhcG9pbnRlckRvd25TdGF0ZS5oaXQuaGFzSGl0RWxlbWVudEluc2lkZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVkaXRpbmdMaW5lYXJFbGVtZW50ID0gTGluZWFyRWxlbWVudEVkaXRvci5oYW5kbGVQb2ludGVyVXAoXG4gICAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZWRpdGluZ0xpbmVhckVsZW1lbnQgIT09IHRoaXMuc3RhdGUuZWRpdGluZ0xpbmVhckVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICBlZGl0aW5nTGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQb2ludGVyVXAgPSBudWxsO1xuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuUE9JTlRFUl9NT1ZFLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLmV2ZW50TGlzdGVuZXJzLm9uTW92ZSEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULlBPSU5URVJfVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25VcCEsXG4gICAgICApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIEVWRU5ULktFWURPV04sXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlEb3duISxcbiAgICAgICk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRVZFTlQuS0VZVVAsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUuZXZlbnRMaXN0ZW5lcnMub25LZXlVcCEsXG4gICAgICApO1xuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBwZW5kaW5nSW1hZ2VFbGVtZW50OiBudWxsIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50Py50eXBlID09PSBcImZyZWVkcmF3XCIpIHtcbiAgICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgcG9pbnRzID0gZHJhZ2dpbmdFbGVtZW50LnBvaW50cztcbiAgICAgICAgbGV0IGR4ID0gcG9pbnRlckNvb3Jkcy54IC0gZHJhZ2dpbmdFbGVtZW50Lng7XG4gICAgICAgIGxldCBkeSA9IHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55O1xuXG4gICAgICAgIC8vIEFsbG93cyBkb3RzIHRvIGF2b2lkIGJlaW5nIGZsYWdnZWQgYXMgaW5maW5pdGVseSBzbWFsbFxuICAgICAgICBpZiAoZHggPT09IHBvaW50c1swXVswXSAmJiBkeSA9PT0gcG9pbnRzWzBdWzFdKSB7XG4gICAgICAgICAgZHkgKz0gMC4wMDAxO1xuICAgICAgICAgIGR4ICs9IDAuMDAwMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByZXNzdXJlcyA9IGRyYWdnaW5nRWxlbWVudC5zaW11bGF0ZVByZXNzdXJlXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogWy4uLmRyYWdnaW5nRWxlbWVudC5wcmVzc3VyZXMsIGNoaWxkRXZlbnQucHJlc3N1cmVdO1xuXG4gICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgcG9pbnRzOiBbLi4ucG9pbnRzLCBbZHgsIGR5XV0sXG4gICAgICAgICAgcHJlc3N1cmVzLFxuICAgICAgICAgIGxhc3RDb21taXR0ZWRQb2ludDogW2R4LCBkeV0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaXNJbWFnZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KSkge1xuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSBkcmFnZ2luZ0VsZW1lbnQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplSW1hZ2VEaW1lbnNpb25zKGltYWdlRWxlbWVudCk7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAgIHsgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtpbWFnZUVsZW1lbnQuaWRdOiB0cnVlIH0gfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgICB0aGlzLnNjZW5lXG4gICAgICAgICAgICAgIC5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKVxuICAgICAgICAgICAgICAuZmlsdGVyKChlbCkgPT4gZWwuaWQgIT09IGltYWdlRWxlbWVudC5pZCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNMaW5lYXJFbGVtZW50KGRyYWdnaW5nRWxlbWVudCkpIHtcbiAgICAgICAgaWYgKGRyYWdnaW5nRWxlbWVudCEucG9pbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICB0aGlzLmhpc3RvcnkucmVzdW1lUmVjb3JkaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9pbnRlckNvb3JkcyA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhcbiAgICAgICAgICBjaGlsZEV2ZW50LFxuICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQgJiZcbiAgICAgICAgICAhbXVsdGlFbGVtZW50XG4gICAgICAgICkge1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50LCB7XG4gICAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgICAgLi4uZHJhZ2dpbmdFbGVtZW50LnBvaW50cyxcbiAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueCAtIGRyYWdnaW5nRWxlbWVudC54LFxuICAgICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMueSAtIGRyYWdnaW5nRWxlbWVudC55LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIG11bHRpRWxlbWVudDogZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCAmJiAhbXVsdGlFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNCaW5kaW5nRW5hYmxlZCh0aGlzLnN0YXRlKSAmJlxuICAgICAgICAgICAgaXNCaW5kaW5nRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBtYXliZUJpbmRMaW5lYXJFbGVtZW50KFxuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICAgICAgIHBvaW50ZXJDb29yZHMsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLCBzdGFydEJvdW5kRWxlbWVudDogbnVsbCB9KTtcbiAgICAgICAgICBpZiAoIWVsZW1lbnRMb2NrZWQpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICBlbGVtZW50VHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7XG4gICAgICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgICAgICBbdGhpcy5zdGF0ZS5kcmFnZ2luZ0VsZW1lbnQhLmlkXTogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgW3RoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIiAmJlxuICAgICAgICBkcmFnZ2luZ0VsZW1lbnQgJiZcbiAgICAgICAgaXNJbnZpc2libHlTbWFsbEVsZW1lbnQoZHJhZ2dpbmdFbGVtZW50KVxuICAgICAgKSB7XG4gICAgICAgIC8vIHJlbW92ZSBpbnZpc2libGUgZWxlbWVudCB3aGljaCB3YXMgYWRkZWQgaW4gb25Qb2ludGVyRG93blxuICAgICAgICB0aGlzLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhcbiAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLnNsaWNlKDAsIC0xKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICAgIG11dGF0ZUVsZW1lbnQoXG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICAgIGdldE5vcm1hbGl6ZWREaW1lbnNpb25zKGRyYWdnaW5nRWxlbWVudCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNpemluZ0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5oaXN0b3J5LnJlc3VtZVJlY29yZGluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzaXppbmdFbGVtZW50ICYmIGlzSW52aXNpYmx5U21hbGxFbGVtZW50KHJlc2l6aW5nRWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5zY2VuZS5yZXBsYWNlQWxsRWxlbWVudHMoXG4gICAgICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAgICAgLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpXG4gICAgICAgICAgICAuZmlsdGVyKChlbCkgPT4gZWwuaWQgIT09IHJlc2l6aW5nRWxlbWVudC5pZCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvZGUgYmVsb3cgaGFuZGxlcyBzZWxlY3Rpb24gd2hlbiBlbGVtZW50KHMpIHdlcmVuJ3RcbiAgICAgIC8vIGRyYWcgb3IgYWRkZWQgdG8gc2VsZWN0aW9uIG9uIHBvaW50ZXIgZG93biBwaGFzZS5cbiAgICAgIGNvbnN0IGhpdEVsZW1lbnQgPSBwb2ludGVyRG93blN0YXRlLmhpdC5lbGVtZW50O1xuICAgICAgaWYgKFxuICAgICAgICBoaXRFbGVtZW50ICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuaGl0Lndhc0FkZGVkVG9TZWxlY3Rpb24gJiZcbiAgICAgICAgLy8gaWYgd2UncmUgZWRpdGluZyBhIGxpbmUsIHBvaW50ZXJ1cCBzaG91bGRuJ3Qgc3dpdGNoIHNlbGVjdGlvbiBpZlxuICAgICAgICAvLyBib3ggc2VsZWN0ZWRcbiAgICAgICAgKCF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50IHx8XG4gICAgICAgICAgIXBvaW50ZXJEb3duU3RhdGUuYm94U2VsZWN0aW9uLmhhc09jY3VycmVkKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHdoZW4gaW5zaWRlIGxpbmUgZWRpdG9yLCBzaGlmdCBzZWxlY3RzIHBvaW50cyBpbnN0ZWFkXG4gICAgICAgIGlmIChjaGlsZEV2ZW50LnNoaWZ0S2V5ICYmICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzW2hpdEVsZW1lbnQuaWRdKSB7XG4gICAgICAgICAgICBpZiAoaXNTZWxlY3RlZFZpYUdyb3VwKHRoaXMuc3RhdGUsIGhpdEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gdW5zZWxlY3QgYWxsIGdyb3VwcyBoaXRFbGVtZW50IGlzIHBhcnQgb2ZcbiAgICAgICAgICAgICAgLy8gYXMgd2VsbCBhcyBhbGwgZWxlbWVudHMgdGhhdCBhcmUgcGFydCBvZiB0aGUgZ3JvdXBzXG4gICAgICAgICAgICAgIC8vIGhpdEVsZW1lbnQgaXMgcGFydCBvZlxuICAgICAgICAgICAgICBjb25zdCBpZHNPZlNlbGVjdGVkRWxlbWVudHNUaGF0QXJlSW5Hcm91cHMgPSBoaXRFbGVtZW50Lmdyb3VwSWRzXG4gICAgICAgICAgICAgICAgLmZsYXRNYXAoKGdyb3VwSWQpID0+XG4gICAgICAgICAgICAgICAgICBnZXRFbGVtZW50c0luR3JvdXAodGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCBncm91cElkKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLm1hcCgoZWxlbWVudCkgPT4gKHsgW2VsZW1lbnQuaWRdOiBmYWxzZSB9KSlcbiAgICAgICAgICAgICAgICAucmVkdWNlKChwcmV2SWQsIGFjYykgPT4gKHsgLi4ucHJldklkLCAuLi5hY2MgfSksIHt9KTtcblxuICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKChfcHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgICAgLi4uaGl0RWxlbWVudC5ncm91cElkc1xuICAgICAgICAgICAgICAgICAgICAubWFwKChnSWQpID0+ICh7IFtnSWRdOiBmYWxzZSB9KSlcbiAgICAgICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldiwgYWNjKSA9PiAoeyAuLi5wcmV2LCAuLi5hY2MgfSksIHt9KSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgLi4uX3ByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAuLi5pZHNPZlNlbGVjdGVkRWxlbWVudHNUaGF0QXJlSW5Hcm91cHMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gcmVtb3ZlIGVsZW1lbnQgZnJvbSBzZWxlY3Rpb24gd2hpbGVcbiAgICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG4gICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT5cbiAgICAgICAgICAgICAgICBzZWxlY3RHcm91cHNGb3JTZWxlY3RlZEVsZW1lbnRzKFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLnByZXZTdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgW2hpdEVsZW1lbnQhLmlkXTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFkZCBlbGVtZW50IHRvIHNlbGVjdGlvbiB3aGlsZVxuICAgICAgICAgICAgLy8ga2VlcGluZyBwcmV2IGVsZW1lbnRzIHNlbGVjdGVkXG5cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKF9wcmV2U3RhdGUpID0+ICh7XG4gICAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgICAgIC4uLl9wcmV2U3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgICAgICAgICAgICAgIFtoaXRFbGVtZW50IS5pZF06IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKHByZXZTdGF0ZSkgPT4gKHtcbiAgICAgICAgICAgIC4uLnNlbGVjdEdyb3Vwc0ZvclNlbGVjdGVkRWxlbWVudHMoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5wcmV2U3RhdGUsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7IFtoaXRFbGVtZW50LmlkXTogdHJ1ZSB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzKCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnN0YXRlLmVkaXRpbmdMaW5lYXJFbGVtZW50ICYmXG4gICAgICAgICFwb2ludGVyRG93blN0YXRlLmRyYWcuaGFzT2NjdXJyZWQgJiZcbiAgICAgICAgIXRoaXMuc3RhdGUuaXNSZXNpemluZyAmJlxuICAgICAgICAoKGhpdEVsZW1lbnQgJiZcbiAgICAgICAgICBpc0hpdHRpbmdFbGVtZW50Qm91bmRpbmdCb3hXaXRob3V0SGl0dGluZ0VsZW1lbnQoXG4gICAgICAgICAgICBoaXRFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbi55LFxuICAgICAgICAgICkpIHx8XG4gICAgICAgICAgKCFoaXRFbGVtZW50ICYmXG4gICAgICAgICAgICBwb2ludGVyRG93blN0YXRlLmhpdC5oYXNIaXRDb21tb25Cb3VuZGluZ0JveE9mU2VsZWN0ZWRFbGVtZW50cykpXG4gICAgICApIHtcbiAgICAgICAgLy8gRGVzZWxlY3Qgc2VsZWN0ZWQgZWxlbWVudHNcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgICAgICBzZWxlY3RlZEdyb3VwSWRzOiB7fSxcbiAgICAgICAgICBlZGl0aW5nR3JvdXBJZDogbnVsbCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnRMb2NrZWQgJiYgZWxlbWVudFR5cGUgIT09IFwiZnJlZWRyYXdcIiAmJiBkcmFnZ2luZ0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczoge1xuICAgICAgICAgICAgLi4ucHJldlN0YXRlLnNlbGVjdGVkRWxlbWVudElkcyxcbiAgICAgICAgICAgIFtkcmFnZ2luZ0VsZW1lbnQuaWRdOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBlbGVtZW50VHlwZSAhPT0gXCJzZWxlY3Rpb25cIiB8fFxuICAgICAgICBpc1NvbWVFbGVtZW50U2VsZWN0ZWQodGhpcy5zY2VuZS5nZXRFbGVtZW50cygpLCB0aGlzLnN0YXRlKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5yZXN1bWVSZWNvcmRpbmcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBvaW50ZXJEb3duU3RhdGUuZHJhZy5oYXNPY2N1cnJlZCB8fCBpc1Jlc2l6aW5nIHx8IGlzUm90YXRpbmcpIHtcbiAgICAgICAgKGlzQmluZGluZ0VuYWJsZWQodGhpcy5zdGF0ZSlcbiAgICAgICAgICA/IGJpbmRPclVuYmluZFNlbGVjdGVkRWxlbWVudHNcbiAgICAgICAgICA6IHVuYmluZExpbmVhckVsZW1lbnRzKShcbiAgICAgICAgICBnZXRTZWxlY3RlZEVsZW1lbnRzKHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSwgdGhpcy5zdGF0ZSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICghZWxlbWVudExvY2tlZCAmJiBlbGVtZW50VHlwZSAhPT0gXCJmcmVlZHJhd1wiKSB7XG4gICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgZHJhZ2dpbmdFbGVtZW50OiBudWxsLFxuICAgICAgICAgIHN1Z2dlc3RlZEJpbmRpbmdzOiBbXSxcbiAgICAgICAgICBlbGVtZW50VHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBkcmFnZ2luZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6IFtdLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUltYWdlID0gYXN5bmMgKHtcbiAgICBpbWFnZUZpbGUsXG4gICAgaW1hZ2VFbGVtZW50OiBfaW1hZ2VFbGVtZW50LFxuICAgIHNob3dDdXJzb3JJbWFnZVByZXZpZXcgPSBmYWxzZSxcbiAgfToge1xuICAgIGltYWdlRmlsZTogRmlsZTtcbiAgICBpbWFnZUVsZW1lbnQ6IEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ7XG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW47XG4gIH0pID0+IHtcbiAgICAvLyBhdCB0aGlzIHBvaW50IHRoaXMgc2hvdWxkIGJlIGd1YXJhbnRlZWQgaW1hZ2UgZmlsZSwgYnV0IHdlIGRvIHRoaXMgY2hlY2tcbiAgICAvLyB0byBzYXRpc2Z5IFRTIGRvd24gdGhlIGxpbmVcbiAgICBpZiAoIWlzU3VwcG9ydGVkSW1hZ2VGaWxlKGltYWdlRmlsZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KFwiZXJyb3JzLnVuc3VwcG9ydGVkRmlsZVR5cGVcIikpO1xuICAgIH1cbiAgICBjb25zdCBtaW1lVHlwZSA9IGltYWdlRmlsZS50eXBlO1xuXG4gICAgc2V0Q3Vyc29yKHRoaXMuY2FudmFzLCBcIndhaXRcIik7XG5cbiAgICBpZiAobWltZVR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbWFnZUZpbGUgPSBTVkdTdHJpbmdUb0ZpbGUoXG4gICAgICAgICAgYXdhaXQgbm9ybWFsaXplU1ZHKGF3YWl0IGltYWdlRmlsZS50ZXh0KCkpLFxuICAgICAgICAgIGltYWdlRmlsZS5uYW1lLFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5zdmdJbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBnZW5lcmF0ZSBpbWFnZSBpZCAoYnkgZGVmYXVsdCB0aGUgZmlsZSBkaWdlc3QpIGJlZm9yZSBhbnlcbiAgICAvLyByZXNpemluZy9jb21wcmVzc2lvbiB0YWtlcyBwbGFjZSB0byBrZWVwIGl0IG1vcmUgcG9ydGFibGVcbiAgICBjb25zdCBmaWxlSWQgPSBhd2FpdCAoKHRoaXMucHJvcHMuZ2VuZXJhdGVJZEZvckZpbGU/LihcbiAgICAgIGltYWdlRmlsZSxcbiAgICApIGFzIFByb21pc2U8RmlsZUlkPikgfHwgZ2VuZXJhdGVJZEZyb21GaWxlKGltYWdlRmlsZSkpO1xuXG4gICAgaWYgKCFmaWxlSWQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJDb3VsZG4ndCBnZW5lcmF0ZSBmaWxlIGlkIG9yIHRoZSBzdXBwbGllZCBgZ2VuZXJhdGVJZEZvckZpbGVgIGRpZG4ndCByZXNvbHZlIHRvIG9uZS5cIixcbiAgICAgICk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodChcImVycm9ycy5pbWFnZUluc2VydEVycm9yXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZ0ZpbGVEYXRhID0gdGhpcy5maWxlc1tmaWxlSWRdO1xuICAgIGlmICghZXhpc3RpbmdGaWxlRGF0YT8uZGF0YVVSTCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW1hZ2VGaWxlID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgICAgIG1heFdpZHRoT3JIZWlnaHQ6IERFRkFVTFRfTUFYX0lNQUdFX1dJRFRIX09SX0hFSUdIVCxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJlcnJvciB0cnlpbmcgdG8gcmVzaW5nIGltYWdlIGZpbGUgb24gaW5zZXJ0aW9uXCIsIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGltYWdlRmlsZS5zaXplID4gTUFYX0FMTE9XRURfRklMRV9CWVRFUykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgdChcImVycm9ycy5maWxlVG9vQmlnXCIsIHtcbiAgICAgICAgICAgIG1heFNpemU6IGAke01hdGgudHJ1bmMoTUFYX0FMTE9XRURfRklMRV9CWVRFUyAvIDEwMjQgLyAxMDI0KX1NQmAsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgIGNvbnN0IGRhdGFVUkwgPSB0aGlzLmZpbGVzW2ZpbGVJZF0/LmRhdGFVUkw7XG4gICAgICAvLyBvcHRpbWl6YXRpb24gc28gdGhhdCB3ZSBkb24ndCB1bm5lY2Vzc2FyaWx5IHJlc2l6ZSB0aGUgb3JpZ2luYWxcbiAgICAgIC8vIGZ1bGwtc2l6ZSBmaWxlIGZvciBjdXJzb3IgcHJldmlld1xuICAgICAgLy8gKGl0J3MgbXVjaCBmYXN0ZXIgdG8gY29udmVydCB0aGUgcmVzaXplZCBkYXRhVVJMIHRvIEZpbGUpXG4gICAgICBjb25zdCByZXNpemVkRmlsZSA9IGRhdGFVUkwgJiYgZGF0YVVSTFRvRmlsZShkYXRhVVJMKTtcblxuICAgICAgdGhpcy5zZXRJbWFnZVByZXZpZXdDdXJzb3IocmVzaXplZEZpbGUgfHwgaW1hZ2VGaWxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhVVJMID1cbiAgICAgIHRoaXMuZmlsZXNbZmlsZUlkXT8uZGF0YVVSTCB8fCAoYXdhaXQgZ2V0RGF0YVVSTChpbWFnZUZpbGUpKTtcblxuICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IG11dGF0ZUVsZW1lbnQoXG4gICAgICBfaW1hZ2VFbGVtZW50LFxuICAgICAge1xuICAgICAgICBmaWxlSWQsXG4gICAgICB9LFxuICAgICAgZmFsc2UsXG4gICAgKSBhcyBOb25EZWxldGVkPEluaXRpYWxpemVkRXhjYWxpZHJhd0ltYWdlRWxlbWVudD47XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8Tm9uRGVsZXRlZDxJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnQ+PihcbiAgICAgIGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmZpbGVzID0ge1xuICAgICAgICAgICAgLi4udGhpcy5maWxlcyxcbiAgICAgICAgICAgIFtmaWxlSWRdOiB7XG4gICAgICAgICAgICAgIG1pbWVUeXBlLFxuICAgICAgICAgICAgICBpZDogZmlsZUlkLFxuICAgICAgICAgICAgICBkYXRhVVJMLFxuICAgICAgICAgICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNhY2hlZEltYWdlRGF0YSA9IHRoaXMuaW1hZ2VDYWNoZS5nZXQoZmlsZUlkKTtcbiAgICAgICAgICBpZiAoIWNhY2hlZEltYWdlRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5hZGROZXdJbWFnZXNUb0ltYWdlQ2FjaGUoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudXBkYXRlSW1hZ2VDYWNoZShbaW1hZ2VFbGVtZW50XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjYWNoZWRJbWFnZURhdGE/LmltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgYXdhaXQgY2FjaGVkSW1hZ2VEYXRhLmltYWdlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnBlbmRpbmdJbWFnZUVsZW1lbnQ/LmlkICE9PSBpbWFnZUVsZW1lbnQuaWQgJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdFbGVtZW50Py5pZCAhPT0gaW1hZ2VFbGVtZW50LmlkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50LCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShpbWFnZUVsZW1lbnQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcih0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIikpKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBpZiAoIXNob3dDdXJzb3JJbWFnZVByZXZpZXcpIHtcbiAgICAgICAgICAgIHJlc2V0Q3Vyc29yKHRoaXMuY2FudmFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogaW5zZXJ0cyBpbWFnZSBpbnRvIGVsZW1lbnRzIGFycmF5IGFuZCByZXJlbmRlcnNcbiAgICovXG4gIHByaXZhdGUgaW5zZXJ0SW1hZ2VFbGVtZW50ID0gYXN5bmMgKFxuICAgIGltYWdlRWxlbWVudDogRXhjYWxpZHJhd0ltYWdlRWxlbWVudCxcbiAgICBpbWFnZUZpbGU6IEZpbGUsXG4gICAgc2hvd0N1cnNvckltYWdlUHJldmlldz86IGJvb2xlYW4sXG4gICkgPT4ge1xuICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFtcbiAgICAgIC4uLnRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICBpbWFnZUVsZW1lbnQsXG4gICAgXSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplSW1hZ2Uoe1xuICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgIGltYWdlRWxlbWVudCxcbiAgICAgICAgc2hvd0N1cnNvckltYWdlUHJldmlldyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIG11dGF0ZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCB7XG4gICAgICAgIGlzRGVsZXRlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hY3Rpb25NYW5hZ2VyLmV4ZWN1dGVBY3Rpb24oYWN0aW9uRmluYWxpemUpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB8fCB0KFwiZXJyb3JzLmltYWdlSW5zZXJ0RXJyb3JcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRJbWFnZVByZXZpZXdDdXJzb3IgPSBhc3luYyAoaW1hZ2VGaWxlOiBGaWxlKSA9PiB7XG4gICAgLy8gbXVzdG4ndCBiZSBsYXJnZXIgdGhhbiAxMjggcHhcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX0Jhc2ljX1VzZXJfSW50ZXJmYWNlL1VzaW5nX1VSTF92YWx1ZXNfZm9yX3RoZV9jdXJzb3JfcHJvcGVydHlcbiAgICBjb25zdCBjdXJzb3JJbWFnZVNpemVQeCA9IDk2O1xuXG4gICAgY29uc3QgaW1hZ2VQcmV2aWV3ID0gYXdhaXQgcmVzaXplSW1hZ2VGaWxlKGltYWdlRmlsZSwge1xuICAgICAgbWF4V2lkdGhPckhlaWdodDogY3Vyc29ySW1hZ2VTaXplUHgsXG4gICAgfSk7XG5cbiAgICBsZXQgcHJldmlld0RhdGFVUkwgPSBhd2FpdCBnZXREYXRhVVJMKGltYWdlUHJldmlldyk7XG5cbiAgICAvLyBTVkcgY2Fubm90IGJlIHJlc2l6ZWQgdmlhIGByZXNpemVJbWFnZUZpbGVgIHNvIHdlIHJlc2l6ZSBieSByZW5kZXJpbmcgdG9cbiAgICAvLyBhIHNtYWxsIGNhbnZhc1xuICAgIGlmIChpbWFnZUZpbGUudHlwZSA9PT0gTUlNRV9UWVBFUy5zdmcpIHtcbiAgICAgIGNvbnN0IGltZyA9IGF3YWl0IGxvYWRIVE1MSW1hZ2VFbGVtZW50KHByZXZpZXdEYXRhVVJMKTtcblxuICAgICAgbGV0IGhlaWdodCA9IE1hdGgubWluKGltZy5oZWlnaHQsIGN1cnNvckltYWdlU2l6ZVB4KTtcbiAgICAgIGxldCB3aWR0aCA9IGhlaWdodCAqIChpbWcud2lkdGggLyBpbWcuaGVpZ2h0KTtcblxuICAgICAgaWYgKHdpZHRoID4gY3Vyc29ySW1hZ2VTaXplUHgpIHtcbiAgICAgICAgd2lkdGggPSBjdXJzb3JJbWFnZVNpemVQeDtcbiAgICAgICAgaGVpZ2h0ID0gd2lkdGggKiAoaW1nLmhlaWdodCAvIGltZy53aWR0aCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKSE7XG5cbiAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIHByZXZpZXdEYXRhVVJMID0gY2FudmFzLnRvRGF0YVVSTChNSU1FX1RZUEVTLnN2ZykgYXMgRGF0YVVSTDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZS5wZW5kaW5nSW1hZ2VFbGVtZW50KSB7XG4gICAgICBzZXRDdXJzb3IodGhpcy5jYW52YXMsIGB1cmwoJHtwcmV2aWV3RGF0YVVSTH0pIDQgNCwgYXV0b2ApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG9uSW1hZ2VBY3Rpb24gPSBhc3luYyAoXG4gICAgeyBpbnNlcnRPbkNhbnZhc0RpcmVjdGx5IH0gPSB7IGluc2VydE9uQ2FudmFzRGlyZWN0bHk6IGZhbHNlIH0sXG4gICkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjbGllbnRYID0gdGhpcy5zdGF0ZS53aWR0aCAvIDIgKyB0aGlzLnN0YXRlLm9mZnNldExlZnQ7XG4gICAgICBjb25zdCBjbGllbnRZID0gdGhpcy5zdGF0ZS5oZWlnaHQgLyAyICsgdGhpcy5zdGF0ZS5vZmZzZXRUb3A7XG5cbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgICB7IGNsaWVudFgsIGNsaWVudFkgfSxcbiAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGltYWdlRmlsZSA9IGF3YWl0IGZpbGVPcGVuKHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiSW1hZ2VcIixcbiAgICAgICAgZXh0ZW5zaW9uczogW1wianBnXCIsIFwicG5nXCIsIFwic3ZnXCIsIFwiZ2lmXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGltYWdlRWxlbWVudCA9IHRoaXMuY3JlYXRlSW1hZ2VFbGVtZW50KHtcbiAgICAgICAgc2NlbmVYOiB4LFxuICAgICAgICBzY2VuZVk6IHksXG4gICAgICB9KTtcblxuICAgICAgaWYgKGluc2VydE9uQ2FudmFzRGlyZWN0bHkpIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJbWFnZUVsZW1lbnQoaW1hZ2VFbGVtZW50LCBpbWFnZUZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2ltYWdlRWxlbWVudC5pZF06IHRydWUgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5leGVjdXRlQWN0aW9uKGFjdGlvbkZpbmFsaXplKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwZW5kaW5nSW1hZ2VFbGVtZW50OiBpbWFnZUVsZW1lbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChcbiAgICAgICAgICAgICAgaW1hZ2VFbGVtZW50LFxuICAgICAgICAgICAgICBpbWFnZUZpbGUsXG4gICAgICAgICAgICAgIC8qIHNob3dDdXJzb3JJbWFnZVByZXZpZXcgKi8gdHJ1ZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBpZiAoZXJyb3IubmFtZSAhPT0gXCJBYm9ydEVycm9yXCIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHBlbmRpbmdJbWFnZUVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWRpdGluZ0VsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgZWxlbWVudFR5cGU6IFwic2VsZWN0aW9uXCIsXG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZXhlY3V0ZUFjdGlvbihhY3Rpb25GaW5hbGl6ZSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMgPSAoXG4gICAgaW1hZ2VFbGVtZW50OiBFeGNhbGlkcmF3SW1hZ2VFbGVtZW50LFxuICAgIGZvcmNlTmF0dXJhbFNpemUgPSBmYWxzZSxcbiAgKSA9PiB7XG4gICAgY29uc3QgaW1hZ2UgPVxuICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQpICYmXG4gICAgICB0aGlzLmltYWdlQ2FjaGUuZ2V0KGltYWdlRWxlbWVudC5maWxlSWQpPy5pbWFnZTtcblxuICAgIGlmICghaW1hZ2UgfHwgaW1hZ2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGltYWdlRWxlbWVudC53aWR0aCA8IERSQUdHSU5HX1RIUkVTSE9MRCAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSAmJlxuICAgICAgICBpbWFnZUVsZW1lbnQuaGVpZ2h0IDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgcGxhY2Vob2xkZXJTaXplID0gMTAwIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlO1xuICAgICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwge1xuICAgICAgICAgIHg6IGltYWdlRWxlbWVudC54IC0gcGxhY2Vob2xkZXJTaXplIC8gMixcbiAgICAgICAgICB5OiBpbWFnZUVsZW1lbnQueSAtIHBsYWNlaG9sZGVyU2l6ZSAvIDIsXG4gICAgICAgICAgd2lkdGg6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgICBoZWlnaHQ6IHBsYWNlaG9sZGVyU2l6ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBmb3JjZU5hdHVyYWxTaXplIHx8XG4gICAgICAvLyBpZiB1c2VyLWNyZWF0ZWQgYm91bmRpbmcgYm94IGlzIGJlbG93IHRocmVzaG9sZCwgYXNzdW1lIHRoZVxuICAgICAgLy8gaW50ZW50aW9uIHdhcyB0byBjbGljayBpbnN0ZWFkIG9mIGRyYWcsIGFuZCB1c2UgdGhlIGltYWdlJ3NcbiAgICAgIC8vIGludHJpbnNpYyBzaXplXG4gICAgICAoaW1hZ2VFbGVtZW50LndpZHRoIDwgRFJBR0dJTkdfVEhSRVNIT0xEIC8gdGhpcy5zdGF0ZS56b29tLnZhbHVlICYmXG4gICAgICAgIGltYWdlRWxlbWVudC5oZWlnaHQgPCBEUkFHR0lOR19USFJFU0hPTEQgLyB0aGlzLnN0YXRlLnpvb20udmFsdWUpXG4gICAgKSB7XG4gICAgICBjb25zdCBtaW5IZWlnaHQgPSBNYXRoLm1heCh0aGlzLnN0YXRlLmhlaWdodCAtIDEyMCwgMTYwKTtcbiAgICAgIC8vIG1heCA2NSUgb2YgY2FudmFzIGhlaWdodCwgY2xhbXBlZCB0byA8MzAwcHgsIHZoIC0gMTIwcHg+XG4gICAgICBjb25zdCBtYXhIZWlnaHQgPSBNYXRoLm1pbihcbiAgICAgICAgbWluSGVpZ2h0LFxuICAgICAgICBNYXRoLmZsb29yKHRoaXMuc3RhdGUuaGVpZ2h0ICogMC41KSAvIHRoaXMuc3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGhlaWdodCA9IE1hdGgubWluKGltYWdlLm5hdHVyYWxIZWlnaHQsIG1heEhlaWdodCk7XG4gICAgICBjb25zdCB3aWR0aCA9IGhlaWdodCAqIChpbWFnZS5uYXR1cmFsV2lkdGggLyBpbWFnZS5uYXR1cmFsSGVpZ2h0KTtcblxuICAgICAgLy8gYWRkIGN1cnJlbnQgaW1hZ2VFbGVtZW50IHdpZHRoL2hlaWdodCB0byBhY2NvdW50IGZvciBwcmV2aW91cyBjZW50ZXJpbmdcbiAgICAgIC8vIG9mIHRoZSBwbGFjaG9sZGVyIGltYWdlXG4gICAgICBjb25zdCB4ID0gaW1hZ2VFbGVtZW50LnggKyBpbWFnZUVsZW1lbnQud2lkdGggLyAyIC0gd2lkdGggLyAyO1xuICAgICAgY29uc3QgeSA9IGltYWdlRWxlbWVudC55ICsgaW1hZ2VFbGVtZW50LmhlaWdodCAvIDIgLSBoZWlnaHQgLyAyO1xuXG4gICAgICBtdXRhdGVFbGVtZW50KGltYWdlRWxlbWVudCwgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgIH1cbiAgfTtcblxuICAvKiogdXBkYXRlcyBpbWFnZSBjYWNoZSwgcmVmcmVzaGluZyB1cGRhdGVkIGVsZW1lbnRzIGFuZC9vciBzZXR0aW5nIHN0YXR1c1xuICAgICAgdG8gZXJyb3IgZm9yIGltYWdlcyB0aGF0IGZhaWwgZHVyaW5nIDxpbWc+IGVsZW1lbnQgY3JlYXRpb24gKi9cbiAgcHJpdmF0ZSB1cGRhdGVJbWFnZUNhY2hlID0gYXN5bmMgKFxuICAgIGVsZW1lbnRzOiByZWFkb25seSBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnRbXSxcbiAgICBmaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHsgdXBkYXRlZEZpbGVzLCBlcnJvcmVkRmlsZXMgfSA9IGF3YWl0IF91cGRhdGVJbWFnZUNhY2hlKHtcbiAgICAgIGltYWdlQ2FjaGU6IHRoaXMuaW1hZ2VDYWNoZSxcbiAgICAgIGZpbGVJZHM6IGVsZW1lbnRzLm1hcCgoZWxlbWVudCkgPT4gZWxlbWVudC5maWxlSWQpLFxuICAgICAgZmlsZXMsXG4gICAgfSk7XG4gICAgaWYgKHVwZGF0ZWRGaWxlcy5zaXplIHx8IGVycm9yZWRGaWxlcy5zaXplKSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgaWYgKHVwZGF0ZWRGaWxlcy5oYXMoZWxlbWVudC5maWxlSWQpKSB7XG4gICAgICAgICAgaW52YWxpZGF0ZVNoYXBlRm9yRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZXJyb3JlZEZpbGVzLnNpemUpIHtcbiAgICAgIHRoaXMuc2NlbmUucmVwbGFjZUFsbEVsZW1lbnRzKFxuICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzSW5pdGlhbGl6ZWRJbWFnZUVsZW1lbnQoZWxlbWVudCkgJiZcbiAgICAgICAgICAgIGVycm9yZWRGaWxlcy5oYXMoZWxlbWVudC5maWxlSWQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3RWxlbWVudFdpdGgoZWxlbWVudCwge1xuICAgICAgICAgICAgICBzdGF0dXM6IFwiZXJyb3JcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7IHVwZGF0ZWRGaWxlcywgZXJyb3JlZEZpbGVzIH07XG4gIH07XG5cbiAgLyoqIGFkZHMgbmV3IGltYWdlcyB0byBpbWFnZUNhY2hlIGFuZCByZS1yZW5kZXJzIGlmIG5lZWRlZCAqL1xuICBwcml2YXRlIGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSA9IGFzeW5jIChcbiAgICBpbWFnZUVsZW1lbnRzOiBJbml0aWFsaXplZEV4Y2FsaWRyYXdJbWFnZUVsZW1lbnRbXSA9IGdldEluaXRpYWxpemVkSW1hZ2VFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICApLFxuICAgIGZpbGVzOiBCaW5hcnlGaWxlcyA9IHRoaXMuZmlsZXMsXG4gICkgPT4ge1xuICAgIGNvbnN0IHVuY2FjaGVkSW1hZ2VFbGVtZW50cyA9IGltYWdlRWxlbWVudHMuZmlsdGVyKFxuICAgICAgKGVsZW1lbnQpID0+ICFlbGVtZW50LmlzRGVsZXRlZCAmJiAhdGhpcy5pbWFnZUNhY2hlLmhhcyhlbGVtZW50LmZpbGVJZCksXG4gICAgKTtcblxuICAgIGlmICh1bmNhY2hlZEltYWdlRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB7IHVwZGF0ZWRGaWxlcyB9ID0gYXdhaXQgdGhpcy51cGRhdGVJbWFnZUNhY2hlKFxuICAgICAgICB1bmNhY2hlZEltYWdlRWxlbWVudHMsXG4gICAgICAgIGZpbGVzLFxuICAgICAgKTtcbiAgICAgIGlmICh1cGRhdGVkRmlsZXMuc2l6ZSkge1xuICAgICAgICB0aGlzLnNjZW5lLmluZm9ybU11dGF0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKiBnZW5lcmFsbHkgeW91IHNob3VsZCB1c2UgYGFkZE5ld0ltYWdlc1RvSW1hZ2VDYWNoZSgpYCBkaXJlY3RseSBpZiB5b3UgbmVlZFxuICAgKiAgdG8gcmVuZGVyIG5ldyBpbWFnZXMuIFRoaXMgaXMganVzdCBhIGZhaWxzYWZlICAqL1xuICBwcml2YXRlIHNjaGVkdWxlSW1hZ2VSZWZyZXNoID0gdGhyb3R0bGUoKCkgPT4ge1xuICAgIHRoaXMuYWRkTmV3SW1hZ2VzVG9JbWFnZUNhY2hlKCk7XG4gIH0sIElNQUdFX1JFTkRFUl9USU1FT1VUKTtcblxuICBwcml2YXRlIHVwZGF0ZUJpbmRpbmdFbmFibGVkT25Qb2ludGVyTW92ZSA9IChcbiAgICBldmVudDogUmVhY3QuUG9pbnRlckV2ZW50PEhUTUxDYW52YXNFbGVtZW50PixcbiAgKSA9PiB7XG4gICAgY29uc3Qgc2hvdWxkRW5hYmxlQmluZGluZyA9IHNob3VsZEVuYWJsZUJpbmRpbmdGb3JQb2ludGVyRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0aGlzLnN0YXRlLmlzQmluZGluZ0VuYWJsZWQgIT09IHNob3VsZEVuYWJsZUJpbmRpbmcpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0JpbmRpbmdFbmFibGVkOiBzaG91bGRFbmFibGVCaW5kaW5nIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlU3VnZ2VzdEJpbmRpbmdBdEN1cnNvciA9IChwb2ludGVyQ29vcmRzOiB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgfSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICBwb2ludGVyQ29vcmRzLFxuICAgICAgdGhpcy5zY2VuZSxcbiAgICApO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc3VnZ2VzdGVkQmluZGluZ3M6XG4gICAgICAgIGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgIT0gbnVsbCA/IFtob3ZlcmVkQmluZGFibGVFbGVtZW50XSA6IFtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ3NGb3JMaW5lYXJFbGVtZW50QXRDb29yZHMgPSAoXG4gICAgbGluZWFyRWxlbWVudDogTm9uRGVsZXRlZDxFeGNhbGlkcmF3TGluZWFyRWxlbWVudD4sXG4gICAgLyoqIHNjZW5lIGNvb3JkcyAqL1xuICAgIHBvaW50ZXJDb29yZHM6IHtcbiAgICAgIHg6IG51bWJlcjtcbiAgICAgIHk6IG51bWJlcjtcbiAgICB9W10sXG4gICAgLy8gRHVyaW5nIGxpbmUgY3JlYXRpb24gdGhlIHN0YXJ0IGJpbmRpbmcgaGFzbid0IGJlZW4gd3JpdHRlbiB5ZXRcbiAgICAvLyBpbnRvIGBsaW5lYXJFbGVtZW50YFxuICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD86IEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQgfCBudWxsLFxuICApOiB2b2lkID0+IHtcbiAgICBpZiAoIXBvaW50ZXJDb29yZHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3VnZ2VzdGVkQmluZGluZ3MgPSBwb2ludGVyQ29vcmRzLnJlZHVjZShcbiAgICAgIChhY2M6IE5vbkRlbGV0ZWQ8RXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudD5bXSwgY29vcmRzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvdmVyZWRCaW5kYWJsZUVsZW1lbnQgPSBnZXRIb3ZlcmVkRWxlbWVudEZvckJpbmRpbmcoXG4gICAgICAgICAgY29vcmRzLFxuICAgICAgICAgIHRoaXMuc2NlbmUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50ICE9IG51bGwgJiZcbiAgICAgICAgICAhaXNMaW5lYXJFbGVtZW50U2ltcGxlQW5kQWxyZWFkeUJvdW5kKFxuICAgICAgICAgICAgbGluZWFyRWxlbWVudCxcbiAgICAgICAgICAgIG9wcG9zaXRlQmluZGluZ0JvdW5kRWxlbWVudD8uaWQsXG4gICAgICAgICAgICBob3ZlcmVkQmluZGFibGVFbGVtZW50LFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjLnB1c2goaG92ZXJlZEJpbmRhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICBbXSxcbiAgICApO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHN1Z2dlc3RlZEJpbmRpbmdzIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgbWF5YmVTdWdnZXN0QmluZGluZ0ZvckFsbChcbiAgICBzZWxlY3RlZEVsZW1lbnRzOiBOb25EZWxldGVkPEV4Y2FsaWRyYXdFbGVtZW50PltdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBzdWdnZXN0ZWRCaW5kaW5ncyA9IGdldEVsaWdpYmxlRWxlbWVudHNGb3JCaW5kaW5nKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBzdWdnZXN0ZWRCaW5kaW5ncyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTZWxlY3Rpb24oaGl0RWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zZXRTdGF0ZSgocHJldlN0YXRlKSA9PiAoe1xuICAgICAgc2VsZWN0ZWRFbGVtZW50SWRzOiB7fSxcbiAgICAgIHNlbGVjdGVkR3JvdXBJZHM6IHt9LFxuICAgICAgLy8gQ29udGludWUgZWRpdGluZyB0aGUgc2FtZSBncm91cCBpZiB0aGUgdXNlciBzZWxlY3RlZCBhIGRpZmZlcmVudFxuICAgICAgLy8gZWxlbWVudCBmcm9tIGl0XG4gICAgICBlZGl0aW5nR3JvdXBJZDpcbiAgICAgICAgcHJldlN0YXRlLmVkaXRpbmdHcm91cElkICYmXG4gICAgICAgIGhpdEVsZW1lbnQgIT0gbnVsbCAmJlxuICAgICAgICBpc0VsZW1lbnRJbkdyb3VwKGhpdEVsZW1lbnQsIHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZClcbiAgICAgICAgICA/IHByZXZTdGF0ZS5lZGl0aW5nR3JvdXBJZFxuICAgICAgICAgIDogbnVsbCxcbiAgICB9KSk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHM6IHRoaXMuc3RhdGUuc2VsZWN0ZWRFbGVtZW50SWRzLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXNSZWYgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4ge1xuICAgIC8vIGNhbnZhcyBpcyBudWxsIHdoZW4gdW5tb3VudGluZ1xuICAgIGlmIChjYW52YXMgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgdGhpcy5yYyA9IHJvdWdoLmNhbnZhcyh0aGlzLmNhbnZhcyk7XG5cbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuV0hFRUwsIHRoaXMuaGFuZGxlV2hlZWwsIHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfU1RBUlQsIHRoaXMub25UYXBTdGFydCk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX0VORCwgdGhpcy5vblRhcEVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULldIRUVMLCB0aGlzLmhhbmRsZVdoZWVsKTtcbiAgICAgIHRoaXMuY2FudmFzPy5yZW1vdmVFdmVudExpc3RlbmVyKEVWRU5ULlRPVUNIX1NUQVJULCB0aGlzLm9uVGFwU3RhcnQpO1xuICAgICAgdGhpcy5jYW52YXM/LnJlbW92ZUV2ZW50TGlzdGVuZXIoRVZFTlQuVE9VQ0hfRU5ELCB0aGlzLm9uVGFwRW5kKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVBcHBPbkRyb3AgPSBhc3luYyAoZXZlbnQ6IFJlYWN0LkRyYWdFdmVudDxIVE1MRGl2RWxlbWVudD4pID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZmlsZSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5maWxlc1swXTtcblxuICAgICAgaWYgKGlzU3VwcG9ydGVkSW1hZ2VGaWxlKGZpbGUpKSB7XG4gICAgICAgIC8vIGZpcnN0IGF0dGVtcHQgdG8gZGVjb2RlIHNjZW5lIGZyb20gdGhlIGltYWdlIGlmIGl0J3MgZW1iZWRkZWRcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgICAgaWYgKGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMucG5nIHx8IGZpbGU/LnR5cGUgPT09IE1JTUVfVFlQRVMuc3ZnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVGaWxlU3lzdGVtU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyB3aWxsIG9ubHkgd29yayBhcyBvZiBDaHJvbWUgODYsXG4gICAgICAgICAgICAgICAgLy8gYnV0IGNhbiBiZSBzYWZlbHkgaWdub3JlZCBvbiBvbGRlciByZWxlYXNlcy5cbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gZXZlbnQuZGF0YVRyYW5zZmVyLml0ZW1zWzBdO1xuICAgICAgICAgICAgICAgIChmaWxlIGFzIGFueSkuaGFuZGxlID0gYXdhaXQgKFxuICAgICAgICAgICAgICAgICAgaXRlbSBhcyBhbnlcbiAgICAgICAgICAgICAgICApLmdldEFzRmlsZVN5c3RlbUhhbmRsZSgpO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm5hbWUsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNjZW5lID0gYXdhaXQgbG9hZEZyb21CbG9iKFxuICAgICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgICB0aGlzLnN0YXRlLFxuICAgICAgICAgICAgICB0aGlzLnNjZW5lLmdldEVsZW1lbnRzSW5jbHVkaW5nRGVsZXRlZCgpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuc3luY0FjdGlvblJlc3VsdCh7XG4gICAgICAgICAgICAgIC4uLnNjZW5lLFxuICAgICAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgICAgIC4uLihzY2VuZS5hcHBTdGF0ZSB8fCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICAgICAgICBpc0xvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICByZXBsYWNlRmlsZXM6IHRydWUsXG4gICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIGlmIChlcnJvci5uYW1lICE9PSBcIkVuY29kaW5nRXJyb3JcIikge1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBubyBzY2VuZSBpcyBlbWJlZGRlZCBvciB3ZSBmYWlsIGZvciB3aGF0ZXZlciByZWFzb24sIGZhbGwgYmFja1xuICAgICAgICAvLyB0byBpbXBvcnRpbmcgYXMgcmVndWxhciBpbWFnZVxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgICAgICBjb25zdCB7IHg6IHNjZW5lWCwgeTogc2NlbmVZIH0gPSB2aWV3cG9ydENvb3Jkc1RvU2NlbmVDb29yZHMoXG4gICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgdGhpcy5zdGF0ZSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBpbWFnZUVsZW1lbnQgPSB0aGlzLmNyZWF0ZUltYWdlRWxlbWVudCh7IHNjZW5lWCwgc2NlbmVZIH0pO1xuICAgICAgICB0aGlzLmluc2VydEltYWdlRWxlbWVudChpbWFnZUVsZW1lbnQsIGZpbGUpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVJbWFnZURpbWVuc2lvbnMoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRWxlbWVudElkczogeyBbaW1hZ2VFbGVtZW50LmlkXTogdHJ1ZSB9IH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGlzTG9hZGluZzogZmFsc2UsXG4gICAgICAgIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGxpYnJhcnlTaGFwZXMgPSBldmVudC5kYXRhVHJhbnNmZXIuZ2V0RGF0YShNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIpO1xuICAgIGlmIChsaWJyYXJ5U2hhcGVzICE9PSBcIlwiKSB7XG4gICAgICB0aGlzLmFkZEVsZW1lbnRzRnJvbVBhc3RlT3JMaWJyYXJ5KHtcbiAgICAgICAgZWxlbWVudHM6IEpTT04ucGFyc2UobGlicmFyeVNoYXBlcyksXG4gICAgICAgIHBvc2l0aW9uOiBldmVudCxcbiAgICAgICAgZmlsZXM6IG51bGwsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlID0gZXZlbnQuZGF0YVRyYW5zZmVyPy5maWxlc1swXTtcbiAgICBpZiAoXG4gICAgICBmaWxlPy50eXBlID09PSBNSU1FX1RZUEVTLmV4Y2FsaWRyYXdsaWIgfHxcbiAgICAgIGZpbGU/Lm5hbWU/LmVuZHNXaXRoKFwiLmV4Y2FsaWRyYXdsaWJcIilcbiAgICApIHtcbiAgICAgIHRoaXMubGlicmFyeVxuICAgICAgICAuaW1wb3J0TGlicmFyeShmaWxlKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gQ2xvc2UgYW5kIHRoZW4gb3BlbiB0byBnZXQgdGhlIGxpYnJhcmllcyB1cGRhdGVkXG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTGlicmFyeU9wZW46IGZhbHNlIH0pO1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xpYnJhcnlPcGVuOiB0cnVlIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PlxuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IGZhbHNlLCBlcnJvck1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSksXG4gICAgICAgICk7XG4gICAgICAvLyBkZWZhdWx0OiBhc3N1bWUgYW4gRXhjYWxpZHJhdyBmaWxlIHJlZ2FyZGxlc3Mgb2YgZXh0ZW5zaW9uL01pbWVUeXBlXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc0xvYWRpbmc6IHRydWUgfSk7XG4gICAgICBpZiAobmF0aXZlRmlsZVN5c3RlbVN1cHBvcnRlZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IHdvcmsgYXMgb2YgQ2hyb21lIDg2LFxuICAgICAgICAgIC8vIGJ1dCBjYW4gYmUgc2FmZWx5IGlnbm9yZWQgb24gb2xkZXIgcmVsZWFzZXMuXG4gICAgICAgICAgY29uc3QgaXRlbSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5pdGVtc1swXTtcbiAgICAgICAgICAoZmlsZSBhcyBhbnkpLmhhbmRsZSA9IGF3YWl0IChpdGVtIGFzIGFueSkuZ2V0QXNGaWxlU3lzdGVtSGFuZGxlKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IubmFtZSwgZXJyb3IubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMubG9hZEZpbGVUb0NhbnZhcyhmaWxlKTtcbiAgICB9XG4gIH07XG5cbiAgbG9hZEZpbGVUb0NhbnZhcyA9IChmaWxlOiBCbG9iKSA9PiB7XG4gICAgbG9hZEZyb21CbG9iKGZpbGUsIHRoaXMuc3RhdGUsIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCkpXG4gICAgICAudGhlbigoc2NlbmUpID0+IHtcbiAgICAgICAgdGhpcy5zeW5jQWN0aW9uUmVzdWx0KHtcbiAgICAgICAgICAuLi5zY2VuZSxcbiAgICAgICAgICBhcHBTdGF0ZToge1xuICAgICAgICAgICAgLi4uKHNjZW5lLmFwcFN0YXRlIHx8IHRoaXMuc3RhdGUpLFxuICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcGxhY2VGaWxlczogdHJ1ZSxcbiAgICAgICAgICBjb21taXRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzTG9hZGluZzogZmFsc2UsIGVycm9yTWVzc2FnZTogZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgPSAoXG4gICAgZXZlbnQ6IFJlYWN0LlBvaW50ZXJFdmVudDxIVE1MQ2FudmFzRWxlbWVudD4sXG4gICkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCB7IHgsIHkgfSA9IHZpZXdwb3J0Q29vcmRzVG9TY2VuZUNvb3JkcyhldmVudCwgdGhpcy5zdGF0ZSk7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudEF0UG9zaXRpb24oeCwgeSwgeyBwcmVmZXJTZWxlY3RlZDogdHJ1ZSB9KTtcblxuICAgIGNvbnN0IHR5cGUgPSBlbGVtZW50ID8gXCJlbGVtZW50XCIgOiBcImNhbnZhc1wiO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhO1xuICAgIGNvbnN0IHsgdG9wOiBvZmZzZXRUb3AsIGxlZnQ6IG9mZnNldExlZnQgfSA9XG4gICAgICBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgbGVmdCA9IGV2ZW50LmNsaWVudFggLSBvZmZzZXRMZWZ0O1xuICAgIGNvbnN0IHRvcCA9IGV2ZW50LmNsaWVudFkgLSBvZmZzZXRUb3A7XG5cbiAgICBpZiAoZWxlbWVudCAmJiAhdGhpcy5zdGF0ZS5zZWxlY3RlZEVsZW1lbnRJZHNbZWxlbWVudC5pZF0pIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3RlZEVsZW1lbnRJZHM6IHsgW2VsZW1lbnQuaWRdOiB0cnVlIH0gfSwgKCkgPT4ge1xuICAgICAgICB0aGlzLl9vcGVuQ29udGV4dE1lbnUoeyB0b3AsIGxlZnQgfSwgdHlwZSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fb3BlbkNvbnRleHRNZW51KHsgdG9wLCBsZWZ0IH0sIHR5cGUpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlRHJhZ05ld0dlbmVyaWNFbGVtZW50ID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiB2b2lkID0+IHtcbiAgICBjb25zdCBkcmFnZ2luZ0VsZW1lbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nRWxlbWVudDtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGlmICghZHJhZ2dpbmdFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChkcmFnZ2luZ0VsZW1lbnQudHlwZSA9PT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgZHJhZ05ld0VsZW1lbnQoXG4gICAgICAgIGRyYWdnaW5nRWxlbWVudCxcbiAgICAgICAgdGhpcy5zdGF0ZS5lbGVtZW50VHlwZSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueCxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5vcmlnaW4ueSxcbiAgICAgICAgcG9pbnRlckNvb3Jkcy54LFxuICAgICAgICBwb2ludGVyQ29vcmRzLnksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLngsIHBvaW50ZXJDb29yZHMueCksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luLnksIHBvaW50ZXJDb29yZHMueSksXG4gICAgICAgIHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtncmlkWCwgZ3JpZFldID0gZ2V0R3JpZFBvaW50KFxuICAgICAgICBwb2ludGVyQ29vcmRzLngsXG4gICAgICAgIHBvaW50ZXJDb29yZHMueSxcbiAgICAgICAgdGhpcy5zdGF0ZS5ncmlkU2l6ZSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGltYWdlID1cbiAgICAgICAgaXNJbml0aWFsaXplZEltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpICYmXG4gICAgICAgIHRoaXMuaW1hZ2VDYWNoZS5nZXQoZHJhZ2dpbmdFbGVtZW50LmZpbGVJZCk/LmltYWdlO1xuICAgICAgY29uc3QgYXNwZWN0UmF0aW8gPVxuICAgICAgICBpbWFnZSAmJiAhKGltYWdlIGluc3RhbmNlb2YgUHJvbWlzZSlcbiAgICAgICAgICA/IGltYWdlLndpZHRoIC8gaW1hZ2UuaGVpZ2h0XG4gICAgICAgICAgOiBudWxsO1xuXG4gICAgICBkcmFnTmV3RWxlbWVudChcbiAgICAgICAgZHJhZ2dpbmdFbGVtZW50LFxuICAgICAgICB0aGlzLnN0YXRlLmVsZW1lbnRUeXBlLFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC54LFxuICAgICAgICBwb2ludGVyRG93blN0YXRlLm9yaWdpbkluR3JpZC55LFxuICAgICAgICBncmlkWCxcbiAgICAgICAgZ3JpZFksXG4gICAgICAgIGRpc3RhbmNlKHBvaW50ZXJEb3duU3RhdGUub3JpZ2luSW5HcmlkLngsIGdyaWRYKSxcbiAgICAgICAgZGlzdGFuY2UocG9pbnRlckRvd25TdGF0ZS5vcmlnaW5JbkdyaWQueSwgZ3JpZFkpLFxuICAgICAgICBpc0ltYWdlRWxlbWVudChkcmFnZ2luZ0VsZW1lbnQpXG4gICAgICAgICAgPyAhc2hvdWxkTWFpbnRhaW5Bc3BlY3RSYXRpbyhldmVudClcbiAgICAgICAgICA6IHNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpLFxuICAgICAgICBzaG91bGRSZXNpemVGcm9tQ2VudGVyKGV2ZW50KSxcbiAgICAgICAgYXNwZWN0UmF0aW8sXG4gICAgICApO1xuXG4gICAgICB0aGlzLm1heWJlU3VnZ2VzdEJpbmRpbmdGb3JBbGwoW2RyYWdnaW5nRWxlbWVudF0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIG1heWJlSGFuZGxlUmVzaXplID0gKFxuICAgIHBvaW50ZXJEb3duU3RhdGU6IFBvaW50ZXJEb3duU3RhdGUsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LFxuICApOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cyhcbiAgICAgIHRoaXMuc2NlbmUuZ2V0RWxlbWVudHMoKSxcbiAgICAgIHRoaXMuc3RhdGUsXG4gICAgKTtcbiAgICBjb25zdCB0cmFuc2Zvcm1IYW5kbGVUeXBlID0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuaGFuZGxlVHlwZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIFRPRE86IHJlbmFtZSB0aGlzIHN0YXRlIGZpZWxkIHRvIFwiaXNTY2FsaW5nXCIgdG8gZGlzdGluZ3Vpc2hcbiAgICAgIC8vIGl0IGZyb20gdGhlIGdlbmVyaWMgXCJpc1Jlc2l6aW5nXCIgd2hpY2ggaW5jbHVkZXMgc2NhbGluZyBhbmRcbiAgICAgIC8vIHJvdGF0aW5nXG4gICAgICBpc1Jlc2l6aW5nOiB0cmFuc2Zvcm1IYW5kbGVUeXBlICYmIHRyYW5zZm9ybUhhbmRsZVR5cGUgIT09IFwicm90YXRpb25cIixcbiAgICAgIGlzUm90YXRpbmc6IHRyYW5zZm9ybUhhbmRsZVR5cGUgPT09IFwicm90YXRpb25cIixcbiAgICB9KTtcbiAgICBjb25zdCBwb2ludGVyQ29vcmRzID0gcG9pbnRlckRvd25TdGF0ZS5sYXN0Q29vcmRzO1xuICAgIGNvbnN0IFtyZXNpemVYLCByZXNpemVZXSA9IGdldEdyaWRQb2ludChcbiAgICAgIHBvaW50ZXJDb29yZHMueCAtIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLm9mZnNldC54LFxuICAgICAgcG9pbnRlckNvb3Jkcy55IC0gcG9pbnRlckRvd25TdGF0ZS5yZXNpemUub2Zmc2V0LnksXG4gICAgICB0aGlzLnN0YXRlLmdyaWRTaXplLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMoXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUsXG4gICAgICAgIHRyYW5zZm9ybUhhbmRsZVR5cGUsXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmFycm93RGlyZWN0aW9uLFxuICAgICAgICBzaG91bGRSb3RhdGVXaXRoRGlzY3JldGVBbmdsZShldmVudCksXG4gICAgICAgIHNob3VsZFJlc2l6ZUZyb21DZW50ZXIoZXZlbnQpLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0ltYWdlRWxlbWVudChzZWxlY3RlZEVsZW1lbnRzWzBdKVxuICAgICAgICAgID8gIXNob3VsZE1haW50YWluQXNwZWN0UmF0aW8oZXZlbnQpXG4gICAgICAgICAgOiBzaG91bGRNYWludGFpbkFzcGVjdFJhdGlvKGV2ZW50KSxcbiAgICAgICAgcmVzaXplWCxcbiAgICAgICAgcmVzaXplWSxcbiAgICAgICAgcG9pbnRlckRvd25TdGF0ZS5yZXNpemUuY2VudGVyLngsXG4gICAgICAgIHBvaW50ZXJEb3duU3RhdGUucmVzaXplLmNlbnRlci55LFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhpcy5tYXliZVN1Z2dlc3RCaW5kaW5nRm9yQWxsKHNlbGVjdGVkRWxlbWVudHMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKiogQHByaXZhdGUgdXNlIHRoaXMuaGFuZGxlQ2FudmFzQ29udGV4dE1lbnUgKi9cbiAgcHJpdmF0ZSBfb3BlbkNvbnRleHRNZW51ID0gKFxuICAgIHtcbiAgICAgIGxlZnQsXG4gICAgICB0b3AsXG4gICAgfToge1xuICAgICAgbGVmdDogbnVtYmVyO1xuICAgICAgdG9wOiBudW1iZXI7XG4gICAgfSxcbiAgICB0eXBlOiBcImNhbnZhc1wiIHwgXCJlbGVtZW50XCIsXG4gICkgPT4ge1xuICAgIGNvbnN0IG1heWJlR3JvdXBBY3Rpb24gPSBhY3Rpb25Hcm91cC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVVbmdyb3VwQWN0aW9uID0gYWN0aW9uVW5ncm91cC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3QgbWF5YmVGbGlwSG9yaXpvbnRhbCA9IGFjdGlvbkZsaXBIb3Jpem9udGFsLmNvbnRleHRJdGVtUHJlZGljYXRlIShcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKSxcbiAgICAgIHRoaXMuYWN0aW9uTWFuYWdlci5nZXRBcHBTdGF0ZSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBtYXliZUZsaXBWZXJ0aWNhbCA9IGFjdGlvbkZsaXBWZXJ0aWNhbC5jb250ZXh0SXRlbVByZWRpY2F0ZSEoXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKCksXG4gICAgICB0aGlzLmFjdGlvbk1hbmFnZXIuZ2V0QXBwU3RhdGUoKSxcbiAgICApO1xuXG4gICAgY29uc3Qgc2VwYXJhdG9yID0gXCJzZXBhcmF0b3JcIjtcblxuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5zY2VuZS5nZXRFbGVtZW50cygpO1xuXG4gICAgY29uc3Qgb3B0aW9uczogQ29udGV4dE1lbnVPcHRpb25bXSA9IFtdO1xuICAgIGlmIChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBvcHRpb25zLnB1c2goYWN0aW9uQ29weUFzUG5nKTtcbiAgICB9XG5cbiAgICBpZiAocHJvYmFibHlTdXBwb3J0c0NsaXBib2FyZFdyaXRlVGV4dCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBvcHRpb25zLnB1c2goYWN0aW9uQ29weUFzU3ZnKTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwiY2FudmFzXCIpIHtcbiAgICAgIGNvbnN0IHZpZXdNb2RlT3B0aW9ucyA9IFtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMuZ3JpZE1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnplbk1vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmIGFjdGlvblRvZ2dsZVplbk1vZGUsXG4gICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLnZpZXdNb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICBhY3Rpb25Ub2dnbGVTdGF0cyxcbiAgICAgIF07XG5cbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiB2aWV3TW9kZU9wdGlvbnMsXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgYWN0aW9uTWFuYWdlcjogdGhpcy5hY3Rpb25NYW5hZ2VyLFxuICAgICAgICAgIGFwcFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgICAgIGNvbnRhaW5lcjogdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQhLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIENvbnRleHRNZW51LnB1c2goe1xuICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiZcbiAgICAgICAgICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJwYXN0ZVwiLFxuICAgICAgICAgICAgICAgIHBlcmZvcm06IChlbGVtZW50cywgYXBwU3RhdGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZChudWxsKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29udGV4dEl0ZW1MYWJlbDogXCJsYWJlbHMucGFzdGVcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiYgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiBzZXBhcmF0b3IsXG4gICAgICAgICAgICBwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkQmxvYiAmJlxuICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgIGFjdGlvbkNvcHlBc1BuZyxcbiAgICAgICAgICAgIHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRXcml0ZVRleHQgJiZcbiAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBhY3Rpb25Db3B5QXNTdmcsXG4gICAgICAgICAgICAoKHByb2JhYmx5U3VwcG9ydHNDbGlwYm9hcmRCbG9iICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApIHx8XG4gICAgICAgICAgICAgIChwcm9iYWJseVN1cHBvcnRzQ2xpcGJvYXJkV3JpdGVUZXh0ICYmIGVsZW1lbnRzLmxlbmd0aCA+IDApKSAmJlxuICAgICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICBhY3Rpb25TZWxlY3RBbGwsXG4gICAgICAgICAgICBzZXBhcmF0b3IsXG4gICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy5ncmlkTW9kZUVuYWJsZWQgPT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgYWN0aW9uVG9nZ2xlR3JpZE1vZGUsXG4gICAgICAgICAgICB0eXBlb2YgdGhpcy5wcm9wcy56ZW5Nb2RlRW5hYmxlZCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICBhY3Rpb25Ub2dnbGVaZW5Nb2RlLFxuICAgICAgICAgICAgdHlwZW9mIHRoaXMucHJvcHMudmlld01vZGVFbmFibGVkID09PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgIGFjdGlvblRvZ2dsZVZpZXdNb2RlLFxuICAgICAgICAgICAgYWN0aW9uVG9nZ2xlU3RhdHMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJlbGVtZW50XCIpIHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLnZpZXdNb2RlRW5hYmxlZCkge1xuICAgICAgICBDb250ZXh0TWVudS5wdXNoKHtcbiAgICAgICAgICBvcHRpb25zOiBbbmF2aWdhdG9yLmNsaXBib2FyZCAmJiBhY3Rpb25Db3B5LCAuLi5vcHRpb25zXSxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgQ29udGV4dE1lbnUucHVzaCh7XG4gICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgdGhpcy5pc01vYmlsZSAmJiBhY3Rpb25DdXQsXG4gICAgICAgICAgICB0aGlzLmlzTW9iaWxlICYmIG5hdmlnYXRvci5jbGlwYm9hcmQgJiYgYWN0aW9uQ29weSxcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiZcbiAgICAgICAgICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZCAmJiB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJwYXN0ZVwiLFxuICAgICAgICAgICAgICAgIHBlcmZvcm06IChlbGVtZW50cywgYXBwU3RhdGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnBhc3RlRnJvbUNsaXBib2FyZChudWxsKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1pdFRvSGlzdG9yeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29udGV4dEl0ZW1MYWJlbDogXCJsYWJlbHMucGFzdGVcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXMuaXNNb2JpbGUgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIGFjdGlvbkNvcHlTdHlsZXMsXG4gICAgICAgICAgICBhY3Rpb25QYXN0ZVN0eWxlcyxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIG1heWJlR3JvdXBBY3Rpb24gJiYgYWN0aW9uR3JvdXAsXG4gICAgICAgICAgICBtYXliZVVuZ3JvdXBBY3Rpb24gJiYgYWN0aW9uVW5ncm91cCxcbiAgICAgICAgICAgIChtYXliZUdyb3VwQWN0aW9uIHx8IG1heWJlVW5ncm91cEFjdGlvbikgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uQWRkVG9MaWJyYXJ5LFxuICAgICAgICAgICAgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uU2VuZEJhY2t3YXJkLFxuICAgICAgICAgICAgYWN0aW9uQnJpbmdGb3J3YXJkLFxuICAgICAgICAgICAgYWN0aW9uU2VuZFRvQmFjayxcbiAgICAgICAgICAgIGFjdGlvbkJyaW5nVG9Gcm9udCxcbiAgICAgICAgICAgIHNlcGFyYXRvcixcbiAgICAgICAgICAgIG1heWJlRmxpcEhvcml6b250YWwgJiYgYWN0aW9uRmxpcEhvcml6b250YWwsXG4gICAgICAgICAgICBtYXliZUZsaXBWZXJ0aWNhbCAmJiBhY3Rpb25GbGlwVmVydGljYWwsXG4gICAgICAgICAgICAobWF5YmVGbGlwSG9yaXpvbnRhbCB8fCBtYXliZUZsaXBWZXJ0aWNhbCkgJiYgc2VwYXJhdG9yLFxuICAgICAgICAgICAgYWN0aW9uRHVwbGljYXRlU2VsZWN0aW9uLFxuICAgICAgICAgICAgYWN0aW9uRGVsZXRlU2VsZWN0ZWQsXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0b3AsXG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICBhY3Rpb25NYW5hZ2VyOiB0aGlzLmFjdGlvbk1hbmFnZXIsXG4gICAgICAgICAgYXBwU3RhdGU6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgY29udGFpbmVyOiB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudCEsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVdoZWVsID0gd2l0aEJhdGNoZWRVcGRhdGVzKChldmVudDogV2hlZWxFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAoaXNQYW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBkZWx0YVgsIGRlbHRhWSB9ID0gZXZlbnQ7XG4gICAgY29uc3QgeyBzZWxlY3RlZEVsZW1lbnRJZHMsIHByZXZpb3VzU2VsZWN0ZWRFbGVtZW50SWRzIH0gPSB0aGlzLnN0YXRlO1xuICAgIC8vIG5vdGUgdGhhdCBldmVudC5jdHJsS2V5IGlzIG5lY2Vzc2FyeSB0byBoYW5kbGUgcGluY2ggem9vbWluZ1xuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIGNvbnN0IHNpZ24gPSBNYXRoLnNpZ24oZGVsdGFZKTtcbiAgICAgIGNvbnN0IE1BWF9TVEVQID0gMTA7XG4gICAgICBsZXQgZGVsdGEgPSBNYXRoLmFicyhkZWx0YVkpO1xuICAgICAgaWYgKGRlbHRhID4gTUFYX1NURVApIHtcbiAgICAgICAgZGVsdGEgPSBNQVhfU1RFUDtcbiAgICAgIH1cbiAgICAgIGRlbHRhICo9IHNpZ247XG4gICAgICBpZiAoT2JqZWN0LmtleXMocHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkRWxlbWVudElkczogcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIDEwMDApO1xuICAgICAgfVxuXG4gICAgICBsZXQgbmV3Wm9vbSA9IHRoaXMuc3RhdGUuem9vbS52YWx1ZSAtIGRlbHRhIC8gMTAwO1xuICAgICAgLy8gaW5jcmVhc2Ugem9vbSBzdGVwcyB0aGUgbW9yZSB6b29tZWQtaW4gd2UgYXJlIChhcHBsaWVzIHRvID4xMDAlIG9ubHkpXG4gICAgICBuZXdab29tICs9IE1hdGgubG9nMTAoTWF0aC5tYXgoMSwgdGhpcy5zdGF0ZS56b29tLnZhbHVlKSkgKiAtc2lnbjtcbiAgICAgIC8vIHJvdW5kIHRvIG5lYXJlc3Qgc3RlcFxuICAgICAgbmV3Wm9vbSA9IE1hdGgucm91bmQobmV3Wm9vbSAqIFpPT01fU1RFUCAqIDEwMCkgLyAoWk9PTV9TVEVQICogMTAwKTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBvZmZzZXRMZWZ0LCBvZmZzZXRUb3AgfSkgPT4gKHtcbiAgICAgICAgem9vbTogZ2V0TmV3Wm9vbShcbiAgICAgICAgICBnZXROb3JtYWxpemVkWm9vbShuZXdab29tKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIHsgbGVmdDogb2Zmc2V0TGVmdCwgdG9wOiBvZmZzZXRUb3AgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4OiBjdXJzb3JYLFxuICAgICAgICAgICAgeTogY3Vyc29yWSxcbiAgICAgICAgICB9LFxuICAgICAgICApLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRJZHM6IHt9LFxuICAgICAgICBwcmV2aW91c1NlbGVjdGVkRWxlbWVudElkczpcbiAgICAgICAgICBPYmplY3Qua2V5cyhzZWxlY3RlZEVsZW1lbnRJZHMpLmxlbmd0aCAhPT0gMFxuICAgICAgICAgICAgPyBzZWxlY3RlZEVsZW1lbnRJZHNcbiAgICAgICAgICAgIDogcHJldmlvdXNTZWxlY3RlZEVsZW1lbnRJZHMsXG4gICAgICAgIHNob3VsZENhY2hlSWdub3JlWm9vbTogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMucmVzZXRTaG91bGRDYWNoZUlnbm9yZVpvb21EZWJvdW5jZWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzY3JvbGwgaG9yaXpvbnRhbGx5IHdoZW4gc2hpZnQgcHJlc3NlZFxuICAgIGlmIChldmVudC5zaGlmdEtleSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSgoeyB6b29tLCBzY3JvbGxYIH0pID0+ICh7XG4gICAgICAgIC8vIG9uIE1hYywgc2hpZnQrd2hlZWwgdGVuZHMgdG8gcmVzdWx0IGluIGRlbHRhWFxuICAgICAgICBzY3JvbGxYOiBzY3JvbGxYIC0gKGRlbHRhWSB8fCBkZWx0YVgpIC8gem9vbS52YWx1ZSxcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldFN0YXRlKCh7IHpvb20sIHNjcm9sbFgsIHNjcm9sbFkgfSkgPT4gKHtcbiAgICAgIHNjcm9sbFg6IHNjcm9sbFggLSBkZWx0YVggLyB6b29tLnZhbHVlLFxuICAgICAgc2Nyb2xsWTogc2Nyb2xsWSAtIGRlbHRhWSAvIHpvb20udmFsdWUsXG4gICAgfSkpO1xuICB9KTtcblxuICBwcml2YXRlIGdldFRleHRXeXNpd3lnU25hcHBlZFRvQ2VudGVyUG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gICAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwsXG4gICAgc2NhbGU6IG51bWJlcixcbiAgKSB7XG4gICAgY29uc3QgZWxlbWVudENsaWNrZWRJbnNpZGUgPSBnZXRFbGVtZW50Q29udGFpbmluZ1Bvc2l0aW9uKFxuICAgICAgdGhpcy5zY2VuZVxuICAgICAgICAuZ2V0RWxlbWVudHNJbmNsdWRpbmdEZWxldGVkKClcbiAgICAgICAgLmZpbHRlcigoZWxlbWVudCkgPT4gIWlzVGV4dEVsZW1lbnQoZWxlbWVudCkpLFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgKTtcbiAgICBpZiAoZWxlbWVudENsaWNrZWRJbnNpZGUpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRDZW50ZXJYID1cbiAgICAgICAgZWxlbWVudENsaWNrZWRJbnNpZGUueCArIGVsZW1lbnRDbGlja2VkSW5zaWRlLndpZHRoIC8gMjtcbiAgICAgIGNvbnN0IGVsZW1lbnRDZW50ZXJZID1cbiAgICAgICAgZWxlbWVudENsaWNrZWRJbnNpZGUueSArIGVsZW1lbnRDbGlja2VkSW5zaWRlLmhlaWdodCAvIDI7XG4gICAgICBjb25zdCBkaXN0YW5jZVRvQ2VudGVyID0gTWF0aC5oeXBvdChcbiAgICAgICAgeCAtIGVsZW1lbnRDZW50ZXJYLFxuICAgICAgICB5IC0gZWxlbWVudENlbnRlclksXG4gICAgICApO1xuICAgICAgY29uc3QgaXNTbmFwcGVkVG9DZW50ZXIgPVxuICAgICAgICBkaXN0YW5jZVRvQ2VudGVyIDwgVEVYVF9UT19DRU5URVJfU05BUF9USFJFU0hPTEQ7XG4gICAgICBpZiAoaXNTbmFwcGVkVG9DZW50ZXIpIHtcbiAgICAgICAgY29uc3QgeyB4OiB2aWV3cG9ydFgsIHk6IHZpZXdwb3J0WSB9ID0gc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzKFxuICAgICAgICAgIHsgc2NlbmVYOiBlbGVtZW50Q2VudGVyWCwgc2NlbmVZOiBlbGVtZW50Q2VudGVyWSB9LFxuICAgICAgICAgIGFwcFN0YXRlLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4geyB2aWV3cG9ydFgsIHZpZXdwb3J0WSwgZWxlbWVudENlbnRlclgsIGVsZW1lbnRDZW50ZXJZIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlUG9pbnRlciA9ICh4OiBudW1iZXIsIHk6IG51bWJlciwgYnV0dG9uOiBcInVwXCIgfCBcImRvd25cIikgPT4ge1xuICAgIGlmICgheCB8fCAheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwb2ludGVyID0gdmlld3BvcnRDb29yZHNUb1NjZW5lQ29vcmRzKFxuICAgICAgeyBjbGllbnRYOiB4LCBjbGllbnRZOiB5IH0sXG4gICAgICB0aGlzLnN0YXRlLFxuICAgICk7XG5cbiAgICBpZiAoaXNOYU4ocG9pbnRlci54KSB8fCBpc05hTihwb2ludGVyLnkpKSB7XG4gICAgICAvLyBzb21ldGltZXMgdGhlIHBvaW50ZXIgZ29lcyBvZmYgc2NyZWVuXG4gICAgfVxuXG4gICAgdGhpcy5wcm9wcy5vblBvaW50ZXJVcGRhdGU/Lih7XG4gICAgICBwb2ludGVyLFxuICAgICAgYnV0dG9uLFxuICAgICAgcG9pbnRlcnNNYXA6IGdlc3R1cmUucG9pbnRlcnMsXG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZXNldFNob3VsZENhY2hlSWdub3JlWm9vbURlYm91bmNlZCA9IGRlYm91bmNlKCgpID0+IHtcbiAgICBpZiAoIXRoaXMudW5tb3VudGVkKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc2hvdWxkQ2FjaGVJZ25vcmVab29tOiBmYWxzZSB9KTtcbiAgICB9XG4gIH0sIDMwMCk7XG5cbiAgcHJpdmF0ZSB1cGRhdGVET01SZWN0ID0gKGNiPzogKCkgPT4gdm9pZCkgPT4ge1xuICAgIGlmICh0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWY/LmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGV4Y2FsaWRyYXdDb250YWluZXIgPSB0aGlzLmV4Y2FsaWRyYXdDb250YWluZXJSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgbGVmdDogb2Zmc2V0TGVmdCxcbiAgICAgICAgdG9wOiBvZmZzZXRUb3AsXG4gICAgICB9ID0gZXhjYWxpZHJhd0NvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGg6IGN1cnJlbnRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiBjdXJyZW50SGVpZ2h0LFxuICAgICAgICBvZmZzZXRUb3A6IGN1cnJlbnRPZmZzZXRUb3AsXG4gICAgICAgIG9mZnNldExlZnQ6IGN1cnJlbnRPZmZzZXRMZWZ0LFxuICAgICAgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICAgIGlmIChcbiAgICAgICAgd2lkdGggPT09IGN1cnJlbnRXaWR0aCAmJlxuICAgICAgICBoZWlnaHQgPT09IGN1cnJlbnRIZWlnaHQgJiZcbiAgICAgICAgb2Zmc2V0TGVmdCA9PT0gY3VycmVudE9mZnNldExlZnQgJiZcbiAgICAgICAgb2Zmc2V0VG9wID09PSBjdXJyZW50T2Zmc2V0VG9wXG4gICAgICApIHtcbiAgICAgICAgaWYgKGNiKSB7XG4gICAgICAgICAgY2IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgb2Zmc2V0TGVmdCxcbiAgICAgICAgICBvZmZzZXRUb3AsXG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBjYiAmJiBjYigpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgcHVibGljIHJlZnJlc2ggPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IC4uLnRoaXMuZ2V0Q2FudmFzT2Zmc2V0cygpIH0pO1xuICB9O1xuXG4gIHByaXZhdGUgZ2V0Q2FudmFzT2Zmc2V0cygpOiBQaWNrPEFwcFN0YXRlLCBcIm9mZnNldFRvcFwiIHwgXCJvZmZzZXRMZWZ0XCI+IHtcbiAgICBpZiAodGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmPy5jdXJyZW50KSB7XG4gICAgICBjb25zdCBleGNhbGlkcmF3Q29udGFpbmVyID0gdGhpcy5leGNhbGlkcmF3Q29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB7IGxlZnQsIHRvcCB9ID0gZXhjYWxpZHJhd0NvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9mZnNldExlZnQ6IGxlZnQsXG4gICAgICAgIG9mZnNldFRvcDogdG9wLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG9mZnNldExlZnQ6IDAsXG4gICAgICBvZmZzZXRUb3A6IDAsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlTGFuZ3VhZ2UoKSB7XG4gICAgY29uc3QgY3VycmVudExhbmcgPVxuICAgICAgbGFuZ3VhZ2VzLmZpbmQoKGxhbmcpID0+IGxhbmcuY29kZSA9PT0gdGhpcy5wcm9wcy5sYW5nQ29kZSkgfHxcbiAgICAgIGRlZmF1bHRMYW5nO1xuICAgIGF3YWl0IHNldExhbmd1YWdlKGN1cnJlbnRMYW5nKTtcbiAgICB0aGlzLnNldEFwcFN0YXRlKHt9KTtcbiAgfVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVEVTVCBIT09LU1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZGVjbGFyZSBnbG9iYWwge1xuICBpbnRlcmZhY2UgV2luZG93IHtcbiAgICBoOiB7XG4gICAgICBlbGVtZW50czogcmVhZG9ubHkgRXhjYWxpZHJhd0VsZW1lbnRbXTtcbiAgICAgIHN0YXRlOiBBcHBTdGF0ZTtcbiAgICAgIHNldFN0YXRlOiBSZWFjdC5Db21wb25lbnQ8YW55LCBBcHBTdGF0ZT5bXCJzZXRTdGF0ZVwiXTtcbiAgICAgIGFwcDogSW5zdGFuY2VUeXBlPHR5cGVvZiBBcHA+O1xuICAgICAgaGlzdG9yeTogSGlzdG9yeTtcbiAgICB9O1xuICB9XG59XG5cbmlmIChcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IEVOVi5URVNUIHx8XG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBFTlYuREVWRUxPUE1FTlRcbikge1xuICB3aW5kb3cuaCA9IHdpbmRvdy5oIHx8ICh7fSBhcyBXaW5kb3dbXCJoXCJdKTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3cuaCwge1xuICAgIGVsZW1lbnRzOiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcC5zY2VuZS5nZXRFbGVtZW50c0luY2x1ZGluZ0RlbGV0ZWQoKTtcbiAgICAgIH0sXG4gICAgICBzZXQoZWxlbWVudHM6IEV4Y2FsaWRyYXdFbGVtZW50W10pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwLnNjZW5lLnJlcGxhY2VBbGxFbGVtZW50cyhlbGVtZW50cyk7XG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xufVxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../components/App.tsx\n");
1787
1787
 
1788
1788
  /***/ }),
1789
1789
 
@@ -2542,7 +2542,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
2542
2542
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2543
2543
 
2544
2544
  "use strict";
2545
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"textWysiwyg\": () => (/* binding */ textWysiwyg)\n/* harmony export */ });\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst normalizeText = (text) => {\r\n return (text\r\n // replace tabs with spaces so they render and measure correctly\r\n .replace(/\\t/g, \" \")\r\n // normalize newlines\r\n .replace(/\\r?\\n|\\r/g, \"\\n\"));\r\n};\r\nconst getTransform = (width, height, angle, appState, maxWidth, maxHeight) => {\r\n const { zoom, offsetTop, offsetLeft } = appState;\r\n const degree = (180 * angle) / Math.PI;\r\n // offsets must be multiplied by 2 to account for the division by 2 of\r\n // the whole expression afterwards\r\n let translateX = ((width - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n let translateY = ((height - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n if (width > maxWidth && zoom.value !== 1) {\r\n translateX = ((maxWidth - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n }\r\n if (height > maxHeight && zoom.value !== 1) {\r\n translateY = ((maxHeight - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n }\r\n return `translate(${translateX}px, ${translateY}px) scale(${zoom.value}) rotate(${degree}deg)`;\r\n};\r\nconst textWysiwyg = ({ id, appState, onChange, onSubmit, getViewportCoords, element, canvas, excalidrawContainer, }) => {\r\n const textPropertiesUpdated = (updatedElement, editable) => {\r\n const currentFont = editable.style.fontFamily.replaceAll('\"', \"\");\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontFamilyString)({ fontFamily: updatedElement.fontFamily }) !==\r\n currentFont) {\r\n return true;\r\n }\r\n if (`${updatedElement.fontSize}px` !== editable.style.fontSize) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n let originalContainerHeight;\r\n let approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(element)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(element))\r\n : 0;\r\n const updateWysiwygStyle = () => {\r\n var _a, _b;\r\n const updatedElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(id);\r\n if (updatedElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)) {\r\n let coordX = updatedElement.x;\r\n let coordY = updatedElement.y;\r\n let container = (updatedElement === null || updatedElement === void 0 ? void 0 : updatedElement.containerId)\r\n ? _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement).getElement(updatedElement.containerId)\r\n : null;\r\n let maxWidth = updatedElement.width;\r\n let maxHeight = updatedElement.height;\r\n let width = updatedElement.width;\r\n const height = editable.scrollHeight === 0\r\n ? updatedElement.height\r\n : editable.scrollHeight;\r\n if (container && updatedElement.containerId) {\r\n const propertiesUpdated = textPropertiesUpdated(updatedElement, editable);\r\n if (propertiesUpdated) {\r\n const currentContainer = (_b = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement)) === null || _b === void 0 ? void 0 : _b.getElement(updatedElement.containerId);\r\n approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement))\r\n : 0;\r\n if (updatedElement.height > currentContainer.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2) {\r\n const nextHeight = updatedElement.height + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n originalContainerHeight = nextHeight;\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: nextHeight });\r\n container = Object.assign(Object.assign({}, container), { height: nextHeight });\r\n }\r\n editable.style.height = `${updatedElement.height}px`;\r\n }\r\n if (!originalContainerHeight) {\r\n originalContainerHeight = container.height;\r\n }\r\n maxWidth = container.width - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n maxHeight = container.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n width = maxWidth;\r\n // The coordinates of text box set a distance of\r\n // 30px to preserve padding\r\n coordX = container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING;\r\n // autogrow container height if text exceeds\r\n if (editable.scrollHeight > maxHeight) {\r\n const diff = Math.min(editable.scrollHeight - maxHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height + diff });\r\n return;\r\n }\r\n else if (\r\n // autoshrink container height until original container height\r\n // is reached when text is removed\r\n container.height > originalContainerHeight &&\r\n editable.scrollHeight < maxHeight) {\r\n const diff = Math.min(maxHeight - editable.scrollHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height - diff });\r\n }\r\n // Start pushing text upward until a diff of 30px (padding)\r\n // is reached\r\n else {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n if (lines > 1 || propertiesUpdated) {\r\n // vertically center align the text\r\n coordY =\r\n container.y + container.height / 2 - editable.scrollHeight / 2;\r\n }\r\n }\r\n }\r\n const [viewportX, viewportY] = getViewportCoords(coordX, coordY);\r\n const { textAlign, angle } = updatedElement;\r\n editable.value = updatedElement.originalText || updatedElement.text;\r\n const lines = updatedElement.originalText.split(\"\\n\");\r\n const lineHeight = updatedElement.containerId\r\n ? approxLineHeight\r\n : updatedElement.height / lines.length;\r\n if (!container) {\r\n maxWidth =\r\n (appState.width + appState.offsetLeft - viewportX - 8) / appState.zoom.value -\r\n // margin-right of parent if any\r\n Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2));\r\n }\r\n // Make sure text editor height doesn't go beyond viewport\r\n const editorMaxHeight = (appState.height + appState.offsetTop - viewportY) / appState.zoom.value;\r\n console.log({\r\n maxWidth,\r\n editorMaxHeight,\r\n width,\r\n height,\r\n viewportX,\r\n viewportY,\r\n sceneX: coordX,\r\n sceneY: coordY,\r\n appWidth: appState.width,\r\n appHeight: appState.height,\r\n scrollX: appState.scrollX,\r\n scrollY: appState.scrollY,\r\n offsetTop: appState.offsetTop,\r\n offsetLeft: appState.offsetLeft,\r\n zoom: appState.zoom.value,\r\n translation: appState.zoom.translation,\r\n marginRight: Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2)),\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight)\r\n });\r\n Object.assign(editable.style, {\r\n font: (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement),\r\n // must be defined *after* font ¯\\_(ツ)_/¯\r\n lineHeight: `${lineHeight}px`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n left: `${viewportX}px`,\r\n top: `${viewportY}px`,\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight),\r\n textAlign,\r\n color: updatedElement.strokeColor,\r\n opacity: updatedElement.opacity / 100,\r\n filter: \"var(--theme-filter)\",\r\n maxWidth: `${maxWidth}px`,\r\n maxHeight: `${editorMaxHeight}px`,\r\n });\r\n }\r\n };\r\n const editable = document.createElement(\"textarea\");\r\n editable.dir = \"auto\";\r\n editable.tabIndex = 0;\r\n editable.dataset.type = \"wysiwyg\";\r\n // prevent line wrapping on Safari\r\n editable.wrap = \"off\";\r\n editable.classList.add(\"excalidraw-wysiwyg\");\r\n let whiteSpace = \"pre\";\r\n let wordBreak = \"normal\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element)) {\r\n whiteSpace = \"pre-wrap\";\r\n wordBreak = \"break-word\";\r\n }\r\n Object.assign(editable.style, {\r\n position: \"absolute\",\r\n display: \"inline-block\",\r\n minHeight: \"1em\",\r\n backfaceVisibility: \"hidden\",\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n outline: 0,\r\n resize: \"none\",\r\n background: \"transparent\",\r\n overflow: \"hidden\",\r\n // must be specified because in dark mode canvas creates a stacking context\r\n zIndex: \"var(--zIndex-wysiwyg)\",\r\n wordBreak,\r\n // prevent line wrapping (`whitespace: nowrap` doesn't work on FF)\r\n whiteSpace,\r\n overflowWrap: \"break-word\",\r\n });\r\n updateWysiwygStyle();\r\n if (onChange) {\r\n editable.oninput = () => {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n // auto increase height only when lines > 1 so its\r\n // measured correctly and vertically alignes for\r\n // first line as well as setting height to \"auto\"\r\n // doubles the height as soon as user starts typing\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element) && lines > 1) {\r\n editable.style.height = \"auto\";\r\n editable.style.height = `${editable.scrollHeight}px`;\r\n }\r\n onChange(normalizeText(editable.value));\r\n };\r\n }\r\n editable.onkeydown = (event) => {\r\n event.stopPropagation();\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ESCAPE) {\r\n event.preventDefault();\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ENTER && event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD]) {\r\n event.preventDefault();\r\n if (event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.TAB ||\r\n (event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD] &&\r\n (event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT ||\r\n event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_RIGHT))) {\r\n event.preventDefault();\r\n if (event.shiftKey || event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT) {\r\n outdent();\r\n }\r\n else {\r\n indent();\r\n }\r\n // We must send an input event to resize the element\r\n editable.dispatchEvent(new Event(\"input\"));\r\n }\r\n };\r\n const TAB_SIZE = 4;\r\n const TAB = \" \".repeat(TAB_SIZE);\r\n const RE_LEADING_TAB = new RegExp(`^ {1,${TAB_SIZE}}`);\r\n const indent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex);\r\n value = `${startValue}${TAB}${endValue}`;\r\n });\r\n editable.value = value;\r\n editable.selectionStart = selectionStart + TAB_SIZE;\r\n editable.selectionEnd = selectionEnd + TAB_SIZE * linesStartIndices.length;\r\n };\r\n const outdent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n const removedTabs = [];\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const tabMatch = value\r\n .slice(startIndex, startIndex + TAB_SIZE)\r\n .match(RE_LEADING_TAB);\r\n if (tabMatch) {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex + tabMatch[0].length);\r\n // Delete a tab from the line\r\n value = `${startValue}${endValue}`;\r\n removedTabs.push(startIndex);\r\n }\r\n });\r\n editable.value = value;\r\n if (removedTabs.length) {\r\n if (selectionStart > removedTabs[removedTabs.length - 1]) {\r\n editable.selectionStart = Math.max(selectionStart - TAB_SIZE, removedTabs[removedTabs.length - 1]);\r\n }\r\n else {\r\n // If the cursor is before the first tab removed, ex:\r\n // Line| #1\r\n // Line #2\r\n // Lin|e #3\r\n // we should reset the selectionStart to his initial value.\r\n editable.selectionStart = selectionStart;\r\n }\r\n editable.selectionEnd = Math.max(editable.selectionStart, selectionEnd - TAB_SIZE * removedTabs.length);\r\n }\r\n };\r\n /**\r\n * @returns indeces of start positions of selected lines, in reverse order\r\n */\r\n const getSelectedLinesStartIndices = () => {\r\n let { selectionStart, selectionEnd, value } = editable;\r\n // chars before selectionStart on the same line\r\n const startOffset = value.slice(0, selectionStart).match(/[^\\n]*$/)[0]\r\n .length;\r\n // put caret at the start of the line\r\n selectionStart = selectionStart - startOffset;\r\n const selected = value.slice(selectionStart, selectionEnd);\r\n return selected\r\n .split(\"\\n\")\r\n .reduce((startIndices, line, idx, lines) => startIndices.concat(idx\r\n ? // curr line index is prev line's start + prev line's length + \\n\r\n startIndices[idx - 1] + lines[idx - 1].length + 1\r\n : // first selected line\r\n selectionStart), [])\r\n .reverse();\r\n };\r\n const stopEvent = (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n // using a state variable instead of passing it to the handleSubmit callback\r\n // so that we don't need to create separate a callback for event handlers\r\n let submittedViaKeyboard = false;\r\n const handleSubmit = () => {\r\n var _a, _b;\r\n // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg\r\n // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the\r\n // wysiwyg on update\r\n cleanup();\r\n const updateElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.id);\r\n if (!updateElement) {\r\n return;\r\n }\r\n let wrappedText = \"\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && (updateElement === null || updateElement === void 0 ? void 0 : updateElement.containerId)) {\r\n const container = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updateElement).getElement(updateElement.containerId);\r\n if (container) {\r\n wrappedText = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.wrapText)(editable.value, (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updateElement), container.width);\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && updateElement.containerId) {\r\n const editorHeight = Number(editable.style.height.slice(0, -2));\r\n if (editable.value) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(updateElement, {\r\n // vertically center align\r\n y: container.y + container.height / 2 - editorHeight / 2,\r\n height: editorHeight,\r\n width: Number(editable.style.width.slice(0, -2)),\r\n // preserve padding\r\n x: container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING,\r\n });\r\n const boundTextElementId = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getBoundTextElementId)(container);\r\n if (!boundTextElementId || boundTextElementId !== element.id) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (container.boundElements || []).concat({\r\n type: \"text\",\r\n id: element.id,\r\n }),\r\n });\r\n }\r\n }\r\n else {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (_b = container.boundElements) === null || _b === void 0 ? void 0 : _b.filter((ele) => ele.type !== \"text\"),\r\n });\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n wrappedText = editable.value;\r\n }\r\n onSubmit({\r\n text: normalizeText(wrappedText),\r\n viaKeyboard: submittedViaKeyboard,\r\n originalText: editable.value,\r\n });\r\n };\r\n const cleanup = () => {\r\n if (isDestroyed) {\r\n return;\r\n }\r\n isDestroyed = true;\r\n // remove events to ensure they don't late-fire\r\n editable.onblur = null;\r\n editable.oninput = null;\r\n editable.onkeydown = null;\r\n if (observer) {\r\n observer.disconnect();\r\n }\r\n window.removeEventListener(\"resize\", updateWysiwygStyle);\r\n window.removeEventListener(\"wheel\", stopEvent, true);\r\n window.removeEventListener(\"pointerdown\", onPointerDown);\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n window.removeEventListener(\"blur\", handleSubmit);\r\n unbindUpdate();\r\n editable.remove();\r\n };\r\n const bindBlurEvent = (event) => {\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n // Deferred so that the pointerdown that initiates the wysiwyg doesn't\r\n // trigger the blur on ensuing pointerup.\r\n // Also to handle cases such as picking a color which would trigger a blur\r\n // in that same tick.\r\n const target = event === null || event === void 0 ? void 0 : event.target;\r\n const isTargetColorPicker = target instanceof HTMLInputElement &&\r\n target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(target);\r\n setTimeout(() => {\r\n editable.onblur = handleSubmit;\r\n if (target && isTargetColorPicker) {\r\n target.onblur = () => {\r\n editable.focus();\r\n };\r\n }\r\n // case: clicking on the same property → no change → no update → no focus\r\n if (!isTargetColorPicker) {\r\n editable.focus();\r\n }\r\n });\r\n };\r\n // prevent blur when changing properties from the menu\r\n const onPointerDown = (event) => {\r\n const isTargetColorPicker = event.target instanceof HTMLInputElement &&\r\n event.target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target);\r\n if (((event.target instanceof HTMLElement ||\r\n event.target instanceof SVGElement) &&\r\n event.target.closest(`.${_constants__WEBPACK_IMPORTED_MODULE_4__.CLASSES.SHAPE_ACTIONS_MENU}`) &&\r\n !(0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target)) ||\r\n isTargetColorPicker) {\r\n editable.onblur = null;\r\n window.addEventListener(\"pointerup\", bindBlurEvent);\r\n // handle edge-case where pointerup doesn't fire e.g. due to user\r\n // alt-tabbing away\r\n window.addEventListener(\"blur\", handleSubmit);\r\n }\r\n };\r\n // handle updates of textElement properties of editing element\r\n const unbindUpdate = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element).addCallback(() => {\r\n var _a;\r\n updateWysiwygStyle();\r\n const isColorPickerActive = !!((_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest(\".color-picker-input\"));\r\n if (!isColorPickerActive) {\r\n editable.focus();\r\n }\r\n });\r\n // ---------------------------------------------------------------------------\r\n let isDestroyed = false;\r\n // select on init (focusing is done separately inside the bindBlurEvent()\r\n // because we need it to happen *after* the blur event from `pointerdown`)\r\n editable.select();\r\n bindBlurEvent();\r\n // reposition wysiwyg in case of canvas is resized. Using ResizeObserver\r\n // is preferred so we catch changes from host, where window may not resize.\r\n let observer = null;\r\n if (canvas && \"ResizeObserver\" in window) {\r\n observer = new window.ResizeObserver(() => {\r\n updateWysiwygStyle();\r\n });\r\n observer.observe(canvas);\r\n }\r\n else {\r\n window.addEventListener(\"resize\", updateWysiwygStyle);\r\n }\r\n window.addEventListener(\"pointerdown\", onPointerDown);\r\n window.addEventListener(\"wheel\", stopEvent, {\r\n passive: false,\r\n capture: true,\r\n });\r\n excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.querySelector(\".excalidraw-textEditorContainer\").appendChild(editable);\r\n};\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFNO1FBQ0wsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0tBQ3ZEO0lBRUQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN0RCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRTtRQUMxQyxPQUFPLEVBQUUsS0FBSztRQUNkLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQyxDQUFDO0lBQ0gsbUJBQW1CLGFBQW5CLG1CQUFtQix1QkFBbkIsbUJBQW1CLENBQ2YsYUFBYSxDQUFDLGlDQUFpQyxFQUNoRCxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDM0IsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uL2VsZW1lbnQvdGV4dFd5c2l3eWcudHN4PzhmNGQiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09ERVMsIEtFWVMgfSBmcm9tIFwiLi4va2V5c1wiO1xuaW1wb3J0IHtcbiAgaXNXcml0YWJsZUVsZW1lbnQsXG4gIGdldEZvbnRTdHJpbmcsXG4gIGdldEZvbnRGYW1pbHlTdHJpbmcsXG4gIHNjZW5lQ29vcmRzVG9WaWV3cG9ydENvb3Jkcyxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgU2NlbmUgZnJvbSBcIi4uL3NjZW5lL1NjZW5lXCI7XG5pbXBvcnQgeyBpc0JvdW5kVG9Db250YWluZXIsIGlzVGV4dEVsZW1lbnQgfSBmcm9tIFwiLi90eXBlQ2hlY2tzXCI7XG5pbXBvcnQgeyBDTEFTU0VTLCBQQURESU5HIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudCxcbiAgRXhjYWxpZHJhd0VsZW1lbnQsXG4gIEV4Y2FsaWRyYXdUZXh0RWxlbWVudCxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IEFwcFN0YXRlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBtdXRhdGVFbGVtZW50IH0gZnJvbSBcIi4vbXV0YXRlRWxlbWVudFwiO1xuaW1wb3J0IHtcbiAgZ2V0QXBwcm94TGluZUhlaWdodCxcbiAgZ2V0Qm91bmRUZXh0RWxlbWVudElkLFxuICB3cmFwVGV4dCxcbn0gZnJvbSBcIi4vdGV4dEVsZW1lbnRcIjtcblxuY29uc3Qgbm9ybWFsaXplVGV4dCA9ICh0ZXh0OiBzdHJpbmcpID0+IHtcbiAgcmV0dXJuIChcbiAgICB0ZXh0XG4gICAgICAvLyByZXBsYWNlIHRhYnMgd2l0aCBzcGFjZXMgc28gdGhleSByZW5kZXIgYW5kIG1lYXN1cmUgY29ycmVjdGx5XG4gICAgICAucmVwbGFjZSgvXFx0L2csIFwiICAgICAgICBcIilcbiAgICAgIC8vIG5vcm1hbGl6ZSBuZXdsaW5lc1xuICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFwiXFxuXCIpXG4gICk7XG59O1xuXG5jb25zdCBnZXRUcmFuc2Zvcm0gPSAoXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBhbmdsZTogbnVtYmVyLFxuICBhcHBTdGF0ZTogQXBwU3RhdGUsXG4gIG1heFdpZHRoOiBudW1iZXIsXG4gIG1heEhlaWdodDogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IHsgem9vbSwgb2Zmc2V0VG9wLCBvZmZzZXRMZWZ0IH0gPSBhcHBTdGF0ZTtcbiAgY29uc3QgZGVncmVlID0gKDE4MCAqIGFuZ2xlKSAvIE1hdGguUEk7XG4gIC8vIG9mZnNldHMgbXVzdCBiZSBtdWx0aXBsaWVkIGJ5IDIgdG8gYWNjb3VudCBmb3IgdGhlIGRpdmlzaW9uIGJ5IDIgb2ZcbiAgLy8gdGhlIHdob2xlIGV4cHJlc3Npb24gYWZ0ZXJ3YXJkc1xuICBsZXQgdHJhbnNsYXRlWCA9ICgod2lkdGggLSBvZmZzZXRMZWZ0ICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDI7XG4gIGxldCB0cmFuc2xhdGVZID0gKChoZWlnaHQgLSBvZmZzZXRUb3AgKiAyKSAqICh6b29tLnZhbHVlIC0gMSkpIC8gMjtcbiAgaWYgKHdpZHRoID4gbWF4V2lkdGggJiYgem9vbS52YWx1ZSAhPT0gMSkge1xuICAgIHRyYW5zbGF0ZVggPSAoKG1heFdpZHRoIC0gb2Zmc2V0TGVmdCAqIDIpICogKHpvb20udmFsdWUgLSAxKSkgLyAyXG4gIH1cbiAgaWYgKGhlaWdodCA+IG1heEhlaWdodCAmJiB6b29tLnZhbHVlICE9PSAxKSB7XG4gICAgdHJhbnNsYXRlWSA9ICgobWF4SGVpZ2h0IC0gb2Zmc2V0VG9wICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDI7XG4gIH1cbiAgcmV0dXJuIGB0cmFuc2xhdGUoJHt0cmFuc2xhdGVYfXB4LCAke3RyYW5zbGF0ZVl9cHgpIHNjYWxlKCR7em9vbS52YWx1ZX0pIHJvdGF0ZSgke2RlZ3JlZX1kZWcpYDtcbn07XG5cbmV4cG9ydCBjb25zdCB0ZXh0V3lzaXd5ZyA9ICh7XG4gIGlkLFxuICBhcHBTdGF0ZSxcbiAgb25DaGFuZ2UsXG4gIG9uU3VibWl0LFxuICBnZXRWaWV3cG9ydENvb3JkcyxcbiAgZWxlbWVudCxcbiAgY2FudmFzLFxuICBleGNhbGlkcmF3Q29udGFpbmVyLFxufToge1xuICBpZDogRXhjYWxpZHJhd0VsZW1lbnRbXCJpZFwiXTtcbiAgYXBwU3RhdGU6IEFwcFN0YXRlO1xuICBvbkNoYW5nZT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uU3VibWl0OiAoZGF0YToge1xuICAgIHRleHQ6IHN0cmluZztcbiAgICB2aWFLZXlib2FyZDogYm9vbGVhbjtcbiAgICBvcmlnaW5hbFRleHQ6IHN0cmluZztcbiAgfSkgPT4gdm9pZDtcbiAgZ2V0Vmlld3BvcnRDb29yZHM6ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gW251bWJlciwgbnVtYmVyXTtcbiAgZWxlbWVudDogRXhjYWxpZHJhd0VsZW1lbnQ7XG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBudWxsO1xuICBleGNhbGlkcmF3Q29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCB8IG51bGw7XG59KSA9PiB7XG4gIGNvbnN0IHRleHRQcm9wZXJ0aWVzVXBkYXRlZCA9IChcbiAgICB1cGRhdGVkRWxlbWVudDogRXhjYWxpZHJhd1RleHRFbGVtZW50LFxuICAgIGVkaXRhYmxlOiBIVE1MVGV4dEFyZWFFbGVtZW50LFxuICApID0+IHtcbiAgICBjb25zdCBjdXJyZW50Rm9udCA9IGVkaXRhYmxlLnN0eWxlLmZvbnRGYW1pbHkucmVwbGFjZUFsbCgnXCInLCBcIlwiKTtcbiAgICBpZiAoXG4gICAgICBnZXRGb250RmFtaWx5U3RyaW5nKHsgZm9udEZhbWlseTogdXBkYXRlZEVsZW1lbnQuZm9udEZhbWlseSB9KSAhPT1cbiAgICAgIGN1cnJlbnRGb250XG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGAke3VwZGF0ZWRFbGVtZW50LmZvbnRTaXplfXB4YCAhPT0gZWRpdGFibGUuc3R5bGUuZm9udFNpemUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIGxldCBvcmlnaW5hbENvbnRhaW5lckhlaWdodDogbnVtYmVyO1xuICBsZXQgYXBwcm94TGluZUhlaWdodCA9IGlzVGV4dEVsZW1lbnQoZWxlbWVudClcbiAgICA/IGdldEFwcHJveExpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyhlbGVtZW50KSlcbiAgICA6IDA7XG5cbiAgY29uc3QgdXBkYXRlV3lzaXd5Z1N0eWxlID0gKCkgPT4ge1xuICAgIGNvbnN0IHVwZGF0ZWRFbGVtZW50ID0gU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCk/LmdldEVsZW1lbnQoaWQpO1xuICAgIGlmICh1cGRhdGVkRWxlbWVudCAmJiBpc1RleHRFbGVtZW50KHVwZGF0ZWRFbGVtZW50KSkge1xuICAgICAgbGV0IGNvb3JkWCA9IHVwZGF0ZWRFbGVtZW50Lng7XG4gICAgICBsZXQgY29vcmRZID0gdXBkYXRlZEVsZW1lbnQueTtcbiAgICAgIGxldCBjb250YWluZXIgPSB1cGRhdGVkRWxlbWVudD8uY29udGFpbmVySWRcbiAgICAgICAgPyBTY2VuZS5nZXRTY2VuZSh1cGRhdGVkRWxlbWVudCkhLmdldEVsZW1lbnQodXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWQpXG4gICAgICAgIDogbnVsbDtcbiAgICAgIGxldCBtYXhXaWR0aCA9IHVwZGF0ZWRFbGVtZW50LndpZHRoO1xuXG4gICAgICBsZXQgbWF4SGVpZ2h0ID0gdXBkYXRlZEVsZW1lbnQuaGVpZ2h0O1xuICAgICAgbGV0IHdpZHRoID0gdXBkYXRlZEVsZW1lbnQud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPVxuICAgICAgICBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgPT09IDBcbiAgICAgICAgICA/IHVwZGF0ZWRFbGVtZW50LmhlaWdodFxuICAgICAgICAgIDogZWRpdGFibGUuc2Nyb2xsSGVpZ2h0O1xuICAgICAgaWYgKGNvbnRhaW5lciAmJiB1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZCkge1xuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzVXBkYXRlZCA9IHRleHRQcm9wZXJ0aWVzVXBkYXRlZChcbiAgICAgICAgICB1cGRhdGVkRWxlbWVudCxcbiAgICAgICAgICBlZGl0YWJsZSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocHJvcGVydGllc1VwZGF0ZWQpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGFpbmVyID0gU2NlbmUuZ2V0U2NlbmUodXBkYXRlZEVsZW1lbnQpPy5nZXRFbGVtZW50KFxuICAgICAgICAgICAgdXBkYXRlZEVsZW1lbnQuY29udGFpbmVySWQsXG4gICAgICAgICAgKSBhcyBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50O1xuICAgICAgICAgIGFwcHJveExpbmVIZWlnaHQgPSBpc1RleHRFbGVtZW50KHVwZGF0ZWRFbGVtZW50KVxuICAgICAgICAgICAgPyBnZXRBcHByb3hMaW5lSGVpZ2h0KGdldEZvbnRTdHJpbmcodXBkYXRlZEVsZW1lbnQpKVxuICAgICAgICAgICAgOiAwO1xuICAgICAgICAgIGlmICh1cGRhdGVkRWxlbWVudC5oZWlnaHQgPiBjdXJyZW50Q29udGFpbmVyLmhlaWdodCAtIFBBRERJTkcgKiAyKSB7XG4gICAgICAgICAgICBjb25zdCBuZXh0SGVpZ2h0ID0gdXBkYXRlZEVsZW1lbnQuaGVpZ2h0ICsgUEFERElORyAqIDI7XG4gICAgICAgICAgICBvcmlnaW5hbENvbnRhaW5lckhlaWdodCA9IG5leHRIZWlnaHQ7XG4gICAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IG5leHRIZWlnaHQgfSk7XG4gICAgICAgICAgICBjb250YWluZXIgPSB7IC4uLmNvbnRhaW5lciwgaGVpZ2h0OiBuZXh0SGVpZ2h0IH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGVkaXRhYmxlLnN0eWxlLmhlaWdodCA9IGAke3VwZGF0ZWRFbGVtZW50LmhlaWdodH1weGA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFvcmlnaW5hbENvbnRhaW5lckhlaWdodCkge1xuICAgICAgICAgIG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0ID0gY29udGFpbmVyLmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBtYXhXaWR0aCA9IGNvbnRhaW5lci53aWR0aCAtIFBBRERJTkcgKiAyO1xuICAgICAgICBtYXhIZWlnaHQgPSBjb250YWluZXIuaGVpZ2h0IC0gUEFERElORyAqIDI7XG4gICAgICAgIHdpZHRoID0gbWF4V2lkdGg7XG4gICAgICAgIC8vIFRoZSBjb29yZGluYXRlcyBvZiB0ZXh0IGJveCBzZXQgYSBkaXN0YW5jZSBvZlxuICAgICAgICAvLyAzMHB4IHRvIHByZXNlcnZlIHBhZGRpbmdcbiAgICAgICAgY29vcmRYID0gY29udGFpbmVyLnggKyBQQURESU5HO1xuXG4gICAgICAgIC8vIGF1dG9ncm93IGNvbnRhaW5lciBoZWlnaHQgaWYgdGV4dCBleGNlZWRzXG4gICAgICAgIGlmIChlZGl0YWJsZS5zY3JvbGxIZWlnaHQgPiBtYXhIZWlnaHQpIHtcbiAgICAgICAgICBjb25zdCBkaWZmID0gTWF0aC5taW4oXG4gICAgICAgICAgICBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLSBtYXhIZWlnaHQsXG4gICAgICAgICAgICBhcHByb3hMaW5lSGVpZ2h0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHsgaGVpZ2h0OiBjb250YWluZXIuaGVpZ2h0ICsgZGlmZiB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgLy8gYXV0b3NocmluayBjb250YWluZXIgaGVpZ2h0IHVudGlsIG9yaWdpbmFsIGNvbnRhaW5lciBoZWlnaHRcbiAgICAgICAgICAvLyBpcyByZWFjaGVkIHdoZW4gdGV4dCBpcyByZW1vdmVkXG4gICAgICAgICAgY29udGFpbmVyLmhlaWdodCA+IG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0ICYmXG4gICAgICAgICAgZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IDwgbWF4SGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IGRpZmYgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIG1heEhlaWdodCAtIGVkaXRhYmxlLnNjcm9sbEhlaWdodCxcbiAgICAgICAgICAgIGFwcHJveExpbmVIZWlnaHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IGNvbnRhaW5lci5oZWlnaHQgLSBkaWZmIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFN0YXJ0IHB1c2hpbmcgdGV4dCB1cHdhcmQgdW50aWwgYSBkaWZmIG9mIDMwcHggKHBhZGRpbmcpXG4gICAgICAgIC8vIGlzIHJlYWNoZWRcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY29uc3QgbGluZXMgPSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLyBhcHByb3hMaW5lSGVpZ2h0O1xuXG4gICAgICAgICAgaWYgKGxpbmVzID4gMSB8fCBwcm9wZXJ0aWVzVXBkYXRlZCkge1xuICAgICAgICAgICAgLy8gdmVydGljYWxseSBjZW50ZXIgYWxpZ24gdGhlIHRleHRcbiAgICAgICAgICAgIGNvb3JkWSA9XG4gICAgICAgICAgICAgIGNvbnRhaW5lci55ICsgY29udGFpbmVyLmhlaWdodCAvIDIgLSBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgLyAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgW3ZpZXdwb3J0WCwgdmlld3BvcnRZXSA9IGdldFZpZXdwb3J0Q29vcmRzKGNvb3JkWCwgY29vcmRZKTtcbiAgICAgIGNvbnN0IHsgdGV4dEFsaWduLCBhbmdsZSB9ID0gdXBkYXRlZEVsZW1lbnQ7XG5cbiAgICAgIGVkaXRhYmxlLnZhbHVlID0gdXBkYXRlZEVsZW1lbnQub3JpZ2luYWxUZXh0IHx8IHVwZGF0ZWRFbGVtZW50LnRleHQ7XG4gICAgICBjb25zdCBsaW5lcyA9IHVwZGF0ZWRFbGVtZW50Lm9yaWdpbmFsVGV4dC5zcGxpdChcIlxcblwiKTtcbiAgICAgIGNvbnN0IGxpbmVIZWlnaHQgPSB1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZFxuICAgICAgICA/IGFwcHJveExpbmVIZWlnaHRcbiAgICAgICAgOiB1cGRhdGVkRWxlbWVudC5oZWlnaHQgLyBsaW5lcy5sZW5ndGg7XG4gICAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgICBtYXhXaWR0aCA9XG4gICAgICAgICAgKCBhcHBTdGF0ZS53aWR0aCArIGFwcFN0YXRlLm9mZnNldExlZnQgLSB2aWV3cG9ydFggLSA4KSAvIGFwcFN0YXRlLnpvb20udmFsdWUgLVxuICAgICAgICAgIC8vIG1hcmdpbi1yaWdodCBvZiBwYXJlbnQgaWYgYW55XG4gICAgICAgICAgTnVtYmVyKFxuICAgICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShcbiAgICAgICAgICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcj8ucGFyZW50Tm9kZSBhcyBFbGVtZW50LFxuICAgICAgICAgICAgKS5tYXJnaW5SaWdodC5zbGljZSgwLCAtMiksXG4gICAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gTWFrZSBzdXJlIHRleHQgZWRpdG9yIGhlaWdodCBkb2Vzbid0IGdvIGJleW9uZCB2aWV3cG9ydFxuICAgICAgY29uc3QgZWRpdG9yTWF4SGVpZ2h0ID1cbiAgICAgICAgKGFwcFN0YXRlLmhlaWdodCArIGFwcFN0YXRlLm9mZnNldFRvcCAtIHZpZXdwb3J0WSkgLyBhcHBTdGF0ZS56b29tLnZhbHVlO1xuXG4gICAgICBjb25zb2xlLmxvZyh7XG4gICAgICAgIG1heFdpZHRoLFxuICAgICAgICBlZGl0b3JNYXhIZWlnaHQsXG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIHZpZXdwb3J0WCxcbiAgICAgICAgdmlld3BvcnRZLFxuICAgICAgICBzY2VuZVg6IGNvb3JkWCxcbiAgICAgICAgc2NlbmVZOiBjb29yZFksXG4gICAgICAgIGFwcFdpZHRoOmFwcFN0YXRlLndpZHRoLFxuICAgICAgICBhcHBIZWlnaHQ6YXBwU3RhdGUuaGVpZ2h0LFxuICAgICAgICBzY3JvbGxYOiBhcHBTdGF0ZS5zY3JvbGxYLFxuICAgICAgICBzY3JvbGxZOiBhcHBTdGF0ZS5zY3JvbGxZLFxuICAgICAgICBvZmZzZXRUb3A6IGFwcFN0YXRlLm9mZnNldFRvcCxcbiAgICAgICAgb2Zmc2V0TGVmdDogYXBwU3RhdGUub2Zmc2V0TGVmdCxcbiAgICAgICAgem9vbTogYXBwU3RhdGUuem9vbS52YWx1ZSxcbiAgICAgICAgdHJhbnNsYXRpb246IGFwcFN0YXRlLnpvb20udHJhbnNsYXRpb24sXG4gICAgICAgIG1hcmdpblJpZ2h0OiBOdW1iZXIoXG4gICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShcbiAgICAgICAgICAgIGV4Y2FsaWRyYXdDb250YWluZXI/LnBhcmVudE5vZGUgYXMgRWxlbWVudCxcbiAgICAgICAgICApLm1hcmdpblJpZ2h0LnNsaWNlKDAsIC0yKSxcbiAgICAgICAgKSxcbiAgICAgICAgdHJhbnNmb3JtOiBnZXRUcmFuc2Zvcm0oXG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIGFuZ2xlLFxuICAgICAgICAgIGFwcFN0YXRlLFxuICAgICAgICAgIG1heFdpZHRoLFxuICAgICAgICAgIGVkaXRvck1heEhlaWdodCxcbiAgICAgICAgKVxuICAgICAgfSk7XG4gICAgICBPYmplY3QuYXNzaWduKGVkaXRhYmxlLnN0eWxlLCB7XG4gICAgICAgIGZvbnQ6IGdldEZvbnRTdHJpbmcodXBkYXRlZEVsZW1lbnQpLFxuICAgICAgICAvLyBtdXN0IGJlIGRlZmluZWQgKmFmdGVyKiBmb250IMKvXFxfKOODhClfL8KvXG4gICAgICAgIGxpbmVIZWlnaHQ6IGAke2xpbmVIZWlnaHR9cHhgLFxuICAgICAgICB3aWR0aDogYCR7d2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke2hlaWdodH1weGAsXG4gICAgICAgIGxlZnQ6IGAke3ZpZXdwb3J0WH1weGAsXG4gICAgICAgIHRvcDogYCR7dmlld3BvcnRZfXB4YCxcbiAgICAgICAgdHJhbnNmb3JtOiBnZXRUcmFuc2Zvcm0oXG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIGFuZ2xlLFxuICAgICAgICAgIGFwcFN0YXRlLFxuICAgICAgICAgIG1heFdpZHRoLFxuICAgICAgICAgIGVkaXRvck1heEhlaWdodCxcbiAgICAgICAgKSxcbiAgICAgICAgdGV4dEFsaWduLFxuICAgICAgICBjb2xvcjogdXBkYXRlZEVsZW1lbnQuc3Ryb2tlQ29sb3IsXG4gICAgICAgIG9wYWNpdHk6IHVwZGF0ZWRFbGVtZW50Lm9wYWNpdHkgLyAxMDAsXG4gICAgICAgIGZpbHRlcjogXCJ2YXIoLS10aGVtZS1maWx0ZXIpXCIsXG4gICAgICAgIG1heFdpZHRoOiBgJHttYXhXaWR0aH1weGAsXG4gICAgICAgIG1heEhlaWdodDogYCR7ZWRpdG9yTWF4SGVpZ2h0fXB4YCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBlZGl0YWJsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZXh0YXJlYVwiKTtcblxuICBlZGl0YWJsZS5kaXIgPSBcImF1dG9cIjtcbiAgZWRpdGFibGUudGFiSW5kZXggPSAwO1xuICBlZGl0YWJsZS5kYXRhc2V0LnR5cGUgPSBcInd5c2l3eWdcIjtcbiAgLy8gcHJldmVudCBsaW5lIHdyYXBwaW5nIG9uIFNhZmFyaVxuICBlZGl0YWJsZS53cmFwID0gXCJvZmZcIjtcbiAgZWRpdGFibGUuY2xhc3NMaXN0LmFkZChcImV4Y2FsaWRyYXctd3lzaXd5Z1wiKTtcblxuICBsZXQgd2hpdGVTcGFjZSA9IFwicHJlXCI7XG4gIGxldCB3b3JkQnJlYWsgPSBcIm5vcm1hbFwiO1xuXG4gIGlmIChpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkpIHtcbiAgICB3aGl0ZVNwYWNlID0gXCJwcmUtd3JhcFwiO1xuICAgIHdvcmRCcmVhayA9IFwiYnJlYWstd29yZFwiO1xuICB9XG4gIE9iamVjdC5hc3NpZ24oZWRpdGFibGUuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIGRpc3BsYXk6IFwiaW5saW5lLWJsb2NrXCIsXG4gICAgbWluSGVpZ2h0OiBcIjFlbVwiLFxuICAgIGJhY2tmYWNlVmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICBtYXJnaW46IDAsXG4gICAgcGFkZGluZzogMCxcbiAgICBib3JkZXI6IDAsXG4gICAgb3V0bGluZTogMCxcbiAgICByZXNpemU6IFwibm9uZVwiLFxuICAgIGJhY2tncm91bmQ6IFwidHJhbnNwYXJlbnRcIixcbiAgICBvdmVyZmxvdzogXCJoaWRkZW5cIixcbiAgICAvLyBtdXN0IGJlIHNwZWNpZmllZCBiZWNhdXNlIGluIGRhcmsgbW9kZSBjYW52YXMgY3JlYXRlcyBhIHN0YWNraW5nIGNvbnRleHRcbiAgICB6SW5kZXg6IFwidmFyKC0tekluZGV4LXd5c2l3eWcpXCIsXG4gICAgd29yZEJyZWFrLFxuICAgIC8vIHByZXZlbnQgbGluZSB3cmFwcGluZyAoYHdoaXRlc3BhY2U6IG5vd3JhcGAgZG9lc24ndCB3b3JrIG9uIEZGKVxuICAgIHdoaXRlU3BhY2UsXG4gICAgb3ZlcmZsb3dXcmFwOiBcImJyZWFrLXdvcmRcIixcbiAgfSk7XG4gIHVwZGF0ZVd5c2l3eWdTdHlsZSgpO1xuXG4gIGlmIChvbkNoYW5nZSkge1xuICAgIGVkaXRhYmxlLm9uaW5wdXQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBsaW5lcyA9IGVkaXRhYmxlLnNjcm9sbEhlaWdodCAvIGFwcHJveExpbmVIZWlnaHQ7XG4gICAgICAvLyBhdXRvIGluY3JlYXNlIGhlaWdodCBvbmx5IHdoZW4gbGluZXMgID4gMSBzbyBpdHNcbiAgICAgIC8vIG1lYXN1cmVkIGNvcnJlY3RseSBhbmQgdmVydGljYWxseSBhbGlnbmVzIGZvclxuICAgICAgLy8gZmlyc3QgbGluZSBhcyB3ZWxsIGFzIHNldHRpbmcgaGVpZ2h0IHRvIFwiYXV0b1wiXG4gICAgICAvLyBkb3VibGVzIHRoZSBoZWlnaHQgYXMgc29vbiBhcyB1c2VyIHN0YXJ0cyB0eXBpbmdcbiAgICAgIGlmIChpc0JvdW5kVG9Db250YWluZXIoZWxlbWVudCkgJiYgbGluZXMgPiAxKSB7XG4gICAgICAgIGVkaXRhYmxlLnN0eWxlLmhlaWdodCA9IFwiYXV0b1wiO1xuICAgICAgICBlZGl0YWJsZS5zdHlsZS5oZWlnaHQgPSBgJHtlZGl0YWJsZS5zY3JvbGxIZWlnaHR9cHhgO1xuICAgICAgfVxuICAgICAgb25DaGFuZ2Uobm9ybWFsaXplVGV4dChlZGl0YWJsZS52YWx1ZSkpO1xuICAgIH07XG4gIH1cblxuICBlZGl0YWJsZS5vbmtleWRvd24gPSAoZXZlbnQpID0+IHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVTQ0FQRSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHN1Ym1pdHRlZFZpYUtleWJvYXJkID0gdHJ1ZTtcbiAgICAgIGhhbmRsZVN1Ym1pdCgpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBLRVlTLkVOVEVSICYmIGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKGV2ZW50LmlzQ29tcG9zaW5nIHx8IGV2ZW50LmtleUNvZGUgPT09IDIyOSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdWJtaXR0ZWRWaWFLZXlib2FyZCA9IHRydWU7XG4gICAgICBoYW5kbGVTdWJtaXQoKTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgZXZlbnQua2V5ID09PSBLRVlTLlRBQiB8fFxuICAgICAgKGV2ZW50W0tFWVMuQ1RSTF9PUl9DTURdICYmXG4gICAgICAgIChldmVudC5jb2RlID09PSBDT0RFUy5CUkFDS0VUX0xFRlQgfHxcbiAgICAgICAgICBldmVudC5jb2RlID09PSBDT0RFUy5CUkFDS0VUX1JJR0hUKSlcbiAgICApIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuY29kZSA9PT0gQ09ERVMuQlJBQ0tFVF9MRUZUKSB7XG4gICAgICAgIG91dGRlbnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGVudCgpO1xuICAgICAgfVxuICAgICAgLy8gV2UgbXVzdCBzZW5kIGFuIGlucHV0IGV2ZW50IHRvIHJlc2l6ZSB0aGUgZWxlbWVudFxuICAgICAgZWRpdGFibGUuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiKSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IFRBQl9TSVpFID0gNDtcbiAgY29uc3QgVEFCID0gXCIgXCIucmVwZWF0KFRBQl9TSVpFKTtcbiAgY29uc3QgUkVfTEVBRElOR19UQUIgPSBuZXcgUmVnRXhwKGBeIHsxLCR7VEFCX1NJWkV9fWApO1xuICBjb25zdCBpbmRlbnQgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kIH0gPSBlZGl0YWJsZTtcbiAgICBjb25zdCBsaW5lc1N0YXJ0SW5kaWNlcyA9IGdldFNlbGVjdGVkTGluZXNTdGFydEluZGljZXMoKTtcblxuICAgIGxldCB2YWx1ZSA9IGVkaXRhYmxlLnZhbHVlO1xuICAgIGxpbmVzU3RhcnRJbmRpY2VzLmZvckVhY2goKHN0YXJ0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRWYWx1ZSA9IHZhbHVlLnNsaWNlKDAsIHN0YXJ0SW5kZXgpO1xuICAgICAgY29uc3QgZW5kVmFsdWUgPSB2YWx1ZS5zbGljZShzdGFydEluZGV4KTtcblxuICAgICAgdmFsdWUgPSBgJHtzdGFydFZhbHVlfSR7VEFCfSR7ZW5kVmFsdWV9YDtcbiAgICB9KTtcblxuICAgIGVkaXRhYmxlLnZhbHVlID0gdmFsdWU7XG5cbiAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvblN0YXJ0ICsgVEFCX1NJWkU7XG4gICAgZWRpdGFibGUuc2VsZWN0aW9uRW5kID0gc2VsZWN0aW9uRW5kICsgVEFCX1NJWkUgKiBsaW5lc1N0YXJ0SW5kaWNlcy5sZW5ndGg7XG4gIH07XG5cbiAgY29uc3Qgb3V0ZGVudCA9ICgpID0+IHtcbiAgICBjb25zdCB7IHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQgfSA9IGVkaXRhYmxlO1xuICAgIGNvbnN0IGxpbmVzU3RhcnRJbmRpY2VzID0gZ2V0U2VsZWN0ZWRMaW5lc1N0YXJ0SW5kaWNlcygpO1xuICAgIGNvbnN0IHJlbW92ZWRUYWJzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgbGV0IHZhbHVlID0gZWRpdGFibGUudmFsdWU7XG4gICAgbGluZXNTdGFydEluZGljZXMuZm9yRWFjaCgoc3RhcnRJbmRleCkgPT4ge1xuICAgICAgY29uc3QgdGFiTWF0Y2ggPSB2YWx1ZVxuICAgICAgICAuc2xpY2Uoc3RhcnRJbmRleCwgc3RhcnRJbmRleCArIFRBQl9TSVpFKVxuICAgICAgICAubWF0Y2goUkVfTEVBRElOR19UQUIpO1xuXG4gICAgICBpZiAodGFiTWF0Y2gpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRWYWx1ZSA9IHZhbHVlLnNsaWNlKDAsIHN0YXJ0SW5kZXgpO1xuICAgICAgICBjb25zdCBlbmRWYWx1ZSA9IHZhbHVlLnNsaWNlKHN0YXJ0SW5kZXggKyB0YWJNYXRjaFswXS5sZW5ndGgpO1xuXG4gICAgICAgIC8vIERlbGV0ZSBhIHRhYiBmcm9tIHRoZSBsaW5lXG4gICAgICAgIHZhbHVlID0gYCR7c3RhcnRWYWx1ZX0ke2VuZFZhbHVlfWA7XG4gICAgICAgIHJlbW92ZWRUYWJzLnB1c2goc3RhcnRJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBlZGl0YWJsZS52YWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHJlbW92ZWRUYWJzLmxlbmd0aCkge1xuICAgICAgaWYgKHNlbGVjdGlvblN0YXJ0ID4gcmVtb3ZlZFRhYnNbcmVtb3ZlZFRhYnMubGVuZ3RoIC0gMV0pIHtcbiAgICAgICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQgPSBNYXRoLm1heChcbiAgICAgICAgICBzZWxlY3Rpb25TdGFydCAtIFRBQl9TSVpFLFxuICAgICAgICAgIHJlbW92ZWRUYWJzW3JlbW92ZWRUYWJzLmxlbmd0aCAtIDFdLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSWYgdGhlIGN1cnNvciBpcyBiZWZvcmUgdGhlIGZpcnN0IHRhYiByZW1vdmVkLCBleDpcbiAgICAgICAgLy8gTGluZXwgIzFcbiAgICAgICAgLy8gICAgIExpbmUgIzJcbiAgICAgICAgLy8gTGlufGUgIzNcbiAgICAgICAgLy8gd2Ugc2hvdWxkIHJlc2V0IHRoZSBzZWxlY3Rpb25TdGFydCB0byBoaXMgaW5pdGlhbCB2YWx1ZS5cbiAgICAgICAgZWRpdGFibGUuc2VsZWN0aW9uU3RhcnQgPSBzZWxlY3Rpb25TdGFydDtcbiAgICAgIH1cbiAgICAgIGVkaXRhYmxlLnNlbGVjdGlvbkVuZCA9IE1hdGgubWF4KFxuICAgICAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCxcbiAgICAgICAgc2VsZWN0aW9uRW5kIC0gVEFCX1NJWkUgKiByZW1vdmVkVGFicy5sZW5ndGgsXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybnMgaW5kZWNlcyBvZiBzdGFydCBwb3NpdGlvbnMgb2Ygc2VsZWN0ZWQgbGluZXMsIGluIHJldmVyc2Ugb3JkZXJcbiAgICovXG4gIGNvbnN0IGdldFNlbGVjdGVkTGluZXNTdGFydEluZGljZXMgPSAoKSA9PiB7XG4gICAgbGV0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCwgdmFsdWUgfSA9IGVkaXRhYmxlO1xuXG4gICAgLy8gY2hhcnMgYmVmb3JlIHNlbGVjdGlvblN0YXJ0IG9uIHRoZSBzYW1lIGxpbmVcbiAgICBjb25zdCBzdGFydE9mZnNldCA9IHZhbHVlLnNsaWNlKDAsIHNlbGVjdGlvblN0YXJ0KS5tYXRjaCgvW15cXG5dKiQvKSFbMF1cbiAgICAgIC5sZW5ndGg7XG4gICAgLy8gcHV0IGNhcmV0IGF0IHRoZSBzdGFydCBvZiB0aGUgbGluZVxuICAgIHNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgLSBzdGFydE9mZnNldDtcblxuICAgIGNvbnN0IHNlbGVjdGVkID0gdmFsdWUuc2xpY2Uoc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCk7XG5cbiAgICByZXR1cm4gc2VsZWN0ZWRcbiAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgLnJlZHVjZShcbiAgICAgICAgKHN0YXJ0SW5kaWNlcywgbGluZSwgaWR4LCBsaW5lcykgPT5cbiAgICAgICAgICBzdGFydEluZGljZXMuY29uY2F0KFxuICAgICAgICAgICAgaWR4XG4gICAgICAgICAgICAgID8gLy8gY3VyciBsaW5lIGluZGV4IGlzIHByZXYgbGluZSdzIHN0YXJ0ICsgcHJldiBsaW5lJ3MgbGVuZ3RoICsgXFxuXG4gICAgICAgICAgICAgICAgc3RhcnRJbmRpY2VzW2lkeCAtIDFdICsgbGluZXNbaWR4IC0gMV0ubGVuZ3RoICsgMVxuICAgICAgICAgICAgICA6IC8vIGZpcnN0IHNlbGVjdGVkIGxpbmVcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICApLFxuICAgICAgICBbXSBhcyBudW1iZXJbXSxcbiAgICAgIClcbiAgICAgIC5yZXZlcnNlKCk7XG4gIH07XG5cbiAgY29uc3Qgc3RvcEV2ZW50ID0gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH07XG5cbiAgLy8gdXNpbmcgYSBzdGF0ZSB2YXJpYWJsZSBpbnN0ZWFkIG9mIHBhc3NpbmcgaXQgdG8gdGhlIGhhbmRsZVN1Ym1pdCBjYWxsYmFja1xuICAvLyBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gY3JlYXRlIHNlcGFyYXRlIGEgY2FsbGJhY2sgZm9yIGV2ZW50IGhhbmRsZXJzXG4gIGxldCBzdWJtaXR0ZWRWaWFLZXlib2FyZCA9IGZhbHNlO1xuICBjb25zdCBoYW5kbGVTdWJtaXQgPSAoKSA9PiB7XG4gICAgLy8gY2xlYW51cCBtdXN0IGJlIHJ1biBiZWZvcmUgb25TdWJtaXQgb3RoZXJ3aXNlIHdoZW4gYXBwIGJsdXJzIHRoZSB3eXNpd3lnXG4gICAgLy8gaXQnZCBnZXQgc3R1Y2sgaW4gYW4gaW5maW5pdGUgbG9vcCBvZiBibHVy4oaSb25TdWJtaXQgYWZ0ZXIgd2UgcmUtZm9jdXMgdGhlXG4gICAgLy8gd3lzaXd5ZyBvbiB1cGRhdGVcbiAgICBjbGVhbnVwKCk7XG4gICAgY29uc3QgdXBkYXRlRWxlbWVudCA9IFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpPy5nZXRFbGVtZW50KGVsZW1lbnQuaWQpO1xuICAgIGlmICghdXBkYXRlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgd3JhcHBlZFRleHQgPSBcIlwiO1xuICAgIGlmIChpc1RleHRFbGVtZW50KHVwZGF0ZUVsZW1lbnQpICYmIHVwZGF0ZUVsZW1lbnQ/LmNvbnRhaW5lcklkKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBTY2VuZS5nZXRTY2VuZSh1cGRhdGVFbGVtZW50KSEuZ2V0RWxlbWVudChcbiAgICAgICAgdXBkYXRlRWxlbWVudC5jb250YWluZXJJZCxcbiAgICAgICkgYXMgRXhjYWxpZHJhd0JpbmRhYmxlRWxlbWVudDtcblxuICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICB3cmFwcGVkVGV4dCA9IHdyYXBUZXh0KFxuICAgICAgICAgIGVkaXRhYmxlLnZhbHVlLFxuICAgICAgICAgIGdldEZvbnRTdHJpbmcodXBkYXRlRWxlbWVudCksXG4gICAgICAgICAgY29udGFpbmVyLndpZHRoLFxuICAgICAgICApO1xuICAgICAgICBpZiAoaXNUZXh0RWxlbWVudCh1cGRhdGVFbGVtZW50KSAmJiB1cGRhdGVFbGVtZW50LmNvbnRhaW5lcklkKSB7XG4gICAgICAgICAgY29uc3QgZWRpdG9ySGVpZ2h0ID0gTnVtYmVyKGVkaXRhYmxlLnN0eWxlLmhlaWdodC5zbGljZSgwLCAtMikpO1xuICAgICAgICAgIGlmIChlZGl0YWJsZS52YWx1ZSkge1xuICAgICAgICAgICAgbXV0YXRlRWxlbWVudCh1cGRhdGVFbGVtZW50LCB7XG4gICAgICAgICAgICAgIC8vIHZlcnRpY2FsbHkgY2VudGVyIGFsaWduXG4gICAgICAgICAgICAgIHk6IGNvbnRhaW5lci55ICsgY29udGFpbmVyLmhlaWdodCAvIDIgLSBlZGl0b3JIZWlnaHQgLyAyLFxuICAgICAgICAgICAgICBoZWlnaHQ6IGVkaXRvckhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IE51bWJlcihlZGl0YWJsZS5zdHlsZS53aWR0aC5zbGljZSgwLCAtMikpLFxuICAgICAgICAgICAgICAvLyBwcmVzZXJ2ZSBwYWRkaW5nXG4gICAgICAgICAgICAgIHg6IGNvbnRhaW5lci54ICsgUEFERElORyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgYm91bmRUZXh0RWxlbWVudElkID0gZ2V0Qm91bmRUZXh0RWxlbWVudElkKGNvbnRhaW5lcik7XG4gICAgICAgICAgICBpZiAoIWJvdW5kVGV4dEVsZW1lbnRJZCB8fCBib3VuZFRleHRFbGVtZW50SWQgIT09IGVsZW1lbnQuaWQpIHtcbiAgICAgICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHtcbiAgICAgICAgICAgICAgICBib3VuZEVsZW1lbnRzOiAoY29udGFpbmVyLmJvdW5kRWxlbWVudHMgfHwgW10pLmNvbmNhdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICAgIGlkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbXV0YXRlRWxlbWVudChjb250YWluZXIsIHtcbiAgICAgICAgICAgICAgYm91bmRFbGVtZW50czogY29udGFpbmVyLmJvdW5kRWxlbWVudHM/LmZpbHRlcihcbiAgICAgICAgICAgICAgICAoZWxlKSA9PiBlbGUudHlwZSAhPT0gXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgd3JhcHBlZFRleHQgPSBlZGl0YWJsZS52YWx1ZTtcbiAgICB9XG5cbiAgICBvblN1Ym1pdCh7XG4gICAgICB0ZXh0OiBub3JtYWxpemVUZXh0KHdyYXBwZWRUZXh0KSxcbiAgICAgIHZpYUtleWJvYXJkOiBzdWJtaXR0ZWRWaWFLZXlib2FyZCxcbiAgICAgIG9yaWdpbmFsVGV4dDogZWRpdGFibGUudmFsdWUsXG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICBpZiAoaXNEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgIC8vIHJlbW92ZSBldmVudHMgdG8gZW5zdXJlIHRoZXkgZG9uJ3QgbGF0ZS1maXJlXG4gICAgZWRpdGFibGUub25ibHVyID0gbnVsbDtcbiAgICBlZGl0YWJsZS5vbmlucHV0ID0gbnVsbDtcbiAgICBlZGl0YWJsZS5vbmtleWRvd24gPSBudWxsO1xuXG4gICAgaWYgKG9ic2VydmVyKSB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgdXBkYXRlV3lzaXd5Z1N0eWxlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIHN0b3BFdmVudCwgdHJ1ZSk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVyZG93blwiLCBvblBvaW50ZXJEb3duKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBiaW5kQmx1ckV2ZW50KTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgaGFuZGxlU3VibWl0KTtcblxuICAgIHVuYmluZFVwZGF0ZSgpO1xuXG4gICAgZWRpdGFibGUucmVtb3ZlKCk7XG4gIH07XG5cbiAgY29uc3QgYmluZEJsdXJFdmVudCA9IChldmVudD86IE1vdXNlRXZlbnQpID0+IHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBiaW5kQmx1ckV2ZW50KTtcbiAgICAvLyBEZWZlcnJlZCBzbyB0aGF0IHRoZSBwb2ludGVyZG93biB0aGF0IGluaXRpYXRlcyB0aGUgd3lzaXd5ZyBkb2Vzbid0XG4gICAgLy8gdHJpZ2dlciB0aGUgYmx1ciBvbiBlbnN1aW5nIHBvaW50ZXJ1cC5cbiAgICAvLyBBbHNvIHRvIGhhbmRsZSBjYXNlcyBzdWNoIGFzIHBpY2tpbmcgYSBjb2xvciB3aGljaCB3b3VsZCB0cmlnZ2VyIGEgYmx1clxuICAgIC8vIGluIHRoYXQgc2FtZSB0aWNrLlxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50Py50YXJnZXQ7XG5cbiAgICBjb25zdCBpc1RhcmdldENvbG9yUGlja2VyID1cbiAgICAgIHRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiZcbiAgICAgIHRhcmdldC5jbG9zZXN0KFwiLmNvbG9yLXBpY2tlci1pbnB1dFwiKSAmJlxuICAgICAgaXNXcml0YWJsZUVsZW1lbnQodGFyZ2V0KTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgZWRpdGFibGUub25ibHVyID0gaGFuZGxlU3VibWl0O1xuICAgICAgaWYgKHRhcmdldCAmJiBpc1RhcmdldENvbG9yUGlja2VyKSB7XG4gICAgICAgIHRhcmdldC5vbmJsdXIgPSAoKSA9PiB7XG4gICAgICAgICAgZWRpdGFibGUuZm9jdXMoKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIGNhc2U6IGNsaWNraW5nIG9uIHRoZSBzYW1lIHByb3BlcnR5IOKGkiBubyBjaGFuZ2Ug4oaSIG5vIHVwZGF0ZSDihpIgbm8gZm9jdXNcbiAgICAgIGlmICghaXNUYXJnZXRDb2xvclBpY2tlcikge1xuICAgICAgICBlZGl0YWJsZS5mb2N1cygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vIHByZXZlbnQgYmx1ciB3aGVuIGNoYW5naW5nIHByb3BlcnRpZXMgZnJvbSB0aGUgbWVudVxuICBjb25zdCBvblBvaW50ZXJEb3duID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNUYXJnZXRDb2xvclBpY2tlciA9XG4gICAgICBldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50ICYmXG4gICAgICBldmVudC50YXJnZXQuY2xvc2VzdChcIi5jb2xvci1waWNrZXItaW5wdXRcIikgJiZcbiAgICAgIGlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCk7XG4gICAgaWYgKFxuICAgICAgKChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fFxuICAgICAgICBldmVudC50YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSAmJlxuICAgICAgICBldmVudC50YXJnZXQuY2xvc2VzdChgLiR7Q0xBU1NFUy5TSEFQRV9BQ1RJT05TX01FTlV9YCkgJiZcbiAgICAgICAgIWlzV3JpdGFibGVFbGVtZW50KGV2ZW50LnRhcmdldCkpIHx8XG4gICAgICBpc1RhcmdldENvbG9yUGlja2VyXG4gICAgKSB7XG4gICAgICBlZGl0YWJsZS5vbmJsdXIgPSBudWxsO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgYmluZEJsdXJFdmVudCk7XG4gICAgICAvLyBoYW5kbGUgZWRnZS1jYXNlIHdoZXJlIHBvaW50ZXJ1cCBkb2Vzbid0IGZpcmUgZS5nLiBkdWUgdG8gdXNlclxuICAgICAgLy8gYWx0LXRhYmJpbmcgYXdheVxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIGhhbmRsZVN1Ym1pdCk7XG4gICAgfVxuICB9O1xuXG4gIC8vIGhhbmRsZSB1cGRhdGVzIG9mIHRleHRFbGVtZW50IHByb3BlcnRpZXMgb2YgZWRpdGluZyBlbGVtZW50XG4gIGNvbnN0IHVuYmluZFVwZGF0ZSA9IFNjZW5lLmdldFNjZW5lKGVsZW1lbnQpIS5hZGRDYWxsYmFjaygoKSA9PiB7XG4gICAgdXBkYXRlV3lzaXd5Z1N0eWxlKCk7XG4gICAgY29uc3QgaXNDb2xvclBpY2tlckFjdGl2ZSA9ICEhZG9jdW1lbnQuYWN0aXZlRWxlbWVudD8uY2xvc2VzdChcbiAgICAgIFwiLmNvbG9yLXBpY2tlci1pbnB1dFwiLFxuICAgICk7XG4gICAgaWYgKCFpc0NvbG9yUGlja2VyQWN0aXZlKSB7XG4gICAgICBlZGl0YWJsZS5mb2N1cygpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgbGV0IGlzRGVzdHJveWVkID0gZmFsc2U7XG5cbiAgLy8gc2VsZWN0IG9uIGluaXQgKGZvY3VzaW5nIGlzIGRvbmUgc2VwYXJhdGVseSBpbnNpZGUgdGhlIGJpbmRCbHVyRXZlbnQoKVxuICAvLyBiZWNhdXNlIHdlIG5lZWQgaXQgdG8gaGFwcGVuICphZnRlciogdGhlIGJsdXIgZXZlbnQgZnJvbSBgcG9pbnRlcmRvd25gKVxuICBlZGl0YWJsZS5zZWxlY3QoKTtcbiAgYmluZEJsdXJFdmVudCgpO1xuXG4gIC8vIHJlcG9zaXRpb24gd3lzaXd5ZyBpbiBjYXNlIG9mIGNhbnZhcyBpcyByZXNpemVkLiBVc2luZyBSZXNpemVPYnNlcnZlclxuICAvLyBpcyBwcmVmZXJyZWQgc28gd2UgY2F0Y2ggY2hhbmdlcyBmcm9tIGhvc3QsIHdoZXJlIHdpbmRvdyBtYXkgbm90IHJlc2l6ZS5cbiAgbGV0IG9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xuICBpZiAoY2FudmFzICYmIFwiUmVzaXplT2JzZXJ2ZXJcIiBpbiB3aW5kb3cpIHtcbiAgICBvYnNlcnZlciA9IG5ldyB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgdXBkYXRlV3lzaXd5Z1N0eWxlKCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShjYW52YXMpO1xuICB9IGVsc2Uge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHVwZGF0ZVd5c2l3eWdTdHlsZSk7XG4gIH1cblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJkb3duXCIsIG9uUG9pbnRlckRvd24pO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsIHN0b3BFdmVudCwge1xuICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgIGNhcHR1cmU6IHRydWUsXG4gIH0pO1xuICBleGNhbGlkcmF3Q29udGFpbmVyXG4gICAgPy5xdWVyeVNlbGVjdG9yKFwiLmV4Y2FsaWRyYXctdGV4dEVkaXRvckNvbnRhaW5lclwiKSFcbiAgICAuYXBwZW5kQ2hpbGQoZWRpdGFibGUpO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../element/textWysiwyg.tsx\n");
2545
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"textWysiwyg\": () => (/* binding */ textWysiwyg)\n/* harmony export */ });\n/* harmony import */ var _keys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../keys */ \"../../keys.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ \"../../utils.ts\");\n/* harmony import */ var _scene_Scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene/Scene */ \"../../scene/Scene.ts\");\n/* harmony import */ var _typeChecks__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./typeChecks */ \"../../element/typeChecks.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../constants */ \"../../constants.ts\");\n/* harmony import */ var _mutateElement__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mutateElement */ \"../../element/mutateElement.ts\");\n/* harmony import */ var _textElement__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./textElement */ \"../../element/textElement.ts\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst normalizeText = (text) => {\r\n return (text\r\n // replace tabs with spaces so they render and measure correctly\r\n .replace(/\\t/g, \" \")\r\n // normalize newlines\r\n .replace(/\\r?\\n|\\r/g, \"\\n\"));\r\n};\r\nconst getTransform = (width, height, angle, appState, maxWidth, maxHeight) => {\r\n const { zoom, offsetTop, offsetLeft } = appState;\r\n const degree = (180 * angle) / Math.PI;\r\n return `translate(0px, 0px) scale(${zoom.value}) rotate(${degree}deg)`;\r\n // offsets must be multiplied by 2 to account for the division by 2 of\r\n // the whole expression afterwards\r\n let translateX = ((width - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n let translateY = ((height - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n if (width > maxWidth && zoom.value !== 1) {\r\n translateX = ((maxWidth - offsetLeft * 2) * (zoom.value - 1)) / 2;\r\n }\r\n if (height > maxHeight && zoom.value !== 1) {\r\n translateY = ((maxHeight - offsetTop * 2) * (zoom.value - 1)) / 2;\r\n }\r\n return `translate(${translateX}px, ${translateY}px) scale(${zoom.value}) rotate(${degree}deg)`;\r\n};\r\nconst textWysiwyg = ({ id, appState, onChange, onSubmit, getViewportCoords, element, canvas, excalidrawContainer, }) => {\r\n const textPropertiesUpdated = (updatedElement, editable) => {\r\n const currentFont = editable.style.fontFamily.replaceAll('\"', \"\");\r\n if ((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontFamilyString)({ fontFamily: updatedElement.fontFamily }) !==\r\n currentFont) {\r\n return true;\r\n }\r\n if (`${updatedElement.fontSize}px` !== editable.style.fontSize) {\r\n return true;\r\n }\r\n return false;\r\n };\r\n let originalContainerHeight;\r\n let approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(element)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(element))\r\n : 0;\r\n const updateWysiwygStyle = () => {\r\n var _a, _b;\r\n const updatedElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(id);\r\n if (updatedElement && (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)) {\r\n let coordX = updatedElement.x;\r\n let coordY = updatedElement.y;\r\n let container = (updatedElement === null || updatedElement === void 0 ? void 0 : updatedElement.containerId)\r\n ? _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement).getElement(updatedElement.containerId)\r\n : null;\r\n let maxWidth = updatedElement.width;\r\n let maxHeight = updatedElement.height;\r\n let width = updatedElement.width;\r\n const height = editable.scrollHeight === 0\r\n ? updatedElement.height\r\n : editable.scrollHeight;\r\n if (container && updatedElement.containerId) {\r\n const propertiesUpdated = textPropertiesUpdated(updatedElement, editable);\r\n if (propertiesUpdated) {\r\n const currentContainer = (_b = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updatedElement)) === null || _b === void 0 ? void 0 : _b.getElement(updatedElement.containerId);\r\n approxLineHeight = (0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updatedElement)\r\n ? (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getApproxLineHeight)((0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement))\r\n : 0;\r\n if (updatedElement.height > currentContainer.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2) {\r\n const nextHeight = updatedElement.height + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n originalContainerHeight = nextHeight;\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: nextHeight });\r\n container = Object.assign(Object.assign({}, container), { height: nextHeight });\r\n }\r\n editable.style.height = `${updatedElement.height}px`;\r\n }\r\n if (!originalContainerHeight) {\r\n originalContainerHeight = container.height;\r\n }\r\n maxWidth = container.width - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n maxHeight = container.height - _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING * 2;\r\n width = maxWidth;\r\n // The coordinates of text box set a distance of\r\n // 30px to preserve padding\r\n coordX = container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING;\r\n // autogrow container height if text exceeds\r\n if (editable.scrollHeight > maxHeight) {\r\n const diff = Math.min(editable.scrollHeight - maxHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height + diff });\r\n return;\r\n }\r\n else if (\r\n // autoshrink container height until original container height\r\n // is reached when text is removed\r\n container.height > originalContainerHeight &&\r\n editable.scrollHeight < maxHeight) {\r\n const diff = Math.min(maxHeight - editable.scrollHeight, approxLineHeight);\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, { height: container.height - diff });\r\n }\r\n // Start pushing text upward until a diff of 30px (padding)\r\n // is reached\r\n else {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n if (lines > 1 || propertiesUpdated) {\r\n // vertically center align the text\r\n coordY =\r\n container.y + container.height / 2 - editable.scrollHeight / 2;\r\n }\r\n }\r\n }\r\n const [viewportX, viewportY] = getViewportCoords(coordX, coordY);\r\n const { textAlign, angle } = updatedElement;\r\n editable.value = updatedElement.originalText || updatedElement.text;\r\n const lines = updatedElement.originalText.split(\"\\n\");\r\n const lineHeight = updatedElement.containerId\r\n ? approxLineHeight\r\n : updatedElement.height / lines.length;\r\n if (!container) {\r\n maxWidth =\r\n (appState.width + appState.offsetLeft - viewportX - 8) / appState.zoom.value -\r\n // margin-right of parent if any\r\n Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2));\r\n }\r\n // Make sure text editor height doesn't go beyond viewport\r\n const editorMaxHeight = (appState.height + appState.offsetTop - viewportY) / appState.zoom.value;\r\n console.log({\r\n maxWidth,\r\n editorMaxHeight,\r\n width,\r\n height,\r\n viewportX,\r\n viewportY,\r\n sceneX: coordX,\r\n sceneY: coordY,\r\n appWidth: appState.width,\r\n appHeight: appState.height,\r\n scrollX: appState.scrollX,\r\n scrollY: appState.scrollY,\r\n offsetTop: appState.offsetTop,\r\n offsetLeft: appState.offsetLeft,\r\n zoom: appState.zoom.value,\r\n translation: appState.zoom.translation,\r\n marginRight: Number(getComputedStyle(excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.parentNode).marginRight.slice(0, -2)),\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight)\r\n });\r\n Object.assign(editable.style, {\r\n font: (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updatedElement),\r\n // must be defined *after* font ¯\\_(ツ)_/¯\r\n lineHeight: `${lineHeight}px`,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n left: `${viewportX}px`,\r\n top: `${viewportY}px`,\r\n transform: getTransform(width, height, angle, appState, maxWidth, editorMaxHeight),\r\n textAlign,\r\n color: updatedElement.strokeColor,\r\n opacity: updatedElement.opacity / 100,\r\n filter: \"var(--theme-filter)\",\r\n maxWidth: `${maxWidth}px`,\r\n maxHeight: `${editorMaxHeight}px`,\r\n });\r\n }\r\n };\r\n const editable = document.createElement(\"textarea\");\r\n editable.dir = \"auto\";\r\n editable.tabIndex = 0;\r\n editable.dataset.type = \"wysiwyg\";\r\n // prevent line wrapping on Safari\r\n editable.wrap = \"off\";\r\n editable.classList.add(\"excalidraw-wysiwyg\");\r\n let whiteSpace = \"pre\";\r\n let wordBreak = \"normal\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element)) {\r\n whiteSpace = \"pre-wrap\";\r\n wordBreak = \"break-word\";\r\n }\r\n Object.assign(editable.style, {\r\n position: \"absolute\",\r\n display: \"inline-block\",\r\n minHeight: \"1em\",\r\n backfaceVisibility: \"hidden\",\r\n margin: 0,\r\n padding: 0,\r\n border: 0,\r\n outline: 0,\r\n resize: \"none\",\r\n background: \"transparent\",\r\n overflow: \"hidden\",\r\n // must be specified because in dark mode canvas creates a stacking context\r\n zIndex: \"var(--zIndex-wysiwyg)\",\r\n wordBreak,\r\n // prevent line wrapping (`whitespace: nowrap` doesn't work on FF)\r\n whiteSpace,\r\n overflowWrap: \"break-word\",\r\n });\r\n updateWysiwygStyle();\r\n if (onChange) {\r\n editable.oninput = () => {\r\n const lines = editable.scrollHeight / approxLineHeight;\r\n // auto increase height only when lines > 1 so its\r\n // measured correctly and vertically alignes for\r\n // first line as well as setting height to \"auto\"\r\n // doubles the height as soon as user starts typing\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isBoundToContainer)(element) && lines > 1) {\r\n editable.style.height = \"auto\";\r\n editable.style.height = `${editable.scrollHeight}px`;\r\n }\r\n onChange(normalizeText(editable.value));\r\n };\r\n }\r\n editable.onkeydown = (event) => {\r\n event.stopPropagation();\r\n if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ESCAPE) {\r\n event.preventDefault();\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.ENTER && event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD]) {\r\n event.preventDefault();\r\n if (event.isComposing || event.keyCode === 229) {\r\n return;\r\n }\r\n submittedViaKeyboard = true;\r\n handleSubmit();\r\n }\r\n else if (event.key === _keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.TAB ||\r\n (event[_keys__WEBPACK_IMPORTED_MODULE_0__.KEYS.CTRL_OR_CMD] &&\r\n (event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT ||\r\n event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_RIGHT))) {\r\n event.preventDefault();\r\n if (event.shiftKey || event.code === _keys__WEBPACK_IMPORTED_MODULE_0__.CODES.BRACKET_LEFT) {\r\n outdent();\r\n }\r\n else {\r\n indent();\r\n }\r\n // We must send an input event to resize the element\r\n editable.dispatchEvent(new Event(\"input\"));\r\n }\r\n };\r\n const TAB_SIZE = 4;\r\n const TAB = \" \".repeat(TAB_SIZE);\r\n const RE_LEADING_TAB = new RegExp(`^ {1,${TAB_SIZE}}`);\r\n const indent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex);\r\n value = `${startValue}${TAB}${endValue}`;\r\n });\r\n editable.value = value;\r\n editable.selectionStart = selectionStart + TAB_SIZE;\r\n editable.selectionEnd = selectionEnd + TAB_SIZE * linesStartIndices.length;\r\n };\r\n const outdent = () => {\r\n const { selectionStart, selectionEnd } = editable;\r\n const linesStartIndices = getSelectedLinesStartIndices();\r\n const removedTabs = [];\r\n let value = editable.value;\r\n linesStartIndices.forEach((startIndex) => {\r\n const tabMatch = value\r\n .slice(startIndex, startIndex + TAB_SIZE)\r\n .match(RE_LEADING_TAB);\r\n if (tabMatch) {\r\n const startValue = value.slice(0, startIndex);\r\n const endValue = value.slice(startIndex + tabMatch[0].length);\r\n // Delete a tab from the line\r\n value = `${startValue}${endValue}`;\r\n removedTabs.push(startIndex);\r\n }\r\n });\r\n editable.value = value;\r\n if (removedTabs.length) {\r\n if (selectionStart > removedTabs[removedTabs.length - 1]) {\r\n editable.selectionStart = Math.max(selectionStart - TAB_SIZE, removedTabs[removedTabs.length - 1]);\r\n }\r\n else {\r\n // If the cursor is before the first tab removed, ex:\r\n // Line| #1\r\n // Line #2\r\n // Lin|e #3\r\n // we should reset the selectionStart to his initial value.\r\n editable.selectionStart = selectionStart;\r\n }\r\n editable.selectionEnd = Math.max(editable.selectionStart, selectionEnd - TAB_SIZE * removedTabs.length);\r\n }\r\n };\r\n /**\r\n * @returns indeces of start positions of selected lines, in reverse order\r\n */\r\n const getSelectedLinesStartIndices = () => {\r\n let { selectionStart, selectionEnd, value } = editable;\r\n // chars before selectionStart on the same line\r\n const startOffset = value.slice(0, selectionStart).match(/[^\\n]*$/)[0]\r\n .length;\r\n // put caret at the start of the line\r\n selectionStart = selectionStart - startOffset;\r\n const selected = value.slice(selectionStart, selectionEnd);\r\n return selected\r\n .split(\"\\n\")\r\n .reduce((startIndices, line, idx, lines) => startIndices.concat(idx\r\n ? // curr line index is prev line's start + prev line's length + \\n\r\n startIndices[idx - 1] + lines[idx - 1].length + 1\r\n : // first selected line\r\n selectionStart), [])\r\n .reverse();\r\n };\r\n const stopEvent = (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n // using a state variable instead of passing it to the handleSubmit callback\r\n // so that we don't need to create separate a callback for event handlers\r\n let submittedViaKeyboard = false;\r\n const handleSubmit = () => {\r\n var _a, _b;\r\n // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg\r\n // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the\r\n // wysiwyg on update\r\n cleanup();\r\n const updateElement = (_a = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element)) === null || _a === void 0 ? void 0 : _a.getElement(element.id);\r\n if (!updateElement) {\r\n return;\r\n }\r\n let wrappedText = \"\";\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && (updateElement === null || updateElement === void 0 ? void 0 : updateElement.containerId)) {\r\n const container = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(updateElement).getElement(updateElement.containerId);\r\n if (container) {\r\n wrappedText = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.wrapText)(editable.value, (0,_utils__WEBPACK_IMPORTED_MODULE_1__.getFontString)(updateElement), container.width);\r\n if ((0,_typeChecks__WEBPACK_IMPORTED_MODULE_3__.isTextElement)(updateElement) && updateElement.containerId) {\r\n const editorHeight = Number(editable.style.height.slice(0, -2));\r\n if (editable.value) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(updateElement, {\r\n // vertically center align\r\n y: container.y + container.height / 2 - editorHeight / 2,\r\n height: editorHeight,\r\n width: Number(editable.style.width.slice(0, -2)),\r\n // preserve padding\r\n x: container.x + _constants__WEBPACK_IMPORTED_MODULE_4__.PADDING,\r\n });\r\n const boundTextElementId = (0,_textElement__WEBPACK_IMPORTED_MODULE_6__.getBoundTextElementId)(container);\r\n if (!boundTextElementId || boundTextElementId !== element.id) {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (container.boundElements || []).concat({\r\n type: \"text\",\r\n id: element.id,\r\n }),\r\n });\r\n }\r\n }\r\n else {\r\n (0,_mutateElement__WEBPACK_IMPORTED_MODULE_5__.mutateElement)(container, {\r\n boundElements: (_b = container.boundElements) === null || _b === void 0 ? void 0 : _b.filter((ele) => ele.type !== \"text\"),\r\n });\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n wrappedText = editable.value;\r\n }\r\n onSubmit({\r\n text: normalizeText(wrappedText),\r\n viaKeyboard: submittedViaKeyboard,\r\n originalText: editable.value,\r\n });\r\n };\r\n const cleanup = () => {\r\n if (isDestroyed) {\r\n return;\r\n }\r\n isDestroyed = true;\r\n // remove events to ensure they don't late-fire\r\n editable.onblur = null;\r\n editable.oninput = null;\r\n editable.onkeydown = null;\r\n if (observer) {\r\n observer.disconnect();\r\n }\r\n window.removeEventListener(\"resize\", updateWysiwygStyle);\r\n window.removeEventListener(\"wheel\", stopEvent, true);\r\n window.removeEventListener(\"pointerdown\", onPointerDown);\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n window.removeEventListener(\"blur\", handleSubmit);\r\n unbindUpdate();\r\n editable.remove();\r\n };\r\n const bindBlurEvent = (event) => {\r\n window.removeEventListener(\"pointerup\", bindBlurEvent);\r\n // Deferred so that the pointerdown that initiates the wysiwyg doesn't\r\n // trigger the blur on ensuing pointerup.\r\n // Also to handle cases such as picking a color which would trigger a blur\r\n // in that same tick.\r\n const target = event === null || event === void 0 ? void 0 : event.target;\r\n const isTargetColorPicker = target instanceof HTMLInputElement &&\r\n target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(target);\r\n setTimeout(() => {\r\n editable.onblur = handleSubmit;\r\n if (target && isTargetColorPicker) {\r\n target.onblur = () => {\r\n editable.focus();\r\n };\r\n }\r\n // case: clicking on the same property → no change → no update → no focus\r\n if (!isTargetColorPicker) {\r\n editable.focus();\r\n }\r\n });\r\n };\r\n // prevent blur when changing properties from the menu\r\n const onPointerDown = (event) => {\r\n const isTargetColorPicker = event.target instanceof HTMLInputElement &&\r\n event.target.closest(\".color-picker-input\") &&\r\n (0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target);\r\n if (((event.target instanceof HTMLElement ||\r\n event.target instanceof SVGElement) &&\r\n event.target.closest(`.${_constants__WEBPACK_IMPORTED_MODULE_4__.CLASSES.SHAPE_ACTIONS_MENU}`) &&\r\n !(0,_utils__WEBPACK_IMPORTED_MODULE_1__.isWritableElement)(event.target)) ||\r\n isTargetColorPicker) {\r\n editable.onblur = null;\r\n window.addEventListener(\"pointerup\", bindBlurEvent);\r\n // handle edge-case where pointerup doesn't fire e.g. due to user\r\n // alt-tabbing away\r\n window.addEventListener(\"blur\", handleSubmit);\r\n }\r\n };\r\n // handle updates of textElement properties of editing element\r\n const unbindUpdate = _scene_Scene__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getScene(element).addCallback(() => {\r\n var _a;\r\n updateWysiwygStyle();\r\n const isColorPickerActive = !!((_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest(\".color-picker-input\"));\r\n if (!isColorPickerActive) {\r\n editable.focus();\r\n }\r\n });\r\n // ---------------------------------------------------------------------------\r\n let isDestroyed = false;\r\n // select on init (focusing is done separately inside the bindBlurEvent()\r\n // because we need it to happen *after* the blur event from `pointerdown`)\r\n editable.select();\r\n bindBlurEvent();\r\n // reposition wysiwyg in case of canvas is resized. Using ResizeObserver\r\n // is preferred so we catch changes from host, where window may not resize.\r\n let observer = null;\r\n if (canvas && \"ResizeObserver\" in window) {\r\n observer = new window.ResizeObserver(() => {\r\n updateWysiwygStyle();\r\n });\r\n observer.observe(canvas);\r\n }\r\n else {\r\n window.addEventListener(\"resize\", updateWysiwygStyle);\r\n }\r\n window.addEventListener(\"pointerdown\", onPointerDown);\r\n window.addEventListener(\"wheel\", stopEvent, {\r\n passive: false,\r\n capture: true,\r\n });\r\n excalidrawContainer === null || excalidrawContainer === void 0 ? void 0 : excalidrawContainer.querySelector(\".excalidraw-textEditorContainer\").appendChild(editable);\r\n};\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUM7UUFDSCxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQzFCO1NBQU07UUFDTCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLGtCQUFrQixDQUFDLENBQUM7S0FDdkQ7SUFFRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFO1FBQzFDLE9BQU8sRUFBRSxLQUFLO1FBQ2QsT0FBTyxFQUFFLElBQUk7S0FDZCxDQUFDLENBQUM7SUFDSCxtQkFBbUIsYUFBbkIsbUJBQW1CLHVCQUFuQixtQkFBbUIsQ0FDZixhQUFhLENBQUMsaUNBQWlDLEVBQ2hELFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMzQixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vZWxlbWVudC90ZXh0V3lzaXd5Zy50c3g/OGY0ZCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDT0RFUywgS0VZUyB9IGZyb20gXCIuLi9rZXlzXCI7XG5pbXBvcnQge1xuICBpc1dyaXRhYmxlRWxlbWVudCxcbiAgZ2V0Rm9udFN0cmluZyxcbiAgZ2V0Rm9udEZhbWlseVN0cmluZyxcbiAgc2NlbmVDb29yZHNUb1ZpZXdwb3J0Q29vcmRzLFxufSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCBTY2VuZSBmcm9tIFwiLi4vc2NlbmUvU2NlbmVcIjtcbmltcG9ydCB7IGlzQm91bmRUb0NvbnRhaW5lciwgaXNUZXh0RWxlbWVudCB9IGZyb20gXCIuL3R5cGVDaGVja3NcIjtcbmltcG9ydCB7IENMQVNTRVMsIFBBRERJTkcgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50LFxuICBFeGNhbGlkcmF3RWxlbWVudCxcbiAgRXhjYWxpZHJhd1RleHRFbGVtZW50LFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgQXBwU3RhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IG11dGF0ZUVsZW1lbnQgfSBmcm9tIFwiLi9tdXRhdGVFbGVtZW50XCI7XG5pbXBvcnQge1xuICBnZXRBcHByb3hMaW5lSGVpZ2h0LFxuICBnZXRCb3VuZFRleHRFbGVtZW50SWQsXG4gIHdyYXBUZXh0LFxufSBmcm9tIFwiLi90ZXh0RWxlbWVudFwiO1xuXG5jb25zdCBub3JtYWxpemVUZXh0ID0gKHRleHQ6IHN0cmluZykgPT4ge1xuICByZXR1cm4gKFxuICAgIHRleHRcbiAgICAgIC8vIHJlcGxhY2UgdGFicyB3aXRoIHNwYWNlcyBzbyB0aGV5IHJlbmRlciBhbmQgbWVhc3VyZSBjb3JyZWN0bHlcbiAgICAgIC5yZXBsYWNlKC9cXHQvZywgXCIgICAgICAgIFwiKVxuICAgICAgLy8gbm9ybWFsaXplIG5ld2xpbmVzXG4gICAgICAucmVwbGFjZSgvXFxyP1xcbnxcXHIvZywgXCJcXG5cIilcbiAgKTtcbn07XG5cbmNvbnN0IGdldFRyYW5zZm9ybSA9IChcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIGFuZ2xlOiBudW1iZXIsXG4gIGFwcFN0YXRlOiBBcHBTdGF0ZSxcbiAgbWF4V2lkdGg6IG51bWJlcixcbiAgbWF4SGVpZ2h0OiBudW1iZXIsXG4pID0+IHtcbiAgY29uc3QgeyB6b29tLCBvZmZzZXRUb3AsIG9mZnNldExlZnQgfSA9IGFwcFN0YXRlO1xuICBjb25zdCBkZWdyZWUgPSAoMTgwICogYW5nbGUpIC8gTWF0aC5QSTtcbiAgcmV0dXJuIGB0cmFuc2xhdGUoMHB4LCAwcHgpIHNjYWxlKCR7em9vbS52YWx1ZX0pIHJvdGF0ZSgke2RlZ3JlZX1kZWcpYDtcbiAgLy8gb2Zmc2V0cyBtdXN0IGJlIG11bHRpcGxpZWQgYnkgMiB0byBhY2NvdW50IGZvciB0aGUgZGl2aXNpb24gYnkgMiBvZlxuICAvLyB0aGUgd2hvbGUgZXhwcmVzc2lvbiBhZnRlcndhcmRzXG4gIGxldCB0cmFuc2xhdGVYID0gKCh3aWR0aCAtIG9mZnNldExlZnQgKiAyKSAqICh6b29tLnZhbHVlIC0gMSkpIC8gMjtcbiAgbGV0IHRyYW5zbGF0ZVkgPSAoKGhlaWdodCAtIG9mZnNldFRvcCAqIDIpICogKHpvb20udmFsdWUgLSAxKSkgLyAyO1xuICBpZiAod2lkdGggPiBtYXhXaWR0aCAmJiB6b29tLnZhbHVlICE9PSAxKSB7XG4gICAgdHJhbnNsYXRlWCA9ICgobWF4V2lkdGggLSBvZmZzZXRMZWZ0ICogMikgKiAoem9vbS52YWx1ZSAtIDEpKSAvIDJcbiAgfVxuICBpZiAoaGVpZ2h0ID4gbWF4SGVpZ2h0ICYmIHpvb20udmFsdWUgIT09IDEpIHtcbiAgICB0cmFuc2xhdGVZID0gKChtYXhIZWlnaHQgLSBvZmZzZXRUb3AgKiAyKSAqICh6b29tLnZhbHVlIC0gMSkpIC8gMjtcbiAgfVxuICByZXR1cm4gYHRyYW5zbGF0ZSgke3RyYW5zbGF0ZVh9cHgsICR7dHJhbnNsYXRlWX1weCkgc2NhbGUoJHt6b29tLnZhbHVlfSkgcm90YXRlKCR7ZGVncmVlfWRlZylgO1xufTtcblxuZXhwb3J0IGNvbnN0IHRleHRXeXNpd3lnID0gKHtcbiAgaWQsXG4gIGFwcFN0YXRlLFxuICBvbkNoYW5nZSxcbiAgb25TdWJtaXQsXG4gIGdldFZpZXdwb3J0Q29vcmRzLFxuICBlbGVtZW50LFxuICBjYW52YXMsXG4gIGV4Y2FsaWRyYXdDb250YWluZXIsXG59OiB7XG4gIGlkOiBFeGNhbGlkcmF3RWxlbWVudFtcImlkXCJdO1xuICBhcHBTdGF0ZTogQXBwU3RhdGU7XG4gIG9uQ2hhbmdlPzogKHRleHQ6IHN0cmluZykgPT4gdm9pZDtcbiAgb25TdWJtaXQ6IChkYXRhOiB7XG4gICAgdGV4dDogc3RyaW5nO1xuICAgIHZpYUtleWJvYXJkOiBib29sZWFuO1xuICAgIG9yaWdpbmFsVGV4dDogc3RyaW5nO1xuICB9KSA9PiB2b2lkO1xuICBnZXRWaWV3cG9ydENvb3JkczogKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBbbnVtYmVyLCBudW1iZXJdO1xuICBlbGVtZW50OiBFeGNhbGlkcmF3RWxlbWVudDtcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGw7XG4gIGV4Y2FsaWRyYXdDb250YWluZXI6IEhUTUxEaXZFbGVtZW50IHwgbnVsbDtcbn0pID0+IHtcbiAgY29uc3QgdGV4dFByb3BlcnRpZXNVcGRhdGVkID0gKFxuICAgIHVwZGF0ZWRFbGVtZW50OiBFeGNhbGlkcmF3VGV4dEVsZW1lbnQsXG4gICAgZWRpdGFibGU6IEhUTUxUZXh0QXJlYUVsZW1lbnQsXG4gICkgPT4ge1xuICAgIGNvbnN0IGN1cnJlbnRGb250ID0gZWRpdGFibGUuc3R5bGUuZm9udEZhbWlseS5yZXBsYWNlQWxsKCdcIicsIFwiXCIpO1xuICAgIGlmIChcbiAgICAgIGdldEZvbnRGYW1pbHlTdHJpbmcoeyBmb250RmFtaWx5OiB1cGRhdGVkRWxlbWVudC5mb250RmFtaWx5IH0pICE9PVxuICAgICAgY3VycmVudEZvbnRcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoYCR7dXBkYXRlZEVsZW1lbnQuZm9udFNpemV9cHhgICE9PSBlZGl0YWJsZS5zdHlsZS5mb250U2l6ZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgbGV0IG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0OiBudW1iZXI7XG4gIGxldCBhcHByb3hMaW5lSGVpZ2h0ID0gaXNUZXh0RWxlbWVudChlbGVtZW50KVxuICAgID8gZ2V0QXBwcm94TGluZUhlaWdodChnZXRGb250U3RyaW5nKGVsZW1lbnQpKVxuICAgIDogMDtcblxuICBjb25zdCB1cGRhdGVXeXNpd3lnU3R5bGUgPSAoKSA9PiB7XG4gICAgY29uc3QgdXBkYXRlZEVsZW1lbnQgPSBTY2VuZS5nZXRTY2VuZShlbGVtZW50KT8uZ2V0RWxlbWVudChpZCk7XG4gICAgaWYgKHVwZGF0ZWRFbGVtZW50ICYmIGlzVGV4dEVsZW1lbnQodXBkYXRlZEVsZW1lbnQpKSB7XG4gICAgICBsZXQgY29vcmRYID0gdXBkYXRlZEVsZW1lbnQueDtcbiAgICAgIGxldCBjb29yZFkgPSB1cGRhdGVkRWxlbWVudC55O1xuICAgICAgbGV0IGNvbnRhaW5lciA9IHVwZGF0ZWRFbGVtZW50Py5jb250YWluZXJJZFxuICAgICAgICA/IFNjZW5lLmdldFNjZW5lKHVwZGF0ZWRFbGVtZW50KSEuZ2V0RWxlbWVudCh1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZClcbiAgICAgICAgOiBudWxsO1xuICAgICAgbGV0IG1heFdpZHRoID0gdXBkYXRlZEVsZW1lbnQud2lkdGg7XG5cbiAgICAgIGxldCBtYXhIZWlnaHQgPSB1cGRhdGVkRWxlbWVudC5oZWlnaHQ7XG4gICAgICBsZXQgd2lkdGggPSB1cGRhdGVkRWxlbWVudC53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9XG4gICAgICAgIGVkaXRhYmxlLnNjcm9sbEhlaWdodCA9PT0gMFxuICAgICAgICAgID8gdXBkYXRlZEVsZW1lbnQuaGVpZ2h0XG4gICAgICAgICAgOiBlZGl0YWJsZS5zY3JvbGxIZWlnaHQ7XG4gICAgICBpZiAoY29udGFpbmVyICYmIHVwZGF0ZWRFbGVtZW50LmNvbnRhaW5lcklkKSB7XG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXNVcGRhdGVkID0gdGV4dFByb3BlcnRpZXNVcGRhdGVkKFxuICAgICAgICAgIHVwZGF0ZWRFbGVtZW50LFxuICAgICAgICAgIGVkaXRhYmxlLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzVXBkYXRlZCkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb250YWluZXIgPSBTY2VuZS5nZXRTY2VuZSh1cGRhdGVkRWxlbWVudCk/LmdldEVsZW1lbnQoXG4gICAgICAgICAgICB1cGRhdGVkRWxlbWVudC5jb250YWluZXJJZCxcbiAgICAgICAgICApIGFzIEV4Y2FsaWRyYXdCaW5kYWJsZUVsZW1lbnQ7XG4gICAgICAgICAgYXBwcm94TGluZUhlaWdodCA9IGlzVGV4dEVsZW1lbnQodXBkYXRlZEVsZW1lbnQpXG4gICAgICAgICAgICA/IGdldEFwcHJveExpbmVIZWlnaHQoZ2V0Rm9udFN0cmluZyh1cGRhdGVkRWxlbWVudCkpXG4gICAgICAgICAgICA6IDA7XG4gICAgICAgICAgaWYgKHVwZGF0ZWRFbGVtZW50LmhlaWdodCA+IGN1cnJlbnRDb250YWluZXIuaGVpZ2h0IC0gUEFERElORyAqIDIpIHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRIZWlnaHQgPSB1cGRhdGVkRWxlbWVudC5oZWlnaHQgKyBQQURESU5HICogMjtcbiAgICAgICAgICAgIG9yaWdpbmFsQ29udGFpbmVySGVpZ2h0ID0gbmV4dEhlaWdodDtcbiAgICAgICAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogbmV4dEhlaWdodCB9KTtcbiAgICAgICAgICAgIGNvbnRhaW5lciA9IHsgLi4uY29udGFpbmVyLCBoZWlnaHQ6IG5leHRIZWlnaHQgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWRpdGFibGUuc3R5bGUuaGVpZ2h0ID0gYCR7dXBkYXRlZEVsZW1lbnQuaGVpZ2h0fXB4YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW9yaWdpbmFsQ29udGFpbmVySGVpZ2h0KSB7XG4gICAgICAgICAgb3JpZ2luYWxDb250YWluZXJIZWlnaHQgPSBjb250YWluZXIuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIG1heFdpZHRoID0gY29udGFpbmVyLndpZHRoIC0gUEFERElORyAqIDI7XG4gICAgICAgIG1heEhlaWdodCA9IGNvbnRhaW5lci5oZWlnaHQgLSBQQURESU5HICogMjtcbiAgICAgICAgd2lkdGggPSBtYXhXaWR0aDtcbiAgICAgICAgLy8gVGhlIGNvb3JkaW5hdGVzIG9mIHRleHQgYm94IHNldCBhIGRpc3RhbmNlIG9mXG4gICAgICAgIC8vIDMwcHggdG8gcHJlc2VydmUgcGFkZGluZ1xuICAgICAgICBjb29yZFggPSBjb250YWluZXIueCArIFBBRERJTkc7XG5cbiAgICAgICAgLy8gYXV0b2dyb3cgY29udGFpbmVyIGhlaWdodCBpZiB0ZXh0IGV4Y2VlZHNcbiAgICAgICAgaWYgKGVkaXRhYmxlLnNjcm9sbEhlaWdodCA+IG1heEhlaWdodCkge1xuICAgICAgICAgIGNvbnN0IGRpZmYgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIGVkaXRhYmxlLnNjcm9sbEhlaWdodCAtIG1heEhlaWdodCxcbiAgICAgICAgICAgIGFwcHJveExpbmVIZWlnaHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwgeyBoZWlnaHQ6IGNvbnRhaW5lci5oZWlnaHQgKyBkaWZmIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAvLyBhdXRvc2hyaW5rIGNvbnRhaW5lciBoZWlnaHQgdW50aWwgb3JpZ2luYWwgY29udGFpbmVyIGhlaWdodFxuICAgICAgICAgIC8vIGlzIHJlYWNoZWQgd2hlbiB0ZXh0IGlzIHJlbW92ZWRcbiAgICAgICAgICBjb250YWluZXIuaGVpZ2h0ID4gb3JpZ2luYWxDb250YWluZXJIZWlnaHQgJiZcbiAgICAgICAgICBlZGl0YWJsZS5zY3JvbGxIZWlnaHQgPCBtYXhIZWlnaHRcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZGlmZiA9IE1hdGgubWluKFxuICAgICAgICAgICAgbWF4SGVpZ2h0IC0gZWRpdGFibGUuc2Nyb2xsSGVpZ2h0LFxuICAgICAgICAgICAgYXBwcm94TGluZUhlaWdodCxcbiAgICAgICAgICApO1xuICAgICAgICAgIG11dGF0ZUVsZW1lbnQoY29udGFpbmVyLCB7IGhlaWdodDogY29udGFpbmVyLmhlaWdodCAtIGRpZmYgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RhcnQgcHVzaGluZyB0ZXh0IHVwd2FyZCB1bnRpbCBhIGRpZmYgb2YgMzBweCAocGFkZGluZylcbiAgICAgICAgLy8gaXMgcmVhY2hlZFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjb25zdCBsaW5lcyA9IGVkaXRhYmxlLnNjcm9sbEhlaWdodCAvIGFwcHJveExpbmVIZWlnaHQ7XG5cbiAgICAgICAgICBpZiAobGluZXMgPiAxIHx8IHByb3BlcnRpZXNVcGRhdGVkKSB7XG4gICAgICAgICAgICAvLyB2ZXJ0aWNhbGx5IGNlbnRlciBhbGlnbiB0aGUgdGV4dFxuICAgICAgICAgICAgY29vcmRZID1cbiAgICAgICAgICAgICAgY29udGFpbmVyLnkgKyBjb250YWluZXIuaGVpZ2h0IC8gMiAtIGVkaXRhYmxlLnNjcm9sbEhlaWdodCAvIDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBbdmlld3BvcnRYLCB2aWV3cG9ydFldID0gZ2V0Vmlld3BvcnRDb29yZHMoY29vcmRYLCBjb29yZFkpO1xuICAgICAgY29uc3QgeyB0ZXh0QWxpZ24sIGFuZ2xlIH0gPSB1cGRhdGVkRWxlbWVudDtcblxuICAgICAgZWRpdGFibGUudmFsdWUgPSB1cGRhdGVkRWxlbWVudC5vcmlnaW5hbFRleHQgfHwgdXBkYXRlZEVsZW1lbnQudGV4dDtcbiAgICAgIGNvbnN0IGxpbmVzID0gdXBkYXRlZEVsZW1lbnQub3JpZ2luYWxUZXh0LnNwbGl0KFwiXFxuXCIpO1xuICAgICAgY29uc3QgbGluZUhlaWdodCA9IHVwZGF0ZWRFbGVtZW50LmNvbnRhaW5lcklkXG4gICAgICAgID8gYXBwcm94TGluZUhlaWdodFxuICAgICAgICA6IHVwZGF0ZWRFbGVtZW50LmhlaWdodCAvIGxpbmVzLmxlbmd0aDtcbiAgICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICAgIG1heFdpZHRoID1cbiAgICAgICAgICAoIGFwcFN0YXRlLndpZHRoICsgYXBwU3RhdGUub2Zmc2V0TGVmdCAtIHZpZXdwb3J0WCAtIDgpIC8gYXBwU3RhdGUuem9vbS52YWx1ZSAtXG4gICAgICAgICAgLy8gbWFyZ2luLXJpZ2h0IG9mIHBhcmVudCBpZiBhbnlcbiAgICAgICAgICBOdW1iZXIoXG4gICAgICAgICAgICBnZXRDb21wdXRlZFN0eWxlKFxuICAgICAgICAgICAgICBleGNhbGlkcmF3Q29udGFpbmVyPy5wYXJlbnROb2RlIGFzIEVsZW1lbnQsXG4gICAgICAgICAgICApLm1hcmdpblJpZ2h0LnNsaWNlKDAsIC0yKSxcbiAgICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBNYWtlIHN1cmUgdGV4dCBlZGl0b3IgaGVpZ2h0IGRvZXNuJ3QgZ28gYmV5b25kIHZpZXdwb3J0XG4gICAgICBjb25zdCBlZGl0b3JNYXhIZWlnaHQgPVxuICAgICAgICAoYXBwU3RhdGUuaGVpZ2h0ICsgYXBwU3RhdGUub2Zmc2V0VG9wIC0gdmlld3BvcnRZKSAvIGFwcFN0YXRlLnpvb20udmFsdWU7XG5cbiAgICAgIGNvbnNvbGUubG9nKHtcbiAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgIGVkaXRvck1heEhlaWdodCxcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgdmlld3BvcnRYLFxuICAgICAgICB2aWV3cG9ydFksXG4gICAgICAgIHNjZW5lWDogY29vcmRYLFxuICAgICAgICBzY2VuZVk6IGNvb3JkWSxcbiAgICAgICAgYXBwV2lkdGg6YXBwU3RhdGUud2lkdGgsXG4gICAgICAgIGFwcEhlaWdodDphcHBTdGF0ZS5oZWlnaHQsXG4gICAgICAgIHNjcm9sbFg6IGFwcFN0YXRlLnNjcm9sbFgsXG4gICAgICAgIHNjcm9sbFk6IGFwcFN0YXRlLnNjcm9sbFksXG4gICAgICAgIG9mZnNldFRvcDogYXBwU3RhdGUub2Zmc2V0VG9wLFxuICAgICAgICBvZmZzZXRMZWZ0OiBhcHBTdGF0ZS5vZmZzZXRMZWZ0LFxuICAgICAgICB6b29tOiBhcHBTdGF0ZS56b29tLnZhbHVlLFxuICAgICAgICB0cmFuc2xhdGlvbjogYXBwU3RhdGUuem9vbS50cmFuc2xhdGlvbixcbiAgICAgICAgbWFyZ2luUmlnaHQ6IE51bWJlcihcbiAgICAgICAgICBnZXRDb21wdXRlZFN0eWxlKFxuICAgICAgICAgICAgZXhjYWxpZHJhd0NvbnRhaW5lcj8ucGFyZW50Tm9kZSBhcyBFbGVtZW50LFxuICAgICAgICAgICkubWFyZ2luUmlnaHQuc2xpY2UoMCwgLTIpLFxuICAgICAgICApLFxuICAgICAgICB0cmFuc2Zvcm06IGdldFRyYW5zZm9ybShcbiAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgYW5nbGUsXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgICAgZWRpdG9yTWF4SGVpZ2h0LFxuICAgICAgICApXG4gICAgICB9KTtcbiAgICAgIE9iamVjdC5hc3NpZ24oZWRpdGFibGUuc3R5bGUsIHtcbiAgICAgICAgZm9udDogZ2V0Rm9udFN0cmluZyh1cGRhdGVkRWxlbWVudCksXG4gICAgICAgIC8vIG11c3QgYmUgZGVmaW5lZCAqYWZ0ZXIqIGZvbnQgwq9cXF8o44OEKV8vwq9cbiAgICAgICAgbGluZUhlaWdodDogYCR7bGluZUhlaWdodH1weGAsXG4gICAgICAgIHdpZHRoOiBgJHt3aWR0aH1weGAsXG4gICAgICAgIGhlaWdodDogYCR7aGVpZ2h0fXB4YCxcbiAgICAgICAgbGVmdDogYCR7dmlld3BvcnRYfXB4YCxcbiAgICAgICAgdG9wOiBgJHt2aWV3cG9ydFl9cHhgLFxuICAgICAgICB0cmFuc2Zvcm06IGdldFRyYW5zZm9ybShcbiAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgYW5nbGUsXG4gICAgICAgICAgYXBwU3RhdGUsXG4gICAgICAgICAgbWF4V2lkdGgsXG4gICAgICAgICAgZWRpdG9yTWF4SGVpZ2h0LFxuICAgICAgICApLFxuICAgICAgICB0ZXh0QWxpZ24sXG4gICAgICAgIGNvbG9yOiB1cGRhdGVkRWxlbWVudC5zdHJva2VDb2xvcixcbiAgICAgICAgb3BhY2l0eTogdXBkYXRlZEVsZW1lbnQub3BhY2l0eSAvIDEwMCxcbiAgICAgICAgZmlsdGVyOiBcInZhcigtLXRoZW1lLWZpbHRlcilcIixcbiAgICAgICAgbWF4V2lkdGg6IGAke21heFdpZHRofXB4YCxcbiAgICAgICAgbWF4SGVpZ2h0OiBgJHtlZGl0b3JNYXhIZWlnaHR9cHhgLFxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGVkaXRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRleHRhcmVhXCIpO1xuXG4gIGVkaXRhYmxlLmRpciA9IFwiYXV0b1wiO1xuICBlZGl0YWJsZS50YWJJbmRleCA9IDA7XG4gIGVkaXRhYmxlLmRhdGFzZXQudHlwZSA9IFwid3lzaXd5Z1wiO1xuICAvLyBwcmV2ZW50IGxpbmUgd3JhcHBpbmcgb24gU2FmYXJpXG4gIGVkaXRhYmxlLndyYXAgPSBcIm9mZlwiO1xuICBlZGl0YWJsZS5jbGFzc0xpc3QuYWRkKFwiZXhjYWxpZHJhdy13eXNpd3lnXCIpO1xuXG4gIGxldCB3aGl0ZVNwYWNlID0gXCJwcmVcIjtcbiAgbGV0IHdvcmRCcmVhayA9IFwibm9ybWFsXCI7XG5cbiAgaWYgKGlzQm91bmRUb0NvbnRhaW5lcihlbGVtZW50KSkge1xuICAgIHdoaXRlU3BhY2UgPSBcInByZS13cmFwXCI7XG4gICAgd29yZEJyZWFrID0gXCJicmVhay13b3JkXCI7XG4gIH1cbiAgT2JqZWN0LmFzc2lnbihlZGl0YWJsZS5zdHlsZSwge1xuICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgZGlzcGxheTogXCJpbmxpbmUtYmxvY2tcIixcbiAgICBtaW5IZWlnaHQ6IFwiMWVtXCIsXG4gICAgYmFja2ZhY2VWaXNpYmlsaXR5OiBcImhpZGRlblwiLFxuICAgIG1hcmdpbjogMCxcbiAgICBwYWRkaW5nOiAwLFxuICAgIGJvcmRlcjogMCxcbiAgICBvdXRsaW5lOiAwLFxuICAgIHJlc2l6ZTogXCJub25lXCIsXG4gICAgYmFja2dyb3VuZDogXCJ0cmFuc3BhcmVudFwiLFxuICAgIG92ZXJmbG93OiBcImhpZGRlblwiLFxuICAgIC8vIG11c3QgYmUgc3BlY2lmaWVkIGJlY2F1c2UgaW4gZGFyayBtb2RlIGNhbnZhcyBjcmVhdGVzIGEgc3RhY2tpbmcgY29udGV4dFxuICAgIHpJbmRleDogXCJ2YXIoLS16SW5kZXgtd3lzaXd5ZylcIixcbiAgICB3b3JkQnJlYWssXG4gICAgLy8gcHJldmVudCBsaW5lIHdyYXBwaW5nIChgd2hpdGVzcGFjZTogbm93cmFwYCBkb2Vzbid0IHdvcmsgb24gRkYpXG4gICAgd2hpdGVTcGFjZSxcbiAgICBvdmVyZmxvd1dyYXA6IFwiYnJlYWstd29yZFwiLFxuICB9KTtcbiAgdXBkYXRlV3lzaXd5Z1N0eWxlKCk7XG5cbiAgaWYgKG9uQ2hhbmdlKSB7XG4gICAgZWRpdGFibGUub25pbnB1dCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGxpbmVzID0gZWRpdGFibGUuc2Nyb2xsSGVpZ2h0IC8gYXBwcm94TGluZUhlaWdodDtcbiAgICAgIC8vIGF1dG8gaW5jcmVhc2UgaGVpZ2h0IG9ubHkgd2hlbiBsaW5lcyAgPiAxIHNvIGl0c1xuICAgICAgLy8gbWVhc3VyZWQgY29ycmVjdGx5IGFuZCB2ZXJ0aWNhbGx5IGFsaWduZXMgZm9yXG4gICAgICAvLyBmaXJzdCBsaW5lIGFzIHdlbGwgYXMgc2V0dGluZyBoZWlnaHQgdG8gXCJhdXRvXCJcbiAgICAgIC8vIGRvdWJsZXMgdGhlIGhlaWdodCBhcyBzb29uIGFzIHVzZXIgc3RhcnRzIHR5cGluZ1xuICAgICAgaWYgKGlzQm91bmRUb0NvbnRhaW5lcihlbGVtZW50KSAmJiBsaW5lcyA+IDEpIHtcbiAgICAgICAgZWRpdGFibGUuc3R5bGUuaGVpZ2h0ID0gXCJhdXRvXCI7XG4gICAgICAgIGVkaXRhYmxlLnN0eWxlLmhlaWdodCA9IGAke2VkaXRhYmxlLnNjcm9sbEhlaWdodH1weGA7XG4gICAgICB9XG4gICAgICBvbkNoYW5nZShub3JtYWxpemVUZXh0KGVkaXRhYmxlLnZhbHVlKSk7XG4gICAgfTtcbiAgfVxuXG4gIGVkaXRhYmxlLm9ua2V5ZG93biA9IChldmVudCkgPT4ge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmIChldmVudC5rZXkgPT09IEtFWVMuRVNDQVBFKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgc3VibWl0dGVkVmlhS2V5Ym9hcmQgPSB0cnVlO1xuICAgICAgaGFuZGxlU3VibWl0KCk7XG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IEtFWVMuRU5URVIgJiYgZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoZXZlbnQuaXNDb21wb3NpbmcgfHwgZXZlbnQua2V5Q29kZSA9PT0gMjI5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHN1Ym1pdHRlZFZpYUtleWJvYXJkID0gdHJ1ZTtcbiAgICAgIGhhbmRsZVN1Ym1pdCgpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBldmVudC5rZXkgPT09IEtFWVMuVEFCIHx8XG4gICAgICAoZXZlbnRbS0VZUy5DVFJMX09SX0NNRF0gJiZcbiAgICAgICAgKGV2ZW50LmNvZGUgPT09IENPREVTLkJSQUNLRVRfTEVGVCB8fFxuICAgICAgICAgIGV2ZW50LmNvZGUgPT09IENPREVTLkJSQUNLRVRfUklHSFQpKVxuICAgICkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChldmVudC5zaGlmdEtleSB8fCBldmVudC5jb2RlID09PSBDT0RFUy5CUkFDS0VUX0xFRlQpIHtcbiAgICAgICAgb3V0ZGVudCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5kZW50KCk7XG4gICAgICB9XG4gICAgICAvLyBXZSBtdXN0IHNlbmQgYW4gaW5wdXQgZXZlbnQgdG8gcmVzaXplIHRoZSBlbGVtZW50XG4gICAgICBlZGl0YWJsZS5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIpKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgVEFCX1NJWkUgPSA0O1xuICBjb25zdCBUQUIgPSBcIiBcIi5yZXBlYXQoVEFCX1NJWkUpO1xuICBjb25zdCBSRV9MRUFESU5HX1RBQiA9IG5ldyBSZWdFeHAoYF4gezEsJHtUQUJfU0laRX19YCk7XG4gIGNvbnN0IGluZGVudCA9ICgpID0+IHtcbiAgICBjb25zdCB7IHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQgfSA9IGVkaXRhYmxlO1xuICAgIGNvbnN0IGxpbmVzU3RhcnRJbmRpY2VzID0gZ2V0U2VsZWN0ZWRMaW5lc1N0YXJ0SW5kaWNlcygpO1xuXG4gICAgbGV0IHZhbHVlID0gZWRpdGFibGUudmFsdWU7XG4gICAgbGluZXNTdGFydEluZGljZXMuZm9yRWFjaCgoc3RhcnRJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBzdGFydFZhbHVlID0gdmFsdWUuc2xpY2UoMCwgc3RhcnRJbmRleCk7XG4gICAgICBjb25zdCBlbmRWYWx1ZSA9IHZhbHVlLnNsaWNlKHN0YXJ0SW5kZXgpO1xuXG4gICAgICB2YWx1ZSA9IGAke3N0YXJ0VmFsdWV9JHtUQUJ9JHtlbmRWYWx1ZX1gO1xuICAgIH0pO1xuXG4gICAgZWRpdGFibGUudmFsdWUgPSB2YWx1ZTtcblxuICAgIGVkaXRhYmxlLnNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgKyBUQUJfU0laRTtcbiAgICBlZGl0YWJsZS5zZWxlY3Rpb25FbmQgPSBzZWxlY3Rpb25FbmQgKyBUQUJfU0laRSAqIGxpbmVzU3RhcnRJbmRpY2VzLmxlbmd0aDtcbiAgfTtcblxuICBjb25zdCBvdXRkZW50ID0gKCkgPT4ge1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCB9ID0gZWRpdGFibGU7XG4gICAgY29uc3QgbGluZXNTdGFydEluZGljZXMgPSBnZXRTZWxlY3RlZExpbmVzU3RhcnRJbmRpY2VzKCk7XG4gICAgY29uc3QgcmVtb3ZlZFRhYnM6IG51bWJlcltdID0gW107XG5cbiAgICBsZXQgdmFsdWUgPSBlZGl0YWJsZS52YWx1ZTtcbiAgICBsaW5lc1N0YXJ0SW5kaWNlcy5mb3JFYWNoKChzdGFydEluZGV4KSA9PiB7XG4gICAgICBjb25zdCB0YWJNYXRjaCA9IHZhbHVlXG4gICAgICAgIC5zbGljZShzdGFydEluZGV4LCBzdGFydEluZGV4ICsgVEFCX1NJWkUpXG4gICAgICAgIC5tYXRjaChSRV9MRUFESU5HX1RBQik7XG5cbiAgICAgIGlmICh0YWJNYXRjaCkge1xuICAgICAgICBjb25zdCBzdGFydFZhbHVlID0gdmFsdWUuc2xpY2UoMCwgc3RhcnRJbmRleCk7XG4gICAgICAgIGNvbnN0IGVuZFZhbHVlID0gdmFsdWUuc2xpY2Uoc3RhcnRJbmRleCArIHRhYk1hdGNoWzBdLmxlbmd0aCk7XG5cbiAgICAgICAgLy8gRGVsZXRlIGEgdGFiIGZyb20gdGhlIGxpbmVcbiAgICAgICAgdmFsdWUgPSBgJHtzdGFydFZhbHVlfSR7ZW5kVmFsdWV9YDtcbiAgICAgICAgcmVtb3ZlZFRhYnMucHVzaChzdGFydEluZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGVkaXRhYmxlLnZhbHVlID0gdmFsdWU7XG5cbiAgICBpZiAocmVtb3ZlZFRhYnMubGVuZ3RoKSB7XG4gICAgICBpZiAoc2VsZWN0aW9uU3RhcnQgPiByZW1vdmVkVGFic1tyZW1vdmVkVGFicy5sZW5ndGggLSAxXSkge1xuICAgICAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCA9IE1hdGgubWF4KFxuICAgICAgICAgIHNlbGVjdGlvblN0YXJ0IC0gVEFCX1NJWkUsXG4gICAgICAgICAgcmVtb3ZlZFRhYnNbcmVtb3ZlZFRhYnMubGVuZ3RoIC0gMV0sXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiB0aGUgY3Vyc29yIGlzIGJlZm9yZSB0aGUgZmlyc3QgdGFiIHJlbW92ZWQsIGV4OlxuICAgICAgICAvLyBMaW5lfCAjMVxuICAgICAgICAvLyAgICAgTGluZSAjMlxuICAgICAgICAvLyBMaW58ZSAjM1xuICAgICAgICAvLyB3ZSBzaG91bGQgcmVzZXQgdGhlIHNlbGVjdGlvblN0YXJ0IHRvIGhpcyBpbml0aWFsIHZhbHVlLlxuICAgICAgICBlZGl0YWJsZS5zZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvblN0YXJ0O1xuICAgICAgfVxuICAgICAgZWRpdGFibGUuc2VsZWN0aW9uRW5kID0gTWF0aC5tYXgoXG4gICAgICAgIGVkaXRhYmxlLnNlbGVjdGlvblN0YXJ0LFxuICAgICAgICBzZWxlY3Rpb25FbmQgLSBUQUJfU0laRSAqIHJlbW92ZWRUYWJzLmxlbmd0aCxcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBpbmRlY2VzIG9mIHN0YXJ0IHBvc2l0aW9ucyBvZiBzZWxlY3RlZCBsaW5lcywgaW4gcmV2ZXJzZSBvcmRlclxuICAgKi9cbiAgY29uc3QgZ2V0U2VsZWN0ZWRMaW5lc1N0YXJ0SW5kaWNlcyA9ICgpID0+IHtcbiAgICBsZXQgeyBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kLCB2YWx1ZSB9ID0gZWRpdGFibGU7XG5cbiAgICAvLyBjaGFycyBiZWZvcmUgc2VsZWN0aW9uU3RhcnQgb24gdGhlIHNhbWUgbGluZVxuICAgIGNvbnN0IHN0YXJ0T2Zmc2V0ID0gdmFsdWUuc2xpY2UoMCwgc2VsZWN0aW9uU3RhcnQpLm1hdGNoKC9bXlxcbl0qJC8pIVswXVxuICAgICAgLmxlbmd0aDtcbiAgICAvLyBwdXQgY2FyZXQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsaW5lXG4gICAgc2VsZWN0aW9uU3RhcnQgPSBzZWxlY3Rpb25TdGFydCAtIHN0YXJ0T2Zmc2V0O1xuXG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB2YWx1ZS5zbGljZShzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKTtcblxuICAgIHJldHVybiBzZWxlY3RlZFxuICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAucmVkdWNlKFxuICAgICAgICAoc3RhcnRJbmRpY2VzLCBsaW5lLCBpZHgsIGxpbmVzKSA9PlxuICAgICAgICAgIHN0YXJ0SW5kaWNlcy5jb25jYXQoXG4gICAgICAgICAgICBpZHhcbiAgICAgICAgICAgICAgPyAvLyBjdXJyIGxpbmUgaW5kZXggaXMgcHJldiBsaW5lJ3Mgc3RhcnQgKyBwcmV2IGxpbmUncyBsZW5ndGggKyBcXG5cbiAgICAgICAgICAgICAgICBzdGFydEluZGljZXNbaWR4IC0gMV0gKyBsaW5lc1tpZHggLSAxXS5sZW5ndGggKyAxXG4gICAgICAgICAgICAgIDogLy8gZmlyc3Qgc2VsZWN0ZWQgbGluZVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0LFxuICAgICAgICAgICksXG4gICAgICAgIFtdIGFzIG51bWJlcltdLFxuICAgICAgKVxuICAgICAgLnJldmVyc2UoKTtcbiAgfTtcblxuICBjb25zdCBzdG9wRXZlbnQgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfTtcblxuICAvLyB1c2luZyBhIHN0YXRlIHZhcmlhYmxlIGluc3RlYWQgb2YgcGFzc2luZyBpdCB0byB0aGUgaGFuZGxlU3VibWl0IGNhbGxiYWNrXG4gIC8vIHNvIHRoYXQgd2UgZG9uJ3QgbmVlZCB0byBjcmVhdGUgc2VwYXJhdGUgYSBjYWxsYmFjayBmb3IgZXZlbnQgaGFuZGxlcnNcbiAgbGV0IHN1Ym1pdHRlZFZpYUtleWJvYXJkID0gZmFsc2U7XG4gIGNvbnN0IGhhbmRsZVN1Ym1pdCA9ICgpID0+IHtcbiAgICAvLyBjbGVhbnVwIG11c3QgYmUgcnVuIGJlZm9yZSBvblN1Ym1pdCBvdGhlcndpc2Ugd2hlbiBhcHAgYmx1cnMgdGhlIHd5c2l3eWdcbiAgICAvLyBpdCdkIGdldCBzdHVjayBpbiBhbiBpbmZpbml0ZSBsb29wIG9mIGJsdXLihpJvblN1Ym1pdCBhZnRlciB3ZSByZS1mb2N1cyB0aGVcbiAgICAvLyB3eXNpd3lnIG9uIHVwZGF0ZVxuICAgIGNsZWFudXAoKTtcbiAgICBjb25zdCB1cGRhdGVFbGVtZW50ID0gU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCk/LmdldEVsZW1lbnQoZWxlbWVudC5pZCk7XG4gICAgaWYgKCF1cGRhdGVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCB3cmFwcGVkVGV4dCA9IFwiXCI7XG4gICAgaWYgKGlzVGV4dEVsZW1lbnQodXBkYXRlRWxlbWVudCkgJiYgdXBkYXRlRWxlbWVudD8uY29udGFpbmVySWQpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IFNjZW5lLmdldFNjZW5lKHVwZGF0ZUVsZW1lbnQpIS5nZXRFbGVtZW50KFxuICAgICAgICB1cGRhdGVFbGVtZW50LmNvbnRhaW5lcklkLFxuICAgICAgKSBhcyBFeGNhbGlkcmF3QmluZGFibGVFbGVtZW50O1xuXG4gICAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgIHdyYXBwZWRUZXh0ID0gd3JhcFRleHQoXG4gICAgICAgICAgZWRpdGFibGUudmFsdWUsXG4gICAgICAgICAgZ2V0Rm9udFN0cmluZyh1cGRhdGVFbGVtZW50KSxcbiAgICAgICAgICBjb250YWluZXIud2lkdGgsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChpc1RleHRFbGVtZW50KHVwZGF0ZUVsZW1lbnQpICYmIHVwZGF0ZUVsZW1lbnQuY29udGFpbmVySWQpIHtcbiAgICAgICAgICBjb25zdCBlZGl0b3JIZWlnaHQgPSBOdW1iZXIoZWRpdGFibGUuc3R5bGUuaGVpZ2h0LnNsaWNlKDAsIC0yKSk7XG4gICAgICAgICAgaWYgKGVkaXRhYmxlLnZhbHVlKSB7XG4gICAgICAgICAgICBtdXRhdGVFbGVtZW50KHVwZGF0ZUVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgLy8gdmVydGljYWxseSBjZW50ZXIgYWxpZ25cbiAgICAgICAgICAgICAgeTogY29udGFpbmVyLnkgKyBjb250YWluZXIuaGVpZ2h0IC8gMiAtIGVkaXRvckhlaWdodCAvIDIsXG4gICAgICAgICAgICAgIGhlaWdodDogZWRpdG9ySGVpZ2h0LFxuICAgICAgICAgICAgICB3aWR0aDogTnVtYmVyKGVkaXRhYmxlLnN0eWxlLndpZHRoLnNsaWNlKDAsIC0yKSksXG4gICAgICAgICAgICAgIC8vIHByZXNlcnZlIHBhZGRpbmdcbiAgICAgICAgICAgICAgeDogY29udGFpbmVyLnggKyBQQURESU5HLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBib3VuZFRleHRFbGVtZW50SWQgPSBnZXRCb3VuZFRleHRFbGVtZW50SWQoY29udGFpbmVyKTtcbiAgICAgICAgICAgIGlmICghYm91bmRUZXh0RWxlbWVudElkIHx8IGJvdW5kVGV4dEVsZW1lbnRJZCAhPT0gZWxlbWVudC5pZCkge1xuICAgICAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwge1xuICAgICAgICAgICAgICAgIGJvdW5kRWxlbWVudHM6IChjb250YWluZXIuYm91bmRFbGVtZW50cyB8fCBbXSkuY29uY2F0KHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgICAgaWQ6IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtdXRhdGVFbGVtZW50KGNvbnRhaW5lciwge1xuICAgICAgICAgICAgICBib3VuZEVsZW1lbnRzOiBjb250YWluZXIuYm91bmRFbGVtZW50cz8uZmlsdGVyKFxuICAgICAgICAgICAgICAgIChlbGUpID0+IGVsZS50eXBlICE9PSBcInRleHRcIixcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB3cmFwcGVkVGV4dCA9IGVkaXRhYmxlLnZhbHVlO1xuICAgIH1cblxuICAgIG9uU3VibWl0KHtcbiAgICAgIHRleHQ6IG5vcm1hbGl6ZVRleHQod3JhcHBlZFRleHQpLFxuICAgICAgdmlhS2V5Ym9hcmQ6IHN1Ym1pdHRlZFZpYUtleWJvYXJkLFxuICAgICAgb3JpZ2luYWxUZXh0OiBlZGl0YWJsZS52YWx1ZSxcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgIGlmIChpc0Rlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpc0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgLy8gcmVtb3ZlIGV2ZW50cyB0byBlbnN1cmUgdGhleSBkb24ndCBsYXRlLWZpcmVcbiAgICBlZGl0YWJsZS5vbmJsdXIgPSBudWxsO1xuICAgIGVkaXRhYmxlLm9uaW5wdXQgPSBudWxsO1xuICAgIGVkaXRhYmxlLm9ua2V5ZG93biA9IG51bGw7XG5cbiAgICBpZiAob2JzZXJ2ZXIpIHtcbiAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG5cbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCB1cGRhdGVXeXNpd3lnU3R5bGUpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIiwgc3RvcEV2ZW50LCB0cnVlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJkb3duXCIsIG9uUG9pbnRlckRvd24pO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcnVwXCIsIGJpbmRCbHVyRXZlbnQpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYmx1clwiLCBoYW5kbGVTdWJtaXQpO1xuXG4gICAgdW5iaW5kVXBkYXRlKCk7XG5cbiAgICBlZGl0YWJsZS5yZW1vdmUoKTtcbiAgfTtcblxuICBjb25zdCBiaW5kQmx1ckV2ZW50ID0gKGV2ZW50PzogTW91c2VFdmVudCkgPT4ge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcnVwXCIsIGJpbmRCbHVyRXZlbnQpO1xuICAgIC8vIERlZmVycmVkIHNvIHRoYXQgdGhlIHBvaW50ZXJkb3duIHRoYXQgaW5pdGlhdGVzIHRoZSB3eXNpd3lnIGRvZXNuJ3RcbiAgICAvLyB0cmlnZ2VyIHRoZSBibHVyIG9uIGVuc3VpbmcgcG9pbnRlcnVwLlxuICAgIC8vIEFsc28gdG8gaGFuZGxlIGNhc2VzIHN1Y2ggYXMgcGlja2luZyBhIGNvbG9yIHdoaWNoIHdvdWxkIHRyaWdnZXIgYSBibHVyXG4gICAgLy8gaW4gdGhhdCBzYW1lIHRpY2suXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQ/LnRhcmdldDtcblxuICAgIGNvbnN0IGlzVGFyZ2V0Q29sb3JQaWNrZXIgPVxuICAgICAgdGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJlxuICAgICAgdGFyZ2V0LmNsb3Nlc3QoXCIuY29sb3ItcGlja2VyLWlucHV0XCIpICYmXG4gICAgICBpc1dyaXRhYmxlRWxlbWVudCh0YXJnZXQpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBlZGl0YWJsZS5vbmJsdXIgPSBoYW5kbGVTdWJtaXQ7XG4gICAgICBpZiAodGFyZ2V0ICYmIGlzVGFyZ2V0Q29sb3JQaWNrZXIpIHtcbiAgICAgICAgdGFyZ2V0Lm9uYmx1ciA9ICgpID0+IHtcbiAgICAgICAgICBlZGl0YWJsZS5mb2N1cygpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgLy8gY2FzZTogY2xpY2tpbmcgb24gdGhlIHNhbWUgcHJvcGVydHkg4oaSIG5vIGNoYW5nZSDihpIgbm8gdXBkYXRlIOKGkiBubyBmb2N1c1xuICAgICAgaWYgKCFpc1RhcmdldENvbG9yUGlja2VyKSB7XG4gICAgICAgIGVkaXRhYmxlLmZvY3VzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gcHJldmVudCBibHVyIHdoZW4gY2hhbmdpbmcgcHJvcGVydGllcyBmcm9tIHRoZSBtZW51XG4gIGNvbnN0IG9uUG9pbnRlckRvd24gPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICBjb25zdCBpc1RhcmdldENvbG9yUGlja2VyID1cbiAgICAgIGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiZcbiAgICAgIGV2ZW50LnRhcmdldC5jbG9zZXN0KFwiLmNvbG9yLXBpY2tlci1pbnB1dFwiKSAmJlxuICAgICAgaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KTtcbiAgICBpZiAoXG4gICAgICAoKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8XG4gICAgICAgIGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIFNWR0VsZW1lbnQpICYmXG4gICAgICAgIGV2ZW50LnRhcmdldC5jbG9zZXN0KGAuJHtDTEFTU0VTLlNIQVBFX0FDVElPTlNfTUVOVX1gKSAmJlxuICAgICAgICAhaXNXcml0YWJsZUVsZW1lbnQoZXZlbnQudGFyZ2V0KSkgfHxcbiAgICAgIGlzVGFyZ2V0Q29sb3JQaWNrZXJcbiAgICApIHtcbiAgICAgIGVkaXRhYmxlLm9uYmx1ciA9IG51bGw7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCBiaW5kQmx1ckV2ZW50KTtcbiAgICAgIC8vIGhhbmRsZSBlZGdlLWNhc2Ugd2hlcmUgcG9pbnRlcnVwIGRvZXNuJ3QgZmlyZSBlLmcuIGR1ZSB0byB1c2VyXG4gICAgICAvLyBhbHQtdGFiYmluZyBhd2F5XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgaGFuZGxlU3VibWl0KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gaGFuZGxlIHVwZGF0ZXMgb2YgdGV4dEVsZW1lbnQgcHJvcGVydGllcyBvZiBlZGl0aW5nIGVsZW1lbnRcbiAgY29uc3QgdW5iaW5kVXBkYXRlID0gU2NlbmUuZ2V0U2NlbmUoZWxlbWVudCkhLmFkZENhbGxiYWNrKCgpID0+IHtcbiAgICB1cGRhdGVXeXNpd3lnU3R5bGUoKTtcbiAgICBjb25zdCBpc0NvbG9yUGlja2VyQWN0aXZlID0gISFkb2N1bWVudC5hY3RpdmVFbGVtZW50Py5jbG9zZXN0KFxuICAgICAgXCIuY29sb3ItcGlja2VyLWlucHV0XCIsXG4gICAgKTtcbiAgICBpZiAoIWlzQ29sb3JQaWNrZXJBY3RpdmUpIHtcbiAgICAgIGVkaXRhYmxlLmZvY3VzKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBsZXQgaXNEZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBzZWxlY3Qgb24gaW5pdCAoZm9jdXNpbmcgaXMgZG9uZSBzZXBhcmF0ZWx5IGluc2lkZSB0aGUgYmluZEJsdXJFdmVudCgpXG4gIC8vIGJlY2F1c2Ugd2UgbmVlZCBpdCB0byBoYXBwZW4gKmFmdGVyKiB0aGUgYmx1ciBldmVudCBmcm9tIGBwb2ludGVyZG93bmApXG4gIGVkaXRhYmxlLnNlbGVjdCgpO1xuICBiaW5kQmx1ckV2ZW50KCk7XG5cbiAgLy8gcmVwb3NpdGlvbiB3eXNpd3lnIGluIGNhc2Ugb2YgY2FudmFzIGlzIHJlc2l6ZWQuIFVzaW5nIFJlc2l6ZU9ic2VydmVyXG4gIC8vIGlzIHByZWZlcnJlZCBzbyB3ZSBjYXRjaCBjaGFuZ2VzIGZyb20gaG9zdCwgd2hlcmUgd2luZG93IG1heSBub3QgcmVzaXplLlxuICBsZXQgb2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyIHwgbnVsbCA9IG51bGw7XG4gIGlmIChjYW52YXMgJiYgXCJSZXNpemVPYnNlcnZlclwiIGluIHdpbmRvdykge1xuICAgIG9ic2VydmVyID0gbmV3IHdpbmRvdy5SZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICB1cGRhdGVXeXNpd3lnU3R5bGUoKTtcbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGNhbnZhcyk7XG4gIH0gZWxzZSB7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgdXBkYXRlV3lzaXd5Z1N0eWxlKTtcbiAgfVxuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcmRvd25cIiwgb25Qb2ludGVyRG93bik7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwid2hlZWxcIiwgc3RvcEV2ZW50LCB7XG4gICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgY2FwdHVyZTogdHJ1ZSxcbiAgfSk7XG4gIGV4Y2FsaWRyYXdDb250YWluZXJcbiAgICA/LnF1ZXJ5U2VsZWN0b3IoXCIuZXhjYWxpZHJhdy10ZXh0RWRpdG9yQ29udGFpbmVyXCIpIVxuICAgIC5hcHBlbmRDaGlsZChlZGl0YWJsZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../element/textWysiwyg.tsx\n");
2546
2546
 
2547
2547
  /***/ }),
2548
2548