"use strict"; /* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ exports.id = "vendor-chunks/react-easy-crop"; exports.ids = ["vendor-chunks/react-easy-crop"]; exports.modules = { /***/ "(ssr)/./node_modules/react-easy-crop/index.module.mjs": /*!*******************************************************!*\ !*** ./node_modules/react-easy-crop/index.module.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 */ \"default\": () => (/* binding */ Cropper),\n/* harmony export */ getInitialCropFromCroppedAreaPercentages: () => (/* binding */ getInitialCropFromCroppedAreaPercentages),\n/* harmony export */ getInitialCropFromCroppedAreaPixels: () => (/* binding */ getInitialCropFromCroppedAreaPixels)\n/* harmony export */ });\n/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ \"(ssr)/./node_modules/tslib/tslib.es6.mjs\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"(ssr)/./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react.js\");\n/* harmony import */ var normalize_wheel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! normalize-wheel */ \"(ssr)/./node_modules/normalize-wheel/index.js\");\n\n\n\n\n/**\r\n * Compute the dimension of the crop area based on media size,\r\n * aspect ratio and optionally rotation\r\n */\nfunction getCropSize(mediaWidth, mediaHeight, containerWidth, containerHeight, aspect, rotation) {\n if (rotation === void 0) {\n rotation = 0;\n }\n var _a = rotateSize(mediaWidth, mediaHeight, rotation),\n width = _a.width,\n height = _a.height;\n var fittingWidth = Math.min(width, containerWidth);\n var fittingHeight = Math.min(height, containerHeight);\n if (fittingWidth > fittingHeight * aspect) {\n return {\n width: fittingHeight * aspect,\n height: fittingHeight\n };\n }\n return {\n width: fittingWidth,\n height: fittingWidth / aspect\n };\n}\n/**\r\n * Compute media zoom.\r\n * We fit the media into the container with \"max-width: 100%; max-height: 100%;\"\r\n */\nfunction getMediaZoom(mediaSize) {\n // Take the axis with more pixels to improve accuracy\n return mediaSize.width > mediaSize.height ? mediaSize.width / mediaSize.naturalWidth : mediaSize.height / mediaSize.naturalHeight;\n}\n/**\r\n * Ensure a new media position stays in the crop area.\r\n */\nfunction restrictPosition(position, mediaSize, cropSize, zoom, rotation) {\n if (rotation === void 0) {\n rotation = 0;\n }\n var _a = rotateSize(mediaSize.width, mediaSize.height, rotation),\n width = _a.width,\n height = _a.height;\n return {\n x: restrictPositionCoord(position.x, width, cropSize.width, zoom),\n y: restrictPositionCoord(position.y, height, cropSize.height, zoom)\n };\n}\nfunction restrictPositionCoord(position, mediaSize, cropSize, zoom) {\n var maxPosition = mediaSize * zoom / 2 - cropSize / 2;\n return clamp(position, -maxPosition, maxPosition);\n}\nfunction getDistanceBetweenPoints(pointA, pointB) {\n return Math.sqrt(Math.pow(pointA.y - pointB.y, 2) + Math.pow(pointA.x - pointB.x, 2));\n}\nfunction getRotationBetweenPoints(pointA, pointB) {\n return Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 180 / Math.PI;\n}\n/**\r\n * Compute the output cropped area of the media in percentages and pixels.\r\n * x/y are the top-left coordinates on the src media\r\n */\nfunction computeCroppedArea(crop, mediaSize, cropSize, aspect, zoom, rotation, restrictPosition) {\n if (rotation === void 0) {\n rotation = 0;\n }\n if (restrictPosition === void 0) {\n restrictPosition = true;\n }\n // if the media is rotated by the user, we cannot limit the position anymore\n // as it might need to be negative.\n var limitAreaFn = restrictPosition ? limitArea : noOp;\n var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation);\n var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation);\n // calculate the crop area in percentages\n // in the rotated space\n var croppedAreaPercentages = {\n x: limitAreaFn(100, ((mediaBBoxSize.width - cropSize.width / zoom) / 2 - crop.x / zoom) / mediaBBoxSize.width * 100),\n y: limitAreaFn(100, ((mediaBBoxSize.height - cropSize.height / zoom) / 2 - crop.y / zoom) / mediaBBoxSize.height * 100),\n width: limitAreaFn(100, cropSize.width / mediaBBoxSize.width * 100 / zoom),\n height: limitAreaFn(100, cropSize.height / mediaBBoxSize.height * 100 / zoom)\n };\n // we compute the pixels size naively\n var widthInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.width, croppedAreaPercentages.width * mediaNaturalBBoxSize.width / 100));\n var heightInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.height, croppedAreaPercentages.height * mediaNaturalBBoxSize.height / 100));\n var isImgWiderThanHigh = mediaNaturalBBoxSize.width >= mediaNaturalBBoxSize.height * aspect;\n // then we ensure the width and height exactly match the aspect (to avoid rounding approximations)\n // if the media is wider than high, when zoom is 0, the crop height will be equals to image height\n // thus we want to compute the width from the height and aspect for accuracy.\n // Otherwise, we compute the height from width and aspect.\n var sizePixels = isImgWiderThanHigh ? {\n width: Math.round(heightInPixels * aspect),\n height: heightInPixels\n } : {\n width: widthInPixels,\n height: Math.round(widthInPixels / aspect)\n };\n var croppedAreaPixels = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, sizePixels), {\n x: Math.round(limitAreaFn(mediaNaturalBBoxSize.width - sizePixels.width, croppedAreaPercentages.x * mediaNaturalBBoxSize.width / 100)),\n y: Math.round(limitAreaFn(mediaNaturalBBoxSize.height - sizePixels.height, croppedAreaPercentages.y * mediaNaturalBBoxSize.height / 100))\n });\n return {\n croppedAreaPercentages: croppedAreaPercentages,\n croppedAreaPixels: croppedAreaPixels\n };\n}\n/**\r\n * Ensure the returned value is between 0 and max\r\n */\nfunction limitArea(max, value) {\n return Math.min(max, Math.max(0, value));\n}\nfunction noOp(_max, value) {\n return value;\n}\n/**\r\n * Compute crop and zoom from the croppedAreaPercentages.\r\n */\nfunction getInitialCropFromCroppedAreaPercentages(croppedAreaPercentages, mediaSize, rotation, cropSize, minZoom, maxZoom) {\n var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation);\n // This is the inverse process of computeCroppedArea\n var zoom = clamp(cropSize.width / mediaBBoxSize.width * (100 / croppedAreaPercentages.width), minZoom, maxZoom);\n var crop = {\n x: zoom * mediaBBoxSize.width / 2 - cropSize.width / 2 - mediaBBoxSize.width * zoom * (croppedAreaPercentages.x / 100),\n y: zoom * mediaBBoxSize.height / 2 - cropSize.height / 2 - mediaBBoxSize.height * zoom * (croppedAreaPercentages.y / 100)\n };\n return {\n crop: crop,\n zoom: zoom\n };\n}\n/**\r\n * Compute zoom from the croppedAreaPixels\r\n */\nfunction getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize) {\n var mediaZoom = getMediaZoom(mediaSize);\n return cropSize.height > cropSize.width ? cropSize.height / (croppedAreaPixels.height * mediaZoom) : cropSize.width / (croppedAreaPixels.width * mediaZoom);\n}\n/**\r\n * Compute crop and zoom from the croppedAreaPixels\r\n */\nfunction getInitialCropFromCroppedAreaPixels(croppedAreaPixels, mediaSize, rotation, cropSize, minZoom, maxZoom) {\n if (rotation === void 0) {\n rotation = 0;\n }\n var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation);\n var zoom = clamp(getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize), minZoom, maxZoom);\n var cropZoom = cropSize.height > cropSize.width ? cropSize.height / croppedAreaPixels.height : cropSize.width / croppedAreaPixels.width;\n var crop = {\n x: ((mediaNaturalBBoxSize.width - croppedAreaPixels.width) / 2 - croppedAreaPixels.x) * cropZoom,\n y: ((mediaNaturalBBoxSize.height - croppedAreaPixels.height) / 2 - croppedAreaPixels.y) * cropZoom\n };\n return {\n crop: crop,\n zoom: zoom\n };\n}\n/**\r\n * Return the point that is the center of point a and b\r\n */\nfunction getCenter(a, b) {\n return {\n x: (b.x + a.x) / 2,\n y: (b.y + a.y) / 2\n };\n}\nfunction getRadianAngle(degreeValue) {\n return degreeValue * Math.PI / 180;\n}\n/**\r\n * Returns the new bounding area of a rotated rectangle.\r\n */\nfunction rotateSize(width, height, rotation) {\n var rotRad = getRadianAngle(rotation);\n return {\n width: Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height),\n height: Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height)\n };\n}\n/**\r\n * Clamp value between min and max\r\n */\nfunction clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n/**\r\n * Combine multiple class names into a single string.\r\n */\nfunction classNames() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n return args.filter(function (value) {\n if (typeof value === 'string' && value.length > 0) {\n return true;\n }\n return false;\n }).join(' ').trim();\n}\n\nvar css_248z = \".reactEasyCrop_Container {\\n position: absolute;\\n top: 0;\\n left: 0;\\n right: 0;\\n bottom: 0;\\n overflow: hidden;\\n user-select: none;\\n touch-action: none;\\n cursor: move;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n}\\n\\n.reactEasyCrop_Image,\\n.reactEasyCrop_Video {\\n will-change: transform; /* this improves performances and prevent painting issues on iOS Chrome */\\n}\\n\\n.reactEasyCrop_Contain {\\n max-width: 100%;\\n max-height: 100%;\\n margin: auto;\\n position: absolute;\\n top: 0;\\n bottom: 0;\\n left: 0;\\n right: 0;\\n}\\n.reactEasyCrop_Cover_Horizontal {\\n width: 100%;\\n height: auto;\\n}\\n.reactEasyCrop_Cover_Vertical {\\n width: auto;\\n height: 100%;\\n}\\n\\n.reactEasyCrop_CropArea {\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n transform: translate(-50%, -50%);\\n border: 1px solid rgba(255, 255, 255, 0.5);\\n box-sizing: border-box;\\n box-shadow: 0 0 0 9999em;\\n color: rgba(0, 0, 0, 0.5);\\n overflow: hidden;\\n}\\n\\n.reactEasyCrop_CropAreaRound {\\n border-radius: 50%;\\n}\\n\\n.reactEasyCrop_CropAreaGrid::before {\\n content: ' ';\\n box-sizing: border-box;\\n position: absolute;\\n border: 1px solid rgba(255, 255, 255, 0.5);\\n top: 0;\\n bottom: 0;\\n left: 33.33%;\\n right: 33.33%;\\n border-top: 0;\\n border-bottom: 0;\\n}\\n\\n.reactEasyCrop_CropAreaGrid::after {\\n content: ' ';\\n box-sizing: border-box;\\n position: absolute;\\n border: 1px solid rgba(255, 255, 255, 0.5);\\n top: 33.33%;\\n bottom: 33.33%;\\n left: 0;\\n right: 0;\\n border-left: 0;\\n border-right: 0;\\n}\\n\";\n\nvar MIN_ZOOM = 1;\nvar MAX_ZOOM = 3;\nvar KEYBOARD_STEP = 1;\nvar Cropper = /** @class */function (_super) {\n (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(Cropper, _super);\n function Cropper() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.cropperRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();\n _this.imageRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();\n _this.videoRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();\n _this.containerPosition = {\n x: 0,\n y: 0\n };\n _this.containerRef = null;\n _this.styleRef = null;\n _this.containerRect = null;\n _this.mediaSize = {\n width: 0,\n height: 0,\n naturalWidth: 0,\n naturalHeight: 0\n };\n _this.dragStartPosition = {\n x: 0,\n y: 0\n };\n _this.dragStartCrop = {\n x: 0,\n y: 0\n };\n _this.gestureZoomStart = 0;\n _this.gestureRotationStart = 0;\n _this.isTouching = false;\n _this.lastPinchDistance = 0;\n _this.lastPinchRotation = 0;\n _this.rafDragTimeout = null;\n _this.rafPinchTimeout = null;\n _this.wheelTimer = null;\n _this.currentDoc = typeof document !== 'undefined' ? document : null;\n _this.currentWindow = typeof window !== 'undefined' ? window : null;\n _this.resizeObserver = null;\n _this.previousCropSize = null;\n _this.isInitialized = false;\n _this.state = {\n cropSize: null,\n hasWheelJustStarted: false,\n mediaObjectFit: undefined\n };\n _this.initResizeObserver = function () {\n if (typeof window.ResizeObserver === 'undefined' || !_this.containerRef) {\n return;\n }\n var isFirstResize = true;\n _this.resizeObserver = new window.ResizeObserver(function (entries) {\n if (isFirstResize) {\n isFirstResize = false; // observe() is called on mount, we don't want to trigger a recompute on mount\n return;\n }\n _this.computeSizes();\n });\n _this.resizeObserver.observe(_this.containerRef);\n };\n // this is to prevent Safari on iOS >= 10 to zoom the page\n _this.preventZoomSafari = function (e) {\n return e.preventDefault();\n };\n _this.cleanEvents = function () {\n if (!_this.currentDoc) return;\n _this.currentDoc.removeEventListener('mousemove', _this.onMouseMove);\n _this.currentDoc.removeEventListener('mouseup', _this.onDragStopped);\n _this.currentDoc.removeEventListener('touchmove', _this.onTouchMove);\n _this.currentDoc.removeEventListener('touchend', _this.onDragStopped);\n _this.currentDoc.removeEventListener('gesturechange', _this.onGestureChange);\n _this.currentDoc.removeEventListener('gestureend', _this.onGestureEnd);\n _this.currentDoc.removeEventListener('scroll', _this.onScroll);\n };\n _this.clearScrollEvent = function () {\n if (_this.containerRef) _this.containerRef.removeEventListener('wheel', _this.onWheel);\n if (_this.wheelTimer) {\n clearTimeout(_this.wheelTimer);\n }\n };\n _this.onMediaLoad = function () {\n var cropSize = _this.computeSizes();\n if (cropSize) {\n _this.previousCropSize = cropSize;\n _this.emitCropData();\n _this.setInitialCrop(cropSize);\n _this.isInitialized = true;\n }\n if (_this.props.onMediaLoaded) {\n _this.props.onMediaLoaded(_this.mediaSize);\n }\n };\n _this.setInitialCrop = function (cropSize) {\n if (_this.props.initialCroppedAreaPercentages) {\n var _a = getInitialCropFromCroppedAreaPercentages(_this.props.initialCroppedAreaPercentages, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom),\n crop = _a.crop,\n zoom = _a.zoom;\n _this.props.onCropChange(crop);\n _this.props.onZoomChange && _this.props.onZoomChange(zoom);\n } else if (_this.props.initialCroppedAreaPixels) {\n var _b = getInitialCropFromCroppedAreaPixels(_this.props.initialCroppedAreaPixels, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom),\n crop = _b.crop,\n zoom = _b.zoom;\n _this.props.onCropChange(crop);\n _this.props.onZoomChange && _this.props.onZoomChange(zoom);\n }\n };\n _this.computeSizes = function () {\n var _a, _b, _c, _d, _e, _f;\n var mediaRef = _this.imageRef.current || _this.videoRef.current;\n if (mediaRef && _this.containerRef) {\n _this.containerRect = _this.containerRef.getBoundingClientRect();\n _this.saveContainerPosition();\n var containerAspect = _this.containerRect.width / _this.containerRect.height;\n var naturalWidth = ((_a = _this.imageRef.current) === null || _a === void 0 ? void 0 : _a.naturalWidth) || ((_b = _this.videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth) || 0;\n var naturalHeight = ((_c = _this.imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalHeight) || ((_d = _this.videoRef.current) === null || _d === void 0 ? void 0 : _d.videoHeight) || 0;\n var isMediaScaledDown = mediaRef.offsetWidth < naturalWidth || mediaRef.offsetHeight < naturalHeight;\n var mediaAspect = naturalWidth / naturalHeight;\n // We do not rely on the offsetWidth/offsetHeight if the media is scaled down\n // as the values they report are rounded. That will result in precision losses\n // when calculating zoom. We use the fact that the media is positionned relative\n // to the container. That allows us to use the container's dimensions\n // and natural aspect ratio of the media to calculate accurate media size.\n // However, for this to work, the container should not be rotated\n var renderedMediaSize = void 0;\n if (isMediaScaledDown) {\n switch (_this.state.mediaObjectFit) {\n default:\n case 'contain':\n renderedMediaSize = containerAspect > mediaAspect ? {\n width: _this.containerRect.height * mediaAspect,\n height: _this.containerRect.height\n } : {\n width: _this.containerRect.width,\n height: _this.containerRect.width / mediaAspect\n };\n break;\n case 'horizontal-cover':\n renderedMediaSize = {\n width: _this.containerRect.width,\n height: _this.containerRect.width / mediaAspect\n };\n break;\n case 'vertical-cover':\n renderedMediaSize = {\n width: _this.containerRect.height * mediaAspect,\n height: _this.containerRect.height\n };\n break;\n }\n } else {\n renderedMediaSize = {\n width: mediaRef.offsetWidth,\n height: mediaRef.offsetHeight\n };\n }\n _this.mediaSize = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, renderedMediaSize), {\n naturalWidth: naturalWidth,\n naturalHeight: naturalHeight\n });\n // set media size in the parent\n if (_this.props.setMediaSize) {\n _this.props.setMediaSize(_this.mediaSize);\n }\n var cropSize = _this.props.cropSize ? _this.props.cropSize : getCropSize(_this.mediaSize.width, _this.mediaSize.height, _this.containerRect.width, _this.containerRect.height, _this.props.aspect, _this.props.rotation);\n if (((_e = _this.state.cropSize) === null || _e === void 0 ? void 0 : _e.height) !== cropSize.height || ((_f = _this.state.cropSize) === null || _f === void 0 ? void 0 : _f.width) !== cropSize.width) {\n _this.props.onCropSizeChange && _this.props.onCropSizeChange(cropSize);\n }\n _this.setState({\n cropSize: cropSize\n }, _this.recomputeCropPosition);\n // pass crop size to parent\n if (_this.props.setCropSize) {\n _this.props.setCropSize(cropSize);\n }\n return cropSize;\n }\n };\n _this.saveContainerPosition = function () {\n if (_this.containerRef) {\n var bounds = _this.containerRef.getBoundingClientRect();\n _this.containerPosition = {\n x: bounds.left,\n y: bounds.top\n };\n }\n };\n _this.onMouseDown = function (e) {\n if (!_this.currentDoc) return;\n e.preventDefault();\n _this.currentDoc.addEventListener('mousemove', _this.onMouseMove);\n _this.currentDoc.addEventListener('mouseup', _this.onDragStopped);\n _this.saveContainerPosition();\n _this.onDragStart(Cropper.getMousePoint(e));\n };\n _this.onMouseMove = function (e) {\n return _this.onDrag(Cropper.getMousePoint(e));\n };\n _this.onScroll = function (e) {\n if (!_this.currentDoc) return;\n e.preventDefault();\n _this.saveContainerPosition();\n };\n _this.onTouchStart = function (e) {\n if (!_this.currentDoc) return;\n _this.isTouching = true;\n if (_this.props.onTouchRequest && !_this.props.onTouchRequest(e)) {\n return;\n }\n _this.currentDoc.addEventListener('touchmove', _this.onTouchMove, {\n passive: false\n }); // iOS 11 now defaults to passive: true\n _this.currentDoc.addEventListener('touchend', _this.onDragStopped);\n _this.saveContainerPosition();\n if (e.touches.length === 2) {\n _this.onPinchStart(e);\n } else if (e.touches.length === 1) {\n _this.onDragStart(Cropper.getTouchPoint(e.touches[0]));\n }\n };\n _this.onTouchMove = function (e) {\n // Prevent whole page from scrolling on iOS.\n e.preventDefault();\n if (e.touches.length === 2) {\n _this.onPinchMove(e);\n } else if (e.touches.length === 1) {\n _this.onDrag(Cropper.getTouchPoint(e.touches[0]));\n }\n };\n _this.onGestureStart = function (e) {\n if (!_this.currentDoc) return;\n e.preventDefault();\n _this.currentDoc.addEventListener('gesturechange', _this.onGestureChange);\n _this.currentDoc.addEventListener('gestureend', _this.onGestureEnd);\n _this.gestureZoomStart = _this.props.zoom;\n _this.gestureRotationStart = _this.props.rotation;\n };\n _this.onGestureChange = function (e) {\n e.preventDefault();\n if (_this.isTouching) {\n // this is to avoid conflict between gesture and touch events\n return;\n }\n var point = Cropper.getMousePoint(e);\n var newZoom = _this.gestureZoomStart - 1 + e.scale;\n _this.setNewZoom(newZoom, point, {\n shouldUpdatePosition: true\n });\n if (_this.props.onRotationChange) {\n var newRotation = _this.gestureRotationStart + e.rotation;\n _this.props.onRotationChange(newRotation);\n }\n };\n _this.onGestureEnd = function (e) {\n _this.cleanEvents();\n };\n _this.onDragStart = function (_a) {\n var _b, _c;\n var x = _a.x,\n y = _a.y;\n _this.dragStartPosition = {\n x: x,\n y: y\n };\n _this.dragStartCrop = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, _this.props.crop);\n (_c = (_b = _this.props).onInteractionStart) === null || _c === void 0 ? void 0 : _c.call(_b);\n };\n _this.onDrag = function (_a) {\n var x = _a.x,\n y = _a.y;\n if (!_this.currentWindow) return;\n if (_this.rafDragTimeout) _this.currentWindow.cancelAnimationFrame(_this.rafDragTimeout);\n _this.rafDragTimeout = _this.currentWindow.requestAnimationFrame(function () {\n if (!_this.state.cropSize) return;\n if (x === undefined || y === undefined) return;\n var offsetX = x - _this.dragStartPosition.x;\n var offsetY = y - _this.dragStartPosition.y;\n var requestedPosition = {\n x: _this.dragStartCrop.x + offsetX,\n y: _this.dragStartCrop.y + offsetY\n };\n var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : requestedPosition;\n _this.props.onCropChange(newPosition);\n });\n };\n _this.onDragStopped = function () {\n var _a, _b;\n _this.isTouching = false;\n _this.cleanEvents();\n _this.emitCropData();\n (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a);\n };\n _this.onWheel = function (e) {\n if (!_this.currentWindow) return;\n if (_this.props.onWheelRequest && !_this.props.onWheelRequest(e)) {\n return;\n }\n e.preventDefault();\n var point = Cropper.getMousePoint(e);\n var pixelY = normalize_wheel__WEBPACK_IMPORTED_MODULE_1__(e).pixelY;\n var newZoom = _this.props.zoom - pixelY * _this.props.zoomSpeed / 200;\n _this.setNewZoom(newZoom, point, {\n shouldUpdatePosition: true\n });\n if (!_this.state.hasWheelJustStarted) {\n _this.setState({\n hasWheelJustStarted: true\n }, function () {\n var _a, _b;\n return (_b = (_a = _this.props).onInteractionStart) === null || _b === void 0 ? void 0 : _b.call(_a);\n });\n }\n if (_this.wheelTimer) {\n clearTimeout(_this.wheelTimer);\n }\n _this.wheelTimer = _this.currentWindow.setTimeout(function () {\n return _this.setState({\n hasWheelJustStarted: false\n }, function () {\n var _a, _b;\n return (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a);\n });\n }, 250);\n };\n _this.getPointOnContainer = function (_a, containerTopLeft) {\n var x = _a.x,\n y = _a.y;\n if (!_this.containerRect) {\n throw new Error('The Cropper is not mounted');\n }\n return {\n x: _this.containerRect.width / 2 - (x - containerTopLeft.x),\n y: _this.containerRect.height / 2 - (y - containerTopLeft.y)\n };\n };\n _this.getPointOnMedia = function (_a) {\n var x = _a.x,\n y = _a.y;\n var _b = _this.props,\n crop = _b.crop,\n zoom = _b.zoom;\n return {\n x: (x + crop.x) / zoom,\n y: (y + crop.y) / zoom\n };\n };\n _this.setNewZoom = function (zoom, point, _a) {\n var _b = _a === void 0 ? {} : _a,\n _c = _b.shouldUpdatePosition,\n shouldUpdatePosition = _c === void 0 ? true : _c;\n if (!_this.state.cropSize || !_this.props.onZoomChange) return;\n var newZoom = clamp(zoom, _this.props.minZoom, _this.props.maxZoom);\n if (shouldUpdatePosition) {\n var zoomPoint = _this.getPointOnContainer(point, _this.containerPosition);\n var zoomTarget = _this.getPointOnMedia(zoomPoint);\n var requestedPosition = {\n x: zoomTarget.x * newZoom - zoomPoint.x,\n y: zoomTarget.y * newZoom - zoomPoint.y\n };\n var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, newZoom, _this.props.rotation) : requestedPosition;\n _this.props.onCropChange(newPosition);\n }\n _this.props.onZoomChange(newZoom);\n };\n _this.getCropData = function () {\n if (!_this.state.cropSize) {\n return null;\n }\n // this is to ensure the crop is correctly restricted after a zoom back (https://github.com/ValentinH/react-easy-crop/issues/6)\n var restrictedPosition = _this.props.restrictPosition ? restrictPosition(_this.props.crop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : _this.props.crop;\n return computeCroppedArea(restrictedPosition, _this.mediaSize, _this.state.cropSize, _this.getAspect(), _this.props.zoom, _this.props.rotation, _this.props.restrictPosition);\n };\n _this.emitCropData = function () {\n var cropData = _this.getCropData();\n if (!cropData) return;\n var croppedAreaPercentages = cropData.croppedAreaPercentages,\n croppedAreaPixels = cropData.croppedAreaPixels;\n if (_this.props.onCropComplete) {\n _this.props.onCropComplete(croppedAreaPercentages, croppedAreaPixels);\n }\n if (_this.props.onCropAreaChange) {\n _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels);\n }\n };\n _this.emitCropAreaChange = function () {\n var cropData = _this.getCropData();\n if (!cropData) return;\n var croppedAreaPercentages = cropData.croppedAreaPercentages,\n croppedAreaPixels = cropData.croppedAreaPixels;\n if (_this.props.onCropAreaChange) {\n _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels);\n }\n };\n _this.recomputeCropPosition = function () {\n var _a, _b;\n if (!_this.state.cropSize) return;\n var adjustedCrop = _this.props.crop;\n // Only scale if we're initialized and this is a legitimate resize\n if (_this.isInitialized && ((_a = _this.previousCropSize) === null || _a === void 0 ? void 0 : _a.width) && ((_b = _this.previousCropSize) === null || _b === void 0 ? void 0 : _b.height)) {\n var sizeChanged = Math.abs(_this.previousCropSize.width - _this.state.cropSize.width) > 1e-6 || Math.abs(_this.previousCropSize.height - _this.state.cropSize.height) > 1e-6;\n if (sizeChanged) {\n var scaleX = _this.state.cropSize.width / _this.previousCropSize.width;\n var scaleY = _this.state.cropSize.height / _this.previousCropSize.height;\n adjustedCrop = {\n x: _this.props.crop.x * scaleX,\n y: _this.props.crop.y * scaleY\n };\n }\n }\n var newPosition = _this.props.restrictPosition ? restrictPosition(adjustedCrop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : adjustedCrop;\n _this.previousCropSize = _this.state.cropSize;\n _this.props.onCropChange(newPosition);\n _this.emitCropData();\n };\n _this.onKeyDown = function (event) {\n var _a, _b;\n var _c = _this.props,\n crop = _c.crop,\n onCropChange = _c.onCropChange,\n keyboardStep = _c.keyboardStep,\n zoom = _c.zoom,\n rotation = _c.rotation;\n var step = keyboardStep;\n if (!_this.state.cropSize) return;\n // if the shift key is pressed, reduce the step to allow finer control\n if (event.shiftKey) {\n step *= 0.2;\n }\n var newCrop = (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, crop);\n switch (event.key) {\n case 'ArrowUp':\n newCrop.y -= step;\n event.preventDefault();\n break;\n case 'ArrowDown':\n newCrop.y += step;\n event.preventDefault();\n break;\n case 'ArrowLeft':\n newCrop.x -= step;\n event.preventDefault();\n break;\n case 'ArrowRight':\n newCrop.x += step;\n event.preventDefault();\n break;\n default:\n return;\n }\n if (_this.props.restrictPosition) {\n newCrop = restrictPosition(newCrop, _this.mediaSize, _this.state.cropSize, zoom, rotation);\n }\n if (!event.repeat) {\n (_b = (_a = _this.props).onInteractionStart) === null || _b === void 0 ? void 0 : _b.call(_a);\n }\n onCropChange(newCrop);\n };\n _this.onKeyUp = function (event) {\n var _a, _b;\n switch (event.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n case 'ArrowLeft':\n case 'ArrowRight':\n event.preventDefault();\n break;\n default:\n return;\n }\n _this.emitCropData();\n (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a);\n };\n return _this;\n }\n Cropper.prototype.componentDidMount = function () {\n if (!this.currentDoc || !this.currentWindow) return;\n if (this.containerRef) {\n if (this.containerRef.ownerDocument) {\n this.currentDoc = this.containerRef.ownerDocument;\n }\n if (this.currentDoc.defaultView) {\n this.currentWindow = this.currentDoc.defaultView;\n }\n this.initResizeObserver();\n // only add window resize listener if ResizeObserver is not supported. Otherwise, it would be redundant\n if (typeof window.ResizeObserver === 'undefined') {\n this.currentWindow.addEventListener('resize', this.computeSizes);\n }\n this.props.zoomWithScroll && this.containerRef.addEventListener('wheel', this.onWheel, {\n passive: false\n });\n this.containerRef.addEventListener('gesturestart', this.onGestureStart);\n }\n this.currentDoc.addEventListener('scroll', this.onScroll);\n if (!this.props.disableAutomaticStylesInjection) {\n this.styleRef = this.currentDoc.createElement('style');\n this.styleRef.setAttribute('type', 'text/css');\n if (this.props.nonce) {\n this.styleRef.setAttribute('nonce', this.props.nonce);\n }\n this.styleRef.innerHTML = css_248z;\n this.currentDoc.head.appendChild(this.styleRef);\n }\n // when rendered via SSR, the image can already be loaded and its onLoad callback will never be called\n if (this.imageRef.current && this.imageRef.current.complete) {\n this.onMediaLoad();\n }\n // set image and video refs in the parent if the callbacks exist\n if (this.props.setImageRef) {\n this.props.setImageRef(this.imageRef);\n }\n if (this.props.setVideoRef) {\n this.props.setVideoRef(this.videoRef);\n }\n if (this.props.setCropperRef) {\n this.props.setCropperRef(this.cropperRef);\n }\n };\n Cropper.prototype.componentWillUnmount = function () {\n var _a, _b;\n if (!this.currentDoc || !this.currentWindow) return;\n if (typeof window.ResizeObserver === 'undefined') {\n this.currentWindow.removeEventListener('resize', this.computeSizes);\n }\n (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();\n if (this.containerRef) {\n this.containerRef.removeEventListener('gesturestart', this.preventZoomSafari);\n }\n if (this.styleRef) {\n (_b = this.styleRef.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.styleRef);\n }\n this.cleanEvents();\n this.props.zoomWithScroll && this.clearScrollEvent();\n };\n Cropper.prototype.componentDidUpdate = function (prevProps) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (prevProps.rotation !== this.props.rotation) {\n this.computeSizes();\n this.recomputeCropPosition();\n } else if (prevProps.aspect !== this.props.aspect) {\n this.computeSizes();\n } else if (prevProps.objectFit !== this.props.objectFit) {\n this.computeSizes();\n } else if (prevProps.zoom !== this.props.zoom) {\n this.recomputeCropPosition();\n } else if (((_a = prevProps.cropSize) === null || _a === void 0 ? void 0 : _a.height) !== ((_b = this.props.cropSize) === null || _b === void 0 ? void 0 : _b.height) || ((_c = prevProps.cropSize) === null || _c === void 0 ? void 0 : _c.width) !== ((_d = this.props.cropSize) === null || _d === void 0 ? void 0 : _d.width)) {\n this.computeSizes();\n } else if (((_e = prevProps.crop) === null || _e === void 0 ? void 0 : _e.x) !== ((_f = this.props.crop) === null || _f === void 0 ? void 0 : _f.x) || ((_g = prevProps.crop) === null || _g === void 0 ? void 0 : _g.y) !== ((_h = this.props.crop) === null || _h === void 0 ? void 0 : _h.y)) {\n this.emitCropAreaChange();\n }\n if (prevProps.zoomWithScroll !== this.props.zoomWithScroll && this.containerRef) {\n this.props.zoomWithScroll ? this.containerRef.addEventListener('wheel', this.onWheel, {\n passive: false\n }) : this.clearScrollEvent();\n }\n if (prevProps.video !== this.props.video) {\n (_j = this.videoRef.current) === null || _j === void 0 ? void 0 : _j.load();\n }\n var objectFit = this.getObjectFit();\n if (objectFit !== this.state.mediaObjectFit) {\n this.setState({\n mediaObjectFit: objectFit\n }, this.computeSizes);\n }\n };\n Cropper.prototype.getAspect = function () {\n var _a = this.props,\n cropSize = _a.cropSize,\n aspect = _a.aspect;\n if (cropSize) {\n return cropSize.width / cropSize.height;\n }\n return aspect;\n };\n Cropper.prototype.getObjectFit = function () {\n var _a, _b, _c, _d;\n if (this.props.objectFit === 'cover') {\n var mediaRef = this.imageRef.current || this.videoRef.current;\n if (mediaRef && this.containerRef) {\n this.containerRect = this.containerRef.getBoundingClientRect();\n var containerAspect = this.containerRect.width / this.containerRect.height;\n var naturalWidth = ((_a = this.imageRef.current) === null || _a === void 0 ? void 0 : _a.naturalWidth) || ((_b = this.videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth) || 0;\n var naturalHeight = ((_c = this.imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalHeight) || ((_d = this.videoRef.current) === null || _d === void 0 ? void 0 : _d.videoHeight) || 0;\n var mediaAspect = naturalWidth / naturalHeight;\n return mediaAspect < containerAspect ? 'horizontal-cover' : 'vertical-cover';\n }\n return 'horizontal-cover';\n }\n return this.props.objectFit;\n };\n Cropper.prototype.onPinchStart = function (e) {\n var pointA = Cropper.getTouchPoint(e.touches[0]);\n var pointB = Cropper.getTouchPoint(e.touches[1]);\n this.lastPinchDistance = getDistanceBetweenPoints(pointA, pointB);\n this.lastPinchRotation = getRotationBetweenPoints(pointA, pointB);\n this.onDragStart(getCenter(pointA, pointB));\n };\n Cropper.prototype.onPinchMove = function (e) {\n var _this = this;\n if (!this.currentDoc || !this.currentWindow) return;\n var pointA = Cropper.getTouchPoint(e.touches[0]);\n var pointB = Cropper.getTouchPoint(e.touches[1]);\n var center = getCenter(pointA, pointB);\n this.onDrag(center);\n if (this.rafPinchTimeout) this.currentWindow.cancelAnimationFrame(this.rafPinchTimeout);\n this.rafPinchTimeout = this.currentWindow.requestAnimationFrame(function () {\n var distance = getDistanceBetweenPoints(pointA, pointB);\n var newZoom = _this.props.zoom * (distance / _this.lastPinchDistance);\n _this.setNewZoom(newZoom, center, {\n shouldUpdatePosition: false\n });\n _this.lastPinchDistance = distance;\n var rotation = getRotationBetweenPoints(pointA, pointB);\n var newRotation = _this.props.rotation + (rotation - _this.lastPinchRotation);\n _this.props.onRotationChange && _this.props.onRotationChange(newRotation);\n _this.lastPinchRotation = rotation;\n });\n };\n Cropper.prototype.render = function () {\n var _this = this;\n var _a;\n var _b = this.props,\n image = _b.image,\n video = _b.video,\n mediaProps = _b.mediaProps,\n cropperProps = _b.cropperProps,\n transform = _b.transform,\n _c = _b.crop,\n x = _c.x,\n y = _c.y,\n rotation = _b.rotation,\n zoom = _b.zoom,\n cropShape = _b.cropShape,\n showGrid = _b.showGrid,\n roundCropAreaPixels = _b.roundCropAreaPixels,\n _d = _b.style,\n containerStyle = _d.containerStyle,\n cropAreaStyle = _d.cropAreaStyle,\n mediaStyle = _d.mediaStyle,\n _e = _b.classes,\n containerClassName = _e.containerClassName,\n cropAreaClassName = _e.cropAreaClassName,\n mediaClassName = _e.mediaClassName;\n var objectFit = (_a = this.state.mediaObjectFit) !== null && _a !== void 0 ? _a : this.getObjectFit();\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", {\n onMouseDown: this.onMouseDown,\n onTouchStart: this.onTouchStart,\n ref: function ref(el) {\n return _this.containerRef = el;\n },\n \"data-testid\": \"container\",\n style: containerStyle,\n className: classNames('reactEasyCrop_Container', containerClassName)\n }, image ? react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({\n alt: \"\",\n className: classNames('reactEasyCrop_Image', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', mediaClassName)\n }, mediaProps, {\n src: image,\n ref: this.imageRef,\n style: (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, mediaStyle), {\n transform: transform || \"translate(\".concat(x, \"px, \").concat(y, \"px) rotate(\").concat(rotation, \"deg) scale(\").concat(zoom, \")\")\n }),\n onLoad: this.onMediaLoad\n })) : video && react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"video\", (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({\n autoPlay: true,\n playsInline: true,\n loop: true,\n muted: true,\n className: classNames('reactEasyCrop_Video', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', mediaClassName)\n }, mediaProps, {\n ref: this.videoRef,\n onLoadedMetadata: this.onMediaLoad,\n style: (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, mediaStyle), {\n transform: transform || \"translate(\".concat(x, \"px, \").concat(y, \"px) rotate(\").concat(rotation, \"deg) scale(\").concat(zoom, \")\")\n }),\n controls: false\n }), (Array.isArray(video) ? video : [{\n src: video\n }]).map(function (item) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"source\", (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({\n key: item.src\n }, item));\n })), this.state.cropSize && react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({\n ref: this.cropperRef,\n style: (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({}, cropAreaStyle), {\n width: roundCropAreaPixels ? Math.round(this.state.cropSize.width) : this.state.cropSize.width,\n height: roundCropAreaPixels ? Math.round(this.state.cropSize.height) : this.state.cropSize.height\n }),\n tabIndex: 0,\n onKeyDown: this.onKeyDown,\n onKeyUp: this.onKeyUp,\n \"data-testid\": \"cropper\",\n className: classNames('reactEasyCrop_CropArea', cropShape === 'round' && 'reactEasyCrop_CropAreaRound', showGrid && 'reactEasyCrop_CropAreaGrid', cropAreaClassName)\n }, cropperProps)));\n };\n Cropper.defaultProps = {\n zoom: 1,\n rotation: 0,\n aspect: 4 / 3,\n maxZoom: MAX_ZOOM,\n minZoom: MIN_ZOOM,\n cropShape: 'rect',\n objectFit: 'contain',\n showGrid: true,\n style: {},\n classes: {},\n mediaProps: {},\n cropperProps: {},\n zoomSpeed: 1,\n restrictPosition: true,\n zoomWithScroll: true,\n keyboardStep: KEYBOARD_STEP\n };\n Cropper.getMousePoint = function (e) {\n return {\n x: Number(e.clientX),\n y: Number(e.clientY)\n };\n };\n Cropper.getTouchPoint = function (touch) {\n return {\n x: Number(touch.clientX),\n y: Number(touch.clientY)\n };\n };\n return Cropper;\n}(react__WEBPACK_IMPORTED_MODULE_0__.Component);\n\n\n//# sourceMappingURL=index.module.mjs.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvcmVhY3QtZWFzeS1jcm9wL2luZGV4Lm1vZHVsZS5tanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQTRDO0FBQ2I7QUFDYzs7QUFFN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxpQkFBaUI7QUFDL0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsK0NBQVEsQ0FBQywrQ0FBUSxHQUFHO0FBQzlDO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsMENBQTBDLHVCQUF1QixXQUFXLFlBQVksYUFBYSxjQUFjLHFCQUFxQixzQkFBc0IsdUJBQXVCLGlCQUFpQixrQkFBa0IsNEJBQTRCLHdCQUF3QixHQUFHLGlEQUFpRCw0QkFBNEIsNkVBQTZFLDRCQUE0QixvQkFBb0IscUJBQXFCLGlCQUFpQix1QkFBdUIsV0FBVyxjQUFjLFlBQVksYUFBYSxHQUFHLG1DQUFtQyxnQkFBZ0IsaUJBQWlCLEdBQUcsaUNBQWlDLGdCQUFnQixpQkFBaUIsR0FBRyw2QkFBNkIsdUJBQXVCLGNBQWMsYUFBYSxxQ0FBcUMsK0NBQStDLDJCQUEyQiw2QkFBNkIsOEJBQThCLHFCQUFxQixHQUFHLGtDQUFrQyx1QkFBdUIsR0FBRyx5Q0FBeUMsaUJBQWlCLDJCQUEyQix1QkFBdUIsK0NBQStDLFdBQVcsY0FBYyxpQkFBaUIsa0JBQWtCLGtCQUFrQixxQkFBcUIsR0FBRyx3Q0FBd0MsaUJBQWlCLDJCQUEyQix1QkFBdUIsK0NBQStDLGdCQUFnQixtQkFBbUIsWUFBWSxhQUFhLG1CQUFtQixvQkFBb0IsR0FBRzs7QUFFcmlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxnREFBUztBQUNYO0FBQ0E7QUFDQSx1QkFBdUIsNENBQWU7QUFDdEMscUJBQXFCLDRDQUFlO0FBQ3BDLHFCQUFxQiw0Q0FBZTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiwrQ0FBUSxDQUFDLCtDQUFRLEdBQUc7QUFDOUM7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sR0FBRztBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLCtDQUFRLEdBQUc7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw0Q0FBYztBQUNqQztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsK0NBQVEsR0FBRztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGdEQUFtQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLLFVBQVUsZ0RBQW1CLFFBQVEsK0NBQVE7QUFDbEQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsYUFBYSwrQ0FBUSxDQUFDLCtDQUFRLEdBQUc7QUFDakM7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLGNBQWMsZ0RBQW1CLFVBQVUsK0NBQVE7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsYUFBYSwrQ0FBUSxDQUFDLCtDQUFRLEdBQUc7QUFDakM7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0wsYUFBYSxnREFBbUIsV0FBVywrQ0FBUTtBQUNuRDtBQUNBLE9BQU87QUFDUCxLQUFLLDJCQUEyQixnREFBbUIsUUFBUSwrQ0FBUTtBQUNuRTtBQUNBLGFBQWEsK0NBQVEsQ0FBQywrQ0FBUSxHQUFHO0FBQ2pDO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixlQUFlO0FBQ2Ysa0JBQWtCO0FBQ2xCLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLENBQUMsNENBQWU7O0FBRTRGO0FBQzdHIiwic291cmNlcyI6WyJFOlxcR0lUXFxtdnBcXG5hc2hlbC1mcm9udGVuZFxcbm9kZV9tb2R1bGVzXFxyZWFjdC1lYXN5LWNyb3BcXGluZGV4Lm1vZHVsZS5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgX19hc3NpZ24sIF9fZXh0ZW5kcyB9IGZyb20gJ3RzbGliJztcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBub3JtYWxpemVXaGVlbCBmcm9tICdub3JtYWxpemUtd2hlZWwnO1xuXG4vKipcclxuICogQ29tcHV0ZSB0aGUgZGltZW5zaW9uIG9mIHRoZSBjcm9wIGFyZWEgYmFzZWQgb24gbWVkaWEgc2l6ZSxcclxuICogYXNwZWN0IHJhdGlvIGFuZCBvcHRpb25hbGx5IHJvdGF0aW9uXHJcbiAqL1xuZnVuY3Rpb24gZ2V0Q3JvcFNpemUobWVkaWFXaWR0aCwgbWVkaWFIZWlnaHQsIGNvbnRhaW5lcldpZHRoLCBjb250YWluZXJIZWlnaHQsIGFzcGVjdCwgcm90YXRpb24pIHtcbiAgaWYgKHJvdGF0aW9uID09PSB2b2lkIDApIHtcbiAgICByb3RhdGlvbiA9IDA7XG4gIH1cbiAgdmFyIF9hID0gcm90YXRlU2l6ZShtZWRpYVdpZHRoLCBtZWRpYUhlaWdodCwgcm90YXRpb24pLFxuICAgIHdpZHRoID0gX2Eud2lkdGgsXG4gICAgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICB2YXIgZml0dGluZ1dpZHRoID0gTWF0aC5taW4od2lkdGgsIGNvbnRhaW5lcldpZHRoKTtcbiAgdmFyIGZpdHRpbmdIZWlnaHQgPSBNYXRoLm1pbihoZWlnaHQsIGNvbnRhaW5lckhlaWdodCk7XG4gIGlmIChmaXR0aW5nV2lkdGggPiBmaXR0aW5nSGVpZ2h0ICogYXNwZWN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiBmaXR0aW5nSGVpZ2h0ICogYXNwZWN0LFxuICAgICAgaGVpZ2h0OiBmaXR0aW5nSGVpZ2h0XG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHdpZHRoOiBmaXR0aW5nV2lkdGgsXG4gICAgaGVpZ2h0OiBmaXR0aW5nV2lkdGggLyBhc3BlY3RcbiAgfTtcbn1cbi8qKlxyXG4gKiBDb21wdXRlIG1lZGlhIHpvb20uXHJcbiAqIFdlIGZpdCB0aGUgbWVkaWEgaW50byB0aGUgY29udGFpbmVyIHdpdGggXCJtYXgtd2lkdGg6IDEwMCU7IG1heC1oZWlnaHQ6IDEwMCU7XCJcclxuICovXG5mdW5jdGlvbiBnZXRNZWRpYVpvb20obWVkaWFTaXplKSB7XG4gIC8vIFRha2UgdGhlIGF4aXMgd2l0aCBtb3JlIHBpeGVscyB0byBpbXByb3ZlIGFjY3VyYWN5XG4gIHJldHVybiBtZWRpYVNpemUud2lkdGggPiBtZWRpYVNpemUuaGVpZ2h0ID8gbWVkaWFTaXplLndpZHRoIC8gbWVkaWFTaXplLm5hdHVyYWxXaWR0aCA6IG1lZGlhU2l6ZS5oZWlnaHQgLyBtZWRpYVNpemUubmF0dXJhbEhlaWdodDtcbn1cbi8qKlxyXG4gKiBFbnN1cmUgYSBuZXcgbWVkaWEgcG9zaXRpb24gc3RheXMgaW4gdGhlIGNyb3AgYXJlYS5cclxuICovXG5mdW5jdGlvbiByZXN0cmljdFBvc2l0aW9uKHBvc2l0aW9uLCBtZWRpYVNpemUsIGNyb3BTaXplLCB6b29tLCByb3RhdGlvbikge1xuICBpZiAocm90YXRpb24gPT09IHZvaWQgMCkge1xuICAgIHJvdGF0aW9uID0gMDtcbiAgfVxuICB2YXIgX2EgPSByb3RhdGVTaXplKG1lZGlhU2l6ZS53aWR0aCwgbWVkaWFTaXplLmhlaWdodCwgcm90YXRpb24pLFxuICAgIHdpZHRoID0gX2Eud2lkdGgsXG4gICAgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xuICByZXR1cm4ge1xuICAgIHg6IHJlc3RyaWN0UG9zaXRpb25Db29yZChwb3NpdGlvbi54LCB3aWR0aCwgY3JvcFNpemUud2lkdGgsIHpvb20pLFxuICAgIHk6IHJlc3RyaWN0UG9zaXRpb25Db29yZChwb3NpdGlvbi55LCBoZWlnaHQsIGNyb3BTaXplLmhlaWdodCwgem9vbSlcbiAgfTtcbn1cbmZ1bmN0aW9uIHJlc3RyaWN0UG9zaXRpb25Db29yZChwb3NpdGlvbiwgbWVkaWFTaXplLCBjcm9wU2l6ZSwgem9vbSkge1xuICB2YXIgbWF4UG9zaXRpb24gPSBtZWRpYVNpemUgKiB6b29tIC8gMiAtIGNyb3BTaXplIC8gMjtcbiAgcmV0dXJuIGNsYW1wKHBvc2l0aW9uLCAtbWF4UG9zaXRpb24sIG1heFBvc2l0aW9uKTtcbn1cbmZ1bmN0aW9uIGdldERpc3RhbmNlQmV0d2VlblBvaW50cyhwb2ludEEsIHBvaW50Qikge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHBvaW50QS55IC0gcG9pbnRCLnksIDIpICsgTWF0aC5wb3cocG9pbnRBLnggLSBwb2ludEIueCwgMikpO1xufVxuZnVuY3Rpb24gZ2V0Um90YXRpb25CZXR3ZWVuUG9pbnRzKHBvaW50QSwgcG9pbnRCKSB7XG4gIHJldHVybiBNYXRoLmF0YW4yKHBvaW50Qi55IC0gcG9pbnRBLnksIHBvaW50Qi54IC0gcG9pbnRBLngpICogMTgwIC8gTWF0aC5QSTtcbn1cbi8qKlxyXG4gKiBDb21wdXRlIHRoZSBvdXRwdXQgY3JvcHBlZCBhcmVhIG9mIHRoZSBtZWRpYSBpbiBwZXJjZW50YWdlcyBhbmQgcGl4ZWxzLlxyXG4gKiB4L3kgYXJlIHRoZSB0b3AtbGVmdCBjb29yZGluYXRlcyBvbiB0aGUgc3JjIG1lZGlhXHJcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUNyb3BwZWRBcmVhKGNyb3AsIG1lZGlhU2l6ZSwgY3JvcFNpemUsIGFzcGVjdCwgem9vbSwgcm90YXRpb24sIHJlc3RyaWN0UG9zaXRpb24pIHtcbiAgaWYgKHJvdGF0aW9uID09PSB2b2lkIDApIHtcbiAgICByb3RhdGlvbiA9IDA7XG4gIH1cbiAgaWYgKHJlc3RyaWN0UG9zaXRpb24gPT09IHZvaWQgMCkge1xuICAgIHJlc3RyaWN0UG9zaXRpb24gPSB0cnVlO1xuICB9XG4gIC8vIGlmIHRoZSBtZWRpYSBpcyByb3RhdGVkIGJ5IHRoZSB1c2VyLCB3ZSBjYW5ub3QgbGltaXQgdGhlIHBvc2l0aW9uIGFueW1vcmVcbiAgLy8gYXMgaXQgbWlnaHQgbmVlZCB0byBiZSBuZWdhdGl2ZS5cbiAgdmFyIGxpbWl0QXJlYUZuID0gcmVzdHJpY3RQb3NpdGlvbiA/IGxpbWl0QXJlYSA6IG5vT3A7XG4gIHZhciBtZWRpYUJCb3hTaXplID0gcm90YXRlU2l6ZShtZWRpYVNpemUud2lkdGgsIG1lZGlhU2l6ZS5oZWlnaHQsIHJvdGF0aW9uKTtcbiAgdmFyIG1lZGlhTmF0dXJhbEJCb3hTaXplID0gcm90YXRlU2l6ZShtZWRpYVNpemUubmF0dXJhbFdpZHRoLCBtZWRpYVNpemUubmF0dXJhbEhlaWdodCwgcm90YXRpb24pO1xuICAvLyBjYWxjdWxhdGUgdGhlIGNyb3AgYXJlYSBpbiBwZXJjZW50YWdlc1xuICAvLyBpbiB0aGUgcm90YXRlZCBzcGFjZVxuICB2YXIgY3JvcHBlZEFyZWFQZXJjZW50YWdlcyA9IHtcbiAgICB4OiBsaW1pdEFyZWFGbigxMDAsICgobWVkaWFCQm94U2l6ZS53aWR0aCAtIGNyb3BTaXplLndpZHRoIC8gem9vbSkgLyAyIC0gY3JvcC54IC8gem9vbSkgLyBtZWRpYUJCb3hTaXplLndpZHRoICogMTAwKSxcbiAgICB5OiBsaW1pdEFyZWFGbigxMDAsICgobWVkaWFCQm94U2l6ZS5oZWlnaHQgLSBjcm9wU2l6ZS5oZWlnaHQgLyB6b29tKSAvIDIgLSBjcm9wLnkgLyB6b29tKSAvIG1lZGlhQkJveFNpemUuaGVpZ2h0ICogMTAwKSxcbiAgICB3aWR0aDogbGltaXRBcmVhRm4oMTAwLCBjcm9wU2l6ZS53aWR0aCAvIG1lZGlhQkJveFNpemUud2lkdGggKiAxMDAgLyB6b29tKSxcbiAgICBoZWlnaHQ6IGxpbWl0QXJlYUZuKDEwMCwgY3JvcFNpemUuaGVpZ2h0IC8gbWVkaWFCQm94U2l6ZS5oZWlnaHQgKiAxMDAgLyB6b29tKVxuICB9O1xuICAvLyB3ZSBjb21wdXRlIHRoZSBwaXhlbHMgc2l6ZSBuYWl2ZWx5XG4gIHZhciB3aWR0aEluUGl4ZWxzID0gTWF0aC5yb3VuZChsaW1pdEFyZWFGbihtZWRpYU5hdHVyYWxCQm94U2l6ZS53aWR0aCwgY3JvcHBlZEFyZWFQZXJjZW50YWdlcy53aWR0aCAqIG1lZGlhTmF0dXJhbEJCb3hTaXplLndpZHRoIC8gMTAwKSk7XG4gIHZhciBoZWlnaHRJblBpeGVscyA9IE1hdGgucm91bmQobGltaXRBcmVhRm4obWVkaWFOYXR1cmFsQkJveFNpemUuaGVpZ2h0LCBjcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLmhlaWdodCAqIG1lZGlhTmF0dXJhbEJCb3hTaXplLmhlaWdodCAvIDEwMCkpO1xuICB2YXIgaXNJbWdXaWRlclRoYW5IaWdoID0gbWVkaWFOYXR1cmFsQkJveFNpemUud2lkdGggPj0gbWVkaWFOYXR1cmFsQkJveFNpemUuaGVpZ2h0ICogYXNwZWN0O1xuICAvLyB0aGVuIHdlIGVuc3VyZSB0aGUgd2lkdGggYW5kIGhlaWdodCBleGFjdGx5IG1hdGNoIHRoZSBhc3BlY3QgKHRvIGF2b2lkIHJvdW5kaW5nIGFwcHJveGltYXRpb25zKVxuICAvLyBpZiB0aGUgbWVkaWEgaXMgd2lkZXIgdGhhbiBoaWdoLCB3aGVuIHpvb20gaXMgMCwgdGhlIGNyb3AgaGVpZ2h0IHdpbGwgYmUgZXF1YWxzIHRvIGltYWdlIGhlaWdodFxuICAvLyB0aHVzIHdlIHdhbnQgdG8gY29tcHV0ZSB0aGUgd2lkdGggZnJvbSB0aGUgaGVpZ2h0IGFuZCBhc3BlY3QgZm9yIGFjY3VyYWN5LlxuICAvLyBPdGhlcndpc2UsIHdlIGNvbXB1dGUgdGhlIGhlaWdodCBmcm9tIHdpZHRoIGFuZCBhc3BlY3QuXG4gIHZhciBzaXplUGl4ZWxzID0gaXNJbWdXaWRlclRoYW5IaWdoID8ge1xuICAgIHdpZHRoOiBNYXRoLnJvdW5kKGhlaWdodEluUGl4ZWxzICogYXNwZWN0KSxcbiAgICBoZWlnaHQ6IGhlaWdodEluUGl4ZWxzXG4gIH0gOiB7XG4gICAgd2lkdGg6IHdpZHRoSW5QaXhlbHMsXG4gICAgaGVpZ2h0OiBNYXRoLnJvdW5kKHdpZHRoSW5QaXhlbHMgLyBhc3BlY3QpXG4gIH07XG4gIHZhciBjcm9wcGVkQXJlYVBpeGVscyA9IF9fYXNzaWduKF9fYXNzaWduKHt9LCBzaXplUGl4ZWxzKSwge1xuICAgIHg6IE1hdGgucm91bmQobGltaXRBcmVhRm4obWVkaWFOYXR1cmFsQkJveFNpemUud2lkdGggLSBzaXplUGl4ZWxzLndpZHRoLCBjcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLnggKiBtZWRpYU5hdHVyYWxCQm94U2l6ZS53aWR0aCAvIDEwMCkpLFxuICAgIHk6IE1hdGgucm91bmQobGltaXRBcmVhRm4obWVkaWFOYXR1cmFsQkJveFNpemUuaGVpZ2h0IC0gc2l6ZVBpeGVscy5oZWlnaHQsIGNyb3BwZWRBcmVhUGVyY2VudGFnZXMueSAqIG1lZGlhTmF0dXJhbEJCb3hTaXplLmhlaWdodCAvIDEwMCkpXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIGNyb3BwZWRBcmVhUGVyY2VudGFnZXM6IGNyb3BwZWRBcmVhUGVyY2VudGFnZXMsXG4gICAgY3JvcHBlZEFyZWFQaXhlbHM6IGNyb3BwZWRBcmVhUGl4ZWxzXG4gIH07XG59XG4vKipcclxuICogRW5zdXJlIHRoZSByZXR1cm5lZCB2YWx1ZSBpcyBiZXR3ZWVuIDAgYW5kIG1heFxyXG4gKi9cbmZ1bmN0aW9uIGxpbWl0QXJlYShtYXgsIHZhbHVlKSB7XG4gIHJldHVybiBNYXRoLm1pbihtYXgsIE1hdGgubWF4KDAsIHZhbHVlKSk7XG59XG5mdW5jdGlvbiBub09wKF9tYXgsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cbi8qKlxyXG4gKiBDb21wdXRlIGNyb3AgYW5kIHpvb20gZnJvbSB0aGUgY3JvcHBlZEFyZWFQZXJjZW50YWdlcy5cclxuICovXG5mdW5jdGlvbiBnZXRJbml0aWFsQ3JvcEZyb21Dcm9wcGVkQXJlYVBlcmNlbnRhZ2VzKGNyb3BwZWRBcmVhUGVyY2VudGFnZXMsIG1lZGlhU2l6ZSwgcm90YXRpb24sIGNyb3BTaXplLCBtaW5ab29tLCBtYXhab29tKSB7XG4gIHZhciBtZWRpYUJCb3hTaXplID0gcm90YXRlU2l6ZShtZWRpYVNpemUud2lkdGgsIG1lZGlhU2l6ZS5oZWlnaHQsIHJvdGF0aW9uKTtcbiAgLy8gVGhpcyBpcyB0aGUgaW52ZXJzZSBwcm9jZXNzIG9mIGNvbXB1dGVDcm9wcGVkQXJlYVxuICB2YXIgem9vbSA9IGNsYW1wKGNyb3BTaXplLndpZHRoIC8gbWVkaWFCQm94U2l6ZS53aWR0aCAqICgxMDAgLyBjcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLndpZHRoKSwgbWluWm9vbSwgbWF4Wm9vbSk7XG4gIHZhciBjcm9wID0ge1xuICAgIHg6IHpvb20gKiBtZWRpYUJCb3hTaXplLndpZHRoIC8gMiAtIGNyb3BTaXplLndpZHRoIC8gMiAtIG1lZGlhQkJveFNpemUud2lkdGggKiB6b29tICogKGNyb3BwZWRBcmVhUGVyY2VudGFnZXMueCAvIDEwMCksXG4gICAgeTogem9vbSAqIG1lZGlhQkJveFNpemUuaGVpZ2h0IC8gMiAtIGNyb3BTaXplLmhlaWdodCAvIDIgLSBtZWRpYUJCb3hTaXplLmhlaWdodCAqIHpvb20gKiAoY3JvcHBlZEFyZWFQZXJjZW50YWdlcy55IC8gMTAwKVxuICB9O1xuICByZXR1cm4ge1xuICAgIGNyb3A6IGNyb3AsXG4gICAgem9vbTogem9vbVxuICB9O1xufVxuLyoqXHJcbiAqIENvbXB1dGUgem9vbSBmcm9tIHRoZSBjcm9wcGVkQXJlYVBpeGVsc1xyXG4gKi9cbmZ1bmN0aW9uIGdldFpvb21Gcm9tQ3JvcHBlZEFyZWFQaXhlbHMoY3JvcHBlZEFyZWFQaXhlbHMsIG1lZGlhU2l6ZSwgY3JvcFNpemUpIHtcbiAgdmFyIG1lZGlhWm9vbSA9IGdldE1lZGlhWm9vbShtZWRpYVNpemUpO1xuICByZXR1cm4gY3JvcFNpemUuaGVpZ2h0ID4gY3JvcFNpemUud2lkdGggPyBjcm9wU2l6ZS5oZWlnaHQgLyAoY3JvcHBlZEFyZWFQaXhlbHMuaGVpZ2h0ICogbWVkaWFab29tKSA6IGNyb3BTaXplLndpZHRoIC8gKGNyb3BwZWRBcmVhUGl4ZWxzLndpZHRoICogbWVkaWFab29tKTtcbn1cbi8qKlxyXG4gKiBDb21wdXRlIGNyb3AgYW5kIHpvb20gZnJvbSB0aGUgY3JvcHBlZEFyZWFQaXhlbHNcclxuICovXG5mdW5jdGlvbiBnZXRJbml0aWFsQ3JvcEZyb21Dcm9wcGVkQXJlYVBpeGVscyhjcm9wcGVkQXJlYVBpeGVscywgbWVkaWFTaXplLCByb3RhdGlvbiwgY3JvcFNpemUsIG1pblpvb20sIG1heFpvb20pIHtcbiAgaWYgKHJvdGF0aW9uID09PSB2b2lkIDApIHtcbiAgICByb3RhdGlvbiA9IDA7XG4gIH1cbiAgdmFyIG1lZGlhTmF0dXJhbEJCb3hTaXplID0gcm90YXRlU2l6ZShtZWRpYVNpemUubmF0dXJhbFdpZHRoLCBtZWRpYVNpemUubmF0dXJhbEhlaWdodCwgcm90YXRpb24pO1xuICB2YXIgem9vbSA9IGNsYW1wKGdldFpvb21Gcm9tQ3JvcHBlZEFyZWFQaXhlbHMoY3JvcHBlZEFyZWFQaXhlbHMsIG1lZGlhU2l6ZSwgY3JvcFNpemUpLCBtaW5ab29tLCBtYXhab29tKTtcbiAgdmFyIGNyb3Bab29tID0gY3JvcFNpemUuaGVpZ2h0ID4gY3JvcFNpemUud2lkdGggPyBjcm9wU2l6ZS5oZWlnaHQgLyBjcm9wcGVkQXJlYVBpeGVscy5oZWlnaHQgOiBjcm9wU2l6ZS53aWR0aCAvIGNyb3BwZWRBcmVhUGl4ZWxzLndpZHRoO1xuICB2YXIgY3JvcCA9IHtcbiAgICB4OiAoKG1lZGlhTmF0dXJhbEJCb3hTaXplLndpZHRoIC0gY3JvcHBlZEFyZWFQaXhlbHMud2lkdGgpIC8gMiAtIGNyb3BwZWRBcmVhUGl4ZWxzLngpICogY3JvcFpvb20sXG4gICAgeTogKChtZWRpYU5hdHVyYWxCQm94U2l6ZS5oZWlnaHQgLSBjcm9wcGVkQXJlYVBpeGVscy5oZWlnaHQpIC8gMiAtIGNyb3BwZWRBcmVhUGl4ZWxzLnkpICogY3JvcFpvb21cbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBjcm9wOiBjcm9wLFxuICAgIHpvb206IHpvb21cbiAgfTtcbn1cbi8qKlxyXG4gKiBSZXR1cm4gdGhlIHBvaW50IHRoYXQgaXMgdGhlIGNlbnRlciBvZiBwb2ludCBhIGFuZCBiXHJcbiAqL1xuZnVuY3Rpb24gZ2V0Q2VudGVyKGEsIGIpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiAoYi54ICsgYS54KSAvIDIsXG4gICAgeTogKGIueSArIGEueSkgLyAyXG4gIH07XG59XG5mdW5jdGlvbiBnZXRSYWRpYW5BbmdsZShkZWdyZWVWYWx1ZSkge1xuICByZXR1cm4gZGVncmVlVmFsdWUgKiBNYXRoLlBJIC8gMTgwO1xufVxuLyoqXHJcbiAqIFJldHVybnMgdGhlIG5ldyBib3VuZGluZyBhcmVhIG9mIGEgcm90YXRlZCByZWN0YW5nbGUuXHJcbiAqL1xuZnVuY3Rpb24gcm90YXRlU2l6ZSh3aWR0aCwgaGVpZ2h0LCByb3RhdGlvbikge1xuICB2YXIgcm90UmFkID0gZ2V0UmFkaWFuQW5nbGUocm90YXRpb24pO1xuICByZXR1cm4ge1xuICAgIHdpZHRoOiBNYXRoLmFicyhNYXRoLmNvcyhyb3RSYWQpICogd2lkdGgpICsgTWF0aC5hYnMoTWF0aC5zaW4ocm90UmFkKSAqIGhlaWdodCksXG4gICAgaGVpZ2h0OiBNYXRoLmFicyhNYXRoLnNpbihyb3RSYWQpICogd2lkdGgpICsgTWF0aC5hYnMoTWF0aC5jb3Mocm90UmFkKSAqIGhlaWdodClcbiAgfTtcbn1cbi8qKlxyXG4gKiBDbGFtcCB2YWx1ZSBiZXR3ZWVuIG1pbiBhbmQgbWF4XHJcbiAqL1xuZnVuY3Rpb24gY2xhbXAodmFsdWUsIG1pbiwgbWF4KSB7XG4gIHJldHVybiBNYXRoLm1pbihNYXRoLm1heCh2YWx1ZSwgbWluKSwgbWF4KTtcbn1cbi8qKlxyXG4gKiBDb21iaW5lIG11bHRpcGxlIGNsYXNzIG5hbWVzIGludG8gYSBzaW5nbGUgc3RyaW5nLlxyXG4gKi9cbmZ1bmN0aW9uIGNsYXNzTmFtZXMoKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgYXJnc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICB9XG4gIHJldHVybiBhcmdzLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KS5qb2luKCcgJykudHJpbSgpO1xufVxuXG52YXIgY3NzXzI0OHogPSBcIi5yZWFjdEVhc3lDcm9wX0NvbnRhaW5lciB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAwO1xcbiAgcmlnaHQ6IDA7XFxuICBib3R0b206IDA7XFxuICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XFxuICB0b3VjaC1hY3Rpb246IG5vbmU7XFxuICBjdXJzb3I6IG1vdmU7XFxuICBkaXNwbGF5OiBmbGV4O1xcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XFxuICBhbGlnbi1pdGVtczogY2VudGVyO1xcbn1cXG5cXG4ucmVhY3RFYXN5Q3JvcF9JbWFnZSxcXG4ucmVhY3RFYXN5Q3JvcF9WaWRlbyB7XFxuICB3aWxsLWNoYW5nZTogdHJhbnNmb3JtOyAvKiB0aGlzIGltcHJvdmVzIHBlcmZvcm1hbmNlcyBhbmQgcHJldmVudCBwYWludGluZyBpc3N1ZXMgb24gaU9TIENocm9tZSAqL1xcbn1cXG5cXG4ucmVhY3RFYXN5Q3JvcF9Db250YWluIHtcXG4gIG1heC13aWR0aDogMTAwJTtcXG4gIG1heC1oZWlnaHQ6IDEwMCU7XFxuICBtYXJnaW46IGF1dG87XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDA7XFxuICBib3R0b206IDA7XFxuICBsZWZ0OiAwO1xcbiAgcmlnaHQ6IDA7XFxufVxcbi5yZWFjdEVhc3lDcm9wX0NvdmVyX0hvcml6b250YWwge1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IGF1dG87XFxufVxcbi5yZWFjdEVhc3lDcm9wX0NvdmVyX1ZlcnRpY2FsIHtcXG4gIHdpZHRoOiBhdXRvO1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG5cXG4ucmVhY3RFYXN5Q3JvcF9Dcm9wQXJlYSB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICBsZWZ0OiA1MCU7XFxuICB0b3A6IDUwJTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjUpO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIGJveC1zaGFkb3c6IDAgMCAwIDk5OTllbTtcXG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNSk7XFxuICBvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG5cXG4ucmVhY3RFYXN5Q3JvcF9Dcm9wQXJlYVJvdW5kIHtcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXG59XFxuXFxuLnJlYWN0RWFzeUNyb3BfQ3JvcEFyZWFHcmlkOjpiZWZvcmUge1xcbiAgY29udGVudDogJyAnO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC41KTtcXG4gIHRvcDogMDtcXG4gIGJvdHRvbTogMDtcXG4gIGxlZnQ6IDMzLjMzJTtcXG4gIHJpZ2h0OiAzMy4zMyU7XFxuICBib3JkZXItdG9wOiAwO1xcbiAgYm9yZGVyLWJvdHRvbTogMDtcXG59XFxuXFxuLnJlYWN0RWFzeUNyb3BfQ3JvcEFyZWFHcmlkOjphZnRlciB7XFxuICBjb250ZW50OiAnICc7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjUpO1xcbiAgdG9wOiAzMy4zMyU7XFxuICBib3R0b206IDMzLjMzJTtcXG4gIGxlZnQ6IDA7XFxuICByaWdodDogMDtcXG4gIGJvcmRlci1sZWZ0OiAwO1xcbiAgYm9yZGVyLXJpZ2h0OiAwO1xcbn1cXG5cIjtcblxudmFyIE1JTl9aT09NID0gMTtcbnZhciBNQVhfWk9PTSA9IDM7XG52YXIgS0VZQk9BUkRfU1RFUCA9IDE7XG52YXIgQ3JvcHBlciA9IC8qKiBAY2xhc3MgKi9mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDcm9wcGVyLCBfc3VwZXIpO1xuICBmdW5jdGlvbiBDcm9wcGVyKCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICAgIF90aGlzLmNyb3BwZXJSZWYgPSBSZWFjdC5jcmVhdGVSZWYoKTtcbiAgICBfdGhpcy5pbWFnZVJlZiA9IFJlYWN0LmNyZWF0ZVJlZigpO1xuICAgIF90aGlzLnZpZGVvUmVmID0gUmVhY3QuY3JlYXRlUmVmKCk7XG4gICAgX3RoaXMuY29udGFpbmVyUG9zaXRpb24gPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG4gICAgX3RoaXMuY29udGFpbmVyUmVmID0gbnVsbDtcbiAgICBfdGhpcy5zdHlsZVJlZiA9IG51bGw7XG4gICAgX3RoaXMuY29udGFpbmVyUmVjdCA9IG51bGw7XG4gICAgX3RoaXMubWVkaWFTaXplID0ge1xuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBuYXR1cmFsV2lkdGg6IDAsXG4gICAgICBuYXR1cmFsSGVpZ2h0OiAwXG4gICAgfTtcbiAgICBfdGhpcy5kcmFnU3RhcnRQb3NpdGlvbiA9IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgICBfdGhpcy5kcmFnU3RhcnRDcm9wID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICAgIF90aGlzLmdlc3R1cmVab29tU3RhcnQgPSAwO1xuICAgIF90aGlzLmdlc3R1cmVSb3RhdGlvblN0YXJ0ID0gMDtcbiAgICBfdGhpcy5pc1RvdWNoaW5nID0gZmFsc2U7XG4gICAgX3RoaXMubGFzdFBpbmNoRGlzdGFuY2UgPSAwO1xuICAgIF90aGlzLmxhc3RQaW5jaFJvdGF0aW9uID0gMDtcbiAgICBfdGhpcy5yYWZEcmFnVGltZW91dCA9IG51bGw7XG4gICAgX3RoaXMucmFmUGluY2hUaW1lb3V0ID0gbnVsbDtcbiAgICBfdGhpcy53aGVlbFRpbWVyID0gbnVsbDtcbiAgICBfdGhpcy5jdXJyZW50RG9jID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IGRvY3VtZW50IDogbnVsbDtcbiAgICBfdGhpcy5jdXJyZW50V2luZG93ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiBudWxsO1xuICAgIF90aGlzLnJlc2l6ZU9ic2VydmVyID0gbnVsbDtcbiAgICBfdGhpcy5wcmV2aW91c0Nyb3BTaXplID0gbnVsbDtcbiAgICBfdGhpcy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgX3RoaXMuc3RhdGUgPSB7XG4gICAgICBjcm9wU2l6ZTogbnVsbCxcbiAgICAgIGhhc1doZWVsSnVzdFN0YXJ0ZWQ6IGZhbHNlLFxuICAgICAgbWVkaWFPYmplY3RGaXQ6IHVuZGVmaW5lZFxuICAgIH07XG4gICAgX3RoaXMuaW5pdFJlc2l6ZU9ic2VydmVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIgPT09ICd1bmRlZmluZWQnIHx8ICFfdGhpcy5jb250YWluZXJSZWYpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmFyIGlzRmlyc3RSZXNpemUgPSB0cnVlO1xuICAgICAgX3RoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgd2luZG93LlJlc2l6ZU9ic2VydmVyKGZ1bmN0aW9uIChlbnRyaWVzKSB7XG4gICAgICAgIGlmIChpc0ZpcnN0UmVzaXplKSB7XG4gICAgICAgICAgaXNGaXJzdFJlc2l6ZSA9IGZhbHNlOyAvLyBvYnNlcnZlKCkgaXMgY2FsbGVkIG9uIG1vdW50LCB3ZSBkb24ndCB3YW50IHRvIHRyaWdnZXIgYSByZWNvbXB1dGUgb24gbW91bnRcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgX3RoaXMuY29tcHV0ZVNpemVzKCk7XG4gICAgICB9KTtcbiAgICAgIF90aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUoX3RoaXMuY29udGFpbmVyUmVmKTtcbiAgICB9O1xuICAgIC8vIHRoaXMgaXMgdG8gcHJldmVudCBTYWZhcmkgb24gaU9TID49IDEwIHRvIHpvb20gdGhlIHBhZ2VcbiAgICBfdGhpcy5wcmV2ZW50Wm9vbVNhZmFyaSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH07XG4gICAgX3RoaXMuY2xlYW5FdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIV90aGlzLmN1cnJlbnREb2MpIHJldHVybjtcbiAgICAgIF90aGlzLmN1cnJlbnREb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgX3RoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgX3RoaXMuY3VycmVudERvYy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgX3RoaXMub25EcmFnU3RvcHBlZCk7XG4gICAgICBfdGhpcy5jdXJyZW50RG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIF90aGlzLm9uVG91Y2hNb3ZlKTtcbiAgICAgIF90aGlzLmN1cnJlbnREb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBfdGhpcy5vbkRyYWdTdG9wcGVkKTtcbiAgICAgIF90aGlzLmN1cnJlbnREb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignZ2VzdHVyZWNoYW5nZScsIF90aGlzLm9uR2VzdHVyZUNoYW5nZSk7XG4gICAgICBfdGhpcy5jdXJyZW50RG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2dlc3R1cmVlbmQnLCBfdGhpcy5vbkdlc3R1cmVFbmQpO1xuICAgICAgX3RoaXMuY3VycmVudERvYy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBfdGhpcy5vblNjcm9sbCk7XG4gICAgfTtcbiAgICBfdGhpcy5jbGVhclNjcm9sbEV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKF90aGlzLmNvbnRhaW5lclJlZikgX3RoaXMuY29udGFpbmVyUmVmLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3doZWVsJywgX3RoaXMub25XaGVlbCk7XG4gICAgICBpZiAoX3RoaXMud2hlZWxUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMud2hlZWxUaW1lcik7XG4gICAgICB9XG4gICAgfTtcbiAgICBfdGhpcy5vbk1lZGlhTG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjcm9wU2l6ZSA9IF90aGlzLmNvbXB1dGVTaXplcygpO1xuICAgICAgaWYgKGNyb3BTaXplKSB7XG4gICAgICAgIF90aGlzLnByZXZpb3VzQ3JvcFNpemUgPSBjcm9wU2l6ZTtcbiAgICAgICAgX3RoaXMuZW1pdENyb3BEYXRhKCk7XG4gICAgICAgIF90aGlzLnNldEluaXRpYWxDcm9wKGNyb3BTaXplKTtcbiAgICAgICAgX3RoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoX3RoaXMucHJvcHMub25NZWRpYUxvYWRlZCkge1xuICAgICAgICBfdGhpcy5wcm9wcy5vbk1lZGlhTG9hZGVkKF90aGlzLm1lZGlhU2l6ZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBfdGhpcy5zZXRJbml0aWFsQ3JvcCA9IGZ1bmN0aW9uIChjcm9wU2l6ZSkge1xuICAgICAgaWYgKF90aGlzLnByb3BzLmluaXRpYWxDcm9wcGVkQXJlYVBlcmNlbnRhZ2VzKSB7XG4gICAgICAgIHZhciBfYSA9IGdldEluaXRpYWxDcm9wRnJvbUNyb3BwZWRBcmVhUGVyY2VudGFnZXMoX3RoaXMucHJvcHMuaW5pdGlhbENyb3BwZWRBcmVhUGVyY2VudGFnZXMsIF90aGlzLm1lZGlhU2l6ZSwgX3RoaXMucHJvcHMucm90YXRpb24sIGNyb3BTaXplLCBfdGhpcy5wcm9wcy5taW5ab29tLCBfdGhpcy5wcm9wcy5tYXhab29tKSxcbiAgICAgICAgICBjcm9wID0gX2EuY3JvcCxcbiAgICAgICAgICB6b29tID0gX2Euem9vbTtcbiAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wQ2hhbmdlKGNyb3ApO1xuICAgICAgICBfdGhpcy5wcm9wcy5vblpvb21DaGFuZ2UgJiYgX3RoaXMucHJvcHMub25ab29tQ2hhbmdlKHpvb20pO1xuICAgICAgfSBlbHNlIGlmIChfdGhpcy5wcm9wcy5pbml0aWFsQ3JvcHBlZEFyZWFQaXhlbHMpIHtcbiAgICAgICAgdmFyIF9iID0gZ2V0SW5pdGlhbENyb3BGcm9tQ3JvcHBlZEFyZWFQaXhlbHMoX3RoaXMucHJvcHMuaW5pdGlhbENyb3BwZWRBcmVhUGl4ZWxzLCBfdGhpcy5tZWRpYVNpemUsIF90aGlzLnByb3BzLnJvdGF0aW9uLCBjcm9wU2l6ZSwgX3RoaXMucHJvcHMubWluWm9vbSwgX3RoaXMucHJvcHMubWF4Wm9vbSksXG4gICAgICAgICAgY3JvcCA9IF9iLmNyb3AsXG4gICAgICAgICAgem9vbSA9IF9iLnpvb207XG4gICAgICAgIF90aGlzLnByb3BzLm9uQ3JvcENoYW5nZShjcm9wKTtcbiAgICAgICAgX3RoaXMucHJvcHMub25ab29tQ2hhbmdlICYmIF90aGlzLnByb3BzLm9uWm9vbUNoYW5nZSh6b29tKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIF90aGlzLmNvbXB1dGVTaXplcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYSwgX2IsIF9jLCBfZCwgX2UsIF9mO1xuICAgICAgdmFyIG1lZGlhUmVmID0gX3RoaXMuaW1hZ2VSZWYuY3VycmVudCB8fCBfdGhpcy52aWRlb1JlZi5jdXJyZW50O1xuICAgICAgaWYgKG1lZGlhUmVmICYmIF90aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgICBfdGhpcy5jb250YWluZXJSZWN0ID0gX3RoaXMuY29udGFpbmVyUmVmLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBfdGhpcy5zYXZlQ29udGFpbmVyUG9zaXRpb24oKTtcbiAgICAgICAgdmFyIGNvbnRhaW5lckFzcGVjdCA9IF90aGlzLmNvbnRhaW5lclJlY3Qud2lkdGggLyBfdGhpcy5jb250YWluZXJSZWN0LmhlaWdodDtcbiAgICAgICAgdmFyIG5hdHVyYWxXaWR0aCA9ICgoX2EgPSBfdGhpcy5pbWFnZVJlZi5jdXJyZW50KSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubmF0dXJhbFdpZHRoKSB8fCAoKF9iID0gX3RoaXMudmlkZW9SZWYuY3VycmVudCkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLnZpZGVvV2lkdGgpIHx8IDA7XG4gICAgICAgIHZhciBuYXR1cmFsSGVpZ2h0ID0gKChfYyA9IF90aGlzLmltYWdlUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5uYXR1cmFsSGVpZ2h0KSB8fCAoKF9kID0gX3RoaXMudmlkZW9SZWYuY3VycmVudCkgPT09IG51bGwgfHwgX2QgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9kLnZpZGVvSGVpZ2h0KSB8fCAwO1xuICAgICAgICB2YXIgaXNNZWRpYVNjYWxlZERvd24gPSBtZWRpYVJlZi5vZmZzZXRXaWR0aCA8IG5hdHVyYWxXaWR0aCB8fCBtZWRpYVJlZi5vZmZzZXRIZWlnaHQgPCBuYXR1cmFsSGVpZ2h0O1xuICAgICAgICB2YXIgbWVkaWFBc3BlY3QgPSBuYXR1cmFsV2lkdGggLyBuYXR1cmFsSGVpZ2h0O1xuICAgICAgICAvLyBXZSBkbyBub3QgcmVseSBvbiB0aGUgb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGlmIHRoZSBtZWRpYSBpcyBzY2FsZWQgZG93blxuICAgICAgICAvLyBhcyB0aGUgdmFsdWVzIHRoZXkgcmVwb3J0IGFyZSByb3VuZGVkLiBUaGF0IHdpbGwgcmVzdWx0IGluIHByZWNpc2lvbiBsb3NzZXNcbiAgICAgICAgLy8gd2hlbiBjYWxjdWxhdGluZyB6b29tLiBXZSB1c2UgdGhlIGZhY3QgdGhhdCB0aGUgbWVkaWEgaXMgcG9zaXRpb25uZWQgcmVsYXRpdmVcbiAgICAgICAgLy8gdG8gdGhlIGNvbnRhaW5lci4gVGhhdCBhbGxvd3MgdXMgdG8gdXNlIHRoZSBjb250YWluZXIncyBkaW1lbnNpb25zXG4gICAgICAgIC8vIGFuZCBuYXR1cmFsIGFzcGVjdCByYXRpbyBvZiB0aGUgbWVkaWEgdG8gY2FsY3VsYXRlIGFjY3VyYXRlIG1lZGlhIHNpemUuXG4gICAgICAgIC8vIEhvd2V2ZXIsIGZvciB0aGlzIHRvIHdvcmssIHRoZSBjb250YWluZXIgc2hvdWxkIG5vdCBiZSByb3RhdGVkXG4gICAgICAgIHZhciByZW5kZXJlZE1lZGlhU2l6ZSA9IHZvaWQgMDtcbiAgICAgICAgaWYgKGlzTWVkaWFTY2FsZWREb3duKSB7XG4gICAgICAgICAgc3dpdGNoIChfdGhpcy5zdGF0ZS5tZWRpYU9iamVjdEZpdCkge1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNhc2UgJ2NvbnRhaW4nOlxuICAgICAgICAgICAgICByZW5kZXJlZE1lZGlhU2l6ZSA9IGNvbnRhaW5lckFzcGVjdCA+IG1lZGlhQXNwZWN0ID8ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiBfdGhpcy5jb250YWluZXJSZWN0LmhlaWdodCAqIG1lZGlhQXNwZWN0LFxuICAgICAgICAgICAgICAgIGhlaWdodDogX3RoaXMuY29udGFpbmVyUmVjdC5oZWlnaHRcbiAgICAgICAgICAgICAgfSA6IHtcbiAgICAgICAgICAgICAgICB3aWR0aDogX3RoaXMuY29udGFpbmVyUmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IF90aGlzLmNvbnRhaW5lclJlY3Qud2lkdGggLyBtZWRpYUFzcGVjdFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvcml6b250YWwtY292ZXInOlxuICAgICAgICAgICAgICByZW5kZXJlZE1lZGlhU2l6ZSA9IHtcbiAgICAgICAgICAgICAgICB3aWR0aDogX3RoaXMuY29udGFpbmVyUmVjdC53aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IF90aGlzLmNvbnRhaW5lclJlY3Qud2lkdGggLyBtZWRpYUFzcGVjdFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3ZlcnRpY2FsLWNvdmVyJzpcbiAgICAgICAgICAgICAgcmVuZGVyZWRNZWRpYVNpemUgPSB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IF90aGlzLmNvbnRhaW5lclJlY3QuaGVpZ2h0ICogbWVkaWFBc3BlY3QsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBfdGhpcy5jb250YWluZXJSZWN0LmhlaWdodFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVuZGVyZWRNZWRpYVNpemUgPSB7XG4gICAgICAgICAgICB3aWR0aDogbWVkaWFSZWYub2Zmc2V0V2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IG1lZGlhUmVmLm9mZnNldEhlaWdodFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgX3RoaXMubWVkaWFTaXplID0gX19hc3NpZ24oX19hc3NpZ24oe30sIHJlbmRlcmVkTWVkaWFTaXplKSwge1xuICAgICAgICAgIG5hdHVyYWxXaWR0aDogbmF0dXJhbFdpZHRoLFxuICAgICAgICAgIG5hdHVyYWxIZWlnaHQ6IG5hdHVyYWxIZWlnaHRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCBtZWRpYSBzaXplIGluIHRoZSBwYXJlbnRcbiAgICAgICAgaWYgKF90aGlzLnByb3BzLnNldE1lZGlhU2l6ZSkge1xuICAgICAgICAgIF90aGlzLnByb3BzLnNldE1lZGlhU2l6ZShfdGhpcy5tZWRpYVNpemUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjcm9wU2l6ZSA9IF90aGlzLnByb3BzLmNyb3BTaXplID8gX3RoaXMucHJvcHMuY3JvcFNpemUgOiBnZXRDcm9wU2l6ZShfdGhpcy5tZWRpYVNpemUud2lkdGgsIF90aGlzLm1lZGlhU2l6ZS5oZWlnaHQsIF90aGlzLmNvbnRhaW5lclJlY3Qud2lkdGgsIF90aGlzLmNvbnRhaW5lclJlY3QuaGVpZ2h0LCBfdGhpcy5wcm9wcy5hc3BlY3QsIF90aGlzLnByb3BzLnJvdGF0aW9uKTtcbiAgICAgICAgaWYgKCgoX2UgPSBfdGhpcy5zdGF0ZS5jcm9wU2l6ZSkgPT09IG51bGwgfHwgX2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9lLmhlaWdodCkgIT09IGNyb3BTaXplLmhlaWdodCB8fCAoKF9mID0gX3RoaXMuc3RhdGUuY3JvcFNpemUpID09PSBudWxsIHx8IF9mID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZi53aWR0aCkgIT09IGNyb3BTaXplLndpZHRoKSB7XG4gICAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wU2l6ZUNoYW5nZSAmJiBfdGhpcy5wcm9wcy5vbkNyb3BTaXplQ2hhbmdlKGNyb3BTaXplKTtcbiAgICAgICAgfVxuICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY3JvcFNpemU6IGNyb3BTaXplXG4gICAgICAgIH0sIF90aGlzLnJlY29tcHV0ZUNyb3BQb3NpdGlvbik7XG4gICAgICAgIC8vIHBhc3MgY3JvcCBzaXplIHRvIHBhcmVudFxuICAgICAgICBpZiAoX3RoaXMucHJvcHMuc2V0Q3JvcFNpemUpIHtcbiAgICAgICAgICBfdGhpcy5wcm9wcy5zZXRDcm9wU2l6ZShjcm9wU2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNyb3BTaXplO1xuICAgICAgfVxuICAgIH07XG4gICAgX3RoaXMuc2F2ZUNvbnRhaW5lclBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKF90aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgICB2YXIgYm91bmRzID0gX3RoaXMuY29udGFpbmVyUmVmLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBfdGhpcy5jb250YWluZXJQb3NpdGlvbiA9IHtcbiAgICAgICAgICB4OiBib3VuZHMubGVmdCxcbiAgICAgICAgICB5OiBib3VuZHMudG9wXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgICBfdGhpcy5vbk1vdXNlRG93biA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoIV90aGlzLmN1cnJlbnREb2MpIHJldHVybjtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIF90aGlzLmN1cnJlbnREb2MuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgX3RoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgX3RoaXMuY3VycmVudERvYy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgX3RoaXMub25EcmFnU3RvcHBlZCk7XG4gICAgICBfdGhpcy5zYXZlQ29udGFpbmVyUG9zaXRpb24oKTtcbiAgICAgIF90aGlzLm9uRHJhZ1N0YXJ0KENyb3BwZXIuZ2V0TW91c2VQb2ludChlKSk7XG4gICAgfTtcbiAgICBfdGhpcy5vbk1vdXNlTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gX3RoaXMub25EcmFnKENyb3BwZXIuZ2V0TW91c2VQb2ludChlKSk7XG4gICAgfTtcbiAgICBfdGhpcy5vblNjcm9sbCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoIV90aGlzLmN1cnJlbnREb2MpIHJldHVybjtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIF90aGlzLnNhdmVDb250YWluZXJQb3NpdGlvbigpO1xuICAgIH07XG4gICAgX3RoaXMub25Ub3VjaFN0YXJ0ID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmICghX3RoaXMuY3VycmVudERvYykgcmV0dXJuO1xuICAgICAgX3RoaXMuaXNUb3VjaGluZyA9IHRydWU7XG4gICAgICBpZiAoX3RoaXMucHJvcHMub25Ub3VjaFJlcXVlc3QgJiYgIV90aGlzLnByb3BzLm9uVG91Y2hSZXF1ZXN0KGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIF90aGlzLmN1cnJlbnREb2MuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgX3RoaXMub25Ub3VjaE1vdmUsIHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2VcbiAgICAgIH0pOyAvLyBpT1MgMTEgbm93IGRlZmF1bHRzIHRvIHBhc3NpdmU6IHRydWVcbiAgICAgIF90aGlzLmN1cnJlbnREb2MuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBfdGhpcy5vbkRyYWdTdG9wcGVkKTtcbiAgICAgIF90aGlzLnNhdmVDb250YWluZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgX3RoaXMub25QaW5jaFN0YXJ0KGUpO1xuICAgICAgfSBlbHNlIGlmIChlLnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIF90aGlzLm9uRHJhZ1N0YXJ0KENyb3BwZXIuZ2V0VG91Y2hQb2ludChlLnRvdWNoZXNbMF0pKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIF90aGlzLm9uVG91Y2hNb3ZlID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIC8vIFByZXZlbnQgd2hvbGUgcGFnZSBmcm9tIHNjcm9sbGluZyBvbiBpT1MuXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICBfdGhpcy5vblBpbmNoTW92ZShlKTtcbiAgICAgIH0gZWxzZSBpZiAoZS50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBfdGhpcy5vbkRyYWcoQ3JvcHBlci5nZXRUb3VjaFBvaW50KGUudG91Y2hlc1swXSkpO1xuICAgICAgfVxuICAgIH07XG4gICAgX3RoaXMub25HZXN0dXJlU3RhcnQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKCFfdGhpcy5jdXJyZW50RG9jKSByZXR1cm47XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBfdGhpcy5jdXJyZW50RG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2dlc3R1cmVjaGFuZ2UnLCBfdGhpcy5vbkdlc3R1cmVDaGFuZ2UpO1xuICAgICAgX3RoaXMuY3VycmVudERvYy5hZGRFdmVudExpc3RlbmVyKCdnZXN0dXJlZW5kJywgX3RoaXMub25HZXN0dXJlRW5kKTtcbiAgICAgIF90aGlzLmdlc3R1cmVab29tU3RhcnQgPSBfdGhpcy5wcm9wcy56b29tO1xuICAgICAgX3RoaXMuZ2VzdHVyZVJvdGF0aW9uU3RhcnQgPSBfdGhpcy5wcm9wcy5yb3RhdGlvbjtcbiAgICB9O1xuICAgIF90aGlzLm9uR2VzdHVyZUNoYW5nZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoX3RoaXMuaXNUb3VjaGluZykge1xuICAgICAgICAvLyB0aGlzIGlzIHRvIGF2b2lkIGNvbmZsaWN0IGJldHdlZW4gZ2VzdHVyZSBhbmQgdG91Y2ggZXZlbnRzXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBwb2ludCA9IENyb3BwZXIuZ2V0TW91c2VQb2ludChlKTtcbiAgICAgIHZhciBuZXdab29tID0gX3RoaXMuZ2VzdHVyZVpvb21TdGFydCAtIDEgKyBlLnNjYWxlO1xuICAgICAgX3RoaXMuc2V0TmV3Wm9vbShuZXdab29tLCBwb2ludCwge1xuICAgICAgICBzaG91bGRVcGRhdGVQb3NpdGlvbjogdHJ1ZVxuICAgICAgfSk7XG4gICAgICBpZiAoX3RoaXMucHJvcHMub25Sb3RhdGlvbkNoYW5nZSkge1xuICAgICAgICB2YXIgbmV3Um90YXRpb24gPSBfdGhpcy5nZXN0dXJlUm90YXRpb25TdGFydCArIGUucm90YXRpb247XG4gICAgICAgIF90aGlzLnByb3BzLm9uUm90YXRpb25DaGFuZ2UobmV3Um90YXRpb24pO1xuICAgICAgfVxuICAgIH07XG4gICAgX3RoaXMub25HZXN0dXJlRW5kID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIF90aGlzLmNsZWFuRXZlbnRzKCk7XG4gICAgfTtcbiAgICBfdGhpcy5vbkRyYWdTdGFydCA9IGZ1bmN0aW9uIChfYSkge1xuICAgICAgdmFyIF9iLCBfYztcbiAgICAgIHZhciB4ID0gX2EueCxcbiAgICAgICAgeSA9IF9hLnk7XG4gICAgICBfdGhpcy5kcmFnU3RhcnRQb3NpdGlvbiA9IHtcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeVxuICAgICAgfTtcbiAgICAgIF90aGlzLmRyYWdTdGFydENyb3AgPSBfX2Fzc2lnbih7fSwgX3RoaXMucHJvcHMuY3JvcCk7XG4gICAgICAoX2MgPSAoX2IgPSBfdGhpcy5wcm9wcykub25JbnRlcmFjdGlvblN0YXJ0KSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2MuY2FsbChfYik7XG4gICAgfTtcbiAgICBfdGhpcy5vbkRyYWcgPSBmdW5jdGlvbiAoX2EpIHtcbiAgICAgIHZhciB4ID0gX2EueCxcbiAgICAgICAgeSA9IF9hLnk7XG4gICAgICBpZiAoIV90aGlzLmN1cnJlbnRXaW5kb3cpIHJldHVybjtcbiAgICAgIGlmIChfdGhpcy5yYWZEcmFnVGltZW91dCkgX3RoaXMuY3VycmVudFdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShfdGhpcy5yYWZEcmFnVGltZW91dCk7XG4gICAgICBfdGhpcy5yYWZEcmFnVGltZW91dCA9IF90aGlzLmN1cnJlbnRXaW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFfdGhpcy5zdGF0ZS5jcm9wU2l6ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoeCA9PT0gdW5kZWZpbmVkIHx8IHkgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgICAgICB2YXIgb2Zmc2V0WCA9IHggLSBfdGhpcy5kcmFnU3RhcnRQb3NpdGlvbi54O1xuICAgICAgICB2YXIgb2Zmc2V0WSA9IHkgLSBfdGhpcy5kcmFnU3RhcnRQb3NpdGlvbi55O1xuICAgICAgICB2YXIgcmVxdWVzdGVkUG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogX3RoaXMuZHJhZ1N0YXJ0Q3JvcC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICB5OiBfdGhpcy5kcmFnU3RhcnRDcm9wLnkgKyBvZmZzZXRZXG4gICAgICAgIH07XG4gICAgICAgIHZhciBuZXdQb3NpdGlvbiA9IF90aGlzLnByb3BzLnJlc3RyaWN0UG9zaXRpb24gPyByZXN0cmljdFBvc2l0aW9uKHJlcXVlc3RlZFBvc2l0aW9uLCBfdGhpcy5tZWRpYVNpemUsIF90aGlzLnN0YXRlLmNyb3BTaXplLCBfdGhpcy5wcm9wcy56b29tLCBfdGhpcy5wcm9wcy5yb3RhdGlvbikgOiByZXF1ZXN0ZWRQb3NpdGlvbjtcbiAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wQ2hhbmdlKG5ld1Bvc2l0aW9uKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgX3RoaXMub25EcmFnU3RvcHBlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYSwgX2I7XG4gICAgICBfdGhpcy5pc1RvdWNoaW5nID0gZmFsc2U7XG4gICAgICBfdGhpcy5jbGVhbkV2ZW50cygpO1xuICAgICAgX3RoaXMuZW1pdENyb3BEYXRhKCk7XG4gICAgICAoX2IgPSAoX2EgPSBfdGhpcy5wcm9wcykub25JbnRlcmFjdGlvbkVuZCkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmNhbGwoX2EpO1xuICAgIH07XG4gICAgX3RoaXMub25XaGVlbCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoIV90aGlzLmN1cnJlbnRXaW5kb3cpIHJldHVybjtcbiAgICAgIGlmIChfdGhpcy5wcm9wcy5vbldoZWVsUmVxdWVzdCAmJiAhX3RoaXMucHJvcHMub25XaGVlbFJlcXVlc3QoZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdmFyIHBvaW50ID0gQ3JvcHBlci5nZXRNb3VzZVBvaW50KGUpO1xuICAgICAgdmFyIHBpeGVsWSA9IG5vcm1hbGl6ZVdoZWVsKGUpLnBpeGVsWTtcbiAgICAgIHZhciBuZXdab29tID0gX3RoaXMucHJvcHMuem9vbSAtIHBpeGVsWSAqIF90aGlzLnByb3BzLnpvb21TcGVlZCAvIDIwMDtcbiAgICAgIF90aGlzLnNldE5ld1pvb20obmV3Wm9vbSwgcG9pbnQsIHtcbiAgICAgICAgc2hvdWxkVXBkYXRlUG9zaXRpb246IHRydWVcbiAgICAgIH0pO1xuICAgICAgaWYgKCFfdGhpcy5zdGF0ZS5oYXNXaGVlbEp1c3RTdGFydGVkKSB7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBoYXNXaGVlbEp1c3RTdGFydGVkOiB0cnVlXG4gICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSBfdGhpcy5wcm9wcykub25JbnRlcmFjdGlvblN0YXJ0KSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY2FsbChfYSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKF90aGlzLndoZWVsVGltZXIpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KF90aGlzLndoZWVsVGltZXIpO1xuICAgICAgfVxuICAgICAgX3RoaXMud2hlZWxUaW1lciA9IF90aGlzLmN1cnJlbnRXaW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgaGFzV2hlZWxKdXN0U3RhcnRlZDogZmFsc2VcbiAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgICAgcmV0dXJuIChfYiA9IChfYSA9IF90aGlzLnByb3BzKS5vbkludGVyYWN0aW9uRW5kKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY2FsbChfYSk7XG4gICAgICAgIH0pO1xuICAgICAgfSwgMjUwKTtcbiAgICB9O1xuICAgIF90aGlzLmdldFBvaW50T25Db250YWluZXIgPSBmdW5jdGlvbiAoX2EsIGNvbnRhaW5lclRvcExlZnQpIHtcbiAgICAgIHZhciB4ID0gX2EueCxcbiAgICAgICAgeSA9IF9hLnk7XG4gICAgICBpZiAoIV90aGlzLmNvbnRhaW5lclJlY3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQ3JvcHBlciBpcyBub3QgbW91bnRlZCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogX3RoaXMuY29udGFpbmVyUmVjdC53aWR0aCAvIDIgLSAoeCAtIGNvbnRhaW5lclRvcExlZnQueCksXG4gICAgICAgIHk6IF90aGlzLmNvbnRhaW5lclJlY3QuaGVpZ2h0IC8gMiAtICh5IC0gY29udGFpbmVyVG9wTGVmdC55KVxuICAgICAgfTtcbiAgICB9O1xuICAgIF90aGlzLmdldFBvaW50T25NZWRpYSA9IGZ1bmN0aW9uIChfYSkge1xuICAgICAgdmFyIHggPSBfYS54LFxuICAgICAgICB5ID0gX2EueTtcbiAgICAgIHZhciBfYiA9IF90aGlzLnByb3BzLFxuICAgICAgICBjcm9wID0gX2IuY3JvcCxcbiAgICAgICAgem9vbSA9IF9iLnpvb207XG4gICAgICByZXR1cm4ge1xuICAgICAgICB4OiAoeCArIGNyb3AueCkgLyB6b29tLFxuICAgICAgICB5OiAoeSArIGNyb3AueSkgLyB6b29tXG4gICAgICB9O1xuICAgIH07XG4gICAgX3RoaXMuc2V0TmV3Wm9vbSA9IGZ1bmN0aW9uICh6b29tLCBwb2ludCwgX2EpIHtcbiAgICAgIHZhciBfYiA9IF9hID09PSB2b2lkIDAgPyB7fSA6IF9hLFxuICAgICAgICBfYyA9IF9iLnNob3VsZFVwZGF0ZVBvc2l0aW9uLFxuICAgICAgICBzaG91bGRVcGRhdGVQb3NpdGlvbiA9IF9jID09PSB2b2lkIDAgPyB0cnVlIDogX2M7XG4gICAgICBpZiAoIV90aGlzLnN0YXRlLmNyb3BTaXplIHx8ICFfdGhpcy5wcm9wcy5vblpvb21DaGFuZ2UpIHJldHVybjtcbiAgICAgIHZhciBuZXdab29tID0gY2xhbXAoem9vbSwgX3RoaXMucHJvcHMubWluWm9vbSwgX3RoaXMucHJvcHMubWF4Wm9vbSk7XG4gICAgICBpZiAoc2hvdWxkVXBkYXRlUG9zaXRpb24pIHtcbiAgICAgICAgdmFyIHpvb21Qb2ludCA9IF90aGlzLmdldFBvaW50T25Db250YWluZXIocG9pbnQsIF90aGlzLmNvbnRhaW5lclBvc2l0aW9uKTtcbiAgICAgICAgdmFyIHpvb21UYXJnZXQgPSBfdGhpcy5nZXRQb2ludE9uTWVkaWEoem9vbVBvaW50KTtcbiAgICAgICAgdmFyIHJlcXVlc3RlZFBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHpvb21UYXJnZXQueCAqIG5ld1pvb20gLSB6b29tUG9pbnQueCxcbiAgICAgICAgICB5OiB6b29tVGFyZ2V0LnkgKiBuZXdab29tIC0gem9vbVBvaW50LnlcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG5ld1Bvc2l0aW9uID0gX3RoaXMucHJvcHMucmVzdHJpY3RQb3NpdGlvbiA/IHJlc3RyaWN0UG9zaXRpb24ocmVxdWVzdGVkUG9zaXRpb24sIF90aGlzLm1lZGlhU2l6ZSwgX3RoaXMuc3RhdGUuY3JvcFNpemUsIG5ld1pvb20sIF90aGlzLnByb3BzLnJvdGF0aW9uKSA6IHJlcXVlc3RlZFBvc2l0aW9uO1xuICAgICAgICBfdGhpcy5wcm9wcy5vbkNyb3BDaGFuZ2UobmV3UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgX3RoaXMucHJvcHMub25ab29tQ2hhbmdlKG5ld1pvb20pO1xuICAgIH07XG4gICAgX3RoaXMuZ2V0Q3JvcERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIV90aGlzLnN0YXRlLmNyb3BTaXplKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gdGhpcyBpcyB0byBlbnN1cmUgdGhlIGNyb3AgaXMgY29ycmVjdGx5IHJlc3RyaWN0ZWQgYWZ0ZXIgYSB6b29tIGJhY2sgKGh0dHBzOi8vZ2l0aHViLmNvbS9WYWxlbnRpbkgvcmVhY3QtZWFzeS1jcm9wL2lzc3Vlcy82KVxuICAgICAgdmFyIHJlc3RyaWN0ZWRQb3NpdGlvbiA9IF90aGlzLnByb3BzLnJlc3RyaWN0UG9zaXRpb24gPyByZXN0cmljdFBvc2l0aW9uKF90aGlzLnByb3BzLmNyb3AsIF90aGlzLm1lZGlhU2l6ZSwgX3RoaXMuc3RhdGUuY3JvcFNpemUsIF90aGlzLnByb3BzLnpvb20sIF90aGlzLnByb3BzLnJvdGF0aW9uKSA6IF90aGlzLnByb3BzLmNyb3A7XG4gICAgICByZXR1cm4gY29tcHV0ZUNyb3BwZWRBcmVhKHJlc3RyaWN0ZWRQb3NpdGlvbiwgX3RoaXMubWVkaWFTaXplLCBfdGhpcy5zdGF0ZS5jcm9wU2l6ZSwgX3RoaXMuZ2V0QXNwZWN0KCksIF90aGlzLnByb3BzLnpvb20sIF90aGlzLnByb3BzLnJvdGF0aW9uLCBfdGhpcy5wcm9wcy5yZXN0cmljdFBvc2l0aW9uKTtcbiAgICB9O1xuICAgIF90aGlzLmVtaXRDcm9wRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjcm9wRGF0YSA9IF90aGlzLmdldENyb3BEYXRhKCk7XG4gICAgICBpZiAoIWNyb3BEYXRhKSByZXR1cm47XG4gICAgICB2YXIgY3JvcHBlZEFyZWFQZXJjZW50YWdlcyA9IGNyb3BEYXRhLmNyb3BwZWRBcmVhUGVyY2VudGFnZXMsXG4gICAgICAgIGNyb3BwZWRBcmVhUGl4ZWxzID0gY3JvcERhdGEuY3JvcHBlZEFyZWFQaXhlbHM7XG4gICAgICBpZiAoX3RoaXMucHJvcHMub25Dcm9wQ29tcGxldGUpIHtcbiAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wQ29tcGxldGUoY3JvcHBlZEFyZWFQZXJjZW50YWdlcywgY3JvcHBlZEFyZWFQaXhlbHMpO1xuICAgICAgfVxuICAgICAgaWYgKF90aGlzLnByb3BzLm9uQ3JvcEFyZWFDaGFuZ2UpIHtcbiAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wQXJlYUNoYW5nZShjcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLCBjcm9wcGVkQXJlYVBpeGVscyk7XG4gICAgICB9XG4gICAgfTtcbiAgICBfdGhpcy5lbWl0Q3JvcEFyZWFDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgY3JvcERhdGEgPSBfdGhpcy5nZXRDcm9wRGF0YSgpO1xuICAgICAgaWYgKCFjcm9wRGF0YSkgcmV0dXJuO1xuICAgICAgdmFyIGNyb3BwZWRBcmVhUGVyY2VudGFnZXMgPSBjcm9wRGF0YS5jcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLFxuICAgICAgICBjcm9wcGVkQXJlYVBpeGVscyA9IGNyb3BEYXRhLmNyb3BwZWRBcmVhUGl4ZWxzO1xuICAgICAgaWYgKF90aGlzLnByb3BzLm9uQ3JvcEFyZWFDaGFuZ2UpIHtcbiAgICAgICAgX3RoaXMucHJvcHMub25Dcm9wQXJlYUNoYW5nZShjcm9wcGVkQXJlYVBlcmNlbnRhZ2VzLCBjcm9wcGVkQXJlYVBpeGVscyk7XG4gICAgICB9XG4gICAgfTtcbiAgICBfdGhpcy5yZWNvbXB1dGVDcm9wUG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2EsIF9iO1xuICAgICAgaWYgKCFfdGhpcy5zdGF0ZS5jcm9wU2l6ZSkgcmV0dXJuO1xuICAgICAgdmFyIGFkanVzdGVkQ3JvcCA9IF90aGlzLnByb3BzLmNyb3A7XG4gICAgICAvLyBPbmx5IHNjYWxlIGlmIHdlJ3JlIGluaXRpYWxpemVkIGFuZCB0aGlzIGlzIGEgbGVnaXRpbWF0ZSByZXNpemVcbiAgICAgIGlmIChfdGhpcy5pc0luaXRpYWxpemVkICYmICgoX2EgPSBfdGhpcy5wcmV2aW91c0Nyb3BTaXplKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Eud2lkdGgpICYmICgoX2IgPSBfdGhpcy5wcmV2aW91c0Nyb3BTaXplKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuaGVpZ2h0KSkge1xuICAgICAgICB2YXIgc2l6ZUNoYW5nZWQgPSBNYXRoLmFicyhfdGhpcy5wcmV2aW91c0Nyb3BTaXplLndpZHRoIC0gX3RoaXMuc3RhdGUuY3JvcFNpemUud2lkdGgpID4gMWUtNiB8fCBNYXRoLmFicyhfdGhpcy5wcmV2aW91c0Nyb3BTaXplLmhlaWdodCAtIF90aGlzLnN0YXRlLmNyb3BTaXplLmhlaWdodCkgPiAxZS02O1xuICAgICAgICBpZiAoc2l6ZUNoYW5nZWQpIHtcbiAgICAgICAgICB2YXIgc2NhbGVYID0gX3RoaXMuc3RhdGUuY3JvcFNpemUud2lkdGggLyBfdGhpcy5wcmV2aW91c0Nyb3BTaXplLndpZHRoO1xuICAgICAgICAgIHZhciBzY2FsZVkgPSBfdGhpcy5zdGF0ZS5jcm9wU2l6ZS5oZWlnaHQgLyBfdGhpcy5wcmV2aW91c0Nyb3BTaXplLmhlaWdodDtcbiAgICAgICAgICBhZGp1c3RlZENyb3AgPSB7XG4gICAgICAgICAgICB4OiBfdGhpcy5wcm9wcy5jcm9wLnggKiBzY2FsZVgsXG4gICAgICAgICAgICB5OiBfdGhpcy5wcm9wcy5jcm9wLnkgKiBzY2FsZVlcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgbmV3UG9zaXRpb24gPSBfdGhpcy5wcm9wcy5yZXN0cmljdFBvc2l0aW9uID8gcmVzdHJpY3RQb3NpdGlvbihhZGp1c3RlZENyb3AsIF90aGlzLm1lZGlhU2l6ZSwgX3RoaXMuc3RhdGUuY3JvcFNpemUsIF90aGlzLnByb3BzLnpvb20sIF90aGlzLnByb3BzLnJvdGF0aW9uKSA6IGFkanVzdGVkQ3JvcDtcbiAgICAgIF90aGlzLnByZXZpb3VzQ3JvcFNpemUgPSBfdGhpcy5zdGF0ZS5jcm9wU2l6ZTtcbiAgICAgIF90aGlzLnByb3BzLm9uQ3JvcENoYW5nZShuZXdQb3NpdGlvbik7XG4gICAgICBfdGhpcy5lbWl0Q3JvcERhdGEoKTtcbiAgICB9O1xuICAgIF90aGlzLm9uS2V5RG93biA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgdmFyIF9hLCBfYjtcbiAgICAgIHZhciBfYyA9IF90aGlzLnByb3BzLFxuICAgICAgICBjcm9wID0gX2MuY3JvcCxcbiAgICAgICAgb25Dcm9wQ2hhbmdlID0gX2Mub25Dcm9wQ2hhbmdlLFxuICAgICAgICBrZXlib2FyZFN0ZXAgPSBfYy5rZXlib2FyZFN0ZXAsXG4gICAgICAgIHpvb20gPSBfYy56b29tLFxuICAgICAgICByb3RhdGlvbiA9IF9jLnJvdGF0aW9uO1xuICAgICAgdmFyIHN0ZXAgPSBrZXlib2FyZFN0ZXA7XG4gICAgICBpZiAoIV90aGlzLnN0YXRlLmNyb3BTaXplKSByZXR1cm47XG4gICAgICAvLyBpZiB0aGUgc2hpZnQga2V5IGlzIHByZXNzZWQsIHJlZHVjZSB0aGUgc3RlcCB0byBhbGxvdyBmaW5lciBjb250cm9sXG4gICAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgc3RlcCAqPSAwLjI7XG4gICAgICB9XG4gICAgICB2YXIgbmV3Q3JvcCA9IF9fYXNzaWduKHt9LCBjcm9wKTtcbiAgICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgIG5ld0Nyb3AueSAtPSBzdGVwO1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgICAgbmV3Q3JvcC55ICs9IHN0ZXA7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnQXJyb3dMZWZ0JzpcbiAgICAgICAgICBuZXdDcm9wLnggLT0gc3RlcDtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBcnJvd1JpZ2h0JzpcbiAgICAgICAgICBuZXdDcm9wLnggKz0gc3RlcDtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChfdGhpcy5wcm9wcy5yZXN0cmljdFBvc2l0aW9uKSB7XG4gICAgICAgIG5ld0Nyb3AgPSByZXN0cmljdFBvc2l0aW9uKG5ld0Nyb3AsIF90aGlzLm1lZGlhU2l6ZSwgX3RoaXMuc3RhdGUuY3JvcFNpemUsIHpvb20sIHJvdGF0aW9uKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXZlbnQucmVwZWF0KSB7XG4gICAgICAgIChfYiA9IChfYSA9IF90aGlzLnByb3BzKS5vbkludGVyYWN0aW9uU3RhcnQpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKF9hKTtcbiAgICAgIH1cbiAgICAgIG9uQ3JvcENoYW5nZShuZXdDcm9wKTtcbiAgICB9O1xuICAgIF90aGlzLm9uS2V5VXAgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHZhciBfYSwgX2I7XG4gICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgY2FzZSAnQXJyb3dMZWZ0JzpcbiAgICAgICAgY2FzZSAnQXJyb3dSaWdodCc6XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBfdGhpcy5lbWl0Q3JvcERhdGEoKTtcbiAgICAgIChfYiA9IChfYSA9IF90aGlzLnByb3BzKS5vbkludGVyYWN0aW9uRW5kKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY2FsbChfYSk7XG4gICAgfTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgQ3JvcHBlci5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnREb2MgfHwgIXRoaXMuY3VycmVudFdpbmRvdykgcmV0dXJuO1xuICAgIGlmICh0aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgaWYgKHRoaXMuY29udGFpbmVyUmVmLm93bmVyRG9jdW1lbnQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50RG9jID0gdGhpcy5jb250YWluZXJSZWYub3duZXJEb2N1bWVudDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmN1cnJlbnREb2MuZGVmYXVsdFZpZXcpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50V2luZG93ID0gdGhpcy5jdXJyZW50RG9jLmRlZmF1bHRWaWV3O1xuICAgICAgfVxuICAgICAgdGhpcy5pbml0UmVzaXplT2JzZXJ2ZXIoKTtcbiAgICAgIC8vIG9ubHkgYWRkIHdpbmRvdyByZXNpemUgbGlzdGVuZXIgaWYgUmVzaXplT2JzZXJ2ZXIgaXMgbm90IHN1cHBvcnRlZC4gT3RoZXJ3aXNlLCBpdCB3b3VsZCBiZSByZWR1bmRhbnRcbiAgICAgIGlmICh0eXBlb2Ygd2luZG93LlJlc2l6ZU9ic2VydmVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aGlzLmN1cnJlbnRXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5jb21wdXRlU2l6ZXMpO1xuICAgICAgfVxuICAgICAgdGhpcy5wcm9wcy56b29tV2l0aFNjcm9sbCAmJiB0aGlzLmNvbnRhaW5lclJlZi5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsIHRoaXMub25XaGVlbCwge1xuICAgICAgICBwYXNzaXZlOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICB0aGlzLmNvbnRhaW5lclJlZi5hZGRFdmVudExpc3RlbmVyKCdnZXN0dXJlc3RhcnQnLCB0aGlzLm9uR2VzdHVyZVN0YXJ0KTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50RG9jLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMub25TY3JvbGwpO1xuICAgIGlmICghdGhpcy5wcm9wcy5kaXNhYmxlQXV0b21hdGljU3R5bGVzSW5qZWN0aW9uKSB7XG4gICAgICB0aGlzLnN0eWxlUmVmID0gdGhpcy5jdXJyZW50RG9jLmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgICB0aGlzLnN0eWxlUmVmLnNldEF0dHJpYnV0ZSgndHlwZScsICd0ZXh0L2NzcycpO1xuICAgICAgaWYgKHRoaXMucHJvcHMubm9uY2UpIHtcbiAgICAgICAgdGhpcy5zdHlsZVJlZi5zZXRBdHRyaWJ1dGUoJ25vbmNlJywgdGhpcy5wcm9wcy5ub25jZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0eWxlUmVmLmlubmVySFRNTCA9IGNzc18yNDh6O1xuICAgICAgdGhpcy5jdXJyZW50RG9jLmhlYWQuYXBwZW5kQ2hpbGQodGhpcy5zdHlsZVJlZik7XG4gICAgfVxuICAgIC8vIHdoZW4gcmVuZGVyZWQgdmlhIFNTUiwgdGhlIGltYWdlIGNhbiBhbHJlYWR5IGJlIGxvYWRlZCBhbmQgaXRzIG9uTG9hZCBjYWxsYmFjayB3aWxsIG5ldmVyIGJlIGNhbGxlZFxuICAgIGlmICh0aGlzLmltYWdlUmVmLmN1cnJlbnQgJiYgdGhpcy5pbWFnZVJlZi5jdXJyZW50LmNvbXBsZXRlKSB7XG4gICAgICB0aGlzLm9uTWVkaWFMb2FkKCk7XG4gICAgfVxuICAgIC8vIHNldCBpbWFnZSBhbmQgdmlkZW8gcmVmcyBpbiB0aGUgcGFyZW50IGlmIHRoZSBjYWxsYmFja3MgZXhpc3RcbiAgICBpZiAodGhpcy5wcm9wcy5zZXRJbWFnZVJlZikge1xuICAgICAgdGhpcy5wcm9wcy5zZXRJbWFnZVJlZih0aGlzLmltYWdlUmVmKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJvcHMuc2V0VmlkZW9SZWYpIHtcbiAgICAgIHRoaXMucHJvcHMuc2V0VmlkZW9SZWYodGhpcy52aWRlb1JlZik7XG4gICAgfVxuICAgIGlmICh0aGlzLnByb3BzLnNldENyb3BwZXJSZWYpIHtcbiAgICAgIHRoaXMucHJvcHMuc2V0Q3JvcHBlclJlZih0aGlzLmNyb3BwZXJSZWYpO1xuICAgIH1cbiAgfTtcbiAgQ3JvcHBlci5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9hLCBfYjtcbiAgICBpZiAoIXRoaXMuY3VycmVudERvYyB8fCAhdGhpcy5jdXJyZW50V2luZG93KSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLmN1cnJlbnRXaW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5jb21wdXRlU2l6ZXMpO1xuICAgIH1cbiAgICAoX2EgPSB0aGlzLnJlc2l6ZU9ic2VydmVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZGlzY29ubmVjdCgpO1xuICAgIGlmICh0aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgdGhpcy5jb250YWluZXJSZWYucmVtb3ZlRXZlbnRMaXN0ZW5lcignZ2VzdHVyZXN0YXJ0JywgdGhpcy5wcmV2ZW50Wm9vbVNhZmFyaSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnN0eWxlUmVmKSB7XG4gICAgICAoX2IgPSB0aGlzLnN0eWxlUmVmLnBhcmVudE5vZGUpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5yZW1vdmVDaGlsZCh0aGlzLnN0eWxlUmVmKTtcbiAgICB9XG4gICAgdGhpcy5jbGVhbkV2ZW50cygpO1xuICAgIHRoaXMucHJvcHMuem9vbVdpdGhTY3JvbGwgJiYgdGhpcy5jbGVhclNjcm9sbEV2ZW50KCk7XG4gIH07XG4gIENyb3BwZXIucHJvdG90eXBlLmNvbXBvbmVudERpZFVwZGF0ZSA9IGZ1bmN0aW9uIChwcmV2UHJvcHMpIHtcbiAgICB2YXIgX2EsIF9iLCBfYywgX2QsIF9lLCBfZiwgX2csIF9oLCBfajtcbiAgICBpZiAocHJldlByb3BzLnJvdGF0aW9uICE9PSB0aGlzLnByb3BzLnJvdGF0aW9uKSB7XG4gICAgICB0aGlzLmNvbXB1dGVTaXplcygpO1xuICAgICAgdGhpcy5yZWNvbXB1dGVDcm9wUG9zaXRpb24oKTtcbiAgICB9IGVsc2UgaWYgKHByZXZQcm9wcy5hc3BlY3QgIT09IHRoaXMucHJvcHMuYXNwZWN0KSB7XG4gICAgICB0aGlzLmNvbXB1dGVTaXplcygpO1xuICAgIH0gZWxzZSBpZiAocHJldlByb3BzLm9iamVjdEZpdCAhPT0gdGhpcy5wcm9wcy5vYmplY3RGaXQpIHtcbiAgICAgIHRoaXMuY29tcHV0ZVNpemVzKCk7XG4gICAgfSBlbHNlIGlmIChwcmV2UHJvcHMuem9vbSAhPT0gdGhpcy5wcm9wcy56b29tKSB7XG4gICAgICB0aGlzLnJlY29tcHV0ZUNyb3BQb3NpdGlvbigpO1xuICAgIH0gZWxzZSBpZiAoKChfYSA9IHByZXZQcm9wcy5jcm9wU2l6ZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmhlaWdodCkgIT09ICgoX2IgPSB0aGlzLnByb3BzLmNyb3BTaXplKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuaGVpZ2h0KSB8fCAoKF9jID0gcHJldlByb3BzLmNyb3BTaXplKSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Mud2lkdGgpICE9PSAoKF9kID0gdGhpcy5wcm9wcy5jcm9wU2l6ZSkgPT09IG51bGwgfHwgX2QgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9kLndpZHRoKSkge1xuICAgICAgdGhpcy5jb21wdXRlU2l6ZXMoKTtcbiAgICB9IGVsc2UgaWYgKCgoX2UgPSBwcmV2UHJvcHMuY3JvcCkgPT09IG51bGwgfHwgX2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9lLngpICE9PSAoKF9mID0gdGhpcy5wcm9wcy5jcm9wKSA9PT0gbnVsbCB8fCBfZiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2YueCkgfHwgKChfZyA9IHByZXZQcm9wcy5jcm9wKSA9PT0gbnVsbCB8fCBfZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2cueSkgIT09ICgoX2ggPSB0aGlzLnByb3BzLmNyb3ApID09PSBudWxsIHx8IF9oID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfaC55KSkge1xuICAgICAgdGhpcy5lbWl0Q3JvcEFyZWFDaGFuZ2UoKTtcbiAgICB9XG4gICAgaWYgKHByZXZQcm9wcy56b29tV2l0aFNjcm9sbCAhPT0gdGhpcy5wcm9wcy56b29tV2l0aFNjcm9sbCAmJiB0aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgdGhpcy5wcm9wcy56b29tV2l0aFNjcm9sbCA/IHRoaXMuY29udGFpbmVyUmVmLmFkZEV2ZW50TGlzdGVuZXIoJ3doZWVsJywgdGhpcy5vbldoZWVsLCB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlXG4gICAgICB9KSA6IHRoaXMuY2xlYXJTY3JvbGxFdmVudCgpO1xuICAgIH1cbiAgICBpZiAocHJldlByb3BzLnZpZGVvICE9PSB0aGlzLnByb3BzLnZpZGVvKSB7XG4gICAgICAoX2ogPSB0aGlzLnZpZGVvUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9qID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfai5sb2FkKCk7XG4gICAgfVxuICAgIHZhciBvYmplY3RGaXQgPSB0aGlzLmdldE9iamVjdEZpdCgpO1xuICAgIGlmIChvYmplY3RGaXQgIT09IHRoaXMuc3RhdGUubWVkaWFPYmplY3RGaXQpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBtZWRpYU9iamVjdEZpdDogb2JqZWN0Rml0XG4gICAgICB9LCB0aGlzLmNvbXB1dGVTaXplcyk7XG4gICAgfVxuICB9O1xuICBDcm9wcGVyLnByb3RvdHlwZS5nZXRBc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9hID0gdGhpcy5wcm9wcyxcbiAgICAgIGNyb3BTaXplID0gX2EuY3JvcFNpemUsXG4gICAgICBhc3BlY3QgPSBfYS5hc3BlY3Q7XG4gICAgaWYgKGNyb3BTaXplKSB7XG4gICAgICByZXR1cm4gY3JvcFNpemUud2lkdGggLyBjcm9wU2l6ZS5oZWlnaHQ7XG4gICAgfVxuICAgIHJldHVybiBhc3BlY3Q7XG4gIH07XG4gIENyb3BwZXIucHJvdG90eXBlLmdldE9iamVjdEZpdCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2EsIF9iLCBfYywgX2Q7XG4gICAgaWYgKHRoaXMucHJvcHMub2JqZWN0Rml0ID09PSAnY292ZXInKSB7XG4gICAgICB2YXIgbWVkaWFSZWYgPSB0aGlzLmltYWdlUmVmLmN1cnJlbnQgfHwgdGhpcy52aWRlb1JlZi5jdXJyZW50O1xuICAgICAgaWYgKG1lZGlhUmVmICYmIHRoaXMuY29udGFpbmVyUmVmKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyUmVjdCA9IHRoaXMuY29udGFpbmVyUmVmLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB2YXIgY29udGFpbmVyQXNwZWN0ID0gdGhpcy5jb250YWluZXJSZWN0LndpZHRoIC8gdGhpcy5jb250YWluZXJSZWN0LmhlaWdodDtcbiAgICAgICAgdmFyIG5hdHVyYWxXaWR0aCA9ICgoX2EgPSB0aGlzLmltYWdlUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5uYXR1cmFsV2lkdGgpIHx8ICgoX2IgPSB0aGlzLnZpZGVvUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi52aWRlb1dpZHRoKSB8fCAwO1xuICAgICAgICB2YXIgbmF0dXJhbEhlaWdodCA9ICgoX2MgPSB0aGlzLmltYWdlUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5uYXR1cmFsSGVpZ2h0KSB8fCAoKF9kID0gdGhpcy52aWRlb1JlZi5jdXJyZW50KSA9PT0gbnVsbCB8fCBfZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2QudmlkZW9IZWlnaHQpIHx8IDA7XG4gICAgICAgIHZhciBtZWRpYUFzcGVjdCA9IG5hdHVyYWxXaWR0aCAvIG5hdHVyYWxIZWlnaHQ7XG4gICAgICAgIHJldHVybiBtZWRpYUFzcGVjdCA8IGNvbnRhaW5lckFzcGVjdCA/ICdob3Jpem9udGFsLWNvdmVyJyA6ICd2ZXJ0aWNhbC1jb3Zlcic7XG4gICAgICB9XG4gICAgICByZXR1cm4gJ2hvcml6b250YWwtY292ZXInO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9wcy5vYmplY3RGaXQ7XG4gIH07XG4gIENyb3BwZXIucHJvdG90eXBlLm9uUGluY2hTdGFydCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHBvaW50QSA9IENyb3BwZXIuZ2V0VG91Y2hQb2ludChlLnRvdWNoZXNbMF0pO1xuICAgIHZhciBwb2ludEIgPSBDcm9wcGVyLmdldFRvdWNoUG9pbnQoZS50b3VjaGVzWzFdKTtcbiAgICB0aGlzLmxhc3RQaW5jaERpc3RhbmNlID0gZ2V0RGlzdGFuY2VCZXR3ZWVuUG9pbnRzKHBvaW50QSwgcG9pbnRCKTtcbiAgICB0aGlzLmxhc3RQaW5jaFJvdGF0aW9uID0gZ2V0Um90YXRpb25CZXR3ZWVuUG9pbnRzKHBvaW50QSwgcG9pbnRCKTtcbiAgICB0aGlzLm9uRHJhZ1N0YXJ0KGdldENlbnRlcihwb2ludEEsIHBvaW50QikpO1xuICB9O1xuICBDcm9wcGVyLnByb3RvdHlwZS5vblBpbmNoTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcbiAgICBpZiAoIXRoaXMuY3VycmVudERvYyB8fCAhdGhpcy5jdXJyZW50V2luZG93KSByZXR1cm47XG4gICAgdmFyIHBvaW50QSA9IENyb3BwZXIuZ2V0VG91Y2hQb2ludChlLnRvdWNoZXNbMF0pO1xuICAgIHZhciBwb2ludEIgPSBDcm9wcGVyLmdldFRvdWNoUG9pbnQoZS50b3VjaGVzWzFdKTtcbiAgICB2YXIgY2VudGVyID0gZ2V0Q2VudGVyKHBvaW50QSwgcG9pbnRCKTtcbiAgICB0aGlzLm9uRHJhZyhjZW50ZXIpO1xuICAgIGlmICh0aGlzLnJhZlBpbmNoVGltZW91dCkgdGhpcy5jdXJyZW50V2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmFmUGluY2hUaW1lb3V0KTtcbiAgICB0aGlzLnJhZlBpbmNoVGltZW91dCA9IHRoaXMuY3VycmVudFdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGRpc3RhbmNlID0gZ2V0RGlzdGFuY2VCZXR3ZWVuUG9pbnRzKHBvaW50QSwgcG9pbnRCKTtcbiAgICAgIHZhciBuZXdab29tID0gX3RoaXMucHJvcHMuem9vbSAqIChkaXN0YW5jZSAvIF90aGlzLmxhc3RQaW5jaERpc3RhbmNlKTtcbiAgICAgIF90aGlzLnNldE5ld1pvb20obmV3Wm9vbSwgY2VudGVyLCB7XG4gICAgICAgIHNob3VsZFVwZGF0ZVBvc2l0aW9uOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICBfdGhpcy5sYXN0UGluY2hEaXN0YW5jZSA9IGRpc3RhbmNlO1xuICAgICAgdmFyIHJvdGF0aW9uID0gZ2V0Um90YXRpb25CZXR3ZWVuUG9pbnRzKHBvaW50QSwgcG9pbnRCKTtcbiAgICAgIHZhciBuZXdSb3RhdGlvbiA9IF90aGlzLnByb3BzLnJvdGF0aW9uICsgKHJvdGF0aW9uIC0gX3RoaXMubGFzdFBpbmNoUm90YXRpb24pO1xuICAgICAgX3RoaXMucHJvcHMub25Sb3RhdGlvbkNoYW5nZSAmJiBfdGhpcy5wcm9wcy5vblJvdGF0aW9uQ2hhbmdlKG5ld1JvdGF0aW9uKTtcbiAgICAgIF90aGlzLmxhc3RQaW5jaFJvdGF0aW9uID0gcm90YXRpb247XG4gICAgfSk7XG4gIH07XG4gIENyb3BwZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgIHZhciBfYTtcbiAgICB2YXIgX2IgPSB0aGlzLnByb3BzLFxuICAgICAgaW1hZ2UgPSBfYi5pbWFnZSxcbiAgICAgIHZpZGVvID0gX2IudmlkZW8sXG4gICAgICBtZWRpYVByb3BzID0gX2IubWVkaWFQcm9wcyxcbiAgICAgIGNyb3BwZXJQcm9wcyA9IF9iLmNyb3BwZXJQcm9wcyxcbiAgICAgIHRyYW5zZm9ybSA9IF9iLnRyYW5zZm9ybSxcbiAgICAgIF9jID0gX2IuY3JvcCxcbiAgICAgIHggPSBfYy54LFxuICAgICAgeSA9IF9jLnksXG4gICAgICByb3RhdGlvbiA9IF9iLnJvdGF0aW9uLFxuICAgICAgem9vbSA9IF9iLnpvb20sXG4gICAgICBjcm9wU2hhcGUgPSBfYi5jcm9wU2hhcGUsXG4gICAgICBzaG93R3JpZCA9IF9iLnNob3dHcmlkLFxuICAgICAgcm91bmRDcm9wQXJlYVBpeGVscyA9IF9iLnJvdW5kQ3JvcEFyZWFQaXhlbHMsXG4gICAgICBfZCA9IF9iLnN0eWxlLFxuICAgICAgY29udGFpbmVyU3R5bGUgPSBfZC5jb250YWluZXJTdHlsZSxcbiAgICAgIGNyb3BBcmVhU3R5bGUgPSBfZC5jcm9wQXJlYVN0eWxlLFxuICAgICAgbWVkaWFTdHlsZSA9IF9kLm1lZGlhU3R5bGUsXG4gICAgICBfZSA9IF9iLmNsYXNzZXMsXG4gICAgICBjb250YWluZXJDbGFzc05hbWUgPSBfZS5jb250YWluZXJDbGFzc05hbWUsXG4gICAgICBjcm9wQXJlYUNsYXNzTmFtZSA9IF9lLmNyb3BBcmVhQ2xhc3NOYW1lLFxuICAgICAgbWVkaWFDbGFzc05hbWUgPSBfZS5tZWRpYUNsYXNzTmFtZTtcbiAgICB2YXIgb2JqZWN0Rml0ID0gKF9hID0gdGhpcy5zdGF0ZS5tZWRpYU9iamVjdEZpdCkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogdGhpcy5nZXRPYmplY3RGaXQoKTtcbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICBvbk1vdXNlRG93bjogdGhpcy5vbk1vdXNlRG93bixcbiAgICAgIG9uVG91Y2hTdGFydDogdGhpcy5vblRvdWNoU3RhcnQsXG4gICAgICByZWY6IGZ1bmN0aW9uIHJlZihlbCkge1xuICAgICAgICByZXR1cm4gX3RoaXMuY29udGFpbmVyUmVmID0gZWw7XG4gICAgICB9LFxuICAgICAgXCJkYXRhLXRlc3RpZFwiOiBcImNvbnRhaW5lclwiLFxuICAgICAgc3R5bGU6IGNvbnRhaW5lclN0eWxlLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKCdyZWFjdEVhc3lDcm9wX0NvbnRhaW5lcicsIGNvbnRhaW5lckNsYXNzTmFtZSlcbiAgICB9LCBpbWFnZSA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIiwgX19hc3NpZ24oe1xuICAgICAgYWx0OiBcIlwiLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKCdyZWFjdEVhc3lDcm9wX0ltYWdlJywgb2JqZWN0Rml0ID09PSAnY29udGFpbicgJiYgJ3JlYWN0RWFzeUNyb3BfQ29udGFpbicsIG9iamVjdEZpdCA9PT0gJ2hvcml6b250YWwtY292ZXInICYmICdyZWFjdEVhc3lDcm9wX0NvdmVyX0hvcml6b250YWwnLCBvYmplY3RGaXQgPT09ICd2ZXJ0aWNhbC1jb3ZlcicgJiYgJ3JlYWN0RWFzeUNyb3BfQ292ZXJfVmVydGljYWwnLCBtZWRpYUNsYXNzTmFtZSlcbiAgICB9LCBtZWRpYVByb3BzLCB7XG4gICAgICBzcmM6IGltYWdlLFxuICAgICAgcmVmOiB0aGlzLmltYWdlUmVmLFxuICAgICAgc3R5bGU6IF9fYXNzaWduKF9fYXNzaWduKHt9LCBtZWRpYVN0eWxlKSwge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zZm9ybSB8fCBcInRyYW5zbGF0ZShcIi5jb25jYXQoeCwgXCJweCwgXCIpLmNvbmNhdCh5LCBcInB4KSByb3RhdGUoXCIpLmNvbmNhdChyb3RhdGlvbiwgXCJkZWcpIHNjYWxlKFwiKS5jb25jYXQoem9vbSwgXCIpXCIpXG4gICAgICB9KSxcbiAgICAgIG9uTG9hZDogdGhpcy5vbk1lZGlhTG9hZFxuICAgIH0pKSA6IHZpZGVvICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiLCBfX2Fzc2lnbih7XG4gICAgICBhdXRvUGxheTogdHJ1ZSxcbiAgICAgIHBsYXlzSW5saW5lOiB0cnVlLFxuICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgIG11dGVkOiB0cnVlLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKCdyZWFjdEVhc3lDcm9wX1ZpZGVvJywgb2JqZWN0Rml0ID09PSAnY29udGFpbicgJiYgJ3JlYWN0RWFzeUNyb3BfQ29udGFpbicsIG9iamVjdEZpdCA9PT0gJ2hvcml6b250YWwtY292ZXInICYmICdyZWFjdEVhc3lDcm9wX0NvdmVyX0hvcml6b250YWwnLCBvYmplY3RGaXQgPT09ICd2ZXJ0aWNhbC1jb3ZlcicgJiYgJ3JlYWN0RWFzeUNyb3BfQ292ZXJfVmVydGljYWwnLCBtZWRpYUNsYXNzTmFtZSlcbiAgICB9LCBtZWRpYVByb3BzLCB7XG4gICAgICByZWY6IHRoaXMudmlkZW9SZWYsXG4gICAgICBvbkxvYWRlZE1ldGFkYXRhOiB0aGlzLm9uTWVkaWFMb2FkLFxuICAgICAgc3R5bGU6IF9fYXNzaWduKF9fYXNzaWduKHt9LCBtZWRpYVN0eWxlKSwge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zZm9ybSB8fCBcInRyYW5zbGF0ZShcIi5jb25jYXQoeCwgXCJweCwgXCIpLmNvbmNhdCh5LCBcInB4KSByb3RhdGUoXCIpLmNvbmNhdChyb3RhdGlvbiwgXCJkZWcpIHNjYWxlKFwiKS5jb25jYXQoem9vbSwgXCIpXCIpXG4gICAgICB9KSxcbiAgICAgIGNvbnRyb2xzOiBmYWxzZVxuICAgIH0pLCAoQXJyYXkuaXNBcnJheSh2aWRlbykgPyB2aWRlbyA6IFt7XG4gICAgICBzcmM6IHZpZGVvXG4gICAgfV0pLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJzb3VyY2VcIiwgX19hc3NpZ24oe1xuICAgICAgICBrZXk6IGl0ZW0uc3JjXG4gICAgICB9LCBpdGVtKSk7XG4gICAgfSkpLCB0aGlzLnN0YXRlLmNyb3BTaXplICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgX19hc3NpZ24oe1xuICAgICAgcmVmOiB0aGlzLmNyb3BwZXJSZWYsXG4gICAgICBzdHlsZTogX19hc3NpZ24oX19hc3NpZ24oe30sIGNyb3BBcmVhU3R5bGUpLCB7XG4gICAgICAgIHdpZHRoOiByb3VuZENyb3BBcmVhUGl4ZWxzID8gTWF0aC5yb3VuZCh0aGlzLnN0YXRlLmNyb3BTaXplLndpZHRoKSA6IHRoaXMuc3RhdGUuY3JvcFNpemUud2lkdGgsXG4gICAgICAgIGhlaWdodDogcm91bmRDcm9wQXJlYVBpeGVscyA/IE1hdGgucm91bmQodGhpcy5zdGF0ZS5jcm9wU2l6ZS5oZWlnaHQpIDogdGhpcy5zdGF0ZS5jcm9wU2l6ZS5oZWlnaHRcbiAgICAgIH0pLFxuICAgICAgdGFiSW5kZXg6IDAsXG4gICAgICBvbktleURvd246IHRoaXMub25LZXlEb3duLFxuICAgICAgb25LZXlVcDogdGhpcy5vbktleVVwLFxuICAgICAgXCJkYXRhLXRlc3RpZFwiOiBcImNyb3BwZXJcIixcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcygncmVhY3RFYXN5Q3JvcF9Dcm9wQXJlYScsIGNyb3BTaGFwZSA9PT0gJ3JvdW5kJyAmJiAncmVhY3RFYXN5Q3JvcF9Dcm9wQXJlYVJvdW5kJywgc2hvd0dyaWQgJiYgJ3JlYWN0RWFzeUNyb3BfQ3JvcEFyZWFHcmlkJywgY3JvcEFyZWFDbGFzc05hbWUpXG4gICAgfSwgY3JvcHBlclByb3BzKSkpO1xuICB9O1xuICBDcm9wcGVyLmRlZmF1bHRQcm9wcyA9IHtcbiAgICB6b29tOiAxLFxuICAgIHJvdGF0aW9uOiAwLFxuICAgIGFzcGVjdDogNCAvIDMsXG4gICAgbWF4Wm9vbTogTUFYX1pPT00sXG4gICAgbWluWm9vbTogTUlOX1pPT00sXG4gICAgY3JvcFNoYXBlOiAncmVjdCcsXG4gICAgb2JqZWN0Rml0OiAnY29udGFpbicsXG4gICAgc2hvd0dyaWQ6IHRydWUsXG4gICAgc3R5bGU6IHt9LFxuICAgIGNsYXNzZXM6IHt9LFxuICAgIG1lZGlhUHJvcHM6IHt9LFxuICAgIGNyb3BwZXJQcm9wczoge30sXG4gICAgem9vbVNwZWVkOiAxLFxuICAgIHJlc3RyaWN0UG9zaXRpb246IHRydWUsXG4gICAgem9vbVdpdGhTY3JvbGw6IHRydWUsXG4gICAga2V5Ym9hcmRTdGVwOiBLRVlCT0FSRF9TVEVQXG4gIH07XG4gIENyb3BwZXIuZ2V0TW91c2VQb2ludCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IE51bWJlcihlLmNsaWVudFgpLFxuICAgICAgeTogTnVtYmVyKGUuY2xpZW50WSlcbiAgICB9O1xuICB9O1xuICBDcm9wcGVyLmdldFRvdWNoUG9pbnQgPSBmdW5jdGlvbiAodG91Y2gpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogTnVtYmVyKHRvdWNoLmNsaWVudFgpLFxuICAgICAgeTogTnVtYmVyKHRvdWNoLmNsaWVudFkpXG4gICAgfTtcbiAgfTtcbiAgcmV0dXJuIENyb3BwZXI7XG59KFJlYWN0LkNvbXBvbmVudCk7XG5cbmV4cG9ydCB7IENyb3BwZXIgYXMgZGVmYXVsdCwgZ2V0SW5pdGlhbENyb3BGcm9tQ3JvcHBlZEFyZWFQZXJjZW50YWdlcywgZ2V0SW5pdGlhbENyb3BGcm9tQ3JvcHBlZEFyZWFQaXhlbHMgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4Lm1vZHVsZS5tanMubWFwXG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/react-easy-crop/index.module.mjs\n"); /***/ }) }; ;