serverHandoffComplete ? genId() : undefined);\n index(() => {\n if (id == null) {\n setId(genId());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n serverHandoffComplete = true;\n }, []);\n return id;\n}\nconst useReactId = SafeReact.useId;\n\n/**\n * Uses React 18's built-in `useId()` when available, or falls back to a\n * slightly less performant (requiring a double render) implementation for\n * earlier React versions.\n * @see https://floating-ui.com/docs/react-utils#useid\n */\nconst useId = useReactId || useFloatingId;\n\nlet devMessageSet;\nif (true) {\n devMessageSet = /*#__PURE__*/new Set();\n}\nfunction warn() {\n var _devMessageSet;\n for (var _len = arguments.length, messages = new Array(_len), _key = 0; _key < _len; _key++) {\n messages[_key] = arguments[_key];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet = devMessageSet) != null && _devMessageSet.has(message))) {\n var _devMessageSet2;\n (_devMessageSet2 = devMessageSet) == null || _devMessageSet2.add(message);\n console.warn(message);\n }\n}\nfunction error() {\n var _devMessageSet3;\n for (var _len2 = arguments.length, messages = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n messages[_key2] = arguments[_key2];\n }\n const message = \"Floating UI: \" + messages.join(' ');\n if (!((_devMessageSet3 = devMessageSet) != null && _devMessageSet3.has(message))) {\n var _devMessageSet4;\n (_devMessageSet4 = devMessageSet) == null || _devMessageSet4.add(message);\n console.error(message);\n }\n}\n\n/**\n * Renders a pointing arrow triangle.\n * @see https://floating-ui.com/docs/FloatingArrow\n */\nconst FloatingArrow = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function FloatingArrow(props, ref) {\n const {\n context: {\n placement,\n elements: {\n floating\n },\n middlewareData: {\n arrow,\n shift\n }\n },\n width = 14,\n height = 7,\n tipRadius = 0,\n strokeWidth = 0,\n staticOffset,\n stroke,\n d,\n style: {\n transform,\n ...restStyle\n } = {},\n ...rest\n } = props;\n if (true) {\n if (!ref) {\n warn('The `ref` prop is required for `FloatingArrow`.');\n }\n }\n const clipPathId = useId();\n const [isRTL, setIsRTL] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);\n\n // https://github.com/floating-ui/floating-ui/issues/2932\n index(() => {\n if (!floating) return;\n const isRTL = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getComputedStyle)(floating).direction === 'rtl';\n if (isRTL) {\n setIsRTL(true);\n }\n }, [floating]);\n if (!floating) {\n return null;\n }\n const [side, alignment] = placement.split('-');\n const isVerticalSide = side === 'top' || side === 'bottom';\n let computedStaticOffset = staticOffset;\n if (isVerticalSide && shift != null && shift.x || !isVerticalSide && shift != null && shift.y) {\n computedStaticOffset = null;\n }\n\n // Strokes must be double the border width, this ensures the stroke's width\n // works as you'd expect.\n const computedStrokeWidth = strokeWidth * 2;\n const halfStrokeWidth = computedStrokeWidth / 2;\n const svgX = width / 2 * (tipRadius / -8 + 1);\n const svgY = height / 2 * tipRadius / 4;\n const isCustomShape = !!d;\n const yOffsetProp = computedStaticOffset && alignment === 'end' ? 'bottom' : 'top';\n let xOffsetProp = computedStaticOffset && alignment === 'end' ? 'right' : 'left';\n if (computedStaticOffset && isRTL) {\n xOffsetProp = alignment === 'end' ? 'left' : 'right';\n }\n const arrowX = (arrow == null ? void 0 : arrow.x) != null ? computedStaticOffset || arrow.x : '';\n const arrowY = (arrow == null ? void 0 : arrow.y) != null ? computedStaticOffset || arrow.y : '';\n const dValue = d || 'M0,0' + (\" H\" + width) + (\" L\" + (width - svgX) + \",\" + (height - svgY)) + (\" Q\" + width / 2 + \",\" + height + \" \" + svgX + \",\" + (height - svgY)) + ' Z';\n const rotation = {\n top: isCustomShape ? 'rotate(180deg)' : '',\n left: isCustomShape ? 'rotate(90deg)' : 'rotate(-90deg)',\n bottom: isCustomShape ? '' : 'rotate(180deg)',\n right: isCustomShape ? 'rotate(-90deg)' : 'rotate(90deg)'\n }[side];\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"svg\", _extends({}, rest, {\n \"aria-hidden\": true,\n ref: ref,\n width: isCustomShape ? width : width + computedStrokeWidth,\n height: width,\n viewBox: \"0 0 \" + width + \" \" + (height > width ? height : width),\n style: {\n position: 'absolute',\n pointerEvents: 'none',\n [xOffsetProp]: arrowX,\n [yOffsetProp]: arrowY,\n [side]: isVerticalSide || isCustomShape ? '100%' : \"calc(100% - \" + computedStrokeWidth / 2 + \"px)\",\n transform: \"\" + rotation + (transform != null ? transform : ''),\n ...restStyle\n }\n }), computedStrokeWidth > 0 && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"path\", {\n clipPath: \"url(#\" + clipPathId + \")\",\n fill: \"none\",\n stroke: stroke\n // Account for the stroke on the fill path rendered below.\n ,\n strokeWidth: computedStrokeWidth + (d ? 0 : 1),\n d: dValue\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"path\", {\n stroke: computedStrokeWidth && !d ? rest.fill : 'none',\n d: dValue\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"clipPath\", {\n id: clipPathId\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"rect\", {\n x: -halfStrokeWidth,\n y: halfStrokeWidth * (isCustomShape ? -1 : 1),\n width: width + computedStrokeWidth,\n height: width\n })));\n});\n\nfunction createPubSub() {\n const map = new Map();\n return {\n emit(event, data) {\n var _map$get;\n (_map$get = map.get(event)) == null || _map$get.forEach(handler => handler(data));\n },\n on(event, listener) {\n map.set(event, [...(map.get(event) || []), listener]);\n },\n off(event, listener) {\n var _map$get2;\n map.set(event, ((_map$get2 = map.get(event)) == null ? void 0 : _map$get2.filter(l => l !== listener)) || []);\n }\n };\n}\n\nconst FloatingNodeContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);\nconst FloatingTreeContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);\n\n/**\n * Returns the parent node id for nested floating elements, if available.\n * Returns `null` for top-level floating elements.\n */\nconst useFloatingParentNodeId = () => {\n var _React$useContext;\n return ((_React$useContext = react__WEBPACK_IMPORTED_MODULE_0__.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;\n};\n\n/**\n * Returns the nearest floating tree context, if available.\n */\nconst useFloatingTree = () => react__WEBPACK_IMPORTED_MODULE_0__.useContext(FloatingTreeContext);\n\n/**\n * Registers a node into the `FloatingTree`, returning its id.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction useFloatingNodeId(customParentId) {\n const id = useId();\n const tree = useFloatingTree();\n const reactParentId = useFloatingParentNodeId();\n const parentId = customParentId || reactParentId;\n index(() => {\n const node = {\n id,\n parentId\n };\n tree == null || tree.addNode(node);\n return () => {\n tree == null || tree.removeNode(node);\n };\n }, [tree, id, parentId]);\n return id;\n}\n/**\n * Provides parent node context for nested floating elements.\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingNode(props) {\n const {\n children,\n id\n } = props;\n const parentId = useFloatingParentNodeId();\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FloatingNodeContext.Provider, {\n value: react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n id,\n parentId\n }), [id, parentId])\n }, children);\n}\n/**\n * Provides context for nested floating elements when they are not children of\n * each other on the DOM.\n * This is not necessary in all cases, except when there must be explicit communication between parent and child floating elements. It is necessary for:\n * - The `bubbles` option in the `useDismiss()` Hook\n * - Nested virtual list navigation\n * - Nested floating elements that each open on hover\n * - Custom communication between parent and child floating elements\n * @see https://floating-ui.com/docs/FloatingTree\n */\nfunction FloatingTree(props) {\n const {\n children\n } = props;\n const nodesRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef([]);\n const addNode = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {\n nodesRef.current = [...nodesRef.current, node];\n }, []);\n const removeNode = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {\n nodesRef.current = nodesRef.current.filter(n => n !== node);\n }, []);\n const events = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => createPubSub())[0];\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FloatingTreeContext.Provider, {\n value: react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n nodesRef,\n addNode,\n removeNode,\n events\n }), [addNode, removeNode, events])\n }, children);\n}\n\nfunction createAttribute(name) {\n return \"data-floating-ui-\" + name;\n}\n\nfunction useLatestRef(value) {\n const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(value);\n index(() => {\n ref.current = value;\n });\n return ref;\n}\n\nconst safePolygonIdentifier = /*#__PURE__*/createAttribute('safe-polygon');\nfunction getDelay(value, prop, pointerType) {\n if (pointerType && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerType)) {\n return 0;\n }\n if (typeof value === 'number') {\n return value;\n }\n return value == null ? void 0 : value[prop];\n}\n/**\n * Opens the floating element while hovering over the reference element, like\n * CSS `:hover`.\n * @see https://floating-ui.com/docs/useHover\n */\nfunction useHover(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n events,\n elements\n } = context;\n const {\n enabled = true,\n delay = 0,\n handleClose = null,\n mouseOnly = false,\n restMs = 0,\n move = true\n } = props;\n const tree = useFloatingTree();\n const parentId = useFloatingParentNodeId();\n const handleCloseRef = useLatestRef(handleClose);\n const delayRef = useLatestRef(delay);\n const openRef = useLatestRef(open);\n const pointerTypeRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();\n const timeoutRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(-1);\n const handlerRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();\n const restTimeoutRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(-1);\n const blockMouseMoveRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(true);\n const performedPointerEventsMutationRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const unbindMouseMoveRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(() => {});\n const isHoverOpen = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(() => {\n var _dataRef$current$open;\n const type = (_dataRef$current$open = dataRef.current.openEvent) == null ? void 0 : _dataRef$current$open.type;\n return (type == null ? void 0 : type.includes('mouse')) && type !== 'mousedown';\n }, [dataRef]);\n\n // When closing before opening, clear the delay timeouts to cancel it\n // from showing.\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n open\n } = _ref;\n if (!open) {\n clearTimeout(timeoutRef.current);\n clearTimeout(restTimeoutRef.current);\n blockMouseMoveRef.current = true;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [enabled, events]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n if (!handleCloseRef.current) return;\n if (!open) return;\n function onLeave(event) {\n if (isHoverOpen()) {\n onOpenChange(false, event, 'hover');\n }\n }\n const html = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating).documentElement;\n html.addEventListener('mouseleave', onLeave);\n return () => {\n html.removeEventListener('mouseleave', onLeave);\n };\n }, [elements.floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);\n const closeWithDelay = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(function (event, runElseBranch, reason) {\n if (runElseBranch === void 0) {\n runElseBranch = true;\n }\n if (reason === void 0) {\n reason = 'hover';\n }\n const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);\n if (closeDelay && !handlerRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = window.setTimeout(() => onOpenChange(false, event, reason), closeDelay);\n } else if (runElseBranch) {\n clearTimeout(timeoutRef.current);\n onOpenChange(false, event, reason);\n }\n }, [delayRef, onOpenChange]);\n const cleanupMouseMoveHandler = useEffectEvent(() => {\n unbindMouseMoveRef.current();\n handlerRef.current = undefined;\n });\n const clearPointerEvents = useEffectEvent(() => {\n if (performedPointerEventsMutationRef.current) {\n const body = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating).body;\n body.style.pointerEvents = '';\n body.removeAttribute(safePolygonIdentifier);\n performedPointerEventsMutationRef.current = false;\n }\n });\n\n // Registering the mouse events on the reference directly to bypass React's\n // delegation system. If the cursor was on a disabled element and then entered\n // the reference (no gap), `mouseenter` doesn't fire in the delegation system.\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n function isClickLikeOpenEvent() {\n return dataRef.current.openEvent ? ['click', 'mousedown'].includes(dataRef.current.openEvent.type) : false;\n }\n function onMouseEnter(event) {\n clearTimeout(timeoutRef.current);\n blockMouseMoveRef.current = false;\n if (mouseOnly && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerTypeRef.current) || restMs > 0 && !getDelay(delayRef.current, 'open')) {\n return;\n }\n const openDelay = getDelay(delayRef.current, 'open', pointerTypeRef.current);\n if (openDelay) {\n timeoutRef.current = window.setTimeout(() => {\n if (!openRef.current) {\n onOpenChange(true, event, 'hover');\n }\n }, openDelay);\n } else {\n onOpenChange(true, event, 'hover');\n }\n }\n function onMouseLeave(event) {\n if (isClickLikeOpenEvent()) return;\n unbindMouseMoveRef.current();\n const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating);\n clearTimeout(restTimeoutRef.current);\n if (handleCloseRef.current && dataRef.current.floatingContext) {\n // Prevent clearing `onScrollMouseLeave` timeout.\n if (!open) {\n clearTimeout(timeoutRef.current);\n }\n handlerRef.current = handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n closeWithDelay(event, true, 'safe-polygon');\n }\n });\n const handler = handlerRef.current;\n doc.addEventListener('mousemove', handler);\n unbindMouseMoveRef.current = () => {\n doc.removeEventListener('mousemove', handler);\n };\n return;\n }\n\n // Allow interactivity without `safePolygon` on touch devices. With a\n // pointer, a short close delay is an alternative, so it should work\n // consistently.\n const shouldClose = pointerTypeRef.current === 'touch' ? !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(elements.floating, event.relatedTarget) : true;\n if (shouldClose) {\n closeWithDelay(event);\n }\n }\n\n // Ensure the floating element closes after scrolling even if the pointer\n // did not move.\n // https://github.com/floating-ui/floating-ui/discussions/1692\n function onScrollMouseLeave(event) {\n if (isClickLikeOpenEvent()) return;\n if (!dataRef.current.floatingContext) return;\n handleCloseRef.current == null || handleCloseRef.current({\n ...dataRef.current.floatingContext,\n tree,\n x: event.clientX,\n y: event.clientY,\n onClose() {\n clearPointerEvents();\n cleanupMouseMoveHandler();\n closeWithDelay(event);\n }\n })(event);\n }\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(elements.domReference)) {\n var _elements$floating;\n const ref = elements.domReference;\n open && ref.addEventListener('mouseleave', onScrollMouseLeave);\n (_elements$floating = elements.floating) == null || _elements$floating.addEventListener('mouseleave', onScrollMouseLeave);\n move && ref.addEventListener('mousemove', onMouseEnter, {\n once: true\n });\n ref.addEventListener('mouseenter', onMouseEnter);\n ref.addEventListener('mouseleave', onMouseLeave);\n return () => {\n var _elements$floating2;\n open && ref.removeEventListener('mouseleave', onScrollMouseLeave);\n (_elements$floating2 = elements.floating) == null || _elements$floating2.removeEventListener('mouseleave', onScrollMouseLeave);\n move && ref.removeEventListener('mousemove', onMouseEnter);\n ref.removeEventListener('mouseenter', onMouseEnter);\n ref.removeEventListener('mouseleave', onMouseLeave);\n };\n }\n }, [elements, enabled, context, mouseOnly, restMs, move, closeWithDelay, cleanupMouseMoveHandler, clearPointerEvents, onOpenChange, open, openRef, tree, delayRef, handleCloseRef, dataRef]);\n\n // Block pointer-events of every element other than the reference and floating\n // while the floating element is open and has a `handleClose` handler. Also\n // handles nested floating elements.\n // https://github.com/floating-ui/floating-ui/issues/1722\n index(() => {\n var _handleCloseRef$curre;\n if (!enabled) return;\n if (open && (_handleCloseRef$curre = handleCloseRef.current) != null && _handleCloseRef$curre.__options.blockPointerEvents && isHoverOpen()) {\n performedPointerEventsMutationRef.current = true;\n const floatingEl = elements.floating;\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(elements.domReference) && floatingEl) {\n var _tree$nodesRef$curren;\n const body = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating).body;\n body.setAttribute(safePolygonIdentifier, '');\n const ref = elements.domReference;\n const parentFloating = tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ? void 0 : _tree$nodesRef$curren.elements.floating;\n if (parentFloating) {\n parentFloating.style.pointerEvents = '';\n }\n body.style.pointerEvents = 'none';\n ref.style.pointerEvents = 'auto';\n floatingEl.style.pointerEvents = 'auto';\n return () => {\n body.style.pointerEvents = '';\n ref.style.pointerEvents = '';\n floatingEl.style.pointerEvents = '';\n };\n }\n }\n }, [enabled, open, parentId, elements, tree, handleCloseRef, isHoverOpen]);\n index(() => {\n if (!open) {\n pointerTypeRef.current = undefined;\n cleanupMouseMoveHandler();\n clearPointerEvents();\n }\n }, [open, cleanupMouseMoveHandler, clearPointerEvents]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n return () => {\n cleanupMouseMoveHandler();\n clearTimeout(timeoutRef.current);\n clearTimeout(restTimeoutRef.current);\n clearPointerEvents();\n };\n }, [enabled, elements.domReference, cleanupMouseMoveHandler, clearPointerEvents]);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n function setPointerRef(event) {\n pointerTypeRef.current = event.pointerType;\n }\n return {\n onPointerDown: setPointerRef,\n onPointerEnter: setPointerRef,\n onMouseMove(event) {\n const {\n nativeEvent\n } = event;\n function handleMouseMove() {\n if (!blockMouseMoveRef.current && !openRef.current) {\n onOpenChange(true, nativeEvent, 'hover');\n }\n }\n if (mouseOnly && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerTypeRef.current)) {\n return;\n }\n if (open || restMs === 0) {\n return;\n }\n clearTimeout(restTimeoutRef.current);\n if (pointerTypeRef.current === 'touch') {\n handleMouseMove();\n } else {\n restTimeoutRef.current = window.setTimeout(handleMouseMove, restMs);\n }\n }\n };\n }, [mouseOnly, onOpenChange, open, openRef, restMs]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onMouseEnter() {\n clearTimeout(timeoutRef.current);\n },\n onMouseLeave(event) {\n closeWithDelay(event.nativeEvent, false);\n }\n }), [closeWithDelay]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nconst NOOP = () => {};\nconst FloatingDelayGroupContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext({\n delay: 0,\n initialDelay: 0,\n timeoutMs: 0,\n currentId: null,\n setCurrentId: NOOP,\n setState: NOOP,\n isInstantPhase: false\n});\n\n/**\n * @deprecated\n * Use the return value of `useDelayGroup()` instead.\n */\nconst useDelayGroupContext = () => react__WEBPACK_IMPORTED_MODULE_0__.useContext(FloatingDelayGroupContext);\n/**\n * Provides context for a group of floating elements that should share a\n * `delay`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction FloatingDelayGroup(props) {\n const {\n children,\n delay,\n timeoutMs = 0\n } = props;\n const [state, setState] = react__WEBPACK_IMPORTED_MODULE_0__.useReducer((prev, next) => ({\n ...prev,\n ...next\n }), {\n delay,\n timeoutMs,\n initialDelay: delay,\n currentId: null,\n isInstantPhase: false\n });\n const initialCurrentIdRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const setCurrentId = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(currentId => {\n setState({\n currentId\n });\n }, []);\n index(() => {\n if (state.currentId) {\n if (initialCurrentIdRef.current === null) {\n initialCurrentIdRef.current = state.currentId;\n } else if (!state.isInstantPhase) {\n setState({\n isInstantPhase: true\n });\n }\n } else {\n if (state.isInstantPhase) {\n setState({\n isInstantPhase: false\n });\n }\n initialCurrentIdRef.current = null;\n }\n }, [state.currentId, state.isInstantPhase]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FloatingDelayGroupContext.Provider, {\n value: react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n ...state,\n setState,\n setCurrentId\n }), [state, setCurrentId])\n }, children);\n}\n/**\n * Enables grouping when called inside a component that's a child of a\n * `FloatingDelayGroup`.\n * @see https://floating-ui.com/docs/FloatingDelayGroup\n */\nfunction useDelayGroup(context, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n open,\n onOpenChange,\n floatingId\n } = context;\n const {\n id: optionId\n } = options;\n const id = optionId != null ? optionId : floatingId;\n const groupContext = useDelayGroupContext();\n const {\n currentId,\n setCurrentId,\n initialDelay,\n setState,\n timeoutMs\n } = groupContext;\n index(() => {\n if (!currentId) return;\n setState({\n delay: {\n open: 1,\n close: getDelay(initialDelay, 'close')\n }\n });\n if (currentId !== id) {\n onOpenChange(false);\n }\n }, [id, onOpenChange, setState, currentId, initialDelay]);\n index(() => {\n function unset() {\n onOpenChange(false);\n setState({\n delay: initialDelay,\n currentId: null\n });\n }\n if (!currentId) return;\n if (!open && currentId === id) {\n if (timeoutMs) {\n const timeout = window.setTimeout(unset, timeoutMs);\n return () => {\n clearTimeout(timeout);\n };\n }\n unset();\n }\n }, [open, setState, currentId, id, onOpenChange, initialDelay, timeoutMs]);\n index(() => {\n if (setCurrentId === NOOP || !open) return;\n setCurrentId(id);\n }, [open, setCurrentId, id]);\n return groupContext;\n}\n\nfunction getAncestors(nodes, id) {\n var _nodes$find;\n let allAncestors = [];\n let currentParentId = (_nodes$find = nodes.find(node => node.id === id)) == null ? void 0 : _nodes$find.parentId;\n while (currentParentId) {\n const currentNode = nodes.find(node => node.id === currentParentId);\n currentParentId = currentNode == null ? void 0 : currentNode.parentId;\n if (currentNode) {\n allAncestors = allAncestors.concat(currentNode);\n }\n }\n return allAncestors;\n}\n\nfunction getChildren(nodes, id) {\n let allChildren = nodes.filter(node => {\n var _node$context;\n return node.parentId === id && ((_node$context = node.context) == null ? void 0 : _node$context.open);\n });\n let currentChildren = allChildren;\n while (currentChildren.length) {\n currentChildren = nodes.filter(node => {\n var _currentChildren;\n return (_currentChildren = currentChildren) == null ? void 0 : _currentChildren.some(n => {\n var _node$context2;\n return node.parentId === n.id && ((_node$context2 = node.context) == null ? void 0 : _node$context2.open);\n });\n });\n allChildren = allChildren.concat(currentChildren);\n }\n return allChildren;\n}\nfunction getDeepestNode(nodes, id) {\n let deepestNodeId;\n let maxDepth = -1;\n function findDeepest(nodeId, depth) {\n if (depth > maxDepth) {\n deepestNodeId = nodeId;\n maxDepth = depth;\n }\n const children = getChildren(nodes, nodeId);\n children.forEach(child => {\n findDeepest(child.id, depth + 1);\n });\n }\n findDeepest(id, 0);\n return nodes.find(node => node.id === deepestNodeId);\n}\n\n// Modified to add conditional `aria-hidden` support:\n// https://github.com/theKashey/aria-hidden/blob/9220c8f4a4fd35f63bee5510a9f41a37264382d4/src/index.ts\nlet counterMap = /*#__PURE__*/new WeakMap();\nlet uncontrolledElementsSet = /*#__PURE__*/new WeakSet();\nlet markerMap = {};\nlet lockCount = 0;\nconst supportsInert = () => typeof HTMLElement !== 'undefined' && 'inert' in HTMLElement.prototype;\nconst unwrapHost = node => node && (node.host || unwrapHost(node.parentNode));\nconst correctElements = (parent, targets) => targets.map(target => {\n if (parent.contains(target)) {\n return target;\n }\n const correctedTarget = unwrapHost(target);\n if (parent.contains(correctedTarget)) {\n return correctedTarget;\n }\n return null;\n}).filter(x => x != null);\nfunction applyAttributeToOthers(uncorrectedAvoidElements, body, ariaHidden, inert) {\n const markerName = 'data-floating-ui-inert';\n const controlAttribute = inert ? 'inert' : ariaHidden ? 'aria-hidden' : null;\n const avoidElements = correctElements(body, uncorrectedAvoidElements);\n const elementsToKeep = new Set();\n const elementsToStop = new Set(avoidElements);\n const hiddenElements = [];\n if (!markerMap[markerName]) {\n markerMap[markerName] = new WeakMap();\n }\n const markerCounter = markerMap[markerName];\n avoidElements.forEach(keep);\n deep(body);\n elementsToKeep.clear();\n function keep(el) {\n if (!el || elementsToKeep.has(el)) {\n return;\n }\n elementsToKeep.add(el);\n el.parentNode && keep(el.parentNode);\n }\n function deep(parent) {\n if (!parent || elementsToStop.has(parent)) {\n return;\n }\n [].forEach.call(parent.children, node => {\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getNodeName)(node) === 'script') return;\n if (elementsToKeep.has(node)) {\n deep(node);\n } else {\n const attr = controlAttribute ? node.getAttribute(controlAttribute) : null;\n const alreadyHidden = attr !== null && attr !== 'false';\n const counterValue = (counterMap.get(node) || 0) + 1;\n const markerValue = (markerCounter.get(node) || 0) + 1;\n counterMap.set(node, counterValue);\n markerCounter.set(node, markerValue);\n hiddenElements.push(node);\n if (counterValue === 1 && alreadyHidden) {\n uncontrolledElementsSet.add(node);\n }\n if (markerValue === 1) {\n node.setAttribute(markerName, '');\n }\n if (!alreadyHidden && controlAttribute) {\n node.setAttribute(controlAttribute, 'true');\n }\n }\n });\n }\n lockCount++;\n return () => {\n hiddenElements.forEach(element => {\n const counterValue = (counterMap.get(element) || 0) - 1;\n const markerValue = (markerCounter.get(element) || 0) - 1;\n counterMap.set(element, counterValue);\n markerCounter.set(element, markerValue);\n if (!counterValue) {\n if (!uncontrolledElementsSet.has(element) && controlAttribute) {\n element.removeAttribute(controlAttribute);\n }\n uncontrolledElementsSet.delete(element);\n }\n if (!markerValue) {\n element.removeAttribute(markerName);\n }\n });\n lockCount--;\n if (!lockCount) {\n counterMap = new WeakMap();\n counterMap = new WeakMap();\n uncontrolledElementsSet = new WeakSet();\n markerMap = {};\n }\n };\n}\nfunction markOthers(avoidElements, ariaHidden, inert) {\n if (ariaHidden === void 0) {\n ariaHidden = false;\n }\n if (inert === void 0) {\n inert = false;\n }\n const body = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(avoidElements[0]).body;\n return applyAttributeToOthers(avoidElements.concat(Array.from(body.querySelectorAll('[aria-live]'))), body, ariaHidden, inert);\n}\n\nconst getTabbableOptions = () => ({\n getShadowRoot: true,\n displayCheck:\n // JSDOM does not support the `tabbable` library. To solve this we can\n // check if `ResizeObserver` is a real function (not polyfilled), which\n // determines if the current environment is JSDOM-like.\n typeof ResizeObserver === 'function' && ResizeObserver.toString().includes('[native code]') ? 'full' : 'none'\n});\nfunction getTabbableIn(container, direction) {\n const allTabbable = (0,tabbable__WEBPACK_IMPORTED_MODULE_7__.tabbable)(container, getTabbableOptions());\n if (direction === 'prev') {\n allTabbable.reverse();\n }\n const activeIndex = allTabbable.indexOf((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(container)));\n const nextTabbableElements = allTabbable.slice(activeIndex + 1);\n return nextTabbableElements[0];\n}\nfunction getNextTabbable() {\n return getTabbableIn(document.body, 'next');\n}\nfunction getPreviousTabbable() {\n return getTabbableIn(document.body, 'prev');\n}\nfunction isOutsideEvent(event, container) {\n const containerElement = container || event.currentTarget;\n const relatedTarget = event.relatedTarget;\n return !relatedTarget || !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(containerElement, relatedTarget);\n}\nfunction disableFocusInside(container) {\n const tabbableElements = (0,tabbable__WEBPACK_IMPORTED_MODULE_7__.tabbable)(container, getTabbableOptions());\n tabbableElements.forEach(element => {\n element.dataset.tabindex = element.getAttribute('tabindex') || '';\n element.setAttribute('tabindex', '-1');\n });\n}\nfunction enableFocusInside(container) {\n const elements = container.querySelectorAll('[data-tabindex]');\n elements.forEach(element => {\n const tabindex = element.dataset.tabindex;\n delete element.dataset.tabindex;\n if (tabindex) {\n element.setAttribute('tabindex', tabindex);\n } else {\n element.removeAttribute('tabindex');\n }\n });\n}\nfunction getClosestTabbableElement(tabbableElements, element, floating) {\n const elementIndex = tabbableElements.indexOf(element);\n function traverseTabbableElements(next) {\n const attr = createAttribute('focus-guard');\n let index = elementIndex + (next ? 1 : 0);\n let currentElement = tabbableElements[index];\n while (currentElement && (!currentElement.isConnected || currentElement.hasAttribute(attr) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floating, currentElement))) {\n if (next) {\n index++;\n } else {\n index--;\n }\n currentElement = tabbableElements[index];\n }\n return currentElement;\n }\n\n // First, try to find the next tabbable element\n const next = traverseTabbableElements(true);\n if (next) {\n return next;\n }\n\n // If we can't find a next tabbable element, try to find the previous one\n return traverseTabbableElements(false);\n}\n\n// See Diego Haz's Sandbox for making this logic work well on Safari/iOS:\n// https://codesandbox.io/s/tabbable-portal-f4tng?file=/src/FocusTrap.tsx\n\nconst HIDDEN_STYLES = {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'fixed',\n whiteSpace: 'nowrap',\n width: '1px',\n top: 0,\n left: 0\n};\nlet timeoutId;\nfunction setActiveElementOnTab(event) {\n if (event.key === 'Tab') {\n event.target;\n clearTimeout(timeoutId);\n }\n}\nconst FocusGuard = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function FocusGuard(props, ref) {\n const [role, setRole] = react__WEBPACK_IMPORTED_MODULE_0__.useState();\n index(() => {\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isSafari)()) {\n // Unlike other screen readers such as NVDA and JAWS, the virtual cursor\n // on VoiceOver does trigger the onFocus event, so we can use the focus\n // trap element. On Safari, only buttons trigger the onFocus event.\n // NB: \"group\" role in the Sandbox no longer appears to work, must be a\n // button role.\n setRole('button');\n }\n document.addEventListener('keydown', setActiveElementOnTab);\n return () => {\n document.removeEventListener('keydown', setActiveElementOnTab);\n };\n }, []);\n const restProps = {\n ref,\n tabIndex: 0,\n // Role is only for VoiceOver\n role,\n 'aria-hidden': role ? undefined : true,\n [createAttribute('focus-guard')]: '',\n style: HIDDEN_STYLES\n };\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", _extends({}, props, restProps));\n});\n\nconst PortalContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);\nconst attr = /*#__PURE__*/createAttribute('portal');\n/**\n * @see https://floating-ui.com/docs/FloatingPortal#usefloatingportalnode\n */\nfunction useFloatingPortalNode(props) {\n if (props === void 0) {\n props = {};\n }\n const {\n id,\n root\n } = props;\n const uniqueId = useId();\n const portalContext = usePortalContext();\n const [portalNode, setPortalNode] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const portalNodeRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n index(() => {\n return () => {\n portalNode == null || portalNode.remove();\n // Allow the subsequent layout effects to create a new node on updates.\n // The portal node will still be cleaned up on unmount.\n // https://github.com/floating-ui/floating-ui/issues/2454\n queueMicrotask(() => {\n portalNodeRef.current = null;\n });\n };\n }, [portalNode]);\n index(() => {\n // Wait for the uniqueId to be generated before creating the portal node in\n // React <18 (using `useFloatingId` instead of the native `useId`).\n // https://github.com/floating-ui/floating-ui/issues/2778\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n const existingIdRoot = id ? document.getElementById(id) : null;\n if (!existingIdRoot) return;\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n existingIdRoot.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, uniqueId]);\n index(() => {\n if (!uniqueId) return;\n if (portalNodeRef.current) return;\n let container = root || (portalContext == null ? void 0 : portalContext.portalNode);\n if (container && !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(container)) container = container.current;\n container = container || document.body;\n let idWrapper = null;\n if (id) {\n idWrapper = document.createElement('div');\n idWrapper.id = id;\n container.appendChild(idWrapper);\n }\n const subRoot = document.createElement('div');\n subRoot.id = uniqueId;\n subRoot.setAttribute(attr, '');\n container = idWrapper || container;\n container.appendChild(subRoot);\n portalNodeRef.current = subRoot;\n setPortalNode(subRoot);\n }, [id, root, uniqueId, portalContext]);\n return portalNode;\n}\n/**\n * Portals the floating element into a given container element — by default,\n * outside of the app root and into the body.\n * This is necessary to ensure the floating element can appear outside any\n * potential parent containers that cause clipping (such as `overflow: hidden`),\n * while retaining its location in the React tree.\n * @see https://floating-ui.com/docs/FloatingPortal\n */\nfunction FloatingPortal(props) {\n const {\n children,\n id,\n root = null,\n preserveTabOrder = true\n } = props;\n const portalNode = useFloatingPortalNode({\n id,\n root\n });\n const [focusManagerState, setFocusManagerState] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const beforeOutsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const afterOutsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const beforeInsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const afterInsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const modal = focusManagerState == null ? void 0 : focusManagerState.modal;\n const open = focusManagerState == null ? void 0 : focusManagerState.open;\n const shouldRenderGuards =\n // The FocusManager and therefore floating element are currently open/\n // rendered.\n !!focusManagerState &&\n // Guards are only for non-modal focus management.\n !focusManagerState.modal &&\n // Don't render if unmount is transitioning.\n focusManagerState.open && preserveTabOrder && !!(root || portalNode);\n\n // https://codesandbox.io/s/tabbable-portal-f4tng?file=/src/TabbablePortal.tsx\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!portalNode || !preserveTabOrder || modal) {\n return;\n }\n\n // Make sure elements inside the portal element are tabbable only when the\n // portal has already been focused, either by tabbing into a focus trap\n // element outside or using the mouse.\n function onFocus(event) {\n if (portalNode && isOutsideEvent(event)) {\n const focusing = event.type === 'focusin';\n const manageFocus = focusing ? enableFocusInside : disableFocusInside;\n manageFocus(portalNode);\n }\n }\n // Listen to the event on the capture phase so they run before the focus\n // trap elements onFocus prop is called.\n portalNode.addEventListener('focusin', onFocus, true);\n portalNode.addEventListener('focusout', onFocus, true);\n return () => {\n portalNode.removeEventListener('focusin', onFocus, true);\n portalNode.removeEventListener('focusout', onFocus, true);\n };\n }, [portalNode, preserveTabOrder, modal]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!portalNode) return;\n if (open) return;\n enableFocusInside(portalNode);\n }, [open, portalNode]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(PortalContext.Provider, {\n value: react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n preserveTabOrder,\n beforeOutsideRef,\n afterOutsideRef,\n beforeInsideRef,\n afterInsideRef,\n portalNode,\n setFocusManagerState\n }), [preserveTabOrder, portalNode])\n }, shouldRenderGuards && portalNode && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FocusGuard, {\n \"data-type\": \"outside\",\n ref: beforeOutsideRef,\n onFocus: event => {\n if (isOutsideEvent(event, portalNode)) {\n var _beforeInsideRef$curr;\n (_beforeInsideRef$curr = beforeInsideRef.current) == null || _beforeInsideRef$curr.focus();\n } else {\n const prevTabbable = getPreviousTabbable() || (focusManagerState == null ? void 0 : focusManagerState.refs.domReference.current);\n prevTabbable == null || prevTabbable.focus();\n }\n }\n }), shouldRenderGuards && portalNode && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"span\", {\n \"aria-owns\": portalNode.id,\n style: HIDDEN_STYLES\n }), portalNode && /*#__PURE__*/react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(children, portalNode), shouldRenderGuards && portalNode && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FocusGuard, {\n \"data-type\": \"outside\",\n ref: afterOutsideRef,\n onFocus: event => {\n if (isOutsideEvent(event, portalNode)) {\n var _afterInsideRef$curre;\n (_afterInsideRef$curre = afterInsideRef.current) == null || _afterInsideRef$curre.focus();\n } else {\n const nextTabbable = getNextTabbable() || (focusManagerState == null ? void 0 : focusManagerState.refs.domReference.current);\n nextTabbable == null || nextTabbable.focus();\n (focusManagerState == null ? void 0 : focusManagerState.closeOnFocusOut) && (focusManagerState == null ? void 0 : focusManagerState.onOpenChange(false, event.nativeEvent, 'focus-out'));\n }\n }\n }));\n}\nconst usePortalContext = () => react__WEBPACK_IMPORTED_MODULE_0__.useContext(PortalContext);\n\nconst FOCUSABLE_ATTRIBUTE = 'data-floating-ui-focusable';\nfunction getFloatingFocusElement(floatingElement) {\n if (!floatingElement) {\n return null;\n }\n // Try to find the element that has `{...getFloatingProps()}` spread on it.\n // This indicates the floating element is acting as a positioning wrapper, and\n // so focus should be managed on the child element with the event handlers and\n // aria props.\n return floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE) ? floatingElement : floatingElement.querySelector(\"[\" + FOCUSABLE_ATTRIBUTE + \"]\") || floatingElement;\n}\n\nconst LIST_LIMIT = 20;\nlet previouslyFocusedElements = [];\nfunction addPreviouslyFocusedElement(element) {\n previouslyFocusedElements = previouslyFocusedElements.filter(el => el.isConnected);\n let tabbableEl = element;\n if (!tabbableEl || (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getNodeName)(tabbableEl) === 'body') return;\n if (!(0,tabbable__WEBPACK_IMPORTED_MODULE_7__.isTabbable)(tabbableEl, getTabbableOptions())) {\n const tabbableChild = (0,tabbable__WEBPACK_IMPORTED_MODULE_7__.tabbable)(tabbableEl, getTabbableOptions())[0];\n if (tabbableChild) {\n tabbableEl = tabbableChild;\n }\n }\n previouslyFocusedElements.push(tabbableEl);\n if (previouslyFocusedElements.length > LIST_LIMIT) {\n previouslyFocusedElements = previouslyFocusedElements.slice(-LIST_LIMIT);\n }\n}\nfunction getPreviouslyFocusedElement() {\n return previouslyFocusedElements.slice().reverse().find(el => el.isConnected);\n}\nconst VisuallyHiddenDismiss = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function VisuallyHiddenDismiss(props, ref) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", _extends({}, props, {\n type: \"button\",\n ref: ref,\n tabIndex: -1,\n style: HIDDEN_STYLES\n }));\n});\n/**\n * Provides focus management for the floating element.\n * @see https://floating-ui.com/docs/FloatingFocusManager\n */\nfunction FloatingFocusManager(props) {\n const {\n context,\n children,\n disabled = false,\n order = ['content'],\n guards: _guards = true,\n initialFocus = 0,\n returnFocus = true,\n restoreFocus = false,\n modal = true,\n visuallyHiddenDismiss = false,\n closeOnFocusOut = true\n } = props;\n const {\n open,\n refs,\n nodeId,\n onOpenChange,\n events,\n dataRef,\n floatingId,\n elements: {\n domReference,\n floating\n }\n } = context;\n const ignoreInitialFocus = typeof initialFocus === 'number' && initialFocus < 0;\n // If the reference is a combobox and is typeable (e.g. input/textarea),\n // there are different focus semantics. The guards should not be rendered, but\n // aria-hidden should be applied to all nodes still. Further, the visually\n // hidden dismiss button should only appear at the end of the list, not the\n // start.\n const isUntrappedTypeableCombobox = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isTypeableCombobox)(domReference) && ignoreInitialFocus;\n\n // Force the guards to be rendered if the `inert` attribute is not supported.\n const guards = supportsInert() ? _guards : true;\n const orderRef = useLatestRef(order);\n const initialFocusRef = useLatestRef(initialFocus);\n const returnFocusRef = useLatestRef(returnFocus);\n const tree = useFloatingTree();\n const portalContext = usePortalContext();\n const startDismissButtonRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const endDismissButtonRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const preventReturnFocusRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const isPointerDownRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const tabbableIndexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(-1);\n const isInsidePortal = portalContext != null;\n const floatingFocusElement = getFloatingFocusElement(floating);\n const getTabbableContent = useEffectEvent(function (container) {\n if (container === void 0) {\n container = floatingFocusElement;\n }\n return container ? (0,tabbable__WEBPACK_IMPORTED_MODULE_7__.tabbable)(container, getTabbableOptions()) : [];\n });\n const getTabbableElements = useEffectEvent(container => {\n const content = getTabbableContent(container);\n return orderRef.current.map(type => {\n if (domReference && type === 'reference') {\n return domReference;\n }\n if (floatingFocusElement && type === 'floating') {\n return floatingFocusElement;\n }\n return content;\n }).filter(Boolean).flat();\n });\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n preventReturnFocusRef.current = false;\n }, [disabled]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (disabled) return;\n if (!modal) return;\n function onKeyDown(event) {\n if (event.key === 'Tab') {\n // The focus guards have nothing to focus, so we need to stop the event.\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floatingFocusElement, (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement))) && getTabbableContent().length === 0 && !isUntrappedTypeableCombobox) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n }\n const els = getTabbableElements();\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event);\n if (orderRef.current[0] === 'reference' && target === domReference) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n if (event.shiftKey) {\n enqueueFocus(els[els.length - 1]);\n } else {\n enqueueFocus(els[1]);\n }\n }\n if (orderRef.current[1] === 'floating' && target === floatingFocusElement && event.shiftKey) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n enqueueFocus(els[0]);\n }\n }\n }\n const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement);\n doc.addEventListener('keydown', onKeyDown);\n return () => {\n doc.removeEventListener('keydown', onKeyDown);\n };\n }, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (disabled) return;\n if (!floating) return;\n function handleFocusIn(event) {\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event);\n const tabbableContent = getTabbableContent();\n const tabbableIndex = tabbableContent.indexOf(target);\n if (tabbableIndex !== -1) {\n tabbableIndexRef.current = tabbableIndex;\n }\n }\n floating.addEventListener('focusin', handleFocusIn);\n return () => {\n floating.removeEventListener('focusin', handleFocusIn);\n };\n }, [disabled, floating, getTabbableContent]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (disabled) return;\n if (!closeOnFocusOut) return;\n\n // In Safari, buttons lose focus when pressing them.\n function handlePointerDown() {\n isPointerDownRef.current = true;\n setTimeout(() => {\n isPointerDownRef.current = false;\n });\n }\n function handleFocusOutside(event) {\n const relatedTarget = event.relatedTarget;\n queueMicrotask(() => {\n const movedToUnrelatedNode = !((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(domReference, relatedTarget) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floating, relatedTarget) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(relatedTarget, floating) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(portalContext == null ? void 0 : portalContext.portalNode, relatedTarget) || relatedTarget != null && relatedTarget.hasAttribute(createAttribute('focus-guard')) || tree && (getChildren(tree.nodesRef.current, nodeId).find(node => {\n var _node$context, _node$context2;\n return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)((_node$context = node.context) == null ? void 0 : _node$context.elements.floating, relatedTarget) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)((_node$context2 = node.context) == null ? void 0 : _node$context2.elements.domReference, relatedTarget);\n }) || getAncestors(tree.nodesRef.current, nodeId).find(node => {\n var _node$context3, _node$context4;\n return ((_node$context3 = node.context) == null ? void 0 : _node$context3.elements.floating) === relatedTarget || ((_node$context4 = node.context) == null ? void 0 : _node$context4.elements.domReference) === relatedTarget;\n })));\n\n // Restore focus to the previous tabbable element index to prevent\n // focus from being lost outside the floating tree.\n if (restoreFocus && movedToUnrelatedNode && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement)) === (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement).body) {\n // Let `FloatingPortal` effect knows that focus is still inside the\n // floating tree.\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(floatingFocusElement)) {\n floatingFocusElement.focus();\n }\n const prevTabbableIndex = tabbableIndexRef.current;\n const tabbableContent = getTabbableContent();\n const nodeToFocus = tabbableContent[prevTabbableIndex] || tabbableContent[tabbableContent.length - 1] || floatingFocusElement;\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(nodeToFocus)) {\n nodeToFocus.focus();\n }\n }\n\n // Focus did not move inside the floating tree, and there are no tabbable\n // portal guards to handle closing.\n if ((isUntrappedTypeableCombobox ? true : !modal) && relatedTarget && movedToUnrelatedNode && !isPointerDownRef.current &&\n // Fix React 18 Strict Mode returnFocus due to double rendering.\n relatedTarget !== getPreviouslyFocusedElement()) {\n preventReturnFocusRef.current = true;\n onOpenChange(false, event, 'focus-out');\n }\n });\n }\n if (floating && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(domReference)) {\n domReference.addEventListener('focusout', handleFocusOutside);\n domReference.addEventListener('pointerdown', handlePointerDown);\n floating.addEventListener('focusout', handleFocusOutside);\n return () => {\n domReference.removeEventListener('focusout', handleFocusOutside);\n domReference.removeEventListener('pointerdown', handlePointerDown);\n floating.removeEventListener('focusout', handleFocusOutside);\n };\n }\n }, [disabled, domReference, floating, floatingFocusElement, modal, nodeId, tree, portalContext, onOpenChange, closeOnFocusOut, restoreFocus, getTabbableContent, isUntrappedTypeableCombobox]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n var _portalContext$portal;\n if (disabled) return;\n\n // Don't hide portals nested within the parent portal.\n const portalNodes = Array.from((portalContext == null || (_portalContext$portal = portalContext.portalNode) == null ? void 0 : _portalContext$portal.querySelectorAll(\"[\" + createAttribute('portal') + \"]\")) || []);\n if (floating) {\n const insideElements = [floating, ...portalNodes, startDismissButtonRef.current, endDismissButtonRef.current, orderRef.current.includes('reference') || isUntrappedTypeableCombobox ? domReference : null].filter(x => x != null);\n const cleanup = modal || isUntrappedTypeableCombobox ? markOthers(insideElements, guards, !guards) : markOthers(insideElements);\n return () => {\n cleanup();\n };\n }\n }, [disabled, domReference, floating, modal, orderRef, portalContext, isUntrappedTypeableCombobox, guards]);\n index(() => {\n if (disabled || !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(floatingFocusElement)) return;\n const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)(doc);\n\n // Wait for any layout effect state setters to execute to set `tabIndex`.\n queueMicrotask(() => {\n const focusableElements = getTabbableElements(floatingFocusElement);\n const initialFocusValue = initialFocusRef.current;\n const elToFocus = (typeof initialFocusValue === 'number' ? focusableElements[initialFocusValue] : initialFocusValue.current) || floatingFocusElement;\n const focusAlreadyInsideFloatingEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floatingFocusElement, previouslyFocusedElement);\n if (!ignoreInitialFocus && !focusAlreadyInsideFloatingEl && open) {\n enqueueFocus(elToFocus, {\n preventScroll: elToFocus === floatingFocusElement\n });\n }\n });\n }, [disabled, open, floatingFocusElement, ignoreInitialFocus, getTabbableElements, initialFocusRef]);\n index(() => {\n if (disabled || !floatingFocusElement) return;\n let preventReturnFocusScroll = false;\n const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floatingFocusElement);\n const previouslyFocusedElement = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)(doc);\n const contextData = dataRef.current;\n let openEvent = contextData.openEvent;\n const domReference = refs.domReference.current;\n addPreviouslyFocusedElement(previouslyFocusedElement);\n\n // Dismissing via outside press should always ignore `returnFocus` to\n // prevent unwanted scrolling.\n function onOpenChange(_ref) {\n let {\n open,\n reason,\n event,\n nested\n } = _ref;\n if (open) {\n openEvent = event;\n }\n if (reason === 'escape-key' && refs.domReference.current) {\n addPreviouslyFocusedElement(refs.domReference.current);\n }\n if (reason === 'hover' && event.type === 'mouseleave') {\n preventReturnFocusRef.current = true;\n }\n if (reason !== 'outside-press') return;\n if (nested) {\n preventReturnFocusRef.current = false;\n preventReturnFocusScroll = true;\n } else {\n preventReturnFocusRef.current = !((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isVirtualClick)(event) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isVirtualPointerEvent)(event));\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)(doc);\n const isFocusInsideFloatingTree = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floating, activeEl) || tree && getChildren(tree.nodesRef.current, nodeId).some(node => {\n var _node$context5;\n return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)((_node$context5 = node.context) == null ? void 0 : _node$context5.elements.floating, activeEl);\n });\n const shouldFocusReference = isFocusInsideFloatingTree || openEvent && ['click', 'mousedown'].includes(openEvent.type);\n if (shouldFocusReference && refs.domReference.current) {\n addPreviouslyFocusedElement(refs.domReference.current);\n }\n const returnContextElement = domReference || previouslyFocusedElement;\n const tabbableElements = (0,tabbable__WEBPACK_IMPORTED_MODULE_7__.tabbable)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(returnContextElement).body, getTabbableOptions());\n\n // Wait for the return element to get potentially disconnected before\n // checking.\n queueMicrotask(() => {\n let returnElement = getPreviouslyFocusedElement();\n if (!returnElement && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(returnContextElement) && floating) {\n returnElement = getClosestTabbableElement(tabbableElements, returnContextElement, floating);\n }\n if (\n // eslint-disable-next-line react-hooks/exhaustive-deps\n returnFocusRef.current && !preventReturnFocusRef.current && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(returnElement) && (\n // If the focus moved somewhere else after mount, avoid returning focus\n // since it likely entered a different element which should be\n // respected: https://github.com/floating-ui/floating-ui/issues/2607\n returnElement !== activeEl && activeEl !== doc.body ? isFocusInsideFloatingTree : true)) {\n returnElement.focus({\n preventScroll: preventReturnFocusScroll\n });\n }\n });\n };\n }, [disabled, floating, floatingFocusElement, returnFocusRef, dataRef, refs, events, tree, nodeId]);\n\n // Synchronize the `context` & `modal` value to the FloatingPortal context.\n // It will decide whether or not it needs to render its own guards.\n index(() => {\n if (disabled) return;\n if (!portalContext) return;\n portalContext.setFocusManagerState({\n modal,\n closeOnFocusOut,\n open,\n onOpenChange,\n refs\n });\n return () => {\n portalContext.setFocusManagerState(null);\n };\n }, [disabled, portalContext, modal, open, onOpenChange, refs, closeOnFocusOut]);\n index(() => {\n if (disabled) return;\n if (!floatingFocusElement) return;\n if (typeof MutationObserver !== 'function') return;\n if (ignoreInitialFocus) return;\n const handleMutation = () => {\n const tabIndex = floatingFocusElement.getAttribute('tabindex');\n const tabbableContent = getTabbableContent();\n const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(floating));\n const tabbableIndex = tabbableContent.indexOf(activeEl);\n if (tabbableIndex !== -1) {\n tabbableIndexRef.current = tabbableIndex;\n }\n if (orderRef.current.includes('floating') || activeEl !== refs.domReference.current && tabbableContent.length === 0) {\n if (tabIndex !== '0') {\n floatingFocusElement.setAttribute('tabindex', '0');\n }\n } else if (tabIndex !== '-1') {\n floatingFocusElement.setAttribute('tabindex', '-1');\n }\n };\n handleMutation();\n const observer = new MutationObserver(handleMutation);\n observer.observe(floatingFocusElement, {\n childList: true,\n subtree: true,\n attributes: true\n });\n return () => {\n observer.disconnect();\n };\n }, [disabled, floating, floatingFocusElement, refs, orderRef, getTabbableContent, ignoreInitialFocus]);\n function renderDismissButton(location) {\n if (disabled || !visuallyHiddenDismiss || !modal) {\n return null;\n }\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(VisuallyHiddenDismiss, {\n ref: location === 'start' ? startDismissButtonRef : endDismissButtonRef,\n onClick: event => onOpenChange(false, event.nativeEvent)\n }, typeof visuallyHiddenDismiss === 'string' ? visuallyHiddenDismiss : 'Dismiss');\n }\n const shouldRenderGuards = !disabled && guards && (modal ? !isUntrappedTypeableCombobox : true) && (isInsidePortal || modal);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, shouldRenderGuards && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FocusGuard, {\n \"data-type\": \"inside\",\n ref: portalContext == null ? void 0 : portalContext.beforeInsideRef,\n onFocus: event => {\n if (modal) {\n const els = getTabbableElements();\n enqueueFocus(order[0] === 'reference' ? els[0] : els[els.length - 1]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n preventReturnFocusRef.current = false;\n if (isOutsideEvent(event, portalContext.portalNode)) {\n const nextTabbable = getNextTabbable() || domReference;\n nextTabbable == null || nextTabbable.focus();\n } else {\n var _portalContext$before;\n (_portalContext$before = portalContext.beforeOutsideRef.current) == null || _portalContext$before.focus();\n }\n }\n }\n }), !isUntrappedTypeableCombobox && renderDismissButton('start'), children, renderDismissButton('end'), shouldRenderGuards && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(FocusGuard, {\n \"data-type\": \"inside\",\n ref: portalContext == null ? void 0 : portalContext.afterInsideRef,\n onFocus: event => {\n if (modal) {\n enqueueFocus(getTabbableElements()[0]);\n } else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {\n if (closeOnFocusOut) {\n preventReturnFocusRef.current = true;\n }\n if (isOutsideEvent(event, portalContext.portalNode)) {\n const prevTabbable = getPreviousTabbable() || domReference;\n prevTabbable == null || prevTabbable.focus();\n } else {\n var _portalContext$afterO;\n (_portalContext$afterO = portalContext.afterOutsideRef.current) == null || _portalContext$afterO.focus();\n }\n }\n }\n }));\n}\n\nconst activeLocks = /*#__PURE__*/new Set();\n/**\n * Provides base styling for a fixed overlay element to dim content or block\n * pointer events behind a floating element.\n * It's a regular ``, so it can be styled via any CSS solution you prefer.\n * @see https://floating-ui.com/docs/FloatingOverlay\n */\nconst FloatingOverlay = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function FloatingOverlay(props, ref) {\n const {\n lockScroll = false,\n ...rest\n } = props;\n const lockId = useId();\n index(() => {\n if (!lockScroll) return;\n activeLocks.add(lockId);\n const isIOS = /iP(hone|ad|od)|iOS/.test((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getPlatform)());\n const bodyStyle = document.body.style;\n // RTL scrollbar\n const scrollbarX = Math.round(document.documentElement.getBoundingClientRect().left) + document.documentElement.scrollLeft;\n const paddingProp = scrollbarX ? 'paddingLeft' : 'paddingRight';\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n const scrollX = bodyStyle.left ? parseFloat(bodyStyle.left) : window.scrollX;\n const scrollY = bodyStyle.top ? parseFloat(bodyStyle.top) : window.scrollY;\n bodyStyle.overflow = 'hidden';\n if (scrollbarWidth) {\n bodyStyle[paddingProp] = scrollbarWidth + \"px\";\n }\n\n // Only iOS doesn't respect `overflow: hidden` on document.body, and this\n // technique has fewer side effects.\n if (isIOS) {\n var _window$visualViewpor, _window$visualViewpor2;\n // iOS 12 does not support `visualViewport`.\n const offsetLeft = ((_window$visualViewpor = window.visualViewport) == null ? void 0 : _window$visualViewpor.offsetLeft) || 0;\n const offsetTop = ((_window$visualViewpor2 = window.visualViewport) == null ? void 0 : _window$visualViewpor2.offsetTop) || 0;\n Object.assign(bodyStyle, {\n position: 'fixed',\n top: -(scrollY - Math.floor(offsetTop)) + \"px\",\n left: -(scrollX - Math.floor(offsetLeft)) + \"px\",\n right: '0'\n });\n }\n return () => {\n activeLocks.delete(lockId);\n if (activeLocks.size === 0) {\n Object.assign(bodyStyle, {\n overflow: '',\n [paddingProp]: ''\n });\n if (isIOS) {\n Object.assign(bodyStyle, {\n position: '',\n top: '',\n left: '',\n right: ''\n });\n window.scrollTo(scrollX, scrollY);\n }\n }\n };\n }, [lockId, lockScroll]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", _extends({\n ref: ref\n }, rest, {\n style: {\n position: 'fixed',\n overflow: 'auto',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...rest.style\n }\n }));\n});\n\nfunction isButtonTarget(event) {\n return (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(event.target) && event.target.tagName === 'BUTTON';\n}\nfunction isSpaceIgnored(element) {\n return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isTypeableElement)(element);\n}\n/**\n * Opens or closes the floating element when clicking the reference element.\n * @see https://floating-ui.com/docs/useClick\n */\nfunction useClick(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n dataRef,\n elements: {\n domReference\n }\n } = context;\n const {\n enabled = true,\n event: eventOption = 'click',\n toggle = true,\n ignoreMouse = false,\n keyboardHandlers = true\n } = props;\n const pointerTypeRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();\n const didKeyDownRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onPointerDown(event) {\n pointerTypeRef.current = event.pointerType;\n },\n onMouseDown(event) {\n const pointerType = pointerTypeRef.current;\n\n // Ignore all buttons except for the \"main\" button.\n // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\n if (event.button !== 0) return;\n if (eventOption === 'click') return;\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent ? dataRef.current.openEvent.type === 'mousedown' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n // Prevent stealing focus from the floating element\n event.preventDefault();\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onClick(event) {\n const pointerType = pointerTypeRef.current;\n if (eventOption === 'mousedown' && pointerTypeRef.current) {\n pointerTypeRef.current = undefined;\n return;\n }\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;\n if (open && toggle && (dataRef.current.openEvent ? dataRef.current.openEvent.type === 'click' : true)) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n },\n onKeyDown(event) {\n pointerTypeRef.current = undefined;\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event)) {\n return;\n }\n if (event.key === ' ' && !isSpaceIgnored(domReference)) {\n // Prevent scrolling\n event.preventDefault();\n didKeyDownRef.current = true;\n }\n if (event.key === 'Enter') {\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n },\n onKeyUp(event) {\n if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event) || isSpaceIgnored(domReference)) {\n return;\n }\n if (event.key === ' ' && didKeyDownRef.current) {\n didKeyDownRef.current = false;\n if (open && toggle) {\n onOpenChange(false, event.nativeEvent, 'click');\n } else {\n onOpenChange(true, event.nativeEvent, 'click');\n }\n }\n }\n }), [dataRef, domReference, eventOption, ignoreMouse, keyboardHandlers, onOpenChange, open, toggle]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nfunction createVirtualElement(domElement, data) {\n let offsetX = null;\n let offsetY = null;\n let isAutoUpdateEvent = false;\n return {\n contextElement: domElement || undefined,\n getBoundingClientRect() {\n var _data$dataRef$current;\n const domRect = (domElement == null ? void 0 : domElement.getBoundingClientRect()) || {\n width: 0,\n height: 0,\n x: 0,\n y: 0\n };\n const isXAxis = data.axis === 'x' || data.axis === 'both';\n const isYAxis = data.axis === 'y' || data.axis === 'both';\n const canTrackCursorOnAutoUpdate = ['mouseenter', 'mousemove'].includes(((_data$dataRef$current = data.dataRef.current.openEvent) == null ? void 0 : _data$dataRef$current.type) || '') && data.pointerType !== 'touch';\n let width = domRect.width;\n let height = domRect.height;\n let x = domRect.x;\n let y = domRect.y;\n if (offsetX == null && data.x && isXAxis) {\n offsetX = domRect.x - data.x;\n }\n if (offsetY == null && data.y && isYAxis) {\n offsetY = domRect.y - data.y;\n }\n x -= offsetX || 0;\n y -= offsetY || 0;\n width = 0;\n height = 0;\n if (!isAutoUpdateEvent || canTrackCursorOnAutoUpdate) {\n width = data.axis === 'y' ? domRect.width : 0;\n height = data.axis === 'x' ? domRect.height : 0;\n x = isXAxis && data.x != null ? data.x : x;\n y = isYAxis && data.y != null ? data.y : y;\n } else if (isAutoUpdateEvent && !canTrackCursorOnAutoUpdate) {\n height = data.axis === 'x' ? domRect.height : height;\n width = data.axis === 'y' ? domRect.width : width;\n }\n isAutoUpdateEvent = true;\n return {\n width,\n height,\n x,\n y,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x\n };\n }\n };\n}\nfunction isMouseBasedEvent(event) {\n return event != null && event.clientX != null;\n}\n/**\n * Positions the floating element relative to a client point (in the viewport),\n * such as the mouse position. By default, it follows the mouse cursor.\n * @see https://floating-ui.com/docs/useClientPoint\n */\nfunction useClientPoint(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n dataRef,\n elements: {\n floating,\n domReference\n },\n refs\n } = context;\n const {\n enabled = true,\n axis = 'both',\n x = null,\n y = null\n } = props;\n const initialRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const cleanupListenerRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const [pointerType, setPointerType] = react__WEBPACK_IMPORTED_MODULE_0__.useState();\n const [reactive, setReactive] = react__WEBPACK_IMPORTED_MODULE_0__.useState([]);\n const setReference = useEffectEvent((x, y) => {\n if (initialRef.current) return;\n\n // Prevent setting if the open event was not a mouse-like one\n // (e.g. focus to open, then hover over the reference element).\n // Only apply if the event exists.\n if (dataRef.current.openEvent && !isMouseBasedEvent(dataRef.current.openEvent)) {\n return;\n }\n refs.setPositionReference(createVirtualElement(domReference, {\n x,\n y,\n axis,\n dataRef,\n pointerType\n }));\n });\n const handleReferenceEnterOrMove = useEffectEvent(event => {\n if (x != null || y != null) return;\n if (!open) {\n setReference(event.clientX, event.clientY);\n } else if (!cleanupListenerRef.current) {\n // If there's no cleanup, there's no listener, but we want to ensure\n // we add the listener if the cursor landed on the floating element and\n // then back on the reference (i.e. it's interactive).\n setReactive([]);\n }\n });\n\n // If the pointer is a mouse-like pointer, we want to continue following the\n // mouse even if the floating element is transitioning out. On touch\n // devices, this is undesirable because the floating element will move to\n // the dismissal touch point.\n const openCheck = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMouseLikePointerType)(pointerType) ? floating : open;\n const addListener = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(() => {\n // Explicitly specified `x`/`y` coordinates shouldn't add a listener.\n if (!openCheck || !enabled || x != null || y != null) return;\n const win = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getWindow)(floating);\n function handleMouseMove(event) {\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event);\n if (!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(floating, target)) {\n setReference(event.clientX, event.clientY);\n } else {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n }\n }\n if (!dataRef.current.openEvent || isMouseBasedEvent(dataRef.current.openEvent)) {\n win.addEventListener('mousemove', handleMouseMove);\n const cleanup = () => {\n win.removeEventListener('mousemove', handleMouseMove);\n cleanupListenerRef.current = null;\n };\n cleanupListenerRef.current = cleanup;\n return cleanup;\n }\n refs.setPositionReference(domReference);\n }, [openCheck, enabled, x, y, floating, dataRef, refs, domReference, setReference]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n return addListener();\n }, [addListener, reactive]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (enabled && !floating) {\n initialRef.current = false;\n }\n }, [enabled, floating]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled && open) {\n initialRef.current = true;\n }\n }, [enabled, open]);\n index(() => {\n if (enabled && (x != null || y != null)) {\n initialRef.current = false;\n setReference(x, y);\n }\n }, [enabled, x, y, setReference]);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n function setPointerTypeRef(_ref) {\n let {\n pointerType\n } = _ref;\n setPointerType(pointerType);\n }\n return {\n onPointerDown: setPointerTypeRef,\n onPointerEnter: setPointerTypeRef,\n onMouseMove: handleReferenceEnterOrMove,\n onMouseEnter: handleReferenceEnterOrMove\n };\n }, [handleReferenceEnterOrMove]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst bubbleHandlerKeys = {\n pointerdown: 'onPointerDown',\n mousedown: 'onMouseDown',\n click: 'onClick'\n};\nconst captureHandlerKeys = {\n pointerdown: 'onPointerDownCapture',\n mousedown: 'onMouseDownCapture',\n click: 'onClickCapture'\n};\nconst normalizeProp = normalizable => {\n var _normalizable$escapeK, _normalizable$outside;\n return {\n escapeKey: typeof normalizable === 'boolean' ? normalizable : (_normalizable$escapeK = normalizable == null ? void 0 : normalizable.escapeKey) != null ? _normalizable$escapeK : false,\n outsidePress: typeof normalizable === 'boolean' ? normalizable : (_normalizable$outside = normalizable == null ? void 0 : normalizable.outsidePress) != null ? _normalizable$outside : true\n };\n};\n/**\n * Closes the floating element when a dismissal is requested — by default, when\n * the user presses the `escape` key or outside of the floating element.\n * @see https://floating-ui.com/docs/useDismiss\n */\nfunction useDismiss(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n elements,\n dataRef\n } = context;\n const {\n enabled = true,\n escapeKey = true,\n outsidePress: unstable_outsidePress = true,\n outsidePressEvent = 'pointerdown',\n referencePress = false,\n referencePressEvent = 'pointerdown',\n ancestorScroll = false,\n bubbles,\n capture\n } = props;\n const tree = useFloatingTree();\n const outsidePressFn = useEffectEvent(typeof unstable_outsidePress === 'function' ? unstable_outsidePress : () => false);\n const outsidePress = typeof unstable_outsidePress === 'function' ? outsidePressFn : unstable_outsidePress;\n const insideReactTreeRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const endedOrStartedInsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const {\n escapeKey: escapeKeyBubbles,\n outsidePress: outsidePressBubbles\n } = normalizeProp(bubbles);\n const {\n escapeKey: escapeKeyCapture,\n outsidePress: outsidePressCapture\n } = normalizeProp(capture);\n const closeOnEscapeKeyDown = useEffectEvent(event => {\n var _dataRef$current$floa;\n if (!open || !enabled || !escapeKey || event.key !== 'Escape') {\n return;\n }\n const nodeId = (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;\n const children = tree ? getChildren(tree.nodesRef.current, nodeId) : [];\n if (!escapeKeyBubbles) {\n event.stopPropagation();\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context;\n if ((_child$context = child.context) != null && _child$context.open && !child.context.dataRef.current.__escapeKeyBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n }\n onOpenChange(false, (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isReactEvent)(event) ? event.nativeEvent : event, 'escape-key');\n });\n const closeOnEscapeKeyDownCapture = useEffectEvent(event => {\n var _getTarget2;\n const callback = () => {\n var _getTarget;\n closeOnEscapeKeyDown(event);\n (_getTarget = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event)) == null || _getTarget.removeEventListener('keydown', callback);\n };\n (_getTarget2 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event)) == null || _getTarget2.addEventListener('keydown', callback);\n });\n const closeOnPressOutside = useEffectEvent(event => {\n var _dataRef$current$floa2;\n // Given developers can stop the propagation of the synthetic event,\n // we can only be confident with a positive value.\n const insideReactTree = insideReactTreeRef.current;\n insideReactTreeRef.current = false;\n\n // When click outside is lazy (`click` event), handle dragging.\n // Don't close if:\n // - The click started inside the floating element.\n // - The click ended inside the floating element.\n const endedOrStartedInside = endedOrStartedInsideRef.current;\n endedOrStartedInsideRef.current = false;\n if (outsidePressEvent === 'click' && endedOrStartedInside) {\n return;\n }\n if (insideReactTree) {\n return;\n }\n if (typeof outsidePress === 'function' && !outsidePress(event)) {\n return;\n }\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event);\n const inertSelector = \"[\" + createAttribute('inert') + \"]\";\n const markers = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating).querySelectorAll(inertSelector);\n let targetRootAncestor = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(target) ? target : null;\n while (targetRootAncestor && !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isLastTraversableNode)(targetRootAncestor)) {\n const nextParent = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getParentNode)(targetRootAncestor);\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isLastTraversableNode)(nextParent) || !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(nextParent)) {\n break;\n }\n targetRootAncestor = nextParent;\n }\n\n // Check if the click occurred on a third-party element injected after the\n // floating element rendered.\n if (markers.length && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(target) && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isRootElement)(target) &&\n // Clicked on a direct ancestor (e.g. FloatingOverlay).\n !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(target, elements.floating) &&\n // If the target root element contains none of the markers, then the\n // element was injected after the floating element rendered.\n Array.from(markers).every(marker => !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(targetRootAncestor, marker))) {\n return;\n }\n\n // Check if the click occurred on the scrollbar\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(target) && floating) {\n // In Firefox, `target.scrollWidth > target.clientWidth` for inline\n // elements.\n const canScrollX = target.clientWidth > 0 && target.scrollWidth > target.clientWidth;\n const canScrollY = target.clientHeight > 0 && target.scrollHeight > target.clientHeight;\n let xCond = canScrollY && event.offsetX > target.clientWidth;\n\n // In some browsers it is possible to change the (or window)\n // scrollbar to the left side, but is very rare and is difficult to\n // check for. Plus, for modal dialogs with backdrops, it is more\n // important that the backdrop is checked but not so much the window.\n if (canScrollY) {\n const isRTL = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getComputedStyle)(target).direction === 'rtl';\n if (isRTL) {\n xCond = event.offsetX <= target.offsetWidth - target.clientWidth;\n }\n }\n if (xCond || canScrollX && event.offsetY > target.clientHeight) {\n return;\n }\n }\n const nodeId = (_dataRef$current$floa2 = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa2.nodeId;\n const targetIsInsideChildren = tree && getChildren(tree.nodesRef.current, nodeId).some(node => {\n var _node$context;\n return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isEventTargetWithin)(event, (_node$context = node.context) == null ? void 0 : _node$context.elements.floating);\n });\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isEventTargetWithin)(event, elements.floating) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isEventTargetWithin)(event, elements.domReference) || targetIsInsideChildren) {\n return;\n }\n const children = tree ? getChildren(tree.nodesRef.current, nodeId) : [];\n if (children.length > 0) {\n let shouldDismiss = true;\n children.forEach(child => {\n var _child$context2;\n if ((_child$context2 = child.context) != null && _child$context2.open && !child.context.dataRef.current.__outsidePressBubbles) {\n shouldDismiss = false;\n return;\n }\n });\n if (!shouldDismiss) {\n return;\n }\n }\n onOpenChange(false, event, 'outside-press');\n });\n const closeOnPressOutsideCapture = useEffectEvent(event => {\n var _getTarget4;\n const callback = () => {\n var _getTarget3;\n closeOnPressOutside(event);\n (_getTarget3 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event)) == null || _getTarget3.removeEventListener(outsidePressEvent, callback);\n };\n (_getTarget4 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event)) == null || _getTarget4.addEventListener(outsidePressEvent, callback);\n });\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!open || !enabled) {\n return;\n }\n dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;\n dataRef.current.__outsidePressBubbles = outsidePressBubbles;\n function onScroll(event) {\n onOpenChange(false, event, 'ancestor-scroll');\n }\n const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating);\n escapeKey && doc.addEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n let ancestors = [];\n if (ancestorScroll) {\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(elements.domReference)) {\n ancestors = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getOverflowAncestors)(elements.domReference);\n }\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(elements.floating)) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getOverflowAncestors)(elements.floating));\n }\n if (!(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(elements.reference) && elements.reference && elements.reference.contextElement) {\n ancestors = ancestors.concat((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getOverflowAncestors)(elements.reference.contextElement));\n }\n }\n\n // Ignore the visual viewport for scrolling dismissal (allow pinch-zoom)\n ancestors = ancestors.filter(ancestor => {\n var _doc$defaultView;\n return ancestor !== ((_doc$defaultView = doc.defaultView) == null ? void 0 : _doc$defaultView.visualViewport);\n });\n ancestors.forEach(ancestor => {\n ancestor.addEventListener('scroll', onScroll, {\n passive: true\n });\n });\n return () => {\n escapeKey && doc.removeEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);\n outsidePress && doc.removeEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);\n ancestors.forEach(ancestor => {\n ancestor.removeEventListener('scroll', onScroll);\n });\n };\n }, [dataRef, elements, escapeKey, outsidePress, outsidePressEvent, open, onOpenChange, ancestorScroll, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, escapeKeyCapture, closeOnEscapeKeyDownCapture, closeOnPressOutside, outsidePressCapture, closeOnPressOutsideCapture]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n insideReactTreeRef.current = false;\n }, [outsidePress, outsidePressEvent]);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n [bubbleHandlerKeys[referencePressEvent]]: event => {\n if (referencePress) {\n onOpenChange(false, event.nativeEvent, 'reference-press');\n }\n }\n }), [closeOnEscapeKeyDown, onOpenChange, referencePress, referencePressEvent]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onKeyDown: closeOnEscapeKeyDown,\n onMouseDown() {\n endedOrStartedInsideRef.current = true;\n },\n onMouseUp() {\n endedOrStartedInsideRef.current = true;\n },\n [captureHandlerKeys[outsidePressEvent]]: () => {\n insideReactTreeRef.current = true;\n }\n }), [closeOnEscapeKeyDown, outsidePressEvent]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction useFloatingRootContext(options) {\n const {\n open = false,\n onOpenChange: onOpenChangeProp,\n elements: elementsProp\n } = options;\n const floatingId = useId();\n const dataRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef({});\n const [events] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => createPubSub());\n const nested = useFloatingParentNodeId() != null;\n if (true) {\n const optionDomReference = elementsProp.reference;\n if (optionDomReference && !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(optionDomReference)) {\n error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.');\n }\n }\n const [positionReference, setPositionReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(elementsProp.reference);\n const onOpenChange = useEffectEvent((open, event, reason) => {\n dataRef.current.openEvent = open ? event : undefined;\n events.emit('openchange', {\n open,\n event,\n reason,\n nested\n });\n onOpenChangeProp == null || onOpenChangeProp(open, event, reason);\n });\n const refs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n setPositionReference\n }), []);\n const elements = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n reference: positionReference || elementsProp.reference || null,\n floating: elementsProp.floating || null,\n domReference: elementsProp.reference\n }), [positionReference, elementsProp.reference, elementsProp.floating]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n dataRef,\n open,\n onOpenChange,\n elements,\n events,\n floatingId,\n refs\n }), [open, onOpenChange, elements, events, floatingId, refs]);\n}\n\n/**\n * Provides data to position a floating element and context to add interactions.\n * @see https://floating-ui.com/docs/useFloating\n */\nfunction useFloating(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n nodeId\n } = options;\n const internalRootContext = useFloatingRootContext({\n ...options,\n elements: {\n reference: null,\n floating: null,\n ...options.elements\n }\n });\n const rootContext = options.rootContext || internalRootContext;\n const computedElements = rootContext.elements;\n const [_domReference, setDomReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [positionReference, _setPositionReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const optionDomReference = computedElements == null ? void 0 : computedElements.reference;\n const domReference = optionDomReference || _domReference;\n const domReferenceRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const tree = useFloatingTree();\n index(() => {\n if (domReference) {\n domReferenceRef.current = domReference;\n }\n }, [domReference]);\n const position = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_2__.useFloating)({\n ...options,\n elements: {\n ...computedElements,\n ...(positionReference && {\n reference: positionReference\n })\n }\n });\n const setPositionReference = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {\n const computedPositionReference = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(node) ? {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n contextElement: node\n } : node;\n // Store the positionReference in state if the DOM reference is specified externally via the\n // `elements.reference` option. This ensures that it won't be overridden on future renders.\n _setPositionReference(computedPositionReference);\n position.refs.setReference(computedPositionReference);\n }, [position.refs]);\n const setReference = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(node) || node === null) {\n domReferenceRef.current = node;\n setDomReference(node);\n }\n\n // Backwards-compatibility for passing a virtual element to `reference`\n // after it has set the DOM reference.\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(position.refs.reference.current) || position.refs.reference.current === null ||\n // Don't allow setting virtual elements using the old technique back to\n // `null` to support `positionReference` + an unstable `reference`\n // callback ref.\n node !== null && !(0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(node)) {\n position.refs.setReference(node);\n }\n }, [position.refs]);\n const refs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n ...position.refs,\n setReference,\n setPositionReference,\n domReference: domReferenceRef\n }), [position.refs, setReference, setPositionReference]);\n const elements = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n ...position.elements,\n domReference: domReference\n }), [position.elements, domReference]);\n const context = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n ...position,\n ...rootContext,\n refs,\n elements,\n nodeId\n }), [position, refs, elements, nodeId, rootContext]);\n index(() => {\n rootContext.dataRef.current.floatingContext = context;\n const node = tree == null ? void 0 : tree.nodesRef.current.find(node => node.id === nodeId);\n if (node) {\n node.context = context;\n }\n });\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n ...position,\n context,\n refs,\n elements\n }), [position, refs, elements, context]);\n}\n\n/**\n * Opens the floating element while the reference element has focus, like CSS\n * `:focus`.\n * @see https://floating-ui.com/docs/useFocus\n */\nfunction useFocus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n onOpenChange,\n events,\n dataRef,\n elements\n } = context;\n const {\n enabled = true,\n visibleOnly = true\n } = props;\n const blockFocusRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const timeoutRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();\n const keyboardModalityRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(true);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n const win = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.getWindow)(elements.domReference);\n\n // If the reference was focused and the user left the tab/window, and the\n // floating element was not open, the focus should be blocked when they\n // return to the tab/window.\n function onBlur() {\n if (!open && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(elements.domReference) && elements.domReference === (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.domReference))) {\n blockFocusRef.current = true;\n }\n }\n function onKeyDown() {\n keyboardModalityRef.current = true;\n }\n win.addEventListener('blur', onBlur);\n win.addEventListener('keydown', onKeyDown, true);\n return () => {\n win.removeEventListener('blur', onBlur);\n win.removeEventListener('keydown', onKeyDown, true);\n };\n }, [elements.domReference, open, enabled]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n function onOpenChange(_ref) {\n let {\n reason\n } = _ref;\n if (reason === 'reference-press' || reason === 'escape-key') {\n blockFocusRef.current = true;\n }\n }\n events.on('openchange', onOpenChange);\n return () => {\n events.off('openchange', onOpenChange);\n };\n }, [events, enabled]);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n return () => {\n clearTimeout(timeoutRef.current);\n };\n }, []);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onPointerDown(event) {\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isVirtualPointerEvent)(event.nativeEvent)) return;\n keyboardModalityRef.current = false;\n },\n onMouseLeave() {\n blockFocusRef.current = false;\n },\n onFocus(event) {\n if (blockFocusRef.current) return;\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event.nativeEvent);\n if (visibleOnly && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(target)) {\n try {\n // Mac Safari unreliably matches `:focus-visible` on the reference\n // if focus was outside the page initially - use the fallback\n // instead.\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isSafari)() && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMac)()) throw Error();\n if (!target.matches(':focus-visible')) return;\n } catch (e) {\n // Old browsers will throw an error when using `:focus-visible`.\n if (!keyboardModalityRef.current && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isTypeableElement)(target)) {\n return;\n }\n }\n }\n onOpenChange(true, event.nativeEvent, 'focus');\n },\n onBlur(event) {\n blockFocusRef.current = false;\n const relatedTarget = event.relatedTarget;\n const nativeEvent = event.nativeEvent;\n\n // Hit the non-modal focus management portal guard. Focus will be\n // moved into the floating element immediately after.\n const movedToFocusGuard = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';\n\n // Wait for the window blur listener to fire.\n timeoutRef.current = window.setTimeout(() => {\n var _dataRef$current$floa;\n const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)(elements.domReference ? elements.domReference.ownerDocument : document);\n\n // Focus left the page, keep it open.\n if (!relatedTarget && activeEl === elements.domReference) return;\n\n // When focusing the reference element (e.g. regular click), then\n // clicking into the floating element, prevent it from hiding.\n // Note: it must be focusable, e.g. `tabindex=\"-1\"`.\n // We can not rely on relatedTarget to point to the correct element\n // as it will only point to the shadow host of the newly focused element\n // and not the element that actually has received focus if it is located\n // inside a shadow root.\n if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)((_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.refs.floating.current, activeEl) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(elements.domReference, activeEl) || movedToFocusGuard) {\n return;\n }\n onOpenChange(false, nativeEvent, 'focus');\n });\n }\n }), [dataRef, elements.domReference, onOpenChange, visibleOnly]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference\n } : {}, [enabled, reference]);\n}\n\nconst ACTIVE_KEY = 'active';\nconst SELECTED_KEY = 'selected';\nfunction mergeProps(userProps, propsList, elementKey) {\n const map = new Map();\n const isItem = elementKey === 'item';\n let domUserProps = userProps;\n if (isItem && userProps) {\n const {\n [ACTIVE_KEY]: _,\n [SELECTED_KEY]: __,\n ...validProps\n } = userProps;\n domUserProps = validProps;\n }\n return {\n ...(elementKey === 'floating' && {\n tabIndex: -1,\n [FOCUSABLE_ATTRIBUTE]: ''\n }),\n ...domUserProps,\n ...propsList.map(value => {\n const propsOrGetProps = value ? value[elementKey] : null;\n if (typeof propsOrGetProps === 'function') {\n return userProps ? propsOrGetProps(userProps) : null;\n }\n return propsOrGetProps;\n }).concat(userProps).reduce((acc, props) => {\n if (!props) {\n return acc;\n }\n Object.entries(props).forEach(_ref => {\n let [key, value] = _ref;\n if (isItem && [ACTIVE_KEY, SELECTED_KEY].includes(key)) {\n return;\n }\n if (key.indexOf('on') === 0) {\n if (!map.has(key)) {\n map.set(key, []);\n }\n if (typeof value === 'function') {\n var _map$get;\n (_map$get = map.get(key)) == null || _map$get.push(value);\n acc[key] = function () {\n var _map$get2;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return (_map$get2 = map.get(key)) == null ? void 0 : _map$get2.map(fn => fn(...args)).find(val => val !== undefined);\n };\n }\n } else {\n acc[key] = value;\n }\n });\n return acc;\n }, {})\n };\n}\n/**\n * Merges an array of interaction hooks' props into prop getters, allowing\n * event handler functions to be composed together without overwriting one\n * another.\n * @see https://floating-ui.com/docs/useInteractions\n */\nfunction useInteractions(propsList) {\n if (propsList === void 0) {\n propsList = [];\n }\n const referenceDeps = propsList.map(key => key == null ? void 0 : key.reference);\n const floatingDeps = propsList.map(key => key == null ? void 0 : key.floating);\n const itemDeps = propsList.map(key => key == null ? void 0 : key.item);\n const getReferenceProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'reference'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n referenceDeps);\n const getFloatingProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'floating'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n floatingDeps);\n const getItemProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'item'),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n itemDeps);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n getReferenceProps,\n getFloatingProps,\n getItemProps\n }), [getReferenceProps, getFloatingProps, getItemProps]);\n}\n\nlet isPreventScrollSupported = false;\nfunction doSwitch(orientation, vertical, horizontal) {\n switch (orientation) {\n case 'vertical':\n return vertical;\n case 'horizontal':\n return horizontal;\n default:\n return vertical || horizontal;\n }\n}\nfunction isMainOrientationKey(key, orientation) {\n const vertical = key === ARROW_UP || key === ARROW_DOWN;\n const horizontal = key === ARROW_LEFT || key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isMainOrientationToEndKey(key, orientation, rtl) {\n const vertical = key === ARROW_DOWN;\n const horizontal = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';\n}\nfunction isCrossOrientationOpenKey(key, orientation, rtl) {\n const vertical = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;\n const horizontal = key === ARROW_DOWN;\n return doSwitch(orientation, vertical, horizontal);\n}\nfunction isCrossOrientationCloseKey(key, orientation, rtl) {\n const vertical = rtl ? key === ARROW_RIGHT : key === ARROW_LEFT;\n const horizontal = key === ARROW_UP;\n return doSwitch(orientation, vertical, horizontal);\n}\n/**\n * Adds arrow key-based navigation of a list of items, either using real DOM\n * focus or virtual focus.\n * @see https://floating-ui.com/docs/useListNavigation\n */\nfunction useListNavigation(context, props) {\n const {\n open,\n onOpenChange,\n elements\n } = context;\n const {\n listRef,\n activeIndex,\n onNavigate: unstable_onNavigate = () => {},\n enabled = true,\n selectedIndex = null,\n allowEscape = false,\n loop = false,\n nested = false,\n rtl = false,\n virtual = false,\n focusItemOnOpen = 'auto',\n focusItemOnHover = true,\n openOnArrowKeyDown = true,\n disabledIndices = undefined,\n orientation = 'vertical',\n cols = 1,\n scrollItemIntoView = true,\n virtualItemRef,\n itemSizes,\n dense = false\n } = props;\n if (true) {\n if (allowEscape) {\n if (!loop) {\n warn('`useListNavigation` looping must be enabled to allow escaping.');\n }\n if (!virtual) {\n warn('`useListNavigation` must be virtual to allow escaping.');\n }\n }\n if (orientation === 'vertical' && cols > 1) {\n warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either \"horizontal\" or \"both\".');\n }\n }\n const floatingFocusElement = getFloatingFocusElement(elements.floating);\n const floatingFocusElementRef = useLatestRef(floatingFocusElement);\n const parentId = useFloatingParentNodeId();\n const tree = useFloatingTree();\n const onNavigate = useEffectEvent(unstable_onNavigate);\n const focusItemOnOpenRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(focusItemOnOpen);\n const indexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(selectedIndex != null ? selectedIndex : -1);\n const keyRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const isPointerModalityRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(true);\n const previousOnNavigateRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(onNavigate);\n const previousMountedRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(!!elements.floating);\n const previousOpenRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(open);\n const forceSyncFocus = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const forceScrollIntoViewRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const disabledIndicesRef = useLatestRef(disabledIndices);\n const latestOpenRef = useLatestRef(open);\n const scrollItemIntoViewRef = useLatestRef(scrollItemIntoView);\n const selectedIndexRef = useLatestRef(selectedIndex);\n const [activeId, setActiveId] = react__WEBPACK_IMPORTED_MODULE_0__.useState();\n const [virtualId, setVirtualId] = react__WEBPACK_IMPORTED_MODULE_0__.useState();\n const focusItem = useEffectEvent(function (listRef, indexRef, forceScrollIntoView) {\n if (forceScrollIntoView === void 0) {\n forceScrollIntoView = false;\n }\n function runFocus(item) {\n if (virtual) {\n setActiveId(item.id);\n tree == null || tree.events.emit('virtualfocus', item);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n } else {\n enqueueFocus(item, {\n preventScroll: true,\n // Mac Safari does not move the virtual cursor unless the focus call\n // is sync. However, for the very first focus call, we need to wait\n // for the position to be ready in order to prevent unwanted\n // scrolling. This means the virtual cursor will not move to the first\n // item when first opening the floating element, but will on\n // subsequent calls. `preventScroll` is supported in modern Safari,\n // so we can use that instead.\n // iOS Safari must be async or the first item will not be focused.\n sync: (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isMac)() && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isSafari)() ? isPreventScrollSupported || forceSyncFocus.current : false\n });\n }\n }\n const initialItem = listRef.current[indexRef.current];\n if (initialItem) {\n runFocus(initialItem);\n }\n requestAnimationFrame(() => {\n const waitedItem = listRef.current[indexRef.current] || initialItem;\n if (!waitedItem) return;\n if (!initialItem) {\n runFocus(waitedItem);\n }\n const scrollIntoViewOptions = scrollItemIntoViewRef.current;\n const shouldScrollIntoView = scrollIntoViewOptions && item && (forceScrollIntoView || !isPointerModalityRef.current);\n if (shouldScrollIntoView) {\n // JSDOM doesn't support `.scrollIntoView()` but it's widely supported\n // by all browsers.\n waitedItem.scrollIntoView == null || waitedItem.scrollIntoView(typeof scrollIntoViewOptions === 'boolean' ? {\n block: 'nearest',\n inline: 'nearest'\n } : scrollIntoViewOptions);\n }\n });\n });\n index(() => {\n document.createElement('div').focus({\n get preventScroll() {\n isPreventScrollSupported = true;\n return false;\n }\n });\n }, []);\n\n // Sync `selectedIndex` to be the `activeIndex` upon opening the floating\n // element. Also, reset `activeIndex` upon closing the floating element.\n index(() => {\n if (!enabled) return;\n if (open && elements.floating) {\n if (focusItemOnOpenRef.current && selectedIndex != null) {\n // Regardless of the pointer modality, we want to ensure the selected\n // item comes into view when the floating element is opened.\n forceScrollIntoViewRef.current = true;\n indexRef.current = selectedIndex;\n onNavigate(selectedIndex);\n }\n } else if (previousMountedRef.current) {\n // Since the user can specify `onNavigate` conditionally\n // (onNavigate: open ? setActiveIndex : setSelectedIndex),\n // we store and call the previous function.\n indexRef.current = -1;\n previousOnNavigateRef.current(null);\n }\n }, [enabled, open, elements.floating, selectedIndex, onNavigate]);\n\n // Sync `activeIndex` to be the focused item while the floating element is\n // open.\n index(() => {\n if (!enabled) return;\n if (open && elements.floating) {\n if (activeIndex == null) {\n forceSyncFocus.current = false;\n if (selectedIndexRef.current != null) {\n return;\n }\n\n // Reset while the floating element was open (e.g. the list changed).\n if (previousMountedRef.current) {\n indexRef.current = -1;\n focusItem(listRef, indexRef);\n }\n\n // Initial sync.\n if ((!previousOpenRef.current || !previousMountedRef.current) && focusItemOnOpenRef.current && (keyRef.current != null || focusItemOnOpenRef.current === true && keyRef.current == null)) {\n let runs = 0;\n const waitForListPopulated = () => {\n if (listRef.current[0] == null) {\n // Avoid letting the browser paint if possible on the first try,\n // otherwise use rAF. Don't try more than twice, since something\n // is wrong otherwise.\n if (runs < 2) {\n const scheduler = runs ? requestAnimationFrame : queueMicrotask;\n scheduler(waitForListPopulated);\n }\n runs++;\n } else {\n indexRef.current = keyRef.current == null || isMainOrientationToEndKey(keyRef.current, orientation, rtl) || nested ? getMinIndex(listRef, disabledIndicesRef.current) : getMaxIndex(listRef, disabledIndicesRef.current);\n keyRef.current = null;\n onNavigate(indexRef.current);\n }\n };\n waitForListPopulated();\n }\n } else if (!isIndexOutOfBounds(listRef, activeIndex)) {\n indexRef.current = activeIndex;\n focusItem(listRef, indexRef, forceScrollIntoViewRef.current);\n forceScrollIntoViewRef.current = false;\n }\n }\n }, [enabled, open, elements.floating, activeIndex, selectedIndexRef, nested, listRef, orientation, rtl, onNavigate, focusItem, disabledIndicesRef]);\n\n // Ensure the parent floating element has focus when a nested child closes\n // to allow arrow key navigation to work after the pointer leaves the child.\n index(() => {\n var _nodes$find;\n if (!enabled || elements.floating || !tree || virtual || !previousMountedRef.current) {\n return;\n }\n const nodes = tree.nodesRef.current;\n const parent = (_nodes$find = nodes.find(node => node.id === parentId)) == null || (_nodes$find = _nodes$find.context) == null ? void 0 : _nodes$find.elements.floating;\n const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getDocument)(elements.floating));\n const treeContainsActiveEl = nodes.some(node => node.context && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(node.context.elements.floating, activeEl));\n if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {\n parent.focus({\n preventScroll: true\n });\n }\n }, [enabled, elements.floating, tree, parentId, virtual]);\n index(() => {\n if (!enabled) return;\n if (!tree) return;\n if (!virtual) return;\n if (parentId) return;\n function handleVirtualFocus(item) {\n setVirtualId(item.id);\n if (virtualItemRef) {\n virtualItemRef.current = item;\n }\n }\n tree.events.on('virtualfocus', handleVirtualFocus);\n return () => {\n tree.events.off('virtualfocus', handleVirtualFocus);\n };\n }, [enabled, tree, virtual, parentId, virtualItemRef]);\n index(() => {\n previousOnNavigateRef.current = onNavigate;\n previousMountedRef.current = !!elements.floating;\n });\n index(() => {\n if (!open) {\n keyRef.current = null;\n }\n }, [open]);\n index(() => {\n previousOpenRef.current = open;\n }, [open]);\n const hasActiveIndex = activeIndex != null;\n const item = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n function syncCurrentTarget(currentTarget) {\n if (!open) return;\n const index = listRef.current.indexOf(currentTarget);\n if (index !== -1) {\n onNavigate(index);\n }\n }\n const props = {\n onFocus(_ref) {\n let {\n currentTarget\n } = _ref;\n syncCurrentTarget(currentTarget);\n },\n onClick: _ref2 => {\n let {\n currentTarget\n } = _ref2;\n return currentTarget.focus({\n preventScroll: true\n });\n },\n // Safari\n ...(focusItemOnHover && {\n onMouseMove(_ref3) {\n let {\n currentTarget\n } = _ref3;\n syncCurrentTarget(currentTarget);\n },\n onPointerLeave(_ref4) {\n let {\n pointerType\n } = _ref4;\n if (!isPointerModalityRef.current || pointerType === 'touch') {\n return;\n }\n indexRef.current = -1;\n focusItem(listRef, indexRef);\n onNavigate(null);\n if (!virtual) {\n enqueueFocus(floatingFocusElementRef.current, {\n preventScroll: true\n });\n }\n }\n })\n };\n return props;\n }, [open, floatingFocusElementRef, focusItem, focusItemOnHover, listRef, onNavigate, virtual]);\n const commonOnKeyDown = useEffectEvent(event => {\n isPointerModalityRef.current = false;\n forceSyncFocus.current = true;\n\n // If the floating element is animating out, ignore navigation. Otherwise,\n // the `activeIndex` gets set to 0 despite not being open so the next time\n // the user ArrowDowns, the first item won't be focused.\n if (!latestOpenRef.current && event.currentTarget === floatingFocusElementRef.current) {\n return;\n }\n if (nested && isCrossOrientationCloseKey(event.key, orientation, rtl)) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n onOpenChange(false, event.nativeEvent, 'list-navigation');\n if ((0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(elements.domReference) && !virtual) {\n elements.domReference.focus();\n }\n return;\n }\n const currentIndex = indexRef.current;\n const minIndex = getMinIndex(listRef, disabledIndices);\n const maxIndex = getMaxIndex(listRef, disabledIndices);\n if (event.key === 'Home') {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n indexRef.current = minIndex;\n onNavigate(indexRef.current);\n }\n if (event.key === 'End') {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n indexRef.current = maxIndex;\n onNavigate(indexRef.current);\n }\n\n // Grid navigation.\n if (cols > 1) {\n const sizes = itemSizes || Array.from({\n length: listRef.current.length\n }, () => ({\n width: 1,\n height: 1\n }));\n // To calculate movements on the grid, we use hypothetical cell indices\n // as if every item was 1x1, then convert back to real indices.\n const cellMap = buildCellMap(sizes, cols, dense);\n const minGridIndex = cellMap.findIndex(index => index != null && !isDisabled(listRef.current, index, disabledIndices));\n // last enabled index\n const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !isDisabled(listRef.current, index, disabledIndices) ? cellIndex : foundIndex, -1);\n const index = cellMap[getGridNavigatedIndex({\n current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)\n }, {\n event,\n orientation,\n loop,\n cols,\n // treat undefined (empty grid spaces) as disabled indices so we\n // don't end up in them\n disabledIndices: getCellIndices([...(disabledIndices || listRef.current.map((_, index) => isDisabled(listRef.current, index) ? index : undefined)), undefined], cellMap),\n minIndex: minGridIndex,\n maxIndex: maxGridIndex,\n prevIndex: getCellIndexOfCorner(indexRef.current > maxIndex ? minIndex : indexRef.current, sizes, cellMap, cols,\n // use a corner matching the edge closest to the direction\n // we're moving in so we don't end up in the same item. Prefer\n // top/left over bottom/right.\n event.key === ARROW_DOWN ? 'bl' : event.key === ARROW_RIGHT ? 'tr' : 'tl'),\n stopEvent: true\n })];\n if (index != null) {\n indexRef.current = index;\n onNavigate(indexRef.current);\n }\n if (orientation === 'both') {\n return;\n }\n }\n if (isMainOrientationKey(event.key, orientation)) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n\n // Reset the index if no item is focused.\n if (open && !virtual && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.activeElement)(event.currentTarget.ownerDocument) === event.currentTarget) {\n indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;\n onNavigate(indexRef.current);\n return;\n }\n if (isMainOrientationToEndKey(event.key, orientation, rtl)) {\n if (loop) {\n indexRef.current = currentIndex >= maxIndex ? allowEscape && currentIndex !== listRef.current.length ? -1 : minIndex : findNonDisabledIndex(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n });\n } else {\n indexRef.current = Math.min(maxIndex, findNonDisabledIndex(listRef, {\n startingIndex: currentIndex,\n disabledIndices\n }));\n }\n } else {\n if (loop) {\n indexRef.current = currentIndex <= minIndex ? allowEscape && currentIndex !== -1 ? listRef.current.length : maxIndex : findNonDisabledIndex(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n });\n } else {\n indexRef.current = Math.max(minIndex, findNonDisabledIndex(listRef, {\n startingIndex: currentIndex,\n decrement: true,\n disabledIndices\n }));\n }\n }\n if (isIndexOutOfBounds(listRef, indexRef.current)) {\n onNavigate(null);\n } else {\n onNavigate(indexRef.current);\n }\n }\n });\n const ariaActiveDescendantProp = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n return virtual && open && hasActiveIndex && {\n 'aria-activedescendant': virtualId || activeId\n };\n }, [virtual, open, hasActiveIndex, virtualId, activeId]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n return {\n 'aria-orientation': orientation === 'both' ? undefined : orientation,\n ...(!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isTypeableCombobox)(elements.domReference) && ariaActiveDescendantProp),\n onKeyDown: commonOnKeyDown,\n onPointerMove() {\n isPointerModalityRef.current = true;\n }\n };\n }, [ariaActiveDescendantProp, commonOnKeyDown, elements.domReference, orientation]);\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n function checkVirtualMouse(event) {\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isVirtualClick)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n function checkVirtualPointer(event) {\n // `pointerdown` fires first, reset the state then perform the checks.\n focusItemOnOpenRef.current = focusItemOnOpen;\n if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.isVirtualPointerEvent)(event.nativeEvent)) {\n focusItemOnOpenRef.current = true;\n }\n }\n return {\n ...ariaActiveDescendantProp,\n onKeyDown(event) {\n isPointerModalityRef.current = false;\n const isArrowKey = event.key.indexOf('Arrow') === 0;\n const isCrossOpenKey = isCrossOrientationOpenKey(event.key, orientation, rtl);\n const isCrossCloseKey = isCrossOrientationCloseKey(event.key, orientation, rtl);\n const isMainKey = isMainOrientationKey(event.key, orientation);\n const isNavigationKey = (nested ? isCrossOpenKey : isMainKey) || event.key === 'Enter' || event.key.trim() === '';\n if (virtual && open) {\n const rootNode = tree == null ? void 0 : tree.nodesRef.current.find(node => node.parentId == null);\n const deepestNode = tree && rootNode ? getDeepestNode(tree.nodesRef.current, rootNode.id) : null;\n if (isArrowKey && deepestNode && virtualItemRef) {\n const eventObject = new KeyboardEvent('keydown', {\n key: event.key,\n bubbles: true\n });\n if (isCrossOpenKey || isCrossCloseKey) {\n var _deepestNode$context, _deepestNode$context2;\n const isCurrentTarget = ((_deepestNode$context = deepestNode.context) == null ? void 0 : _deepestNode$context.elements.domReference) === event.currentTarget;\n const dispatchItem = isCrossCloseKey && !isCurrentTarget ? (_deepestNode$context2 = deepestNode.context) == null ? void 0 : _deepestNode$context2.elements.domReference : isCrossOpenKey ? listRef.current.find(item => (item == null ? void 0 : item.id) === activeId) : null;\n if (dispatchItem) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n dispatchItem.dispatchEvent(eventObject);\n setVirtualId(undefined);\n }\n }\n if (isMainKey && deepestNode.context) {\n if (deepestNode.context.open && deepestNode.parentId && event.currentTarget !== deepestNode.context.elements.domReference) {\n var _deepestNode$context$;\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n (_deepestNode$context$ = deepestNode.context.elements.domReference) == null || _deepestNode$context$.dispatchEvent(eventObject);\n return;\n }\n }\n }\n return commonOnKeyDown(event);\n }\n\n // If a floating element should not open on arrow key down, avoid\n // setting `activeIndex` while it's closed.\n if (!open && !openOnArrowKeyDown && isArrowKey) {\n return;\n }\n if (isNavigationKey) {\n keyRef.current = nested && isMainKey ? null : event.key;\n }\n if (nested) {\n if (isCrossOpenKey) {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n if (open) {\n indexRef.current = getMinIndex(listRef, disabledIndicesRef.current);\n onNavigate(indexRef.current);\n } else {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n }\n }\n return;\n }\n if (isMainKey) {\n if (selectedIndex != null) {\n indexRef.current = selectedIndex;\n }\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n if (!open && openOnArrowKeyDown) {\n onOpenChange(true, event.nativeEvent, 'list-navigation');\n } else {\n commonOnKeyDown(event);\n }\n if (open) {\n onNavigate(indexRef.current);\n }\n }\n },\n onFocus() {\n if (open && !virtual) {\n onNavigate(null);\n }\n },\n onPointerDown: checkVirtualPointer,\n onMouseDown: checkVirtualMouse,\n onClick: checkVirtualMouse\n };\n }, [activeId, ariaActiveDescendantProp, commonOnKeyDown, disabledIndicesRef, focusItemOnOpen, listRef, nested, onNavigate, onOpenChange, open, openOnArrowKeyDown, orientation, rtl, selectedIndex, tree, virtual, virtualItemRef]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\nconst componentRoleToAriaRoleMap = /*#__PURE__*/new Map([['select', 'listbox'], ['combobox', 'listbox'], ['label', false]]);\n\n/**\n * Adds base screen reader props to the reference and floating elements for a\n * given floating element `role`.\n * @see https://floating-ui.com/docs/useRole\n */\nfunction useRole(context, props) {\n var _componentRoleToAriaR;\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n floatingId\n } = context;\n const {\n enabled = true,\n role = 'dialog'\n } = props;\n const ariaRole = (_componentRoleToAriaR = componentRoleToAriaRoleMap.get(role)) != null ? _componentRoleToAriaR : role;\n const referenceId = useId();\n const parentId = useFloatingParentNodeId();\n const isNested = parentId != null;\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n if (ariaRole === 'tooltip' || role === 'label') {\n return {\n [\"aria-\" + (role === 'label' ? 'labelledby' : 'describedby')]: open ? floatingId : undefined\n };\n }\n return {\n 'aria-expanded': open ? 'true' : 'false',\n 'aria-haspopup': ariaRole === 'alertdialog' ? 'dialog' : ariaRole,\n 'aria-controls': open ? floatingId : undefined,\n ...(ariaRole === 'listbox' && {\n role: 'combobox'\n }),\n ...(ariaRole === 'menu' && {\n id: referenceId\n }),\n ...(ariaRole === 'menu' && isNested && {\n role: 'menuitem'\n }),\n ...(role === 'select' && {\n 'aria-autocomplete': 'none'\n }),\n ...(role === 'combobox' && {\n 'aria-autocomplete': 'list'\n })\n };\n }, [ariaRole, floatingId, isNested, open, referenceId, role]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n const floatingProps = {\n id: floatingId,\n ...(ariaRole && {\n role: ariaRole\n })\n };\n if (ariaRole === 'tooltip' || role === 'label') {\n return floatingProps;\n }\n return {\n ...floatingProps,\n ...(ariaRole === 'menu' && {\n 'aria-labelledby': referenceId\n })\n };\n }, [ariaRole, floatingId, referenceId, role]);\n const item = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(_ref => {\n let {\n active,\n selected\n } = _ref;\n const commonProps = {\n role: 'option',\n ...(active && {\n id: floatingId + \"-option\"\n })\n };\n\n // For `menu`, we are unable to tell if the item is a `menuitemradio`\n // or `menuitemcheckbox`. For backwards-compatibility reasons, also\n // avoid defaulting to `menuitem` as it may overwrite custom role props.\n switch (role) {\n case 'select':\n return {\n ...commonProps,\n 'aria-selected': active && selected\n };\n case 'combobox':\n {\n return {\n ...commonProps,\n ...(active && {\n 'aria-selected': true\n })\n };\n }\n }\n return {};\n }, [floatingId, role]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference,\n floating,\n item\n } : {}, [enabled, reference, floating, item]);\n}\n\n// Converts a JS style key like `backgroundColor` to a CSS transition-property\n// like `background-color`.\nconst camelCaseToKebabCase = str => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());\nfunction execWithArgsOrReturn(valueOrFn, args) {\n return typeof valueOrFn === 'function' ? valueOrFn(args) : valueOrFn;\n}\nfunction useDelayUnmount(open, durationMs) {\n const [isMounted, setIsMounted] = react__WEBPACK_IMPORTED_MODULE_0__.useState(open);\n if (open && !isMounted) {\n setIsMounted(true);\n }\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!open && isMounted) {\n const timeout = setTimeout(() => setIsMounted(false), durationMs);\n return () => clearTimeout(timeout);\n }\n }, [open, isMounted, durationMs]);\n return isMounted;\n}\n/**\n * Provides a status string to apply CSS transitions to a floating element,\n * correctly handling placement-aware transitions.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstatus\n */\nfunction useTransitionStatus(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n open,\n elements: {\n floating\n }\n } = context;\n const {\n duration = 250\n } = props;\n const isNumberDuration = typeof duration === 'number';\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [status, setStatus] = react__WEBPACK_IMPORTED_MODULE_0__.useState('unmounted');\n const isMounted = useDelayUnmount(open, closeDuration);\n if (!isMounted && status === 'close') {\n setStatus('unmounted');\n }\n index(() => {\n if (!floating) return;\n if (open) {\n setStatus('initial');\n const frame = requestAnimationFrame(() => {\n setStatus('open');\n });\n return () => {\n cancelAnimationFrame(frame);\n };\n }\n setStatus('close');\n }, [open, floating]);\n return {\n isMounted,\n status\n };\n}\n/**\n * Provides styles to apply CSS transitions to a floating element, correctly\n * handling placement-aware transitions. Wrapper around `useTransitionStatus`.\n * @see https://floating-ui.com/docs/useTransition#usetransitionstyles\n */\nfunction useTransitionStyles(context, props) {\n if (props === void 0) {\n props = {};\n }\n const {\n initial: unstable_initial = {\n opacity: 0\n },\n open: unstable_open,\n close: unstable_close,\n common: unstable_common,\n duration = 250\n } = props;\n const placement = context.placement;\n const side = placement.split('-')[0];\n const fnArgs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n side,\n placement\n }), [side, placement]);\n const isNumberDuration = typeof duration === 'number';\n const openDuration = (isNumberDuration ? duration : duration.open) || 0;\n const closeDuration = (isNumberDuration ? duration : duration.close) || 0;\n const [styles, setStyles] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => ({\n ...execWithArgsOrReturn(unstable_common, fnArgs),\n ...execWithArgsOrReturn(unstable_initial, fnArgs)\n }));\n const {\n isMounted,\n status\n } = useTransitionStatus(context, {\n duration\n });\n const initialRef = useLatestRef(unstable_initial);\n const openRef = useLatestRef(unstable_open);\n const closeRef = useLatestRef(unstable_close);\n const commonRef = useLatestRef(unstable_common);\n index(() => {\n const initialStyles = execWithArgsOrReturn(initialRef.current, fnArgs);\n const closeStyles = execWithArgsOrReturn(closeRef.current, fnArgs);\n const commonStyles = execWithArgsOrReturn(commonRef.current, fnArgs);\n const openStyles = execWithArgsOrReturn(openRef.current, fnArgs) || Object.keys(initialStyles).reduce((acc, key) => {\n acc[key] = '';\n return acc;\n }, {});\n if (status === 'initial') {\n setStyles(styles => ({\n transitionProperty: styles.transitionProperty,\n ...commonStyles,\n ...initialStyles\n }));\n }\n if (status === 'open') {\n setStyles({\n transitionProperty: Object.keys(openStyles).map(camelCaseToKebabCase).join(','),\n transitionDuration: openDuration + \"ms\",\n ...commonStyles,\n ...openStyles\n });\n }\n if (status === 'close') {\n const styles = closeStyles || initialStyles;\n setStyles({\n transitionProperty: Object.keys(styles).map(camelCaseToKebabCase).join(','),\n transitionDuration: closeDuration + \"ms\",\n ...commonStyles,\n ...styles\n });\n }\n }, [closeDuration, closeRef, initialRef, openRef, commonRef, openDuration, status, fnArgs]);\n return {\n isMounted,\n styles\n };\n}\n\n/**\n * Provides a matching callback that can be used to focus an item as the user\n * types, often used in tandem with `useListNavigation()`.\n * @see https://floating-ui.com/docs/useTypeahead\n */\nfunction useTypeahead(context, props) {\n var _ref;\n const {\n open,\n dataRef\n } = context;\n const {\n listRef,\n activeIndex,\n onMatch: unstable_onMatch,\n onTypingChange: unstable_onTypingChange,\n enabled = true,\n findMatch = null,\n resetMs = 750,\n ignoreKeys = [],\n selectedIndex = null\n } = props;\n const timeoutIdRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();\n const stringRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef('');\n const prevIndexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef((_ref = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref : -1);\n const matchIndexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const onMatch = useEffectEvent(unstable_onMatch);\n const onTypingChange = useEffectEvent(unstable_onTypingChange);\n const findMatchRef = useLatestRef(findMatch);\n const ignoreKeysRef = useLatestRef(ignoreKeys);\n index(() => {\n if (open) {\n clearTimeout(timeoutIdRef.current);\n matchIndexRef.current = null;\n stringRef.current = '';\n }\n }, [open]);\n index(() => {\n // Sync arrow key navigation but not typeahead navigation.\n if (open && stringRef.current === '') {\n var _ref2;\n prevIndexRef.current = (_ref2 = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref2 : -1;\n }\n }, [open, selectedIndex, activeIndex]);\n const setTypingChange = useEffectEvent(value => {\n if (value) {\n if (!dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n } else {\n if (dataRef.current.typing) {\n dataRef.current.typing = value;\n onTypingChange(value);\n }\n }\n });\n const onKeyDown = useEffectEvent(event => {\n function getMatchingIndex(list, orderedList, string) {\n const str = findMatchRef.current ? findMatchRef.current(orderedList, string) : orderedList.find(text => (text == null ? void 0 : text.toLocaleLowerCase().indexOf(string.toLocaleLowerCase())) === 0);\n return str ? list.indexOf(str) : -1;\n }\n const listContent = listRef.current;\n if (stringRef.current.length > 0 && stringRef.current[0] !== ' ') {\n if (getMatchingIndex(listContent, listContent, stringRef.current) === -1) {\n setTypingChange(false);\n } else if (event.key === ' ') {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n }\n }\n if (listContent == null || ignoreKeysRef.current.includes(event.key) ||\n // Character key.\n event.key.length !== 1 ||\n // Modifier key.\n event.ctrlKey || event.metaKey || event.altKey) {\n return;\n }\n if (open && event.key !== ' ') {\n (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.stopEvent)(event);\n setTypingChange(true);\n }\n\n // Bail out if the list contains a word like \"llama\" or \"aaron\". TODO:\n // allow it in this case, too.\n const allowRapidSuccessionOfFirstLetter = listContent.every(text => {\n var _text$, _text$2;\n return text ? ((_text$ = text[0]) == null ? void 0 : _text$.toLocaleLowerCase()) !== ((_text$2 = text[1]) == null ? void 0 : _text$2.toLocaleLowerCase()) : true;\n });\n\n // Allows the user to cycle through items that start with the same letter\n // in rapid succession.\n if (allowRapidSuccessionOfFirstLetter && stringRef.current === event.key) {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n }\n stringRef.current += event.key;\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = setTimeout(() => {\n stringRef.current = '';\n prevIndexRef.current = matchIndexRef.current;\n setTypingChange(false);\n }, resetMs);\n const prevIndex = prevIndexRef.current;\n const index = getMatchingIndex(listContent, [...listContent.slice((prevIndex || 0) + 1), ...listContent.slice(0, (prevIndex || 0) + 1)], stringRef.current);\n if (index !== -1) {\n onMatch(index);\n matchIndexRef.current = index;\n } else if (event.key !== ' ') {\n stringRef.current = '';\n setTypingChange(false);\n }\n });\n const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onKeyDown\n }), [onKeyDown]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {\n return {\n onKeyDown,\n onKeyUp(event) {\n if (event.key === ' ') {\n setTypingChange(false);\n }\n }\n };\n }, [onKeyDown, setTypingChange]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n reference,\n floating\n } : {}, [enabled, reference, floating]);\n}\n\nfunction getArgsWithCustomFloatingHeight(state, height) {\n return {\n ...state,\n rects: {\n ...state.rects,\n floating: {\n ...state.rects.floating,\n height\n }\n }\n };\n}\n/**\n * Positions the floating element such that an inner element inside of it is\n * anchored to the reference element.\n * @see https://floating-ui.com/docs/inner\n */\nconst inner = props => ({\n name: 'inner',\n options: props,\n async fn(state) {\n const {\n listRef,\n overflowRef,\n onFallbackChange,\n offset: innerOffset = 0,\n index = 0,\n minItemsVisible = 4,\n referenceOverflowThreshold = 0,\n scrollRef,\n ...detectOverflowOptions\n } = (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_6__.evaluate)(props, state);\n const {\n rects,\n elements: {\n floating\n }\n } = state;\n const item = listRef.current[index];\n const scrollEl = (scrollRef == null ? void 0 : scrollRef.current) || floating;\n\n // Valid combinations:\n // 1. Floating element is the scrollRef and has a border (default)\n // 2. Floating element is not the scrollRef, floating element has a border\n // 3. Floating element is not the scrollRef, scrollRef has a border\n // Floating > {...getFloatingProps()} wrapper > scrollRef > items is not\n // allowed as VoiceOver doesn't work.\n const clientTop = floating.clientTop || scrollEl.clientTop;\n const floatingIsBordered = floating.clientTop !== 0;\n const scrollElIsBordered = scrollEl.clientTop !== 0;\n const floatingIsScrollEl = floating === scrollEl;\n if (true) {\n if (!state.placement.startsWith('bottom')) {\n warn('`placement` side must be \"bottom\" when using the `inner`', 'middleware.');\n }\n }\n if (!item) {\n return {};\n }\n const nextArgs = {\n ...state,\n ...(await (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_2__.offset)(-item.offsetTop - floating.clientTop - rects.reference.height / 2 - item.offsetHeight / 2 - innerOffset).fn(state))\n };\n const overflow = await (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_3__.detectOverflow)(getArgsWithCustomFloatingHeight(nextArgs, scrollEl.scrollHeight + clientTop + floating.clientTop), detectOverflowOptions);\n const refOverflow = await (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_3__.detectOverflow)(nextArgs, {\n ...detectOverflowOptions,\n elementContext: 'reference'\n });\n const diffY = Math.max(0, overflow.top);\n const nextY = nextArgs.y + diffY;\n const maxHeight = Math.max(0, scrollEl.scrollHeight + (floatingIsBordered && floatingIsScrollEl || scrollElIsBordered ? clientTop * 2 : 0) - diffY - Math.max(0, overflow.bottom));\n scrollEl.style.maxHeight = maxHeight + \"px\";\n scrollEl.scrollTop = diffY;\n\n // There is not enough space, fallback to standard anchored positioning\n if (onFallbackChange) {\n if (scrollEl.offsetHeight < item.offsetHeight * Math.min(minItemsVisible, listRef.current.length - 1) - 1 || refOverflow.top >= -referenceOverflowThreshold || refOverflow.bottom >= -referenceOverflowThreshold) {\n react_dom__WEBPACK_IMPORTED_MODULE_1__.flushSync(() => onFallbackChange(true));\n } else {\n react_dom__WEBPACK_IMPORTED_MODULE_1__.flushSync(() => onFallbackChange(false));\n }\n }\n if (overflowRef) {\n overflowRef.current = await (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_3__.detectOverflow)(getArgsWithCustomFloatingHeight({\n ...nextArgs,\n y: nextY\n }, scrollEl.offsetHeight + clientTop + floating.clientTop), detectOverflowOptions);\n }\n return {\n y: nextY\n };\n }\n});\n/**\n * Changes the `inner` middleware's `offset` upon a `wheel` event to\n * expand the floating element's height, revealing more list items.\n * @see https://floating-ui.com/docs/inner\n */\nfunction useInnerOffset(context, props) {\n const {\n open,\n elements\n } = context;\n const {\n enabled = true,\n overflowRef,\n scrollRef,\n onChange: unstable_onChange\n } = props;\n const onChange = useEffectEvent(unstable_onChange);\n const controlledScrollingRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);\n const prevScrollTopRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const initialOverflowRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n if (!enabled) return;\n function onWheel(e) {\n if (e.ctrlKey || !el || overflowRef.current == null) {\n return;\n }\n const dY = e.deltaY;\n const isAtTop = overflowRef.current.top >= -0.5;\n const isAtBottom = overflowRef.current.bottom >= -0.5;\n const remainingScroll = el.scrollHeight - el.clientHeight;\n const sign = dY < 0 ? -1 : 1;\n const method = dY < 0 ? 'max' : 'min';\n if (el.scrollHeight <= el.clientHeight) {\n return;\n }\n if (!isAtTop && dY > 0 || !isAtBottom && dY < 0) {\n e.preventDefault();\n react_dom__WEBPACK_IMPORTED_MODULE_1__.flushSync(() => {\n onChange(d => d + Math[method](dY, remainingScroll * sign));\n });\n } else if (/firefox/i.test((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getUserAgent)())) {\n // Needed to propagate scrolling during momentum scrolling phase once\n // it gets limited by the boundary. UX improvement, not critical.\n el.scrollTop += dY;\n }\n }\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (open && el) {\n el.addEventListener('wheel', onWheel);\n\n // Wait for the position to be ready.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n if (overflowRef.current != null) {\n initialOverflowRef.current = {\n ...overflowRef.current\n };\n }\n });\n return () => {\n prevScrollTopRef.current = null;\n initialOverflowRef.current = null;\n el.removeEventListener('wheel', onWheel);\n };\n }\n }, [enabled, open, elements.floating, overflowRef, scrollRef, onChange]);\n const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({\n onKeyDown() {\n controlledScrollingRef.current = true;\n },\n onWheel() {\n controlledScrollingRef.current = false;\n },\n onPointerMove() {\n controlledScrollingRef.current = false;\n },\n onScroll() {\n const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;\n if (!overflowRef.current || !el || !controlledScrollingRef.current) {\n return;\n }\n if (prevScrollTopRef.current !== null) {\n const scrollDiff = el.scrollTop - prevScrollTopRef.current;\n if (overflowRef.current.bottom < -0.5 && scrollDiff < -1 || overflowRef.current.top < -0.5 && scrollDiff > 1) {\n react_dom__WEBPACK_IMPORTED_MODULE_1__.flushSync(() => onChange(d => d + scrollDiff));\n }\n }\n\n // [Firefox] Wait for the height change to have been applied.\n requestAnimationFrame(() => {\n prevScrollTopRef.current = el.scrollTop;\n });\n }\n }), [elements.floating, onChange, overflowRef, scrollRef]);\n return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {\n floating\n } : {}, [enabled, floating]);\n}\n\nfunction isPointInPolygon(point, polygon) {\n const [x, y] = point;\n let isInside = false;\n const length = polygon.length;\n for (let i = 0, j = length - 1; i < length; j = i++) {\n const [xi, yi] = polygon[i] || [0, 0];\n const [xj, yj] = polygon[j] || [0, 0];\n const intersect = yi >= y !== yj >= y && x <= (xj - xi) * (y - yi) / (yj - yi) + xi;\n if (intersect) {\n isInside = !isInside;\n }\n }\n return isInside;\n}\nfunction isInside(point, rect) {\n return point[0] >= rect.x && point[0] <= rect.x + rect.width && point[1] >= rect.y && point[1] <= rect.y + rect.height;\n}\n/**\n * Generates a safe polygon area that the user can traverse without closing the\n * floating element once leaving the reference element.\n * @see https://floating-ui.com/docs/useHover#safepolygon\n */\nfunction safePolygon(options) {\n if (options === void 0) {\n options = {};\n }\n const {\n buffer = 0.5,\n blockPointerEvents = false,\n requireIntent = true\n } = options;\n let timeoutId;\n let hasLanded = false;\n let lastX = null;\n let lastY = null;\n let lastCursorTime = performance.now();\n function getCursorSpeed(x, y) {\n const currentTime = performance.now();\n const elapsedTime = currentTime - lastCursorTime;\n if (lastX === null || lastY === null || elapsedTime === 0) {\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return null;\n }\n const deltaX = x - lastX;\n const deltaY = y - lastY;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n const speed = distance / elapsedTime; // px / ms\n\n lastX = x;\n lastY = y;\n lastCursorTime = currentTime;\n return speed;\n }\n const fn = _ref => {\n let {\n x,\n y,\n placement,\n elements,\n onClose,\n nodeId,\n tree\n } = _ref;\n return function onMouseMove(event) {\n function close() {\n clearTimeout(timeoutId);\n onClose();\n }\n clearTimeout(timeoutId);\n if (!elements.domReference || !elements.floating || placement == null || x == null || y == null) {\n return;\n }\n const {\n clientX,\n clientY\n } = event;\n const clientPoint = [clientX, clientY];\n const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.getTarget)(event);\n const isLeave = event.type === 'mouseleave';\n const isOverFloatingEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(elements.floating, target);\n const isOverReferenceEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(elements.domReference, target);\n const refRect = elements.domReference.getBoundingClientRect();\n const rect = elements.floating.getBoundingClientRect();\n const side = placement.split('-')[0];\n const cursorLeaveFromRight = x > rect.right - rect.width / 2;\n const cursorLeaveFromBottom = y > rect.bottom - rect.height / 2;\n const isOverReferenceRect = isInside(clientPoint, refRect);\n const isFloatingWider = rect.width > refRect.width;\n const isFloatingTaller = rect.height > refRect.height;\n const left = (isFloatingWider ? refRect : rect).left;\n const right = (isFloatingWider ? refRect : rect).right;\n const top = (isFloatingTaller ? refRect : rect).top;\n const bottom = (isFloatingTaller ? refRect : rect).bottom;\n if (isOverFloatingEl) {\n hasLanded = true;\n if (!isLeave) {\n return;\n }\n }\n if (isOverReferenceEl) {\n hasLanded = false;\n }\n if (isOverReferenceEl && !isLeave) {\n hasLanded = true;\n return;\n }\n\n // Prevent overlapping floating element from being stuck in an open-close\n // loop: https://github.com/floating-ui/floating-ui/issues/1910\n if (isLeave && (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_4__.isElement)(event.relatedTarget) && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_5__.contains)(elements.floating, event.relatedTarget)) {\n return;\n }\n\n // If any nested child is open, abort.\n if (tree && getChildren(tree.nodesRef.current, nodeId).some(_ref2 => {\n let {\n context\n } = _ref2;\n return context == null ? void 0 : context.open;\n })) {\n return;\n }\n\n // If the pointer is leaving from the opposite side, the \"buffer\" logic\n // creates a point where the floating element remains open, but should be\n // ignored.\n // A constant of 1 handles floating point rounding errors.\n if (side === 'top' && y >= refRect.bottom - 1 || side === 'bottom' && y <= refRect.top + 1 || side === 'left' && x >= refRect.right - 1 || side === 'right' && x <= refRect.left + 1) {\n return close();\n }\n\n // Ignore when the cursor is within the rectangular trough between the\n // two elements. Since the triangle is created from the cursor point,\n // which can start beyond the ref element's edge, traversing back and\n // forth from the ref to the floating element can cause it to close. This\n // ensures it always remains open in that case.\n let rectPoly = [];\n switch (side) {\n case 'top':\n rectPoly = [[left, refRect.top + 1], [left, rect.bottom - 1], [right, rect.bottom - 1], [right, refRect.top + 1]];\n break;\n case 'bottom':\n rectPoly = [[left, rect.top + 1], [left, refRect.bottom - 1], [right, refRect.bottom - 1], [right, rect.top + 1]];\n break;\n case 'left':\n rectPoly = [[rect.right - 1, bottom], [rect.right - 1, top], [refRect.left + 1, top], [refRect.left + 1, bottom]];\n break;\n case 'right':\n rectPoly = [[refRect.right - 1, bottom], [refRect.right - 1, top], [rect.left + 1, top], [rect.left + 1, bottom]];\n break;\n }\n function getPolygon(_ref3) {\n let [x, y] = _ref3;\n switch (side) {\n case 'top':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.bottom - buffer : isFloatingWider ? rect.bottom - buffer : rect.top], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.bottom - buffer : rect.top : rect.bottom - buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'bottom':\n {\n const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];\n const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.top + buffer : isFloatingWider ? rect.top + buffer : rect.bottom], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.top + buffer : rect.bottom : rect.top + buffer]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n case 'left':\n {\n const cursorPointOne = [x + buffer + 1, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x + buffer + 1, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.right - buffer : isFloatingTaller ? rect.right - buffer : rect.left, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.right - buffer : rect.left : rect.right - buffer, rect.bottom]];\n return [...commonPoints, cursorPointOne, cursorPointTwo];\n }\n case 'right':\n {\n const cursorPointOne = [x - buffer, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const cursorPointTwo = [x - buffer, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];\n const commonPoints = [[cursorLeaveFromBottom ? rect.left + buffer : isFloatingTaller ? rect.left + buffer : rect.right, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.left + buffer : rect.right : rect.left + buffer, rect.bottom]];\n return [cursorPointOne, cursorPointTwo, ...commonPoints];\n }\n }\n }\n if (isPointInPolygon([clientX, clientY], rectPoly)) {\n return;\n }\n if (hasLanded && !isOverReferenceRect) {\n return close();\n }\n if (!isLeave && requireIntent) {\n const cursorSpeed = getCursorSpeed(event.clientX, event.clientY);\n const cursorSpeedThreshold = 0.1;\n if (cursorSpeed !== null && cursorSpeed < cursorSpeedThreshold) {\n return close();\n }\n }\n if (!isPointInPolygon([clientX, clientY], getPolygon([x, y]))) {\n close();\n } else if (!hasLanded && requireIntent) {\n timeoutId = window.setTimeout(close, 40);\n }\n };\n };\n fn.__options = {\n blockPointerEvents\n };\n return fn;\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3JlYWN0L2Rpc3QvZmxvYXRpbmctdWkucmVhY3QubWpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDNEI7QUFDK087QUFDclA7QUFDNkY7QUFDbEc7QUFDVjtBQUM4RTtBQUM0RTs7QUFFaE07QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsMENBQWE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxLQUFLLHlMQUFLO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYyx5Q0FBWTtBQUMxQixRQUFRLElBQXFDO0FBQzdDO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSCxTQUFTLDhDQUFpQjtBQUMxQix3RUFBd0UsYUFBYTtBQUNyRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSx3QkFBd0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLFlBQVksbUVBQVM7QUFDckI7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxtRUFBVztBQUNyQjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUscUVBQVc7QUFDMUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBLHNCQUFzQixrREFBUTtBQUM5QjtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsdUVBQWEsQ0FBQyxxRUFBVztBQUNuRTtBQUNB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDOztBQUUxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLHFCQUFxQixtRUFBUztBQUM5QjtBQUNBLCtCQUErQixrRUFBUTtBQUN2QyxnQ0FBZ0Msa0VBQVE7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixpRUFBUyx5QkFBeUIsa0VBQVE7QUFDL0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUUyaUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yYWRpYW50Ly4vbm9kZV9tb2R1bGVzL0BmbG9hdGluZy11aS9yZWFjdC9kaXN0L2Zsb2F0aW5nLXVpLnJlYWN0Lm1qcz84ZmUzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZUxheW91dEVmZmVjdCwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBzdG9wRXZlbnQsIGdldERvY3VtZW50LCBpc01vdXNlTGlrZVBvaW50ZXJUeXBlLCBjb250YWlucywgYWN0aXZlRWxlbWVudCwgaXNTYWZhcmksIGlzVHlwZWFibGVDb21ib2JveCwgaXNWaXJ0dWFsQ2xpY2ssIGlzVmlydHVhbFBvaW50ZXJFdmVudCwgZ2V0VGFyZ2V0LCBnZXRQbGF0Zm9ybSwgaXNUeXBlYWJsZUVsZW1lbnQsIGlzUmVhY3RFdmVudCwgaXNSb290RWxlbWVudCwgaXNFdmVudFRhcmdldFdpdGhpbiwgaXNNYWMsIGdldFVzZXJBZ2VudCB9IGZyb20gJ0BmbG9hdGluZy11aS9yZWFjdC91dGlscyc7XG5pbXBvcnQgeyBmbG9vciwgZXZhbHVhdGUgfSBmcm9tICdAZmxvYXRpbmctdWkvdXRpbHMnO1xuaW1wb3J0IHsgZ2V0Q29tcHV0ZWRTdHlsZSwgaXNFbGVtZW50LCBnZXROb2RlTmFtZSwgaXNIVE1MRWxlbWVudCwgZ2V0V2luZG93LCBpc0xhc3RUcmF2ZXJzYWJsZU5vZGUsIGdldFBhcmVudE5vZGUgfSBmcm9tICdAZmxvYXRpbmctdWkvdXRpbHMvZG9tJztcbmltcG9ydCB7IHRhYmJhYmxlLCBpc1RhYmJhYmxlIH0gZnJvbSAndGFiYmFibGUnO1xuaW1wb3J0ICogYXMgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB7IGdldE92ZXJmbG93QW5jZXN0b3JzLCB1c2VGbG9hdGluZyBhcyB1c2VGbG9hdGluZyQxLCBvZmZzZXQsIGRldGVjdE92ZXJmbG93IH0gZnJvbSAnQGZsb2F0aW5nLXVpL3JlYWN0LWRvbSc7XG5leHBvcnQgeyBhcnJvdywgYXV0b1BsYWNlbWVudCwgYXV0b1VwZGF0ZSwgY29tcHV0ZVBvc2l0aW9uLCBkZXRlY3RPdmVyZmxvdywgZmxpcCwgZ2V0T3ZlcmZsb3dBbmNlc3RvcnMsIGhpZGUsIGlubGluZSwgbGltaXRTaGlmdCwgb2Zmc2V0LCBwbGF0Zm9ybSwgc2hpZnQsIHNpemUgfSBmcm9tICdAZmxvYXRpbmctdWkvcmVhY3QtZG9tJztcblxuLyoqXG4gKiBNZXJnZXMgYW4gYXJyYXkgb2YgcmVmcyBpbnRvIGEgc2luZ2xlIG1lbW9pemVkIGNhbGxiYWNrIHJlZiBvciBgbnVsbGAuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvcmVhY3QtdXRpbHMjdXNlbWVyZ2VyZWZzXG4gKi9cbmZ1bmN0aW9uIHVzZU1lcmdlUmVmcyhyZWZzKSB7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBpZiAocmVmcy5ldmVyeShyZWYgPT4gcmVmID09IG51bGwpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlID0+IHtcbiAgICAgIHJlZnMuZm9yRWFjaChyZWYgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJlZih2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVmICE9IG51bGwpIHtcbiAgICAgICAgICByZWYuY3VycmVudCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgcmVmcyk7XG59XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tdWkvbWF0ZXJpYWwtdWkvaXNzdWVzLzQxMTkwI2lzc3VlY29tbWVudC0yMDQwODczMzc5XG5jb25zdCBTYWZlUmVhY3QgPSB7XG4gIC4uLlJlYWN0XG59O1xuXG5jb25zdCB1c2VJbnNlcnRpb25FZmZlY3QgPSBTYWZlUmVhY3QudXNlSW5zZXJ0aW9uRWZmZWN0O1xuY29uc3QgdXNlU2FmZUluc2VydGlvbkVmZmVjdCA9IHVzZUluc2VydGlvbkVmZmVjdCB8fCAoZm4gPT4gZm4oKSk7XG5mdW5jdGlvbiB1c2VFZmZlY3RFdmVudChjYWxsYmFjaykge1xuICBjb25zdCByZWYgPSBSZWFjdC51c2VSZWYoKCkgPT4ge1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNhbGwgYW4gZXZlbnQgaGFuZGxlciB3aGlsZSByZW5kZXJpbmcuJyk7XG4gICAgfVxuICB9KTtcbiAgdXNlU2FmZUluc2VydGlvbkVmZmVjdCgoKSA9PiB7XG4gICAgcmVmLmN1cnJlbnQgPSBjYWxsYmFjaztcbiAgfSk7XG4gIHJldHVybiBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cbiAgICByZXR1cm4gcmVmLmN1cnJlbnQgPT0gbnVsbCA/IHZvaWQgMCA6IHJlZi5jdXJyZW50KC4uLmFyZ3MpO1xuICB9LCBbXSk7XG59XG5cbmNvbnN0IEFSUk9XX1VQID0gJ0Fycm93VXAnO1xuY29uc3QgQVJST1dfRE9XTiA9ICdBcnJvd0Rvd24nO1xuY29uc3QgQVJST1dfTEVGVCA9ICdBcnJvd0xlZnQnO1xuY29uc3QgQVJST1dfUklHSFQgPSAnQXJyb3dSaWdodCc7XG5mdW5jdGlvbiBpc0RpZmZlcmVudFJvdyhpbmRleCwgY29scywgcHJldlJvdykge1xuICByZXR1cm4gTWF0aC5mbG9vcihpbmRleCAvIGNvbHMpICE9PSBwcmV2Um93O1xufVxuZnVuY3Rpb24gaXNJbmRleE91dE9mQm91bmRzKGxpc3RSZWYsIGluZGV4KSB7XG4gIHJldHVybiBpbmRleCA8IDAgfHwgaW5kZXggPj0gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aDtcbn1cbmZ1bmN0aW9uIGdldE1pbkluZGV4KGxpc3RSZWYsIGRpc2FibGVkSW5kaWNlcykge1xuICByZXR1cm4gZmluZE5vbkRpc2FibGVkSW5kZXgobGlzdFJlZiwge1xuICAgIGRpc2FibGVkSW5kaWNlc1xuICB9KTtcbn1cbmZ1bmN0aW9uIGdldE1heEluZGV4KGxpc3RSZWYsIGRpc2FibGVkSW5kaWNlcykge1xuICByZXR1cm4gZmluZE5vbkRpc2FibGVkSW5kZXgobGlzdFJlZiwge1xuICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICBzdGFydGluZ0luZGV4OiBsaXN0UmVmLmN1cnJlbnQubGVuZ3RoLFxuICAgIGRpc2FibGVkSW5kaWNlc1xuICB9KTtcbn1cbmZ1bmN0aW9uIGZpbmROb25EaXNhYmxlZEluZGV4KGxpc3RSZWYsIF90ZW1wKSB7XG4gIGxldCB7XG4gICAgc3RhcnRpbmdJbmRleCA9IC0xLFxuICAgIGRlY3JlbWVudCA9IGZhbHNlLFxuICAgIGRpc2FibGVkSW5kaWNlcyxcbiAgICBhbW91bnQgPSAxXG4gIH0gPSBfdGVtcCA9PT0gdm9pZCAwID8ge30gOiBfdGVtcDtcbiAgY29uc3QgbGlzdCA9IGxpc3RSZWYuY3VycmVudDtcbiAgbGV0IGluZGV4ID0gc3RhcnRpbmdJbmRleDtcbiAgZG8ge1xuICAgIGluZGV4ICs9IGRlY3JlbWVudCA/IC1hbW91bnQgOiBhbW91bnQ7XG4gIH0gd2hpbGUgKGluZGV4ID49IDAgJiYgaW5kZXggPD0gbGlzdC5sZW5ndGggLSAxICYmIGlzRGlzYWJsZWQobGlzdCwgaW5kZXgsIGRpc2FibGVkSW5kaWNlcykpO1xuICByZXR1cm4gaW5kZXg7XG59XG5mdW5jdGlvbiBnZXRHcmlkTmF2aWdhdGVkSW5kZXgoZWxlbWVudHNSZWYsIF9yZWYpIHtcbiAgbGV0IHtcbiAgICBldmVudCxcbiAgICBvcmllbnRhdGlvbixcbiAgICBsb29wLFxuICAgIGNvbHMsXG4gICAgZGlzYWJsZWRJbmRpY2VzLFxuICAgIG1pbkluZGV4LFxuICAgIG1heEluZGV4LFxuICAgIHByZXZJbmRleCxcbiAgICBzdG9wRXZlbnQ6IHN0b3AgPSBmYWxzZVxuICB9ID0gX3JlZjtcbiAgbGV0IG5leHRJbmRleCA9IHByZXZJbmRleDtcbiAgaWYgKGV2ZW50LmtleSA9PT0gQVJST1dfVVApIHtcbiAgICBzdG9wICYmIHN0b3BFdmVudChldmVudCk7XG4gICAgaWYgKHByZXZJbmRleCA9PT0gLTEpIHtcbiAgICAgIG5leHRJbmRleCA9IG1heEluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0SW5kZXggPSBmaW5kTm9uRGlzYWJsZWRJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICBzdGFydGluZ0luZGV4OiBuZXh0SW5kZXgsXG4gICAgICAgIGFtb3VudDogY29scyxcbiAgICAgICAgZGVjcmVtZW50OiB0cnVlLFxuICAgICAgICBkaXNhYmxlZEluZGljZXNcbiAgICAgIH0pO1xuICAgICAgaWYgKGxvb3AgJiYgKHByZXZJbmRleCAtIGNvbHMgPCBtaW5JbmRleCB8fCBuZXh0SW5kZXggPCAwKSkge1xuICAgICAgICBjb25zdCBjb2wgPSBwcmV2SW5kZXggJSBjb2xzO1xuICAgICAgICBjb25zdCBtYXhDb2wgPSBtYXhJbmRleCAlIGNvbHM7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IG1heEluZGV4IC0gKG1heENvbCAtIGNvbCk7XG4gICAgICAgIGlmIChtYXhDb2wgPT09IGNvbCkge1xuICAgICAgICAgIG5leHRJbmRleCA9IG1heEluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5leHRJbmRleCA9IG1heENvbCA+IGNvbCA/IG9mZnNldCA6IG9mZnNldCAtIGNvbHM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzSW5kZXhPdXRPZkJvdW5kcyhlbGVtZW50c1JlZiwgbmV4dEluZGV4KSkge1xuICAgICAgbmV4dEluZGV4ID0gcHJldkluZGV4O1xuICAgIH1cbiAgfVxuICBpZiAoZXZlbnQua2V5ID09PSBBUlJPV19ET1dOKSB7XG4gICAgc3RvcCAmJiBzdG9wRXZlbnQoZXZlbnQpO1xuICAgIGlmIChwcmV2SW5kZXggPT09IC0xKSB7XG4gICAgICBuZXh0SW5kZXggPSBtaW5JbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dEluZGV4ID0gZmluZE5vbkRpc2FibGVkSW5kZXgoZWxlbWVudHNSZWYsIHtcbiAgICAgICAgc3RhcnRpbmdJbmRleDogcHJldkluZGV4LFxuICAgICAgICBhbW91bnQ6IGNvbHMsXG4gICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgfSk7XG4gICAgICBpZiAobG9vcCAmJiBwcmV2SW5kZXggKyBjb2xzID4gbWF4SW5kZXgpIHtcbiAgICAgICAgbmV4dEluZGV4ID0gZmluZE5vbkRpc2FibGVkSW5kZXgoZWxlbWVudHNSZWYsIHtcbiAgICAgICAgICBzdGFydGluZ0luZGV4OiBwcmV2SW5kZXggJSBjb2xzIC0gY29scyxcbiAgICAgICAgICBhbW91bnQ6IGNvbHMsXG4gICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNJbmRleE91dE9mQm91bmRzKGVsZW1lbnRzUmVmLCBuZXh0SW5kZXgpKSB7XG4gICAgICBuZXh0SW5kZXggPSBwcmV2SW5kZXg7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVtYWlucyBvbiB0aGUgc2FtZSByb3cvY29sdW1uLlxuICBpZiAob3JpZW50YXRpb24gPT09ICdib3RoJykge1xuICAgIGNvbnN0IHByZXZSb3cgPSBmbG9vcihwcmV2SW5kZXggLyBjb2xzKTtcbiAgICBpZiAoZXZlbnQua2V5ID09PSBBUlJPV19SSUdIVCkge1xuICAgICAgc3RvcCAmJiBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgaWYgKHByZXZJbmRleCAlIGNvbHMgIT09IGNvbHMgLSAxKSB7XG4gICAgICAgIG5leHRJbmRleCA9IGZpbmROb25EaXNhYmxlZEluZGV4KGVsZW1lbnRzUmVmLCB7XG4gICAgICAgICAgc3RhcnRpbmdJbmRleDogcHJldkluZGV4LFxuICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxvb3AgJiYgaXNEaWZmZXJlbnRSb3cobmV4dEluZGV4LCBjb2xzLCBwcmV2Um93KSkge1xuICAgICAgICAgIG5leHRJbmRleCA9IGZpbmROb25EaXNhYmxlZEluZGV4KGVsZW1lbnRzUmVmLCB7XG4gICAgICAgICAgICBzdGFydGluZ0luZGV4OiBwcmV2SW5kZXggLSBwcmV2SW5kZXggJSBjb2xzIC0gMSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGxvb3ApIHtcbiAgICAgICAgbmV4dEluZGV4ID0gZmluZE5vbkRpc2FibGVkSW5kZXgoZWxlbWVudHNSZWYsIHtcbiAgICAgICAgICBzdGFydGluZ0luZGV4OiBwcmV2SW5kZXggLSBwcmV2SW5kZXggJSBjb2xzIC0gMSxcbiAgICAgICAgICBkaXNhYmxlZEluZGljZXNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNEaWZmZXJlbnRSb3cobmV4dEluZGV4LCBjb2xzLCBwcmV2Um93KSkge1xuICAgICAgICBuZXh0SW5kZXggPSBwcmV2SW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChldmVudC5rZXkgPT09IEFSUk9XX0xFRlQpIHtcbiAgICAgIHN0b3AgJiYgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIGlmIChwcmV2SW5kZXggJSBjb2xzICE9PSAwKSB7XG4gICAgICAgIG5leHRJbmRleCA9IGZpbmROb25EaXNhYmxlZEluZGV4KGVsZW1lbnRzUmVmLCB7XG4gICAgICAgICAgc3RhcnRpbmdJbmRleDogcHJldkluZGV4LFxuICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICBkaXNhYmxlZEluZGljZXNcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChsb29wICYmIGlzRGlmZmVyZW50Um93KG5leHRJbmRleCwgY29scywgcHJldlJvdykpIHtcbiAgICAgICAgICBuZXh0SW5kZXggPSBmaW5kTm9uRGlzYWJsZWRJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogcHJldkluZGV4ICsgKGNvbHMgLSBwcmV2SW5kZXggJSBjb2xzKSxcbiAgICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGxvb3ApIHtcbiAgICAgICAgbmV4dEluZGV4ID0gZmluZE5vbkRpc2FibGVkSW5kZXgoZWxlbWVudHNSZWYsIHtcbiAgICAgICAgICBzdGFydGluZ0luZGV4OiBwcmV2SW5kZXggKyAoY29scyAtIHByZXZJbmRleCAlIGNvbHMpLFxuICAgICAgICAgIGRlY3JlbWVudDogdHJ1ZSxcbiAgICAgICAgICBkaXNhYmxlZEluZGljZXNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNEaWZmZXJlbnRSb3cobmV4dEluZGV4LCBjb2xzLCBwcmV2Um93KSkge1xuICAgICAgICBuZXh0SW5kZXggPSBwcmV2SW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGxhc3RSb3cgPSBmbG9vcihtYXhJbmRleCAvIGNvbHMpID09PSBwcmV2Um93O1xuICAgIGlmIChpc0luZGV4T3V0T2ZCb3VuZHMoZWxlbWVudHNSZWYsIG5leHRJbmRleCkpIHtcbiAgICAgIGlmIChsb29wICYmIGxhc3RSb3cpIHtcbiAgICAgICAgbmV4dEluZGV4ID0gZXZlbnQua2V5ID09PSBBUlJPV19MRUZUID8gbWF4SW5kZXggOiBmaW5kTm9uRGlzYWJsZWRJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IHByZXZJbmRleCAtIHByZXZJbmRleCAlIGNvbHMgLSAxLFxuICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRJbmRleCA9IHByZXZJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5leHRJbmRleDtcbn1cblxuLyoqIEZvciBlYWNoIGNlbGwgaW5kZXgsIGdldHMgdGhlIGl0ZW0gaW5kZXggdGhhdCBvY2N1cGllcyB0aGF0IGNlbGwgKi9cbmZ1bmN0aW9uIGJ1aWxkQ2VsbE1hcChzaXplcywgY29scywgZGVuc2UpIHtcbiAgY29uc3QgY2VsbE1hcCA9IFtdO1xuICBsZXQgc3RhcnRJbmRleCA9IDA7XG4gIHNpemVzLmZvckVhY2goKF9yZWYyLCBpbmRleCkgPT4ge1xuICAgIGxldCB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodFxuICAgIH0gPSBfcmVmMjtcbiAgICBpZiAod2lkdGggPiBjb2xzKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIltGbG9hdGluZyBVSV06IEludmFsaWQgZ3JpZCAtIGl0ZW0gd2lkdGggYXQgaW5kZXggXCIgKyBpbmRleCArIFwiIGlzIGdyZWF0ZXIgdGhhbiBncmlkIGNvbHVtbnNcIik7XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBpdGVtUGxhY2VkID0gZmFsc2U7XG4gICAgaWYgKGRlbnNlKSB7XG4gICAgICBzdGFydEluZGV4ID0gMDtcbiAgICB9XG4gICAgd2hpbGUgKCFpdGVtUGxhY2VkKSB7XG4gICAgICBjb25zdCB0YXJnZXRDZWxscyA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3aWR0aDsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaGVpZ2h0OyBqKyspIHtcbiAgICAgICAgICB0YXJnZXRDZWxscy5wdXNoKHN0YXJ0SW5kZXggKyBpICsgaiAqIGNvbHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhcnRJbmRleCAlIGNvbHMgKyB3aWR0aCA8PSBjb2xzICYmIHRhcmdldENlbGxzLmV2ZXJ5KGNlbGwgPT4gY2VsbE1hcFtjZWxsXSA9PSBudWxsKSkge1xuICAgICAgICB0YXJnZXRDZWxscy5mb3JFYWNoKGNlbGwgPT4ge1xuICAgICAgICAgIGNlbGxNYXBbY2VsbF0gPSBpbmRleDtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0ZW1QbGFjZWQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnRJbmRleCsrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLy8gY29udmVydCBpbnRvIGEgbm9uLXNwYXJzZSBhcnJheVxuICByZXR1cm4gWy4uLmNlbGxNYXBdO1xufVxuXG4vKiogR2V0cyBjZWxsIGluZGV4IG9mIGFuIGl0ZW0ncyBjb3JuZXIgb3IgLTEgd2hlbiBpbmRleCBpcyAtMS4gKi9cbmZ1bmN0aW9uIGdldENlbGxJbmRleE9mQ29ybmVyKGluZGV4LCBzaXplcywgY2VsbE1hcCwgY29scywgY29ybmVyKSB7XG4gIGlmIChpbmRleCA9PT0gLTEpIHJldHVybiAtMTtcbiAgY29uc3QgZmlyc3RDZWxsSW5kZXggPSBjZWxsTWFwLmluZGV4T2YoaW5kZXgpO1xuICBjb25zdCBzaXplSXRlbSA9IHNpemVzW2luZGV4XTtcbiAgc3dpdGNoIChjb3JuZXIpIHtcbiAgICBjYXNlICd0bCc6XG4gICAgICByZXR1cm4gZmlyc3RDZWxsSW5kZXg7XG4gICAgY2FzZSAndHInOlxuICAgICAgaWYgKCFzaXplSXRlbSkge1xuICAgICAgICByZXR1cm4gZmlyc3RDZWxsSW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmlyc3RDZWxsSW5kZXggKyBzaXplSXRlbS53aWR0aCAtIDE7XG4gICAgY2FzZSAnYmwnOlxuICAgICAgaWYgKCFzaXplSXRlbSkge1xuICAgICAgICByZXR1cm4gZmlyc3RDZWxsSW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmlyc3RDZWxsSW5kZXggKyAoc2l6ZUl0ZW0uaGVpZ2h0IC0gMSkgKiBjb2xzO1xuICAgIGNhc2UgJ2JyJzpcbiAgICAgIHJldHVybiBjZWxsTWFwLmxhc3RJbmRleE9mKGluZGV4KTtcbiAgfVxufVxuXG4vKiogR2V0cyBhbGwgY2VsbCBpbmRpY2VzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgc3BlY2lmaWVkIGluZGljZXMgKi9cbmZ1bmN0aW9uIGdldENlbGxJbmRpY2VzKGluZGljZXMsIGNlbGxNYXApIHtcbiAgcmV0dXJuIGNlbGxNYXAuZmxhdE1hcCgoaW5kZXgsIGNlbGxJbmRleCkgPT4gaW5kaWNlcy5pbmNsdWRlcyhpbmRleCkgPyBbY2VsbEluZGV4XSA6IFtdKTtcbn1cbmZ1bmN0aW9uIGlzRGlzYWJsZWQobGlzdCwgaW5kZXgsIGRpc2FibGVkSW5kaWNlcykge1xuICBpZiAoZGlzYWJsZWRJbmRpY2VzKSB7XG4gICAgcmV0dXJuIGRpc2FibGVkSW5kaWNlcy5pbmNsdWRlcyhpbmRleCk7XG4gIH1cbiAgY29uc3QgZWxlbWVudCA9IGxpc3RbaW5kZXhdO1xuICByZXR1cm4gZWxlbWVudCA9PSBudWxsIHx8IGVsZW1lbnQuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdhcmlhLWRpc2FibGVkJykgPT09ICd0cnVlJztcbn1cblxubGV0IHJhZklkID0gMDtcbmZ1bmN0aW9uIGVucXVldWVGb2N1cyhlbCwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBwcmV2ZW50U2Nyb2xsID0gZmFsc2UsXG4gICAgY2FuY2VsUHJldmlvdXMgPSB0cnVlLFxuICAgIHN5bmMgPSBmYWxzZVxuICB9ID0gb3B0aW9ucztcbiAgY2FuY2VsUHJldmlvdXMgJiYgY2FuY2VsQW5pbWF0aW9uRnJhbWUocmFmSWQpO1xuICBjb25zdCBleGVjID0gKCkgPT4gZWwgPT0gbnVsbCA/IHZvaWQgMCA6IGVsLmZvY3VzKHtcbiAgICBwcmV2ZW50U2Nyb2xsXG4gIH0pO1xuICBpZiAoc3luYykge1xuICAgIGV4ZWMoKTtcbiAgfSBlbHNlIHtcbiAgICByYWZJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShleGVjKTtcbiAgfVxufVxuXG52YXIgaW5kZXggPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gdXNlTGF5b3V0RWZmZWN0IDogdXNlRWZmZWN0O1xuXG5mdW5jdGlvbiBzb3J0QnlEb2N1bWVudFBvc2l0aW9uKGEsIGIpIHtcbiAgY29uc3QgcG9zaXRpb24gPSBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpO1xuICBpZiAocG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyB8fCBwb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmIChwb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HIHx8IHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUykge1xuICAgIHJldHVybiAxO1xuICB9XG4gIHJldHVybiAwO1xufVxuZnVuY3Rpb24gYXJlTWFwc0VxdWFsKG1hcDEsIG1hcDIpIHtcbiAgaWYgKG1hcDEuc2l6ZSAhPT0gbWFwMi5zaXplKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIG1hcDEuZW50cmllcygpKSB7XG4gICAgaWYgKHZhbHVlICE9PSBtYXAyLmdldChrZXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuY29uc3QgRmxvYXRpbmdMaXN0Q29udGV4dCA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVDb250ZXh0KHtcbiAgcmVnaXN0ZXI6ICgpID0+IHt9LFxuICB1bnJlZ2lzdGVyOiAoKSA9PiB7fSxcbiAgbWFwOiAvKiNfX1BVUkVfXyovbmV3IE1hcCgpLFxuICBlbGVtZW50c1JlZjoge1xuICAgIGN1cnJlbnQ6IFtdXG4gIH1cbn0pO1xuLyoqXG4gKiBQcm92aWRlcyBjb250ZXh0IGZvciBhIGxpc3Qgb2YgaXRlbXMgd2l0aGluIHRoZSBmbG9hdGluZyBlbGVtZW50LlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nTGlzdFxuICovXG5mdW5jdGlvbiBGbG9hdGluZ0xpc3QocHJvcHMpIHtcbiAgY29uc3Qge1xuICAgIGNoaWxkcmVuLFxuICAgIGVsZW1lbnRzUmVmLFxuICAgIGxhYmVsc1JlZlxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IFttYXAsIHNldE1hcF0gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBuZXcgTWFwKCkpO1xuICBjb25zdCByZWdpc3RlciA9IFJlYWN0LnVzZUNhbGxiYWNrKG5vZGUgPT4ge1xuICAgIHNldE1hcChwcmV2TWFwID0+IG5ldyBNYXAocHJldk1hcCkuc2V0KG5vZGUsIG51bGwpKTtcbiAgfSwgW10pO1xuICBjb25zdCB1bnJlZ2lzdGVyID0gUmVhY3QudXNlQ2FsbGJhY2sobm9kZSA9PiB7XG4gICAgc2V0TWFwKHByZXZNYXAgPT4ge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE1hcChwcmV2TWFwKTtcbiAgICAgIG1hcC5kZWxldGUobm9kZSk7XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH0pO1xuICB9LCBbXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBjb25zdCBuZXdNYXAgPSBuZXcgTWFwKG1hcCk7XG4gICAgY29uc3Qgbm9kZXMgPSBBcnJheS5mcm9tKG5ld01hcC5rZXlzKCkpLnNvcnQoc29ydEJ5RG9jdW1lbnRQb3NpdGlvbik7XG4gICAgbm9kZXMuZm9yRWFjaCgobm9kZSwgaW5kZXgpID0+IHtcbiAgICAgIG5ld01hcC5zZXQobm9kZSwgaW5kZXgpO1xuICAgIH0pO1xuICAgIGlmICghYXJlTWFwc0VxdWFsKG1hcCwgbmV3TWFwKSkge1xuICAgICAgc2V0TWFwKG5ld01hcCk7XG4gICAgfVxuICB9LCBbbWFwXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGbG9hdGluZ0xpc3RDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAgIHJlZ2lzdGVyLFxuICAgICAgdW5yZWdpc3RlcixcbiAgICAgIG1hcCxcbiAgICAgIGVsZW1lbnRzUmVmLFxuICAgICAgbGFiZWxzUmVmXG4gICAgfSksIFtyZWdpc3RlciwgdW5yZWdpc3RlciwgbWFwLCBlbGVtZW50c1JlZiwgbGFiZWxzUmVmXSlcbiAgfSwgY2hpbGRyZW4pO1xufVxuLyoqXG4gKiBVc2VkIHRvIHJlZ2lzdGVyIGEgbGlzdCBpdGVtIGFuZCBpdHMgaW5kZXggKERPTSBwb3NpdGlvbikgaW4gdGhlXG4gKiBgRmxvYXRpbmdMaXN0YC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0xpc3QjdXNlbGlzdGl0ZW1cbiAqL1xuZnVuY3Rpb24gdXNlTGlzdEl0ZW0ocHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBsYWJlbFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHtcbiAgICByZWdpc3RlcixcbiAgICB1bnJlZ2lzdGVyLFxuICAgIG1hcCxcbiAgICBlbGVtZW50c1JlZixcbiAgICBsYWJlbHNSZWZcbiAgfSA9IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdMaXN0Q29udGV4dCk7XG4gIGNvbnN0IFtpbmRleCQxLCBzZXRJbmRleF0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3QgY29tcG9uZW50UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCByZWYgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBjb21wb25lbnRSZWYuY3VycmVudCA9IG5vZGU7XG4gICAgaWYgKGluZGV4JDEgIT09IG51bGwpIHtcbiAgICAgIGVsZW1lbnRzUmVmLmN1cnJlbnRbaW5kZXgkMV0gPSBub2RlO1xuICAgICAgaWYgKGxhYmVsc1JlZikge1xuICAgICAgICB2YXIgX25vZGUkdGV4dENvbnRlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGFiZWxEZWZpbmVkID0gbGFiZWwgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgbGFiZWxzUmVmLmN1cnJlbnRbaW5kZXgkMV0gPSBpc0xhYmVsRGVmaW5lZCA/IGxhYmVsIDogKF9ub2RlJHRleHRDb250ZW50ID0gbm9kZSA9PSBudWxsID8gdm9pZCAwIDogbm9kZS50ZXh0Q29udGVudCkgIT0gbnVsbCA/IF9ub2RlJHRleHRDb250ZW50IDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtpbmRleCQxLCBlbGVtZW50c1JlZiwgbGFiZWxzUmVmLCBsYWJlbF0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgY29uc3Qgbm9kZSA9IGNvbXBvbmVudFJlZi5jdXJyZW50O1xuICAgIGlmIChub2RlKSB7XG4gICAgICByZWdpc3Rlcihub2RlKTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHVucmVnaXN0ZXIobm9kZSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW3JlZ2lzdGVyLCB1bnJlZ2lzdGVyXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBjb25zdCBpbmRleCA9IGNvbXBvbmVudFJlZi5jdXJyZW50ID8gbWFwLmdldChjb21wb25lbnRSZWYuY3VycmVudCkgOiBudWxsO1xuICAgIGlmIChpbmRleCAhPSBudWxsKSB7XG4gICAgICBzZXRJbmRleChpbmRleCk7XG4gICAgfVxuICB9LCBbbWFwXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgcmVmLFxuICAgIGluZGV4OiBpbmRleCQxID09IG51bGwgPyAtMSA6IGluZGV4JDFcbiAgfSksIFtpbmRleCQxLCByZWZdKTtcbn1cblxuZnVuY3Rpb24gcmVuZGVySnN4KHJlbmRlciwgY29tcHV0ZWRQcm9wcykge1xuICBpZiAodHlwZW9mIHJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiByZW5kZXIoY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgaWYgKHJlbmRlcikge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KHJlbmRlciwgY29tcHV0ZWRQcm9wcyk7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIGNvbXB1dGVkUHJvcHMpO1xufVxuY29uc3QgQ29tcG9zaXRlQ29udGV4dCA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVDb250ZXh0KHtcbiAgYWN0aXZlSW5kZXg6IDAsXG4gIG9uTmF2aWdhdGU6ICgpID0+IHt9XG59KTtcbmNvbnN0IGhvcml6b250YWxLZXlzID0gW0FSUk9XX0xFRlQsIEFSUk9XX1JJR0hUXTtcbmNvbnN0IHZlcnRpY2FsS2V5cyA9IFtBUlJPV19VUCwgQVJST1dfRE9XTl07XG5jb25zdCBhbGxLZXlzID0gWy4uLmhvcml6b250YWxLZXlzLCAuLi52ZXJ0aWNhbEtleXNdO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBzaW5nbGUgdGFiIHN0b3Agd2hvc2UgaXRlbXMgYXJlIG5hdmlnYXRlZCBieSBhcnJvdyBrZXlzLCB3aGljaFxuICogcHJvdmlkZXMgbGlzdCBuYXZpZ2F0aW9uIG91dHNpZGUgb2YgZmxvYXRpbmcgZWxlbWVudCBjb250ZXh0cy5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCB0byBlbmFibGUgbmF2aWdhdGlvbiBvZiBhIGxpc3Qgb2YgaXRlbXMgdGhhdCBhcmVu4oCZdCBwYXJ0IG9mIGFcbiAqIGZsb2F0aW5nIGVsZW1lbnQuIEEgbWVudWJhciBpcyBhbiBleGFtcGxlIG9mIGEgY29tcG9zaXRlLCB3aXRoIGVhY2ggcmVmZXJlbmNlXG4gKiBlbGVtZW50IGJlaW5nIGFuIGl0ZW0uXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvQ29tcG9zaXRlXG4gKi9cbmNvbnN0IENvbXBvc2l0ZSA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIENvbXBvc2l0ZShwcm9wcywgZm9yd2FyZGVkUmVmKSB7XG4gIGNvbnN0IHtcbiAgICByZW5kZXIsXG4gICAgb3JpZW50YXRpb24gPSAnYm90aCcsXG4gICAgbG9vcCA9IHRydWUsXG4gICAgY29scyA9IDEsXG4gICAgZGlzYWJsZWRJbmRpY2VzLFxuICAgIGFjdGl2ZUluZGV4OiBleHRlcm5hbEFjdGl2ZUluZGV4LFxuICAgIG9uTmF2aWdhdGU6IGV4dGVybmFsU2V0QWN0aXZlSW5kZXgsXG4gICAgaXRlbVNpemVzLFxuICAgIGRlbnNlID0gZmFsc2UsXG4gICAgLi4uZG9tUHJvcHNcbiAgfSA9IHByb3BzO1xuICBjb25zdCBbaW50ZXJuYWxBY3RpdmVJbmRleCwgaW50ZXJuYWxTZXRBY3RpdmVJbmRleF0gPSBSZWFjdC51c2VTdGF0ZSgwKTtcbiAgY29uc3QgYWN0aXZlSW5kZXggPSBleHRlcm5hbEFjdGl2ZUluZGV4ICE9IG51bGwgPyBleHRlcm5hbEFjdGl2ZUluZGV4IDogaW50ZXJuYWxBY3RpdmVJbmRleDtcbiAgY29uc3Qgb25OYXZpZ2F0ZSA9IHVzZUVmZmVjdEV2ZW50KGV4dGVybmFsU2V0QWN0aXZlSW5kZXggIT0gbnVsbCA/IGV4dGVybmFsU2V0QWN0aXZlSW5kZXggOiBpbnRlcm5hbFNldEFjdGl2ZUluZGV4KTtcbiAgY29uc3QgZWxlbWVudHNSZWYgPSBSZWFjdC51c2VSZWYoW10pO1xuICBjb25zdCByZW5kZXJFbGVtZW50UHJvcHMgPSByZW5kZXIgJiYgdHlwZW9mIHJlbmRlciAhPT0gJ2Z1bmN0aW9uJyA/IHJlbmRlci5wcm9wcyA6IHt9O1xuICBjb25zdCBjb250ZXh0VmFsdWUgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25OYXZpZ2F0ZVxuICB9KSwgW2FjdGl2ZUluZGV4LCBvbk5hdmlnYXRlXSk7XG4gIGNvbnN0IGlzR3JpZCA9IGNvbHMgPiAxO1xuICBmdW5jdGlvbiBoYW5kbGVLZXlEb3duKGV2ZW50KSB7XG4gICAgaWYgKCFhbGxLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSkpIHJldHVybjtcbiAgICBsZXQgbmV4dEluZGV4ID0gYWN0aXZlSW5kZXg7XG4gICAgY29uc3QgbWluSW5kZXggPSBnZXRNaW5JbmRleChlbGVtZW50c1JlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBjb25zdCBtYXhJbmRleCA9IGdldE1heEluZGV4KGVsZW1lbnRzUmVmLCBkaXNhYmxlZEluZGljZXMpO1xuICAgIGlmIChpc0dyaWQpIHtcbiAgICAgIGNvbnN0IHNpemVzID0gaXRlbVNpemVzIHx8IEFycmF5LmZyb20oe1xuICAgICAgICBsZW5ndGg6IGVsZW1lbnRzUmVmLmN1cnJlbnQubGVuZ3RoXG4gICAgICB9LCAoKSA9PiAoe1xuICAgICAgICB3aWR0aDogMSxcbiAgICAgICAgaGVpZ2h0OiAxXG4gICAgICB9KSk7XG4gICAgICAvLyBUbyBjYWxjdWxhdGUgbW92ZW1lbnRzIG9uIHRoZSBncmlkLCB3ZSB1c2UgaHlwb3RoZXRpY2FsIGNlbGwgaW5kaWNlc1xuICAgICAgLy8gYXMgaWYgZXZlcnkgaXRlbSB3YXMgMXgxLCB0aGVuIGNvbnZlcnQgYmFjayB0byByZWFsIGluZGljZXMuXG4gICAgICBjb25zdCBjZWxsTWFwID0gYnVpbGRDZWxsTWFwKHNpemVzLCBjb2xzLCBkZW5zZSk7XG4gICAgICBjb25zdCBtaW5HcmlkSW5kZXggPSBjZWxsTWFwLmZpbmRJbmRleChpbmRleCA9PiBpbmRleCAhPSBudWxsICYmICFpc0Rpc2FibGVkKGVsZW1lbnRzUmVmLmN1cnJlbnQsIGluZGV4LCBkaXNhYmxlZEluZGljZXMpKTtcbiAgICAgIC8vIGxhc3QgZW5hYmxlZCBpbmRleFxuICAgICAgY29uc3QgbWF4R3JpZEluZGV4ID0gY2VsbE1hcC5yZWR1Y2UoKGZvdW5kSW5kZXgsIGluZGV4LCBjZWxsSW5kZXgpID0+IGluZGV4ICE9IG51bGwgJiYgIWlzRGlzYWJsZWQoZWxlbWVudHNSZWYuY3VycmVudCwgaW5kZXgsIGRpc2FibGVkSW5kaWNlcykgPyBjZWxsSW5kZXggOiBmb3VuZEluZGV4LCAtMSk7XG4gICAgICBjb25zdCBtYXliZU5leHRJbmRleCA9IGNlbGxNYXBbZ2V0R3JpZE5hdmlnYXRlZEluZGV4KHtcbiAgICAgICAgY3VycmVudDogY2VsbE1hcC5tYXAoaXRlbUluZGV4ID0+IGl0ZW1JbmRleCA/IGVsZW1lbnRzUmVmLmN1cnJlbnRbaXRlbUluZGV4XSA6IG51bGwpXG4gICAgICB9LCB7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBvcmllbnRhdGlvbixcbiAgICAgICAgbG9vcCxcbiAgICAgICAgY29scyxcbiAgICAgICAgLy8gdHJlYXQgdW5kZWZpbmVkIChlbXB0eSBncmlkIHNwYWNlcykgYXMgZGlzYWJsZWQgaW5kaWNlcyBzbyB3ZVxuICAgICAgICAvLyBkb24ndCBlbmQgdXAgaW4gdGhlbVxuICAgICAgICBkaXNhYmxlZEluZGljZXM6IGdldENlbGxJbmRpY2VzKFsuLi4oZGlzYWJsZWRJbmRpY2VzIHx8IGVsZW1lbnRzUmVmLmN1cnJlbnQubWFwKChfLCBpbmRleCkgPT4gaXNEaXNhYmxlZChlbGVtZW50c1JlZi5jdXJyZW50LCBpbmRleCkgPyBpbmRleCA6IHVuZGVmaW5lZCkpLCB1bmRlZmluZWRdLCBjZWxsTWFwKSxcbiAgICAgICAgbWluSW5kZXg6IG1pbkdyaWRJbmRleCxcbiAgICAgICAgbWF4SW5kZXg6IG1heEdyaWRJbmRleCxcbiAgICAgICAgcHJldkluZGV4OiBnZXRDZWxsSW5kZXhPZkNvcm5lcihhY3RpdmVJbmRleCA+IG1heEluZGV4ID8gbWluSW5kZXggOiBhY3RpdmVJbmRleCwgc2l6ZXMsIGNlbGxNYXAsIGNvbHMsXG4gICAgICAgIC8vIHVzZSBhIGNvcm5lciBtYXRjaGluZyB0aGUgZWRnZSBjbG9zZXN0IHRvIHRoZSBkaXJlY3Rpb24gd2UncmVcbiAgICAgICAgLy8gbW92aW5nIGluIHNvIHdlIGRvbid0IGVuZCB1cCBpbiB0aGUgc2FtZSBpdGVtLiBQcmVmZXJcbiAgICAgICAgLy8gdG9wL2xlZnQgb3ZlciBib3R0b20vcmlnaHQuXG4gICAgICAgIGV2ZW50LmtleSA9PT0gQVJST1dfRE9XTiA/ICdibCcgOiBldmVudC5rZXkgPT09IEFSUk9XX1JJR0hUID8gJ3RyJyA6ICd0bCcpXG4gICAgICB9KV07XG4gICAgICBpZiAobWF5YmVOZXh0SW5kZXggIT0gbnVsbCkge1xuICAgICAgICBuZXh0SW5kZXggPSBtYXliZU5leHRJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG9FbmRLZXlzID0ge1xuICAgICAgaG9yaXpvbnRhbDogW0FSUk9XX1JJR0hUXSxcbiAgICAgIHZlcnRpY2FsOiBbQVJST1dfRE9XTl0sXG4gICAgICBib3RoOiBbQVJST1dfUklHSFQsIEFSUk9XX0RPV05dXG4gICAgfVtvcmllbnRhdGlvbl07XG4gICAgY29uc3QgdG9TdGFydEtleXMgPSB7XG4gICAgICBob3Jpem9udGFsOiBbQVJST1dfTEVGVF0sXG4gICAgICB2ZXJ0aWNhbDogW0FSUk9XX1VQXSxcbiAgICAgIGJvdGg6IFtBUlJPV19MRUZULCBBUlJPV19VUF1cbiAgICB9W29yaWVudGF0aW9uXTtcbiAgICBjb25zdCBwcmV2ZW50ZWRLZXlzID0gaXNHcmlkID8gYWxsS2V5cyA6IHtcbiAgICAgIGhvcml6b250YWw6IGhvcml6b250YWxLZXlzLFxuICAgICAgdmVydGljYWw6IHZlcnRpY2FsS2V5cyxcbiAgICAgIGJvdGg6IGFsbEtleXNcbiAgICB9W29yaWVudGF0aW9uXTtcbiAgICBpZiAobmV4dEluZGV4ID09PSBhY3RpdmVJbmRleCAmJiBbLi4udG9FbmRLZXlzLCAuLi50b1N0YXJ0S2V5c10uaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgaWYgKGxvb3AgJiYgbmV4dEluZGV4ID09PSBtYXhJbmRleCAmJiB0b0VuZEtleXMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAgICBuZXh0SW5kZXggPSBtaW5JbmRleDtcbiAgICAgIH0gZWxzZSBpZiAobG9vcCAmJiBuZXh0SW5kZXggPT09IG1pbkluZGV4ICYmIHRvU3RhcnRLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSkpIHtcbiAgICAgICAgbmV4dEluZGV4ID0gbWF4SW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0SW5kZXggPSBmaW5kTm9uRGlzYWJsZWRJbmRleChlbGVtZW50c1JlZiwge1xuICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IG5leHRJbmRleCxcbiAgICAgICAgICBkZWNyZW1lbnQ6IHRvU3RhcnRLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSksXG4gICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobmV4dEluZGV4ICE9PSBhY3RpdmVJbmRleCAmJiAhaXNJbmRleE91dE9mQm91bmRzKGVsZW1lbnRzUmVmLCBuZXh0SW5kZXgpKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGlmIChwcmV2ZW50ZWRLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIG9uTmF2aWdhdGUobmV4dEluZGV4KTtcblxuICAgICAgLy8gV2FpdCBmb3IgRm9jdXNNYW5hZ2VyIGByZXR1cm5Gb2N1c2AgdG8gZXhlY3V0ZS5cbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgZW5xdWV1ZUZvY3VzKGVsZW1lbnRzUmVmLmN1cnJlbnRbbmV4dEluZGV4XSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgY29uc3QgY29tcHV0ZWRQcm9wcyA9IHtcbiAgICAuLi5kb21Qcm9wcyxcbiAgICAuLi5yZW5kZXJFbGVtZW50UHJvcHMsXG4gICAgcmVmOiBmb3J3YXJkZWRSZWYsXG4gICAgJ2FyaWEtb3JpZW50YXRpb24nOiBvcmllbnRhdGlvbiA9PT0gJ2JvdGgnID8gdW5kZWZpbmVkIDogb3JpZW50YXRpb24sXG4gICAgb25LZXlEb3duKGUpIHtcbiAgICAgIGRvbVByb3BzLm9uS2V5RG93biA9PSBudWxsIHx8IGRvbVByb3BzLm9uS2V5RG93bihlKTtcbiAgICAgIHJlbmRlckVsZW1lbnRQcm9wcy5vbktleURvd24gPT0gbnVsbCB8fCByZW5kZXJFbGVtZW50UHJvcHMub25LZXlEb3duKGUpO1xuICAgICAgaGFuZGxlS2V5RG93bihlKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDb21wb3NpdGVDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IGNvbnRleHRWYWx1ZVxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGbG9hdGluZ0xpc3QsIHtcbiAgICBlbGVtZW50c1JlZjogZWxlbWVudHNSZWZcbiAgfSwgcmVuZGVySnN4KHJlbmRlciwgY29tcHV0ZWRQcm9wcykpKTtcbn0pO1xuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvQ29tcG9zaXRlXG4gKi9cbmNvbnN0IENvbXBvc2l0ZUl0ZW0gPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiBDb21wb3NpdGVJdGVtKHByb3BzLCBmb3J3YXJkZWRSZWYpIHtcbiAgY29uc3Qge1xuICAgIHJlbmRlcixcbiAgICAuLi5kb21Qcm9wc1xuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHJlbmRlckVsZW1lbnRQcm9wcyA9IHJlbmRlciAmJiB0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nID8gcmVuZGVyLnByb3BzIDoge307XG4gIGNvbnN0IHtcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk5hdmlnYXRlXG4gIH0gPSBSZWFjdC51c2VDb250ZXh0KENvbXBvc2l0ZUNvbnRleHQpO1xuICBjb25zdCB7XG4gICAgcmVmLFxuICAgIGluZGV4XG4gIH0gPSB1c2VMaXN0SXRlbSgpO1xuICBjb25zdCBtZXJnZWRSZWYgPSB1c2VNZXJnZVJlZnMoW3JlZiwgZm9yd2FyZGVkUmVmLCByZW5kZXJFbGVtZW50UHJvcHMucmVmXSk7XG4gIGNvbnN0IGlzQWN0aXZlID0gYWN0aXZlSW5kZXggPT09IGluZGV4O1xuICBjb25zdCBjb21wdXRlZFByb3BzID0ge1xuICAgIC4uLmRvbVByb3BzLFxuICAgIC4uLnJlbmRlckVsZW1lbnRQcm9wcyxcbiAgICByZWY6IG1lcmdlZFJlZixcbiAgICB0YWJJbmRleDogaXNBY3RpdmUgPyAwIDogLTEsXG4gICAgJ2RhdGEtYWN0aXZlJzogaXNBY3RpdmUgPyAnJyA6IHVuZGVmaW5lZCxcbiAgICBvbkZvY3VzKGUpIHtcbiAgICAgIGRvbVByb3BzLm9uRm9jdXMgPT0gbnVsbCB8fCBkb21Qcm9wcy5vbkZvY3VzKGUpO1xuICAgICAgcmVuZGVyRWxlbWVudFByb3BzLm9uRm9jdXMgPT0gbnVsbCB8fCByZW5kZXJFbGVtZW50UHJvcHMub25Gb2N1cyhlKTtcbiAgICAgIG9uTmF2aWdhdGUoaW5kZXgpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJlbmRlckpzeChyZW5kZXIsIGNvbXB1dGVkUHJvcHMpO1xufSk7XG5cbmZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gPyBPYmplY3QuYXNzaWduLmJpbmQoKSA6IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG4gIHJldHVybiBfZXh0ZW5kcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5sZXQgc2VydmVySGFuZG9mZkNvbXBsZXRlID0gZmFsc2U7XG5sZXQgY291bnQgPSAwO1xuY29uc3QgZ2VuSWQgPSAoKSA9PiAvLyBFbnN1cmUgdGhlIGlkIGlzIHVuaXF1ZSB3aXRoIG11bHRpcGxlIGluZGVwZW5kZW50IHZlcnNpb25zIG9mIEZsb2F0aW5nIFVJXG4vLyBvbiA8UmVhY3QgMThcblwiZmxvYXRpbmctdWktXCIgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA2KSArIGNvdW50Kys7XG5mdW5jdGlvbiB1c2VGbG9hdGluZ0lkKCkge1xuICBjb25zdCBbaWQsIHNldElkXSA9IFJlYWN0LnVzZVN0YXRlKCgpID0+IHNlcnZlckhhbmRvZmZDb21wbGV0ZSA/IGdlbklkKCkgOiB1bmRlZmluZWQpO1xuICBpbmRleCgoKSA9PiB7XG4gICAgaWYgKGlkID09IG51bGwpIHtcbiAgICAgIHNldElkKGdlbklkKCkpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBzZXJ2ZXJIYW5kb2ZmQ29tcGxldGUgPSB0cnVlO1xuICB9LCBbXSk7XG4gIHJldHVybiBpZDtcbn1cbmNvbnN0IHVzZVJlYWN0SWQgPSBTYWZlUmVhY3QudXNlSWQ7XG5cbi8qKlxuICogVXNlcyBSZWFjdCAxOCdzIGJ1aWx0LWluIGB1c2VJZCgpYCB3aGVuIGF2YWlsYWJsZSwgb3IgZmFsbHMgYmFjayB0byBhXG4gKiBzbGlnaHRseSBsZXNzIHBlcmZvcm1hbnQgKHJlcXVpcmluZyBhIGRvdWJsZSByZW5kZXIpIGltcGxlbWVudGF0aW9uIGZvclxuICogZWFybGllciBSZWFjdCB2ZXJzaW9ucy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9yZWFjdC11dGlscyN1c2VpZFxuICovXG5jb25zdCB1c2VJZCA9IHVzZVJlYWN0SWQgfHwgdXNlRmxvYXRpbmdJZDtcblxubGV0IGRldk1lc3NhZ2VTZXQ7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gIGRldk1lc3NhZ2VTZXQgPSAvKiNfX1BVUkVfXyovbmV3IFNldCgpO1xufVxuZnVuY3Rpb24gd2FybigpIHtcbiAgdmFyIF9kZXZNZXNzYWdlU2V0O1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgbWVzc2FnZXMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgbWVzc2FnZXNbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cbiAgY29uc3QgbWVzc2FnZSA9IFwiRmxvYXRpbmcgVUk6IFwiICsgbWVzc2FnZXMuam9pbignICcpO1xuICBpZiAoISgoX2Rldk1lc3NhZ2VTZXQgPSBkZXZNZXNzYWdlU2V0KSAhPSBudWxsICYmIF9kZXZNZXNzYWdlU2V0LmhhcyhtZXNzYWdlKSkpIHtcbiAgICB2YXIgX2Rldk1lc3NhZ2VTZXQyO1xuICAgIChfZGV2TWVzc2FnZVNldDIgPSBkZXZNZXNzYWdlU2V0KSA9PSBudWxsIHx8IF9kZXZNZXNzYWdlU2V0Mi5hZGQobWVzc2FnZSk7XG4gICAgY29uc29sZS53YXJuKG1lc3NhZ2UpO1xuICB9XG59XG5mdW5jdGlvbiBlcnJvcigpIHtcbiAgdmFyIF9kZXZNZXNzYWdlU2V0MztcbiAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBtZXNzYWdlcyA9IG5ldyBBcnJheShfbGVuMiksIF9rZXkyID0gMDsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgIG1lc3NhZ2VzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gIH1cbiAgY29uc3QgbWVzc2FnZSA9IFwiRmxvYXRpbmcgVUk6IFwiICsgbWVzc2FnZXMuam9pbignICcpO1xuICBpZiAoISgoX2Rldk1lc3NhZ2VTZXQzID0gZGV2TWVzc2FnZVNldCkgIT0gbnVsbCAmJiBfZGV2TWVzc2FnZVNldDMuaGFzKG1lc3NhZ2UpKSkge1xuICAgIHZhciBfZGV2TWVzc2FnZVNldDQ7XG4gICAgKF9kZXZNZXNzYWdlU2V0NCA9IGRldk1lc3NhZ2VTZXQpID09IG51bGwgfHwgX2Rldk1lc3NhZ2VTZXQ0LmFkZChtZXNzYWdlKTtcbiAgICBjb25zb2xlLmVycm9yKG1lc3NhZ2UpO1xuICB9XG59XG5cbi8qKlxuICogUmVuZGVycyBhIHBvaW50aW5nIGFycm93IHRyaWFuZ2xlLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nQXJyb3dcbiAqL1xuY29uc3QgRmxvYXRpbmdBcnJvdyA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIEZsb2F0aW5nQXJyb3cocHJvcHMsIHJlZikge1xuICBjb25zdCB7XG4gICAgY29udGV4dDoge1xuICAgICAgcGxhY2VtZW50LFxuICAgICAgZWxlbWVudHM6IHtcbiAgICAgICAgZmxvYXRpbmdcbiAgICAgIH0sXG4gICAgICBtaWRkbGV3YXJlRGF0YToge1xuICAgICAgICBhcnJvdyxcbiAgICAgICAgc2hpZnRcbiAgICAgIH1cbiAgICB9LFxuICAgIHdpZHRoID0gMTQsXG4gICAgaGVpZ2h0ID0gNyxcbiAgICB0aXBSYWRpdXMgPSAwLFxuICAgIHN0cm9rZVdpZHRoID0gMCxcbiAgICBzdGF0aWNPZmZzZXQsXG4gICAgc3Ryb2tlLFxuICAgIGQsXG4gICAgc3R5bGU6IHtcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIC4uLnJlc3RTdHlsZVxuICAgIH0gPSB7fSxcbiAgICAuLi5yZXN0XG4gIH0gPSBwcm9wcztcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgIGlmICghcmVmKSB7XG4gICAgICB3YXJuKCdUaGUgYHJlZmAgcHJvcCBpcyByZXF1aXJlZCBmb3IgYEZsb2F0aW5nQXJyb3dgLicpO1xuICAgIH1cbiAgfVxuICBjb25zdCBjbGlwUGF0aElkID0gdXNlSWQoKTtcbiAgY29uc3QgW2lzUlRMLCBzZXRJc1JUTF0gPSBSZWFjdC51c2VTdGF0ZShmYWxzZSk7XG5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yOTMyXG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoIWZsb2F0aW5nKSByZXR1cm47XG4gICAgY29uc3QgaXNSVEwgPSBnZXRDb21wdXRlZFN0eWxlKGZsb2F0aW5nKS5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIGlmIChpc1JUTCkge1xuICAgICAgc2V0SXNSVEwodHJ1ZSk7XG4gICAgfVxuICB9LCBbZmxvYXRpbmddKTtcbiAgaWYgKCFmbG9hdGluZykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IFtzaWRlLCBhbGlnbm1lbnRdID0gcGxhY2VtZW50LnNwbGl0KCctJyk7XG4gIGNvbnN0IGlzVmVydGljYWxTaWRlID0gc2lkZSA9PT0gJ3RvcCcgfHwgc2lkZSA9PT0gJ2JvdHRvbSc7XG4gIGxldCBjb21wdXRlZFN0YXRpY09mZnNldCA9IHN0YXRpY09mZnNldDtcbiAgaWYgKGlzVmVydGljYWxTaWRlICYmIHNoaWZ0ICE9IG51bGwgJiYgc2hpZnQueCB8fCAhaXNWZXJ0aWNhbFNpZGUgJiYgc2hpZnQgIT0gbnVsbCAmJiBzaGlmdC55KSB7XG4gICAgY29tcHV0ZWRTdGF0aWNPZmZzZXQgPSBudWxsO1xuICB9XG5cbiAgLy8gU3Ryb2tlcyBtdXN0IGJlIGRvdWJsZSB0aGUgYm9yZGVyIHdpZHRoLCB0aGlzIGVuc3VyZXMgdGhlIHN0cm9rZSdzIHdpZHRoXG4gIC8vIHdvcmtzIGFzIHlvdSdkIGV4cGVjdC5cbiAgY29uc3QgY29tcHV0ZWRTdHJva2VXaWR0aCA9IHN0cm9rZVdpZHRoICogMjtcbiAgY29uc3QgaGFsZlN0cm9rZVdpZHRoID0gY29tcHV0ZWRTdHJva2VXaWR0aCAvIDI7XG4gIGNvbnN0IHN2Z1ggPSB3aWR0aCAvIDIgKiAodGlwUmFkaXVzIC8gLTggKyAxKTtcbiAgY29uc3Qgc3ZnWSA9IGhlaWdodCAvIDIgKiB0aXBSYWRpdXMgLyA0O1xuICBjb25zdCBpc0N1c3RvbVNoYXBlID0gISFkO1xuICBjb25zdCB5T2Zmc2V0UHJvcCA9IGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGFsaWdubWVudCA9PT0gJ2VuZCcgPyAnYm90dG9tJyA6ICd0b3AnO1xuICBsZXQgeE9mZnNldFByb3AgPSBjb21wdXRlZFN0YXRpY09mZnNldCAmJiBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgaWYgKGNvbXB1dGVkU3RhdGljT2Zmc2V0ICYmIGlzUlRMKSB7XG4gICAgeE9mZnNldFByb3AgPSBhbGlnbm1lbnQgPT09ICdlbmQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgfVxuICBjb25zdCBhcnJvd1ggPSAoYXJyb3cgPT0gbnVsbCA/IHZvaWQgMCA6IGFycm93LngpICE9IG51bGwgPyBjb21wdXRlZFN0YXRpY09mZnNldCB8fCBhcnJvdy54IDogJyc7XG4gIGNvbnN0IGFycm93WSA9IChhcnJvdyA9PSBudWxsID8gdm9pZCAwIDogYXJyb3cueSkgIT0gbnVsbCA/IGNvbXB1dGVkU3RhdGljT2Zmc2V0IHx8IGFycm93LnkgOiAnJztcbiAgY29uc3QgZFZhbHVlID0gZCB8fCAnTTAsMCcgKyAoXCIgSFwiICsgd2lkdGgpICsgKFwiIExcIiArICh3aWR0aCAtIHN2Z1gpICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgKFwiIFFcIiArIHdpZHRoIC8gMiArIFwiLFwiICsgaGVpZ2h0ICsgXCIgXCIgKyBzdmdYICsgXCIsXCIgKyAoaGVpZ2h0IC0gc3ZnWSkpICsgJyBaJztcbiAgY29uc3Qgcm90YXRpb24gPSB7XG4gICAgdG9wOiBpc0N1c3RvbVNoYXBlID8gJ3JvdGF0ZSgxODBkZWcpJyA6ICcnLFxuICAgIGxlZnQ6IGlzQ3VzdG9tU2hhcGUgPyAncm90YXRlKDkwZGVnKScgOiAncm90YXRlKC05MGRlZyknLFxuICAgIGJvdHRvbTogaXNDdXN0b21TaGFwZSA/ICcnIDogJ3JvdGF0ZSgxODBkZWcpJyxcbiAgICByaWdodDogaXNDdXN0b21TaGFwZSA/ICdyb3RhdGUoLTkwZGVnKScgOiAncm90YXRlKDkwZGVnKSdcbiAgfVtzaWRlXTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwic3ZnXCIsIF9leHRlbmRzKHt9LCByZXN0LCB7XG4gICAgXCJhcmlhLWhpZGRlblwiOiB0cnVlLFxuICAgIHJlZjogcmVmLFxuICAgIHdpZHRoOiBpc0N1c3RvbVNoYXBlID8gd2lkdGggOiB3aWR0aCArIGNvbXB1dGVkU3Ryb2tlV2lkdGgsXG4gICAgaGVpZ2h0OiB3aWR0aCxcbiAgICB2aWV3Qm94OiBcIjAgMCBcIiArIHdpZHRoICsgXCIgXCIgKyAoaGVpZ2h0ID4gd2lkdGggPyBoZWlnaHQgOiB3aWR0aCksXG4gICAgc3R5bGU6IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgICAgW3hPZmZzZXRQcm9wXTogYXJyb3dYLFxuICAgICAgW3lPZmZzZXRQcm9wXTogYXJyb3dZLFxuICAgICAgW3NpZGVdOiBpc1ZlcnRpY2FsU2lkZSB8fCBpc0N1c3RvbVNoYXBlID8gJzEwMCUnIDogXCJjYWxjKDEwMCUgLSBcIiArIGNvbXB1dGVkU3Ryb2tlV2lkdGggLyAyICsgXCJweClcIixcbiAgICAgIHRyYW5zZm9ybTogXCJcIiArIHJvdGF0aW9uICsgKHRyYW5zZm9ybSAhPSBudWxsID8gdHJhbnNmb3JtIDogJycpLFxuICAgICAgLi4ucmVzdFN0eWxlXG4gICAgfVxuICB9KSwgY29tcHV0ZWRTdHJva2VXaWR0aCA+IDAgJiYgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwYXRoXCIsIHtcbiAgICBjbGlwUGF0aDogXCJ1cmwoI1wiICsgY2xpcFBhdGhJZCArIFwiKVwiLFxuICAgIGZpbGw6IFwibm9uZVwiLFxuICAgIHN0cm9rZTogc3Ryb2tlXG4gICAgLy8gQWNjb3VudCBmb3IgdGhlIHN0cm9rZSBvbiB0aGUgZmlsbCBwYXRoIHJlbmRlcmVkIGJlbG93LlxuICAgICxcbiAgICBzdHJva2VXaWR0aDogY29tcHV0ZWRTdHJva2VXaWR0aCArIChkID8gMCA6IDEpLFxuICAgIGQ6IGRWYWx1ZVxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwYXRoXCIsIHtcbiAgICBzdHJva2U6IGNvbXB1dGVkU3Ryb2tlV2lkdGggJiYgIWQgPyByZXN0LmZpbGwgOiAnbm9uZScsXG4gICAgZDogZFZhbHVlXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImNsaXBQYXRoXCIsIHtcbiAgICBpZDogY2xpcFBhdGhJZFxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcInJlY3RcIiwge1xuICAgIHg6IC1oYWxmU3Ryb2tlV2lkdGgsXG4gICAgeTogaGFsZlN0cm9rZVdpZHRoICogKGlzQ3VzdG9tU2hhcGUgPyAtMSA6IDEpLFxuICAgIHdpZHRoOiB3aWR0aCArIGNvbXB1dGVkU3Ryb2tlV2lkdGgsXG4gICAgaGVpZ2h0OiB3aWR0aFxuICB9KSkpO1xufSk7XG5cbmZ1bmN0aW9uIGNyZWF0ZVB1YlN1YigpIHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcCgpO1xuICByZXR1cm4ge1xuICAgIGVtaXQoZXZlbnQsIGRhdGEpIHtcbiAgICAgIHZhciBfbWFwJGdldDtcbiAgICAgIChfbWFwJGdldCA9IG1hcC5nZXQoZXZlbnQpKSA9PSBudWxsIHx8IF9tYXAkZ2V0LmZvckVhY2goaGFuZGxlciA9PiBoYW5kbGVyKGRhdGEpKTtcbiAgICB9LFxuICAgIG9uKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgICAgbWFwLnNldChldmVudCwgWy4uLihtYXAuZ2V0KGV2ZW50KSB8fCBbXSksIGxpc3RlbmVyXSk7XG4gICAgfSxcbiAgICBvZmYoZXZlbnQsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgX21hcCRnZXQyO1xuICAgICAgbWFwLnNldChldmVudCwgKChfbWFwJGdldDIgPSBtYXAuZ2V0KGV2ZW50KSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9tYXAkZ2V0Mi5maWx0ZXIobCA9PiBsICE9PSBsaXN0ZW5lcikpIHx8IFtdKTtcbiAgICB9XG4gIH07XG59XG5cbmNvbnN0IEZsb2F0aW5nTm9kZUNvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dChudWxsKTtcbmNvbnN0IEZsb2F0aW5nVHJlZUNvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dChudWxsKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwYXJlbnQgbm9kZSBpZCBmb3IgbmVzdGVkIGZsb2F0aW5nIGVsZW1lbnRzLCBpZiBhdmFpbGFibGUuXG4gKiBSZXR1cm5zIGBudWxsYCBmb3IgdG9wLWxldmVsIGZsb2F0aW5nIGVsZW1lbnRzLlxuICovXG5jb25zdCB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCA9ICgpID0+IHtcbiAgdmFyIF9SZWFjdCR1c2VDb250ZXh0O1xuICByZXR1cm4gKChfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdOb2RlQ29udGV4dCkpID09IG51bGwgPyB2b2lkIDAgOiBfUmVhY3QkdXNlQ29udGV4dC5pZCkgfHwgbnVsbDtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbmVhcmVzdCBmbG9hdGluZyB0cmVlIGNvbnRleHQsIGlmIGF2YWlsYWJsZS5cbiAqL1xuY29uc3QgdXNlRmxvYXRpbmdUcmVlID0gKCkgPT4gUmVhY3QudXNlQ29udGV4dChGbG9hdGluZ1RyZWVDb250ZXh0KTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBub2RlIGludG8gdGhlIGBGbG9hdGluZ1RyZWVgLCByZXR1cm5pbmcgaXRzIGlkLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nVHJlZVxuICovXG5mdW5jdGlvbiB1c2VGbG9hdGluZ05vZGVJZChjdXN0b21QYXJlbnRJZCkge1xuICBjb25zdCBpZCA9IHVzZUlkKCk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgY29uc3QgcmVhY3RQYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIGNvbnN0IHBhcmVudElkID0gY3VzdG9tUGFyZW50SWQgfHwgcmVhY3RQYXJlbnRJZDtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICBpZCxcbiAgICAgIHBhcmVudElkXG4gICAgfTtcbiAgICB0cmVlID09IG51bGwgfHwgdHJlZS5hZGROb2RlKG5vZGUpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5yZW1vdmVOb2RlKG5vZGUpO1xuICAgIH07XG4gIH0sIFt0cmVlLCBpZCwgcGFyZW50SWRdKTtcbiAgcmV0dXJuIGlkO1xufVxuLyoqXG4gKiBQcm92aWRlcyBwYXJlbnQgbm9kZSBjb250ZXh0IGZvciBuZXN0ZWQgZmxvYXRpbmcgZWxlbWVudHMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdUcmVlXG4gKi9cbmZ1bmN0aW9uIEZsb2F0aW5nTm9kZShwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgaWRcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGbG9hdGluZ05vZGVDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICAgIGlkLFxuICAgICAgcGFyZW50SWRcbiAgICB9KSwgW2lkLCBwYXJlbnRJZF0pXG4gIH0sIGNoaWxkcmVuKTtcbn1cbi8qKlxuICogUHJvdmlkZXMgY29udGV4dCBmb3IgbmVzdGVkIGZsb2F0aW5nIGVsZW1lbnRzIHdoZW4gdGhleSBhcmUgbm90IGNoaWxkcmVuIG9mXG4gKiBlYWNoIG90aGVyIG9uIHRoZSBET00uXG4gKiBUaGlzIGlzIG5vdCBuZWNlc3NhcnkgaW4gYWxsIGNhc2VzLCBleGNlcHQgd2hlbiB0aGVyZSBtdXN0IGJlIGV4cGxpY2l0IGNvbW11bmljYXRpb24gYmV0d2VlbiBwYXJlbnQgYW5kIGNoaWxkIGZsb2F0aW5nIGVsZW1lbnRzLiBJdCBpcyBuZWNlc3NhcnkgZm9yOlxuICogLSBUaGUgYGJ1YmJsZXNgIG9wdGlvbiBpbiB0aGUgYHVzZURpc21pc3MoKWAgSG9va1xuICogLSBOZXN0ZWQgdmlydHVhbCBsaXN0IG5hdmlnYXRpb25cbiAqIC0gTmVzdGVkIGZsb2F0aW5nIGVsZW1lbnRzIHRoYXQgZWFjaCBvcGVuIG9uIGhvdmVyXG4gKiAtIEN1c3RvbSBjb21tdW5pY2F0aW9uIGJldHdlZW4gcGFyZW50IGFuZCBjaGlsZCBmbG9hdGluZyBlbGVtZW50c1xuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL0Zsb2F0aW5nVHJlZVxuICovXG5mdW5jdGlvbiBGbG9hdGluZ1RyZWUocHJvcHMpIHtcbiAgY29uc3Qge1xuICAgIGNoaWxkcmVuXG4gIH0gPSBwcm9wcztcbiAgY29uc3Qgbm9kZXNSZWYgPSBSZWFjdC51c2VSZWYoW10pO1xuICBjb25zdCBhZGROb2RlID0gUmVhY3QudXNlQ2FsbGJhY2sobm9kZSA9PiB7XG4gICAgbm9kZXNSZWYuY3VycmVudCA9IFsuLi5ub2Rlc1JlZi5jdXJyZW50LCBub2RlXTtcbiAgfSwgW10pO1xuICBjb25zdCByZW1vdmVOb2RlID0gUmVhY3QudXNlQ2FsbGJhY2sobm9kZSA9PiB7XG4gICAgbm9kZXNSZWYuY3VycmVudCA9IG5vZGVzUmVmLmN1cnJlbnQuZmlsdGVyKG4gPT4gbiAhPT0gbm9kZSk7XG4gIH0sIFtdKTtcbiAgY29uc3QgZXZlbnRzID0gUmVhY3QudXNlU3RhdGUoKCkgPT4gY3JlYXRlUHViU3ViKCkpWzBdO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRmxvYXRpbmdUcmVlQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICBub2Rlc1JlZixcbiAgICAgIGFkZE5vZGUsXG4gICAgICByZW1vdmVOb2RlLFxuICAgICAgZXZlbnRzXG4gICAgfSksIFthZGROb2RlLCByZW1vdmVOb2RlLCBldmVudHNdKVxuICB9LCBjaGlsZHJlbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF0dHJpYnV0ZShuYW1lKSB7XG4gIHJldHVybiBcImRhdGEtZmxvYXRpbmctdWktXCIgKyBuYW1lO1xufVxuXG5mdW5jdGlvbiB1c2VMYXRlc3RSZWYodmFsdWUpIHtcbiAgY29uc3QgcmVmID0gdXNlUmVmKHZhbHVlKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIHJlZi5jdXJyZW50ID0gdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gcmVmO1xufVxuXG5jb25zdCBzYWZlUG9seWdvbklkZW50aWZpZXIgPSAvKiNfX1BVUkVfXyovY3JlYXRlQXR0cmlidXRlKCdzYWZlLXBvbHlnb24nKTtcbmZ1bmN0aW9uIGdldERlbGF5KHZhbHVlLCBwcm9wLCBwb2ludGVyVHlwZSkge1xuICBpZiAocG9pbnRlclR5cGUgJiYgIWlzTW91c2VMaWtlUG9pbnRlclR5cGUocG9pbnRlclR5cGUpKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09IG51bGwgPyB2b2lkIDAgOiB2YWx1ZVtwcm9wXTtcbn1cbi8qKlxuICogT3BlbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2hpbGUgaG92ZXJpbmcgb3ZlciB0aGUgcmVmZXJlbmNlIGVsZW1lbnQsIGxpa2VcbiAqIENTUyBgOmhvdmVyYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VIb3ZlclxuICovXG5mdW5jdGlvbiB1c2VIb3Zlcihjb250ZXh0LCBwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGRhdGFSZWYsXG4gICAgZXZlbnRzLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZGVsYXkgPSAwLFxuICAgIGhhbmRsZUNsb3NlID0gbnVsbCxcbiAgICBtb3VzZU9ubHkgPSBmYWxzZSxcbiAgICByZXN0TXMgPSAwLFxuICAgIG1vdmUgPSB0cnVlXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgdHJlZSA9IHVzZUZsb2F0aW5nVHJlZSgpO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIGNvbnN0IGhhbmRsZUNsb3NlUmVmID0gdXNlTGF0ZXN0UmVmKGhhbmRsZUNsb3NlKTtcbiAgY29uc3QgZGVsYXlSZWYgPSB1c2VMYXRlc3RSZWYoZGVsYXkpO1xuICBjb25zdCBvcGVuUmVmID0gdXNlTGF0ZXN0UmVmKG9wZW4pO1xuICBjb25zdCBwb2ludGVyVHlwZVJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBjb25zdCB0aW1lb3V0UmVmID0gUmVhY3QudXNlUmVmKC0xKTtcbiAgY29uc3QgaGFuZGxlclJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBjb25zdCByZXN0VGltZW91dFJlZiA9IFJlYWN0LnVzZVJlZigtMSk7XG4gIGNvbnN0IGJsb2NrTW91c2VNb3ZlUmVmID0gUmVhY3QudXNlUmVmKHRydWUpO1xuICBjb25zdCBwZXJmb3JtZWRQb2ludGVyRXZlbnRzTXV0YXRpb25SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCB1bmJpbmRNb3VzZU1vdmVSZWYgPSBSZWFjdC51c2VSZWYoKCkgPT4ge30pO1xuICBjb25zdCBpc0hvdmVyT3BlbiA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRvcGVuO1xuICAgIGNvbnN0IHR5cGUgPSAoX2RhdGFSZWYkY3VycmVudCRvcGVuID0gZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9kYXRhUmVmJGN1cnJlbnQkb3Blbi50eXBlO1xuICAgIHJldHVybiAodHlwZSA9PSBudWxsID8gdm9pZCAwIDogdHlwZS5pbmNsdWRlcygnbW91c2UnKSkgJiYgdHlwZSAhPT0gJ21vdXNlZG93bic7XG4gIH0sIFtkYXRhUmVmXSk7XG5cbiAgLy8gV2hlbiBjbG9zaW5nIGJlZm9yZSBvcGVuaW5nLCBjbGVhciB0aGUgZGVsYXkgdGltZW91dHMgdG8gY2FuY2VsIGl0XG4gIC8vIGZyb20gc2hvd2luZy5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBvbk9wZW5DaGFuZ2UoX3JlZikge1xuICAgICAgbGV0IHtcbiAgICAgICAgb3BlblxuICAgICAgfSA9IF9yZWY7XG4gICAgICBpZiAoIW9wZW4pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICAgIGNsZWFyVGltZW91dChyZXN0VGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgICAgYmxvY2tNb3VzZU1vdmVSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGV2ZW50cy5vbignb3BlbmNoYW5nZScsIG9uT3BlbkNoYW5nZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGV2ZW50cy5vZmYoJ29wZW5jaGFuZ2UnLCBvbk9wZW5DaGFuZ2UpO1xuICAgIH07XG4gIH0sIFtlbmFibGVkLCBldmVudHNdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIWhhbmRsZUNsb3NlUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBpZiAoIW9wZW4pIHJldHVybjtcbiAgICBmdW5jdGlvbiBvbkxlYXZlKGV2ZW50KSB7XG4gICAgICBpZiAoaXNIb3Zlck9wZW4oKSkge1xuICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCAnaG92ZXInKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaHRtbCA9IGdldERvY3VtZW50KGVsZW1lbnRzLmZsb2F0aW5nKS5kb2N1bWVudEVsZW1lbnQ7XG4gICAgaHRtbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25MZWF2ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGh0bWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIG9uTGVhdmUpO1xuICAgIH07XG4gIH0sIFtlbGVtZW50cy5mbG9hdGluZywgb3Blbiwgb25PcGVuQ2hhbmdlLCBlbmFibGVkLCBoYW5kbGVDbG9zZVJlZiwgaXNIb3Zlck9wZW5dKTtcbiAgY29uc3QgY2xvc2VXaXRoRGVsYXkgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoZXZlbnQsIHJ1bkVsc2VCcmFuY2gsIHJlYXNvbikge1xuICAgIGlmIChydW5FbHNlQnJhbmNoID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkVsc2VCcmFuY2ggPSB0cnVlO1xuICAgIH1cbiAgICBpZiAocmVhc29uID09PSB2b2lkIDApIHtcbiAgICAgIHJlYXNvbiA9ICdob3Zlcic7XG4gICAgfVxuICAgIGNvbnN0IGNsb3NlRGVsYXkgPSBnZXREZWxheShkZWxheVJlZi5jdXJyZW50LCAnY2xvc2UnLCBwb2ludGVyVHlwZVJlZi5jdXJyZW50KTtcbiAgICBpZiAoY2xvc2VEZWxheSAmJiAhaGFuZGxlclJlZi5jdXJyZW50KSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgIHRpbWVvdXRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsIHJlYXNvbiksIGNsb3NlRGVsYXkpO1xuICAgIH0gZWxzZSBpZiAocnVuRWxzZUJyYW5jaCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCByZWFzb24pO1xuICAgIH1cbiAgfSwgW2RlbGF5UmVmLCBvbk9wZW5DaGFuZ2VdKTtcbiAgY29uc3QgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgdW5iaW5kTW91c2VNb3ZlUmVmLmN1cnJlbnQoKTtcbiAgICBoYW5kbGVyUmVmLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gIH0pO1xuICBjb25zdCBjbGVhclBvaW50ZXJFdmVudHMgPSB1c2VFZmZlY3RFdmVudCgoKSA9PiB7XG4gICAgaWYgKHBlcmZvcm1lZFBvaW50ZXJFdmVudHNNdXRhdGlvblJlZi5jdXJyZW50KSB7XG4gICAgICBjb25zdCBib2R5ID0gZ2V0RG9jdW1lbnQoZWxlbWVudHMuZmxvYXRpbmcpLmJvZHk7XG4gICAgICBib2R5LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnJztcbiAgICAgIGJvZHkucmVtb3ZlQXR0cmlidXRlKHNhZmVQb2x5Z29uSWRlbnRpZmllcik7XG4gICAgICBwZXJmb3JtZWRQb2ludGVyRXZlbnRzTXV0YXRpb25SZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXJpbmcgdGhlIG1vdXNlIGV2ZW50cyBvbiB0aGUgcmVmZXJlbmNlIGRpcmVjdGx5IHRvIGJ5cGFzcyBSZWFjdCdzXG4gIC8vIGRlbGVnYXRpb24gc3lzdGVtLiBJZiB0aGUgY3Vyc29yIHdhcyBvbiBhIGRpc2FibGVkIGVsZW1lbnQgYW5kIHRoZW4gZW50ZXJlZFxuICAvLyB0aGUgcmVmZXJlbmNlIChubyBnYXApLCBgbW91c2VlbnRlcmAgZG9lc24ndCBmaXJlIGluIHRoZSBkZWxlZ2F0aW9uIHN5c3RlbS5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBpc0NsaWNrTGlrZU9wZW5FdmVudCgpIHtcbiAgICAgIHJldHVybiBkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50ID8gWydjbGljaycsICdtb3VzZWRvd24nXS5pbmNsdWRlcyhkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50LnR5cGUpIDogZmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uTW91c2VFbnRlcihldmVudCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBibG9ja01vdXNlTW92ZVJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBpZiAobW91c2VPbmx5ICYmICFpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQpIHx8IHJlc3RNcyA+IDAgJiYgIWdldERlbGF5KGRlbGF5UmVmLmN1cnJlbnQsICdvcGVuJykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3BlbkRlbGF5ID0gZ2V0RGVsYXkoZGVsYXlSZWYuY3VycmVudCwgJ29wZW4nLCBwb2ludGVyVHlwZVJlZi5jdXJyZW50KTtcbiAgICAgIGlmIChvcGVuRGVsYXkpIHtcbiAgICAgICAgdGltZW91dFJlZi5jdXJyZW50ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlmICghb3BlblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQsICdob3ZlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgb3BlbkRlbGF5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uT3BlbkNoYW5nZSh0cnVlLCBldmVudCwgJ2hvdmVyJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uTW91c2VMZWF2ZShldmVudCkge1xuICAgICAgaWYgKGlzQ2xpY2tMaWtlT3BlbkV2ZW50KCkpIHJldHVybjtcbiAgICAgIHVuYmluZE1vdXNlTW92ZVJlZi5jdXJyZW50KCk7XG4gICAgICBjb25zdCBkb2MgPSBnZXREb2N1bWVudChlbGVtZW50cy5mbG9hdGluZyk7XG4gICAgICBjbGVhclRpbWVvdXQocmVzdFRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBpZiAoaGFuZGxlQ2xvc2VSZWYuY3VycmVudCAmJiBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSB7XG4gICAgICAgIC8vIFByZXZlbnQgY2xlYXJpbmcgYG9uU2Nyb2xsTW91c2VMZWF2ZWAgdGltZW91dC5cbiAgICAgICAgaWYgKCFvcGVuKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaGFuZGxlclJlZi5jdXJyZW50ID0gaGFuZGxlQ2xvc2VSZWYuY3VycmVudCh7XG4gICAgICAgICAgLi4uZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCxcbiAgICAgICAgICB0cmVlLFxuICAgICAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgICAgeTogZXZlbnQuY2xpZW50WSxcbiAgICAgICAgICBvbkNsb3NlKCkge1xuICAgICAgICAgICAgY2xlYXJQb2ludGVyRXZlbnRzKCk7XG4gICAgICAgICAgICBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlcigpO1xuICAgICAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQsIHRydWUsICdzYWZlLXBvbHlnb24nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gaGFuZGxlclJlZi5jdXJyZW50O1xuICAgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgaGFuZGxlcik7XG4gICAgICAgIHVuYmluZE1vdXNlTW92ZVJlZi5jdXJyZW50ID0gKCkgPT4ge1xuICAgICAgICAgIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVyKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBBbGxvdyBpbnRlcmFjdGl2aXR5IHdpdGhvdXQgYHNhZmVQb2x5Z29uYCBvbiB0b3VjaCBkZXZpY2VzLiBXaXRoIGFcbiAgICAgIC8vIHBvaW50ZXIsIGEgc2hvcnQgY2xvc2UgZGVsYXkgaXMgYW4gYWx0ZXJuYXRpdmUsIHNvIGl0IHNob3VsZCB3b3JrXG4gICAgICAvLyBjb25zaXN0ZW50bHkuXG4gICAgICBjb25zdCBzaG91bGRDbG9zZSA9IHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPT09ICd0b3VjaCcgPyAhY29udGFpbnMoZWxlbWVudHMuZmxvYXRpbmcsIGV2ZW50LnJlbGF0ZWRUYXJnZXQpIDogdHJ1ZTtcbiAgICAgIGlmIChzaG91bGRDbG9zZSkge1xuICAgICAgICBjbG9zZVdpdGhEZWxheShldmVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIHRoZSBmbG9hdGluZyBlbGVtZW50IGNsb3NlcyBhZnRlciBzY3JvbGxpbmcgZXZlbiBpZiB0aGUgcG9pbnRlclxuICAgIC8vIGRpZCBub3QgbW92ZS5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvZGlzY3Vzc2lvbnMvMTY5MlxuICAgIGZ1bmN0aW9uIG9uU2Nyb2xsTW91c2VMZWF2ZShldmVudCkge1xuICAgICAgaWYgKGlzQ2xpY2tMaWtlT3BlbkV2ZW50KCkpIHJldHVybjtcbiAgICAgIGlmICghZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCkgcmV0dXJuO1xuICAgICAgaGFuZGxlQ2xvc2VSZWYuY3VycmVudCA9PSBudWxsIHx8IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQoe1xuICAgICAgICAuLi5kYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0LFxuICAgICAgICB0cmVlLFxuICAgICAgICB4OiBldmVudC5jbGllbnRYLFxuICAgICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgICAgICBvbkNsb3NlKCkge1xuICAgICAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgICAgICAgIGNsZWFudXBNb3VzZU1vdmVIYW5kbGVyKCk7XG4gICAgICAgICAgY2xvc2VXaXRoRGVsYXkoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9KShldmVudCk7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZG9tUmVmZXJlbmNlKSkge1xuICAgICAgdmFyIF9lbGVtZW50cyRmbG9hdGluZztcbiAgICAgIGNvbnN0IHJlZiA9IGVsZW1lbnRzLmRvbVJlZmVyZW5jZTtcbiAgICAgIG9wZW4gJiYgcmVmLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblNjcm9sbE1vdXNlTGVhdmUpO1xuICAgICAgKF9lbGVtZW50cyRmbG9hdGluZyA9IGVsZW1lbnRzLmZsb2F0aW5nKSA9PSBudWxsIHx8IF9lbGVtZW50cyRmbG9hdGluZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25TY3JvbGxNb3VzZUxlYXZlKTtcbiAgICAgIG1vdmUgJiYgcmVmLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG9uTW91c2VFbnRlciwge1xuICAgICAgICBvbmNlOiB0cnVlXG4gICAgICB9KTtcbiAgICAgIHJlZi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgb25Nb3VzZUVudGVyKTtcbiAgICAgIHJlZi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25Nb3VzZUxlYXZlKTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHZhciBfZWxlbWVudHMkZmxvYXRpbmcyO1xuICAgICAgICBvcGVuICYmIHJlZi5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25TY3JvbGxNb3VzZUxlYXZlKTtcbiAgICAgICAgKF9lbGVtZW50cyRmbG9hdGluZzIgPSBlbGVtZW50cy5mbG9hdGluZykgPT0gbnVsbCB8fCBfZWxlbWVudHMkZmxvYXRpbmcyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBvblNjcm9sbE1vdXNlTGVhdmUpO1xuICAgICAgICBtb3ZlICYmIHJlZi5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdXNlRW50ZXIpO1xuICAgICAgICByZWYucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIG9uTW91c2VFbnRlcik7XG4gICAgICAgIHJlZi5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgb25Nb3VzZUxlYXZlKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZWxlbWVudHMsIGVuYWJsZWQsIGNvbnRleHQsIG1vdXNlT25seSwgcmVzdE1zLCBtb3ZlLCBjbG9zZVdpdGhEZWxheSwgY2xlYW51cE1vdXNlTW92ZUhhbmRsZXIsIGNsZWFyUG9pbnRlckV2ZW50cywgb25PcGVuQ2hhbmdlLCBvcGVuLCBvcGVuUmVmLCB0cmVlLCBkZWxheVJlZiwgaGFuZGxlQ2xvc2VSZWYsIGRhdGFSZWZdKTtcblxuICAvLyBCbG9jayBwb2ludGVyLWV2ZW50cyBvZiBldmVyeSBlbGVtZW50IG90aGVyIHRoYW4gdGhlIHJlZmVyZW5jZSBhbmQgZmxvYXRpbmdcbiAgLy8gd2hpbGUgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXMgb3BlbiBhbmQgaGFzIGEgYGhhbmRsZUNsb3NlYCBoYW5kbGVyLiBBbHNvXG4gIC8vIGhhbmRsZXMgbmVzdGVkIGZsb2F0aW5nIGVsZW1lbnRzLlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmxvYXRpbmctdWkvZmxvYXRpbmctdWkvaXNzdWVzLzE3MjJcbiAgaW5kZXgoKCkgPT4ge1xuICAgIHZhciBfaGFuZGxlQ2xvc2VSZWYkY3VycmU7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgaWYgKG9wZW4gJiYgKF9oYW5kbGVDbG9zZVJlZiRjdXJyZSA9IGhhbmRsZUNsb3NlUmVmLmN1cnJlbnQpICE9IG51bGwgJiYgX2hhbmRsZUNsb3NlUmVmJGN1cnJlLl9fb3B0aW9ucy5ibG9ja1BvaW50ZXJFdmVudHMgJiYgaXNIb3Zlck9wZW4oKSkge1xuICAgICAgcGVyZm9ybWVkUG9pbnRlckV2ZW50c011dGF0aW9uUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgY29uc3QgZmxvYXRpbmdFbCA9IGVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgaWYgKGlzRWxlbWVudChlbGVtZW50cy5kb21SZWZlcmVuY2UpICYmIGZsb2F0aW5nRWwpIHtcbiAgICAgICAgdmFyIF90cmVlJG5vZGVzUmVmJGN1cnJlbjtcbiAgICAgICAgY29uc3QgYm9keSA9IGdldERvY3VtZW50KGVsZW1lbnRzLmZsb2F0aW5nKS5ib2R5O1xuICAgICAgICBib2R5LnNldEF0dHJpYnV0ZShzYWZlUG9seWdvbklkZW50aWZpZXIsICcnKTtcbiAgICAgICAgY29uc3QgcmVmID0gZWxlbWVudHMuZG9tUmVmZXJlbmNlO1xuICAgICAgICBjb25zdCBwYXJlbnRGbG9hdGluZyA9IHRyZWUgPT0gbnVsbCB8fCAoX3RyZWUkbm9kZXNSZWYkY3VycmVuID0gdHJlZS5ub2Rlc1JlZi5jdXJyZW50LmZpbmQobm9kZSA9PiBub2RlLmlkID09PSBwYXJlbnRJZCkpID09IG51bGwgfHwgKF90cmVlJG5vZGVzUmVmJGN1cnJlbiA9IF90cmVlJG5vZGVzUmVmJGN1cnJlbi5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX3RyZWUkbm9kZXNSZWYkY3VycmVuLmVsZW1lbnRzLmZsb2F0aW5nO1xuICAgICAgICBpZiAocGFyZW50RmxvYXRpbmcpIHtcbiAgICAgICAgICBwYXJlbnRGbG9hdGluZy5zdHlsZS5wb2ludGVyRXZlbnRzID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgYm9keS5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgICAgICByZWYuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICAgICAgZmxvYXRpbmdFbC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgIGJvZHkuc3R5bGUucG9pbnRlckV2ZW50cyA9ICcnO1xuICAgICAgICAgIHJlZi5zdHlsZS5wb2ludGVyRXZlbnRzID0gJyc7XG4gICAgICAgICAgZmxvYXRpbmdFbC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJyc7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgb3BlbiwgcGFyZW50SWQsIGVsZW1lbnRzLCB0cmVlLCBoYW5kbGVDbG9zZVJlZiwgaXNIb3Zlck9wZW5dKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmICghb3Blbikge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgIGNsZWFudXBNb3VzZU1vdmVIYW5kbGVyKCk7XG4gICAgICBjbGVhclBvaW50ZXJFdmVudHMoKTtcbiAgICB9XG4gIH0sIFtvcGVuLCBjbGVhbnVwTW91c2VNb3ZlSGFuZGxlciwgY2xlYXJQb2ludGVyRXZlbnRzXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNsZWFudXBNb3VzZU1vdmVIYW5kbGVyKCk7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgIGNsZWFyVGltZW91dChyZXN0VGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgIGNsZWFyUG9pbnRlckV2ZW50cygpO1xuICAgIH07XG4gIH0sIFtlbmFibGVkLCBlbGVtZW50cy5kb21SZWZlcmVuY2UsIGNsZWFudXBNb3VzZU1vdmVIYW5kbGVyLCBjbGVhclBvaW50ZXJFdmVudHNdKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgZnVuY3Rpb24gc2V0UG9pbnRlclJlZihldmVudCkge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IGV2ZW50LnBvaW50ZXJUeXBlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgb25Qb2ludGVyRG93bjogc2V0UG9pbnRlclJlZixcbiAgICAgIG9uUG9pbnRlckVudGVyOiBzZXRQb2ludGVyUmVmLFxuICAgICAgb25Nb3VzZU1vdmUoZXZlbnQpIHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIG5hdGl2ZUV2ZW50XG4gICAgICAgIH0gPSBldmVudDtcbiAgICAgICAgZnVuY3Rpb24gaGFuZGxlTW91c2VNb3ZlKCkge1xuICAgICAgICAgIGlmICghYmxvY2tNb3VzZU1vdmVSZWYuY3VycmVudCAmJiAhb3BlblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgbmF0aXZlRXZlbnQsICdob3ZlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobW91c2VPbmx5ICYmICFpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcGVuIHx8IHJlc3RNcyA9PT0gMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjbGVhclRpbWVvdXQocmVzdFRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICAgIGlmIChwb2ludGVyVHlwZVJlZi5jdXJyZW50ID09PSAndG91Y2gnKSB7XG4gICAgICAgICAgaGFuZGxlTW91c2VNb3ZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdFRpbWVvdXRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KGhhbmRsZU1vdXNlTW92ZSwgcmVzdE1zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH0sIFttb3VzZU9ubHksIG9uT3BlbkNoYW5nZSwgb3Blbiwgb3BlblJlZiwgcmVzdE1zXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uTW91c2VFbnRlcigpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0UmVmLmN1cnJlbnQpO1xuICAgIH0sXG4gICAgb25Nb3VzZUxlYXZlKGV2ZW50KSB7XG4gICAgICBjbG9zZVdpdGhEZWxheShldmVudC5uYXRpdmVFdmVudCwgZmFsc2UpO1xuICAgIH1cbiAgfSksIFtjbG9zZVdpdGhEZWxheV0pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiBlbmFibGVkID8ge1xuICAgIHJlZmVyZW5jZSxcbiAgICBmbG9hdGluZ1xuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2UsIGZsb2F0aW5nXSk7XG59XG5cbmNvbnN0IE5PT1AgPSAoKSA9PiB7fTtcbmNvbnN0IEZsb2F0aW5nRGVsYXlHcm91cENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIGRlbGF5OiAwLFxuICBpbml0aWFsRGVsYXk6IDAsXG4gIHRpbWVvdXRNczogMCxcbiAgY3VycmVudElkOiBudWxsLFxuICBzZXRDdXJyZW50SWQ6IE5PT1AsXG4gIHNldFN0YXRlOiBOT09QLFxuICBpc0luc3RhbnRQaGFzZTogZmFsc2Vcbn0pO1xuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKiBVc2UgdGhlIHJldHVybiB2YWx1ZSBvZiBgdXNlRGVsYXlHcm91cCgpYCBpbnN0ZWFkLlxuICovXG5jb25zdCB1c2VEZWxheUdyb3VwQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dCk7XG4vKipcbiAqIFByb3ZpZGVzIGNvbnRleHQgZm9yIGEgZ3JvdXAgb2YgZmxvYXRpbmcgZWxlbWVudHMgdGhhdCBzaG91bGQgc2hhcmUgYVxuICogYGRlbGF5YC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gRmxvYXRpbmdEZWxheUdyb3VwKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbixcbiAgICBkZWxheSxcbiAgICB0aW1lb3V0TXMgPSAwXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VSZWR1Y2VyKChwcmV2LCBuZXh0KSA9PiAoe1xuICAgIC4uLnByZXYsXG4gICAgLi4ubmV4dFxuICB9KSwge1xuICAgIGRlbGF5LFxuICAgIHRpbWVvdXRNcyxcbiAgICBpbml0aWFsRGVsYXk6IGRlbGF5LFxuICAgIGN1cnJlbnRJZDogbnVsbCxcbiAgICBpc0luc3RhbnRQaGFzZTogZmFsc2VcbiAgfSk7XG4gIGNvbnN0IGluaXRpYWxDdXJyZW50SWRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHNldEN1cnJlbnRJZCA9IFJlYWN0LnVzZUNhbGxiYWNrKGN1cnJlbnRJZCA9PiB7XG4gICAgc2V0U3RhdGUoe1xuICAgICAgY3VycmVudElkXG4gICAgfSk7XG4gIH0sIFtdKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmIChzdGF0ZS5jdXJyZW50SWQpIHtcbiAgICAgIGlmIChpbml0aWFsQ3VycmVudElkUmVmLmN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgICAgaW5pdGlhbEN1cnJlbnRJZFJlZi5jdXJyZW50ID0gc3RhdGUuY3VycmVudElkO1xuICAgICAgfSBlbHNlIGlmICghc3RhdGUuaXNJbnN0YW50UGhhc2UpIHtcbiAgICAgICAgc2V0U3RhdGUoe1xuICAgICAgICAgIGlzSW5zdGFudFBoYXNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3RhdGUuaXNJbnN0YW50UGhhc2UpIHtcbiAgICAgICAgc2V0U3RhdGUoe1xuICAgICAgICAgIGlzSW5zdGFudFBoYXNlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGluaXRpYWxDdXJyZW50SWRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbc3RhdGUuY3VycmVudElkLCBzdGF0ZS5pc0luc3RhbnRQaGFzZV0pO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRmxvYXRpbmdEZWxheUdyb3VwQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIHNldFN0YXRlLFxuICAgICAgc2V0Q3VycmVudElkXG4gICAgfSksIFtzdGF0ZSwgc2V0Q3VycmVudElkXSlcbiAgfSwgY2hpbGRyZW4pO1xufVxuLyoqXG4gKiBFbmFibGVzIGdyb3VwaW5nIHdoZW4gY2FsbGVkIGluc2lkZSBhIGNvbXBvbmVudCB0aGF0J3MgYSBjaGlsZCBvZiBhXG4gKiBgRmxvYXRpbmdEZWxheUdyb3VwYC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ0RlbGF5R3JvdXBcbiAqL1xuZnVuY3Rpb24gdXNlRGVsYXlHcm91cChjb250ZXh0LCBvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGZsb2F0aW5nSWRcbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBpZDogb3B0aW9uSWRcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGlkID0gb3B0aW9uSWQgIT0gbnVsbCA/IG9wdGlvbklkIDogZmxvYXRpbmdJZDtcbiAgY29uc3QgZ3JvdXBDb250ZXh0ID0gdXNlRGVsYXlHcm91cENvbnRleHQoKTtcbiAgY29uc3Qge1xuICAgIGN1cnJlbnRJZCxcbiAgICBzZXRDdXJyZW50SWQsXG4gICAgaW5pdGlhbERlbGF5LFxuICAgIHNldFN0YXRlLFxuICAgIHRpbWVvdXRNc1xuICB9ID0gZ3JvdXBDb250ZXh0O1xuICBpbmRleCgoKSA9PiB7XG4gICAgaWYgKCFjdXJyZW50SWQpIHJldHVybjtcbiAgICBzZXRTdGF0ZSh7XG4gICAgICBkZWxheToge1xuICAgICAgICBvcGVuOiAxLFxuICAgICAgICBjbG9zZTogZ2V0RGVsYXkoaW5pdGlhbERlbGF5LCAnY2xvc2UnKVxuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChjdXJyZW50SWQgIT09IGlkKSB7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UpO1xuICAgIH1cbiAgfSwgW2lkLCBvbk9wZW5DaGFuZ2UsIHNldFN0YXRlLCBjdXJyZW50SWQsIGluaXRpYWxEZWxheV0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgZnVuY3Rpb24gdW5zZXQoKSB7XG4gICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UpO1xuICAgICAgc2V0U3RhdGUoe1xuICAgICAgICBkZWxheTogaW5pdGlhbERlbGF5LFxuICAgICAgICBjdXJyZW50SWQ6IG51bGxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIWN1cnJlbnRJZCkgcmV0dXJuO1xuICAgIGlmICghb3BlbiAmJiBjdXJyZW50SWQgPT09IGlkKSB7XG4gICAgICBpZiAodGltZW91dE1zKSB7XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCh1bnNldCwgdGltZW91dE1zKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB1bnNldCgpO1xuICAgIH1cbiAgfSwgW29wZW4sIHNldFN0YXRlLCBjdXJyZW50SWQsIGlkLCBvbk9wZW5DaGFuZ2UsIGluaXRpYWxEZWxheSwgdGltZW91dE1zXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoc2V0Q3VycmVudElkID09PSBOT09QIHx8ICFvcGVuKSByZXR1cm47XG4gICAgc2V0Q3VycmVudElkKGlkKTtcbiAgfSwgW29wZW4sIHNldEN1cnJlbnRJZCwgaWRdKTtcbiAgcmV0dXJuIGdyb3VwQ29udGV4dDtcbn1cblxuZnVuY3Rpb24gZ2V0QW5jZXN0b3JzKG5vZGVzLCBpZCkge1xuICB2YXIgX25vZGVzJGZpbmQ7XG4gIGxldCBhbGxBbmNlc3RvcnMgPSBbXTtcbiAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IChfbm9kZXMkZmluZCA9IG5vZGVzLmZpbmQobm9kZSA9PiBub2RlLmlkID09PSBpZCkpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZXMkZmluZC5wYXJlbnRJZDtcbiAgd2hpbGUgKGN1cnJlbnRQYXJlbnRJZCkge1xuICAgIGNvbnN0IGN1cnJlbnROb2RlID0gbm9kZXMuZmluZChub2RlID0+IG5vZGUuaWQgPT09IGN1cnJlbnRQYXJlbnRJZCk7XG4gICAgY3VycmVudFBhcmVudElkID0gY3VycmVudE5vZGUgPT0gbnVsbCA/IHZvaWQgMCA6IGN1cnJlbnROb2RlLnBhcmVudElkO1xuICAgIGlmIChjdXJyZW50Tm9kZSkge1xuICAgICAgYWxsQW5jZXN0b3JzID0gYWxsQW5jZXN0b3JzLmNvbmNhdChjdXJyZW50Tm9kZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBhbGxBbmNlc3RvcnM7XG59XG5cbmZ1bmN0aW9uIGdldENoaWxkcmVuKG5vZGVzLCBpZCkge1xuICBsZXQgYWxsQ2hpbGRyZW4gPSBub2Rlcy5maWx0ZXIobm9kZSA9PiB7XG4gICAgdmFyIF9ub2RlJGNvbnRleHQ7XG4gICAgcmV0dXJuIG5vZGUucGFyZW50SWQgPT09IGlkICYmICgoX25vZGUkY29udGV4dCA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQub3Blbik7XG4gIH0pO1xuICBsZXQgY3VycmVudENoaWxkcmVuID0gYWxsQ2hpbGRyZW47XG4gIHdoaWxlIChjdXJyZW50Q2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgY3VycmVudENoaWxkcmVuID0gbm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgdmFyIF9jdXJyZW50Q2hpbGRyZW47XG4gICAgICByZXR1cm4gKF9jdXJyZW50Q2hpbGRyZW4gPSBjdXJyZW50Q2hpbGRyZW4pID09IG51bGwgPyB2b2lkIDAgOiBfY3VycmVudENoaWxkcmVuLnNvbWUobiA9PiB7XG4gICAgICAgIHZhciBfbm9kZSRjb250ZXh0MjtcbiAgICAgICAgcmV0dXJuIG5vZGUucGFyZW50SWQgPT09IG4uaWQgJiYgKChfbm9kZSRjb250ZXh0MiA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQyLm9wZW4pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgYWxsQ2hpbGRyZW4gPSBhbGxDaGlsZHJlbi5jb25jYXQoY3VycmVudENoaWxkcmVuKTtcbiAgfVxuICByZXR1cm4gYWxsQ2hpbGRyZW47XG59XG5mdW5jdGlvbiBnZXREZWVwZXN0Tm9kZShub2RlcywgaWQpIHtcbiAgbGV0IGRlZXBlc3ROb2RlSWQ7XG4gIGxldCBtYXhEZXB0aCA9IC0xO1xuICBmdW5jdGlvbiBmaW5kRGVlcGVzdChub2RlSWQsIGRlcHRoKSB7XG4gICAgaWYgKGRlcHRoID4gbWF4RGVwdGgpIHtcbiAgICAgIGRlZXBlc3ROb2RlSWQgPSBub2RlSWQ7XG4gICAgICBtYXhEZXB0aCA9IGRlcHRoO1xuICAgIH1cbiAgICBjb25zdCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKG5vZGVzLCBub2RlSWQpO1xuICAgIGNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgZmluZERlZXBlc3QoY2hpbGQuaWQsIGRlcHRoICsgMSk7XG4gICAgfSk7XG4gIH1cbiAgZmluZERlZXBlc3QoaWQsIDApO1xuICByZXR1cm4gbm9kZXMuZmluZChub2RlID0+IG5vZGUuaWQgPT09IGRlZXBlc3ROb2RlSWQpO1xufVxuXG4vLyBNb2RpZmllZCB0byBhZGQgY29uZGl0aW9uYWwgYGFyaWEtaGlkZGVuYCBzdXBwb3J0OlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RoZUthc2hleS9hcmlhLWhpZGRlbi9ibG9iLzkyMjBjOGY0YTRmZDM1ZjYzYmVlNTUxMGE5ZjQxYTM3MjY0MzgyZDQvc3JjL2luZGV4LnRzXG5sZXQgY291bnRlck1hcCA9IC8qI19fUFVSRV9fKi9uZXcgV2Vha01hcCgpO1xubGV0IHVuY29udHJvbGxlZEVsZW1lbnRzU2V0ID0gLyojX19QVVJFX18qL25ldyBXZWFrU2V0KCk7XG5sZXQgbWFya2VyTWFwID0ge307XG5sZXQgbG9ja0NvdW50ID0gMDtcbmNvbnN0IHN1cHBvcnRzSW5lcnQgPSAoKSA9PiB0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmICdpbmVydCcgaW4gSFRNTEVsZW1lbnQucHJvdG90eXBlO1xuY29uc3QgdW53cmFwSG9zdCA9IG5vZGUgPT4gbm9kZSAmJiAobm9kZS5ob3N0IHx8IHVud3JhcEhvc3Qobm9kZS5wYXJlbnROb2RlKSk7XG5jb25zdCBjb3JyZWN0RWxlbWVudHMgPSAocGFyZW50LCB0YXJnZXRzKSA9PiB0YXJnZXRzLm1hcCh0YXJnZXQgPT4ge1xuICBpZiAocGFyZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG4gIGNvbnN0IGNvcnJlY3RlZFRhcmdldCA9IHVud3JhcEhvc3QodGFyZ2V0KTtcbiAgaWYgKHBhcmVudC5jb250YWlucyhjb3JyZWN0ZWRUYXJnZXQpKSB7XG4gICAgcmV0dXJuIGNvcnJlY3RlZFRhcmdldDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn0pLmZpbHRlcih4ID0+IHggIT0gbnVsbCk7XG5mdW5jdGlvbiBhcHBseUF0dHJpYnV0ZVRvT3RoZXJzKHVuY29ycmVjdGVkQXZvaWRFbGVtZW50cywgYm9keSwgYXJpYUhpZGRlbiwgaW5lcnQpIHtcbiAgY29uc3QgbWFya2VyTmFtZSA9ICdkYXRhLWZsb2F0aW5nLXVpLWluZXJ0JztcbiAgY29uc3QgY29udHJvbEF0dHJpYnV0ZSA9IGluZXJ0ID8gJ2luZXJ0JyA6IGFyaWFIaWRkZW4gPyAnYXJpYS1oaWRkZW4nIDogbnVsbDtcbiAgY29uc3QgYXZvaWRFbGVtZW50cyA9IGNvcnJlY3RFbGVtZW50cyhib2R5LCB1bmNvcnJlY3RlZEF2b2lkRWxlbWVudHMpO1xuICBjb25zdCBlbGVtZW50c1RvS2VlcCA9IG5ldyBTZXQoKTtcbiAgY29uc3QgZWxlbWVudHNUb1N0b3AgPSBuZXcgU2V0KGF2b2lkRWxlbWVudHMpO1xuICBjb25zdCBoaWRkZW5FbGVtZW50cyA9IFtdO1xuICBpZiAoIW1hcmtlck1hcFttYXJrZXJOYW1lXSkge1xuICAgIG1hcmtlck1hcFttYXJrZXJOYW1lXSA9IG5ldyBXZWFrTWFwKCk7XG4gIH1cbiAgY29uc3QgbWFya2VyQ291bnRlciA9IG1hcmtlck1hcFttYXJrZXJOYW1lXTtcbiAgYXZvaWRFbGVtZW50cy5mb3JFYWNoKGtlZXApO1xuICBkZWVwKGJvZHkpO1xuICBlbGVtZW50c1RvS2VlcC5jbGVhcigpO1xuICBmdW5jdGlvbiBrZWVwKGVsKSB7XG4gICAgaWYgKCFlbCB8fCBlbGVtZW50c1RvS2VlcC5oYXMoZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVsZW1lbnRzVG9LZWVwLmFkZChlbCk7XG4gICAgZWwucGFyZW50Tm9kZSAmJiBrZWVwKGVsLnBhcmVudE5vZGUpO1xuICB9XG4gIGZ1bmN0aW9uIGRlZXAocGFyZW50KSB7XG4gICAgaWYgKCFwYXJlbnQgfHwgZWxlbWVudHNUb1N0b3AuaGFzKHBhcmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgW10uZm9yRWFjaC5jYWxsKHBhcmVudC5jaGlsZHJlbiwgbm9kZSA9PiB7XG4gICAgICBpZiAoZ2V0Tm9kZU5hbWUobm9kZSkgPT09ICdzY3JpcHQnKSByZXR1cm47XG4gICAgICBpZiAoZWxlbWVudHNUb0tlZXAuaGFzKG5vZGUpKSB7XG4gICAgICAgIGRlZXAobm9kZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBhdHRyID0gY29udHJvbEF0dHJpYnV0ZSA/IG5vZGUuZ2V0QXR0cmlidXRlKGNvbnRyb2xBdHRyaWJ1dGUpIDogbnVsbDtcbiAgICAgICAgY29uc3QgYWxyZWFkeUhpZGRlbiA9IGF0dHIgIT09IG51bGwgJiYgYXR0ciAhPT0gJ2ZhbHNlJztcbiAgICAgICAgY29uc3QgY291bnRlclZhbHVlID0gKGNvdW50ZXJNYXAuZ2V0KG5vZGUpIHx8IDApICsgMTtcbiAgICAgICAgY29uc3QgbWFya2VyVmFsdWUgPSAobWFya2VyQ291bnRlci5nZXQobm9kZSkgfHwgMCkgKyAxO1xuICAgICAgICBjb3VudGVyTWFwLnNldChub2RlLCBjb3VudGVyVmFsdWUpO1xuICAgICAgICBtYXJrZXJDb3VudGVyLnNldChub2RlLCBtYXJrZXJWYWx1ZSk7XG4gICAgICAgIGhpZGRlbkVsZW1lbnRzLnB1c2gobm9kZSk7XG4gICAgICAgIGlmIChjb3VudGVyVmFsdWUgPT09IDEgJiYgYWxyZWFkeUhpZGRlbikge1xuICAgICAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0LmFkZChub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWFya2VyVmFsdWUgPT09IDEpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShtYXJrZXJOYW1lLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbHJlYWR5SGlkZGVuICYmIGNvbnRyb2xBdHRyaWJ1dGUpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShjb250cm9sQXR0cmlidXRlLCAndHJ1ZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgbG9ja0NvdW50Kys7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgaGlkZGVuRWxlbWVudHMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIGNvbnN0IGNvdW50ZXJWYWx1ZSA9IChjb3VudGVyTWFwLmdldChlbGVtZW50KSB8fCAwKSAtIDE7XG4gICAgICBjb25zdCBtYXJrZXJWYWx1ZSA9IChtYXJrZXJDb3VudGVyLmdldChlbGVtZW50KSB8fCAwKSAtIDE7XG4gICAgICBjb3VudGVyTWFwLnNldChlbGVtZW50LCBjb3VudGVyVmFsdWUpO1xuICAgICAgbWFya2VyQ291bnRlci5zZXQoZWxlbWVudCwgbWFya2VyVmFsdWUpO1xuICAgICAgaWYgKCFjb3VudGVyVmFsdWUpIHtcbiAgICAgICAgaWYgKCF1bmNvbnRyb2xsZWRFbGVtZW50c1NldC5oYXMoZWxlbWVudCkgJiYgY29udHJvbEF0dHJpYnV0ZSkge1xuICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGNvbnRyb2xBdHRyaWJ1dGUpO1xuICAgICAgICB9XG4gICAgICAgIHVuY29udHJvbGxlZEVsZW1lbnRzU2V0LmRlbGV0ZShlbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIGlmICghbWFya2VyVmFsdWUpIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUobWFya2VyTmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbG9ja0NvdW50LS07XG4gICAgaWYgKCFsb2NrQ291bnQpIHtcbiAgICAgIGNvdW50ZXJNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgY291bnRlck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICB1bmNvbnRyb2xsZWRFbGVtZW50c1NldCA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICBtYXJrZXJNYXAgPSB7fTtcbiAgICB9XG4gIH07XG59XG5mdW5jdGlvbiBtYXJrT3RoZXJzKGF2b2lkRWxlbWVudHMsIGFyaWFIaWRkZW4sIGluZXJ0KSB7XG4gIGlmIChhcmlhSGlkZGVuID09PSB2b2lkIDApIHtcbiAgICBhcmlhSGlkZGVuID0gZmFsc2U7XG4gIH1cbiAgaWYgKGluZXJ0ID09PSB2b2lkIDApIHtcbiAgICBpbmVydCA9IGZhbHNlO1xuICB9XG4gIGNvbnN0IGJvZHkgPSBnZXREb2N1bWVudChhdm9pZEVsZW1lbnRzWzBdKS5ib2R5O1xuICByZXR1cm4gYXBwbHlBdHRyaWJ1dGVUb090aGVycyhhdm9pZEVsZW1lbnRzLmNvbmNhdChBcnJheS5mcm9tKGJvZHkucXVlcnlTZWxlY3RvckFsbCgnW2FyaWEtbGl2ZV0nKSkpLCBib2R5LCBhcmlhSGlkZGVuLCBpbmVydCk7XG59XG5cbmNvbnN0IGdldFRhYmJhYmxlT3B0aW9ucyA9ICgpID0+ICh7XG4gIGdldFNoYWRvd1Jvb3Q6IHRydWUsXG4gIGRpc3BsYXlDaGVjazpcbiAgLy8gSlNET00gZG9lcyBub3Qgc3VwcG9ydCB0aGUgYHRhYmJhYmxlYCBsaWJyYXJ5LiBUbyBzb2x2ZSB0aGlzIHdlIGNhblxuICAvLyBjaGVjayBpZiBgUmVzaXplT2JzZXJ2ZXJgIGlzIGEgcmVhbCBmdW5jdGlvbiAobm90IHBvbHlmaWxsZWQpLCB3aGljaFxuICAvLyBkZXRlcm1pbmVzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIEpTRE9NLWxpa2UuXG4gIHR5cGVvZiBSZXNpemVPYnNlcnZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBSZXNpemVPYnNlcnZlci50b1N0cmluZygpLmluY2x1ZGVzKCdbbmF0aXZlIGNvZGVdJykgPyAnZnVsbCcgOiAnbm9uZSdcbn0pO1xuZnVuY3Rpb24gZ2V0VGFiYmFibGVJbihjb250YWluZXIsIGRpcmVjdGlvbikge1xuICBjb25zdCBhbGxUYWJiYWJsZSA9IHRhYmJhYmxlKGNvbnRhaW5lciwgZ2V0VGFiYmFibGVPcHRpb25zKCkpO1xuICBpZiAoZGlyZWN0aW9uID09PSAncHJldicpIHtcbiAgICBhbGxUYWJiYWJsZS5yZXZlcnNlKCk7XG4gIH1cbiAgY29uc3QgYWN0aXZlSW5kZXggPSBhbGxUYWJiYWJsZS5pbmRleE9mKGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQoY29udGFpbmVyKSkpO1xuICBjb25zdCBuZXh0VGFiYmFibGVFbGVtZW50cyA9IGFsbFRhYmJhYmxlLnNsaWNlKGFjdGl2ZUluZGV4ICsgMSk7XG4gIHJldHVybiBuZXh0VGFiYmFibGVFbGVtZW50c1swXTtcbn1cbmZ1bmN0aW9uIGdldE5leHRUYWJiYWJsZSgpIHtcbiAgcmV0dXJuIGdldFRhYmJhYmxlSW4oZG9jdW1lbnQuYm9keSwgJ25leHQnKTtcbn1cbmZ1bmN0aW9uIGdldFByZXZpb3VzVGFiYmFibGUoKSB7XG4gIHJldHVybiBnZXRUYWJiYWJsZUluKGRvY3VtZW50LmJvZHksICdwcmV2Jyk7XG59XG5mdW5jdGlvbiBpc091dHNpZGVFdmVudChldmVudCwgY29udGFpbmVyKSB7XG4gIGNvbnN0IGNvbnRhaW5lckVsZW1lbnQgPSBjb250YWluZXIgfHwgZXZlbnQuY3VycmVudFRhcmdldDtcbiAgY29uc3QgcmVsYXRlZFRhcmdldCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG4gIHJldHVybiAhcmVsYXRlZFRhcmdldCB8fCAhY29udGFpbnMoY29udGFpbmVyRWxlbWVudCwgcmVsYXRlZFRhcmdldCk7XG59XG5mdW5jdGlvbiBkaXNhYmxlRm9jdXNJbnNpZGUoY29udGFpbmVyKSB7XG4gIGNvbnN0IHRhYmJhYmxlRWxlbWVudHMgPSB0YWJiYWJsZShjb250YWluZXIsIGdldFRhYmJhYmxlT3B0aW9ucygpKTtcbiAgdGFiYmFibGVFbGVtZW50cy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgIGVsZW1lbnQuZGF0YXNldC50YWJpbmRleCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd0YWJpbmRleCcpIHx8ICcnO1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpO1xuICB9KTtcbn1cbmZ1bmN0aW9uIGVuYWJsZUZvY3VzSW5zaWRlKGNvbnRhaW5lcikge1xuICBjb25zdCBlbGVtZW50cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS10YWJpbmRleF0nKTtcbiAgZWxlbWVudHMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICBjb25zdCB0YWJpbmRleCA9IGVsZW1lbnQuZGF0YXNldC50YWJpbmRleDtcbiAgICBkZWxldGUgZWxlbWVudC5kYXRhc2V0LnRhYmluZGV4O1xuICAgIGlmICh0YWJpbmRleCkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgdGFiaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgndGFiaW5kZXgnKTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gZ2V0Q2xvc2VzdFRhYmJhYmxlRWxlbWVudCh0YWJiYWJsZUVsZW1lbnRzLCBlbGVtZW50LCBmbG9hdGluZykge1xuICBjb25zdCBlbGVtZW50SW5kZXggPSB0YWJiYWJsZUVsZW1lbnRzLmluZGV4T2YoZWxlbWVudCk7XG4gIGZ1bmN0aW9uIHRyYXZlcnNlVGFiYmFibGVFbGVtZW50cyhuZXh0KSB7XG4gICAgY29uc3QgYXR0ciA9IGNyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKTtcbiAgICBsZXQgaW5kZXggPSBlbGVtZW50SW5kZXggKyAobmV4dCA/IDEgOiAwKTtcbiAgICBsZXQgY3VycmVudEVsZW1lbnQgPSB0YWJiYWJsZUVsZW1lbnRzW2luZGV4XTtcbiAgICB3aGlsZSAoY3VycmVudEVsZW1lbnQgJiYgKCFjdXJyZW50RWxlbWVudC5pc0Nvbm5lY3RlZCB8fCBjdXJyZW50RWxlbWVudC5oYXNBdHRyaWJ1dGUoYXR0cikgfHwgY29udGFpbnMoZmxvYXRpbmcsIGN1cnJlbnRFbGVtZW50KSkpIHtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIGluZGV4Kys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgY3VycmVudEVsZW1lbnQgPSB0YWJiYWJsZUVsZW1lbnRzW2luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRFbGVtZW50O1xuICB9XG5cbiAgLy8gRmlyc3QsIHRyeSB0byBmaW5kIHRoZSBuZXh0IHRhYmJhYmxlIGVsZW1lbnRcbiAgY29uc3QgbmV4dCA9IHRyYXZlcnNlVGFiYmFibGVFbGVtZW50cyh0cnVlKTtcbiAgaWYgKG5leHQpIHtcbiAgICByZXR1cm4gbmV4dDtcbiAgfVxuXG4gIC8vIElmIHdlIGNhbid0IGZpbmQgYSBuZXh0IHRhYmJhYmxlIGVsZW1lbnQsIHRyeSB0byBmaW5kIHRoZSBwcmV2aW91cyBvbmVcbiAgcmV0dXJuIHRyYXZlcnNlVGFiYmFibGVFbGVtZW50cyhmYWxzZSk7XG59XG5cbi8vIFNlZSBEaWVnbyBIYXoncyBTYW5kYm94IGZvciBtYWtpbmcgdGhpcyBsb2dpYyB3b3JrIHdlbGwgb24gU2FmYXJpL2lPUzpcbi8vIGh0dHBzOi8vY29kZXNhbmRib3guaW8vcy90YWJiYWJsZS1wb3J0YWwtZjR0bmc/ZmlsZT0vc3JjL0ZvY3VzVHJhcC50c3hcblxuY29uc3QgSElEREVOX1NUWUxFUyA9IHtcbiAgYm9yZGVyOiAwLFxuICBjbGlwOiAncmVjdCgwIDAgMCAwKScsXG4gIGhlaWdodDogJzFweCcsXG4gIG1hcmdpbjogJy0xcHgnLFxuICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gIHBhZGRpbmc6IDAsXG4gIHBvc2l0aW9uOiAnZml4ZWQnLFxuICB3aGl0ZVNwYWNlOiAnbm93cmFwJyxcbiAgd2lkdGg6ICcxcHgnLFxuICB0b3A6IDAsXG4gIGxlZnQ6IDBcbn07XG5sZXQgdGltZW91dElkO1xuZnVuY3Rpb24gc2V0QWN0aXZlRWxlbWVudE9uVGFiKGV2ZW50KSB7XG4gIGlmIChldmVudC5rZXkgPT09ICdUYWInKSB7XG4gICAgZXZlbnQudGFyZ2V0O1xuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICB9XG59XG5jb25zdCBGb2N1c0d1YXJkID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gRm9jdXNHdWFyZChwcm9wcywgcmVmKSB7XG4gIGNvbnN0IFtyb2xlLCBzZXRSb2xlXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoaXNTYWZhcmkoKSkge1xuICAgICAgLy8gVW5saWtlIG90aGVyIHNjcmVlbiByZWFkZXJzIHN1Y2ggYXMgTlZEQSBhbmQgSkFXUywgdGhlIHZpcnR1YWwgY3Vyc29yXG4gICAgICAvLyBvbiBWb2ljZU92ZXIgZG9lcyB0cmlnZ2VyIHRoZSBvbkZvY3VzIGV2ZW50LCBzbyB3ZSBjYW4gdXNlIHRoZSBmb2N1c1xuICAgICAgLy8gdHJhcCBlbGVtZW50LiBPbiBTYWZhcmksIG9ubHkgYnV0dG9ucyB0cmlnZ2VyIHRoZSBvbkZvY3VzIGV2ZW50LlxuICAgICAgLy8gTkI6IFwiZ3JvdXBcIiByb2xlIGluIHRoZSBTYW5kYm94IG5vIGxvbmdlciBhcHBlYXJzIHRvIHdvcmssIG11c3QgYmUgYVxuICAgICAgLy8gYnV0dG9uIHJvbGUuXG4gICAgICBzZXRSb2xlKCdidXR0b24nKTtcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHNldEFjdGl2ZUVsZW1lbnRPblRhYik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBzZXRBY3RpdmVFbGVtZW50T25UYWIpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgY29uc3QgcmVzdFByb3BzID0ge1xuICAgIHJlZixcbiAgICB0YWJJbmRleDogMCxcbiAgICAvLyBSb2xlIGlzIG9ubHkgZm9yIFZvaWNlT3ZlclxuICAgIHJvbGUsXG4gICAgJ2FyaWEtaGlkZGVuJzogcm9sZSA/IHVuZGVmaW5lZCA6IHRydWUsXG4gICAgW2NyZWF0ZUF0dHJpYnV0ZSgnZm9jdXMtZ3VhcmQnKV06ICcnLFxuICAgIHN0eWxlOiBISURERU5fU1RZTEVTXG4gIH07XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwgX2V4dGVuZHMoe30sIHByb3BzLCByZXN0UHJvcHMpKTtcbn0pO1xuXG5jb25zdCBQb3J0YWxDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5jb25zdCBhdHRyID0gLyojX19QVVJFX18qL2NyZWF0ZUF0dHJpYnV0ZSgncG9ydGFsJyk7XG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1BvcnRhbCN1c2VmbG9hdGluZ3BvcnRhbG5vZGVcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmdQb3J0YWxOb2RlKHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgaWQsXG4gICAgcm9vdFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHVuaXF1ZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcG9ydGFsQ29udGV4dCA9IHVzZVBvcnRhbENvbnRleHQoKTtcbiAgY29uc3QgW3BvcnRhbE5vZGUsIHNldFBvcnRhbE5vZGVdID0gUmVhY3QudXNlU3RhdGUobnVsbCk7XG4gIGNvbnN0IHBvcnRhbE5vZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGluZGV4KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgcG9ydGFsTm9kZSA9PSBudWxsIHx8IHBvcnRhbE5vZGUucmVtb3ZlKCk7XG4gICAgICAvLyBBbGxvdyB0aGUgc3Vic2VxdWVudCBsYXlvdXQgZWZmZWN0cyB0byBjcmVhdGUgYSBuZXcgbm9kZSBvbiB1cGRhdGVzLlxuICAgICAgLy8gVGhlIHBvcnRhbCBub2RlIHdpbGwgc3RpbGwgYmUgY2xlYW5lZCB1cCBvbiB1bm1vdW50LlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yNDU0XG4gICAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICAgIHBvcnRhbE5vZGVSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9KTtcbiAgICB9O1xuICB9LCBbcG9ydGFsTm9kZV0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHVuaXF1ZUlkIHRvIGJlIGdlbmVyYXRlZCBiZWZvcmUgY3JlYXRpbmcgdGhlIHBvcnRhbCBub2RlIGluXG4gICAgLy8gUmVhY3QgPDE4ICh1c2luZyBgdXNlRmxvYXRpbmdJZGAgaW5zdGVhZCBvZiB0aGUgbmF0aXZlIGB1c2VJZGApLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjc3OFxuICAgIGlmICghdW5pcXVlSWQpIHJldHVybjtcbiAgICBpZiAocG9ydGFsTm9kZVJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgY29uc3QgZXhpc3RpbmdJZFJvb3QgPSBpZCA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSA6IG51bGw7XG4gICAgaWYgKCFleGlzdGluZ0lkUm9vdCkgcmV0dXJuO1xuICAgIGNvbnN0IHN1YlJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBzdWJSb290LmlkID0gdW5pcXVlSWQ7XG4gICAgc3ViUm9vdC5zZXRBdHRyaWJ1dGUoYXR0ciwgJycpO1xuICAgIGV4aXN0aW5nSWRSb290LmFwcGVuZENoaWxkKHN1YlJvb3QpO1xuICAgIHBvcnRhbE5vZGVSZWYuY3VycmVudCA9IHN1YlJvb3Q7XG4gICAgc2V0UG9ydGFsTm9kZShzdWJSb290KTtcbiAgfSwgW2lkLCB1bmlxdWVJZF0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgaWYgKCF1bmlxdWVJZCkgcmV0dXJuO1xuICAgIGlmIChwb3J0YWxOb2RlUmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBsZXQgY29udGFpbmVyID0gcm9vdCB8fCAocG9ydGFsQ29udGV4dCA9PSBudWxsID8gdm9pZCAwIDogcG9ydGFsQ29udGV4dC5wb3J0YWxOb2RlKTtcbiAgICBpZiAoY29udGFpbmVyICYmICFpc0VsZW1lbnQoY29udGFpbmVyKSkgY29udGFpbmVyID0gY29udGFpbmVyLmN1cnJlbnQ7XG4gICAgY29udGFpbmVyID0gY29udGFpbmVyIHx8IGRvY3VtZW50LmJvZHk7XG4gICAgbGV0IGlkV3JhcHBlciA9IG51bGw7XG4gICAgaWYgKGlkKSB7XG4gICAgICBpZFdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGlkV3JhcHBlci5pZCA9IGlkO1xuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGlkV3JhcHBlcik7XG4gICAgfVxuICAgIGNvbnN0IHN1YlJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBzdWJSb290LmlkID0gdW5pcXVlSWQ7XG4gICAgc3ViUm9vdC5zZXRBdHRyaWJ1dGUoYXR0ciwgJycpO1xuICAgIGNvbnRhaW5lciA9IGlkV3JhcHBlciB8fCBjb250YWluZXI7XG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHN1YlJvb3QpO1xuICAgIHBvcnRhbE5vZGVSZWYuY3VycmVudCA9IHN1YlJvb3Q7XG4gICAgc2V0UG9ydGFsTm9kZShzdWJSb290KTtcbiAgfSwgW2lkLCByb290LCB1bmlxdWVJZCwgcG9ydGFsQ29udGV4dF0pO1xuICByZXR1cm4gcG9ydGFsTm9kZTtcbn1cbi8qKlxuICogUG9ydGFscyB0aGUgZmxvYXRpbmcgZWxlbWVudCBpbnRvIGEgZ2l2ZW4gY29udGFpbmVyIGVsZW1lbnQg4oCUIGJ5IGRlZmF1bHQsXG4gKiBvdXRzaWRlIG9mIHRoZSBhcHAgcm9vdCBhbmQgaW50byB0aGUgYm9keS5cbiAqIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGVuc3VyZSB0aGUgZmxvYXRpbmcgZWxlbWVudCBjYW4gYXBwZWFyIG91dHNpZGUgYW55XG4gKiBwb3RlbnRpYWwgcGFyZW50IGNvbnRhaW5lcnMgdGhhdCBjYXVzZSBjbGlwcGluZyAoc3VjaCBhcyBgb3ZlcmZsb3c6IGhpZGRlbmApLFxuICogd2hpbGUgcmV0YWluaW5nIGl0cyBsb2NhdGlvbiBpbiB0aGUgUmVhY3QgdHJlZS5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9GbG9hdGluZ1BvcnRhbFxuICovXG5mdW5jdGlvbiBGbG9hdGluZ1BvcnRhbChwcm9wcykge1xuICBjb25zdCB7XG4gICAgY2hpbGRyZW4sXG4gICAgaWQsXG4gICAgcm9vdCA9IG51bGwsXG4gICAgcHJlc2VydmVUYWJPcmRlciA9IHRydWVcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwb3J0YWxOb2RlID0gdXNlRmxvYXRpbmdQb3J0YWxOb2RlKHtcbiAgICBpZCxcbiAgICByb290XG4gIH0pO1xuICBjb25zdCBbZm9jdXNNYW5hZ2VyU3RhdGUsIHNldEZvY3VzTWFuYWdlclN0YXRlXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpO1xuICBjb25zdCBiZWZvcmVPdXRzaWRlUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBhZnRlck91dHNpZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGJlZm9yZUluc2lkZVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgYWZ0ZXJJbnNpZGVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IG1vZGFsID0gZm9jdXNNYW5hZ2VyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IGZvY3VzTWFuYWdlclN0YXRlLm1vZGFsO1xuICBjb25zdCBvcGVuID0gZm9jdXNNYW5hZ2VyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IGZvY3VzTWFuYWdlclN0YXRlLm9wZW47XG4gIGNvbnN0IHNob3VsZFJlbmRlckd1YXJkcyA9XG4gIC8vIFRoZSBGb2N1c01hbmFnZXIgYW5kIHRoZXJlZm9yZSBmbG9hdGluZyBlbGVtZW50IGFyZSBjdXJyZW50bHkgb3Blbi9cbiAgLy8gcmVuZGVyZWQuXG4gICEhZm9jdXNNYW5hZ2VyU3RhdGUgJiZcbiAgLy8gR3VhcmRzIGFyZSBvbmx5IGZvciBub24tbW9kYWwgZm9jdXMgbWFuYWdlbWVudC5cbiAgIWZvY3VzTWFuYWdlclN0YXRlLm1vZGFsICYmXG4gIC8vIERvbid0IHJlbmRlciBpZiB1bm1vdW50IGlzIHRyYW5zaXRpb25pbmcuXG4gIGZvY3VzTWFuYWdlclN0YXRlLm9wZW4gJiYgcHJlc2VydmVUYWJPcmRlciAmJiAhIShyb290IHx8IHBvcnRhbE5vZGUpO1xuXG4gIC8vIGh0dHBzOi8vY29kZXNhbmRib3guaW8vcy90YWJiYWJsZS1wb3J0YWwtZjR0bmc/ZmlsZT0vc3JjL1RhYmJhYmxlUG9ydGFsLnRzeFxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghcG9ydGFsTm9kZSB8fCAhcHJlc2VydmVUYWJPcmRlciB8fCBtb2RhbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSBlbGVtZW50cyBpbnNpZGUgdGhlIHBvcnRhbCBlbGVtZW50IGFyZSB0YWJiYWJsZSBvbmx5IHdoZW4gdGhlXG4gICAgLy8gcG9ydGFsIGhhcyBhbHJlYWR5IGJlZW4gZm9jdXNlZCwgZWl0aGVyIGJ5IHRhYmJpbmcgaW50byBhIGZvY3VzIHRyYXBcbiAgICAvLyBlbGVtZW50IG91dHNpZGUgb3IgdXNpbmcgdGhlIG1vdXNlLlxuICAgIGZ1bmN0aW9uIG9uRm9jdXMoZXZlbnQpIHtcbiAgICAgIGlmIChwb3J0YWxOb2RlICYmIGlzT3V0c2lkZUV2ZW50KGV2ZW50KSkge1xuICAgICAgICBjb25zdCBmb2N1c2luZyA9IGV2ZW50LnR5cGUgPT09ICdmb2N1c2luJztcbiAgICAgICAgY29uc3QgbWFuYWdlRm9jdXMgPSBmb2N1c2luZyA/IGVuYWJsZUZvY3VzSW5zaWRlIDogZGlzYWJsZUZvY3VzSW5zaWRlO1xuICAgICAgICBtYW5hZ2VGb2N1cyhwb3J0YWxOb2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gTGlzdGVuIHRvIHRoZSBldmVudCBvbiB0aGUgY2FwdHVyZSBwaGFzZSBzbyB0aGV5IHJ1biBiZWZvcmUgdGhlIGZvY3VzXG4gICAgLy8gdHJhcCBlbGVtZW50cyBvbkZvY3VzIHByb3AgaXMgY2FsbGVkLlxuICAgIHBvcnRhbE5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIG9uRm9jdXMsIHRydWUpO1xuICAgIHBvcnRhbE5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNvdXQnLCBvbkZvY3VzLCB0cnVlKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgcG9ydGFsTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c2luJywgb25Gb2N1cywgdHJ1ZSk7XG4gICAgICBwb3J0YWxOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0Jywgb25Gb2N1cywgdHJ1ZSk7XG4gICAgfTtcbiAgfSwgW3BvcnRhbE5vZGUsIHByZXNlcnZlVGFiT3JkZXIsIG1vZGFsXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFwb3J0YWxOb2RlKSByZXR1cm47XG4gICAgaWYgKG9wZW4pIHJldHVybjtcbiAgICBlbmFibGVGb2N1c0luc2lkZShwb3J0YWxOb2RlKTtcbiAgfSwgW29wZW4sIHBvcnRhbE5vZGVdKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBvcnRhbENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgICAgcHJlc2VydmVUYWJPcmRlcixcbiAgICAgIGJlZm9yZU91dHNpZGVSZWYsXG4gICAgICBhZnRlck91dHNpZGVSZWYsXG4gICAgICBiZWZvcmVJbnNpZGVSZWYsXG4gICAgICBhZnRlckluc2lkZVJlZixcbiAgICAgIHBvcnRhbE5vZGUsXG4gICAgICBzZXRGb2N1c01hbmFnZXJTdGF0ZVxuICAgIH0pLCBbcHJlc2VydmVUYWJPcmRlciwgcG9ydGFsTm9kZV0pXG4gIH0sIHNob3VsZFJlbmRlckd1YXJkcyAmJiBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KEZvY3VzR3VhcmQsIHtcbiAgICBcImRhdGEtdHlwZVwiOiBcIm91dHNpZGVcIixcbiAgICByZWY6IGJlZm9yZU91dHNpZGVSZWYsXG4gICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgaWYgKGlzT3V0c2lkZUV2ZW50KGV2ZW50LCBwb3J0YWxOb2RlKSkge1xuICAgICAgICB2YXIgX2JlZm9yZUluc2lkZVJlZiRjdXJyO1xuICAgICAgICAoX2JlZm9yZUluc2lkZVJlZiRjdXJyID0gYmVmb3JlSW5zaWRlUmVmLmN1cnJlbnQpID09IG51bGwgfHwgX2JlZm9yZUluc2lkZVJlZiRjdXJyLmZvY3VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwcmV2VGFiYmFibGUgPSBnZXRQcmV2aW91c1RhYmJhYmxlKCkgfHwgKGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5yZWZzLmRvbVJlZmVyZW5jZS5jdXJyZW50KTtcbiAgICAgICAgcHJldlRhYmJhYmxlID09IG51bGwgfHwgcHJldlRhYmJhYmxlLmZvY3VzKCk7XG4gICAgICB9XG4gICAgfVxuICB9KSwgc2hvdWxkUmVuZGVyR3VhcmRzICYmIHBvcnRhbE5vZGUgJiYgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIHtcbiAgICBcImFyaWEtb3duc1wiOiBwb3J0YWxOb2RlLmlkLFxuICAgIHN0eWxlOiBISURERU5fU1RZTEVTXG4gIH0pLCBwb3J0YWxOb2RlICYmIC8qI19fUFVSRV9fKi9SZWFjdERPTS5jcmVhdGVQb3J0YWwoY2hpbGRyZW4sIHBvcnRhbE5vZGUpLCBzaG91bGRSZW5kZXJHdWFyZHMgJiYgcG9ydGFsTm9kZSAmJiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGb2N1c0d1YXJkLCB7XG4gICAgXCJkYXRhLXR5cGVcIjogXCJvdXRzaWRlXCIsXG4gICAgcmVmOiBhZnRlck91dHNpZGVSZWYsXG4gICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgaWYgKGlzT3V0c2lkZUV2ZW50KGV2ZW50LCBwb3J0YWxOb2RlKSkge1xuICAgICAgICB2YXIgX2FmdGVySW5zaWRlUmVmJGN1cnJlO1xuICAgICAgICAoX2FmdGVySW5zaWRlUmVmJGN1cnJlID0gYWZ0ZXJJbnNpZGVSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfYWZ0ZXJJbnNpZGVSZWYkY3VycmUuZm9jdXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG5leHRUYWJiYWJsZSA9IGdldE5leHRUYWJiYWJsZSgpIHx8IChmb2N1c01hbmFnZXJTdGF0ZSA9PSBudWxsID8gdm9pZCAwIDogZm9jdXNNYW5hZ2VyU3RhdGUucmVmcy5kb21SZWZlcmVuY2UuY3VycmVudCk7XG4gICAgICAgIG5leHRUYWJiYWJsZSA9PSBudWxsIHx8IG5leHRUYWJiYWJsZS5mb2N1cygpO1xuICAgICAgICAoZm9jdXNNYW5hZ2VyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IGZvY3VzTWFuYWdlclN0YXRlLmNsb3NlT25Gb2N1c091dCkgJiYgKGZvY3VzTWFuYWdlclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBmb2N1c01hbmFnZXJTdGF0ZS5vbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnZm9jdXMtb3V0JykpO1xuICAgICAgfVxuICAgIH1cbiAgfSkpO1xufVxuY29uc3QgdXNlUG9ydGFsQ29udGV4dCA9ICgpID0+IFJlYWN0LnVzZUNvbnRleHQoUG9ydGFsQ29udGV4dCk7XG5cbmNvbnN0IEZPQ1VTQUJMRV9BVFRSSUJVVEUgPSAnZGF0YS1mbG9hdGluZy11aS1mb2N1c2FibGUnO1xuZnVuY3Rpb24gZ2V0RmxvYXRpbmdGb2N1c0VsZW1lbnQoZmxvYXRpbmdFbGVtZW50KSB7XG4gIGlmICghZmxvYXRpbmdFbGVtZW50KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gVHJ5IHRvIGZpbmQgdGhlIGVsZW1lbnQgdGhhdCBoYXMgYHsuLi5nZXRGbG9hdGluZ1Byb3BzKCl9YCBzcHJlYWQgb24gaXQuXG4gIC8vIFRoaXMgaW5kaWNhdGVzIHRoZSBmbG9hdGluZyBlbGVtZW50IGlzIGFjdGluZyBhcyBhIHBvc2l0aW9uaW5nIHdyYXBwZXIsIGFuZFxuICAvLyBzbyBmb2N1cyBzaG91bGQgYmUgbWFuYWdlZCBvbiB0aGUgY2hpbGQgZWxlbWVudCB3aXRoIHRoZSBldmVudCBoYW5kbGVycyBhbmRcbiAgLy8gYXJpYSBwcm9wcy5cbiAgcmV0dXJuIGZsb2F0aW5nRWxlbWVudC5oYXNBdHRyaWJ1dGUoRk9DVVNBQkxFX0FUVFJJQlVURSkgPyBmbG9hdGluZ0VsZW1lbnQgOiBmbG9hdGluZ0VsZW1lbnQucXVlcnlTZWxlY3RvcihcIltcIiArIEZPQ1VTQUJMRV9BVFRSSUJVVEUgKyBcIl1cIikgfHwgZmxvYXRpbmdFbGVtZW50O1xufVxuXG5jb25zdCBMSVNUX0xJTUlUID0gMjA7XG5sZXQgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IFtdO1xuZnVuY3Rpb24gYWRkUHJldmlvdXNseUZvY3VzZWRFbGVtZW50KGVsZW1lbnQpIHtcbiAgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cyA9IHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMuZmlsdGVyKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbiAgbGV0IHRhYmJhYmxlRWwgPSBlbGVtZW50O1xuICBpZiAoIXRhYmJhYmxlRWwgfHwgZ2V0Tm9kZU5hbWUodGFiYmFibGVFbCkgPT09ICdib2R5JykgcmV0dXJuO1xuICBpZiAoIWlzVGFiYmFibGUodGFiYmFibGVFbCwgZ2V0VGFiYmFibGVPcHRpb25zKCkpKSB7XG4gICAgY29uc3QgdGFiYmFibGVDaGlsZCA9IHRhYmJhYmxlKHRhYmJhYmxlRWwsIGdldFRhYmJhYmxlT3B0aW9ucygpKVswXTtcbiAgICBpZiAodGFiYmFibGVDaGlsZCkge1xuICAgICAgdGFiYmFibGVFbCA9IHRhYmJhYmxlQ2hpbGQ7XG4gICAgfVxuICB9XG4gIHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMucHVzaCh0YWJiYWJsZUVsKTtcbiAgaWYgKHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMubGVuZ3RoID4gTElTVF9MSU1JVCkge1xuICAgIHByZXZpb3VzbHlGb2N1c2VkRWxlbWVudHMgPSBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnRzLnNsaWNlKC1MSVNUX0xJTUlUKTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0UHJldmlvdXNseUZvY3VzZWRFbGVtZW50KCkge1xuICByZXR1cm4gcHJldmlvdXNseUZvY3VzZWRFbGVtZW50cy5zbGljZSgpLnJldmVyc2UoKS5maW5kKGVsID0+IGVsLmlzQ29ubmVjdGVkKTtcbn1cbmNvbnN0IFZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIFZpc3VhbGx5SGlkZGVuRGlzbWlzcyhwcm9wcywgcmVmKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImJ1dHRvblwiLCBfZXh0ZW5kcyh7fSwgcHJvcHMsIHtcbiAgICB0eXBlOiBcImJ1dHRvblwiLFxuICAgIHJlZjogcmVmLFxuICAgIHRhYkluZGV4OiAtMSxcbiAgICBzdHlsZTogSElEREVOX1NUWUxFU1xuICB9KSk7XG59KTtcbi8qKlxuICogUHJvdmlkZXMgZm9jdXMgbWFuYWdlbWVudCBmb3IgdGhlIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdGb2N1c01hbmFnZXJcbiAqL1xuZnVuY3Rpb24gRmxvYXRpbmdGb2N1c01hbmFnZXIocHJvcHMpIHtcbiAgY29uc3Qge1xuICAgIGNvbnRleHQsXG4gICAgY2hpbGRyZW4sXG4gICAgZGlzYWJsZWQgPSBmYWxzZSxcbiAgICBvcmRlciA9IFsnY29udGVudCddLFxuICAgIGd1YXJkczogX2d1YXJkcyA9IHRydWUsXG4gICAgaW5pdGlhbEZvY3VzID0gMCxcbiAgICByZXR1cm5Gb2N1cyA9IHRydWUsXG4gICAgcmVzdG9yZUZvY3VzID0gZmFsc2UsXG4gICAgbW9kYWwgPSB0cnVlLFxuICAgIHZpc3VhbGx5SGlkZGVuRGlzbWlzcyA9IGZhbHNlLFxuICAgIGNsb3NlT25Gb2N1c091dCA9IHRydWVcbiAgfSA9IHByb3BzO1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICByZWZzLFxuICAgIG5vZGVJZCxcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZXZlbnRzLFxuICAgIGRhdGFSZWYsXG4gICAgZmxvYXRpbmdJZCxcbiAgICBlbGVtZW50czoge1xuICAgICAgZG9tUmVmZXJlbmNlLFxuICAgICAgZmxvYXRpbmdcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCBpZ25vcmVJbml0aWFsRm9jdXMgPSB0eXBlb2YgaW5pdGlhbEZvY3VzID09PSAnbnVtYmVyJyAmJiBpbml0aWFsRm9jdXMgPCAwO1xuICAvLyBJZiB0aGUgcmVmZXJlbmNlIGlzIGEgY29tYm9ib3ggYW5kIGlzIHR5cGVhYmxlIChlLmcuIGlucHV0L3RleHRhcmVhKSxcbiAgLy8gdGhlcmUgYXJlIGRpZmZlcmVudCBmb2N1cyBzZW1hbnRpY3MuIFRoZSBndWFyZHMgc2hvdWxkIG5vdCBiZSByZW5kZXJlZCwgYnV0XG4gIC8vIGFyaWEtaGlkZGVuIHNob3VsZCBiZSBhcHBsaWVkIHRvIGFsbCBub2RlcyBzdGlsbC4gRnVydGhlciwgdGhlIHZpc3VhbGx5XG4gIC8vIGhpZGRlbiBkaXNtaXNzIGJ1dHRvbiBzaG91bGQgb25seSBhcHBlYXIgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgbm90IHRoZVxuICAvLyBzdGFydC5cbiAgY29uc3QgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94ID0gaXNUeXBlYWJsZUNvbWJvYm94KGRvbVJlZmVyZW5jZSkgJiYgaWdub3JlSW5pdGlhbEZvY3VzO1xuXG4gIC8vIEZvcmNlIHRoZSBndWFyZHMgdG8gYmUgcmVuZGVyZWQgaWYgdGhlIGBpbmVydGAgYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gIGNvbnN0IGd1YXJkcyA9IHN1cHBvcnRzSW5lcnQoKSA/IF9ndWFyZHMgOiB0cnVlO1xuICBjb25zdCBvcmRlclJlZiA9IHVzZUxhdGVzdFJlZihvcmRlcik7XG4gIGNvbnN0IGluaXRpYWxGb2N1c1JlZiA9IHVzZUxhdGVzdFJlZihpbml0aWFsRm9jdXMpO1xuICBjb25zdCByZXR1cm5Gb2N1c1JlZiA9IHVzZUxhdGVzdFJlZihyZXR1cm5Gb2N1cyk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgY29uc3QgcG9ydGFsQ29udGV4dCA9IHVzZVBvcnRhbENvbnRleHQoKTtcbiAgY29uc3Qgc3RhcnREaXNtaXNzQnV0dG9uUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBlbmREaXNtaXNzQnV0dG9uUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBwcmV2ZW50UmV0dXJuRm9jdXNSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCBpc1BvaW50ZXJEb3duUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgdGFiYmFibGVJbmRleFJlZiA9IFJlYWN0LnVzZVJlZigtMSk7XG4gIGNvbnN0IGlzSW5zaWRlUG9ydGFsID0gcG9ydGFsQ29udGV4dCAhPSBudWxsO1xuICBjb25zdCBmbG9hdGluZ0ZvY3VzRWxlbWVudCA9IGdldEZsb2F0aW5nRm9jdXNFbGVtZW50KGZsb2F0aW5nKTtcbiAgY29uc3QgZ2V0VGFiYmFibGVDb250ZW50ID0gdXNlRWZmZWN0RXZlbnQoZnVuY3Rpb24gKGNvbnRhaW5lcikge1xuICAgIGlmIChjb250YWluZXIgPT09IHZvaWQgMCkge1xuICAgICAgY29udGFpbmVyID0gZmxvYXRpbmdGb2N1c0VsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBjb250YWluZXIgPyB0YWJiYWJsZShjb250YWluZXIsIGdldFRhYmJhYmxlT3B0aW9ucygpKSA6IFtdO1xuICB9KTtcbiAgY29uc3QgZ2V0VGFiYmFibGVFbGVtZW50cyA9IHVzZUVmZmVjdEV2ZW50KGNvbnRhaW5lciA9PiB7XG4gICAgY29uc3QgY29udGVudCA9IGdldFRhYmJhYmxlQ29udGVudChjb250YWluZXIpO1xuICAgIHJldHVybiBvcmRlclJlZi5jdXJyZW50Lm1hcCh0eXBlID0+IHtcbiAgICAgIGlmIChkb21SZWZlcmVuY2UgJiYgdHlwZSA9PT0gJ3JlZmVyZW5jZScpIHtcbiAgICAgICAgcmV0dXJuIGRvbVJlZmVyZW5jZTtcbiAgICAgIH1cbiAgICAgIGlmIChmbG9hdGluZ0ZvY3VzRWxlbWVudCAmJiB0eXBlID09PSAnZmxvYXRpbmcnKSB7XG4gICAgICAgIHJldHVybiBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZW50O1xuICAgIH0pLmZpbHRlcihCb29sZWFuKS5mbGF0KCk7XG4gIH0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gIH0sIFtkaXNhYmxlZF0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChkaXNhYmxlZCkgcmV0dXJuO1xuICAgIGlmICghbW9kYWwpIHJldHVybjtcbiAgICBmdW5jdGlvbiBvbktleURvd24oZXZlbnQpIHtcbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdUYWInKSB7XG4gICAgICAgIC8vIFRoZSBmb2N1cyBndWFyZHMgaGF2ZSBub3RoaW5nIHRvIGZvY3VzLCBzbyB3ZSBuZWVkIHRvIHN0b3AgdGhlIGV2ZW50LlxuICAgICAgICBpZiAoY29udGFpbnMoZmxvYXRpbmdGb2N1c0VsZW1lbnQsIGFjdGl2ZUVsZW1lbnQoZ2V0RG9jdW1lbnQoZmxvYXRpbmdGb2N1c0VsZW1lbnQpKSkgJiYgZ2V0VGFiYmFibGVDb250ZW50KCkubGVuZ3RoID09PSAwICYmICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3gpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVscyA9IGdldFRhYmJhYmxlRWxlbWVudHMoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0KGV2ZW50KTtcbiAgICAgICAgaWYgKG9yZGVyUmVmLmN1cnJlbnRbMF0gPT09ICdyZWZlcmVuY2UnICYmIHRhcmdldCA9PT0gZG9tUmVmZXJlbmNlKSB7XG4gICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgIGVucXVldWVGb2N1cyhlbHNbZWxzLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZW5xdWV1ZUZvY3VzKGVsc1sxXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRlclJlZi5jdXJyZW50WzFdID09PSAnZmxvYXRpbmcnICYmIHRhcmdldCA9PT0gZmxvYXRpbmdGb2N1c0VsZW1lbnQgJiYgZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgIGVucXVldWVGb2N1cyhlbHNbMF0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGRvYyA9IGdldERvY3VtZW50KGZsb2F0aW5nRm9jdXNFbGVtZW50KTtcbiAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93bik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICB9O1xuICB9LCBbZGlzYWJsZWQsIGRvbVJlZmVyZW5jZSwgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIG1vZGFsLCBvcmRlclJlZiwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94LCBnZXRUYWJiYWJsZUNvbnRlbnQsIGdldFRhYmJhYmxlRWxlbWVudHNdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQpIHJldHVybjtcbiAgICBpZiAoIWZsb2F0aW5nKSByZXR1cm47XG4gICAgZnVuY3Rpb24gaGFuZGxlRm9jdXNJbihldmVudCkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0KGV2ZW50KTtcbiAgICAgIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGdldFRhYmJhYmxlQ29udGVudCgpO1xuICAgICAgY29uc3QgdGFiYmFibGVJbmRleCA9IHRhYmJhYmxlQ29udGVudC5pbmRleE9mKHRhcmdldCk7XG4gICAgICBpZiAodGFiYmFibGVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGFiYmFibGVJbmRleFJlZi5jdXJyZW50ID0gdGFiYmFibGVJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgZmxvYXRpbmcuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIGhhbmRsZUZvY3VzSW4pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c2luJywgaGFuZGxlRm9jdXNJbik7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZ2V0VGFiYmFibGVDb250ZW50XSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFjbG9zZU9uRm9jdXNPdXQpIHJldHVybjtcblxuICAgIC8vIEluIFNhZmFyaSwgYnV0dG9ucyBsb3NlIGZvY3VzIHdoZW4gcHJlc3NpbmcgdGhlbS5cbiAgICBmdW5jdGlvbiBoYW5kbGVQb2ludGVyRG93bigpIHtcbiAgICAgIGlzUG9pbnRlckRvd25SZWYuY3VycmVudCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaXNQb2ludGVyRG93blJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaGFuZGxlRm9jdXNPdXRzaWRlKGV2ZW50KSB7XG4gICAgICBjb25zdCByZWxhdGVkVGFyZ2V0ID0gZXZlbnQucmVsYXRlZFRhcmdldDtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgY29uc3QgbW92ZWRUb1VucmVsYXRlZE5vZGUgPSAhKGNvbnRhaW5zKGRvbVJlZmVyZW5jZSwgcmVsYXRlZFRhcmdldCkgfHwgY29udGFpbnMoZmxvYXRpbmcsIHJlbGF0ZWRUYXJnZXQpIHx8IGNvbnRhaW5zKHJlbGF0ZWRUYXJnZXQsIGZsb2F0aW5nKSB8fCBjb250YWlucyhwb3J0YWxDb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUsIHJlbGF0ZWRUYXJnZXQpIHx8IHJlbGF0ZWRUYXJnZXQgIT0gbnVsbCAmJiByZWxhdGVkVGFyZ2V0Lmhhc0F0dHJpYnV0ZShjcmVhdGVBdHRyaWJ1dGUoJ2ZvY3VzLWd1YXJkJykpIHx8IHRyZWUgJiYgKGdldENoaWxkcmVuKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5maW5kKG5vZGUgPT4ge1xuICAgICAgICAgIHZhciBfbm9kZSRjb250ZXh0LCBfbm9kZSRjb250ZXh0MjtcbiAgICAgICAgICByZXR1cm4gY29udGFpbnMoKF9ub2RlJGNvbnRleHQgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0LmVsZW1lbnRzLmZsb2F0aW5nLCByZWxhdGVkVGFyZ2V0KSB8fCBjb250YWlucygoX25vZGUkY29udGV4dDIgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0Mi5lbGVtZW50cy5kb21SZWZlcmVuY2UsIHJlbGF0ZWRUYXJnZXQpO1xuICAgICAgICB9KSB8fCBnZXRBbmNlc3RvcnModHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLmZpbmQobm9kZSA9PiB7XG4gICAgICAgICAgdmFyIF9ub2RlJGNvbnRleHQzLCBfbm9kZSRjb250ZXh0NDtcbiAgICAgICAgICByZXR1cm4gKChfbm9kZSRjb250ZXh0MyA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQzLmVsZW1lbnRzLmZsb2F0aW5nKSA9PT0gcmVsYXRlZFRhcmdldCB8fCAoKF9ub2RlJGNvbnRleHQ0ID0gbm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGUkY29udGV4dDQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PT0gcmVsYXRlZFRhcmdldDtcbiAgICAgICAgfSkpKTtcblxuICAgICAgICAvLyBSZXN0b3JlIGZvY3VzIHRvIHRoZSBwcmV2aW91cyB0YWJiYWJsZSBlbGVtZW50IGluZGV4IHRvIHByZXZlbnRcbiAgICAgICAgLy8gZm9jdXMgZnJvbSBiZWluZyBsb3N0IG91dHNpZGUgdGhlIGZsb2F0aW5nIHRyZWUuXG4gICAgICAgIGlmIChyZXN0b3JlRm9jdXMgJiYgbW92ZWRUb1VucmVsYXRlZE5vZGUgJiYgYWN0aXZlRWxlbWVudChnZXREb2N1bWVudChmbG9hdGluZ0ZvY3VzRWxlbWVudCkpID09PSBnZXREb2N1bWVudChmbG9hdGluZ0ZvY3VzRWxlbWVudCkuYm9keSkge1xuICAgICAgICAgIC8vIExldCBgRmxvYXRpbmdQb3J0YWxgIGVmZmVjdCBrbm93cyB0aGF0IGZvY3VzIGlzIHN0aWxsIGluc2lkZSB0aGVcbiAgICAgICAgICAvLyBmbG9hdGluZyB0cmVlLlxuICAgICAgICAgIGlmIChpc0hUTUxFbGVtZW50KGZsb2F0aW5nRm9jdXNFbGVtZW50KSkge1xuICAgICAgICAgICAgZmxvYXRpbmdGb2N1c0VsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcHJldlRhYmJhYmxlSW5kZXggPSB0YWJiYWJsZUluZGV4UmVmLmN1cnJlbnQ7XG4gICAgICAgICAgY29uc3QgdGFiYmFibGVDb250ZW50ID0gZ2V0VGFiYmFibGVDb250ZW50KCk7XG4gICAgICAgICAgY29uc3Qgbm9kZVRvRm9jdXMgPSB0YWJiYWJsZUNvbnRlbnRbcHJldlRhYmJhYmxlSW5kZXhdIHx8IHRhYmJhYmxlQ29udGVudFt0YWJiYWJsZUNvbnRlbnQubGVuZ3RoIC0gMV0gfHwgZmxvYXRpbmdGb2N1c0VsZW1lbnQ7XG4gICAgICAgICAgaWYgKGlzSFRNTEVsZW1lbnQobm9kZVRvRm9jdXMpKSB7XG4gICAgICAgICAgICBub2RlVG9Gb2N1cy5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvY3VzIGRpZCBub3QgbW92ZSBpbnNpZGUgdGhlIGZsb2F0aW5nIHRyZWUsIGFuZCB0aGVyZSBhcmUgbm8gdGFiYmFibGVcbiAgICAgICAgLy8gcG9ydGFsIGd1YXJkcyB0byBoYW5kbGUgY2xvc2luZy5cbiAgICAgICAgaWYgKChpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggPyB0cnVlIDogIW1vZGFsKSAmJiByZWxhdGVkVGFyZ2V0ICYmIG1vdmVkVG9VbnJlbGF0ZWROb2RlICYmICFpc1BvaW50ZXJEb3duUmVmLmN1cnJlbnQgJiZcbiAgICAgICAgLy8gRml4IFJlYWN0IDE4IFN0cmljdCBNb2RlIHJldHVybkZvY3VzIGR1ZSB0byBkb3VibGUgcmVuZGVyaW5nLlxuICAgICAgICByZWxhdGVkVGFyZ2V0ICE9PSBnZXRQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKSkge1xuICAgICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCAnZm9jdXMtb3V0Jyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoZmxvYXRpbmcgJiYgaXNIVE1MRWxlbWVudChkb21SZWZlcmVuY2UpKSB7XG4gICAgICBkb21SZWZlcmVuY2UuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNvdXQnLCBoYW5kbGVGb2N1c091dHNpZGUpO1xuICAgICAgZG9tUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24pO1xuICAgICAgZmxvYXRpbmcuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNvdXQnLCBoYW5kbGVGb2N1c091dHNpZGUpO1xuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgZG9tUmVmZXJlbmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgaGFuZGxlRm9jdXNPdXRzaWRlKTtcbiAgICAgICAgZG9tUmVmZXJlbmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24pO1xuICAgICAgICBmbG9hdGluZy5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIGhhbmRsZUZvY3VzT3V0c2lkZSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW2Rpc2FibGVkLCBkb21SZWZlcmVuY2UsIGZsb2F0aW5nLCBmbG9hdGluZ0ZvY3VzRWxlbWVudCwgbW9kYWwsIG5vZGVJZCwgdHJlZSwgcG9ydGFsQ29udGV4dCwgb25PcGVuQ2hhbmdlLCBjbG9zZU9uRm9jdXNPdXQsIHJlc3RvcmVGb2N1cywgZ2V0VGFiYmFibGVDb250ZW50LCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3hdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICB2YXIgX3BvcnRhbENvbnRleHQkcG9ydGFsO1xuICAgIGlmIChkaXNhYmxlZCkgcmV0dXJuO1xuXG4gICAgLy8gRG9uJ3QgaGlkZSBwb3J0YWxzIG5lc3RlZCB3aXRoaW4gdGhlIHBhcmVudCBwb3J0YWwuXG4gICAgY29uc3QgcG9ydGFsTm9kZXMgPSBBcnJheS5mcm9tKChwb3J0YWxDb250ZXh0ID09IG51bGwgfHwgKF9wb3J0YWxDb250ZXh0JHBvcnRhbCA9IHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9wb3J0YWxDb250ZXh0JHBvcnRhbC5xdWVyeVNlbGVjdG9yQWxsKFwiW1wiICsgY3JlYXRlQXR0cmlidXRlKCdwb3J0YWwnKSArIFwiXVwiKSkgfHwgW10pO1xuICAgIGlmIChmbG9hdGluZykge1xuICAgICAgY29uc3QgaW5zaWRlRWxlbWVudHMgPSBbZmxvYXRpbmcsIC4uLnBvcnRhbE5vZGVzLCBzdGFydERpc21pc3NCdXR0b25SZWYuY3VycmVudCwgZW5kRGlzbWlzc0J1dHRvblJlZi5jdXJyZW50LCBvcmRlclJlZi5jdXJyZW50LmluY2x1ZGVzKCdyZWZlcmVuY2UnKSB8fCBpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggPyBkb21SZWZlcmVuY2UgOiBudWxsXS5maWx0ZXIoeCA9PiB4ICE9IG51bGwpO1xuICAgICAgY29uc3QgY2xlYW51cCA9IG1vZGFsIHx8IGlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCA/IG1hcmtPdGhlcnMoaW5zaWRlRWxlbWVudHMsIGd1YXJkcywgIWd1YXJkcykgOiBtYXJrT3RoZXJzKGluc2lkZUVsZW1lbnRzKTtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbZGlzYWJsZWQsIGRvbVJlZmVyZW5jZSwgZmxvYXRpbmcsIG1vZGFsLCBvcmRlclJlZiwgcG9ydGFsQ29udGV4dCwgaXNVbnRyYXBwZWRUeXBlYWJsZUNvbWJvYm94LCBndWFyZHNdKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmIChkaXNhYmxlZCB8fCAhaXNIVE1MRWxlbWVudChmbG9hdGluZ0ZvY3VzRWxlbWVudCkpIHJldHVybjtcbiAgICBjb25zdCBkb2MgPSBnZXREb2N1bWVudChmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgY29uc3QgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50ID0gYWN0aXZlRWxlbWVudChkb2MpO1xuXG4gICAgLy8gV2FpdCBmb3IgYW55IGxheW91dCBlZmZlY3Qgc3RhdGUgc2V0dGVycyB0byBleGVjdXRlIHRvIHNldCBgdGFiSW5kZXhgLlxuICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgIGNvbnN0IGZvY3VzYWJsZUVsZW1lbnRzID0gZ2V0VGFiYmFibGVFbGVtZW50cyhmbG9hdGluZ0ZvY3VzRWxlbWVudCk7XG4gICAgICBjb25zdCBpbml0aWFsRm9jdXNWYWx1ZSA9IGluaXRpYWxGb2N1c1JlZi5jdXJyZW50O1xuICAgICAgY29uc3QgZWxUb0ZvY3VzID0gKHR5cGVvZiBpbml0aWFsRm9jdXNWYWx1ZSA9PT0gJ251bWJlcicgPyBmb2N1c2FibGVFbGVtZW50c1tpbml0aWFsRm9jdXNWYWx1ZV0gOiBpbml0aWFsRm9jdXNWYWx1ZS5jdXJyZW50KSB8fCBmbG9hdGluZ0ZvY3VzRWxlbWVudDtcbiAgICAgIGNvbnN0IGZvY3VzQWxyZWFkeUluc2lkZUZsb2F0aW5nRWwgPSBjb250YWlucyhmbG9hdGluZ0ZvY3VzRWxlbWVudCwgcHJldmlvdXNseUZvY3VzZWRFbGVtZW50KTtcbiAgICAgIGlmICghaWdub3JlSW5pdGlhbEZvY3VzICYmICFmb2N1c0FscmVhZHlJbnNpZGVGbG9hdGluZ0VsICYmIG9wZW4pIHtcbiAgICAgICAgZW5xdWV1ZUZvY3VzKGVsVG9Gb2N1cywge1xuICAgICAgICAgIHByZXZlbnRTY3JvbGw6IGVsVG9Gb2N1cyA9PT0gZmxvYXRpbmdGb2N1c0VsZW1lbnRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sIFtkaXNhYmxlZCwgb3BlbiwgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIGlnbm9yZUluaXRpYWxGb2N1cywgZ2V0VGFiYmFibGVFbGVtZW50cywgaW5pdGlhbEZvY3VzUmVmXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoZGlzYWJsZWQgfHwgIWZsb2F0aW5nRm9jdXNFbGVtZW50KSByZXR1cm47XG4gICAgbGV0IHByZXZlbnRSZXR1cm5Gb2N1c1Njcm9sbCA9IGZhbHNlO1xuICAgIGNvbnN0IGRvYyA9IGdldERvY3VtZW50KGZsb2F0aW5nRm9jdXNFbGVtZW50KTtcbiAgICBjb25zdCBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQgPSBhY3RpdmVFbGVtZW50KGRvYyk7XG4gICAgY29uc3QgY29udGV4dERhdGEgPSBkYXRhUmVmLmN1cnJlbnQ7XG4gICAgbGV0IG9wZW5FdmVudCA9IGNvbnRleHREYXRhLm9wZW5FdmVudDtcbiAgICBjb25zdCBkb21SZWZlcmVuY2UgPSByZWZzLmRvbVJlZmVyZW5jZS5jdXJyZW50O1xuICAgIGFkZFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudChwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQpO1xuXG4gICAgLy8gRGlzbWlzc2luZyB2aWEgb3V0c2lkZSBwcmVzcyBzaG91bGQgYWx3YXlzIGlnbm9yZSBgcmV0dXJuRm9jdXNgIHRvXG4gICAgLy8gcHJldmVudCB1bndhbnRlZCBzY3JvbGxpbmcuXG4gICAgZnVuY3Rpb24gb25PcGVuQ2hhbmdlKF9yZWYpIHtcbiAgICAgIGxldCB7XG4gICAgICAgIG9wZW4sXG4gICAgICAgIHJlYXNvbixcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIG5lc3RlZFxuICAgICAgfSA9IF9yZWY7XG4gICAgICBpZiAob3Blbikge1xuICAgICAgICBvcGVuRXZlbnQgPSBldmVudDtcbiAgICAgIH1cbiAgICAgIGlmIChyZWFzb24gPT09ICdlc2NhcGUta2V5JyAmJiByZWZzLmRvbVJlZmVyZW5jZS5jdXJyZW50KSB7XG4gICAgICAgIGFkZFByZXZpb3VzbHlGb2N1c2VkRWxlbWVudChyZWZzLmRvbVJlZmVyZW5jZS5jdXJyZW50KTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWFzb24gPT09ICdob3ZlcicgJiYgZXZlbnQudHlwZSA9PT0gJ21vdXNlbGVhdmUnKSB7XG4gICAgICAgIHByZXZlbnRSZXR1cm5Gb2N1c1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWFzb24gIT09ICdvdXRzaWRlLXByZXNzJykgcmV0dXJuO1xuICAgICAgaWYgKG5lc3RlZCkge1xuICAgICAgICBwcmV2ZW50UmV0dXJuRm9jdXNSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgICBwcmV2ZW50UmV0dXJuRm9jdXNTY3JvbGwgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSAhKGlzVmlydHVhbENsaWNrKGV2ZW50KSB8fCBpc1ZpcnR1YWxQb2ludGVyRXZlbnQoZXZlbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZXZlbnRzLm9uKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZXZlbnRzLm9mZignb3BlbmNoYW5nZScsIG9uT3BlbkNoYW5nZSk7XG4gICAgICBjb25zdCBhY3RpdmVFbCA9IGFjdGl2ZUVsZW1lbnQoZG9jKTtcbiAgICAgIGNvbnN0IGlzRm9jdXNJbnNpZGVGbG9hdGluZ1RyZWUgPSBjb250YWlucyhmbG9hdGluZywgYWN0aXZlRWwpIHx8IHRyZWUgJiYgZ2V0Q2hpbGRyZW4odHJlZS5ub2Rlc1JlZi5jdXJyZW50LCBub2RlSWQpLnNvbWUobm9kZSA9PiB7XG4gICAgICAgIHZhciBfbm9kZSRjb250ZXh0NTtcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5zKChfbm9kZSRjb250ZXh0NSA9IG5vZGUuY29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9ub2RlJGNvbnRleHQ1LmVsZW1lbnRzLmZsb2F0aW5nLCBhY3RpdmVFbCk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNob3VsZEZvY3VzUmVmZXJlbmNlID0gaXNGb2N1c0luc2lkZUZsb2F0aW5nVHJlZSB8fCBvcGVuRXZlbnQgJiYgWydjbGljaycsICdtb3VzZWRvd24nXS5pbmNsdWRlcyhvcGVuRXZlbnQudHlwZSk7XG4gICAgICBpZiAoc2hvdWxkRm9jdXNSZWZlcmVuY2UgJiYgcmVmcy5kb21SZWZlcmVuY2UuY3VycmVudCkge1xuICAgICAgICBhZGRQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQocmVmcy5kb21SZWZlcmVuY2UuY3VycmVudCk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXR1cm5Db250ZXh0RWxlbWVudCA9IGRvbVJlZmVyZW5jZSB8fCBwcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQ7XG4gICAgICBjb25zdCB0YWJiYWJsZUVsZW1lbnRzID0gdGFiYmFibGUoZ2V0RG9jdW1lbnQocmV0dXJuQ29udGV4dEVsZW1lbnQpLmJvZHksIGdldFRhYmJhYmxlT3B0aW9ucygpKTtcblxuICAgICAgLy8gV2FpdCBmb3IgdGhlIHJldHVybiBlbGVtZW50IHRvIGdldCBwb3RlbnRpYWxseSBkaXNjb25uZWN0ZWQgYmVmb3JlXG4gICAgICAvLyBjaGVja2luZy5cbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgbGV0IHJldHVybkVsZW1lbnQgPSBnZXRQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKTtcbiAgICAgICAgaWYgKCFyZXR1cm5FbGVtZW50ICYmIGlzSFRNTEVsZW1lbnQocmV0dXJuQ29udGV4dEVsZW1lbnQpICYmIGZsb2F0aW5nKSB7XG4gICAgICAgICAgcmV0dXJuRWxlbWVudCA9IGdldENsb3Nlc3RUYWJiYWJsZUVsZW1lbnQodGFiYmFibGVFbGVtZW50cywgcmV0dXJuQ29udGV4dEVsZW1lbnQsIGZsb2F0aW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgICAgICAgcmV0dXJuRm9jdXNSZWYuY3VycmVudCAmJiAhcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgJiYgaXNIVE1MRWxlbWVudChyZXR1cm5FbGVtZW50KSAmJiAoXG4gICAgICAgIC8vIElmIHRoZSBmb2N1cyBtb3ZlZCBzb21ld2hlcmUgZWxzZSBhZnRlciBtb3VudCwgYXZvaWQgcmV0dXJuaW5nIGZvY3VzXG4gICAgICAgIC8vIHNpbmNlIGl0IGxpa2VseSBlbnRlcmVkIGEgZGlmZmVyZW50IGVsZW1lbnQgd2hpY2ggc2hvdWxkIGJlXG4gICAgICAgIC8vIHJlc3BlY3RlZDogaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yNjA3XG4gICAgICAgIHJldHVybkVsZW1lbnQgIT09IGFjdGl2ZUVsICYmIGFjdGl2ZUVsICE9PSBkb2MuYm9keSA/IGlzRm9jdXNJbnNpZGVGbG9hdGluZ1RyZWUgOiB0cnVlKSkge1xuICAgICAgICAgIHJldHVybkVsZW1lbnQuZm9jdXMoe1xuICAgICAgICAgICAgcHJldmVudFNjcm9sbDogcHJldmVudFJldHVybkZvY3VzU2Nyb2xsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG4gIH0sIFtkaXNhYmxlZCwgZmxvYXRpbmcsIGZsb2F0aW5nRm9jdXNFbGVtZW50LCByZXR1cm5Gb2N1c1JlZiwgZGF0YVJlZiwgcmVmcywgZXZlbnRzLCB0cmVlLCBub2RlSWRdKTtcblxuICAvLyBTeW5jaHJvbml6ZSB0aGUgYGNvbnRleHRgICYgYG1vZGFsYCB2YWx1ZSB0byB0aGUgRmxvYXRpbmdQb3J0YWwgY29udGV4dC5cbiAgLy8gSXQgd2lsbCBkZWNpZGUgd2hldGhlciBvciBub3QgaXQgbmVlZHMgdG8gcmVuZGVyIGl0cyBvd24gZ3VhcmRzLlxuICBpbmRleCgoKSA9PiB7XG4gICAgaWYgKGRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKCFwb3J0YWxDb250ZXh0KSByZXR1cm47XG4gICAgcG9ydGFsQ29udGV4dC5zZXRGb2N1c01hbmFnZXJTdGF0ZSh7XG4gICAgICBtb2RhbCxcbiAgICAgIGNsb3NlT25Gb2N1c091dCxcbiAgICAgIG9wZW4sXG4gICAgICBvbk9wZW5DaGFuZ2UsXG4gICAgICByZWZzXG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHBvcnRhbENvbnRleHQuc2V0Rm9jdXNNYW5hZ2VyU3RhdGUobnVsbCk7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBwb3J0YWxDb250ZXh0LCBtb2RhbCwgb3Blbiwgb25PcGVuQ2hhbmdlLCByZWZzLCBjbG9zZU9uRm9jdXNPdXRdKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmIChkaXNhYmxlZCkgcmV0dXJuO1xuICAgIGlmICghZmxvYXRpbmdGb2N1c0VsZW1lbnQpIHJldHVybjtcbiAgICBpZiAodHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgIT09ICdmdW5jdGlvbicpIHJldHVybjtcbiAgICBpZiAoaWdub3JlSW5pdGlhbEZvY3VzKSByZXR1cm47XG4gICAgY29uc3QgaGFuZGxlTXV0YXRpb24gPSAoKSA9PiB7XG4gICAgICBjb25zdCB0YWJJbmRleCA9IGZsb2F0aW5nRm9jdXNFbGVtZW50LmdldEF0dHJpYnV0ZSgndGFiaW5kZXgnKTtcbiAgICAgIGNvbnN0IHRhYmJhYmxlQ29udGVudCA9IGdldFRhYmJhYmxlQ29udGVudCgpO1xuICAgICAgY29uc3QgYWN0aXZlRWwgPSBhY3RpdmVFbGVtZW50KGdldERvY3VtZW50KGZsb2F0aW5nKSk7XG4gICAgICBjb25zdCB0YWJiYWJsZUluZGV4ID0gdGFiYmFibGVDb250ZW50LmluZGV4T2YoYWN0aXZlRWwpO1xuICAgICAgaWYgKHRhYmJhYmxlSW5kZXggIT09IC0xKSB7XG4gICAgICAgIHRhYmJhYmxlSW5kZXhSZWYuY3VycmVudCA9IHRhYmJhYmxlSW5kZXg7XG4gICAgICB9XG4gICAgICBpZiAob3JkZXJSZWYuY3VycmVudC5pbmNsdWRlcygnZmxvYXRpbmcnKSB8fCBhY3RpdmVFbCAhPT0gcmVmcy5kb21SZWZlcmVuY2UuY3VycmVudCAmJiB0YWJiYWJsZUNvbnRlbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlmICh0YWJJbmRleCAhPT0gJzAnKSB7XG4gICAgICAgICAgZmxvYXRpbmdGb2N1c0VsZW1lbnQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICcwJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGFiSW5kZXggIT09ICctMScpIHtcbiAgICAgICAgZmxvYXRpbmdGb2N1c0VsZW1lbnQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpO1xuICAgICAgfVxuICAgIH07XG4gICAgaGFuZGxlTXV0YXRpb24oKTtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGhhbmRsZU11dGF0aW9uKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGZsb2F0aW5nRm9jdXNFbGVtZW50LCB7XG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgYXR0cmlidXRlczogdHJ1ZVxuICAgIH0pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfTtcbiAgfSwgW2Rpc2FibGVkLCBmbG9hdGluZywgZmxvYXRpbmdGb2N1c0VsZW1lbnQsIHJlZnMsIG9yZGVyUmVmLCBnZXRUYWJiYWJsZUNvbnRlbnQsIGlnbm9yZUluaXRpYWxGb2N1c10pO1xuICBmdW5jdGlvbiByZW5kZXJEaXNtaXNzQnV0dG9uKGxvY2F0aW9uKSB7XG4gICAgaWYgKGRpc2FibGVkIHx8ICF2aXN1YWxseUhpZGRlbkRpc21pc3MgfHwgIW1vZGFsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFZpc3VhbGx5SGlkZGVuRGlzbWlzcywge1xuICAgICAgcmVmOiBsb2NhdGlvbiA9PT0gJ3N0YXJ0JyA/IHN0YXJ0RGlzbWlzc0J1dHRvblJlZiA6IGVuZERpc21pc3NCdXR0b25SZWYsXG4gICAgICBvbkNsaWNrOiBldmVudCA9PiBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50Lm5hdGl2ZUV2ZW50KVxuICAgIH0sIHR5cGVvZiB2aXN1YWxseUhpZGRlbkRpc21pc3MgPT09ICdzdHJpbmcnID8gdmlzdWFsbHlIaWRkZW5EaXNtaXNzIDogJ0Rpc21pc3MnKTtcbiAgfVxuICBjb25zdCBzaG91bGRSZW5kZXJHdWFyZHMgPSAhZGlzYWJsZWQgJiYgZ3VhcmRzICYmIChtb2RhbCA/ICFpc1VudHJhcHBlZFR5cGVhYmxlQ29tYm9ib3ggOiB0cnVlKSAmJiAoaXNJbnNpZGVQb3J0YWwgfHwgbW9kYWwpO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3QuRnJhZ21lbnQsIG51bGwsIHNob3VsZFJlbmRlckd1YXJkcyAmJiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGb2N1c0d1YXJkLCB7XG4gICAgXCJkYXRhLXR5cGVcIjogXCJpbnNpZGVcIixcbiAgICByZWY6IHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQuYmVmb3JlSW5zaWRlUmVmLFxuICAgIG9uRm9jdXM6IGV2ZW50ID0+IHtcbiAgICAgIGlmIChtb2RhbCkge1xuICAgICAgICBjb25zdCBlbHMgPSBnZXRUYWJiYWJsZUVsZW1lbnRzKCk7XG4gICAgICAgIGVucXVldWVGb2N1cyhvcmRlclswXSA9PT0gJ3JlZmVyZW5jZScgPyBlbHNbMF0gOiBlbHNbZWxzLmxlbmd0aCAtIDFdKTtcbiAgICAgIH0gZWxzZSBpZiAocG9ydGFsQ29udGV4dCAhPSBudWxsICYmIHBvcnRhbENvbnRleHQucHJlc2VydmVUYWJPcmRlciAmJiBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpIHtcbiAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGlzT3V0c2lkZUV2ZW50KGV2ZW50LCBwb3J0YWxDb250ZXh0LnBvcnRhbE5vZGUpKSB7XG4gICAgICAgICAgY29uc3QgbmV4dFRhYmJhYmxlID0gZ2V0TmV4dFRhYmJhYmxlKCkgfHwgZG9tUmVmZXJlbmNlO1xuICAgICAgICAgIG5leHRUYWJiYWJsZSA9PSBudWxsIHx8IG5leHRUYWJiYWJsZS5mb2N1cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBfcG9ydGFsQ29udGV4dCRiZWZvcmU7XG4gICAgICAgICAgKF9wb3J0YWxDb250ZXh0JGJlZm9yZSA9IHBvcnRhbENvbnRleHQuYmVmb3JlT3V0c2lkZVJlZi5jdXJyZW50KSA9PSBudWxsIHx8IF9wb3J0YWxDb250ZXh0JGJlZm9yZS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KSwgIWlzVW50cmFwcGVkVHlwZWFibGVDb21ib2JveCAmJiByZW5kZXJEaXNtaXNzQnV0dG9uKCdzdGFydCcpLCBjaGlsZHJlbiwgcmVuZGVyRGlzbWlzc0J1dHRvbignZW5kJyksIHNob3VsZFJlbmRlckd1YXJkcyAmJiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChGb2N1c0d1YXJkLCB7XG4gICAgXCJkYXRhLXR5cGVcIjogXCJpbnNpZGVcIixcbiAgICByZWY6IHBvcnRhbENvbnRleHQgPT0gbnVsbCA/IHZvaWQgMCA6IHBvcnRhbENvbnRleHQuYWZ0ZXJJbnNpZGVSZWYsXG4gICAgb25Gb2N1czogZXZlbnQgPT4ge1xuICAgICAgaWYgKG1vZGFsKSB7XG4gICAgICAgIGVucXVldWVGb2N1cyhnZXRUYWJiYWJsZUVsZW1lbnRzKClbMF0pO1xuICAgICAgfSBlbHNlIGlmIChwb3J0YWxDb250ZXh0ICE9IG51bGwgJiYgcG9ydGFsQ29udGV4dC5wcmVzZXJ2ZVRhYk9yZGVyICYmIHBvcnRhbENvbnRleHQucG9ydGFsTm9kZSkge1xuICAgICAgICBpZiAoY2xvc2VPbkZvY3VzT3V0KSB7XG4gICAgICAgICAgcHJldmVudFJldHVybkZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc091dHNpZGVFdmVudChldmVudCwgcG9ydGFsQ29udGV4dC5wb3J0YWxOb2RlKSkge1xuICAgICAgICAgIGNvbnN0IHByZXZUYWJiYWJsZSA9IGdldFByZXZpb3VzVGFiYmFibGUoKSB8fCBkb21SZWZlcmVuY2U7XG4gICAgICAgICAgcHJldlRhYmJhYmxlID09IG51bGwgfHwgcHJldlRhYmJhYmxlLmZvY3VzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIF9wb3J0YWxDb250ZXh0JGFmdGVyTztcbiAgICAgICAgICAoX3BvcnRhbENvbnRleHQkYWZ0ZXJPID0gcG9ydGFsQ29udGV4dC5hZnRlck91dHNpZGVSZWYuY3VycmVudCkgPT0gbnVsbCB8fCBfcG9ydGFsQ29udGV4dCRhZnRlck8uZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSkpO1xufVxuXG5jb25zdCBhY3RpdmVMb2NrcyA9IC8qI19fUFVSRV9fKi9uZXcgU2V0KCk7XG4vKipcbiAqIFByb3ZpZGVzIGJhc2Ugc3R5bGluZyBmb3IgYSBmaXhlZCBvdmVybGF5IGVsZW1lbnQgdG8gZGltIGNvbnRlbnQgb3IgYmxvY2tcbiAqIHBvaW50ZXIgZXZlbnRzIGJlaGluZCBhIGZsb2F0aW5nIGVsZW1lbnQuXG4gKiBJdCdzIGEgcmVndWxhciBgPGRpdj5gLCBzbyBpdCBjYW4gYmUgc3R5bGVkIHZpYSBhbnkgQ1NTIHNvbHV0aW9uIHlvdSBwcmVmZXIuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvRmxvYXRpbmdPdmVybGF5XG4gKi9cbmNvbnN0IEZsb2F0aW5nT3ZlcmxheSA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIEZsb2F0aW5nT3ZlcmxheShwcm9wcywgcmVmKSB7XG4gIGNvbnN0IHtcbiAgICBsb2NrU2Nyb2xsID0gZmFsc2UsXG4gICAgLi4ucmVzdFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGxvY2tJZCA9IHVzZUlkKCk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoIWxvY2tTY3JvbGwpIHJldHVybjtcbiAgICBhY3RpdmVMb2Nrcy5hZGQobG9ja0lkKTtcbiAgICBjb25zdCBpc0lPUyA9IC9pUChob25lfGFkfG9kKXxpT1MvLnRlc3QoZ2V0UGxhdGZvcm0oKSk7XG4gICAgY29uc3QgYm9keVN0eWxlID0gZG9jdW1lbnQuYm9keS5zdHlsZTtcbiAgICAvLyBSVEwgPGJvZHk+IHNjcm9sbGJhclxuICAgIGNvbnN0IHNjcm9sbGJhclggPSBNYXRoLnJvdW5kKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0KSArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIGNvbnN0IHBhZGRpbmdQcm9wID0gc2Nyb2xsYmFyWCA/ICdwYWRkaW5nTGVmdCcgOiAncGFkZGluZ1JpZ2h0JztcbiAgICBjb25zdCBzY3JvbGxiYXJXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoIC0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IHNjcm9sbFggPSBib2R5U3R5bGUubGVmdCA/IHBhcnNlRmxvYXQoYm9keVN0eWxlLmxlZnQpIDogd2luZG93LnNjcm9sbFg7XG4gICAgY29uc3Qgc2Nyb2xsWSA9IGJvZHlTdHlsZS50b3AgPyBwYXJzZUZsb2F0KGJvZHlTdHlsZS50b3ApIDogd2luZG93LnNjcm9sbFk7XG4gICAgYm9keVN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgaWYgKHNjcm9sbGJhcldpZHRoKSB7XG4gICAgICBib2R5U3R5bGVbcGFkZGluZ1Byb3BdID0gc2Nyb2xsYmFyV2lkdGggKyBcInB4XCI7XG4gICAgfVxuXG4gICAgLy8gT25seSBpT1MgZG9lc24ndCByZXNwZWN0IGBvdmVyZmxvdzogaGlkZGVuYCBvbiBkb2N1bWVudC5ib2R5LCBhbmQgdGhpc1xuICAgIC8vIHRlY2huaXF1ZSBoYXMgZmV3ZXIgc2lkZSBlZmZlY3RzLlxuICAgIGlmIChpc0lPUykge1xuICAgICAgdmFyIF93aW5kb3ckdmlzdWFsVmlld3BvciwgX3dpbmRvdyR2aXN1YWxWaWV3cG9yMjtcbiAgICAgIC8vIGlPUyAxMiBkb2VzIG5vdCBzdXBwb3J0IGB2aXN1YWxWaWV3cG9ydGAuXG4gICAgICBjb25zdCBvZmZzZXRMZWZ0ID0gKChfd2luZG93JHZpc3VhbFZpZXdwb3IgPSB3aW5kb3cudmlzdWFsVmlld3BvcnQpID09IG51bGwgPyB2b2lkIDAgOiBfd2luZG93JHZpc3VhbFZpZXdwb3Iub2Zmc2V0TGVmdCkgfHwgMDtcbiAgICAgIGNvbnN0IG9mZnNldFRvcCA9ICgoX3dpbmRvdyR2aXN1YWxWaWV3cG9yMiA9IHdpbmRvdy52aXN1YWxWaWV3cG9ydCkgPT0gbnVsbCA/IHZvaWQgMCA6IF93aW5kb3ckdmlzdWFsVmlld3BvcjIub2Zmc2V0VG9wKSB8fCAwO1xuICAgICAgT2JqZWN0LmFzc2lnbihib2R5U3R5bGUsIHtcbiAgICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICAgIHRvcDogLShzY3JvbGxZIC0gTWF0aC5mbG9vcihvZmZzZXRUb3ApKSArIFwicHhcIixcbiAgICAgICAgbGVmdDogLShzY3JvbGxYIC0gTWF0aC5mbG9vcihvZmZzZXRMZWZ0KSkgKyBcInB4XCIsXG4gICAgICAgIHJpZ2h0OiAnMCdcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgYWN0aXZlTG9ja3MuZGVsZXRlKGxvY2tJZCk7XG4gICAgICBpZiAoYWN0aXZlTG9ja3Muc2l6ZSA9PT0gMCkge1xuICAgICAgICBPYmplY3QuYXNzaWduKGJvZHlTdHlsZSwge1xuICAgICAgICAgIG92ZXJmbG93OiAnJyxcbiAgICAgICAgICBbcGFkZGluZ1Byb3BdOiAnJ1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzSU9TKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihib2R5U3R5bGUsIHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnJyxcbiAgICAgICAgICAgIHRvcDogJycsXG4gICAgICAgICAgICBsZWZ0OiAnJyxcbiAgICAgICAgICAgIHJpZ2h0OiAnJ1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyhzY3JvbGxYLCBzY3JvbGxZKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH0sIFtsb2NrSWQsIGxvY2tTY3JvbGxdKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIF9leHRlbmRzKHtcbiAgICByZWY6IHJlZlxuICB9LCByZXN0LCB7XG4gICAgc3R5bGU6IHtcbiAgICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgIHRvcDogMCxcbiAgICAgIHJpZ2h0OiAwLFxuICAgICAgYm90dG9tOiAwLFxuICAgICAgbGVmdDogMCxcbiAgICAgIC4uLnJlc3Quc3R5bGVcbiAgICB9XG4gIH0pKTtcbn0pO1xuXG5mdW5jdGlvbiBpc0J1dHRvblRhcmdldChldmVudCkge1xuICByZXR1cm4gaXNIVE1MRWxlbWVudChldmVudC50YXJnZXQpICYmIGV2ZW50LnRhcmdldC50YWdOYW1lID09PSAnQlVUVE9OJztcbn1cbmZ1bmN0aW9uIGlzU3BhY2VJZ25vcmVkKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzVHlwZWFibGVFbGVtZW50KGVsZW1lbnQpO1xufVxuLyoqXG4gKiBPcGVucyBvciBjbG9zZXMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2hlbiBjbGlja2luZyB0aGUgcmVmZXJlbmNlIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlQ2xpY2tcbiAqL1xuZnVuY3Rpb24gdXNlQ2xpY2soY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBkYXRhUmVmLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICBkb21SZWZlcmVuY2VcbiAgICB9XG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZXZlbnQ6IGV2ZW50T3B0aW9uID0gJ2NsaWNrJyxcbiAgICB0b2dnbGUgPSB0cnVlLFxuICAgIGlnbm9yZU1vdXNlID0gZmFsc2UsXG4gICAga2V5Ym9hcmRIYW5kbGVycyA9IHRydWVcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwb2ludGVyVHlwZVJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBjb25zdCBkaWRLZXlEb3duUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uUG9pbnRlckRvd24oZXZlbnQpIHtcbiAgICAgIHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQgPSBldmVudC5wb2ludGVyVHlwZTtcbiAgICB9LFxuICAgIG9uTW91c2VEb3duKGV2ZW50KSB7XG4gICAgICBjb25zdCBwb2ludGVyVHlwZSA9IHBvaW50ZXJUeXBlUmVmLmN1cnJlbnQ7XG5cbiAgICAgIC8vIElnbm9yZSBhbGwgYnV0dG9ucyBleGNlcHQgZm9yIHRoZSBcIm1haW5cIiBidXR0b24uXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTW91c2VFdmVudC9idXR0b25cbiAgICAgIGlmIChldmVudC5idXR0b24gIT09IDApIHJldHVybjtcbiAgICAgIGlmIChldmVudE9wdGlvbiA9PT0gJ2NsaWNrJykgcmV0dXJuO1xuICAgICAgaWYgKGlzTW91c2VMaWtlUG9pbnRlclR5cGUocG9pbnRlclR5cGUsIHRydWUpICYmIGlnbm9yZU1vdXNlKSByZXR1cm47XG4gICAgICBpZiAob3BlbiAmJiB0b2dnbGUgJiYgKGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgPyBkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50LnR5cGUgPT09ICdtb3VzZWRvd24nIDogdHJ1ZSkpIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcmV2ZW50IHN0ZWFsaW5nIGZvY3VzIGZyb20gdGhlIGZsb2F0aW5nIGVsZW1lbnRcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9uQ2xpY2soZXZlbnQpIHtcbiAgICAgIGNvbnN0IHBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGVSZWYuY3VycmVudDtcbiAgICAgIGlmIChldmVudE9wdGlvbiA9PT0gJ21vdXNlZG93bicgJiYgcG9pbnRlclR5cGVSZWYuY3VycmVudCkge1xuICAgICAgICBwb2ludGVyVHlwZVJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZSwgdHJ1ZSkgJiYgaWdub3JlTW91c2UpIHJldHVybjtcbiAgICAgIGlmIChvcGVuICYmIHRvZ2dsZSAmJiAoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCA/IGRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQudHlwZSA9PT0gJ2NsaWNrJyA6IHRydWUpKSB7XG4gICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdjbGljaycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9uS2V5RG93bihldmVudCkge1xuICAgICAgcG9pbnRlclR5cGVSZWYuY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkIHx8ICFrZXlib2FyZEhhbmRsZXJzIHx8IGlzQnV0dG9uVGFyZ2V0KGV2ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSAnICcgJiYgIWlzU3BhY2VJZ25vcmVkKGRvbVJlZmVyZW5jZSkpIHtcbiAgICAgICAgLy8gUHJldmVudCBzY3JvbGxpbmdcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZGlkS2V5RG93blJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgaWYgKG9wZW4gJiYgdG9nZ2xlKSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgb25LZXlVcChldmVudCkge1xuICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHwgIWtleWJvYXJkSGFuZGxlcnMgfHwgaXNCdXR0b25UYXJnZXQoZXZlbnQpIHx8IGlzU3BhY2VJZ25vcmVkKGRvbVJlZmVyZW5jZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJyAnICYmIGRpZEtleURvd25SZWYuY3VycmVudCkge1xuICAgICAgICBkaWRLZXlEb3duUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgaWYgKG9wZW4gJiYgdG9nZ2xlKSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBldmVudC5uYXRpdmVFdmVudCwgJ2NsaWNrJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb25PcGVuQ2hhbmdlKHRydWUsIGV2ZW50Lm5hdGl2ZUV2ZW50LCAnY2xpY2snKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSksIFtkYXRhUmVmLCBkb21SZWZlcmVuY2UsIGV2ZW50T3B0aW9uLCBpZ25vcmVNb3VzZSwga2V5Ym9hcmRIYW5kbGVycywgb25PcGVuQ2hhbmdlLCBvcGVuLCB0b2dnbGVdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2VcbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlXSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpcnR1YWxFbGVtZW50KGRvbUVsZW1lbnQsIGRhdGEpIHtcbiAgbGV0IG9mZnNldFggPSBudWxsO1xuICBsZXQgb2Zmc2V0WSA9IG51bGw7XG4gIGxldCBpc0F1dG9VcGRhdGVFdmVudCA9IGZhbHNlO1xuICByZXR1cm4ge1xuICAgIGNvbnRleHRFbGVtZW50OiBkb21FbGVtZW50IHx8IHVuZGVmaW5lZCxcbiAgICBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKSB7XG4gICAgICB2YXIgX2RhdGEkZGF0YVJlZiRjdXJyZW50O1xuICAgICAgY29uc3QgZG9tUmVjdCA9IChkb21FbGVtZW50ID09IG51bGwgPyB2b2lkIDAgOiBkb21FbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSB8fCB7XG4gICAgICAgIHdpZHRoOiAwLFxuICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDBcbiAgICAgIH07XG4gICAgICBjb25zdCBpc1hBeGlzID0gZGF0YS5heGlzID09PSAneCcgfHwgZGF0YS5heGlzID09PSAnYm90aCc7XG4gICAgICBjb25zdCBpc1lBeGlzID0gZGF0YS5heGlzID09PSAneScgfHwgZGF0YS5heGlzID09PSAnYm90aCc7XG4gICAgICBjb25zdCBjYW5UcmFja0N1cnNvck9uQXV0b1VwZGF0ZSA9IFsnbW91c2VlbnRlcicsICdtb3VzZW1vdmUnXS5pbmNsdWRlcygoKF9kYXRhJGRhdGFSZWYkY3VycmVudCA9IGRhdGEuZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9kYXRhJGRhdGFSZWYkY3VycmVudC50eXBlKSB8fCAnJykgJiYgZGF0YS5wb2ludGVyVHlwZSAhPT0gJ3RvdWNoJztcbiAgICAgIGxldCB3aWR0aCA9IGRvbVJlY3Qud2lkdGg7XG4gICAgICBsZXQgaGVpZ2h0ID0gZG9tUmVjdC5oZWlnaHQ7XG4gICAgICBsZXQgeCA9IGRvbVJlY3QueDtcbiAgICAgIGxldCB5ID0gZG9tUmVjdC55O1xuICAgICAgaWYgKG9mZnNldFggPT0gbnVsbCAmJiBkYXRhLnggJiYgaXNYQXhpcykge1xuICAgICAgICBvZmZzZXRYID0gZG9tUmVjdC54IC0gZGF0YS54O1xuICAgICAgfVxuICAgICAgaWYgKG9mZnNldFkgPT0gbnVsbCAmJiBkYXRhLnkgJiYgaXNZQXhpcykge1xuICAgICAgICBvZmZzZXRZID0gZG9tUmVjdC55IC0gZGF0YS55O1xuICAgICAgfVxuICAgICAgeCAtPSBvZmZzZXRYIHx8IDA7XG4gICAgICB5IC09IG9mZnNldFkgfHwgMDtcbiAgICAgIHdpZHRoID0gMDtcbiAgICAgIGhlaWdodCA9IDA7XG4gICAgICBpZiAoIWlzQXV0b1VwZGF0ZUV2ZW50IHx8IGNhblRyYWNrQ3Vyc29yT25BdXRvVXBkYXRlKSB7XG4gICAgICAgIHdpZHRoID0gZGF0YS5heGlzID09PSAneScgPyBkb21SZWN0LndpZHRoIDogMDtcbiAgICAgICAgaGVpZ2h0ID0gZGF0YS5heGlzID09PSAneCcgPyBkb21SZWN0LmhlaWdodCA6IDA7XG4gICAgICAgIHggPSBpc1hBeGlzICYmIGRhdGEueCAhPSBudWxsID8gZGF0YS54IDogeDtcbiAgICAgICAgeSA9IGlzWUF4aXMgJiYgZGF0YS55ICE9IG51bGwgPyBkYXRhLnkgOiB5O1xuICAgICAgfSBlbHNlIGlmIChpc0F1dG9VcGRhdGVFdmVudCAmJiAhY2FuVHJhY2tDdXJzb3JPbkF1dG9VcGRhdGUpIHtcbiAgICAgICAgaGVpZ2h0ID0gZGF0YS5heGlzID09PSAneCcgPyBkb21SZWN0LmhlaWdodCA6IGhlaWdodDtcbiAgICAgICAgd2lkdGggPSBkYXRhLmF4aXMgPT09ICd5JyA/IGRvbVJlY3Qud2lkdGggOiB3aWR0aDtcbiAgICAgIH1cbiAgICAgIGlzQXV0b1VwZGF0ZUV2ZW50ID0gdHJ1ZTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIHRvcDogeSxcbiAgICAgICAgcmlnaHQ6IHggKyB3aWR0aCxcbiAgICAgICAgYm90dG9tOiB5ICsgaGVpZ2h0LFxuICAgICAgICBsZWZ0OiB4XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIGlzTW91c2VCYXNlZEV2ZW50KGV2ZW50KSB7XG4gIHJldHVybiBldmVudCAhPSBudWxsICYmIGV2ZW50LmNsaWVudFggIT0gbnVsbDtcbn1cbi8qKlxuICogUG9zaXRpb25zIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbGF0aXZlIHRvIGEgY2xpZW50IHBvaW50IChpbiB0aGUgdmlld3BvcnQpLFxuICogc3VjaCBhcyB0aGUgbW91c2UgcG9zaXRpb24uIEJ5IGRlZmF1bHQsIGl0IGZvbGxvd3MgdGhlIG1vdXNlIGN1cnNvci5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VDbGllbnRQb2ludFxuICovXG5mdW5jdGlvbiB1c2VDbGllbnRQb2ludChjb250ZXh0LCBwcm9wcykge1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgZGF0YVJlZixcbiAgICBlbGVtZW50czoge1xuICAgICAgZmxvYXRpbmcsXG4gICAgICBkb21SZWZlcmVuY2VcbiAgICB9LFxuICAgIHJlZnNcbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBlbmFibGVkID0gdHJ1ZSxcbiAgICBheGlzID0gJ2JvdGgnLFxuICAgIHggPSBudWxsLFxuICAgIHkgPSBudWxsXG4gIH0gPSBwcm9wcztcbiAgY29uc3QgaW5pdGlhbFJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGNsZWFudXBMaXN0ZW5lclJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgY29uc3QgW3BvaW50ZXJUeXBlLCBzZXRQb2ludGVyVHlwZV0gPSBSZWFjdC51c2VTdGF0ZSgpO1xuICBjb25zdCBbcmVhY3RpdmUsIHNldFJlYWN0aXZlXSA9IFJlYWN0LnVzZVN0YXRlKFtdKTtcbiAgY29uc3Qgc2V0UmVmZXJlbmNlID0gdXNlRWZmZWN0RXZlbnQoKHgsIHkpID0+IHtcbiAgICBpZiAoaW5pdGlhbFJlZi5jdXJyZW50KSByZXR1cm47XG5cbiAgICAvLyBQcmV2ZW50IHNldHRpbmcgaWYgdGhlIG9wZW4gZXZlbnQgd2FzIG5vdCBhIG1vdXNlLWxpa2Ugb25lXG4gICAgLy8gKGUuZy4gZm9jdXMgdG8gb3BlbiwgdGhlbiBob3ZlciBvdmVyIHRoZSByZWZlcmVuY2UgZWxlbWVudCkuXG4gICAgLy8gT25seSBhcHBseSBpZiB0aGUgZXZlbnQgZXhpc3RzLlxuICAgIGlmIChkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50ICYmICFpc01vdXNlQmFzZWRFdmVudChkYXRhUmVmLmN1cnJlbnQub3BlbkV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZWZzLnNldFBvc2l0aW9uUmVmZXJlbmNlKGNyZWF0ZVZpcnR1YWxFbGVtZW50KGRvbVJlZmVyZW5jZSwge1xuICAgICAgeCxcbiAgICAgIHksXG4gICAgICBheGlzLFxuICAgICAgZGF0YVJlZixcbiAgICAgIHBvaW50ZXJUeXBlXG4gICAgfSkpO1xuICB9KTtcbiAgY29uc3QgaGFuZGxlUmVmZXJlbmNlRW50ZXJPck1vdmUgPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgaWYgKHggIT0gbnVsbCB8fCB5ICE9IG51bGwpIHJldHVybjtcbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIHNldFJlZmVyZW5jZShldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKCFjbGVhbnVwTGlzdGVuZXJSZWYuY3VycmVudCkge1xuICAgICAgLy8gSWYgdGhlcmUncyBubyBjbGVhbnVwLCB0aGVyZSdzIG5vIGxpc3RlbmVyLCBidXQgd2Ugd2FudCB0byBlbnN1cmVcbiAgICAgIC8vIHdlIGFkZCB0aGUgbGlzdGVuZXIgaWYgdGhlIGN1cnNvciBsYW5kZWQgb24gdGhlIGZsb2F0aW5nIGVsZW1lbnQgYW5kXG4gICAgICAvLyB0aGVuIGJhY2sgb24gdGhlIHJlZmVyZW5jZSAoaS5lLiBpdCdzIGludGVyYWN0aXZlKS5cbiAgICAgIHNldFJlYWN0aXZlKFtdKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIElmIHRoZSBwb2ludGVyIGlzIGEgbW91c2UtbGlrZSBwb2ludGVyLCB3ZSB3YW50IHRvIGNvbnRpbnVlIGZvbGxvd2luZyB0aGVcbiAgLy8gbW91c2UgZXZlbiBpZiB0aGUgZmxvYXRpbmcgZWxlbWVudCBpcyB0cmFuc2l0aW9uaW5nIG91dC4gT24gdG91Y2hcbiAgLy8gZGV2aWNlcywgdGhpcyBpcyB1bmRlc2lyYWJsZSBiZWNhdXNlIHRoZSBmbG9hdGluZyBlbGVtZW50IHdpbGwgbW92ZSB0b1xuICAvLyB0aGUgZGlzbWlzc2FsIHRvdWNoIHBvaW50LlxuICBjb25zdCBvcGVuQ2hlY2sgPSBpc01vdXNlTGlrZVBvaW50ZXJUeXBlKHBvaW50ZXJUeXBlKSA/IGZsb2F0aW5nIDogb3BlbjtcbiAgY29uc3QgYWRkTGlzdGVuZXIgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgLy8gRXhwbGljaXRseSBzcGVjaWZpZWQgYHhgL2B5YCBjb29yZGluYXRlcyBzaG91bGRuJ3QgYWRkIGEgbGlzdGVuZXIuXG4gICAgaWYgKCFvcGVuQ2hlY2sgfHwgIWVuYWJsZWQgfHwgeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkgcmV0dXJuO1xuICAgIGNvbnN0IHdpbiA9IGdldFdpbmRvdyhmbG9hdGluZyk7XG4gICAgZnVuY3Rpb24gaGFuZGxlTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBnZXRUYXJnZXQoZXZlbnQpO1xuICAgICAgaWYgKCFjb250YWlucyhmbG9hdGluZywgdGFyZ2V0KSkge1xuICAgICAgICBzZXRSZWZlcmVuY2UoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgaGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgY2xlYW51cExpc3RlbmVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWRhdGFSZWYuY3VycmVudC5vcGVuRXZlbnQgfHwgaXNNb3VzZUJhc2VkRXZlbnQoZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCkpIHtcbiAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBoYW5kbGVNb3VzZU1vdmUpO1xuICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgIGNsZWFudXBMaXN0ZW5lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBjbGVhbnVwTGlzdGVuZXJSZWYuY3VycmVudCA9IGNsZWFudXA7XG4gICAgICByZXR1cm4gY2xlYW51cDtcbiAgICB9XG4gICAgcmVmcy5zZXRQb3NpdGlvblJlZmVyZW5jZShkb21SZWZlcmVuY2UpO1xuICB9LCBbb3BlbkNoZWNrLCBlbmFibGVkLCB4LCB5LCBmbG9hdGluZywgZGF0YVJlZiwgcmVmcywgZG9tUmVmZXJlbmNlLCBzZXRSZWZlcmVuY2VdKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gYWRkTGlzdGVuZXIoKTtcbiAgfSwgW2FkZExpc3RlbmVyLCByZWFjdGl2ZV0pO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChlbmFibGVkICYmICFmbG9hdGluZykge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuICB9LCBbZW5hYmxlZCwgZmxvYXRpbmddKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQgJiYgb3Blbikge1xuICAgICAgaW5pdGlhbFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvcGVuXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoZW5hYmxlZCAmJiAoeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkpIHtcbiAgICAgIGluaXRpYWxSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgc2V0UmVmZXJlbmNlKHgsIHkpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIHgsIHksIHNldFJlZmVyZW5jZV0pO1xuICBjb25zdCByZWZlcmVuY2UgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBmdW5jdGlvbiBzZXRQb2ludGVyVHlwZVJlZihfcmVmKSB7XG4gICAgICBsZXQge1xuICAgICAgICBwb2ludGVyVHlwZVxuICAgICAgfSA9IF9yZWY7XG4gICAgICBzZXRQb2ludGVyVHlwZShwb2ludGVyVHlwZSk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvblBvaW50ZXJEb3duOiBzZXRQb2ludGVyVHlwZVJlZixcbiAgICAgIG9uUG9pbnRlckVudGVyOiBzZXRQb2ludGVyVHlwZVJlZixcbiAgICAgIG9uTW91c2VNb3ZlOiBoYW5kbGVSZWZlcmVuY2VFbnRlck9yTW92ZSxcbiAgICAgIG9uTW91c2VFbnRlcjogaGFuZGxlUmVmZXJlbmNlRW50ZXJPck1vdmVcbiAgICB9O1xuICB9LCBbaGFuZGxlUmVmZXJlbmNlRW50ZXJPck1vdmVdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2VcbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlXSk7XG59XG5cbmNvbnN0IGJ1YmJsZUhhbmRsZXJLZXlzID0ge1xuICBwb2ludGVyZG93bjogJ29uUG9pbnRlckRvd24nLFxuICBtb3VzZWRvd246ICdvbk1vdXNlRG93bicsXG4gIGNsaWNrOiAnb25DbGljaydcbn07XG5jb25zdCBjYXB0dXJlSGFuZGxlcktleXMgPSB7XG4gIHBvaW50ZXJkb3duOiAnb25Qb2ludGVyRG93bkNhcHR1cmUnLFxuICBtb3VzZWRvd246ICdvbk1vdXNlRG93bkNhcHR1cmUnLFxuICBjbGljazogJ29uQ2xpY2tDYXB0dXJlJ1xufTtcbmNvbnN0IG5vcm1hbGl6ZVByb3AgPSBub3JtYWxpemFibGUgPT4ge1xuICB2YXIgX25vcm1hbGl6YWJsZSRlc2NhcGVLLCBfbm9ybWFsaXphYmxlJG91dHNpZGU7XG4gIHJldHVybiB7XG4gICAgZXNjYXBlS2V5OiB0eXBlb2Ygbm9ybWFsaXphYmxlID09PSAnYm9vbGVhbicgPyBub3JtYWxpemFibGUgOiAoX25vcm1hbGl6YWJsZSRlc2NhcGVLID0gbm9ybWFsaXphYmxlID09IG51bGwgPyB2b2lkIDAgOiBub3JtYWxpemFibGUuZXNjYXBlS2V5KSAhPSBudWxsID8gX25vcm1hbGl6YWJsZSRlc2NhcGVLIDogZmFsc2UsXG4gICAgb3V0c2lkZVByZXNzOiB0eXBlb2Ygbm9ybWFsaXphYmxlID09PSAnYm9vbGVhbicgPyBub3JtYWxpemFibGUgOiAoX25vcm1hbGl6YWJsZSRvdXRzaWRlID0gbm9ybWFsaXphYmxlID09IG51bGwgPyB2b2lkIDAgOiBub3JtYWxpemFibGUub3V0c2lkZVByZXNzKSAhPSBudWxsID8gX25vcm1hbGl6YWJsZSRvdXRzaWRlIDogdHJ1ZVxuICB9O1xufTtcbi8qKlxuICogQ2xvc2VzIHRoZSBmbG9hdGluZyBlbGVtZW50IHdoZW4gYSBkaXNtaXNzYWwgaXMgcmVxdWVzdGVkIOKAlCBieSBkZWZhdWx0LCB3aGVuXG4gKiB0aGUgdXNlciBwcmVzc2VzIHRoZSBgZXNjYXBlYCBrZXkgb3Igb3V0c2lkZSBvZiB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VEaXNtaXNzXG4gKi9cbmZ1bmN0aW9uIHVzZURpc21pc3MoY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZSxcbiAgICBlbGVtZW50cyxcbiAgICBkYXRhUmVmXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZXNjYXBlS2V5ID0gdHJ1ZSxcbiAgICBvdXRzaWRlUHJlc3M6IHVuc3RhYmxlX291dHNpZGVQcmVzcyA9IHRydWUsXG4gICAgb3V0c2lkZVByZXNzRXZlbnQgPSAncG9pbnRlcmRvd24nLFxuICAgIHJlZmVyZW5jZVByZXNzID0gZmFsc2UsXG4gICAgcmVmZXJlbmNlUHJlc3NFdmVudCA9ICdwb2ludGVyZG93bicsXG4gICAgYW5jZXN0b3JTY3JvbGwgPSBmYWxzZSxcbiAgICBidWJibGVzLFxuICAgIGNhcHR1cmVcbiAgfSA9IHByb3BzO1xuICBjb25zdCB0cmVlID0gdXNlRmxvYXRpbmdUcmVlKCk7XG4gIGNvbnN0IG91dHNpZGVQcmVzc0ZuID0gdXNlRWZmZWN0RXZlbnQodHlwZW9mIHVuc3RhYmxlX291dHNpZGVQcmVzcyA9PT0gJ2Z1bmN0aW9uJyA/IHVuc3RhYmxlX291dHNpZGVQcmVzcyA6ICgpID0+IGZhbHNlKTtcbiAgY29uc3Qgb3V0c2lkZVByZXNzID0gdHlwZW9mIHVuc3RhYmxlX291dHNpZGVQcmVzcyA9PT0gJ2Z1bmN0aW9uJyA/IG91dHNpZGVQcmVzc0ZuIDogdW5zdGFibGVfb3V0c2lkZVByZXNzO1xuICBjb25zdCBpbnNpZGVSZWFjdFRyZWVSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCBlbmRlZE9yU3RhcnRlZEluc2lkZVJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IHtcbiAgICBlc2NhcGVLZXk6IGVzY2FwZUtleUJ1YmJsZXMsXG4gICAgb3V0c2lkZVByZXNzOiBvdXRzaWRlUHJlc3NCdWJibGVzXG4gIH0gPSBub3JtYWxpemVQcm9wKGJ1YmJsZXMpO1xuICBjb25zdCB7XG4gICAgZXNjYXBlS2V5OiBlc2NhcGVLZXlDYXB0dXJlLFxuICAgIG91dHNpZGVQcmVzczogb3V0c2lkZVByZXNzQ2FwdHVyZVxuICB9ID0gbm9ybWFsaXplUHJvcChjYXB0dXJlKTtcbiAgY29uc3QgY2xvc2VPbkVzY2FwZUtleURvd24gPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQgfHwgIWVzY2FwZUtleSB8fCBldmVudC5rZXkgIT09ICdFc2NhcGUnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5vZGVJZCA9IChfZGF0YVJlZiRjdXJyZW50JGZsb2EgPSBkYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RhdGFSZWYkY3VycmVudCRmbG9hLm5vZGVJZDtcbiAgICBjb25zdCBjaGlsZHJlbiA9IHRyZWUgPyBnZXRDaGlsZHJlbih0cmVlLm5vZGVzUmVmLmN1cnJlbnQsIG5vZGVJZCkgOiBbXTtcbiAgICBpZiAoIWVzY2FwZUtleUJ1YmJsZXMpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGV0IHNob3VsZERpc21pc3MgPSB0cnVlO1xuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgICAgICB2YXIgX2NoaWxkJGNvbnRleHQ7XG4gICAgICAgICAgaWYgKChfY2hpbGQkY29udGV4dCA9IGNoaWxkLmNvbnRleHQpICE9IG51bGwgJiYgX2NoaWxkJGNvbnRleHQub3BlbiAmJiAhY2hpbGQuY29udGV4dC5kYXRhUmVmLmN1cnJlbnQuX19lc2NhcGVLZXlCdWJibGVzKSB7XG4gICAgICAgICAgICBzaG91bGREaXNtaXNzID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFzaG91bGREaXNtaXNzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgaXNSZWFjdEV2ZW50KGV2ZW50KSA/IGV2ZW50Lm5hdGl2ZUV2ZW50IDogZXZlbnQsICdlc2NhcGUta2V5Jyk7XG4gIH0pO1xuICBjb25zdCBjbG9zZU9uRXNjYXBlS2V5RG93bkNhcHR1cmUgPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgdmFyIF9nZXRUYXJnZXQyO1xuICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgdmFyIF9nZXRUYXJnZXQ7XG4gICAgICBjbG9zZU9uRXNjYXBlS2V5RG93bihldmVudCk7XG4gICAgICAoX2dldFRhcmdldCA9IGdldFRhcmdldChldmVudCkpID09IG51bGwgfHwgX2dldFRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgY2FsbGJhY2spO1xuICAgIH07XG4gICAgKF9nZXRUYXJnZXQyID0gZ2V0VGFyZ2V0KGV2ZW50KSkgPT0gbnVsbCB8fCBfZ2V0VGFyZ2V0Mi5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgY2FsbGJhY2spO1xuICB9KTtcbiAgY29uc3QgY2xvc2VPblByZXNzT3V0c2lkZSA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICB2YXIgX2RhdGFSZWYkY3VycmVudCRmbG9hMjtcbiAgICAvLyBHaXZlbiBkZXZlbG9wZXJzIGNhbiBzdG9wIHRoZSBwcm9wYWdhdGlvbiBvZiB0aGUgc3ludGhldGljIGV2ZW50LFxuICAgIC8vIHdlIGNhbiBvbmx5IGJlIGNvbmZpZGVudCB3aXRoIGEgcG9zaXRpdmUgdmFsdWUuXG4gICAgY29uc3QgaW5zaWRlUmVhY3RUcmVlID0gaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQ7XG4gICAgaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQgPSBmYWxzZTtcblxuICAgIC8vIFdoZW4gY2xpY2sgb3V0c2lkZSBpcyBsYXp5IChgY2xpY2tgIGV2ZW50KSwgaGFuZGxlIGRyYWdnaW5nLlxuICAgIC8vIERvbid0IGNsb3NlIGlmOlxuICAgIC8vIC0gVGhlIGNsaWNrIHN0YXJ0ZWQgaW5zaWRlIHRoZSBmbG9hdGluZyBlbGVtZW50LlxuICAgIC8vIC0gVGhlIGNsaWNrIGVuZGVkIGluc2lkZSB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAgICBjb25zdCBlbmRlZE9yU3RhcnRlZEluc2lkZSA9IGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQ7XG4gICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIGlmIChvdXRzaWRlUHJlc3NFdmVudCA9PT0gJ2NsaWNrJyAmJiBlbmRlZE9yU3RhcnRlZEluc2lkZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5zaWRlUmVhY3RUcmVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb3V0c2lkZVByZXNzID09PSAnZnVuY3Rpb24nICYmICFvdXRzaWRlUHJlc3MoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGdldFRhcmdldChldmVudCk7XG4gICAgY29uc3QgaW5lcnRTZWxlY3RvciA9IFwiW1wiICsgY3JlYXRlQXR0cmlidXRlKCdpbmVydCcpICsgXCJdXCI7XG4gICAgY29uc3QgbWFya2VycyA9IGdldERvY3VtZW50KGVsZW1lbnRzLmZsb2F0aW5nKS5xdWVyeVNlbGVjdG9yQWxsKGluZXJ0U2VsZWN0b3IpO1xuICAgIGxldCB0YXJnZXRSb290QW5jZXN0b3IgPSBpc0VsZW1lbnQodGFyZ2V0KSA/IHRhcmdldCA6IG51bGw7XG4gICAgd2hpbGUgKHRhcmdldFJvb3RBbmNlc3RvciAmJiAhaXNMYXN0VHJhdmVyc2FibGVOb2RlKHRhcmdldFJvb3RBbmNlc3RvcikpIHtcbiAgICAgIGNvbnN0IG5leHRQYXJlbnQgPSBnZXRQYXJlbnROb2RlKHRhcmdldFJvb3RBbmNlc3Rvcik7XG4gICAgICBpZiAoaXNMYXN0VHJhdmVyc2FibGVOb2RlKG5leHRQYXJlbnQpIHx8ICFpc0VsZW1lbnQobmV4dFBhcmVudCkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB0YXJnZXRSb290QW5jZXN0b3IgPSBuZXh0UGFyZW50O1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRoZSBjbGljayBvY2N1cnJlZCBvbiBhIHRoaXJkLXBhcnR5IGVsZW1lbnQgaW5qZWN0ZWQgYWZ0ZXIgdGhlXG4gICAgLy8gZmxvYXRpbmcgZWxlbWVudCByZW5kZXJlZC5cbiAgICBpZiAobWFya2Vycy5sZW5ndGggJiYgaXNFbGVtZW50KHRhcmdldCkgJiYgIWlzUm9vdEVsZW1lbnQodGFyZ2V0KSAmJlxuICAgIC8vIENsaWNrZWQgb24gYSBkaXJlY3QgYW5jZXN0b3IgKGUuZy4gRmxvYXRpbmdPdmVybGF5KS5cbiAgICAhY29udGFpbnModGFyZ2V0LCBlbGVtZW50cy5mbG9hdGluZykgJiZcbiAgICAvLyBJZiB0aGUgdGFyZ2V0IHJvb3QgZWxlbWVudCBjb250YWlucyBub25lIG9mIHRoZSBtYXJrZXJzLCB0aGVuIHRoZVxuICAgIC8vIGVsZW1lbnQgd2FzIGluamVjdGVkIGFmdGVyIHRoZSBmbG9hdGluZyBlbGVtZW50IHJlbmRlcmVkLlxuICAgIEFycmF5LmZyb20obWFya2VycykuZXZlcnkobWFya2VyID0+ICFjb250YWlucyh0YXJnZXRSb290QW5jZXN0b3IsIG1hcmtlcikpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGNsaWNrIG9jY3VycmVkIG9uIHRoZSBzY3JvbGxiYXJcbiAgICBpZiAoaXNIVE1MRWxlbWVudCh0YXJnZXQpICYmIGZsb2F0aW5nKSB7XG4gICAgICAvLyBJbiBGaXJlZm94LCBgdGFyZ2V0LnNjcm9sbFdpZHRoID4gdGFyZ2V0LmNsaWVudFdpZHRoYCBmb3IgaW5saW5lXG4gICAgICAvLyBlbGVtZW50cy5cbiAgICAgIGNvbnN0IGNhblNjcm9sbFggPSB0YXJnZXQuY2xpZW50V2lkdGggPiAwICYmIHRhcmdldC5zY3JvbGxXaWR0aCA+IHRhcmdldC5jbGllbnRXaWR0aDtcbiAgICAgIGNvbnN0IGNhblNjcm9sbFkgPSB0YXJnZXQuY2xpZW50SGVpZ2h0ID4gMCAmJiB0YXJnZXQuc2Nyb2xsSGVpZ2h0ID4gdGFyZ2V0LmNsaWVudEhlaWdodDtcbiAgICAgIGxldCB4Q29uZCA9IGNhblNjcm9sbFkgJiYgZXZlbnQub2Zmc2V0WCA+IHRhcmdldC5jbGllbnRXaWR0aDtcblxuICAgICAgLy8gSW4gc29tZSBicm93c2VycyBpdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIDxib2R5PiAob3Igd2luZG93KVxuICAgICAgLy8gc2Nyb2xsYmFyIHRvIHRoZSBsZWZ0IHNpZGUsIGJ1dCBpcyB2ZXJ5IHJhcmUgYW5kIGlzIGRpZmZpY3VsdCB0b1xuICAgICAgLy8gY2hlY2sgZm9yLiBQbHVzLCBmb3IgbW9kYWwgZGlhbG9ncyB3aXRoIGJhY2tkcm9wcywgaXQgaXMgbW9yZVxuICAgICAgLy8gaW1wb3J0YW50IHRoYXQgdGhlIGJhY2tkcm9wIGlzIGNoZWNrZWQgYnV0IG5vdCBzbyBtdWNoIHRoZSB3aW5kb3cuXG4gICAgICBpZiAoY2FuU2Nyb2xsWSkge1xuICAgICAgICBjb25zdCBpc1JUTCA9IGdldENvbXB1dGVkU3R5bGUodGFyZ2V0KS5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgICAgICBpZiAoaXNSVEwpIHtcbiAgICAgICAgICB4Q29uZCA9IGV2ZW50Lm9mZnNldFggPD0gdGFyZ2V0Lm9mZnNldFdpZHRoIC0gdGFyZ2V0LmNsaWVudFdpZHRoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoeENvbmQgfHwgY2FuU2Nyb2xsWCAmJiBldmVudC5vZmZzZXRZID4gdGFyZ2V0LmNsaWVudEhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG5vZGVJZCA9IChfZGF0YVJlZiRjdXJyZW50JGZsb2EyID0gZGF0YVJlZi5jdXJyZW50LmZsb2F0aW5nQ29udGV4dCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9kYXRhUmVmJGN1cnJlbnQkZmxvYTIubm9kZUlkO1xuICAgIGNvbnN0IHRhcmdldElzSW5zaWRlQ2hpbGRyZW4gPSB0cmVlICYmIGdldENoaWxkcmVuKHRyZWUubm9kZXNSZWYuY3VycmVudCwgbm9kZUlkKS5zb21lKG5vZGUgPT4ge1xuICAgICAgdmFyIF9ub2RlJGNvbnRleHQ7XG4gICAgICByZXR1cm4gaXNFdmVudFRhcmdldFdpdGhpbihldmVudCwgKF9ub2RlJGNvbnRleHQgPSBub2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRjb250ZXh0LmVsZW1lbnRzLmZsb2F0aW5nKTtcbiAgICB9KTtcbiAgICBpZiAoaXNFdmVudFRhcmdldFdpdGhpbihldmVudCwgZWxlbWVudHMuZmxvYXRpbmcpIHx8IGlzRXZlbnRUYXJnZXRXaXRoaW4oZXZlbnQsIGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgfHwgdGFyZ2V0SXNJbnNpZGVDaGlsZHJlbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjaGlsZHJlbiA9IHRyZWUgPyBnZXRDaGlsZHJlbih0cmVlLm5vZGVzUmVmLmN1cnJlbnQsIG5vZGVJZCkgOiBbXTtcbiAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgbGV0IHNob3VsZERpc21pc3MgPSB0cnVlO1xuICAgICAgY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgIHZhciBfY2hpbGQkY29udGV4dDI7XG4gICAgICAgIGlmICgoX2NoaWxkJGNvbnRleHQyID0gY2hpbGQuY29udGV4dCkgIT0gbnVsbCAmJiBfY2hpbGQkY29udGV4dDIub3BlbiAmJiAhY2hpbGQuY29udGV4dC5kYXRhUmVmLmN1cnJlbnQuX19vdXRzaWRlUHJlc3NCdWJibGVzKSB7XG4gICAgICAgICAgc2hvdWxkRGlzbWlzcyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoIXNob3VsZERpc21pc3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBvbk9wZW5DaGFuZ2UoZmFsc2UsIGV2ZW50LCAnb3V0c2lkZS1wcmVzcycpO1xuICB9KTtcbiAgY29uc3QgY2xvc2VPblByZXNzT3V0c2lkZUNhcHR1cmUgPSB1c2VFZmZlY3RFdmVudChldmVudCA9PiB7XG4gICAgdmFyIF9nZXRUYXJnZXQ0O1xuICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgdmFyIF9nZXRUYXJnZXQzO1xuICAgICAgY2xvc2VPblByZXNzT3V0c2lkZShldmVudCk7XG4gICAgICAoX2dldFRhcmdldDMgPSBnZXRUYXJnZXQoZXZlbnQpKSA9PSBudWxsIHx8IF9nZXRUYXJnZXQzLnJlbW92ZUV2ZW50TGlzdGVuZXIob3V0c2lkZVByZXNzRXZlbnQsIGNhbGxiYWNrKTtcbiAgICB9O1xuICAgIChfZ2V0VGFyZ2V0NCA9IGdldFRhcmdldChldmVudCkpID09IG51bGwgfHwgX2dldFRhcmdldDQuYWRkRXZlbnRMaXN0ZW5lcihvdXRzaWRlUHJlc3NFdmVudCwgY2FsbGJhY2spO1xuICB9KTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4gfHwgIWVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fZXNjYXBlS2V5QnViYmxlcyA9IGVzY2FwZUtleUJ1YmJsZXM7XG4gICAgZGF0YVJlZi5jdXJyZW50Ll9fb3V0c2lkZVByZXNzQnViYmxlcyA9IG91dHNpZGVQcmVzc0J1YmJsZXM7XG4gICAgZnVuY3Rpb24gb25TY3JvbGwoZXZlbnQpIHtcbiAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQsICdhbmNlc3Rvci1zY3JvbGwnKTtcbiAgICB9XG4gICAgY29uc3QgZG9jID0gZ2V0RG9jdW1lbnQoZWxlbWVudHMuZmxvYXRpbmcpO1xuICAgIGVzY2FwZUtleSAmJiBkb2MuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGVzY2FwZUtleUNhcHR1cmUgPyBjbG9zZU9uRXNjYXBlS2V5RG93bkNhcHR1cmUgOiBjbG9zZU9uRXNjYXBlS2V5RG93biwgZXNjYXBlS2V5Q2FwdHVyZSk7XG4gICAgb3V0c2lkZVByZXNzICYmIGRvYy5hZGRFdmVudExpc3RlbmVyKG91dHNpZGVQcmVzc0V2ZW50LCBvdXRzaWRlUHJlc3NDYXB0dXJlID8gY2xvc2VPblByZXNzT3V0c2lkZUNhcHR1cmUgOiBjbG9zZU9uUHJlc3NPdXRzaWRlLCBvdXRzaWRlUHJlc3NDYXB0dXJlKTtcbiAgICBsZXQgYW5jZXN0b3JzID0gW107XG4gICAgaWYgKGFuY2VzdG9yU2Nyb2xsKSB7XG4gICAgICBpZiAoaXNFbGVtZW50KGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkpIHtcbiAgICAgICAgYW5jZXN0b3JzID0gZ2V0T3ZlcmZsb3dBbmNlc3RvcnMoZWxlbWVudHMuZG9tUmVmZXJlbmNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0VsZW1lbnQoZWxlbWVudHMuZmxvYXRpbmcpKSB7XG4gICAgICAgIGFuY2VzdG9ycyA9IGFuY2VzdG9ycy5jb25jYXQoZ2V0T3ZlcmZsb3dBbmNlc3RvcnMoZWxlbWVudHMuZmxvYXRpbmcpKTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNFbGVtZW50KGVsZW1lbnRzLnJlZmVyZW5jZSkgJiYgZWxlbWVudHMucmVmZXJlbmNlICYmIGVsZW1lbnRzLnJlZmVyZW5jZS5jb250ZXh0RWxlbWVudCkge1xuICAgICAgICBhbmNlc3RvcnMgPSBhbmNlc3RvcnMuY29uY2F0KGdldE92ZXJmbG93QW5jZXN0b3JzKGVsZW1lbnRzLnJlZmVyZW5jZS5jb250ZXh0RWxlbWVudCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElnbm9yZSB0aGUgdmlzdWFsIHZpZXdwb3J0IGZvciBzY3JvbGxpbmcgZGlzbWlzc2FsIChhbGxvdyBwaW5jaC16b29tKVxuICAgIGFuY2VzdG9ycyA9IGFuY2VzdG9ycy5maWx0ZXIoYW5jZXN0b3IgPT4ge1xuICAgICAgdmFyIF9kb2MkZGVmYXVsdFZpZXc7XG4gICAgICByZXR1cm4gYW5jZXN0b3IgIT09ICgoX2RvYyRkZWZhdWx0VmlldyA9IGRvYy5kZWZhdWx0VmlldykgPT0gbnVsbCA/IHZvaWQgMCA6IF9kb2MkZGVmYXVsdFZpZXcudmlzdWFsVmlld3BvcnQpO1xuICAgIH0pO1xuICAgIGFuY2VzdG9ycy5mb3JFYWNoKGFuY2VzdG9yID0+IHtcbiAgICAgIGFuY2VzdG9yLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG9uU2Nyb2xsLCB7XG4gICAgICAgIHBhc3NpdmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBlc2NhcGVLZXkgJiYgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBlc2NhcGVLZXlDYXB0dXJlID8gY2xvc2VPbkVzY2FwZUtleURvd25DYXB0dXJlIDogY2xvc2VPbkVzY2FwZUtleURvd24sIGVzY2FwZUtleUNhcHR1cmUpO1xuICAgICAgb3V0c2lkZVByZXNzICYmIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKG91dHNpZGVQcmVzc0V2ZW50LCBvdXRzaWRlUHJlc3NDYXB0dXJlID8gY2xvc2VPblByZXNzT3V0c2lkZUNhcHR1cmUgOiBjbG9zZU9uUHJlc3NPdXRzaWRlLCBvdXRzaWRlUHJlc3NDYXB0dXJlKTtcbiAgICAgIGFuY2VzdG9ycy5mb3JFYWNoKGFuY2VzdG9yID0+IHtcbiAgICAgICAgYW5jZXN0b3IucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSwgW2RhdGFSZWYsIGVsZW1lbnRzLCBlc2NhcGVLZXksIG91dHNpZGVQcmVzcywgb3V0c2lkZVByZXNzRXZlbnQsIG9wZW4sIG9uT3BlbkNoYW5nZSwgYW5jZXN0b3JTY3JvbGwsIGVuYWJsZWQsIGVzY2FwZUtleUJ1YmJsZXMsIG91dHNpZGVQcmVzc0J1YmJsZXMsIGNsb3NlT25Fc2NhcGVLZXlEb3duLCBlc2NhcGVLZXlDYXB0dXJlLCBjbG9zZU9uRXNjYXBlS2V5RG93bkNhcHR1cmUsIGNsb3NlT25QcmVzc091dHNpZGUsIG91dHNpZGVQcmVzc0NhcHR1cmUsIGNsb3NlT25QcmVzc091dHNpZGVDYXB0dXJlXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaW5zaWRlUmVhY3RUcmVlUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgfSwgW291dHNpZGVQcmVzcywgb3V0c2lkZVByZXNzRXZlbnRdKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uS2V5RG93bjogY2xvc2VPbkVzY2FwZUtleURvd24sXG4gICAgW2J1YmJsZUhhbmRsZXJLZXlzW3JlZmVyZW5jZVByZXNzRXZlbnRdXTogZXZlbnQgPT4ge1xuICAgICAgaWYgKHJlZmVyZW5jZVByZXNzKSB7XG4gICAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdyZWZlcmVuY2UtcHJlc3MnKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG9uT3BlbkNoYW5nZSwgcmVmZXJlbmNlUHJlc3MsIHJlZmVyZW5jZVByZXNzRXZlbnRdKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgb25LZXlEb3duOiBjbG9zZU9uRXNjYXBlS2V5RG93bixcbiAgICBvbk1vdXNlRG93bigpIHtcbiAgICAgIGVuZGVkT3JTdGFydGVkSW5zaWRlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH0sXG4gICAgb25Nb3VzZVVwKCkge1xuICAgICAgZW5kZWRPclN0YXJ0ZWRJbnNpZGVSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBbY2FwdHVyZUhhbmRsZXJLZXlzW291dHNpZGVQcmVzc0V2ZW50XV06ICgpID0+IHtcbiAgICAgIGluc2lkZVJlYWN0VHJlZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0pLCBbY2xvc2VPbkVzY2FwZUtleURvd24sIG91dHNpZGVQcmVzc0V2ZW50XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZSwgZmxvYXRpbmddKTtcbn1cblxuZnVuY3Rpb24gdXNlRmxvYXRpbmdSb290Q29udGV4dChvcHRpb25zKSB7XG4gIGNvbnN0IHtcbiAgICBvcGVuID0gZmFsc2UsXG4gICAgb25PcGVuQ2hhbmdlOiBvbk9wZW5DaGFuZ2VQcm9wLFxuICAgIGVsZW1lbnRzOiBlbGVtZW50c1Byb3BcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZsb2F0aW5nSWQgPSB1c2VJZCgpO1xuICBjb25zdCBkYXRhUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgY29uc3QgW2V2ZW50c10gPSBSZWFjdC51c2VTdGF0ZSgoKSA9PiBjcmVhdGVQdWJTdWIoKSk7XG4gIGNvbnN0IG5lc3RlZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCkgIT0gbnVsbDtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgIGNvbnN0IG9wdGlvbkRvbVJlZmVyZW5jZSA9IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2U7XG4gICAgaWYgKG9wdGlvbkRvbVJlZmVyZW5jZSAmJiAhaXNFbGVtZW50KG9wdGlvbkRvbVJlZmVyZW5jZSkpIHtcbiAgICAgIGVycm9yKCdDYW5ub3QgcGFzcyBhIHZpcnR1YWwgZWxlbWVudCB0byB0aGUgYGVsZW1lbnRzLnJlZmVyZW5jZWAgb3B0aW9uLCcsICdhcyBpdCBtdXN0IGJlIGEgcmVhbCBET00gZWxlbWVudC4gVXNlIGByZWZzLnNldFBvc2l0aW9uUmVmZXJlbmNlKClgJywgJ2luc3RlYWQuJyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IFtwb3NpdGlvblJlZmVyZW5jZSwgc2V0UG9zaXRpb25SZWZlcmVuY2VdID0gUmVhY3QudXNlU3RhdGUoZWxlbWVudHNQcm9wLnJlZmVyZW5jZSk7XG4gIGNvbnN0IG9uT3BlbkNoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KChvcGVuLCBldmVudCwgcmVhc29uKSA9PiB7XG4gICAgZGF0YVJlZi5jdXJyZW50Lm9wZW5FdmVudCA9IG9wZW4gPyBldmVudCA6IHVuZGVmaW5lZDtcbiAgICBldmVudHMuZW1pdCgnb3BlbmNoYW5nZScsIHtcbiAgICAgIG9wZW4sXG4gICAgICBldmVudCxcbiAgICAgIHJlYXNvbixcbiAgICAgIG5lc3RlZFxuICAgIH0pO1xuICAgIG9uT3BlbkNoYW5nZVByb3AgPT0gbnVsbCB8fCBvbk9wZW5DaGFuZ2VQcm9wKG9wZW4sIGV2ZW50LCByZWFzb24pO1xuICB9KTtcbiAgY29uc3QgcmVmcyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBzZXRQb3NpdGlvblJlZmVyZW5jZVxuICB9KSwgW10pO1xuICBjb25zdCBlbGVtZW50cyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICByZWZlcmVuY2U6IHBvc2l0aW9uUmVmZXJlbmNlIHx8IGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UgfHwgbnVsbCxcbiAgICBmbG9hdGluZzogZWxlbWVudHNQcm9wLmZsb2F0aW5nIHx8IG51bGwsXG4gICAgZG9tUmVmZXJlbmNlOiBlbGVtZW50c1Byb3AucmVmZXJlbmNlXG4gIH0pLCBbcG9zaXRpb25SZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5yZWZlcmVuY2UsIGVsZW1lbnRzUHJvcC5mbG9hdGluZ10pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIGRhdGFSZWYsXG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZWxlbWVudHMsXG4gICAgZXZlbnRzLFxuICAgIGZsb2F0aW5nSWQsXG4gICAgcmVmc1xuICB9KSwgW29wZW4sIG9uT3BlbkNoYW5nZSwgZWxlbWVudHMsIGV2ZW50cywgZmxvYXRpbmdJZCwgcmVmc10pO1xufVxuXG4vKipcbiAqIFByb3ZpZGVzIGRhdGEgdG8gcG9zaXRpb24gYSBmbG9hdGluZyBlbGVtZW50IGFuZCBjb250ZXh0IHRvIGFkZCBpbnRlcmFjdGlvbnMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlRmxvYXRpbmdcbiAqL1xuZnVuY3Rpb24gdXNlRmxvYXRpbmcob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBub2RlSWRcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGludGVybmFsUm9vdENvbnRleHQgPSB1c2VGbG9hdGluZ1Jvb3RDb250ZXh0KHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICByZWZlcmVuY2U6IG51bGwsXG4gICAgICBmbG9hdGluZzogbnVsbCxcbiAgICAgIC4uLm9wdGlvbnMuZWxlbWVudHNcbiAgICB9XG4gIH0pO1xuICBjb25zdCByb290Q29udGV4dCA9IG9wdGlvbnMucm9vdENvbnRleHQgfHwgaW50ZXJuYWxSb290Q29udGV4dDtcbiAgY29uc3QgY29tcHV0ZWRFbGVtZW50cyA9IHJvb3RDb250ZXh0LmVsZW1lbnRzO1xuICBjb25zdCBbX2RvbVJlZmVyZW5jZSwgc2V0RG9tUmVmZXJlbmNlXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpO1xuICBjb25zdCBbcG9zaXRpb25SZWZlcmVuY2UsIF9zZXRQb3NpdGlvblJlZmVyZW5jZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKTtcbiAgY29uc3Qgb3B0aW9uRG9tUmVmZXJlbmNlID0gY29tcHV0ZWRFbGVtZW50cyA9PSBudWxsID8gdm9pZCAwIDogY29tcHV0ZWRFbGVtZW50cy5yZWZlcmVuY2U7XG4gIGNvbnN0IGRvbVJlZmVyZW5jZSA9IG9wdGlvbkRvbVJlZmVyZW5jZSB8fCBfZG9tUmVmZXJlbmNlO1xuICBjb25zdCBkb21SZWZlcmVuY2VSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmIChkb21SZWZlcmVuY2UpIHtcbiAgICAgIGRvbVJlZmVyZW5jZVJlZi5jdXJyZW50ID0gZG9tUmVmZXJlbmNlO1xuICAgIH1cbiAgfSwgW2RvbVJlZmVyZW5jZV0pO1xuICBjb25zdCBwb3NpdGlvbiA9IHVzZUZsb2F0aW5nJDEoe1xuICAgIC4uLm9wdGlvbnMsXG4gICAgZWxlbWVudHM6IHtcbiAgICAgIC4uLmNvbXB1dGVkRWxlbWVudHMsXG4gICAgICAuLi4ocG9zaXRpb25SZWZlcmVuY2UgJiYge1xuICAgICAgICByZWZlcmVuY2U6IHBvc2l0aW9uUmVmZXJlbmNlXG4gICAgICB9KVxuICAgIH1cbiAgfSk7XG4gIGNvbnN0IHNldFBvc2l0aW9uUmVmZXJlbmNlID0gUmVhY3QudXNlQ2FsbGJhY2sobm9kZSA9PiB7XG4gICAgY29uc3QgY29tcHV0ZWRQb3NpdGlvblJlZmVyZW5jZSA9IGlzRWxlbWVudChub2RlKSA/IHtcbiAgICAgIGdldEJvdW5kaW5nQ2xpZW50UmVjdDogKCkgPT4gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgIGNvbnRleHRFbGVtZW50OiBub2RlXG4gICAgfSA6IG5vZGU7XG4gICAgLy8gU3RvcmUgdGhlIHBvc2l0aW9uUmVmZXJlbmNlIGluIHN0YXRlIGlmIHRoZSBET00gcmVmZXJlbmNlIGlzIHNwZWNpZmllZCBleHRlcm5hbGx5IHZpYSB0aGVcbiAgICAvLyBgZWxlbWVudHMucmVmZXJlbmNlYCBvcHRpb24uIFRoaXMgZW5zdXJlcyB0aGF0IGl0IHdvbid0IGJlIG92ZXJyaWRkZW4gb24gZnV0dXJlIHJlbmRlcnMuXG4gICAgX3NldFBvc2l0aW9uUmVmZXJlbmNlKGNvbXB1dGVkUG9zaXRpb25SZWZlcmVuY2UpO1xuICAgIHBvc2l0aW9uLnJlZnMuc2V0UmVmZXJlbmNlKGNvbXB1dGVkUG9zaXRpb25SZWZlcmVuY2UpO1xuICB9LCBbcG9zaXRpb24ucmVmc10pO1xuICBjb25zdCBzZXRSZWZlcmVuY2UgPSBSZWFjdC51c2VDYWxsYmFjayhub2RlID0+IHtcbiAgICBpZiAoaXNFbGVtZW50KG5vZGUpIHx8IG5vZGUgPT09IG51bGwpIHtcbiAgICAgIGRvbVJlZmVyZW5jZVJlZi5jdXJyZW50ID0gbm9kZTtcbiAgICAgIHNldERvbVJlZmVyZW5jZShub2RlKTtcbiAgICB9XG5cbiAgICAvLyBCYWNrd2FyZHMtY29tcGF0aWJpbGl0eSBmb3IgcGFzc2luZyBhIHZpcnR1YWwgZWxlbWVudCB0byBgcmVmZXJlbmNlYFxuICAgIC8vIGFmdGVyIGl0IGhhcyBzZXQgdGhlIERPTSByZWZlcmVuY2UuXG4gICAgaWYgKGlzRWxlbWVudChwb3NpdGlvbi5yZWZzLnJlZmVyZW5jZS5jdXJyZW50KSB8fCBwb3NpdGlvbi5yZWZzLnJlZmVyZW5jZS5jdXJyZW50ID09PSBudWxsIHx8XG4gICAgLy8gRG9uJ3QgYWxsb3cgc2V0dGluZyB2aXJ0dWFsIGVsZW1lbnRzIHVzaW5nIHRoZSBvbGQgdGVjaG5pcXVlIGJhY2sgdG9cbiAgICAvLyBgbnVsbGAgdG8gc3VwcG9ydCBgcG9zaXRpb25SZWZlcmVuY2VgICsgYW4gdW5zdGFibGUgYHJlZmVyZW5jZWBcbiAgICAvLyBjYWxsYmFjayByZWYuXG4gICAgbm9kZSAhPT0gbnVsbCAmJiAhaXNFbGVtZW50KG5vZGUpKSB7XG4gICAgICBwb3NpdGlvbi5yZWZzLnNldFJlZmVyZW5jZShub2RlKTtcbiAgICB9XG4gIH0sIFtwb3NpdGlvbi5yZWZzXSk7XG4gIGNvbnN0IHJlZnMgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24ucmVmcyxcbiAgICBzZXRSZWZlcmVuY2UsXG4gICAgc2V0UG9zaXRpb25SZWZlcmVuY2UsXG4gICAgZG9tUmVmZXJlbmNlOiBkb21SZWZlcmVuY2VSZWZcbiAgfSksIFtwb3NpdGlvbi5yZWZzLCBzZXRSZWZlcmVuY2UsIHNldFBvc2l0aW9uUmVmZXJlbmNlXSk7XG4gIGNvbnN0IGVsZW1lbnRzID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIC4uLnBvc2l0aW9uLmVsZW1lbnRzLFxuICAgIGRvbVJlZmVyZW5jZTogZG9tUmVmZXJlbmNlXG4gIH0pLCBbcG9zaXRpb24uZWxlbWVudHMsIGRvbVJlZmVyZW5jZV0pO1xuICBjb25zdCBjb250ZXh0ID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIC4uLnBvc2l0aW9uLFxuICAgIC4uLnJvb3RDb250ZXh0LFxuICAgIHJlZnMsXG4gICAgZWxlbWVudHMsXG4gICAgbm9kZUlkXG4gIH0pLCBbcG9zaXRpb24sIHJlZnMsIGVsZW1lbnRzLCBub2RlSWQsIHJvb3RDb250ZXh0XSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICByb290Q29udGV4dC5kYXRhUmVmLmN1cnJlbnQuZmxvYXRpbmdDb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCBub2RlID0gdHJlZSA9PSBudWxsID8gdm9pZCAwIDogdHJlZS5ub2Rlc1JlZi5jdXJyZW50LmZpbmQobm9kZSA9PiBub2RlLmlkID09PSBub2RlSWQpO1xuICAgIGlmIChub2RlKSB7XG4gICAgICBub2RlLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgLi4ucG9zaXRpb24sXG4gICAgY29udGV4dCxcbiAgICByZWZzLFxuICAgIGVsZW1lbnRzXG4gIH0pLCBbcG9zaXRpb24sIHJlZnMsIGVsZW1lbnRzLCBjb250ZXh0XSk7XG59XG5cbi8qKlxuICogT3BlbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgd2hpbGUgdGhlIHJlZmVyZW5jZSBlbGVtZW50IGhhcyBmb2N1cywgbGlrZSBDU1NcbiAqIGA6Zm9jdXNgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZUZvY3VzXG4gKi9cbmZ1bmN0aW9uIHVzZUZvY3VzKGNvbnRleHQsIHByb3BzKSB7XG4gIGlmIChwcm9wcyA9PT0gdm9pZCAwKSB7XG4gICAgcHJvcHMgPSB7fTtcbiAgfVxuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBvbk9wZW5DaGFuZ2UsXG4gICAgZXZlbnRzLFxuICAgIGRhdGFSZWYsXG4gICAgZWxlbWVudHNcbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBlbmFibGVkID0gdHJ1ZSxcbiAgICB2aXNpYmxlT25seSA9IHRydWVcbiAgfSA9IHByb3BzO1xuICBjb25zdCBibG9ja0ZvY3VzUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgdGltZW91dFJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBjb25zdCBrZXlib2FyZE1vZGFsaXR5UmVmID0gUmVhY3QudXNlUmVmKHRydWUpO1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGNvbnN0IHdpbiA9IGdldFdpbmRvdyhlbGVtZW50cy5kb21SZWZlcmVuY2UpO1xuXG4gICAgLy8gSWYgdGhlIHJlZmVyZW5jZSB3YXMgZm9jdXNlZCBhbmQgdGhlIHVzZXIgbGVmdCB0aGUgdGFiL3dpbmRvdywgYW5kIHRoZVxuICAgIC8vIGZsb2F0aW5nIGVsZW1lbnQgd2FzIG5vdCBvcGVuLCB0aGUgZm9jdXMgc2hvdWxkIGJlIGJsb2NrZWQgd2hlbiB0aGV5XG4gICAgLy8gcmV0dXJuIHRvIHRoZSB0YWIvd2luZG93LlxuICAgIGZ1bmN0aW9uIG9uQmx1cigpIHtcbiAgICAgIGlmICghb3BlbiAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgJiYgZWxlbWVudHMuZG9tUmVmZXJlbmNlID09PSBhY3RpdmVFbGVtZW50KGdldERvY3VtZW50KGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkpKSB7XG4gICAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uS2V5RG93bigpIHtcbiAgICAgIGtleWJvYXJkTW9kYWxpdHlSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfVxuICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgb25CbHVyKTtcbiAgICB3aW4uYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93biwgdHJ1ZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgb25CbHVyKTtcbiAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duLCB0cnVlKTtcbiAgICB9O1xuICB9LCBbZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBvcGVuLCBlbmFibGVkXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgZnVuY3Rpb24gb25PcGVuQ2hhbmdlKF9yZWYpIHtcbiAgICAgIGxldCB7XG4gICAgICAgIHJlYXNvblxuICAgICAgfSA9IF9yZWY7XG4gICAgICBpZiAocmVhc29uID09PSAncmVmZXJlbmNlLXByZXNzJyB8fCByZWFzb24gPT09ICdlc2NhcGUta2V5Jykge1xuICAgICAgICBibG9ja0ZvY3VzUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBldmVudHMub24oJ29wZW5jaGFuZ2UnLCBvbk9wZW5DaGFuZ2UpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBldmVudHMub2ZmKCdvcGVuY2hhbmdlJywgb25PcGVuQ2hhbmdlKTtcbiAgICB9O1xuICB9LCBbZXZlbnRzLCBlbmFibGVkXSk7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0UmVmLmN1cnJlbnQpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uUG9pbnRlckRvd24oZXZlbnQpIHtcbiAgICAgIGlmIChpc1ZpcnR1YWxQb2ludGVyRXZlbnQoZXZlbnQubmF0aXZlRXZlbnQpKSByZXR1cm47XG4gICAgICBrZXlib2FyZE1vZGFsaXR5UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICB9LFxuICAgIG9uTW91c2VMZWF2ZSgpIHtcbiAgICAgIGJsb2NrRm9jdXNSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIH0sXG4gICAgb25Gb2N1cyhldmVudCkge1xuICAgICAgaWYgKGJsb2NrRm9jdXNSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0KGV2ZW50Lm5hdGl2ZUV2ZW50KTtcbiAgICAgIGlmICh2aXNpYmxlT25seSAmJiBpc0VsZW1lbnQodGFyZ2V0KSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIE1hYyBTYWZhcmkgdW5yZWxpYWJseSBtYXRjaGVzIGA6Zm9jdXMtdmlzaWJsZWAgb24gdGhlIHJlZmVyZW5jZVxuICAgICAgICAgIC8vIGlmIGZvY3VzIHdhcyBvdXRzaWRlIHRoZSBwYWdlIGluaXRpYWxseSAtIHVzZSB0aGUgZmFsbGJhY2tcbiAgICAgICAgICAvLyBpbnN0ZWFkLlxuICAgICAgICAgIGlmIChpc1NhZmFyaSgpICYmIGlzTWFjKCkpIHRocm93IEVycm9yKCk7XG4gICAgICAgICAgaWYgKCF0YXJnZXQubWF0Y2hlcygnOmZvY3VzLXZpc2libGUnKSkgcmV0dXJuO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gT2xkIGJyb3dzZXJzIHdpbGwgdGhyb3cgYW4gZXJyb3Igd2hlbiB1c2luZyBgOmZvY3VzLXZpc2libGVgLlxuICAgICAgICAgIGlmICgha2V5Ym9hcmRNb2RhbGl0eVJlZi5jdXJyZW50ICYmICFpc1R5cGVhYmxlRWxlbWVudCh0YXJnZXQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdmb2N1cycpO1xuICAgIH0sXG4gICAgb25CbHVyKGV2ZW50KSB7XG4gICAgICBibG9ja0ZvY3VzUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIGNvbnN0IHJlbGF0ZWRUYXJnZXQgPSBldmVudC5yZWxhdGVkVGFyZ2V0O1xuICAgICAgY29uc3QgbmF0aXZlRXZlbnQgPSBldmVudC5uYXRpdmVFdmVudDtcblxuICAgICAgLy8gSGl0IHRoZSBub24tbW9kYWwgZm9jdXMgbWFuYWdlbWVudCBwb3J0YWwgZ3VhcmQuIEZvY3VzIHdpbGwgYmVcbiAgICAgIC8vIG1vdmVkIGludG8gdGhlIGZsb2F0aW5nIGVsZW1lbnQgaW1tZWRpYXRlbHkgYWZ0ZXIuXG4gICAgICBjb25zdCBtb3ZlZFRvRm9jdXNHdWFyZCA9IGlzRWxlbWVudChyZWxhdGVkVGFyZ2V0KSAmJiByZWxhdGVkVGFyZ2V0Lmhhc0F0dHJpYnV0ZShjcmVhdGVBdHRyaWJ1dGUoJ2ZvY3VzLWd1YXJkJykpICYmIHJlbGF0ZWRUYXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ291dHNpZGUnO1xuXG4gICAgICAvLyBXYWl0IGZvciB0aGUgd2luZG93IGJsdXIgbGlzdGVuZXIgdG8gZmlyZS5cbiAgICAgIHRpbWVvdXRSZWYuY3VycmVudCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdmFyIF9kYXRhUmVmJGN1cnJlbnQkZmxvYTtcbiAgICAgICAgY29uc3QgYWN0aXZlRWwgPSBhY3RpdmVFbGVtZW50KGVsZW1lbnRzLmRvbVJlZmVyZW5jZSA/IGVsZW1lbnRzLmRvbVJlZmVyZW5jZS5vd25lckRvY3VtZW50IDogZG9jdW1lbnQpO1xuXG4gICAgICAgIC8vIEZvY3VzIGxlZnQgdGhlIHBhZ2UsIGtlZXAgaXQgb3Blbi5cbiAgICAgICAgaWYgKCFyZWxhdGVkVGFyZ2V0ICYmIGFjdGl2ZUVsID09PSBlbGVtZW50cy5kb21SZWZlcmVuY2UpIHJldHVybjtcblxuICAgICAgICAvLyBXaGVuIGZvY3VzaW5nIHRoZSByZWZlcmVuY2UgZWxlbWVudCAoZS5nLiByZWd1bGFyIGNsaWNrKSwgdGhlblxuICAgICAgICAvLyBjbGlja2luZyBpbnRvIHRoZSBmbG9hdGluZyBlbGVtZW50LCBwcmV2ZW50IGl0IGZyb20gaGlkaW5nLlxuICAgICAgICAvLyBOb3RlOiBpdCBtdXN0IGJlIGZvY3VzYWJsZSwgZS5nLiBgdGFiaW5kZXg9XCItMVwiYC5cbiAgICAgICAgLy8gV2UgY2FuIG5vdCByZWx5IG9uIHJlbGF0ZWRUYXJnZXQgdG8gcG9pbnQgdG8gdGhlIGNvcnJlY3QgZWxlbWVudFxuICAgICAgICAvLyBhcyBpdCB3aWxsIG9ubHkgcG9pbnQgdG8gdGhlIHNoYWRvdyBob3N0IG9mIHRoZSBuZXdseSBmb2N1c2VkIGVsZW1lbnRcbiAgICAgICAgLy8gYW5kIG5vdCB0aGUgZWxlbWVudCB0aGF0IGFjdHVhbGx5IGhhcyByZWNlaXZlZCBmb2N1cyBpZiBpdCBpcyBsb2NhdGVkXG4gICAgICAgIC8vIGluc2lkZSBhIHNoYWRvdyByb290LlxuICAgICAgICBpZiAoY29udGFpbnMoKF9kYXRhUmVmJGN1cnJlbnQkZmxvYSA9IGRhdGFSZWYuY3VycmVudC5mbG9hdGluZ0NvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGF0YVJlZiRjdXJyZW50JGZsb2EucmVmcy5mbG9hdGluZy5jdXJyZW50LCBhY3RpdmVFbCkgfHwgY29udGFpbnMoZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBhY3RpdmVFbCkgfHwgbW92ZWRUb0ZvY3VzR3VhcmQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25PcGVuQ2hhbmdlKGZhbHNlLCBuYXRpdmVFdmVudCwgJ2ZvY3VzJyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pLCBbZGF0YVJlZiwgZWxlbWVudHMuZG9tUmVmZXJlbmNlLCBvbk9wZW5DaGFuZ2UsIHZpc2libGVPbmx5XSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlXG4gIH0gOiB7fSwgW2VuYWJsZWQsIHJlZmVyZW5jZV0pO1xufVxuXG5jb25zdCBBQ1RJVkVfS0VZID0gJ2FjdGl2ZSc7XG5jb25zdCBTRUxFQ1RFRF9LRVkgPSAnc2VsZWN0ZWQnO1xuZnVuY3Rpb24gbWVyZ2VQcm9wcyh1c2VyUHJvcHMsIHByb3BzTGlzdCwgZWxlbWVudEtleSkge1xuICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gIGNvbnN0IGlzSXRlbSA9IGVsZW1lbnRLZXkgPT09ICdpdGVtJztcbiAgbGV0IGRvbVVzZXJQcm9wcyA9IHVzZXJQcm9wcztcbiAgaWYgKGlzSXRlbSAmJiB1c2VyUHJvcHMpIHtcbiAgICBjb25zdCB7XG4gICAgICBbQUNUSVZFX0tFWV06IF8sXG4gICAgICBbU0VMRUNURURfS0VZXTogX18sXG4gICAgICAuLi52YWxpZFByb3BzXG4gICAgfSA9IHVzZXJQcm9wcztcbiAgICBkb21Vc2VyUHJvcHMgPSB2YWxpZFByb3BzO1xuICB9XG4gIHJldHVybiB7XG4gICAgLi4uKGVsZW1lbnRLZXkgPT09ICdmbG9hdGluZycgJiYge1xuICAgICAgdGFiSW5kZXg6IC0xLFxuICAgICAgW0ZPQ1VTQUJMRV9BVFRSSUJVVEVdOiAnJ1xuICAgIH0pLFxuICAgIC4uLmRvbVVzZXJQcm9wcyxcbiAgICAuLi5wcm9wc0xpc3QubWFwKHZhbHVlID0+IHtcbiAgICAgIGNvbnN0IHByb3BzT3JHZXRQcm9wcyA9IHZhbHVlID8gdmFsdWVbZWxlbWVudEtleV0gOiBudWxsO1xuICAgICAgaWYgKHR5cGVvZiBwcm9wc09yR2V0UHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIHVzZXJQcm9wcyA/IHByb3BzT3JHZXRQcm9wcyh1c2VyUHJvcHMpIDogbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9wc09yR2V0UHJvcHM7XG4gICAgfSkuY29uY2F0KHVzZXJQcm9wcykucmVkdWNlKChhY2MsIHByb3BzKSA9PiB7XG4gICAgICBpZiAoIXByb3BzKSB7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG4gICAgICBPYmplY3QuZW50cmllcyhwcm9wcykuZm9yRWFjaChfcmVmID0+IHtcbiAgICAgICAgbGV0IFtrZXksIHZhbHVlXSA9IF9yZWY7XG4gICAgICAgIGlmIChpc0l0ZW0gJiYgW0FDVElWRV9LRVksIFNFTEVDVEVEX0tFWV0uaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoa2V5LmluZGV4T2YoJ29uJykgPT09IDApIHtcbiAgICAgICAgICBpZiAoIW1hcC5oYXMoa2V5KSkge1xuICAgICAgICAgICAgbWFwLnNldChrZXksIFtdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdmFyIF9tYXAkZ2V0O1xuICAgICAgICAgICAgKF9tYXAkZ2V0ID0gbWFwLmdldChrZXkpKSA9PSBudWxsIHx8IF9tYXAkZ2V0LnB1c2godmFsdWUpO1xuICAgICAgICAgICAgYWNjW2tleV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHZhciBfbWFwJGdldDI7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgICAgICAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIChfbWFwJGdldDIgPSBtYXAuZ2V0KGtleSkpID09IG51bGwgPyB2b2lkIDAgOiBfbWFwJGdldDIubWFwKGZuID0+IGZuKC4uLmFyZ3MpKS5maW5kKHZhbCA9PiB2YWwgIT09IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pXG4gIH07XG59XG4vKipcbiAqIE1lcmdlcyBhbiBhcnJheSBvZiBpbnRlcmFjdGlvbiBob29rcycgcHJvcHMgaW50byBwcm9wIGdldHRlcnMsIGFsbG93aW5nXG4gKiBldmVudCBoYW5kbGVyIGZ1bmN0aW9ucyB0byBiZSBjb21wb3NlZCB0b2dldGhlciB3aXRob3V0IG92ZXJ3cml0aW5nIG9uZVxuICogYW5vdGhlci5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy91c2VJbnRlcmFjdGlvbnNcbiAqL1xuZnVuY3Rpb24gdXNlSW50ZXJhY3Rpb25zKHByb3BzTGlzdCkge1xuICBpZiAocHJvcHNMaXN0ID09PSB2b2lkIDApIHtcbiAgICBwcm9wc0xpc3QgPSBbXTtcbiAgfVxuICBjb25zdCByZWZlcmVuY2VEZXBzID0gcHJvcHNMaXN0Lm1hcChrZXkgPT4ga2V5ID09IG51bGwgPyB2b2lkIDAgOiBrZXkucmVmZXJlbmNlKTtcbiAgY29uc3QgZmxvYXRpbmdEZXBzID0gcHJvcHNMaXN0Lm1hcChrZXkgPT4ga2V5ID09IG51bGwgPyB2b2lkIDAgOiBrZXkuZmxvYXRpbmcpO1xuICBjb25zdCBpdGVtRGVwcyA9IHByb3BzTGlzdC5tYXAoa2V5ID0+IGtleSA9PSBudWxsID8gdm9pZCAwIDoga2V5Lml0ZW0pO1xuICBjb25zdCBnZXRSZWZlcmVuY2VQcm9wcyA9IFJlYWN0LnVzZUNhbGxiYWNrKHVzZXJQcm9wcyA9PiBtZXJnZVByb3BzKHVzZXJQcm9wcywgcHJvcHNMaXN0LCAncmVmZXJlbmNlJyksXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgcmVmZXJlbmNlRGVwcyk7XG4gIGNvbnN0IGdldEZsb2F0aW5nUHJvcHMgPSBSZWFjdC51c2VDYWxsYmFjayh1c2VyUHJvcHMgPT4gbWVyZ2VQcm9wcyh1c2VyUHJvcHMsIHByb3BzTGlzdCwgJ2Zsb2F0aW5nJyksXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgZmxvYXRpbmdEZXBzKTtcbiAgY29uc3QgZ2V0SXRlbVByb3BzID0gUmVhY3QudXNlQ2FsbGJhY2sodXNlclByb3BzID0+IG1lcmdlUHJvcHModXNlclByb3BzLCBwcm9wc0xpc3QsICdpdGVtJyksXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgaXRlbURlcHMpO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIGdldFJlZmVyZW5jZVByb3BzLFxuICAgIGdldEZsb2F0aW5nUHJvcHMsXG4gICAgZ2V0SXRlbVByb3BzXG4gIH0pLCBbZ2V0UmVmZXJlbmNlUHJvcHMsIGdldEZsb2F0aW5nUHJvcHMsIGdldEl0ZW1Qcm9wc10pO1xufVxuXG5sZXQgaXNQcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID0gZmFsc2U7XG5mdW5jdGlvbiBkb1N3aXRjaChvcmllbnRhdGlvbiwgdmVydGljYWwsIGhvcml6b250YWwpIHtcbiAgc3dpdGNoIChvcmllbnRhdGlvbikge1xuICAgIGNhc2UgJ3ZlcnRpY2FsJzpcbiAgICAgIHJldHVybiB2ZXJ0aWNhbDtcbiAgICBjYXNlICdob3Jpem9udGFsJzpcbiAgICAgIHJldHVybiBob3Jpem9udGFsO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmVydGljYWwgfHwgaG9yaXpvbnRhbDtcbiAgfVxufVxuZnVuY3Rpb24gaXNNYWluT3JpZW50YXRpb25LZXkoa2V5LCBvcmllbnRhdGlvbikge1xuICBjb25zdCB2ZXJ0aWNhbCA9IGtleSA9PT0gQVJST1dfVVAgfHwga2V5ID09PSBBUlJPV19ET1dOO1xuICBjb25zdCBob3Jpem9udGFsID0ga2V5ID09PSBBUlJPV19MRUZUIHx8IGtleSA9PT0gQVJST1dfUklHSFQ7XG4gIHJldHVybiBkb1N3aXRjaChvcmllbnRhdGlvbiwgdmVydGljYWwsIGhvcml6b250YWwpO1xufVxuZnVuY3Rpb24gaXNNYWluT3JpZW50YXRpb25Ub0VuZEtleShrZXksIG9yaWVudGF0aW9uLCBydGwpIHtcbiAgY29uc3QgdmVydGljYWwgPSBrZXkgPT09IEFSUk9XX0RPV047XG4gIGNvbnN0IGhvcml6b250YWwgPSBydGwgPyBrZXkgPT09IEFSUk9XX0xFRlQgOiBrZXkgPT09IEFSUk9XX1JJR0hUO1xuICByZXR1cm4gZG9Td2l0Y2gob3JpZW50YXRpb24sIHZlcnRpY2FsLCBob3Jpem9udGFsKSB8fCBrZXkgPT09ICdFbnRlcicgfHwga2V5ID09PSAnICcgfHwga2V5ID09PSAnJztcbn1cbmZ1bmN0aW9uIGlzQ3Jvc3NPcmllbnRhdGlvbk9wZW5LZXkoa2V5LCBvcmllbnRhdGlvbiwgcnRsKSB7XG4gIGNvbnN0IHZlcnRpY2FsID0gcnRsID8ga2V5ID09PSBBUlJPV19MRUZUIDoga2V5ID09PSBBUlJPV19SSUdIVDtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGtleSA9PT0gQVJST1dfRE9XTjtcbiAgcmV0dXJuIGRvU3dpdGNoKG9yaWVudGF0aW9uLCB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCk7XG59XG5mdW5jdGlvbiBpc0Nyb3NzT3JpZW50YXRpb25DbG9zZUtleShrZXksIG9yaWVudGF0aW9uLCBydGwpIHtcbiAgY29uc3QgdmVydGljYWwgPSBydGwgPyBrZXkgPT09IEFSUk9XX1JJR0hUIDoga2V5ID09PSBBUlJPV19MRUZUO1xuICBjb25zdCBob3Jpem9udGFsID0ga2V5ID09PSBBUlJPV19VUDtcbiAgcmV0dXJuIGRvU3dpdGNoKG9yaWVudGF0aW9uLCB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCk7XG59XG4vKipcbiAqIEFkZHMgYXJyb3cga2V5LWJhc2VkIG5hdmlnYXRpb24gb2YgYSBsaXN0IG9mIGl0ZW1zLCBlaXRoZXIgdXNpbmcgcmVhbCBET01cbiAqIGZvY3VzIG9yIHZpcnR1YWwgZm9jdXMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlTGlzdE5hdmlnYXRpb25cbiAqL1xuZnVuY3Rpb24gdXNlTGlzdE5hdmlnYXRpb24oY29udGV4dCwgcHJvcHMpIHtcbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgb25PcGVuQ2hhbmdlLFxuICAgIGVsZW1lbnRzXG4gIH0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgbGlzdFJlZixcbiAgICBhY3RpdmVJbmRleCxcbiAgICBvbk5hdmlnYXRlOiB1bnN0YWJsZV9vbk5hdmlnYXRlID0gKCkgPT4ge30sXG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgc2VsZWN0ZWRJbmRleCA9IG51bGwsXG4gICAgYWxsb3dFc2NhcGUgPSBmYWxzZSxcbiAgICBsb29wID0gZmFsc2UsXG4gICAgbmVzdGVkID0gZmFsc2UsXG4gICAgcnRsID0gZmFsc2UsXG4gICAgdmlydHVhbCA9IGZhbHNlLFxuICAgIGZvY3VzSXRlbU9uT3BlbiA9ICdhdXRvJyxcbiAgICBmb2N1c0l0ZW1PbkhvdmVyID0gdHJ1ZSxcbiAgICBvcGVuT25BcnJvd0tleURvd24gPSB0cnVlLFxuICAgIGRpc2FibGVkSW5kaWNlcyA9IHVuZGVmaW5lZCxcbiAgICBvcmllbnRhdGlvbiA9ICd2ZXJ0aWNhbCcsXG4gICAgY29scyA9IDEsXG4gICAgc2Nyb2xsSXRlbUludG9WaWV3ID0gdHJ1ZSxcbiAgICB2aXJ0dWFsSXRlbVJlZixcbiAgICBpdGVtU2l6ZXMsXG4gICAgZGVuc2UgPSBmYWxzZVxuICB9ID0gcHJvcHM7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICBpZiAoYWxsb3dFc2NhcGUpIHtcbiAgICAgIGlmICghbG9vcCkge1xuICAgICAgICB3YXJuKCdgdXNlTGlzdE5hdmlnYXRpb25gIGxvb3BpbmcgbXVzdCBiZSBlbmFibGVkIHRvIGFsbG93IGVzY2FwaW5nLicpO1xuICAgICAgfVxuICAgICAgaWYgKCF2aXJ0dWFsKSB7XG4gICAgICAgIHdhcm4oJ2B1c2VMaXN0TmF2aWdhdGlvbmAgbXVzdCBiZSB2aXJ0dWFsIHRvIGFsbG93IGVzY2FwaW5nLicpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAob3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcgJiYgY29scyA+IDEpIHtcbiAgICAgIHdhcm4oJ0luIGdyaWQgbGlzdCBuYXZpZ2F0aW9uIG1vZGUgKGBjb2xzYCA+IDEpLCB0aGUgYG9yaWVudGF0aW9uYCBzaG91bGQnLCAnYmUgZWl0aGVyIFwiaG9yaXpvbnRhbFwiIG9yIFwiYm90aFwiLicpO1xuICAgIH1cbiAgfVxuICBjb25zdCBmbG9hdGluZ0ZvY3VzRWxlbWVudCA9IGdldEZsb2F0aW5nRm9jdXNFbGVtZW50KGVsZW1lbnRzLmZsb2F0aW5nKTtcbiAgY29uc3QgZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYgPSB1c2VMYXRlc3RSZWYoZmxvYXRpbmdGb2N1c0VsZW1lbnQpO1xuICBjb25zdCBwYXJlbnRJZCA9IHVzZUZsb2F0aW5nUGFyZW50Tm9kZUlkKCk7XG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcbiAgY29uc3Qgb25OYXZpZ2F0ZSA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uTmF2aWdhdGUpO1xuICBjb25zdCBmb2N1c0l0ZW1Pbk9wZW5SZWYgPSBSZWFjdC51c2VSZWYoZm9jdXNJdGVtT25PcGVuKTtcbiAgY29uc3QgaW5kZXhSZWYgPSBSZWFjdC51c2VSZWYoc2VsZWN0ZWRJbmRleCAhPSBudWxsID8gc2VsZWN0ZWRJbmRleCA6IC0xKTtcbiAgY29uc3Qga2V5UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBpc1BvaW50ZXJNb2RhbGl0eVJlZiA9IFJlYWN0LnVzZVJlZih0cnVlKTtcbiAgY29uc3QgcHJldmlvdXNPbk5hdmlnYXRlUmVmID0gUmVhY3QudXNlUmVmKG9uTmF2aWdhdGUpO1xuICBjb25zdCBwcmV2aW91c01vdW50ZWRSZWYgPSBSZWFjdC51c2VSZWYoISFlbGVtZW50cy5mbG9hdGluZyk7XG4gIGNvbnN0IHByZXZpb3VzT3BlblJlZiA9IFJlYWN0LnVzZVJlZihvcGVuKTtcbiAgY29uc3QgZm9yY2VTeW5jRm9jdXMgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICBjb25zdCBmb3JjZVNjcm9sbEludG9WaWV3UmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgZGlzYWJsZWRJbmRpY2VzUmVmID0gdXNlTGF0ZXN0UmVmKGRpc2FibGVkSW5kaWNlcyk7XG4gIGNvbnN0IGxhdGVzdE9wZW5SZWYgPSB1c2VMYXRlc3RSZWYob3Blbik7XG4gIGNvbnN0IHNjcm9sbEl0ZW1JbnRvVmlld1JlZiA9IHVzZUxhdGVzdFJlZihzY3JvbGxJdGVtSW50b1ZpZXcpO1xuICBjb25zdCBzZWxlY3RlZEluZGV4UmVmID0gdXNlTGF0ZXN0UmVmKHNlbGVjdGVkSW5kZXgpO1xuICBjb25zdCBbYWN0aXZlSWQsIHNldEFjdGl2ZUlkXSA9IFJlYWN0LnVzZVN0YXRlKCk7XG4gIGNvbnN0IFt2aXJ0dWFsSWQsIHNldFZpcnR1YWxJZF0gPSBSZWFjdC51c2VTdGF0ZSgpO1xuICBjb25zdCBmb2N1c0l0ZW0gPSB1c2VFZmZlY3RFdmVudChmdW5jdGlvbiAobGlzdFJlZiwgaW5kZXhSZWYsIGZvcmNlU2Nyb2xsSW50b1ZpZXcpIHtcbiAgICBpZiAoZm9yY2VTY3JvbGxJbnRvVmlldyA9PT0gdm9pZCAwKSB7XG4gICAgICBmb3JjZVNjcm9sbEludG9WaWV3ID0gZmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJ1bkZvY3VzKGl0ZW0pIHtcbiAgICAgIGlmICh2aXJ0dWFsKSB7XG4gICAgICAgIHNldEFjdGl2ZUlkKGl0ZW0uaWQpO1xuICAgICAgICB0cmVlID09IG51bGwgfHwgdHJlZS5ldmVudHMuZW1pdCgndmlydHVhbGZvY3VzJywgaXRlbSk7XG4gICAgICAgIGlmICh2aXJ0dWFsSXRlbVJlZikge1xuICAgICAgICAgIHZpcnR1YWxJdGVtUmVmLmN1cnJlbnQgPSBpdGVtO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnF1ZXVlRm9jdXMoaXRlbSwge1xuICAgICAgICAgIHByZXZlbnRTY3JvbGw6IHRydWUsXG4gICAgICAgICAgLy8gTWFjIFNhZmFyaSBkb2VzIG5vdCBtb3ZlIHRoZSB2aXJ0dWFsIGN1cnNvciB1bmxlc3MgdGhlIGZvY3VzIGNhbGxcbiAgICAgICAgICAvLyBpcyBzeW5jLiBIb3dldmVyLCBmb3IgdGhlIHZlcnkgZmlyc3QgZm9jdXMgY2FsbCwgd2UgbmVlZCB0byB3YWl0XG4gICAgICAgICAgLy8gZm9yIHRoZSBwb3NpdGlvbiB0byBiZSByZWFkeSBpbiBvcmRlciB0byBwcmV2ZW50IHVud2FudGVkXG4gICAgICAgICAgLy8gc2Nyb2xsaW5nLiBUaGlzIG1lYW5zIHRoZSB2aXJ0dWFsIGN1cnNvciB3aWxsIG5vdCBtb3ZlIHRvIHRoZSBmaXJzdFxuICAgICAgICAgIC8vIGl0ZW0gd2hlbiBmaXJzdCBvcGVuaW5nIHRoZSBmbG9hdGluZyBlbGVtZW50LCBidXQgd2lsbCBvblxuICAgICAgICAgIC8vIHN1YnNlcXVlbnQgY2FsbHMuIGBwcmV2ZW50U2Nyb2xsYCBpcyBzdXBwb3J0ZWQgaW4gbW9kZXJuIFNhZmFyaSxcbiAgICAgICAgICAvLyBzbyB3ZSBjYW4gdXNlIHRoYXQgaW5zdGVhZC5cbiAgICAgICAgICAvLyBpT1MgU2FmYXJpIG11c3QgYmUgYXN5bmMgb3IgdGhlIGZpcnN0IGl0ZW0gd2lsbCBub3QgYmUgZm9jdXNlZC5cbiAgICAgICAgICBzeW5jOiBpc01hYygpICYmIGlzU2FmYXJpKCkgPyBpc1ByZXZlbnRTY3JvbGxTdXBwb3J0ZWQgfHwgZm9yY2VTeW5jRm9jdXMuY3VycmVudCA6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBpbml0aWFsSXRlbSA9IGxpc3RSZWYuY3VycmVudFtpbmRleFJlZi5jdXJyZW50XTtcbiAgICBpZiAoaW5pdGlhbEl0ZW0pIHtcbiAgICAgIHJ1bkZvY3VzKGluaXRpYWxJdGVtKTtcbiAgICB9XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIGNvbnN0IHdhaXRlZEl0ZW0gPSBsaXN0UmVmLmN1cnJlbnRbaW5kZXhSZWYuY3VycmVudF0gfHwgaW5pdGlhbEl0ZW07XG4gICAgICBpZiAoIXdhaXRlZEl0ZW0pIHJldHVybjtcbiAgICAgIGlmICghaW5pdGlhbEl0ZW0pIHtcbiAgICAgICAgcnVuRm9jdXMod2FpdGVkSXRlbSk7XG4gICAgICB9XG4gICAgICBjb25zdCBzY3JvbGxJbnRvVmlld09wdGlvbnMgPSBzY3JvbGxJdGVtSW50b1ZpZXdSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IHNob3VsZFNjcm9sbEludG9WaWV3ID0gc2Nyb2xsSW50b1ZpZXdPcHRpb25zICYmIGl0ZW0gJiYgKGZvcmNlU2Nyb2xsSW50b1ZpZXcgfHwgIWlzUG9pbnRlck1vZGFsaXR5UmVmLmN1cnJlbnQpO1xuICAgICAgaWYgKHNob3VsZFNjcm9sbEludG9WaWV3KSB7XG4gICAgICAgIC8vIEpTRE9NIGRvZXNuJ3Qgc3VwcG9ydCBgLnNjcm9sbEludG9WaWV3KClgIGJ1dCBpdCdzIHdpZGVseSBzdXBwb3J0ZWRcbiAgICAgICAgLy8gYnkgYWxsIGJyb3dzZXJzLlxuICAgICAgICB3YWl0ZWRJdGVtLnNjcm9sbEludG9WaWV3ID09IG51bGwgfHwgd2FpdGVkSXRlbS5zY3JvbGxJbnRvVmlldyh0eXBlb2Ygc2Nyb2xsSW50b1ZpZXdPcHRpb25zID09PSAnYm9vbGVhbicgPyB7XG4gICAgICAgICAgYmxvY2s6ICduZWFyZXN0JyxcbiAgICAgICAgICBpbmxpbmU6ICduZWFyZXN0J1xuICAgICAgICB9IDogc2Nyb2xsSW50b1ZpZXdPcHRpb25zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5mb2N1cyh7XG4gICAgICBnZXQgcHJldmVudFNjcm9sbCgpIHtcbiAgICAgICAgaXNQcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCBbXSk7XG5cbiAgLy8gU3luYyBgc2VsZWN0ZWRJbmRleGAgdG8gYmUgdGhlIGBhY3RpdmVJbmRleGAgdXBvbiBvcGVuaW5nIHRoZSBmbG9hdGluZ1xuICAvLyBlbGVtZW50LiBBbHNvLCByZXNldCBgYWN0aXZlSW5kZXhgIHVwb24gY2xvc2luZyB0aGUgZmxvYXRpbmcgZWxlbWVudC5cbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmIChvcGVuICYmIGVsZW1lbnRzLmZsb2F0aW5nKSB7XG4gICAgICBpZiAoZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgJiYgc2VsZWN0ZWRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgIC8vIFJlZ2FyZGxlc3Mgb2YgdGhlIHBvaW50ZXIgbW9kYWxpdHksIHdlIHdhbnQgdG8gZW5zdXJlIHRoZSBzZWxlY3RlZFxuICAgICAgICAvLyBpdGVtIGNvbWVzIGludG8gdmlldyB3aGVuIHRoZSBmbG9hdGluZyBlbGVtZW50IGlzIG9wZW5lZC5cbiAgICAgICAgZm9yY2VTY3JvbGxJbnRvVmlld1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IHNlbGVjdGVkSW5kZXg7XG4gICAgICAgIG9uTmF2aWdhdGUoc2VsZWN0ZWRJbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcmV2aW91c01vdW50ZWRSZWYuY3VycmVudCkge1xuICAgICAgLy8gU2luY2UgdGhlIHVzZXIgY2FuIHNwZWNpZnkgYG9uTmF2aWdhdGVgIGNvbmRpdGlvbmFsbHlcbiAgICAgIC8vIChvbk5hdmlnYXRlOiBvcGVuID8gc2V0QWN0aXZlSW5kZXggOiBzZXRTZWxlY3RlZEluZGV4KSxcbiAgICAgIC8vIHdlIHN0b3JlIGFuZCBjYWxsIHRoZSBwcmV2aW91cyBmdW5jdGlvbi5cbiAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgIHByZXZpb3VzT25OYXZpZ2F0ZVJlZi5jdXJyZW50KG51bGwpO1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGVsZW1lbnRzLmZsb2F0aW5nLCBzZWxlY3RlZEluZGV4LCBvbk5hdmlnYXRlXSk7XG5cbiAgLy8gU3luYyBgYWN0aXZlSW5kZXhgIHRvIGJlIHRoZSBmb2N1c2VkIGl0ZW0gd2hpbGUgdGhlIGZsb2F0aW5nIGVsZW1lbnQgaXNcbiAgLy8gb3Blbi5cbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmIChvcGVuICYmIGVsZW1lbnRzLmZsb2F0aW5nKSB7XG4gICAgICBpZiAoYWN0aXZlSW5kZXggPT0gbnVsbCkge1xuICAgICAgICBmb3JjZVN5bmNGb2N1cy5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIGlmIChzZWxlY3RlZEluZGV4UmVmLmN1cnJlbnQgIT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlc2V0IHdoaWxlIHRoZSBmbG9hdGluZyBlbGVtZW50IHdhcyBvcGVuIChlLmcuIHRoZSBsaXN0IGNoYW5nZWQpLlxuICAgICAgICBpZiAocHJldmlvdXNNb3VudGVkUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gLTE7XG4gICAgICAgICAgZm9jdXNJdGVtKGxpc3RSZWYsIGluZGV4UmVmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEluaXRpYWwgc3luYy5cbiAgICAgICAgaWYgKCghcHJldmlvdXNPcGVuUmVmLmN1cnJlbnQgfHwgIXByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50KSAmJiBmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCAmJiAoa2V5UmVmLmN1cnJlbnQgIT0gbnVsbCB8fCBmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCA9PT0gdHJ1ZSAmJiBrZXlSZWYuY3VycmVudCA9PSBudWxsKSkge1xuICAgICAgICAgIGxldCBydW5zID0gMDtcbiAgICAgICAgICBjb25zdCB3YWl0Rm9yTGlzdFBvcHVsYXRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChsaXN0UmVmLmN1cnJlbnRbMF0gPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBBdm9pZCBsZXR0aW5nIHRoZSBicm93c2VyIHBhaW50IGlmIHBvc3NpYmxlIG9uIHRoZSBmaXJzdCB0cnksXG4gICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB1c2UgckFGLiBEb24ndCB0cnkgbW9yZSB0aGFuIHR3aWNlLCBzaW5jZSBzb21ldGhpbmdcbiAgICAgICAgICAgICAgLy8gaXMgd3Jvbmcgb3RoZXJ3aXNlLlxuICAgICAgICAgICAgICBpZiAocnVucyA8IDIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlZHVsZXIgPSBydW5zID8gcmVxdWVzdEFuaW1hdGlvbkZyYW1lIDogcXVldWVNaWNyb3Rhc2s7XG4gICAgICAgICAgICAgICAgc2NoZWR1bGVyKHdhaXRGb3JMaXN0UG9wdWxhdGVkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBydW5zKys7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0ga2V5UmVmLmN1cnJlbnQgPT0gbnVsbCB8fCBpc01haW5PcmllbnRhdGlvblRvRW5kS2V5KGtleVJlZi5jdXJyZW50LCBvcmllbnRhdGlvbiwgcnRsKSB8fCBuZXN0ZWQgPyBnZXRNaW5JbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXNSZWYuY3VycmVudCkgOiBnZXRNYXhJbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXNSZWYuY3VycmVudCk7XG4gICAgICAgICAgICAgIGtleVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICAgICAgb25OYXZpZ2F0ZShpbmRleFJlZi5jdXJyZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICAgIHdhaXRGb3JMaXN0UG9wdWxhdGVkKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWlzSW5kZXhPdXRPZkJvdW5kcyhsaXN0UmVmLCBhY3RpdmVJbmRleCkpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGFjdGl2ZUluZGV4O1xuICAgICAgICBmb2N1c0l0ZW0obGlzdFJlZiwgaW5kZXhSZWYsIGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudCk7XG4gICAgICAgIGZvcmNlU2Nyb2xsSW50b1ZpZXdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGVsZW1lbnRzLmZsb2F0aW5nLCBhY3RpdmVJbmRleCwgc2VsZWN0ZWRJbmRleFJlZiwgbmVzdGVkLCBsaXN0UmVmLCBvcmllbnRhdGlvbiwgcnRsLCBvbk5hdmlnYXRlLCBmb2N1c0l0ZW0sIGRpc2FibGVkSW5kaWNlc1JlZl0pO1xuXG4gIC8vIEVuc3VyZSB0aGUgcGFyZW50IGZsb2F0aW5nIGVsZW1lbnQgaGFzIGZvY3VzIHdoZW4gYSBuZXN0ZWQgY2hpbGQgY2xvc2VzXG4gIC8vIHRvIGFsbG93IGFycm93IGtleSBuYXZpZ2F0aW9uIHRvIHdvcmsgYWZ0ZXIgdGhlIHBvaW50ZXIgbGVhdmVzIHRoZSBjaGlsZC5cbiAgaW5kZXgoKCkgPT4ge1xuICAgIHZhciBfbm9kZXMkZmluZDtcbiAgICBpZiAoIWVuYWJsZWQgfHwgZWxlbWVudHMuZmxvYXRpbmcgfHwgIXRyZWUgfHwgdmlydHVhbCB8fCAhcHJldmlvdXNNb3VudGVkUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9kZXMgPSB0cmVlLm5vZGVzUmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgcGFyZW50ID0gKF9ub2RlcyRmaW5kID0gbm9kZXMuZmluZChub2RlID0+IG5vZGUuaWQgPT09IHBhcmVudElkKSkgPT0gbnVsbCB8fCAoX25vZGVzJGZpbmQgPSBfbm9kZXMkZmluZC5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX25vZGVzJGZpbmQuZWxlbWVudHMuZmxvYXRpbmc7XG4gICAgY29uc3QgYWN0aXZlRWwgPSBhY3RpdmVFbGVtZW50KGdldERvY3VtZW50KGVsZW1lbnRzLmZsb2F0aW5nKSk7XG4gICAgY29uc3QgdHJlZUNvbnRhaW5zQWN0aXZlRWwgPSBub2Rlcy5zb21lKG5vZGUgPT4gbm9kZS5jb250ZXh0ICYmIGNvbnRhaW5zKG5vZGUuY29udGV4dC5lbGVtZW50cy5mbG9hdGluZywgYWN0aXZlRWwpKTtcbiAgICBpZiAocGFyZW50ICYmICF0cmVlQ29udGFpbnNBY3RpdmVFbCAmJiBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50KSB7XG4gICAgICBwYXJlbnQuZm9jdXMoe1xuICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBlbGVtZW50cy5mbG9hdGluZywgdHJlZSwgcGFyZW50SWQsIHZpcnR1YWxdKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmICghZW5hYmxlZCkgcmV0dXJuO1xuICAgIGlmICghdHJlZSkgcmV0dXJuO1xuICAgIGlmICghdmlydHVhbCkgcmV0dXJuO1xuICAgIGlmIChwYXJlbnRJZCkgcmV0dXJuO1xuICAgIGZ1bmN0aW9uIGhhbmRsZVZpcnR1YWxGb2N1cyhpdGVtKSB7XG4gICAgICBzZXRWaXJ0dWFsSWQoaXRlbS5pZCk7XG4gICAgICBpZiAodmlydHVhbEl0ZW1SZWYpIHtcbiAgICAgICAgdmlydHVhbEl0ZW1SZWYuY3VycmVudCA9IGl0ZW07XG4gICAgICB9XG4gICAgfVxuICAgIHRyZWUuZXZlbnRzLm9uKCd2aXJ0dWFsZm9jdXMnLCBoYW5kbGVWaXJ0dWFsRm9jdXMpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0cmVlLmV2ZW50cy5vZmYoJ3ZpcnR1YWxmb2N1cycsIGhhbmRsZVZpcnR1YWxGb2N1cyk7XG4gICAgfTtcbiAgfSwgW2VuYWJsZWQsIHRyZWUsIHZpcnR1YWwsIHBhcmVudElkLCB2aXJ0dWFsSXRlbVJlZl0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgcHJldmlvdXNPbk5hdmlnYXRlUmVmLmN1cnJlbnQgPSBvbk5hdmlnYXRlO1xuICAgIHByZXZpb3VzTW91bnRlZFJlZi5jdXJyZW50ID0gISFlbGVtZW50cy5mbG9hdGluZztcbiAgfSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIGtleVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH0sIFtvcGVuXSk7XG4gIGluZGV4KCgpID0+IHtcbiAgICBwcmV2aW91c09wZW5SZWYuY3VycmVudCA9IG9wZW47XG4gIH0sIFtvcGVuXSk7XG4gIGNvbnN0IGhhc0FjdGl2ZUluZGV4ID0gYWN0aXZlSW5kZXggIT0gbnVsbDtcbiAgY29uc3QgaXRlbSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGZ1bmN0aW9uIHN5bmNDdXJyZW50VGFyZ2V0KGN1cnJlbnRUYXJnZXQpIHtcbiAgICAgIGlmICghb3BlbikgcmV0dXJuO1xuICAgICAgY29uc3QgaW5kZXggPSBsaXN0UmVmLmN1cnJlbnQuaW5kZXhPZihjdXJyZW50VGFyZ2V0KTtcbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgb25OYXZpZ2F0ZShpbmRleCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHByb3BzID0ge1xuICAgICAgb25Gb2N1cyhfcmVmKSB7XG4gICAgICAgIGxldCB7XG4gICAgICAgICAgY3VycmVudFRhcmdldFxuICAgICAgICB9ID0gX3JlZjtcbiAgICAgICAgc3luY0N1cnJlbnRUYXJnZXQoY3VycmVudFRhcmdldCk7XG4gICAgICB9LFxuICAgICAgb25DbGljazogX3JlZjIgPT4ge1xuICAgICAgICBsZXQge1xuICAgICAgICAgIGN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSA9IF9yZWYyO1xuICAgICAgICByZXR1cm4gY3VycmVudFRhcmdldC5mb2N1cyh7XG4gICAgICAgICAgcHJldmVudFNjcm9sbDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAvLyBTYWZhcmlcbiAgICAgIC4uLihmb2N1c0l0ZW1PbkhvdmVyICYmIHtcbiAgICAgICAgb25Nb3VzZU1vdmUoX3JlZjMpIHtcbiAgICAgICAgICBsZXQge1xuICAgICAgICAgICAgY3VycmVudFRhcmdldFxuICAgICAgICAgIH0gPSBfcmVmMztcbiAgICAgICAgICBzeW5jQ3VycmVudFRhcmdldChjdXJyZW50VGFyZ2V0KTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Qb2ludGVyTGVhdmUoX3JlZjQpIHtcbiAgICAgICAgICBsZXQge1xuICAgICAgICAgICAgcG9pbnRlclR5cGVcbiAgICAgICAgICB9ID0gX3JlZjQ7XG4gICAgICAgICAgaWYgKCFpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50IHx8IHBvaW50ZXJUeXBlID09PSAndG91Y2gnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSAtMTtcbiAgICAgICAgICBmb2N1c0l0ZW0obGlzdFJlZiwgaW5kZXhSZWYpO1xuICAgICAgICAgIG9uTmF2aWdhdGUobnVsbCk7XG4gICAgICAgICAgaWYgKCF2aXJ0dWFsKSB7XG4gICAgICAgICAgICBlbnF1ZXVlRm9jdXMoZmxvYXRpbmdGb2N1c0VsZW1lbnRSZWYuY3VycmVudCwge1xuICAgICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfTtcbiAgICByZXR1cm4gcHJvcHM7XG4gIH0sIFtvcGVuLCBmbG9hdGluZ0ZvY3VzRWxlbWVudFJlZiwgZm9jdXNJdGVtLCBmb2N1c0l0ZW1PbkhvdmVyLCBsaXN0UmVmLCBvbk5hdmlnYXRlLCB2aXJ0dWFsXSk7XG4gIGNvbnN0IGNvbW1vbk9uS2V5RG93biA9IHVzZUVmZmVjdEV2ZW50KGV2ZW50ID0+IHtcbiAgICBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgZm9yY2VTeW5jRm9jdXMuY3VycmVudCA9IHRydWU7XG5cbiAgICAvLyBJZiB0aGUgZmxvYXRpbmcgZWxlbWVudCBpcyBhbmltYXRpbmcgb3V0LCBpZ25vcmUgbmF2aWdhdGlvbi4gT3RoZXJ3aXNlLFxuICAgIC8vIHRoZSBgYWN0aXZlSW5kZXhgIGdldHMgc2V0IHRvIDAgZGVzcGl0ZSBub3QgYmVpbmcgb3BlbiBzbyB0aGUgbmV4dCB0aW1lXG4gICAgLy8gdGhlIHVzZXIgQXJyb3dEb3ducywgdGhlIGZpcnN0IGl0ZW0gd29uJ3QgYmUgZm9jdXNlZC5cbiAgICBpZiAoIWxhdGVzdE9wZW5SZWYuY3VycmVudCAmJiBldmVudC5jdXJyZW50VGFyZ2V0ID09PSBmbG9hdGluZ0ZvY3VzRWxlbWVudFJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChuZXN0ZWQgJiYgaXNDcm9zc09yaWVudGF0aW9uQ2xvc2VLZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsKSkge1xuICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIG9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgIGlmIChpc0hUTUxFbGVtZW50KGVsZW1lbnRzLmRvbVJlZmVyZW5jZSkgJiYgIXZpcnR1YWwpIHtcbiAgICAgICAgZWxlbWVudHMuZG9tUmVmZXJlbmNlLmZvY3VzKCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGluZGV4UmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgbWluSW5kZXggPSBnZXRNaW5JbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXMpO1xuICAgIGNvbnN0IG1heEluZGV4ID0gZ2V0TWF4SW5kZXgobGlzdFJlZiwgZGlzYWJsZWRJbmRpY2VzKTtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnSG9tZScpIHtcbiAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICBpbmRleFJlZi5jdXJyZW50ID0gbWluSW5kZXg7XG4gICAgICBvbk5hdmlnYXRlKGluZGV4UmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW5kJykge1xuICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBtYXhJbmRleDtcbiAgICAgIG9uTmF2aWdhdGUoaW5kZXhSZWYuY3VycmVudCk7XG4gICAgfVxuXG4gICAgLy8gR3JpZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChjb2xzID4gMSkge1xuICAgICAgY29uc3Qgc2l6ZXMgPSBpdGVtU2l6ZXMgfHwgQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogbGlzdFJlZi5jdXJyZW50Lmxlbmd0aFxuICAgICAgfSwgKCkgPT4gKHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMVxuICAgICAgfSkpO1xuICAgICAgLy8gVG8gY2FsY3VsYXRlIG1vdmVtZW50cyBvbiB0aGUgZ3JpZCwgd2UgdXNlIGh5cG90aGV0aWNhbCBjZWxsIGluZGljZXNcbiAgICAgIC8vIGFzIGlmIGV2ZXJ5IGl0ZW0gd2FzIDF4MSwgdGhlbiBjb252ZXJ0IGJhY2sgdG8gcmVhbCBpbmRpY2VzLlxuICAgICAgY29uc3QgY2VsbE1hcCA9IGJ1aWxkQ2VsbE1hcChzaXplcywgY29scywgZGVuc2UpO1xuICAgICAgY29uc3QgbWluR3JpZEluZGV4ID0gY2VsbE1hcC5maW5kSW5kZXgoaW5kZXggPT4gaW5kZXggIT0gbnVsbCAmJiAhaXNEaXNhYmxlZChsaXN0UmVmLmN1cnJlbnQsIGluZGV4LCBkaXNhYmxlZEluZGljZXMpKTtcbiAgICAgIC8vIGxhc3QgZW5hYmxlZCBpbmRleFxuICAgICAgY29uc3QgbWF4R3JpZEluZGV4ID0gY2VsbE1hcC5yZWR1Y2UoKGZvdW5kSW5kZXgsIGluZGV4LCBjZWxsSW5kZXgpID0+IGluZGV4ICE9IG51bGwgJiYgIWlzRGlzYWJsZWQobGlzdFJlZi5jdXJyZW50LCBpbmRleCwgZGlzYWJsZWRJbmRpY2VzKSA/IGNlbGxJbmRleCA6IGZvdW5kSW5kZXgsIC0xKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gY2VsbE1hcFtnZXRHcmlkTmF2aWdhdGVkSW5kZXgoe1xuICAgICAgICBjdXJyZW50OiBjZWxsTWFwLm1hcChpdGVtSW5kZXggPT4gaXRlbUluZGV4ICE9IG51bGwgPyBsaXN0UmVmLmN1cnJlbnRbaXRlbUluZGV4XSA6IG51bGwpXG4gICAgICB9LCB7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBvcmllbnRhdGlvbixcbiAgICAgICAgbG9vcCxcbiAgICAgICAgY29scyxcbiAgICAgICAgLy8gdHJlYXQgdW5kZWZpbmVkIChlbXB0eSBncmlkIHNwYWNlcykgYXMgZGlzYWJsZWQgaW5kaWNlcyBzbyB3ZVxuICAgICAgICAvLyBkb24ndCBlbmQgdXAgaW4gdGhlbVxuICAgICAgICBkaXNhYmxlZEluZGljZXM6IGdldENlbGxJbmRpY2VzKFsuLi4oZGlzYWJsZWRJbmRpY2VzIHx8IGxpc3RSZWYuY3VycmVudC5tYXAoKF8sIGluZGV4KSA9PiBpc0Rpc2FibGVkKGxpc3RSZWYuY3VycmVudCwgaW5kZXgpID8gaW5kZXggOiB1bmRlZmluZWQpKSwgdW5kZWZpbmVkXSwgY2VsbE1hcCksXG4gICAgICAgIG1pbkluZGV4OiBtaW5HcmlkSW5kZXgsXG4gICAgICAgIG1heEluZGV4OiBtYXhHcmlkSW5kZXgsXG4gICAgICAgIHByZXZJbmRleDogZ2V0Q2VsbEluZGV4T2ZDb3JuZXIoaW5kZXhSZWYuY3VycmVudCA+IG1heEluZGV4ID8gbWluSW5kZXggOiBpbmRleFJlZi5jdXJyZW50LCBzaXplcywgY2VsbE1hcCwgY29scyxcbiAgICAgICAgLy8gdXNlIGEgY29ybmVyIG1hdGNoaW5nIHRoZSBlZGdlIGNsb3Nlc3QgdG8gdGhlIGRpcmVjdGlvblxuICAgICAgICAvLyB3ZSdyZSBtb3ZpbmcgaW4gc28gd2UgZG9uJ3QgZW5kIHVwIGluIHRoZSBzYW1lIGl0ZW0uIFByZWZlclxuICAgICAgICAvLyB0b3AvbGVmdCBvdmVyIGJvdHRvbS9yaWdodC5cbiAgICAgICAgZXZlbnQua2V5ID09PSBBUlJPV19ET1dOID8gJ2JsJyA6IGV2ZW50LmtleSA9PT0gQVJST1dfUklHSFQgPyAndHInIDogJ3RsJyksXG4gICAgICAgIHN0b3BFdmVudDogdHJ1ZVxuICAgICAgfSldO1xuICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGluZGV4O1xuICAgICAgICBvbk5hdmlnYXRlKGluZGV4UmVmLmN1cnJlbnQpO1xuICAgICAgfVxuICAgICAgaWYgKG9yaWVudGF0aW9uID09PSAnYm90aCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNNYWluT3JpZW50YXRpb25LZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbikpIHtcbiAgICAgIHN0b3BFdmVudChldmVudCk7XG5cbiAgICAgIC8vIFJlc2V0IHRoZSBpbmRleCBpZiBubyBpdGVtIGlzIGZvY3VzZWQuXG4gICAgICBpZiAob3BlbiAmJiAhdmlydHVhbCAmJiBhY3RpdmVFbGVtZW50KGV2ZW50LmN1cnJlbnRUYXJnZXQub3duZXJEb2N1bWVudCkgPT09IGV2ZW50LmN1cnJlbnRUYXJnZXQpIHtcbiAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IGlzTWFpbk9yaWVudGF0aW9uVG9FbmRLZXkoZXZlbnQua2V5LCBvcmllbnRhdGlvbiwgcnRsKSA/IG1pbkluZGV4IDogbWF4SW5kZXg7XG4gICAgICAgIG9uTmF2aWdhdGUoaW5kZXhSZWYuY3VycmVudCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc01haW5PcmllbnRhdGlvblRvRW5kS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24sIHJ0bCkpIHtcbiAgICAgICAgaWYgKGxvb3ApIHtcbiAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gY3VycmVudEluZGV4ID49IG1heEluZGV4ID8gYWxsb3dFc2NhcGUgJiYgY3VycmVudEluZGV4ICE9PSBsaXN0UmVmLmN1cnJlbnQubGVuZ3RoID8gLTEgOiBtaW5JbmRleCA6IGZpbmROb25EaXNhYmxlZEluZGV4KGxpc3RSZWYsIHtcbiAgICAgICAgICAgIHN0YXJ0aW5nSW5kZXg6IGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAgIGRpc2FibGVkSW5kaWNlc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBNYXRoLm1pbihtYXhJbmRleCwgZmluZE5vbkRpc2FibGVkSW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobG9vcCkge1xuICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBjdXJyZW50SW5kZXggPD0gbWluSW5kZXggPyBhbGxvd0VzY2FwZSAmJiBjdXJyZW50SW5kZXggIT09IC0xID8gbGlzdFJlZi5jdXJyZW50Lmxlbmd0aCA6IG1heEluZGV4IDogZmluZE5vbkRpc2FibGVkSW5kZXgobGlzdFJlZiwge1xuICAgICAgICAgICAgc3RhcnRpbmdJbmRleDogY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZGVjcmVtZW50OiB0cnVlLFxuICAgICAgICAgICAgZGlzYWJsZWRJbmRpY2VzXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaW5kZXhSZWYuY3VycmVudCA9IE1hdGgubWF4KG1pbkluZGV4LCBmaW5kTm9uRGlzYWJsZWRJbmRleChsaXN0UmVmLCB7XG4gICAgICAgICAgICBzdGFydGluZ0luZGV4OiBjdXJyZW50SW5kZXgsXG4gICAgICAgICAgICBkZWNyZW1lbnQ6IHRydWUsXG4gICAgICAgICAgICBkaXNhYmxlZEluZGljZXNcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc0luZGV4T3V0T2ZCb3VuZHMobGlzdFJlZiwgaW5kZXhSZWYuY3VycmVudCkpIHtcbiAgICAgICAgb25OYXZpZ2F0ZShudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uTmF2aWdhdGUoaW5kZXhSZWYuY3VycmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgY29uc3QgYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIHZpcnR1YWwgJiYgb3BlbiAmJiBoYXNBY3RpdmVJbmRleCAmJiB7XG4gICAgICAnYXJpYS1hY3RpdmVkZXNjZW5kYW50JzogdmlydHVhbElkIHx8IGFjdGl2ZUlkXG4gICAgfTtcbiAgfSwgW3ZpcnR1YWwsIG9wZW4sIGhhc0FjdGl2ZUluZGV4LCB2aXJ0dWFsSWQsIGFjdGl2ZUlkXSk7XG4gIGNvbnN0IGZsb2F0aW5nID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdhcmlhLW9yaWVudGF0aW9uJzogb3JpZW50YXRpb24gPT09ICdib3RoJyA/IHVuZGVmaW5lZCA6IG9yaWVudGF0aW9uLFxuICAgICAgLi4uKCFpc1R5cGVhYmxlQ29tYm9ib3goZWxlbWVudHMuZG9tUmVmZXJlbmNlKSAmJiBhcmlhQWN0aXZlRGVzY2VuZGFudFByb3ApLFxuICAgICAgb25LZXlEb3duOiBjb21tb25PbktleURvd24sXG4gICAgICBvblBvaW50ZXJNb3ZlKCkge1xuICAgICAgICBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbYXJpYUFjdGl2ZURlc2NlbmRhbnRQcm9wLCBjb21tb25PbktleURvd24sIGVsZW1lbnRzLmRvbVJlZmVyZW5jZSwgb3JpZW50YXRpb25dKTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgZnVuY3Rpb24gY2hlY2tWaXJ0dWFsTW91c2UoZXZlbnQpIHtcbiAgICAgIGlmIChmb2N1c0l0ZW1Pbk9wZW4gPT09ICdhdXRvJyAmJiBpc1ZpcnR1YWxDbGljayhldmVudC5uYXRpdmVFdmVudCkpIHtcbiAgICAgICAgZm9jdXNJdGVtT25PcGVuUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBjaGVja1ZpcnR1YWxQb2ludGVyKGV2ZW50KSB7XG4gICAgICAvLyBgcG9pbnRlcmRvd25gIGZpcmVzIGZpcnN0LCByZXNldCB0aGUgc3RhdGUgdGhlbiBwZXJmb3JtIHRoZSBjaGVja3MuXG4gICAgICBmb2N1c0l0ZW1Pbk9wZW5SZWYuY3VycmVudCA9IGZvY3VzSXRlbU9uT3BlbjtcbiAgICAgIGlmIChmb2N1c0l0ZW1Pbk9wZW4gPT09ICdhdXRvJyAmJiBpc1ZpcnR1YWxQb2ludGVyRXZlbnQoZXZlbnQubmF0aXZlRXZlbnQpKSB7XG4gICAgICAgIGZvY3VzSXRlbU9uT3BlblJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmFyaWFBY3RpdmVEZXNjZW5kYW50UHJvcCxcbiAgICAgIG9uS2V5RG93bihldmVudCkge1xuICAgICAgICBpc1BvaW50ZXJNb2RhbGl0eVJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGlzQXJyb3dLZXkgPSBldmVudC5rZXkuaW5kZXhPZignQXJyb3cnKSA9PT0gMDtcbiAgICAgICAgY29uc3QgaXNDcm9zc09wZW5LZXkgPSBpc0Nyb3NzT3JpZW50YXRpb25PcGVuS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24sIHJ0bCk7XG4gICAgICAgIGNvbnN0IGlzQ3Jvc3NDbG9zZUtleSA9IGlzQ3Jvc3NPcmllbnRhdGlvbkNsb3NlS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24sIHJ0bCk7XG4gICAgICAgIGNvbnN0IGlzTWFpbktleSA9IGlzTWFpbk9yaWVudGF0aW9uS2V5KGV2ZW50LmtleSwgb3JpZW50YXRpb24pO1xuICAgICAgICBjb25zdCBpc05hdmlnYXRpb25LZXkgPSAobmVzdGVkID8gaXNDcm9zc09wZW5LZXkgOiBpc01haW5LZXkpIHx8IGV2ZW50LmtleSA9PT0gJ0VudGVyJyB8fCBldmVudC5rZXkudHJpbSgpID09PSAnJztcbiAgICAgICAgaWYgKHZpcnR1YWwgJiYgb3Blbikge1xuICAgICAgICAgIGNvbnN0IHJvb3ROb2RlID0gdHJlZSA9PSBudWxsID8gdm9pZCAwIDogdHJlZS5ub2Rlc1JlZi5jdXJyZW50LmZpbmQobm9kZSA9PiBub2RlLnBhcmVudElkID09IG51bGwpO1xuICAgICAgICAgIGNvbnN0IGRlZXBlc3ROb2RlID0gdHJlZSAmJiByb290Tm9kZSA/IGdldERlZXBlc3ROb2RlKHRyZWUubm9kZXNSZWYuY3VycmVudCwgcm9vdE5vZGUuaWQpIDogbnVsbDtcbiAgICAgICAgICBpZiAoaXNBcnJvd0tleSAmJiBkZWVwZXN0Tm9kZSAmJiB2aXJ0dWFsSXRlbVJlZikge1xuICAgICAgICAgICAgY29uc3QgZXZlbnRPYmplY3QgPSBuZXcgS2V5Ym9hcmRFdmVudCgna2V5ZG93bicsIHtcbiAgICAgICAgICAgICAga2V5OiBldmVudC5rZXksXG4gICAgICAgICAgICAgIGJ1YmJsZXM6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGlzQ3Jvc3NPcGVuS2V5IHx8IGlzQ3Jvc3NDbG9zZUtleSkge1xuICAgICAgICAgICAgICB2YXIgX2RlZXBlc3ROb2RlJGNvbnRleHQsIF9kZWVwZXN0Tm9kZSRjb250ZXh0MjtcbiAgICAgICAgICAgICAgY29uc3QgaXNDdXJyZW50VGFyZ2V0ID0gKChfZGVlcGVzdE5vZGUkY29udGV4dCA9IGRlZXBlc3ROb2RlLmNvbnRleHQpID09IG51bGwgPyB2b2lkIDAgOiBfZGVlcGVzdE5vZGUkY29udGV4dC5lbGVtZW50cy5kb21SZWZlcmVuY2UpID09PSBldmVudC5jdXJyZW50VGFyZ2V0O1xuICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEl0ZW0gPSBpc0Nyb3NzQ2xvc2VLZXkgJiYgIWlzQ3VycmVudFRhcmdldCA/IChfZGVlcGVzdE5vZGUkY29udGV4dDIgPSBkZWVwZXN0Tm9kZS5jb250ZXh0KSA9PSBudWxsID8gdm9pZCAwIDogX2RlZXBlc3ROb2RlJGNvbnRleHQyLmVsZW1lbnRzLmRvbVJlZmVyZW5jZSA6IGlzQ3Jvc3NPcGVuS2V5ID8gbGlzdFJlZi5jdXJyZW50LmZpbmQoaXRlbSA9PiAoaXRlbSA9PSBudWxsID8gdm9pZCAwIDogaXRlbS5pZCkgPT09IGFjdGl2ZUlkKSA6IG51bGw7XG4gICAgICAgICAgICAgIGlmIChkaXNwYXRjaEl0ZW0pIHtcbiAgICAgICAgICAgICAgICBzdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgICAgIGRpc3BhdGNoSXRlbS5kaXNwYXRjaEV2ZW50KGV2ZW50T2JqZWN0KTtcbiAgICAgICAgICAgICAgICBzZXRWaXJ0dWFsSWQodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTWFpbktleSAmJiBkZWVwZXN0Tm9kZS5jb250ZXh0KSB7XG4gICAgICAgICAgICAgIGlmIChkZWVwZXN0Tm9kZS5jb250ZXh0Lm9wZW4gJiYgZGVlcGVzdE5vZGUucGFyZW50SWQgJiYgZXZlbnQuY3VycmVudFRhcmdldCAhPT0gZGVlcGVzdE5vZGUuY29udGV4dC5lbGVtZW50cy5kb21SZWZlcmVuY2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2RlZXBlc3ROb2RlJGNvbnRleHQkO1xuICAgICAgICAgICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgICAgICAgKF9kZWVwZXN0Tm9kZSRjb250ZXh0JCA9IGRlZXBlc3ROb2RlLmNvbnRleHQuZWxlbWVudHMuZG9tUmVmZXJlbmNlKSA9PSBudWxsIHx8IF9kZWVwZXN0Tm9kZSRjb250ZXh0JC5kaXNwYXRjaEV2ZW50KGV2ZW50T2JqZWN0KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNvbW1vbk9uS2V5RG93bihldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBhIGZsb2F0aW5nIGVsZW1lbnQgc2hvdWxkIG5vdCBvcGVuIG9uIGFycm93IGtleSBkb3duLCBhdm9pZFxuICAgICAgICAvLyBzZXR0aW5nIGBhY3RpdmVJbmRleGAgd2hpbGUgaXQncyBjbG9zZWQuXG4gICAgICAgIGlmICghb3BlbiAmJiAhb3Blbk9uQXJyb3dLZXlEb3duICYmIGlzQXJyb3dLZXkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmF2aWdhdGlvbktleSkge1xuICAgICAgICAgIGtleVJlZi5jdXJyZW50ID0gbmVzdGVkICYmIGlzTWFpbktleSA/IG51bGwgOiBldmVudC5rZXk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lc3RlZCkge1xuICAgICAgICAgIGlmIChpc0Nyb3NzT3BlbktleSkge1xuICAgICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgICAgICAgIGluZGV4UmVmLmN1cnJlbnQgPSBnZXRNaW5JbmRleChsaXN0UmVmLCBkaXNhYmxlZEluZGljZXNSZWYuY3VycmVudCk7XG4gICAgICAgICAgICAgIG9uTmF2aWdhdGUoaW5kZXhSZWYuY3VycmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc01haW5LZXkpIHtcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpbmRleFJlZi5jdXJyZW50ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICBpZiAoIW9wZW4gJiYgb3Blbk9uQXJyb3dLZXlEb3duKSB7XG4gICAgICAgICAgICBvbk9wZW5DaGFuZ2UodHJ1ZSwgZXZlbnQubmF0aXZlRXZlbnQsICdsaXN0LW5hdmlnYXRpb24nKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29tbW9uT25LZXlEb3duKGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICAgIG9uTmF2aWdhdGUoaW5kZXhSZWYuY3VycmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgb25Gb2N1cygpIHtcbiAgICAgICAgaWYgKG9wZW4gJiYgIXZpcnR1YWwpIHtcbiAgICAgICAgICBvbk5hdmlnYXRlKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgb25Qb2ludGVyRG93bjogY2hlY2tWaXJ0dWFsUG9pbnRlcixcbiAgICAgIG9uTW91c2VEb3duOiBjaGVja1ZpcnR1YWxNb3VzZSxcbiAgICAgIG9uQ2xpY2s6IGNoZWNrVmlydHVhbE1vdXNlXG4gICAgfTtcbiAgfSwgW2FjdGl2ZUlkLCBhcmlhQWN0aXZlRGVzY2VuZGFudFByb3AsIGNvbW1vbk9uS2V5RG93biwgZGlzYWJsZWRJbmRpY2VzUmVmLCBmb2N1c0l0ZW1Pbk9wZW4sIGxpc3RSZWYsIG5lc3RlZCwgb25OYXZpZ2F0ZSwgb25PcGVuQ2hhbmdlLCBvcGVuLCBvcGVuT25BcnJvd0tleURvd24sIG9yaWVudGF0aW9uLCBydGwsIHNlbGVjdGVkSW5kZXgsIHRyZWUsIHZpcnR1YWwsIHZpcnR1YWxJdGVtUmVmXSk7XG4gIHJldHVybiBSZWFjdC51c2VNZW1vKCgpID0+IGVuYWJsZWQgPyB7XG4gICAgcmVmZXJlbmNlLFxuICAgIGZsb2F0aW5nLFxuICAgIGl0ZW1cbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlLCBmbG9hdGluZywgaXRlbV0pO1xufVxuXG5jb25zdCBjb21wb25lbnRSb2xlVG9BcmlhUm9sZU1hcCA9IC8qI19fUFVSRV9fKi9uZXcgTWFwKFtbJ3NlbGVjdCcsICdsaXN0Ym94J10sIFsnY29tYm9ib3gnLCAnbGlzdGJveCddLCBbJ2xhYmVsJywgZmFsc2VdXSk7XG5cbi8qKlxuICogQWRkcyBiYXNlIHNjcmVlbiByZWFkZXIgcHJvcHMgdG8gdGhlIHJlZmVyZW5jZSBhbmQgZmxvYXRpbmcgZWxlbWVudHMgZm9yIGFcbiAqIGdpdmVuIGZsb2F0aW5nIGVsZW1lbnQgYHJvbGVgLlxuICogQHNlZSBodHRwczovL2Zsb2F0aW5nLXVpLmNvbS9kb2NzL3VzZVJvbGVcbiAqL1xuZnVuY3Rpb24gdXNlUm9sZShjb250ZXh0LCBwcm9wcykge1xuICB2YXIgX2NvbXBvbmVudFJvbGVUb0FyaWFSO1xuICBpZiAocHJvcHMgPT09IHZvaWQgMCkge1xuICAgIHByb3BzID0ge307XG4gIH1cbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgZmxvYXRpbmdJZFxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIHJvbGUgPSAnZGlhbG9nJ1xuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGFyaWFSb2xlID0gKF9jb21wb25lbnRSb2xlVG9BcmlhUiA9IGNvbXBvbmVudFJvbGVUb0FyaWFSb2xlTWFwLmdldChyb2xlKSkgIT0gbnVsbCA/IF9jb21wb25lbnRSb2xlVG9BcmlhUiA6IHJvbGU7XG4gIGNvbnN0IHJlZmVyZW5jZUlkID0gdXNlSWQoKTtcbiAgY29uc3QgcGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuICBjb25zdCBpc05lc3RlZCA9IHBhcmVudElkICE9IG51bGw7XG4gIGNvbnN0IHJlZmVyZW5jZSA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChhcmlhUm9sZSA9PT0gJ3Rvb2x0aXAnIHx8IHJvbGUgPT09ICdsYWJlbCcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFtcImFyaWEtXCIgKyAocm9sZSA9PT0gJ2xhYmVsJyA/ICdsYWJlbGxlZGJ5JyA6ICdkZXNjcmliZWRieScpXTogb3BlbiA/IGZsb2F0aW5nSWQgOiB1bmRlZmluZWRcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAnYXJpYS1leHBhbmRlZCc6IG9wZW4gPyAndHJ1ZScgOiAnZmFsc2UnLFxuICAgICAgJ2FyaWEtaGFzcG9wdXAnOiBhcmlhUm9sZSA9PT0gJ2FsZXJ0ZGlhbG9nJyA/ICdkaWFsb2cnIDogYXJpYVJvbGUsXG4gICAgICAnYXJpYS1jb250cm9scyc6IG9wZW4gPyBmbG9hdGluZ0lkIDogdW5kZWZpbmVkLFxuICAgICAgLi4uKGFyaWFSb2xlID09PSAnbGlzdGJveCcgJiYge1xuICAgICAgICByb2xlOiAnY29tYm9ib3gnXG4gICAgICB9KSxcbiAgICAgIC4uLihhcmlhUm9sZSA9PT0gJ21lbnUnICYmIHtcbiAgICAgICAgaWQ6IHJlZmVyZW5jZUlkXG4gICAgICB9KSxcbiAgICAgIC4uLihhcmlhUm9sZSA9PT0gJ21lbnUnICYmIGlzTmVzdGVkICYmIHtcbiAgICAgICAgcm9sZTogJ21lbnVpdGVtJ1xuICAgICAgfSksXG4gICAgICAuLi4ocm9sZSA9PT0gJ3NlbGVjdCcgJiYge1xuICAgICAgICAnYXJpYS1hdXRvY29tcGxldGUnOiAnbm9uZSdcbiAgICAgIH0pLFxuICAgICAgLi4uKHJvbGUgPT09ICdjb21ib2JveCcgJiYge1xuICAgICAgICAnYXJpYS1hdXRvY29tcGxldGUnOiAnbGlzdCdcbiAgICAgIH0pXG4gICAgfTtcbiAgfSwgW2FyaWFSb2xlLCBmbG9hdGluZ0lkLCBpc05lc3RlZCwgb3BlbiwgcmVmZXJlbmNlSWQsIHJvbGVdKTtcbiAgY29uc3QgZmxvYXRpbmcgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBmbG9hdGluZ1Byb3BzID0ge1xuICAgICAgaWQ6IGZsb2F0aW5nSWQsXG4gICAgICAuLi4oYXJpYVJvbGUgJiYge1xuICAgICAgICByb2xlOiBhcmlhUm9sZVxuICAgICAgfSlcbiAgICB9O1xuICAgIGlmIChhcmlhUm9sZSA9PT0gJ3Rvb2x0aXAnIHx8IHJvbGUgPT09ICdsYWJlbCcpIHtcbiAgICAgIHJldHVybiBmbG9hdGluZ1Byb3BzO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4uZmxvYXRpbmdQcm9wcyxcbiAgICAgIC4uLihhcmlhUm9sZSA9PT0gJ21lbnUnICYmIHtcbiAgICAgICAgJ2FyaWEtbGFiZWxsZWRieSc6IHJlZmVyZW5jZUlkXG4gICAgICB9KVxuICAgIH07XG4gIH0sIFthcmlhUm9sZSwgZmxvYXRpbmdJZCwgcmVmZXJlbmNlSWQsIHJvbGVdKTtcbiAgY29uc3QgaXRlbSA9IFJlYWN0LnVzZUNhbGxiYWNrKF9yZWYgPT4ge1xuICAgIGxldCB7XG4gICAgICBhY3RpdmUsXG4gICAgICBzZWxlY3RlZFxuICAgIH0gPSBfcmVmO1xuICAgIGNvbnN0IGNvbW1vblByb3BzID0ge1xuICAgICAgcm9sZTogJ29wdGlvbicsXG4gICAgICAuLi4oYWN0aXZlICYmIHtcbiAgICAgICAgaWQ6IGZsb2F0aW5nSWQgKyBcIi1vcHRpb25cIlxuICAgICAgfSlcbiAgICB9O1xuXG4gICAgLy8gRm9yIGBtZW51YCwgd2UgYXJlIHVuYWJsZSB0byB0ZWxsIGlmIHRoZSBpdGVtIGlzIGEgYG1lbnVpdGVtcmFkaW9gXG4gICAgLy8gb3IgYG1lbnVpdGVtY2hlY2tib3hgLiBGb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgcmVhc29ucywgYWxzb1xuICAgIC8vIGF2b2lkIGRlZmF1bHRpbmcgdG8gYG1lbnVpdGVtYCBhcyBpdCBtYXkgb3ZlcndyaXRlIGN1c3RvbSByb2xlIHByb3BzLlxuICAgIHN3aXRjaCAocm9sZSkge1xuICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5jb21tb25Qcm9wcyxcbiAgICAgICAgICAnYXJpYS1zZWxlY3RlZCc6IGFjdGl2ZSAmJiBzZWxlY3RlZFxuICAgICAgICB9O1xuICAgICAgY2FzZSAnY29tYm9ib3gnOlxuICAgICAgICB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblByb3BzLFxuICAgICAgICAgICAgLi4uKGFjdGl2ZSAmJiB7XG4gICAgICAgICAgICAgICdhcmlhLXNlbGVjdGVkJzogdHJ1ZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfSwgW2Zsb2F0aW5nSWQsIHJvbGVdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2UsXG4gICAgZmxvYXRpbmcsXG4gICAgaXRlbVxuICB9IDoge30sIFtlbmFibGVkLCByZWZlcmVuY2UsIGZsb2F0aW5nLCBpdGVtXSk7XG59XG5cbi8vIENvbnZlcnRzIGEgSlMgc3R5bGUga2V5IGxpa2UgYGJhY2tncm91bmRDb2xvcmAgdG8gYSBDU1MgdHJhbnNpdGlvbi1wcm9wZXJ0eVxuLy8gbGlrZSBgYmFja2dyb3VuZC1jb2xvcmAuXG5jb25zdCBjYW1lbENhc2VUb0tlYmFiQ2FzZSA9IHN0ciA9PiBzdHIucmVwbGFjZSgvW0EtWl0rKD8hW2Etel0pfFtBLVpdL2csICgkLCBvZnMpID0+IChvZnMgPyAnLScgOiAnJykgKyAkLnRvTG93ZXJDYXNlKCkpO1xuZnVuY3Rpb24gZXhlY1dpdGhBcmdzT3JSZXR1cm4odmFsdWVPckZuLCBhcmdzKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWVPckZuID09PSAnZnVuY3Rpb24nID8gdmFsdWVPckZuKGFyZ3MpIDogdmFsdWVPckZuO1xufVxuZnVuY3Rpb24gdXNlRGVsYXlVbm1vdW50KG9wZW4sIGR1cmF0aW9uTXMpIHtcbiAgY29uc3QgW2lzTW91bnRlZCwgc2V0SXNNb3VudGVkXSA9IFJlYWN0LnVzZVN0YXRlKG9wZW4pO1xuICBpZiAob3BlbiAmJiAhaXNNb3VudGVkKSB7XG4gICAgc2V0SXNNb3VudGVkKHRydWUpO1xuICB9XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFvcGVuICYmIGlzTW91bnRlZCkge1xuICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gc2V0SXNNb3VudGVkKGZhbHNlKSwgZHVyYXRpb25Ncyk7XG4gICAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgIH1cbiAgfSwgW29wZW4sIGlzTW91bnRlZCwgZHVyYXRpb25Nc10pO1xuICByZXR1cm4gaXNNb3VudGVkO1xufVxuLyoqXG4gKiBQcm92aWRlcyBhIHN0YXR1cyBzdHJpbmcgdG8gYXBwbHkgQ1NTIHRyYW5zaXRpb25zIHRvIGEgZmxvYXRpbmcgZWxlbWVudCxcbiAqIGNvcnJlY3RseSBoYW5kbGluZyBwbGFjZW1lbnQtYXdhcmUgdHJhbnNpdGlvbnMuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlVHJhbnNpdGlvbiN1c2V0cmFuc2l0aW9uc3RhdHVzXG4gKi9cbmZ1bmN0aW9uIHVzZVRyYW5zaXRpb25TdGF0dXMoY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBvcGVuLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICBmbG9hdGluZ1xuICAgIH1cbiAgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtcbiAgICBkdXJhdGlvbiA9IDI1MFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IGlzTnVtYmVyRHVyYXRpb24gPSB0eXBlb2YgZHVyYXRpb24gPT09ICdudW1iZXInO1xuICBjb25zdCBjbG9zZUR1cmF0aW9uID0gKGlzTnVtYmVyRHVyYXRpb24gPyBkdXJhdGlvbiA6IGR1cmF0aW9uLmNsb3NlKSB8fCAwO1xuICBjb25zdCBbc3RhdHVzLCBzZXRTdGF0dXNdID0gUmVhY3QudXNlU3RhdGUoJ3VubW91bnRlZCcpO1xuICBjb25zdCBpc01vdW50ZWQgPSB1c2VEZWxheVVubW91bnQob3BlbiwgY2xvc2VEdXJhdGlvbik7XG4gIGlmICghaXNNb3VudGVkICYmIHN0YXR1cyA9PT0gJ2Nsb3NlJykge1xuICAgIHNldFN0YXR1cygndW5tb3VudGVkJyk7XG4gIH1cbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmICghZmxvYXRpbmcpIHJldHVybjtcbiAgICBpZiAob3Blbikge1xuICAgICAgc2V0U3RhdHVzKCdpbml0aWFsJyk7XG4gICAgICBjb25zdCBmcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHNldFN0YXR1cygnb3BlbicpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShmcmFtZSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBzZXRTdGF0dXMoJ2Nsb3NlJyk7XG4gIH0sIFtvcGVuLCBmbG9hdGluZ10pO1xuICByZXR1cm4ge1xuICAgIGlzTW91bnRlZCxcbiAgICBzdGF0dXNcbiAgfTtcbn1cbi8qKlxuICogUHJvdmlkZXMgc3R5bGVzIHRvIGFwcGx5IENTUyB0cmFuc2l0aW9ucyB0byBhIGZsb2F0aW5nIGVsZW1lbnQsIGNvcnJlY3RseVxuICogaGFuZGxpbmcgcGxhY2VtZW50LWF3YXJlIHRyYW5zaXRpb25zLiBXcmFwcGVyIGFyb3VuZCBgdXNlVHJhbnNpdGlvblN0YXR1c2AuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlVHJhbnNpdGlvbiN1c2V0cmFuc2l0aW9uc3R5bGVzXG4gKi9cbmZ1bmN0aW9uIHVzZVRyYW5zaXRpb25TdHlsZXMoY29udGV4dCwgcHJvcHMpIHtcbiAgaWYgKHByb3BzID09PSB2b2lkIDApIHtcbiAgICBwcm9wcyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBpbml0aWFsOiB1bnN0YWJsZV9pbml0aWFsID0ge1xuICAgICAgb3BhY2l0eTogMFxuICAgIH0sXG4gICAgb3BlbjogdW5zdGFibGVfb3BlbixcbiAgICBjbG9zZTogdW5zdGFibGVfY2xvc2UsXG4gICAgY29tbW9uOiB1bnN0YWJsZV9jb21tb24sXG4gICAgZHVyYXRpb24gPSAyNTBcbiAgfSA9IHByb3BzO1xuICBjb25zdCBwbGFjZW1lbnQgPSBjb250ZXh0LnBsYWNlbWVudDtcbiAgY29uc3Qgc2lkZSA9IHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xuICBjb25zdCBmbkFyZ3MgPSBSZWFjdC51c2VNZW1vKCgpID0+ICh7XG4gICAgc2lkZSxcbiAgICBwbGFjZW1lbnRcbiAgfSksIFtzaWRlLCBwbGFjZW1lbnRdKTtcbiAgY29uc3QgaXNOdW1iZXJEdXJhdGlvbiA9IHR5cGVvZiBkdXJhdGlvbiA9PT0gJ251bWJlcic7XG4gIGNvbnN0IG9wZW5EdXJhdGlvbiA9IChpc051bWJlckR1cmF0aW9uID8gZHVyYXRpb24gOiBkdXJhdGlvbi5vcGVuKSB8fCAwO1xuICBjb25zdCBjbG9zZUR1cmF0aW9uID0gKGlzTnVtYmVyRHVyYXRpb24gPyBkdXJhdGlvbiA6IGR1cmF0aW9uLmNsb3NlKSB8fCAwO1xuICBjb25zdCBbc3R5bGVzLCBzZXRTdHlsZXNdID0gUmVhY3QudXNlU3RhdGUoKCkgPT4gKHtcbiAgICAuLi5leGVjV2l0aEFyZ3NPclJldHVybih1bnN0YWJsZV9jb21tb24sIGZuQXJncyksXG4gICAgLi4uZXhlY1dpdGhBcmdzT3JSZXR1cm4odW5zdGFibGVfaW5pdGlhbCwgZm5BcmdzKVxuICB9KSk7XG4gIGNvbnN0IHtcbiAgICBpc01vdW50ZWQsXG4gICAgc3RhdHVzXG4gIH0gPSB1c2VUcmFuc2l0aW9uU3RhdHVzKGNvbnRleHQsIHtcbiAgICBkdXJhdGlvblxuICB9KTtcbiAgY29uc3QgaW5pdGlhbFJlZiA9IHVzZUxhdGVzdFJlZih1bnN0YWJsZV9pbml0aWFsKTtcbiAgY29uc3Qgb3BlblJlZiA9IHVzZUxhdGVzdFJlZih1bnN0YWJsZV9vcGVuKTtcbiAgY29uc3QgY2xvc2VSZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfY2xvc2UpO1xuICBjb25zdCBjb21tb25SZWYgPSB1c2VMYXRlc3RSZWYodW5zdGFibGVfY29tbW9uKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGNvbnN0IGluaXRpYWxTdHlsZXMgPSBleGVjV2l0aEFyZ3NPclJldHVybihpbml0aWFsUmVmLmN1cnJlbnQsIGZuQXJncyk7XG4gICAgY29uc3QgY2xvc2VTdHlsZXMgPSBleGVjV2l0aEFyZ3NPclJldHVybihjbG9zZVJlZi5jdXJyZW50LCBmbkFyZ3MpO1xuICAgIGNvbnN0IGNvbW1vblN0eWxlcyA9IGV4ZWNXaXRoQXJnc09yUmV0dXJuKGNvbW1vblJlZi5jdXJyZW50LCBmbkFyZ3MpO1xuICAgIGNvbnN0IG9wZW5TdHlsZXMgPSBleGVjV2l0aEFyZ3NPclJldHVybihvcGVuUmVmLmN1cnJlbnQsIGZuQXJncykgfHwgT2JqZWN0LmtleXMoaW5pdGlhbFN0eWxlcykucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgYWNjW2tleV0gPSAnJztcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuICAgIGlmIChzdGF0dXMgPT09ICdpbml0aWFsJykge1xuICAgICAgc2V0U3R5bGVzKHN0eWxlcyA9PiAoe1xuICAgICAgICB0cmFuc2l0aW9uUHJvcGVydHk6IHN0eWxlcy50cmFuc2l0aW9uUHJvcGVydHksXG4gICAgICAgIC4uLmNvbW1vblN0eWxlcyxcbiAgICAgICAgLi4uaW5pdGlhbFN0eWxlc1xuICAgICAgfSkpO1xuICAgIH1cbiAgICBpZiAoc3RhdHVzID09PSAnb3BlbicpIHtcbiAgICAgIHNldFN0eWxlcyh7XG4gICAgICAgIHRyYW5zaXRpb25Qcm9wZXJ0eTogT2JqZWN0LmtleXMob3BlblN0eWxlcykubWFwKGNhbWVsQ2FzZVRvS2ViYWJDYXNlKS5qb2luKCcsJyksXG4gICAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogb3BlbkR1cmF0aW9uICsgXCJtc1wiLFxuICAgICAgICAuLi5jb21tb25TdHlsZXMsXG4gICAgICAgIC4uLm9wZW5TdHlsZXNcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoc3RhdHVzID09PSAnY2xvc2UnKSB7XG4gICAgICBjb25zdCBzdHlsZXMgPSBjbG9zZVN0eWxlcyB8fCBpbml0aWFsU3R5bGVzO1xuICAgICAgc2V0U3R5bGVzKHtcbiAgICAgICAgdHJhbnNpdGlvblByb3BlcnR5OiBPYmplY3Qua2V5cyhzdHlsZXMpLm1hcChjYW1lbENhc2VUb0tlYmFiQ2FzZSkuam9pbignLCcpLFxuICAgICAgICB0cmFuc2l0aW9uRHVyYXRpb246IGNsb3NlRHVyYXRpb24gKyBcIm1zXCIsXG4gICAgICAgIC4uLmNvbW1vblN0eWxlcyxcbiAgICAgICAgLi4uc3R5bGVzXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtjbG9zZUR1cmF0aW9uLCBjbG9zZVJlZiwgaW5pdGlhbFJlZiwgb3BlblJlZiwgY29tbW9uUmVmLCBvcGVuRHVyYXRpb24sIHN0YXR1cywgZm5BcmdzXSk7XG4gIHJldHVybiB7XG4gICAgaXNNb3VudGVkLFxuICAgIHN0eWxlc1xuICB9O1xufVxuXG4vKipcbiAqIFByb3ZpZGVzIGEgbWF0Y2hpbmcgY2FsbGJhY2sgdGhhdCBjYW4gYmUgdXNlZCB0byBmb2N1cyBhbiBpdGVtIGFzIHRoZSB1c2VyXG4gKiB0eXBlcywgb2Z0ZW4gdXNlZCBpbiB0YW5kZW0gd2l0aCBgdXNlTGlzdE5hdmlnYXRpb24oKWAuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlVHlwZWFoZWFkXG4gKi9cbmZ1bmN0aW9uIHVzZVR5cGVhaGVhZChjb250ZXh0LCBwcm9wcykge1xuICB2YXIgX3JlZjtcbiAgY29uc3Qge1xuICAgIG9wZW4sXG4gICAgZGF0YVJlZlxuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGxpc3RSZWYsXG4gICAgYWN0aXZlSW5kZXgsXG4gICAgb25NYXRjaDogdW5zdGFibGVfb25NYXRjaCxcbiAgICBvblR5cGluZ0NoYW5nZTogdW5zdGFibGVfb25UeXBpbmdDaGFuZ2UsXG4gICAgZW5hYmxlZCA9IHRydWUsXG4gICAgZmluZE1hdGNoID0gbnVsbCxcbiAgICByZXNldE1zID0gNzUwLFxuICAgIGlnbm9yZUtleXMgPSBbXSxcbiAgICBzZWxlY3RlZEluZGV4ID0gbnVsbFxuICB9ID0gcHJvcHM7XG4gIGNvbnN0IHRpbWVvdXRJZFJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBjb25zdCBzdHJpbmdSZWYgPSBSZWFjdC51c2VSZWYoJycpO1xuICBjb25zdCBwcmV2SW5kZXhSZWYgPSBSZWFjdC51c2VSZWYoKF9yZWYgPSBzZWxlY3RlZEluZGV4ICE9IG51bGwgPyBzZWxlY3RlZEluZGV4IDogYWN0aXZlSW5kZXgpICE9IG51bGwgPyBfcmVmIDogLTEpO1xuICBjb25zdCBtYXRjaEluZGV4UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBjb25zdCBvbk1hdGNoID0gdXNlRWZmZWN0RXZlbnQodW5zdGFibGVfb25NYXRjaCk7XG4gIGNvbnN0IG9uVHlwaW5nQ2hhbmdlID0gdXNlRWZmZWN0RXZlbnQodW5zdGFibGVfb25UeXBpbmdDaGFuZ2UpO1xuICBjb25zdCBmaW5kTWF0Y2hSZWYgPSB1c2VMYXRlc3RSZWYoZmluZE1hdGNoKTtcbiAgY29uc3QgaWdub3JlS2V5c1JlZiA9IHVzZUxhdGVzdFJlZihpZ25vcmVLZXlzKTtcbiAgaW5kZXgoKCkgPT4ge1xuICAgIGlmIChvcGVuKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkUmVmLmN1cnJlbnQpO1xuICAgICAgbWF0Y2hJbmRleFJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIHN0cmluZ1JlZi5jdXJyZW50ID0gJyc7XG4gICAgfVxuICB9LCBbb3Blbl0pO1xuICBpbmRleCgoKSA9PiB7XG4gICAgLy8gU3luYyBhcnJvdyBrZXkgbmF2aWdhdGlvbiBidXQgbm90IHR5cGVhaGVhZCBuYXZpZ2F0aW9uLlxuICAgIGlmIChvcGVuICYmIHN0cmluZ1JlZi5jdXJyZW50ID09PSAnJykge1xuICAgICAgdmFyIF9yZWYyO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSAoX3JlZjIgPSBzZWxlY3RlZEluZGV4ICE9IG51bGwgPyBzZWxlY3RlZEluZGV4IDogYWN0aXZlSW5kZXgpICE9IG51bGwgPyBfcmVmMiA6IC0xO1xuICAgIH1cbiAgfSwgW29wZW4sIHNlbGVjdGVkSW5kZXgsIGFjdGl2ZUluZGV4XSk7XG4gIGNvbnN0IHNldFR5cGluZ0NoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHZhbHVlID0+IHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGlmICghZGF0YVJlZi5jdXJyZW50LnR5cGluZykge1xuICAgICAgICBkYXRhUmVmLmN1cnJlbnQudHlwaW5nID0gdmFsdWU7XG4gICAgICAgIG9uVHlwaW5nQ2hhbmdlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGFSZWYuY3VycmVudC50eXBpbmcpIHtcbiAgICAgICAgZGF0YVJlZi5jdXJyZW50LnR5cGluZyA9IHZhbHVlO1xuICAgICAgICBvblR5cGluZ0NoYW5nZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgY29uc3Qgb25LZXlEb3duID0gdXNlRWZmZWN0RXZlbnQoZXZlbnQgPT4ge1xuICAgIGZ1bmN0aW9uIGdldE1hdGNoaW5nSW5kZXgobGlzdCwgb3JkZXJlZExpc3QsIHN0cmluZykge1xuICAgICAgY29uc3Qgc3RyID0gZmluZE1hdGNoUmVmLmN1cnJlbnQgPyBmaW5kTWF0Y2hSZWYuY3VycmVudChvcmRlcmVkTGlzdCwgc3RyaW5nKSA6IG9yZGVyZWRMaXN0LmZpbmQodGV4dCA9PiAodGV4dCA9PSBudWxsID8gdm9pZCAwIDogdGV4dC50b0xvY2FsZUxvd2VyQ2FzZSgpLmluZGV4T2Yoc3RyaW5nLnRvTG9jYWxlTG93ZXJDYXNlKCkpKSA9PT0gMCk7XG4gICAgICByZXR1cm4gc3RyID8gbGlzdC5pbmRleE9mKHN0cikgOiAtMTtcbiAgICB9XG4gICAgY29uc3QgbGlzdENvbnRlbnQgPSBsaXN0UmVmLmN1cnJlbnQ7XG4gICAgaWYgKHN0cmluZ1JlZi5jdXJyZW50Lmxlbmd0aCA+IDAgJiYgc3RyaW5nUmVmLmN1cnJlbnRbMF0gIT09ICcgJykge1xuICAgICAgaWYgKGdldE1hdGNoaW5nSW5kZXgobGlzdENvbnRlbnQsIGxpc3RDb250ZW50LCBzdHJpbmdSZWYuY3VycmVudCkgPT09IC0xKSB7XG4gICAgICAgIHNldFR5cGluZ0NoYW5nZShmYWxzZSk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJyAnKSB7XG4gICAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsaXN0Q29udGVudCA9PSBudWxsIHx8IGlnbm9yZUtleXNSZWYuY3VycmVudC5pbmNsdWRlcyhldmVudC5rZXkpIHx8XG4gICAgLy8gQ2hhcmFjdGVyIGtleS5cbiAgICBldmVudC5rZXkubGVuZ3RoICE9PSAxIHx8XG4gICAgLy8gTW9kaWZpZXIga2V5LlxuICAgIGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG9wZW4gJiYgZXZlbnQua2V5ICE9PSAnICcpIHtcbiAgICAgIHN0b3BFdmVudChldmVudCk7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQmFpbCBvdXQgaWYgdGhlIGxpc3QgY29udGFpbnMgYSB3b3JkIGxpa2UgXCJsbGFtYVwiIG9yIFwiYWFyb25cIi4gVE9ETzpcbiAgICAvLyBhbGxvdyBpdCBpbiB0aGlzIGNhc2UsIHRvby5cbiAgICBjb25zdCBhbGxvd1JhcGlkU3VjY2Vzc2lvbk9mRmlyc3RMZXR0ZXIgPSBsaXN0Q29udGVudC5ldmVyeSh0ZXh0ID0+IHtcbiAgICAgIHZhciBfdGV4dCQsIF90ZXh0JDI7XG4gICAgICByZXR1cm4gdGV4dCA/ICgoX3RleHQkID0gdGV4dFswXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JC50b0xvY2FsZUxvd2VyQ2FzZSgpKSAhPT0gKChfdGV4dCQyID0gdGV4dFsxXSkgPT0gbnVsbCA/IHZvaWQgMCA6IF90ZXh0JDIudG9Mb2NhbGVMb3dlckNhc2UoKSkgOiB0cnVlO1xuICAgIH0pO1xuXG4gICAgLy8gQWxsb3dzIHRoZSB1c2VyIHRvIGN5Y2xlIHRocm91Z2ggaXRlbXMgdGhhdCBzdGFydCB3aXRoIHRoZSBzYW1lIGxldHRlclxuICAgIC8vIGluIHJhcGlkIHN1Y2Nlc3Npb24uXG4gICAgaWYgKGFsbG93UmFwaWRTdWNjZXNzaW9uT2ZGaXJzdExldHRlciAmJiBzdHJpbmdSZWYuY3VycmVudCA9PT0gZXZlbnQua2V5KSB7XG4gICAgICBzdHJpbmdSZWYuY3VycmVudCA9ICcnO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSBtYXRjaEluZGV4UmVmLmN1cnJlbnQ7XG4gICAgfVxuICAgIHN0cmluZ1JlZi5jdXJyZW50ICs9IGV2ZW50LmtleTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dElkUmVmLmN1cnJlbnQpO1xuICAgIHRpbWVvdXRJZFJlZi5jdXJyZW50ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBzdHJpbmdSZWYuY3VycmVudCA9ICcnO1xuICAgICAgcHJldkluZGV4UmVmLmN1cnJlbnQgPSBtYXRjaEluZGV4UmVmLmN1cnJlbnQ7XG4gICAgICBzZXRUeXBpbmdDaGFuZ2UoZmFsc2UpO1xuICAgIH0sIHJlc2V0TXMpO1xuICAgIGNvbnN0IHByZXZJbmRleCA9IHByZXZJbmRleFJlZi5jdXJyZW50O1xuICAgIGNvbnN0IGluZGV4ID0gZ2V0TWF0Y2hpbmdJbmRleChsaXN0Q29udGVudCwgWy4uLmxpc3RDb250ZW50LnNsaWNlKChwcmV2SW5kZXggfHwgMCkgKyAxKSwgLi4ubGlzdENvbnRlbnQuc2xpY2UoMCwgKHByZXZJbmRleCB8fCAwKSArIDEpXSwgc3RyaW5nUmVmLmN1cnJlbnQpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIG9uTWF0Y2goaW5kZXgpO1xuICAgICAgbWF0Y2hJbmRleFJlZi5jdXJyZW50ID0gaW5kZXg7XG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgIT09ICcgJykge1xuICAgICAgc3RyaW5nUmVmLmN1cnJlbnQgPSAnJztcbiAgICAgIHNldFR5cGluZ0NoYW5nZShmYWxzZSk7XG4gICAgfVxuICB9KTtcbiAgY29uc3QgcmVmZXJlbmNlID0gUmVhY3QudXNlTWVtbygoKSA9PiAoe1xuICAgIG9uS2V5RG93blxuICB9KSwgW29uS2V5RG93bl0pO1xuICBjb25zdCBmbG9hdGluZyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBvbktleURvd24sXG4gICAgICBvbktleVVwKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09ICcgJykge1xuICAgICAgICAgIHNldFR5cGluZ0NoYW5nZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9LCBbb25LZXlEb3duLCBzZXRUeXBpbmdDaGFuZ2VdKTtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oKCkgPT4gZW5hYmxlZCA/IHtcbiAgICByZWZlcmVuY2UsXG4gICAgZmxvYXRpbmdcbiAgfSA6IHt9LCBbZW5hYmxlZCwgcmVmZXJlbmNlLCBmbG9hdGluZ10pO1xufVxuXG5mdW5jdGlvbiBnZXRBcmdzV2l0aEN1c3RvbUZsb2F0aW5nSGVpZ2h0KHN0YXRlLCBoZWlnaHQpIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICByZWN0czoge1xuICAgICAgLi4uc3RhdGUucmVjdHMsXG4gICAgICBmbG9hdGluZzoge1xuICAgICAgICAuLi5zdGF0ZS5yZWN0cy5mbG9hdGluZyxcbiAgICAgICAgaGVpZ2h0XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuLyoqXG4gKiBQb3NpdGlvbnMgdGhlIGZsb2F0aW5nIGVsZW1lbnQgc3VjaCB0aGF0IGFuIGlubmVyIGVsZW1lbnQgaW5zaWRlIG9mIGl0IGlzXG4gKiBhbmNob3JlZCB0byB0aGUgcmVmZXJlbmNlIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvaW5uZXJcbiAqL1xuY29uc3QgaW5uZXIgPSBwcm9wcyA9PiAoe1xuICBuYW1lOiAnaW5uZXInLFxuICBvcHRpb25zOiBwcm9wcyxcbiAgYXN5bmMgZm4oc3RhdGUpIHtcbiAgICBjb25zdCB7XG4gICAgICBsaXN0UmVmLFxuICAgICAgb3ZlcmZsb3dSZWYsXG4gICAgICBvbkZhbGxiYWNrQ2hhbmdlLFxuICAgICAgb2Zmc2V0OiBpbm5lck9mZnNldCA9IDAsXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBtaW5JdGVtc1Zpc2libGUgPSA0LFxuICAgICAgcmVmZXJlbmNlT3ZlcmZsb3dUaHJlc2hvbGQgPSAwLFxuICAgICAgc2Nyb2xsUmVmLFxuICAgICAgLi4uZGV0ZWN0T3ZlcmZsb3dPcHRpb25zXG4gICAgfSA9IGV2YWx1YXRlKHByb3BzLCBzdGF0ZSk7XG4gICAgY29uc3Qge1xuICAgICAgcmVjdHMsXG4gICAgICBlbGVtZW50czoge1xuICAgICAgICBmbG9hdGluZ1xuICAgICAgfVxuICAgIH0gPSBzdGF0ZTtcbiAgICBjb25zdCBpdGVtID0gbGlzdFJlZi5jdXJyZW50W2luZGV4XTtcbiAgICBjb25zdCBzY3JvbGxFbCA9IChzY3JvbGxSZWYgPT0gbnVsbCA/IHZvaWQgMCA6IHNjcm9sbFJlZi5jdXJyZW50KSB8fCBmbG9hdGluZztcblxuICAgIC8vIFZhbGlkIGNvbWJpbmF0aW9uczpcbiAgICAvLyAxLiBGbG9hdGluZyBlbGVtZW50IGlzIHRoZSBzY3JvbGxSZWYgYW5kIGhhcyBhIGJvcmRlciAoZGVmYXVsdClcbiAgICAvLyAyLiBGbG9hdGluZyBlbGVtZW50IGlzIG5vdCB0aGUgc2Nyb2xsUmVmLCBmbG9hdGluZyBlbGVtZW50IGhhcyBhIGJvcmRlclxuICAgIC8vIDMuIEZsb2F0aW5nIGVsZW1lbnQgaXMgbm90IHRoZSBzY3JvbGxSZWYsIHNjcm9sbFJlZiBoYXMgYSBib3JkZXJcbiAgICAvLyBGbG9hdGluZyA+IHsuLi5nZXRGbG9hdGluZ1Byb3BzKCl9IHdyYXBwZXIgPiBzY3JvbGxSZWYgPiBpdGVtcyBpcyBub3RcbiAgICAvLyBhbGxvd2VkIGFzIFZvaWNlT3ZlciBkb2Vzbid0IHdvcmsuXG4gICAgY29uc3QgY2xpZW50VG9wID0gZmxvYXRpbmcuY2xpZW50VG9wIHx8IHNjcm9sbEVsLmNsaWVudFRvcDtcbiAgICBjb25zdCBmbG9hdGluZ0lzQm9yZGVyZWQgPSBmbG9hdGluZy5jbGllbnRUb3AgIT09IDA7XG4gICAgY29uc3Qgc2Nyb2xsRWxJc0JvcmRlcmVkID0gc2Nyb2xsRWwuY2xpZW50VG9wICE9PSAwO1xuICAgIGNvbnN0IGZsb2F0aW5nSXNTY3JvbGxFbCA9IGZsb2F0aW5nID09PSBzY3JvbGxFbDtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICBpZiAoIXN0YXRlLnBsYWNlbWVudC5zdGFydHNXaXRoKCdib3R0b20nKSkge1xuICAgICAgICB3YXJuKCdgcGxhY2VtZW50YCBzaWRlIG11c3QgYmUgXCJib3R0b21cIiB3aGVuIHVzaW5nIHRoZSBgaW5uZXJgJywgJ21pZGRsZXdhcmUuJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghaXRlbSkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBuZXh0QXJncyA9IHtcbiAgICAgIC4uLnN0YXRlLFxuICAgICAgLi4uKGF3YWl0IG9mZnNldCgtaXRlbS5vZmZzZXRUb3AgLSBmbG9hdGluZy5jbGllbnRUb3AgLSByZWN0cy5yZWZlcmVuY2UuaGVpZ2h0IC8gMiAtIGl0ZW0ub2Zmc2V0SGVpZ2h0IC8gMiAtIGlubmVyT2Zmc2V0KS5mbihzdGF0ZSkpXG4gICAgfTtcbiAgICBjb25zdCBvdmVyZmxvdyA9IGF3YWl0IGRldGVjdE92ZXJmbG93KGdldEFyZ3NXaXRoQ3VzdG9tRmxvYXRpbmdIZWlnaHQobmV4dEFyZ3MsIHNjcm9sbEVsLnNjcm9sbEhlaWdodCArIGNsaWVudFRvcCArIGZsb2F0aW5nLmNsaWVudFRvcCksIGRldGVjdE92ZXJmbG93T3B0aW9ucyk7XG4gICAgY29uc3QgcmVmT3ZlcmZsb3cgPSBhd2FpdCBkZXRlY3RPdmVyZmxvdyhuZXh0QXJncywge1xuICAgICAgLi4uZGV0ZWN0T3ZlcmZsb3dPcHRpb25zLFxuICAgICAgZWxlbWVudENvbnRleHQ6ICdyZWZlcmVuY2UnXG4gICAgfSk7XG4gICAgY29uc3QgZGlmZlkgPSBNYXRoLm1heCgwLCBvdmVyZmxvdy50b3ApO1xuICAgIGNvbnN0IG5leHRZID0gbmV4dEFyZ3MueSArIGRpZmZZO1xuICAgIGNvbnN0IG1heEhlaWdodCA9IE1hdGgubWF4KDAsIHNjcm9sbEVsLnNjcm9sbEhlaWdodCArIChmbG9hdGluZ0lzQm9yZGVyZWQgJiYgZmxvYXRpbmdJc1Njcm9sbEVsIHx8IHNjcm9sbEVsSXNCb3JkZXJlZCA/IGNsaWVudFRvcCAqIDIgOiAwKSAtIGRpZmZZIC0gTWF0aC5tYXgoMCwgb3ZlcmZsb3cuYm90dG9tKSk7XG4gICAgc2Nyb2xsRWwuc3R5bGUubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0ICsgXCJweFwiO1xuICAgIHNjcm9sbEVsLnNjcm9sbFRvcCA9IGRpZmZZO1xuXG4gICAgLy8gVGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSwgZmFsbGJhY2sgdG8gc3RhbmRhcmQgYW5jaG9yZWQgcG9zaXRpb25pbmdcbiAgICBpZiAob25GYWxsYmFja0NoYW5nZSkge1xuICAgICAgaWYgKHNjcm9sbEVsLm9mZnNldEhlaWdodCA8IGl0ZW0ub2Zmc2V0SGVpZ2h0ICogTWF0aC5taW4obWluSXRlbXNWaXNpYmxlLCBsaXN0UmVmLmN1cnJlbnQubGVuZ3RoIC0gMSkgLSAxIHx8IHJlZk92ZXJmbG93LnRvcCA+PSAtcmVmZXJlbmNlT3ZlcmZsb3dUaHJlc2hvbGQgfHwgcmVmT3ZlcmZsb3cuYm90dG9tID49IC1yZWZlcmVuY2VPdmVyZmxvd1RocmVzaG9sZCkge1xuICAgICAgICBSZWFjdERPTS5mbHVzaFN5bmMoKCkgPT4gb25GYWxsYmFja0NoYW5nZSh0cnVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBSZWFjdERPTS5mbHVzaFN5bmMoKCkgPT4gb25GYWxsYmFja0NoYW5nZShmYWxzZSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAob3ZlcmZsb3dSZWYpIHtcbiAgICAgIG92ZXJmbG93UmVmLmN1cnJlbnQgPSBhd2FpdCBkZXRlY3RPdmVyZmxvdyhnZXRBcmdzV2l0aEN1c3RvbUZsb2F0aW5nSGVpZ2h0KHtcbiAgICAgICAgLi4ubmV4dEFyZ3MsXG4gICAgICAgIHk6IG5leHRZXG4gICAgICB9LCBzY3JvbGxFbC5vZmZzZXRIZWlnaHQgKyBjbGllbnRUb3AgKyBmbG9hdGluZy5jbGllbnRUb3ApLCBkZXRlY3RPdmVyZmxvd09wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgeTogbmV4dFlcbiAgICB9O1xuICB9XG59KTtcbi8qKlxuICogQ2hhbmdlcyB0aGUgYGlubmVyYCBtaWRkbGV3YXJlJ3MgYG9mZnNldGAgdXBvbiBhIGB3aGVlbGAgZXZlbnQgdG9cbiAqIGV4cGFuZCB0aGUgZmxvYXRpbmcgZWxlbWVudCdzIGhlaWdodCwgcmV2ZWFsaW5nIG1vcmUgbGlzdCBpdGVtcy5cbiAqIEBzZWUgaHR0cHM6Ly9mbG9hdGluZy11aS5jb20vZG9jcy9pbm5lclxuICovXG5mdW5jdGlvbiB1c2VJbm5lck9mZnNldChjb250ZXh0LCBwcm9wcykge1xuICBjb25zdCB7XG4gICAgb3BlbixcbiAgICBlbGVtZW50c1xuICB9ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGVuYWJsZWQgPSB0cnVlLFxuICAgIG92ZXJmbG93UmVmLFxuICAgIHNjcm9sbFJlZixcbiAgICBvbkNoYW5nZTogdW5zdGFibGVfb25DaGFuZ2VcbiAgfSA9IHByb3BzO1xuICBjb25zdCBvbkNoYW5nZSA9IHVzZUVmZmVjdEV2ZW50KHVuc3RhYmxlX29uQ2hhbmdlKTtcbiAgY29uc3QgY29udHJvbGxlZFNjcm9sbGluZ1JlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IHByZXZTY3JvbGxUb3BSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGNvbnN0IGluaXRpYWxPdmVyZmxvd1JlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgICBmdW5jdGlvbiBvbldoZWVsKGUpIHtcbiAgICAgIGlmIChlLmN0cmxLZXkgfHwgIWVsIHx8IG92ZXJmbG93UmVmLmN1cnJlbnQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBkWSA9IGUuZGVsdGFZO1xuICAgICAgY29uc3QgaXNBdFRvcCA9IG92ZXJmbG93UmVmLmN1cnJlbnQudG9wID49IC0wLjU7XG4gICAgICBjb25zdCBpc0F0Qm90dG9tID0gb3ZlcmZsb3dSZWYuY3VycmVudC5ib3R0b20gPj0gLTAuNTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1Njcm9sbCA9IGVsLnNjcm9sbEhlaWdodCAtIGVsLmNsaWVudEhlaWdodDtcbiAgICAgIGNvbnN0IHNpZ24gPSBkWSA8IDAgPyAtMSA6IDE7XG4gICAgICBjb25zdCBtZXRob2QgPSBkWSA8IDAgPyAnbWF4JyA6ICdtaW4nO1xuICAgICAgaWYgKGVsLnNjcm9sbEhlaWdodCA8PSBlbC5jbGllbnRIZWlnaHQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0F0VG9wICYmIGRZID4gMCB8fCAhaXNBdEJvdHRvbSAmJiBkWSA8IDApIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBSZWFjdERPTS5mbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgIG9uQ2hhbmdlKGQgPT4gZCArIE1hdGhbbWV0aG9kXShkWSwgcmVtYWluaW5nU2Nyb2xsICogc2lnbikpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoL2ZpcmVmb3gvaS50ZXN0KGdldFVzZXJBZ2VudCgpKSkge1xuICAgICAgICAvLyBOZWVkZWQgdG8gcHJvcGFnYXRlIHNjcm9sbGluZyBkdXJpbmcgbW9tZW50dW0gc2Nyb2xsaW5nIHBoYXNlIG9uY2VcbiAgICAgICAgLy8gaXQgZ2V0cyBsaW1pdGVkIGJ5IHRoZSBib3VuZGFyeS4gVVggaW1wcm92ZW1lbnQsIG5vdCBjcml0aWNhbC5cbiAgICAgICAgZWwuc2Nyb2xsVG9wICs9IGRZO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBlbCA9IChzY3JvbGxSZWYgPT0gbnVsbCA/IHZvaWQgMCA6IHNjcm9sbFJlZi5jdXJyZW50KSB8fCBlbGVtZW50cy5mbG9hdGluZztcbiAgICBpZiAob3BlbiAmJiBlbCkge1xuICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBvbldoZWVsKTtcblxuICAgICAgLy8gV2FpdCBmb3IgdGhlIHBvc2l0aW9uIHRvIGJlIHJlYWR5LlxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgcHJldlNjcm9sbFRvcFJlZi5jdXJyZW50ID0gZWwuc2Nyb2xsVG9wO1xuICAgICAgICBpZiAob3ZlcmZsb3dSZWYuY3VycmVudCAhPSBudWxsKSB7XG4gICAgICAgICAgaW5pdGlhbE92ZXJmbG93UmVmLmN1cnJlbnQgPSB7XG4gICAgICAgICAgICAuLi5vdmVyZmxvd1JlZi5jdXJyZW50XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICBpbml0aWFsT3ZlcmZsb3dSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3doZWVsJywgb25XaGVlbCk7XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW2VuYWJsZWQsIG9wZW4sIGVsZW1lbnRzLmZsb2F0aW5nLCBvdmVyZmxvd1JlZiwgc2Nyb2xsUmVmLCBvbkNoYW5nZV0pO1xuICBjb25zdCBmbG9hdGluZyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4gKHtcbiAgICBvbktleURvd24oKSB7XG4gICAgICBjb250cm9sbGVkU2Nyb2xsaW5nUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH0sXG4gICAgb25XaGVlbCgpIHtcbiAgICAgIGNvbnRyb2xsZWRTY3JvbGxpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIH0sXG4gICAgb25Qb2ludGVyTW92ZSgpIHtcbiAgICAgIGNvbnRyb2xsZWRTY3JvbGxpbmdSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIH0sXG4gICAgb25TY3JvbGwoKSB7XG4gICAgICBjb25zdCBlbCA9IChzY3JvbGxSZWYgPT0gbnVsbCA/IHZvaWQgMCA6IHNjcm9sbFJlZi5jdXJyZW50KSB8fCBlbGVtZW50cy5mbG9hdGluZztcbiAgICAgIGlmICghb3ZlcmZsb3dSZWYuY3VycmVudCB8fCAhZWwgfHwgIWNvbnRyb2xsZWRTY3JvbGxpbmdSZWYuY3VycmVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAocHJldlNjcm9sbFRvcFJlZi5jdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHNjcm9sbERpZmYgPSBlbC5zY3JvbGxUb3AgLSBwcmV2U2Nyb2xsVG9wUmVmLmN1cnJlbnQ7XG4gICAgICAgIGlmIChvdmVyZmxvd1JlZi5jdXJyZW50LmJvdHRvbSA8IC0wLjUgJiYgc2Nyb2xsRGlmZiA8IC0xIHx8IG92ZXJmbG93UmVmLmN1cnJlbnQudG9wIDwgLTAuNSAmJiBzY3JvbGxEaWZmID4gMSkge1xuICAgICAgICAgIFJlYWN0RE9NLmZsdXNoU3luYygoKSA9PiBvbkNoYW5nZShkID0+IGQgKyBzY3JvbGxEaWZmKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gW0ZpcmVmb3hdIFdhaXQgZm9yIHRoZSBoZWlnaHQgY2hhbmdlIHRvIGhhdmUgYmVlbiBhcHBsaWVkLlxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgcHJldlNjcm9sbFRvcFJlZi5jdXJyZW50ID0gZWwuc2Nyb2xsVG9wO1xuICAgICAgfSk7XG4gICAgfVxuICB9KSwgW2VsZW1lbnRzLmZsb2F0aW5nLCBvbkNoYW5nZSwgb3ZlcmZsb3dSZWYsIHNjcm9sbFJlZl0pO1xuICByZXR1cm4gUmVhY3QudXNlTWVtbygoKSA9PiBlbmFibGVkID8ge1xuICAgIGZsb2F0aW5nXG4gIH0gOiB7fSwgW2VuYWJsZWQsIGZsb2F0aW5nXSk7XG59XG5cbmZ1bmN0aW9uIGlzUG9pbnRJblBvbHlnb24ocG9pbnQsIHBvbHlnb24pIHtcbiAgY29uc3QgW3gsIHldID0gcG9pbnQ7XG4gIGxldCBpc0luc2lkZSA9IGZhbHNlO1xuICBjb25zdCBsZW5ndGggPSBwb2x5Z29uLmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDAsIGogPSBsZW5ndGggLSAxOyBpIDwgbGVuZ3RoOyBqID0gaSsrKSB7XG4gICAgY29uc3QgW3hpLCB5aV0gPSBwb2x5Z29uW2ldIHx8IFswLCAwXTtcbiAgICBjb25zdCBbeGosIHlqXSA9IHBvbHlnb25bal0gfHwgWzAsIDBdO1xuICAgIGNvbnN0IGludGVyc2VjdCA9IHlpID49IHkgIT09IHlqID49IHkgJiYgeCA8PSAoeGogLSB4aSkgKiAoeSAtIHlpKSAvICh5aiAtIHlpKSArIHhpO1xuICAgIGlmIChpbnRlcnNlY3QpIHtcbiAgICAgIGlzSW5zaWRlID0gIWlzSW5zaWRlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaXNJbnNpZGU7XG59XG5mdW5jdGlvbiBpc0luc2lkZShwb2ludCwgcmVjdCkge1xuICByZXR1cm4gcG9pbnRbMF0gPj0gcmVjdC54ICYmIHBvaW50WzBdIDw9IHJlY3QueCArIHJlY3Qud2lkdGggJiYgcG9pbnRbMV0gPj0gcmVjdC55ICYmIHBvaW50WzFdIDw9IHJlY3QueSArIHJlY3QuaGVpZ2h0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBzYWZlIHBvbHlnb24gYXJlYSB0aGF0IHRoZSB1c2VyIGNhbiB0cmF2ZXJzZSB3aXRob3V0IGNsb3NpbmcgdGhlXG4gKiBmbG9hdGluZyBlbGVtZW50IG9uY2UgbGVhdmluZyB0aGUgcmVmZXJlbmNlIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdXNlSG92ZXIjc2FmZXBvbHlnb25cbiAqL1xuZnVuY3Rpb24gc2FmZVBvbHlnb24ob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGNvbnN0IHtcbiAgICBidWZmZXIgPSAwLjUsXG4gICAgYmxvY2tQb2ludGVyRXZlbnRzID0gZmFsc2UsXG4gICAgcmVxdWlyZUludGVudCA9IHRydWVcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCB0aW1lb3V0SWQ7XG4gIGxldCBoYXNMYW5kZWQgPSBmYWxzZTtcbiAgbGV0IGxhc3RYID0gbnVsbDtcbiAgbGV0IGxhc3RZID0gbnVsbDtcbiAgbGV0IGxhc3RDdXJzb3JUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gIGZ1bmN0aW9uIGdldEN1cnNvclNwZWVkKHgsIHkpIHtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGNvbnN0IGVsYXBzZWRUaW1lID0gY3VycmVudFRpbWUgLSBsYXN0Q3Vyc29yVGltZTtcbiAgICBpZiAobGFzdFggPT09IG51bGwgfHwgbGFzdFkgPT09IG51bGwgfHwgZWxhcHNlZFRpbWUgPT09IDApIHtcbiAgICAgIGxhc3RYID0geDtcbiAgICAgIGxhc3RZID0geTtcbiAgICAgIGxhc3RDdXJzb3JUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgZGVsdGFYID0geCAtIGxhc3RYO1xuICAgIGNvbnN0IGRlbHRhWSA9IHkgLSBsYXN0WTtcbiAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGguc3FydChkZWx0YVggKiBkZWx0YVggKyBkZWx0YVkgKiBkZWx0YVkpO1xuICAgIGNvbnN0IHNwZWVkID0gZGlzdGFuY2UgLyBlbGFwc2VkVGltZTsgLy8gcHggLyBtc1xuXG4gICAgbGFzdFggPSB4O1xuICAgIGxhc3RZID0geTtcbiAgICBsYXN0Q3Vyc29yVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIHJldHVybiBzcGVlZDtcbiAgfVxuICBjb25zdCBmbiA9IF9yZWYgPT4ge1xuICAgIGxldCB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHBsYWNlbWVudCxcbiAgICAgIGVsZW1lbnRzLFxuICAgICAgb25DbG9zZSxcbiAgICAgIG5vZGVJZCxcbiAgICAgIHRyZWVcbiAgICB9ID0gX3JlZjtcbiAgICByZXR1cm4gZnVuY3Rpb24gb25Nb3VzZU1vdmUoZXZlbnQpIHtcbiAgICAgIGZ1bmN0aW9uIGNsb3NlKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgb25DbG9zZSgpO1xuICAgICAgfVxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICBpZiAoIWVsZW1lbnRzLmRvbVJlZmVyZW5jZSB8fCAhZWxlbWVudHMuZmxvYXRpbmcgfHwgcGxhY2VtZW50ID09IG51bGwgfHwgeCA9PSBudWxsIHx8IHkgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB7XG4gICAgICAgIGNsaWVudFgsXG4gICAgICAgIGNsaWVudFlcbiAgICAgIH0gPSBldmVudDtcbiAgICAgIGNvbnN0IGNsaWVudFBvaW50ID0gW2NsaWVudFgsIGNsaWVudFldO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0VGFyZ2V0KGV2ZW50KTtcbiAgICAgIGNvbnN0IGlzTGVhdmUgPSBldmVudC50eXBlID09PSAnbW91c2VsZWF2ZSc7XG4gICAgICBjb25zdCBpc092ZXJGbG9hdGluZ0VsID0gY29udGFpbnMoZWxlbWVudHMuZmxvYXRpbmcsIHRhcmdldCk7XG4gICAgICBjb25zdCBpc092ZXJSZWZlcmVuY2VFbCA9IGNvbnRhaW5zKGVsZW1lbnRzLmRvbVJlZmVyZW5jZSwgdGFyZ2V0KTtcbiAgICAgIGNvbnN0IHJlZlJlY3QgPSBlbGVtZW50cy5kb21SZWZlcmVuY2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCByZWN0ID0gZWxlbWVudHMuZmxvYXRpbmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBzaWRlID0gcGxhY2VtZW50LnNwbGl0KCctJylbMF07XG4gICAgICBjb25zdCBjdXJzb3JMZWF2ZUZyb21SaWdodCA9IHggPiByZWN0LnJpZ2h0IC0gcmVjdC53aWR0aCAvIDI7XG4gICAgICBjb25zdCBjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPSB5ID4gcmVjdC5ib3R0b20gLSByZWN0LmhlaWdodCAvIDI7XG4gICAgICBjb25zdCBpc092ZXJSZWZlcmVuY2VSZWN0ID0gaXNJbnNpZGUoY2xpZW50UG9pbnQsIHJlZlJlY3QpO1xuICAgICAgY29uc3QgaXNGbG9hdGluZ1dpZGVyID0gcmVjdC53aWR0aCA+IHJlZlJlY3Qud2lkdGg7XG4gICAgICBjb25zdCBpc0Zsb2F0aW5nVGFsbGVyID0gcmVjdC5oZWlnaHQgPiByZWZSZWN0LmhlaWdodDtcbiAgICAgIGNvbnN0IGxlZnQgPSAoaXNGbG9hdGluZ1dpZGVyID8gcmVmUmVjdCA6IHJlY3QpLmxlZnQ7XG4gICAgICBjb25zdCByaWdodCA9IChpc0Zsb2F0aW5nV2lkZXIgPyByZWZSZWN0IDogcmVjdCkucmlnaHQ7XG4gICAgICBjb25zdCB0b3AgPSAoaXNGbG9hdGluZ1RhbGxlciA/IHJlZlJlY3QgOiByZWN0KS50b3A7XG4gICAgICBjb25zdCBib3R0b20gPSAoaXNGbG9hdGluZ1RhbGxlciA/IHJlZlJlY3QgOiByZWN0KS5ib3R0b207XG4gICAgICBpZiAoaXNPdmVyRmxvYXRpbmdFbCkge1xuICAgICAgICBoYXNMYW5kZWQgPSB0cnVlO1xuICAgICAgICBpZiAoIWlzTGVhdmUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc092ZXJSZWZlcmVuY2VFbCkge1xuICAgICAgICBoYXNMYW5kZWQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc092ZXJSZWZlcmVuY2VFbCAmJiAhaXNMZWF2ZSkge1xuICAgICAgICBoYXNMYW5kZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFByZXZlbnQgb3ZlcmxhcHBpbmcgZmxvYXRpbmcgZWxlbWVudCBmcm9tIGJlaW5nIHN0dWNrIGluIGFuIG9wZW4tY2xvc2VcbiAgICAgIC8vIGxvb3A6IGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMTkxMFxuICAgICAgaWYgKGlzTGVhdmUgJiYgaXNFbGVtZW50KGV2ZW50LnJlbGF0ZWRUYXJnZXQpICYmIGNvbnRhaW5zKGVsZW1lbnRzLmZsb2F0aW5nLCBldmVudC5yZWxhdGVkVGFyZ2V0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIElmIGFueSBuZXN0ZWQgY2hpbGQgaXMgb3BlbiwgYWJvcnQuXG4gICAgICBpZiAodHJlZSAmJiBnZXRDaGlsZHJlbih0cmVlLm5vZGVzUmVmLmN1cnJlbnQsIG5vZGVJZCkuc29tZShfcmVmMiA9PiB7XG4gICAgICAgIGxldCB7XG4gICAgICAgICAgY29udGV4dFxuICAgICAgICB9ID0gX3JlZjI7XG4gICAgICAgIHJldHVybiBjb250ZXh0ID09IG51bGwgPyB2b2lkIDAgOiBjb250ZXh0Lm9wZW47XG4gICAgICB9KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoZSBwb2ludGVyIGlzIGxlYXZpbmcgZnJvbSB0aGUgb3Bwb3NpdGUgc2lkZSwgdGhlIFwiYnVmZmVyXCIgbG9naWNcbiAgICAgIC8vIGNyZWF0ZXMgYSBwb2ludCB3aGVyZSB0aGUgZmxvYXRpbmcgZWxlbWVudCByZW1haW5zIG9wZW4sIGJ1dCBzaG91bGQgYmVcbiAgICAgIC8vIGlnbm9yZWQuXG4gICAgICAvLyBBIGNvbnN0YW50IG9mIDEgaGFuZGxlcyBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMuXG4gICAgICBpZiAoc2lkZSA9PT0gJ3RvcCcgJiYgeSA+PSByZWZSZWN0LmJvdHRvbSAtIDEgfHwgc2lkZSA9PT0gJ2JvdHRvbScgJiYgeSA8PSByZWZSZWN0LnRvcCArIDEgfHwgc2lkZSA9PT0gJ2xlZnQnICYmIHggPj0gcmVmUmVjdC5yaWdodCAtIDEgfHwgc2lkZSA9PT0gJ3JpZ2h0JyAmJiB4IDw9IHJlZlJlY3QubGVmdCArIDEpIHtcbiAgICAgICAgcmV0dXJuIGNsb3NlKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIElnbm9yZSB3aGVuIHRoZSBjdXJzb3IgaXMgd2l0aGluIHRoZSByZWN0YW5ndWxhciB0cm91Z2ggYmV0d2VlbiB0aGVcbiAgICAgIC8vIHR3byBlbGVtZW50cy4gU2luY2UgdGhlIHRyaWFuZ2xlIGlzIGNyZWF0ZWQgZnJvbSB0aGUgY3Vyc29yIHBvaW50LFxuICAgICAgLy8gd2hpY2ggY2FuIHN0YXJ0IGJleW9uZCB0aGUgcmVmIGVsZW1lbnQncyBlZGdlLCB0cmF2ZXJzaW5nIGJhY2sgYW5kXG4gICAgICAvLyBmb3J0aCBmcm9tIHRoZSByZWYgdG8gdGhlIGZsb2F0aW5nIGVsZW1lbnQgY2FuIGNhdXNlIGl0IHRvIGNsb3NlLiBUaGlzXG4gICAgICAvLyBlbnN1cmVzIGl0IGFsd2F5cyByZW1haW5zIG9wZW4gaW4gdGhhdCBjYXNlLlxuICAgICAgbGV0IHJlY3RQb2x5ID0gW107XG4gICAgICBzd2l0Y2ggKHNpZGUpIHtcbiAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICByZWN0UG9seSA9IFtbbGVmdCwgcmVmUmVjdC50b3AgKyAxXSwgW2xlZnQsIHJlY3QuYm90dG9tIC0gMV0sIFtyaWdodCwgcmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWZSZWN0LnRvcCArIDFdXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICByZWN0UG9seSA9IFtbbGVmdCwgcmVjdC50b3AgKyAxXSwgW2xlZnQsIHJlZlJlY3QuYm90dG9tIC0gMV0sIFtyaWdodCwgcmVmUmVjdC5ib3R0b20gLSAxXSwgW3JpZ2h0LCByZWN0LnRvcCArIDFdXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgcmVjdFBvbHkgPSBbW3JlY3QucmlnaHQgLSAxLCBib3R0b21dLCBbcmVjdC5yaWdodCAtIDEsIHRvcF0sIFtyZWZSZWN0LmxlZnQgKyAxLCB0b3BdLCBbcmVmUmVjdC5sZWZ0ICsgMSwgYm90dG9tXV07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICByZWN0UG9seSA9IFtbcmVmUmVjdC5yaWdodCAtIDEsIGJvdHRvbV0sIFtyZWZSZWN0LnJpZ2h0IC0gMSwgdG9wXSwgW3JlY3QubGVmdCArIDEsIHRvcF0sIFtyZWN0LmxlZnQgKyAxLCBib3R0b21dXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGdldFBvbHlnb24oX3JlZjMpIHtcbiAgICAgICAgbGV0IFt4LCB5XSA9IF9yZWYzO1xuICAgICAgICBzd2l0Y2ggKHNpZGUpIHtcbiAgICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludE9uZSA9IFtpc0Zsb2F0aW5nV2lkZXIgPyB4ICsgYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8geCArIGJ1ZmZlciAqIDQgOiB4IC0gYnVmZmVyICogNCwgeSArIGJ1ZmZlciArIDFdO1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludFR3byA9IFtpc0Zsb2F0aW5nV2lkZXIgPyB4IC0gYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8geCArIGJ1ZmZlciAqIDQgOiB4IC0gYnVmZmVyICogNCwgeSArIGJ1ZmZlciArIDFdO1xuICAgICAgICAgICAgICBjb25zdCBjb21tb25Qb2ludHMgPSBbW3JlY3QubGVmdCwgY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyByZWN0LmJvdHRvbSAtIGJ1ZmZlciA6IGlzRmxvYXRpbmdXaWRlciA/IHJlY3QuYm90dG9tIC0gYnVmZmVyIDogcmVjdC50b3BdLCBbcmVjdC5yaWdodCwgY3Vyc29yTGVhdmVGcm9tUmlnaHQgPyBpc0Zsb2F0aW5nV2lkZXIgPyByZWN0LmJvdHRvbSAtIGJ1ZmZlciA6IHJlY3QudG9wIDogcmVjdC5ib3R0b20gLSBidWZmZXJdXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFtjdXJzb3JQb2ludE9uZSwgY3Vyc29yUG9pbnRUd28sIC4uLmNvbW1vblBvaW50c107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29uc3QgY3Vyc29yUG9pbnRPbmUgPSBbaXNGbG9hdGluZ1dpZGVyID8geCArIGJ1ZmZlciAvIDIgOiBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IHggKyBidWZmZXIgKiA0IDogeCAtIGJ1ZmZlciAqIDQsIHkgLSBidWZmZXJdO1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludFR3byA9IFtpc0Zsb2F0aW5nV2lkZXIgPyB4IC0gYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbVJpZ2h0ID8geCArIGJ1ZmZlciAqIDQgOiB4IC0gYnVmZmVyICogNCwgeSAtIGJ1ZmZlcl07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbcmVjdC5sZWZ0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IHJlY3QudG9wICsgYnVmZmVyIDogaXNGbG9hdGluZ1dpZGVyID8gcmVjdC50b3AgKyBidWZmZXIgOiByZWN0LmJvdHRvbV0sIFtyZWN0LnJpZ2h0LCBjdXJzb3JMZWF2ZUZyb21SaWdodCA/IGlzRmxvYXRpbmdXaWRlciA/IHJlY3QudG9wICsgYnVmZmVyIDogcmVjdC5ib3R0b20gOiByZWN0LnRvcCArIGJ1ZmZlcl1dO1xuICAgICAgICAgICAgICByZXR1cm4gW2N1cnNvclBvaW50T25lLCBjdXJzb3JQb2ludFR3bywgLi4uY29tbW9uUG9pbnRzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29uc3QgY3Vyc29yUG9pbnRPbmUgPSBbeCArIGJ1ZmZlciArIDEsIGlzRmxvYXRpbmdUYWxsZXIgPyB5ICsgYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbUJvdHRvbSA/IHkgKyBidWZmZXIgKiA0IDogeSAtIGJ1ZmZlciAqIDRdO1xuICAgICAgICAgICAgICBjb25zdCBjdXJzb3JQb2ludFR3byA9IFt4ICsgYnVmZmVyICsgMSwgaXNGbG9hdGluZ1RhbGxlciA/IHkgLSBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGNvbW1vblBvaW50cyA9IFtbY3Vyc29yTGVhdmVGcm9tQm90dG9tID8gcmVjdC5yaWdodCAtIGJ1ZmZlciA6IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LnJpZ2h0IC0gYnVmZmVyIDogcmVjdC5sZWZ0LCByZWN0LnRvcF0sIFtjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyBpc0Zsb2F0aW5nVGFsbGVyID8gcmVjdC5yaWdodCAtIGJ1ZmZlciA6IHJlY3QubGVmdCA6IHJlY3QucmlnaHQgLSBidWZmZXIsIHJlY3QuYm90dG9tXV07XG4gICAgICAgICAgICAgIHJldHVybiBbLi4uY29tbW9uUG9pbnRzLCBjdXJzb3JQb2ludE9uZSwgY3Vyc29yUG9pbnRUd29dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29uc3QgY3Vyc29yUG9pbnRPbmUgPSBbeCAtIGJ1ZmZlciwgaXNGbG9hdGluZ1RhbGxlciA/IHkgKyBidWZmZXIgLyAyIDogY3Vyc29yTGVhdmVGcm9tQm90dG9tID8geSArIGJ1ZmZlciAqIDQgOiB5IC0gYnVmZmVyICogNF07XG4gICAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvaW50VHdvID0gW3ggLSBidWZmZXIsIGlzRmxvYXRpbmdUYWxsZXIgPyB5IC0gYnVmZmVyIC8gMiA6IGN1cnNvckxlYXZlRnJvbUJvdHRvbSA/IHkgKyBidWZmZXIgKiA0IDogeSAtIGJ1ZmZlciAqIDRdO1xuICAgICAgICAgICAgICBjb25zdCBjb21tb25Qb2ludHMgPSBbW2N1cnNvckxlYXZlRnJvbUJvdHRvbSA/IHJlY3QubGVmdCArIGJ1ZmZlciA6IGlzRmxvYXRpbmdUYWxsZXIgPyByZWN0LmxlZnQgKyBidWZmZXIgOiByZWN0LnJpZ2h0LCByZWN0LnRvcF0sIFtjdXJzb3JMZWF2ZUZyb21Cb3R0b20gPyBpc0Zsb2F0aW5nVGFsbGVyID8gcmVjdC5sZWZ0ICsgYnVmZmVyIDogcmVjdC5yaWdodCA6IHJlY3QubGVmdCArIGJ1ZmZlciwgcmVjdC5ib3R0b21dXTtcbiAgICAgICAgICAgICAgcmV0dXJuIFtjdXJzb3JQb2ludE9uZSwgY3Vyc29yUG9pbnRUd28sIC4uLmNvbW1vblBvaW50c107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc1BvaW50SW5Qb2x5Z29uKFtjbGllbnRYLCBjbGllbnRZXSwgcmVjdFBvbHkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChoYXNMYW5kZWQgJiYgIWlzT3ZlclJlZmVyZW5jZVJlY3QpIHtcbiAgICAgICAgcmV0dXJuIGNsb3NlKCk7XG4gICAgICB9XG4gICAgICBpZiAoIWlzTGVhdmUgJiYgcmVxdWlyZUludGVudCkge1xuICAgICAgICBjb25zdCBjdXJzb3JTcGVlZCA9IGdldEN1cnNvclNwZWVkKGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuICAgICAgICBjb25zdCBjdXJzb3JTcGVlZFRocmVzaG9sZCA9IDAuMTtcbiAgICAgICAgaWYgKGN1cnNvclNwZWVkICE9PSBudWxsICYmIGN1cnNvclNwZWVkIDwgY3Vyc29yU3BlZWRUaHJlc2hvbGQpIHtcbiAgICAgICAgICByZXR1cm4gY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFpc1BvaW50SW5Qb2x5Z29uKFtjbGllbnRYLCBjbGllbnRZXSwgZ2V0UG9seWdvbihbeCwgeV0pKSkge1xuICAgICAgICBjbG9zZSgpO1xuICAgICAgfSBlbHNlIGlmICghaGFzTGFuZGVkICYmIHJlcXVpcmVJbnRlbnQpIHtcbiAgICAgICAgdGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoY2xvc2UsIDQwKTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuICBmbi5fX29wdGlvbnMgPSB7XG4gICAgYmxvY2tQb2ludGVyRXZlbnRzXG4gIH07XG4gIHJldHVybiBmbjtcbn1cblxuZXhwb3J0IHsgQ29tcG9zaXRlLCBDb21wb3NpdGVJdGVtLCBGbG9hdGluZ0Fycm93LCBGbG9hdGluZ0RlbGF5R3JvdXAsIEZsb2F0aW5nRm9jdXNNYW5hZ2VyLCBGbG9hdGluZ0xpc3QsIEZsb2F0aW5nTm9kZSwgRmxvYXRpbmdPdmVybGF5LCBGbG9hdGluZ1BvcnRhbCwgRmxvYXRpbmdUcmVlLCBpbm5lciwgc2FmZVBvbHlnb24sIHVzZUNsaWNrLCB1c2VDbGllbnRQb2ludCwgdXNlRGVsYXlHcm91cCwgdXNlRGVsYXlHcm91cENvbnRleHQsIHVzZURpc21pc3MsIHVzZUZsb2F0aW5nLCB1c2VGbG9hdGluZ05vZGVJZCwgdXNlRmxvYXRpbmdQYXJlbnROb2RlSWQsIHVzZUZsb2F0aW5nUG9ydGFsTm9kZSwgdXNlRmxvYXRpbmdSb290Q29udGV4dCwgdXNlRmxvYXRpbmdUcmVlLCB1c2VGb2N1cywgdXNlSG92ZXIsIHVzZUlkLCB1c2VJbm5lck9mZnNldCwgdXNlSW50ZXJhY3Rpb25zLCB1c2VMaXN0SXRlbSwgdXNlTGlzdE5hdmlnYXRpb24sIHVzZU1lcmdlUmVmcywgdXNlUm9sZSwgdXNlVHJhbnNpdGlvblN0YXR1cywgdXNlVHJhbnNpdGlvblN0eWxlcywgdXNlVHlwZWFoZWFkIH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@floating-ui/react/dist/floating-ui.react.mjs\n");
/***/ }),
/***/ "(ssr)/./node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs":
/*!**************************************************************************!*\
!*** ./node_modules/@floating-ui/react/dist/floating-ui.react.utils.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 */ TYPEABLE_SELECTOR: () => (/* binding */ TYPEABLE_SELECTOR),\n/* harmony export */ activeElement: () => (/* binding */ activeElement),\n/* harmony export */ contains: () => (/* binding */ contains),\n/* harmony export */ getDocument: () => (/* binding */ getDocument),\n/* harmony export */ getPlatform: () => (/* binding */ getPlatform),\n/* harmony export */ getTarget: () => (/* binding */ getTarget),\n/* harmony export */ getUserAgent: () => (/* binding */ getUserAgent),\n/* harmony export */ isAndroid: () => (/* binding */ isAndroid),\n/* harmony export */ isEventTargetWithin: () => (/* binding */ isEventTargetWithin),\n/* harmony export */ isJSDOM: () => (/* binding */ isJSDOM),\n/* harmony export */ isMac: () => (/* binding */ isMac),\n/* harmony export */ isMouseLikePointerType: () => (/* binding */ isMouseLikePointerType),\n/* harmony export */ isReactEvent: () => (/* binding */ isReactEvent),\n/* harmony export */ isRootElement: () => (/* binding */ isRootElement),\n/* harmony export */ isSafari: () => (/* binding */ isSafari),\n/* harmony export */ isTypeableCombobox: () => (/* binding */ isTypeableCombobox),\n/* harmony export */ isTypeableElement: () => (/* binding */ isTypeableElement),\n/* harmony export */ isVirtualClick: () => (/* binding */ isVirtualClick),\n/* harmony export */ isVirtualPointerEvent: () => (/* binding */ isVirtualPointerEvent),\n/* harmony export */ stopEvent: () => (/* binding */ stopEvent)\n/* harmony export */ });\n/* harmony import */ var _floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @floating-ui/utils/dom */ \"(ssr)/./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs\");\n\n\nfunction activeElement(doc) {\n let activeElement = doc.activeElement;\n while (((_activeElement = activeElement) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {\n var _activeElement;\n activeElement = activeElement.shadowRoot.activeElement;\n }\n return activeElement;\n}\nfunction contains(parent, child) {\n if (!parent || !child) {\n return false;\n }\n const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();\n\n // First, attempt with faster native method\n if (parent.contains(child)) {\n return true;\n }\n\n // then fallback to custom implementation with Shadow DOM support\n if (rootNode && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(rootNode)) {\n let next = child;\n while (next) {\n if (parent === next) {\n return true;\n }\n // @ts-ignore\n next = next.parentNode || next.host;\n }\n }\n\n // Give up, the result is false\n return false;\n}\n// Avoid Chrome DevTools blue warning.\nfunction getPlatform() {\n const uaData = navigator.userAgentData;\n if (uaData != null && uaData.platform) {\n return uaData.platform;\n }\n return navigator.platform;\n}\nfunction getUserAgent() {\n const uaData = navigator.userAgentData;\n if (uaData && Array.isArray(uaData.brands)) {\n return uaData.brands.map(_ref => {\n let {\n brand,\n version\n } = _ref;\n return brand + \"/\" + version;\n }).join(' ');\n }\n return navigator.userAgent;\n}\n\n// License: https://github.com/adobe/react-spectrum/blob/b35d5c02fe900badccd0cf1a8f23bb593419f238/packages/@react-aria/utils/src/isVirtualEvent.ts\nfunction isVirtualClick(event) {\n // FIXME: Firefox is now emitting a deprecation warning for `mozInputSource`.\n // Try to find a workaround for this. `react-aria` source still has the check.\n if (event.mozInputSource === 0 && event.isTrusted) {\n return true;\n }\n if (isAndroid() && event.pointerType) {\n return event.type === 'click' && event.buttons === 1;\n }\n return event.detail === 0 && !event.pointerType;\n}\nfunction isVirtualPointerEvent(event) {\n if (isJSDOM()) return false;\n return !isAndroid() && event.width === 0 && event.height === 0 || isAndroid() && event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'mouse' ||\n // iOS VoiceOver returns 0.333• for width/height.\n event.width < 1 && event.height < 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'touch';\n}\nfunction isSafari() {\n // Chrome DevTools does not complain about navigator.vendor\n return /apple/i.test(navigator.vendor);\n}\nfunction isAndroid() {\n const re = /android/i;\n return re.test(getPlatform()) || re.test(getUserAgent());\n}\nfunction isMac() {\n return getPlatform().toLowerCase().startsWith('mac') && !navigator.maxTouchPoints;\n}\nfunction isJSDOM() {\n return getUserAgent().includes('jsdom/');\n}\nfunction isMouseLikePointerType(pointerType, strict) {\n // On some Linux machines with Chromium, mouse inputs return a `pointerType`\n // of \"pen\": https://github.com/floating-ui/floating-ui/issues/2015\n const values = ['mouse', 'pen'];\n if (!strict) {\n values.push('', undefined);\n }\n return values.includes(pointerType);\n}\nfunction isReactEvent(event) {\n return 'nativeEvent' in event;\n}\nfunction isRootElement(element) {\n return element.matches('html,body');\n}\nfunction getDocument(node) {\n return (node == null ? void 0 : node.ownerDocument) || document;\n}\nfunction isEventTargetWithin(event, node) {\n if (node == null) {\n return false;\n }\n if ('composedPath' in event) {\n return event.composedPath().includes(node);\n }\n\n // TS thinks `event` is of type never as it assumes all browsers support composedPath, but browsers without shadow dom don't\n const e = event;\n return e.target != null && node.contains(e.target);\n}\nfunction getTarget(event) {\n if ('composedPath' in event) {\n return event.composedPath()[0];\n }\n\n // TS thinks `event` is of type never as it assumes all browsers support\n // `composedPath()`, but browsers without shadow DOM don't.\n return event.target;\n}\nconst TYPEABLE_SELECTOR = \"input:not([type='hidden']):not([disabled]),\" + \"[contenteditable]:not([contenteditable='false']),textarea:not([disabled])\";\nfunction isTypeableElement(element) {\n return (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) && element.matches(TYPEABLE_SELECTOR);\n}\nfunction stopEvent(event) {\n event.preventDefault();\n event.stopPropagation();\n}\nfunction isTypeableCombobox(element) {\n if (!element) return false;\n return element.getAttribute('role') === 'combobox' && isTypeableElement(element);\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3JlYWN0L2Rpc3QvZmxvYXRpbmctdWkucmVhY3QudXRpbHMubWpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFxRTs7QUFFckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0Isb0VBQVk7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxxRUFBYTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRWlUIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmFkaWFudC8uL25vZGVfbW9kdWxlcy9AZmxvYXRpbmctdWkvcmVhY3QvZGlzdC9mbG9hdGluZy11aS5yZWFjdC51dGlscy5tanM/MGUxMyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1NoYWRvd1Jvb3QsIGlzSFRNTEVsZW1lbnQgfSBmcm9tICdAZmxvYXRpbmctdWkvdXRpbHMvZG9tJztcblxuZnVuY3Rpb24gYWN0aXZlRWxlbWVudChkb2MpIHtcbiAgbGV0IGFjdGl2ZUVsZW1lbnQgPSBkb2MuYWN0aXZlRWxlbWVudDtcbiAgd2hpbGUgKCgoX2FjdGl2ZUVsZW1lbnQgPSBhY3RpdmVFbGVtZW50KSA9PSBudWxsIHx8IChfYWN0aXZlRWxlbWVudCA9IF9hY3RpdmVFbGVtZW50LnNoYWRvd1Jvb3QpID09IG51bGwgPyB2b2lkIDAgOiBfYWN0aXZlRWxlbWVudC5hY3RpdmVFbGVtZW50KSAhPSBudWxsKSB7XG4gICAgdmFyIF9hY3RpdmVFbGVtZW50O1xuICAgIGFjdGl2ZUVsZW1lbnQgPSBhY3RpdmVFbGVtZW50LnNoYWRvd1Jvb3QuYWN0aXZlRWxlbWVudDtcbiAgfVxuICByZXR1cm4gYWN0aXZlRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgaWYgKCFwYXJlbnQgfHwgIWNoaWxkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgPT0gbnVsbCA/IHZvaWQgMCA6IGNoaWxkLmdldFJvb3ROb2RlKCk7XG5cbiAgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuICBpZiAocGFyZW50LmNvbnRhaW5zKGNoaWxkKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgaWYgKHJvb3ROb2RlICYmIGlzU2hhZG93Um9vdChyb290Tm9kZSkpIHtcbiAgICBsZXQgbmV4dCA9IGNoaWxkO1xuICAgIHdoaWxlIChuZXh0KSB7XG4gICAgICBpZiAocGFyZW50ID09PSBuZXh0KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgbmV4dCA9IG5leHQucGFyZW50Tm9kZSB8fCBuZXh0Lmhvc3Q7XG4gICAgfVxuICB9XG5cbiAgLy8gR2l2ZSB1cCwgdGhlIHJlc3VsdCBpcyBmYWxzZVxuICByZXR1cm4gZmFsc2U7XG59XG4vLyBBdm9pZCBDaHJvbWUgRGV2VG9vbHMgYmx1ZSB3YXJuaW5nLlxuZnVuY3Rpb24gZ2V0UGxhdGZvcm0oKSB7XG4gIGNvbnN0IHVhRGF0YSA9IG5hdmlnYXRvci51c2VyQWdlbnREYXRhO1xuICBpZiAodWFEYXRhICE9IG51bGwgJiYgdWFEYXRhLnBsYXRmb3JtKSB7XG4gICAgcmV0dXJuIHVhRGF0YS5wbGF0Zm9ybTtcbiAgfVxuICByZXR1cm4gbmF2aWdhdG9yLnBsYXRmb3JtO1xufVxuZnVuY3Rpb24gZ2V0VXNlckFnZW50KCkge1xuICBjb25zdCB1YURhdGEgPSBuYXZpZ2F0b3IudXNlckFnZW50RGF0YTtcbiAgaWYgKHVhRGF0YSAmJiBBcnJheS5pc0FycmF5KHVhRGF0YS5icmFuZHMpKSB7XG4gICAgcmV0dXJuIHVhRGF0YS5icmFuZHMubWFwKF9yZWYgPT4ge1xuICAgICAgbGV0IHtcbiAgICAgICAgYnJhbmQsXG4gICAgICAgIHZlcnNpb25cbiAgICAgIH0gPSBfcmVmO1xuICAgICAgcmV0dXJuIGJyYW5kICsgXCIvXCIgKyB2ZXJzaW9uO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgfVxuICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbn1cblxuLy8gTGljZW5zZTogaHR0cHM6Ly9naXRodWIuY29tL2Fkb2JlL3JlYWN0LXNwZWN0cnVtL2Jsb2IvYjM1ZDVjMDJmZTkwMGJhZGNjZDBjZjFhOGYyM2JiNTkzNDE5ZjIzOC9wYWNrYWdlcy9AcmVhY3QtYXJpYS91dGlscy9zcmMvaXNWaXJ0dWFsRXZlbnQudHNcbmZ1bmN0aW9uIGlzVmlydHVhbENsaWNrKGV2ZW50KSB7XG4gIC8vIEZJWE1FOiBGaXJlZm94IGlzIG5vdyBlbWl0dGluZyBhIGRlcHJlY2F0aW9uIHdhcm5pbmcgZm9yIGBtb3pJbnB1dFNvdXJjZWAuXG4gIC8vIFRyeSB0byBmaW5kIGEgd29ya2Fyb3VuZCBmb3IgdGhpcy4gYHJlYWN0LWFyaWFgIHNvdXJjZSBzdGlsbCBoYXMgdGhlIGNoZWNrLlxuICBpZiAoZXZlbnQubW96SW5wdXRTb3VyY2UgPT09IDAgJiYgZXZlbnQuaXNUcnVzdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQW5kcm9pZCgpICYmIGV2ZW50LnBvaW50ZXJUeXBlKSB7XG4gICAgcmV0dXJuIGV2ZW50LnR5cGUgPT09ICdjbGljaycgJiYgZXZlbnQuYnV0dG9ucyA9PT0gMTtcbiAgfVxuICByZXR1cm4gZXZlbnQuZGV0YWlsID09PSAwICYmICFldmVudC5wb2ludGVyVHlwZTtcbn1cbmZ1bmN0aW9uIGlzVmlydHVhbFBvaW50ZXJFdmVudChldmVudCkge1xuICBpZiAoaXNKU0RPTSgpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAhaXNBbmRyb2lkKCkgJiYgZXZlbnQud2lkdGggPT09IDAgJiYgZXZlbnQuaGVpZ2h0ID09PSAwIHx8IGlzQW5kcm9pZCgpICYmIGV2ZW50LndpZHRoID09PSAxICYmIGV2ZW50LmhlaWdodCA9PT0gMSAmJiBldmVudC5wcmVzc3VyZSA9PT0gMCAmJiBldmVudC5kZXRhaWwgPT09IDAgJiYgZXZlbnQucG9pbnRlclR5cGUgPT09ICdtb3VzZScgfHxcbiAgLy8gaU9TIFZvaWNlT3ZlciByZXR1cm5zIDAuMzMz4oCiIGZvciB3aWR0aC9oZWlnaHQuXG4gIGV2ZW50LndpZHRoIDwgMSAmJiBldmVudC5oZWlnaHQgPCAxICYmIGV2ZW50LnByZXNzdXJlID09PSAwICYmIGV2ZW50LmRldGFpbCA9PT0gMCAmJiBldmVudC5wb2ludGVyVHlwZSA9PT0gJ3RvdWNoJztcbn1cbmZ1bmN0aW9uIGlzU2FmYXJpKCkge1xuICAvLyBDaHJvbWUgRGV2VG9vbHMgZG9lcyBub3QgY29tcGxhaW4gYWJvdXQgbmF2aWdhdG9yLnZlbmRvclxuICByZXR1cm4gL2FwcGxlL2kudGVzdChuYXZpZ2F0b3IudmVuZG9yKTtcbn1cbmZ1bmN0aW9uIGlzQW5kcm9pZCgpIHtcbiAgY29uc3QgcmUgPSAvYW5kcm9pZC9pO1xuICByZXR1cm4gcmUudGVzdChnZXRQbGF0Zm9ybSgpKSB8fCByZS50ZXN0KGdldFVzZXJBZ2VudCgpKTtcbn1cbmZ1bmN0aW9uIGlzTWFjKCkge1xuICByZXR1cm4gZ2V0UGxhdGZvcm0oKS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoJ21hYycpICYmICFuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHM7XG59XG5mdW5jdGlvbiBpc0pTRE9NKCkge1xuICByZXR1cm4gZ2V0VXNlckFnZW50KCkuaW5jbHVkZXMoJ2pzZG9tLycpO1xufVxuZnVuY3Rpb24gaXNNb3VzZUxpa2VQb2ludGVyVHlwZShwb2ludGVyVHlwZSwgc3RyaWN0KSB7XG4gIC8vIE9uIHNvbWUgTGludXggbWFjaGluZXMgd2l0aCBDaHJvbWl1bSwgbW91c2UgaW5wdXRzIHJldHVybiBhIGBwb2ludGVyVHlwZWBcbiAgLy8gb2YgXCJwZW5cIjogaHR0cHM6Ly9naXRodWIuY29tL2Zsb2F0aW5nLXVpL2Zsb2F0aW5nLXVpL2lzc3Vlcy8yMDE1XG4gIGNvbnN0IHZhbHVlcyA9IFsnbW91c2UnLCAncGVuJ107XG4gIGlmICghc3RyaWN0KSB7XG4gICAgdmFsdWVzLnB1c2goJycsIHVuZGVmaW5lZCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcy5pbmNsdWRlcyhwb2ludGVyVHlwZSk7XG59XG5mdW5jdGlvbiBpc1JlYWN0RXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuICduYXRpdmVFdmVudCcgaW4gZXZlbnQ7XG59XG5mdW5jdGlvbiBpc1Jvb3RFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQubWF0Y2hlcygnaHRtbCxib2R5Jyk7XG59XG5mdW5jdGlvbiBnZXREb2N1bWVudChub2RlKSB7XG4gIHJldHVybiAobm9kZSA9PSBudWxsID8gdm9pZCAwIDogbm9kZS5vd25lckRvY3VtZW50KSB8fCBkb2N1bWVudDtcbn1cbmZ1bmN0aW9uIGlzRXZlbnRUYXJnZXRXaXRoaW4oZXZlbnQsIG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoJ2NvbXBvc2VkUGF0aCcgaW4gZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuY29tcG9zZWRQYXRoKCkuaW5jbHVkZXMobm9kZSk7XG4gIH1cblxuICAvLyBUUyB0aGlua3MgYGV2ZW50YCBpcyBvZiB0eXBlIG5ldmVyIGFzIGl0IGFzc3VtZXMgYWxsIGJyb3dzZXJzIHN1cHBvcnQgY29tcG9zZWRQYXRoLCBidXQgYnJvd3NlcnMgd2l0aG91dCBzaGFkb3cgZG9tIGRvbid0XG4gIGNvbnN0IGUgPSBldmVudDtcbiAgcmV0dXJuIGUudGFyZ2V0ICE9IG51bGwgJiYgbm9kZS5jb250YWlucyhlLnRhcmdldCk7XG59XG5mdW5jdGlvbiBnZXRUYXJnZXQoZXZlbnQpIHtcbiAgaWYgKCdjb21wb3NlZFBhdGgnIGluIGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50LmNvbXBvc2VkUGF0aCgpWzBdO1xuICB9XG5cbiAgLy8gVFMgdGhpbmtzIGBldmVudGAgaXMgb2YgdHlwZSBuZXZlciBhcyBpdCBhc3N1bWVzIGFsbCBicm93c2VycyBzdXBwb3J0XG4gIC8vIGBjb21wb3NlZFBhdGgoKWAsIGJ1dCBicm93c2VycyB3aXRob3V0IHNoYWRvdyBET00gZG9uJ3QuXG4gIHJldHVybiBldmVudC50YXJnZXQ7XG59XG5jb25zdCBUWVBFQUJMRV9TRUxFQ1RPUiA9IFwiaW5wdXQ6bm90KFt0eXBlPSdoaWRkZW4nXSk6bm90KFtkaXNhYmxlZF0pLFwiICsgXCJbY29udGVudGVkaXRhYmxlXTpub3QoW2NvbnRlbnRlZGl0YWJsZT0nZmFsc2UnXSksdGV4dGFyZWE6bm90KFtkaXNhYmxlZF0pXCI7XG5mdW5jdGlvbiBpc1R5cGVhYmxlRWxlbWVudChlbGVtZW50KSB7XG4gIHJldHVybiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpICYmIGVsZW1lbnQubWF0Y2hlcyhUWVBFQUJMRV9TRUxFQ1RPUik7XG59XG5mdW5jdGlvbiBzdG9wRXZlbnQoZXZlbnQpIHtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG59XG5mdW5jdGlvbiBpc1R5cGVhYmxlQ29tYm9ib3goZWxlbWVudCkge1xuICBpZiAoIWVsZW1lbnQpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdyb2xlJykgPT09ICdjb21ib2JveCcgJiYgaXNUeXBlYWJsZUVsZW1lbnQoZWxlbWVudCk7XG59XG5cbmV4cG9ydCB7IFRZUEVBQkxFX1NFTEVDVE9SLCBhY3RpdmVFbGVtZW50LCBjb250YWlucywgZ2V0RG9jdW1lbnQsIGdldFBsYXRmb3JtLCBnZXRUYXJnZXQsIGdldFVzZXJBZ2VudCwgaXNBbmRyb2lkLCBpc0V2ZW50VGFyZ2V0V2l0aGluLCBpc0pTRE9NLCBpc01hYywgaXNNb3VzZUxpa2VQb2ludGVyVHlwZSwgaXNSZWFjdEV2ZW50LCBpc1Jvb3RFbGVtZW50LCBpc1NhZmFyaSwgaXNUeXBlYWJsZUNvbWJvYm94LCBpc1R5cGVhYmxlRWxlbWVudCwgaXNWaXJ0dWFsQ2xpY2ssIGlzVmlydHVhbFBvaW50ZXJFdmVudCwgc3RvcEV2ZW50IH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs\n");
/***/ }),
/***/ "(ssr)/./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs":
/*!************************************************************************!*\
!*** ./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.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 */ getComputedStyle: () => (/* binding */ getComputedStyle),\n/* harmony export */ getContainingBlock: () => (/* binding */ getContainingBlock),\n/* harmony export */ getDocumentElement: () => (/* binding */ getDocumentElement),\n/* harmony export */ getFrameElement: () => (/* binding */ getFrameElement),\n/* harmony export */ getNearestOverflowAncestor: () => (/* binding */ getNearestOverflowAncestor),\n/* harmony export */ getNodeName: () => (/* binding */ getNodeName),\n/* harmony export */ getNodeScroll: () => (/* binding */ getNodeScroll),\n/* harmony export */ getOverflowAncestors: () => (/* binding */ getOverflowAncestors),\n/* harmony export */ getParentNode: () => (/* binding */ getParentNode),\n/* harmony export */ getWindow: () => (/* binding */ getWindow),\n/* harmony export */ isContainingBlock: () => (/* binding */ isContainingBlock),\n/* harmony export */ isElement: () => (/* binding */ isElement),\n/* harmony export */ isHTMLElement: () => (/* binding */ isHTMLElement),\n/* harmony export */ isLastTraversableNode: () => (/* binding */ isLastTraversableNode),\n/* harmony export */ isNode: () => (/* binding */ isNode),\n/* harmony export */ isOverflowElement: () => (/* binding */ isOverflowElement),\n/* harmony export */ isShadowRoot: () => (/* binding */ isShadowRoot),\n/* harmony export */ isTableElement: () => (/* binding */ isTableElement),\n/* harmony export */ isTopLayer: () => (/* binding */ isTopLayer),\n/* harmony export */ isWebKit: () => (/* binding */ isWebKit)\n/* harmony export */ });\nfunction getNodeName(node) {\n if (isNode(node)) {\n return (node.nodeName || '').toLowerCase();\n }\n // Mocked nodes in testing environments may not be instances of Node. By\n // returning `#document` an infinite loop won't occur.\n // https://github.com/floating-ui/floating-ui/issues/2317\n return '#document';\n}\nfunction getWindow(node) {\n var _node$ownerDocument;\n return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;\n}\nfunction getDocumentElement(node) {\n var _ref;\n return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;\n}\nfunction isNode(value) {\n return value instanceof Node || value instanceof getWindow(value).Node;\n}\nfunction isElement(value) {\n return value instanceof Element || value instanceof getWindow(value).Element;\n}\nfunction isHTMLElement(value) {\n return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;\n}\nfunction isShadowRoot(value) {\n // Browsers without `ShadowRoot` support.\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;\n}\nfunction isOverflowElement(element) {\n const {\n overflow,\n overflowX,\n overflowY,\n display\n } = getComputedStyle(element);\n return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);\n}\nfunction isTableElement(element) {\n return ['table', 'td', 'th'].includes(getNodeName(element));\n}\nfunction isTopLayer(element) {\n return [':popover-open', ':modal'].some(selector => {\n try {\n return element.matches(selector);\n } catch (e) {\n return false;\n }\n });\n}\nfunction isContainingBlock(elementOrCss) {\n const webkit = isWebKit();\n const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n return css.transform !== 'none' || css.perspective !== 'none' || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective', 'filter'].some(value => (css.willChange || '').includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => (css.contain || '').includes(value));\n}\nfunction getContainingBlock(element) {\n let currentNode = getParentNode(element);\n while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {\n if (isContainingBlock(currentNode)) {\n return currentNode;\n } else if (isTopLayer(currentNode)) {\n return null;\n }\n currentNode = getParentNode(currentNode);\n }\n return null;\n}\nfunction isWebKit() {\n if (typeof CSS === 'undefined' || !CSS.supports) return false;\n return CSS.supports('-webkit-backdrop-filter', 'none');\n}\nfunction isLastTraversableNode(node) {\n return ['html', 'body', '#document'].includes(getNodeName(node));\n}\nfunction getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}\nfunction getNodeScroll(element) {\n if (isElement(element)) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n }\n return {\n scrollLeft: element.scrollX,\n scrollTop: element.scrollY\n };\n}\nfunction getParentNode(node) {\n if (getNodeName(node) === 'html') {\n return node;\n }\n const result =\n // Step into the shadow DOM of the parent of a slotted node.\n node.assignedSlot ||\n // DOM Element detected.\n node.parentNode ||\n // ShadowRoot detected.\n isShadowRoot(node) && node.host ||\n // Fallback.\n getDocumentElement(node);\n return isShadowRoot(result) ? result.host : result;\n}\nfunction getNearestOverflowAncestor(node) {\n const parentNode = getParentNode(node);\n if (isLastTraversableNode(parentNode)) {\n return node.ownerDocument ? node.ownerDocument.body : node.body;\n }\n if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {\n return parentNode;\n }\n return getNearestOverflowAncestor(parentNode);\n}\nfunction getOverflowAncestors(node, list, traverseIframes) {\n var _node$ownerDocument2;\n if (list === void 0) {\n list = [];\n }\n if (traverseIframes === void 0) {\n traverseIframes = true;\n }\n const scrollableAncestor = getNearestOverflowAncestor(node);\n const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);\n const win = getWindow(scrollableAncestor);\n if (isBody) {\n const frameElement = getFrameElement(win);\n return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);\n }\n return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));\n}\nfunction getFrameElement(win) {\n return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3V0aWxzL2Rpc3QvZmxvYXRpbmctdWkudXRpbHMuZG9tLm1qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVnViIsInNvdXJjZXMiOlsid2VicGFjazovL3JhZGlhbnQvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3V0aWxzL2Rpc3QvZmxvYXRpbmctdWkudXRpbHMuZG9tLm1qcz8yZDNhIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIGdldE5vZGVOYW1lKG5vZGUpIHtcbiAgaWYgKGlzTm9kZShub2RlKSkge1xuICAgIHJldHVybiAobm9kZS5ub2RlTmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuICAvLyBNb2NrZWQgbm9kZXMgaW4gdGVzdGluZyBlbnZpcm9ubWVudHMgbWF5IG5vdCBiZSBpbnN0YW5jZXMgb2YgTm9kZS4gQnlcbiAgLy8gcmV0dXJuaW5nIGAjZG9jdW1lbnRgIGFuIGluZmluaXRlIGxvb3Agd29uJ3Qgb2NjdXIuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9hdGluZy11aS9mbG9hdGluZy11aS9pc3N1ZXMvMjMxN1xuICByZXR1cm4gJyNkb2N1bWVudCc7XG59XG5mdW5jdGlvbiBnZXRXaW5kb3cobm9kZSkge1xuICB2YXIgX25vZGUkb3duZXJEb2N1bWVudDtcbiAgcmV0dXJuIChub2RlID09IG51bGwgfHwgKF9ub2RlJG93bmVyRG9jdW1lbnQgPSBub2RlLm93bmVyRG9jdW1lbnQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRvd25lckRvY3VtZW50LmRlZmF1bHRWaWV3KSB8fCB3aW5kb3c7XG59XG5mdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQobm9kZSkge1xuICB2YXIgX3JlZjtcbiAgcmV0dXJuIChfcmVmID0gKGlzTm9kZShub2RlKSA/IG5vZGUub3duZXJEb2N1bWVudCA6IG5vZGUuZG9jdW1lbnQpIHx8IHdpbmRvdy5kb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9yZWYuZG9jdW1lbnRFbGVtZW50O1xufVxuZnVuY3Rpb24gaXNOb2RlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIE5vZGUgfHwgdmFsdWUgaW5zdGFuY2VvZiBnZXRXaW5kb3codmFsdWUpLk5vZGU7XG59XG5mdW5jdGlvbiBpc0VsZW1lbnQodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRWxlbWVudCB8fCB2YWx1ZSBpbnN0YW5jZW9mIGdldFdpbmRvdyh2YWx1ZSkuRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGlzSFRNTEVsZW1lbnQodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgdmFsdWUgaW5zdGFuY2VvZiBnZXRXaW5kb3codmFsdWUpLkhUTUxFbGVtZW50O1xufVxuZnVuY3Rpb24gaXNTaGFkb3dSb290KHZhbHVlKSB7XG4gIC8vIEJyb3dzZXJzIHdpdGhvdXQgYFNoYWRvd1Jvb3RgIHN1cHBvcnQuXG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgU2hhZG93Um9vdCB8fCB2YWx1ZSBpbnN0YW5jZW9mIGdldFdpbmRvdyh2YWx1ZSkuU2hhZG93Um9vdDtcbn1cbmZ1bmN0aW9uIGlzT3ZlcmZsb3dFbGVtZW50KGVsZW1lbnQpIHtcbiAgY29uc3Qge1xuICAgIG92ZXJmbG93LFxuICAgIG92ZXJmbG93WCxcbiAgICBvdmVyZmxvd1ksXG4gICAgZGlzcGxheVxuICB9ID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbnxjbGlwLy50ZXN0KG92ZXJmbG93ICsgb3ZlcmZsb3dZICsgb3ZlcmZsb3dYKSAmJiAhWydpbmxpbmUnLCAnY29udGVudHMnXS5pbmNsdWRlcyhkaXNwbGF5KTtcbn1cbmZ1bmN0aW9uIGlzVGFibGVFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsndGFibGUnLCAndGQnLCAndGgnXS5pbmNsdWRlcyhnZXROb2RlTmFtZShlbGVtZW50KSk7XG59XG5mdW5jdGlvbiBpc1RvcExheWVyKGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsnOnBvcG92ZXItb3BlbicsICc6bW9kYWwnXS5zb21lKHNlbGVjdG9yID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQubWF0Y2hlcyhzZWxlY3Rvcik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG59XG5mdW5jdGlvbiBpc0NvbnRhaW5pbmdCbG9jayhlbGVtZW50T3JDc3MpIHtcbiAgY29uc3Qgd2Via2l0ID0gaXNXZWJLaXQoKTtcbiAgY29uc3QgY3NzID0gaXNFbGVtZW50KGVsZW1lbnRPckNzcykgPyBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnRPckNzcykgOiBlbGVtZW50T3JDc3M7XG5cbiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NvbnRhaW5pbmdfYmxvY2sjaWRlbnRpZnlpbmdfdGhlX2NvbnRhaW5pbmdfYmxvY2tcbiAgcmV0dXJuIGNzcy50cmFuc2Zvcm0gIT09ICdub25lJyB8fCBjc3MucGVyc3BlY3RpdmUgIT09ICdub25lJyB8fCAoY3NzLmNvbnRhaW5lclR5cGUgPyBjc3MuY29udGFpbmVyVHlwZSAhPT0gJ25vcm1hbCcgOiBmYWxzZSkgfHwgIXdlYmtpdCAmJiAoY3NzLmJhY2tkcm9wRmlsdGVyID8gY3NzLmJhY2tkcm9wRmlsdGVyICE9PSAnbm9uZScgOiBmYWxzZSkgfHwgIXdlYmtpdCAmJiAoY3NzLmZpbHRlciA/IGNzcy5maWx0ZXIgIT09ICdub25lJyA6IGZhbHNlKSB8fCBbJ3RyYW5zZm9ybScsICdwZXJzcGVjdGl2ZScsICdmaWx0ZXInXS5zb21lKHZhbHVlID0+IChjc3Mud2lsbENoYW5nZSB8fCAnJykuaW5jbHVkZXModmFsdWUpKSB8fCBbJ3BhaW50JywgJ2xheW91dCcsICdzdHJpY3QnLCAnY29udGVudCddLnNvbWUodmFsdWUgPT4gKGNzcy5jb250YWluIHx8ICcnKS5pbmNsdWRlcyh2YWx1ZSkpO1xufVxuZnVuY3Rpb24gZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHtcbiAgbGV0IGN1cnJlbnROb2RlID0gZ2V0UGFyZW50Tm9kZShlbGVtZW50KTtcbiAgd2hpbGUgKGlzSFRNTEVsZW1lbnQoY3VycmVudE5vZGUpICYmICFpc0xhc3RUcmF2ZXJzYWJsZU5vZGUoY3VycmVudE5vZGUpKSB7XG4gICAgaWYgKGlzQ29udGFpbmluZ0Jsb2NrKGN1cnJlbnROb2RlKSkge1xuICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgIH0gZWxzZSBpZiAoaXNUb3BMYXllcihjdXJyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjdXJyZW50Tm9kZSA9IGdldFBhcmVudE5vZGUoY3VycmVudE5vZGUpO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gaXNXZWJLaXQoKSB7XG4gIGlmICh0eXBlb2YgQ1NTID09PSAndW5kZWZpbmVkJyB8fCAhQ1NTLnN1cHBvcnRzKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBDU1Muc3VwcG9ydHMoJy13ZWJraXQtYmFja2Ryb3AtZmlsdGVyJywgJ25vbmUnKTtcbn1cbmZ1bmN0aW9uIGlzTGFzdFRyYXZlcnNhYmxlTm9kZShub2RlKSB7XG4gIHJldHVybiBbJ2h0bWwnLCAnYm9keScsICcjZG9jdW1lbnQnXS5pbmNsdWRlcyhnZXROb2RlTmFtZShub2RlKSk7XG59XG5mdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufVxuZnVuY3Rpb24gZ2V0Tm9kZVNjcm9sbChlbGVtZW50KSB7XG4gIGlmIChpc0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2Nyb2xsTGVmdDogZWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFRvcFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBlbGVtZW50LnNjcm9sbFgsXG4gICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFlcbiAgfTtcbn1cbmZ1bmN0aW9uIGdldFBhcmVudE5vZGUobm9kZSkge1xuICBpZiAoZ2V0Tm9kZU5hbWUobm9kZSkgPT09ICdodG1sJykge1xuICAgIHJldHVybiBub2RlO1xuICB9XG4gIGNvbnN0IHJlc3VsdCA9XG4gIC8vIFN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlLlxuICBub2RlLmFzc2lnbmVkU2xvdCB8fFxuICAvLyBET00gRWxlbWVudCBkZXRlY3RlZC5cbiAgbm9kZS5wYXJlbnROb2RlIHx8XG4gIC8vIFNoYWRvd1Jvb3QgZGV0ZWN0ZWQuXG4gIGlzU2hhZG93Um9vdChub2RlKSAmJiBub2RlLmhvc3QgfHxcbiAgLy8gRmFsbGJhY2suXG4gIGdldERvY3VtZW50RWxlbWVudChub2RlKTtcbiAgcmV0dXJuIGlzU2hhZG93Um9vdChyZXN1bHQpID8gcmVzdWx0Lmhvc3QgOiByZXN1bHQ7XG59XG5mdW5jdGlvbiBnZXROZWFyZXN0T3ZlcmZsb3dBbmNlc3Rvcihub2RlKSB7XG4gIGNvbnN0IHBhcmVudE5vZGUgPSBnZXRQYXJlbnROb2RlKG5vZGUpO1xuICBpZiAoaXNMYXN0VHJhdmVyc2FibGVOb2RlKHBhcmVudE5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGUub3duZXJEb2N1bWVudCA/IG5vZGUub3duZXJEb2N1bWVudC5ib2R5IDogbm9kZS5ib2R5O1xuICB9XG4gIGlmIChpc0hUTUxFbGVtZW50KHBhcmVudE5vZGUpICYmIGlzT3ZlcmZsb3dFbGVtZW50KHBhcmVudE5vZGUpKSB7XG4gICAgcmV0dXJuIHBhcmVudE5vZGU7XG4gIH1cbiAgcmV0dXJuIGdldE5lYXJlc3RPdmVyZmxvd0FuY2VzdG9yKHBhcmVudE5vZGUpO1xufVxuZnVuY3Rpb24gZ2V0T3ZlcmZsb3dBbmNlc3RvcnMobm9kZSwgbGlzdCwgdHJhdmVyc2VJZnJhbWVzKSB7XG4gIHZhciBfbm9kZSRvd25lckRvY3VtZW50MjtcbiAgaWYgKGxpc3QgPT09IHZvaWQgMCkge1xuICAgIGxpc3QgPSBbXTtcbiAgfVxuICBpZiAodHJhdmVyc2VJZnJhbWVzID09PSB2b2lkIDApIHtcbiAgICB0cmF2ZXJzZUlmcmFtZXMgPSB0cnVlO1xuICB9XG4gIGNvbnN0IHNjcm9sbGFibGVBbmNlc3RvciA9IGdldE5lYXJlc3RPdmVyZmxvd0FuY2VzdG9yKG5vZGUpO1xuICBjb25zdCBpc0JvZHkgPSBzY3JvbGxhYmxlQW5jZXN0b3IgPT09ICgoX25vZGUkb3duZXJEb2N1bWVudDIgPSBub2RlLm93bmVyRG9jdW1lbnQpID09IG51bGwgPyB2b2lkIDAgOiBfbm9kZSRvd25lckRvY3VtZW50Mi5ib2R5KTtcbiAgY29uc3Qgd2luID0gZ2V0V2luZG93KHNjcm9sbGFibGVBbmNlc3Rvcik7XG4gIGlmIChpc0JvZHkpIHtcbiAgICBjb25zdCBmcmFtZUVsZW1lbnQgPSBnZXRGcmFtZUVsZW1lbnQod2luKTtcbiAgICByZXR1cm4gbGlzdC5jb25jYXQod2luLCB3aW4udmlzdWFsVmlld3BvcnQgfHwgW10sIGlzT3ZlcmZsb3dFbGVtZW50KHNjcm9sbGFibGVBbmNlc3RvcikgPyBzY3JvbGxhYmxlQW5jZXN0b3IgOiBbXSwgZnJhbWVFbGVtZW50ICYmIHRyYXZlcnNlSWZyYW1lcyA/IGdldE92ZXJmbG93QW5jZXN0b3JzKGZyYW1lRWxlbWVudCkgOiBbXSk7XG4gIH1cbiAgcmV0dXJuIGxpc3QuY29uY2F0KHNjcm9sbGFibGVBbmNlc3RvciwgZ2V0T3ZlcmZsb3dBbmNlc3RvcnMoc2Nyb2xsYWJsZUFuY2VzdG9yLCBbXSwgdHJhdmVyc2VJZnJhbWVzKSk7XG59XG5mdW5jdGlvbiBnZXRGcmFtZUVsZW1lbnQod2luKSB7XG4gIHJldHVybiB3aW4ucGFyZW50ICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZih3aW4ucGFyZW50KSA/IHdpbi5mcmFtZUVsZW1lbnQgOiBudWxsO1xufVxuXG5leHBvcnQgeyBnZXRDb21wdXRlZFN0eWxlLCBnZXRDb250YWluaW5nQmxvY2ssIGdldERvY3VtZW50RWxlbWVudCwgZ2V0RnJhbWVFbGVtZW50LCBnZXROZWFyZXN0T3ZlcmZsb3dBbmNlc3RvciwgZ2V0Tm9kZU5hbWUsIGdldE5vZGVTY3JvbGwsIGdldE92ZXJmbG93QW5jZXN0b3JzLCBnZXRQYXJlbnROb2RlLCBnZXRXaW5kb3csIGlzQ29udGFpbmluZ0Jsb2NrLCBpc0VsZW1lbnQsIGlzSFRNTEVsZW1lbnQsIGlzTGFzdFRyYXZlcnNhYmxlTm9kZSwgaXNOb2RlLCBpc092ZXJmbG93RWxlbWVudCwgaXNTaGFkb3dSb290LCBpc1RhYmxlRWxlbWVudCwgaXNUb3BMYXllciwgaXNXZWJLaXQgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs\n");
/***/ }),
/***/ "(ssr)/./node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs":
/*!********************************************************************!*\
!*** ./node_modules/@floating-ui/utils/dist/floating-ui.utils.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 */ alignments: () => (/* binding */ alignments),\n/* harmony export */ clamp: () => (/* binding */ clamp),\n/* harmony export */ createCoords: () => (/* binding */ createCoords),\n/* harmony export */ evaluate: () => (/* binding */ evaluate),\n/* harmony export */ expandPaddingObject: () => (/* binding */ expandPaddingObject),\n/* harmony export */ floor: () => (/* binding */ floor),\n/* harmony export */ getAlignment: () => (/* binding */ getAlignment),\n/* harmony export */ getAlignmentAxis: () => (/* binding */ getAlignmentAxis),\n/* harmony export */ getAlignmentSides: () => (/* binding */ getAlignmentSides),\n/* harmony export */ getAxisLength: () => (/* binding */ getAxisLength),\n/* harmony export */ getExpandedPlacements: () => (/* binding */ getExpandedPlacements),\n/* harmony export */ getOppositeAlignmentPlacement: () => (/* binding */ getOppositeAlignmentPlacement),\n/* harmony export */ getOppositeAxis: () => (/* binding */ getOppositeAxis),\n/* harmony export */ getOppositeAxisPlacements: () => (/* binding */ getOppositeAxisPlacements),\n/* harmony export */ getOppositePlacement: () => (/* binding */ getOppositePlacement),\n/* harmony export */ getPaddingObject: () => (/* binding */ getPaddingObject),\n/* harmony export */ getSide: () => (/* binding */ getSide),\n/* harmony export */ getSideAxis: () => (/* binding */ getSideAxis),\n/* harmony export */ max: () => (/* binding */ max),\n/* harmony export */ min: () => (/* binding */ min),\n/* harmony export */ placements: () => (/* binding */ placements),\n/* harmony export */ rectToClientRect: () => (/* binding */ rectToClientRect),\n/* harmony export */ round: () => (/* binding */ round),\n/* harmony export */ sides: () => (/* binding */ sides)\n/* harmony export */ });\n/**\n * Custom positioning reference element.\n * @see https://floating-ui.com/docs/virtual-elements\n */\n\nconst sides = ['top', 'right', 'bottom', 'left'];\nconst alignments = ['start', 'end'];\nconst placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + \"-\" + alignments[0], side + \"-\" + alignments[1]), []);\nconst min = Math.min;\nconst max = Math.max;\nconst round = Math.round;\nconst floor = Math.floor;\nconst createCoords = v => ({\n x: v,\n y: v\n});\nconst oppositeSideMap = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nconst oppositeAlignmentMap = {\n start: 'end',\n end: 'start'\n};\nfunction clamp(start, value, end) {\n return max(start, min(value, end));\n}\nfunction evaluate(value, param) {\n return typeof value === 'function' ? value(param) : value;\n}\nfunction getSide(placement) {\n return placement.split('-')[0];\n}\nfunction getAlignment(placement) {\n return placement.split('-')[1];\n}\nfunction getOppositeAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}\nfunction getAxisLength(axis) {\n return axis === 'y' ? 'height' : 'width';\n}\nfunction getSideAxis(placement) {\n return ['top', 'bottom'].includes(getSide(placement)) ? 'y' : 'x';\n}\nfunction getAlignmentAxis(placement) {\n return getOppositeAxis(getSideAxis(placement));\n}\nfunction getAlignmentSides(placement, rects, rtl) {\n if (rtl === void 0) {\n rtl = false;\n }\n const alignment = getAlignment(placement);\n const alignmentAxis = getAlignmentAxis(placement);\n const length = getAxisLength(alignmentAxis);\n let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';\n if (rects.reference[length] > rects.floating[length]) {\n mainAlignmentSide = getOppositePlacement(mainAlignmentSide);\n }\n return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];\n}\nfunction getExpandedPlacements(placement) {\n const oppositePlacement = getOppositePlacement(placement);\n return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];\n}\nfunction getOppositeAlignmentPlacement(placement) {\n return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);\n}\nfunction getSideList(side, isStart, rtl) {\n const lr = ['left', 'right'];\n const rl = ['right', 'left'];\n const tb = ['top', 'bottom'];\n const bt = ['bottom', 'top'];\n switch (side) {\n case 'top':\n case 'bottom':\n if (rtl) return isStart ? rl : lr;\n return isStart ? lr : rl;\n case 'left':\n case 'right':\n return isStart ? tb : bt;\n default:\n return [];\n }\n}\nfunction getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {\n const alignment = getAlignment(placement);\n let list = getSideList(getSide(placement), direction === 'start', rtl);\n if (alignment) {\n list = list.map(side => side + \"-\" + alignment);\n if (flipAlignment) {\n list = list.concat(list.map(getOppositeAlignmentPlacement));\n }\n }\n return list;\n}\nfunction getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);\n}\nfunction expandPaddingObject(padding) {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...padding\n };\n}\nfunction getPaddingObject(padding) {\n return typeof padding !== 'number' ? expandPaddingObject(padding) : {\n top: padding,\n right: padding,\n bottom: padding,\n left: padding\n };\n}\nfunction rectToClientRect(rect) {\n const {\n x,\n y,\n width,\n height\n } = rect;\n return {\n width,\n height,\n top: y,\n left: x,\n right: x + width,\n bottom: y + height,\n x,\n y\n };\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3V0aWxzL2Rpc3QvZmxvYXRpbmctdWkudXRpbHMubWpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUV5VyIsInNvdXJjZXMiOlsid2VicGFjazovL3JhZGlhbnQvLi9ub2RlX21vZHVsZXMvQGZsb2F0aW5nLXVpL3V0aWxzL2Rpc3QvZmxvYXRpbmctdWkudXRpbHMubWpzPzhmYmUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXN0b20gcG9zaXRpb25pbmcgcmVmZXJlbmNlIGVsZW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvdmlydHVhbC1lbGVtZW50c1xuICovXG5cbmNvbnN0IHNpZGVzID0gWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnXTtcbmNvbnN0IGFsaWdubWVudHMgPSBbJ3N0YXJ0JywgJ2VuZCddO1xuY29uc3QgcGxhY2VtZW50cyA9IC8qI19fUFVSRV9fKi9zaWRlcy5yZWR1Y2UoKGFjYywgc2lkZSkgPT4gYWNjLmNvbmNhdChzaWRlLCBzaWRlICsgXCItXCIgKyBhbGlnbm1lbnRzWzBdLCBzaWRlICsgXCItXCIgKyBhbGlnbm1lbnRzWzFdKSwgW10pO1xuY29uc3QgbWluID0gTWF0aC5taW47XG5jb25zdCBtYXggPSBNYXRoLm1heDtcbmNvbnN0IHJvdW5kID0gTWF0aC5yb3VuZDtcbmNvbnN0IGZsb29yID0gTWF0aC5mbG9vcjtcbmNvbnN0IGNyZWF0ZUNvb3JkcyA9IHYgPT4gKHtcbiAgeDogdixcbiAgeTogdlxufSk7XG5jb25zdCBvcHBvc2l0ZVNpZGVNYXAgPSB7XG4gIGxlZnQ6ICdyaWdodCcsXG4gIHJpZ2h0OiAnbGVmdCcsXG4gIGJvdHRvbTogJ3RvcCcsXG4gIHRvcDogJ2JvdHRvbSdcbn07XG5jb25zdCBvcHBvc2l0ZUFsaWdubWVudE1hcCA9IHtcbiAgc3RhcnQ6ICdlbmQnLFxuICBlbmQ6ICdzdGFydCdcbn07XG5mdW5jdGlvbiBjbGFtcChzdGFydCwgdmFsdWUsIGVuZCkge1xuICByZXR1cm4gbWF4KHN0YXJ0LCBtaW4odmFsdWUsIGVuZCkpO1xufVxuZnVuY3Rpb24gZXZhbHVhdGUodmFsdWUsIHBhcmFtKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZShwYXJhbSkgOiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGdldFNpZGUocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQuc3BsaXQoJy0nKVswXTtcbn1cbmZ1bmN0aW9uIGdldEFsaWdubWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzFdO1xufVxuZnVuY3Rpb24gZ2V0T3Bwb3NpdGVBeGlzKGF4aXMpIHtcbiAgcmV0dXJuIGF4aXMgPT09ICd4JyA/ICd5JyA6ICd4Jztcbn1cbmZ1bmN0aW9uIGdldEF4aXNMZW5ndGgoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xufVxuZnVuY3Rpb24gZ2V0U2lkZUF4aXMocGxhY2VtZW50KSB7XG4gIHJldHVybiBbJ3RvcCcsICdib3R0b20nXS5pbmNsdWRlcyhnZXRTaWRlKHBsYWNlbWVudCkpID8gJ3knIDogJ3gnO1xufVxuZnVuY3Rpb24gZ2V0QWxpZ25tZW50QXhpcyhwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGdldE9wcG9zaXRlQXhpcyhnZXRTaWRlQXhpcyhwbGFjZW1lbnQpKTtcbn1cbmZ1bmN0aW9uIGdldEFsaWdubWVudFNpZGVzKHBsYWNlbWVudCwgcmVjdHMsIHJ0bCkge1xuICBpZiAocnRsID09PSB2b2lkIDApIHtcbiAgICBydGwgPSBmYWxzZTtcbiAgfVxuICBjb25zdCBhbGlnbm1lbnQgPSBnZXRBbGlnbm1lbnQocGxhY2VtZW50KTtcbiAgY29uc3QgYWxpZ25tZW50QXhpcyA9IGdldEFsaWdubWVudEF4aXMocGxhY2VtZW50KTtcbiAgY29uc3QgbGVuZ3RoID0gZ2V0QXhpc0xlbmd0aChhbGlnbm1lbnRBeGlzKTtcbiAgbGV0IG1haW5BbGlnbm1lbnRTaWRlID0gYWxpZ25tZW50QXhpcyA9PT0gJ3gnID8gYWxpZ25tZW50ID09PSAocnRsID8gJ2VuZCcgOiAnc3RhcnQnKSA/ICdyaWdodCcgOiAnbGVmdCcgOiBhbGlnbm1lbnQgPT09ICdzdGFydCcgPyAnYm90dG9tJyA6ICd0b3AnO1xuICBpZiAocmVjdHMucmVmZXJlbmNlW2xlbmd0aF0gPiByZWN0cy5mbG9hdGluZ1tsZW5ndGhdKSB7XG4gICAgbWFpbkFsaWdubWVudFNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluQWxpZ25tZW50U2lkZSk7XG4gIH1cbiAgcmV0dXJuIFttYWluQWxpZ25tZW50U2lkZSwgZ2V0T3Bwb3NpdGVQbGFjZW1lbnQobWFpbkFsaWdubWVudFNpZGUpXTtcbn1cbmZ1bmN0aW9uIGdldEV4cGFuZGVkUGxhY2VtZW50cyhwbGFjZW1lbnQpIHtcbiAgY29uc3Qgb3Bwb3NpdGVQbGFjZW1lbnQgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICByZXR1cm4gW2dldE9wcG9zaXRlQWxpZ25tZW50UGxhY2VtZW50KHBsYWNlbWVudCksIG9wcG9zaXRlUGxhY2VtZW50LCBnZXRPcHBvc2l0ZUFsaWdubWVudFBsYWNlbWVudChvcHBvc2l0ZVBsYWNlbWVudCldO1xufVxuZnVuY3Rpb24gZ2V0T3Bwb3NpdGVBbGlnbm1lbnRQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvc3RhcnR8ZW5kL2csIGFsaWdubWVudCA9PiBvcHBvc2l0ZUFsaWdubWVudE1hcFthbGlnbm1lbnRdKTtcbn1cbmZ1bmN0aW9uIGdldFNpZGVMaXN0KHNpZGUsIGlzU3RhcnQsIHJ0bCkge1xuICBjb25zdCBsciA9IFsnbGVmdCcsICdyaWdodCddO1xuICBjb25zdCBybCA9IFsncmlnaHQnLCAnbGVmdCddO1xuICBjb25zdCB0YiA9IFsndG9wJywgJ2JvdHRvbSddO1xuICBjb25zdCBidCA9IFsnYm90dG9tJywgJ3RvcCddO1xuICBzd2l0Y2ggKHNpZGUpIHtcbiAgICBjYXNlICd0b3AnOlxuICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICBpZiAocnRsKSByZXR1cm4gaXNTdGFydCA/IHJsIDogbHI7XG4gICAgICByZXR1cm4gaXNTdGFydCA/IGxyIDogcmw7XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgY2FzZSAncmlnaHQnOlxuICAgICAgcmV0dXJuIGlzU3RhcnQgPyB0YiA6IGJ0O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gW107XG4gIH1cbn1cbmZ1bmN0aW9uIGdldE9wcG9zaXRlQXhpc1BsYWNlbWVudHMocGxhY2VtZW50LCBmbGlwQWxpZ25tZW50LCBkaXJlY3Rpb24sIHJ0bCkge1xuICBjb25zdCBhbGlnbm1lbnQgPSBnZXRBbGlnbm1lbnQocGxhY2VtZW50KTtcbiAgbGV0IGxpc3QgPSBnZXRTaWRlTGlzdChnZXRTaWRlKHBsYWNlbWVudCksIGRpcmVjdGlvbiA9PT0gJ3N0YXJ0JywgcnRsKTtcbiAgaWYgKGFsaWdubWVudCkge1xuICAgIGxpc3QgPSBsaXN0Lm1hcChzaWRlID0+IHNpZGUgKyBcIi1cIiArIGFsaWdubWVudCk7XG4gICAgaWYgKGZsaXBBbGlnbm1lbnQpIHtcbiAgICAgIGxpc3QgPSBsaXN0LmNvbmNhdChsaXN0Lm1hcChnZXRPcHBvc2l0ZUFsaWdubWVudFBsYWNlbWVudCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbGlzdDtcbn1cbmZ1bmN0aW9uIGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnJlcGxhY2UoL2xlZnR8cmlnaHR8Ym90dG9tfHRvcC9nLCBzaWRlID0+IG9wcG9zaXRlU2lkZU1hcFtzaWRlXSk7XG59XG5mdW5jdGlvbiBleHBhbmRQYWRkaW5nT2JqZWN0KHBhZGRpbmcpIHtcbiAgcmV0dXJuIHtcbiAgICB0b3A6IDAsXG4gICAgcmlnaHQ6IDAsXG4gICAgYm90dG9tOiAwLFxuICAgIGxlZnQ6IDAsXG4gICAgLi4ucGFkZGluZ1xuICB9O1xufVxuZnVuY3Rpb24gZ2V0UGFkZGluZ09iamVjdChwYWRkaW5nKSB7XG4gIHJldHVybiB0eXBlb2YgcGFkZGluZyAhPT0gJ251bWJlcicgPyBleHBhbmRQYWRkaW5nT2JqZWN0KHBhZGRpbmcpIDoge1xuICAgIHRvcDogcGFkZGluZyxcbiAgICByaWdodDogcGFkZGluZyxcbiAgICBib3R0b206IHBhZGRpbmcsXG4gICAgbGVmdDogcGFkZGluZ1xuICB9O1xufVxuZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIGNvbnN0IHtcbiAgICB4LFxuICAgIHksXG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0XG4gIH0gPSByZWN0O1xuICByZXR1cm4ge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICB0b3A6IHksXG4gICAgbGVmdDogeCxcbiAgICByaWdodDogeCArIHdpZHRoLFxuICAgIGJvdHRvbTogeSArIGhlaWdodCxcbiAgICB4LFxuICAgIHlcbiAgfTtcbn1cblxuZXhwb3J0IHsgYWxpZ25tZW50cywgY2xhbXAsIGNyZWF0ZUNvb3JkcywgZXZhbHVhdGUsIGV4cGFuZFBhZGRpbmdPYmplY3QsIGZsb29yLCBnZXRBbGlnbm1lbnQsIGdldEFsaWdubWVudEF4aXMsIGdldEFsaWdubWVudFNpZGVzLCBnZXRBeGlzTGVuZ3RoLCBnZXRFeHBhbmRlZFBsYWNlbWVudHMsIGdldE9wcG9zaXRlQWxpZ25tZW50UGxhY2VtZW50LCBnZXRPcHBvc2l0ZUF4aXMsIGdldE9wcG9zaXRlQXhpc1BsYWNlbWVudHMsIGdldE9wcG9zaXRlUGxhY2VtZW50LCBnZXRQYWRkaW5nT2JqZWN0LCBnZXRTaWRlLCBnZXRTaWRlQXhpcywgbWF4LCBtaW4sIHBsYWNlbWVudHMsIHJlY3RUb0NsaWVudFJlY3QsIHJvdW5kLCBzaWRlcyB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs\n");
/***/ })
};
;