Files
e-tib.com/.next/dev/server/vendor-chunks/@lexical+utils@0.41.0.js
Marc Mintel d14122005d Initial commit: E-TIB production hardening & E2E foundation
Former-commit-id: ef04fca3d76375630c05aac117bf586953f3b657
2026-04-28 19:11:38 +02:00

25 lines
106 KiB
JavaScript

"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
exports.id = "vendor-chunks/@lexical+utils@0.41.0";
exports.ids = ["vendor-chunks/@lexical+utils@0.41.0"];
exports.modules = {
/***/ "(rsc)/./node_modules/.pnpm/@lexical+utils@0.41.0/node_modules/@lexical/utils/LexicalUtils.dev.mjs":
/*!***************************************************************************************************!*\
!*** ./node_modules/.pnpm/@lexical+utils@0.41.0/node_modules/@lexical/utils/LexicalUtils.dev.mjs ***!
\***************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ $descendantsMatching: () => (/* binding */ $descendantsMatching),\n/* harmony export */ $dfs: () => (/* binding */ $dfs),\n/* harmony export */ $dfsIterator: () => (/* binding */ $dfsIterator),\n/* harmony export */ $filter: () => (/* binding */ $filter),\n/* harmony export */ $findMatchingParent: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.$findMatchingParent),\n/* harmony export */ $firstToLastIterator: () => (/* binding */ $firstToLastIterator),\n/* harmony export */ $getAdjacentCaret: () => (/* binding */ $getAdjacentCaret),\n/* harmony export */ $getAdjacentSiblingOrParentSiblingCaret: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentSiblingOrParentSiblingCaret),\n/* harmony export */ $getDepth: () => (/* binding */ $getDepth),\n/* harmony export */ $getNearestBlockElementAncestorOrThrow: () => (/* binding */ $getNearestBlockElementAncestorOrThrow),\n/* harmony export */ $getNearestNodeOfType: () => (/* binding */ $getNearestNodeOfType),\n/* harmony export */ $getNextRightPreorderNode: () => (/* binding */ $getNextRightPreorderNode),\n/* harmony export */ $getNextSiblingOrParentSibling: () => (/* binding */ $getNextSiblingOrParentSibling),\n/* harmony export */ $handleIndentAndOutdent: () => (/* binding */ $handleIndentAndOutdent),\n/* harmony export */ $insertFirst: () => (/* binding */ $insertFirst),\n/* harmony export */ $insertNodeToNearestRoot: () => (/* binding */ $insertNodeToNearestRoot),\n/* harmony export */ $insertNodeToNearestRootAtCaret: () => (/* binding */ $insertNodeToNearestRootAtCaret),\n/* harmony export */ $isEditorIsNestedEditor: () => (/* binding */ $isEditorIsNestedEditor),\n/* harmony export */ $lastToFirstIterator: () => (/* binding */ $lastToFirstIterator),\n/* harmony export */ $restoreEditorState: () => (/* binding */ $restoreEditorState),\n/* harmony export */ $reverseDfs: () => (/* binding */ $reverseDfs),\n/* harmony export */ $reverseDfsIterator: () => (/* binding */ $reverseDfsIterator),\n/* harmony export */ $splitNode: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.$splitNode),\n/* harmony export */ $unwrapAndFilterDescendants: () => (/* binding */ $unwrapAndFilterDescendants),\n/* harmony export */ $unwrapNode: () => (/* binding */ $unwrapNode),\n/* harmony export */ $wrapNodeInElement: () => (/* binding */ $wrapNodeInElement),\n/* harmony export */ CAN_USE_BEFORE_INPUT: () => (/* binding */ CAN_USE_BEFORE_INPUT),\n/* harmony export */ CAN_USE_DOM: () => (/* binding */ CAN_USE_DOM),\n/* harmony export */ IS_ANDROID: () => (/* binding */ IS_ANDROID),\n/* harmony export */ IS_ANDROID_CHROME: () => (/* binding */ IS_ANDROID_CHROME),\n/* harmony export */ IS_APPLE: () => (/* binding */ IS_APPLE),\n/* harmony export */ IS_APPLE_WEBKIT: () => (/* binding */ IS_APPLE_WEBKIT),\n/* harmony export */ IS_CHROME: () => (/* binding */ IS_CHROME),\n/* harmony export */ IS_FIREFOX: () => (/* binding */ IS_FIREFOX),\n/* harmony export */ IS_IOS: () => (/* binding */ IS_IOS),\n/* harmony export */ IS_SAFARI: () => (/* binding */ IS_SAFARI),\n/* harmony export */ addClassNamesToElement: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.addClassNamesToElement),\n/* harmony export */ calculateZoomLevel: () => (/* binding */ calculateZoomLevel),\n/* harmony export */ isBlockDomNode: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.isBlockDomNode),\n/* harmony export */ isHTMLAnchorElement: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.isHTMLAnchorElement),\n/* harmony export */ isHTMLElement: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement),\n/* harmony export */ isInlineDomNode: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.isInlineDomNode),\n/* harmony export */ isMimeType: () => (/* binding */ isMimeType),\n/* harmony export */ makeStateWrapper: () => (/* binding */ makeStateWrapper),\n/* harmony export */ markSelection: () => (/* binding */ markSelection),\n/* harmony export */ mediaFileReader: () => (/* binding */ mediaFileReader),\n/* harmony export */ mergeRegister: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.mergeRegister),\n/* harmony export */ objectKlassEquals: () => (/* binding */ objectKlassEquals),\n/* harmony export */ positionNodeOnRange: () => (/* binding */ mlcPositionNodeOnRange),\n/* harmony export */ registerNestedElementResolver: () => (/* binding */ registerNestedElementResolver),\n/* harmony export */ removeClassNamesFromElement: () => (/* reexport safe */ lexical__WEBPACK_IMPORTED_MODULE_0__.removeClassNamesFromElement),\n/* harmony export */ selectionAlwaysOnDisplay: () => (/* binding */ selectionAlwaysOnDisplay)\n/* harmony export */ });\n/* harmony import */ var lexical__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lexical */ \"(rsc)/./node_modules/.pnpm/lexical@0.41.0/node_modules/lexical/Lexical.dev.mjs\");\n/* harmony import */ var _lexical_selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lexical/selection */ \"(rsc)/./node_modules/.pnpm/@lexical+selection@0.41.0/node_modules/@lexical/selection/LexicalSelection.dev.mjs\");\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n\n\n\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n// Do not require this module directly! Use normal `invariant` calls.\n\nfunction formatDevErrorMessage(message) {\n throw new Error(message);\n}\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nconst CAN_USE_DOM$1 = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nconst documentMode = CAN_USE_DOM$1 && 'documentMode' in document ? document.documentMode : null;\nconst IS_APPLE$1 = CAN_USE_DOM$1 && /Mac|iPod|iPhone|iPad/.test(navigator.platform);\nconst IS_FIREFOX$1 = CAN_USE_DOM$1 && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);\nconst CAN_USE_BEFORE_INPUT$1 = CAN_USE_DOM$1 && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;\nconst IS_SAFARI$1 = CAN_USE_DOM$1 && /Version\\/[\\d.]+.*Safari/.test(navigator.userAgent);\nconst IS_IOS$1 = CAN_USE_DOM$1 && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;\nconst IS_ANDROID$1 = CAN_USE_DOM$1 && /Android/.test(navigator.userAgent);\n\n// Keep these in case we need to use them in the future.\n// export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);\nconst IS_CHROME$1 = CAN_USE_DOM$1 && /^(?=.*Chrome).*/i.test(navigator.userAgent);\n// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;\n\nconst IS_ANDROID_CHROME$1 = CAN_USE_DOM$1 && IS_ANDROID$1 && IS_CHROME$1;\nconst IS_APPLE_WEBKIT$1 = CAN_USE_DOM$1 && /AppleWebKit\\/[\\d.]+/.test(navigator.userAgent) && IS_APPLE$1 && !IS_CHROME$1;\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nfunction px(value) {\n return `${value}px`;\n}\n\nconst mutationObserverConfig = {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true\n};\nfunction prependDOMNode(parent, node) {\n parent.insertBefore(node, parent.firstChild);\n}\n\n/**\n * Place one or multiple newly created Nodes at the passed Range's position.\n * Multiple nodes will only be created when the Range spans multiple lines (aka\n * client rects).\n *\n * This function can come particularly useful to highlight particular parts of\n * the text without interfering with the EditorState, that will often replicate\n * the state across collab and clipboard.\n *\n * This function accounts for DOM updates which can modify the passed Range.\n * Hence, the function return to remove the listener.\n */\nfunction mlcPositionNodeOnRange(editor, range, onReposition) {\n let rootDOMNode = null;\n let parentDOMNode = null;\n let observer = null;\n let lastNodes = [];\n const wrapperNode = document.createElement('div');\n wrapperNode.style.position = 'relative';\n function position() {\n if (!(rootDOMNode !== null)) {\n formatDevErrorMessage(`Unexpected null rootDOMNode`);\n }\n if (!(parentDOMNode !== null)) {\n formatDevErrorMessage(`Unexpected null parentDOMNode`);\n }\n const {\n left: parentLeft,\n top: parentTop\n } = parentDOMNode.getBoundingClientRect();\n const rects = (0,_lexical_selection__WEBPACK_IMPORTED_MODULE_1__.createRectsFromDOMRange)(editor, range);\n if (!wrapperNode.isConnected) {\n prependDOMNode(parentDOMNode, wrapperNode);\n }\n let hasRepositioned = false;\n for (let i = 0; i < rects.length; i++) {\n const rect = rects[i];\n // Try to reuse the previously created Node when possible, no need to\n // remove/create on the most common case reposition case\n const rectNode = lastNodes[i] || document.createElement('div');\n const rectNodeStyle = rectNode.style;\n if (rectNodeStyle.position !== 'absolute') {\n rectNodeStyle.position = 'absolute';\n hasRepositioned = true;\n }\n const left = px(rect.left - parentLeft);\n if (rectNodeStyle.left !== left) {\n rectNodeStyle.left = left;\n hasRepositioned = true;\n }\n const top = px(rect.top - parentTop);\n if (rectNodeStyle.top !== top) {\n rectNode.style.top = top;\n hasRepositioned = true;\n }\n const width = px(rect.width);\n if (rectNodeStyle.width !== width) {\n rectNode.style.width = width;\n hasRepositioned = true;\n }\n const height = px(rect.height);\n if (rectNodeStyle.height !== height) {\n rectNode.style.height = height;\n hasRepositioned = true;\n }\n if (rectNode.parentNode !== wrapperNode) {\n wrapperNode.append(rectNode);\n hasRepositioned = true;\n }\n lastNodes[i] = rectNode;\n }\n while (lastNodes.length > rects.length) {\n lastNodes.pop();\n }\n if (hasRepositioned) {\n onReposition(lastNodes);\n }\n }\n function stop() {\n parentDOMNode = null;\n rootDOMNode = null;\n if (observer !== null) {\n observer.disconnect();\n }\n observer = null;\n wrapperNode.remove();\n for (const node of lastNodes) {\n node.remove();\n }\n lastNodes = [];\n }\n function restart() {\n const currentRootDOMNode = editor.getRootElement();\n if (currentRootDOMNode === null) {\n return stop();\n }\n const currentParentDOMNode = currentRootDOMNode.parentElement;\n if (!(0,lexical__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(currentParentDOMNode)) {\n return stop();\n }\n stop();\n rootDOMNode = currentRootDOMNode;\n parentDOMNode = currentParentDOMNode;\n observer = new MutationObserver(mutations => {\n const nextRootDOMNode = editor.getRootElement();\n const nextParentDOMNode = nextRootDOMNode && nextRootDOMNode.parentElement;\n if (nextRootDOMNode !== rootDOMNode || nextParentDOMNode !== parentDOMNode) {\n return restart();\n }\n for (const mutation of mutations) {\n if (!wrapperNode.contains(mutation.target)) {\n // TODO throttle\n return position();\n }\n }\n });\n observer.observe(currentParentDOMNode, mutationObserverConfig);\n position();\n }\n const removeRootListener = editor.registerRootListener(restart);\n return () => {\n removeRootListener();\n stop();\n };\n}\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nfunction $getOrderedSelectionPoints(selection) {\n const points = selection.getStartEndPoints();\n return selection.isBackward() ? [points[1], points[0]] : points;\n}\nfunction rangeTargetFromPoint(point, node, dom) {\n if (point.type === 'text' || !(0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(node)) {\n const textDOM = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.getDOMTextNode)(dom) || dom;\n return [textDOM, point.offset];\n } else {\n const slot = node.getDOMSlot(dom);\n return [slot.element, slot.getFirstChildOffset() + point.offset];\n }\n}\nfunction rangeFromPoints(editor, start, startNode, startDOM, end, endNode, endDOM) {\n const editorDocument = editor._window ? editor._window.document : document;\n const range = editorDocument.createRange();\n range.setStart(...rangeTargetFromPoint(start, startNode, startDOM));\n range.setEnd(...rangeTargetFromPoint(end, endNode, endDOM));\n return range;\n}\n/**\n * Place one or multiple newly created Nodes at the current selection. Multiple\n * nodes will only be created when the selection spans multiple lines (aka\n * client rects).\n *\n * This function can come useful when you want to show the selection but the\n * editor has been focused away.\n */\nfunction markSelection(editor, onReposition) {\n let previousAnchorNode = null;\n let previousAnchorNodeDOM = null;\n let previousAnchorOffset = null;\n let previousFocusNode = null;\n let previousFocusNodeDOM = null;\n let previousFocusOffset = null;\n let removeRangeListener = () => {};\n function compute(editorState) {\n editorState.read(() => {\n const selection = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSelection)();\n if (!(0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isRangeSelection)(selection)) {\n // TODO\n previousAnchorNode = null;\n previousAnchorOffset = null;\n previousFocusNode = null;\n previousFocusOffset = null;\n removeRangeListener();\n removeRangeListener = () => {};\n return;\n }\n const [start, end] = $getOrderedSelectionPoints(selection);\n const currentStartNode = start.getNode();\n const currentStartNodeKey = currentStartNode.getKey();\n const currentStartOffset = start.offset;\n const currentEndNode = end.getNode();\n const currentEndNodeKey = currentEndNode.getKey();\n const currentEndOffset = end.offset;\n const currentStartNodeDOM = editor.getElementByKey(currentStartNodeKey);\n const currentEndNodeDOM = editor.getElementByKey(currentEndNodeKey);\n const differentStartDOM = previousAnchorNode === null || currentStartNodeDOM !== previousAnchorNodeDOM || currentStartOffset !== previousAnchorOffset || currentStartNodeKey !== previousAnchorNode.getKey();\n const differentEndDOM = previousFocusNode === null || currentEndNodeDOM !== previousFocusNodeDOM || currentEndOffset !== previousFocusOffset || currentEndNodeKey !== previousFocusNode.getKey();\n if ((differentStartDOM || differentEndDOM) && currentStartNodeDOM !== null && currentEndNodeDOM !== null) {\n const range = rangeFromPoints(editor, start, currentStartNode, currentStartNodeDOM, end, currentEndNode, currentEndNodeDOM);\n removeRangeListener();\n removeRangeListener = mlcPositionNodeOnRange(editor, range, domNodes => {\n if (onReposition === undefined) {\n for (const domNode of domNodes) {\n const domNodeStyle = domNode.style;\n if (domNodeStyle.background !== 'Highlight') {\n domNodeStyle.background = 'Highlight';\n }\n if (domNodeStyle.color !== 'HighlightText') {\n domNodeStyle.color = 'HighlightText';\n }\n if (domNodeStyle.marginTop !== px(-1.5)) {\n domNodeStyle.marginTop = px(-1.5);\n }\n if (domNodeStyle.paddingTop !== px(4)) {\n domNodeStyle.paddingTop = px(4);\n }\n if (domNodeStyle.paddingBottom !== px(0)) {\n domNodeStyle.paddingBottom = px(0);\n }\n }\n } else {\n onReposition(domNodes);\n }\n });\n }\n previousAnchorNode = currentStartNode;\n previousAnchorNodeDOM = currentStartNodeDOM;\n previousAnchorOffset = currentStartOffset;\n previousFocusNode = currentEndNode;\n previousFocusNodeDOM = currentEndNodeDOM;\n previousFocusOffset = currentEndOffset;\n });\n }\n compute(editor.getEditorState());\n return (0,lexical__WEBPACK_IMPORTED_MODULE_0__.mergeRegister)(editor.registerUpdateListener(({\n editorState\n }) => compute(editorState)), () => {\n removeRangeListener();\n });\n}\n\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nfunction selectionAlwaysOnDisplay(editor, onReposition) {\n let removeSelectionMark = null;\n const onSelectionChange = () => {\n const domSelection = getSelection();\n const domAnchorNode = domSelection && domSelection.anchorNode;\n const editorRootElement = editor.getRootElement();\n const isSelectionInsideEditor = domAnchorNode !== null && editorRootElement !== null && editorRootElement.contains(domAnchorNode);\n if (isSelectionInsideEditor) {\n if (removeSelectionMark !== null) {\n removeSelectionMark();\n removeSelectionMark = null;\n }\n } else {\n if (removeSelectionMark === null) {\n removeSelectionMark = markSelection(editor, onReposition);\n }\n }\n };\n document.addEventListener('selectionchange', onSelectionChange);\n return () => {\n if (removeSelectionMark !== null) {\n removeSelectionMark();\n }\n document.removeEventListener('selectionchange', onSelectionChange);\n };\n}\n\n// Hotfix to export these with inlined types #5918\nconst CAN_USE_BEFORE_INPUT = CAN_USE_BEFORE_INPUT$1;\nconst CAN_USE_DOM = CAN_USE_DOM$1;\nconst IS_ANDROID = IS_ANDROID$1;\nconst IS_ANDROID_CHROME = IS_ANDROID_CHROME$1;\nconst IS_APPLE = IS_APPLE$1;\nconst IS_APPLE_WEBKIT = IS_APPLE_WEBKIT$1;\nconst IS_CHROME = IS_CHROME$1;\nconst IS_FIREFOX = IS_FIREFOX$1;\nconst IS_IOS = IS_IOS$1;\nconst IS_SAFARI = IS_SAFARI$1;\n\n/**\n * Returns true if the file type matches the types passed within the acceptableMimeTypes array, false otherwise.\n * The types passed must be strings and are CASE-SENSITIVE.\n * eg. if file is of type 'text' and acceptableMimeTypes = ['TEXT', 'IMAGE'] the function will return false.\n * @param file - The file you want to type check.\n * @param acceptableMimeTypes - An array of strings of types which the file is checked against.\n * @returns true if the file is an acceptable mime type, false otherwise.\n */\nfunction isMimeType(file, acceptableMimeTypes) {\n for (const acceptableType of acceptableMimeTypes) {\n if (file.type.startsWith(acceptableType)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Lexical File Reader with:\n * 1. MIME type support\n * 2. batched results (HistoryPlugin compatibility)\n * 3. Order aware (respects the order when multiple Files are passed)\n *\n * const filesResult = await mediaFileReader(files, ['image/']);\n * filesResult.forEach(file => editor.dispatchCommand('INSERT_IMAGE', \\\\{\n * src: file.result,\n * \\\\}));\n */\nfunction mediaFileReader(files, acceptableMimeTypes) {\n const filesIterator = files[Symbol.iterator]();\n return new Promise((resolve, reject) => {\n const processed = [];\n const handleNextFile = () => {\n const {\n done,\n value: file\n } = filesIterator.next();\n if (done) {\n return resolve(processed);\n }\n const fileReader = new FileReader();\n fileReader.addEventListener('error', reject);\n fileReader.addEventListener('load', () => {\n const result = fileReader.result;\n if (typeof result === 'string') {\n processed.push({\n file,\n result\n });\n }\n handleNextFile();\n });\n if (isMimeType(file, acceptableMimeTypes)) {\n fileReader.readAsDataURL(file);\n } else {\n handleNextFile();\n }\n };\n handleNextFile();\n });\n}\n/**\n * \"Depth-First Search\" starts at the root/top node of a tree and goes as far as it can down a branch end\n * before backtracking and finding a new path. Consider solving a maze by hugging either wall, moving down a\n * branch until you hit a dead-end (leaf) and backtracking to find the nearest branching path and repeat.\n * It will then return all the nodes found in the search in an array of objects.\n * Preorder traversal is used, meaning that nodes are listed in the order of when they are FIRST encountered.\n * @param startNode - The node to start the search (inclusive), if omitted, it will start at the root node.\n * @param endNode - The node to end the search (inclusive), if omitted, it will find all descendants of the startingNode. If endNode\n * is an ElementNode, it will stop before visiting any of its children.\n * @returns An array of objects of all the nodes found by the search, including their depth into the tree.\n * \\\\{depth: number, node: LexicalNode\\\\} It will always return at least 1 node (the start node).\n */\nfunction $dfs(startNode, endNode) {\n return Array.from($dfsIterator(startNode, endNode));\n}\n\n/**\n * Get the adjacent caret in the same direction\n *\n * @param caret A caret or null\n * @returns `caret.getAdjacentCaret()` or `null`\n */\nfunction $getAdjacentCaret(caret) {\n return caret ? caret.getAdjacentCaret() : null;\n}\n\n/**\n * $dfs iterator (right to left). Tree traversal is done on the fly as new values are requested with O(1) memory.\n * @param startNode - The node to start the search, if omitted, it will start at the root node.\n * @param endNode - The node to end the search, if omitted, it will find all descendants of the startingNode.\n * @returns An iterator, each yielded value is a DFSNode. It will always return at least 1 node (the start node).\n */\nfunction $reverseDfs(startNode, endNode) {\n return Array.from($reverseDfsIterator(startNode, endNode));\n}\n\n/**\n * $dfs iterator (left to right). Tree traversal is done on the fly as new values are requested with O(1) memory.\n * Preorder traversal is used, meaning that nodes are iterated over in the order of when they are FIRST encountered.\n * @param startNode - The node to start the search (inclusive), if omitted, it will start at the root node.\n * @param endNode - The node to end the search (inclusive), if omitted, it will find all descendants of the startingNode.\n * If endNode is an ElementNode, the iterator will end as soon as it reaches the endNode (no children will be visited).\n * @returns An iterator, each yielded value is a DFSNode. It will always return at least 1 node (the start node).\n */\nfunction $dfsIterator(startNode, endNode) {\n return $dfsCaretIterator('next', startNode, endNode);\n}\nfunction $getEndCaret(startNode, direction) {\n const rval = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentSiblingOrParentSiblingCaret)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(startNode, direction));\n return rval && rval[0];\n}\nfunction $dfsCaretIterator(direction, startNode, endNode) {\n const root = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getRoot)();\n const start = startNode || root;\n const startCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(start) ? (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaret)(start, direction) : (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(start, direction);\n const startDepth = $getDepth(start);\n const endCaret = endNode ? (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentChildCaret)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaretOrSelf)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(endNode, direction))) || $getEndCaret(endNode, direction) : $getEndCaret(start, direction);\n let depth = startDepth;\n return (0,lexical__WEBPACK_IMPORTED_MODULE_0__.makeStepwiseIterator)({\n hasNext: state => state !== null,\n initial: startCaret,\n map: state => ({\n depth,\n node: state.origin\n }),\n step: state => {\n if (state.isSameNodeCaret(endCaret)) {\n return null;\n }\n if ((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isChildCaret)(state)) {\n depth++;\n }\n const rval = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentSiblingOrParentSiblingCaret)(state);\n if (!rval || rval[0].isSameNodeCaret(endCaret)) {\n return null;\n }\n depth += rval[1];\n return rval[0];\n }\n });\n}\n\n/**\n * Returns the Node sibling when this exists, otherwise the closest parent sibling. For example\n * R -> P -> T1, T2\n * -> P2\n * returns T2 for node T1, P2 for node T2, and null for node P2.\n * @param node LexicalNode.\n * @returns An array (tuple) containing the found Lexical node and the depth difference, or null, if this node doesn't exist.\n */\nfunction $getNextSiblingOrParentSibling(node) {\n const rval = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentSiblingOrParentSiblingCaret)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(node, 'next'));\n return rval && [rval[0].origin, rval[1]];\n}\nfunction $getDepth(node) {\n let depth = -1;\n for (let innerNode = node; innerNode !== null; innerNode = innerNode.getParent()) {\n depth++;\n }\n return depth;\n}\n\n/**\n * Performs a right-to-left preorder tree traversal.\n * From the starting node it goes to the rightmost child, than backtracks to parent and finds new rightmost path.\n * It will return the next node in traversal sequence after the startingNode.\n * The traversal is similar to $dfs functions above, but the nodes are visited right-to-left, not left-to-right.\n * @param startingNode - The node to start the search.\n * @returns The next node in pre-order right to left traversal sequence or `null`, if the node does not exist\n */\nfunction $getNextRightPreorderNode(startingNode) {\n const startCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaretOrSelf)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(startingNode, 'previous'));\n const next = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentSiblingOrParentSiblingCaret)(startCaret, 'root');\n return next && next[0].origin;\n}\n\n/**\n * $dfs iterator (right to left). Tree traversal is done on the fly as new values are requested with O(1) memory.\n * @param startNode - The node to start the search, if omitted, it will start at the root node.\n * @param endNode - The node to end the search, if omitted, it will find all descendants of the startingNode.\n * @returns An iterator, each yielded value is a DFSNode. It will always return at least 1 node (the start node).\n */\nfunction $reverseDfsIterator(startNode, endNode) {\n return $dfsCaretIterator('previous', startNode, endNode);\n}\n\n/**\n * Takes a node and traverses up its ancestors (toward the root node)\n * in order to find a specific type of node.\n * @param node - the node to begin searching.\n * @param klass - an instance of the type of node to look for.\n * @returns the node of type klass that was passed, or null if none exist.\n */\nfunction $getNearestNodeOfType(node, klass) {\n let parent = node;\n while (parent != null) {\n if (parent instanceof klass) {\n return parent;\n }\n parent = parent.getParent();\n }\n return null;\n}\n\n/**\n * Returns the element node of the nearest ancestor, otherwise throws an error.\n * @param startNode - The starting node of the search\n * @returns The ancestor node found\n */\nfunction $getNearestBlockElementAncestorOrThrow(startNode) {\n const blockNode = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$findMatchingParent)(startNode, node => (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(node) && !node.isInline());\n if (!(0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(blockNode)) {\n {\n formatDevErrorMessage(`Expected node ${startNode.__key} to have closest block element node.`);\n }\n }\n return blockNode;\n}\n/**\n * Attempts to resolve nested element nodes of the same type into a single node of that type.\n * It is generally used for marks/commenting\n * @param editor - The lexical editor\n * @param targetNode - The target for the nested element to be extracted from.\n * @param cloneNode - See {@link $createMarkNode}\n * @param handleOverlap - Handles any overlap between the node to extract and the targetNode\n * @returns The lexical editor\n */\nfunction registerNestedElementResolver(editor, targetNode, cloneNode, handleOverlap) {\n const $isTargetNode = node => {\n return node instanceof targetNode;\n };\n const $findMatch = node => {\n // First validate we don't have any children that are of the target,\n // as we need to handle them first.\n const children = node.getChildren();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if ($isTargetNode(child)) {\n return null;\n }\n }\n let parentNode = node;\n let childNode = node;\n while (parentNode !== null) {\n childNode = parentNode;\n parentNode = parentNode.getParent();\n if ($isTargetNode(parentNode)) {\n return {\n child: childNode,\n parent: parentNode\n };\n }\n }\n return null;\n };\n const $elementNodeTransform = node => {\n const match = $findMatch(node);\n if (match !== null) {\n const {\n child,\n parent\n } = match;\n\n // Simple path, we can move child out and siblings into a new parent.\n\n if (child.is(node)) {\n handleOverlap(parent, node);\n const nextSiblings = child.getNextSiblings();\n const nextSiblingsLength = nextSiblings.length;\n parent.insertAfter(child);\n if (nextSiblingsLength !== 0) {\n const newParent = cloneNode(parent);\n child.insertAfter(newParent);\n for (let i = 0; i < nextSiblingsLength; i++) {\n newParent.append(nextSiblings[i]);\n }\n }\n if (!parent.canBeEmpty() && parent.getChildrenSize() === 0) {\n parent.remove();\n }\n }\n }\n };\n return editor.registerNodeTransform(targetNode, $elementNodeTransform);\n}\n\n/**\n * Clones the editor and marks it as dirty to be reconciled. If there was a selection,\n * it would be set back to its previous state, or null otherwise.\n * @param editor - The lexical editor\n * @param editorState - The editor's state\n */\nfunction $restoreEditorState(editor, editorState) {\n const FULL_RECONCILE = 2;\n const nodeMap = new Map();\n const activeEditorState = editor._pendingEditorState;\n for (const [key, node] of editorState._nodeMap) {\n nodeMap.set(key, (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$cloneWithProperties)(node));\n }\n if (activeEditorState) {\n activeEditorState._nodeMap = nodeMap;\n }\n editor._dirtyType = FULL_RECONCILE;\n const selection = editorState._selection;\n (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$setSelection)(selection === null ? null : selection.clone());\n}\n\n/**\n * If the selected insertion area is the root/shadow root node (see {@link lexical!$isRootOrShadowRoot}),\n * the node will be appended there, otherwise, it will be inserted before the insertion area.\n * If there is no selection where the node is to be inserted, it will be appended after any current nodes\n * within the tree, as a child of the root node. A paragraph will then be added after the inserted node and selected.\n * @param node - The node to be inserted\n * @returns The node after its insertion\n */\nfunction $insertNodeToNearestRoot(node) {\n const selection = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSelection)() || (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getPreviousSelection)();\n let initialCaret;\n if ((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isRangeSelection)(selection)) {\n initialCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$caretFromPoint)(selection.focus, 'next');\n } else {\n if (selection != null) {\n const nodes = selection.getNodes();\n const lastNode = nodes[nodes.length - 1];\n if (lastNode) {\n initialCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(lastNode, 'next');\n }\n }\n initialCaret = initialCaret || (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaret)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getRoot)(), 'previous').getFlipped().insert((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$createParagraphNode)());\n }\n const insertCaret = $insertNodeToNearestRootAtCaret(node, initialCaret);\n const adjacent = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getAdjacentChildCaret)(insertCaret);\n const selectionCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isChildCaret)(adjacent) ? (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$normalizeCaret)(adjacent) : insertCaret;\n (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$setSelectionFromCaretRange)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getCollapsedCaretRange)(selectionCaret));\n return node.getLatest();\n}\n\n/**\n * If the insertion caret is the root/shadow root node (see {@link lexical!$isRootOrShadowRoot}),\n * the node will be inserted there, otherwise the parent nodes will be split according to the\n * given options.\n * @param node - The node to be inserted\n * @param caret - The location to insert or split from\n * @returns The node after its insertion\n */\nfunction $insertNodeToNearestRootAtCaret(node, caret, options) {\n let insertCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getCaretInDirection)(caret, 'next');\n for (let nextCaret = insertCaret; nextCaret; nextCaret = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$splitAtPointCaretNext)(nextCaret, options)) {\n insertCaret = nextCaret;\n }\n if (!!(0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isTextPointCaret)(insertCaret)) {\n formatDevErrorMessage(`$insertNodeToNearestRootAtCaret: An unattached TextNode can not be split`);\n }\n insertCaret.insert(node.isInline() ? (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$createParagraphNode)().append(node) : node);\n return (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getCaretInDirection)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(node.getLatest(), 'next'), caret.direction);\n}\n\n/**\n * Wraps the node into another node created from a createElementNode function, eg. $createParagraphNode\n * @param node - Node to be wrapped.\n * @param createElementNode - Creates a new lexical element to wrap the to-be-wrapped node and returns it.\n * @returns A new lexical element with the previous node appended within (as a child, including its children).\n */\nfunction $wrapNodeInElement(node, createElementNode) {\n const elementNode = createElementNode();\n node.replace(elementNode);\n elementNode.append(node);\n return elementNode;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\n/**\n * @param object = The instance of the type\n * @param objectClass = The class of the type\n * @returns Whether the object is has the same Klass of the objectClass, ignoring the difference across window (e.g. different iframes)\n */\nfunction objectKlassEquals(object, objectClass) {\n return object !== null ? Object.getPrototypeOf(object).constructor.name === objectClass.name : false;\n}\n\n/**\n * @deprecated Use Array filter or flatMap\n *\n * Filter the nodes\n * @param nodes Array of nodes that needs to be filtered\n * @param filterFn A filter function that returns node if the current node satisfies the condition otherwise null\n * @returns Array of filtered nodes\n */\n\nfunction $filter(nodes, filterFn) {\n const result = [];\n for (let i = 0; i < nodes.length; i++) {\n const node = filterFn(nodes[i]);\n if (node !== null) {\n result.push(node);\n }\n }\n return result;\n}\n\n/**\n * Applies the provided callback to each indentable block element in the Selection\n *\n * @param indentOrOutdent callback for performing the indent or outdent action\n * on a given block element.\n * @returns true if at least one block was handled, false otherwise.\n */\nfunction $handleIndentAndOutdent(indentOrOutdent) {\n const selection = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSelection)();\n if (!(0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isRangeSelection)(selection)) {\n return false;\n }\n const alreadyHandled = new Set();\n const nodes = selection.getNodes();\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const key = node.getKey();\n if (alreadyHandled.has(key)) {\n continue;\n }\n const parentBlock = (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$findMatchingParent)(node, parentNode => (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(parentNode) && !parentNode.isInline());\n if (parentBlock === null) {\n continue;\n }\n const parentKey = parentBlock.getKey();\n if (parentBlock.canIndent() && !alreadyHandled.has(parentKey)) {\n alreadyHandled.add(parentKey);\n indentOrOutdent(parentBlock);\n }\n }\n return alreadyHandled.size > 0;\n}\n\n/**\n * Appends the node before the first child of the parent node\n * @param parent A parent node\n * @param node Node that needs to be appended\n */\nfunction $insertFirst(parent, node) {\n (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaret)(parent, 'next').insert(node);\n}\nlet NEEDS_MANUAL_ZOOM = IS_FIREFOX || !CAN_USE_DOM ? false : undefined;\nfunction needsManualZoom() {\n if (NEEDS_MANUAL_ZOOM === undefined) {\n // If the browser implements standardized CSS zoom, then the client rect\n // will be wider after zoom is applied\n // https://chromestatus.com/feature/5198254868529152\n // https://github.com/facebook/lexical/issues/6863\n const div = document.createElement('div');\n div.style.cssText = 'position: absolute; opacity: 0; width: 100px; left: -1000px;';\n document.body.appendChild(div);\n const noZoom = div.getBoundingClientRect();\n div.style.setProperty('zoom', '2');\n NEEDS_MANUAL_ZOOM = div.getBoundingClientRect().width === noZoom.width;\n document.body.removeChild(div);\n }\n return NEEDS_MANUAL_ZOOM;\n}\n\n/**\n * Calculates the zoom level of an element as a result of using\n * css zoom property. For browsers that implement standardized CSS\n * zoom (Firefox, Chrome >= 128), this will always return 1.\n * @param element\n * @param useManualZoom - If true, always use zoom level will be calculated manually, otherwise it will be calculated on as needed basis.\n */\nfunction calculateZoomLevel(element, useManualZoom = false) {\n let zoom = 1;\n if (needsManualZoom() || useManualZoom) {\n while (element) {\n zoom *= Number(window.getComputedStyle(element).getPropertyValue('zoom'));\n element = element.parentElement;\n }\n }\n return zoom;\n}\n\n/**\n * Checks if the editor is a nested editor created by LexicalNestedComposer\n */\nfunction $isEditorIsNestedEditor(editor) {\n return editor._parentEditor !== null;\n}\n\n/**\n * A depth first last-to-first traversal of root that stops at each node that matches\n * $predicate and ensures that its parent is root. This is typically used to discard\n * invalid or unsupported wrapping nodes. For example, a TableNode must only have\n * TableRowNode as children, but an importer might add invalid nodes based on\n * caption, tbody, thead, etc. and this will unwrap and discard those.\n *\n * @param root The root to start the traversal\n * @param $predicate Should return true for nodes that are permitted to be children of root\n * @returns true if this unwrapped or removed any nodes\n */\nfunction $unwrapAndFilterDescendants(root, $predicate) {\n return $unwrapAndFilterDescendantsImpl(root, $predicate, null);\n}\nfunction $unwrapAndFilterDescendantsImpl(root, $predicate, $onSuccess) {\n let didMutate = false;\n for (const node of $lastToFirstIterator(root)) {\n if ($predicate(node)) {\n if ($onSuccess !== null) {\n $onSuccess(node);\n }\n continue;\n }\n didMutate = true;\n if ((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(node)) {\n $unwrapAndFilterDescendantsImpl(node, $predicate, $onSuccess || (child => node.insertAfter(child)));\n }\n node.remove();\n }\n return didMutate;\n}\n\n/**\n * A depth first traversal of the children array that stops at and collects\n * each node that `$predicate` matches. This is typically used to discard\n * invalid or unsupported wrapping nodes on a children array in the `after`\n * of an {@link lexical!DOMConversionOutput}. For example, a TableNode must only have\n * TableRowNode as children, but an importer might add invalid nodes based on\n * caption, tbody, thead, etc. and this will unwrap and discard those.\n *\n * This function is read-only and performs no mutation operations, which makes\n * it suitable for import and export purposes but likely not for any in-place\n * mutation. You should use {@link $unwrapAndFilterDescendants} for in-place\n * mutations such as node transforms.\n *\n * @param children The children to traverse\n * @param $predicate Should return true for nodes that are permitted to be children of root\n * @returns The children or their descendants that match $predicate\n */\n\nfunction $descendantsMatching(children, $predicate) {\n const result = [];\n const stack = Array.from(children).reverse();\n for (let child = stack.pop(); child !== undefined; child = stack.pop()) {\n if ($predicate(child)) {\n result.push(child);\n } else if ((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$isElementNode)(child)) {\n for (const grandchild of $lastToFirstIterator(child)) {\n stack.push(grandchild);\n }\n }\n }\n return result;\n}\n\n/**\n * Return an iterator that yields each child of node from first to last, taking\n * care to preserve the next sibling before yielding the value in case the caller\n * removes the yielded node.\n *\n * @param node The node whose children to iterate\n * @returns An iterator of the node's children\n */\nfunction $firstToLastIterator(node) {\n return $childIterator((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaret)(node, 'next'));\n}\n\n/**\n * Return an iterator that yields each child of node from last to first, taking\n * care to preserve the previous sibling before yielding the value in case the caller\n * removes the yielded node.\n *\n * @param node The node whose children to iterate\n * @returns An iterator of the node's children\n */\nfunction $lastToFirstIterator(node) {\n return $childIterator((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getChildCaret)(node, 'previous'));\n}\nfunction $childIterator(startCaret) {\n const seen = new Set() ;\n return (0,lexical__WEBPACK_IMPORTED_MODULE_0__.makeStepwiseIterator)({\n hasNext: lexical__WEBPACK_IMPORTED_MODULE_0__.$isSiblingCaret,\n initial: startCaret.getAdjacentCaret(),\n map: caret => {\n const origin = caret.origin.getLatest();\n if (seen !== null) {\n const key = origin.getKey();\n if (!!seen.has(key)) {\n formatDevErrorMessage(`$childIterator: Cycle detected, node with key ${String(key)} has already been traversed`);\n }\n seen.add(key);\n }\n return origin;\n },\n step: caret => caret.getAdjacentCaret()\n });\n}\n\n/**\n * Replace this node with its children\n *\n * @param node The ElementNode to unwrap and remove\n */\nfunction $unwrapNode(node) {\n (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$rewindSiblingCaret)((0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getSiblingCaret)(node, 'next')).splice(1, node.getChildren());\n}\n\n/**\n * A wrapper that creates bound functions and methods for the\n * StateConfig to save some boilerplate when defining methods\n * or exporting only the accessors from your modules rather\n * than exposing the StateConfig directly.\n */\n\n/**\n * EXPERIMENTAL\n *\n * A convenience interface for working with {@link $getState} and\n * {@link $setState}.\n *\n * @param stateConfig The stateConfig to wrap with convenience functionality\n * @returns a StateWrapper\n */\nfunction makeStateWrapper(stateConfig) {\n const $get = node => (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$getState)(node, stateConfig);\n const $set = (node, valueOrUpdater) => (0,lexical__WEBPACK_IMPORTED_MODULE_0__.$setState)(node, stateConfig, valueOrUpdater);\n return {\n $get,\n $set,\n accessors: [$get, $set],\n makeGetterMethod: () => function $getter() {\n return $get(this);\n },\n makeSetterMethod: () => function $setter(valueOrUpdater) {\n return $set(this, valueOrUpdater);\n },\n stateConfig\n };\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvLnBucG0vQGxleGljYWwrdXRpbHNAMC40MS4wL25vZGVfbW9kdWxlcy9AbGV4aWNhbC91dGlscy9MZXhpY2FsVXRpbHMuZGV2Lm1qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFNmxCO0FBQ2pYO0FBQy9LOztBQUU3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVksTUFBTTtBQUNsQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixrQkFBa0IsMkVBQXVCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGtCQUFrQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsc0RBQWE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1REFBYztBQUM5QyxvQkFBb0IsdURBQWM7QUFDbEM7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixzREFBYTtBQUNyQyxXQUFXLDBEQUFpQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxTQUFTLHNEQUFhO0FBQ3RCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sb0NBQW9DO0FBQzFDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnRkFB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b2R1bGVzLy5wbnBtL0BsZXhpY2FsK3V0aWxzQDAuNDEuMC9ub2RlX21vZHVsZXMvQGxleGljYWwvdXRpbHMvTGV4aWNhbFV0aWxzLmRldi5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIE1ldGEgUGxhdGZvcm1zLCBJbmMuIGFuZCBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50LCBtZXJnZVJlZ2lzdGVyLCAkZ2V0U2VsZWN0aW9uLCAkaXNSYW5nZVNlbGVjdGlvbiwgJGlzRWxlbWVudE5vZGUsIGdldERPTVRleHROb2RlLCAkZ2V0QWRqYWNlbnRTaWJsaW5nT3JQYXJlbnRTaWJsaW5nQ2FyZXQsICRnZXRTaWJsaW5nQ2FyZXQsICRnZXRDaGlsZENhcmV0T3JTZWxmLCAkZmluZE1hdGNoaW5nUGFyZW50LCAkY2xvbmVXaXRoUHJvcGVydGllcywgJHNldFNlbGVjdGlvbiwgJGdldFByZXZpb3VzU2VsZWN0aW9uLCAkY2FyZXRGcm9tUG9pbnQsICRnZXRDaGlsZENhcmV0LCAkZ2V0Um9vdCwgJGNyZWF0ZVBhcmFncmFwaE5vZGUsICRnZXRBZGphY2VudENoaWxkQ2FyZXQsICRpc0NoaWxkQ2FyZXQsICRub3JtYWxpemVDYXJldCwgJHNldFNlbGVjdGlvbkZyb21DYXJldFJhbmdlLCAkZ2V0Q29sbGFwc2VkQ2FyZXRSYW5nZSwgJGdldENhcmV0SW5EaXJlY3Rpb24sICRzcGxpdEF0UG9pbnRDYXJldE5leHQsICRpc1RleHRQb2ludENhcmV0LCAkcmV3aW5kU2libGluZ0NhcmV0LCAkZ2V0U3RhdGUsICRzZXRTdGF0ZSwgbWFrZVN0ZXB3aXNlSXRlcmF0b3IsICRpc1NpYmxpbmdDYXJldCB9IGZyb20gJ2xleGljYWwnO1xuZXhwb3J0IHsgJGZpbmRNYXRjaGluZ1BhcmVudCwgJGdldEFkamFjZW50U2libGluZ09yUGFyZW50U2libGluZ0NhcmV0LCAkc3BsaXROb2RlLCBhZGRDbGFzc05hbWVzVG9FbGVtZW50LCBpc0Jsb2NrRG9tTm9kZSwgaXNIVE1MQW5jaG9yRWxlbWVudCwgaXNIVE1MRWxlbWVudCwgaXNJbmxpbmVEb21Ob2RlLCBtZXJnZVJlZ2lzdGVyLCByZW1vdmVDbGFzc05hbWVzRnJvbUVsZW1lbnQgfSBmcm9tICdsZXhpY2FsJztcbmltcG9ydCB7IGNyZWF0ZVJlY3RzRnJvbURPTVJhbmdlIH0gZnJvbSAnQGxleGljYWwvc2VsZWN0aW9uJztcblxuLyoqXG4gKiBDb3B5cmlnaHQgKGMpIE1ldGEgUGxhdGZvcm1zLCBJbmMuIGFuZCBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG4vLyBEbyBub3QgcmVxdWlyZSB0aGlzIG1vZHVsZSBkaXJlY3RseSEgVXNlIG5vcm1hbCBgaW52YXJpYW50YCBjYWxscy5cblxuZnVuY3Rpb24gZm9ybWF0RGV2RXJyb3JNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIENvcHlyaWdodCAoYykgTWV0YSBQbGF0Zm9ybXMsIEluYy4gYW5kIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKlxuICovXG5cbmNvbnN0IENBTl9VU0VfRE9NJDEgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93LmRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgIT09ICd1bmRlZmluZWQnO1xuXG4vKipcbiAqIENvcHlyaWdodCAoYykgTWV0YSBQbGF0Zm9ybXMsIEluYy4gYW5kIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKlxuICovXG5cbmNvbnN0IGRvY3VtZW50TW9kZSA9IENBTl9VU0VfRE9NJDEgJiYgJ2RvY3VtZW50TW9kZScgaW4gZG9jdW1lbnQgPyBkb2N1bWVudC5kb2N1bWVudE1vZGUgOiBudWxsO1xuY29uc3QgSVNfQVBQTEUkMSA9IENBTl9VU0VfRE9NJDEgJiYgL01hY3xpUG9kfGlQaG9uZXxpUGFkLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5jb25zdCBJU19GSVJFRk9YJDEgPSBDQU5fVVNFX0RPTSQxICYmIC9eKD8hLipTZWFtb25rZXkpKD89LipGaXJlZm94KS4qL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbmNvbnN0IENBTl9VU0VfQkVGT1JFX0lOUFVUJDEgPSBDQU5fVVNFX0RPTSQxICYmICdJbnB1dEV2ZW50JyBpbiB3aW5kb3cgJiYgIWRvY3VtZW50TW9kZSA/ICdnZXRUYXJnZXRSYW5nZXMnIGluIG5ldyB3aW5kb3cuSW5wdXRFdmVudCgnaW5wdXQnKSA6IGZhbHNlO1xuY29uc3QgSVNfU0FGQVJJJDEgPSBDQU5fVVNFX0RPTSQxICYmIC9WZXJzaW9uXFwvW1xcZC5dKy4qU2FmYXJpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuY29uc3QgSVNfSU9TJDEgPSBDQU5fVVNFX0RPTSQxICYmIC9pUGFkfGlQaG9uZXxpUG9kLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpICYmICF3aW5kb3cuTVNTdHJlYW07XG5jb25zdCBJU19BTkRST0lEJDEgPSBDQU5fVVNFX0RPTSQxICYmIC9BbmRyb2lkLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4vLyBLZWVwIHRoZXNlIGluIGNhc2Ugd2UgbmVlZCB0byB1c2UgdGhlbSBpbiB0aGUgZnV0dXJlLlxuLy8gZXhwb3J0IGNvbnN0IElTX1dJTkRPV1M6IGJvb2xlYW4gPSBDQU5fVVNFX0RPTSAmJiAvV2luLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5jb25zdCBJU19DSFJPTUUkMSA9IENBTl9VU0VfRE9NJDEgJiYgL14oPz0uKkNocm9tZSkuKi9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4vLyBleHBvcnQgY29uc3QgY2FuVXNlVGV4dElucHV0RXZlbnQ6IGJvb2xlYW4gPSBDQU5fVVNFX0RPTSAmJiAnVGV4dEV2ZW50JyBpbiB3aW5kb3cgJiYgIWRvY3VtZW50TW9kZTtcblxuY29uc3QgSVNfQU5EUk9JRF9DSFJPTUUkMSA9IENBTl9VU0VfRE9NJDEgJiYgSVNfQU5EUk9JRCQxICYmIElTX0NIUk9NRSQxO1xuY29uc3QgSVNfQVBQTEVfV0VCS0lUJDEgPSBDQU5fVVNFX0RPTSQxICYmIC9BcHBsZVdlYktpdFxcL1tcXGQuXSsvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgSVNfQVBQTEUkMSAmJiAhSVNfQ0hST01FJDE7XG5cbi8qKlxuICogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqXG4gKi9cblxuZnVuY3Rpb24gcHgodmFsdWUpIHtcbiAgcmV0dXJuIGAke3ZhbHVlfXB4YDtcbn1cblxuY29uc3QgbXV0YXRpb25PYnNlcnZlckNvbmZpZyA9IHtcbiAgYXR0cmlidXRlczogdHJ1ZSxcbiAgY2hhcmFjdGVyRGF0YTogdHJ1ZSxcbiAgY2hpbGRMaXN0OiB0cnVlLFxuICBzdWJ0cmVlOiB0cnVlXG59O1xuZnVuY3Rpb24gcHJlcGVuZERPTU5vZGUocGFyZW50LCBub2RlKSB7XG4gIHBhcmVudC5pbnNlcnRCZWZvcmUobm9kZSwgcGFyZW50LmZpcnN0Q2hpbGQpO1xufVxuXG4vKipcbiAqIFBsYWNlIG9uZSBvciBtdWx0aXBsZSBuZXdseSBjcmVhdGVkIE5vZGVzIGF0IHRoZSBwYXNzZWQgUmFuZ2UncyBwb3NpdGlvbi5cbiAqIE11bHRpcGxlIG5vZGVzIHdpbGwgb25seSBiZSBjcmVhdGVkIHdoZW4gdGhlIFJhbmdlIHNwYW5zIG11bHRpcGxlIGxpbmVzIChha2FcbiAqIGNsaWVudCByZWN0cykuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBjYW4gY29tZSBwYXJ0aWN1bGFybHkgdXNlZnVsIHRvIGhpZ2hsaWdodCBwYXJ0aWN1bGFyIHBhcnRzIG9mXG4gKiB0aGUgdGV4dCB3aXRob3V0IGludGVyZmVyaW5nIHdpdGggdGhlIEVkaXRvclN0YXRlLCB0aGF0IHdpbGwgb2Z0ZW4gcmVwbGljYXRlXG4gKiB0aGUgc3RhdGUgYWNyb3NzIGNvbGxhYiBhbmQgY2xpcGJvYXJkLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gYWNjb3VudHMgZm9yIERPTSB1cGRhdGVzIHdoaWNoIGNhbiBtb2RpZnkgdGhlIHBhc3NlZCBSYW5nZS5cbiAqIEhlbmNlLCB0aGUgZnVuY3Rpb24gcmV0dXJuIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmZ1bmN0aW9uIG1sY1Bvc2l0aW9uTm9kZU9uUmFuZ2UoZWRpdG9yLCByYW5nZSwgb25SZXBvc2l0aW9uKSB7XG4gIGxldCByb290RE9NTm9kZSA9IG51bGw7XG4gIGxldCBwYXJlbnRET01Ob2RlID0gbnVsbDtcbiAgbGV0IG9ic2VydmVyID0gbnVsbDtcbiAgbGV0IGxhc3ROb2RlcyA9IFtdO1xuICBjb25zdCB3cmFwcGVyTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICB3cmFwcGVyTm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gIGZ1bmN0aW9uIHBvc2l0aW9uKCkge1xuICAgIGlmICghKHJvb3RET01Ob2RlICE9PSBudWxsKSkge1xuICAgICAgZm9ybWF0RGV2RXJyb3JNZXNzYWdlKGBVbmV4cGVjdGVkIG51bGwgcm9vdERPTU5vZGVgKTtcbiAgICB9XG4gICAgaWYgKCEocGFyZW50RE9NTm9kZSAhPT0gbnVsbCkpIHtcbiAgICAgIGZvcm1hdERldkVycm9yTWVzc2FnZShgVW5leHBlY3RlZCBudWxsIHBhcmVudERPTU5vZGVgKTtcbiAgICB9XG4gICAgY29uc3Qge1xuICAgICAgbGVmdDogcGFyZW50TGVmdCxcbiAgICAgIHRvcDogcGFyZW50VG9wXG4gICAgfSA9IHBhcmVudERPTU5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgcmVjdHMgPSBjcmVhdGVSZWN0c0Zyb21ET01SYW5nZShlZGl0b3IsIHJhbmdlKTtcbiAgICBpZiAoIXdyYXBwZXJOb2RlLmlzQ29ubmVjdGVkKSB7XG4gICAgICBwcmVwZW5kRE9NTm9kZShwYXJlbnRET01Ob2RlLCB3cmFwcGVyTm9kZSk7XG4gICAgfVxuICAgIGxldCBoYXNSZXBvc2l0aW9uZWQgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByZWN0ID0gcmVjdHNbaV07XG4gICAgICAvLyBUcnkgdG8gcmV1c2UgdGhlIHByZXZpb3VzbHkgY3JlYXRlZCBOb2RlIHdoZW4gcG9zc2libGUsIG5vIG5lZWQgdG9cbiAgICAgIC8vIHJlbW92ZS9jcmVhdGUgb24gdGhlIG1vc3QgY29tbW9uIGNhc2UgcmVwb3NpdGlvbiBjYXNlXG4gICAgICBjb25zdCByZWN0Tm9kZSA9IGxhc3ROb2Rlc1tpXSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnN0IHJlY3ROb2RlU3R5bGUgPSByZWN0Tm9kZS5zdHlsZTtcbiAgICAgIGlmIChyZWN0Tm9kZVN0eWxlLnBvc2l0aW9uICE9PSAnYWJzb2x1dGUnKSB7XG4gICAgICAgIHJlY3ROb2RlU3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICBoYXNSZXBvc2l0aW9uZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbGVmdCA9IHB4KHJlY3QubGVmdCAtIHBhcmVudExlZnQpO1xuICAgICAgaWYgKHJlY3ROb2RlU3R5bGUubGVmdCAhPT0gbGVmdCkge1xuICAgICAgICByZWN0Tm9kZVN0eWxlLmxlZnQgPSBsZWZ0O1xuICAgICAgICBoYXNSZXBvc2l0aW9uZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgdG9wID0gcHgocmVjdC50b3AgLSBwYXJlbnRUb3ApO1xuICAgICAgaWYgKHJlY3ROb2RlU3R5bGUudG9wICE9PSB0b3ApIHtcbiAgICAgICAgcmVjdE5vZGUuc3R5bGUudG9wID0gdG9wO1xuICAgICAgICBoYXNSZXBvc2l0aW9uZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgd2lkdGggPSBweChyZWN0LndpZHRoKTtcbiAgICAgIGlmIChyZWN0Tm9kZVN0eWxlLndpZHRoICE9PSB3aWR0aCkge1xuICAgICAgICByZWN0Tm9kZS5zdHlsZS53aWR0aCA9IHdpZHRoO1xuICAgICAgICBoYXNSZXBvc2l0aW9uZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaGVpZ2h0ID0gcHgocmVjdC5oZWlnaHQpO1xuICAgICAgaWYgKHJlY3ROb2RlU3R5bGUuaGVpZ2h0ICE9PSBoZWlnaHQpIHtcbiAgICAgICAgcmVjdE5vZGUuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBoYXNSZXBvc2l0aW9uZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlY3ROb2RlLnBhcmVudE5vZGUgIT09IHdyYXBwZXJOb2RlKSB7XG4gICAgICAgIHdyYXBwZXJOb2RlLmFwcGVuZChyZWN0Tm9kZSk7XG4gICAgICAgIGhhc1JlcG9zaXRpb25lZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBsYXN0Tm9kZXNbaV0gPSByZWN0Tm9kZTtcbiAgICB9XG4gICAgd2hpbGUgKGxhc3ROb2Rlcy5sZW5ndGggPiByZWN0cy5sZW5ndGgpIHtcbiAgICAgIGxhc3ROb2Rlcy5wb3AoKTtcbiAgICB9XG4gICAgaWYgKGhhc1JlcG9zaXRpb25lZCkge1xuICAgICAgb25SZXBvc2l0aW9uKGxhc3ROb2Rlcyk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgcGFyZW50RE9NTm9kZSA9IG51bGw7XG4gICAgcm9vdERPTU5vZGUgPSBudWxsO1xuICAgIGlmIChvYnNlcnZlciAhPT0gbnVsbCkge1xuICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgICBvYnNlcnZlciA9IG51bGw7XG4gICAgd3JhcHBlck5vZGUucmVtb3ZlKCk7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIGxhc3ROb2Rlcykge1xuICAgICAgbm9kZS5yZW1vdmUoKTtcbiAgICB9XG4gICAgbGFzdE5vZGVzID0gW107XG4gIH1cbiAgZnVuY3Rpb24gcmVzdGFydCgpIHtcbiAgICBjb25zdCBjdXJyZW50Um9vdERPTU5vZGUgPSBlZGl0b3IuZ2V0Um9vdEVsZW1lbnQoKTtcbiAgICBpZiAoY3VycmVudFJvb3RET01Ob2RlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gc3RvcCgpO1xuICAgIH1cbiAgICBjb25zdCBjdXJyZW50UGFyZW50RE9NTm9kZSA9IGN1cnJlbnRSb290RE9NTm9kZS5wYXJlbnRFbGVtZW50O1xuICAgIGlmICghaXNIVE1MRWxlbWVudChjdXJyZW50UGFyZW50RE9NTm9kZSkpIHtcbiAgICAgIHJldHVybiBzdG9wKCk7XG4gICAgfVxuICAgIHN0b3AoKTtcbiAgICByb290RE9NTm9kZSA9IGN1cnJlbnRSb290RE9NTm9kZTtcbiAgICBwYXJlbnRET01Ob2RlID0gY3VycmVudFBhcmVudERPTU5vZGU7XG4gICAgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihtdXRhdGlvbnMgPT4ge1xuICAgICAgY29uc3QgbmV4dFJvb3RET01Ob2RlID0gZWRpdG9yLmdldFJvb3RFbGVtZW50KCk7XG4gICAgICBjb25zdCBuZXh0UGFyZW50RE9NTm9kZSA9IG5leHRSb290RE9NTm9kZSAmJiBuZXh0Um9vdERPTU5vZGUucGFyZW50RWxlbWVudDtcbiAgICAgIGlmIChuZXh0Um9vdERPTU5vZGUgIT09IHJvb3RET01Ob2RlIHx8IG5leHRQYXJlbnRET01Ob2RlICE9PSBwYXJlbnRET01Ob2RlKSB7XG4gICAgICAgIHJldHVybiByZXN0YXJ0KCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG11dGF0aW9uIG9mIG11dGF0aW9ucykge1xuICAgICAgICBpZiAoIXdyYXBwZXJOb2RlLmNvbnRhaW5zKG11dGF0aW9uLnRhcmdldCkpIHtcbiAgICAgICAgICAvLyBUT0RPIHRocm90dGxlXG4gICAgICAgICAgcmV0dXJuIHBvc2l0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRQYXJlbnRET01Ob2RlLCBtdXRhdGlvbk9ic2VydmVyQ29uZmlnKTtcbiAgICBwb3NpdGlvbigpO1xuICB9XG4gIGNvbnN0IHJlbW92ZVJvb3RMaXN0ZW5lciA9IGVkaXRvci5yZWdpc3RlclJvb3RMaXN0ZW5lcihyZXN0YXJ0KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICByZW1vdmVSb290TGlzdGVuZXIoKTtcbiAgICBzdG9wKCk7XG4gIH07XG59XG5cbi8qKlxuICogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqXG4gKi9cblxuZnVuY3Rpb24gJGdldE9yZGVyZWRTZWxlY3Rpb25Qb2ludHMoc2VsZWN0aW9uKSB7XG4gIGNvbnN0IHBvaW50cyA9IHNlbGVjdGlvbi5nZXRTdGFydEVuZFBvaW50cygpO1xuICByZXR1cm4gc2VsZWN0aW9uLmlzQmFja3dhcmQoKSA/IFtwb2ludHNbMV0sIHBvaW50c1swXV0gOiBwb2ludHM7XG59XG5mdW5jdGlvbiByYW5nZVRhcmdldEZyb21Qb2ludChwb2ludCwgbm9kZSwgZG9tKSB7XG4gIGlmIChwb2ludC50eXBlID09PSAndGV4dCcgfHwgISRpc0VsZW1lbnROb2RlKG5vZGUpKSB7XG4gICAgY29uc3QgdGV4dERPTSA9IGdldERPTVRleHROb2RlKGRvbSkgfHwgZG9tO1xuICAgIHJldHVybiBbdGV4dERPTSwgcG9pbnQub2Zmc2V0XTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBzbG90ID0gbm9kZS5nZXRET01TbG90KGRvbSk7XG4gICAgcmV0dXJuIFtzbG90LmVsZW1lbnQsIHNsb3QuZ2V0Rmlyc3RDaGlsZE9mZnNldCgpICsgcG9pbnQub2Zmc2V0XTtcbiAgfVxufVxuZnVuY3Rpb24gcmFuZ2VGcm9tUG9pbnRzKGVkaXRvciwgc3RhcnQsIHN0YXJ0Tm9kZSwgc3RhcnRET00sIGVuZCwgZW5kTm9kZSwgZW5kRE9NKSB7XG4gIGNvbnN0IGVkaXRvckRvY3VtZW50ID0gZWRpdG9yLl93aW5kb3cgPyBlZGl0b3IuX3dpbmRvdy5kb2N1bWVudCA6IGRvY3VtZW50O1xuICBjb25zdCByYW5nZSA9IGVkaXRvckRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gIHJhbmdlLnNldFN0YXJ0KC4uLnJhbmdlVGFyZ2V0RnJvbVBvaW50KHN0YXJ0LCBzdGFydE5vZGUsIHN0YXJ0RE9NKSk7XG4gIHJhbmdlLnNldEVuZCguLi5yYW5nZVRhcmdldEZyb21Qb2ludChlbmQsIGVuZE5vZGUsIGVuZERPTSkpO1xuICByZXR1cm4gcmFuZ2U7XG59XG4vKipcbiAqIFBsYWNlIG9uZSBvciBtdWx0aXBsZSBuZXdseSBjcmVhdGVkIE5vZGVzIGF0IHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gTXVsdGlwbGVcbiAqIG5vZGVzIHdpbGwgb25seSBiZSBjcmVhdGVkIHdoZW4gdGhlIHNlbGVjdGlvbiBzcGFucyBtdWx0aXBsZSBsaW5lcyAoYWthXG4gKiBjbGllbnQgcmVjdHMpLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gY2FuIGNvbWUgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gc2hvdyB0aGUgc2VsZWN0aW9uIGJ1dCB0aGVcbiAqIGVkaXRvciBoYXMgYmVlbiBmb2N1c2VkIGF3YXkuXG4gKi9cbmZ1bmN0aW9uIG1hcmtTZWxlY3Rpb24oZWRpdG9yLCBvblJlcG9zaXRpb24pIHtcbiAgbGV0IHByZXZpb3VzQW5jaG9yTm9kZSA9IG51bGw7XG4gIGxldCBwcmV2aW91c0FuY2hvck5vZGVET00gPSBudWxsO1xuICBsZXQgcHJldmlvdXNBbmNob3JPZmZzZXQgPSBudWxsO1xuICBsZXQgcHJldmlvdXNGb2N1c05vZGUgPSBudWxsO1xuICBsZXQgcHJldmlvdXNGb2N1c05vZGVET00gPSBudWxsO1xuICBsZXQgcHJldmlvdXNGb2N1c09mZnNldCA9IG51bGw7XG4gIGxldCByZW1vdmVSYW5nZUxpc3RlbmVyID0gKCkgPT4ge307XG4gIGZ1bmN0aW9uIGNvbXB1dGUoZWRpdG9yU3RhdGUpIHtcbiAgICBlZGl0b3JTdGF0ZS5yZWFkKCgpID0+IHtcbiAgICAgIGNvbnN0IHNlbGVjdGlvbiA9ICRnZXRTZWxlY3Rpb24oKTtcbiAgICAgIGlmICghJGlzUmFuZ2VTZWxlY3Rpb24oc2VsZWN0aW9uKSkge1xuICAgICAgICAvLyBUT0RPXG4gICAgICAgIHByZXZpb3VzQW5jaG9yTm9kZSA9IG51bGw7XG4gICAgICAgIHByZXZpb3VzQW5jaG9yT2Zmc2V0ID0gbnVsbDtcbiAgICAgICAgcHJldmlvdXNGb2N1c05vZGUgPSBudWxsO1xuICAgICAgICBwcmV2aW91c0ZvY3VzT2Zmc2V0ID0gbnVsbDtcbiAgICAgICAgcmVtb3ZlUmFuZ2VMaXN0ZW5lcigpO1xuICAgICAgICByZW1vdmVSYW5nZUxpc3RlbmVyID0gKCkgPT4ge307XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9ICRnZXRPcmRlcmVkU2VsZWN0aW9uUG9pbnRzKHNlbGVjdGlvbik7XG4gICAgICBjb25zdCBjdXJyZW50U3RhcnROb2RlID0gc3RhcnQuZ2V0Tm9kZSgpO1xuICAgICAgY29uc3QgY3VycmVudFN0YXJ0Tm9kZUtleSA9IGN1cnJlbnRTdGFydE5vZGUuZ2V0S2V5KCk7XG4gICAgICBjb25zdCBjdXJyZW50U3RhcnRPZmZzZXQgPSBzdGFydC5vZmZzZXQ7XG4gICAgICBjb25zdCBjdXJyZW50RW5kTm9kZSA9IGVuZC5nZXROb2RlKCk7XG4gICAgICBjb25zdCBjdXJyZW50RW5kTm9kZUtleSA9IGN1cnJlbnRFbmROb2RlLmdldEtleSgpO1xuICAgICAgY29uc3QgY3VycmVudEVuZE9mZnNldCA9IGVuZC5vZmZzZXQ7XG4gICAgICBjb25zdCBjdXJyZW50U3RhcnROb2RlRE9NID0gZWRpdG9yLmdldEVsZW1lbnRCeUtleShjdXJyZW50U3RhcnROb2RlS2V5KTtcbiAgICAgIGNvbnN0IGN1cnJlbnRFbmROb2RlRE9NID0gZWRpdG9yLmdldEVsZW1lbnRCeUtleShjdXJyZW50RW5kTm9kZUtleSk7XG4gICAgICBjb25zdCBkaWZmZXJlbnRTdGFydERPTSA9IHByZXZpb3VzQW5jaG9yTm9kZSA9PT0gbnVsbCB8fCBjdXJyZW50U3RhcnROb2RlRE9NICE9PSBwcmV2aW91c0FuY2hvck5vZGVET00gfHwgY3VycmVudFN0YXJ0T2Zmc2V0ICE9PSBwcmV2aW91c0FuY2hvck9mZnNldCB8fCBjdXJyZW50U3RhcnROb2RlS2V5ICE9PSBwcmV2aW91c0FuY2hvck5vZGUuZ2V0S2V5KCk7XG4gICAgICBjb25zdCBkaWZmZXJlbnRFbmRET00gPSBwcmV2aW91c0ZvY3VzTm9kZSA9PT0gbnVsbCB8fCBjdXJyZW50RW5kTm9kZURPTSAhPT0gcHJldmlvdXNGb2N1c05vZGVET00gfHwgY3VycmVudEVuZE9mZnNldCAhPT0gcHJldmlvdXNGb2N1c09mZnNldCB8fCBjdXJyZW50RW5kTm9kZUtleSAhPT0gcHJldmlvdXNGb2N1c05vZGUuZ2V0S2V5KCk7XG4gICAgICBpZiAoKGRpZmZlcmVudFN0YXJ0RE9NIHx8IGRpZmZlcmVudEVuZERPTSkgJiYgY3VycmVudFN0YXJ0Tm9kZURPTSAhPT0gbnVsbCAmJiBjdXJyZW50RW5kTm9kZURPTSAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCByYW5nZSA9IHJhbmdlRnJvbVBvaW50cyhlZGl0b3IsIHN0YXJ0LCBjdXJyZW50U3RhcnROb2RlLCBjdXJyZW50U3RhcnROb2RlRE9NLCBlbmQsIGN1cnJlbnRFbmROb2RlLCBjdXJyZW50RW5kTm9kZURPTSk7XG4gICAgICAgIHJlbW92ZVJhbmdlTGlzdGVuZXIoKTtcbiAgICAgICAgcmVtb3ZlUmFuZ2VMaXN0ZW5lciA9IG1sY1Bvc2l0aW9uTm9kZU9uUmFuZ2UoZWRpdG9yLCByYW5nZSwgZG9tTm9kZXMgPT4ge1xuICAgICAgICAgIGlmIChvblJlcG9zaXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBkb21Ob2RlIG9mIGRvbU5vZGVzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGRvbU5vZGVTdHlsZSA9IGRvbU5vZGUuc3R5bGU7XG4gICAgICAgICAgICAgIGlmIChkb21Ob2RlU3R5bGUuYmFja2dyb3VuZCAhPT0gJ0hpZ2hsaWdodCcpIHtcbiAgICAgICAgICAgICAgICBkb21Ob2RlU3R5bGUuYmFja2dyb3VuZCA9ICdIaWdobGlnaHQnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChkb21Ob2RlU3R5bGUuY29sb3IgIT09ICdIaWdobGlnaHRUZXh0Jykge1xuICAgICAgICAgICAgICAgIGRvbU5vZGVTdHlsZS5jb2xvciA9ICdIaWdobGlnaHRUZXh0JztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoZG9tTm9kZVN0eWxlLm1hcmdpblRvcCAhPT0gcHgoLTEuNSkpIHtcbiAgICAgICAgICAgICAgICBkb21Ob2RlU3R5bGUubWFyZ2luVG9wID0gcHgoLTEuNSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGRvbU5vZGVTdHlsZS5wYWRkaW5nVG9wICE9PSBweCg0KSkge1xuICAgICAgICAgICAgICAgIGRvbU5vZGVTdHlsZS5wYWRkaW5nVG9wID0gcHgoNCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGRvbU5vZGVTdHlsZS5wYWRkaW5nQm90dG9tICE9PSBweCgwKSkge1xuICAgICAgICAgICAgICAgIGRvbU5vZGVTdHlsZS5wYWRkaW5nQm90dG9tID0gcHgoMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb25SZXBvc2l0aW9uKGRvbU5vZGVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcHJldmlvdXNBbmNob3JOb2RlID0gY3VycmVudFN0YXJ0Tm9kZTtcbiAgICAgIHByZXZpb3VzQW5jaG9yTm9kZURPTSA9IGN1cnJlbnRTdGFydE5vZGVET007XG4gICAgICBwcmV2aW91c0FuY2hvck9mZnNldCA9IGN1cnJlbnRTdGFydE9mZnNldDtcbiAgICAgIHByZXZpb3VzRm9jdXNOb2RlID0gY3VycmVudEVuZE5vZGU7XG4gICAgICBwcmV2aW91c0ZvY3VzTm9kZURPTSA9IGN1cnJlbnRFbmROb2RlRE9NO1xuICAgICAgcHJldmlvdXNGb2N1c09mZnNldCA9IGN1cnJlbnRFbmRPZmZzZXQ7XG4gICAgfSk7XG4gIH1cbiAgY29tcHV0ZShlZGl0b3IuZ2V0RWRpdG9yU3RhdGUoKSk7XG4gIHJldHVybiBtZXJnZVJlZ2lzdGVyKGVkaXRvci5yZWdpc3RlclVwZGF0ZUxpc3RlbmVyKCh7XG4gICAgZWRpdG9yU3RhdGVcbiAgfSkgPT4gY29tcHV0ZShlZGl0b3JTdGF0ZSkpLCAoKSA9PiB7XG4gICAgcmVtb3ZlUmFuZ2VMaXN0ZW5lcigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgKGMpIE1ldGEgUGxhdGZvcm1zLCBJbmMuIGFuZCBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3Rpb25BbHdheXNPbkRpc3BsYXkoZWRpdG9yLCBvblJlcG9zaXRpb24pIHtcbiAgbGV0IHJlbW92ZVNlbGVjdGlvbk1hcmsgPSBudWxsO1xuICBjb25zdCBvblNlbGVjdGlvbkNoYW5nZSA9ICgpID0+IHtcbiAgICBjb25zdCBkb21TZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBkb21BbmNob3JOb2RlID0gZG9tU2VsZWN0aW9uICYmIGRvbVNlbGVjdGlvbi5hbmNob3JOb2RlO1xuICAgIGNvbnN0IGVkaXRvclJvb3RFbGVtZW50ID0gZWRpdG9yLmdldFJvb3RFbGVtZW50KCk7XG4gICAgY29uc3QgaXNTZWxlY3Rpb25JbnNpZGVFZGl0b3IgPSBkb21BbmNob3JOb2RlICE9PSBudWxsICYmIGVkaXRvclJvb3RFbGVtZW50ICE9PSBudWxsICYmIGVkaXRvclJvb3RFbGVtZW50LmNvbnRhaW5zKGRvbUFuY2hvck5vZGUpO1xuICAgIGlmIChpc1NlbGVjdGlvbkluc2lkZUVkaXRvcikge1xuICAgICAgaWYgKHJlbW92ZVNlbGVjdGlvbk1hcmsgIT09IG51bGwpIHtcbiAgICAgICAgcmVtb3ZlU2VsZWN0aW9uTWFyaygpO1xuICAgICAgICByZW1vdmVTZWxlY3Rpb25NYXJrID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlbW92ZVNlbGVjdGlvbk1hcmsgPT09IG51bGwpIHtcbiAgICAgICAgcmVtb3ZlU2VsZWN0aW9uTWFyayA9IG1hcmtTZWxlY3Rpb24oZWRpdG9yLCBvblJlcG9zaXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0aW9uY2hhbmdlJywgb25TZWxlY3Rpb25DaGFuZ2UpO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIGlmIChyZW1vdmVTZWxlY3Rpb25NYXJrICE9PSBudWxsKSB7XG4gICAgICByZW1vdmVTZWxlY3Rpb25NYXJrKCk7XG4gICAgfVxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbmNoYW5nZScsIG9uU2VsZWN0aW9uQ2hhbmdlKTtcbiAgfTtcbn1cblxuLy8gSG90Zml4IHRvIGV4cG9ydCB0aGVzZSB3aXRoIGlubGluZWQgdHlwZXMgIzU5MThcbmNvbnN0IENBTl9VU0VfQkVGT1JFX0lOUFVUID0gQ0FOX1VTRV9CRUZPUkVfSU5QVVQkMTtcbmNvbnN0IENBTl9VU0VfRE9NID0gQ0FOX1VTRV9ET00kMTtcbmNvbnN0IElTX0FORFJPSUQgPSBJU19BTkRST0lEJDE7XG5jb25zdCBJU19BTkRST0lEX0NIUk9NRSA9IElTX0FORFJPSURfQ0hST01FJDE7XG5jb25zdCBJU19BUFBMRSA9IElTX0FQUExFJDE7XG5jb25zdCBJU19BUFBMRV9XRUJLSVQgPSBJU19BUFBMRV9XRUJLSVQkMTtcbmNvbnN0IElTX0NIUk9NRSA9IElTX0NIUk9NRSQxO1xuY29uc3QgSVNfRklSRUZPWCA9IElTX0ZJUkVGT1gkMTtcbmNvbnN0IElTX0lPUyA9IElTX0lPUyQxO1xuY29uc3QgSVNfU0FGQVJJID0gSVNfU0FGQVJJJDE7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIHR5cGUgbWF0Y2hlcyB0aGUgdHlwZXMgcGFzc2VkIHdpdGhpbiB0aGUgYWNjZXB0YWJsZU1pbWVUeXBlcyBhcnJheSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICogVGhlIHR5cGVzIHBhc3NlZCBtdXN0IGJlIHN0cmluZ3MgYW5kIGFyZSBDQVNFLVNFTlNJVElWRS5cbiAqIGVnLiBpZiBmaWxlIGlzIG9mIHR5cGUgJ3RleHQnIGFuZCBhY2NlcHRhYmxlTWltZVR5cGVzID0gWydURVhUJywgJ0lNQUdFJ10gdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGZhbHNlLlxuICogQHBhcmFtIGZpbGUgLSBUaGUgZmlsZSB5b3Ugd2FudCB0byB0eXBlIGNoZWNrLlxuICogQHBhcmFtIGFjY2VwdGFibGVNaW1lVHlwZXMgLSBBbiBhcnJheSBvZiBzdHJpbmdzIG9mIHR5cGVzIHdoaWNoIHRoZSBmaWxlIGlzIGNoZWNrZWQgYWdhaW5zdC5cbiAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGZpbGUgaXMgYW4gYWNjZXB0YWJsZSBtaW1lIHR5cGUsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZnVuY3Rpb24gaXNNaW1lVHlwZShmaWxlLCBhY2NlcHRhYmxlTWltZVR5cGVzKSB7XG4gIGZvciAoY29uc3QgYWNjZXB0YWJsZVR5cGUgb2YgYWNjZXB0YWJsZU1pbWVUeXBlcykge1xuICAgIGlmIChmaWxlLnR5cGUuc3RhcnRzV2l0aChhY2NlcHRhYmxlVHlwZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogTGV4aWNhbCBGaWxlIFJlYWRlciB3aXRoOlxuICogIDEuIE1JTUUgdHlwZSBzdXBwb3J0XG4gKiAgMi4gYmF0Y2hlZCByZXN1bHRzIChIaXN0b3J5UGx1Z2luIGNvbXBhdGliaWxpdHkpXG4gKiAgMy4gT3JkZXIgYXdhcmUgKHJlc3BlY3RzIHRoZSBvcmRlciB3aGVuIG11bHRpcGxlIEZpbGVzIGFyZSBwYXNzZWQpXG4gKlxuICogY29uc3QgZmlsZXNSZXN1bHQgPSBhd2FpdCBtZWRpYUZpbGVSZWFkZXIoZmlsZXMsIFsnaW1hZ2UvJ10pO1xuICogZmlsZXNSZXN1bHQuZm9yRWFjaChmaWxlID0+IGVkaXRvci5kaXNwYXRjaENvbW1hbmQoJ0lOU0VSVF9JTUFHRScsIFxcXFx7XG4gKiAgIHNyYzogZmlsZS5yZXN1bHQsXG4gKiBcXFxcfSkpO1xuICovXG5mdW5jdGlvbiBtZWRpYUZpbGVSZWFkZXIoZmlsZXMsIGFjY2VwdGFibGVNaW1lVHlwZXMpIHtcbiAgY29uc3QgZmlsZXNJdGVyYXRvciA9IGZpbGVzW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBwcm9jZXNzZWQgPSBbXTtcbiAgICBjb25zdCBoYW5kbGVOZXh0RmlsZSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZG9uZSxcbiAgICAgICAgdmFsdWU6IGZpbGVcbiAgICAgIH0gPSBmaWxlc0l0ZXJhdG9yLm5leHQoKTtcbiAgICAgIGlmIChkb25lKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHByb2Nlc3NlZCk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCByZWplY3QpO1xuICAgICAgZmlsZVJlYWRlci5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBmaWxlUmVhZGVyLnJlc3VsdDtcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcHJvY2Vzc2VkLnB1c2goe1xuICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZU5leHRGaWxlKCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChpc01pbWVUeXBlKGZpbGUsIGFjY2VwdGFibGVNaW1lVHlwZXMpKSB7XG4gICAgICAgIGZpbGVSZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhhbmRsZU5leHRGaWxlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBoYW5kbGVOZXh0RmlsZSgpO1xuICB9KTtcbn1cbi8qKlxuICogXCJEZXB0aC1GaXJzdCBTZWFyY2hcIiBzdGFydHMgYXQgdGhlIHJvb3QvdG9wIG5vZGUgb2YgYSB0cmVlIGFuZCBnb2VzIGFzIGZhciBhcyBpdCBjYW4gZG93biBhIGJyYW5jaCBlbmRcbiAqIGJlZm9yZSBiYWNrdHJhY2tpbmcgYW5kIGZpbmRpbmcgYSBuZXcgcGF0aC4gQ29uc2lkZXIgc29sdmluZyBhIG1hemUgYnkgaHVnZ2luZyBlaXRoZXIgd2FsbCwgbW92aW5nIGRvd24gYVxuICogYnJhbmNoIHVudGlsIHlvdSBoaXQgYSBkZWFkLWVuZCAobGVhZikgYW5kIGJhY2t0cmFja2luZyB0byBmaW5kIHRoZSBuZWFyZXN0IGJyYW5jaGluZyBwYXRoIGFuZCByZXBlYXQuXG4gKiBJdCB3aWxsIHRoZW4gcmV0dXJuIGFsbCB0aGUgbm9kZXMgZm91bmQgaW4gdGhlIHNlYXJjaCBpbiBhbiBhcnJheSBvZiBvYmplY3RzLlxuICogUHJlb3JkZXIgdHJhdmVyc2FsIGlzIHVzZWQsIG1lYW5pbmcgdGhhdCBub2RlcyBhcmUgbGlzdGVkIGluIHRoZSBvcmRlciBvZiB3aGVuIHRoZXkgYXJlIEZJUlNUIGVuY291bnRlcmVkLlxuICogQHBhcmFtIHN0YXJ0Tm9kZSAtIFRoZSBub2RlIHRvIHN0YXJ0IHRoZSBzZWFyY2ggKGluY2x1c2l2ZSksIGlmIG9taXR0ZWQsIGl0IHdpbGwgc3RhcnQgYXQgdGhlIHJvb3Qgbm9kZS5cbiAqIEBwYXJhbSBlbmROb2RlIC0gVGhlIG5vZGUgdG8gZW5kIHRoZSBzZWFyY2ggKGluY2x1c2l2ZSksIGlmIG9taXR0ZWQsIGl0IHdpbGwgZmluZCBhbGwgZGVzY2VuZGFudHMgb2YgdGhlIHN0YXJ0aW5nTm9kZS4gSWYgZW5kTm9kZVxuICogaXMgYW4gRWxlbWVudE5vZGUsIGl0IHdpbGwgc3RvcCBiZWZvcmUgdmlzaXRpbmcgYW55IG9mIGl0cyBjaGlsZHJlbi5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIG9iamVjdHMgb2YgYWxsIHRoZSBub2RlcyBmb3VuZCBieSB0aGUgc2VhcmNoLCBpbmNsdWRpbmcgdGhlaXIgZGVwdGggaW50byB0aGUgdHJlZS5cbiAqIFxcXFx7ZGVwdGg6IG51bWJlciwgbm9kZTogTGV4aWNhbE5vZGVcXFxcfSBJdCB3aWxsIGFsd2F5cyByZXR1cm4gYXQgbGVhc3QgMSBub2RlICh0aGUgc3RhcnQgbm9kZSkuXG4gKi9cbmZ1bmN0aW9uICRkZnMoc3RhcnROb2RlLCBlbmROb2RlKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKCRkZnNJdGVyYXRvcihzdGFydE5vZGUsIGVuZE5vZGUpKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGFkamFjZW50IGNhcmV0IGluIHRoZSBzYW1lIGRpcmVjdGlvblxuICpcbiAqIEBwYXJhbSBjYXJldCBBIGNhcmV0IG9yIG51bGxcbiAqIEByZXR1cm5zIGBjYXJldC5nZXRBZGphY2VudENhcmV0KClgIG9yIGBudWxsYFxuICovXG5mdW5jdGlvbiAkZ2V0QWRqYWNlbnRDYXJldChjYXJldCkge1xuICByZXR1cm4gY2FyZXQgPyBjYXJldC5nZXRBZGphY2VudENhcmV0KCkgOiBudWxsO1xufVxuXG4vKipcbiAqICRkZnMgaXRlcmF0b3IgKHJpZ2h0IHRvIGxlZnQpLiBUcmVlIHRyYXZlcnNhbCBpcyBkb25lIG9uIHRoZSBmbHkgYXMgbmV3IHZhbHVlcyBhcmUgcmVxdWVzdGVkIHdpdGggTygxKSBtZW1vcnkuXG4gKiBAcGFyYW0gc3RhcnROb2RlIC0gVGhlIG5vZGUgdG8gc3RhcnQgdGhlIHNlYXJjaCwgaWYgb21pdHRlZCwgaXQgd2lsbCBzdGFydCBhdCB0aGUgcm9vdCBub2RlLlxuICogQHBhcmFtIGVuZE5vZGUgLSBUaGUgbm9kZSB0byBlbmQgdGhlIHNlYXJjaCwgaWYgb21pdHRlZCwgaXQgd2lsbCBmaW5kIGFsbCBkZXNjZW5kYW50cyBvZiB0aGUgc3RhcnRpbmdOb2RlLlxuICogQHJldHVybnMgQW4gaXRlcmF0b3IsIGVhY2ggeWllbGRlZCB2YWx1ZSBpcyBhIERGU05vZGUuIEl0IHdpbGwgYWx3YXlzIHJldHVybiBhdCBsZWFzdCAxIG5vZGUgKHRoZSBzdGFydCBub2RlKS5cbiAqL1xuZnVuY3Rpb24gJHJldmVyc2VEZnMoc3RhcnROb2RlLCBlbmROb2RlKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKCRyZXZlcnNlRGZzSXRlcmF0b3Ioc3RhcnROb2RlLCBlbmROb2RlKSk7XG59XG5cbi8qKlxuICogJGRmcyBpdGVyYXRvciAobGVmdCB0byByaWdodCkuIFRyZWUgdHJhdmVyc2FsIGlzIGRvbmUgb24gdGhlIGZseSBhcyBuZXcgdmFsdWVzIGFyZSByZXF1ZXN0ZWQgd2l0aCBPKDEpIG1lbW9yeS5cbiAqIFByZW9yZGVyIHRyYXZlcnNhbCBpcyB1c2VkLCBtZWFuaW5nIHRoYXQgbm9kZXMgYXJlIGl0ZXJhdGVkIG92ZXIgaW4gdGhlIG9yZGVyIG9mIHdoZW4gdGhleSBhcmUgRklSU1QgZW5jb3VudGVyZWQuXG4gKiBAcGFyYW0gc3RhcnROb2RlIC0gVGhlIG5vZGUgdG8gc3RhcnQgdGhlIHNlYXJjaCAoaW5jbHVzaXZlKSwgaWYgb21pdHRlZCwgaXQgd2lsbCBzdGFydCBhdCB0aGUgcm9vdCBub2RlLlxuICogQHBhcmFtIGVuZE5vZGUgLSBUaGUgbm9kZSB0byBlbmQgdGhlIHNlYXJjaCAoaW5jbHVzaXZlKSwgaWYgb21pdHRlZCwgaXQgd2lsbCBmaW5kIGFsbCBkZXNjZW5kYW50cyBvZiB0aGUgc3RhcnRpbmdOb2RlLlxuICogSWYgZW5kTm9kZSBpcyBhbiBFbGVtZW50Tm9kZSwgdGhlIGl0ZXJhdG9yIHdpbGwgZW5kIGFzIHNvb24gYXMgaXQgcmVhY2hlcyB0aGUgZW5kTm9kZSAobm8gY2hpbGRyZW4gd2lsbCBiZSB2aXNpdGVkKS5cbiAqIEByZXR1cm5zIEFuIGl0ZXJhdG9yLCBlYWNoIHlpZWxkZWQgdmFsdWUgaXMgYSBERlNOb2RlLiBJdCB3aWxsIGFsd2F5cyByZXR1cm4gYXQgbGVhc3QgMSBub2RlICh0aGUgc3RhcnQgbm9kZSkuXG4gKi9cbmZ1bmN0aW9uICRkZnNJdGVyYXRvcihzdGFydE5vZGUsIGVuZE5vZGUpIHtcbiAgcmV0dXJuICRkZnNDYXJldEl0ZXJhdG9yKCduZXh0Jywgc3RhcnROb2RlLCBlbmROb2RlKTtcbn1cbmZ1bmN0aW9uICRnZXRFbmRDYXJldChzdGFydE5vZGUsIGRpcmVjdGlvbikge1xuICBjb25zdCBydmFsID0gJGdldEFkamFjZW50U2libGluZ09yUGFyZW50U2libGluZ0NhcmV0KCRnZXRTaWJsaW5nQ2FyZXQoc3RhcnROb2RlLCBkaXJlY3Rpb24pKTtcbiAgcmV0dXJuIHJ2YWwgJiYgcnZhbFswXTtcbn1cbmZ1bmN0aW9uICRkZnNDYXJldEl0ZXJhdG9yKGRpcmVjdGlvbiwgc3RhcnROb2RlLCBlbmROb2RlKSB7XG4gIGNvbnN0IHJvb3QgPSAkZ2V0Um9vdCgpO1xuICBjb25zdCBzdGFydCA9IHN0YXJ0Tm9kZSB8fCByb290O1xuICBjb25zdCBzdGFydENhcmV0ID0gJGlzRWxlbWVudE5vZGUoc3RhcnQpID8gJGdldENoaWxkQ2FyZXQoc3RhcnQsIGRpcmVjdGlvbikgOiAkZ2V0U2libGluZ0NhcmV0KHN0YXJ0LCBkaXJlY3Rpb24pO1xuICBjb25zdCBzdGFydERlcHRoID0gJGdldERlcHRoKHN0YXJ0KTtcbiAgY29uc3QgZW5kQ2FyZXQgPSBlbmROb2RlID8gJGdldEFkamFjZW50Q2hpbGRDYXJldCgkZ2V0Q2hpbGRDYXJldE9yU2VsZigkZ2V0U2libGluZ0NhcmV0KGVuZE5vZGUsIGRpcmVjdGlvbikpKSB8fCAkZ2V0RW5kQ2FyZXQoZW5kTm9kZSwgZGlyZWN0aW9uKSA6ICRnZXRFbmRDYXJldChzdGFydCwgZGlyZWN0aW9uKTtcbiAgbGV0IGRlcHRoID0gc3RhcnREZXB0aDtcbiAgcmV0dXJuIG1ha2VTdGVwd2lzZUl0ZXJhdG9yKHtcbiAgICBoYXNOZXh0OiBzdGF0ZSA9PiBzdGF0ZSAhPT0gbnVsbCxcbiAgICBpbml0aWFsOiBzdGFydENhcmV0LFxuICAgIG1hcDogc3RhdGUgPT4gKHtcbiAgICAgIGRlcHRoLFxuICAgICAgbm9kZTogc3RhdGUub3JpZ2luXG4gICAgfSksXG4gICAgc3RlcDogc3RhdGUgPT4ge1xuICAgICAgaWYgKHN0YXRlLmlzU2FtZU5vZGVDYXJldChlbmRDYXJldCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoJGlzQ2hpbGRDYXJldChzdGF0ZSkpIHtcbiAgICAgICAgZGVwdGgrKztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJ2YWwgPSAkZ2V0QWRqYWNlbnRTaWJsaW5nT3JQYXJlbnRTaWJsaW5nQ2FyZXQoc3RhdGUpO1xuICAgICAgaWYgKCFydmFsIHx8IHJ2YWxbMF0uaXNTYW1lTm9kZUNhcmV0KGVuZENhcmV0KSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGRlcHRoICs9IHJ2YWxbMV07XG4gICAgICByZXR1cm4gcnZhbFswXTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIE5vZGUgc2libGluZyB3aGVuIHRoaXMgZXhpc3RzLCBvdGhlcndpc2UgdGhlIGNsb3Nlc3QgcGFyZW50IHNpYmxpbmcuIEZvciBleGFtcGxlXG4gKiBSIC0+IFAgLT4gVDEsIFQyXG4gKiAgIC0+IFAyXG4gKiByZXR1cm5zIFQyIGZvciBub2RlIFQxLCBQMiBmb3Igbm9kZSBUMiwgYW5kIG51bGwgZm9yIG5vZGUgUDIuXG4gKiBAcGFyYW0gbm9kZSBMZXhpY2FsTm9kZS5cbiAqIEByZXR1cm5zIEFuIGFycmF5ICh0dXBsZSkgY29udGFpbmluZyB0aGUgZm91bmQgTGV4aWNhbCBub2RlIGFuZCB0aGUgZGVwdGggZGlmZmVyZW5jZSwgb3IgbnVsbCwgaWYgdGhpcyBub2RlIGRvZXNuJ3QgZXhpc3QuXG4gKi9cbmZ1bmN0aW9uICRnZXROZXh0U2libGluZ09yUGFyZW50U2libGluZyhub2RlKSB7XG4gIGNvbnN0IHJ2YWwgPSAkZ2V0QWRqYWNlbnRTaWJsaW5nT3JQYXJlbnRTaWJsaW5nQ2FyZXQoJGdldFNpYmxpbmdDYXJldChub2RlLCAnbmV4dCcpKTtcbiAgcmV0dXJuIHJ2YWwgJiYgW3J2YWxbMF0ub3JpZ2luLCBydmFsWzFdXTtcbn1cbmZ1bmN0aW9uICRnZXREZXB0aChub2RlKSB7XG4gIGxldCBkZXB0aCA9IC0xO1xuICBmb3IgKGxldCBpbm5lck5vZGUgPSBub2RlOyBpbm5lck5vZGUgIT09IG51bGw7IGlubmVyTm9kZSA9IGlubmVyTm9kZS5nZXRQYXJlbnQoKSkge1xuICAgIGRlcHRoKys7XG4gIH1cbiAgcmV0dXJuIGRlcHRoO1xufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgcmlnaHQtdG8tbGVmdCBwcmVvcmRlciB0cmVlIHRyYXZlcnNhbC5cbiAqIEZyb20gdGhlIHN0YXJ0aW5nIG5vZGUgaXQgZ29lcyB0byB0aGUgcmlnaHRtb3N0IGNoaWxkLCB0aGFuIGJhY2t0cmFja3MgdG8gcGFyZW50IGFuZCBmaW5kcyBuZXcgcmlnaHRtb3N0IHBhdGguXG4gKiBJdCB3aWxsIHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRyYXZlcnNhbCBzZXF1ZW5jZSBhZnRlciB0aGUgc3RhcnRpbmdOb2RlLlxuICogVGhlIHRyYXZlcnNhbCBpcyBzaW1pbGFyIHRvICRkZnMgZnVuY3Rpb25zIGFib3ZlLCBidXQgdGhlIG5vZGVzIGFyZSB2aXNpdGVkIHJpZ2h0LXRvLWxlZnQsIG5vdCBsZWZ0LXRvLXJpZ2h0LlxuICogQHBhcmFtIHN0YXJ0aW5nTm9kZSAtIFRoZSBub2RlIHRvIHN0YXJ0IHRoZSBzZWFyY2guXG4gKiBAcmV0dXJucyBUaGUgbmV4dCBub2RlIGluIHByZS1vcmRlciByaWdodCB0byBsZWZ0IHRyYXZlcnNhbCBzZXF1ZW5jZSBvciBgbnVsbGAsIGlmIHRoZSBub2RlIGRvZXMgbm90IGV4aXN0XG4gKi9cbmZ1bmN0aW9uICRnZXROZXh0UmlnaHRQcmVvcmRlck5vZGUoc3RhcnRpbmdOb2RlKSB7XG4gIGNvbnN0IHN0YXJ0Q2FyZXQgPSAkZ2V0Q2hpbGRDYXJldE9yU2VsZigkZ2V0U2libGluZ0NhcmV0KHN0YXJ0aW5nTm9kZSwgJ3ByZXZpb3VzJykpO1xuICBjb25zdCBuZXh0ID0gJGdldEFkamFjZW50U2libGluZ09yUGFyZW50U2libGluZ0NhcmV0KHN0YXJ0Q2FyZXQsICdyb290Jyk7XG4gIHJldHVybiBuZXh0ICYmIG5leHRbMF0ub3JpZ2luO1xufVxuXG4vKipcbiAqICRkZnMgaXRlcmF0b3IgKHJpZ2h0IHRvIGxlZnQpLiBUcmVlIHRyYXZlcnNhbCBpcyBkb25lIG9uIHRoZSBmbHkgYXMgbmV3IHZhbHVlcyBhcmUgcmVxdWVzdGVkIHdpdGggTygxKSBtZW1vcnkuXG4gKiBAcGFyYW0gc3RhcnROb2RlIC0gVGhlIG5vZGUgdG8gc3RhcnQgdGhlIHNlYXJjaCwgaWYgb21pdHRlZCwgaXQgd2lsbCBzdGFydCBhdCB0aGUgcm9vdCBub2RlLlxuICogQHBhcmFtIGVuZE5vZGUgLSBUaGUgbm9kZSB0byBlbmQgdGhlIHNlYXJjaCwgaWYgb21pdHRlZCwgaXQgd2lsbCBmaW5kIGFsbCBkZXNjZW5kYW50cyBvZiB0aGUgc3RhcnRpbmdOb2RlLlxuICogQHJldHVybnMgQW4gaXRlcmF0b3IsIGVhY2ggeWllbGRlZCB2YWx1ZSBpcyBhIERGU05vZGUuIEl0IHdpbGwgYWx3YXlzIHJldHVybiBhdCBsZWFzdCAxIG5vZGUgKHRoZSBzdGFydCBub2RlKS5cbiAqL1xuZnVuY3Rpb24gJHJldmVyc2VEZnNJdGVyYXRvcihzdGFydE5vZGUsIGVuZE5vZGUpIHtcbiAgcmV0dXJuICRkZnNDYXJldEl0ZXJhdG9yKCdwcmV2aW91cycsIHN0YXJ0Tm9kZSwgZW5kTm9kZSk7XG59XG5cbi8qKlxuICogVGFrZXMgYSBub2RlIGFuZCB0cmF2ZXJzZXMgdXAgaXRzIGFuY2VzdG9ycyAodG93YXJkIHRoZSByb290IG5vZGUpXG4gKiBpbiBvcmRlciB0byBmaW5kIGEgc3BlY2lmaWMgdHlwZSBvZiBub2RlLlxuICogQHBhcmFtIG5vZGUgLSB0aGUgbm9kZSB0byBiZWdpbiBzZWFyY2hpbmcuXG4gKiBAcGFyYW0ga2xhc3MgLSBhbiBpbnN0YW5jZSBvZiB0aGUgdHlwZSBvZiBub2RlIHRvIGxvb2sgZm9yLlxuICogQHJldHVybnMgdGhlIG5vZGUgb2YgdHlwZSBrbGFzcyB0aGF0IHdhcyBwYXNzZWQsIG9yIG51bGwgaWYgbm9uZSBleGlzdC5cbiAqL1xuZnVuY3Rpb24gJGdldE5lYXJlc3ROb2RlT2ZUeXBlKG5vZGUsIGtsYXNzKSB7XG4gIGxldCBwYXJlbnQgPSBub2RlO1xuICB3aGlsZSAocGFyZW50ICE9IG51bGwpIHtcbiAgICBpZiAocGFyZW50IGluc3RhbmNlb2Yga2xhc3MpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnQoKTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBlbGVtZW50IG5vZGUgb2YgdGhlIG5lYXJlc3QgYW5jZXN0b3IsIG90aGVyd2lzZSB0aHJvd3MgYW4gZXJyb3IuXG4gKiBAcGFyYW0gc3RhcnROb2RlIC0gVGhlIHN0YXJ0aW5nIG5vZGUgb2YgdGhlIHNlYXJjaFxuICogQHJldHVybnMgVGhlIGFuY2VzdG9yIG5vZGUgZm91bmRcbiAqL1xuZnVuY3Rpb24gJGdldE5lYXJlc3RCbG9ja0VsZW1lbnRBbmNlc3Rvck9yVGhyb3coc3RhcnROb2RlKSB7XG4gIGNvbnN0IGJsb2NrTm9kZSA9ICRmaW5kTWF0Y2hpbmdQYXJlbnQoc3RhcnROb2RlLCBub2RlID0+ICRpc0VsZW1lbnROb2RlKG5vZGUpICYmICFub2RlLmlzSW5saW5lKCkpO1xuICBpZiAoISRpc0VsZW1lbnROb2RlKGJsb2NrTm9kZSkpIHtcbiAgICB7XG4gICAgICBmb3JtYXREZXZFcnJvck1lc3NhZ2UoYEV4cGVjdGVkIG5vZGUgJHtzdGFydE5vZGUuX19rZXl9IHRvIGhhdmUgY2xvc2VzdCBibG9jayBlbGVtZW50IG5vZGUuYCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBibG9ja05vZGU7XG59XG4vKipcbiAqIEF0dGVtcHRzIHRvIHJlc29sdmUgbmVzdGVkIGVsZW1lbnQgbm9kZXMgb2YgdGhlIHNhbWUgdHlwZSBpbnRvIGEgc2luZ2xlIG5vZGUgb2YgdGhhdCB0eXBlLlxuICogSXQgaXMgZ2VuZXJhbGx5IHVzZWQgZm9yIG1hcmtzL2NvbW1lbnRpbmdcbiAqIEBwYXJhbSBlZGl0b3IgLSBUaGUgbGV4aWNhbCBlZGl0b3JcbiAqIEBwYXJhbSB0YXJnZXROb2RlIC0gVGhlIHRhcmdldCBmb3IgdGhlIG5lc3RlZCBlbGVtZW50IHRvIGJlIGV4dHJhY3RlZCBmcm9tLlxuICogQHBhcmFtIGNsb25lTm9kZSAtIFNlZSB7QGxpbmsgJGNyZWF0ZU1hcmtOb2RlfVxuICogQHBhcmFtIGhhbmRsZU92ZXJsYXAgLSBIYW5kbGVzIGFueSBvdmVybGFwIGJldHdlZW4gdGhlIG5vZGUgdG8gZXh0cmFjdCBhbmQgdGhlIHRhcmdldE5vZGVcbiAqIEByZXR1cm5zIFRoZSBsZXhpY2FsIGVkaXRvclxuICovXG5mdW5jdGlvbiByZWdpc3Rlck5lc3RlZEVsZW1lbnRSZXNvbHZlcihlZGl0b3IsIHRhcmdldE5vZGUsIGNsb25lTm9kZSwgaGFuZGxlT3ZlcmxhcCkge1xuICBjb25zdCAkaXNUYXJnZXROb2RlID0gbm9kZSA9PiB7XG4gICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiB0YXJnZXROb2RlO1xuICB9O1xuICBjb25zdCAkZmluZE1hdGNoID0gbm9kZSA9PiB7XG4gICAgLy8gRmlyc3QgdmFsaWRhdGUgd2UgZG9uJ3QgaGF2ZSBhbnkgY2hpbGRyZW4gdGhhdCBhcmUgb2YgdGhlIHRhcmdldCxcbiAgICAvLyBhcyB3ZSBuZWVkIHRvIGhhbmRsZSB0aGVtIGZpcnN0LlxuICAgIGNvbnN0IGNoaWxkcmVuID0gbm9kZS5nZXRDaGlsZHJlbigpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICBpZiAoJGlzVGFyZ2V0Tm9kZShjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBwYXJlbnROb2RlID0gbm9kZTtcbiAgICBsZXQgY2hpbGROb2RlID0gbm9kZTtcbiAgICB3aGlsZSAocGFyZW50Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgY2hpbGROb2RlID0gcGFyZW50Tm9kZTtcbiAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLmdldFBhcmVudCgpO1xuICAgICAgaWYgKCRpc1RhcmdldE5vZGUocGFyZW50Tm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjaGlsZDogY2hpbGROb2RlLFxuICAgICAgICAgIHBhcmVudDogcGFyZW50Tm9kZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbiAgY29uc3QgJGVsZW1lbnROb2RlVHJhbnNmb3JtID0gbm9kZSA9PiB7XG4gICAgY29uc3QgbWF0Y2ggPSAkZmluZE1hdGNoKG5vZGUpO1xuICAgIGlmIChtYXRjaCAhPT0gbnVsbCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjaGlsZCxcbiAgICAgICAgcGFyZW50XG4gICAgICB9ID0gbWF0Y2g7XG5cbiAgICAgIC8vIFNpbXBsZSBwYXRoLCB3ZSBjYW4gbW92ZSBjaGlsZCBvdXQgYW5kIHNpYmxpbmdzIGludG8gYSBuZXcgcGFyZW50LlxuXG4gICAgICBpZiAoY2hpbGQuaXMobm9kZSkpIHtcbiAgICAgICAgaGFuZGxlT3ZlcmxhcChwYXJlbnQsIG5vZGUpO1xuICAgICAgICBjb25zdCBuZXh0U2libGluZ3MgPSBjaGlsZC5nZXROZXh0U2libGluZ3MoKTtcbiAgICAgICAgY29uc3QgbmV4dFNpYmxpbmdzTGVuZ3RoID0gbmV4dFNpYmxpbmdzLmxlbmd0aDtcbiAgICAgICAgcGFyZW50Lmluc2VydEFmdGVyKGNoaWxkKTtcbiAgICAgICAgaWYgKG5leHRTaWJsaW5nc0xlbmd0aCAhPT0gMCkge1xuICAgICAgICAgIGNvbnN0IG5ld1BhcmVudCA9IGNsb25lTm9kZShwYXJlbnQpO1xuICAgICAgICAgIGNoaWxkLmluc2VydEFmdGVyKG5ld1BhcmVudCk7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXh0U2libGluZ3NMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbmV3UGFyZW50LmFwcGVuZChuZXh0U2libGluZ3NbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhcmVudC5jYW5CZUVtcHR5KCkgJiYgcGFyZW50LmdldENoaWxkcmVuU2l6ZSgpID09PSAwKSB7XG4gICAgICAgICAgcGFyZW50LnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuICByZXR1cm4gZWRpdG9yLnJlZ2lzdGVyTm9kZVRyYW5zZm9ybSh0YXJnZXROb2RlLCAkZWxlbWVudE5vZGVUcmFuc2Zvcm0pO1xufVxuXG4vKipcbiAqIENsb25lcyB0aGUgZWRpdG9yIGFuZCBtYXJrcyBpdCBhcyBkaXJ0eSB0byBiZSByZWNvbmNpbGVkLiBJZiB0aGVyZSB3YXMgYSBzZWxlY3Rpb24sXG4gKiBpdCB3b3VsZCBiZSBzZXQgYmFjayB0byBpdHMgcHJldmlvdXMgc3RhdGUsIG9yIG51bGwgb3RoZXJ3aXNlLlxuICogQHBhcmFtIGVkaXRvciAtIFRoZSBsZXhpY2FsIGVkaXRvclxuICogQHBhcmFtIGVkaXRvclN0YXRlIC0gVGhlIGVkaXRvcidzIHN0YXRlXG4gKi9cbmZ1bmN0aW9uICRyZXN0b3JlRWRpdG9yU3RhdGUoZWRpdG9yLCBlZGl0b3JTdGF0ZSkge1xuICBjb25zdCBGVUxMX1JFQ09OQ0lMRSA9IDI7XG4gIGNvbnN0IG5vZGVNYXAgPSBuZXcgTWFwKCk7XG4gIGNvbnN0IGFjdGl2ZUVkaXRvclN0YXRlID0gZWRpdG9yLl9wZW5kaW5nRWRpdG9yU3RhdGU7XG4gIGZvciAoY29uc3QgW2tleSwgbm9kZV0gb2YgZWRpdG9yU3RhdGUuX25vZGVNYXApIHtcbiAgICBub2RlTWFwLnNldChrZXksICRjbG9uZVdpdGhQcm9wZXJ0aWVzKG5vZGUpKTtcbiAgfVxuICBpZiAoYWN0aXZlRWRpdG9yU3RhdGUpIHtcbiAgICBhY3RpdmVFZGl0b3JTdGF0ZS5fbm9kZU1hcCA9IG5vZGVNYXA7XG4gIH1cbiAgZWRpdG9yLl9kaXJ0eVR5cGUgPSBGVUxMX1JFQ09OQ0lMRTtcbiAgY29uc3Qgc2VsZWN0aW9uID0gZWRpdG9yU3RhdGUuX3NlbGVjdGlvbjtcbiAgJHNldFNlbGVjdGlvbihzZWxlY3Rpb24gPT09IG51bGwgPyBudWxsIDogc2VsZWN0aW9uLmNsb25lKCkpO1xufVxuXG4vKipcbiAqIElmIHRoZSBzZWxlY3RlZCBpbnNlcnRpb24gYXJlYSBpcyB0aGUgcm9vdC9zaGFkb3cgcm9vdCBub2RlIChzZWUge0BsaW5rIGxleGljYWwhJGlzUm9vdE9yU2hhZG93Um9vdH0pLFxuICogdGhlIG5vZGUgd2lsbCBiZSBhcHBlbmRlZCB0aGVyZSwgb3RoZXJ3aXNlLCBpdCB3aWxsIGJlIGluc2VydGVkIGJlZm9yZSB0aGUgaW5zZXJ0aW9uIGFyZWEuXG4gKiBJZiB0aGVyZSBpcyBubyBzZWxlY3Rpb24gd2hlcmUgdGhlIG5vZGUgaXMgdG8gYmUgaW5zZXJ0ZWQsIGl0IHdpbGwgYmUgYXBwZW5kZWQgYWZ0ZXIgYW55IGN1cnJlbnQgbm9kZXNcbiAqIHdpdGhpbiB0aGUgdHJlZSwgYXMgYSBjaGlsZCBvZiB0aGUgcm9vdCBub2RlLiBBIHBhcmFncmFwaCB3aWxsIHRoZW4gYmUgYWRkZWQgYWZ0ZXIgdGhlIGluc2VydGVkIG5vZGUgYW5kIHNlbGVjdGVkLlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBiZSBpbnNlcnRlZFxuICogQHJldHVybnMgVGhlIG5vZGUgYWZ0ZXIgaXRzIGluc2VydGlvblxuICovXG5mdW5jdGlvbiAkaW5zZXJ0Tm9kZVRvTmVhcmVzdFJvb3Qobm9kZSkge1xuICBjb25zdCBzZWxlY3Rpb24gPSAkZ2V0U2VsZWN0aW9uKCkgfHwgJGdldFByZXZpb3VzU2VsZWN0aW9uKCk7XG4gIGxldCBpbml0aWFsQ2FyZXQ7XG4gIGlmICgkaXNSYW5nZVNlbGVjdGlvbihzZWxlY3Rpb24pKSB7XG4gICAgaW5pdGlhbENhcmV0ID0gJGNhcmV0RnJvbVBvaW50KHNlbGVjdGlvbi5mb2N1cywgJ25leHQnKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoc2VsZWN0aW9uICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IG5vZGVzID0gc2VsZWN0aW9uLmdldE5vZGVzKCk7XG4gICAgICBjb25zdCBsYXN0Tm9kZSA9IG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdO1xuICAgICAgaWYgKGxhc3ROb2RlKSB7XG4gICAgICAgIGluaXRpYWxDYXJldCA9ICRnZXRTaWJsaW5nQ2FyZXQobGFzdE5vZGUsICduZXh0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIGluaXRpYWxDYXJldCA9IGluaXRpYWxDYXJldCB8fCAkZ2V0Q2hpbGRDYXJldCgkZ2V0Um9vdCgpLCAncHJldmlvdXMnKS5nZXRGbGlwcGVkKCkuaW5zZXJ0KCRjcmVhdGVQYXJhZ3JhcGhOb2RlKCkpO1xuICB9XG4gIGNvbnN0IGluc2VydENhcmV0ID0gJGluc2VydE5vZGVUb05lYXJlc3RSb290QXRDYXJldChub2RlLCBpbml0aWFsQ2FyZXQpO1xuICBjb25zdCBhZGphY2VudCA9ICRnZXRBZGphY2VudENoaWxkQ2FyZXQoaW5zZXJ0Q2FyZXQpO1xuICBjb25zdCBzZWxlY3Rpb25DYXJldCA9ICRpc0NoaWxkQ2FyZXQoYWRqYWNlbnQpID8gJG5vcm1hbGl6ZUNhcmV0KGFkamFjZW50KSA6IGluc2VydENhcmV0O1xuICAkc2V0U2VsZWN0aW9uRnJvbUNhcmV0UmFuZ2UoJGdldENvbGxhcHNlZENhcmV0UmFuZ2Uoc2VsZWN0aW9uQ2FyZXQpKTtcbiAgcmV0dXJuIG5vZGUuZ2V0TGF0ZXN0KCk7XG59XG5cbi8qKlxuICogSWYgdGhlIGluc2VydGlvbiBjYXJldCBpcyB0aGUgcm9vdC9zaGFkb3cgcm9vdCBub2RlIChzZWUge0BsaW5rIGxleGljYWwhJGlzUm9vdE9yU2hhZG93Um9vdH0pLFxuICogdGhlIG5vZGUgd2lsbCBiZSBpbnNlcnRlZCB0aGVyZSwgb3RoZXJ3aXNlIHRoZSBwYXJlbnQgbm9kZXMgd2lsbCBiZSBzcGxpdCBhY2NvcmRpbmcgdG8gdGhlXG4gKiBnaXZlbiBvcHRpb25zLlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBiZSBpbnNlcnRlZFxuICogQHBhcmFtIGNhcmV0IC0gVGhlIGxvY2F0aW9uIHRvIGluc2VydCBvciBzcGxpdCBmcm9tXG4gKiBAcmV0dXJucyBUaGUgbm9kZSBhZnRlciBpdHMgaW5zZXJ0aW9uXG4gKi9cbmZ1bmN0aW9uICRpbnNlcnROb2RlVG9OZWFyZXN0Um9vdEF0Q2FyZXQobm9kZSwgY2FyZXQsIG9wdGlvbnMpIHtcbiAgbGV0IGluc2VydENhcmV0ID0gJGdldENhcmV0SW5EaXJlY3Rpb24oY2FyZXQsICduZXh0Jyk7XG4gIGZvciAobGV0IG5leHRDYXJldCA9IGluc2VydENhcmV0OyBuZXh0Q2FyZXQ7IG5leHRDYXJldCA9ICRzcGxpdEF0UG9pbnRDYXJldE5leHQobmV4dENhcmV0LCBvcHRpb25zKSkge1xuICAgIGluc2VydENhcmV0ID0gbmV4dENhcmV0O1xuICB9XG4gIGlmICghISRpc1RleHRQb2ludENhcmV0KGluc2VydENhcmV0KSkge1xuICAgIGZvcm1hdERldkVycm9yTWVzc2FnZShgJGluc2VydE5vZGVUb05lYXJlc3RSb290QXRDYXJldDogQW4gdW5hdHRhY2hlZCBUZXh0Tm9kZSBjYW4gbm90IGJlIHNwbGl0YCk7XG4gIH1cbiAgaW5zZXJ0Q2FyZXQuaW5zZXJ0KG5vZGUuaXNJbmxpbmUoKSA/ICRjcmVhdGVQYXJhZ3JhcGhOb2RlKCkuYXBwZW5kKG5vZGUpIDogbm9kZSk7XG4gIHJldHVybiAkZ2V0Q2FyZXRJbkRpcmVjdGlvbigkZ2V0U2libGluZ0NhcmV0KG5vZGUuZ2V0TGF0ZXN0KCksICduZXh0JyksIGNhcmV0LmRpcmVjdGlvbik7XG59XG5cbi8qKlxuICogV3JhcHMgdGhlIG5vZGUgaW50byBhbm90aGVyIG5vZGUgY3JlYXRlZCBmcm9tIGEgY3JlYXRlRWxlbWVudE5vZGUgZnVuY3Rpb24sIGVnLiAkY3JlYXRlUGFyYWdyYXBoTm9kZVxuICogQHBhcmFtIG5vZGUgLSBOb2RlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0gY3JlYXRlRWxlbWVudE5vZGUgLSBDcmVhdGVzIGEgbmV3IGxleGljYWwgZWxlbWVudCB0byB3cmFwIHRoZSB0by1iZS13cmFwcGVkIG5vZGUgYW5kIHJldHVybnMgaXQuXG4gKiBAcmV0dXJucyBBIG5ldyBsZXhpY2FsIGVsZW1lbnQgd2l0aCB0aGUgcHJldmlvdXMgbm9kZSBhcHBlbmRlZCB3aXRoaW4gKGFzIGEgY2hpbGQsIGluY2x1ZGluZyBpdHMgY2hpbGRyZW4pLlxuICovXG5mdW5jdGlvbiAkd3JhcE5vZGVJbkVsZW1lbnQobm9kZSwgY3JlYXRlRWxlbWVudE5vZGUpIHtcbiAgY29uc3QgZWxlbWVudE5vZGUgPSBjcmVhdGVFbGVtZW50Tm9kZSgpO1xuICBub2RlLnJlcGxhY2UoZWxlbWVudE5vZGUpO1xuICBlbGVtZW50Tm9kZS5hcHBlbmQobm9kZSk7XG4gIHJldHVybiBlbGVtZW50Tm9kZTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcblxuLyoqXG4gKiBAcGFyYW0gb2JqZWN0ID0gVGhlIGluc3RhbmNlIG9mIHRoZSB0eXBlXG4gKiBAcGFyYW0gb2JqZWN0Q2xhc3MgPSBUaGUgY2xhc3Mgb2YgdGhlIHR5cGVcbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIG9iamVjdCBpcyBoYXMgdGhlIHNhbWUgS2xhc3Mgb2YgdGhlIG9iamVjdENsYXNzLCBpZ25vcmluZyB0aGUgZGlmZmVyZW5jZSBhY3Jvc3Mgd2luZG93IChlLmcuIGRpZmZlcmVudCBpZnJhbWVzKVxuICovXG5mdW5jdGlvbiBvYmplY3RLbGFzc0VxdWFscyhvYmplY3QsIG9iamVjdENsYXNzKSB7XG4gIHJldHVybiBvYmplY3QgIT09IG51bGwgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KS5jb25zdHJ1Y3Rvci5uYW1lID09PSBvYmplY3RDbGFzcy5uYW1lIDogZmFsc2U7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNlIEFycmF5IGZpbHRlciBvciBmbGF0TWFwXG4gKlxuICogRmlsdGVyIHRoZSBub2Rlc1xuICogQHBhcmFtIG5vZGVzIEFycmF5IG9mIG5vZGVzIHRoYXQgbmVlZHMgdG8gYmUgZmlsdGVyZWRcbiAqIEBwYXJhbSBmaWx0ZXJGbiBBIGZpbHRlciBmdW5jdGlvbiB0aGF0IHJldHVybnMgbm9kZSBpZiB0aGUgY3VycmVudCBub2RlIHNhdGlzZmllcyB0aGUgY29uZGl0aW9uIG90aGVyd2lzZSBudWxsXG4gKiBAcmV0dXJucyBBcnJheSBvZiBmaWx0ZXJlZCBub2Rlc1xuICovXG5cbmZ1bmN0aW9uICRmaWx0ZXIobm9kZXMsIGZpbHRlckZuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgbm9kZSA9IGZpbHRlckZuKG5vZGVzW2ldKTtcbiAgICBpZiAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0LnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQXBwbGllcyB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgdG8gZWFjaCBpbmRlbnRhYmxlIGJsb2NrIGVsZW1lbnQgaW4gdGhlIFNlbGVjdGlvblxuICpcbiAqIEBwYXJhbSBpbmRlbnRPck91dGRlbnQgY2FsbGJhY2sgZm9yIHBlcmZvcm1pbmcgdGhlIGluZGVudCBvciBvdXRkZW50IGFjdGlvblxuICogb24gYSBnaXZlbiBibG9jayBlbGVtZW50LlxuICogQHJldHVybnMgdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgYmxvY2sgd2FzIGhhbmRsZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZnVuY3Rpb24gJGhhbmRsZUluZGVudEFuZE91dGRlbnQoaW5kZW50T3JPdXRkZW50KSB7XG4gIGNvbnN0IHNlbGVjdGlvbiA9ICRnZXRTZWxlY3Rpb24oKTtcbiAgaWYgKCEkaXNSYW5nZVNlbGVjdGlvbihzZWxlY3Rpb24pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGFscmVhZHlIYW5kbGVkID0gbmV3IFNldCgpO1xuICBjb25zdCBub2RlcyA9IHNlbGVjdGlvbi5nZXROb2RlcygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgbm9kZSA9IG5vZGVzW2ldO1xuICAgIGNvbnN0IGtleSA9IG5vZGUuZ2V0S2V5KCk7XG4gICAgaWYgKGFscmVhZHlIYW5kbGVkLmhhcyhrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50QmxvY2sgPSAkZmluZE1hdGNoaW5nUGFyZW50KG5vZGUsIHBhcmVudE5vZGUgPT4gJGlzRWxlbWVudE5vZGUocGFyZW50Tm9kZSkgJiYgIXBhcmVudE5vZGUuaXNJbmxpbmUoKSk7XG4gICAgaWYgKHBhcmVudEJsb2NrID09PSBudWxsKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50S2V5ID0gcGFyZW50QmxvY2suZ2V0S2V5KCk7XG4gICAgaWYgKHBhcmVudEJsb2NrLmNhbkluZGVudCgpICYmICFhbHJlYWR5SGFuZGxlZC5oYXMocGFyZW50S2V5KSkge1xuICAgICAgYWxyZWFkeUhhbmRsZWQuYWRkKHBhcmVudEtleSk7XG4gICAgICBpbmRlbnRPck91dGRlbnQocGFyZW50QmxvY2spO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYWxyZWFkeUhhbmRsZWQuc2l6ZSA+IDA7XG59XG5cbi8qKlxuICogQXBwZW5kcyB0aGUgbm9kZSBiZWZvcmUgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBwYXJlbnQgbm9kZVxuICogQHBhcmFtIHBhcmVudCBBIHBhcmVudCBub2RlXG4gKiBAcGFyYW0gbm9kZSBOb2RlIHRoYXQgbmVlZHMgdG8gYmUgYXBwZW5kZWRcbiAqL1xuZnVuY3Rpb24gJGluc2VydEZpcnN0KHBhcmVudCwgbm9kZSkge1xuICAkZ2V0Q2hpbGRDYXJldChwYXJlbnQsICduZXh0JykuaW5zZXJ0KG5vZGUpO1xufVxubGV0IE5FRURTX01BTlVBTF9aT09NID0gSVNfRklSRUZPWCB8fCAhQ0FOX1VTRV9ET00gPyBmYWxzZSA6IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIG5lZWRzTWFudWFsWm9vbSgpIHtcbiAgaWYgKE5FRURTX01BTlVBTF9aT09NID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBJZiB0aGUgYnJvd3NlciBpbXBsZW1lbnRzIHN0YW5kYXJkaXplZCBDU1Mgem9vbSwgdGhlbiB0aGUgY2xpZW50IHJlY3RcbiAgICAvLyB3aWxsIGJlIHdpZGVyIGFmdGVyIHpvb20gaXMgYXBwbGllZFxuICAgIC8vIGh0dHBzOi8vY2hyb21lc3RhdHVzLmNvbS9mZWF0dXJlLzUxOTgyNTQ4Njg1MjkxNTJcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svbGV4aWNhbC9pc3N1ZXMvNjg2M1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5zdHlsZS5jc3NUZXh0ID0gJ3Bvc2l0aW9uOiBhYnNvbHV0ZTsgb3BhY2l0eTogMDsgd2lkdGg6IDEwMHB4OyBsZWZ0OiAtMTAwMHB4Oyc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xuICAgIGNvbnN0IG5vWm9vbSA9IGRpdi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBkaXYuc3R5bGUuc2V0UHJvcGVydHkoJ3pvb20nLCAnMicpO1xuICAgIE5FRURTX01BTlVBTF9aT09NID0gZGl2LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoID09PSBub1pvb20ud2lkdGg7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChkaXYpO1xuICB9XG4gIHJldHVybiBORUVEU19NQU5VQUxfWk9PTTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSB6b29tIGxldmVsIG9mIGFuIGVsZW1lbnQgYXMgYSByZXN1bHQgb2YgdXNpbmdcbiAqIGNzcyB6b29tIHByb3BlcnR5LiBGb3IgYnJvd3NlcnMgdGhhdCBpbXBsZW1lbnQgc3RhbmRhcmRpemVkIENTU1xuICogem9vbSAoRmlyZWZveCwgQ2hyb21lID49IDEyOCksIHRoaXMgd2lsbCBhbHdheXMgcmV0dXJuIDEuXG4gKiBAcGFyYW0gZWxlbWVudFxuICogQHBhcmFtIHVzZU1hbnVhbFpvb20gLSBJZiB0cnVlLCBhbHdheXMgdXNlIHpvb20gbGV2ZWwgd2lsbCBiZSBjYWxjdWxhdGVkIG1hbnVhbGx5LCBvdGhlcndpc2UgaXQgd2lsbCBiZSBjYWxjdWxhdGVkIG9uIGFzIG5lZWRlZCBiYXNpcy5cbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlWm9vbUxldmVsKGVsZW1lbnQsIHVzZU1hbnVhbFpvb20gPSBmYWxzZSkge1xuICBsZXQgem9vbSA9IDE7XG4gIGlmIChuZWVkc01hbnVhbFpvb20oKSB8fCB1c2VNYW51YWxab29tKSB7XG4gICAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICAgIHpvb20gKj0gTnVtYmVyKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJ3pvb20nKSk7XG4gICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgIH1cbiAgfVxuICByZXR1cm4gem9vbTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGVkaXRvciBpcyBhIG5lc3RlZCBlZGl0b3IgY3JlYXRlZCBieSBMZXhpY2FsTmVzdGVkQ29tcG9zZXJcbiAqL1xuZnVuY3Rpb24gJGlzRWRpdG9ySXNOZXN0ZWRFZGl0b3IoZWRpdG9yKSB7XG4gIHJldHVybiBlZGl0b3IuX3BhcmVudEVkaXRvciAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBBIGRlcHRoIGZpcnN0IGxhc3QtdG8tZmlyc3QgdHJhdmVyc2FsIG9mIHJvb3QgdGhhdCBzdG9wcyBhdCBlYWNoIG5vZGUgdGhhdCBtYXRjaGVzXG4gKiAkcHJlZGljYXRlIGFuZCBlbnN1cmVzIHRoYXQgaXRzIHBhcmVudCBpcyByb290LiBUaGlzIGlzIHR5cGljYWxseSB1c2VkIHRvIGRpc2NhcmRcbiAqIGludmFsaWQgb3IgdW5zdXBwb3J0ZWQgd3JhcHBpbmcgbm9kZXMuIEZvciBleGFtcGxlLCBhIFRhYmxlTm9kZSBtdXN0IG9ubHkgaGF2ZVxuICogVGFibGVSb3dOb2RlIGFzIGNoaWxkcmVuLCBidXQgYW4gaW1wb3J0ZXIgbWlnaHQgYWRkIGludmFsaWQgbm9kZXMgYmFzZWQgb25cbiAqIGNhcHRpb24sIHRib2R5LCB0aGVhZCwgZXRjLiBhbmQgdGhpcyB3aWxsIHVud3JhcCBhbmQgZGlzY2FyZCB0aG9zZS5cbiAqXG4gKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCB0byBzdGFydCB0aGUgdHJhdmVyc2FsXG4gKiBAcGFyYW0gJHByZWRpY2F0ZSBTaG91bGQgcmV0dXJuIHRydWUgZm9yIG5vZGVzIHRoYXQgYXJlIHBlcm1pdHRlZCB0byBiZSBjaGlsZHJlbiBvZiByb290XG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoaXMgdW53cmFwcGVkIG9yIHJlbW92ZWQgYW55IG5vZGVzXG4gKi9cbmZ1bmN0aW9uICR1bndyYXBBbmRGaWx0ZXJEZXNjZW5kYW50cyhyb290LCAkcHJlZGljYXRlKSB7XG4gIHJldHVybiAkdW53cmFwQW5kRmlsdGVyRGVzY2VuZGFudHNJbXBsKHJvb3QsICRwcmVkaWNhdGUsIG51bGwpO1xufVxuZnVuY3Rpb24gJHVud3JhcEFuZEZpbHRlckRlc2NlbmRhbnRzSW1wbChyb290LCAkcHJlZGljYXRlLCAkb25TdWNjZXNzKSB7XG4gIGxldCBkaWRNdXRhdGUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCBub2RlIG9mICRsYXN0VG9GaXJzdEl0ZXJhdG9yKHJvb3QpKSB7XG4gICAgaWYgKCRwcmVkaWNhdGUobm9kZSkpIHtcbiAgICAgIGlmICgkb25TdWNjZXNzICE9PSBudWxsKSB7XG4gICAgICAgICRvblN1Y2Nlc3Mobm9kZSk7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICBpZiAoJGlzRWxlbWVudE5vZGUobm9kZSkpIHtcbiAgICAgICR1bndyYXBBbmRGaWx0ZXJEZXNjZW5kYW50c0ltcGwobm9kZSwgJHByZWRpY2F0ZSwgJG9uU3VjY2VzcyB8fCAoY2hpbGQgPT4gbm9kZS5pbnNlcnRBZnRlcihjaGlsZCkpKTtcbiAgICB9XG4gICAgbm9kZS5yZW1vdmUoKTtcbiAgfVxuICByZXR1cm4gZGlkTXV0YXRlO1xufVxuXG4vKipcbiAqIEEgZGVwdGggZmlyc3QgdHJhdmVyc2FsIG9mIHRoZSBjaGlsZHJlbiBhcnJheSB0aGF0IHN0b3BzIGF0IGFuZCBjb2xsZWN0c1xuICogZWFjaCBub2RlIHRoYXQgYCRwcmVkaWNhdGVgIG1hdGNoZXMuIFRoaXMgaXMgdHlwaWNhbGx5IHVzZWQgdG8gZGlzY2FyZFxuICogaW52YWxpZCBvciB1bnN1cHBvcnRlZCB3cmFwcGluZyBub2RlcyBvbiBhIGNoaWxkcmVuIGFycmF5IGluIHRoZSBgYWZ0ZXJgXG4gKiBvZiBhbiB7QGxpbmsgbGV4aWNhbCFET01Db252ZXJzaW9uT3V0cHV0fS4gRm9yIGV4YW1wbGUsIGEgVGFibGVOb2RlIG11c3Qgb25seSBoYXZlXG4gKiBUYWJsZVJvd05vZGUgYXMgY2hpbGRyZW4sIGJ1dCBhbiBpbXBvcnRlciBtaWdodCBhZGQgaW52YWxpZCBub2RlcyBiYXNlZCBvblxuICogY2FwdGlvbiwgdGJvZHksIHRoZWFkLCBldGMuIGFuZCB0aGlzIHdpbGwgdW53cmFwIGFuZCBkaXNjYXJkIHRob3NlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgcmVhZC1vbmx5IGFuZCBwZXJmb3JtcyBubyBtdXRhdGlvbiBvcGVyYXRpb25zLCB3aGljaCBtYWtlc1xuICogaXQgc3VpdGFibGUgZm9yIGltcG9ydCBhbmQgZXhwb3J0IHB1cnBvc2VzIGJ1dCBsaWtlbHkgbm90IGZvciBhbnkgaW4tcGxhY2VcbiAqIG11dGF0aW9uLiBZb3Ugc2hvdWxkIHVzZSB7QGxpbmsgJHVud3JhcEFuZEZpbHRlckRlc2NlbmRhbnRzfSBmb3IgaW4tcGxhY2VcbiAqIG11dGF0aW9ucyBzdWNoIGFzIG5vZGUgdHJhbnNmb3Jtcy5cbiAqXG4gKiBAcGFyYW0gY2hpbGRyZW4gVGhlIGNoaWxkcmVuIHRvIHRyYXZlcnNlXG4gKiBAcGFyYW0gJHByZWRpY2F0ZSBTaG91bGQgcmV0dXJuIHRydWUgZm9yIG5vZGVzIHRoYXQgYXJlIHBlcm1pdHRlZCB0byBiZSBjaGlsZHJlbiBvZiByb290XG4gKiBAcmV0dXJucyBUaGUgY2hpbGRyZW4gb3IgdGhlaXIgZGVzY2VuZGFudHMgdGhhdCBtYXRjaCAkcHJlZGljYXRlXG4gKi9cblxuZnVuY3Rpb24gJGRlc2NlbmRhbnRzTWF0Y2hpbmcoY2hpbGRyZW4sICRwcmVkaWNhdGUpIHtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGNvbnN0IHN0YWNrID0gQXJyYXkuZnJvbShjaGlsZHJlbikucmV2ZXJzZSgpO1xuICBmb3IgKGxldCBjaGlsZCA9IHN0YWNrLnBvcCgpOyBjaGlsZCAhPT0gdW5kZWZpbmVkOyBjaGlsZCA9IHN0YWNrLnBvcCgpKSB7XG4gICAgaWYgKCRwcmVkaWNhdGUoY2hpbGQpKSB7XG4gICAgICByZXN1bHQucHVzaChjaGlsZCk7XG4gICAgfSBlbHNlIGlmICgkaXNFbGVtZW50Tm9kZShjaGlsZCkpIHtcbiAgICAgIGZvciAoY29uc3QgZ3JhbmRjaGlsZCBvZiAkbGFzdFRvRmlyc3RJdGVyYXRvcihjaGlsZCkpIHtcbiAgICAgICAgc3RhY2sucHVzaChncmFuZGNoaWxkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYW4gaXRlcmF0b3IgdGhhdCB5aWVsZHMgZWFjaCBjaGlsZCBvZiBub2RlIGZyb20gZmlyc3QgdG8gbGFzdCwgdGFraW5nXG4gKiBjYXJlIHRvIHByZXNlcnZlIHRoZSBuZXh0IHNpYmxpbmcgYmVmb3JlIHlpZWxkaW5nIHRoZSB2YWx1ZSBpbiBjYXNlIHRoZSBjYWxsZXJcbiAqIHJlbW92ZXMgdGhlIHlpZWxkZWQgbm9kZS5cbiAqXG4gKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB3aG9zZSBjaGlsZHJlbiB0byBpdGVyYXRlXG4gKiBAcmV0dXJucyBBbiBpdGVyYXRvciBvZiB0aGUgbm9kZSdzIGNoaWxkcmVuXG4gKi9cbmZ1bmN0aW9uICRmaXJzdFRvTGFzdEl0ZXJhdG9yKG5vZGUpIHtcbiAgcmV0dXJuICRjaGlsZEl0ZXJhdG9yKCRnZXRDaGlsZENhcmV0KG5vZGUsICduZXh0JykpO1xufVxuXG4vKipcbiAqIFJldHVybiBhbiBpdGVyYXRvciB0aGF0IHlpZWxkcyBlYWNoIGNoaWxkIG9mIG5vZGUgZnJvbSBsYXN0IHRvIGZpcnN0LCB0YWtpbmdcbiAqIGNhcmUgdG8gcHJlc2VydmUgdGhlIHByZXZpb3VzIHNpYmxpbmcgYmVmb3JlIHlpZWxkaW5nIHRoZSB2YWx1ZSBpbiBjYXNlIHRoZSBjYWxsZXJcbiAqIHJlbW92ZXMgdGhlIHlpZWxkZWQgbm9kZS5cbiAqXG4gKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB3aG9zZSBjaGlsZHJlbiB0byBpdGVyYXRlXG4gKiBAcmV0dXJucyBBbiBpdGVyYXRvciBvZiB0aGUgbm9kZSdzIGNoaWxkcmVuXG4gKi9cbmZ1bmN0aW9uICRsYXN0VG9GaXJzdEl0ZXJhdG9yKG5vZGUpIHtcbiAgcmV0dXJuICRjaGlsZEl0ZXJhdG9yKCRnZXRDaGlsZENhcmV0KG5vZGUsICdwcmV2aW91cycpKTtcbn1cbmZ1bmN0aW9uICRjaGlsZEl0ZXJhdG9yKHN0YXJ0Q2FyZXQpIHtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKSA7XG4gIHJldHVybiBtYWtlU3RlcHdpc2VJdGVyYXRvcih7XG4gICAgaGFzTmV4dDogJGlzU2libGluZ0NhcmV0LFxuICAgIGluaXRpYWw6IHN0YXJ0Q2FyZXQuZ2V0QWRqYWNlbnRDYXJldCgpLFxuICAgIG1hcDogY2FyZXQgPT4ge1xuICAgICAgY29uc3Qgb3JpZ2luID0gY2FyZXQub3JpZ2luLmdldExhdGVzdCgpO1xuICAgICAgaWYgKHNlZW4gIT09IG51bGwpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gb3JpZ2luLmdldEtleSgpO1xuICAgICAgICBpZiAoISFzZWVuLmhhcyhrZXkpKSB7XG4gICAgICAgICAgZm9ybWF0RGV2RXJyb3JNZXNzYWdlKGAkY2hpbGRJdGVyYXRvcjogQ3ljbGUgZGV0ZWN0ZWQsIG5vZGUgd2l0aCBrZXkgJHtTdHJpbmcoa2V5KX0gaGFzIGFscmVhZHkgYmVlbiB0cmF2ZXJzZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBzZWVuLmFkZChrZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9yaWdpbjtcbiAgICB9LFxuICAgIHN0ZXA6IGNhcmV0ID0+IGNhcmV0LmdldEFkamFjZW50Q2FyZXQoKVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlIHRoaXMgbm9kZSB3aXRoIGl0cyBjaGlsZHJlblxuICpcbiAqIEBwYXJhbSBub2RlIFRoZSBFbGVtZW50Tm9kZSB0byB1bndyYXAgYW5kIHJlbW92ZVxuICovXG5mdW5jdGlvbiAkdW53cmFwTm9kZShub2RlKSB7XG4gICRyZXdpbmRTaWJsaW5nQ2FyZXQoJGdldFNpYmxpbmdDYXJldChub2RlLCAnbmV4dCcpKS5zcGxpY2UoMSwgbm9kZS5nZXRDaGlsZHJlbigpKTtcbn1cblxuLyoqXG4gKiBBIHdyYXBwZXIgdGhhdCBjcmVhdGVzIGJvdW5kIGZ1bmN0aW9ucyBhbmQgbWV0aG9kcyBmb3IgdGhlXG4gKiBTdGF0ZUNvbmZpZyB0byBzYXZlIHNvbWUgYm9pbGVycGxhdGUgd2hlbiBkZWZpbmluZyBtZXRob2RzXG4gKiBvciBleHBvcnRpbmcgb25seSB0aGUgYWNjZXNzb3JzIGZyb20geW91ciBtb2R1bGVzIHJhdGhlclxuICogdGhhbiBleHBvc2luZyB0aGUgU3RhdGVDb25maWcgZGlyZWN0bHkuXG4gKi9cblxuLyoqXG4gKiBFWFBFUklNRU5UQUxcbiAqXG4gKiBBIGNvbnZlbmllbmNlIGludGVyZmFjZSBmb3Igd29ya2luZyB3aXRoIHtAbGluayAkZ2V0U3RhdGV9IGFuZFxuICoge0BsaW5rICRzZXRTdGF0ZX0uXG4gKlxuICogQHBhcmFtIHN0YXRlQ29uZmlnIFRoZSBzdGF0ZUNvbmZpZyB0byB3cmFwIHdpdGggY29udmVuaWVuY2UgZnVuY3Rpb25hbGl0eVxuICogQHJldHVybnMgYSBTdGF0ZVdyYXBwZXJcbiAqL1xuZnVuY3Rpb24gbWFrZVN0YXRlV3JhcHBlcihzdGF0ZUNvbmZpZykge1xuICBjb25zdCAkZ2V0ID0gbm9kZSA9PiAkZ2V0U3RhdGUobm9kZSwgc3RhdGVDb25maWcpO1xuICBjb25zdCAkc2V0ID0gKG5vZGUsIHZhbHVlT3JVcGRhdGVyKSA9PiAkc2V0U3RhdGUobm9kZSwgc3RhdGVDb25maWcsIHZhbHVlT3JVcGRhdGVyKTtcbiAgcmV0dXJuIHtcbiAgICAkZ2V0LFxuICAgICRzZXQsXG4gICAgYWNjZXNzb3JzOiBbJGdldCwgJHNldF0sXG4gICAgbWFrZUdldHRlck1ldGhvZDogKCkgPT4gZnVuY3Rpb24gJGdldHRlcigpIHtcbiAgICAgIHJldHVybiAkZ2V0KHRoaXMpO1xuICAgIH0sXG4gICAgbWFrZVNldHRlck1ldGhvZDogKCkgPT4gZnVuY3Rpb24gJHNldHRlcih2YWx1ZU9yVXBkYXRlcikge1xuICAgICAgcmV0dXJuICRzZXQodGhpcywgdmFsdWVPclVwZGF0ZXIpO1xuICAgIH0sXG4gICAgc3RhdGVDb25maWdcbiAgfTtcbn1cblxuZXhwb3J0IHsgJGRlc2NlbmRhbnRzTWF0Y2hpbmcsICRkZnMsICRkZnNJdGVyYXRvciwgJGZpbHRlciwgJGZpcnN0VG9MYXN0SXRlcmF0b3IsICRnZXRBZGphY2VudENhcmV0LCAkZ2V0RGVwdGgsICRnZXROZWFyZXN0QmxvY2tFbGVtZW50QW5jZXN0b3JPclRocm93LCAkZ2V0TmVhcmVzdE5vZGVPZlR5cGUsICRnZXROZXh0UmlnaHRQcmVvcmRlck5vZGUsICRnZXROZXh0U2libGluZ09yUGFyZW50U2libGluZywgJGhhbmRsZUluZGVudEFuZE91dGRlbnQsICRpbnNlcnRGaXJzdCwgJGluc2VydE5vZGVUb05lYXJlc3RSb290LCAkaW5zZXJ0Tm9kZVRvTmVhcmVzdFJvb3RBdENhcmV0LCAkaXNFZGl0b3JJc05lc3RlZEVkaXRvciwgJGxhc3RUb0ZpcnN0SXRlcmF0b3IsICRyZXN0b3JlRWRpdG9yU3RhdGUsICRyZXZlcnNlRGZzLCAkcmV2ZXJzZURmc0l0ZXJhdG9yLCAkdW53cmFwQW5kRmlsdGVyRGVzY2VuZGFudHMsICR1bndyYXBOb2RlLCAkd3JhcE5vZGVJbkVsZW1lbnQsIENBTl9VU0VfQkVGT1JFX0lOUFVULCBDQU5fVVNFX0RPTSwgSVNfQU5EUk9JRCwgSVNfQU5EUk9JRF9DSFJPTUUsIElTX0FQUExFLCBJU19BUFBMRV9XRUJLSVQsIElTX0NIUk9NRSwgSVNfRklSRUZPWCwgSVNfSU9TLCBJU19TQUZBUkksIGNhbGN1bGF0ZVpvb21MZXZlbCwgaXNNaW1lVHlwZSwgbWFrZVN0YXRlV3JhcHBlciwgbWFya1NlbGVjdGlvbiwgbWVkaWFGaWxlUmVhZGVyLCBvYmplY3RLbGFzc0VxdWFscywgbWxjUG9zaXRpb25Ob2RlT25SYW5nZSBhcyBwb3NpdGlvbk5vZGVPblJhbmdlLCByZWdpc3Rlck5lc3RlZEVsZW1lbnRSZXNvbHZlciwgc2VsZWN0aW9uQWx3YXlzT25EaXNwbGF5IH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/.pnpm/@lexical+utils@0.41.0/node_modules/@lexical/utils/LexicalUtils.dev.mjs\n");
/***/ })
};
;