/* * 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/). */ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./src/js/animations.js": /*!******************************!*\ !*** ./src/js/animations.js ***! \******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var gsap_ScrollToPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/ScrollToPlugin */ \"./node_modules/gsap/ScrollToPlugin.js\");\n/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! gsap/ScrollTrigger */ \"./node_modules/gsap/ScrollTrigger.js\");\n/* harmony import */ var gsap_dist_SplitText_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! gsap/dist/SplitText.js */ \"./node_modules/gsap/dist/SplitText.js\");\n/* harmony import */ var gsap_dist_SplitText_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(gsap_dist_SplitText_js__WEBPACK_IMPORTED_MODULE_3__);\n\n\n\n\ngsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_ScrollToPlugin__WEBPACK_IMPORTED_MODULE_1__.ScrollToPlugin, gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger);\ngsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_dist_SplitText_js__WEBPACK_IMPORTED_MODULE_3__.SplitText);\n\n// scroll top\nlet h = document.querySelector(\".hero\").offsetHeight;\nlet arrow = document.querySelector(\".scroll_down\");\narrow.addEventListener(\"click\", function () {\n gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(window, {\n duration: 1.5,\n scrollTo: h,\n ease: \"power3\"\n });\n});\n\n// hero \n\nlet heroTimeline = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline();\nconst heroSpan = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.toArray(\".hero_span span\");\nlet heroHeight = document.querySelector(\".hero-text-container\");\nlet height = heroHeight.offsetHeight - 30;\nheroTimeline.to(\".hero-title img\", {\n y: 0,\n ease: \"power4.out\",\n duration: 1\n}, \"start\");\nheroTimeline.to(heroSpan, {\n y: 0,\n ease: \"power4.out\",\n duration: 0.6,\n stagger: 0.2\n}, \"<0.3\");\nheroTimeline.to(\".hero-subtitle p\", {\n opacity: 1,\n ease: \"power4.out\",\n duration: 3\n}, \"start\");\nheroTimeline.fromTo(\".hero-v-line\", {\n height: 0\n}, {\n height: `${heroHeight.offsetHeight - 30}`,\n ease: \"power4.out\",\n duration: 2\n}, \"start\");\n\n// text anim\nconst textAnim = document.querySelectorAll(\".text-anim\");\ntextAnim.forEach((quote, i) => {\n quote.split = new gsap_dist_SplitText_js__WEBPACK_IMPORTED_MODULE_3__.SplitText(quote, {\n type: \"words,chars\",\n wordsClass: \"split-line\"\n });\n gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(quote, {\n perspective: 800\n });\n let tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline({\n scrollTrigger: {\n trigger: quote\n }\n });\n tl.fromTo(quote.split.words, {\n autoAlpha: 0\n }, {\n duration: 1,\n autoAlpha: 1,\n ease: \"ease\",\n stagger: 0.03\n });\n});\n\n// // fade up text-animation\nconst fadeUp = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.toArray(\"[fade]\");\nfadeUp.forEach((el, i) => {\n const anim = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.fromTo(el, {\n autoAlpha: 0,\n y: 0\n }, {\n duration: 1.2,\n autoAlpha: 1,\n delay: 0.05\n });\n gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger.create({\n trigger: el,\n animation: anim,\n toggleActions: 'play none none none',\n once: true\n });\n});\n\n// animation card batch\n\ngsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger.batch('.row', {\n onEnter: batch => {\n batch.forEach((card, index) => gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(card, {\n opacity: 1,\n delay: index * 0.3,\n ease: \"power4.out\",\n duration: 1\n }));\n },\n once: true,\n start: \"30px bottom\",\n interval: 0.15\n});\n\n// parallax\nconst parallax = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.toArray(\".image_svg .p-desktop\");\nconsole.log(parallax);\nparallax.forEach(item => {\n gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(item, {\n yPercent: 30,\n ease: \"none\",\n scrollTrigger: {\n trigger: item,\n scrub: true\n }\n });\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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SUFBRztFQUN2QjNELHlDQUFPLENBQUMyRCxJQUFJLEVBQUU7SUFDWkMsUUFBUSxFQUFFLEVBQUU7SUFDWjdDLElBQUksRUFBRSxNQUFNO0lBQ1p1QixhQUFhLEVBQUU7TUFDYkMsT0FBTyxFQUFFb0IsSUFBSTtNQUNiRSxLQUFLLEVBQUU7SUFDVDtFQUNGLENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vc3JjL2pzL2FuaW1hdGlvbnMuanM/ODdlZiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnc2FwIH0gZnJvbSBcImdzYXBcIjtcbmltcG9ydCB7IFNjcm9sbFRvUGx1Z2luIH0gZnJvbSBcImdzYXAvU2Nyb2xsVG9QbHVnaW5cIjtcbmltcG9ydCB7IFNjcm9sbFRyaWdnZXIgfSBmcm9tIFwiZ3NhcC9TY3JvbGxUcmlnZ2VyXCI7XG5pbXBvcnQgeyBTcGxpdFRleHQgfSBmcm9tIFwiZ3NhcC9kaXN0L1NwbGl0VGV4dC5qc1wiO1xuXG5nc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRvUGx1Z2luLCBTY3JvbGxUcmlnZ2VyKTtcbmdzYXAucmVnaXN0ZXJQbHVnaW4oU3BsaXRUZXh0KTtcblxuXG4vLyAgc2Nyb2xsIHRvcFxubGV0IGggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmhlcm9cIikub2Zmc2V0SGVpZ2h0O1xubGV0IGFycm93ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5zY3JvbGxfZG93blwiKTtcbmFycm93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbigpe1xuICBnc2FwLnRvKHdpbmRvdywge2R1cmF0aW9uOiAxLjUsIHNjcm9sbFRvOiBoLCBlYXNlOiBcInBvd2VyM1wifSk7XG59KTtcblxuLy8gaGVybyBcblxubGV0IGhlcm9UaW1lbGluZSA9IGdzYXAudGltZWxpbmUoKTtcbmNvbnN0IGhlcm9TcGFuID0gZ3NhcC51dGlscy50b0FycmF5KFwiLmhlcm9fc3BhbiBzcGFuXCIpO1xubGV0IGhlcm9IZWlnaHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmhlcm8tdGV4dC1jb250YWluZXJcIik7IFxuXG5sZXQgaGVpZ2h0ID0gaGVyb0hlaWdodC5vZmZzZXRIZWlnaHQgLSAzMDtcblxuaGVyb1RpbWVsaW5lLnRvKFwiLmhlcm8tdGl0bGUgaW1nXCIsIHt5OiAwLCAgZWFzZTogXCJwb3dlcjQub3V0XCIsIGR1cmF0aW9uOiAxfSwgXCJzdGFydFwiKVxuaGVyb1RpbWVsaW5lLnRvKGhlcm9TcGFuLCB7eTogMCwgIGVhc2U6IFwicG93ZXI0Lm91dFwiLCBkdXJhdGlvbjogMC42LCBzdGFnZ2VyOiAwLjIsfSwgXCI8MC4zXCIpXG5oZXJvVGltZWxpbmUudG8oXCIuaGVyby1zdWJ0aXRsZSBwXCIsIHsgb3BhY2l0eTogMSwgIGVhc2U6IFwicG93ZXI0Lm91dFwiLCBkdXJhdGlvbjogM30sIFwic3RhcnRcIilcbmhlcm9UaW1lbGluZS5mcm9tVG8oXCIuaGVyby12LWxpbmVcIiwge2hlaWdodDogMH0seyBoZWlnaHQ6IGAke2hlcm9IZWlnaHQub2Zmc2V0SGVpZ2h0IC0gMzB9YCwgIGVhc2U6IFwicG93ZXI0Lm91dFwiLCBkdXJhdGlvbjogMn0sIFwic3RhcnRcIilcblxuXG5cbi8vIHRleHQgYW5pbVxuY29uc3QgdGV4dEFuaW0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnRleHQtYW5pbVwiKTtcbnRleHRBbmltLmZvckVhY2goKHF1b3RlLCBpKSA9PiB7XG4gICAgXG4gICAgICBxdW90ZS5zcGxpdCA9IG5ldyBTcGxpdFRleHQocXVvdGUsIHtcbiAgICAgIHR5cGU6XCJ3b3JkcyxjaGFyc1wiLFxuICAgICAgd29yZHNDbGFzczogXCJzcGxpdC1saW5lXCJcbiAgICB9KTtcbiAgICBnc2FwLnNldChxdW90ZSwge3BlcnNwZWN0aXZlOiA4MDB9KTtcbiAgICBsZXQgdGwgPSBnc2FwLnRpbWVsaW5lKHtcbiAgICAgIHNjcm9sbFRyaWdnZXIgOntcbiAgICAgICAgdHJpZ2dlcjogcXVvdGUsXG4gICAgICB9XG4gICAgfSlcbiAgICB0bC5mcm9tVG8ocXVvdGUuc3BsaXQud29yZHMsXG4gICAge2F1dG9BbHBoYTogMH0seyAgZHVyYXRpb246IDEsIGF1dG9BbHBoYTogMSxlYXNlOiBcImVhc2VcIixzdGFnZ2VyOiAwLjAzfSk7XG5cbiAgfSk7XG5cbiAgICAvLyAvLyBmYWRlIHVwIHRleHQtYW5pbWF0aW9uXG4gICAgY29uc3QgZmFkZVVwID0gZ3NhcC51dGlscy50b0FycmF5KFwiW2ZhZGVdXCIpO1xuICAgIGZhZGVVcC5mb3JFYWNoKChlbCwgaSkgPT4ge1xuICAgICAgY29uc3QgYW5pbSA9IGdzYXAuZnJvbVRvKGVsLCB7YXV0b0FscGhhOiAwLCB5OjB9LCB7ZHVyYXRpb246IDEuMiwgYXV0b0FscGhhOiAxLCBkZWxheTogMC4wNX0pO1xuICAgICAgU2Nyb2xsVHJpZ2dlci5jcmVhdGUoe1xuICAgICAgICB0cmlnZ2VyOiBlbCxcbiAgICAgICAgYW5pbWF0aW9uOiBhbmltLFxuICAgICAgICB0b2dnbGVBY3Rpb25zOiAncGxheSBub25lIG5vbmUgbm9uZScsXG4gICAgICAgIG9uY2U6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIGFuaW1hdGlvbiBjYXJkIGJhdGNoXG5cbiAgICBTY3JvbGxUcmlnZ2VyLmJhdGNoKCcucm93Jywge1xuICAgICAgb25FbnRlcjogYmF0Y2ggPT4ge1xuICAgICAgICBiYXRjaC5mb3JFYWNoKChjYXJkLCBpbmRleCkgPT4gZ3NhcC50byhjYXJkLCB7b3BhY2l0eTogMSwgZGVsYXk6IGluZGV4ICogMC4zLCAgZWFzZTogXCJwb3dlcjQub3V0XCIsIGR1cmF0aW9uOiAxfSkpXG4gICAgICB9LFxuICAgICAgb25jZTogdHJ1ZSxcbiAgICAgIHN0YXJ0OiBcIjMwcHggYm90dG9tXCIsXG4gICAgICBpbnRlcnZhbDogMC4xNSxcbiAgICB9KTtcblxuXG4gICAgLy8gcGFyYWxsYXhcbiAgICBjb25zdCBwYXJhbGxheCA9IGdzYXAudXRpbHMudG9BcnJheShcIi5pbWFnZV9zdmcgLnAtZGVza3RvcFwiKTtcbiAgICBjb25zb2xlLmxvZyhwYXJhbGxheClcblxuICAgIHBhcmFsbGF4LmZvckVhY2goKGl0ZW0pPT57XG4gICAgICBnc2FwLnRvKGl0ZW0sIHtcbiAgICAgICAgeVBlcmNlbnQ6IDMwLFxuICAgICAgICBlYXNlOiBcIm5vbmVcIixcbiAgICAgICAgc2Nyb2xsVHJpZ2dlcjoge1xuICAgICAgICAgIHRyaWdnZXI6IGl0ZW0sXG4gICAgICAgICAgc2NydWI6IHRydWVcbiAgICAgICAgfSwgXG4gICAgICB9KTtcbiAgICB9KVxuXG5cblxuXG5cbiJdLCJuYW1lcyI6WyJnc2FwIiwiU2Nyb2xsVG9QbHVnaW4iLCJTY3JvbGxUcmlnZ2VyIiwiU3BsaXRUZXh0IiwicmVnaXN0ZXJQbHVnaW4iLCJoIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwib2Zmc2V0SGVpZ2h0IiwiYXJyb3ciLCJhZGRFdmVudExpc3RlbmVyIiwidG8iLCJ3aW5kb3ciLCJkdXJhdGlvbiIsInNjcm9sbFRvIiwiZWFzZSIsImhlcm9UaW1lbGluZSIsInRpbWVsaW5lIiwiaGVyb1NwYW4iLCJ1dGlscyIsInRvQXJyYXkiLCJoZXJvSGVpZ2h0IiwiaGVpZ2h0IiwieSIsInN0YWdnZXIiLCJvcGFjaXR5IiwiZnJvbVRvIiwidGV4dEFuaW0iLCJxdWVyeVNlbGVjdG9yQWxsIiwiZm9yRWFjaCIsInF1b3RlIiwiaSIsInNwbGl0IiwidHlwZSIsIndvcmRzQ2xhc3MiLCJzZXQiLCJwZXJzcGVjdGl2ZSIsInRsIiwic2Nyb2xsVHJpZ2dlciIsInRyaWdnZXIiLCJ3b3JkcyIsImF1dG9BbHBoYSIsImZhZGVVcCIsImVsIiwiYW5pbSIsImRlbGF5IiwiY3JlYXRlIiwiYW5pbWF0aW9uIiwidG9nZ2xlQWN0aW9ucyIsIm9uY2UiLCJiYXRjaCIsIm9uRW50ZXIiLCJjYXJkIiwiaW5kZXgiLCJzdGFydCIsImludGVydmFsIiwicGFyYWxsYXgiLCJjb25zb2xlIiwibG9nIiwiaXRlbSIsInlQZXJjZW50Iiwic2NydWIiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/animations.js\n"); /***/ }), /***/ "./src/js/app.js": /*!***********************!*\ !*** ./src/js/app.js ***! \***********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _animations__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./animations */ \"./src/js/animations.js\");\n/* harmony import */ var _scss_app_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scss/app.scss */ \"./src/scss/app.scss\");\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYXBwLmpzLmpzIiwibWFwcGluZ3MiOiI7OztBQUNzQiIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vc3JjL2pzL2FwcC5qcz85MGU5Il0sInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0ICcuL2FuaW1hdGlvbnMnO1xuXG5pbXBvcnQgJy4uL3Njc3MvYXBwLnNjc3MnO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/app.js\n"); /***/ }), /***/ "./node_modules/gsap/CSSPlugin.js": /*!****************************************!*\ !*** ./node_modules/gsap/CSSPlugin.js ***! \****************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CSSPlugin\": () => (/* binding */ CSSPlugin),\n/* harmony export */ \"_createElement\": () => (/* binding */ _createElement),\n/* harmony export */ \"_getBBox\": () => (/* binding */ _getBBox),\n/* harmony export */ \"checkPrefix\": () => (/* binding */ _checkPropPrefix),\n/* harmony export */ \"default\": () => (/* binding */ CSSPlugin)\n/* harmony export */ });\n/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ \"./node_modules/gsap/gsap-core.js\");\n/*!\n * CSSPlugin 3.11.5\n * https://greensock.com\n *\n * Copyright 2008-2023, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n\n/* eslint-disable */\n\n\nvar _win,\n _doc,\n _docElement,\n _pluginInitted,\n _tempDiv,\n _tempDivStyler,\n _recentSetterPlugin,\n _reverting,\n _windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _transformProps = {},\n _RAD2DEG = 180 / Math.PI,\n _DEG2RAD = Math.PI / 180,\n _atan2 = Math.atan2,\n _bigNum = 1e8,\n _capsExp = /([A-Z])/g,\n _horizontalExp = /(left|right|width|margin|padding|x)/i,\n _complexExp = /[\\s,\\(]\\S/,\n _propertyAliases = {\n autoAlpha: \"opacity,visibility\",\n scale: \"scaleX,scaleY\",\n alpha: \"opacity\"\n},\n _renderCSSProp = function _renderCSSProp(ratio, data) {\n return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {\n return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {\n return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);\n},\n //if units change, we need a way to render the original unit/value when the tween goes all the way back to the beginning (ratio:0)\n_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {\n var value = data.s + data.c * ratio;\n data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);\n},\n _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {\n return data.set(data.t, data.p, ratio ? data.e : data.b, data);\n},\n _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {\n return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);\n},\n _setterCSSStyle = function _setterCSSStyle(target, property, value) {\n return target.style[property] = value;\n},\n _setterCSSProp = function _setterCSSProp(target, property, value) {\n return target.style.setProperty(property, value);\n},\n _setterTransform = function _setterTransform(target, property, value) {\n return target._gsap[property] = value;\n},\n _setterScale = function _setterScale(target, property, value) {\n return target._gsap.scaleX = target._gsap.scaleY = value;\n},\n _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {\n var cache = target._gsap;\n cache.scaleX = cache.scaleY = value;\n cache.renderTransform(ratio, cache);\n},\n _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {\n var cache = target._gsap;\n cache[property] = value;\n cache.renderTransform(ratio, cache);\n},\n _transformProp = \"transform\",\n _transformOriginProp = _transformProp + \"Origin\",\n _saveStyle = function _saveStyle(property, isNotCSS) {\n var _this = this;\n\n var target = this.target,\n style = target.style;\n\n if (property in _transformProps) {\n this.tfm = this.tfm || {};\n\n if (property !== \"transform\") {\n property = _propertyAliases[property] || property;\n ~property.indexOf(\",\") ? property.split(\",\").forEach(function (a) {\n return _this.tfm[a] = _get(target, a);\n }) : this.tfm[property] = target._gsap.x ? target._gsap[property] : _get(target, property); // note: scale would map to \"scaleX,scaleY\", thus we loop and apply them both.\n } else {\n return _propertyAliases.transform.split(\",\").forEach(function (p) {\n return _saveStyle.call(_this, p, isNotCSS);\n });\n }\n\n if (this.props.indexOf(_transformProp) >= 0) {\n return;\n }\n\n if (target._gsap.svg) {\n this.svgo = target.getAttribute(\"data-svg-origin\");\n this.props.push(_transformOriginProp, isNotCSS, \"\");\n }\n\n property = _transformProp;\n }\n\n (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]);\n},\n _removeIndependentTransforms = function _removeIndependentTransforms(style) {\n if (style.translate) {\n style.removeProperty(\"translate\");\n style.removeProperty(\"scale\");\n style.removeProperty(\"rotate\");\n }\n},\n _revertStyle = function _revertStyle() {\n var props = this.props,\n target = this.target,\n style = target.style,\n cache = target._gsap,\n i,\n p;\n\n for (i = 0; i < props.length; i += 3) {\n // stored like this: property, isNotCSS, value\n props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === \"--\" ? props[i] : props[i].replace(_capsExp, \"-$1\").toLowerCase());\n }\n\n if (this.tfm) {\n for (p in this.tfm) {\n cache[p] = this.tfm[p];\n }\n\n if (cache.svg) {\n cache.renderTransform();\n target.setAttribute(\"data-svg-origin\", this.svgo || \"\");\n }\n\n i = _reverting();\n\n if ((!i || !i.isStart) && !style[_transformProp]) {\n _removeIndependentTransforms(style);\n\n cache.uncache = 1; // if it's a startAt that's being reverted in the _initTween() of the core, we don't need to uncache transforms. This is purely a performance optimization.\n }\n }\n},\n _getStyleSaver = function _getStyleSaver(target, properties) {\n var saver = {\n target: target,\n props: [],\n revert: _revertStyle,\n save: _saveStyle\n };\n target._gsap || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.getCache(target); // just make sure there's a _gsap cache defined because we read from it in _saveStyle() and it's more efficient to just check it here once.\n\n properties && properties.split(\",\").forEach(function (p) {\n return saver.save(p);\n });\n return saver;\n},\n _supports3D,\n _createElement = function _createElement(type, ns) {\n var e = _doc.createElementNS ? _doc.createElementNS((ns || \"http://www.w3.org/1999/xhtml\").replace(/^https/, \"http\"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making \"style\" inaccessible.\n\n return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/).\n},\n _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {\n var cs = getComputedStyle(target);\n return cs[property] || cs.getPropertyValue(property.replace(_capsExp, \"-$1\").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || \"\"; //css variables may not need caps swapped out for dashes and lowercase.\n},\n _prefixes = \"O,Moz,ms,Ms,Webkit\".split(\",\"),\n _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {\n var e = element || _tempDiv,\n s = e.style,\n i = 5;\n\n if (property in s && !preferPrefix) {\n return property;\n }\n\n property = property.charAt(0).toUpperCase() + property.substr(1);\n\n while (i-- && !(_prefixes[i] + property in s)) {}\n\n return i < 0 ? null : (i === 3 ? \"ms\" : i >= 0 ? _prefixes[i] : \"\") + property;\n},\n _initCore = function _initCore() {\n if (_windowExists() && window.document) {\n _win = window;\n _doc = _win.document;\n _docElement = _doc.documentElement;\n _tempDiv = _createElement(\"div\") || {\n style: {}\n };\n _tempDivStyler = _createElement(\"div\");\n _transformProp = _checkPropPrefix(_transformProp);\n _transformOriginProp = _transformProp + \"Origin\";\n _tempDiv.style.cssText = \"border-width:0;line-height:0;position:absolute;padding:0\"; //make sure to override certain properties that may contaminate measurements, in case the user has overreaching style sheets.\n\n _supports3D = !!_checkPropPrefix(\"perspective\");\n _reverting = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.reverting;\n _pluginInitted = 1;\n }\n},\n _getBBoxHack = function _getBBoxHack(swapIfPossible) {\n //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a element and/or . We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it).\n var svg = _createElement(\"svg\", this.ownerSVGElement && this.ownerSVGElement.getAttribute(\"xmlns\") || \"http://www.w3.org/2000/svg\"),\n oldParent = this.parentNode,\n oldSibling = this.nextSibling,\n oldCSS = this.style.cssText,\n bbox;\n\n _docElement.appendChild(svg);\n\n svg.appendChild(this);\n this.style.display = \"block\";\n\n if (swapIfPossible) {\n try {\n bbox = this.getBBox();\n this._gsapBBox = this.getBBox; //store the original\n\n this.getBBox = _getBBoxHack;\n } catch (e) {}\n } else if (this._gsapBBox) {\n bbox = this._gsapBBox();\n }\n\n if (oldParent) {\n if (oldSibling) {\n oldParent.insertBefore(this, oldSibling);\n } else {\n oldParent.appendChild(this);\n }\n }\n\n _docElement.removeChild(svg);\n\n this.style.cssText = oldCSS;\n return bbox;\n},\n _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {\n var i = attributesArray.length;\n\n while (i--) {\n if (target.hasAttribute(attributesArray[i])) {\n return target.getAttribute(attributesArray[i]);\n }\n }\n},\n _getBBox = function _getBBox(target) {\n var bounds;\n\n try {\n bounds = target.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a or ). https://bugzilla.mozilla.org/show_bug.cgi?id=612118\n } catch (error) {\n bounds = _getBBoxHack.call(target, true);\n }\n\n bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case.\n\n return bounds && !bounds.width && !bounds.x && !bounds.y ? {\n x: +_getAttributeFallbacks(target, [\"x\", \"cx\", \"x1\"]) || 0,\n y: +_getAttributeFallbacks(target, [\"y\", \"cy\", \"y1\"]) || 0,\n width: 0,\n height: 0\n } : bounds;\n},\n _isSVG = function _isSVG(e) {\n return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));\n},\n //reports if the element is an SVG on which getBBox() actually works\n_removeProperty = function _removeProperty(target, property) {\n if (property) {\n var style = target.style;\n\n if (property in _transformProps && property !== _transformOriginProp) {\n property = _transformProp;\n }\n\n if (style.removeProperty) {\n if (property.substr(0, 2) === \"ms\" || property.substr(0, 6) === \"webkit\") {\n //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be \"ms-transform\" instead of \"-ms-transform\" for IE9, for example)\n property = \"-\" + property;\n }\n\n style.removeProperty(property.replace(_capsExp, \"-$1\").toLowerCase());\n } else {\n //note: old versions of IE use \"removeAttribute()\" instead of \"removeProperty()\"\n style.removeAttribute(property);\n }\n }\n},\n _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {\n var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);\n plugin._pt = pt;\n pt.b = beginning;\n pt.e = end;\n\n plugin._props.push(property);\n\n return pt;\n},\n _nonConvertibleUnits = {\n deg: 1,\n rad: 1,\n turn: 1\n},\n _nonStandardLayouts = {\n grid: 1,\n flex: 1\n},\n //takes a single value like 20px and converts it to the unit specified, like \"%\", returning only the numeric amount.\n_convertToUnit = function _convertToUnit(target, property, value, unit) {\n var curValue = parseFloat(value) || 0,\n curUnit = (value + \"\").trim().substr((curValue + \"\").length) || \"px\",\n // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim()\n style = _tempDiv.style,\n horizontal = _horizontalExp.test(property),\n isRootSVG = target.tagName.toLowerCase() === \"svg\",\n measureProperty = (isRootSVG ? \"client\" : \"offset\") + (horizontal ? \"Width\" : \"Height\"),\n amount = 100,\n toPixels = unit === \"px\",\n toPercent = unit === \"%\",\n px,\n parent,\n cache,\n isSVG;\n\n if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {\n return curValue;\n }\n\n curUnit !== \"px\" && !toPixels && (curValue = _convertToUnit(target, property, value, \"px\"));\n isSVG = target.getCTM && _isSVG(target);\n\n if ((toPercent || curUnit === \"%\") && (_transformProps[property] || ~property.indexOf(\"adius\"))) {\n px = isSVG ? target.getBBox()[horizontal ? \"width\" : \"height\"] : target[measureProperty];\n return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPercent ? curValue / px * amount : curValue / 100 * px);\n }\n\n style[horizontal ? \"width\" : \"height\"] = amount + (toPixels ? curUnit : unit);\n parent = ~property.indexOf(\"adius\") || unit === \"em\" && target.appendChild && !isRootSVG ? target : target.parentNode;\n\n if (isSVG) {\n parent = (target.ownerSVGElement || {}).parentNode;\n }\n\n if (!parent || parent === _doc || !parent.appendChild) {\n parent = _doc.body;\n }\n\n cache = parent._gsap;\n\n if (cache && toPercent && cache.width && horizontal && cache.time === _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time && !cache.uncache) {\n return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(curValue / cache.width * amount);\n } else {\n (toPercent || curUnit === \"%\") && !_nonStandardLayouts[_getComputedProperty(parent, \"display\")] && (style.position = _getComputedProperty(target, \"position\"));\n parent === target && (style.position = \"static\"); // like for borderRadius, if it's a % we must have it relative to the target itself but that may not have position: relative or position: absolute in which case it'd go up the chain until it finds its offsetParent (bad). position: static protects against that.\n\n parent.appendChild(_tempDiv);\n px = _tempDiv[measureProperty];\n parent.removeChild(_tempDiv);\n style.position = \"absolute\";\n\n if (horizontal && toPercent) {\n cache = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(parent);\n cache.time = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time;\n cache.width = parent[measureProperty];\n }\n }\n\n return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);\n},\n _get = function _get(target, property, unit, uncache) {\n var value;\n _pluginInitted || _initCore();\n\n if (property in _propertyAliases && property !== \"transform\") {\n property = _propertyAliases[property];\n\n if (~property.indexOf(\",\")) {\n property = property.split(\",\")[0];\n }\n }\n\n if (_transformProps[property] && property !== \"transform\") {\n value = _parseTransform(target, uncache);\n value = property !== \"transformOrigin\" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + \" \" + value.zOrigin + \"px\";\n } else {\n value = target.style[property];\n\n if (!value || value === \"auto\" || uncache || ~(value + \"\").indexOf(\"calc(\")) {\n value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getProperty)(target, property) || (property === \"opacity\" ? 1 : 0); // note: some browsers, like Firefox, don't report borderRadius correctly! Instead, it only reports every corner like borderTopLeftRadius\n }\n }\n\n return unit && !~(value + \"\").trim().indexOf(\" \") ? _convertToUnit(target, property, value, unit) + unit : value;\n},\n _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {\n // note: we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n if (!start || start === \"none\") {\n // some browsers like Safari actually PREFER the prefixed property and mis-report the unprefixed value like clipPath (BUG). In other words, even though clipPath exists in the style (\"clipPath\" in target.style) and it's set in the CSS properly (along with -webkit-clip-path), Safari reports clipPath as \"none\" whereas WebkitClipPath reports accurately like \"ellipse(100% 0% at 50% 0%)\", so in this case we must SWITCH to using the prefixed property instead. See https://greensock.com/forums/topic/18310-clippath-doesnt-work-on-ios/\n var p = _checkPropPrefix(prop, target, 1),\n s = p && _getComputedProperty(target, p, 1);\n\n if (s && s !== start) {\n prop = p;\n start = s;\n } else if (prop === \"borderColor\") {\n start = _getComputedProperty(target, \"borderTopColor\"); // Firefox bug: always reports \"borderColor\" as \"\", so we must fall back to borderTopColor. See https://greensock.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/\n }\n }\n\n var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, target.style, prop, 0, 1, _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._renderComplexString),\n index = 0,\n matchIndex = 0,\n a,\n result,\n startValues,\n startNum,\n color,\n startValue,\n endValue,\n endNum,\n chunk,\n endUnit,\n startUnit,\n endValues;\n pt.b = start;\n pt.e = end;\n start += \"\"; // ensure values are strings\n\n end += \"\";\n\n if (end === \"auto\") {\n target.style[prop] = end;\n end = _getComputedProperty(target, prop) || end;\n target.style[prop] = start;\n }\n\n a = [start, end];\n\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorStringFilter)(a); // pass an array with the starting and ending values and let the filter do whatever it needs to the values. If colors are found, it returns true and then we must match where the color shows up order-wise because for things like boxShadow, sometimes the browser provides the computed values with the color FIRST, but the user provides it with the color LAST, so flip them if necessary. Same for drop-shadow().\n\n\n start = a[0];\n end = a[1];\n startValues = start.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || [];\n endValues = end.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || [];\n\n if (endValues.length) {\n while (result = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.exec(end)) {\n endValue = result[0];\n chunk = end.substring(index, result.index);\n\n if (color) {\n color = (color + 1) % 5;\n } else if (chunk.substr(-5) === \"rgba(\" || chunk.substr(-5) === \"hsla(\") {\n color = 1;\n }\n\n if (endValue !== (startValue = startValues[matchIndex++] || \"\")) {\n startNum = parseFloat(startValue) || 0;\n startUnit = startValue.substr((startNum + \"\").length);\n endValue.charAt(1) === \"=\" && (endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, endValue) + startUnit);\n endNum = parseFloat(endValue);\n endUnit = endValue.substr((endNum + \"\").length);\n index = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.lastIndex - endUnit.length;\n\n if (!endUnit) {\n //if something like \"perspective:300\" is passed in and we must add a unit to the end\n endUnit = endUnit || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[prop] || startUnit;\n\n if (index === end.length) {\n end += endUnit;\n pt.e += endUnit;\n }\n }\n\n if (startUnit !== endUnit) {\n startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;\n } // these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method.\n\n\n pt._pt = {\n _next: pt._pt,\n p: chunk || matchIndex === 1 ? chunk : \",\",\n //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.\n s: startNum,\n c: endNum - startNum,\n m: color && color < 4 || prop === \"zIndex\" ? Math.round : 0\n };\n }\n }\n\n pt.c = index < end.length ? end.substring(index, end.length) : \"\"; //we use the \"c\" of the PropTween to store the final part of the string (after the last number)\n } else {\n pt.r = prop === \"display\" && end === \"none\" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;\n }\n\n _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._relExp.test(end) && (pt.e = 0); //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value).\n\n this._pt = pt; //start the linked list with this new PropTween. Remember, we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within another plugin too, thus \"this\" would refer to the plugin.\n\n return pt;\n},\n _keywordToPercent = {\n top: \"0%\",\n bottom: \"100%\",\n left: \"0%\",\n right: \"100%\",\n center: \"50%\"\n},\n _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {\n var split = value.split(\" \"),\n x = split[0],\n y = split[1] || \"50%\";\n\n if (x === \"top\" || x === \"bottom\" || y === \"left\" || y === \"right\") {\n //the user provided them in the wrong order, so flip them\n value = x;\n x = y;\n y = value;\n }\n\n split[0] = _keywordToPercent[x] || x;\n split[1] = _keywordToPercent[y] || y;\n return split.join(\" \");\n},\n _renderClearProps = function _renderClearProps(ratio, data) {\n if (data.tween && data.tween._time === data.tween._dur) {\n var target = data.t,\n style = target.style,\n props = data.u,\n cache = target._gsap,\n prop,\n clearTransforms,\n i;\n\n if (props === \"all\" || props === true) {\n style.cssText = \"\";\n clearTransforms = 1;\n } else {\n props = props.split(\",\");\n i = props.length;\n\n while (--i > -1) {\n prop = props[i];\n\n if (_transformProps[prop]) {\n clearTransforms = 1;\n prop = prop === \"transformOrigin\" ? _transformOriginProp : _transformProp;\n }\n\n _removeProperty(target, prop);\n }\n }\n\n if (clearTransforms) {\n _removeProperty(target, _transformProp);\n\n if (cache) {\n cache.svg && target.removeAttribute(\"transform\");\n\n _parseTransform(target, 1); // force all the cached values back to \"normal\"/identity, otherwise if there's another tween that's already set to render transforms on this element, it could display the wrong values.\n\n\n cache.uncache = 1;\n\n _removeIndependentTransforms(style);\n }\n }\n }\n},\n // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list.\n_specialProps = {\n clearProps: function clearProps(plugin, target, property, endValue, tween) {\n if (tween.data !== \"isFromStart\") {\n var pt = plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);\n pt.u = endValue;\n pt.pr = -10;\n pt.tween = tween;\n\n plugin._props.push(property);\n\n return 1;\n }\n }\n /* className feature (about 0.4kb gzipped).\n , className(plugin, target, property, endValue, tween) {\n \tlet _renderClassName = (ratio, data) => {\n \t\t\tdata.css.render(ratio, data.css);\n \t\t\tif (!ratio || ratio === 1) {\n \t\t\t\tlet inline = data.rmv,\n \t\t\t\t\ttarget = data.t,\n \t\t\t\t\tp;\n \t\t\t\ttarget.setAttribute(\"class\", ratio ? data.e : data.b);\n \t\t\t\tfor (p in inline) {\n \t\t\t\t\t_removeProperty(target, p);\n \t\t\t\t}\n \t\t\t}\n \t\t},\n \t\t_getAllStyles = (target) => {\n \t\t\tlet styles = {},\n \t\t\t\tcomputed = getComputedStyle(target),\n \t\t\t\tp;\n \t\t\tfor (p in computed) {\n \t\t\t\tif (isNaN(p) && p !== \"cssText\" && p !== \"length\") {\n \t\t\t\t\tstyles[p] = computed[p];\n \t\t\t\t}\n \t\t\t}\n \t\t\t_setDefaults(styles, _parseTransform(target, 1));\n \t\t\treturn styles;\n \t\t},\n \t\tstartClassList = target.getAttribute(\"class\"),\n \t\tstyle = target.style,\n \t\tcssText = style.cssText,\n \t\tcache = target._gsap,\n \t\tclassPT = cache.classPT,\n \t\tinlineToRemoveAtEnd = {},\n \t\tdata = {t:target, plugin:plugin, rmv:inlineToRemoveAtEnd, b:startClassList, e:(endValue.charAt(1) !== \"=\") ? endValue : startClassList.replace(new RegExp(\"(?:\\\\s|^)\" + endValue.substr(2) + \"(?![\\\\w-])\"), \"\") + ((endValue.charAt(0) === \"+\") ? \" \" + endValue.substr(2) : \"\")},\n \t\tchangingVars = {},\n \t\tstartVars = _getAllStyles(target),\n \t\ttransformRelated = /(transform|perspective)/i,\n \t\tendVars, p;\n \tif (classPT) {\n \t\tclassPT.r(1, classPT.d);\n \t\t_removeLinkedListItem(classPT.d.plugin, classPT, \"_pt\");\n \t}\n \ttarget.setAttribute(\"class\", data.e);\n \tendVars = _getAllStyles(target, true);\n \ttarget.setAttribute(\"class\", startClassList);\n \tfor (p in endVars) {\n \t\tif (endVars[p] !== startVars[p] && !transformRelated.test(p)) {\n \t\t\tchangingVars[p] = endVars[p];\n \t\t\tif (!style[p] && style[p] !== \"0\") {\n \t\t\t\tinlineToRemoveAtEnd[p] = 1;\n \t\t\t}\n \t\t}\n \t}\n \tcache.classPT = plugin._pt = new PropTween(plugin._pt, target, \"className\", 0, 0, _renderClassName, data, 0, -11);\n \tif (style.cssText !== cssText) { //only apply if things change. Otherwise, in cases like a background-image that's pulled dynamically, it could cause a refresh. See https://greensock.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/.\n \t\tstyle.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity).\n \t}\n \t_parseTransform(target, true); //to clear the caching of transforms\n \tdata.css = new gsap.plugins.css();\n \tdata.css.init(target, changingVars, tween);\n \tplugin._props.push(...data.css._props);\n \treturn 1;\n }\n */\n\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TRANSFORMS\n * --------------------------------------------------------------------------------------\n */\n_identity2DMatrix = [1, 0, 0, 1, 0, 0],\n _rotationalProperties = {},\n _isNullTransform = function _isNullTransform(value) {\n return value === \"matrix(1, 0, 0, 1, 0, 0)\" || value === \"none\" || !value;\n},\n _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {\n var matrixString = _getComputedProperty(target, _transformProp);\n\n return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numExp).map(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round);\n},\n _getMatrix = function _getMatrix(target, force2D) {\n var cache = target._gsap || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(target),\n style = target.style,\n matrix = _getComputedTransformMatrixAsArray(target),\n parent,\n nextSibling,\n temp,\n addedToDOM;\n\n if (cache.svg && target.getAttribute(\"transform\")) {\n temp = target.transform.baseVal.consolidate().matrix; //ensures that even complex values like \"translate(50,60) rotate(135,0,0)\" are parsed because it mashes it into a matrix.\n\n matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];\n return matrix.join(\",\") === \"1,0,0,1,0,0\" ? _identity2DMatrix : matrix;\n } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {\n //note: if offsetParent is null, that means the element isn't in the normal document flow, like if it has display:none or one of its ancestors has display:none). Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not \"none\". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px).\n temp = style.display;\n style.display = \"block\";\n parent = target.parentNode;\n\n if (!parent || !target.offsetParent) {\n // note: in 3.3.0 we switched target.offsetParent to _doc.body.contains(target) to avoid [sometimes unnecessary] MutationObserver calls but that wasn't adequate because there are edge cases where nested position: fixed elements need to get reparented to accurately sense transforms. See https://github.com/greensock/GSAP/issues/388 and https://github.com/greensock/GSAP/issues/375\n addedToDOM = 1; //flag\n\n nextSibling = target.nextElementSibling;\n\n _docElement.appendChild(target); //we must add it to the DOM in order to get values properly\n\n }\n\n matrix = _getComputedTransformMatrixAsArray(target);\n temp ? style.display = temp : _removeProperty(target, \"display\");\n\n if (addedToDOM) {\n nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);\n }\n }\n\n return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;\n},\n _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {\n var cache = target._gsap,\n matrix = matrixArray || _getMatrix(target, true),\n xOriginOld = cache.xOrigin || 0,\n yOriginOld = cache.yOrigin || 0,\n xOffsetOld = cache.xOffset || 0,\n yOffsetOld = cache.yOffset || 0,\n a = matrix[0],\n b = matrix[1],\n c = matrix[2],\n d = matrix[3],\n tx = matrix[4],\n ty = matrix[5],\n originSplit = origin.split(\" \"),\n xOrigin = parseFloat(originSplit[0]) || 0,\n yOrigin = parseFloat(originSplit[1]) || 0,\n bounds,\n determinant,\n x,\n y;\n\n if (!originIsAbsolute) {\n bounds = _getBBox(target);\n xOrigin = bounds.x + (~originSplit[0].indexOf(\"%\") ? xOrigin / 100 * bounds.width : xOrigin);\n yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf(\"%\") ? yOrigin / 100 * bounds.height : yOrigin);\n } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {\n //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.\n x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;\n y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;\n xOrigin = x;\n yOrigin = y;\n }\n\n if (smooth || smooth !== false && cache.smooth) {\n tx = xOrigin - xOriginOld;\n ty = yOrigin - yOriginOld;\n cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;\n cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;\n } else {\n cache.xOffset = cache.yOffset = 0;\n }\n\n cache.xOrigin = xOrigin;\n cache.yOrigin = yOrigin;\n cache.smooth = !!smooth;\n cache.origin = origin;\n cache.originIsAbsolute = !!originIsAbsolute;\n target.style[_transformOriginProp] = \"0px 0px\"; //otherwise, if someone sets an origin via CSS, it will likely interfere with the SVG transform attribute ones (because remember, we're baking the origin into the matrix() value).\n\n if (pluginToAddPropTweensTo) {\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"xOrigin\", xOriginOld, xOrigin);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"yOrigin\", yOriginOld, yOrigin);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"xOffset\", xOffsetOld, cache.xOffset);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"yOffset\", yOffsetOld, cache.yOffset);\n }\n\n target.setAttribute(\"data-svg-origin\", xOrigin + \" \" + yOrigin);\n},\n _parseTransform = function _parseTransform(target, uncache) {\n var cache = target._gsap || new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.GSCache(target);\n\n if (\"x\" in cache && !uncache && !cache.uncache) {\n return cache;\n }\n\n var style = target.style,\n invertedScaleX = cache.scaleX < 0,\n px = \"px\",\n deg = \"deg\",\n cs = getComputedStyle(target),\n origin = _getComputedProperty(target, _transformOriginProp) || \"0\",\n x,\n y,\n z,\n scaleX,\n scaleY,\n rotation,\n rotationX,\n rotationY,\n skewX,\n skewY,\n perspective,\n xOrigin,\n yOrigin,\n matrix,\n angle,\n cos,\n sin,\n a,\n b,\n c,\n d,\n a12,\n a22,\n t1,\n t2,\n t3,\n a13,\n a23,\n a33,\n a42,\n a43,\n a32;\n x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;\n scaleX = scaleY = 1;\n cache.svg = !!(target.getCTM && _isSVG(target));\n\n if (cs.translate) {\n // accommodate independent transforms by combining them into normal ones.\n if (cs.translate !== \"none\" || cs.scale !== \"none\" || cs.rotate !== \"none\") {\n style[_transformProp] = (cs.translate !== \"none\" ? \"translate3d(\" + (cs.translate + \" 0 0\").split(\" \").slice(0, 3).join(\", \") + \") \" : \"\") + (cs.rotate !== \"none\" ? \"rotate(\" + cs.rotate + \") \" : \"\") + (cs.scale !== \"none\" ? \"scale(\" + cs.scale.split(\" \").join(\",\") + \") \" : \"\") + (cs[_transformProp] !== \"none\" ? cs[_transformProp] : \"\");\n }\n\n style.scale = style.rotate = style.translate = \"none\";\n }\n\n matrix = _getMatrix(target, cache.svg);\n\n if (cache.svg) {\n if (cache.uncache) {\n // if cache.uncache is true (and maybe if origin is 0,0), we need to set element.style.transformOrigin = (cache.xOrigin - bbox.x) + \"px \" + (cache.yOrigin - bbox.y) + \"px\". Previously we let the data-svg-origin stay instead, but when introducing revert(), it complicated things.\n t2 = target.getBBox();\n origin = cache.xOrigin - t2.x + \"px \" + (cache.yOrigin - t2.y) + \"px\";\n t1 = \"\";\n } else {\n t1 = !uncache && target.getAttribute(\"data-svg-origin\"); // Remember, to work around browser inconsistencies we always force SVG elements' transformOrigin to 0,0 and offset the translation accordingly.\n }\n\n _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix);\n }\n\n xOrigin = cache.xOrigin || 0;\n yOrigin = cache.yOrigin || 0;\n\n if (matrix !== _identity2DMatrix) {\n a = matrix[0]; //a11\n\n b = matrix[1]; //a21\n\n c = matrix[2]; //a31\n\n d = matrix[3]; //a41\n\n x = a12 = matrix[4];\n y = a22 = matrix[5]; //2D matrix\n\n if (matrix.length === 6) {\n scaleX = Math.sqrt(a * a + b * b);\n scaleY = Math.sqrt(d * d + c * c);\n rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).\n\n skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;\n skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));\n\n if (cache.svg) {\n x -= xOrigin - (xOrigin * a + yOrigin * c);\n y -= yOrigin - (xOrigin * b + yOrigin * d);\n } //3D matrix\n\n } else {\n a32 = matrix[6];\n a42 = matrix[7];\n a13 = matrix[8];\n a23 = matrix[9];\n a33 = matrix[10];\n a43 = matrix[11];\n x = matrix[12];\n y = matrix[13];\n z = matrix[14];\n angle = _atan2(a32, a33);\n rotationX = angle * _RAD2DEG; //rotationX\n\n if (angle) {\n cos = Math.cos(-angle);\n sin = Math.sin(-angle);\n t1 = a12 * cos + a13 * sin;\n t2 = a22 * cos + a23 * sin;\n t3 = a32 * cos + a33 * sin;\n a13 = a12 * -sin + a13 * cos;\n a23 = a22 * -sin + a23 * cos;\n a33 = a32 * -sin + a33 * cos;\n a43 = a42 * -sin + a43 * cos;\n a12 = t1;\n a22 = t2;\n a32 = t3;\n } //rotationY\n\n\n angle = _atan2(-c, a33);\n rotationY = angle * _RAD2DEG;\n\n if (angle) {\n cos = Math.cos(-angle);\n sin = Math.sin(-angle);\n t1 = a * cos - a13 * sin;\n t2 = b * cos - a23 * sin;\n t3 = c * cos - a33 * sin;\n a43 = d * sin + a43 * cos;\n a = t1;\n b = t2;\n c = t3;\n } //rotationZ\n\n\n angle = _atan2(b, a);\n rotation = angle * _RAD2DEG;\n\n if (angle) {\n cos = Math.cos(angle);\n sin = Math.sin(angle);\n t1 = a * cos + b * sin;\n t2 = a12 * cos + a22 * sin;\n b = b * cos - a * sin;\n a22 = a22 * cos - a12 * sin;\n a = t1;\n a12 = t2;\n }\n\n if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {\n //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here.\n rotationX = rotation = 0;\n rotationY = 180 - rotationY;\n }\n\n scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a * a + b * b + c * c));\n scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a22 * a22 + a32 * a32));\n angle = _atan2(a12, a22);\n skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;\n perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;\n }\n\n if (cache.svg) {\n //sense if there are CSS transforms applied on an SVG element in which case we must overwrite them when rendering. The transform attribute is more reliable cross-browser, but we can't just remove the CSS ones because they may be applied in a CSS rule somewhere (not just inline).\n t1 = target.getAttribute(\"transform\");\n cache.forceCSS = target.setAttribute(\"transform\", \"\") || !_isNullTransform(_getComputedProperty(target, _transformProp));\n t1 && target.setAttribute(\"transform\", t1);\n }\n }\n\n if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {\n if (invertedScaleX) {\n scaleX *= -1;\n skewX += rotation <= 0 ? 180 : -180;\n rotation += rotation <= 0 ? 180 : -180;\n } else {\n scaleY *= -1;\n skewX += skewX <= 0 ? 180 : -180;\n }\n }\n\n uncache = uncache || cache.uncache;\n cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px;\n cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px;\n cache.z = z + px;\n cache.scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleX);\n cache.scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleY);\n cache.rotation = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotation) + deg;\n cache.rotationX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationX) + deg;\n cache.rotationY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationY) + deg;\n cache.skewX = skewX + deg;\n cache.skewY = skewY + deg;\n cache.transformPerspective = perspective + px;\n\n if (cache.zOrigin = parseFloat(origin.split(\" \")[2]) || 0) {\n style[_transformOriginProp] = _firstTwoOnly(origin);\n }\n\n cache.xOffset = cache.yOffset = 0;\n cache.force3D = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.force3D;\n cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;\n cache.uncache = 0;\n return cache;\n},\n _firstTwoOnly = function _firstTwoOnly(value) {\n return (value = value.split(\" \"))[0] + \" \" + value[1];\n},\n //for handling transformOrigin values, stripping out the 3rd dimension\n_addPxTranslate = function _addPxTranslate(target, start, value) {\n var unit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(start);\n return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(parseFloat(start) + parseFloat(_convertToUnit(target, \"x\", value + \"px\", unit))) + unit;\n},\n _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {\n cache.z = \"0px\";\n cache.rotationY = cache.rotationX = \"0deg\";\n cache.force3D = 0;\n\n _renderCSSTransforms(ratio, cache);\n},\n _zeroDeg = \"0deg\",\n _zeroPx = \"0px\",\n _endParenthesis = \") \",\n _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {\n var _ref = cache || this,\n xPercent = _ref.xPercent,\n yPercent = _ref.yPercent,\n x = _ref.x,\n y = _ref.y,\n z = _ref.z,\n rotation = _ref.rotation,\n rotationY = _ref.rotationY,\n rotationX = _ref.rotationX,\n skewX = _ref.skewX,\n skewY = _ref.skewY,\n scaleX = _ref.scaleX,\n scaleY = _ref.scaleY,\n transformPerspective = _ref.transformPerspective,\n force3D = _ref.force3D,\n target = _ref.target,\n zOrigin = _ref.zOrigin,\n transforms = \"\",\n use3D = force3D === \"auto\" && ratio && ratio !== 1 || force3D === true; // Safari has a bug that causes it not to render 3D transform-origin values properly, so we force the z origin to 0, record it in the cache, and then do the math here to offset the translate values accordingly (basically do the 3D transform-origin part manually)\n\n\n if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {\n var angle = parseFloat(rotationY) * _DEG2RAD,\n a13 = Math.sin(angle),\n a33 = Math.cos(angle),\n cos;\n\n angle = parseFloat(rotationX) * _DEG2RAD;\n cos = Math.cos(angle);\n x = _addPxTranslate(target, x, a13 * cos * -zOrigin);\n y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);\n z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);\n }\n\n if (transformPerspective !== _zeroPx) {\n transforms += \"perspective(\" + transformPerspective + _endParenthesis;\n }\n\n if (xPercent || yPercent) {\n transforms += \"translate(\" + xPercent + \"%, \" + yPercent + \"%) \";\n }\n\n if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {\n transforms += z !== _zeroPx || use3D ? \"translate3d(\" + x + \", \" + y + \", \" + z + \") \" : \"translate(\" + x + \", \" + y + _endParenthesis;\n }\n\n if (rotation !== _zeroDeg) {\n transforms += \"rotate(\" + rotation + _endParenthesis;\n }\n\n if (rotationY !== _zeroDeg) {\n transforms += \"rotateY(\" + rotationY + _endParenthesis;\n }\n\n if (rotationX !== _zeroDeg) {\n transforms += \"rotateX(\" + rotationX + _endParenthesis;\n }\n\n if (skewX !== _zeroDeg || skewY !== _zeroDeg) {\n transforms += \"skew(\" + skewX + \", \" + skewY + _endParenthesis;\n }\n\n if (scaleX !== 1 || scaleY !== 1) {\n transforms += \"scale(\" + scaleX + \", \" + scaleY + _endParenthesis;\n }\n\n target.style[_transformProp] = transforms || \"translate(0, 0)\";\n},\n _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {\n var _ref2 = cache || this,\n xPercent = _ref2.xPercent,\n yPercent = _ref2.yPercent,\n x = _ref2.x,\n y = _ref2.y,\n rotation = _ref2.rotation,\n skewX = _ref2.skewX,\n skewY = _ref2.skewY,\n scaleX = _ref2.scaleX,\n scaleY = _ref2.scaleY,\n target = _ref2.target,\n xOrigin = _ref2.xOrigin,\n yOrigin = _ref2.yOrigin,\n xOffset = _ref2.xOffset,\n yOffset = _ref2.yOffset,\n forceCSS = _ref2.forceCSS,\n tx = parseFloat(x),\n ty = parseFloat(y),\n a11,\n a21,\n a12,\n a22,\n temp;\n\n rotation = parseFloat(rotation);\n skewX = parseFloat(skewX);\n skewY = parseFloat(skewY);\n\n if (skewY) {\n //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees.\n skewY = parseFloat(skewY);\n skewX += skewY;\n rotation += skewY;\n }\n\n if (rotation || skewX) {\n rotation *= _DEG2RAD;\n skewX *= _DEG2RAD;\n a11 = Math.cos(rotation) * scaleX;\n a21 = Math.sin(rotation) * scaleX;\n a12 = Math.sin(rotation - skewX) * -scaleY;\n a22 = Math.cos(rotation - skewX) * scaleY;\n\n if (skewX) {\n skewY *= _DEG2RAD;\n temp = Math.tan(skewX - skewY);\n temp = Math.sqrt(1 + temp * temp);\n a12 *= temp;\n a22 *= temp;\n\n if (skewY) {\n temp = Math.tan(skewY);\n temp = Math.sqrt(1 + temp * temp);\n a11 *= temp;\n a21 *= temp;\n }\n }\n\n a11 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a11);\n a21 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a21);\n a12 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a12);\n a22 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a22);\n } else {\n a11 = scaleX;\n a22 = scaleY;\n a21 = a12 = 0;\n }\n\n if (tx && !~(x + \"\").indexOf(\"px\") || ty && !~(y + \"\").indexOf(\"px\")) {\n tx = _convertToUnit(target, \"x\", x, \"px\");\n ty = _convertToUnit(target, \"y\", y, \"px\");\n }\n\n if (xOrigin || yOrigin || xOffset || yOffset) {\n tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);\n ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);\n }\n\n if (xPercent || yPercent) {\n //The SVG spec doesn't support percentage-based translation in the \"transform\" attribute, so we merge it into the translation to simulate it.\n temp = target.getBBox();\n tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xPercent / 100 * temp.width);\n ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yPercent / 100 * temp.height);\n }\n\n temp = \"matrix(\" + a11 + \",\" + a21 + \",\" + a12 + \",\" + a22 + \",\" + tx + \",\" + ty + \")\";\n target.setAttribute(\"transform\", temp);\n forceCSS && (target.style[_transformProp] = temp); //some browsers prioritize CSS transforms over the transform attribute. When we sense that the user has CSS transforms applied, we must overwrite them this way (otherwise some browser simply won't render the transform attribute changes!)\n},\n _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {\n var cap = 360,\n isString = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(endValue),\n endNum = parseFloat(endValue) * (isString && ~endValue.indexOf(\"rad\") ? _RAD2DEG : 1),\n change = endNum - startNum,\n finalValue = startNum + change + \"deg\",\n direction,\n pt;\n\n if (isString) {\n direction = endValue.split(\"_\")[1];\n\n if (direction === \"short\") {\n change %= cap;\n\n if (change !== change % (cap / 2)) {\n change += change < 0 ? cap : -cap;\n }\n }\n\n if (direction === \"cw\" && change < 0) {\n change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap;\n } else if (direction === \"ccw\" && change > 0) {\n change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap;\n }\n }\n\n plugin._pt = pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);\n pt.e = finalValue;\n pt.u = \"deg\";\n\n plugin._props.push(property);\n\n return pt;\n},\n _assign = function _assign(target, source) {\n // Internet Explorer doesn't have Object.assign(), so we recreate it here.\n for (var p in source) {\n target[p] = source[p];\n }\n\n return target;\n},\n _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {\n //for handling cases where someone passes in a whole transform string, like transform: \"scale(2, 3) rotate(20deg) translateY(30em)\"\n var startCache = _assign({}, target._gsap),\n exclude = \"perspective,force3D,transformOrigin,svgOrigin\",\n style = target.style,\n endCache,\n p,\n startValue,\n endValue,\n startNum,\n endNum,\n startUnit,\n endUnit;\n\n if (startCache.svg) {\n startValue = target.getAttribute(\"transform\");\n target.setAttribute(\"transform\", \"\");\n style[_transformProp] = transforms;\n endCache = _parseTransform(target, 1);\n\n _removeProperty(target, _transformProp);\n\n target.setAttribute(\"transform\", startValue);\n } else {\n startValue = getComputedStyle(target)[_transformProp];\n style[_transformProp] = transforms;\n endCache = _parseTransform(target, 1);\n style[_transformProp] = startValue;\n }\n\n for (p in _transformProps) {\n startValue = startCache[p];\n endValue = endCache[p];\n\n if (startValue !== endValue && exclude.indexOf(p) < 0) {\n //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.\n startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue);\n endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue);\n startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);\n endNum = parseFloat(endValue);\n plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);\n plugin._pt.u = endUnit || 0;\n\n plugin._props.push(p);\n }\n }\n\n _assign(endCache, startCache);\n}; // handle splitting apart padding, margin, borderWidth, and borderRadius into their 4 components. Firefox, for example, won't report borderRadius correctly - it will only do borderTopLeftRadius and the other corners. We also want to handle paddingTop, marginLeft, borderRightWidth, etc.\n\n\n(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(\"padding,margin,Width,Radius\", function (name, index) {\n var t = \"Top\",\n r = \"Right\",\n b = \"Bottom\",\n l = \"Left\",\n props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {\n return index < 2 ? name + side : \"border\" + side + name;\n });\n\n _specialProps[index > 1 ? \"border\" + name : name] = function (plugin, target, property, endValue, tween) {\n var a, vars;\n\n if (arguments.length < 4) {\n // getter, passed target, property, and unit (from _get())\n a = props.map(function (prop) {\n return _get(plugin, prop, property);\n });\n vars = a.join(\" \");\n return vars.split(a[0]).length === 5 ? a[0] : vars;\n }\n\n a = (endValue + \"\").split(\" \");\n vars = {};\n props.forEach(function (prop, i) {\n return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];\n });\n plugin.init(target, vars, tween);\n };\n});\n\nvar CSSPlugin = {\n name: \"css\",\n register: _initCore,\n targetTest: function targetTest(target) {\n return target.style && target.nodeType;\n },\n init: function init(target, vars, tween, index, targets) {\n var props = this._props,\n style = target.style,\n startAt = tween.vars.startAt,\n startValue,\n endValue,\n endNum,\n startNum,\n type,\n specialProp,\n p,\n startUnit,\n endUnit,\n relative,\n isTransformRelated,\n transformPropTween,\n cache,\n smooth,\n hasPriority,\n inlineProps;\n _pluginInitted || _initCore(); // we may call init() multiple times on the same plugin instance, like when adding special properties, so make sure we don't overwrite the revert data or inlineProps\n\n this.styles = this.styles || _getStyleSaver(target);\n inlineProps = this.styles.props;\n this.tween = tween;\n\n for (p in vars) {\n if (p === \"autoRound\") {\n continue;\n }\n\n endValue = vars[p];\n\n if (_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._plugins[p] && (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._checkPlugin)(p, vars, tween, index, target, targets)) {\n // plugins\n continue;\n }\n\n type = typeof endValue;\n specialProp = _specialProps[p];\n\n if (type === \"function\") {\n endValue = endValue.call(tween, index, target, targets);\n type = typeof endValue;\n }\n\n if (type === \"string\" && ~endValue.indexOf(\"random(\")) {\n endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(endValue);\n }\n\n if (specialProp) {\n specialProp(this, target, p, endValue, tween) && (hasPriority = 1);\n } else if (p.substr(0, 2) === \"--\") {\n //CSS variable\n startValue = (getComputedStyle(target).getPropertyValue(p) + \"\").trim();\n endValue += \"\";\n _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.lastIndex = 0;\n\n if (!_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.test(startValue)) {\n // colors don't have units\n startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue);\n endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue);\n }\n\n endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);\n this.add(style, \"setProperty\", startValue, endValue, index, targets, 0, 0, p);\n props.push(p);\n inlineProps.push(p, 0, style[p]);\n } else if (type !== \"undefined\") {\n if (startAt && p in startAt) {\n // in case someone hard-codes a complex value as the start, like top: \"calc(2vh / 2)\". Without this, it'd use the computed value (always in px)\n startValue = typeof startAt[p] === \"function\" ? startAt[p].call(tween, index, target, targets) : startAt[p];\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(startValue) && ~startValue.indexOf(\"random(\") && (startValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(startValue));\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue + \"\") || (startValue += _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[p] || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(_get(target, p)) || \"\"); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work.\n\n (startValue + \"\").charAt(1) === \"=\" && (startValue = _get(target, p)); // can't work with relative values\n } else {\n startValue = _get(target, p);\n }\n\n startNum = parseFloat(startValue);\n relative = type === \"string\" && endValue.charAt(1) === \"=\" && endValue.substr(0, 2);\n relative && (endValue = endValue.substr(2));\n endNum = parseFloat(endValue);\n\n if (p in _propertyAliases) {\n if (p === \"autoAlpha\") {\n //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened.\n if (startNum === 1 && _get(target, \"visibility\") === \"hidden\" && endNum) {\n //if visibility is initially set to \"hidden\", we should interpret that as intent to make opacity 0 (a convenience)\n startNum = 0;\n }\n\n inlineProps.push(\"visibility\", 0, style.visibility);\n\n _addNonTweeningPT(this, style, \"visibility\", startNum ? \"inherit\" : \"hidden\", endNum ? \"inherit\" : \"hidden\", !endNum);\n }\n\n if (p !== \"scale\" && p !== \"transform\") {\n p = _propertyAliases[p];\n ~p.indexOf(\",\") && (p = p.split(\",\")[0]);\n }\n }\n\n isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED ---\n\n if (isTransformRelated) {\n this.styles.save(p);\n\n if (!transformPropTween) {\n cache = target._gsap;\n cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); // if, for example, gsap.set(... {transform:\"translateX(50vw)\"}), the _get() call doesn't parse the transform, thus cache.renderTransform won't be set yet so force the parsing of the transform here.\n\n smooth = vars.smoothOrigin !== false && cache.smooth;\n transformPropTween = this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); //the first time through, create the rendering PropTween so that it runs LAST (in the linked list, we keep adding to the beginning)\n\n transformPropTween.dep = 1; //flag it as dependent so that if things get killed/overwritten and this is the only PropTween left, we can safely kill the whole tween.\n }\n\n if (p === \"scale\") {\n this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, cache, \"scaleY\", cache.scaleY, (relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp);\n this._pt.u = 0;\n props.push(\"scaleY\", p);\n p += \"X\";\n } else if (p === \"transformOrigin\") {\n inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]);\n endValue = _convertKeywordsToPercentages(endValue); //in case something like \"left top\" or \"bottom right\" is passed in. Convert to percentages.\n\n if (cache.svg) {\n _applySVGOrigin(target, endValue, 0, smooth, 0, this);\n } else {\n endUnit = parseFloat(endValue.split(\" \")[2]) || 0; //handle the zOrigin separately!\n\n endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, \"zOrigin\", cache.zOrigin, endUnit);\n\n _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));\n }\n\n continue;\n } else if (p === \"svgOrigin\") {\n _applySVGOrigin(target, endValue, 1, smooth, 0, this);\n\n continue;\n } else if (p in _rotationalProperties) {\n _addRotationalPropTween(this, cache, p, startNum, relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, relative + endValue) : endValue);\n\n continue;\n } else if (p === \"smoothOrigin\") {\n _addNonTweeningPT(this, cache, \"smooth\", cache.smooth, endValue);\n\n continue;\n } else if (p === \"force3D\") {\n cache[p] = endValue;\n continue;\n } else if (p === \"transform\") {\n _addRawTransformPTs(this, endValue, target);\n\n continue;\n }\n } else if (!(p in style)) {\n p = _checkPropPrefix(p) || p;\n }\n\n if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {\n startUnit = (startValue + \"\").substr((startNum + \"\").length);\n endNum || (endNum = 0); // protect against NaN\n\n endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue) || (p in _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units ? _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[p] : startUnit);\n startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));\n this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === \"px\" || p === \"zIndex\") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);\n this._pt.u = endUnit || 0;\n\n if (startUnit !== endUnit && endUnit !== \"%\") {\n //when the tween goes all the way back to the beginning, we need to revert it to the OLD/ORIGINAL value (with those units). We record that as a \"b\" (beginning) property and point to a render method that handles that. (performance optimization)\n this._pt.b = startValue;\n this._pt.r = _renderCSSPropWithBeginning;\n }\n } else if (!(p in style)) {\n if (p in target) {\n //maybe it's not a style - it could be a property added directly to an element in which case we'll try to animate that.\n this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);\n } else if (p !== \"parseTransform\") {\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._missingPlugin)(p, endValue);\n\n continue;\n }\n } else {\n _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);\n }\n\n isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p]));\n props.push(p);\n }\n }\n\n hasPriority && (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._sortPropTweensByPriority)(this);\n },\n render: function render(ratio, data) {\n if (data.tween._time || !_reverting()) {\n var pt = data._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n } else {\n data.styles.revert();\n }\n },\n get: _get,\n aliases: _propertyAliases,\n getSetter: function getSetter(target, property, plugin) {\n //returns a setter function that accepts target, property, value and applies it accordingly. Remember, properties like \"x\" aren't as simple as target.style.property = value because they've got to be applied to a proxy object and then merged into a transform string in a renderer.\n var p = _propertyAliases[property];\n p && p.indexOf(\",\") < 0 && (property = p);\n return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, \"x\")) ? plugin && _recentSetterPlugin === plugin ? property === \"scale\" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === \"scale\" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isUndefined)(target.style[property]) ? _setterCSSStyle : ~property.indexOf(\"-\") ? _setterCSSProp : (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getSetter)(target, property);\n },\n core: {\n _removeProperty: _removeProperty,\n _getMatrix: _getMatrix\n }\n};\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.checkPrefix = _checkPropPrefix;\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.getStyleSaver = _getStyleSaver;\n\n(function (positionAndScale, rotation, others, aliases) {\n var all = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(positionAndScale + \",\" + rotation + \",\" + others, function (name) {\n _transformProps[name] = 1;\n });\n\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(rotation, function (name) {\n _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = \"deg\";\n _rotationalProperties[name] = 1;\n });\n\n _propertyAliases[all[13]] = positionAndScale + \",\" + rotation;\n\n (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(aliases, function (name) {\n var split = name.split(\":\");\n _propertyAliases[split[1]] = all[split[0]];\n });\n})(\"x,y,z,scale,scaleX,scaleY,xPercent,yPercent\", \"rotation,rotationX,rotationY,skewX,skewY\", \"transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective\", \"0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY\");\n\n(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(\"x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective\", function (name) {\n _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = \"px\";\n});\n\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(CSSPlugin);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QW1CIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vQHdlYXJlYXRobG9uL2Zyb250ZW5kLXdlYnBhY2stYm9pbGVycGxhdGUvLi9ub2RlX21vZHVsZXMvZ3NhcC9DU1NQbHVnaW4uanM/OWNlNiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIENTU1BsdWdpbiAzLjExLjVcbiAqIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbVxuICpcbiAqIENvcHlyaWdodCAyMDA4LTIwMjMsIEdyZWVuU29jay4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFN1YmplY3QgdG8gdGhlIHRlcm1zIGF0IGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHcmVlblNvY2sgbWVtYmVycywgdGhlIGFncmVlbWVudCBpc3N1ZWQgd2l0aCB0aGF0IG1lbWJlcnNoaXAuXG4gKiBAYXV0aG9yOiBKYWNrIERveWxlLCBqYWNrQGdyZWVuc29jay5jb21cbiovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgeyBnc2FwLCBfZ2V0UHJvcGVydHksIF9udW1FeHAsIF9udW1XaXRoVW5pdEV4cCwgZ2V0VW5pdCwgX2lzU3RyaW5nLCBfaXNVbmRlZmluZWQsIF9yZW5kZXJDb21wbGV4U3RyaW5nLCBfcmVsRXhwLCBfZm9yRWFjaE5hbWUsIF9zb3J0UHJvcFR3ZWVuc0J5UHJpb3JpdHksIF9jb2xvclN0cmluZ0ZpbHRlciwgX2NoZWNrUGx1Z2luLCBfcmVwbGFjZVJhbmRvbSwgX3BsdWdpbnMsIEdTQ2FjaGUsIFByb3BUd2VlbiwgX2NvbmZpZywgX3RpY2tlciwgX3JvdW5kLCBfbWlzc2luZ1BsdWdpbiwgX2dldFNldHRlciwgX2dldENhY2hlLCBfY29sb3JFeHAsIF9wYXJzZVJlbGF0aXZlLCBfc2V0RGVmYXVsdHMsIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSAvL2ZvciB0aGUgY29tbWVudGVkLW91dCBjbGFzc05hbWUgZmVhdHVyZS5cbn0gZnJvbSBcIi4vZ3NhcC1jb3JlLmpzXCI7XG5cbnZhciBfd2luLFxuICAgIF9kb2MsXG4gICAgX2RvY0VsZW1lbnQsXG4gICAgX3BsdWdpbkluaXR0ZWQsXG4gICAgX3RlbXBEaXYsXG4gICAgX3RlbXBEaXZTdHlsZXIsXG4gICAgX3JlY2VudFNldHRlclBsdWdpbixcbiAgICBfcmV2ZXJ0aW5nLFxuICAgIF93aW5kb3dFeGlzdHMgPSBmdW5jdGlvbiBfd2luZG93RXhpc3RzKCkge1xuICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIjtcbn0sXG4gICAgX3RyYW5zZm9ybVByb3BzID0ge30sXG4gICAgX1JBRDJERUcgPSAxODAgLyBNYXRoLlBJLFxuICAgIF9ERUcyUkFEID0gTWF0aC5QSSAvIDE4MCxcbiAgICBfYXRhbjIgPSBNYXRoLmF0YW4yLFxuICAgIF9iaWdOdW0gPSAxZTgsXG4gICAgX2NhcHNFeHAgPSAvKFtBLVpdKS9nLFxuICAgIF9ob3Jpem9udGFsRXhwID0gLyhsZWZ0fHJpZ2h0fHdpZHRofG1hcmdpbnxwYWRkaW5nfHgpL2ksXG4gICAgX2NvbXBsZXhFeHAgPSAvW1xccyxcXChdXFxTLyxcbiAgICBfcHJvcGVydHlBbGlhc2VzID0ge1xuICBhdXRvQWxwaGE6IFwib3BhY2l0eSx2aXNpYmlsaXR5XCIsXG4gIHNjYWxlOiBcInNjYWxlWCxzY2FsZVlcIixcbiAgYWxwaGE6IFwib3BhY2l0eVwiXG59LFxuICAgIF9yZW5kZXJDU1NQcm9wID0gZnVuY3Rpb24gX3JlbmRlckNTU1Byb3AocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCBNYXRoLnJvdW5kKChkYXRhLnMgKyBkYXRhLmMgKiByYXRpbykgKiAxMDAwMCkgLyAxMDAwMCArIGRhdGEudSwgZGF0YSk7XG59LFxuICAgIF9yZW5kZXJQcm9wV2l0aEVuZCA9IGZ1bmN0aW9uIF9yZW5kZXJQcm9wV2l0aEVuZChyYXRpbywgZGF0YSkge1xuICByZXR1cm4gZGF0YS5zZXQoZGF0YS50LCBkYXRhLnAsIHJhdGlvID09PSAxID8gZGF0YS5lIDogTWF0aC5yb3VuZCgoZGF0YS5zICsgZGF0YS5jICogcmF0aW8pICogMTAwMDApIC8gMTAwMDAgKyBkYXRhLnUsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyQ1NTUHJvcFdpdGhCZWdpbm5pbmcgPSBmdW5jdGlvbiBfcmVuZGVyQ1NTUHJvcFdpdGhCZWdpbm5pbmcocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCByYXRpbyA/IE1hdGgucm91bmQoKGRhdGEucyArIGRhdGEuYyAqIHJhdGlvKSAqIDEwMDAwKSAvIDEwMDAwICsgZGF0YS51IDogZGF0YS5iLCBkYXRhKTtcbn0sXG4gICAgLy9pZiB1bml0cyBjaGFuZ2UsIHdlIG5lZWQgYSB3YXkgdG8gcmVuZGVyIHRoZSBvcmlnaW5hbCB1bml0L3ZhbHVlIHdoZW4gdGhlIHR3ZWVuIGdvZXMgYWxsIHRoZSB3YXkgYmFjayB0byB0aGUgYmVnaW5uaW5nIChyYXRpbzowKVxuX3JlbmRlclJvdW5kZWRDU1NQcm9wID0gZnVuY3Rpb24gX3JlbmRlclJvdW5kZWRDU1NQcm9wKHJhdGlvLCBkYXRhKSB7XG4gIHZhciB2YWx1ZSA9IGRhdGEucyArIGRhdGEuYyAqIHJhdGlvO1xuICBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgfn4odmFsdWUgKyAodmFsdWUgPCAwID8gLS41IDogLjUpKSArIGRhdGEudSwgZGF0YSk7XG59LFxuICAgIF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlID0gZnVuY3Rpb24gX3JlbmRlck5vblR3ZWVuaW5nVmFsdWUocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCByYXRpbyA/IGRhdGEuZSA6IGRhdGEuYiwgZGF0YSk7XG59LFxuICAgIF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlT25seUF0RW5kID0gZnVuY3Rpb24gX3JlbmRlck5vblR3ZWVuaW5nVmFsdWVPbmx5QXRFbmQocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCByYXRpbyAhPT0gMSA/IGRhdGEuYiA6IGRhdGEuZSwgZGF0YSk7XG59LFxuICAgIF9zZXR0ZXJDU1NTdHlsZSA9IGZ1bmN0aW9uIF9zZXR0ZXJDU1NTdHlsZSh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gdGFyZ2V0LnN0eWxlW3Byb3BlcnR5XSA9IHZhbHVlO1xufSxcbiAgICBfc2V0dGVyQ1NTUHJvcCA9IGZ1bmN0aW9uIF9zZXR0ZXJDU1NQcm9wKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG4gIHJldHVybiB0YXJnZXQuc3R5bGUuc2V0UHJvcGVydHkocHJvcGVydHksIHZhbHVlKTtcbn0sXG4gICAgX3NldHRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uIF9zZXR0ZXJUcmFuc2Zvcm0odGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgcmV0dXJuIHRhcmdldC5fZ3NhcFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbn0sXG4gICAgX3NldHRlclNjYWxlID0gZnVuY3Rpb24gX3NldHRlclNjYWxlKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG4gIHJldHVybiB0YXJnZXQuX2dzYXAuc2NhbGVYID0gdGFyZ2V0Ll9nc2FwLnNjYWxlWSA9IHZhbHVlO1xufSxcbiAgICBfc2V0dGVyU2NhbGVXaXRoUmVuZGVyID0gZnVuY3Rpb24gX3NldHRlclNjYWxlV2l0aFJlbmRlcih0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgZGF0YSwgcmF0aW8pIHtcbiAgdmFyIGNhY2hlID0gdGFyZ2V0Ll9nc2FwO1xuICBjYWNoZS5zY2FsZVggPSBjYWNoZS5zY2FsZVkgPSB2YWx1ZTtcbiAgY2FjaGUucmVuZGVyVHJhbnNmb3JtKHJhdGlvLCBjYWNoZSk7XG59LFxuICAgIF9zZXR0ZXJUcmFuc2Zvcm1XaXRoUmVuZGVyID0gZnVuY3Rpb24gX3NldHRlclRyYW5zZm9ybVdpdGhSZW5kZXIodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIGRhdGEsIHJhdGlvKSB7XG4gIHZhciBjYWNoZSA9IHRhcmdldC5fZ3NhcDtcbiAgY2FjaGVbcHJvcGVydHldID0gdmFsdWU7XG4gIGNhY2hlLnJlbmRlclRyYW5zZm9ybShyYXRpbywgY2FjaGUpO1xufSxcbiAgICBfdHJhbnNmb3JtUHJvcCA9IFwidHJhbnNmb3JtXCIsXG4gICAgX3RyYW5zZm9ybU9yaWdpblByb3AgPSBfdHJhbnNmb3JtUHJvcCArIFwiT3JpZ2luXCIsXG4gICAgX3NhdmVTdHlsZSA9IGZ1bmN0aW9uIF9zYXZlU3R5bGUocHJvcGVydHksIGlzTm90Q1NTKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHRhcmdldCA9IHRoaXMudGFyZ2V0LFxuICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGU7XG5cbiAgaWYgKHByb3BlcnR5IGluIF90cmFuc2Zvcm1Qcm9wcykge1xuICAgIHRoaXMudGZtID0gdGhpcy50Zm0gfHwge307XG5cbiAgICBpZiAocHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgIHByb3BlcnR5ID0gX3Byb3BlcnR5QWxpYXNlc1twcm9wZXJ0eV0gfHwgcHJvcGVydHk7XG4gICAgICB+cHJvcGVydHkuaW5kZXhPZihcIixcIikgPyBwcm9wZXJ0eS5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAoYSkge1xuICAgICAgICByZXR1cm4gX3RoaXMudGZtW2FdID0gX2dldCh0YXJnZXQsIGEpO1xuICAgICAgfSkgOiB0aGlzLnRmbVtwcm9wZXJ0eV0gPSB0YXJnZXQuX2dzYXAueCA/IHRhcmdldC5fZ3NhcFtwcm9wZXJ0eV0gOiBfZ2V0KHRhcmdldCwgcHJvcGVydHkpOyAvLyBub3RlOiBzY2FsZSB3b3VsZCBtYXAgdG8gXCJzY2FsZVgsc2NhbGVZXCIsIHRodXMgd2UgbG9vcCBhbmQgYXBwbHkgdGhlbSBib3RoLlxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gX3Byb3BlcnR5QWxpYXNlcy50cmFuc2Zvcm0uc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgICAgcmV0dXJuIF9zYXZlU3R5bGUuY2FsbChfdGhpcywgcCwgaXNOb3RDU1MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvcHMuaW5kZXhPZihfdHJhbnNmb3JtUHJvcCkgPj0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQuX2dzYXAuc3ZnKSB7XG4gICAgICB0aGlzLnN2Z28gPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0YS1zdmctb3JpZ2luXCIpO1xuICAgICAgdGhpcy5wcm9wcy5wdXNoKF90cmFuc2Zvcm1PcmlnaW5Qcm9wLCBpc05vdENTUywgXCJcIik7XG4gICAgfVxuXG4gICAgcHJvcGVydHkgPSBfdHJhbnNmb3JtUHJvcDtcbiAgfVxuXG4gIChzdHlsZSB8fCBpc05vdENTUykgJiYgdGhpcy5wcm9wcy5wdXNoKHByb3BlcnR5LCBpc05vdENTUywgc3R5bGVbcHJvcGVydHldKTtcbn0sXG4gICAgX3JlbW92ZUluZGVwZW5kZW50VHJhbnNmb3JtcyA9IGZ1bmN0aW9uIF9yZW1vdmVJbmRlcGVuZGVudFRyYW5zZm9ybXMoc3R5bGUpIHtcbiAgaWYgKHN0eWxlLnRyYW5zbGF0ZSkge1xuICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KFwidHJhbnNsYXRlXCIpO1xuICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KFwic2NhbGVcIik7XG4gICAgc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJyb3RhdGVcIik7XG4gIH1cbn0sXG4gICAgX3JldmVydFN0eWxlID0gZnVuY3Rpb24gX3JldmVydFN0eWxlKCkge1xuICB2YXIgcHJvcHMgPSB0aGlzLnByb3BzLFxuICAgICAgdGFyZ2V0ID0gdGhpcy50YXJnZXQsXG4gICAgICBzdHlsZSA9IHRhcmdldC5zdHlsZSxcbiAgICAgIGNhY2hlID0gdGFyZ2V0Ll9nc2FwLFxuICAgICAgaSxcbiAgICAgIHA7XG5cbiAgZm9yIChpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgLy8gc3RvcmVkIGxpa2UgdGhpczogcHJvcGVydHksIGlzTm90Q1NTLCB2YWx1ZVxuICAgIHByb3BzW2kgKyAxXSA/IHRhcmdldFtwcm9wc1tpXV0gPSBwcm9wc1tpICsgMl0gOiBwcm9wc1tpICsgMl0gPyBzdHlsZVtwcm9wc1tpXV0gPSBwcm9wc1tpICsgMl0gOiBzdHlsZS5yZW1vdmVQcm9wZXJ0eShwcm9wc1tpXS5zdWJzdHIoMCwgMikgPT09IFwiLS1cIiA/IHByb3BzW2ldIDogcHJvcHNbaV0ucmVwbGFjZShfY2Fwc0V4cCwgXCItJDFcIikudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICBpZiAodGhpcy50Zm0pIHtcbiAgICBmb3IgKHAgaW4gdGhpcy50Zm0pIHtcbiAgICAgIGNhY2hlW3BdID0gdGhpcy50Zm1bcF07XG4gICAgfVxuXG4gICAgaWYgKGNhY2hlLnN2Zykge1xuICAgICAgY2FjaGUucmVuZGVyVHJhbnNmb3JtKCk7XG4gICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwiZGF0YS1zdmctb3JpZ2luXCIsIHRoaXMuc3ZnbyB8fCBcIlwiKTtcbiAgICB9XG5cbiAgICBpID0gX3JldmVydGluZygpO1xuXG4gICAgaWYgKCghaSB8fCAhaS5pc1N0YXJ0KSAmJiAhc3R5bGVbX3RyYW5zZm9ybVByb3BdKSB7XG4gICAgICBfcmVtb3ZlSW5kZXBlbmRlbnRUcmFuc2Zvcm1zKHN0eWxlKTtcblxuICAgICAgY2FjaGUudW5jYWNoZSA9IDE7IC8vIGlmIGl0J3MgYSBzdGFydEF0IHRoYXQncyBiZWluZyByZXZlcnRlZCBpbiB0aGUgX2luaXRUd2VlbigpIG9mIHRoZSBjb3JlLCB3ZSBkb24ndCBuZWVkIHRvIHVuY2FjaGUgdHJhbnNmb3Jtcy4gVGhpcyBpcyBwdXJlbHkgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24uXG4gICAgfVxuICB9XG59LFxuICAgIF9nZXRTdHlsZVNhdmVyID0gZnVuY3Rpb24gX2dldFN0eWxlU2F2ZXIodGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciBzYXZlciA9IHtcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICBwcm9wczogW10sXG4gICAgcmV2ZXJ0OiBfcmV2ZXJ0U3R5bGUsXG4gICAgc2F2ZTogX3NhdmVTdHlsZVxuICB9O1xuICB0YXJnZXQuX2dzYXAgfHwgZ3NhcC5jb3JlLmdldENhY2hlKHRhcmdldCk7IC8vIGp1c3QgbWFrZSBzdXJlIHRoZXJlJ3MgYSBfZ3NhcCBjYWNoZSBkZWZpbmVkIGJlY2F1c2Ugd2UgcmVhZCBmcm9tIGl0IGluIF9zYXZlU3R5bGUoKSBhbmQgaXQncyBtb3JlIGVmZmljaWVudCB0byBqdXN0IGNoZWNrIGl0IGhlcmUgb25jZS5cblxuICBwcm9wZXJ0aWVzICYmIHByb3BlcnRpZXMuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gc2F2ZXIuc2F2ZShwKTtcbiAgfSk7XG4gIHJldHVybiBzYXZlcjtcbn0sXG4gICAgX3N1cHBvcnRzM0QsXG4gICAgX2NyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiBfY3JlYXRlRWxlbWVudCh0eXBlLCBucykge1xuICB2YXIgZSA9IF9kb2MuY3JlYXRlRWxlbWVudE5TID8gX2RvYy5jcmVhdGVFbGVtZW50TlMoKG5zIHx8IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiKS5yZXBsYWNlKC9eaHR0cHMvLCBcImh0dHBcIiksIHR5cGUpIDogX2RvYy5jcmVhdGVFbGVtZW50KHR5cGUpOyAvL3NvbWUgc2VydmVycyBzd2FwIGluIGh0dHBzIGZvciBodHRwIGluIHRoZSBuYW1lc3BhY2Ugd2hpY2ggY2FuIGJyZWFrIHRoaW5ncywgbWFraW5nIFwic3R5bGVcIiBpbmFjY2Vzc2libGUuXG5cbiAgcmV0dXJuIGUuc3R5bGUgPyBlIDogX2RvYy5jcmVhdGVFbGVtZW50KHR5cGUpOyAvL3NvbWUgZW52aXJvbm1lbnRzIHdvbid0IGFsbG93IGFjY2VzcyB0byB0aGUgZWxlbWVudCdzIHN0eWxlIHdoZW4gY3JlYXRlZCB3aXRoIGEgbmFtZXNwYWNlIGluIHdoaWNoIGNhc2Ugd2UgZGVmYXVsdCB0byB0aGUgc3RhbmRhcmQgY3JlYXRlRWxlbWVudCgpIHRvIHdvcmsgYXJvdW5kIHRoZSBpc3N1ZS4gQWxzbyBub3RlIHRoYXQgd2hlbiBHU0FQIGlzIGVtYmVkZGVkIGRpcmVjdGx5IGluc2lkZSBhbiBTVkcgZmlsZSwgY3JlYXRlRWxlbWVudCgpIHdvbid0IGFsbG93IGFjY2VzcyB0byB0aGUgc3R5bGUgb2JqZWN0IGluIEZpcmVmb3ggKHNlZSBodHRwczovL2dyZWVuc29jay5jb20vZm9ydW1zL3RvcGljLzIwMjE1LXByb2JsZW0tdXNpbmctdHdlZW5tYXgtaW4tc3RhbmRhbG9uZS1zZWxmLWNvbnRhaW5pbmctc3ZnLWZpbGUtZXJyLWNhbm5vdC1zZXQtcHJvcGVydHktY3NzdGV4dC1vZi11bmRlZmluZWQvKS5cbn0sXG4gICAgX2dldENvbXB1dGVkUHJvcGVydHkgPSBmdW5jdGlvbiBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCBza2lwUHJlZml4RmFsbGJhY2spIHtcbiAgdmFyIGNzID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xuICByZXR1cm4gY3NbcHJvcGVydHldIHx8IGNzLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkucmVwbGFjZShfY2Fwc0V4cCwgXCItJDFcIikudG9Mb3dlckNhc2UoKSkgfHwgY3MuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSkgfHwgIXNraXBQcmVmaXhGYWxsYmFjayAmJiBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIF9jaGVja1Byb3BQcmVmaXgocHJvcGVydHkpIHx8IHByb3BlcnR5LCAxKSB8fCBcIlwiOyAvL2NzcyB2YXJpYWJsZXMgbWF5IG5vdCBuZWVkIGNhcHMgc3dhcHBlZCBvdXQgZm9yIGRhc2hlcyBhbmQgbG93ZXJjYXNlLlxufSxcbiAgICBfcHJlZml4ZXMgPSBcIk8sTW96LG1zLE1zLFdlYmtpdFwiLnNwbGl0KFwiLFwiKSxcbiAgICBfY2hlY2tQcm9wUHJlZml4ID0gZnVuY3Rpb24gX2NoZWNrUHJvcFByZWZpeChwcm9wZXJ0eSwgZWxlbWVudCwgcHJlZmVyUHJlZml4KSB7XG4gIHZhciBlID0gZWxlbWVudCB8fCBfdGVtcERpdixcbiAgICAgIHMgPSBlLnN0eWxlLFxuICAgICAgaSA9IDU7XG5cbiAgaWYgKHByb3BlcnR5IGluIHMgJiYgIXByZWZlclByZWZpeCkge1xuICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgfVxuXG4gIHByb3BlcnR5ID0gcHJvcGVydHkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwcm9wZXJ0eS5zdWJzdHIoMSk7XG5cbiAgd2hpbGUgKGktLSAmJiAhKF9wcmVmaXhlc1tpXSArIHByb3BlcnR5IGluIHMpKSB7fVxuXG4gIHJldHVybiBpIDwgMCA/IG51bGwgOiAoaSA9PT0gMyA/IFwibXNcIiA6IGkgPj0gMCA/IF9wcmVmaXhlc1tpXSA6IFwiXCIpICsgcHJvcGVydHk7XG59LFxuICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZSgpIHtcbiAgaWYgKF93aW5kb3dFeGlzdHMoKSAmJiB3aW5kb3cuZG9jdW1lbnQpIHtcbiAgICBfd2luID0gd2luZG93O1xuICAgIF9kb2MgPSBfd2luLmRvY3VtZW50O1xuICAgIF9kb2NFbGVtZW50ID0gX2RvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgX3RlbXBEaXYgPSBfY3JlYXRlRWxlbWVudChcImRpdlwiKSB8fCB7XG4gICAgICBzdHlsZToge31cbiAgICB9O1xuICAgIF90ZW1wRGl2U3R5bGVyID0gX2NyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgX3RyYW5zZm9ybVByb3AgPSBfY2hlY2tQcm9wUHJlZml4KF90cmFuc2Zvcm1Qcm9wKTtcbiAgICBfdHJhbnNmb3JtT3JpZ2luUHJvcCA9IF90cmFuc2Zvcm1Qcm9wICsgXCJPcmlnaW5cIjtcbiAgICBfdGVtcERpdi5zdHlsZS5jc3NUZXh0ID0gXCJib3JkZXItd2lkdGg6MDtsaW5lLWhlaWdodDowO3Bvc2l0aW9uOmFic29sdXRlO3BhZGRpbmc6MFwiOyAvL21ha2Ugc3VyZSB0byBvdmVycmlkZSBjZXJ0YWluIHByb3BlcnRpZXMgdGhhdCBtYXkgY29udGFtaW5hdGUgbWVhc3VyZW1lbnRzLCBpbiBjYXNlIHRoZSB1c2VyIGhhcyBvdmVycmVhY2hpbmcgc3R5bGUgc2hlZXRzLlxuXG4gICAgX3N1cHBvcnRzM0QgPSAhIV9jaGVja1Byb3BQcmVmaXgoXCJwZXJzcGVjdGl2ZVwiKTtcbiAgICBfcmV2ZXJ0aW5nID0gZ3NhcC5jb3JlLnJldmVydGluZztcbiAgICBfcGx1Z2luSW5pdHRlZCA9IDE7XG4gIH1cbn0sXG4gICAgX2dldEJCb3hIYWNrID0gZnVuY3Rpb24gX2dldEJCb3hIYWNrKHN3YXBJZlBvc3NpYmxlKSB7XG4gIC8vd29ya3MgYXJvdW5kIGlzc3VlcyBpbiBzb21lIGJyb3dzZXJzIChsaWtlIEZpcmVmb3gpIHRoYXQgZG9uJ3QgY29ycmVjdGx5IHJlcG9ydCBnZXRCQm94KCkgb24gU1ZHIGVsZW1lbnRzIGluc2lkZSBhIDxkZWZzPiBlbGVtZW50IGFuZC9vciA8bWFzaz4uIFdlIHRyeSBjcmVhdGluZyBhbiBTVkcsIGFkZGluZyBpdCB0byB0aGUgZG9jdW1lbnRFbGVtZW50IGFuZCB0b3NzIHRoZSBlbGVtZW50IGluIHRoZXJlIHNvIHRoYXQgaXQncyBkZWZpbml0ZWx5IHBhcnQgb2YgdGhlIHJlbmRlcmluZyB0cmVlLCB0aGVuIGdyYWIgdGhlIGJib3ggYW5kIGlmIGl0IHdvcmtzLCB3ZSBhY3R1YWxseSBzd2FwIG91dCB0aGUgb3JpZ2luYWwgZ2V0QkJveCgpIG1ldGhvZCBmb3Igb3VyIG93biB0aGF0IGRvZXMgdGhlc2UgZXh0cmEgc3RlcHMgd2hlbmV2ZXIgZ2V0QkJveCBpcyBuZWVkZWQuIFRoaXMgaGVscHMgZW5zdXJlIHRoYXQgcGVyZm9ybWFuY2UgaXMgb3B0aW1hbCAob25seSBkbyBhbGwgdGhlc2UgZXh0cmEgc3RlcHMgd2hlbiBhYnNvbHV0ZWx5IG5lY2Vzc2FyeS4uLm1vc3QgZWxlbWVudHMgZG9uJ3QgbmVlZCBpdCkuXG4gIHZhciBzdmcgPSBfY3JlYXRlRWxlbWVudChcInN2Z1wiLCB0aGlzLm93bmVyU1ZHRWxlbWVudCAmJiB0aGlzLm93bmVyU1ZHRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ4bWxuc1wiKSB8fCBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIpLFxuICAgICAgb2xkUGFyZW50ID0gdGhpcy5wYXJlbnROb2RlLFxuICAgICAgb2xkU2libGluZyA9IHRoaXMubmV4dFNpYmxpbmcsXG4gICAgICBvbGRDU1MgPSB0aGlzLnN0eWxlLmNzc1RleHQsXG4gICAgICBiYm94O1xuXG4gIF9kb2NFbGVtZW50LmFwcGVuZENoaWxkKHN2Zyk7XG5cbiAgc3ZnLmFwcGVuZENoaWxkKHRoaXMpO1xuICB0aGlzLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG5cbiAgaWYgKHN3YXBJZlBvc3NpYmxlKSB7XG4gICAgdHJ5IHtcbiAgICAgIGJib3ggPSB0aGlzLmdldEJCb3goKTtcbiAgICAgIHRoaXMuX2dzYXBCQm94ID0gdGhpcy5nZXRCQm94OyAvL3N0b3JlIHRoZSBvcmlnaW5hbFxuXG4gICAgICB0aGlzLmdldEJCb3ggPSBfZ2V0QkJveEhhY2s7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfSBlbHNlIGlmICh0aGlzLl9nc2FwQkJveCkge1xuICAgIGJib3ggPSB0aGlzLl9nc2FwQkJveCgpO1xuICB9XG5cbiAgaWYgKG9sZFBhcmVudCkge1xuICAgIGlmIChvbGRTaWJsaW5nKSB7XG4gICAgICBvbGRQYXJlbnQuaW5zZXJ0QmVmb3JlKHRoaXMsIG9sZFNpYmxpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvbGRQYXJlbnQuYXBwZW5kQ2hpbGQodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgX2RvY0VsZW1lbnQucmVtb3ZlQ2hpbGQoc3ZnKTtcblxuICB0aGlzLnN0eWxlLmNzc1RleHQgPSBvbGRDU1M7XG4gIHJldHVybiBiYm94O1xufSxcbiAgICBfZ2V0QXR0cmlidXRlRmFsbGJhY2tzID0gZnVuY3Rpb24gX2dldEF0dHJpYnV0ZUZhbGxiYWNrcyh0YXJnZXQsIGF0dHJpYnV0ZXNBcnJheSkge1xuICB2YXIgaSA9IGF0dHJpYnV0ZXNBcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIGlmICh0YXJnZXQuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZXNBcnJheVtpXSkpIHtcbiAgICAgIHJldHVybiB0YXJnZXQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZXNBcnJheVtpXSk7XG4gICAgfVxuICB9XG59LFxuICAgIF9nZXRCQm94ID0gZnVuY3Rpb24gX2dldEJCb3godGFyZ2V0KSB7XG4gIHZhciBib3VuZHM7XG5cbiAgdHJ5IHtcbiAgICBib3VuZHMgPSB0YXJnZXQuZ2V0QkJveCgpOyAvL0ZpcmVmb3ggdGhyb3dzIGVycm9ycyBpZiB5b3UgdHJ5IGNhbGxpbmcgZ2V0QkJveCgpIG9uIGFuIFNWRyBlbGVtZW50IHRoYXQncyBub3QgcmVuZGVyZWQgKGxpa2UgaW4gYSA8c3ltYm9sPiBvciA8ZGVmcz4pLiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02MTIxMThcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBib3VuZHMgPSBfZ2V0QkJveEhhY2suY2FsbCh0YXJnZXQsIHRydWUpO1xuICB9XG5cbiAgYm91bmRzICYmIChib3VuZHMud2lkdGggfHwgYm91bmRzLmhlaWdodCkgfHwgdGFyZ2V0LmdldEJCb3ggPT09IF9nZXRCQm94SGFjayB8fCAoYm91bmRzID0gX2dldEJCb3hIYWNrLmNhbGwodGFyZ2V0LCB0cnVlKSk7IC8vc29tZSBicm93c2VycyAobGlrZSBGaXJlZm94KSBtaXNyZXBvcnQgdGhlIGJvdW5kcyBpZiB0aGUgZWxlbWVudCBoYXMgemVybyB3aWR0aCBhbmQgaGVpZ2h0IChpdCBqdXN0IGFzc3VtZXMgaXQncyBhdCB4OjAsIHk6MCksIHRodXMgd2UgbmVlZCB0byBtYW51YWxseSBncmFiIHRoZSBwb3NpdGlvbiBpbiB0aGF0IGNhc2UuXG5cbiAgcmV0dXJuIGJvdW5kcyAmJiAhYm91bmRzLndpZHRoICYmICFib3VuZHMueCAmJiAhYm91bmRzLnkgPyB7XG4gICAgeDogK19nZXRBdHRyaWJ1dGVGYWxsYmFja3ModGFyZ2V0LCBbXCJ4XCIsIFwiY3hcIiwgXCJ4MVwiXSkgfHwgMCxcbiAgICB5OiArX2dldEF0dHJpYnV0ZUZhbGxiYWNrcyh0YXJnZXQsIFtcInlcIiwgXCJjeVwiLCBcInkxXCJdKSB8fCAwLFxuICAgIHdpZHRoOiAwLFxuICAgIGhlaWdodDogMFxuICB9IDogYm91bmRzO1xufSxcbiAgICBfaXNTVkcgPSBmdW5jdGlvbiBfaXNTVkcoZSkge1xuICByZXR1cm4gISEoZS5nZXRDVE0gJiYgKCFlLnBhcmVudE5vZGUgfHwgZS5vd25lclNWR0VsZW1lbnQpICYmIF9nZXRCQm94KGUpKTtcbn0sXG4gICAgLy9yZXBvcnRzIGlmIHRoZSBlbGVtZW50IGlzIGFuIFNWRyBvbiB3aGljaCBnZXRCQm94KCkgYWN0dWFsbHkgd29ya3Ncbl9yZW1vdmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIF9yZW1vdmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5KSB7XG4gIGlmIChwcm9wZXJ0eSkge1xuICAgIHZhciBzdHlsZSA9IHRhcmdldC5zdHlsZTtcblxuICAgIGlmIChwcm9wZXJ0eSBpbiBfdHJhbnNmb3JtUHJvcHMgJiYgcHJvcGVydHkgIT09IF90cmFuc2Zvcm1PcmlnaW5Qcm9wKSB7XG4gICAgICBwcm9wZXJ0eSA9IF90cmFuc2Zvcm1Qcm9wO1xuICAgIH1cblxuICAgIGlmIChzdHlsZS5yZW1vdmVQcm9wZXJ0eSkge1xuICAgICAgaWYgKHByb3BlcnR5LnN1YnN0cigwLCAyKSA9PT0gXCJtc1wiIHx8IHByb3BlcnR5LnN1YnN0cigwLCA2KSA9PT0gXCJ3ZWJraXRcIikge1xuICAgICAgICAvL01pY3Jvc29mdCBhbmQgc29tZSBXZWJraXQgYnJvd3NlcnMgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3RhbmRhcmQgb2YgY2FwaXRhbGl6aW5nIHRoZSBmaXJzdCBwcmVmaXggY2hhcmFjdGVyLCBzbyB3ZSBhZGp1c3Qgc28gdGhhdCB3aGVuIHdlIHByZWZpeCB0aGUgY2FwcyB3aXRoIGEgZGFzaCwgaXQncyBjb3JyZWN0IChvdGhlcndpc2UgaXQnZCBiZSBcIm1zLXRyYW5zZm9ybVwiIGluc3RlYWQgb2YgXCItbXMtdHJhbnNmb3JtXCIgZm9yIElFOSwgZm9yIGV4YW1wbGUpXG4gICAgICAgIHByb3BlcnR5ID0gXCItXCIgKyBwcm9wZXJ0eTtcbiAgICAgIH1cblxuICAgICAgc3R5bGUucmVtb3ZlUHJvcGVydHkocHJvcGVydHkucmVwbGFjZShfY2Fwc0V4cCwgXCItJDFcIikudG9Mb3dlckNhc2UoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vbm90ZTogb2xkIHZlcnNpb25zIG9mIElFIHVzZSBcInJlbW92ZUF0dHJpYnV0ZSgpXCIgaW5zdGVhZCBvZiBcInJlbW92ZVByb3BlcnR5KClcIlxuICAgICAgc3R5bGUucmVtb3ZlQXR0cmlidXRlKHByb3BlcnR5KTtcbiAgICB9XG4gIH1cbn0sXG4gICAgX2FkZE5vblR3ZWVuaW5nUFQgPSBmdW5jdGlvbiBfYWRkTm9uVHdlZW5pbmdQVChwbHVnaW4sIHRhcmdldCwgcHJvcGVydHksIGJlZ2lubmluZywgZW5kLCBvbmx5U2V0QXRFbmQpIHtcbiAgdmFyIHB0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIHByb3BlcnR5LCAwLCAxLCBvbmx5U2V0QXRFbmQgPyBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZU9ubHlBdEVuZCA6IF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlKTtcbiAgcGx1Z2luLl9wdCA9IHB0O1xuICBwdC5iID0gYmVnaW5uaW5nO1xuICBwdC5lID0gZW5kO1xuXG4gIHBsdWdpbi5fcHJvcHMucHVzaChwcm9wZXJ0eSk7XG5cbiAgcmV0dXJuIHB0O1xufSxcbiAgICBfbm9uQ29udmVydGlibGVVbml0cyA9IHtcbiAgZGVnOiAxLFxuICByYWQ6IDEsXG4gIHR1cm46IDFcbn0sXG4gICAgX25vblN0YW5kYXJkTGF5b3V0cyA9IHtcbiAgZ3JpZDogMSxcbiAgZmxleDogMVxufSxcbiAgICAvL3Rha2VzIGEgc2luZ2xlIHZhbHVlIGxpa2UgMjBweCBhbmQgY29udmVydHMgaXQgdG8gdGhlIHVuaXQgc3BlY2lmaWVkLCBsaWtlIFwiJVwiLCByZXR1cm5pbmcgb25seSB0aGUgbnVtZXJpYyBhbW91bnQuXG5fY29udmVydFRvVW5pdCA9IGZ1bmN0aW9uIF9jb252ZXJ0VG9Vbml0KHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCB1bml0KSB7XG4gIHZhciBjdXJWYWx1ZSA9IHBhcnNlRmxvYXQodmFsdWUpIHx8IDAsXG4gICAgICBjdXJVbml0ID0gKHZhbHVlICsgXCJcIikudHJpbSgpLnN1YnN0cigoY3VyVmFsdWUgKyBcIlwiKS5sZW5ndGgpIHx8IFwicHhcIixcbiAgICAgIC8vIHNvbWUgYnJvd3NlcnMgbGVhdmUgZXh0cmEgd2hpdGVzcGFjZSBhdCB0aGUgYmVnaW5uaW5nIG9mIENTUyB2YXJpYWJsZXMsIGhlbmNlIHRoZSBuZWVkIHRvIHRyaW0oKVxuICBzdHlsZSA9IF90ZW1wRGl2LnN0eWxlLFxuICAgICAgaG9yaXpvbnRhbCA9IF9ob3Jpem9udGFsRXhwLnRlc3QocHJvcGVydHkpLFxuICAgICAgaXNSb290U1ZHID0gdGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJzdmdcIixcbiAgICAgIG1lYXN1cmVQcm9wZXJ0eSA9IChpc1Jvb3RTVkcgPyBcImNsaWVudFwiIDogXCJvZmZzZXRcIikgKyAoaG9yaXpvbnRhbCA/IFwiV2lkdGhcIiA6IFwiSGVpZ2h0XCIpLFxuICAgICAgYW1vdW50ID0gMTAwLFxuICAgICAgdG9QaXhlbHMgPSB1bml0ID09PSBcInB4XCIsXG4gICAgICB0b1BlcmNlbnQgPSB1bml0ID09PSBcIiVcIixcbiAgICAgIHB4LFxuICAgICAgcGFyZW50LFxuICAgICAgY2FjaGUsXG4gICAgICBpc1NWRztcblxuICBpZiAodW5pdCA9PT0gY3VyVW5pdCB8fCAhY3VyVmFsdWUgfHwgX25vbkNvbnZlcnRpYmxlVW5pdHNbdW5pdF0gfHwgX25vbkNvbnZlcnRpYmxlVW5pdHNbY3VyVW5pdF0pIHtcbiAgICByZXR1cm4gY3VyVmFsdWU7XG4gIH1cblxuICBjdXJVbml0ICE9PSBcInB4XCIgJiYgIXRvUGl4ZWxzICYmIChjdXJWYWx1ZSA9IF9jb252ZXJ0VG9Vbml0KHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCBcInB4XCIpKTtcbiAgaXNTVkcgPSB0YXJnZXQuZ2V0Q1RNICYmIF9pc1NWRyh0YXJnZXQpO1xuXG4gIGlmICgodG9QZXJjZW50IHx8IGN1clVuaXQgPT09IFwiJVwiKSAmJiAoX3RyYW5zZm9ybVByb3BzW3Byb3BlcnR5XSB8fCB+cHJvcGVydHkuaW5kZXhPZihcImFkaXVzXCIpKSkge1xuICAgIHB4ID0gaXNTVkcgPyB0YXJnZXQuZ2V0QkJveCgpW2hvcml6b250YWwgPyBcIndpZHRoXCIgOiBcImhlaWdodFwiXSA6IHRhcmdldFttZWFzdXJlUHJvcGVydHldO1xuICAgIHJldHVybiBfcm91bmQodG9QZXJjZW50ID8gY3VyVmFsdWUgLyBweCAqIGFtb3VudCA6IGN1clZhbHVlIC8gMTAwICogcHgpO1xuICB9XG5cbiAgc3R5bGVbaG9yaXpvbnRhbCA/IFwid2lkdGhcIiA6IFwiaGVpZ2h0XCJdID0gYW1vdW50ICsgKHRvUGl4ZWxzID8gY3VyVW5pdCA6IHVuaXQpO1xuICBwYXJlbnQgPSB+cHJvcGVydHkuaW5kZXhPZihcImFkaXVzXCIpIHx8IHVuaXQgPT09IFwiZW1cIiAmJiB0YXJnZXQuYXBwZW5kQ2hpbGQgJiYgIWlzUm9vdFNWRyA/IHRhcmdldCA6IHRhcmdldC5wYXJlbnROb2RlO1xuXG4gIGlmIChpc1NWRykge1xuICAgIHBhcmVudCA9ICh0YXJnZXQub3duZXJTVkdFbGVtZW50IHx8IHt9KS5wYXJlbnROb2RlO1xuICB9XG5cbiAgaWYgKCFwYXJlbnQgfHwgcGFyZW50ID09PSBfZG9jIHx8ICFwYXJlbnQuYXBwZW5kQ2hpbGQpIHtcbiAgICBwYXJlbnQgPSBfZG9jLmJvZHk7XG4gIH1cblxuICBjYWNoZSA9IHBhcmVudC5fZ3NhcDtcblxuICBpZiAoY2FjaGUgJiYgdG9QZXJjZW50ICYmIGNhY2hlLndpZHRoICYmIGhvcml6b250YWwgJiYgY2FjaGUudGltZSA9PT0gX3RpY2tlci50aW1lICYmICFjYWNoZS51bmNhY2hlKSB7XG4gICAgcmV0dXJuIF9yb3VuZChjdXJWYWx1ZSAvIGNhY2hlLndpZHRoICogYW1vdW50KTtcbiAgfSBlbHNlIHtcbiAgICAodG9QZXJjZW50IHx8IGN1clVuaXQgPT09IFwiJVwiKSAmJiAhX25vblN0YW5kYXJkTGF5b3V0c1tfZ2V0Q29tcHV0ZWRQcm9wZXJ0eShwYXJlbnQsIFwiZGlzcGxheVwiKV0gJiYgKHN0eWxlLnBvc2l0aW9uID0gX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBcInBvc2l0aW9uXCIpKTtcbiAgICBwYXJlbnQgPT09IHRhcmdldCAmJiAoc3R5bGUucG9zaXRpb24gPSBcInN0YXRpY1wiKTsgLy8gbGlrZSBmb3IgYm9yZGVyUmFkaXVzLCBpZiBpdCdzIGEgJSB3ZSBtdXN0IGhhdmUgaXQgcmVsYXRpdmUgdG8gdGhlIHRhcmdldCBpdHNlbGYgYnV0IHRoYXQgbWF5IG5vdCBoYXZlIHBvc2l0aW9uOiByZWxhdGl2ZSBvciBwb3NpdGlvbjogYWJzb2x1dGUgaW4gd2hpY2ggY2FzZSBpdCdkIGdvIHVwIHRoZSBjaGFpbiB1bnRpbCBpdCBmaW5kcyBpdHMgb2Zmc2V0UGFyZW50IChiYWQpLiBwb3NpdGlvbjogc3RhdGljIHByb3RlY3RzIGFnYWluc3QgdGhhdC5cblxuICAgIHBhcmVudC5hcHBlbmRDaGlsZChfdGVtcERpdik7XG4gICAgcHggPSBfdGVtcERpdlttZWFzdXJlUHJvcGVydHldO1xuICAgIHBhcmVudC5yZW1vdmVDaGlsZChfdGVtcERpdik7XG4gICAgc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cbiAgICBpZiAoaG9yaXpvbnRhbCAmJiB0b1BlcmNlbnQpIHtcbiAgICAgIGNhY2hlID0gX2dldENhY2hlKHBhcmVudCk7XG4gICAgICBjYWNoZS50aW1lID0gX3RpY2tlci50aW1lO1xuICAgICAgY2FjaGUud2lkdGggPSBwYXJlbnRbbWVhc3VyZVByb3BlcnR5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gX3JvdW5kKHRvUGl4ZWxzID8gcHggKiBjdXJWYWx1ZSAvIGFtb3VudCA6IHB4ICYmIGN1clZhbHVlID8gYW1vdW50IC8gcHggKiBjdXJWYWx1ZSA6IDApO1xufSxcbiAgICBfZ2V0ID0gZnVuY3Rpb24gX2dldCh0YXJnZXQsIHByb3BlcnR5LCB1bml0LCB1bmNhY2hlKSB7XG4gIHZhciB2YWx1ZTtcbiAgX3BsdWdpbkluaXR0ZWQgfHwgX2luaXRDb3JlKCk7XG5cbiAgaWYgKHByb3BlcnR5IGluIF9wcm9wZXJ0eUFsaWFzZXMgJiYgcHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICBwcm9wZXJ0eSA9IF9wcm9wZXJ0eUFsaWFzZXNbcHJvcGVydHldO1xuXG4gICAgaWYgKH5wcm9wZXJ0eS5pbmRleE9mKFwiLFwiKSkge1xuICAgICAgcHJvcGVydHkgPSBwcm9wZXJ0eS5zcGxpdChcIixcIilbMF07XG4gICAgfVxuICB9XG5cbiAgaWYgKF90cmFuc2Zvcm1Qcm9wc1twcm9wZXJ0eV0gJiYgcHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICB2YWx1ZSA9IF9wYXJzZVRyYW5zZm9ybSh0YXJnZXQsIHVuY2FjaGUpO1xuICAgIHZhbHVlID0gcHJvcGVydHkgIT09IFwidHJhbnNmb3JtT3JpZ2luXCIgPyB2YWx1ZVtwcm9wZXJ0eV0gOiB2YWx1ZS5zdmcgPyB2YWx1ZS5vcmlnaW4gOiBfZmlyc3RUd29Pbmx5KF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybU9yaWdpblByb3ApKSArIFwiIFwiICsgdmFsdWUuek9yaWdpbiArIFwicHhcIjtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IHRhcmdldC5zdHlsZVtwcm9wZXJ0eV07XG5cbiAgICBpZiAoIXZhbHVlIHx8IHZhbHVlID09PSBcImF1dG9cIiB8fCB1bmNhY2hlIHx8IH4odmFsdWUgKyBcIlwiKS5pbmRleE9mKFwiY2FsYyhcIikpIHtcbiAgICAgIHZhbHVlID0gX3NwZWNpYWxQcm9wc1twcm9wZXJ0eV0gJiYgX3NwZWNpYWxQcm9wc1twcm9wZXJ0eV0odGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCkgfHwgX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSkgfHwgX2dldFByb3BlcnR5KHRhcmdldCwgcHJvcGVydHkpIHx8IChwcm9wZXJ0eSA9PT0gXCJvcGFjaXR5XCIgPyAxIDogMCk7IC8vIG5vdGU6IHNvbWUgYnJvd3NlcnMsIGxpa2UgRmlyZWZveCwgZG9uJ3QgcmVwb3J0IGJvcmRlclJhZGl1cyBjb3JyZWN0bHkhIEluc3RlYWQsIGl0IG9ubHkgcmVwb3J0cyBldmVyeSBjb3JuZXIgbGlrZSAgYm9yZGVyVG9wTGVmdFJhZGl1c1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bml0ICYmICF+KHZhbHVlICsgXCJcIikudHJpbSgpLmluZGV4T2YoXCIgXCIpID8gX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIHVuaXQpICsgdW5pdCA6IHZhbHVlO1xufSxcbiAgICBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nID0gZnVuY3Rpb24gX3R3ZWVuQ29tcGxleENTU1N0cmluZyh0YXJnZXQsIHByb3AsIHN0YXJ0LCBlbmQpIHtcbiAgLy8gbm90ZTogd2UgY2FsbCBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nLmNhbGwocGx1Z2luSW5zdGFuY2UuLi4pIHRvIGVuc3VyZSB0aGF0IGl0J3Mgc2NvcGVkIHByb3Blcmx5LiBXZSBtYXkgY2FsbCBpdCBmcm9tIHdpdGhpbiBhIHBsdWdpbiB0b28sIHRodXMgXCJ0aGlzXCIgd291bGQgcmVmZXIgdG8gdGhlIHBsdWdpbi5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA9PT0gXCJub25lXCIpIHtcbiAgICAvLyBzb21lIGJyb3dzZXJzIGxpa2UgU2FmYXJpIGFjdHVhbGx5IFBSRUZFUiB0aGUgcHJlZml4ZWQgcHJvcGVydHkgYW5kIG1pcy1yZXBvcnQgdGhlIHVucHJlZml4ZWQgdmFsdWUgbGlrZSBjbGlwUGF0aCAoQlVHKS4gSW4gb3RoZXIgd29yZHMsIGV2ZW4gdGhvdWdoIGNsaXBQYXRoIGV4aXN0cyBpbiB0aGUgc3R5bGUgKFwiY2xpcFBhdGhcIiBpbiB0YXJnZXQuc3R5bGUpIGFuZCBpdCdzIHNldCBpbiB0aGUgQ1NTIHByb3Blcmx5IChhbG9uZyB3aXRoIC13ZWJraXQtY2xpcC1wYXRoKSwgU2FmYXJpIHJlcG9ydHMgY2xpcFBhdGggYXMgXCJub25lXCIgd2hlcmVhcyBXZWJraXRDbGlwUGF0aCByZXBvcnRzIGFjY3VyYXRlbHkgbGlrZSBcImVsbGlwc2UoMTAwJSAwJSBhdCA1MCUgMCUpXCIsIHNvIGluIHRoaXMgY2FzZSB3ZSBtdXN0IFNXSVRDSCB0byB1c2luZyB0aGUgcHJlZml4ZWQgcHJvcGVydHkgaW5zdGVhZC4gU2VlIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9mb3J1bXMvdG9waWMvMTgzMTAtY2xpcHBhdGgtZG9lc250LXdvcmstb24taW9zL1xuICAgIHZhciBwID0gX2NoZWNrUHJvcFByZWZpeChwcm9wLCB0YXJnZXQsIDEpLFxuICAgICAgICBzID0gcCAmJiBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIHAsIDEpO1xuXG4gICAgaWYgKHMgJiYgcyAhPT0gc3RhcnQpIHtcbiAgICAgIHByb3AgPSBwO1xuICAgICAgc3RhcnQgPSBzO1xuICAgIH0gZWxzZSBpZiAocHJvcCA9PT0gXCJib3JkZXJDb2xvclwiKSB7XG4gICAgICBzdGFydCA9IF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgXCJib3JkZXJUb3BDb2xvclwiKTsgLy8gRmlyZWZveCBidWc6IGFsd2F5cyByZXBvcnRzIFwiYm9yZGVyQ29sb3JcIiBhcyBcIlwiLCBzbyB3ZSBtdXN0IGZhbGwgYmFjayB0byBib3JkZXJUb3BDb2xvci4gU2VlIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9mb3J1bXMvdG9waWMvMjQ1ODMtaG93LXRvLXJldHVybi1jb2xvcnMtdGhhdC1pLWhhZC1hZnRlci1yZXZlcnNlL1xuICAgIH1cbiAgfVxuXG4gIHZhciBwdCA9IG5ldyBQcm9wVHdlZW4odGhpcy5fcHQsIHRhcmdldC5zdHlsZSwgcHJvcCwgMCwgMSwgX3JlbmRlckNvbXBsZXhTdHJpbmcpLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgbWF0Y2hJbmRleCA9IDAsXG4gICAgICBhLFxuICAgICAgcmVzdWx0LFxuICAgICAgc3RhcnRWYWx1ZXMsXG4gICAgICBzdGFydE51bSxcbiAgICAgIGNvbG9yLFxuICAgICAgc3RhcnRWYWx1ZSxcbiAgICAgIGVuZFZhbHVlLFxuICAgICAgZW5kTnVtLFxuICAgICAgY2h1bmssXG4gICAgICBlbmRVbml0LFxuICAgICAgc3RhcnRVbml0LFxuICAgICAgZW5kVmFsdWVzO1xuICBwdC5iID0gc3RhcnQ7XG4gIHB0LmUgPSBlbmQ7XG4gIHN0YXJ0ICs9IFwiXCI7IC8vIGVuc3VyZSB2YWx1ZXMgYXJlIHN0cmluZ3NcblxuICBlbmQgKz0gXCJcIjtcblxuICBpZiAoZW5kID09PSBcImF1dG9cIikge1xuICAgIHRhcmdldC5zdHlsZVtwcm9wXSA9IGVuZDtcbiAgICBlbmQgPSBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIHByb3ApIHx8IGVuZDtcbiAgICB0YXJnZXQuc3R5bGVbcHJvcF0gPSBzdGFydDtcbiAgfVxuXG4gIGEgPSBbc3RhcnQsIGVuZF07XG5cbiAgX2NvbG9yU3RyaW5nRmlsdGVyKGEpOyAvLyBwYXNzIGFuIGFycmF5IHdpdGggdGhlIHN0YXJ0aW5nIGFuZCBlbmRpbmcgdmFsdWVzIGFuZCBsZXQgdGhlIGZpbHRlciBkbyB3aGF0ZXZlciBpdCBuZWVkcyB0byB0aGUgdmFsdWVzLiBJZiBjb2xvcnMgYXJlIGZvdW5kLCBpdCByZXR1cm5zIHRydWUgYW5kIHRoZW4gd2UgbXVzdCBtYXRjaCB3aGVyZSB0aGUgY29sb3Igc2hvd3MgdXAgb3JkZXItd2lzZSBiZWNhdXNlIGZvciB0aGluZ3MgbGlrZSBib3hTaGFkb3csIHNvbWV0aW1lcyB0aGUgYnJvd3NlciBwcm92aWRlcyB0aGUgY29tcHV0ZWQgdmFsdWVzIHdpdGggdGhlIGNvbG9yIEZJUlNULCBidXQgdGhlIHVzZXIgcHJvdmlkZXMgaXQgd2l0aCB0aGUgY29sb3IgTEFTVCwgc28gZmxpcCB0aGVtIGlmIG5lY2Vzc2FyeS4gU2FtZSBmb3IgZHJvcC1zaGFkb3coKS5cblxuXG4gIHN0YXJ0ID0gYVswXTtcbiAgZW5kID0gYVsxXTtcbiAgc3RhcnRWYWx1ZXMgPSBzdGFydC5tYXRjaChfbnVtV2l0aFVuaXRFeHApIHx8IFtdO1xuICBlbmRWYWx1ZXMgPSBlbmQubWF0Y2goX251bVdpdGhVbml0RXhwKSB8fCBbXTtcblxuICBpZiAoZW5kVmFsdWVzLmxlbmd0aCkge1xuICAgIHdoaWxlIChyZXN1bHQgPSBfbnVtV2l0aFVuaXRFeHAuZXhlYyhlbmQpKSB7XG4gICAgICBlbmRWYWx1ZSA9IHJlc3VsdFswXTtcbiAgICAgIGNodW5rID0gZW5kLnN1YnN0cmluZyhpbmRleCwgcmVzdWx0LmluZGV4KTtcblxuICAgICAgaWYgKGNvbG9yKSB7XG4gICAgICAgIGNvbG9yID0gKGNvbG9yICsgMSkgJSA1O1xuICAgICAgfSBlbHNlIGlmIChjaHVuay5zdWJzdHIoLTUpID09PSBcInJnYmEoXCIgfHwgY2h1bmsuc3Vic3RyKC01KSA9PT0gXCJoc2xhKFwiKSB7XG4gICAgICAgIGNvbG9yID0gMTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVuZFZhbHVlICE9PSAoc3RhcnRWYWx1ZSA9IHN0YXJ0VmFsdWVzW21hdGNoSW5kZXgrK10gfHwgXCJcIikpIHtcbiAgICAgICAgc3RhcnROdW0gPSBwYXJzZUZsb2F0KHN0YXJ0VmFsdWUpIHx8IDA7XG4gICAgICAgIHN0YXJ0VW5pdCA9IHN0YXJ0VmFsdWUuc3Vic3RyKChzdGFydE51bSArIFwiXCIpLmxlbmd0aCk7XG4gICAgICAgIGVuZFZhbHVlLmNoYXJBdCgxKSA9PT0gXCI9XCIgJiYgKGVuZFZhbHVlID0gX3BhcnNlUmVsYXRpdmUoc3RhcnROdW0sIGVuZFZhbHVlKSArIHN0YXJ0VW5pdCk7XG4gICAgICAgIGVuZE51bSA9IHBhcnNlRmxvYXQoZW5kVmFsdWUpO1xuICAgICAgICBlbmRVbml0ID0gZW5kVmFsdWUuc3Vic3RyKChlbmROdW0gKyBcIlwiKS5sZW5ndGgpO1xuICAgICAgICBpbmRleCA9IF9udW1XaXRoVW5pdEV4cC5sYXN0SW5kZXggLSBlbmRVbml0Lmxlbmd0aDtcblxuICAgICAgICBpZiAoIWVuZFVuaXQpIHtcbiAgICAgICAgICAvL2lmIHNvbWV0aGluZyBsaWtlIFwicGVyc3BlY3RpdmU6MzAwXCIgaXMgcGFzc2VkIGluIGFuZCB3ZSBtdXN0IGFkZCBhIHVuaXQgdG8gdGhlIGVuZFxuICAgICAgICAgIGVuZFVuaXQgPSBlbmRVbml0IHx8IF9jb25maWcudW5pdHNbcHJvcF0gfHwgc3RhcnRVbml0O1xuXG4gICAgICAgICAgaWYgKGluZGV4ID09PSBlbmQubGVuZ3RoKSB7XG4gICAgICAgICAgICBlbmQgKz0gZW5kVW5pdDtcbiAgICAgICAgICAgIHB0LmUgKz0gZW5kVW5pdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhcnRVbml0ICE9PSBlbmRVbml0KSB7XG4gICAgICAgICAgc3RhcnROdW0gPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIHByb3AsIHN0YXJ0VmFsdWUsIGVuZFVuaXQpIHx8IDA7XG4gICAgICAgIH0gLy8gdGhlc2UgbmVzdGVkIFByb3BUd2VlbnMgYXJlIGhhbmRsZWQgaW4gYSBzcGVjaWFsIHdheSAtIHdlJ2xsIG5ldmVyIGFjdHVhbGx5IGNhbGwgYSByZW5kZXIgb3Igc2V0dGVyIG1ldGhvZCBvbiB0aGVtLiBXZSdsbCBqdXN0IGxvb3AgdGhyb3VnaCB0aGVtIGluIHRoZSBwYXJlbnQgY29tcGxleCBzdHJpbmcgUHJvcFR3ZWVuJ3MgcmVuZGVyIG1ldGhvZC5cblxuXG4gICAgICAgIHB0Ll9wdCA9IHtcbiAgICAgICAgICBfbmV4dDogcHQuX3B0LFxuICAgICAgICAgIHA6IGNodW5rIHx8IG1hdGNoSW5kZXggPT09IDEgPyBjaHVuayA6IFwiLFwiLFxuICAgICAgICAgIC8vbm90ZTogU1ZHIHNwZWMgYWxsb3dzIG9taXNzaW9uIG9mIGNvbW1hL3NwYWNlIHdoZW4gYSBuZWdhdGl2ZSBzaWduIGlzIHdlZGdlZCBiZXR3ZWVuIHR3byBudW1iZXJzLCBsaWtlIDIuNS01LjMgaW5zdGVhZCBvZiAyLjUsLTUuMyBidXQgd2hlbiB0d2VlbmluZywgdGhlIG5lZ2F0aXZlIHZhbHVlIG1heSBzd2l0Y2ggdG8gcG9zaXRpdmUsIHNvIHdlIGluc2VydCB0aGUgY29tbWEganVzdCBpbiBjYXNlLlxuICAgICAgICAgIHM6IHN0YXJ0TnVtLFxuICAgICAgICAgIGM6IGVuZE51bSAtIHN0YXJ0TnVtLFxuICAgICAgICAgIG06IGNvbG9yICYmIGNvbG9yIDwgNCB8fCBwcm9wID09PSBcInpJbmRleFwiID8gTWF0aC5yb3VuZCA6IDBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwdC5jID0gaW5kZXggPCBlbmQubGVuZ3RoID8gZW5kLnN1YnN0cmluZyhpbmRleCwgZW5kLmxlbmd0aCkgOiBcIlwiOyAvL3dlIHVzZSB0aGUgXCJjXCIgb2YgdGhlIFByb3BUd2VlbiB0byBzdG9yZSB0aGUgZmluYWwgcGFydCBvZiB0aGUgc3RyaW5nIChhZnRlciB0aGUgbGFzdCBudW1iZXIpXG4gIH0gZWxzZSB7XG4gICAgcHQuciA9IHByb3AgPT09IFwiZGlzcGxheVwiICYmIGVuZCA9PT0gXCJub25lXCIgPyBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZU9ubHlBdEVuZCA6IF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlO1xuICB9XG5cbiAgX3JlbEV4cC50ZXN0KGVuZCkgJiYgKHB0LmUgPSAwKTsgLy9pZiB0aGUgZW5kIHN0cmluZyBjb250YWlucyByZWxhdGl2ZSB2YWx1ZXMgb3IgZHluYW1pYyByYW5kb20oLi4uKSB2YWx1ZXMsIGRlbGV0ZSB0aGUgZW5kIGl0IHNvIHRoYXQgb24gdGhlIGZpbmFsIHJlbmRlciB3ZSBkb24ndCBhY3R1YWxseSBzZXQgaXQgdG8gdGhlIHN0cmluZyB3aXRoICs9IG9yIC09IGNoYXJhY3RlcnMgKGZvcmNlcyBpdCB0byB1c2UgdGhlIGNhbGN1bGF0ZWQgdmFsdWUpLlxuXG4gIHRoaXMuX3B0ID0gcHQ7IC8vc3RhcnQgdGhlIGxpbmtlZCBsaXN0IHdpdGggdGhpcyBuZXcgUHJvcFR3ZWVuLiBSZW1lbWJlciwgd2UgY2FsbCBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nLmNhbGwocGx1Z2luSW5zdGFuY2UuLi4pIHRvIGVuc3VyZSB0aGF0IGl0J3Mgc2NvcGVkIHByb3Blcmx5LiBXZSBtYXkgY2FsbCBpdCBmcm9tIHdpdGhpbiBhbm90aGVyIHBsdWdpbiB0b28sIHRodXMgXCJ0aGlzXCIgd291bGQgcmVmZXIgdG8gdGhlIHBsdWdpbi5cblxuICByZXR1cm4gcHQ7XG59LFxuICAgIF9rZXl3b3JkVG9QZXJjZW50ID0ge1xuICB0b3A6IFwiMCVcIixcbiAgYm90dG9tOiBcIjEwMCVcIixcbiAgbGVmdDogXCIwJVwiLFxuICByaWdodDogXCIxMDAlXCIsXG4gIGNlbnRlcjogXCI1MCVcIlxufSxcbiAgICBfY29udmVydEtleXdvcmRzVG9QZXJjZW50YWdlcyA9IGZ1bmN0aW9uIF9jb252ZXJ0S2V5d29yZHNUb1BlcmNlbnRhZ2VzKHZhbHVlKSB7XG4gIHZhciBzcGxpdCA9IHZhbHVlLnNwbGl0KFwiIFwiKSxcbiAgICAgIHggPSBzcGxpdFswXSxcbiAgICAgIHkgPSBzcGxpdFsxXSB8fCBcIjUwJVwiO1xuXG4gIGlmICh4ID09PSBcInRvcFwiIHx8IHggPT09IFwiYm90dG9tXCIgfHwgeSA9PT0gXCJsZWZ0XCIgfHwgeSA9PT0gXCJyaWdodFwiKSB7XG4gICAgLy90aGUgdXNlciBwcm92aWRlZCB0aGVtIGluIHRoZSB3cm9uZyBvcmRlciwgc28gZmxpcCB0aGVtXG4gICAgdmFsdWUgPSB4O1xuICAgIHggPSB5O1xuICAgIHkgPSB2YWx1ZTtcbiAgfVxuXG4gIHNwbGl0WzBdID0gX2tleXdvcmRUb1BlcmNlbnRbeF0gfHwgeDtcbiAgc3BsaXRbMV0gPSBfa2V5d29yZFRvUGVyY2VudFt5XSB8fCB5O1xuICByZXR1cm4gc3BsaXQuam9pbihcIiBcIik7XG59LFxuICAgIF9yZW5kZXJDbGVhclByb3BzID0gZnVuY3Rpb24gX3JlbmRlckNsZWFyUHJvcHMocmF0aW8sIGRhdGEpIHtcbiAgaWYgKGRhdGEudHdlZW4gJiYgZGF0YS50d2Vlbi5fdGltZSA9PT0gZGF0YS50d2Vlbi5fZHVyKSB7XG4gICAgdmFyIHRhcmdldCA9IGRhdGEudCxcbiAgICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICAgIHByb3BzID0gZGF0YS51LFxuICAgICAgICBjYWNoZSA9IHRhcmdldC5fZ3NhcCxcbiAgICAgICAgcHJvcCxcbiAgICAgICAgY2xlYXJUcmFuc2Zvcm1zLFxuICAgICAgICBpO1xuXG4gICAgaWYgKHByb3BzID09PSBcImFsbFwiIHx8IHByb3BzID09PSB0cnVlKSB7XG4gICAgICBzdHlsZS5jc3NUZXh0ID0gXCJcIjtcbiAgICAgIGNsZWFyVHJhbnNmb3JtcyA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3BzID0gcHJvcHMuc3BsaXQoXCIsXCIpO1xuICAgICAgaSA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKC0taSA+IC0xKSB7XG4gICAgICAgIHByb3AgPSBwcm9wc1tpXTtcblxuICAgICAgICBpZiAoX3RyYW5zZm9ybVByb3BzW3Byb3BdKSB7XG4gICAgICAgICAgY2xlYXJUcmFuc2Zvcm1zID0gMTtcbiAgICAgICAgICBwcm9wID0gcHJvcCA9PT0gXCJ0cmFuc2Zvcm1PcmlnaW5cIiA/IF90cmFuc2Zvcm1PcmlnaW5Qcm9wIDogX3RyYW5zZm9ybVByb3A7XG4gICAgICAgIH1cblxuICAgICAgICBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBwcm9wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYXJUcmFuc2Zvcm1zKSB7XG4gICAgICBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtUHJvcCk7XG5cbiAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICBjYWNoZS5zdmcgJiYgdGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKTtcblxuICAgICAgICBfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCAxKTsgLy8gZm9yY2UgYWxsIHRoZSBjYWNoZWQgdmFsdWVzIGJhY2sgdG8gXCJub3JtYWxcIi9pZGVudGl0eSwgb3RoZXJ3aXNlIGlmIHRoZXJlJ3MgYW5vdGhlciB0d2VlbiB0aGF0J3MgYWxyZWFkeSBzZXQgdG8gcmVuZGVyIHRyYW5zZm9ybXMgb24gdGhpcyBlbGVtZW50LCBpdCBjb3VsZCBkaXNwbGF5IHRoZSB3cm9uZyB2YWx1ZXMuXG5cblxuICAgICAgICBjYWNoZS51bmNhY2hlID0gMTtcblxuICAgICAgICBfcmVtb3ZlSW5kZXBlbmRlbnRUcmFuc2Zvcm1zKHN0eWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0sXG4gICAgLy8gbm90ZTogc3BlY2lhbFByb3BzIHNob3VsZCByZXR1cm4gMSBpZiAoYW5kIG9ubHkgaWYpIHRoZXkgaGF2ZSBhIG5vbi16ZXJvIHByaW9yaXR5LiBJdCBpbmRpY2F0ZXMgd2UgbmVlZCB0byBzb3J0IHRoZSBsaW5rZWQgbGlzdC5cbl9zcGVjaWFsUHJvcHMgPSB7XG4gIGNsZWFyUHJvcHM6IGZ1bmN0aW9uIGNsZWFyUHJvcHMocGx1Z2luLCB0YXJnZXQsIHByb3BlcnR5LCBlbmRWYWx1ZSwgdHdlZW4pIHtcbiAgICBpZiAodHdlZW4uZGF0YSAhPT0gXCJpc0Zyb21TdGFydFwiKSB7XG4gICAgICB2YXIgcHQgPSBwbHVnaW4uX3B0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIHByb3BlcnR5LCAwLCAwLCBfcmVuZGVyQ2xlYXJQcm9wcyk7XG4gICAgICBwdC51ID0gZW5kVmFsdWU7XG4gICAgICBwdC5wciA9IC0xMDtcbiAgICAgIHB0LnR3ZWVuID0gdHdlZW47XG5cbiAgICAgIHBsdWdpbi5fcHJvcHMucHVzaChwcm9wZXJ0eSk7XG5cbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuICAvKiBjbGFzc05hbWUgZmVhdHVyZSAoYWJvdXQgMC40a2IgZ3ppcHBlZCkuXG4gICwgY2xhc3NOYW1lKHBsdWdpbiwgdGFyZ2V0LCBwcm9wZXJ0eSwgZW5kVmFsdWUsIHR3ZWVuKSB7XG4gIFx0bGV0IF9yZW5kZXJDbGFzc05hbWUgPSAocmF0aW8sIGRhdGEpID0+IHtcbiAgXHRcdFx0ZGF0YS5jc3MucmVuZGVyKHJhdGlvLCBkYXRhLmNzcyk7XG4gIFx0XHRcdGlmICghcmF0aW8gfHwgcmF0aW8gPT09IDEpIHtcbiAgXHRcdFx0XHRsZXQgaW5saW5lID0gZGF0YS5ybXYsXG4gIFx0XHRcdFx0XHR0YXJnZXQgPSBkYXRhLnQsXG4gIFx0XHRcdFx0XHRwO1xuICBcdFx0XHRcdHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCByYXRpbyA/IGRhdGEuZSA6IGRhdGEuYik7XG4gIFx0XHRcdFx0Zm9yIChwIGluIGlubGluZSkge1xuICBcdFx0XHRcdFx0X3JlbW92ZVByb3BlcnR5KHRhcmdldCwgcCk7XG4gIFx0XHRcdFx0fVxuICBcdFx0XHR9XG4gIFx0XHR9LFxuICBcdFx0X2dldEFsbFN0eWxlcyA9ICh0YXJnZXQpID0+IHtcbiAgXHRcdFx0bGV0IHN0eWxlcyA9IHt9LFxuICBcdFx0XHRcdGNvbXB1dGVkID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpLFxuICBcdFx0XHRcdHA7XG4gIFx0XHRcdGZvciAocCBpbiBjb21wdXRlZCkge1xuICBcdFx0XHRcdGlmIChpc05hTihwKSAmJiBwICE9PSBcImNzc1RleHRcIiAmJiBwICE9PSBcImxlbmd0aFwiKSB7XG4gIFx0XHRcdFx0XHRzdHlsZXNbcF0gPSBjb21wdXRlZFtwXTtcbiAgXHRcdFx0XHR9XG4gIFx0XHRcdH1cbiAgXHRcdFx0X3NldERlZmF1bHRzKHN0eWxlcywgX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgMSkpO1xuICBcdFx0XHRyZXR1cm4gc3R5bGVzO1xuICBcdFx0fSxcbiAgXHRcdHN0YXJ0Q2xhc3NMaXN0ID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShcImNsYXNzXCIpLFxuICBcdFx0c3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gIFx0XHRjc3NUZXh0ID0gc3R5bGUuY3NzVGV4dCxcbiAgXHRcdGNhY2hlID0gdGFyZ2V0Ll9nc2FwLFxuICBcdFx0Y2xhc3NQVCA9IGNhY2hlLmNsYXNzUFQsXG4gIFx0XHRpbmxpbmVUb1JlbW92ZUF0RW5kID0ge30sXG4gIFx0XHRkYXRhID0ge3Q6dGFyZ2V0LCBwbHVnaW46cGx1Z2luLCBybXY6aW5saW5lVG9SZW1vdmVBdEVuZCwgYjpzdGFydENsYXNzTGlzdCwgZTooZW5kVmFsdWUuY2hhckF0KDEpICE9PSBcIj1cIikgPyBlbmRWYWx1ZSA6IHN0YXJ0Q2xhc3NMaXN0LnJlcGxhY2UobmV3IFJlZ0V4cChcIig/OlxcXFxzfF4pXCIgKyBlbmRWYWx1ZS5zdWJzdHIoMikgKyBcIig/IVtcXFxcdy1dKVwiKSwgXCJcIikgKyAoKGVuZFZhbHVlLmNoYXJBdCgwKSA9PT0gXCIrXCIpID8gXCIgXCIgKyBlbmRWYWx1ZS5zdWJzdHIoMikgOiBcIlwiKX0sXG4gIFx0XHRjaGFuZ2luZ1ZhcnMgPSB7fSxcbiAgXHRcdHN0YXJ0VmFycyA9IF9nZXRBbGxTdHlsZXModGFyZ2V0KSxcbiAgXHRcdHRyYW5zZm9ybVJlbGF0ZWQgPSAvKHRyYW5zZm9ybXxwZXJzcGVjdGl2ZSkvaSxcbiAgXHRcdGVuZFZhcnMsIHA7XG4gIFx0aWYgKGNsYXNzUFQpIHtcbiAgXHRcdGNsYXNzUFQucigxLCBjbGFzc1BULmQpO1xuICBcdFx0X3JlbW92ZUxpbmtlZExpc3RJdGVtKGNsYXNzUFQuZC5wbHVnaW4sIGNsYXNzUFQsIFwiX3B0XCIpO1xuICBcdH1cbiAgXHR0YXJnZXQuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgZGF0YS5lKTtcbiAgXHRlbmRWYXJzID0gX2dldEFsbFN0eWxlcyh0YXJnZXQsIHRydWUpO1xuICBcdHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBzdGFydENsYXNzTGlzdCk7XG4gIFx0Zm9yIChwIGluIGVuZFZhcnMpIHtcbiAgXHRcdGlmIChlbmRWYXJzW3BdICE9PSBzdGFydFZhcnNbcF0gJiYgIXRyYW5zZm9ybVJlbGF0ZWQudGVzdChwKSkge1xuICBcdFx0XHRjaGFuZ2luZ1ZhcnNbcF0gPSBlbmRWYXJzW3BdO1xuICBcdFx0XHRpZiAoIXN0eWxlW3BdICYmIHN0eWxlW3BdICE9PSBcIjBcIikge1xuICBcdFx0XHRcdGlubGluZVRvUmVtb3ZlQXRFbmRbcF0gPSAxO1xuICBcdFx0XHR9XG4gIFx0XHR9XG4gIFx0fVxuICBcdGNhY2hlLmNsYXNzUFQgPSBwbHVnaW4uX3B0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIFwiY2xhc3NOYW1lXCIsIDAsIDAsIF9yZW5kZXJDbGFzc05hbWUsIGRhdGEsIDAsIC0xMSk7XG4gIFx0aWYgKHN0eWxlLmNzc1RleHQgIT09IGNzc1RleHQpIHsgLy9vbmx5IGFwcGx5IGlmIHRoaW5ncyBjaGFuZ2UuIE90aGVyd2lzZSwgaW4gY2FzZXMgbGlrZSBhIGJhY2tncm91bmQtaW1hZ2UgdGhhdCdzIHB1bGxlZCBkeW5hbWljYWxseSwgaXQgY291bGQgY2F1c2UgYSByZWZyZXNoLiBTZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2ZvcnVtcy90b3BpYy8yMDM2OC1wb3NzaWJsZS1nc2FwLWJ1Zy1zd2l0Y2hpbmctY2xhc3NuYW1lcy1pbi1jaHJvbWUvLlxuICBcdFx0c3R5bGUuY3NzVGV4dCA9IGNzc1RleHQ7IC8vd2UgcmVjb3JkZWQgY3NzVGV4dCBiZWZvcmUgd2Ugc3dhcHBlZCBjbGFzc2VzIGFuZCByYW4gX2dldEFsbFN0eWxlcygpIGJlY2F1c2UgaW4gY2FzZXMgd2hlbiBhIGNsYXNzTmFtZSB0d2VlbiBpcyBvdmVyd3JpdHRlbiwgd2UgcmVtb3ZlIGFsbCB0aGUgcmVsYXRlZCB0d2VlbmluZyBwcm9wZXJ0aWVzIGZyb20gdGhhdCBjbGFzcyBjaGFuZ2UgKG90aGVyd2lzZSBjbGFzcy1zcGVjaWZpYyBzdHVmZiBjYW4ndCBvdmVycmlkZSBwcm9wZXJ0aWVzIHdlJ3ZlIGRpcmVjdGx5IHNldCBvbiB0aGUgdGFyZ2V0J3Mgc3R5bGUgb2JqZWN0IGR1ZSB0byBzcGVjaWZpY2l0eSkuXG4gIFx0fVxuICBcdF9wYXJzZVRyYW5zZm9ybSh0YXJnZXQsIHRydWUpOyAvL3RvIGNsZWFyIHRoZSBjYWNoaW5nIG9mIHRyYW5zZm9ybXNcbiAgXHRkYXRhLmNzcyA9IG5ldyBnc2FwLnBsdWdpbnMuY3NzKCk7XG4gIFx0ZGF0YS5jc3MuaW5pdCh0YXJnZXQsIGNoYW5naW5nVmFycywgdHdlZW4pO1xuICBcdHBsdWdpbi5fcHJvcHMucHVzaCguLi5kYXRhLmNzcy5fcHJvcHMpO1xuICBcdHJldHVybiAxO1xuICB9XG4gICovXG5cbn0sXG5cbi8qXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogVFJBTlNGT1JNU1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuX2lkZW50aXR5MkRNYXRyaXggPSBbMSwgMCwgMCwgMSwgMCwgMF0sXG4gICAgX3JvdGF0aW9uYWxQcm9wZXJ0aWVzID0ge30sXG4gICAgX2lzTnVsbFRyYW5zZm9ybSA9IGZ1bmN0aW9uIF9pc051bGxUcmFuc2Zvcm0odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBcIm1hdHJpeCgxLCAwLCAwLCAxLCAwLCAwKVwiIHx8IHZhbHVlID09PSBcIm5vbmVcIiB8fCAhdmFsdWU7XG59LFxuICAgIF9nZXRDb21wdXRlZFRyYW5zZm9ybU1hdHJpeEFzQXJyYXkgPSBmdW5jdGlvbiBfZ2V0Q29tcHV0ZWRUcmFuc2Zvcm1NYXRyaXhBc0FycmF5KHRhcmdldCkge1xuICB2YXIgbWF0cml4U3RyaW5nID0gX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtUHJvcCk7XG5cbiAgcmV0dXJuIF9pc051bGxUcmFuc2Zvcm0obWF0cml4U3RyaW5nKSA/IF9pZGVudGl0eTJETWF0cml4IDogbWF0cml4U3RyaW5nLnN1YnN0cig3KS5tYXRjaChfbnVtRXhwKS5tYXAoX3JvdW5kKTtcbn0sXG4gICAgX2dldE1hdHJpeCA9IGZ1bmN0aW9uIF9nZXRNYXRyaXgodGFyZ2V0LCBmb3JjZTJEKSB7XG4gIHZhciBjYWNoZSA9IHRhcmdldC5fZ3NhcCB8fCBfZ2V0Q2FjaGUodGFyZ2V0KSxcbiAgICAgIHN0eWxlID0gdGFyZ2V0LnN0eWxlLFxuICAgICAgbWF0cml4ID0gX2dldENvbXB1dGVkVHJhbnNmb3JtTWF0cml4QXNBcnJheSh0YXJnZXQpLFxuICAgICAgcGFyZW50LFxuICAgICAgbmV4dFNpYmxpbmcsXG4gICAgICB0ZW1wLFxuICAgICAgYWRkZWRUb0RPTTtcblxuICBpZiAoY2FjaGUuc3ZnICYmIHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIikpIHtcbiAgICB0ZW1wID0gdGFyZ2V0LnRyYW5zZm9ybS5iYXNlVmFsLmNvbnNvbGlkYXRlKCkubWF0cml4OyAvL2Vuc3VyZXMgdGhhdCBldmVuIGNvbXBsZXggdmFsdWVzIGxpa2UgXCJ0cmFuc2xhdGUoNTAsNjApIHJvdGF0ZSgxMzUsMCwwKVwiIGFyZSBwYXJzZWQgYmVjYXVzZSBpdCBtYXNoZXMgaXQgaW50byBhIG1hdHJpeC5cblxuICAgIG1hdHJpeCA9IFt0ZW1wLmEsIHRlbXAuYiwgdGVtcC5jLCB0ZW1wLmQsIHRlbXAuZSwgdGVtcC5mXTtcbiAgICByZXR1cm4gbWF0cml4LmpvaW4oXCIsXCIpID09PSBcIjEsMCwwLDEsMCwwXCIgPyBfaWRlbnRpdHkyRE1hdHJpeCA6IG1hdHJpeDtcbiAgfSBlbHNlIGlmIChtYXRyaXggPT09IF9pZGVudGl0eTJETWF0cml4ICYmICF0YXJnZXQub2Zmc2V0UGFyZW50ICYmIHRhcmdldCAhPT0gX2RvY0VsZW1lbnQgJiYgIWNhY2hlLnN2Zykge1xuICAgIC8vbm90ZTogaWYgb2Zmc2V0UGFyZW50IGlzIG51bGwsIHRoYXQgbWVhbnMgdGhlIGVsZW1lbnQgaXNuJ3QgaW4gdGhlIG5vcm1hbCBkb2N1bWVudCBmbG93LCBsaWtlIGlmIGl0IGhhcyBkaXNwbGF5Om5vbmUgb3Igb25lIG9mIGl0cyBhbmNlc3RvcnMgaGFzIGRpc3BsYXk6bm9uZSkuIEZpcmVmb3ggcmV0dXJucyBudWxsIGZvciBnZXRDb21wdXRlZFN0eWxlKCkgaWYgdGhlIGVsZW1lbnQgaXMgaW4gYW4gaWZyYW1lIHRoYXQgaGFzIGRpc3BsYXk6bm9uZS4gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NTQ4Mzk3XG4gICAgLy9icm93c2VycyBkb24ndCByZXBvcnQgdHJhbnNmb3JtcyBhY2N1cmF0ZWx5IHVubGVzcyB0aGUgZWxlbWVudCBpcyBpbiB0aGUgRE9NIGFuZCBoYXMgYSBkaXNwbGF5IHZhbHVlIHRoYXQncyBub3QgXCJub25lXCIuIEZpcmVmb3ggYW5kIE1pY3Jvc29mdCBicm93c2VycyBoYXZlIGEgcGFydGlhbCBidWcgd2hlcmUgdGhleSdsbCByZXBvcnQgdHJhbnNmb3JtcyBldmVuIGlmIGRpc3BsYXk6bm9uZSBCVVQgbm90IGFueSBwZXJjZW50YWdlLWJhc2VkIHZhbHVlcyBsaWtlIHRyYW5zbGF0ZSgtNTAlLCA4cHgpIHdpbGwgYmUgcmVwb3J0ZWQgYXMgaWYgaXQncyB0cmFuc2xhdGUoMCwgOHB4KS5cbiAgICB0ZW1wID0gc3R5bGUuZGlzcGxheTtcbiAgICBzdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgIHBhcmVudCA9IHRhcmdldC5wYXJlbnROb2RlO1xuXG4gICAgaWYgKCFwYXJlbnQgfHwgIXRhcmdldC5vZmZzZXRQYXJlbnQpIHtcbiAgICAgIC8vIG5vdGU6IGluIDMuMy4wIHdlIHN3aXRjaGVkIHRhcmdldC5vZmZzZXRQYXJlbnQgdG8gX2RvYy5ib2R5LmNvbnRhaW5zKHRhcmdldCkgdG8gYXZvaWQgW3NvbWV0aW1lcyB1bm5lY2Vzc2FyeV0gTXV0YXRpb25PYnNlcnZlciBjYWxscyBidXQgdGhhdCB3YXNuJ3QgYWRlcXVhdGUgYmVjYXVzZSB0aGVyZSBhcmUgZWRnZSBjYXNlcyB3aGVyZSBuZXN0ZWQgcG9zaXRpb246IGZpeGVkIGVsZW1lbnRzIG5lZWQgdG8gZ2V0IHJlcGFyZW50ZWQgdG8gYWNjdXJhdGVseSBzZW5zZSB0cmFuc2Zvcm1zLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2dyZWVuc29jay9HU0FQL2lzc3Vlcy8zODggYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbnNvY2svR1NBUC9pc3N1ZXMvMzc1XG4gICAgICBhZGRlZFRvRE9NID0gMTsgLy9mbGFnXG5cbiAgICAgIG5leHRTaWJsaW5nID0gdGFyZ2V0Lm5leHRFbGVtZW50U2libGluZztcblxuICAgICAgX2RvY0VsZW1lbnQuYXBwZW5kQ2hpbGQodGFyZ2V0KTsgLy93ZSBtdXN0IGFkZCBpdCB0byB0aGUgRE9NIGluIG9yZGVyIHRvIGdldCB2YWx1ZXMgcHJvcGVybHlcblxuICAgIH1cblxuICAgIG1hdHJpeCA9IF9nZXRDb21wdXRlZFRyYW5zZm9ybU1hdHJpeEFzQXJyYXkodGFyZ2V0KTtcbiAgICB0ZW1wID8gc3R5bGUuZGlzcGxheSA9IHRlbXAgOiBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBcImRpc3BsYXlcIik7XG5cbiAgICBpZiAoYWRkZWRUb0RPTSkge1xuICAgICAgbmV4dFNpYmxpbmcgPyBwYXJlbnQuaW5zZXJ0QmVmb3JlKHRhcmdldCwgbmV4dFNpYmxpbmcpIDogcGFyZW50ID8gcGFyZW50LmFwcGVuZENoaWxkKHRhcmdldCkgOiBfZG9jRWxlbWVudC5yZW1vdmVDaGlsZCh0YXJnZXQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmb3JjZTJEICYmIG1hdHJpeC5sZW5ndGggPiA2ID8gW21hdHJpeFswXSwgbWF0cml4WzFdLCBtYXRyaXhbNF0sIG1hdHJpeFs1XSwgbWF0cml4WzEyXSwgbWF0cml4WzEzXV0gOiBtYXRyaXg7XG59LFxuICAgIF9hcHBseVNWR09yaWdpbiA9IGZ1bmN0aW9uIF9hcHBseVNWR09yaWdpbih0YXJnZXQsIG9yaWdpbiwgb3JpZ2luSXNBYnNvbHV0ZSwgc21vb3RoLCBtYXRyaXhBcnJheSwgcGx1Z2luVG9BZGRQcm9wVHdlZW5zVG8pIHtcbiAgdmFyIGNhY2hlID0gdGFyZ2V0Ll9nc2FwLFxuICAgICAgbWF0cml4ID0gbWF0cml4QXJyYXkgfHwgX2dldE1hdHJpeCh0YXJnZXQsIHRydWUpLFxuICAgICAgeE9yaWdpbk9sZCA9IGNhY2hlLnhPcmlnaW4gfHwgMCxcbiAgICAgIHlPcmlnaW5PbGQgPSBjYWNoZS55T3JpZ2luIHx8IDAsXG4gICAgICB4T2Zmc2V0T2xkID0gY2FjaGUueE9mZnNldCB8fCAwLFxuICAgICAgeU9mZnNldE9sZCA9IGNhY2hlLnlPZmZzZXQgfHwgMCxcbiAgICAgIGEgPSBtYXRyaXhbMF0sXG4gICAgICBiID0gbWF0cml4WzFdLFxuICAgICAgYyA9IG1hdHJpeFsyXSxcbiAgICAgIGQgPSBtYXRyaXhbM10sXG4gICAgICB0eCA9IG1hdHJpeFs0XSxcbiAgICAgIHR5ID0gbWF0cml4WzVdLFxuICAgICAgb3JpZ2luU3BsaXQgPSBvcmlnaW4uc3BsaXQoXCIgXCIpLFxuICAgICAgeE9yaWdpbiA9IHBhcnNlRmxvYXQob3JpZ2luU3BsaXRbMF0pIHx8IDAsXG4gICAgICB5T3JpZ2luID0gcGFyc2VGbG9hdChvcmlnaW5TcGxpdFsxXSkgfHwgMCxcbiAgICAgIGJvdW5kcyxcbiAgICAgIGRldGVybWluYW50LFxuICAgICAgeCxcbiAgICAgIHk7XG5cbiAgaWYgKCFvcmlnaW5Jc0Fic29sdXRlKSB7XG4gICAgYm91bmRzID0gX2dldEJCb3godGFyZ2V0KTtcbiAgICB4T3JpZ2luID0gYm91bmRzLnggKyAofm9yaWdpblNwbGl0WzBdLmluZGV4T2YoXCIlXCIpID8geE9yaWdpbiAvIDEwMCAqIGJvdW5kcy53aWR0aCA6IHhPcmlnaW4pO1xuICAgIHlPcmlnaW4gPSBib3VuZHMueSArICh+KG9yaWdpblNwbGl0WzFdIHx8IG9yaWdpblNwbGl0WzBdKS5pbmRleE9mKFwiJVwiKSA/IHlPcmlnaW4gLyAxMDAgKiBib3VuZHMuaGVpZ2h0IDogeU9yaWdpbik7XG4gIH0gZWxzZSBpZiAobWF0cml4ICE9PSBfaWRlbnRpdHkyRE1hdHJpeCAmJiAoZGV0ZXJtaW5hbnQgPSBhICogZCAtIGIgKiBjKSkge1xuICAgIC8vaWYgaXQncyB6ZXJvIChsaWtlIGlmIHNjYWxlWCBhbmQgc2NhbGVZIGFyZSB6ZXJvKSwgc2tpcCBpdCB0byBhdm9pZCBlcnJvcnMgd2l0aCBkaXZpZGluZyBieSB6ZXJvLlxuICAgIHggPSB4T3JpZ2luICogKGQgLyBkZXRlcm1pbmFudCkgKyB5T3JpZ2luICogKC1jIC8gZGV0ZXJtaW5hbnQpICsgKGMgKiB0eSAtIGQgKiB0eCkgLyBkZXRlcm1pbmFudDtcbiAgICB5ID0geE9yaWdpbiAqICgtYiAvIGRldGVybWluYW50KSArIHlPcmlnaW4gKiAoYSAvIGRldGVybWluYW50KSAtIChhICogdHkgLSBiICogdHgpIC8gZGV0ZXJtaW5hbnQ7XG4gICAgeE9yaWdpbiA9IHg7XG4gICAgeU9yaWdpbiA9IHk7XG4gIH1cblxuICBpZiAoc21vb3RoIHx8IHNtb290aCAhPT0gZmFsc2UgJiYgY2FjaGUuc21vb3RoKSB7XG4gICAgdHggPSB4T3JpZ2luIC0geE9yaWdpbk9sZDtcbiAgICB0eSA9IHlPcmlnaW4gLSB5T3JpZ2luT2xkO1xuICAgIGNhY2hlLnhPZmZzZXQgPSB4T2Zmc2V0T2xkICsgKHR4ICogYSArIHR5ICogYykgLSB0eDtcbiAgICBjYWNoZS55T2Zmc2V0ID0geU9mZnNldE9sZCArICh0eCAqIGIgKyB0eSAqIGQpIC0gdHk7XG4gIH0gZWxzZSB7XG4gICAgY2FjaGUueE9mZnNldCA9IGNhY2hlLnlPZmZzZXQgPSAwO1xuICB9XG5cbiAgY2FjaGUueE9yaWdpbiA9IHhPcmlnaW47XG4gIGNhY2hlLnlPcmlnaW4gPSB5T3JpZ2luO1xuICBjYWNoZS5zbW9vdGggPSAhIXNtb290aDtcbiAgY2FjaGUub3JpZ2luID0gb3JpZ2luO1xuICBjYWNoZS5vcmlnaW5Jc0Fic29sdXRlID0gISFvcmlnaW5Jc0Fic29sdXRlO1xuICB0YXJnZXQuc3R5bGVbX3RyYW5zZm9ybU9yaWdpblByb3BdID0gXCIwcHggMHB4XCI7IC8vb3RoZXJ3aXNlLCBpZiBzb21lb25lIHNldHMgIGFuIG9yaWdpbiB2aWEgQ1NTLCBpdCB3aWxsIGxpa2VseSBpbnRlcmZlcmUgd2l0aCB0aGUgU1ZHIHRyYW5zZm9ybSBhdHRyaWJ1dGUgb25lcyAoYmVjYXVzZSByZW1lbWJlciwgd2UncmUgYmFraW5nIHRoZSBvcmlnaW4gaW50byB0aGUgbWF0cml4KCkgdmFsdWUpLlxuXG4gIGlmIChwbHVnaW5Ub0FkZFByb3BUd2VlbnNUbykge1xuICAgIF9hZGROb25Ud2VlbmluZ1BUKHBsdWdpblRvQWRkUHJvcFR3ZWVuc1RvLCBjYWNoZSwgXCJ4T3JpZ2luXCIsIHhPcmlnaW5PbGQsIHhPcmlnaW4pO1xuXG4gICAgX2FkZE5vblR3ZWVuaW5nUFQocGx1Z2luVG9BZGRQcm9wVHdlZW5zVG8sIGNhY2hlLCBcInlPcmlnaW5cIiwgeU9yaWdpbk9sZCwgeU9yaWdpbik7XG5cbiAgICBfYWRkTm9uVHdlZW5pbmdQVChwbHVnaW5Ub0FkZFByb3BUd2VlbnNUbywgY2FjaGUsIFwieE9mZnNldFwiLCB4T2Zmc2V0T2xkLCBjYWNoZS54T2Zmc2V0KTtcblxuICAgIF9hZGROb25Ud2VlbmluZ1BUKHBsdWdpblRvQWRkUHJvcFR3ZWVuc1RvLCBjYWNoZSwgXCJ5T2Zmc2V0XCIsIHlPZmZzZXRPbGQsIGNhY2hlLnlPZmZzZXQpO1xuICB9XG5cbiAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcImRhdGEtc3ZnLW9yaWdpblwiLCB4T3JpZ2luICsgXCIgXCIgKyB5T3JpZ2luKTtcbn0sXG4gICAgX3BhcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgdW5jYWNoZSkge1xuICB2YXIgY2FjaGUgPSB0YXJnZXQuX2dzYXAgfHwgbmV3IEdTQ2FjaGUodGFyZ2V0KTtcblxuICBpZiAoXCJ4XCIgaW4gY2FjaGUgJiYgIXVuY2FjaGUgJiYgIWNhY2hlLnVuY2FjaGUpIHtcbiAgICByZXR1cm4gY2FjaGU7XG4gIH1cblxuICB2YXIgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICBpbnZlcnRlZFNjYWxlWCA9IGNhY2hlLnNjYWxlWCA8IDAsXG4gICAgICBweCA9IFwicHhcIixcbiAgICAgIGRlZyA9IFwiZGVnXCIsXG4gICAgICBjcyA9IGdldENvbXB1dGVkU3R5bGUodGFyZ2V0KSxcbiAgICAgIG9yaWdpbiA9IF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybU9yaWdpblByb3ApIHx8IFwiMFwiLFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICB6LFxuICAgICAgc2NhbGVYLFxuICAgICAgc2NhbGVZLFxuICAgICAgcm90YXRpb24sXG4gICAgICByb3RhdGlvblgsXG4gICAgICByb3RhdGlvblksXG4gICAgICBza2V3WCxcbiAgICAgIHNrZXdZLFxuICAgICAgcGVyc3BlY3RpdmUsXG4gICAgICB4T3JpZ2luLFxuICAgICAgeU9yaWdpbixcbiAgICAgIG1hdHJpeCxcbiAgICAgIGFuZ2xlLFxuICAgICAgY29zLFxuICAgICAgc2luLFxuICAgICAgYSxcbiAgICAgIGIsXG4gICAgICBjLFxuICAgICAgZCxcbiAgICAgIGExMixcbiAgICAgIGEyMixcbiAgICAgIHQxLFxuICAgICAgdDIsXG4gICAgICB0MyxcbiAgICAgIGExMyxcbiAgICAgIGEyMyxcbiAgICAgIGEzMyxcbiAgICAgIGE0MixcbiAgICAgIGE0MyxcbiAgICAgIGEzMjtcbiAgeCA9IHkgPSB6ID0gcm90YXRpb24gPSByb3RhdGlvblggPSByb3RhdGlvblkgPSBza2V3WCA9IHNrZXdZID0gcGVyc3BlY3RpdmUgPSAwO1xuICBzY2FsZVggPSBzY2FsZVkgPSAxO1xuICBjYWNoZS5zdmcgPSAhISh0YXJnZXQuZ2V0Q1RNICYmIF9pc1NWRyh0YXJnZXQpKTtcblxuICBpZiAoY3MudHJhbnNsYXRlKSB7XG4gICAgLy8gYWNjb21tb2RhdGUgaW5kZXBlbmRlbnQgdHJhbnNmb3JtcyBieSBjb21iaW5pbmcgdGhlbSBpbnRvIG5vcm1hbCBvbmVzLlxuICAgIGlmIChjcy50cmFuc2xhdGUgIT09IFwibm9uZVwiIHx8IGNzLnNjYWxlICE9PSBcIm5vbmVcIiB8fCBjcy5yb3RhdGUgIT09IFwibm9uZVwiKSB7XG4gICAgICBzdHlsZVtfdHJhbnNmb3JtUHJvcF0gPSAoY3MudHJhbnNsYXRlICE9PSBcIm5vbmVcIiA/IFwidHJhbnNsYXRlM2QoXCIgKyAoY3MudHJhbnNsYXRlICsgXCIgMCAwXCIpLnNwbGl0KFwiIFwiKS5zbGljZSgwLCAzKS5qb2luKFwiLCBcIikgKyBcIikgXCIgOiBcIlwiKSArIChjcy5yb3RhdGUgIT09IFwibm9uZVwiID8gXCJyb3RhdGUoXCIgKyBjcy5yb3RhdGUgKyBcIikgXCIgOiBcIlwiKSArIChjcy5zY2FsZSAhPT0gXCJub25lXCIgPyBcInNjYWxlKFwiICsgY3Muc2NhbGUuc3BsaXQoXCIgXCIpLmpvaW4oXCIsXCIpICsgXCIpIFwiIDogXCJcIikgKyAoY3NbX3RyYW5zZm9ybVByb3BdICE9PSBcIm5vbmVcIiA/IGNzW190cmFuc2Zvcm1Qcm9wXSA6IFwiXCIpO1xuICAgIH1cblxuICAgIHN0eWxlLnNjYWxlID0gc3R5bGUucm90YXRlID0gc3R5bGUudHJhbnNsYXRlID0gXCJub25lXCI7XG4gIH1cblxuICBtYXRyaXggPSBfZ2V0TWF0cml4KHRhcmdldCwgY2FjaGUuc3ZnKTtcblxuICBpZiAoY2FjaGUuc3ZnKSB7XG4gICAgaWYgKGNhY2hlLnVuY2FjaGUpIHtcbiAgICAgIC8vIGlmIGNhY2hlLnVuY2FjaGUgaXMgdHJ1ZSAoYW5kIG1heWJlIGlmIG9yaWdpbiBpcyAwLDApLCB3ZSBuZWVkIHRvIHNldCBlbGVtZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IChjYWNoZS54T3JpZ2luIC0gYmJveC54KSArIFwicHggXCIgKyAoY2FjaGUueU9yaWdpbiAtIGJib3gueSkgKyBcInB4XCIuIFByZXZpb3VzbHkgd2UgbGV0IHRoZSBkYXRhLXN2Zy1vcmlnaW4gc3RheSBpbnN0ZWFkLCBidXQgd2hlbiBpbnRyb2R1Y2luZyByZXZlcnQoKSwgaXQgY29tcGxpY2F0ZWQgdGhpbmdzLlxuICAgICAgdDIgPSB0YXJnZXQuZ2V0QkJveCgpO1xuICAgICAgb3JpZ2luID0gY2FjaGUueE9yaWdpbiAtIHQyLnggKyBcInB4IFwiICsgKGNhY2hlLnlPcmlnaW4gLSB0Mi55KSArIFwicHhcIjtcbiAgICAgIHQxID0gXCJcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgdDEgPSAhdW5jYWNoZSAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0YS1zdmctb3JpZ2luXCIpOyAvLyAgUmVtZW1iZXIsIHRvIHdvcmsgYXJvdW5kIGJyb3dzZXIgaW5jb25zaXN0ZW5jaWVzIHdlIGFsd2F5cyBmb3JjZSBTVkcgZWxlbWVudHMnIHRyYW5zZm9ybU9yaWdpbiB0byAwLDAgYW5kIG9mZnNldCB0aGUgdHJhbnNsYXRpb24gYWNjb3JkaW5nbHkuXG4gICAgfVxuXG4gICAgX2FwcGx5U1ZHT3JpZ2luKHRhcmdldCwgdDEgfHwgb3JpZ2luLCAhIXQxIHx8IGNhY2hlLm9yaWdpbklzQWJzb2x1dGUsIGNhY2hlLnNtb290aCAhPT0gZmFsc2UsIG1hdHJpeCk7XG4gIH1cblxuICB4T3JpZ2luID0gY2FjaGUueE9yaWdpbiB8fCAwO1xuICB5T3JpZ2luID0gY2FjaGUueU9yaWdpbiB8fCAwO1xuXG4gIGlmIChtYXRyaXggIT09IF9pZGVudGl0eTJETWF0cml4KSB7XG4gICAgYSA9IG1hdHJpeFswXTsgLy9hMTFcblxuICAgIGIgPSBtYXRyaXhbMV07IC8vYTIxXG5cbiAgICBjID0gbWF0cml4WzJdOyAvL2EzMVxuXG4gICAgZCA9IG1hdHJpeFszXTsgLy9hNDFcblxuICAgIHggPSBhMTIgPSBtYXRyaXhbNF07XG4gICAgeSA9IGEyMiA9IG1hdHJpeFs1XTsgLy8yRCBtYXRyaXhcblxuICAgIGlmIChtYXRyaXgubGVuZ3RoID09PSA2KSB7XG4gICAgICBzY2FsZVggPSBNYXRoLnNxcnQoYSAqIGEgKyBiICogYik7XG4gICAgICBzY2FsZVkgPSBNYXRoLnNxcnQoZCAqIGQgKyBjICogYyk7XG4gICAgICByb3RhdGlvbiA9IGEgfHwgYiA/IF9hdGFuMihiLCBhKSAqIF9SQUQyREVHIDogMDsgLy9ub3RlOiBpZiBzY2FsZVggaXMgMCwgd2UgY2Fubm90IGFjY3VyYXRlbHkgbWVhc3VyZSByb3RhdGlvbi4gU2FtZSBmb3Igc2tld1ggd2l0aCBhIHNjYWxlWSBvZiAwLiBUaGVyZWZvcmUsIHdlIGRlZmF1bHQgdG8gdGhlIHByZXZpb3VzbHkgcmVjb3JkZWQgdmFsdWUgKG9yIHplcm8gaWYgdGhhdCBkb2Vzbid0IGV4aXN0KS5cblxuICAgICAgc2tld1ggPSBjIHx8IGQgPyBfYXRhbjIoYywgZCkgKiBfUkFEMkRFRyArIHJvdGF0aW9uIDogMDtcbiAgICAgIHNrZXdYICYmIChzY2FsZVkgKj0gTWF0aC5hYnMoTWF0aC5jb3Moc2tld1ggKiBfREVHMlJBRCkpKTtcblxuICAgICAgaWYgKGNhY2hlLnN2Zykge1xuICAgICAgICB4IC09IHhPcmlnaW4gLSAoeE9yaWdpbiAqIGEgKyB5T3JpZ2luICogYyk7XG4gICAgICAgIHkgLT0geU9yaWdpbiAtICh4T3JpZ2luICogYiArIHlPcmlnaW4gKiBkKTtcbiAgICAgIH0gLy8zRCBtYXRyaXhcblxuICAgIH0gZWxzZSB7XG4gICAgICBhMzIgPSBtYXRyaXhbNl07XG4gICAgICBhNDIgPSBtYXRyaXhbN107XG4gICAgICBhMTMgPSBtYXRyaXhbOF07XG4gICAgICBhMjMgPSBtYXRyaXhbOV07XG4gICAgICBhMzMgPSBtYXRyaXhbMTBdO1xuICAgICAgYTQzID0gbWF0cml4WzExXTtcbiAgICAgIHggPSBtYXRyaXhbMTJdO1xuICAgICAgeSA9IG1hdHJpeFsxM107XG4gICAgICB6ID0gbWF0cml4WzE0XTtcbiAgICAgIGFuZ2xlID0gX2F0YW4yKGEzMiwgYTMzKTtcbiAgICAgIHJvdGF0aW9uWCA9IGFuZ2xlICogX1JBRDJERUc7IC8vcm90YXRpb25YXG5cbiAgICAgIGlmIChhbmdsZSkge1xuICAgICAgICBjb3MgPSBNYXRoLmNvcygtYW5nbGUpO1xuICAgICAgICBzaW4gPSBNYXRoLnNpbigtYW5nbGUpO1xuICAgICAgICB0MSA9IGExMiAqIGNvcyArIGExMyAqIHNpbjtcbiAgICAgICAgdDIgPSBhMjIgKiBjb3MgKyBhMjMgKiBzaW47XG4gICAgICAgIHQzID0gYTMyICogY29zICsgYTMzICogc2luO1xuICAgICAgICBhMTMgPSBhMTIgKiAtc2luICsgYTEzICogY29zO1xuICAgICAgICBhMjMgPSBhMjIgKiAtc2luICsgYTIzICogY29zO1xuICAgICAgICBhMzMgPSBhMzIgKiAtc2luICsgYTMzICogY29zO1xuICAgICAgICBhNDMgPSBhNDIgKiAtc2luICsgYTQzICogY29zO1xuICAgICAgICBhMTIgPSB0MTtcbiAgICAgICAgYTIyID0gdDI7XG4gICAgICAgIGEzMiA9IHQzO1xuICAgICAgfSAvL3JvdGF0aW9uWVxuXG5cbiAgICAgIGFuZ2xlID0gX2F0YW4yKC1jLCBhMzMpO1xuICAgICAgcm90YXRpb25ZID0gYW5nbGUgKiBfUkFEMkRFRztcblxuICAgICAgaWYgKGFuZ2xlKSB7XG4gICAgICAgIGNvcyA9IE1hdGguY29zKC1hbmdsZSk7XG4gICAgICAgIHNpbiA9IE1hdGguc2luKC1hbmdsZSk7XG4gICAgICAgIHQxID0gYSAqIGNvcyAtIGExMyAqIHNpbjtcbiAgICAgICAgdDIgPSBiICogY29zIC0gYTIzICogc2luO1xuICAgICAgICB0MyA9IGMgKiBjb3MgLSBhMzMgKiBzaW47XG4gICAgICAgIGE0MyA9IGQgKiBzaW4gKyBhNDMgKiBjb3M7XG4gICAgICAgIGEgPSB0MTtcbiAgICAgICAgYiA9IHQyO1xuICAgICAgICBjID0gdDM7XG4gICAgICB9IC8vcm90YXRpb25aXG5cblxuICAgICAgYW5nbGUgPSBfYXRhbjIoYiwgYSk7XG4gICAgICByb3RhdGlvbiA9IGFuZ2xlICogX1JBRDJERUc7XG5cbiAgICAgIGlmIChhbmdsZSkge1xuICAgICAgICBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICAgIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgICAgICAgdDEgPSBhICogY29zICsgYiAqIHNpbjtcbiAgICAgICAgdDIgPSBhMTIgKiBjb3MgKyBhMjIgKiBzaW47XG4gICAgICAgIGIgPSBiICogY29zIC0gYSAqIHNpbjtcbiAgICAgICAgYTIyID0gYTIyICogY29zIC0gYTEyICogc2luO1xuICAgICAgICBhID0gdDE7XG4gICAgICAgIGExMiA9IHQyO1xuICAgICAgfVxuXG4gICAgICBpZiAocm90YXRpb25YICYmIE1hdGguYWJzKHJvdGF0aW9uWCkgKyBNYXRoLmFicyhyb3RhdGlvbikgPiAzNTkuOSkge1xuICAgICAgICAvL3doZW4gcm90YXRpb25ZIGlzIHNldCwgaXQgd2lsbCBvZnRlbiBiZSBwYXJzZWQgYXMgMTgwIGRlZ3JlZXMgZGlmZmVyZW50IHRoYW4gaXQgc2hvdWxkIGJlLCBhbmQgcm90YXRpb25YIGFuZCByb3RhdGlvbiBib3RoIGJlaW5nIDE4MCAoaXQgbG9va3MgdGhlIHNhbWUpLCBzbyB3ZSBhZGp1c3QgZm9yIHRoYXQgaGVyZS5cbiAgICAgICAgcm90YXRpb25YID0gcm90YXRpb24gPSAwO1xuICAgICAgICByb3RhdGlvblkgPSAxODAgLSByb3RhdGlvblk7XG4gICAgICB9XG5cbiAgICAgIHNjYWxlWCA9IF9yb3VuZChNYXRoLnNxcnQoYSAqIGEgKyBiICogYiArIGMgKiBjKSk7XG4gICAgICBzY2FsZVkgPSBfcm91bmQoTWF0aC5zcXJ0KGEyMiAqIGEyMiArIGEzMiAqIGEzMikpO1xuICAgICAgYW5nbGUgPSBfYXRhbjIoYTEyLCBhMjIpO1xuICAgICAgc2tld1ggPSBNYXRoLmFicyhhbmdsZSkgPiAwLjAwMDIgPyBhbmdsZSAqIF9SQUQyREVHIDogMDtcbiAgICAgIHBlcnNwZWN0aXZlID0gYTQzID8gMSAvIChhNDMgPCAwID8gLWE0MyA6IGE0MykgOiAwO1xuICAgIH1cblxuICAgIGlmIChjYWNoZS5zdmcpIHtcbiAgICAgIC8vc2Vuc2UgaWYgdGhlcmUgYXJlIENTUyB0cmFuc2Zvcm1zIGFwcGxpZWQgb24gYW4gU1ZHIGVsZW1lbnQgaW4gd2hpY2ggY2FzZSB3ZSBtdXN0IG92ZXJ3cml0ZSB0aGVtIHdoZW4gcmVuZGVyaW5nLiBUaGUgdHJhbnNmb3JtIGF0dHJpYnV0ZSBpcyBtb3JlIHJlbGlhYmxlIGNyb3NzLWJyb3dzZXIsIGJ1dCB3ZSBjYW4ndCBqdXN0IHJlbW92ZSB0aGUgQ1NTIG9uZXMgYmVjYXVzZSB0aGV5IG1heSBiZSBhcHBsaWVkIGluIGEgQ1NTIHJ1bGUgc29tZXdoZXJlIChub3QganVzdCBpbmxpbmUpLlxuICAgICAgdDEgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpO1xuICAgICAgY2FjaGUuZm9yY2VDU1MgPSB0YXJnZXQuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwiXCIpIHx8ICFfaXNOdWxsVHJhbnNmb3JtKF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybVByb3ApKTtcbiAgICAgIHQxICYmIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgdDEpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChNYXRoLmFicyhza2V3WCkgPiA5MCAmJiBNYXRoLmFicyhza2V3WCkgPCAyNzApIHtcbiAgICBpZiAoaW52ZXJ0ZWRTY2FsZVgpIHtcbiAgICAgIHNjYWxlWCAqPSAtMTtcbiAgICAgIHNrZXdYICs9IHJvdGF0aW9uIDw9IDAgPyAxODAgOiAtMTgwO1xuICAgICAgcm90YXRpb24gKz0gcm90YXRpb24gPD0gMCA/IDE4MCA6IC0xODA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlWSAqPSAtMTtcbiAgICAgIHNrZXdYICs9IHNrZXdYIDw9IDAgPyAxODAgOiAtMTgwO1xuICAgIH1cbiAgfVxuXG4gIHVuY2FjaGUgPSB1bmNhY2hlIHx8IGNhY2hlLnVuY2FjaGU7XG4gIGNhY2hlLnggPSB4IC0gKChjYWNoZS54UGVyY2VudCA9IHggJiYgKCF1bmNhY2hlICYmIGNhY2hlLnhQZXJjZW50IHx8IChNYXRoLnJvdW5kKHRhcmdldC5vZmZzZXRXaWR0aCAvIDIpID09PSBNYXRoLnJvdW5kKC14KSA/IC01MCA6IDApKSkgPyB0YXJnZXQub2Zmc2V0V2lkdGggKiBjYWNoZS54UGVyY2VudCAvIDEwMCA6IDApICsgcHg7XG4gIGNhY2hlLnkgPSB5IC0gKChjYWNoZS55UGVyY2VudCA9IHkgJiYgKCF1bmNhY2hlICYmIGNhY2hlLnlQZXJjZW50IHx8IChNYXRoLnJvdW5kKHRhcmdldC5vZmZzZXRIZWlnaHQgLyAyKSA9PT0gTWF0aC5yb3VuZCgteSkgPyAtNTAgOiAwKSkpID8gdGFyZ2V0Lm9mZnNldEhlaWdodCAqIGNhY2hlLnlQZXJjZW50IC8gMTAwIDogMCkgKyBweDtcbiAgY2FjaGUueiA9IHogKyBweDtcbiAgY2FjaGUuc2NhbGVYID0gX3JvdW5kKHNjYWxlWCk7XG4gIGNhY2hlLnNjYWxlWSA9IF9yb3VuZChzY2FsZVkpO1xuICBjYWNoZS5yb3RhdGlvbiA9IF9yb3VuZChyb3RhdGlvbikgKyBkZWc7XG4gIGNhY2hlLnJvdGF0aW9uWCA9IF9yb3VuZChyb3RhdGlvblgpICsgZGVnO1xuICBjYWNoZS5yb3RhdGlvblkgPSBfcm91bmQocm90YXRpb25ZKSArIGRlZztcbiAgY2FjaGUuc2tld1ggPSBza2V3WCArIGRlZztcbiAgY2FjaGUuc2tld1kgPSBza2V3WSArIGRlZztcbiAgY2FjaGUudHJhbnNmb3JtUGVyc3BlY3RpdmUgPSBwZXJzcGVjdGl2ZSArIHB4O1xuXG4gIGlmIChjYWNoZS56T3JpZ2luID0gcGFyc2VGbG9hdChvcmlnaW4uc3BsaXQoXCIgXCIpWzJdKSB8fCAwKSB7XG4gICAgc3R5bGVbX3RyYW5zZm9ybU9yaWdpblByb3BdID0gX2ZpcnN0VHdvT25seShvcmlnaW4pO1xuICB9XG5cbiAgY2FjaGUueE9mZnNldCA9IGNhY2hlLnlPZmZzZXQgPSAwO1xuICBjYWNoZS5mb3JjZTNEID0gX2NvbmZpZy5mb3JjZTNEO1xuICBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0gPSBjYWNoZS5zdmcgPyBfcmVuZGVyU1ZHVHJhbnNmb3JtcyA6IF9zdXBwb3J0czNEID8gX3JlbmRlckNTU1RyYW5zZm9ybXMgOiBfcmVuZGVyTm9uM0RUcmFuc2Zvcm1zO1xuICBjYWNoZS51bmNhY2hlID0gMDtcbiAgcmV0dXJuIGNhY2hlO1xufSxcbiAgICBfZmlyc3RUd29Pbmx5ID0gZnVuY3Rpb24gX2ZpcnN0VHdvT25seSh2YWx1ZSkge1xuICByZXR1cm4gKHZhbHVlID0gdmFsdWUuc3BsaXQoXCIgXCIpKVswXSArIFwiIFwiICsgdmFsdWVbMV07XG59LFxuICAgIC8vZm9yIGhhbmRsaW5nIHRyYW5zZm9ybU9yaWdpbiB2YWx1ZXMsIHN0cmlwcGluZyBvdXQgdGhlIDNyZCBkaW1lbnNpb25cbl9hZGRQeFRyYW5zbGF0ZSA9IGZ1bmN0aW9uIF9hZGRQeFRyYW5zbGF0ZSh0YXJnZXQsIHN0YXJ0LCB2YWx1ZSkge1xuICB2YXIgdW5pdCA9IGdldFVuaXQoc3RhcnQpO1xuICByZXR1cm4gX3JvdW5kKHBhcnNlRmxvYXQoc3RhcnQpICsgcGFyc2VGbG9hdChfY29udmVydFRvVW5pdCh0YXJnZXQsIFwieFwiLCB2YWx1ZSArIFwicHhcIiwgdW5pdCkpKSArIHVuaXQ7XG59LFxuICAgIF9yZW5kZXJOb24zRFRyYW5zZm9ybXMgPSBmdW5jdGlvbiBfcmVuZGVyTm9uM0RUcmFuc2Zvcm1zKHJhdGlvLCBjYWNoZSkge1xuICBjYWNoZS56ID0gXCIwcHhcIjtcbiAgY2FjaGUucm90YXRpb25ZID0gY2FjaGUucm90YXRpb25YID0gXCIwZGVnXCI7XG4gIGNhY2hlLmZvcmNlM0QgPSAwO1xuXG4gIF9yZW5kZXJDU1NUcmFuc2Zvcm1zKHJhdGlvLCBjYWNoZSk7XG59LFxuICAgIF96ZXJvRGVnID0gXCIwZGVnXCIsXG4gICAgX3plcm9QeCA9IFwiMHB4XCIsXG4gICAgX2VuZFBhcmVudGhlc2lzID0gXCIpIFwiLFxuICAgIF9yZW5kZXJDU1NUcmFuc2Zvcm1zID0gZnVuY3Rpb24gX3JlbmRlckNTU1RyYW5zZm9ybXMocmF0aW8sIGNhY2hlKSB7XG4gIHZhciBfcmVmID0gY2FjaGUgfHwgdGhpcyxcbiAgICAgIHhQZXJjZW50ID0gX3JlZi54UGVyY2VudCxcbiAgICAgIHlQZXJjZW50ID0gX3JlZi55UGVyY2VudCxcbiAgICAgIHggPSBfcmVmLngsXG4gICAgICB5ID0gX3JlZi55LFxuICAgICAgeiA9IF9yZWYueixcbiAgICAgIHJvdGF0aW9uID0gX3JlZi5yb3RhdGlvbixcbiAgICAgIHJvdGF0aW9uWSA9IF9yZWYucm90YXRpb25ZLFxuICAgICAgcm90YXRpb25YID0gX3JlZi5yb3RhdGlvblgsXG4gICAgICBza2V3WCA9IF9yZWYuc2tld1gsXG4gICAgICBza2V3WSA9IF9yZWYuc2tld1ksXG4gICAgICBzY2FsZVggPSBfcmVmLnNjYWxlWCxcbiAgICAgIHNjYWxlWSA9IF9yZWYuc2NhbGVZLFxuICAgICAgdHJhbnNmb3JtUGVyc3BlY3RpdmUgPSBfcmVmLnRyYW5zZm9ybVBlcnNwZWN0aXZlLFxuICAgICAgZm9yY2UzRCA9IF9yZWYuZm9yY2UzRCxcbiAgICAgIHRhcmdldCA9IF9yZWYudGFyZ2V0LFxuICAgICAgek9yaWdpbiA9IF9yZWYuek9yaWdpbixcbiAgICAgIHRyYW5zZm9ybXMgPSBcIlwiLFxuICAgICAgdXNlM0QgPSBmb3JjZTNEID09PSBcImF1dG9cIiAmJiByYXRpbyAmJiByYXRpbyAhPT0gMSB8fCBmb3JjZTNEID09PSB0cnVlOyAvLyBTYWZhcmkgaGFzIGEgYnVnIHRoYXQgY2F1c2VzIGl0IG5vdCB0byByZW5kZXIgM0QgdHJhbnNmb3JtLW9yaWdpbiB2YWx1ZXMgcHJvcGVybHksIHNvIHdlIGZvcmNlIHRoZSB6IG9yaWdpbiB0byAwLCByZWNvcmQgaXQgaW4gdGhlIGNhY2hlLCBhbmQgdGhlbiBkbyB0aGUgbWF0aCBoZXJlIHRvIG9mZnNldCB0aGUgdHJhbnNsYXRlIHZhbHVlcyBhY2NvcmRpbmdseSAoYmFzaWNhbGx5IGRvIHRoZSAzRCB0cmFuc2Zvcm0tb3JpZ2luIHBhcnQgbWFudWFsbHkpXG5cblxuICBpZiAoek9yaWdpbiAmJiAocm90YXRpb25YICE9PSBfemVyb0RlZyB8fCByb3RhdGlvblkgIT09IF96ZXJvRGVnKSkge1xuICAgIHZhciBhbmdsZSA9IHBhcnNlRmxvYXQocm90YXRpb25ZKSAqIF9ERUcyUkFELFxuICAgICAgICBhMTMgPSBNYXRoLnNpbihhbmdsZSksXG4gICAgICAgIGEzMyA9IE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgY29zO1xuXG4gICAgYW5nbGUgPSBwYXJzZUZsb2F0KHJvdGF0aW9uWCkgKiBfREVHMlJBRDtcbiAgICBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgeCA9IF9hZGRQeFRyYW5zbGF0ZSh0YXJnZXQsIHgsIGExMyAqIGNvcyAqIC16T3JpZ2luKTtcbiAgICB5ID0gX2FkZFB4VHJhbnNsYXRlKHRhcmdldCwgeSwgLU1hdGguc2luKGFuZ2xlKSAqIC16T3JpZ2luKTtcbiAgICB6ID0gX2FkZFB4VHJhbnNsYXRlKHRhcmdldCwgeiwgYTMzICogY29zICogLXpPcmlnaW4gKyB6T3JpZ2luKTtcbiAgfVxuXG4gIGlmICh0cmFuc2Zvcm1QZXJzcGVjdGl2ZSAhPT0gX3plcm9QeCkge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJwZXJzcGVjdGl2ZShcIiArIHRyYW5zZm9ybVBlcnNwZWN0aXZlICsgX2VuZFBhcmVudGhlc2lzO1xuICB9XG5cbiAgaWYgKHhQZXJjZW50IHx8IHlQZXJjZW50KSB7XG4gICAgdHJhbnNmb3JtcyArPSBcInRyYW5zbGF0ZShcIiArIHhQZXJjZW50ICsgXCIlLCBcIiArIHlQZXJjZW50ICsgXCIlKSBcIjtcbiAgfVxuXG4gIGlmICh1c2UzRCB8fCB4ICE9PSBfemVyb1B4IHx8IHkgIT09IF96ZXJvUHggfHwgeiAhPT0gX3plcm9QeCkge1xuICAgIHRyYW5zZm9ybXMgKz0geiAhPT0gX3plcm9QeCB8fCB1c2UzRCA/IFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCIsIFwiICsgeSArIFwiLCBcIiArIHogKyBcIikgXCIgOiBcInRyYW5zbGF0ZShcIiArIHggKyBcIiwgXCIgKyB5ICsgX2VuZFBhcmVudGhlc2lzO1xuICB9XG5cbiAgaWYgKHJvdGF0aW9uICE9PSBfemVyb0RlZykge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJyb3RhdGUoXCIgKyByb3RhdGlvbiArIF9lbmRQYXJlbnRoZXNpcztcbiAgfVxuXG4gIGlmIChyb3RhdGlvblkgIT09IF96ZXJvRGVnKSB7XG4gICAgdHJhbnNmb3JtcyArPSBcInJvdGF0ZVkoXCIgKyByb3RhdGlvblkgKyBfZW5kUGFyZW50aGVzaXM7XG4gIH1cblxuICBpZiAocm90YXRpb25YICE9PSBfemVyb0RlZykge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJyb3RhdGVYKFwiICsgcm90YXRpb25YICsgX2VuZFBhcmVudGhlc2lzO1xuICB9XG5cbiAgaWYgKHNrZXdYICE9PSBfemVyb0RlZyB8fCBza2V3WSAhPT0gX3plcm9EZWcpIHtcbiAgICB0cmFuc2Zvcm1zICs9IFwic2tldyhcIiArIHNrZXdYICsgXCIsIFwiICsgc2tld1kgKyBfZW5kUGFyZW50aGVzaXM7XG4gIH1cblxuICBpZiAoc2NhbGVYICE9PSAxIHx8IHNjYWxlWSAhPT0gMSkge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJzY2FsZShcIiArIHNjYWxlWCArIFwiLCBcIiArIHNjYWxlWSArIF9lbmRQYXJlbnRoZXNpcztcbiAgfVxuXG4gIHRhcmdldC5zdHlsZVtfdHJhbnNmb3JtUHJvcF0gPSB0cmFuc2Zvcm1zIHx8IFwidHJhbnNsYXRlKDAsIDApXCI7XG59LFxuICAgIF9yZW5kZXJTVkdUcmFuc2Zvcm1zID0gZnVuY3Rpb24gX3JlbmRlclNWR1RyYW5zZm9ybXMocmF0aW8sIGNhY2hlKSB7XG4gIHZhciBfcmVmMiA9IGNhY2hlIHx8IHRoaXMsXG4gICAgICB4UGVyY2VudCA9IF9yZWYyLnhQZXJjZW50LFxuICAgICAgeVBlcmNlbnQgPSBfcmVmMi55UGVyY2VudCxcbiAgICAgIHggPSBfcmVmMi54LFxuICAgICAgeSA9IF9yZWYyLnksXG4gICAgICByb3RhdGlvbiA9IF9yZWYyLnJvdGF0aW9uLFxuICAgICAgc2tld1ggPSBfcmVmMi5za2V3WCxcbiAgICAgIHNrZXdZID0gX3JlZjIuc2tld1ksXG4gICAgICBzY2FsZVggPSBfcmVmMi5zY2FsZVgsXG4gICAgICBzY2FsZVkgPSBfcmVmMi5zY2FsZVksXG4gICAgICB0YXJnZXQgPSBfcmVmMi50YXJnZXQsXG4gICAgICB4T3JpZ2luID0gX3JlZjIueE9yaWdpbixcbiAgICAgIHlPcmlnaW4gPSBfcmVmMi55T3JpZ2luLFxuICAgICAgeE9mZnNldCA9IF9yZWYyLnhPZmZzZXQsXG4gICAgICB5T2Zmc2V0ID0gX3JlZjIueU9mZnNldCxcbiAgICAgIGZvcmNlQ1NTID0gX3JlZjIuZm9yY2VDU1MsXG4gICAgICB0eCA9IHBhcnNlRmxvYXQoeCksXG4gICAgICB0eSA9IHBhcnNlRmxvYXQoeSksXG4gICAgICBhMTEsXG4gICAgICBhMjEsXG4gICAgICBhMTIsXG4gICAgICBhMjIsXG4gICAgICB0ZW1wO1xuXG4gIHJvdGF0aW9uID0gcGFyc2VGbG9hdChyb3RhdGlvbik7XG4gIHNrZXdYID0gcGFyc2VGbG9hdChza2V3WCk7XG4gIHNrZXdZID0gcGFyc2VGbG9hdChza2V3WSk7XG5cbiAgaWYgKHNrZXdZKSB7XG4gICAgLy9mb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgd2UgY29tYmluZSBhbGwgc2tld2luZyBpbnRvIHRoZSBza2V3WCBhbmQgcm90YXRpb24gdmFsdWVzLiBSZW1lbWJlciwgYSBza2V3WSBvZiAxMCBkZWdyZWVzIGxvb2tzIHRoZSBzYW1lIGFzIGEgcm90YXRpb24gb2YgMTAgZGVncmVlcyBwbHVzIGEgc2tld1ggb2YgMTAgZGVncmVlcy5cbiAgICBza2V3WSA9IHBhcnNlRmxvYXQoc2tld1kpO1xuICAgIHNrZXdYICs9IHNrZXdZO1xuICAgIHJvdGF0aW9uICs9IHNrZXdZO1xuICB9XG5cbiAgaWYgKHJvdGF0aW9uIHx8IHNrZXdYKSB7XG4gICAgcm90YXRpb24gKj0gX0RFRzJSQUQ7XG4gICAgc2tld1ggKj0gX0RFRzJSQUQ7XG4gICAgYTExID0gTWF0aC5jb3Mocm90YXRpb24pICogc2NhbGVYO1xuICAgIGEyMSA9IE1hdGguc2luKHJvdGF0aW9uKSAqIHNjYWxlWDtcbiAgICBhMTIgPSBNYXRoLnNpbihyb3RhdGlvbiAtIHNrZXdYKSAqIC1zY2FsZVk7XG4gICAgYTIyID0gTWF0aC5jb3Mocm90YXRpb24gLSBza2V3WCkgKiBzY2FsZVk7XG5cbiAgICBpZiAoc2tld1gpIHtcbiAgICAgIHNrZXdZICo9IF9ERUcyUkFEO1xuICAgICAgdGVtcCA9IE1hdGgudGFuKHNrZXdYIC0gc2tld1kpO1xuICAgICAgdGVtcCA9IE1hdGguc3FydCgxICsgdGVtcCAqIHRlbXApO1xuICAgICAgYTEyICo9IHRlbXA7XG4gICAgICBhMjIgKj0gdGVtcDtcblxuICAgICAgaWYgKHNrZXdZKSB7XG4gICAgICAgIHRlbXAgPSBNYXRoLnRhbihza2V3WSk7XG4gICAgICAgIHRlbXAgPSBNYXRoLnNxcnQoMSArIHRlbXAgKiB0ZW1wKTtcbiAgICAgICAgYTExICo9IHRlbXA7XG4gICAgICAgIGEyMSAqPSB0ZW1wO1xuICAgICAgfVxuICAgIH1cblxuICAgIGExMSA9IF9yb3VuZChhMTEpO1xuICAgIGEyMSA9IF9yb3VuZChhMjEpO1xuICAgIGExMiA9IF9yb3VuZChhMTIpO1xuICAgIGEyMiA9IF9yb3VuZChhMjIpO1xuICB9IGVsc2Uge1xuICAgIGExMSA9IHNjYWxlWDtcbiAgICBhMjIgPSBzY2FsZVk7XG4gICAgYTIxID0gYTEyID0gMDtcbiAgfVxuXG4gIGlmICh0eCAmJiAhfih4ICsgXCJcIikuaW5kZXhPZihcInB4XCIpIHx8IHR5ICYmICF+KHkgKyBcIlwiKS5pbmRleE9mKFwicHhcIikpIHtcbiAgICB0eCA9IF9jb252ZXJ0VG9Vbml0KHRhcmdldCwgXCJ4XCIsIHgsIFwicHhcIik7XG4gICAgdHkgPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIFwieVwiLCB5LCBcInB4XCIpO1xuICB9XG5cbiAgaWYgKHhPcmlnaW4gfHwgeU9yaWdpbiB8fCB4T2Zmc2V0IHx8IHlPZmZzZXQpIHtcbiAgICB0eCA9IF9yb3VuZCh0eCArIHhPcmlnaW4gLSAoeE9yaWdpbiAqIGExMSArIHlPcmlnaW4gKiBhMTIpICsgeE9mZnNldCk7XG4gICAgdHkgPSBfcm91bmQodHkgKyB5T3JpZ2luIC0gKHhPcmlnaW4gKiBhMjEgKyB5T3JpZ2luICogYTIyKSArIHlPZmZzZXQpO1xuICB9XG5cbiAgaWYgKHhQZXJjZW50IHx8IHlQZXJjZW50KSB7XG4gICAgLy9UaGUgU1ZHIHNwZWMgZG9lc24ndCBzdXBwb3J0IHBlcmNlbnRhZ2UtYmFzZWQgdHJhbnNsYXRpb24gaW4gdGhlIFwidHJhbnNmb3JtXCIgYXR0cmlidXRlLCBzbyB3ZSBtZXJnZSBpdCBpbnRvIHRoZSB0cmFuc2xhdGlvbiB0byBzaW11bGF0ZSBpdC5cbiAgICB0ZW1wID0gdGFyZ2V0LmdldEJCb3goKTtcbiAgICB0eCA9IF9yb3VuZCh0eCArIHhQZXJjZW50IC8gMTAwICogdGVtcC53aWR0aCk7XG4gICAgdHkgPSBfcm91bmQodHkgKyB5UGVyY2VudCAvIDEwMCAqIHRlbXAuaGVpZ2h0KTtcbiAgfVxuXG4gIHRlbXAgPSBcIm1hdHJpeChcIiArIGExMSArIFwiLFwiICsgYTIxICsgXCIsXCIgKyBhMTIgKyBcIixcIiArIGEyMiArIFwiLFwiICsgdHggKyBcIixcIiArIHR5ICsgXCIpXCI7XG4gIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgdGVtcCk7XG4gIGZvcmNlQ1NTICYmICh0YXJnZXQuc3R5bGVbX3RyYW5zZm9ybVByb3BdID0gdGVtcCk7IC8vc29tZSBicm93c2VycyBwcmlvcml0aXplIENTUyB0cmFuc2Zvcm1zIG92ZXIgdGhlIHRyYW5zZm9ybSBhdHRyaWJ1dGUuIFdoZW4gd2Ugc2Vuc2UgdGhhdCB0aGUgdXNlciBoYXMgQ1NTIHRyYW5zZm9ybXMgYXBwbGllZCwgd2UgbXVzdCBvdmVyd3JpdGUgdGhlbSB0aGlzIHdheSAob3RoZXJ3aXNlIHNvbWUgYnJvd3NlciBzaW1wbHkgd29uJ3QgcmVuZGVyIHRoZSB0cmFuc2Zvcm0gYXR0cmlidXRlIGNoYW5nZXMhKVxufSxcbiAgICBfYWRkUm90YXRpb25hbFByb3BUd2VlbiA9IGZ1bmN0aW9uIF9hZGRSb3RhdGlvbmFsUHJvcFR3ZWVuKHBsdWdpbiwgdGFyZ2V0LCBwcm9wZXJ0eSwgc3RhcnROdW0sIGVuZFZhbHVlKSB7XG4gIHZhciBjYXAgPSAzNjAsXG4gICAgICBpc1N0cmluZyA9IF9pc1N0cmluZyhlbmRWYWx1ZSksXG4gICAgICBlbmROdW0gPSBwYXJzZUZsb2F0KGVuZFZhbHVlKSAqIChpc1N0cmluZyAmJiB+ZW5kVmFsdWUuaW5kZXhPZihcInJhZFwiKSA/IF9SQUQyREVHIDogMSksXG4gICAgICBjaGFuZ2UgPSBlbmROdW0gLSBzdGFydE51bSxcbiAgICAgIGZpbmFsVmFsdWUgPSBzdGFydE51bSArIGNoYW5nZSArIFwiZGVnXCIsXG4gICAgICBkaXJlY3Rpb24sXG4gICAgICBwdDtcblxuICBpZiAoaXNTdHJpbmcpIHtcbiAgICBkaXJlY3Rpb24gPSBlbmRWYWx1ZS5zcGxpdChcIl9cIilbMV07XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSBcInNob3J0XCIpIHtcbiAgICAgIGNoYW5nZSAlPSBjYXA7XG5cbiAgICAgIGlmIChjaGFuZ2UgIT09IGNoYW5nZSAlIChjYXAgLyAyKSkge1xuICAgICAgICBjaGFuZ2UgKz0gY2hhbmdlIDwgMCA/IGNhcCA6IC1jYXA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gXCJjd1wiICYmIGNoYW5nZSA8IDApIHtcbiAgICAgIGNoYW5nZSA9IChjaGFuZ2UgKyBjYXAgKiBfYmlnTnVtKSAlIGNhcCAtIH5+KGNoYW5nZSAvIGNhcCkgKiBjYXA7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09IFwiY2N3XCIgJiYgY2hhbmdlID4gMCkge1xuICAgICAgY2hhbmdlID0gKGNoYW5nZSAtIGNhcCAqIF9iaWdOdW0pICUgY2FwIC0gfn4oY2hhbmdlIC8gY2FwKSAqIGNhcDtcbiAgICB9XG4gIH1cblxuICBwbHVnaW4uX3B0ID0gcHQgPSBuZXcgUHJvcFR3ZWVuKHBsdWdpbi5fcHQsIHRhcmdldCwgcHJvcGVydHksIHN0YXJ0TnVtLCBjaGFuZ2UsIF9yZW5kZXJQcm9wV2l0aEVuZCk7XG4gIHB0LmUgPSBmaW5hbFZhbHVlO1xuICBwdC51ID0gXCJkZWdcIjtcblxuICBwbHVnaW4uX3Byb3BzLnB1c2gocHJvcGVydHkpO1xuXG4gIHJldHVybiBwdDtcbn0sXG4gICAgX2Fzc2lnbiA9IGZ1bmN0aW9uIF9hc3NpZ24odGFyZ2V0LCBzb3VyY2UpIHtcbiAgLy8gSW50ZXJuZXQgRXhwbG9yZXIgZG9lc24ndCBoYXZlIE9iamVjdC5hc3NpZ24oKSwgc28gd2UgcmVjcmVhdGUgaXQgaGVyZS5cbiAgZm9yICh2YXIgcCBpbiBzb3VyY2UpIHtcbiAgICB0YXJnZXRbcF0gPSBzb3VyY2VbcF07XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufSxcbiAgICBfYWRkUmF3VHJhbnNmb3JtUFRzID0gZnVuY3Rpb24gX2FkZFJhd1RyYW5zZm9ybVBUcyhwbHVnaW4sIHRyYW5zZm9ybXMsIHRhcmdldCkge1xuICAvL2ZvciBoYW5kbGluZyBjYXNlcyB3aGVyZSBzb21lb25lIHBhc3NlcyBpbiBhIHdob2xlIHRyYW5zZm9ybSBzdHJpbmcsIGxpa2UgdHJhbnNmb3JtOiBcInNjYWxlKDIsIDMpIHJvdGF0ZSgyMGRlZykgdHJhbnNsYXRlWSgzMGVtKVwiXG4gIHZhciBzdGFydENhY2hlID0gX2Fzc2lnbih7fSwgdGFyZ2V0Ll9nc2FwKSxcbiAgICAgIGV4Y2x1ZGUgPSBcInBlcnNwZWN0aXZlLGZvcmNlM0QsdHJhbnNmb3JtT3JpZ2luLHN2Z09yaWdpblwiLFxuICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICBlbmRDYWNoZSxcbiAgICAgIHAsXG4gICAgICBzdGFydFZhbHVlLFxuICAgICAgZW5kVmFsdWUsXG4gICAgICBzdGFydE51bSxcbiAgICAgIGVuZE51bSxcbiAgICAgIHN0YXJ0VW5pdCxcbiAgICAgIGVuZFVuaXQ7XG5cbiAgaWYgKHN0YXJ0Q2FjaGUuc3ZnKSB7XG4gICAgc3RhcnRWYWx1ZSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIik7XG4gICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcIlwiKTtcbiAgICBzdHlsZVtfdHJhbnNmb3JtUHJvcF0gPSB0cmFuc2Zvcm1zO1xuICAgIGVuZENhY2hlID0gX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgMSk7XG5cbiAgICBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtUHJvcCk7XG5cbiAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIHN0YXJ0VmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIHN0YXJ0VmFsdWUgPSBnZXRDb21wdXRlZFN0eWxlKHRhcmdldClbX3RyYW5zZm9ybVByb3BdO1xuICAgIHN0eWxlW190cmFuc2Zvcm1Qcm9wXSA9IHRyYW5zZm9ybXM7XG4gICAgZW5kQ2FjaGUgPSBfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCAxKTtcbiAgICBzdHlsZVtfdHJhbnNmb3JtUHJvcF0gPSBzdGFydFZhbHVlO1xuICB9XG5cbiAgZm9yIChwIGluIF90cmFuc2Zvcm1Qcm9wcykge1xuICAgIHN0YXJ0VmFsdWUgPSBzdGFydENhY2hlW3BdO1xuICAgIGVuZFZhbHVlID0gZW5kQ2FjaGVbcF07XG5cbiAgICBpZiAoc3RhcnRWYWx1ZSAhPT0gZW5kVmFsdWUgJiYgZXhjbHVkZS5pbmRleE9mKHApIDwgMCkge1xuICAgICAgLy90d2VlbmluZyB0byBubyBwZXJzcGVjdGl2ZSBnaXZlcyB2ZXJ5IHVuaW50dWl0aXZlIHJlc3VsdHMgLSBqdXN0IGtlZXAgdGhlIHNhbWUgcGVyc3BlY3RpdmUgaW4gdGhhdCBjYXNlLlxuICAgICAgc3RhcnRVbml0ID0gZ2V0VW5pdChzdGFydFZhbHVlKTtcbiAgICAgIGVuZFVuaXQgPSBnZXRVbml0KGVuZFZhbHVlKTtcbiAgICAgIHN0YXJ0TnVtID0gc3RhcnRVbml0ICE9PSBlbmRVbml0ID8gX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBwLCBzdGFydFZhbHVlLCBlbmRVbml0KSA6IHBhcnNlRmxvYXQoc3RhcnRWYWx1ZSk7XG4gICAgICBlbmROdW0gPSBwYXJzZUZsb2F0KGVuZFZhbHVlKTtcbiAgICAgIHBsdWdpbi5fcHQgPSBuZXcgUHJvcFR3ZWVuKHBsdWdpbi5fcHQsIGVuZENhY2hlLCBwLCBzdGFydE51bSwgZW5kTnVtIC0gc3RhcnROdW0sIF9yZW5kZXJDU1NQcm9wKTtcbiAgICAgIHBsdWdpbi5fcHQudSA9IGVuZFVuaXQgfHwgMDtcblxuICAgICAgcGx1Z2luLl9wcm9wcy5wdXNoKHApO1xuICAgIH1cbiAgfVxuXG4gIF9hc3NpZ24oZW5kQ2FjaGUsIHN0YXJ0Q2FjaGUpO1xufTsgLy8gaGFuZGxlIHNwbGl0dGluZyBhcGFydCBwYWRkaW5nLCBtYXJnaW4sIGJvcmRlcldpZHRoLCBhbmQgYm9yZGVyUmFkaXVzIGludG8gdGhlaXIgNCBjb21wb25lbnRzLiBGaXJlZm94LCBmb3IgZXhhbXBsZSwgd29uJ3QgcmVwb3J0IGJvcmRlclJhZGl1cyBjb3JyZWN0bHkgLSBpdCB3aWxsIG9ubHkgZG8gYm9yZGVyVG9wTGVmdFJhZGl1cyBhbmQgdGhlIG90aGVyIGNvcm5lcnMuIFdlIGFsc28gd2FudCB0byBoYW5kbGUgcGFkZGluZ1RvcCwgbWFyZ2luTGVmdCwgYm9yZGVyUmlnaHRXaWR0aCwgZXRjLlxuXG5cbl9mb3JFYWNoTmFtZShcInBhZGRpbmcsbWFyZ2luLFdpZHRoLFJhZGl1c1wiLCBmdW5jdGlvbiAobmFtZSwgaW5kZXgpIHtcbiAgdmFyIHQgPSBcIlRvcFwiLFxuICAgICAgciA9IFwiUmlnaHRcIixcbiAgICAgIGIgPSBcIkJvdHRvbVwiLFxuICAgICAgbCA9IFwiTGVmdFwiLFxuICAgICAgcHJvcHMgPSAoaW5kZXggPCAzID8gW3QsIHIsIGIsIGxdIDogW3QgKyBsLCB0ICsgciwgYiArIHIsIGIgKyBsXSkubWFwKGZ1bmN0aW9uIChzaWRlKSB7XG4gICAgcmV0dXJuIGluZGV4IDwgMiA/IG5hbWUgKyBzaWRlIDogXCJib3JkZXJcIiArIHNpZGUgKyBuYW1lO1xuICB9KTtcblxuICBfc3BlY2lhbFByb3BzW2luZGV4ID4gMSA/IFwiYm9yZGVyXCIgKyBuYW1lIDogbmFtZV0gPSBmdW5jdGlvbiAocGx1Z2luLCB0YXJnZXQsIHByb3BlcnR5LCBlbmRWYWx1ZSwgdHdlZW4pIHtcbiAgICB2YXIgYSwgdmFycztcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xuICAgICAgLy8gZ2V0dGVyLCBwYXNzZWQgdGFyZ2V0LCBwcm9wZXJ0eSwgYW5kIHVuaXQgKGZyb20gX2dldCgpKVxuICAgICAgYSA9IHByb3BzLm1hcChmdW5jdGlvbiAocHJvcCkge1xuICAgICAgICByZXR1cm4gX2dldChwbHVnaW4sIHByb3AsIHByb3BlcnR5KTtcbiAgICAgIH0pO1xuICAgICAgdmFycyA9IGEuam9pbihcIiBcIik7XG4gICAgICByZXR1cm4gdmFycy5zcGxpdChhWzBdKS5sZW5ndGggPT09IDUgPyBhWzBdIDogdmFycztcbiAgICB9XG5cbiAgICBhID0gKGVuZFZhbHVlICsgXCJcIikuc3BsaXQoXCIgXCIpO1xuICAgIHZhcnMgPSB7fTtcbiAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wLCBpKSB7XG4gICAgICByZXR1cm4gdmFyc1twcm9wXSA9IGFbaV0gPSBhW2ldIHx8IGFbKGkgLSAxKSAvIDIgfCAwXTtcbiAgICB9KTtcbiAgICBwbHVnaW4uaW5pdCh0YXJnZXQsIHZhcnMsIHR3ZWVuKTtcbiAgfTtcbn0pO1xuXG5leHBvcnQgdmFyIENTU1BsdWdpbiA9IHtcbiAgbmFtZTogXCJjc3NcIixcbiAgcmVnaXN0ZXI6IF9pbml0Q29yZSxcbiAgdGFyZ2V0VGVzdDogZnVuY3Rpb24gdGFyZ2V0VGVzdCh0YXJnZXQpIHtcbiAgICByZXR1cm4gdGFyZ2V0LnN0eWxlICYmIHRhcmdldC5ub2RlVHlwZTtcbiAgfSxcbiAgaW5pdDogZnVuY3Rpb24gaW5pdCh0YXJnZXQsIHZhcnMsIHR3ZWVuLCBpbmRleCwgdGFyZ2V0cykge1xuICAgIHZhciBwcm9wcyA9IHRoaXMuX3Byb3BzLFxuICAgICAgICBzdHlsZSA9IHRhcmdldC5zdHlsZSxcbiAgICAgICAgc3RhcnRBdCA9IHR3ZWVuLnZhcnMuc3RhcnRBdCxcbiAgICAgICAgc3RhcnRWYWx1ZSxcbiAgICAgICAgZW5kVmFsdWUsXG4gICAgICAgIGVuZE51bSxcbiAgICAgICAgc3RhcnROdW0sXG4gICAgICAgIHR5cGUsXG4gICAgICAgIHNwZWNpYWxQcm9wLFxuICAgICAgICBwLFxuICAgICAgICBzdGFydFVuaXQsXG4gICAgICAgIGVuZFVuaXQsXG4gICAgICAgIHJlbGF0aXZlLFxuICAgICAgICBpc1RyYW5zZm9ybVJlbGF0ZWQsXG4gICAgICAgIHRyYW5zZm9ybVByb3BUd2VlbixcbiAgICAgICAgY2FjaGUsXG4gICAgICAgIHNtb290aCxcbiAgICAgICAgaGFzUHJpb3JpdHksXG4gICAgICAgIGlubGluZVByb3BzO1xuICAgIF9wbHVnaW5Jbml0dGVkIHx8IF9pbml0Q29yZSgpOyAvLyB3ZSBtYXkgY2FsbCBpbml0KCkgbXVsdGlwbGUgdGltZXMgb24gdGhlIHNhbWUgcGx1Z2luIGluc3RhbmNlLCBsaWtlIHdoZW4gYWRkaW5nIHNwZWNpYWwgcHJvcGVydGllcywgc28gbWFrZSBzdXJlIHdlIGRvbid0IG92ZXJ3cml0ZSB0aGUgcmV2ZXJ0IGRhdGEgb3IgaW5saW5lUHJvcHNcblxuICAgIHRoaXMuc3R5bGVzID0gdGhpcy5zdHlsZXMgfHwgX2dldFN0eWxlU2F2ZXIodGFyZ2V0KTtcbiAgICBpbmxpbmVQcm9wcyA9IHRoaXMuc3R5bGVzLnByb3BzO1xuICAgIHRoaXMudHdlZW4gPSB0d2VlbjtcblxuICAgIGZvciAocCBpbiB2YXJzKSB7XG4gICAgICBpZiAocCA9PT0gXCJhdXRvUm91bmRcIikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgZW5kVmFsdWUgPSB2YXJzW3BdO1xuXG4gICAgICBpZiAoX3BsdWdpbnNbcF0gJiYgX2NoZWNrUGx1Z2luKHAsIHZhcnMsIHR3ZWVuLCBpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSkge1xuICAgICAgICAvLyBwbHVnaW5zXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0eXBlID0gdHlwZW9mIGVuZFZhbHVlO1xuICAgICAgc3BlY2lhbFByb3AgPSBfc3BlY2lhbFByb3BzW3BdO1xuXG4gICAgICBpZiAodHlwZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGVuZFZhbHVlID0gZW5kVmFsdWUuY2FsbCh0d2VlbiwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cyk7XG4gICAgICAgIHR5cGUgPSB0eXBlb2YgZW5kVmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlID09PSBcInN0cmluZ1wiICYmIH5lbmRWYWx1ZS5pbmRleE9mKFwicmFuZG9tKFwiKSkge1xuICAgICAgICBlbmRWYWx1ZSA9IF9yZXBsYWNlUmFuZG9tKGVuZFZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNwZWNpYWxQcm9wKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wKHRoaXMsIHRhcmdldCwgcCwgZW5kVmFsdWUsIHR3ZWVuKSAmJiAoaGFzUHJpb3JpdHkgPSAxKTtcbiAgICAgIH0gZWxzZSBpZiAocC5zdWJzdHIoMCwgMikgPT09IFwiLS1cIikge1xuICAgICAgICAvL0NTUyB2YXJpYWJsZVxuICAgICAgICBzdGFydFZhbHVlID0gKGdldENvbXB1dGVkU3R5bGUodGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKHApICsgXCJcIikudHJpbSgpO1xuICAgICAgICBlbmRWYWx1ZSArPSBcIlwiO1xuICAgICAgICBfY29sb3JFeHAubGFzdEluZGV4ID0gMDtcblxuICAgICAgICBpZiAoIV9jb2xvckV4cC50ZXN0KHN0YXJ0VmFsdWUpKSB7XG4gICAgICAgICAgLy8gY29sb3JzIGRvbid0IGhhdmUgdW5pdHNcbiAgICAgICAgICBzdGFydFVuaXQgPSBnZXRVbml0KHN0YXJ0VmFsdWUpO1xuICAgICAgICAgIGVuZFVuaXQgPSBnZXRVbml0KGVuZFZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVuZFVuaXQgPyBzdGFydFVuaXQgIT09IGVuZFVuaXQgJiYgKHN0YXJ0VmFsdWUgPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIHAsIHN0YXJ0VmFsdWUsIGVuZFVuaXQpICsgZW5kVW5pdCkgOiBzdGFydFVuaXQgJiYgKGVuZFZhbHVlICs9IHN0YXJ0VW5pdCk7XG4gICAgICAgIHRoaXMuYWRkKHN0eWxlLCBcInNldFByb3BlcnR5XCIsIHN0YXJ0VmFsdWUsIGVuZFZhbHVlLCBpbmRleCwgdGFyZ2V0cywgMCwgMCwgcCk7XG4gICAgICAgIHByb3BzLnB1c2gocCk7XG4gICAgICAgIGlubGluZVByb3BzLnB1c2gocCwgMCwgc3R5bGVbcF0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGlmIChzdGFydEF0ICYmIHAgaW4gc3RhcnRBdCkge1xuICAgICAgICAgIC8vIGluIGNhc2Ugc29tZW9uZSBoYXJkLWNvZGVzIGEgY29tcGxleCB2YWx1ZSBhcyB0aGUgc3RhcnQsIGxpa2UgdG9wOiBcImNhbGMoMnZoIC8gMilcIi4gV2l0aG91dCB0aGlzLCBpdCdkIHVzZSB0aGUgY29tcHV0ZWQgdmFsdWUgKGFsd2F5cyBpbiBweClcbiAgICAgICAgICBzdGFydFZhbHVlID0gdHlwZW9mIHN0YXJ0QXRbcF0gPT09IFwiZnVuY3Rpb25cIiA/IHN0YXJ0QXRbcF0uY2FsbCh0d2VlbiwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cykgOiBzdGFydEF0W3BdO1xuICAgICAgICAgIF9pc1N0cmluZyhzdGFydFZhbHVlKSAmJiB+c3RhcnRWYWx1ZS5pbmRleE9mKFwicmFuZG9tKFwiKSAmJiAoc3RhcnRWYWx1ZSA9IF9yZXBsYWNlUmFuZG9tKHN0YXJ0VmFsdWUpKTtcbiAgICAgICAgICBnZXRVbml0KHN0YXJ0VmFsdWUgKyBcIlwiKSB8fCAoc3RhcnRWYWx1ZSArPSBfY29uZmlnLnVuaXRzW3BdIHx8IGdldFVuaXQoX2dldCh0YXJnZXQsIHApKSB8fCBcIlwiKTsgLy8gZm9yIGNhc2VzIHdoZW4gc29tZW9uZSBwYXNzZXMgaW4gYSB1bml0bGVzcyB2YWx1ZSBsaWtlIHt4OiAxMDB9OyBpZiB3ZSB0cnkgc2V0dGluZyB0cmFuc2xhdGUoMTAwLCAwcHgpIGl0IHdvbid0IHdvcmsuXG5cbiAgICAgICAgICAoc3RhcnRWYWx1ZSArIFwiXCIpLmNoYXJBdCgxKSA9PT0gXCI9XCIgJiYgKHN0YXJ0VmFsdWUgPSBfZ2V0KHRhcmdldCwgcCkpOyAvLyBjYW4ndCB3b3JrIHdpdGggcmVsYXRpdmUgdmFsdWVzXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhcnRWYWx1ZSA9IF9nZXQodGFyZ2V0LCBwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXJ0TnVtID0gcGFyc2VGbG9hdChzdGFydFZhbHVlKTtcbiAgICAgICAgcmVsYXRpdmUgPSB0eXBlID09PSBcInN0cmluZ1wiICYmIGVuZFZhbHVlLmNoYXJBdCgxKSA9PT0gXCI9XCIgJiYgZW5kVmFsdWUuc3Vic3RyKDAsIDIpO1xuICAgICAgICByZWxhdGl2ZSAmJiAoZW5kVmFsdWUgPSBlbmRWYWx1ZS5zdWJzdHIoMikpO1xuICAgICAgICBlbmROdW0gPSBwYXJzZUZsb2F0KGVuZFZhbHVlKTtcblxuICAgICAgICBpZiAocCBpbiBfcHJvcGVydHlBbGlhc2VzKSB7XG4gICAgICAgICAgaWYgKHAgPT09IFwiYXV0b0FscGhhXCIpIHtcbiAgICAgICAgICAgIC8vc3BlY2lhbCBjYXNlIHdoZXJlIHdlIGNvbnRyb2wgdGhlIHZpc2liaWxpdHkgYWxvbmcgd2l0aCBvcGFjaXR5LiBXZSBzdGlsbCBhbGxvdyB0aGUgb3BhY2l0eSB2YWx1ZSB0byBwYXNzIHRocm91Z2ggYW5kIGdldCB0d2VlbmVkLlxuICAgICAgICAgICAgaWYgKHN0YXJ0TnVtID09PSAxICYmIF9nZXQodGFyZ2V0LCBcInZpc2liaWxpdHlcIikgPT09IFwiaGlkZGVuXCIgJiYgZW5kTnVtKSB7XG4gICAgICAgICAgICAgIC8vaWYgdmlzaWJpbGl0eSBpcyBpbml0aWFsbHkgc2V0IHRvIFwiaGlkZGVuXCIsIHdlIHNob3VsZCBpbnRlcnByZXQgdGhhdCBhcyBpbnRlbnQgdG8gbWFrZSBvcGFjaXR5IDAgKGEgY29udmVuaWVuY2UpXG4gICAgICAgICAgICAgIHN0YXJ0TnVtID0gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW5saW5lUHJvcHMucHVzaChcInZpc2liaWxpdHlcIiwgMCwgc3R5bGUudmlzaWJpbGl0eSk7XG5cbiAgICAgICAgICAgIF9hZGROb25Ud2VlbmluZ1BUKHRoaXMsIHN0eWxlLCBcInZpc2liaWxpdHlcIiwgc3RhcnROdW0gPyBcImluaGVyaXRcIiA6IFwiaGlkZGVuXCIsIGVuZE51bSA/IFwiaW5oZXJpdFwiIDogXCJoaWRkZW5cIiwgIWVuZE51bSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHAgIT09IFwic2NhbGVcIiAmJiBwICE9PSBcInRyYW5zZm9ybVwiKSB7XG4gICAgICAgICAgICBwID0gX3Byb3BlcnR5QWxpYXNlc1twXTtcbiAgICAgICAgICAgIH5wLmluZGV4T2YoXCIsXCIpICYmIChwID0gcC5zcGxpdChcIixcIilbMF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlzVHJhbnNmb3JtUmVsYXRlZCA9IHAgaW4gX3RyYW5zZm9ybVByb3BzOyAvLy0tLSBUUkFOU0ZPUk0tUkVMQVRFRCAtLS1cblxuICAgICAgICBpZiAoaXNUcmFuc2Zvcm1SZWxhdGVkKSB7XG4gICAgICAgICAgdGhpcy5zdHlsZXMuc2F2ZShwKTtcblxuICAgICAgICAgIGlmICghdHJhbnNmb3JtUHJvcFR3ZWVuKSB7XG4gICAgICAgICAgICBjYWNoZSA9IHRhcmdldC5fZ3NhcDtcbiAgICAgICAgICAgIGNhY2hlLnJlbmRlclRyYW5zZm9ybSAmJiAhdmFycy5wYXJzZVRyYW5zZm9ybSB8fCBfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCB2YXJzLnBhcnNlVHJhbnNmb3JtKTsgLy8gaWYsIGZvciBleGFtcGxlLCBnc2FwLnNldCguLi4ge3RyYW5zZm9ybTpcInRyYW5zbGF0ZVgoNTB2dylcIn0pLCB0aGUgX2dldCgpIGNhbGwgZG9lc24ndCBwYXJzZSB0aGUgdHJhbnNmb3JtLCB0aHVzIGNhY2hlLnJlbmRlclRyYW5zZm9ybSB3b24ndCBiZSBzZXQgeWV0IHNvIGZvcmNlIHRoZSBwYXJzaW5nIG9mIHRoZSB0cmFuc2Zvcm0gaGVyZS5cblxuICAgICAgICAgICAgc21vb3RoID0gdmFycy5zbW9vdGhPcmlnaW4gIT09IGZhbHNlICYmIGNhY2hlLnNtb290aDtcbiAgICAgICAgICAgIHRyYW5zZm9ybVByb3BUd2VlbiA9IHRoaXMuX3B0ID0gbmV3IFByb3BUd2Vlbih0aGlzLl9wdCwgc3R5bGUsIF90cmFuc2Zvcm1Qcm9wLCAwLCAxLCBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0sIGNhY2hlLCAwLCAtMSk7IC8vdGhlIGZpcnN0IHRpbWUgdGhyb3VnaCwgY3JlYXRlIHRoZSByZW5kZXJpbmcgUHJvcFR3ZWVuIHNvIHRoYXQgaXQgcnVucyBMQVNUIChpbiB0aGUgbGlua2VkIGxpc3QsIHdlIGtlZXAgYWRkaW5nIHRvIHRoZSBiZWdpbm5pbmcpXG5cbiAgICAgICAgICAgIHRyYW5zZm9ybVByb3BUd2Vlbi5kZXAgPSAxOyAvL2ZsYWcgaXQgYXMgZGVwZW5kZW50IHNvIHRoYXQgaWYgdGhpbmdzIGdldCBraWxsZWQvb3ZlcndyaXR0ZW4gYW5kIHRoaXMgaXMgdGhlIG9ubHkgUHJvcFR3ZWVuIGxlZnQsIHdlIGNhbiBzYWZlbHkga2lsbCB0aGUgd2hvbGUgdHdlZW4uXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHAgPT09IFwic2NhbGVcIikge1xuICAgICAgICAgICAgdGhpcy5fcHQgPSBuZXcgUHJvcFR3ZWVuKHRoaXMuX3B0LCBjYWNoZSwgXCJzY2FsZVlcIiwgY2FjaGUuc2NhbGVZLCAocmVsYXRpdmUgPyBfcGFyc2VSZWxhdGl2ZShjYWNoZS5zY2FsZVksIHJlbGF0aXZlICsgZW5kTnVtKSA6IGVuZE51bSkgLSBjYWNoZS5zY2FsZVkgfHwgMCwgX3JlbmRlckNTU1Byb3ApO1xuICAgICAgICAgICAgdGhpcy5fcHQudSA9IDA7XG4gICAgICAgICAgICBwcm9wcy5wdXNoKFwic2NhbGVZXCIsIHApO1xuICAgICAgICAgICAgcCArPSBcIlhcIjtcbiAgICAgICAgICB9IGVsc2UgaWYgKHAgPT09IFwidHJhbnNmb3JtT3JpZ2luXCIpIHtcbiAgICAgICAgICAgIGlubGluZVByb3BzLnB1c2goX3RyYW5zZm9ybU9yaWdpblByb3AsIDAsIHN0eWxlW190cmFuc2Zvcm1PcmlnaW5Qcm9wXSk7XG4gICAgICAgICAgICBlbmRWYWx1ZSA9IF9jb252ZXJ0S2V5d29yZHNUb1BlcmNlbnRhZ2VzKGVuZFZhbHVlKTsgLy9pbiBjYXNlIHNvbWV0aGluZyBsaWtlIFwibGVmdCB0b3BcIiBvciBcImJvdHRvbSByaWdodFwiIGlzIHBhc3NlZCBpbi4gQ29udmVydCB0byBwZXJjZW50YWdlcy5cblxuICAgICAgICAgICAgaWYgKGNhY2hlLnN2Zykge1xuICAgICAgICAgICAgICBfYXBwbHlTVkdPcmlnaW4odGFyZ2V0LCBlbmRWYWx1ZSwgMCwgc21vb3RoLCAwLCB0aGlzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGVuZFVuaXQgPSBwYXJzZUZsb2F0KGVuZFZhbHVlLnNwbGl0KFwiIFwiKVsyXSkgfHwgMDsgLy9oYW5kbGUgdGhlIHpPcmlnaW4gc2VwYXJhdGVseSFcblxuICAgICAgICAgICAgICBlbmRVbml0ICE9PSBjYWNoZS56T3JpZ2luICYmIF9hZGROb25Ud2VlbmluZ1BUKHRoaXMsIGNhY2hlLCBcInpPcmlnaW5cIiwgY2FjaGUuek9yaWdpbiwgZW5kVW5pdCk7XG5cbiAgICAgICAgICAgICAgX2FkZE5vblR3ZWVuaW5nUFQodGhpcywgc3R5bGUsIHAsIF9maXJzdFR3b09ubHkoc3RhcnRWYWx1ZSksIF9maXJzdFR3b09ubHkoZW5kVmFsdWUpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChwID09PSBcInN2Z09yaWdpblwiKSB7XG4gICAgICAgICAgICBfYXBwbHlTVkdPcmlnaW4odGFyZ2V0LCBlbmRWYWx1ZSwgMSwgc21vb3RoLCAwLCB0aGlzKTtcblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChwIGluIF9yb3RhdGlvbmFsUHJvcGVydGllcykge1xuICAgICAgICAgICAgX2FkZFJvdGF0aW9uYWxQcm9wVHdlZW4odGhpcywgY2FjaGUsIHAsIHN0YXJ0TnVtLCByZWxhdGl2ZSA/IF9wYXJzZVJlbGF0aXZlKHN0YXJ0TnVtLCByZWxhdGl2ZSArIGVuZFZhbHVlKSA6IGVuZFZhbHVlKTtcblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChwID09PSBcInNtb290aE9yaWdpblwiKSB7XG4gICAgICAgICAgICBfYWRkTm9uVHdlZW5pbmdQVCh0aGlzLCBjYWNoZSwgXCJzbW9vdGhcIiwgY2FjaGUuc21vb3RoLCBlbmRWYWx1ZSk7XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocCA9PT0gXCJmb3JjZTNEXCIpIHtcbiAgICAgICAgICAgIGNhY2hlW3BdID0gZW5kVmFsdWU7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHAgPT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgICAgICAgIF9hZGRSYXdUcmFuc2Zvcm1QVHModGhpcywgZW5kVmFsdWUsIHRhcmdldCk7XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghKHAgaW4gc3R5bGUpKSB7XG4gICAgICAgICAgcCA9IF9jaGVja1Byb3BQcmVmaXgocCkgfHwgcDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1RyYW5zZm9ybVJlbGF0ZWQgfHwgKGVuZE51bSB8fCBlbmROdW0gPT09IDApICYmIChzdGFydE51bSB8fCBzdGFydE51bSA9PT0gMCkgJiYgIV9jb21wbGV4RXhwLnRlc3QoZW5kVmFsdWUpICYmIHAgaW4gc3R5bGUpIHtcbiAgICAgICAgICBzdGFydFVuaXQgPSAoc3RhcnRWYWx1ZSArIFwiXCIpLnN1YnN0cigoc3RhcnROdW0gKyBcIlwiKS5sZW5ndGgpO1xuICAgICAgICAgIGVuZE51bSB8fCAoZW5kTnVtID0gMCk7IC8vIHByb3RlY3QgYWdhaW5zdCBOYU5cblxuICAgICAgICAgIGVuZFVuaXQgPSBnZXRVbml0KGVuZFZhbHVlKSB8fCAocCBpbiBfY29uZmlnLnVuaXRzID8gX2NvbmZpZy51bml0c1twXSA6IHN0YXJ0VW5pdCk7XG4gICAgICAgICAgc3RhcnRVbml0ICE9PSBlbmRVbml0ICYmIChzdGFydE51bSA9IF9jb252ZXJ0VG9Vbml0KHRhcmdldCwgcCwgc3RhcnRWYWx1ZSwgZW5kVW5pdCkpO1xuICAgICAgICAgIHRoaXMuX3B0ID0gbmV3IFByb3BUd2Vlbih0aGlzLl9wdCwgaXNUcmFuc2Zvcm1SZWxhdGVkID8gY2FjaGUgOiBzdHlsZSwgcCwgc3RhcnROdW0sIChyZWxhdGl2ZSA/IF9wYXJzZVJlbGF0aXZlKHN0YXJ0TnVtLCByZWxhdGl2ZSArIGVuZE51bSkgOiBlbmROdW0pIC0gc3RhcnROdW0sICFpc1RyYW5zZm9ybVJlbGF0ZWQgJiYgKGVuZFVuaXQgPT09IFwicHhcIiB8fCBwID09PSBcInpJbmRleFwiKSAmJiB2YXJzLmF1dG9Sb3VuZCAhPT0gZmFsc2UgPyBfcmVuZGVyUm91bmRlZENTU1Byb3AgOiBfcmVuZGVyQ1NTUHJvcCk7XG4gICAgICAgICAgdGhpcy5fcHQudSA9IGVuZFVuaXQgfHwgMDtcblxuICAgICAgICAgIGlmIChzdGFydFVuaXQgIT09IGVuZFVuaXQgJiYgZW5kVW5pdCAhPT0gXCIlXCIpIHtcbiAgICAgICAgICAgIC8vd2hlbiB0aGUgdHdlZW4gZ29lcyBhbGwgdGhlIHdheSBiYWNrIHRvIHRoZSBiZWdpbm5pbmcsIHdlIG5lZWQgdG8gcmV2ZXJ0IGl0IHRvIHRoZSBPTEQvT1JJR0lOQUwgdmFsdWUgKHdpdGggdGhvc2UgdW5pdHMpLiBXZSByZWNvcmQgdGhhdCBhcyBhIFwiYlwiIChiZWdpbm5pbmcpIHByb3BlcnR5IGFuZCBwb2ludCB0byBhIHJlbmRlciBtZXRob2QgdGhhdCBoYW5kbGVzIHRoYXQuIChwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24pXG4gICAgICAgICAgICB0aGlzLl9wdC5iID0gc3RhcnRWYWx1ZTtcbiAgICAgICAgICAgIHRoaXMuX3B0LnIgPSBfcmVuZGVyQ1NTUHJvcFdpdGhCZWdpbm5pbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEocCBpbiBzdHlsZSkpIHtcbiAgICAgICAgICBpZiAocCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgIC8vbWF5YmUgaXQncyBub3QgYSBzdHlsZSAtIGl0IGNvdWxkIGJlIGEgcHJvcGVydHkgYWRkZWQgZGlyZWN0bHkgdG8gYW4gZWxlbWVudCBpbiB3aGljaCBjYXNlIHdlJ2xsIHRyeSB0byBhbmltYXRlIHRoYXQuXG4gICAgICAgICAgICB0aGlzLmFkZCh0YXJnZXQsIHAsIHN0YXJ0VmFsdWUgfHwgdGFyZ2V0W3BdLCByZWxhdGl2ZSA/IHJlbGF0aXZlICsgZW5kVmFsdWUgOiBlbmRWYWx1ZSwgaW5kZXgsIHRhcmdldHMpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocCAhPT0gXCJwYXJzZVRyYW5zZm9ybVwiKSB7XG4gICAgICAgICAgICBfbWlzc2luZ1BsdWdpbihwLCBlbmRWYWx1ZSk7XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nLmNhbGwodGhpcywgdGFyZ2V0LCBwLCBzdGFydFZhbHVlLCByZWxhdGl2ZSA/IHJlbGF0aXZlICsgZW5kVmFsdWUgOiBlbmRWYWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpc1RyYW5zZm9ybVJlbGF0ZWQgfHwgKHAgaW4gc3R5bGUgPyBpbmxpbmVQcm9wcy5wdXNoKHAsIDAsIHN0eWxlW3BdKSA6IGlubGluZVByb3BzLnB1c2gocCwgMSwgc3RhcnRWYWx1ZSB8fCB0YXJnZXRbcF0pKTtcbiAgICAgICAgcHJvcHMucHVzaChwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNQcmlvcml0eSAmJiBfc29ydFByb3BUd2VlbnNCeVByaW9yaXR5KHRoaXMpO1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcihyYXRpbywgZGF0YSkge1xuICAgIGlmIChkYXRhLnR3ZWVuLl90aW1lIHx8ICFfcmV2ZXJ0aW5nKCkpIHtcbiAgICAgIHZhciBwdCA9IGRhdGEuX3B0O1xuXG4gICAgICB3aGlsZSAocHQpIHtcbiAgICAgICAgcHQucihyYXRpbywgcHQuZCk7XG4gICAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEuc3R5bGVzLnJldmVydCgpO1xuICAgIH1cbiAgfSxcbiAgZ2V0OiBfZ2V0LFxuICBhbGlhc2VzOiBfcHJvcGVydHlBbGlhc2VzLFxuICBnZXRTZXR0ZXI6IGZ1bmN0aW9uIGdldFNldHRlcih0YXJnZXQsIHByb3BlcnR5LCBwbHVnaW4pIHtcbiAgICAvL3JldHVybnMgYSBzZXR0ZXIgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHRhcmdldCwgcHJvcGVydHksIHZhbHVlIGFuZCBhcHBsaWVzIGl0IGFjY29yZGluZ2x5LiBSZW1lbWJlciwgcHJvcGVydGllcyBsaWtlIFwieFwiIGFyZW4ndCBhcyBzaW1wbGUgYXMgdGFyZ2V0LnN0eWxlLnByb3BlcnR5ID0gdmFsdWUgYmVjYXVzZSB0aGV5J3ZlIGdvdCB0byBiZSBhcHBsaWVkIHRvIGEgcHJveHkgb2JqZWN0IGFuZCB0aGVuIG1lcmdlZCBpbnRvIGEgdHJhbnNmb3JtIHN0cmluZyBpbiBhIHJlbmRlcmVyLlxuICAgIHZhciBwID0gX3Byb3BlcnR5QWxpYXNlc1twcm9wZXJ0eV07XG4gICAgcCAmJiBwLmluZGV4T2YoXCIsXCIpIDwgMCAmJiAocHJvcGVydHkgPSBwKTtcbiAgICByZXR1cm4gcHJvcGVydHkgaW4gX3RyYW5zZm9ybVByb3BzICYmIHByb3BlcnR5ICE9PSBfdHJhbnNmb3JtT3JpZ2luUHJvcCAmJiAodGFyZ2V0Ll9nc2FwLnggfHwgX2dldCh0YXJnZXQsIFwieFwiKSkgPyBwbHVnaW4gJiYgX3JlY2VudFNldHRlclBsdWdpbiA9PT0gcGx1Z2luID8gcHJvcGVydHkgPT09IFwic2NhbGVcIiA/IF9zZXR0ZXJTY2FsZSA6IF9zZXR0ZXJUcmFuc2Zvcm0gOiAoX3JlY2VudFNldHRlclBsdWdpbiA9IHBsdWdpbiB8fCB7fSkgJiYgKHByb3BlcnR5ID09PSBcInNjYWxlXCIgPyBfc2V0dGVyU2NhbGVXaXRoUmVuZGVyIDogX3NldHRlclRyYW5zZm9ybVdpdGhSZW5kZXIpIDogdGFyZ2V0LnN0eWxlICYmICFfaXNVbmRlZmluZWQodGFyZ2V0LnN0eWxlW3Byb3BlcnR5XSkgPyBfc2V0dGVyQ1NTU3R5bGUgOiB+cHJvcGVydHkuaW5kZXhPZihcIi1cIikgPyBfc2V0dGVyQ1NTUHJvcCA6IF9nZXRTZXR0ZXIodGFyZ2V0LCBwcm9wZXJ0eSk7XG4gIH0sXG4gIGNvcmU6IHtcbiAgICBfcmVtb3ZlUHJvcGVydHk6IF9yZW1vdmVQcm9wZXJ0eSxcbiAgICBfZ2V0TWF0cml4OiBfZ2V0TWF0cml4XG4gIH1cbn07XG5nc2FwLnV0aWxzLmNoZWNrUHJlZml4ID0gX2NoZWNrUHJvcFByZWZpeDtcbmdzYXAuY29yZS5nZXRTdHlsZVNhdmVyID0gX2dldFN0eWxlU2F2ZXI7XG5cbihmdW5jdGlvbiAocG9zaXRpb25BbmRTY2FsZSwgcm90YXRpb24sIG90aGVycywgYWxpYXNlcykge1xuICB2YXIgYWxsID0gX2ZvckVhY2hOYW1lKHBvc2l0aW9uQW5kU2NhbGUgKyBcIixcIiArIHJvdGF0aW9uICsgXCIsXCIgKyBvdGhlcnMsIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgX3RyYW5zZm9ybVByb3BzW25hbWVdID0gMTtcbiAgfSk7XG5cbiAgX2ZvckVhY2hOYW1lKHJvdGF0aW9uLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIF9jb25maWcudW5pdHNbbmFtZV0gPSBcImRlZ1wiO1xuICAgIF9yb3RhdGlvbmFsUHJvcGVydGllc1tuYW1lXSA9IDE7XG4gIH0pO1xuXG4gIF9wcm9wZXJ0eUFsaWFzZXNbYWxsWzEzXV0gPSBwb3NpdGlvbkFuZFNjYWxlICsgXCIsXCIgKyByb3RhdGlvbjtcblxuICBfZm9yRWFjaE5hbWUoYWxpYXNlcywgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgc3BsaXQgPSBuYW1lLnNwbGl0KFwiOlwiKTtcbiAgICBfcHJvcGVydHlBbGlhc2VzW3NwbGl0WzFdXSA9IGFsbFtzcGxpdFswXV07XG4gIH0pO1xufSkoXCJ4LHkseixzY2FsZSxzY2FsZVgsc2NhbGVZLHhQZXJjZW50LHlQZXJjZW50XCIsIFwicm90YXRpb24scm90YXRpb25YLHJvdGF0aW9uWSxza2V3WCxza2V3WVwiLCBcInRyYW5zZm9ybSx0cmFuc2Zvcm1PcmlnaW4sc3ZnT3JpZ2luLGZvcmNlM0Qsc21vb3RoT3JpZ2luLHRyYW5zZm9ybVBlcnNwZWN0aXZlXCIsIFwiMDp0cmFuc2xhdGVYLDE6dHJhbnNsYXRlWSwyOnRyYW5zbGF0ZVosODpyb3RhdGUsODpyb3RhdGlvblosODpyb3RhdGVaLDk6cm90YXRlWCwxMDpyb3RhdGVZXCIpO1xuXG5fZm9yRWFjaE5hbWUoXCJ4LHkseix0b3AscmlnaHQsYm90dG9tLGxlZnQsd2lkdGgsaGVpZ2h0LGZvbnRTaXplLHBhZGRpbmcsbWFyZ2luLHBlcnNwZWN0aXZlXCIsIGZ1bmN0aW9uIChuYW1lKSB7XG4gIF9jb25maWcudW5pdHNbbmFtZV0gPSBcInB4XCI7XG59KTtcblxuZ3NhcC5yZWdpc3RlclBsdWdpbihDU1NQbHVnaW4pO1xuZXhwb3J0IHsgQ1NTUGx1Z2luIGFzIGRlZmF1bHQsIF9nZXRCQm94LCBfY3JlYXRlRWxlbWVudCwgX2NoZWNrUHJvcFByZWZpeCBhcyBjaGVja1ByZWZpeCB9OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/gsap/CSSPlugin.js\n"); /***/ }), /***/ "./node_modules/gsap/Observer.js": /*!***************************************!*\ !*** ./node_modules/gsap/Observer.js ***! \***************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Observer\": () => (/* binding */ Observer),\n/* harmony export */ \"_getProxyProp\": () => (/* binding */ _getProxyProp),\n/* harmony export */ \"_getScrollFunc\": () => (/* binding */ _getScrollFunc),\n/* harmony export */ \"_getTarget\": () => (/* binding */ _getTarget),\n/* harmony export */ \"_getVelocityProp\": () => (/* binding */ _getVelocityProp),\n/* harmony export */ \"_horizontal\": () => (/* binding */ _horizontal),\n/* harmony export */ \"_isViewport\": () => (/* binding */ _isViewport),\n/* harmony export */ \"_proxies\": () => (/* binding */ _proxies),\n/* harmony export */ \"_scrollers\": () => (/* binding */ _scrollers),\n/* harmony export */ \"_vertical\": () => (/* binding */ _vertical),\n/* harmony export */ \"default\": () => (/* binding */ Observer)\n/* harmony export */ });\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/*!\n * Observer 3.11.5\n * https://greensock.com\n *\n * @license Copyright 2008-2023, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n\n/* eslint-disable */\nvar gsap,\n _coreInitted,\n _clamp,\n _win,\n _doc,\n _docEl,\n _body,\n _isTouch,\n _pointerType,\n ScrollTrigger,\n _root,\n _normalizer,\n _eventTypes,\n _context,\n _getGSAP = function _getGSAP() {\n return gsap || typeof window !== \"undefined\" && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n _passThrough = function _passThrough(p) {\n return p;\n},\n _startup = 1,\n _observers = [],\n _scrollers = [],\n _proxies = [],\n _getTime = Date.now,\n _bridge = function _bridge(name, value) {\n return value;\n},\n _integrate = function _integrate() {\n var core = ScrollTrigger.core,\n data = core.bridge || {},\n scrollers = core._scrollers,\n proxies = core._proxies;\n scrollers.push.apply(scrollers, _scrollers);\n proxies.push.apply(proxies, _proxies);\n _scrollers = scrollers;\n _proxies = proxies;\n\n _bridge = function _bridge(name, value) {\n return data[name](value);\n };\n},\n _getProxyProp = function _getProxyProp(element, property) {\n return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];\n},\n _isViewport = function _isViewport(el) {\n return !!~_root.indexOf(el);\n},\n _addListener = function _addListener(element, type, func, nonPassive, capture) {\n return element.addEventListener(type, func, {\n passive: !nonPassive,\n capture: !!capture\n });\n},\n _removeListener = function _removeListener(element, type, func, capture) {\n return element.removeEventListener(type, func, !!capture);\n},\n _scrollLeft = \"scrollLeft\",\n _scrollTop = \"scrollTop\",\n _onScroll = function _onScroll() {\n return _normalizer && _normalizer.isPressed || _scrollers.cache++;\n},\n _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {\n var cachingFunc = function cachingFunc(value) {\n // since reading the scrollTop/scrollLeft/pageOffsetY/pageOffsetX can trigger a layout, this function allows us to cache the value so it only gets read fresh after a \"scroll\" event fires (or while we're refreshing because that can lengthen the page and alter the scroll position). when \"soft\" is true, that means don't actually set the scroll, but cache the new value instead (useful in ScrollSmoother)\n if (value || value === 0) {\n _startup && (_win.history.scrollRestoration = \"manual\"); // otherwise the new position will get overwritten by the browser onload.\n\n var isNormalizing = _normalizer && _normalizer.isPressed;\n value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0); //TODO: iOS Bug: if you allow it to go to 0, Safari can start to report super strange (wildly inaccurate) touch positions!\n\n f(value);\n cachingFunc.cacheID = _scrollers.cache;\n isNormalizing && _bridge(\"ss\", value); // set scroll (notify ScrollTrigger so it can dispatch a \"scrollStart\" event if necessary\n } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge(\"ref\")) {\n cachingFunc.cacheID = _scrollers.cache;\n cachingFunc.v = f();\n }\n\n return cachingFunc.v + cachingFunc.offset;\n };\n\n cachingFunc.offset = 0;\n return f && cachingFunc;\n},\n _horizontal = {\n s: _scrollLeft,\n p: \"left\",\n p2: \"Left\",\n os: \"right\",\n os2: \"Right\",\n d: \"width\",\n d2: \"Width\",\n a: \"x\",\n sc: _scrollCacheFunc(function (value) {\n return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;\n })\n},\n _vertical = {\n s: _scrollTop,\n p: \"top\",\n p2: \"Top\",\n os: \"bottom\",\n os2: \"Bottom\",\n d: \"height\",\n d2: \"Height\",\n a: \"y\",\n op: _horizontal,\n sc: _scrollCacheFunc(function (value) {\n return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;\n })\n},\n _getTarget = function _getTarget(t) {\n return gsap.utils.toArray(t)[0] || (typeof t === \"string\" && gsap.config().nullTargetWarn !== false ? console.warn(\"Element not found:\", t) : null);\n},\n _getScrollFunc = function _getScrollFunc(element, _ref) {\n var s = _ref.s,\n sc = _ref.sc;\n // we store the scroller functions in an alternating sequenced Array like [element, verticalScrollFunc, horizontalScrollFunc, ...] so that we can minimize memory, maximize performance, and we also record the last position as a \".rec\" property in order to revert to that after refreshing to ensure things don't shift around.\n _isViewport(element) && (element = _doc.scrollingElement || _docEl);\n\n var i = _scrollers.indexOf(element),\n offset = sc === _vertical.sc ? 1 : 2;\n\n !~i && (i = _scrollers.push(element) - 1);\n _scrollers[i + offset] || element.addEventListener(\"scroll\", _onScroll); // clear the cache when a scroll occurs\n\n var prev = _scrollers[i + offset],\n func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {\n return arguments.length ? element[s] = value : element[s];\n })));\n func.target = element;\n prev || (func.smooth = gsap.getProperty(element, \"scrollBehavior\") === \"smooth\"); // only set it the first time (don't reset every time a scrollFunc is requested because perhaps it happens during a refresh() when it's disabled in ScrollTrigger.\n\n return func;\n},\n _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {\n var v1 = value,\n v2 = value,\n t1 = _getTime(),\n t2 = t1,\n min = minTimeRefresh || 50,\n dropToZeroTime = Math.max(500, min * 3),\n update = function update(value, force) {\n var t = _getTime();\n\n if (force || t - t1 > min) {\n v2 = v1;\n v1 = value;\n t2 = t1;\n t1 = t;\n } else if (useDelta) {\n v1 += value;\n } else {\n // not totally necessary, but makes it a bit more accurate by adjusting the v1 value according to the new slope. This way we're not just ignoring the incoming data. Removing for now because it doesn't seem to make much practical difference and it's probably not worth the kb.\n v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);\n }\n },\n reset = function reset() {\n v2 = v1 = useDelta ? 0 : v1;\n t2 = t1 = 0;\n },\n getVelocity = function getVelocity(latestValue) {\n var tOld = t2,\n vOld = v2,\n t = _getTime();\n\n (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);\n return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;\n };\n\n return {\n update: update,\n reset: reset,\n getVelocity: getVelocity\n };\n},\n _getEvent = function _getEvent(e, preventDefault) {\n preventDefault && !e._gsapAllow && e.preventDefault();\n return e.changedTouches ? e.changedTouches[0] : e;\n},\n _getAbsoluteMax = function _getAbsoluteMax(a) {\n var max = Math.max.apply(Math, a),\n min = Math.min.apply(Math, a);\n return Math.abs(max) >= Math.abs(min) ? max : min;\n},\n _setScrollTrigger = function _setScrollTrigger() {\n ScrollTrigger = gsap.core.globals().ScrollTrigger;\n ScrollTrigger && ScrollTrigger.core && _integrate();\n},\n _initCore = function _initCore(core) {\n gsap = core || _getGSAP();\n\n if (gsap && typeof document !== \"undefined\" && document.body) {\n _win = window;\n _doc = document;\n _docEl = _doc.documentElement;\n _body = _doc.body;\n _root = [_win, _doc, _docEl, _body];\n _clamp = gsap.utils.clamp;\n\n _context = gsap.core.context || function () {};\n\n _pointerType = \"onpointerenter\" in _body ? \"pointer\" : \"mouse\"; // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer.\n\n _isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia(\"(hover: none), (pointer: coarse)\").matches ? 1 : \"ontouchstart\" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;\n _eventTypes = Observer.eventTypes = (\"ontouchstart\" in _docEl ? \"touchstart,touchmove,touchcancel,touchend\" : !(\"onpointerdown\" in _docEl) ? \"mousedown,mousemove,mouseup,mouseup\" : \"pointerdown,pointermove,pointercancel,pointerup\").split(\",\");\n setTimeout(function () {\n return _startup = 0;\n }, 500);\n\n _setScrollTrigger();\n\n _coreInitted = 1;\n }\n\n return _coreInitted;\n};\n\n_horizontal.op = _vertical;\n_scrollers.cache = 0;\nvar Observer = /*#__PURE__*/function () {\n function Observer(vars) {\n this.init(vars);\n }\n\n var _proto = Observer.prototype;\n\n _proto.init = function init(vars) {\n _coreInitted || _initCore(gsap) || console.warn(\"Please gsap.registerPlugin(Observer)\");\n ScrollTrigger || _setScrollTrigger();\n var tolerance = vars.tolerance,\n dragMinimum = vars.dragMinimum,\n type = vars.type,\n target = vars.target,\n lineHeight = vars.lineHeight,\n debounce = vars.debounce,\n preventDefault = vars.preventDefault,\n onStop = vars.onStop,\n onStopDelay = vars.onStopDelay,\n ignore = vars.ignore,\n wheelSpeed = vars.wheelSpeed,\n event = vars.event,\n onDragStart = vars.onDragStart,\n onDragEnd = vars.onDragEnd,\n onDrag = vars.onDrag,\n onPress = vars.onPress,\n onRelease = vars.onRelease,\n onRight = vars.onRight,\n onLeft = vars.onLeft,\n onUp = vars.onUp,\n onDown = vars.onDown,\n onChangeX = vars.onChangeX,\n onChangeY = vars.onChangeY,\n onChange = vars.onChange,\n onToggleX = vars.onToggleX,\n onToggleY = vars.onToggleY,\n onHover = vars.onHover,\n onHoverEnd = vars.onHoverEnd,\n onMove = vars.onMove,\n ignoreCheck = vars.ignoreCheck,\n isNormalizer = vars.isNormalizer,\n onGestureStart = vars.onGestureStart,\n onGestureEnd = vars.onGestureEnd,\n onWheel = vars.onWheel,\n onEnable = vars.onEnable,\n onDisable = vars.onDisable,\n onClick = vars.onClick,\n scrollSpeed = vars.scrollSpeed,\n capture = vars.capture,\n allowClicks = vars.allowClicks,\n lockAxis = vars.lockAxis,\n onLockAxis = vars.onLockAxis;\n this.target = target = _getTarget(target) || _docEl;\n this.vars = vars;\n ignore && (ignore = gsap.utils.toArray(ignore));\n tolerance = tolerance || 1e-9;\n dragMinimum = dragMinimum || 0;\n wheelSpeed = wheelSpeed || 1;\n scrollSpeed = scrollSpeed || 1;\n type = type || \"wheel,touch,pointer\";\n debounce = debounce !== false;\n lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22); // note: browser may report \"normal\", so default to 22.\n\n var id,\n onStopDelayedCall,\n dragged,\n moved,\n wheeled,\n locked,\n axis,\n self = this,\n prevDeltaX = 0,\n prevDeltaY = 0,\n scrollFuncX = _getScrollFunc(target, _horizontal),\n scrollFuncY = _getScrollFunc(target, _vertical),\n scrollX = scrollFuncX(),\n scrollY = scrollFuncY(),\n limitToTouch = ~type.indexOf(\"touch\") && !~type.indexOf(\"pointer\") && _eventTypes[0] === \"pointerdown\",\n // for devices that accommodate mouse events and touch events, we need to distinguish.\n isViewport = _isViewport(target),\n ownerDoc = target.ownerDocument || _doc,\n deltaX = [0, 0, 0],\n // wheel, scroll, pointer/touch\n deltaY = [0, 0, 0],\n onClickTime = 0,\n clickCapture = function clickCapture() {\n return onClickTime = _getTime();\n },\n _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {\n return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== \"touch\" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);\n },\n onStopFunc = function onStopFunc() {\n self._vx.reset();\n\n self._vy.reset();\n\n onStopDelayedCall.pause();\n onStop && onStop(self);\n },\n update = function update() {\n var dx = self.deltaX = _getAbsoluteMax(deltaX),\n dy = self.deltaY = _getAbsoluteMax(deltaY),\n changedX = Math.abs(dx) >= tolerance,\n changedY = Math.abs(dy) >= tolerance;\n\n onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY); // in ScrollTrigger.normalizeScroll(), we need to know if it was touch/pointer so we need access to the deltaX/deltaY Arrays before we clear them out.\n\n if (changedX) {\n onRight && self.deltaX > 0 && onRight(self);\n onLeft && self.deltaX < 0 && onLeft(self);\n onChangeX && onChangeX(self);\n onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);\n prevDeltaX = self.deltaX;\n deltaX[0] = deltaX[1] = deltaX[2] = 0;\n }\n\n if (changedY) {\n onDown && self.deltaY > 0 && onDown(self);\n onUp && self.deltaY < 0 && onUp(self);\n onChangeY && onChangeY(self);\n onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);\n prevDeltaY = self.deltaY;\n deltaY[0] = deltaY[1] = deltaY[2] = 0;\n }\n\n if (moved || dragged) {\n onMove && onMove(self);\n\n if (dragged) {\n onDrag(self);\n dragged = false;\n }\n\n moved = false;\n }\n\n locked && !(locked = false) && onLockAxis && onLockAxis(self);\n\n if (wheeled) {\n onWheel(self);\n wheeled = false;\n }\n\n id = 0;\n },\n onDelta = function onDelta(x, y, index) {\n deltaX[index] += x;\n deltaY[index] += y;\n\n self._vx.update(x);\n\n self._vy.update(y);\n\n debounce ? id || (id = requestAnimationFrame(update)) : update();\n },\n onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {\n if (lockAxis && !axis) {\n self.axis = axis = Math.abs(x) > Math.abs(y) ? \"x\" : \"y\";\n locked = true;\n }\n\n if (axis !== \"y\") {\n deltaX[2] += x;\n\n self._vx.update(x, true); // update the velocity as frequently as possible instead of in the debounced function so that very quick touch-scrolls (flicks) feel natural. If it's the mouse/touch/pointer, force it so that we get snappy/accurate momentum scroll.\n\n }\n\n if (axis !== \"x\") {\n deltaY[2] += y;\n\n self._vy.update(y, true);\n }\n\n debounce ? id || (id = requestAnimationFrame(update)) : update();\n },\n _onDrag = function _onDrag(e) {\n if (_ignoreCheck(e, 1)) {\n return;\n }\n\n e = _getEvent(e, preventDefault);\n var x = e.clientX,\n y = e.clientY,\n dx = x - self.x,\n dy = y - self.y,\n isDragging = self.isDragging;\n self.x = x;\n self.y = y;\n\n if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) {\n onDrag && (dragged = true);\n isDragging || (self.isDragging = true);\n onTouchOrPointerDelta(dx, dy);\n isDragging || onDragStart && onDragStart(self);\n }\n },\n _onPress = self.onPress = function (e) {\n if (_ignoreCheck(e, 1) || e && e.button) {\n return;\n }\n\n self.axis = axis = null;\n onStopDelayedCall.pause();\n self.isPressed = true;\n e = _getEvent(e); // note: may need to preventDefault(?) Won't side-scroll on iOS Safari if we do, though.\n\n prevDeltaX = prevDeltaY = 0;\n self.startX = self.x = e.clientX;\n self.startY = self.y = e.clientY;\n\n self._vx.reset(); // otherwise the t2 may be stale if the user touches and flicks super fast and releases in less than 2 requestAnimationFrame ticks, causing velocity to be 0.\n\n\n self._vy.reset();\n\n _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, preventDefault, true);\n\n self.deltaX = self.deltaY = 0;\n onPress && onPress(self);\n },\n _onRelease = self.onRelease = function (e) {\n if (_ignoreCheck(e, 1)) {\n return;\n }\n\n _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n\n var isTrackingDrag = !isNaN(self.y - self.startY),\n wasDragging = self.isDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),\n // some touch devices need some wiggle room in terms of sensing clicks - the finger may move a few pixels.\n eventData = _getEvent(e);\n\n if (!wasDragging && isTrackingDrag) {\n self._vx.reset();\n\n self._vy.reset();\n\n if (preventDefault && allowClicks) {\n gsap.delayedCall(0.08, function () {\n // some browsers (like Firefox) won't trust script-generated clicks, so if the user tries to click on a video to play it, for example, it simply won't work. Since a regular \"click\" event will most likely be generated anyway (one that has its isTrusted flag set to true), we must slightly delay our script-generated click so that the \"real\"/trusted one is prioritized. Remember, when there are duplicate events in quick succession, we suppress all but the first one. Some browsers don't even trigger the \"real\" one at all, so our synthetic one is a safety valve that ensures that no matter what, a click event does get dispatched.\n if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {\n if (e.target.click) {\n //some browsers (like mobile Safari) don't properly trigger the click event\n e.target.click();\n } else if (ownerDoc.createEvent) {\n var syntheticEvent = ownerDoc.createEvent(\"MouseEvents\");\n syntheticEvent.initMouseEvent(\"click\", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);\n e.target.dispatchEvent(syntheticEvent);\n }\n }\n });\n }\n }\n\n self.isDragging = self.isGesturing = self.isPressed = false;\n onStop && !isNormalizer && onStopDelayedCall.restart(true);\n onDragEnd && wasDragging && onDragEnd(self);\n onRelease && onRelease(self, wasDragging);\n },\n _onGestureStart = function _onGestureStart(e) {\n return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);\n },\n _onGestureEnd = function _onGestureEnd() {\n return (self.isGesturing = false) || onGestureEnd(self);\n },\n onScroll = function onScroll(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n var x = scrollFuncX(),\n y = scrollFuncY();\n onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);\n scrollX = x;\n scrollY = y;\n onStop && onStopDelayedCall.restart(true);\n },\n _onWheel = function _onWheel(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n e = _getEvent(e, preventDefault);\n onWheel && (wheeled = true);\n var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed;\n onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);\n onStop && !isNormalizer && onStopDelayedCall.restart(true);\n },\n _onMove = function _onMove(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n var x = e.clientX,\n y = e.clientY,\n dx = x - self.x,\n dy = y - self.y;\n self.x = x;\n self.y = y;\n moved = true;\n (dx || dy) && onTouchOrPointerDelta(dx, dy);\n },\n _onHover = function _onHover(e) {\n self.event = e;\n onHover(self);\n },\n _onHoverEnd = function _onHoverEnd(e) {\n self.event = e;\n onHoverEnd(self);\n },\n _onClick = function _onClick(e) {\n return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);\n };\n\n onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();\n self.deltaX = self.deltaY = 0;\n self._vx = _getVelocityProp(0, 50, true);\n self._vy = _getVelocityProp(0, 50, true);\n self.scrollX = scrollFuncX;\n self.scrollY = scrollFuncY;\n self.isDragging = self.isGesturing = self.isPressed = false;\n\n _context(this);\n\n self.enable = function (e) {\n if (!self.isEnabled) {\n _addListener(isViewport ? ownerDoc : target, \"scroll\", _onScroll);\n\n type.indexOf(\"scroll\") >= 0 && _addListener(isViewport ? ownerDoc : target, \"scroll\", onScroll, preventDefault, capture);\n type.indexOf(\"wheel\") >= 0 && _addListener(target, \"wheel\", _onWheel, preventDefault, capture);\n\n if (type.indexOf(\"touch\") >= 0 && _isTouch || type.indexOf(\"pointer\") >= 0) {\n _addListener(target, _eventTypes[0], _onPress, preventDefault, capture);\n\n _addListener(ownerDoc, _eventTypes[2], _onRelease);\n\n _addListener(ownerDoc, _eventTypes[3], _onRelease);\n\n allowClicks && _addListener(target, \"click\", clickCapture, false, true);\n onClick && _addListener(target, \"click\", _onClick);\n onGestureStart && _addListener(ownerDoc, \"gesturestart\", _onGestureStart);\n onGestureEnd && _addListener(ownerDoc, \"gestureend\", _onGestureEnd);\n onHover && _addListener(target, _pointerType + \"enter\", _onHover);\n onHoverEnd && _addListener(target, _pointerType + \"leave\", _onHoverEnd);\n onMove && _addListener(target, _pointerType + \"move\", _onMove);\n }\n\n self.isEnabled = true;\n e && e.type && _onPress(e);\n onEnable && onEnable(self);\n }\n\n return self;\n };\n\n self.disable = function () {\n if (self.isEnabled) {\n // only remove the _onScroll listener if there aren't any others that rely on the functionality.\n _observers.filter(function (o) {\n return o !== self && _isViewport(o.target);\n }).length || _removeListener(isViewport ? ownerDoc : target, \"scroll\", _onScroll);\n\n if (self.isPressed) {\n self._vx.reset();\n\n self._vy.reset();\n\n _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n }\n\n _removeListener(isViewport ? ownerDoc : target, \"scroll\", onScroll, capture);\n\n _removeListener(target, \"wheel\", _onWheel, capture);\n\n _removeListener(target, _eventTypes[0], _onPress, capture);\n\n _removeListener(ownerDoc, _eventTypes[2], _onRelease);\n\n _removeListener(ownerDoc, _eventTypes[3], _onRelease);\n\n _removeListener(target, \"click\", clickCapture, true);\n\n _removeListener(target, \"click\", _onClick);\n\n _removeListener(ownerDoc, \"gesturestart\", _onGestureStart);\n\n _removeListener(ownerDoc, \"gestureend\", _onGestureEnd);\n\n _removeListener(target, _pointerType + \"enter\", _onHover);\n\n _removeListener(target, _pointerType + \"leave\", _onHoverEnd);\n\n _removeListener(target, _pointerType + \"move\", _onMove);\n\n self.isEnabled = self.isPressed = self.isDragging = false;\n onDisable && onDisable(self);\n }\n };\n\n self.kill = self.revert = function () {\n self.disable();\n\n var i = _observers.indexOf(self);\n\n i >= 0 && _observers.splice(i, 1);\n _normalizer === self && (_normalizer = 0);\n };\n\n _observers.push(self);\n\n isNormalizer && _isViewport(target) && (_normalizer = self);\n self.enable(event);\n };\n\n _createClass(Observer, [{\n key: \"velocityX\",\n get: function get() {\n return this._vx.getVelocity();\n }\n }, {\n key: \"velocityY\",\n get: function get() {\n return this._vy.getVelocity();\n }\n }]);\n\n return Observer;\n}();\nObserver.version = \"3.11.5\";\n\nObserver.create = function (vars) {\n return new Observer(vars);\n};\n\nObserver.register = _initCore;\n\nObserver.getAll = function () {\n return _observers.slice();\n};\n\nObserver.getById = function (id) {\n return _observers.filter(function (o) {\n return o.vars.id === id;\n })[0];\n};\n\n_getGSAP() && gsap.registerPlugin(Observer);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9PYnNlcnZlci5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUE0QyxnQkFBZ0Isa0JBQWtCLE9BQU8sMkJBQTJCLHdEQUF3RCxnQ0FBZ0MsdURBQXVEOztBQUUvUCw4REFBOEQsc0VBQXNFLDhEQUE4RDs7QUFFbE07QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStEOztBQUUvRDtBQUNBLDZGQUE2Rjs7QUFFN0Y7QUFDQTtBQUNBLDZDQUE2QztBQUM3QyxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkVBQTJFOztBQUUzRTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxvRkFBb0Y7O0FBRXBGO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG9FQUFvRTs7QUFFcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEZBQTRGOztBQUU1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvRkFBb0Y7O0FBRXBGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQ0FBa0M7O0FBRWxDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7O0FBRXhCO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0I7OztBQUd4Qjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ad2VhcmVhdGhsb24vZnJvbnRlbmQtd2VicGFjay1ib2lsZXJwbGF0ZS8uL25vZGVfbW9kdWxlcy9nc2FwL09ic2VydmVyLmpzPzY2YzMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG4vKiFcbiAqIE9ic2VydmVyIDMuMTEuNVxuICogaHR0cHM6Ly9ncmVlbnNvY2suY29tXG4gKlxuICogQGxpY2Vuc2UgQ29weXJpZ2h0IDIwMDgtMjAyMywgR3JlZW5Tb2NrLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU3ViamVjdCB0byB0aGUgdGVybXMgYXQgaHR0cHM6Ly9ncmVlbnNvY2suY29tL3N0YW5kYXJkLWxpY2Vuc2Ugb3IgZm9yXG4gKiBDbHViIEdyZWVuU29jayBtZW1iZXJzLCB0aGUgYWdyZWVtZW50IGlzc3VlZCB3aXRoIHRoYXQgbWVtYmVyc2hpcC5cbiAqIEBhdXRob3I6IEphY2sgRG95bGUsIGphY2tAZ3JlZW5zb2NrLmNvbVxuKi9cblxuLyogZXNsaW50LWRpc2FibGUgKi9cbnZhciBnc2FwLFxuICAgIF9jb3JlSW5pdHRlZCxcbiAgICBfY2xhbXAsXG4gICAgX3dpbixcbiAgICBfZG9jLFxuICAgIF9kb2NFbCxcbiAgICBfYm9keSxcbiAgICBfaXNUb3VjaCxcbiAgICBfcG9pbnRlclR5cGUsXG4gICAgU2Nyb2xsVHJpZ2dlcixcbiAgICBfcm9vdCxcbiAgICBfbm9ybWFsaXplcixcbiAgICBfZXZlbnRUeXBlcyxcbiAgICBfY29udGV4dCxcbiAgICBfZ2V0R1NBUCA9IGZ1bmN0aW9uIF9nZXRHU0FQKCkge1xuICByZXR1cm4gZ3NhcCB8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIChnc2FwID0gd2luZG93LmdzYXApICYmIGdzYXAucmVnaXN0ZXJQbHVnaW4gJiYgZ3NhcDtcbn0sXG4gICAgX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24gX3Bhc3NUaHJvdWdoKHApIHtcbiAgcmV0dXJuIHA7XG59LFxuICAgIF9zdGFydHVwID0gMSxcbiAgICBfb2JzZXJ2ZXJzID0gW10sXG4gICAgX3Njcm9sbGVycyA9IFtdLFxuICAgIF9wcm94aWVzID0gW10sXG4gICAgX2dldFRpbWUgPSBEYXRlLm5vdyxcbiAgICBfYnJpZGdlID0gZnVuY3Rpb24gX2JyaWRnZShuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gdmFsdWU7XG59LFxuICAgIF9pbnRlZ3JhdGUgPSBmdW5jdGlvbiBfaW50ZWdyYXRlKCkge1xuICB2YXIgY29yZSA9IFNjcm9sbFRyaWdnZXIuY29yZSxcbiAgICAgIGRhdGEgPSBjb3JlLmJyaWRnZSB8fCB7fSxcbiAgICAgIHNjcm9sbGVycyA9IGNvcmUuX3Njcm9sbGVycyxcbiAgICAgIHByb3hpZXMgPSBjb3JlLl9wcm94aWVzO1xuICBzY3JvbGxlcnMucHVzaC5hcHBseShzY3JvbGxlcnMsIF9zY3JvbGxlcnMpO1xuICBwcm94aWVzLnB1c2guYXBwbHkocHJveGllcywgX3Byb3hpZXMpO1xuICBfc2Nyb2xsZXJzID0gc2Nyb2xsZXJzO1xuICBfcHJveGllcyA9IHByb3hpZXM7XG5cbiAgX2JyaWRnZSA9IGZ1bmN0aW9uIF9icmlkZ2UobmFtZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gZGF0YVtuYW1lXSh2YWx1ZSk7XG4gIH07XG59LFxuICAgIF9nZXRQcm94eVByb3AgPSBmdW5jdGlvbiBfZ2V0UHJveHlQcm9wKGVsZW1lbnQsIHByb3BlcnR5KSB7XG4gIHJldHVybiB+X3Byb3hpZXMuaW5kZXhPZihlbGVtZW50KSAmJiBfcHJveGllc1tfcHJveGllcy5pbmRleE9mKGVsZW1lbnQpICsgMV1bcHJvcGVydHldO1xufSxcbiAgICBfaXNWaWV3cG9ydCA9IGZ1bmN0aW9uIF9pc1ZpZXdwb3J0KGVsKSB7XG4gIHJldHVybiAhIX5fcm9vdC5pbmRleE9mKGVsKTtcbn0sXG4gICAgX2FkZExpc3RlbmVyID0gZnVuY3Rpb24gX2FkZExpc3RlbmVyKGVsZW1lbnQsIHR5cGUsIGZ1bmMsIG5vblBhc3NpdmUsIGNhcHR1cmUpIHtcbiAgcmV0dXJuIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBmdW5jLCB7XG4gICAgcGFzc2l2ZTogIW5vblBhc3NpdmUsXG4gICAgY2FwdHVyZTogISFjYXB0dXJlXG4gIH0pO1xufSxcbiAgICBfcmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiBfcmVtb3ZlTGlzdGVuZXIoZWxlbWVudCwgdHlwZSwgZnVuYywgY2FwdHVyZSkge1xuICByZXR1cm4gZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGZ1bmMsICEhY2FwdHVyZSk7XG59LFxuICAgIF9zY3JvbGxMZWZ0ID0gXCJzY3JvbGxMZWZ0XCIsXG4gICAgX3Njcm9sbFRvcCA9IFwic2Nyb2xsVG9wXCIsXG4gICAgX29uU2Nyb2xsID0gZnVuY3Rpb24gX29uU2Nyb2xsKCkge1xuICByZXR1cm4gX25vcm1hbGl6ZXIgJiYgX25vcm1hbGl6ZXIuaXNQcmVzc2VkIHx8IF9zY3JvbGxlcnMuY2FjaGUrKztcbn0sXG4gICAgX3Njcm9sbENhY2hlRnVuYyA9IGZ1bmN0aW9uIF9zY3JvbGxDYWNoZUZ1bmMoZiwgZG9Ob3RDYWNoZSkge1xuICB2YXIgY2FjaGluZ0Z1bmMgPSBmdW5jdGlvbiBjYWNoaW5nRnVuYyh2YWx1ZSkge1xuICAgIC8vIHNpbmNlIHJlYWRpbmcgdGhlIHNjcm9sbFRvcC9zY3JvbGxMZWZ0L3BhZ2VPZmZzZXRZL3BhZ2VPZmZzZXRYIGNhbiB0cmlnZ2VyIGEgbGF5b3V0LCB0aGlzIGZ1bmN0aW9uIGFsbG93cyB1cyB0byBjYWNoZSB0aGUgdmFsdWUgc28gaXQgb25seSBnZXRzIHJlYWQgZnJlc2ggYWZ0ZXIgYSBcInNjcm9sbFwiIGV2ZW50IGZpcmVzIChvciB3aGlsZSB3ZSdyZSByZWZyZXNoaW5nIGJlY2F1c2UgdGhhdCBjYW4gbGVuZ3RoZW4gdGhlIHBhZ2UgYW5kIGFsdGVyIHRoZSBzY3JvbGwgcG9zaXRpb24pLiB3aGVuIFwic29mdFwiIGlzIHRydWUsIHRoYXQgbWVhbnMgZG9uJ3QgYWN0dWFsbHkgc2V0IHRoZSBzY3JvbGwsIGJ1dCBjYWNoZSB0aGUgbmV3IHZhbHVlIGluc3RlYWQgKHVzZWZ1bCBpbiBTY3JvbGxTbW9vdGhlcilcbiAgICBpZiAodmFsdWUgfHwgdmFsdWUgPT09IDApIHtcbiAgICAgIF9zdGFydHVwICYmIChfd2luLmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBcIm1hbnVhbFwiKTsgLy8gb3RoZXJ3aXNlIHRoZSBuZXcgcG9zaXRpb24gd2lsbCBnZXQgb3ZlcndyaXR0ZW4gYnkgdGhlIGJyb3dzZXIgb25sb2FkLlxuXG4gICAgICB2YXIgaXNOb3JtYWxpemluZyA9IF9ub3JtYWxpemVyICYmIF9ub3JtYWxpemVyLmlzUHJlc3NlZDtcbiAgICAgIHZhbHVlID0gY2FjaGluZ0Z1bmMudiA9IE1hdGgucm91bmQodmFsdWUpIHx8IChfbm9ybWFsaXplciAmJiBfbm9ybWFsaXplci5pT1MgPyAxIDogMCk7IC8vVE9ETzogaU9TIEJ1ZzogaWYgeW91IGFsbG93IGl0IHRvIGdvIHRvIDAsIFNhZmFyaSBjYW4gc3RhcnQgdG8gcmVwb3J0IHN1cGVyIHN0cmFuZ2UgKHdpbGRseSBpbmFjY3VyYXRlKSB0b3VjaCBwb3NpdGlvbnMhXG5cbiAgICAgIGYodmFsdWUpO1xuICAgICAgY2FjaGluZ0Z1bmMuY2FjaGVJRCA9IF9zY3JvbGxlcnMuY2FjaGU7XG4gICAgICBpc05vcm1hbGl6aW5nICYmIF9icmlkZ2UoXCJzc1wiLCB2YWx1ZSk7IC8vIHNldCBzY3JvbGwgKG5vdGlmeSBTY3JvbGxUcmlnZ2VyIHNvIGl0IGNhbiBkaXNwYXRjaCBhIFwic2Nyb2xsU3RhcnRcIiBldmVudCBpZiBuZWNlc3NhcnlcbiAgICB9IGVsc2UgaWYgKGRvTm90Q2FjaGUgfHwgX3Njcm9sbGVycy5jYWNoZSAhPT0gY2FjaGluZ0Z1bmMuY2FjaGVJRCB8fCBfYnJpZGdlKFwicmVmXCIpKSB7XG4gICAgICBjYWNoaW5nRnVuYy5jYWNoZUlEID0gX3Njcm9sbGVycy5jYWNoZTtcbiAgICAgIGNhY2hpbmdGdW5jLnYgPSBmKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhY2hpbmdGdW5jLnYgKyBjYWNoaW5nRnVuYy5vZmZzZXQ7XG4gIH07XG5cbiAgY2FjaGluZ0Z1bmMub2Zmc2V0ID0gMDtcbiAgcmV0dXJuIGYgJiYgY2FjaGluZ0Z1bmM7XG59LFxuICAgIF9ob3Jpem9udGFsID0ge1xuICBzOiBfc2Nyb2xsTGVmdCxcbiAgcDogXCJsZWZ0XCIsXG4gIHAyOiBcIkxlZnRcIixcbiAgb3M6IFwicmlnaHRcIixcbiAgb3MyOiBcIlJpZ2h0XCIsXG4gIGQ6IFwid2lkdGhcIixcbiAgZDI6IFwiV2lkdGhcIixcbiAgYTogXCJ4XCIsXG4gIHNjOiBfc2Nyb2xsQ2FjaGVGdW5jKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gX3dpbi5zY3JvbGxUbyh2YWx1ZSwgX3ZlcnRpY2FsLnNjKCkpIDogX3dpbi5wYWdlWE9mZnNldCB8fCBfZG9jW19zY3JvbGxMZWZ0XSB8fCBfZG9jRWxbX3Njcm9sbExlZnRdIHx8IF9ib2R5W19zY3JvbGxMZWZ0XSB8fCAwO1xuICB9KVxufSxcbiAgICBfdmVydGljYWwgPSB7XG4gIHM6IF9zY3JvbGxUb3AsXG4gIHA6IFwidG9wXCIsXG4gIHAyOiBcIlRvcFwiLFxuICBvczogXCJib3R0b21cIixcbiAgb3MyOiBcIkJvdHRvbVwiLFxuICBkOiBcImhlaWdodFwiLFxuICBkMjogXCJIZWlnaHRcIixcbiAgYTogXCJ5XCIsXG4gIG9wOiBfaG9yaXpvbnRhbCxcbiAgc2M6IF9zY3JvbGxDYWNoZUZ1bmMoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBfd2luLnNjcm9sbFRvKF9ob3Jpem9udGFsLnNjKCksIHZhbHVlKSA6IF93aW4ucGFnZVlPZmZzZXQgfHwgX2RvY1tfc2Nyb2xsVG9wXSB8fCBfZG9jRWxbX3Njcm9sbFRvcF0gfHwgX2JvZHlbX3Njcm9sbFRvcF0gfHwgMDtcbiAgfSlcbn0sXG4gICAgX2dldFRhcmdldCA9IGZ1bmN0aW9uIF9nZXRUYXJnZXQodCkge1xuICByZXR1cm4gZ3NhcC51dGlscy50b0FycmF5KHQpWzBdIHx8ICh0eXBlb2YgdCA9PT0gXCJzdHJpbmdcIiAmJiBnc2FwLmNvbmZpZygpLm51bGxUYXJnZXRXYXJuICE9PSBmYWxzZSA/IGNvbnNvbGUud2FybihcIkVsZW1lbnQgbm90IGZvdW5kOlwiLCB0KSA6IG51bGwpO1xufSxcbiAgICBfZ2V0U2Nyb2xsRnVuYyA9IGZ1bmN0aW9uIF9nZXRTY3JvbGxGdW5jKGVsZW1lbnQsIF9yZWYpIHtcbiAgdmFyIHMgPSBfcmVmLnMsXG4gICAgICBzYyA9IF9yZWYuc2M7XG4gIC8vIHdlIHN0b3JlIHRoZSBzY3JvbGxlciBmdW5jdGlvbnMgaW4gYW4gYWx0ZXJuYXRpbmcgc2VxdWVuY2VkIEFycmF5IGxpa2UgW2VsZW1lbnQsIHZlcnRpY2FsU2Nyb2xsRnVuYywgaG9yaXpvbnRhbFNjcm9sbEZ1bmMsIC4uLl0gc28gdGhhdCB3ZSBjYW4gbWluaW1pemUgbWVtb3J5LCBtYXhpbWl6ZSBwZXJmb3JtYW5jZSwgYW5kIHdlIGFsc28gcmVjb3JkIHRoZSBsYXN0IHBvc2l0aW9uIGFzIGEgXCIucmVjXCIgcHJvcGVydHkgaW4gb3JkZXIgdG8gcmV2ZXJ0IHRvIHRoYXQgYWZ0ZXIgcmVmcmVzaGluZyB0byBlbnN1cmUgdGhpbmdzIGRvbid0IHNoaWZ0IGFyb3VuZC5cbiAgX2lzVmlld3BvcnQoZWxlbWVudCkgJiYgKGVsZW1lbnQgPSBfZG9jLnNjcm9sbGluZ0VsZW1lbnQgfHwgX2RvY0VsKTtcblxuICB2YXIgaSA9IF9zY3JvbGxlcnMuaW5kZXhPZihlbGVtZW50KSxcbiAgICAgIG9mZnNldCA9IHNjID09PSBfdmVydGljYWwuc2MgPyAxIDogMjtcblxuICAhfmkgJiYgKGkgPSBfc2Nyb2xsZXJzLnB1c2goZWxlbWVudCkgLSAxKTtcbiAgX3Njcm9sbGVyc1tpICsgb2Zmc2V0XSB8fCBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTsgLy8gY2xlYXIgdGhlIGNhY2hlIHdoZW4gYSBzY3JvbGwgb2NjdXJzXG5cbiAgdmFyIHByZXYgPSBfc2Nyb2xsZXJzW2kgKyBvZmZzZXRdLFxuICAgICAgZnVuYyA9IHByZXYgfHwgKF9zY3JvbGxlcnNbaSArIG9mZnNldF0gPSBfc2Nyb2xsQ2FjaGVGdW5jKF9nZXRQcm94eVByb3AoZWxlbWVudCwgcyksIHRydWUpIHx8IChfaXNWaWV3cG9ydChlbGVtZW50KSA/IHNjIDogX3Njcm9sbENhY2hlRnVuYyhmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGVsZW1lbnRbc10gPSB2YWx1ZSA6IGVsZW1lbnRbc107XG4gIH0pKSk7XG4gIGZ1bmMudGFyZ2V0ID0gZWxlbWVudDtcbiAgcHJldiB8fCAoZnVuYy5zbW9vdGggPSBnc2FwLmdldFByb3BlcnR5KGVsZW1lbnQsIFwic2Nyb2xsQmVoYXZpb3JcIikgPT09IFwic21vb3RoXCIpOyAvLyBvbmx5IHNldCBpdCB0aGUgZmlyc3QgdGltZSAoZG9uJ3QgcmVzZXQgZXZlcnkgdGltZSBhIHNjcm9sbEZ1bmMgaXMgcmVxdWVzdGVkIGJlY2F1c2UgcGVyaGFwcyBpdCBoYXBwZW5zIGR1cmluZyBhIHJlZnJlc2goKSB3aGVuIGl0J3MgZGlzYWJsZWQgaW4gU2Nyb2xsVHJpZ2dlci5cblxuICByZXR1cm4gZnVuYztcbn0sXG4gICAgX2dldFZlbG9jaXR5UHJvcCA9IGZ1bmN0aW9uIF9nZXRWZWxvY2l0eVByb3AodmFsdWUsIG1pblRpbWVSZWZyZXNoLCB1c2VEZWx0YSkge1xuICB2YXIgdjEgPSB2YWx1ZSxcbiAgICAgIHYyID0gdmFsdWUsXG4gICAgICB0MSA9IF9nZXRUaW1lKCksXG4gICAgICB0MiA9IHQxLFxuICAgICAgbWluID0gbWluVGltZVJlZnJlc2ggfHwgNTAsXG4gICAgICBkcm9wVG9aZXJvVGltZSA9IE1hdGgubWF4KDUwMCwgbWluICogMyksXG4gICAgICB1cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUodmFsdWUsIGZvcmNlKSB7XG4gICAgdmFyIHQgPSBfZ2V0VGltZSgpO1xuXG4gICAgaWYgKGZvcmNlIHx8IHQgLSB0MSA+IG1pbikge1xuICAgICAgdjIgPSB2MTtcbiAgICAgIHYxID0gdmFsdWU7XG4gICAgICB0MiA9IHQxO1xuICAgICAgdDEgPSB0O1xuICAgIH0gZWxzZSBpZiAodXNlRGVsdGEpIHtcbiAgICAgIHYxICs9IHZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3QgdG90YWxseSBuZWNlc3NhcnksIGJ1dCBtYWtlcyBpdCBhIGJpdCBtb3JlIGFjY3VyYXRlIGJ5IGFkanVzdGluZyB0aGUgdjEgdmFsdWUgYWNjb3JkaW5nIHRvIHRoZSBuZXcgc2xvcGUuIFRoaXMgd2F5IHdlJ3JlIG5vdCBqdXN0IGlnbm9yaW5nIHRoZSBpbmNvbWluZyBkYXRhLiBSZW1vdmluZyBmb3Igbm93IGJlY2F1c2UgaXQgZG9lc24ndCBzZWVtIHRvIG1ha2UgbXVjaCBwcmFjdGljYWwgZGlmZmVyZW5jZSBhbmQgaXQncyBwcm9iYWJseSBub3Qgd29ydGggdGhlIGtiLlxuICAgICAgdjEgPSB2MiArICh2YWx1ZSAtIHYyKSAvICh0IC0gdDIpICogKHQxIC0gdDIpO1xuICAgIH1cbiAgfSxcbiAgICAgIHJlc2V0ID0gZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgdjIgPSB2MSA9IHVzZURlbHRhID8gMCA6IHYxO1xuICAgIHQyID0gdDEgPSAwO1xuICB9LFxuICAgICAgZ2V0VmVsb2NpdHkgPSBmdW5jdGlvbiBnZXRWZWxvY2l0eShsYXRlc3RWYWx1ZSkge1xuICAgIHZhciB0T2xkID0gdDIsXG4gICAgICAgIHZPbGQgPSB2MixcbiAgICAgICAgdCA9IF9nZXRUaW1lKCk7XG5cbiAgICAobGF0ZXN0VmFsdWUgfHwgbGF0ZXN0VmFsdWUgPT09IDApICYmIGxhdGVzdFZhbHVlICE9PSB2MSAmJiB1cGRhdGUobGF0ZXN0VmFsdWUpO1xuICAgIHJldHVybiB0MSA9PT0gdDIgfHwgdCAtIHQyID4gZHJvcFRvWmVyb1RpbWUgPyAwIDogKHYxICsgKHVzZURlbHRhID8gdk9sZCA6IC12T2xkKSkgLyAoKHVzZURlbHRhID8gdCA6IHQxKSAtIHRPbGQpICogMTAwMDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogdXBkYXRlLFxuICAgIHJlc2V0OiByZXNldCxcbiAgICBnZXRWZWxvY2l0eTogZ2V0VmVsb2NpdHlcbiAgfTtcbn0sXG4gICAgX2dldEV2ZW50ID0gZnVuY3Rpb24gX2dldEV2ZW50KGUsIHByZXZlbnREZWZhdWx0KSB7XG4gIHByZXZlbnREZWZhdWx0ICYmICFlLl9nc2FwQWxsb3cgJiYgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICByZXR1cm4gZS5jaGFuZ2VkVG91Y2hlcyA/IGUuY2hhbmdlZFRvdWNoZXNbMF0gOiBlO1xufSxcbiAgICBfZ2V0QWJzb2x1dGVNYXggPSBmdW5jdGlvbiBfZ2V0QWJzb2x1dGVNYXgoYSkge1xuICB2YXIgbWF4ID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgYSksXG4gICAgICBtaW4gPSBNYXRoLm1pbi5hcHBseShNYXRoLCBhKTtcbiAgcmV0dXJuIE1hdGguYWJzKG1heCkgPj0gTWF0aC5hYnMobWluKSA/IG1heCA6IG1pbjtcbn0sXG4gICAgX3NldFNjcm9sbFRyaWdnZXIgPSBmdW5jdGlvbiBfc2V0U2Nyb2xsVHJpZ2dlcigpIHtcbiAgU2Nyb2xsVHJpZ2dlciA9IGdzYXAuY29yZS5nbG9iYWxzKCkuU2Nyb2xsVHJpZ2dlcjtcbiAgU2Nyb2xsVHJpZ2dlciAmJiBTY3JvbGxUcmlnZ2VyLmNvcmUgJiYgX2ludGVncmF0ZSgpO1xufSxcbiAgICBfaW5pdENvcmUgPSBmdW5jdGlvbiBfaW5pdENvcmUoY29yZSkge1xuICBnc2FwID0gY29yZSB8fCBfZ2V0R1NBUCgpO1xuXG4gIGlmIChnc2FwICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudC5ib2R5KSB7XG4gICAgX3dpbiA9IHdpbmRvdztcbiAgICBfZG9jID0gZG9jdW1lbnQ7XG4gICAgX2RvY0VsID0gX2RvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgX2JvZHkgPSBfZG9jLmJvZHk7XG4gICAgX3Jvb3QgPSBbX3dpbiwgX2RvYywgX2RvY0VsLCBfYm9keV07XG4gICAgX2NsYW1wID0gZ3NhcC51dGlscy5jbGFtcDtcblxuICAgIF9jb250ZXh0ID0gZ3NhcC5jb3JlLmNvbnRleHQgfHwgZnVuY3Rpb24gKCkge307XG5cbiAgICBfcG9pbnRlclR5cGUgPSBcIm9ucG9pbnRlcmVudGVyXCIgaW4gX2JvZHkgPyBcInBvaW50ZXJcIiA6IFwibW91c2VcIjsgLy8gaXNUb3VjaCBpcyAwIGlmIG5vIHRvdWNoLCAxIGlmIE9OTFkgdG91Y2gsIGFuZCAyIGlmIGl0IGNhbiBhY2NvbW1vZGF0ZSB0b3VjaCBidXQgYWxzbyBvdGhlciB0eXBlcyBsaWtlIG1vdXNlL3BvaW50ZXIuXG5cbiAgICBfaXNUb3VjaCA9IE9ic2VydmVyLmlzVG91Y2ggPSBfd2luLm1hdGNoTWVkaWEgJiYgX3dpbi5tYXRjaE1lZGlhKFwiKGhvdmVyOiBub25lKSwgKHBvaW50ZXI6IGNvYXJzZSlcIikubWF0Y2hlcyA/IDEgOiBcIm9udG91Y2hzdGFydFwiIGluIF93aW4gfHwgbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzID4gMCB8fCBuYXZpZ2F0b3IubXNNYXhUb3VjaFBvaW50cyA+IDAgPyAyIDogMDtcbiAgICBfZXZlbnRUeXBlcyA9IE9ic2VydmVyLmV2ZW50VHlwZXMgPSAoXCJvbnRvdWNoc3RhcnRcIiBpbiBfZG9jRWwgPyBcInRvdWNoc3RhcnQsdG91Y2htb3ZlLHRvdWNoY2FuY2VsLHRvdWNoZW5kXCIgOiAhKFwib25wb2ludGVyZG93blwiIGluIF9kb2NFbCkgPyBcIm1vdXNlZG93bixtb3VzZW1vdmUsbW91c2V1cCxtb3VzZXVwXCIgOiBcInBvaW50ZXJkb3duLHBvaW50ZXJtb3ZlLHBvaW50ZXJjYW5jZWwscG9pbnRlcnVwXCIpLnNwbGl0KFwiLFwiKTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfc3RhcnR1cCA9IDA7XG4gICAgfSwgNTAwKTtcblxuICAgIF9zZXRTY3JvbGxUcmlnZ2VyKCk7XG5cbiAgICBfY29yZUluaXR0ZWQgPSAxO1xuICB9XG5cbiAgcmV0dXJuIF9jb3JlSW5pdHRlZDtcbn07XG5cbl9ob3Jpem9udGFsLm9wID0gX3ZlcnRpY2FsO1xuX3Njcm9sbGVycy5jYWNoZSA9IDA7XG5leHBvcnQgdmFyIE9ic2VydmVyID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gT2JzZXJ2ZXIodmFycykge1xuICAgIHRoaXMuaW5pdCh2YXJzKTtcbiAgfVxuXG4gIHZhciBfcHJvdG8gPSBPYnNlcnZlci5wcm90b3R5cGU7XG5cbiAgX3Byb3RvLmluaXQgPSBmdW5jdGlvbiBpbml0KHZhcnMpIHtcbiAgICBfY29yZUluaXR0ZWQgfHwgX2luaXRDb3JlKGdzYXApIHx8IGNvbnNvbGUud2FybihcIlBsZWFzZSBnc2FwLnJlZ2lzdGVyUGx1Z2luKE9ic2VydmVyKVwiKTtcbiAgICBTY3JvbGxUcmlnZ2VyIHx8IF9zZXRTY3JvbGxUcmlnZ2VyKCk7XG4gICAgdmFyIHRvbGVyYW5jZSA9IHZhcnMudG9sZXJhbmNlLFxuICAgICAgICBkcmFnTWluaW11bSA9IHZhcnMuZHJhZ01pbmltdW0sXG4gICAgICAgIHR5cGUgPSB2YXJzLnR5cGUsXG4gICAgICAgIHRhcmdldCA9IHZhcnMudGFyZ2V0LFxuICAgICAgICBsaW5lSGVpZ2h0ID0gdmFycy5saW5lSGVpZ2h0LFxuICAgICAgICBkZWJvdW5jZSA9IHZhcnMuZGVib3VuY2UsXG4gICAgICAgIHByZXZlbnREZWZhdWx0ID0gdmFycy5wcmV2ZW50RGVmYXVsdCxcbiAgICAgICAgb25TdG9wID0gdmFycy5vblN0b3AsXG4gICAgICAgIG9uU3RvcERlbGF5ID0gdmFycy5vblN0b3BEZWxheSxcbiAgICAgICAgaWdub3JlID0gdmFycy5pZ25vcmUsXG4gICAgICAgIHdoZWVsU3BlZWQgPSB2YXJzLndoZWVsU3BlZWQsXG4gICAgICAgIGV2ZW50ID0gdmFycy5ldmVudCxcbiAgICAgICAgb25EcmFnU3RhcnQgPSB2YXJzLm9uRHJhZ1N0YXJ0LFxuICAgICAgICBvbkRyYWdFbmQgPSB2YXJzLm9uRHJhZ0VuZCxcbiAgICAgICAgb25EcmFnID0gdmFycy5vbkRyYWcsXG4gICAgICAgIG9uUHJlc3MgPSB2YXJzLm9uUHJlc3MsXG4gICAgICAgIG9uUmVsZWFzZSA9IHZhcnMub25SZWxlYXNlLFxuICAgICAgICBvblJpZ2h0ID0gdmFycy5vblJpZ2h0LFxuICAgICAgICBvbkxlZnQgPSB2YXJzLm9uTGVmdCxcbiAgICAgICAgb25VcCA9IHZhcnMub25VcCxcbiAgICAgICAgb25Eb3duID0gdmFycy5vbkRvd24sXG4gICAgICAgIG9uQ2hhbmdlWCA9IHZhcnMub25DaGFuZ2VYLFxuICAgICAgICBvbkNoYW5nZVkgPSB2YXJzLm9uQ2hhbmdlWSxcbiAgICAgICAgb25DaGFuZ2UgPSB2YXJzLm9uQ2hhbmdlLFxuICAgICAgICBvblRvZ2dsZVggPSB2YXJzLm9uVG9nZ2xlWCxcbiAgICAgICAgb25Ub2dnbGVZID0gdmFycy5vblRvZ2dsZVksXG4gICAgICAgIG9uSG92ZXIgPSB2YXJzLm9uSG92ZXIsXG4gICAgICAgIG9uSG92ZXJFbmQgPSB2YXJzLm9uSG92ZXJFbmQsXG4gICAgICAgIG9uTW92ZSA9IHZhcnMub25Nb3ZlLFxuICAgICAgICBpZ25vcmVDaGVjayA9IHZhcnMuaWdub3JlQ2hlY2ssXG4gICAgICAgIGlzTm9ybWFsaXplciA9IHZhcnMuaXNOb3JtYWxpemVyLFxuICAgICAgICBvbkdlc3R1cmVTdGFydCA9IHZhcnMub25HZXN0dXJlU3RhcnQsXG4gICAgICAgIG9uR2VzdHVyZUVuZCA9IHZhcnMub25HZXN0dXJlRW5kLFxuICAgICAgICBvbldoZWVsID0gdmFycy5vbldoZWVsLFxuICAgICAgICBvbkVuYWJsZSA9IHZhcnMub25FbmFibGUsXG4gICAgICAgIG9uRGlzYWJsZSA9IHZhcnMub25EaXNhYmxlLFxuICAgICAgICBvbkNsaWNrID0gdmFycy5vbkNsaWNrLFxuICAgICAgICBzY3JvbGxTcGVlZCA9IHZhcnMuc2Nyb2xsU3BlZWQsXG4gICAgICAgIGNhcHR1cmUgPSB2YXJzLmNhcHR1cmUsXG4gICAgICAgIGFsbG93Q2xpY2tzID0gdmFycy5hbGxvd0NsaWNrcyxcbiAgICAgICAgbG9ja0F4aXMgPSB2YXJzLmxvY2tBeGlzLFxuICAgICAgICBvbkxvY2tBeGlzID0gdmFycy5vbkxvY2tBeGlzO1xuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0ID0gX2dldFRhcmdldCh0YXJnZXQpIHx8IF9kb2NFbDtcbiAgICB0aGlzLnZhcnMgPSB2YXJzO1xuICAgIGlnbm9yZSAmJiAoaWdub3JlID0gZ3NhcC51dGlscy50b0FycmF5KGlnbm9yZSkpO1xuICAgIHRvbGVyYW5jZSA9IHRvbGVyYW5jZSB8fCAxZS05O1xuICAgIGRyYWdNaW5pbXVtID0gZHJhZ01pbmltdW0gfHwgMDtcbiAgICB3aGVlbFNwZWVkID0gd2hlZWxTcGVlZCB8fCAxO1xuICAgIHNjcm9sbFNwZWVkID0gc2Nyb2xsU3BlZWQgfHwgMTtcbiAgICB0eXBlID0gdHlwZSB8fCBcIndoZWVsLHRvdWNoLHBvaW50ZXJcIjtcbiAgICBkZWJvdW5jZSA9IGRlYm91bmNlICE9PSBmYWxzZTtcbiAgICBsaW5lSGVpZ2h0IHx8IChsaW5lSGVpZ2h0ID0gcGFyc2VGbG9hdChfd2luLmdldENvbXB1dGVkU3R5bGUoX2JvZHkpLmxpbmVIZWlnaHQpIHx8IDIyKTsgLy8gbm90ZTogYnJvd3NlciBtYXkgcmVwb3J0IFwibm9ybWFsXCIsIHNvIGRlZmF1bHQgdG8gMjIuXG5cbiAgICB2YXIgaWQsXG4gICAgICAgIG9uU3RvcERlbGF5ZWRDYWxsLFxuICAgICAgICBkcmFnZ2VkLFxuICAgICAgICBtb3ZlZCxcbiAgICAgICAgd2hlZWxlZCxcbiAgICAgICAgbG9ja2VkLFxuICAgICAgICBheGlzLFxuICAgICAgICBzZWxmID0gdGhpcyxcbiAgICAgICAgcHJldkRlbHRhWCA9IDAsXG4gICAgICAgIHByZXZEZWx0YVkgPSAwLFxuICAgICAgICBzY3JvbGxGdW5jWCA9IF9nZXRTY3JvbGxGdW5jKHRhcmdldCwgX2hvcml6b250YWwpLFxuICAgICAgICBzY3JvbGxGdW5jWSA9IF9nZXRTY3JvbGxGdW5jKHRhcmdldCwgX3ZlcnRpY2FsKSxcbiAgICAgICAgc2Nyb2xsWCA9IHNjcm9sbEZ1bmNYKCksXG4gICAgICAgIHNjcm9sbFkgPSBzY3JvbGxGdW5jWSgpLFxuICAgICAgICBsaW1pdFRvVG91Y2ggPSB+dHlwZS5pbmRleE9mKFwidG91Y2hcIikgJiYgIX50eXBlLmluZGV4T2YoXCJwb2ludGVyXCIpICYmIF9ldmVudFR5cGVzWzBdID09PSBcInBvaW50ZXJkb3duXCIsXG4gICAgICAgIC8vIGZvciBkZXZpY2VzIHRoYXQgYWNjb21tb2RhdGUgbW91c2UgZXZlbnRzIGFuZCB0b3VjaCBldmVudHMsIHdlIG5lZWQgdG8gZGlzdGluZ3Vpc2guXG4gICAgaXNWaWV3cG9ydCA9IF9pc1ZpZXdwb3J0KHRhcmdldCksXG4gICAgICAgIG93bmVyRG9jID0gdGFyZ2V0Lm93bmVyRG9jdW1lbnQgfHwgX2RvYyxcbiAgICAgICAgZGVsdGFYID0gWzAsIDAsIDBdLFxuICAgICAgICAvLyB3aGVlbCwgc2Nyb2xsLCBwb2ludGVyL3RvdWNoXG4gICAgZGVsdGFZID0gWzAsIDAsIDBdLFxuICAgICAgICBvbkNsaWNrVGltZSA9IDAsXG4gICAgICAgIGNsaWNrQ2FwdHVyZSA9IGZ1bmN0aW9uIGNsaWNrQ2FwdHVyZSgpIHtcbiAgICAgIHJldHVybiBvbkNsaWNrVGltZSA9IF9nZXRUaW1lKCk7XG4gICAgfSxcbiAgICAgICAgX2lnbm9yZUNoZWNrID0gZnVuY3Rpb24gX2lnbm9yZUNoZWNrKGUsIGlzUG9pbnRlck9yVG91Y2gpIHtcbiAgICAgIHJldHVybiAoc2VsZi5ldmVudCA9IGUpICYmIGlnbm9yZSAmJiB+aWdub3JlLmluZGV4T2YoZS50YXJnZXQpIHx8IGlzUG9pbnRlck9yVG91Y2ggJiYgbGltaXRUb1RvdWNoICYmIGUucG9pbnRlclR5cGUgIT09IFwidG91Y2hcIiB8fCBpZ25vcmVDaGVjayAmJiBpZ25vcmVDaGVjayhlLCBpc1BvaW50ZXJPclRvdWNoKTtcbiAgICB9LFxuICAgICAgICBvblN0b3BGdW5jID0gZnVuY3Rpb24gb25TdG9wRnVuYygpIHtcbiAgICAgIHNlbGYuX3Z4LnJlc2V0KCk7XG5cbiAgICAgIHNlbGYuX3Z5LnJlc2V0KCk7XG5cbiAgICAgIG9uU3RvcERlbGF5ZWRDYWxsLnBhdXNlKCk7XG4gICAgICBvblN0b3AgJiYgb25TdG9wKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIHVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICAgIHZhciBkeCA9IHNlbGYuZGVsdGFYID0gX2dldEFic29sdXRlTWF4KGRlbHRhWCksXG4gICAgICAgICAgZHkgPSBzZWxmLmRlbHRhWSA9IF9nZXRBYnNvbHV0ZU1heChkZWx0YVkpLFxuICAgICAgICAgIGNoYW5nZWRYID0gTWF0aC5hYnMoZHgpID49IHRvbGVyYW5jZSxcbiAgICAgICAgICBjaGFuZ2VkWSA9IE1hdGguYWJzKGR5KSA+PSB0b2xlcmFuY2U7XG5cbiAgICAgIG9uQ2hhbmdlICYmIChjaGFuZ2VkWCB8fCBjaGFuZ2VkWSkgJiYgb25DaGFuZ2Uoc2VsZiwgZHgsIGR5LCBkZWx0YVgsIGRlbHRhWSk7IC8vIGluIFNjcm9sbFRyaWdnZXIubm9ybWFsaXplU2Nyb2xsKCksIHdlIG5lZWQgdG8ga25vdyBpZiBpdCB3YXMgdG91Y2gvcG9pbnRlciBzbyB3ZSBuZWVkIGFjY2VzcyB0byB0aGUgZGVsdGFYL2RlbHRhWSBBcnJheXMgYmVmb3JlIHdlIGNsZWFyIHRoZW0gb3V0LlxuXG4gICAgICBpZiAoY2hhbmdlZFgpIHtcbiAgICAgICAgb25SaWdodCAmJiBzZWxmLmRlbHRhWCA+IDAgJiYgb25SaWdodChzZWxmKTtcbiAgICAgICAgb25MZWZ0ICYmIHNlbGYuZGVsdGFYIDwgMCAmJiBvbkxlZnQoc2VsZik7XG4gICAgICAgIG9uQ2hhbmdlWCAmJiBvbkNoYW5nZVgoc2VsZik7XG4gICAgICAgIG9uVG9nZ2xlWCAmJiBzZWxmLmRlbHRhWCA8IDAgIT09IHByZXZEZWx0YVggPCAwICYmIG9uVG9nZ2xlWChzZWxmKTtcbiAgICAgICAgcHJldkRlbHRhWCA9IHNlbGYuZGVsdGFYO1xuICAgICAgICBkZWx0YVhbMF0gPSBkZWx0YVhbMV0gPSBkZWx0YVhbMl0gPSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhbmdlZFkpIHtcbiAgICAgICAgb25Eb3duICYmIHNlbGYuZGVsdGFZID4gMCAmJiBvbkRvd24oc2VsZik7XG4gICAgICAgIG9uVXAgJiYgc2VsZi5kZWx0YVkgPCAwICYmIG9uVXAoc2VsZik7XG4gICAgICAgIG9uQ2hhbmdlWSAmJiBvbkNoYW5nZVkoc2VsZik7XG4gICAgICAgIG9uVG9nZ2xlWSAmJiBzZWxmLmRlbHRhWSA8IDAgIT09IHByZXZEZWx0YVkgPCAwICYmIG9uVG9nZ2xlWShzZWxmKTtcbiAgICAgICAgcHJldkRlbHRhWSA9IHNlbGYuZGVsdGFZO1xuICAgICAgICBkZWx0YVlbMF0gPSBkZWx0YVlbMV0gPSBkZWx0YVlbMl0gPSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAobW92ZWQgfHwgZHJhZ2dlZCkge1xuICAgICAgICBvbk1vdmUgJiYgb25Nb3ZlKHNlbGYpO1xuXG4gICAgICAgIGlmIChkcmFnZ2VkKSB7XG4gICAgICAgICAgb25EcmFnKHNlbGYpO1xuICAgICAgICAgIGRyYWdnZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1vdmVkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGxvY2tlZCAmJiAhKGxvY2tlZCA9IGZhbHNlKSAmJiBvbkxvY2tBeGlzICYmIG9uTG9ja0F4aXMoc2VsZik7XG5cbiAgICAgIGlmICh3aGVlbGVkKSB7XG4gICAgICAgIG9uV2hlZWwoc2VsZik7XG4gICAgICAgIHdoZWVsZWQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWQgPSAwO1xuICAgIH0sXG4gICAgICAgIG9uRGVsdGEgPSBmdW5jdGlvbiBvbkRlbHRhKHgsIHksIGluZGV4KSB7XG4gICAgICBkZWx0YVhbaW5kZXhdICs9IHg7XG4gICAgICBkZWx0YVlbaW5kZXhdICs9IHk7XG5cbiAgICAgIHNlbGYuX3Z4LnVwZGF0ZSh4KTtcblxuICAgICAgc2VsZi5fdnkudXBkYXRlKHkpO1xuXG4gICAgICBkZWJvdW5jZSA/IGlkIHx8IChpZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh1cGRhdGUpKSA6IHVwZGF0ZSgpO1xuICAgIH0sXG4gICAgICAgIG9uVG91Y2hPclBvaW50ZXJEZWx0YSA9IGZ1bmN0aW9uIG9uVG91Y2hPclBvaW50ZXJEZWx0YSh4LCB5KSB7XG4gICAgICBpZiAobG9ja0F4aXMgJiYgIWF4aXMpIHtcbiAgICAgICAgc2VsZi5heGlzID0gYXhpcyA9IE1hdGguYWJzKHgpID4gTWF0aC5hYnMoeSkgPyBcInhcIiA6IFwieVwiO1xuICAgICAgICBsb2NrZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXhpcyAhPT0gXCJ5XCIpIHtcbiAgICAgICAgZGVsdGFYWzJdICs9IHg7XG5cbiAgICAgICAgc2VsZi5fdngudXBkYXRlKHgsIHRydWUpOyAvLyB1cGRhdGUgdGhlIHZlbG9jaXR5IGFzIGZyZXF1ZW50bHkgYXMgcG9zc2libGUgaW5zdGVhZCBvZiBpbiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHNvIHRoYXQgdmVyeSBxdWljayB0b3VjaC1zY3JvbGxzIChmbGlja3MpIGZlZWwgbmF0dXJhbC4gSWYgaXQncyB0aGUgbW91c2UvdG91Y2gvcG9pbnRlciwgZm9yY2UgaXQgc28gdGhhdCB3ZSBnZXQgc25hcHB5L2FjY3VyYXRlIG1vbWVudHVtIHNjcm9sbC5cblxuICAgICAgfVxuXG4gICAgICBpZiAoYXhpcyAhPT0gXCJ4XCIpIHtcbiAgICAgICAgZGVsdGFZWzJdICs9IHk7XG5cbiAgICAgICAgc2VsZi5fdnkudXBkYXRlKHksIHRydWUpO1xuICAgICAgfVxuXG4gICAgICBkZWJvdW5jZSA/IGlkIHx8IChpZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh1cGRhdGUpKSA6IHVwZGF0ZSgpO1xuICAgIH0sXG4gICAgICAgIF9vbkRyYWcgPSBmdW5jdGlvbiBfb25EcmFnKGUpIHtcbiAgICAgIGlmIChfaWdub3JlQ2hlY2soZSwgMSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBlID0gX2dldEV2ZW50KGUsIHByZXZlbnREZWZhdWx0KTtcbiAgICAgIHZhciB4ID0gZS5jbGllbnRYLFxuICAgICAgICAgIHkgPSBlLmNsaWVudFksXG4gICAgICAgICAgZHggPSB4IC0gc2VsZi54LFxuICAgICAgICAgIGR5ID0geSAtIHNlbGYueSxcbiAgICAgICAgICBpc0RyYWdnaW5nID0gc2VsZi5pc0RyYWdnaW5nO1xuICAgICAgc2VsZi54ID0geDtcbiAgICAgIHNlbGYueSA9IHk7XG5cbiAgICAgIGlmIChpc0RyYWdnaW5nIHx8IE1hdGguYWJzKHNlbGYuc3RhcnRYIC0geCkgPj0gZHJhZ01pbmltdW0gfHwgTWF0aC5hYnMoc2VsZi5zdGFydFkgLSB5KSA+PSBkcmFnTWluaW11bSkge1xuICAgICAgICBvbkRyYWcgJiYgKGRyYWdnZWQgPSB0cnVlKTtcbiAgICAgICAgaXNEcmFnZ2luZyB8fCAoc2VsZi5pc0RyYWdnaW5nID0gdHJ1ZSk7XG4gICAgICAgIG9uVG91Y2hPclBvaW50ZXJEZWx0YShkeCwgZHkpO1xuICAgICAgICBpc0RyYWdnaW5nIHx8IG9uRHJhZ1N0YXJ0ICYmIG9uRHJhZ1N0YXJ0KHNlbGYpO1xuICAgICAgfVxuICAgIH0sXG4gICAgICAgIF9vblByZXNzID0gc2VsZi5vblByZXNzID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmIChfaWdub3JlQ2hlY2soZSwgMSkgfHwgZSAmJiBlLmJ1dHRvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHNlbGYuYXhpcyA9IGF4aXMgPSBudWxsO1xuICAgICAgb25TdG9wRGVsYXllZENhbGwucGF1c2UoKTtcbiAgICAgIHNlbGYuaXNQcmVzc2VkID0gdHJ1ZTtcbiAgICAgIGUgPSBfZ2V0RXZlbnQoZSk7IC8vIG5vdGU6IG1heSBuZWVkIHRvIHByZXZlbnREZWZhdWx0KD8pIFdvbid0IHNpZGUtc2Nyb2xsIG9uIGlPUyBTYWZhcmkgaWYgd2UgZG8sIHRob3VnaC5cblxuICAgICAgcHJldkRlbHRhWCA9IHByZXZEZWx0YVkgPSAwO1xuICAgICAgc2VsZi5zdGFydFggPSBzZWxmLnggPSBlLmNsaWVudFg7XG4gICAgICBzZWxmLnN0YXJ0WSA9IHNlbGYueSA9IGUuY2xpZW50WTtcblxuICAgICAgc2VsZi5fdngucmVzZXQoKTsgLy8gb3RoZXJ3aXNlIHRoZSB0MiBtYXkgYmUgc3RhbGUgaWYgdGhlIHVzZXIgdG91Y2hlcyBhbmQgZmxpY2tzIHN1cGVyIGZhc3QgYW5kIHJlbGVhc2VzIGluIGxlc3MgdGhhbiAyIHJlcXVlc3RBbmltYXRpb25GcmFtZSB0aWNrcywgY2F1c2luZyB2ZWxvY2l0eSB0byBiZSAwLlxuXG5cbiAgICAgIHNlbGYuX3Z5LnJlc2V0KCk7XG5cbiAgICAgIF9hZGRMaXN0ZW5lcihpc05vcm1hbGl6ZXIgPyB0YXJnZXQgOiBvd25lckRvYywgX2V2ZW50VHlwZXNbMV0sIF9vbkRyYWcsIHByZXZlbnREZWZhdWx0LCB0cnVlKTtcblxuICAgICAgc2VsZi5kZWx0YVggPSBzZWxmLmRlbHRhWSA9IDA7XG4gICAgICBvblByZXNzICYmIG9uUHJlc3Moc2VsZik7XG4gICAgfSxcbiAgICAgICAgX29uUmVsZWFzZSA9IHNlbGYub25SZWxlYXNlID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmIChfaWdub3JlQ2hlY2soZSwgMSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBfcmVtb3ZlTGlzdGVuZXIoaXNOb3JtYWxpemVyID8gdGFyZ2V0IDogb3duZXJEb2MsIF9ldmVudFR5cGVzWzFdLCBfb25EcmFnLCB0cnVlKTtcblxuICAgICAgdmFyIGlzVHJhY2tpbmdEcmFnID0gIWlzTmFOKHNlbGYueSAtIHNlbGYuc3RhcnRZKSxcbiAgICAgICAgICB3YXNEcmFnZ2luZyA9IHNlbGYuaXNEcmFnZ2luZyAmJiAoTWF0aC5hYnMoc2VsZi54IC0gc2VsZi5zdGFydFgpID4gMyB8fCBNYXRoLmFicyhzZWxmLnkgLSBzZWxmLnN0YXJ0WSkgPiAzKSxcbiAgICAgICAgICAvLyBzb21lIHRvdWNoIGRldmljZXMgbmVlZCBzb21lIHdpZ2dsZSByb29tIGluIHRlcm1zIG9mIHNlbnNpbmcgY2xpY2tzIC0gdGhlIGZpbmdlciBtYXkgbW92ZSBhIGZldyBwaXhlbHMuXG4gICAgICBldmVudERhdGEgPSBfZ2V0RXZlbnQoZSk7XG5cbiAgICAgIGlmICghd2FzRHJhZ2dpbmcgJiYgaXNUcmFja2luZ0RyYWcpIHtcbiAgICAgICAgc2VsZi5fdngucmVzZXQoKTtcblxuICAgICAgICBzZWxmLl92eS5yZXNldCgpO1xuXG4gICAgICAgIGlmIChwcmV2ZW50RGVmYXVsdCAmJiBhbGxvd0NsaWNrcykge1xuICAgICAgICAgIGdzYXAuZGVsYXllZENhbGwoMC4wOCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gc29tZSBicm93c2VycyAobGlrZSBGaXJlZm94KSB3b24ndCB0cnVzdCBzY3JpcHQtZ2VuZXJhdGVkIGNsaWNrcywgc28gaWYgdGhlIHVzZXIgdHJpZXMgdG8gY2xpY2sgb24gYSB2aWRlbyB0byBwbGF5IGl0LCBmb3IgZXhhbXBsZSwgaXQgc2ltcGx5IHdvbid0IHdvcmsuIFNpbmNlIGEgcmVndWxhciBcImNsaWNrXCIgZXZlbnQgd2lsbCBtb3N0IGxpa2VseSBiZSBnZW5lcmF0ZWQgYW55d2F5IChvbmUgdGhhdCBoYXMgaXRzIGlzVHJ1c3RlZCBmbGFnIHNldCB0byB0cnVlKSwgd2UgbXVzdCBzbGlnaHRseSBkZWxheSBvdXIgc2NyaXB0LWdlbmVyYXRlZCBjbGljayBzbyB0aGF0IHRoZSBcInJlYWxcIi90cnVzdGVkIG9uZSBpcyBwcmlvcml0aXplZC4gUmVtZW1iZXIsIHdoZW4gdGhlcmUgYXJlIGR1cGxpY2F0ZSBldmVudHMgaW4gcXVpY2sgc3VjY2Vzc2lvbiwgd2Ugc3VwcHJlc3MgYWxsIGJ1dCB0aGUgZmlyc3Qgb25lLiBTb21lIGJyb3dzZXJzIGRvbid0IGV2ZW4gdHJpZ2dlciB0aGUgXCJyZWFsXCIgb25lIGF0IGFsbCwgc28gb3VyIHN5bnRoZXRpYyBvbmUgaXMgYSBzYWZldHkgdmFsdmUgdGhhdCBlbnN1cmVzIHRoYXQgbm8gbWF0dGVyIHdoYXQsIGEgY2xpY2sgZXZlbnQgZG9lcyBnZXQgZGlzcGF0Y2hlZC5cbiAgICAgICAgICAgIGlmIChfZ2V0VGltZSgpIC0gb25DbGlja1RpbWUgPiAzMDAgJiYgIWUuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgICAgICBpZiAoZS50YXJnZXQuY2xpY2spIHtcbiAgICAgICAgICAgICAgICAvL3NvbWUgYnJvd3NlcnMgKGxpa2UgbW9iaWxlIFNhZmFyaSkgZG9uJ3QgcHJvcGVybHkgdHJpZ2dlciB0aGUgY2xpY2sgZXZlbnRcbiAgICAgICAgICAgICAgICBlLnRhcmdldC5jbGljaygpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKG93bmVyRG9jLmNyZWF0ZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyIHN5bnRoZXRpY0V2ZW50ID0gb3duZXJEb2MuY3JlYXRlRXZlbnQoXCJNb3VzZUV2ZW50c1wiKTtcbiAgICAgICAgICAgICAgICBzeW50aGV0aWNFdmVudC5pbml0TW91c2VFdmVudChcImNsaWNrXCIsIHRydWUsIHRydWUsIF93aW4sIDEsIGV2ZW50RGF0YS5zY3JlZW5YLCBldmVudERhdGEuc2NyZWVuWSwgZXZlbnREYXRhLmNsaWVudFgsIGV2ZW50RGF0YS5jbGllbnRZLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgMCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgZS50YXJnZXQuZGlzcGF0Y2hFdmVudChzeW50aGV0aWNFdmVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzZWxmLmlzRHJhZ2dpbmcgPSBzZWxmLmlzR2VzdHVyaW5nID0gc2VsZi5pc1ByZXNzZWQgPSBmYWxzZTtcbiAgICAgIG9uU3RvcCAmJiAhaXNOb3JtYWxpemVyICYmIG9uU3RvcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgICBvbkRyYWdFbmQgJiYgd2FzRHJhZ2dpbmcgJiYgb25EcmFnRW5kKHNlbGYpO1xuICAgICAgb25SZWxlYXNlICYmIG9uUmVsZWFzZShzZWxmLCB3YXNEcmFnZ2luZyk7XG4gICAgfSxcbiAgICAgICAgX29uR2VzdHVyZVN0YXJ0ID0gZnVuY3Rpb24gX29uR2VzdHVyZVN0YXJ0KGUpIHtcbiAgICAgIHJldHVybiBlLnRvdWNoZXMgJiYgZS50b3VjaGVzLmxlbmd0aCA+IDEgJiYgKHNlbGYuaXNHZXN0dXJpbmcgPSB0cnVlKSAmJiBvbkdlc3R1cmVTdGFydChlLCBzZWxmLmlzRHJhZ2dpbmcpO1xuICAgIH0sXG4gICAgICAgIF9vbkdlc3R1cmVFbmQgPSBmdW5jdGlvbiBfb25HZXN0dXJlRW5kKCkge1xuICAgICAgcmV0dXJuIChzZWxmLmlzR2VzdHVyaW5nID0gZmFsc2UpIHx8IG9uR2VzdHVyZUVuZChzZWxmKTtcbiAgICB9LFxuICAgICAgICBvblNjcm9sbCA9IGZ1bmN0aW9uIG9uU2Nyb2xsKGUpIHtcbiAgICAgIGlmIChfaWdub3JlQ2hlY2soZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgeCA9IHNjcm9sbEZ1bmNYKCksXG4gICAgICAgICAgeSA9IHNjcm9sbEZ1bmNZKCk7XG4gICAgICBvbkRlbHRhKCh4IC0gc2Nyb2xsWCkgKiBzY3JvbGxTcGVlZCwgKHkgLSBzY3JvbGxZKSAqIHNjcm9sbFNwZWVkLCAxKTtcbiAgICAgIHNjcm9sbFggPSB4O1xuICAgICAgc2Nyb2xsWSA9IHk7XG4gICAgICBvblN0b3AgJiYgb25TdG9wRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICB9LFxuICAgICAgICBfb25XaGVlbCA9IGZ1bmN0aW9uIF9vbldoZWVsKGUpIHtcbiAgICAgIGlmIChfaWdub3JlQ2hlY2soZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBlID0gX2dldEV2ZW50KGUsIHByZXZlbnREZWZhdWx0KTtcbiAgICAgIG9uV2hlZWwgJiYgKHdoZWVsZWQgPSB0cnVlKTtcbiAgICAgIHZhciBtdWx0aXBsaWVyID0gKGUuZGVsdGFNb2RlID09PSAxID8gbGluZUhlaWdodCA6IGUuZGVsdGFNb2RlID09PSAyID8gX3dpbi5pbm5lckhlaWdodCA6IDEpICogd2hlZWxTcGVlZDtcbiAgICAgIG9uRGVsdGEoZS5kZWx0YVggKiBtdWx0aXBsaWVyLCBlLmRlbHRhWSAqIG11bHRpcGxpZXIsIDApO1xuICAgICAgb25TdG9wICYmICFpc05vcm1hbGl6ZXIgJiYgb25TdG9wRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICB9LFxuICAgICAgICBfb25Nb3ZlID0gZnVuY3Rpb24gX29uTW92ZShlKSB7XG4gICAgICBpZiAoX2lnbm9yZUNoZWNrKGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHggPSBlLmNsaWVudFgsXG4gICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICBkeCA9IHggLSBzZWxmLngsXG4gICAgICAgICAgZHkgPSB5IC0gc2VsZi55O1xuICAgICAgc2VsZi54ID0geDtcbiAgICAgIHNlbGYueSA9IHk7XG4gICAgICBtb3ZlZCA9IHRydWU7XG4gICAgICAoZHggfHwgZHkpICYmIG9uVG91Y2hPclBvaW50ZXJEZWx0YShkeCwgZHkpO1xuICAgIH0sXG4gICAgICAgIF9vbkhvdmVyID0gZnVuY3Rpb24gX29uSG92ZXIoZSkge1xuICAgICAgc2VsZi5ldmVudCA9IGU7XG4gICAgICBvbkhvdmVyKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIF9vbkhvdmVyRW5kID0gZnVuY3Rpb24gX29uSG92ZXJFbmQoZSkge1xuICAgICAgc2VsZi5ldmVudCA9IGU7XG4gICAgICBvbkhvdmVyRW5kKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIF9vbkNsaWNrID0gZnVuY3Rpb24gX29uQ2xpY2soZSkge1xuICAgICAgcmV0dXJuIF9pZ25vcmVDaGVjayhlKSB8fCBfZ2V0RXZlbnQoZSwgcHJldmVudERlZmF1bHQpICYmIG9uQ2xpY2soc2VsZik7XG4gICAgfTtcblxuICAgIG9uU3RvcERlbGF5ZWRDYWxsID0gc2VsZi5fZGMgPSBnc2FwLmRlbGF5ZWRDYWxsKG9uU3RvcERlbGF5IHx8IDAuMjUsIG9uU3RvcEZ1bmMpLnBhdXNlKCk7XG4gICAgc2VsZi5kZWx0YVggPSBzZWxmLmRlbHRhWSA9IDA7XG4gICAgc2VsZi5fdnggPSBfZ2V0VmVsb2NpdHlQcm9wKDAsIDUwLCB0cnVlKTtcbiAgICBzZWxmLl92eSA9IF9nZXRWZWxvY2l0eVByb3AoMCwgNTAsIHRydWUpO1xuICAgIHNlbGYuc2Nyb2xsWCA9IHNjcm9sbEZ1bmNYO1xuICAgIHNlbGYuc2Nyb2xsWSA9IHNjcm9sbEZ1bmNZO1xuICAgIHNlbGYuaXNEcmFnZ2luZyA9IHNlbGYuaXNHZXN0dXJpbmcgPSBzZWxmLmlzUHJlc3NlZCA9IGZhbHNlO1xuXG4gICAgX2NvbnRleHQodGhpcyk7XG5cbiAgICBzZWxmLmVuYWJsZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoIXNlbGYuaXNFbmFibGVkKSB7XG4gICAgICAgIF9hZGRMaXN0ZW5lcihpc1ZpZXdwb3J0ID8gb3duZXJEb2MgOiB0YXJnZXQsIFwic2Nyb2xsXCIsIF9vblNjcm9sbCk7XG5cbiAgICAgICAgdHlwZS5pbmRleE9mKFwic2Nyb2xsXCIpID49IDAgJiYgX2FkZExpc3RlbmVyKGlzVmlld3BvcnQgPyBvd25lckRvYyA6IHRhcmdldCwgXCJzY3JvbGxcIiwgb25TY3JvbGwsIHByZXZlbnREZWZhdWx0LCBjYXB0dXJlKTtcbiAgICAgICAgdHlwZS5pbmRleE9mKFwid2hlZWxcIikgPj0gMCAmJiBfYWRkTGlzdGVuZXIodGFyZ2V0LCBcIndoZWVsXCIsIF9vbldoZWVsLCBwcmV2ZW50RGVmYXVsdCwgY2FwdHVyZSk7XG5cbiAgICAgICAgaWYgKHR5cGUuaW5kZXhPZihcInRvdWNoXCIpID49IDAgJiYgX2lzVG91Y2ggfHwgdHlwZS5pbmRleE9mKFwicG9pbnRlclwiKSA+PSAwKSB7XG4gICAgICAgICAgX2FkZExpc3RlbmVyKHRhcmdldCwgX2V2ZW50VHlwZXNbMF0sIF9vblByZXNzLCBwcmV2ZW50RGVmYXVsdCwgY2FwdHVyZSk7XG5cbiAgICAgICAgICBfYWRkTGlzdGVuZXIob3duZXJEb2MsIF9ldmVudFR5cGVzWzJdLCBfb25SZWxlYXNlKTtcblxuICAgICAgICAgIF9hZGRMaXN0ZW5lcihvd25lckRvYywgX2V2ZW50VHlwZXNbM10sIF9vblJlbGVhc2UpO1xuXG4gICAgICAgICAgYWxsb3dDbGlja3MgJiYgX2FkZExpc3RlbmVyKHRhcmdldCwgXCJjbGlja1wiLCBjbGlja0NhcHR1cmUsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgICBvbkNsaWNrICYmIF9hZGRMaXN0ZW5lcih0YXJnZXQsIFwiY2xpY2tcIiwgX29uQ2xpY2spO1xuICAgICAgICAgIG9uR2VzdHVyZVN0YXJ0ICYmIF9hZGRMaXN0ZW5lcihvd25lckRvYywgXCJnZXN0dXJlc3RhcnRcIiwgX29uR2VzdHVyZVN0YXJ0KTtcbiAgICAgICAgICBvbkdlc3R1cmVFbmQgJiYgX2FkZExpc3RlbmVyKG93bmVyRG9jLCBcImdlc3R1cmVlbmRcIiwgX29uR2VzdHVyZUVuZCk7XG4gICAgICAgICAgb25Ib3ZlciAmJiBfYWRkTGlzdGVuZXIodGFyZ2V0LCBfcG9pbnRlclR5cGUgKyBcImVudGVyXCIsIF9vbkhvdmVyKTtcbiAgICAgICAgICBvbkhvdmVyRW5kICYmIF9hZGRMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwibGVhdmVcIiwgX29uSG92ZXJFbmQpO1xuICAgICAgICAgIG9uTW92ZSAmJiBfYWRkTGlzdGVuZXIodGFyZ2V0LCBfcG9pbnRlclR5cGUgKyBcIm1vdmVcIiwgX29uTW92ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLmlzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgIGUgJiYgZS50eXBlICYmIF9vblByZXNzKGUpO1xuICAgICAgICBvbkVuYWJsZSAmJiBvbkVuYWJsZShzZWxmKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfTtcblxuICAgIHNlbGYuZGlzYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmlzRW5hYmxlZCkge1xuICAgICAgICAvLyBvbmx5IHJlbW92ZSB0aGUgX29uU2Nyb2xsIGxpc3RlbmVyIGlmIHRoZXJlIGFyZW4ndCBhbnkgb3RoZXJzIHRoYXQgcmVseSBvbiB0aGUgZnVuY3Rpb25hbGl0eS5cbiAgICAgICAgX29ic2VydmVycy5maWx0ZXIoZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICByZXR1cm4gbyAhPT0gc2VsZiAmJiBfaXNWaWV3cG9ydChvLnRhcmdldCk7XG4gICAgICAgIH0pLmxlbmd0aCB8fCBfcmVtb3ZlTGlzdGVuZXIoaXNWaWV3cG9ydCA/IG93bmVyRG9jIDogdGFyZ2V0LCBcInNjcm9sbFwiLCBfb25TY3JvbGwpO1xuXG4gICAgICAgIGlmIChzZWxmLmlzUHJlc3NlZCkge1xuICAgICAgICAgIHNlbGYuX3Z4LnJlc2V0KCk7XG5cbiAgICAgICAgICBzZWxmLl92eS5yZXNldCgpO1xuXG4gICAgICAgICAgX3JlbW92ZUxpc3RlbmVyKGlzTm9ybWFsaXplciA/IHRhcmdldCA6IG93bmVyRG9jLCBfZXZlbnRUeXBlc1sxXSwgX29uRHJhZywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIoaXNWaWV3cG9ydCA/IG93bmVyRG9jIDogdGFyZ2V0LCBcInNjcm9sbFwiLCBvblNjcm9sbCwgY2FwdHVyZSk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgXCJ3aGVlbFwiLCBfb25XaGVlbCwgY2FwdHVyZSk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgX2V2ZW50VHlwZXNbMF0sIF9vblByZXNzLCBjYXB0dXJlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIob3duZXJEb2MsIF9ldmVudFR5cGVzWzJdLCBfb25SZWxlYXNlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIob3duZXJEb2MsIF9ldmVudFR5cGVzWzNdLCBfb25SZWxlYXNlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIodGFyZ2V0LCBcImNsaWNrXCIsIGNsaWNrQ2FwdHVyZSwgdHJ1ZSk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgXCJjbGlja1wiLCBfb25DbGljayk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKG93bmVyRG9jLCBcImdlc3R1cmVzdGFydFwiLCBfb25HZXN0dXJlU3RhcnQpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcihvd25lckRvYywgXCJnZXN0dXJlZW5kXCIsIF9vbkdlc3R1cmVFbmQpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwiZW50ZXJcIiwgX29uSG92ZXIpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwibGVhdmVcIiwgX29uSG92ZXJFbmQpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwibW92ZVwiLCBfb25Nb3ZlKTtcblxuICAgICAgICBzZWxmLmlzRW5hYmxlZCA9IHNlbGYuaXNQcmVzc2VkID0gc2VsZi5pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgIG9uRGlzYWJsZSAmJiBvbkRpc2FibGUoc2VsZik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNlbGYua2lsbCA9IHNlbGYucmV2ZXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5kaXNhYmxlKCk7XG5cbiAgICAgIHZhciBpID0gX29ic2VydmVycy5pbmRleE9mKHNlbGYpO1xuXG4gICAgICBpID49IDAgJiYgX29ic2VydmVycy5zcGxpY2UoaSwgMSk7XG4gICAgICBfbm9ybWFsaXplciA9PT0gc2VsZiAmJiAoX25vcm1hbGl6ZXIgPSAwKTtcbiAgICB9O1xuXG4gICAgX29ic2VydmVycy5wdXNoKHNlbGYpO1xuXG4gICAgaXNOb3JtYWxpemVyICYmIF9pc1ZpZXdwb3J0KHRhcmdldCkgJiYgKF9ub3JtYWxpemVyID0gc2VsZik7XG4gICAgc2VsZi5lbmFibGUoZXZlbnQpO1xuICB9O1xuXG4gIF9jcmVhdGVDbGFzcyhPYnNlcnZlciwgW3tcbiAgICBrZXk6IFwidmVsb2NpdHlYXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdnguZ2V0VmVsb2NpdHkoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidmVsb2NpdHlZXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdnkuZ2V0VmVsb2NpdHkoKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gT2JzZXJ2ZXI7XG59KCk7XG5PYnNlcnZlci52ZXJzaW9uID0gXCIzLjExLjVcIjtcblxuT2JzZXJ2ZXIuY3JlYXRlID0gZnVuY3Rpb24gKHZhcnMpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZlcih2YXJzKTtcbn07XG5cbk9ic2VydmVyLnJlZ2lzdGVyID0gX2luaXRDb3JlO1xuXG5PYnNlcnZlci5nZXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBfb2JzZXJ2ZXJzLnNsaWNlKCk7XG59O1xuXG5PYnNlcnZlci5nZXRCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gIHJldHVybiBfb2JzZXJ2ZXJzLmZpbHRlcihmdW5jdGlvbiAobykge1xuICAgIHJldHVybiBvLnZhcnMuaWQgPT09IGlkO1xuICB9KVswXTtcbn07XG5cbl9nZXRHU0FQKCkgJiYgZ3NhcC5yZWdpc3RlclBsdWdpbihPYnNlcnZlcik7XG5leHBvcnQgeyBPYnNlcnZlciBhcyBkZWZhdWx0LCBfaXNWaWV3cG9ydCwgX3Njcm9sbGVycywgX2dldFNjcm9sbEZ1bmMsIF9nZXRQcm94eVByb3AsIF9wcm94aWVzLCBfZ2V0VmVsb2NpdHlQcm9wLCBfdmVydGljYWwsIF9ob3Jpem9udGFsLCBfZ2V0VGFyZ2V0IH07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/gsap/Observer.js\n"); /***/ }), /***/ "./node_modules/gsap/ScrollToPlugin.js": /*!*********************************************!*\ !*** ./node_modules/gsap/ScrollToPlugin.js ***! \*********************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ScrollToPlugin\": () => (/* binding */ ScrollToPlugin),\n/* harmony export */ \"default\": () => (/* binding */ ScrollToPlugin)\n/* harmony export */ });\n/*!\n * ScrollToPlugin 3.11.5\n * https://greensock.com\n *\n * @license Copyright 2008-2023, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n\n/* eslint-disable */\nvar gsap,\n _coreInitted,\n _window,\n _docEl,\n _body,\n _toArray,\n _config,\n ScrollTrigger,\n _windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _getGSAP = function _getGSAP() {\n return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n _isString = function _isString(value) {\n return typeof value === \"string\";\n},\n _isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n _max = function _max(element, axis) {\n var dim = axis === \"x\" ? \"Width\" : \"Height\",\n scroll = \"scroll\" + dim,\n client = \"client\" + dim;\n return element === _window || element === _docEl || element === _body ? Math.max(_docEl[scroll], _body[scroll]) - (_window[\"inner\" + dim] || _docEl[client] || _body[client]) : element[scroll] - element[\"offset\" + dim];\n},\n _buildGetter = function _buildGetter(e, axis) {\n //pass in an element and an axis (\"x\" or \"y\") and it'll return a getter function for the scroll position of that element (like scrollTop or scrollLeft, although if the element is the window, it'll use the pageXOffset/pageYOffset or the documentElement's scrollTop/scrollLeft or document.body's. Basically this streamlines things and makes a very fast getter across browsers.\n var p = \"scroll\" + (axis === \"x\" ? \"Left\" : \"Top\");\n\n if (e === _window) {\n if (e.pageXOffset != null) {\n p = \"page\" + axis.toUpperCase() + \"Offset\";\n } else {\n e = _docEl[p] != null ? _docEl : _body;\n }\n }\n\n return function () {\n return e[p];\n };\n},\n _clean = function _clean(value, index, target, targets) {\n _isFunction(value) && (value = value(index, target, targets));\n\n if (typeof value !== \"object\") {\n return _isString(value) && value !== \"max\" && value.charAt(1) !== \"=\" ? {\n x: value,\n y: value\n } : {\n y: value\n }; //if we don't receive an object as the parameter, assume the user intends \"y\".\n } else if (value.nodeType) {\n return {\n y: value,\n x: value\n };\n } else {\n var result = {},\n p;\n\n for (p in value) {\n result[p] = p !== \"onAutoKill\" && _isFunction(value[p]) ? value[p](index, target, targets) : value[p];\n }\n\n return result;\n }\n},\n _getOffset = function _getOffset(element, container) {\n element = _toArray(element)[0];\n\n if (!element || !element.getBoundingClientRect) {\n return console.warn(\"scrollTo target doesn't exist. Using 0\") || {\n x: 0,\n y: 0\n };\n }\n\n var rect = element.getBoundingClientRect(),\n isRoot = !container || container === _window || container === _body,\n cRect = isRoot ? {\n top: _docEl.clientTop - (_window.pageYOffset || _docEl.scrollTop || _body.scrollTop || 0),\n left: _docEl.clientLeft - (_window.pageXOffset || _docEl.scrollLeft || _body.scrollLeft || 0)\n } : container.getBoundingClientRect(),\n offsets = {\n x: rect.left - cRect.left,\n y: rect.top - cRect.top\n };\n\n if (!isRoot && container) {\n //only add the current scroll position if it's not the window/body.\n offsets.x += _buildGetter(container, \"x\")();\n offsets.y += _buildGetter(container, \"y\")();\n }\n\n return offsets;\n},\n _parseVal = function _parseVal(value, target, axis, currentVal, offset) {\n return !isNaN(value) && typeof value !== \"object\" ? parseFloat(value) - offset : _isString(value) && value.charAt(1) === \"=\" ? parseFloat(value.substr(2)) * (value.charAt(0) === \"-\" ? -1 : 1) + currentVal - offset : value === \"max\" ? _max(target, axis) - offset : Math.min(_max(target, axis), _getOffset(value, target)[axis] - offset);\n},\n _initCore = function _initCore() {\n gsap = _getGSAP();\n\n if (_windowExists() && gsap && typeof document !== \"undefined\" && document.body) {\n _window = window;\n _body = document.body;\n _docEl = document.documentElement;\n _toArray = gsap.utils.toArray;\n gsap.config({\n autoKillThreshold: 7\n });\n _config = gsap.config();\n _coreInitted = 1;\n }\n};\n\nvar ScrollToPlugin = {\n version: \"3.11.5\",\n name: \"scrollTo\",\n rawVars: 1,\n register: function register(core) {\n gsap = core;\n\n _initCore();\n },\n init: function init(target, value, tween, index, targets) {\n _coreInitted || _initCore();\n var data = this,\n snapType = gsap.getProperty(target, \"scrollSnapType\");\n data.isWin = target === _window;\n data.target = target;\n data.tween = tween;\n value = _clean(value, index, target, targets);\n data.vars = value;\n data.autoKill = !!value.autoKill;\n data.getX = _buildGetter(target, \"x\");\n data.getY = _buildGetter(target, \"y\");\n data.x = data.xPrev = data.getX();\n data.y = data.yPrev = data.getY();\n ScrollTrigger || (ScrollTrigger = gsap.core.globals().ScrollTrigger);\n gsap.getProperty(target, \"scrollBehavior\") === \"smooth\" && gsap.set(target, {\n scrollBehavior: \"auto\"\n });\n\n if (snapType && snapType !== \"none\") {\n // disable scroll snapping to avoid strange behavior\n data.snap = 1;\n data.snapInline = target.style.scrollSnapType;\n target.style.scrollSnapType = \"none\";\n }\n\n if (value.x != null) {\n data.add(data, \"x\", data.x, _parseVal(value.x, target, \"x\", data.x, value.offsetX || 0), index, targets);\n\n data._props.push(\"scrollTo_x\");\n } else {\n data.skipX = 1;\n }\n\n if (value.y != null) {\n data.add(data, \"y\", data.y, _parseVal(value.y, target, \"y\", data.y, value.offsetY || 0), index, targets);\n\n data._props.push(\"scrollTo_y\");\n } else {\n data.skipY = 1;\n }\n },\n render: function render(ratio, data) {\n var pt = data._pt,\n target = data.target,\n tween = data.tween,\n autoKill = data.autoKill,\n xPrev = data.xPrev,\n yPrev = data.yPrev,\n isWin = data.isWin,\n snap = data.snap,\n snapInline = data.snapInline,\n x,\n y,\n yDif,\n xDif,\n threshold;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n x = isWin || !data.skipX ? data.getX() : xPrev;\n y = isWin || !data.skipY ? data.getY() : yPrev;\n yDif = y - yPrev;\n xDif = x - xPrev;\n threshold = _config.autoKillThreshold;\n\n if (data.x < 0) {\n //can't scroll to a position less than 0! Might happen if someone uses a Back.easeOut or Elastic.easeOut when scrolling back to the top of the page (for example)\n data.x = 0;\n }\n\n if (data.y < 0) {\n data.y = 0;\n }\n\n if (autoKill) {\n //note: iOS has a bug that throws off the scroll by several pixels, so we need to check if it's within 7 pixels of the previous one that we set instead of just looking for an exact match.\n if (!data.skipX && (xDif > threshold || xDif < -threshold) && x < _max(target, \"x\")) {\n data.skipX = 1; //if the user scrolls separately, we should stop tweening!\n }\n\n if (!data.skipY && (yDif > threshold || yDif < -threshold) && y < _max(target, \"y\")) {\n data.skipY = 1; //if the user scrolls separately, we should stop tweening!\n }\n\n if (data.skipX && data.skipY) {\n tween.kill();\n data.vars.onAutoKill && data.vars.onAutoKill.apply(tween, data.vars.onAutoKillParams || []);\n }\n }\n\n if (isWin) {\n _window.scrollTo(!data.skipX ? data.x : x, !data.skipY ? data.y : y);\n } else {\n data.skipY || (target.scrollTop = data.y);\n data.skipX || (target.scrollLeft = data.x);\n }\n\n if (snap && (ratio === 1 || ratio === 0)) {\n y = target.scrollTop;\n x = target.scrollLeft;\n snapInline ? target.style.scrollSnapType = snapInline : target.style.removeProperty(\"scroll-snap-type\");\n target.scrollTop = y + 1; // bug in Safari causes the element to totally reset its scroll position when scroll-snap-type changes, so we need to set it to a slightly different value and then back again to work around this bug.\n\n target.scrollLeft = x + 1;\n target.scrollTop = y;\n target.scrollLeft = x;\n }\n\n data.xPrev = data.x;\n data.yPrev = data.y;\n ScrollTrigger && ScrollTrigger.update();\n },\n kill: function kill(property) {\n var both = property === \"scrollTo\";\n\n if (both || property === \"scrollTo_x\") {\n this.skipX = 1;\n }\n\n if (both || property === \"scrollTo_y\") {\n this.skipY = 1;\n }\n }\n};\nScrollToPlugin.max = _max;\nScrollToPlugin.getOffset = _getOffset;\nScrollToPlugin.buildGetter = _buildGetter;\n_getGSAP() && gsap.registerPlugin(ScrollToPlugin);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9TY3JvbGxUb1BsdWdpbi5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxPQUFPO0FBQ1AsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLG1CQUFtQjtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCOztBQUVBO0FBQ0Esd0JBQXdCO0FBQ3hCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7O0FBRWhDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ad2VhcmVhdGhsb24vZnJvbnRlbmQtd2VicGFjay1ib2lsZXJwbGF0ZS8uL25vZGVfbW9kdWxlcy9nc2FwL1Njcm9sbFRvUGx1Z2luLmpzPzk0MjAiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBTY3JvbGxUb1BsdWdpbiAzLjExLjVcbiAqIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbVxuICpcbiAqIEBsaWNlbnNlIENvcHlyaWdodCAyMDA4LTIwMjMsIEdyZWVuU29jay4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFN1YmplY3QgdG8gdGhlIHRlcm1zIGF0IGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHcmVlblNvY2sgbWVtYmVycywgdGhlIGFncmVlbWVudCBpc3N1ZWQgd2l0aCB0aGF0IG1lbWJlcnNoaXAuXG4gKiBAYXV0aG9yOiBKYWNrIERveWxlLCBqYWNrQGdyZWVuc29jay5jb21cbiovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG52YXIgZ3NhcCxcbiAgICBfY29yZUluaXR0ZWQsXG4gICAgX3dpbmRvdyxcbiAgICBfZG9jRWwsXG4gICAgX2JvZHksXG4gICAgX3RvQXJyYXksXG4gICAgX2NvbmZpZyxcbiAgICBTY3JvbGxUcmlnZ2VyLFxuICAgIF93aW5kb3dFeGlzdHMgPSBmdW5jdGlvbiBfd2luZG93RXhpc3RzKCkge1xuICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIjtcbn0sXG4gICAgX2dldEdTQVAgPSBmdW5jdGlvbiBfZ2V0R1NBUCgpIHtcbiAgcmV0dXJuIGdzYXAgfHwgX3dpbmRvd0V4aXN0cygpICYmIChnc2FwID0gd2luZG93LmdzYXApICYmIGdzYXAucmVnaXN0ZXJQbHVnaW4gJiYgZ3NhcDtcbn0sXG4gICAgX2lzU3RyaW5nID0gZnVuY3Rpb24gX2lzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XG59LFxuICAgIF9pc0Z1bmN0aW9uID0gZnVuY3Rpb24gX2lzRnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiO1xufSxcbiAgICBfbWF4ID0gZnVuY3Rpb24gX21heChlbGVtZW50LCBheGlzKSB7XG4gIHZhciBkaW0gPSBheGlzID09PSBcInhcIiA/IFwiV2lkdGhcIiA6IFwiSGVpZ2h0XCIsXG4gICAgICBzY3JvbGwgPSBcInNjcm9sbFwiICsgZGltLFxuICAgICAgY2xpZW50ID0gXCJjbGllbnRcIiArIGRpbTtcbiAgcmV0dXJuIGVsZW1lbnQgPT09IF93aW5kb3cgfHwgZWxlbWVudCA9PT0gX2RvY0VsIHx8IGVsZW1lbnQgPT09IF9ib2R5ID8gTWF0aC5tYXgoX2RvY0VsW3Njcm9sbF0sIF9ib2R5W3Njcm9sbF0pIC0gKF93aW5kb3dbXCJpbm5lclwiICsgZGltXSB8fCBfZG9jRWxbY2xpZW50XSB8fCBfYm9keVtjbGllbnRdKSA6IGVsZW1lbnRbc2Nyb2xsXSAtIGVsZW1lbnRbXCJvZmZzZXRcIiArIGRpbV07XG59LFxuICAgIF9idWlsZEdldHRlciA9IGZ1bmN0aW9uIF9idWlsZEdldHRlcihlLCBheGlzKSB7XG4gIC8vcGFzcyBpbiBhbiBlbGVtZW50IGFuZCBhbiBheGlzIChcInhcIiBvciBcInlcIikgYW5kIGl0J2xsIHJldHVybiBhIGdldHRlciBmdW5jdGlvbiBmb3IgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGF0IGVsZW1lbnQgKGxpa2Ugc2Nyb2xsVG9wIG9yIHNjcm9sbExlZnQsIGFsdGhvdWdoIGlmIHRoZSBlbGVtZW50IGlzIHRoZSB3aW5kb3csIGl0J2xsIHVzZSB0aGUgcGFnZVhPZmZzZXQvcGFnZVlPZmZzZXQgb3IgdGhlIGRvY3VtZW50RWxlbWVudCdzIHNjcm9sbFRvcC9zY3JvbGxMZWZ0IG9yIGRvY3VtZW50LmJvZHkncy4gQmFzaWNhbGx5IHRoaXMgc3RyZWFtbGluZXMgdGhpbmdzIGFuZCBtYWtlcyBhIHZlcnkgZmFzdCBnZXR0ZXIgYWNyb3NzIGJyb3dzZXJzLlxuICB2YXIgcCA9IFwic2Nyb2xsXCIgKyAoYXhpcyA9PT0gXCJ4XCIgPyBcIkxlZnRcIiA6IFwiVG9wXCIpO1xuXG4gIGlmIChlID09PSBfd2luZG93KSB7XG4gICAgaWYgKGUucGFnZVhPZmZzZXQgIT0gbnVsbCkge1xuICAgICAgcCA9IFwicGFnZVwiICsgYXhpcy50b1VwcGVyQ2FzZSgpICsgXCJPZmZzZXRcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgZSA9IF9kb2NFbFtwXSAhPSBudWxsID8gX2RvY0VsIDogX2JvZHk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZVtwXTtcbiAgfTtcbn0sXG4gICAgX2NsZWFuID0gZnVuY3Rpb24gX2NsZWFuKHZhbHVlLCBpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSB7XG4gIF9pc0Z1bmN0aW9uKHZhbHVlKSAmJiAodmFsdWUgPSB2YWx1ZShpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSk7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIikge1xuICAgIHJldHVybiBfaXNTdHJpbmcodmFsdWUpICYmIHZhbHVlICE9PSBcIm1heFwiICYmIHZhbHVlLmNoYXJBdCgxKSAhPT0gXCI9XCIgPyB7XG4gICAgICB4OiB2YWx1ZSxcbiAgICAgIHk6IHZhbHVlXG4gICAgfSA6IHtcbiAgICAgIHk6IHZhbHVlXG4gICAgfTsgLy9pZiB3ZSBkb24ndCByZWNlaXZlIGFuIG9iamVjdCBhcyB0aGUgcGFyYW1ldGVyLCBhc3N1bWUgdGhlIHVzZXIgaW50ZW5kcyBcInlcIi5cbiAgfSBlbHNlIGlmICh2YWx1ZS5ub2RlVHlwZSkge1xuICAgIHJldHVybiB7XG4gICAgICB5OiB2YWx1ZSxcbiAgICAgIHg6IHZhbHVlXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcmVzdWx0ID0ge30sXG4gICAgICAgIHA7XG5cbiAgICBmb3IgKHAgaW4gdmFsdWUpIHtcbiAgICAgIHJlc3VsdFtwXSA9IHAgIT09IFwib25BdXRvS2lsbFwiICYmIF9pc0Z1bmN0aW9uKHZhbHVlW3BdKSA/IHZhbHVlW3BdKGluZGV4LCB0YXJnZXQsIHRhcmdldHMpIDogdmFsdWVbcF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSxcbiAgICBfZ2V0T2Zmc2V0ID0gZnVuY3Rpb24gX2dldE9mZnNldChlbGVtZW50LCBjb250YWluZXIpIHtcbiAgZWxlbWVudCA9IF90b0FycmF5KGVsZW1lbnQpWzBdO1xuXG4gIGlmICghZWxlbWVudCB8fCAhZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QpIHtcbiAgICByZXR1cm4gY29uc29sZS53YXJuKFwic2Nyb2xsVG8gdGFyZ2V0IGRvZXNuJ3QgZXhpc3QuIFVzaW5nIDBcIikgfHwge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgaXNSb290ID0gIWNvbnRhaW5lciB8fCBjb250YWluZXIgPT09IF93aW5kb3cgfHwgY29udGFpbmVyID09PSBfYm9keSxcbiAgICAgIGNSZWN0ID0gaXNSb290ID8ge1xuICAgIHRvcDogX2RvY0VsLmNsaWVudFRvcCAtIChfd2luZG93LnBhZ2VZT2Zmc2V0IHx8IF9kb2NFbC5zY3JvbGxUb3AgfHwgX2JvZHkuc2Nyb2xsVG9wIHx8IDApLFxuICAgIGxlZnQ6IF9kb2NFbC5jbGllbnRMZWZ0IC0gKF93aW5kb3cucGFnZVhPZmZzZXQgfHwgX2RvY0VsLnNjcm9sbExlZnQgfHwgX2JvZHkuc2Nyb2xsTGVmdCB8fCAwKVxuICB9IDogY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICB4OiByZWN0LmxlZnQgLSBjUmVjdC5sZWZ0LFxuICAgIHk6IHJlY3QudG9wIC0gY1JlY3QudG9wXG4gIH07XG5cbiAgaWYgKCFpc1Jvb3QgJiYgY29udGFpbmVyKSB7XG4gICAgLy9vbmx5IGFkZCB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24gaWYgaXQncyBub3QgdGhlIHdpbmRvdy9ib2R5LlxuICAgIG9mZnNldHMueCArPSBfYnVpbGRHZXR0ZXIoY29udGFpbmVyLCBcInhcIikoKTtcbiAgICBvZmZzZXRzLnkgKz0gX2J1aWxkR2V0dGVyKGNvbnRhaW5lciwgXCJ5XCIpKCk7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0cztcbn0sXG4gICAgX3BhcnNlVmFsID0gZnVuY3Rpb24gX3BhcnNlVmFsKHZhbHVlLCB0YXJnZXQsIGF4aXMsIGN1cnJlbnRWYWwsIG9mZnNldCkge1xuICByZXR1cm4gIWlzTmFOKHZhbHVlKSAmJiB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgPyBwYXJzZUZsb2F0KHZhbHVlKSAtIG9mZnNldCA6IF9pc1N0cmluZyh2YWx1ZSkgJiYgdmFsdWUuY2hhckF0KDEpID09PSBcIj1cIiA/IHBhcnNlRmxvYXQodmFsdWUuc3Vic3RyKDIpKSAqICh2YWx1ZS5jaGFyQXQoMCkgPT09IFwiLVwiID8gLTEgOiAxKSArIGN1cnJlbnRWYWwgLSBvZmZzZXQgOiB2YWx1ZSA9PT0gXCJtYXhcIiA/IF9tYXgodGFyZ2V0LCBheGlzKSAtIG9mZnNldCA6IE1hdGgubWluKF9tYXgodGFyZ2V0LCBheGlzKSwgX2dldE9mZnNldCh2YWx1ZSwgdGFyZ2V0KVtheGlzXSAtIG9mZnNldCk7XG59LFxuICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZSgpIHtcbiAgZ3NhcCA9IF9nZXRHU0FQKCk7XG5cbiAgaWYgKF93aW5kb3dFeGlzdHMoKSAmJiBnc2FwICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudC5ib2R5KSB7XG4gICAgX3dpbmRvdyA9IHdpbmRvdztcbiAgICBfYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgX2RvY0VsID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIF90b0FycmF5ID0gZ3NhcC51dGlscy50b0FycmF5O1xuICAgIGdzYXAuY29uZmlnKHtcbiAgICAgIGF1dG9LaWxsVGhyZXNob2xkOiA3XG4gICAgfSk7XG4gICAgX2NvbmZpZyA9IGdzYXAuY29uZmlnKCk7XG4gICAgX2NvcmVJbml0dGVkID0gMTtcbiAgfVxufTtcblxuZXhwb3J0IHZhciBTY3JvbGxUb1BsdWdpbiA9IHtcbiAgdmVyc2lvbjogXCIzLjExLjVcIixcbiAgbmFtZTogXCJzY3JvbGxUb1wiLFxuICByYXdWYXJzOiAxLFxuICByZWdpc3RlcjogZnVuY3Rpb24gcmVnaXN0ZXIoY29yZSkge1xuICAgIGdzYXAgPSBjb3JlO1xuXG4gICAgX2luaXRDb3JlKCk7XG4gIH0sXG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQodGFyZ2V0LCB2YWx1ZSwgdHdlZW4sIGluZGV4LCB0YXJnZXRzKSB7XG4gICAgX2NvcmVJbml0dGVkIHx8IF9pbml0Q29yZSgpO1xuICAgIHZhciBkYXRhID0gdGhpcyxcbiAgICAgICAgc25hcFR5cGUgPSBnc2FwLmdldFByb3BlcnR5KHRhcmdldCwgXCJzY3JvbGxTbmFwVHlwZVwiKTtcbiAgICBkYXRhLmlzV2luID0gdGFyZ2V0ID09PSBfd2luZG93O1xuICAgIGRhdGEudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGRhdGEudHdlZW4gPSB0d2VlbjtcbiAgICB2YWx1ZSA9IF9jbGVhbih2YWx1ZSwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cyk7XG4gICAgZGF0YS52YXJzID0gdmFsdWU7XG4gICAgZGF0YS5hdXRvS2lsbCA9ICEhdmFsdWUuYXV0b0tpbGw7XG4gICAgZGF0YS5nZXRYID0gX2J1aWxkR2V0dGVyKHRhcmdldCwgXCJ4XCIpO1xuICAgIGRhdGEuZ2V0WSA9IF9idWlsZEdldHRlcih0YXJnZXQsIFwieVwiKTtcbiAgICBkYXRhLnggPSBkYXRhLnhQcmV2ID0gZGF0YS5nZXRYKCk7XG4gICAgZGF0YS55ID0gZGF0YS55UHJldiA9IGRhdGEuZ2V0WSgpO1xuICAgIFNjcm9sbFRyaWdnZXIgfHwgKFNjcm9sbFRyaWdnZXIgPSBnc2FwLmNvcmUuZ2xvYmFscygpLlNjcm9sbFRyaWdnZXIpO1xuICAgIGdzYXAuZ2V0UHJvcGVydHkodGFyZ2V0LCBcInNjcm9sbEJlaGF2aW9yXCIpID09PSBcInNtb290aFwiICYmIGdzYXAuc2V0KHRhcmdldCwge1xuICAgICAgc2Nyb2xsQmVoYXZpb3I6IFwiYXV0b1wiXG4gICAgfSk7XG5cbiAgICBpZiAoc25hcFR5cGUgJiYgc25hcFR5cGUgIT09IFwibm9uZVwiKSB7XG4gICAgICAvLyBkaXNhYmxlIHNjcm9sbCBzbmFwcGluZyB0byBhdm9pZCBzdHJhbmdlIGJlaGF2aW9yXG4gICAgICBkYXRhLnNuYXAgPSAxO1xuICAgICAgZGF0YS5zbmFwSW5saW5lID0gdGFyZ2V0LnN0eWxlLnNjcm9sbFNuYXBUeXBlO1xuICAgICAgdGFyZ2V0LnN0eWxlLnNjcm9sbFNuYXBUeXBlID0gXCJub25lXCI7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnggIT0gbnVsbCkge1xuICAgICAgZGF0YS5hZGQoZGF0YSwgXCJ4XCIsIGRhdGEueCwgX3BhcnNlVmFsKHZhbHVlLngsIHRhcmdldCwgXCJ4XCIsIGRhdGEueCwgdmFsdWUub2Zmc2V0WCB8fCAwKSwgaW5kZXgsIHRhcmdldHMpO1xuXG4gICAgICBkYXRhLl9wcm9wcy5wdXNoKFwic2Nyb2xsVG9feFwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5za2lwWCA9IDE7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnkgIT0gbnVsbCkge1xuICAgICAgZGF0YS5hZGQoZGF0YSwgXCJ5XCIsIGRhdGEueSwgX3BhcnNlVmFsKHZhbHVlLnksIHRhcmdldCwgXCJ5XCIsIGRhdGEueSwgdmFsdWUub2Zmc2V0WSB8fCAwKSwgaW5kZXgsIHRhcmdldHMpO1xuXG4gICAgICBkYXRhLl9wcm9wcy5wdXNoKFwic2Nyb2xsVG9feVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5za2lwWSA9IDE7XG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcihyYXRpbywgZGF0YSkge1xuICAgIHZhciBwdCA9IGRhdGEuX3B0LFxuICAgICAgICB0YXJnZXQgPSBkYXRhLnRhcmdldCxcbiAgICAgICAgdHdlZW4gPSBkYXRhLnR3ZWVuLFxuICAgICAgICBhdXRvS2lsbCA9IGRhdGEuYXV0b0tpbGwsXG4gICAgICAgIHhQcmV2ID0gZGF0YS54UHJldixcbiAgICAgICAgeVByZXYgPSBkYXRhLnlQcmV2LFxuICAgICAgICBpc1dpbiA9IGRhdGEuaXNXaW4sXG4gICAgICAgIHNuYXAgPSBkYXRhLnNuYXAsXG4gICAgICAgIHNuYXBJbmxpbmUgPSBkYXRhLnNuYXBJbmxpbmUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIHlEaWYsXG4gICAgICAgIHhEaWYsXG4gICAgICAgIHRocmVzaG9sZDtcblxuICAgIHdoaWxlIChwdCkge1xuICAgICAgcHQucihyYXRpbywgcHQuZCk7XG4gICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgIH1cblxuICAgIHggPSBpc1dpbiB8fCAhZGF0YS5za2lwWCA/IGRhdGEuZ2V0WCgpIDogeFByZXY7XG4gICAgeSA9IGlzV2luIHx8ICFkYXRhLnNraXBZID8gZGF0YS5nZXRZKCkgOiB5UHJldjtcbiAgICB5RGlmID0geSAtIHlQcmV2O1xuICAgIHhEaWYgPSB4IC0geFByZXY7XG4gICAgdGhyZXNob2xkID0gX2NvbmZpZy5hdXRvS2lsbFRocmVzaG9sZDtcblxuICAgIGlmIChkYXRhLnggPCAwKSB7XG4gICAgICAvL2Nhbid0IHNjcm9sbCB0byBhIHBvc2l0aW9uIGxlc3MgdGhhbiAwISBNaWdodCBoYXBwZW4gaWYgc29tZW9uZSB1c2VzIGEgQmFjay5lYXNlT3V0IG9yIEVsYXN0aWMuZWFzZU91dCB3aGVuIHNjcm9sbGluZyBiYWNrIHRvIHRoZSB0b3Agb2YgdGhlIHBhZ2UgKGZvciBleGFtcGxlKVxuICAgICAgZGF0YS54ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS55IDwgMCkge1xuICAgICAgZGF0YS55ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoYXV0b0tpbGwpIHtcbiAgICAgIC8vbm90ZTogaU9TIGhhcyBhIGJ1ZyB0aGF0IHRocm93cyBvZmYgdGhlIHNjcm9sbCBieSBzZXZlcmFsIHBpeGVscywgc28gd2UgbmVlZCB0byBjaGVjayBpZiBpdCdzIHdpdGhpbiA3IHBpeGVscyBvZiB0aGUgcHJldmlvdXMgb25lIHRoYXQgd2Ugc2V0IGluc3RlYWQgb2YganVzdCBsb29raW5nIGZvciBhbiBleGFjdCBtYXRjaC5cbiAgICAgIGlmICghZGF0YS5za2lwWCAmJiAoeERpZiA+IHRocmVzaG9sZCB8fCB4RGlmIDwgLXRocmVzaG9sZCkgJiYgeCA8IF9tYXgodGFyZ2V0LCBcInhcIikpIHtcbiAgICAgICAgZGF0YS5za2lwWCA9IDE7IC8vaWYgdGhlIHVzZXIgc2Nyb2xscyBzZXBhcmF0ZWx5LCB3ZSBzaG91bGQgc3RvcCB0d2VlbmluZyFcbiAgICAgIH1cblxuICAgICAgaWYgKCFkYXRhLnNraXBZICYmICh5RGlmID4gdGhyZXNob2xkIHx8IHlEaWYgPCAtdGhyZXNob2xkKSAmJiB5IDwgX21heCh0YXJnZXQsIFwieVwiKSkge1xuICAgICAgICBkYXRhLnNraXBZID0gMTsgLy9pZiB0aGUgdXNlciBzY3JvbGxzIHNlcGFyYXRlbHksIHdlIHNob3VsZCBzdG9wIHR3ZWVuaW5nIVxuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5za2lwWCAmJiBkYXRhLnNraXBZKSB7XG4gICAgICAgIHR3ZWVuLmtpbGwoKTtcbiAgICAgICAgZGF0YS52YXJzLm9uQXV0b0tpbGwgJiYgZGF0YS52YXJzLm9uQXV0b0tpbGwuYXBwbHkodHdlZW4sIGRhdGEudmFycy5vbkF1dG9LaWxsUGFyYW1zIHx8IFtdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNXaW4pIHtcbiAgICAgIF93aW5kb3cuc2Nyb2xsVG8oIWRhdGEuc2tpcFggPyBkYXRhLnggOiB4LCAhZGF0YS5za2lwWSA/IGRhdGEueSA6IHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhLnNraXBZIHx8ICh0YXJnZXQuc2Nyb2xsVG9wID0gZGF0YS55KTtcbiAgICAgIGRhdGEuc2tpcFggfHwgKHRhcmdldC5zY3JvbGxMZWZ0ID0gZGF0YS54KTtcbiAgICB9XG5cbiAgICBpZiAoc25hcCAmJiAocmF0aW8gPT09IDEgfHwgcmF0aW8gPT09IDApKSB7XG4gICAgICB5ID0gdGFyZ2V0LnNjcm9sbFRvcDtcbiAgICAgIHggPSB0YXJnZXQuc2Nyb2xsTGVmdDtcbiAgICAgIHNuYXBJbmxpbmUgPyB0YXJnZXQuc3R5bGUuc2Nyb2xsU25hcFR5cGUgPSBzbmFwSW5saW5lIDogdGFyZ2V0LnN0eWxlLnJlbW92ZVByb3BlcnR5KFwic2Nyb2xsLXNuYXAtdHlwZVwiKTtcbiAgICAgIHRhcmdldC5zY3JvbGxUb3AgPSB5ICsgMTsgLy8gYnVnIGluIFNhZmFyaSBjYXVzZXMgdGhlIGVsZW1lbnQgdG8gdG90YWxseSByZXNldCBpdHMgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gc2Nyb2xsLXNuYXAtdHlwZSBjaGFuZ2VzLCBzbyB3ZSBuZWVkIHRvIHNldCBpdCB0byBhIHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZSBhbmQgdGhlbiBiYWNrIGFnYWluIHRvIHdvcmsgYXJvdW5kIHRoaXMgYnVnLlxuXG4gICAgICB0YXJnZXQuc2Nyb2xsTGVmdCA9IHggKyAxO1xuICAgICAgdGFyZ2V0LnNjcm9sbFRvcCA9IHk7XG4gICAgICB0YXJnZXQuc2Nyb2xsTGVmdCA9IHg7XG4gICAgfVxuXG4gICAgZGF0YS54UHJldiA9IGRhdGEueDtcbiAgICBkYXRhLnlQcmV2ID0gZGF0YS55O1xuICAgIFNjcm9sbFRyaWdnZXIgJiYgU2Nyb2xsVHJpZ2dlci51cGRhdGUoKTtcbiAgfSxcbiAga2lsbDogZnVuY3Rpb24ga2lsbChwcm9wZXJ0eSkge1xuICAgIHZhciBib3RoID0gcHJvcGVydHkgPT09IFwic2Nyb2xsVG9cIjtcblxuICAgIGlmIChib3RoIHx8IHByb3BlcnR5ID09PSBcInNjcm9sbFRvX3hcIikge1xuICAgICAgdGhpcy5za2lwWCA9IDE7XG4gICAgfVxuXG4gICAgaWYgKGJvdGggfHwgcHJvcGVydHkgPT09IFwic2Nyb2xsVG9feVwiKSB7XG4gICAgICB0aGlzLnNraXBZID0gMTtcbiAgICB9XG4gIH1cbn07XG5TY3JvbGxUb1BsdWdpbi5tYXggPSBfbWF4O1xuU2Nyb2xsVG9QbHVnaW4uZ2V0T2Zmc2V0ID0gX2dldE9mZnNldDtcblNjcm9sbFRvUGx1Z2luLmJ1aWxkR2V0dGVyID0gX2J1aWxkR2V0dGVyO1xuX2dldEdTQVAoKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRvUGx1Z2luKTtcbmV4cG9ydCB7IFNjcm9sbFRvUGx1Z2luIGFzIGRlZmF1bHQgfTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/gsap/ScrollToPlugin.js\n"); /***/ }), /***/ "./node_modules/gsap/ScrollTrigger.js": /*!********************************************!*\ !*** ./node_modules/gsap/ScrollTrigger.js ***! \********************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ScrollTrigger\": () => (/* binding */ ScrollTrigger),\n/* harmony export */ \"default\": () => (/* binding */ ScrollTrigger)\n/* harmony export */ });\n/* harmony import */ var _Observer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Observer.js */ \"./node_modules/gsap/Observer.js\");\n/*!\n * ScrollTrigger 3.11.5\n * https://greensock.com\n *\n * @license Copyright 2008-2023, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n\n/* eslint-disable */\n\n\nvar gsap,\n _coreInitted,\n _win,\n _doc,\n _docEl,\n _body,\n _root,\n _resizeDelay,\n _toArray,\n _clamp,\n _time2,\n _syncInterval,\n _refreshing,\n _pointerIsDown,\n _transformProp,\n _i,\n _prevWidth,\n _prevHeight,\n _autoRefresh,\n _sort,\n _suppressOverwrites,\n _ignoreResize,\n _normalizer,\n _ignoreMobileResize,\n _baseScreenHeight,\n _baseScreenWidth,\n _fixIOSBug,\n _context,\n _scrollRestoration,\n _limitCallbacks,\n // if true, we'll only trigger callbacks if the active state toggles, so if you scroll immediately past both the start and end positions of a ScrollTrigger (thus inactive to inactive), neither its onEnter nor onLeave will be called. This is useful during startup.\n_startup = 1,\n _getTime = Date.now,\n _time1 = _getTime(),\n _lastScrollTime = 0,\n _enabled = 0,\n _rafBugFix = function _rafBugFix() {\n return _enabled && requestAnimationFrame(_rafBugFix);\n},\n // in some browsers (like Firefox), screen repaints weren't consistent unless we had SOMETHING queued up in requestAnimationFrame()! So this just creates a super simple loop to keep it alive and smooth out repaints.\n_pointerDownHandler = function _pointerDownHandler() {\n return _pointerIsDown = 1;\n},\n _pointerUpHandler = function _pointerUpHandler() {\n return _pointerIsDown = 0;\n},\n _passThrough = function _passThrough(v) {\n return v;\n},\n _round = function _round(value) {\n return Math.round(value * 100000) / 100000 || 0;\n},\n _windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _getGSAP = function _getGSAP() {\n return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n _isViewport = function _isViewport(e) {\n return !!~_root.indexOf(e);\n},\n _getBoundsFunc = function _getBoundsFunc(element) {\n return (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(element, \"getBoundingClientRect\") || (_isViewport(element) ? function () {\n _winOffsets.width = _win.innerWidth;\n _winOffsets.height = _win.innerHeight;\n return _winOffsets;\n } : function () {\n return _getBounds(element);\n });\n},\n _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {\n var d = _ref.d,\n d2 = _ref.d2,\n a = _ref.a;\n return (a = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, \"getBoundingClientRect\")) ? function () {\n return a()[d];\n } : function () {\n return (isViewport ? _win[\"inner\" + d2] : scroller[\"client\" + d2]) || 0;\n };\n},\n _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {\n return !isViewport || ~_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.indexOf(element) ? _getBoundsFunc(element) : function () {\n return _winOffsets;\n };\n},\n _maxScroll = function _maxScroll(element, _ref2) {\n var s = _ref2.s,\n d2 = _ref2.d2,\n d = _ref2.d,\n a = _ref2.a;\n return Math.max(0, (s = \"scroll\" + d2) && (a = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? (_docEl[s] || _body[s]) - (_win[\"inner\" + d2] || _docEl[\"client\" + d2] || _body[\"client\" + d2]) : element[s] - element[\"offset\" + d2]);\n},\n _iterateAutoRefresh = function _iterateAutoRefresh(func, events) {\n for (var i = 0; i < _autoRefresh.length; i += 3) {\n (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);\n }\n},\n _isString = function _isString(value) {\n return typeof value === \"string\";\n},\n _isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n _isNumber = function _isNumber(value) {\n return typeof value === \"number\";\n},\n _isObject = function _isObject(value) {\n return typeof value === \"object\";\n},\n _callIfFunc = function _callIfFunc(value) {\n return _isFunction(value) && value();\n},\n _combineFunc = function _combineFunc(f1, f2) {\n return function () {\n var result1 = _callIfFunc(f1),\n result2 = _callIfFunc(f2);\n\n return function () {\n _callIfFunc(result1);\n\n _callIfFunc(result2);\n };\n };\n},\n _endAnimation = function _endAnimation(animation, reversed, pause) {\n return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();\n},\n _callback = function _callback(self, func) {\n if (self.enabled) {\n var result = func(self);\n result && result.totalTime && (self.callbackAnimation = result);\n }\n},\n _abs = Math.abs,\n _scrollLeft = \"scrollLeft\",\n _scrollTop = \"scrollTop\",\n _left = \"left\",\n _top = \"top\",\n _right = \"right\",\n _bottom = \"bottom\",\n _width = \"width\",\n _height = \"height\",\n _Right = \"Right\",\n _Left = \"Left\",\n _Top = \"Top\",\n _Bottom = \"Bottom\",\n _padding = \"padding\",\n _margin = \"margin\",\n _Width = \"Width\",\n _Height = \"Height\",\n _px = \"px\",\n _getComputedStyle = function _getComputedStyle(element) {\n return _win.getComputedStyle(element);\n},\n _makePositionable = function _makePositionable(element) {\n // if the element already has position: absolute or fixed, leave that, otherwise make it position: relative\n var position = _getComputedStyle(element).position;\n\n element.style.position = position === \"absolute\" || position === \"fixed\" ? position : \"relative\";\n},\n _setDefaults = function _setDefaults(obj, defaults) {\n for (var p in defaults) {\n p in obj || (obj[p] = defaults[p]);\n }\n\n return obj;\n},\n _getBounds = function _getBounds(element, withoutTransforms) {\n var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== \"matrix(1, 0, 0, 1, 0, 0)\" && gsap.to(element, {\n x: 0,\n y: 0,\n xPercent: 0,\n yPercent: 0,\n rotation: 0,\n rotationX: 0,\n rotationY: 0,\n scale: 1,\n skewX: 0,\n skewY: 0\n }).progress(1),\n bounds = element.getBoundingClientRect();\n tween && tween.progress(0).kill();\n return bounds;\n},\n _getSize = function _getSize(element, _ref3) {\n var d2 = _ref3.d2;\n return element[\"offset\" + d2] || element[\"client\" + d2] || 0;\n},\n _getLabelRatioArray = function _getLabelRatioArray(timeline) {\n var a = [],\n labels = timeline.labels,\n duration = timeline.duration(),\n p;\n\n for (p in labels) {\n a.push(labels[p] / duration);\n }\n\n return a;\n},\n _getClosestLabel = function _getClosestLabel(animation) {\n return function (value) {\n return gsap.utils.snap(_getLabelRatioArray(animation), value);\n };\n},\n _snapDirectional = function _snapDirectional(snapIncrementOrArray) {\n var snap = gsap.utils.snap(snapIncrementOrArray),\n a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {\n return a - b;\n });\n return a ? function (value, direction, threshold) {\n if (threshold === void 0) {\n threshold = 1e-3;\n }\n\n var i;\n\n if (!direction) {\n return snap(value);\n }\n\n if (direction > 0) {\n value -= threshold; // to avoid rounding errors. If we're too strict, it might snap forward, then immediately again, and again.\n\n for (i = 0; i < a.length; i++) {\n if (a[i] >= value) {\n return a[i];\n }\n }\n\n return a[i - 1];\n } else {\n i = a.length;\n value += threshold;\n\n while (i--) {\n if (a[i] <= value) {\n return a[i];\n }\n }\n }\n\n return a[0];\n } : function (value, direction, threshold) {\n if (threshold === void 0) {\n threshold = 1e-3;\n }\n\n var snapped = snap(value);\n return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);\n };\n},\n _getLabelAtDirection = function _getLabelAtDirection(timeline) {\n return function (value, st) {\n return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);\n };\n},\n _multiListener = function _multiListener(func, element, types, callback) {\n return types.split(\",\").forEach(function (type) {\n return func(element, type, callback);\n });\n},\n _addListener = function _addListener(element, type, func, nonPassive, capture) {\n return element.addEventListener(type, func, {\n passive: !nonPassive,\n capture: !!capture\n });\n},\n _removeListener = function _removeListener(element, type, func, capture) {\n return element.removeEventListener(type, func, !!capture);\n},\n _wheelListener = function _wheelListener(func, el, scrollFunc) {\n scrollFunc = scrollFunc && scrollFunc.wheelHandler;\n\n if (scrollFunc) {\n func(el, \"wheel\", scrollFunc);\n func(el, \"touchmove\", scrollFunc);\n }\n},\n _markerDefaults = {\n startColor: \"green\",\n endColor: \"red\",\n indent: 0,\n fontSize: \"16px\",\n fontWeight: \"normal\"\n},\n _defaults = {\n toggleActions: \"play\",\n anticipatePin: 0\n},\n _keywords = {\n top: 0,\n left: 0,\n center: 0.5,\n bottom: 1,\n right: 1\n},\n _offsetToPx = function _offsetToPx(value, size) {\n if (_isString(value)) {\n var eqIndex = value.indexOf(\"=\"),\n relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;\n\n if (~eqIndex) {\n value.indexOf(\"%\") > eqIndex && (relative *= size / 100);\n value = value.substr(0, eqIndex - 1);\n }\n\n value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf(\"%\") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);\n }\n\n return value;\n},\n _createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {\n var startColor = _ref4.startColor,\n endColor = _ref4.endColor,\n fontSize = _ref4.fontSize,\n indent = _ref4.indent,\n fontWeight = _ref4.fontWeight;\n\n var e = _doc.createElement(\"div\"),\n useFixedPosition = _isViewport(container) || (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(container, \"pinType\") === \"fixed\",\n isScroller = type.indexOf(\"scroller\") !== -1,\n parent = useFixedPosition ? _body : container,\n isStart = type.indexOf(\"start\") !== -1,\n color = isStart ? startColor : endColor,\n css = \"border-color:\" + color + \";font-size:\" + fontSize + \";color:\" + color + \";font-weight:\" + fontWeight + \";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;\";\n\n css += \"position:\" + ((isScroller || containerAnimation) && useFixedPosition ? \"fixed;\" : \"absolute;\");\n (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? _right : _bottom) + \":\" + (offset + parseFloat(indent)) + \"px;\");\n matchWidthEl && (css += \"box-sizing:border-box;text-align:left;width:\" + matchWidthEl.offsetWidth + \"px;\");\n e._isStart = isStart;\n e.setAttribute(\"class\", \"gsap-marker-\" + type + (name ? \" marker-\" + name : \"\"));\n e.style.cssText = css;\n e.innerText = name || name === 0 ? type + \"-\" + name : type;\n parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);\n e._offset = e[\"offset\" + direction.op.d2];\n\n _positionMarker(e, 0, direction, isStart);\n\n return e;\n},\n _positionMarker = function _positionMarker(marker, start, direction, flipped) {\n var vars = {\n display: \"block\"\n },\n side = direction[flipped ? \"os2\" : \"p2\"],\n oppositeSide = direction[flipped ? \"p2\" : \"os2\"];\n marker._isFlipped = flipped;\n vars[direction.a + \"Percent\"] = flipped ? -100 : 0;\n vars[direction.a] = flipped ? \"1px\" : 0;\n vars[\"border\" + side + _Width] = 1;\n vars[\"border\" + oppositeSide + _Width] = 0;\n vars[direction.p] = start + \"px\";\n gsap.set(marker, vars);\n},\n _triggers = [],\n _ids = {},\n _rafID,\n _sync = function _sync() {\n return _getTime() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));\n},\n _onScroll = function _onScroll() {\n // previously, we tried to optimize performance by batching/deferring to the next requestAnimationFrame(), but discovered that Safari has a few bugs that make this unworkable (especially on iOS). See https://codepen.io/GreenSock/pen/16c435b12ef09c38125204818e7b45fc?editors=0010 and https://codepen.io/GreenSock/pen/JjOxYpQ/3dd65ccec5a60f1d862c355d84d14562?editors=0010 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503?editors=0010\n if (!_normalizer || !_normalizer.isPressed || _normalizer.startX > _body.clientWidth) {\n // if the user is dragging the scrollbar, allow it.\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n\n if (_normalizer) {\n _rafID || (_rafID = requestAnimationFrame(_updateAll));\n } else {\n _updateAll(); // Safari in particular (on desktop) NEEDS the immediate update rather than waiting for a requestAnimationFrame() whereas iOS seems to benefit from waiting for the requestAnimationFrame() tick, at least when normalizing. See https://codepen.io/GreenSock/pen/qBYozqO?editors=0110\n\n }\n\n _lastScrollTime || _dispatch(\"scrollStart\");\n _lastScrollTime = _getTime();\n }\n},\n _setBaseDimensions = function _setBaseDimensions() {\n _baseScreenWidth = _win.innerWidth;\n _baseScreenHeight = _win.innerHeight;\n},\n _onResize = function _onResize() {\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n !_refreshing && !_ignoreResize && !_doc.fullscreenElement && !_doc.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== _win.innerWidth || Math.abs(_win.innerHeight - _baseScreenHeight) > _win.innerHeight * 0.25) && _resizeDelay.restart(true);\n},\n // ignore resizes triggered by refresh()\n_listeners = {},\n _emptyArray = [],\n _softRefresh = function _softRefresh() {\n return _removeListener(ScrollTrigger, \"scrollEnd\", _softRefresh) || _refreshAll(true);\n},\n _dispatch = function _dispatch(type) {\n return _listeners[type] && _listeners[type].map(function (f) {\n return f();\n }) || _emptyArray;\n},\n _savedStyles = [],\n // when ScrollTrigger.saveStyles() is called, the inline styles are recorded in this Array in a sequential format like [element, cssText, gsCache, media]. This keeps it very memory-efficient and fast to iterate through.\n_revertRecorded = function _revertRecorded(media) {\n for (var i = 0; i < _savedStyles.length; i += 5) {\n if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {\n _savedStyles[i].style.cssText = _savedStyles[i + 1];\n _savedStyles[i].getBBox && _savedStyles[i].setAttribute(\"transform\", _savedStyles[i + 2] || \"\");\n _savedStyles[i + 3].uncache = 1;\n }\n }\n},\n _revertAll = function _revertAll(kill, media) {\n var trigger;\n\n for (_i = 0; _i < _triggers.length; _i++) {\n trigger = _triggers[_i];\n\n if (trigger && (!media || trigger._ctx === media)) {\n if (kill) {\n trigger.kill(1);\n } else {\n trigger.revert(true, true);\n }\n }\n }\n\n media && _revertRecorded(media);\n media || _dispatch(\"revert\");\n},\n _clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {\n // zero-out all the recorded scroll positions. Don't use _triggers because if, for example, .matchMedia() is used to create some ScrollTriggers and then the user resizes and it removes ALL ScrollTriggers, and then go back to a size where there are ScrollTriggers, it would have kept the position(s) saved from the initial state.\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n (force || !_refreshingAll) && _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0);\n });\n _isString(scrollRestoration) && (_win.history.scrollRestoration = _scrollRestoration = scrollRestoration);\n},\n _refreshingAll,\n _refreshID = 0,\n _queueRefreshID,\n _queueRefreshAll = function _queueRefreshAll() {\n // we don't want to call _refreshAll() every time we create a new ScrollTrigger (for performance reasons) - it's better to batch them. Some frameworks dynamically load content and we can't rely on the window's \"load\" or \"DOMContentLoaded\" events to trigger it.\n if (_queueRefreshID !== _refreshID) {\n var id = _queueRefreshID = _refreshID;\n requestAnimationFrame(function () {\n return id === _refreshID && _refreshAll(true);\n });\n }\n},\n _refreshAll = function _refreshAll(force, skipRevert) {\n if (_lastScrollTime && !force) {\n _addListener(ScrollTrigger, \"scrollEnd\", _softRefresh);\n\n return;\n }\n\n _refreshingAll = ScrollTrigger.isRefreshing = true;\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n return _isFunction(obj) && obj.cacheID++ && (obj.rec = obj());\n }); // force the clearing of the cache because some browsers take a little while to dispatch the \"scroll\" event and the user may have changed the scroll position and then called ScrollTrigger.refresh() right away\n\n\n var refreshInits = _dispatch(\"refreshInit\");\n\n _sort && ScrollTrigger.sort();\n skipRevert || _revertAll();\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n if (_isFunction(obj)) {\n obj.smooth && (obj.target.style.scrollBehavior = \"auto\"); // smooth scrolling interferes\n\n obj(0);\n }\n });\n\n _triggers.slice(0).forEach(function (t) {\n return t.refresh();\n }); // don't loop with _i because during a refresh() someone could call ScrollTrigger.update() which would iterate through _i resulting in a skip.\n\n\n _triggers.forEach(function (t, i) {\n // nested pins (pinnedContainer) with pinSpacing may expand the container, so we must accommodate that here.\n if (t._subPinOffset && t.pin) {\n var prop = t.vars.horizontal ? \"offsetWidth\" : \"offsetHeight\",\n original = t.pin[prop];\n t.revert(true, 1);\n t.adjustPinSpacing(t.pin[prop] - original);\n t.refresh();\n }\n });\n\n _triggers.forEach(function (t) {\n return t.vars.end === \"max\" && t.setPositions(t.start, Math.max(t.start + 1, _maxScroll(t.scroller, t._dir)));\n }); // the scroller's max scroll position may change after all the ScrollTriggers refreshed (like pinning could push it down), so we need to loop back and correct any with end: \"max\".\n\n\n refreshInits.forEach(function (result) {\n return result && result.render && result.render(-1);\n }); // if the onRefreshInit() returns an animation (typically a gsap.set()), revert it. This makes it easy to put things in a certain spot before refreshing for measurement purposes, and then put things back.\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n if (_isFunction(obj)) {\n obj.smooth && requestAnimationFrame(function () {\n return obj.target.style.scrollBehavior = \"smooth\";\n });\n obj.rec && obj(obj.rec);\n }\n });\n\n _clearScrollMemory(_scrollRestoration, 1);\n\n _resizeDelay.pause();\n\n _refreshID++;\n _refreshingAll = 2;\n\n _updateAll(2);\n\n _triggers.forEach(function (t) {\n return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);\n });\n\n _refreshingAll = ScrollTrigger.isRefreshing = false;\n\n _dispatch(\"refresh\");\n},\n _lastScroll = 0,\n _direction = 1,\n _primary,\n _updateAll = function _updateAll(force) {\n if (!_refreshingAll || force === 2) {\n ScrollTrigger.isUpdating = true;\n _primary && _primary.update(0); // ScrollSmoother uses refreshPriority -9999 to become the primary that gets updated before all others because it affects the scroll position.\n\n var l = _triggers.length,\n time = _getTime(),\n recordVelocity = time - _time1 >= 50,\n scroll = l && _triggers[0].scroll();\n\n _direction = _lastScroll > scroll ? -1 : 1;\n _refreshingAll || (_lastScroll = scroll);\n\n if (recordVelocity) {\n if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {\n _lastScrollTime = 0;\n\n _dispatch(\"scrollEnd\");\n }\n\n _time2 = _time1;\n _time1 = time;\n }\n\n if (_direction < 0) {\n _i = l;\n\n while (_i-- > 0) {\n _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n }\n\n _direction = 1;\n } else {\n for (_i = 0; _i < l; _i++) {\n _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n }\n }\n\n ScrollTrigger.isUpdating = false;\n }\n\n _rafID = 0;\n},\n _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, \"display\", \"flexShrink\", \"float\", \"zIndex\", \"gridColumnStart\", \"gridColumnEnd\", \"gridRowStart\", \"gridRowEnd\", \"gridArea\", \"justifySelf\", \"alignSelf\", \"placeSelf\", \"order\"],\n _stateProps = _propNamesToCopy.concat([_width, _height, \"boxSizing\", \"max\" + _Width, \"max\" + _Height, \"position\", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),\n _swapPinOut = function _swapPinOut(pin, spacer, state) {\n _setState(state);\n\n var cache = pin._gsap;\n\n if (cache.spacerIsNative) {\n _setState(cache.spacerState);\n } else if (pin._gsap.swappedIn) {\n var parent = spacer.parentNode;\n\n if (parent) {\n parent.insertBefore(pin, spacer);\n parent.removeChild(spacer);\n }\n }\n\n pin._gsap.swappedIn = false;\n},\n _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {\n if (!pin._gsap.swappedIn) {\n var i = _propNamesToCopy.length,\n spacerStyle = spacer.style,\n pinStyle = pin.style,\n p;\n\n while (i--) {\n p = _propNamesToCopy[i];\n spacerStyle[p] = cs[p];\n }\n\n spacerStyle.position = cs.position === \"absolute\" ? \"absolute\" : \"relative\";\n cs.display === \"inline\" && (spacerStyle.display = \"inline-block\");\n pinStyle[_bottom] = pinStyle[_right] = \"auto\";\n spacerStyle.flexBasis = cs.flexBasis || \"auto\";\n spacerStyle.overflow = \"visible\";\n spacerStyle.boxSizing = \"border-box\";\n spacerStyle[_width] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal) + _px;\n spacerStyle[_height] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical) + _px;\n spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = \"0\";\n\n _setState(spacerState);\n\n pinStyle[_width] = pinStyle[\"max\" + _Width] = cs[_width];\n pinStyle[_height] = pinStyle[\"max\" + _Height] = cs[_height];\n pinStyle[_padding] = cs[_padding];\n\n if (pin.parentNode !== spacer) {\n pin.parentNode.insertBefore(spacer, pin);\n spacer.appendChild(pin);\n }\n\n pin._gsap.swappedIn = true;\n }\n},\n _capsExp = /([A-Z])/g,\n _setState = function _setState(state) {\n if (state) {\n var style = state.t.style,\n l = state.length,\n i = 0,\n p,\n value;\n (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off\n\n for (; i < l; i += 2) {\n value = state[i + 1];\n p = state[i];\n\n if (value) {\n style[p] = value;\n } else if (style[p]) {\n style.removeProperty(p.replace(_capsExp, \"-$1\").toLowerCase());\n }\n }\n }\n},\n _getState = function _getState(element) {\n // returns an Array with alternating values like [property, value, property, value] and a \"t\" property pointing to the target (element). Makes it fast and cheap.\n var l = _stateProps.length,\n style = element.style,\n state = [],\n i = 0;\n\n for (; i < l; i++) {\n state.push(_stateProps[i], style[_stateProps[i]]);\n }\n\n state.t = element;\n return state;\n},\n _copyState = function _copyState(state, override, omitOffsets) {\n var result = [],\n l = state.length,\n i = omitOffsets ? 8 : 0,\n // skip top, left, right, bottom if omitOffsets is true\n p;\n\n for (; i < l; i += 2) {\n p = state[i];\n result.push(p, p in override ? override[p] : state[i + 1]);\n }\n\n result.t = state.t;\n return result;\n},\n _winOffsets = {\n left: 0,\n top: 0\n},\n // // potential future feature (?) Allow users to calculate where a trigger hits (scroll position) like getScrollPosition(\"#id\", \"top bottom\")\n// _getScrollPosition = (trigger, position, {scroller, containerAnimation, horizontal}) => {\n// \tscroller = _getTarget(scroller || _win);\n// \tlet direction = horizontal ? _horizontal : _vertical,\n// \t\tisViewport = _isViewport(scroller);\n// \t_getSizeFunc(scroller, isViewport, direction);\n// \treturn _parsePosition(position, _getTarget(trigger), _getSizeFunc(scroller, isViewport, direction)(), direction, _getScrollFunc(scroller, direction)(), 0, 0, 0, _getOffsetsFunc(scroller, isViewport)(), isViewport ? 0 : parseFloat(_getComputedStyle(scroller)[\"border\" + direction.p2 + _Width]) || 0, 0, containerAnimation ? containerAnimation.duration() : _maxScroll(scroller), containerAnimation);\n// },\n_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) {\n _isFunction(value) && (value = value(self));\n\n if (_isString(value) && value.substr(0, 3) === \"max\") {\n value = scrollerMax + (value.charAt(4) === \"=\" ? _offsetToPx(\"0\" + value.substr(3), scrollerSize) : 0);\n }\n\n var time = containerAnimation ? containerAnimation.time() : 0,\n p1,\n p2,\n element;\n containerAnimation && containerAnimation.seek(0);\n\n if (!_isNumber(value)) {\n _isFunction(trigger) && (trigger = trigger(self));\n var offsets = (value || \"0\").split(\" \"),\n bounds,\n localOffset,\n globalOffset,\n display;\n element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(trigger) || _body;\n bounds = _getBounds(element) || {};\n\n if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === \"none\") {\n // if display is \"none\", it won't report getBoundingClientRect() properly\n display = element.style.display;\n element.style.display = \"block\";\n bounds = _getBounds(element);\n display ? element.style.display = display : element.style.removeProperty(\"display\");\n }\n\n localOffset = _offsetToPx(offsets[0], bounds[direction.d]);\n globalOffset = _offsetToPx(offsets[1] || \"0\", scrollerSize);\n value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;\n markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);\n scrollerSize -= scrollerSize - globalOffset; // adjust for the marker\n } else {\n containerAnimation && (value = gsap.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMax, value));\n markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);\n }\n\n if (marker) {\n var position = value + scrollerSize,\n isStart = marker._isStart;\n p1 = \"scroll\" + direction.d2;\n\n _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1);\n\n if (useFixedPosition) {\n scrollerBounds = _getBounds(markerScroller);\n useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);\n }\n }\n\n if (containerAnimation && element) {\n p1 = _getBounds(element);\n containerAnimation.seek(scrollerMax);\n p2 = _getBounds(element);\n containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];\n value = value / containerAnimation._caScrollDist * scrollerMax;\n }\n\n containerAnimation && containerAnimation.seek(time);\n return containerAnimation ? value : Math.round(value);\n},\n _prefixExp = /(webkit|moz|length|cssText|inset)/i,\n _reparent = function _reparent(element, parent, top, left) {\n if (element.parentNode !== parent) {\n var style = element.style,\n p,\n cs;\n\n if (parent === _body) {\n element._stOrig = style.cssText; // record original inline styles so we can revert them later\n\n cs = _getComputedStyle(element);\n\n for (p in cs) {\n // must copy all relevant styles to ensure that nothing changes visually when we reparent to the . Skip the vendor prefixed ones.\n if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === \"string\" && p !== \"0\") {\n style[p] = cs[p];\n }\n }\n\n style.top = top;\n style.left = left;\n } else {\n style.cssText = element._stOrig;\n }\n\n gsap.core.getCache(element).uncache = 1;\n parent.appendChild(element);\n }\n},\n _interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {\n var last1 = initialValue,\n last2 = last1;\n return function (value) {\n var current = Math.round(getValueFunc()); // round because in some [very uncommon] Windows environments, scroll can get reported with decimals even though it was set without.\n\n if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {\n // if the user scrolls, kill the tween. iOS Safari intermittently misreports the scroll position, it may be the most recently-set one or the one before that! When Safari is zoomed (CMD-+), it often misreports as 1 pixel off too! So if we set the scroll position to 125, for example, it'll actually report it as 124.\n value = current;\n onInterrupt && onInterrupt();\n }\n\n last2 = last1;\n last1 = value;\n return value;\n };\n},\n // _mergeAnimations = animations => {\n// \tlet tl = gsap.timeline({smoothChildTiming: true}).startTime(Math.min(...animations.map(a => a.globalTime(0))));\n// \tanimations.forEach(a => {let time = a.totalTime(); tl.add(a); a.totalTime(time); });\n// \ttl.smoothChildTiming = false;\n// \treturn tl;\n// },\n// returns a function that can be used to tween the scroll position in the direction provided, and when doing so it'll add a .tween property to the FUNCTION itself, and remove it when the tween completes or gets killed. This gives us a way to have multiple ScrollTriggers use a central function for any given scroller and see if there's a scroll tween running (which would affect if/how things get updated)\n_getTweenCreator = function _getTweenCreator(scroller, direction) {\n var getScroll = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction),\n prop = \"_scroll\" + direction.p2,\n // add a tweenable property to the scroller that's a getter/setter function, like _scrollTop or _scrollLeft. This way, if someone does gsap.killTweensOf(scroller) it'll kill the scroll tween.\n lastScroll1,\n lastScroll2,\n getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {\n var tween = getTween.tween,\n onComplete = vars.onComplete,\n modifiers = {};\n initialValue = initialValue || getScroll();\n\n var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {\n tween.kill();\n getTween.tween = 0;\n });\n\n change2 = change1 && change2 || 0; // if change1 is 0, we set that to the difference and ignore change2. Otherwise, there would be a compound effect.\n\n change1 = change1 || scrollTo - initialValue;\n tween && tween.kill();\n lastScroll1 = Math.round(initialValue);\n vars[prop] = scrollTo;\n vars.modifiers = modifiers;\n\n modifiers[prop] = function () {\n return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);\n };\n\n vars.onUpdate = function () {\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n\n _updateAll();\n };\n\n vars.onComplete = function () {\n getTween.tween = 0;\n onComplete && onComplete.call(tween);\n };\n\n tween = getTween.tween = gsap.to(scroller, vars);\n return tween;\n };\n\n scroller[prop] = getScroll;\n\n getScroll.wheelHandler = function () {\n return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);\n };\n\n _addListener(scroller, \"wheel\", getScroll.wheelHandler); // Windows machines handle mousewheel scrolling in chunks (like \"3 lines per scroll\") meaning the typical strategy for cancelling the scroll isn't as sensitive. It's much more likely to match one of the previous 2 scroll event positions. So we kill any snapping as soon as there's a wheel event.\n\n\n ScrollTrigger.isTouch && _addListener(scroller, \"touchmove\", getScroll.wheelHandler);\n return getTween;\n};\n\nvar ScrollTrigger = /*#__PURE__*/function () {\n function ScrollTrigger(vars, animation) {\n _coreInitted || ScrollTrigger.register(gsap) || console.warn(\"Please gsap.registerPlugin(ScrollTrigger)\");\n this.init(vars, animation);\n }\n\n var _proto = ScrollTrigger.prototype;\n\n _proto.init = function init(vars, animation) {\n this.progress = this.start = 0;\n this.vars && this.kill(true, true); // in case it's being initted again\n\n if (!_enabled) {\n this.update = this.refresh = this.kill = _passThrough;\n return;\n }\n\n vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? {\n trigger: vars\n } : vars, _defaults);\n\n var _vars = vars,\n onUpdate = _vars.onUpdate,\n toggleClass = _vars.toggleClass,\n id = _vars.id,\n onToggle = _vars.onToggle,\n onRefresh = _vars.onRefresh,\n scrub = _vars.scrub,\n trigger = _vars.trigger,\n pin = _vars.pin,\n pinSpacing = _vars.pinSpacing,\n invalidateOnRefresh = _vars.invalidateOnRefresh,\n anticipatePin = _vars.anticipatePin,\n onScrubComplete = _vars.onScrubComplete,\n onSnapComplete = _vars.onSnapComplete,\n once = _vars.once,\n snap = _vars.snap,\n pinReparent = _vars.pinReparent,\n pinSpacer = _vars.pinSpacer,\n containerAnimation = _vars.containerAnimation,\n fastScrollEnd = _vars.fastScrollEnd,\n preventOverlaps = _vars.preventOverlaps,\n direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical,\n isToggle = !scrub && scrub !== 0,\n scroller = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.scroller || _win),\n scrollerCache = gsap.core.getCache(scroller),\n isViewport = _isViewport(scroller),\n useFixedPosition = (\"pinType\" in vars ? vars.pinType : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, \"pinType\") || isViewport && \"fixed\") === \"fixed\",\n callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],\n toggleActions = isToggle && vars.toggleActions.split(\" \"),\n markers = \"markers\" in vars ? vars.markers : _defaults.markers,\n borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)[\"border\" + direction.p2 + _Width]) || 0,\n self = this,\n onRefreshInit = vars.onRefreshInit && function () {\n return vars.onRefreshInit(self);\n },\n getScrollerSize = _getSizeFunc(scroller, isViewport, direction),\n getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),\n lastSnap = 0,\n lastRefresh = 0,\n scrollFunc = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction),\n tweenTo,\n pinCache,\n snapFunc,\n scroll1,\n scroll2,\n start,\n end,\n markerStart,\n markerEnd,\n markerStartTrigger,\n markerEndTrigger,\n markerVars,\n change,\n pinOriginalState,\n pinActiveState,\n pinState,\n spacer,\n offset,\n pinGetter,\n pinSetter,\n pinStart,\n pinChange,\n spacingStart,\n spacerState,\n markerStartSetter,\n pinMoves,\n markerEndSetter,\n cs,\n snap1,\n snap2,\n scrubTween,\n scrubSmooth,\n snapDurClamp,\n snapDelayedCall,\n prevProgress,\n prevScroll,\n prevAnimProgress,\n caMarkerSetter,\n customRevertReturn;\n\n _context(self);\n\n self._dir = direction;\n anticipatePin *= 45;\n self.scroller = scroller;\n self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;\n scroll1 = scrollFunc();\n self.vars = vars;\n animation = animation || vars.animation;\n\n if (\"refreshPriority\" in vars) {\n _sort = 1;\n vars.refreshPriority === -9999 && (_primary = self); // used by ScrollSmoother\n }\n\n scrollerCache.tweenScroll = scrollerCache.tweenScroll || {\n top: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical),\n left: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal)\n };\n self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];\n\n self.scrubDuration = function (value) {\n scrubSmooth = _isNumber(value) && value;\n\n if (!scrubSmooth) {\n scrubTween && scrubTween.progress(1).kill();\n scrubTween = 0;\n } else {\n scrubTween ? scrubTween.duration(value) : scrubTween = gsap.to(animation, {\n ease: \"expo\",\n totalProgress: \"+=0.001\",\n duration: scrubSmooth,\n paused: true,\n onComplete: function onComplete() {\n return onScrubComplete && onScrubComplete(self);\n }\n });\n }\n };\n\n if (animation) {\n animation.vars.lazy = false;\n animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true);\n self.animation = animation.pause();\n animation.scrollTrigger = self;\n self.scrubDuration(scrub);\n scrubTween && scrubTween.resetTo && scrubTween.resetTo(\"totalProgress\", 0); // otherwise the initial scrub progress value would start at 0.001 which normally is no big deal, but for containerAnimation it can be noticeable since the range is so tiny.\n\n snap1 = 0;\n id || (id = animation.vars.id);\n }\n\n _triggers.push(self);\n\n if (snap) {\n // TODO: potential idea: use legitimate CSS scroll snapping by pushing invisible elements into the DOM that serve as snap positions, and toggle the document.scrollingElement.style.scrollSnapType onToggle. See https://codepen.io/GreenSock/pen/JjLrgWM for a quick proof of concept.\n if (!_isObject(snap) || snap.push) {\n snap = {\n snapTo: snap\n };\n }\n\n \"scrollBehavior\" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, {\n scrollBehavior: \"auto\"\n }); // smooth scrolling doesn't work with snap.\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (o) {\n return _isFunction(o) && o.target === (isViewport ? _doc.scrollingElement || _docEl : scroller) && (o.smooth = false);\n }); // note: set smooth to false on both the vertical and horizontal scroll getters/setters\n\n\n snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === \"labels\" ? _getClosestLabel(animation) : snap.snapTo === \"labelsDirectional\" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {\n return _snapDirectional(snap.snapTo)(value, _getTime() - lastRefresh < 500 ? 0 : st.direction);\n } : gsap.utils.snap(snap.snapTo);\n snapDurClamp = snap.duration || {\n min: 0.1,\n max: 2\n };\n snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp);\n snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {\n var scroll = scrollFunc(),\n refreshedRecently = _getTime() - lastRefresh < 500,\n tween = tweenTo.tween;\n\n if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {\n var progress = (scroll - start) / change,\n totalProgress = animation && !isToggle ? animation.totalProgress() : progress,\n velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0,\n change1 = gsap.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),\n naturalEnd = progress + (snap.inertia === false ? 0 : change1),\n endValue = _clamp(0, 1, snapFunc(naturalEnd, self)),\n endScroll = Math.round(start + endValue * change),\n _snap = snap,\n onStart = _snap.onStart,\n _onInterrupt = _snap.onInterrupt,\n _onComplete = _snap.onComplete;\n\n if (scroll <= end && scroll >= start && endScroll !== scroll) {\n if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {\n // there's an overlapping snap! So we must figure out which one is closer and let that tween live.\n return;\n }\n\n if (snap.inertia === false) {\n change1 = endValue - progress;\n }\n\n tweenTo(endScroll, {\n duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),\n ease: snap.ease || \"power3\",\n data: _abs(endScroll - scroll),\n // record the distance so that if another snap tween occurs (conflict) we can prioritize the closest snap.\n onInterrupt: function onInterrupt() {\n return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self);\n },\n onComplete: function onComplete() {\n self.update();\n lastSnap = scrollFunc();\n snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;\n onSnapComplete && onSnapComplete(self);\n _onComplete && _onComplete(self);\n }\n }, scroll, change1 * change, endScroll - scroll - change1 * change);\n onStart && onStart(self, tweenTo.tween);\n }\n } else if (self.isActive && lastSnap !== scroll) {\n snapDelayedCall.restart(true);\n }\n }).pause();\n }\n\n id && (_ids[id] = self);\n trigger = self.trigger = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(trigger || pin); // if a trigger has some kind of scroll-related effect applied that could contaminate the \"y\" or \"x\" position (like a ScrollSmoother effect), we needed a way to temporarily revert it, so we use the stRevert property of the gsCache. It can return another function that we'll call at the end so it can return to its normal state.\n\n customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;\n customRevertReturn && (customRevertReturn = customRevertReturn(self));\n pin = pin === true ? trigger : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pin);\n _isString(toggleClass) && (toggleClass = {\n targets: trigger,\n className: toggleClass\n });\n\n if (pin) {\n pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === \"flex\" ? false : _padding); // if the parent is display: flex, don't apply pinSpacing by default. We should check that pin.parentNode is an element (not shadow dom window)\n\n self.pin = pin;\n pinCache = gsap.core.getCache(pin);\n\n if (!pinCache.spacer) {\n // record the spacer and pinOriginalState on the cache in case someone tries pinning the same element with MULTIPLE ScrollTriggers - we don't want to have multiple spacers or record the \"original\" pin state after it has already been affected by another ScrollTrigger.\n if (pinSpacer) {\n pinSpacer = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pinSpacer);\n pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); // for React & Angular\n\n pinCache.spacerIsNative = !!pinSpacer;\n pinSpacer && (pinCache.spacerState = _getState(pinSpacer));\n }\n\n pinCache.spacer = spacer = pinSpacer || _doc.createElement(\"div\");\n spacer.classList.add(\"pin-spacer\");\n id && spacer.classList.add(\"pin-spacer-\" + id);\n pinCache.pinState = pinOriginalState = _getState(pin);\n } else {\n pinOriginalState = pinCache.pinState;\n }\n\n vars.force3D !== false && gsap.set(pin, {\n force3D: true\n });\n self.spacer = spacer = pinCache.spacer;\n cs = _getComputedStyle(pin);\n spacingStart = cs[pinSpacing + direction.os2];\n pinGetter = gsap.getProperty(pin);\n pinSetter = gsap.quickSetter(pin, direction.a, _px); // pin.firstChild && !_maxScroll(pin, direction) && (pin.style.overflow = \"hidden\"); // protects from collapsing margins, but can have unintended consequences as demonstrated here: https://codepen.io/GreenSock/pen/1e42c7a73bfa409d2cf1e184e7a4248d so it was removed in favor of just telling people to set up their CSS to avoid the collapsing margins (overflow: hidden | auto is just one option. Another is border-top: 1px solid transparent).\n\n _swapPinIn(pin, spacer, cs);\n\n pinState = _getState(pin);\n }\n\n if (markers) {\n markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults;\n markerStartTrigger = _createMarker(\"scroller-start\", id, scroller, direction, markerVars, 0);\n markerEndTrigger = _createMarker(\"scroller-end\", id, scroller, direction, markerVars, 0, markerStartTrigger);\n offset = markerStartTrigger[\"offset\" + direction.op.d2];\n\n var content = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)((0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, \"content\") || scroller);\n\n markerStart = this.markerStart = _createMarker(\"start\", id, content, direction, markerVars, offset, 0, containerAnimation);\n markerEnd = this.markerEnd = _createMarker(\"end\", id, content, direction, markerVars, offset, 0, containerAnimation);\n containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px));\n\n if (!useFixedPosition && !(_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.length && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, \"fixedMarkers\") === true)) {\n _makePositionable(isViewport ? _body : scroller);\n\n gsap.set([markerStartTrigger, markerEndTrigger], {\n force3D: true\n });\n markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px);\n markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px);\n }\n }\n\n if (containerAnimation) {\n var oldOnUpdate = containerAnimation.vars.onUpdate,\n oldParams = containerAnimation.vars.onUpdateParams;\n containerAnimation.eventCallback(\"onUpdate\", function () {\n self.update(0, 0, 1);\n oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);\n });\n }\n\n self.previous = function () {\n return _triggers[_triggers.indexOf(self) - 1];\n };\n\n self.next = function () {\n return _triggers[_triggers.indexOf(self) + 1];\n };\n\n self.revert = function (revert, temp) {\n if (!temp) {\n return self.kill(true);\n } // for compatibility with gsap.context() and gsap.matchMedia() which call revert()\n\n\n var r = revert !== false || !self.enabled,\n prevRefreshing = _refreshing;\n\n if (r !== self.isReverted) {\n if (r) {\n // if (!self.scroll.rec && (_refreshing || _refreshingAll)) {\n // \tself.scroll.rec = scrollFunc();\n // \t_refreshingAll && scrollFunc(0);\n // }\n prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); // record the scroll so we can revert later (repositioning/pinning things can affect scroll position). In the static refresh() method, we first record all the scroll positions as a reference.\n\n prevProgress = self.progress;\n prevAnimProgress = animation && animation.progress();\n }\n\n markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n return m.style.display = r ? \"none\" : \"block\";\n });\n\n if (r) {\n _refreshing = self;\n self.update(r); // make sure the pin is back in its original position so that all the measurements are correct. do this BEFORE swapping the pin out\n }\n\n if (pin && (!pinReparent || !self.isActive)) {\n if (r) {\n _swapPinOut(pin, spacer, pinOriginalState);\n } else {\n _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);\n }\n }\n\n r || self.update(r); // when we're restoring, the update should run AFTER swapping the pin into its pin-spacer.\n\n _refreshing = prevRefreshing; // restore. We set it to true during the update() so that things fire properly in there.\n\n self.isReverted = r;\n }\n };\n\n self.refresh = function (soft, force) {\n if ((_refreshing || !self.enabled) && !force) {\n return;\n }\n\n if (pin && soft && _lastScrollTime) {\n _addListener(ScrollTrigger, \"scrollEnd\", _softRefresh);\n\n return;\n }\n\n !_refreshingAll && onRefreshInit && onRefreshInit(self);\n _refreshing = self;\n lastRefresh = _getTime();\n\n if (tweenTo.tween) {\n tweenTo.tween.kill();\n tweenTo.tween = 0;\n }\n\n scrubTween && scrubTween.pause();\n invalidateOnRefresh && animation && animation.revert({\n kill: false\n }).invalidate();\n self.isReverted || self.revert(true, true);\n self._subPinOffset = false; // we'll set this to true in the sub-pins if we find any\n\n var size = getScrollerSize(),\n scrollerBounds = getScrollerOffsets(),\n max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction),\n isFirstRefresh = change <= 0.01,\n offset = 0,\n otherPinOffset = 0,\n parsedEnd = vars.end,\n parsedEndTrigger = vars.endTrigger || trigger,\n parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? \"0 0\" : \"0 100%\"),\n pinnedContainer = self.pinnedContainer = vars.pinnedContainer && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.pinnedContainer),\n triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,\n i = triggerIndex,\n cs,\n bounds,\n scroll,\n isVertical,\n override,\n curTrigger,\n curPin,\n oppositeScroll,\n initted,\n revertedPins,\n forcedOverflow;\n\n while (i--) {\n // user might try to pin the same element more than once, so we must find any prior triggers with the same pin, revert them, and determine how long they're pinning so that we can offset things appropriately. Make sure we revert from last to first so that things \"rewind\" properly.\n curTrigger = _triggers[i];\n curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self); // if it's a timeline-based trigger that hasn't been fully initialized yet because it's waiting for 1 tick, just force the refresh() here, otherwise if it contains a pin that's supposed to affect other ScrollTriggers further down the page, they won't be adjusted properly.\n\n curPin = curTrigger.pin;\n\n if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {\n revertedPins || (revertedPins = []);\n revertedPins.unshift(curTrigger); // we'll revert from first to last to make sure things reach their end state properly\n\n curTrigger.revert(true, true);\n }\n\n if (curTrigger !== _triggers[i]) {\n // in case it got removed.\n triggerIndex--;\n i--;\n }\n }\n\n _isFunction(parsedStart) && (parsedStart = parsedStart(self));\n start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0);\n _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));\n\n if (_isString(parsedEnd) && !parsedEnd.indexOf(\"+=\")) {\n if (~parsedEnd.indexOf(\" \")) {\n parsedEnd = (_isString(parsedStart) ? parsedStart.split(\" \")[0] : \"\") + parsedEnd;\n } else {\n offset = _offsetToPx(parsedEnd.substr(2), size);\n parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset; // _parsePosition won't factor in the offset if the start is a number, so do it here.\n\n parsedEndTrigger = trigger;\n }\n }\n\n end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? \"100% 0\" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation)) || -0.001;\n change = end - start || (start -= 0.01) && 0.001;\n offset = 0;\n i = triggerIndex;\n\n while (i--) {\n curTrigger = _triggers[i];\n curPin = curTrigger.pin;\n\n if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {\n cs = curTrigger.end - curTrigger.start;\n\n if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && !_isNumber(parsedStart)) {\n // numeric start values shouldn't be offset at all - treat them as absolute\n offset += cs * (1 - curTrigger.progress);\n }\n\n curPin === pin && (otherPinOffset += cs);\n }\n }\n\n start += offset;\n end += offset;\n\n if (isFirstRefresh) {\n // on the very first refresh(), the prevProgress couldn't have been accurate yet because the start/end were never calculated, so we set it here. Before 3.11.5, it could lead to an inaccurate scroll position restoration with snapping.\n prevProgress = gsap.utils.clamp(0, 1, gsap.utils.normalize(start, end, prevScroll));\n }\n\n self._pinPush = otherPinOffset;\n\n if (markerStart && offset) {\n // offset the markers if necessary\n cs = {};\n cs[direction.a] = \"+=\" + offset;\n pinnedContainer && (cs[direction.p] = \"-=\" + scrollFunc());\n gsap.set([markerStart, markerEnd], cs);\n }\n\n if (pin) {\n cs = _getComputedStyle(pin);\n isVertical = direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical;\n scroll = scrollFunc(); // recalculate because the triggers can affect the scroll\n\n pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;\n\n if (!max && end > 1) {\n // makes sure the scroller has a scrollbar, otherwise if something has width: 100%, for example, it would be too big (exclude the scrollbar). See https://greensock.com/forums/topic/25182-scrolltrigger-width-of-page-increase-where-markers-are-set-to-false/\n forcedOverflow = (isViewport ? _doc.scrollingElement || _docEl : scroller).style;\n forcedOverflow = {\n style: forcedOverflow,\n value: forcedOverflow[\"overflow\" + direction.a.toUpperCase()]\n };\n forcedOverflow.style[\"overflow\" + direction.a.toUpperCase()] = \"scroll\";\n }\n\n _swapPinIn(pin, spacer, cs);\n\n pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms.\n\n bounds = _getBounds(pin, true);\n oppositeScroll = useFixedPosition && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, isVertical ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical)();\n\n if (pinSpacing) {\n spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];\n spacerState.t = spacer;\n i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;\n i && spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding).\n\n _setState(spacerState);\n\n if (pinnedContainer) {\n // in ScrollTrigger.refresh(), we need to re-evaluate the pinContainer's size because this pinSpacing may stretch it out, but we can't just add the exact distance because depending on layout, it may not push things down or it may only do so partially.\n _triggers.forEach(function (t) {\n if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {\n t._subPinOffset = true;\n }\n });\n }\n\n useFixedPosition && scrollFunc(prevScroll);\n }\n\n if (useFixedPosition) {\n override = {\n top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,\n left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,\n boxSizing: \"border-box\",\n position: \"fixed\"\n };\n override[_width] = override[\"max\" + _Width] = Math.ceil(bounds.width) + _px;\n override[_height] = override[\"max\" + _Height] = Math.ceil(bounds.height) + _px;\n override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = \"0\";\n override[_padding] = cs[_padding];\n override[_padding + _Top] = cs[_padding + _Top];\n override[_padding + _Right] = cs[_padding + _Right];\n override[_padding + _Bottom] = cs[_padding + _Bottom];\n override[_padding + _Left] = cs[_padding + _Left];\n pinActiveState = _copyState(pinOriginalState, override, pinReparent);\n _refreshingAll && scrollFunc(0);\n }\n\n if (animation) {\n // the animation might be affecting the transform, so we must jump to the end, check the value, and compensate accordingly. Otherwise, when it becomes unpinned, the pinSetter() will get set to a value that doesn't include whatever the animation did.\n initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock in starting values prematurely.\n\n _suppressOverwrites(1);\n\n animation.render(animation.duration(), true, true);\n pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;\n pinMoves = Math.abs(change - pinChange) > 1;\n useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2); // transform is the last property/value set in the state Array. Since the animation is controlling that, we should omit it.\n\n animation.render(0, true, true);\n initted || animation.invalidate(true);\n animation.parent || animation.totalTime(animation.totalTime()); // if, for example, a toggleAction called play() and then refresh() happens and when we render(1) above, it would cause the animation to complete and get removed from its parent, so this makes sure it gets put back in.\n\n _suppressOverwrites(0);\n } else {\n pinChange = change;\n }\n\n forcedOverflow && (forcedOverflow.value ? forcedOverflow.style[\"overflow\" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty(\"overflow-\" + direction.a));\n } else if (trigger && scrollFunc() && !containerAnimation) {\n // it may be INSIDE a pinned element, so walk up the tree and look for any elements with _pinOffset to compensate because anything with pinSpacing that's already scrolled would throw off the measurements in getBoundingClientRect()\n bounds = trigger.parentNode;\n\n while (bounds && bounds !== _body) {\n if (bounds._pinOffset) {\n start -= bounds._pinOffset;\n end -= bounds._pinOffset;\n }\n\n bounds = bounds.parentNode;\n }\n }\n\n revertedPins && revertedPins.forEach(function (t) {\n return t.revert(false, true);\n });\n self.start = start;\n self.end = end;\n scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc(); // reset velocity\n\n if (!containerAnimation && !_refreshingAll) {\n scroll1 < prevScroll && scrollFunc(prevScroll);\n self.scroll.rec = 0;\n }\n\n self.revert(false, true);\n\n if (snapDelayedCall) {\n lastSnap = -1;\n self.isActive && scrollFunc(start + change * prevProgress); // just so snapping gets re-enabled, clear out any recorded last value\n\n snapDelayedCall.restart(true);\n }\n\n _refreshing = 0;\n animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); // must force a re-render because if saveStyles() was used on the target(s), the styles could have been wiped out during the refresh().\n\n if (isFirstRefresh || prevProgress !== self.progress || containerAnimation) {\n // ensures that the direction is set properly (when refreshing, progress is set back to 0 initially, then back again to wherever it needs to be) and that callbacks are triggered.\n animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap.utils.normalize(start, end, 0) : prevProgress, true); // to avoid issues where animation callbacks like onStart aren't triggered.\n\n self.progress = (scroll1 - start) / change === prevProgress ? 0 : prevProgress;\n }\n\n pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));\n scrubTween && scrubTween.invalidate();\n onRefresh && !_refreshingAll && onRefresh(self); // when refreshing all, we do extra work to correct pinnedContainer sizes and ensure things don't exceed the maxScroll, so we should do all the refreshes at the end after all that work so that the start/end values are corrected.\n };\n\n self.getVelocity = function () {\n return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0;\n };\n\n self.endAnimation = function () {\n _endAnimation(self.callbackAnimation);\n\n if (animation) {\n scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);\n }\n };\n\n self.labelToScroll = function (label) {\n return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;\n };\n\n self.getTrailing = function (name) {\n var i = _triggers.indexOf(self),\n a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);\n\n return (_isString(name) ? a.filter(function (t) {\n return t.vars.preventOverlaps === name;\n }) : a).filter(function (t) {\n return self.direction > 0 ? t.end <= start : t.start >= end;\n });\n };\n\n self.update = function (reset, recordVelocity, forceFake) {\n if (containerAnimation && !forceFake && !reset) {\n return;\n }\n\n var scroll = _refreshingAll === true ? prevScroll : self.scroll(),\n p = reset ? 0 : (scroll - start) / change,\n clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,\n prevProgress = self.progress,\n isActive,\n wasActive,\n toggleState,\n action,\n stateChanged,\n toggled,\n isAtMax,\n isTakingAction;\n\n if (recordVelocity) {\n scroll2 = scroll1;\n scroll1 = containerAnimation ? scrollFunc() : scroll;\n\n if (snap) {\n snap2 = snap1;\n snap1 = animation && !isToggle ? animation.totalProgress() : clipped;\n }\n } // anticipate the pinning a few ticks ahead of time based on velocity to avoid a visual glitch due to the fact that most browsers do scrolling on a separate thread (not synced with requestAnimationFrame).\n\n\n anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001);\n\n if (clipped !== prevProgress && self.enabled) {\n isActive = self.isActive = !!clipped && clipped < 1;\n wasActive = !!prevProgress && prevProgress < 1;\n toggled = isActive !== wasActive;\n stateChanged = toggled || !!clipped !== !!prevProgress; // could go from start all the way to end, thus it didn't toggle but it did change state in a sense (may need to fire a callback)\n\n self.direction = clipped > prevProgress ? 1 : -1;\n self.progress = clipped;\n\n if (stateChanged && !_refreshing) {\n toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; // 0 = enter, 1 = leave, 2 = enterBack, 3 = leaveBack (we prioritize the FIRST encounter, thus if you scroll really fast past the onEnter and onLeave in one tick, it'd prioritize onEnter.\n\n if (isToggle) {\n action = !toggled && toggleActions[toggleState + 1] !== \"none\" && toggleActions[toggleState + 1] || toggleActions[toggleState]; // if it didn't toggle, that means it shot right past and since we prioritize the \"enter\" action, we should switch to the \"leave\" in this case (but only if one is defined)\n\n isTakingAction = animation && (action === \"complete\" || action === \"reset\" || action in animation);\n }\n }\n\n preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) {\n return t.endAnimation();\n }));\n\n if (!isToggle) {\n if (scrubTween && !_refreshing && !_startup) {\n scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start); // if there's a scrub on both the container animation and this one (or a ScrollSmoother), the update order would cause this one not to have rendered yet, so it wouldn't make any progress before we .restart() it heading toward the new progress so it'd appear stuck thus we force a render here.\n\n if (scrubTween.resetTo) {\n scrubTween.resetTo(\"totalProgress\", clipped, animation._tTime / animation._tDur);\n } else {\n // legacy support (courtesy), before 3.10.0\n scrubTween.vars.totalProgress = clipped;\n scrubTween.invalidate().restart();\n }\n } else if (animation) {\n animation.totalProgress(clipped, !!_refreshing);\n }\n }\n\n if (pin) {\n reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);\n\n if (!useFixedPosition) {\n pinSetter(_round(pinStart + pinChange * clipped));\n } else if (stateChanged) {\n isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); // if it's at the VERY end of the page, don't switch away from position: fixed because it's pointless and it could cause a brief flash when the user scrolls back up (when it gets pinned again)\n\n if (pinReparent) {\n if (!reset && (isActive || isAtMax)) {\n var bounds = _getBounds(pin, true),\n _offset = scroll - start;\n\n _reparent(pin, _body, bounds.top + (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? _offset : 0) + _px, bounds.left + (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? 0 : _offset) + _px);\n } else {\n _reparent(pin, spacer);\n }\n }\n\n _setState(isActive || isAtMax ? pinActiveState : pinState);\n\n pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));\n }\n }\n\n snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true);\n toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) {\n return el.classList[isActive || once ? \"add\" : \"remove\"](toggleClass.className);\n }); // classes could affect positioning, so do it even if reset or refreshing is true.\n\n onUpdate && !isToggle && !reset && onUpdate(self);\n\n if (stateChanged && !_refreshing) {\n if (isToggle) {\n if (isTakingAction) {\n if (action === \"complete\") {\n animation.pause().totalProgress(1);\n } else if (action === \"reset\") {\n animation.restart(true).pause();\n } else if (action === \"restart\") {\n animation.restart(true);\n } else {\n animation[action]();\n }\n }\n\n onUpdate && onUpdate(self);\n }\n\n if (toggled || !_limitCallbacks) {\n // on startup, the page could be scrolled and we don't want to fire callbacks that didn't toggle. For example onEnter shouldn't fire if the ScrollTrigger isn't actually entered.\n onToggle && toggled && _callback(self, onToggle);\n callbacks[toggleState] && _callback(self, callbacks[toggleState]);\n once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn't be called again if once is true.\n\n if (!toggled) {\n // it's possible to go completely past, like from before the start to after the end (or vice-versa) in which case BOTH callbacks should be fired in that order\n toggleState = clipped === 1 ? 1 : 3;\n callbacks[toggleState] && _callback(self, callbacks[toggleState]);\n }\n }\n\n if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {\n _endAnimation(self.callbackAnimation);\n\n scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === \"reverse\" ? 1 : !clipped, 1);\n }\n } else if (isToggle && onUpdate && !_refreshing) {\n onUpdate(self);\n }\n } // update absolutely-positioned markers (only if the scroller isn't the viewport)\n\n\n if (markerEndSetter) {\n var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;\n markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));\n markerEndSetter(n);\n }\n\n caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));\n };\n\n self.enable = function (reset, refresh) {\n if (!self.enabled) {\n self.enabled = true;\n\n _addListener(scroller, \"resize\", _onResize);\n\n _addListener(isViewport ? _doc : scroller, \"scroll\", _onScroll);\n\n onRefreshInit && _addListener(ScrollTrigger, \"refreshInit\", onRefreshInit);\n\n if (reset !== false) {\n self.progress = prevProgress = 0;\n scroll1 = scroll2 = lastSnap = scrollFunc();\n }\n\n refresh !== false && self.refresh();\n }\n };\n\n self.getTween = function (snap) {\n return snap && tweenTo ? tweenTo.tween : scrubTween;\n };\n\n self.setPositions = function (newStart, newEnd) {\n // doesn't persist after refresh()! Intended to be a way to override values that were set during refresh(), like you could set it in onRefresh()\n if (pin) {\n pinStart += newStart - start;\n pinChange += newEnd - newStart - change;\n pinSpacing === _padding && self.adjustPinSpacing(newEnd - newStart - change);\n }\n\n self.start = start = newStart;\n self.end = end = newEnd;\n change = newEnd - newStart;\n self.update();\n };\n\n self.adjustPinSpacing = function (amount) {\n if (spacerState && amount) {\n var i = spacerState.indexOf(direction.d) + 1;\n spacerState[i] = parseFloat(spacerState[i]) + amount + _px;\n spacerState[1] = parseFloat(spacerState[1]) + amount + _px;\n\n _setState(spacerState);\n }\n };\n\n self.disable = function (reset, allowAnimation) {\n if (self.enabled) {\n reset !== false && self.revert(true, true);\n self.enabled = self.isActive = false;\n allowAnimation || scrubTween && scrubTween.pause();\n prevScroll = 0;\n pinCache && (pinCache.uncache = 1);\n onRefreshInit && _removeListener(ScrollTrigger, \"refreshInit\", onRefreshInit);\n\n if (snapDelayedCall) {\n snapDelayedCall.pause();\n tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);\n }\n\n if (!isViewport) {\n var i = _triggers.length;\n\n while (i--) {\n if (_triggers[i].scroller === scroller && _triggers[i] !== self) {\n return; //don't remove the listeners if there are still other triggers referencing it.\n }\n }\n\n _removeListener(scroller, \"resize\", _onResize);\n\n _removeListener(scroller, \"scroll\", _onScroll);\n }\n }\n };\n\n self.kill = function (revert, allowAnimation) {\n self.disable(revert, allowAnimation);\n scrubTween && !allowAnimation && scrubTween.kill();\n id && delete _ids[id];\n\n var i = _triggers.indexOf(self);\n\n i >= 0 && _triggers.splice(i, 1);\n i === _i && _direction > 0 && _i--; // if we're in the middle of a refresh() or update(), splicing would cause skips in the index, so adjust...\n // if no other ScrollTrigger instances of the same scroller are found, wipe out any recorded scroll position. Otherwise, in a single page application, for example, it could maintain scroll position when it really shouldn't.\n\n i = 0;\n\n _triggers.forEach(function (t) {\n return t.scroller === self.scroller && (i = 1);\n });\n\n i || _refreshingAll || (self.scroll.rec = 0);\n\n if (animation) {\n animation.scrollTrigger = null;\n revert && animation.revert({\n kill: false\n });\n allowAnimation || animation.kill();\n }\n\n markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n return m.parentNode && m.parentNode.removeChild(m);\n });\n _primary === self && (_primary = 0);\n\n if (pin) {\n pinCache && (pinCache.uncache = 1);\n i = 0;\n\n _triggers.forEach(function (t) {\n return t.pin === pin && i++;\n });\n\n i || (pinCache.spacer = 0); // if there aren't any more ScrollTriggers with the same pin, remove the spacer, otherwise it could be contaminated with old/stale values if the user re-creates a ScrollTrigger for the same element.\n }\n\n vars.onKill && vars.onKill(self);\n };\n\n self.enable(false, false);\n customRevertReturn && customRevertReturn(self);\n !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () {\n return start || end || self.refresh();\n }) && (change = 0.01) && (start = end = 0); // if the animation is a timeline, it may not have been populated yet, so it wouldn't render at the proper place on the first refresh(), thus we should schedule one for the next tick. If \"change\" is defined, we know it must be re-enabling, thus we can refresh() right away.\n\n pin && _queueRefreshAll(); // pinning could affect the positions of other things, so make sure we queue a full refresh()\n };\n\n ScrollTrigger.register = function register(core) {\n if (!_coreInitted) {\n gsap = core || _getGSAP();\n _windowExists() && window.document && ScrollTrigger.enable();\n _coreInitted = _enabled;\n }\n\n return _coreInitted;\n };\n\n ScrollTrigger.defaults = function defaults(config) {\n if (config) {\n for (var p in config) {\n _defaults[p] = config[p];\n }\n }\n\n return _defaults;\n };\n\n ScrollTrigger.disable = function disable(reset, kill) {\n _enabled = 0;\n\n _triggers.forEach(function (trigger) {\n return trigger[kill ? \"kill\" : \"disable\"](reset);\n });\n\n _removeListener(_win, \"wheel\", _onScroll);\n\n _removeListener(_doc, \"scroll\", _onScroll);\n\n clearInterval(_syncInterval);\n\n _removeListener(_doc, \"touchcancel\", _passThrough);\n\n _removeListener(_body, \"touchstart\", _passThrough);\n\n _multiListener(_removeListener, _doc, \"pointerdown,touchstart,mousedown\", _pointerDownHandler);\n\n _multiListener(_removeListener, _doc, \"pointerup,touchend,mouseup\", _pointerUpHandler);\n\n _resizeDelay.kill();\n\n _iterateAutoRefresh(_removeListener);\n\n for (var i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) {\n _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]);\n\n _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]);\n }\n };\n\n ScrollTrigger.enable = function enable() {\n _win = window;\n _doc = document;\n _docEl = _doc.documentElement;\n _body = _doc.body;\n\n if (gsap) {\n _toArray = gsap.utils.toArray;\n _clamp = gsap.utils.clamp;\n _context = gsap.core.context || _passThrough;\n _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough;\n _scrollRestoration = _win.history.scrollRestoration || \"auto\";\n _lastScroll = _win.pageYOffset;\n gsap.core.globals(\"ScrollTrigger\", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don't have a \"name\" property.\n\n if (_body) {\n _enabled = 1;\n\n _rafBugFix();\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.register(gsap); // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer.\n\n ScrollTrigger.isTouch = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch;\n _fixIOSBug = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent); // since 2017, iOS has had a bug that causes event.clientX/Y to be inaccurate when a scroll occurs, thus we must alternate ignoring every other touchmove event to work around it. See https://bugs.webkit.org/show_bug.cgi?id=181954 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503\n\n _addListener(_win, \"wheel\", _onScroll); // mostly for 3rd party smooth scrolling libraries.\n\n\n _root = [_win, _doc, _docEl, _body];\n\n if (gsap.matchMedia) {\n ScrollTrigger.matchMedia = function (vars) {\n var mm = gsap.matchMedia(),\n p;\n\n for (p in vars) {\n mm.add(p, vars[p]);\n }\n\n return mm;\n };\n\n gsap.addEventListener(\"matchMediaInit\", function () {\n return _revertAll();\n });\n gsap.addEventListener(\"matchMediaRevert\", function () {\n return _revertRecorded();\n });\n gsap.addEventListener(\"matchMedia\", function () {\n _refreshAll(0, 1);\n\n _dispatch(\"matchMedia\");\n });\n gsap.matchMedia(\"(orientation: portrait)\", function () {\n // when orientation changes, we should take new base measurements for the ignoreMobileResize feature.\n _setBaseDimensions();\n\n return _setBaseDimensions;\n });\n } else {\n console.warn(\"Requires GSAP 3.11.0 or later\");\n }\n\n _setBaseDimensions();\n\n _addListener(_doc, \"scroll\", _onScroll); // some browsers (like Chrome), the window stops dispatching scroll events on the window if you scroll really fast, but it's consistent on the document!\n\n\n var bodyStyle = _body.style,\n border = bodyStyle.borderTopStyle,\n AnimationProto = gsap.core.Animation.prototype,\n bounds,\n i;\n AnimationProto.revert || Object.defineProperty(AnimationProto, \"revert\", {\n value: function value() {\n return this.time(-0.01, true);\n }\n }); // only for backwards compatibility (Animation.revert() was added after 3.10.4)\n\n bodyStyle.borderTopStyle = \"solid\"; // works around an issue where a margin of a child element could throw off the bounds of the _body, making it seem like there's a margin when there actually isn't. The border ensures that the bounds are accurate.\n\n bounds = _getBounds(_body);\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical.m = Math.round(bounds.top + _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical.sc()) || 0; // accommodate the offset of the caused by margins and/or padding\n\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.m = Math.round(bounds.left + _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.sc()) || 0;\n border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty(\"border-top-style\"); // TODO: (?) maybe move to leveraging the velocity mechanism in Observer and skip intervals.\n\n _syncInterval = setInterval(_sync, 250);\n gsap.delayedCall(0.5, function () {\n return _startup = 0;\n });\n\n _addListener(_doc, \"touchcancel\", _passThrough); // some older Android devices intermittently stop dispatching \"touchmove\" events if we don't listen for \"touchcancel\" on the document.\n\n\n _addListener(_body, \"touchstart\", _passThrough); //works around Safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/\n\n\n _multiListener(_addListener, _doc, \"pointerdown,touchstart,mousedown\", _pointerDownHandler);\n\n _multiListener(_addListener, _doc, \"pointerup,touchend,mouseup\", _pointerUpHandler);\n\n _transformProp = gsap.utils.checkPrefix(\"transform\");\n\n _stateProps.push(_transformProp);\n\n _coreInitted = _getTime();\n _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause();\n _autoRefresh = [_doc, \"visibilitychange\", function () {\n var w = _win.innerWidth,\n h = _win.innerHeight;\n\n if (_doc.hidden) {\n _prevWidth = w;\n _prevHeight = h;\n } else if (_prevWidth !== w || _prevHeight !== h) {\n _onResize();\n }\n }, _doc, \"DOMContentLoaded\", _refreshAll, _win, \"load\", _refreshAll, _win, \"resize\", _onResize];\n\n _iterateAutoRefresh(_addListener);\n\n _triggers.forEach(function (trigger) {\n return trigger.enable(0, 1);\n });\n\n for (i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) {\n _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]);\n\n _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]);\n }\n }\n }\n };\n\n ScrollTrigger.config = function config(vars) {\n \"limitCallbacks\" in vars && (_limitCallbacks = !!vars.limitCallbacks);\n var ms = vars.syncInterval;\n ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);\n \"ignoreMobileResize\" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);\n\n if (\"autoRefreshEvents\" in vars) {\n _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || \"none\");\n _ignoreResize = (vars.autoRefreshEvents + \"\").indexOf(\"resize\") === -1;\n }\n };\n\n ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {\n var t = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(target),\n i = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.indexOf(t),\n isViewport = _isViewport(t);\n\n if (~i) {\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.splice(i, isViewport ? 6 : 2);\n }\n\n if (vars) {\n isViewport ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.unshift(t, vars);\n }\n };\n\n ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {\n _triggers.forEach(function (t) {\n return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);\n });\n };\n\n ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {\n var bounds = (_isString(element) ? (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element) : element).getBoundingClientRect(),\n offset = bounds[horizontal ? _width : _height] * ratio || 0;\n return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight;\n };\n\n ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {\n _isString(element) && (element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element));\n var bounds = element.getBoundingClientRect(),\n size = bounds[horizontal ? _width : _height],\n offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf(\"%\") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;\n return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight;\n };\n\n ScrollTrigger.killAll = function killAll(allowListeners) {\n _triggers.slice(0).forEach(function (t) {\n return t.vars.id !== \"ScrollSmoother\" && t.kill();\n });\n\n if (allowListeners !== true) {\n var listeners = _listeners.killAll || [];\n _listeners = {};\n listeners.forEach(function (f) {\n return f();\n });\n }\n };\n\n return ScrollTrigger;\n}();\nScrollTrigger.version = \"3.11.5\";\n\nScrollTrigger.saveStyles = function (targets) {\n return targets ? _toArray(targets).forEach(function (target) {\n // saved styles are recorded in a consecutive alternating Array, like [element, cssText, transform attribute, cache, matchMedia, ...]\n if (target && target.style) {\n var i = _savedStyles.indexOf(target);\n\n i >= 0 && _savedStyles.splice(i, 5);\n\n _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute(\"transform\"), gsap.core.getCache(target), _context());\n }\n }) : _savedStyles;\n};\n\nScrollTrigger.revert = function (soft, media) {\n return _revertAll(!soft, media);\n};\n\nScrollTrigger.create = function (vars, animation) {\n return new ScrollTrigger(vars, animation);\n};\n\nScrollTrigger.refresh = function (safe) {\n return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true);\n};\n\nScrollTrigger.update = function (force) {\n return ++_Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache && _updateAll(force === true ? 2 : 0);\n};\n\nScrollTrigger.clearScrollMemory = _clearScrollMemory;\n\nScrollTrigger.maxScroll = function (element, horizontal) {\n return _maxScroll(element, horizontal ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical);\n};\n\nScrollTrigger.getScrollFunc = function (element, horizontal) {\n return (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)((0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element), horizontal ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical);\n};\n\nScrollTrigger.getById = function (id) {\n return _ids[id];\n};\n\nScrollTrigger.getAll = function () {\n return _triggers.filter(function (t) {\n return t.vars.id !== \"ScrollSmoother\";\n });\n}; // it's common for people to ScrollTrigger.getAll(t => t.kill()) on page routes, for example, and we don't want it to ruin smooth scrolling by killing the main ScrollSmoother one.\n\n\nScrollTrigger.isScrolling = function () {\n return !!_lastScrollTime;\n};\n\nScrollTrigger.snapDirectional = _snapDirectional;\n\nScrollTrigger.addEventListener = function (type, callback) {\n var a = _listeners[type] || (_listeners[type] = []);\n ~a.indexOf(callback) || a.push(callback);\n};\n\nScrollTrigger.removeEventListener = function (type, callback) {\n var a = _listeners[type],\n i = a && a.indexOf(callback);\n i >= 0 && a.splice(i, 1);\n};\n\nScrollTrigger.batch = function (targets, vars) {\n var result = [],\n varsCopy = {},\n interval = vars.interval || 0.016,\n batchMax = vars.batchMax || 1e9,\n proxyCallback = function proxyCallback(type, callback) {\n var elements = [],\n triggers = [],\n delay = gsap.delayedCall(interval, function () {\n callback(elements, triggers);\n elements = [];\n triggers = [];\n }).pause();\n return function (self) {\n elements.length || delay.restart(true);\n elements.push(self.trigger);\n triggers.push(self);\n batchMax <= elements.length && delay.progress(1);\n };\n },\n p;\n\n for (p in vars) {\n varsCopy[p] = p.substr(0, 2) === \"on\" && _isFunction(vars[p]) && p !== \"onRefreshInit\" ? proxyCallback(p, vars[p]) : vars[p];\n }\n\n if (_isFunction(batchMax)) {\n batchMax = batchMax();\n\n _addListener(ScrollTrigger, \"refresh\", function () {\n return batchMax = vars.batchMax();\n });\n }\n\n _toArray(targets).forEach(function (target) {\n var config = {};\n\n for (p in varsCopy) {\n config[p] = varsCopy[p];\n }\n\n config.trigger = target;\n result.push(ScrollTrigger.create(config));\n });\n\n return result;\n}; // to reduce file size. clamps the scroll and also returns a duration multiplier so that if the scroll gets chopped shorter, the duration gets curtailed as well (otherwise if you're very close to the top of the page, for example, and swipe up really fast, it'll suddenly slow down and take a long time to reach the top).\n\n\nvar _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {\n current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);\n return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;\n},\n _allowNativePanning = function _allowNativePanning(target, direction) {\n if (direction === true) {\n target.style.removeProperty(\"touch-action\");\n } else {\n target.style.touchAction = direction === true ? \"auto\" : direction ? \"pan-\" + direction + (_Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch ? \" pinch-zoom\" : \"\") : \"none\"; // note: Firefox doesn't support it pinch-zoom properly, at least in addition to a pan-x or pan-y.\n }\n\n target === _docEl && _allowNativePanning(_body, direction);\n},\n _overflow = {\n auto: 1,\n scroll: 1\n},\n _nestedScroll = function _nestedScroll(_ref5) {\n var event = _ref5.event,\n target = _ref5.target,\n axis = _ref5.axis;\n\n var node = (event.changedTouches ? event.changedTouches[0] : event).target,\n cache = node._gsap || gsap.core.getCache(node),\n time = _getTime(),\n cs;\n\n if (!cache._isScrollT || time - cache._isScrollT > 2000) {\n // cache for 2 seconds to improve performance.\n while (node && node !== _body && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {\n node = node.parentNode;\n }\n\n cache._isScroll = node && node !== target && !_isViewport(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);\n cache._isScrollT = time;\n }\n\n if (cache._isScroll || axis === \"x\") {\n event.stopPropagation();\n event._gsapAllow = true;\n }\n},\n // capture events on scrollable elements INSIDE the and allow those by calling stopPropagation() when we find a scrollable ancestor\n_inputObserver = function _inputObserver(target, type, inputs, nested) {\n return _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.create({\n target: target,\n capture: true,\n debounce: false,\n lockAxis: true,\n type: type,\n onWheel: nested = nested && _nestedScroll,\n onPress: nested,\n onDrag: nested,\n onScroll: nested,\n onEnable: function onEnable() {\n return inputs && _addListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, false, true);\n },\n onDisable: function onDisable() {\n return _removeListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, true);\n }\n });\n},\n _inputExp = /(input|label|select|textarea)/i,\n _inputIsFocused,\n _captureInputs = function _captureInputs(e) {\n var isInput = _inputExp.test(e.target.tagName);\n\n if (isInput || _inputIsFocused) {\n e._gsapAllow = true;\n _inputIsFocused = isInput;\n }\n},\n _getScrollNormalizer = function _getScrollNormalizer(vars) {\n _isObject(vars) || (vars = {});\n vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;\n vars.type || (vars.type = \"wheel,touch\");\n vars.debounce = !!vars.debounce;\n vars.id = vars.id || \"normalizer\";\n\n var _vars2 = vars,\n normalizeScrollX = _vars2.normalizeScrollX,\n momentum = _vars2.momentum,\n allowNestedScroll = _vars2.allowNestedScroll,\n onRelease = _vars2.onRelease,\n self,\n maxY,\n target = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.target) || _docEl,\n smoother = gsap.core.globals().ScrollSmoother,\n smootherInstance = smoother && smoother.get(),\n content = _fixIOSBug && (vars.content && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),\n scrollFuncY = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical),\n scrollFuncX = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal),\n scale = 1,\n initialScale = (_Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch && _win.visualViewport ? _win.visualViewport.scale * _win.visualViewport.width : _win.outerWidth) / _win.innerWidth,\n wheelRefresh = 0,\n resolveMomentumDuration = _isFunction(momentum) ? function () {\n return momentum(self);\n } : function () {\n return momentum || 2.8;\n },\n lastRefreshID,\n skipTouchMove,\n inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),\n resumeTouchMove = function resumeTouchMove() {\n return skipTouchMove = false;\n },\n scrollClampX = _passThrough,\n scrollClampY = _passThrough,\n updateClamps = function updateClamps() {\n maxY = _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical);\n scrollClampY = _clamp(_fixIOSBug ? 1 : 0, maxY);\n normalizeScrollX && (scrollClampX = _clamp(0, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal)));\n lastRefreshID = _refreshID;\n },\n removeContentOffset = function removeContentOffset() {\n content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + \"px\";\n content.style.transform = \"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \" + parseFloat(content._gsap.y) + \", 0, 1)\";\n scrollFuncY.offset = scrollFuncY.cacheID = 0;\n },\n ignoreDrag = function ignoreDrag() {\n if (skipTouchMove) {\n requestAnimationFrame(resumeTouchMove);\n\n var offset = _round(self.deltaY / 2),\n scroll = scrollClampY(scrollFuncY.v - offset);\n\n if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {\n scrollFuncY.offset = scroll - scrollFuncY.v;\n\n var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);\n\n content.style.transform = \"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \" + y + \", 0, 1)\";\n content._gsap.y = y + \"px\";\n scrollFuncY.cacheID = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache;\n\n _updateAll();\n }\n\n return true;\n }\n\n scrollFuncY.offset && removeContentOffset();\n skipTouchMove = true;\n },\n tween,\n startScrollX,\n startScrollY,\n onStopDelayedCall,\n onResize = function onResize() {\n // if the window resizes, like on an iPhone which Apple FORCES the address bar to show/hide even if we event.preventDefault(), it may be scrolling too far now that the address bar is showing, so we must dynamically adjust the momentum tween.\n updateClamps();\n\n if (tween.isActive() && tween.vars.scrollY > maxY) {\n scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo(\"scrollY\", maxY);\n }\n };\n\n content && gsap.set(content, {\n y: \"+=0\"\n }); // to ensure there's a cache (element._gsap)\n\n vars.ignoreCheck = function (e) {\n return _fixIOSBug && e.type === \"touchmove\" && ignoreDrag(e) || scale > 1.05 && e.type !== \"touchstart\" || self.isGesturing || e.touches && e.touches.length > 1;\n };\n\n vars.onPress = function () {\n skipTouchMove = false;\n var prevScale = scale;\n scale = _round((_win.visualViewport && _win.visualViewport.scale || 1) / initialScale);\n tween.pause();\n prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : \"x\");\n startScrollX = scrollFuncX();\n startScrollY = scrollFuncY();\n updateClamps();\n lastRefreshID = _refreshID;\n };\n\n vars.onRelease = vars.onGestureStart = function (self, wasDragging) {\n scrollFuncY.offset && removeContentOffset();\n\n if (!wasDragging) {\n onStopDelayedCall.restart(true);\n } else {\n _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; // make sure we're pulling the non-cached value\n // alternate algorithm: durX = Math.min(6, Math.abs(self.velocityX / 800)),\tdur = Math.max(durX, Math.min(6, Math.abs(self.velocityY / 800))); dur = dur * (0.4 + (1 - _power4In(dur / 6)) * 0.6)) * (momentumSpeed || 1)\n\n var dur = resolveMomentumDuration(),\n currentScroll,\n endScroll;\n\n if (normalizeScrollX) {\n currentScroll = scrollFuncX();\n endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227; // the constant .227 is from power4(0.05). velocity is inverted because scrolling goes in the opposite direction.\n\n dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal));\n tween.vars.scrollX = scrollClampX(endScroll);\n }\n\n currentScroll = scrollFuncY();\n endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227; // the constant .227 is from power4(0.05)\n\n dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical));\n tween.vars.scrollY = scrollClampY(endScroll);\n tween.invalidate().duration(dur).play(0.01);\n\n if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {\n // iOS bug: it'll show the address bar but NOT fire the window \"resize\" event until the animation is done but we must protect against overshoot so we leverage an onUpdate to do so.\n gsap.to({}, {\n onUpdate: onResize,\n duration: dur\n });\n }\n }\n\n onRelease && onRelease(self);\n };\n\n vars.onWheel = function () {\n tween._ts && tween.pause();\n\n if (_getTime() - wheelRefresh > 1000) {\n // after 1 second, refresh the clamps otherwise that'll only happen when ScrollTrigger.refresh() is called or for touch-scrolling.\n lastRefreshID = 0;\n wheelRefresh = _getTime();\n }\n };\n\n vars.onChange = function (self, dx, dy, xArray, yArray) {\n _refreshID !== lastRefreshID && updateClamps();\n dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1])); // for more precision, we track pointer/touch movement from the start, otherwise it'll drift.\n\n if (dy) {\n scrollFuncY.offset && removeContentOffset();\n var isTouch = yArray[2] === dy,\n y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],\n yClamped = scrollClampY(y);\n isTouch && y !== yClamped && (startScrollY += yClamped - y);\n scrollFuncY(yClamped);\n }\n\n (dy || dx) && _updateAll();\n };\n\n vars.onEnable = function () {\n _allowNativePanning(target, normalizeScrollX ? false : \"x\");\n\n ScrollTrigger.addEventListener(\"refresh\", onResize);\n\n _addListener(_win, \"resize\", onResize);\n\n if (scrollFuncY.smooth) {\n scrollFuncY.target.style.scrollBehavior = \"auto\";\n scrollFuncY.smooth = scrollFuncX.smooth = false;\n }\n\n inputObserver.enable();\n };\n\n vars.onDisable = function () {\n _allowNativePanning(target, true);\n\n _removeListener(_win, \"resize\", onResize);\n\n ScrollTrigger.removeEventListener(\"refresh\", onResize);\n inputObserver.kill();\n };\n\n vars.lockAxis = vars.lockAxis !== false;\n self = new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars);\n self.iOS = _fixIOSBug; // used in the Observer getCachedScroll() function to work around an iOS bug that wreaks havoc with TouchEvent.clientY if we allow scroll to go all the way back to 0.\n\n _fixIOSBug && !scrollFuncY() && scrollFuncY(1); // iOS bug causes event.clientY values to freak out (wildly inaccurate) if the scroll position is exactly 0.\n\n _fixIOSBug && gsap.ticker.add(_passThrough); // prevent the ticker from sleeping\n\n onStopDelayedCall = self._dc;\n tween = gsap.to(self, {\n ease: \"power4\",\n paused: true,\n scrollX: normalizeScrollX ? \"+=0.1\" : \"+=0\",\n scrollY: \"+=0.1\",\n modifiers: {\n scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {\n return tween.pause();\n })\n },\n onUpdate: _updateAll,\n onComplete: onStopDelayedCall.vars.onComplete\n }); // we need the modifier to sense if the scroll position is altered outside of the momentum tween (like with a scrollTo tween) so we can pause() it to prevent conflicts.\n\n return self;\n};\n\nScrollTrigger.sort = function (func) {\n return _triggers.sort(func || function (a, b) {\n return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6);\n });\n};\n\nScrollTrigger.observe = function (vars) {\n return new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars);\n};\n\nScrollTrigger.normalizeScroll = function (vars) {\n if (typeof vars === \"undefined\") {\n return _normalizer;\n }\n\n if (vars === true && _normalizer) {\n return _normalizer.enable();\n }\n\n if (vars === false) {\n return _normalizer && _normalizer.kill();\n }\n\n var normalizer = vars instanceof _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer ? vars : _getScrollNormalizer(vars);\n _normalizer && _normalizer.target === normalizer.target && _normalizer.kill();\n _isViewport(normalizer.target) && (_normalizer = normalizer);\n return normalizer;\n};\n\nScrollTrigger.core = {\n // smaller file size way to leverage in ScrollSmoother and Observer\n _getVelocityProp: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._getVelocityProp,\n _inputObserver: _inputObserver,\n _scrollers: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers,\n _proxies: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies,\n bridge: {\n // when normalizeScroll sets the scroll position (ss = setScroll)\n ss: function ss() {\n _lastScrollTime || _dispatch(\"scrollStart\");\n _lastScrollTime = _getTime();\n },\n // a way to get the _refreshing value in Observer\n ref: function ref() {\n return _refreshing;\n }\n }\n};\n_getGSAP() && gsap.registerPlugin(ScrollTrigger);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9TY3JvbGxUcmlnZ2VyLmpzLmpzIiwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNvSjs7QUFFcEo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxTQUFTLDJEQUFhO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLDJEQUFhO0FBQzNCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSx5QkFBeUIsMERBQWdCO0FBQ3pDO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCwyREFBYTtBQUM5RCxDQUFDO0FBQ0Q7QUFDQSxrQkFBa0IseUJBQXlCO0FBQzNDO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7O0FBRTFCLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLGtEQUFRO0FBQ3JCLHlCQUF5Qjs7QUFFekIsa0RBQWtEOztBQUVsRCwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUcsR0FBRzs7QUFFTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBLGFBQWEsa0RBQVE7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQ0FBbUMsa0RBQVE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQiwwREFBZ0I7QUFDcEM7QUFDQSxjQUFjLG9EQUFVO0FBQ3hCLFlBQVksa0RBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vbm9kZV9tb2R1bGVzL2dzYXAvU2Nyb2xsVHJpZ2dlci5qcz8xZGFjIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogU2Nyb2xsVHJpZ2dlciAzLjExLjVcbiAqIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbVxuICpcbiAqIEBsaWNlbnNlIENvcHlyaWdodCAyMDA4LTIwMjMsIEdyZWVuU29jay4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFN1YmplY3QgdG8gdGhlIHRlcm1zIGF0IGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHcmVlblNvY2sgbWVtYmVycywgdGhlIGFncmVlbWVudCBpc3N1ZWQgd2l0aCB0aGF0IG1lbWJlcnNoaXAuXG4gKiBAYXV0aG9yOiBKYWNrIERveWxlLCBqYWNrQGdyZWVuc29jay5jb21cbiovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgeyBPYnNlcnZlciwgX2dldFRhcmdldCwgX3ZlcnRpY2FsLCBfaG9yaXpvbnRhbCwgX3Njcm9sbGVycywgX3Byb3hpZXMsIF9nZXRTY3JvbGxGdW5jLCBfZ2V0UHJveHlQcm9wLCBfZ2V0VmVsb2NpdHlQcm9wIH0gZnJvbSBcIi4vT2JzZXJ2ZXIuanNcIjtcblxudmFyIGdzYXAsXG4gICAgX2NvcmVJbml0dGVkLFxuICAgIF93aW4sXG4gICAgX2RvYyxcbiAgICBfZG9jRWwsXG4gICAgX2JvZHksXG4gICAgX3Jvb3QsXG4gICAgX3Jlc2l6ZURlbGF5LFxuICAgIF90b0FycmF5LFxuICAgIF9jbGFtcCxcbiAgICBfdGltZTIsXG4gICAgX3N5bmNJbnRlcnZhbCxcbiAgICBfcmVmcmVzaGluZyxcbiAgICBfcG9pbnRlcklzRG93bixcbiAgICBfdHJhbnNmb3JtUHJvcCxcbiAgICBfaSxcbiAgICBfcHJldldpZHRoLFxuICAgIF9wcmV2SGVpZ2h0LFxuICAgIF9hdXRvUmVmcmVzaCxcbiAgICBfc29ydCxcbiAgICBfc3VwcHJlc3NPdmVyd3JpdGVzLFxuICAgIF9pZ25vcmVSZXNpemUsXG4gICAgX25vcm1hbGl6ZXIsXG4gICAgX2lnbm9yZU1vYmlsZVJlc2l6ZSxcbiAgICBfYmFzZVNjcmVlbkhlaWdodCxcbiAgICBfYmFzZVNjcmVlbldpZHRoLFxuICAgIF9maXhJT1NCdWcsXG4gICAgX2NvbnRleHQsXG4gICAgX3Njcm9sbFJlc3RvcmF0aW9uLFxuICAgIF9saW1pdENhbGxiYWNrcyxcbiAgICAvLyBpZiB0cnVlLCB3ZSdsbCBvbmx5IHRyaWdnZXIgY2FsbGJhY2tzIGlmIHRoZSBhY3RpdmUgc3RhdGUgdG9nZ2xlcywgc28gaWYgeW91IHNjcm9sbCBpbW1lZGlhdGVseSBwYXN0IGJvdGggdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIGEgU2Nyb2xsVHJpZ2dlciAodGh1cyBpbmFjdGl2ZSB0byBpbmFjdGl2ZSksIG5laXRoZXIgaXRzIG9uRW50ZXIgbm9yIG9uTGVhdmUgd2lsbCBiZSBjYWxsZWQuIFRoaXMgaXMgdXNlZnVsIGR1cmluZyBzdGFydHVwLlxuX3N0YXJ0dXAgPSAxLFxuICAgIF9nZXRUaW1lID0gRGF0ZS5ub3csXG4gICAgX3RpbWUxID0gX2dldFRpbWUoKSxcbiAgICBfbGFzdFNjcm9sbFRpbWUgPSAwLFxuICAgIF9lbmFibGVkID0gMCxcbiAgICBfcmFmQnVnRml4ID0gZnVuY3Rpb24gX3JhZkJ1Z0ZpeCgpIHtcbiAgcmV0dXJuIF9lbmFibGVkICYmIHJlcXVlc3RBbmltYXRpb25GcmFtZShfcmFmQnVnRml4KTtcbn0sXG4gICAgLy8gaW4gc29tZSBicm93c2VycyAobGlrZSBGaXJlZm94KSwgc2NyZWVuIHJlcGFpbnRzIHdlcmVuJ3QgY29uc2lzdGVudCB1bmxlc3Mgd2UgaGFkIFNPTUVUSElORyBxdWV1ZWQgdXAgaW4gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCkhIFNvIHRoaXMganVzdCBjcmVhdGVzIGEgc3VwZXIgc2ltcGxlIGxvb3AgdG8ga2VlcCBpdCBhbGl2ZSBhbmQgc21vb3RoIG91dCByZXBhaW50cy5cbl9wb2ludGVyRG93bkhhbmRsZXIgPSBmdW5jdGlvbiBfcG9pbnRlckRvd25IYW5kbGVyKCkge1xuICByZXR1cm4gX3BvaW50ZXJJc0Rvd24gPSAxO1xufSxcbiAgICBfcG9pbnRlclVwSGFuZGxlciA9IGZ1bmN0aW9uIF9wb2ludGVyVXBIYW5kbGVyKCkge1xuICByZXR1cm4gX3BvaW50ZXJJc0Rvd24gPSAwO1xufSxcbiAgICBfcGFzc1Rocm91Z2ggPSBmdW5jdGlvbiBfcGFzc1Rocm91Z2godikge1xuICByZXR1cm4gdjtcbn0sXG4gICAgX3JvdW5kID0gZnVuY3Rpb24gX3JvdW5kKHZhbHVlKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwMDAwKSAvIDEwMDAwMCB8fCAwO1xufSxcbiAgICBfd2luZG93RXhpc3RzID0gZnVuY3Rpb24gX3dpbmRvd0V4aXN0cygpIHtcbiAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG59LFxuICAgIF9nZXRHU0FQID0gZnVuY3Rpb24gX2dldEdTQVAoKSB7XG4gIHJldHVybiBnc2FwIHx8IF93aW5kb3dFeGlzdHMoKSAmJiAoZ3NhcCA9IHdpbmRvdy5nc2FwKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luICYmIGdzYXA7XG59LFxuICAgIF9pc1ZpZXdwb3J0ID0gZnVuY3Rpb24gX2lzVmlld3BvcnQoZSkge1xuICByZXR1cm4gISF+X3Jvb3QuaW5kZXhPZihlKTtcbn0sXG4gICAgX2dldEJvdW5kc0Z1bmMgPSBmdW5jdGlvbiBfZ2V0Qm91bmRzRnVuYyhlbGVtZW50KSB7XG4gIHJldHVybiBfZ2V0UHJveHlQcm9wKGVsZW1lbnQsIFwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0XCIpIHx8IChfaXNWaWV3cG9ydChlbGVtZW50KSA/IGZ1bmN0aW9uICgpIHtcbiAgICBfd2luT2Zmc2V0cy53aWR0aCA9IF93aW4uaW5uZXJXaWR0aDtcbiAgICBfd2luT2Zmc2V0cy5oZWlnaHQgPSBfd2luLmlubmVySGVpZ2h0O1xuICAgIHJldHVybiBfd2luT2Zmc2V0cztcbiAgfSA6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2dldEJvdW5kcyhlbGVtZW50KTtcbiAgfSk7XG59LFxuICAgIF9nZXRTaXplRnVuYyA9IGZ1bmN0aW9uIF9nZXRTaXplRnVuYyhzY3JvbGxlciwgaXNWaWV3cG9ydCwgX3JlZikge1xuICB2YXIgZCA9IF9yZWYuZCxcbiAgICAgIGQyID0gX3JlZi5kMixcbiAgICAgIGEgPSBfcmVmLmE7XG4gIHJldHVybiAoYSA9IF9nZXRQcm94eVByb3Aoc2Nyb2xsZXIsIFwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0XCIpKSA/IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYSgpW2RdO1xuICB9IDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoaXNWaWV3cG9ydCA/IF93aW5bXCJpbm5lclwiICsgZDJdIDogc2Nyb2xsZXJbXCJjbGllbnRcIiArIGQyXSkgfHwgMDtcbiAgfTtcbn0sXG4gICAgX2dldE9mZnNldHNGdW5jID0gZnVuY3Rpb24gX2dldE9mZnNldHNGdW5jKGVsZW1lbnQsIGlzVmlld3BvcnQpIHtcbiAgcmV0dXJuICFpc1ZpZXdwb3J0IHx8IH5fcHJveGllcy5pbmRleE9mKGVsZW1lbnQpID8gX2dldEJvdW5kc0Z1bmMoZWxlbWVudCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF93aW5PZmZzZXRzO1xuICB9O1xufSxcbiAgICBfbWF4U2Nyb2xsID0gZnVuY3Rpb24gX21heFNjcm9sbChlbGVtZW50LCBfcmVmMikge1xuICB2YXIgcyA9IF9yZWYyLnMsXG4gICAgICBkMiA9IF9yZWYyLmQyLFxuICAgICAgZCA9IF9yZWYyLmQsXG4gICAgICBhID0gX3JlZjIuYTtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIChzID0gXCJzY3JvbGxcIiArIGQyKSAmJiAoYSA9IF9nZXRQcm94eVByb3AoZWxlbWVudCwgcykpID8gYSgpIC0gX2dldEJvdW5kc0Z1bmMoZWxlbWVudCkoKVtkXSA6IF9pc1ZpZXdwb3J0KGVsZW1lbnQpID8gKF9kb2NFbFtzXSB8fCBfYm9keVtzXSkgLSAoX3dpbltcImlubmVyXCIgKyBkMl0gfHwgX2RvY0VsW1wiY2xpZW50XCIgKyBkMl0gfHwgX2JvZHlbXCJjbGllbnRcIiArIGQyXSkgOiBlbGVtZW50W3NdIC0gZWxlbWVudFtcIm9mZnNldFwiICsgZDJdKTtcbn0sXG4gICAgX2l0ZXJhdGVBdXRvUmVmcmVzaCA9IGZ1bmN0aW9uIF9pdGVyYXRlQXV0b1JlZnJlc2goZnVuYywgZXZlbnRzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgX2F1dG9SZWZyZXNoLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgKCFldmVudHMgfHwgfmV2ZW50cy5pbmRleE9mKF9hdXRvUmVmcmVzaFtpICsgMV0pKSAmJiBmdW5jKF9hdXRvUmVmcmVzaFtpXSwgX2F1dG9SZWZyZXNoW2kgKyAxXSwgX2F1dG9SZWZyZXNoW2kgKyAyXSk7XG4gIH1cbn0sXG4gICAgX2lzU3RyaW5nID0gZnVuY3Rpb24gX2lzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XG59LFxuICAgIF9pc0Z1bmN0aW9uID0gZnVuY3Rpb24gX2lzRnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiO1xufSxcbiAgICBfaXNOdW1iZXIgPSBmdW5jdGlvbiBfaXNOdW1iZXIodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIjtcbn0sXG4gICAgX2lzT2JqZWN0ID0gZnVuY3Rpb24gX2lzT2JqZWN0KHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI7XG59LFxuICAgIF9jYWxsSWZGdW5jID0gZnVuY3Rpb24gX2NhbGxJZkZ1bmModmFsdWUpIHtcbiAgcmV0dXJuIF9pc0Z1bmN0aW9uKHZhbHVlKSAmJiB2YWx1ZSgpO1xufSxcbiAgICBfY29tYmluZUZ1bmMgPSBmdW5jdGlvbiBfY29tYmluZUZ1bmMoZjEsIGYyKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdDEgPSBfY2FsbElmRnVuYyhmMSksXG4gICAgICAgIHJlc3VsdDIgPSBfY2FsbElmRnVuYyhmMik7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgX2NhbGxJZkZ1bmMocmVzdWx0MSk7XG5cbiAgICAgIF9jYWxsSWZGdW5jKHJlc3VsdDIpO1xuICAgIH07XG4gIH07XG59LFxuICAgIF9lbmRBbmltYXRpb24gPSBmdW5jdGlvbiBfZW5kQW5pbWF0aW9uKGFuaW1hdGlvbiwgcmV2ZXJzZWQsIHBhdXNlKSB7XG4gIHJldHVybiBhbmltYXRpb24gJiYgYW5pbWF0aW9uLnByb2dyZXNzKHJldmVyc2VkID8gMCA6IDEpICYmIHBhdXNlICYmIGFuaW1hdGlvbi5wYXVzZSgpO1xufSxcbiAgICBfY2FsbGJhY2sgPSBmdW5jdGlvbiBfY2FsbGJhY2soc2VsZiwgZnVuYykge1xuICBpZiAoc2VsZi5lbmFibGVkKSB7XG4gICAgdmFyIHJlc3VsdCA9IGZ1bmMoc2VsZik7XG4gICAgcmVzdWx0ICYmIHJlc3VsdC50b3RhbFRpbWUgJiYgKHNlbGYuY2FsbGJhY2tBbmltYXRpb24gPSByZXN1bHQpO1xuICB9XG59LFxuICAgIF9hYnMgPSBNYXRoLmFicyxcbiAgICBfc2Nyb2xsTGVmdCA9IFwic2Nyb2xsTGVmdFwiLFxuICAgIF9zY3JvbGxUb3AgPSBcInNjcm9sbFRvcFwiLFxuICAgIF9sZWZ0ID0gXCJsZWZ0XCIsXG4gICAgX3RvcCA9IFwidG9wXCIsXG4gICAgX3JpZ2h0ID0gXCJyaWdodFwiLFxuICAgIF9ib3R0b20gPSBcImJvdHRvbVwiLFxuICAgIF93aWR0aCA9IFwid2lkdGhcIixcbiAgICBfaGVpZ2h0ID0gXCJoZWlnaHRcIixcbiAgICBfUmlnaHQgPSBcIlJpZ2h0XCIsXG4gICAgX0xlZnQgPSBcIkxlZnRcIixcbiAgICBfVG9wID0gXCJUb3BcIixcbiAgICBfQm90dG9tID0gXCJCb3R0b21cIixcbiAgICBfcGFkZGluZyA9IFwicGFkZGluZ1wiLFxuICAgIF9tYXJnaW4gPSBcIm1hcmdpblwiLFxuICAgIF9XaWR0aCA9IFwiV2lkdGhcIixcbiAgICBfSGVpZ2h0ID0gXCJIZWlnaHRcIixcbiAgICBfcHggPSBcInB4XCIsXG4gICAgX2dldENvbXB1dGVkU3R5bGUgPSBmdW5jdGlvbiBfZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSB7XG4gIHJldHVybiBfd2luLmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG59LFxuICAgIF9tYWtlUG9zaXRpb25hYmxlID0gZnVuY3Rpb24gX21ha2VQb3NpdGlvbmFibGUoZWxlbWVudCkge1xuICAvLyBpZiB0aGUgZWxlbWVudCBhbHJlYWR5IGhhcyBwb3NpdGlvbjogYWJzb2x1dGUgb3IgZml4ZWQsIGxlYXZlIHRoYXQsIG90aGVyd2lzZSBtYWtlIGl0IHBvc2l0aW9uOiByZWxhdGl2ZVxuICB2YXIgcG9zaXRpb24gPSBfZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbjtcblxuICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiID8gcG9zaXRpb24gOiBcInJlbGF0aXZlXCI7XG59LFxuICAgIF9zZXREZWZhdWx0cyA9IGZ1bmN0aW9uIF9zZXREZWZhdWx0cyhvYmosIGRlZmF1bHRzKSB7XG4gIGZvciAodmFyIHAgaW4gZGVmYXVsdHMpIHtcbiAgICBwIGluIG9iaiB8fCAob2JqW3BdID0gZGVmYXVsdHNbcF0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn0sXG4gICAgX2dldEJvdW5kcyA9IGZ1bmN0aW9uIF9nZXRCb3VuZHMoZWxlbWVudCwgd2l0aG91dFRyYW5zZm9ybXMpIHtcbiAgdmFyIHR3ZWVuID0gd2l0aG91dFRyYW5zZm9ybXMgJiYgX2dldENvbXB1dGVkU3R5bGUoZWxlbWVudClbX3RyYW5zZm9ybVByb3BdICE9PSBcIm1hdHJpeCgxLCAwLCAwLCAxLCAwLCAwKVwiICYmIGdzYXAudG8oZWxlbWVudCwge1xuICAgIHg6IDAsXG4gICAgeTogMCxcbiAgICB4UGVyY2VudDogMCxcbiAgICB5UGVyY2VudDogMCxcbiAgICByb3RhdGlvbjogMCxcbiAgICByb3RhdGlvblg6IDAsXG4gICAgcm90YXRpb25ZOiAwLFxuICAgIHNjYWxlOiAxLFxuICAgIHNrZXdYOiAwLFxuICAgIHNrZXdZOiAwXG4gIH0pLnByb2dyZXNzKDEpLFxuICAgICAgYm91bmRzID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgdHdlZW4gJiYgdHdlZW4ucHJvZ3Jlc3MoMCkua2lsbCgpO1xuICByZXR1cm4gYm91bmRzO1xufSxcbiAgICBfZ2V0U2l6ZSA9IGZ1bmN0aW9uIF9nZXRTaXplKGVsZW1lbnQsIF9yZWYzKSB7XG4gIHZhciBkMiA9IF9yZWYzLmQyO1xuICByZXR1cm4gZWxlbWVudFtcIm9mZnNldFwiICsgZDJdIHx8IGVsZW1lbnRbXCJjbGllbnRcIiArIGQyXSB8fCAwO1xufSxcbiAgICBfZ2V0TGFiZWxSYXRpb0FycmF5ID0gZnVuY3Rpb24gX2dldExhYmVsUmF0aW9BcnJheSh0aW1lbGluZSkge1xuICB2YXIgYSA9IFtdLFxuICAgICAgbGFiZWxzID0gdGltZWxpbmUubGFiZWxzLFxuICAgICAgZHVyYXRpb24gPSB0aW1lbGluZS5kdXJhdGlvbigpLFxuICAgICAgcDtcblxuICBmb3IgKHAgaW4gbGFiZWxzKSB7XG4gICAgYS5wdXNoKGxhYmVsc1twXSAvIGR1cmF0aW9uKTtcbiAgfVxuXG4gIHJldHVybiBhO1xufSxcbiAgICBfZ2V0Q2xvc2VzdExhYmVsID0gZnVuY3Rpb24gX2dldENsb3Nlc3RMYWJlbChhbmltYXRpb24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBnc2FwLnV0aWxzLnNuYXAoX2dldExhYmVsUmF0aW9BcnJheShhbmltYXRpb24pLCB2YWx1ZSk7XG4gIH07XG59LFxuICAgIF9zbmFwRGlyZWN0aW9uYWwgPSBmdW5jdGlvbiBfc25hcERpcmVjdGlvbmFsKHNuYXBJbmNyZW1lbnRPckFycmF5KSB7XG4gIHZhciBzbmFwID0gZ3NhcC51dGlscy5zbmFwKHNuYXBJbmNyZW1lbnRPckFycmF5KSxcbiAgICAgIGEgPSBBcnJheS5pc0FycmF5KHNuYXBJbmNyZW1lbnRPckFycmF5KSAmJiBzbmFwSW5jcmVtZW50T3JBcnJheS5zbGljZSgwKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGEgLSBiO1xuICB9KTtcbiAgcmV0dXJuIGEgPyBmdW5jdGlvbiAodmFsdWUsIGRpcmVjdGlvbiwgdGhyZXNob2xkKSB7XG4gICAgaWYgKHRocmVzaG9sZCA9PT0gdm9pZCAwKSB7XG4gICAgICB0aHJlc2hvbGQgPSAxZS0zO1xuICAgIH1cblxuICAgIHZhciBpO1xuXG4gICAgaWYgKCFkaXJlY3Rpb24pIHtcbiAgICAgIHJldHVybiBzbmFwKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAoZGlyZWN0aW9uID4gMCkge1xuICAgICAgdmFsdWUgLT0gdGhyZXNob2xkOyAvLyB0byBhdm9pZCByb3VuZGluZyBlcnJvcnMuIElmIHdlJ3JlIHRvbyBzdHJpY3QsIGl0IG1pZ2h0IHNuYXAgZm9yd2FyZCwgdGhlbiBpbW1lZGlhdGVseSBhZ2FpbiwgYW5kIGFnYWluLlxuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYVtpXSA+PSB2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBhW2ldO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhW2kgLSAxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaSA9IGEubGVuZ3RoO1xuICAgICAgdmFsdWUgKz0gdGhyZXNob2xkO1xuXG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIGlmIChhW2ldIDw9IHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGFbaV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYVswXTtcbiAgfSA6IGZ1bmN0aW9uICh2YWx1ZSwgZGlyZWN0aW9uLCB0aHJlc2hvbGQpIHtcbiAgICBpZiAodGhyZXNob2xkID09PSB2b2lkIDApIHtcbiAgICAgIHRocmVzaG9sZCA9IDFlLTM7XG4gICAgfVxuXG4gICAgdmFyIHNuYXBwZWQgPSBzbmFwKHZhbHVlKTtcbiAgICByZXR1cm4gIWRpcmVjdGlvbiB8fCBNYXRoLmFicyhzbmFwcGVkIC0gdmFsdWUpIDwgdGhyZXNob2xkIHx8IHNuYXBwZWQgLSB2YWx1ZSA8IDAgPT09IGRpcmVjdGlvbiA8IDAgPyBzbmFwcGVkIDogc25hcChkaXJlY3Rpb24gPCAwID8gdmFsdWUgLSBzbmFwSW5jcmVtZW50T3JBcnJheSA6IHZhbHVlICsgc25hcEluY3JlbWVudE9yQXJyYXkpO1xuICB9O1xufSxcbiAgICBfZ2V0TGFiZWxBdERpcmVjdGlvbiA9IGZ1bmN0aW9uIF9nZXRMYWJlbEF0RGlyZWN0aW9uKHRpbWVsaW5lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIHN0KSB7XG4gICAgcmV0dXJuIF9zbmFwRGlyZWN0aW9uYWwoX2dldExhYmVsUmF0aW9BcnJheSh0aW1lbGluZSkpKHZhbHVlLCBzdC5kaXJlY3Rpb24pO1xuICB9O1xufSxcbiAgICBfbXVsdGlMaXN0ZW5lciA9IGZ1bmN0aW9uIF9tdWx0aUxpc3RlbmVyKGZ1bmMsIGVsZW1lbnQsIHR5cGVzLCBjYWxsYmFjaykge1xuICByZXR1cm4gdHlwZXMuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICByZXR1cm4gZnVuYyhlbGVtZW50LCB0eXBlLCBjYWxsYmFjayk7XG4gIH0pO1xufSxcbiAgICBfYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBfYWRkTGlzdGVuZXIoZWxlbWVudCwgdHlwZSwgZnVuYywgbm9uUGFzc2l2ZSwgY2FwdHVyZSkge1xuICByZXR1cm4gZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGZ1bmMsIHtcbiAgICBwYXNzaXZlOiAhbm9uUGFzc2l2ZSxcbiAgICBjYXB0dXJlOiAhIWNhcHR1cmVcbiAgfSk7XG59LFxuICAgIF9yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIF9yZW1vdmVMaXN0ZW5lcihlbGVtZW50LCB0eXBlLCBmdW5jLCBjYXB0dXJlKSB7XG4gIHJldHVybiBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZnVuYywgISFjYXB0dXJlKTtcbn0sXG4gICAgX3doZWVsTGlzdGVuZXIgPSBmdW5jdGlvbiBfd2hlZWxMaXN0ZW5lcihmdW5jLCBlbCwgc2Nyb2xsRnVuYykge1xuICBzY3JvbGxGdW5jID0gc2Nyb2xsRnVuYyAmJiBzY3JvbGxGdW5jLndoZWVsSGFuZGxlcjtcblxuICBpZiAoc2Nyb2xsRnVuYykge1xuICAgIGZ1bmMoZWwsIFwid2hlZWxcIiwgc2Nyb2xsRnVuYyk7XG4gICAgZnVuYyhlbCwgXCJ0b3VjaG1vdmVcIiwgc2Nyb2xsRnVuYyk7XG4gIH1cbn0sXG4gICAgX21hcmtlckRlZmF1bHRzID0ge1xuICBzdGFydENvbG9yOiBcImdyZWVuXCIsXG4gIGVuZENvbG9yOiBcInJlZFwiLFxuICBpbmRlbnQ6IDAsXG4gIGZvbnRTaXplOiBcIjE2cHhcIixcbiAgZm9udFdlaWdodDogXCJub3JtYWxcIlxufSxcbiAgICBfZGVmYXVsdHMgPSB7XG4gIHRvZ2dsZUFjdGlvbnM6IFwicGxheVwiLFxuICBhbnRpY2lwYXRlUGluOiAwXG59LFxuICAgIF9rZXl3b3JkcyA9IHtcbiAgdG9wOiAwLFxuICBsZWZ0OiAwLFxuICBjZW50ZXI6IDAuNSxcbiAgYm90dG9tOiAxLFxuICByaWdodDogMVxufSxcbiAgICBfb2Zmc2V0VG9QeCA9IGZ1bmN0aW9uIF9vZmZzZXRUb1B4KHZhbHVlLCBzaXplKSB7XG4gIGlmIChfaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIGVxSW5kZXggPSB2YWx1ZS5pbmRleE9mKFwiPVwiKSxcbiAgICAgICAgcmVsYXRpdmUgPSB+ZXFJbmRleCA/ICsodmFsdWUuY2hhckF0KGVxSW5kZXggLSAxKSArIDEpICogcGFyc2VGbG9hdCh2YWx1ZS5zdWJzdHIoZXFJbmRleCArIDEpKSA6IDA7XG5cbiAgICBpZiAofmVxSW5kZXgpIHtcbiAgICAgIHZhbHVlLmluZGV4T2YoXCIlXCIpID4gZXFJbmRleCAmJiAocmVsYXRpdmUgKj0gc2l6ZSAvIDEwMCk7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cigwLCBlcUluZGV4IC0gMSk7XG4gICAgfVxuXG4gICAgdmFsdWUgPSByZWxhdGl2ZSArICh2YWx1ZSBpbiBfa2V5d29yZHMgPyBfa2V5d29yZHNbdmFsdWVdICogc2l6ZSA6IH52YWx1ZS5pbmRleE9mKFwiJVwiKSA/IHBhcnNlRmxvYXQodmFsdWUpICogc2l6ZSAvIDEwMCA6IHBhcnNlRmxvYXQodmFsdWUpIHx8IDApO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufSxcbiAgICBfY3JlYXRlTWFya2VyID0gZnVuY3Rpb24gX2NyZWF0ZU1hcmtlcih0eXBlLCBuYW1lLCBjb250YWluZXIsIGRpcmVjdGlvbiwgX3JlZjQsIG9mZnNldCwgbWF0Y2hXaWR0aEVsLCBjb250YWluZXJBbmltYXRpb24pIHtcbiAgdmFyIHN0YXJ0Q29sb3IgPSBfcmVmNC5zdGFydENvbG9yLFxuICAgICAgZW5kQ29sb3IgPSBfcmVmNC5lbmRDb2xvcixcbiAgICAgIGZvbnRTaXplID0gX3JlZjQuZm9udFNpemUsXG4gICAgICBpbmRlbnQgPSBfcmVmNC5pbmRlbnQsXG4gICAgICBmb250V2VpZ2h0ID0gX3JlZjQuZm9udFdlaWdodDtcblxuICB2YXIgZSA9IF9kb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKSxcbiAgICAgIHVzZUZpeGVkUG9zaXRpb24gPSBfaXNWaWV3cG9ydChjb250YWluZXIpIHx8IF9nZXRQcm94eVByb3AoY29udGFpbmVyLCBcInBpblR5cGVcIikgPT09IFwiZml4ZWRcIixcbiAgICAgIGlzU2Nyb2xsZXIgPSB0eXBlLmluZGV4T2YoXCJzY3JvbGxlclwiKSAhPT0gLTEsXG4gICAgICBwYXJlbnQgPSB1c2VGaXhlZFBvc2l0aW9uID8gX2JvZHkgOiBjb250YWluZXIsXG4gICAgICBpc1N0YXJ0ID0gdHlwZS5pbmRleE9mKFwic3RhcnRcIikgIT09IC0xLFxuICAgICAgY29sb3IgPSBpc1N0YXJ0ID8gc3RhcnRDb2xvciA6IGVuZENvbG9yLFxuICAgICAgY3NzID0gXCJib3JkZXItY29sb3I6XCIgKyBjb2xvciArIFwiO2ZvbnQtc2l6ZTpcIiArIGZvbnRTaXplICsgXCI7Y29sb3I6XCIgKyBjb2xvciArIFwiO2ZvbnQtd2VpZ2h0OlwiICsgZm9udFdlaWdodCArIFwiO3BvaW50ZXItZXZlbnRzOm5vbmU7d2hpdGUtc3BhY2U6bm93cmFwO2ZvbnQtZmFtaWx5OnNhbnMtc2VyaWYsQXJpYWw7ei1pbmRleDoxMDAwO3BhZGRpbmc6NHB4IDhweDtib3JkZXItd2lkdGg6MDtib3JkZXItc3R5bGU6c29saWQ7XCI7XG5cbiAgY3NzICs9IFwicG9zaXRpb246XCIgKyAoKGlzU2Nyb2xsZXIgfHwgY29udGFpbmVyQW5pbWF0aW9uKSAmJiB1c2VGaXhlZFBvc2l0aW9uID8gXCJmaXhlZDtcIiA6IFwiYWJzb2x1dGU7XCIpO1xuICAoaXNTY3JvbGxlciB8fCBjb250YWluZXJBbmltYXRpb24gfHwgIXVzZUZpeGVkUG9zaXRpb24pICYmIChjc3MgKz0gKGRpcmVjdGlvbiA9PT0gX3ZlcnRpY2FsID8gX3JpZ2h0IDogX2JvdHRvbSkgKyBcIjpcIiArIChvZmZzZXQgKyBwYXJzZUZsb2F0KGluZGVudCkpICsgXCJweDtcIik7XG4gIG1hdGNoV2lkdGhFbCAmJiAoY3NzICs9IFwiYm94LXNpemluZzpib3JkZXItYm94O3RleHQtYWxpZ246bGVmdDt3aWR0aDpcIiArIG1hdGNoV2lkdGhFbC5vZmZzZXRXaWR0aCArIFwicHg7XCIpO1xuICBlLl9pc1N0YXJ0ID0gaXNTdGFydDtcbiAgZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcImdzYXAtbWFya2VyLVwiICsgdHlwZSArIChuYW1lID8gXCIgbWFya2VyLVwiICsgbmFtZSA6IFwiXCIpKTtcbiAgZS5zdHlsZS5jc3NUZXh0ID0gY3NzO1xuICBlLmlubmVyVGV4dCA9IG5hbWUgfHwgbmFtZSA9PT0gMCA/IHR5cGUgKyBcIi1cIiArIG5hbWUgOiB0eXBlO1xuICBwYXJlbnQuY2hpbGRyZW5bMF0gPyBwYXJlbnQuaW5zZXJ0QmVmb3JlKGUsIHBhcmVudC5jaGlsZHJlblswXSkgOiBwYXJlbnQuYXBwZW5kQ2hpbGQoZSk7XG4gIGUuX29mZnNldCA9IGVbXCJvZmZzZXRcIiArIGRpcmVjdGlvbi5vcC5kMl07XG5cbiAgX3Bvc2l0aW9uTWFya2VyKGUsIDAsIGRpcmVjdGlvbiwgaXNTdGFydCk7XG5cbiAgcmV0dXJuIGU7XG59LFxuICAgIF9wb3NpdGlvbk1hcmtlciA9IGZ1bmN0aW9uIF9wb3NpdGlvbk1hcmtlcihtYXJrZXIsIHN0YXJ0LCBkaXJlY3Rpb24sIGZsaXBwZWQpIHtcbiAgdmFyIHZhcnMgPSB7XG4gICAgZGlzcGxheTogXCJibG9ja1wiXG4gIH0sXG4gICAgICBzaWRlID0gZGlyZWN0aW9uW2ZsaXBwZWQgPyBcIm9zMlwiIDogXCJwMlwiXSxcbiAgICAgIG9wcG9zaXRlU2lkZSA9IGRpcmVjdGlvbltmbGlwcGVkID8gXCJwMlwiIDogXCJvczJcIl07XG4gIG1hcmtlci5faXNGbGlwcGVkID0gZmxpcHBlZDtcbiAgdmFyc1tkaXJlY3Rpb24uYSArIFwiUGVyY2VudFwiXSA9IGZsaXBwZWQgPyAtMTAwIDogMDtcbiAgdmFyc1tkaXJlY3Rpb24uYV0gPSBmbGlwcGVkID8gXCIxcHhcIiA6IDA7XG4gIHZhcnNbXCJib3JkZXJcIiArIHNpZGUgKyBfV2lkdGhdID0gMTtcbiAgdmFyc1tcImJvcmRlclwiICsgb3Bwb3NpdGVTaWRlICsgX1dpZHRoXSA9IDA7XG4gIHZhcnNbZGlyZWN0aW9uLnBdID0gc3RhcnQgKyBcInB4XCI7XG4gIGdzYXAuc2V0KG1hcmtlciwgdmFycyk7XG59LFxuICAgIF90cmlnZ2VycyA9IFtdLFxuICAgIF9pZHMgPSB7fSxcbiAgICBfcmFmSUQsXG4gICAgX3N5bmMgPSBmdW5jdGlvbiBfc3luYygpIHtcbiAgcmV0dXJuIF9nZXRUaW1lKCkgLSBfbGFzdFNjcm9sbFRpbWUgPiAzNCAmJiAoX3JhZklEIHx8IChfcmFmSUQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoX3VwZGF0ZUFsbCkpKTtcbn0sXG4gICAgX29uU2Nyb2xsID0gZnVuY3Rpb24gX29uU2Nyb2xsKCkge1xuICAvLyBwcmV2aW91c2x5LCB3ZSB0cmllZCB0byBvcHRpbWl6ZSBwZXJmb3JtYW5jZSBieSBiYXRjaGluZy9kZWZlcnJpbmcgdG8gdGhlIG5leHQgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCksIGJ1dCBkaXNjb3ZlcmVkIHRoYXQgU2FmYXJpIGhhcyBhIGZldyBidWdzIHRoYXQgbWFrZSB0aGlzIHVud29ya2FibGUgKGVzcGVjaWFsbHkgb24gaU9TKS4gU2VlIGh0dHBzOi8vY29kZXBlbi5pby9HcmVlblNvY2svcGVuLzE2YzQzNWIxMmVmMDljMzgxMjUyMDQ4MThlN2I0NWZjP2VkaXRvcnM9MDAxMCBhbmQgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vSmpPeFlwUS8zZGQ2NWNjZWM1YTYwZjFkODYyYzM1NWQ4NGQxNDU2Mj9lZGl0b3JzPTAwMTAgYW5kIGh0dHBzOi8vY29kZXBlbi5pby9HcmVlblNvY2svcGVuL0V4YnJQTmEvMDg3Y2VmMTk3ZGMzNTQ0NWEwOTUxZTg5MzVjNDE1MDM/ZWRpdG9ycz0wMDEwXG4gIGlmICghX25vcm1hbGl6ZXIgfHwgIV9ub3JtYWxpemVyLmlzUHJlc3NlZCB8fCBfbm9ybWFsaXplci5zdGFydFggPiBfYm9keS5jbGllbnRXaWR0aCkge1xuICAgIC8vIGlmIHRoZSB1c2VyIGlzIGRyYWdnaW5nIHRoZSBzY3JvbGxiYXIsIGFsbG93IGl0LlxuICAgIF9zY3JvbGxlcnMuY2FjaGUrKztcblxuICAgIGlmIChfbm9ybWFsaXplcikge1xuICAgICAgX3JhZklEIHx8IChfcmFmSUQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoX3VwZGF0ZUFsbCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfdXBkYXRlQWxsKCk7IC8vIFNhZmFyaSBpbiBwYXJ0aWN1bGFyIChvbiBkZXNrdG9wKSBORUVEUyB0aGUgaW1tZWRpYXRlIHVwZGF0ZSByYXRoZXIgdGhhbiB3YWl0aW5nIGZvciBhIHJlcXVlc3RBbmltYXRpb25GcmFtZSgpIHdoZXJlYXMgaU9TIHNlZW1zIHRvIGJlbmVmaXQgZnJvbSB3YWl0aW5nIGZvciB0aGUgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCkgdGljaywgYXQgbGVhc3Qgd2hlbiBub3JtYWxpemluZy4gU2VlIGh0dHBzOi8vY29kZXBlbi5pby9HcmVlblNvY2svcGVuL3FCWW96cU8/ZWRpdG9ycz0wMTEwXG5cbiAgICB9XG5cbiAgICBfbGFzdFNjcm9sbFRpbWUgfHwgX2Rpc3BhdGNoKFwic2Nyb2xsU3RhcnRcIik7XG4gICAgX2xhc3RTY3JvbGxUaW1lID0gX2dldFRpbWUoKTtcbiAgfVxufSxcbiAgICBfc2V0QmFzZURpbWVuc2lvbnMgPSBmdW5jdGlvbiBfc2V0QmFzZURpbWVuc2lvbnMoKSB7XG4gIF9iYXNlU2NyZWVuV2lkdGggPSBfd2luLmlubmVyV2lkdGg7XG4gIF9iYXNlU2NyZWVuSGVpZ2h0ID0gX3dpbi5pbm5lckhlaWdodDtcbn0sXG4gICAgX29uUmVzaXplID0gZnVuY3Rpb24gX29uUmVzaXplKCkge1xuICBfc2Nyb2xsZXJzLmNhY2hlKys7XG4gICFfcmVmcmVzaGluZyAmJiAhX2lnbm9yZVJlc2l6ZSAmJiAhX2RvYy5mdWxsc2NyZWVuRWxlbWVudCAmJiAhX2RvYy53ZWJraXRGdWxsc2NyZWVuRWxlbWVudCAmJiAoIV9pZ25vcmVNb2JpbGVSZXNpemUgfHwgX2Jhc2VTY3JlZW5XaWR0aCAhPT0gX3dpbi5pbm5lcldpZHRoIHx8IE1hdGguYWJzKF93aW4uaW5uZXJIZWlnaHQgLSBfYmFzZVNjcmVlbkhlaWdodCkgPiBfd2luLmlubmVySGVpZ2h0ICogMC4yNSkgJiYgX3Jlc2l6ZURlbGF5LnJlc3RhcnQodHJ1ZSk7XG59LFxuICAgIC8vIGlnbm9yZSByZXNpemVzIHRyaWdnZXJlZCBieSByZWZyZXNoKClcbl9saXN0ZW5lcnMgPSB7fSxcbiAgICBfZW1wdHlBcnJheSA9IFtdLFxuICAgIF9zb2Z0UmVmcmVzaCA9IGZ1bmN0aW9uIF9zb2Z0UmVmcmVzaCgpIHtcbiAgcmV0dXJuIF9yZW1vdmVMaXN0ZW5lcihTY3JvbGxUcmlnZ2VyLCBcInNjcm9sbEVuZFwiLCBfc29mdFJlZnJlc2gpIHx8IF9yZWZyZXNoQWxsKHRydWUpO1xufSxcbiAgICBfZGlzcGF0Y2ggPSBmdW5jdGlvbiBfZGlzcGF0Y2godHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVyc1t0eXBlXSAmJiBfbGlzdGVuZXJzW3R5cGVdLm1hcChmdW5jdGlvbiAoZikge1xuICAgIHJldHVybiBmKCk7XG4gIH0pIHx8IF9lbXB0eUFycmF5O1xufSxcbiAgICBfc2F2ZWRTdHlsZXMgPSBbXSxcbiAgICAvLyB3aGVuIFNjcm9sbFRyaWdnZXIuc2F2ZVN0eWxlcygpIGlzIGNhbGxlZCwgdGhlIGlubGluZSBzdHlsZXMgYXJlIHJlY29yZGVkIGluIHRoaXMgQXJyYXkgaW4gYSBzZXF1ZW50aWFsIGZvcm1hdCBsaWtlIFtlbGVtZW50LCBjc3NUZXh0LCBnc0NhY2hlLCBtZWRpYV0uIFRoaXMga2VlcHMgaXQgdmVyeSBtZW1vcnktZWZmaWNpZW50IGFuZCBmYXN0IHRvIGl0ZXJhdGUgdGhyb3VnaC5cbl9yZXZlcnRSZWNvcmRlZCA9IGZ1bmN0aW9uIF9yZXZlcnRSZWNvcmRlZChtZWRpYSkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IF9zYXZlZFN0eWxlcy5sZW5ndGg7IGkgKz0gNSkge1xuICAgIGlmICghbWVkaWEgfHwgX3NhdmVkU3R5bGVzW2kgKyA0XSAmJiBfc2F2ZWRTdHlsZXNbaSArIDRdLnF1ZXJ5ID09PSBtZWRpYSkge1xuICAgICAgX3NhdmVkU3R5bGVzW2ldLnN0eWxlLmNzc1RleHQgPSBfc2F2ZWRTdHlsZXNbaSArIDFdO1xuICAgICAgX3NhdmVkU3R5bGVzW2ldLmdldEJCb3ggJiYgX3NhdmVkU3R5bGVzW2ldLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBfc2F2ZWRTdHlsZXNbaSArIDJdIHx8IFwiXCIpO1xuICAgICAgX3NhdmVkU3R5bGVzW2kgKyAzXS51bmNhY2hlID0gMTtcbiAgICB9XG4gIH1cbn0sXG4gICAgX3JldmVydEFsbCA9IGZ1bmN0aW9uIF9yZXZlcnRBbGwoa2lsbCwgbWVkaWEpIHtcbiAgdmFyIHRyaWdnZXI7XG5cbiAgZm9yIChfaSA9IDA7IF9pIDwgX3RyaWdnZXJzLmxlbmd0aDsgX2krKykge1xuICAgIHRyaWdnZXIgPSBfdHJpZ2dlcnNbX2ldO1xuXG4gICAgaWYgKHRyaWdnZXIgJiYgKCFtZWRpYSB8fCB0cmlnZ2VyLl9jdHggPT09IG1lZGlhKSkge1xuICAgICAgaWYgKGtpbGwpIHtcbiAgICAgICAgdHJpZ2dlci5raWxsKDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJpZ2dlci5yZXZlcnQodHJ1ZSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbWVkaWEgJiYgX3JldmVydFJlY29yZGVkKG1lZGlhKTtcbiAgbWVkaWEgfHwgX2Rpc3BhdGNoKFwicmV2ZXJ0XCIpO1xufSxcbiAgICBfY2xlYXJTY3JvbGxNZW1vcnkgPSBmdW5jdGlvbiBfY2xlYXJTY3JvbGxNZW1vcnkoc2Nyb2xsUmVzdG9yYXRpb24sIGZvcmNlKSB7XG4gIC8vIHplcm8tb3V0IGFsbCB0aGUgcmVjb3JkZWQgc2Nyb2xsIHBvc2l0aW9ucy4gRG9uJ3QgdXNlIF90cmlnZ2VycyBiZWNhdXNlIGlmLCBmb3IgZXhhbXBsZSwgLm1hdGNoTWVkaWEoKSBpcyB1c2VkIHRvIGNyZWF0ZSBzb21lIFNjcm9sbFRyaWdnZXJzIGFuZCB0aGVuIHRoZSB1c2VyIHJlc2l6ZXMgYW5kIGl0IHJlbW92ZXMgQUxMIFNjcm9sbFRyaWdnZXJzLCBhbmQgdGhlbiBnbyBiYWNrIHRvIGEgc2l6ZSB3aGVyZSB0aGVyZSBhcmUgU2Nyb2xsVHJpZ2dlcnMsIGl0IHdvdWxkIGhhdmUga2VwdCB0aGUgcG9zaXRpb24ocykgc2F2ZWQgZnJvbSB0aGUgaW5pdGlhbCBzdGF0ZS5cbiAgX3Njcm9sbGVycy5jYWNoZSsrO1xuICAoZm9yY2UgfHwgIV9yZWZyZXNoaW5nQWxsKSAmJiBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBfaXNGdW5jdGlvbihvYmopICYmIG9iai5jYWNoZUlEKysgJiYgKG9iai5yZWMgPSAwKTtcbiAgfSk7XG4gIF9pc1N0cmluZyhzY3JvbGxSZXN0b3JhdGlvbikgJiYgKF93aW4uaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IF9zY3JvbGxSZXN0b3JhdGlvbiA9IHNjcm9sbFJlc3RvcmF0aW9uKTtcbn0sXG4gICAgX3JlZnJlc2hpbmdBbGwsXG4gICAgX3JlZnJlc2hJRCA9IDAsXG4gICAgX3F1ZXVlUmVmcmVzaElELFxuICAgIF9xdWV1ZVJlZnJlc2hBbGwgPSBmdW5jdGlvbiBfcXVldWVSZWZyZXNoQWxsKCkge1xuICAvLyB3ZSBkb24ndCB3YW50IHRvIGNhbGwgX3JlZnJlc2hBbGwoKSBldmVyeSB0aW1lIHdlIGNyZWF0ZSBhIG5ldyBTY3JvbGxUcmlnZ2VyIChmb3IgcGVyZm9ybWFuY2UgcmVhc29ucykgLSBpdCdzIGJldHRlciB0byBiYXRjaCB0aGVtLiBTb21lIGZyYW1ld29ya3MgZHluYW1pY2FsbHkgbG9hZCBjb250ZW50IGFuZCB3ZSBjYW4ndCByZWx5IG9uIHRoZSB3aW5kb3cncyBcImxvYWRcIiBvciBcIkRPTUNvbnRlbnRMb2FkZWRcIiBldmVudHMgdG8gdHJpZ2dlciBpdC5cbiAgaWYgKF9xdWV1ZVJlZnJlc2hJRCAhPT0gX3JlZnJlc2hJRCkge1xuICAgIHZhciBpZCA9IF9xdWV1ZVJlZnJlc2hJRCA9IF9yZWZyZXNoSUQ7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBpZCA9PT0gX3JlZnJlc2hJRCAmJiBfcmVmcmVzaEFsbCh0cnVlKTtcbiAgICB9KTtcbiAgfVxufSxcbiAgICBfcmVmcmVzaEFsbCA9IGZ1bmN0aW9uIF9yZWZyZXNoQWxsKGZvcmNlLCBza2lwUmV2ZXJ0KSB7XG4gIGlmIChfbGFzdFNjcm9sbFRpbWUgJiYgIWZvcmNlKSB7XG4gICAgX2FkZExpc3RlbmVyKFNjcm9sbFRyaWdnZXIsIFwic2Nyb2xsRW5kXCIsIF9zb2Z0UmVmcmVzaCk7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICBfcmVmcmVzaGluZ0FsbCA9IFNjcm9sbFRyaWdnZXIuaXNSZWZyZXNoaW5nID0gdHJ1ZTtcblxuICBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBfaXNGdW5jdGlvbihvYmopICYmIG9iai5jYWNoZUlEKysgJiYgKG9iai5yZWMgPSBvYmooKSk7XG4gIH0pOyAvLyBmb3JjZSB0aGUgY2xlYXJpbmcgb2YgdGhlIGNhY2hlIGJlY2F1c2Ugc29tZSBicm93c2VycyB0YWtlIGEgbGl0dGxlIHdoaWxlIHRvIGRpc3BhdGNoIHRoZSBcInNjcm9sbFwiIGV2ZW50IGFuZCB0aGUgdXNlciBtYXkgaGF2ZSBjaGFuZ2VkIHRoZSBzY3JvbGwgcG9zaXRpb24gYW5kIHRoZW4gY2FsbGVkIFNjcm9sbFRyaWdnZXIucmVmcmVzaCgpIHJpZ2h0IGF3YXlcblxuXG4gIHZhciByZWZyZXNoSW5pdHMgPSBfZGlzcGF0Y2goXCJyZWZyZXNoSW5pdFwiKTtcblxuICBfc29ydCAmJiBTY3JvbGxUcmlnZ2VyLnNvcnQoKTtcbiAgc2tpcFJldmVydCB8fCBfcmV2ZXJ0QWxsKCk7XG5cbiAgX3Njcm9sbGVycy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAoX2lzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgb2JqLnNtb290aCAmJiAob2JqLnRhcmdldC5zdHlsZS5zY3JvbGxCZWhhdmlvciA9IFwiYXV0b1wiKTsgLy8gc21vb3RoIHNjcm9sbGluZyBpbnRlcmZlcmVzXG5cbiAgICAgIG9iaigwKTtcbiAgICB9XG4gIH0pO1xuXG4gIF90cmlnZ2Vycy5zbGljZSgwKS5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIHQucmVmcmVzaCgpO1xuICB9KTsgLy8gZG9uJ3QgbG9vcCB3aXRoIF9pIGJlY2F1c2UgZHVyaW5nIGEgcmVmcmVzaCgpIHNvbWVvbmUgY291bGQgY2FsbCBTY3JvbGxUcmlnZ2VyLnVwZGF0ZSgpIHdoaWNoIHdvdWxkIGl0ZXJhdGUgdGhyb3VnaCBfaSByZXN1bHRpbmcgaW4gYSBza2lwLlxuXG5cbiAgX3RyaWdnZXJzLmZvckVhY2goZnVuY3Rpb24gKHQsIGkpIHtcbiAgICAvLyBuZXN0ZWQgcGlucyAocGlubmVkQ29udGFpbmVyKSB3aXRoIHBpblNwYWNpbmcgbWF5IGV4cGFuZCB0aGUgY29udGFpbmVyLCBzbyB3ZSBtdXN0IGFjY29tbW9kYXRlIHRoYXQgaGVyZS5cbiAgICBpZiAodC5fc3ViUGluT2Zmc2V0ICYmIHQucGluKSB7XG4gICAgICB2YXIgcHJvcCA9IHQudmFycy5ob3Jpem9udGFsID8gXCJvZmZzZXRXaWR0aFwiIDogXCJvZmZzZXRIZWlnaHRcIixcbiAgICAgICAgICBvcmlnaW5hbCA9IHQucGluW3Byb3BdO1xuICAgICAgdC5yZXZlcnQodHJ1ZSwgMSk7XG4gICAgICB0LmFkanVzdFBpblNwYWNpbmcodC5waW5bcHJvcF0gLSBvcmlnaW5hbCk7XG4gICAgICB0LnJlZnJlc2goKTtcbiAgICB9XG4gIH0pO1xuXG4gIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIHQudmFycy5lbmQgPT09IFwibWF4XCIgJiYgdC5zZXRQb3NpdGlvbnModC5zdGFydCwgTWF0aC5tYXgodC5zdGFydCArIDEsIF9tYXhTY3JvbGwodC5zY3JvbGxlciwgdC5fZGlyKSkpO1xuICB9KTsgLy8gdGhlIHNjcm9sbGVyJ3MgbWF4IHNjcm9sbCBwb3NpdGlvbiBtYXkgY2hhbmdlIGFmdGVyIGFsbCB0aGUgU2Nyb2xsVHJpZ2dlcnMgcmVmcmVzaGVkIChsaWtlIHBpbm5pbmcgY291bGQgcHVzaCBpdCBkb3duKSwgc28gd2UgbmVlZCB0byBsb29wIGJhY2sgYW5kIGNvcnJlY3QgYW55IHdpdGggZW5kOiBcIm1heFwiLlxuXG5cbiAgcmVmcmVzaEluaXRzLmZvckVhY2goZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LnJlbmRlciAmJiByZXN1bHQucmVuZGVyKC0xKTtcbiAgfSk7IC8vIGlmIHRoZSBvblJlZnJlc2hJbml0KCkgcmV0dXJucyBhbiBhbmltYXRpb24gKHR5cGljYWxseSBhIGdzYXAuc2V0KCkpLCByZXZlcnQgaXQuIFRoaXMgbWFrZXMgaXQgZWFzeSB0byBwdXQgdGhpbmdzIGluIGEgY2VydGFpbiBzcG90IGJlZm9yZSByZWZyZXNoaW5nIGZvciBtZWFzdXJlbWVudCBwdXJwb3NlcywgYW5kIHRoZW4gcHV0IHRoaW5ncyBiYWNrLlxuXG4gIF9zY3JvbGxlcnMuZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG4gICAgaWYgKF9pc0Z1bmN0aW9uKG9iaikpIHtcbiAgICAgIG9iai5zbW9vdGggJiYgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG9iai50YXJnZXQuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSBcInNtb290aFwiO1xuICAgICAgfSk7XG4gICAgICBvYmoucmVjICYmIG9iaihvYmoucmVjKTtcbiAgICB9XG4gIH0pO1xuXG4gIF9jbGVhclNjcm9sbE1lbW9yeShfc2Nyb2xsUmVzdG9yYXRpb24sIDEpO1xuXG4gIF9yZXNpemVEZWxheS5wYXVzZSgpO1xuXG4gIF9yZWZyZXNoSUQrKztcbiAgX3JlZnJlc2hpbmdBbGwgPSAyO1xuXG4gIF91cGRhdGVBbGwoMik7XG5cbiAgX3RyaWdnZXJzLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gX2lzRnVuY3Rpb24odC52YXJzLm9uUmVmcmVzaCkgJiYgdC52YXJzLm9uUmVmcmVzaCh0KTtcbiAgfSk7XG5cbiAgX3JlZnJlc2hpbmdBbGwgPSBTY3JvbGxUcmlnZ2VyLmlzUmVmcmVzaGluZyA9IGZhbHNlO1xuXG4gIF9kaXNwYXRjaChcInJlZnJlc2hcIik7XG59LFxuICAgIF9sYXN0U2Nyb2xsID0gMCxcbiAgICBfZGlyZWN0aW9uID0gMSxcbiAgICBfcHJpbWFyeSxcbiAgICBfdXBkYXRlQWxsID0gZnVuY3Rpb24gX3VwZGF0ZUFsbChmb3JjZSkge1xuICBpZiAoIV9yZWZyZXNoaW5nQWxsIHx8IGZvcmNlID09PSAyKSB7XG4gICAgU2Nyb2xsVHJpZ2dlci5pc1VwZGF0aW5nID0gdHJ1ZTtcbiAgICBfcHJpbWFyeSAmJiBfcHJpbWFyeS51cGRhdGUoMCk7IC8vIFNjcm9sbFNtb290aGVyIHVzZXMgcmVmcmVzaFByaW9yaXR5IC05OTk5IHRvIGJlY29tZSB0aGUgcHJpbWFyeSB0aGF0IGdldHMgdXBkYXRlZCBiZWZvcmUgYWxsIG90aGVycyBiZWNhdXNlIGl0IGFmZmVjdHMgdGhlIHNjcm9sbCBwb3NpdGlvbi5cblxuICAgIHZhciBsID0gX3RyaWdnZXJzLmxlbmd0aCxcbiAgICAgICAgdGltZSA9IF9nZXRUaW1lKCksXG4gICAgICAgIHJlY29yZFZlbG9jaXR5ID0gdGltZSAtIF90aW1lMSA+PSA1MCxcbiAgICAgICAgc2Nyb2xsID0gbCAmJiBfdHJpZ2dlcnNbMF0uc2Nyb2xsKCk7XG5cbiAgICBfZGlyZWN0aW9uID0gX2xhc3RTY3JvbGwgPiBzY3JvbGwgPyAtMSA6IDE7XG4gICAgX3JlZnJlc2hpbmdBbGwgfHwgKF9sYXN0U2Nyb2xsID0gc2Nyb2xsKTtcblxuICAgIGlmIChyZWNvcmRWZWxvY2l0eSkge1xuICAgICAgaWYgKF9sYXN0U2Nyb2xsVGltZSAmJiAhX3BvaW50ZXJJc0Rvd24gJiYgdGltZSAtIF9sYXN0U2Nyb2xsVGltZSA+IDIwMCkge1xuICAgICAgICBfbGFzdFNjcm9sbFRpbWUgPSAwO1xuXG4gICAgICAgIF9kaXNwYXRjaChcInNjcm9sbEVuZFwiKTtcbiAgICAgIH1cblxuICAgICAgX3RpbWUyID0gX3RpbWUxO1xuICAgICAgX3RpbWUxID0gdGltZTtcbiAgICB9XG5cbiAgICBpZiAoX2RpcmVjdGlvbiA8IDApIHtcbiAgICAgIF9pID0gbDtcblxuICAgICAgd2hpbGUgKF9pLS0gPiAwKSB7XG4gICAgICAgIF90cmlnZ2Vyc1tfaV0gJiYgX3RyaWdnZXJzW19pXS51cGRhdGUoMCwgcmVjb3JkVmVsb2NpdHkpO1xuICAgICAgfVxuXG4gICAgICBfZGlyZWN0aW9uID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChfaSA9IDA7IF9pIDwgbDsgX2krKykge1xuICAgICAgICBfdHJpZ2dlcnNbX2ldICYmIF90cmlnZ2Vyc1tfaV0udXBkYXRlKDAsIHJlY29yZFZlbG9jaXR5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBTY3JvbGxUcmlnZ2VyLmlzVXBkYXRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIF9yYWZJRCA9IDA7XG59LFxuICAgIF9wcm9wTmFtZXNUb0NvcHkgPSBbX2xlZnQsIF90b3AsIF9ib3R0b20sIF9yaWdodCwgX21hcmdpbiArIF9Cb3R0b20sIF9tYXJnaW4gKyBfUmlnaHQsIF9tYXJnaW4gKyBfVG9wLCBfbWFyZ2luICsgX0xlZnQsIFwiZGlzcGxheVwiLCBcImZsZXhTaHJpbmtcIiwgXCJmbG9hdFwiLCBcInpJbmRleFwiLCBcImdyaWRDb2x1bW5TdGFydFwiLCBcImdyaWRDb2x1bW5FbmRcIiwgXCJncmlkUm93U3RhcnRcIiwgXCJncmlkUm93RW5kXCIsIFwiZ3JpZEFyZWFcIiwgXCJqdXN0aWZ5U2VsZlwiLCBcImFsaWduU2VsZlwiLCBcInBsYWNlU2VsZlwiLCBcIm9yZGVyXCJdLFxuICAgIF9zdGF0ZVByb3BzID0gX3Byb3BOYW1lc1RvQ29weS5jb25jYXQoW193aWR0aCwgX2hlaWdodCwgXCJib3hTaXppbmdcIiwgXCJtYXhcIiArIF9XaWR0aCwgXCJtYXhcIiArIF9IZWlnaHQsIFwicG9zaXRpb25cIiwgX21hcmdpbiwgX3BhZGRpbmcsIF9wYWRkaW5nICsgX1RvcCwgX3BhZGRpbmcgKyBfUmlnaHQsIF9wYWRkaW5nICsgX0JvdHRvbSwgX3BhZGRpbmcgKyBfTGVmdF0pLFxuICAgIF9zd2FwUGluT3V0ID0gZnVuY3Rpb24gX3N3YXBQaW5PdXQocGluLCBzcGFjZXIsIHN0YXRlKSB7XG4gIF9zZXRTdGF0ZShzdGF0ZSk7XG5cbiAgdmFyIGNhY2hlID0gcGluLl9nc2FwO1xuXG4gIGlmIChjYWNoZS5zcGFjZXJJc05hdGl2ZSkge1xuICAgIF9zZXRTdGF0ZShjYWNoZS5zcGFjZXJTdGF0ZSk7XG4gIH0gZWxzZSBpZiAocGluLl9nc2FwLnN3YXBwZWRJbikge1xuICAgIHZhciBwYXJlbnQgPSBzcGFjZXIucGFyZW50Tm9kZTtcblxuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUocGluLCBzcGFjZXIpO1xuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHNwYWNlcik7XG4gICAgfVxuICB9XG5cbiAgcGluLl9nc2FwLnN3YXBwZWRJbiA9IGZhbHNlO1xufSxcbiAgICBfc3dhcFBpbkluID0gZnVuY3Rpb24gX3N3YXBQaW5JbihwaW4sIHNwYWNlciwgY3MsIHNwYWNlclN0YXRlKSB7XG4gIGlmICghcGluLl9nc2FwLnN3YXBwZWRJbikge1xuICAgIHZhciBpID0gX3Byb3BOYW1lc1RvQ29weS5sZW5ndGgsXG4gICAgICAgIHNwYWNlclN0eWxlID0gc3BhY2VyLnN0eWxlLFxuICAgICAgICBwaW5TdHlsZSA9IHBpbi5zdHlsZSxcbiAgICAgICAgcDtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHAgPSBfcHJvcE5hbWVzVG9Db3B5W2ldO1xuICAgICAgc3BhY2VyU3R5bGVbcF0gPSBjc1twXTtcbiAgICB9XG5cbiAgICBzcGFjZXJTdHlsZS5wb3NpdGlvbiA9IGNzLnBvc2l0aW9uID09PSBcImFic29sdXRlXCIgPyBcImFic29sdXRlXCIgOiBcInJlbGF0aXZlXCI7XG4gICAgY3MuZGlzcGxheSA9PT0gXCJpbmxpbmVcIiAmJiAoc3BhY2VyU3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCIpO1xuICAgIHBpblN0eWxlW19ib3R0b21dID0gcGluU3R5bGVbX3JpZ2h0XSA9IFwiYXV0b1wiO1xuICAgIHNwYWNlclN0eWxlLmZsZXhCYXNpcyA9IGNzLmZsZXhCYXNpcyB8fCBcImF1dG9cIjtcbiAgICBzcGFjZXJTdHlsZS5vdmVyZmxvdyA9IFwidmlzaWJsZVwiO1xuICAgIHNwYWNlclN0eWxlLmJveFNpemluZyA9IFwiYm9yZGVyLWJveFwiO1xuICAgIHNwYWNlclN0eWxlW193aWR0aF0gPSBfZ2V0U2l6ZShwaW4sIF9ob3Jpem9udGFsKSArIF9weDtcbiAgICBzcGFjZXJTdHlsZVtfaGVpZ2h0XSA9IF9nZXRTaXplKHBpbiwgX3ZlcnRpY2FsKSArIF9weDtcbiAgICBzcGFjZXJTdHlsZVtfcGFkZGluZ10gPSBwaW5TdHlsZVtfbWFyZ2luXSA9IHBpblN0eWxlW190b3BdID0gcGluU3R5bGVbX2xlZnRdID0gXCIwXCI7XG5cbiAgICBfc2V0U3RhdGUoc3BhY2VyU3RhdGUpO1xuXG4gICAgcGluU3R5bGVbX3dpZHRoXSA9IHBpblN0eWxlW1wibWF4XCIgKyBfV2lkdGhdID0gY3NbX3dpZHRoXTtcbiAgICBwaW5TdHlsZVtfaGVpZ2h0XSA9IHBpblN0eWxlW1wibWF4XCIgKyBfSGVpZ2h0XSA9IGNzW19oZWlnaHRdO1xuICAgIHBpblN0eWxlW19wYWRkaW5nXSA9IGNzW19wYWRkaW5nXTtcblxuICAgIGlmIChwaW4ucGFyZW50Tm9kZSAhPT0gc3BhY2VyKSB7XG4gICAgICBwaW4ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc3BhY2VyLCBwaW4pO1xuICAgICAgc3BhY2VyLmFwcGVuZENoaWxkKHBpbik7XG4gICAgfVxuXG4gICAgcGluLl9nc2FwLnN3YXBwZWRJbiA9IHRydWU7XG4gIH1cbn0sXG4gICAgX2NhcHNFeHAgPSAvKFtBLVpdKS9nLFxuICAgIF9zZXRTdGF0ZSA9IGZ1bmN0aW9uIF9zZXRTdGF0ZShzdGF0ZSkge1xuICBpZiAoc3RhdGUpIHtcbiAgICB2YXIgc3R5bGUgPSBzdGF0ZS50LnN0eWxlLFxuICAgICAgICBsID0gc3RhdGUubGVuZ3RoLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgcCxcbiAgICAgICAgdmFsdWU7XG4gICAgKHN0YXRlLnQuX2dzYXAgfHwgZ3NhcC5jb3JlLmdldENhY2hlKHN0YXRlLnQpKS51bmNhY2hlID0gMTsgLy8gb3RoZXJ3aXNlIHRyYW5zZm9ybXMgbWF5IGJlIG9mZlxuXG4gICAgZm9yICg7IGkgPCBsOyBpICs9IDIpIHtcbiAgICAgIHZhbHVlID0gc3RhdGVbaSArIDFdO1xuICAgICAgcCA9IHN0YXRlW2ldO1xuXG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgc3R5bGVbcF0gPSB2YWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAoc3R5bGVbcF0pIHtcbiAgICAgICAgc3R5bGUucmVtb3ZlUHJvcGVydHkocC5yZXBsYWNlKF9jYXBzRXhwLCBcIi0kMVwiKS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0sXG4gICAgX2dldFN0YXRlID0gZnVuY3Rpb24gX2dldFN0YXRlKGVsZW1lbnQpIHtcbiAgLy8gcmV0dXJucyBhbiBBcnJheSB3aXRoIGFsdGVybmF0aW5nIHZhbHVlcyBsaWtlIFtwcm9wZXJ0eSwgdmFsdWUsIHByb3BlcnR5LCB2YWx1ZV0gYW5kIGEgXCJ0XCIgcHJvcGVydHkgcG9pbnRpbmcgdG8gdGhlIHRhcmdldCAoZWxlbWVudCkuIE1ha2VzIGl0IGZhc3QgYW5kIGNoZWFwLlxuICB2YXIgbCA9IF9zdGF0ZVByb3BzLmxlbmd0aCxcbiAgICAgIHN0eWxlID0gZWxlbWVudC5zdHlsZSxcbiAgICAgIHN0YXRlID0gW10sXG4gICAgICBpID0gMDtcblxuICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgIHN0YXRlLnB1c2goX3N0YXRlUHJvcHNbaV0sIHN0eWxlW19zdGF0ZVByb3BzW2ldXSk7XG4gIH1cblxuICBzdGF0ZS50ID0gZWxlbWVudDtcbiAgcmV0dXJuIHN0YXRlO1xufSxcbiAgICBfY29weVN0YXRlID0gZnVuY3Rpb24gX2NvcHlTdGF0ZShzdGF0ZSwgb3ZlcnJpZGUsIG9taXRPZmZzZXRzKSB7XG4gIHZhciByZXN1bHQgPSBbXSxcbiAgICAgIGwgPSBzdGF0ZS5sZW5ndGgsXG4gICAgICBpID0gb21pdE9mZnNldHMgPyA4IDogMCxcbiAgICAgIC8vIHNraXAgdG9wLCBsZWZ0LCByaWdodCwgYm90dG9tIGlmIG9taXRPZmZzZXRzIGlzIHRydWVcbiAgcDtcblxuICBmb3IgKDsgaSA8IGw7IGkgKz0gMikge1xuICAgIHAgPSBzdGF0ZVtpXTtcbiAgICByZXN1bHQucHVzaChwLCBwIGluIG92ZXJyaWRlID8gb3ZlcnJpZGVbcF0gOiBzdGF0ZVtpICsgMV0pO1xuICB9XG5cbiAgcmVzdWx0LnQgPSBzdGF0ZS50O1xuICByZXR1cm4gcmVzdWx0O1xufSxcbiAgICBfd2luT2Zmc2V0cyA9IHtcbiAgbGVmdDogMCxcbiAgdG9wOiAwXG59LFxuICAgIC8vIC8vIHBvdGVudGlhbCBmdXR1cmUgZmVhdHVyZSAoPykgQWxsb3cgdXNlcnMgdG8gY2FsY3VsYXRlIHdoZXJlIGEgdHJpZ2dlciBoaXRzIChzY3JvbGwgcG9zaXRpb24pIGxpa2UgZ2V0U2Nyb2xsUG9zaXRpb24oXCIjaWRcIiwgXCJ0b3AgYm90dG9tXCIpXG4vLyBfZ2V0U2Nyb2xsUG9zaXRpb24gPSAodHJpZ2dlciwgcG9zaXRpb24sIHtzY3JvbGxlciwgY29udGFpbmVyQW5pbWF0aW9uLCBob3Jpem9udGFsfSkgPT4ge1xuLy8gXHRzY3JvbGxlciA9IF9nZXRUYXJnZXQoc2Nyb2xsZXIgfHwgX3dpbik7XG4vLyBcdGxldCBkaXJlY3Rpb24gPSBob3Jpem9udGFsID8gX2hvcml6b250YWwgOiBfdmVydGljYWwsXG4vLyBcdFx0aXNWaWV3cG9ydCA9IF9pc1ZpZXdwb3J0KHNjcm9sbGVyKTtcbi8vIFx0X2dldFNpemVGdW5jKHNjcm9sbGVyLCBpc1ZpZXdwb3J0LCBkaXJlY3Rpb24pO1xuLy8gXHRyZXR1cm4gX3BhcnNlUG9zaXRpb24ocG9zaXRpb24sIF9nZXRUYXJnZXQodHJpZ2dlciksIF9nZXRTaXplRnVuYyhzY3JvbGxlciwgaXNWaWV3cG9ydCwgZGlyZWN0aW9uKSgpLCBkaXJlY3Rpb24sIF9nZXRTY3JvbGxGdW5jKHNjcm9sbGVyLCBkaXJlY3Rpb24pKCksIDAsIDAsIDAsIF9nZXRPZmZzZXRzRnVuYyhzY3JvbGxlciwgaXNWaWV3cG9ydCkoKSwgaXNWaWV3cG9ydCA/IDAgOiBwYXJzZUZsb2F0KF9nZXRDb21wdXRlZFN0eWxlKHNjcm9sbGVyKVtcImJvcmRlclwiICsgZGlyZWN0aW9uLnAyICsgX1dpZHRoXSkgfHwgMCwgMCwgY29udGFpbmVyQW5pbWF0aW9uID8gY29udGFpbmVyQW5pbWF0aW9uLmR1cmF0aW9uKCkgOiBfbWF4U2Nyb2xsKHNjcm9sbGVyKSwgY29udGFpbmVyQW5pbWF0aW9uKTtcbi8vIH0sXG5fcGFyc2VQb3NpdGlvbiA9IGZ1bmN0aW9uIF9wYXJzZVBvc2l0aW9uKHZhbHVlLCB0cmlnZ2VyLCBzY3JvbGxlclNpemUsIGRpcmVjdGlvbiwgc2Nyb2xsLCBtYXJrZXIsIG1hcmtlclNjcm9sbGVyLCBzZWxmLCBzY3JvbGxlckJvdW5kcywgYm9yZGVyV2lkdGgsIHVzZUZpeGVkUG9zaXRpb24sIHNjcm9sbGVyTWF4LCBjb250YWluZXJBbmltYXRpb24pIHtcbiAgX2lzRnVuY3Rpb24odmFsdWUpICYmICh2YWx1ZSA9IHZhbHVlKHNlbGYpKTtcblxuICBpZiAoX2lzU3RyaW5nKHZhbHVlKSAmJiB2YWx1ZS5zdWJzdHIoMCwgMykgPT09IFwibWF4XCIpIHtcbiAgICB2YWx1ZSA9IHNjcm9sbGVyTWF4ICsgKHZhbHVlLmNoYXJBdCg0KSA9PT0gXCI9XCIgPyBfb2Zmc2V0VG9QeChcIjBcIiArIHZhbHVlLnN1YnN0cigzKSwgc2Nyb2xsZXJTaXplKSA6IDApO1xuICB9XG5cbiAgdmFyIHRpbWUgPSBjb250YWluZXJBbmltYXRpb24gPyBjb250YWluZXJBbmltYXRpb24udGltZSgpIDogMCxcbiAgICAgIHAxLFxuICAgICAgcDIsXG4gICAgICBlbGVtZW50O1xuICBjb250YWluZXJBbmltYXRpb24gJiYgY29udGFpbmVyQW5pbWF0aW9uLnNlZWsoMCk7XG5cbiAgaWYgKCFfaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgX2lzRnVuY3Rpb24odHJpZ2dlcikgJiYgKHRyaWdnZXIgPSB0cmlnZ2VyKHNlbGYpKTtcbiAgICB2YXIgb2Zmc2V0cyA9ICh2YWx1ZSB8fCBcIjBcIikuc3BsaXQoXCIgXCIpLFxuICAgICAgICBib3VuZHMsXG4gICAgICAgIGxvY2FsT2Zmc2V0LFxuICAgICAgICBnbG9iYWxPZmZzZXQsXG4gICAgICAgIGRpc3BsYXk7XG4gICAgZWxlbWVudCA9IF9nZXRUYXJnZXQodHJpZ2dlcikgfHwgX2JvZHk7XG4gICAgYm91bmRzID0gX2dldEJvdW5kcyhlbGVtZW50KSB8fCB7fTtcblxuICAgIGlmICgoIWJvdW5kcyB8fCAhYm91bmRzLmxlZnQgJiYgIWJvdW5kcy50b3ApICYmIF9nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmRpc3BsYXkgPT09IFwibm9uZVwiKSB7XG4gICAgICAvLyBpZiBkaXNwbGF5IGlzIFwibm9uZVwiLCBpdCB3b24ndCByZXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgcHJvcGVybHlcbiAgICAgIGRpc3BsYXkgPSBlbGVtZW50LnN0eWxlLmRpc3BsYXk7XG4gICAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICBib3VuZHMgPSBfZ2V0Qm91bmRzKGVsZW1lbnQpO1xuICAgICAgZGlzcGxheSA/IGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IGRpc3BsYXkgOiBlbGVtZW50LnN0eWxlLnJlbW92ZVByb3BlcnR5KFwiZGlzcGxheVwiKTtcbiAgICB9XG5cbiAgICBsb2NhbE9mZnNldCA9IF9vZmZzZXRUb1B4KG9mZnNldHNbMF0sIGJvdW5kc1tkaXJlY3Rpb24uZF0pO1xuICAgIGdsb2JhbE9mZnNldCA9IF9vZmZzZXRUb1B4KG9mZnNldHNbMV0gfHwgXCIwXCIsIHNjcm9sbGVyU2l6ZSk7XG4gICAgdmFsdWUgPSBib3VuZHNbZGlyZWN0aW9uLnBdIC0gc2Nyb2xsZXJCb3VuZHNbZGlyZWN0aW9uLnBdIC0gYm9yZGVyV2lkdGggKyBsb2NhbE9mZnNldCArIHNjcm9sbCAtIGdsb2JhbE9mZnNldDtcbiAgICBtYXJrZXJTY3JvbGxlciAmJiBfcG9zaXRpb25NYXJrZXIobWFya2VyU2Nyb2xsZXIsIGdsb2JhbE9mZnNldCwgZGlyZWN0aW9uLCBzY3JvbGxlclNpemUgLSBnbG9iYWxPZmZzZXQgPCAyMCB8fCBtYXJrZXJTY3JvbGxlci5faXNTdGFydCAmJiBnbG9iYWxPZmZzZXQgPiAyMCk7XG4gICAgc2Nyb2xsZXJTaXplIC09IHNjcm9sbGVyU2l6ZSAtIGdsb2JhbE9mZnNldDsgLy8gYWRqdXN0IGZvciB0aGUgbWFya2VyXG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyQW5pbWF0aW9uICYmICh2YWx1ZSA9IGdzYXAudXRpbHMubWFwUmFuZ2UoY29udGFpbmVyQW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIuc3RhcnQsIGNvbnRhaW5lckFuaW1hdGlvbi5zY3JvbGxUcmlnZ2VyLmVuZCwgMCwgc2Nyb2xsZXJNYXgsIHZhbHVlKSk7XG4gICAgbWFya2VyU2Nyb2xsZXIgJiYgX3Bvc2l0aW9uTWFya2VyKG1hcmtlclNjcm9sbGVyLCBzY3JvbGxlclNpemUsIGRpcmVjdGlvbiwgdHJ1ZSk7XG4gIH1cblxuICBpZiAobWFya2VyKSB7XG4gICAgdmFyIHBvc2l0aW9uID0gdmFsdWUgKyBzY3JvbGxlclNpemUsXG4gICAgICAgIGlzU3RhcnQgPSBtYXJrZXIuX2lzU3RhcnQ7XG4gICAgcDEgPSBcInNjcm9sbFwiICsgZGlyZWN0aW9uLmQyO1xuXG4gICAgX3Bvc2l0aW9uTWFya2VyKG1hcmtlciwgcG9zaXRpb24sIGRpcmVjdGlvbiwgaXNTdGFydCAmJiBwb3NpdGlvbiA+IDIwIHx8ICFpc1N0YXJ0ICYmICh1c2VGaXhlZFBvc2l0aW9uID8gTWF0aC5tYXgoX2JvZHlbcDFdLCBfZG9jRWxbcDFdKSA6IG1hcmtlci5wYXJlbnROb2RlW3AxXSkgPD0gcG9zaXRpb24gKyAxKTtcblxuICAgIGlmICh1c2VGaXhlZFBvc2l0aW9uKSB7XG4gICAgICBzY3JvbGxlckJvdW5kcyA9IF9nZXRCb3VuZHMobWFya2VyU2Nyb2xsZXIpO1xuICAgICAgdXNlRml4ZWRQb3NpdGlvbiAmJiAobWFya2VyLnN0eWxlW2RpcmVjdGlvbi5vcC5wXSA9IHNjcm9sbGVyQm91bmRzW2RpcmVjdGlvbi5vcC5wXSAtIGRpcmVjdGlvbi5vcC5tIC0gbWFya2VyLl9vZmZzZXQgKyBfcHgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb250YWluZXJBbmltYXRpb24gJiYgZWxlbWVudCkge1xuICAgIHAxID0gX2dldEJvdW5kcyhlbGVtZW50KTtcbiAgICBjb250YWluZXJBbmltYXRpb24uc2VlayhzY3JvbGxlck1heCk7XG4gICAgcDIgPSBfZ2V0Qm91bmRzKGVsZW1lbnQpO1xuICAgIGNvbnRhaW5lckFuaW1hdGlvbi5fY2FTY3JvbGxEaXN0ID0gcDFbZGlyZWN0aW9uLnBdIC0gcDJbZGlyZWN0aW9uLnBdO1xuICAgIHZhbHVlID0gdmFsdWUgLyBjb250YWluZXJBbmltYXRpb24uX2NhU2Nyb2xsRGlzdCAqIHNjcm9sbGVyTWF4O1xuICB9XG5cbiAgY29udGFpbmVyQW5pbWF0aW9uICYmIGNvbnRhaW5lckFuaW1hdGlvbi5zZWVrKHRpbWUpO1xuICByZXR1cm4gY29udGFpbmVyQW5pbWF0aW9uID8gdmFsdWUgOiBNYXRoLnJvdW5kKHZhbHVlKTtcbn0sXG4gICAgX3ByZWZpeEV4cCA9IC8od2Via2l0fG1venxsZW5ndGh8Y3NzVGV4dHxpbnNldCkvaSxcbiAgICBfcmVwYXJlbnQgPSBmdW5jdGlvbiBfcmVwYXJlbnQoZWxlbWVudCwgcGFyZW50LCB0b3AsIGxlZnQpIHtcbiAgaWYgKGVsZW1lbnQucGFyZW50Tm9kZSAhPT0gcGFyZW50KSB7XG4gICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZSxcbiAgICAgICAgcCxcbiAgICAgICAgY3M7XG5cbiAgICBpZiAocGFyZW50ID09PSBfYm9keSkge1xuICAgICAgZWxlbWVudC5fc3RPcmlnID0gc3R5bGUuY3NzVGV4dDsgLy8gcmVjb3JkIG9yaWdpbmFsIGlubGluZSBzdHlsZXMgc28gd2UgY2FuIHJldmVydCB0aGVtIGxhdGVyXG5cbiAgICAgIGNzID0gX2dldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG5cbiAgICAgIGZvciAocCBpbiBjcykge1xuICAgICAgICAvLyBtdXN0IGNvcHkgYWxsIHJlbGV2YW50IHN0eWxlcyB0byBlbnN1cmUgdGhhdCBub3RoaW5nIGNoYW5nZXMgdmlzdWFsbHkgd2hlbiB3ZSByZXBhcmVudCB0byB0aGUgPGJvZHk+LiBTa2lwIHRoZSB2ZW5kb3IgcHJlZml4ZWQgb25lcy5cbiAgICAgICAgaWYgKCErcCAmJiAhX3ByZWZpeEV4cC50ZXN0KHApICYmIGNzW3BdICYmIHR5cGVvZiBzdHlsZVtwXSA9PT0gXCJzdHJpbmdcIiAmJiBwICE9PSBcIjBcIikge1xuICAgICAgICAgIHN0eWxlW3BdID0gY3NbcF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3R5bGUudG9wID0gdG9wO1xuICAgICAgc3R5bGUubGVmdCA9IGxlZnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlLmNzc1RleHQgPSBlbGVtZW50Ll9zdE9yaWc7XG4gICAgfVxuXG4gICAgZ3NhcC5jb3JlLmdldENhY2hlKGVsZW1lbnQpLnVuY2FjaGUgPSAxO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgfVxufSxcbiAgICBfaW50ZXJydXB0aW9uVHJhY2tlciA9IGZ1bmN0aW9uIF9pbnRlcnJ1cHRpb25UcmFja2VyKGdldFZhbHVlRnVuYywgaW5pdGlhbFZhbHVlLCBvbkludGVycnVwdCkge1xuICB2YXIgbGFzdDEgPSBpbml0aWFsVmFsdWUsXG4gICAgICBsYXN0MiA9IGxhc3QxO1xuICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBNYXRoLnJvdW5kKGdldFZhbHVlRnVuYygpKTsgLy8gcm91bmQgYmVjYXVzZSBpbiBzb21lIFt2ZXJ5IHVuY29tbW9uXSBXaW5kb3dzIGVudmlyb25tZW50cywgc2Nyb2xsIGNhbiBnZXQgcmVwb3J0ZWQgd2l0aCBkZWNpbWFscyBldmVuIHRob3VnaCBpdCB3YXMgc2V0IHdpdGhvdXQuXG5cbiAgICBpZiAoY3VycmVudCAhPT0gbGFzdDEgJiYgY3VycmVudCAhPT0gbGFzdDIgJiYgTWF0aC5hYnMoY3VycmVudCAtIGxhc3QxKSA+IDMgJiYgTWF0aC5hYnMoY3VycmVudCAtIGxhc3QyKSA+IDMpIHtcbiAgICAgIC8vIGlmIHRoZSB1c2VyIHNjcm9sbHMsIGtpbGwgdGhlIHR3ZWVuLiBpT1MgU2FmYXJpIGludGVybWl0dGVudGx5IG1pc3JlcG9ydHMgdGhlIHNjcm9sbCBwb3NpdGlvbiwgaXQgbWF5IGJlIHRoZSBtb3N0IHJlY2VudGx5LXNldCBvbmUgb3IgdGhlIG9uZSBiZWZvcmUgdGhhdCEgV2hlbiBTYWZhcmkgaXMgem9vbWVkIChDTUQtKyksIGl0IG9mdGVuIG1pc3JlcG9ydHMgYXMgMSBwaXhlbCBvZmYgdG9vISBTbyBpZiB3ZSBzZXQgdGhlIHNjcm9sbCBwb3NpdGlvbiB0byAxMjUsIGZvciBleGFtcGxlLCBpdCdsbCBhY3R1YWxseSByZXBvcnQgaXQgYXMgMTI0LlxuICAgICAgdmFsdWUgPSBjdXJyZW50O1xuICAgICAgb25JbnRlcnJ1cHQgJiYgb25JbnRlcnJ1cHQoKTtcbiAgICB9XG5cbiAgICBsYXN0MiA9IGxhc3QxO1xuICAgIGxhc3QxID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufSxcbiAgICAvLyBfbWVyZ2VBbmltYXRpb25zID0gYW5pbWF0aW9ucyA9PiB7XG4vLyBcdGxldCB0bCA9IGdzYXAudGltZWxpbmUoe3Ntb290aENoaWxkVGltaW5nOiB0cnVlfSkuc3RhcnRUaW1lKE1hdGgubWluKC4uLmFuaW1hdGlvbnMubWFwKGEgPT4gYS5nbG9iYWxUaW1lKDApKSkpO1xuLy8gXHRhbmltYXRpb25zLmZvckVhY2goYSA9PiB7bGV0IHRpbWUgPSBhLnRvdGFsVGltZSgpOyB0bC5hZGQoYSk7IGEudG90YWxUaW1lKHRpbWUpOyB9KTtcbi8vIFx0dGwuc21vb3RoQ2hpbGRUaW1pbmcgPSBmYWxzZTtcbi8vIFx0cmV0dXJuIHRsO1xuLy8gfSxcbi8vIHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIHRvIHR3ZWVuIHRoZSBzY3JvbGwgcG9zaXRpb24gaW4gdGhlIGRpcmVjdGlvbiBwcm92aWRlZCwgYW5kIHdoZW4gZG9pbmcgc28gaXQnbGwgYWRkIGEgLnR3ZWVuIHByb3BlcnR5IHRvIHRoZSBGVU5DVElPTiBpdHNlbGYsIGFuZCByZW1vdmUgaXQgd2hlbiB0aGUgdHdlZW4gY29tcGxldGVzIG9yIGdldHMga2lsbGVkLiBUaGlzIGdpdmVzIHVzIGEgd2F5IHRvIGhhdmUgbXVsdGlwbGUgU2Nyb2xsVHJpZ2dlcnMgdXNlIGEgY2VudHJhbCBmdW5jdGlvbiBmb3IgYW55IGdpdmVuIHNjcm9sbGVyIGFuZCBzZWUgaWYgdGhlcmUncyBhIHNjcm9sbCB0d2VlbiBydW5uaW5nICh3aGljaCB3b3VsZCBhZmZlY3QgaWYvaG93IHRoaW5ncyBnZXQgdXBkYXRlZClcbl9nZXRUd2VlbkNyZWF0b3IgPSBmdW5jdGlvbiBfZ2V0VHdlZW5DcmVhdG9yKHNjcm9sbGVyLCBkaXJlY3Rpb24pIHtcbiAgdmFyIGdldFNjcm9sbCA9IF9nZXRTY3JvbGxGdW5jKHNjcm9sbGVyLCBkaXJlY3Rpb24pLFxuICAgICAgcHJvcCA9IFwiX3Njcm9sbFwiICsgZGlyZWN0aW9uLnAyLFxuICAgICAgLy8gYWRkIGEgdHdlZW5hYmxlIHByb3BlcnR5IHRvIHRoZSBzY3JvbGxlciB0aGF0J3MgYSBnZXR0ZXIvc2V0dGVyIGZ1bmN0aW9uLCBsaWtlIF9zY3JvbGxUb3Agb3IgX3Njcm9sbExlZnQuIFRoaXMgd2F5LCBpZiBzb21lb25lIGRvZXMgZ3NhcC5raWxsVHdlZW5zT2Yoc2Nyb2xsZXIpIGl0J2xsIGtpbGwgdGhlIHNjcm9sbCB0d2Vlbi5cbiAgbGFzdFNjcm9sbDEsXG4gICAgICBsYXN0U2Nyb2xsMixcbiAgICAgIGdldFR3ZWVuID0gZnVuY3Rpb24gZ2V0VHdlZW4oc2Nyb2xsVG8sIHZhcnMsIGluaXRpYWxWYWx1ZSwgY2hhbmdlMSwgY2hhbmdlMikge1xuICAgIHZhciB0d2VlbiA9IGdldFR3ZWVuLnR3ZWVuLFxuICAgICAgICBvbkNvbXBsZXRlID0gdmFycy5vbkNvbXBsZXRlLFxuICAgICAgICBtb2RpZmllcnMgPSB7fTtcbiAgICBpbml0aWFsVmFsdWUgPSBpbml0aWFsVmFsdWUgfHwgZ2V0U2Nyb2xsKCk7XG5cbiAgICB2YXIgY2hlY2tGb3JJbnRlcnJ1cHRpb24gPSBfaW50ZXJydXB0aW9uVHJhY2tlcihnZXRTY3JvbGwsIGluaXRpYWxWYWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgdHdlZW4ua2lsbCgpO1xuICAgICAgZ2V0VHdlZW4udHdlZW4gPSAwO1xuICAgIH0pO1xuXG4gICAgY2hhbmdlMiA9IGNoYW5nZTEgJiYgY2hhbmdlMiB8fCAwOyAvLyBpZiBjaGFuZ2UxIGlzIDAsIHdlIHNldCB0aGF0IHRvIHRoZSBkaWZmZXJlbmNlIGFuZCBpZ25vcmUgY2hhbmdlMi4gT3RoZXJ3aXNlLCB0aGVyZSB3b3VsZCBiZSBhIGNvbXBvdW5kIGVmZmVjdC5cblxuICAgIGNoYW5nZTEgPSBjaGFuZ2UxIHx8IHNjcm9sbFRvIC0gaW5pdGlhbFZhbHVlO1xuICAgIHR3ZWVuICYmIHR3ZWVuLmtpbGwoKTtcbiAgICBsYXN0U2Nyb2xsMSA9IE1hdGgucm91bmQoaW5pdGlhbFZhbHVlKTtcbiAgICB2YXJzW3Byb3BdID0gc2Nyb2xsVG87XG4gICAgdmFycy5tb2RpZmllcnMgPSBtb2RpZmllcnM7XG5cbiAgICBtb2RpZmllcnNbcHJvcF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gY2hlY2tGb3JJbnRlcnJ1cHRpb24oaW5pdGlhbFZhbHVlICsgY2hhbmdlMSAqIHR3ZWVuLnJhdGlvICsgY2hhbmdlMiAqIHR3ZWVuLnJhdGlvICogdHdlZW4ucmF0aW8pO1xuICAgIH07XG5cbiAgICB2YXJzLm9uVXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgX3Njcm9sbGVycy5jYWNoZSsrO1xuXG4gICAgICBfdXBkYXRlQWxsKCk7XG4gICAgfTtcblxuICAgIHZhcnMub25Db21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGdldFR3ZWVuLnR3ZWVuID0gMDtcbiAgICAgIG9uQ29tcGxldGUgJiYgb25Db21wbGV0ZS5jYWxsKHR3ZWVuKTtcbiAgICB9O1xuXG4gICAgdHdlZW4gPSBnZXRUd2Vlbi50d2VlbiA9IGdzYXAudG8oc2Nyb2xsZXIsIHZhcnMpO1xuICAgIHJldHVybiB0d2VlbjtcbiAgfTtcblxuICBzY3JvbGxlcltwcm9wXSA9IGdldFNjcm9sbDtcblxuICBnZXRTY3JvbGwud2hlZWxIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBnZXRUd2Vlbi50d2VlbiAmJiBnZXRUd2Vlbi50d2Vlbi5raWxsKCkgJiYgKGdldFR3ZWVuLnR3ZWVuID0gMCk7XG4gIH07XG5cbiAgX2FkZExpc3RlbmVyKHNjcm9sbGVyLCBcIndoZWVsXCIsIGdldFNjcm9sbC53aGVlbEhhbmRsZXIpOyAvLyBXaW5kb3dzIG1hY2hpbmVzIGhhbmRsZSBtb3VzZXdoZWVsIHNjcm9sbGluZyBpbiBjaHVua3MgKGxpa2UgXCIzIGxpbmVzIHBlciBzY3JvbGxcIikgbWVhbmluZyB0aGUgdHlwaWNhbCBzdHJhdGVneSBmb3IgY2FuY2VsbGluZyB0aGUgc2Nyb2xsIGlzbid0IGFzIHNlbnNpdGl2ZS4gSXQncyBtdWNoIG1vcmUgbGlrZWx5IHRvIG1hdGNoIG9uZSBvZiB0aGUgcHJldmlvdXMgMiBzY3JvbGwgZXZlbnQgcG9zaXRpb25zLiBTbyB3ZSBraWxsIGFueSBzbmFwcGluZyBhcyBzb29uIGFzIHRoZXJlJ3MgYSB3aGVlbCBldmVudC5cblxuXG4gIFNjcm9sbFRyaWdnZXIuaXNUb3VjaCAmJiBfYWRkTGlzdGVuZXIoc2Nyb2xsZXIsIFwidG91Y2htb3ZlXCIsIGdldFNjcm9sbC53aGVlbEhhbmRsZXIpO1xuICByZXR1cm4gZ2V0VHdlZW47XG59O1xuXG5leHBvcnQgdmFyIFNjcm9sbFRyaWdnZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTY3JvbGxUcmlnZ2VyKHZhcnMsIGFuaW1hdGlvbikge1xuICAgIF9jb3JlSW5pdHRlZCB8fCBTY3JvbGxUcmlnZ2VyLnJlZ2lzdGVyKGdzYXApIHx8IGNvbnNvbGUud2FybihcIlBsZWFzZSBnc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRyaWdnZXIpXCIpO1xuICAgIHRoaXMuaW5pdCh2YXJzLCBhbmltYXRpb24pO1xuICB9XG5cbiAgdmFyIF9wcm90byA9IFNjcm9sbFRyaWdnZXIucHJvdG90eXBlO1xuXG4gIF9wcm90by5pbml0ID0gZnVuY3Rpb24gaW5pdCh2YXJzLCBhbmltYXRpb24pIHtcbiAgICB0aGlzLnByb2dyZXNzID0gdGhpcy5zdGFydCA9IDA7XG4gICAgdGhpcy52YXJzICYmIHRoaXMua2lsbCh0cnVlLCB0cnVlKTsgLy8gaW4gY2FzZSBpdCdzIGJlaW5nIGluaXR0ZWQgYWdhaW5cblxuICAgIGlmICghX2VuYWJsZWQpIHtcbiAgICAgIHRoaXMudXBkYXRlID0gdGhpcy5yZWZyZXNoID0gdGhpcy5raWxsID0gX3Bhc3NUaHJvdWdoO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhcnMgPSBfc2V0RGVmYXVsdHMoX2lzU3RyaW5nKHZhcnMpIHx8IF9pc051bWJlcih2YXJzKSB8fCB2YXJzLm5vZGVUeXBlID8ge1xuICAgICAgdHJpZ2dlcjogdmFyc1xuICAgIH0gOiB2YXJzLCBfZGVmYXVsdHMpO1xuXG4gICAgdmFyIF92YXJzID0gdmFycyxcbiAgICAgICAgb25VcGRhdGUgPSBfdmFycy5vblVwZGF0ZSxcbiAgICAgICAgdG9nZ2xlQ2xhc3MgPSBfdmFycy50b2dnbGVDbGFzcyxcbiAgICAgICAgaWQgPSBfdmFycy5pZCxcbiAgICAgICAgb25Ub2dnbGUgPSBfdmFycy5vblRvZ2dsZSxcbiAgICAgICAgb25SZWZyZXNoID0gX3ZhcnMub25SZWZyZXNoLFxuICAgICAgICBzY3J1YiA9IF92YXJzLnNjcnViLFxuICAgICAgICB0cmlnZ2VyID0gX3ZhcnMudHJpZ2dlcixcbiAgICAgICAgcGluID0gX3ZhcnMucGluLFxuICAgICAgICBwaW5TcGFjaW5nID0gX3ZhcnMucGluU3BhY2luZyxcbiAgICAgICAgaW52YWxpZGF0ZU9uUmVmcmVzaCA9IF92YXJzLmludmFsaWRhdGVPblJlZnJlc2gsXG4gICAgICAgIGFudGljaXBhdGVQaW4gPSBfdmFycy5hbnRpY2lwYXRlUGluLFxuICAgICAgICBvblNjcnViQ29tcGxldGUgPSBfdmFycy5vblNjcnViQ29tcGxldGUsXG4gICAgICAgIG9uU25hcENvbXBsZXRlID0gX3ZhcnMub25TbmFwQ29tcGxldGUsXG4gICAgICAgIG9uY2UgPSBfdmFycy5vbmNlLFxuICAgICAgICBzbmFwID0gX3ZhcnMuc25hcCxcbiAgICAgICAgcGluUmVwYXJlbnQgPSBfdmFycy5waW5SZXBhcmVudCxcbiAgICAgICAgcGluU3BhY2VyID0gX3ZhcnMucGluU3BhY2VyLFxuICAgICAgICBjb250YWluZXJBbmltYXRpb24gPSBfdmFycy5jb250YWluZXJBbmltYXRpb24sXG4gICAgICAgIGZhc3RTY3JvbGxFbmQgPSBfdmFycy5mYXN0U2Nyb2xsRW5kLFxuICAgICAgICBwcmV2ZW50T3ZlcmxhcHMgPSBfdmFycy5wcmV2ZW50T3ZlcmxhcHMsXG4gICAgICAgIGRpcmVjdGlvbiA9IHZhcnMuaG9yaXpvbnRhbCB8fCB2YXJzLmNvbnRhaW5lckFuaW1hdGlvbiAmJiB2YXJzLmhvcml6b250YWwgIT09IGZhbHNlID8gX2hvcml6b250YWwgOiBfdmVydGljYWwsXG4gICAgICAgIGlzVG9nZ2xlID0gIXNjcnViICYmIHNjcnViICE9PSAwLFxuICAgICAgICBzY3JvbGxlciA9IF9nZXRUYXJnZXQodmFycy5zY3JvbGxlciB8fCBfd2luKSxcbiAgICAgICAgc2Nyb2xsZXJDYWNoZSA9IGdzYXAuY29yZS5nZXRDYWNoZShzY3JvbGxlciksXG4gICAgICAgIGlzVmlld3BvcnQgPSBfaXNWaWV3cG9ydChzY3JvbGxlciksXG4gICAgICAgIHVzZUZpeGVkUG9zaXRpb24gPSAoXCJwaW5UeXBlXCIgaW4gdmFycyA/IHZhcnMucGluVHlwZSA6IF9nZXRQcm94eVByb3Aoc2Nyb2xsZXIsIFwicGluVHlwZVwiKSB8fCBpc1ZpZXdwb3J0ICYmIFwiZml4ZWRcIikgPT09IFwiZml4ZWRcIixcbiAgICAgICAgY2FsbGJhY2tzID0gW3ZhcnMub25FbnRlciwgdmFycy5vbkxlYXZlLCB2YXJzLm9uRW50ZXJCYWNrLCB2YXJzLm9uTGVhdmVCYWNrXSxcbiAgICAgICAgdG9nZ2xlQWN0aW9ucyA9IGlzVG9nZ2xlICYmIHZhcnMudG9nZ2xlQWN0aW9ucy5zcGxpdChcIiBcIiksXG4gICAgICAgIG1hcmtlcnMgPSBcIm1hcmtlcnNcIiBpbiB2YXJzID8gdmFycy5tYXJrZXJzIDogX2RlZmF1bHRzLm1hcmtlcnMsXG4gICAgICAgIGJvcmRlcldpZHRoID0gaXNWaWV3cG9ydCA/IDAgOiBwYXJzZUZsb2F0KF9nZXRDb21wdXRlZFN0eWxlKHNjcm9sbGVyKVtcImJvcmRlclwiICsgZGlyZWN0aW9uLnAyICsgX1dpZHRoXSkgfHwgMCxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIG9uUmVmcmVzaEluaXQgPSB2YXJzLm9uUmVmcmVzaEluaXQgJiYgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHZhcnMub25SZWZyZXNoSW5pdChzZWxmKTtcbiAgICB9LFxuICAgICAgICBnZXRTY3JvbGxlclNpemUgPSBfZ2V0U2l6ZUZ1bmMoc2Nyb2xsZXIsIGlzVmlld3BvcnQsIGRpcmVjdGlvbiksXG4gICAgICAgIGdldFNjcm9sbGVyT2Zmc2V0cyA9IF9nZXRPZmZzZXRzRnVuYyhzY3JvbGxlciwgaXNWaWV3cG9ydCksXG4gICAgICAgIGxhc3RTbmFwID0gMCxcbiAgICAgICAgbGFzdFJlZnJlc2ggPSAwLFxuICAgICAgICBzY3JvbGxGdW5jID0gX2dldFNjcm9sbEZ1bmMoc2Nyb2xsZXIsIGRpcmVjdGlvbiksXG4gICAgICAgIHR3ZWVuVG8sXG4gICAgICAgIHBpbkNhY2hlLFxuICAgICAgICBzbmFwRnVuYyxcbiAgICAgICAgc2Nyb2xsMSxcbiAgICAgICAgc2Nyb2xsMixcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGVuZCxcbiAgICAgICAgbWFya2VyU3RhcnQsXG4gICAgICAgIG1hcmtlckVuZCxcbiAgICAgICAgbWFya2VyU3RhcnRUcmlnZ2VyLFxuICAgICAgICBtYXJrZXJFbmRUcmlnZ2VyLFxuICAgICAgICBtYXJrZXJWYXJzLFxuICAgICAgICBjaGFuZ2UsXG4gICAgICAgIHBpbk9yaWdpbmFsU3RhdGUsXG4gICAgICAgIHBpbkFjdGl2ZVN0YXRlLFxuICAgICAgICBwaW5TdGF0ZSxcbiAgICAgICAgc3BhY2VyLFxuICAgICAgICBvZmZzZXQsXG4gICAgICAgIHBpbkdldHRlcixcbiAgICAgICAgcGluU2V0dGVyLFxuICAgICAgICBwaW5TdGFydCxcbiAgICAgICAgcGluQ2hhbmdlLFxuICAgICAgICBzcGFjaW5nU3RhcnQsXG4gICAgICAgIHNwYWNlclN0YXRlLFxuICAgICAgICBtYXJrZXJTdGFydFNldHRlcixcbiAgICAgICAgcGluTW92ZXMsXG4gICAgICAgIG1hcmtlckVuZFNldHRlcixcbiAgICAgICAgY3MsXG4gICAgICAgIHNuYXAxLFxuICAgICAgICBzbmFwMixcbiAgICAgICAgc2NydWJUd2VlbixcbiAgICAgICAgc2NydWJTbW9vdGgsXG4gICAgICAgIHNuYXBEdXJDbGFtcCxcbiAgICAgICAgc25hcERlbGF5ZWRDYWxsLFxuICAgICAgICBwcmV2UHJvZ3Jlc3MsXG4gICAgICAgIHByZXZTY3JvbGwsXG4gICAgICAgIHByZXZBbmltUHJvZ3Jlc3MsXG4gICAgICAgIGNhTWFya2VyU2V0dGVyLFxuICAgICAgICBjdXN0b21SZXZlcnRSZXR1cm47XG5cbiAgICBfY29udGV4dChzZWxmKTtcblxuICAgIHNlbGYuX2RpciA9IGRpcmVjdGlvbjtcbiAgICBhbnRpY2lwYXRlUGluICo9IDQ1O1xuICAgIHNlbGYuc2Nyb2xsZXIgPSBzY3JvbGxlcjtcbiAgICBzZWxmLnNjcm9sbCA9IGNvbnRhaW5lckFuaW1hdGlvbiA/IGNvbnRhaW5lckFuaW1hdGlvbi50aW1lLmJpbmQoY29udGFpbmVyQW5pbWF0aW9uKSA6IHNjcm9sbEZ1bmM7XG4gICAgc2Nyb2xsMSA9IHNjcm9sbEZ1bmMoKTtcbiAgICBzZWxmLnZhcnMgPSB2YXJzO1xuICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbiB8fCB2YXJzLmFuaW1hdGlvbjtcblxuICAgIGlmIChcInJlZnJlc2hQcmlvcml0eVwiIGluIHZhcnMpIHtcbiAgICAgIF9zb3J0ID0gMTtcbiAgICAgIHZhcnMucmVmcmVzaFByaW9yaXR5ID09PSAtOTk5OSAmJiAoX3ByaW1hcnkgPSBzZWxmKTsgLy8gdXNlZCBieSBTY3JvbGxTbW9vdGhlclxuICAgIH1cblxuICAgIHNjcm9sbGVyQ2FjaGUudHdlZW5TY3JvbGwgPSBzY3JvbGxlckNhY2hlLnR3ZWVuU2Nyb2xsIHx8IHtcbiAgICAgIHRvcDogX2dldFR3ZWVuQ3JlYXRvcihzY3JvbGxlciwgX3ZlcnRpY2FsKSxcbiAgICAgIGxlZnQ6IF9nZXRUd2VlbkNyZWF0b3Ioc2Nyb2xsZXIsIF9ob3Jpem9udGFsKVxuICAgIH07XG4gICAgc2VsZi50d2VlblRvID0gdHdlZW5UbyA9IHNjcm9sbGVyQ2FjaGUudHdlZW5TY3JvbGxbZGlyZWN0aW9uLnBdO1xuXG4gICAgc2VsZi5zY3J1YkR1cmF0aW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBzY3J1YlNtb290aCA9IF9pc051bWJlcih2YWx1ZSkgJiYgdmFsdWU7XG5cbiAgICAgIGlmICghc2NydWJTbW9vdGgpIHtcbiAgICAgICAgc2NydWJUd2VlbiAmJiBzY3J1YlR3ZWVuLnByb2dyZXNzKDEpLmtpbGwoKTtcbiAgICAgICAgc2NydWJUd2VlbiA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzY3J1YlR3ZWVuID8gc2NydWJUd2Vlbi5kdXJhdGlvbih2YWx1ZSkgOiBzY3J1YlR3ZWVuID0gZ3NhcC50byhhbmltYXRpb24sIHtcbiAgICAgICAgICBlYXNlOiBcImV4cG9cIixcbiAgICAgICAgICB0b3RhbFByb2dyZXNzOiBcIis9MC4wMDFcIixcbiAgICAgICAgICBkdXJhdGlvbjogc2NydWJTbW9vdGgsXG4gICAgICAgICAgcGF1c2VkOiB0cnVlLFxuICAgICAgICAgIG9uQ29tcGxldGU6IGZ1bmN0aW9uIG9uQ29tcGxldGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gb25TY3J1YkNvbXBsZXRlICYmIG9uU2NydWJDb21wbGV0ZShzZWxmKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICBhbmltYXRpb24udmFycy5sYXp5ID0gZmFsc2U7XG4gICAgICBhbmltYXRpb24uX2luaXR0ZWQgfHwgYW5pbWF0aW9uLnZhcnMuaW1tZWRpYXRlUmVuZGVyICE9PSBmYWxzZSAmJiB2YXJzLmltbWVkaWF0ZVJlbmRlciAhPT0gZmFsc2UgJiYgYW5pbWF0aW9uLmR1cmF0aW9uKCkgJiYgYW5pbWF0aW9uLnJlbmRlcigwLCB0cnVlLCB0cnVlKTtcbiAgICAgIHNlbGYuYW5pbWF0aW9uID0gYW5pbWF0aW9uLnBhdXNlKCk7XG4gICAgICBhbmltYXRpb24uc2Nyb2xsVHJpZ2dlciA9IHNlbGY7XG4gICAgICBzZWxmLnNjcnViRHVyYXRpb24oc2NydWIpO1xuICAgICAgc2NydWJUd2VlbiAmJiBzY3J1YlR3ZWVuLnJlc2V0VG8gJiYgc2NydWJUd2Vlbi5yZXNldFRvKFwidG90YWxQcm9ncmVzc1wiLCAwKTsgLy8gb3RoZXJ3aXNlIHRoZSBpbml0aWFsIHNjcnViIHByb2dyZXNzIHZhbHVlIHdvdWxkIHN0YXJ0IGF0IDAuMDAxIHdoaWNoIG5vcm1hbGx5IGlzIG5vIGJpZyBkZWFsLCBidXQgZm9yIGNvbnRhaW5lckFuaW1hdGlvbiBpdCBjYW4gYmUgbm90aWNlYWJsZSBzaW5jZSB0aGUgcmFuZ2UgaXMgc28gdGlueS5cblxuICAgICAgc25hcDEgPSAwO1xuICAgICAgaWQgfHwgKGlkID0gYW5pbWF0aW9uLnZhcnMuaWQpO1xuICAgIH1cblxuICAgIF90cmlnZ2Vycy5wdXNoKHNlbGYpO1xuXG4gICAgaWYgKHNuYXApIHtcbiAgICAgIC8vIFRPRE86IHBvdGVudGlhbCBpZGVhOiB1c2UgbGVnaXRpbWF0ZSBDU1Mgc2Nyb2xsIHNuYXBwaW5nIGJ5IHB1c2hpbmcgaW52aXNpYmxlIGVsZW1lbnRzIGludG8gdGhlIERPTSB0aGF0IHNlcnZlIGFzIHNuYXAgcG9zaXRpb25zLCBhbmQgdG9nZ2xlIHRoZSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnN0eWxlLnNjcm9sbFNuYXBUeXBlIG9uVG9nZ2xlLiBTZWUgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vSmpMcmdXTSBmb3IgYSBxdWljayBwcm9vZiBvZiBjb25jZXB0LlxuICAgICAgaWYgKCFfaXNPYmplY3Qoc25hcCkgfHwgc25hcC5wdXNoKSB7XG4gICAgICAgIHNuYXAgPSB7XG4gICAgICAgICAgc25hcFRvOiBzbmFwXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIFwic2Nyb2xsQmVoYXZpb3JcIiBpbiBfYm9keS5zdHlsZSAmJiBnc2FwLnNldChpc1ZpZXdwb3J0ID8gW19ib2R5LCBfZG9jRWxdIDogc2Nyb2xsZXIsIHtcbiAgICAgICAgc2Nyb2xsQmVoYXZpb3I6IFwiYXV0b1wiXG4gICAgICB9KTsgLy8gc21vb3RoIHNjcm9sbGluZyBkb2Vzbid0IHdvcmsgd2l0aCBzbmFwLlxuXG4gICAgICBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgcmV0dXJuIF9pc0Z1bmN0aW9uKG8pICYmIG8udGFyZ2V0ID09PSAoaXNWaWV3cG9ydCA/IF9kb2Muc2Nyb2xsaW5nRWxlbWVudCB8fCBfZG9jRWwgOiBzY3JvbGxlcikgJiYgKG8uc21vb3RoID0gZmFsc2UpO1xuICAgICAgfSk7IC8vIG5vdGU6IHNldCBzbW9vdGggdG8gZmFsc2Ugb24gYm90aCB0aGUgdmVydGljYWwgYW5kIGhvcml6b250YWwgc2Nyb2xsIGdldHRlcnMvc2V0dGVyc1xuXG5cbiAgICAgIHNuYXBGdW5jID0gX2lzRnVuY3Rpb24oc25hcC5zbmFwVG8pID8gc25hcC5zbmFwVG8gOiBzbmFwLnNuYXBUbyA9PT0gXCJsYWJlbHNcIiA/IF9nZXRDbG9zZXN0TGFiZWwoYW5pbWF0aW9uKSA6IHNuYXAuc25hcFRvID09PSBcImxhYmVsc0RpcmVjdGlvbmFsXCIgPyBfZ2V0TGFiZWxBdERpcmVjdGlvbihhbmltYXRpb24pIDogc25hcC5kaXJlY3Rpb25hbCAhPT0gZmFsc2UgPyBmdW5jdGlvbiAodmFsdWUsIHN0KSB7XG4gICAgICAgIHJldHVybiBfc25hcERpcmVjdGlvbmFsKHNuYXAuc25hcFRvKSh2YWx1ZSwgX2dldFRpbWUoKSAtIGxhc3RSZWZyZXNoIDwgNTAwID8gMCA6IHN0LmRpcmVjdGlvbik7XG4gICAgICB9IDogZ3NhcC51dGlscy5zbmFwKHNuYXAuc25hcFRvKTtcbiAgICAgIHNuYXBEdXJDbGFtcCA9IHNuYXAuZHVyYXRpb24gfHwge1xuICAgICAgICBtaW46IDAuMSxcbiAgICAgICAgbWF4OiAyXG4gICAgICB9O1xuICAgICAgc25hcER1ckNsYW1wID0gX2lzT2JqZWN0KHNuYXBEdXJDbGFtcCkgPyBfY2xhbXAoc25hcER1ckNsYW1wLm1pbiwgc25hcER1ckNsYW1wLm1heCkgOiBfY2xhbXAoc25hcER1ckNsYW1wLCBzbmFwRHVyQ2xhbXApO1xuICAgICAgc25hcERlbGF5ZWRDYWxsID0gZ3NhcC5kZWxheWVkQ2FsbChzbmFwLmRlbGF5IHx8IHNjcnViU21vb3RoIC8gMiB8fCAwLjEsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNjcm9sbCA9IHNjcm9sbEZ1bmMoKSxcbiAgICAgICAgICAgIHJlZnJlc2hlZFJlY2VudGx5ID0gX2dldFRpbWUoKSAtIGxhc3RSZWZyZXNoIDwgNTAwLFxuICAgICAgICAgICAgdHdlZW4gPSB0d2VlblRvLnR3ZWVuO1xuXG4gICAgICAgIGlmICgocmVmcmVzaGVkUmVjZW50bHkgfHwgTWF0aC5hYnMoc2VsZi5nZXRWZWxvY2l0eSgpKSA8IDEwKSAmJiAhdHdlZW4gJiYgIV9wb2ludGVySXNEb3duICYmIGxhc3RTbmFwICE9PSBzY3JvbGwpIHtcbiAgICAgICAgICB2YXIgcHJvZ3Jlc3MgPSAoc2Nyb2xsIC0gc3RhcnQpIC8gY2hhbmdlLFxuICAgICAgICAgICAgICB0b3RhbFByb2dyZXNzID0gYW5pbWF0aW9uICYmICFpc1RvZ2dsZSA/IGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKCkgOiBwcm9ncmVzcyxcbiAgICAgICAgICAgICAgdmVsb2NpdHkgPSByZWZyZXNoZWRSZWNlbnRseSA/IDAgOiAodG90YWxQcm9ncmVzcyAtIHNuYXAyKSAvIChfZ2V0VGltZSgpIC0gX3RpbWUyKSAqIDEwMDAgfHwgMCxcbiAgICAgICAgICAgICAgY2hhbmdlMSA9IGdzYXAudXRpbHMuY2xhbXAoLXByb2dyZXNzLCAxIC0gcHJvZ3Jlc3MsIF9hYnModmVsb2NpdHkgLyAyKSAqIHZlbG9jaXR5IC8gMC4xODUpLFxuICAgICAgICAgICAgICBuYXR1cmFsRW5kID0gcHJvZ3Jlc3MgKyAoc25hcC5pbmVydGlhID09PSBmYWxzZSA/IDAgOiBjaGFuZ2UxKSxcbiAgICAgICAgICAgICAgZW5kVmFsdWUgPSBfY2xhbXAoMCwgMSwgc25hcEZ1bmMobmF0dXJhbEVuZCwgc2VsZikpLFxuICAgICAgICAgICAgICBlbmRTY3JvbGwgPSBNYXRoLnJvdW5kKHN0YXJ0ICsgZW5kVmFsdWUgKiBjaGFuZ2UpLFxuICAgICAgICAgICAgICBfc25hcCA9IHNuYXAsXG4gICAgICAgICAgICAgIG9uU3RhcnQgPSBfc25hcC5vblN0YXJ0LFxuICAgICAgICAgICAgICBfb25JbnRlcnJ1cHQgPSBfc25hcC5vbkludGVycnVwdCxcbiAgICAgICAgICAgICAgX29uQ29tcGxldGUgPSBfc25hcC5vbkNvbXBsZXRlO1xuXG4gICAgICAgICAgaWYgKHNjcm9sbCA8PSBlbmQgJiYgc2Nyb2xsID49IHN0YXJ0ICYmIGVuZFNjcm9sbCAhPT0gc2Nyb2xsKSB7XG4gICAgICAgICAgICBpZiAodHdlZW4gJiYgIXR3ZWVuLl9pbml0dGVkICYmIHR3ZWVuLmRhdGEgPD0gX2FicyhlbmRTY3JvbGwgLSBzY3JvbGwpKSB7XG4gICAgICAgICAgICAgIC8vIHRoZXJlJ3MgYW4gb3ZlcmxhcHBpbmcgc25hcCEgU28gd2UgbXVzdCBmaWd1cmUgb3V0IHdoaWNoIG9uZSBpcyBjbG9zZXIgYW5kIGxldCB0aGF0IHR3ZWVuIGxpdmUuXG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNuYXAuaW5lcnRpYSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgY2hhbmdlMSA9IGVuZFZhbHVlIC0gcHJvZ3Jlc3M7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHR3ZWVuVG8oZW5kU2Nyb2xsLCB7XG4gICAgICAgICAgICAgIGR1cmF0aW9uOiBzbmFwRHVyQ2xhbXAoX2FicyhNYXRoLm1heChfYWJzKG5hdHVyYWxFbmQgLSB0b3RhbFByb2dyZXNzKSwgX2FicyhlbmRWYWx1ZSAtIHRvdGFsUHJvZ3Jlc3MpKSAqIDAuMTg1IC8gdmVsb2NpdHkgLyAwLjA1IHx8IDApKSxcbiAgICAgICAgICAgICAgZWFzZTogc25hcC5lYXNlIHx8IFwicG93ZXIzXCIsXG4gICAgICAgICAgICAgIGRhdGE6IF9hYnMoZW5kU2Nyb2xsIC0gc2Nyb2xsKSxcbiAgICAgICAgICAgICAgLy8gcmVjb3JkIHRoZSBkaXN0YW5jZSBzbyB0aGF0IGlmIGFub3RoZXIgc25hcCB0d2VlbiBvY2N1cnMgKGNvbmZsaWN0KSB3ZSBjYW4gcHJpb3JpdGl6ZSB0aGUgY2xvc2VzdCBzbmFwLlxuICAgICAgICAgICAgICBvbkludGVycnVwdDogZnVuY3Rpb24gb25JbnRlcnJ1cHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNuYXBEZWxheWVkQ2FsbC5yZXN0YXJ0KHRydWUpICYmIF9vbkludGVycnVwdCAmJiBfb25JbnRlcnJ1cHQoc2VsZik7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG9uQ29tcGxldGU6IGZ1bmN0aW9uIG9uQ29tcGxldGUoKSB7XG4gICAgICAgICAgICAgICAgc2VsZi51cGRhdGUoKTtcbiAgICAgICAgICAgICAgICBsYXN0U25hcCA9IHNjcm9sbEZ1bmMoKTtcbiAgICAgICAgICAgICAgICBzbmFwMSA9IHNuYXAyID0gYW5pbWF0aW9uICYmICFpc1RvZ2dsZSA/IGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKCkgOiBzZWxmLnByb2dyZXNzO1xuICAgICAgICAgICAgICAgIG9uU25hcENvbXBsZXRlICYmIG9uU25hcENvbXBsZXRlKHNlbGYpO1xuICAgICAgICAgICAgICAgIF9vbkNvbXBsZXRlICYmIF9vbkNvbXBsZXRlKHNlbGYpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCBzY3JvbGwsIGNoYW5nZTEgKiBjaGFuZ2UsIGVuZFNjcm9sbCAtIHNjcm9sbCAtIGNoYW5nZTEgKiBjaGFuZ2UpO1xuICAgICAgICAgICAgb25TdGFydCAmJiBvblN0YXJ0KHNlbGYsIHR3ZWVuVG8udHdlZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzZWxmLmlzQWN0aXZlICYmIGxhc3RTbmFwICE9PSBzY3JvbGwpIHtcbiAgICAgICAgICBzbmFwRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSkucGF1c2UoKTtcbiAgICB9XG5cbiAgICBpZCAmJiAoX2lkc1tpZF0gPSBzZWxmKTtcbiAgICB0cmlnZ2VyID0gc2VsZi50cmlnZ2VyID0gX2dldFRhcmdldCh0cmlnZ2VyIHx8IHBpbik7IC8vIGlmIGEgdHJpZ2dlciBoYXMgc29tZSBraW5kIG9mIHNjcm9sbC1yZWxhdGVkIGVmZmVjdCBhcHBsaWVkIHRoYXQgY291bGQgY29udGFtaW5hdGUgdGhlIFwieVwiIG9yIFwieFwiIHBvc2l0aW9uIChsaWtlIGEgU2Nyb2xsU21vb3RoZXIgZWZmZWN0KSwgd2UgbmVlZGVkIGEgd2F5IHRvIHRlbXBvcmFyaWx5IHJldmVydCBpdCwgc28gd2UgdXNlIHRoZSBzdFJldmVydCBwcm9wZXJ0eSBvZiB0aGUgZ3NDYWNoZS4gSXQgY2FuIHJldHVybiBhbm90aGVyIGZ1bmN0aW9uIHRoYXQgd2UnbGwgY2FsbCBhdCB0aGUgZW5kIHNvIGl0IGNhbiByZXR1cm4gdG8gaXRzIG5vcm1hbCBzdGF0ZS5cblxuICAgIGN1c3RvbVJldmVydFJldHVybiA9IHRyaWdnZXIgJiYgdHJpZ2dlci5fZ3NhcCAmJiB0cmlnZ2VyLl9nc2FwLnN0UmV2ZXJ0O1xuICAgIGN1c3RvbVJldmVydFJldHVybiAmJiAoY3VzdG9tUmV2ZXJ0UmV0dXJuID0gY3VzdG9tUmV2ZXJ0UmV0dXJuKHNlbGYpKTtcbiAgICBwaW4gPSBwaW4gPT09IHRydWUgPyB0cmlnZ2VyIDogX2dldFRhcmdldChwaW4pO1xuICAgIF9pc1N0cmluZyh0b2dnbGVDbGFzcykgJiYgKHRvZ2dsZUNsYXNzID0ge1xuICAgICAgdGFyZ2V0czogdHJpZ2dlcixcbiAgICAgIGNsYXNzTmFtZTogdG9nZ2xlQ2xhc3NcbiAgICB9KTtcblxuICAgIGlmIChwaW4pIHtcbiAgICAgIHBpblNwYWNpbmcgPT09IGZhbHNlIHx8IHBpblNwYWNpbmcgPT09IF9tYXJnaW4gfHwgKHBpblNwYWNpbmcgPSAhcGluU3BhY2luZyAmJiBwaW4ucGFyZW50Tm9kZSAmJiBwaW4ucGFyZW50Tm9kZS5zdHlsZSAmJiBfZ2V0Q29tcHV0ZWRTdHlsZShwaW4ucGFyZW50Tm9kZSkuZGlzcGxheSA9PT0gXCJmbGV4XCIgPyBmYWxzZSA6IF9wYWRkaW5nKTsgLy8gaWYgdGhlIHBhcmVudCBpcyBkaXNwbGF5OiBmbGV4LCBkb24ndCBhcHBseSBwaW5TcGFjaW5nIGJ5IGRlZmF1bHQuIFdlIHNob3VsZCBjaGVjayB0aGF0IHBpbi5wYXJlbnROb2RlIGlzIGFuIGVsZW1lbnQgKG5vdCBzaGFkb3cgZG9tIHdpbmRvdylcblxuICAgICAgc2VsZi5waW4gPSBwaW47XG4gICAgICBwaW5DYWNoZSA9IGdzYXAuY29yZS5nZXRDYWNoZShwaW4pO1xuXG4gICAgICBpZiAoIXBpbkNhY2hlLnNwYWNlcikge1xuICAgICAgICAvLyByZWNvcmQgdGhlIHNwYWNlciBhbmQgcGluT3JpZ2luYWxTdGF0ZSBvbiB0aGUgY2FjaGUgaW4gY2FzZSBzb21lb25lIHRyaWVzIHBpbm5pbmcgdGhlIHNhbWUgZWxlbWVudCB3aXRoIE1VTFRJUExFIFNjcm9sbFRyaWdnZXJzIC0gd2UgZG9uJ3Qgd2FudCB0byBoYXZlIG11bHRpcGxlIHNwYWNlcnMgb3IgcmVjb3JkIHRoZSBcIm9yaWdpbmFsXCIgcGluIHN0YXRlIGFmdGVyIGl0IGhhcyBhbHJlYWR5IGJlZW4gYWZmZWN0ZWQgYnkgYW5vdGhlciBTY3JvbGxUcmlnZ2VyLlxuICAgICAgICBpZiAocGluU3BhY2VyKSB7XG4gICAgICAgICAgcGluU3BhY2VyID0gX2dldFRhcmdldChwaW5TcGFjZXIpO1xuICAgICAgICAgIHBpblNwYWNlciAmJiAhcGluU3BhY2VyLm5vZGVUeXBlICYmIChwaW5TcGFjZXIgPSBwaW5TcGFjZXIuY3VycmVudCB8fCBwaW5TcGFjZXIubmF0aXZlRWxlbWVudCk7IC8vIGZvciBSZWFjdCAmIEFuZ3VsYXJcblxuICAgICAgICAgIHBpbkNhY2hlLnNwYWNlcklzTmF0aXZlID0gISFwaW5TcGFjZXI7XG4gICAgICAgICAgcGluU3BhY2VyICYmIChwaW5DYWNoZS5zcGFjZXJTdGF0ZSA9IF9nZXRTdGF0ZShwaW5TcGFjZXIpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHBpbkNhY2hlLnNwYWNlciA9IHNwYWNlciA9IHBpblNwYWNlciB8fCBfZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIHNwYWNlci5jbGFzc0xpc3QuYWRkKFwicGluLXNwYWNlclwiKTtcbiAgICAgICAgaWQgJiYgc3BhY2VyLmNsYXNzTGlzdC5hZGQoXCJwaW4tc3BhY2VyLVwiICsgaWQpO1xuICAgICAgICBwaW5DYWNoZS5waW5TdGF0ZSA9IHBpbk9yaWdpbmFsU3RhdGUgPSBfZ2V0U3RhdGUocGluKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBpbk9yaWdpbmFsU3RhdGUgPSBwaW5DYWNoZS5waW5TdGF0ZTtcbiAgICAgIH1cblxuICAgICAgdmFycy5mb3JjZTNEICE9PSBmYWxzZSAmJiBnc2FwLnNldChwaW4sIHtcbiAgICAgICAgZm9yY2UzRDogdHJ1ZVxuICAgICAgfSk7XG4gICAgICBzZWxmLnNwYWNlciA9IHNwYWNlciA9IHBpbkNhY2hlLnNwYWNlcjtcbiAgICAgIGNzID0gX2dldENvbXB1dGVkU3R5bGUocGluKTtcbiAgICAgIHNwYWNpbmdTdGFydCA9IGNzW3BpblNwYWNpbmcgKyBkaXJlY3Rpb24ub3MyXTtcbiAgICAgIHBpbkdldHRlciA9IGdzYXAuZ2V0UHJvcGVydHkocGluKTtcbiAgICAgIHBpblNldHRlciA9IGdzYXAucXVpY2tTZXR0ZXIocGluLCBkaXJlY3Rpb24uYSwgX3B4KTsgLy8gcGluLmZpcnN0Q2hpbGQgJiYgIV9tYXhTY3JvbGwocGluLCBkaXJlY3Rpb24pICYmIChwaW4uc3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiKTsgLy8gcHJvdGVjdHMgZnJvbSBjb2xsYXBzaW5nIG1hcmdpbnMsIGJ1dCBjYW4gaGF2ZSB1bmludGVuZGVkIGNvbnNlcXVlbmNlcyBhcyBkZW1vbnN0cmF0ZWQgaGVyZTogaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vMWU0MmM3YTczYmZhNDA5ZDJjZjFlMTg0ZTdhNDI0OGQgc28gaXQgd2FzIHJlbW92ZWQgaW4gZmF2b3Igb2YganVzdCB0ZWxsaW5nIHBlb3BsZSB0byBzZXQgdXAgdGhlaXIgQ1NTIHRvIGF2b2lkIHRoZSBjb2xsYXBzaW5nIG1hcmdpbnMgKG92ZXJmbG93OiBoaWRkZW4gfCBhdXRvIGlzIGp1c3Qgb25lIG9wdGlvbi4gQW5vdGhlciBpcyBib3JkZXItdG9wOiAxcHggc29saWQgdHJhbnNwYXJlbnQpLlxuXG4gICAgICBfc3dhcFBpbkluKHBpbiwgc3BhY2VyLCBjcyk7XG5cbiAgICAgIHBpblN0YXRlID0gX2dldFN0YXRlKHBpbik7XG4gICAgfVxuXG4gICAgaWYgKG1hcmtlcnMpIHtcbiAgICAgIG1hcmtlclZhcnMgPSBfaXNPYmplY3QobWFya2VycykgPyBfc2V0RGVmYXVsdHMobWFya2VycywgX21hcmtlckRlZmF1bHRzKSA6IF9tYXJrZXJEZWZhdWx0cztcbiAgICAgIG1hcmtlclN0YXJ0VHJpZ2dlciA9IF9jcmVhdGVNYXJrZXIoXCJzY3JvbGxlci1zdGFydFwiLCBpZCwgc2Nyb2xsZXIsIGRpcmVjdGlvbiwgbWFya2VyVmFycywgMCk7XG4gICAgICBtYXJrZXJFbmRUcmlnZ2VyID0gX2NyZWF0ZU1hcmtlcihcInNjcm9sbGVyLWVuZFwiLCBpZCwgc2Nyb2xsZXIsIGRpcmVjdGlvbiwgbWFya2VyVmFycywgMCwgbWFya2VyU3RhcnRUcmlnZ2VyKTtcbiAgICAgIG9mZnNldCA9IG1hcmtlclN0YXJ0VHJpZ2dlcltcIm9mZnNldFwiICsgZGlyZWN0aW9uLm9wLmQyXTtcblxuICAgICAgdmFyIGNvbnRlbnQgPSBfZ2V0VGFyZ2V0KF9nZXRQcm94eVByb3Aoc2Nyb2xsZXIsIFwiY29udGVudFwiKSB8fCBzY3JvbGxlcik7XG5cbiAgICAgIG1hcmtlclN0YXJ0ID0gdGhpcy5tYXJrZXJTdGFydCA9IF9jcmVhdGVNYXJrZXIoXCJzdGFydFwiLCBpZCwgY29udGVudCwgZGlyZWN0aW9uLCBtYXJrZXJWYXJzLCBvZmZzZXQsIDAsIGNvbnRhaW5lckFuaW1hdGlvbik7XG4gICAgICBtYXJrZXJFbmQgPSB0aGlzLm1hcmtlckVuZCA9IF9jcmVhdGVNYXJrZXIoXCJlbmRcIiwgaWQsIGNvbnRlbnQsIGRpcmVjdGlvbiwgbWFya2VyVmFycywgb2Zmc2V0LCAwLCBjb250YWluZXJBbmltYXRpb24pO1xuICAgICAgY29udGFpbmVyQW5pbWF0aW9uICYmIChjYU1hcmtlclNldHRlciA9IGdzYXAucXVpY2tTZXR0ZXIoW21hcmtlclN0YXJ0LCBtYXJrZXJFbmRdLCBkaXJlY3Rpb24uYSwgX3B4KSk7XG5cbiAgICAgIGlmICghdXNlRml4ZWRQb3NpdGlvbiAmJiAhKF9wcm94aWVzLmxlbmd0aCAmJiBfZ2V0UHJveHlQcm9wKHNjcm9sbGVyLCBcImZpeGVkTWFya2Vyc1wiKSA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgX21ha2VQb3NpdGlvbmFibGUoaXNWaWV3cG9ydCA/IF9ib2R5IDogc2Nyb2xsZXIpO1xuXG4gICAgICAgIGdzYXAuc2V0KFttYXJrZXJTdGFydFRyaWdnZXIsIG1hcmtlckVuZFRyaWdnZXJdLCB7XG4gICAgICAgICAgZm9yY2UzRDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgbWFya2VyU3RhcnRTZXR0ZXIgPSBnc2FwLnF1aWNrU2V0dGVyKG1hcmtlclN0YXJ0VHJpZ2dlciwgZGlyZWN0aW9uLmEsIF9weCk7XG4gICAgICAgIG1hcmtlckVuZFNldHRlciA9IGdzYXAucXVpY2tTZXR0ZXIobWFya2VyRW5kVHJpZ2dlciwgZGlyZWN0aW9uLmEsIF9weCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRhaW5lckFuaW1hdGlvbikge1xuICAgICAgdmFyIG9sZE9uVXBkYXRlID0gY29udGFpbmVyQW5pbWF0aW9uLnZhcnMub25VcGRhdGUsXG4gICAgICAgICAgb2xkUGFyYW1zID0gY29udGFpbmVyQW5pbWF0aW9uLnZhcnMub25VcGRhdGVQYXJhbXM7XG4gICAgICBjb250YWluZXJBbmltYXRpb24uZXZlbnRDYWxsYmFjayhcIm9uVXBkYXRlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi51cGRhdGUoMCwgMCwgMSk7XG4gICAgICAgIG9sZE9uVXBkYXRlICYmIG9sZE9uVXBkYXRlLmFwcGx5KGNvbnRhaW5lckFuaW1hdGlvbiwgb2xkUGFyYW1zIHx8IFtdKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHNlbGYucHJldmlvdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RyaWdnZXJzW190cmlnZ2Vycy5pbmRleE9mKHNlbGYpIC0gMV07XG4gICAgfTtcblxuICAgIHNlbGYubmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdHJpZ2dlcnNbX3RyaWdnZXJzLmluZGV4T2Yoc2VsZikgKyAxXTtcbiAgICB9O1xuXG4gICAgc2VsZi5yZXZlcnQgPSBmdW5jdGlvbiAocmV2ZXJ0LCB0ZW1wKSB7XG4gICAgICBpZiAoIXRlbXApIHtcbiAgICAgICAgcmV0dXJuIHNlbGYua2lsbCh0cnVlKTtcbiAgICAgIH0gLy8gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBnc2FwLmNvbnRleHQoKSBhbmQgZ3NhcC5tYXRjaE1lZGlhKCkgd2hpY2ggY2FsbCByZXZlcnQoKVxuXG5cbiAgICAgIHZhciByID0gcmV2ZXJ0ICE9PSBmYWxzZSB8fCAhc2VsZi5lbmFibGVkLFxuICAgICAgICAgIHByZXZSZWZyZXNoaW5nID0gX3JlZnJlc2hpbmc7XG5cbiAgICAgIGlmIChyICE9PSBzZWxmLmlzUmV2ZXJ0ZWQpIHtcbiAgICAgICAgaWYgKHIpIHtcbiAgICAgICAgICAvLyBpZiAoIXNlbGYuc2Nyb2xsLnJlYyAmJiAoX3JlZnJlc2hpbmcgfHwgX3JlZnJlc2hpbmdBbGwpKSB7XG4gICAgICAgICAgLy8gXHRzZWxmLnNjcm9sbC5yZWMgPSBzY3JvbGxGdW5jKCk7XG4gICAgICAgICAgLy8gXHRfcmVmcmVzaGluZ0FsbCAmJiBzY3JvbGxGdW5jKDApO1xuICAgICAgICAgIC8vIH1cbiAgICAgICAgICBwcmV2U2Nyb2xsID0gTWF0aC5tYXgoc2Nyb2xsRnVuYygpLCBzZWxmLnNjcm9sbC5yZWMgfHwgMCk7IC8vIHJlY29yZCB0aGUgc2Nyb2xsIHNvIHdlIGNhbiByZXZlcnQgbGF0ZXIgKHJlcG9zaXRpb25pbmcvcGlubmluZyB0aGluZ3MgY2FuIGFmZmVjdCBzY3JvbGwgcG9zaXRpb24pLiBJbiB0aGUgc3RhdGljIHJlZnJlc2goKSBtZXRob2QsIHdlIGZpcnN0IHJlY29yZCBhbGwgdGhlIHNjcm9sbCBwb3NpdGlvbnMgYXMgYSByZWZlcmVuY2UuXG5cbiAgICAgICAgICBwcmV2UHJvZ3Jlc3MgPSBzZWxmLnByb2dyZXNzO1xuICAgICAgICAgIHByZXZBbmltUHJvZ3Jlc3MgPSBhbmltYXRpb24gJiYgYW5pbWF0aW9uLnByb2dyZXNzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBtYXJrZXJTdGFydCAmJiBbbWFya2VyU3RhcnQsIG1hcmtlckVuZCwgbWFya2VyU3RhcnRUcmlnZ2VyLCBtYXJrZXJFbmRUcmlnZ2VyXS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgcmV0dXJuIG0uc3R5bGUuZGlzcGxheSA9IHIgPyBcIm5vbmVcIiA6IFwiYmxvY2tcIjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHIpIHtcbiAgICAgICAgICBfcmVmcmVzaGluZyA9IHNlbGY7XG4gICAgICAgICAgc2VsZi51cGRhdGUocik7IC8vIG1ha2Ugc3VyZSB0aGUgcGluIGlzIGJhY2sgaW4gaXRzIG9yaWdpbmFsIHBvc2l0aW9uIHNvIHRoYXQgYWxsIHRoZSBtZWFzdXJlbWVudHMgYXJlIGNvcnJlY3QuIGRvIHRoaXMgQkVGT1JFIHN3YXBwaW5nIHRoZSBwaW4gb3V0XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGluICYmICghcGluUmVwYXJlbnQgfHwgIXNlbGYuaXNBY3RpdmUpKSB7XG4gICAgICAgICAgaWYgKHIpIHtcbiAgICAgICAgICAgIF9zd2FwUGluT3V0KHBpbiwgc3BhY2VyLCBwaW5PcmlnaW5hbFN0YXRlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgX3N3YXBQaW5JbihwaW4sIHNwYWNlciwgX2dldENvbXB1dGVkU3R5bGUocGluKSwgc3BhY2VyU3RhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHIgfHwgc2VsZi51cGRhdGUocik7IC8vIHdoZW4gd2UncmUgcmVzdG9yaW5nLCB0aGUgdXBkYXRlIHNob3VsZCBydW4gQUZURVIgc3dhcHBpbmcgdGhlIHBpbiBpbnRvIGl0cyBwaW4tc3BhY2VyLlxuXG4gICAgICAgIF9yZWZyZXNoaW5nID0gcHJldlJlZnJlc2hpbmc7IC8vIHJlc3RvcmUuIFdlIHNldCBpdCB0byB0cnVlIGR1cmluZyB0aGUgdXBkYXRlKCkgc28gdGhhdCB0aGluZ3MgZmlyZSBwcm9wZXJseSBpbiB0aGVyZS5cblxuICAgICAgICBzZWxmLmlzUmV2ZXJ0ZWQgPSByO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmLnJlZnJlc2ggPSBmdW5jdGlvbiAoc29mdCwgZm9yY2UpIHtcbiAgICAgIGlmICgoX3JlZnJlc2hpbmcgfHwgIXNlbGYuZW5hYmxlZCkgJiYgIWZvcmNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHBpbiAmJiBzb2Z0ICYmIF9sYXN0U2Nyb2xsVGltZSkge1xuICAgICAgICBfYWRkTGlzdGVuZXIoU2Nyb2xsVHJpZ2dlciwgXCJzY3JvbGxFbmRcIiwgX3NvZnRSZWZyZXNoKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgICFfcmVmcmVzaGluZ0FsbCAmJiBvblJlZnJlc2hJbml0ICYmIG9uUmVmcmVzaEluaXQoc2VsZik7XG4gICAgICBfcmVmcmVzaGluZyA9IHNlbGY7XG4gICAgICBsYXN0UmVmcmVzaCA9IF9nZXRUaW1lKCk7XG5cbiAgICAgIGlmICh0d2VlblRvLnR3ZWVuKSB7XG4gICAgICAgIHR3ZWVuVG8udHdlZW4ua2lsbCgpO1xuICAgICAgICB0d2VlblRvLnR3ZWVuID0gMDtcbiAgICAgIH1cblxuICAgICAgc2NydWJUd2VlbiAmJiBzY3J1YlR3ZWVuLnBhdXNlKCk7XG4gICAgICBpbnZhbGlkYXRlT25SZWZyZXNoICYmIGFuaW1hdGlvbiAmJiBhbmltYXRpb24ucmV2ZXJ0KHtcbiAgICAgICAga2lsbDogZmFsc2VcbiAgICAgIH0pLmludmFsaWRhdGUoKTtcbiAgICAgIHNlbGYuaXNSZXZlcnRlZCB8fCBzZWxmLnJldmVydCh0cnVlLCB0cnVlKTtcbiAgICAgIHNlbGYuX3N1YlBpbk9mZnNldCA9IGZhbHNlOyAvLyB3ZSdsbCBzZXQgdGhpcyB0byB0cnVlIGluIHRoZSBzdWItcGlucyBpZiB3ZSBmaW5kIGFueVxuXG4gICAgICB2YXIgc2l6ZSA9IGdldFNjcm9sbGVyU2l6ZSgpLFxuICAgICAgICAgIHNjcm9sbGVyQm91bmRzID0gZ2V0U2Nyb2xsZXJPZmZzZXRzKCksXG4gICAgICAgICAgbWF4ID0gY29udGFpbmVyQW5pbWF0aW9uID8gY29udGFpbmVyQW5pbWF0aW9uLmR1cmF0aW9uKCkgOiBfbWF4U2Nyb2xsKHNjcm9sbGVyLCBkaXJlY3Rpb24pLFxuICAgICAgICAgIGlzRmlyc3RSZWZyZXNoID0gY2hhbmdlIDw9IDAuMDEsXG4gICAgICAgICAgb2Zmc2V0ID0gMCxcbiAgICAgICAgICBvdGhlclBpbk9mZnNldCA9IDAsXG4gICAgICAgICAgcGFyc2VkRW5kID0gdmFycy5lbmQsXG4gICAgICAgICAgcGFyc2VkRW5kVHJpZ2dlciA9IHZhcnMuZW5kVHJpZ2dlciB8fCB0cmlnZ2VyLFxuICAgICAgICAgIHBhcnNlZFN0YXJ0ID0gdmFycy5zdGFydCB8fCAodmFycy5zdGFydCA9PT0gMCB8fCAhdHJpZ2dlciA/IDAgOiBwaW4gPyBcIjAgMFwiIDogXCIwIDEwMCVcIiksXG4gICAgICAgICAgcGlubmVkQ29udGFpbmVyID0gc2VsZi5waW5uZWRDb250YWluZXIgPSB2YXJzLnBpbm5lZENvbnRhaW5lciAmJiBfZ2V0VGFyZ2V0KHZhcnMucGlubmVkQ29udGFpbmVyKSxcbiAgICAgICAgICB0cmlnZ2VySW5kZXggPSB0cmlnZ2VyICYmIE1hdGgubWF4KDAsIF90cmlnZ2Vycy5pbmRleE9mKHNlbGYpKSB8fCAwLFxuICAgICAgICAgIGkgPSB0cmlnZ2VySW5kZXgsXG4gICAgICAgICAgY3MsXG4gICAgICAgICAgYm91bmRzLFxuICAgICAgICAgIHNjcm9sbCxcbiAgICAgICAgICBpc1ZlcnRpY2FsLFxuICAgICAgICAgIG92ZXJyaWRlLFxuICAgICAgICAgIGN1clRyaWdnZXIsXG4gICAgICAgICAgY3VyUGluLFxuICAgICAgICAgIG9wcG9zaXRlU2Nyb2xsLFxuICAgICAgICAgIGluaXR0ZWQsXG4gICAgICAgICAgcmV2ZXJ0ZWRQaW5zLFxuICAgICAgICAgIGZvcmNlZE92ZXJmbG93O1xuXG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIC8vIHVzZXIgbWlnaHQgdHJ5IHRvIHBpbiB0aGUgc2FtZSBlbGVtZW50IG1vcmUgdGhhbiBvbmNlLCBzbyB3ZSBtdXN0IGZpbmQgYW55IHByaW9yIHRyaWdnZXJzIHdpdGggdGhlIHNhbWUgcGluLCByZXZlcnQgdGhlbSwgYW5kIGRldGVybWluZSBob3cgbG9uZyB0aGV5J3JlIHBpbm5pbmcgc28gdGhhdCB3ZSBjYW4gb2Zmc2V0IHRoaW5ncyBhcHByb3ByaWF0ZWx5LiBNYWtlIHN1cmUgd2UgcmV2ZXJ0IGZyb20gbGFzdCB0byBmaXJzdCBzbyB0aGF0IHRoaW5ncyBcInJld2luZFwiIHByb3Blcmx5LlxuICAgICAgICBjdXJUcmlnZ2VyID0gX3RyaWdnZXJzW2ldO1xuICAgICAgICBjdXJUcmlnZ2VyLmVuZCB8fCBjdXJUcmlnZ2VyLnJlZnJlc2goMCwgMSkgfHwgKF9yZWZyZXNoaW5nID0gc2VsZik7IC8vIGlmIGl0J3MgYSB0aW1lbGluZS1iYXNlZCB0cmlnZ2VyIHRoYXQgaGFzbid0IGJlZW4gZnVsbHkgaW5pdGlhbGl6ZWQgeWV0IGJlY2F1c2UgaXQncyB3YWl0aW5nIGZvciAxIHRpY2ssIGp1c3QgZm9yY2UgdGhlIHJlZnJlc2goKSBoZXJlLCBvdGhlcndpc2UgaWYgaXQgY29udGFpbnMgYSBwaW4gdGhhdCdzIHN1cHBvc2VkIHRvIGFmZmVjdCBvdGhlciBTY3JvbGxUcmlnZ2VycyBmdXJ0aGVyIGRvd24gdGhlIHBhZ2UsIHRoZXkgd29uJ3QgYmUgYWRqdXN0ZWQgcHJvcGVybHkuXG5cbiAgICAgICAgY3VyUGluID0gY3VyVHJpZ2dlci5waW47XG5cbiAgICAgICAgaWYgKGN1clBpbiAmJiAoY3VyUGluID09PSB0cmlnZ2VyIHx8IGN1clBpbiA9PT0gcGluIHx8IGN1clBpbiA9PT0gcGlubmVkQ29udGFpbmVyKSAmJiAhY3VyVHJpZ2dlci5pc1JldmVydGVkKSB7XG4gICAgICAgICAgcmV2ZXJ0ZWRQaW5zIHx8IChyZXZlcnRlZFBpbnMgPSBbXSk7XG4gICAgICAgICAgcmV2ZXJ0ZWRQaW5zLnVuc2hpZnQoY3VyVHJpZ2dlcik7IC8vIHdlJ2xsIHJldmVydCBmcm9tIGZpcnN0IHRvIGxhc3QgdG8gbWFrZSBzdXJlIHRoaW5ncyByZWFjaCB0aGVpciBlbmQgc3RhdGUgcHJvcGVybHlcblxuICAgICAgICAgIGN1clRyaWdnZXIucmV2ZXJ0KHRydWUsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGN1clRyaWdnZXIgIT09IF90cmlnZ2Vyc1tpXSkge1xuICAgICAgICAgIC8vIGluIGNhc2UgaXQgZ290IHJlbW92ZWQuXG4gICAgICAgICAgdHJpZ2dlckluZGV4LS07XG4gICAgICAgICAgaS0tO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIF9pc0Z1bmN0aW9uKHBhcnNlZFN0YXJ0KSAmJiAocGFyc2VkU3RhcnQgPSBwYXJzZWRTdGFydChzZWxmKSk7XG4gICAgICBzdGFydCA9IF9wYXJzZVBvc2l0aW9uKHBhcnNlZFN0YXJ0LCB0cmlnZ2VyLCBzaXplLCBkaXJlY3Rpb24sIHNjcm9sbEZ1bmMoKSwgbWFya2VyU3RhcnQsIG1hcmtlclN0YXJ0VHJpZ2dlciwgc2VsZiwgc2Nyb2xsZXJCb3VuZHMsIGJvcmRlcldpZHRoLCB1c2VGaXhlZFBvc2l0aW9uLCBtYXgsIGNvbnRhaW5lckFuaW1hdGlvbikgfHwgKHBpbiA/IC0wLjAwMSA6IDApO1xuICAgICAgX2lzRnVuY3Rpb24ocGFyc2VkRW5kKSAmJiAocGFyc2VkRW5kID0gcGFyc2VkRW5kKHNlbGYpKTtcblxuICAgICAgaWYgKF9pc1N0cmluZyhwYXJzZWRFbmQpICYmICFwYXJzZWRFbmQuaW5kZXhPZihcIis9XCIpKSB7XG4gICAgICAgIGlmICh+cGFyc2VkRW5kLmluZGV4T2YoXCIgXCIpKSB7XG4gICAgICAgICAgcGFyc2VkRW5kID0gKF9pc1N0cmluZyhwYXJzZWRTdGFydCkgPyBwYXJzZWRTdGFydC5zcGxpdChcIiBcIilbMF0gOiBcIlwiKSArIHBhcnNlZEVuZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvZmZzZXQgPSBfb2Zmc2V0VG9QeChwYXJzZWRFbmQuc3Vic3RyKDIpLCBzaXplKTtcbiAgICAgICAgICBwYXJzZWRFbmQgPSBfaXNTdHJpbmcocGFyc2VkU3RhcnQpID8gcGFyc2VkU3RhcnQgOiAoY29udGFpbmVyQW5pbWF0aW9uID8gZ3NhcC51dGlscy5tYXBSYW5nZSgwLCBjb250YWluZXJBbmltYXRpb24uZHVyYXRpb24oKSwgY29udGFpbmVyQW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIuc3RhcnQsIGNvbnRhaW5lckFuaW1hdGlvbi5zY3JvbGxUcmlnZ2VyLmVuZCwgc3RhcnQpIDogc3RhcnQpICsgb2Zmc2V0OyAvLyBfcGFyc2VQb3NpdGlvbiB3b24ndCBmYWN0b3IgaW4gdGhlIG9mZnNldCBpZiB0aGUgc3RhcnQgaXMgYSBudW1iZXIsIHNvIGRvIGl0IGhlcmUuXG5cbiAgICAgICAgICBwYXJzZWRFbmRUcmlnZ2VyID0gdHJpZ2dlcjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlbmQgPSBNYXRoLm1heChzdGFydCwgX3BhcnNlUG9zaXRpb24ocGFyc2VkRW5kIHx8IChwYXJzZWRFbmRUcmlnZ2VyID8gXCIxMDAlIDBcIiA6IG1heCksIHBhcnNlZEVuZFRyaWdnZXIsIHNpemUsIGRpcmVjdGlvbiwgc2Nyb2xsRnVuYygpICsgb2Zmc2V0LCBtYXJrZXJFbmQsIG1hcmtlckVuZFRyaWdnZXIsIHNlbGYsIHNjcm9sbGVyQm91bmRzLCBib3JkZXJXaWR0aCwgdXNlRml4ZWRQb3NpdGlvbiwgbWF4LCBjb250YWluZXJBbmltYXRpb24pKSB8fCAtMC4wMDE7XG4gICAgICBjaGFuZ2UgPSBlbmQgLSBzdGFydCB8fCAoc3RhcnQgLT0gMC4wMSkgJiYgMC4wMDE7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgICAgaSA9IHRyaWdnZXJJbmRleDtcblxuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBjdXJUcmlnZ2VyID0gX3RyaWdnZXJzW2ldO1xuICAgICAgICBjdXJQaW4gPSBjdXJUcmlnZ2VyLnBpbjtcblxuICAgICAgICBpZiAoY3VyUGluICYmIGN1clRyaWdnZXIuc3RhcnQgLSBjdXJUcmlnZ2VyLl9waW5QdXNoIDw9IHN0YXJ0ICYmICFjb250YWluZXJBbmltYXRpb24gJiYgY3VyVHJpZ2dlci5lbmQgPiAwKSB7XG4gICAgICAgICAgY3MgPSBjdXJUcmlnZ2VyLmVuZCAtIGN1clRyaWdnZXIuc3RhcnQ7XG5cbiAgICAgICAgICBpZiAoKGN1clBpbiA9PT0gdHJpZ2dlciAmJiBjdXJUcmlnZ2VyLnN0YXJ0IC0gY3VyVHJpZ2dlci5fcGluUHVzaCA8IHN0YXJ0IHx8IGN1clBpbiA9PT0gcGlubmVkQ29udGFpbmVyKSAmJiAhX2lzTnVtYmVyKHBhcnNlZFN0YXJ0KSkge1xuICAgICAgICAgICAgLy8gbnVtZXJpYyBzdGFydCB2YWx1ZXMgc2hvdWxkbid0IGJlIG9mZnNldCBhdCBhbGwgLSB0cmVhdCB0aGVtIGFzIGFic29sdXRlXG4gICAgICAgICAgICBvZmZzZXQgKz0gY3MgKiAoMSAtIGN1clRyaWdnZXIucHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN1clBpbiA9PT0gcGluICYmIChvdGhlclBpbk9mZnNldCArPSBjcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RhcnQgKz0gb2Zmc2V0O1xuICAgICAgZW5kICs9IG9mZnNldDtcblxuICAgICAgaWYgKGlzRmlyc3RSZWZyZXNoKSB7XG4gICAgICAgIC8vIG9uIHRoZSB2ZXJ5IGZpcnN0IHJlZnJlc2goKSwgdGhlIHByZXZQcm9ncmVzcyBjb3VsZG4ndCBoYXZlIGJlZW4gYWNjdXJhdGUgeWV0IGJlY2F1c2UgdGhlIHN0YXJ0L2VuZCB3ZXJlIG5ldmVyIGNhbGN1bGF0ZWQsIHNvIHdlIHNldCBpdCBoZXJlLiBCZWZvcmUgMy4xMS41LCBpdCBjb3VsZCBsZWFkIHRvIGFuIGluYWNjdXJhdGUgc2Nyb2xsIHBvc2l0aW9uIHJlc3RvcmF0aW9uIHdpdGggc25hcHBpbmcuXG4gICAgICAgIHByZXZQcm9ncmVzcyA9IGdzYXAudXRpbHMuY2xhbXAoMCwgMSwgZ3NhcC51dGlscy5ub3JtYWxpemUoc3RhcnQsIGVuZCwgcHJldlNjcm9sbCkpO1xuICAgICAgfVxuXG4gICAgICBzZWxmLl9waW5QdXNoID0gb3RoZXJQaW5PZmZzZXQ7XG5cbiAgICAgIGlmIChtYXJrZXJTdGFydCAmJiBvZmZzZXQpIHtcbiAgICAgICAgLy8gb2Zmc2V0IHRoZSBtYXJrZXJzIGlmIG5lY2Vzc2FyeVxuICAgICAgICBjcyA9IHt9O1xuICAgICAgICBjc1tkaXJlY3Rpb24uYV0gPSBcIis9XCIgKyBvZmZzZXQ7XG4gICAgICAgIHBpbm5lZENvbnRhaW5lciAmJiAoY3NbZGlyZWN0aW9uLnBdID0gXCItPVwiICsgc2Nyb2xsRnVuYygpKTtcbiAgICAgICAgZ3NhcC5zZXQoW21hcmtlclN0YXJ0LCBtYXJrZXJFbmRdLCBjcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwaW4pIHtcbiAgICAgICAgY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShwaW4pO1xuICAgICAgICBpc1ZlcnRpY2FsID0gZGlyZWN0aW9uID09PSBfdmVydGljYWw7XG4gICAgICAgIHNjcm9sbCA9IHNjcm9sbEZ1bmMoKTsgLy8gcmVjYWxjdWxhdGUgYmVjYXVzZSB0aGUgdHJpZ2dlcnMgY2FuIGFmZmVjdCB0aGUgc2Nyb2xsXG5cbiAgICAgICAgcGluU3RhcnQgPSBwYXJzZUZsb2F0KHBpbkdldHRlcihkaXJlY3Rpb24uYSkpICsgb3RoZXJQaW5PZmZzZXQ7XG5cbiAgICAgICAgaWYgKCFtYXggJiYgZW5kID4gMSkge1xuICAgICAgICAgIC8vIG1ha2VzIHN1cmUgdGhlIHNjcm9sbGVyIGhhcyBhIHNjcm9sbGJhciwgb3RoZXJ3aXNlIGlmIHNvbWV0aGluZyBoYXMgd2lkdGg6IDEwMCUsIGZvciBleGFtcGxlLCBpdCB3b3VsZCBiZSB0b28gYmlnIChleGNsdWRlIHRoZSBzY3JvbGxiYXIpLiBTZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2ZvcnVtcy90b3BpYy8yNTE4Mi1zY3JvbGx0cmlnZ2VyLXdpZHRoLW9mLXBhZ2UtaW5jcmVhc2Utd2hlcmUtbWFya2Vycy1hcmUtc2V0LXRvLWZhbHNlL1xuICAgICAgICAgIGZvcmNlZE92ZXJmbG93ID0gKGlzVmlld3BvcnQgPyBfZG9jLnNjcm9sbGluZ0VsZW1lbnQgfHwgX2RvY0VsIDogc2Nyb2xsZXIpLnN0eWxlO1xuICAgICAgICAgIGZvcmNlZE92ZXJmbG93ID0ge1xuICAgICAgICAgICAgc3R5bGU6IGZvcmNlZE92ZXJmbG93LFxuICAgICAgICAgICAgdmFsdWU6IGZvcmNlZE92ZXJmbG93W1wib3ZlcmZsb3dcIiArIGRpcmVjdGlvbi5hLnRvVXBwZXJDYXNlKCldXG4gICAgICAgICAgfTtcbiAgICAgICAgICBmb3JjZWRPdmVyZmxvdy5zdHlsZVtcIm92ZXJmbG93XCIgKyBkaXJlY3Rpb24uYS50b1VwcGVyQ2FzZSgpXSA9IFwic2Nyb2xsXCI7XG4gICAgICAgIH1cblxuICAgICAgICBfc3dhcFBpbkluKHBpbiwgc3BhY2VyLCBjcyk7XG5cbiAgICAgICAgcGluU3RhdGUgPSBfZ2V0U3RhdGUocGluKTsgLy8gdHJhbnNmb3JtcyB3aWxsIGludGVyZmVyZSB3aXRoIHRoZSB0b3AvbGVmdC9yaWdodC9ib3R0b20gcGxhY2VtZW50LCBzbyByZW1vdmUgdGhlbSB0ZW1wb3JhcmlseS4gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgZmFjdG9ycyBpbiB0cmFuc2Zvcm1zLlxuXG4gICAgICAgIGJvdW5kcyA9IF9nZXRCb3VuZHMocGluLCB0cnVlKTtcbiAgICAgICAgb3Bwb3NpdGVTY3JvbGwgPSB1c2VGaXhlZFBvc2l0aW9uICYmIF9nZXRTY3JvbGxGdW5jKHNjcm9sbGVyLCBpc1ZlcnRpY2FsID8gX2hvcml6b250YWwgOiBfdmVydGljYWwpKCk7XG5cbiAgICAgICAgaWYgKHBpblNwYWNpbmcpIHtcbiAgICAgICAgICBzcGFjZXJTdGF0ZSA9IFtwaW5TcGFjaW5nICsgZGlyZWN0aW9uLm9zMiwgY2hhbmdlICsgb3RoZXJQaW5PZmZzZXQgKyBfcHhdO1xuICAgICAgICAgIHNwYWNlclN0YXRlLnQgPSBzcGFjZXI7XG4gICAgICAgICAgaSA9IHBpblNwYWNpbmcgPT09IF9wYWRkaW5nID8gX2dldFNpemUocGluLCBkaXJlY3Rpb24pICsgY2hhbmdlICsgb3RoZXJQaW5PZmZzZXQgOiAwO1xuICAgICAgICAgIGkgJiYgc3BhY2VyU3RhdGUucHVzaChkaXJlY3Rpb24uZCwgaSArIF9weCk7IC8vIGZvciBib3gtc2l6aW5nOiBib3JkZXItYm94IChtdXN0IGluY2x1ZGUgcGFkZGluZykuXG5cbiAgICAgICAgICBfc2V0U3RhdGUoc3BhY2VyU3RhdGUpO1xuXG4gICAgICAgICAgaWYgKHBpbm5lZENvbnRhaW5lcikge1xuICAgICAgICAgICAgLy8gaW4gU2Nyb2xsVHJpZ2dlci5yZWZyZXNoKCksIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgdGhlIHBpbkNvbnRhaW5lcidzIHNpemUgYmVjYXVzZSB0aGlzIHBpblNwYWNpbmcgbWF5IHN0cmV0Y2ggaXQgb3V0LCBidXQgd2UgY2FuJ3QganVzdCBhZGQgdGhlIGV4YWN0IGRpc3RhbmNlIGJlY2F1c2UgZGVwZW5kaW5nIG9uIGxheW91dCwgaXQgbWF5IG5vdCBwdXNoIHRoaW5ncyBkb3duIG9yIGl0IG1heSBvbmx5IGRvIHNvIHBhcnRpYWxseS5cbiAgICAgICAgICAgIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgIGlmICh0LnBpbiA9PT0gcGlubmVkQ29udGFpbmVyICYmIHQudmFycy5waW5TcGFjaW5nICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHQuX3N1YlBpbk9mZnNldCA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVzZUZpeGVkUG9zaXRpb24gJiYgc2Nyb2xsRnVuYyhwcmV2U2Nyb2xsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1c2VGaXhlZFBvc2l0aW9uKSB7XG4gICAgICAgICAgb3ZlcnJpZGUgPSB7XG4gICAgICAgICAgICB0b3A6IGJvdW5kcy50b3AgKyAoaXNWZXJ0aWNhbCA/IHNjcm9sbCAtIHN0YXJ0IDogb3Bwb3NpdGVTY3JvbGwpICsgX3B4LFxuICAgICAgICAgICAgbGVmdDogYm91bmRzLmxlZnQgKyAoaXNWZXJ0aWNhbCA/IG9wcG9zaXRlU2Nyb2xsIDogc2Nyb2xsIC0gc3RhcnQpICsgX3B4LFxuICAgICAgICAgICAgYm94U2l6aW5nOiBcImJvcmRlci1ib3hcIixcbiAgICAgICAgICAgIHBvc2l0aW9uOiBcImZpeGVkXCJcbiAgICAgICAgICB9O1xuICAgICAgICAgIG92ZXJyaWRlW193aWR0aF0gPSBvdmVycmlkZVtcIm1heFwiICsgX1dpZHRoXSA9IE1hdGguY2VpbChib3VuZHMud2lkdGgpICsgX3B4O1xuICAgICAgICAgIG92ZXJyaWRlW19oZWlnaHRdID0gb3ZlcnJpZGVbXCJtYXhcIiArIF9IZWlnaHRdID0gTWF0aC5jZWlsKGJvdW5kcy5oZWlnaHQpICsgX3B4O1xuICAgICAgICAgIG92ZXJyaWRlW19tYXJnaW5dID0gb3ZlcnJpZGVbX21hcmdpbiArIF9Ub3BdID0gb3ZlcnJpZGVbX21hcmdpbiArIF9SaWdodF0gPSBvdmVycmlkZVtfbWFyZ2luICsgX0JvdHRvbV0gPSBvdmVycmlkZVtfbWFyZ2luICsgX0xlZnRdID0gXCIwXCI7XG4gICAgICAgICAgb3ZlcnJpZGVbX3BhZGRpbmddID0gY3NbX3BhZGRpbmddO1xuICAgICAgICAgIG92ZXJyaWRlW19wYWRkaW5nICsgX1RvcF0gPSBjc1tfcGFkZGluZyArIF9Ub3BdO1xuICAgICAgICAgIG92ZXJyaWRlW19wYWRkaW5nICsgX1JpZ2h0XSA9IGNzW19wYWRkaW5nICsgX1JpZ2h0XTtcbiAgICAgICAgICBvdmVycmlkZVtfcGFkZGluZyArIF9Cb3R0b21dID0gY3NbX3BhZGRpbmcgKyBfQm90dG9tXTtcbiAgICAgICAgICBvdmVycmlkZVtfcGFkZGluZyArIF9MZWZ0XSA9IGNzW19wYWRkaW5nICsgX0xlZnRdO1xuICAgICAgICAgIHBpbkFjdGl2ZVN0YXRlID0gX2NvcHlTdGF0ZShwaW5PcmlnaW5hbFN0YXRlLCBvdmVycmlkZSwgcGluUmVwYXJlbnQpO1xuICAgICAgICAgIF9yZWZyZXNoaW5nQWxsICYmIHNjcm9sbEZ1bmMoMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICAgICAgLy8gdGhlIGFuaW1hdGlvbiBtaWdodCBiZSBhZmZlY3RpbmcgdGhlIHRyYW5zZm9ybSwgc28gd2UgbXVzdCBqdW1wIHRvIHRoZSBlbmQsIGNoZWNrIHRoZSB2YWx1ZSwgYW5kIGNvbXBlbnNhdGUgYWNjb3JkaW5nbHkuIE90aGVyd2lzZSwgd2hlbiBpdCBiZWNvbWVzIHVucGlubmVkLCB0aGUgcGluU2V0dGVyKCkgd2lsbCBnZXQgc2V0IHRvIGEgdmFsdWUgdGhhdCBkb2Vzbid0IGluY2x1ZGUgd2hhdGV2ZXIgdGhlIGFuaW1hdGlvbiBkaWQuXG4gICAgICAgICAgaW5pdHRlZCA9IGFuaW1hdGlvbi5faW5pdHRlZDsgLy8gaWYgbm90LCB3ZSBtdXN0IGludmFsaWRhdGUoKSBhZnRlciB0aGlzIHN0ZXAsIG90aGVyd2lzZSBpdCBjb3VsZCBsb2NrIGluIHN0YXJ0aW5nIHZhbHVlcyBwcmVtYXR1cmVseS5cblxuICAgICAgICAgIF9zdXBwcmVzc092ZXJ3cml0ZXMoMSk7XG5cbiAgICAgICAgICBhbmltYXRpb24ucmVuZGVyKGFuaW1hdGlvbi5kdXJhdGlvbigpLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgICBwaW5DaGFuZ2UgPSBwaW5HZXR0ZXIoZGlyZWN0aW9uLmEpIC0gcGluU3RhcnQgKyBjaGFuZ2UgKyBvdGhlclBpbk9mZnNldDtcbiAgICAgICAgICBwaW5Nb3ZlcyA9IE1hdGguYWJzKGNoYW5nZSAtIHBpbkNoYW5nZSkgPiAxO1xuICAgICAgICAgIHVzZUZpeGVkUG9zaXRpb24gJiYgcGluTW92ZXMgJiYgcGluQWN0aXZlU3RhdGUuc3BsaWNlKHBpbkFjdGl2ZVN0YXRlLmxlbmd0aCAtIDIsIDIpOyAvLyB0cmFuc2Zvcm0gaXMgdGhlIGxhc3QgcHJvcGVydHkvdmFsdWUgc2V0IGluIHRoZSBzdGF0ZSBBcnJheS4gU2luY2UgdGhlIGFuaW1hdGlvbiBpcyBjb250cm9sbGluZyB0aGF0LCB3ZSBzaG91bGQgb21pdCBpdC5cblxuICAgICAgICAgIGFuaW1hdGlvbi5yZW5kZXIoMCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgaW5pdHRlZCB8fCBhbmltYXRpb24uaW52YWxpZGF0ZSh0cnVlKTtcbiAgICAgICAgICBhbmltYXRpb24ucGFyZW50IHx8IGFuaW1hdGlvbi50b3RhbFRpbWUoYW5pbWF0aW9uLnRvdGFsVGltZSgpKTsgLy8gaWYsIGZvciBleGFtcGxlLCBhIHRvZ2dsZUFjdGlvbiBjYWxsZWQgcGxheSgpIGFuZCB0aGVuIHJlZnJlc2goKSBoYXBwZW5zIGFuZCB3aGVuIHdlIHJlbmRlcigxKSBhYm92ZSwgaXQgd291bGQgY2F1c2UgdGhlIGFuaW1hdGlvbiB0byBjb21wbGV0ZSBhbmQgZ2V0IHJlbW92ZWQgZnJvbSBpdHMgcGFyZW50LCBzbyB0aGlzIG1ha2VzIHN1cmUgaXQgZ2V0cyBwdXQgYmFjayBpbi5cblxuICAgICAgICAgIF9zdXBwcmVzc092ZXJ3cml0ZXMoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGluQ2hhbmdlID0gY2hhbmdlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yY2VkT3ZlcmZsb3cgJiYgKGZvcmNlZE92ZXJmbG93LnZhbHVlID8gZm9yY2VkT3ZlcmZsb3cuc3R5bGVbXCJvdmVyZmxvd1wiICsgZGlyZWN0aW9uLmEudG9VcHBlckNhc2UoKV0gPSBmb3JjZWRPdmVyZmxvdy52YWx1ZSA6IGZvcmNlZE92ZXJmbG93LnN0eWxlLnJlbW92ZVByb3BlcnR5KFwib3ZlcmZsb3ctXCIgKyBkaXJlY3Rpb24uYSkpO1xuICAgICAgfSBlbHNlIGlmICh0cmlnZ2VyICYmIHNjcm9sbEZ1bmMoKSAmJiAhY29udGFpbmVyQW5pbWF0aW9uKSB7XG4gICAgICAgIC8vIGl0IG1heSBiZSBJTlNJREUgYSBwaW5uZWQgZWxlbWVudCwgc28gd2FsayB1cCB0aGUgdHJlZSBhbmQgbG9vayBmb3IgYW55IGVsZW1lbnRzIHdpdGggX3Bpbk9mZnNldCB0byBjb21wZW5zYXRlIGJlY2F1c2UgYW55dGhpbmcgd2l0aCBwaW5TcGFjaW5nIHRoYXQncyBhbHJlYWR5IHNjcm9sbGVkIHdvdWxkIHRocm93IG9mZiB0aGUgbWVhc3VyZW1lbnRzIGluIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIGJvdW5kcyA9IHRyaWdnZXIucGFyZW50Tm9kZTtcblxuICAgICAgICB3aGlsZSAoYm91bmRzICYmIGJvdW5kcyAhPT0gX2JvZHkpIHtcbiAgICAgICAgICBpZiAoYm91bmRzLl9waW5PZmZzZXQpIHtcbiAgICAgICAgICAgIHN0YXJ0IC09IGJvdW5kcy5fcGluT2Zmc2V0O1xuICAgICAgICAgICAgZW5kIC09IGJvdW5kcy5fcGluT2Zmc2V0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJvdW5kcyA9IGJvdW5kcy5wYXJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldmVydGVkUGlucyAmJiByZXZlcnRlZFBpbnMuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdC5yZXZlcnQoZmFsc2UsIHRydWUpO1xuICAgICAgfSk7XG4gICAgICBzZWxmLnN0YXJ0ID0gc3RhcnQ7XG4gICAgICBzZWxmLmVuZCA9IGVuZDtcbiAgICAgIHNjcm9sbDEgPSBzY3JvbGwyID0gX3JlZnJlc2hpbmdBbGwgPyBwcmV2U2Nyb2xsIDogc2Nyb2xsRnVuYygpOyAvLyByZXNldCB2ZWxvY2l0eVxuXG4gICAgICBpZiAoIWNvbnRhaW5lckFuaW1hdGlvbiAmJiAhX3JlZnJlc2hpbmdBbGwpIHtcbiAgICAgICAgc2Nyb2xsMSA8IHByZXZTY3JvbGwgJiYgc2Nyb2xsRnVuYyhwcmV2U2Nyb2xsKTtcbiAgICAgICAgc2VsZi5zY3JvbGwucmVjID0gMDtcbiAgICAgIH1cblxuICAgICAgc2VsZi5yZXZlcnQoZmFsc2UsIHRydWUpO1xuXG4gICAgICBpZiAoc25hcERlbGF5ZWRDYWxsKSB7XG4gICAgICAgIGxhc3RTbmFwID0gLTE7XG4gICAgICAgIHNlbGYuaXNBY3RpdmUgJiYgc2Nyb2xsRnVuYyhzdGFydCArIGNoYW5nZSAqIHByZXZQcm9ncmVzcyk7IC8vIGp1c3Qgc28gc25hcHBpbmcgZ2V0cyByZS1lbmFibGVkLCBjbGVhciBvdXQgYW55IHJlY29yZGVkIGxhc3QgdmFsdWVcblxuICAgICAgICBzbmFwRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICAgIH1cblxuICAgICAgX3JlZnJlc2hpbmcgPSAwO1xuICAgICAgYW5pbWF0aW9uICYmIGlzVG9nZ2xlICYmIChhbmltYXRpb24uX2luaXR0ZWQgfHwgcHJldkFuaW1Qcm9ncmVzcykgJiYgYW5pbWF0aW9uLnByb2dyZXNzKCkgIT09IHByZXZBbmltUHJvZ3Jlc3MgJiYgYW5pbWF0aW9uLnByb2dyZXNzKHByZXZBbmltUHJvZ3Jlc3MsIHRydWUpLnJlbmRlcihhbmltYXRpb24udGltZSgpLCB0cnVlLCB0cnVlKTsgLy8gbXVzdCBmb3JjZSBhIHJlLXJlbmRlciBiZWNhdXNlIGlmIHNhdmVTdHlsZXMoKSB3YXMgdXNlZCBvbiB0aGUgdGFyZ2V0KHMpLCB0aGUgc3R5bGVzIGNvdWxkIGhhdmUgYmVlbiB3aXBlZCBvdXQgZHVyaW5nIHRoZSByZWZyZXNoKCkuXG5cbiAgICAgIGlmIChpc0ZpcnN0UmVmcmVzaCB8fCBwcmV2UHJvZ3Jlc3MgIT09IHNlbGYucHJvZ3Jlc3MgfHwgY29udGFpbmVyQW5pbWF0aW9uKSB7XG4gICAgICAgIC8vIGVuc3VyZXMgdGhhdCB0aGUgZGlyZWN0aW9uIGlzIHNldCBwcm9wZXJseSAod2hlbiByZWZyZXNoaW5nLCBwcm9ncmVzcyBpcyBzZXQgYmFjayB0byAwIGluaXRpYWxseSwgdGhlbiBiYWNrIGFnYWluIHRvIHdoZXJldmVyIGl0IG5lZWRzIHRvIGJlKSBhbmQgdGhhdCBjYWxsYmFja3MgYXJlIHRyaWdnZXJlZC5cbiAgICAgICAgYW5pbWF0aW9uICYmICFpc1RvZ2dsZSAmJiBhbmltYXRpb24udG90YWxQcm9ncmVzcyhjb250YWluZXJBbmltYXRpb24gJiYgc3RhcnQgPCAtMC4wMDEgJiYgIXByZXZQcm9ncmVzcyA/IGdzYXAudXRpbHMubm9ybWFsaXplKHN0YXJ0LCBlbmQsIDApIDogcHJldlByb2dyZXNzLCB0cnVlKTsgLy8gdG8gYXZvaWQgaXNzdWVzIHdoZXJlIGFuaW1hdGlvbiBjYWxsYmFja3MgbGlrZSBvblN0YXJ0IGFyZW4ndCB0cmlnZ2VyZWQuXG5cbiAgICAgICAgc2VsZi5wcm9ncmVzcyA9IChzY3JvbGwxIC0gc3RhcnQpIC8gY2hhbmdlID09PSBwcmV2UHJvZ3Jlc3MgPyAwIDogcHJldlByb2dyZXNzO1xuICAgICAgfVxuXG4gICAgICBwaW4gJiYgcGluU3BhY2luZyAmJiAoc3BhY2VyLl9waW5PZmZzZXQgPSBNYXRoLnJvdW5kKHNlbGYucHJvZ3Jlc3MgKiBwaW5DaGFuZ2UpKTtcbiAgICAgIHNjcnViVHdlZW4gJiYgc2NydWJUd2Vlbi5pbnZhbGlkYXRlKCk7XG4gICAgICBvblJlZnJlc2ggJiYgIV9yZWZyZXNoaW5nQWxsICYmIG9uUmVmcmVzaChzZWxmKTsgLy8gd2hlbiByZWZyZXNoaW5nIGFsbCwgd2UgZG8gZXh0cmEgd29yayB0byBjb3JyZWN0IHBpbm5lZENvbnRhaW5lciBzaXplcyBhbmQgZW5zdXJlIHRoaW5ncyBkb24ndCBleGNlZWQgdGhlIG1heFNjcm9sbCwgc28gd2Ugc2hvdWxkIGRvIGFsbCB0aGUgcmVmcmVzaGVzIGF0IHRoZSBlbmQgYWZ0ZXIgYWxsIHRoYXQgd29yayBzbyB0aGF0IHRoZSBzdGFydC9lbmQgdmFsdWVzIGFyZSBjb3JyZWN0ZWQuXG4gICAgfTtcblxuICAgIHNlbGYuZ2V0VmVsb2NpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gKHNjcm9sbEZ1bmMoKSAtIHNjcm9sbDIpIC8gKF9nZXRUaW1lKCkgLSBfdGltZTIpICogMTAwMCB8fCAwO1xuICAgIH07XG5cbiAgICBzZWxmLmVuZEFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIF9lbmRBbmltYXRpb24oc2VsZi5jYWxsYmFja0FuaW1hdGlvbik7XG5cbiAgICAgIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgc2NydWJUd2VlbiA/IHNjcnViVHdlZW4ucHJvZ3Jlc3MoMSkgOiAhYW5pbWF0aW9uLnBhdXNlZCgpID8gX2VuZEFuaW1hdGlvbihhbmltYXRpb24sIGFuaW1hdGlvbi5yZXZlcnNlZCgpKSA6IGlzVG9nZ2xlIHx8IF9lbmRBbmltYXRpb24oYW5pbWF0aW9uLCBzZWxmLmRpcmVjdGlvbiA8IDAsIDEpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmLmxhYmVsVG9TY3JvbGwgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgIHJldHVybiBhbmltYXRpb24gJiYgYW5pbWF0aW9uLmxhYmVscyAmJiAoc3RhcnQgfHwgc2VsZi5yZWZyZXNoKCkgfHwgc3RhcnQpICsgYW5pbWF0aW9uLmxhYmVsc1tsYWJlbF0gLyBhbmltYXRpb24uZHVyYXRpb24oKSAqIGNoYW5nZSB8fCAwO1xuICAgIH07XG5cbiAgICBzZWxmLmdldFRyYWlsaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBpID0gX3RyaWdnZXJzLmluZGV4T2Yoc2VsZiksXG4gICAgICAgICAgYSA9IHNlbGYuZGlyZWN0aW9uID4gMCA/IF90cmlnZ2Vycy5zbGljZSgwLCBpKS5yZXZlcnNlKCkgOiBfdHJpZ2dlcnMuc2xpY2UoaSArIDEpO1xuXG4gICAgICByZXR1cm4gKF9pc1N0cmluZyhuYW1lKSA/IGEuZmlsdGVyKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0LnZhcnMucHJldmVudE92ZXJsYXBzID09PSBuYW1lO1xuICAgICAgfSkgOiBhKS5maWx0ZXIoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZGlyZWN0aW9uID4gMCA/IHQuZW5kIDw9IHN0YXJ0IDogdC5zdGFydCA+PSBlbmQ7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc2VsZi51cGRhdGUgPSBmdW5jdGlvbiAocmVzZXQsIHJlY29yZFZlbG9jaXR5LCBmb3JjZUZha2UpIHtcbiAgICAgIGlmIChjb250YWluZXJBbmltYXRpb24gJiYgIWZvcmNlRmFrZSAmJiAhcmVzZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2Nyb2xsID0gX3JlZnJlc2hpbmdBbGwgPT09IHRydWUgPyBwcmV2U2Nyb2xsIDogc2VsZi5zY3JvbGwoKSxcbiAgICAgICAgICBwID0gcmVzZXQgPyAwIDogKHNjcm9sbCAtIHN0YXJ0KSAvIGNoYW5nZSxcbiAgICAgICAgICBjbGlwcGVkID0gcCA8IDAgPyAwIDogcCA+IDEgPyAxIDogcCB8fCAwLFxuICAgICAgICAgIHByZXZQcm9ncmVzcyA9IHNlbGYucHJvZ3Jlc3MsXG4gICAgICAgICAgaXNBY3RpdmUsXG4gICAgICAgICAgd2FzQWN0aXZlLFxuICAgICAgICAgIHRvZ2dsZVN0YXRlLFxuICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICBzdGF0ZUNoYW5nZWQsXG4gICAgICAgICAgdG9nZ2xlZCxcbiAgICAgICAgICBpc0F0TWF4LFxuICAgICAgICAgIGlzVGFraW5nQWN0aW9uO1xuXG4gICAgICBpZiAocmVjb3JkVmVsb2NpdHkpIHtcbiAgICAgICAgc2Nyb2xsMiA9IHNjcm9sbDE7XG4gICAgICAgIHNjcm9sbDEgPSBjb250YWluZXJBbmltYXRpb24gPyBzY3JvbGxGdW5jKCkgOiBzY3JvbGw7XG5cbiAgICAgICAgaWYgKHNuYXApIHtcbiAgICAgICAgICBzbmFwMiA9IHNuYXAxO1xuICAgICAgICAgIHNuYXAxID0gYW5pbWF0aW9uICYmICFpc1RvZ2dsZSA/IGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKCkgOiBjbGlwcGVkO1xuICAgICAgICB9XG4gICAgICB9IC8vIGFudGljaXBhdGUgdGhlIHBpbm5pbmcgYSBmZXcgdGlja3MgYWhlYWQgb2YgdGltZSBiYXNlZCBvbiB2ZWxvY2l0eSB0byBhdm9pZCBhIHZpc3VhbCBnbGl0Y2ggZHVlIHRvIHRoZSBmYWN0IHRoYXQgbW9zdCBicm93c2VycyBkbyBzY3JvbGxpbmcgb24gYSBzZXBhcmF0ZSB0aHJlYWQgKG5vdCBzeW5jZWQgd2l0aCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpLlxuXG5cbiAgICAgIGFudGljaXBhdGVQaW4gJiYgIWNsaXBwZWQgJiYgcGluICYmICFfcmVmcmVzaGluZyAmJiAhX3N0YXJ0dXAgJiYgX2xhc3RTY3JvbGxUaW1lICYmIHN0YXJ0IDwgc2Nyb2xsICsgKHNjcm9sbCAtIHNjcm9sbDIpIC8gKF9nZXRUaW1lKCkgLSBfdGltZTIpICogYW50aWNpcGF0ZVBpbiAmJiAoY2xpcHBlZCA9IDAuMDAwMSk7XG5cbiAgICAgIGlmIChjbGlwcGVkICE9PSBwcmV2UHJvZ3Jlc3MgJiYgc2VsZi5lbmFibGVkKSB7XG4gICAgICAgIGlzQWN0aXZlID0gc2VsZi5pc0FjdGl2ZSA9ICEhY2xpcHBlZCAmJiBjbGlwcGVkIDwgMTtcbiAgICAgICAgd2FzQWN0aXZlID0gISFwcmV2UHJvZ3Jlc3MgJiYgcHJldlByb2dyZXNzIDwgMTtcbiAgICAgICAgdG9nZ2xlZCA9IGlzQWN0aXZlICE9PSB3YXNBY3RpdmU7XG4gICAgICAgIHN0YXRlQ2hhbmdlZCA9IHRvZ2dsZWQgfHwgISFjbGlwcGVkICE9PSAhIXByZXZQcm9ncmVzczsgLy8gY291bGQgZ28gZnJvbSBzdGFydCBhbGwgdGhlIHdheSB0byBlbmQsIHRodXMgaXQgZGlkbid0IHRvZ2dsZSBidXQgaXQgZGlkIGNoYW5nZSBzdGF0ZSBpbiBhIHNlbnNlIChtYXkgbmVlZCB0byBmaXJlIGEgY2FsbGJhY2spXG5cbiAgICAgICAgc2VsZi5kaXJlY3Rpb24gPSBjbGlwcGVkID4gcHJldlByb2dyZXNzID8gMSA6IC0xO1xuICAgICAgICBzZWxmLnByb2dyZXNzID0gY2xpcHBlZDtcblxuICAgICAgICBpZiAoc3RhdGVDaGFuZ2VkICYmICFfcmVmcmVzaGluZykge1xuICAgICAgICAgIHRvZ2dsZVN0YXRlID0gY2xpcHBlZCAmJiAhcHJldlByb2dyZXNzID8gMCA6IGNsaXBwZWQgPT09IDEgPyAxIDogcHJldlByb2dyZXNzID09PSAxID8gMiA6IDM7IC8vIDAgPSBlbnRlciwgMSA9IGxlYXZlLCAyID0gZW50ZXJCYWNrLCAzID0gbGVhdmVCYWNrICh3ZSBwcmlvcml0aXplIHRoZSBGSVJTVCBlbmNvdW50ZXIsIHRodXMgaWYgeW91IHNjcm9sbCByZWFsbHkgZmFzdCBwYXN0IHRoZSBvbkVudGVyIGFuZCBvbkxlYXZlIGluIG9uZSB0aWNrLCBpdCdkIHByaW9yaXRpemUgb25FbnRlci5cblxuICAgICAgICAgIGlmIChpc1RvZ2dsZSkge1xuICAgICAgICAgICAgYWN0aW9uID0gIXRvZ2dsZWQgJiYgdG9nZ2xlQWN0aW9uc1t0b2dnbGVTdGF0ZSArIDFdICE9PSBcIm5vbmVcIiAmJiB0b2dnbGVBY3Rpb25zW3RvZ2dsZVN0YXRlICsgMV0gfHwgdG9nZ2xlQWN0aW9uc1t0b2dnbGVTdGF0ZV07IC8vIGlmIGl0IGRpZG4ndCB0b2dnbGUsIHRoYXQgbWVhbnMgaXQgc2hvdCByaWdodCBwYXN0IGFuZCBzaW5jZSB3ZSBwcmlvcml0aXplIHRoZSBcImVudGVyXCIgYWN0aW9uLCB3ZSBzaG91bGQgc3dpdGNoIHRvIHRoZSBcImxlYXZlXCIgaW4gdGhpcyBjYXNlIChidXQgb25seSBpZiBvbmUgaXMgZGVmaW5lZClcblxuICAgICAgICAgICAgaXNUYWtpbmdBY3Rpb24gPSBhbmltYXRpb24gJiYgKGFjdGlvbiA9PT0gXCJjb21wbGV0ZVwiIHx8IGFjdGlvbiA9PT0gXCJyZXNldFwiIHx8IGFjdGlvbiBpbiBhbmltYXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZlbnRPdmVybGFwcyAmJiAodG9nZ2xlZCB8fCBpc1Rha2luZ0FjdGlvbikgJiYgKGlzVGFraW5nQWN0aW9uIHx8IHNjcnViIHx8ICFhbmltYXRpb24pICYmIChfaXNGdW5jdGlvbihwcmV2ZW50T3ZlcmxhcHMpID8gcHJldmVudE92ZXJsYXBzKHNlbGYpIDogc2VsZi5nZXRUcmFpbGluZyhwcmV2ZW50T3ZlcmxhcHMpLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICByZXR1cm4gdC5lbmRBbmltYXRpb24oKTtcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGlmICghaXNUb2dnbGUpIHtcbiAgICAgICAgICBpZiAoc2NydWJUd2VlbiAmJiAhX3JlZnJlc2hpbmcgJiYgIV9zdGFydHVwKSB7XG4gICAgICAgICAgICBzY3J1YlR3ZWVuLl9kcC5fdGltZSAtIHNjcnViVHdlZW4uX3N0YXJ0ICE9PSBzY3J1YlR3ZWVuLl90aW1lICYmIHNjcnViVHdlZW4ucmVuZGVyKHNjcnViVHdlZW4uX2RwLl90aW1lIC0gc2NydWJUd2Vlbi5fc3RhcnQpOyAvLyBpZiB0aGVyZSdzIGEgc2NydWIgb24gYm90aCB0aGUgY29udGFpbmVyIGFuaW1hdGlvbiBhbmQgdGhpcyBvbmUgKG9yIGEgU2Nyb2xsU21vb3RoZXIpLCB0aGUgdXBkYXRlIG9yZGVyIHdvdWxkIGNhdXNlIHRoaXMgb25lIG5vdCB0byBoYXZlIHJlbmRlcmVkIHlldCwgc28gaXQgd291bGRuJ3QgbWFrZSBhbnkgcHJvZ3Jlc3MgYmVmb3JlIHdlIC5yZXN0YXJ0KCkgaXQgaGVhZGluZyB0b3dhcmQgdGhlIG5ldyBwcm9ncmVzcyBzbyBpdCdkIGFwcGVhciBzdHVjayB0aHVzIHdlIGZvcmNlIGEgcmVuZGVyIGhlcmUuXG5cbiAgICAgICAgICAgIGlmIChzY3J1YlR3ZWVuLnJlc2V0VG8pIHtcbiAgICAgICAgICAgICAgc2NydWJUd2Vlbi5yZXNldFRvKFwidG90YWxQcm9ncmVzc1wiLCBjbGlwcGVkLCBhbmltYXRpb24uX3RUaW1lIC8gYW5pbWF0aW9uLl90RHVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGxlZ2FjeSBzdXBwb3J0IChjb3VydGVzeSksIGJlZm9yZSAzLjEwLjBcbiAgICAgICAgICAgICAgc2NydWJUd2Vlbi52YXJzLnRvdGFsUHJvZ3Jlc3MgPSBjbGlwcGVkO1xuICAgICAgICAgICAgICBzY3J1YlR3ZWVuLmludmFsaWRhdGUoKS5yZXN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKGNsaXBwZWQsICEhX3JlZnJlc2hpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwaW4pIHtcbiAgICAgICAgICByZXNldCAmJiBwaW5TcGFjaW5nICYmIChzcGFjZXIuc3R5bGVbcGluU3BhY2luZyArIGRpcmVjdGlvbi5vczJdID0gc3BhY2luZ1N0YXJ0KTtcblxuICAgICAgICAgIGlmICghdXNlRml4ZWRQb3NpdGlvbikge1xuICAgICAgICAgICAgcGluU2V0dGVyKF9yb3VuZChwaW5TdGFydCArIHBpbkNoYW5nZSAqIGNsaXBwZWQpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHN0YXRlQ2hhbmdlZCkge1xuICAgICAgICAgICAgaXNBdE1heCA9ICFyZXNldCAmJiBjbGlwcGVkID4gcHJldlByb2dyZXNzICYmIGVuZCArIDEgPiBzY3JvbGwgJiYgc2Nyb2xsICsgMSA+PSBfbWF4U2Nyb2xsKHNjcm9sbGVyLCBkaXJlY3Rpb24pOyAvLyBpZiBpdCdzIGF0IHRoZSBWRVJZIGVuZCBvZiB0aGUgcGFnZSwgZG9uJ3Qgc3dpdGNoIGF3YXkgZnJvbSBwb3NpdGlvbjogZml4ZWQgYmVjYXVzZSBpdCdzIHBvaW50bGVzcyBhbmQgaXQgY291bGQgY2F1c2UgYSBicmllZiBmbGFzaCB3aGVuIHRoZSB1c2VyIHNjcm9sbHMgYmFjayB1cCAod2hlbiBpdCBnZXRzIHBpbm5lZCBhZ2FpbilcblxuICAgICAgICAgICAgaWYgKHBpblJlcGFyZW50KSB7XG4gICAgICAgICAgICAgIGlmICghcmVzZXQgJiYgKGlzQWN0aXZlIHx8IGlzQXRNYXgpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IF9nZXRCb3VuZHMocGluLCB0cnVlKSxcbiAgICAgICAgICAgICAgICAgICAgX29mZnNldCA9IHNjcm9sbCAtIHN0YXJ0O1xuXG4gICAgICAgICAgICAgICAgX3JlcGFyZW50KHBpbiwgX2JvZHksIGJvdW5kcy50b3AgKyAoZGlyZWN0aW9uID09PSBfdmVydGljYWwgPyBfb2Zmc2V0IDogMCkgKyBfcHgsIGJvdW5kcy5sZWZ0ICsgKGRpcmVjdGlvbiA9PT0gX3ZlcnRpY2FsID8gMCA6IF9vZmZzZXQpICsgX3B4KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBfcmVwYXJlbnQocGluLCBzcGFjZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIF9zZXRTdGF0ZShpc0FjdGl2ZSB8fCBpc0F0TWF4ID8gcGluQWN0aXZlU3RhdGUgOiBwaW5TdGF0ZSk7XG5cbiAgICAgICAgICAgIHBpbk1vdmVzICYmIGNsaXBwZWQgPCAxICYmIGlzQWN0aXZlIHx8IHBpblNldHRlcihwaW5TdGFydCArIChjbGlwcGVkID09PSAxICYmICFpc0F0TWF4ID8gcGluQ2hhbmdlIDogMCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNuYXAgJiYgIXR3ZWVuVG8udHdlZW4gJiYgIV9yZWZyZXNoaW5nICYmICFfc3RhcnR1cCAmJiBzbmFwRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICAgICAgdG9nZ2xlQ2xhc3MgJiYgKHRvZ2dsZWQgfHwgb25jZSAmJiBjbGlwcGVkICYmIChjbGlwcGVkIDwgMSB8fCAhX2xpbWl0Q2FsbGJhY2tzKSkgJiYgX3RvQXJyYXkodG9nZ2xlQ2xhc3MudGFyZ2V0cykuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICByZXR1cm4gZWwuY2xhc3NMaXN0W2lzQWN0aXZlIHx8IG9uY2UgPyBcImFkZFwiIDogXCJyZW1vdmVcIl0odG9nZ2xlQ2xhc3MuY2xhc3NOYW1lKTtcbiAgICAgICAgfSk7IC8vIGNsYXNzZXMgY291bGQgYWZmZWN0IHBvc2l0aW9uaW5nLCBzbyBkbyBpdCBldmVuIGlmIHJlc2V0IG9yIHJlZnJlc2hpbmcgaXMgdHJ1ZS5cblxuICAgICAgICBvblVwZGF0ZSAmJiAhaXNUb2dnbGUgJiYgIXJlc2V0ICYmIG9uVXBkYXRlKHNlbGYpO1xuXG4gICAgICAgIGlmIChzdGF0ZUNoYW5nZWQgJiYgIV9yZWZyZXNoaW5nKSB7XG4gICAgICAgICAgaWYgKGlzVG9nZ2xlKSB7XG4gICAgICAgICAgICBpZiAoaXNUYWtpbmdBY3Rpb24pIHtcbiAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gXCJjb21wbGV0ZVwiKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uLnBhdXNlKCkudG90YWxQcm9ncmVzcygxKTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT09IFwicmVzZXRcIikge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5yZXN0YXJ0KHRydWUpLnBhdXNlKCk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uID09PSBcInJlc3RhcnRcIikge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5yZXN0YXJ0KHRydWUpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvblthY3Rpb25dKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgb25VcGRhdGUgJiYgb25VcGRhdGUoc2VsZik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRvZ2dsZWQgfHwgIV9saW1pdENhbGxiYWNrcykge1xuICAgICAgICAgICAgLy8gb24gc3RhcnR1cCwgdGhlIHBhZ2UgY291bGQgYmUgc2Nyb2xsZWQgYW5kIHdlIGRvbid0IHdhbnQgdG8gZmlyZSBjYWxsYmFja3MgdGhhdCBkaWRuJ3QgdG9nZ2xlLiBGb3IgZXhhbXBsZSBvbkVudGVyIHNob3VsZG4ndCBmaXJlIGlmIHRoZSBTY3JvbGxUcmlnZ2VyIGlzbid0IGFjdHVhbGx5IGVudGVyZWQuXG4gICAgICAgICAgICBvblRvZ2dsZSAmJiB0b2dnbGVkICYmIF9jYWxsYmFjayhzZWxmLCBvblRvZ2dsZSk7XG4gICAgICAgICAgICBjYWxsYmFja3NbdG9nZ2xlU3RhdGVdICYmIF9jYWxsYmFjayhzZWxmLCBjYWxsYmFja3NbdG9nZ2xlU3RhdGVdKTtcbiAgICAgICAgICAgIG9uY2UgJiYgKGNsaXBwZWQgPT09IDEgPyBzZWxmLmtpbGwoZmFsc2UsIDEpIDogY2FsbGJhY2tzW3RvZ2dsZVN0YXRlXSA9IDApOyAvLyBhIGNhbGxiYWNrIHNob3VsZG4ndCBiZSBjYWxsZWQgYWdhaW4gaWYgb25jZSBpcyB0cnVlLlxuXG4gICAgICAgICAgICBpZiAoIXRvZ2dsZWQpIHtcbiAgICAgICAgICAgICAgLy8gaXQncyBwb3NzaWJsZSB0byBnbyBjb21wbGV0ZWx5IHBhc3QsIGxpa2UgZnJvbSBiZWZvcmUgdGhlIHN0YXJ0IHRvIGFmdGVyIHRoZSBlbmQgKG9yIHZpY2UtdmVyc2EpIGluIHdoaWNoIGNhc2UgQk9USCBjYWxsYmFja3Mgc2hvdWxkIGJlIGZpcmVkIGluIHRoYXQgb3JkZXJcbiAgICAgICAgICAgICAgdG9nZ2xlU3RhdGUgPSBjbGlwcGVkID09PSAxID8gMSA6IDM7XG4gICAgICAgICAgICAgIGNhbGxiYWNrc1t0b2dnbGVTdGF0ZV0gJiYgX2NhbGxiYWNrKHNlbGYsIGNhbGxiYWNrc1t0b2dnbGVTdGF0ZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmYXN0U2Nyb2xsRW5kICYmICFpc0FjdGl2ZSAmJiBNYXRoLmFicyhzZWxmLmdldFZlbG9jaXR5KCkpID4gKF9pc051bWJlcihmYXN0U2Nyb2xsRW5kKSA/IGZhc3RTY3JvbGxFbmQgOiAyNTAwKSkge1xuICAgICAgICAgICAgX2VuZEFuaW1hdGlvbihzZWxmLmNhbGxiYWNrQW5pbWF0aW9uKTtcblxuICAgICAgICAgICAgc2NydWJUd2VlbiA/IHNjcnViVHdlZW4ucHJvZ3Jlc3MoMSkgOiBfZW5kQW5pbWF0aW9uKGFuaW1hdGlvbiwgYWN0aW9uID09PSBcInJldmVyc2VcIiA/IDEgOiAhY2xpcHBlZCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGlzVG9nZ2xlICYmIG9uVXBkYXRlICYmICFfcmVmcmVzaGluZykge1xuICAgICAgICAgIG9uVXBkYXRlKHNlbGYpO1xuICAgICAgICB9XG4gICAgICB9IC8vIHVwZGF0ZSBhYnNvbHV0ZWx5LXBvc2l0aW9uZWQgbWFya2VycyAob25seSBpZiB0aGUgc2Nyb2xsZXIgaXNuJ3QgdGhlIHZpZXdwb3J0KVxuXG5cbiAgICAgIGlmIChtYXJrZXJFbmRTZXR0ZXIpIHtcbiAgICAgICAgdmFyIG4gPSBjb250YWluZXJBbmltYXRpb24gPyBzY3JvbGwgLyBjb250YWluZXJBbmltYXRpb24uZHVyYXRpb24oKSAqIChjb250YWluZXJBbmltYXRpb24uX2NhU2Nyb2xsRGlzdCB8fCAwKSA6IHNjcm9sbDtcbiAgICAgICAgbWFya2VyU3RhcnRTZXR0ZXIobiArIChtYXJrZXJTdGFydFRyaWdnZXIuX2lzRmxpcHBlZCA/IDEgOiAwKSk7XG4gICAgICAgIG1hcmtlckVuZFNldHRlcihuKTtcbiAgICAgIH1cblxuICAgICAgY2FNYXJrZXJTZXR0ZXIgJiYgY2FNYXJrZXJTZXR0ZXIoLXNjcm9sbCAvIGNvbnRhaW5lckFuaW1hdGlvbi5kdXJhdGlvbigpICogKGNvbnRhaW5lckFuaW1hdGlvbi5fY2FTY3JvbGxEaXN0IHx8IDApKTtcbiAgICB9O1xuXG4gICAgc2VsZi5lbmFibGUgPSBmdW5jdGlvbiAocmVzZXQsIHJlZnJlc2gpIHtcbiAgICAgIGlmICghc2VsZi5lbmFibGVkKSB7XG4gICAgICAgIHNlbGYuZW5hYmxlZCA9IHRydWU7XG5cbiAgICAgICAgX2FkZExpc3RlbmVyKHNjcm9sbGVyLCBcInJlc2l6ZVwiLCBfb25SZXNpemUpO1xuXG4gICAgICAgIF9hZGRMaXN0ZW5lcihpc1ZpZXdwb3J0ID8gX2RvYyA6IHNjcm9sbGVyLCBcInNjcm9sbFwiLCBfb25TY3JvbGwpO1xuXG4gICAgICAgIG9uUmVmcmVzaEluaXQgJiYgX2FkZExpc3RlbmVyKFNjcm9sbFRyaWdnZXIsIFwicmVmcmVzaEluaXRcIiwgb25SZWZyZXNoSW5pdCk7XG5cbiAgICAgICAgaWYgKHJlc2V0ICE9PSBmYWxzZSkge1xuICAgICAgICAgIHNlbGYucHJvZ3Jlc3MgPSBwcmV2UHJvZ3Jlc3MgPSAwO1xuICAgICAgICAgIHNjcm9sbDEgPSBzY3JvbGwyID0gbGFzdFNuYXAgPSBzY3JvbGxGdW5jKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZWZyZXNoICE9PSBmYWxzZSAmJiBzZWxmLnJlZnJlc2goKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc2VsZi5nZXRUd2VlbiA9IGZ1bmN0aW9uIChzbmFwKSB7XG4gICAgICByZXR1cm4gc25hcCAmJiB0d2VlblRvID8gdHdlZW5Uby50d2VlbiA6IHNjcnViVHdlZW47XG4gICAgfTtcblxuICAgIHNlbGYuc2V0UG9zaXRpb25zID0gZnVuY3Rpb24gKG5ld1N0YXJ0LCBuZXdFbmQpIHtcbiAgICAgIC8vIGRvZXNuJ3QgcGVyc2lzdCBhZnRlciByZWZyZXNoKCkhIEludGVuZGVkIHRvIGJlIGEgd2F5IHRvIG92ZXJyaWRlIHZhbHVlcyB0aGF0IHdlcmUgc2V0IGR1cmluZyByZWZyZXNoKCksIGxpa2UgeW91IGNvdWxkIHNldCBpdCBpbiBvblJlZnJlc2goKVxuICAgICAgaWYgKHBpbikge1xuICAgICAgICBwaW5TdGFydCArPSBuZXdTdGFydCAtIHN0YXJ0O1xuICAgICAgICBwaW5DaGFuZ2UgKz0gbmV3RW5kIC0gbmV3U3RhcnQgLSBjaGFuZ2U7XG4gICAgICAgIHBpblNwYWNpbmcgPT09IF9wYWRkaW5nICYmIHNlbGYuYWRqdXN0UGluU3BhY2luZyhuZXdFbmQgLSBuZXdTdGFydCAtIGNoYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIHNlbGYuc3RhcnQgPSBzdGFydCA9IG5ld1N0YXJ0O1xuICAgICAgc2VsZi5lbmQgPSBlbmQgPSBuZXdFbmQ7XG4gICAgICBjaGFuZ2UgPSBuZXdFbmQgLSBuZXdTdGFydDtcbiAgICAgIHNlbGYudXBkYXRlKCk7XG4gICAgfTtcblxuICAgIHNlbGYuYWRqdXN0UGluU3BhY2luZyA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICAgIGlmIChzcGFjZXJTdGF0ZSAmJiBhbW91bnQpIHtcbiAgICAgICAgdmFyIGkgPSBzcGFjZXJTdGF0ZS5pbmRleE9mKGRpcmVjdGlvbi5kKSArIDE7XG4gICAgICAgIHNwYWNlclN0YXRlW2ldID0gcGFyc2VGbG9hdChzcGFjZXJTdGF0ZVtpXSkgKyBhbW91bnQgKyBfcHg7XG4gICAgICAgIHNwYWNlclN0YXRlWzFdID0gcGFyc2VGbG9hdChzcGFjZXJTdGF0ZVsxXSkgKyBhbW91bnQgKyBfcHg7XG5cbiAgICAgICAgX3NldFN0YXRlKHNwYWNlclN0YXRlKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc2VsZi5kaXNhYmxlID0gZnVuY3Rpb24gKHJlc2V0LCBhbGxvd0FuaW1hdGlvbikge1xuICAgICAgaWYgKHNlbGYuZW5hYmxlZCkge1xuICAgICAgICByZXNldCAhPT0gZmFsc2UgJiYgc2VsZi5yZXZlcnQodHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIHNlbGYuZW5hYmxlZCA9IHNlbGYuaXNBY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgYWxsb3dBbmltYXRpb24gfHwgc2NydWJUd2VlbiAmJiBzY3J1YlR3ZWVuLnBhdXNlKCk7XG4gICAgICAgIHByZXZTY3JvbGwgPSAwO1xuICAgICAgICBwaW5DYWNoZSAmJiAocGluQ2FjaGUudW5jYWNoZSA9IDEpO1xuICAgICAgICBvblJlZnJlc2hJbml0ICYmIF9yZW1vdmVMaXN0ZW5lcihTY3JvbGxUcmlnZ2VyLCBcInJlZnJlc2hJbml0XCIsIG9uUmVmcmVzaEluaXQpO1xuXG4gICAgICAgIGlmIChzbmFwRGVsYXllZENhbGwpIHtcbiAgICAgICAgICBzbmFwRGVsYXllZENhbGwucGF1c2UoKTtcbiAgICAgICAgICB0d2VlblRvLnR3ZWVuICYmIHR3ZWVuVG8udHdlZW4ua2lsbCgpICYmICh0d2VlblRvLnR3ZWVuID0gMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzVmlld3BvcnQpIHtcbiAgICAgICAgICB2YXIgaSA9IF90cmlnZ2Vycy5sZW5ndGg7XG5cbiAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAoX3RyaWdnZXJzW2ldLnNjcm9sbGVyID09PSBzY3JvbGxlciAmJiBfdHJpZ2dlcnNbaV0gIT09IHNlbGYpIHtcbiAgICAgICAgICAgICAgcmV0dXJuOyAvL2Rvbid0IHJlbW92ZSB0aGUgbGlzdGVuZXJzIGlmIHRoZXJlIGFyZSBzdGlsbCBvdGhlciB0cmlnZ2VycyByZWZlcmVuY2luZyBpdC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfcmVtb3ZlTGlzdGVuZXIoc2Nyb2xsZXIsIFwicmVzaXplXCIsIF9vblJlc2l6ZSk7XG5cbiAgICAgICAgICBfcmVtb3ZlTGlzdGVuZXIoc2Nyb2xsZXIsIFwic2Nyb2xsXCIsIF9vblNjcm9sbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc2VsZi5raWxsID0gZnVuY3Rpb24gKHJldmVydCwgYWxsb3dBbmltYXRpb24pIHtcbiAgICAgIHNlbGYuZGlzYWJsZShyZXZlcnQsIGFsbG93QW5pbWF0aW9uKTtcbiAgICAgIHNjcnViVHdlZW4gJiYgIWFsbG93QW5pbWF0aW9uICYmIHNjcnViVHdlZW4ua2lsbCgpO1xuICAgICAgaWQgJiYgZGVsZXRlIF9pZHNbaWRdO1xuXG4gICAgICB2YXIgaSA9IF90cmlnZ2Vycy5pbmRleE9mKHNlbGYpO1xuXG4gICAgICBpID49IDAgJiYgX3RyaWdnZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIGkgPT09IF9pICYmIF9kaXJlY3Rpb24gPiAwICYmIF9pLS07IC8vIGlmIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSByZWZyZXNoKCkgb3IgdXBkYXRlKCksIHNwbGljaW5nIHdvdWxkIGNhdXNlIHNraXBzIGluIHRoZSBpbmRleCwgc28gYWRqdXN0Li4uXG4gICAgICAvLyBpZiBubyBvdGhlciBTY3JvbGxUcmlnZ2VyIGluc3RhbmNlcyBvZiB0aGUgc2FtZSBzY3JvbGxlciBhcmUgZm91bmQsIHdpcGUgb3V0IGFueSByZWNvcmRlZCBzY3JvbGwgcG9zaXRpb24uIE90aGVyd2lzZSwgaW4gYSBzaW5nbGUgcGFnZSBhcHBsaWNhdGlvbiwgZm9yIGV4YW1wbGUsIGl0IGNvdWxkIG1haW50YWluIHNjcm9sbCBwb3NpdGlvbiB3aGVuIGl0IHJlYWxseSBzaG91bGRuJ3QuXG5cbiAgICAgIGkgPSAwO1xuXG4gICAgICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdC5zY3JvbGxlciA9PT0gc2VsZi5zY3JvbGxlciAmJiAoaSA9IDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGkgfHwgX3JlZnJlc2hpbmdBbGwgfHwgKHNlbGYuc2Nyb2xsLnJlYyA9IDApO1xuXG4gICAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICAgIGFuaW1hdGlvbi5zY3JvbGxUcmlnZ2VyID0gbnVsbDtcbiAgICAgICAgcmV2ZXJ0ICYmIGFuaW1hdGlvbi5yZXZlcnQoe1xuICAgICAgICAgIGtpbGw6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBhbGxvd0FuaW1hdGlvbiB8fCBhbmltYXRpb24ua2lsbCgpO1xuICAgICAgfVxuXG4gICAgICBtYXJrZXJTdGFydCAmJiBbbWFya2VyU3RhcnQsIG1hcmtlckVuZCwgbWFya2VyU3RhcnRUcmlnZ2VyLCBtYXJrZXJFbmRUcmlnZ2VyXS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIHJldHVybiBtLnBhcmVudE5vZGUgJiYgbS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG0pO1xuICAgICAgfSk7XG4gICAgICBfcHJpbWFyeSA9PT0gc2VsZiAmJiAoX3ByaW1hcnkgPSAwKTtcblxuICAgICAgaWYgKHBpbikge1xuICAgICAgICBwaW5DYWNoZSAmJiAocGluQ2FjaGUudW5jYWNoZSA9IDEpO1xuICAgICAgICBpID0gMDtcblxuICAgICAgICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgICAgICAgIHJldHVybiB0LnBpbiA9PT0gcGluICYmIGkrKztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaSB8fCAocGluQ2FjaGUuc3BhY2VyID0gMCk7IC8vIGlmIHRoZXJlIGFyZW4ndCBhbnkgbW9yZSBTY3JvbGxUcmlnZ2VycyB3aXRoIHRoZSBzYW1lIHBpbiwgcmVtb3ZlIHRoZSBzcGFjZXIsIG90aGVyd2lzZSBpdCBjb3VsZCBiZSBjb250YW1pbmF0ZWQgd2l0aCBvbGQvc3RhbGUgdmFsdWVzIGlmIHRoZSB1c2VyIHJlLWNyZWF0ZXMgYSBTY3JvbGxUcmlnZ2VyIGZvciB0aGUgc2FtZSBlbGVtZW50LlxuICAgICAgfVxuXG4gICAgICB2YXJzLm9uS2lsbCAmJiB2YXJzLm9uS2lsbChzZWxmKTtcbiAgICB9O1xuXG4gICAgc2VsZi5lbmFibGUoZmFsc2UsIGZhbHNlKTtcbiAgICBjdXN0b21SZXZlcnRSZXR1cm4gJiYgY3VzdG9tUmV2ZXJ0UmV0dXJuKHNlbGYpO1xuICAgICFhbmltYXRpb24gfHwgIWFuaW1hdGlvbi5hZGQgfHwgY2hhbmdlID8gc2VsZi5yZWZyZXNoKCkgOiBnc2FwLmRlbGF5ZWRDYWxsKDAuMDEsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBzdGFydCB8fCBlbmQgfHwgc2VsZi5yZWZyZXNoKCk7XG4gICAgfSkgJiYgKGNoYW5nZSA9IDAuMDEpICYmIChzdGFydCA9IGVuZCA9IDApOyAvLyBpZiB0aGUgYW5pbWF0aW9uIGlzIGEgdGltZWxpbmUsIGl0IG1heSBub3QgaGF2ZSBiZWVuIHBvcHVsYXRlZCB5ZXQsIHNvIGl0IHdvdWxkbid0IHJlbmRlciBhdCB0aGUgcHJvcGVyIHBsYWNlIG9uIHRoZSBmaXJzdCByZWZyZXNoKCksIHRodXMgd2Ugc2hvdWxkIHNjaGVkdWxlIG9uZSBmb3IgdGhlIG5leHQgdGljay4gSWYgXCJjaGFuZ2VcIiBpcyBkZWZpbmVkLCB3ZSBrbm93IGl0IG11c3QgYmUgcmUtZW5hYmxpbmcsIHRodXMgd2UgY2FuIHJlZnJlc2goKSByaWdodCBhd2F5LlxuXG4gICAgcGluICYmIF9xdWV1ZVJlZnJlc2hBbGwoKTsgLy8gcGlubmluZyBjb3VsZCBhZmZlY3QgdGhlIHBvc2l0aW9ucyBvZiBvdGhlciB0aGluZ3MsIHNvIG1ha2Ugc3VyZSB3ZSBxdWV1ZSBhIGZ1bGwgcmVmcmVzaCgpXG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5yZWdpc3RlciA9IGZ1bmN0aW9uIHJlZ2lzdGVyKGNvcmUpIHtcbiAgICBpZiAoIV9jb3JlSW5pdHRlZCkge1xuICAgICAgZ3NhcCA9IGNvcmUgfHwgX2dldEdTQVAoKTtcbiAgICAgIF93aW5kb3dFeGlzdHMoKSAmJiB3aW5kb3cuZG9jdW1lbnQgJiYgU2Nyb2xsVHJpZ2dlci5lbmFibGUoKTtcbiAgICAgIF9jb3JlSW5pdHRlZCA9IF9lbmFibGVkO1xuICAgIH1cblxuICAgIHJldHVybiBfY29yZUluaXR0ZWQ7XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5kZWZhdWx0cyA9IGZ1bmN0aW9uIGRlZmF1bHRzKGNvbmZpZykge1xuICAgIGlmIChjb25maWcpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gY29uZmlnKSB7XG4gICAgICAgIF9kZWZhdWx0c1twXSA9IGNvbmZpZ1twXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX2RlZmF1bHRzO1xuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuZGlzYWJsZSA9IGZ1bmN0aW9uIGRpc2FibGUocmVzZXQsIGtpbGwpIHtcbiAgICBfZW5hYmxlZCA9IDA7XG5cbiAgICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodHJpZ2dlcikge1xuICAgICAgcmV0dXJuIHRyaWdnZXJba2lsbCA/IFwia2lsbFwiIDogXCJkaXNhYmxlXCJdKHJlc2V0KTtcbiAgICB9KTtcblxuICAgIF9yZW1vdmVMaXN0ZW5lcihfd2luLCBcIndoZWVsXCIsIF9vblNjcm9sbCk7XG5cbiAgICBfcmVtb3ZlTGlzdGVuZXIoX2RvYywgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTtcblxuICAgIGNsZWFySW50ZXJ2YWwoX3N5bmNJbnRlcnZhbCk7XG5cbiAgICBfcmVtb3ZlTGlzdGVuZXIoX2RvYywgXCJ0b3VjaGNhbmNlbFwiLCBfcGFzc1Rocm91Z2gpO1xuXG4gICAgX3JlbW92ZUxpc3RlbmVyKF9ib2R5LCBcInRvdWNoc3RhcnRcIiwgX3Bhc3NUaHJvdWdoKTtcblxuICAgIF9tdWx0aUxpc3RlbmVyKF9yZW1vdmVMaXN0ZW5lciwgX2RvYywgXCJwb2ludGVyZG93bix0b3VjaHN0YXJ0LG1vdXNlZG93blwiLCBfcG9pbnRlckRvd25IYW5kbGVyKTtcblxuICAgIF9tdWx0aUxpc3RlbmVyKF9yZW1vdmVMaXN0ZW5lciwgX2RvYywgXCJwb2ludGVydXAsdG91Y2hlbmQsbW91c2V1cFwiLCBfcG9pbnRlclVwSGFuZGxlcik7XG5cbiAgICBfcmVzaXplRGVsYXkua2lsbCgpO1xuXG4gICAgX2l0ZXJhdGVBdXRvUmVmcmVzaChfcmVtb3ZlTGlzdGVuZXIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfc2Nyb2xsZXJzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICBfd2hlZWxMaXN0ZW5lcihfcmVtb3ZlTGlzdGVuZXIsIF9zY3JvbGxlcnNbaV0sIF9zY3JvbGxlcnNbaSArIDFdKTtcblxuICAgICAgX3doZWVsTGlzdGVuZXIoX3JlbW92ZUxpc3RlbmVyLCBfc2Nyb2xsZXJzW2ldLCBfc2Nyb2xsZXJzW2kgKyAyXSk7XG4gICAgfVxuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuZW5hYmxlID0gZnVuY3Rpb24gZW5hYmxlKCkge1xuICAgIF93aW4gPSB3aW5kb3c7XG4gICAgX2RvYyA9IGRvY3VtZW50O1xuICAgIF9kb2NFbCA9IF9kb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgIF9ib2R5ID0gX2RvYy5ib2R5O1xuXG4gICAgaWYgKGdzYXApIHtcbiAgICAgIF90b0FycmF5ID0gZ3NhcC51dGlscy50b0FycmF5O1xuICAgICAgX2NsYW1wID0gZ3NhcC51dGlscy5jbGFtcDtcbiAgICAgIF9jb250ZXh0ID0gZ3NhcC5jb3JlLmNvbnRleHQgfHwgX3Bhc3NUaHJvdWdoO1xuICAgICAgX3N1cHByZXNzT3ZlcndyaXRlcyA9IGdzYXAuY29yZS5zdXBwcmVzc092ZXJ3cml0ZXMgfHwgX3Bhc3NUaHJvdWdoO1xuICAgICAgX3Njcm9sbFJlc3RvcmF0aW9uID0gX3dpbi5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uIHx8IFwiYXV0b1wiO1xuICAgICAgX2xhc3RTY3JvbGwgPSBfd2luLnBhZ2VZT2Zmc2V0O1xuICAgICAgZ3NhcC5jb3JlLmdsb2JhbHMoXCJTY3JvbGxUcmlnZ2VyXCIsIFNjcm9sbFRyaWdnZXIpOyAvLyBtdXN0IHJlZ2lzdGVyIHRoZSBnbG9iYWwgbWFudWFsbHkgYmVjYXVzZSBpbiBJbnRlcm5ldCBFeHBsb3JlciwgZnVuY3Rpb25zIChjbGFzc2VzKSBkb24ndCBoYXZlIGEgXCJuYW1lXCIgcHJvcGVydHkuXG5cbiAgICAgIGlmIChfYm9keSkge1xuICAgICAgICBfZW5hYmxlZCA9IDE7XG5cbiAgICAgICAgX3JhZkJ1Z0ZpeCgpO1xuXG4gICAgICAgIE9ic2VydmVyLnJlZ2lzdGVyKGdzYXApOyAvLyBpc1RvdWNoIGlzIDAgaWYgbm8gdG91Y2gsIDEgaWYgT05MWSB0b3VjaCwgYW5kIDIgaWYgaXQgY2FuIGFjY29tbW9kYXRlIHRvdWNoIGJ1dCBhbHNvIG90aGVyIHR5cGVzIGxpa2UgbW91c2UvcG9pbnRlci5cblxuICAgICAgICBTY3JvbGxUcmlnZ2VyLmlzVG91Y2ggPSBPYnNlcnZlci5pc1RvdWNoO1xuICAgICAgICBfZml4SU9TQnVnID0gT2JzZXJ2ZXIuaXNUb3VjaCAmJiAvKGlQYWR8aVBob25lfGlQb2R8TWFjKS9nLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7IC8vIHNpbmNlIDIwMTcsIGlPUyBoYXMgaGFkIGEgYnVnIHRoYXQgY2F1c2VzIGV2ZW50LmNsaWVudFgvWSB0byBiZSBpbmFjY3VyYXRlIHdoZW4gYSBzY3JvbGwgb2NjdXJzLCB0aHVzIHdlIG11c3QgYWx0ZXJuYXRlIGlnbm9yaW5nIGV2ZXJ5IG90aGVyIHRvdWNobW92ZSBldmVudCB0byB3b3JrIGFyb3VuZCBpdC4gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODE5NTQgYW5kIGh0dHBzOi8vY29kZXBlbi5pby9HcmVlblNvY2svcGVuL0V4YnJQTmEvMDg3Y2VmMTk3ZGMzNTQ0NWEwOTUxZTg5MzVjNDE1MDNcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX3dpbiwgXCJ3aGVlbFwiLCBfb25TY3JvbGwpOyAvLyBtb3N0bHkgZm9yIDNyZCBwYXJ0eSBzbW9vdGggc2Nyb2xsaW5nIGxpYnJhcmllcy5cblxuXG4gICAgICAgIF9yb290ID0gW193aW4sIF9kb2MsIF9kb2NFbCwgX2JvZHldO1xuXG4gICAgICAgIGlmIChnc2FwLm1hdGNoTWVkaWEpIHtcbiAgICAgICAgICBTY3JvbGxUcmlnZ2VyLm1hdGNoTWVkaWEgPSBmdW5jdGlvbiAodmFycykge1xuICAgICAgICAgICAgdmFyIG1tID0gZ3NhcC5tYXRjaE1lZGlhKCksXG4gICAgICAgICAgICAgICAgcDtcblxuICAgICAgICAgICAgZm9yIChwIGluIHZhcnMpIHtcbiAgICAgICAgICAgICAgbW0uYWRkKHAsIHZhcnNbcF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbW07XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGdzYXAuYWRkRXZlbnRMaXN0ZW5lcihcIm1hdGNoTWVkaWFJbml0XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfcmV2ZXJ0QWxsKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZ3NhcC5hZGRFdmVudExpc3RlbmVyKFwibWF0Y2hNZWRpYVJldmVydFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gX3JldmVydFJlY29yZGVkKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZ3NhcC5hZGRFdmVudExpc3RlbmVyKFwibWF0Y2hNZWRpYVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfcmVmcmVzaEFsbCgwLCAxKTtcblxuICAgICAgICAgICAgX2Rpc3BhdGNoKFwibWF0Y2hNZWRpYVwiKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBnc2FwLm1hdGNoTWVkaWEoXCIob3JpZW50YXRpb246IHBvcnRyYWl0KVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyB3aGVuIG9yaWVudGF0aW9uIGNoYW5nZXMsIHdlIHNob3VsZCB0YWtlIG5ldyBiYXNlIG1lYXN1cmVtZW50cyBmb3IgdGhlIGlnbm9yZU1vYmlsZVJlc2l6ZSBmZWF0dXJlLlxuICAgICAgICAgICAgX3NldEJhc2VEaW1lbnNpb25zKCk7XG5cbiAgICAgICAgICAgIHJldHVybiBfc2V0QmFzZURpbWVuc2lvbnM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFwiUmVxdWlyZXMgR1NBUCAzLjExLjAgb3IgbGF0ZXJcIik7XG4gICAgICAgIH1cblxuICAgICAgICBfc2V0QmFzZURpbWVuc2lvbnMoKTtcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX2RvYywgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTsgLy8gc29tZSBicm93c2VycyAobGlrZSBDaHJvbWUpLCB0aGUgd2luZG93IHN0b3BzIGRpc3BhdGNoaW5nIHNjcm9sbCBldmVudHMgb24gdGhlIHdpbmRvdyBpZiB5b3Ugc2Nyb2xsIHJlYWxseSBmYXN0LCBidXQgaXQncyBjb25zaXN0ZW50IG9uIHRoZSBkb2N1bWVudCFcblxuXG4gICAgICAgIHZhciBib2R5U3R5bGUgPSBfYm9keS5zdHlsZSxcbiAgICAgICAgICAgIGJvcmRlciA9IGJvZHlTdHlsZS5ib3JkZXJUb3BTdHlsZSxcbiAgICAgICAgICAgIEFuaW1hdGlvblByb3RvID0gZ3NhcC5jb3JlLkFuaW1hdGlvbi5wcm90b3R5cGUsXG4gICAgICAgICAgICBib3VuZHMsXG4gICAgICAgICAgICBpO1xuICAgICAgICBBbmltYXRpb25Qcm90by5yZXZlcnQgfHwgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFuaW1hdGlvblByb3RvLCBcInJldmVydFwiLCB7XG4gICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZSgtMC4wMSwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTsgLy8gb25seSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgKEFuaW1hdGlvbi5yZXZlcnQoKSB3YXMgYWRkZWQgYWZ0ZXIgMy4xMC40KVxuXG4gICAgICAgIGJvZHlTdHlsZS5ib3JkZXJUb3BTdHlsZSA9IFwic29saWRcIjsgLy8gd29ya3MgYXJvdW5kIGFuIGlzc3VlIHdoZXJlIGEgbWFyZ2luIG9mIGEgY2hpbGQgZWxlbWVudCBjb3VsZCB0aHJvdyBvZmYgdGhlIGJvdW5kcyBvZiB0aGUgX2JvZHksIG1ha2luZyBpdCBzZWVtIGxpa2UgdGhlcmUncyBhIG1hcmdpbiB3aGVuIHRoZXJlIGFjdHVhbGx5IGlzbid0LiBUaGUgYm9yZGVyIGVuc3VyZXMgdGhhdCB0aGUgYm91bmRzIGFyZSBhY2N1cmF0ZS5cblxuICAgICAgICBib3VuZHMgPSBfZ2V0Qm91bmRzKF9ib2R5KTtcbiAgICAgICAgX3ZlcnRpY2FsLm0gPSBNYXRoLnJvdW5kKGJvdW5kcy50b3AgKyBfdmVydGljYWwuc2MoKSkgfHwgMDsgLy8gYWNjb21tb2RhdGUgdGhlIG9mZnNldCBvZiB0aGUgPGJvZHk+IGNhdXNlZCBieSBtYXJnaW5zIGFuZC9vciBwYWRkaW5nXG5cbiAgICAgICAgX2hvcml6b250YWwubSA9IE1hdGgucm91bmQoYm91bmRzLmxlZnQgKyBfaG9yaXpvbnRhbC5zYygpKSB8fCAwO1xuICAgICAgICBib3JkZXIgPyBib2R5U3R5bGUuYm9yZGVyVG9wU3R5bGUgPSBib3JkZXIgOiBib2R5U3R5bGUucmVtb3ZlUHJvcGVydHkoXCJib3JkZXItdG9wLXN0eWxlXCIpOyAvLyBUT0RPOiAoPykgbWF5YmUgbW92ZSB0byBsZXZlcmFnaW5nIHRoZSB2ZWxvY2l0eSBtZWNoYW5pc20gaW4gT2JzZXJ2ZXIgYW5kIHNraXAgaW50ZXJ2YWxzLlxuXG4gICAgICAgIF9zeW5jSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChfc3luYywgMjUwKTtcbiAgICAgICAgZ3NhcC5kZWxheWVkQ2FsbCgwLjUsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gX3N0YXJ0dXAgPSAwO1xuICAgICAgICB9KTtcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX2RvYywgXCJ0b3VjaGNhbmNlbFwiLCBfcGFzc1Rocm91Z2gpOyAvLyBzb21lIG9sZGVyIEFuZHJvaWQgZGV2aWNlcyBpbnRlcm1pdHRlbnRseSBzdG9wIGRpc3BhdGNoaW5nIFwidG91Y2htb3ZlXCIgZXZlbnRzIGlmIHdlIGRvbid0IGxpc3RlbiBmb3IgXCJ0b3VjaGNhbmNlbFwiIG9uIHRoZSBkb2N1bWVudC5cblxuXG4gICAgICAgIF9hZGRMaXN0ZW5lcihfYm9keSwgXCJ0b3VjaHN0YXJ0XCIsIF9wYXNzVGhyb3VnaCk7IC8vd29ya3MgYXJvdW5kIFNhZmFyaSBidWc6IGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9mb3J1bXMvdG9waWMvMjE0NTAtZHJhZ2dhYmxlLWluLWlmcmFtZS1vbi1tb2JpbGUtaXMtYnVnZ3kvXG5cblxuICAgICAgICBfbXVsdGlMaXN0ZW5lcihfYWRkTGlzdGVuZXIsIF9kb2MsIFwicG9pbnRlcmRvd24sdG91Y2hzdGFydCxtb3VzZWRvd25cIiwgX3BvaW50ZXJEb3duSGFuZGxlcik7XG5cbiAgICAgICAgX211bHRpTGlzdGVuZXIoX2FkZExpc3RlbmVyLCBfZG9jLCBcInBvaW50ZXJ1cCx0b3VjaGVuZCxtb3VzZXVwXCIsIF9wb2ludGVyVXBIYW5kbGVyKTtcblxuICAgICAgICBfdHJhbnNmb3JtUHJvcCA9IGdzYXAudXRpbHMuY2hlY2tQcmVmaXgoXCJ0cmFuc2Zvcm1cIik7XG5cbiAgICAgICAgX3N0YXRlUHJvcHMucHVzaChfdHJhbnNmb3JtUHJvcCk7XG5cbiAgICAgICAgX2NvcmVJbml0dGVkID0gX2dldFRpbWUoKTtcbiAgICAgICAgX3Jlc2l6ZURlbGF5ID0gZ3NhcC5kZWxheWVkQ2FsbCgwLjIsIF9yZWZyZXNoQWxsKS5wYXVzZSgpO1xuICAgICAgICBfYXV0b1JlZnJlc2ggPSBbX2RvYywgXCJ2aXNpYmlsaXR5Y2hhbmdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgdyA9IF93aW4uaW5uZXJXaWR0aCxcbiAgICAgICAgICAgICAgaCA9IF93aW4uaW5uZXJIZWlnaHQ7XG5cbiAgICAgICAgICBpZiAoX2RvYy5oaWRkZW4pIHtcbiAgICAgICAgICAgIF9wcmV2V2lkdGggPSB3O1xuICAgICAgICAgICAgX3ByZXZIZWlnaHQgPSBoO1xuICAgICAgICAgIH0gZWxzZSBpZiAoX3ByZXZXaWR0aCAhPT0gdyB8fCBfcHJldkhlaWdodCAhPT0gaCkge1xuICAgICAgICAgICAgX29uUmVzaXplKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfZG9jLCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgX3JlZnJlc2hBbGwsIF93aW4sIFwibG9hZFwiLCBfcmVmcmVzaEFsbCwgX3dpbiwgXCJyZXNpemVcIiwgX29uUmVzaXplXTtcblxuICAgICAgICBfaXRlcmF0ZUF1dG9SZWZyZXNoKF9hZGRMaXN0ZW5lcik7XG5cbiAgICAgICAgX3RyaWdnZXJzLmZvckVhY2goZnVuY3Rpb24gKHRyaWdnZXIpIHtcbiAgICAgICAgICByZXR1cm4gdHJpZ2dlci5lbmFibGUoMCwgMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBfc2Nyb2xsZXJzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgX3doZWVsTGlzdGVuZXIoX3JlbW92ZUxpc3RlbmVyLCBfc2Nyb2xsZXJzW2ldLCBfc2Nyb2xsZXJzW2kgKyAxXSk7XG5cbiAgICAgICAgICBfd2hlZWxMaXN0ZW5lcihfcmVtb3ZlTGlzdGVuZXIsIF9zY3JvbGxlcnNbaV0sIF9zY3JvbGxlcnNbaSArIDJdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBTY3JvbGxUcmlnZ2VyLmNvbmZpZyA9IGZ1bmN0aW9uIGNvbmZpZyh2YXJzKSB7XG4gICAgXCJsaW1pdENhbGxiYWNrc1wiIGluIHZhcnMgJiYgKF9saW1pdENhbGxiYWNrcyA9ICEhdmFycy5saW1pdENhbGxiYWNrcyk7XG4gICAgdmFyIG1zID0gdmFycy5zeW5jSW50ZXJ2YWw7XG4gICAgbXMgJiYgY2xlYXJJbnRlcnZhbChfc3luY0ludGVydmFsKSB8fCAoX3N5bmNJbnRlcnZhbCA9IG1zKSAmJiBzZXRJbnRlcnZhbChfc3luYywgbXMpO1xuICAgIFwiaWdub3JlTW9iaWxlUmVzaXplXCIgaW4gdmFycyAmJiAoX2lnbm9yZU1vYmlsZVJlc2l6ZSA9IFNjcm9sbFRyaWdnZXIuaXNUb3VjaCA9PT0gMSAmJiB2YXJzLmlnbm9yZU1vYmlsZVJlc2l6ZSk7XG5cbiAgICBpZiAoXCJhdXRvUmVmcmVzaEV2ZW50c1wiIGluIHZhcnMpIHtcbiAgICAgIF9pdGVyYXRlQXV0b1JlZnJlc2goX3JlbW92ZUxpc3RlbmVyKSB8fCBfaXRlcmF0ZUF1dG9SZWZyZXNoKF9hZGRMaXN0ZW5lciwgdmFycy5hdXRvUmVmcmVzaEV2ZW50cyB8fCBcIm5vbmVcIik7XG4gICAgICBfaWdub3JlUmVzaXplID0gKHZhcnMuYXV0b1JlZnJlc2hFdmVudHMgKyBcIlwiKS5pbmRleE9mKFwicmVzaXplXCIpID09PSAtMTtcbiAgICB9XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5zY3JvbGxlclByb3h5ID0gZnVuY3Rpb24gc2Nyb2xsZXJQcm94eSh0YXJnZXQsIHZhcnMpIHtcbiAgICB2YXIgdCA9IF9nZXRUYXJnZXQodGFyZ2V0KSxcbiAgICAgICAgaSA9IF9zY3JvbGxlcnMuaW5kZXhPZih0KSxcbiAgICAgICAgaXNWaWV3cG9ydCA9IF9pc1ZpZXdwb3J0KHQpO1xuXG4gICAgaWYgKH5pKSB7XG4gICAgICBfc2Nyb2xsZXJzLnNwbGljZShpLCBpc1ZpZXdwb3J0ID8gNiA6IDIpO1xuICAgIH1cblxuICAgIGlmICh2YXJzKSB7XG4gICAgICBpc1ZpZXdwb3J0ID8gX3Byb3hpZXMudW5zaGlmdChfd2luLCB2YXJzLCBfYm9keSwgdmFycywgX2RvY0VsLCB2YXJzKSA6IF9wcm94aWVzLnVuc2hpZnQodCwgdmFycyk7XG4gICAgfVxuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuY2xlYXJNYXRjaE1lZGlhID0gZnVuY3Rpb24gY2xlYXJNYXRjaE1lZGlhKHF1ZXJ5KSB7XG4gICAgX3RyaWdnZXJzLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICAgIHJldHVybiB0Ll9jdHggJiYgdC5fY3R4LnF1ZXJ5ID09PSBxdWVyeSAmJiB0Ll9jdHgua2lsbCh0cnVlLCB0cnVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBTY3JvbGxUcmlnZ2VyLmlzSW5WaWV3cG9ydCA9IGZ1bmN0aW9uIGlzSW5WaWV3cG9ydChlbGVtZW50LCByYXRpbywgaG9yaXpvbnRhbCkge1xuICAgIHZhciBib3VuZHMgPSAoX2lzU3RyaW5nKGVsZW1lbnQpID8gX2dldFRhcmdldChlbGVtZW50KSA6IGVsZW1lbnQpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICBvZmZzZXQgPSBib3VuZHNbaG9yaXpvbnRhbCA/IF93aWR0aCA6IF9oZWlnaHRdICogcmF0aW8gfHwgMDtcbiAgICByZXR1cm4gaG9yaXpvbnRhbCA/IGJvdW5kcy5yaWdodCAtIG9mZnNldCA+IDAgJiYgYm91bmRzLmxlZnQgKyBvZmZzZXQgPCBfd2luLmlubmVyV2lkdGggOiBib3VuZHMuYm90dG9tIC0gb2Zmc2V0ID4gMCAmJiBib3VuZHMudG9wICsgb2Zmc2V0IDwgX3dpbi5pbm5lckhlaWdodDtcbiAgfTtcblxuICBTY3JvbGxUcmlnZ2VyLnBvc2l0aW9uSW5WaWV3cG9ydCA9IGZ1bmN0aW9uIHBvc2l0aW9uSW5WaWV3cG9ydChlbGVtZW50LCByZWZlcmVuY2VQb2ludCwgaG9yaXpvbnRhbCkge1xuICAgIF9pc1N0cmluZyhlbGVtZW50KSAmJiAoZWxlbWVudCA9IF9nZXRUYXJnZXQoZWxlbWVudCkpO1xuICAgIHZhciBib3VuZHMgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICBzaXplID0gYm91bmRzW2hvcml6b250YWwgPyBfd2lkdGggOiBfaGVpZ2h0XSxcbiAgICAgICAgb2Zmc2V0ID0gcmVmZXJlbmNlUG9pbnQgPT0gbnVsbCA/IHNpemUgLyAyIDogcmVmZXJlbmNlUG9pbnQgaW4gX2tleXdvcmRzID8gX2tleXdvcmRzW3JlZmVyZW5jZVBvaW50XSAqIHNpemUgOiB+cmVmZXJlbmNlUG9pbnQuaW5kZXhPZihcIiVcIikgPyBwYXJzZUZsb2F0KHJlZmVyZW5jZVBvaW50KSAqIHNpemUgLyAxMDAgOiBwYXJzZUZsb2F0KHJlZmVyZW5jZVBvaW50KSB8fCAwO1xuICAgIHJldHVybiBob3Jpem9udGFsID8gKGJvdW5kcy5sZWZ0ICsgb2Zmc2V0KSAvIF93aW4uaW5uZXJXaWR0aCA6IChib3VuZHMudG9wICsgb2Zmc2V0KSAvIF93aW4uaW5uZXJIZWlnaHQ7XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5raWxsQWxsID0gZnVuY3Rpb24ga2lsbEFsbChhbGxvd0xpc3RlbmVycykge1xuICAgIF90cmlnZ2Vycy5zbGljZSgwKS5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICByZXR1cm4gdC52YXJzLmlkICE9PSBcIlNjcm9sbFNtb290aGVyXCIgJiYgdC5raWxsKCk7XG4gICAgfSk7XG5cbiAgICBpZiAoYWxsb3dMaXN0ZW5lcnMgIT09IHRydWUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBfbGlzdGVuZXJzLmtpbGxBbGwgfHwgW107XG4gICAgICBfbGlzdGVuZXJzID0ge307XG4gICAgICBsaXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICByZXR1cm4gZigpO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBTY3JvbGxUcmlnZ2VyO1xufSgpO1xuU2Nyb2xsVHJpZ2dlci52ZXJzaW9uID0gXCIzLjExLjVcIjtcblxuU2Nyb2xsVHJpZ2dlci5zYXZlU3R5bGVzID0gZnVuY3Rpb24gKHRhcmdldHMpIHtcbiAgcmV0dXJuIHRhcmdldHMgPyBfdG9BcnJheSh0YXJnZXRzKS5mb3JFYWNoKGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAvLyBzYXZlZCBzdHlsZXMgYXJlIHJlY29yZGVkIGluIGEgY29uc2VjdXRpdmUgYWx0ZXJuYXRpbmcgQXJyYXksIGxpa2UgW2VsZW1lbnQsIGNzc1RleHQsIHRyYW5zZm9ybSBhdHRyaWJ1dGUsIGNhY2hlLCBtYXRjaE1lZGlhLCAuLi5dXG4gICAgaWYgKHRhcmdldCAmJiB0YXJnZXQuc3R5bGUpIHtcbiAgICAgIHZhciBpID0gX3NhdmVkU3R5bGVzLmluZGV4T2YodGFyZ2V0KTtcblxuICAgICAgaSA+PSAwICYmIF9zYXZlZFN0eWxlcy5zcGxpY2UoaSwgNSk7XG5cbiAgICAgIF9zYXZlZFN0eWxlcy5wdXNoKHRhcmdldCwgdGFyZ2V0LnN0eWxlLmNzc1RleHQsIHRhcmdldC5nZXRCQm94ICYmIHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiksIGdzYXAuY29yZS5nZXRDYWNoZSh0YXJnZXQpLCBfY29udGV4dCgpKTtcbiAgICB9XG4gIH0pIDogX3NhdmVkU3R5bGVzO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5yZXZlcnQgPSBmdW5jdGlvbiAoc29mdCwgbWVkaWEpIHtcbiAgcmV0dXJuIF9yZXZlcnRBbGwoIXNvZnQsIG1lZGlhKTtcbn07XG5cblNjcm9sbFRyaWdnZXIuY3JlYXRlID0gZnVuY3Rpb24gKHZhcnMsIGFuaW1hdGlvbikge1xuICByZXR1cm4gbmV3IFNjcm9sbFRyaWdnZXIodmFycywgYW5pbWF0aW9uKTtcbn07XG5cblNjcm9sbFRyaWdnZXIucmVmcmVzaCA9IGZ1bmN0aW9uIChzYWZlKSB7XG4gIHJldHVybiBzYWZlID8gX29uUmVzaXplKCkgOiAoX2NvcmVJbml0dGVkIHx8IFNjcm9sbFRyaWdnZXIucmVnaXN0ZXIoKSkgJiYgX3JlZnJlc2hBbGwodHJ1ZSk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLnVwZGF0ZSA9IGZ1bmN0aW9uIChmb3JjZSkge1xuICByZXR1cm4gKytfc2Nyb2xsZXJzLmNhY2hlICYmIF91cGRhdGVBbGwoZm9yY2UgPT09IHRydWUgPyAyIDogMCk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmNsZWFyU2Nyb2xsTWVtb3J5ID0gX2NsZWFyU2Nyb2xsTWVtb3J5O1xuXG5TY3JvbGxUcmlnZ2VyLm1heFNjcm9sbCA9IGZ1bmN0aW9uIChlbGVtZW50LCBob3Jpem9udGFsKSB7XG4gIHJldHVybiBfbWF4U2Nyb2xsKGVsZW1lbnQsIGhvcml6b250YWwgPyBfaG9yaXpvbnRhbCA6IF92ZXJ0aWNhbCk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmdldFNjcm9sbEZ1bmMgPSBmdW5jdGlvbiAoZWxlbWVudCwgaG9yaXpvbnRhbCkge1xuICByZXR1cm4gX2dldFNjcm9sbEZ1bmMoX2dldFRhcmdldChlbGVtZW50KSwgaG9yaXpvbnRhbCA/IF9ob3Jpem9udGFsIDogX3ZlcnRpY2FsKTtcbn07XG5cblNjcm9sbFRyaWdnZXIuZ2V0QnlJZCA9IGZ1bmN0aW9uIChpZCkge1xuICByZXR1cm4gX2lkc1tpZF07XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmdldEFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIF90cmlnZ2Vycy5maWx0ZXIoZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gdC52YXJzLmlkICE9PSBcIlNjcm9sbFNtb290aGVyXCI7XG4gIH0pO1xufTsgLy8gaXQncyBjb21tb24gZm9yIHBlb3BsZSB0byBTY3JvbGxUcmlnZ2VyLmdldEFsbCh0ID0+IHQua2lsbCgpKSBvbiBwYWdlIHJvdXRlcywgZm9yIGV4YW1wbGUsIGFuZCB3ZSBkb24ndCB3YW50IGl0IHRvIHJ1aW4gc21vb3RoIHNjcm9sbGluZyBieSBraWxsaW5nIHRoZSBtYWluIFNjcm9sbFNtb290aGVyIG9uZS5cblxuXG5TY3JvbGxUcmlnZ2VyLmlzU2Nyb2xsaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gISFfbGFzdFNjcm9sbFRpbWU7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLnNuYXBEaXJlY3Rpb25hbCA9IF9zbmFwRGlyZWN0aW9uYWw7XG5cblNjcm9sbFRyaWdnZXIuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uICh0eXBlLCBjYWxsYmFjaykge1xuICB2YXIgYSA9IF9saXN0ZW5lcnNbdHlwZV0gfHwgKF9saXN0ZW5lcnNbdHlwZV0gPSBbXSk7XG4gIH5hLmluZGV4T2YoY2FsbGJhY2spIHx8IGEucHVzaChjYWxsYmFjayk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgdmFyIGEgPSBfbGlzdGVuZXJzW3R5cGVdLFxuICAgICAgaSA9IGEgJiYgYS5pbmRleE9mKGNhbGxiYWNrKTtcbiAgaSA+PSAwICYmIGEuc3BsaWNlKGksIDEpO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5iYXRjaCA9IGZ1bmN0aW9uICh0YXJnZXRzLCB2YXJzKSB7XG4gIHZhciByZXN1bHQgPSBbXSxcbiAgICAgIHZhcnNDb3B5ID0ge30sXG4gICAgICBpbnRlcnZhbCA9IHZhcnMuaW50ZXJ2YWwgfHwgMC4wMTYsXG4gICAgICBiYXRjaE1heCA9IHZhcnMuYmF0Y2hNYXggfHwgMWU5LFxuICAgICAgcHJveHlDYWxsYmFjayA9IGZ1bmN0aW9uIHByb3h5Q2FsbGJhY2sodHlwZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgZWxlbWVudHMgPSBbXSxcbiAgICAgICAgdHJpZ2dlcnMgPSBbXSxcbiAgICAgICAgZGVsYXkgPSBnc2FwLmRlbGF5ZWRDYWxsKGludGVydmFsLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjYWxsYmFjayhlbGVtZW50cywgdHJpZ2dlcnMpO1xuICAgICAgZWxlbWVudHMgPSBbXTtcbiAgICAgIHRyaWdnZXJzID0gW107XG4gICAgfSkucGF1c2UoKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHNlbGYpIHtcbiAgICAgIGVsZW1lbnRzLmxlbmd0aCB8fCBkZWxheS5yZXN0YXJ0KHRydWUpO1xuICAgICAgZWxlbWVudHMucHVzaChzZWxmLnRyaWdnZXIpO1xuICAgICAgdHJpZ2dlcnMucHVzaChzZWxmKTtcbiAgICAgIGJhdGNoTWF4IDw9IGVsZW1lbnRzLmxlbmd0aCAmJiBkZWxheS5wcm9ncmVzcygxKTtcbiAgICB9O1xuICB9LFxuICAgICAgcDtcblxuICBmb3IgKHAgaW4gdmFycykge1xuICAgIHZhcnNDb3B5W3BdID0gcC5zdWJzdHIoMCwgMikgPT09IFwib25cIiAmJiBfaXNGdW5jdGlvbih2YXJzW3BdKSAmJiBwICE9PSBcIm9uUmVmcmVzaEluaXRcIiA/IHByb3h5Q2FsbGJhY2socCwgdmFyc1twXSkgOiB2YXJzW3BdO1xuICB9XG5cbiAgaWYgKF9pc0Z1bmN0aW9uKGJhdGNoTWF4KSkge1xuICAgIGJhdGNoTWF4ID0gYmF0Y2hNYXgoKTtcblxuICAgIF9hZGRMaXN0ZW5lcihTY3JvbGxUcmlnZ2VyLCBcInJlZnJlc2hcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGJhdGNoTWF4ID0gdmFycy5iYXRjaE1heCgpO1xuICAgIH0pO1xuICB9XG5cbiAgX3RvQXJyYXkodGFyZ2V0cykuZm9yRWFjaChmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgdmFyIGNvbmZpZyA9IHt9O1xuXG4gICAgZm9yIChwIGluIHZhcnNDb3B5KSB7XG4gICAgICBjb25maWdbcF0gPSB2YXJzQ29weVtwXTtcbiAgICB9XG5cbiAgICBjb25maWcudHJpZ2dlciA9IHRhcmdldDtcbiAgICByZXN1bHQucHVzaChTY3JvbGxUcmlnZ2VyLmNyZWF0ZShjb25maWcpKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07IC8vIHRvIHJlZHVjZSBmaWxlIHNpemUuIGNsYW1wcyB0aGUgc2Nyb2xsIGFuZCBhbHNvIHJldHVybnMgYSBkdXJhdGlvbiBtdWx0aXBsaWVyIHNvIHRoYXQgaWYgdGhlIHNjcm9sbCBnZXRzIGNob3BwZWQgc2hvcnRlciwgdGhlIGR1cmF0aW9uIGdldHMgY3VydGFpbGVkIGFzIHdlbGwgKG90aGVyd2lzZSBpZiB5b3UncmUgdmVyeSBjbG9zZSB0byB0aGUgdG9wIG9mIHRoZSBwYWdlLCBmb3IgZXhhbXBsZSwgYW5kIHN3aXBlIHVwIHJlYWxseSBmYXN0LCBpdCdsbCBzdWRkZW5seSBzbG93IGRvd24gYW5kIHRha2UgYSBsb25nIHRpbWUgdG8gcmVhY2ggdGhlIHRvcCkuXG5cblxudmFyIF9jbGFtcFNjcm9sbEFuZEdldER1cmF0aW9uTXVsdGlwbGllciA9IGZ1bmN0aW9uIF9jbGFtcFNjcm9sbEFuZEdldER1cmF0aW9uTXVsdGlwbGllcihzY3JvbGxGdW5jLCBjdXJyZW50LCBlbmQsIG1heCkge1xuICBjdXJyZW50ID4gbWF4ID8gc2Nyb2xsRnVuYyhtYXgpIDogY3VycmVudCA8IDAgJiYgc2Nyb2xsRnVuYygwKTtcbiAgcmV0dXJuIGVuZCA+IG1heCA/IChtYXggLSBjdXJyZW50KSAvIChlbmQgLSBjdXJyZW50KSA6IGVuZCA8IDAgPyBjdXJyZW50IC8gKGN1cnJlbnQgLSBlbmQpIDogMTtcbn0sXG4gICAgX2FsbG93TmF0aXZlUGFubmluZyA9IGZ1bmN0aW9uIF9hbGxvd05hdGl2ZVBhbm5pbmcodGFyZ2V0LCBkaXJlY3Rpb24pIHtcbiAgaWYgKGRpcmVjdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHRhcmdldC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShcInRvdWNoLWFjdGlvblwiKTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuc3R5bGUudG91Y2hBY3Rpb24gPSBkaXJlY3Rpb24gPT09IHRydWUgPyBcImF1dG9cIiA6IGRpcmVjdGlvbiA/IFwicGFuLVwiICsgZGlyZWN0aW9uICsgKE9ic2VydmVyLmlzVG91Y2ggPyBcIiBwaW5jaC16b29tXCIgOiBcIlwiKSA6IFwibm9uZVwiOyAvLyBub3RlOiBGaXJlZm94IGRvZXNuJ3Qgc3VwcG9ydCBpdCBwaW5jaC16b29tIHByb3Blcmx5LCBhdCBsZWFzdCBpbiBhZGRpdGlvbiB0byBhIHBhbi14IG9yIHBhbi15LlxuICB9XG5cbiAgdGFyZ2V0ID09PSBfZG9jRWwgJiYgX2FsbG93TmF0aXZlUGFubmluZyhfYm9keSwgZGlyZWN0aW9uKTtcbn0sXG4gICAgX292ZXJmbG93ID0ge1xuICBhdXRvOiAxLFxuICBzY3JvbGw6IDFcbn0sXG4gICAgX25lc3RlZFNjcm9sbCA9IGZ1bmN0aW9uIF9uZXN0ZWRTY3JvbGwoX3JlZjUpIHtcbiAgdmFyIGV2ZW50ID0gX3JlZjUuZXZlbnQsXG4gICAgICB0YXJnZXQgPSBfcmVmNS50YXJnZXQsXG4gICAgICBheGlzID0gX3JlZjUuYXhpcztcblxuICB2YXIgbm9kZSA9IChldmVudC5jaGFuZ2VkVG91Y2hlcyA/IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdIDogZXZlbnQpLnRhcmdldCxcbiAgICAgIGNhY2hlID0gbm9kZS5fZ3NhcCB8fCBnc2FwLmNvcmUuZ2V0Q2FjaGUobm9kZSksXG4gICAgICB0aW1lID0gX2dldFRpbWUoKSxcbiAgICAgIGNzO1xuXG4gIGlmICghY2FjaGUuX2lzU2Nyb2xsVCB8fCB0aW1lIC0gY2FjaGUuX2lzU2Nyb2xsVCA+IDIwMDApIHtcbiAgICAvLyBjYWNoZSBmb3IgMiBzZWNvbmRzIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXG4gICAgd2hpbGUgKG5vZGUgJiYgbm9kZSAhPT0gX2JvZHkgJiYgKG5vZGUuc2Nyb2xsSGVpZ2h0IDw9IG5vZGUuY2xpZW50SGVpZ2h0ICYmIG5vZGUuc2Nyb2xsV2lkdGggPD0gbm9kZS5jbGllbnRXaWR0aCB8fCAhKF9vdmVyZmxvd1soY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShub2RlKSkub3ZlcmZsb3dZXSB8fCBfb3ZlcmZsb3dbY3Mub3ZlcmZsb3dYXSkpKSB7XG4gICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cblxuICAgIGNhY2hlLl9pc1Njcm9sbCA9IG5vZGUgJiYgbm9kZSAhPT0gdGFyZ2V0ICYmICFfaXNWaWV3cG9ydChub2RlKSAmJiAoX292ZXJmbG93WyhjcyA9IF9nZXRDb21wdXRlZFN0eWxlKG5vZGUpKS5vdmVyZmxvd1ldIHx8IF9vdmVyZmxvd1tjcy5vdmVyZmxvd1hdKTtcbiAgICBjYWNoZS5faXNTY3JvbGxUID0gdGltZTtcbiAgfVxuXG4gIGlmIChjYWNoZS5faXNTY3JvbGwgfHwgYXhpcyA9PT0gXCJ4XCIpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5fZ3NhcEFsbG93ID0gdHJ1ZTtcbiAgfVxufSxcbiAgICAvLyBjYXB0dXJlIGV2ZW50cyBvbiBzY3JvbGxhYmxlIGVsZW1lbnRzIElOU0lERSB0aGUgPGJvZHk+IGFuZCBhbGxvdyB0aG9zZSBieSBjYWxsaW5nIHN0b3BQcm9wYWdhdGlvbigpIHdoZW4gd2UgZmluZCBhIHNjcm9sbGFibGUgYW5jZXN0b3Jcbl9pbnB1dE9ic2VydmVyID0gZnVuY3Rpb24gX2lucHV0T2JzZXJ2ZXIodGFyZ2V0LCB0eXBlLCBpbnB1dHMsIG5lc3RlZCkge1xuICByZXR1cm4gT2JzZXJ2ZXIuY3JlYXRlKHtcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICBjYXB0dXJlOiB0cnVlLFxuICAgIGRlYm91bmNlOiBmYWxzZSxcbiAgICBsb2NrQXhpczogdHJ1ZSxcbiAgICB0eXBlOiB0eXBlLFxuICAgIG9uV2hlZWw6IG5lc3RlZCA9IG5lc3RlZCAmJiBfbmVzdGVkU2Nyb2xsLFxuICAgIG9uUHJlc3M6IG5lc3RlZCxcbiAgICBvbkRyYWc6IG5lc3RlZCxcbiAgICBvblNjcm9sbDogbmVzdGVkLFxuICAgIG9uRW5hYmxlOiBmdW5jdGlvbiBvbkVuYWJsZSgpIHtcbiAgICAgIHJldHVybiBpbnB1dHMgJiYgX2FkZExpc3RlbmVyKF9kb2MsIE9ic2VydmVyLmV2ZW50VHlwZXNbMF0sIF9jYXB0dXJlSW5wdXRzLCBmYWxzZSwgdHJ1ZSk7XG4gICAgfSxcbiAgICBvbkRpc2FibGU6IGZ1bmN0aW9uIG9uRGlzYWJsZSgpIHtcbiAgICAgIHJldHVybiBfcmVtb3ZlTGlzdGVuZXIoX2RvYywgT2JzZXJ2ZXIuZXZlbnRUeXBlc1swXSwgX2NhcHR1cmVJbnB1dHMsIHRydWUpO1xuICAgIH1cbiAgfSk7XG59LFxuICAgIF9pbnB1dEV4cCA9IC8oaW5wdXR8bGFiZWx8c2VsZWN0fHRleHRhcmVhKS9pLFxuICAgIF9pbnB1dElzRm9jdXNlZCxcbiAgICBfY2FwdHVyZUlucHV0cyA9IGZ1bmN0aW9uIF9jYXB0dXJlSW5wdXRzKGUpIHtcbiAgdmFyIGlzSW5wdXQgPSBfaW5wdXRFeHAudGVzdChlLnRhcmdldC50YWdOYW1lKTtcblxuICBpZiAoaXNJbnB1dCB8fCBfaW5wdXRJc0ZvY3VzZWQpIHtcbiAgICBlLl9nc2FwQWxsb3cgPSB0cnVlO1xuICAgIF9pbnB1dElzRm9jdXNlZCA9IGlzSW5wdXQ7XG4gIH1cbn0sXG4gICAgX2dldFNjcm9sbE5vcm1hbGl6ZXIgPSBmdW5jdGlvbiBfZ2V0U2Nyb2xsTm9ybWFsaXplcih2YXJzKSB7XG4gIF9pc09iamVjdCh2YXJzKSB8fCAodmFycyA9IHt9KTtcbiAgdmFycy5wcmV2ZW50RGVmYXVsdCA9IHZhcnMuaXNOb3JtYWxpemVyID0gdmFycy5hbGxvd0NsaWNrcyA9IHRydWU7XG4gIHZhcnMudHlwZSB8fCAodmFycy50eXBlID0gXCJ3aGVlbCx0b3VjaFwiKTtcbiAgdmFycy5kZWJvdW5jZSA9ICEhdmFycy5kZWJvdW5jZTtcbiAgdmFycy5pZCA9IHZhcnMuaWQgfHwgXCJub3JtYWxpemVyXCI7XG5cbiAgdmFyIF92YXJzMiA9IHZhcnMsXG4gICAgICBub3JtYWxpemVTY3JvbGxYID0gX3ZhcnMyLm5vcm1hbGl6ZVNjcm9sbFgsXG4gICAgICBtb21lbnR1bSA9IF92YXJzMi5tb21lbnR1bSxcbiAgICAgIGFsbG93TmVzdGVkU2Nyb2xsID0gX3ZhcnMyLmFsbG93TmVzdGVkU2Nyb2xsLFxuICAgICAgb25SZWxlYXNlID0gX3ZhcnMyLm9uUmVsZWFzZSxcbiAgICAgIHNlbGYsXG4gICAgICBtYXhZLFxuICAgICAgdGFyZ2V0ID0gX2dldFRhcmdldCh2YXJzLnRhcmdldCkgfHwgX2RvY0VsLFxuICAgICAgc21vb3RoZXIgPSBnc2FwLmNvcmUuZ2xvYmFscygpLlNjcm9sbFNtb290aGVyLFxuICAgICAgc21vb3RoZXJJbnN0YW5jZSA9IHNtb290aGVyICYmIHNtb290aGVyLmdldCgpLFxuICAgICAgY29udGVudCA9IF9maXhJT1NCdWcgJiYgKHZhcnMuY29udGVudCAmJiBfZ2V0VGFyZ2V0KHZhcnMuY29udGVudCkgfHwgc21vb3RoZXJJbnN0YW5jZSAmJiB2YXJzLmNvbnRlbnQgIT09IGZhbHNlICYmICFzbW9vdGhlckluc3RhbmNlLnNtb290aCgpICYmIHNtb290aGVySW5zdGFuY2UuY29udGVudCgpKSxcbiAgICAgIHNjcm9sbEZ1bmNZID0gX2dldFNjcm9sbEZ1bmModGFyZ2V0LCBfdmVydGljYWwpLFxuICAgICAgc2Nyb2xsRnVuY1ggPSBfZ2V0U2Nyb2xsRnVuYyh0YXJnZXQsIF9ob3Jpem9udGFsKSxcbiAgICAgIHNjYWxlID0gMSxcbiAgICAgIGluaXRpYWxTY2FsZSA9IChPYnNlcnZlci5pc1RvdWNoICYmIF93aW4udmlzdWFsVmlld3BvcnQgPyBfd2luLnZpc3VhbFZpZXdwb3J0LnNjYWxlICogX3dpbi52aXN1YWxWaWV3cG9ydC53aWR0aCA6IF93aW4ub3V0ZXJXaWR0aCkgLyBfd2luLmlubmVyV2lkdGgsXG4gICAgICB3aGVlbFJlZnJlc2ggPSAwLFxuICAgICAgcmVzb2x2ZU1vbWVudHVtRHVyYXRpb24gPSBfaXNGdW5jdGlvbihtb21lbnR1bSkgPyBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG1vbWVudHVtKHNlbGYpO1xuICB9IDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBtb21lbnR1bSB8fCAyLjg7XG4gIH0sXG4gICAgICBsYXN0UmVmcmVzaElELFxuICAgICAgc2tpcFRvdWNoTW92ZSxcbiAgICAgIGlucHV0T2JzZXJ2ZXIgPSBfaW5wdXRPYnNlcnZlcih0YXJnZXQsIHZhcnMudHlwZSwgdHJ1ZSwgYWxsb3dOZXN0ZWRTY3JvbGwpLFxuICAgICAgcmVzdW1lVG91Y2hNb3ZlID0gZnVuY3Rpb24gcmVzdW1lVG91Y2hNb3ZlKCkge1xuICAgIHJldHVybiBza2lwVG91Y2hNb3ZlID0gZmFsc2U7XG4gIH0sXG4gICAgICBzY3JvbGxDbGFtcFggPSBfcGFzc1Rocm91Z2gsXG4gICAgICBzY3JvbGxDbGFtcFkgPSBfcGFzc1Rocm91Z2gsXG4gICAgICB1cGRhdGVDbGFtcHMgPSBmdW5jdGlvbiB1cGRhdGVDbGFtcHMoKSB7XG4gICAgbWF4WSA9IF9tYXhTY3JvbGwodGFyZ2V0LCBfdmVydGljYWwpO1xuICAgIHNjcm9sbENsYW1wWSA9IF9jbGFtcChfZml4SU9TQnVnID8gMSA6IDAsIG1heFkpO1xuICAgIG5vcm1hbGl6ZVNjcm9sbFggJiYgKHNjcm9sbENsYW1wWCA9IF9jbGFtcCgwLCBfbWF4U2Nyb2xsKHRhcmdldCwgX2hvcml6b250YWwpKSk7XG4gICAgbGFzdFJlZnJlc2hJRCA9IF9yZWZyZXNoSUQ7XG4gIH0sXG4gICAgICByZW1vdmVDb250ZW50T2Zmc2V0ID0gZnVuY3Rpb24gcmVtb3ZlQ29udGVudE9mZnNldCgpIHtcbiAgICBjb250ZW50Ll9nc2FwLnkgPSBfcm91bmQocGFyc2VGbG9hdChjb250ZW50Ll9nc2FwLnkpICsgc2Nyb2xsRnVuY1kub2Zmc2V0KSArIFwicHhcIjtcbiAgICBjb250ZW50LnN0eWxlLnRyYW5zZm9ybSA9IFwibWF0cml4M2QoMSwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgXCIgKyBwYXJzZUZsb2F0KGNvbnRlbnQuX2dzYXAueSkgKyBcIiwgMCwgMSlcIjtcbiAgICBzY3JvbGxGdW5jWS5vZmZzZXQgPSBzY3JvbGxGdW5jWS5jYWNoZUlEID0gMDtcbiAgfSxcbiAgICAgIGlnbm9yZURyYWcgPSBmdW5jdGlvbiBpZ25vcmVEcmFnKCkge1xuICAgIGlmIChza2lwVG91Y2hNb3ZlKSB7XG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzdW1lVG91Y2hNb3ZlKTtcblxuICAgICAgdmFyIG9mZnNldCA9IF9yb3VuZChzZWxmLmRlbHRhWSAvIDIpLFxuICAgICAgICAgIHNjcm9sbCA9IHNjcm9sbENsYW1wWShzY3JvbGxGdW5jWS52IC0gb2Zmc2V0KTtcblxuICAgICAgaWYgKGNvbnRlbnQgJiYgc2Nyb2xsICE9PSBzY3JvbGxGdW5jWS52ICsgc2Nyb2xsRnVuY1kub2Zmc2V0KSB7XG4gICAgICAgIHNjcm9sbEZ1bmNZLm9mZnNldCA9IHNjcm9sbCAtIHNjcm9sbEZ1bmNZLnY7XG5cbiAgICAgICAgdmFyIHkgPSBfcm91bmQoKHBhcnNlRmxvYXQoY29udGVudCAmJiBjb250ZW50Ll9nc2FwLnkpIHx8IDApIC0gc2Nyb2xsRnVuY1kub2Zmc2V0KTtcblxuICAgICAgICBjb250ZW50LnN0eWxlLnRyYW5zZm9ybSA9IFwibWF0cml4M2QoMSwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgXCIgKyB5ICsgXCIsIDAsIDEpXCI7XG4gICAgICAgIGNvbnRlbnQuX2dzYXAueSA9IHkgKyBcInB4XCI7XG4gICAgICAgIHNjcm9sbEZ1bmNZLmNhY2hlSUQgPSBfc2Nyb2xsZXJzLmNhY2hlO1xuXG4gICAgICAgIF91cGRhdGVBbGwoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2Nyb2xsRnVuY1kub2Zmc2V0ICYmIHJlbW92ZUNvbnRlbnRPZmZzZXQoKTtcbiAgICBza2lwVG91Y2hNb3ZlID0gdHJ1ZTtcbiAgfSxcbiAgICAgIHR3ZWVuLFxuICAgICAgc3RhcnRTY3JvbGxYLFxuICAgICAgc3RhcnRTY3JvbGxZLFxuICAgICAgb25TdG9wRGVsYXllZENhbGwsXG4gICAgICBvblJlc2l6ZSA9IGZ1bmN0aW9uIG9uUmVzaXplKCkge1xuICAgIC8vIGlmIHRoZSB3aW5kb3cgcmVzaXplcywgbGlrZSBvbiBhbiBpUGhvbmUgd2hpY2ggQXBwbGUgRk9SQ0VTIHRoZSBhZGRyZXNzIGJhciB0byBzaG93L2hpZGUgZXZlbiBpZiB3ZSBldmVudC5wcmV2ZW50RGVmYXVsdCgpLCBpdCBtYXkgYmUgc2Nyb2xsaW5nIHRvbyBmYXIgbm93IHRoYXQgdGhlIGFkZHJlc3MgYmFyIGlzIHNob3dpbmcsIHNvIHdlIG11c3QgZHluYW1pY2FsbHkgYWRqdXN0IHRoZSBtb21lbnR1bSB0d2Vlbi5cbiAgICB1cGRhdGVDbGFtcHMoKTtcblxuICAgIGlmICh0d2Vlbi5pc0FjdGl2ZSgpICYmIHR3ZWVuLnZhcnMuc2Nyb2xsWSA+IG1heFkpIHtcbiAgICAgIHNjcm9sbEZ1bmNZKCkgPiBtYXhZID8gdHdlZW4ucHJvZ3Jlc3MoMSkgJiYgc2Nyb2xsRnVuY1kobWF4WSkgOiB0d2Vlbi5yZXNldFRvKFwic2Nyb2xsWVwiLCBtYXhZKTtcbiAgICB9XG4gIH07XG5cbiAgY29udGVudCAmJiBnc2FwLnNldChjb250ZW50LCB7XG4gICAgeTogXCIrPTBcIlxuICB9KTsgLy8gdG8gZW5zdXJlIHRoZXJlJ3MgYSBjYWNoZSAoZWxlbWVudC5fZ3NhcClcblxuICB2YXJzLmlnbm9yZUNoZWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICByZXR1cm4gX2ZpeElPU0J1ZyAmJiBlLnR5cGUgPT09IFwidG91Y2htb3ZlXCIgJiYgaWdub3JlRHJhZyhlKSB8fCBzY2FsZSA+IDEuMDUgJiYgZS50eXBlICE9PSBcInRvdWNoc3RhcnRcIiB8fCBzZWxmLmlzR2VzdHVyaW5nIHx8IGUudG91Y2hlcyAmJiBlLnRvdWNoZXMubGVuZ3RoID4gMTtcbiAgfTtcblxuICB2YXJzLm9uUHJlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgc2tpcFRvdWNoTW92ZSA9IGZhbHNlO1xuICAgIHZhciBwcmV2U2NhbGUgPSBzY2FsZTtcbiAgICBzY2FsZSA9IF9yb3VuZCgoX3dpbi52aXN1YWxWaWV3cG9ydCAmJiBfd2luLnZpc3VhbFZpZXdwb3J0LnNjYWxlIHx8IDEpIC8gaW5pdGlhbFNjYWxlKTtcbiAgICB0d2Vlbi5wYXVzZSgpO1xuICAgIHByZXZTY2FsZSAhPT0gc2NhbGUgJiYgX2FsbG93TmF0aXZlUGFubmluZyh0YXJnZXQsIHNjYWxlID4gMS4wMSA/IHRydWUgOiBub3JtYWxpemVTY3JvbGxYID8gZmFsc2UgOiBcInhcIik7XG4gICAgc3RhcnRTY3JvbGxYID0gc2Nyb2xsRnVuY1goKTtcbiAgICBzdGFydFNjcm9sbFkgPSBzY3JvbGxGdW5jWSgpO1xuICAgIHVwZGF0ZUNsYW1wcygpO1xuICAgIGxhc3RSZWZyZXNoSUQgPSBfcmVmcmVzaElEO1xuICB9O1xuXG4gIHZhcnMub25SZWxlYXNlID0gdmFycy5vbkdlc3R1cmVTdGFydCA9IGZ1bmN0aW9uIChzZWxmLCB3YXNEcmFnZ2luZykge1xuICAgIHNjcm9sbEZ1bmNZLm9mZnNldCAmJiByZW1vdmVDb250ZW50T2Zmc2V0KCk7XG5cbiAgICBpZiAoIXdhc0RyYWdnaW5nKSB7XG4gICAgICBvblN0b3BEZWxheWVkQ2FsbC5yZXN0YXJ0KHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfc2Nyb2xsZXJzLmNhY2hlKys7IC8vIG1ha2Ugc3VyZSB3ZSdyZSBwdWxsaW5nIHRoZSBub24tY2FjaGVkIHZhbHVlXG4gICAgICAvLyBhbHRlcm5hdGUgYWxnb3JpdGhtOiBkdXJYID0gTWF0aC5taW4oNiwgTWF0aC5hYnMoc2VsZi52ZWxvY2l0eVggLyA4MDApKSxcdGR1ciA9IE1hdGgubWF4KGR1clgsIE1hdGgubWluKDYsIE1hdGguYWJzKHNlbGYudmVsb2NpdHlZIC8gODAwKSkpOyBkdXIgPSBkdXIgKiAoMC40ICsgKDEgLSBfcG93ZXI0SW4oZHVyIC8gNikpICogMC42KSkgKiAobW9tZW50dW1TcGVlZCB8fCAxKVxuXG4gICAgICB2YXIgZHVyID0gcmVzb2x2ZU1vbWVudHVtRHVyYXRpb24oKSxcbiAgICAgICAgICBjdXJyZW50U2Nyb2xsLFxuICAgICAgICAgIGVuZFNjcm9sbDtcblxuICAgICAgaWYgKG5vcm1hbGl6ZVNjcm9sbFgpIHtcbiAgICAgICAgY3VycmVudFNjcm9sbCA9IHNjcm9sbEZ1bmNYKCk7XG4gICAgICAgIGVuZFNjcm9sbCA9IGN1cnJlbnRTY3JvbGwgKyBkdXIgKiAwLjA1ICogLXNlbGYudmVsb2NpdHlYIC8gMC4yMjc7IC8vIHRoZSBjb25zdGFudCAuMjI3IGlzIGZyb20gcG93ZXI0KDAuMDUpLiB2ZWxvY2l0eSBpcyBpbnZlcnRlZCBiZWNhdXNlIHNjcm9sbGluZyBnb2VzIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24uXG5cbiAgICAgICAgZHVyICo9IF9jbGFtcFNjcm9sbEFuZEdldER1cmF0aW9uTXVsdGlwbGllcihzY3JvbGxGdW5jWCwgY3VycmVudFNjcm9sbCwgZW5kU2Nyb2xsLCBfbWF4U2Nyb2xsKHRhcmdldCwgX2hvcml6b250YWwpKTtcbiAgICAgICAgdHdlZW4udmFycy5zY3JvbGxYID0gc2Nyb2xsQ2xhbXBYKGVuZFNjcm9sbCk7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRTY3JvbGwgPSBzY3JvbGxGdW5jWSgpO1xuICAgICAgZW5kU2Nyb2xsID0gY3VycmVudFNjcm9sbCArIGR1ciAqIDAuMDUgKiAtc2VsZi52ZWxvY2l0eVkgLyAwLjIyNzsgLy8gdGhlIGNvbnN0YW50IC4yMjcgaXMgZnJvbSBwb3dlcjQoMC4wNSlcblxuICAgICAgZHVyICo9IF9jbGFtcFNjcm9sbEFuZEdldER1cmF0aW9uTXVsdGlwbGllcihzY3JvbGxGdW5jWSwgY3VycmVudFNjcm9sbCwgZW5kU2Nyb2xsLCBfbWF4U2Nyb2xsKHRhcmdldCwgX3ZlcnRpY2FsKSk7XG4gICAgICB0d2Vlbi52YXJzLnNjcm9sbFkgPSBzY3JvbGxDbGFtcFkoZW5kU2Nyb2xsKTtcbiAgICAgIHR3ZWVuLmludmFsaWRhdGUoKS5kdXJhdGlvbihkdXIpLnBsYXkoMC4wMSk7XG5cbiAgICAgIGlmIChfZml4SU9TQnVnICYmIHR3ZWVuLnZhcnMuc2Nyb2xsWSA+PSBtYXhZIHx8IGN1cnJlbnRTY3JvbGwgPj0gbWF4WSAtIDEpIHtcbiAgICAgICAgLy8gaU9TIGJ1ZzogaXQnbGwgc2hvdyB0aGUgYWRkcmVzcyBiYXIgYnV0IE5PVCBmaXJlIHRoZSB3aW5kb3cgXCJyZXNpemVcIiBldmVudCB1bnRpbCB0aGUgYW5pbWF0aW9uIGlzIGRvbmUgYnV0IHdlIG11c3QgcHJvdGVjdCBhZ2FpbnN0IG92ZXJzaG9vdCBzbyB3ZSBsZXZlcmFnZSBhbiBvblVwZGF0ZSB0byBkbyBzby5cbiAgICAgICAgZ3NhcC50byh7fSwge1xuICAgICAgICAgIG9uVXBkYXRlOiBvblJlc2l6ZSxcbiAgICAgICAgICBkdXJhdGlvbjogZHVyXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIG9uUmVsZWFzZSAmJiBvblJlbGVhc2Uoc2VsZik7XG4gIH07XG5cbiAgdmFycy5vbldoZWVsID0gZnVuY3Rpb24gKCkge1xuICAgIHR3ZWVuLl90cyAmJiB0d2Vlbi5wYXVzZSgpO1xuXG4gICAgaWYgKF9nZXRUaW1lKCkgLSB3aGVlbFJlZnJlc2ggPiAxMDAwKSB7XG4gICAgICAvLyBhZnRlciAxIHNlY29uZCwgcmVmcmVzaCB0aGUgY2xhbXBzIG90aGVyd2lzZSB0aGF0J2xsIG9ubHkgaGFwcGVuIHdoZW4gU2Nyb2xsVHJpZ2dlci5yZWZyZXNoKCkgaXMgY2FsbGVkIG9yIGZvciB0b3VjaC1zY3JvbGxpbmcuXG4gICAgICBsYXN0UmVmcmVzaElEID0gMDtcbiAgICAgIHdoZWVsUmVmcmVzaCA9IF9nZXRUaW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHZhcnMub25DaGFuZ2UgPSBmdW5jdGlvbiAoc2VsZiwgZHgsIGR5LCB4QXJyYXksIHlBcnJheSkge1xuICAgIF9yZWZyZXNoSUQgIT09IGxhc3RSZWZyZXNoSUQgJiYgdXBkYXRlQ2xhbXBzKCk7XG4gICAgZHggJiYgbm9ybWFsaXplU2Nyb2xsWCAmJiBzY3JvbGxGdW5jWChzY3JvbGxDbGFtcFgoeEFycmF5WzJdID09PSBkeCA/IHN0YXJ0U2Nyb2xsWCArIChzZWxmLnN0YXJ0WCAtIHNlbGYueCkgOiBzY3JvbGxGdW5jWCgpICsgZHggLSB4QXJyYXlbMV0pKTsgLy8gZm9yIG1vcmUgcHJlY2lzaW9uLCB3ZSB0cmFjayBwb2ludGVyL3RvdWNoIG1vdmVtZW50IGZyb20gdGhlIHN0YXJ0LCBvdGhlcndpc2UgaXQnbGwgZHJpZnQuXG5cbiAgICBpZiAoZHkpIHtcbiAgICAgIHNjcm9sbEZ1bmNZLm9mZnNldCAmJiByZW1vdmVDb250ZW50T2Zmc2V0KCk7XG4gICAgICB2YXIgaXNUb3VjaCA9IHlBcnJheVsyXSA9PT0gZHksXG4gICAgICAgICAgeSA9IGlzVG91Y2ggPyBzdGFydFNjcm9sbFkgKyBzZWxmLnN0YXJ0WSAtIHNlbGYueSA6IHNjcm9sbEZ1bmNZKCkgKyBkeSAtIHlBcnJheVsxXSxcbiAgICAgICAgICB5Q2xhbXBlZCA9IHNjcm9sbENsYW1wWSh5KTtcbiAgICAgIGlzVG91Y2ggJiYgeSAhPT0geUNsYW1wZWQgJiYgKHN0YXJ0U2Nyb2xsWSArPSB5Q2xhbXBlZCAtIHkpO1xuICAgICAgc2Nyb2xsRnVuY1koeUNsYW1wZWQpO1xuICAgIH1cblxuICAgIChkeSB8fCBkeCkgJiYgX3VwZGF0ZUFsbCgpO1xuICB9O1xuXG4gIHZhcnMub25FbmFibGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgX2FsbG93TmF0aXZlUGFubmluZyh0YXJnZXQsIG5vcm1hbGl6ZVNjcm9sbFggPyBmYWxzZSA6IFwieFwiKTtcblxuICAgIFNjcm9sbFRyaWdnZXIuYWRkRXZlbnRMaXN0ZW5lcihcInJlZnJlc2hcIiwgb25SZXNpemUpO1xuXG4gICAgX2FkZExpc3RlbmVyKF93aW4sIFwicmVzaXplXCIsIG9uUmVzaXplKTtcblxuICAgIGlmIChzY3JvbGxGdW5jWS5zbW9vdGgpIHtcbiAgICAgIHNjcm9sbEZ1bmNZLnRhcmdldC5zdHlsZS5zY3JvbGxCZWhhdmlvciA9IFwiYXV0b1wiO1xuICAgICAgc2Nyb2xsRnVuY1kuc21vb3RoID0gc2Nyb2xsRnVuY1guc21vb3RoID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaW5wdXRPYnNlcnZlci5lbmFibGUoKTtcbiAgfTtcblxuICB2YXJzLm9uRGlzYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBfYWxsb3dOYXRpdmVQYW5uaW5nKHRhcmdldCwgdHJ1ZSk7XG5cbiAgICBfcmVtb3ZlTGlzdGVuZXIoX3dpbiwgXCJyZXNpemVcIiwgb25SZXNpemUpO1xuXG4gICAgU2Nyb2xsVHJpZ2dlci5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVmcmVzaFwiLCBvblJlc2l6ZSk7XG4gICAgaW5wdXRPYnNlcnZlci5raWxsKCk7XG4gIH07XG5cbiAgdmFycy5sb2NrQXhpcyA9IHZhcnMubG9ja0F4aXMgIT09IGZhbHNlO1xuICBzZWxmID0gbmV3IE9ic2VydmVyKHZhcnMpO1xuICBzZWxmLmlPUyA9IF9maXhJT1NCdWc7IC8vIHVzZWQgaW4gdGhlIE9ic2VydmVyIGdldENhY2hlZFNjcm9sbCgpIGZ1bmN0aW9uIHRvIHdvcmsgYXJvdW5kIGFuIGlPUyBidWcgdGhhdCB3cmVha3MgaGF2b2Mgd2l0aCBUb3VjaEV2ZW50LmNsaWVudFkgaWYgd2UgYWxsb3cgc2Nyb2xsIHRvIGdvIGFsbCB0aGUgd2F5IGJhY2sgdG8gMC5cblxuICBfZml4SU9TQnVnICYmICFzY3JvbGxGdW5jWSgpICYmIHNjcm9sbEZ1bmNZKDEpOyAvLyBpT1MgYnVnIGNhdXNlcyBldmVudC5jbGllbnRZIHZhbHVlcyB0byBmcmVhayBvdXQgKHdpbGRseSBpbmFjY3VyYXRlKSBpZiB0aGUgc2Nyb2xsIHBvc2l0aW9uIGlzIGV4YWN0bHkgMC5cblxuICBfZml4SU9TQnVnICYmIGdzYXAudGlja2VyLmFkZChfcGFzc1Rocm91Z2gpOyAvLyBwcmV2ZW50IHRoZSB0aWNrZXIgZnJvbSBzbGVlcGluZ1xuXG4gIG9uU3RvcERlbGF5ZWRDYWxsID0gc2VsZi5fZGM7XG4gIHR3ZWVuID0gZ3NhcC50byhzZWxmLCB7XG4gICAgZWFzZTogXCJwb3dlcjRcIixcbiAgICBwYXVzZWQ6IHRydWUsXG4gICAgc2Nyb2xsWDogbm9ybWFsaXplU2Nyb2xsWCA/IFwiKz0wLjFcIiA6IFwiKz0wXCIsXG4gICAgc2Nyb2xsWTogXCIrPTAuMVwiLFxuICAgIG1vZGlmaWVyczoge1xuICAgICAgc2Nyb2xsWTogX2ludGVycnVwdGlvblRyYWNrZXIoc2Nyb2xsRnVuY1ksIHNjcm9sbEZ1bmNZKCksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHR3ZWVuLnBhdXNlKCk7XG4gICAgICB9KVxuICAgIH0sXG4gICAgb25VcGRhdGU6IF91cGRhdGVBbGwsXG4gICAgb25Db21wbGV0ZTogb25TdG9wRGVsYXllZENhbGwudmFycy5vbkNvbXBsZXRlXG4gIH0pOyAvLyB3ZSBuZWVkIHRoZSBtb2RpZmllciB0byBzZW5zZSBpZiB0aGUgc2Nyb2xsIHBvc2l0aW9uIGlzIGFsdGVyZWQgb3V0c2lkZSBvZiB0aGUgbW9tZW50dW0gdHdlZW4gKGxpa2Ugd2l0aCBhIHNjcm9sbFRvIHR3ZWVuKSBzbyB3ZSBjYW4gcGF1c2UoKSBpdCB0byBwcmV2ZW50IGNvbmZsaWN0cy5cblxuICByZXR1cm4gc2VsZjtcbn07XG5cblNjcm9sbFRyaWdnZXIuc29ydCA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gIHJldHVybiBfdHJpZ2dlcnMuc29ydChmdW5jIHx8IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIChhLnZhcnMucmVmcmVzaFByaW9yaXR5IHx8IDApICogLTFlNiArIGEuc3RhcnQgLSAoYi5zdGFydCArIChiLnZhcnMucmVmcmVzaFByaW9yaXR5IHx8IDApICogLTFlNik7XG4gIH0pO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5vYnNlcnZlID0gZnVuY3Rpb24gKHZhcnMpIHtcbiAgcmV0dXJuIG5ldyBPYnNlcnZlcih2YXJzKTtcbn07XG5cblNjcm9sbFRyaWdnZXIubm9ybWFsaXplU2Nyb2xsID0gZnVuY3Rpb24gKHZhcnMpIHtcbiAgaWYgKHR5cGVvZiB2YXJzID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmV0dXJuIF9ub3JtYWxpemVyO1xuICB9XG5cbiAgaWYgKHZhcnMgPT09IHRydWUgJiYgX25vcm1hbGl6ZXIpIHtcbiAgICByZXR1cm4gX25vcm1hbGl6ZXIuZW5hYmxlKCk7XG4gIH1cblxuICBpZiAodmFycyA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gX25vcm1hbGl6ZXIgJiYgX25vcm1hbGl6ZXIua2lsbCgpO1xuICB9XG5cbiAgdmFyIG5vcm1hbGl6ZXIgPSB2YXJzIGluc3RhbmNlb2YgT2JzZXJ2ZXIgPyB2YXJzIDogX2dldFNjcm9sbE5vcm1hbGl6ZXIodmFycyk7XG4gIF9ub3JtYWxpemVyICYmIF9ub3JtYWxpemVyLnRhcmdldCA9PT0gbm9ybWFsaXplci50YXJnZXQgJiYgX25vcm1hbGl6ZXIua2lsbCgpO1xuICBfaXNWaWV3cG9ydChub3JtYWxpemVyLnRhcmdldCkgJiYgKF9ub3JtYWxpemVyID0gbm9ybWFsaXplcik7XG4gIHJldHVybiBub3JtYWxpemVyO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5jb3JlID0ge1xuICAvLyBzbWFsbGVyIGZpbGUgc2l6ZSB3YXkgdG8gbGV2ZXJhZ2UgaW4gU2Nyb2xsU21vb3RoZXIgYW5kIE9ic2VydmVyXG4gIF9nZXRWZWxvY2l0eVByb3A6IF9nZXRWZWxvY2l0eVByb3AsXG4gIF9pbnB1dE9ic2VydmVyOiBfaW5wdXRPYnNlcnZlcixcbiAgX3Njcm9sbGVyczogX3Njcm9sbGVycyxcbiAgX3Byb3hpZXM6IF9wcm94aWVzLFxuICBicmlkZ2U6IHtcbiAgICAvLyB3aGVuIG5vcm1hbGl6ZVNjcm9sbCBzZXRzIHRoZSBzY3JvbGwgcG9zaXRpb24gKHNzID0gc2V0U2Nyb2xsKVxuICAgIHNzOiBmdW5jdGlvbiBzcygpIHtcbiAgICAgIF9sYXN0U2Nyb2xsVGltZSB8fCBfZGlzcGF0Y2goXCJzY3JvbGxTdGFydFwiKTtcbiAgICAgIF9sYXN0U2Nyb2xsVGltZSA9IF9nZXRUaW1lKCk7XG4gICAgfSxcbiAgICAvLyBhIHdheSB0byBnZXQgdGhlIF9yZWZyZXNoaW5nIHZhbHVlIGluIE9ic2VydmVyXG4gICAgcmVmOiBmdW5jdGlvbiByZWYoKSB7XG4gICAgICByZXR1cm4gX3JlZnJlc2hpbmc7XG4gICAgfVxuICB9XG59O1xuX2dldEdTQVAoKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRyaWdnZXIpO1xuZXhwb3J0IHsgU2Nyb2xsVHJpZ2dlciBhcyBkZWZhdWx0IH07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/gsap/ScrollTrigger.js\n"); /***/ }), /***/ "./node_modules/gsap/dist/SplitText.js": /*!*********************************************!*\ !*** ./node_modules/gsap/dist/SplitText.js ***! \*********************************************/ /***/ (function(__unused_webpack_module, exports) { eval("(function (global, factory) {\n\t true ? factory(exports) :\n\t0;\n}(this, (function (exports) { 'use strict';\n\n\tvar emojiExp = /([\\uD800-\\uDBFF][\\uDC00-\\uDFFF](?:[\\u200D\\uFE0F][\\uD800-\\uDBFF][\\uDC00-\\uDFFF]){2,}|\\uD83D\\uDC69(?:\\u200D(?:(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC67|(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC66)|\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C\\uDFF3\\uFE0F\\u200D\\uD83C\\uDF08|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642]\\uFE0F|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92])|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC6F\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDD6-\\uDDDF])\\u200D[\\u2640\\u2642]\\uFE0F|\\uD83C\\uDDFD\\uD83C\\uDDF0|\\uD83C\\uDDF6\\uD83C\\uDDE6|\\uD83C\\uDDF4\\uD83C\\uDDF2|\\uD83C\\uDDE9(?:\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF])|\\uD83C\\uDDF7(?:\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC])|\\uD83C\\uDDE8(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF5\\uDDF7\\uDDFA-\\uDDFF])|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:\\uFE0F\\u200D[\\u2640\\u2642]|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642])\\uFE0F|(?:\\uD83D\\uDC41\\uFE0F\\u200D\\uD83D\\uDDE8|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2695\\u2696\\u2708]|\\uD83D\\uDC69\\u200D[\\u2695\\u2696\\u2708]|\\uD83D\\uDC68(?:(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708]))\\uFE0F|\\uD83C\\uDDF2(?:\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF])|\\uD83D\\uDC69\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\u2764\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69]))|\\uD83C\\uDDF1(?:\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE])|\\uD83C\\uDDEF(?:\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5])|\\uD83C\\uDDED(?:\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA])|\\uD83C\\uDDEB(?:\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7])|[#\\*0-9]\\uFE0F\\u20E3|\\uD83C\\uDDE7(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDE6(?:\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF])|\\uD83C\\uDDFF(?:\\uD83C[\\uDDE6\\uDDF2\\uDDFC])|\\uD83C\\uDDF5(?:\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE])|\\uD83C\\uDDFB(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA])|\\uD83C\\uDDF3(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF])|\\uD83C\\uDFF4\\uDB40\\uDC67\\uDB40\\uDC62(?:\\uDB40\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73|\\uDB40\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDB40\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67)\\uDB40\\uDC7F|\\uD83D\\uDC68(?:\\u200D(?:\\u2764\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83D\\uDC68|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92])|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]))|\\uD83C\\uDDF8(?:\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF])|\\uD83C\\uDDF0(?:\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDFE(?:\\uD83C[\\uDDEA\\uDDF9])|\\uD83C\\uDDEE(?:\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9])|\\uD83C\\uDDF9(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF])|\\uD83C\\uDDEC(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE])|\\uD83C\\uDDFA(?:\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF])|\\uD83C\\uDDEA(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA])|\\uD83C\\uDDFC(?:\\uD83C[\\uDDEB\\uDDF8])|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u270A-\\u270D]|\\uD83C[\\uDF85\\uDFC2\\uDFC7]|\\uD83D[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC70\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDCAA\\uDD74\\uDD7A\\uDD90\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC]|\\uD83E[\\uDD18-\\uDD1C\\uDD1E\\uDD1F\\uDD30-\\uDD36\\uDDD1-\\uDDD5])(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\u200D(?:(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC67|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC66)|\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u26F9\\u270A-\\u270D]|\\uD83C[\\uDF85\\uDFC2-\\uDFC4\\uDFC7\\uDFCA-\\uDFCC]|\\uD83D[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66-\\uDC69\\uDC6E\\uDC70-\\uDC78\\uDC7C\\uDC81-\\uDC83\\uDC85-\\uDC87\\uDCAA\\uDD74\\uDD75\\uDD7A\\uDD90\\uDD95\\uDD96\\uDE45-\\uDE47\\uDE4B-\\uDE4F\\uDEA3\\uDEB4-\\uDEB6\\uDEC0\\uDECC]|\\uD83E[\\uDD18-\\uDD1C\\uDD1E\\uDD1F\\uDD26\\uDD30-\\uDD39\\uDD3D\\uDD3E\\uDDD1-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])?|(?:[\\u231A\\u231B\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u25FE\\u2614\\u2615\\u2648-\\u2653\\u267F\\u2693\\u26A1\\u26AA\\u26AB\\u26BD\\u26BE\\u26C4\\u26C5\\u26CE\\u26D4\\u26EA\\u26F2\\u26F3\\u26F5\\u26FA\\u26FD\\u2705\\u270A\\u270B\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2795-\\u2797\\u27B0\\u27BF\\u2B1B\\u2B1C\\u2B50\\u2B55]|\\uD83C[\\uDC04\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDDE6-\\uDDFF\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF7C\\uDF7E-\\uDF93\\uDFA0-\\uDFCA\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF4\\uDFF8-\\uDFFF]|\\uD83D[\\uDC00-\\uDC3E\\uDC40\\uDC42-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDD7A\\uDD95\\uDD96\\uDDA4\\uDDFB-\\uDE4F\\uDE80-\\uDEC5\\uDECC\\uDED0-\\uDED2\\uDEEB\\uDEEC\\uDEF4-\\uDEF8]|\\uD83E[\\uDD10-\\uDD3A\\uDD3C-\\uDD3E\\uDD40-\\uDD45\\uDD47-\\uDD4C\\uDD50-\\uDD6B\\uDD80-\\uDD97\\uDDC0\\uDDD0-\\uDDE6])|(?:[#\\*0-9\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23E9-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u261D\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267F\\u2692-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A1\\u26AA\\u26AB\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C5\\u26C8\\u26CE\\u26CF\\u26D1\\u26D3\\u26D4\\u26E9\\u26EA\\u26F0-\\u26F5\\u26F7-\\u26FA\\u26FD\\u2702\\u2705\\u2708-\\u270D\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2728\\u2733\\u2734\\u2744\\u2747\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2763\\u2764\\u2795-\\u2797\\u27A1\\u27B0\\u27BF\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC04\\uDCCF\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDD8E\\uDD91-\\uDD9A\\uDDE6-\\uDDFF\\uDE01\\uDE02\\uDE1A\\uDE2F\\uDE32-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF21\\uDF24-\\uDF93\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E-\\uDFF0\\uDFF3-\\uDFF5\\uDFF7-\\uDFFF]|\\uD83D[\\uDC00-\\uDCFD\\uDCFF-\\uDD3D\\uDD49-\\uDD4E\\uDD50-\\uDD67\\uDD6F\\uDD70\\uDD73-\\uDD7A\\uDD87\\uDD8A-\\uDD8D\\uDD90\\uDD95\\uDD96\\uDDA4\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA-\\uDE4F\\uDE80-\\uDEC5\\uDECB-\\uDED2\\uDEE0-\\uDEE5\\uDEE9\\uDEEB\\uDEEC\\uDEF0\\uDEF3-\\uDEF8]|\\uD83E[\\uDD10-\\uDD3A\\uDD3C-\\uDD3E\\uDD40-\\uDD45\\uDD47-\\uDD4C\\uDD50-\\uDD6B\\uDD80-\\uDD97\\uDDC0\\uDDD0-\\uDDE6])\\uFE0F)/;\n\tfunction getText(e) {\n\t var type = e.nodeType,\n\t result = \"\";\n\n\t if (type === 1 || type === 9 || type === 11) {\n\t if (typeof e.textContent === \"string\") {\n\t return e.textContent;\n\t } else {\n\t for (e = e.firstChild; e; e = e.nextSibling) {\n\t result += getText(e);\n\t }\n\t }\n\t } else if (type === 3 || type === 4) {\n\t return e.nodeValue;\n\t }\n\n\t return result;\n\t}\n\n\t/*!\n\t * SplitText: 3.11.5\n\t * https://greensock.com\n\t *\n\t * @license Copyright 2008-2023, GreenSock. All rights reserved.\n\t * Subject to the terms at https://greensock.com/standard-license or for\n\t * Club GreenSock members, the agreement issued with that membership.\n\t * @author: Jack Doyle, jack@greensock.com\n\t*/\n\n\tvar _doc,\n\t _win,\n\t _coreInitted,\n\t gsap,\n\t _context,\n\t _toArray,\n\t _stripExp = /(?:\\r|\\n|\\t\\t)/g,\n\t _multipleSpacesExp = /(?:\\s\\s+)/g,\n\t _initCore = function _initCore(core) {\n\t _doc = document;\n\t _win = window;\n\t gsap = gsap || core || _win.gsap || console.warn(\"Please gsap.registerPlugin(SplitText)\");\n\n\t if (gsap) {\n\t _toArray = gsap.utils.toArray;\n\n\t _context = gsap.core.context || function () {};\n\n\t _coreInitted = 1;\n\t }\n\t},\n\t _getComputedStyle = function _getComputedStyle(element) {\n\t return _win.getComputedStyle(element);\n\t},\n\t _isAbsolute = function _isAbsolute(vars) {\n\t return vars.position === \"absolute\" || vars.absolute === true;\n\t},\n\t _findSpecialChars = function _findSpecialChars(text, chars) {\n\t var i = chars.length,\n\t s;\n\n\t while (--i > -1) {\n\t s = chars[i];\n\n\t if (text.substr(0, s.length) === s) {\n\t return s.length;\n\t }\n\t }\n\t},\n\t _divStart = \" style='position:relative;display:inline-block;'\",\n\t _cssClassFunc = function _cssClassFunc(cssClass, tag) {\n\t if (cssClass === void 0) {\n\t cssClass = \"\";\n\t }\n\n\t var iterate = ~cssClass.indexOf(\"++\"),\n\t num = 1;\n\n\t if (iterate) {\n\t cssClass = cssClass.split(\"++\").join(\"\");\n\t }\n\n\t return function () {\n\t return \"<\" + tag + _divStart + (cssClass ? \" class='\" + cssClass + (iterate ? num++ : \"\") + \"'>\" : \">\");\n\t };\n\t},\n\t _swapText = function _swapText(element, oldText, newText) {\n\t var type = element.nodeType;\n\n\t if (type === 1 || type === 9 || type === 11) {\n\t for (element = element.firstChild; element; element = element.nextSibling) {\n\t _swapText(element, oldText, newText);\n\t }\n\t } else if (type === 3 || type === 4) {\n\t element.nodeValue = element.nodeValue.split(oldText).join(newText);\n\t }\n\t},\n\t _pushReversed = function _pushReversed(a, merge) {\n\t var i = merge.length;\n\n\t while (--i > -1) {\n\t a.push(merge[i]);\n\t }\n\t},\n\t _isBeforeWordDelimiter = function _isBeforeWordDelimiter(e, root, wordDelimiter) {\n\t var next;\n\n\t while (e && e !== root) {\n\t next = e._next || e.nextSibling;\n\n\t if (next) {\n\t return next.textContent.charAt(0) === wordDelimiter;\n\t }\n\n\t e = e.parentNode || e._parent;\n\t }\n\t},\n\t _deWordify = function _deWordify(e) {\n\t var children = _toArray(e.childNodes),\n\t l = children.length,\n\t i,\n\t child;\n\n\t for (i = 0; i < l; i++) {\n\t child = children[i];\n\n\t if (child._isSplit) {\n\t _deWordify(child);\n\t } else {\n\t if (i && child.previousSibling && child.previousSibling.nodeType === 3) {\n\t child.previousSibling.nodeValue += child.nodeType === 3 ? child.nodeValue : child.firstChild.nodeValue;\n\t e.removeChild(child);\n\t } else if (child.nodeType !== 3) {\n\t e.insertBefore(child.firstChild, child);\n\t e.removeChild(child);\n\t }\n\t }\n\t }\n\t},\n\t _getStyleAsNumber = function _getStyleAsNumber(name, computedStyle) {\n\t return parseFloat(computedStyle[name]) || 0;\n\t},\n\t _setPositionsAfterSplit = function _setPositionsAfterSplit(element, vars, allChars, allWords, allLines, origWidth, origHeight) {\n\t var cs = _getComputedStyle(element),\n\t paddingLeft = _getStyleAsNumber(\"paddingLeft\", cs),\n\t lineOffsetY = -999,\n\t borderTopAndBottom = _getStyleAsNumber(\"borderBottomWidth\", cs) + _getStyleAsNumber(\"borderTopWidth\", cs),\n\t borderLeftAndRight = _getStyleAsNumber(\"borderLeftWidth\", cs) + _getStyleAsNumber(\"borderRightWidth\", cs),\n\t padTopAndBottom = _getStyleAsNumber(\"paddingTop\", cs) + _getStyleAsNumber(\"paddingBottom\", cs),\n\t padLeftAndRight = _getStyleAsNumber(\"paddingLeft\", cs) + _getStyleAsNumber(\"paddingRight\", cs),\n\t lineThreshold = _getStyleAsNumber(\"fontSize\", cs) * (vars.lineThreshold || 0.2),\n\t textAlign = cs.textAlign,\n\t charArray = [],\n\t wordArray = [],\n\t lineArray = [],\n\t wordDelimiter = vars.wordDelimiter || \" \",\n\t tag = vars.tag ? vars.tag : vars.span ? \"span\" : \"div\",\n\t types = vars.type || vars.split || \"chars,words,lines\",\n\t lines = allLines && ~types.indexOf(\"lines\") ? [] : null,\n\t words = ~types.indexOf(\"words\"),\n\t chars = ~types.indexOf(\"chars\"),\n\t absolute = _isAbsolute(vars),\n\t linesClass = vars.linesClass,\n\t iterateLine = ~(linesClass || \"\").indexOf(\"++\"),\n\t spaceNodesToRemove = [],\n\t isFlex = cs.display === \"flex\",\n\t prevInlineDisplay = element.style.display,\n\t i,\n\t j,\n\t l,\n\t node,\n\t nodes,\n\t isChild,\n\t curLine,\n\t addWordSpaces,\n\t style,\n\t lineNode,\n\t lineWidth,\n\t offset;\n\n\t iterateLine && (linesClass = linesClass.split(\"++\").join(\"\"));\n\t isFlex && (element.style.display = \"block\");\n\t j = element.getElementsByTagName(\"*\");\n\t l = j.length;\n\t nodes = [];\n\n\t for (i = 0; i < l; i++) {\n\t nodes[i] = j[i];\n\t }\n\n\t if (lines || absolute) {\n\t for (i = 0; i < l; i++) {\n\t node = nodes[i];\n\t isChild = node.parentNode === element;\n\n\t if (isChild || absolute || chars && !words) {\n\t offset = node.offsetTop;\n\n\t if (lines && isChild && Math.abs(offset - lineOffsetY) > lineThreshold && (node.nodeName !== \"BR\" || i === 0)) {\n\t curLine = [];\n\t lines.push(curLine);\n\t lineOffsetY = offset;\n\t }\n\n\t if (absolute) {\n\t node._x = node.offsetLeft;\n\t node._y = offset;\n\t node._w = node.offsetWidth;\n\t node._h = node.offsetHeight;\n\t }\n\n\t if (lines) {\n\t if (node._isSplit && isChild || !chars && isChild || words && isChild || !words && node.parentNode.parentNode === element && !node.parentNode._isSplit) {\n\t curLine.push(node);\n\t node._x -= paddingLeft;\n\n\t if (_isBeforeWordDelimiter(node, element, wordDelimiter)) {\n\t node._wordEnd = true;\n\t }\n\t }\n\n\t if (node.nodeName === \"BR\" && (node.nextSibling && node.nextSibling.nodeName === \"BR\" || i === 0)) {\n\t lines.push([]);\n\t }\n\t }\n\t }\n\t }\n\t }\n\n\t for (i = 0; i < l; i++) {\n\t node = nodes[i];\n\t isChild = node.parentNode === element;\n\n\t if (node.nodeName === \"BR\") {\n\t if (lines || absolute) {\n\t node.parentNode && node.parentNode.removeChild(node);\n\t nodes.splice(i--, 1);\n\t l--;\n\t } else if (!words) {\n\t element.appendChild(node);\n\t }\n\n\t continue;\n\t }\n\n\t if (absolute) {\n\t style = node.style;\n\n\t if (!words && !isChild) {\n\t node._x += node.parentNode._x;\n\t node._y += node.parentNode._y;\n\t }\n\n\t style.left = node._x + \"px\";\n\t style.top = node._y + \"px\";\n\t style.position = \"absolute\";\n\t style.display = \"block\";\n\t style.width = node._w + 1 + \"px\";\n\t style.height = node._h + \"px\";\n\t }\n\n\t if (!words && chars) {\n\t if (node._isSplit) {\n\t node._next = j = node.nextSibling;\n\t node.parentNode.appendChild(node);\n\n\t while (j && j.nodeType === 3 && j.textContent === \" \") {\n\t node._next = j.nextSibling;\n\t node.parentNode.appendChild(j);\n\t j = j.nextSibling;\n\t }\n\t } else if (node.parentNode._isSplit) {\n\t node._parent = node.parentNode;\n\n\t if (!node.previousSibling && node.firstChild) {\n\t node.firstChild._isFirst = true;\n\t }\n\n\t if (node.nextSibling && node.nextSibling.textContent === \" \" && !node.nextSibling.nextSibling) {\n\t spaceNodesToRemove.push(node.nextSibling);\n\t }\n\n\t node._next = node.nextSibling && node.nextSibling._isFirst ? null : node.nextSibling;\n\t node.parentNode.removeChild(node);\n\t nodes.splice(i--, 1);\n\t l--;\n\t } else if (!isChild) {\n\t offset = !node.nextSibling && _isBeforeWordDelimiter(node.parentNode, element, wordDelimiter);\n\t node.parentNode._parent && node.parentNode._parent.appendChild(node);\n\t offset && node.parentNode.appendChild(_doc.createTextNode(\" \"));\n\n\t if (tag === \"span\") {\n\t node.style.display = \"inline\";\n\t }\n\n\t charArray.push(node);\n\t }\n\t } else if (node.parentNode._isSplit && !node._isSplit && node.innerHTML !== \"\") {\n\t wordArray.push(node);\n\t } else if (chars && !node._isSplit) {\n\t if (tag === \"span\") {\n\t node.style.display = \"inline\";\n\t }\n\n\t charArray.push(node);\n\t }\n\t }\n\n\t i = spaceNodesToRemove.length;\n\n\t while (--i > -1) {\n\t spaceNodesToRemove[i].parentNode.removeChild(spaceNodesToRemove[i]);\n\t }\n\n\t if (lines) {\n\t if (absolute) {\n\t lineNode = _doc.createElement(tag);\n\t element.appendChild(lineNode);\n\t lineWidth = lineNode.offsetWidth + \"px\";\n\t offset = lineNode.offsetParent === element ? 0 : element.offsetLeft;\n\t element.removeChild(lineNode);\n\t }\n\n\t style = element.style.cssText;\n\t element.style.cssText = \"display:none;\";\n\n\t while (element.firstChild) {\n\t element.removeChild(element.firstChild);\n\t }\n\n\t addWordSpaces = wordDelimiter === \" \" && (!absolute || !words && !chars);\n\n\t for (i = 0; i < lines.length; i++) {\n\t curLine = lines[i];\n\t lineNode = _doc.createElement(tag);\n\t lineNode.style.cssText = \"display:block;text-align:\" + textAlign + \";position:\" + (absolute ? \"absolute;\" : \"relative;\");\n\n\t if (linesClass) {\n\t lineNode.className = linesClass + (iterateLine ? i + 1 : \"\");\n\t }\n\n\t lineArray.push(lineNode);\n\t l = curLine.length;\n\n\t for (j = 0; j < l; j++) {\n\t if (curLine[j].nodeName !== \"BR\") {\n\t node = curLine[j];\n\t lineNode.appendChild(node);\n\t addWordSpaces && node._wordEnd && lineNode.appendChild(_doc.createTextNode(\" \"));\n\n\t if (absolute) {\n\t if (j === 0) {\n\t lineNode.style.top = node._y + \"px\";\n\t lineNode.style.left = paddingLeft + offset + \"px\";\n\t }\n\n\t node.style.top = \"0px\";\n\n\t if (offset) {\n\t node.style.left = node._x - offset + \"px\";\n\t }\n\t }\n\t }\n\t }\n\n\t if (l === 0) {\n\t lineNode.innerHTML = \" \";\n\t } else if (!words && !chars) {\n\t _deWordify(lineNode);\n\n\t _swapText(lineNode, String.fromCharCode(160), \" \");\n\t }\n\n\t if (absolute) {\n\t lineNode.style.width = lineWidth;\n\t lineNode.style.height = node._h + \"px\";\n\t }\n\n\t element.appendChild(lineNode);\n\t }\n\n\t element.style.cssText = style;\n\t }\n\n\t if (absolute) {\n\t if (origHeight > element.clientHeight) {\n\t element.style.height = origHeight - padTopAndBottom + \"px\";\n\n\t if (element.clientHeight < origHeight) {\n\t element.style.height = origHeight + borderTopAndBottom + \"px\";\n\t }\n\t }\n\n\t if (origWidth > element.clientWidth) {\n\t element.style.width = origWidth - padLeftAndRight + \"px\";\n\n\t if (element.clientWidth < origWidth) {\n\t element.style.width = origWidth + borderLeftAndRight + \"px\";\n\t }\n\t }\n\t }\n\n\t isFlex && (prevInlineDisplay ? element.style.display = prevInlineDisplay : element.style.removeProperty(\"display\"));\n\n\t _pushReversed(allChars, charArray);\n\n\t words && _pushReversed(allWords, wordArray);\n\n\t _pushReversed(allLines, lineArray);\n\t},\n\t _splitRawText = function _splitRawText(element, vars, wordStart, charStart) {\n\t var tag = vars.tag ? vars.tag : vars.span ? \"span\" : \"div\",\n\t types = vars.type || vars.split || \"chars,words,lines\",\n\t chars = ~types.indexOf(\"chars\"),\n\t absolute = _isAbsolute(vars),\n\t wordDelimiter = vars.wordDelimiter || \" \",\n\t space = wordDelimiter !== \" \" ? \"\" : absolute ? \"­ \" : \" \",\n\t wordEnd = \"\",\n\t wordIsOpen = 1,\n\t specialChars = vars.specialChars ? typeof vars.specialChars === \"function\" ? vars.specialChars : _findSpecialChars : null,\n\t text,\n\t splitText,\n\t i,\n\t j,\n\t l,\n\t character,\n\t hasTagStart,\n\t testResult,\n\t container = _doc.createElement(\"div\"),\n\t parent = element.parentNode;\n\n\t parent.insertBefore(container, element);\n\t container.textContent = element.nodeValue;\n\t parent.removeChild(element);\n\t element = container;\n\t text = getText(element);\n\t hasTagStart = text.indexOf(\"<\") !== -1;\n\n\t if (vars.reduceWhiteSpace !== false) {\n\t text = text.replace(_multipleSpacesExp, \" \").replace(_stripExp, \"\");\n\t }\n\n\t if (hasTagStart) {\n\t text = text.split(\"<\").join(\"{{LT}}\");\n\t }\n\n\t l = text.length;\n\t splitText = (text.charAt(0) === \" \" ? space : \"\") + wordStart();\n\n\t for (i = 0; i < l; i++) {\n\t character = text.charAt(i);\n\n\t if (specialChars && (testResult = specialChars(text.substr(i), vars.specialChars))) {\n\t character = text.substr(i, testResult || 1);\n\t splitText += chars && character !== \" \" ? charStart() + character + \"\" : character;\n\t i += testResult - 1;\n\t } else if (character === wordDelimiter && text.charAt(i - 1) !== wordDelimiter && i) {\n\t splitText += wordIsOpen ? wordEnd : \"\";\n\t wordIsOpen = 0;\n\n\t while (text.charAt(i + 1) === wordDelimiter) {\n\t splitText += space;\n\t i++;\n\t }\n\n\t if (i === l - 1) {\n\t splitText += space;\n\t } else if (text.charAt(i + 1) !== \")\") {\n\t splitText += space + wordStart();\n\t wordIsOpen = 1;\n\t }\n\t } else if (character === \"{\" && text.substr(i, 6) === \"{{LT}}\") {\n\t splitText += chars ? charStart() + \"{{LT}}\" + \"\" : \"{{LT}}\";\n\t i += 5;\n\t } else if (character.charCodeAt(0) >= 0xD800 && character.charCodeAt(0) <= 0xDBFF || text.charCodeAt(i + 1) >= 0xFE00 && text.charCodeAt(i + 1) <= 0xFE0F) {\n\t j = ((text.substr(i, 12).split(emojiExp) || [])[1] || \"\").length || 2;\n\t splitText += chars && character !== \" \" ? charStart() + text.substr(i, j) + \"\" : text.substr(i, j);\n\t i += j - 1;\n\t } else {\n\t splitText += chars && character !== \" \" ? charStart() + character + \"\" : character;\n\t }\n\t }\n\n\t element.outerHTML = splitText + (wordIsOpen ? wordEnd : \"\");\n\t hasTagStart && _swapText(parent, \"{{LT}}\", \"<\");\n\t},\n\t _split = function _split(element, vars, wordStart, charStart) {\n\t var children = _toArray(element.childNodes),\n\t l = children.length,\n\t absolute = _isAbsolute(vars),\n\t i,\n\t child;\n\n\t if (element.nodeType !== 3 || l > 1) {\n\t vars.absolute = false;\n\n\t for (i = 0; i < l; i++) {\n\t child = children[i];\n\t child._next = child._isFirst = child._parent = child._wordEnd = null;\n\n\t if (child.nodeType !== 3 || /\\S+/.test(child.nodeValue)) {\n\t if (absolute && child.nodeType !== 3 && _getComputedStyle(child).display === \"inline\") {\n\t child.style.display = \"inline-block\";\n\t child.style.position = \"relative\";\n\t }\n\n\t child._isSplit = true;\n\n\t _split(child, vars, wordStart, charStart);\n\t }\n\t }\n\n\t vars.absolute = absolute;\n\t element._isSplit = true;\n\t return;\n\t }\n\n\t _splitRawText(element, vars, wordStart, charStart);\n\t};\n\n\tvar SplitText = function () {\n\t function SplitText(element, vars) {\n\t _coreInitted || _initCore();\n\t this.elements = _toArray(element);\n\t this.chars = [];\n\t this.words = [];\n\t this.lines = [];\n\t this._originals = [];\n\t this.vars = vars || {};\n\n\t _context(this);\n\n\t this.split(vars);\n\t }\n\n\t var _proto = SplitText.prototype;\n\n\t _proto.split = function split(vars) {\n\t this.isSplit && this.revert();\n\t this.vars = vars = vars || this.vars;\n\t this._originals.length = this.chars.length = this.words.length = this.lines.length = 0;\n\n\t var i = this.elements.length,\n\t tag = vars.tag ? vars.tag : vars.span ? \"span\" : \"div\",\n\t wordStart = _cssClassFunc(vars.wordsClass, tag),\n\t charStart = _cssClassFunc(vars.charsClass, tag),\n\t origHeight,\n\t origWidth,\n\t e;\n\n\t while (--i > -1) {\n\t e = this.elements[i];\n\t this._originals[i] = e.innerHTML;\n\t origHeight = e.clientHeight;\n\t origWidth = e.clientWidth;\n\n\t _split(e, vars, wordStart, charStart);\n\n\t _setPositionsAfterSplit(e, vars, this.chars, this.words, this.lines, origWidth, origHeight);\n\t }\n\n\t this.chars.reverse();\n\t this.words.reverse();\n\t this.lines.reverse();\n\t this.isSplit = true;\n\t return this;\n\t };\n\n\t _proto.revert = function revert() {\n\t var originals = this._originals;\n\n\t if (!originals) {\n\t throw \"revert() call wasn't scoped properly.\";\n\t }\n\n\t this.elements.forEach(function (e, i) {\n\t return e.innerHTML = originals[i];\n\t });\n\t this.chars = [];\n\t this.words = [];\n\t this.lines = [];\n\t this.isSplit = false;\n\t return this;\n\t };\n\n\t SplitText.create = function create(element, vars) {\n\t return new SplitText(element, vars);\n\t };\n\n\t return SplitText;\n\t}();\n\tSplitText.version = \"3.11.5\";\n\tSplitText.register = _initCore;\n\n\texports.SplitText = SplitText;\n\texports.default = SplitText;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9kaXN0L1NwbGl0VGV4dC5qcy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBLENBQUMsS0FBNEQ7QUFDN0QsQ0FBQyxDQUN1RTtBQUN4RSxDQUFDLDZCQUE2Qjs7QUFFOUIsaUdBQWlHLEdBQUc7QUFDcEc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCw4QkFBOEIsR0FBRztBQUNqQztBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRiw0Q0FBNEMscUJBQXFCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0Esd0NBQXdDLFNBQVM7QUFDakQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGVBQWUsT0FBTztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEyQzs7QUFFM0M7QUFDQTtBQUNBOztBQUVBOztBQUVBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBLCtDQUErQyw2QkFBNkIsbUNBQW1DLGNBQWM7O0FBRTdIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUNBQXFDO0FBQ3JDLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEQUErRDtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0NBQW9DLElBQUk7QUFDeEM7O0FBRUE7QUFDQTs7QUFFQSxlQUFlLE9BQU87QUFDdEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU8seUJBQXlCLDhCQUE4QixJQUFJO0FBQ2xFLDZDQUE2QyxJQUFJLDBCQUEwQixJQUFJO0FBQy9FO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1Q0FBdUMsSUFBSTtBQUMzQyxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxnREFBZ0QsYUFBYTs7QUFFN0QsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vbm9kZV9tb2R1bGVzL2dzYXAvZGlzdC9TcGxpdFRleHQuanM/MGY4YyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHR0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMpIDpcblx0dHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKFsnZXhwb3J0cyddLCBmYWN0b3J5KSA6XG5cdChnbG9iYWwgPSBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwud2luZG93ID0gZ2xvYmFsLndpbmRvdyB8fCB7fSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG5cdHZhciBlbW9qaUV4cCA9IC8oW1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXSg/OltcXHUyMDBEXFx1RkUwRl1bXFx1RDgwMC1cXHVEQkZGXVtcXHVEQzAwLVxcdURGRkZdKXsyLH18XFx1RDgzRFxcdURDNjkoPzpcXHUyMDBEKD86KD86XFx1RDgzRFxcdURDNjlcXHUyMDBEKT9cXHVEODNEXFx1REM2N3woPzpcXHVEODNEXFx1REM2OVxcdTIwMEQpP1xcdUQ4M0RcXHVEQzY2KXxcXHVEODNDW1xcdURGRkItXFx1REZGRl0pfFxcdUQ4M0RcXHVEQzY5XFx1MjAwRCg/OlxcdUQ4M0RcXHVEQzY5XFx1MjAwRCk/XFx1RDgzRFxcdURDNjZcXHUyMDBEXFx1RDgzRFxcdURDNjZ8XFx1RDgzRFxcdURDNjlcXHUyMDBEKD86XFx1RDgzRFxcdURDNjlcXHUyMDBEKT9cXHVEODNEXFx1REM2N1xcdTIwMEQoPzpcXHVEODNEW1xcdURDNjZcXHVEQzY3XSl8XFx1RDgzQ1xcdURGRjNcXHVGRTBGXFx1MjAwRFxcdUQ4M0NcXHVERjA4fCg/OlxcdUQ4M0NbXFx1REZDM1xcdURGQzRcXHVERkNBXXxcXHVEODNEW1xcdURDNkVcXHVEQzcxXFx1REM3M1xcdURDNzdcXHVEQzgxXFx1REM4MlxcdURDODZcXHVEQzg3XFx1REU0NS1cXHVERTQ3XFx1REU0QlxcdURFNERcXHVERTRFXFx1REVBM1xcdURFQjQtXFx1REVCNl18XFx1RDgzRVtcXHVERDI2XFx1REQzNy1cXHVERDM5XFx1REQzRFxcdUREM0VcXHVEREQ2LVxcdURERERdKSg/OlxcdUQ4M0NbXFx1REZGQi1cXHVERkZGXSlcXHUyMDBEW1xcdTI2NDBcXHUyNjQyXVxcdUZFMEZ8XFx1RDgzRFxcdURDNjkoPzpcXHVEODNDW1xcdURGRkItXFx1REZGRl0pXFx1MjAwRCg/OlxcdUQ4M0NbXFx1REYzRVxcdURGNzNcXHVERjkzXFx1REZBNFxcdURGQThcXHVERkVCXFx1REZFRF18XFx1RDgzRFtcXHVEQ0JCXFx1RENCQ1xcdUREMjdcXHVERDJDXFx1REU4MFxcdURFOTJdKXwoPzpcXHVEODNDW1xcdURGQzNcXHVERkM0XFx1REZDQV18XFx1RDgzRFtcXHVEQzZFXFx1REM2RlxcdURDNzFcXHVEQzczXFx1REM3N1xcdURDODFcXHVEQzgyXFx1REM4NlxcdURDODdcXHVERTQ1LVxcdURFNDdcXHVERTRCXFx1REU0RFxcdURFNEVcXHVERUEzXFx1REVCNC1cXHVERUI2XXxcXHVEODNFW1xcdUREMjZcXHVERDM3LVxcdUREMzlcXHVERDNDLVxcdUREM0VcXHVEREQ2LVxcdUREREZdKVxcdTIwMERbXFx1MjY0MFxcdTI2NDJdXFx1RkUwRnxcXHVEODNDXFx1RERGRFxcdUQ4M0NcXHVEREYwfFxcdUQ4M0NcXHVEREY2XFx1RDgzQ1xcdURERTZ8XFx1RDgzQ1xcdURERjRcXHVEODNDXFx1RERGMnxcXHVEODNDXFx1RERFOSg/OlxcdUQ4M0NbXFx1RERFQVxcdURERUNcXHVEREVGXFx1RERGMFxcdURERjJcXHVEREY0XFx1RERGRl0pfFxcdUQ4M0NcXHVEREY3KD86XFx1RDgzQ1tcXHVEREVBXFx1RERGNFxcdURERjhcXHVEREZBXFx1RERGQ10pfFxcdUQ4M0NcXHVEREU4KD86XFx1RDgzQ1tcXHVEREU2XFx1RERFOFxcdURERTlcXHVEREVCLVxcdURERUVcXHVEREYwLVxcdURERjVcXHVEREY3XFx1RERGQS1cXHVEREZGXSl8KD86XFx1MjZGOXxcXHVEODNDW1xcdURGQ0JcXHVERkNDXXxcXHVEODNEXFx1REQ3NSkoPzpcXHVGRTBGXFx1MjAwRFtcXHUyNjQwXFx1MjY0Ml18KD86XFx1RDgzQ1tcXHVERkZCLVxcdURGRkZdKVxcdTIwMERbXFx1MjY0MFxcdTI2NDJdKVxcdUZFMEZ8KD86XFx1RDgzRFxcdURDNDFcXHVGRTBGXFx1MjAwRFxcdUQ4M0RcXHVEREU4fFxcdUQ4M0RcXHVEQzY5KD86XFx1RDgzQ1tcXHVERkZCLVxcdURGRkZdKVxcdTIwMERbXFx1MjY5NVxcdTI2OTZcXHUyNzA4XXxcXHVEODNEXFx1REM2OVxcdTIwMERbXFx1MjY5NVxcdTI2OTZcXHUyNzA4XXxcXHVEODNEXFx1REM2OCg/Oig/OlxcdUQ4M0NbXFx1REZGQi1cXHVERkZGXSlcXHUyMDBEW1xcdTI2OTVcXHUyNjk2XFx1MjcwOF18XFx1MjAwRFtcXHUyNjk1XFx1MjY5NlxcdTI3MDhdKSlcXHVGRTBGfFxcdUQ4M0NcXHVEREYyKD86XFx1RDgzQ1tcXHVEREU2XFx1RERFOC1cXHVEREVEXFx1RERGMC1cXHVEREZGXSl8XFx1RDgzRFxcdURDNjlcXHUyMDBEKD86XFx1RDgzQ1tcXHVERjNFXFx1REY3M1xcdURGOTNcXHVERkE0XFx1REZBOFxcdURGRUJcXHVERkVEXXxcXHVEODNEW1xcdURDQkJcXHVEQ0JDXFx1REQyN1xcdUREMkNcXHVERTgwXFx1REU5Ml18XFx1Mjc2NFxcdUZFMEZcXHUyMDBEKD86XFx1RDgzRFxcdURDOEJcXHUyMDBEKD86XFx1RDgzRFtcXHVEQzY4XFx1REM2OV0pfFxcdUQ4M0RbXFx1REM2OFxcdURDNjldKSl8XFx1RDgzQ1xcdURERjEoPzpcXHVEODNDW1xcdURERTYtXFx1RERFOFxcdURERUVcXHVEREYwXFx1RERGNy1cXHVEREZCXFx1RERGRV0pfFxcdUQ4M0NcXHVEREVGKD86XFx1RDgzQ1tcXHVEREVBXFx1RERGMlxcdURERjRcXHVEREY1XSl8XFx1RDgzQ1xcdURERUQoPzpcXHVEODNDW1xcdURERjBcXHVEREYyXFx1RERGM1xcdURERjdcXHVEREY5XFx1RERGQV0pfFxcdUQ4M0NcXHVEREVCKD86XFx1RDgzQ1tcXHVEREVFLVxcdURERjBcXHVEREYyXFx1RERGNFxcdURERjddKXxbI1xcKjAtOV1cXHVGRTBGXFx1MjBFM3xcXHVEODNDXFx1RERFNyg/OlxcdUQ4M0NbXFx1RERFNlxcdURERTdcXHVEREU5LVxcdURERUZcXHVEREYxLVxcdURERjRcXHVEREY2LVxcdURERjlcXHVEREZCXFx1RERGQ1xcdURERkVcXHVEREZGXSl8XFx1RDgzQ1xcdURERTYoPzpcXHVEODNDW1xcdURERTgtXFx1RERFQ1xcdURERUVcXHVEREYxXFx1RERGMlxcdURERjRcXHVEREY2LVxcdURERkFcXHVEREZDXFx1RERGRFxcdURERkZdKXxcXHVEODNDXFx1RERGRig/OlxcdUQ4M0NbXFx1RERFNlxcdURERjJcXHVEREZDXSl8XFx1RDgzQ1xcdURERjUoPzpcXHVEODNDW1xcdURERTZcXHVEREVBLVxcdURERURcXHVEREYwLVxcdURERjNcXHVEREY3LVxcdURERjlcXHVEREZDXFx1RERGRV0pfFxcdUQ4M0NcXHVEREZCKD86XFx1RDgzQ1tcXHVEREU2XFx1RERFOFxcdURERUFcXHVEREVDXFx1RERFRVxcdURERjNcXHVEREZBXSl8XFx1RDgzQ1xcdURERjMoPzpcXHVEODNDW1xcdURERTZcXHVEREU4XFx1RERFQS1cXHVEREVDXFx1RERFRVxcdURERjFcXHVEREY0XFx1RERGNVxcdURERjdcXHVEREZBXFx1RERGRl0pfFxcdUQ4M0NcXHVERkY0XFx1REI0MFxcdURDNjdcXHVEQjQwXFx1REM2Mig/OlxcdURCNDBcXHVEQzc3XFx1REI0MFxcdURDNkNcXHVEQjQwXFx1REM3M3xcXHVEQjQwXFx1REM3M1xcdURCNDBcXHVEQzYzXFx1REI0MFxcdURDNzR8XFx1REI0MFxcdURDNjVcXHVEQjQwXFx1REM2RVxcdURCNDBcXHVEQzY3KVxcdURCNDBcXHVEQzdGfFxcdUQ4M0RcXHVEQzY4KD86XFx1MjAwRCg/OlxcdTI3NjRcXHVGRTBGXFx1MjAwRCg/OlxcdUQ4M0RcXHVEQzhCXFx1MjAwRCk/XFx1RDgzRFxcdURDNjh8KD86KD86XFx1RDgzRFtcXHVEQzY4XFx1REM2OV0pXFx1MjAwRCk/XFx1RDgzRFxcdURDNjZcXHUyMDBEXFx1RDgzRFxcdURDNjZ8KD86KD86XFx1RDgzRFtcXHVEQzY4XFx1REM2OV0pXFx1MjAwRCk/XFx1RDgzRFxcdURDNjdcXHUyMDBEKD86XFx1RDgzRFtcXHVEQzY2XFx1REM2N10pfFxcdUQ4M0NbXFx1REYzRVxcdURGNzNcXHVERjkzXFx1REZBNFxcdURGQThcXHVERkVCXFx1REZFRF18XFx1RDgzRFtcXHVEQ0JCXFx1RENCQ1xcdUREMjdcXHVERDJDXFx1REU4MFxcdURFOTJdKXwoPzpcXHVEODNDW1xcdURGRkItXFx1REZGRl0pXFx1MjAwRCg/OlxcdUQ4M0NbXFx1REYzRVxcdURGNzNcXHVERjkzXFx1REZBNFxcdURGQThcXHVERkVCXFx1REZFRF18XFx1RDgzRFtcXHVEQ0JCXFx1RENCQ1xcdUREMjdcXHVERDJDXFx1REU4MFxcdURFOTJdKSl8XFx1RDgzQ1xcdURERjgoPzpcXHVEODNDW1xcdURERTYtXFx1RERFQVxcdURERUMtXFx1RERGNFxcdURERjctXFx1RERGOVxcdURERkJcXHVEREZELVxcdURERkZdKXxcXHVEODNDXFx1RERGMCg/OlxcdUQ4M0NbXFx1RERFQVxcdURERUMtXFx1RERFRVxcdURERjJcXHVEREYzXFx1RERGNVxcdURERjdcXHVEREZDXFx1RERGRVxcdURERkZdKXxcXHVEODNDXFx1RERGRSg/OlxcdUQ4M0NbXFx1RERFQVxcdURERjldKXxcXHVEODNDXFx1RERFRSg/OlxcdUQ4M0NbXFx1RERFOC1cXHVEREVBXFx1RERGMS1cXHVEREY0XFx1RERGNi1cXHVEREY5XSl8XFx1RDgzQ1xcdURERjkoPzpcXHVEODNDW1xcdURERTZcXHVEREU4XFx1RERFOVxcdURERUItXFx1RERFRFxcdURERUYtXFx1RERGNFxcdURERjdcXHVEREY5XFx1RERGQlxcdURERkNcXHVEREZGXSl8XFx1RDgzQ1xcdURERUMoPzpcXHVEODNDW1xcdURERTZcXHVEREU3XFx1RERFOS1cXHVEREVFXFx1RERGMS1cXHVEREYzXFx1RERGNS1cXHVEREZBXFx1RERGQ1xcdURERkVdKXxcXHVEODNDXFx1RERGQSg/OlxcdUQ4M0NbXFx1RERFNlxcdURERUNcXHVEREYyXFx1RERGM1xcdURERjhcXHVEREZFXFx1RERGRl0pfFxcdUQ4M0NcXHVEREVBKD86XFx1RDgzQ1tcXHVEREU2XFx1RERFOFxcdURERUFcXHVEREVDXFx1RERFRFxcdURERjctXFx1RERGQV0pfFxcdUQ4M0NcXHVEREZDKD86XFx1RDgzQ1tcXHVEREVCXFx1RERGOF0pfCg/OlxcdTI2Rjl8XFx1RDgzQ1tcXHVERkNCXFx1REZDQ118XFx1RDgzRFxcdURENzUpKD86XFx1RDgzQ1tcXHVERkZCLVxcdURGRkZdKXwoPzpcXHVEODNDW1xcdURGQzNcXHVERkM0XFx1REZDQV18XFx1RDgzRFtcXHVEQzZFXFx1REM3MVxcdURDNzNcXHVEQzc3XFx1REM4MVxcdURDODJcXHVEQzg2XFx1REM4N1xcdURFNDUtXFx1REU0N1xcdURFNEJcXHVERTREXFx1REU0RVxcdURFQTNcXHVERUI0LVxcdURFQjZdfFxcdUQ4M0VbXFx1REQyNlxcdUREMzctXFx1REQzOVxcdUREM0RcXHVERDNFXFx1RERENi1cXHVEREREXSkoPzpcXHVEODNDW1xcdURGRkItXFx1REZGRl0pfCg/OltcXHUyNjFEXFx1MjcwQS1cXHUyNzBEXXxcXHVEODNDW1xcdURGODVcXHVERkMyXFx1REZDN118XFx1RDgzRFtcXHVEQzQyXFx1REM0M1xcdURDNDYtXFx1REM1MFxcdURDNjZcXHVEQzY3XFx1REM3MFxcdURDNzJcXHVEQzc0LVxcdURDNzZcXHVEQzc4XFx1REM3Q1xcdURDODNcXHVEQzg1XFx1RENBQVxcdURENzRcXHVERDdBXFx1REQ5MFxcdUREOTVcXHVERDk2XFx1REU0Q1xcdURFNEZcXHVERUMwXFx1REVDQ118XFx1RDgzRVtcXHVERDE4LVxcdUREMUNcXHVERDFFXFx1REQxRlxcdUREMzAtXFx1REQzNlxcdURERDEtXFx1RERENV0pKD86XFx1RDgzQ1tcXHVERkZCLVxcdURGRkZdKXxcXHVEODNEXFx1REM2OCg/OlxcdTIwMEQoPzooPzooPzpcXHVEODNEW1xcdURDNjhcXHVEQzY5XSlcXHUyMDBEKT9cXHVEODNEXFx1REM2N3woPzooPzpcXHVEODNEW1xcdURDNjhcXHVEQzY5XSlcXHUyMDBEKT9cXHVEODNEXFx1REM2Nil8XFx1RDgzQ1tcXHVERkZCLVxcdURGRkZdKXwoPzpbXFx1MjYxRFxcdTI2RjlcXHUyNzBBLVxcdTI3MERdfFxcdUQ4M0NbXFx1REY4NVxcdURGQzItXFx1REZDNFxcdURGQzdcXHVERkNBLVxcdURGQ0NdfFxcdUQ4M0RbXFx1REM0MlxcdURDNDNcXHVEQzQ2LVxcdURDNTBcXHVEQzY2LVxcdURDNjlcXHVEQzZFXFx1REM3MC1cXHVEQzc4XFx1REM3Q1xcdURDODEtXFx1REM4M1xcdURDODUtXFx1REM4N1xcdURDQUFcXHVERDc0XFx1REQ3NVxcdUREN0FcXHVERDkwXFx1REQ5NVxcdUREOTZcXHVERTQ1LVxcdURFNDdcXHVERTRCLVxcdURFNEZcXHVERUEzXFx1REVCNC1cXHVERUI2XFx1REVDMFxcdURFQ0NdfFxcdUQ4M0VbXFx1REQxOC1cXHVERDFDXFx1REQxRVxcdUREMUZcXHVERDI2XFx1REQzMC1cXHVERDM5XFx1REQzRFxcdUREM0VcXHVEREQxLVxcdURERERdKSg/OlxcdUQ4M0NbXFx1REZGQi1cXHVERkZGXSk/fCg/OltcXHUyMzFBXFx1MjMxQlxcdTIzRTktXFx1MjNFQ1xcdTIzRjBcXHUyM0YzXFx1MjVGRFxcdTI1RkVcXHUyNjE0XFx1MjYxNVxcdTI2NDgtXFx1MjY1M1xcdTI2N0ZcXHUyNjkzXFx1MjZBMVxcdTI2QUFcXHUyNkFCXFx1MjZCRFxcdTI2QkVcXHUyNkM0XFx1MjZDNVxcdTI2Q0VcXHUyNkQ0XFx1MjZFQVxcdTI2RjJcXHUyNkYzXFx1MjZGNVxcdTI2RkFcXHUyNkZEXFx1MjcwNVxcdTI3MEFcXHUyNzBCXFx1MjcyOFxcdTI3NENcXHUyNzRFXFx1Mjc1My1cXHUyNzU1XFx1Mjc1N1xcdTI3OTUtXFx1Mjc5N1xcdTI3QjBcXHUyN0JGXFx1MkIxQlxcdTJCMUNcXHUyQjUwXFx1MkI1NV18XFx1RDgzQ1tcXHVEQzA0XFx1RENDRlxcdUREOEVcXHVERDkxLVxcdUREOUFcXHVEREU2LVxcdURERkZcXHVERTAxXFx1REUxQVxcdURFMkZcXHVERTMyLVxcdURFMzZcXHVERTM4LVxcdURFM0FcXHVERTUwXFx1REU1MVxcdURGMDAtXFx1REYyMFxcdURGMkQtXFx1REYzNVxcdURGMzctXFx1REY3Q1xcdURGN0UtXFx1REY5M1xcdURGQTAtXFx1REZDQVxcdURGQ0YtXFx1REZEM1xcdURGRTAtXFx1REZGMFxcdURGRjRcXHVERkY4LVxcdURGRkZdfFxcdUQ4M0RbXFx1REMwMC1cXHVEQzNFXFx1REM0MFxcdURDNDItXFx1RENGQ1xcdURDRkYtXFx1REQzRFxcdURENEItXFx1REQ0RVxcdURENTAtXFx1REQ2N1xcdUREN0FcXHVERDk1XFx1REQ5NlxcdUREQTRcXHVEREZCLVxcdURFNEZcXHVERTgwLVxcdURFQzVcXHVERUNDXFx1REVEMC1cXHVERUQyXFx1REVFQlxcdURFRUNcXHVERUY0LVxcdURFRjhdfFxcdUQ4M0VbXFx1REQxMC1cXHVERDNBXFx1REQzQy1cXHVERDNFXFx1REQ0MC1cXHVERDQ1XFx1REQ0Ny1cXHVERDRDXFx1REQ1MC1cXHVERDZCXFx1REQ4MC1cXHVERDk3XFx1RERDMFxcdURERDAtXFx1RERFNl0pfCg/OlsjXFwqMC05XFx4QTlcXHhBRVxcdTIwM0NcXHUyMDQ5XFx1MjEyMlxcdTIxMzlcXHUyMTk0LVxcdTIxOTlcXHUyMUE5XFx1MjFBQVxcdTIzMUFcXHUyMzFCXFx1MjMyOFxcdTIzQ0ZcXHUyM0U5LVxcdTIzRjNcXHUyM0Y4LVxcdTIzRkFcXHUyNEMyXFx1MjVBQVxcdTI1QUJcXHUyNUI2XFx1MjVDMFxcdTI1RkItXFx1MjVGRVxcdTI2MDAtXFx1MjYwNFxcdTI2MEVcXHUyNjExXFx1MjYxNFxcdTI2MTVcXHUyNjE4XFx1MjYxRFxcdTI2MjBcXHUyNjIyXFx1MjYyM1xcdTI2MjZcXHUyNjJBXFx1MjYyRVxcdTI2MkZcXHUyNjM4LVxcdTI2M0FcXHUyNjQwXFx1MjY0MlxcdTI2NDgtXFx1MjY1M1xcdTI2NjBcXHUyNjYzXFx1MjY2NVxcdTI2NjZcXHUyNjY4XFx1MjY3QlxcdTI2N0ZcXHUyNjkyLVxcdTI2OTdcXHUyNjk5XFx1MjY5QlxcdTI2OUNcXHUyNkEwXFx1MjZBMVxcdTI2QUFcXHUyNkFCXFx1MjZCMFxcdTI2QjFcXHUyNkJEXFx1MjZCRVxcdTI2QzRcXHUyNkM1XFx1MjZDOFxcdTI2Q0VcXHUyNkNGXFx1MjZEMVxcdTI2RDNcXHUyNkQ0XFx1MjZFOVxcdTI2RUFcXHUyNkYwLVxcdTI2RjVcXHUyNkY3LVxcdTI2RkFcXHUyNkZEXFx1MjcwMlxcdTI3MDVcXHUyNzA4LVxcdTI3MERcXHUyNzBGXFx1MjcxMlxcdTI3MTRcXHUyNzE2XFx1MjcxRFxcdTI3MjFcXHUyNzI4XFx1MjczM1xcdTI3MzRcXHUyNzQ0XFx1Mjc0N1xcdTI3NENcXHUyNzRFXFx1Mjc1My1cXHUyNzU1XFx1Mjc1N1xcdTI3NjNcXHUyNzY0XFx1Mjc5NS1cXHUyNzk3XFx1MjdBMVxcdTI3QjBcXHUyN0JGXFx1MjkzNFxcdTI5MzVcXHUyQjA1LVxcdTJCMDdcXHUyQjFCXFx1MkIxQ1xcdTJCNTBcXHUyQjU1XFx1MzAzMFxcdTMwM0RcXHUzMjk3XFx1MzI5OV18XFx1RDgzQ1tcXHVEQzA0XFx1RENDRlxcdURENzBcXHVERDcxXFx1REQ3RVxcdUREN0ZcXHVERDhFXFx1REQ5MS1cXHVERDlBXFx1RERFNi1cXHVEREZGXFx1REUwMVxcdURFMDJcXHVERTFBXFx1REUyRlxcdURFMzItXFx1REUzQVxcdURFNTBcXHVERTUxXFx1REYwMC1cXHVERjIxXFx1REYyNC1cXHVERjkzXFx1REY5NlxcdURGOTdcXHVERjk5LVxcdURGOUJcXHVERjlFLVxcdURGRjBcXHVERkYzLVxcdURGRjVcXHVERkY3LVxcdURGRkZdfFxcdUQ4M0RbXFx1REMwMC1cXHVEQ0ZEXFx1RENGRi1cXHVERDNEXFx1REQ0OS1cXHVERDRFXFx1REQ1MC1cXHVERDY3XFx1REQ2RlxcdURENzBcXHVERDczLVxcdUREN0FcXHVERDg3XFx1REQ4QS1cXHVERDhEXFx1REQ5MFxcdUREOTVcXHVERDk2XFx1RERBNFxcdUREQTVcXHVEREE4XFx1RERCMVxcdUREQjJcXHVEREJDXFx1RERDMi1cXHVEREM0XFx1REREMS1cXHVEREQzXFx1REREQy1cXHVERERFXFx1RERFMVxcdURERTNcXHVEREU4XFx1RERFRlxcdURERjNcXHVEREZBLVxcdURFNEZcXHVERTgwLVxcdURFQzVcXHVERUNCLVxcdURFRDJcXHVERUUwLVxcdURFRTVcXHVERUU5XFx1REVFQlxcdURFRUNcXHVERUYwXFx1REVGMy1cXHVERUY4XXxcXHVEODNFW1xcdUREMTAtXFx1REQzQVxcdUREM0MtXFx1REQzRVxcdURENDAtXFx1REQ0NVxcdURENDctXFx1REQ0Q1xcdURENTAtXFx1REQ2QlxcdUREODAtXFx1REQ5N1xcdUREQzBcXHVEREQwLVxcdURERTZdKVxcdUZFMEYpLztcblx0ZnVuY3Rpb24gZ2V0VGV4dChlKSB7XG5cdCAgdmFyIHR5cGUgPSBlLm5vZGVUeXBlLFxuXHQgICAgICByZXN1bHQgPSBcIlwiO1xuXG5cdCAgaWYgKHR5cGUgPT09IDEgfHwgdHlwZSA9PT0gOSB8fCB0eXBlID09PSAxMSkge1xuXHQgICAgaWYgKHR5cGVvZiBlLnRleHRDb250ZW50ID09PSBcInN0cmluZ1wiKSB7XG5cdCAgICAgIHJldHVybiBlLnRleHRDb250ZW50O1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgZm9yIChlID0gZS5maXJzdENoaWxkOyBlOyBlID0gZS5uZXh0U2libGluZykge1xuXHQgICAgICAgIHJlc3VsdCArPSBnZXRUZXh0KGUpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSBlbHNlIGlmICh0eXBlID09PSAzIHx8IHR5cGUgPT09IDQpIHtcblx0ICAgIHJldHVybiBlLm5vZGVWYWx1ZTtcblx0ICB9XG5cblx0ICByZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0LyohXG5cdCAqIFNwbGl0VGV4dDogMy4xMS41XG5cdCAqIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbVxuXHQgKlxuXHQgKiBAbGljZW5zZSBDb3B5cmlnaHQgMjAwOC0yMDIzLCBHcmVlblNvY2suIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cdCAqIFN1YmplY3QgdG8gdGhlIHRlcm1zIGF0IGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuXHQgKiBDbHViIEdyZWVuU29jayBtZW1iZXJzLCB0aGUgYWdyZWVtZW50IGlzc3VlZCB3aXRoIHRoYXQgbWVtYmVyc2hpcC5cblx0ICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG5cdCovXG5cblx0dmFyIF9kb2MsXG5cdCAgICBfd2luLFxuXHQgICAgX2NvcmVJbml0dGVkLFxuXHQgICAgZ3NhcCxcblx0ICAgIF9jb250ZXh0LFxuXHQgICAgX3RvQXJyYXksXG5cdCAgICBfc3RyaXBFeHAgPSAvKD86XFxyfFxcbnxcXHRcXHQpL2csXG5cdCAgICBfbXVsdGlwbGVTcGFjZXNFeHAgPSAvKD86XFxzXFxzKykvZyxcblx0ICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZShjb3JlKSB7XG5cdCAgX2RvYyA9IGRvY3VtZW50O1xuXHQgIF93aW4gPSB3aW5kb3c7XG5cdCAgZ3NhcCA9IGdzYXAgfHwgY29yZSB8fCBfd2luLmdzYXAgfHwgY29uc29sZS53YXJuKFwiUGxlYXNlIGdzYXAucmVnaXN0ZXJQbHVnaW4oU3BsaXRUZXh0KVwiKTtcblxuXHQgIGlmIChnc2FwKSB7XG5cdCAgICBfdG9BcnJheSA9IGdzYXAudXRpbHMudG9BcnJheTtcblxuXHQgICAgX2NvbnRleHQgPSBnc2FwLmNvcmUuY29udGV4dCB8fCBmdW5jdGlvbiAoKSB7fTtcblxuXHQgICAgX2NvcmVJbml0dGVkID0gMTtcblx0ICB9XG5cdH0sXG5cdCAgICBfZ2V0Q29tcHV0ZWRTdHlsZSA9IGZ1bmN0aW9uIF9nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcblx0ICByZXR1cm4gX3dpbi5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuXHR9LFxuXHQgICAgX2lzQWJzb2x1dGUgPSBmdW5jdGlvbiBfaXNBYnNvbHV0ZSh2YXJzKSB7XG5cdCAgcmV0dXJuIHZhcnMucG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCB2YXJzLmFic29sdXRlID09PSB0cnVlO1xuXHR9LFxuXHQgICAgX2ZpbmRTcGVjaWFsQ2hhcnMgPSBmdW5jdGlvbiBfZmluZFNwZWNpYWxDaGFycyh0ZXh0LCBjaGFycykge1xuXHQgIHZhciBpID0gY2hhcnMubGVuZ3RoLFxuXHQgICAgICBzO1xuXG5cdCAgd2hpbGUgKC0taSA+IC0xKSB7XG5cdCAgICBzID0gY2hhcnNbaV07XG5cblx0ICAgIGlmICh0ZXh0LnN1YnN0cigwLCBzLmxlbmd0aCkgPT09IHMpIHtcblx0ICAgICAgcmV0dXJuIHMubGVuZ3RoO1xuXHQgICAgfVxuXHQgIH1cblx0fSxcblx0ICAgIF9kaXZTdGFydCA9IFwiIHN0eWxlPSdwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmlubGluZS1ibG9jazsnXCIsXG5cdCAgICBfY3NzQ2xhc3NGdW5jID0gZnVuY3Rpb24gX2Nzc0NsYXNzRnVuYyhjc3NDbGFzcywgdGFnKSB7XG5cdCAgaWYgKGNzc0NsYXNzID09PSB2b2lkIDApIHtcblx0ICAgIGNzc0NsYXNzID0gXCJcIjtcblx0ICB9XG5cblx0ICB2YXIgaXRlcmF0ZSA9IH5jc3NDbGFzcy5pbmRleE9mKFwiKytcIiksXG5cdCAgICAgIG51bSA9IDE7XG5cblx0ICBpZiAoaXRlcmF0ZSkge1xuXHQgICAgY3NzQ2xhc3MgPSBjc3NDbGFzcy5zcGxpdChcIisrXCIpLmpvaW4oXCJcIik7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgIHJldHVybiBcIjxcIiArIHRhZyArIF9kaXZTdGFydCArIChjc3NDbGFzcyA/IFwiIGNsYXNzPSdcIiArIGNzc0NsYXNzICsgKGl0ZXJhdGUgPyBudW0rKyA6IFwiXCIpICsgXCInPlwiIDogXCI+XCIpO1xuXHQgIH07XG5cdH0sXG5cdCAgICBfc3dhcFRleHQgPSBmdW5jdGlvbiBfc3dhcFRleHQoZWxlbWVudCwgb2xkVGV4dCwgbmV3VGV4dCkge1xuXHQgIHZhciB0eXBlID0gZWxlbWVudC5ub2RlVHlwZTtcblxuXHQgIGlmICh0eXBlID09PSAxIHx8IHR5cGUgPT09IDkgfHwgdHlwZSA9PT0gMTEpIHtcblx0ICAgIGZvciAoZWxlbWVudCA9IGVsZW1lbnQuZmlyc3RDaGlsZDsgZWxlbWVudDsgZWxlbWVudCA9IGVsZW1lbnQubmV4dFNpYmxpbmcpIHtcblx0ICAgICAgX3N3YXBUZXh0KGVsZW1lbnQsIG9sZFRleHQsIG5ld1RleHQpO1xuXHQgICAgfVxuXHQgIH0gZWxzZSBpZiAodHlwZSA9PT0gMyB8fCB0eXBlID09PSA0KSB7XG5cdCAgICBlbGVtZW50Lm5vZGVWYWx1ZSA9IGVsZW1lbnQubm9kZVZhbHVlLnNwbGl0KG9sZFRleHQpLmpvaW4obmV3VGV4dCk7XG5cdCAgfVxuXHR9LFxuXHQgICAgX3B1c2hSZXZlcnNlZCA9IGZ1bmN0aW9uIF9wdXNoUmV2ZXJzZWQoYSwgbWVyZ2UpIHtcblx0ICB2YXIgaSA9IG1lcmdlLmxlbmd0aDtcblxuXHQgIHdoaWxlICgtLWkgPiAtMSkge1xuXHQgICAgYS5wdXNoKG1lcmdlW2ldKTtcblx0ICB9XG5cdH0sXG5cdCAgICBfaXNCZWZvcmVXb3JkRGVsaW1pdGVyID0gZnVuY3Rpb24gX2lzQmVmb3JlV29yZERlbGltaXRlcihlLCByb290LCB3b3JkRGVsaW1pdGVyKSB7XG5cdCAgdmFyIG5leHQ7XG5cblx0ICB3aGlsZSAoZSAmJiBlICE9PSByb290KSB7XG5cdCAgICBuZXh0ID0gZS5fbmV4dCB8fCBlLm5leHRTaWJsaW5nO1xuXG5cdCAgICBpZiAobmV4dCkge1xuXHQgICAgICByZXR1cm4gbmV4dC50ZXh0Q29udGVudC5jaGFyQXQoMCkgPT09IHdvcmREZWxpbWl0ZXI7XG5cdCAgICB9XG5cblx0ICAgIGUgPSBlLnBhcmVudE5vZGUgfHwgZS5fcGFyZW50O1xuXHQgIH1cblx0fSxcblx0ICAgIF9kZVdvcmRpZnkgPSBmdW5jdGlvbiBfZGVXb3JkaWZ5KGUpIHtcblx0ICB2YXIgY2hpbGRyZW4gPSBfdG9BcnJheShlLmNoaWxkTm9kZXMpLFxuXHQgICAgICBsID0gY2hpbGRyZW4ubGVuZ3RoLFxuXHQgICAgICBpLFxuXHQgICAgICBjaGlsZDtcblxuXHQgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcblx0ICAgIGNoaWxkID0gY2hpbGRyZW5baV07XG5cblx0ICAgIGlmIChjaGlsZC5faXNTcGxpdCkge1xuXHQgICAgICBfZGVXb3JkaWZ5KGNoaWxkKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGlmIChpICYmIGNoaWxkLnByZXZpb3VzU2libGluZyAmJiBjaGlsZC5wcmV2aW91c1NpYmxpbmcubm9kZVR5cGUgPT09IDMpIHtcblx0ICAgICAgICBjaGlsZC5wcmV2aW91c1NpYmxpbmcubm9kZVZhbHVlICs9IGNoaWxkLm5vZGVUeXBlID09PSAzID8gY2hpbGQubm9kZVZhbHVlIDogY2hpbGQuZmlyc3RDaGlsZC5ub2RlVmFsdWU7XG5cdCAgICAgICAgZS5yZW1vdmVDaGlsZChjaGlsZCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoY2hpbGQubm9kZVR5cGUgIT09IDMpIHtcblx0ICAgICAgICBlLmluc2VydEJlZm9yZShjaGlsZC5maXJzdENoaWxkLCBjaGlsZCk7XG5cdCAgICAgICAgZS5yZW1vdmVDaGlsZChjaGlsZCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cdH0sXG5cdCAgICBfZ2V0U3R5bGVBc051bWJlciA9IGZ1bmN0aW9uIF9nZXRTdHlsZUFzTnVtYmVyKG5hbWUsIGNvbXB1dGVkU3R5bGUpIHtcblx0ICByZXR1cm4gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlW25hbWVdKSB8fCAwO1xuXHR9LFxuXHQgICAgX3NldFBvc2l0aW9uc0FmdGVyU3BsaXQgPSBmdW5jdGlvbiBfc2V0UG9zaXRpb25zQWZ0ZXJTcGxpdChlbGVtZW50LCB2YXJzLCBhbGxDaGFycywgYWxsV29yZHMsIGFsbExpbmVzLCBvcmlnV2lkdGgsIG9yaWdIZWlnaHQpIHtcblx0ICB2YXIgY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcblx0ICAgICAgcGFkZGluZ0xlZnQgPSBfZ2V0U3R5bGVBc051bWJlcihcInBhZGRpbmdMZWZ0XCIsIGNzKSxcblx0ICAgICAgbGluZU9mZnNldFkgPSAtOTk5LFxuXHQgICAgICBib3JkZXJUb3BBbmRCb3R0b20gPSBfZ2V0U3R5bGVBc051bWJlcihcImJvcmRlckJvdHRvbVdpZHRoXCIsIGNzKSArIF9nZXRTdHlsZUFzTnVtYmVyKFwiYm9yZGVyVG9wV2lkdGhcIiwgY3MpLFxuXHQgICAgICBib3JkZXJMZWZ0QW5kUmlnaHQgPSBfZ2V0U3R5bGVBc051bWJlcihcImJvcmRlckxlZnRXaWR0aFwiLCBjcykgKyBfZ2V0U3R5bGVBc051bWJlcihcImJvcmRlclJpZ2h0V2lkdGhcIiwgY3MpLFxuXHQgICAgICBwYWRUb3BBbmRCb3R0b20gPSBfZ2V0U3R5bGVBc051bWJlcihcInBhZGRpbmdUb3BcIiwgY3MpICsgX2dldFN0eWxlQXNOdW1iZXIoXCJwYWRkaW5nQm90dG9tXCIsIGNzKSxcblx0ICAgICAgcGFkTGVmdEFuZFJpZ2h0ID0gX2dldFN0eWxlQXNOdW1iZXIoXCJwYWRkaW5nTGVmdFwiLCBjcykgKyBfZ2V0U3R5bGVBc051bWJlcihcInBhZGRpbmdSaWdodFwiLCBjcyksXG5cdCAgICAgIGxpbmVUaHJlc2hvbGQgPSBfZ2V0U3R5bGVBc051bWJlcihcImZvbnRTaXplXCIsIGNzKSAqICh2YXJzLmxpbmVUaHJlc2hvbGQgfHwgMC4yKSxcblx0ICAgICAgdGV4dEFsaWduID0gY3MudGV4dEFsaWduLFxuXHQgICAgICBjaGFyQXJyYXkgPSBbXSxcblx0ICAgICAgd29yZEFycmF5ID0gW10sXG5cdCAgICAgIGxpbmVBcnJheSA9IFtdLFxuXHQgICAgICB3b3JkRGVsaW1pdGVyID0gdmFycy53b3JkRGVsaW1pdGVyIHx8IFwiIFwiLFxuXHQgICAgICB0YWcgPSB2YXJzLnRhZyA/IHZhcnMudGFnIDogdmFycy5zcGFuID8gXCJzcGFuXCIgOiBcImRpdlwiLFxuXHQgICAgICB0eXBlcyA9IHZhcnMudHlwZSB8fCB2YXJzLnNwbGl0IHx8IFwiY2hhcnMsd29yZHMsbGluZXNcIixcblx0ICAgICAgbGluZXMgPSBhbGxMaW5lcyAmJiB+dHlwZXMuaW5kZXhPZihcImxpbmVzXCIpID8gW10gOiBudWxsLFxuXHQgICAgICB3b3JkcyA9IH50eXBlcy5pbmRleE9mKFwid29yZHNcIiksXG5cdCAgICAgIGNoYXJzID0gfnR5cGVzLmluZGV4T2YoXCJjaGFyc1wiKSxcblx0ICAgICAgYWJzb2x1dGUgPSBfaXNBYnNvbHV0ZSh2YXJzKSxcblx0ICAgICAgbGluZXNDbGFzcyA9IHZhcnMubGluZXNDbGFzcyxcblx0ICAgICAgaXRlcmF0ZUxpbmUgPSB+KGxpbmVzQ2xhc3MgfHwgXCJcIikuaW5kZXhPZihcIisrXCIpLFxuXHQgICAgICBzcGFjZU5vZGVzVG9SZW1vdmUgPSBbXSxcblx0ICAgICAgaXNGbGV4ID0gY3MuZGlzcGxheSA9PT0gXCJmbGV4XCIsXG5cdCAgICAgIHByZXZJbmxpbmVEaXNwbGF5ID0gZWxlbWVudC5zdHlsZS5kaXNwbGF5LFxuXHQgICAgICBpLFxuXHQgICAgICBqLFxuXHQgICAgICBsLFxuXHQgICAgICBub2RlLFxuXHQgICAgICBub2Rlcyxcblx0ICAgICAgaXNDaGlsZCxcblx0ICAgICAgY3VyTGluZSxcblx0ICAgICAgYWRkV29yZFNwYWNlcyxcblx0ICAgICAgc3R5bGUsXG5cdCAgICAgIGxpbmVOb2RlLFxuXHQgICAgICBsaW5lV2lkdGgsXG5cdCAgICAgIG9mZnNldDtcblxuXHQgIGl0ZXJhdGVMaW5lICYmIChsaW5lc0NsYXNzID0gbGluZXNDbGFzcy5zcGxpdChcIisrXCIpLmpvaW4oXCJcIikpO1xuXHQgIGlzRmxleCAmJiAoZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiKTtcblx0ICBqID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIik7XG5cdCAgbCA9IGoubGVuZ3RoO1xuXHQgIG5vZGVzID0gW107XG5cblx0ICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdCAgICBub2Rlc1tpXSA9IGpbaV07XG5cdCAgfVxuXG5cdCAgaWYgKGxpbmVzIHx8IGFic29sdXRlKSB7XG5cdCAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdCAgICAgIG5vZGUgPSBub2Rlc1tpXTtcblx0ICAgICAgaXNDaGlsZCA9IG5vZGUucGFyZW50Tm9kZSA9PT0gZWxlbWVudDtcblxuXHQgICAgICBpZiAoaXNDaGlsZCB8fCBhYnNvbHV0ZSB8fCBjaGFycyAmJiAhd29yZHMpIHtcblx0ICAgICAgICBvZmZzZXQgPSBub2RlLm9mZnNldFRvcDtcblxuXHQgICAgICAgIGlmIChsaW5lcyAmJiBpc0NoaWxkICYmIE1hdGguYWJzKG9mZnNldCAtIGxpbmVPZmZzZXRZKSA+IGxpbmVUaHJlc2hvbGQgJiYgKG5vZGUubm9kZU5hbWUgIT09IFwiQlJcIiB8fCBpID09PSAwKSkge1xuXHQgICAgICAgICAgY3VyTGluZSA9IFtdO1xuXHQgICAgICAgICAgbGluZXMucHVzaChjdXJMaW5lKTtcblx0ICAgICAgICAgIGxpbmVPZmZzZXRZID0gb2Zmc2V0O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChhYnNvbHV0ZSkge1xuXHQgICAgICAgICAgbm9kZS5feCA9IG5vZGUub2Zmc2V0TGVmdDtcblx0ICAgICAgICAgIG5vZGUuX3kgPSBvZmZzZXQ7XG5cdCAgICAgICAgICBub2RlLl93ID0gbm9kZS5vZmZzZXRXaWR0aDtcblx0ICAgICAgICAgIG5vZGUuX2ggPSBub2RlLm9mZnNldEhlaWdodDtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAobGluZXMpIHtcblx0ICAgICAgICAgIGlmIChub2RlLl9pc1NwbGl0ICYmIGlzQ2hpbGQgfHwgIWNoYXJzICYmIGlzQ2hpbGQgfHwgd29yZHMgJiYgaXNDaGlsZCB8fCAhd29yZHMgJiYgbm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUgPT09IGVsZW1lbnQgJiYgIW5vZGUucGFyZW50Tm9kZS5faXNTcGxpdCkge1xuXHQgICAgICAgICAgICBjdXJMaW5lLnB1c2gobm9kZSk7XG5cdCAgICAgICAgICAgIG5vZGUuX3ggLT0gcGFkZGluZ0xlZnQ7XG5cblx0ICAgICAgICAgICAgaWYgKF9pc0JlZm9yZVdvcmREZWxpbWl0ZXIobm9kZSwgZWxlbWVudCwgd29yZERlbGltaXRlcikpIHtcblx0ICAgICAgICAgICAgICBub2RlLl93b3JkRW5kID0gdHJ1ZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfVxuXG5cdCAgICAgICAgICBpZiAobm9kZS5ub2RlTmFtZSA9PT0gXCJCUlwiICYmIChub2RlLm5leHRTaWJsaW5nICYmIG5vZGUubmV4dFNpYmxpbmcubm9kZU5hbWUgPT09IFwiQlJcIiB8fCBpID09PSAwKSkge1xuXHQgICAgICAgICAgICBsaW5lcy5wdXNoKFtdKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cblx0ICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdCAgICBub2RlID0gbm9kZXNbaV07XG5cdCAgICBpc0NoaWxkID0gbm9kZS5wYXJlbnROb2RlID09PSBlbGVtZW50O1xuXG5cdCAgICBpZiAobm9kZS5ub2RlTmFtZSA9PT0gXCJCUlwiKSB7XG5cdCAgICAgIGlmIChsaW5lcyB8fCBhYnNvbHV0ZSkge1xuXHQgICAgICAgIG5vZGUucGFyZW50Tm9kZSAmJiBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG5cdCAgICAgICAgbm9kZXMuc3BsaWNlKGktLSwgMSk7XG5cdCAgICAgICAgbC0tO1xuXHQgICAgICB9IGVsc2UgaWYgKCF3b3Jkcykge1xuXHQgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQobm9kZSk7XG5cdCAgICAgIH1cblxuXHQgICAgICBjb250aW51ZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGFic29sdXRlKSB7XG5cdCAgICAgIHN0eWxlID0gbm9kZS5zdHlsZTtcblxuXHQgICAgICBpZiAoIXdvcmRzICYmICFpc0NoaWxkKSB7XG5cdCAgICAgICAgbm9kZS5feCArPSBub2RlLnBhcmVudE5vZGUuX3g7XG5cdCAgICAgICAgbm9kZS5feSArPSBub2RlLnBhcmVudE5vZGUuX3k7XG5cdCAgICAgIH1cblxuXHQgICAgICBzdHlsZS5sZWZ0ID0gbm9kZS5feCArIFwicHhcIjtcblx0ICAgICAgc3R5bGUudG9wID0gbm9kZS5feSArIFwicHhcIjtcblx0ICAgICAgc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG5cdCAgICAgIHN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG5cdCAgICAgIHN0eWxlLndpZHRoID0gbm9kZS5fdyArIDEgKyBcInB4XCI7XG5cdCAgICAgIHN0eWxlLmhlaWdodCA9IG5vZGUuX2ggKyBcInB4XCI7XG5cdCAgICB9XG5cblx0ICAgIGlmICghd29yZHMgJiYgY2hhcnMpIHtcblx0ICAgICAgaWYgKG5vZGUuX2lzU3BsaXQpIHtcblx0ICAgICAgICBub2RlLl9uZXh0ID0gaiA9IG5vZGUubmV4dFNpYmxpbmc7XG5cdCAgICAgICAgbm9kZS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKG5vZGUpO1xuXG5cdCAgICAgICAgd2hpbGUgKGogJiYgai5ub2RlVHlwZSA9PT0gMyAmJiBqLnRleHRDb250ZW50ID09PSBcIiBcIikge1xuXHQgICAgICAgICAgbm9kZS5fbmV4dCA9IGoubmV4dFNpYmxpbmc7XG5cdCAgICAgICAgICBub2RlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoaik7XG5cdCAgICAgICAgICBqID0gai5uZXh0U2libGluZztcblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSBpZiAobm9kZS5wYXJlbnROb2RlLl9pc1NwbGl0KSB7XG5cdCAgICAgICAgbm9kZS5fcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG5cdCAgICAgICAgaWYgKCFub2RlLnByZXZpb3VzU2libGluZyAmJiBub2RlLmZpcnN0Q2hpbGQpIHtcblx0ICAgICAgICAgIG5vZGUuZmlyc3RDaGlsZC5faXNGaXJzdCA9IHRydWU7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKG5vZGUubmV4dFNpYmxpbmcgJiYgbm9kZS5uZXh0U2libGluZy50ZXh0Q29udGVudCA9PT0gXCIgXCIgJiYgIW5vZGUubmV4dFNpYmxpbmcubmV4dFNpYmxpbmcpIHtcblx0ICAgICAgICAgIHNwYWNlTm9kZXNUb1JlbW92ZS5wdXNoKG5vZGUubmV4dFNpYmxpbmcpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIG5vZGUuX25leHQgPSBub2RlLm5leHRTaWJsaW5nICYmIG5vZGUubmV4dFNpYmxpbmcuX2lzRmlyc3QgPyBudWxsIDogbm9kZS5uZXh0U2libGluZztcblx0ICAgICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG5cdCAgICAgICAgbm9kZXMuc3BsaWNlKGktLSwgMSk7XG5cdCAgICAgICAgbC0tO1xuXHQgICAgICB9IGVsc2UgaWYgKCFpc0NoaWxkKSB7XG5cdCAgICAgICAgb2Zmc2V0ID0gIW5vZGUubmV4dFNpYmxpbmcgJiYgX2lzQmVmb3JlV29yZERlbGltaXRlcihub2RlLnBhcmVudE5vZGUsIGVsZW1lbnQsIHdvcmREZWxpbWl0ZXIpO1xuXHQgICAgICAgIG5vZGUucGFyZW50Tm9kZS5fcGFyZW50ICYmIG5vZGUucGFyZW50Tm9kZS5fcGFyZW50LmFwcGVuZENoaWxkKG5vZGUpO1xuXHQgICAgICAgIG9mZnNldCAmJiBub2RlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoX2RvYy5jcmVhdGVUZXh0Tm9kZShcIiBcIikpO1xuXG5cdCAgICAgICAgaWYgKHRhZyA9PT0gXCJzcGFuXCIpIHtcblx0ICAgICAgICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lXCI7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2hhckFycmF5LnB1c2gobm9kZSk7XG5cdCAgICAgIH1cblx0ICAgIH0gZWxzZSBpZiAobm9kZS5wYXJlbnROb2RlLl9pc1NwbGl0ICYmICFub2RlLl9pc1NwbGl0ICYmIG5vZGUuaW5uZXJIVE1MICE9PSBcIlwiKSB7XG5cdCAgICAgIHdvcmRBcnJheS5wdXNoKG5vZGUpO1xuXHQgICAgfSBlbHNlIGlmIChjaGFycyAmJiAhbm9kZS5faXNTcGxpdCkge1xuXHQgICAgICBpZiAodGFnID09PSBcInNwYW5cIikge1xuXHQgICAgICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lXCI7XG5cdCAgICAgIH1cblxuXHQgICAgICBjaGFyQXJyYXkucHVzaChub2RlKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBpID0gc3BhY2VOb2Rlc1RvUmVtb3ZlLmxlbmd0aDtcblxuXHQgIHdoaWxlICgtLWkgPiAtMSkge1xuXHQgICAgc3BhY2VOb2Rlc1RvUmVtb3ZlW2ldLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3BhY2VOb2Rlc1RvUmVtb3ZlW2ldKTtcblx0ICB9XG5cblx0ICBpZiAobGluZXMpIHtcblx0ICAgIGlmIChhYnNvbHV0ZSkge1xuXHQgICAgICBsaW5lTm9kZSA9IF9kb2MuY3JlYXRlRWxlbWVudCh0YWcpO1xuXHQgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGxpbmVOb2RlKTtcblx0ICAgICAgbGluZVdpZHRoID0gbGluZU5vZGUub2Zmc2V0V2lkdGggKyBcInB4XCI7XG5cdCAgICAgIG9mZnNldCA9IGxpbmVOb2RlLm9mZnNldFBhcmVudCA9PT0gZWxlbWVudCA/IDAgOiBlbGVtZW50Lm9mZnNldExlZnQ7XG5cdCAgICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQobGluZU5vZGUpO1xuXHQgICAgfVxuXG5cdCAgICBzdHlsZSA9IGVsZW1lbnQuc3R5bGUuY3NzVGV4dDtcblx0ICAgIGVsZW1lbnQuc3R5bGUuY3NzVGV4dCA9IFwiZGlzcGxheTpub25lO1wiO1xuXG5cdCAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7XG5cdCAgICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQoZWxlbWVudC5maXJzdENoaWxkKTtcblx0ICAgIH1cblxuXHQgICAgYWRkV29yZFNwYWNlcyA9IHdvcmREZWxpbWl0ZXIgPT09IFwiIFwiICYmICghYWJzb2x1dGUgfHwgIXdvcmRzICYmICFjaGFycyk7XG5cblx0ICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuXHQgICAgICBjdXJMaW5lID0gbGluZXNbaV07XG5cdCAgICAgIGxpbmVOb2RlID0gX2RvYy5jcmVhdGVFbGVtZW50KHRhZyk7XG5cdCAgICAgIGxpbmVOb2RlLnN0eWxlLmNzc1RleHQgPSBcImRpc3BsYXk6YmxvY2s7dGV4dC1hbGlnbjpcIiArIHRleHRBbGlnbiArIFwiO3Bvc2l0aW9uOlwiICsgKGFic29sdXRlID8gXCJhYnNvbHV0ZTtcIiA6IFwicmVsYXRpdmU7XCIpO1xuXG5cdCAgICAgIGlmIChsaW5lc0NsYXNzKSB7XG5cdCAgICAgICAgbGluZU5vZGUuY2xhc3NOYW1lID0gbGluZXNDbGFzcyArIChpdGVyYXRlTGluZSA/IGkgKyAxIDogXCJcIik7XG5cdCAgICAgIH1cblxuXHQgICAgICBsaW5lQXJyYXkucHVzaChsaW5lTm9kZSk7XG5cdCAgICAgIGwgPSBjdXJMaW5lLmxlbmd0aDtcblxuXHQgICAgICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG5cdCAgICAgICAgaWYgKGN1ckxpbmVbal0ubm9kZU5hbWUgIT09IFwiQlJcIikge1xuXHQgICAgICAgICAgbm9kZSA9IGN1ckxpbmVbal07XG5cdCAgICAgICAgICBsaW5lTm9kZS5hcHBlbmRDaGlsZChub2RlKTtcblx0ICAgICAgICAgIGFkZFdvcmRTcGFjZXMgJiYgbm9kZS5fd29yZEVuZCAmJiBsaW5lTm9kZS5hcHBlbmRDaGlsZChfZG9jLmNyZWF0ZVRleHROb2RlKFwiIFwiKSk7XG5cblx0ICAgICAgICAgIGlmIChhYnNvbHV0ZSkge1xuXHQgICAgICAgICAgICBpZiAoaiA9PT0gMCkge1xuXHQgICAgICAgICAgICAgIGxpbmVOb2RlLnN0eWxlLnRvcCA9IG5vZGUuX3kgKyBcInB4XCI7XG5cdCAgICAgICAgICAgICAgbGluZU5vZGUuc3R5bGUubGVmdCA9IHBhZGRpbmdMZWZ0ICsgb2Zmc2V0ICsgXCJweFwiO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgbm9kZS5zdHlsZS50b3AgPSBcIjBweFwiO1xuXG5cdCAgICAgICAgICAgIGlmIChvZmZzZXQpIHtcblx0ICAgICAgICAgICAgICBub2RlLnN0eWxlLmxlZnQgPSBub2RlLl94IC0gb2Zmc2V0ICsgXCJweFwiO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKGwgPT09IDApIHtcblx0ICAgICAgICBsaW5lTm9kZS5pbm5lckhUTUwgPSBcIiZuYnNwO1wiO1xuXHQgICAgICB9IGVsc2UgaWYgKCF3b3JkcyAmJiAhY2hhcnMpIHtcblx0ICAgICAgICBfZGVXb3JkaWZ5KGxpbmVOb2RlKTtcblxuXHQgICAgICAgIF9zd2FwVGV4dChsaW5lTm9kZSwgU3RyaW5nLmZyb21DaGFyQ29kZSgxNjApLCBcIiBcIik7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoYWJzb2x1dGUpIHtcblx0ICAgICAgICBsaW5lTm9kZS5zdHlsZS53aWR0aCA9IGxpbmVXaWR0aDtcblx0ICAgICAgICBsaW5lTm9kZS5zdHlsZS5oZWlnaHQgPSBub2RlLl9oICsgXCJweFwiO1xuXHQgICAgICB9XG5cblx0ICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lTm9kZSk7XG5cdCAgICB9XG5cblx0ICAgIGVsZW1lbnQuc3R5bGUuY3NzVGV4dCA9IHN0eWxlO1xuXHQgIH1cblxuXHQgIGlmIChhYnNvbHV0ZSkge1xuXHQgICAgaWYgKG9yaWdIZWlnaHQgPiBlbGVtZW50LmNsaWVudEhlaWdodCkge1xuXHQgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IG9yaWdIZWlnaHQgLSBwYWRUb3BBbmRCb3R0b20gKyBcInB4XCI7XG5cblx0ICAgICAgaWYgKGVsZW1lbnQuY2xpZW50SGVpZ2h0IDwgb3JpZ0hlaWdodCkge1xuXHQgICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gb3JpZ0hlaWdodCArIGJvcmRlclRvcEFuZEJvdHRvbSArIFwicHhcIjtcblx0ICAgICAgfVxuXHQgICAgfVxuXG5cdCAgICBpZiAob3JpZ1dpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aCkge1xuXHQgICAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gb3JpZ1dpZHRoIC0gcGFkTGVmdEFuZFJpZ2h0ICsgXCJweFwiO1xuXG5cdCAgICAgIGlmIChlbGVtZW50LmNsaWVudFdpZHRoIDwgb3JpZ1dpZHRoKSB7XG5cdCAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IG9yaWdXaWR0aCArIGJvcmRlckxlZnRBbmRSaWdodCArIFwicHhcIjtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblxuXHQgIGlzRmxleCAmJiAocHJldklubGluZURpc3BsYXkgPyBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBwcmV2SW5saW5lRGlzcGxheSA6IGVsZW1lbnQuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJkaXNwbGF5XCIpKTtcblxuXHQgIF9wdXNoUmV2ZXJzZWQoYWxsQ2hhcnMsIGNoYXJBcnJheSk7XG5cblx0ICB3b3JkcyAmJiBfcHVzaFJldmVyc2VkKGFsbFdvcmRzLCB3b3JkQXJyYXkpO1xuXG5cdCAgX3B1c2hSZXZlcnNlZChhbGxMaW5lcywgbGluZUFycmF5KTtcblx0fSxcblx0ICAgIF9zcGxpdFJhd1RleHQgPSBmdW5jdGlvbiBfc3BsaXRSYXdUZXh0KGVsZW1lbnQsIHZhcnMsIHdvcmRTdGFydCwgY2hhclN0YXJ0KSB7XG5cdCAgdmFyIHRhZyA9IHZhcnMudGFnID8gdmFycy50YWcgOiB2YXJzLnNwYW4gPyBcInNwYW5cIiA6IFwiZGl2XCIsXG5cdCAgICAgIHR5cGVzID0gdmFycy50eXBlIHx8IHZhcnMuc3BsaXQgfHwgXCJjaGFycyx3b3JkcyxsaW5lc1wiLFxuXHQgICAgICBjaGFycyA9IH50eXBlcy5pbmRleE9mKFwiY2hhcnNcIiksXG5cdCAgICAgIGFic29sdXRlID0gX2lzQWJzb2x1dGUodmFycyksXG5cdCAgICAgIHdvcmREZWxpbWl0ZXIgPSB2YXJzLndvcmREZWxpbWl0ZXIgfHwgXCIgXCIsXG5cdCAgICAgIHNwYWNlID0gd29yZERlbGltaXRlciAhPT0gXCIgXCIgPyBcIlwiIDogYWJzb2x1dGUgPyBcIiYjMTczOyBcIiA6IFwiIFwiLFxuXHQgICAgICB3b3JkRW5kID0gXCI8L1wiICsgdGFnICsgXCI+XCIsXG5cdCAgICAgIHdvcmRJc09wZW4gPSAxLFxuXHQgICAgICBzcGVjaWFsQ2hhcnMgPSB2YXJzLnNwZWNpYWxDaGFycyA/IHR5cGVvZiB2YXJzLnNwZWNpYWxDaGFycyA9PT0gXCJmdW5jdGlvblwiID8gdmFycy5zcGVjaWFsQ2hhcnMgOiBfZmluZFNwZWNpYWxDaGFycyA6IG51bGwsXG5cdCAgICAgIHRleHQsXG5cdCAgICAgIHNwbGl0VGV4dCxcblx0ICAgICAgaSxcblx0ICAgICAgaixcblx0ICAgICAgbCxcblx0ICAgICAgY2hhcmFjdGVyLFxuXHQgICAgICBoYXNUYWdTdGFydCxcblx0ICAgICAgdGVzdFJlc3VsdCxcblx0ICAgICAgY29udGFpbmVyID0gX2RvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuXHQgICAgICBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG5cblx0ICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNvbnRhaW5lciwgZWxlbWVudCk7XG5cdCAgY29udGFpbmVyLnRleHRDb250ZW50ID0gZWxlbWVudC5ub2RlVmFsdWU7XG5cdCAgcGFyZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuXHQgIGVsZW1lbnQgPSBjb250YWluZXI7XG5cdCAgdGV4dCA9IGdldFRleHQoZWxlbWVudCk7XG5cdCAgaGFzVGFnU3RhcnQgPSB0ZXh0LmluZGV4T2YoXCI8XCIpICE9PSAtMTtcblxuXHQgIGlmICh2YXJzLnJlZHVjZVdoaXRlU3BhY2UgIT09IGZhbHNlKSB7XG5cdCAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKF9tdWx0aXBsZVNwYWNlc0V4cCwgXCIgXCIpLnJlcGxhY2UoX3N0cmlwRXhwLCBcIlwiKTtcblx0ICB9XG5cblx0ICBpZiAoaGFzVGFnU3RhcnQpIHtcblx0ICAgIHRleHQgPSB0ZXh0LnNwbGl0KFwiPFwiKS5qb2luKFwie3tMVH19XCIpO1xuXHQgIH1cblxuXHQgIGwgPSB0ZXh0Lmxlbmd0aDtcblx0ICBzcGxpdFRleHQgPSAodGV4dC5jaGFyQXQoMCkgPT09IFwiIFwiID8gc3BhY2UgOiBcIlwiKSArIHdvcmRTdGFydCgpO1xuXG5cdCAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuXHQgICAgY2hhcmFjdGVyID0gdGV4dC5jaGFyQXQoaSk7XG5cblx0ICAgIGlmIChzcGVjaWFsQ2hhcnMgJiYgKHRlc3RSZXN1bHQgPSBzcGVjaWFsQ2hhcnModGV4dC5zdWJzdHIoaSksIHZhcnMuc3BlY2lhbENoYXJzKSkpIHtcblx0ICAgICAgY2hhcmFjdGVyID0gdGV4dC5zdWJzdHIoaSwgdGVzdFJlc3VsdCB8fCAxKTtcblx0ICAgICAgc3BsaXRUZXh0ICs9IGNoYXJzICYmIGNoYXJhY3RlciAhPT0gXCIgXCIgPyBjaGFyU3RhcnQoKSArIGNoYXJhY3RlciArIFwiPC9cIiArIHRhZyArIFwiPlwiIDogY2hhcmFjdGVyO1xuXHQgICAgICBpICs9IHRlc3RSZXN1bHQgLSAxO1xuXHQgICAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPT09IHdvcmREZWxpbWl0ZXIgJiYgdGV4dC5jaGFyQXQoaSAtIDEpICE9PSB3b3JkRGVsaW1pdGVyICYmIGkpIHtcblx0ICAgICAgc3BsaXRUZXh0ICs9IHdvcmRJc09wZW4gPyB3b3JkRW5kIDogXCJcIjtcblx0ICAgICAgd29yZElzT3BlbiA9IDA7XG5cblx0ICAgICAgd2hpbGUgKHRleHQuY2hhckF0KGkgKyAxKSA9PT0gd29yZERlbGltaXRlcikge1xuXHQgICAgICAgIHNwbGl0VGV4dCArPSBzcGFjZTtcblx0ICAgICAgICBpKys7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoaSA9PT0gbCAtIDEpIHtcblx0ICAgICAgICBzcGxpdFRleHQgKz0gc3BhY2U7XG5cdCAgICAgIH0gZWxzZSBpZiAodGV4dC5jaGFyQXQoaSArIDEpICE9PSBcIilcIikge1xuXHQgICAgICAgIHNwbGl0VGV4dCArPSBzcGFjZSArIHdvcmRTdGFydCgpO1xuXHQgICAgICAgIHdvcmRJc09wZW4gPSAxO1xuXHQgICAgICB9XG5cdCAgICB9IGVsc2UgaWYgKGNoYXJhY3RlciA9PT0gXCJ7XCIgJiYgdGV4dC5zdWJzdHIoaSwgNikgPT09IFwie3tMVH19XCIpIHtcblx0ICAgICAgc3BsaXRUZXh0ICs9IGNoYXJzID8gY2hhclN0YXJ0KCkgKyBcInt7TFR9fVwiICsgXCI8L1wiICsgdGFnICsgXCI+XCIgOiBcInt7TFR9fVwiO1xuXHQgICAgICBpICs9IDU7XG5cdCAgICB9IGVsc2UgaWYgKGNoYXJhY3Rlci5jaGFyQ29kZUF0KDApID49IDB4RDgwMCAmJiBjaGFyYWN0ZXIuY2hhckNvZGVBdCgwKSA8PSAweERCRkYgfHwgdGV4dC5jaGFyQ29kZUF0KGkgKyAxKSA+PSAweEZFMDAgJiYgdGV4dC5jaGFyQ29kZUF0KGkgKyAxKSA8PSAweEZFMEYpIHtcblx0ICAgICAgaiA9ICgodGV4dC5zdWJzdHIoaSwgMTIpLnNwbGl0KGVtb2ppRXhwKSB8fCBbXSlbMV0gfHwgXCJcIikubGVuZ3RoIHx8IDI7XG5cdCAgICAgIHNwbGl0VGV4dCArPSBjaGFycyAmJiBjaGFyYWN0ZXIgIT09IFwiIFwiID8gY2hhclN0YXJ0KCkgKyB0ZXh0LnN1YnN0cihpLCBqKSArIFwiPC9cIiArIHRhZyArIFwiPlwiIDogdGV4dC5zdWJzdHIoaSwgaik7XG5cdCAgICAgIGkgKz0gaiAtIDE7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBzcGxpdFRleHQgKz0gY2hhcnMgJiYgY2hhcmFjdGVyICE9PSBcIiBcIiA/IGNoYXJTdGFydCgpICsgY2hhcmFjdGVyICsgXCI8L1wiICsgdGFnICsgXCI+XCIgOiBjaGFyYWN0ZXI7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgZWxlbWVudC5vdXRlckhUTUwgPSBzcGxpdFRleHQgKyAod29yZElzT3BlbiA/IHdvcmRFbmQgOiBcIlwiKTtcblx0ICBoYXNUYWdTdGFydCAmJiBfc3dhcFRleHQocGFyZW50LCBcInt7TFR9fVwiLCBcIjxcIik7XG5cdH0sXG5cdCAgICBfc3BsaXQgPSBmdW5jdGlvbiBfc3BsaXQoZWxlbWVudCwgdmFycywgd29yZFN0YXJ0LCBjaGFyU3RhcnQpIHtcblx0ICB2YXIgY2hpbGRyZW4gPSBfdG9BcnJheShlbGVtZW50LmNoaWxkTm9kZXMpLFxuXHQgICAgICBsID0gY2hpbGRyZW4ubGVuZ3RoLFxuXHQgICAgICBhYnNvbHV0ZSA9IF9pc0Fic29sdXRlKHZhcnMpLFxuXHQgICAgICBpLFxuXHQgICAgICBjaGlsZDtcblxuXHQgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAzIHx8IGwgPiAxKSB7XG5cdCAgICB2YXJzLmFic29sdXRlID0gZmFsc2U7XG5cblx0ICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcblx0ICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcblx0ICAgICAgY2hpbGQuX25leHQgPSBjaGlsZC5faXNGaXJzdCA9IGNoaWxkLl9wYXJlbnQgPSBjaGlsZC5fd29yZEVuZCA9IG51bGw7XG5cblx0ICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlICE9PSAzIHx8IC9cXFMrLy50ZXN0KGNoaWxkLm5vZGVWYWx1ZSkpIHtcblx0ICAgICAgICBpZiAoYWJzb2x1dGUgJiYgY2hpbGQubm9kZVR5cGUgIT09IDMgJiYgX2dldENvbXB1dGVkU3R5bGUoY2hpbGQpLmRpc3BsYXkgPT09IFwiaW5saW5lXCIpIHtcblx0ICAgICAgICAgIGNoaWxkLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHQgICAgICAgICAgY2hpbGQuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2hpbGQuX2lzU3BsaXQgPSB0cnVlO1xuXG5cdCAgICAgICAgX3NwbGl0KGNoaWxkLCB2YXJzLCB3b3JkU3RhcnQsIGNoYXJTdGFydCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgdmFycy5hYnNvbHV0ZSA9IGFic29sdXRlO1xuXHQgICAgZWxlbWVudC5faXNTcGxpdCA9IHRydWU7XG5cdCAgICByZXR1cm47XG5cdCAgfVxuXG5cdCAgX3NwbGl0UmF3VGV4dChlbGVtZW50LCB2YXJzLCB3b3JkU3RhcnQsIGNoYXJTdGFydCk7XG5cdH07XG5cblx0dmFyIFNwbGl0VGV4dCA9IGZ1bmN0aW9uICgpIHtcblx0ICBmdW5jdGlvbiBTcGxpdFRleHQoZWxlbWVudCwgdmFycykge1xuXHQgICAgX2NvcmVJbml0dGVkIHx8IF9pbml0Q29yZSgpO1xuXHQgICAgdGhpcy5lbGVtZW50cyA9IF90b0FycmF5KGVsZW1lbnQpO1xuXHQgICAgdGhpcy5jaGFycyA9IFtdO1xuXHQgICAgdGhpcy53b3JkcyA9IFtdO1xuXHQgICAgdGhpcy5saW5lcyA9IFtdO1xuXHQgICAgdGhpcy5fb3JpZ2luYWxzID0gW107XG5cdCAgICB0aGlzLnZhcnMgPSB2YXJzIHx8IHt9O1xuXG5cdCAgICBfY29udGV4dCh0aGlzKTtcblxuXHQgICAgIHRoaXMuc3BsaXQodmFycyk7XG5cdCAgfVxuXG5cdCAgdmFyIF9wcm90byA9IFNwbGl0VGV4dC5wcm90b3R5cGU7XG5cblx0ICBfcHJvdG8uc3BsaXQgPSBmdW5jdGlvbiBzcGxpdCh2YXJzKSB7XG5cdCAgICB0aGlzLmlzU3BsaXQgJiYgdGhpcy5yZXZlcnQoKTtcblx0ICAgIHRoaXMudmFycyA9IHZhcnMgPSB2YXJzIHx8IHRoaXMudmFycztcblx0ICAgIHRoaXMuX29yaWdpbmFscy5sZW5ndGggPSB0aGlzLmNoYXJzLmxlbmd0aCA9IHRoaXMud29yZHMubGVuZ3RoID0gdGhpcy5saW5lcy5sZW5ndGggPSAwO1xuXG5cdCAgICB2YXIgaSA9IHRoaXMuZWxlbWVudHMubGVuZ3RoLFxuXHQgICAgICAgIHRhZyA9IHZhcnMudGFnID8gdmFycy50YWcgOiB2YXJzLnNwYW4gPyBcInNwYW5cIiA6IFwiZGl2XCIsXG5cdCAgICAgICAgd29yZFN0YXJ0ID0gX2Nzc0NsYXNzRnVuYyh2YXJzLndvcmRzQ2xhc3MsIHRhZyksXG5cdCAgICAgICAgY2hhclN0YXJ0ID0gX2Nzc0NsYXNzRnVuYyh2YXJzLmNoYXJzQ2xhc3MsIHRhZyksXG5cdCAgICAgICAgb3JpZ0hlaWdodCxcblx0ICAgICAgICBvcmlnV2lkdGgsXG5cdCAgICAgICAgZTtcblxuXHQgICAgd2hpbGUgKC0taSA+IC0xKSB7XG5cdCAgICAgIGUgPSB0aGlzLmVsZW1lbnRzW2ldO1xuXHQgICAgICB0aGlzLl9vcmlnaW5hbHNbaV0gPSBlLmlubmVySFRNTDtcblx0ICAgICAgb3JpZ0hlaWdodCA9IGUuY2xpZW50SGVpZ2h0O1xuXHQgICAgICBvcmlnV2lkdGggPSBlLmNsaWVudFdpZHRoO1xuXG5cdCAgICAgIF9zcGxpdChlLCB2YXJzLCB3b3JkU3RhcnQsIGNoYXJTdGFydCk7XG5cblx0ICAgICAgX3NldFBvc2l0aW9uc0FmdGVyU3BsaXQoZSwgdmFycywgdGhpcy5jaGFycywgdGhpcy53b3JkcywgdGhpcy5saW5lcywgb3JpZ1dpZHRoLCBvcmlnSGVpZ2h0KTtcblx0ICAgIH1cblxuXHQgICAgdGhpcy5jaGFycy5yZXZlcnNlKCk7XG5cdCAgICB0aGlzLndvcmRzLnJldmVyc2UoKTtcblx0ICAgIHRoaXMubGluZXMucmV2ZXJzZSgpO1xuXHQgICAgdGhpcy5pc1NwbGl0ID0gdHJ1ZTtcblx0ICAgIHJldHVybiB0aGlzO1xuXHQgIH07XG5cblx0ICBfcHJvdG8ucmV2ZXJ0ID0gZnVuY3Rpb24gcmV2ZXJ0KCkge1xuXHQgICAgdmFyIG9yaWdpbmFscyA9IHRoaXMuX29yaWdpbmFscztcblxuXHQgICAgaWYgKCFvcmlnaW5hbHMpIHtcblx0ICAgICAgdGhyb3cgXCJyZXZlcnQoKSBjYWxsIHdhc24ndCBzY29wZWQgcHJvcGVybHkuXCI7XG5cdCAgICB9XG5cblx0ICAgIHRoaXMuZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZSwgaSkge1xuXHQgICAgICByZXR1cm4gZS5pbm5lckhUTUwgPSBvcmlnaW5hbHNbaV07XG5cdCAgICB9KTtcblx0ICAgIHRoaXMuY2hhcnMgPSBbXTtcblx0ICAgIHRoaXMud29yZHMgPSBbXTtcblx0ICAgIHRoaXMubGluZXMgPSBbXTtcblx0ICAgIHRoaXMuaXNTcGxpdCA9IGZhbHNlO1xuXHQgICAgcmV0dXJuIHRoaXM7XG5cdCAgfTtcblxuXHQgIFNwbGl0VGV4dC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoZWxlbWVudCwgdmFycykge1xuXHQgICAgcmV0dXJuIG5ldyBTcGxpdFRleHQoZWxlbWVudCwgdmFycyk7XG5cdCAgfTtcblxuXHQgIHJldHVybiBTcGxpdFRleHQ7XG5cdH0oKTtcblx0U3BsaXRUZXh0LnZlcnNpb24gPSBcIjMuMTEuNVwiO1xuXHRTcGxpdFRleHQucmVnaXN0ZXIgPSBfaW5pdENvcmU7XG5cblx0ZXhwb3J0cy5TcGxpdFRleHQgPSBTcGxpdFRleHQ7XG5cdGV4cG9ydHMuZGVmYXVsdCA9IFNwbGl0VGV4dDtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSkpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/gsap/dist/SplitText.js\n"); /***/ }), /***/ "./node_modules/gsap/gsap-core.js": /*!****************************************!*\ !*** ./node_modules/gsap/gsap-core.js ***! \****************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Animation\": () => (/* binding */ Animation),\n/* harmony export */ \"Back\": () => (/* binding */ Back),\n/* harmony export */ \"Bounce\": () => (/* binding */ Bounce),\n/* harmony export */ \"Circ\": () => (/* binding */ Circ),\n/* harmony export */ \"Cubic\": () => (/* binding */ Cubic),\n/* harmony export */ \"Elastic\": () => (/* binding */ Elastic),\n/* harmony export */ \"Expo\": () => (/* binding */ Expo),\n/* harmony export */ \"GSCache\": () => (/* binding */ GSCache),\n/* harmony export */ \"Linear\": () => (/* binding */ Linear),\n/* harmony export */ \"Power0\": () => (/* binding */ Power0),\n/* harmony export */ \"Power1\": () => (/* binding */ Power1),\n/* harmony export */ \"Power2\": () => (/* binding */ Power2),\n/* harmony export */ \"Power3\": () => (/* binding */ Power3),\n/* harmony export */ \"Power4\": () => (/* binding */ Power4),\n/* harmony export */ \"PropTween\": () => (/* binding */ PropTween),\n/* harmony export */ \"Quad\": () => (/* binding */ Quad),\n/* harmony export */ \"Quart\": () => (/* binding */ Quart),\n/* harmony export */ \"Quint\": () => (/* binding */ Quint),\n/* harmony export */ \"Sine\": () => (/* binding */ Sine),\n/* harmony export */ \"SteppedEase\": () => (/* binding */ SteppedEase),\n/* harmony export */ \"Strong\": () => (/* binding */ Strong),\n/* harmony export */ \"Timeline\": () => (/* binding */ Timeline),\n/* harmony export */ \"TimelineLite\": () => (/* binding */ Timeline),\n/* harmony export */ \"TimelineMax\": () => (/* binding */ Timeline),\n/* harmony export */ \"Tween\": () => (/* binding */ Tween),\n/* harmony export */ \"TweenLite\": () => (/* binding */ Tween),\n/* harmony export */ \"TweenMax\": () => (/* binding */ Tween),\n/* harmony export */ \"_checkPlugin\": () => (/* binding */ _checkPlugin),\n/* harmony export */ \"_colorExp\": () => (/* binding */ _colorExp),\n/* harmony export */ \"_colorStringFilter\": () => (/* binding */ _colorStringFilter),\n/* harmony export */ \"_config\": () => (/* binding */ _config),\n/* harmony export */ \"_forEachName\": () => (/* binding */ _forEachName),\n/* harmony export */ \"_getCache\": () => (/* binding */ _getCache),\n/* harmony export */ \"_getProperty\": () => (/* binding */ _getProperty),\n/* harmony export */ \"_getSetter\": () => (/* binding */ _getSetter),\n/* harmony export */ \"_isString\": () => (/* binding */ _isString),\n/* harmony export */ \"_isUndefined\": () => (/* binding */ _isUndefined),\n/* harmony export */ \"_missingPlugin\": () => (/* binding */ _missingPlugin),\n/* harmony export */ \"_numExp\": () => (/* binding */ _numExp),\n/* harmony export */ \"_numWithUnitExp\": () => (/* binding */ _numWithUnitExp),\n/* harmony export */ \"_parseRelative\": () => (/* binding */ _parseRelative),\n/* harmony export */ \"_plugins\": () => (/* binding */ _plugins),\n/* harmony export */ \"_relExp\": () => (/* binding */ _relExp),\n/* harmony export */ \"_removeLinkedListItem\": () => (/* binding */ _removeLinkedListItem),\n/* harmony export */ \"_renderComplexString\": () => (/* binding */ _renderComplexString),\n/* harmony export */ \"_replaceRandom\": () => (/* binding */ _replaceRandom),\n/* harmony export */ \"_round\": () => (/* binding */ _round),\n/* harmony export */ \"_roundModifier\": () => (/* binding */ _roundModifier),\n/* harmony export */ \"_setDefaults\": () => (/* binding */ _setDefaults),\n/* harmony export */ \"_sortPropTweensByPriority\": () => (/* binding */ _sortPropTweensByPriority),\n/* harmony export */ \"_ticker\": () => (/* binding */ _ticker),\n/* harmony export */ \"clamp\": () => (/* binding */ clamp),\n/* harmony export */ \"default\": () => (/* binding */ gsap),\n/* harmony export */ \"distribute\": () => (/* binding */ distribute),\n/* harmony export */ \"getUnit\": () => (/* binding */ getUnit),\n/* harmony export */ \"gsap\": () => (/* binding */ gsap),\n/* harmony export */ \"interpolate\": () => (/* binding */ interpolate),\n/* harmony export */ \"mapRange\": () => (/* binding */ mapRange),\n/* harmony export */ \"normalize\": () => (/* binding */ normalize),\n/* harmony export */ \"pipe\": () => (/* binding */ pipe),\n/* harmony export */ \"random\": () => (/* binding */ random),\n/* harmony export */ \"selector\": () => (/* binding */ selector),\n/* harmony export */ \"shuffle\": () => (/* binding */ shuffle),\n/* harmony export */ \"snap\": () => (/* binding */ snap),\n/* harmony export */ \"splitColor\": () => (/* binding */ splitColor),\n/* harmony export */ \"toArray\": () => (/* binding */ toArray),\n/* harmony export */ \"unitize\": () => (/* binding */ unitize),\n/* harmony export */ \"wrap\": () => (/* binding */ wrap),\n/* harmony export */ \"wrapYoyo\": () => (/* binding */ wrapYoyo)\n/* harmony export */ });\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\n/*!\n * GSAP 3.11.5\n * https://greensock.com\n *\n * @license Copyright 2008-2023, GreenSock. All rights reserved.\n * Subject to the terms at https://greensock.com/standard-license or for\n * Club GreenSock members, the agreement issued with that membership.\n * @author: Jack Doyle, jack@greensock.com\n*/\n\n/* eslint-disable */\nvar _config = {\n autoSleep: 120,\n force3D: \"auto\",\n nullTargetWarn: 1,\n units: {\n lineHeight: \"\"\n }\n},\n _defaults = {\n duration: .5,\n overwrite: false,\n delay: 0\n},\n _suppressOverwrites,\n _reverting,\n _context,\n _bigNum = 1e8,\n _tinyNum = 1 / _bigNum,\n _2PI = Math.PI * 2,\n _HALF_PI = _2PI / 4,\n _gsID = 0,\n _sqrt = Math.sqrt,\n _cos = Math.cos,\n _sin = Math.sin,\n _isString = function _isString(value) {\n return typeof value === \"string\";\n},\n _isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n _isNumber = function _isNumber(value) {\n return typeof value === \"number\";\n},\n _isUndefined = function _isUndefined(value) {\n return typeof value === \"undefined\";\n},\n _isObject = function _isObject(value) {\n return typeof value === \"object\";\n},\n _isNotFalse = function _isNotFalse(value) {\n return value !== false;\n},\n _windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _isFuncOrString = function _isFuncOrString(value) {\n return _isFunction(value) || _isString(value);\n},\n _isTypedArray = typeof ArrayBuffer === \"function\" && ArrayBuffer.isView || function () {},\n // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView().\n_isArray = Array.isArray,\n _strictNumExp = /(?:-?\\.?\\d|\\.)+/gi,\n //only numbers (including negatives and decimals) but NOT relative values.\n_numExp = /[-+=.]*\\d+[.e\\-+]*\\d*[e\\-+]*\\d*/g,\n //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8.\n_numWithUnitExp = /[-+=.]*\\d+[.e-]*\\d*[a-z%]*/g,\n _complexStringNumExp = /[-+=.]*\\d+\\.?\\d*(?:e-|e\\+)?\\d*/gi,\n //duplicate so that while we're looping through matches from exec(), it doesn't contaminate the lastIndex of _numExp which we use to search for colors too.\n_relExp = /[+-]=-?[.\\d]+/,\n _delimitedValueExp = /[^,'\"\\[\\]\\s]+/gi,\n // previously /[#\\-+.]*\\b[a-z\\d\\-=+%.]+/gi but didn't catch special characters.\n_unitExp = /^[+\\-=e\\s\\d]*\\d+[.\\d]*([a-z]*|%)\\s*$/i,\n _globalTimeline,\n _win,\n _coreInitted,\n _doc,\n _globals = {},\n _installScope = {},\n _coreReady,\n _install = function _install(scope) {\n return (_installScope = _merge(scope, _globals)) && gsap;\n},\n _missingPlugin = function _missingPlugin(property, value) {\n return console.warn(\"Invalid property\", property, \"set to\", value, \"Missing plugin? gsap.registerPlugin()\");\n},\n _warn = function _warn(message, suppress) {\n return !suppress && console.warn(message);\n},\n _addGlobal = function _addGlobal(name, obj) {\n return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals;\n},\n _emptyFunc = function _emptyFunc() {\n return 0;\n},\n _startAtRevertConfig = {\n suppressEvents: true,\n isStart: true,\n kill: false\n},\n _revertConfigNoKill = {\n suppressEvents: true,\n kill: false\n},\n _revertConfig = {\n suppressEvents: true\n},\n _reservedProps = {},\n _lazyTweens = [],\n _lazyLookup = {},\n _lastRenderedFrame,\n _plugins = {},\n _effects = {},\n _nextGCFrame = 30,\n _harnessPlugins = [],\n _callbackNames = \"\",\n _harness = function _harness(targets) {\n var target = targets[0],\n harnessPlugin,\n i;\n _isObject(target) || _isFunction(target) || (targets = [targets]);\n\n if (!(harnessPlugin = (target._gsap || {}).harness)) {\n // find the first target with a harness. We assume targets passed into an animation will be of similar type, meaning the same kind of harness can be used for them all (performance optimization)\n i = _harnessPlugins.length;\n\n while (i-- && !_harnessPlugins[i].targetTest(target)) {}\n\n harnessPlugin = _harnessPlugins[i];\n }\n\n i = targets.length;\n\n while (i--) {\n targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1);\n }\n\n return targets;\n},\n _getCache = function _getCache(target) {\n return target._gsap || _harness(toArray(target))[0]._gsap;\n},\n _getProperty = function _getProperty(target, property, v) {\n return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v;\n},\n _forEachName = function _forEachName(names, func) {\n return (names = names.split(\",\")).forEach(func) || names;\n},\n //split a comma-delimited list of names into an array, then run a forEach() function and return the split array (this is just a way to consolidate/shorten some code).\n_round = function _round(value) {\n return Math.round(value * 100000) / 100000 || 0;\n},\n _roundPrecise = function _roundPrecise(value) {\n return Math.round(value * 10000000) / 10000000 || 0;\n},\n // increased precision mostly for timing values.\n_parseRelative = function _parseRelative(start, value) {\n var operator = value.charAt(0),\n end = parseFloat(value.substr(2));\n start = parseFloat(start);\n return operator === \"+\" ? start + end : operator === \"-\" ? start - end : operator === \"*\" ? start * end : start / end;\n},\n _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) {\n //searches one array to find matches for any of the items in the toFind array. As soon as one is found, it returns true. It does NOT return all the matches; it's simply a boolean search.\n var l = toFind.length,\n i = 0;\n\n for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {}\n\n return i < l;\n},\n _lazyRender = function _lazyRender() {\n var l = _lazyTweens.length,\n a = _lazyTweens.slice(0),\n i,\n tween;\n\n _lazyLookup = {};\n _lazyTweens.length = 0;\n\n for (i = 0; i < l; i++) {\n tween = a[i];\n tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0);\n }\n},\n _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) {\n _lazyTweens.length && !_reverting && _lazyRender();\n animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt));\n _lazyTweens.length && !_reverting && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render.\n},\n _numericIfPossible = function _numericIfPossible(value) {\n var n = parseFloat(value);\n return (n || n === 0) && (value + \"\").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value;\n},\n _passThrough = function _passThrough(p) {\n return p;\n},\n _setDefaults = function _setDefaults(obj, defaults) {\n for (var p in defaults) {\n p in obj || (obj[p] = defaults[p]);\n }\n\n return obj;\n},\n _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) {\n return function (obj, defaults) {\n for (var p in defaults) {\n p in obj || p === \"duration\" && excludeDuration || p === \"ease\" || (obj[p] = defaults[p]);\n }\n };\n},\n _merge = function _merge(base, toMerge) {\n for (var p in toMerge) {\n base[p] = toMerge[p];\n }\n\n return base;\n},\n _mergeDeep = function _mergeDeep(base, toMerge) {\n for (var p in toMerge) {\n p !== \"__proto__\" && p !== \"constructor\" && p !== \"prototype\" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]);\n }\n\n return base;\n},\n _copyExcluding = function _copyExcluding(obj, excluding) {\n var copy = {},\n p;\n\n for (p in obj) {\n p in excluding || (copy[p] = obj[p]);\n }\n\n return copy;\n},\n _inheritDefaults = function _inheritDefaults(vars) {\n var parent = vars.parent || _globalTimeline,\n func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults;\n\n if (_isNotFalse(vars.inherit)) {\n while (parent) {\n func(vars, parent.vars.defaults);\n parent = parent.parent || parent._dp;\n }\n }\n\n return vars;\n},\n _arraysMatch = function _arraysMatch(a1, a2) {\n var i = a1.length,\n match = i === a2.length;\n\n while (match && i-- && a1[i] === a2[i]) {}\n\n return i < 0;\n},\n _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) {\n if (firstProp === void 0) {\n firstProp = \"_first\";\n }\n\n if (lastProp === void 0) {\n lastProp = \"_last\";\n }\n\n var prev = parent[lastProp],\n t;\n\n if (sortBy) {\n t = child[sortBy];\n\n while (prev && prev[sortBy] > t) {\n prev = prev._prev;\n }\n }\n\n if (prev) {\n child._next = prev._next;\n prev._next = child;\n } else {\n child._next = parent[firstProp];\n parent[firstProp] = child;\n }\n\n if (child._next) {\n child._next._prev = child;\n } else {\n parent[lastProp] = child;\n }\n\n child._prev = prev;\n child.parent = child._dp = parent;\n return child;\n},\n _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) {\n if (firstProp === void 0) {\n firstProp = \"_first\";\n }\n\n if (lastProp === void 0) {\n lastProp = \"_last\";\n }\n\n var prev = child._prev,\n next = child._next;\n\n if (prev) {\n prev._next = next;\n } else if (parent[firstProp] === child) {\n parent[firstProp] = next;\n }\n\n if (next) {\n next._prev = prev;\n } else if (parent[lastProp] === child) {\n parent[lastProp] = prev;\n }\n\n child._next = child._prev = child.parent = null; // don't delete the _dp just so we can revert if necessary. But parent should be null to indicate the item isn't in a linked list.\n},\n _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) {\n child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove(child);\n child._act = 0;\n},\n _uncache = function _uncache(animation, child) {\n if (animation && (!child || child._end > animation._dur || child._start < 0)) {\n // performance optimization: if a child animation is passed in we should only uncache if that child EXTENDS the animation (its end time is beyond the end)\n var a = animation;\n\n while (a) {\n a._dirty = 1;\n a = a.parent;\n }\n }\n\n return animation;\n},\n _recacheAncestors = function _recacheAncestors(animation) {\n var parent = animation.parent;\n\n while (parent && parent.parent) {\n //sometimes we must force a re-sort of all children and update the duration/totalDuration of all ancestor timelines immediately in case, for example, in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though.\n parent._dirty = 1;\n parent.totalDuration();\n parent = parent.parent;\n }\n\n return animation;\n},\n _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) {\n return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force));\n},\n _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) {\n return !animation || animation._ts && _hasNoPausedAncestors(animation.parent);\n},\n _elapsedCycleDuration = function _elapsedCycleDuration(animation) {\n return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0;\n},\n // feed in the totalTime and cycleDuration and it'll return the cycle (iteration minus 1) and if the playhead is exactly at the very END, it will NOT bump up to the next cycle.\n_animationCycle = function _animationCycle(tTime, cycleDuration) {\n var whole = Math.floor(tTime /= cycleDuration);\n return tTime && whole === tTime ? whole - 1 : whole;\n},\n _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) {\n return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur);\n},\n _setEnd = function _setEnd(animation) {\n return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0));\n},\n _alignPlayhead = function _alignPlayhead(animation, totalTime) {\n // adjusts the animation's _start and _end according to the provided totalTime (only if the parent's smoothChildTiming is true and the animation isn't paused). It doesn't do any rendering or forcing things back into parent timelines, etc. - that's what totalTime() is for.\n var parent = animation._dp;\n\n if (parent && parent.smoothChildTiming && animation._ts) {\n animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts));\n\n _setEnd(animation);\n\n parent._dirty || _uncache(parent, animation); //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here.\n }\n\n return animation;\n},\n\n/*\n_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => {\n\tlet cycleDuration = duration + repeatDelay,\n\t\ttime = _round(clampedTotalTime % cycleDuration);\n\tif (time > duration) {\n\t\ttime = duration;\n\t}\n\treturn (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time;\n},\n*/\n_postAddChecks = function _postAddChecks(timeline, child) {\n var t;\n\n if (child._time || child._initted && !child._dur) {\n //in case, for example, the _start is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.\n t = _parentToChildTotalTime(timeline.rawTime(), child);\n\n if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) {\n child.render(t, true);\n }\n } //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.\n\n\n if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) {\n //in case any of the ancestors had completed but should now be enabled...\n if (timeline._dur < timeline.duration()) {\n t = timeline;\n\n while (t._dp) {\n t.rawTime() >= 0 && t.totalTime(t._tTime); //moves the timeline (shifts its startTime) if necessary, and also enables it. If it's currently zero, though, it may not be scheduled to render until later so there's no need to force it to align with the current playhead position. Only move to catch up with the playhead.\n\n t = t._dp;\n }\n }\n\n timeline._zTime = -_tinyNum; // helps ensure that the next render() will be forced (crossingStart = true in render()), even if the duration hasn't changed (we're adding a child which would need to get rendered). Definitely an edge case. Note: we MUST do this AFTER the loop above where the totalTime() might trigger a render() because this _addToTimeline() method gets called from the Animation constructor, BEFORE tweens even record their targets, etc. so we wouldn't want things to get triggered in the wrong order.\n }\n},\n _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) {\n child.parent && _removeFromParent(child);\n child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay);\n child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0));\n\n _addLinkedListItem(timeline, child, \"_first\", \"_last\", timeline._sort ? \"_start\" : 0);\n\n _isFromOrFromStart(child) || (timeline._recent = child);\n skipChecks || _postAddChecks(timeline, child);\n timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime); // if the timeline is reversed and the new child makes it longer, we may need to adjust the parent's _start (push it back)\n\n return timeline;\n},\n _scrollTrigger = function _scrollTrigger(animation, trigger) {\n return (_globals.ScrollTrigger || _missingPlugin(\"scrollTrigger\", trigger)) && _globals.ScrollTrigger.create(trigger, animation);\n},\n _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) {\n _initTween(tween, time, tTime);\n\n if (!tween._initted) {\n return 1;\n }\n\n if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) {\n _lazyTweens.push(tween);\n\n tween._lazy = [tTime, suppressEvents];\n return 1;\n }\n},\n _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) {\n var parent = _ref.parent;\n return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent));\n},\n // check parent's _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn't force the ratio back to 0\n_isFromOrFromStart = function _isFromOrFromStart(_ref2) {\n var data = _ref2.data;\n return data === \"isFromStart\" || data === \"isStart\";\n},\n _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) {\n var prevRatio = tween.ratio,\n ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1,\n // if the tween or its parent is reversed and the totalTime is 0, we should go to a ratio of 0. Edge case: if a from() or fromTo() stagger tween is placed later in a timeline, the \"startAt\" zero-duration tween could initially render at a time when the parent timeline's playhead is technically BEFORE where this tween is, so make sure that any \"from\" and \"fromTo\" startAt tweens are rendered the first time at a ratio of 1.\n repeatDelay = tween._rDelay,\n tTime = 0,\n pt,\n iteration,\n prevIteration;\n\n if (repeatDelay && tween._repeat) {\n // in case there's a zero-duration tween that has a repeat with a repeatDelay\n tTime = _clamp(0, tween._tDur, totalTime);\n iteration = _animationCycle(tTime, repeatDelay);\n tween._yoyo && iteration & 1 && (ratio = 1 - ratio);\n\n if (iteration !== _animationCycle(tween._tTime, repeatDelay)) {\n // if iteration changed\n prevRatio = 1 - ratio;\n tween.vars.repeatRefresh && tween._initted && tween.invalidate();\n }\n }\n\n if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) {\n if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) {\n // if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.\n return;\n }\n\n prevIteration = tween._zTime;\n tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect.\n\n suppressEvents || (suppressEvents = totalTime && !prevIteration); // if it was rendered previously at exactly 0 (_zTime) and now the playhead is moving away, DON'T fire callbacks otherwise they'll seem like duplicates.\n\n tween.ratio = ratio;\n tween._from && (ratio = 1 - ratio);\n tween._time = 0;\n tween._tTime = tTime;\n pt = tween._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true);\n tween._onUpdate && !suppressEvents && _callback(tween, \"onUpdate\");\n tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, \"onRepeat\");\n\n if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) {\n ratio && _removeFromParent(tween, 1);\n\n if (!suppressEvents && !_reverting) {\n _callback(tween, ratio ? \"onComplete\" : \"onReverseComplete\", true);\n\n tween._prom && tween._prom();\n }\n }\n } else if (!tween._zTime) {\n tween._zTime = totalTime;\n }\n},\n _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) {\n var child;\n\n if (time > prevTime) {\n child = animation._first;\n\n while (child && child._start <= time) {\n if (child.data === \"isPause\" && child._start > prevTime) {\n return child;\n }\n\n child = child._next;\n }\n } else {\n child = animation._last;\n\n while (child && child._start >= time) {\n if (child.data === \"isPause\" && child._start < prevTime) {\n return child;\n }\n\n child = child._prev;\n }\n }\n},\n _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) {\n var repeat = animation._repeat,\n dur = _roundPrecise(duration) || 0,\n totalProgress = animation._tTime / animation._tDur;\n totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur);\n animation._dur = dur;\n animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat);\n totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress);\n animation.parent && _setEnd(animation);\n skipUncache || _uncache(animation.parent, animation);\n return animation;\n},\n _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) {\n return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur);\n},\n _zeroPosition = {\n _start: 0,\n endTime: _emptyFunc,\n totalDuration: _emptyFunc\n},\n _parsePosition = function _parsePosition(animation, position, percentAnimation) {\n var labels = animation.labels,\n recent = animation._recent || _zeroPosition,\n clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur,\n //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.\n i,\n offset,\n isPercent;\n\n if (_isString(position) && (isNaN(position) || position in labels)) {\n //if the string is a number like \"1\", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).\n offset = position.charAt(0);\n isPercent = position.substr(-1) === \"%\";\n i = position.indexOf(\"=\");\n\n if (offset === \"<\" || offset === \">\") {\n i >= 0 && (position = position.replace(/=/, \"\"));\n return (offset === \"<\" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1);\n }\n\n if (i < 0) {\n position in labels || (labels[position] = clippedDuration);\n return labels[position];\n }\n\n offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1));\n\n if (isPercent && percentAnimation) {\n offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration();\n }\n\n return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset;\n }\n\n return position == null ? clippedDuration : +position;\n},\n _createTweenType = function _createTweenType(type, params, timeline) {\n var isLegacy = _isNumber(params[1]),\n varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1),\n vars = params[varsIndex],\n irVars,\n parent;\n\n isLegacy && (vars.duration = params[1]);\n vars.parent = timeline;\n\n if (type) {\n irVars = vars;\n parent = timeline;\n\n while (parent && !(\"immediateRender\" in irVars)) {\n // inheritance hasn't happened yet, but someone may have set a default in an ancestor timeline. We could do vars.immediateRender = _isNotFalse(_inheritDefaults(vars).immediateRender) but that'd exact a slight performance penalty because _inheritDefaults() also runs in the Tween constructor. We're paying a small kb price here to gain speed.\n irVars = parent.vars.defaults || {};\n parent = _isNotFalse(parent.vars.inherit) && parent.parent;\n }\n\n vars.immediateRender = _isNotFalse(irVars.immediateRender);\n type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // \"from\" vars\n }\n\n return new Tween(params[0], vars, params[varsIndex + 1]);\n},\n _conditionalReturn = function _conditionalReturn(value, func) {\n return value || value === 0 ? func(value) : func;\n},\n _clamp = function _clamp(min, max, value) {\n return value < min ? min : value > max ? max : value;\n},\n getUnit = function getUnit(value, v) {\n return !_isString(value) || !(v = _unitExp.exec(value)) ? \"\" : v[1];\n},\n // note: protect against padded numbers as strings, like \"100.100\". That shouldn't return \"00\" as the unit. If it's numeric, return no unit.\nclamp = function clamp(min, max, value) {\n return _conditionalReturn(value, function (v) {\n return _clamp(min, max, v);\n });\n},\n _slice = [].slice,\n _isArrayLike = function _isArrayLike(value, nonEmpty) {\n return value && _isObject(value) && \"length\" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win;\n},\n _flatten = function _flatten(ar, leaveStrings, accumulator) {\n if (accumulator === void 0) {\n accumulator = [];\n }\n\n return ar.forEach(function (value) {\n var _accumulator;\n\n return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value);\n }) || accumulator;\n},\n //takes any value and returns an array. If it's a string (and leaveStrings isn't true), it'll use document.querySelectorAll() and convert that to an array. It'll also accept iterables like jQuery objects.\ntoArray = function toArray(value, scope, leaveStrings) {\n return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : [];\n},\n selector = function selector(value) {\n value = toArray(value)[0] || _warn(\"Invalid scope\") || {};\n return function (v) {\n var el = value.current || value.nativeElement || value;\n return toArray(v, el.querySelectorAll ? el : el === value ? _warn(\"Invalid scope\") || _doc.createElement(\"div\") : value);\n };\n},\n shuffle = function shuffle(a) {\n return a.sort(function () {\n return .5 - Math.random();\n });\n},\n // alternative that's a bit faster and more reliably diverse but bigger: for (let j, v, i = a.length; i; j = Math.floor(Math.random() * i), v = a[--i], a[i] = a[j], a[j] = v); return a;\n//for distributing values across an array. Can accept a number, a function or (most commonly) a function which can contain the following properties: {base, amount, from, ease, grid, axis, length, each}. Returns a function that expects the following parameters: index, target, array. Recognizes the following\ndistribute = function distribute(v) {\n if (_isFunction(v)) {\n return v;\n }\n\n var vars = _isObject(v) ? v : {\n each: v\n },\n //n:1 is just to indicate v was a number; we leverage that later to set v according to the length we get. If a number is passed in, we treat it like the old stagger value where 0.1, for example, would mean that things would be distributed with 0.1 between each element in the array rather than a total \"amount\" that's chunked out among them all.\n ease = _parseEase(vars.ease),\n from = vars.from || 0,\n base = parseFloat(vars.base) || 0,\n cache = {},\n isDecimal = from > 0 && from < 1,\n ratios = isNaN(from) || isDecimal,\n axis = vars.axis,\n ratioX = from,\n ratioY = from;\n\n if (_isString(from)) {\n ratioX = ratioY = {\n center: .5,\n edges: .5,\n end: 1\n }[from] || 0;\n } else if (!isDecimal && ratios) {\n ratioX = from[0];\n ratioY = from[1];\n }\n\n return function (i, target, a) {\n var l = (a || vars).length,\n distances = cache[l],\n originX,\n originY,\n x,\n y,\n d,\n j,\n max,\n min,\n wrapAt;\n\n if (!distances) {\n wrapAt = vars.grid === \"auto\" ? 0 : (vars.grid || [1, _bigNum])[1];\n\n if (!wrapAt) {\n max = -_bigNum;\n\n while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {}\n\n wrapAt--;\n }\n\n distances = cache[l] = [];\n originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt;\n originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0;\n max = 0;\n min = _bigNum;\n\n for (j = 0; j < l; j++) {\n x = j % wrapAt - originX;\n y = originY - (j / wrapAt | 0);\n distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === \"y\" ? y : x);\n d > max && (max = d);\n d < min && (min = d);\n }\n\n from === \"random\" && shuffle(distances);\n distances.max = max - min;\n distances.min = min;\n distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === \"y\" ? l / wrapAt : wrapAt) || 0) * (from === \"edges\" ? -1 : 1);\n distances.b = l < 0 ? base - l : base;\n distances.u = getUnit(vars.amount || vars.each) || 0; //unit\n\n ease = ease && l < 0 ? _invertEase(ease) : ease;\n }\n\n l = (distances[i] - distances.min) / distances.max || 0;\n return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors\n };\n},\n _roundModifier = function _roundModifier(v) {\n //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc.\n var p = Math.pow(10, ((v + \"\").split(\".\")[1] || \"\").length); //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed())\n\n return function (raw) {\n var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p);\n\n return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); // n - n % 1 replaces Math.floor() in order to handle negative values properly. For example, Math.floor(-150.00000000000003) is 151!\n };\n},\n snap = function snap(snapTo, value) {\n var isArray = _isArray(snapTo),\n radius,\n is2D;\n\n if (!isArray && _isObject(snapTo)) {\n radius = isArray = snapTo.radius || _bigNum;\n\n if (snapTo.values) {\n snapTo = toArray(snapTo.values);\n\n if (is2D = !_isNumber(snapTo[0])) {\n radius *= radius; //performance optimization so we don't have to Math.sqrt() in the loop.\n }\n } else {\n snapTo = _roundModifier(snapTo.increment);\n }\n }\n\n return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) {\n is2D = snapTo(raw);\n return Math.abs(is2D - raw) <= radius ? is2D : raw;\n } : function (raw) {\n var x = parseFloat(is2D ? raw.x : raw),\n y = parseFloat(is2D ? raw.y : 0),\n min = _bigNum,\n closest = 0,\n i = snapTo.length,\n dx,\n dy;\n\n while (i--) {\n if (is2D) {\n dx = snapTo[i].x - x;\n dy = snapTo[i].y - y;\n dx = dx * dx + dy * dy;\n } else {\n dx = Math.abs(snapTo[i] - x);\n }\n\n if (dx < min) {\n min = dx;\n closest = i;\n }\n }\n\n closest = !radius || min <= radius ? snapTo[closest] : raw;\n return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw);\n });\n},\n random = function random(min, max, roundingIncrement, returnFunction) {\n return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () {\n return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + \"\").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction;\n });\n},\n pipe = function pipe() {\n for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) {\n functions[_key] = arguments[_key];\n }\n\n return function (value) {\n return functions.reduce(function (v, f) {\n return f(v);\n }, value);\n };\n},\n unitize = function unitize(func, unit) {\n return function (value) {\n return func(parseFloat(value)) + (unit || getUnit(value));\n };\n},\n normalize = function normalize(min, max, value) {\n return mapRange(min, max, 0, 1, value);\n},\n _wrapArray = function _wrapArray(a, wrapper, value) {\n return _conditionalReturn(value, function (index) {\n return a[~~wrapper(index)];\n });\n},\n wrap = function wrap(min, max, value) {\n // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug causes problems (unrelated to GSAP).\n var range = max - min;\n return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) {\n return (range + (value - min) % range) % range + min;\n });\n},\n wrapYoyo = function wrapYoyo(min, max, value) {\n var range = max - min,\n total = range * 2;\n return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) {\n value = (total + (value - min) % total) % total || 0;\n return min + (value > range ? total - value : value);\n });\n},\n _replaceRandom = function _replaceRandom(value) {\n //replaces all occurrences of random(...) in a string with the calculated random value. can be a range like random(-100, 100, 5) or an array like random([0, 100, 500])\n var prev = 0,\n s = \"\",\n i,\n nums,\n end,\n isArray;\n\n while (~(i = value.indexOf(\"random(\", prev))) {\n end = value.indexOf(\")\", i);\n isArray = value.charAt(i + 7) === \"[\";\n nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp);\n s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5);\n prev = end + 1;\n }\n\n return s + value.substr(prev, value.length - prev);\n},\n mapRange = function mapRange(inMin, inMax, outMin, outMax, value) {\n var inRange = inMax - inMin,\n outRange = outMax - outMin;\n return _conditionalReturn(value, function (value) {\n return outMin + ((value - inMin) / inRange * outRange || 0);\n });\n},\n interpolate = function interpolate(start, end, progress, mutate) {\n var func = isNaN(start + end) ? 0 : function (p) {\n return (1 - p) * start + p * end;\n };\n\n if (!func) {\n var isString = _isString(start),\n master = {},\n p,\n i,\n interpolators,\n l,\n il;\n\n progress === true && (mutate = 1) && (progress = null);\n\n if (isString) {\n start = {\n p: start\n };\n end = {\n p: end\n };\n } else if (_isArray(start) && !_isArray(end)) {\n interpolators = [];\n l = start.length;\n il = l - 2;\n\n for (i = 1; i < l; i++) {\n interpolators.push(interpolate(start[i - 1], start[i])); //build the interpolators up front as a performance optimization so that when the function is called many times, it can just reuse them.\n }\n\n l--;\n\n func = function func(p) {\n p *= l;\n var i = Math.min(il, ~~p);\n return interpolators[i](p - i);\n };\n\n progress = end;\n } else if (!mutate) {\n start = _merge(_isArray(start) ? [] : {}, start);\n }\n\n if (!interpolators) {\n for (p in end) {\n _addPropTween.call(master, start, p, \"get\", end[p]);\n }\n\n func = function func(p) {\n return _renderPropTweens(p, master) || (isString ? start.p : start);\n };\n }\n }\n\n return _conditionalReturn(progress, func);\n},\n _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) {\n //used for nextLabel() and previousLabel()\n var labels = timeline.labels,\n min = _bigNum,\n p,\n distance,\n label;\n\n for (p in labels) {\n distance = labels[p] - fromTime;\n\n if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) {\n label = p;\n min = distance;\n }\n }\n\n return label;\n},\n _callback = function _callback(animation, type, executeLazyFirst) {\n var v = animation.vars,\n callback = v[type],\n prevContext = _context,\n context = animation._ctx,\n params,\n scope,\n result;\n\n if (!callback) {\n return;\n }\n\n params = v[type + \"Params\"];\n scope = v.callbackScope || animation;\n executeLazyFirst && _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.\n\n context && (_context = context);\n result = params ? callback.apply(scope, params) : callback.call(scope);\n _context = prevContext;\n return result;\n},\n _interrupt = function _interrupt(animation) {\n _removeFromParent(animation);\n\n animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting);\n animation.progress() < 1 && _callback(animation, \"onInterrupt\");\n return animation;\n},\n _quickTween,\n _registerPluginQueue = [],\n _createPlugin = function _createPlugin(config) {\n if (!_windowExists()) {\n _registerPluginQueue.push(config);\n\n return;\n }\n\n config = !config.name && config[\"default\"] || config; //UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}.\n\n var name = config.name,\n isFunc = _isFunction(config),\n Plugin = name && !isFunc && config.init ? function () {\n this._props = [];\n } : config,\n //in case someone passes in an object that's not a plugin, like CustomEase\n instanceDefaults = {\n init: _emptyFunc,\n render: _renderPropTweens,\n add: _addPropTween,\n kill: _killPropTweensOf,\n modifier: _addPluginModifier,\n rawVars: 0\n },\n statics = {\n targetTest: 0,\n get: 0,\n getSetter: _getSetter,\n aliases: {},\n register: 0\n };\n\n _wake();\n\n if (config !== Plugin) {\n if (_plugins[name]) {\n return;\n }\n\n _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods\n\n\n _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods\n\n\n _plugins[Plugin.prop = name] = Plugin;\n\n if (config.targetTest) {\n _harnessPlugins.push(Plugin);\n\n _reservedProps[name] = 1;\n }\n\n name = (name === \"css\" ? \"CSS\" : name.charAt(0).toUpperCase() + name.substr(1)) + \"Plugin\"; //for the global name. \"motionPath\" should become MotionPathPlugin\n }\n\n _addGlobal(name, Plugin);\n\n config.register && config.register(gsap, Plugin, PropTween);\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * COLORS\n * --------------------------------------------------------------------------------------\n */\n_255 = 255,\n _colorLookup = {\n aqua: [0, _255, _255],\n lime: [0, _255, 0],\n silver: [192, 192, 192],\n black: [0, 0, 0],\n maroon: [128, 0, 0],\n teal: [0, 128, 128],\n blue: [0, 0, _255],\n navy: [0, 0, 128],\n white: [_255, _255, _255],\n olive: [128, 128, 0],\n yellow: [_255, _255, 0],\n orange: [_255, 165, 0],\n gray: [128, 128, 128],\n purple: [128, 0, 128],\n green: [0, 128, 0],\n red: [_255, 0, 0],\n pink: [_255, 192, 203],\n cyan: [0, _255, _255],\n transparent: [_255, _255, _255, 0]\n},\n // possible future idea to replace the hard-coded color name values - put this in the ticker.wake() where we set the _doc:\n// let ctx = _doc.createElement(\"canvas\").getContext(\"2d\");\n// _forEachName(\"aqua,lime,silver,black,maroon,teal,blue,navy,white,olive,yellow,orange,gray,purple,green,red,pink,cyan\", color => {ctx.fillStyle = color; _colorLookup[color] = splitColor(ctx.fillStyle)});\n_hue = function _hue(h, m1, m2) {\n h += h < 0 ? 1 : h > 1 ? -1 : 0;\n return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0;\n},\n splitColor = function splitColor(v, toHSL, forceAlpha) {\n var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0,\n r,\n g,\n b,\n h,\n s,\n l,\n max,\n min,\n d,\n wasHSL;\n\n if (!a) {\n if (v.substr(-1) === \",\") {\n //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:\"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)\" - in this example \"blue,\" has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value.\n v = v.substr(0, v.length - 1);\n }\n\n if (_colorLookup[v]) {\n a = _colorLookup[v];\n } else if (v.charAt(0) === \"#\") {\n if (v.length < 6) {\n //for shorthand like #9F0 or #9F0F (could have alpha)\n r = v.charAt(1);\n g = v.charAt(2);\n b = v.charAt(3);\n v = \"#\" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : \"\");\n }\n\n if (v.length === 9) {\n // hex with alpha, like #fd5e53ff\n a = parseInt(v.substr(1, 6), 16);\n return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255];\n }\n\n v = parseInt(v.substr(1), 16);\n a = [v >> 16, v >> 8 & _255, v & _255];\n } else if (v.substr(0, 3) === \"hsl\") {\n a = wasHSL = v.match(_strictNumExp);\n\n if (!toHSL) {\n h = +a[0] % 360 / 360;\n s = +a[1] / 100;\n l = +a[2] / 100;\n g = l <= .5 ? l * (s + 1) : l + s - l * s;\n r = l * 2 - g;\n a.length > 3 && (a[3] *= 1); //cast as number\n\n a[0] = _hue(h + 1 / 3, r, g);\n a[1] = _hue(h, r, g);\n a[2] = _hue(h - 1 / 3, r, g);\n } else if (~v.indexOf(\"=\")) {\n //if relative values are found, just return the raw strings with the relative prefixes in place.\n a = v.match(_numExp);\n forceAlpha && a.length < 4 && (a[3] = 1);\n return a;\n }\n } else {\n a = v.match(_strictNumExp) || _colorLookup.transparent;\n }\n\n a = a.map(Number);\n }\n\n if (toHSL && !wasHSL) {\n r = a[0] / _255;\n g = a[1] / _255;\n b = a[2] / _255;\n max = Math.max(r, g, b);\n min = Math.min(r, g, b);\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0;\n } else {\n d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;\n h *= 60;\n }\n\n a[0] = ~~(h + .5);\n a[1] = ~~(s * 100 + .5);\n a[2] = ~~(l * 100 + .5);\n }\n\n forceAlpha && a.length < 4 && (a[3] = 1);\n return a;\n},\n _colorOrderData = function _colorOrderData(v) {\n // strips out the colors from the string, finds all the numeric slots (with units) and returns an array of those. The Array also has a \"c\" property which is an Array of the index values where the colors belong. This is to help work around issues where there's a mis-matched order of color/numeric data like drop-shadow(#f00 0px 1px 2px) and drop-shadow(0x 1px 2px #f00). This is basically a helper function used in _formatColors()\n var values = [],\n c = [],\n i = -1;\n v.split(_colorExp).forEach(function (v) {\n var a = v.match(_numWithUnitExp) || [];\n values.push.apply(values, a);\n c.push(i += a.length + 1);\n });\n values.c = c;\n return values;\n},\n _formatColors = function _formatColors(s, toHSL, orderMatchData) {\n var result = \"\",\n colors = (s + result).match(_colorExp),\n type = toHSL ? \"hsla(\" : \"rgba(\",\n i = 0,\n c,\n shell,\n d,\n l;\n\n if (!colors) {\n return s;\n }\n\n colors = colors.map(function (color) {\n return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + \",\" + color[1] + \"%,\" + color[2] + \"%,\" + color[3] : color.join(\",\")) + \")\";\n });\n\n if (orderMatchData) {\n d = _colorOrderData(s);\n c = orderMatchData.c;\n\n if (c.join(result) !== d.c.join(result)) {\n shell = s.replace(_colorExp, \"1\").split(_numWithUnitExp);\n l = shell.length - 1;\n\n for (; i < l; i++) {\n result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + \"0,0,0,0)\" : (d.length ? d : colors.length ? colors : orderMatchData).shift());\n }\n }\n }\n\n if (!shell) {\n shell = s.split(_colorExp);\n l = shell.length - 1;\n\n for (; i < l; i++) {\n result += shell[i] + colors[i];\n }\n }\n\n return result + shell[l];\n},\n _colorExp = function () {\n var s = \"(?:\\\\b(?:(?:rgb|rgba|hsl|hsla)\\\\(.+?\\\\))|\\\\B#(?:[0-9a-f]{3,4}){1,2}\\\\b\",\n //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc.,\n p;\n\n for (p in _colorLookup) {\n s += \"|\" + p + \"\\\\b\";\n }\n\n return new RegExp(s + \")\", \"gi\");\n}(),\n _hslExp = /hsl[a]?\\(/,\n _colorStringFilter = function _colorStringFilter(a) {\n var combined = a.join(\" \"),\n toHSL;\n _colorExp.lastIndex = 0;\n\n if (_colorExp.test(combined)) {\n toHSL = _hslExp.test(combined);\n a[1] = _formatColors(a[1], toHSL);\n a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value.\n\n return true;\n }\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TICKER\n * --------------------------------------------------------------------------------------\n */\n_tickerActive,\n _ticker = function () {\n var _getTime = Date.now,\n _lagThreshold = 500,\n _adjustedLag = 33,\n _startTime = _getTime(),\n _lastUpdate = _startTime,\n _gap = 1000 / 240,\n _nextTime = _gap,\n _listeners = [],\n _id,\n _req,\n _raf,\n _self,\n _delta,\n _i,\n _tick = function _tick(v) {\n var elapsed = _getTime() - _lastUpdate,\n manual = v === true,\n overlap,\n dispatch,\n time,\n frame;\n\n elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag);\n _lastUpdate += elapsed;\n time = _lastUpdate - _startTime;\n overlap = time - _nextTime;\n\n if (overlap > 0 || manual) {\n frame = ++_self.frame;\n _delta = time - _self.time * 1000;\n _self.time = time = time / 1000;\n _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap);\n dispatch = 1;\n }\n\n manual || (_id = _req(_tick)); //make sure the request is made before we dispatch the \"tick\" event so that timing is maintained. Otherwise, if processing the \"tick\" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise.\n\n if (dispatch) {\n for (_i = 0; _i < _listeners.length; _i++) {\n // use _i and check _listeners.length instead of a variable because a listener could get removed during the loop, and if that happens to an element less than the current index, it'd throw things off in the loop.\n _listeners[_i](time, _delta, frame, v);\n }\n }\n };\n\n _self = {\n time: 0,\n frame: 0,\n tick: function tick() {\n _tick(true);\n },\n deltaRatio: function deltaRatio(fps) {\n return _delta / (1000 / (fps || 60));\n },\n wake: function wake() {\n if (_coreReady) {\n if (!_coreInitted && _windowExists()) {\n _win = _coreInitted = window;\n _doc = _win.document || {};\n _globals.gsap = gsap;\n (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version);\n\n _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {});\n\n _raf = _win.requestAnimationFrame;\n\n _registerPluginQueue.forEach(_createPlugin);\n }\n\n _id && _self.sleep();\n\n _req = _raf || function (f) {\n return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0);\n };\n\n _tickerActive = 1;\n\n _tick(2);\n }\n },\n sleep: function sleep() {\n (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id);\n _tickerActive = 0;\n _req = _emptyFunc;\n },\n lagSmoothing: function lagSmoothing(threshold, adjustedLag) {\n _lagThreshold = threshold || Infinity; // zero should be interpreted as basically unlimited\n\n _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold);\n },\n fps: function fps(_fps) {\n _gap = 1000 / (_fps || 240);\n _nextTime = _self.time * 1000 + _gap;\n },\n add: function add(callback, once, prioritize) {\n var func = once ? function (t, d, f, v) {\n callback(t, d, f, v);\n\n _self.remove(func);\n } : callback;\n\n _self.remove(callback);\n\n _listeners[prioritize ? \"unshift\" : \"push\"](func);\n\n _wake();\n\n return func;\n },\n remove: function remove(callback, i) {\n ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--;\n },\n _listeners: _listeners\n };\n return _self;\n}(),\n _wake = function _wake() {\n return !_tickerActive && _ticker.wake();\n},\n //also ensures the core classes are initialized.\n\n/*\n* -------------------------------------------------\n* EASING\n* -------------------------------------------------\n*/\n_easeMap = {},\n _customEaseExp = /^[\\d.\\-M][\\d.\\-,\\s]/,\n _quotesExp = /[\"']/g,\n _parseObjectInString = function _parseObjectInString(value) {\n //takes a string like \"{wiggles:10, type:anticipate})\" and turns it into a real object. Notice it ends in \")\" and includes the {} wrappers. This is because we only use this function for parsing ease configs and prioritized optimization rather than reusability.\n var obj = {},\n split = value.substr(1, value.length - 3).split(\":\"),\n key = split[0],\n i = 1,\n l = split.length,\n index,\n val,\n parsedVal;\n\n for (; i < l; i++) {\n val = split[i];\n index = i !== l - 1 ? val.lastIndexOf(\",\") : val.length;\n parsedVal = val.substr(0, index);\n obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, \"\").trim() : +parsedVal;\n key = val.substr(index + 1).trim();\n }\n\n return obj;\n},\n _valueInParentheses = function _valueInParentheses(value) {\n var open = value.indexOf(\"(\") + 1,\n close = value.indexOf(\")\"),\n nested = value.indexOf(\"(\", open);\n return value.substring(open, ~nested && nested < close ? value.indexOf(\")\", close + 1) : close);\n},\n _configEaseFromString = function _configEaseFromString(name) {\n //name can be a string like \"elastic.out(1,0.5)\", and pass in _easeMap as obj and it'll parse it out and call the actual function like _easeMap.Elastic.easeOut.config(1,0.5). It will also parse custom ease strings as long as CustomEase is loaded and registered (internally as _easeMap._CE).\n var split = (name + \"\").split(\"(\"),\n ease = _easeMap[split[0]];\n return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf(\"{\") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(\",\").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE(\"\", name) : ease;\n},\n _invertEase = function _invertEase(ease) {\n return function (p) {\n return 1 - ease(1 - p);\n };\n},\n // allow yoyoEase to be set in children and have those affected when the parent/ancestor timeline yoyos.\n_propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) {\n var child = timeline._first,\n ease;\n\n while (child) {\n if (child instanceof Timeline) {\n _propagateYoyoEase(child, isYoyo);\n } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) {\n if (child.timeline) {\n _propagateYoyoEase(child.timeline, isYoyo);\n } else {\n ease = child._ease;\n child._ease = child._yEase;\n child._yEase = ease;\n child._yoyo = isYoyo;\n }\n }\n\n child = child._next;\n }\n},\n _parseEase = function _parseEase(ease, defaultEase) {\n return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase;\n},\n _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) {\n if (easeOut === void 0) {\n easeOut = function easeOut(p) {\n return 1 - easeIn(1 - p);\n };\n }\n\n if (easeInOut === void 0) {\n easeInOut = function easeInOut(p) {\n return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2;\n };\n }\n\n var ease = {\n easeIn: easeIn,\n easeOut: easeOut,\n easeInOut: easeInOut\n },\n lowercaseName;\n\n _forEachName(names, function (name) {\n _easeMap[name] = _globals[name] = ease;\n _easeMap[lowercaseName = name.toLowerCase()] = easeOut;\n\n for (var p in ease) {\n _easeMap[lowercaseName + (p === \"easeIn\" ? \".in\" : p === \"easeOut\" ? \".out\" : \".inOut\")] = _easeMap[name + \".\" + p] = ease[p];\n }\n });\n\n return ease;\n},\n _easeInOutFromOut = function _easeInOutFromOut(easeOut) {\n return function (p) {\n return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2;\n };\n},\n _configElastic = function _configElastic(type, amplitude, period) {\n var p1 = amplitude >= 1 ? amplitude : 1,\n //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1.\n p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1),\n p3 = p2 / _2PI * (Math.asin(1 / p1) || 0),\n easeOut = function easeOut(p) {\n return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1;\n },\n ease = type === \"out\" ? easeOut : type === \"in\" ? function (p) {\n return 1 - easeOut(1 - p);\n } : _easeInOutFromOut(easeOut);\n\n p2 = _2PI / p2; //precalculate to optimize\n\n ease.config = function (amplitude, period) {\n return _configElastic(type, amplitude, period);\n };\n\n return ease;\n},\n _configBack = function _configBack(type, overshoot) {\n if (overshoot === void 0) {\n overshoot = 1.70158;\n }\n\n var easeOut = function easeOut(p) {\n return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0;\n },\n ease = type === \"out\" ? easeOut : type === \"in\" ? function (p) {\n return 1 - easeOut(1 - p);\n } : _easeInOutFromOut(easeOut);\n\n ease.config = function (overshoot) {\n return _configBack(type, overshoot);\n };\n\n return ease;\n}; // a cheaper (kb and cpu) but more mild way to get a parameterized weighted ease by feeding in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear.\n// _weightedEase = ratio => {\n// \tlet y = 0.5 + ratio / 2;\n// \treturn p => (2 * (1 - p) * p * y + p * p);\n// },\n// a stronger (but more expensive kb/cpu) parameterized weighted ease that lets you feed in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear.\n// _weightedEaseStrong = ratio => {\n// \tratio = .5 + ratio / 2;\n// \tlet o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio),\n// \t\tb = ratio - o,\n// \t\tc = ratio + o;\n// \treturn p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p;\n// };\n\n\n_forEachName(\"Linear,Quad,Cubic,Quart,Quint,Strong\", function (name, i) {\n var power = i < 5 ? i + 1 : i;\n\n _insertEase(name + \",Power\" + (power - 1), i ? function (p) {\n return Math.pow(p, power);\n } : function (p) {\n return p;\n }, function (p) {\n return 1 - Math.pow(1 - p, power);\n }, function (p) {\n return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2;\n });\n});\n\n_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn;\n\n_insertEase(\"Elastic\", _configElastic(\"in\"), _configElastic(\"out\"), _configElastic());\n\n(function (n, c) {\n var n1 = 1 / c,\n n2 = 2 * n1,\n n3 = 2.5 * n1,\n easeOut = function easeOut(p) {\n return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375;\n };\n\n _insertEase(\"Bounce\", function (p) {\n return 1 - easeOut(1 - p);\n }, easeOut);\n})(7.5625, 2.75);\n\n_insertEase(\"Expo\", function (p) {\n return p ? Math.pow(2, 10 * (p - 1)) : 0;\n});\n\n_insertEase(\"Circ\", function (p) {\n return -(_sqrt(1 - p * p) - 1);\n});\n\n_insertEase(\"Sine\", function (p) {\n return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1;\n});\n\n_insertEase(\"Back\", _configBack(\"in\"), _configBack(\"out\"), _configBack());\n\n_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = {\n config: function config(steps, immediateStart) {\n if (steps === void 0) {\n steps = 1;\n }\n\n var p1 = 1 / steps,\n p2 = steps + (immediateStart ? 0 : 1),\n p3 = immediateStart ? 1 : 0,\n max = 1 - _tinyNum;\n return function (p) {\n return ((p2 * _clamp(0, max, p) | 0) + p3) * p1;\n };\n }\n};\n_defaults.ease = _easeMap[\"quad.out\"];\n\n_forEachName(\"onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt\", function (name) {\n return _callbackNames += name + \",\" + name + \"Params,\";\n});\n/*\n * --------------------------------------------------------------------------------------\n * CACHE\n * --------------------------------------------------------------------------------------\n */\n\n\nvar GSCache = function GSCache(target, harness) {\n this.id = _gsID++;\n target._gsap = this;\n this.target = target;\n this.harness = harness;\n this.get = harness ? harness.get : _getProperty;\n this.set = harness ? harness.getSetter : _getSetter;\n};\n/*\n * --------------------------------------------------------------------------------------\n * ANIMATION\n * --------------------------------------------------------------------------------------\n */\n\nvar Animation = /*#__PURE__*/function () {\n function Animation(vars) {\n this.vars = vars;\n this._delay = +vars.delay || 0;\n\n if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) {\n // TODO: repeat: Infinity on a timeline's children must flag that timeline internally and affect its totalDuration, otherwise it'll stop in the negative direction when reaching the start.\n this._rDelay = vars.repeatDelay || 0;\n this._yoyo = !!vars.yoyo || !!vars.yoyoEase;\n }\n\n this._ts = 1;\n\n _setDuration(this, +vars.duration, 1, 1);\n\n this.data = vars.data;\n\n if (_context) {\n this._ctx = _context;\n\n _context.data.push(this);\n }\n\n _tickerActive || _ticker.wake();\n }\n\n var _proto = Animation.prototype;\n\n _proto.delay = function delay(value) {\n if (value || value === 0) {\n this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay);\n this._delay = value;\n return this;\n }\n\n return this._delay;\n };\n\n _proto.duration = function duration(value) {\n return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur;\n };\n\n _proto.totalDuration = function totalDuration(value) {\n if (!arguments.length) {\n return this._tDur;\n }\n\n this._dirty = 0;\n return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1));\n };\n\n _proto.totalTime = function totalTime(_totalTime, suppressEvents) {\n _wake();\n\n if (!arguments.length) {\n return this._tTime;\n }\n\n var parent = this._dp;\n\n if (parent && parent.smoothChildTiming && this._ts) {\n _alignPlayhead(this, _totalTime);\n\n !parent._dp || parent.parent || _postAddChecks(parent, this); // edge case: if this is a child of a timeline that already completed, for example, we must re-activate the parent.\n //in case any of the ancestor timelines had completed but should now be enabled, we should reset their totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The start of that child would get pushed out, but one of the ancestors may have completed.\n\n while (parent && parent.parent) {\n if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) {\n parent.totalTime(parent._tTime, true);\n }\n\n parent = parent.parent;\n }\n\n if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) {\n //if the animation doesn't have a parent, put it back into its last parent (recorded as _dp for exactly cases like this). Limit to parents with autoRemoveChildren (like globalTimeline) so that if the user manually removes an animation from a timeline and then alters its playhead, it doesn't get added back in.\n _addToTimeline(this._dp, this, this._start - this._delay);\n }\n }\n\n if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) {\n // check for _ptLookup on a Tween instance to ensure it has actually finished being instantiated, otherwise if this.reverse() gets called in the Animation constructor, it could trigger a render() here even though the _targets weren't populated, thus when _init() is called there won't be any PropTweens (it'll act like the tween is non-functional)\n this._ts || (this._pTime = _totalTime); // otherwise, if an animation is paused, then the playhead is moved back to zero, then resumed, it'd revert back to the original time at the pause\n //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it's worth the performance hit)\n // this._lock = 1;\n\n _lazySafeRender(this, _totalTime, suppressEvents); // this._lock = 0;\n //}\n\n }\n\n return this;\n };\n\n _proto.time = function time(value, suppressEvents) {\n return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time; // note: if the modulus results in 0, the playhead could be exactly at the end or the beginning, and we always defer to the END with a non-zero value, otherwise if you set the time() to the very end (duration()), it would render at the START!\n };\n\n _proto.totalProgress = function totalProgress(value, suppressEvents) {\n return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio;\n };\n\n _proto.progress = function progress(value, suppressEvents) {\n return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.ratio;\n };\n\n _proto.iteration = function iteration(value, suppressEvents) {\n var cycleDuration = this.duration() + this._rDelay;\n\n return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1;\n } // potential future addition:\n // isPlayingBackwards() {\n // \tlet animation = this,\n // \t\torientation = 1; // 1 = forward, -1 = backward\n // \twhile (animation) {\n // \t\torientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1;\n // \t\tanimation = animation.parent;\n // \t}\n // \treturn orientation < 0;\n // }\n ;\n\n _proto.timeScale = function timeScale(value) {\n if (!arguments.length) {\n return this._rts === -_tinyNum ? 0 : this._rts; // recorded timeScale. Special case: if someone calls reverse() on an animation with timeScale of 0, we assign it -_tinyNum to remember it's reversed.\n }\n\n if (this._rts === value) {\n return this;\n }\n\n var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; // make sure to do the parentToChildTotalTime() BEFORE setting the new _ts because the old one must be used in that calculation.\n // future addition? Up side: fast and minimal file size. Down side: only works on this animation; if a timeline is reversed, for example, its childrens' onReverse wouldn't get called.\n //(+value < 0 && this._rts >= 0) && _callback(this, \"onReverse\", true);\n // prioritize rendering where the parent's playhead lines up instead of this._tTime because there could be a tween that's animating another tween's timeScale in the same rendering loop (same parent), thus if the timeScale tween renders first, it would alter _start BEFORE _tTime was set on that tick (in the rendering loop), effectively freezing it until the timeScale tween finishes.\n\n this._rts = +value || 0;\n this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused.\n\n this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), true);\n\n _setEnd(this); // if parent.smoothChildTiming was false, the end time didn't get updated in the _alignPlayhead() method, so do it here.\n\n\n return _recacheAncestors(this);\n };\n\n _proto.paused = function paused(value) {\n if (!arguments.length) {\n return this._ps;\n }\n\n if (this._ps !== value) {\n this._ps = value;\n\n if (value) {\n this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); // if the pause occurs during the delay phase, make sure that's factored in when resuming.\n\n this._ts = this._act = 0; // _ts is the functional timeScale, so a paused tween would effectively have a timeScale of 0. We record the \"real\" timeScale as _rts (recorded time scale)\n } else {\n _wake();\n\n this._ts = this._rts; //only defer to _pTime (pauseTime) if tTime is zero. Remember, someone could pause() an animation, then scrub the playhead and resume(). If the parent doesn't have smoothChildTiming, we render at the rawTime() because the startTime won't get updated.\n\n this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum)); // edge case: animation.progress(1).pause().play() wouldn't render again because the playhead is already at the end, but the call to totalTime() below will add it back to its parent...and not remove it again (since removing only happens upon rendering at a new time). Offsetting the _tTime slightly is done simply to cause the final render in totalTime() that'll pop it off its timeline (if autoRemoveChildren is true, of course). Check to make sure _zTime isn't -_tinyNum to avoid an edge case where the playhead is pushed to the end but INSIDE a tween/callback, the timeline itself is paused thus halting rendering and leaving a few unrendered. When resuming, it wouldn't render those otherwise.\n }\n }\n\n return this;\n };\n\n _proto.startTime = function startTime(value) {\n if (arguments.length) {\n this._start = value;\n var parent = this.parent || this._dp;\n parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay);\n return this;\n }\n\n return this._start;\n };\n\n _proto.endTime = function endTime(includeRepeats) {\n return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1);\n };\n\n _proto.rawTime = function rawTime(wrapRepeats) {\n var parent = this.parent || this._dp; // _dp = detached parent\n\n return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this);\n };\n\n _proto.revert = function revert(config) {\n if (config === void 0) {\n config = _revertConfig;\n }\n\n var prevIsReverting = _reverting;\n _reverting = config;\n\n if (this._initted || this._startAt) {\n this.timeline && this.timeline.revert(config);\n this.totalTime(-0.01, config.suppressEvents);\n }\n\n this.data !== \"nested\" && config.kill !== false && this.kill();\n _reverting = prevIsReverting;\n return this;\n };\n\n _proto.globalTime = function globalTime(rawTime) {\n var animation = this,\n time = arguments.length ? rawTime : animation.rawTime();\n\n while (animation) {\n time = animation._start + time / (animation._ts || 1);\n animation = animation._dp;\n }\n\n return !this.parent && this._sat ? this._sat.vars.immediateRender ? -1 : this._sat.globalTime(rawTime) : time; // the _startAt tweens for .fromTo() and .from() that have immediateRender should always be FIRST in the timeline (important for context.revert()). \"_sat\" stands for _startAtTween, referring to the parent tween that created the _startAt. We must discern if that tween had immediateRender so that we can know whether or not to prioritize it in revert().\n };\n\n _proto.repeat = function repeat(value) {\n if (arguments.length) {\n this._repeat = value === Infinity ? -2 : value;\n return _onUpdateTotalDuration(this);\n }\n\n return this._repeat === -2 ? Infinity : this._repeat;\n };\n\n _proto.repeatDelay = function repeatDelay(value) {\n if (arguments.length) {\n var time = this._time;\n this._rDelay = value;\n\n _onUpdateTotalDuration(this);\n\n return time ? this.time(time) : this;\n }\n\n return this._rDelay;\n };\n\n _proto.yoyo = function yoyo(value) {\n if (arguments.length) {\n this._yoyo = value;\n return this;\n }\n\n return this._yoyo;\n };\n\n _proto.seek = function seek(position, suppressEvents) {\n return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents));\n };\n\n _proto.restart = function restart(includeDelay, suppressEvents) {\n return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents));\n };\n\n _proto.play = function play(from, suppressEvents) {\n from != null && this.seek(from, suppressEvents);\n return this.reversed(false).paused(false);\n };\n\n _proto.reverse = function reverse(from, suppressEvents) {\n from != null && this.seek(from || this.totalDuration(), suppressEvents);\n return this.reversed(true).paused(false);\n };\n\n _proto.pause = function pause(atTime, suppressEvents) {\n atTime != null && this.seek(atTime, suppressEvents);\n return this.paused(true);\n };\n\n _proto.resume = function resume() {\n return this.paused(false);\n };\n\n _proto.reversed = function reversed(value) {\n if (arguments.length) {\n !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum.\n\n return this;\n }\n\n return this._rts < 0;\n };\n\n _proto.invalidate = function invalidate() {\n this._initted = this._act = 0;\n this._zTime = -_tinyNum;\n return this;\n };\n\n _proto.isActive = function isActive() {\n var parent = this.parent || this._dp,\n start = this._start,\n rawTime;\n return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum);\n };\n\n _proto.eventCallback = function eventCallback(type, callback, params) {\n var vars = this.vars;\n\n if (arguments.length > 1) {\n if (!callback) {\n delete vars[type];\n } else {\n vars[type] = callback;\n params && (vars[type + \"Params\"] = params);\n type === \"onUpdate\" && (this._onUpdate = callback);\n }\n\n return this;\n }\n\n return vars[type];\n };\n\n _proto.then = function then(onFulfilled) {\n var self = this;\n return new Promise(function (resolve) {\n var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough,\n _resolve = function _resolve() {\n var _then = self.then;\n self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322)\n\n _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then);\n resolve(f);\n self.then = _then;\n };\n\n if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) {\n _resolve();\n } else {\n self._prom = _resolve;\n }\n });\n };\n\n _proto.kill = function kill() {\n _interrupt(this);\n };\n\n return Animation;\n}();\n\n_setDefaults(Animation.prototype, {\n _time: 0,\n _start: 0,\n _end: 0,\n _tTime: 0,\n _tDur: 0,\n _dirty: 0,\n _repeat: 0,\n _yoyo: false,\n parent: null,\n _initted: false,\n _rDelay: 0,\n _ts: 1,\n _dp: 0,\n ratio: 0,\n _zTime: -_tinyNum,\n _prom: 0,\n _ps: false,\n _rts: 1\n});\n/*\n * -------------------------------------------------\n * TIMELINE\n * -------------------------------------------------\n */\n\n\nvar Timeline = /*#__PURE__*/function (_Animation) {\n _inheritsLoose(Timeline, _Animation);\n\n function Timeline(vars, position) {\n var _this;\n\n if (vars === void 0) {\n vars = {};\n }\n\n _this = _Animation.call(this, vars) || this;\n _this.labels = {};\n _this.smoothChildTiming = !!vars.smoothChildTiming;\n _this.autoRemoveChildren = !!vars.autoRemoveChildren;\n _this._sort = _isNotFalse(vars.sortChildren);\n _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position);\n vars.reversed && _this.reverse();\n vars.paused && _this.paused(true);\n vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger);\n return _this;\n }\n\n var _proto2 = Timeline.prototype;\n\n _proto2.to = function to(targets, vars, position) {\n _createTweenType(0, arguments, this);\n\n return this;\n };\n\n _proto2.from = function from(targets, vars, position) {\n _createTweenType(1, arguments, this);\n\n return this;\n };\n\n _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) {\n _createTweenType(2, arguments, this);\n\n return this;\n };\n\n _proto2.set = function set(targets, vars, position) {\n vars.duration = 0;\n vars.parent = this;\n _inheritDefaults(vars).repeatDelay || (vars.repeat = 0);\n vars.immediateRender = !!vars.immediateRender;\n new Tween(targets, vars, _parsePosition(this, position), 1);\n return this;\n };\n\n _proto2.call = function call(callback, params, position) {\n return _addToTimeline(this, Tween.delayedCall(0, callback, params), position);\n } //ONLY for backward compatibility! Maybe delete?\n ;\n\n _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n vars.duration = duration;\n vars.stagger = vars.stagger || stagger;\n vars.onComplete = onCompleteAll;\n vars.onCompleteParams = onCompleteAllParams;\n vars.parent = this;\n new Tween(targets, vars, _parsePosition(this, position));\n return this;\n };\n\n _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n vars.runBackwards = 1;\n _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender);\n return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams);\n };\n\n _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) {\n toVars.startAt = fromVars;\n _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender);\n return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams);\n };\n\n _proto2.render = function render(totalTime, suppressEvents, force) {\n var prevTime = this._time,\n tDur = this._dirty ? this.totalDuration() : this._tDur,\n dur = this._dur,\n tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime),\n // if a paused timeline is resumed (or its _start is updated for another reason...which rounds it), that could result in the playhead shifting a **tiny** amount and a zero-duration child at that spot may get rendered at a different ratio, like its totalTime in render() may be 1e-17 instead of 0, for example.\n crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur),\n time,\n child,\n next,\n iteration,\n cycleDuration,\n prevPaused,\n pauseTween,\n timeScale,\n prevStart,\n prevIteration,\n yoyo,\n isYoyo;\n this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur);\n\n if (tTime !== this._tTime || force || crossingStart) {\n if (prevTime !== this._time && dur) {\n //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).\n tTime += this._time - prevTime;\n totalTime += this._time - prevTime;\n }\n\n time = tTime;\n prevStart = this._start;\n timeScale = this._ts;\n prevPaused = !timeScale;\n\n if (crossingStart) {\n dur || (prevTime = this._zTime); //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect.\n\n (totalTime || !suppressEvents) && (this._zTime = totalTime);\n }\n\n if (this._repeat) {\n //adjust the time for repeats and yoyos\n yoyo = this._yoyo;\n cycleDuration = dur + this._rDelay;\n\n if (this._repeat < -1 && totalTime < 0) {\n return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n }\n\n time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n if (tTime === tDur) {\n // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't)\n iteration = this._repeat;\n time = dur;\n } else {\n iteration = ~~(tTime / cycleDuration);\n\n if (iteration && iteration === tTime / cycleDuration) {\n time = dur;\n iteration--;\n }\n\n time > dur && (time = dur);\n }\n\n prevIteration = _animationCycle(this._tTime, cycleDuration);\n !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration); // edge case - if someone does addPause() at the very beginning of a repeating timeline, that pause is technically at the same spot as the end which causes this._time to get set to 0 when the totalTime would normally place the playhead at the end. See https://greensock.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 also, this._tTime - prevIteration * cycleDuration - this._dur <= 0 just checks to make sure it wasn't previously in the \"repeatDelay\" portion\n\n if (yoyo && iteration & 1) {\n time = dur - time;\n isYoyo = 1;\n }\n /*\n make sure children at the end/beginning of the timeline are rendered properly. If, for example,\n a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which\n would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there\n could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So\n we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must\n ensure that zero-duration tweens at the very beginning or end of the Timeline work.\n */\n\n\n if (iteration !== prevIteration && !this._lock) {\n var rewinding = yoyo && prevIteration & 1,\n doesWrap = rewinding === (yoyo && iteration & 1);\n iteration < prevIteration && (rewinding = !rewinding);\n prevTime = rewinding ? 0 : dur;\n this._lock = 1;\n this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0;\n this._tTime = tTime; // if a user gets the iteration() inside the onRepeat, for example, it should be accurate.\n\n !suppressEvents && this.parent && _callback(this, \"onRepeat\");\n this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1);\n\n if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) {\n // if prevTime is 0 and we render at the very end, _time will be the end, thus won't match. So in this edge case, prevTime won't match _time but that's okay. If it gets killed in the onRepeat, eject as well.\n return this;\n }\n\n dur = this._dur; // in case the duration changed in the onRepeat\n\n tDur = this._tDur;\n\n if (doesWrap) {\n this._lock = 2;\n prevTime = rewinding ? dur : -0.0001;\n this.render(prevTime, true);\n this.vars.repeatRefresh && !isYoyo && this.invalidate();\n }\n\n this._lock = 0;\n\n if (!this._ts && !prevPaused) {\n return this;\n } //in order for yoyoEase to work properly when there's a stagger, we must swap out the ease in each sub-tween.\n\n\n _propagateYoyoEase(this, isYoyo);\n }\n }\n\n if (this._hasPause && !this._forcing && this._lock < 2) {\n pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time));\n\n if (pauseTween) {\n tTime -= time - (time = pauseTween._start);\n }\n }\n\n this._tTime = tTime;\n this._time = time;\n this._act = !timeScale; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick.\n\n if (!this._initted) {\n this._onUpdate = this.vars.onUpdate;\n this._initted = 1;\n this._zTime = totalTime;\n prevTime = 0; // upon init, the playhead should always go forward; someone could invalidate() a completed timeline and then if they restart(), that would make child tweens render in reverse order which could lock in the wrong starting values if they build on each other, like tl.to(obj, {x: 100}).to(obj, {x: 0}).\n }\n\n if (!prevTime && time && !suppressEvents && !iteration) {\n _callback(this, \"onStart\");\n\n if (this._tTime !== tTime) {\n // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart.\n return this;\n }\n }\n\n if (time >= prevTime && totalTime >= 0) {\n child = this._first;\n\n while (child) {\n next = child._next;\n\n if ((child._act || time >= child._start) && child._ts && pauseTween !== child) {\n if (child.parent !== this) {\n // an extreme edge case - the child's render could do something like kill() the \"next\" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe.\n return this.render(totalTime, suppressEvents, force);\n }\n\n child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force);\n\n if (time !== this._time || !this._ts && !prevPaused) {\n //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n pauseTween = 0;\n next && (tTime += this._zTime = -_tinyNum); // it didn't finish rendering, so flag zTime as negative so that so that the next time render() is called it'll be forced (to render any remaining children)\n\n break;\n }\n }\n\n child = next;\n }\n } else {\n child = this._last;\n var adjustedTime = totalTime < 0 ? totalTime : time; //when the playhead goes backward beyond the start of this timeline, we must pass that information down to the child animations so that zero-duration tweens know whether to render their starting or ending values.\n\n while (child) {\n next = child._prev;\n\n if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) {\n if (child.parent !== this) {\n // an extreme edge case - the child's render could do something like kill() the \"next\" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe.\n return this.render(totalTime, suppressEvents, force);\n }\n\n child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt)); // if reverting, we should always force renders of initted tweens (but remember that .fromTo() or .from() may have a _startAt but not _initted yet). If, for example, a .fromTo() tween with a stagger (which creates an internal timeline) gets reverted BEFORE some of its child tweens render for the first time, it may not properly trigger them to revert.\n\n if (time !== this._time || !this._ts && !prevPaused) {\n //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n pauseTween = 0;\n next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); // it didn't finish rendering, so adjust zTime so that so that the next time render() is called it'll be forced (to render any remaining children)\n\n break;\n }\n }\n\n child = next;\n }\n }\n\n if (pauseTween && !suppressEvents) {\n this.pause();\n pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1;\n\n if (this._ts) {\n //the callback resumed playback! So since we may have held back the playhead due to where the pause is positioned, go ahead and jump to where it's SUPPOSED to be (if no pause happened).\n this._start = prevStart; //if the pause was at an earlier time and the user resumed in the callback, it could reposition the timeline (changing its startTime), throwing things off slightly, so we make sure the _start doesn't shift.\n\n _setEnd(this);\n\n return this.render(totalTime, suppressEvents, force);\n }\n }\n\n this._onUpdate && !suppressEvents && _callback(this, \"onUpdate\", true);\n if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) {\n // remember, a child's callback may alter this timeline's playhead or timeScale which is why we need to add some of these checks.\n (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative.\n\n if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) {\n _callback(this, tTime === tDur && totalTime >= 0 ? \"onComplete\" : \"onReverseComplete\", true);\n\n this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n }\n }\n }\n\n return this;\n };\n\n _proto2.add = function add(child, position) {\n var _this2 = this;\n\n _isNumber(position) || (position = _parsePosition(this, position, child));\n\n if (!(child instanceof Animation)) {\n if (_isArray(child)) {\n child.forEach(function (obj) {\n return _this2.add(obj, position);\n });\n return this;\n }\n\n if (_isString(child)) {\n return this.addLabel(child, position);\n }\n\n if (_isFunction(child)) {\n child = Tween.delayedCall(0, child);\n } else {\n return this;\n }\n }\n\n return this !== child ? _addToTimeline(this, child, position) : this; //don't allow a timeline to be added to itself as a child!\n };\n\n _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) {\n if (nested === void 0) {\n nested = true;\n }\n\n if (tweens === void 0) {\n tweens = true;\n }\n\n if (timelines === void 0) {\n timelines = true;\n }\n\n if (ignoreBeforeTime === void 0) {\n ignoreBeforeTime = -_bigNum;\n }\n\n var a = [],\n child = this._first;\n\n while (child) {\n if (child._start >= ignoreBeforeTime) {\n if (child instanceof Tween) {\n tweens && a.push(child);\n } else {\n timelines && a.push(child);\n nested && a.push.apply(a, child.getChildren(true, tweens, timelines));\n }\n }\n\n child = child._next;\n }\n\n return a;\n };\n\n _proto2.getById = function getById(id) {\n var animations = this.getChildren(1, 1, 1),\n i = animations.length;\n\n while (i--) {\n if (animations[i].vars.id === id) {\n return animations[i];\n }\n }\n };\n\n _proto2.remove = function remove(child) {\n if (_isString(child)) {\n return this.removeLabel(child);\n }\n\n if (_isFunction(child)) {\n return this.killTweensOf(child);\n }\n\n _removeLinkedListItem(this, child);\n\n if (child === this._recent) {\n this._recent = this._last;\n }\n\n return _uncache(this);\n };\n\n _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) {\n if (!arguments.length) {\n return this._tTime;\n }\n\n this._forcing = 1;\n\n if (!this._dp && this._ts) {\n //special case for the global timeline (or any other that has no parent or detached parent).\n this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts));\n }\n\n _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents);\n\n this._forcing = 0;\n return this;\n };\n\n _proto2.addLabel = function addLabel(label, position) {\n this.labels[label] = _parsePosition(this, position);\n return this;\n };\n\n _proto2.removeLabel = function removeLabel(label) {\n delete this.labels[label];\n return this;\n };\n\n _proto2.addPause = function addPause(position, callback, params) {\n var t = Tween.delayedCall(0, callback || _emptyFunc, params);\n t.data = \"isPause\";\n this._hasPause = 1;\n return _addToTimeline(this, t, _parsePosition(this, position));\n };\n\n _proto2.removePause = function removePause(position) {\n var child = this._first;\n position = _parsePosition(this, position);\n\n while (child) {\n if (child._start === position && child.data === \"isPause\") {\n _removeFromParent(child);\n }\n\n child = child._next;\n }\n };\n\n _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n var tweens = this.getTweensOf(targets, onlyActive),\n i = tweens.length;\n\n while (i--) {\n _overwritingTween !== tweens[i] && tweens[i].kill(targets, props);\n }\n\n return this;\n };\n\n _proto2.getTweensOf = function getTweensOf(targets, onlyActive) {\n var a = [],\n parsedTargets = toArray(targets),\n child = this._first,\n isGlobalTime = _isNumber(onlyActive),\n // a number is interpreted as a global time. If the animation spans\n children;\n\n while (child) {\n if (child instanceof Tween) {\n if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) {\n // note: if this is for overwriting, it should only be for tweens that aren't paused and are initted.\n a.push(child);\n }\n } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) {\n a.push.apply(a, children);\n }\n\n child = child._next;\n }\n\n return a;\n } // potential future feature - targets() on timelines\n // targets() {\n // \tlet result = [];\n // \tthis.getChildren(true, true, false).forEach(t => result.push(...t.targets()));\n // \treturn result.filter((v, i) => result.indexOf(v) === i);\n // }\n ;\n\n _proto2.tweenTo = function tweenTo(position, vars) {\n vars = vars || {};\n\n var tl = this,\n endTime = _parsePosition(tl, position),\n _vars = vars,\n startAt = _vars.startAt,\n _onStart = _vars.onStart,\n onStartParams = _vars.onStartParams,\n immediateRender = _vars.immediateRender,\n initted,\n tween = Tween.to(tl, _setDefaults({\n ease: vars.ease || \"none\",\n lazy: false,\n immediateRender: false,\n time: endTime,\n overwrite: \"auto\",\n duration: vars.duration || Math.abs((endTime - (startAt && \"time\" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum,\n onStart: function onStart() {\n tl.pause();\n\n if (!initted) {\n var duration = vars.duration || Math.abs((endTime - (startAt && \"time\" in startAt ? startAt.time : tl._time)) / tl.timeScale());\n tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true);\n initted = 1;\n }\n\n _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don't want to overwrite it.\n }\n }, vars));\n\n return immediateRender ? tween.render(0) : tween;\n };\n\n _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) {\n return this.tweenTo(toPosition, _setDefaults({\n startAt: {\n time: _parsePosition(this, fromPosition)\n }\n }, vars));\n };\n\n _proto2.recent = function recent() {\n return this._recent;\n };\n\n _proto2.nextLabel = function nextLabel(afterTime) {\n if (afterTime === void 0) {\n afterTime = this._time;\n }\n\n return _getLabelInDirection(this, _parsePosition(this, afterTime));\n };\n\n _proto2.previousLabel = function previousLabel(beforeTime) {\n if (beforeTime === void 0) {\n beforeTime = this._time;\n }\n\n return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1);\n };\n\n _proto2.currentLabel = function currentLabel(value) {\n return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum);\n };\n\n _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) {\n if (ignoreBeforeTime === void 0) {\n ignoreBeforeTime = 0;\n }\n\n var child = this._first,\n labels = this.labels,\n p;\n\n while (child) {\n if (child._start >= ignoreBeforeTime) {\n child._start += amount;\n child._end += amount;\n }\n\n child = child._next;\n }\n\n if (adjustLabels) {\n for (p in labels) {\n if (labels[p] >= ignoreBeforeTime) {\n labels[p] += amount;\n }\n }\n }\n\n return _uncache(this);\n };\n\n _proto2.invalidate = function invalidate(soft) {\n var child = this._first;\n this._lock = 0;\n\n while (child) {\n child.invalidate(soft);\n child = child._next;\n }\n\n return _Animation.prototype.invalidate.call(this, soft);\n };\n\n _proto2.clear = function clear(includeLabels) {\n if (includeLabels === void 0) {\n includeLabels = true;\n }\n\n var child = this._first,\n next;\n\n while (child) {\n next = child._next;\n this.remove(child);\n child = next;\n }\n\n this._dp && (this._time = this._tTime = this._pTime = 0);\n includeLabels && (this.labels = {});\n return _uncache(this);\n };\n\n _proto2.totalDuration = function totalDuration(value) {\n var max = 0,\n self = this,\n child = self._last,\n prevStart = _bigNum,\n prev,\n start,\n parent;\n\n if (arguments.length) {\n return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value));\n }\n\n if (self._dirty) {\n parent = self.parent;\n\n while (child) {\n prev = child._prev; //record it here in case the tween changes position in the sequence...\n\n child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation's cache is clean before analyzing it.\n\n start = child._start;\n\n if (start > prevStart && self._sort && child._ts && !self._lock) {\n //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence\n self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add().\n\n _addToTimeline(self, child, start - child._delay, 1)._lock = 0;\n } else {\n prevStart = start;\n }\n\n if (start < 0 && child._ts) {\n //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.\n max -= start;\n\n if (!parent && !self._dp || parent && parent.smoothChildTiming) {\n self._start += start / self._ts;\n self._time -= start;\n self._tTime -= start;\n }\n\n self.shiftChildren(-start, false, -1e999);\n prevStart = 0;\n }\n\n child._end > max && child._ts && (max = child._end);\n child = prev;\n }\n\n _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1);\n\n self._dirty = 0;\n }\n\n return self._tDur;\n };\n\n Timeline.updateRoot = function updateRoot(time) {\n if (_globalTimeline._ts) {\n _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline));\n\n _lastRenderedFrame = _ticker.frame;\n }\n\n if (_ticker.frame >= _nextGCFrame) {\n _nextGCFrame += _config.autoSleep || 120;\n var child = _globalTimeline._first;\n if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) {\n while (child && !child._ts) {\n child = child._next;\n }\n\n child || _ticker.sleep();\n }\n }\n };\n\n return Timeline;\n}(Animation);\n\n_setDefaults(Timeline.prototype, {\n _lock: 0,\n _hasPause: 0,\n _forcing: 0\n});\n\nvar _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) {\n //note: we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter),\n index = 0,\n matchIndex = 0,\n result,\n startNums,\n color,\n endNum,\n chunk,\n startNum,\n hasRandom,\n a;\n pt.b = start;\n pt.e = end;\n start += \"\"; //ensure values are strings\n\n end += \"\";\n\n if (hasRandom = ~end.indexOf(\"random(\")) {\n end = _replaceRandom(end);\n }\n\n if (stringFilter) {\n a = [start, end];\n stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.\n\n start = a[0];\n end = a[1];\n }\n\n startNums = start.match(_complexStringNumExp) || [];\n\n while (result = _complexStringNumExp.exec(end)) {\n endNum = result[0];\n chunk = end.substring(index, result.index);\n\n if (color) {\n color = (color + 1) % 5;\n } else if (chunk.substr(-5) === \"rgba(\") {\n color = 1;\n }\n\n if (endNum !== startNums[matchIndex++]) {\n startNum = parseFloat(startNums[matchIndex - 1]) || 0; //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method.\n\n pt._pt = {\n _next: pt._pt,\n p: chunk || matchIndex === 1 ? chunk : \",\",\n //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.\n s: startNum,\n c: endNum.charAt(1) === \"=\" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum,\n m: color && color < 4 ? Math.round : 0\n };\n index = _complexStringNumExp.lastIndex;\n }\n }\n\n pt.c = index < end.length ? end.substring(index, end.length) : \"\"; //we use the \"c\" of the PropTween to store the final part of the string (after the last number)\n\n pt.fp = funcParam;\n\n if (_relExp.test(end) || hasRandom) {\n pt.e = 0; //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value).\n }\n\n this._pt = pt; //start the linked list with this new PropTween. Remember, we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n\n return pt;\n},\n _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {\n _isFunction(end) && (end = end(index || 0, target, targets));\n var currentValue = target[prop],\n parsedStart = start !== \"get\" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf(\"set\") || !_isFunction(target[\"get\" + prop.substr(3)]) ? prop : \"get\" + prop.substr(3)](funcParam) : target[prop](),\n setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc,\n pt;\n\n if (_isString(end)) {\n if (~end.indexOf(\"random(\")) {\n end = _replaceRandom(end);\n }\n\n if (end.charAt(1) === \"=\") {\n pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0);\n\n if (pt || pt === 0) {\n // to avoid isNaN, like if someone passes in a value like \"!= whatever\"\n end = pt;\n }\n }\n }\n\n if (!optional || parsedStart !== end || _forceAllPropTweens) {\n if (!isNaN(parsedStart * end) && end !== \"\") {\n // fun fact: any number multiplied by \"\" is evaluated as the number 0!\n pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === \"boolean\" ? _renderBoolean : _renderPlain, 0, setter);\n funcParam && (pt.fp = funcParam);\n modifier && pt.modifier(modifier, this, target);\n return this._pt = pt;\n }\n\n !currentValue && !(prop in target) && _missingPlugin(prop, end);\n return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam);\n }\n},\n //creates a copy of the vars object and processes any function-based values (putting the resulting values directly into the copy) as well as strings with \"random()\" in them. It does NOT process relative values.\n_processVars = function _processVars(vars, index, target, targets, tween) {\n _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets));\n\n if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) {\n return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars;\n }\n\n var copy = {},\n p;\n\n for (p in vars) {\n copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets);\n }\n\n return copy;\n},\n _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) {\n var plugin, pt, ptLookup, i;\n\n if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) {\n tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n if (tween !== _quickTween) {\n ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; //note: we can't use tween._ptLookup[index] because for staggered tweens, the index from the fullTargets array won't match what it is in each individual tween that spawns from the stagger.\n\n i = plugin._props.length;\n\n while (i--) {\n ptLookup[plugin._props[i]] = pt;\n }\n }\n }\n\n return plugin;\n},\n _overwritingTween,\n //store a reference temporarily so we can avoid overwriting itself.\n_forceAllPropTweens,\n _initTween = function _initTween(tween, time, tTime) {\n var vars = tween.vars,\n ease = vars.ease,\n startAt = vars.startAt,\n immediateRender = vars.immediateRender,\n lazy = vars.lazy,\n onUpdate = vars.onUpdate,\n onUpdateParams = vars.onUpdateParams,\n callbackScope = vars.callbackScope,\n runBackwards = vars.runBackwards,\n yoyoEase = vars.yoyoEase,\n keyframes = vars.keyframes,\n autoRevert = vars.autoRevert,\n dur = tween._dur,\n prevStartAt = tween._startAt,\n targets = tween._targets,\n parent = tween.parent,\n fullTargets = parent && parent.data === \"nested\" ? parent.vars.targets : targets,\n autoOverwrite = tween._overwrite === \"auto\" && !_suppressOverwrites,\n tl = tween.timeline,\n cleanVars,\n i,\n p,\n pt,\n target,\n hasPriority,\n gsData,\n harness,\n plugin,\n ptLookup,\n index,\n harnessVars,\n overwritten;\n tl && (!keyframes || !ease) && (ease = \"none\");\n tween._ease = _parseEase(ease, _defaults.ease);\n tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0;\n\n if (yoyoEase && tween._yoyo && !tween._repeat) {\n //there must have been a parent timeline with yoyo:true that is currently in its yoyo phase, so flip the eases.\n yoyoEase = tween._yEase;\n tween._yEase = tween._ease;\n tween._ease = yoyoEase;\n }\n\n tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens.\n\n if (!tl || keyframes && !vars.stagger) {\n //if there's an internal timeline, skip all the parsing because we passed that task down the chain.\n harness = targets[0] ? _getCache(targets[0]).harness : 0;\n harnessVars = harness && vars[harness.prop]; //someone may need to specify CSS-specific values AND non-CSS values, like if the element has an \"x\" property plus it's a standard DOM element. We allow people to distinguish by wrapping plugin-specific stuff in a css:{} object for example.\n\n cleanVars = _copyExcluding(vars, _reservedProps);\n\n if (prevStartAt) {\n prevStartAt._zTime < 0 && prevStartAt.progress(1); // in case it's a lazy startAt that hasn't rendered yet.\n\n time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); // if it's a \"startAt\" (not \"from()\" or runBackwards: true), we only need to do a shallow revert (keep transforms cached in CSSPlugin)\n // don't just _removeFromParent(prevStartAt.render(-1, true)) because that'll leave inline styles. We're creating a new _startAt for \"startAt\" tweens that re-capture things to ensure that if the pre-tween values changed since the tween was created, they're recorded.\n\n prevStartAt._lazy = 0;\n }\n\n if (startAt) {\n _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({\n data: \"isStart\",\n overwrite: false,\n parent: parent,\n immediateRender: true,\n lazy: !prevStartAt && _isNotFalse(lazy),\n startAt: null,\n delay: 0,\n onUpdate: onUpdate,\n onUpdateParams: onUpdateParams,\n callbackScope: callbackScope,\n stagger: 0\n }, startAt))); //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, from, to).fromTo(e, to, from);\n\n\n tween._startAt._dp = 0; // don't allow it to get put back into root timeline! Like when revert() is called and totalTime() gets set.\n\n tween._startAt._sat = tween; // used in globalTime(). _sat stands for _startAtTween\n\n time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); // rare edge case, like if a render is forced in the negative direction of a non-initted tween.\n\n if (immediateRender) {\n if (dur && time <= 0 && tTime <= 0) {\n // check tTime here because in the case of a yoyo tween whose playhead gets pushed to the end like tween.progress(1), we should allow it through so that the onComplete gets fired properly.\n time && (tween._zTime = time);\n return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a Timeline, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting.\n }\n }\n } else if (runBackwards && dur) {\n //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards)\n if (!prevStartAt) {\n time && (immediateRender = false); //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0\n\n p = _setDefaults({\n overwrite: false,\n data: \"isFromStart\",\n //we tag the tween with as \"isFromStart\" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a \"from()\" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:\"height\", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in.\n lazy: immediateRender && !prevStartAt && _isNotFalse(lazy),\n immediateRender: immediateRender,\n //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after)\n stagger: 0,\n parent: parent //ensures that nested tweens that had a stagger are handled properly, like gsap.from(\".class\", {y:gsap.utils.wrap([-100,100])})\n\n }, cleanVars);\n harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}})\n\n _removeFromParent(tween._startAt = Tween.set(targets, p));\n\n tween._startAt._dp = 0; // don't allow it to get put back into root timeline!\n\n tween._startAt._sat = tween; // used in globalTime()\n\n time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true));\n tween._zTime = time;\n\n if (!immediateRender) {\n _initTween(tween._startAt, _tinyNum, _tinyNum); //ensures that the initial values are recorded\n\n } else if (!time) {\n return;\n }\n }\n }\n\n tween._pt = tween._ptCache = 0;\n lazy = dur && _isNotFalse(lazy) || lazy && !dur;\n\n for (i = 0; i < targets.length; i++) {\n target = targets[i];\n gsData = target._gsap || _harness(targets)[i]._gsap;\n tween._ptLookup[i] = ptLookup = {};\n _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end)\n\n index = fullTargets === targets ? i : fullTargets.indexOf(target);\n\n if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) {\n tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n plugin._props.forEach(function (name) {\n ptLookup[name] = pt;\n });\n\n plugin.priority && (hasPriority = 1);\n }\n\n if (!harness || harnessVars) {\n for (p in cleanVars) {\n if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) {\n plugin.priority && (hasPriority = 1);\n } else {\n ptLookup[p] = pt = _addPropTween.call(tween, target, p, \"get\", cleanVars[p], index, fullTargets, 0, vars.stringFilter);\n }\n }\n }\n\n tween._op && tween._op[i] && tween.kill(target, tween._op[i]);\n\n if (autoOverwrite && tween._pt) {\n _overwritingTween = tween;\n\n _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); // make sure the overwriting doesn't overwrite THIS tween!!!\n\n\n overwritten = !tween.parent;\n _overwritingTween = 0;\n }\n\n tween._pt && lazy && (_lazyLookup[gsData.id] = 1);\n }\n\n hasPriority && _sortPropTweensByPriority(tween);\n tween._onInit && tween._onInit(tween); //plugins like RoundProps must wait until ALL of the PropTweens are instantiated. In the plugin's init() function, it sets the _onInit on the tween instance. May not be pretty/intuitive, but it's fast and keeps file size down.\n }\n\n tween._onUpdate = onUpdate;\n tween._initted = (!tween._op || tween._pt) && !overwritten; // if overwrittenProps resulted in the entire tween being killed, do NOT flag it as initted or else it may render for one tick.\n\n keyframes && time <= 0 && tl.render(_bigNum, true, true); // if there's a 0% keyframe, it'll render in the \"before\" state for any staggered/delayed animations thus when the following tween initializes, it'll use the \"before\" state instead of the \"after\" state as the initial values.\n},\n _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time) {\n var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property],\n pt,\n rootPT,\n lookup,\n i;\n\n if (!ptCache) {\n ptCache = tween._ptCache[property] = [];\n lookup = tween._ptLookup;\n i = tween._targets.length;\n\n while (i--) {\n pt = lookup[i][property];\n\n if (pt && pt.d && pt.d._pt) {\n // it's a plugin, so find the nested PropTween\n pt = pt.d._pt;\n\n while (pt && pt.p !== property && pt.fp !== property) {\n // \"fp\" is functionParam for things like setting CSS variables which require .setProperty(\"--var-name\", value)\n pt = pt._next;\n }\n }\n\n if (!pt) {\n // there is no PropTween associated with that property, so we must FORCE one to be created and ditch out of this\n // if the tween has other properties that already rendered at new positions, we'd normally have to rewind to put them back like tween.render(0, true) before forcing an _initTween(), but that can create another edge case like tweening a timeline's progress would trigger onUpdates to fire which could move other things around. It's better to just inform users that .resetTo() should ONLY be used for tweens that already have that property. For example, you can't gsap.to(...{ y: 0 }) and then tween.restTo(\"x\", 200) for example.\n _forceAllPropTweens = 1; // otherwise, when we _addPropTween() and it finds no change between the start and end values, it skips creating a PropTween (for efficiency...why tween when there's no difference?) but in this case we NEED that PropTween created so we can edit it.\n\n tween.vars[property] = \"+=0\";\n\n _initTween(tween, time);\n\n _forceAllPropTweens = 0;\n return 1;\n }\n\n ptCache.push(pt);\n }\n }\n\n i = ptCache.length;\n\n while (i--) {\n rootPT = ptCache[i];\n pt = rootPT._pt || rootPT; // complex values may have nested PropTweens. We only accommodate the FIRST value.\n\n pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c;\n pt.c = value - pt.s;\n rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); // mainly for CSSPlugin (end value)\n\n rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); // (beginning value)\n }\n},\n _addAliasesToVars = function _addAliasesToVars(targets, vars) {\n var harness = targets[0] ? _getCache(targets[0]).harness : 0,\n propertyAliases = harness && harness.aliases,\n copy,\n p,\n i,\n aliases;\n\n if (!propertyAliases) {\n return vars;\n }\n\n copy = _merge({}, vars);\n\n for (p in propertyAliases) {\n if (p in copy) {\n aliases = propertyAliases[p].split(\",\");\n i = aliases.length;\n\n while (i--) {\n copy[aliases[i]] = copy[p];\n }\n }\n }\n\n return copy;\n},\n // parses multiple formats, like {\"0%\": {x: 100}, {\"50%\": {x: -20}} and { x: {\"0%\": 100, \"50%\": -20} }, and an \"ease\" can be set on any object. We populate an \"allProps\" object with an Array for each property, like {x: [{}, {}], y:[{}, {}]} with data for each property tween. The objects have a \"t\" (time), \"v\", (value), and \"e\" (ease) property. This allows us to piece together a timeline later.\n_parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) {\n var ease = obj.ease || easeEach || \"power1.inOut\",\n p,\n a;\n\n if (_isArray(obj)) {\n a = allProps[prop] || (allProps[prop] = []); // t = time (out of 100), v = value, e = ease\n\n obj.forEach(function (value, i) {\n return a.push({\n t: i / (obj.length - 1) * 100,\n v: value,\n e: ease\n });\n });\n } else {\n for (p in obj) {\n a = allProps[p] || (allProps[p] = []);\n p === \"ease\" || a.push({\n t: parseFloat(prop),\n v: obj[p],\n e: ease\n });\n }\n }\n},\n _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) {\n return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf(\"random(\") ? _replaceRandom(value) : value;\n},\n _staggerTweenProps = _callbackNames + \"repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert\",\n _staggerPropsToSkip = {};\n\n_forEachName(_staggerTweenProps + \",id,stagger,delay,duration,paused,scrollTrigger\", function (name) {\n return _staggerPropsToSkip[name] = 1;\n});\n/*\n * --------------------------------------------------------------------------------------\n * TWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar Tween = /*#__PURE__*/function (_Animation2) {\n _inheritsLoose(Tween, _Animation2);\n\n function Tween(targets, vars, position, skipInherit) {\n var _this3;\n\n if (typeof vars === \"number\") {\n position.duration = vars;\n vars = position;\n position = null;\n }\n\n _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this;\n var _this3$vars = _this3.vars,\n duration = _this3$vars.duration,\n delay = _this3$vars.delay,\n immediateRender = _this3$vars.immediateRender,\n stagger = _this3$vars.stagger,\n overwrite = _this3$vars.overwrite,\n keyframes = _this3$vars.keyframes,\n defaults = _this3$vars.defaults,\n scrollTrigger = _this3$vars.scrollTrigger,\n yoyoEase = _this3$vars.yoyoEase,\n parent = vars.parent || _globalTimeline,\n parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : \"length\" in vars) ? [targets] : toArray(targets),\n tl,\n i,\n copy,\n l,\n p,\n curTarget,\n staggerFunc,\n staggerVarsToMerge;\n _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn(\"GSAP target \" + targets + \" not found. https://greensock.com\", !_config.nullTargetWarn) || [];\n _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property\n\n _this3._overwrite = overwrite;\n\n if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n vars = _this3.vars;\n tl = _this3.timeline = new Timeline({\n data: \"nested\",\n defaults: defaults || {},\n targets: parent && parent.data === \"nested\" ? parent.vars.targets : parsedTargets\n }); // we need to store the targets because for staggers and keyframes, we end up creating an individual tween for each but function-based values need to know the index and the whole Array of targets.\n\n tl.kill();\n tl.parent = tl._dp = _assertThisInitialized(_this3);\n tl._start = 0;\n\n if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n l = parsedTargets.length;\n staggerFunc = stagger && distribute(stagger);\n\n if (_isObject(stagger)) {\n //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween.\n for (p in stagger) {\n if (~_staggerTweenProps.indexOf(p)) {\n staggerVarsToMerge || (staggerVarsToMerge = {});\n staggerVarsToMerge[p] = stagger[p];\n }\n }\n }\n\n for (i = 0; i < l; i++) {\n copy = _copyExcluding(vars, _staggerPropsToSkip);\n copy.stagger = 0;\n yoyoEase && (copy.yoyoEase = yoyoEase);\n staggerVarsToMerge && _merge(copy, staggerVarsToMerge);\n curTarget = parsedTargets[i]; //don't just copy duration or delay because if they're a string or function, we'd end up in an infinite loop because _isFuncOrString() would evaluate as true in the child tweens, entering this loop, etc. So we parse the value straight from vars and default to 0.\n\n copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets);\n copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay;\n\n if (!stagger && l === 1 && copy.delay) {\n // if someone does delay:\"random(1, 5)\", repeat:-1, for example, the delay shouldn't be inside the repeat.\n _this3._delay = delay = copy.delay;\n _this3._start += delay;\n copy.delay = 0;\n }\n\n tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0);\n tl._ease = _easeMap.none;\n }\n\n tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline's duration is 0, we don't need a timeline internally!\n } else if (keyframes) {\n _inheritDefaults(_setDefaults(tl.vars.defaults, {\n ease: \"none\"\n }));\n\n tl._ease = _parseEase(keyframes.ease || vars.ease || \"none\");\n var time = 0,\n a,\n kf,\n v;\n\n if (_isArray(keyframes)) {\n keyframes.forEach(function (frame) {\n return tl.to(parsedTargets, frame, \">\");\n });\n tl.duration(); // to ensure tl._dur is cached because we tap into it for performance purposes in the render() method.\n } else {\n copy = {};\n\n for (p in keyframes) {\n p === \"ease\" || p === \"easeEach\" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach);\n }\n\n for (p in copy) {\n a = copy[p].sort(function (a, b) {\n return a.t - b.t;\n });\n time = 0;\n\n for (i = 0; i < a.length; i++) {\n kf = a[i];\n v = {\n ease: kf.e,\n duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration\n };\n v[p] = kf.v;\n tl.to(parsedTargets, v, time);\n time += v.duration;\n }\n }\n\n tl.duration() < duration && tl.to({}, {\n duration: duration - tl.duration()\n }); // in case keyframes didn't go to 100%\n }\n }\n\n duration || _this3.duration(duration = tl.duration());\n } else {\n _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain)\n }\n\n if (overwrite === true && !_suppressOverwrites) {\n _overwritingTween = _assertThisInitialized(_this3);\n\n _globalTimeline.killTweensOf(parsedTargets);\n\n _overwritingTween = 0;\n }\n\n _addToTimeline(parent, _assertThisInitialized(_this3), position);\n\n vars.reversed && _this3.reverse();\n vars.paused && _this3.paused(true);\n\n if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== \"nested\") {\n _this3._tTime = -_tinyNum; //forces a render without having to set the render() \"force\" parameter to true because we want to allow lazying by default (using the \"force\" parameter always forces an immediate full render)\n\n _this3.render(Math.max(0, -delay) || 0); //in case delay is negative\n\n }\n\n scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger);\n return _this3;\n }\n\n var _proto3 = Tween.prototype;\n\n _proto3.render = function render(totalTime, suppressEvents, force) {\n var prevTime = this._time,\n tDur = this._tDur,\n dur = this._dur,\n isNegative = totalTime < 0,\n tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime,\n time,\n pt,\n iteration,\n cycleDuration,\n prevIteration,\n isYoyo,\n ratio,\n timeline,\n yoyoEase;\n\n if (!dur) {\n _renderZeroDurationTween(this, totalTime, suppressEvents, force);\n } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) {\n //this senses if we're crossing over the start time, in which case we must record _zTime and force the render, but we do it in this lengthy conditional way for performance reasons (usually we can skip the calculations): this._initted && (this._zTime < 0) !== (totalTime < 0)\n time = tTime;\n timeline = this.timeline;\n\n if (this._repeat) {\n //adjust the time for repeats and yoyos\n cycleDuration = dur + this._rDelay;\n\n if (this._repeat < -1 && isNegative) {\n return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n }\n\n time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n if (tTime === tDur) {\n // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't)\n iteration = this._repeat;\n time = dur;\n } else {\n iteration = ~~(tTime / cycleDuration);\n\n if (iteration && iteration === tTime / cycleDuration) {\n time = dur;\n iteration--;\n }\n\n time > dur && (time = dur);\n }\n\n isYoyo = this._yoyo && iteration & 1;\n\n if (isYoyo) {\n yoyoEase = this._yEase;\n time = dur - time;\n }\n\n prevIteration = _animationCycle(this._tTime, cycleDuration);\n\n if (time === prevTime && !force && this._initted) {\n //could be during the repeatDelay part. No need to render and fire callbacks.\n this._tTime = tTime;\n return this;\n }\n\n if (iteration !== prevIteration) {\n timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); //repeatRefresh functionality\n\n if (this.vars.repeatRefresh && !isYoyo && !this._lock) {\n this._lock = force = 1; //force, otherwise if lazy is true, the _attemptInitTween() will return and we'll jump out and get caught bouncing on each tick.\n\n this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0;\n }\n }\n }\n\n if (!this._initted) {\n if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) {\n this._tTime = 0; // in constructor if immediateRender is true, we set _tTime to -_tinyNum to have the playhead cross the starting point but we can't leave _tTime as a negative number.\n\n return this;\n }\n\n if (prevTime !== this._time) {\n // rare edge case - during initialization, an onUpdate in the _startAt (.fromTo()) might force this tween to render at a different spot in which case we should ditch this render() call so that it doesn't revert the values.\n return this;\n }\n\n if (dur !== this._dur) {\n // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should.\n return this.render(totalTime, suppressEvents, force);\n }\n }\n\n this._tTime = tTime;\n this._time = time;\n\n if (!this._act && this._ts) {\n this._act = 1; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick.\n\n this._lazy = 0;\n }\n\n this.ratio = ratio = (yoyoEase || this._ease)(time / dur);\n\n if (this._from) {\n this.ratio = ratio = 1 - ratio;\n }\n\n if (time && !prevTime && !suppressEvents && !iteration) {\n _callback(this, \"onStart\");\n\n if (this._tTime !== tTime) {\n // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart.\n return this;\n }\n }\n\n pt = this._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime);\n\n if (this._onUpdate && !suppressEvents) {\n isNegative && _rewindStartAt(this, totalTime, suppressEvents, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.\n\n _callback(this, \"onUpdate\");\n }\n\n this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, \"onRepeat\");\n\n if ((tTime === this._tDur || !tTime) && this._tTime === tTime) {\n isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true);\n (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if we're rendering at exactly a time of 0, as there could be autoRevert values that should get set on the next tick (if the playhead goes backward beyond the startTime, negative totalTime). Don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative.\n\n if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) {\n // if prevTime and tTime are zero, we shouldn't fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play();\n _callback(this, tTime === tDur ? \"onComplete\" : \"onReverseComplete\", true);\n\n this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n }\n }\n }\n\n return this;\n };\n\n _proto3.targets = function targets() {\n return this._targets;\n };\n\n _proto3.invalidate = function invalidate(soft) {\n // \"soft\" gives us a way to clear out everything EXCEPT the recorded pre-\"from\" portion of from() tweens. Otherwise, for example, if you tween.progress(1).render(0, true true).invalidate(), the \"from\" values would persist and then on the next render, the from() tweens would initialize and the current value would match the \"from\" values, thus animate from the same value to the same value (no animation). We tap into this in ScrollTrigger's refresh() where we must push a tween to completion and then back again but honor its init state in case the tween is dependent on another tween further up on the page.\n (!soft || !this.vars.runBackwards) && (this._startAt = 0);\n this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0;\n this._ptLookup = [];\n this.timeline && this.timeline.invalidate(soft);\n return _Animation2.prototype.invalidate.call(this, soft);\n };\n\n _proto3.resetTo = function resetTo(property, value, start, startIsRelative) {\n _tickerActive || _ticker.wake();\n this._ts || this.play();\n var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts),\n ratio;\n this._initted || _initTween(this, time);\n ratio = this._ease(time / this._dur); // don't just get tween.ratio because it may not have rendered yet.\n // possible future addition to allow an object with multiple values to update, like tween.resetTo({x: 100, y: 200}); At this point, it doesn't seem worth the added kb given the fact that most users will likely opt for the convenient gsap.quickTo() way of interacting with this method.\n // if (_isObject(property)) { // performance optimization\n // \tfor (p in property) {\n // \t\tif (_updatePropTweens(this, p, property[p], value ? value[p] : null, start, ratio, time)) {\n // \t\t\treturn this.resetTo(property, value, start, startIsRelative); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again.\n // \t\t}\n // \t}\n // } else {\n\n if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time)) {\n return this.resetTo(property, value, start, startIsRelative); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again.\n } //}\n\n\n _alignPlayhead(this, 0);\n\n this.parent || _addLinkedListItem(this._dp, this, \"_first\", \"_last\", this._dp._sort ? \"_start\" : 0);\n return this.render(0);\n };\n\n _proto3.kill = function kill(targets, vars) {\n if (vars === void 0) {\n vars = \"all\";\n }\n\n if (!targets && (!vars || vars === \"all\")) {\n this._lazy = this._pt = 0;\n return this.parent ? _interrupt(this) : this;\n }\n\n if (this.timeline) {\n var tDur = this.timeline.totalDuration();\n this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt.\n\n this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); // if a nested tween is killed that changes the duration, it should affect this tween's duration. We must use the ratio, though, because sometimes the internal timeline is stretched like for keyframes where they don't all add up to whatever the parent tween's duration was set to.\n\n return this;\n }\n\n var parsedTargets = this._targets,\n killingTargets = targets ? toArray(targets) : parsedTargets,\n propTweenLookup = this._ptLookup,\n firstPT = this._pt,\n overwrittenProps,\n curLookup,\n curOverwriteProps,\n props,\n p,\n pt,\n i;\n\n if ((!vars || vars === \"all\") && _arraysMatch(parsedTargets, killingTargets)) {\n vars === \"all\" && (this._pt = 0);\n return _interrupt(this);\n }\n\n overwrittenProps = this._op = this._op || [];\n\n if (vars !== \"all\") {\n //so people can pass in a comma-delimited list of property names\n if (_isString(vars)) {\n p = {};\n\n _forEachName(vars, function (name) {\n return p[name] = 1;\n });\n\n vars = p;\n }\n\n vars = _addAliasesToVars(parsedTargets, vars);\n }\n\n i = parsedTargets.length;\n\n while (i--) {\n if (~killingTargets.indexOf(parsedTargets[i])) {\n curLookup = propTweenLookup[i];\n\n if (vars === \"all\") {\n overwrittenProps[i] = vars;\n props = curLookup;\n curOverwriteProps = {};\n } else {\n curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {};\n props = vars;\n }\n\n for (p in props) {\n pt = curLookup && curLookup[p];\n\n if (pt) {\n if (!(\"kill\" in pt.d) || pt.d.kill(p) === true) {\n _removeLinkedListItem(this, pt, \"_pt\");\n }\n\n delete curLookup[p];\n }\n\n if (curOverwriteProps !== \"all\") {\n curOverwriteProps[p] = 1;\n }\n }\n }\n }\n\n this._initted && !this._pt && firstPT && _interrupt(this); //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening.\n\n return this;\n };\n\n Tween.to = function to(targets, vars) {\n return new Tween(targets, vars, arguments[2]);\n };\n\n Tween.from = function from(targets, vars) {\n return _createTweenType(1, arguments);\n };\n\n Tween.delayedCall = function delayedCall(delay, callback, params, scope) {\n return new Tween(callback, 0, {\n immediateRender: false,\n lazy: false,\n overwrite: false,\n delay: delay,\n onComplete: callback,\n onReverseComplete: callback,\n onCompleteParams: params,\n onReverseCompleteParams: params,\n callbackScope: scope\n }); // we must use onReverseComplete too for things like timeline.add(() => {...}) which should be triggered in BOTH directions (forward and reverse)\n };\n\n Tween.fromTo = function fromTo(targets, fromVars, toVars) {\n return _createTweenType(2, arguments);\n };\n\n Tween.set = function set(targets, vars) {\n vars.duration = 0;\n vars.repeatDelay || (vars.repeat = 0);\n return new Tween(targets, vars);\n };\n\n Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n return _globalTimeline.killTweensOf(targets, props, onlyActive);\n };\n\n return Tween;\n}(Animation);\n\n_setDefaults(Tween.prototype, {\n _targets: [],\n _lazy: 0,\n _startAt: 0,\n _op: 0,\n _onInit: 0\n}); //add the pertinent timeline methods to Tween instances so that users can chain conveniently and create a timeline automatically. (removed due to concerns that it'd ultimately add to more confusion especially for beginners)\n// _forEachName(\"to,from,fromTo,set,call,add,addLabel,addPause\", name => {\n// \tTween.prototype[name] = function() {\n// \t\tlet tl = new Timeline();\n// \t\treturn _addToTimeline(tl, this)[name].apply(tl, toArray(arguments));\n// \t}\n// });\n//for backward compatibility. Leverage the timeline calls.\n\n\n_forEachName(\"staggerTo,staggerFrom,staggerFromTo\", function (name) {\n Tween[name] = function () {\n var tl = new Timeline(),\n params = _slice.call(arguments, 0);\n\n params.splice(name === \"staggerFromTo\" ? 5 : 4, 0, 0);\n return tl[name].apply(tl, params);\n };\n});\n/*\n * --------------------------------------------------------------------------------------\n * PROPTWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _setterPlain = function _setterPlain(target, property, value) {\n return target[property] = value;\n},\n _setterFunc = function _setterFunc(target, property, value) {\n return target[property](value);\n},\n _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) {\n return target[property](data.fp, value);\n},\n _setterAttribute = function _setterAttribute(target, property, value) {\n return target.setAttribute(property, value);\n},\n _getSetter = function _getSetter(target, property) {\n return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain;\n},\n _renderPlain = function _renderPlain(ratio, data) {\n return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data);\n},\n _renderBoolean = function _renderBoolean(ratio, data) {\n return data.set(data.t, data.p, !!(data.s + data.c * ratio), data);\n},\n _renderComplexString = function _renderComplexString(ratio, data) {\n var pt = data._pt,\n s = \"\";\n\n if (!ratio && data.b) {\n //b = beginning string\n s = data.b;\n } else if (ratio === 1 && data.e) {\n //e = ending string\n s = data.e;\n } else {\n while (pt) {\n s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; //we use the \"p\" property for the text inbetween (like a suffix). And in the context of a complex string, the modifier (m) is typically just Math.round(), like for RGB colors.\n\n pt = pt._next;\n }\n\n s += data.c; //we use the \"c\" of the PropTween to store the final chunk of non-numeric text.\n }\n\n data.set(data.t, data.p, s, data);\n},\n _renderPropTweens = function _renderPropTweens(ratio, data) {\n var pt = data._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n},\n _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) {\n var pt = this._pt,\n next;\n\n while (pt) {\n next = pt._next;\n pt.p === property && pt.modifier(modifier, tween, target);\n pt = next;\n }\n},\n _killPropTweensOf = function _killPropTweensOf(property) {\n var pt = this._pt,\n hasNonDependentRemaining,\n next;\n\n while (pt) {\n next = pt._next;\n\n if (pt.p === property && !pt.op || pt.op === property) {\n _removeLinkedListItem(this, pt, \"_pt\");\n } else if (!pt.dep) {\n hasNonDependentRemaining = 1;\n }\n\n pt = next;\n }\n\n return !hasNonDependentRemaining;\n},\n _setterWithModifier = function _setterWithModifier(target, property, value, data) {\n data.mSet(target, property, data.m.call(data.tween, value, data.mt), data);\n},\n _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) {\n var pt = parent._pt,\n next,\n pt2,\n first,\n last; //sorts the PropTween linked list in order of priority because some plugins need to do their work after ALL of the PropTweens were created (like RoundPropsPlugin and ModifiersPlugin)\n\n while (pt) {\n next = pt._next;\n pt2 = first;\n\n while (pt2 && pt2.pr > pt.pr) {\n pt2 = pt2._next;\n }\n\n if (pt._prev = pt2 ? pt2._prev : last) {\n pt._prev._next = pt;\n } else {\n first = pt;\n }\n\n if (pt._next = pt2) {\n pt2._prev = pt;\n } else {\n last = pt;\n }\n\n pt = next;\n }\n\n parent._pt = first;\n}; //PropTween key: t = target, p = prop, r = renderer, d = data, s = start, c = change, op = overwriteProperty (ONLY populated when it's different than p), pr = priority, _next/_prev for the linked list siblings, set = setter, m = modifier, mSet = modifierSetter (the original setter, before a modifier was added)\n\n\nvar PropTween = /*#__PURE__*/function () {\n function PropTween(next, target, prop, start, change, renderer, data, setter, priority) {\n this.t = target;\n this.s = start;\n this.c = change;\n this.p = prop;\n this.r = renderer || _renderPlain;\n this.d = data || this;\n this.set = setter || _setterPlain;\n this.pr = priority || 0;\n this._next = next;\n\n if (next) {\n next._prev = this;\n }\n }\n\n var _proto4 = PropTween.prototype;\n\n _proto4.modifier = function modifier(func, tween, target) {\n this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier)\n\n this.set = _setterWithModifier;\n this.m = func;\n this.mt = target; //modifier target\n\n this.tween = tween;\n };\n\n return PropTween;\n}(); //Initialization tasks\n\n_forEachName(_callbackNames + \"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger\", function (name) {\n return _reservedProps[name] = 1;\n});\n\n_globals.TweenMax = _globals.TweenLite = Tween;\n_globals.TimelineLite = _globals.TimelineMax = Timeline;\n_globalTimeline = new Timeline({\n sortChildren: false,\n defaults: _defaults,\n autoRemoveChildren: true,\n id: \"root\",\n smoothChildTiming: true\n});\n_config.stringFilter = _colorStringFilter;\n\nvar _media = [],\n _listeners = {},\n _emptyArray = [],\n _lastMediaTime = 0,\n _dispatch = function _dispatch(type) {\n return (_listeners[type] || _emptyArray).map(function (f) {\n return f();\n });\n},\n _onMediaChange = function _onMediaChange() {\n var time = Date.now(),\n matches = [];\n\n if (time - _lastMediaTime > 2) {\n _dispatch(\"matchMediaInit\");\n\n _media.forEach(function (c) {\n var queries = c.queries,\n conditions = c.conditions,\n match,\n p,\n anyMatch,\n toggled;\n\n for (p in queries) {\n match = _win.matchMedia(queries[p]).matches; // Firefox doesn't update the \"matches\" property of the MediaQueryList object correctly - it only does so as it calls its change handler - so we must re-create a media query here to ensure it's accurate.\n\n match && (anyMatch = 1);\n\n if (match !== conditions[p]) {\n conditions[p] = match;\n toggled = 1;\n }\n }\n\n if (toggled) {\n c.revert();\n anyMatch && matches.push(c);\n }\n });\n\n _dispatch(\"matchMediaRevert\");\n\n matches.forEach(function (c) {\n return c.onMatch(c);\n });\n _lastMediaTime = time;\n\n _dispatch(\"matchMedia\");\n }\n};\n\nvar Context = /*#__PURE__*/function () {\n function Context(func, scope) {\n this.selector = scope && selector(scope);\n this.data = [];\n this._r = []; // returned/cleanup functions\n\n this.isReverted = false;\n func && this.add(func);\n }\n\n var _proto5 = Context.prototype;\n\n _proto5.add = function add(name, func, scope) {\n // possible future addition if we need the ability to add() an animation to a context and for whatever reason cannot create that animation inside of a context.add(() => {...}) function.\n // if (name && _isFunction(name.revert)) {\n // \tthis.data.push(name);\n // \treturn (name._ctx = this);\n // }\n if (_isFunction(name)) {\n scope = func;\n func = name;\n name = _isFunction;\n }\n\n var self = this,\n f = function f() {\n var prev = _context,\n prevSelector = self.selector,\n result;\n prev && prev !== self && prev.data.push(self);\n scope && (self.selector = selector(scope));\n _context = self;\n result = func.apply(self, arguments);\n _isFunction(result) && self._r.push(result);\n _context = prev;\n self.selector = prevSelector;\n self.isReverted = false;\n return result;\n };\n\n self.last = f;\n return name === _isFunction ? f(self) : name ? self[name] = f : f;\n };\n\n _proto5.ignore = function ignore(func) {\n var prev = _context;\n _context = null;\n func(this);\n _context = prev;\n };\n\n _proto5.getTweens = function getTweens() {\n var a = [];\n this.data.forEach(function (e) {\n return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === \"nested\") && a.push(e);\n });\n return a;\n };\n\n _proto5.clear = function clear() {\n this._r.length = this.data.length = 0;\n };\n\n _proto5.kill = function kill(revert, matchMedia) {\n var _this4 = this;\n\n if (revert) {\n var tweens = this.getTweens();\n this.data.forEach(function (t) {\n // Flip plugin tweens are very different in that they should actually be pushed to their end. The plugin replaces the timeline's .revert() method to do exactly that. But we also need to remove any of those nested tweens inside the flip timeline so that they don't get individually reverted.\n if (t.data === \"isFlip\") {\n t.revert();\n t.getChildren(true, true, false).forEach(function (tween) {\n return tweens.splice(tweens.indexOf(tween), 1);\n });\n }\n }); // save as an object so that we can cache the globalTime for each tween to optimize performance during the sort\n\n tweens.map(function (t) {\n return {\n g: t.globalTime(0),\n t: t\n };\n }).sort(function (a, b) {\n return b.g - a.g || -1;\n }).forEach(function (o) {\n return o.t.revert(revert);\n }); // note: all of the _startAt tweens should be reverted in reverse order that they were created, and they'll all have the same globalTime (-1) so the \" || -1\" in the sort keeps the order properly.\n\n this.data.forEach(function (e) {\n return !(e instanceof Animation) && e.revert && e.revert(revert);\n });\n\n this._r.forEach(function (f) {\n return f(revert, _this4);\n });\n\n this.isReverted = true;\n } else {\n this.data.forEach(function (e) {\n return e.kill && e.kill();\n });\n }\n\n this.clear();\n\n if (matchMedia) {\n var i = _media.indexOf(this);\n\n !!~i && _media.splice(i, 1);\n }\n };\n\n _proto5.revert = function revert(config) {\n this.kill(config || {});\n };\n\n return Context;\n}();\n\nvar MatchMedia = /*#__PURE__*/function () {\n function MatchMedia(scope) {\n this.contexts = [];\n this.scope = scope;\n }\n\n var _proto6 = MatchMedia.prototype;\n\n _proto6.add = function add(conditions, func, scope) {\n _isObject(conditions) || (conditions = {\n matches: conditions\n });\n var context = new Context(0, scope || this.scope),\n cond = context.conditions = {},\n mq,\n p,\n active;\n this.contexts.push(context);\n func = context.add(\"onMatch\", func);\n context.queries = conditions;\n\n for (p in conditions) {\n if (p === \"all\") {\n active = 1;\n } else {\n mq = _win.matchMedia(conditions[p]);\n\n if (mq) {\n _media.indexOf(context) < 0 && _media.push(context);\n (cond[p] = mq.matches) && (active = 1);\n mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener(\"change\", _onMediaChange);\n }\n }\n }\n\n active && func(context);\n return this;\n } // refresh() {\n // \tlet time = _lastMediaTime,\n // \t\tmedia = _media;\n // \t_lastMediaTime = -1;\n // \t_media = this.contexts;\n // \t_onMediaChange();\n // \t_lastMediaTime = time;\n // \t_media = media;\n // }\n ;\n\n _proto6.revert = function revert(config) {\n this.kill(config || {});\n };\n\n _proto6.kill = function kill(revert) {\n this.contexts.forEach(function (c) {\n return c.kill(revert, true);\n });\n };\n\n return MatchMedia;\n}();\n/*\n * --------------------------------------------------------------------------------------\n * GSAP\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _gsap = {\n registerPlugin: function registerPlugin() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n args.forEach(function (config) {\n return _createPlugin(config);\n });\n },\n timeline: function timeline(vars) {\n return new Timeline(vars);\n },\n getTweensOf: function getTweensOf(targets, onlyActive) {\n return _globalTimeline.getTweensOf(targets, onlyActive);\n },\n getProperty: function getProperty(target, property, unit, uncache) {\n _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in\n\n var getter = _getCache(target || {}).get,\n format = unit ? _passThrough : _numericIfPossible;\n\n unit === \"native\" && (unit = \"\");\n return !target ? target : !property ? function (property, unit, uncache) {\n return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n },\n quickSetter: function quickSetter(target, property, unit) {\n target = toArray(target);\n\n if (target.length > 1) {\n var setters = target.map(function (t) {\n return gsap.quickSetter(t, property, unit);\n }),\n l = setters.length;\n return function (value) {\n var i = l;\n\n while (i--) {\n setters[i](value);\n }\n };\n }\n\n target = target[0] || {};\n\n var Plugin = _plugins[property],\n cache = _getCache(target),\n p = cache.harness && (cache.harness.aliases || {})[property] || property,\n // in case it's an alias, like \"rotate\" for \"rotation\".\n setter = Plugin ? function (value) {\n var p = new Plugin();\n _quickTween._pt = 0;\n p.init(target, unit ? value + unit : value, _quickTween, 0, [target]);\n p.render(1, p);\n _quickTween._pt && _renderPropTweens(1, _quickTween);\n } : cache.set(target, p);\n\n return Plugin ? setter : function (value) {\n return setter(target, p, unit ? value + unit : value, cache, 1);\n };\n },\n quickTo: function quickTo(target, property, vars) {\n var _merge2;\n\n var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = \"+=0.1\", _merge2.paused = true, _merge2), vars || {})),\n func = function func(value, start, startIsRelative) {\n return tween.resetTo(property, value, start, startIsRelative);\n };\n\n func.tween = tween;\n return func;\n },\n isTweening: function isTweening(targets) {\n return _globalTimeline.getTweensOf(targets, true).length > 0;\n },\n defaults: function defaults(value) {\n value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease));\n return _mergeDeep(_defaults, value || {});\n },\n config: function config(value) {\n return _mergeDeep(_config, value || {});\n },\n registerEffect: function registerEffect(_ref3) {\n var name = _ref3.name,\n effect = _ref3.effect,\n plugins = _ref3.plugins,\n defaults = _ref3.defaults,\n extendTimeline = _ref3.extendTimeline;\n (plugins || \"\").split(\",\").forEach(function (pluginName) {\n return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + \" effect requires \" + pluginName + \" plugin.\");\n });\n\n _effects[name] = function (targets, vars, tl) {\n return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl);\n };\n\n if (extendTimeline) {\n Timeline.prototype[name] = function (targets, vars, position) {\n return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position);\n };\n }\n },\n registerEase: function registerEase(name, ease) {\n _easeMap[name] = _parseEase(ease);\n },\n parseEase: function parseEase(ease, defaultEase) {\n return arguments.length ? _parseEase(ease, defaultEase) : _easeMap;\n },\n getById: function getById(id) {\n return _globalTimeline.getById(id);\n },\n exportRoot: function exportRoot(vars, includeDelayedCalls) {\n if (vars === void 0) {\n vars = {};\n }\n\n var tl = new Timeline(vars),\n child,\n next;\n tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming);\n\n _globalTimeline.remove(tl);\n\n tl._dp = 0; //otherwise it'll get re-activated when adding children and be re-introduced into _globalTimeline's linked list (then added to itself).\n\n tl._time = tl._tTime = _globalTimeline._time;\n child = _globalTimeline._first;\n\n while (child) {\n next = child._next;\n\n if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {\n _addToTimeline(tl, child, child._start - child._delay);\n }\n\n child = next;\n }\n\n _addToTimeline(_globalTimeline, tl, 0);\n\n return tl;\n },\n context: function context(func, scope) {\n return func ? new Context(func, scope) : _context;\n },\n matchMedia: function matchMedia(scope) {\n return new MatchMedia(scope);\n },\n matchMediaRefresh: function matchMediaRefresh() {\n return _media.forEach(function (c) {\n var cond = c.conditions,\n found,\n p;\n\n for (p in cond) {\n if (cond[p]) {\n cond[p] = false;\n found = 1;\n }\n }\n\n found && c.revert();\n }) || _onMediaChange();\n },\n addEventListener: function addEventListener(type, callback) {\n var a = _listeners[type] || (_listeners[type] = []);\n ~a.indexOf(callback) || a.push(callback);\n },\n removeEventListener: function removeEventListener(type, callback) {\n var a = _listeners[type],\n i = a && a.indexOf(callback);\n i >= 0 && a.splice(i, 1);\n },\n utils: {\n wrap: wrap,\n wrapYoyo: wrapYoyo,\n distribute: distribute,\n random: random,\n snap: snap,\n normalize: normalize,\n getUnit: getUnit,\n clamp: clamp,\n splitColor: splitColor,\n toArray: toArray,\n selector: selector,\n mapRange: mapRange,\n pipe: pipe,\n unitize: unitize,\n interpolate: interpolate,\n shuffle: shuffle\n },\n install: _install,\n effects: _effects,\n ticker: _ticker,\n updateRoot: Timeline.updateRoot,\n plugins: _plugins,\n globalTimeline: _globalTimeline,\n core: {\n PropTween: PropTween,\n globals: _addGlobal,\n Tween: Tween,\n Timeline: Timeline,\n Animation: Animation,\n getCache: _getCache,\n _removeLinkedListItem: _removeLinkedListItem,\n reverting: function reverting() {\n return _reverting;\n },\n context: function context(toAdd) {\n if (toAdd && _context) {\n _context.data.push(toAdd);\n\n toAdd._ctx = _context;\n }\n\n return _context;\n },\n suppressOverwrites: function suppressOverwrites(value) {\n return _suppressOverwrites = value;\n }\n }\n};\n\n_forEachName(\"to,from,fromTo,delayedCall,set,killTweensOf\", function (name) {\n return _gsap[name] = Tween[name];\n});\n\n_ticker.add(Timeline.updateRoot);\n\n_quickTween = _gsap.to({}, {\n duration: 0\n}); // ---- EXTRA PLUGINS --------------------------------------------------------\n\nvar _getPluginPropTween = function _getPluginPropTween(plugin, prop) {\n var pt = plugin._pt;\n\n while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) {\n pt = pt._next;\n }\n\n return pt;\n},\n _addModifiers = function _addModifiers(tween, modifiers) {\n var targets = tween._targets,\n p,\n i,\n pt;\n\n for (p in modifiers) {\n i = targets.length;\n\n while (i--) {\n pt = tween._ptLookup[i][p];\n\n if (pt && (pt = pt.d)) {\n if (pt._pt) {\n // is a plugin\n pt = _getPluginPropTween(pt, p);\n }\n\n pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p);\n }\n }\n }\n},\n _buildModifierPlugin = function _buildModifierPlugin(name, modifier) {\n return {\n name: name,\n rawVars: 1,\n //don't pre-process function-based values or \"random()\" strings.\n init: function init(target, vars, tween) {\n tween._onInit = function (tween) {\n var temp, p;\n\n if (_isString(vars)) {\n temp = {};\n\n _forEachName(vars, function (name) {\n return temp[name] = 1;\n }); //if the user passes in a comma-delimited list of property names to roundProps, like \"x,y\", we round to whole numbers.\n\n\n vars = temp;\n }\n\n if (modifier) {\n temp = {};\n\n for (p in vars) {\n temp[p] = modifier(vars[p]);\n }\n\n vars = temp;\n }\n\n _addModifiers(tween, vars);\n };\n }\n };\n}; //register core plugins\n\n\nvar gsap = _gsap.registerPlugin({\n name: \"attr\",\n init: function init(target, vars, tween, index, targets) {\n var p, pt, v;\n this.tween = tween;\n\n for (p in vars) {\n v = target.getAttribute(p) || \"\";\n pt = this.add(target, \"setAttribute\", (v || 0) + \"\", vars[p], index, targets, 0, 0, p);\n pt.op = p;\n pt.b = v; // record the beginning value so we can revert()\n\n this._props.push(p);\n }\n },\n render: function render(ratio, data) {\n var pt = data._pt;\n\n while (pt) {\n _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); // if reverting, go back to the original (pt.b)\n\n pt = pt._next;\n }\n }\n}, {\n name: \"endArray\",\n init: function init(target, value) {\n var i = value.length;\n\n while (i--) {\n this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1);\n }\n }\n}, _buildModifierPlugin(\"roundProps\", _roundModifier), _buildModifierPlugin(\"modifiers\"), _buildModifierPlugin(\"snap\", snap)) || _gsap; //to prevent the core plugins from being dropped via aggressive tree shaking, we must include them in the variable declaration in this way.\n\nTween.version = Timeline.version = gsap.version = \"3.11.5\";\n_coreReady = 1;\n_windowExists() && _wake();\nvar Power0 = _easeMap.Power0,\n Power1 = _easeMap.Power1,\n Power2 = _easeMap.Power2,\n Power3 = _easeMap.Power3,\n Power4 = _easeMap.Power4,\n Linear = _easeMap.Linear,\n Quad = _easeMap.Quad,\n Cubic = _easeMap.Cubic,\n Quart = _easeMap.Quart,\n Quint = _easeMap.Quint,\n Strong = _easeMap.Strong,\n Elastic = _easeMap.Elastic,\n Back = _easeMap.Back,\n SteppedEase = _easeMap.SteppedEase,\n Bounce = _easeMap.Bounce,\n Sine = _easeMap.Sine,\n Expo = _easeMap.Expo,\n Circ = _easeMap.Circ;\n\n //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it.\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9nc2FwLWNvcmUuanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsd0NBQXdDLHVCQUF1Qix5RkFBeUY7O0FBRXhKLGdEQUFnRCwwREFBMEQsMkNBQTJDOztBQUVySjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNELDZGQUE2RjtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRCx1QkFBdUI7QUFDdkI7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxpQkFBaUI7QUFDakIsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMkNBQTJDO0FBQzNDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0EsK0pBQStKO0FBQy9KO0FBQ0E7O0FBRUEsU0FBUywyQ0FBMkM7O0FBRXBEO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRDtBQUN0RCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSwySUFBMkk7QUFDM0k7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUEsbURBQW1EO0FBQ25ELENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsa0RBQWtEO0FBQ2xEOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtREFBbUQ7O0FBRW5EO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLGlFQUFpRTs7QUFFakU7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpRUFBaUU7O0FBRWpFLHNFQUFzRTs7QUFFdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkVBQTZFO0FBQzdFOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNB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Q0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBSTs7QUFFSixrQkFBa0I7O0FBRWxCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILENBQUM7O0FBRUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSxvRUFBb0U7QUFDcEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUMsMkJBQTJCO0FBQzNCOztBQUVBLHlEQUF5RDtBQUN6RDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0Esd01BQXdNO0FBQ3hNOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDBHQUEwRztBQUMxRyxzR0FBc0c7QUFDdEc7QUFDQTs7QUFFQTtBQUNBLGdFQUFnRTs7QUFFaEU7O0FBRUEsbUJBQW1COzs7QUFHbkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkVBQTZFOztBQUU3RSxrQ0FBa0M7QUFDbEMsUUFBUTtBQUNSOztBQUVBLDhCQUE4Qjs7QUFFOUIsK01BQStNO0FBQy9NO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBDQUEwQzs7QUFFMUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtSEFBbUg7QUFDbkg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRGQUE0Rjs7QUFFNUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7O0FBRTFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlDQUF5Qzs7QUFFekM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscURBQXFEOztBQUVyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsZ0tBQWdLOztBQUVoSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJCQUEyQjs7QUFFM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxZQUFZOzs7QUFHWjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixxREFBcUQsNk5BQTZOLE9BQU8sV0FBVyxLQUFLO0FBQy9UOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQ7O0FBRTFEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsNkRBQTZEOztBQUU3RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbVFBQW1ROztBQUVuUTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0Y7O0FBRXBGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUM7O0FBRW5DOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx5SEFBeUg7O0FBRXpIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBLDBFQUEwRTtBQUMxRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdFQUFnRTtBQUNoRTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNEJBQTRCOztBQUU1QiwrQ0FBK0M7O0FBRS9DOztBQUVBO0FBQ0E7QUFDQSwwQkFBMEI7O0FBRTFCO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DOztBQUVuQztBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBLDZEQUE2RDs7QUFFN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxRUFBcUU7O0FBRXJFOztBQUVBO0FBQ0EsY0FBYztBQUNkOztBQUVBLGlCQUFpQjs7QUFFakI7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxrRUFBa0U7O0FBRWxFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0Q0FBNEM7O0FBRTVDO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCw2TkFBNk47O0FBRTlROztBQUVBO0FBQ0EseURBQXlEOztBQUV6RCx3TEFBd0w7QUFDeEw7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sY0FBYyxtRkFBbUYsSUFBSSxVQUFVLFFBQVE7OztBQUc5SCw4QkFBOEI7O0FBRTlCLG1DQUFtQzs7QUFFbkMsaUhBQWlIOztBQUVqSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSwyQ0FBMkM7O0FBRTNDO0FBQ0E7QUFDQTtBQUNBLG9YQUFvWCx5Q0FBeUM7QUFDN1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5SEFBeUgsOEJBQThCOztBQUV2SixTQUFTO0FBQ1Qsd0RBQXdELG1EQUFtRCxPQUFPOztBQUVsSDs7QUFFQSxnQ0FBZ0M7O0FBRWhDLHFDQUFxQzs7QUFFckM7QUFDQTs7QUFFQTtBQUNBLDBEQUEwRDs7QUFFMUQsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7O0FBRXJFOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLGdGQUFnRjs7O0FBR2hGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkNBQTJDO0FBQzNDOztBQUVBO0FBQ0EsOERBQThEOztBQUU5RCw0REFBNEQ7QUFDNUQsQ0FBQztBQUNEO0FBQ0Esb0VBQW9FO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1lQUFtZSxNQUFNO0FBQ3plLGlDQUFpQzs7QUFFakM7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBO0FBQ0EsZ0VBQWdFOztBQUVoRSx1REFBdUQ7QUFDdkQ7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRCxzQ0FBc0MsT0FBTyxPQUFPLEdBQUcsUUFBUSxTQUFTLE1BQU0sSUFBSSx3QkFBd0Isa0hBQWtILE1BQU0sSUFBSSxRQUFRLElBQUksR0FBRztBQUNyUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlEQUFpRDs7QUFFakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0wsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCOztBQUUzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBLE9BQU8sR0FBRzs7QUFFVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTREO0FBQzVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9CQUFvQixPQUFPO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDOztBQUV4QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0VBQW9FO0FBQ3BFLFFBQVE7QUFDUjtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCx5QkFBeUI7QUFDekIsVUFBVTtBQUNWOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUEsd0JBQXdCLGNBQWM7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsOENBQThDO0FBQzlDO0FBQ0EsV0FBVyxHQUFHO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTiwyQkFBMkI7QUFDM0I7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUM7O0FBRWpDLCtDQUErQzs7QUFFL0M7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFEQUFxRDs7QUFFckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkVBQTJFOztBQUUzRTtBQUNBLG9DQUFvQzs7QUFFcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJCQUEyQjs7QUFFM0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUI7O0FBRXZCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDhFQUE4RTs7QUFFOUU7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsK0hBQStIOztBQUUvSDtBQUNBLDRIQUE0SCxZQUFZO0FBQ3hJOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDLHVHQUF1RyxlQUFlLEdBQUc7QUFDekgsa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQSx3RUFBd0U7QUFDeEU7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQSxvRUFBb0U7QUFDcEUsTUFBTTs7O0FBR047O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0SUFBNEk7O0FBRTVJLGlJQUFpSTs7QUFFakk7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0RBQStEOztBQUUvRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssR0FBRyx5RUFBeUUsSUFBSTtBQUNyRjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsR0FBRztBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLDZHQUE2Rzs7QUFFN0c7QUFDQTs7QUFFQSxpQkFBaUI7QUFDakI7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7O0FBRVo7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOzs7QUFHSTtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsdUNBQXVDOztBQUV2QztBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QjtBQUNBOztBQUVBO0FBQ0EsQ0FBQyxJQUFJOztBQUVMO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxREFBcUQ7O0FBRXJEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCOztBQUVsQjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSw4S0FBOEssSUFBSTtBQUNsTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsT0FBTyxHQUFHOztBQUVWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPLEdBQUc7O0FBRVY7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQjtBQUMxQjs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBLHFFQUFxRTs7QUFFckU7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsdUlBQXVJOztBQUV4STtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDbUo7QUFDcUgsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vbm9kZV9tb2R1bGVzL2dzYXAvZ3NhcC1jb3JlLmpzP2E1Y2YiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKSB7IGlmIChzZWxmID09PSB2b2lkIDApIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0c0xvb3NlKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcy5wcm90b3R5cGUpOyBzdWJDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBzdWJDbGFzczsgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG4vKiFcbiAqIEdTQVAgMy4xMS41XG4gKiBodHRwczovL2dyZWVuc29jay5jb21cbiAqXG4gKiBAbGljZW5zZSBDb3B5cmlnaHQgMjAwOC0yMDIzLCBHcmVlblNvY2suIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhdCBodHRwczovL2dyZWVuc29jay5jb20vc3RhbmRhcmQtbGljZW5zZSBvciBmb3JcbiAqIENsdWIgR3JlZW5Tb2NrIG1lbWJlcnMsIHRoZSBhZ3JlZW1lbnQgaXNzdWVkIHdpdGggdGhhdCBtZW1iZXJzaGlwLlxuICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG4qL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xudmFyIF9jb25maWcgPSB7XG4gIGF1dG9TbGVlcDogMTIwLFxuICBmb3JjZTNEOiBcImF1dG9cIixcbiAgbnVsbFRhcmdldFdhcm46IDEsXG4gIHVuaXRzOiB7XG4gICAgbGluZUhlaWdodDogXCJcIlxuICB9XG59LFxuICAgIF9kZWZhdWx0cyA9IHtcbiAgZHVyYXRpb246IC41LFxuICBvdmVyd3JpdGU6IGZhbHNlLFxuICBkZWxheTogMFxufSxcbiAgICBfc3VwcHJlc3NPdmVyd3JpdGVzLFxuICAgIF9yZXZlcnRpbmcsXG4gICAgX2NvbnRleHQsXG4gICAgX2JpZ051bSA9IDFlOCxcbiAgICBfdGlueU51bSA9IDEgLyBfYmlnTnVtLFxuICAgIF8yUEkgPSBNYXRoLlBJICogMixcbiAgICBfSEFMRl9QSSA9IF8yUEkgLyA0LFxuICAgIF9nc0lEID0gMCxcbiAgICBfc3FydCA9IE1hdGguc3FydCxcbiAgICBfY29zID0gTWF0aC5jb3MsXG4gICAgX3NpbiA9IE1hdGguc2luLFxuICAgIF9pc1N0cmluZyA9IGZ1bmN0aW9uIF9pc1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiO1xufSxcbiAgICBfaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIF9pc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIjtcbn0sXG4gICAgX2lzTnVtYmVyID0gZnVuY3Rpb24gX2lzTnVtYmVyKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCI7XG59LFxuICAgIF9pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uIF9pc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiO1xufSxcbiAgICBfaXNPYmplY3QgPSBmdW5jdGlvbiBfaXNPYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn0sXG4gICAgX2lzTm90RmFsc2UgPSBmdW5jdGlvbiBfaXNOb3RGYWxzZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IGZhbHNlO1xufSxcbiAgICBfd2luZG93RXhpc3RzID0gZnVuY3Rpb24gX3dpbmRvd0V4aXN0cygpIHtcbiAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG59LFxuICAgIF9pc0Z1bmNPclN0cmluZyA9IGZ1bmN0aW9uIF9pc0Z1bmNPclN0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gX2lzRnVuY3Rpb24odmFsdWUpIHx8IF9pc1N0cmluZyh2YWx1ZSk7XG59LFxuICAgIF9pc1R5cGVkQXJyYXkgPSB0eXBlb2YgQXJyYXlCdWZmZXIgPT09IFwiZnVuY3Rpb25cIiAmJiBBcnJheUJ1ZmZlci5pc1ZpZXcgfHwgZnVuY3Rpb24gKCkge30sXG4gICAgLy8gbm90ZTogSUUxMCBoYXMgQXJyYXlCdWZmZXIsIGJ1dCBOT1QgQXJyYXlCdWZmZXIuaXNWaWV3KCkuXG5faXNBcnJheSA9IEFycmF5LmlzQXJyYXksXG4gICAgX3N0cmljdE51bUV4cCA9IC8oPzotP1xcLj9cXGR8XFwuKSsvZ2ksXG4gICAgLy9vbmx5IG51bWJlcnMgKGluY2x1ZGluZyBuZWdhdGl2ZXMgYW5kIGRlY2ltYWxzKSBidXQgTk9UIHJlbGF0aXZlIHZhbHVlcy5cbl9udW1FeHAgPSAvWy0rPS5dKlxcZCtbLmVcXC0rXSpcXGQqW2VcXC0rXSpcXGQqL2csXG4gICAgLy9maW5kcyBhbnkgbnVtYmVycywgaW5jbHVkaW5nIG9uZXMgdGhhdCBzdGFydCB3aXRoICs9IG9yIC09LCBuZWdhdGl2ZSBudW1iZXJzLCBhbmQgb25lcyBpbiBzY2llbnRpZmljIG5vdGF0aW9uIGxpa2UgMWUtOC5cbl9udW1XaXRoVW5pdEV4cCA9IC9bLSs9Ll0qXFxkK1suZS1dKlxcZCpbYS16JV0qL2csXG4gICAgX2NvbXBsZXhTdHJpbmdOdW1FeHAgPSAvWy0rPS5dKlxcZCtcXC4/XFxkKig/OmUtfGVcXCspP1xcZCovZ2ksXG4gICAgLy9kdXBsaWNhdGUgc28gdGhhdCB3aGlsZSB3ZSdyZSBsb29waW5nIHRocm91Z2ggbWF0Y2hlcyBmcm9tIGV4ZWMoKSwgaXQgZG9lc24ndCBjb250YW1pbmF0ZSB0aGUgbGFzdEluZGV4IG9mIF9udW1FeHAgd2hpY2ggd2UgdXNlIHRvIHNlYXJjaCBmb3IgY29sb3JzIHRvby5cbl9yZWxFeHAgPSAvWystXT0tP1suXFxkXSsvLFxuICAgIF9kZWxpbWl0ZWRWYWx1ZUV4cCA9IC9bXiwnXCJcXFtcXF1cXHNdKy9naSxcbiAgICAvLyBwcmV2aW91c2x5IC9bI1xcLSsuXSpcXGJbYS16XFxkXFwtPSslLl0rL2dpIGJ1dCBkaWRuJ3QgY2F0Y2ggc3BlY2lhbCBjaGFyYWN0ZXJzLlxuX3VuaXRFeHAgPSAvXlsrXFwtPWVcXHNcXGRdKlxcZCtbLlxcZF0qKFthLXpdKnwlKVxccyokL2ksXG4gICAgX2dsb2JhbFRpbWVsaW5lLFxuICAgIF93aW4sXG4gICAgX2NvcmVJbml0dGVkLFxuICAgIF9kb2MsXG4gICAgX2dsb2JhbHMgPSB7fSxcbiAgICBfaW5zdGFsbFNjb3BlID0ge30sXG4gICAgX2NvcmVSZWFkeSxcbiAgICBfaW5zdGFsbCA9IGZ1bmN0aW9uIF9pbnN0YWxsKHNjb3BlKSB7XG4gIHJldHVybiAoX2luc3RhbGxTY29wZSA9IF9tZXJnZShzY29wZSwgX2dsb2JhbHMpKSAmJiBnc2FwO1xufSxcbiAgICBfbWlzc2luZ1BsdWdpbiA9IGZ1bmN0aW9uIF9taXNzaW5nUGx1Z2luKHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gY29uc29sZS53YXJuKFwiSW52YWxpZCBwcm9wZXJ0eVwiLCBwcm9wZXJ0eSwgXCJzZXQgdG9cIiwgdmFsdWUsIFwiTWlzc2luZyBwbHVnaW4/IGdzYXAucmVnaXN0ZXJQbHVnaW4oKVwiKTtcbn0sXG4gICAgX3dhcm4gPSBmdW5jdGlvbiBfd2FybihtZXNzYWdlLCBzdXBwcmVzcykge1xuICByZXR1cm4gIXN1cHByZXNzICYmIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbn0sXG4gICAgX2FkZEdsb2JhbCA9IGZ1bmN0aW9uIF9hZGRHbG9iYWwobmFtZSwgb2JqKSB7XG4gIHJldHVybiBuYW1lICYmIChfZ2xvYmFsc1tuYW1lXSA9IG9iaikgJiYgX2luc3RhbGxTY29wZSAmJiAoX2luc3RhbGxTY29wZVtuYW1lXSA9IG9iaikgfHwgX2dsb2JhbHM7XG59LFxuICAgIF9lbXB0eUZ1bmMgPSBmdW5jdGlvbiBfZW1wdHlGdW5jKCkge1xuICByZXR1cm4gMDtcbn0sXG4gICAgX3N0YXJ0QXRSZXZlcnRDb25maWcgPSB7XG4gIHN1cHByZXNzRXZlbnRzOiB0cnVlLFxuICBpc1N0YXJ0OiB0cnVlLFxuICBraWxsOiBmYWxzZVxufSxcbiAgICBfcmV2ZXJ0Q29uZmlnTm9LaWxsID0ge1xuICBzdXBwcmVzc0V2ZW50czogdHJ1ZSxcbiAga2lsbDogZmFsc2Vcbn0sXG4gICAgX3JldmVydENvbmZpZyA9IHtcbiAgc3VwcHJlc3NFdmVudHM6IHRydWVcbn0sXG4gICAgX3Jlc2VydmVkUHJvcHMgPSB7fSxcbiAgICBfbGF6eVR3ZWVucyA9IFtdLFxuICAgIF9sYXp5TG9va3VwID0ge30sXG4gICAgX2xhc3RSZW5kZXJlZEZyYW1lLFxuICAgIF9wbHVnaW5zID0ge30sXG4gICAgX2VmZmVjdHMgPSB7fSxcbiAgICBfbmV4dEdDRnJhbWUgPSAzMCxcbiAgICBfaGFybmVzc1BsdWdpbnMgPSBbXSxcbiAgICBfY2FsbGJhY2tOYW1lcyA9IFwiXCIsXG4gICAgX2hhcm5lc3MgPSBmdW5jdGlvbiBfaGFybmVzcyh0YXJnZXRzKSB7XG4gIHZhciB0YXJnZXQgPSB0YXJnZXRzWzBdLFxuICAgICAgaGFybmVzc1BsdWdpbixcbiAgICAgIGk7XG4gIF9pc09iamVjdCh0YXJnZXQpIHx8IF9pc0Z1bmN0aW9uKHRhcmdldCkgfHwgKHRhcmdldHMgPSBbdGFyZ2V0c10pO1xuXG4gIGlmICghKGhhcm5lc3NQbHVnaW4gPSAodGFyZ2V0Ll9nc2FwIHx8IHt9KS5oYXJuZXNzKSkge1xuICAgIC8vIGZpbmQgdGhlIGZpcnN0IHRhcmdldCB3aXRoIGEgaGFybmVzcy4gV2UgYXNzdW1lIHRhcmdldHMgcGFzc2VkIGludG8gYW4gYW5pbWF0aW9uIHdpbGwgYmUgb2Ygc2ltaWxhciB0eXBlLCBtZWFuaW5nIHRoZSBzYW1lIGtpbmQgb2YgaGFybmVzcyBjYW4gYmUgdXNlZCBmb3IgdGhlbSBhbGwgKHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbilcbiAgICBpID0gX2hhcm5lc3NQbHVnaW5zLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0gJiYgIV9oYXJuZXNzUGx1Z2luc1tpXS50YXJnZXRUZXN0KHRhcmdldCkpIHt9XG5cbiAgICBoYXJuZXNzUGx1Z2luID0gX2hhcm5lc3NQbHVnaW5zW2ldO1xuICB9XG5cbiAgaSA9IHRhcmdldHMubGVuZ3RoO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICB0YXJnZXRzW2ldICYmICh0YXJnZXRzW2ldLl9nc2FwIHx8ICh0YXJnZXRzW2ldLl9nc2FwID0gbmV3IEdTQ2FjaGUodGFyZ2V0c1tpXSwgaGFybmVzc1BsdWdpbikpKSB8fCB0YXJnZXRzLnNwbGljZShpLCAxKTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXRzO1xufSxcbiAgICBfZ2V0Q2FjaGUgPSBmdW5jdGlvbiBfZ2V0Q2FjaGUodGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuX2dzYXAgfHwgX2hhcm5lc3ModG9BcnJheSh0YXJnZXQpKVswXS5fZ3NhcDtcbn0sXG4gICAgX2dldFByb3BlcnR5ID0gZnVuY3Rpb24gX2dldFByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHYpIHtcbiAgcmV0dXJuICh2ID0gdGFyZ2V0W3Byb3BlcnR5XSkgJiYgX2lzRnVuY3Rpb24odikgPyB0YXJnZXRbcHJvcGVydHldKCkgOiBfaXNVbmRlZmluZWQodikgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZSAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKHByb3BlcnR5KSB8fCB2O1xufSxcbiAgICBfZm9yRWFjaE5hbWUgPSBmdW5jdGlvbiBfZm9yRWFjaE5hbWUobmFtZXMsIGZ1bmMpIHtcbiAgcmV0dXJuIChuYW1lcyA9IG5hbWVzLnNwbGl0KFwiLFwiKSkuZm9yRWFjaChmdW5jKSB8fCBuYW1lcztcbn0sXG4gICAgLy9zcGxpdCBhIGNvbW1hLWRlbGltaXRlZCBsaXN0IG9mIG5hbWVzIGludG8gYW4gYXJyYXksIHRoZW4gcnVuIGEgZm9yRWFjaCgpIGZ1bmN0aW9uIGFuZCByZXR1cm4gdGhlIHNwbGl0IGFycmF5ICh0aGlzIGlzIGp1c3QgYSB3YXkgdG8gY29uc29saWRhdGUvc2hvcnRlbiBzb21lIGNvZGUpLlxuX3JvdW5kID0gZnVuY3Rpb24gX3JvdW5kKHZhbHVlKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwMDAwKSAvIDEwMDAwMCB8fCAwO1xufSxcbiAgICBfcm91bmRQcmVjaXNlID0gZnVuY3Rpb24gX3JvdW5kUHJlY2lzZSh2YWx1ZSkge1xuICByZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIDEwMDAwMDAwKSAvIDEwMDAwMDAwIHx8IDA7XG59LFxuICAgIC8vIGluY3JlYXNlZCBwcmVjaXNpb24gbW9zdGx5IGZvciB0aW1pbmcgdmFsdWVzLlxuX3BhcnNlUmVsYXRpdmUgPSBmdW5jdGlvbiBfcGFyc2VSZWxhdGl2ZShzdGFydCwgdmFsdWUpIHtcbiAgdmFyIG9wZXJhdG9yID0gdmFsdWUuY2hhckF0KDApLFxuICAgICAgZW5kID0gcGFyc2VGbG9hdCh2YWx1ZS5zdWJzdHIoMikpO1xuICBzdGFydCA9IHBhcnNlRmxvYXQoc3RhcnQpO1xuICByZXR1cm4gb3BlcmF0b3IgPT09IFwiK1wiID8gc3RhcnQgKyBlbmQgOiBvcGVyYXRvciA9PT0gXCItXCIgPyBzdGFydCAtIGVuZCA6IG9wZXJhdG9yID09PSBcIipcIiA/IHN0YXJ0ICogZW5kIDogc3RhcnQgLyBlbmQ7XG59LFxuICAgIF9hcnJheUNvbnRhaW5zQW55ID0gZnVuY3Rpb24gX2FycmF5Q29udGFpbnNBbnkodG9TZWFyY2gsIHRvRmluZCkge1xuICAvL3NlYXJjaGVzIG9uZSBhcnJheSB0byBmaW5kIG1hdGNoZXMgZm9yIGFueSBvZiB0aGUgaXRlbXMgaW4gdGhlIHRvRmluZCBhcnJheS4gQXMgc29vbiBhcyBvbmUgaXMgZm91bmQsIGl0IHJldHVybnMgdHJ1ZS4gSXQgZG9lcyBOT1QgcmV0dXJuIGFsbCB0aGUgbWF0Y2hlczsgaXQncyBzaW1wbHkgYSBib29sZWFuIHNlYXJjaC5cbiAgdmFyIGwgPSB0b0ZpbmQubGVuZ3RoLFxuICAgICAgaSA9IDA7XG5cbiAgZm9yICg7IHRvU2VhcmNoLmluZGV4T2YodG9GaW5kW2ldKSA8IDAgJiYgKytpIDwgbDspIHt9XG5cbiAgcmV0dXJuIGkgPCBsO1xufSxcbiAgICBfbGF6eVJlbmRlciA9IGZ1bmN0aW9uIF9sYXp5UmVuZGVyKCkge1xuICB2YXIgbCA9IF9sYXp5VHdlZW5zLmxlbmd0aCxcbiAgICAgIGEgPSBfbGF6eVR3ZWVucy5zbGljZSgwKSxcbiAgICAgIGksXG4gICAgICB0d2VlbjtcblxuICBfbGF6eUxvb2t1cCA9IHt9O1xuICBfbGF6eVR3ZWVucy5sZW5ndGggPSAwO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICB0d2VlbiA9IGFbaV07XG4gICAgdHdlZW4gJiYgdHdlZW4uX2xhenkgJiYgKHR3ZWVuLnJlbmRlcih0d2Vlbi5fbGF6eVswXSwgdHdlZW4uX2xhenlbMV0sIHRydWUpLl9sYXp5ID0gMCk7XG4gIH1cbn0sXG4gICAgX2xhenlTYWZlUmVuZGVyID0gZnVuY3Rpb24gX2xhenlTYWZlUmVuZGVyKGFuaW1hdGlvbiwgdGltZSwgc3VwcHJlc3NFdmVudHMsIGZvcmNlKSB7XG4gIF9sYXp5VHdlZW5zLmxlbmd0aCAmJiAhX3JldmVydGluZyAmJiBfbGF6eVJlbmRlcigpO1xuICBhbmltYXRpb24ucmVuZGVyKHRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSB8fCBfcmV2ZXJ0aW5nICYmIHRpbWUgPCAwICYmIChhbmltYXRpb24uX2luaXR0ZWQgfHwgYW5pbWF0aW9uLl9zdGFydEF0KSk7XG4gIF9sYXp5VHdlZW5zLmxlbmd0aCAmJiAhX3JldmVydGluZyAmJiBfbGF6eVJlbmRlcigpOyAvL2luIGNhc2UgcmVuZGVyaW5nIGNhdXNlZCBhbnkgdHdlZW5zIHRvIGxhenktaW5pdCwgd2Ugc2hvdWxkIHJlbmRlciB0aGVtIGJlY2F1c2UgdHlwaWNhbGx5IHdoZW4gc29tZW9uZSBjYWxscyBzZWVrKCkgb3IgdGltZSgpIG9yIHByb2dyZXNzKCksIHRoZXkgZXhwZWN0IGFuIGltbWVkaWF0ZSByZW5kZXIuXG59LFxuICAgIF9udW1lcmljSWZQb3NzaWJsZSA9IGZ1bmN0aW9uIF9udW1lcmljSWZQb3NzaWJsZSh2YWx1ZSkge1xuICB2YXIgbiA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICByZXR1cm4gKG4gfHwgbiA9PT0gMCkgJiYgKHZhbHVlICsgXCJcIikubWF0Y2goX2RlbGltaXRlZFZhbHVlRXhwKS5sZW5ndGggPCAyID8gbiA6IF9pc1N0cmluZyh2YWx1ZSkgPyB2YWx1ZS50cmltKCkgOiB2YWx1ZTtcbn0sXG4gICAgX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24gX3Bhc3NUaHJvdWdoKHApIHtcbiAgcmV0dXJuIHA7XG59LFxuICAgIF9zZXREZWZhdWx0cyA9IGZ1bmN0aW9uIF9zZXREZWZhdWx0cyhvYmosIGRlZmF1bHRzKSB7XG4gIGZvciAodmFyIHAgaW4gZGVmYXVsdHMpIHtcbiAgICBwIGluIG9iaiB8fCAob2JqW3BdID0gZGVmYXVsdHNbcF0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn0sXG4gICAgX3NldEtleWZyYW1lRGVmYXVsdHMgPSBmdW5jdGlvbiBfc2V0S2V5ZnJhbWVEZWZhdWx0cyhleGNsdWRlRHVyYXRpb24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmosIGRlZmF1bHRzKSB7XG4gICAgZm9yICh2YXIgcCBpbiBkZWZhdWx0cykge1xuICAgICAgcCBpbiBvYmogfHwgcCA9PT0gXCJkdXJhdGlvblwiICYmIGV4Y2x1ZGVEdXJhdGlvbiB8fCBwID09PSBcImVhc2VcIiB8fCAob2JqW3BdID0gZGVmYXVsdHNbcF0pO1xuICAgIH1cbiAgfTtcbn0sXG4gICAgX21lcmdlID0gZnVuY3Rpb24gX21lcmdlKGJhc2UsIHRvTWVyZ2UpIHtcbiAgZm9yICh2YXIgcCBpbiB0b01lcmdlKSB7XG4gICAgYmFzZVtwXSA9IHRvTWVyZ2VbcF07XG4gIH1cblxuICByZXR1cm4gYmFzZTtcbn0sXG4gICAgX21lcmdlRGVlcCA9IGZ1bmN0aW9uIF9tZXJnZURlZXAoYmFzZSwgdG9NZXJnZSkge1xuICBmb3IgKHZhciBwIGluIHRvTWVyZ2UpIHtcbiAgICBwICE9PSBcIl9fcHJvdG9fX1wiICYmIHAgIT09IFwiY29uc3RydWN0b3JcIiAmJiBwICE9PSBcInByb3RvdHlwZVwiICYmIChiYXNlW3BdID0gX2lzT2JqZWN0KHRvTWVyZ2VbcF0pID8gX21lcmdlRGVlcChiYXNlW3BdIHx8IChiYXNlW3BdID0ge30pLCB0b01lcmdlW3BdKSA6IHRvTWVyZ2VbcF0pO1xuICB9XG5cbiAgcmV0dXJuIGJhc2U7XG59LFxuICAgIF9jb3B5RXhjbHVkaW5nID0gZnVuY3Rpb24gX2NvcHlFeGNsdWRpbmcob2JqLCBleGNsdWRpbmcpIHtcbiAgdmFyIGNvcHkgPSB7fSxcbiAgICAgIHA7XG5cbiAgZm9yIChwIGluIG9iaikge1xuICAgIHAgaW4gZXhjbHVkaW5nIHx8IChjb3B5W3BdID0gb2JqW3BdKTtcbiAgfVxuXG4gIHJldHVybiBjb3B5O1xufSxcbiAgICBfaW5oZXJpdERlZmF1bHRzID0gZnVuY3Rpb24gX2luaGVyaXREZWZhdWx0cyh2YXJzKSB7XG4gIHZhciBwYXJlbnQgPSB2YXJzLnBhcmVudCB8fCBfZ2xvYmFsVGltZWxpbmUsXG4gICAgICBmdW5jID0gdmFycy5rZXlmcmFtZXMgPyBfc2V0S2V5ZnJhbWVEZWZhdWx0cyhfaXNBcnJheSh2YXJzLmtleWZyYW1lcykpIDogX3NldERlZmF1bHRzO1xuXG4gIGlmIChfaXNOb3RGYWxzZSh2YXJzLmluaGVyaXQpKSB7XG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgZnVuYyh2YXJzLCBwYXJlbnQudmFycy5kZWZhdWx0cyk7XG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50IHx8IHBhcmVudC5fZHA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhcnM7XG59LFxuICAgIF9hcnJheXNNYXRjaCA9IGZ1bmN0aW9uIF9hcnJheXNNYXRjaChhMSwgYTIpIHtcbiAgdmFyIGkgPSBhMS5sZW5ndGgsXG4gICAgICBtYXRjaCA9IGkgPT09IGEyLmxlbmd0aDtcblxuICB3aGlsZSAobWF0Y2ggJiYgaS0tICYmIGExW2ldID09PSBhMltpXSkge31cblxuICByZXR1cm4gaSA8IDA7XG59LFxuICAgIF9hZGRMaW5rZWRMaXN0SXRlbSA9IGZ1bmN0aW9uIF9hZGRMaW5rZWRMaXN0SXRlbShwYXJlbnQsIGNoaWxkLCBmaXJzdFByb3AsIGxhc3RQcm9wLCBzb3J0QnkpIHtcbiAgaWYgKGZpcnN0UHJvcCA9PT0gdm9pZCAwKSB7XG4gICAgZmlyc3RQcm9wID0gXCJfZmlyc3RcIjtcbiAgfVxuXG4gIGlmIChsYXN0UHJvcCA9PT0gdm9pZCAwKSB7XG4gICAgbGFzdFByb3AgPSBcIl9sYXN0XCI7XG4gIH1cblxuICB2YXIgcHJldiA9IHBhcmVudFtsYXN0UHJvcF0sXG4gICAgICB0O1xuXG4gIGlmIChzb3J0QnkpIHtcbiAgICB0ID0gY2hpbGRbc29ydEJ5XTtcblxuICAgIHdoaWxlIChwcmV2ICYmIHByZXZbc29ydEJ5XSA+IHQpIHtcbiAgICAgIHByZXYgPSBwcmV2Ll9wcmV2O1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmV2KSB7XG4gICAgY2hpbGQuX25leHQgPSBwcmV2Ll9uZXh0O1xuICAgIHByZXYuX25leHQgPSBjaGlsZDtcbiAgfSBlbHNlIHtcbiAgICBjaGlsZC5fbmV4dCA9IHBhcmVudFtmaXJzdFByb3BdO1xuICAgIHBhcmVudFtmaXJzdFByb3BdID0gY2hpbGQ7XG4gIH1cblxuICBpZiAoY2hpbGQuX25leHQpIHtcbiAgICBjaGlsZC5fbmV4dC5fcHJldiA9IGNoaWxkO1xuICB9IGVsc2Uge1xuICAgIHBhcmVudFtsYXN0UHJvcF0gPSBjaGlsZDtcbiAgfVxuXG4gIGNoaWxkLl9wcmV2ID0gcHJldjtcbiAgY2hpbGQucGFyZW50ID0gY2hpbGQuX2RwID0gcGFyZW50O1xuICByZXR1cm4gY2hpbGQ7XG59LFxuICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSA9IGZ1bmN0aW9uIF9yZW1vdmVMaW5rZWRMaXN0SXRlbShwYXJlbnQsIGNoaWxkLCBmaXJzdFByb3AsIGxhc3RQcm9wKSB7XG4gIGlmIChmaXJzdFByb3AgPT09IHZvaWQgMCkge1xuICAgIGZpcnN0UHJvcCA9IFwiX2ZpcnN0XCI7XG4gIH1cblxuICBpZiAobGFzdFByb3AgPT09IHZvaWQgMCkge1xuICAgIGxhc3RQcm9wID0gXCJfbGFzdFwiO1xuICB9XG5cbiAgdmFyIHByZXYgPSBjaGlsZC5fcHJldixcbiAgICAgIG5leHQgPSBjaGlsZC5fbmV4dDtcblxuICBpZiAocHJldikge1xuICAgIHByZXYuX25leHQgPSBuZXh0O1xuICB9IGVsc2UgaWYgKHBhcmVudFtmaXJzdFByb3BdID09PSBjaGlsZCkge1xuICAgIHBhcmVudFtmaXJzdFByb3BdID0gbmV4dDtcbiAgfVxuXG4gIGlmIChuZXh0KSB7XG4gICAgbmV4dC5fcHJldiA9IHByZXY7XG4gIH0gZWxzZSBpZiAocGFyZW50W2xhc3RQcm9wXSA9PT0gY2hpbGQpIHtcbiAgICBwYXJlbnRbbGFzdFByb3BdID0gcHJldjtcbiAgfVxuXG4gIGNoaWxkLl9uZXh0ID0gY2hpbGQuX3ByZXYgPSBjaGlsZC5wYXJlbnQgPSBudWxsOyAvLyBkb24ndCBkZWxldGUgdGhlIF9kcCBqdXN0IHNvIHdlIGNhbiByZXZlcnQgaWYgbmVjZXNzYXJ5LiBCdXQgcGFyZW50IHNob3VsZCBiZSBudWxsIHRvIGluZGljYXRlIHRoZSBpdGVtIGlzbid0IGluIGEgbGlua2VkIGxpc3QuXG59LFxuICAgIF9yZW1vdmVGcm9tUGFyZW50ID0gZnVuY3Rpb24gX3JlbW92ZUZyb21QYXJlbnQoY2hpbGQsIG9ubHlJZlBhcmVudEhhc0F1dG9SZW1vdmUpIHtcbiAgY2hpbGQucGFyZW50ICYmICghb25seUlmUGFyZW50SGFzQXV0b1JlbW92ZSB8fCBjaGlsZC5wYXJlbnQuYXV0b1JlbW92ZUNoaWxkcmVuKSAmJiBjaGlsZC5wYXJlbnQucmVtb3ZlKGNoaWxkKTtcbiAgY2hpbGQuX2FjdCA9IDA7XG59LFxuICAgIF91bmNhY2hlID0gZnVuY3Rpb24gX3VuY2FjaGUoYW5pbWF0aW9uLCBjaGlsZCkge1xuICBpZiAoYW5pbWF0aW9uICYmICghY2hpbGQgfHwgY2hpbGQuX2VuZCA+IGFuaW1hdGlvbi5fZHVyIHx8IGNoaWxkLl9zdGFydCA8IDApKSB7XG4gICAgLy8gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uOiBpZiBhIGNoaWxkIGFuaW1hdGlvbiBpcyBwYXNzZWQgaW4gd2Ugc2hvdWxkIG9ubHkgdW5jYWNoZSBpZiB0aGF0IGNoaWxkIEVYVEVORFMgdGhlIGFuaW1hdGlvbiAoaXRzIGVuZCB0aW1lIGlzIGJleW9uZCB0aGUgZW5kKVxuICAgIHZhciBhID0gYW5pbWF0aW9uO1xuXG4gICAgd2hpbGUgKGEpIHtcbiAgICAgIGEuX2RpcnR5ID0gMTtcbiAgICAgIGEgPSBhLnBhcmVudDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYW5pbWF0aW9uO1xufSxcbiAgICBfcmVjYWNoZUFuY2VzdG9ycyA9IGZ1bmN0aW9uIF9yZWNhY2hlQW5jZXN0b3JzKGFuaW1hdGlvbikge1xuICB2YXIgcGFyZW50ID0gYW5pbWF0aW9uLnBhcmVudDtcblxuICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5wYXJlbnQpIHtcbiAgICAvL3NvbWV0aW1lcyB3ZSBtdXN0IGZvcmNlIGEgcmUtc29ydCBvZiBhbGwgY2hpbGRyZW4gYW5kIHVwZGF0ZSB0aGUgZHVyYXRpb24vdG90YWxEdXJhdGlvbiBvZiBhbGwgYW5jZXN0b3IgdGltZWxpbmVzIGltbWVkaWF0ZWx5IGluIGNhc2UsIGZvciBleGFtcGxlLCBpbiB0aGUgbWlkZGxlIG9mIGEgcmVuZGVyIGxvb3AsIG9uZSB0d2VlbiBhbHRlcnMgYW5vdGhlciB0d2VlbidzIHRpbWVTY2FsZSB3aGljaCBzaG92ZXMgaXRzIHN0YXJ0VGltZSBiZWZvcmUgMCwgZm9yY2luZyB0aGUgcGFyZW50IHRpbWVsaW5lIHRvIHNoaWZ0IGFyb3VuZCBhbmQgc2hpZnRDaGlsZHJlbigpIHdoaWNoIGNvdWxkIGFmZmVjdCB0aGF0IG5leHQgdHdlZW4ncyByZW5kZXIgKHN0YXJ0VGltZSkuIERvZXNuJ3QgbWF0dGVyIGZvciB0aGUgcm9vdCB0aW1lbGluZSB0aG91Z2guXG4gICAgcGFyZW50Ll9kaXJ0eSA9IDE7XG4gICAgcGFyZW50LnRvdGFsRHVyYXRpb24oKTtcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIGFuaW1hdGlvbjtcbn0sXG4gICAgX3Jld2luZFN0YXJ0QXQgPSBmdW5jdGlvbiBfcmV3aW5kU3RhcnRBdCh0d2VlbiwgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpIHtcbiAgcmV0dXJuIHR3ZWVuLl9zdGFydEF0ICYmIChfcmV2ZXJ0aW5nID8gdHdlZW4uX3N0YXJ0QXQucmV2ZXJ0KF9yZXZlcnRDb25maWdOb0tpbGwpIDogdHdlZW4udmFycy5pbW1lZGlhdGVSZW5kZXIgJiYgIXR3ZWVuLnZhcnMuYXV0b1JldmVydCB8fCB0d2Vlbi5fc3RhcnRBdC5yZW5kZXIodG90YWxUaW1lLCB0cnVlLCBmb3JjZSkpO1xufSxcbiAgICBfaGFzTm9QYXVzZWRBbmNlc3RvcnMgPSBmdW5jdGlvbiBfaGFzTm9QYXVzZWRBbmNlc3RvcnMoYW5pbWF0aW9uKSB7XG4gIHJldHVybiAhYW5pbWF0aW9uIHx8IGFuaW1hdGlvbi5fdHMgJiYgX2hhc05vUGF1c2VkQW5jZXN0b3JzKGFuaW1hdGlvbi5wYXJlbnQpO1xufSxcbiAgICBfZWxhcHNlZEN5Y2xlRHVyYXRpb24gPSBmdW5jdGlvbiBfZWxhcHNlZEN5Y2xlRHVyYXRpb24oYW5pbWF0aW9uKSB7XG4gIHJldHVybiBhbmltYXRpb24uX3JlcGVhdCA/IF9hbmltYXRpb25DeWNsZShhbmltYXRpb24uX3RUaW1lLCBhbmltYXRpb24gPSBhbmltYXRpb24uZHVyYXRpb24oKSArIGFuaW1hdGlvbi5fckRlbGF5KSAqIGFuaW1hdGlvbiA6IDA7XG59LFxuICAgIC8vIGZlZWQgaW4gdGhlIHRvdGFsVGltZSBhbmQgY3ljbGVEdXJhdGlvbiBhbmQgaXQnbGwgcmV0dXJuIHRoZSBjeWNsZSAoaXRlcmF0aW9uIG1pbnVzIDEpIGFuZCBpZiB0aGUgcGxheWhlYWQgaXMgZXhhY3RseSBhdCB0aGUgdmVyeSBFTkQsIGl0IHdpbGwgTk9UIGJ1bXAgdXAgdG8gdGhlIG5leHQgY3ljbGUuXG5fYW5pbWF0aW9uQ3ljbGUgPSBmdW5jdGlvbiBfYW5pbWF0aW9uQ3ljbGUodFRpbWUsIGN5Y2xlRHVyYXRpb24pIHtcbiAgdmFyIHdob2xlID0gTWF0aC5mbG9vcih0VGltZSAvPSBjeWNsZUR1cmF0aW9uKTtcbiAgcmV0dXJuIHRUaW1lICYmIHdob2xlID09PSB0VGltZSA/IHdob2xlIC0gMSA6IHdob2xlO1xufSxcbiAgICBfcGFyZW50VG9DaGlsZFRvdGFsVGltZSA9IGZ1bmN0aW9uIF9wYXJlbnRUb0NoaWxkVG90YWxUaW1lKHBhcmVudFRpbWUsIGNoaWxkKSB7XG4gIHJldHVybiAocGFyZW50VGltZSAtIGNoaWxkLl9zdGFydCkgKiBjaGlsZC5fdHMgKyAoY2hpbGQuX3RzID49IDAgPyAwIDogY2hpbGQuX2RpcnR5ID8gY2hpbGQudG90YWxEdXJhdGlvbigpIDogY2hpbGQuX3REdXIpO1xufSxcbiAgICBfc2V0RW5kID0gZnVuY3Rpb24gX3NldEVuZChhbmltYXRpb24pIHtcbiAgcmV0dXJuIGFuaW1hdGlvbi5fZW5kID0gX3JvdW5kUHJlY2lzZShhbmltYXRpb24uX3N0YXJ0ICsgKGFuaW1hdGlvbi5fdER1ciAvIE1hdGguYWJzKGFuaW1hdGlvbi5fdHMgfHwgYW5pbWF0aW9uLl9ydHMgfHwgX3RpbnlOdW0pIHx8IDApKTtcbn0sXG4gICAgX2FsaWduUGxheWhlYWQgPSBmdW5jdGlvbiBfYWxpZ25QbGF5aGVhZChhbmltYXRpb24sIHRvdGFsVGltZSkge1xuICAvLyBhZGp1c3RzIHRoZSBhbmltYXRpb24ncyBfc3RhcnQgYW5kIF9lbmQgYWNjb3JkaW5nIHRvIHRoZSBwcm92aWRlZCB0b3RhbFRpbWUgKG9ubHkgaWYgdGhlIHBhcmVudCdzIHNtb290aENoaWxkVGltaW5nIGlzIHRydWUgYW5kIHRoZSBhbmltYXRpb24gaXNuJ3QgcGF1c2VkKS4gSXQgZG9lc24ndCBkbyBhbnkgcmVuZGVyaW5nIG9yIGZvcmNpbmcgdGhpbmdzIGJhY2sgaW50byBwYXJlbnQgdGltZWxpbmVzLCBldGMuIC0gdGhhdCdzIHdoYXQgdG90YWxUaW1lKCkgaXMgZm9yLlxuICB2YXIgcGFyZW50ID0gYW5pbWF0aW9uLl9kcDtcblxuICBpZiAocGFyZW50ICYmIHBhcmVudC5zbW9vdGhDaGlsZFRpbWluZyAmJiBhbmltYXRpb24uX3RzKSB7XG4gICAgYW5pbWF0aW9uLl9zdGFydCA9IF9yb3VuZFByZWNpc2UocGFyZW50Ll90aW1lIC0gKGFuaW1hdGlvbi5fdHMgPiAwID8gdG90YWxUaW1lIC8gYW5pbWF0aW9uLl90cyA6ICgoYW5pbWF0aW9uLl9kaXJ0eSA/IGFuaW1hdGlvbi50b3RhbER1cmF0aW9uKCkgOiBhbmltYXRpb24uX3REdXIpIC0gdG90YWxUaW1lKSAvIC1hbmltYXRpb24uX3RzKSk7XG5cbiAgICBfc2V0RW5kKGFuaW1hdGlvbik7XG5cbiAgICBwYXJlbnQuX2RpcnR5IHx8IF91bmNhY2hlKHBhcmVudCwgYW5pbWF0aW9uKTsgLy9mb3IgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQuIElmIHRoZSBwYXJlbnQncyBjYWNoZSBpcyBhbHJlYWR5IGRpcnR5LCBpdCBhbHJlYWR5IHRvb2sgY2FyZSBvZiBtYXJraW5nIHRoZSBhbmNlc3RvcnMgYXMgZGlydHkgdG9vLCBzbyBza2lwIHRoZSBmdW5jdGlvbiBjYWxsIGhlcmUuXG4gIH1cblxuICByZXR1cm4gYW5pbWF0aW9uO1xufSxcblxuLypcbl90b3RhbFRpbWVUb1RpbWUgPSAoY2xhbXBlZFRvdGFsVGltZSwgZHVyYXRpb24sIHJlcGVhdCwgcmVwZWF0RGVsYXksIHlveW8pID0+IHtcblx0bGV0IGN5Y2xlRHVyYXRpb24gPSBkdXJhdGlvbiArIHJlcGVhdERlbGF5LFxuXHRcdHRpbWUgPSBfcm91bmQoY2xhbXBlZFRvdGFsVGltZSAlIGN5Y2xlRHVyYXRpb24pO1xuXHRpZiAodGltZSA+IGR1cmF0aW9uKSB7XG5cdFx0dGltZSA9IGR1cmF0aW9uO1xuXHR9XG5cdHJldHVybiAoeW95byAmJiAofn4oY2xhbXBlZFRvdGFsVGltZSAvIGN5Y2xlRHVyYXRpb24pICYgMSkpID8gZHVyYXRpb24gLSB0aW1lIDogdGltZTtcbn0sXG4qL1xuX3Bvc3RBZGRDaGVja3MgPSBmdW5jdGlvbiBfcG9zdEFkZENoZWNrcyh0aW1lbGluZSwgY2hpbGQpIHtcbiAgdmFyIHQ7XG5cbiAgaWYgKGNoaWxkLl90aW1lIHx8IGNoaWxkLl9pbml0dGVkICYmICFjaGlsZC5fZHVyKSB7XG4gICAgLy9pbiBjYXNlLCBmb3IgZXhhbXBsZSwgdGhlIF9zdGFydCBpcyBtb3ZlZCBvbiBhIHR3ZWVuIHRoYXQgaGFzIGFscmVhZHkgcmVuZGVyZWQuIEltYWdpbmUgaXQncyBhdCBpdHMgZW5kIHN0YXRlLCB0aGVuIHRoZSBzdGFydFRpbWUgaXMgbW92ZWQgV0FZIGxhdGVyIChhZnRlciB0aGUgZW5kIG9mIHRoaXMgdGltZWxpbmUpLCBpdCBzaG91bGQgcmVuZGVyIGF0IGl0cyBiZWdpbm5pbmcuXG4gICAgdCA9IF9wYXJlbnRUb0NoaWxkVG90YWxUaW1lKHRpbWVsaW5lLnJhd1RpbWUoKSwgY2hpbGQpO1xuXG4gICAgaWYgKCFjaGlsZC5fZHVyIHx8IF9jbGFtcCgwLCBjaGlsZC50b3RhbER1cmF0aW9uKCksIHQpIC0gY2hpbGQuX3RUaW1lID4gX3RpbnlOdW0pIHtcbiAgICAgIGNoaWxkLnJlbmRlcih0LCB0cnVlKTtcbiAgICB9XG4gIH0gLy9pZiB0aGUgdGltZWxpbmUgaGFzIGFscmVhZHkgZW5kZWQgYnV0IHRoZSBpbnNlcnRlZCB0d2Vlbi90aW1lbGluZSBleHRlbmRzIHRoZSBkdXJhdGlvbiwgd2Ugc2hvdWxkIGVuYWJsZSB0aGlzIHRpbWVsaW5lIGFnYWluIHNvIHRoYXQgaXQgcmVuZGVycyBwcm9wZXJseS4gV2Ugc2hvdWxkIGFsc28gYWxpZ24gdGhlIHBsYXloZWFkIHdpdGggdGhlIHBhcmVudCB0aW1lbGluZSdzIHdoZW4gYXBwcm9wcmlhdGUuXG5cblxuICBpZiAoX3VuY2FjaGUodGltZWxpbmUsIGNoaWxkKS5fZHAgJiYgdGltZWxpbmUuX2luaXR0ZWQgJiYgdGltZWxpbmUuX3RpbWUgPj0gdGltZWxpbmUuX2R1ciAmJiB0aW1lbGluZS5fdHMpIHtcbiAgICAvL2luIGNhc2UgYW55IG9mIHRoZSBhbmNlc3RvcnMgaGFkIGNvbXBsZXRlZCBidXQgc2hvdWxkIG5vdyBiZSBlbmFibGVkLi4uXG4gICAgaWYgKHRpbWVsaW5lLl9kdXIgPCB0aW1lbGluZS5kdXJhdGlvbigpKSB7XG4gICAgICB0ID0gdGltZWxpbmU7XG5cbiAgICAgIHdoaWxlICh0Ll9kcCkge1xuICAgICAgICB0LnJhd1RpbWUoKSA+PSAwICYmIHQudG90YWxUaW1lKHQuX3RUaW1lKTsgLy9tb3ZlcyB0aGUgdGltZWxpbmUgKHNoaWZ0cyBpdHMgc3RhcnRUaW1lKSBpZiBuZWNlc3NhcnksIGFuZCBhbHNvIGVuYWJsZXMgaXQuIElmIGl0J3MgY3VycmVudGx5IHplcm8sIHRob3VnaCwgaXQgbWF5IG5vdCBiZSBzY2hlZHVsZWQgdG8gcmVuZGVyIHVudGlsIGxhdGVyIHNvIHRoZXJlJ3Mgbm8gbmVlZCB0byBmb3JjZSBpdCB0byBhbGlnbiB3aXRoIHRoZSBjdXJyZW50IHBsYXloZWFkIHBvc2l0aW9uLiBPbmx5IG1vdmUgdG8gY2F0Y2ggdXAgd2l0aCB0aGUgcGxheWhlYWQuXG5cbiAgICAgICAgdCA9IHQuX2RwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRpbWVsaW5lLl96VGltZSA9IC1fdGlueU51bTsgLy8gaGVscHMgZW5zdXJlIHRoYXQgdGhlIG5leHQgcmVuZGVyKCkgd2lsbCBiZSBmb3JjZWQgKGNyb3NzaW5nU3RhcnQgPSB0cnVlIGluIHJlbmRlcigpKSwgZXZlbiBpZiB0aGUgZHVyYXRpb24gaGFzbid0IGNoYW5nZWQgKHdlJ3JlIGFkZGluZyBhIGNoaWxkIHdoaWNoIHdvdWxkIG5lZWQgdG8gZ2V0IHJlbmRlcmVkKS4gRGVmaW5pdGVseSBhbiBlZGdlIGNhc2UuIE5vdGU6IHdlIE1VU1QgZG8gdGhpcyBBRlRFUiB0aGUgbG9vcCBhYm92ZSB3aGVyZSB0aGUgdG90YWxUaW1lKCkgbWlnaHQgdHJpZ2dlciBhIHJlbmRlcigpIGJlY2F1c2UgdGhpcyBfYWRkVG9UaW1lbGluZSgpIG1ldGhvZCBnZXRzIGNhbGxlZCBmcm9tIHRoZSBBbmltYXRpb24gY29uc3RydWN0b3IsIEJFRk9SRSB0d2VlbnMgZXZlbiByZWNvcmQgdGhlaXIgdGFyZ2V0cywgZXRjLiBzbyB3ZSB3b3VsZG4ndCB3YW50IHRoaW5ncyB0byBnZXQgdHJpZ2dlcmVkIGluIHRoZSB3cm9uZyBvcmRlci5cbiAgfVxufSxcbiAgICBfYWRkVG9UaW1lbGluZSA9IGZ1bmN0aW9uIF9hZGRUb1RpbWVsaW5lKHRpbWVsaW5lLCBjaGlsZCwgcG9zaXRpb24sIHNraXBDaGVja3MpIHtcbiAgY2hpbGQucGFyZW50ICYmIF9yZW1vdmVGcm9tUGFyZW50KGNoaWxkKTtcbiAgY2hpbGQuX3N0YXJ0ID0gX3JvdW5kUHJlY2lzZSgoX2lzTnVtYmVyKHBvc2l0aW9uKSA/IHBvc2l0aW9uIDogcG9zaXRpb24gfHwgdGltZWxpbmUgIT09IF9nbG9iYWxUaW1lbGluZSA/IF9wYXJzZVBvc2l0aW9uKHRpbWVsaW5lLCBwb3NpdGlvbiwgY2hpbGQpIDogdGltZWxpbmUuX3RpbWUpICsgY2hpbGQuX2RlbGF5KTtcbiAgY2hpbGQuX2VuZCA9IF9yb3VuZFByZWNpc2UoY2hpbGQuX3N0YXJ0ICsgKGNoaWxkLnRvdGFsRHVyYXRpb24oKSAvIE1hdGguYWJzKGNoaWxkLnRpbWVTY2FsZSgpKSB8fCAwKSk7XG5cbiAgX2FkZExpbmtlZExpc3RJdGVtKHRpbWVsaW5lLCBjaGlsZCwgXCJfZmlyc3RcIiwgXCJfbGFzdFwiLCB0aW1lbGluZS5fc29ydCA/IFwiX3N0YXJ0XCIgOiAwKTtcblxuICBfaXNGcm9tT3JGcm9tU3RhcnQoY2hpbGQpIHx8ICh0aW1lbGluZS5fcmVjZW50ID0gY2hpbGQpO1xuICBza2lwQ2hlY2tzIHx8IF9wb3N0QWRkQ2hlY2tzKHRpbWVsaW5lLCBjaGlsZCk7XG4gIHRpbWVsaW5lLl90cyA8IDAgJiYgX2FsaWduUGxheWhlYWQodGltZWxpbmUsIHRpbWVsaW5lLl90VGltZSk7IC8vIGlmIHRoZSB0aW1lbGluZSBpcyByZXZlcnNlZCBhbmQgdGhlIG5ldyBjaGlsZCBtYWtlcyBpdCBsb25nZXIsIHdlIG1heSBuZWVkIHRvIGFkanVzdCB0aGUgcGFyZW50J3MgX3N0YXJ0IChwdXNoIGl0IGJhY2spXG5cbiAgcmV0dXJuIHRpbWVsaW5lO1xufSxcbiAgICBfc2Nyb2xsVHJpZ2dlciA9IGZ1bmN0aW9uIF9zY3JvbGxUcmlnZ2VyKGFuaW1hdGlvbiwgdHJpZ2dlcikge1xuICByZXR1cm4gKF9nbG9iYWxzLlNjcm9sbFRyaWdnZXIgfHwgX21pc3NpbmdQbHVnaW4oXCJzY3JvbGxUcmlnZ2VyXCIsIHRyaWdnZXIpKSAmJiBfZ2xvYmFscy5TY3JvbGxUcmlnZ2VyLmNyZWF0ZSh0cmlnZ2VyLCBhbmltYXRpb24pO1xufSxcbiAgICBfYXR0ZW1wdEluaXRUd2VlbiA9IGZ1bmN0aW9uIF9hdHRlbXB0SW5pdFR3ZWVuKHR3ZWVuLCB0aW1lLCBmb3JjZSwgc3VwcHJlc3NFdmVudHMsIHRUaW1lKSB7XG4gIF9pbml0VHdlZW4odHdlZW4sIHRpbWUsIHRUaW1lKTtcblxuICBpZiAoIXR3ZWVuLl9pbml0dGVkKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBpZiAoIWZvcmNlICYmIHR3ZWVuLl9wdCAmJiAhX3JldmVydGluZyAmJiAodHdlZW4uX2R1ciAmJiB0d2Vlbi52YXJzLmxhenkgIT09IGZhbHNlIHx8ICF0d2Vlbi5fZHVyICYmIHR3ZWVuLnZhcnMubGF6eSkgJiYgX2xhc3RSZW5kZXJlZEZyYW1lICE9PSBfdGlja2VyLmZyYW1lKSB7XG4gICAgX2xhenlUd2VlbnMucHVzaCh0d2Vlbik7XG5cbiAgICB0d2Vlbi5fbGF6eSA9IFt0VGltZSwgc3VwcHJlc3NFdmVudHNdO1xuICAgIHJldHVybiAxO1xuICB9XG59LFxuICAgIF9wYXJlbnRQbGF5aGVhZElzQmVmb3JlU3RhcnQgPSBmdW5jdGlvbiBfcGFyZW50UGxheWhlYWRJc0JlZm9yZVN0YXJ0KF9yZWYpIHtcbiAgdmFyIHBhcmVudCA9IF9yZWYucGFyZW50O1xuICByZXR1cm4gcGFyZW50ICYmIHBhcmVudC5fdHMgJiYgcGFyZW50Ll9pbml0dGVkICYmICFwYXJlbnQuX2xvY2sgJiYgKHBhcmVudC5yYXdUaW1lKCkgPCAwIHx8IF9wYXJlbnRQbGF5aGVhZElzQmVmb3JlU3RhcnQocGFyZW50KSk7XG59LFxuICAgIC8vIGNoZWNrIHBhcmVudCdzIF9sb2NrIGJlY2F1c2Ugd2hlbiBhIHRpbWVsaW5lIHJlcGVhdHMveW95b3MgYW5kIGRvZXMgaXRzIGFydGlmaWNpYWwgd3JhcHBpbmcsIHdlIHNob3VsZG4ndCBmb3JjZSB0aGUgcmF0aW8gYmFjayB0byAwXG5faXNGcm9tT3JGcm9tU3RhcnQgPSBmdW5jdGlvbiBfaXNGcm9tT3JGcm9tU3RhcnQoX3JlZjIpIHtcbiAgdmFyIGRhdGEgPSBfcmVmMi5kYXRhO1xuICByZXR1cm4gZGF0YSA9PT0gXCJpc0Zyb21TdGFydFwiIHx8IGRhdGEgPT09IFwiaXNTdGFydFwiO1xufSxcbiAgICBfcmVuZGVyWmVyb0R1cmF0aW9uVHdlZW4gPSBmdW5jdGlvbiBfcmVuZGVyWmVyb0R1cmF0aW9uVHdlZW4odHdlZW4sIHRvdGFsVGltZSwgc3VwcHJlc3NFdmVudHMsIGZvcmNlKSB7XG4gIHZhciBwcmV2UmF0aW8gPSB0d2Vlbi5yYXRpbyxcbiAgICAgIHJhdGlvID0gdG90YWxUaW1lIDwgMCB8fCAhdG90YWxUaW1lICYmICghdHdlZW4uX3N0YXJ0ICYmIF9wYXJlbnRQbGF5aGVhZElzQmVmb3JlU3RhcnQodHdlZW4pICYmICEoIXR3ZWVuLl9pbml0dGVkICYmIF9pc0Zyb21PckZyb21TdGFydCh0d2VlbikpIHx8ICh0d2Vlbi5fdHMgPCAwIHx8IHR3ZWVuLl9kcC5fdHMgPCAwKSAmJiAhX2lzRnJvbU9yRnJvbVN0YXJ0KHR3ZWVuKSkgPyAwIDogMSxcbiAgICAgIC8vIGlmIHRoZSB0d2VlbiBvciBpdHMgcGFyZW50IGlzIHJldmVyc2VkIGFuZCB0aGUgdG90YWxUaW1lIGlzIDAsIHdlIHNob3VsZCBnbyB0byBhIHJhdGlvIG9mIDAuIEVkZ2UgY2FzZTogaWYgYSBmcm9tKCkgb3IgZnJvbVRvKCkgc3RhZ2dlciB0d2VlbiBpcyBwbGFjZWQgbGF0ZXIgaW4gYSB0aW1lbGluZSwgdGhlIFwic3RhcnRBdFwiIHplcm8tZHVyYXRpb24gdHdlZW4gY291bGQgaW5pdGlhbGx5IHJlbmRlciBhdCBhIHRpbWUgd2hlbiB0aGUgcGFyZW50IHRpbWVsaW5lJ3MgcGxheWhlYWQgaXMgdGVjaG5pY2FsbHkgQkVGT1JFIHdoZXJlIHRoaXMgdHdlZW4gaXMsIHNvIG1ha2Ugc3VyZSB0aGF0IGFueSBcImZyb21cIiBhbmQgXCJmcm9tVG9cIiBzdGFydEF0IHR3ZWVucyBhcmUgcmVuZGVyZWQgdGhlIGZpcnN0IHRpbWUgYXQgYSByYXRpbyBvZiAxLlxuICByZXBlYXREZWxheSA9IHR3ZWVuLl9yRGVsYXksXG4gICAgICB0VGltZSA9IDAsXG4gICAgICBwdCxcbiAgICAgIGl0ZXJhdGlvbixcbiAgICAgIHByZXZJdGVyYXRpb247XG5cbiAgaWYgKHJlcGVhdERlbGF5ICYmIHR3ZWVuLl9yZXBlYXQpIHtcbiAgICAvLyBpbiBjYXNlIHRoZXJlJ3MgYSB6ZXJvLWR1cmF0aW9uIHR3ZWVuIHRoYXQgaGFzIGEgcmVwZWF0IHdpdGggYSByZXBlYXREZWxheVxuICAgIHRUaW1lID0gX2NsYW1wKDAsIHR3ZWVuLl90RHVyLCB0b3RhbFRpbWUpO1xuICAgIGl0ZXJhdGlvbiA9IF9hbmltYXRpb25DeWNsZSh0VGltZSwgcmVwZWF0RGVsYXkpO1xuICAgIHR3ZWVuLl95b3lvICYmIGl0ZXJhdGlvbiAmIDEgJiYgKHJhdGlvID0gMSAtIHJhdGlvKTtcblxuICAgIGlmIChpdGVyYXRpb24gIT09IF9hbmltYXRpb25DeWNsZSh0d2Vlbi5fdFRpbWUsIHJlcGVhdERlbGF5KSkge1xuICAgICAgLy8gaWYgaXRlcmF0aW9uIGNoYW5nZWRcbiAgICAgIHByZXZSYXRpbyA9IDEgLSByYXRpbztcbiAgICAgIHR3ZWVuLnZhcnMucmVwZWF0UmVmcmVzaCAmJiB0d2Vlbi5faW5pdHRlZCAmJiB0d2Vlbi5pbnZhbGlkYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJhdGlvICE9PSBwcmV2UmF0aW8gfHwgX3JldmVydGluZyB8fCBmb3JjZSB8fCB0d2Vlbi5felRpbWUgPT09IF90aW55TnVtIHx8ICF0b3RhbFRpbWUgJiYgdHdlZW4uX3pUaW1lKSB7XG4gICAgaWYgKCF0d2Vlbi5faW5pdHRlZCAmJiBfYXR0ZW1wdEluaXRUd2Vlbih0d2VlbiwgdG90YWxUaW1lLCBmb3JjZSwgc3VwcHJlc3NFdmVudHMsIHRUaW1lKSkge1xuICAgICAgLy8gaWYgd2UgcmVuZGVyIHRoZSB2ZXJ5IGJlZ2lubmluZyAodGltZSA9PSAwKSBvZiBhIGZyb21UbygpLCB3ZSBtdXN0IGZvcmNlIHRoZSByZW5kZXIgKG5vcm1hbCB0d2VlbnMgd291bGRuJ3QgbmVlZCB0byByZW5kZXIgYXQgYSB0aW1lIG9mIDAgd2hlbiB0aGUgcHJldlRpbWUgd2FzIGFsc28gMCkuIFRoaXMgaXMgYWxzbyBtYW5kYXRvcnkgdG8gbWFrZSBzdXJlIG92ZXJ3cml0aW5nIGtpY2tzIGluIGltbWVkaWF0ZWx5LlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHByZXZJdGVyYXRpb24gPSB0d2Vlbi5felRpbWU7XG4gICAgdHdlZW4uX3pUaW1lID0gdG90YWxUaW1lIHx8IChzdXBwcmVzc0V2ZW50cyA/IF90aW55TnVtIDogMCk7IC8vIHdoZW4gdGhlIHBsYXloZWFkIGFycml2ZXMgYXQgRVhBQ1RMWSB0aW1lIDAgKHJpZ2h0IG9uIHRvcCkgb2YgYSB6ZXJvLWR1cmF0aW9uIHR3ZWVuLCB3ZSBuZWVkIHRvIGRpc2Nlcm4gaWYgZXZlbnRzIGFyZSBzdXBwcmVzc2VkIHNvIHRoYXQgd2hlbiB0aGUgcGxheWhlYWQgbW92ZXMgYWdhaW4gKG5leHQgdGltZSksIGl0J2xsIHRyaWdnZXIgdGhlIGNhbGxiYWNrLiBJZiBldmVudHMgYXJlIE5PVCBzdXBwcmVzc2VkLCBvYnZpb3VzbHkgdGhlIGNhbGxiYWNrIHdvdWxkIGJlIHRyaWdnZXJlZCBpbiB0aGlzIHJlbmRlci4gQmFzaWNhbGx5LCB0aGUgY2FsbGJhY2sgc2hvdWxkIGZpcmUgZWl0aGVyIHdoZW4gdGhlIHBsYXloZWFkIEFSUklWRVMgb3IgTEVBVkVTIHRoaXMgZXhhY3Qgc3BvdCwgbm90IGJvdGguIEltYWdpbmUgZG9pbmcgYSB0aW1lbGluZS5zZWVrKDApIGFuZCB0aGVyZSdzIGEgY2FsbGJhY2sgdGhhdCBzaXRzIGF0IDAuIFNpbmNlIGV2ZW50cyBhcmUgc3VwcHJlc3NlZCBvbiB0aGF0IHNlZWsoKSBieSBkZWZhdWx0LCBub3RoaW5nIHdpbGwgZmlyZSwgYnV0IHdoZW4gdGhlIHBsYXloZWFkIG1vdmVzIG9mZiBvZiB0aGF0IHBvc2l0aW9uLCB0aGUgY2FsbGJhY2sgc2hvdWxkIGZpcmUuIFRoaXMgYmVoYXZpb3IgaXMgd2hhdCBwZW9wbGUgaW50dWl0aXZlbHkgZXhwZWN0LlxuXG4gICAgc3VwcHJlc3NFdmVudHMgfHwgKHN1cHByZXNzRXZlbnRzID0gdG90YWxUaW1lICYmICFwcmV2SXRlcmF0aW9uKTsgLy8gaWYgaXQgd2FzIHJlbmRlcmVkIHByZXZpb3VzbHkgYXQgZXhhY3RseSAwIChfelRpbWUpIGFuZCBub3cgdGhlIHBsYXloZWFkIGlzIG1vdmluZyBhd2F5LCBET04nVCBmaXJlIGNhbGxiYWNrcyBvdGhlcndpc2UgdGhleSdsbCBzZWVtIGxpa2UgZHVwbGljYXRlcy5cblxuICAgIHR3ZWVuLnJhdGlvID0gcmF0aW87XG4gICAgdHdlZW4uX2Zyb20gJiYgKHJhdGlvID0gMSAtIHJhdGlvKTtcbiAgICB0d2Vlbi5fdGltZSA9IDA7XG4gICAgdHdlZW4uX3RUaW1lID0gdFRpbWU7XG4gICAgcHQgPSB0d2Vlbi5fcHQ7XG5cbiAgICB3aGlsZSAocHQpIHtcbiAgICAgIHB0LnIocmF0aW8sIHB0LmQpO1xuICAgICAgcHQgPSBwdC5fbmV4dDtcbiAgICB9XG5cbiAgICB0b3RhbFRpbWUgPCAwICYmIF9yZXdpbmRTdGFydEF0KHR3ZWVuLCB0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCB0cnVlKTtcbiAgICB0d2Vlbi5fb25VcGRhdGUgJiYgIXN1cHByZXNzRXZlbnRzICYmIF9jYWxsYmFjayh0d2VlbiwgXCJvblVwZGF0ZVwiKTtcbiAgICB0VGltZSAmJiB0d2Vlbi5fcmVwZWF0ICYmICFzdXBwcmVzc0V2ZW50cyAmJiB0d2Vlbi5wYXJlbnQgJiYgX2NhbGxiYWNrKHR3ZWVuLCBcIm9uUmVwZWF0XCIpO1xuXG4gICAgaWYgKCh0b3RhbFRpbWUgPj0gdHdlZW4uX3REdXIgfHwgdG90YWxUaW1lIDwgMCkgJiYgdHdlZW4ucmF0aW8gPT09IHJhdGlvKSB7XG4gICAgICByYXRpbyAmJiBfcmVtb3ZlRnJvbVBhcmVudCh0d2VlbiwgMSk7XG5cbiAgICAgIGlmICghc3VwcHJlc3NFdmVudHMgJiYgIV9yZXZlcnRpbmcpIHtcbiAgICAgICAgX2NhbGxiYWNrKHR3ZWVuLCByYXRpbyA/IFwib25Db21wbGV0ZVwiIDogXCJvblJldmVyc2VDb21wbGV0ZVwiLCB0cnVlKTtcblxuICAgICAgICB0d2Vlbi5fcHJvbSAmJiB0d2Vlbi5fcHJvbSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICghdHdlZW4uX3pUaW1lKSB7XG4gICAgdHdlZW4uX3pUaW1lID0gdG90YWxUaW1lO1xuICB9XG59LFxuICAgIF9maW5kTmV4dFBhdXNlVHdlZW4gPSBmdW5jdGlvbiBfZmluZE5leHRQYXVzZVR3ZWVuKGFuaW1hdGlvbiwgcHJldlRpbWUsIHRpbWUpIHtcbiAgdmFyIGNoaWxkO1xuXG4gIGlmICh0aW1lID4gcHJldlRpbWUpIHtcbiAgICBjaGlsZCA9IGFuaW1hdGlvbi5fZmlyc3Q7XG5cbiAgICB3aGlsZSAoY2hpbGQgJiYgY2hpbGQuX3N0YXJ0IDw9IHRpbWUpIHtcbiAgICAgIGlmIChjaGlsZC5kYXRhID09PSBcImlzUGF1c2VcIiAmJiBjaGlsZC5fc3RhcnQgPiBwcmV2VGltZSkge1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNoaWxkID0gYW5pbWF0aW9uLl9sYXN0O1xuXG4gICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLl9zdGFydCA+PSB0aW1lKSB7XG4gICAgICBpZiAoY2hpbGQuZGF0YSA9PT0gXCJpc1BhdXNlXCIgJiYgY2hpbGQuX3N0YXJ0IDwgcHJldlRpbWUpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLl9wcmV2O1xuICAgIH1cbiAgfVxufSxcbiAgICBfc2V0RHVyYXRpb24gPSBmdW5jdGlvbiBfc2V0RHVyYXRpb24oYW5pbWF0aW9uLCBkdXJhdGlvbiwgc2tpcFVuY2FjaGUsIGxlYXZlUGxheWhlYWQpIHtcbiAgdmFyIHJlcGVhdCA9IGFuaW1hdGlvbi5fcmVwZWF0LFxuICAgICAgZHVyID0gX3JvdW5kUHJlY2lzZShkdXJhdGlvbikgfHwgMCxcbiAgICAgIHRvdGFsUHJvZ3Jlc3MgPSBhbmltYXRpb24uX3RUaW1lIC8gYW5pbWF0aW9uLl90RHVyO1xuICB0b3RhbFByb2dyZXNzICYmICFsZWF2ZVBsYXloZWFkICYmIChhbmltYXRpb24uX3RpbWUgKj0gZHVyIC8gYW5pbWF0aW9uLl9kdXIpO1xuICBhbmltYXRpb24uX2R1ciA9IGR1cjtcbiAgYW5pbWF0aW9uLl90RHVyID0gIXJlcGVhdCA/IGR1ciA6IHJlcGVhdCA8IDAgPyAxZTEwIDogX3JvdW5kUHJlY2lzZShkdXIgKiAocmVwZWF0ICsgMSkgKyBhbmltYXRpb24uX3JEZWxheSAqIHJlcGVhdCk7XG4gIHRvdGFsUHJvZ3Jlc3MgPiAwICYmICFsZWF2ZVBsYXloZWFkICYmIF9hbGlnblBsYXloZWFkKGFuaW1hdGlvbiwgYW5pbWF0aW9uLl90VGltZSA9IGFuaW1hdGlvbi5fdER1ciAqIHRvdGFsUHJvZ3Jlc3MpO1xuICBhbmltYXRpb24ucGFyZW50ICYmIF9zZXRFbmQoYW5pbWF0aW9uKTtcbiAgc2tpcFVuY2FjaGUgfHwgX3VuY2FjaGUoYW5pbWF0aW9uLnBhcmVudCwgYW5pbWF0aW9uKTtcbiAgcmV0dXJuIGFuaW1hdGlvbjtcbn0sXG4gICAgX29uVXBkYXRlVG90YWxEdXJhdGlvbiA9IGZ1bmN0aW9uIF9vblVwZGF0ZVRvdGFsRHVyYXRpb24oYW5pbWF0aW9uKSB7XG4gIHJldHVybiBhbmltYXRpb24gaW5zdGFuY2VvZiBUaW1lbGluZSA/IF91bmNhY2hlKGFuaW1hdGlvbikgOiBfc2V0RHVyYXRpb24oYW5pbWF0aW9uLCBhbmltYXRpb24uX2R1cik7XG59LFxuICAgIF96ZXJvUG9zaXRpb24gPSB7XG4gIF9zdGFydDogMCxcbiAgZW5kVGltZTogX2VtcHR5RnVuYyxcbiAgdG90YWxEdXJhdGlvbjogX2VtcHR5RnVuY1xufSxcbiAgICBfcGFyc2VQb3NpdGlvbiA9IGZ1bmN0aW9uIF9wYXJzZVBvc2l0aW9uKGFuaW1hdGlvbiwgcG9zaXRpb24sIHBlcmNlbnRBbmltYXRpb24pIHtcbiAgdmFyIGxhYmVscyA9IGFuaW1hdGlvbi5sYWJlbHMsXG4gICAgICByZWNlbnQgPSBhbmltYXRpb24uX3JlY2VudCB8fCBfemVyb1Bvc2l0aW9uLFxuICAgICAgY2xpcHBlZER1cmF0aW9uID0gYW5pbWF0aW9uLmR1cmF0aW9uKCkgPj0gX2JpZ051bSA/IHJlY2VudC5lbmRUaW1lKGZhbHNlKSA6IGFuaW1hdGlvbi5fZHVyLFxuICAgICAgLy9pbiBjYXNlIHRoZXJlJ3MgYSBjaGlsZCB0aGF0IGluZmluaXRlbHkgcmVwZWF0cywgdXNlcnMgYWxtb3N0IG5ldmVyIGludGVuZCBmb3IgdGhlIGluc2VydGlvbiBwb2ludCBvZiBhIG5ldyBjaGlsZCB0byBiZSBiYXNlZCBvbiBhIFNVUEVSIGxvbmcgdmFsdWUgbGlrZSB0aGF0IHNvIHdlIGNsaXAgaXQgYW5kIGFzc3VtZSB0aGUgbW9zdCByZWNlbnRseS1hZGRlZCBjaGlsZCdzIGVuZFRpbWUgc2hvdWxkIGJlIHVzZWQgaW5zdGVhZC5cbiAgaSxcbiAgICAgIG9mZnNldCxcbiAgICAgIGlzUGVyY2VudDtcblxuICBpZiAoX2lzU3RyaW5nKHBvc2l0aW9uKSAmJiAoaXNOYU4ocG9zaXRpb24pIHx8IHBvc2l0aW9uIGluIGxhYmVscykpIHtcbiAgICAvL2lmIHRoZSBzdHJpbmcgaXMgYSBudW1iZXIgbGlrZSBcIjFcIiwgY2hlY2sgdG8gc2VlIGlmIHRoZXJlJ3MgYSBsYWJlbCB3aXRoIHRoYXQgbmFtZSwgb3RoZXJ3aXNlIGludGVycHJldCBpdCBhcyBhIG51bWJlciAoYWJzb2x1dGUgdmFsdWUpLlxuICAgIG9mZnNldCA9IHBvc2l0aW9uLmNoYXJBdCgwKTtcbiAgICBpc1BlcmNlbnQgPSBwb3NpdGlvbi5zdWJzdHIoLTEpID09PSBcIiVcIjtcbiAgICBpID0gcG9zaXRpb24uaW5kZXhPZihcIj1cIik7XG5cbiAgICBpZiAob2Zmc2V0ID09PSBcIjxcIiB8fCBvZmZzZXQgPT09IFwiPlwiKSB7XG4gICAgICBpID49IDAgJiYgKHBvc2l0aW9uID0gcG9zaXRpb24ucmVwbGFjZSgvPS8sIFwiXCIpKTtcbiAgICAgIHJldHVybiAob2Zmc2V0ID09PSBcIjxcIiA/IHJlY2VudC5fc3RhcnQgOiByZWNlbnQuZW5kVGltZShyZWNlbnQuX3JlcGVhdCA+PSAwKSkgKyAocGFyc2VGbG9hdChwb3NpdGlvbi5zdWJzdHIoMSkpIHx8IDApICogKGlzUGVyY2VudCA/IChpIDwgMCA/IHJlY2VudCA6IHBlcmNlbnRBbmltYXRpb24pLnRvdGFsRHVyYXRpb24oKSAvIDEwMCA6IDEpO1xuICAgIH1cblxuICAgIGlmIChpIDwgMCkge1xuICAgICAgcG9zaXRpb24gaW4gbGFiZWxzIHx8IChsYWJlbHNbcG9zaXRpb25dID0gY2xpcHBlZER1cmF0aW9uKTtcbiAgICAgIHJldHVybiBsYWJlbHNbcG9zaXRpb25dO1xuICAgIH1cblxuICAgIG9mZnNldCA9IHBhcnNlRmxvYXQocG9zaXRpb24uY2hhckF0KGkgLSAxKSArIHBvc2l0aW9uLnN1YnN0cihpICsgMSkpO1xuXG4gICAgaWYgKGlzUGVyY2VudCAmJiBwZXJjZW50QW5pbWF0aW9uKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgLyAxMDAgKiAoX2lzQXJyYXkocGVyY2VudEFuaW1hdGlvbikgPyBwZXJjZW50QW5pbWF0aW9uWzBdIDogcGVyY2VudEFuaW1hdGlvbikudG90YWxEdXJhdGlvbigpO1xuICAgIH1cblxuICAgIHJldHVybiBpID4gMSA/IF9wYXJzZVBvc2l0aW9uKGFuaW1hdGlvbiwgcG9zaXRpb24uc3Vic3RyKDAsIGkgLSAxKSwgcGVyY2VudEFuaW1hdGlvbikgKyBvZmZzZXQgOiBjbGlwcGVkRHVyYXRpb24gKyBvZmZzZXQ7XG4gIH1cblxuICByZXR1cm4gcG9zaXRpb24gPT0gbnVsbCA/IGNsaXBwZWREdXJhdGlvbiA6ICtwb3NpdGlvbjtcbn0sXG4gICAgX2NyZWF0ZVR3ZWVuVHlwZSA9IGZ1bmN0aW9uIF9jcmVhdGVUd2VlblR5cGUodHlwZSwgcGFyYW1zLCB0aW1lbGluZSkge1xuICB2YXIgaXNMZWdhY3kgPSBfaXNOdW1iZXIocGFyYW1zWzFdKSxcbiAgICAgIHZhcnNJbmRleCA9IChpc0xlZ2FjeSA/IDIgOiAxKSArICh0eXBlIDwgMiA/IDAgOiAxKSxcbiAgICAgIHZhcnMgPSBwYXJhbXNbdmFyc0luZGV4XSxcbiAgICAgIGlyVmFycyxcbiAgICAgIHBhcmVudDtcblxuICBpc0xlZ2FjeSAmJiAodmFycy5kdXJhdGlvbiA9IHBhcmFtc1sxXSk7XG4gIHZhcnMucGFyZW50ID0gdGltZWxpbmU7XG5cbiAgaWYgKHR5cGUpIHtcbiAgICBpclZhcnMgPSB2YXJzO1xuICAgIHBhcmVudCA9IHRpbWVsaW5lO1xuXG4gICAgd2hpbGUgKHBhcmVudCAmJiAhKFwiaW1tZWRpYXRlUmVuZGVyXCIgaW4gaXJWYXJzKSkge1xuICAgICAgLy8gaW5oZXJpdGFuY2UgaGFzbid0IGhhcHBlbmVkIHlldCwgYnV0IHNvbWVvbmUgbWF5IGhhdmUgc2V0IGEgZGVmYXVsdCBpbiBhbiBhbmNlc3RvciB0aW1lbGluZS4gV2UgY291bGQgZG8gdmFycy5pbW1lZGlhdGVSZW5kZXIgPSBfaXNOb3RGYWxzZShfaW5oZXJpdERlZmF1bHRzKHZhcnMpLmltbWVkaWF0ZVJlbmRlcikgYnV0IHRoYXQnZCBleGFjdCBhIHNsaWdodCBwZXJmb3JtYW5jZSBwZW5hbHR5IGJlY2F1c2UgX2luaGVyaXREZWZhdWx0cygpIGFsc28gcnVucyBpbiB0aGUgVHdlZW4gY29uc3RydWN0b3IuIFdlJ3JlIHBheWluZyBhIHNtYWxsIGtiIHByaWNlIGhlcmUgdG8gZ2FpbiBzcGVlZC5cbiAgICAgIGlyVmFycyA9IHBhcmVudC52YXJzLmRlZmF1bHRzIHx8IHt9O1xuICAgICAgcGFyZW50ID0gX2lzTm90RmFsc2UocGFyZW50LnZhcnMuaW5oZXJpdCkgJiYgcGFyZW50LnBhcmVudDtcbiAgICB9XG5cbiAgICB2YXJzLmltbWVkaWF0ZVJlbmRlciA9IF9pc05vdEZhbHNlKGlyVmFycy5pbW1lZGlhdGVSZW5kZXIpO1xuICAgIHR5cGUgPCAyID8gdmFycy5ydW5CYWNrd2FyZHMgPSAxIDogdmFycy5zdGFydEF0ID0gcGFyYW1zW3ZhcnNJbmRleCAtIDFdOyAvLyBcImZyb21cIiB2YXJzXG4gIH1cblxuICByZXR1cm4gbmV3IFR3ZWVuKHBhcmFtc1swXSwgdmFycywgcGFyYW1zW3ZhcnNJbmRleCArIDFdKTtcbn0sXG4gICAgX2NvbmRpdGlvbmFsUmV0dXJuID0gZnVuY3Rpb24gX2NvbmRpdGlvbmFsUmV0dXJuKHZhbHVlLCBmdW5jKSB7XG4gIHJldHVybiB2YWx1ZSB8fCB2YWx1ZSA9PT0gMCA/IGZ1bmModmFsdWUpIDogZnVuYztcbn0sXG4gICAgX2NsYW1wID0gZnVuY3Rpb24gX2NsYW1wKG1pbiwgbWF4LCB2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPCBtaW4gPyBtaW4gOiB2YWx1ZSA+IG1heCA/IG1heCA6IHZhbHVlO1xufSxcbiAgICBnZXRVbml0ID0gZnVuY3Rpb24gZ2V0VW5pdCh2YWx1ZSwgdikge1xuICByZXR1cm4gIV9pc1N0cmluZyh2YWx1ZSkgfHwgISh2ID0gX3VuaXRFeHAuZXhlYyh2YWx1ZSkpID8gXCJcIiA6IHZbMV07XG59LFxuICAgIC8vIG5vdGU6IHByb3RlY3QgYWdhaW5zdCBwYWRkZWQgbnVtYmVycyBhcyBzdHJpbmdzLCBsaWtlIFwiMTAwLjEwMFwiLiBUaGF0IHNob3VsZG4ndCByZXR1cm4gXCIwMFwiIGFzIHRoZSB1bml0LiBJZiBpdCdzIG51bWVyaWMsIHJldHVybiBubyB1bml0LlxuY2xhbXAgPSBmdW5jdGlvbiBjbGFtcChtaW4sIG1heCwgdmFsdWUpIHtcbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4gX2NsYW1wKG1pbiwgbWF4LCB2KTtcbiAgfSk7XG59LFxuICAgIF9zbGljZSA9IFtdLnNsaWNlLFxuICAgIF9pc0FycmF5TGlrZSA9IGZ1bmN0aW9uIF9pc0FycmF5TGlrZSh2YWx1ZSwgbm9uRW1wdHkpIHtcbiAgcmV0dXJuIHZhbHVlICYmIF9pc09iamVjdCh2YWx1ZSkgJiYgXCJsZW5ndGhcIiBpbiB2YWx1ZSAmJiAoIW5vbkVtcHR5ICYmICF2YWx1ZS5sZW5ndGggfHwgdmFsdWUubGVuZ3RoIC0gMSBpbiB2YWx1ZSAmJiBfaXNPYmplY3QodmFsdWVbMF0pKSAmJiAhdmFsdWUubm9kZVR5cGUgJiYgdmFsdWUgIT09IF93aW47XG59LFxuICAgIF9mbGF0dGVuID0gZnVuY3Rpb24gX2ZsYXR0ZW4oYXIsIGxlYXZlU3RyaW5ncywgYWNjdW11bGF0b3IpIHtcbiAgaWYgKGFjY3VtdWxhdG9yID09PSB2b2lkIDApIHtcbiAgICBhY2N1bXVsYXRvciA9IFtdO1xuICB9XG5cbiAgcmV0dXJuIGFyLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIF9hY2N1bXVsYXRvcjtcblxuICAgIHJldHVybiBfaXNTdHJpbmcodmFsdWUpICYmICFsZWF2ZVN0cmluZ3MgfHwgX2lzQXJyYXlMaWtlKHZhbHVlLCAxKSA/IChfYWNjdW11bGF0b3IgPSBhY2N1bXVsYXRvcikucHVzaC5hcHBseShfYWNjdW11bGF0b3IsIHRvQXJyYXkodmFsdWUpKSA6IGFjY3VtdWxhdG9yLnB1c2godmFsdWUpO1xuICB9KSB8fCBhY2N1bXVsYXRvcjtcbn0sXG4gICAgLy90YWtlcyBhbnkgdmFsdWUgYW5kIHJldHVybnMgYW4gYXJyYXkuIElmIGl0J3MgYSBzdHJpbmcgKGFuZCBsZWF2ZVN0cmluZ3MgaXNuJ3QgdHJ1ZSksIGl0J2xsIHVzZSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCkgYW5kIGNvbnZlcnQgdGhhdCB0byBhbiBhcnJheS4gSXQnbGwgYWxzbyBhY2NlcHQgaXRlcmFibGVzIGxpa2UgalF1ZXJ5IG9iamVjdHMuXG50b0FycmF5ID0gZnVuY3Rpb24gdG9BcnJheSh2YWx1ZSwgc2NvcGUsIGxlYXZlU3RyaW5ncykge1xuICByZXR1cm4gX2NvbnRleHQgJiYgIXNjb3BlICYmIF9jb250ZXh0LnNlbGVjdG9yID8gX2NvbnRleHQuc2VsZWN0b3IodmFsdWUpIDogX2lzU3RyaW5nKHZhbHVlKSAmJiAhbGVhdmVTdHJpbmdzICYmIChfY29yZUluaXR0ZWQgfHwgIV93YWtlKCkpID8gX3NsaWNlLmNhbGwoKHNjb3BlIHx8IF9kb2MpLnF1ZXJ5U2VsZWN0b3JBbGwodmFsdWUpLCAwKSA6IF9pc0FycmF5KHZhbHVlKSA/IF9mbGF0dGVuKHZhbHVlLCBsZWF2ZVN0cmluZ3MpIDogX2lzQXJyYXlMaWtlKHZhbHVlKSA/IF9zbGljZS5jYWxsKHZhbHVlLCAwKSA6IHZhbHVlID8gW3ZhbHVlXSA6IFtdO1xufSxcbiAgICBzZWxlY3RvciA9IGZ1bmN0aW9uIHNlbGVjdG9yKHZhbHVlKSB7XG4gIHZhbHVlID0gdG9BcnJheSh2YWx1ZSlbMF0gfHwgX3dhcm4oXCJJbnZhbGlkIHNjb3BlXCIpIHx8IHt9O1xuICByZXR1cm4gZnVuY3Rpb24gKHYpIHtcbiAgICB2YXIgZWwgPSB2YWx1ZS5jdXJyZW50IHx8IHZhbHVlLm5hdGl2ZUVsZW1lbnQgfHwgdmFsdWU7XG4gICAgcmV0dXJuIHRvQXJyYXkodiwgZWwucXVlcnlTZWxlY3RvckFsbCA/IGVsIDogZWwgPT09IHZhbHVlID8gX3dhcm4oXCJJbnZhbGlkIHNjb3BlXCIpIHx8IF9kb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKSA6IHZhbHVlKTtcbiAgfTtcbn0sXG4gICAgc2h1ZmZsZSA9IGZ1bmN0aW9uIHNodWZmbGUoYSkge1xuICByZXR1cm4gYS5zb3J0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gLjUgLSBNYXRoLnJhbmRvbSgpO1xuICB9KTtcbn0sXG4gICAgLy8gYWx0ZXJuYXRpdmUgdGhhdCdzIGEgYml0IGZhc3RlciBhbmQgbW9yZSByZWxpYWJseSBkaXZlcnNlIGJ1dCBiaWdnZXI6ICAgZm9yIChsZXQgaiwgdiwgaSA9IGEubGVuZ3RoOyBpOyBqID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogaSksIHYgPSBhWy0taV0sIGFbaV0gPSBhW2pdLCBhW2pdID0gdik7IHJldHVybiBhO1xuLy9mb3IgZGlzdHJpYnV0aW5nIHZhbHVlcyBhY3Jvc3MgYW4gYXJyYXkuIENhbiBhY2NlcHQgYSBudW1iZXIsIGEgZnVuY3Rpb24gb3IgKG1vc3QgY29tbW9ubHkpIGEgZnVuY3Rpb24gd2hpY2ggY2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOiB7YmFzZSwgYW1vdW50LCBmcm9tLCBlYXNlLCBncmlkLCBheGlzLCBsZW5ndGgsIGVhY2h9LiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBleHBlY3RzIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczogaW5kZXgsIHRhcmdldCwgYXJyYXkuIFJlY29nbml6ZXMgdGhlIGZvbGxvd2luZ1xuZGlzdHJpYnV0ZSA9IGZ1bmN0aW9uIGRpc3RyaWJ1dGUodikge1xuICBpZiAoX2lzRnVuY3Rpb24odikpIHtcbiAgICByZXR1cm4gdjtcbiAgfVxuXG4gIHZhciB2YXJzID0gX2lzT2JqZWN0KHYpID8gdiA6IHtcbiAgICBlYWNoOiB2XG4gIH0sXG4gICAgICAvL246MSBpcyBqdXN0IHRvIGluZGljYXRlIHYgd2FzIGEgbnVtYmVyOyB3ZSBsZXZlcmFnZSB0aGF0IGxhdGVyIHRvIHNldCB2IGFjY29yZGluZyB0byB0aGUgbGVuZ3RoIHdlIGdldC4gSWYgYSBudW1iZXIgaXMgcGFzc2VkIGluLCB3ZSB0cmVhdCBpdCBsaWtlIHRoZSBvbGQgc3RhZ2dlciB2YWx1ZSB3aGVyZSAwLjEsIGZvciBleGFtcGxlLCB3b3VsZCBtZWFuIHRoYXQgdGhpbmdzIHdvdWxkIGJlIGRpc3RyaWJ1dGVkIHdpdGggMC4xIGJldHdlZW4gZWFjaCBlbGVtZW50IGluIHRoZSBhcnJheSByYXRoZXIgdGhhbiBhIHRvdGFsIFwiYW1vdW50XCIgdGhhdCdzIGNodW5rZWQgb3V0IGFtb25nIHRoZW0gYWxsLlxuICBlYXNlID0gX3BhcnNlRWFzZSh2YXJzLmVhc2UpLFxuICAgICAgZnJvbSA9IHZhcnMuZnJvbSB8fCAwLFxuICAgICAgYmFzZSA9IHBhcnNlRmxvYXQodmFycy5iYXNlKSB8fCAwLFxuICAgICAgY2FjaGUgPSB7fSxcbiAgICAgIGlzRGVjaW1hbCA9IGZyb20gPiAwICYmIGZyb20gPCAxLFxuICAgICAgcmF0aW9zID0gaXNOYU4oZnJvbSkgfHwgaXNEZWNpbWFsLFxuICAgICAgYXhpcyA9IHZhcnMuYXhpcyxcbiAgICAgIHJhdGlvWCA9IGZyb20sXG4gICAgICByYXRpb1kgPSBmcm9tO1xuXG4gIGlmIChfaXNTdHJpbmcoZnJvbSkpIHtcbiAgICByYXRpb1ggPSByYXRpb1kgPSB7XG4gICAgICBjZW50ZXI6IC41LFxuICAgICAgZWRnZXM6IC41LFxuICAgICAgZW5kOiAxXG4gICAgfVtmcm9tXSB8fCAwO1xuICB9IGVsc2UgaWYgKCFpc0RlY2ltYWwgJiYgcmF0aW9zKSB7XG4gICAgcmF0aW9YID0gZnJvbVswXTtcbiAgICByYXRpb1kgPSBmcm9tWzFdO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChpLCB0YXJnZXQsIGEpIHtcbiAgICB2YXIgbCA9IChhIHx8IHZhcnMpLmxlbmd0aCxcbiAgICAgICAgZGlzdGFuY2VzID0gY2FjaGVbbF0sXG4gICAgICAgIG9yaWdpblgsXG4gICAgICAgIG9yaWdpblksXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIGQsXG4gICAgICAgIGosXG4gICAgICAgIG1heCxcbiAgICAgICAgbWluLFxuICAgICAgICB3cmFwQXQ7XG5cbiAgICBpZiAoIWRpc3RhbmNlcykge1xuICAgICAgd3JhcEF0ID0gdmFycy5ncmlkID09PSBcImF1dG9cIiA/IDAgOiAodmFycy5ncmlkIHx8IFsxLCBfYmlnTnVtXSlbMV07XG5cbiAgICAgIGlmICghd3JhcEF0KSB7XG4gICAgICAgIG1heCA9IC1fYmlnTnVtO1xuXG4gICAgICAgIHdoaWxlIChtYXggPCAobWF4ID0gYVt3cmFwQXQrK10uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCkgJiYgd3JhcEF0IDwgbCkge31cblxuICAgICAgICB3cmFwQXQtLTtcbiAgICAgIH1cblxuICAgICAgZGlzdGFuY2VzID0gY2FjaGVbbF0gPSBbXTtcbiAgICAgIG9yaWdpblggPSByYXRpb3MgPyBNYXRoLm1pbih3cmFwQXQsIGwpICogcmF0aW9YIC0gLjUgOiBmcm9tICUgd3JhcEF0O1xuICAgICAgb3JpZ2luWSA9IHdyYXBBdCA9PT0gX2JpZ051bSA/IDAgOiByYXRpb3MgPyBsICogcmF0aW9ZIC8gd3JhcEF0IC0gLjUgOiBmcm9tIC8gd3JhcEF0IHwgMDtcbiAgICAgIG1heCA9IDA7XG4gICAgICBtaW4gPSBfYmlnTnVtO1xuXG4gICAgICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgICAgIHggPSBqICUgd3JhcEF0IC0gb3JpZ2luWDtcbiAgICAgICAgeSA9IG9yaWdpblkgLSAoaiAvIHdyYXBBdCB8IDApO1xuICAgICAgICBkaXN0YW5jZXNbal0gPSBkID0gIWF4aXMgPyBfc3FydCh4ICogeCArIHkgKiB5KSA6IE1hdGguYWJzKGF4aXMgPT09IFwieVwiID8geSA6IHgpO1xuICAgICAgICBkID4gbWF4ICYmIChtYXggPSBkKTtcbiAgICAgICAgZCA8IG1pbiAmJiAobWluID0gZCk7XG4gICAgICB9XG5cbiAgICAgIGZyb20gPT09IFwicmFuZG9tXCIgJiYgc2h1ZmZsZShkaXN0YW5jZXMpO1xuICAgICAgZGlzdGFuY2VzLm1heCA9IG1heCAtIG1pbjtcbiAgICAgIGRpc3RhbmNlcy5taW4gPSBtaW47XG4gICAgICBkaXN0YW5jZXMudiA9IGwgPSAocGFyc2VGbG9hdCh2YXJzLmFtb3VudCkgfHwgcGFyc2VGbG9hdCh2YXJzLmVhY2gpICogKHdyYXBBdCA+IGwgPyBsIC0gMSA6ICFheGlzID8gTWF0aC5tYXgod3JhcEF0LCBsIC8gd3JhcEF0KSA6IGF4aXMgPT09IFwieVwiID8gbCAvIHdyYXBBdCA6IHdyYXBBdCkgfHwgMCkgKiAoZnJvbSA9PT0gXCJlZGdlc1wiID8gLTEgOiAxKTtcbiAgICAgIGRpc3RhbmNlcy5iID0gbCA8IDAgPyBiYXNlIC0gbCA6IGJhc2U7XG4gICAgICBkaXN0YW5jZXMudSA9IGdldFVuaXQodmFycy5hbW91bnQgfHwgdmFycy5lYWNoKSB8fCAwOyAvL3VuaXRcblxuICAgICAgZWFzZSA9IGVhc2UgJiYgbCA8IDAgPyBfaW52ZXJ0RWFzZShlYXNlKSA6IGVhc2U7XG4gICAgfVxuXG4gICAgbCA9IChkaXN0YW5jZXNbaV0gLSBkaXN0YW5jZXMubWluKSAvIGRpc3RhbmNlcy5tYXggfHwgMDtcbiAgICByZXR1cm4gX3JvdW5kUHJlY2lzZShkaXN0YW5jZXMuYiArIChlYXNlID8gZWFzZShsKSA6IGwpICogZGlzdGFuY2VzLnYpICsgZGlzdGFuY2VzLnU7IC8vcm91bmQgaW4gb3JkZXIgdG8gd29yayBhcm91bmQgZmxvYXRpbmcgcG9pbnQgZXJyb3JzXG4gIH07XG59LFxuICAgIF9yb3VuZE1vZGlmaWVyID0gZnVuY3Rpb24gX3JvdW5kTW9kaWZpZXIodikge1xuICAvL3Bhc3MgaW4gMC4xIGdldCBhIGZ1bmN0aW9uIHRoYXQnbGwgcm91bmQgdG8gdGhlIG5lYXJlc3QgdGVudGgsIG9yIDUgdG8gcm91bmQgdG8gdGhlIGNsb3Nlc3QgNSwgb3IgMC4wMDEgdG8gdGhlIGNsb3Nlc3QgMTAwMHRoLCBldGMuXG4gIHZhciBwID0gTWF0aC5wb3coMTAsICgodiArIFwiXCIpLnNwbGl0KFwiLlwiKVsxXSB8fCBcIlwiKS5sZW5ndGgpOyAvL3RvIGF2b2lkIGZsb2F0aW5nIHBvaW50IG1hdGggZXJyb3JzIChsaWtlIDI0ICogMC4xID09IDIuNDAwMDAwMDAwMDAwMDAwNCksIHdlIGNob3Agb2ZmIGF0IGEgc3BlY2lmaWMgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIChtdWNoIGZhc3RlciB0aGFuIHRvRml4ZWQoKSlcblxuICByZXR1cm4gZnVuY3Rpb24gKHJhdykge1xuICAgIHZhciBuID0gX3JvdW5kUHJlY2lzZShNYXRoLnJvdW5kKHBhcnNlRmxvYXQocmF3KSAvIHYpICogdiAqIHApO1xuXG4gICAgcmV0dXJuIChuIC0gbiAlIDEpIC8gcCArIChfaXNOdW1iZXIocmF3KSA/IDAgOiBnZXRVbml0KHJhdykpOyAvLyBuIC0gbiAlIDEgcmVwbGFjZXMgTWF0aC5mbG9vcigpIGluIG9yZGVyIHRvIGhhbmRsZSBuZWdhdGl2ZSB2YWx1ZXMgcHJvcGVybHkuIEZvciBleGFtcGxlLCBNYXRoLmZsb29yKC0xNTAuMDAwMDAwMDAwMDAwMDMpIGlzIDE1MSFcbiAgfTtcbn0sXG4gICAgc25hcCA9IGZ1bmN0aW9uIHNuYXAoc25hcFRvLCB2YWx1ZSkge1xuICB2YXIgaXNBcnJheSA9IF9pc0FycmF5KHNuYXBUbyksXG4gICAgICByYWRpdXMsXG4gICAgICBpczJEO1xuXG4gIGlmICghaXNBcnJheSAmJiBfaXNPYmplY3Qoc25hcFRvKSkge1xuICAgIHJhZGl1cyA9IGlzQXJyYXkgPSBzbmFwVG8ucmFkaXVzIHx8IF9iaWdOdW07XG5cbiAgICBpZiAoc25hcFRvLnZhbHVlcykge1xuICAgICAgc25hcFRvID0gdG9BcnJheShzbmFwVG8udmFsdWVzKTtcblxuICAgICAgaWYgKGlzMkQgPSAhX2lzTnVtYmVyKHNuYXBUb1swXSkpIHtcbiAgICAgICAgcmFkaXVzICo9IHJhZGl1czsgLy9wZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gc28gd2UgZG9uJ3QgaGF2ZSB0byBNYXRoLnNxcnQoKSBpbiB0aGUgbG9vcC5cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc25hcFRvID0gX3JvdW5kTW9kaWZpZXIoc25hcFRvLmluY3JlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgIWlzQXJyYXkgPyBfcm91bmRNb2RpZmllcihzbmFwVG8pIDogX2lzRnVuY3Rpb24oc25hcFRvKSA/IGZ1bmN0aW9uIChyYXcpIHtcbiAgICBpczJEID0gc25hcFRvKHJhdyk7XG4gICAgcmV0dXJuIE1hdGguYWJzKGlzMkQgLSByYXcpIDw9IHJhZGl1cyA/IGlzMkQgOiByYXc7XG4gIH0gOiBmdW5jdGlvbiAocmF3KSB7XG4gICAgdmFyIHggPSBwYXJzZUZsb2F0KGlzMkQgPyByYXcueCA6IHJhdyksXG4gICAgICAgIHkgPSBwYXJzZUZsb2F0KGlzMkQgPyByYXcueSA6IDApLFxuICAgICAgICBtaW4gPSBfYmlnTnVtLFxuICAgICAgICBjbG9zZXN0ID0gMCxcbiAgICAgICAgaSA9IHNuYXBUby5sZW5ndGgsXG4gICAgICAgIGR4LFxuICAgICAgICBkeTtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGlmIChpczJEKSB7XG4gICAgICAgIGR4ID0gc25hcFRvW2ldLnggLSB4O1xuICAgICAgICBkeSA9IHNuYXBUb1tpXS55IC0geTtcbiAgICAgICAgZHggPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGR4ID0gTWF0aC5hYnMoc25hcFRvW2ldIC0geCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkeCA8IG1pbikge1xuICAgICAgICBtaW4gPSBkeDtcbiAgICAgICAgY2xvc2VzdCA9IGk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2xvc2VzdCA9ICFyYWRpdXMgfHwgbWluIDw9IHJhZGl1cyA/IHNuYXBUb1tjbG9zZXN0XSA6IHJhdztcbiAgICByZXR1cm4gaXMyRCB8fCBjbG9zZXN0ID09PSByYXcgfHwgX2lzTnVtYmVyKHJhdykgPyBjbG9zZXN0IDogY2xvc2VzdCArIGdldFVuaXQocmF3KTtcbiAgfSk7XG59LFxuICAgIHJhbmRvbSA9IGZ1bmN0aW9uIHJhbmRvbShtaW4sIG1heCwgcm91bmRpbmdJbmNyZW1lbnQsIHJldHVybkZ1bmN0aW9uKSB7XG4gIHJldHVybiBfY29uZGl0aW9uYWxSZXR1cm4oX2lzQXJyYXkobWluKSA/ICFtYXggOiByb3VuZGluZ0luY3JlbWVudCA9PT0gdHJ1ZSA/ICEhKHJvdW5kaW5nSW5jcmVtZW50ID0gMCkgOiAhcmV0dXJuRnVuY3Rpb24sIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2lzQXJyYXkobWluKSA/IG1pblt+fihNYXRoLnJhbmRvbSgpICogbWluLmxlbmd0aCldIDogKHJvdW5kaW5nSW5jcmVtZW50ID0gcm91bmRpbmdJbmNyZW1lbnQgfHwgMWUtNSkgJiYgKHJldHVybkZ1bmN0aW9uID0gcm91bmRpbmdJbmNyZW1lbnQgPCAxID8gTWF0aC5wb3coMTAsIChyb3VuZGluZ0luY3JlbWVudCArIFwiXCIpLmxlbmd0aCAtIDIpIDogMSkgJiYgTWF0aC5mbG9vcihNYXRoLnJvdW5kKChtaW4gLSByb3VuZGluZ0luY3JlbWVudCAvIDIgKyBNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIHJvdW5kaW5nSW5jcmVtZW50ICogLjk5KSkgLyByb3VuZGluZ0luY3JlbWVudCkgKiByb3VuZGluZ0luY3JlbWVudCAqIHJldHVybkZ1bmN0aW9uKSAvIHJldHVybkZ1bmN0aW9uO1xuICB9KTtcbn0sXG4gICAgcGlwZSA9IGZ1bmN0aW9uIHBpcGUoKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBmdW5jdGlvbnMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgZnVuY3Rpb25zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbnMucmVkdWNlKGZ1bmN0aW9uICh2LCBmKSB7XG4gICAgICByZXR1cm4gZih2KTtcbiAgICB9LCB2YWx1ZSk7XG4gIH07XG59LFxuICAgIHVuaXRpemUgPSBmdW5jdGlvbiB1bml0aXplKGZ1bmMsIHVuaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jKHBhcnNlRmxvYXQodmFsdWUpKSArICh1bml0IHx8IGdldFVuaXQodmFsdWUpKTtcbiAgfTtcbn0sXG4gICAgbm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKG1pbiwgbWF4LCB2YWx1ZSkge1xuICByZXR1cm4gbWFwUmFuZ2UobWluLCBtYXgsIDAsIDEsIHZhbHVlKTtcbn0sXG4gICAgX3dyYXBBcnJheSA9IGZ1bmN0aW9uIF93cmFwQXJyYXkoYSwgd3JhcHBlciwgdmFsdWUpIHtcbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgcmV0dXJuIGFbfn53cmFwcGVyKGluZGV4KV07XG4gIH0pO1xufSxcbiAgICB3cmFwID0gZnVuY3Rpb24gd3JhcChtaW4sIG1heCwgdmFsdWUpIHtcbiAgLy8gTk9URTogd3JhcCgpIENBTk5PVCBiZSBhbiBhcnJvdyBmdW5jdGlvbiEgQSB2ZXJ5IG9kZCBjb21waWxpbmcgYnVnIGNhdXNlcyBwcm9ibGVtcyAodW5yZWxhdGVkIHRvIEdTQVApLlxuICB2YXIgcmFuZ2UgPSBtYXggLSBtaW47XG4gIHJldHVybiBfaXNBcnJheShtaW4pID8gX3dyYXBBcnJheShtaW4sIHdyYXAoMCwgbWluLmxlbmd0aCksIG1heCkgOiBfY29uZGl0aW9uYWxSZXR1cm4odmFsdWUsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiAocmFuZ2UgKyAodmFsdWUgLSBtaW4pICUgcmFuZ2UpICUgcmFuZ2UgKyBtaW47XG4gIH0pO1xufSxcbiAgICB3cmFwWW95byA9IGZ1bmN0aW9uIHdyYXBZb3lvKG1pbiwgbWF4LCB2YWx1ZSkge1xuICB2YXIgcmFuZ2UgPSBtYXggLSBtaW4sXG4gICAgICB0b3RhbCA9IHJhbmdlICogMjtcbiAgcmV0dXJuIF9pc0FycmF5KG1pbikgPyBfd3JhcEFycmF5KG1pbiwgd3JhcFlveW8oMCwgbWluLmxlbmd0aCAtIDEpLCBtYXgpIDogX2NvbmRpdGlvbmFsUmV0dXJuKHZhbHVlLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YWx1ZSA9ICh0b3RhbCArICh2YWx1ZSAtIG1pbikgJSB0b3RhbCkgJSB0b3RhbCB8fCAwO1xuICAgIHJldHVybiBtaW4gKyAodmFsdWUgPiByYW5nZSA/IHRvdGFsIC0gdmFsdWUgOiB2YWx1ZSk7XG4gIH0pO1xufSxcbiAgICBfcmVwbGFjZVJhbmRvbSA9IGZ1bmN0aW9uIF9yZXBsYWNlUmFuZG9tKHZhbHVlKSB7XG4gIC8vcmVwbGFjZXMgYWxsIG9jY3VycmVuY2VzIG9mIHJhbmRvbSguLi4pIGluIGEgc3RyaW5nIHdpdGggdGhlIGNhbGN1bGF0ZWQgcmFuZG9tIHZhbHVlLiBjYW4gYmUgYSByYW5nZSBsaWtlIHJhbmRvbSgtMTAwLCAxMDAsIDUpIG9yIGFuIGFycmF5IGxpa2UgcmFuZG9tKFswLCAxMDAsIDUwMF0pXG4gIHZhciBwcmV2ID0gMCxcbiAgICAgIHMgPSBcIlwiLFxuICAgICAgaSxcbiAgICAgIG51bXMsXG4gICAgICBlbmQsXG4gICAgICBpc0FycmF5O1xuXG4gIHdoaWxlICh+KGkgPSB2YWx1ZS5pbmRleE9mKFwicmFuZG9tKFwiLCBwcmV2KSkpIHtcbiAgICBlbmQgPSB2YWx1ZS5pbmRleE9mKFwiKVwiLCBpKTtcbiAgICBpc0FycmF5ID0gdmFsdWUuY2hhckF0KGkgKyA3KSA9PT0gXCJbXCI7XG4gICAgbnVtcyA9IHZhbHVlLnN1YnN0cihpICsgNywgZW5kIC0gaSAtIDcpLm1hdGNoKGlzQXJyYXkgPyBfZGVsaW1pdGVkVmFsdWVFeHAgOiBfc3RyaWN0TnVtRXhwKTtcbiAgICBzICs9IHZhbHVlLnN1YnN0cihwcmV2LCBpIC0gcHJldikgKyByYW5kb20oaXNBcnJheSA/IG51bXMgOiArbnVtc1swXSwgaXNBcnJheSA/IDAgOiArbnVtc1sxXSwgK251bXNbMl0gfHwgMWUtNSk7XG4gICAgcHJldiA9IGVuZCArIDE7XG4gIH1cblxuICByZXR1cm4gcyArIHZhbHVlLnN1YnN0cihwcmV2LCB2YWx1ZS5sZW5ndGggLSBwcmV2KTtcbn0sXG4gICAgbWFwUmFuZ2UgPSBmdW5jdGlvbiBtYXBSYW5nZShpbk1pbiwgaW5NYXgsIG91dE1pbiwgb3V0TWF4LCB2YWx1ZSkge1xuICB2YXIgaW5SYW5nZSA9IGluTWF4IC0gaW5NaW4sXG4gICAgICBvdXRSYW5nZSA9IG91dE1heCAtIG91dE1pbjtcbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIG91dE1pbiArICgodmFsdWUgLSBpbk1pbikgLyBpblJhbmdlICogb3V0UmFuZ2UgfHwgMCk7XG4gIH0pO1xufSxcbiAgICBpbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlKHN0YXJ0LCBlbmQsIHByb2dyZXNzLCBtdXRhdGUpIHtcbiAgdmFyIGZ1bmMgPSBpc05hTihzdGFydCArIGVuZCkgPyAwIDogZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gKDEgLSBwKSAqIHN0YXJ0ICsgcCAqIGVuZDtcbiAgfTtcblxuICBpZiAoIWZ1bmMpIHtcbiAgICB2YXIgaXNTdHJpbmcgPSBfaXNTdHJpbmcoc3RhcnQpLFxuICAgICAgICBtYXN0ZXIgPSB7fSxcbiAgICAgICAgcCxcbiAgICAgICAgaSxcbiAgICAgICAgaW50ZXJwb2xhdG9ycyxcbiAgICAgICAgbCxcbiAgICAgICAgaWw7XG5cbiAgICBwcm9ncmVzcyA9PT0gdHJ1ZSAmJiAobXV0YXRlID0gMSkgJiYgKHByb2dyZXNzID0gbnVsbCk7XG5cbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIHN0YXJ0ID0ge1xuICAgICAgICBwOiBzdGFydFxuICAgICAgfTtcbiAgICAgIGVuZCA9IHtcbiAgICAgICAgcDogZW5kXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoX2lzQXJyYXkoc3RhcnQpICYmICFfaXNBcnJheShlbmQpKSB7XG4gICAgICBpbnRlcnBvbGF0b3JzID0gW107XG4gICAgICBsID0gc3RhcnQubGVuZ3RoO1xuICAgICAgaWwgPSBsIC0gMjtcblxuICAgICAgZm9yIChpID0gMTsgaSA8IGw7IGkrKykge1xuICAgICAgICBpbnRlcnBvbGF0b3JzLnB1c2goaW50ZXJwb2xhdGUoc3RhcnRbaSAtIDFdLCBzdGFydFtpXSkpOyAvL2J1aWxkIHRoZSBpbnRlcnBvbGF0b3JzIHVwIGZyb250IGFzIGEgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIHNvIHRoYXQgd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIG1hbnkgdGltZXMsIGl0IGNhbiBqdXN0IHJldXNlIHRoZW0uXG4gICAgICB9XG5cbiAgICAgIGwtLTtcblxuICAgICAgZnVuYyA9IGZ1bmN0aW9uIGZ1bmMocCkge1xuICAgICAgICBwICo9IGw7XG4gICAgICAgIHZhciBpID0gTWF0aC5taW4oaWwsIH5+cCk7XG4gICAgICAgIHJldHVybiBpbnRlcnBvbGF0b3JzW2ldKHAgLSBpKTtcbiAgICAgIH07XG5cbiAgICAgIHByb2dyZXNzID0gZW5kO1xuICAgIH0gZWxzZSBpZiAoIW11dGF0ZSkge1xuICAgICAgc3RhcnQgPSBfbWVyZ2UoX2lzQXJyYXkoc3RhcnQpID8gW10gOiB7fSwgc3RhcnQpO1xuICAgIH1cblxuICAgIGlmICghaW50ZXJwb2xhdG9ycykge1xuICAgICAgZm9yIChwIGluIGVuZCkge1xuICAgICAgICBfYWRkUHJvcFR3ZWVuLmNhbGwobWFzdGVyLCBzdGFydCwgcCwgXCJnZXRcIiwgZW5kW3BdKTtcbiAgICAgIH1cblxuICAgICAgZnVuYyA9IGZ1bmN0aW9uIGZ1bmMocCkge1xuICAgICAgICByZXR1cm4gX3JlbmRlclByb3BUd2VlbnMocCwgbWFzdGVyKSB8fCAoaXNTdHJpbmcgPyBzdGFydC5wIDogc3RhcnQpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gX2NvbmRpdGlvbmFsUmV0dXJuKHByb2dyZXNzLCBmdW5jKTtcbn0sXG4gICAgX2dldExhYmVsSW5EaXJlY3Rpb24gPSBmdW5jdGlvbiBfZ2V0TGFiZWxJbkRpcmVjdGlvbih0aW1lbGluZSwgZnJvbVRpbWUsIGJhY2t3YXJkKSB7XG4gIC8vdXNlZCBmb3IgbmV4dExhYmVsKCkgYW5kIHByZXZpb3VzTGFiZWwoKVxuICB2YXIgbGFiZWxzID0gdGltZWxpbmUubGFiZWxzLFxuICAgICAgbWluID0gX2JpZ051bSxcbiAgICAgIHAsXG4gICAgICBkaXN0YW5jZSxcbiAgICAgIGxhYmVsO1xuXG4gIGZvciAocCBpbiBsYWJlbHMpIHtcbiAgICBkaXN0YW5jZSA9IGxhYmVsc1twXSAtIGZyb21UaW1lO1xuXG4gICAgaWYgKGRpc3RhbmNlIDwgMCA9PT0gISFiYWNrd2FyZCAmJiBkaXN0YW5jZSAmJiBtaW4gPiAoZGlzdGFuY2UgPSBNYXRoLmFicyhkaXN0YW5jZSkpKSB7XG4gICAgICBsYWJlbCA9IHA7XG4gICAgICBtaW4gPSBkaXN0YW5jZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbGFiZWw7XG59LFxuICAgIF9jYWxsYmFjayA9IGZ1bmN0aW9uIF9jYWxsYmFjayhhbmltYXRpb24sIHR5cGUsIGV4ZWN1dGVMYXp5Rmlyc3QpIHtcbiAgdmFyIHYgPSBhbmltYXRpb24udmFycyxcbiAgICAgIGNhbGxiYWNrID0gdlt0eXBlXSxcbiAgICAgIHByZXZDb250ZXh0ID0gX2NvbnRleHQsXG4gICAgICBjb250ZXh0ID0gYW5pbWF0aW9uLl9jdHgsXG4gICAgICBwYXJhbXMsXG4gICAgICBzY29wZSxcbiAgICAgIHJlc3VsdDtcblxuICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcGFyYW1zID0gdlt0eXBlICsgXCJQYXJhbXNcIl07XG4gIHNjb3BlID0gdi5jYWxsYmFja1Njb3BlIHx8IGFuaW1hdGlvbjtcbiAgZXhlY3V0ZUxhenlGaXJzdCAmJiBfbGF6eVR3ZWVucy5sZW5ndGggJiYgX2xhenlSZW5kZXIoKTsgLy9pbiBjYXNlIHJlbmRlcmluZyBjYXVzZWQgYW55IHR3ZWVucyB0byBsYXp5LWluaXQsIHdlIHNob3VsZCByZW5kZXIgdGhlbSBiZWNhdXNlIHR5cGljYWxseSB3aGVuIGEgdGltZWxpbmUgZmluaXNoZXMsIHVzZXJzIGV4cGVjdCB0aGluZ3MgdG8gaGF2ZSByZW5kZXJlZCBmdWxseS4gSW1hZ2luZSBhbiBvblVwZGF0ZSBvbiBhIHRpbWVsaW5lIHRoYXQgcmVwb3J0cy9jaGVja3MgdHdlZW5lZCB2YWx1ZXMuXG5cbiAgY29udGV4dCAmJiAoX2NvbnRleHQgPSBjb250ZXh0KTtcbiAgcmVzdWx0ID0gcGFyYW1zID8gY2FsbGJhY2suYXBwbHkoc2NvcGUsIHBhcmFtcykgOiBjYWxsYmFjay5jYWxsKHNjb3BlKTtcbiAgX2NvbnRleHQgPSBwcmV2Q29udGV4dDtcbiAgcmV0dXJuIHJlc3VsdDtcbn0sXG4gICAgX2ludGVycnVwdCA9IGZ1bmN0aW9uIF9pbnRlcnJ1cHQoYW5pbWF0aW9uKSB7XG4gIF9yZW1vdmVGcm9tUGFyZW50KGFuaW1hdGlvbik7XG5cbiAgYW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIgJiYgYW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIua2lsbCghIV9yZXZlcnRpbmcpO1xuICBhbmltYXRpb24ucHJvZ3Jlc3MoKSA8IDEgJiYgX2NhbGxiYWNrKGFuaW1hdGlvbiwgXCJvbkludGVycnVwdFwiKTtcbiAgcmV0dXJuIGFuaW1hdGlvbjtcbn0sXG4gICAgX3F1aWNrVHdlZW4sXG4gICAgX3JlZ2lzdGVyUGx1Z2luUXVldWUgPSBbXSxcbiAgICBfY3JlYXRlUGx1Z2luID0gZnVuY3Rpb24gX2NyZWF0ZVBsdWdpbihjb25maWcpIHtcbiAgaWYgKCFfd2luZG93RXhpc3RzKCkpIHtcbiAgICBfcmVnaXN0ZXJQbHVnaW5RdWV1ZS5wdXNoKGNvbmZpZyk7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25maWcgPSAhY29uZmlnLm5hbWUgJiYgY29uZmlnW1wiZGVmYXVsdFwiXSB8fCBjb25maWc7IC8vVU1EIHBhY2thZ2luZyB3cmFwcyB0aGluZ3Mgb2RkbHksIHNvIGZvciBleGFtcGxlIE1vdGlvblBhdGhIZWxwZXIgYmVjb21lcyB7TW90aW9uUGF0aEhlbHBlcjpNb3Rpb25QYXRoSGVscGVyLCBkZWZhdWx0Ok1vdGlvblBhdGhIZWxwZXJ9LlxuXG4gIHZhciBuYW1lID0gY29uZmlnLm5hbWUsXG4gICAgICBpc0Z1bmMgPSBfaXNGdW5jdGlvbihjb25maWcpLFxuICAgICAgUGx1Z2luID0gbmFtZSAmJiAhaXNGdW5jICYmIGNvbmZpZy5pbml0ID8gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX3Byb3BzID0gW107XG4gIH0gOiBjb25maWcsXG4gICAgICAvL2luIGNhc2Ugc29tZW9uZSBwYXNzZXMgaW4gYW4gb2JqZWN0IHRoYXQncyBub3QgYSBwbHVnaW4sIGxpa2UgQ3VzdG9tRWFzZVxuICBpbnN0YW5jZURlZmF1bHRzID0ge1xuICAgIGluaXQ6IF9lbXB0eUZ1bmMsXG4gICAgcmVuZGVyOiBfcmVuZGVyUHJvcFR3ZWVucyxcbiAgICBhZGQ6IF9hZGRQcm9wVHdlZW4sXG4gICAga2lsbDogX2tpbGxQcm9wVHdlZW5zT2YsXG4gICAgbW9kaWZpZXI6IF9hZGRQbHVnaW5Nb2RpZmllcixcbiAgICByYXdWYXJzOiAwXG4gIH0sXG4gICAgICBzdGF0aWNzID0ge1xuICAgIHRhcmdldFRlc3Q6IDAsXG4gICAgZ2V0OiAwLFxuICAgIGdldFNldHRlcjogX2dldFNldHRlcixcbiAgICBhbGlhc2VzOiB7fSxcbiAgICByZWdpc3RlcjogMFxuICB9O1xuXG4gIF93YWtlKCk7XG5cbiAgaWYgKGNvbmZpZyAhPT0gUGx1Z2luKSB7XG4gICAgaWYgKF9wbHVnaW5zW25hbWVdKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgX3NldERlZmF1bHRzKFBsdWdpbiwgX3NldERlZmF1bHRzKF9jb3B5RXhjbHVkaW5nKGNvbmZpZywgaW5zdGFuY2VEZWZhdWx0cyksIHN0YXRpY3MpKTsgLy9zdGF0aWMgbWV0aG9kc1xuXG5cbiAgICBfbWVyZ2UoUGx1Z2luLnByb3RvdHlwZSwgX21lcmdlKGluc3RhbmNlRGVmYXVsdHMsIF9jb3B5RXhjbHVkaW5nKGNvbmZpZywgc3RhdGljcykpKTsgLy9pbnN0YW5jZSBtZXRob2RzXG5cblxuICAgIF9wbHVnaW5zW1BsdWdpbi5wcm9wID0gbmFtZV0gPSBQbHVnaW47XG5cbiAgICBpZiAoY29uZmlnLnRhcmdldFRlc3QpIHtcbiAgICAgIF9oYXJuZXNzUGx1Z2lucy5wdXNoKFBsdWdpbik7XG5cbiAgICAgIF9yZXNlcnZlZFByb3BzW25hbWVdID0gMTtcbiAgICB9XG5cbiAgICBuYW1lID0gKG5hbWUgPT09IFwiY3NzXCIgPyBcIkNTU1wiIDogbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc3Vic3RyKDEpKSArIFwiUGx1Z2luXCI7IC8vZm9yIHRoZSBnbG9iYWwgbmFtZS4gXCJtb3Rpb25QYXRoXCIgc2hvdWxkIGJlY29tZSBNb3Rpb25QYXRoUGx1Z2luXG4gIH1cblxuICBfYWRkR2xvYmFsKG5hbWUsIFBsdWdpbik7XG5cbiAgY29uZmlnLnJlZ2lzdGVyICYmIGNvbmZpZy5yZWdpc3Rlcihnc2FwLCBQbHVnaW4sIFByb3BUd2Vlbik7XG59LFxuXG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENPTE9SU1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXzI1NSA9IDI1NSxcbiAgICBfY29sb3JMb29rdXAgPSB7XG4gIGFxdWE6IFswLCBfMjU1LCBfMjU1XSxcbiAgbGltZTogWzAsIF8yNTUsIDBdLFxuICBzaWx2ZXI6IFsxOTIsIDE5MiwgMTkyXSxcbiAgYmxhY2s6IFswLCAwLCAwXSxcbiAgbWFyb29uOiBbMTI4LCAwLCAwXSxcbiAgdGVhbDogWzAsIDEyOCwgMTI4XSxcbiAgYmx1ZTogWzAsIDAsIF8yNTVdLFxuICBuYXZ5OiBbMCwgMCwgMTI4XSxcbiAgd2hpdGU6IFtfMjU1LCBfMjU1LCBfMjU1XSxcbiAgb2xpdmU6IFsxMjgsIDEyOCwgMF0sXG4gIHllbGxvdzogW18yNTUsIF8yNTUsIDBdLFxuICBvcmFuZ2U6IFtfMjU1LCAxNjUsIDBdLFxuICBncmF5OiBbMTI4LCAxMjgsIDEyOF0sXG4gIHB1cnBsZTogWzEyOCwgMCwgMTI4XSxcbiAgZ3JlZW46IFswLCAxMjgsIDBdLFxuICByZWQ6IFtfMjU1LCAwLCAwXSxcbiAgcGluazogW18yNTUsIDE5MiwgMjAzXSxcbiAgY3lhbjogWzAsIF8yNTUsIF8yNTVdLFxuICB0cmFuc3BhcmVudDogW18yNTUsIF8yNTUsIF8yNTUsIDBdXG59LFxuICAgIC8vIHBvc3NpYmxlIGZ1dHVyZSBpZGVhIHRvIHJlcGxhY2UgdGhlIGhhcmQtY29kZWQgY29sb3IgbmFtZSB2YWx1ZXMgLSBwdXQgdGhpcyBpbiB0aGUgdGlja2VyLndha2UoKSB3aGVyZSB3ZSBzZXQgdGhlIF9kb2M6XG4vLyBsZXQgY3R4ID0gX2RvYy5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpLmdldENvbnRleHQoXCIyZFwiKTtcbi8vIF9mb3JFYWNoTmFtZShcImFxdWEsbGltZSxzaWx2ZXIsYmxhY2ssbWFyb29uLHRlYWwsYmx1ZSxuYXZ5LHdoaXRlLG9saXZlLHllbGxvdyxvcmFuZ2UsZ3JheSxwdXJwbGUsZ3JlZW4scmVkLHBpbmssY3lhblwiLCBjb2xvciA9PiB7Y3R4LmZpbGxTdHlsZSA9IGNvbG9yOyBfY29sb3JMb29rdXBbY29sb3JdID0gc3BsaXRDb2xvcihjdHguZmlsbFN0eWxlKX0pO1xuX2h1ZSA9IGZ1bmN0aW9uIF9odWUoaCwgbTEsIG0yKSB7XG4gIGggKz0gaCA8IDAgPyAxIDogaCA+IDEgPyAtMSA6IDA7XG4gIHJldHVybiAoaCAqIDYgPCAxID8gbTEgKyAobTIgLSBtMSkgKiBoICogNiA6IGggPCAuNSA/IG0yIDogaCAqIDMgPCAyID8gbTEgKyAobTIgLSBtMSkgKiAoMiAvIDMgLSBoKSAqIDYgOiBtMSkgKiBfMjU1ICsgLjUgfCAwO1xufSxcbiAgICBzcGxpdENvbG9yID0gZnVuY3Rpb24gc3BsaXRDb2xvcih2LCB0b0hTTCwgZm9yY2VBbHBoYSkge1xuICB2YXIgYSA9ICF2ID8gX2NvbG9yTG9va3VwLmJsYWNrIDogX2lzTnVtYmVyKHYpID8gW3YgPj4gMTYsIHYgPj4gOCAmIF8yNTUsIHYgJiBfMjU1XSA6IDAsXG4gICAgICByLFxuICAgICAgZyxcbiAgICAgIGIsXG4gICAgICBoLFxuICAgICAgcyxcbiAgICAgIGwsXG4gICAgICBtYXgsXG4gICAgICBtaW4sXG4gICAgICBkLFxuICAgICAgd2FzSFNMO1xuXG4gIGlmICghYSkge1xuICAgIGlmICh2LnN1YnN0cigtMSkgPT09IFwiLFwiKSB7XG4gICAgICAvL3NvbWV0aW1lcyBhIHRyYWlsaW5nIGNvbW1hIGlzIGluY2x1ZGVkIGFuZCB3ZSBzaG91bGQgY2hvcCBpdCBvZmYgKHR5cGljYWxseSBmcm9tIGEgY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgdmFsdWVzIGxpa2UgYSB0ZXh0U2hhZG93OlwiMnB4IDJweCAycHggYmx1ZSwgNXB4IDVweCA1cHggcmdiKDI1NSwwLDApXCIgLSBpbiB0aGlzIGV4YW1wbGUgXCJibHVlLFwiIGhhcyBhIHRyYWlsaW5nIGNvbW1hLiBXZSBjb3VsZCBzdHJpcCBpdCBvdXQgaW5zaWRlIHBhcnNlQ29tcGxleCgpIGJ1dCB3ZSdkIG5lZWQgdG8gZG8gaXQgdG8gdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIHZhbHVlcyBwbHVzIGl0IHdvdWxkbid0IHByb3ZpZGUgcHJvdGVjdGlvbiBmcm9tIG90aGVyIHBvdGVudGlhbCBzY2VuYXJpb3MgbGlrZSBpZiB0aGUgdXNlciBwYXNzZXMgaW4gYSBzaW1pbGFyIHZhbHVlLlxuICAgICAgdiA9IHYuc3Vic3RyKDAsIHYubGVuZ3RoIC0gMSk7XG4gICAgfVxuXG4gICAgaWYgKF9jb2xvckxvb2t1cFt2XSkge1xuICAgICAgYSA9IF9jb2xvckxvb2t1cFt2XTtcbiAgICB9IGVsc2UgaWYgKHYuY2hhckF0KDApID09PSBcIiNcIikge1xuICAgICAgaWYgKHYubGVuZ3RoIDwgNikge1xuICAgICAgICAvL2ZvciBzaG9ydGhhbmQgbGlrZSAjOUYwIG9yICM5RjBGIChjb3VsZCBoYXZlIGFscGhhKVxuICAgICAgICByID0gdi5jaGFyQXQoMSk7XG4gICAgICAgIGcgPSB2LmNoYXJBdCgyKTtcbiAgICAgICAgYiA9IHYuY2hhckF0KDMpO1xuICAgICAgICB2ID0gXCIjXCIgKyByICsgciArIGcgKyBnICsgYiArIGIgKyAodi5sZW5ndGggPT09IDUgPyB2LmNoYXJBdCg0KSArIHYuY2hhckF0KDQpIDogXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmICh2Lmxlbmd0aCA9PT0gOSkge1xuICAgICAgICAvLyBoZXggd2l0aCBhbHBoYSwgbGlrZSAjZmQ1ZTUzZmZcbiAgICAgICAgYSA9IHBhcnNlSW50KHYuc3Vic3RyKDEsIDYpLCAxNik7XG4gICAgICAgIHJldHVybiBbYSA+PiAxNiwgYSA+PiA4ICYgXzI1NSwgYSAmIF8yNTUsIHBhcnNlSW50KHYuc3Vic3RyKDcpLCAxNikgLyAyNTVdO1xuICAgICAgfVxuXG4gICAgICB2ID0gcGFyc2VJbnQodi5zdWJzdHIoMSksIDE2KTtcbiAgICAgIGEgPSBbdiA+PiAxNiwgdiA+PiA4ICYgXzI1NSwgdiAmIF8yNTVdO1xuICAgIH0gZWxzZSBpZiAodi5zdWJzdHIoMCwgMykgPT09IFwiaHNsXCIpIHtcbiAgICAgIGEgPSB3YXNIU0wgPSB2Lm1hdGNoKF9zdHJpY3ROdW1FeHApO1xuXG4gICAgICBpZiAoIXRvSFNMKSB7XG4gICAgICAgIGggPSArYVswXSAlIDM2MCAvIDM2MDtcbiAgICAgICAgcyA9ICthWzFdIC8gMTAwO1xuICAgICAgICBsID0gK2FbMl0gLyAxMDA7XG4gICAgICAgIGcgPSBsIDw9IC41ID8gbCAqIChzICsgMSkgOiBsICsgcyAtIGwgKiBzO1xuICAgICAgICByID0gbCAqIDIgLSBnO1xuICAgICAgICBhLmxlbmd0aCA+IDMgJiYgKGFbM10gKj0gMSk7IC8vY2FzdCBhcyBudW1iZXJcblxuICAgICAgICBhWzBdID0gX2h1ZShoICsgMSAvIDMsIHIsIGcpO1xuICAgICAgICBhWzFdID0gX2h1ZShoLCByLCBnKTtcbiAgICAgICAgYVsyXSA9IF9odWUoaCAtIDEgLyAzLCByLCBnKTtcbiAgICAgIH0gZWxzZSBpZiAofnYuaW5kZXhPZihcIj1cIikpIHtcbiAgICAgICAgLy9pZiByZWxhdGl2ZSB2YWx1ZXMgYXJlIGZvdW5kLCBqdXN0IHJldHVybiB0aGUgcmF3IHN0cmluZ3Mgd2l0aCB0aGUgcmVsYXRpdmUgcHJlZml4ZXMgaW4gcGxhY2UuXG4gICAgICAgIGEgPSB2Lm1hdGNoKF9udW1FeHApO1xuICAgICAgICBmb3JjZUFscGhhICYmIGEubGVuZ3RoIDwgNCAmJiAoYVszXSA9IDEpO1xuICAgICAgICByZXR1cm4gYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IHYubWF0Y2goX3N0cmljdE51bUV4cCkgfHwgX2NvbG9yTG9va3VwLnRyYW5zcGFyZW50O1xuICAgIH1cblxuICAgIGEgPSBhLm1hcChOdW1iZXIpO1xuICB9XG5cbiAgaWYgKHRvSFNMICYmICF3YXNIU0wpIHtcbiAgICByID0gYVswXSAvIF8yNTU7XG4gICAgZyA9IGFbMV0gLyBfMjU1O1xuICAgIGIgPSBhWzJdIC8gXzI1NTtcbiAgICBtYXggPSBNYXRoLm1heChyLCBnLCBiKTtcbiAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKTtcbiAgICBsID0gKG1heCArIG1pbikgLyAyO1xuXG4gICAgaWYgKG1heCA9PT0gbWluKSB7XG4gICAgICBoID0gcyA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGQgPSBtYXggLSBtaW47XG4gICAgICBzID0gbCA+IDAuNSA/IGQgLyAoMiAtIG1heCAtIG1pbikgOiBkIC8gKG1heCArIG1pbik7XG4gICAgICBoID0gbWF4ID09PSByID8gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCkgOiBtYXggPT09IGcgPyAoYiAtIHIpIC8gZCArIDIgOiAociAtIGcpIC8gZCArIDQ7XG4gICAgICBoICo9IDYwO1xuICAgIH1cblxuICAgIGFbMF0gPSB+fihoICsgLjUpO1xuICAgIGFbMV0gPSB+fihzICogMTAwICsgLjUpO1xuICAgIGFbMl0gPSB+fihsICogMTAwICsgLjUpO1xuICB9XG5cbiAgZm9yY2VBbHBoYSAmJiBhLmxlbmd0aCA8IDQgJiYgKGFbM10gPSAxKTtcbiAgcmV0dXJuIGE7XG59LFxuICAgIF9jb2xvck9yZGVyRGF0YSA9IGZ1bmN0aW9uIF9jb2xvck9yZGVyRGF0YSh2KSB7XG4gIC8vIHN0cmlwcyBvdXQgdGhlIGNvbG9ycyBmcm9tIHRoZSBzdHJpbmcsIGZpbmRzIGFsbCB0aGUgbnVtZXJpYyBzbG90cyAod2l0aCB1bml0cykgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhvc2UuIFRoZSBBcnJheSBhbHNvIGhhcyBhIFwiY1wiIHByb3BlcnR5IHdoaWNoIGlzIGFuIEFycmF5IG9mIHRoZSBpbmRleCB2YWx1ZXMgd2hlcmUgdGhlIGNvbG9ycyBiZWxvbmcuIFRoaXMgaXMgdG8gaGVscCB3b3JrIGFyb3VuZCBpc3N1ZXMgd2hlcmUgdGhlcmUncyBhIG1pcy1tYXRjaGVkIG9yZGVyIG9mIGNvbG9yL251bWVyaWMgZGF0YSBsaWtlIGRyb3Atc2hhZG93KCNmMDAgMHB4IDFweCAycHgpIGFuZCBkcm9wLXNoYWRvdygweCAxcHggMnB4ICNmMDApLiBUaGlzIGlzIGJhc2ljYWxseSBhIGhlbHBlciBmdW5jdGlvbiB1c2VkIGluIF9mb3JtYXRDb2xvcnMoKVxuICB2YXIgdmFsdWVzID0gW10sXG4gICAgICBjID0gW10sXG4gICAgICBpID0gLTE7XG4gIHYuc3BsaXQoX2NvbG9yRXhwKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgdmFyIGEgPSB2Lm1hdGNoKF9udW1XaXRoVW5pdEV4cCkgfHwgW107XG4gICAgdmFsdWVzLnB1c2guYXBwbHkodmFsdWVzLCBhKTtcbiAgICBjLnB1c2goaSArPSBhLmxlbmd0aCArIDEpO1xuICB9KTtcbiAgdmFsdWVzLmMgPSBjO1xuICByZXR1cm4gdmFsdWVzO1xufSxcbiAgICBfZm9ybWF0Q29sb3JzID0gZnVuY3Rpb24gX2Zvcm1hdENvbG9ycyhzLCB0b0hTTCwgb3JkZXJNYXRjaERhdGEpIHtcbiAgdmFyIHJlc3VsdCA9IFwiXCIsXG4gICAgICBjb2xvcnMgPSAocyArIHJlc3VsdCkubWF0Y2goX2NvbG9yRXhwKSxcbiAgICAgIHR5cGUgPSB0b0hTTCA/IFwiaHNsYShcIiA6IFwicmdiYShcIixcbiAgICAgIGkgPSAwLFxuICAgICAgYyxcbiAgICAgIHNoZWxsLFxuICAgICAgZCxcbiAgICAgIGw7XG5cbiAgaWYgKCFjb2xvcnMpIHtcbiAgICByZXR1cm4gcztcbiAgfVxuXG4gIGNvbG9ycyA9IGNvbG9ycy5tYXAoZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgcmV0dXJuIChjb2xvciA9IHNwbGl0Q29sb3IoY29sb3IsIHRvSFNMLCAxKSkgJiYgdHlwZSArICh0b0hTTCA/IGNvbG9yWzBdICsgXCIsXCIgKyBjb2xvclsxXSArIFwiJSxcIiArIGNvbG9yWzJdICsgXCIlLFwiICsgY29sb3JbM10gOiBjb2xvci5qb2luKFwiLFwiKSkgKyBcIilcIjtcbiAgfSk7XG5cbiAgaWYgKG9yZGVyTWF0Y2hEYXRhKSB7XG4gICAgZCA9IF9jb2xvck9yZGVyRGF0YShzKTtcbiAgICBjID0gb3JkZXJNYXRjaERhdGEuYztcblxuICAgIGlmIChjLmpvaW4ocmVzdWx0KSAhPT0gZC5jLmpvaW4ocmVzdWx0KSkge1xuICAgICAgc2hlbGwgPSBzLnJlcGxhY2UoX2NvbG9yRXhwLCBcIjFcIikuc3BsaXQoX251bVdpdGhVbml0RXhwKTtcbiAgICAgIGwgPSBzaGVsbC5sZW5ndGggLSAxO1xuXG4gICAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgICByZXN1bHQgKz0gc2hlbGxbaV0gKyAofmMuaW5kZXhPZihpKSA/IGNvbG9ycy5zaGlmdCgpIHx8IHR5cGUgKyBcIjAsMCwwLDApXCIgOiAoZC5sZW5ndGggPyBkIDogY29sb3JzLmxlbmd0aCA/IGNvbG9ycyA6IG9yZGVyTWF0Y2hEYXRhKS5zaGlmdCgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIXNoZWxsKSB7XG4gICAgc2hlbGwgPSBzLnNwbGl0KF9jb2xvckV4cCk7XG4gICAgbCA9IHNoZWxsLmxlbmd0aCAtIDE7XG5cbiAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgcmVzdWx0ICs9IHNoZWxsW2ldICsgY29sb3JzW2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQgKyBzaGVsbFtsXTtcbn0sXG4gICAgX2NvbG9yRXhwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcyA9IFwiKD86XFxcXGIoPzooPzpyZ2J8cmdiYXxoc2x8aHNsYSlcXFxcKC4rP1xcXFwpKXxcXFxcQiMoPzpbMC05YS1mXXszLDR9KXsxLDJ9XFxcXGJcIixcbiAgICAgIC8vd2UnbGwgZHluYW1pY2FsbHkgYnVpbGQgdGhpcyBSZWd1bGFyIEV4cHJlc3Npb24gdG8gY29uc2VydmUgZmlsZSBzaXplLiBBZnRlciBidWlsZGluZyBpdCwgaXQgd2lsbCBiZSBhYmxlIHRvIGZpbmQgcmdiKCksIHJnYmEoKSwgIyAoaGV4YWRlY2ltYWwpLCBhbmQgbmFtZWQgY29sb3IgdmFsdWVzIGxpa2UgcmVkLCBibHVlLCBwdXJwbGUsIGV0Yy4sXG4gIHA7XG5cbiAgZm9yIChwIGluIF9jb2xvckxvb2t1cCkge1xuICAgIHMgKz0gXCJ8XCIgKyBwICsgXCJcXFxcYlwiO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWdFeHAocyArIFwiKVwiLCBcImdpXCIpO1xufSgpLFxuICAgIF9oc2xFeHAgPSAvaHNsW2FdP1xcKC8sXG4gICAgX2NvbG9yU3RyaW5nRmlsdGVyID0gZnVuY3Rpb24gX2NvbG9yU3RyaW5nRmlsdGVyKGEpIHtcbiAgdmFyIGNvbWJpbmVkID0gYS5qb2luKFwiIFwiKSxcbiAgICAgIHRvSFNMO1xuICBfY29sb3JFeHAubGFzdEluZGV4ID0gMDtcblxuICBpZiAoX2NvbG9yRXhwLnRlc3QoY29tYmluZWQpKSB7XG4gICAgdG9IU0wgPSBfaHNsRXhwLnRlc3QoY29tYmluZWQpO1xuICAgIGFbMV0gPSBfZm9ybWF0Q29sb3JzKGFbMV0sIHRvSFNMKTtcbiAgICBhWzBdID0gX2Zvcm1hdENvbG9ycyhhWzBdLCB0b0hTTCwgX2NvbG9yT3JkZXJEYXRhKGFbMV0pKTsgLy8gbWFrZSBzdXJlIHRoZSBvcmRlciBvZiBudW1iZXJzL2NvbG9ycyBtYXRjaCB3aXRoIHRoZSBFTkQgdmFsdWUuXG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufSxcblxuLypcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBUSUNLRVJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cbl90aWNrZXJBY3RpdmUsXG4gICAgX3RpY2tlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9nZXRUaW1lID0gRGF0ZS5ub3csXG4gICAgICBfbGFnVGhyZXNob2xkID0gNTAwLFxuICAgICAgX2FkanVzdGVkTGFnID0gMzMsXG4gICAgICBfc3RhcnRUaW1lID0gX2dldFRpbWUoKSxcbiAgICAgIF9sYXN0VXBkYXRlID0gX3N0YXJ0VGltZSxcbiAgICAgIF9nYXAgPSAxMDAwIC8gMjQwLFxuICAgICAgX25leHRUaW1lID0gX2dhcCxcbiAgICAgIF9saXN0ZW5lcnMgPSBbXSxcbiAgICAgIF9pZCxcbiAgICAgIF9yZXEsXG4gICAgICBfcmFmLFxuICAgICAgX3NlbGYsXG4gICAgICBfZGVsdGEsXG4gICAgICBfaSxcbiAgICAgIF90aWNrID0gZnVuY3Rpb24gX3RpY2sodikge1xuICAgIHZhciBlbGFwc2VkID0gX2dldFRpbWUoKSAtIF9sYXN0VXBkYXRlLFxuICAgICAgICBtYW51YWwgPSB2ID09PSB0cnVlLFxuICAgICAgICBvdmVybGFwLFxuICAgICAgICBkaXNwYXRjaCxcbiAgICAgICAgdGltZSxcbiAgICAgICAgZnJhbWU7XG5cbiAgICBlbGFwc2VkID4gX2xhZ1RocmVzaG9sZCAmJiAoX3N0YXJ0VGltZSArPSBlbGFwc2VkIC0gX2FkanVzdGVkTGFnKTtcbiAgICBfbGFzdFVwZGF0ZSArPSBlbGFwc2VkO1xuICAgIHRpbWUgPSBfbGFzdFVwZGF0ZSAtIF9zdGFydFRpbWU7XG4gICAgb3ZlcmxhcCA9IHRpbWUgLSBfbmV4dFRpbWU7XG5cbiAgICBpZiAob3ZlcmxhcCA+IDAgfHwgbWFudWFsKSB7XG4gICAgICBmcmFtZSA9ICsrX3NlbGYuZnJhbWU7XG4gICAgICBfZGVsdGEgPSB0aW1lIC0gX3NlbGYudGltZSAqIDEwMDA7XG4gICAgICBfc2VsZi50aW1lID0gdGltZSA9IHRpbWUgLyAxMDAwO1xuICAgICAgX25leHRUaW1lICs9IG92ZXJsYXAgKyAob3ZlcmxhcCA+PSBfZ2FwID8gNCA6IF9nYXAgLSBvdmVybGFwKTtcbiAgICAgIGRpc3BhdGNoID0gMTtcbiAgICB9XG5cbiAgICBtYW51YWwgfHwgKF9pZCA9IF9yZXEoX3RpY2spKTsgLy9tYWtlIHN1cmUgdGhlIHJlcXVlc3QgaXMgbWFkZSBiZWZvcmUgd2UgZGlzcGF0Y2ggdGhlIFwidGlja1wiIGV2ZW50IHNvIHRoYXQgdGltaW5nIGlzIG1haW50YWluZWQuIE90aGVyd2lzZSwgaWYgcHJvY2Vzc2luZyB0aGUgXCJ0aWNrXCIgcmVxdWlyZXMgYSBidW5jaCBvZiB0aW1lIChsaWtlIDE1bXMpIGFuZCB3ZSdyZSB1c2luZyBhIHNldFRpbWVvdXQoKSB0aGF0J3MgYmFzZWQgb24gMTYuN21zLCBpdCdkIHRlY2huaWNhbGx5IHRha2UgMzEuN21zIGJldHdlZW4gZnJhbWVzIG90aGVyd2lzZS5cblxuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgZm9yIChfaSA9IDA7IF9pIDwgX2xpc3RlbmVycy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgLy8gdXNlIF9pIGFuZCBjaGVjayBfbGlzdGVuZXJzLmxlbmd0aCBpbnN0ZWFkIG9mIGEgdmFyaWFibGUgYmVjYXVzZSBhIGxpc3RlbmVyIGNvdWxkIGdldCByZW1vdmVkIGR1cmluZyB0aGUgbG9vcCwgYW5kIGlmIHRoYXQgaGFwcGVucyB0byBhbiBlbGVtZW50IGxlc3MgdGhhbiB0aGUgY3VycmVudCBpbmRleCwgaXQnZCB0aHJvdyB0aGluZ3Mgb2ZmIGluIHRoZSBsb29wLlxuICAgICAgICBfbGlzdGVuZXJzW19pXSh0aW1lLCBfZGVsdGEsIGZyYW1lLCB2KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgX3NlbGYgPSB7XG4gICAgdGltZTogMCxcbiAgICBmcmFtZTogMCxcbiAgICB0aWNrOiBmdW5jdGlvbiB0aWNrKCkge1xuICAgICAgX3RpY2sodHJ1ZSk7XG4gICAgfSxcbiAgICBkZWx0YVJhdGlvOiBmdW5jdGlvbiBkZWx0YVJhdGlvKGZwcykge1xuICAgICAgcmV0dXJuIF9kZWx0YSAvICgxMDAwIC8gKGZwcyB8fCA2MCkpO1xuICAgIH0sXG4gICAgd2FrZTogZnVuY3Rpb24gd2FrZSgpIHtcbiAgICAgIGlmIChfY29yZVJlYWR5KSB7XG4gICAgICAgIGlmICghX2NvcmVJbml0dGVkICYmIF93aW5kb3dFeGlzdHMoKSkge1xuICAgICAgICAgIF93aW4gPSBfY29yZUluaXR0ZWQgPSB3aW5kb3c7XG4gICAgICAgICAgX2RvYyA9IF93aW4uZG9jdW1lbnQgfHwge307XG4gICAgICAgICAgX2dsb2JhbHMuZ3NhcCA9IGdzYXA7XG4gICAgICAgICAgKF93aW4uZ3NhcFZlcnNpb25zIHx8IChfd2luLmdzYXBWZXJzaW9ucyA9IFtdKSkucHVzaChnc2FwLnZlcnNpb24pO1xuXG4gICAgICAgICAgX2luc3RhbGwoX2luc3RhbGxTY29wZSB8fCBfd2luLkdyZWVuU29ja0dsb2JhbHMgfHwgIV93aW4uZ3NhcCAmJiBfd2luIHx8IHt9KTtcblxuICAgICAgICAgIF9yYWYgPSBfd2luLnJlcXVlc3RBbmltYXRpb25GcmFtZTtcblxuICAgICAgICAgIF9yZWdpc3RlclBsdWdpblF1ZXVlLmZvckVhY2goX2NyZWF0ZVBsdWdpbik7XG4gICAgICAgIH1cblxuICAgICAgICBfaWQgJiYgX3NlbGYuc2xlZXAoKTtcblxuICAgICAgICBfcmVxID0gX3JhZiB8fCBmdW5jdGlvbiAoZikge1xuICAgICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGYsIF9uZXh0VGltZSAtIF9zZWxmLnRpbWUgKiAxMDAwICsgMSB8IDApO1xuICAgICAgICB9O1xuXG4gICAgICAgIF90aWNrZXJBY3RpdmUgPSAxO1xuXG4gICAgICAgIF90aWNrKDIpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2xlZXA6IGZ1bmN0aW9uIHNsZWVwKCkge1xuICAgICAgKF9yYWYgPyBfd2luLmNhbmNlbEFuaW1hdGlvbkZyYW1lIDogY2xlYXJUaW1lb3V0KShfaWQpO1xuICAgICAgX3RpY2tlckFjdGl2ZSA9IDA7XG4gICAgICBfcmVxID0gX2VtcHR5RnVuYztcbiAgICB9LFxuICAgIGxhZ1Ntb290aGluZzogZnVuY3Rpb24gbGFnU21vb3RoaW5nKHRocmVzaG9sZCwgYWRqdXN0ZWRMYWcpIHtcbiAgICAgIF9sYWdUaHJlc2hvbGQgPSB0aHJlc2hvbGQgfHwgSW5maW5pdHk7IC8vIHplcm8gc2hvdWxkIGJlIGludGVycHJldGVkIGFzIGJhc2ljYWxseSB1bmxpbWl0ZWRcblxuICAgICAgX2FkanVzdGVkTGFnID0gTWF0aC5taW4oYWRqdXN0ZWRMYWcgfHwgMzMsIF9sYWdUaHJlc2hvbGQpO1xuICAgIH0sXG4gICAgZnBzOiBmdW5jdGlvbiBmcHMoX2Zwcykge1xuICAgICAgX2dhcCA9IDEwMDAgLyAoX2ZwcyB8fCAyNDApO1xuICAgICAgX25leHRUaW1lID0gX3NlbGYudGltZSAqIDEwMDAgKyBfZ2FwO1xuICAgIH0sXG4gICAgYWRkOiBmdW5jdGlvbiBhZGQoY2FsbGJhY2ssIG9uY2UsIHByaW9yaXRpemUpIHtcbiAgICAgIHZhciBmdW5jID0gb25jZSA/IGZ1bmN0aW9uICh0LCBkLCBmLCB2KSB7XG4gICAgICAgIGNhbGxiYWNrKHQsIGQsIGYsIHYpO1xuXG4gICAgICAgIF9zZWxmLnJlbW92ZShmdW5jKTtcbiAgICAgIH0gOiBjYWxsYmFjaztcblxuICAgICAgX3NlbGYucmVtb3ZlKGNhbGxiYWNrKTtcblxuICAgICAgX2xpc3RlbmVyc1twcmlvcml0aXplID8gXCJ1bnNoaWZ0XCIgOiBcInB1c2hcIl0oZnVuYyk7XG5cbiAgICAgIF93YWtlKCk7XG5cbiAgICAgIHJldHVybiBmdW5jO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoY2FsbGJhY2ssIGkpIHtcbiAgICAgIH4oaSA9IF9saXN0ZW5lcnMuaW5kZXhPZihjYWxsYmFjaykpICYmIF9saXN0ZW5lcnMuc3BsaWNlKGksIDEpICYmIF9pID49IGkgJiYgX2ktLTtcbiAgICB9LFxuICAgIF9saXN0ZW5lcnM6IF9saXN0ZW5lcnNcbiAgfTtcbiAgcmV0dXJuIF9zZWxmO1xufSgpLFxuICAgIF93YWtlID0gZnVuY3Rpb24gX3dha2UoKSB7XG4gIHJldHVybiAhX3RpY2tlckFjdGl2ZSAmJiBfdGlja2VyLndha2UoKTtcbn0sXG4gICAgLy9hbHNvIGVuc3VyZXMgdGhlIGNvcmUgY2xhc3NlcyBhcmUgaW5pdGlhbGl6ZWQuXG5cbi8qXG4qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiogRUFTSU5HXG4qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiovXG5fZWFzZU1hcCA9IHt9LFxuICAgIF9jdXN0b21FYXNlRXhwID0gL15bXFxkLlxcLU1dW1xcZC5cXC0sXFxzXS8sXG4gICAgX3F1b3Rlc0V4cCA9IC9bXCInXS9nLFxuICAgIF9wYXJzZU9iamVjdEluU3RyaW5nID0gZnVuY3Rpb24gX3BhcnNlT2JqZWN0SW5TdHJpbmcodmFsdWUpIHtcbiAgLy90YWtlcyBhIHN0cmluZyBsaWtlIFwie3dpZ2dsZXM6MTAsIHR5cGU6YW50aWNpcGF0ZX0pXCIgYW5kIHR1cm5zIGl0IGludG8gYSByZWFsIG9iamVjdC4gTm90aWNlIGl0IGVuZHMgaW4gXCIpXCIgYW5kIGluY2x1ZGVzIHRoZSB7fSB3cmFwcGVycy4gVGhpcyBpcyBiZWNhdXNlIHdlIG9ubHkgdXNlIHRoaXMgZnVuY3Rpb24gZm9yIHBhcnNpbmcgZWFzZSBjb25maWdzIGFuZCBwcmlvcml0aXplZCBvcHRpbWl6YXRpb24gcmF0aGVyIHRoYW4gcmV1c2FiaWxpdHkuXG4gIHZhciBvYmogPSB7fSxcbiAgICAgIHNwbGl0ID0gdmFsdWUuc3Vic3RyKDEsIHZhbHVlLmxlbmd0aCAtIDMpLnNwbGl0KFwiOlwiKSxcbiAgICAgIGtleSA9IHNwbGl0WzBdLFxuICAgICAgaSA9IDEsXG4gICAgICBsID0gc3BsaXQubGVuZ3RoLFxuICAgICAgaW5kZXgsXG4gICAgICB2YWwsXG4gICAgICBwYXJzZWRWYWw7XG5cbiAgZm9yICg7IGkgPCBsOyBpKyspIHtcbiAgICB2YWwgPSBzcGxpdFtpXTtcbiAgICBpbmRleCA9IGkgIT09IGwgLSAxID8gdmFsLmxhc3RJbmRleE9mKFwiLFwiKSA6IHZhbC5sZW5ndGg7XG4gICAgcGFyc2VkVmFsID0gdmFsLnN1YnN0cigwLCBpbmRleCk7XG4gICAgb2JqW2tleV0gPSBpc05hTihwYXJzZWRWYWwpID8gcGFyc2VkVmFsLnJlcGxhY2UoX3F1b3Rlc0V4cCwgXCJcIikudHJpbSgpIDogK3BhcnNlZFZhbDtcbiAgICBrZXkgPSB2YWwuc3Vic3RyKGluZGV4ICsgMSkudHJpbSgpO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn0sXG4gICAgX3ZhbHVlSW5QYXJlbnRoZXNlcyA9IGZ1bmN0aW9uIF92YWx1ZUluUGFyZW50aGVzZXModmFsdWUpIHtcbiAgdmFyIG9wZW4gPSB2YWx1ZS5pbmRleE9mKFwiKFwiKSArIDEsXG4gICAgICBjbG9zZSA9IHZhbHVlLmluZGV4T2YoXCIpXCIpLFxuICAgICAgbmVzdGVkID0gdmFsdWUuaW5kZXhPZihcIihcIiwgb3Blbik7XG4gIHJldHVybiB2YWx1ZS5zdWJzdHJpbmcob3Blbiwgfm5lc3RlZCAmJiBuZXN0ZWQgPCBjbG9zZSA/IHZhbHVlLmluZGV4T2YoXCIpXCIsIGNsb3NlICsgMSkgOiBjbG9zZSk7XG59LFxuICAgIF9jb25maWdFYXNlRnJvbVN0cmluZyA9IGZ1bmN0aW9uIF9jb25maWdFYXNlRnJvbVN0cmluZyhuYW1lKSB7XG4gIC8vbmFtZSBjYW4gYmUgYSBzdHJpbmcgbGlrZSBcImVsYXN0aWMub3V0KDEsMC41KVwiLCBhbmQgcGFzcyBpbiBfZWFzZU1hcCBhcyBvYmogYW5kIGl0J2xsIHBhcnNlIGl0IG91dCBhbmQgY2FsbCB0aGUgYWN0dWFsIGZ1bmN0aW9uIGxpa2UgX2Vhc2VNYXAuRWxhc3RpYy5lYXNlT3V0LmNvbmZpZygxLDAuNSkuIEl0IHdpbGwgYWxzbyBwYXJzZSBjdXN0b20gZWFzZSBzdHJpbmdzIGFzIGxvbmcgYXMgQ3VzdG9tRWFzZSBpcyBsb2FkZWQgYW5kIHJlZ2lzdGVyZWQgKGludGVybmFsbHkgYXMgX2Vhc2VNYXAuX0NFKS5cbiAgdmFyIHNwbGl0ID0gKG5hbWUgKyBcIlwiKS5zcGxpdChcIihcIiksXG4gICAgICBlYXNlID0gX2Vhc2VNYXBbc3BsaXRbMF1dO1xuICByZXR1cm4gZWFzZSAmJiBzcGxpdC5sZW5ndGggPiAxICYmIGVhc2UuY29uZmlnID8gZWFzZS5jb25maWcuYXBwbHkobnVsbCwgfm5hbWUuaW5kZXhPZihcIntcIikgPyBbX3BhcnNlT2JqZWN0SW5TdHJpbmcoc3BsaXRbMV0pXSA6IF92YWx1ZUluUGFyZW50aGVzZXMobmFtZSkuc3BsaXQoXCIsXCIpLm1hcChfbnVtZXJpY0lmUG9zc2libGUpKSA6IF9lYXNlTWFwLl9DRSAmJiBfY3VzdG9tRWFzZUV4cC50ZXN0KG5hbWUpID8gX2Vhc2VNYXAuX0NFKFwiXCIsIG5hbWUpIDogZWFzZTtcbn0sXG4gICAgX2ludmVydEVhc2UgPSBmdW5jdGlvbiBfaW52ZXJ0RWFzZShlYXNlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiAxIC0gZWFzZSgxIC0gcCk7XG4gIH07XG59LFxuICAgIC8vIGFsbG93IHlveW9FYXNlIHRvIGJlIHNldCBpbiBjaGlsZHJlbiBhbmQgaGF2ZSB0aG9zZSBhZmZlY3RlZCB3aGVuIHRoZSBwYXJlbnQvYW5jZXN0b3IgdGltZWxpbmUgeW95b3MuXG5fcHJvcGFnYXRlWW95b0Vhc2UgPSBmdW5jdGlvbiBfcHJvcGFnYXRlWW95b0Vhc2UodGltZWxpbmUsIGlzWW95bykge1xuICB2YXIgY2hpbGQgPSB0aW1lbGluZS5fZmlyc3QsXG4gICAgICBlYXNlO1xuXG4gIHdoaWxlIChjaGlsZCkge1xuICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFRpbWVsaW5lKSB7XG4gICAgICBfcHJvcGFnYXRlWW95b0Vhc2UoY2hpbGQsIGlzWW95byk7XG4gICAgfSBlbHNlIGlmIChjaGlsZC52YXJzLnlveW9FYXNlICYmICghY2hpbGQuX3lveW8gfHwgIWNoaWxkLl9yZXBlYXQpICYmIGNoaWxkLl95b3lvICE9PSBpc1lveW8pIHtcbiAgICAgIGlmIChjaGlsZC50aW1lbGluZSkge1xuICAgICAgICBfcHJvcGFnYXRlWW95b0Vhc2UoY2hpbGQudGltZWxpbmUsIGlzWW95byk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlYXNlID0gY2hpbGQuX2Vhc2U7XG4gICAgICAgIGNoaWxkLl9lYXNlID0gY2hpbGQuX3lFYXNlO1xuICAgICAgICBjaGlsZC5feUVhc2UgPSBlYXNlO1xuICAgICAgICBjaGlsZC5feW95byA9IGlzWW95bztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICB9XG59LFxuICAgIF9wYXJzZUVhc2UgPSBmdW5jdGlvbiBfcGFyc2VFYXNlKGVhc2UsIGRlZmF1bHRFYXNlKSB7XG4gIHJldHVybiAhZWFzZSA/IGRlZmF1bHRFYXNlIDogKF9pc0Z1bmN0aW9uKGVhc2UpID8gZWFzZSA6IF9lYXNlTWFwW2Vhc2VdIHx8IF9jb25maWdFYXNlRnJvbVN0cmluZyhlYXNlKSkgfHwgZGVmYXVsdEVhc2U7XG59LFxuICAgIF9pbnNlcnRFYXNlID0gZnVuY3Rpb24gX2luc2VydEVhc2UobmFtZXMsIGVhc2VJbiwgZWFzZU91dCwgZWFzZUluT3V0KSB7XG4gIGlmIChlYXNlT3V0ID09PSB2b2lkIDApIHtcbiAgICBlYXNlT3V0ID0gZnVuY3Rpb24gZWFzZU91dChwKSB7XG4gICAgICByZXR1cm4gMSAtIGVhc2VJbigxIC0gcCk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChlYXNlSW5PdXQgPT09IHZvaWQgMCkge1xuICAgIGVhc2VJbk91dCA9IGZ1bmN0aW9uIGVhc2VJbk91dChwKSB7XG4gICAgICByZXR1cm4gcCA8IC41ID8gZWFzZUluKHAgKiAyKSAvIDIgOiAxIC0gZWFzZUluKCgxIC0gcCkgKiAyKSAvIDI7XG4gICAgfTtcbiAgfVxuXG4gIHZhciBlYXNlID0ge1xuICAgIGVhc2VJbjogZWFzZUluLFxuICAgIGVhc2VPdXQ6IGVhc2VPdXQsXG4gICAgZWFzZUluT3V0OiBlYXNlSW5PdXRcbiAgfSxcbiAgICAgIGxvd2VyY2FzZU5hbWU7XG5cbiAgX2ZvckVhY2hOYW1lKG5hbWVzLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIF9lYXNlTWFwW25hbWVdID0gX2dsb2JhbHNbbmFtZV0gPSBlYXNlO1xuICAgIF9lYXNlTWFwW2xvd2VyY2FzZU5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCldID0gZWFzZU91dDtcblxuICAgIGZvciAodmFyIHAgaW4gZWFzZSkge1xuICAgICAgX2Vhc2VNYXBbbG93ZXJjYXNlTmFtZSArIChwID09PSBcImVhc2VJblwiID8gXCIuaW5cIiA6IHAgPT09IFwiZWFzZU91dFwiID8gXCIub3V0XCIgOiBcIi5pbk91dFwiKV0gPSBfZWFzZU1hcFtuYW1lICsgXCIuXCIgKyBwXSA9IGVhc2VbcF07XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZWFzZTtcbn0sXG4gICAgX2Vhc2VJbk91dEZyb21PdXQgPSBmdW5jdGlvbiBfZWFzZUluT3V0RnJvbU91dChlYXNlT3V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiBwIDwgLjUgPyAoMSAtIGVhc2VPdXQoMSAtIHAgKiAyKSkgLyAyIDogLjUgKyBlYXNlT3V0KChwIC0gLjUpICogMikgLyAyO1xuICB9O1xufSxcbiAgICBfY29uZmlnRWxhc3RpYyA9IGZ1bmN0aW9uIF9jb25maWdFbGFzdGljKHR5cGUsIGFtcGxpdHVkZSwgcGVyaW9kKSB7XG4gIHZhciBwMSA9IGFtcGxpdHVkZSA+PSAxID8gYW1wbGl0dWRlIDogMSxcbiAgICAgIC8vbm90ZTogaWYgYW1wbGl0dWRlIGlzIDwgMSwgd2Ugc2ltcGx5IGFkanVzdCB0aGUgcGVyaW9kIGZvciBhIG1vcmUgbmF0dXJhbCBmZWVsLiBPdGhlcndpc2UgdGhlIG1hdGggZG9lc24ndCB3b3JrIHJpZ2h0IGFuZCB0aGUgY3VydmUgc3RhcnRzIGF0IDEuXG4gIHAyID0gKHBlcmlvZCB8fCAodHlwZSA/IC4zIDogLjQ1KSkgLyAoYW1wbGl0dWRlIDwgMSA/IGFtcGxpdHVkZSA6IDEpLFxuICAgICAgcDMgPSBwMiAvIF8yUEkgKiAoTWF0aC5hc2luKDEgLyBwMSkgfHwgMCksXG4gICAgICBlYXNlT3V0ID0gZnVuY3Rpb24gZWFzZU91dChwKSB7XG4gICAgcmV0dXJuIHAgPT09IDEgPyAxIDogcDEgKiBNYXRoLnBvdygyLCAtMTAgKiBwKSAqIF9zaW4oKHAgLSBwMykgKiBwMikgKyAxO1xuICB9LFxuICAgICAgZWFzZSA9IHR5cGUgPT09IFwib3V0XCIgPyBlYXNlT3V0IDogdHlwZSA9PT0gXCJpblwiID8gZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gMSAtIGVhc2VPdXQoMSAtIHApO1xuICB9IDogX2Vhc2VJbk91dEZyb21PdXQoZWFzZU91dCk7XG5cbiAgcDIgPSBfMlBJIC8gcDI7IC8vcHJlY2FsY3VsYXRlIHRvIG9wdGltaXplXG5cbiAgZWFzZS5jb25maWcgPSBmdW5jdGlvbiAoYW1wbGl0dWRlLCBwZXJpb2QpIHtcbiAgICByZXR1cm4gX2NvbmZpZ0VsYXN0aWModHlwZSwgYW1wbGl0dWRlLCBwZXJpb2QpO1xuICB9O1xuXG4gIHJldHVybiBlYXNlO1xufSxcbiAgICBfY29uZmlnQmFjayA9IGZ1bmN0aW9uIF9jb25maWdCYWNrKHR5cGUsIG92ZXJzaG9vdCkge1xuICBpZiAob3ZlcnNob290ID09PSB2b2lkIDApIHtcbiAgICBvdmVyc2hvb3QgPSAxLjcwMTU4O1xuICB9XG5cbiAgdmFyIGVhc2VPdXQgPSBmdW5jdGlvbiBlYXNlT3V0KHApIHtcbiAgICByZXR1cm4gcCA/IC0tcCAqIHAgKiAoKG92ZXJzaG9vdCArIDEpICogcCArIG92ZXJzaG9vdCkgKyAxIDogMDtcbiAgfSxcbiAgICAgIGVhc2UgPSB0eXBlID09PSBcIm91dFwiID8gZWFzZU91dCA6IHR5cGUgPT09IFwiaW5cIiA/IGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIDEgLSBlYXNlT3V0KDEgLSBwKTtcbiAgfSA6IF9lYXNlSW5PdXRGcm9tT3V0KGVhc2VPdXQpO1xuXG4gIGVhc2UuY29uZmlnID0gZnVuY3Rpb24gKG92ZXJzaG9vdCkge1xuICAgIHJldHVybiBfY29uZmlnQmFjayh0eXBlLCBvdmVyc2hvb3QpO1xuICB9O1xuXG4gIHJldHVybiBlYXNlO1xufTsgLy8gYSBjaGVhcGVyIChrYiBhbmQgY3B1KSBidXQgbW9yZSBtaWxkIHdheSB0byBnZXQgYSBwYXJhbWV0ZXJpemVkIHdlaWdodGVkIGVhc2UgYnkgZmVlZGluZyBpbiBhIHZhbHVlIGJldHdlZW4gLTEgKGVhc2VJbikgYW5kIDEgKGVhc2VPdXQpIHdoZXJlIDAgaXMgbGluZWFyLlxuLy8gX3dlaWdodGVkRWFzZSA9IHJhdGlvID0+IHtcbi8vIFx0bGV0IHkgPSAwLjUgKyByYXRpbyAvIDI7XG4vLyBcdHJldHVybiBwID0+ICgyICogKDEgLSBwKSAqIHAgKiB5ICsgcCAqIHApO1xuLy8gfSxcbi8vIGEgc3Ryb25nZXIgKGJ1dCBtb3JlIGV4cGVuc2l2ZSBrYi9jcHUpIHBhcmFtZXRlcml6ZWQgd2VpZ2h0ZWQgZWFzZSB0aGF0IGxldHMgeW91IGZlZWQgaW4gYSB2YWx1ZSBiZXR3ZWVuIC0xIChlYXNlSW4pIGFuZCAxIChlYXNlT3V0KSB3aGVyZSAwIGlzIGxpbmVhci5cbi8vIF93ZWlnaHRlZEVhc2VTdHJvbmcgPSByYXRpbyA9PiB7XG4vLyBcdHJhdGlvID0gLjUgKyByYXRpbyAvIDI7XG4vLyBcdGxldCBvID0gMSAvIDMgKiAocmF0aW8gPCAuNSA/IHJhdGlvIDogMSAtIHJhdGlvKSxcbi8vIFx0XHRiID0gcmF0aW8gLSBvLFxuLy8gXHRcdGMgPSByYXRpbyArIG87XG4vLyBcdHJldHVybiBwID0+IHAgPT09IDEgPyBwIDogMyAqIGIgKiAoMSAtIHApICogKDEgLSBwKSAqIHAgKyAzICogYyAqICgxIC0gcCkgKiBwICogcCArIHAgKiBwICogcDtcbi8vIH07XG5cblxuX2ZvckVhY2hOYW1lKFwiTGluZWFyLFF1YWQsQ3ViaWMsUXVhcnQsUXVpbnQsU3Ryb25nXCIsIGZ1bmN0aW9uIChuYW1lLCBpKSB7XG4gIHZhciBwb3dlciA9IGkgPCA1ID8gaSArIDEgOiBpO1xuXG4gIF9pbnNlcnRFYXNlKG5hbWUgKyBcIixQb3dlclwiICsgKHBvd2VyIC0gMSksIGkgPyBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiBNYXRoLnBvdyhwLCBwb3dlcik7XG4gIH0gOiBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiBwO1xuICB9LCBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiAxIC0gTWF0aC5wb3coMSAtIHAsIHBvd2VyKTtcbiAgfSwgZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gcCA8IC41ID8gTWF0aC5wb3cocCAqIDIsIHBvd2VyKSAvIDIgOiAxIC0gTWF0aC5wb3coKDEgLSBwKSAqIDIsIHBvd2VyKSAvIDI7XG4gIH0pO1xufSk7XG5cbl9lYXNlTWFwLkxpbmVhci5lYXNlTm9uZSA9IF9lYXNlTWFwLm5vbmUgPSBfZWFzZU1hcC5MaW5lYXIuZWFzZUluO1xuXG5faW5zZXJ0RWFzZShcIkVsYXN0aWNcIiwgX2NvbmZpZ0VsYXN0aWMoXCJpblwiKSwgX2NvbmZpZ0VsYXN0aWMoXCJvdXRcIiksIF9jb25maWdFbGFzdGljKCkpO1xuXG4oZnVuY3Rpb24gKG4sIGMpIHtcbiAgdmFyIG4xID0gMSAvIGMsXG4gICAgICBuMiA9IDIgKiBuMSxcbiAgICAgIG4zID0gMi41ICogbjEsXG4gICAgICBlYXNlT3V0ID0gZnVuY3Rpb24gZWFzZU91dChwKSB7XG4gICAgcmV0dXJuIHAgPCBuMSA/IG4gKiBwICogcCA6IHAgPCBuMiA/IG4gKiBNYXRoLnBvdyhwIC0gMS41IC8gYywgMikgKyAuNzUgOiBwIDwgbjMgPyBuICogKHAgLT0gMi4yNSAvIGMpICogcCArIC45Mzc1IDogbiAqIE1hdGgucG93KHAgLSAyLjYyNSAvIGMsIDIpICsgLjk4NDM3NTtcbiAgfTtcblxuICBfaW5zZXJ0RWFzZShcIkJvdW5jZVwiLCBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiAxIC0gZWFzZU91dCgxIC0gcCk7XG4gIH0sIGVhc2VPdXQpO1xufSkoNy41NjI1LCAyLjc1KTtcblxuX2luc2VydEVhc2UoXCJFeHBvXCIsIGZ1bmN0aW9uIChwKSB7XG4gIHJldHVybiBwID8gTWF0aC5wb3coMiwgMTAgKiAocCAtIDEpKSA6IDA7XG59KTtcblxuX2luc2VydEVhc2UoXCJDaXJjXCIsIGZ1bmN0aW9uIChwKSB7XG4gIHJldHVybiAtKF9zcXJ0KDEgLSBwICogcCkgLSAxKTtcbn0pO1xuXG5faW5zZXJ0RWFzZShcIlNpbmVcIiwgZnVuY3Rpb24gKHApIHtcbiAgcmV0dXJuIHAgPT09IDEgPyAxIDogLV9jb3MocCAqIF9IQUxGX1BJKSArIDE7XG59KTtcblxuX2luc2VydEVhc2UoXCJCYWNrXCIsIF9jb25maWdCYWNrKFwiaW5cIiksIF9jb25maWdCYWNrKFwib3V0XCIpLCBfY29uZmlnQmFjaygpKTtcblxuX2Vhc2VNYXAuU3RlcHBlZEVhc2UgPSBfZWFzZU1hcC5zdGVwcyA9IF9nbG9iYWxzLlN0ZXBwZWRFYXNlID0ge1xuICBjb25maWc6IGZ1bmN0aW9uIGNvbmZpZyhzdGVwcywgaW1tZWRpYXRlU3RhcnQpIHtcbiAgICBpZiAoc3RlcHMgPT09IHZvaWQgMCkge1xuICAgICAgc3RlcHMgPSAxO1xuICAgIH1cblxuICAgIHZhciBwMSA9IDEgLyBzdGVwcyxcbiAgICAgICAgcDIgPSBzdGVwcyArIChpbW1lZGlhdGVTdGFydCA/IDAgOiAxKSxcbiAgICAgICAgcDMgPSBpbW1lZGlhdGVTdGFydCA/IDEgOiAwLFxuICAgICAgICBtYXggPSAxIC0gX3RpbnlOdW07XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChwKSB7XG4gICAgICByZXR1cm4gKChwMiAqIF9jbGFtcCgwLCBtYXgsIHApIHwgMCkgKyBwMykgKiBwMTtcbiAgICB9O1xuICB9XG59O1xuX2RlZmF1bHRzLmVhc2UgPSBfZWFzZU1hcFtcInF1YWQub3V0XCJdO1xuXG5fZm9yRWFjaE5hbWUoXCJvbkNvbXBsZXRlLG9uVXBkYXRlLG9uU3RhcnQsb25SZXBlYXQsb25SZXZlcnNlQ29tcGxldGUsb25JbnRlcnJ1cHRcIiwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIF9jYWxsYmFja05hbWVzICs9IG5hbWUgKyBcIixcIiArIG5hbWUgKyBcIlBhcmFtcyxcIjtcbn0pO1xuLypcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDQUNIRVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbmV4cG9ydCB2YXIgR1NDYWNoZSA9IGZ1bmN0aW9uIEdTQ2FjaGUodGFyZ2V0LCBoYXJuZXNzKSB7XG4gIHRoaXMuaWQgPSBfZ3NJRCsrO1xuICB0YXJnZXQuX2dzYXAgPSB0aGlzO1xuICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgdGhpcy5oYXJuZXNzID0gaGFybmVzcztcbiAgdGhpcy5nZXQgPSBoYXJuZXNzID8gaGFybmVzcy5nZXQgOiBfZ2V0UHJvcGVydHk7XG4gIHRoaXMuc2V0ID0gaGFybmVzcyA/IGhhcm5lc3MuZ2V0U2V0dGVyIDogX2dldFNldHRlcjtcbn07XG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEFOSU1BVElPTlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5leHBvcnQgdmFyIEFuaW1hdGlvbiA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEFuaW1hdGlvbih2YXJzKSB7XG4gICAgdGhpcy52YXJzID0gdmFycztcbiAgICB0aGlzLl9kZWxheSA9ICt2YXJzLmRlbGF5IHx8IDA7XG5cbiAgICBpZiAodGhpcy5fcmVwZWF0ID0gdmFycy5yZXBlYXQgPT09IEluZmluaXR5ID8gLTIgOiB2YXJzLnJlcGVhdCB8fCAwKSB7XG4gICAgICAvLyBUT0RPOiByZXBlYXQ6IEluZmluaXR5IG9uIGEgdGltZWxpbmUncyBjaGlsZHJlbiBtdXN0IGZsYWcgdGhhdCB0aW1lbGluZSBpbnRlcm5hbGx5IGFuZCBhZmZlY3QgaXRzIHRvdGFsRHVyYXRpb24sIG90aGVyd2lzZSBpdCdsbCBzdG9wIGluIHRoZSBuZWdhdGl2ZSBkaXJlY3Rpb24gd2hlbiByZWFjaGluZyB0aGUgc3RhcnQuXG4gICAgICB0aGlzLl9yRGVsYXkgPSB2YXJzLnJlcGVhdERlbGF5IHx8IDA7XG4gICAgICB0aGlzLl95b3lvID0gISF2YXJzLnlveW8gfHwgISF2YXJzLnlveW9FYXNlO1xuICAgIH1cblxuICAgIHRoaXMuX3RzID0gMTtcblxuICAgIF9zZXREdXJhdGlvbih0aGlzLCArdmFycy5kdXJhdGlvbiwgMSwgMSk7XG5cbiAgICB0aGlzLmRhdGEgPSB2YXJzLmRhdGE7XG5cbiAgICBpZiAoX2NvbnRleHQpIHtcbiAgICAgIHRoaXMuX2N0eCA9IF9jb250ZXh0O1xuXG4gICAgICBfY29udGV4dC5kYXRhLnB1c2godGhpcyk7XG4gICAgfVxuXG4gICAgX3RpY2tlckFjdGl2ZSB8fCBfdGlja2VyLndha2UoKTtcbiAgfVxuXG4gIHZhciBfcHJvdG8gPSBBbmltYXRpb24ucHJvdG90eXBlO1xuXG4gIF9wcm90by5kZWxheSA9IGZ1bmN0aW9uIGRlbGF5KHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlIHx8IHZhbHVlID09PSAwKSB7XG4gICAgICB0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudC5zbW9vdGhDaGlsZFRpbWluZyAmJiB0aGlzLnN0YXJ0VGltZSh0aGlzLl9zdGFydCArIHZhbHVlIC0gdGhpcy5fZGVsYXkpO1xuICAgICAgdGhpcy5fZGVsYXkgPSB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9kZWxheTtcbiAgfTtcblxuICBfcHJvdG8uZHVyYXRpb24gPSBmdW5jdGlvbiBkdXJhdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy50b3RhbER1cmF0aW9uKHRoaXMuX3JlcGVhdCA+IDAgPyB2YWx1ZSArICh2YWx1ZSArIHRoaXMuX3JEZWxheSkgKiB0aGlzLl9yZXBlYXQgOiB2YWx1ZSkgOiB0aGlzLnRvdGFsRHVyYXRpb24oKSAmJiB0aGlzLl9kdXI7XG4gIH07XG5cbiAgX3Byb3RvLnRvdGFsRHVyYXRpb24gPSBmdW5jdGlvbiB0b3RhbER1cmF0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdER1cjtcbiAgICB9XG5cbiAgICB0aGlzLl9kaXJ0eSA9IDA7XG4gICAgcmV0dXJuIF9zZXREdXJhdGlvbih0aGlzLCB0aGlzLl9yZXBlYXQgPCAwID8gdmFsdWUgOiAodmFsdWUgLSB0aGlzLl9yZXBlYXQgKiB0aGlzLl9yRGVsYXkpIC8gKHRoaXMuX3JlcGVhdCArIDEpKTtcbiAgfTtcblxuICBfcHJvdG8udG90YWxUaW1lID0gZnVuY3Rpb24gdG90YWxUaW1lKF90b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgX3dha2UoKTtcblxuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3RUaW1lO1xuICAgIH1cblxuICAgIHZhciBwYXJlbnQgPSB0aGlzLl9kcDtcblxuICAgIGlmIChwYXJlbnQgJiYgcGFyZW50LnNtb290aENoaWxkVGltaW5nICYmIHRoaXMuX3RzKSB7XG4gICAgICBfYWxpZ25QbGF5aGVhZCh0aGlzLCBfdG90YWxUaW1lKTtcblxuICAgICAgIXBhcmVudC5fZHAgfHwgcGFyZW50LnBhcmVudCB8fCBfcG9zdEFkZENoZWNrcyhwYXJlbnQsIHRoaXMpOyAvLyBlZGdlIGNhc2U6IGlmIHRoaXMgaXMgYSBjaGlsZCBvZiBhIHRpbWVsaW5lIHRoYXQgYWxyZWFkeSBjb21wbGV0ZWQsIGZvciBleGFtcGxlLCB3ZSBtdXN0IHJlLWFjdGl2YXRlIHRoZSBwYXJlbnQuXG4gICAgICAvL2luIGNhc2UgYW55IG9mIHRoZSBhbmNlc3RvciB0aW1lbGluZXMgaGFkIGNvbXBsZXRlZCBidXQgc2hvdWxkIG5vdyBiZSBlbmFibGVkLCB3ZSBzaG91bGQgcmVzZXQgdGhlaXIgdG90YWxUaW1lKCkgd2hpY2ggd2lsbCBhbHNvIGVuc3VyZSB0aGF0IHRoZXkncmUgbGluZWQgdXAgcHJvcGVybHkgYW5kIGVuYWJsZWQuIFNraXAgZm9yIGFuaW1hdGlvbnMgdGhhdCBhcmUgb24gdGhlIHJvb3QgKHdhc3RlZnVsKS4gRXhhbXBsZTogYSBUaW1lbGluZUxpdGUuZXhwb3J0Um9vdCgpIGlzIHBlcmZvcm1lZCB3aGVuIHRoZXJlJ3MgYSBwYXVzZWQgdHdlZW4gb24gdGhlIHJvb3QsIHRoZSBleHBvcnQgd2lsbCBub3QgY29tcGxldGUgdW50aWwgdGhhdCB0d2VlbiBpcyB1bnBhdXNlZCwgYnV0IGltYWdpbmUgYSBjaGlsZCBnZXRzIHJlc3RhcnRlZCBsYXRlciwgYWZ0ZXIgYWxsIFt1bnBhdXNlZF0gdHdlZW5zIGhhdmUgY29tcGxldGVkLiBUaGUgc3RhcnQgb2YgdGhhdCBjaGlsZCB3b3VsZCBnZXQgcHVzaGVkIG91dCwgYnV0IG9uZSBvZiB0aGUgYW5jZXN0b3JzIG1heSBoYXZlIGNvbXBsZXRlZC5cblxuICAgICAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQucGFyZW50KSB7XG4gICAgICAgIGlmIChwYXJlbnQucGFyZW50Ll90aW1lICE9PSBwYXJlbnQuX3N0YXJ0ICsgKHBhcmVudC5fdHMgPj0gMCA/IHBhcmVudC5fdFRpbWUgLyBwYXJlbnQuX3RzIDogKHBhcmVudC50b3RhbER1cmF0aW9uKCkgLSBwYXJlbnQuX3RUaW1lKSAvIC1wYXJlbnQuX3RzKSkge1xuICAgICAgICAgIHBhcmVudC50b3RhbFRpbWUocGFyZW50Ll90VGltZSwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMucGFyZW50ICYmIHRoaXMuX2RwLmF1dG9SZW1vdmVDaGlsZHJlbiAmJiAodGhpcy5fdHMgPiAwICYmIF90b3RhbFRpbWUgPCB0aGlzLl90RHVyIHx8IHRoaXMuX3RzIDwgMCAmJiBfdG90YWxUaW1lID4gMCB8fCAhdGhpcy5fdER1ciAmJiAhX3RvdGFsVGltZSkpIHtcbiAgICAgICAgLy9pZiB0aGUgYW5pbWF0aW9uIGRvZXNuJ3QgaGF2ZSBhIHBhcmVudCwgcHV0IGl0IGJhY2sgaW50byBpdHMgbGFzdCBwYXJlbnQgKHJlY29yZGVkIGFzIF9kcCBmb3IgZXhhY3RseSBjYXNlcyBsaWtlIHRoaXMpLiBMaW1pdCB0byBwYXJlbnRzIHdpdGggYXV0b1JlbW92ZUNoaWxkcmVuIChsaWtlIGdsb2JhbFRpbWVsaW5lKSBzbyB0aGF0IGlmIHRoZSB1c2VyIG1hbnVhbGx5IHJlbW92ZXMgYW4gYW5pbWF0aW9uIGZyb20gYSB0aW1lbGluZSBhbmQgdGhlbiBhbHRlcnMgaXRzIHBsYXloZWFkLCBpdCBkb2Vzbid0IGdldCBhZGRlZCBiYWNrIGluLlxuICAgICAgICBfYWRkVG9UaW1lbGluZSh0aGlzLl9kcCwgdGhpcywgdGhpcy5fc3RhcnQgLSB0aGlzLl9kZWxheSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3RUaW1lICE9PSBfdG90YWxUaW1lIHx8ICF0aGlzLl9kdXIgJiYgIXN1cHByZXNzRXZlbnRzIHx8IHRoaXMuX2luaXR0ZWQgJiYgTWF0aC5hYnModGhpcy5felRpbWUpID09PSBfdGlueU51bSB8fCAhX3RvdGFsVGltZSAmJiAhdGhpcy5faW5pdHRlZCAmJiAodGhpcy5hZGQgfHwgdGhpcy5fcHRMb29rdXApKSB7XG4gICAgICAvLyBjaGVjayBmb3IgX3B0TG9va3VwIG9uIGEgVHdlZW4gaW5zdGFuY2UgdG8gZW5zdXJlIGl0IGhhcyBhY3R1YWxseSBmaW5pc2hlZCBiZWluZyBpbnN0YW50aWF0ZWQsIG90aGVyd2lzZSBpZiB0aGlzLnJldmVyc2UoKSBnZXRzIGNhbGxlZCBpbiB0aGUgQW5pbWF0aW9uIGNvbnN0cnVjdG9yLCBpdCBjb3VsZCB0cmlnZ2VyIGEgcmVuZGVyKCkgaGVyZSBldmVuIHRob3VnaCB0aGUgX3RhcmdldHMgd2VyZW4ndCBwb3B1bGF0ZWQsIHRodXMgd2hlbiBfaW5pdCgpIGlzIGNhbGxlZCB0aGVyZSB3b24ndCBiZSBhbnkgUHJvcFR3ZWVucyAoaXQnbGwgYWN0IGxpa2UgdGhlIHR3ZWVuIGlzIG5vbi1mdW5jdGlvbmFsKVxuICAgICAgdGhpcy5fdHMgfHwgKHRoaXMuX3BUaW1lID0gX3RvdGFsVGltZSk7IC8vIG90aGVyd2lzZSwgaWYgYW4gYW5pbWF0aW9uIGlzIHBhdXNlZCwgdGhlbiB0aGUgcGxheWhlYWQgaXMgbW92ZWQgYmFjayB0byB6ZXJvLCB0aGVuIHJlc3VtZWQsIGl0J2QgcmV2ZXJ0IGJhY2sgdG8gdGhlIG9yaWdpbmFsIHRpbWUgYXQgdGhlIHBhdXNlXG4gICAgICAvL2lmICghdGhpcy5fbG9jaykgeyAvLyBhdm9pZCBlbmRsZXNzIHJlY3Vyc2lvbiAobm90IHN1cmUgd2UgbmVlZCB0aGlzIHlldCBvciBpZiBpdCdzIHdvcnRoIHRoZSBwZXJmb3JtYW5jZSBoaXQpXG4gICAgICAvLyAgIHRoaXMuX2xvY2sgPSAxO1xuXG4gICAgICBfbGF6eVNhZmVSZW5kZXIodGhpcywgX3RvdGFsVGltZSwgc3VwcHJlc3NFdmVudHMpOyAvLyAgIHRoaXMuX2xvY2sgPSAwO1xuICAgICAgLy99XG5cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8udGltZSA9IGZ1bmN0aW9uIHRpbWUodmFsdWUsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnRvdGFsVGltZShNYXRoLm1pbih0aGlzLnRvdGFsRHVyYXRpb24oKSwgdmFsdWUgKyBfZWxhcHNlZEN5Y2xlRHVyYXRpb24odGhpcykpICUgKHRoaXMuX2R1ciArIHRoaXMuX3JEZWxheSkgfHwgKHZhbHVlID8gdGhpcy5fZHVyIDogMCksIHN1cHByZXNzRXZlbnRzKSA6IHRoaXMuX3RpbWU7IC8vIG5vdGU6IGlmIHRoZSBtb2R1bHVzIHJlc3VsdHMgaW4gMCwgdGhlIHBsYXloZWFkIGNvdWxkIGJlIGV4YWN0bHkgYXQgdGhlIGVuZCBvciB0aGUgYmVnaW5uaW5nLCBhbmQgd2UgYWx3YXlzIGRlZmVyIHRvIHRoZSBFTkQgd2l0aCBhIG5vbi16ZXJvIHZhbHVlLCBvdGhlcndpc2UgaWYgeW91IHNldCB0aGUgdGltZSgpIHRvIHRoZSB2ZXJ5IGVuZCAoZHVyYXRpb24oKSksIGl0IHdvdWxkIHJlbmRlciBhdCB0aGUgU1RBUlQhXG4gIH07XG5cbiAgX3Byb3RvLnRvdGFsUHJvZ3Jlc3MgPSBmdW5jdGlvbiB0b3RhbFByb2dyZXNzKHZhbHVlLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy50b3RhbFRpbWUodGhpcy50b3RhbER1cmF0aW9uKCkgKiB2YWx1ZSwgc3VwcHJlc3NFdmVudHMpIDogdGhpcy50b3RhbER1cmF0aW9uKCkgPyBNYXRoLm1pbigxLCB0aGlzLl90VGltZSAvIHRoaXMuX3REdXIpIDogdGhpcy5yYXRpbztcbiAgfTtcblxuICBfcHJvdG8ucHJvZ3Jlc3MgPSBmdW5jdGlvbiBwcm9ncmVzcyh2YWx1ZSwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMudG90YWxUaW1lKHRoaXMuZHVyYXRpb24oKSAqICh0aGlzLl95b3lvICYmICEodGhpcy5pdGVyYXRpb24oKSAmIDEpID8gMSAtIHZhbHVlIDogdmFsdWUpICsgX2VsYXBzZWRDeWNsZUR1cmF0aW9uKHRoaXMpLCBzdXBwcmVzc0V2ZW50cykgOiB0aGlzLmR1cmF0aW9uKCkgPyBNYXRoLm1pbigxLCB0aGlzLl90aW1lIC8gdGhpcy5fZHVyKSA6IHRoaXMucmF0aW87XG4gIH07XG5cbiAgX3Byb3RvLml0ZXJhdGlvbiA9IGZ1bmN0aW9uIGl0ZXJhdGlvbih2YWx1ZSwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICB2YXIgY3ljbGVEdXJhdGlvbiA9IHRoaXMuZHVyYXRpb24oKSArIHRoaXMuX3JEZWxheTtcblxuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy50b3RhbFRpbWUodGhpcy5fdGltZSArICh2YWx1ZSAtIDEpICogY3ljbGVEdXJhdGlvbiwgc3VwcHJlc3NFdmVudHMpIDogdGhpcy5fcmVwZWF0ID8gX2FuaW1hdGlvbkN5Y2xlKHRoaXMuX3RUaW1lLCBjeWNsZUR1cmF0aW9uKSArIDEgOiAxO1xuICB9IC8vIHBvdGVudGlhbCBmdXR1cmUgYWRkaXRpb246XG4gIC8vIGlzUGxheWluZ0JhY2t3YXJkcygpIHtcbiAgLy8gXHRsZXQgYW5pbWF0aW9uID0gdGhpcyxcbiAgLy8gXHRcdG9yaWVudGF0aW9uID0gMTsgLy8gMSA9IGZvcndhcmQsIC0xID0gYmFja3dhcmRcbiAgLy8gXHR3aGlsZSAoYW5pbWF0aW9uKSB7XG4gIC8vIFx0XHRvcmllbnRhdGlvbiAqPSBhbmltYXRpb24ucmV2ZXJzZWQoKSB8fCAoYW5pbWF0aW9uLnJlcGVhdCgpICYmICEoYW5pbWF0aW9uLml0ZXJhdGlvbigpICYgMSkpID8gLTEgOiAxO1xuICAvLyBcdFx0YW5pbWF0aW9uID0gYW5pbWF0aW9uLnBhcmVudDtcbiAgLy8gXHR9XG4gIC8vIFx0cmV0dXJuIG9yaWVudGF0aW9uIDwgMDtcbiAgLy8gfVxuICA7XG5cbiAgX3Byb3RvLnRpbWVTY2FsZSA9IGZ1bmN0aW9uIHRpbWVTY2FsZSh2YWx1ZSkge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3J0cyA9PT0gLV90aW55TnVtID8gMCA6IHRoaXMuX3J0czsgLy8gcmVjb3JkZWQgdGltZVNjYWxlLiBTcGVjaWFsIGNhc2U6IGlmIHNvbWVvbmUgY2FsbHMgcmV2ZXJzZSgpIG9uIGFuIGFuaW1hdGlvbiB3aXRoIHRpbWVTY2FsZSBvZiAwLCB3ZSBhc3NpZ24gaXQgLV90aW55TnVtIHRvIHJlbWVtYmVyIGl0J3MgcmV2ZXJzZWQuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3J0cyA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHZhciB0VGltZSA9IHRoaXMucGFyZW50ICYmIHRoaXMuX3RzID8gX3BhcmVudFRvQ2hpbGRUb3RhbFRpbWUodGhpcy5wYXJlbnQuX3RpbWUsIHRoaXMpIDogdGhpcy5fdFRpbWU7IC8vIG1ha2Ugc3VyZSB0byBkbyB0aGUgcGFyZW50VG9DaGlsZFRvdGFsVGltZSgpIEJFRk9SRSBzZXR0aW5nIHRoZSBuZXcgX3RzIGJlY2F1c2UgdGhlIG9sZCBvbmUgbXVzdCBiZSB1c2VkIGluIHRoYXQgY2FsY3VsYXRpb24uXG4gICAgLy8gZnV0dXJlIGFkZGl0aW9uPyBVcCBzaWRlOiBmYXN0IGFuZCBtaW5pbWFsIGZpbGUgc2l6ZS4gRG93biBzaWRlOiBvbmx5IHdvcmtzIG9uIHRoaXMgYW5pbWF0aW9uOyBpZiBhIHRpbWVsaW5lIGlzIHJldmVyc2VkLCBmb3IgZXhhbXBsZSwgaXRzIGNoaWxkcmVucycgb25SZXZlcnNlIHdvdWxkbid0IGdldCBjYWxsZWQuXG4gICAgLy8oK3ZhbHVlIDwgMCAmJiB0aGlzLl9ydHMgPj0gMCkgJiYgX2NhbGxiYWNrKHRoaXMsIFwib25SZXZlcnNlXCIsIHRydWUpO1xuICAgIC8vIHByaW9yaXRpemUgcmVuZGVyaW5nIHdoZXJlIHRoZSBwYXJlbnQncyBwbGF5aGVhZCBsaW5lcyB1cCBpbnN0ZWFkIG9mIHRoaXMuX3RUaW1lIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgYSB0d2VlbiB0aGF0J3MgYW5pbWF0aW5nIGFub3RoZXIgdHdlZW4ncyB0aW1lU2NhbGUgaW4gdGhlIHNhbWUgcmVuZGVyaW5nIGxvb3AgKHNhbWUgcGFyZW50KSwgdGh1cyBpZiB0aGUgdGltZVNjYWxlIHR3ZWVuIHJlbmRlcnMgZmlyc3QsIGl0IHdvdWxkIGFsdGVyIF9zdGFydCBCRUZPUkUgX3RUaW1lIHdhcyBzZXQgb24gdGhhdCB0aWNrIChpbiB0aGUgcmVuZGVyaW5nIGxvb3ApLCBlZmZlY3RpdmVseSBmcmVlemluZyBpdCB1bnRpbCB0aGUgdGltZVNjYWxlIHR3ZWVuIGZpbmlzaGVzLlxuXG4gICAgdGhpcy5fcnRzID0gK3ZhbHVlIHx8IDA7XG4gICAgdGhpcy5fdHMgPSB0aGlzLl9wcyB8fCB2YWx1ZSA9PT0gLV90aW55TnVtID8gMCA6IHRoaXMuX3J0czsgLy8gX3RzIGlzIHRoZSBmdW5jdGlvbmFsIHRpbWVTY2FsZSB3aGljaCB3b3VsZCBiZSAwIGlmIHRoZSBhbmltYXRpb24gaXMgcGF1c2VkLlxuXG4gICAgdGhpcy50b3RhbFRpbWUoX2NsYW1wKC1NYXRoLmFicyh0aGlzLl9kZWxheSksIHRoaXMuX3REdXIsIHRUaW1lKSwgdHJ1ZSk7XG5cbiAgICBfc2V0RW5kKHRoaXMpOyAvLyBpZiBwYXJlbnQuc21vb3RoQ2hpbGRUaW1pbmcgd2FzIGZhbHNlLCB0aGUgZW5kIHRpbWUgZGlkbid0IGdldCB1cGRhdGVkIGluIHRoZSBfYWxpZ25QbGF5aGVhZCgpIG1ldGhvZCwgc28gZG8gaXQgaGVyZS5cblxuXG4gICAgcmV0dXJuIF9yZWNhY2hlQW5jZXN0b3JzKHRoaXMpO1xuICB9O1xuXG4gIF9wcm90by5wYXVzZWQgPSBmdW5jdGlvbiBwYXVzZWQodmFsdWUpIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9wcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcHMgIT09IHZhbHVlKSB7XG4gICAgICB0aGlzLl9wcyA9IHZhbHVlO1xuXG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fcFRpbWUgPSB0aGlzLl90VGltZSB8fCBNYXRoLm1heCgtdGhpcy5fZGVsYXksIHRoaXMucmF3VGltZSgpKTsgLy8gaWYgdGhlIHBhdXNlIG9jY3VycyBkdXJpbmcgdGhlIGRlbGF5IHBoYXNlLCBtYWtlIHN1cmUgdGhhdCdzIGZhY3RvcmVkIGluIHdoZW4gcmVzdW1pbmcuXG5cbiAgICAgICAgdGhpcy5fdHMgPSB0aGlzLl9hY3QgPSAwOyAvLyBfdHMgaXMgdGhlIGZ1bmN0aW9uYWwgdGltZVNjYWxlLCBzbyBhIHBhdXNlZCB0d2VlbiB3b3VsZCBlZmZlY3RpdmVseSBoYXZlIGEgdGltZVNjYWxlIG9mIDAuIFdlIHJlY29yZCB0aGUgXCJyZWFsXCIgdGltZVNjYWxlIGFzIF9ydHMgKHJlY29yZGVkIHRpbWUgc2NhbGUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfd2FrZSgpO1xuXG4gICAgICAgIHRoaXMuX3RzID0gdGhpcy5fcnRzOyAvL29ubHkgZGVmZXIgdG8gX3BUaW1lIChwYXVzZVRpbWUpIGlmIHRUaW1lIGlzIHplcm8uIFJlbWVtYmVyLCBzb21lb25lIGNvdWxkIHBhdXNlKCkgYW4gYW5pbWF0aW9uLCB0aGVuIHNjcnViIHRoZSBwbGF5aGVhZCBhbmQgcmVzdW1lKCkuIElmIHRoZSBwYXJlbnQgZG9lc24ndCBoYXZlIHNtb290aENoaWxkVGltaW5nLCB3ZSByZW5kZXIgYXQgdGhlIHJhd1RpbWUoKSBiZWNhdXNlIHRoZSBzdGFydFRpbWUgd29uJ3QgZ2V0IHVwZGF0ZWQuXG5cbiAgICAgICAgdGhpcy50b3RhbFRpbWUodGhpcy5wYXJlbnQgJiYgIXRoaXMucGFyZW50LnNtb290aENoaWxkVGltaW5nID8gdGhpcy5yYXdUaW1lKCkgOiB0aGlzLl90VGltZSB8fCB0aGlzLl9wVGltZSwgdGhpcy5wcm9ncmVzcygpID09PSAxICYmIE1hdGguYWJzKHRoaXMuX3pUaW1lKSAhPT0gX3RpbnlOdW0gJiYgKHRoaXMuX3RUaW1lIC09IF90aW55TnVtKSk7IC8vIGVkZ2UgY2FzZTogYW5pbWF0aW9uLnByb2dyZXNzKDEpLnBhdXNlKCkucGxheSgpIHdvdWxkbid0IHJlbmRlciBhZ2FpbiBiZWNhdXNlIHRoZSBwbGF5aGVhZCBpcyBhbHJlYWR5IGF0IHRoZSBlbmQsIGJ1dCB0aGUgY2FsbCB0byB0b3RhbFRpbWUoKSBiZWxvdyB3aWxsIGFkZCBpdCBiYWNrIHRvIGl0cyBwYXJlbnQuLi5hbmQgbm90IHJlbW92ZSBpdCBhZ2FpbiAoc2luY2UgcmVtb3Zpbmcgb25seSBoYXBwZW5zIHVwb24gcmVuZGVyaW5nIGF0IGEgbmV3IHRpbWUpLiBPZmZzZXR0aW5nIHRoZSBfdFRpbWUgc2xpZ2h0bHkgaXMgZG9uZSBzaW1wbHkgdG8gY2F1c2UgdGhlIGZpbmFsIHJlbmRlciBpbiB0b3RhbFRpbWUoKSB0aGF0J2xsIHBvcCBpdCBvZmYgaXRzIHRpbWVsaW5lIChpZiBhdXRvUmVtb3ZlQ2hpbGRyZW4gaXMgdHJ1ZSwgb2YgY291cnNlKS4gQ2hlY2sgdG8gbWFrZSBzdXJlIF96VGltZSBpc24ndCAtX3RpbnlOdW0gdG8gYXZvaWQgYW4gZWRnZSBjYXNlIHdoZXJlIHRoZSBwbGF5aGVhZCBpcyBwdXNoZWQgdG8gdGhlIGVuZCBidXQgSU5TSURFIGEgdHdlZW4vY2FsbGJhY2ssIHRoZSB0aW1lbGluZSBpdHNlbGYgaXMgcGF1c2VkIHRodXMgaGFsdGluZyByZW5kZXJpbmcgYW5kIGxlYXZpbmcgYSBmZXcgdW5yZW5kZXJlZC4gV2hlbiByZXN1bWluZywgaXQgd291bGRuJ3QgcmVuZGVyIHRob3NlIG90aGVyd2lzZS5cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8uc3RhcnRUaW1lID0gZnVuY3Rpb24gc3RhcnRUaW1lKHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3N0YXJ0ID0gdmFsdWU7XG4gICAgICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnQgfHwgdGhpcy5fZHA7XG4gICAgICBwYXJlbnQgJiYgKHBhcmVudC5fc29ydCB8fCAhdGhpcy5wYXJlbnQpICYmIF9hZGRUb1RpbWVsaW5lKHBhcmVudCwgdGhpcywgdmFsdWUgLSB0aGlzLl9kZWxheSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3RhcnQ7XG4gIH07XG5cbiAgX3Byb3RvLmVuZFRpbWUgPSBmdW5jdGlvbiBlbmRUaW1lKGluY2x1ZGVSZXBlYXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0ICsgKF9pc05vdEZhbHNlKGluY2x1ZGVSZXBlYXRzKSA/IHRoaXMudG90YWxEdXJhdGlvbigpIDogdGhpcy5kdXJhdGlvbigpKSAvIE1hdGguYWJzKHRoaXMuX3RzIHx8IDEpO1xuICB9O1xuXG4gIF9wcm90by5yYXdUaW1lID0gZnVuY3Rpb24gcmF3VGltZSh3cmFwUmVwZWF0cykge1xuICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzLl9kcDsgLy8gX2RwID0gZGV0YWNoZWQgcGFyZW50XG5cbiAgICByZXR1cm4gIXBhcmVudCA/IHRoaXMuX3RUaW1lIDogd3JhcFJlcGVhdHMgJiYgKCF0aGlzLl90cyB8fCB0aGlzLl9yZXBlYXQgJiYgdGhpcy5fdGltZSAmJiB0aGlzLnRvdGFsUHJvZ3Jlc3MoKSA8IDEpID8gdGhpcy5fdFRpbWUgJSAodGhpcy5fZHVyICsgdGhpcy5fckRlbGF5KSA6ICF0aGlzLl90cyA/IHRoaXMuX3RUaW1lIDogX3BhcmVudFRvQ2hpbGRUb3RhbFRpbWUocGFyZW50LnJhd1RpbWUod3JhcFJlcGVhdHMpLCB0aGlzKTtcbiAgfTtcblxuICBfcHJvdG8ucmV2ZXJ0ID0gZnVuY3Rpb24gcmV2ZXJ0KGNvbmZpZykge1xuICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkge1xuICAgICAgY29uZmlnID0gX3JldmVydENvbmZpZztcbiAgICB9XG5cbiAgICB2YXIgcHJldklzUmV2ZXJ0aW5nID0gX3JldmVydGluZztcbiAgICBfcmV2ZXJ0aW5nID0gY29uZmlnO1xuXG4gICAgaWYgKHRoaXMuX2luaXR0ZWQgfHwgdGhpcy5fc3RhcnRBdCkge1xuICAgICAgdGhpcy50aW1lbGluZSAmJiB0aGlzLnRpbWVsaW5lLnJldmVydChjb25maWcpO1xuICAgICAgdGhpcy50b3RhbFRpbWUoLTAuMDEsIGNvbmZpZy5zdXBwcmVzc0V2ZW50cyk7XG4gICAgfVxuXG4gICAgdGhpcy5kYXRhICE9PSBcIm5lc3RlZFwiICYmIGNvbmZpZy5raWxsICE9PSBmYWxzZSAmJiB0aGlzLmtpbGwoKTtcbiAgICBfcmV2ZXJ0aW5nID0gcHJldklzUmV2ZXJ0aW5nO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90by5nbG9iYWxUaW1lID0gZnVuY3Rpb24gZ2xvYmFsVGltZShyYXdUaW1lKSB7XG4gICAgdmFyIGFuaW1hdGlvbiA9IHRoaXMsXG4gICAgICAgIHRpbWUgPSBhcmd1bWVudHMubGVuZ3RoID8gcmF3VGltZSA6IGFuaW1hdGlvbi5yYXdUaW1lKCk7XG5cbiAgICB3aGlsZSAoYW5pbWF0aW9uKSB7XG4gICAgICB0aW1lID0gYW5pbWF0aW9uLl9zdGFydCArIHRpbWUgLyAoYW5pbWF0aW9uLl90cyB8fCAxKTtcbiAgICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5fZHA7XG4gICAgfVxuXG4gICAgcmV0dXJuICF0aGlzLnBhcmVudCAmJiB0aGlzLl9zYXQgPyB0aGlzLl9zYXQudmFycy5pbW1lZGlhdGVSZW5kZXIgPyAtMSA6IHRoaXMuX3NhdC5nbG9iYWxUaW1lKHJhd1RpbWUpIDogdGltZTsgLy8gdGhlIF9zdGFydEF0IHR3ZWVucyBmb3IgLmZyb21UbygpIGFuZCAuZnJvbSgpIHRoYXQgaGF2ZSBpbW1lZGlhdGVSZW5kZXIgc2hvdWxkIGFsd2F5cyBiZSBGSVJTVCBpbiB0aGUgdGltZWxpbmUgKGltcG9ydGFudCBmb3IgY29udGV4dC5yZXZlcnQoKSkuIFwiX3NhdFwiIHN0YW5kcyBmb3IgX3N0YXJ0QXRUd2VlbiwgcmVmZXJyaW5nIHRvIHRoZSBwYXJlbnQgdHdlZW4gdGhhdCBjcmVhdGVkIHRoZSBfc3RhcnRBdC4gV2UgbXVzdCBkaXNjZXJuIGlmIHRoYXQgdHdlZW4gaGFkIGltbWVkaWF0ZVJlbmRlciBzbyB0aGF0IHdlIGNhbiBrbm93IHdoZXRoZXIgb3Igbm90IHRvIHByaW9yaXRpemUgaXQgaW4gcmV2ZXJ0KCkuXG4gIH07XG5cbiAgX3Byb3RvLnJlcGVhdCA9IGZ1bmN0aW9uIHJlcGVhdCh2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9yZXBlYXQgPSB2YWx1ZSA9PT0gSW5maW5pdHkgPyAtMiA6IHZhbHVlO1xuICAgICAgcmV0dXJuIF9vblVwZGF0ZVRvdGFsRHVyYXRpb24odGhpcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcGVhdCA9PT0gLTIgPyBJbmZpbml0eSA6IHRoaXMuX3JlcGVhdDtcbiAgfTtcblxuICBfcHJvdG8ucmVwZWF0RGVsYXkgPSBmdW5jdGlvbiByZXBlYXREZWxheSh2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2YXIgdGltZSA9IHRoaXMuX3RpbWU7XG4gICAgICB0aGlzLl9yRGVsYXkgPSB2YWx1ZTtcblxuICAgICAgX29uVXBkYXRlVG90YWxEdXJhdGlvbih0aGlzKTtcblxuICAgICAgcmV0dXJuIHRpbWUgPyB0aGlzLnRpbWUodGltZSkgOiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yRGVsYXk7XG4gIH07XG5cbiAgX3Byb3RvLnlveW8gPSBmdW5jdGlvbiB5b3lvKHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3lveW8gPSB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl95b3lvO1xuICB9O1xuXG4gIF9wcm90by5zZWVrID0gZnVuY3Rpb24gc2Vlayhwb3NpdGlvbiwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICByZXR1cm4gdGhpcy50b3RhbFRpbWUoX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pLCBfaXNOb3RGYWxzZShzdXBwcmVzc0V2ZW50cykpO1xuICB9O1xuXG4gIF9wcm90by5yZXN0YXJ0ID0gZnVuY3Rpb24gcmVzdGFydChpbmNsdWRlRGVsYXksIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgcmV0dXJuIHRoaXMucGxheSgpLnRvdGFsVGltZShpbmNsdWRlRGVsYXkgPyAtdGhpcy5fZGVsYXkgOiAwLCBfaXNOb3RGYWxzZShzdXBwcmVzc0V2ZW50cykpO1xuICB9O1xuXG4gIF9wcm90by5wbGF5ID0gZnVuY3Rpb24gcGxheShmcm9tLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGZyb20gIT0gbnVsbCAmJiB0aGlzLnNlZWsoZnJvbSwgc3VwcHJlc3NFdmVudHMpO1xuICAgIHJldHVybiB0aGlzLnJldmVyc2VkKGZhbHNlKS5wYXVzZWQoZmFsc2UpO1xuICB9O1xuXG4gIF9wcm90by5yZXZlcnNlID0gZnVuY3Rpb24gcmV2ZXJzZShmcm9tLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGZyb20gIT0gbnVsbCAmJiB0aGlzLnNlZWsoZnJvbSB8fCB0aGlzLnRvdGFsRHVyYXRpb24oKSwgc3VwcHJlc3NFdmVudHMpO1xuICAgIHJldHVybiB0aGlzLnJldmVyc2VkKHRydWUpLnBhdXNlZChmYWxzZSk7XG4gIH07XG5cbiAgX3Byb3RvLnBhdXNlID0gZnVuY3Rpb24gcGF1c2UoYXRUaW1lLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGF0VGltZSAhPSBudWxsICYmIHRoaXMuc2VlayhhdFRpbWUsIHN1cHByZXNzRXZlbnRzKTtcbiAgICByZXR1cm4gdGhpcy5wYXVzZWQodHJ1ZSk7XG4gIH07XG5cbiAgX3Byb3RvLnJlc3VtZSA9IGZ1bmN0aW9uIHJlc3VtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXVzZWQoZmFsc2UpO1xuICB9O1xuXG4gIF9wcm90by5yZXZlcnNlZCA9IGZ1bmN0aW9uIHJldmVyc2VkKHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICEhdmFsdWUgIT09IHRoaXMucmV2ZXJzZWQoKSAmJiB0aGlzLnRpbWVTY2FsZSgtdGhpcy5fcnRzIHx8ICh2YWx1ZSA/IC1fdGlueU51bSA6IDApKTsgLy8gaW4gY2FzZSB0aW1lU2NhbGUgaXMgemVybywgcmV2ZXJzaW5nIHdvdWxkIGhhdmUgbm8gZWZmZWN0IHNvIHdlIHVzZSBfdGlueU51bS5cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3J0cyA8IDA7XG4gIH07XG5cbiAgX3Byb3RvLmludmFsaWRhdGUgPSBmdW5jdGlvbiBpbnZhbGlkYXRlKCkge1xuICAgIHRoaXMuX2luaXR0ZWQgPSB0aGlzLl9hY3QgPSAwO1xuICAgIHRoaXMuX3pUaW1lID0gLV90aW55TnVtO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90by5pc0FjdGl2ZSA9IGZ1bmN0aW9uIGlzQWN0aXZlKCkge1xuICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzLl9kcCxcbiAgICAgICAgc3RhcnQgPSB0aGlzLl9zdGFydCxcbiAgICAgICAgcmF3VGltZTtcbiAgICByZXR1cm4gISEoIXBhcmVudCB8fCB0aGlzLl90cyAmJiB0aGlzLl9pbml0dGVkICYmIHBhcmVudC5pc0FjdGl2ZSgpICYmIChyYXdUaW1lID0gcGFyZW50LnJhd1RpbWUodHJ1ZSkpID49IHN0YXJ0ICYmIHJhd1RpbWUgPCB0aGlzLmVuZFRpbWUodHJ1ZSkgLSBfdGlueU51bSk7XG4gIH07XG5cbiAgX3Byb3RvLmV2ZW50Q2FsbGJhY2sgPSBmdW5jdGlvbiBldmVudENhbGxiYWNrKHR5cGUsIGNhbGxiYWNrLCBwYXJhbXMpIHtcbiAgICB2YXIgdmFycyA9IHRoaXMudmFycztcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICBkZWxldGUgdmFyc1t0eXBlXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhcnNbdHlwZV0gPSBjYWxsYmFjaztcbiAgICAgICAgcGFyYW1zICYmICh2YXJzW3R5cGUgKyBcIlBhcmFtc1wiXSA9IHBhcmFtcyk7XG4gICAgICAgIHR5cGUgPT09IFwib25VcGRhdGVcIiAmJiAodGhpcy5fb25VcGRhdGUgPSBjYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB2YXJzW3R5cGVdO1xuICB9O1xuXG4gIF9wcm90by50aGVuID0gZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxlZCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIHZhciBmID0gX2lzRnVuY3Rpb24ob25GdWxmaWxsZWQpID8gb25GdWxmaWxsZWQgOiBfcGFzc1Rocm91Z2gsXG4gICAgICAgICAgX3Jlc29sdmUgPSBmdW5jdGlvbiBfcmVzb2x2ZSgpIHtcbiAgICAgICAgdmFyIF90aGVuID0gc2VsZi50aGVuO1xuICAgICAgICBzZWxmLnRoZW4gPSBudWxsOyAvLyB0ZW1wb3JhcmlseSBudWxsIHRoZSB0aGVuKCkgbWV0aG9kIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3AgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ3JlZW5zb2NrL0dTQVAvaXNzdWVzLzMyMilcblxuICAgICAgICBfaXNGdW5jdGlvbihmKSAmJiAoZiA9IGYoc2VsZikpICYmIChmLnRoZW4gfHwgZiA9PT0gc2VsZikgJiYgKHNlbGYudGhlbiA9IF90aGVuKTtcbiAgICAgICAgcmVzb2x2ZShmKTtcbiAgICAgICAgc2VsZi50aGVuID0gX3RoZW47XG4gICAgICB9O1xuXG4gICAgICBpZiAoc2VsZi5faW5pdHRlZCAmJiBzZWxmLnRvdGFsUHJvZ3Jlc3MoKSA9PT0gMSAmJiBzZWxmLl90cyA+PSAwIHx8ICFzZWxmLl90VGltZSAmJiBzZWxmLl90cyA8IDApIHtcbiAgICAgICAgX3Jlc29sdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYuX3Byb20gPSBfcmVzb2x2ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBfcHJvdG8ua2lsbCA9IGZ1bmN0aW9uIGtpbGwoKSB7XG4gICAgX2ludGVycnVwdCh0aGlzKTtcbiAgfTtcblxuICByZXR1cm4gQW5pbWF0aW9uO1xufSgpO1xuXG5fc2V0RGVmYXVsdHMoQW5pbWF0aW9uLnByb3RvdHlwZSwge1xuICBfdGltZTogMCxcbiAgX3N0YXJ0OiAwLFxuICBfZW5kOiAwLFxuICBfdFRpbWU6IDAsXG4gIF90RHVyOiAwLFxuICBfZGlydHk6IDAsXG4gIF9yZXBlYXQ6IDAsXG4gIF95b3lvOiBmYWxzZSxcbiAgcGFyZW50OiBudWxsLFxuICBfaW5pdHRlZDogZmFsc2UsXG4gIF9yRGVsYXk6IDAsXG4gIF90czogMSxcbiAgX2RwOiAwLFxuICByYXRpbzogMCxcbiAgX3pUaW1lOiAtX3RpbnlOdW0sXG4gIF9wcm9tOiAwLFxuICBfcHM6IGZhbHNlLFxuICBfcnRzOiAxXG59KTtcbi8qXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBUSU1FTElORVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuZXhwb3J0IHZhciBUaW1lbGluZSA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0FuaW1hdGlvbikge1xuICBfaW5oZXJpdHNMb29zZShUaW1lbGluZSwgX0FuaW1hdGlvbik7XG5cbiAgZnVuY3Rpb24gVGltZWxpbmUodmFycywgcG9zaXRpb24pIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBpZiAodmFycyA9PT0gdm9pZCAwKSB7XG4gICAgICB2YXJzID0ge307XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfQW5pbWF0aW9uLmNhbGwodGhpcywgdmFycykgfHwgdGhpcztcbiAgICBfdGhpcy5sYWJlbHMgPSB7fTtcbiAgICBfdGhpcy5zbW9vdGhDaGlsZFRpbWluZyA9ICEhdmFycy5zbW9vdGhDaGlsZFRpbWluZztcbiAgICBfdGhpcy5hdXRvUmVtb3ZlQ2hpbGRyZW4gPSAhIXZhcnMuYXV0b1JlbW92ZUNoaWxkcmVuO1xuICAgIF90aGlzLl9zb3J0ID0gX2lzTm90RmFsc2UodmFycy5zb3J0Q2hpbGRyZW4pO1xuICAgIF9nbG9iYWxUaW1lbGluZSAmJiBfYWRkVG9UaW1lbGluZSh2YXJzLnBhcmVudCB8fCBfZ2xvYmFsVGltZWxpbmUsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBwb3NpdGlvbik7XG4gICAgdmFycy5yZXZlcnNlZCAmJiBfdGhpcy5yZXZlcnNlKCk7XG4gICAgdmFycy5wYXVzZWQgJiYgX3RoaXMucGF1c2VkKHRydWUpO1xuICAgIHZhcnMuc2Nyb2xsVHJpZ2dlciAmJiBfc2Nyb2xsVHJpZ2dlcihfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgdmFycy5zY3JvbGxUcmlnZ2VyKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICB2YXIgX3Byb3RvMiA9IFRpbWVsaW5lLnByb3RvdHlwZTtcblxuICBfcHJvdG8yLnRvID0gZnVuY3Rpb24gdG8odGFyZ2V0cywgdmFycywgcG9zaXRpb24pIHtcbiAgICBfY3JlYXRlVHdlZW5UeXBlKDAsIGFyZ3VtZW50cywgdGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmZyb20gPSBmdW5jdGlvbiBmcm9tKHRhcmdldHMsIHZhcnMsIHBvc2l0aW9uKSB7XG4gICAgX2NyZWF0ZVR3ZWVuVHlwZSgxLCBhcmd1bWVudHMsIHRoaXMpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMi5mcm9tVG8gPSBmdW5jdGlvbiBmcm9tVG8odGFyZ2V0cywgZnJvbVZhcnMsIHRvVmFycywgcG9zaXRpb24pIHtcbiAgICBfY3JlYXRlVHdlZW5UeXBlKDIsIGFyZ3VtZW50cywgdGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLnNldCA9IGZ1bmN0aW9uIHNldCh0YXJnZXRzLCB2YXJzLCBwb3NpdGlvbikge1xuICAgIHZhcnMuZHVyYXRpb24gPSAwO1xuICAgIHZhcnMucGFyZW50ID0gdGhpcztcbiAgICBfaW5oZXJpdERlZmF1bHRzKHZhcnMpLnJlcGVhdERlbGF5IHx8ICh2YXJzLnJlcGVhdCA9IDApO1xuICAgIHZhcnMuaW1tZWRpYXRlUmVuZGVyID0gISF2YXJzLmltbWVkaWF0ZVJlbmRlcjtcbiAgICBuZXcgVHdlZW4odGFyZ2V0cywgdmFycywgX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pLCAxKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmNhbGwgPSBmdW5jdGlvbiBjYWxsKGNhbGxiYWNrLCBwYXJhbXMsIHBvc2l0aW9uKSB7XG4gICAgcmV0dXJuIF9hZGRUb1RpbWVsaW5lKHRoaXMsIFR3ZWVuLmRlbGF5ZWRDYWxsKDAsIGNhbGxiYWNrLCBwYXJhbXMpLCBwb3NpdGlvbik7XG4gIH0gLy9PTkxZIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5ISBNYXliZSBkZWxldGU/XG4gIDtcblxuICBfcHJvdG8yLnN0YWdnZXJUbyA9IGZ1bmN0aW9uIHN0YWdnZXJUbyh0YXJnZXRzLCBkdXJhdGlvbiwgdmFycywgc3RhZ2dlciwgcG9zaXRpb24sIG9uQ29tcGxldGVBbGwsIG9uQ29tcGxldGVBbGxQYXJhbXMpIHtcbiAgICB2YXJzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgdmFycy5zdGFnZ2VyID0gdmFycy5zdGFnZ2VyIHx8IHN0YWdnZXI7XG4gICAgdmFycy5vbkNvbXBsZXRlID0gb25Db21wbGV0ZUFsbDtcbiAgICB2YXJzLm9uQ29tcGxldGVQYXJhbXMgPSBvbkNvbXBsZXRlQWxsUGFyYW1zO1xuICAgIHZhcnMucGFyZW50ID0gdGhpcztcbiAgICBuZXcgVHdlZW4odGFyZ2V0cywgdmFycywgX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLnN0YWdnZXJGcm9tID0gZnVuY3Rpb24gc3RhZ2dlckZyb20odGFyZ2V0cywgZHVyYXRpb24sIHZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKSB7XG4gICAgdmFycy5ydW5CYWNrd2FyZHMgPSAxO1xuICAgIF9pbmhlcml0RGVmYXVsdHModmFycykuaW1tZWRpYXRlUmVuZGVyID0gX2lzTm90RmFsc2UodmFycy5pbW1lZGlhdGVSZW5kZXIpO1xuICAgIHJldHVybiB0aGlzLnN0YWdnZXJUbyh0YXJnZXRzLCBkdXJhdGlvbiwgdmFycywgc3RhZ2dlciwgcG9zaXRpb24sIG9uQ29tcGxldGVBbGwsIG9uQ29tcGxldGVBbGxQYXJhbXMpO1xuICB9O1xuXG4gIF9wcm90bzIuc3RhZ2dlckZyb21UbyA9IGZ1bmN0aW9uIHN0YWdnZXJGcm9tVG8odGFyZ2V0cywgZHVyYXRpb24sIGZyb21WYXJzLCB0b1ZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKSB7XG4gICAgdG9WYXJzLnN0YXJ0QXQgPSBmcm9tVmFycztcbiAgICBfaW5oZXJpdERlZmF1bHRzKHRvVmFycykuaW1tZWRpYXRlUmVuZGVyID0gX2lzTm90RmFsc2UodG9WYXJzLmltbWVkaWF0ZVJlbmRlcik7XG4gICAgcmV0dXJuIHRoaXMuc3RhZ2dlclRvKHRhcmdldHMsIGR1cmF0aW9uLCB0b1ZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKTtcbiAgfTtcblxuICBfcHJvdG8yLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICAgIHZhciBwcmV2VGltZSA9IHRoaXMuX3RpbWUsXG4gICAgICAgIHREdXIgPSB0aGlzLl9kaXJ0eSA/IHRoaXMudG90YWxEdXJhdGlvbigpIDogdGhpcy5fdER1cixcbiAgICAgICAgZHVyID0gdGhpcy5fZHVyLFxuICAgICAgICB0VGltZSA9IHRvdGFsVGltZSA8PSAwID8gMCA6IF9yb3VuZFByZWNpc2UodG90YWxUaW1lKSxcbiAgICAgICAgLy8gaWYgYSBwYXVzZWQgdGltZWxpbmUgaXMgcmVzdW1lZCAob3IgaXRzIF9zdGFydCBpcyB1cGRhdGVkIGZvciBhbm90aGVyIHJlYXNvbi4uLndoaWNoIHJvdW5kcyBpdCksIHRoYXQgY291bGQgcmVzdWx0IGluIHRoZSBwbGF5aGVhZCBzaGlmdGluZyBhICoqdGlueSoqIGFtb3VudCBhbmQgYSB6ZXJvLWR1cmF0aW9uIGNoaWxkIGF0IHRoYXQgc3BvdCBtYXkgZ2V0IHJlbmRlcmVkIGF0IGEgZGlmZmVyZW50IHJhdGlvLCBsaWtlIGl0cyB0b3RhbFRpbWUgaW4gcmVuZGVyKCkgbWF5IGJlIDFlLTE3IGluc3RlYWQgb2YgMCwgZm9yIGV4YW1wbGUuXG4gICAgY3Jvc3NpbmdTdGFydCA9IHRoaXMuX3pUaW1lIDwgMCAhPT0gdG90YWxUaW1lIDwgMCAmJiAodGhpcy5faW5pdHRlZCB8fCAhZHVyKSxcbiAgICAgICAgdGltZSxcbiAgICAgICAgY2hpbGQsXG4gICAgICAgIG5leHQsXG4gICAgICAgIGl0ZXJhdGlvbixcbiAgICAgICAgY3ljbGVEdXJhdGlvbixcbiAgICAgICAgcHJldlBhdXNlZCxcbiAgICAgICAgcGF1c2VUd2VlbixcbiAgICAgICAgdGltZVNjYWxlLFxuICAgICAgICBwcmV2U3RhcnQsXG4gICAgICAgIHByZXZJdGVyYXRpb24sXG4gICAgICAgIHlveW8sXG4gICAgICAgIGlzWW95bztcbiAgICB0aGlzICE9PSBfZ2xvYmFsVGltZWxpbmUgJiYgdFRpbWUgPiB0RHVyICYmIHRvdGFsVGltZSA+PSAwICYmICh0VGltZSA9IHREdXIpO1xuXG4gICAgaWYgKHRUaW1lICE9PSB0aGlzLl90VGltZSB8fCBmb3JjZSB8fCBjcm9zc2luZ1N0YXJ0KSB7XG4gICAgICBpZiAocHJldlRpbWUgIT09IHRoaXMuX3RpbWUgJiYgZHVyKSB7XG4gICAgICAgIC8vaWYgdG90YWxEdXJhdGlvbigpIGZpbmRzIGEgY2hpbGQgd2l0aCBhIG5lZ2F0aXZlIHN0YXJ0VGltZSBhbmQgc21vb3RoQ2hpbGRUaW1pbmcgaXMgdHJ1ZSwgdGhpbmdzIGdldCBzaGlmdGVkIGFyb3VuZCBpbnRlcm5hbGx5IHNvIHdlIG5lZWQgdG8gYWRqdXN0IHRoZSB0aW1lIGFjY29yZGluZ2x5LiBGb3IgZXhhbXBsZSwgaWYgYSB0d2VlbiBzdGFydHMgYXQgLTMwIHdlIG11c3Qgc2hpZnQgRVZFUllUSElORyBmb3J3YXJkIDMwIHNlY29uZHMgYW5kIG1vdmUgdGhpcyB0aW1lbGluZSdzIHN0YXJ0VGltZSBiYWNrd2FyZCBieSAzMCBzZWNvbmRzIHNvIHRoYXQgdGhpbmdzIGFsaWduIHdpdGggdGhlIHBsYXloZWFkIChubyBqdW1wKS5cbiAgICAgICAgdFRpbWUgKz0gdGhpcy5fdGltZSAtIHByZXZUaW1lO1xuICAgICAgICB0b3RhbFRpbWUgKz0gdGhpcy5fdGltZSAtIHByZXZUaW1lO1xuICAgICAgfVxuXG4gICAgICB0aW1lID0gdFRpbWU7XG4gICAgICBwcmV2U3RhcnQgPSB0aGlzLl9zdGFydDtcbiAgICAgIHRpbWVTY2FsZSA9IHRoaXMuX3RzO1xuICAgICAgcHJldlBhdXNlZCA9ICF0aW1lU2NhbGU7XG5cbiAgICAgIGlmIChjcm9zc2luZ1N0YXJ0KSB7XG4gICAgICAgIGR1ciB8fCAocHJldlRpbWUgPSB0aGlzLl96VGltZSk7IC8vd2hlbiB0aGUgcGxheWhlYWQgYXJyaXZlcyBhdCBFWEFDVExZIHRpbWUgMCAocmlnaHQgb24gdG9wKSBvZiBhIHplcm8tZHVyYXRpb24gdGltZWxpbmUsIHdlIG5lZWQgdG8gZGlzY2VybiBpZiBldmVudHMgYXJlIHN1cHByZXNzZWQgc28gdGhhdCB3aGVuIHRoZSBwbGF5aGVhZCBtb3ZlcyBhZ2FpbiAobmV4dCB0aW1lKSwgaXQnbGwgdHJpZ2dlciB0aGUgY2FsbGJhY2suIElmIGV2ZW50cyBhcmUgTk9UIHN1cHByZXNzZWQsIG9idmlvdXNseSB0aGUgY2FsbGJhY2sgd291bGQgYmUgdHJpZ2dlcmVkIGluIHRoaXMgcmVuZGVyLiBCYXNpY2FsbHksIHRoZSBjYWxsYmFjayBzaG91bGQgZmlyZSBlaXRoZXIgd2hlbiB0aGUgcGxheWhlYWQgQVJSSVZFUyBvciBMRUFWRVMgdGhpcyBleGFjdCBzcG90LCBub3QgYm90aC4gSW1hZ2luZSBkb2luZyBhIHRpbWVsaW5lLnNlZWsoMCkgYW5kIHRoZXJlJ3MgYSBjYWxsYmFjayB0aGF0IHNpdHMgYXQgMC4gU2luY2UgZXZlbnRzIGFyZSBzdXBwcmVzc2VkIG9uIHRoYXQgc2VlaygpIGJ5IGRlZmF1bHQsIG5vdGhpbmcgd2lsbCBmaXJlLCBidXQgd2hlbiB0aGUgcGxheWhlYWQgbW92ZXMgb2ZmIG9mIHRoYXQgcG9zaXRpb24sIHRoZSBjYWxsYmFjayBzaG91bGQgZmlyZS4gVGhpcyBiZWhhdmlvciBpcyB3aGF0IHBlb3BsZSBpbnR1aXRpdmVseSBleHBlY3QuXG5cbiAgICAgICAgKHRvdGFsVGltZSB8fCAhc3VwcHJlc3NFdmVudHMpICYmICh0aGlzLl96VGltZSA9IHRvdGFsVGltZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9yZXBlYXQpIHtcbiAgICAgICAgLy9hZGp1c3QgdGhlIHRpbWUgZm9yIHJlcGVhdHMgYW5kIHlveW9zXG4gICAgICAgIHlveW8gPSB0aGlzLl95b3lvO1xuICAgICAgICBjeWNsZUR1cmF0aW9uID0gZHVyICsgdGhpcy5fckRlbGF5O1xuXG4gICAgICAgIGlmICh0aGlzLl9yZXBlYXQgPCAtMSAmJiB0b3RhbFRpbWUgPCAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudG90YWxUaW1lKGN5Y2xlRHVyYXRpb24gKiAxMDAgKyB0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aW1lID0gX3JvdW5kUHJlY2lzZSh0VGltZSAlIGN5Y2xlRHVyYXRpb24pOyAvL3JvdW5kIHRvIGF2b2lkIGZsb2F0aW5nIHBvaW50IGVycm9ycy4gKDQgJSAwLjggc2hvdWxkIGJlIDAgYnV0IHNvbWUgYnJvd3NlcnMgcmVwb3J0IGl0IGFzIDAuNzk5OTk5OTkhKVxuXG4gICAgICAgIGlmICh0VGltZSA9PT0gdER1cikge1xuICAgICAgICAgIC8vIHRoZSB0RHVyID09PSB0VGltZSBpcyBmb3IgZWRnZSBjYXNlcyB3aGVyZSB0aGVyZSdzIGEgbGVuZ3RoeSBkZWNpbWFsIG9uIHRoZSBkdXJhdGlvbiBhbmQgaXQgbWF5IHJlYWNoIHRoZSB2ZXJ5IGVuZCBidXQgdGhlIHRpbWUgaXMgcmVuZGVyZWQgYXMgbm90LXF1aXRlLXRoZXJlIChyZW1lbWJlciwgdER1ciBpcyByb3VuZGVkIHRvIDQgZGVjaW1hbHMgd2hlcmVhcyBkdXIgaXNuJ3QpXG4gICAgICAgICAgaXRlcmF0aW9uID0gdGhpcy5fcmVwZWF0O1xuICAgICAgICAgIHRpbWUgPSBkdXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlcmF0aW9uID0gfn4odFRpbWUgLyBjeWNsZUR1cmF0aW9uKTtcblxuICAgICAgICAgIGlmIChpdGVyYXRpb24gJiYgaXRlcmF0aW9uID09PSB0VGltZSAvIGN5Y2xlRHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRpbWUgPSBkdXI7XG4gICAgICAgICAgICBpdGVyYXRpb24tLTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aW1lID4gZHVyICYmICh0aW1lID0gZHVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZJdGVyYXRpb24gPSBfYW5pbWF0aW9uQ3ljbGUodGhpcy5fdFRpbWUsIGN5Y2xlRHVyYXRpb24pO1xuICAgICAgICAhcHJldlRpbWUgJiYgdGhpcy5fdFRpbWUgJiYgcHJldkl0ZXJhdGlvbiAhPT0gaXRlcmF0aW9uICYmIHRoaXMuX3RUaW1lIC0gcHJldkl0ZXJhdGlvbiAqIGN5Y2xlRHVyYXRpb24gLSB0aGlzLl9kdXIgPD0gMCAmJiAocHJldkl0ZXJhdGlvbiA9IGl0ZXJhdGlvbik7IC8vIGVkZ2UgY2FzZSAtIGlmIHNvbWVvbmUgZG9lcyBhZGRQYXVzZSgpIGF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBvZiBhIHJlcGVhdGluZyB0aW1lbGluZSwgdGhhdCBwYXVzZSBpcyB0ZWNobmljYWxseSBhdCB0aGUgc2FtZSBzcG90IGFzIHRoZSBlbmQgd2hpY2ggY2F1c2VzIHRoaXMuX3RpbWUgdG8gZ2V0IHNldCB0byAwIHdoZW4gdGhlIHRvdGFsVGltZSB3b3VsZCBub3JtYWxseSBwbGFjZSB0aGUgcGxheWhlYWQgYXQgdGhlIGVuZC4gU2VlIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9mb3J1bXMvdG9waWMvMjM4MjMtY2xvc2luZy1uYXYtYW5pbWF0aW9uLW5vdC13b3JraW5nLW9uLWllLWFuZC1pcGhvbmUtNi1tYXliZS1vdGhlci1vbGRlci1icm93c2VyLz90YWI9Y29tbWVudHMjY29tbWVudC0xMTMwMDUgYWxzbywgdGhpcy5fdFRpbWUgLSBwcmV2SXRlcmF0aW9uICogY3ljbGVEdXJhdGlvbiAtIHRoaXMuX2R1ciA8PSAwIGp1c3QgY2hlY2tzIHRvIG1ha2Ugc3VyZSBpdCB3YXNuJ3QgcHJldmlvdXNseSBpbiB0aGUgXCJyZXBlYXREZWxheVwiIHBvcnRpb25cblxuICAgICAgICBpZiAoeW95byAmJiBpdGVyYXRpb24gJiAxKSB7XG4gICAgICAgICAgdGltZSA9IGR1ciAtIHRpbWU7XG4gICAgICAgICAgaXNZb3lvID0gMTtcbiAgICAgICAgfVxuICAgICAgICAvKlxuICAgICAgICBtYWtlIHN1cmUgY2hpbGRyZW4gYXQgdGhlIGVuZC9iZWdpbm5pbmcgb2YgdGhlIHRpbWVsaW5lIGFyZSByZW5kZXJlZCBwcm9wZXJseS4gSWYsIGZvciBleGFtcGxlLFxuICAgICAgICBhIDMtc2Vjb25kIGxvbmcgdGltZWxpbmUgcmVuZGVyZWQgYXQgMi45IHNlY29uZHMgcHJldmlvdXNseSwgYW5kIG5vdyByZW5kZXJzIGF0IDMuMiBzZWNvbmRzICh3aGljaFxuICAgICAgICB3b3VsZCBnZXQgdHJhbnNsYXRlZCB0byAyLjggc2Vjb25kcyBpZiB0aGUgdGltZWxpbmUgeW95b3Mgb3IgMC4yIHNlY29uZHMgaWYgaXQganVzdCByZXBlYXRzKSwgdGhlcmVcbiAgICAgICAgY291bGQgYmUgYSBjYWxsYmFjayBvciBhIHNob3J0IHR3ZWVuIHRoYXQncyBhdCAyLjk1IG9yIDMgc2Vjb25kcyBpbiB3aGljaCB3b3VsZG4ndCByZW5kZXIuIFNvXG4gICAgICAgIHdlIG5lZWQgdG8gcHVzaCB0aGUgdGltZWxpbmUgdG8gdGhlIGVuZCAoYW5kL29yIGJlZ2lubmluZyBkZXBlbmRpbmcgb24gaXRzIHlveW8gdmFsdWUpLiBBbHNvIHdlIG11c3RcbiAgICAgICAgZW5zdXJlIHRoYXQgemVyby1kdXJhdGlvbiB0d2VlbnMgYXQgdGhlIHZlcnkgYmVnaW5uaW5nIG9yIGVuZCBvZiB0aGUgVGltZWxpbmUgd29yay5cbiAgICAgICAgKi9cblxuXG4gICAgICAgIGlmIChpdGVyYXRpb24gIT09IHByZXZJdGVyYXRpb24gJiYgIXRoaXMuX2xvY2spIHtcbiAgICAgICAgICB2YXIgcmV3aW5kaW5nID0geW95byAmJiBwcmV2SXRlcmF0aW9uICYgMSxcbiAgICAgICAgICAgICAgZG9lc1dyYXAgPSByZXdpbmRpbmcgPT09ICh5b3lvICYmIGl0ZXJhdGlvbiAmIDEpO1xuICAgICAgICAgIGl0ZXJhdGlvbiA8IHByZXZJdGVyYXRpb24gJiYgKHJld2luZGluZyA9ICFyZXdpbmRpbmcpO1xuICAgICAgICAgIHByZXZUaW1lID0gcmV3aW5kaW5nID8gMCA6IGR1cjtcbiAgICAgICAgICB0aGlzLl9sb2NrID0gMTtcbiAgICAgICAgICB0aGlzLnJlbmRlcihwcmV2VGltZSB8fCAoaXNZb3lvID8gMCA6IF9yb3VuZFByZWNpc2UoaXRlcmF0aW9uICogY3ljbGVEdXJhdGlvbikpLCBzdXBwcmVzc0V2ZW50cywgIWR1cikuX2xvY2sgPSAwO1xuICAgICAgICAgIHRoaXMuX3RUaW1lID0gdFRpbWU7IC8vIGlmIGEgdXNlciBnZXRzIHRoZSBpdGVyYXRpb24oKSBpbnNpZGUgdGhlIG9uUmVwZWF0LCBmb3IgZXhhbXBsZSwgaXQgc2hvdWxkIGJlIGFjY3VyYXRlLlxuXG4gICAgICAgICAgIXN1cHByZXNzRXZlbnRzICYmIHRoaXMucGFyZW50ICYmIF9jYWxsYmFjayh0aGlzLCBcIm9uUmVwZWF0XCIpO1xuICAgICAgICAgIHRoaXMudmFycy5yZXBlYXRSZWZyZXNoICYmICFpc1lveW8gJiYgKHRoaXMuaW52YWxpZGF0ZSgpLl9sb2NrID0gMSk7XG5cbiAgICAgICAgICBpZiAocHJldlRpbWUgJiYgcHJldlRpbWUgIT09IHRoaXMuX3RpbWUgfHwgcHJldlBhdXNlZCAhPT0gIXRoaXMuX3RzIHx8IHRoaXMudmFycy5vblJlcGVhdCAmJiAhdGhpcy5wYXJlbnQgJiYgIXRoaXMuX2FjdCkge1xuICAgICAgICAgICAgLy8gaWYgcHJldlRpbWUgaXMgMCBhbmQgd2UgcmVuZGVyIGF0IHRoZSB2ZXJ5IGVuZCwgX3RpbWUgd2lsbCBiZSB0aGUgZW5kLCB0aHVzIHdvbid0IG1hdGNoLiBTbyBpbiB0aGlzIGVkZ2UgY2FzZSwgcHJldlRpbWUgd29uJ3QgbWF0Y2ggX3RpbWUgYnV0IHRoYXQncyBva2F5LiBJZiBpdCBnZXRzIGtpbGxlZCBpbiB0aGUgb25SZXBlYXQsIGVqZWN0IGFzIHdlbGwuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkdXIgPSB0aGlzLl9kdXI7IC8vIGluIGNhc2UgdGhlIGR1cmF0aW9uIGNoYW5nZWQgaW4gdGhlIG9uUmVwZWF0XG5cbiAgICAgICAgICB0RHVyID0gdGhpcy5fdER1cjtcblxuICAgICAgICAgIGlmIChkb2VzV3JhcCkge1xuICAgICAgICAgICAgdGhpcy5fbG9jayA9IDI7XG4gICAgICAgICAgICBwcmV2VGltZSA9IHJld2luZGluZyA/IGR1ciA6IC0wLjAwMDE7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcihwcmV2VGltZSwgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnZhcnMucmVwZWF0UmVmcmVzaCAmJiAhaXNZb3lvICYmIHRoaXMuaW52YWxpZGF0ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2xvY2sgPSAwO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLl90cyAmJiAhcHJldlBhdXNlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgfSAvL2luIG9yZGVyIGZvciB5b3lvRWFzZSB0byB3b3JrIHByb3Blcmx5IHdoZW4gdGhlcmUncyBhIHN0YWdnZXIsIHdlIG11c3Qgc3dhcCBvdXQgdGhlIGVhc2UgaW4gZWFjaCBzdWItdHdlZW4uXG5cblxuICAgICAgICAgIF9wcm9wYWdhdGVZb3lvRWFzZSh0aGlzLCBpc1lveW8pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9oYXNQYXVzZSAmJiAhdGhpcy5fZm9yY2luZyAmJiB0aGlzLl9sb2NrIDwgMikge1xuICAgICAgICBwYXVzZVR3ZWVuID0gX2ZpbmROZXh0UGF1c2VUd2Vlbih0aGlzLCBfcm91bmRQcmVjaXNlKHByZXZUaW1lKSwgX3JvdW5kUHJlY2lzZSh0aW1lKSk7XG5cbiAgICAgICAgaWYgKHBhdXNlVHdlZW4pIHtcbiAgICAgICAgICB0VGltZSAtPSB0aW1lIC0gKHRpbWUgPSBwYXVzZVR3ZWVuLl9zdGFydCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fdFRpbWUgPSB0VGltZTtcbiAgICAgIHRoaXMuX3RpbWUgPSB0aW1lO1xuICAgICAgdGhpcy5fYWN0ID0gIXRpbWVTY2FsZTsgLy9hcyBsb25nIGFzIGl0J3Mgbm90IHBhdXNlZCwgZm9yY2UgaXQgdG8gYmUgYWN0aXZlIHNvIHRoYXQgaWYgdGhlIHVzZXIgcmVuZGVycyBpbmRlcGVuZGVudCBvZiB0aGUgcGFyZW50IHRpbWVsaW5lLCBpdCdsbCBiZSBmb3JjZWQgdG8gcmUtcmVuZGVyIG9uIHRoZSBuZXh0IHRpY2suXG5cbiAgICAgIGlmICghdGhpcy5faW5pdHRlZCkge1xuICAgICAgICB0aGlzLl9vblVwZGF0ZSA9IHRoaXMudmFycy5vblVwZGF0ZTtcbiAgICAgICAgdGhpcy5faW5pdHRlZCA9IDE7XG4gICAgICAgIHRoaXMuX3pUaW1lID0gdG90YWxUaW1lO1xuICAgICAgICBwcmV2VGltZSA9IDA7IC8vIHVwb24gaW5pdCwgdGhlIHBsYXloZWFkIHNob3VsZCBhbHdheXMgZ28gZm9yd2FyZDsgc29tZW9uZSBjb3VsZCBpbnZhbGlkYXRlKCkgYSBjb21wbGV0ZWQgdGltZWxpbmUgYW5kIHRoZW4gaWYgdGhleSByZXN0YXJ0KCksIHRoYXQgd291bGQgbWFrZSBjaGlsZCB0d2VlbnMgcmVuZGVyIGluIHJldmVyc2Ugb3JkZXIgd2hpY2ggY291bGQgbG9jayBpbiB0aGUgd3Jvbmcgc3RhcnRpbmcgdmFsdWVzIGlmIHRoZXkgYnVpbGQgb24gZWFjaCBvdGhlciwgbGlrZSB0bC50byhvYmosIHt4OiAxMDB9KS50byhvYmosIHt4OiAwfSkuXG4gICAgICB9XG5cbiAgICAgIGlmICghcHJldlRpbWUgJiYgdGltZSAmJiAhc3VwcHJlc3NFdmVudHMgJiYgIWl0ZXJhdGlvbikge1xuICAgICAgICBfY2FsbGJhY2sodGhpcywgXCJvblN0YXJ0XCIpO1xuXG4gICAgICAgIGlmICh0aGlzLl90VGltZSAhPT0gdFRpbWUpIHtcbiAgICAgICAgICAvLyBpbiBjYXNlIHRoZSBvblN0YXJ0IHRyaWdnZXJlZCBhIHJlbmRlciBhdCBhIGRpZmZlcmVudCBzcG90LCBlamVjdC4gTGlrZSBpZiBzb21lb25lIGRpZCBhbmltYXRpb24ucGF1c2UoMC41KSBvciBzb21ldGhpbmcgaW5zaWRlIHRoZSBvblN0YXJ0LlxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aW1lID49IHByZXZUaW1lICYmIHRvdGFsVGltZSA+PSAwKSB7XG4gICAgICAgIGNoaWxkID0gdGhpcy5fZmlyc3Q7XG5cbiAgICAgICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICAgICAgbmV4dCA9IGNoaWxkLl9uZXh0O1xuXG4gICAgICAgICAgaWYgKChjaGlsZC5fYWN0IHx8IHRpbWUgPj0gY2hpbGQuX3N0YXJ0KSAmJiBjaGlsZC5fdHMgJiYgcGF1c2VUd2VlbiAhPT0gY2hpbGQpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5wYXJlbnQgIT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgLy8gYW4gZXh0cmVtZSBlZGdlIGNhc2UgLSB0aGUgY2hpbGQncyByZW5kZXIgY291bGQgZG8gc29tZXRoaW5nIGxpa2Uga2lsbCgpIHRoZSBcIm5leHRcIiBvbmUgaW4gdGhlIGxpbmtlZCBsaXN0LCBvciByZXBhcmVudCBpdC4gSW4gdGhhdCBjYXNlIHdlIG11c3QgcmUtaW5pdGlhdGUgdGhlIHdob2xlIHJlbmRlciB0byBiZSBzYWZlLlxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXIodG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjaGlsZC5yZW5kZXIoY2hpbGQuX3RzID4gMCA/ICh0aW1lIC0gY2hpbGQuX3N0YXJ0KSAqIGNoaWxkLl90cyA6IChjaGlsZC5fZGlydHkgPyBjaGlsZC50b3RhbER1cmF0aW9uKCkgOiBjaGlsZC5fdER1cikgKyAodGltZSAtIGNoaWxkLl9zdGFydCkgKiBjaGlsZC5fdHMsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG5cbiAgICAgICAgICAgIGlmICh0aW1lICE9PSB0aGlzLl90aW1lIHx8ICF0aGlzLl90cyAmJiAhcHJldlBhdXNlZCkge1xuICAgICAgICAgICAgICAvL2luIGNhc2UgYSB0d2VlbiBwYXVzZXMgb3Igc2Vla3MgdGhlIHRpbWVsaW5lIHdoZW4gcmVuZGVyaW5nLCBsaWtlIGluc2lkZSBvZiBhbiBvblVwZGF0ZS9vbkNvbXBsZXRlXG4gICAgICAgICAgICAgIHBhdXNlVHdlZW4gPSAwO1xuICAgICAgICAgICAgICBuZXh0ICYmICh0VGltZSArPSB0aGlzLl96VGltZSA9IC1fdGlueU51bSk7IC8vIGl0IGRpZG4ndCBmaW5pc2ggcmVuZGVyaW5nLCBzbyBmbGFnIHpUaW1lIGFzIG5lZ2F0aXZlIHNvIHRoYXQgc28gdGhhdCB0aGUgbmV4dCB0aW1lIHJlbmRlcigpIGlzIGNhbGxlZCBpdCdsbCBiZSBmb3JjZWQgKHRvIHJlbmRlciBhbnkgcmVtYWluaW5nIGNoaWxkcmVuKVxuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNoaWxkID0gbmV4dDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGQgPSB0aGlzLl9sYXN0O1xuICAgICAgICB2YXIgYWRqdXN0ZWRUaW1lID0gdG90YWxUaW1lIDwgMCA/IHRvdGFsVGltZSA6IHRpbWU7IC8vd2hlbiB0aGUgcGxheWhlYWQgZ29lcyBiYWNrd2FyZCBiZXlvbmQgdGhlIHN0YXJ0IG9mIHRoaXMgdGltZWxpbmUsIHdlIG11c3QgcGFzcyB0aGF0IGluZm9ybWF0aW9uIGRvd24gdG8gdGhlIGNoaWxkIGFuaW1hdGlvbnMgc28gdGhhdCB6ZXJvLWR1cmF0aW9uIHR3ZWVucyBrbm93IHdoZXRoZXIgdG8gcmVuZGVyIHRoZWlyIHN0YXJ0aW5nIG9yIGVuZGluZyB2YWx1ZXMuXG5cbiAgICAgICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICAgICAgbmV4dCA9IGNoaWxkLl9wcmV2O1xuXG4gICAgICAgICAgaWYgKChjaGlsZC5fYWN0IHx8IGFkanVzdGVkVGltZSA8PSBjaGlsZC5fZW5kKSAmJiBjaGlsZC5fdHMgJiYgcGF1c2VUd2VlbiAhPT0gY2hpbGQpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5wYXJlbnQgIT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgLy8gYW4gZXh0cmVtZSBlZGdlIGNhc2UgLSB0aGUgY2hpbGQncyByZW5kZXIgY291bGQgZG8gc29tZXRoaW5nIGxpa2Uga2lsbCgpIHRoZSBcIm5leHRcIiBvbmUgaW4gdGhlIGxpbmtlZCBsaXN0LCBvciByZXBhcmVudCBpdC4gSW4gdGhhdCBjYXNlIHdlIG11c3QgcmUtaW5pdGlhdGUgdGhlIHdob2xlIHJlbmRlciB0byBiZSBzYWZlLlxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXIodG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjaGlsZC5yZW5kZXIoY2hpbGQuX3RzID4gMCA/IChhZGp1c3RlZFRpbWUgLSBjaGlsZC5fc3RhcnQpICogY2hpbGQuX3RzIDogKGNoaWxkLl9kaXJ0eSA/IGNoaWxkLnRvdGFsRHVyYXRpb24oKSA6IGNoaWxkLl90RHVyKSArIChhZGp1c3RlZFRpbWUgLSBjaGlsZC5fc3RhcnQpICogY2hpbGQuX3RzLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UgfHwgX3JldmVydGluZyAmJiAoY2hpbGQuX2luaXR0ZWQgfHwgY2hpbGQuX3N0YXJ0QXQpKTsgLy8gaWYgcmV2ZXJ0aW5nLCB3ZSBzaG91bGQgYWx3YXlzIGZvcmNlIHJlbmRlcnMgb2YgaW5pdHRlZCB0d2VlbnMgKGJ1dCByZW1lbWJlciB0aGF0IC5mcm9tVG8oKSBvciAuZnJvbSgpIG1heSBoYXZlIGEgX3N0YXJ0QXQgYnV0IG5vdCBfaW5pdHRlZCB5ZXQpLiBJZiwgZm9yIGV4YW1wbGUsIGEgLmZyb21UbygpIHR3ZWVuIHdpdGggYSBzdGFnZ2VyICh3aGljaCBjcmVhdGVzIGFuIGludGVybmFsIHRpbWVsaW5lKSBnZXRzIHJldmVydGVkIEJFRk9SRSBzb21lIG9mIGl0cyBjaGlsZCB0d2VlbnMgcmVuZGVyIGZvciB0aGUgZmlyc3QgdGltZSwgaXQgbWF5IG5vdCBwcm9wZXJseSB0cmlnZ2VyIHRoZW0gdG8gcmV2ZXJ0LlxuXG4gICAgICAgICAgICBpZiAodGltZSAhPT0gdGhpcy5fdGltZSB8fCAhdGhpcy5fdHMgJiYgIXByZXZQYXVzZWQpIHtcbiAgICAgICAgICAgICAgLy9pbiBjYXNlIGEgdHdlZW4gcGF1c2VzIG9yIHNlZWtzIHRoZSB0aW1lbGluZSB3aGVuIHJlbmRlcmluZywgbGlrZSBpbnNpZGUgb2YgYW4gb25VcGRhdGUvb25Db21wbGV0ZVxuICAgICAgICAgICAgICBwYXVzZVR3ZWVuID0gMDtcbiAgICAgICAgICAgICAgbmV4dCAmJiAodFRpbWUgKz0gdGhpcy5felRpbWUgPSBhZGp1c3RlZFRpbWUgPyAtX3RpbnlOdW0gOiBfdGlueU51bSk7IC8vIGl0IGRpZG4ndCBmaW5pc2ggcmVuZGVyaW5nLCBzbyBhZGp1c3QgelRpbWUgc28gdGhhdCBzbyB0aGF0IHRoZSBuZXh0IHRpbWUgcmVuZGVyKCkgaXMgY2FsbGVkIGl0J2xsIGJlIGZvcmNlZCAodG8gcmVuZGVyIGFueSByZW1haW5pbmcgY2hpbGRyZW4pXG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2hpbGQgPSBuZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXVzZVR3ZWVuICYmICFzdXBwcmVzc0V2ZW50cykge1xuICAgICAgICB0aGlzLnBhdXNlKCk7XG4gICAgICAgIHBhdXNlVHdlZW4ucmVuZGVyKHRpbWUgPj0gcHJldlRpbWUgPyAwIDogLV90aW55TnVtKS5felRpbWUgPSB0aW1lID49IHByZXZUaW1lID8gMSA6IC0xO1xuXG4gICAgICAgIGlmICh0aGlzLl90cykge1xuICAgICAgICAgIC8vdGhlIGNhbGxiYWNrIHJlc3VtZWQgcGxheWJhY2shIFNvIHNpbmNlIHdlIG1heSBoYXZlIGhlbGQgYmFjayB0aGUgcGxheWhlYWQgZHVlIHRvIHdoZXJlIHRoZSBwYXVzZSBpcyBwb3NpdGlvbmVkLCBnbyBhaGVhZCBhbmQganVtcCB0byB3aGVyZSBpdCdzIFNVUFBPU0VEIHRvIGJlIChpZiBubyBwYXVzZSBoYXBwZW5lZCkuXG4gICAgICAgICAgdGhpcy5fc3RhcnQgPSBwcmV2U3RhcnQ7IC8vaWYgdGhlIHBhdXNlIHdhcyBhdCBhbiBlYXJsaWVyIHRpbWUgYW5kIHRoZSB1c2VyIHJlc3VtZWQgaW4gdGhlIGNhbGxiYWNrLCBpdCBjb3VsZCByZXBvc2l0aW9uIHRoZSB0aW1lbGluZSAoY2hhbmdpbmcgaXRzIHN0YXJ0VGltZSksIHRocm93aW5nIHRoaW5ncyBvZmYgc2xpZ2h0bHksIHNvIHdlIG1ha2Ugc3VyZSB0aGUgX3N0YXJ0IGRvZXNuJ3Qgc2hpZnQuXG5cbiAgICAgICAgICBfc2V0RW5kKHRoaXMpO1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKHRvdGFsVGltZSwgc3VwcHJlc3NFdmVudHMsIGZvcmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9vblVwZGF0ZSAmJiAhc3VwcHJlc3NFdmVudHMgJiYgX2NhbGxiYWNrKHRoaXMsIFwib25VcGRhdGVcIiwgdHJ1ZSk7XG4gICAgICBpZiAodFRpbWUgPT09IHREdXIgJiYgdGhpcy5fdFRpbWUgPj0gdGhpcy50b3RhbER1cmF0aW9uKCkgfHwgIXRUaW1lICYmIHByZXZUaW1lKSBpZiAocHJldlN0YXJ0ID09PSB0aGlzLl9zdGFydCB8fCBNYXRoLmFicyh0aW1lU2NhbGUpICE9PSBNYXRoLmFicyh0aGlzLl90cykpIGlmICghdGhpcy5fbG9jaykge1xuICAgICAgICAvLyByZW1lbWJlciwgYSBjaGlsZCdzIGNhbGxiYWNrIG1heSBhbHRlciB0aGlzIHRpbWVsaW5lJ3MgcGxheWhlYWQgb3IgdGltZVNjYWxlIHdoaWNoIGlzIHdoeSB3ZSBuZWVkIHRvIGFkZCBzb21lIG9mIHRoZXNlIGNoZWNrcy5cbiAgICAgICAgKHRvdGFsVGltZSB8fCAhZHVyKSAmJiAodFRpbWUgPT09IHREdXIgJiYgdGhpcy5fdHMgPiAwIHx8ICF0VGltZSAmJiB0aGlzLl90cyA8IDApICYmIF9yZW1vdmVGcm9tUGFyZW50KHRoaXMsIDEpOyAvLyBkb24ndCByZW1vdmUgaWYgdGhlIHRpbWVsaW5lIGlzIHJldmVyc2VkIGFuZCB0aGUgcGxheWhlYWQgaXNuJ3QgYXQgMCwgb3RoZXJ3aXNlIHRsLnByb2dyZXNzKDEpLnJldmVyc2UoKSB3b24ndCB3b3JrLiBPbmx5IHJlbW92ZSBpZiB0aGUgcGxheWhlYWQgaXMgYXQgdGhlIGVuZCBhbmQgdGltZVNjYWxlIGlzIHBvc2l0aXZlLCBvciBpZiB0aGUgcGxheWhlYWQgaXMgYXQgMCBhbmQgdGhlIHRpbWVTY2FsZSBpcyBuZWdhdGl2ZS5cblxuICAgICAgICBpZiAoIXN1cHByZXNzRXZlbnRzICYmICEodG90YWxUaW1lIDwgMCAmJiAhcHJldlRpbWUpICYmICh0VGltZSB8fCBwcmV2VGltZSB8fCAhdER1cikpIHtcbiAgICAgICAgICBfY2FsbGJhY2sodGhpcywgdFRpbWUgPT09IHREdXIgJiYgdG90YWxUaW1lID49IDAgPyBcIm9uQ29tcGxldGVcIiA6IFwib25SZXZlcnNlQ29tcGxldGVcIiwgdHJ1ZSk7XG5cbiAgICAgICAgICB0aGlzLl9wcm9tICYmICEodFRpbWUgPCB0RHVyICYmIHRoaXMudGltZVNjYWxlKCkgPiAwKSAmJiB0aGlzLl9wcm9tKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmFkZCA9IGZ1bmN0aW9uIGFkZChjaGlsZCwgcG9zaXRpb24pIHtcbiAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgIF9pc051bWJlcihwb3NpdGlvbikgfHwgKHBvc2l0aW9uID0gX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24sIGNoaWxkKSk7XG5cbiAgICBpZiAoIShjaGlsZCBpbnN0YW5jZW9mIEFuaW1hdGlvbikpIHtcbiAgICAgIGlmIChfaXNBcnJheShjaGlsZCkpIHtcbiAgICAgICAgY2hpbGQuZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzMi5hZGQob2JqLCBwb3NpdGlvbik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgaWYgKF9pc1N0cmluZyhjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGFiZWwoY2hpbGQsIHBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKF9pc0Z1bmN0aW9uKGNoaWxkKSkge1xuICAgICAgICBjaGlsZCA9IFR3ZWVuLmRlbGF5ZWRDYWxsKDAsIGNoaWxkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzICE9PSBjaGlsZCA/IF9hZGRUb1RpbWVsaW5lKHRoaXMsIGNoaWxkLCBwb3NpdGlvbikgOiB0aGlzOyAvL2Rvbid0IGFsbG93IGEgdGltZWxpbmUgdG8gYmUgYWRkZWQgdG8gaXRzZWxmIGFzIGEgY2hpbGQhXG4gIH07XG5cbiAgX3Byb3RvMi5nZXRDaGlsZHJlbiA9IGZ1bmN0aW9uIGdldENoaWxkcmVuKG5lc3RlZCwgdHdlZW5zLCB0aW1lbGluZXMsIGlnbm9yZUJlZm9yZVRpbWUpIHtcbiAgICBpZiAobmVzdGVkID09PSB2b2lkIDApIHtcbiAgICAgIG5lc3RlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHR3ZWVucyA9PT0gdm9pZCAwKSB7XG4gICAgICB0d2VlbnMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aW1lbGluZXMgPT09IHZvaWQgMCkge1xuICAgICAgdGltZWxpbmVzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaWdub3JlQmVmb3JlVGltZSA9PT0gdm9pZCAwKSB7XG4gICAgICBpZ25vcmVCZWZvcmVUaW1lID0gLV9iaWdOdW07XG4gICAgfVxuXG4gICAgdmFyIGEgPSBbXSxcbiAgICAgICAgY2hpbGQgPSB0aGlzLl9maXJzdDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkLl9zdGFydCA+PSBpZ25vcmVCZWZvcmVUaW1lKSB7XG4gICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFR3ZWVuKSB7XG4gICAgICAgICAgdHdlZW5zICYmIGEucHVzaChjaGlsZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGltZWxpbmVzICYmIGEucHVzaChjaGlsZCk7XG4gICAgICAgICAgbmVzdGVkICYmIGEucHVzaC5hcHBseShhLCBjaGlsZC5nZXRDaGlsZHJlbih0cnVlLCB0d2VlbnMsIHRpbWVsaW5lcykpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGE7XG4gIH07XG5cbiAgX3Byb3RvMi5nZXRCeUlkID0gZnVuY3Rpb24gZ2V0QnlJZChpZCkge1xuICAgIHZhciBhbmltYXRpb25zID0gdGhpcy5nZXRDaGlsZHJlbigxLCAxLCAxKSxcbiAgICAgICAgaSA9IGFuaW1hdGlvbnMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWYgKGFuaW1hdGlvbnNbaV0udmFycy5pZCA9PT0gaWQpIHtcbiAgICAgICAgcmV0dXJuIGFuaW1hdGlvbnNbaV07XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIF9wcm90bzIucmVtb3ZlID0gZnVuY3Rpb24gcmVtb3ZlKGNoaWxkKSB7XG4gICAgaWYgKF9pc1N0cmluZyhjaGlsZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZUxhYmVsKGNoaWxkKTtcbiAgICB9XG5cbiAgICBpZiAoX2lzRnVuY3Rpb24oY2hpbGQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5raWxsVHdlZW5zT2YoY2hpbGQpO1xuICAgIH1cblxuICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSh0aGlzLCBjaGlsZCk7XG5cbiAgICBpZiAoY2hpbGQgPT09IHRoaXMuX3JlY2VudCkge1xuICAgICAgdGhpcy5fcmVjZW50ID0gdGhpcy5fbGFzdDtcbiAgICB9XG5cbiAgICByZXR1cm4gX3VuY2FjaGUodGhpcyk7XG4gIH07XG5cbiAgX3Byb3RvMi50b3RhbFRpbWUgPSBmdW5jdGlvbiB0b3RhbFRpbWUoX3RvdGFsVGltZTIsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdFRpbWU7XG4gICAgfVxuXG4gICAgdGhpcy5fZm9yY2luZyA9IDE7XG5cbiAgICBpZiAoIXRoaXMuX2RwICYmIHRoaXMuX3RzKSB7XG4gICAgICAvL3NwZWNpYWwgY2FzZSBmb3IgdGhlIGdsb2JhbCB0aW1lbGluZSAob3IgYW55IG90aGVyIHRoYXQgaGFzIG5vIHBhcmVudCBvciBkZXRhY2hlZCBwYXJlbnQpLlxuICAgICAgdGhpcy5fc3RhcnQgPSBfcm91bmRQcmVjaXNlKF90aWNrZXIudGltZSAtICh0aGlzLl90cyA+IDAgPyBfdG90YWxUaW1lMiAvIHRoaXMuX3RzIDogKHRoaXMudG90YWxEdXJhdGlvbigpIC0gX3RvdGFsVGltZTIpIC8gLXRoaXMuX3RzKSk7XG4gICAgfVxuXG4gICAgX0FuaW1hdGlvbi5wcm90b3R5cGUudG90YWxUaW1lLmNhbGwodGhpcywgX3RvdGFsVGltZTIsIHN1cHByZXNzRXZlbnRzKTtcblxuICAgIHRoaXMuX2ZvcmNpbmcgPSAwO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90bzIuYWRkTGFiZWwgPSBmdW5jdGlvbiBhZGRMYWJlbChsYWJlbCwgcG9zaXRpb24pIHtcbiAgICB0aGlzLmxhYmVsc1tsYWJlbF0gPSBfcGFyc2VQb3NpdGlvbih0aGlzLCBwb3NpdGlvbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMi5yZW1vdmVMYWJlbCA9IGZ1bmN0aW9uIHJlbW92ZUxhYmVsKGxhYmVsKSB7XG4gICAgZGVsZXRlIHRoaXMubGFiZWxzW2xhYmVsXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmFkZFBhdXNlID0gZnVuY3Rpb24gYWRkUGF1c2UocG9zaXRpb24sIGNhbGxiYWNrLCBwYXJhbXMpIHtcbiAgICB2YXIgdCA9IFR3ZWVuLmRlbGF5ZWRDYWxsKDAsIGNhbGxiYWNrIHx8IF9lbXB0eUZ1bmMsIHBhcmFtcyk7XG4gICAgdC5kYXRhID0gXCJpc1BhdXNlXCI7XG4gICAgdGhpcy5faGFzUGF1c2UgPSAxO1xuICAgIHJldHVybiBfYWRkVG9UaW1lbGluZSh0aGlzLCB0LCBfcGFyc2VQb3NpdGlvbih0aGlzLCBwb3NpdGlvbikpO1xuICB9O1xuXG4gIF9wcm90bzIucmVtb3ZlUGF1c2UgPSBmdW5jdGlvbiByZW1vdmVQYXVzZShwb3NpdGlvbikge1xuICAgIHZhciBjaGlsZCA9IHRoaXMuX2ZpcnN0O1xuICAgIHBvc2l0aW9uID0gX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pO1xuXG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAoY2hpbGQuX3N0YXJ0ID09PSBwb3NpdGlvbiAmJiBjaGlsZC5kYXRhID09PSBcImlzUGF1c2VcIikge1xuICAgICAgICBfcmVtb3ZlRnJvbVBhcmVudChjaGlsZCk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gICAgfVxuICB9O1xuXG4gIF9wcm90bzIua2lsbFR3ZWVuc09mID0gZnVuY3Rpb24ga2lsbFR3ZWVuc09mKHRhcmdldHMsIHByb3BzLCBvbmx5QWN0aXZlKSB7XG4gICAgdmFyIHR3ZWVucyA9IHRoaXMuZ2V0VHdlZW5zT2YodGFyZ2V0cywgb25seUFjdGl2ZSksXG4gICAgICAgIGkgPSB0d2VlbnMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgX292ZXJ3cml0aW5nVHdlZW4gIT09IHR3ZWVuc1tpXSAmJiB0d2VlbnNbaV0ua2lsbCh0YXJnZXRzLCBwcm9wcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMi5nZXRUd2VlbnNPZiA9IGZ1bmN0aW9uIGdldFR3ZWVuc09mKHRhcmdldHMsIG9ubHlBY3RpdmUpIHtcbiAgICB2YXIgYSA9IFtdLFxuICAgICAgICBwYXJzZWRUYXJnZXRzID0gdG9BcnJheSh0YXJnZXRzKSxcbiAgICAgICAgY2hpbGQgPSB0aGlzLl9maXJzdCxcbiAgICAgICAgaXNHbG9iYWxUaW1lID0gX2lzTnVtYmVyKG9ubHlBY3RpdmUpLFxuICAgICAgICAvLyBhIG51bWJlciBpcyBpbnRlcnByZXRlZCBhcyBhIGdsb2JhbCB0aW1lLiBJZiB0aGUgYW5pbWF0aW9uIHNwYW5zXG4gICAgY2hpbGRyZW47XG5cbiAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFR3ZWVuKSB7XG4gICAgICAgIGlmIChfYXJyYXlDb250YWluc0FueShjaGlsZC5fdGFyZ2V0cywgcGFyc2VkVGFyZ2V0cykgJiYgKGlzR2xvYmFsVGltZSA/ICghX292ZXJ3cml0aW5nVHdlZW4gfHwgY2hpbGQuX2luaXR0ZWQgJiYgY2hpbGQuX3RzKSAmJiBjaGlsZC5nbG9iYWxUaW1lKDApIDw9IG9ubHlBY3RpdmUgJiYgY2hpbGQuZ2xvYmFsVGltZShjaGlsZC50b3RhbER1cmF0aW9uKCkpID4gb25seUFjdGl2ZSA6ICFvbmx5QWN0aXZlIHx8IGNoaWxkLmlzQWN0aXZlKCkpKSB7XG4gICAgICAgICAgLy8gbm90ZTogaWYgdGhpcyBpcyBmb3Igb3ZlcndyaXRpbmcsIGl0IHNob3VsZCBvbmx5IGJlIGZvciB0d2VlbnMgdGhhdCBhcmVuJ3QgcGF1c2VkIGFuZCBhcmUgaW5pdHRlZC5cbiAgICAgICAgICBhLnB1c2goY2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKChjaGlsZHJlbiA9IGNoaWxkLmdldFR3ZWVuc09mKHBhcnNlZFRhcmdldHMsIG9ubHlBY3RpdmUpKS5sZW5ndGgpIHtcbiAgICAgICAgYS5wdXNoLmFwcGx5KGEsIGNoaWxkcmVuKTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5fbmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfSAvLyBwb3RlbnRpYWwgZnV0dXJlIGZlYXR1cmUgLSB0YXJnZXRzKCkgb24gdGltZWxpbmVzXG4gIC8vIHRhcmdldHMoKSB7XG4gIC8vIFx0bGV0IHJlc3VsdCA9IFtdO1xuICAvLyBcdHRoaXMuZ2V0Q2hpbGRyZW4odHJ1ZSwgdHJ1ZSwgZmFsc2UpLmZvckVhY2godCA9PiByZXN1bHQucHVzaCguLi50LnRhcmdldHMoKSkpO1xuICAvLyBcdHJldHVybiByZXN1bHQuZmlsdGVyKCh2LCBpKSA9PiByZXN1bHQuaW5kZXhPZih2KSA9PT0gaSk7XG4gIC8vIH1cbiAgO1xuXG4gIF9wcm90bzIudHdlZW5UbyA9IGZ1bmN0aW9uIHR3ZWVuVG8ocG9zaXRpb24sIHZhcnMpIHtcbiAgICB2YXJzID0gdmFycyB8fCB7fTtcblxuICAgIHZhciB0bCA9IHRoaXMsXG4gICAgICAgIGVuZFRpbWUgPSBfcGFyc2VQb3NpdGlvbih0bCwgcG9zaXRpb24pLFxuICAgICAgICBfdmFycyA9IHZhcnMsXG4gICAgICAgIHN0YXJ0QXQgPSBfdmFycy5zdGFydEF0LFxuICAgICAgICBfb25TdGFydCA9IF92YXJzLm9uU3RhcnQsXG4gICAgICAgIG9uU3RhcnRQYXJhbXMgPSBfdmFycy5vblN0YXJ0UGFyYW1zLFxuICAgICAgICBpbW1lZGlhdGVSZW5kZXIgPSBfdmFycy5pbW1lZGlhdGVSZW5kZXIsXG4gICAgICAgIGluaXR0ZWQsXG4gICAgICAgIHR3ZWVuID0gVHdlZW4udG8odGwsIF9zZXREZWZhdWx0cyh7XG4gICAgICBlYXNlOiB2YXJzLmVhc2UgfHwgXCJub25lXCIsXG4gICAgICBsYXp5OiBmYWxzZSxcbiAgICAgIGltbWVkaWF0ZVJlbmRlcjogZmFsc2UsXG4gICAgICB0aW1lOiBlbmRUaW1lLFxuICAgICAgb3ZlcndyaXRlOiBcImF1dG9cIixcbiAgICAgIGR1cmF0aW9uOiB2YXJzLmR1cmF0aW9uIHx8IE1hdGguYWJzKChlbmRUaW1lIC0gKHN0YXJ0QXQgJiYgXCJ0aW1lXCIgaW4gc3RhcnRBdCA/IHN0YXJ0QXQudGltZSA6IHRsLl90aW1lKSkgLyB0bC50aW1lU2NhbGUoKSkgfHwgX3RpbnlOdW0sXG4gICAgICBvblN0YXJ0OiBmdW5jdGlvbiBvblN0YXJ0KCkge1xuICAgICAgICB0bC5wYXVzZSgpO1xuXG4gICAgICAgIGlmICghaW5pdHRlZCkge1xuICAgICAgICAgIHZhciBkdXJhdGlvbiA9IHZhcnMuZHVyYXRpb24gfHwgTWF0aC5hYnMoKGVuZFRpbWUgLSAoc3RhcnRBdCAmJiBcInRpbWVcIiBpbiBzdGFydEF0ID8gc3RhcnRBdC50aW1lIDogdGwuX3RpbWUpKSAvIHRsLnRpbWVTY2FsZSgpKTtcbiAgICAgICAgICB0d2Vlbi5fZHVyICE9PSBkdXJhdGlvbiAmJiBfc2V0RHVyYXRpb24odHdlZW4sIGR1cmF0aW9uLCAwLCAxKS5yZW5kZXIodHdlZW4uX3RpbWUsIHRydWUsIHRydWUpO1xuICAgICAgICAgIGluaXR0ZWQgPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgX29uU3RhcnQgJiYgX29uU3RhcnQuYXBwbHkodHdlZW4sIG9uU3RhcnRQYXJhbXMgfHwgW10pOyAvL2luIGNhc2UgdGhlIHVzZXIgaGFkIGFuIG9uU3RhcnQgaW4gdGhlIHZhcnMgLSB3ZSBkb24ndCB3YW50IHRvIG92ZXJ3cml0ZSBpdC5cbiAgICAgIH1cbiAgICB9LCB2YXJzKSk7XG5cbiAgICByZXR1cm4gaW1tZWRpYXRlUmVuZGVyID8gdHdlZW4ucmVuZGVyKDApIDogdHdlZW47XG4gIH07XG5cbiAgX3Byb3RvMi50d2VlbkZyb21UbyA9IGZ1bmN0aW9uIHR3ZWVuRnJvbVRvKGZyb21Qb3NpdGlvbiwgdG9Qb3NpdGlvbiwgdmFycykge1xuICAgIHJldHVybiB0aGlzLnR3ZWVuVG8odG9Qb3NpdGlvbiwgX3NldERlZmF1bHRzKHtcbiAgICAgIHN0YXJ0QXQ6IHtcbiAgICAgICAgdGltZTogX3BhcnNlUG9zaXRpb24odGhpcywgZnJvbVBvc2l0aW9uKVxuICAgICAgfVxuICAgIH0sIHZhcnMpKTtcbiAgfTtcblxuICBfcHJvdG8yLnJlY2VudCA9IGZ1bmN0aW9uIHJlY2VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVjZW50O1xuICB9O1xuXG4gIF9wcm90bzIubmV4dExhYmVsID0gZnVuY3Rpb24gbmV4dExhYmVsKGFmdGVyVGltZSkge1xuICAgIGlmIChhZnRlclRpbWUgPT09IHZvaWQgMCkge1xuICAgICAgYWZ0ZXJUaW1lID0gdGhpcy5fdGltZTtcbiAgICB9XG5cbiAgICByZXR1cm4gX2dldExhYmVsSW5EaXJlY3Rpb24odGhpcywgX3BhcnNlUG9zaXRpb24odGhpcywgYWZ0ZXJUaW1lKSk7XG4gIH07XG5cbiAgX3Byb3RvMi5wcmV2aW91c0xhYmVsID0gZnVuY3Rpb24gcHJldmlvdXNMYWJlbChiZWZvcmVUaW1lKSB7XG4gICAgaWYgKGJlZm9yZVRpbWUgPT09IHZvaWQgMCkge1xuICAgICAgYmVmb3JlVGltZSA9IHRoaXMuX3RpbWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9nZXRMYWJlbEluRGlyZWN0aW9uKHRoaXMsIF9wYXJzZVBvc2l0aW9uKHRoaXMsIGJlZm9yZVRpbWUpLCAxKTtcbiAgfTtcblxuICBfcHJvdG8yLmN1cnJlbnRMYWJlbCA9IGZ1bmN0aW9uIGN1cnJlbnRMYWJlbCh2YWx1ZSkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5zZWVrKHZhbHVlLCB0cnVlKSA6IHRoaXMucHJldmlvdXNMYWJlbCh0aGlzLl90aW1lICsgX3RpbnlOdW0pO1xuICB9O1xuXG4gIF9wcm90bzIuc2hpZnRDaGlsZHJlbiA9IGZ1bmN0aW9uIHNoaWZ0Q2hpbGRyZW4oYW1vdW50LCBhZGp1c3RMYWJlbHMsIGlnbm9yZUJlZm9yZVRpbWUpIHtcbiAgICBpZiAoaWdub3JlQmVmb3JlVGltZSA9PT0gdm9pZCAwKSB7XG4gICAgICBpZ25vcmVCZWZvcmVUaW1lID0gMDtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGQgPSB0aGlzLl9maXJzdCxcbiAgICAgICAgbGFiZWxzID0gdGhpcy5sYWJlbHMsXG4gICAgICAgIHA7XG5cbiAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgIGlmIChjaGlsZC5fc3RhcnQgPj0gaWdub3JlQmVmb3JlVGltZSkge1xuICAgICAgICBjaGlsZC5fc3RhcnQgKz0gYW1vdW50O1xuICAgICAgICBjaGlsZC5fZW5kICs9IGFtb3VudDtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5fbmV4dDtcbiAgICB9XG5cbiAgICBpZiAoYWRqdXN0TGFiZWxzKSB7XG4gICAgICBmb3IgKHAgaW4gbGFiZWxzKSB7XG4gICAgICAgIGlmIChsYWJlbHNbcF0gPj0gaWdub3JlQmVmb3JlVGltZSkge1xuICAgICAgICAgIGxhYmVsc1twXSArPSBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX3VuY2FjaGUodGhpcyk7XG4gIH07XG5cbiAgX3Byb3RvMi5pbnZhbGlkYXRlID0gZnVuY3Rpb24gaW52YWxpZGF0ZShzb2Z0KSB7XG4gICAgdmFyIGNoaWxkID0gdGhpcy5fZmlyc3Q7XG4gICAgdGhpcy5fbG9jayA9IDA7XG5cbiAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgIGNoaWxkLmludmFsaWRhdGUoc29mdCk7XG4gICAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBfQW5pbWF0aW9uLnByb3RvdHlwZS5pbnZhbGlkYXRlLmNhbGwodGhpcywgc29mdCk7XG4gIH07XG5cbiAgX3Byb3RvMi5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKGluY2x1ZGVMYWJlbHMpIHtcbiAgICBpZiAoaW5jbHVkZUxhYmVscyA9PT0gdm9pZCAwKSB7XG4gICAgICBpbmNsdWRlTGFiZWxzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGQgPSB0aGlzLl9maXJzdCxcbiAgICAgICAgbmV4dDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgbmV4dCA9IGNoaWxkLl9uZXh0O1xuICAgICAgdGhpcy5yZW1vdmUoY2hpbGQpO1xuICAgICAgY2hpbGQgPSBuZXh0O1xuICAgIH1cblxuICAgIHRoaXMuX2RwICYmICh0aGlzLl90aW1lID0gdGhpcy5fdFRpbWUgPSB0aGlzLl9wVGltZSA9IDApO1xuICAgIGluY2x1ZGVMYWJlbHMgJiYgKHRoaXMubGFiZWxzID0ge30pO1xuICAgIHJldHVybiBfdW5jYWNoZSh0aGlzKTtcbiAgfTtcblxuICBfcHJvdG8yLnRvdGFsRHVyYXRpb24gPSBmdW5jdGlvbiB0b3RhbER1cmF0aW9uKHZhbHVlKSB7XG4gICAgdmFyIG1heCA9IDAsXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBjaGlsZCA9IHNlbGYuX2xhc3QsXG4gICAgICAgIHByZXZTdGFydCA9IF9iaWdOdW0sXG4gICAgICAgIHByZXYsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBwYXJlbnQ7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHNlbGYudGltZVNjYWxlKChzZWxmLl9yZXBlYXQgPCAwID8gc2VsZi5kdXJhdGlvbigpIDogc2VsZi50b3RhbER1cmF0aW9uKCkpIC8gKHNlbGYucmV2ZXJzZWQoKSA/IC12YWx1ZSA6IHZhbHVlKSk7XG4gICAgfVxuXG4gICAgaWYgKHNlbGYuX2RpcnR5KSB7XG4gICAgICBwYXJlbnQgPSBzZWxmLnBhcmVudDtcblxuICAgICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICAgIHByZXYgPSBjaGlsZC5fcHJldjsgLy9yZWNvcmQgaXQgaGVyZSBpbiBjYXNlIHRoZSB0d2VlbiBjaGFuZ2VzIHBvc2l0aW9uIGluIHRoZSBzZXF1ZW5jZS4uLlxuXG4gICAgICAgIGNoaWxkLl9kaXJ0eSAmJiBjaGlsZC50b3RhbER1cmF0aW9uKCk7IC8vY291bGQgY2hhbmdlIHRoZSB0d2Vlbi5fc3RhcnRUaW1lLCBzbyBtYWtlIHN1cmUgdGhlIGFuaW1hdGlvbidzIGNhY2hlIGlzIGNsZWFuIGJlZm9yZSBhbmFseXppbmcgaXQuXG5cbiAgICAgICAgc3RhcnQgPSBjaGlsZC5fc3RhcnQ7XG5cbiAgICAgICAgaWYgKHN0YXJ0ID4gcHJldlN0YXJ0ICYmIHNlbGYuX3NvcnQgJiYgY2hpbGQuX3RzICYmICFzZWxmLl9sb2NrKSB7XG4gICAgICAgICAgLy9pbiBjYXNlIG9uZSBvZiB0aGUgdHdlZW5zIHNoaWZ0ZWQgb3V0IG9mIG9yZGVyLCBpdCBuZWVkcyB0byBiZSByZS1pbnNlcnRlZCBpbnRvIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBzZXF1ZW5jZVxuICAgICAgICAgIHNlbGYuX2xvY2sgPSAxOyAvL3ByZXZlbnQgZW5kbGVzcyByZWN1cnNpdmUgY2FsbHMgLSB0aGVyZSBhcmUgbWV0aG9kcyB0aGF0IGdldCB0cmlnZ2VyZWQgdGhhdCBjaGVjayBkdXJhdGlvbi90b3RhbER1cmF0aW9uIHdoZW4gd2UgYWRkKCkuXG5cbiAgICAgICAgICBfYWRkVG9UaW1lbGluZShzZWxmLCBjaGlsZCwgc3RhcnQgLSBjaGlsZC5fZGVsYXksIDEpLl9sb2NrID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2U3RhcnQgPSBzdGFydDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGFydCA8IDAgJiYgY2hpbGQuX3RzKSB7XG4gICAgICAgICAgLy9jaGlsZHJlbiBhcmVuJ3QgYWxsb3dlZCB0byBoYXZlIG5lZ2F0aXZlIHN0YXJ0VGltZXMgdW5sZXNzIHNtb290aENoaWxkVGltaW5nIGlzIHRydWUsIHNvIGFkanVzdCBoZXJlIGlmIG9uZSBpcyBmb3VuZC5cbiAgICAgICAgICBtYXggLT0gc3RhcnQ7XG5cbiAgICAgICAgICBpZiAoIXBhcmVudCAmJiAhc2VsZi5fZHAgfHwgcGFyZW50ICYmIHBhcmVudC5zbW9vdGhDaGlsZFRpbWluZykge1xuICAgICAgICAgICAgc2VsZi5fc3RhcnQgKz0gc3RhcnQgLyBzZWxmLl90cztcbiAgICAgICAgICAgIHNlbGYuX3RpbWUgLT0gc3RhcnQ7XG4gICAgICAgICAgICBzZWxmLl90VGltZSAtPSBzdGFydDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzZWxmLnNoaWZ0Q2hpbGRyZW4oLXN0YXJ0LCBmYWxzZSwgLTFlOTk5KTtcbiAgICAgICAgICBwcmV2U3RhcnQgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQuX2VuZCA+IG1heCAmJiBjaGlsZC5fdHMgJiYgKG1heCA9IGNoaWxkLl9lbmQpO1xuICAgICAgICBjaGlsZCA9IHByZXY7XG4gICAgICB9XG5cbiAgICAgIF9zZXREdXJhdGlvbihzZWxmLCBzZWxmID09PSBfZ2xvYmFsVGltZWxpbmUgJiYgc2VsZi5fdGltZSA+IG1heCA/IHNlbGYuX3RpbWUgOiBtYXgsIDEsIDEpO1xuXG4gICAgICBzZWxmLl9kaXJ0eSA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGYuX3REdXI7XG4gIH07XG5cbiAgVGltZWxpbmUudXBkYXRlUm9vdCA9IGZ1bmN0aW9uIHVwZGF0ZVJvb3QodGltZSkge1xuICAgIGlmIChfZ2xvYmFsVGltZWxpbmUuX3RzKSB7XG4gICAgICBfbGF6eVNhZmVSZW5kZXIoX2dsb2JhbFRpbWVsaW5lLCBfcGFyZW50VG9DaGlsZFRvdGFsVGltZSh0aW1lLCBfZ2xvYmFsVGltZWxpbmUpKTtcblxuICAgICAgX2xhc3RSZW5kZXJlZEZyYW1lID0gX3RpY2tlci5mcmFtZTtcbiAgICB9XG5cbiAgICBpZiAoX3RpY2tlci5mcmFtZSA+PSBfbmV4dEdDRnJhbWUpIHtcbiAgICAgIF9uZXh0R0NGcmFtZSArPSBfY29uZmlnLmF1dG9TbGVlcCB8fCAxMjA7XG4gICAgICB2YXIgY2hpbGQgPSBfZ2xvYmFsVGltZWxpbmUuX2ZpcnN0O1xuICAgICAgaWYgKCFjaGlsZCB8fCAhY2hpbGQuX3RzKSBpZiAoX2NvbmZpZy5hdXRvU2xlZXAgJiYgX3RpY2tlci5fbGlzdGVuZXJzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgd2hpbGUgKGNoaWxkICYmICFjaGlsZC5fdHMpIHtcbiAgICAgICAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgfHwgX3RpY2tlci5zbGVlcCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gVGltZWxpbmU7XG59KEFuaW1hdGlvbik7XG5cbl9zZXREZWZhdWx0cyhUaW1lbGluZS5wcm90b3R5cGUsIHtcbiAgX2xvY2s6IDAsXG4gIF9oYXNQYXVzZTogMCxcbiAgX2ZvcmNpbmc6IDBcbn0pO1xuXG52YXIgX2FkZENvbXBsZXhTdHJpbmdQcm9wVHdlZW4gPSBmdW5jdGlvbiBfYWRkQ29tcGxleFN0cmluZ1Byb3BUd2Vlbih0YXJnZXQsIHByb3AsIHN0YXJ0LCBlbmQsIHNldHRlciwgc3RyaW5nRmlsdGVyLCBmdW5jUGFyYW0pIHtcbiAgLy9ub3RlOiB3ZSBjYWxsIF9hZGRDb21wbGV4U3RyaW5nUHJvcFR3ZWVuLmNhbGwodHdlZW5JbnN0YW5jZS4uLikgdG8gZW5zdXJlIHRoYXQgaXQncyBzY29wZWQgcHJvcGVybHkuIFdlIG1heSBjYWxsIGl0IGZyb20gd2l0aGluIGEgcGx1Z2luIHRvbywgdGh1cyBcInRoaXNcIiB3b3VsZCByZWZlciB0byB0aGUgcGx1Z2luLlxuICB2YXIgcHQgPSBuZXcgUHJvcFR3ZWVuKHRoaXMuX3B0LCB0YXJnZXQsIHByb3AsIDAsIDEsIF9yZW5kZXJDb21wbGV4U3RyaW5nLCBudWxsLCBzZXR0ZXIpLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgbWF0Y2hJbmRleCA9IDAsXG4gICAgICByZXN1bHQsXG4gICAgICBzdGFydE51bXMsXG4gICAgICBjb2xvcixcbiAgICAgIGVuZE51bSxcbiAgICAgIGNodW5rLFxuICAgICAgc3RhcnROdW0sXG4gICAgICBoYXNSYW5kb20sXG4gICAgICBhO1xuICBwdC5iID0gc3RhcnQ7XG4gIHB0LmUgPSBlbmQ7XG4gIHN0YXJ0ICs9IFwiXCI7IC8vZW5zdXJlIHZhbHVlcyBhcmUgc3RyaW5nc1xuXG4gIGVuZCArPSBcIlwiO1xuXG4gIGlmIChoYXNSYW5kb20gPSB+ZW5kLmluZGV4T2YoXCJyYW5kb20oXCIpKSB7XG4gICAgZW5kID0gX3JlcGxhY2VSYW5kb20oZW5kKTtcbiAgfVxuXG4gIGlmIChzdHJpbmdGaWx0ZXIpIHtcbiAgICBhID0gW3N0YXJ0LCBlbmRdO1xuICAgIHN0cmluZ0ZpbHRlcihhLCB0YXJnZXQsIHByb3ApOyAvL3Bhc3MgYW4gYXJyYXkgd2l0aCB0aGUgc3RhcnRpbmcgYW5kIGVuZGluZyB2YWx1ZXMgYW5kIGxldCB0aGUgZmlsdGVyIGRvIHdoYXRldmVyIGl0IG5lZWRzIHRvIHRoZSB2YWx1ZXMuXG5cbiAgICBzdGFydCA9IGFbMF07XG4gICAgZW5kID0gYVsxXTtcbiAgfVxuXG4gIHN0YXJ0TnVtcyA9IHN0YXJ0Lm1hdGNoKF9jb21wbGV4U3RyaW5nTnVtRXhwKSB8fCBbXTtcblxuICB3aGlsZSAocmVzdWx0ID0gX2NvbXBsZXhTdHJpbmdOdW1FeHAuZXhlYyhlbmQpKSB7XG4gICAgZW5kTnVtID0gcmVzdWx0WzBdO1xuICAgIGNodW5rID0gZW5kLnN1YnN0cmluZyhpbmRleCwgcmVzdWx0LmluZGV4KTtcblxuICAgIGlmIChjb2xvcikge1xuICAgICAgY29sb3IgPSAoY29sb3IgKyAxKSAlIDU7XG4gICAgfSBlbHNlIGlmIChjaHVuay5zdWJzdHIoLTUpID09PSBcInJnYmEoXCIpIHtcbiAgICAgIGNvbG9yID0gMTtcbiAgICB9XG5cbiAgICBpZiAoZW5kTnVtICE9PSBzdGFydE51bXNbbWF0Y2hJbmRleCsrXSkge1xuICAgICAgc3RhcnROdW0gPSBwYXJzZUZsb2F0KHN0YXJ0TnVtc1ttYXRjaEluZGV4IC0gMV0pIHx8IDA7IC8vdGhlc2UgbmVzdGVkIFByb3BUd2VlbnMgYXJlIGhhbmRsZWQgaW4gYSBzcGVjaWFsIHdheSAtIHdlJ2xsIG5ldmVyIGFjdHVhbGx5IGNhbGwgYSByZW5kZXIgb3Igc2V0dGVyIG1ldGhvZCBvbiB0aGVtLiBXZSdsbCBqdXN0IGxvb3AgdGhyb3VnaCB0aGVtIGluIHRoZSBwYXJlbnQgY29tcGxleCBzdHJpbmcgUHJvcFR3ZWVuJ3MgcmVuZGVyIG1ldGhvZC5cblxuICAgICAgcHQuX3B0ID0ge1xuICAgICAgICBfbmV4dDogcHQuX3B0LFxuICAgICAgICBwOiBjaHVuayB8fCBtYXRjaEluZGV4ID09PSAxID8gY2h1bmsgOiBcIixcIixcbiAgICAgICAgLy9ub3RlOiBTVkcgc3BlYyBhbGxvd3Mgb21pc3Npb24gb2YgY29tbWEvc3BhY2Ugd2hlbiBhIG5lZ2F0aXZlIHNpZ24gaXMgd2VkZ2VkIGJldHdlZW4gdHdvIG51bWJlcnMsIGxpa2UgMi41LTUuMyBpbnN0ZWFkIG9mIDIuNSwtNS4zIGJ1dCB3aGVuIHR3ZWVuaW5nLCB0aGUgbmVnYXRpdmUgdmFsdWUgbWF5IHN3aXRjaCB0byBwb3NpdGl2ZSwgc28gd2UgaW5zZXJ0IHRoZSBjb21tYSBqdXN0IGluIGNhc2UuXG4gICAgICAgIHM6IHN0YXJ0TnVtLFxuICAgICAgICBjOiBlbmROdW0uY2hhckF0KDEpID09PSBcIj1cIiA/IF9wYXJzZVJlbGF0aXZlKHN0YXJ0TnVtLCBlbmROdW0pIC0gc3RhcnROdW0gOiBwYXJzZUZsb2F0KGVuZE51bSkgLSBzdGFydE51bSxcbiAgICAgICAgbTogY29sb3IgJiYgY29sb3IgPCA0ID8gTWF0aC5yb3VuZCA6IDBcbiAgICAgIH07XG4gICAgICBpbmRleCA9IF9jb21wbGV4U3RyaW5nTnVtRXhwLmxhc3RJbmRleDtcbiAgICB9XG4gIH1cblxuICBwdC5jID0gaW5kZXggPCBlbmQubGVuZ3RoID8gZW5kLnN1YnN0cmluZyhpbmRleCwgZW5kLmxlbmd0aCkgOiBcIlwiOyAvL3dlIHVzZSB0aGUgXCJjXCIgb2YgdGhlIFByb3BUd2VlbiB0byBzdG9yZSB0aGUgZmluYWwgcGFydCBvZiB0aGUgc3RyaW5nIChhZnRlciB0aGUgbGFzdCBudW1iZXIpXG5cbiAgcHQuZnAgPSBmdW5jUGFyYW07XG5cbiAgaWYgKF9yZWxFeHAudGVzdChlbmQpIHx8IGhhc1JhbmRvbSkge1xuICAgIHB0LmUgPSAwOyAvL2lmIHRoZSBlbmQgc3RyaW5nIGNvbnRhaW5zIHJlbGF0aXZlIHZhbHVlcyBvciBkeW5hbWljIHJhbmRvbSguLi4pIHZhbHVlcywgZGVsZXRlIHRoZSBlbmQgaXQgc28gdGhhdCBvbiB0aGUgZmluYWwgcmVuZGVyIHdlIGRvbid0IGFjdHVhbGx5IHNldCBpdCB0byB0aGUgc3RyaW5nIHdpdGggKz0gb3IgLT0gY2hhcmFjdGVycyAoZm9yY2VzIGl0IHRvIHVzZSB0aGUgY2FsY3VsYXRlZCB2YWx1ZSkuXG4gIH1cblxuICB0aGlzLl9wdCA9IHB0OyAvL3N0YXJ0IHRoZSBsaW5rZWQgbGlzdCB3aXRoIHRoaXMgbmV3IFByb3BUd2Vlbi4gUmVtZW1iZXIsIHdlIGNhbGwgX2FkZENvbXBsZXhTdHJpbmdQcm9wVHdlZW4uY2FsbCh0d2Vlbkluc3RhbmNlLi4uKSB0byBlbnN1cmUgdGhhdCBpdCdzIHNjb3BlZCBwcm9wZXJseS4gV2UgbWF5IGNhbGwgaXQgZnJvbSB3aXRoaW4gYSBwbHVnaW4gdG9vLCB0aHVzIFwidGhpc1wiIHdvdWxkIHJlZmVyIHRvIHRoZSBwbHVnaW4uXG5cbiAgcmV0dXJuIHB0O1xufSxcbiAgICBfYWRkUHJvcFR3ZWVuID0gZnVuY3Rpb24gX2FkZFByb3BUd2Vlbih0YXJnZXQsIHByb3AsIHN0YXJ0LCBlbmQsIGluZGV4LCB0YXJnZXRzLCBtb2RpZmllciwgc3RyaW5nRmlsdGVyLCBmdW5jUGFyYW0sIG9wdGlvbmFsKSB7XG4gIF9pc0Z1bmN0aW9uKGVuZCkgJiYgKGVuZCA9IGVuZChpbmRleCB8fCAwLCB0YXJnZXQsIHRhcmdldHMpKTtcbiAgdmFyIGN1cnJlbnRWYWx1ZSA9IHRhcmdldFtwcm9wXSxcbiAgICAgIHBhcnNlZFN0YXJ0ID0gc3RhcnQgIT09IFwiZ2V0XCIgPyBzdGFydCA6ICFfaXNGdW5jdGlvbihjdXJyZW50VmFsdWUpID8gY3VycmVudFZhbHVlIDogZnVuY1BhcmFtID8gdGFyZ2V0W3Byb3AuaW5kZXhPZihcInNldFwiKSB8fCAhX2lzRnVuY3Rpb24odGFyZ2V0W1wiZ2V0XCIgKyBwcm9wLnN1YnN0cigzKV0pID8gcHJvcCA6IFwiZ2V0XCIgKyBwcm9wLnN1YnN0cigzKV0oZnVuY1BhcmFtKSA6IHRhcmdldFtwcm9wXSgpLFxuICAgICAgc2V0dGVyID0gIV9pc0Z1bmN0aW9uKGN1cnJlbnRWYWx1ZSkgPyBfc2V0dGVyUGxhaW4gOiBmdW5jUGFyYW0gPyBfc2V0dGVyRnVuY1dpdGhQYXJhbSA6IF9zZXR0ZXJGdW5jLFxuICAgICAgcHQ7XG5cbiAgaWYgKF9pc1N0cmluZyhlbmQpKSB7XG4gICAgaWYgKH5lbmQuaW5kZXhPZihcInJhbmRvbShcIikpIHtcbiAgICAgIGVuZCA9IF9yZXBsYWNlUmFuZG9tKGVuZCk7XG4gICAgfVxuXG4gICAgaWYgKGVuZC5jaGFyQXQoMSkgPT09IFwiPVwiKSB7XG4gICAgICBwdCA9IF9wYXJzZVJlbGF0aXZlKHBhcnNlZFN0YXJ0LCBlbmQpICsgKGdldFVuaXQocGFyc2VkU3RhcnQpIHx8IDApO1xuXG4gICAgICBpZiAocHQgfHwgcHQgPT09IDApIHtcbiAgICAgICAgLy8gdG8gYXZvaWQgaXNOYU4sIGxpa2UgaWYgc29tZW9uZSBwYXNzZXMgaW4gYSB2YWx1ZSBsaWtlIFwiIT0gd2hhdGV2ZXJcIlxuICAgICAgICBlbmQgPSBwdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIW9wdGlvbmFsIHx8IHBhcnNlZFN0YXJ0ICE9PSBlbmQgfHwgX2ZvcmNlQWxsUHJvcFR3ZWVucykge1xuICAgIGlmICghaXNOYU4ocGFyc2VkU3RhcnQgKiBlbmQpICYmIGVuZCAhPT0gXCJcIikge1xuICAgICAgLy8gZnVuIGZhY3Q6IGFueSBudW1iZXIgbXVsdGlwbGllZCBieSBcIlwiIGlzIGV2YWx1YXRlZCBhcyB0aGUgbnVtYmVyIDAhXG4gICAgICBwdCA9IG5ldyBQcm9wVHdlZW4odGhpcy5fcHQsIHRhcmdldCwgcHJvcCwgK3BhcnNlZFN0YXJ0IHx8IDAsIGVuZCAtIChwYXJzZWRTdGFydCB8fCAwKSwgdHlwZW9mIGN1cnJlbnRWYWx1ZSA9PT0gXCJib29sZWFuXCIgPyBfcmVuZGVyQm9vbGVhbiA6IF9yZW5kZXJQbGFpbiwgMCwgc2V0dGVyKTtcbiAgICAgIGZ1bmNQYXJhbSAmJiAocHQuZnAgPSBmdW5jUGFyYW0pO1xuICAgICAgbW9kaWZpZXIgJiYgcHQubW9kaWZpZXIobW9kaWZpZXIsIHRoaXMsIHRhcmdldCk7XG4gICAgICByZXR1cm4gdGhpcy5fcHQgPSBwdDtcbiAgICB9XG5cbiAgICAhY3VycmVudFZhbHVlICYmICEocHJvcCBpbiB0YXJnZXQpICYmIF9taXNzaW5nUGx1Z2luKHByb3AsIGVuZCk7XG4gICAgcmV0dXJuIF9hZGRDb21wbGV4U3RyaW5nUHJvcFR3ZWVuLmNhbGwodGhpcywgdGFyZ2V0LCBwcm9wLCBwYXJzZWRTdGFydCwgZW5kLCBzZXR0ZXIsIHN0cmluZ0ZpbHRlciB8fCBfY29uZmlnLnN0cmluZ0ZpbHRlciwgZnVuY1BhcmFtKTtcbiAgfVxufSxcbiAgICAvL2NyZWF0ZXMgYSBjb3B5IG9mIHRoZSB2YXJzIG9iamVjdCBhbmQgcHJvY2Vzc2VzIGFueSBmdW5jdGlvbi1iYXNlZCB2YWx1ZXMgKHB1dHRpbmcgdGhlIHJlc3VsdGluZyB2YWx1ZXMgZGlyZWN0bHkgaW50byB0aGUgY29weSkgYXMgd2VsbCBhcyBzdHJpbmdzIHdpdGggXCJyYW5kb20oKVwiIGluIHRoZW0uIEl0IGRvZXMgTk9UIHByb2Nlc3MgcmVsYXRpdmUgdmFsdWVzLlxuX3Byb2Nlc3NWYXJzID0gZnVuY3Rpb24gX3Byb2Nlc3NWYXJzKHZhcnMsIGluZGV4LCB0YXJnZXQsIHRhcmdldHMsIHR3ZWVuKSB7XG4gIF9pc0Z1bmN0aW9uKHZhcnMpICYmICh2YXJzID0gX3BhcnNlRnVuY09yU3RyaW5nKHZhcnMsIHR3ZWVuLCBpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSk7XG5cbiAgaWYgKCFfaXNPYmplY3QodmFycykgfHwgdmFycy5zdHlsZSAmJiB2YXJzLm5vZGVUeXBlIHx8IF9pc0FycmF5KHZhcnMpIHx8IF9pc1R5cGVkQXJyYXkodmFycykpIHtcbiAgICByZXR1cm4gX2lzU3RyaW5nKHZhcnMpID8gX3BhcnNlRnVuY09yU3RyaW5nKHZhcnMsIHR3ZWVuLCBpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSA6IHZhcnM7XG4gIH1cblxuICB2YXIgY29weSA9IHt9LFxuICAgICAgcDtcblxuICBmb3IgKHAgaW4gdmFycykge1xuICAgIGNvcHlbcF0gPSBfcGFyc2VGdW5jT3JTdHJpbmcodmFyc1twXSwgdHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpO1xuICB9XG5cbiAgcmV0dXJuIGNvcHk7XG59LFxuICAgIF9jaGVja1BsdWdpbiA9IGZ1bmN0aW9uIF9jaGVja1BsdWdpbihwcm9wZXJ0eSwgdmFycywgdHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpIHtcbiAgdmFyIHBsdWdpbiwgcHQsIHB0TG9va3VwLCBpO1xuXG4gIGlmIChfcGx1Z2luc1twcm9wZXJ0eV0gJiYgKHBsdWdpbiA9IG5ldyBfcGx1Z2luc1twcm9wZXJ0eV0oKSkuaW5pdCh0YXJnZXQsIHBsdWdpbi5yYXdWYXJzID8gdmFyc1twcm9wZXJ0eV0gOiBfcHJvY2Vzc1ZhcnModmFyc1twcm9wZXJ0eV0sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMsIHR3ZWVuKSwgdHdlZW4sIGluZGV4LCB0YXJnZXRzKSAhPT0gZmFsc2UpIHtcbiAgICB0d2Vlbi5fcHQgPSBwdCA9IG5ldyBQcm9wVHdlZW4odHdlZW4uX3B0LCB0YXJnZXQsIHByb3BlcnR5LCAwLCAxLCBwbHVnaW4ucmVuZGVyLCBwbHVnaW4sIDAsIHBsdWdpbi5wcmlvcml0eSk7XG5cbiAgICBpZiAodHdlZW4gIT09IF9xdWlja1R3ZWVuKSB7XG4gICAgICBwdExvb2t1cCA9IHR3ZWVuLl9wdExvb2t1cFt0d2Vlbi5fdGFyZ2V0cy5pbmRleE9mKHRhcmdldCldOyAvL25vdGU6IHdlIGNhbid0IHVzZSB0d2Vlbi5fcHRMb29rdXBbaW5kZXhdIGJlY2F1c2UgZm9yIHN0YWdnZXJlZCB0d2VlbnMsIHRoZSBpbmRleCBmcm9tIHRoZSBmdWxsVGFyZ2V0cyBhcnJheSB3b24ndCBtYXRjaCB3aGF0IGl0IGlzIGluIGVhY2ggaW5kaXZpZHVhbCB0d2VlbiB0aGF0IHNwYXducyBmcm9tIHRoZSBzdGFnZ2VyLlxuXG4gICAgICBpID0gcGx1Z2luLl9wcm9wcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgcHRMb29rdXBbcGx1Z2luLl9wcm9wc1tpXV0gPSBwdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcGx1Z2luO1xufSxcbiAgICBfb3ZlcndyaXRpbmdUd2VlbixcbiAgICAvL3N0b3JlIGEgcmVmZXJlbmNlIHRlbXBvcmFyaWx5IHNvIHdlIGNhbiBhdm9pZCBvdmVyd3JpdGluZyBpdHNlbGYuXG5fZm9yY2VBbGxQcm9wVHdlZW5zLFxuICAgIF9pbml0VHdlZW4gPSBmdW5jdGlvbiBfaW5pdFR3ZWVuKHR3ZWVuLCB0aW1lLCB0VGltZSkge1xuICB2YXIgdmFycyA9IHR3ZWVuLnZhcnMsXG4gICAgICBlYXNlID0gdmFycy5lYXNlLFxuICAgICAgc3RhcnRBdCA9IHZhcnMuc3RhcnRBdCxcbiAgICAgIGltbWVkaWF0ZVJlbmRlciA9IHZhcnMuaW1tZWRpYXRlUmVuZGVyLFxuICAgICAgbGF6eSA9IHZhcnMubGF6eSxcbiAgICAgIG9uVXBkYXRlID0gdmFycy5vblVwZGF0ZSxcbiAgICAgIG9uVXBkYXRlUGFyYW1zID0gdmFycy5vblVwZGF0ZVBhcmFtcyxcbiAgICAgIGNhbGxiYWNrU2NvcGUgPSB2YXJzLmNhbGxiYWNrU2NvcGUsXG4gICAgICBydW5CYWNrd2FyZHMgPSB2YXJzLnJ1bkJhY2t3YXJkcyxcbiAgICAgIHlveW9FYXNlID0gdmFycy55b3lvRWFzZSxcbiAgICAgIGtleWZyYW1lcyA9IHZhcnMua2V5ZnJhbWVzLFxuICAgICAgYXV0b1JldmVydCA9IHZhcnMuYXV0b1JldmVydCxcbiAgICAgIGR1ciA9IHR3ZWVuLl9kdXIsXG4gICAgICBwcmV2U3RhcnRBdCA9IHR3ZWVuLl9zdGFydEF0LFxuICAgICAgdGFyZ2V0cyA9IHR3ZWVuLl90YXJnZXRzLFxuICAgICAgcGFyZW50ID0gdHdlZW4ucGFyZW50LFxuICAgICAgZnVsbFRhcmdldHMgPSBwYXJlbnQgJiYgcGFyZW50LmRhdGEgPT09IFwibmVzdGVkXCIgPyBwYXJlbnQudmFycy50YXJnZXRzIDogdGFyZ2V0cyxcbiAgICAgIGF1dG9PdmVyd3JpdGUgPSB0d2Vlbi5fb3ZlcndyaXRlID09PSBcImF1dG9cIiAmJiAhX3N1cHByZXNzT3ZlcndyaXRlcyxcbiAgICAgIHRsID0gdHdlZW4udGltZWxpbmUsXG4gICAgICBjbGVhblZhcnMsXG4gICAgICBpLFxuICAgICAgcCxcbiAgICAgIHB0LFxuICAgICAgdGFyZ2V0LFxuICAgICAgaGFzUHJpb3JpdHksXG4gICAgICBnc0RhdGEsXG4gICAgICBoYXJuZXNzLFxuICAgICAgcGx1Z2luLFxuICAgICAgcHRMb29rdXAsXG4gICAgICBpbmRleCxcbiAgICAgIGhhcm5lc3NWYXJzLFxuICAgICAgb3ZlcndyaXR0ZW47XG4gIHRsICYmICgha2V5ZnJhbWVzIHx8ICFlYXNlKSAmJiAoZWFzZSA9IFwibm9uZVwiKTtcbiAgdHdlZW4uX2Vhc2UgPSBfcGFyc2VFYXNlKGVhc2UsIF9kZWZhdWx0cy5lYXNlKTtcbiAgdHdlZW4uX3lFYXNlID0geW95b0Vhc2UgPyBfaW52ZXJ0RWFzZShfcGFyc2VFYXNlKHlveW9FYXNlID09PSB0cnVlID8gZWFzZSA6IHlveW9FYXNlLCBfZGVmYXVsdHMuZWFzZSkpIDogMDtcblxuICBpZiAoeW95b0Vhc2UgJiYgdHdlZW4uX3lveW8gJiYgIXR3ZWVuLl9yZXBlYXQpIHtcbiAgICAvL3RoZXJlIG11c3QgaGF2ZSBiZWVuIGEgcGFyZW50IHRpbWVsaW5lIHdpdGggeW95bzp0cnVlIHRoYXQgaXMgY3VycmVudGx5IGluIGl0cyB5b3lvIHBoYXNlLCBzbyBmbGlwIHRoZSBlYXNlcy5cbiAgICB5b3lvRWFzZSA9IHR3ZWVuLl95RWFzZTtcbiAgICB0d2Vlbi5feUVhc2UgPSB0d2Vlbi5fZWFzZTtcbiAgICB0d2Vlbi5fZWFzZSA9IHlveW9FYXNlO1xuICB9XG5cbiAgdHdlZW4uX2Zyb20gPSAhdGwgJiYgISF2YXJzLnJ1bkJhY2t3YXJkczsgLy9uZXN0ZWQgdGltZWxpbmVzIHNob3VsZCBuZXZlciBydW4gYmFja3dhcmRzIC0gdGhlIGJhY2t3YXJkcy1uZXNzIGlzIGluIHRoZSBjaGlsZCB0d2VlbnMuXG5cbiAgaWYgKCF0bCB8fCBrZXlmcmFtZXMgJiYgIXZhcnMuc3RhZ2dlcikge1xuICAgIC8vaWYgdGhlcmUncyBhbiBpbnRlcm5hbCB0aW1lbGluZSwgc2tpcCBhbGwgdGhlIHBhcnNpbmcgYmVjYXVzZSB3ZSBwYXNzZWQgdGhhdCB0YXNrIGRvd24gdGhlIGNoYWluLlxuICAgIGhhcm5lc3MgPSB0YXJnZXRzWzBdID8gX2dldENhY2hlKHRhcmdldHNbMF0pLmhhcm5lc3MgOiAwO1xuICAgIGhhcm5lc3NWYXJzID0gaGFybmVzcyAmJiB2YXJzW2hhcm5lc3MucHJvcF07IC8vc29tZW9uZSBtYXkgbmVlZCB0byBzcGVjaWZ5IENTUy1zcGVjaWZpYyB2YWx1ZXMgQU5EIG5vbi1DU1MgdmFsdWVzLCBsaWtlIGlmIHRoZSBlbGVtZW50IGhhcyBhbiBcInhcIiBwcm9wZXJ0eSBwbHVzIGl0J3MgYSBzdGFuZGFyZCBET00gZWxlbWVudC4gV2UgYWxsb3cgcGVvcGxlIHRvIGRpc3Rpbmd1aXNoIGJ5IHdyYXBwaW5nIHBsdWdpbi1zcGVjaWZpYyBzdHVmZiBpbiBhIGNzczp7fSBvYmplY3QgZm9yIGV4YW1wbGUuXG5cbiAgICBjbGVhblZhcnMgPSBfY29weUV4Y2x1ZGluZyh2YXJzLCBfcmVzZXJ2ZWRQcm9wcyk7XG5cbiAgICBpZiAocHJldlN0YXJ0QXQpIHtcbiAgICAgIHByZXZTdGFydEF0Ll96VGltZSA8IDAgJiYgcHJldlN0YXJ0QXQucHJvZ3Jlc3MoMSk7IC8vIGluIGNhc2UgaXQncyBhIGxhenkgc3RhcnRBdCB0aGF0IGhhc24ndCByZW5kZXJlZCB5ZXQuXG5cbiAgICAgIHRpbWUgPCAwICYmIHJ1bkJhY2t3YXJkcyAmJiBpbW1lZGlhdGVSZW5kZXIgJiYgIWF1dG9SZXZlcnQgPyBwcmV2U3RhcnRBdC5yZW5kZXIoLTEsIHRydWUpIDogcHJldlN0YXJ0QXQucmV2ZXJ0KHJ1bkJhY2t3YXJkcyAmJiBkdXIgPyBfcmV2ZXJ0Q29uZmlnTm9LaWxsIDogX3N0YXJ0QXRSZXZlcnRDb25maWcpOyAvLyBpZiBpdCdzIGEgXCJzdGFydEF0XCIgKG5vdCBcImZyb20oKVwiIG9yIHJ1bkJhY2t3YXJkczogdHJ1ZSksIHdlIG9ubHkgbmVlZCB0byBkbyBhIHNoYWxsb3cgcmV2ZXJ0IChrZWVwIHRyYW5zZm9ybXMgY2FjaGVkIGluIENTU1BsdWdpbilcbiAgICAgIC8vIGRvbid0IGp1c3QgX3JlbW92ZUZyb21QYXJlbnQocHJldlN0YXJ0QXQucmVuZGVyKC0xLCB0cnVlKSkgYmVjYXVzZSB0aGF0J2xsIGxlYXZlIGlubGluZSBzdHlsZXMuIFdlJ3JlIGNyZWF0aW5nIGEgbmV3IF9zdGFydEF0IGZvciBcInN0YXJ0QXRcIiB0d2VlbnMgdGhhdCByZS1jYXB0dXJlIHRoaW5ncyB0byBlbnN1cmUgdGhhdCBpZiB0aGUgcHJlLXR3ZWVuIHZhbHVlcyBjaGFuZ2VkIHNpbmNlIHRoZSB0d2VlbiB3YXMgY3JlYXRlZCwgdGhleSdyZSByZWNvcmRlZC5cblxuICAgICAgcHJldlN0YXJ0QXQuX2xhenkgPSAwO1xuICAgIH1cblxuICAgIGlmIChzdGFydEF0KSB7XG4gICAgICBfcmVtb3ZlRnJvbVBhcmVudCh0d2Vlbi5fc3RhcnRBdCA9IFR3ZWVuLnNldCh0YXJnZXRzLCBfc2V0RGVmYXVsdHMoe1xuICAgICAgICBkYXRhOiBcImlzU3RhcnRcIixcbiAgICAgICAgb3ZlcndyaXRlOiBmYWxzZSxcbiAgICAgICAgcGFyZW50OiBwYXJlbnQsXG4gICAgICAgIGltbWVkaWF0ZVJlbmRlcjogdHJ1ZSxcbiAgICAgICAgbGF6eTogIXByZXZTdGFydEF0ICYmIF9pc05vdEZhbHNlKGxhenkpLFxuICAgICAgICBzdGFydEF0OiBudWxsLFxuICAgICAgICBkZWxheTogMCxcbiAgICAgICAgb25VcGRhdGU6IG9uVXBkYXRlLFxuICAgICAgICBvblVwZGF0ZVBhcmFtczogb25VcGRhdGVQYXJhbXMsXG4gICAgICAgIGNhbGxiYWNrU2NvcGU6IGNhbGxiYWNrU2NvcGUsXG4gICAgICAgIHN0YWdnZXI6IDBcbiAgICAgIH0sIHN0YXJ0QXQpKSk7IC8vY29weSB0aGUgcHJvcGVydGllcy92YWx1ZXMgaW50byBhIG5ldyBvYmplY3QgdG8gYXZvaWQgY29sbGlzaW9ucywgbGlrZSB2YXIgdG8gPSB7eDowfSwgZnJvbSA9IHt4OjUwMH07IHRpbWVsaW5lLmZyb21UbyhlLCBmcm9tLCB0bykuZnJvbVRvKGUsIHRvLCBmcm9tKTtcblxuXG4gICAgICB0d2Vlbi5fc3RhcnRBdC5fZHAgPSAwOyAvLyBkb24ndCBhbGxvdyBpdCB0byBnZXQgcHV0IGJhY2sgaW50byByb290IHRpbWVsaW5lISBMaWtlIHdoZW4gcmV2ZXJ0KCkgaXMgY2FsbGVkIGFuZCB0b3RhbFRpbWUoKSBnZXRzIHNldC5cblxuICAgICAgdHdlZW4uX3N0YXJ0QXQuX3NhdCA9IHR3ZWVuOyAvLyB1c2VkIGluIGdsb2JhbFRpbWUoKS4gX3NhdCBzdGFuZHMgZm9yIF9zdGFydEF0VHdlZW5cblxuICAgICAgdGltZSA8IDAgJiYgKF9yZXZlcnRpbmcgfHwgIWltbWVkaWF0ZVJlbmRlciAmJiAhYXV0b1JldmVydCkgJiYgdHdlZW4uX3N0YXJ0QXQucmV2ZXJ0KF9yZXZlcnRDb25maWdOb0tpbGwpOyAvLyByYXJlIGVkZ2UgY2FzZSwgbGlrZSBpZiBhIHJlbmRlciBpcyBmb3JjZWQgaW4gdGhlIG5lZ2F0aXZlIGRpcmVjdGlvbiBvZiBhIG5vbi1pbml0dGVkIHR3ZWVuLlxuXG4gICAgICBpZiAoaW1tZWRpYXRlUmVuZGVyKSB7XG4gICAgICAgIGlmIChkdXIgJiYgdGltZSA8PSAwICYmIHRUaW1lIDw9IDApIHtcbiAgICAgICAgICAvLyBjaGVjayB0VGltZSBoZXJlIGJlY2F1c2UgaW4gdGhlIGNhc2Ugb2YgYSB5b3lvIHR3ZWVuIHdob3NlIHBsYXloZWFkIGdldHMgcHVzaGVkIHRvIHRoZSBlbmQgbGlrZSB0d2Vlbi5wcm9ncmVzcygxKSwgd2Ugc2hvdWxkIGFsbG93IGl0IHRocm91Z2ggc28gdGhhdCB0aGUgb25Db21wbGV0ZSBnZXRzIGZpcmVkIHByb3Blcmx5LlxuICAgICAgICAgIHRpbWUgJiYgKHR3ZWVuLl96VGltZSA9IHRpbWUpO1xuICAgICAgICAgIHJldHVybjsgLy93ZSBza2lwIGluaXRpYWxpemF0aW9uIGhlcmUgc28gdGhhdCBvdmVyd3JpdGluZyBkb2Vzbid0IG9jY3VyIHVudGlsIHRoZSB0d2VlbiBhY3R1YWxseSBiZWdpbnMuIE90aGVyd2lzZSwgaWYgeW91IGNyZWF0ZSBzZXZlcmFsIGltbWVkaWF0ZVJlbmRlcjp0cnVlIHR3ZWVucyBvZiB0aGUgc2FtZSB0YXJnZXQvcHJvcGVydGllcyB0byBkcm9wIGludG8gYSBUaW1lbGluZSwgdGhlIGxhc3Qgb25lIGNyZWF0ZWQgd291bGQgb3ZlcndyaXRlIHRoZSBmaXJzdCBvbmVzIGJlY2F1c2UgdGhleSBkaWRuJ3QgZ2V0IHBsYWNlZCBpbnRvIHRoZSB0aW1lbGluZSB5ZXQgYmVmb3JlIHRoZSBmaXJzdCByZW5kZXIgb2NjdXJzIGFuZCBraWNrcyBpbiBvdmVyd3JpdGluZy5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocnVuQmFja3dhcmRzICYmIGR1cikge1xuICAgICAgLy9mcm9tKCkgdHdlZW5zIG11c3QgYmUgaGFuZGxlZCB1bmlxdWVseTogdGhlaXIgYmVnaW5uaW5nIHZhbHVlcyBtdXN0IGJlIHJlbmRlcmVkIGJ1dCB3ZSBkb24ndCB3YW50IG92ZXJ3cml0aW5nIHRvIG9jY3VyIHlldCAod2hlbiB0aW1lIGlzIHN0aWxsIDApLiBXYWl0IHVudGlsIHRoZSB0d2VlbiBhY3R1YWxseSBiZWdpbnMgYmVmb3JlIGRvaW5nIGFsbCB0aGUgcm91dGluZXMgbGlrZSBvdmVyd3JpdGluZy4gQXQgdGhhdCB0aW1lLCB3ZSBzaG91bGQgcmVuZGVyIGF0IHRoZSBFTkQgb2YgdGhlIHR3ZWVuIHRvIGVuc3VyZSB0aGF0IHRoaW5ncyBpbml0aWFsaXplIGNvcnJlY3RseSAocmVtZW1iZXIsIGZyb20oKSB0d2VlbnMgZ28gYmFja3dhcmRzKVxuICAgICAgaWYgKCFwcmV2U3RhcnRBdCkge1xuICAgICAgICB0aW1lICYmIChpbW1lZGlhdGVSZW5kZXIgPSBmYWxzZSk7IC8vaW4gcmFyZSBjYXNlcyAobGlrZSBpZiBhIGZyb20oKSB0d2VlbiBydW5zIGFuZCB0aGVuIGlzIGludmFsaWRhdGUoKS1lZCksIGltbWVkaWF0ZVJlbmRlciBjb3VsZCBiZSB0cnVlIGJ1dCB0aGUgaW5pdGlhbCBmb3JjZWQtcmVuZGVyIGdldHMgc2tpcHBlZCwgc28gdGhlcmUncyBubyBuZWVkIHRvIGZvcmNlIHRoZSByZW5kZXIgaW4gdGhpcyBjb250ZXh0IHdoZW4gdGhlIF90aW1lIGlzIGdyZWF0ZXIgdGhhbiAwXG5cbiAgICAgICAgcCA9IF9zZXREZWZhdWx0cyh7XG4gICAgICAgICAgb3ZlcndyaXRlOiBmYWxzZSxcbiAgICAgICAgICBkYXRhOiBcImlzRnJvbVN0YXJ0XCIsXG4gICAgICAgICAgLy93ZSB0YWcgdGhlIHR3ZWVuIHdpdGggYXMgXCJpc0Zyb21TdGFydFwiIHNvIHRoYXQgaWYgW2luc2lkZSBhIHBsdWdpbl0gd2UgbmVlZCB0byBvbmx5IGRvIHNvbWV0aGluZyBhdCB0aGUgdmVyeSBFTkQgb2YgYSB0d2Vlbiwgd2UgaGF2ZSBhIHdheSBvZiBpZGVudGlmeWluZyB0aGlzIHR3ZWVuIGFzIG1lcmVseSB0aGUgb25lIHRoYXQncyBzZXR0aW5nIHRoZSBiZWdpbm5pbmcgdmFsdWVzIGZvciBhIFwiZnJvbSgpXCIgdHdlZW4uIEZvciBleGFtcGxlLCBjbGVhclByb3BzIGluIENTU1BsdWdpbiBzaG91bGQgb25seSBnZXQgYXBwbGllZCBhdCB0aGUgdmVyeSBFTkQgb2YgYSB0d2VlbiBhbmQgd2l0aG91dCB0aGlzIHRhZywgZnJvbSguLi57aGVpZ2h0OjEwMCwgY2xlYXJQcm9wczpcImhlaWdodFwiLCBkZWxheToxfSkgd291bGQgd2lwZSB0aGUgaGVpZ2h0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHR3ZWVuIGFuZCBhZnRlciAxIHNlY29uZCwgaXQnZCBraWNrIGJhY2sgaW4uXG4gICAgICAgICAgbGF6eTogaW1tZWRpYXRlUmVuZGVyICYmICFwcmV2U3RhcnRBdCAmJiBfaXNOb3RGYWxzZShsYXp5KSxcbiAgICAgICAgICBpbW1lZGlhdGVSZW5kZXI6IGltbWVkaWF0ZVJlbmRlcixcbiAgICAgICAgICAvL3plcm8tZHVyYXRpb24gdHdlZW5zIHJlbmRlciBpbW1lZGlhdGVseSBieSBkZWZhdWx0LCBidXQgaWYgd2UncmUgbm90IHNwZWNpZmljYWxseSBpbnN0cnVjdGVkIHRvIHJlbmRlciB0aGlzIHR3ZWVuIGltbWVkaWF0ZWx5LCB3ZSBzaG91bGQgc2tpcCB0aGlzIGFuZCBtZXJlbHkgX2luaXQoKSB0byByZWNvcmQgdGhlIHN0YXJ0aW5nIHZhbHVlcyAocmVuZGVyaW5nIHRoZW0gaW1tZWRpYXRlbHkgd291bGQgcHVzaCB0aGVtIHRvIGNvbXBsZXRpb24gd2hpY2ggaXMgd2FzdGVmdWwgaW4gdGhhdCBjYXNlIC0gd2UnZCBoYXZlIHRvIHJlbmRlcigtMSkgaW1tZWRpYXRlbHkgYWZ0ZXIpXG4gICAgICAgICAgc3RhZ2dlcjogMCxcbiAgICAgICAgICBwYXJlbnQ6IHBhcmVudCAvL2Vuc3VyZXMgdGhhdCBuZXN0ZWQgdHdlZW5zIHRoYXQgaGFkIGEgc3RhZ2dlciBhcmUgaGFuZGxlZCBwcm9wZXJseSwgbGlrZSBnc2FwLmZyb20oXCIuY2xhc3NcIiwge3k6Z3NhcC51dGlscy53cmFwKFstMTAwLDEwMF0pfSlcblxuICAgICAgICB9LCBjbGVhblZhcnMpO1xuICAgICAgICBoYXJuZXNzVmFycyAmJiAocFtoYXJuZXNzLnByb3BdID0gaGFybmVzc1ZhcnMpOyAvLyBpbiBjYXNlIHNvbWVvbmUgZG9lcyBzb21ldGhpbmcgbGlrZSAuZnJvbSguLi4sIHtjc3M6e319KVxuXG4gICAgICAgIF9yZW1vdmVGcm9tUGFyZW50KHR3ZWVuLl9zdGFydEF0ID0gVHdlZW4uc2V0KHRhcmdldHMsIHApKTtcblxuICAgICAgICB0d2Vlbi5fc3RhcnRBdC5fZHAgPSAwOyAvLyBkb24ndCBhbGxvdyBpdCB0byBnZXQgcHV0IGJhY2sgaW50byByb290IHRpbWVsaW5lIVxuXG4gICAgICAgIHR3ZWVuLl9zdGFydEF0Ll9zYXQgPSB0d2VlbjsgLy8gdXNlZCBpbiBnbG9iYWxUaW1lKClcblxuICAgICAgICB0aW1lIDwgMCAmJiAoX3JldmVydGluZyA/IHR3ZWVuLl9zdGFydEF0LnJldmVydChfcmV2ZXJ0Q29uZmlnTm9LaWxsKSA6IHR3ZWVuLl9zdGFydEF0LnJlbmRlcigtMSwgdHJ1ZSkpO1xuICAgICAgICB0d2Vlbi5felRpbWUgPSB0aW1lO1xuXG4gICAgICAgIGlmICghaW1tZWRpYXRlUmVuZGVyKSB7XG4gICAgICAgICAgX2luaXRUd2Vlbih0d2Vlbi5fc3RhcnRBdCwgX3RpbnlOdW0sIF90aW55TnVtKTsgLy9lbnN1cmVzIHRoYXQgdGhlIGluaXRpYWwgdmFsdWVzIGFyZSByZWNvcmRlZFxuXG4gICAgICAgIH0gZWxzZSBpZiAoIXRpbWUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0d2Vlbi5fcHQgPSB0d2Vlbi5fcHRDYWNoZSA9IDA7XG4gICAgbGF6eSA9IGR1ciAmJiBfaXNOb3RGYWxzZShsYXp5KSB8fCBsYXp5ICYmICFkdXI7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgdGFyZ2V0ID0gdGFyZ2V0c1tpXTtcbiAgICAgIGdzRGF0YSA9IHRhcmdldC5fZ3NhcCB8fCBfaGFybmVzcyh0YXJnZXRzKVtpXS5fZ3NhcDtcbiAgICAgIHR3ZWVuLl9wdExvb2t1cFtpXSA9IHB0TG9va3VwID0ge307XG4gICAgICBfbGF6eUxvb2t1cFtnc0RhdGEuaWRdICYmIF9sYXp5VHdlZW5zLmxlbmd0aCAmJiBfbGF6eVJlbmRlcigpOyAvL2lmIG90aGVyIHR3ZWVucyBvZiB0aGUgc2FtZSB0YXJnZXQgaGF2ZSByZWNlbnRseSBpbml0dGVkIGJ1dCBoYXZlbid0IHJlbmRlcmVkIHlldCwgd2UndmUgZ290IHRvIGZvcmNlIHRoZSByZW5kZXIgc28gdGhhdCB0aGUgc3RhcnRpbmcgdmFsdWVzIGFyZSBjb3JyZWN0IChpbWFnaW5lIHBvcHVsYXRpbmcgYSB0aW1lbGluZSB3aXRoIGEgYnVuY2ggb2Ygc2VxdWVudGlhbCB0d2VlbnMgYW5kIHRoZW4ganVtcGluZyB0byB0aGUgZW5kKVxuXG4gICAgICBpbmRleCA9IGZ1bGxUYXJnZXRzID09PSB0YXJnZXRzID8gaSA6IGZ1bGxUYXJnZXRzLmluZGV4T2YodGFyZ2V0KTtcblxuICAgICAgaWYgKGhhcm5lc3MgJiYgKHBsdWdpbiA9IG5ldyBoYXJuZXNzKCkpLmluaXQodGFyZ2V0LCBoYXJuZXNzVmFycyB8fCBjbGVhblZhcnMsIHR3ZWVuLCBpbmRleCwgZnVsbFRhcmdldHMpICE9PSBmYWxzZSkge1xuICAgICAgICB0d2Vlbi5fcHQgPSBwdCA9IG5ldyBQcm9wVHdlZW4odHdlZW4uX3B0LCB0YXJnZXQsIHBsdWdpbi5uYW1lLCAwLCAxLCBwbHVnaW4ucmVuZGVyLCBwbHVnaW4sIDAsIHBsdWdpbi5wcmlvcml0eSk7XG5cbiAgICAgICAgcGx1Z2luLl9wcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgcHRMb29rdXBbbmFtZV0gPSBwdDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcGx1Z2luLnByaW9yaXR5ICYmIChoYXNQcmlvcml0eSA9IDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWhhcm5lc3MgfHwgaGFybmVzc1ZhcnMpIHtcbiAgICAgICAgZm9yIChwIGluIGNsZWFuVmFycykge1xuICAgICAgICAgIGlmIChfcGx1Z2luc1twXSAmJiAocGx1Z2luID0gX2NoZWNrUGx1Z2luKHAsIGNsZWFuVmFycywgdHdlZW4sIGluZGV4LCB0YXJnZXQsIGZ1bGxUYXJnZXRzKSkpIHtcbiAgICAgICAgICAgIHBsdWdpbi5wcmlvcml0eSAmJiAoaGFzUHJpb3JpdHkgPSAxKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHRMb29rdXBbcF0gPSBwdCA9IF9hZGRQcm9wVHdlZW4uY2FsbCh0d2VlbiwgdGFyZ2V0LCBwLCBcImdldFwiLCBjbGVhblZhcnNbcF0sIGluZGV4LCBmdWxsVGFyZ2V0cywgMCwgdmFycy5zdHJpbmdGaWx0ZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0d2Vlbi5fb3AgJiYgdHdlZW4uX29wW2ldICYmIHR3ZWVuLmtpbGwodGFyZ2V0LCB0d2Vlbi5fb3BbaV0pO1xuXG4gICAgICBpZiAoYXV0b092ZXJ3cml0ZSAmJiB0d2Vlbi5fcHQpIHtcbiAgICAgICAgX292ZXJ3cml0aW5nVHdlZW4gPSB0d2VlbjtcblxuICAgICAgICBfZ2xvYmFsVGltZWxpbmUua2lsbFR3ZWVuc09mKHRhcmdldCwgcHRMb29rdXAsIHR3ZWVuLmdsb2JhbFRpbWUodGltZSkpOyAvLyBtYWtlIHN1cmUgdGhlIG92ZXJ3cml0aW5nIGRvZXNuJ3Qgb3ZlcndyaXRlIFRISVMgdHdlZW4hISFcblxuXG4gICAgICAgIG92ZXJ3cml0dGVuID0gIXR3ZWVuLnBhcmVudDtcbiAgICAgICAgX292ZXJ3cml0aW5nVHdlZW4gPSAwO1xuICAgICAgfVxuXG4gICAgICB0d2Vlbi5fcHQgJiYgbGF6eSAmJiAoX2xhenlMb29rdXBbZ3NEYXRhLmlkXSA9IDEpO1xuICAgIH1cblxuICAgIGhhc1ByaW9yaXR5ICYmIF9zb3J0UHJvcFR3ZWVuc0J5UHJpb3JpdHkodHdlZW4pO1xuICAgIHR3ZWVuLl9vbkluaXQgJiYgdHdlZW4uX29uSW5pdCh0d2Vlbik7IC8vcGx1Z2lucyBsaWtlIFJvdW5kUHJvcHMgbXVzdCB3YWl0IHVudGlsIEFMTCBvZiB0aGUgUHJvcFR3ZWVucyBhcmUgaW5zdGFudGlhdGVkLiBJbiB0aGUgcGx1Z2luJ3MgaW5pdCgpIGZ1bmN0aW9uLCBpdCBzZXRzIHRoZSBfb25Jbml0IG9uIHRoZSB0d2VlbiBpbnN0YW5jZS4gTWF5IG5vdCBiZSBwcmV0dHkvaW50dWl0aXZlLCBidXQgaXQncyBmYXN0IGFuZCBrZWVwcyBmaWxlIHNpemUgZG93bi5cbiAgfVxuXG4gIHR3ZWVuLl9vblVwZGF0ZSA9IG9uVXBkYXRlO1xuICB0d2Vlbi5faW5pdHRlZCA9ICghdHdlZW4uX29wIHx8IHR3ZWVuLl9wdCkgJiYgIW92ZXJ3cml0dGVuOyAvLyBpZiBvdmVyd3JpdHRlblByb3BzIHJlc3VsdGVkIGluIHRoZSBlbnRpcmUgdHdlZW4gYmVpbmcga2lsbGVkLCBkbyBOT1QgZmxhZyBpdCBhcyBpbml0dGVkIG9yIGVsc2UgaXQgbWF5IHJlbmRlciBmb3Igb25lIHRpY2suXG5cbiAga2V5ZnJhbWVzICYmIHRpbWUgPD0gMCAmJiB0bC5yZW5kZXIoX2JpZ051bSwgdHJ1ZSwgdHJ1ZSk7IC8vIGlmIHRoZXJlJ3MgYSAwJSBrZXlmcmFtZSwgaXQnbGwgcmVuZGVyIGluIHRoZSBcImJlZm9yZVwiIHN0YXRlIGZvciBhbnkgc3RhZ2dlcmVkL2RlbGF5ZWQgYW5pbWF0aW9ucyB0aHVzIHdoZW4gdGhlIGZvbGxvd2luZyB0d2VlbiBpbml0aWFsaXplcywgaXQnbGwgdXNlIHRoZSBcImJlZm9yZVwiIHN0YXRlIGluc3RlYWQgb2YgdGhlIFwiYWZ0ZXJcIiBzdGF0ZSBhcyB0aGUgaW5pdGlhbCB2YWx1ZXMuXG59LFxuICAgIF91cGRhdGVQcm9wVHdlZW5zID0gZnVuY3Rpb24gX3VwZGF0ZVByb3BUd2VlbnModHdlZW4sIHByb3BlcnR5LCB2YWx1ZSwgc3RhcnQsIHN0YXJ0SXNSZWxhdGl2ZSwgcmF0aW8sIHRpbWUpIHtcbiAgdmFyIHB0Q2FjaGUgPSAodHdlZW4uX3B0ICYmIHR3ZWVuLl9wdENhY2hlIHx8ICh0d2Vlbi5fcHRDYWNoZSA9IHt9KSlbcHJvcGVydHldLFxuICAgICAgcHQsXG4gICAgICByb290UFQsXG4gICAgICBsb29rdXAsXG4gICAgICBpO1xuXG4gIGlmICghcHRDYWNoZSkge1xuICAgIHB0Q2FjaGUgPSB0d2Vlbi5fcHRDYWNoZVtwcm9wZXJ0eV0gPSBbXTtcbiAgICBsb29rdXAgPSB0d2Vlbi5fcHRMb29rdXA7XG4gICAgaSA9IHR3ZWVuLl90YXJnZXRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHB0ID0gbG9va3VwW2ldW3Byb3BlcnR5XTtcblxuICAgICAgaWYgKHB0ICYmIHB0LmQgJiYgcHQuZC5fcHQpIHtcbiAgICAgICAgLy8gaXQncyBhIHBsdWdpbiwgc28gZmluZCB0aGUgbmVzdGVkIFByb3BUd2VlblxuICAgICAgICBwdCA9IHB0LmQuX3B0O1xuXG4gICAgICAgIHdoaWxlIChwdCAmJiBwdC5wICE9PSBwcm9wZXJ0eSAmJiBwdC5mcCAhPT0gcHJvcGVydHkpIHtcbiAgICAgICAgICAvLyBcImZwXCIgaXMgZnVuY3Rpb25QYXJhbSBmb3IgdGhpbmdzIGxpa2Ugc2V0dGluZyBDU1MgdmFyaWFibGVzIHdoaWNoIHJlcXVpcmUgLnNldFByb3BlcnR5KFwiLS12YXItbmFtZVwiLCB2YWx1ZSlcbiAgICAgICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghcHQpIHtcbiAgICAgICAgLy8gdGhlcmUgaXMgbm8gUHJvcFR3ZWVuIGFzc29jaWF0ZWQgd2l0aCB0aGF0IHByb3BlcnR5LCBzbyB3ZSBtdXN0IEZPUkNFIG9uZSB0byBiZSBjcmVhdGVkIGFuZCBkaXRjaCBvdXQgb2YgdGhpc1xuICAgICAgICAvLyBpZiB0aGUgdHdlZW4gaGFzIG90aGVyIHByb3BlcnRpZXMgdGhhdCBhbHJlYWR5IHJlbmRlcmVkIGF0IG5ldyBwb3NpdGlvbnMsIHdlJ2Qgbm9ybWFsbHkgaGF2ZSB0byByZXdpbmQgdG8gcHV0IHRoZW0gYmFjayBsaWtlIHR3ZWVuLnJlbmRlcigwLCB0cnVlKSBiZWZvcmUgZm9yY2luZyBhbiBfaW5pdFR3ZWVuKCksIGJ1dCB0aGF0IGNhbiBjcmVhdGUgYW5vdGhlciBlZGdlIGNhc2UgbGlrZSB0d2VlbmluZyBhIHRpbWVsaW5lJ3MgcHJvZ3Jlc3Mgd291bGQgdHJpZ2dlciBvblVwZGF0ZXMgdG8gZmlyZSB3aGljaCBjb3VsZCBtb3ZlIG90aGVyIHRoaW5ncyBhcm91bmQuIEl0J3MgYmV0dGVyIHRvIGp1c3QgaW5mb3JtIHVzZXJzIHRoYXQgLnJlc2V0VG8oKSBzaG91bGQgT05MWSBiZSB1c2VkIGZvciB0d2VlbnMgdGhhdCBhbHJlYWR5IGhhdmUgdGhhdCBwcm9wZXJ0eS4gRm9yIGV4YW1wbGUsIHlvdSBjYW4ndCBnc2FwLnRvKC4uLnsgeTogMCB9KSBhbmQgdGhlbiB0d2Vlbi5yZXN0VG8oXCJ4XCIsIDIwMCkgZm9yIGV4YW1wbGUuXG4gICAgICAgIF9mb3JjZUFsbFByb3BUd2VlbnMgPSAxOyAvLyBvdGhlcndpc2UsIHdoZW4gd2UgX2FkZFByb3BUd2VlbigpIGFuZCBpdCBmaW5kcyBubyBjaGFuZ2UgYmV0d2VlbiB0aGUgc3RhcnQgYW5kIGVuZCB2YWx1ZXMsIGl0IHNraXBzIGNyZWF0aW5nIGEgUHJvcFR3ZWVuIChmb3IgZWZmaWNpZW5jeS4uLndoeSB0d2VlbiB3aGVuIHRoZXJlJ3Mgbm8gZGlmZmVyZW5jZT8pIGJ1dCBpbiB0aGlzIGNhc2Ugd2UgTkVFRCB0aGF0IFByb3BUd2VlbiBjcmVhdGVkIHNvIHdlIGNhbiBlZGl0IGl0LlxuXG4gICAgICAgIHR3ZWVuLnZhcnNbcHJvcGVydHldID0gXCIrPTBcIjtcblxuICAgICAgICBfaW5pdFR3ZWVuKHR3ZWVuLCB0aW1lKTtcblxuICAgICAgICBfZm9yY2VBbGxQcm9wVHdlZW5zID0gMDtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG5cbiAgICAgIHB0Q2FjaGUucHVzaChwdCk7XG4gICAgfVxuICB9XG5cbiAgaSA9IHB0Q2FjaGUubGVuZ3RoO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICByb290UFQgPSBwdENhY2hlW2ldO1xuICAgIHB0ID0gcm9vdFBULl9wdCB8fCByb290UFQ7IC8vIGNvbXBsZXggdmFsdWVzIG1heSBoYXZlIG5lc3RlZCBQcm9wVHdlZW5zLiBXZSBvbmx5IGFjY29tbW9kYXRlIHRoZSBGSVJTVCB2YWx1ZS5cblxuICAgIHB0LnMgPSAoc3RhcnQgfHwgc3RhcnQgPT09IDApICYmICFzdGFydElzUmVsYXRpdmUgPyBzdGFydCA6IHB0LnMgKyAoc3RhcnQgfHwgMCkgKyByYXRpbyAqIHB0LmM7XG4gICAgcHQuYyA9IHZhbHVlIC0gcHQucztcbiAgICByb290UFQuZSAmJiAocm9vdFBULmUgPSBfcm91bmQodmFsdWUpICsgZ2V0VW5pdChyb290UFQuZSkpOyAvLyBtYWlubHkgZm9yIENTU1BsdWdpbiAoZW5kIHZhbHVlKVxuXG4gICAgcm9vdFBULmIgJiYgKHJvb3RQVC5iID0gcHQucyArIGdldFVuaXQocm9vdFBULmIpKTsgLy8gKGJlZ2lubmluZyB2YWx1ZSlcbiAgfVxufSxcbiAgICBfYWRkQWxpYXNlc1RvVmFycyA9IGZ1bmN0aW9uIF9hZGRBbGlhc2VzVG9WYXJzKHRhcmdldHMsIHZhcnMpIHtcbiAgdmFyIGhhcm5lc3MgPSB0YXJnZXRzWzBdID8gX2dldENhY2hlKHRhcmdldHNbMF0pLmhhcm5lc3MgOiAwLFxuICAgICAgcHJvcGVydHlBbGlhc2VzID0gaGFybmVzcyAmJiBoYXJuZXNzLmFsaWFzZXMsXG4gICAgICBjb3B5LFxuICAgICAgcCxcbiAgICAgIGksXG4gICAgICBhbGlhc2VzO1xuXG4gIGlmICghcHJvcGVydHlBbGlhc2VzKSB7XG4gICAgcmV0dXJuIHZhcnM7XG4gIH1cblxuICBjb3B5ID0gX21lcmdlKHt9LCB2YXJzKTtcblxuICBmb3IgKHAgaW4gcHJvcGVydHlBbGlhc2VzKSB7XG4gICAgaWYgKHAgaW4gY29weSkge1xuICAgICAgYWxpYXNlcyA9IHByb3BlcnR5QWxpYXNlc1twXS5zcGxpdChcIixcIik7XG4gICAgICBpID0gYWxpYXNlcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgY29weVthbGlhc2VzW2ldXSA9IGNvcHlbcF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvcHk7XG59LFxuICAgIC8vIHBhcnNlcyBtdWx0aXBsZSBmb3JtYXRzLCBsaWtlIHtcIjAlXCI6IHt4OiAxMDB9LCB7XCI1MCVcIjoge3g6IC0yMH19IGFuZCB7IHg6IHtcIjAlXCI6IDEwMCwgXCI1MCVcIjogLTIwfSB9LCBhbmQgYW4gXCJlYXNlXCIgY2FuIGJlIHNldCBvbiBhbnkgb2JqZWN0LiBXZSBwb3B1bGF0ZSBhbiBcImFsbFByb3BzXCIgb2JqZWN0IHdpdGggYW4gQXJyYXkgZm9yIGVhY2ggcHJvcGVydHksIGxpa2Uge3g6IFt7fSwge31dLCB5Olt7fSwge31dfSB3aXRoIGRhdGEgZm9yIGVhY2ggcHJvcGVydHkgdHdlZW4uIFRoZSBvYmplY3RzIGhhdmUgYSBcInRcIiAodGltZSksIFwidlwiLCAodmFsdWUpLCBhbmQgXCJlXCIgKGVhc2UpIHByb3BlcnR5LiBUaGlzIGFsbG93cyB1cyB0byBwaWVjZSB0b2dldGhlciBhIHRpbWVsaW5lIGxhdGVyLlxuX3BhcnNlS2V5ZnJhbWUgPSBmdW5jdGlvbiBfcGFyc2VLZXlmcmFtZShwcm9wLCBvYmosIGFsbFByb3BzLCBlYXNlRWFjaCkge1xuICB2YXIgZWFzZSA9IG9iai5lYXNlIHx8IGVhc2VFYWNoIHx8IFwicG93ZXIxLmluT3V0XCIsXG4gICAgICBwLFxuICAgICAgYTtcblxuICBpZiAoX2lzQXJyYXkob2JqKSkge1xuICAgIGEgPSBhbGxQcm9wc1twcm9wXSB8fCAoYWxsUHJvcHNbcHJvcF0gPSBbXSk7IC8vIHQgPSB0aW1lIChvdXQgb2YgMTAwKSwgdiA9IHZhbHVlLCBlID0gZWFzZVxuXG4gICAgb2JqLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBpKSB7XG4gICAgICByZXR1cm4gYS5wdXNoKHtcbiAgICAgICAgdDogaSAvIChvYmoubGVuZ3RoIC0gMSkgKiAxMDAsXG4gICAgICAgIHY6IHZhbHVlLFxuICAgICAgICBlOiBlYXNlXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHAgaW4gb2JqKSB7XG4gICAgICBhID0gYWxsUHJvcHNbcF0gfHwgKGFsbFByb3BzW3BdID0gW10pO1xuICAgICAgcCA9PT0gXCJlYXNlXCIgfHwgYS5wdXNoKHtcbiAgICAgICAgdDogcGFyc2VGbG9hdChwcm9wKSxcbiAgICAgICAgdjogb2JqW3BdLFxuICAgICAgICBlOiBlYXNlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn0sXG4gICAgX3BhcnNlRnVuY09yU3RyaW5nID0gZnVuY3Rpb24gX3BhcnNlRnVuY09yU3RyaW5nKHZhbHVlLCB0d2VlbiwgaSwgdGFyZ2V0LCB0YXJnZXRzKSB7XG4gIHJldHVybiBfaXNGdW5jdGlvbih2YWx1ZSkgPyB2YWx1ZS5jYWxsKHR3ZWVuLCBpLCB0YXJnZXQsIHRhcmdldHMpIDogX2lzU3RyaW5nKHZhbHVlKSAmJiB+dmFsdWUuaW5kZXhPZihcInJhbmRvbShcIikgPyBfcmVwbGFjZVJhbmRvbSh2YWx1ZSkgOiB2YWx1ZTtcbn0sXG4gICAgX3N0YWdnZXJUd2VlblByb3BzID0gX2NhbGxiYWNrTmFtZXMgKyBcInJlcGVhdCxyZXBlYXREZWxheSx5b3lvLHJlcGVhdFJlZnJlc2gseW95b0Vhc2UsYXV0b1JldmVydFwiLFxuICAgIF9zdGFnZ2VyUHJvcHNUb1NraXAgPSB7fTtcblxuX2ZvckVhY2hOYW1lKF9zdGFnZ2VyVHdlZW5Qcm9wcyArIFwiLGlkLHN0YWdnZXIsZGVsYXksZHVyYXRpb24scGF1c2VkLHNjcm9sbFRyaWdnZXJcIiwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIF9zdGFnZ2VyUHJvcHNUb1NraXBbbmFtZV0gPSAxO1xufSk7XG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIFRXRUVOXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuZXhwb3J0IHZhciBUd2VlbiA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0FuaW1hdGlvbjIpIHtcbiAgX2luaGVyaXRzTG9vc2UoVHdlZW4sIF9BbmltYXRpb24yKTtcblxuICBmdW5jdGlvbiBUd2Vlbih0YXJnZXRzLCB2YXJzLCBwb3NpdGlvbiwgc2tpcEluaGVyaXQpIHtcbiAgICB2YXIgX3RoaXMzO1xuXG4gICAgaWYgKHR5cGVvZiB2YXJzID09PSBcIm51bWJlclwiKSB7XG4gICAgICBwb3NpdGlvbi5kdXJhdGlvbiA9IHZhcnM7XG4gICAgICB2YXJzID0gcG9zaXRpb247XG4gICAgICBwb3NpdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgX3RoaXMzID0gX0FuaW1hdGlvbjIuY2FsbCh0aGlzLCBza2lwSW5oZXJpdCA/IHZhcnMgOiBfaW5oZXJpdERlZmF1bHRzKHZhcnMpKSB8fCB0aGlzO1xuICAgIHZhciBfdGhpczMkdmFycyA9IF90aGlzMy52YXJzLFxuICAgICAgICBkdXJhdGlvbiA9IF90aGlzMyR2YXJzLmR1cmF0aW9uLFxuICAgICAgICBkZWxheSA9IF90aGlzMyR2YXJzLmRlbGF5LFxuICAgICAgICBpbW1lZGlhdGVSZW5kZXIgPSBfdGhpczMkdmFycy5pbW1lZGlhdGVSZW5kZXIsXG4gICAgICAgIHN0YWdnZXIgPSBfdGhpczMkdmFycy5zdGFnZ2VyLFxuICAgICAgICBvdmVyd3JpdGUgPSBfdGhpczMkdmFycy5vdmVyd3JpdGUsXG4gICAgICAgIGtleWZyYW1lcyA9IF90aGlzMyR2YXJzLmtleWZyYW1lcyxcbiAgICAgICAgZGVmYXVsdHMgPSBfdGhpczMkdmFycy5kZWZhdWx0cyxcbiAgICAgICAgc2Nyb2xsVHJpZ2dlciA9IF90aGlzMyR2YXJzLnNjcm9sbFRyaWdnZXIsXG4gICAgICAgIHlveW9FYXNlID0gX3RoaXMzJHZhcnMueW95b0Vhc2UsXG4gICAgICAgIHBhcmVudCA9IHZhcnMucGFyZW50IHx8IF9nbG9iYWxUaW1lbGluZSxcbiAgICAgICAgcGFyc2VkVGFyZ2V0cyA9IChfaXNBcnJheSh0YXJnZXRzKSB8fCBfaXNUeXBlZEFycmF5KHRhcmdldHMpID8gX2lzTnVtYmVyKHRhcmdldHNbMF0pIDogXCJsZW5ndGhcIiBpbiB2YXJzKSA/IFt0YXJnZXRzXSA6IHRvQXJyYXkodGFyZ2V0cyksXG4gICAgICAgIHRsLFxuICAgICAgICBpLFxuICAgICAgICBjb3B5LFxuICAgICAgICBsLFxuICAgICAgICBwLFxuICAgICAgICBjdXJUYXJnZXQsXG4gICAgICAgIHN0YWdnZXJGdW5jLFxuICAgICAgICBzdGFnZ2VyVmFyc1RvTWVyZ2U7XG4gICAgX3RoaXMzLl90YXJnZXRzID0gcGFyc2VkVGFyZ2V0cy5sZW5ndGggPyBfaGFybmVzcyhwYXJzZWRUYXJnZXRzKSA6IF93YXJuKFwiR1NBUCB0YXJnZXQgXCIgKyB0YXJnZXRzICsgXCIgbm90IGZvdW5kLiBodHRwczovL2dyZWVuc29jay5jb21cIiwgIV9jb25maWcubnVsbFRhcmdldFdhcm4pIHx8IFtdO1xuICAgIF90aGlzMy5fcHRMb29rdXAgPSBbXTsgLy9Qcm9wVHdlZW4gbG9va3VwLiBBbiBhcnJheSBjb250YWluaW5nIGFuIG9iamVjdCBmb3IgZWFjaCB0YXJnZXQsIGhhdmluZyBrZXlzIGZvciBlYWNoIHR3ZWVuaW5nIHByb3BlcnR5XG5cbiAgICBfdGhpczMuX292ZXJ3cml0ZSA9IG92ZXJ3cml0ZTtcblxuICAgIGlmIChrZXlmcmFtZXMgfHwgc3RhZ2dlciB8fCBfaXNGdW5jT3JTdHJpbmcoZHVyYXRpb24pIHx8IF9pc0Z1bmNPclN0cmluZyhkZWxheSkpIHtcbiAgICAgIHZhcnMgPSBfdGhpczMudmFycztcbiAgICAgIHRsID0gX3RoaXMzLnRpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHtcbiAgICAgICAgZGF0YTogXCJuZXN0ZWRcIixcbiAgICAgICAgZGVmYXVsdHM6IGRlZmF1bHRzIHx8IHt9LFxuICAgICAgICB0YXJnZXRzOiBwYXJlbnQgJiYgcGFyZW50LmRhdGEgPT09IFwibmVzdGVkXCIgPyBwYXJlbnQudmFycy50YXJnZXRzIDogcGFyc2VkVGFyZ2V0c1xuICAgICAgfSk7IC8vIHdlIG5lZWQgdG8gc3RvcmUgdGhlIHRhcmdldHMgYmVjYXVzZSBmb3Igc3RhZ2dlcnMgYW5kIGtleWZyYW1lcywgd2UgZW5kIHVwIGNyZWF0aW5nIGFuIGluZGl2aWR1YWwgdHdlZW4gZm9yIGVhY2ggYnV0IGZ1bmN0aW9uLWJhc2VkIHZhbHVlcyBuZWVkIHRvIGtub3cgdGhlIGluZGV4IGFuZCB0aGUgd2hvbGUgQXJyYXkgb2YgdGFyZ2V0cy5cblxuICAgICAgdGwua2lsbCgpO1xuICAgICAgdGwucGFyZW50ID0gdGwuX2RwID0gX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpO1xuICAgICAgdGwuX3N0YXJ0ID0gMDtcblxuICAgICAgaWYgKHN0YWdnZXIgfHwgX2lzRnVuY09yU3RyaW5nKGR1cmF0aW9uKSB8fCBfaXNGdW5jT3JTdHJpbmcoZGVsYXkpKSB7XG4gICAgICAgIGwgPSBwYXJzZWRUYXJnZXRzLmxlbmd0aDtcbiAgICAgICAgc3RhZ2dlckZ1bmMgPSBzdGFnZ2VyICYmIGRpc3RyaWJ1dGUoc3RhZ2dlcik7XG5cbiAgICAgICAgaWYgKF9pc09iamVjdChzdGFnZ2VyKSkge1xuICAgICAgICAgIC8vdXNlcnMgY2FuIHBhc3MgaW4gY2FsbGJhY2tzIGxpa2Ugb25TdGFydC9vbkNvbXBsZXRlIGluIHRoZSBzdGFnZ2VyIG9iamVjdC4gVGhlc2Ugc2hvdWxkIGZpcmUgd2l0aCBlYWNoIGluZGl2aWR1YWwgdHdlZW4uXG4gICAgICAgICAgZm9yIChwIGluIHN0YWdnZXIpIHtcbiAgICAgICAgICAgIGlmICh+X3N0YWdnZXJUd2VlblByb3BzLmluZGV4T2YocCkpIHtcbiAgICAgICAgICAgICAgc3RhZ2dlclZhcnNUb01lcmdlIHx8IChzdGFnZ2VyVmFyc1RvTWVyZ2UgPSB7fSk7XG4gICAgICAgICAgICAgIHN0YWdnZXJWYXJzVG9NZXJnZVtwXSA9IHN0YWdnZXJbcF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgIGNvcHkgPSBfY29weUV4Y2x1ZGluZyh2YXJzLCBfc3RhZ2dlclByb3BzVG9Ta2lwKTtcbiAgICAgICAgICBjb3B5LnN0YWdnZXIgPSAwO1xuICAgICAgICAgIHlveW9FYXNlICYmIChjb3B5LnlveW9FYXNlID0geW95b0Vhc2UpO1xuICAgICAgICAgIHN0YWdnZXJWYXJzVG9NZXJnZSAmJiBfbWVyZ2UoY29weSwgc3RhZ2dlclZhcnNUb01lcmdlKTtcbiAgICAgICAgICBjdXJUYXJnZXQgPSBwYXJzZWRUYXJnZXRzW2ldOyAvL2Rvbid0IGp1c3QgY29weSBkdXJhdGlvbiBvciBkZWxheSBiZWNhdXNlIGlmIHRoZXkncmUgYSBzdHJpbmcgb3IgZnVuY3Rpb24sIHdlJ2QgZW5kIHVwIGluIGFuIGluZmluaXRlIGxvb3AgYmVjYXVzZSBfaXNGdW5jT3JTdHJpbmcoKSB3b3VsZCBldmFsdWF0ZSBhcyB0cnVlIGluIHRoZSBjaGlsZCB0d2VlbnMsIGVudGVyaW5nIHRoaXMgbG9vcCwgZXRjLiBTbyB3ZSBwYXJzZSB0aGUgdmFsdWUgc3RyYWlnaHQgZnJvbSB2YXJzIGFuZCBkZWZhdWx0IHRvIDAuXG5cbiAgICAgICAgICBjb3B5LmR1cmF0aW9uID0gK19wYXJzZUZ1bmNPclN0cmluZyhkdXJhdGlvbiwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBpLCBjdXJUYXJnZXQsIHBhcnNlZFRhcmdldHMpO1xuICAgICAgICAgIGNvcHkuZGVsYXkgPSAoK19wYXJzZUZ1bmNPclN0cmluZyhkZWxheSwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBpLCBjdXJUYXJnZXQsIHBhcnNlZFRhcmdldHMpIHx8IDApIC0gX3RoaXMzLl9kZWxheTtcblxuICAgICAgICAgIGlmICghc3RhZ2dlciAmJiBsID09PSAxICYmIGNvcHkuZGVsYXkpIHtcbiAgICAgICAgICAgIC8vIGlmIHNvbWVvbmUgZG9lcyBkZWxheTpcInJhbmRvbSgxLCA1KVwiLCByZXBlYXQ6LTEsIGZvciBleGFtcGxlLCB0aGUgZGVsYXkgc2hvdWxkbid0IGJlIGluc2lkZSB0aGUgcmVwZWF0LlxuICAgICAgICAgICAgX3RoaXMzLl9kZWxheSA9IGRlbGF5ID0gY29weS5kZWxheTtcbiAgICAgICAgICAgIF90aGlzMy5fc3RhcnQgKz0gZGVsYXk7XG4gICAgICAgICAgICBjb3B5LmRlbGF5ID0gMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0bC50byhjdXJUYXJnZXQsIGNvcHksIHN0YWdnZXJGdW5jID8gc3RhZ2dlckZ1bmMoaSwgY3VyVGFyZ2V0LCBwYXJzZWRUYXJnZXRzKSA6IDApO1xuICAgICAgICAgIHRsLl9lYXNlID0gX2Vhc2VNYXAubm9uZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRsLmR1cmF0aW9uKCkgPyBkdXJhdGlvbiA9IGRlbGF5ID0gMCA6IF90aGlzMy50aW1lbGluZSA9IDA7IC8vIGlmIHRoZSB0aW1lbGluZSdzIGR1cmF0aW9uIGlzIDAsIHdlIGRvbid0IG5lZWQgYSB0aW1lbGluZSBpbnRlcm5hbGx5IVxuICAgICAgfSBlbHNlIGlmIChrZXlmcmFtZXMpIHtcbiAgICAgICAgX2luaGVyaXREZWZhdWx0cyhfc2V0RGVmYXVsdHModGwudmFycy5kZWZhdWx0cywge1xuICAgICAgICAgIGVhc2U6IFwibm9uZVwiXG4gICAgICAgIH0pKTtcblxuICAgICAgICB0bC5fZWFzZSA9IF9wYXJzZUVhc2Uoa2V5ZnJhbWVzLmVhc2UgfHwgdmFycy5lYXNlIHx8IFwibm9uZVwiKTtcbiAgICAgICAgdmFyIHRpbWUgPSAwLFxuICAgICAgICAgICAgYSxcbiAgICAgICAgICAgIGtmLFxuICAgICAgICAgICAgdjtcblxuICAgICAgICBpZiAoX2lzQXJyYXkoa2V5ZnJhbWVzKSkge1xuICAgICAgICAgIGtleWZyYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChmcmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRsLnRvKHBhcnNlZFRhcmdldHMsIGZyYW1lLCBcIj5cIik7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGwuZHVyYXRpb24oKTsgLy8gdG8gZW5zdXJlIHRsLl9kdXIgaXMgY2FjaGVkIGJlY2F1c2Ugd2UgdGFwIGludG8gaXQgZm9yIHBlcmZvcm1hbmNlIHB1cnBvc2VzIGluIHRoZSByZW5kZXIoKSBtZXRob2QuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29weSA9IHt9O1xuXG4gICAgICAgICAgZm9yIChwIGluIGtleWZyYW1lcykge1xuICAgICAgICAgICAgcCA9PT0gXCJlYXNlXCIgfHwgcCA9PT0gXCJlYXNlRWFjaFwiIHx8IF9wYXJzZUtleWZyYW1lKHAsIGtleWZyYW1lc1twXSwgY29weSwga2V5ZnJhbWVzLmVhc2VFYWNoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHAgaW4gY29weSkge1xuICAgICAgICAgICAgYSA9IGNvcHlbcF0uc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICByZXR1cm4gYS50IC0gYi50O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aW1lID0gMDtcblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAga2YgPSBhW2ldO1xuICAgICAgICAgICAgICB2ID0ge1xuICAgICAgICAgICAgICAgIGVhc2U6IGtmLmUsXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IChrZi50IC0gKGkgPyBhW2kgLSAxXS50IDogMCkpIC8gMTAwICogZHVyYXRpb25cbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgdltwXSA9IGtmLnY7XG4gICAgICAgICAgICAgIHRsLnRvKHBhcnNlZFRhcmdldHMsIHYsIHRpbWUpO1xuICAgICAgICAgICAgICB0aW1lICs9IHYuZHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGwuZHVyYXRpb24oKSA8IGR1cmF0aW9uICYmIHRsLnRvKHt9LCB7XG4gICAgICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24gLSB0bC5kdXJhdGlvbigpXG4gICAgICAgICAgfSk7IC8vIGluIGNhc2Uga2V5ZnJhbWVzIGRpZG4ndCBnbyB0byAxMDAlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZHVyYXRpb24gfHwgX3RoaXMzLmR1cmF0aW9uKGR1cmF0aW9uID0gdGwuZHVyYXRpb24oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzMy50aW1lbGluZSA9IDA7IC8vc3BlZWQgb3B0aW1pemF0aW9uLCBmYXN0ZXIgbG9va3VwcyAobm8gZ29pbmcgdXAgdGhlIHByb3RvdHlwZSBjaGFpbilcbiAgICB9XG5cbiAgICBpZiAob3ZlcndyaXRlID09PSB0cnVlICYmICFfc3VwcHJlc3NPdmVyd3JpdGVzKSB7XG4gICAgICBfb3ZlcndyaXRpbmdUd2VlbiA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMzKTtcblxuICAgICAgX2dsb2JhbFRpbWVsaW5lLmtpbGxUd2VlbnNPZihwYXJzZWRUYXJnZXRzKTtcblxuICAgICAgX292ZXJ3cml0aW5nVHdlZW4gPSAwO1xuICAgIH1cblxuICAgIF9hZGRUb1RpbWVsaW5lKHBhcmVudCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBwb3NpdGlvbik7XG5cbiAgICB2YXJzLnJldmVyc2VkICYmIF90aGlzMy5yZXZlcnNlKCk7XG4gICAgdmFycy5wYXVzZWQgJiYgX3RoaXMzLnBhdXNlZCh0cnVlKTtcblxuICAgIGlmIChpbW1lZGlhdGVSZW5kZXIgfHwgIWR1cmF0aW9uICYmICFrZXlmcmFtZXMgJiYgX3RoaXMzLl9zdGFydCA9PT0gX3JvdW5kUHJlY2lzZShwYXJlbnQuX3RpbWUpICYmIF9pc05vdEZhbHNlKGltbWVkaWF0ZVJlbmRlcikgJiYgX2hhc05vUGF1c2VkQW5jZXN0b3JzKF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMzKSkgJiYgcGFyZW50LmRhdGEgIT09IFwibmVzdGVkXCIpIHtcbiAgICAgIF90aGlzMy5fdFRpbWUgPSAtX3RpbnlOdW07IC8vZm9yY2VzIGEgcmVuZGVyIHdpdGhvdXQgaGF2aW5nIHRvIHNldCB0aGUgcmVuZGVyKCkgXCJmb3JjZVwiIHBhcmFtZXRlciB0byB0cnVlIGJlY2F1c2Ugd2Ugd2FudCB0byBhbGxvdyBsYXp5aW5nIGJ5IGRlZmF1bHQgKHVzaW5nIHRoZSBcImZvcmNlXCIgcGFyYW1ldGVyIGFsd2F5cyBmb3JjZXMgYW4gaW1tZWRpYXRlIGZ1bGwgcmVuZGVyKVxuXG4gICAgICBfdGhpczMucmVuZGVyKE1hdGgubWF4KDAsIC1kZWxheSkgfHwgMCk7IC8vaW4gY2FzZSBkZWxheSBpcyBuZWdhdGl2ZVxuXG4gICAgfVxuXG4gICAgc2Nyb2xsVHJpZ2dlciAmJiBfc2Nyb2xsVHJpZ2dlcihfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzMyksIHNjcm9sbFRyaWdnZXIpO1xuICAgIHJldHVybiBfdGhpczM7XG4gIH1cblxuICB2YXIgX3Byb3RvMyA9IFR3ZWVuLnByb3RvdHlwZTtcblxuICBfcHJvdG8zLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICAgIHZhciBwcmV2VGltZSA9IHRoaXMuX3RpbWUsXG4gICAgICAgIHREdXIgPSB0aGlzLl90RHVyLFxuICAgICAgICBkdXIgPSB0aGlzLl9kdXIsXG4gICAgICAgIGlzTmVnYXRpdmUgPSB0b3RhbFRpbWUgPCAwLFxuICAgICAgICB0VGltZSA9IHRvdGFsVGltZSA+IHREdXIgLSBfdGlueU51bSAmJiAhaXNOZWdhdGl2ZSA/IHREdXIgOiB0b3RhbFRpbWUgPCBfdGlueU51bSA/IDAgOiB0b3RhbFRpbWUsXG4gICAgICAgIHRpbWUsXG4gICAgICAgIHB0LFxuICAgICAgICBpdGVyYXRpb24sXG4gICAgICAgIGN5Y2xlRHVyYXRpb24sXG4gICAgICAgIHByZXZJdGVyYXRpb24sXG4gICAgICAgIGlzWW95byxcbiAgICAgICAgcmF0aW8sXG4gICAgICAgIHRpbWVsaW5lLFxuICAgICAgICB5b3lvRWFzZTtcblxuICAgIGlmICghZHVyKSB7XG4gICAgICBfcmVuZGVyWmVyb0R1cmF0aW9uVHdlZW4odGhpcywgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgIH0gZWxzZSBpZiAodFRpbWUgIT09IHRoaXMuX3RUaW1lIHx8ICF0b3RhbFRpbWUgfHwgZm9yY2UgfHwgIXRoaXMuX2luaXR0ZWQgJiYgdGhpcy5fdFRpbWUgfHwgdGhpcy5fc3RhcnRBdCAmJiB0aGlzLl96VGltZSA8IDAgIT09IGlzTmVnYXRpdmUpIHtcbiAgICAgIC8vdGhpcyBzZW5zZXMgaWYgd2UncmUgY3Jvc3Npbmcgb3ZlciB0aGUgc3RhcnQgdGltZSwgaW4gd2hpY2ggY2FzZSB3ZSBtdXN0IHJlY29yZCBfelRpbWUgYW5kIGZvcmNlIHRoZSByZW5kZXIsIGJ1dCB3ZSBkbyBpdCBpbiB0aGlzIGxlbmd0aHkgY29uZGl0aW9uYWwgd2F5IGZvciBwZXJmb3JtYW5jZSByZWFzb25zICh1c3VhbGx5IHdlIGNhbiBza2lwIHRoZSBjYWxjdWxhdGlvbnMpOiB0aGlzLl9pbml0dGVkICYmICh0aGlzLl96VGltZSA8IDApICE9PSAodG90YWxUaW1lIDwgMClcbiAgICAgIHRpbWUgPSB0VGltZTtcbiAgICAgIHRpbWVsaW5lID0gdGhpcy50aW1lbGluZTtcblxuICAgICAgaWYgKHRoaXMuX3JlcGVhdCkge1xuICAgICAgICAvL2FkanVzdCB0aGUgdGltZSBmb3IgcmVwZWF0cyBhbmQgeW95b3NcbiAgICAgICAgY3ljbGVEdXJhdGlvbiA9IGR1ciArIHRoaXMuX3JEZWxheTtcblxuICAgICAgICBpZiAodGhpcy5fcmVwZWF0IDwgLTEgJiYgaXNOZWdhdGl2ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvdGFsVGltZShjeWNsZUR1cmF0aW9uICogMTAwICsgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGltZSA9IF9yb3VuZFByZWNpc2UodFRpbWUgJSBjeWNsZUR1cmF0aW9uKTsgLy9yb3VuZCB0byBhdm9pZCBmbG9hdGluZyBwb2ludCBlcnJvcnMuICg0ICUgMC44IHNob3VsZCBiZSAwIGJ1dCBzb21lIGJyb3dzZXJzIHJlcG9ydCBpdCBhcyAwLjc5OTk5OTk5ISlcblxuICAgICAgICBpZiAodFRpbWUgPT09IHREdXIpIHtcbiAgICAgICAgICAvLyB0aGUgdER1ciA9PT0gdFRpbWUgaXMgZm9yIGVkZ2UgY2FzZXMgd2hlcmUgdGhlcmUncyBhIGxlbmd0aHkgZGVjaW1hbCBvbiB0aGUgZHVyYXRpb24gYW5kIGl0IG1heSByZWFjaCB0aGUgdmVyeSBlbmQgYnV0IHRoZSB0aW1lIGlzIHJlbmRlcmVkIGFzIG5vdC1xdWl0ZS10aGVyZSAocmVtZW1iZXIsIHREdXIgaXMgcm91bmRlZCB0byA0IGRlY2ltYWxzIHdoZXJlYXMgZHVyIGlzbid0KVxuICAgICAgICAgIGl0ZXJhdGlvbiA9IHRoaXMuX3JlcGVhdDtcbiAgICAgICAgICB0aW1lID0gZHVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZXJhdGlvbiA9IH5+KHRUaW1lIC8gY3ljbGVEdXJhdGlvbik7XG5cbiAgICAgICAgICBpZiAoaXRlcmF0aW9uICYmIGl0ZXJhdGlvbiA9PT0gdFRpbWUgLyBjeWNsZUR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aW1lID0gZHVyO1xuICAgICAgICAgICAgaXRlcmF0aW9uLS07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGltZSA+IGR1ciAmJiAodGltZSA9IGR1cik7XG4gICAgICAgIH1cblxuICAgICAgICBpc1lveW8gPSB0aGlzLl95b3lvICYmIGl0ZXJhdGlvbiAmIDE7XG5cbiAgICAgICAgaWYgKGlzWW95bykge1xuICAgICAgICAgIHlveW9FYXNlID0gdGhpcy5feUVhc2U7XG4gICAgICAgICAgdGltZSA9IGR1ciAtIHRpbWU7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2SXRlcmF0aW9uID0gX2FuaW1hdGlvbkN5Y2xlKHRoaXMuX3RUaW1lLCBjeWNsZUR1cmF0aW9uKTtcblxuICAgICAgICBpZiAodGltZSA9PT0gcHJldlRpbWUgJiYgIWZvcmNlICYmIHRoaXMuX2luaXR0ZWQpIHtcbiAgICAgICAgICAvL2NvdWxkIGJlIGR1cmluZyB0aGUgcmVwZWF0RGVsYXkgcGFydC4gTm8gbmVlZCB0byByZW5kZXIgYW5kIGZpcmUgY2FsbGJhY2tzLlxuICAgICAgICAgIHRoaXMuX3RUaW1lID0gdFRpbWU7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXRlcmF0aW9uICE9PSBwcmV2SXRlcmF0aW9uKSB7XG4gICAgICAgICAgdGltZWxpbmUgJiYgdGhpcy5feUVhc2UgJiYgX3Byb3BhZ2F0ZVlveW9FYXNlKHRpbWVsaW5lLCBpc1lveW8pOyAvL3JlcGVhdFJlZnJlc2ggZnVuY3Rpb25hbGl0eVxuXG4gICAgICAgICAgaWYgKHRoaXMudmFycy5yZXBlYXRSZWZyZXNoICYmICFpc1lveW8gJiYgIXRoaXMuX2xvY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2xvY2sgPSBmb3JjZSA9IDE7IC8vZm9yY2UsIG90aGVyd2lzZSBpZiBsYXp5IGlzIHRydWUsIHRoZSBfYXR0ZW1wdEluaXRUd2VlbigpIHdpbGwgcmV0dXJuIGFuZCB3ZSdsbCBqdW1wIG91dCBhbmQgZ2V0IGNhdWdodCBib3VuY2luZyBvbiBlYWNoIHRpY2suXG5cbiAgICAgICAgICAgIHRoaXMucmVuZGVyKF9yb3VuZFByZWNpc2UoY3ljbGVEdXJhdGlvbiAqIGl0ZXJhdGlvbiksIHRydWUpLmludmFsaWRhdGUoKS5fbG9jayA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5faW5pdHRlZCkge1xuICAgICAgICBpZiAoX2F0dGVtcHRJbml0VHdlZW4odGhpcywgaXNOZWdhdGl2ZSA/IHRvdGFsVGltZSA6IHRpbWUsIGZvcmNlLCBzdXBwcmVzc0V2ZW50cywgdFRpbWUpKSB7XG4gICAgICAgICAgdGhpcy5fdFRpbWUgPSAwOyAvLyBpbiBjb25zdHJ1Y3RvciBpZiBpbW1lZGlhdGVSZW5kZXIgaXMgdHJ1ZSwgd2Ugc2V0IF90VGltZSB0byAtX3RpbnlOdW0gdG8gaGF2ZSB0aGUgcGxheWhlYWQgY3Jvc3MgdGhlIHN0YXJ0aW5nIHBvaW50IGJ1dCB3ZSBjYW4ndCBsZWF2ZSBfdFRpbWUgYXMgYSBuZWdhdGl2ZSBudW1iZXIuXG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcmV2VGltZSAhPT0gdGhpcy5fdGltZSkge1xuICAgICAgICAgIC8vIHJhcmUgZWRnZSBjYXNlIC0gZHVyaW5nIGluaXRpYWxpemF0aW9uLCBhbiBvblVwZGF0ZSBpbiB0aGUgX3N0YXJ0QXQgKC5mcm9tVG8oKSkgbWlnaHQgZm9yY2UgdGhpcyB0d2VlbiB0byByZW5kZXIgYXQgYSBkaWZmZXJlbnQgc3BvdCBpbiB3aGljaCBjYXNlIHdlIHNob3VsZCBkaXRjaCB0aGlzIHJlbmRlcigpIGNhbGwgc28gdGhhdCBpdCBkb2Vzbid0IHJldmVydCB0aGUgdmFsdWVzLlxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGR1ciAhPT0gdGhpcy5fZHVyKSB7XG4gICAgICAgICAgLy8gd2hpbGUgaW5pdHRpbmcsIGEgcGx1Z2luIGxpa2UgSW5lcnRpYVBsdWdpbiBtaWdodCBhbHRlciB0aGUgZHVyYXRpb24sIHNvIHJlcnVuIGZyb20gdGhlIHN0YXJ0IHRvIGVuc3VyZSBldmVyeXRoaW5nIHJlbmRlcnMgYXMgaXQgc2hvdWxkLlxuICAgICAgICAgIHJldHVybiB0aGlzLnJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fdFRpbWUgPSB0VGltZTtcbiAgICAgIHRoaXMuX3RpbWUgPSB0aW1lO1xuXG4gICAgICBpZiAoIXRoaXMuX2FjdCAmJiB0aGlzLl90cykge1xuICAgICAgICB0aGlzLl9hY3QgPSAxOyAvL2FzIGxvbmcgYXMgaXQncyBub3QgcGF1c2VkLCBmb3JjZSBpdCB0byBiZSBhY3RpdmUgc28gdGhhdCBpZiB0aGUgdXNlciByZW5kZXJzIGluZGVwZW5kZW50IG9mIHRoZSBwYXJlbnQgdGltZWxpbmUsIGl0J2xsIGJlIGZvcmNlZCB0byByZS1yZW5kZXIgb24gdGhlIG5leHQgdGljay5cblxuICAgICAgICB0aGlzLl9sYXp5ID0gMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yYXRpbyA9IHJhdGlvID0gKHlveW9FYXNlIHx8IHRoaXMuX2Vhc2UpKHRpbWUgLyBkdXIpO1xuXG4gICAgICBpZiAodGhpcy5fZnJvbSkge1xuICAgICAgICB0aGlzLnJhdGlvID0gcmF0aW8gPSAxIC0gcmF0aW87XG4gICAgICB9XG5cbiAgICAgIGlmICh0aW1lICYmICFwcmV2VGltZSAmJiAhc3VwcHJlc3NFdmVudHMgJiYgIWl0ZXJhdGlvbikge1xuICAgICAgICBfY2FsbGJhY2sodGhpcywgXCJvblN0YXJ0XCIpO1xuXG4gICAgICAgIGlmICh0aGlzLl90VGltZSAhPT0gdFRpbWUpIHtcbiAgICAgICAgICAvLyBpbiBjYXNlIHRoZSBvblN0YXJ0IHRyaWdnZXJlZCBhIHJlbmRlciBhdCBhIGRpZmZlcmVudCBzcG90LCBlamVjdC4gTGlrZSBpZiBzb21lb25lIGRpZCBhbmltYXRpb24ucGF1c2UoMC41KSBvciBzb21ldGhpbmcgaW5zaWRlIHRoZSBvblN0YXJ0LlxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHB0ID0gdGhpcy5fcHQ7XG5cbiAgICAgIHdoaWxlIChwdCkge1xuICAgICAgICBwdC5yKHJhdGlvLCBwdC5kKTtcbiAgICAgICAgcHQgPSBwdC5fbmV4dDtcbiAgICAgIH1cblxuICAgICAgdGltZWxpbmUgJiYgdGltZWxpbmUucmVuZGVyKHRvdGFsVGltZSA8IDAgPyB0b3RhbFRpbWUgOiAhdGltZSAmJiBpc1lveW8gPyAtX3RpbnlOdW0gOiB0aW1lbGluZS5fZHVyICogdGltZWxpbmUuX2Vhc2UodGltZSAvIHRoaXMuX2R1ciksIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkgfHwgdGhpcy5fc3RhcnRBdCAmJiAodGhpcy5felRpbWUgPSB0b3RhbFRpbWUpO1xuXG4gICAgICBpZiAodGhpcy5fb25VcGRhdGUgJiYgIXN1cHByZXNzRXZlbnRzKSB7XG4gICAgICAgIGlzTmVnYXRpdmUgJiYgX3Jld2luZFN0YXJ0QXQodGhpcywgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpOyAvL25vdGU6IGZvciBwZXJmb3JtYW5jZSByZWFzb25zLCB3ZSB0dWNrIHRoaXMgY29uZGl0aW9uYWwgbG9naWMgaW5zaWRlIGxlc3MgdHJhdmVsZWQgYXJlYXMgKG1vc3QgdHdlZW5zIGRvbid0IGhhdmUgYW4gb25VcGRhdGUpLiBXZSdkIGp1c3QgaGF2ZSBpdCBhdCB0aGUgZW5kIGJlZm9yZSB0aGUgb25Db21wbGV0ZSwgYnV0IHRoZSB2YWx1ZXMgc2hvdWxkIGJlIHVwZGF0ZWQgYmVmb3JlIGFueSBvblVwZGF0ZSBpcyBjYWxsZWQsIHNvIHdlIEFMU08gcHV0IGl0IGhlcmUgYW5kIHRoZW4gaWYgaXQncyBub3QgY2FsbGVkLCB3ZSBkbyBzbyBsYXRlciBuZWFyIHRoZSBvbkNvbXBsZXRlLlxuXG4gICAgICAgIF9jYWxsYmFjayh0aGlzLCBcIm9uVXBkYXRlXCIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZXBlYXQgJiYgaXRlcmF0aW9uICE9PSBwcmV2SXRlcmF0aW9uICYmIHRoaXMudmFycy5vblJlcGVhdCAmJiAhc3VwcHJlc3NFdmVudHMgJiYgdGhpcy5wYXJlbnQgJiYgX2NhbGxiYWNrKHRoaXMsIFwib25SZXBlYXRcIik7XG5cbiAgICAgIGlmICgodFRpbWUgPT09IHRoaXMuX3REdXIgfHwgIXRUaW1lKSAmJiB0aGlzLl90VGltZSA9PT0gdFRpbWUpIHtcbiAgICAgICAgaXNOZWdhdGl2ZSAmJiAhdGhpcy5fb25VcGRhdGUgJiYgX3Jld2luZFN0YXJ0QXQodGhpcywgdG90YWxUaW1lLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgKHRvdGFsVGltZSB8fCAhZHVyKSAmJiAodFRpbWUgPT09IHRoaXMuX3REdXIgJiYgdGhpcy5fdHMgPiAwIHx8ICF0VGltZSAmJiB0aGlzLl90cyA8IDApICYmIF9yZW1vdmVGcm9tUGFyZW50KHRoaXMsIDEpOyAvLyBkb24ndCByZW1vdmUgaWYgd2UncmUgcmVuZGVyaW5nIGF0IGV4YWN0bHkgYSB0aW1lIG9mIDAsIGFzIHRoZXJlIGNvdWxkIGJlIGF1dG9SZXZlcnQgdmFsdWVzIHRoYXQgc2hvdWxkIGdldCBzZXQgb24gdGhlIG5leHQgdGljayAoaWYgdGhlIHBsYXloZWFkIGdvZXMgYmFja3dhcmQgYmV5b25kIHRoZSBzdGFydFRpbWUsIG5lZ2F0aXZlIHRvdGFsVGltZSkuIERvbid0IHJlbW92ZSBpZiB0aGUgdGltZWxpbmUgaXMgcmV2ZXJzZWQgYW5kIHRoZSBwbGF5aGVhZCBpc24ndCBhdCAwLCBvdGhlcndpc2UgdGwucHJvZ3Jlc3MoMSkucmV2ZXJzZSgpIHdvbid0IHdvcmsuIE9ubHkgcmVtb3ZlIGlmIHRoZSBwbGF5aGVhZCBpcyBhdCB0aGUgZW5kIGFuZCB0aW1lU2NhbGUgaXMgcG9zaXRpdmUsIG9yIGlmIHRoZSBwbGF5aGVhZCBpcyBhdCAwIGFuZCB0aGUgdGltZVNjYWxlIGlzIG5lZ2F0aXZlLlxuXG4gICAgICAgIGlmICghc3VwcHJlc3NFdmVudHMgJiYgIShpc05lZ2F0aXZlICYmICFwcmV2VGltZSkgJiYgKHRUaW1lIHx8IHByZXZUaW1lIHx8IGlzWW95bykpIHtcbiAgICAgICAgICAvLyBpZiBwcmV2VGltZSBhbmQgdFRpbWUgYXJlIHplcm8sIHdlIHNob3VsZG4ndCBmaXJlIHRoZSBvblJldmVyc2VDb21wbGV0ZS4gVGhpcyBjb3VsZCBoYXBwZW4gaWYgeW91IGdzYXAudG8oLi4uIHtwYXVzZWQ6dHJ1ZX0pLnBsYXkoKTtcbiAgICAgICAgICBfY2FsbGJhY2sodGhpcywgdFRpbWUgPT09IHREdXIgPyBcIm9uQ29tcGxldGVcIiA6IFwib25SZXZlcnNlQ29tcGxldGVcIiwgdHJ1ZSk7XG5cbiAgICAgICAgICB0aGlzLl9wcm9tICYmICEodFRpbWUgPCB0RHVyICYmIHRoaXMudGltZVNjYWxlKCkgPiAwKSAmJiB0aGlzLl9wcm9tKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8zLnRhcmdldHMgPSBmdW5jdGlvbiB0YXJnZXRzKCkge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXRzO1xuICB9O1xuXG4gIF9wcm90bzMuaW52YWxpZGF0ZSA9IGZ1bmN0aW9uIGludmFsaWRhdGUoc29mdCkge1xuICAgIC8vIFwic29mdFwiIGdpdmVzIHVzIGEgd2F5IHRvIGNsZWFyIG91dCBldmVyeXRoaW5nIEVYQ0VQVCB0aGUgcmVjb3JkZWQgcHJlLVwiZnJvbVwiIHBvcnRpb24gb2YgZnJvbSgpIHR3ZWVucy4gT3RoZXJ3aXNlLCBmb3IgZXhhbXBsZSwgaWYgeW91IHR3ZWVuLnByb2dyZXNzKDEpLnJlbmRlcigwLCB0cnVlIHRydWUpLmludmFsaWRhdGUoKSwgdGhlIFwiZnJvbVwiIHZhbHVlcyB3b3VsZCBwZXJzaXN0IGFuZCB0aGVuIG9uIHRoZSBuZXh0IHJlbmRlciwgdGhlIGZyb20oKSB0d2VlbnMgd291bGQgaW5pdGlhbGl6ZSBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgd291bGQgbWF0Y2ggdGhlIFwiZnJvbVwiIHZhbHVlcywgdGh1cyBhbmltYXRlIGZyb20gdGhlIHNhbWUgdmFsdWUgdG8gdGhlIHNhbWUgdmFsdWUgKG5vIGFuaW1hdGlvbikuIFdlIHRhcCBpbnRvIHRoaXMgaW4gU2Nyb2xsVHJpZ2dlcidzIHJlZnJlc2goKSB3aGVyZSB3ZSBtdXN0IHB1c2ggYSB0d2VlbiB0byBjb21wbGV0aW9uIGFuZCB0aGVuIGJhY2sgYWdhaW4gYnV0IGhvbm9yIGl0cyBpbml0IHN0YXRlIGluIGNhc2UgdGhlIHR3ZWVuIGlzIGRlcGVuZGVudCBvbiBhbm90aGVyIHR3ZWVuIGZ1cnRoZXIgdXAgb24gdGhlIHBhZ2UuXG4gICAgKCFzb2Z0IHx8ICF0aGlzLnZhcnMucnVuQmFja3dhcmRzKSAmJiAodGhpcy5fc3RhcnRBdCA9IDApO1xuICAgIHRoaXMuX3B0ID0gdGhpcy5fb3AgPSB0aGlzLl9vblVwZGF0ZSA9IHRoaXMuX2xhenkgPSB0aGlzLnJhdGlvID0gMDtcbiAgICB0aGlzLl9wdExvb2t1cCA9IFtdO1xuICAgIHRoaXMudGltZWxpbmUgJiYgdGhpcy50aW1lbGluZS5pbnZhbGlkYXRlKHNvZnQpO1xuICAgIHJldHVybiBfQW5pbWF0aW9uMi5wcm90b3R5cGUuaW52YWxpZGF0ZS5jYWxsKHRoaXMsIHNvZnQpO1xuICB9O1xuXG4gIF9wcm90bzMucmVzZXRUbyA9IGZ1bmN0aW9uIHJlc2V0VG8ocHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlKSB7XG4gICAgX3RpY2tlckFjdGl2ZSB8fCBfdGlja2VyLndha2UoKTtcbiAgICB0aGlzLl90cyB8fCB0aGlzLnBsYXkoKTtcbiAgICB2YXIgdGltZSA9IE1hdGgubWluKHRoaXMuX2R1ciwgKHRoaXMuX2RwLl90aW1lIC0gdGhpcy5fc3RhcnQpICogdGhpcy5fdHMpLFxuICAgICAgICByYXRpbztcbiAgICB0aGlzLl9pbml0dGVkIHx8IF9pbml0VHdlZW4odGhpcywgdGltZSk7XG4gICAgcmF0aW8gPSB0aGlzLl9lYXNlKHRpbWUgLyB0aGlzLl9kdXIpOyAvLyBkb24ndCBqdXN0IGdldCB0d2Vlbi5yYXRpbyBiZWNhdXNlIGl0IG1heSBub3QgaGF2ZSByZW5kZXJlZCB5ZXQuXG4gICAgLy8gcG9zc2libGUgZnV0dXJlIGFkZGl0aW9uIHRvIGFsbG93IGFuIG9iamVjdCB3aXRoIG11bHRpcGxlIHZhbHVlcyB0byB1cGRhdGUsIGxpa2UgdHdlZW4ucmVzZXRUbyh7eDogMTAwLCB5OiAyMDB9KTsgQXQgdGhpcyBwb2ludCwgaXQgZG9lc24ndCBzZWVtIHdvcnRoIHRoZSBhZGRlZCBrYiBnaXZlbiB0aGUgZmFjdCB0aGF0IG1vc3QgdXNlcnMgd2lsbCBsaWtlbHkgb3B0IGZvciB0aGUgY29udmVuaWVudCBnc2FwLnF1aWNrVG8oKSB3YXkgb2YgaW50ZXJhY3Rpbmcgd2l0aCB0aGlzIG1ldGhvZC5cbiAgICAvLyBpZiAoX2lzT2JqZWN0KHByb3BlcnR5KSkgeyAvLyBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cbiAgICAvLyBcdGZvciAocCBpbiBwcm9wZXJ0eSkge1xuICAgIC8vIFx0XHRpZiAoX3VwZGF0ZVByb3BUd2VlbnModGhpcywgcCwgcHJvcGVydHlbcF0sIHZhbHVlID8gdmFsdWVbcF0gOiBudWxsLCBzdGFydCwgcmF0aW8sIHRpbWUpKSB7XG4gICAgLy8gXHRcdFx0cmV0dXJuIHRoaXMucmVzZXRUbyhwcm9wZXJ0eSwgdmFsdWUsIHN0YXJ0LCBzdGFydElzUmVsYXRpdmUpOyAvLyBpZiBhIFByb3BUd2VlbiB3YXNuJ3QgZm91bmQgZm9yIHRoZSBwcm9wZXJ0eSwgaXQnbGwgZ2V0IGZvcmNlZCB3aXRoIGEgcmUtaW5pdGlhbGl6YXRpb24gc28gd2UgbmVlZCB0byBqdW1wIG91dCBhbmQgc3RhcnQgb3ZlciBhZ2Fpbi5cbiAgICAvLyBcdFx0fVxuICAgIC8vIFx0fVxuICAgIC8vIH0gZWxzZSB7XG5cbiAgICBpZiAoX3VwZGF0ZVByb3BUd2VlbnModGhpcywgcHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlLCByYXRpbywgdGltZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlc2V0VG8ocHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlKTsgLy8gaWYgYSBQcm9wVHdlZW4gd2Fzbid0IGZvdW5kIGZvciB0aGUgcHJvcGVydHksIGl0J2xsIGdldCBmb3JjZWQgd2l0aCBhIHJlLWluaXRpYWxpemF0aW9uIHNvIHdlIG5lZWQgdG8ganVtcCBvdXQgYW5kIHN0YXJ0IG92ZXIgYWdhaW4uXG4gICAgfSAvL31cblxuXG4gICAgX2FsaWduUGxheWhlYWQodGhpcywgMCk7XG5cbiAgICB0aGlzLnBhcmVudCB8fCBfYWRkTGlua2VkTGlzdEl0ZW0odGhpcy5fZHAsIHRoaXMsIFwiX2ZpcnN0XCIsIFwiX2xhc3RcIiwgdGhpcy5fZHAuX3NvcnQgPyBcIl9zdGFydFwiIDogMCk7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyKDApO1xuICB9O1xuXG4gIF9wcm90bzMua2lsbCA9IGZ1bmN0aW9uIGtpbGwodGFyZ2V0cywgdmFycykge1xuICAgIGlmICh2YXJzID09PSB2b2lkIDApIHtcbiAgICAgIHZhcnMgPSBcImFsbFwiO1xuICAgIH1cblxuICAgIGlmICghdGFyZ2V0cyAmJiAoIXZhcnMgfHwgdmFycyA9PT0gXCJhbGxcIikpIHtcbiAgICAgIHRoaXMuX2xhenkgPSB0aGlzLl9wdCA9IDA7XG4gICAgICByZXR1cm4gdGhpcy5wYXJlbnQgPyBfaW50ZXJydXB0KHRoaXMpIDogdGhpcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy50aW1lbGluZSkge1xuICAgICAgdmFyIHREdXIgPSB0aGlzLnRpbWVsaW5lLnRvdGFsRHVyYXRpb24oKTtcbiAgICAgIHRoaXMudGltZWxpbmUua2lsbFR3ZWVuc09mKHRhcmdldHMsIHZhcnMsIF9vdmVyd3JpdGluZ1R3ZWVuICYmIF9vdmVyd3JpdGluZ1R3ZWVuLnZhcnMub3ZlcndyaXRlICE9PSB0cnVlKS5fZmlyc3QgfHwgX2ludGVycnVwdCh0aGlzKTsgLy8gaWYgbm90aGluZyBpcyBsZWZ0IHR3ZWVuaW5nLCBpbnRlcnJ1cHQuXG5cbiAgICAgIHRoaXMucGFyZW50ICYmIHREdXIgIT09IHRoaXMudGltZWxpbmUudG90YWxEdXJhdGlvbigpICYmIF9zZXREdXJhdGlvbih0aGlzLCB0aGlzLl9kdXIgKiB0aGlzLnRpbWVsaW5lLl90RHVyIC8gdER1ciwgMCwgMSk7IC8vIGlmIGEgbmVzdGVkIHR3ZWVuIGlzIGtpbGxlZCB0aGF0IGNoYW5nZXMgdGhlIGR1cmF0aW9uLCBpdCBzaG91bGQgYWZmZWN0IHRoaXMgdHdlZW4ncyBkdXJhdGlvbi4gV2UgbXVzdCB1c2UgdGhlIHJhdGlvLCB0aG91Z2gsIGJlY2F1c2Ugc29tZXRpbWVzIHRoZSBpbnRlcm5hbCB0aW1lbGluZSBpcyBzdHJldGNoZWQgbGlrZSBmb3Iga2V5ZnJhbWVzIHdoZXJlIHRoZXkgZG9uJ3QgYWxsIGFkZCB1cCB0byB3aGF0ZXZlciB0aGUgcGFyZW50IHR3ZWVuJ3MgZHVyYXRpb24gd2FzIHNldCB0by5cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIHBhcnNlZFRhcmdldHMgPSB0aGlzLl90YXJnZXRzLFxuICAgICAgICBraWxsaW5nVGFyZ2V0cyA9IHRhcmdldHMgPyB0b0FycmF5KHRhcmdldHMpIDogcGFyc2VkVGFyZ2V0cyxcbiAgICAgICAgcHJvcFR3ZWVuTG9va3VwID0gdGhpcy5fcHRMb29rdXAsXG4gICAgICAgIGZpcnN0UFQgPSB0aGlzLl9wdCxcbiAgICAgICAgb3ZlcndyaXR0ZW5Qcm9wcyxcbiAgICAgICAgY3VyTG9va3VwLFxuICAgICAgICBjdXJPdmVyd3JpdGVQcm9wcyxcbiAgICAgICAgcHJvcHMsXG4gICAgICAgIHAsXG4gICAgICAgIHB0LFxuICAgICAgICBpO1xuXG4gICAgaWYgKCghdmFycyB8fCB2YXJzID09PSBcImFsbFwiKSAmJiBfYXJyYXlzTWF0Y2gocGFyc2VkVGFyZ2V0cywga2lsbGluZ1RhcmdldHMpKSB7XG4gICAgICB2YXJzID09PSBcImFsbFwiICYmICh0aGlzLl9wdCA9IDApO1xuICAgICAgcmV0dXJuIF9pbnRlcnJ1cHQodGhpcyk7XG4gICAgfVxuXG4gICAgb3ZlcndyaXR0ZW5Qcm9wcyA9IHRoaXMuX29wID0gdGhpcy5fb3AgfHwgW107XG5cbiAgICBpZiAodmFycyAhPT0gXCJhbGxcIikge1xuICAgICAgLy9zbyBwZW9wbGUgY2FuIHBhc3MgaW4gYSBjb21tYS1kZWxpbWl0ZWQgbGlzdCBvZiBwcm9wZXJ0eSBuYW1lc1xuICAgICAgaWYgKF9pc1N0cmluZyh2YXJzKSkge1xuICAgICAgICBwID0ge307XG5cbiAgICAgICAgX2ZvckVhY2hOYW1lKHZhcnMsIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHBbbmFtZV0gPSAxO1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXJzID0gcDtcbiAgICAgIH1cblxuICAgICAgdmFycyA9IF9hZGRBbGlhc2VzVG9WYXJzKHBhcnNlZFRhcmdldHMsIHZhcnMpO1xuICAgIH1cblxuICAgIGkgPSBwYXJzZWRUYXJnZXRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGlmICh+a2lsbGluZ1RhcmdldHMuaW5kZXhPZihwYXJzZWRUYXJnZXRzW2ldKSkge1xuICAgICAgICBjdXJMb29rdXAgPSBwcm9wVHdlZW5Mb29rdXBbaV07XG5cbiAgICAgICAgaWYgKHZhcnMgPT09IFwiYWxsXCIpIHtcbiAgICAgICAgICBvdmVyd3JpdHRlblByb3BzW2ldID0gdmFycztcbiAgICAgICAgICBwcm9wcyA9IGN1ckxvb2t1cDtcbiAgICAgICAgICBjdXJPdmVyd3JpdGVQcm9wcyA9IHt9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1ck92ZXJ3cml0ZVByb3BzID0gb3ZlcndyaXR0ZW5Qcm9wc1tpXSA9IG92ZXJ3cml0dGVuUHJvcHNbaV0gfHwge307XG4gICAgICAgICAgcHJvcHMgPSB2YXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChwIGluIHByb3BzKSB7XG4gICAgICAgICAgcHQgPSBjdXJMb29rdXAgJiYgY3VyTG9va3VwW3BdO1xuXG4gICAgICAgICAgaWYgKHB0KSB7XG4gICAgICAgICAgICBpZiAoIShcImtpbGxcIiBpbiBwdC5kKSB8fCBwdC5kLmtpbGwocCkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgX3JlbW92ZUxpbmtlZExpc3RJdGVtKHRoaXMsIHB0LCBcIl9wdFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVsZXRlIGN1ckxvb2t1cFtwXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY3VyT3ZlcndyaXRlUHJvcHMgIT09IFwiYWxsXCIpIHtcbiAgICAgICAgICAgIGN1ck92ZXJ3cml0ZVByb3BzW3BdID0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9pbml0dGVkICYmICF0aGlzLl9wdCAmJiBmaXJzdFBUICYmIF9pbnRlcnJ1cHQodGhpcyk7IC8vaWYgYWxsIHR3ZWVuaW5nIHByb3BlcnRpZXMgYXJlIGtpbGxlZCwga2lsbCB0aGUgdHdlZW4uIFdpdGhvdXQgdGhpcyBsaW5lLCBpZiB0aGVyZSdzIGEgdHdlZW4gd2l0aCBtdWx0aXBsZSB0YXJnZXRzIGFuZCB0aGVuIHlvdSBraWxsVHdlZW5zT2YoKSBlYWNoIHRhcmdldCBpbmRpdmlkdWFsbHksIHRoZSB0d2VlbiB3b3VsZCB0ZWNobmljYWxseSBzdGlsbCByZW1haW4gYWN0aXZlIGFuZCBmaXJlIGl0cyBvbkNvbXBsZXRlIGV2ZW4gdGhvdWdoIHRoZXJlIGFyZW4ndCBhbnkgbW9yZSBwcm9wZXJ0aWVzIHR3ZWVuaW5nLlxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgVHdlZW4udG8gPSBmdW5jdGlvbiB0byh0YXJnZXRzLCB2YXJzKSB7XG4gICAgcmV0dXJuIG5ldyBUd2Vlbih0YXJnZXRzLCB2YXJzLCBhcmd1bWVudHNbMl0pO1xuICB9O1xuXG4gIFR3ZWVuLmZyb20gPSBmdW5jdGlvbiBmcm9tKHRhcmdldHMsIHZhcnMpIHtcbiAgICByZXR1cm4gX2NyZWF0ZVR3ZWVuVHlwZSgxLCBhcmd1bWVudHMpO1xuICB9O1xuXG4gIFR3ZWVuLmRlbGF5ZWRDYWxsID0gZnVuY3Rpb24gZGVsYXllZENhbGwoZGVsYXksIGNhbGxiYWNrLCBwYXJhbXMsIHNjb3BlKSB7XG4gICAgcmV0dXJuIG5ldyBUd2VlbihjYWxsYmFjaywgMCwge1xuICAgICAgaW1tZWRpYXRlUmVuZGVyOiBmYWxzZSxcbiAgICAgIGxhenk6IGZhbHNlLFxuICAgICAgb3ZlcndyaXRlOiBmYWxzZSxcbiAgICAgIGRlbGF5OiBkZWxheSxcbiAgICAgIG9uQ29tcGxldGU6IGNhbGxiYWNrLFxuICAgICAgb25SZXZlcnNlQ29tcGxldGU6IGNhbGxiYWNrLFxuICAgICAgb25Db21wbGV0ZVBhcmFtczogcGFyYW1zLFxuICAgICAgb25SZXZlcnNlQ29tcGxldGVQYXJhbXM6IHBhcmFtcyxcbiAgICAgIGNhbGxiYWNrU2NvcGU6IHNjb3BlXG4gICAgfSk7IC8vIHdlIG11c3QgdXNlIG9uUmV2ZXJzZUNvbXBsZXRlIHRvbyBmb3IgdGhpbmdzIGxpa2UgdGltZWxpbmUuYWRkKCgpID0+IHsuLi59KSB3aGljaCBzaG91bGQgYmUgdHJpZ2dlcmVkIGluIEJPVEggZGlyZWN0aW9ucyAoZm9yd2FyZCBhbmQgcmV2ZXJzZSlcbiAgfTtcblxuICBUd2Vlbi5mcm9tVG8gPSBmdW5jdGlvbiBmcm9tVG8odGFyZ2V0cywgZnJvbVZhcnMsIHRvVmFycykge1xuICAgIHJldHVybiBfY3JlYXRlVHdlZW5UeXBlKDIsIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgVHdlZW4uc2V0ID0gZnVuY3Rpb24gc2V0KHRhcmdldHMsIHZhcnMpIHtcbiAgICB2YXJzLmR1cmF0aW9uID0gMDtcbiAgICB2YXJzLnJlcGVhdERlbGF5IHx8ICh2YXJzLnJlcGVhdCA9IDApO1xuICAgIHJldHVybiBuZXcgVHdlZW4odGFyZ2V0cywgdmFycyk7XG4gIH07XG5cbiAgVHdlZW4ua2lsbFR3ZWVuc09mID0gZnVuY3Rpb24ga2lsbFR3ZWVuc09mKHRhcmdldHMsIHByb3BzLCBvbmx5QWN0aXZlKSB7XG4gICAgcmV0dXJuIF9nbG9iYWxUaW1lbGluZS5raWxsVHdlZW5zT2YodGFyZ2V0cywgcHJvcHMsIG9ubHlBY3RpdmUpO1xuICB9O1xuXG4gIHJldHVybiBUd2Vlbjtcbn0oQW5pbWF0aW9uKTtcblxuX3NldERlZmF1bHRzKFR3ZWVuLnByb3RvdHlwZSwge1xuICBfdGFyZ2V0czogW10sXG4gIF9sYXp5OiAwLFxuICBfc3RhcnRBdDogMCxcbiAgX29wOiAwLFxuICBfb25Jbml0OiAwXG59KTsgLy9hZGQgdGhlIHBlcnRpbmVudCB0aW1lbGluZSBtZXRob2RzIHRvIFR3ZWVuIGluc3RhbmNlcyBzbyB0aGF0IHVzZXJzIGNhbiBjaGFpbiBjb252ZW5pZW50bHkgYW5kIGNyZWF0ZSBhIHRpbWVsaW5lIGF1dG9tYXRpY2FsbHkuIChyZW1vdmVkIGR1ZSB0byBjb25jZXJucyB0aGF0IGl0J2QgdWx0aW1hdGVseSBhZGQgdG8gbW9yZSBjb25mdXNpb24gZXNwZWNpYWxseSBmb3IgYmVnaW5uZXJzKVxuLy8gX2ZvckVhY2hOYW1lKFwidG8sZnJvbSxmcm9tVG8sc2V0LGNhbGwsYWRkLGFkZExhYmVsLGFkZFBhdXNlXCIsIG5hbWUgPT4ge1xuLy8gXHRUd2Vlbi5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbi8vIFx0XHRsZXQgdGwgPSBuZXcgVGltZWxpbmUoKTtcbi8vIFx0XHRyZXR1cm4gX2FkZFRvVGltZWxpbmUodGwsIHRoaXMpW25hbWVdLmFwcGx5KHRsLCB0b0FycmF5KGFyZ3VtZW50cykpO1xuLy8gXHR9XG4vLyB9KTtcbi8vZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIExldmVyYWdlIHRoZSB0aW1lbGluZSBjYWxscy5cblxuXG5fZm9yRWFjaE5hbWUoXCJzdGFnZ2VyVG8sc3RhZ2dlckZyb20sc3RhZ2dlckZyb21Ub1wiLCBmdW5jdGlvbiAobmFtZSkge1xuICBUd2VlbltuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGwgPSBuZXcgVGltZWxpbmUoKSxcbiAgICAgICAgcGFyYW1zID0gX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcblxuICAgIHBhcmFtcy5zcGxpY2UobmFtZSA9PT0gXCJzdGFnZ2VyRnJvbVRvXCIgPyA1IDogNCwgMCwgMCk7XG4gICAgcmV0dXJuIHRsW25hbWVdLmFwcGx5KHRsLCBwYXJhbXMpO1xuICB9O1xufSk7XG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIFBST1BUV0VFTlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbnZhciBfc2V0dGVyUGxhaW4gPSBmdW5jdGlvbiBfc2V0dGVyUGxhaW4odGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbn0sXG4gICAgX3NldHRlckZ1bmMgPSBmdW5jdGlvbiBfc2V0dGVyRnVuYyh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5XSh2YWx1ZSk7XG59LFxuICAgIF9zZXR0ZXJGdW5jV2l0aFBhcmFtID0gZnVuY3Rpb24gX3NldHRlckZ1bmNXaXRoUGFyYW0odGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIGRhdGEpIHtcbiAgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eV0oZGF0YS5mcCwgdmFsdWUpO1xufSxcbiAgICBfc2V0dGVyQXR0cmlidXRlID0gZnVuY3Rpb24gX3NldHRlckF0dHJpYnV0ZSh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gdGFyZ2V0LnNldEF0dHJpYnV0ZShwcm9wZXJ0eSwgdmFsdWUpO1xufSxcbiAgICBfZ2V0U2V0dGVyID0gZnVuY3Rpb24gX2dldFNldHRlcih0YXJnZXQsIHByb3BlcnR5KSB7XG4gIHJldHVybiBfaXNGdW5jdGlvbih0YXJnZXRbcHJvcGVydHldKSA/IF9zZXR0ZXJGdW5jIDogX2lzVW5kZWZpbmVkKHRhcmdldFtwcm9wZXJ0eV0pICYmIHRhcmdldC5zZXRBdHRyaWJ1dGUgPyBfc2V0dGVyQXR0cmlidXRlIDogX3NldHRlclBsYWluO1xufSxcbiAgICBfcmVuZGVyUGxhaW4gPSBmdW5jdGlvbiBfcmVuZGVyUGxhaW4ocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCBNYXRoLnJvdW5kKChkYXRhLnMgKyBkYXRhLmMgKiByYXRpbykgKiAxMDAwMDAwKSAvIDEwMDAwMDAsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyQm9vbGVhbiA9IGZ1bmN0aW9uIF9yZW5kZXJCb29sZWFuKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybiBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgISEoZGF0YS5zICsgZGF0YS5jICogcmF0aW8pLCBkYXRhKTtcbn0sXG4gICAgX3JlbmRlckNvbXBsZXhTdHJpbmcgPSBmdW5jdGlvbiBfcmVuZGVyQ29tcGxleFN0cmluZyhyYXRpbywgZGF0YSkge1xuICB2YXIgcHQgPSBkYXRhLl9wdCxcbiAgICAgIHMgPSBcIlwiO1xuXG4gIGlmICghcmF0aW8gJiYgZGF0YS5iKSB7XG4gICAgLy9iID0gYmVnaW5uaW5nIHN0cmluZ1xuICAgIHMgPSBkYXRhLmI7XG4gIH0gZWxzZSBpZiAocmF0aW8gPT09IDEgJiYgZGF0YS5lKSB7XG4gICAgLy9lID0gZW5kaW5nIHN0cmluZ1xuICAgIHMgPSBkYXRhLmU7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKHB0KSB7XG4gICAgICBzID0gcHQucCArIChwdC5tID8gcHQubShwdC5zICsgcHQuYyAqIHJhdGlvKSA6IE1hdGgucm91bmQoKHB0LnMgKyBwdC5jICogcmF0aW8pICogMTAwMDApIC8gMTAwMDApICsgczsgLy93ZSB1c2UgdGhlIFwicFwiIHByb3BlcnR5IGZvciB0aGUgdGV4dCBpbmJldHdlZW4gKGxpa2UgYSBzdWZmaXgpLiBBbmQgaW4gdGhlIGNvbnRleHQgb2YgYSBjb21wbGV4IHN0cmluZywgdGhlIG1vZGlmaWVyIChtKSBpcyB0eXBpY2FsbHkganVzdCBNYXRoLnJvdW5kKCksIGxpa2UgZm9yIFJHQiBjb2xvcnMuXG5cbiAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgfVxuXG4gICAgcyArPSBkYXRhLmM7IC8vd2UgdXNlIHRoZSBcImNcIiBvZiB0aGUgUHJvcFR3ZWVuIHRvIHN0b3JlIHRoZSBmaW5hbCBjaHVuayBvZiBub24tbnVtZXJpYyB0ZXh0LlxuICB9XG5cbiAgZGF0YS5zZXQoZGF0YS50LCBkYXRhLnAsIHMsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyUHJvcFR3ZWVucyA9IGZ1bmN0aW9uIF9yZW5kZXJQcm9wVHdlZW5zKHJhdGlvLCBkYXRhKSB7XG4gIHZhciBwdCA9IGRhdGEuX3B0O1xuXG4gIHdoaWxlIChwdCkge1xuICAgIHB0LnIocmF0aW8sIHB0LmQpO1xuICAgIHB0ID0gcHQuX25leHQ7XG4gIH1cbn0sXG4gICAgX2FkZFBsdWdpbk1vZGlmaWVyID0gZnVuY3Rpb24gX2FkZFBsdWdpbk1vZGlmaWVyKG1vZGlmaWVyLCB0d2VlbiwgdGFyZ2V0LCBwcm9wZXJ0eSkge1xuICB2YXIgcHQgPSB0aGlzLl9wdCxcbiAgICAgIG5leHQ7XG5cbiAgd2hpbGUgKHB0KSB7XG4gICAgbmV4dCA9IHB0Ll9uZXh0O1xuICAgIHB0LnAgPT09IHByb3BlcnR5ICYmIHB0Lm1vZGlmaWVyKG1vZGlmaWVyLCB0d2VlbiwgdGFyZ2V0KTtcbiAgICBwdCA9IG5leHQ7XG4gIH1cbn0sXG4gICAgX2tpbGxQcm9wVHdlZW5zT2YgPSBmdW5jdGlvbiBfa2lsbFByb3BUd2VlbnNPZihwcm9wZXJ0eSkge1xuICB2YXIgcHQgPSB0aGlzLl9wdCxcbiAgICAgIGhhc05vbkRlcGVuZGVudFJlbWFpbmluZyxcbiAgICAgIG5leHQ7XG5cbiAgd2hpbGUgKHB0KSB7XG4gICAgbmV4dCA9IHB0Ll9uZXh0O1xuXG4gICAgaWYgKHB0LnAgPT09IHByb3BlcnR5ICYmICFwdC5vcCB8fCBwdC5vcCA9PT0gcHJvcGVydHkpIHtcbiAgICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSh0aGlzLCBwdCwgXCJfcHRcIik7XG4gICAgfSBlbHNlIGlmICghcHQuZGVwKSB7XG4gICAgICBoYXNOb25EZXBlbmRlbnRSZW1haW5pbmcgPSAxO1xuICAgIH1cblxuICAgIHB0ID0gbmV4dDtcbiAgfVxuXG4gIHJldHVybiAhaGFzTm9uRGVwZW5kZW50UmVtYWluaW5nO1xufSxcbiAgICBfc2V0dGVyV2l0aE1vZGlmaWVyID0gZnVuY3Rpb24gX3NldHRlcldpdGhNb2RpZmllcih0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgZGF0YSkge1xuICBkYXRhLm1TZXQodGFyZ2V0LCBwcm9wZXJ0eSwgZGF0YS5tLmNhbGwoZGF0YS50d2VlbiwgdmFsdWUsIGRhdGEubXQpLCBkYXRhKTtcbn0sXG4gICAgX3NvcnRQcm9wVHdlZW5zQnlQcmlvcml0eSA9IGZ1bmN0aW9uIF9zb3J0UHJvcFR3ZWVuc0J5UHJpb3JpdHkocGFyZW50KSB7XG4gIHZhciBwdCA9IHBhcmVudC5fcHQsXG4gICAgICBuZXh0LFxuICAgICAgcHQyLFxuICAgICAgZmlyc3QsXG4gICAgICBsYXN0OyAvL3NvcnRzIHRoZSBQcm9wVHdlZW4gbGlua2VkIGxpc3QgaW4gb3JkZXIgb2YgcHJpb3JpdHkgYmVjYXVzZSBzb21lIHBsdWdpbnMgbmVlZCB0byBkbyB0aGVpciB3b3JrIGFmdGVyIEFMTCBvZiB0aGUgUHJvcFR3ZWVucyB3ZXJlIGNyZWF0ZWQgKGxpa2UgUm91bmRQcm9wc1BsdWdpbiBhbmQgTW9kaWZpZXJzUGx1Z2luKVxuXG4gIHdoaWxlIChwdCkge1xuICAgIG5leHQgPSBwdC5fbmV4dDtcbiAgICBwdDIgPSBmaXJzdDtcblxuICAgIHdoaWxlIChwdDIgJiYgcHQyLnByID4gcHQucHIpIHtcbiAgICAgIHB0MiA9IHB0Mi5fbmV4dDtcbiAgICB9XG5cbiAgICBpZiAocHQuX3ByZXYgPSBwdDIgPyBwdDIuX3ByZXYgOiBsYXN0KSB7XG4gICAgICBwdC5fcHJldi5fbmV4dCA9IHB0O1xuICAgIH0gZWxzZSB7XG4gICAgICBmaXJzdCA9IHB0O1xuICAgIH1cblxuICAgIGlmIChwdC5fbmV4dCA9IHB0Mikge1xuICAgICAgcHQyLl9wcmV2ID0gcHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhc3QgPSBwdDtcbiAgICB9XG5cbiAgICBwdCA9IG5leHQ7XG4gIH1cblxuICBwYXJlbnQuX3B0ID0gZmlyc3Q7XG59OyAvL1Byb3BUd2VlbiBrZXk6IHQgPSB0YXJnZXQsIHAgPSBwcm9wLCByID0gcmVuZGVyZXIsIGQgPSBkYXRhLCBzID0gc3RhcnQsIGMgPSBjaGFuZ2UsIG9wID0gb3ZlcndyaXRlUHJvcGVydHkgKE9OTFkgcG9wdWxhdGVkIHdoZW4gaXQncyBkaWZmZXJlbnQgdGhhbiBwKSwgcHIgPSBwcmlvcml0eSwgX25leHQvX3ByZXYgZm9yIHRoZSBsaW5rZWQgbGlzdCBzaWJsaW5ncywgc2V0ID0gc2V0dGVyLCBtID0gbW9kaWZpZXIsIG1TZXQgPSBtb2RpZmllclNldHRlciAodGhlIG9yaWdpbmFsIHNldHRlciwgYmVmb3JlIGEgbW9kaWZpZXIgd2FzIGFkZGVkKVxuXG5cbmV4cG9ydCB2YXIgUHJvcFR3ZWVuID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gUHJvcFR3ZWVuKG5leHQsIHRhcmdldCwgcHJvcCwgc3RhcnQsIGNoYW5nZSwgcmVuZGVyZXIsIGRhdGEsIHNldHRlciwgcHJpb3JpdHkpIHtcbiAgICB0aGlzLnQgPSB0YXJnZXQ7XG4gICAgdGhpcy5zID0gc3RhcnQ7XG4gICAgdGhpcy5jID0gY2hhbmdlO1xuICAgIHRoaXMucCA9IHByb3A7XG4gICAgdGhpcy5yID0gcmVuZGVyZXIgfHwgX3JlbmRlclBsYWluO1xuICAgIHRoaXMuZCA9IGRhdGEgfHwgdGhpcztcbiAgICB0aGlzLnNldCA9IHNldHRlciB8fCBfc2V0dGVyUGxhaW47XG4gICAgdGhpcy5wciA9IHByaW9yaXR5IHx8IDA7XG4gICAgdGhpcy5fbmV4dCA9IG5leHQ7XG5cbiAgICBpZiAobmV4dCkge1xuICAgICAgbmV4dC5fcHJldiA9IHRoaXM7XG4gICAgfVxuICB9XG5cbiAgdmFyIF9wcm90bzQgPSBQcm9wVHdlZW4ucHJvdG90eXBlO1xuXG4gIF9wcm90bzQubW9kaWZpZXIgPSBmdW5jdGlvbiBtb2RpZmllcihmdW5jLCB0d2VlbiwgdGFyZ2V0KSB7XG4gICAgdGhpcy5tU2V0ID0gdGhpcy5tU2V0IHx8IHRoaXMuc2V0OyAvL2luIGNhc2UgaXQgd2FzIGFscmVhZHkgc2V0IChhIFByb3BUd2VlbiBjYW4gb25seSBoYXZlIG9uZSBtb2RpZmllcilcblxuICAgIHRoaXMuc2V0ID0gX3NldHRlcldpdGhNb2RpZmllcjtcbiAgICB0aGlzLm0gPSBmdW5jO1xuICAgIHRoaXMubXQgPSB0YXJnZXQ7IC8vbW9kaWZpZXIgdGFyZ2V0XG5cbiAgICB0aGlzLnR3ZWVuID0gdHdlZW47XG4gIH07XG5cbiAgcmV0dXJuIFByb3BUd2Vlbjtcbn0oKTsgLy9Jbml0aWFsaXphdGlvbiB0YXNrc1xuXG5fZm9yRWFjaE5hbWUoX2NhbGxiYWNrTmFtZXMgKyBcInBhcmVudCxkdXJhdGlvbixlYXNlLGRlbGF5LG92ZXJ3cml0ZSxydW5CYWNrd2FyZHMsc3RhcnRBdCx5b3lvLGltbWVkaWF0ZVJlbmRlcixyZXBlYXQscmVwZWF0RGVsYXksZGF0YSxwYXVzZWQscmV2ZXJzZWQsbGF6eSxjYWxsYmFja1Njb3BlLHN0cmluZ0ZpbHRlcixpZCx5b3lvRWFzZSxzdGFnZ2VyLGluaGVyaXQscmVwZWF0UmVmcmVzaCxrZXlmcmFtZXMsYXV0b1JldmVydCxzY3JvbGxUcmlnZ2VyXCIsIGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBfcmVzZXJ2ZWRQcm9wc1tuYW1lXSA9IDE7XG59KTtcblxuX2dsb2JhbHMuVHdlZW5NYXggPSBfZ2xvYmFscy5Ud2VlbkxpdGUgPSBUd2Vlbjtcbl9nbG9iYWxzLlRpbWVsaW5lTGl0ZSA9IF9nbG9iYWxzLlRpbWVsaW5lTWF4ID0gVGltZWxpbmU7XG5fZ2xvYmFsVGltZWxpbmUgPSBuZXcgVGltZWxpbmUoe1xuICBzb3J0Q2hpbGRyZW46IGZhbHNlLFxuICBkZWZhdWx0czogX2RlZmF1bHRzLFxuICBhdXRvUmVtb3ZlQ2hpbGRyZW46IHRydWUsXG4gIGlkOiBcInJvb3RcIixcbiAgc21vb3RoQ2hpbGRUaW1pbmc6IHRydWVcbn0pO1xuX2NvbmZpZy5zdHJpbmdGaWx0ZXIgPSBfY29sb3JTdHJpbmdGaWx0ZXI7XG5cbnZhciBfbWVkaWEgPSBbXSxcbiAgICBfbGlzdGVuZXJzID0ge30sXG4gICAgX2VtcHR5QXJyYXkgPSBbXSxcbiAgICBfbGFzdE1lZGlhVGltZSA9IDAsXG4gICAgX2Rpc3BhdGNoID0gZnVuY3Rpb24gX2Rpc3BhdGNoKHR5cGUpIHtcbiAgcmV0dXJuIChfbGlzdGVuZXJzW3R5cGVdIHx8IF9lbXB0eUFycmF5KS5tYXAoZnVuY3Rpb24gKGYpIHtcbiAgICByZXR1cm4gZigpO1xuICB9KTtcbn0sXG4gICAgX29uTWVkaWFDaGFuZ2UgPSBmdW5jdGlvbiBfb25NZWRpYUNoYW5nZSgpIHtcbiAgdmFyIHRpbWUgPSBEYXRlLm5vdygpLFxuICAgICAgbWF0Y2hlcyA9IFtdO1xuXG4gIGlmICh0aW1lIC0gX2xhc3RNZWRpYVRpbWUgPiAyKSB7XG4gICAgX2Rpc3BhdGNoKFwibWF0Y2hNZWRpYUluaXRcIik7XG5cbiAgICBfbWVkaWEuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgdmFyIHF1ZXJpZXMgPSBjLnF1ZXJpZXMsXG4gICAgICAgICAgY29uZGl0aW9ucyA9IGMuY29uZGl0aW9ucyxcbiAgICAgICAgICBtYXRjaCxcbiAgICAgICAgICBwLFxuICAgICAgICAgIGFueU1hdGNoLFxuICAgICAgICAgIHRvZ2dsZWQ7XG5cbiAgICAgIGZvciAocCBpbiBxdWVyaWVzKSB7XG4gICAgICAgIG1hdGNoID0gX3dpbi5tYXRjaE1lZGlhKHF1ZXJpZXNbcF0pLm1hdGNoZXM7IC8vIEZpcmVmb3ggZG9lc24ndCB1cGRhdGUgdGhlIFwibWF0Y2hlc1wiIHByb3BlcnR5IG9mIHRoZSBNZWRpYVF1ZXJ5TGlzdCBvYmplY3QgY29ycmVjdGx5IC0gaXQgb25seSBkb2VzIHNvIGFzIGl0IGNhbGxzIGl0cyBjaGFuZ2UgaGFuZGxlciAtIHNvIHdlIG11c3QgcmUtY3JlYXRlIGEgbWVkaWEgcXVlcnkgaGVyZSB0byBlbnN1cmUgaXQncyBhY2N1cmF0ZS5cblxuICAgICAgICBtYXRjaCAmJiAoYW55TWF0Y2ggPSAxKTtcblxuICAgICAgICBpZiAobWF0Y2ggIT09IGNvbmRpdGlvbnNbcF0pIHtcbiAgICAgICAgICBjb25kaXRpb25zW3BdID0gbWF0Y2g7XG4gICAgICAgICAgdG9nZ2xlZCA9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRvZ2dsZWQpIHtcbiAgICAgICAgYy5yZXZlcnQoKTtcbiAgICAgICAgYW55TWF0Y2ggJiYgbWF0Y2hlcy5wdXNoKGMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgX2Rpc3BhdGNoKFwibWF0Y2hNZWRpYVJldmVydFwiKTtcblxuICAgIG1hdGNoZXMuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgcmV0dXJuIGMub25NYXRjaChjKTtcbiAgICB9KTtcbiAgICBfbGFzdE1lZGlhVGltZSA9IHRpbWU7XG5cbiAgICBfZGlzcGF0Y2goXCJtYXRjaE1lZGlhXCIpO1xuICB9XG59O1xuXG52YXIgQ29udGV4dCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIENvbnRleHQoZnVuYywgc2NvcGUpIHtcbiAgICB0aGlzLnNlbGVjdG9yID0gc2NvcGUgJiYgc2VsZWN0b3Ioc2NvcGUpO1xuICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgIHRoaXMuX3IgPSBbXTsgLy8gcmV0dXJuZWQvY2xlYW51cCBmdW5jdGlvbnNcblxuICAgIHRoaXMuaXNSZXZlcnRlZCA9IGZhbHNlO1xuICAgIGZ1bmMgJiYgdGhpcy5hZGQoZnVuYyk7XG4gIH1cblxuICB2YXIgX3Byb3RvNSA9IENvbnRleHQucHJvdG90eXBlO1xuXG4gIF9wcm90bzUuYWRkID0gZnVuY3Rpb24gYWRkKG5hbWUsIGZ1bmMsIHNjb3BlKSB7XG4gICAgLy8gcG9zc2libGUgZnV0dXJlIGFkZGl0aW9uIGlmIHdlIG5lZWQgdGhlIGFiaWxpdHkgdG8gYWRkKCkgYW4gYW5pbWF0aW9uIHRvIGEgY29udGV4dCBhbmQgZm9yIHdoYXRldmVyIHJlYXNvbiBjYW5ub3QgY3JlYXRlIHRoYXQgYW5pbWF0aW9uIGluc2lkZSBvZiBhIGNvbnRleHQuYWRkKCgpID0+IHsuLi59KSBmdW5jdGlvbi5cbiAgICAvLyBpZiAobmFtZSAmJiBfaXNGdW5jdGlvbihuYW1lLnJldmVydCkpIHtcbiAgICAvLyBcdHRoaXMuZGF0YS5wdXNoKG5hbWUpO1xuICAgIC8vIFx0cmV0dXJuIChuYW1lLl9jdHggPSB0aGlzKTtcbiAgICAvLyB9XG4gICAgaWYgKF9pc0Z1bmN0aW9uKG5hbWUpKSB7XG4gICAgICBzY29wZSA9IGZ1bmM7XG4gICAgICBmdW5jID0gbmFtZTtcbiAgICAgIG5hbWUgPSBfaXNGdW5jdGlvbjtcbiAgICB9XG5cbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIGYgPSBmdW5jdGlvbiBmKCkge1xuICAgICAgdmFyIHByZXYgPSBfY29udGV4dCxcbiAgICAgICAgICBwcmV2U2VsZWN0b3IgPSBzZWxmLnNlbGVjdG9yLFxuICAgICAgICAgIHJlc3VsdDtcbiAgICAgIHByZXYgJiYgcHJldiAhPT0gc2VsZiAmJiBwcmV2LmRhdGEucHVzaChzZWxmKTtcbiAgICAgIHNjb3BlICYmIChzZWxmLnNlbGVjdG9yID0gc2VsZWN0b3Ioc2NvcGUpKTtcbiAgICAgIF9jb250ZXh0ID0gc2VsZjtcbiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoc2VsZiwgYXJndW1lbnRzKTtcbiAgICAgIF9pc0Z1bmN0aW9uKHJlc3VsdCkgJiYgc2VsZi5fci5wdXNoKHJlc3VsdCk7XG4gICAgICBfY29udGV4dCA9IHByZXY7XG4gICAgICBzZWxmLnNlbGVjdG9yID0gcHJldlNlbGVjdG9yO1xuICAgICAgc2VsZi5pc1JldmVydGVkID0gZmFsc2U7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBzZWxmLmxhc3QgPSBmO1xuICAgIHJldHVybiBuYW1lID09PSBfaXNGdW5jdGlvbiA/IGYoc2VsZikgOiBuYW1lID8gc2VsZltuYW1lXSA9IGYgOiBmO1xuICB9O1xuXG4gIF9wcm90bzUuaWdub3JlID0gZnVuY3Rpb24gaWdub3JlKGZ1bmMpIHtcbiAgICB2YXIgcHJldiA9IF9jb250ZXh0O1xuICAgIF9jb250ZXh0ID0gbnVsbDtcbiAgICBmdW5jKHRoaXMpO1xuICAgIF9jb250ZXh0ID0gcHJldjtcbiAgfTtcblxuICBfcHJvdG81LmdldFR3ZWVucyA9IGZ1bmN0aW9uIGdldFR3ZWVucygpIHtcbiAgICB2YXIgYSA9IFtdO1xuICAgIHRoaXMuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gZSBpbnN0YW5jZW9mIENvbnRleHQgPyBhLnB1c2guYXBwbHkoYSwgZS5nZXRUd2VlbnMoKSkgOiBlIGluc3RhbmNlb2YgVHdlZW4gJiYgIShlLnBhcmVudCAmJiBlLnBhcmVudC5kYXRhID09PSBcIm5lc3RlZFwiKSAmJiBhLnB1c2goZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGE7XG4gIH07XG5cbiAgX3Byb3RvNS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIHRoaXMuX3IubGVuZ3RoID0gdGhpcy5kYXRhLmxlbmd0aCA9IDA7XG4gIH07XG5cbiAgX3Byb3RvNS5raWxsID0gZnVuY3Rpb24ga2lsbChyZXZlcnQsIG1hdGNoTWVkaWEpIHtcbiAgICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICAgIGlmIChyZXZlcnQpIHtcbiAgICAgIHZhciB0d2VlbnMgPSB0aGlzLmdldFR3ZWVucygpO1xuICAgICAgdGhpcy5kYXRhLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgLy8gRmxpcCBwbHVnaW4gdHdlZW5zIGFyZSB2ZXJ5IGRpZmZlcmVudCBpbiB0aGF0IHRoZXkgc2hvdWxkIGFjdHVhbGx5IGJlIHB1c2hlZCB0byB0aGVpciBlbmQuIFRoZSBwbHVnaW4gcmVwbGFjZXMgdGhlIHRpbWVsaW5lJ3MgLnJldmVydCgpIG1ldGhvZCB0byBkbyBleGFjdGx5IHRoYXQuIEJ1dCB3ZSBhbHNvIG5lZWQgdG8gcmVtb3ZlIGFueSBvZiB0aG9zZSBuZXN0ZWQgdHdlZW5zIGluc2lkZSB0aGUgZmxpcCB0aW1lbGluZSBzbyB0aGF0IHRoZXkgZG9uJ3QgZ2V0IGluZGl2aWR1YWxseSByZXZlcnRlZC5cbiAgICAgICAgaWYgKHQuZGF0YSA9PT0gXCJpc0ZsaXBcIikge1xuICAgICAgICAgIHQucmV2ZXJ0KCk7XG4gICAgICAgICAgdC5nZXRDaGlsZHJlbih0cnVlLCB0cnVlLCBmYWxzZSkuZm9yRWFjaChmdW5jdGlvbiAodHdlZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0d2VlbnMuc3BsaWNlKHR3ZWVucy5pbmRleE9mKHR3ZWVuKSwgMSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pOyAvLyBzYXZlIGFzIGFuIG9iamVjdCBzbyB0aGF0IHdlIGNhbiBjYWNoZSB0aGUgZ2xvYmFsVGltZSBmb3IgZWFjaCB0d2VlbiB0byBvcHRpbWl6ZSBwZXJmb3JtYW5jZSBkdXJpbmcgdGhlIHNvcnRcblxuICAgICAgdHdlZW5zLm1hcChmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGc6IHQuZ2xvYmFsVGltZSgwKSxcbiAgICAgICAgICB0OiB0XG4gICAgICAgIH07XG4gICAgICB9KS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBiLmcgLSBhLmcgfHwgLTE7XG4gICAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiBvLnQucmV2ZXJ0KHJldmVydCk7XG4gICAgICB9KTsgLy8gbm90ZTogYWxsIG9mIHRoZSBfc3RhcnRBdCB0d2VlbnMgc2hvdWxkIGJlIHJldmVydGVkIGluIHJldmVyc2Ugb3JkZXIgdGhhdCB0aGV5IHdlcmUgY3JlYXRlZCwgYW5kIHRoZXknbGwgYWxsIGhhdmUgdGhlIHNhbWUgZ2xvYmFsVGltZSAoLTEpIHNvIHRoZSBcIiB8fCAtMVwiIGluIHRoZSBzb3J0IGtlZXBzIHRoZSBvcmRlciBwcm9wZXJseS5cblxuICAgICAgdGhpcy5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuICEoZSBpbnN0YW5jZW9mIEFuaW1hdGlvbikgJiYgZS5yZXZlcnQgJiYgZS5yZXZlcnQocmV2ZXJ0KTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9yLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgcmV0dXJuIGYocmV2ZXJ0LCBfdGhpczQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuaXNSZXZlcnRlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiBlLmtpbGwgJiYgZS5raWxsKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNsZWFyKCk7XG5cbiAgICBpZiAobWF0Y2hNZWRpYSkge1xuICAgICAgdmFyIGkgPSBfbWVkaWEuaW5kZXhPZih0aGlzKTtcblxuICAgICAgISF+aSAmJiBfbWVkaWEuc3BsaWNlKGksIDEpO1xuICAgIH1cbiAgfTtcblxuICBfcHJvdG81LnJldmVydCA9IGZ1bmN0aW9uIHJldmVydChjb25maWcpIHtcbiAgICB0aGlzLmtpbGwoY29uZmlnIHx8IHt9KTtcbiAgfTtcblxuICByZXR1cm4gQ29udGV4dDtcbn0oKTtcblxudmFyIE1hdGNoTWVkaWEgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBNYXRjaE1lZGlhKHNjb3BlKSB7XG4gICAgdGhpcy5jb250ZXh0cyA9IFtdO1xuICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgfVxuXG4gIHZhciBfcHJvdG82ID0gTWF0Y2hNZWRpYS5wcm90b3R5cGU7XG5cbiAgX3Byb3RvNi5hZGQgPSBmdW5jdGlvbiBhZGQoY29uZGl0aW9ucywgZnVuYywgc2NvcGUpIHtcbiAgICBfaXNPYmplY3QoY29uZGl0aW9ucykgfHwgKGNvbmRpdGlvbnMgPSB7XG4gICAgICBtYXRjaGVzOiBjb25kaXRpb25zXG4gICAgfSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCgwLCBzY29wZSB8fCB0aGlzLnNjb3BlKSxcbiAgICAgICAgY29uZCA9IGNvbnRleHQuY29uZGl0aW9ucyA9IHt9LFxuICAgICAgICBtcSxcbiAgICAgICAgcCxcbiAgICAgICAgYWN0aXZlO1xuICAgIHRoaXMuY29udGV4dHMucHVzaChjb250ZXh0KTtcbiAgICBmdW5jID0gY29udGV4dC5hZGQoXCJvbk1hdGNoXCIsIGZ1bmMpO1xuICAgIGNvbnRleHQucXVlcmllcyA9IGNvbmRpdGlvbnM7XG5cbiAgICBmb3IgKHAgaW4gY29uZGl0aW9ucykge1xuICAgICAgaWYgKHAgPT09IFwiYWxsXCIpIHtcbiAgICAgICAgYWN0aXZlID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1xID0gX3dpbi5tYXRjaE1lZGlhKGNvbmRpdGlvbnNbcF0pO1xuXG4gICAgICAgIGlmIChtcSkge1xuICAgICAgICAgIF9tZWRpYS5pbmRleE9mKGNvbnRleHQpIDwgMCAmJiBfbWVkaWEucHVzaChjb250ZXh0KTtcbiAgICAgICAgICAoY29uZFtwXSA9IG1xLm1hdGNoZXMpICYmIChhY3RpdmUgPSAxKTtcbiAgICAgICAgICBtcS5hZGRMaXN0ZW5lciA/IG1xLmFkZExpc3RlbmVyKF9vbk1lZGlhQ2hhbmdlKSA6IG1xLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgX29uTWVkaWFDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYWN0aXZlICYmIGZ1bmMoY29udGV4dCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gLy8gcmVmcmVzaCgpIHtcbiAgLy8gXHRsZXQgdGltZSA9IF9sYXN0TWVkaWFUaW1lLFxuICAvLyBcdFx0bWVkaWEgPSBfbWVkaWE7XG4gIC8vIFx0X2xhc3RNZWRpYVRpbWUgPSAtMTtcbiAgLy8gXHRfbWVkaWEgPSB0aGlzLmNvbnRleHRzO1xuICAvLyBcdF9vbk1lZGlhQ2hhbmdlKCk7XG4gIC8vIFx0X2xhc3RNZWRpYVRpbWUgPSB0aW1lO1xuICAvLyBcdF9tZWRpYSA9IG1lZGlhO1xuICAvLyB9XG4gIDtcblxuICBfcHJvdG82LnJldmVydCA9IGZ1bmN0aW9uIHJldmVydChjb25maWcpIHtcbiAgICB0aGlzLmtpbGwoY29uZmlnIHx8IHt9KTtcbiAgfTtcblxuICBfcHJvdG82LmtpbGwgPSBmdW5jdGlvbiBraWxsKHJldmVydCkge1xuICAgIHRoaXMuY29udGV4dHMuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgcmV0dXJuIGMua2lsbChyZXZlcnQsIHRydWUpO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBNYXRjaE1lZGlhO1xufSgpO1xuLypcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBHU0FQXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxudmFyIF9nc2FwID0ge1xuICByZWdpc3RlclBsdWdpbjogZnVuY3Rpb24gcmVnaXN0ZXJQbHVnaW4oKSB7XG4gICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgfVxuXG4gICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgIHJldHVybiBfY3JlYXRlUGx1Z2luKGNvbmZpZyk7XG4gICAgfSk7XG4gIH0sXG4gIHRpbWVsaW5lOiBmdW5jdGlvbiB0aW1lbGluZSh2YXJzKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lbGluZSh2YXJzKTtcbiAgfSxcbiAgZ2V0VHdlZW5zT2Y6IGZ1bmN0aW9uIGdldFR3ZWVuc09mKHRhcmdldHMsIG9ubHlBY3RpdmUpIHtcbiAgICByZXR1cm4gX2dsb2JhbFRpbWVsaW5lLmdldFR3ZWVuc09mKHRhcmdldHMsIG9ubHlBY3RpdmUpO1xuICB9LFxuICBnZXRQcm9wZXJ0eTogZnVuY3Rpb24gZ2V0UHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCwgdW5jYWNoZSkge1xuICAgIF9pc1N0cmluZyh0YXJnZXQpICYmICh0YXJnZXQgPSB0b0FycmF5KHRhcmdldClbMF0pOyAvL2luIGNhc2Ugc2VsZWN0b3IgdGV4dCBvciBhbiBhcnJheSBpcyBwYXNzZWQgaW5cblxuICAgIHZhciBnZXR0ZXIgPSBfZ2V0Q2FjaGUodGFyZ2V0IHx8IHt9KS5nZXQsXG4gICAgICAgIGZvcm1hdCA9IHVuaXQgPyBfcGFzc1Rocm91Z2ggOiBfbnVtZXJpY0lmUG9zc2libGU7XG5cbiAgICB1bml0ID09PSBcIm5hdGl2ZVwiICYmICh1bml0ID0gXCJcIik7XG4gICAgcmV0dXJuICF0YXJnZXQgPyB0YXJnZXQgOiAhcHJvcGVydHkgPyBmdW5jdGlvbiAocHJvcGVydHksIHVuaXQsIHVuY2FjaGUpIHtcbiAgICAgIHJldHVybiBmb3JtYXQoKF9wbHVnaW5zW3Byb3BlcnR5XSAmJiBfcGx1Z2luc1twcm9wZXJ0eV0uZ2V0IHx8IGdldHRlcikodGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCwgdW5jYWNoZSkpO1xuICAgIH0gOiBmb3JtYXQoKF9wbHVnaW5zW3Byb3BlcnR5XSAmJiBfcGx1Z2luc1twcm9wZXJ0eV0uZ2V0IHx8IGdldHRlcikodGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCwgdW5jYWNoZSkpO1xuICB9LFxuICBxdWlja1NldHRlcjogZnVuY3Rpb24gcXVpY2tTZXR0ZXIodGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCkge1xuICAgIHRhcmdldCA9IHRvQXJyYXkodGFyZ2V0KTtcblxuICAgIGlmICh0YXJnZXQubGVuZ3RoID4gMSkge1xuICAgICAgdmFyIHNldHRlcnMgPSB0YXJnZXQubWFwKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiBnc2FwLnF1aWNrU2V0dGVyKHQsIHByb3BlcnR5LCB1bml0KTtcbiAgICAgIH0pLFxuICAgICAgICAgIGwgPSBzZXR0ZXJzLmxlbmd0aDtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIGkgPSBsO1xuXG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICBzZXR0ZXJzW2ldKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0YXJnZXQgPSB0YXJnZXRbMF0gfHwge307XG5cbiAgICB2YXIgUGx1Z2luID0gX3BsdWdpbnNbcHJvcGVydHldLFxuICAgICAgICBjYWNoZSA9IF9nZXRDYWNoZSh0YXJnZXQpLFxuICAgICAgICBwID0gY2FjaGUuaGFybmVzcyAmJiAoY2FjaGUuaGFybmVzcy5hbGlhc2VzIHx8IHt9KVtwcm9wZXJ0eV0gfHwgcHJvcGVydHksXG4gICAgICAgIC8vIGluIGNhc2UgaXQncyBhbiBhbGlhcywgbGlrZSBcInJvdGF0ZVwiIGZvciBcInJvdGF0aW9uXCIuXG4gICAgc2V0dGVyID0gUGx1Z2luID8gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB2YXIgcCA9IG5ldyBQbHVnaW4oKTtcbiAgICAgIF9xdWlja1R3ZWVuLl9wdCA9IDA7XG4gICAgICBwLmluaXQodGFyZ2V0LCB1bml0ID8gdmFsdWUgKyB1bml0IDogdmFsdWUsIF9xdWlja1R3ZWVuLCAwLCBbdGFyZ2V0XSk7XG4gICAgICBwLnJlbmRlcigxLCBwKTtcbiAgICAgIF9xdWlja1R3ZWVuLl9wdCAmJiBfcmVuZGVyUHJvcFR3ZWVucygxLCBfcXVpY2tUd2Vlbik7XG4gICAgfSA6IGNhY2hlLnNldCh0YXJnZXQsIHApO1xuXG4gICAgcmV0dXJuIFBsdWdpbiA/IHNldHRlciA6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHNldHRlcih0YXJnZXQsIHAsIHVuaXQgPyB2YWx1ZSArIHVuaXQgOiB2YWx1ZSwgY2FjaGUsIDEpO1xuICAgIH07XG4gIH0sXG4gIHF1aWNrVG86IGZ1bmN0aW9uIHF1aWNrVG8odGFyZ2V0LCBwcm9wZXJ0eSwgdmFycykge1xuICAgIHZhciBfbWVyZ2UyO1xuXG4gICAgdmFyIHR3ZWVuID0gZ3NhcC50byh0YXJnZXQsIF9tZXJnZSgoX21lcmdlMiA9IHt9LCBfbWVyZ2UyW3Byb3BlcnR5XSA9IFwiKz0wLjFcIiwgX21lcmdlMi5wYXVzZWQgPSB0cnVlLCBfbWVyZ2UyKSwgdmFycyB8fCB7fSkpLFxuICAgICAgICBmdW5jID0gZnVuY3Rpb24gZnVuYyh2YWx1ZSwgc3RhcnQsIHN0YXJ0SXNSZWxhdGl2ZSkge1xuICAgICAgcmV0dXJuIHR3ZWVuLnJlc2V0VG8ocHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlKTtcbiAgICB9O1xuXG4gICAgZnVuYy50d2VlbiA9IHR3ZWVuO1xuICAgIHJldHVybiBmdW5jO1xuICB9LFxuICBpc1R3ZWVuaW5nOiBmdW5jdGlvbiBpc1R3ZWVuaW5nKHRhcmdldHMpIHtcbiAgICByZXR1cm4gX2dsb2JhbFRpbWVsaW5lLmdldFR3ZWVuc09mKHRhcmdldHMsIHRydWUpLmxlbmd0aCA+IDA7XG4gIH0sXG4gIGRlZmF1bHRzOiBmdW5jdGlvbiBkZWZhdWx0cyh2YWx1ZSkge1xuICAgIHZhbHVlICYmIHZhbHVlLmVhc2UgJiYgKHZhbHVlLmVhc2UgPSBfcGFyc2VFYXNlKHZhbHVlLmVhc2UsIF9kZWZhdWx0cy5lYXNlKSk7XG4gICAgcmV0dXJuIF9tZXJnZURlZXAoX2RlZmF1bHRzLCB2YWx1ZSB8fCB7fSk7XG4gIH0sXG4gIGNvbmZpZzogZnVuY3Rpb24gY29uZmlnKHZhbHVlKSB7XG4gICAgcmV0dXJuIF9tZXJnZURlZXAoX2NvbmZpZywgdmFsdWUgfHwge30pO1xuICB9LFxuICByZWdpc3RlckVmZmVjdDogZnVuY3Rpb24gcmVnaXN0ZXJFZmZlY3QoX3JlZjMpIHtcbiAgICB2YXIgbmFtZSA9IF9yZWYzLm5hbWUsXG4gICAgICAgIGVmZmVjdCA9IF9yZWYzLmVmZmVjdCxcbiAgICAgICAgcGx1Z2lucyA9IF9yZWYzLnBsdWdpbnMsXG4gICAgICAgIGRlZmF1bHRzID0gX3JlZjMuZGVmYXVsdHMsXG4gICAgICAgIGV4dGVuZFRpbWVsaW5lID0gX3JlZjMuZXh0ZW5kVGltZWxpbmU7XG4gICAgKHBsdWdpbnMgfHwgXCJcIikuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKHBsdWdpbk5hbWUpIHtcbiAgICAgIHJldHVybiBwbHVnaW5OYW1lICYmICFfcGx1Z2luc1twbHVnaW5OYW1lXSAmJiAhX2dsb2JhbHNbcGx1Z2luTmFtZV0gJiYgX3dhcm4obmFtZSArIFwiIGVmZmVjdCByZXF1aXJlcyBcIiArIHBsdWdpbk5hbWUgKyBcIiBwbHVnaW4uXCIpO1xuICAgIH0pO1xuXG4gICAgX2VmZmVjdHNbbmFtZV0gPSBmdW5jdGlvbiAodGFyZ2V0cywgdmFycywgdGwpIHtcbiAgICAgIHJldHVybiBlZmZlY3QodG9BcnJheSh0YXJnZXRzKSwgX3NldERlZmF1bHRzKHZhcnMgfHwge30sIGRlZmF1bHRzKSwgdGwpO1xuICAgIH07XG5cbiAgICBpZiAoZXh0ZW5kVGltZWxpbmUpIHtcbiAgICAgIFRpbWVsaW5lLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uICh0YXJnZXRzLCB2YXJzLCBwb3NpdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGQoX2VmZmVjdHNbbmFtZV0odGFyZ2V0cywgX2lzT2JqZWN0KHZhcnMpID8gdmFycyA6IChwb3NpdGlvbiA9IHZhcnMpICYmIHt9LCB0aGlzKSwgcG9zaXRpb24pO1xuICAgICAgfTtcbiAgICB9XG4gIH0sXG4gIHJlZ2lzdGVyRWFzZTogZnVuY3Rpb24gcmVnaXN0ZXJFYXNlKG5hbWUsIGVhc2UpIHtcbiAgICBfZWFzZU1hcFtuYW1lXSA9IF9wYXJzZUVhc2UoZWFzZSk7XG4gIH0sXG4gIHBhcnNlRWFzZTogZnVuY3Rpb24gcGFyc2VFYXNlKGVhc2UsIGRlZmF1bHRFYXNlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBfcGFyc2VFYXNlKGVhc2UsIGRlZmF1bHRFYXNlKSA6IF9lYXNlTWFwO1xuICB9LFxuICBnZXRCeUlkOiBmdW5jdGlvbiBnZXRCeUlkKGlkKSB7XG4gICAgcmV0dXJuIF9nbG9iYWxUaW1lbGluZS5nZXRCeUlkKGlkKTtcbiAgfSxcbiAgZXhwb3J0Um9vdDogZnVuY3Rpb24gZXhwb3J0Um9vdCh2YXJzLCBpbmNsdWRlRGVsYXllZENhbGxzKSB7XG4gICAgaWYgKHZhcnMgPT09IHZvaWQgMCkge1xuICAgICAgdmFycyA9IHt9O1xuICAgIH1cblxuICAgIHZhciB0bCA9IG5ldyBUaW1lbGluZSh2YXJzKSxcbiAgICAgICAgY2hpbGQsXG4gICAgICAgIG5leHQ7XG4gICAgdGwuc21vb3RoQ2hpbGRUaW1pbmcgPSBfaXNOb3RGYWxzZSh2YXJzLnNtb290aENoaWxkVGltaW5nKTtcblxuICAgIF9nbG9iYWxUaW1lbGluZS5yZW1vdmUodGwpO1xuXG4gICAgdGwuX2RwID0gMDsgLy9vdGhlcndpc2UgaXQnbGwgZ2V0IHJlLWFjdGl2YXRlZCB3aGVuIGFkZGluZyBjaGlsZHJlbiBhbmQgYmUgcmUtaW50cm9kdWNlZCBpbnRvIF9nbG9iYWxUaW1lbGluZSdzIGxpbmtlZCBsaXN0ICh0aGVuIGFkZGVkIHRvIGl0c2VsZikuXG5cbiAgICB0bC5fdGltZSA9IHRsLl90VGltZSA9IF9nbG9iYWxUaW1lbGluZS5fdGltZTtcbiAgICBjaGlsZCA9IF9nbG9iYWxUaW1lbGluZS5fZmlyc3Q7XG5cbiAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgIG5leHQgPSBjaGlsZC5fbmV4dDtcblxuICAgICAgaWYgKGluY2x1ZGVEZWxheWVkQ2FsbHMgfHwgISghY2hpbGQuX2R1ciAmJiBjaGlsZCBpbnN0YW5jZW9mIFR3ZWVuICYmIGNoaWxkLnZhcnMub25Db21wbGV0ZSA9PT0gY2hpbGQuX3RhcmdldHNbMF0pKSB7XG4gICAgICAgIF9hZGRUb1RpbWVsaW5lKHRsLCBjaGlsZCwgY2hpbGQuX3N0YXJ0IC0gY2hpbGQuX2RlbGF5KTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBuZXh0O1xuICAgIH1cblxuICAgIF9hZGRUb1RpbWVsaW5lKF9nbG9iYWxUaW1lbGluZSwgdGwsIDApO1xuXG4gICAgcmV0dXJuIHRsO1xuICB9LFxuICBjb250ZXh0OiBmdW5jdGlvbiBjb250ZXh0KGZ1bmMsIHNjb3BlKSB7XG4gICAgcmV0dXJuIGZ1bmMgPyBuZXcgQ29udGV4dChmdW5jLCBzY29wZSkgOiBfY29udGV4dDtcbiAgfSxcbiAgbWF0Y2hNZWRpYTogZnVuY3Rpb24gbWF0Y2hNZWRpYShzY29wZSkge1xuICAgIHJldHVybiBuZXcgTWF0Y2hNZWRpYShzY29wZSk7XG4gIH0sXG4gIG1hdGNoTWVkaWFSZWZyZXNoOiBmdW5jdGlvbiBtYXRjaE1lZGlhUmVmcmVzaCgpIHtcbiAgICByZXR1cm4gX21lZGlhLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIHZhciBjb25kID0gYy5jb25kaXRpb25zLFxuICAgICAgICAgIGZvdW5kLFxuICAgICAgICAgIHA7XG5cbiAgICAgIGZvciAocCBpbiBjb25kKSB7XG4gICAgICAgIGlmIChjb25kW3BdKSB7XG4gICAgICAgICAgY29uZFtwXSA9IGZhbHNlO1xuICAgICAgICAgIGZvdW5kID0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3VuZCAmJiBjLnJldmVydCgpO1xuICAgIH0pIHx8IF9vbk1lZGlhQ2hhbmdlKCk7XG4gIH0sXG4gIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYSA9IF9saXN0ZW5lcnNbdHlwZV0gfHwgKF9saXN0ZW5lcnNbdHlwZV0gPSBbXSk7XG4gICAgfmEuaW5kZXhPZihjYWxsYmFjaykgfHwgYS5wdXNoKGNhbGxiYWNrKTtcbiAgfSxcbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjaykge1xuICAgIHZhciBhID0gX2xpc3RlbmVyc1t0eXBlXSxcbiAgICAgICAgaSA9IGEgJiYgYS5pbmRleE9mKGNhbGxiYWNrKTtcbiAgICBpID49IDAgJiYgYS5zcGxpY2UoaSwgMSk7XG4gIH0sXG4gIHV0aWxzOiB7XG4gICAgd3JhcDogd3JhcCxcbiAgICB3cmFwWW95bzogd3JhcFlveW8sXG4gICAgZGlzdHJpYnV0ZTogZGlzdHJpYnV0ZSxcbiAgICByYW5kb206IHJhbmRvbSxcbiAgICBzbmFwOiBzbmFwLFxuICAgIG5vcm1hbGl6ZTogbm9ybWFsaXplLFxuICAgIGdldFVuaXQ6IGdldFVuaXQsXG4gICAgY2xhbXA6IGNsYW1wLFxuICAgIHNwbGl0Q29sb3I6IHNwbGl0Q29sb3IsXG4gICAgdG9BcnJheTogdG9BcnJheSxcbiAgICBzZWxlY3Rvcjogc2VsZWN0b3IsXG4gICAgbWFwUmFuZ2U6IG1hcFJhbmdlLFxuICAgIHBpcGU6IHBpcGUsXG4gICAgdW5pdGl6ZTogdW5pdGl6ZSxcbiAgICBpbnRlcnBvbGF0ZTogaW50ZXJwb2xhdGUsXG4gICAgc2h1ZmZsZTogc2h1ZmZsZVxuICB9LFxuICBpbnN0YWxsOiBfaW5zdGFsbCxcbiAgZWZmZWN0czogX2VmZmVjdHMsXG4gIHRpY2tlcjogX3RpY2tlcixcbiAgdXBkYXRlUm9vdDogVGltZWxpbmUudXBkYXRlUm9vdCxcbiAgcGx1Z2luczogX3BsdWdpbnMsXG4gIGdsb2JhbFRpbWVsaW5lOiBfZ2xvYmFsVGltZWxpbmUsXG4gIGNvcmU6IHtcbiAgICBQcm9wVHdlZW46IFByb3BUd2VlbixcbiAgICBnbG9iYWxzOiBfYWRkR2xvYmFsLFxuICAgIFR3ZWVuOiBUd2VlbixcbiAgICBUaW1lbGluZTogVGltZWxpbmUsXG4gICAgQW5pbWF0aW9uOiBBbmltYXRpb24sXG4gICAgZ2V0Q2FjaGU6IF9nZXRDYWNoZSxcbiAgICBfcmVtb3ZlTGlua2VkTGlzdEl0ZW06IF9yZW1vdmVMaW5rZWRMaXN0SXRlbSxcbiAgICByZXZlcnRpbmc6IGZ1bmN0aW9uIHJldmVydGluZygpIHtcbiAgICAgIHJldHVybiBfcmV2ZXJ0aW5nO1xuICAgIH0sXG4gICAgY29udGV4dDogZnVuY3Rpb24gY29udGV4dCh0b0FkZCkge1xuICAgICAgaWYgKHRvQWRkICYmIF9jb250ZXh0KSB7XG4gICAgICAgIF9jb250ZXh0LmRhdGEucHVzaCh0b0FkZCk7XG5cbiAgICAgICAgdG9BZGQuX2N0eCA9IF9jb250ZXh0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gX2NvbnRleHQ7XG4gICAgfSxcbiAgICBzdXBwcmVzc092ZXJ3cml0ZXM6IGZ1bmN0aW9uIHN1cHByZXNzT3ZlcndyaXRlcyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIF9zdXBwcmVzc092ZXJ3cml0ZXMgPSB2YWx1ZTtcbiAgICB9XG4gIH1cbn07XG5cbl9mb3JFYWNoTmFtZShcInRvLGZyb20sZnJvbVRvLGRlbGF5ZWRDYWxsLHNldCxraWxsVHdlZW5zT2ZcIiwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIF9nc2FwW25hbWVdID0gVHdlZW5bbmFtZV07XG59KTtcblxuX3RpY2tlci5hZGQoVGltZWxpbmUudXBkYXRlUm9vdCk7XG5cbl9xdWlja1R3ZWVuID0gX2dzYXAudG8oe30sIHtcbiAgZHVyYXRpb246IDBcbn0pOyAvLyAtLS0tIEVYVFJBIFBMVUdJTlMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIF9nZXRQbHVnaW5Qcm9wVHdlZW4gPSBmdW5jdGlvbiBfZ2V0UGx1Z2luUHJvcFR3ZWVuKHBsdWdpbiwgcHJvcCkge1xuICB2YXIgcHQgPSBwbHVnaW4uX3B0O1xuXG4gIHdoaWxlIChwdCAmJiBwdC5wICE9PSBwcm9wICYmIHB0Lm9wICE9PSBwcm9wICYmIHB0LmZwICE9PSBwcm9wKSB7XG4gICAgcHQgPSBwdC5fbmV4dDtcbiAgfVxuXG4gIHJldHVybiBwdDtcbn0sXG4gICAgX2FkZE1vZGlmaWVycyA9IGZ1bmN0aW9uIF9hZGRNb2RpZmllcnModHdlZW4sIG1vZGlmaWVycykge1xuICB2YXIgdGFyZ2V0cyA9IHR3ZWVuLl90YXJnZXRzLFxuICAgICAgcCxcbiAgICAgIGksXG4gICAgICBwdDtcblxuICBmb3IgKHAgaW4gbW9kaWZpZXJzKSB7XG4gICAgaSA9IHRhcmdldHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcHQgPSB0d2Vlbi5fcHRMb29rdXBbaV1bcF07XG5cbiAgICAgIGlmIChwdCAmJiAocHQgPSBwdC5kKSkge1xuICAgICAgICBpZiAocHQuX3B0KSB7XG4gICAgICAgICAgLy8gaXMgYSBwbHVnaW5cbiAgICAgICAgICBwdCA9IF9nZXRQbHVnaW5Qcm9wVHdlZW4ocHQsIHApO1xuICAgICAgICB9XG5cbiAgICAgICAgcHQgJiYgcHQubW9kaWZpZXIgJiYgcHQubW9kaWZpZXIobW9kaWZpZXJzW3BdLCB0d2VlbiwgdGFyZ2V0c1tpXSwgcCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59LFxuICAgIF9idWlsZE1vZGlmaWVyUGx1Z2luID0gZnVuY3Rpb24gX2J1aWxkTW9kaWZpZXJQbHVnaW4obmFtZSwgbW9kaWZpZXIpIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBuYW1lLFxuICAgIHJhd1ZhcnM6IDEsXG4gICAgLy9kb24ndCBwcmUtcHJvY2VzcyBmdW5jdGlvbi1iYXNlZCB2YWx1ZXMgb3IgXCJyYW5kb20oKVwiIHN0cmluZ3MuXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCh0YXJnZXQsIHZhcnMsIHR3ZWVuKSB7XG4gICAgICB0d2Vlbi5fb25Jbml0ID0gZnVuY3Rpb24gKHR3ZWVuKSB7XG4gICAgICAgIHZhciB0ZW1wLCBwO1xuXG4gICAgICAgIGlmIChfaXNTdHJpbmcodmFycykpIHtcbiAgICAgICAgICB0ZW1wID0ge307XG5cbiAgICAgICAgICBfZm9yRWFjaE5hbWUodmFycywgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wW25hbWVdID0gMTtcbiAgICAgICAgICB9KTsgLy9pZiB0aGUgdXNlciBwYXNzZXMgaW4gYSBjb21tYS1kZWxpbWl0ZWQgbGlzdCBvZiBwcm9wZXJ0eSBuYW1lcyB0byByb3VuZFByb3BzLCBsaWtlIFwieCx5XCIsIHdlIHJvdW5kIHRvIHdob2xlIG51bWJlcnMuXG5cblxuICAgICAgICAgIHZhcnMgPSB0ZW1wO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1vZGlmaWVyKSB7XG4gICAgICAgICAgdGVtcCA9IHt9O1xuXG4gICAgICAgICAgZm9yIChwIGluIHZhcnMpIHtcbiAgICAgICAgICAgIHRlbXBbcF0gPSBtb2RpZmllcih2YXJzW3BdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXJzID0gdGVtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIF9hZGRNb2RpZmllcnModHdlZW4sIHZhcnMpO1xuICAgICAgfTtcbiAgICB9XG4gIH07XG59OyAvL3JlZ2lzdGVyIGNvcmUgcGx1Z2luc1xuXG5cbmV4cG9ydCB2YXIgZ3NhcCA9IF9nc2FwLnJlZ2lzdGVyUGx1Z2luKHtcbiAgbmFtZTogXCJhdHRyXCIsXG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQodGFyZ2V0LCB2YXJzLCB0d2VlbiwgaW5kZXgsIHRhcmdldHMpIHtcbiAgICB2YXIgcCwgcHQsIHY7XG4gICAgdGhpcy50d2VlbiA9IHR3ZWVuO1xuXG4gICAgZm9yIChwIGluIHZhcnMpIHtcbiAgICAgIHYgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKHApIHx8IFwiXCI7XG4gICAgICBwdCA9IHRoaXMuYWRkKHRhcmdldCwgXCJzZXRBdHRyaWJ1dGVcIiwgKHYgfHwgMCkgKyBcIlwiLCB2YXJzW3BdLCBpbmRleCwgdGFyZ2V0cywgMCwgMCwgcCk7XG4gICAgICBwdC5vcCA9IHA7XG4gICAgICBwdC5iID0gdjsgLy8gcmVjb3JkIHRoZSBiZWdpbm5pbmcgdmFsdWUgc28gd2UgY2FuIHJldmVydCgpXG5cbiAgICAgIHRoaXMuX3Byb3BzLnB1c2gocCk7XG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcihyYXRpbywgZGF0YSkge1xuICAgIHZhciBwdCA9IGRhdGEuX3B0O1xuXG4gICAgd2hpbGUgKHB0KSB7XG4gICAgICBfcmV2ZXJ0aW5nID8gcHQuc2V0KHB0LnQsIHB0LnAsIHB0LmIsIHB0KSA6IHB0LnIocmF0aW8sIHB0LmQpOyAvLyBpZiByZXZlcnRpbmcsIGdvIGJhY2sgdG8gdGhlIG9yaWdpbmFsIChwdC5iKVxuXG4gICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgIH1cbiAgfVxufSwge1xuICBuYW1lOiBcImVuZEFycmF5XCIsXG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQodGFyZ2V0LCB2YWx1ZSkge1xuICAgIHZhciBpID0gdmFsdWUubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdGhpcy5hZGQodGFyZ2V0LCBpLCB0YXJnZXRbaV0gfHwgMCwgdmFsdWVbaV0sIDAsIDAsIDAsIDAsIDAsIDEpO1xuICAgIH1cbiAgfVxufSwgX2J1aWxkTW9kaWZpZXJQbHVnaW4oXCJyb3VuZFByb3BzXCIsIF9yb3VuZE1vZGlmaWVyKSwgX2J1aWxkTW9kaWZpZXJQbHVnaW4oXCJtb2RpZmllcnNcIiksIF9idWlsZE1vZGlmaWVyUGx1Z2luKFwic25hcFwiLCBzbmFwKSkgfHwgX2dzYXA7IC8vdG8gcHJldmVudCB0aGUgY29yZSBwbHVnaW5zIGZyb20gYmVpbmcgZHJvcHBlZCB2aWEgYWdncmVzc2l2ZSB0cmVlIHNoYWtpbmcsIHdlIG11c3QgaW5jbHVkZSB0aGVtIGluIHRoZSB2YXJpYWJsZSBkZWNsYXJhdGlvbiBpbiB0aGlzIHdheS5cblxuVHdlZW4udmVyc2lvbiA9IFRpbWVsaW5lLnZlcnNpb24gPSBnc2FwLnZlcnNpb24gPSBcIjMuMTEuNVwiO1xuX2NvcmVSZWFkeSA9IDE7XG5fd2luZG93RXhpc3RzKCkgJiYgX3dha2UoKTtcbnZhciBQb3dlcjAgPSBfZWFzZU1hcC5Qb3dlcjAsXG4gICAgUG93ZXIxID0gX2Vhc2VNYXAuUG93ZXIxLFxuICAgIFBvd2VyMiA9IF9lYXNlTWFwLlBvd2VyMixcbiAgICBQb3dlcjMgPSBfZWFzZU1hcC5Qb3dlcjMsXG4gICAgUG93ZXI0ID0gX2Vhc2VNYXAuUG93ZXI0LFxuICAgIExpbmVhciA9IF9lYXNlTWFwLkxpbmVhcixcbiAgICBRdWFkID0gX2Vhc2VNYXAuUXVhZCxcbiAgICBDdWJpYyA9IF9lYXNlTWFwLkN1YmljLFxuICAgIFF1YXJ0ID0gX2Vhc2VNYXAuUXVhcnQsXG4gICAgUXVpbnQgPSBfZWFzZU1hcC5RdWludCxcbiAgICBTdHJvbmcgPSBfZWFzZU1hcC5TdHJvbmcsXG4gICAgRWxhc3RpYyA9IF9lYXNlTWFwLkVsYXN0aWMsXG4gICAgQmFjayA9IF9lYXNlTWFwLkJhY2ssXG4gICAgU3RlcHBlZEVhc2UgPSBfZWFzZU1hcC5TdGVwcGVkRWFzZSxcbiAgICBCb3VuY2UgPSBfZWFzZU1hcC5Cb3VuY2UsXG4gICAgU2luZSA9IF9lYXNlTWFwLlNpbmUsXG4gICAgRXhwbyA9IF9lYXNlTWFwLkV4cG8sXG4gICAgQ2lyYyA9IF9lYXNlTWFwLkNpcmM7XG5leHBvcnQgeyBQb3dlcjAsIFBvd2VyMSwgUG93ZXIyLCBQb3dlcjMsIFBvd2VyNCwgTGluZWFyLCBRdWFkLCBDdWJpYywgUXVhcnQsIFF1aW50LCBTdHJvbmcsIEVsYXN0aWMsIEJhY2ssIFN0ZXBwZWRFYXNlLCBCb3VuY2UsIFNpbmUsIEV4cG8sIENpcmMgfTtcbmV4cG9ydCB7IFR3ZWVuIGFzIFR3ZWVuTWF4LCBUd2VlbiBhcyBUd2VlbkxpdGUsIFRpbWVsaW5lIGFzIFRpbWVsaW5lTWF4LCBUaW1lbGluZSBhcyBUaW1lbGluZUxpdGUsIGdzYXAgYXMgZGVmYXVsdCwgd3JhcCwgd3JhcFlveW8sIGRpc3RyaWJ1dGUsIHJhbmRvbSwgc25hcCwgbm9ybWFsaXplLCBnZXRVbml0LCBjbGFtcCwgc3BsaXRDb2xvciwgdG9BcnJheSwgc2VsZWN0b3IsIG1hcFJhbmdlLCBwaXBlLCB1bml0aXplLCBpbnRlcnBvbGF0ZSwgc2h1ZmZsZSB9OyAvL2V4cG9ydCBzb21lIGludGVybmFsIG1ldGhvZHMvb3JvamVjdHMgZm9yIHVzZSBpbiBDU1NQbHVnaW4gc28gdGhhdCB3ZSBjYW4gZXh0ZXJuYWxpemUgdGhhdCBmaWxlIGFuZCBhbGxvdyBjdXN0b20gYnVpbGRzIHRoYXQgZXhjbHVkZSBpdC5cblxuZXhwb3J0IHsgX2dldFByb3BlcnR5LCBfbnVtRXhwLCBfbnVtV2l0aFVuaXRFeHAsIF9pc1N0cmluZywgX2lzVW5kZWZpbmVkLCBfcmVuZGVyQ29tcGxleFN0cmluZywgX3JlbEV4cCwgX3NldERlZmF1bHRzLCBfcmVtb3ZlTGlua2VkTGlzdEl0ZW0sIF9mb3JFYWNoTmFtZSwgX3NvcnRQcm9wVHdlZW5zQnlQcmlvcml0eSwgX2NvbG9yU3RyaW5nRmlsdGVyLCBfcmVwbGFjZVJhbmRvbSwgX2NoZWNrUGx1Z2luLCBfcGx1Z2lucywgX3RpY2tlciwgX2NvbmZpZywgX3JvdW5kTW9kaWZpZXIsIF9yb3VuZCwgX21pc3NpbmdQbHVnaW4sIF9nZXRTZXR0ZXIsIF9nZXRDYWNoZSwgX2NvbG9yRXhwLCBfcGFyc2VSZWxhdGl2ZSB9OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/gsap/gsap-core.js\n"); /***/ }), /***/ "./node_modules/gsap/index.js": /*!************************************!*\ !*** ./node_modules/gsap/index.js ***! \************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Back\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Back),\n/* harmony export */ \"Bounce\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Bounce),\n/* harmony export */ \"CSSPlugin\": () => (/* reexport safe */ _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__.CSSPlugin),\n/* harmony export */ \"Circ\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Circ),\n/* harmony export */ \"Cubic\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Cubic),\n/* harmony export */ \"Elastic\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Elastic),\n/* harmony export */ \"Expo\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Expo),\n/* harmony export */ \"Linear\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Linear),\n/* harmony export */ \"Power0\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power0),\n/* harmony export */ \"Power1\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power1),\n/* harmony export */ \"Power2\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power2),\n/* harmony export */ \"Power3\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power3),\n/* harmony export */ \"Power4\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power4),\n/* harmony export */ \"Quad\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quad),\n/* harmony export */ \"Quart\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quart),\n/* harmony export */ \"Quint\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quint),\n/* harmony export */ \"Sine\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Sine),\n/* harmony export */ \"SteppedEase\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.SteppedEase),\n/* harmony export */ \"Strong\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Strong),\n/* harmony export */ \"TimelineLite\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineLite),\n/* harmony export */ \"TimelineMax\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineMax),\n/* harmony export */ \"TweenLite\": () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TweenLite),\n/* harmony export */ \"TweenMax\": () => (/* binding */ TweenMaxWithCSS),\n/* harmony export */ \"default\": () => (/* binding */ gsapWithCSS),\n/* harmony export */ \"gsap\": () => (/* binding */ gsapWithCSS)\n/* harmony export */ });\n/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ \"./node_modules/gsap/gsap-core.js\");\n/* harmony import */ var _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CSSPlugin.js */ \"./node_modules/gsap/CSSPlugin.js\");\n\n\nvar gsapWithCSS = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(_CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__.CSSPlugin) || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap,\n // to protect from tree shaking\nTweenMaxWithCSS = gsapWithCSS.core.Tween;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZ3NhcC9pbmRleC5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBcU47QUFDMUs7QUFDM0Msa0JBQWtCLDhEQUFtQixDQUFDLG9EQUFTLEtBQUssK0NBQUk7QUFDeEQ7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL0B3ZWFyZWF0aGxvbi9mcm9udGVuZC13ZWJwYWNrLWJvaWxlcnBsYXRlLy4vbm9kZV9tb2R1bGVzL2dzYXAvaW5kZXguanM/Y2ZmYSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnc2FwLCBQb3dlcjAsIFBvd2VyMSwgUG93ZXIyLCBQb3dlcjMsIFBvd2VyNCwgTGluZWFyLCBRdWFkLCBDdWJpYywgUXVhcnQsIFF1aW50LCBTdHJvbmcsIEVsYXN0aWMsIEJhY2ssIFN0ZXBwZWRFYXNlLCBCb3VuY2UsIFNpbmUsIEV4cG8sIENpcmMsIFR3ZWVuTGl0ZSwgVGltZWxpbmVMaXRlLCBUaW1lbGluZU1heCB9IGZyb20gXCIuL2dzYXAtY29yZS5qc1wiO1xuaW1wb3J0IHsgQ1NTUGx1Z2luIH0gZnJvbSBcIi4vQ1NTUGx1Z2luLmpzXCI7XG52YXIgZ3NhcFdpdGhDU1MgPSBnc2FwLnJlZ2lzdGVyUGx1Z2luKENTU1BsdWdpbikgfHwgZ3NhcCxcbiAgICAvLyB0byBwcm90ZWN0IGZyb20gdHJlZSBzaGFraW5nXG5Ud2Vlbk1heFdpdGhDU1MgPSBnc2FwV2l0aENTUy5jb3JlLlR3ZWVuO1xuZXhwb3J0IHsgZ3NhcFdpdGhDU1MgYXMgZ3NhcCwgZ3NhcFdpdGhDU1MgYXMgZGVmYXVsdCwgQ1NTUGx1Z2luLCBUd2Vlbk1heFdpdGhDU1MgYXMgVHdlZW5NYXgsIFR3ZWVuTGl0ZSwgVGltZWxpbmVNYXgsIFRpbWVsaW5lTGl0ZSwgUG93ZXIwLCBQb3dlcjEsIFBvd2VyMiwgUG93ZXIzLCBQb3dlcjQsIExpbmVhciwgUXVhZCwgQ3ViaWMsIFF1YXJ0LCBRdWludCwgU3Ryb25nLCBFbGFzdGljLCBCYWNrLCBTdGVwcGVkRWFzZSwgQm91bmNlLCBTaW5lLCBFeHBvLCBDaXJjIH07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/gsap/index.js\n"); /***/ }), /***/ "./src/scss/app.scss": /*!***************************!*\ !*** ./src/scss/app.scss ***! \***************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvc2Nzcy9hcHAuc2Nzcy5qcyIsIm1hcHBpbmdzIjoiO0FBQUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ad2VhcmVhdGhsb24vZnJvbnRlbmQtd2VicGFjay1ib2lsZXJwbGF0ZS8uL3NyYy9zY3NzL2FwcC5zY3NzPzYyOWUiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQge307Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/scss/app.scss\n"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module can't be inlined because the eval-source-map devtool is used. /******/ var __webpack_exports__ = __webpack_require__("./src/js/app.js"); /******/ /******/ })() ;