vendor: 5,138 bytes, lines 1-76
1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { 40/******/ configurable: false, 41/******/ enumerable: true, 42/******/ get: getter 43/******/ }); 44/******/ } 45/******/ }; 46/******/ 47/******/ // getDefaultExport function for compatibility with non-harmony modules 48/******/ __webpack_require__.n = function(module) { 49/******/ var getter = module && module.__esModule ? 50/******/ function getDefault() { return module['default']; } : 51/******/ function getModuleExports() { return module; }; 52/******/ __webpack_require__.d(getter, 'a', getter); 53/******/ return getter; 54/******/ }; 55/******/ 56/******/ // Object.prototype.hasOwnProperty.call 57/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58/******/ 59/******/ // __webpack_public_path__ 60/******/ __webpack_require__.p = ""; 61/******/ 62/******/ // Load entry module and return exports 63/******/ return __webpack_require__(__webpack_require__.s = 0); 64/******/ }) 65/************************************************************************/ 66/******/ ([ 67/* 0 */ 68/*!********************!*\ 69 !*** ./src/app.js ***! 70 \********************/ 71/*! dynamic exports provided */ 72/*! all exports used */ 73/***/ (function(module, exports, __webpack_require__) { 74 75"use strict"; 76eval("\n\nvar _app = __webpack_require__(/*! ./app.scss */ 1);\n\nvar _app2 = _interopRequireDefault(_app);\n\n__webpack_require__(/*! ../node_modules/bxslider/dist/jquery.bxslider */ 2);\n\n__webpack_require__(/*! @fancyapps/fancybox */ 3);\n\n__webpack_require__(/*! swiper/swiper-bundle.css */ 4);\n\n__webpack_require__(/*! ./js/search.js */ 5);\n\n__webpack_require__(/*! ./js/megamenu */ 6);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// import \"./js/bootstrap.min.js\";\n// Load 3rd Party Javascript Files - From Node Modules\n//import 'bootstrap'; // Bootstrap Core JS is now loaded via CDN in header.ascx - Failed to load historically\nwindow.Noty = __webpack_require__(/*! noty */ 7);\n\n// import Swiper JS\n// This must be here to be read by Webpack\nwindow.Swiper = __webpack_require__(/*! ../node_modules/swiper/swiper-bundle */ 8);\n\n// import Swiper styles\n\n\n//Load Internal Files\n\n\n// jQuery Ready Function\n$(document).ready(function () {\n $('#search-menu').removeClass('toggled');\n $('#search-icon').click(function (e) {\n e.stopPropagation();\n $('#search-menu').toggleClass('toggled');\n $(\"#popup-search\").focus();\n });\n\n $('#search-menu input').click(function (e) {\n e.stopPropagation();\n });\n\n $('#search-menu, body').click(function () {\n $('#search-menu').removeClass('toggled');\n });\n $('#popup-search-button').click(function () {\n window.location.href = \"/Search-Results?Search=\" + document.getElementById(\"popup-search\").value;\n });\n $(\".bxslider\").bxSlider({\n mode: \"fade\"\n });\n //Enable Popover Functionality\n $(function () {\n $('[data-toggle=\"popover\"]').popover();\n });\n});\n\n// General - Example of Global Function\nwindow.MyFunction = function () {\n alert(\"Hello from my function\");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9zcmMvYXBwLmpzP2JkOWMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gIFRoaXMgbXVzdCBiZSBoZXJlIHRvIGJlIHJlYWQgYnkgV2VicGFja1xyXG5pbXBvcnQgY3NzIGZyb20gXCIuL2FwcC5zY3NzXCI7XHJcbi8vIGltcG9ydCBcIi4vanMvYm9vdHN0cmFwLm1pbi5qc1wiO1xyXG4vLyAgTG9hZCAzcmQgUGFydHkgSmF2YXNjcmlwdCBGaWxlcyAtIEZyb20gTm9kZSBNb2R1bGVzXHJcbi8vaW1wb3J0ICdib290c3RyYXAnOyAvLyBCb290c3RyYXAgQ29yZSBKUyBpcyBub3cgbG9hZGVkIHZpYSBDRE4gaW4gaGVhZGVyLmFzY3ggLSBGYWlsZWQgdG8gbG9hZCBoaXN0b3JpY2FsbHlcclxuaW1wb3J0IFwiLi4vbm9kZV9tb2R1bGVzL2J4c2xpZGVyL2Rpc3QvanF1
76ZXJ5LmJ4c2xpZGVyXCI7XHJcbmltcG9ydCBcIkBmYW5jeWFwcHMvZmFuY3lib3hcIjtcclxuXHJcbndpbmRvdy5Ob3R5ID0gcmVxdWlyZSgnbm90eScpO1xyXG5cclxuLy8gaW1wb3J0IFN3aXBlciBKU1xyXG53aW5kb3cuU3dpcGVyID0gcmVxdWlyZSgnLi4vbm9kZV9tb2R1bGVzL3N3aXBlci9zd2lwZXItYnVuZGxlJyk7XHJcblxyXG4vLyBpbXBvcnQgU3dpcGVyIHN0eWxlc1xyXG5pbXBvcnQgJ3N3aXBlci9zd2lwZXItYnVuZGxlLmNzcyc7XHJcblxyXG4vL0xvYWQgSW50ZXJuYWwgRmlsZXNcclxuaW1wb3J0IFwiLi9qcy9zZWFyY2guanNcIjtcclxuXHJcbmltcG9ydCBcIi4vanMvbWVnYW1lbnVcIjtcclxuXHJcblxyXG4vLyAgalF1ZXJ5IFJlYWR5IEZ1bmN0aW9uXHJcbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcclxuICAkKCcjc2VhcmNoLW1lbnUnKS5yZW1vdmVDbGFzcygndG9nZ2xlZCcpO1xyXG4gICAgJCgnI3NlYXJjaC1pY29uJykuY2xpY2soZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgJCgnI3NlYXJjaC1tZW51JykudG9nZ2xlQ2xhc3MoJ3RvZ2dsZWQnKTtcclxuICAgICAgICAkKFwiI3BvcHVwLXNlYXJjaFwiKS5mb2N1cygpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnI3NlYXJjaC1tZW51IGlucHV0JykuY2xpY2soZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCcjc2VhcmNoLW1lbnUsIGJvZHknKS5jbGljayhmdW5jdGlvbigpIHtcclxuICAgICAgICAkKCcjc2VhcmNoLW1lbnUnKS5yZW1vdmVDbGFzcygndG9nZ2xlZCcpO1xyXG4gICAgfSk7XHJcbiAgICAkKCcjcG9wdXAtc2VhcmNoLWJ1dHRvbicpLmNsaWNrKGZ1bmN0aW9uKCl7XHJcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gXCIvU2VhcmNoLVJlc3VsdHM/U2VhcmNoPVwiICsgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwb3B1cC1zZWFyY2hcIikudmFsdWU7XHJcbiAgICB9KTtcclxuICAkKFwiLmJ4c2xpZGVyXCIpLmJ4U2xpZGVyKHtcclxuICAgIG1vZGU6IFwiZmFkZVwiXHJcbiAgfSk7XHJcbiAgLy9FbmFibGUgUG9wb3ZlciBGdW5jdGlvbmFsaXR5XHJcbiAgJChmdW5jdGlvbiAoKSB7XHJcbiAgICAkKCdbZGF0YS10b2dnbGU9XCJwb3BvdmVyXCJdJykucG9wb3ZlcigpO1xyXG4gIH0pO1xyXG59KTtcclxuXHJcbi8vICBHZW5lcmFsIC0gRXhhbXBsZSBvZiBHbG9iYWwgRnVuY3Rpb25cclxud2luZG93Lk15RnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgYWxlcnQoXCJIZWxsbyBmcm9tIG15IGZ1bmN0aW9uXCIpO1xyXG59O1xuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBzcmMvYXBwLmpzIl0sIm1hcHBpbmdzIjoiOztBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBT0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFsQkE7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBVkE7QUFXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n"); 77 78/***/ }), 79/* 1 */ 80/*!**********************!*\ 81 !*** ./src/app.scss ***! 82 \**********************/ 83/*! dynamic exports provided */ 84/*! all exports used */ 85/***/ (function(module, exports) { 86 87eval("// removed by extract-text-webpack-plugin//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9hcHAuc2Nzcz83ODA0Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvYXBwLnNjc3Ncbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1\n"); 88 89/***/ }), 90/* 2 */ 91/*!*******************************************************!*\ 92 !*** ./node_modules/bxslider/dist/jquery.bxslider.js ***! 93 \*******************************************************/ 94/*! dynamic exports provided */ 95/*! all exports used */ 96/***/ (function(module, exports) { 97 98eval("/**\n * bxSlider v4.2.1d\n * Copyright 2013-2017 Steven Wanderski\n * Written while drinking Belgian ales and listening to jazz\n * Licensed under MIT (http://opensource.org/licenses/MIT)\n */\n\n;(function($) {\n\n var defaults = {\n\n // GENERAL\n mode: 'horizontal',\n slideSelector: '',\n infiniteLoop: true,\n hideControlOnEnd: false,\n speed: 500,\n easing: null,\n slideMargin: 0,\n startSlide: 0,\n randomStart: false,\n captions: false,\n ticker: false,\n tickerHover: false,\n adaptiveHeight: false,\n adaptiveHeightSpeed: 500,\n video: false,\n useCSS: true,\n preloadImages: 'visible',\n responsive: true,\n slideZIndex: 50,\n wrapperClass: 'bx-wrapper',\n\n // TOUCH\n touchEnabled: true,\n swipeThreshold: 50,\n oneToOneTouch: true,\n preventDefaultSwipeX: true,\n preventDefaultSwipeY: false,\n\n // ACCESSIBILITY\n ariaLive: true,\n ariaHidden: true,\n\n // KEYBOARD\n keyboardEnabled: false,\n\n // PAGER\n pager: true,\n pagerType: 'full',\n pagerShortSeparator: ' / ',\n pagerSelector: null,\n buildPager: null,\n pagerCustom: null,\n\n // CONTROLS\n controls: true,\n nextText: 'Next',\n prevText: 'Prev',\n nextSelector: null,\n prevSelector: null,\n autoControls: false,\n startText: 'Start',\n stopText: 'Stop',\n autoControlsCombine: false,\n autoControlsSelector: null,\n\n // AUTO\n auto: fal
98se,\n pause: 4000,\n autoStart: true,\n autoDirection: 'next',\n stopAutoOnClick: false,\n autoHover: false,\n autoDelay: 0,\n autoSlideForOnePage: false,\n\n // CAROUSEL\n minSlides: 1,\n maxSlides: 1,\n moveSlides: 0,\n slideWidth: 0,\n shrinkItems: false,\n\n // CALLBACKS\n onSliderLoad: function() { return true; },\n onSlideBefore: function() { return true; },\n onSlideAfter: function() { return true; },\n onSlideNext: function() { return true; },\n onSlidePrev: function() { return true; },\n onSliderResize: function() { return true; },\n\tonAutoChange: function() { return true; } //calls when auto slides starts and stops\n };\n\n $.fn.bxSlider = function(options) {\n\n if (this.length === 0) {\n return this;\n }\n\n // support multiple elements\n if (this.length > 1) {\n this.each(function() {\n $(this).bxSlider(options);\n });\n return this;\n }\n\n // create a namespace to be used throughout the plugin\n var slider = {},\n // set a reference to our slider element\n el = this,\n // get the original window dimens (thanks a lot IE)\n windowWidth = $(window).width(),\n windowHeight = $(window).height();\n\n // Return if slider is already initialized\n if ($(el).data('bxSlider')) { return; }\n\n /**\n * ===================================================================================\n * = PRIVATE FUNCTIONS\n * ===================================================================================\n */\n\n /**\n * Initializes namespace settings to be used throughout plugin\n */\n var init = function() {\n // Return if slider is already initialized\n if ($(el).data('bxSlider')) { return; }\n // merge user-supplied options with the defaults\n slider.settings = $.extend({}, defaults, options);\n // parse slideWidth setting\n slider.settings.slideWidth = parseInt(slider.settings.slideWidth);\n // store the original children\n slider.children = el.children(slider.settings.slideSelector);\n // check if actual number of slides is less than minSlides / maxSlides\n if (slider.children.length < slider.settings.minSlides) { slider.settings.minSlides = slider.children.length; }\n if (slider.children.length < slider.settings.maxSlides) { slider.settings.maxSlides = slider.children.length; }\n // if random start, set the startSlide setting to random number\n if (slider.settings.randomStart) { slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); }\n // store active slide information\n slider.active = { index: slider.settings.startSlide };\n // store if the slider is in carousel mode (displaying / moving multiple slides)\n slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;\n // if carousel, force preloadImages = 'all'\n if (slider.carousel) { slider.settings.preloadImages = 'all'; }\n // calculate the min / max width thresholds based on min / max number of slides\n // used to setup and update carousel slides dimensions\n slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);\n slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);\n // store the current state of the slider (if currently animating, working is true)\n slider.working = false;\n // initialize the controls object\n slider.controls = {};\n // initialize an auto interval\n slider.interval = null;\n // determine which property to use for transitions\n slider.animProp = slider.settings.mode === 'vertical' ? 'top' : 'left';\n // determine if hardware acceleration can be used\n slider.usingCSS = slider.settings.useCSS && slider.settings.mode !== 'fade' && (function() {\n // create our test div element\n var div = document.createElement('div'),\n // css transition properties\n props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];\n // test for each property\n for (var i = 0; i < props.length;
98 i++) {\n if (div.style[props[i]] !== undefined) {\n slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase();\n slider.animProp = '-' + slider.cssPrefix + '-transform';\n return true;\n }\n }\n return false;\n }());\n // if vertical mode always make maxSlides and minSlides equal\n if (slider.settings.mode === 'vertical') { slider.settings.maxSlides = slider.settings.minSlides; }\n // save original style data\n el.data('origStyle', el.attr('style'));\n el.children(slider.settings.slideSelector).each(function() {\n $(this).data('origStyle', $(this).attr('style'));\n });\n\n // perform all DOM / CSS modifications\n setup();\n };\n\n /**\n * Performs all DOM and CSS modifications\n */\n var setup = function() {\n var preloadSelector = slider.children.eq(slider.settings.startSlide); // set the default preload selector (visible)\n\n // wrap el in a wrapper\n el.wrap('<div class=\"' + slider.settings.wrapperClass + '\"><div class=\"bx-viewport\"></div></div>');\n // store a namespace reference to .bx-viewport\n slider.viewport = el.parent();\n\n // add aria-live if the setting is enabled and ticker mode is disabled\n if (slider.settings.ariaLive && !slider.settings.ticker) {\n slider.viewport.attr('aria-live', 'polite');\n }\n // add a loading div to display while images are loading\n slider.loader = $('<div class=\"bx-loading\" />');\n slider.viewport.prepend(slider.loader);\n // set el to a massive width, to hold any needed slides\n // also strip any margin and padding from el\n el.css({\n width: slider.settings.mode === 'horizontal' ? (slider.children.length * 1000 + 215) + '%' : 'auto',\n position: 'relative'\n });\n // if using CSS, add the easing property\n if (slider.usingCSS && slider.settings.easing) {\n el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing);\n // if not using CSS and no easing value was supplied, use the default JS animation easing (swing)\n } else if (!slider.settings.easing) {\n slider.settings.easing = 'swing';\n }\n // make modifications to the viewport (.bx-viewport)\n slider.viewport.css({\n width: '100%',\n overflow: 'hidden',\n position: 'relative'\n });\n slider.viewport.parent().css({\n maxWidth: getViewportMaxWidth()\n });\n // apply css to all slider children\n slider.children.css({\n // the float attribute is a reserved word in compressors like YUI compressor and need to be quoted #48\n 'float': slider.settings.mode === 'horizontal' ? 'left' : 'none',\n listStyle: 'none',\n position: 'relative'\n });\n // apply the calculated width after the float is applied to prevent scrollbar interference\n slider.children.css('width', getSlideWidth());\n // if slideMargin is supplied, add the css\n if (slider.settings.mode === 'horizontal' && slider.settings.slideMargin > 0) { slider.children.css('marginRight', slider.settings.slideMargin); }\n if (slider.settings.mode === 'vertical' && slider.settings.slideMargin > 0) { slider.children.css('marginBottom', slider.settings.slideMargin); }\n // if \"fade\" mode, add positioning and z-index CSS\n if (slider.settings.mode === 'fade') {\n slider.children.css({\n position: 'absolute',\n zIndex: 0,\n display: 'none'\n });\n // prepare the z-index on the showing element\n slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'});\n }\n // create an element to contain all slider controls (pager, start / stop, etc)\n slider.controls.el = $('<div class=\"bx-controls\" />');\n // if captions are requested, add them\n if (slider.settings.captions) { appendCaptions(); }\n // check if startSlide is last slide\n slider.active.last = slider.settings.startSlide === getPagerQty() - 1;\n // if video is true, set up the fitVids plugin\n if (slider.settings.video) { el.fitVids(); }\n\t //preloadImages\n\t if (slider.settings.preloadImages === 'none') { \n\t\t preloadSelector = null; \n\t }\n else if (slider.settings.preloadImages === 'all' || slider.settings.ticker) { \n\t\t preloadSelector = slider.children; \n\t }
98\n // only check for control addition if not in \"ticker\" mode\n if (!slider.settings.ticker) {\n // if controls are requested, add them\n if (slider.settings.controls) { appendControls(); }\n // if auto is true, and auto controls are requested, add them\n if (slider.settings.auto && slider.settings.autoControls) { appendControlsAuto(); }\n // if pager is requested, add it\n if (slider.settings.pager) { appendPager(); }\n // if any control option is requested, add the controls wrapper\n if (slider.settings.controls || slider.settings.autoControls || slider.settings.pager) { slider.viewport.after(slider.controls.el); }\n // if ticker mode, do not allow a pager\n } else {\n slider.settings.pager = false;\n }\n\t if (preloadSelector === null) {\n start();\n } else {\n loadElements(preloadSelector, start);\n }\n };\n\n var loadElements = function(selector, callback) {\n var total = selector.find('img:not([src=\"\"]), iframe').length,\n count = 0;\n if (total === 0) {\n callback();\n return;\n }\n selector.find('img:not([src=\"\"]), iframe').each(function() {\n $(this).one('load error', function() {\n if (++count === total) { callback(); }\n }).each(function() {\n if (this.complete || this.src == '') { $(this).trigger('load'); }\n });\n });\n };\n\n /**\n * Start the slider\n */\n var start = function() {\n // if infinite loop, prepare additional slides\n if (slider.settings.infiniteLoop && slider.settings.mode !== 'fade' && !slider.settings.ticker) {\n var slice = slider.settings.mode === 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides,\n sliceAppend = slider.children.slice(0, slice).clone(true).addClass('bx-clone'),\n slicePrepend = slider.children.slice(-slice).clone(true).addClass('bx-clone');\n if (slider.settings.ariaHidden) {\n sliceAppend.attr('aria-hidden', true);\n slicePrepend.attr('aria-hidden', true);\n }\n el.append(sliceAppend).prepend(slicePrepend);\n }\n // remove the loading DOM element\n slider.loader.remove();\n // set the left / top position of \"el\"\n setSlidePosition();\n // if \"vertical\" mode, always use adaptiveHeight to prevent odd behavior\n if (slider.settings.mode === 'vertical') { slider.settings.adaptiveHeight = true; }\n // set the viewport height\n slider.viewport.height(getViewportHeight());\n // make sure everything is positioned just right (same as a window resize)\n el.redrawSlider();\n // onSliderLoad callback\n slider.settings.onSliderLoad.call(el, slider.active.index);\n // slider has been fully initialized\n slider.initialized = true;\n // add the resize call to the window\n if (slider.settings.responsive) { $(window).on('resize', resizeWindow); }\n // if auto is true and has more than 1 page, start the show\n if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) { initAuto(); }\n // if ticker is true, start the ticker\n if (slider.settings.ticker) { initTicker(); }\n // if pager is requested, make the appropriate pager link active\n if (slider.settings.pager) { updatePagerActive(slider.settings.startSlide); }\n // check for any updates to the controls (like hideControlOnEnd updates)\n if (slider.settings.controls) { updateDirectionControls(); }\n // if touchEnabled is true, setup the touch events\n if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); }\n // if keyboardEnabled is true, setup the keyboard events\n if (slider.settings.keyboardEnabled && !slider.settings.ticker) {\n $(document).keydown(keyPress);\n }\n };\n\n /**\n * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value\n */\n var getViewportHe
98ight = function() {\n var height = 0;\n // first determine which children (slides) should be used in our height calculation\n var children = $();\n // if mode is not \"vertical\" and adaptiveHeight is false, include all children\n if (slider.settings.mode !== 'vertical' && !slider.settings.adaptiveHeight) {\n children = slider.children;\n } else {\n // if not carousel, return the single active child\n if (!slider.carousel) {\n children = slider.children.eq(slider.active.index);\n // if carousel, return a slice of children\n } else {\n // get the individual slide index\n var currentIndex = slider.settings.moveSlides === 1 ? slider.active.index : slider.active.index * getMoveBy();\n // add the current slide to the children\n children = slider.children.eq(currentIndex);\n // cycle through the remaining \"showing\" slides\n for (i = 1; i <= slider.settings.maxSlides - 1; i++) {\n // if looped back to the start\n if (currentIndex + i >= slider.children.length) {\n children = children.add(slider.children.eq(i - 1));\n } else {\n children = children.add(slider.children.eq(currentIndex + i));\n }\n }\n }\n }\n // if \"vertical\" mode, calculate the sum of the heights of the children\n if (slider.settings.mode === 'vertical') {\n children.each(function(index) {\n height += $(this).outerHeight();\n });\n // add user-supplied margins\n if (slider.settings.slideMargin > 0) {\n height += slider.settings.slideMargin * (slider.settings.minSlides - 1);\n }\n // if not \"vertical\" mode, calculate the max height of the children\n } else {\n height = Math.max.apply(Math, children.map(function() {\n return $(this).outerHeight(false);\n }).get());\n }\n\n if (slider.viewport.css('box-sizing') === 'border-box') {\n height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) +\n parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width'));\n } else if (slider.viewport.css('box-sizing') === 'padding-box') {\n height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom'));\n }\n\n return height;\n };\n\n /**\n * Returns the calculated width to be used for the outer wrapper / viewport\n */\n var getViewportMaxWidth = function() {\n var width = '100%';\n if (slider.settings.slideWidth > 0) {\n if (slider.settings.mode === 'horizontal') {\n width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);\n } else {\n width = slider.settings.slideWidth;\n }\n }\n return width;\n };\n\n /**\n * Returns the calculated width to be applied to each slide\n */\n var getSlideWidth = function() {\n var newElWidth = slider.settings.slideWidth, // start with any user-supplied slide width\n wrapWidth = slider.viewport.width(); // get the current viewport width\n // if slide width was not supplied, or is larger than the viewport use the viewport width\n if (slider.settings.slideWidth === 0 ||\n (slider.settings.slideWidth > wrapWidth && !slider.carousel) ||\n slider.settings.mode === 'vertical') {\n newElWidth = wrapWidth;\n // if carousel, use the thresholds to determine the width\n } else if (slider.settings.maxSlides > 1 && slider.settings.mode === 'horizontal') {\n if (wrapWidth > slider.maxThreshold) {\n return newElWidth;\n } else if (wrapWidth < slider.minThreshold) {\n newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;\n } else if (slider.settings.shrinkItems) {\n newElWidth = Math.floor((wrapWidth + slider.settings.slideMargin) / (Math.ceil((wrapWidth + slider.settings.slideMargin) / (newElWidth + slider.settings.slideMargin))) - slider.settings.slideMargin);\n }\n }\n return newElWidth;\n };\n\n /**\n * Returns the number of slides currently visible in the viewport (includes partially visible slides)\n */\n var getNumberSlidesShowing = function() {\
98n var slidesShowing = 1,\n childWidth = null;\n if (slider.settings.mode === 'horizontal' && slider.settings.slideWidth > 0) {\n // if viewport is smaller than minThreshold, return minSlides\n if (slider.viewport.width() < slider.minThreshold) {\n slidesShowing = slider.settings.minSlides;\n // if viewport is larger than maxThreshold, return maxSlides\n } else if (slider.viewport.width() > slider.maxThreshold) {\n slidesShowing = slider.settings.maxSlides;\n // if viewport is between min / max thresholds, divide viewport width by first child width\n } else {\n childWidth = slider.children.first().width() + slider.settings.slideMargin;\n slidesShowing = Math.floor((slider.viewport.width() +\n slider.settings.slideMargin) / childWidth) || 1;\n }\n // if \"vertical\" mode, slides showing will always be minSlides\n } else if (slider.settings.mode === 'vertical') {\n slidesShowing = slider.settings.minSlides;\n }\n return slidesShowing;\n };\n\n /**\n * Returns the number of pages (one full viewport of slides is one \"page\")\n */\n var getPagerQty = function() {\n var pagerQty = 0,\n breakPoint = 0,\n counter = 0;\n // if moveSlides is specified by the user\n if (slider.settings.moveSlides > 0) {\n if (slider.settings.infiniteLoop) {\n pagerQty = Math.ceil(slider.children.length / getMoveBy());\n } else {\n // when breakpoint goes above children length, counter is the number of pages\n while (breakPoint < slider.children.length) {\n ++pagerQty;\n breakPoint = counter + getNumberSlidesShowing();\n counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();\n }\n\t\t return counter;\n }\n // if moveSlides is 0 (auto) divide children length by sides showing, then round up\n } else {\n pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());\n }\n return pagerQty;\n };\n\n /**\n * Returns the number of individual slides by which to shift the slider\n */\n var getMoveBy = function() {\n // if moveSlides was set by the user and moveSlides is less than number of slides showing\n if (slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()) {\n return slider.settings.moveSlides;\n }\n // if moveSlides is 0 (auto)\n return getNumberSlidesShowing();\n };\n\n /**\n * Sets the slider's (el) left or top position\n */\n var setSlidePosition = function() {\n var position, lastChild, lastShowingIndex;\n // if last slide, not infinite loop, and number of children is larger than specified maxSlides\n if (slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop) {\n if (slider.settings.mode === 'horizontal') {\n // get the last child's position\n lastChild = slider.children.last();\n position = lastChild.position();\n // set the left position\n setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0);\n } else if (slider.settings.mode === 'vertical') {\n // get the last showing index's position\n lastShowingIndex = slider.children.length - slider.settings.minSlides;\n position = slider.children.eq(lastShowingIndex).position();\n // set the top position\n setPositionProperty(-position.top, 'reset', 0);\n }\n // if not last slide\n } else {\n // get the position of the first showing slide\n position = slider.children.eq(slider.active.index * getMoveBy()).position();\n // check for last slide\n if (slider.active.index === getPagerQty() - 1) { slider.active.last = true; }\n // set the respective position\n if (position !== undefined) {\n if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }\n else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); }\n }\n }\n };\n\n /**\n * Sets the el's animating property position (which in turn will sometimes animate el).\n * If using CSS, sets the transform property. If not using CSS, sets the top / left property.\n *\n * @param value (int)\n * - the animating property's value\n *\n * @param type (string) 'slide', 'reset', 'ticker'\n * - the type of instance for which the function is being\n *\n * @param duration (int)\n * - the amount of time (in ms) the transition should occupy\n *\n * @param params (array) optional\n * - an optional parameter containing any variables that need to be passed in\n */\n var setPositionProperty = function(value, type, duration, params) {\n var animateObj, propValue;\n // use CSS transform\n if (slider.usingCSS) {\n // determine the translate3d value\
98n propValue = slider.settings.mode === 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)';\n // add the CSS transition-duration\n el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's');\n if (type === 'slide') {\n // set the property value\n el.css(slider.animProp, propValue);\n if (duration !== 0) {\n // add a callback method - executes when CSS transition completes\n el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) {\n //make sure it's the correct one\n if (!$(e.target).is(el)) { return; }\n // remove the callback\n el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');\n updateAfterSlideTransition();\n });\n } else { //duration = 0\n updateAfterSlideTransition();\n }\n } else if (type === 'reset') {\n el.css(slider.animProp, propValue);\n } else if (type === 'ticker') {\n // make the transition use 'linear'\n el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear');\n el.css(slider.animProp, propValue);\n if (duration !== 0) {\n el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) {\n //make sure it's the correct one\n if (!$(e.target).is(el)) { return; }\n // remove the callback\n el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');\n // reset the position\n setPositionProperty(params.resetValue, 'reset', 0);\n // start the loop again\n tickerLoop();\n });\n } else { //duration = 0\n setPositionProperty(params.resetValue, 'reset', 0);\n tickerLoop();\n }\n }\n // use JS animate\n } else {\n animateObj = {};\n animateObj[slider.animProp] = value;\n if (type === 'slide') {\n el.animate(animateObj, duration, slider.settings.easing, function() {\n updateAfterSlideTransition();\n });\n } else if (type === 'reset') {\n el.css(slider.animProp, value);\n } else if (type === 'ticker') {\n el.animate(animateObj, duration, 'linear', function() {\n setPositionProperty(params.resetValue, 'reset', 0);\n // run the recursive loop after animation\n tickerLoop();\n });\n }\n }\n };\n\n /**\n * Populates the pager with proper amount of pages\n */\n var populatePager = function() {\n var pagerHtml = '',\n linkContent = '',\n pagerQty = getPagerQty();\n // loop through each pager item\n for (var i = 0; i < pagerQty; i++) {\n linkContent = '';\n // if a buildPager function is supplied, use it to get pager link value, else use index + 1\n if (slider.settings.buildPager && $.isFunction(slider.settings.buildPager) || slider.settings.pagerCustom) {\n linkContent = slider.settings.buildPager(i);\n slider.pagerEl.addClass('bx-custom-pager');\n } else {\n linkContent = i + 1;\n slider.pagerEl.addClass('bx-default-pager');\n }\n // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;\n // add the markup to the string\n pagerHtml += '<div class=\"bx-pager-item\"><a href=\"\" data-slide-index=\"' + i + '\" class=\"bx-pager-link\">' + linkContent + '</a></div>';\n }\n // populate the pager element with pager links\n slider.pagerEl.html(pagerHtml);\n };\n\n /**\n * Appends the pager to the controls element\n */\n var appendPager = function() {\n if (!slider.settings.pagerCustom) {\n // create the pager DOM element\n slider.pagerEl = $('<div class=\"bx-pager\" />');\n // if a pager selector was supplied, populate it with the pager\n if (slider.settings.pagerSelector) {\n $(slider.settings.pagerSelector).html(slider.pagerEl);\n // if no pager selector was supplied, add it after the wrapper\n } else {\n slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);\n }\n // populate the pager\n populatePager();\n } else {\n slider.pagerEl = $(slider.settings.pagerCustom);\n }\n // assign the pager click binding\n slider.pagerEl.on('click touchend', 'a', clickPagerBind);\n };\n\n /**\n * Appends prev / next controls to the controls element\n */\n var appendControl
98s = function() {\n slider.controls.next = $('<a class=\"bx-next\" href=\"\">' + slider.settings.nextText + '</a>');\n slider.controls.prev = $('<a class=\"bx-prev\" href=\"\">' + slider.settings.prevText + '</a>');\n // add click actions to the controls\n slider.controls.next.on('click touchend', clickNextBind);\n slider.controls.prev.on('click touchend', clickPrevBind);\n // if nextSelector was supplied, populate it\n if (slider.settings.nextSelector) {\n $(slider.settings.nextSelector).append(slider.controls.next);\n }\n // if prevSelector was supplied, populate it\n if (slider.settings.prevSelector) {\n $(slider.settings.prevSelector).append(slider.controls.prev);\n }\n // if no custom selectors were supplied\n if (!slider.settings.nextSelector && !slider.settings.prevSelector) {\n // add the controls to the DOM\n slider.controls.directionEl = $('<div class=\"bx-controls-direction\" />');\n // add the control elements to the directionEl\n slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);\n // slider.viewport.append(slider.controls.directionEl);\n slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);\n }\n };\n\n /**\n * Appends start / stop auto controls to the controls element\n */\n var appendControlsAuto = function() {\n slider.controls.start = $('<div class=\"bx-controls-auto-item\"><a class=\"bx-start\" href=\"\">' + slider.settings.startText + '</a></div>');\n slider.controls.stop = $('<div class=\"bx-controls-auto-item\"><a class=\"bx-stop\" href=\"\">' + slider.settings.stopText + '</a></div>');\n // add the controls to the DOM\n slider.controls.autoEl = $('<div class=\"bx-controls-auto\" />');\n // on click actions to the controls\n slider.controls.autoEl.on('click', '.bx-start', clickStartBind);\n slider.controls.autoEl.on('click', '.bx-stop', clickStopBind);\n // if autoControlsCombine, insert only the \"start\" control\n if (slider.settings.autoControlsCombine) {\n slider.controls.autoEl.append(slider.controls.start);\n // if autoControlsCombine is false, insert both controls\n } else {\n slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);\n }\n // if auto controls selector was supplied, populate it with the controls\n if (slider.settings.autoControlsSelector) {\n $(slider.settings.autoControlsSelector).html(slider.controls.autoEl);\n // if auto controls selector was not supplied, add it after the wrapper\n } else {\n slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);\n }\n // update the auto controls\n updateAutoControls(sli
98der.settings.autoStart ? 'stop' : 'start');\n };\n\n /**\n * Appends image captions to the DOM\n */\n var appendCaptions = function() {\n // cycle through each child\n slider.children.each(function(index) {\n // get the image title attribute\n var title = $(this).find('img:first').attr('title');\n // append the caption\n if (title !== undefined && ('' + title).length) {\n $(this).append('<div class=\"bx-caption\"><span>' + title + '</span></div>');\n }\n });\n };\n\n /**\n * Click next binding\n *\n * @param e (event)\n * - DOM event object\n */\n var clickNextBind = function(e) {\n e.preventDefault();\n if (slider.controls.el.hasClass('disabled')) { return; }\n // if auto show is running, stop it\n if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }\n el.goToNextSlide();\n };\n\n /**\n * Click prev binding\n *\n * @param e (event)\n * - DOM event object\n */\n var clickPrevBind = function(e) {\n e.preventDefault();\n if (slider.controls.el.hasClass('disabled')) { return; }\n // if auto show is running, stop it\n if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }\n el.goToPrevSlide();\n };\n\n /**\n * Click start binding\n *\n * @param e (event)\n * - DOM event object\n */\n var clickStartBind = function(e) {\n el.startAuto();\n e.preventDefault();\n };\n\n /**\n * Click stop binding\n *\n * @param e (event)\n * - DOM event object\n */\n var clickStopBind = function(e) {\n el.stopAuto();\n e.preventDefault();\n };\n\n /**\n * Click pager binding\n *\n * @param e (event)\n * - DOM event object\n */\n var clickPagerBind = function(e) {\n var pagerLink, pagerIndex;\n e.preventDefault();\n if (slider.controls.el.hasClass('disabled')) {\n return;\n }\n // if auto show is running, stop it\n if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }\n pagerLink = $(e.currentTarget);\n if (pagerLink.attr('data-slide-index') !== undefined) {\n pagerIndex = parseInt(pagerLink.attr('data-slide-index'));\n // if clicked pager link is not active, continue with the goToSlide call\n if (pagerIndex !== slider.active.index) { el.goToSlide(pagerIndex); }\n }\n };\n\n /**\n * Updates the pager links with an active class\n *\n * @param slideIndex (int)\n * - index of slide to make active\n */\n var updatePagerActive = function(slideIndex) {\n // if \"short\" pager type\n var len = slider.children.length; // nb of children\n if (slider.settings.pagerType === 'short') {\n if (slider.settings.maxSlides > 1) {\n len = Math.ceil(slider.children.length / slider.settings.maxSlides);\n }\n slider.pagerEl.html((slideIndex + 1) + slider.settings.pagerShortSeparator + len);\n return;\n }\n // remove all pager active classes\n slider.pagerEl.find('a').removeClass('active');\n // apply the active class for all pagers\n slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); });\n };\n\n /**\n * Performs needed actions after a slide transition\n */\n var updateAfterSlideTransition = function() {\n // if infinite loop is true\n if (slider.settings.infiniteLoop) {\n var position = '';\n // first slide\n if (slider.active.index === 0) {\n // set the new position\n position = slider.children.eq(0).position();\n // carousel, last slide\n } else if (slider.active.index === getPagerQty() - 1 && slider.carousel) {\n position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position();\n // last slide\n } else if (slider.active.index === slider.children.length - 1) {\n position = slider.children.eq(slider.children.length - 1).position();\n }\n if (position) {\n if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }\n else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); }\n }\n }\n // declare that the transition is complete\n slider.working = false;\n // onSlideAfter callback\n slider.settings.onSlideAfter.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);\n };\n\n /**\n * Updates the auto controls state (either active, or combined switch)\n *\n * @param state (string) \"start\", \"stop\"\n * - the new state of the auto show\n */\n var updateAutoControls = function(state) {\n // if autoControlsCombine is true, replace the current control with the new state\n if (slider.settings.autoControlsCombine) {\n slider.controls.autoEl.html(slider.controls[state]);\n // if autoControlsCombine is false, apply the \"active\" class to the appropriate control\n } else {\n slider.controls.autoEl.find('a').removeClass('active');
98\n slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');\n }\n };\n\n /**\n * Updates the direction controls (checks if either should be hidden)\n */\n var updateDirectionControls = function() {\n if (getPagerQty() === 1) {\n slider.controls.prev.addClass('disabled');\n slider.controls.next.addClass('disabled');\n } else if (!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd) {\n // if first slide\n if (slider.active.index === 0) {\n slider.controls.prev.addClass('disabled');\n slider.controls.next.removeClass('disabled');\n // if last slide\n } else if (slider.active.index === getPagerQty() - 1) {\n slider.controls.next.addClass('disabled');\n slider.controls.prev.removeClass('disabled');\n // if any slide in the middle\n } else {\n slider.controls.prev.removeClass('disabled');\n slider.controls.next.removeClass('disabled');\n }\n }\n };\n\t/* auto start and stop functions */\n\tvar windowFocusHandler = function() { el.startAuto(); };\n\tvar windowBlurHandler = function() { el.stopAuto(); };\n /**\n * Initializes the auto process\n */\n var initAuto = function() {\n // if autoDelay was supplied, launch the auto show using a setTimeout() call\n if (slider.settings.autoDelay > 0) {\n setTimeout(el.startAuto, slider.settings.autoDelay);\n // if autoDelay was not supplied, start the auto show normally\n } else {\n el.startAuto();\n\n //add focus and blur events to ensure its running if timeout gets paused\n $(window).focus(windowFocusHandler).blur(windowBlurHandler);\n }\n // if autoHover is requested\n if (slider.settings.autoHover) {\n // on el hover\n el.hover(function() {\n // if the auto show is currently playing (has an active interval)\n if (slider.interval) {\n // stop the auto show and pass true argument which will prevent control update\n el.stopAuto(true);\n // create a new autoPaused value which will be used by the relative \"mouseout\" event\n slider.autoPaused = true;\n }\n }, function() {\n // if the autoPaused value was created be the prior \"mouseover\" event\n if (slider.autoPaused) {\n // start the auto show and pass true argument which will prevent control update\n el.startAuto(true);\n // reset the autoPaused value\n slider.autoPaused = null;\n }\n });\n }\n };\n\n /**\n * Initializes the ticker process\n */\n var initTicker = function() {\n var startPosition = 0,\n position, transform, value, idx, ratio, property, newSpeed, totalDimens;\n // if autoDirection is \"next\", append a clone of the entire slider\n if (slider.settings.autoDirection === 'next') {\n el.append(slider.children.clone().addClass('bx-clone'));\n // if autoDirection is \"prev\", prepend a clone of the entire slider, and set the left position\n } else {\n el.prepend(slider.children.clone().addClass('bx-clone'));\n position = slider.children.first().position();\n startPosition = slider.settings.mode === 'horizontal' ? -position.left : -position.top;\n }\n setPositionProperty(startPosition, 'reset', 0);\n // do not allow controls in ticker mode\n slider.settings.pager = false;\n slider.settings.controls = false;\n slider.settings.autoControls = false;\n // if autoHover is requested\n if (slider.settings.tickerHover) {\n if (slider.usingCSS) {\n idx = slider.settings.mode === 'horizontal' ? 4 : 5;\n slider.viewport.hover(function() {\n transform = el.css('-' + slider.cssPrefix + '-transform');\n value = parseFloat(transform.split(',')[idx]);\n setPositionProperty(value, 'reset', 0);\n }, function() {\n totalDimens = 0;\n slider.children.each(function(index) {\n totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);\n });\n // calculate the speed ratio (used to determine the new speed to finish the paused animation)\n ratio = slider.settings.speed / totalDimens;\n // determine which property to use\n property = slider.settings.mode === 'horizontal' ? 'left' : 'top';\n // calculate the new speed\n newSpeed = ratio * (totalDimens - (Math.abs(parseInt(value))));\n tickerLoop(newSpeed);\n });\n } else {\n // on el hover\n slider.viewport.hover(function() {\
98n el.stop();\n }, function() {\n // calculate the total width of children (used to calculate the speed ratio)\n totalDimens = 0;\n slider.children.each(function(index) {\n totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);\n });\n // calculate the speed ratio (used to determine the new speed to finish the paused animation)\n ratio = slider.settings.speed / totalDimens;\n // determine which property to use\n property = slider.settings.mode === 'horizontal' ? 'left' : 'top';\n // calculate the new speed\n newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));\n tickerLoop(newSpeed);\n });\n }\n }\n // start the ticker loop\n tickerLoop();\n };\n\n /**\n * Runs a continuous loop, news ticker-style\n */\n var tickerLoop = function(resumeSpeed) {\n var speed = resumeSpeed ? resumeSpeed : slider.settings.speed,\n position = {left: 0, top: 0},\n reset = {left: 0, top: 0},\n animateProperty, resetValue, params;\n\n // if \"next\" animate left position to last child, then reset left to 0\n if (slider.settings.autoDirection === 'next') {\n position = el.find('.bx-clone').first().position();\n // if \"prev\" animate left position to 0, then reset left to first non-clone child\n } else {\n reset = slider.children.first().position();\n }\n animateProperty = slider.settings.mode === 'horizontal' ? -position.left : -position.top;\n resetValue = slider.settings.mode === 'horizontal' ? -reset.left : -reset.top;\n params = {resetValue: resetValue};\n setPositionProperty(animateProperty, 'ticker', speed, params);\n };\n\n /**\n * Check if el is on screen\n */\n var isOnScreen = function(el) {\n var win = $(window),\n viewport = {\n top: win.scrollTop(),\n left: win.scrollLeft()\n },\n bounds = el.offset();\n\n viewport.right = viewport.left + win.width();\n viewport.bottom = viewport.top + win.height();\n bounds.right = bounds.left + el.outerWidth();\n bounds.bottom = bounds.top + el.outerHeight();\n\n return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));\n };\n\n /**\n * Initializes keyboard events\n */\n var keyPress = function(e) {\n var activeElementTag = document.activeElement.tagName.toLowerCase(),\n tagFilters = 'input|textarea',\n p = new RegExp(activeElementTag,['i']),\n result = p.exec(tagFilters);\n\n if (result == null && isOnScreen(el)) {\n if (e.keyCode === 39) {\n clickNextBind(e);\n return false;\n } else if (e.keyCode === 37) {\n clickPrevBind(e);\n return false;\n }\n }\n };\n\n /**\n * Initializes touch events\n */\n var initTouch = function() {\n // initialize object to contain all touch values\n slider.touch = {\n start: {x: 0, y: 0},\n end: {x: 0, y: 0}\n };\n slider.viewport.on('touchstart MSPointerDown pointerdown', onTouchStart);\n\n //for browsers that have implemented pointer events and fire a click after\n //every pointerup regardless of whether pointerup is on same screen location as pointerdown or not\n slider.viewport.on('click', '.bxslider a', function(e) {\n if (slider.viewport.hasClass('click-disabled')) {\n e.preventDefault();\n slider.viewport.removeClass('click-disabled');\n }\n });\n };\n\n /**\n * Event handler for \"touchstart\"\n *\n * @param e (event)\n * - DOM event object\n */\n var onTouchStart = function(e) {\n // watch only for left mouse, touch contact and pen contact\n // touchstart event object doesn`t have button property\n if (e.type !== 'touchstart' && e.button !== 0) {\n return;\n }\n e.preventDefault();\n //disable slider controls while user is interacting with slides to avoid slider freeze that happens on touch devices when a slide swipe happens immediately after interacting with slider controls\n slider.controls.el.addClass('disabled');\n\n if (slider.working) {\n slider.controls.el.removeClass('disabled');\n } else {\n // record the original position when touch starts\n slider.touch.originalPos = el.position();\n var orig = e.originalEvent,\n touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig];\n\t\tvar chromePointerEvents = typeof PointerEvent === 'function'; \n\t\tif (chromePointerEvents) { \n\t\t\tif (orig.pointerId === undefined) { \n\t\t\t\treturn;\n\t\t\t} \n\t\t}\n // record the starting touch x, y coordinates\n slider.touch.start.x
98= touchPoints[0].pageX;\n slider.touch.start.y = touchPoints[0].pageY;\n\n if (slider.viewport.get(0).setPointerCapture) {\n slider.pointerId = orig.pointerId;\n slider.viewport.get(0).setPointerCapture(slider.pointerId);\n }\n // store original event data for click fixation\n slider.originalClickTarget = orig.originalTarget || orig.target;\n slider.originalClickButton = orig.button;\n slider.originalClickButtons = orig.buttons;\n slider.originalEventType = orig.type;\n // at this moment we don`t know what it is click or swipe\n slider.hasMove = false;\n // on a \"touchmove\" event to the viewport\n slider.viewport.on('touchmove MSPointerMove pointermove', onTouchMove);\n // on a \"touchend\" event to the viewport\n slider.viewport.on('touchend MSPointerUp pointerup', onTouchEnd);\n slider.viewport.on('MSPointerCancel pointercancel', onPointerCancel);\n }\n };\n\n /**\n * Cancel Pointer for Windows Phone\n *\n * @param e (event)\n * - DOM event object\n */\n var onPointerCancel = function(e) {\n e.preventDefault();\n /* onPointerCancel handler is needed to deal with situations when a touchend\n doesn't fire after a touchstart (this happens on windows phones only) */\n setPositionProperty(slider.touch.originalPos.left, 'reset', 0);\n\n //remove handlers\n slider.controls.el.removeClass('disabled');\n slider.viewport.off('MSPointerCancel pointercancel', onPointerCancel);\n slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove);\n slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd);\n if (slider.viewport.get(0).releasePointerCapture) {\n slider.viewport.get(0).releasePointerCapture(slider.pointerId);\n }\n };\n\n /**\n * Event handler for \"touchmove\"\n *\n * @param e (event)\n * - DOM event object\n */\n var onTouchMove = function(e) {\n var orig = e.originalEvent,\n touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig],\n // if scrolling on y axis, do not prevent default\n xMovement = Math.abs(touchPoints[0].pageX - slider.touch.start.x),\n yMovement = Math.abs(touchPoints[0].pageY - slider.touch.start.y),\n value = 0,\n change = 0;\n // this is swipe\n slider.hasMove = true;\n\n // x axis swipe\n if ((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX) {\n e.preventDefault();\n // y axis swipe\n } else if ((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY) {\n e.preventDefault();\n }\n if (e.type !== 'touchmove') {\n e.preventDefault();\n }\n\n if (slider.settings.mode !== 'fade' && slider.settings.oneToOneTouch) {\n // if horizontal, drag along x axis\n if (slider.settings.mode === 'horizontal') {\n change = touchPoints[0].pageX - slider.touch.start.x;\n value = slider.touch.originalPos.left + change;\n // if vertical, drag along y axis\n } else {\n change = touchPoints[0].pageY - slider.touch.start.y;\n value = slider.touch.originalPos.top + change;\n }\n setPositionProperty(value, 'reset', 0);\n }\n };\n\n /**\n * Event handler for \"touchend\"\n *\n * @param e (event)\n * - DOM event object\n */\n var onTouchEnd = function(e) {\n e.preventDefault();\n slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove);\n //enable slider controls as soon as user stops interacing with slides\n slider.controls.el.removeClass('disabled');\n var orig = e.originalEvent,\n touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig],\n value = 0,\n distance = 0;\n // record end x, y positions\n slider.touch.end.x = touchPoints[0].pageX;\n slider.touch.end.y = touchPoints[0].pageY;\n // if fade mode, check if absolute x distance clears the threshold\n if (slider.settings.mode === 'fade') {\n distance = Math.abs(slider.touch.start.x - slider.touch.end.x);\n if (distance >= slider.settings.swipeThreshold) {\n if (slider.touch.start.x >
98 slider.touch.end.x) {\n el.goToNextSlide();\n } else {\n el.goToPrevSlide();\n }\n el.stopAuto();\n }\n // not fade mode\n } else {\n // calculate distance and el's animate property\n if (slider.settings.mode === 'horizontal') {\n distance = slider.touch.end.x - slider.touch.start.x;\n value = slider.touch.originalPos.left;\n } else {\n distance = slider.touch.end.y - slider.touch.start.y;\n value = slider.touch.originalPos.top;\n }\n // if not infinite loop and first / last slide, do not attempt a slide transition\n if (!slider.settings.infiniteLoop && ((slider.active.index === 0 && distance > 0) || (slider.active.last && distance < 0))) {\n setPositionProperty(value, 'reset', 200);\n } else {\n // check if distance clears threshold\n if (Math.abs(distance) >= slider.settings.swipeThreshold) {\n if (distance < 0) {\n el.goToNextSlide();\n } else {\n el.goToPrevSlide();\n }\n el.stopAuto();\n } else {\n // el.animate(property, 200);\n setPositionProperty(value, 'reset', 200);\n }\n }\n }\n slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd);\n\n if (slider.viewport.get(0).releasePointerCapture) {\n slider.viewport.get(0).releasePointerCapture(slider.pointerId);\n }\n // if slider had swipe with left mouse, touch contact and pen contact\n if (slider.hasMove === false && (slider.originalClickButton === 0 || slider.originalEventType === 'touchstart')) {\n // trigger click event (fix for Firefox59 and PointerEvent standard compatibility)\n $(slider.originalClickTarget).trigger({\n type: 'click',\n button: slider.originalClickButton,\n buttons: slider.originalClickButtons\n });\n }\n };\n\n /**\n * Window resize event callback\n */\n var resizeWindow = function(e) {\n // don't do anything if slider isn't initialized.\n if (!slider.initialized) { return; }\n // Delay if slider working.\n if (slider.working) {\n window.setTimeout(resizeWindow, 10);\n } else {\n // get the new window dimens (again, thank you IE)\n var windowWidthNew = $(window).width(),\n windowHeightNew = $(window).height();\n // make sure that it is a true window resize\n // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements\n // are resized. Can you just die already?*\n if (windowWidth !== windowWidthNew || windowHeight !== windowHeightNew) {\n // set the new window dimens\n windowWidth = windowWidthNew;\n windowHeight = windowHeightNew;\n // update all dynamic elements\n el.redrawSlider();\n // Call user resize handler\n slider.settings.onSliderResize.call(el, slider.active.index);\n }\n }\n };\n\n /**\n * Adds an aria-hidden=true attribute to each element\n *\n * @param startVisibleIndex (int)\n * - the first visible element's index\n */\n var applyAriaHiddenAttributes = function(startVisibleIndex) {\n var numberOfSlidesShowing = getNumberSlidesShowing();\n // only apply attributes if the setting is enabled and not in ticker mode\n if (slider.settings.ariaHidden && !slider.settings.ticker) {\n // add aria-hidden=true to all elements\n slider.children.attr('aria-hidden', 'true');\n // get the visible elements and change to aria-hidden=false\n slider.children.slice(startVisibleIndex, startVisibleIndex + numberOfSlidesShowing).attr('aria-hidden', 'false');\n }\n };\n\n /**\n * Returns index according to present page range\n *\n * @param slideOndex (int)\n * - the desired slide index\n */\n var setSlideIndex = function(slideIndex) {\n if (slideIndex < 0) {\n if (slider.settings.infiniteLoop) {\n return getPagerQty() - 1;\n }else {\n //we don't go to undefined slides\n return slider.active.index;\n }\n // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)\n } else if (slideIndex >= getPagerQty()) {\n if (slider.settings.infiniteLoop) {\n return 0;\n } else {\n //we don't move to undefined pages\n return slider.active.index;\n }\n // set active index to requested slide\n } else {\n return slideIndex;\n }\n };\n\n /**\n * ===================================================================================\n * = PUBLIC FUNCTIONS\n * ===================================================================================\n */\n\n /**\n * Performs slide transition to the specified slide\n *\n * @param slideIndex (int)\n * - the destination slide's index (zero-based)\n *\n * @param direction (string)\n * - INTERNAL USE ONLY - the direction of travel (\"prev\" / \"next\")\n */\n el.goToSlide = function(slideIndex, direction) {\n // onSlideBefore, onSlideNext, onSlidePrev callbacks\n // Allow transition canceling based on returned value\
98n var performTransition = true,\n moveBy = 0,\n position = {left: 0, top: 0},\n lastChild = null,\n lastShowingIndex, eq, value, requestEl;\n // store the old index\n slider.oldIndex = slider.active.index;\n //set new index\n slider.active.index = setSlideIndex(slideIndex);\n\n // if plugin is currently in motion, ignore request\n if (slider.working || slider.active.index === slider.oldIndex) { return; }\n // declare that plugin is in motion\n slider.working = true;\n\n performTransition = slider.settings.onSlideBefore.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);\n\n // If transitions canceled, reset and return\n if (typeof (performTransition) !== 'undefined' && !performTransition) {\n slider.active.index = slider.oldIndex; // restore old index\n slider.working = false; // is not in motion\n return;\n }\n\n if (direction === 'next') {\n // Prevent canceling in future functions or lack there-of from negating previous commands to cancel\n if (!slider.settings.onSlideNext.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) {\n performTransition = false;\n }\n } else if (direction === 'prev') {\n // Prevent canceling in future functions or lack there-of from negating previous commands to cancel\n if (!slider.settings.onSlidePrev.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) {\n performTransition = false;\n }\n }\n\n // check if last slide\n slider.active.last = slider.active.index >= getPagerQty() - 1;\n // update the pager with active class\n if (slider.settings.pager || slider.settings.pagerCustom) { updatePagerActive(slider.active.index); }\n // // check for direction control update\n if (slider.settings.controls) { updateDirectionControls(); }\n // if slider is set to mode: \"fade\"\n if (slider.settings.mode === 'fade') {\n // if adaptiveHeight is true and next height is different from current height, animate to the new height\n if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) {\n slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);\n }\n // fade out the visible child and reset its z-index value\n slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});\n // fade in the newly requested slide\n slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex + 1).fadeIn(slider.settings.speed, function() {\n $(this).css('zIndex', slider.settings.slideZIndex);\n updateAfterSlideTransition();\n });\n // slider mode is not \"fade\"\n } else {\n // if adaptiveHeight is true and next height is different from current height, animate to the new height\n if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) {\n slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);\n }\n // if carousel and not infinite loop\n if (!slider.settings.infiniteLoop && slider.carousel && slider.active.last) {\n if (slider.settings.mode === 'horizontal') {\n // get the last child position\n lastChild = slider.children.eq(slider.children.length - 1);\n position = lastChild.position();\n // calculate the position of the last slide\n moveBy = slider.viewport.width() - lastChild.outerWidth();\n } else {\n // get last showing index position\n lastShowingIndex = slider.children.length - slider.settings.minSlides;\n position = slider.children.eq(lastShowingIndex).position();\n }\n // horizontal carousel, going previous while on first slide (infiniteLoop mode)\n } else if (slider.carousel && slider.active.last && direction === 'prev') {\n // get the last child position\n eq = slider.settings.moveSlides === 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides);\n lastChild = el.children('.bx-clone').eq(eq);\n position = lastChild.position();\n // if infinite loop and \"Next\" is clicked on the last slide\n } else if (direction === 'next' && slider.active.index === 0) {\n // get the last clone position\n position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position();\n slider.active.last = false;\n // normal non-zero requests\n } else if (slideIndex >= 0) {\n //parseInt is applied to allow floats for slides/page\n requestEl = slideIndex * parseInt(getMoveBy());\n position = slider.children.eq(requestEl).position();\n }\n\n /* If the position doesn't exist\n * (e.g. if you destroy the slider on a next click),\n * it doesn't throw an error.\n */\n if (typeof (position) !== 'undefined') {\n value = slider.settings.mode === 'horizontal' ? -(position.left - moveBy) : -position.top;\n // plugin values to be animated\n setPositionProperty(value, 'slide', slider.settings.speed);\n }\n slider.working = false;\n }\n if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); }\n };\n\n /**\n * Transitions to the next slide in the show\n */\n el.goToNextSlide = function() {\
98n // if infiniteLoop is false and last page is showing, disregard call\n if (!slider.settings.infiniteLoop && slider.active.last) { return; }\n\t if (slider.working === true){ return ;}\n var pagerIndex = parseInt(slider.active.index) + 1;\n el.goToSlide(pagerIndex, 'next');\n };\n\n /**\n * Transitions to the prev slide in the show\n */\n el.goToPrevSlide = function() {\n // if infiniteLoop is false and last page is showing, disregard call\n if (!slider.settings.infiniteLoop && slider.active.index === 0) { return; }\n\t if (slider.working === true){ return ;}\n var pagerIndex = parseInt(slider.active.index) - 1;\n el.goToSlide(pagerIndex, 'prev');\n };\n\n /**\n * Starts the auto show\n *\n * @param preventControlUpdate (boolean)\n * - if true, auto controls state will not be updated\n */\n el.startAuto = function(preventControlUpdate) {\n // if an interval already exists, disregard call\n if (slider.interval) { return; }\n // create an interval\n slider.interval = setInterval(function() {\n if (slider.settings.autoDirection === 'next') {\n el.goToNextSlide();\n } else {\n el.goToPrevSlide();\n }\n }, slider.settings.pause);\n\t //allback for when the auto rotate status changes\n\t slider.settings.onAutoChange.call(el, true);\n // if auto controls are displayed and preventControlUpdate is not true\n if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('stop'); }\n };\n\n /**\n * Stops the auto show\n *\n * @param preventControlUpdate (boolean)\n * - if true, auto controls state will not be updated\n */\n el.stopAuto = function(preventControlUpdate) {\n // if slider is auto paused, just clear that state\n if (slider.autoPaused) slider.autoPaused = false;\n // if no interval exists, disregard call\n if (!slider.interval) { return; }\n // clear the interval\n clearInterval(slider.interval);\n slider.interval = null;\n\t //allback for when the auto rotate status changes\n\t slider.settings.onAutoChange.call(el, false);\n // if auto controls are displayed and preventControlUpdate is not true\n if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('start'); }\n };\n\n /**\n * Returns current slide index (zero-based)\n */\n el.getCurrentSlide = function() {\n return slider.active.index;\n };\n\n /**\n * Returns current slide element\n */\n el.getCurrentSlideElement = function() {\n return slider.children.eq(slider.active.index);\n };\n\n /**\n * Returns a slide element\n * @param index (int)\n * - The index (zero-based) of the element you want returned.\n */\n el.getSlideElement = function(index) {\n return slider.children.eq(index);\n };\n\n /**\n * Returns number of slides in show\n */\n el.getSlideCount = function() {\n return slider.children.length;\n };\n\n /**\n * Return slider.working variable\n */\n el.isWorking = function() {\n return slider.working;\n };\n\n /**\n * Update all dynamic slider elements\n */\n el.redrawSlider = function() {\n // resize all children in ratio to new screen size\n slider.children.add(el.find('.bx-clone')).outerWidth(getSlideWidth());\n // adjust the height\n slider.viewport.css('height', getViewportHeight());\n // update the slide position\n if (!slider.settings.ticker) { setSlidePosition(); }\n // if active.last was true before the screen resize, we want\n // to keep it last no matter what screen size we end on\n if (slider.active.last) { slider.active.index = getPagerQty() - 1; }\n // if the active index (page) no longer exists due to the resize, simply set the index as last\n if (slider.active.index >= getPagerQty()) { slider.active.last = true; }\n // if a pager is being displayed and a custom pager is not being used, update it\n if (slider.settings.pager && !slider.settings.pagerCustom) {\n populatePager();\n updatePagerActive(slider.active.index);\n }\n if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); }\n };\n\n /**\n * Destroy the current instance of the slider (revert everything back to original state)\n */\n el.destroySlider = function() {\
98n // don't do anything if slider has already been destroyed\n if (!slider.initialized) { return; }\n slider.initialized = false;\n $('.bx-clone', this).remove();\n slider.children.each(function() {\n if ($(this).data('origStyle') !== undefined) {\n $(this).attr('style', $(this).data('origStyle'));\n } else {\n $(this).removeAttr('style');\n }\n });\n if ($(this).data('origStyle') !== undefined) {\n this.attr('style', $(this).data('origStyle'));\n } else {\n $(this).removeAttr('style');\n }\n $(this).unwrap().unwrap();\n if (slider.controls.el) { slider.controls.el.remove(); }\n if (slider.controls.next) { slider.controls.next.remove(); }\n if (slider.controls.prev) { slider.controls.prev.remove(); }\n if (slider.pagerEl && slider.settings.controls && !slider.settings.pagerCustom) { slider.pagerEl.remove(); }\n $('.bx-caption', this).remove();\n if (slider.controls.autoEl) { slider.controls.autoEl.remove(); }\n clearInterval(slider.interval);\n if (slider.settings.responsive) { $(window).off('resize', resizeWindow); }\n if (slider.settings.keyboardEnabled) { $(document).off('keydown', keyPress); }\n //remove self reference in data\n $(this).removeData('bxSlider');\n\t // remove global window handlers\n\t $(window).off('blur', windowBlurHandler).off('focus', windowFocusHandler);\n };\n\n /**\n * Reload the slider (revert all DOM changes, and re-initialize)\n */\n el.reloadSlider = function(settings) {\n if (settings !== undefined) { options = settings; }\n el.destroySlider();\n init();\n //store reference to self in order to access public functions later\n $(el).data('bxSlider', this);\n };\n\n init();\n\n $(el).data('bxSlider', this);\n\n // returns the current jQuery object\n return this;\n };\n\n})(jQuery);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9ieHNsaWRlci9kaXN0L2pxdWVyeS5ieHNsaWRlci5qcz8xOTkyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYnhTbGlkZXIgdjQuMi4xZFxuICogQ29weXJpZ2h0IDIwMTMtMjAxNyBTdGV2ZW4gV2FuZGVyc2tpXG4gKiBXcml0dGVuIHdoaWxlIGRyaW5raW5nIEJlbGdpYW4gYWxlcyBhbmQgbGlzdGVuaW5nIHRvIGphenpcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVClcbiAqL1xuXG47KGZ1bmN0aW9uKCQpIHtcblxuICB2YXIgZGVmYXVsdHMgPSB7XG5cbiAgICAvLyBHRU5FUkFMXG4gICAgbW9kZTogJ2hvcml6b250YWwnLFxuICAgIHNsaWRlU2VsZWN0b3I6ICcnLFxuICAgIGluZmluaXRlTG9vcDogdHJ1ZSxcbiAgICBoaWRlQ29udHJvbE9uRW5kOiBmYWxzZSxcbiAgICBzcGVlZDogNTAwLFxuICAgIGVhc2luZzogbnVsbCxcbiAgICBzbGlkZU1hcmdpbjogMCxcbiAgICBzdGFydFNsaWRlOiAwLFxuICAgIHJhbmRvbVN0YXJ0OiBmYWxzZSxcbiAgICBjYXB0aW9uczogZmFsc2UsXG4gICAgdGlja2VyOiBmYWxzZSxcbiAgICB0aWNrZXJIb3ZlcjogZmFsc2UsXG4gICAgYWRhcHRpdmVIZWlnaHQ6IGZhbHNlLFxuICAgIGFkYXB0aXZlSGVpZ2h0U3BlZWQ6IDUwMCxcbiAgICB2aWRlbzogZmFsc2UsXG4gICAgdXNlQ1NTOiB0cnVlLFxuICAgIHByZWxvYWRJbWFnZXM6ICd2aXNpYmxlJyxcbiAgICByZXNwb25zaXZlOiB0cnVlLFxuICAgIHNsaWRlWkluZGV4OiA1MCxcbiAgICB3cmFwcGVyQ2xhc3M6ICdieC13cmFwcGVyJyxcblxuICAgIC8vIFRPVUNIXG4gICAgdG91Y2hFbmFibGVkOiB0cnVlLFxuICAgIHN3aXBlVGhyZXNob2xkOiA1MCxcbiAgICBvbmVUb09uZVRvdWNoOiB0cnVlLFxuICAgIHByZXZlbnREZWZhdWx0U3dpcGVYOiB0cnVlLFxuICAgIHByZXZlbnREZWZhdWx0U3dpcGVZOiBmYWxzZSxcblxuICAgIC8vIEFDQ0VTU0lCSUxJVFlcbiAgICBhcmlhTGl2ZTogdHJ1ZSxcbiAgICBhcmlhSGlkZGVuOiB0cnVlLFxuXG4gICAgLy8gS0VZQk9BUkRcbiAgICBrZXlib2FyZEVuYWJsZWQ6IGZhbHNlLFxuXG4gICAgLy8gUEFHRVJcbiAgICBwYWdlcjogdHJ1ZSxcbiAgICBwYWdlclR5cGU6ICdmdWxsJyxcbiAgICBwYWdlclNob3J0U2VwYXJhdG9yOiAnIC8gJyxcbiAgICBwYWdlclNlbGVjdG9yOiBudWxsLFxuICAgIGJ1aWxkUGFnZXI6IG51bGwsXG4gICAgcGFnZXJDdXN0b206IG51bGwsXG5cbiAgICAvLyBDT05UUk9MU1xuICAgIGNvbnRyb2xzOiB0cnVlLFxuICAgIG5leHRUZXh0OiAnTmV4dCcsXG4gICAgcHJldlRleHQ6ICdQcmV2JyxcbiAgICBuZXh0U2VsZWN0b3I6IG51bGwsXG4gICAgcHJldlNlbGVjdG9yOiBudWxsLFxuICAgIGF1dG9Db250cm9sczogZmFsc2UsXG4gICAgc3RhcnRUZXh0OiAnU3RhcnQnLFxuICAgIHN0b3BUZXh0OiAnU3RvcCcsXG4gICAgYXV0b0NvbnRyb2xzQ29tYmluZTogZmFsc2UsXG4gICAgYXV0b0NvbnRyb2xzU2VsZWN0b3I6IG51bGwsXG5cbiAgICAvLyBBVVRPXG4gICAgYXV0bzogZmFsc2UsXG4gICAgcGF1c2U6IDQwMDAsXG4gICAgYXV0b1N0YXJ0Oi
98B0cnVlLFxuICAgIGF1dG9EaXJlY3Rpb246ICduZXh0JyxcbiAgICBzdG9wQXV0b09uQ2xpY2s6IGZhbHNlLFxuICAgIGF1dG9Ib3ZlcjogZmFsc2UsXG4gICAgYXV0b0RlbGF5OiAwLFxuICAgIGF1dG9TbGlkZUZvck9uZVBhZ2U6IGZhbHNlLFxuXG4gICAgLy8gQ0FST1VTRUxcbiAgICBtaW5TbGlkZXM6IDEsXG4gICAgbWF4U2xpZGVzOiAxLFxuICAgIG1vdmVTbGlkZXM6IDAsXG4gICAgc2xpZGVXaWR0aDogMCxcbiAgICBzaHJpbmtJdGVtczogZmFsc2UsXG5cbiAgICAvLyBDQUxMQkFDS1NcbiAgICBvblNsaWRlckxvYWQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSxcbiAgICBvblNsaWRlQmVmb3JlOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0sXG4gICAgb25TbGlkZUFmdGVyOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0sXG4gICAgb25TbGlkZU5leHQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSxcbiAgICBvblNsaWRlUHJldjogZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LFxuICAgIG9uU2xpZGVyUmVzaXplOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0sXG5cdG9uQXV0b0NoYW5nZTogZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9IC8vY2FsbHMgd2hlbiBhdXRvIHNsaWRlcyBzdGFydHMgYW5kIHN0b3BzXG4gIH07XG5cbiAgJC5mbi5ieFNsaWRlciA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gc3VwcG9ydCBtdWx0aXBsZSBlbGVtZW50c1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgJCh0aGlzKS5ieFNsaWRlcihvcHRpb25zKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIGEgbmFtZXNwYWNlIHRvIGJlIHVzZWQgdGhyb3VnaG91dCB0aGUgcGx1Z2luXG4gICAgdmFyIHNsaWRlciA9IHt9LFxuICAgIC8vIHNldCBhIHJlZmVyZW5jZSB0byBvdXIgc2xpZGVyIGVsZW1lbnRcbiAgICBlbCA9IHRoaXMsXG4gICAgLy8gZ2V0IHRoZSBvcmlnaW5hbCB3aW5kb3cgZGltZW5zICh0aGFua3MgYSBsb3QgSUUpXG4gICAgd2luZG93V2lkdGggPSAkKHdpbmRvdykud2lkdGgoKSxcbiAgICB3aW5kb3dIZWlnaHQgPSAkKHdpbmRvdykuaGVpZ2h0KCk7XG5cbiAgICAvLyBSZXR1cm4gaWYgc2xpZGVyIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWRcbiAgICBpZiAoJChlbCkuZGF0YSgnYnhTbGlkZXInKSkgeyByZXR1cm47IH1cblxuICAgIC8qKlxuICAgICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICogPSBQUklWQVRFIEZVTkNUSU9OU1xuICAgICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBuYW1lc3BhY2Ugc2V0dGluZ3MgdG8gYmUgdXNlZCB0aHJvdWdob3V0IHBsdWdpblxuICAgICAqL1xuICAgIHZhciBpbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBSZXR1cm4gaWYgc2xpZGVyIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWRcbiAgICAgIGlmICgkKGVsKS5kYXRhKCdieFNsaWRlcicpKSB7IHJldHVybjsgfVxuICAgICAgLy8gbWVyZ2UgdXNlci1zdXBwbGllZCBvcHRpb25zIHdpdGggdGhlIGRlZmF1bHRzXG4gICAgICBzbGlkZXIuc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuICAgICAgLy8gcGFyc2Ugc2xpZGVXaWR0aCBzZXR0aW5nXG4gICAgICBzbGlkZXIuc2V0dGluZ3Muc2xpZGVXaWR0aCA9IHBhcnNlSW50KHNsaWRlci5zZXR0aW5ncy5zbGlkZVdpZHRoKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBvcmlnaW5hbCBjaGlsZHJlblxuICAgICAgc2xpZGVyLmNoaWxkcmVuID0gZWwuY2hpbGRyZW4oc2xpZGVyLnNldHRpbmdzLnNsaWRlU2VsZWN0b3IpO1xuICAgICAgLy8gY2hlY2sgaWYgYWN0dWFsIG51bWJlciBvZiBzbGlkZXMgaXMgbGVzcyB0aGFuIG1pblNsaWRlcyAvIG1heFNsaWRlc1xuICAgICAgaWYgKHNsaWRlci5jaGlsZHJlbi5sZW5ndGggPCBzbGlkZXIuc2V0dGluZ3MubWluU2xpZGVzKSB7IHNsaWRlci5zZXR0aW5ncy5taW5TbGlkZXMgPSBzbGlkZXIuY2hpbGRyZW4ubGVuZ3RoOyB9XG4gICAgICBpZiAoc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCA8IHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXMpIHsgc2xpZGVyLnNldHRpbmdzLm1heFNsaWRlcyA9IHNsaWRlci5jaGlsZHJlbi5sZW5ndGg7IH1cbiAgICAgIC8vIGlmIHJhbmRvbSBzdGFydCwgc2V0IHRoZSBzdGFydFNsaWRlIHNldHRpbmcgdG8gcmFuZG9tIG51bWJlclxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5yYW5kb21TdGFydCkgeyBzbGlkZXIuc2V0dGluZ3Muc3RhcnRTbGlkZSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHNsaWRlci5jaGlsZHJlbi5sZW5ndGgpOyB9XG4gICAgICAvLyBzdG9yZSBhY3RpdmUgc2xpZGUgaW5mb3JtYXRpb25cbiAgICAgIHNsaWRlci5hY3RpdmUgPSB7IGluZGV4OiBzbGlkZXIuc2V0dGluZ3Muc3RhcnRTbGlkZSB9O1xuICAgICAgLy8gc3RvcmUgaWYgdGhlIHNsaWRlciBpcyBpbiBjYXJvdXNlbCBtb2RlIChkaXNwbGF5aW5nIC8gbW92aW5nIG11bHRpcGxlIHNsaWRlcylcbiAgICAgIHNsaWRlci5jYXJvdXNlbCA9IHNsaWRlci5zZXR0aW5ncy5taW5TbGlkZXMgPiAxIHx8IHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXMgPiAxO1xuICAgICAgLy8gaWYgY2Fyb3VzZWwsIGZvcmNlIHByZWxvYWRJbWFnZXMgPSAnYWxsJ1xuICAgICAgaWYgKHNsaWRlci5jYXJvdXNlbCkgeyBzbGlkZXIuc2V0dGluZ3MucHJlbG9hZEltYWdlcyA9ICdhbGwnOyB9XG4gICAgICAvLyBjYWxjdWxhdGUgdGhlIG1pbiAvIG1heCB3aWR0aCB0aHJlc2hvbGRzIGJhc2VkIG9uIG1pbiAvIG1heCBudW1iZXIgb2Ygc2xpZGVzXG4gICAgICAvLyB1c2VkIHRvIHNldHVwIGFuZCB1cGRhdGUgY2Fyb3VzZWwgc2xpZGVzIGRpbWVuc2lvbnNcbiAgICAgIHNsaWRlci5taW5UaHJlc2hvbGQgPSAoc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcyAqIHNsaWRlci5zZXR0aW5ncy5zbGlkZVdpZHRoKSArICgoc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcyAtIDEpICogc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luKTtcbiAgICAgIHNsaWRlci5tYXhUaHJlc2hvbGQgPSAoc2xpZGVyLnNldHRpbmdzLm1heFNsaWRlcyAqIHNsaWRlci5zZXR0aW5ncy5zbGlkZVdpZHRoKSArICgoc2xpZGVyLnNldHRpbmdzLm1heFNsaWRlcyAtIDEpICogc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBzbGlkZXIgKGlmIGN1cnJlbnRseSBhbmltYXRpbmcsIHdvcmtpbmcgaXMgdHJ1ZSlcbiAgICAgIHNsaWRlci53b3JraW5nID0gZmFsc2U7XG4gICAgICAvLyBpbml0aWFsaXplIHRoZSBjb250cm9scyBvYmplY3RcbiAgICAgIHNsaWRlci5jb250cm9scyA9IHt9O1xuICAgICAgLy8gaW5pdGlhbGl6ZSBhbiBhdXRvIGludGVydmFsXG4gICAgICBzbGlkZXIuaW50ZXJ2YWwgPSBudWxsO1xuICAgICAgLy8gZGV0ZXJtaW5lIHdoaWNoIHByb3BlcnR5IHRvIHVzZSBmb3IgdHJhbnNpdGlvbnNcbiAgICAgIHNsaWRlci5hbmltUHJvcCA9IHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAndmVydGljYWwnID8gJ3RvcCcgOiAnbGVmdCc7XG4gICAgICAvLyBkZXRlcm1pbmUgaWYgaGFyZHdhcmUgYWNjZWxlcmF0aW9uIGNhbiBiZSB1c2VkXG4gICAgICBzbGlkZXIudXNpbmdDU1MgPSBzbGlkZXIuc2V0dGluZ3MudXNlQ1NTICYmIHNsaWRlci5zZXR0aW5ncy5tb2RlICE9PSAnZmFkZScgJiYgKGZ1bmN0aW9uKCkge1xuICAgICAgICAvLyBjcmVhdGUgb3VyIHRlc3QgZGl2IGVsZW1lbnRcbiAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgICAvLyBjc3MgdHJhbnNpdGlvbiBwcm9wZXJ0aWVzXG4gICAgICAgI
98HByb3BzID0gWydXZWJraXRQZXJzcGVjdGl2ZScsICdNb3pQZXJzcGVjdGl2ZScsICdPUGVyc3BlY3RpdmUnLCAnbXNQZXJzcGVjdGl2ZSddO1xuICAgICAgICAvLyB0ZXN0IGZvciBlYWNoIHByb3BlcnR5XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoZGl2LnN0eWxlW3Byb3BzW2ldXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzbGlkZXIuY3NzUHJlZml4ID0gcHJvcHNbaV0ucmVwbGFjZSgnUGVyc3BlY3RpdmUnLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIHNsaWRlci5hbmltUHJvcCA9ICctJyArIHNsaWRlci5jc3NQcmVmaXggKyAnLXRyYW5zZm9ybSc7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSgpKTtcbiAgICAgIC8vIGlmIHZlcnRpY2FsIG1vZGUgYWx3YXlzIG1ha2UgbWF4U2xpZGVzIGFuZCBtaW5TbGlkZXMgZXF1YWxcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykgeyBzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzID0gc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlczsgfVxuICAgICAgLy8gc2F2ZSBvcmlnaW5hbCBzdHlsZSBkYXRhXG4gICAgICBlbC5kYXRhKCdvcmlnU3R5bGUnLCBlbC5hdHRyKCdzdHlsZScpKTtcbiAgICAgIGVsLmNoaWxkcmVuKHNsaWRlci5zZXR0aW5ncy5zbGlkZVNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAkKHRoaXMpLmRhdGEoJ29yaWdTdHlsZScsICQodGhpcykuYXR0cignc3R5bGUnKSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gcGVyZm9ybSBhbGwgRE9NIC8gQ1NTIG1vZGlmaWNhdGlvbnNcbiAgICAgIHNldHVwKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGFsbCBET00gYW5kIENTUyBtb2RpZmljYXRpb25zXG4gICAgICovXG4gICAgdmFyIHNldHVwID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
98XIgcHJlbG9hZFNlbGVjdG9yID0gc2xpZGVyLmNoaWxkcmVuLmVxKHNsaWRlci5zZXR0aW5ncy5zdGFydFNsaWRlKTsgLy8gc2V0IHRoZSBkZWZhdWx0IHByZWxvYWQgc2VsZWN0b3IgKHZpc2libGUpXG5cbiAgICAgIC8vIHdyYXAgZWwgaW4gYSB3cmFwcGVyXG4gICAgICBlbC53cmFwKCc8ZGl2IGNsYXNzPVwiJyArIHNsaWRlci5zZXR0aW5ncy53cmFwcGVyQ2xhc3MgKyAnXCI+PGRpdiBjbGFzcz1cImJ4LXZpZXdwb3J0XCI+PC9kaXY+PC9kaXY+Jyk7XG4gICAgICAvLyBzdG9yZSBhIG5hbWVzcGFjZSByZWZlcmVuY2UgdG8gLmJ4LXZpZXdwb3J0XG4gICAgICBzbGlkZXIudmlld3BvcnQgPSBlbC5wYXJlbnQoKTtcblxuICAgICAgLy8gYWRkIGFyaWEtbGl2ZSBpZiB0aGUgc2V0dGluZyBpcyBlbmFibGVkIGFuZCB0aWNrZXIgbW9kZSBpcyBkaXNhYmxlZFxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hcmlhTGl2ZSAmJiAhc2xpZGVyLnNldHRpbmdzLnRpY2tlcikge1xuICAgICAgICBzbGlkZXIudmlld3BvcnQuYXR0cignYXJpYS1saXZlJywgJ3BvbGl0ZScpO1xuICAgICAgfVxuICAgICAgLy8gYWRkIGEgbG9hZGluZyBkaXYgdG8gZGlzcGxheSB3aGlsZSBpbWFnZXMgYXJlIGxvYWRpbmdcbiAgICAgIHNsaWRlci5sb2FkZXIgPSAkKCc8ZGl2IGNsYXNzPVwiYngtbG9hZGluZ1wiIC8+Jyk7XG4gICAgICBzbGlkZXIudmlld3BvcnQucHJlcGVuZChzbGlkZXIubG9hZGVyKTtcbiAgICAgIC8vIHNldCBlbCB0byBhIG1hc3NpdmUgd2lkdGgsIHRvIGhvbGQgYW55IG5lZWRlZCBzbGlkZXNcbiAgICAgIC8vIGFsc28gc3RyaXAgYW55IG1hcmdpbiBhbmQgcGFkZGluZyBmcm9tIGVsXG4gICAgICBlbC5jc3Moe1xuICAgICAgICB3aWR0aDogc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJyA/IChzbGlkZXIuY2hpbGRyZW4ubGVuZ3RoICogMTAwMCArIDIxNSkgKyAnJScgOiAnYXV0bycsXG4gICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnXG4gICAgICB9KTtcbiAgICAgIC8vIGlmIHVzaW5nIENTUywgYWRkIHRoZSBlYXNpbmcgcHJvcGVydHlcbiAgICAgIGlmIChzbGlkZXIudXNpbmdDU1MgJiYgc2xpZGVyLnNldHRpbmdzLmVhc2luZykge1xuICAgICAgICBlbC5jc3MoJy0nICsgc2xpZGVyLmNzc1ByZWZpeCArICctdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb24nLCBzbGlkZXIuc2V0dGluZ3MuZWFzaW5nKTtcbiAgICAgIC8vIGlmIG5vdCB1c2luZyBDU1MgYW5kIG5vIGVhc2luZyB2YWx1ZSB3YXMgc3VwcGxpZWQsIHVzZSB0aGUgZGVmYXVsdCBKUyBhbmltYXRpb24gZWFzaW5nIChzd2luZylcbiAgICAgIH0gZWxzZSBpZiAoIXNsaWRlci5zZXR0aW5ncy5lYXNpbmcpIHtcbiAgICAgICAgc2xpZGVyLnNldHRpbmdzLmVhc2luZyA9ICdzd2luZyc7XG4gICAgICB9XG4gICAgICAvLyBtYWtlIG1vZGlmaWNhdGlvbnMgdG8gdGhlIHZpZXdwb3J0ICguYngtdmlld3BvcnQpXG4gICAgICBzbGlkZXIudmlld3BvcnQuY3NzKHtcbiAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICAgICAgfSk7XG4gICAgICBzbGlkZXIudmlld3BvcnQucGFyZW50KCkuY3NzKHtcbiAgICAgICAgbWF4V2lkdGg6IGdldFZpZXdwb3J0TWF4V2lkdGgoKVxuICAgICAgfSk7XG4gICAgICAvLyBhcHBseSBjc3MgdG8gYWxsIHNsaWRlciBjaGlsZHJlblxuICAgICAgc2xpZGVyLmNoaWxkcmVuLmNzcyh7XG4gICAgICAgIC8vIHRoZSBmbG9hdCBhdHRyaWJ1dGUgaXMgYSByZXNlcnZlZCB3b3JkIGluIGNvbXByZXNzb3JzIGxpa2UgWVVJIGNvbXByZXNzb3IgYW5kIG5lZWQgdG8gYmUgcXVvdGVkICM0OFxuICAgICAgICAnZmxvYXQnOiBzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnID8gJ2xlZnQnIDogJ25vbmUnLFxuICAgICAgICBsaXN0U3R5bGU6ICdub25lJyxcbiAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbiAgICAgIH0pO1xuICAgICAgLy8gYXBwbHkgdGhlIGNhbGN1bGF0ZWQgd2lkdGggYWZ0ZXIgdGhlIGZsb2F0IGlzIGFwcGxpZWQgdG8gcHJldmVudCBzY3JvbGxiYXIgaW50ZXJmZXJlbmNlXG4gICAgICBzbGlkZXIuY2hpbGRyZW4uY3NzKCd3aWR0aCcsIGdldFNsaWRlV2lkdGgoKSk7XG4gICAgICAvLyBpZiBzbGlkZU1hcmdpbiBpcyBzdXBwbGllZCwgYWRkIHRoZSBjc3NcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnICYmIHNsaWRlci5zZXR0aW5ncy5zbGlkZU1hcmdpbiA+IDApIHsgc2xpZGVyLmNoaWxkcmVuLmNzcygnbWFyZ2luUmlnaHQnLCBzbGlkZXIuc2V0dGluZ3Muc2xpZGVNYXJnaW4pOyB9XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICd2ZXJ0aWNhbCcgJiYgc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luID4gMCkgeyBzbGlkZXIuY2hpbGRyZW4uY3NzKCdtYXJnaW5Cb3R0b20nLCBzbGlkZXIuc2V0dGluZ3Muc2xpZGVNYXJnaW4pOyB9XG4gICAgICAvLyBpZiBcImZhZGVcIiBtb2RlLCBhZGQgcG9zaXRpb25pbmcgYW5kIHotaW5kZXggQ1NTXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdmYWRlJykge1xuICAgICAgICBzbGlkZXIuY2hpbGRyZW4uY3NzKHtcbiAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICB6SW5kZXg6IDAsXG4gICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBwcmVwYXJlIHRoZSB6LWluZGV4IG9uIHRoZSBzaG93aW5nIGVsZW1lbnRcbiAgICAgICAgc2xpZGVyLmNoaWxkcmVuLmVxKHNsaWRlci5zZXR0aW5ncy5zdGFydFNsaWRlKS5jc3Moe3pJbmRleDogc2xpZGVyLnNldHRpbmdzLnNsaWRlWkluZGV4LCBkaXNwbGF5OiAnYmxvY2snfSk7XG4gICAgICB9XG4gICAgICAvLyBjcmVhdGUgYW4gZWxlbWVudCB0byBjb250YWluIGFsbCBzbGlkZXIgY29udHJvbHMgKHBhZ2VyLCBzdGFydCAvIHN0b3AsIGV0YylcbiAgICAgIHNsaWRlci5jb250cm9scy5lbCA9ICQoJzxkaXYgY2xhc3M9XCJieC1jb250cm9sc1wiIC8+Jyk7XG4gICAgICAvLyBpZiBjYXB0aW9ucyBhcmUgcmVxdWVzdGVkLCBhZGQgdGhlbVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5jYXB0aW9ucykgeyBhcHBlbmRDYXB0aW9ucygpOyB9XG4gICAgICAvLyBjaGVjayBpZiBzdGFydFNsaWRlIGlzIGxhc3Qgc2xpZGVcbiAgICAgIHNsaWRlci5hY3RpdmUubGFzdCA9IHNsaWRlci5zZXR0aW5ncy5zdGFydFNsaWRlID09PSBnZXRQYWdlclF0eSgpIC0gMTtcbiAgICAgIC8vIGlmIHZpZGVvIGlzIHRydWUsIHNldCB1cCB0aGUgZml0VmlkcyBwbHVnaW5cbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MudmlkZW8pIHsgZWwuZml0VmlkcygpOyB9XG5cdCAgLy9wcmVsb2FkSW1hZ2VzXG5cdCAgaWYgKHNsaWRlci5zZXR0aW5ncy5wcmVsb2FkSW1hZ2VzID09PSAnbm9uZScpIHsgXG5cdFx0ICBwcmVsb2FkU2VsZWN0b3IgPSBudWxsOyBcblx0ICB9XG4gICAgICBlbHNlIGlmIChzbGlkZXIuc2V0dGluZ3MucHJlbG9hZEltYWdlcyA9PT0gJ2FsbCcgfHwgc2xpZGVyLnNldHRpbmdzLnRpY2tlcikgeyBcblx0XHQgIHByZWxvYWRTZWxlY3RvciA9IHNsaWRlci5jaGlsZHJlbjsgXG5cdCAgfVxuICAgICAgLy8gb25seSBjaGVjayBmb3IgY29udHJvbCBhZGRpdGlvbiBpZiBub3QgaW4gXCJ0aWNrZXJcIiBtb2RlXG4gICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy50aWNrZXIpIHtcbiAgICAgICAgLy8gaWYgY29udHJvbHMgYXJlIHJlcXVlc3RlZCwgYWRkIHRoZW1cbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5jb250cm9scykgeyBhcHBlbmRDb250cm9scygpOyB9XG4gICAgICAgIC8vIGlmIGF1dG8gaXMgdHJ1ZSwgYW5kIGF1dG8gY29udHJvbHMgYXJlIHJlcXVlc3RlZCwgYWRkIHRoZW1cbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hdXRvICYmIHNsaWRlci5zZXR0aW5ncy5hdXRvQ29udHJvbHMpIHsgYXBwZW5kQ29udHJvbHNBdXRvKCk7IH1cbiAgICAgICAgLy8gaWYgcGFnZXIgaXMgcmVxdWVzdGVkLCBhZGQgaXRcbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5wYWdlcikgeyBhcHBlbmRQYWdlcigpOyB9XG4gICAgICAgIC8vIGlmIGFueSBjb250cm9sIG9wdGlvbiBpcyByZXF1ZXN0ZWQsIGFkZCB0aGUgY29udHJvbHMgd3JhcHBlclxuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmNvbn
98Ryb2xzIHx8IHNsaWRlci5zZXR0aW5ncy5hdXRvQ29udHJvbHMgfHwgc2xpZGVyLnNldHRpbmdzLnBhZ2VyKSB7IHNsaWRlci52aWV3cG9ydC5hZnRlcihzbGlkZXIuY29udHJvbHMuZWwpOyB9XG4gICAgICAvLyBpZiB0aWNrZXIgbW9kZSwgZG8gbm90IGFsbG93IGEgcGFnZXJcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNsaWRlci5zZXR0aW5ncy5wYWdlciA9IGZhbHNlO1xuICAgICAgfVxuXHQgIGlmIChwcmVsb2FkU2VsZWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgc3RhcnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvYWRFbGVtZW50cyhwcmVsb2FkU2VsZWN0b3IsIHN0YXJ0KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIGxvYWRFbGVtZW50cyA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHRvdGFsID0gc2VsZWN0b3IuZmluZCgnaW1nOm5vdChbc3JjPVwiXCJdKSwgaWZyYW1lJykubGVuZ3RoLFxuICAgICAgY291bnQgPSAwO1xuICAgICAgaWYgKHRvdGFsID09PSAwKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlbGVjdG9yLmZpbmQoJ2ltZzpub3QoW3NyYz1cIlwiXSksIGlmcmFtZScpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICQodGhpcykub25lKCdsb2FkIGVycm9yJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKCsrY291bnQgPT09IHRvdGFsKSB7IGNhbGxiYWNrKCk7IH1cbiAgICAgICAgfSkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAodGhpcy5jb21wbGV0ZSB8fCB0aGlzLnNyYyA9PSAnJykgeyAkKHRoaXMpLnRyaWdnZXIoJ2xvYWQnKTsgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc2xpZGVyXG4gICAgICovXG4gICAgdmFyIHN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBpZiBpbmZpbml0ZSBsb29wLCBwcmVwYXJlIGFkZGl0aW9uYWwgc2xpZGVzXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCAmJiBzbGlkZXIuc2V0dGluZ3MubW9kZSAhPT0gJ2ZhZGUnICYmICFzbGlkZXIuc2V0dGluZ3MudGlja2VyKSB7XG4gICAgICAgIHZhciBzbGljZSAgICA9IHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAndmVydGljYWwnID8gc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcyA6IHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXMsXG4gICAgICAgIHNsaWNlQXBwZW5kICA9IHNsaWRlci5jaGlsZHJlbi5zbGljZSgwLCBzbGljZSkuY2xvbmUodHJ1ZSkuYWRkQ2xhc3MoJ2J4LWNsb25lJyksXG4gICAgICAgIHNsaWNlUHJlcGVuZCA9IHNsaWRlci5jaGlsZHJlbi5zbGljZSgtc2xpY2UpLmNsb25lKHRydWUpLmFkZENsYXNzKCdieC1jbG9uZScpO1xuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmFyaWFIaWRkZW4pIHtcbiAgICAgICAgICBzbGljZUFwcGVuZC5hdHRyKCdhcmlhLWh
98pZGRlbicsIHRydWUpO1xuICAgICAgICAgIHNsaWNlUHJlcGVuZC5hdHRyKCdhcmlhLWhpZGRlbicsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsLmFwcGVuZChzbGljZUFwcGVuZCkucHJlcGVuZChzbGljZVByZXBlbmQpO1xuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIHRoZSBsb2FkaW5nIERPTSBlbGVtZW50XG4gICAgICBzbGlkZXIubG9hZGVyLnJlbW92ZSgpO1xuICAgICAgLy8gc2V0IHRoZSBsZWZ0IC8gdG9wIHBvc2l0aW9uIG9mIFwiZWxcIlxuICAgICAgc2V0U2xpZGVQb3NpdGlvbigpO1xuICAgICAgLy8gaWYgXCJ2ZXJ0aWNhbFwiIG1vZGUsIGFsd2F5cyB1c2UgYWRhcHRpdmVIZWlnaHQgdG8gcHJldmVudCBvZGQgYmVoYXZpb3JcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykgeyBzbGlkZXIuc2V0dGluZ3MuYWRhcHRpdmVIZWlnaHQgPSB0cnVlOyB9XG4gICAgICAvLyBzZXQgdGhlIHZpZXdwb3J0IGhlaWdodFxuICAgICAgc2xpZGVyLnZpZXdwb3J0LmhlaWdodChnZXRWaWV3cG9ydEhlaWdodCgpKTtcbiAgICAgIC8vIG1ha2Ugc3VyZSBldmVyeXRoaW5nIGlzIHBvc2l0aW9uZWQganVzdCByaWdodCAoc2FtZSBhcyBhIHdpbmRvdyByZXNpemUpXG4gICAgICBlbC5yZWRyYXdTbGlkZXIoKTtcbiAgICAgIC8vIG9uU2xpZGVyTG9hZCBjYWxsYmFja1xuICAgICAgc2xpZGVyLnNldHRpbmdzLm9uU2xpZGVyTG9hZC5jYWxsKGVsLCBzbGlkZXIuYWN0aXZlLmluZGV4KTtcbiAgICAgIC8vIHNsaWRlciBoYXMgYmVlbiBmdWxseSBpbml0aWFsaXplZFxuICAgICAgc2xpZGVyLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIC8vIGFkZCB0aGUgcmVzaXplIGNhbGwgdG8gdGhlIHdpbmRvd1xuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5yZXNwb25zaXZlKSB7ICQod2luZG93KS5vbigncmVzaXplJywgcmVzaXplV2luZG93KTsgfVxuICAgICAgLy8gaWYgYXV0byBpcyB0cnVlIGFuZCBoYXMgbW9yZSB0aGFuIDEgcGFnZSwgc3RhcnQgdGhlIHNob3dcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYXV0byAmJiBzbGlkZXIuc2V0dGluZ3MuYXV0b1N0YXJ0ICYmIChnZXRQYWdlclF0eSgpID4gMSB8fCBzbGlkZXIuc2V0dGluZ3MuYXV0b1NsaWRlRm9yT25lUGFnZSkpIHsgaW5pdEF1dG8oKTsgfVxuICAgICAgLy8gaWYgdGlja2VyIGlzIHRydWUsIHN0YXJ0IHRoZSB0aWNrZXJcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MudGlja2VyKSB7IGluaXRUaWNrZXIoKTsgfVxuICAgICAgLy8gaWYgcGFnZXIgaXMgcmVxdWVzdGVkLCBtYWtlIHRoZSBhcHByb3ByaWF0ZSBwYWdlciBsaW5rIGFjdGl2ZVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5wYWdlcikgeyB1cGRhdGVQYWdlckFjdGl2ZShzbGlkZXIuc2V0dGluZ3Muc3RhcnRTbGlkZSk7IH1cbiAgICAgIC8vIGNoZWNrIGZvciBhbnkgdXBkYXRlcyB0byB0aGUgY29udHJvbHMgKGxpa2UgaGlkZUNvb
98nRyb2xPbkVuZCB1cGRhdGVzKVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5jb250cm9scykgeyB1cGRhdGVEaXJlY3Rpb25Db250cm9scygpOyB9XG4gICAgICAvLyBpZiB0b3VjaEVuYWJsZWQgaXMgdHJ1ZSwgc2V0dXAgdGhlIHRvdWNoIGV2ZW50c1xuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy50b3VjaEVuYWJsZWQgJiYgIXNsaWRlci5zZXR0aW5ncy50aWNrZXIpIHsgaW5pdFRvdWNoKCk7IH1cbiAgICAgIC8vIGlmIGtleWJvYXJkRW5hYmxlZCBpcyB0cnVlLCBzZXR1cCB0aGUga2V5Ym9hcmQgZXZlbnRzXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmtleWJvYXJkRW5hYmxlZCAmJiAhc2xpZGVyLnNldHRpbmdzLnRpY2tlcikge1xuICAgICAgICAkKGRvY3VtZW50KS5rZXlkb3duKGtleVByZXNzKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY2FsY3VsYXRlZCBoZWlnaHQgb2YgdGhlIHZpZXdwb3J0LCB1c2VkIHRvIGRldGVybWluZSBlaXRoZXIgYWRhcHRpdmVIZWlnaHQgb3IgdGhlIG1heEhlaWdodCB2YWx1ZVxuICAgICAqL1xuICAgIHZhciBnZXRWaWV3cG9ydEhlaWdodCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGhlaWdodCA9IDA7XG4gICAgICAvLyBmaXJzdCBkZXRlcm1pbmUgd2hpY2ggY2hpbGRyZW4gKHNsaWRlcykgc2hvdWxkIGJlIHVzZWQgaW4gb3VyIGhlaWdodCBjYWxjdWxhdGlvblxuICAgICAgdmFyIGNoaWxkcmVuID0gJCgpO1xuICAgICAgLy8gaWYgbW9kZSBpcyBub3QgXCJ2ZXJ0aWNhbFwiIGFuZCBhZGFwdGl2ZUhlaWdodCBpcyBmYWxzZSwgaW5jbHVkZSBhbGwgY2hpbGRyZW5cbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSAhPT0gJ3ZlcnRpY2FsJyAmJiAhc2xpZGVyLnNldHRpbmdzLmFkYXB0aXZlSGVpZ2h0KSB7XG4gICAgICAgIGNoaWxkcmVuID0gc2xpZGVyLmNoaWxkcmVuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaWYgbm90IGNhcm91c2VsLCByZXR1cm4gdGhlIHNpbmdsZSBhY3RpdmUgY2hpbGRcbiAgICAgICAgaWYgKCFzbGlkZXIuY2Fyb3VzZWwpIHtcbiAgICAgICAgICBjaGlsZHJlbiA9IHNsaWRlci5jaGlsZHJlbi5lcShzbGlkZXIuYWN0aXZlLmluZGV4KTtcbiAgICAgICAgLy8gaWYgY2Fyb3VzZWwsIHJldHVybiBhIHNsaWNlIG9mIGNoaWxkcmVuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZ2V0IHRoZSBpbmRpdmlkdWFsIHNsaWRlIGluZGV4XG4gICAgICAgICAgdmFyIGN1cnJlbnRJbmRleCA9IHNsaWRlci5zZXR0aW5ncy5tb3ZlU2xpZGVzID09PSAxID8gc2xpZGVyLmFjdGl2ZS5pbmRleCA6IHNsaWRlci5hY3RpdmUuaW5kZXggKiBnZXRNb3ZlQnkoKTtcbiAgICAgICAgICAvLyBhZGQgdGhlIGN1cnJlbnQgc2xpZGUgdG8gdGhlIGNoaWxkcmVuXG4gICAgICAgICAgY2hpbGRyZW4gPSBzbGlkZXIuY2hpbGRyZW4uZXEoY3VycmVudEluZGV4KTtcbiAgICAgICAgICAvLyBjeWNsZSB0aHJvdWdoIHRoZSByZW1haW5pbmcgXCJzaG93aW5nXCIgc2xpZGVzXG4gICAgICAgICAgZm9yIChpID0gMTsgaSA8PSBzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAvLyBpZiBsb29wZWQgYmFjayB0byB0aGUgc3RhcnRcbiAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXggKyBpID49IHNsaWRlci5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbi5hZGQoc2xpZGVyLmNoaWxkcmVuLmVxKGkgLSAxKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuLmFkZChzbGlkZXIuY2hpbGRyZW4uZXEoY3VycmVudEluZGV4ICsgaSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gaWYgXCJ2ZXJ0aWNhbFwiIG1vZGUsIGNhbGN1bGF0ZSB0aGUgc3VtIG9mIHRoZSBoZWlnaHRzIG9mIHRoZSBjaGlsZHJlblxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAndmVydGljYWwnKSB7XG4gICAgICAgIGNoaWxkcmVuLmVhY2goZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgICBoZWlnaHQgKz0gJCh0aGlzKS5vdXRlckhlaWdodCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gYWRkIHVzZXItc3VwcGxpZWQgbWFyZ2luc1xuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luID4gMCkge1xuICAgICAgICAgIGhlaWdodCArPSBzbGlkZXIuc2V0dGluZ3Muc2xpZGVNYXJnaW4gKiAoc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcyAtIDEpO1xuICAgICAgICB9XG4gICAgICAvLyBpZiBub3QgXCJ2ZXJ0aWNhbFwiIG1vZGUsIGNhbGN1bGF0ZSB0aGUgbWF4IGhlaWdodCBvZiB0aGUgY2hpbGRyZW5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhlaWdodCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIGNoaWxkcmVuLm1hcChmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gJCh0aGlzKS5vdXRlckhlaWdodChmYWxzZSk7XG4gICAgICAgIH0pLmdldCgpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNsaWRlci52aWV3cG9ydC5jc3MoJ2JveC1zaXppbmcnKSA9PT0gJ2JvcmRlci1ib3gnKSB7XG4gICAgICAgIGhlaWdodCArPSBwYXJzZUZsb2F0KHNsaWRlci52aWV3cG9ydC5jc3MoJ3BhZGRpbmctdG9wJykpICsgcGFyc2VGbG9hdChzbGlkZXIudmlld3BvcnQuY3NzKCdwYWRkaW5nLWJvdHRvbScpKSArXG4gICAgICAgICAgICAgIHBhcnNlRmxvYXQoc2xpZGVyLnZpZXdwb3J0LmNzcygnYm9yZGVyLXRvcC13aWR0aCcpKSArIHBhcnNlRmxvYXQoc2xpZGVyLnZpZXdwb3J0LmNzcygnYm9yZGVyLWJvdHRvbS13aWR0aCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoc2xpZGVyLnZpZXdwb3J0LmNzcygnYm94LXNpemluZycpID09PSAncGFkZGluZy1ib3gnKSB7XG4gICAgICAgIGhlaWdodCArPSBwYXJzZUZsb2F0KHNsaWRlci52aWV3cG9ydC5jc3MoJ3BhZGRpbmctdG9wJykpICsgcGFyc2VGbG9hdChzbGlkZXIudmlld3BvcnQuY3NzKCdwYWRkaW5nLWJvdHRvbScpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY2FsY3VsYXRlZCB3aWR0aCB0byBiZSB1c2VkIGZvciB0aGUgb3V0ZXIgd3JhcHBlciAvIHZpZXdwb3J0XG4gICAgICovXG4gICAgdmFyIGdldFZpZXdwb3J0TWF4V2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB3aWR0aCA9ICcxMDAlJztcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3Muc2xpZGVXaWR0aCA+IDApIHtcbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbn
98RhbCcpIHtcbiAgICAgICAgICB3aWR0aCA9IChzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzICogc2xpZGVyLnNldHRpbmdzLnNsaWRlV2lkdGgpICsgKChzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzIC0gMSkgKiBzbGlkZXIuc2V0dGluZ3Muc2xpZGVNYXJnaW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdpZHRoID0gc2xpZGVyLnNldHRpbmdzLnNsaWRlV2lkdGg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB3aWR0aDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY2FsY3VsYXRlZCB3aWR0aCB0byBiZSBhcHBsaWVkIHRvIGVhY2ggc2xpZGVcbiAgICAgKi9cbiAgICB2YXIgZ2V0U2xpZGVXaWR0aCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5ld0VsV2lkdGggPSBzbGlkZXIuc2V0dGluZ3Muc2xpZGVXaWR0aCwgLy8gc3RhcnQgd2l0aCBhbnkgdXNlci1zdXBwbGllZCBzbGlkZSB3aWR0aFxuICAgICAgd3JhcFdpZHRoICAgICAgPSBzbGlkZXIudmlld3BvcnQud2lkdGgoKTsgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHZpZXdwb3J0IHdpZHRoXG4gICAgICAvLyBpZiBzbGlkZSB3aWR0aCB3YXMgbm90IHN1cHBsaWVkLCBvciBpcyBsYXJnZXIgdGhhbiB0aGUgdmlld3BvcnQgdXNlIHRoZSB2aWV3cG9ydCB3aWR0aFxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5zbGlkZVdpZHRoID09PSAwIHx8XG4gICAgICAgIChzbGlkZXIuc2V0dGluZ3Muc2xpZGVXaWR0aCA+IHdyYXBXaWR0aCAmJiAhc2xpZGVyLmNhcm91c2VsKSB8fFxuICAgICAgICBzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICBuZXdFbFdpZHRoID0gd3JhcFdpZHRoO1xuICAgICAgLy8gaWYgY2Fyb3VzZWwsIHVzZSB0aGUgdGhyZXNob2xkcyB0byBkZXRlcm1pbmUgdGhlIHdpZHRoXG4gICAgICB9IGVsc2UgaWYgKHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXMgPiAxICYmIHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgaWYgKHdyYXBXaWR0aCA+IHNsaWRlci5tYXhUaHJlc2hvbGQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3RWxXaWR0aDtcbiAgICAgICAgfSBlbHNlIGlmICh3cmFwV2lkdGggPCBzbGlkZXIubWluVGhyZXNob2xkKSB7XG4gICAgICAgICAgbmV3RWxXaWR0aCA9ICh3cmFwV2lkdGggLSAoc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luICogKHNsaWRlci5zZXR0aW5ncy5taW5TbGlkZXMgLSAxKSkpIC8gc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcztcbiAgICAgICAgfSBlbHNlIGlmIChzbGlkZXIuc2V0dGluZ3Muc2hyaW5rSXRlbXMpIHtcbiAgICAgICAgICBuZXdFbFdpZHRoID0gTWF0aC5mbG9vcigod3JhcFdpZHRoICsgc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luKSAvIChNYXRoLmNlaWwoKHdyYXBXaWR0aCArIHNsaWRlci5zZXR0aW5ncy5zbGlkZU1hcmdpbikgLyAobmV3RWxXaWR0aCArIHNsaWRlci5zZXR0aW5ncy5zbGlkZU1hcmdpbikpKSAtIHNsaWRlci5zZXR0aW5ncy5zbGlkZU1hcmdpbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXdFbFdpZHRoO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygc2xpZGVzIGN1cnJlbnRseSB2aXNpYmxlIGluIHRoZSB2aWV3cG9ydCAoaW5jbHVkZXMgcGFydGlhbGx5IHZpc2libGUgc2xpZGVzKVxuICAgICAqL1xuICAgIHZhciBnZXROdW1iZXJTbGlkZXNTaG93aW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
98XIgc2xpZGVzU2hvd2luZyA9IDEsXG4gICAgICBjaGlsZFdpZHRoID0gbnVsbDtcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnICYmIHNsaWRlci5zZXR0aW5ncy5zbGlkZVdpZHRoID4gMCkge1xuICAgICAgICAvLyBpZiB2aWV3cG9ydCBpcyBzbWFsbGVyIHRoYW4gbWluVGhyZXNob2xkLCByZXR1cm4gbWluU2xpZGVzXG4gICAgICAgIGlmIChzbGlkZXIudmlld3BvcnQud2lkdGgoKSA8IHNsaWRlci5taW5UaHJlc2hvbGQpIHtcbiAgICAgICAgICBzbGlkZXNTaG93aW5nID0gc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcztcbiAgICAgICAgLy8gaWYgdmlld3BvcnQgaXMgbGFyZ2VyIHRoYW4gbWF4VGhyZXNob2xkLCByZXR1cm4gbWF4U2xpZGVzXG4gICAgICAgIH0gZWxzZSBpZiAoc2xpZGVyLnZpZXdwb3J0LndpZHRoKCkgPiBzbGlkZXIubWF4VGhyZXNob2xkKSB7XG4gICAgICAgICAgc2xpZGVzU2hvd2luZyA9IHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXM7XG4gICAgICAgIC8vIGlmIHZpZXdwb3J0IGlzIGJldHdlZW4gbWluIC8gbWF4IHRocmVzaG9sZHMsIGRpdmlkZSB2aWV3cG9ydCB3aWR0aCBieSBmaXJzdCBjaGlsZCB3aWR0aFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNoaWxkV2lkdGggPSBzbGlkZXIuY2hpbGRyZW4uZmlyc3QoKS53aWR0aCgpICsgc2xpZGVyLnNldHRpbmdzLnNsaWRlTWFyZ2luO1xuICAgICAgICAgIHNsaWRlc1Nob3dpbmcgPSBNYXRoLmZsb29yKChzbGlkZXIudmlld3BvcnQud2lkdGgoKSArXG4gICAgICAgICAgICBzbGlkZXIuc2V0dGluZ3Muc2xpZGVNYXJnaW4pIC8gY2hpbGRXaWR0aCkgfHwgMTtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgXCJ2ZXJ0aWNhbFwiIG1vZGUsIHNsaWRlcyBzaG93aW5nIHdpbGwgYWx3YXlzIGJlIG1pblNsaWRlc1xuICAgICAgfSBlbHNlIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICBzbGlkZXNTaG93aW5nID0gc2xpZGVyLnNldHRpbmdzLm1pblNsaWRlcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBzbGlkZXNTaG93aW5nO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcGFnZXMgKG9uZSBmdWxsIHZpZXdwb3J0IG9mIHNsaWRlcyBpcyBvbmUgXCJwYWdlXCIpXG4gICAgICovXG4gICAgdmFyIGdldFBhZ2VyUXR5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
98XIgcGFnZXJRdHkgPSAwLFxuICAgICAgYnJlYWtQb2ludCA9IDAsXG4gICAgICBjb3VudGVyID0gMDtcbiAgICAgIC8vIGlmIG1vdmVTbGlkZXMgaXMgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vdmVTbGlkZXMgPiAwKSB7XG4gICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuaW5maW5pdGVMb29wKSB7XG4gICAgICAgICAgcGFnZXJRdHkgPSBNYXRoLmNlaWwoc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCAvIGdldE1vdmVCeSgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB3aGVuIGJyZWFrcG9pbnQgZ29lcyBhYm92ZSBjaGlsZHJlbiBsZW5ndGgsIGNvdW50ZXIgaXMgdGhlIG51bWJlciBvZiBwYWdlc1xuICAgICAgICAgIHdoaWxlIChicmVha1BvaW50IDwgc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgKytwYWdlclF0eTtcbiAgICAgICAgICAgIGJyZWFrUG9pbnQgPSBjb3VudGVyICsgZ2V0TnVtYmVyU2xpZGVzU2hvd2luZygpO1xuICAgICAgICAgICAgY291bnRlciArPSBzbGlkZXIuc2V0dGluZ3MubW92ZVNsaWRlcyA8PSBnZXROdW1iZXJTbGlkZXNTaG93aW5nKCkgPyBzbGlkZXIuc2V0dGluZ3MubW92ZVNsaWRlcyA6IGdldE51bWJlclNsaWRlc1Nob3dpbmcoKTtcbiAgICAgICAgICB9XG5cdFx0ICByZXR1cm4gY291bnRlcjtcbiAgICAgICAgfVxuICAgICAgLy8gaWYgbW92ZVNsaWRlcyBpcyAwIChhdXRvKSBkaXZpZGUgY2hpbGRyZW4gbGVuZ3RoIGJ5IHNpZGVzIHNob3dpbmcsIHRoZW4gcm91bmQgdXBcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhZ2VyUXR5ID0gTWF0aC5jZWlsKHNsaWRlci5jaGlsZHJlbi5sZW5ndGggLyBnZXROdW1iZXJTbGlkZXNTaG93aW5nKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhZ2VyUXR5O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgaW5kaXZpZHVhbCBzbGlkZXMgYnkgd2hpY2ggdG8gc2hpZnQgdGhlIHNsaWRlclxuICAgICAqL1xuICAgIHZhciBnZXRNb3ZlQnkgPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGlmIG1vdmVTbGlkZXMgd2FzIHNldCBieSB0aGUgdXNlciBhbmQgbW92ZVNsaWRlcyBpcyBsZXNzIHRoYW4gbnVtYmVyIG9mIHNsaWRlcyBzaG93aW5nXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vdmVTbGlkZXMgPiAwICYmIHNsaWRlci5zZXR0aW5ncy5tb3ZlU2xpZGVzIDw9IGdldE51bWJlclNsaWRlc1Nob3dpbmcoKSkge1xuICAgICAgICByZXR1cm4gc2xpZGVyLnNldHRpbmdzLm1vdmVTbGlkZXM7XG4gICAgICB9XG4gICAgICAvLyBpZiBtb3ZlU2xpZGVzIGlzIDAgKGF1dG8pXG4gICAgICByZXR1cm4gZ2V0TnVtYmVyU2xpZGVzU2hvd2luZygpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzbGlkZXIncyAoZWwpIGxlZnQgb3IgdG9wIHBvc2l0aW9uXG4gICAgICovXG4gICAgdmFyIHNldFNsaWRlUG9zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBwb3NpdGlvbiwgbGFzdENoaWxkLCBsYXN0U2hvd2luZ0luZGV4O1xuICAgICAgLy8gaWYgbGFzdCBzbGlkZSwgbm90IGluZmluaXRlIGxvb3AsIGFuZCBudW1iZXIgb2YgY2hpbGRyZW4gaXMgbGFyZ2VyIHRoYW4gc3BlY2lmaWVkIG1heFNsaWRlc1xuICAgICAgaWYgKHNsaWRlci5jaGlsZHJlbi5sZW5ndGggPiBzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzICYmIHNsaWRlci5hY3RpdmUubGFzdCAmJiAhc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCkge1xuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICAgIC8vIGdldCB0aGUgbGFzdCBjaGlsZCdzIHBvc2l0aW9uXG4gICAgICAgICAgbGFzdENoaWxkID0gc2xpZGVyLmNoaWxkcmVuLmxhc3QoKTtcbiAgICAgICAgICBwb3NpdGlvbiA9IGxhc3RDaGlsZC5wb3NpdGlvbigpO1xuICAgICAgICAgIC8vIHNldCB0aGUgbGVmdCBwb3NpdGlvblxuICAgICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkoLShwb3NpdGlvbi5sZWZ0IC0gKHNsaWRlci52aWV3cG9ydC53aWR0aCgpIC0gbGFzdENoaWxkLm91dGVyV2lkdGgoKSkpLCAncmVzZXQnLCAwKTtcbiAgICAgICAgfSBlbHNlIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgIC8vIGdldCB0aGUgbGFzdCBzaG93aW5nIGluZGV4J3MgcG9zaXRpb25cbiAgICAgICAgICBsYXN0U2hvd2luZ0luZGV4ID0gc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCAtIHNsaWRlci5zZXR0aW5ncy5taW5TbGlkZXM7XG4gICAgICAgICAgcG9zaXRpb24gPSBzbGlkZXIuY2hpbGRyZW4uZXEobGFzdFNob3dpbmdJbmRleCkucG9zaXRpb24oKTtcbiAgICAgICAgICAvLyBzZXQgdGhlIHRvcCBwb3NpdGlvblxuICAgICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkoLXBvc2l0aW9uLnRvcCwgJ3Jlc2V0JywgMCk7XG4gICAgICAgIH1cbiAgICAgIC8vIGlmIG5vdCBsYXN0IHNsaWRlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBnZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBzaG93aW5nIHNsaWRlXG4gICAgICAgIHBvc2l0aW9uID0gc2xpZGVyLmNoaWxkcmVuLmVxKHNsaWRlci5hY3RpdmUuaW5kZXggKiBnZXRNb3ZlQnkoKSkucG9zaXRpb24oKTtcbiAgICAgICAgLy8gY2hlY2sgZm9yIGxhc3Qgc2xpZGVcbiAgICAgICAgaWYgKHNsaWRlci5hY3RpdmUuaW5kZXggPT09IGdldFBhZ2VyUXR5KCkgLSAxKSB7IHNsaWRlci5hY3RpdmUubGFzdCA9IHRydWU7IH1cbiAgICAgICAgLy8gc2V0IHRoZSByZXNwZWN0aXZlIHBvc2l0aW9uXG4gICAgICAgIGlmIChwb3NpdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcpIHsgc2V0UG9zaXRpb25Qcm9wZXJ0eSgtcG9zaXRpb24ubGVmdCwgJ3Jlc2V0JywgMCk7IH1cbiAgICAgICAgICBlbHNlIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ3ZlcnRpY2FsJykgeyBzZXRQb3NpdGlvblByb3BlcnR5KC1wb3NpdGlvbi50b3AsICdyZXNldCcsIDApOyB9XG4gICAgICAgI
98H1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgZWwncyBhbmltYXRpbmcgcHJvcGVydHkgcG9zaXRpb24gKHdoaWNoIGluIHR1cm4gd2lsbCBzb21ldGltZXMgYW5pbWF0ZSBlbCkuXG4gICAgICogSWYgdXNpbmcgQ1NTLCBzZXRzIHRoZSB0cmFuc2Zvcm0gcHJvcGVydHkuIElmIG5vdCB1c2luZyBDU1MsIHNldHMgdGhlIHRvcCAvIGxlZnQgcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgKGludClcbiAgICAgKiAgLSB0aGUgYW5pbWF0aW5nIHByb3BlcnR5J3MgdmFsdWVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlIChzdHJpbmcpICdzbGlkZScsICdyZXNldCcsICd0aWNrZXInXG4gICAgICogIC0gdGhlIHR5cGUgb2YgaW5zdGFuY2UgZm9yIHdoaWNoIHRoZSBmdW5jdGlvbiBpcyBiZWluZ1xuICAgICAqXG4gICAgICogQHBhcmFtIGR1cmF0aW9uIChpbnQpXG4gICAgICogIC0gdGhlIGFtb3VudCBvZiB0aW1lIChpbiBtcykgdGhlIHRyYW5zaXRpb24gc2hvdWxkIG9jY3VweVxuICAgICAqXG4gICAgICogQHBhcmFtIHBhcmFtcyAoYXJyYXkpIG9wdGlvbmFsXG4gICAgICogIC0gYW4gb3B0aW9uYWwgcGFyYW1ldGVyIGNvbnRhaW5pbmcgYW55IHZhcmlhYmxlcyB0aGF0IG5lZWQgdG8gYmUgcGFzc2VkIGluXG4gICAgICovXG4gICAgdmFyIHNldFBvc2l0aW9uUHJvcGVydHkgPSBmdW5jdGlvbih2YWx1ZSwgdHlwZSwgZHVyYXRpb24sIHBhcmFtcykge1xuICAgICAgdmFyIGFuaW1hdGVPYmosIHByb3BWYWx1ZTtcbiAgICAgIC8vIHVzZSBDU1MgdHJhbnNmb3JtXG4gICAgICBpZiAoc2xpZGVyLnVzaW5nQ1NTKSB7XG4gICAgICAgIC8vIGRldGVybWluZSB0aGUgdHJhbnNsYXRlM2QgdmFsdWVcbiAgICAgICAgcHJvcFZhbHVlID0gc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICd2ZXJ0aWNhbCcgPyAndHJhbnNsYXRlM2QoMCwgJyArIHZhbHVlICsgJ3B4LCAwKScgOiAndHJhbnNsYXRlM2QoJyArIHZhbHVlICsgJ3B4LCAwLCAwKSc7XG4gICAgICAgIC8vIGFkZCB0aGUgQ1NTIHRyYW5zaXRpb24tZHVyYXRpb25cbiAgICAgICAgZWwuY3NzKCctJyArIHNsaWRlci5jc3NQcmVmaXggKyAnLXRyYW5zaXRpb24tZHVyYXRpb24nLCBkdXJhdGlvbiAvIDEwMDAgKyAncycpO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3NsaWRlJykge1xuICAgICAgICAgIC8vIHNldCB0aGUgcHJvcGVydHkgdmFsdWVcbiAgICAgICAgICBlbC5jc3Moc2xpZGVyLmFuaW1Qcm9wLCBwcm9wVmFsdWUpO1xuICAgICAgICAgIGlmIChkdXJhdGlvbiAhPT0gMCkge1xuICAgICAgICAgICAgLy8gYWRkIGEgY2FsbGJhY2sgbWV0aG9kIC0gZXhlY3V0ZXMgd2hlbiBDU1MgdHJhbnNpdGlvbiBjb21wbGV0ZXNcbiAgICAgICAgICAgIGVsLm9uKCd0cmFuc2l0aW9uZW5kIHdlYmtpdFRyYW5zaXRpb25FbmQgb1RyYW5zaXRpb25FbmQgTVNUcmFuc2l0aW9uRW5kJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAvL21ha2Ugc3VyZSBpdCdzIHRoZSBjb3JyZWN0IG9uZVxuICAgICAgICAgICAgICBpZiAoISQoZS50YXJnZXQpLmlzKGVsKSkgeyByZXR1cm47IH1cbiAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgICBlbC5vZmYoJ3RyYW5zaXRpb25lbmQgd2Via2l0VHJhbnNpdGlvbkVuZCBvVHJhbnNpdGlvbkVuZCBNU1RyYW5zaXRpb25FbmQnKTtcbiAgICAgICAgICAgICAgdXBkYXRlQWZ0ZXJTbGlkZVRyYW5zaXRpb24oKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7IC8vZHVyYXRpb24gPSAwXG4gICAgICAgICAgICB1cGRhdGVBZnRlclNsaWRlVHJhbnNpdGlvbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAncmVzZXQnKSB7XG4gICAgICAgICAgZWwuY3NzKHNsaWRlci5hbmltUHJvcCwgcHJvcFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAndGlja2VyJykge1xuICAgICAgICAgIC8vIG1ha2UgdGhlIHRyYW5zaXRpb24gdXNlICdsaW5lYXInXG4gICAgICAgICAgZWwuY3NzKCctJyArIHNsaWRlci5jc3NQcmVmaXggKyAnLXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uJywgJ2xpbmVhcicpO1xuICAgICAgICAgIGVsLmNzcyhzbGlkZXIuYW5pbVByb3AsIHByb3BWYWx1ZSk7XG4gICAgICAgICAgaWYgKGR1cmF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgICBlbC5vbigndHJhbnNpdGlvbmVuZCB3ZWJraXRUcmFuc2l0aW9uRW5kIG9UcmFuc2l0aW9uRW5kIE1TVHJhbnNpdGlvbkVuZCcsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgaXQncyB0aGUgY29ycmVjdCBvbmVcbiAgICAgICAgICAgICAgaWYgKCEkKGUudGFyZ2V0KS5pcyhlbCkpIHsgcmV0dXJuOyB9XG4gICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgICAgZWwub2ZmKCd0cmFuc2l0aW9uZW5kIHdlYmtpdFRyYW5zaXRpb25FbmQgb1RyYW5zaXRpb25FbmQgTVNUcmFuc2l0aW9uRW5kJyk7XG4gICAgICAgICAgICAgIC8vIHJlc2V0IHRoZSBwb3NpdGlvblxuICAgICAgICAgICAgICBzZXRQb3NpdGlvblByb3BlcnR5KHBhcmFtcy5yZXNldFZhbHVlLCAncmVzZXQnLCAwKTtcbiAgICAgICAgICAgICAgLy8gc3RhcnQgdGhlIGxvb3AgYWdhaW5cbiAgICAgICAgICAgICAgdGlja2VyTG9vcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHsgLy9kdXJhdGlvbiA9IDBcbiAgICAgICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkocGFyYW1zLnJlc2V0VmFsdWUsICdyZXNldCcsIDApO1xuICAgICAgICAgICAgdGlja2VyTG9vcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgLy8gdXNlIEpTIGFuaW1hdGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFuaW1hdGVPYmogPSB7fTtcbiAgICAgICAgYW5pbWF0ZU9ialtzbGlkZXIuYW5pbVByb3BdID0gdmFsdWU7XG4gICAgICAgIGlmICh0eXBlID09PSAnc2xpZGUnKSB7XG4gICAgICAgICAgZWwuYW5pbWF0ZShhbmltYXRlT2JqLCBkdXJhdGlvbiwgc2xpZGVyLnNldHRpbmdzLmVhc2luZywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB1cGRhdGVBZnRlclNsaWRlVHJhbnNpdGlvbigpO1xuICAgICAgICAgI
98H0pO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdyZXNldCcpIHtcbiAgICAgICAgICBlbC5jc3Moc2xpZGVyLmFuaW1Qcm9wLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RpY2tlcicpIHtcbiAgICAgICAgICBlbC5hbmltYXRlKGFuaW1hdGVPYmosIGR1cmF0aW9uLCAnbGluZWFyJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBzZXRQb3NpdGlvblByb3BlcnR5KHBhcmFtcy5yZXNldFZhbHVlLCAncmVzZXQnLCAwKTtcbiAgICAgICAgICAgIC8vIHJ1biB0aGUgcmVjdXJzaXZlIGxvb3AgYWZ0ZXIgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aWNrZXJMb29wKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUG9wdWxhdGVzIHRoZSBwYWdlciB3aXRoIHByb3BlciBhbW91bnQgb2YgcGFnZXNcbiAgICAgKi9cbiAgICB2YXIgcG9wdWxhdGVQYWdlciA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHBhZ2VySHRtbCA9ICcnLFxuICAgICAgbGlua0NvbnRlbnQgPSAnJyxcbiAgICAgIHBhZ2VyUXR5ID0gZ2V0UGFnZXJRdHkoKTtcbiAgICAgIC8vIGxvb3AgdGhyb3VnaCBlYWNoIHBhZ2VyIGl0ZW1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFnZXJRdHk7IGkrKykge1xuICAgICAgICBsaW5rQ29udGVudCA9ICcnO1xuICAgICAgICAvLyBpZiBhIGJ1aWxkUGFnZXIgZnVuY3Rpb24gaXMgc3VwcGxpZWQsIHVzZSBpdCB0byBnZXQgcGFnZXIgbGluayB2YWx1ZSwgZWxzZSB1c2UgaW5kZXggKyAxXG4gICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYnVpbGRQYWdlciAmJiAkLmlzRnVuY3Rpb24oc2xpZGVyLnNldHRpbmdzLmJ1aWxkUGFnZXIpIHx8IHNsaWRlci5zZXR0aW5ncy5wYWdlckN1c3RvbSkge1xuICAgICAgICAgIGxpbmtDb250ZW50ID0gc2xpZGVyLnNldHRpbmdzLmJ1aWxkUGFnZXIoaSk7XG4gICAgICAgICAgc2xpZGVyLnBhZ2VyRWwuYWRkQ2xhc3MoJ2J4LWN1c3RvbS1wYWdlcicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpbmtDb250ZW50ID0gaSArIDE7XG4gICAgICAgICAgc2xpZGVyLnBhZ2VyRWwuYWRkQ2xhc3MoJ2J4LWRlZmF1bHQtcGFnZXInKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB2YXIgbGlua0NvbnRlbnQgPSBzbGlkZXIuc2V0dGluZ3MuYnVpbGRQYWdlciAmJiAkLmlzRnVuY3Rpb24oc2xpZGVyLnNldHRpbmdzLmJ1aWxkUGFnZXIpID8gc2xpZGVyLnNldHRpbmdzLmJ1aWxkUGFnZXIoaSkgOiBpICsgMTtcbiAgICAgICAgLy8gYWRkIHRoZSBtYXJrdXAgdG8gdGhlIHN0cmluZ1xuICAgICAgICBwYWdlckh0bWwgKz0gJzxkaXYgY2xhc3M9XCJieC1wYWdlci1pdGVtXCI+PGEgaHJlZj1cIlwiIGRhdGEtc2xpZGUtaW5kZXg9XCInICsgaSArICdcIiBjbGFzcz1cImJ4LXBhZ2VyLWxpbmtcIj4nICsgbGlua0NvbnRlbnQgKyAnPC9hPjwvZGl2Pic7XG4gICAgICB9XG4gICAgICAvLyBwb3B1bGF0ZSB0aGUgcGFnZXIgZWxlbWVudCB3aXRoIHBhZ2VyIGxpbmtzXG4gICAgICBzbGlkZXIucGFnZXJFbC5odG1sKHBhZ2VySHRtbCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFwcGVuZHMgdGhlIHBhZ2VyIHRvIHRoZSBjb250cm9scyBlbGVtZW50XG4gICAgICovXG4gICAgdmFyIGFwcGVuZFBhZ2VyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy5wYWdlckN1c3RvbSkge1xuICAgICAgICAvLyBjcmVhdGUgdGhlIHBhZ2VyIERPTSBlbGVtZW50XG4gICAgICAgIHNsaWRlci5wYWdlckVsID0gJCgnPGRpdiBjbGFzcz1cImJ4LXBhZ2VyXCIgLz4nKTtcbiAgICAgICAgLy8gaWYgYSBwYWdlciBzZWxlY3RvciB3YXMgc3VwcGxpZWQsIHBvcHVsYXRlIGl0IHdpdGggdGhlIHBhZ2VyXG4gICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MucGFnZXJTZWxlY3Rvcikge1xuICAgICAgICAgICQoc2xpZGVyLnNldHRpbmdzLnBhZ2VyU2VsZWN0b3IpLmh0bWwoc2xpZGVyLnBhZ2VyRWwpO1xuICAgICAgICAvLyBpZiBubyBwYWdlciBzZWxlY3RvciB3YXMgc3VwcGxpZWQsIGFkZCBpdCBhZnRlciB0aGUgd3JhcHBlclxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNsaWRlci5jb250cm9scy5lbC5hZGRDbGFzcygnYngtaGFzLXBhZ2VyJykuYXBwZW5kKHNsaWRlci5wYWdlckVsKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwb3B1bGF0ZSB0aGUgcGFnZXJcbiAgICAgICAgcG9wdWxhdGVQYWdlcigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2xpZGVyLnBhZ2VyRWwgPSAkKHNsaWRlci5zZXR0aW5ncy5wYWdlckN1c3RvbSk7XG4gICAgICB9XG4gICAgICAvLyBhc3NpZ24gdGhlIHBhZ2VyIGNsaWNrIGJpbmRpbmdcbiAgICAgIHNsaWRlci5wYWdlckVsLm9uKCdjbGljayB0b3VjaGVuZCcsICdhJywgY2xpY2tQYWdlckJpbmQpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBcHBlbmRzIHByZXYgLyBuZXh0IGNvbnRyb2xzIHRvIHRoZSBjb250cm9scyBlbGVtZW50XG4gICAgICovXG4gICAgdmFyIGFwcGVuZENvbnRyb2xzID0gZnVuY3Rpb24oKSB7XG4gICAgICBzbGlkZXIuY29udHJvbHMubmV4dCA9ICQoJzxhIGNsYXNzPVwiYngtbmV4dFwiIGhyZWY9XCJcIj4nICsgc2xpZGVyLnNldHRpbmdzLm5leHRUZXh0ICsgJzwvYT4nKTtcbiAgICAgIHNsaWRlci5jb250cm9scy5wcmV2ID0gJCgnPGEgY2xhc3M9XCJieC1wcmV2XCIgaHJlZj1cIlwiPicgKyBzbGlkZXIuc2V0dGluZ3MucHJldlRleHQgKyAnPC9hPicpO1xuICAgICAgLy8gYWRkIGNsaWNrIGFjdGlvbnMgdG8gdGhlIGNvbnRyb2xzXG4gICAgICBzbGlkZXIuY29udHJvbHMubmV4dC5vbignY2xpY2sgdG91Y2hlbmQnLCBjbGlja05leHRCaW5kKTtcbiAgICAgIHNsaWRlci5jb250cm9scy5wcmV2Lm9uKCdjbGljayB0b3VjaGVuZCcsIGNsaWNrUHJldkJpbmQpO1xuICAgICAgLy8gaWYgbmV4dFNlbGVjdG9yIHdhcyBzdXBwbGllZCwgcG9wdWxhdGUgaXRcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubmV4dFNlbGVjdG9yKSB7XG4gICAgICAgICQoc2xpZGVyLnNldHRpbmdzLm5leHRTZWxlY3RvcikuYXBwZW5kKHNsaWRlci5jb250cm9scy5uZXh0KTtcbiAgICAgIH1cbiAgICAgIC8vIGlmIHByZXZTZWxlY3RvciB3YXMgc3VwcGxpZWQsIHBvcHVsYXRlIGl0XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLnByZXZTZWxlY3Rvcikge1xuICAgICAgICAkKHNsaWRlci5zZXR0aW5ncy5wcmV2U2VsZWN0b3IpLmFwcGVuZChzbGlkZXIuY29udHJvbHMucHJldik7XG4gICAgICB9XG4gICAgICAvLyBpZiBubyBjdXN0b20gc2VsZWN0b3JzIHdlcmUgc3VwcGxpZWRcbiAgICAgIGlmICghc2xpZGVyLnNldHRpbmdzLm5leHRTZWxlY3RvciAmJiAhc2xpZGVyLnNldHRpbmdzLnByZXZTZWxlY3Rvcikge1xuICAgICAgICAvLyBhZGQgdGhlIGNvbnRyb2xzIHRvIHRoZSBET01cbiAgICAgICAgc2xpZGVyLmNvbnRyb2xzLmRpcmVjdGlvbkVsID0gJCgnPGRpdiBjbGFzcz1cImJ4LWNvbnRyb2xzLWRpcmVjdGlvblwiIC8+Jyk7XG4gICAgICAgIC8vIGFkZCB0aGUgY29udHJvbCBlbGVtZW50cyB0byB0aGUgZGlyZWN0aW9uRWxcbiAgICAgICAgc2xpZGVyLmNvbnRyb2xzLmRpcmVjdGlvbkVsLmFwcGVuZChzbGlkZXIuY29udHJvbHMucHJldikuYXBwZW5kKHNsaWRlci5jb250cm9scy5uZXh0KTtcbiAgICAgICAgLy8gc2xpZGVyLnZpZXdwb3J0LmFwcGVuZChzbGlkZXIuY29udHJvbHMuZGlyZWN0aW9uRWwpO1xuICAgICAgICBzbGlkZXIuY29udHJvbHMuZWwuYWRkQ2xhc3MoJ2J4LWhhcy1jb250cm9scy1kaXJlY3Rpb24nKS5hcHBlbmQoc2xpZGVyLmNvbnRyb2xzLmRpcmVjdGlvbkVsKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQXBwZW5kcyBzdGFydCAvIHN0b3AgYXV0byBjb250cm9scyB0byB0aGUgY29udHJvbHMgZWxlbWVudFxuICAgICAqL1xuICAgIHZhciBhcHBlbmRDb250cm9sc0F1dG8gPSBmdW5jdGlvbigpIHtcbiAgICAgIHNsaWRlci5jb250cm9scy5zdGFydCA9ICQoJzxkaXYgY2xhc3M9XCJieC1jb250cm9scy1hdXRvLWl0ZW1cIj48YSBjbGFzcz1cImJ4LXN0YXJ0XCIgaHJlZj1cIlwiPicgKyBzbGlkZXIuc2V0dGluZ3Muc3RhcnRUZXh0ICsgJzwvYT48L2Rpdj4nKTtcbiAgICAgIHNsaWRlci5jb250cm9scy5zdG9wID0gJCgnPGRpdiBjbGFzcz1cImJ4LWNvbnRyb2xzLWF1dG8taXRlbVwiPjxhIGNsYXNzPVwiYngtc3RvcFwiIGhyZWY9XCJcIj4nICsgc2xpZGVyLnNldHRpbmdzLnN0b3BUZXh0ICsgJzwvYT48L2Rpdj4nKTtcbiAgICAgIC8vIGFkZCB0aGUgY29udHJvbHMgdG8gdGhlIERPTVxuICAgICAgc2xpZGVyLmNvbnRyb2xzLmF1dG9FbCA9ICQoJzxkaXYgY2xhc3M9XCJieC1jb250cm9scy1hdXRvXCIgLz4nKTtcbiAgICAgIC8vIG9uIGNsaWNrIGFjdGlvbnMgdG8gdGhlIGNvbnRyb2xzXG4gICAgICBzbGlkZXIuY29udHJvbHMuYXV0b0VsLm9uKCdjbGljaycsICcuYngtc3RhcnQnLCBjbGlja1N0YXJ0QmluZCk7XG4gICAgICBzbGlkZXIuY29udHJvbHMuYXV0b0VsLm9uKCdjbGljaycsICcuYngtc3RvcCcsIGNsaWNrU3RvcEJpbmQpO1xuICAgICAgLy8gaWYgYXV0b0NvbnRyb2xzQ29tYmluZSwgaW5zZXJ0IG9ubHkgdGhlIFwic3RhcnRcIiBjb250cm9sXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmF1dG9Db250cm9sc0NvbWJpbmUpIHtcbiAgICAgICAgc2xpZGVyLmNvbnRyb2xzLmF1dG9FbC5hcHBlbmQoc2xpZGVyLmNvbnRyb2xzLnN0YXJ0KTtcbiAgICAgIC8vIGlmIGF1dG9Db250cm9sc0NvbWJpbmUgaXMgZmFsc2UsIGluc2VydCBib3RoIGNvbnRyb2xzXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuY29udHJvbHMuYXV0b0VsLmFwcGVuZChzbGlkZXIuY29udHJvbHMuc3RhcnQpLmFwcGVuZChzbGlkZXIuY29udHJvbHMuc3RvcCk7XG4gICAgICB9XG4gICAgICAvLyBpZiBhdXRvIGNvbnRyb2xzIHNlbGVjdG9yIHdhcyBzdXBwbGllZCwgcG9wdWxhdGUgaXQgd2l0aCB0aGUgY29udHJvbHNcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYXV0b0NvbnRyb2xzU2VsZWN0b3IpIHtcbiAgICAgICAgJChzbGlkZXIuc2V0dGluZ3MuYXV0b0NvbnRyb2xzU2VsZWN0b3IpLmh0bWwoc2xpZGVyLmNvbnRyb2xzLmF1dG9FbCk7XG4gICAgICAvLyBpZiBhdXRvIGNvbnRyb2xzIHNlbGVjdG9yIHdhcyBub3Qgc3VwcGxpZWQsIGFkZCBpdCBhZnRlciB0aGUgd3JhcHBlclxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2xpZGVyLmNvbnRyb2xzLmVsLmFkZENsYXNzKCdieC1oYXMtY29udHJvbHMtYXV0bycpLmFwcGVuZChzbGlkZXIuY29udHJvbHMuYXV0b0VsKTtcbiAgICAgIH1cbiAgICAgIC8vIHVwZGF0ZSB0aGUgYXV0byBjb250cm9sc1xuICAgICAgdXBkYXRlQXV0b0NvbnRyb2xzKHNsaWRlci5zZXR0aW5ncy5hdXRvU3RhcnQgPyAnc3RvcCcgOiAnc3RhcnQnKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQXBwZW5kcyBpbWFnZSBjYXB0aW9ucyB0byB0aGUgRE9NXG4gICAgICovXG4gICAgdmFyIGFwcGVuZENhcHRpb25zID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBjeWNsZSB0aHJvdWdoIGVhY2ggY2hpbGRcbiAgICAgIHNsaWRlci5jaGlsZHJlbi5lYWNoKGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICAgIC8vIGdldCB0aGUgaW1hZ2UgdGl0bGUgYXR0cmlidXRlXG4gICAgICAgI
98HZhciB0aXRsZSA9ICQodGhpcykuZmluZCgnaW1nOmZpcnN0JykuYXR0cigndGl0bGUnKTtcbiAgICAgICAgLy8gYXBwZW5kIHRoZSBjYXB0aW9uXG4gICAgICAgIGlmICh0aXRsZSAhPT0gdW5kZWZpbmVkICYmICgnJyArIHRpdGxlKS5sZW5ndGgpIHtcbiAgICAgICAgICAkKHRoaXMpLmFwcGVuZCgnPGRpdiBjbGFzcz1cImJ4LWNhcHRpb25cIj48c3Bhbj4nICsgdGl0bGUgKyAnPC9zcGFuPjwvZGl2PicpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ2xpY2sgbmV4dCBiaW5kaW5nXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZSAoZXZlbnQpXG4gICAgICogIC0gRE9NIGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHZhciBjbGlja05leHRCaW5kID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHNsaWRlci5jb250cm9scy5lbC5oYXNDbGFzcygnZGlzYWJsZWQnKSkgeyByZXR1cm47IH1cbiAgICAgIC8vIGlmIGF1dG8gc2hvdyBpcyBydW5uaW5nLCBzdG9wIGl0XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmF1dG8gJiYgc2xpZGVyLnNldHRpbmdzLnN0b3BBdXRvT25DbGljaykgeyBlbC5zdG9wQXV0bygpOyB9XG4gICAgICBlbC5nb1RvTmV4dFNsaWRlKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENsaWNrIHByZXYgYmluZGluZ1xuICAgICAqXG4gICAgICogQHBhcmFtIGUgKGV2ZW50KVxuICAgICAqICAtIERPTSBldmVudCBvYmplY3RcbiAgICAgKi9cbiAgICB2YXIgY2xpY2tQcmV2QmluZCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChzbGlkZXIuY29udHJvbHMuZWwuaGFzQ2xhc3MoJ2Rpc2FibGVkJykpIHsgcmV0dXJuOyB9XG4gICAgICAvLyBpZiBhdXRvIHNob3cgaXMgcnVubmluZywgc3RvcCBpdFxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hdXRvICYmIHNsaWRlci5zZXR0aW5ncy5zdG9wQXV0b09uQ2xpY2spIHsgZWwuc3RvcEF1dG8oKTsgfVxuICAgICAgZWwuZ29Ub1ByZXZTbGlkZSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBzdGFydCBiaW5kaW5nXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZSAoZXZlbnQpXG4gICAgICogIC0gRE9NIGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHZhciBjbGlja1N0YXJ0QmluZCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGVsLnN0YXJ0QXV0bygpO1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBzdG9wIGJpbmRpbmdcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIChldmVudClcbiAgICAgKiAgLSBET00gZXZlbnQgb2JqZWN0XG4gICAgICovXG4gICAgdmFyIGNsaWNrU3RvcEJpbmQgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlbC5zdG9wQXV0bygpO1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBwYWdlciBiaW5kaW5nXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZSAoZXZlbnQpXG4gICAgICogIC0gRE9NIGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHZhciBjbGlja1BhZ2VyQmluZCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciBwYWdlckxpbmssIHBhZ2VySW5kZXg7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoc2xpZGVyLmNvbnRyb2xzLmVsLmhhc0NsYXNzKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIGlmIGF1dG8gc2hvdyBpcyBydW5uaW5nLCBzdG9wIGl0XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmF1dG8gICYmIHNsaWRlci5zZXR0aW5ncy5zdG9wQXV0b09uQ2xpY2spIHsgZWwuc3RvcEF1dG8oKTsgfVxuICAgICAgcGFnZXJMaW5rID0gJChlLmN1cnJlbnRUYXJnZXQpO1xuICAgICAgaWYgKHBhZ2VyTGluay5hdHRyKCdkYXRhLXNsaWRlLWluZGV4JykgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwYWdlckluZGV4ID0gcGFyc2VJbnQocGFnZXJMaW5rLmF0dHIoJ2RhdGEtc2xpZGUtaW5kZXgnKSk7XG4gICAgICAgIC8vIGlmIGNsaWNrZWQgcGFnZXIgbGluayBpcyBub3QgYWN0aXZlLCBjb250aW51ZSB3aXRoIHRoZSBnb1RvU2xpZGUgY2FsbFxuICAgICAgICBpZiAocGFnZXJJbmRleCAhPT0gc2xpZGVyLmFjdGl2ZS5pbmRleCkgeyBlbC5nb1RvU2xpZGUocGFnZXJJbmRleCk7IH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgcGFnZXIgbGlua3Mgd2l0aCBhbiBhY3RpdmUgY2xhc3NcbiAgICAgKlxuICAgICAqIEBwYXJhbSBzbGlkZUluZGV4IChpbnQpXG4gICAgICogIC0gaW5kZXggb2Ygc2xpZGUgdG8gbWFrZSBhY3RpdmVcbiAgICAgKi9cbiAgICB2YXIgdXBkYXRlUGFnZXJBY3RpdmUgPSBmdW5jdGlvbihzbGlkZUluZGV4KSB7XG4gICAgICAvLyBpZiBcInNob3J0XCIgcGFnZXIgdHlwZVxuICAgICAgdmFyIGxlbiA9IHNsaWRlci5jaGlsZHJlbi5sZW5ndGg7IC8vIG5iIG9mIGNoaWxkcmVuXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLnBhZ2VyVHlwZSA9PT0gJ3Nob3J0Jykge1xuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1heFNsaWRlcyA+IDEpIHtcbiAgICAgICAgICBsZW4gPSBNYXRoLmNlaWwoc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCAvIHNsaWRlci5zZXR0aW5ncy5tYXhTbGlkZXMpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci5wYWdlckVsLmh0bWwoKHNsaWRlSW5kZXggKyAxKSArIHNsaWRlci5zZXR0aW5ncy5wYWdlclNob3J0U2VwYXJhdG9yICsgbGVuKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIGFsbCBwYWdlciBhY3RpdmUgY2xhc3Nlc1xuICAgICAgc2xpZGVyLnBhZ2VyRWwuZmluZCgnYScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgIC8vIGFwcGx5IHRoZSBhY3RpdmUgY2xhc3MgZm9yIGFsbCBwYWdlcnNcbiAgICAgIHNsaWRlci5wYWdlckVsLmVhY2goZnVuY3Rpb24oaSwgZWwpIHsgJChlbCkuZmluZCgnYScpLmVxKHNsaWRlSW5kZXgpLmFkZENsYXNzKCdhY3RpdmUnKTsgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIG5lZWRlZCBhY3Rpb25zIGFmdGVyIGEgc2xpZGUgdHJhbnNpdGlvblxuICAgICAqL1xuICAgIHZhciB1cGRhdGVBZnRlclNsaWRlVHJhbnNpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gaWYgaW5maW5pdGUgbG9vcCBpcyB0cnVlXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCkge1xuICAgICAgICB2Y
98XIgcG9zaXRpb24gPSAnJztcbiAgICAgICAgLy8gZmlyc3Qgc2xpZGVcbiAgICAgICAgaWYgKHNsaWRlci5hY3RpdmUuaW5kZXggPT09IDApIHtcbiAgICAgICAgICAvLyBzZXQgdGhlIG5ldyBwb3NpdGlvblxuICAgICAgICAgIHBvc2l0aW9uID0gc2xpZGVyLmNoaWxkcmVuLmVxKDApLnBvc2l0aW9uKCk7XG4gICAgICAgIC8vIGNhcm91c2VsLCBsYXN0IHNsaWRlXG4gICAgICAgIH0gZWxzZSBpZiAoc2xpZGVyLmFjdGl2ZS5pbmRleCA9PT0gZ2V0UGFnZXJRdHkoKSAtIDEgJiYgc2xpZGVyLmNhcm91c2VsKSB7XG4gICAgICAgICAgcG9zaXRpb24gPSBzbGlkZXIuY2hpbGRyZW4uZXEoKGdldFBhZ2VyUXR5KCkgLSAxKSAqIGdldE1vdmVCeSgpKS5wb3NpdGlvbigpO1xuICAgICAgICAvLyBsYXN0IHNsaWRlXG4gICAgICAgIH0gZWxzZSBpZiAoc2xpZGVyLmFjdGl2ZS5pbmRleCA9PT0gc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBwb3NpdGlvbiA9IHNsaWRlci5jaGlsZHJlbi5lcShzbGlkZXIuY2hpbGRyZW4ubGVuZ3RoIC0gMSkucG9zaXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb24pIHtcbiAgICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJykgeyBzZXRQb3NpdGlvblByb3BlcnR5KC1wb3NpdGlvbi5sZWZ0LCAncmVzZXQnLCAwKTsgfVxuICAgICAgICAgIGVsc2UgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAndmVydGljYWwnKSB7IHNldFBvc2l0aW9uUHJvcGVydHkoLXBvc2l0aW9uLnRvcCwgJ3Jlc2V0JywgMCk7IH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gZGVjbGFyZSB0aGF0IHRoZSB0cmFuc2l0aW9uIGlzIGNvbXBsZXRlXG4gICAgICBzbGlkZXIud29ya2luZyA9IGZhbHNlO1xuICAgICAgLy8gb25TbGlkZUFmdGVyIGNhbGxiYWNrXG4gICAgICBzbGlkZXIuc2V0dGluZ3Mub25TbGlkZUFmdGVyLmNhbGwoZWwsIHNsaWRlci5jaGlsZHJlbi5lcShzbGlkZXIuYWN0aXZlLmluZGV4KSwgc2xpZGVyLm9sZEluZGV4LCBzbGlkZXIuYWN0aXZlLmluZGV4KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgYXV0byBjb250cm9scyBzdGF0ZSAoZWl0aGVyIGFjdGl2ZSwgb3IgY29tYmluZWQgc3dpdGNoKVxuICAgICAqXG4gICAgICogQHBhcmFtIHN0YXRlIChzdHJpbmcpIFwic3RhcnRcIiwgXCJzdG9wXCJcbiAgICAgKiAgLSB0aGUgbmV3IHN0YXRlIG9mIHRoZSBhdXRvIHNob3dcbiAgICAgKi9cbiAgICB2YXIgdXBkYXRlQXV0b0NvbnRyb2xzID0gZnVuY3Rpb24oc3RhdGUpIHtcbiAgICAgIC8vIGlmIGF1dG9Db250cm9sc0NvbWJpbmUgaXMgdHJ1ZSwgcmVwbGFjZSB0aGUgY3VycmVudCBjb250cm9sIHdpdGggdGhlIG5ldyBzdGF0ZVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hdXRvQ29udHJvbHNDb21iaW5lKSB7XG4gICAgICAgIHNsaWRlci5jb250cm9scy5hdXRvRWwuaHRtbChzbGlkZXIuY29udHJvbHNbc3RhdGVdKTtcbiAgICAgIC8vIGlmIGF1dG9Db250cm9sc0NvbWJpbmUgaXMgZmFsc2UsIGFwcGx5IHRoZSBcImFjdGl2ZVwiIGNsYXNzIHRvIHRoZSBhcHByb3ByaWF0ZSBjb250cm9sXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZXIuY29udHJvbHMuYXV0b0VsLmZpbmQoJ2EnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIHNsaWRlci5jb250cm9scy5hdXRvRWwuZmluZCgnYTpub3QoLmJ4LScgKyBzdGF0ZSArICcpJykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSBkaXJlY3Rpb24gY29udHJvbHMgKGNoZWNrcyBpZiBlaXRoZXIgc2hvdWxkIGJlIGhpZGRlbilcbiAgICAgKi9cbiAgICB2YXIgdXBkYXRlRGlyZWN0aW9uQ29udHJvbHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChnZXRQYWdlclF0eSgpID09PSAxKSB7XG4gICAgICAgIHNsaWRlci5jb250cm9scy5wcmV2LmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICBzbGlkZXIuY29udHJvbHMubmV4dC5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgIH0gZWxzZSBpZiAoIXNsaWRlci5zZXR0aW5ncy5pbmZpbml0ZUxvb3AgJiYgc2xpZGVyLnNldHRpbmdzLmhpZGVDb250cm9sT25FbmQpIHtcbiAgICAgICAgLy8gaWYgZmlyc3Qgc2xpZGVcbiAgICAgICAgaWYgKHNsaWRlci5hY3RpdmUuaW5kZXggPT09IDApIHtcbiAgICAgICAgICBzbGlkZXIuY29udHJvbHMucHJldi5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgICBzbGlkZXIuY29udHJvbHMubmV4dC5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgLy8gaWYgbGFzdCBzbGlkZVxuICAgICAgICB9IGVsc2UgaWYgKHNsaWRlci5hY3RpdmUuaW5kZXggPT09IGdldFBhZ2VyUXR5KCkgLSAxKSB7XG4gICAgICAgICAgc2xpZGVyLmNvbnRyb2xzLm5leHQuYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgc2xpZGVyLmNvbnRyb2xzLnByZXYucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgIC8vIGlmIGFueSBzbGlkZSBpbiB0aGUgbWlkZGxlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2xpZGVyLmNvbnRyb2xzLnByZXYucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgc2xpZGVyLmNvbnRyb2xzLm5leHQucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXHQvKiBhdXRvIHN0YXJ0IGFuZCBzdG9wIGZ1bmN0aW9ucyAqL1xuXHR2YXIgd2luZG93Rm9jdXNIYW5kbGVyID0gZnVuY3Rpb24oKSB7IGVsLnN0YXJ0QXV0bygpOyB9O1xuXHR2YXIgd2luZG93Qmx1ckhhbmRsZXIgPSBmdW5jdGlvbigpIHsgZWwuc3RvcEF1dG8oKTsgfTtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgYXV0byBwcm9jZXNzXG4gICAgICovXG4gICAgdmFyIGluaXRBdXRvID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBpZiBhdXRvRGVsYXkgd2FzIHN1cHBsaWVkLCBsYXVuY2ggdGhlIGF1dG8gc2hvdyB1c2luZyBhIHNldFRpbWVvdXQoKSBjYWxsXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmF1dG9EZWxheSA+IDApIHtcbiAgICAgICAgc2V0VGltZW91dChlbC5zdGFydEF1dG8sIHNsaWRlci5zZXR0aW5ncy5hdXRvRGVsYXkpO1xuICAgICAgLy8gaWYgYXV0b0RlbGF5IHdhcyBub3Qgc3VwcGxpZWQsIHN0YXJ0IHRoZSBhdXRvIHNob3cgbm9ybWFsbHlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLnN0YXJ0QXV0bygpO1xuXG4gICAgICAgIC8vYWRkIGZvY3VzIGFuZCBibHVyIGV2ZW50cyB0byBlbnN1cmUgaXRzIHJ1bm5pbmcgaWYgdGltZW91dCBnZXRzIHBhdXNlZFxuICAgICAgICAkKHdpbmRvdykuZm9jdXMod2luZG93Rm9jdXNIYW5kbGVyKS5ibHVyKHdpbmRvd0JsdXJIYW5kbGVyKTtcbiAgICAgIH1cbiAgICAgIC8vIGlmIGF1dG9Ib3ZlciBpcyByZXF1ZXN0ZWRcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYXV0b0hvdmVyKSB7XG4gICAgICAgIC8vIG9uIGVsIGhvdmVyXG4gICAgICAgIGVsLmhvdmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIC8vIGlmIHRoZSBhdXRvIHNob3cgaXMgY3VycmVudGx5IHBsYXlpbmcgKGhhcyBhbiBhY3RpdmUgaW50ZXJ2YWwpXG4gICAgICAgICAgaWYgKHNsaWRlci5pbnRlcnZhbCkge1xuICAgICAgICAgICAgLy8gc3RvcCB0aGUgYXV0byBzaG93IGFuZCBwYXNzIHRydWUgYXJndW1lbnQgd2hpY2ggd2lsbCBwcmV2ZW50IGNvbnRyb2wgdXBkYXRlXG4gICAgICAgICAgICBlbC5zdG9wQXV0byh0cnVlKTtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBhdXRvUGF1c2VkIHZhbHVlIHdoaWNoIHdpbGwgYmUgdXNlZCBieSB0aGUgcmVsYXRpdmUgXCJtb3VzZW91dFwiIGV2ZW50XG4gICAgICAgICAgICBzbGlkZXIuYXV0b1BhdXNlZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAvLyBpZiB0aGUgYXV0b1BhdXNlZCB2YWx1ZSB3YXMgY3JlYXRlZCBiZSB0aGUgcHJpb3IgXCJtb3VzZW92ZXJcIiBldmVudFxuICAgICAgICAgIGlmIChzbGlkZXIuYXV0b1BhdXNlZCkge1xuICAgICAgICAgICAgLy8gc3RhcnQgdGhlIGF1dG8gc2hvdyBhbmQgcGFzcyB0cnVlIGFyZ3VtZW50IHdoaWNoIHdpbGwgcHJldmVudCBjb250cm9sIHVwZGF0ZVxuICAgICAgICAgICAgZWwuc3RhcnRBdXRvKHRydWUpO1xuICAgICAgICAgICAgLy8gcmVzZXQgdGhlIGF1dG9QYXVzZWQgdmFsdWVcbiAgICAgICAgICAgI
98HNsaWRlci5hdXRvUGF1c2VkID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgdGlja2VyIHByb2Nlc3NcbiAgICAgKi9cbiAgICB2YXIgaW5pdFRpY2tlciA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHN0YXJ0UG9zaXRpb24gPSAwLFxuICAgICAgcG9zaXRpb24sIHRyYW5zZm9ybSwgdmFsdWUsIGlkeCwgcmF0aW8sIHByb3BlcnR5LCBuZXdTcGVlZCwgdG90YWxEaW1lbnM7XG4gICAgICAvLyBpZiBhdXRvRGlyZWN0aW9uIGlzIFwibmV4dFwiLCBhcHBlbmQgYSBjbG9uZSBvZiB0aGUgZW50aXJlIHNsaWRlclxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hdXRvRGlyZWN0aW9uID09PSAnbmV4dCcpIHtcbiAgICAgICAgZWwuYXBwZW5kKHNsaWRlci5jaGlsZHJlbi5jbG9uZSgpLmFkZENsYXNzKCdieC1jbG9uZScpKTtcbiAgICAgIC8vIGlmIGF1dG9EaXJlY3Rpb24gaXMgXCJwcmV2XCIsIHByZXBlbmQgYSBjbG9uZSBvZiB0aGUgZW50aXJlIHNsaWRlciwgYW5kIHNldCB0aGUgbGVmdCBwb3NpdGlvblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWwucHJlcGVuZChzbGlkZXIuY2hpbGRyZW4uY2xvbmUoKS5hZGRDbGFzcygnYngtY2xvbmUnKSk7XG4gICAgICAgIHBvc2l0aW9uID0gc2xpZGVyLmNoaWxkcmVuLmZpcnN0KCkucG9zaXRpb24oKTtcbiAgICAgICAgc3RhcnRQb3NpdGlvbiA9IHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcgPyAtcG9zaXRpb24ubGVmdCA6IC1wb3NpdGlvbi50b3A7XG4gICAgICB9XG4gICAgICBzZXRQb3NpdGlvblByb3BlcnR5KHN0YXJ0UG9zaXRpb24sICdyZXNldCcsIDApO1xuICAgICAgLy8gZG8gbm90IGFsbG93IGNvbnRyb2xzIGluIHRpY2tlciBtb2RlXG4gICAgICBzbGlkZXIuc2V0dGluZ3MucGFnZXIgPSBmYWxzZTtcbiAgICAgIHNsaWRlci5zZXR0aW5ncy5jb250cm9scyA9IGZhbHNlO1xuICAgICAgc2xpZGVyLnNldHRpbmdzLmF1dG9Db250cm9scyA9IGZhbHNlO1xuICAgICAgLy8gaWYgYXV0b0hvdmVyIGlzIHJlcXVlc3RlZFxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy50aWNrZXJIb3Zlcikge1xuICAgICAgICBpZiAoc2xpZGVyLnVzaW5nQ1NTKSB7XG4gICAgICAgICAgaWR4ID0gc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJyA/IDQgOiA1O1xuICAgICAgICAgIHNsaWRlci52aWV3cG9ydC5ob3ZlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybSA9IGVsLmNzcygnLScgKyBzbGlkZXIuY3NzUHJlZml4ICsgJy10cmFuc2Zvcm0nKTtcbiAgICAgICAgICAgIHZhbHVlID0gcGFyc2VGbG9hdCh0cmFuc2Zvcm0uc3BsaXQoJywnKVtpZHhdKTtcbiAgICAgICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkodmFsdWUsICdyZXNldCcsIDApO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdG90YWxEaW1lbnMgPSAwO1xuICAgICAgICAgICAgc2xpZGVyLmNoaWxkcmVuLmVhY2goZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgICAgICAgdG90YWxEaW1lbnMgKz0gc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJyA/ICQodGhpcykub3V0ZXJXaWR0aCh0cnVlKSA6ICQodGhpcykub3V0ZXJIZWlnaHQodHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgc3BlZWQgcmF0aW8gKHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBuZXcgc3BlZWQgdG8gZmluaXNoIHRoZSBwYXVzZWQgYW5pbWF0aW9uKVxuICAgICAgICAgICAgcmF0aW8gPSBzbGlkZXIuc2V0dGluZ3Muc3BlZWQgLyB0b3RhbERpbWVucztcbiAgICAgICAgICAgIC8vIGRldGVybWluZSB3aGljaCBwcm9wZXJ0eSB0byB1c2VcbiAgICAgICAgICAgIHByb3BlcnR5ID0gc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJyA/ICdsZWZ0JyA6ICd0b3AnO1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBuZXcgc3BlZWRcbiAgICAgICAgICAgIG5ld1NwZWVkID0gcmF0aW8gKiAodG90YWxEaW1lbnMgLSAoTWF0aC5hYnMocGFyc2VJbnQodmFsdWUpKSkpO1xuICAgICAgICAgICAgdGlja2VyTG9vcChuZXdTcGVlZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gb24gZWwgaG92ZXJcbiAgICAgICAgICBzbGlkZXIudmlld3BvcnQuaG92ZXIoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBlbC5zdG9wKCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIHRvdGFsIHdpZHRoIG9mIGNoaWxkcmVuICh1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgc3BlZWQgcmF0aW8pXG4gICAgICAgICAgICB0b3RhbERpbWVucyA9IDA7XG4gICAgICAgICAgICBzbGlkZXIuY2hpbGRyZW4uZWFjaChmdW5jdGlvbihpbmRleCkge1xuICAgICAgICAgICAgICB0b3RhbERpbWVucyArPSBzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnID8gJCh0aGlzKS5vdXRlcldpZHRoKHRydWUpIDogJCh0aGlzKS5vdXRlckhlaWdodCh0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzcGVlZCByYXRpbyAodXNlZCB0byBkZXRlcm1pbmUgdGhlIG5ldyBzcGVlZCB0byBmaW5pc2ggdGhlIHBhdXNlZCBhbmltYXRpb24pXG4gICAgICAgICAgICByYXRpbyA9IHNsaWRlci5zZXR0aW5ncy5zcGVlZCAvIHRvdGFsRGltZW5zO1xuICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHdoaWNoIHByb3BlcnR5IHRvIHVzZVxuICAgICAgICAgICAgcHJvcGVydHkgPSBzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnID8gJ2xlZnQnIDogJ3RvcCc7XG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIG5ldyBzcGVlZFxuICAgICAgICAgICAgbmV3U3BlZWQgPSByYXRpbyAqICh0b3RhbERpbWVucyAtIChNYXRoLmFicyhwYXJzZUludChlbC5jc3MocHJvcGVydHkpKSkpKTtcbiAgICAgICAgICAgIHRpY2tlckxvb3AobmV3U3BlZWQpO1xuICAgICAgICAgI
98H0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBzdGFydCB0aGUgdGlja2VyIGxvb3BcbiAgICAgIHRpY2tlckxvb3AoKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUnVucyBhIGNvbnRpbnVvdXMgbG9vcCwgbmV3cyB0aWNrZXItc3R5bGVcbiAgICAgKi9cbiAgICB2YXIgdGlja2VyTG9vcCA9IGZ1bmN0aW9uKHJlc3VtZVNwZWVkKSB7XG4gICAgICB2YXIgc3BlZWQgPSByZXN1bWVTcGVlZCA/IHJlc3VtZVNwZWVkIDogc2xpZGVyLnNldHRpbmdzLnNwZWVkLFxuICAgICAgcG9zaXRpb24gPSB7bGVmdDogMCwgdG9wOiAwfSxcbiAgICAgIHJlc2V0ID0ge2xlZnQ6IDAsIHRvcDogMH0sXG4gICAgICBhbmltYXRlUHJvcGVydHksIHJlc2V0VmFsdWUsIHBhcmFtcztcblxuICAgICAgLy8gaWYgXCJuZXh0XCIgYW5pbWF0ZSBsZWZ0IHBvc2l0aW9uIHRvIGxhc3QgY2hpbGQsIHRoZW4gcmVzZXQgbGVmdCB0byAwXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmF1dG9EaXJlY3Rpb24gPT09ICduZXh0Jykge1xuICAgICAgICBwb3NpdGlvbiA9IGVsLmZpbmQoJy5ieC1jbG9uZScpLmZpcnN0KCkucG9zaXRpb24oKTtcbiAgICAgIC8vIGlmIFwicHJldlwiIGFuaW1hdGUgbGVmdCBwb3NpdGlvbiB0byAwLCB0aGVuIHJlc2V0IGxlZnQgdG8gZmlyc3Qgbm9uLWNsb25lIGNoaWxkXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNldCA9IHNsaWRlci5jaGlsZHJlbi5maXJzdCgpLnBvc2l0aW9uKCk7XG4gICAgICB9XG4gICAgICBhbmltYXRlUHJvcGVydHkgPSBzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnID8gLXBvc2l0aW9uLmxlZnQgOiAtcG9zaXRpb24udG9wO1xuICAgICAgcmVzZXRWYWx1ZSA9IHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcgPyAtcmVzZXQubGVmdCA6IC1yZXNldC50b3A7XG4gICAgICBwYXJhbXMgPSB7cmVzZXRWYWx1ZTogcmVzZXRWYWx1ZX07XG4gICAgICBzZXRQb3NpdGlvblByb3BlcnR5KGFuaW1hdGVQcm9wZXJ0eSwgJ3RpY2tlcicsIHNwZWVkLCBwYXJhbXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBlbCBpcyBvbiBzY3JlZW5cbiAgICAgKi9cbiAgICB2YXIgaXNPblNjcmVlbiA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICB2Y
98XIgd2luID0gJCh3aW5kb3cpLFxuICAgICAgdmlld3BvcnQgPSB7XG4gICAgICAgIHRvcDogd2luLnNjcm9sbFRvcCgpLFxuICAgICAgICBsZWZ0OiB3aW4uc2Nyb2xsTGVmdCgpXG4gICAgICB9LFxuICAgICAgYm91bmRzID0gZWwub2Zmc2V0KCk7XG5cbiAgICAgIHZpZXdwb3J0LnJpZ2h0ID0gdmlld3BvcnQubGVmdCArIHdpbi53aWR0aCgpO1xuICAgICAgdmlld3BvcnQuYm90dG9tID0gdmlld3BvcnQudG9wICsgd2luLmhlaWdodCgpO1xuICAgICAgYm91bmRzLnJpZ2h0ID0gYm91bmRzLmxlZnQgKyBlbC5vdXRlcldpZHRoKCk7XG4gICAgICBib3VuZHMuYm90dG9tID0gYm91bmRzLnRvcCArIGVsLm91dGVySGVpZ2h0KCk7XG5cbiAgICAgIHJldHVybiAoISh2aWV3cG9ydC5yaWdodCA8IGJvdW5kcy5sZWZ0IHx8IHZpZXdwb3J0LmxlZnQgPiBib3VuZHMucmlnaHQgfHwgdmlld3BvcnQuYm90dG9tIDwgYm91bmRzLnRvcCB8fCB2aWV3cG9ydC50b3AgPiBib3VuZHMuYm90dG9tKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGtleWJvYXJkIGV2ZW50c1xuICAgICAqL1xuICAgIHZhciBrZXlQcmVzcyA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciBhY3RpdmVFbGVtZW50VGFnID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICB0YWdGaWx0ZXJzID0gJ2lucHV0fHRleHRhcmVhJyxcbiAgICAgIHAgPSBuZXcgUmVnRXhwKGFjdGl2ZUVsZW1lbnRUYWcsWydpJ10pLFxuICAgICAgcmVzdWx0ID0gcC5leGVjKHRhZ0ZpbHRlcnMpO1xuXG4gICAgICBpZiAocmVzdWx0ID09IG51bGwgJiYgaXNPblNjcmVlbihlbCkpIHtcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMzkpIHtcbiAgICAgICAgICBjbGlja05leHRCaW5kKGUpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChlLmtleUNvZGUgPT09IDM3KSB7XG4gICAgICAgICAgY2xpY2tQcmV2QmluZChlKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgdG91Y2ggZXZlbnRzXG4gICAgICovXG4gICAgdmFyIGluaXRUb3VjaCA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gaW5pdGlhbGl6ZSBvYmplY3QgdG8gY29udGFpbiBhbGwgdG91Y2ggdmFsdWVzXG4gICAgICBzbGlkZXIudG91Y2ggPSB7XG4gICAgICAgIHN0YXJ0OiB7eDogMCwgeTogMH0sXG4gICAgICAgIGVuZDoge3g6IDAsIHk6IDB9XG4gICAgICB9O1xuICAgICAgc2xpZGVyLnZpZXdwb3J0Lm9uKCd0b3VjaHN0YXJ0IE1TUG9pbnRlckRvd24gcG9pbnRlcmRvd24nLCBvblRvdWNoU3RhcnQpO1xuXG4gICAgICAvL2ZvciBicm93c2VycyB0aGF0IGhhdmUgaW1wbGVtZW50ZWQgcG9pbnRlciBldmVudHMgYW5kIGZpcmUgYSBjbGljayBhZnRlclxuICAgICAgLy9ldmVyeSBwb2ludGVydXAgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHBvaW50ZXJ1cCBpcyBvbiBzYW1lIHNjcmVlbiBsb2NhdGlvbiBhcyBwb2ludGVyZG93biBvciBub3RcbiAgICAgIHNsaWRlci52aWV3cG9ydC5vbignY2xpY2snLCAnLmJ4c2xpZGVyIGEnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChzbGlkZXIudmlld3BvcnQuaGFzQ2xhc3MoJ2NsaWNrLWRpc2FibGVkJykpIHtcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgc2xpZGVyLnZpZXdwb3J0LnJlbW92ZUNsYXNzKCdjbGljay1kaXNhYmxlZCcpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRXZlbnQgaGFuZGxlciBmb3IgXCJ0b3VjaHN0YXJ0XCJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIChldmVudClcbiAgICAgKiAgLSBET00gZXZlbnQgb2JqZWN0XG4gICAgICovXG4gICAgdmFyIG9uVG91Y2hTdGFydCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIC8vIHdhdGNoIG9ubHkgZm9yIGxlZnQgbW91c2UsIHRvdWNoIGNvbnRhY3QgYW5kIHBlbiBjb250YWN0XG4gICAgICAvLyB0b3VjaHN0YXJ0IGV2ZW50IG9iamVjdCBkb2VzbmB0IGhhdmUgYnV0dG9uIHByb3BlcnR5XG4gICAgICBpZiAoZS50eXBlICE9PSAndG91Y2hzdGFydCcgJiYgZS5idXR0b24gIT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgLy9kaXNhYmxlIHNsaWRlciBjb250cm9scyB3aGlsZSB1c2VyIGlzIGludGVyYWN0aW5nIHdpdGggc2xpZGVzIHRvIGF2b2lkIHNsaWRlciBmcmVlemUgdGhhdCBoYXBwZW5zIG9uIHRvdWNoIGRldmljZXMgd2hlbiBhIHNsaWRlIHN3aXBlIGhhcHBlbnMgaW1tZWRpYXRlbHkgYWZ0ZXIgaW50ZXJhY3Rpbmcgd2l0aCBzbGlkZXIgY29udHJvbHNcbiAgICAgIHNsaWRlci5jb250cm9scy5lbC5hZGRDbGFzcygnZGlzYWJsZWQnKTtcblxuICAgICAgaWYgKHNsaWRlci53b3JraW5nKSB7XG4gICAgICAgIHNsaWRlci5jb250cm9scy5lbC5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgb3JpZ2luYWwgcG9zaXRpb24gd2hlbiB0b3VjaCBzdGFydHNcbiAgICAgICAgc2xpZGVyLnRvdWNoLm9yaWdpbmFsUG9zID0gZWwucG9zaXRpb24oKTtcbiAgICAgICAgdmFyIG9yaWcgPSBlLm9yaWdpbmFsRXZlbnQsXG4gICAgICAgIHRvdWNoUG9pbnRzID0gKHR5cGVvZiBvcmlnLmNoYW5nZWRUb3VjaGVzICE9PSAndW5kZWZpbmVkJykgPyBvcmlnLmNoYW5nZWRUb3VjaGVzIDogW29yaWddO1xuXHRcdHZhciBjaHJvbWVQb2ludGVyRXZlbnRzID0gdHlwZW9mIFBvaW50ZXJFdmVudCA9PT0gJ2Z1bmN0aW9uJzsgXG5cdFx0aWYgKGNocm9tZVBvaW50ZXJFdmVudHMpIHsgXG5cdFx0XHRpZiAob3JpZy5wb2ludGVySWQgPT09IHVuZGVmaW5lZCkgeyBcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fSBcblx0XHR9XG4gICAgICAgIC8vIHJlY29yZCB0aGUgc3RhcnRpbmcgdG91Y2ggeCwgeSBjb29yZGluYXRlc1xuICAgICAgICBzbGlkZXIudG91Y2guc3RhcnQueCA9IHRvdWNoUG9pbnRzWzBdLnBhZ2VYO1xuICAgICAgICBzbGlkZXIudG91Y2guc3RhcnQueSA9IHRvdWNoUG9pbnRzWzBdLnBhZ2VZO1xuXG4gICAgICAgIGlmIChzbGlkZXIudmlld3BvcnQuZ2V0KDApLnNldFBvaW50ZXJDYXB0dXJlKSB7XG4gICAgICAgICAgc2xpZGVyLnBvaW50ZXJJZCA9IG9yaWcucG9pbnRlcklkO1xuICAgICAgICAgI
98HNsaWRlci52aWV3cG9ydC5nZXQoMCkuc2V0UG9pbnRlckNhcHR1cmUoc2xpZGVyLnBvaW50ZXJJZCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RvcmUgb3JpZ2luYWwgZXZlbnQgZGF0YSBmb3IgY2xpY2sgZml4YXRpb25cbiAgICAgICAgc2xpZGVyLm9yaWdpbmFsQ2xpY2tUYXJnZXQgPSBvcmlnLm9yaWdpbmFsVGFyZ2V0IHx8IG9yaWcudGFyZ2V0O1xuICAgICAgICBzbGlkZXIub3JpZ2luYWxDbGlja0J1dHRvbiA9IG9yaWcuYnV0dG9uO1xuICAgICAgICBzbGlkZXIub3JpZ2luYWxDbGlja0J1dHRvbnMgPSBvcmlnLmJ1dHRvbnM7XG4gICAgICAgIHNsaWRlci5vcmlnaW5hbEV2ZW50VHlwZSA9IG9yaWcudHlwZTtcbiAgICAgICAgLy8gYXQgdGhpcyBtb21lbnQgd2UgZG9uYHQga25vdyB3aGF0IGl0IGlzIGNsaWNrIG9yIHN3aXBlXG4gICAgICAgIHNsaWRlci5oYXNNb3ZlID0gZmFsc2U7XG4gICAgICAgIC8vIG9uIGEgXCJ0b3VjaG1vdmVcIiBldmVudCB0byB0aGUgdmlld3BvcnRcbiAgICAgICAgc2xpZGVyLnZpZXdwb3J0Lm9uKCd0b3VjaG1vdmUgTVNQb2ludGVyTW92ZSBwb2ludGVybW92ZScsIG9uVG91Y2hNb3ZlKTtcbiAgICAgICAgLy8gb24gYSBcInRvdWNoZW5kXCIgZXZlbnQgdG8gdGhlIHZpZXdwb3J0XG4gICAgICAgIHNsaWRlci52aWV3cG9ydC5vbigndG91Y2hlbmQgTVNQb2ludGVyVXAgcG9pbnRlcnVwJywgb25Ub3VjaEVuZCk7XG4gICAgICAgIHNsaWRlci52aWV3cG9ydC5vbignTVNQb2ludGVyQ2FuY2VsIHBvaW50ZXJjYW5jZWwnLCBvblBvaW50ZXJDYW5jZWwpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgUG9pbnRlciBmb3IgV2luZG93cyBQaG9uZVxuICAgICAqXG4gICAgICogQHBhcmFtIGUgKGV2ZW50KVxuICAgICAqICAtIERPTSBldmVudCBvYmplY3RcbiAgICAgKi9cbiAgICB2YXIgb25Qb2ludGVyQ2FuY2VsID0gZnVuY3Rpb24oZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgLyogb25Qb2ludGVyQ2FuY2VsIGhhbmRsZXIgaXMgbmVlZGVkIHRvIGRlYWwgd2l0aCBzaXR1YXRpb25zIHdoZW4gYSB0b3VjaGVuZFxuICAgICAgZG9lc24ndCBmaXJlIGFmdGVyIGEgdG91Y2hzdGFydCAodGhpcyBoYXBwZW5zIG9uIHdpbmRvd3MgcGhvbmVzIG9ubHkpICovXG4gICAgICBzZXRQb3NpdGlvblByb3BlcnR5KHNsaWRlci50b3VjaC5vcmlnaW5hbFBvcy5sZWZ0LCAncmVzZXQnLCAwKTtcblxuICAgICAgLy9yZW1vdmUgaGFuZGxlcnNcbiAgICAgIHNsaWRlci5jb250cm9scy5lbC5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgIHNsaWRlci52aWV3cG9ydC5vZmYoJ01TUG9pbnRlckNhbmNlbCBwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyQ2FuY2VsKTtcbiAgICAgIHNsaWRlci52aWV3cG9ydC5vZmYoJ3RvdWNobW92ZSBNU1BvaW50ZXJNb3ZlIHBvaW50ZXJtb3ZlJywgb25Ub3VjaE1vdmUpO1xuICAgICAgc2xpZGVyLnZpZXdwb3J0Lm9mZigndG91Y2hlbmQgTVNQb2ludGVyVXAgcG9pbnRlcnVwJywgb25Ub3VjaEVuZCk7XG4gICAgICBpZiAoc2xpZGVyLnZpZXdwb3J0LmdldCgwKS5yZWxlYXNlUG9pbnRlckNhcHR1cmUpIHtcbiAgICAgICAgc2xpZGVyLnZpZXdwb3J0LmdldCgwKS5yZWxlYXNlUG9pbnRlckNhcHR1cmUoc2xpZGVyLnBvaW50ZXJJZCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGhhbmRsZXIgZm9yIFwidG91Y2htb3ZlXCJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIChldmVudClcbiAgICAgKiAgLSBET00gZXZlbnQgb2JqZWN0XG4gICAgICovXG4gICAgdmFyIG9uVG91Y2hNb3ZlID0gZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIG9yaWcgPSBlLm9yaWdpbmFsRXZlbnQsXG4gICAgICB0b3VjaFBvaW50cyA9ICh0eXBlb2Ygb3JpZy5jaGFuZ2VkVG91Y2hlcyAhPT0gJ3VuZGVmaW5lZCcpID8gb3JpZy5jaGFuZ2VkVG91Y2hlcyA6IFtvcmlnXSxcbiAgICAgIC8vIGlmIHNjcm9sbGluZyBvbiB5IGF4aXMsIGRvIG5vdCBwcmV2ZW50IGRlZmF1bHRcbiAgICAgIHhNb3ZlbWVudCA9IE1hdGguYWJzKHRvdWNoUG9pbnRzWzBdLnBhZ2VYIC0gc2xpZGVyLnRvdWNoLnN0YXJ0LngpLFxuICAgICAgeU1vdmVtZW50ID0gTWF0aC5hYnModG91Y2hQb2ludHNbMF0ucGFnZVkgLSBzbGlkZXIudG91Y2guc3RhcnQueSksXG4gICAgICB2YWx1ZSA9IDAsXG4gICAgICBjaGFuZ2UgPSAwO1xuICAgICAgLy8gdGhpcyBpcyBzd2lwZVxuICAgICAgc2xpZGVyLmhhc01vdmUgPSB0cnVlO1xuXG4gICAgICAvLyB4IGF4aXMgc3dpcGVcbiAgICAgIGlmICgoeE1vdmVtZW50ICogMykgPiB5TW92ZW1lbnQgJiYgc2xpZGVyLnNldHRpbmdzLnByZXZlbnREZWZhdWx0U3dpcGVYKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIC8vIHkgYXhpcyBzd2lwZVxuICAgICAgfSBlbHNlIGlmICgoeU1vdmVtZW50ICogMykgPiB4TW92ZW1lbnQgJiYgc2xpZGVyLnNldHRpbmdzLnByZXZlbnREZWZhdWx0U3dpcGVZKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChlLnR5cGUgIT09ICd0b3VjaG1vdmUnKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlICE9PSAnZmFkZScgJiYgc2xpZGVyLnNldHRpbmdzLm9uZVRvT25lVG91Y2gpIHtcbiAgICAgICAgLy8gaWYgaG9yaXpvbn
98RhbCwgZHJhZyBhbG9uZyB4IGF4aXNcbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICBjaGFuZ2UgPSB0b3VjaFBvaW50c1swXS5wYWdlWCAtIHNsaWRlci50b3VjaC5zdGFydC54O1xuICAgICAgICAgIHZhbHVlID0gc2xpZGVyLnRvdWNoLm9yaWdpbmFsUG9zLmxlZnQgKyBjaGFuZ2U7XG4gICAgICAgIC8vIGlmIHZlcnRpY2FsLCBkcmFnIGFsb25nIHkgYXhpc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNoYW5nZSA9IHRvdWNoUG9pbnRzWzBdLnBhZ2VZIC0gc2xpZGVyLnRvdWNoLnN0YXJ0Lnk7XG4gICAgICAgICAgdmFsdWUgPSBzbGlkZXIudG91Y2gub3JpZ2luYWxQb3MudG9wICsgY2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkodmFsdWUsICdyZXNldCcsIDApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFdmVudCBoYW5kbGVyIGZvciBcInRvdWNoZW5kXCJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIChldmVudClcbiAgICAgKiAgLSBET00gZXZlbnQgb2JqZWN0XG4gICAgICovXG4gICAgdmFyIG9uVG91Y2hFbmQgPSBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzbGlkZXIudmlld3BvcnQub2ZmKCd0b3VjaG1vdmUgTVNQb2ludGVyTW92ZSBwb2ludGVybW92ZScsIG9uVG91Y2hNb3ZlKTtcbiAgICAgIC8vZW5hYmxlIHNsaWRlciBjb250cm9scyBhcyBzb29uIGFzIHVzZXIgc3RvcHMgaW50ZXJhY2luZyB3aXRoIHNsaWRlc1xuICAgICAgc2xpZGVyLmNvbnRyb2xzLmVsLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgdmFyIG9yaWcgICAgPSBlLm9yaWdpbmFsRXZlbnQsXG4gICAgICB0b3VjaFBvaW50cyA9ICh0eXBlb2Ygb3JpZy5jaGFuZ2VkVG91Y2hlcyAhPT0gJ3VuZGVmaW5lZCcpID8gb3JpZy5jaGFuZ2VkVG91Y2hlcyA6IFtvcmlnXSxcbiAgICAgIHZhbHVlICAgICAgID0gMCxcbiAgICAgIGRpc3RhbmNlICAgID0gMDtcbiAgICAgIC8vIHJlY29yZCBlbmQgeCwgeSBwb3NpdGlvbnNcbiAgICAgIHNsaWRlci50b3VjaC5lbmQueCA9IHRvdWNoUG9pbnRzWzBdLnBhZ2VYO1xuICAgICAgc2xpZGVyLnRvdWNoLmVuZC55ID0gdG91Y2hQb2ludHNbMF0ucGFnZVk7XG4gICAgICAvLyBpZiBmYWRlIG1vZGUsIGNoZWNrIGlmIGFic29sdXRlIHggZGlzdGFuY2UgY2xlYXJzIHRoZSB0aHJlc2hvbGRcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2ZhZGUnKSB7XG4gICAgICAgIGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnRvdWNoLnN0YXJ0LnggLSBzbGlkZXIudG91Y2guZW5kLngpO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPj0gc2xpZGVyLnNldHRpbmdzLnN3aXBlVGhyZXNob2xkKSB7XG4gICAgICAgICAgaWYgKHNsaWRlci50b3VjaC5zdGFydC54ID4gc2xpZGVyLnRvdWNoLmVuZC54KSB7XG4gICAgICAgICAgICBlbC5nb1RvTmV4dFNsaWRlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsLmdvVG9QcmV2U2xpZGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWwuc3RvcEF1dG8oKTtcbiAgICAgICAgfVxuICAgICAgLy8gbm90IGZhZGUgbW9kZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY2FsY3VsYXRlIGRpc3RhbmNlIGFuZCBlbCdzIGFuaW1hdGUgcHJvcGVydHlcbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5tb2RlID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICBkaXN0YW5jZSA9IHNsaWRlci50b3VjaC5lbmQueCAtIHNsaWRlci50b3VjaC5zdGFydC54O1xuICAgICAgICAgIHZhbHVlID0gc2xpZGVyLnRvdWNoLm9yaWdpbmFsUG9zLmxlZnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGlzdGFuY2UgPSBzbGlkZXIudG91Y2guZW5kLnkgLSBzbGlkZXIudG91Y2guc3RhcnQueTtcbiAgICAgICAgICB2YWx1ZSA9IHNsaWRlci50b3VjaC5vcmlnaW5hbFBvcy50b3A7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgbm90IGluZmluaXRlIGxvb3AgYW5kIGZpcnN0IC8gbGFzdCBzbGlkZSwgZG8gbm90IGF0dGVtcHQgYSBzbGlkZSB0cmFuc2l0aW9uXG4gICAgICAgIGlmICghc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCAmJiAoKHNsaWRlci5hY3RpdmUuaW5kZXggPT09IDAgJiYgZGlzdGFuY2UgPiAwKSB8fCAoc2xpZGVyLmFjdGl2ZS5sYXN0ICYmIGRpc3RhbmNlIDwgMCkpKSB7XG4gICAgICAgICAgc2V0UG9zaXRpb25Qcm9wZXJ0eSh2YWx1ZSwgJ3Jlc2V0JywgMjAwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBjaGVjayBpZiBkaXN0YW5jZSBjbGVhcnMgdGhyZXNob2xkXG4gICAgICAgICAgaWYgKE1hdGguYWJzKGRpc3RhbmNlKSA+PSBzbGlkZXIuc2V0dGluZ3Muc3dpcGVUaHJlc2hvbGQpIHtcbiAgICAgICAgICAgIGlmIChkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgICAgICAgZWwuZ29Ub05leHRTbGlkZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZWwuZ29Ub1ByZXZTbGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWwuc3RvcEF1dG8oKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZWwuYW5pbWF0ZShwcm9wZXJ0eSwgMjAwKTtcbiAgICAgICAgICAgIHNldFBvc2l0aW9uUHJvcGVydHkodmFsdWUsICdyZXNldCcsIDIwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzbGlkZXIudmlld3BvcnQub2ZmKCd0b3VjaGVuZCBNU1BvaW50ZXJVcCBwb2ludGVydXAnLCBvblRvdWNoRW5kKTtcblxuICAgICAgaWYgKHNsaWRlci52aWV3cG9ydC5nZXQoMCkucmVsZWFzZVBvaW50ZXJDYXB0dXJlKSB7XG4gICAgICAgIHNsaWRlci52aWV3cG9ydC5nZXQoMCkucmVsZWFzZVBvaW50ZXJDYXB0dXJlKHNsaWRlci5wb2ludGVySWQpO1xuICAgICAgfVxuICAgICAgLy8gaWYgc2xpZGVyIGhhZCBzd2lwZSB3aXRoIGxlZnQgbW91c2UsIHRvdWNoIGNvbnRhY3QgYW5kIHBlbiBjb250YWN0XG4gICAgICBpZiAoc2xpZGVyLmhhc01vdmUgPT09IGZhbHNlICYmIChzbGlkZXIub3JpZ2luYWxDbGlja0J1dHRvbiA9PT0gMCB8fCBzbGlkZXIub3JpZ2luYWxFdmVudFR5cGUgPT09ICd0b3VjaHN0YXJ0JykpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBjbGljayBldmVudCAoZml4IGZvciBGaXJlZm94NTkgYW5kIFBvaW50ZXJFdmVudCBzdGFuZGFyZCBjb21wYXRpYmlsaXR5KVxuICAgICAgICAkKHNsaWRlci5vcmlnaW5hbENsaWNrVGFyZ2V0KS50cmlnZ2VyKHtcbiAgICAgICAgICB0eX
98BlOiAnY2xpY2snLFxuICAgICAgICAgIGJ1dHRvbjogc2xpZGVyLm9yaWdpbmFsQ2xpY2tCdXR0b24sXG4gICAgICAgICAgYnV0dG9uczogc2xpZGVyLm9yaWdpbmFsQ2xpY2tCdXR0b25zXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBXaW5kb3cgcmVzaXplIGV2ZW50IGNhbGxiYWNrXG4gICAgICovXG4gICAgdmFyIHJlc2l6ZVdpbmRvdyA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIC8vIGRvbid0IGRvIGFueXRoaW5nIGlmIHNsaWRlciBpc24ndCBpbml0aWFsaXplZC5cbiAgICAgIGlmICghc2xpZGVyLmluaXRpYWxpemVkKSB7IHJldHVybjsgfVxuICAgICAgLy8gRGVsYXkgaWYgc2xpZGVyIHdvcmtpbmcuXG4gICAgICBpZiAoc2xpZGVyLndvcmtpbmcpIHtcbiAgICAgICAgd2luZG93LnNldFRpbWVvdXQocmVzaXplV2luZG93LCAxMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBnZXQgdGhlIG5ldyB3aW5kb3cgZGltZW5zIChhZ2FpbiwgdGhhbmsgeW91IElFKVxuICAgICAgICB2YXIgd2luZG93V2lkdGhOZXcgPSAkKHdpbmRvdykud2lkdGgoKSxcbiAgICAgICAgd2luZG93SGVpZ2h0TmV3ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCBpdCBpcyBhIHRydWUgd2luZG93IHJlc2l6ZVxuICAgICAgICAvLyAqd2UgbXVzdCBjaGVjayB0aGlzIGJlY2F1c2Ugb3VyIGRpbm9zYXVyIGZyaWVuZCBJRSBmaXJlcyBhIHdpbmRvdyByZXNpemUgZXZlbnQgd2hlbiBjZXJ0YWluIERPTSBlbGVtZW50c1xuICAgICAgICAvLyBhcmUgcmVzaXplZC4gQ2FuIHlvdSBqdXN0IGRpZSBhbHJlYWR5PypcbiAgICAgICAgaWYgKHdpbmRvd1dpZHRoICE9PSB3aW5kb3dXaWR0aE5ldyB8fCB3aW5kb3dIZWlnaHQgIT09IHdpbmRvd0hlaWdodE5ldykge1xuICAgICAgICAgIC8vIHNldCB0aGUgbmV3IHdpbmRvdyBkaW1lbnNcbiAgICAgICAgICB3aW5kb3dXaWR0aCA9IHdpbmRvd1dpZHRoTmV3O1xuICAgICAgICAgIHdpbmRvd0hlaWdodCA9IHdpbmRvd0hlaWdodE5ldztcbiAgICAgICAgICAvLyB1cGRhdGUgYWxsIGR5bmFtaWMgZWxlbWVudHNcbiAgICAgICAgICBlbC5yZWRyYXdTbGlkZXIoKTtcbiAgICAgICAgICAvLyBDYWxsIHVzZXIgcmVzaXplIGhhbmRsZXJcbiAgICAgICAgICBzbGlkZXIuc2V0dGluZ3Mub25TbGlkZXJSZXNpemUuY2FsbChlbCwgc2xpZGVyLmFjdGl2ZS5pbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhbiBhcmlhLWhpZGRlbj10cnVlIGF0dHJpYnV0ZSB0byBlYWNoIGVsZW1lbnRcbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdGFydFZpc2libGVJbmRleCAoaW50KVxuICAgICAqICAtIHRoZSBmaXJzdCB2aXNpYmxlIGVsZW1lbnQncyBpbmRleFxuICAgICAqL1xuICAgIHZhciBhcHBseUFyaWFIaWRkZW5BdHRyaWJ1dGVzID0gZnVuY3Rpb24oc3RhcnRWaXNpYmxlSW5kZXgpIHtcbiAgICAgIHZhciBudW1iZXJPZlNsaWRlc1Nob3dpbmcgPSBnZXROdW1iZXJTbGlkZXNTaG93aW5nKCk7XG4gICAgICAvLyBvbmx5IGFwcGx5IGF0dHJpYnV0ZXMgaWYgdGhlIHNldHRpbmcgaXMgZW5hYmxlZCBhbmQgbm90IGluIHRpY2tlciBtb2RlXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmFyaWFIaWRkZW4gJiYgIXNsaWRlci5zZXR0aW5ncy50aWNrZXIpIHtcbiAgICAgICAgLy8gYWRkIGFyaWEtaGlkZGVuPXRydWUgdG8gYWxsIGVsZW1lbnRzXG4gICAgICAgIHNsaWRlci5jaGlsZHJlbi5hdHRyKCdhcmlhLWh
98pZGRlbicsICd0cnVlJyk7XG4gICAgICAgIC8vIGdldCB0aGUgdmlzaWJsZSBlbGVtZW50cyBhbmQgY2hhbmdlIHRvIGFyaWEtaGlkZGVuPWZhbHNlXG4gICAgICAgIHNsaWRlci5jaGlsZHJlbi5zbGljZShzdGFydFZpc2libGVJbmRleCwgc3RhcnRWaXNpYmxlSW5kZXggKyBudW1iZXJPZlNsaWRlc1Nob3dpbmcpLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5kZXggYWNjb3JkaW5nIHRvIHByZXNlbnQgcGFnZSByYW5nZVxuICAgICAqXG4gICAgICogQHBhcmFtIHNsaWRlT25kZXggKGludClcbiAgICAgKiAgLSB0aGUgZGVzaXJlZCBzbGlkZSBpbmRleFxuICAgICAqL1xuICAgIHZhciBzZXRTbGlkZUluZGV4ID0gZnVuY3Rpb24oc2xpZGVJbmRleCkge1xuICAgICAgaWYgKHNsaWRlSW5kZXggPCAwKSB7XG4gICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuaW5maW5pdGVMb29wKSB7XG4gICAgICAgICAgcmV0dXJuIGdldFBhZ2VyUXR5KCkgLSAxO1xuICAgICAgICB9ZWxzZSB7XG4gICAgICAgICAgLy93ZSBkb24ndCBnbyB0byB1bmRlZmluZWQgc2xpZGVzXG4gICAgICAgICAgcmV0dXJuIHNsaWRlci5hY3RpdmUuaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIC8vIGlmIHNsaWRlSW5kZXggaXMgZ3JlYXRlciB0aGFuIGNoaWxkcmVuIGxlbmd0aCwgc2V0IGFjdGl2ZSBpbmRleCB0byAwICh0aGlzIGhhcHBlbnMgZHVyaW5nIGluZmluaXRlIGxvb3ApXG4gICAgICB9IGVsc2UgaWYgKHNsaWRlSW5kZXggPj0gZ2V0UGFnZXJRdHkoKSkge1xuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCkge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vd2UgZG9uJ3QgbW92ZSB0byB1bmRlZmluZWQgcGFnZXNcbiAgICAgICAgICByZXR1cm4gc2xpZGVyLmFjdGl2ZS5pbmRleDtcbiAgICAgICAgfVxuICAgICAgLy8gc2V0IGFjdGl2ZSBpbmRleCB0byByZXF1ZXN0ZWQgc2xpZGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzbGlkZUluZGV4O1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAqID0gUFVCTElDIEZVTkNUSU9OU1xuICAgICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBzbGlkZSB0cmFuc2l0aW9uIHRvIHRoZSBzcGVjaWZpZWQgc2xpZGVcbiAgICAgKlxuICAgICAqIEBwYXJhbSBzbGlkZUluZGV4IChpbnQpXG4gICAgICogIC0gdGhlIGRlc3RpbmF0aW9uIHNsaWRlJ3MgaW5kZXggKHplcm8tYmFzZWQpXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZGlyZWN0aW9uIChzdHJpbmcpXG4gICAgICogIC0gSU5URVJOQUwgVVNFIE9OTFkgLSB0aGUgZGlyZWN0aW9uIG9mIHRyYXZlbCAoXCJwcmV2XCIgLyBcIm5leHRcIilcbiAgICAgKi9cbiAgICBlbC5nb1RvU2xpZGUgPSBmdW5jdGlvbihzbGlkZUluZGV4LCBkaXJlY3Rpb24pIHtcbiAgICAgIC8vIG9uU2xpZGVCZWZvcmUsIG9uU2xpZGVOZXh0LCBvblNsaWRlUHJldiBjYWxsYmFja3NcbiAgICAgIC8vIEFsbG93IHRyYW5zaXRpb24gY2FuY2VsaW5nIGJhc2VkIG9uIHJldHVybmVkIHZhbHVlXG4gICAgICB2Y
98XIgcGVyZm9ybVRyYW5zaXRpb24gPSB0cnVlLFxuICAgICAgbW92ZUJ5ID0gMCxcbiAgICAgIHBvc2l0aW9uID0ge2xlZnQ6IDAsIHRvcDogMH0sXG4gICAgICBsYXN0Q2hpbGQgPSBudWxsLFxuICAgICAgbGFzdFNob3dpbmdJbmRleCwgZXEsIHZhbHVlLCByZXF1ZXN0RWw7XG4gICAgICAvLyBzdG9yZSB0aGUgb2xkIGluZGV4XG4gICAgICBzbGlkZXIub2xkSW5kZXggPSBzbGlkZXIuYWN0aXZlLmluZGV4O1xuICAgICAgLy9zZXQgbmV3IGluZGV4XG4gICAgICBzbGlkZXIuYWN0aXZlLmluZGV4ID0gc2V0U2xpZGVJbmRleChzbGlkZUluZGV4KTtcblxuICAgICAgLy8gaWYgcGx1Z2luIGlzIGN1cnJlbnRseSBpbiBtb3Rpb24sIGlnbm9yZSByZXF1ZXN0XG4gICAgICBpZiAoc2xpZGVyLndvcmtpbmcgfHwgc2xpZGVyLmFjdGl2ZS5pbmRleCA9PT0gc2xpZGVyLm9sZEluZGV4KSB7IHJldHVybjsgfVxuICAgICAgLy8gZGVjbGFyZSB0aGF0IHBsdWdpbiBpcyBpbiBtb3Rpb25cbiAgICAgIHNsaWRlci53b3JraW5nID0gdHJ1ZTtcblxuICAgICAgcGVyZm9ybVRyYW5zaXRpb24gPSBzbGlkZXIuc2V0dGluZ3Mub25TbGlkZUJlZm9yZS5jYWxsKGVsLCBzbGlkZXIuY2hpbGRyZW4uZXEoc2xpZGVyLmFjdGl2ZS5pbmRleCksIHNsaWRlci5vbGRJbmRleCwgc2xpZGVyLmFjdGl2ZS5pbmRleCk7XG5cbiAgICAgIC8vIElmIHRyYW5zaXRpb25zIGNhbmNlbGVkLCByZXNldCBhbmQgcmV0dXJuXG4gICAgICBpZiAodHlwZW9mIChwZXJmb3JtVHJhbnNpdGlvbikgIT09ICd1bmRlZmluZWQnICYmICFwZXJmb3JtVHJhbnNpdGlvbikge1xuICAgICAgICBzbGlkZXIuYWN0aXZlLmluZGV4ID0gc2xpZGVyLm9sZEluZGV4OyAvLyByZXN0b3JlIG9sZCBpbmRleFxuICAgICAgICBzbGlkZXIud29ya2luZyA9IGZhbHNlOyAvLyBpcyBub3QgaW4gbW90aW9uXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ25leHQnKSB7XG4gICAgICAgIC8vIFByZXZlbnQgY2FuY2VsaW5nIGluIGZ1dHVyZSBmdW5jdGlvbnMgb3IgbGFjayB0aGVyZS1vZiBmcm9tIG5lZ2F0aW5nIHByZXZpb3VzIGNvbW1hbmRzIHRvIGNhbmNlbFxuICAgICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy5vblNsaWRlTmV4dC5jYWxsKGVsLCBzbGlkZXIuY2hpbGRyZW4uZXEoc2xpZGVyLmFjdGl2ZS5pbmRleCksIHNsaWRlci5vbGRJbmRleCwgc2xpZGVyLmFjdGl2ZS5pbmRleCkpIHtcbiAgICAgICAgICBwZXJmb3JtVHJhbnNpdGlvbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ3ByZXYnKSB7XG4gICAgICAgIC8vIFByZXZlbnQgY2FuY2VsaW5nIGluIGZ1dHVyZSBmdW5jdGlvbnMgb3IgbGFjayB0aGVyZS1vZiBmcm9tIG5lZ2F0aW5nIHByZXZpb3VzIGNvbW1hbmRzIHRvIGNhbmNlbFxuICAgICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy5vblNsaWRlUHJldi5jYWxsKGVsLCBzbGlkZXIuY2hpbGRyZW4uZXEoc2xpZGVyLmFjdGl2ZS5pbmRleCksIHNsaWRlci5vbGRJbmRleCwgc2xpZGVyLmFjdGl2ZS5pbmRleCkpIHtcbiAgICAgICAgICBwZXJmb3JtVHJhbnNpdGlvbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGNoZWNrIGlmIGxhc3Qgc2xpZGVcbiAgICAgIHNsaWRlci5hY3RpdmUubGFzdCA9IHNsaWRlci5hY3RpdmUuaW5kZXggPj0gZ2V0UGFnZXJRdHkoKSAtIDE7XG4gICAgICAvLyB1cGRhdGUgdGhlIHBhZ2VyIHdpdGggYWN0aXZlIGNsYXNzXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLnBhZ2VyIHx8IHNsaWRlci5zZXR0aW5ncy5wYWdlckN1c3RvbSkgeyB1cGRhdGVQYWdlckFjdGl2ZShzbGlkZXIuYWN0aXZlLmluZGV4KTsgfVxuICAgICAgLy8gLy8gY2hlY2sgZm9yIGRpcmVjdGlvbiBjb250cm9sIHVwZGF0ZVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5jb250cm9scykgeyB1cGRhdGVEaXJlY3Rpb25Db250cm9scygpOyB9XG4gICAgICAvLyBpZiBzbGlkZXIgaXMgc2V0IHRvIG1vZGU6IFwiZmFkZVwiXG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdmYWRlJykge1xuICAgICAgICAvLyBpZiBhZGFwdGl2ZUhlaWdodCBpcyB0cnVlIGFuZCBuZXh0IGhlaWdodCBpcyBkaWZmZXJlbnQgZnJvbSBjdXJyZW50IGhlaWdodCwgYW5pbWF0ZSB0byB0aGUgbmV3IGhlaWdodFxuICAgICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmFkYXB0aXZlSGVpZ2h0ICYmIHNsaWRlci52aWV3cG9ydC5oZWlnaHQoKSAhPT0gZ2V0Vmlld3BvcnRIZWlnaHQoKSkge1xuICAgICAgICAgIHNsaWRlci52aWV3cG9ydC5hbmltYXRlKHtoZWlnaHQ6IGdldFZpZXdwb3J0SGVpZ2h0KCl9LCBzbGlkZXIuc2V0dGluZ3MuYWRhcHRpdmVIZWlnaHRTcGVlZCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZmFkZSBvdXQgdGhlIHZpc2libGUgY2hpbGQgYW5kIHJlc2V0IGl0cyB6LWluZGV4IHZhbHVlXG4gICAgICAgIHNsaWRlci5jaGlsZHJlbi5maWx0ZXIoJzp2aXNpYmxlJykuZmFkZU91dChzbGlkZXIuc2V0dGluZ3Muc3BlZWQpLmNzcyh7ekluZGV4OiAwfSk7XG4gICAgICAgIC8vIGZhZGUgaW4gdGhlIG5ld2x5IHJlcXVlc3RlZCBzbGlkZVxuICAgICAgICBzbGlkZXIuY2hpbGRyZW4uZXEoc2xpZGVyLmFjdGl2ZS5pbmRleCkuY3NzKCd6SW5kZXgnLCBzbGlkZXIuc2V0dGluZ3Muc2xpZGVaSW5kZXggKyAxKS5mYWRlSW4oc2xpZGVyLnNldHRpbmdzLnNwZWVkLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAkKHRoaXMpLmNzcygnekluZGV4Jywgc2xpZGVyLnNldHRpbmdzLnNsaWRlWkluZGV4KTtcbiAgICAgICAgICB1cGRhdGVBZnRlclNsaWRlVHJhbnNpdGlvbigpO1xuICAgICAgICB9KTtcbiAgICAgIC8vIHNsaWRlciBtb2RlIGlzIG5vdCBcImZhZGVcIlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaWYgYWRhcHRpdmVIZWlnaHQgaXMgdHJ1ZSBhbmQgbmV4dCBoZWlnaHQgaXMgZGlmZmVyZW50IGZyb20gY3VycmVudCBoZWlnaHQsIGFuaW1hdGUgdG8gdGhlIG5ldyBoZWlnaHRcbiAgICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hZGFwdGl2ZUhlaWdodCAmJiBzbGlkZXIudmlld3BvcnQuaGVpZ2h0KCkgIT09IGdldFZpZXdwb3J0SGVpZ2h0KCkpIHtcbiAgICAgICAgICBzbGlkZXIudmlld3BvcnQuYW5pbWF0ZSh7aGVpZ2h0OiBnZXRWaWV3cG9ydEhlaWdodCgpfSwgc2xpZGVyLnNldHRpbmdzLmFkYXB0aXZlSGVpZ2h0U3BlZWQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGNhcm91c2VsIGFuZCBub3QgaW5maW5pdGUgbG9vcFxuICAgICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy5pbmZpbml0ZUxvb3AgJiYgc2xpZGVyLmNhcm91c2VsICYmIHNsaWRlci5hY3RpdmUubGFzdCkge1xuICAgICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MubW9kZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICAvLyBnZXQgdGhlIGxhc3QgY2hpbGQgcG9zaXRpb25cbiAgICAgICAgICAgIGxhc3RDaGlsZCA9IHNsaWRlci5jaGlsZHJlbi5lcShzbGlkZXIuY2hpbGRyZW4ubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGxhc3RDaGlsZC5wb3NpdGlvbigpO1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBzbGlkZVxuICAgICAgICAgICAgbW92ZUJ5ID0gc2xpZGVyLnZpZXdwb3J0LndpZHRoKCkgLSBsYXN0Q2hpbGQub3V0ZXJXaWR0aCgpO1xuICAgICAgICAgI
98H0gZWxzZSB7XG4gICAgICAgICAgICAvLyBnZXQgbGFzdCBzaG93aW5nIGluZGV4IHBvc2l0aW9uXG4gICAgICAgICAgICBsYXN0U2hvd2luZ0luZGV4ID0gc2xpZGVyLmNoaWxkcmVuLmxlbmd0aCAtIHNsaWRlci5zZXR0aW5ncy5taW5TbGlkZXM7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IHNsaWRlci5jaGlsZHJlbi5lcShsYXN0U2hvd2luZ0luZGV4KS5wb3NpdGlvbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBob3Jpem9udGFsIGNhcm91c2VsLCBnb2luZyBwcmV2aW91cyB3aGlsZSBvbiBmaXJzdCBzbGlkZSAoaW5maW5pdGVMb29wIG1vZGUpXG4gICAgICAgIH0gZWxzZSBpZiAoc2xpZGVyLmNhcm91c2VsICYmIHNsaWRlci5hY3RpdmUubGFzdCAmJiBkaXJlY3Rpb24gPT09ICdwcmV2Jykge1xuICAgICAgICAgIC8vIGdldCB0aGUgbGFzdCBjaGlsZCBwb3NpdGlvblxuICAgICAgICAgIGVxID0gc2xpZGVyLnNldHRpbmdzLm1vdmVTbGlkZXMgPT09IDEgPyBzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzIC0gZ2V0TW92ZUJ5KCkgOiAoKGdldFBhZ2VyUXR5KCkgLSAxKSAqIGdldE1vdmVCeSgpKSAtIChzbGlkZXIuY2hpbGRyZW4ubGVuZ3RoIC0gc2xpZGVyLnNldHRpbmdzLm1heFNsaWRlcyk7XG4gICAgICAgICAgbGFzdENoaWxkID0gZWwuY2hpbGRyZW4oJy5ieC1jbG9uZScpLmVxKGVxKTtcbiAgICAgICAgICBwb3NpdGlvbiA9IGxhc3RDaGlsZC5wb3NpdGlvbigpO1xuICAgICAgICAvLyBpZiBpbmZpbml0ZSBsb29wIGFuZCBcIk5leHRcIiBpcyBjbGlja2VkIG9uIHRoZSBsYXN0IHNsaWRlXG4gICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnbmV4dCcgJiYgc2xpZGVyLmFjdGl2ZS5pbmRleCA9PT0gMCkge1xuICAgICAgICAgIC8vIGdldCB0aGUgbGFzdCBjbG9uZSBwb3NpdGlvblxuICAgICAgICAgIHBvc2l0aW9uID0gZWwuZmluZCgnPiAuYngtY2xvbmUnKS5lcShzbGlkZXIuc2V0dGluZ3MubWF4U2xpZGVzKS5wb3NpdGlvbigpO1xuICAgICAgICAgIHNsaWRlci5hY3RpdmUubGFzdCA9IGZhbHNlO1xuICAgICAgICAvLyBub3JtYWwgbm9uLXplcm8gcmVxdWVzdHNcbiAgICAgICAgfSBlbHNlIGlmIChzbGlkZUluZGV4ID49IDApIHtcbiAgICAgICAgICAvL3BhcnNlSW50IGlzIGFwcGxpZWQgdG8gYWxsb3cgZmxvYXRzIGZvciBzbGlkZXMvcGFnZVxuICAgICAgICAgIHJlcXVlc3RFbCA9IHNsaWRlSW5kZXggKiBwYXJzZUludChnZXRNb3ZlQnkoKSk7XG4gICAgICAgICAgcG9zaXRpb24gPSBzbGlkZXIuY2hpbGRyZW4uZXEocmVxdWVzdEVsKS5wb3NpdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyogSWYgdGhlIHBvc2l0aW9uIGRvZXNuJ3QgZXhpc3RcbiAgICAgICAgICogKGUuZy4gaWYgeW91IGRlc3Ryb3kgdGhlIHNsaWRlciBvbiBhIG5leHQgY2xpY2spLFxuICAgICAgICAgKiBpdCBkb2Vzbid0IHRocm93IGFuIGVycm9yLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiAocG9zaXRpb24pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhbHVlID0gc2xpZGVyLnNldHRpbmdzLm1vZGUgPT09ICdob3Jpem9udGFsJyA/IC0ocG9zaXRpb24ubGVmdCAtIG1vdmVCeSkgOiAtcG9zaXRpb24udG9wO1xuICAgICAgICAgIC8vIHBsdWdpbiB2YWx1ZXMgdG8gYmUgYW5pbWF0ZWRcbiAgICAgICAgICBzZXRQb3NpdGlvblByb3BlcnR5KHZhbHVlLCAnc2xpZGUnLCBzbGlkZXIuc2V0dGluZ3Muc3BlZWQpO1xuICAgICAgICB9XG4gICAgICAgIHNsaWRlci53b3JraW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmFyaWFIaWRkZW4pIHsgYXBwbHlBcmlhSGlkZGVuQXR0cmlidXRlcyhzbGlkZXIuYWN0aXZlLmluZGV4ICogZ2V0TW92ZUJ5KCkpOyB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRyYW5zaXRpb25zIHRvIHRoZSBuZXh0IHNsaWRlIGluIHRoZSBzaG93XG4gICAgICovXG4gICAgZWwuZ29Ub05leHRTbGlkZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gaWYgaW5maW5pdGVMb29wIGlzIGZhbHNlIGFuZCBsYXN0IHBhZ2UgaXMgc2hvd2luZywgZGlzcmVnYXJkIGNhbGxcbiAgICAgIGlmICghc2xpZGVyLnNldHRpbmdzLmluZmluaXRlTG9vcCAmJiBzbGlkZXIuYWN0aXZlLmxhc3QpIHsgcmV0dXJuOyB9XG5cdCAgaWYgKHNsaWRlci53b3JraW5nID09PSB0cnVlKXsgcmV0dXJuIDt9XG4gICAgICB2Y
98XIgcGFnZXJJbmRleCA9IHBhcnNlSW50KHNsaWRlci5hY3RpdmUuaW5kZXgpICsgMTtcbiAgICAgIGVsLmdvVG9TbGlkZShwYWdlckluZGV4LCAnbmV4dCcpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2l0aW9ucyB0byB0aGUgcHJldiBzbGlkZSBpbiB0aGUgc2hvd1xuICAgICAqL1xuICAgIGVsLmdvVG9QcmV2U2xpZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGlmIGluZmluaXRlTG9vcCBpcyBmYWxzZSBhbmQgbGFzdCBwYWdlIGlzIHNob3dpbmcsIGRpc3JlZ2FyZCBjYWxsXG4gICAgICBpZiAoIXNsaWRlci5zZXR0aW5ncy5pbmZpbml0ZUxvb3AgJiYgc2xpZGVyLmFjdGl2ZS5pbmRleCA9PT0gMCkgeyByZXR1cm47IH1cblx0ICBpZiAoc2xpZGVyLndvcmtpbmcgPT09IHRydWUpeyByZXR1cm4gO31cbiAgICAgIHZhciBwYWdlckluZGV4ID0gcGFyc2VJbnQoc2xpZGVyLmFjdGl2ZS5pbmRleCkgLSAxO1xuICAgICAgZWwuZ29Ub1NsaWRlKHBhZ2VySW5kZXgsICdwcmV2Jyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgYXV0byBzaG93XG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJldmVudENvbnRyb2xVcGRhdGUgKGJvb2xlYW4pXG4gICAgICogIC0gaWYgdHJ1ZSwgYXV0byBjb250cm9scyBzdGF0ZSB3aWxsIG5vdCBiZSB1cGRhdGVkXG4gICAgICovXG4gICAgZWwuc3RhcnRBdXRvID0gZnVuY3Rpb24ocHJldmVudENvbnRyb2xVcGRhdGUpIHtcbiAgICAgIC8vIGlmIGFuIGludGVydmFsIGFscmVhZHkgZXhpc3RzLCBkaXNyZWdhcmQgY2FsbFxuICAgICAgaWYgKHNsaWRlci5pbnRlcnZhbCkgeyByZXR1cm47IH1cbiAgICAgIC8vIGNyZWF0ZSBhbiBpbnRlcnZhbFxuICAgICAgc2xpZGVyLmludGVydmFsID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYXV0b0RpcmVjdGlvbiA9PT0gJ25leHQnKSB7XG4gICAgICAgICAgZWwuZ29Ub05leHRTbGlkZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsLmdvVG9QcmV2U2xpZGUoKTtcbiAgICAgICAgfVxuICAgICAgfSwgc2xpZGVyLnNldHRpbmdzLnBhdXNlKTtcblx0ICAvL2FsbGJhY2sgZm9yIHdoZW4gdGhlIGF1dG8gcm90YXRlIHN0YXR1cyBjaGFuZ2VzXG5cdCAgc2xpZGVyLnNldHRpbmdzLm9uQXV0b0NoYW5nZS5jYWxsKGVsLCB0cnVlKTtcbiAgICAgIC8vIGlmIGF1dG8gY29udHJvbHMgYXJlIGRpc3BsYXllZCBhbmQgcHJldmVudENvbnRyb2xVcGRhdGUgaXMgbm90IHRydWVcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MuYXV0b0NvbnRyb2xzICYmIHByZXZlbnRDb250cm9sVXBkYXRlICE9PSB0cnVlKSB7IHVwZGF0ZUF1dG9Db250cm9scygnc3RvcCcpOyB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFN0b3BzIHRoZSBhdXRvIHNob3dcbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcmV2ZW50Q29udHJvbFVwZGF0ZSAoYm9vbGVhbilcbiAgICAgKiAgLSBpZiB0cnVlLCBhdXRvIGNvbnRyb2xzIHN0YXRlIHdpbGwgbm90IGJlIHVwZGF0ZWRcbiAgICAgKi9cbiAgICBlbC5zdG9wQXV0byA9IGZ1bmN0aW9uKHByZXZlbnRDb250cm9sVXBkYXRlKSB7XG4gICAgICAvLyBpZiBzbGlkZXIgaXMgYXV0byBwYXVzZWQsIGp1c3QgY2xlYXIgdGhhdCBzdGF0ZVxuICAgICAgaWYgKHNsaWRlci5hdXRvUGF1c2VkKSBzbGlkZXIuYXV0b1BhdXNlZCA9IGZhbHNlO1xuICAgICAgLy8gaWYgbm8gaW50ZXJ2YWwgZXhpc3RzLCBkaXNyZWdhcmQgY2FsbFxuICAgICAgaWYgKCFzbGlkZXIuaW50ZXJ2YWwpIHsgcmV0dXJuOyB9XG4gICAgICAvLyBjbGVhciB0aGUgaW50ZXJ2YWxcbiAgICAgIGNsZWFySW50ZXJ2YWwoc2xpZGVyLmludGVydmFsKTtcbiAgICAgIHNsaWRlci5pbnRlcnZhbCA9IG51bGw7XG5cdCAgLy9hbGxiYWNrIGZvciB3aGVuIHRoZSBhdXRvIHJvdGF0ZSBzdGF0dXMgY2hhbmdlc1xuXHQgIHNsaWRlci5zZXR0aW5ncy5vbkF1dG9DaGFuZ2UuY2FsbChlbCwgZmFsc2UpO1xuICAgICAgLy8gaWYgYXV0byBjb250cm9scyBhcmUgZGlzcGxheWVkIGFuZCBwcmV2ZW50Q29udHJvbFVwZGF0ZSBpcyBub3QgdHJ1ZVxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5hdXRvQ29udHJvbHMgJiYgcHJldmVudENvbnRyb2xVcGRhdGUgIT09IHRydWUpIHsgdXBkYXRlQXV0b0NvbnRyb2xzKCdzdGFydCcpOyB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY3VycmVudCBzbGlkZSBpbmRleCAoemVyby1iYXNlZClcbiAgICAgKi9cbiAgICBlbC5nZXRDdXJyZW50U2xpZGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzbGlkZXIuYWN0aXZlLmluZGV4O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGN1cnJlbnQgc2xpZGUgZWxlbWVudFxuICAgICAqL1xuICAgIGVsLmdldEN1cnJlbnRTbGlkZUVsZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzbGlkZXIuY2hpbGRyZW4uZXEoc2xpZGVyLmFjdGl2ZS5pbmRleCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBzbGlkZSBlbGVtZW50XG4gICAgICogQHBhcmFtIGluZGV4IChpbnQpXG4gICAgICogIC0gVGhlIGluZGV4ICh6ZXJvLWJhc2VkKSBvZiB0aGUgZWxlbWVudCB5b3Ugd2FudCByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBlbC5nZXRTbGlkZUVsZW1lbnQgPSBmdW5jdGlvbihpbmRleCkge1xuICAgICAgcmV0dXJuIHNsaWRlci5jaGlsZHJlbi5lcShpbmRleCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgbnVtYmVyIG9mIHNsaWRlcyBpbiBzaG93XG4gICAgICovXG4gICAgZWwuZ2V0U2xpZGVDb3VudCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHNsaWRlci5jaGlsZHJlbi5sZW5ndGg7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybiBzbGlkZXIud29ya2luZyB2YXJpYWJsZVxuICAgICAqL1xuICAgIGVsLmlzV29ya2luZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHNsaWRlci53b3JraW5nO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgYWxsIGR5bmFtaWMgc2xpZGVyIGVsZW1lbnRzXG4gICAgICovXG4gICAgZWwucmVkcmF3U2xpZGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyByZXNpemUgYWxsIGNoaWxkcmVuIGluIHJhdGlvIHRvIG5ldyBzY3JlZW4gc2l6ZVxuICAgICAgc2xpZGVyLmNoaWxkcmVuLmFkZChlbC5maW5kKCcuYngtY2xvbmUnKSkub3V0ZXJXaWR0aChnZXRTbGlkZVdpZHRoKCkpO1xuICAgICAgLy8gYWRqdXN0IHRoZSBoZWlnaHRcbiAgICAgIHNsaWRlci52aWV3cG9ydC5jc3MoJ2hlaWdodCcsIGdldFZpZXdwb3J0SGVpZ2h0KCkpO1xuICAgICAgLy8gdXBkYXRlIHRoZSBzbGlkZSBwb3NpdGlvblxuICAgICAgaWYgKCFzbGlkZXIuc2V0dGluZ3MudGlja2VyKSB7IHNldFNsaWRlUG9zaXRpb24oKTsgfVxuICAgICAgLy8gaWYgYWN0aXZlLmxhc3Qgd2FzIHRydWUgYmVmb3JlIHRoZSBzY3JlZW4gcmVzaXplLCB3ZSB3YW50XG4gICAgICAvLyB0byBrZWVwIGl0IGxhc3Qgbm8gbWF0dGVyIHdoYXQgc2NyZWVuIHNpemUgd2UgZW5kIG9uXG4gICAgICBpZiAoc2xpZGVyLmFjdGl2ZS5sYXN0KSB7IHNsaWRlci5hY3RpdmUuaW5kZXggPSBnZXRQYWdlclF0eSgpIC0gMTsgfVxuICAgICAgLy8gaWYgdGhlIGFjdGl2ZSBpbmRleCAocGFnZSkgbm8gbG9uZ2VyIGV4aXN0cyBkdWUgdG8gdGhlIHJlc2l6ZSwgc2ltcGx5IHNldCB0aGUgaW5kZXggYXMgbGFzdFxuICAgICAgaWYgKHNsaWRlci5hY3RpdmUuaW5kZXggPj0gZ2V0UGFnZXJRdHkoKSkgeyBzbGlkZXIuYWN0aXZlLmxhc3QgPSB0cnVlOyB9XG4gICAgICAvLyBpZiBhIHBhZ2VyIGlzIGJlaW5nIGRpc3BsYXllZCBhbmQgYS
98BjdXN0b20gcGFnZXIgaXMgbm90IGJlaW5nIHVzZWQsIHVwZGF0ZSBpdFxuICAgICAgaWYgKHNsaWRlci5zZXR0aW5ncy5wYWdlciAmJiAhc2xpZGVyLnNldHRpbmdzLnBhZ2VyQ3VzdG9tKSB7XG4gICAgICAgIHBvcHVsYXRlUGFnZXIoKTtcbiAgICAgICAgdXBkYXRlUGFnZXJBY3RpdmUoc2xpZGVyLmFjdGl2ZS5pbmRleCk7XG4gICAgICB9XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmFyaWFIaWRkZW4pIHsgYXBwbHlBcmlhSGlkZGVuQXR0cmlidXRlcyhzbGlkZXIuYWN0aXZlLmluZGV4ICogZ2V0TW92ZUJ5KCkpOyB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlc3Ryb3kgdGhlIGN1cnJlbnQgaW5zdGFuY2Ugb2YgdGhlIHNsaWRlciAocmV2ZXJ0IGV2ZXJ5dGhpbmcgYmFjayB0byBvcmlnaW5hbCBzdGF0ZSlcbiAgICAgKi9cbiAgICBlbC5kZXN0cm95U2xpZGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBkb24ndCBkbyBhbnl0aGluZyBpZiBzbGlkZXIgaGFzIGFscmVhZHkgYmVlbiBkZXN0cm95ZWRcbiAgICAgIGlmICghc2xpZGVyLmluaXRpYWxpemVkKSB7IHJldHVybjsgfVxuICAgICAgc2xpZGVyLmluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICAkKCcuYngtY2xvbmUnLCB0aGlzKS5yZW1vdmUoKTtcbiAgICAgIHNsaWRlci5jaGlsZHJlbi5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoJCh0aGlzKS5kYXRhKCdvcmlnU3R5bGUnKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgJCh0aGlzKS5hdHRyKCdzdHlsZScsICQodGhpcykuZGF0YSgnb3JpZ1N0eWxlJykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICQodGhpcykucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoJCh0aGlzKS5kYXRhKCdvcmlnU3R5bGUnKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuYXR0cignc3R5bGUnLCAkKHRoaXMpLmRhdGEoJ29yaWdTdHlsZScpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICQodGhpcykucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICAgIH1cbiAgICAgICQodGhpcykudW53cmFwKCkudW53cmFwKCk7XG4gICAgICBpZiAoc2xpZGVyLmNvbnRyb2xzLmVsKSB7IHNsaWRlci5jb250cm9scy5lbC5yZW1vdmUoKTsgfVxuICAgICAgaWYgKHNsaWRlci5jb250cm9scy5uZXh0KSB7IHNsaWRlci5jb250cm9scy5uZXh0LnJlbW92ZSgpOyB9XG4gICAgICBpZiAoc2xpZGVyLmNvbnRyb2xzLnByZXYpIHsgc2xpZGVyLmNvbnRyb2xzLnByZXYucmVtb3ZlKCk7IH1cbiAgICAgIGlmIChzbGlkZXIucGFnZXJFbCAmJiBzbGlkZXIuc2V0dGluZ3MuY29udHJvbHMgJiYgIXNsaWRlci5zZXR0aW5ncy5wYWdlckN1c3RvbSkgeyBzbGlkZXIucGFnZXJFbC5yZW1vdmUoKTsgfVxuICAgICAgJCgnLmJ4LWNhcHRpb24nLCB0aGlzKS5yZW1vdmUoKTtcbiAgICAgIGlmIChzbGlkZXIuY29udHJvbHMuYXV0b0VsKSB7IHNsaWRlci5jb250cm9scy5hdXRvRWwucmVtb3ZlKCk7IH1cbiAgICAgIGNsZWFySW50ZXJ2YWwoc2xpZGVyLmludGVydmFsKTtcbiAgICAgIGlmIChzbGlkZXIuc2V0dGluZ3MucmVzcG9uc2l2ZSkgeyAkKHdpbmRvdykub2ZmKCdyZXNpemUnLCByZXNpemVXaW5kb3cpOyB9XG4gICAgICBpZiAoc2xpZGVyLnNldHRpbmdzLmtleWJvYXJkRW5hYmxlZCkgeyAkKGRvY3VtZW50KS5vZmYoJ2tleWRvd24nLCBrZXlQcmVzcyk7IH1cbiAgICAgIC8vcmVtb3ZlIHNlbGYgcmVmZXJlbmNlIGluIGRhdGFcbiAgICAgICQodGhpcykucmVtb3ZlRGF0YSgnYnhTbGlkZXInKTtcblx0ICAvLyByZW1vdmUgZ2xvYmFsIHdpbmRvdyBoYW5kbGVyc1xuXHQgICQod2luZG93KS5vZmYoJ2JsdXInLCB3aW5kb3dCbHVySGFuZGxlcikub2ZmKCdmb2N1cycsIHdpbmRvd0ZvY3VzSGFuZGxlcik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbG9hZCB0aGUgc2xpZGVyIChyZXZlcnQgYWxsIERPTSBjaGFuZ2VzLCBhbmQgcmUtaW5pdGlhbGl6ZSlcbiAgICAgKi9cbiAgICBlbC5yZWxvYWRTbGlkZXIgPSBmdW5jdGlvbihzZXR0aW5ncykge1xuICAgICAgaWYgKHNldHRpbmdzICE9PSB1bmRlZmluZWQpIHsgb3B0aW9ucyA9IHNldHRpbmdzOyB9XG4gICAgICBlbC5kZXN0cm95U2xpZGVyKCk7XG4gICAgICBpbml0KCk7XG4gICAgICAvL3N0b3JlIHJlZmVyZW5jZSB0byBzZWxmIGluIG9yZGVyIHRvIGFjY2VzcyBwdWJsaWMgZnVuY3Rpb25zIGxhdGVyXG4gICAgICAkKGVsKS5kYXRhKCdieFNsaWRlcicsIHRoaXMpO1xuICAgIH07XG5cbiAgICBpbml0KCk7XG5cbiAgICAkKGVsKS5kYXRhKCdieFNsaWRlcicsIHRoaXMpO1xuXG4gICAgLy8gcmV0dXJucyB0aGUgY3VycmVudCBqUXVlcnkgb2JqZWN0XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbn0pKGpRdWVyeSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9ieHNsaWRlci9kaXN0L2pxdWVyeS5ieHNsaWRlci5qc1xuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2\n"); 99 100/***/ }), 101/* 3 */ 102/*!******************************************************************!*\ 103 !*** ./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.js ***! 104 \******************************************************************/ 105/*! dynamic exports provided */ 106/*! all exports used */
107/***/ (function(module, exports) { 108 109eval("// ==================================================\n// fancyBox v3.5.7\n//\n// Licensed GPLv3 for open source use\n// or fancyBox Commercial License for commercial use\n//\n// http://fancyapps.com/fancybox/\n// Copyright 2019 fancyApps\n//\n// ==================================================\n(function (window, document, $, undefined) {\r\n \"use strict\";\r\n\r\n window.console = window.console || {\r\n info: function (stuff) {}\r\n };\r\n\r\n // If there's no jQuery, fancyBox can't work\r\n // =========================================\r\n\r\n if (!$) {\r\n return;\r\n }\r\n\r\n // Check if fancyBox is already initialized\r\n // ========================================\r\n\r\n if ($.fn.fancybox) {\r\n console.info(\"fancyBox already initialized\");\r\n\r\n return;\r\n }\r\n\r\n // Private default settings\r\n // ========================\r\n\r\n var defaults = {\r\n // Close existing modals\r\n // Set this to false if you do not need to stack multiple instances\r\n closeExisting: false,\r\n\r\n // Enable infinite gallery navigation\r\n loop: false,\r\n\r\n // Horizontal space between slides\r\n gutter: 50,\r\n\r\n // Enable keyboard navigation\r\n keyboard: true,\r\n\r\n // Should allow caption to overlap the content\r\n preventCaptionOverlap: true,\r\n\r\n // Should display navigation arrows at the screen edges\r\n arrows: true,\r\n\r\n // Should display counter at the top left corner\r\n infobar: true,\r\n\r\n // Should display close button (using `btnTpl.smallBtn` template) over the content\r\n // Can be true, false, \"auto\"\r\n // If \"auto\" - will be automatically enabled for \"html\", \"inline\" or \"ajax\" items\r\n smallBtn: \"auto\",\r\n\r\n // Should display toolbar (buttons at the top)\r\n // Can be true, false, \"auto\"\r\n // If \"auto\" - will be automatically hidden if \"smallBtn\" is enabled\r\n toolbar: \"auto\",\r\n\r\n // What buttons should appear in the top right corner.\r\n // Buttons will be created using templates from `btnTpl` option\r\n // and they will be placed into toolbar (class=\"fancybox-toolbar\"` element)\r\n buttons: [\r\n \"zoom\",\r\n //\"share\",\r\n \"slideShow\",\r\n //\"fullScreen\",\r\n //\"download\",\r\n \"thumbs\",\r\n \"close\"\r\n ],\r\n\r\n // Detect \"idle\" time in seconds\r\n idleTime: 3,\r\n\r\n // Disable right-click and use simple image protection for images\r\n protect: false,\r\n\r\n // Shortcut to make content \"modal\" - disable keyboard navigtion, hide buttons, etc\r\n modal: false,\r\n\r\n image: {\r\n // Wait for images to load before displaying\r\n // true - wait for image to load and then display;\r\n // false - display thumbnail and load the full-sized image over top,\r\n // requires predefined image dimensions (`data-width` and `data-height` attributes)\r\n preload: false\r\n },\r\n\r\n ajax: {\r\n // Object containing settings for ajax request\r\n settings: {\r\n // This helps to indicate that request comes from the modal\r\n // Feel free to change naming\r\n data: {\r\n fancybox: true\r\n }\r\n }\r\n },\r\n\r\n iframe: {\r\n // Iframe template\r\n tpl: '<iframe id=\"fancybox-frame{rnd}\" name=\"fancybox-frame{rnd}\" class=\"fancybox-iframe\" allowfullscreen=\"allowfullscreen\" allow=\"autoplay; fullscreen\" src=\"\"></iframe>',\r\n\r\n // Preload iframe before displaying it\r\n // This allows to calculate iframe content width and height\r\n // (note: Due to \"Same Origin Policy\", you can't get cross domain data).\r\n preload: true,\r\n\r\n // Custom CSS styling for iframe wrapping element\r\n // You can use this to set custom iframe dimensions\r\n css: {},\r\n\r\n // Iframe tag attributes\r\n attr: {\r\n scrolling: \"auto\"\r\n }\r\n },\r\n\r\n // For HTML5 video only\r\n video: {\r\n tpl: '<video class=\"fancybox-video\" controls controlsList=\"nodownload\" poster=\"{{poster}}\">' +\r\n '<source src=\"{{src}}\" type=\"{{format}}\" />' +\r\n 'Sorry, your browser doesn\\'t support embedded videos, <a href=\"{{src}}\">download</a> and watch with your favorite video player!' +\r\n \"</video>\",\r\n format: \"\", // custom video format\r\n autoStart: true\r\n },\r\n\r\n // Default content type if cannot be detected automatically\r\n defaultType: \"image\",\r\n\r\n // Open/close animation type\r\n // Possible values:\r\n // false - disable\r\n // \"zoom\" - zoom images from/to thumbnail\r\n // \"fade\"\r\n // \"zoom-in-out\"\r\n //\r\n animationEffect: \"zoom\",\r\n\r\n // Duration in ms for open/close animation\r\n animationDuration: 366,\r\n\r\n // Should image change opacity while zooming\r\n // If opacity is \"auto\", then opacity will be changed if image and thumbnail have different aspect ratios\r\n zoomOpacity: \"auto\",\r\n\r\n // Transition effect between slides\r\n //\r\n // Possible values:\r\n // false - disable\r\n // \"fade'\r\n // \"slide'\r\n // \"circular'\r\n // \"tube'\r\n // \"zoom-in-out'\r\n // \"rotate'\r\n //\r\n transitionEffect: \"fade\",\r\n\r\n // Duration in ms for transition animation\r\n transitionDuration: 366,\r\n\r\n // Custom CSS class for slide element\r\n slideClass: \"\",\r\n\r\n // Custom CSS class for layout\r\n baseClass: \"\",\r\n\r\n // Base template for layout\r\n baseTpl: '<div class=\"fancybox-container\" role=\"dialog\" tabindex=\"-1\">' +\r\n '<div class=\"fancybox-bg\"></div>' +\r\n '<div class=\"fancybox-inner\">' +\r\n '<div class=\"fancybox-infobar\"><span data-fancybox-index></span> / <span data-fancybox-count></span></div>' +\r\n '<div class=\"fancybox-toolbar\">{{buttons}}</div>' +\r\n '<div class=\"fancybox-navigation\">{{arrows}}</div>' +\r\n '<div class=\"fancybox-stage\"></div>' +\r\n '<div class=\"fancybox-caption\"><div class=\"fancybox-caption__body\"></div></div>' +\r\n \"</div>\" +\r\n \"</div>\",\r\n\r\n // Loading indicator template\r\n spinnerTpl: '<div class=\"fancybox-loading\"></div>',\r\n\r\n // Error message template\r\n errorTpl: '<div class=\"fancybox-error\"><p>{{ERROR}}</p></div>',\r\n\r\n btnTpl: {\r\n download: '<a download data-fancybox-download class=\"fancybox-button fancybox-button--download\" title=\"{{DOWNLOAD}}\" href=\"javascript:;\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z\"/></svg>
109' +\r\n \"</a>\",\r\n\r\n zoom: '<button data-fancybox-zoom class=\"fancybox-button fancybox-button--zoom\" title=\"{{ZOOM}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z\"/></svg>' +\r\n \"</button>\",\r\n\r\n close: '<button data-fancybox-close class=\"fancybox-button fancybox-button--close\" title=\"{{CLOSE}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z\"/></svg>' +\r\n \"</button>\",\r\n\r\n // Arrows\r\n arrowLeft: '<button data-fancybox-prev class=\"fancybox-button fancybox-button--arrow_left\" title=\"{{PREV}}\">' +\r\n '<div><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z\"/></svg></div>' +\r\n \"</button>\",\r\n\r\n arrowRight: '<button data-fancybox-next class=\"fancybox-button fancybox-button--arrow_right\" title=\"{{NEXT}}\">' +\r\n '<div><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z\"/></svg></div>' +\r\n \"</button>\",\r\n\r\n // This small close button will be appended to your html/inline/ajax content by default,\r\n // if \"smallBtn\" option is not set to false\r\n smallBtn: '<button type=\"button\" data-fancybox-close class=\"fancybox-button fancybox-close-small\" title=\"{{CLOSE}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1\" viewBox=\"0 0 24 24\"><path d=\"M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z\"/></svg>' +\r\n \"</button>\"\r\n },\r\n\r\n // Container is injected into this element\r\n parentEl: \"body\",\r\n\r\n // Hide browser vertical scrollbars; use at your own risk\r\n hideScrollbar: true,\r\n\r\n // Focus handling\r\n // ==============\r\n\r\n // Try to focus on the first focusable element after opening\r\n autoFocus: true,\r\n\r\n // Put focus back to active element after closing\r\n backFocus: true,\r\n\r\n // Do not let user to focus on element outside modal content\r\n trapFocus: true,\r\n\r\n // Module specific options\r\n // =======================\r\n\r\n fullScreen: {\r\n autoStart: false\r\n },\r\n\r\n // Set `touch: false` to disable panning/swiping\r\n touch: {\r\n vertical: true, // Allow to drag content vertically\r\n momentum: true // Continue movement after releasing mouse/touch when panning\r\n },\r\n\r\n // Hash value when initializing manually,\r\n // set `false` to disable hash change\r\n hash: null,\r\n\r\n // Customize or add new media types\r\n // Example:\r\n /*\r\n media : {\r\n youtube : {\r\n params : {\r\n autoplay : 0\r\n }\r\n }\r\n }\r\n */\r\n media: {},\r\n\r\n slideShow: {\r\n autoStart: false,\r\n speed: 3000\r\n },\r\n\r\n thumbs: {\r\n autoStart: false, // Display thumbnails on opening\r\n hideOnClose: true, // Hide thumbnail grid when closing animation starts\r\n parentEl: \".fancybox-container\", // Container is injected into this element\r\n axis: \"y\" // Vertical (y) or horizontal (x) scrolling\r\n },\r\n\r\n // Use mousewheel to navigate gallery\r\n // If 'auto' - enabled for images only\r\n wheel: \"auto\",\r\n\r\n // Callbacks\r\n //==========\r\n\r\n // See Documentation/API/Events for more information\r\n // Example:\r\n /*\r\n afterShow: function( instance, current ) {\r\n console.info( 'Clicked element:' );\r\n console.info( current.opts.$orig );\r\n }\r\n */\r\n\r\n onInit: $.noop, // When instance has been initialized\r\n\r\n beforeLoad: $.noop, // Before the content of a slide is being loaded\r\n afterLoad: $.noop, // When the content of a slide is done loading\r\n\r\n beforeShow: $.noop, // Before open animation starts\r\n afterShow: $.noop, // When content is done loading and animating\r\n\r\n beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.\r\n afterClose: $.noop, // After instance has been closed\r\n\r\n onActivate: $.noop, // When instance is brought to front\r\n onDeactivate: $.noop, // When other instance has been activated\r\n\r\n // Interaction\r\n // ===========\r\n\r\n // Use options below to customize taken action when user clicks or double clicks on the fancyBox area,\r\n // each option can be string or method that returns value.\r\n //\r\n // Possible values:\r\n // \"close\" - close instance\r\n // \"next\" - move to next gallery item\r\n // \"nextOrClose\" - move to next gallery item or close if gallery has only one item\r\n // \"toggleControls\" - show/hide controls\r\n // \"zoom\" - zoom image (if loaded)\r\n // false - do nothing\r\n\r\n // Clicked on the content\r\n clickContent: function (current, event) {\r\n return current.type === \"image\" ? \"zoom\" : false;\r\n },\r\n\r\n // Clicked on the slide\r\n clickSlide: \"close\",\r\n\r\n // Clicked on the background (backdrop) element;\r\n // if you have not changed the layout, then most likely you need to use `clickSlide` option\r\n clickOutside: \"close\",\r\n\r\n // Same as previous two, but for double click\r\n dblclickContent: false,\r\n dblclickSlide: false,\r\n dblclickOutside: false,\r\n\r\n // Custom options when mobile device is detected\r\n // =============================================\r\n\r\n mobile: {\r\n preventCaptionOverlap: false,\r\n idleTime: false,\r\n clickContent: function (current, event) {\r\n return current.type === \"image\" ? \"toggleControls\" : false;\r\n },\r\n clickSlide: function (current, event) {\r\n return current.type === \"image\" ? \"toggleControls\" : \"close\";\r\n },\r\n dblclickContent: function (current, event) {\r\n return current.type === \"image\" ? \"zoom\" : false;\r\n },\r\n dblclickSlide: function (current, event) {\r\n return current.type === \"image\" ? \"zoom\" : false;\r\n }\r\n },\r\n\r\n // Internationalization\r\n // ====================\r\n\r\n lang: \"en\",\r\n i18n: {\r\n en: {\r\n CLOSE: \"Close\",\r\n NEXT: \"Next\",\r\n PREV: \"Previous\",\r\n ERROR: \"The requested content cannot be loaded. <br/> Please try again later.\",\r\n PLAY_START: \"Start slideshow\",\r\n PLAY_STOP: \"Pause slideshow\",\r\n FULL_SCREEN: \"Full screen\",\r\n THUMBS: \"Thumbnails\",\r\n DOWNLOAD: \"Download\",\r\n SHARE: \"Share\",\r\n ZOOM: \"Zoom\"\r\n }
109,\r\n de: {\r\n CLOSE: \"Schließen\",\r\n NEXT: \"Weiter\",\r\n PREV: \"Zurück\",\r\n ERROR: \"Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es später nochmal.\",\r\n PLAY_START: \"Diaschau starten\",\r\n PLAY_STOP: \"Diaschau beenden\",\r\n FULL_SCREEN: \"Vollbild\",\r\n THUMBS: \"Vorschaubilder\",\r\n DOWNLOAD: \"Herunterladen\",\r\n SHARE: \"Teilen\",\r\n ZOOM: \"Vergrößern\"\r\n }\r\n }\r\n };\r\n\r\n // Few useful variables and methods\r\n // ================================\r\n\r\n var $W = $(window);\r\n var $D = $(document);\r\n\r\n var called = 0;\r\n\r\n // Check if an object is a jQuery object and not a native JavaScript object\r\n // ========================================================================\r\n var isQuery = function (obj) {\r\n return obj && obj.hasOwnProperty && obj instanceof $;\r\n };\r\n\r\n // Handle multiple browsers for \"requestAnimationFrame\" and \"cancelAnimationFrame\"\r\n // ===============================================================================\r\n var requestAFrame = (function () {\r\n return (\r\n window.requestAnimationFrame ||\r\n window.webkitRequestAnimationFrame ||\r\n window.mozRequestAnimationFrame ||\r\n window.oRequestAnimationFrame ||\r\n // if all else fails, use setTimeout\r\n function (callback) {\r\n return window.setTimeout(callback, 1000 / 60);\r\n }\r\n );\r\n })();\r\n\r\n var cancelAFrame = (function () {\r\n return (\r\n window.cancelAnimationFrame ||\r\n window.webkitCancelAnimationFrame ||\r\n window.mozCancelAnimationFrame ||\r\n window.oCancelAnimationFrame ||\r\n function (id) {\r\n window.clearTimeout(id);\r\n }\r\n );\r\n })();\r\n\r\n // Detect the supported transition-end event property name\r\n // =======================================================\r\n var transitionEnd = (function () {\r\n var el = document.createElement(\"fakeelement\"),\r\n t;\r\n\r\n var transitions = {\r\n transition: \"transitionend\",\r\n OTransition: \"oTransitionEnd\",\r\n MozTransition: \"transitionend\",\r\n WebkitTransition: \"webkitTransitionEnd\"\r\n };\r\n\r\n for (t in transitions) {\r\n if (el.style[t] !== undefined) {\r\n return transitions[t];\r\n }\r\n }\r\n\r\n return \"transitionend\";\r\n })();\r\n\r\n // Force redraw on an element.\r\n // This helps in cases where the browser doesn't redraw an updated element properly\r\n // ================================================================================\r\n var forceRedraw = function ($el) {\r\n return $el && $el.length && $el[0].offsetHeight;\r\n };\r\n\r\n // Exclude array (`buttons`) options from deep merging\r\n // ===================================================\r\n var mergeOpts = function (opts1, opts2) {\r\n var rez = $.extend(true, {}, opts1, opts2);\r\n\r\n $.each(opts2, function (key, value) {\r\n if ($.isArray(value)) {\r\n rez[key] = value;\r\n }\r\n });\r\n\r\n return rez;\r\n };\r\n\r\n // How much of an element is visible in viewport\r\n // =============================================\r\n\r\n var inViewport = function (elem) {\r\n var elemCenter, rez;\r\n\r\n if (!elem || elem.ownerDocument !== document) {\r\n return false;\r\n }\r\n\r\n $(\".fancybox-container\").css(\"pointer-events\", \"none\");\r\n\r\n elemCenter = {\r\n x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,\r\n y: elem.getBoundingClientRect().top + elem.offsetHeight / 2\r\n };
109\r\n\r\n rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;\r\n\r\n $(\".fancybox-container\").css(\"pointer-events\", \"\");\r\n\r\n return rez;\r\n };\r\n\r\n // Class definition\r\n // ================\r\n\r\n var FancyBox = function (content, opts, index) {\r\n var self = this;\r\n\r\n self.opts = mergeOpts({\r\n index: index\r\n }, $.fancybox.defaults);\r\n\r\n if ($.isPlainObject(opts)) {\r\n self.opts = mergeOpts(self.opts, opts);\r\n }\r\n\r\n if ($.fancybox.isMobile) {\r\n self.opts = mergeOpts(self.opts, self.opts.mobile);\r\n }\r\n\r\n self.id = self.opts.id || ++called;\r\n\r\n self.currIndex = parseInt(self.opts.index, 10) || 0;\r\n self.prevIndex = null;\r\n\r\n self.prevPos = null;\r\n self.currPos = 0;\r\n\r\n self.firstRun = true;\r\n\r\n // All group items\r\n self.group = [];\r\n\r\n // Existing slides (for current, next and previous gallery items)\r\n self.slides = {};\r\n\r\n // Create group elements\r\n self.addContent(content);\r\n\r\n if (!self.group.length) {\r\n return;\r\n }\r\n\r\n self.init();\r\n };\r\n\r\n $.extend(FancyBox.prototype, {\r\n // Create DOM structure\r\n // ====================\r\n\r\n init: function () {\r\n var self = this,\r\n firstItem = self.group[self.currIndex],\r\n firstItemOpts = firstItem.opts,\r\n $container,\r\n buttonStr;\r\n\r\n if (firstItemOpts.closeExisting) {\r\n $.fancybox.close(true);\r\n }\r\n\r\n // Hide scrollbars\r\n // ===============\r\n\r\n $(\"body\").addClass(\"fancybox-active\");\r\n\r\n if (\r\n !$.fancybox.getInstance() &&\r\n firstItemOpts.hideScrollbar !== false &&\r\n !$.fancybox.isMobile &&\r\n document.body.scrollHeight > window.innerHeight\r\n ) {\r\n $(\"head\").append(\r\n '<style id=\"fancybox-style-noscroll\" type=\"text/css\">.compensate-for-scrollbar{margin-right:' +\r\n (window.innerWidth - document.documentElement.clientWidth) +\r\n \"px;}</style>\"\r\n );\r\n\r\n $(\"body\").addClass(\"compensate-for-scrollbar\");\r\n }\r\n\r\n // Build html markup and set references\r\n // ====================================\r\n\r\n // Build html code for buttons and insert into main template\r\n buttonStr = \"\";\r\n\r\n $.each(firstItemOpts.buttons, function (index, value) {\r\n buttonStr += firstItemOpts.btnTpl[value] || \"\";\r\n });\r\n\r\n // Create markup from base template, it will be initially hidden to\r\n // avoid unnecessary work like painting while initializing is not complete\r\n $container = $(\r\n self.translate(\r\n self,\r\n firstItemOpts.baseTpl\r\n .replace(\"{{buttons}}\", buttonStr)\r\n .replace(\"{{arrows}}\", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight)\r\n )\r\n )\r\n .attr(\"id\", \"fancybox-container-\" + self.id)\r\n .addClass(firstItemOpts.baseClass)\r\n .data(\"FancyBox\", self)\r\n .appendTo(firstItemOpts.parentEl);\r\n\r\n // Create object holding references to jQuery wrapped nodes\r\n self.$refs = {\r\n container: $container\r\n };\r\n\r\n [\"bg\", \"inner\", \"infobar\", \"toolbar\", \"stage\", \"caption\", \"navigation\"].forEach(function (item) {\r\n self.$refs[item] = $container.find(\".fancybox-\" + item);\r\n });\r\n\r\n self.trigger(\"onInit\");\r\n\r\n // Enable events, deactive previous instances\r\n self.activate();\r\n\r\n // Build slides, load and reveal content\r\n self.jumpTo(self.currIndex);\r\n },\r\n\r\n // Simple i18n support - replaces object keys found in template\r\n // with corresponding values\r\n // ============================================================\r\n\r\n translate: function (obj, str) {\r\n var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;\r\n\r\n return str.replace(/\\{\\{(\\w+)\\}\\}/g, function (match, n) {\r\n return arr[n] === undefined ? match : arr[n];\r\n });\r\n },\r\n\r\n // Populate current group with fresh content\r\n // Check if each object has valid type and content\r\n // ===============================================\r\n\r\n addContent: function (content) {\r\n var self = this,\r\n items = $.makeArray(content),\r\n thumbs;\r\n\r\n $.each(items, function (i, item) {\r\n var obj = {},\r\n opts = {},\r\n $item,\r\n type,\r\n found,\r\n src,\r\n srcParts;\r\n\r\n // Step 1 - Make sure we have an object\r\n // ====================================\r\n\r\n if ($.isPlainObject(item)) {\r\n // We probably have manual usage here, something like\r\n // $.fancybox.open( [ { src : \"
109image.jpg\", type : \"image\" } ] )\r\n\r\n obj = item;\r\n opts = item.opts || item;\r\n } else if ($.type(item) === \"object\" && $(item).length) {\r\n // Here we probably have jQuery collection returned by some selector\r\n $item = $(item);\r\n\r\n // Support attributes like `data-options='{\"touch\" : false}'` and `data-touch='false'`\r\n opts = $item.data() || {};\r\n opts = $.extend(true, {}, opts, opts.options);\r\n\r\n // Here we store clicked element\r\n opts.$orig = $item;\r\n\r\n obj.src = self.opts.src || opts.src || $item.attr(\"href\");\r\n\r\n // Assume that simple syntax is used, for example:\r\n // `$.fancybox.open( $(\"#test\"), {} );`\r\n if (!obj.type && !obj.src) {\r\n obj.type = \"inline\";\r\n obj.src = item;\r\n }\r\n } else {\r\n // Assume we have a simple html code, for example:\r\n // $.fancybox.open( '<div><h1>Hi!</h1></div>' );\r\n obj = {\r\n type: \"html\",\r\n src: item + \"\"\r\n };\r\n }\r\n\r\n // Each gallery object has full collection of options\r\n obj.opts = $.extend(true, {}, self.opts, opts);\r\n\r\n // Do not merge buttons array\r\n if ($.isArray(opts.buttons)) {\r\n obj.opts.buttons = opts.buttons;\r\n }\r\n\r\n if ($.fancybox.isMobile && obj.opts.mobile) {\r\n obj.opts = mergeOpts(obj.opts, obj.opts.mobile);\r\n }\r\n\r\n // Step 2 - Make sure we have content type, if not - try to guess\r\n // ==============================================================\r\n\r\n type = obj.type || obj.opts.type;\r\n src = obj.src || \"\";\r\n\r\n if (!type && src) {\r\n if ((found = src.match(/\\.(mp4|mov|ogv|webm)((\\?|#).*)?$/i))) {\r\n type = \"video\";\r\n\r\n if (!obj.opts.video.format) {\r\n obj.opts.video.format = \"video/\" + (found[1] === \"ogv\" ? \"ogg\" : found[1]);\r\n }\r\n } else if (src.match(/(^data:image\\/[a-z0-9+\\/=]*,)|(\\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\\?|#).*)?$)/i)) {\r\n type = \"image\";\r\n } else if (src.match(/\\.(pdf)((\\?|#).*)?$/i)) {\r\n type = \"iframe\";\r\n obj = $.extend(true, obj, {\r\n contentType: \"pdf\",\r\n opts: {\r\n iframe: {\r\n preload: false\r\n }\r\n }\r\n });\r\n } else if (src.charAt(0) === \"#\") {\r\n type = \"inline\";\r\n }\r\n }\r\n\r\n if (type) {\r\n obj.type = type;\r\n } else {\r\n self.trigger(\"objectNeedsType\", obj);\r\n }\r\n\r\n if (!obj.contentType) {\r\n obj.contentType = $.inArray(obj.type, [\"html\", \"inline\", \"ajax\"]) > -1 ? \"html\" : obj.type;\r\n }\r\n\r\n // Step 3 - Some adjustments\r\n // =========================\r\n\r\n obj.index = self.group.length;\r\n\r\n if (obj.opts.smallBtn == \"auto\") {\r\n obj.opts.smallBtn = $.inArray(obj.type, [\"html\", \"inline\", \"ajax\"]) > -1;\r\n }\r\n\r\n if (obj.opts.toolbar === \"auto\") {\r\n obj.opts.toolbar = !obj.opts.smallBtn;\r\n }\r\n\r\n // Find thumbnail image, check if exists and if is in the viewport\r\n obj.$thumb = obj.opts.$thumb || null;\r\n\r\n if (obj.opts.$trigger && obj.index === self.opts.index) {\r\n obj.$thumb = obj.opts.$trigger.find(\"img:first\");\r\n\r\n if (obj.$thumb.length) {\r\n obj.opts.$orig = obj.opts.$trigger;\r\n }\r\n }\r\n\r\n if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {\r\n obj.$thumb = obj.opts.$orig.find(\"img:first\");\r\n }\r\n\r\n if (obj.$thumb && !obj.$thumb.length) {\r\n obj.$thumb = null;\r\n }\r\n\r\n obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null);\r\n\r\n // \"caption\" is a \"special\" option, it can be used to customize caption per gallery item\r\n if ($.type(obj.opts.caption) === \"function\") {\r\n obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);\r\n }\r\n\r\n if ($.type(self.opts.caption) === \"function\") {\r\n obj.opts.caption = self.opts.caption.apply(item, [self, obj]);\r\n }\r\n\r\n // Make sure we have caption as a string or jQuery object\r\n if (!(obj.opts.caption instanceof $)) {\r\n obj.opts.caption = obj.opts.caption === undefined ? \"\" : obj.opts.caption + \"\";\r\n }\r\n\r\n // Check if url contains \"filter\" used to filter the content\r\n // Example: \"ajax.html #something\"\r\n if (obj.type === \"ajax\") {\r\n srcParts = src.split(/\\s+/, 2);\r\n\r\n if (srcParts.length > 1) {\r\n obj.src = srcParts.shift();\r\n\r\n obj.opts.filter = srcParts.shift();\r\n }\r\n }\r\n\r\n // Hide all buttons and disable interactivity for modal items\r\n if (obj.opts.modal) {\r\n obj.opts = $.extend(true, obj.opts, {\r\n trapFocus: true,\r\n // Remove buttons\r\n infobar: 0,\r\n toolbar: 0,\r\n\r\n smallBtn: 0,\r\n\r\n // Disable keyboard navigation\r\n keyboard: 0,\r\n\r\n // Disable some modules\r\n slideShow: 0,\r\n fullScreen: 0,\r\n thumbs: 0,\r\n touch: 0,\r\n\r\n // Disable click event handlers\r\n clickContent: false,\r\n clickSlide: false,\r\n clickOutside: false,\r\n dblclickContent: false,\r\n dblclickSlide: false,\r\n dblclickOutside: false\r\n });\r\n }\r\n\r\n // Step 4 - Add processed object to group\r\n // ======================================\r\n\r\n self.group.push(obj);\r\n });\r\n\r\n // Update controls if gallery is already opened\r\n if (Object.keys(self.slides).length) {\r\n self.updateControls();\r\n\r\n // Update thumbnails, if needed\r\n thumbs = self.Thumbs;\r\n\r\n if (thumbs && thumbs.isActive) {\r\n thumbs.create();\r\n\r\n thumbs.focus();\r\n }\r\n }\r\n },\r\n\r\n // Attach an event handler functions for:\r\n // - navigation buttons\r\n // - browser scrolling, resizing;\r\n // - focusing\r\n // - keyboard\r\n // - detecting inactivity\r\n // ======================================\r\n\r\n addEvents: function () {\r\n var self = this;\r\n\r\n self.removeEvents();\r\n\r\n // Make navigation elements clickable\r\n // ==================================\r\n\r\n self.$refs.container\r\n .on(\"click.fb-close\", \"[data-fancybox-close]\", function (e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n self.close(e);\r\n })\r\n .on(\"touchstart.fb-prev click.fb-prev\", \"[data-fancybox-prev]\", function (e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n self.previous();\r\n })\r\n .on(\"touchstart.fb-next click.fb-next\", \"[data-fancybox-next]\", function (e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n self.next();\r\n })\r\n .on(\"click.fb\", \"[data-fancybox-zoom]\", function (e) {\r\n // Click handler for zoom button\r\n self[self.isScaledDown() ? \"scaleToActual\" : \"scaleToFit\"]();\r\n });\r\n\r\n // Handle page scrolling and browser resizing\r\n // ==========================================\r\n\r\n $W.on(\"orientationchange.fb resize.fb\", function (e) {\r\n if (e && e.originalEvent && e.originalEvent.type === \"resize\") {\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n }\r\n\r\n self.requestId = requestAFrame(function () {\r\n self.update(e);\r\n });\r\n } else {\r\n if (self.current && self.current.type === \"iframe\") {\r\n self.$refs.stage.hide();\r\n }\r\n\r\n setTimeout(\r\n function () {\r\n self.$refs.stage.show();\r\n\r\n self.update(e);\r\n },\r\n $.fancybox.isMobile ? 600 : 250\r\n );\r\n }\r\n });\r\n\r\n $D.on(\"keydown.fb\", function (e) {\r\n var instance = $.fancybox ? $.fancybox.getInstance() : null,\r\n current = instance.current,\r\n keycode = e.keyCode || e.which;\r\n\r\n // Trap keyboard focus inside of the modal\r\n // =======================================\r\n\r\n if (keycode == 9) {\r\n if (current.opts.trapFocus) {\r\n self.focus(e);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Enable keyboard navigation\r\n // ==========================\r\n\r\n if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is(\"input,textarea,video,audio,select\")) {\r\n return;\r\n }\r\n\r\n // Backspace and Esc keys\r\n if (keycode === 8 || keycode === 27) {\r\n e.preventDefault();\r\n\r\n self.close(e);\r\n\r\n return;\r\n }\r\n\r\n // Left arrow and Up arrow\r\n if (keycode === 37 || keycode === 38) {\r\n e.preventDefault();\r\n\r\n self.previous();\r\n\r\n return;\r\n }\r\n\r\n // Righ arrow and Down arrow\r\n if (keycode === 39 || keycode === 40) {\r\n e.preventDefault();\r\n\r\n self.next();\r\n\r\n return;\r\n }\r\n\r\n self.trigger(\"afterKeydown\", e, keycode);\r\n });\r\n\r\n // Hide controls after some inactivity period\r\n if (self.group[self.currIndex].opts.idleTime) {\r\n self.idleSecondsCounter = 0;\r\n\r\n $D.on(\r\n \"mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle\",\r\n function (e) {\r\n self.idleSecondsCounter = 0;\r\n\r\n if (self.isIdle) {\r\n self.showControls();\r\n }\r\n\r\n self.isIdle = false;\r\n }\r\n );\r\n\r\n self.idleInterval = window.setInterval(function () {\r\n self.idleSecondsCounter++;\r\n\r\n if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {\r\n self.isIdle = true;\r\n self.idleSecondsCounter = 0;\r\n\r\n self.hideControls();\r\n }\r\n }, 1000);\r\n }\r\n },\r\n\r\n // Remove events added by the core\r\n // ===============================\r\n\r\n removeEvents: function () {\r\n var self = this;\r\n\r\n $W.off(\"orientationchange.fb resize.fb\");\r\n $D.off(\"keydown.fb .fb-idle\");\r\n\r\n this.$refs.container.off(\".fb-close .fb-prev .fb-next\");\r\n\r\n if (self.idleInterval) {\r\n window.clearInterval(self.idleInterval);\r\n\r\n self.idleInterval = null;\r\n }\r\n },\r\n\r\n // Change to previous gallery item\r\n // ===============================\r\n\r\n previous: function (duration) {\r\n return this.jumpTo(this.currPos - 1, duration);\r\n },\r\n\r\n // Change to next gallery item\r\n // ===========================\r\n\r\n next: function (duration) {\r\n return this.jumpTo(this.currPos + 1, duration);\r\n },\r\n\r\n // Switch to selected gallery item\r\n // ===============================\r\n\r\n jumpTo: function (pos, duration) {\r\n var self = this,\r\n groupLen = self.group.length,\r\n firstRun,\r\n isMoved,\r\n loop,\r\n current,\r\n previous,\r\n slidePos,\r\n stagePos,\r\n prop,\r\n diff;\r\n\r\n if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {\r\n return;\r\n }\r\n\r\n // Should loop?\r\n pos = parseInt(pos, 10);\r\n loop = self.current ? self.current.opts.loop : self.opts.loop;\r\n\r\n if (!loop && (pos < 0 || pos >= groupLen)) {\r\n return false;\r\n }\r\n\r\n // Check if opening for the first time; this helps to speed things up\r\n firstRun = self.firstRun = !Object.keys(self.slides).length;\r\n\r\n // Create slides\r\n previous = self.current;\r\n\r\n self.prevIndex = self.currIndex;\r\n self.prevPos = self.currPos;\r\n\r\n current = self.createSlide(pos);\r\n\r\n if (groupLen > 1) {\r\n if (loop || current.index < groupLen - 1) {\r\n self.createSlide(pos + 1);\r\n }\r\n\r\n if (loop || current.index > 0) {\r\n self.createSlide(pos - 1);\r\n }\r\n }\r\n\r\n self.current = current;\r\n self.currIndex = current.index;\r\n self.currPos = current.pos;\r\n\r\n self.trigger(\"beforeShow\", firstRun);\r\n\r\n self.updateControls();\r\n\r\n // Validate duration length\r\n current.forcedDuration = undefined;\r\n\r\n if ($.isNumeric(duration)) {\r\n current.forcedDuration = duration;\r\n } else {\r\n duration = current.opts[firstRun ? \"animationDuration\" : \"transitionDuration\"];\r\n }\r\n\r\n duration = parseInt(duration, 10);\r\n\r\n // Check if user has swiped the slides or if still animating\r\n isMoved = self.isMoved(current);\r\n\r\n // Make sure current slide is visible\r\n current.$slide.addClass(\"fancybox-slide--current\");\r\n\r\n // Fresh start - reveal container, current slide and start loading content\r\n if (firstRun) {\r\n if (current.opts.animationEffect && duration) {\r\n self.$refs.container.css(\"transition-duration\", duration + \"ms\");\r\n }\r\n\r\n self.$refs.container.addClass(\"fancybox-is-open\").trigger(\"focus\");\r\n\r\n // Attempt to load content into slide\r\n // This will later call `afterLoad` -> `revealContent`\r\n self.loadSlide(current);\r\n\r\n self.preload(\"image\");\r\n\r\n return;\r\n }\r\n\r\n // Get actual slide/stage positions (before cleaning up)\r\n slidePos = $.fancybox.getTranslate(previous.$slide);\r\n stagePos = $.fancybox.getTranslate(self.$refs.stage);\r\n\r\n // Clean up all slides\r\n $.each(self.slides, function (index, slide) {\r\n $.fancybox.stop(slide.$slide, true);\r\n });\r\n\r\n if (previous.pos !== current.pos) {\r\n previous.isComplete = false;\r\n }\r\n\r\n previous.$slide.removeClass(\"fancybox-slide--complete fancybox-slide--current\");\r\n\r\n // If slides are out of place, then animate them to correct position\r\n if (isMoved) {\r\n // Calculate horizontal swipe distance\r\n diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);\r\n\r\n $.each(self.slides, function (index, slide) {\r\n slide.$slide.removeClass(\"fancybox-animated\").removeClass(function (index, className) {\r\n return (className.match(/(^|\\s)fancybox-fx-\\S+/g) || []).join(\" \");\r\n });\r\n\r\n // Make sure that each slide is in equal distance\r\n // This is mostly needed for freshly added slides, because they are not yet positioned\r\n var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;\r\n\r\n $.fancybox.setTranslate(slide.$slide, {\r\n top: 0,\r\n left: leftPos - stagePos.left + diff\r\n });\r\n\r\n if (slide.pos !== current.pos) {\r\n slide.$slide.addClass(\"fancybox-slide--\" + (slide.pos > current.pos ? \"next\" : \"previous\"));\r\n }\r\n\r\n // Redraw to make sure that transition will start\r\n forceRedraw(slide.$sli
109de);\r\n\r\n // Animate the slide\r\n $.fancybox.animate(\r\n slide.$slide, {\r\n top: 0,\r\n left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter\r\n },\r\n duration,\r\n function () {\r\n slide.$slide\r\n .css({\r\n transform: \"\",\r\n opacity: \"\"\r\n })\r\n .removeClass(\"fancybox-slide--next fancybox-slide--previous\");\r\n\r\n if (slide.pos === self.currPos) {\r\n self.complete();\r\n }\r\n }\r\n );\r\n });\r\n } else if (duration && current.opts.transitionEffect) {\r\n // Set transition effect for previously active slide\r\n prop = \"fancybox-animated fancybox-fx-\" + current.opts.transitionEffect;\r\n\r\n previous.$slide.addClass(\"fancybox-slide--\" + (previous.pos > current.pos ? \"next\" : \"previous\"));\r\n\r\n $.fancybox.animate(\r\n previous.$slide,\r\n prop,\r\n duration,\r\n function () {\r\n previous.$slide.removeClass(prop).removeClass(\"fancybox-slide--next fancybox-slide--previous\");\r\n },\r\n false\r\n );\r\n }\r\n\r\n if (current.isLoaded) {\r\n self.revealContent(current);\r\n } else {\r\n self.loadSlide(current);\r\n }\r\n\r\n self.preload(\"image\");\r\n },\r\n\r\n // Create new \"slide\" element\r\n // These are gallery items that are actually added to DOM\r\n // =======================================================\r\n\r\n createSlide: function (pos) {\r\n var self = this,\r\n $slide,\r\n index;\r\n\r\n index = pos % self.group.length;\r\n index = index < 0 ? self.group.length + index : index;\r\n\r\n if (!self.slides[pos] && self.group[index]) {\r\n $slide = $('<div class=\"fancybox-slide\"></div>').appendTo(self.$refs.stage);\r\n\r\n self.slides[pos] = $.extend(true, {}, self.group[index], {\r\n pos: pos,\r\n $slide: $slide,\r\n isLoaded: false\r\n });\r\n\r\n self.updateSlide(self.slides[pos]);\r\n }\r\n\r\n return self.slides[pos];\r\n },\r\n\r\n // Scale image to the actual size of the image;\r\n // x and y values should be relative to the slide\r\n // ==============================================\r\n\r\n scaleToActual: function (x, y, duration) {\r\n var self = this,\r\n current = self.current,\r\n $content = current.$content,\r\n canvasWidth = $.fancybox.getTranslate(current.$slide).width,\r\n canvasHeight = $.fancybox.getTranslate(current.$slide).height,\r\n newImgWidth = current.width,\r\n newImgHeight = current.height,\r\n imgPos,\r\n posX,\r\n posY,\r\n scaleX,\r\n scaleY;\r\n\r\n if (self.isAnimating || self.isMoved() || !$content || !(current.type == \"image\" && current.isLoaded && !current.hasError)) {\r\n return;\r\n }\r\n\r\n self.isAnimating = true;\r\n\r\n $.fancybox.stop($content);\r\n\r\n x = x === undefined ? canvasWidth * 0.5 : x;\r\n y = y === undefined ? canvasHeight * 0.5 : y;\r\n\r\n imgPos = $.fancybox.getTranslate($content);\r\n\r\n imgPos.top -= $.fancybox.getTranslate(current.$slide).top;\r\n imgPos.left -= $.fancybox.getTranslate(current.$slide).left;\r\n\r\n scaleX = newImgWidth / imgPos.width;\r\n scaleY = newImgHeight / imgPos.height;\r\n\r\n // Get center position for original image\r\n posX = canvasWidth * 0.5 - newImgWidth * 0.5;\r\n posY = canvasHeight * 0.5 - newImgHeight * 0.5;\r\n\r\n // Make sure image does not move away from edges\r\n if (newImgWidth > canvasWidth) {\r\n posX = imgPos.left * scaleX - (x * scaleX - x);\r\n\r\n if (posX > 0) {\r\n posX = 0;\r\n }\r\n\r\n if (posX < canvasWidth - newImgWidth) {\r\n posX = canvasWidth - newImgWidth;\r\n }\r\n }\r\n\r\n if (newImgHeight > canvasHeight) {\r\n posY = imgPos.top * scaleY - (y * scaleY - y);\r\n\r\n if (posY > 0) {\r\n posY = 0;\r\n }\r\n\r\n if (posY < canvasHeight - newImgHeight) {\r\n posY = canvasHeight - newImgHeight;\r\n }\r\n }\r\n\r\n self.updateCursor(newImgWidth, newImgHeight);\r\n\r\n $.fancybox.animate(\r\n $content, {\r\n top: posY,\r\n left: posX,\r\n scaleX: scaleX,\r\n scaleY: scaleY\r\n },\r\n duration || 366,\r\n function () {\r\n self.isAnimating = false;\r\n }\r\n );\r\n\r\n // Stop slideshow\r\n if (self.SlideShow && self.SlideShow.isActive) {\r\n self.SlideShow.stop();\r\n }\r\n },\r\n\r\n // Scale image to fit inside parent element\r\n // ========================================\r\n\r\n scaleToFit: function (duration) {\r\n var self = this,\r\n current = self.current,\r\n $content = current.$content,\r\n end;\r\n\r\n if (self.isAnimating || self.isMoved() || !$content || !(current.type == \"image\" && current.isLoaded && !current.hasError)) {\r\n return;\r\n }\r\n\r\n self.isAnimating = true;\r\n\r\n $.fancybox.stop($content);\r\n\r\n end = self.getFitPos(current);\r\n\r\n self.updateCursor(end.width, end.height);\r\n\r\n $.fancybox.animate(\r\n $content, {\r\n top: end.top,\r\n left: end.left,\r\n scaleX: end.width / $content.width(),\r\n scaleY: end.height / $content.height()\r\n },\r\n duration || 366,\r\n function () {\r\n self.isAnimating = false;\r\n }\r\n );\r\n },\r\n\r\n // Calculate image size to fit inside viewport\r\n // ===========================================\r\n\r\n getFitPos: function (slide) {\r\n var self = this,\r\n $content = slide.$content,\r\n $slide = slide.$slide,\r\n width = slide.width || slide.opts.width,\r\n height = slide.height || slide.opts.height,\r\n maxWidth,\r\n maxHeight,\r\n minRatio,\r\n aspectRatio,\r\n rez = {};\r\n\r\n if (!slide.isLoaded || !$content || !$content.length) {\r\n return false;\r\n }\r\n\r\n maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;\r\n maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;\r\n\r\n maxWidth -=\r\n parseFloat($slide.css(\"paddingLeft\")) +\r\n parseFloat($slide.css(\"paddingRight\")) +\r\n parseFloat($content.css(\"marginLeft\")) +\r\n parseFloat($content.css(\"marginRight\"));\r\n\r\n maxHeight -=\r\n parseFloat($slide.css(\"paddingTop\")) +\r\n parseFloat($slide.css(\"paddingBottom\")) +\r\n parseFloat($content.css(\"marginTop\")) +\r\n parseFloat($content.css(\"marginBottom\"));\r\n\r\n if (!width || !height) {\r\n width = maxWidth;\r\n height = maxHeight;\r\n }\r\n\r\n minRatio = Math.min(1, maxWidth / width, maxHeight / height);\r\n\r\n width = minRatio * width;\r\n height = minRatio * height;\r\n\r\n // Adjust width/height to precisely fit into container\r\n if (width > maxWidth - 0.5) {\r\n width = maxWidth;\r\n }\r\n\r\n if (height > maxHeight - 0.5) {\r\n height = maxHeight;\r\n }\r\n\r\n if (slide.type === \"image\") {\r\n rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css(\"paddingTop\"));\r\n rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css(\"paddingLeft\"));\r\n } else if (slide.contentType === \"video\") {\r\n // Force aspect ratio for the video\r\n // \"I say the whole world must learn of our peaceful ways… by force!\"\r\n aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;\r\n\r\n if (height > width / aspectRatio) {\r\n height = width / aspectRatio;\r\n } else if (width > height * aspectRatio) {\r\n width = height * aspectRatio;\r\n }\r\n }\r\n\r\n rez.width = width;\r\n rez.height = height;\r\n\r\n return rez;\r\n },\r\n\r\n // Update content size and position for all slides\r\n // ==============================================\r\n\r\n update: function (e) {\r\n var self = this;\r\n\r\n $.each(self.slides, function (key, slide) {\r\n self.updateSlide(slide, e);\r\n });\r\n },\r\n\r\n // Update slide content position and size\r\n // ======================================\r\n\r\n updateSlide: function (slide, e) {\r\n var self = this,\r\n $content = slide && slide.$content,\r\n width = slide.width || slide.opts.width,\r\n height = slide.height || slide.opts.height,\r\n $slide = slide.$slide;\r\n\r\n // First, prevent caption overlap, if needed\r\n self.adjustCaption(slide);\r\n\r\n // Then resize content to fit inside the slide\r\n if ($content && (width || height || slide.contentType === \"video\") && !slide.hasError) {\r\n $.fancybox.stop($content);\r\n\r\n $.fancybox.setTranslate($content, self.getFitPos(slide));\r\n\r\n if (slide.pos === self.currPos) {\r\n self.isAnimating = false;
109\r\n\r\n self.updateCursor();\r\n }\r\n }\r\n\r\n // Then some adjustments\r\n self.adjustLayout(slide);\r\n\r\n if ($slide.length) {\r\n $slide.trigger(\"refresh\");\r\n\r\n if (slide.pos === self.currPos) {\r\n self.$refs.toolbar\r\n .add(self.$refs.navigation.find(\".fancybox-button--arrow_right\"))\r\n .toggleClass(\"compensate-for-scrollbar\", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);\r\n }\r\n }\r\n\r\n self.trigger(\"onUpdate\", slide, e);\r\n },\r\n\r\n // Horizontally center slide\r\n // =========================\r\n\r\n centerSlide: function (duration) {\r\n var self = this,\r\n current = self.current,\r\n $slide = current.$slide;\r\n\r\n if (self.isClosing || !current) {\r\n return;\r\n }\r\n\r\n $slide.siblings().css({\r\n transform: \"\",\r\n opacity: \"\"\r\n });\r\n\r\n $slide\r\n .parent()\r\n .children()\r\n .removeClass(\"fancybox-slide--previous fancybox-slide--next\");\r\n\r\n $.fancybox.animate(\r\n $slide, {\r\n top: 0,\r\n left: 0,\r\n opacity: 1\r\n },\r\n duration === undefined ? 0 : duration,\r\n function () {\r\n // Clean up\r\n $slide.css({\r\n transform: \"\",\r\n opacity: \"\"\r\n });\r\n\r\n if (!current.isComplete) {\r\n self.complete();\r\n }\r\n },\r\n false\r\n );\r\n },\r\n\r\n // Check if current slide is moved (swiped)\r\n // ========================================\r\n\r\n isMoved: function (slide) {\r\n var current = slide || this.current,\r\n slidePos,\r\n stagePos;\r\n\r\n if (!current) {\r\n return false;\r\n }\r\n\r\n stagePos = $.fancybox.getTranslate(this.$refs.stage);\r\n slidePos = $.fancybox.getTranslate(current.$slide);\r\n\r\n return (\r\n !current.$slide.hasClass(\"fancybox-animated\") &&\r\n (Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5)\r\n );\r\n },\r\n\r\n // Update cursor style depending if content can be zoomed\r\n // ======================================================\r\n\r\n updateCursor: function (nextWidth, nextHeight) {\r\n var self = this,\r\n current = self.current,\r\n $container = self.$refs.container,\r\n canPan,\r\n isZoomable;\r\n\r\n if (!current || self.isClosing || !self.Guestures) {\r\n return;\r\n }\r\n\r\n $container.removeClass(\"fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan\");\r\n\r\n canPan = self.canPan(nextWidth, nextHeight);\r\n\r\n isZoomable = canPan ? true : self.isZoomable();\r\n\r\n $container.toggleClass(\"fancybox-is-zoomable\", isZoomable);\r\n\r\n $(\"[data-fancybox-zoom]\").prop(\"disabled\", !isZoomable);\r\n\r\n if (canPan) {\r\n $container.addClass(\"fancybox-can-pan\");\r\n } else if (\r\n isZoomable &&\r\n (current.opts.clickContent === \"zoom\" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == \"zoom\"))\r\n ) {\r\n $container.addClass(\"fancybox-can-zoomIn\");\r\n } else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== \"video\") {\r\n $container.addClass(\"fancybox-can-swipe\");\r\n }\r\n },\r\n\r\n // Check if current slide is zoomable\r\n // ==================================\r\n\r\n isZoomable: function () {\r\n var self = this,\r\n current = self.current,\r\n fitPos;\r\n\r\n // Assume that slide is zoomable if:\r\n // - image is still loading\r\n // - actual size of the image is smaller than available area\r\n if (current && !self.isClosing && current.type === \"image\" && !current.hasError) {\r\n if (!current.isLoaded) {\r\n return true;\r\n }\r\n\r\n fitPos = self.getFitPos(current);\r\n\r\n if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n\r\n // Check if current image dimensions are smaller than actual\r\n // =========================================================\r\n\r\n isScaledDown: function (nextWidth, nextHeight) {\r\n var self = this,\r\n rez = false,\r\n current = self.current,\r\n $content = current.$content;\r\n\r\n if (nextWidth !== undefined && nextHeight !== undefined) {\r\n rez = nextWidth < current.width && nextHeight < current.height;\r\n } else if ($content) {\r\n rez = $.fancybox.getTranslate($content);\r\n rez = rez.width < current.width && rez.height < current.height;\r\n }\r\n\r\n return rez;\r\n },\r\n\r\n // Check if image dimensions exceed parent element\r\n // ===============================================\r\n\r\n canPan: function (nextWidth, nextHeight) {\r\n var self = this,\r\n current = self.current,\r\n pos = null,\r\n rez = false;\r\n\r\n if (current.type === \"image\" && (current.isComplete || (nextWidth && nextHeight)) && !current.hasError) {\r\n rez = self.getFitPos(current);\r\n\r\n if (nextWidth !== undefined && nextHeight !== undefined) {\r\n pos = {\r\n width: nextWidth,\r\n height: nextHeight\r\n };\r\n } else if (current.isComplete) {\r\n pos = $.fancybox.getTranslate(current.$content);\r\n }\r\n\r\n if (pos && rez) {\r\n rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;\r\n }\r\n }\r\n\r\n return rez;\r\n },\r\n\r\n // Load content into the slide\r\n // ===========================\r\n\r\n loadSlide: function (slide) {\r\n var self = this,\r\n type,\r\n $slide,\r\n ajaxLoad;\r\n\r\n if (slide.isLoading || slide.isLoaded) {\r\n return;\r\n }\r\n\r\n slide.isLoading = true;\r\n\r\n if (self.trigger(\"beforeLoad\", slide) === false) {\r\n slide.isLoading = false;\r\n\r\n return false;\r\n }\r\n\r\n type = slide.type;\r\n $slide = slide.$slide;\r\n\r\n $slide\r\n .off(\"refresh\")\r\n .trigger(\"onReset\")\r\n .addClass(slide.opts.slideClass);\r\n\r\n // Create content depending on the type\r\n switch (type) {\r\n case \"image\":\r\n self.setImage(slide);\r\n\r\n break;\r\n\r\n case \"iframe\":\r\n self.setIframe(slide);\r\n\r\n break;\r\n\r\n case \"html\":\r\n self.setContent(slide, slide.src || slide.content);\r\n\r\n break;\r\n\r\n case \"video\":\r\n self.setContent(\r\n slide,\r\n slide.opts.video.tpl\r\n .replace(/\\{\\{src\\}\\}/gi, slide.src)\r\n .replace(\"{{format}}\", slide.opts.videoFormat || slide.opts.video.format || \"\")\r\n .replace(\"{{poster}}\", slide.thumb || \"\")\r\n );\r\n\r\n break;\r\n\r\n case \"inline\":\r\n if ($(slide.src).length) {\r\n self.setContent(slide, $(slide.src));\r\n } else {\r\n self.setError(slide);\r\n }\r\n\r\n break;\r\n\r\n case \"ajax\":\r\n self.showLoading(slide);\r\n\r\n ajaxLoad = $.ajax(\r\n $.extend({}, slide.opts.ajax.settings, {\r\n url: slide.src,\r\n success: function (data, textStatus) {\r\n if (textStatus === \"success\") {\r\n self.setContent(slide, data);\r\n }\r\n },\r\n error: function (jqXHR, textStatus) {\r\n if (jqXHR && textStatus !== \"abort\") {\r\n self.setError(slide);\r\n }\r\n }\r\n })\r\n );\r\n\r\n $slide.one(\"onReset\", function () {\r\n ajaxLoad.abort();\r\n });\r\n\r\n break;\r\n\r\n default:\r\n self.setError(slide);\r\n\r\n break;\r\n }\r\n\r\n return true;\r\n },\r\n\r\n // Use thumbnail image, if possible\r\n // ================================\r\n\r\n setImage: function (slide) {\r\n var self = this,\r\n ghost;\r\n\r\n // Check if need to show loading icon\r\n setTimeout(function () {\r\n var $img = slide.$image;\r\n\r\n if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {\r\n self.showLoading(slide);\r\n }\r\n }, 50);\r\n\r\n //Check if image has srcset\r\n self.checkSrcset(slide);\r\n\r\n // This will be wrapper containing both ghost and actual image\r\n slide.$content = $('<div class=\"fancybox-content\"></div>')\r\n .addClass(\"fancybox-is-hidden\")\r\n .appendTo(slide.$slide.addClass(\"fancybox-slide--image\"));\r\n\r\n // If we have a thumbnail, we can display it while actual image is loading\r\n // Users will not stare at black screen and actual image will appear gradually\r\n if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {\r\n slide.width = slide.opts.width;\r\n slide.height = slide.opts.height;\r\n\r\n ghost = document.createElement(\"img\");\r\n\r\n ghost.onerror = function () {\r\n $(this).remove();\r\n\r\n slide.$ghost = null;\r\n };\r\n\r\n ghost.onload = function () {\r\n self.afterLoad(sli
109de);\r\n };\r\n\r\n slide.$ghost = $(ghost)\r\n .addClass(\"fancybox-image\")\r\n .appendTo(slide.$content)\r\n .attr(\"src\", slide.thumb);\r\n }\r\n\r\n // Start loading actual image\r\n self.setBigImage(slide);\r\n },\r\n\r\n // Check if image has srcset and get the source\r\n // ============================================\r\n checkSrcset: function (slide) {\r\n var srcset = slide.opts.srcset || slide.opts.image.srcset,\r\n found,\r\n temp,\r\n pxRatio,\r\n windowWidth;\r\n\r\n // If we have \"srcset\", then we need to find first matching \"src\" value.\r\n // This is necessary, because when you set an src attribute, the browser will preload the image\r\n // before any javascript or even CSS is applied.\r\n if (srcset) {\r\n pxRatio = window.devicePixelRatio || 1;\r\n windowWidth = window.innerWidth * pxRatio;\r\n\r\n temp = srcset.split(\",\").map(function (el) {\r\n var ret = {};\r\n\r\n el.trim()\r\n .split(/\\s+/)\r\n .forEach(function (el, i) {\r\n var value = parseInt(el.substring(0, el.length - 1), 10);\r\n\r\n if (i === 0) {\r\n return (ret.url = el);\r\n }\r\n\r\n if (value) {\r\n ret.value = value;\r\n ret.postfix = el[el.length - 1];\r\n }\r\n });\r\n\r\n return ret;\r\n });\r\n\r\n // Sort by value\r\n temp.sort(function (a, b) {\r\n return a.value - b.value;\r\n });\r\n\r\n // Ok, now we have an array of all srcset values\r\n for (var j = 0; j < temp.length; j++) {\r\n var el = temp[j];\r\n\r\n if ((el.postfix === \"w\" && el.value >= windowWidth) || (el.postfix === \"x\" && el.value >= pxRatio)) {\r\n found = el;\r\n break;\r\n }\r\n }\r\n\r\n // If not found, take the last one\r\n if (!found && temp.length) {\r\n found = temp[temp.length - 1];\r\n }\r\n\r\n if (found) {\r\n slide.src = found.url;\r\n\r\n // If we have default width/height values, we can calculate height for matching source\r\n if (slide.width && slide.height && found.postfix == \"w\") {\r\n slide.height = (slide.width / slide.height) * found.value;\r\n slide.width = found.value;\r\n }\r\n\r\n slide.opts.srcset = srcset;\r\n }\r\n }\r\n },\r\n\r\n // Create full-size image\r\n // ======================\r\n\r\n setBigImage: function (slide) {\r\n var self = this,\r\n img = document.createElement(\"img\"),\r\n $img = $(img);\r\n\r\n slide.$image = $img\r\n .one(\"error\", function () {\r\n self.setError(slide);\r\n })\r\n .one(\"load\", function () {\r\n var sizes;\r\n\r\n if (!slide.$ghost) {\r\n self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);\r\n\r\n self.afterLoad(slide);\r\n }\r\n\r\n if (self.isClosing) {\r\n return;\r\n }\r\n\r\n if (slide.opts.srcset) {\r\n sizes = slide.opts.sizes;\r\n\r\n if (!sizes || sizes === \"auto\") {\r\n sizes =\r\n (slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? \"100\" : Math.round((slide.width / slide.height) * 100)) +\r\n \"vw\";\r\n }\r\n\r\n $img.attr(\"sizes\", sizes).attr(\"srcset\", slide.opts.srcset);\r\n }\r\n\r\n // Hide temporary image after some delay\r\n if (slide.$ghost) {\r\n setTimeout(function () {\r\n if (slide.$ghost && !self.isClosing) {\r\n slide.$ghost.hide();\r\n }\r\n }, Math.min(300, Math.max(1000, slide.height / 1600)));\r\n }\r\n\r\n self.hideLoading(slide);\r\n })\r\n .addClass(\"fancybox-image\")\r\n .attr(\"src\", slide.src)\r\n .appendTo(slide.$content);\r\n\r\n if ((img.complete || img.readyState == \"complete\") && $img.naturalWi
109dth && $img.naturalHeight) {\r\n $img.trigger(\"load\");\r\n } else if (img.error) {\r\n $img.trigger(\"error\");\r\n }\r\n },\r\n\r\n // Computes the slide size from image size and maxWidth/maxHeight\r\n // ==============================================================\r\n\r\n resolveImageSlideSize: function (slide, imgWidth, imgHeight) {\r\n var maxWidth = parseInt(slide.opts.width, 10),\r\n maxHeight = parseInt(slide.opts.height, 10);\r\n\r\n // Sets the default values from the image\r\n slide.width = imgWidth;\r\n slide.height = imgHeight;\r\n\r\n if (maxWidth > 0) {\r\n slide.width = maxWidth;\r\n slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);\r\n }\r\n\r\n if (maxHeight > 0) {\r\n slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);\r\n slide.height = maxHeight;\r\n }\r\n },\r\n\r\n // Create iframe wrapper, iframe and bindings\r\n // ==========================================\r\n\r\n setIframe: function (slide) {\r\n var self = this,\r\n opts = slide.opts.iframe,\r\n $slide = slide.$slide,\r\n $iframe;\r\n\r\n slide.$content = $('<div class=\"fancybox-content' + (opts.preload ? \" fancybox-is-hidden\" : \"\") + '\"></div>')\r\n .css(opts.css)\r\n .appendTo($slide);\r\n\r\n $slide.addClass(\"fancybox-slide--\" + slide.contentType);\r\n\r\n slide.$iframe = $iframe = $(opts.tpl.replace(/\\{rnd\\}/g, new Date().getTime()))\r\n .attr(opts.attr)\r\n .appendTo(slide.$content);\r\n\r\n if (opts.preload) {\r\n self.showLoading(slide);\r\n\r\n // Unfortunately, it is not always possible to determine if iframe is successfully loaded\r\n // (due to browser security policy)\r\n\r\n $iframe.on(\"load.fb error.fb\", function (e) {\r\n this.isReady = 1;\r\n\r\n slide.$slide.trigger(\"refresh\");\r\n\r\n self.afterLoad(slide);\r\n });\r\n\r\n // Recalculate iframe content size\r\n // ===============================\r\n\r\n $slide.on(\"refresh.fb\", function () {\r\n var $content = slide.$content,\r\n frameWidth = opts.css.width,\r\n frameHeight = opts.css.height,\r\n $contents,\r\n $body;\r\n\r\n if ($iframe[0].isReady !== 1) {\r\n return;\r\n }\r\n\r\n try {\r\n $contents = $iframe.contents();\r\n $body = $contents.find(\"body\");\r\n } catch (ignore) {}\r\n\r\n // Calculate content dimensions, if it is accessible\r\n if ($body && $body.length && $body.children().length) {\r\n // Avoid scrolling to top (if multiple instances)\r\n $slide.css(\"overflow\", \"visible\");\r\n\r\n $content.css({\r\n width: \"100%\",\r\n \"max-width\": \"100%\",\r\n height: \"9999px\"\r\n });\r\n\r\n if (frameWidth === undefined) {\r\n frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));\r\n }\r\n\r\n $content.css(\"width\", frameWidth ? frameWidth : \"\").css(\"max-width\", \"\");\r\n\r\n if (frameHeight === undefined) {\r\n frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));\r\n }\r\n\r\n $content.css(\"height\", frameHeight ? frameHeight : \"\");\r\n\r\n $slide.css(\"overflow\", \"auto\");\r\n }\r\n\r\n $content.removeClass(\"fancybox-is-hidden\");\r\n });\r\n } else {\r\n self.afterLoad(slide);\r\n }\r\n\r\n $iframe.attr(\"src\", slide.src);\r\n\r\n // Remove iframe if closing or changing gallery item\r\n $slide.one(\"onReset\", function () {\r\n // This helps IE not to throw errors when closing\r\n try {\r\n $(this)\r\n .find(\"iframe\")\r\n .hide()\r\n .unbind()\r\n .attr(\"src\", \"//about:blank\");\r\n } catch (ignore) {}\r\n\r\n $(this)\r\n .off(\"refresh.fb\")\r\n .empty();\r\n\r\n slide.isLoaded = false;\r\n slide.isRevealed = false;\r\n });\r\n },\r\n\r\n // Wrap and append content to the slide\r\n // ======================================\r\n\r\n setContent: function (slide, content) {\r\n var self = this;\r\n\r\n if (self.isClosing) {\r\n return;\r\n }\r\n\r\n self.hideLoading(slide);\r\n\r\n if (slide.$content) {\r\n $.fancybox.stop(slide.$content);\r\n }\r\n\r\n slide.$slide.empty();\r\n\r\n // If content is a jQuery object, then it will be moved to the slide.\r\n // The placeholder is created so we will know where to put it back.\r\n if (isQuery(content) && content.parent().length) {\r\n // Make sure content is not already moved to fancyBox\r\n if (content.hasClass(\"fancybox-content\") || content.parent().hasClass(\"fancybox-content\")) {\r\n content.parents(\".fancybox-slide\").trigger(\"onReset\");\r\n }\r\n\r\n // Create temporary element marking original place of the content\r\n slide.$placeholder = $(\"<div>\")\r\n .hide()\r\n .insertAfter(content);\r\n\r\n // Make sure content is visible\r\n content.css(\"display\", \"inline-block\");\r\n } else if (!slide.hasError) {\r\n // If content is just a plain text, try to convert it to html\r\n if ($.type(content) === \"string\") {\r\n content = $(\"<div>\")\r\n .append($.trim(content))\r\n .contents();\r\n }\r\n\r\n // If \"filter\" option is provided, then filter content\r\n if (slide.opts.filter) {\r\n content = $(\"<div>\")\r\n .html(content)\r\n .find(slide.opts.filter);\r\n }\r\n }\r\n\r\n slide.$slide.one(\"onReset\", function () {\r\n // Pause all html5 video/audio\r\n $(this)\r\n .find(\"video,audio\")\r\n .trigger(\"pause\");\r\n\r\n // Put content back\r\n if (slide.$placeholder) {\r\n slide.$placeholder.after(content.removeClass(\"fancybox-content\").hide()).remove();\r\n\r\n slide.$placeholder = null;\r\n }\r\n\r\n // Remove custom close button\r\n if (slide.$smallBtn) {\r\n slide.$smallBtn.remove();\r\n\r\n slide.$smallBtn = null;\r\n }
109\r\n\r\n // Remove content and mark slide as not loaded\r\n if (!slide.hasError) {\r\n $(this).empty();\r\n\r\n slide.isLoaded = false;\r\n slide.isRevealed = false;\r\n }\r\n });\r\n\r\n $(content).appendTo(slide.$slide);\r\n\r\n if ($(content).is(\"video,audio\")) {\r\n $(content).addClass(\"fancybox-video\");\r\n\r\n $(content).wrap(\"<div></div>\");\r\n\r\n slide.contentType = \"video\";\r\n\r\n slide.opts.width = slide.opts.width || $(content).attr(\"width\");\r\n slide.opts.height = slide.opts.height || $(content).attr(\"height\");\r\n }\r\n\r\n slide.$content = slide.$slide\r\n .children()\r\n .filter(\"div,form,main,video,audio,article,.fancybox-content\")\r\n .first();\r\n\r\n slide.$content.siblings().hide();\r\n\r\n // Re-check if there is a valid content\r\n // (in some cases, ajax response can contain various elements or plain text)\r\n if (!slide.$content.length) {\r\n slide.$content = slide.$slide\r\n .wrapInner(\"<div></div>\")\r\n .children()\r\n .first();\r\n }\r\n\r\n slide.$content.addClass(\"fancybox-content\");\r\n\r\n slide.$slide.addClass(\"fancybox-slide--\" + slide.contentType);\r\n\r\n self.afterLoad(slide);\r\n },\r\n\r\n // Display error message\r\n // =====================\r\n\r\n setError: function (slide) {\r\n slide.hasError = true;\r\n\r\n slide.$slide\r\n .trigger(\"onReset\")\r\n .removeClass(\"fancybox-slide--\" + slide.contentType)\r\n .addClass(\"fancybox-slide--error\");\r\n\r\n slide.contentType = \"html\";\r\n\r\n this.setContent(slide, this.translate(slide, slide.opts.errorTpl));\r\n\r\n if (slide.pos === this.currPos) {\r\n this.isAnimating = false;\r\n }\r\n },\r\n\r\n // Show loading icon inside the slide\r\n // ==================================\r\n\r\n showLoading: function (slide) {\r\n var self = this;\r\n\r\n slide = slide || self.current;\r\n\r\n if (slide && !slide.$spinner) {\r\n slide.$spinner = $(self.translate(self, self.opts.spinnerTpl))\r\n .appendTo(slide.$slide)\r\n .hide()\r\n .fadeIn(\"fast\");\r\n }\r\n },\r\n\r\n // Remove loading icon from the slide\r\n // ==================================\r\n\r\n hideLoading: function (slide) {\r\n var self = this;\r\n\r\n slide = slide || self.current;\r\n\r\n if (slide && slide.$spinner) {\r\n slide.$spinner.stop().remove();\r\n\r\n delete slide.$spinner;\r\n }\r\n },\r\n\r\n // Adjustments after slide content has been loaded\r\n // ===============================================\r\n\r\n afterLoad: function (slide) {\r\n var self = this;\r\n\r\n if (self.isClosing) {\r\n return;\r\n }\r\n\r\n slide.isLoading = false;\r\n slide.isLoaded = true;\r\n\r\n self.trigger(\"afterLoad\", slide);\r\n\r\n self.hideLoading(slide);\r\n\r\n // Add small close button\r\n if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {\r\n slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);\r\n }\r\n\r\n // Disable right click\r\n if (slide.opts.protect && slide.$content && !slide.hasError) {\r\n slide.$content.on(\"contextmenu.fb\", function (e) {\r\n if (e.button == 2) {\r\n e.preventDefault();\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Add fake element on top of the image\r\n // This makes a bit harder for user to select image\r\n if (slide.type === \"image\") {\r\n $('<div class=\"fancybox-spaceball\"></div>').appendTo(slide.$content);\r\n }\r\n }\r\n\r\n self.adjustCaption(slide);\r\n\r\n self.adjustLayout(slide);\r\n\r\n if (slide.pos === self.currPos) {\r\n self.updateCursor();\r\n }\r\n\r\n self.revealContent(slide);\r\n },\r\n\r\n // Prevent caption overlap,\r\n // fix css inconsistency across browsers\r\n // =====================================\r\n\r\n adjustCaption: function (slide) {\r\n var self = this,\r\n current = slide || self.current,\r\n caption = current.opts.caption,\r\n preventOverlap = current.opts.preventCaptionOverlap,\r\n $caption = self.$refs.caption,\r\n $clone,\r\n captionH = false;\r\n\r\n $caption.toggleClass(\"fancybox-caption--separate\", preventOverlap);\r\n\r\n if (preventOverlap && caption && caption.length) {\r\n if (current.pos !== self.currPos) {\r\n $clone = $caption.clone().appendTo($caption.parent());\r\n\r\n $clone\r\n .children()\r\n .eq(0)\r\n .empty()\r\n .html(caption);\r\n\r\n captionH = $clone.outerHeight(true);\r\n\r\n $clone.empty().remove();\r\n } else if (self.$caption) {\r\n captionH = self.$caption.outerHeight(true);\r\n }\r\n\r\n current.$slide.css(\"padding-bottom\", captionH || \"\");\r\n }\r\n },\r\n\r\n // Simple hack to fix inconsistency across browsers, described here (affects Edge, too):\r\n // https://bugzilla.mozilla.org/show_bug.cgi?id=748518\r\n // ====================================================================================\r\n\r\n adjustLayout: function (slide) {\r\n var self = this,\r\n current = slide || self.current,\r\n scrollHeight,\r\n marginBottom,\r\n inlinePadding,\r\n actualPadding;\r\n\r\n if (current.isLoaded && current.opts.disableLayoutFix !== true) {\r\n current.$content.css(\"margin-bottom\", \"\");\r\n\r\n // If we would always set margin-bottom for the content,\r\n // then it would potentially break vertical align\r\n if (current.$content.outerHeight() > current.$slide.height() + 0.5) {\r\n inlinePadding = current.$slide[0].style[\"padding-bottom\"];\r\n actualPadding = current.$slide.css(\"padding-bottom\");\r\n\r\n if (parseFloat(actualPadding) > 0) {\r\n scrollHeight = current.$slide[0].scrollHeight;\r\n\r\n current.$slide.css(\"padding-bottom\", 0);\r\n\r\n if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {\r\n marginBottom = actualPadding;\r\n }\r\n\r\n current.$slide.css(\"padding-bottom\", inlinePadding);\r\n }\r\n }\r\n\r\n current.$content.css(\"margin-bottom\", marginBottom);\r\n }\r\n },\r\n\r\n // Make content visible\r\n // This method is called right after content has been loaded or\r\n // user navigates gallery and transition should start\r\n // ============================================================\r\n\r\n revealContent: function (slide) {\r\n var self = this,\r\n $slide = slide.$slide,\r\n end = false,\r\n start = false,\r\n isMoved = self.isMoved(slide),\r\n isRevealed = slide.isRevealed,\r\n effect,\r\n effectClassName,\r\n duration,\r\n opacity;\r\n\r\n slide.isRevealed = true;\r\n\r\n effect = slide.opts[self.firstRun ? \"animationEffect\" : \"transitionEffect\"];\r\n duration = slide.opts[self.firstRun ? \"animationDuration\" : \"transitionDuration\"];\r\n\r\n duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);\r\n\r\n if (isMoved || slide.pos !== self.currPos || !duration) {\r\n effect = false;\r\n }\r\n\r\n // Check if can zoom\r\n if (effect === \"zoom\") {\r\n if (slide.pos === self.currPos && duration && slide.type === \"image\" && !slide.hasError && (start = self.getThumbPos(slide))) {\r\n end = self.getFitPos(slide);\r\n } else {\r\n effect = \"fade\";\r\n }\r\n }\r\n\r\n // Zoom animation\r\n // ==============\r\n if (effect === \"zoom\") {\r\n self.isAnimating = true;\r\n\r\n end.scaleX = end.width / start.width;\r\n end.scaleY = end.height / start.height;\r\n\r\n // Check if we need to animate opacity\r\n opacity = slide.opts.zoomOpacity;\r\n\r\n if (opacity == \"auto\") {\r\n opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;\r\n }\r\n\r\n if (opacity) {\r\n start.opacity = 0.1;\r\n end.opacity = 1;\r\n }\r\n\r\n // Draw image at start position\r\n $.fancybox.setTranslate(slide.$content.removeClass(\"fancybox-is-hidden\"), start);\r\n\r\n forceRedraw(slide.$content);\r\n\r\n // Start animation\r\n $.fancybox.animate(slide.$content, end, duration, function () {\r\n self.isAnimating = false;\r\n\r\n self.complete();\r\n });\r\n\r\n return;\r\n }\r\n\r\n self.updateSlide(slide);\r\n\r\n // Simply show content if no effect\r\n // ================================\r\n if (!effect) {\r\n slide.$content.removeClass(\"fancybox-is-hidden\");\r\n\r\n if (!isRevealed && isMoved && slide.type === \"image\" && !slide.hasError) {\r\n slide.$content.hide().fadeIn(\"fast\");\r\n }\r\n\r\n if (slide.pos === self.currPos) {\r\n self.complete();\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Prepare for CSS transiton\r\n // =========================\r\n $.fancybox.stop($slide);\r\n\r\n //effectClassName = \"fancybox-animated fancybox-slide--\" + (slide.pos >= self.prevPos ? \"next\" : \"previous\") + \" fancybox-fx-\" + effect;\r\n effectClassName = \"fancybox-slide--\" + (slide.pos >= self.prevPos ? \"next\" : \"previous\") + \" fancybox-animated fancybox-fx-\" + effect;\r\n\r\n $slide.addClass(effectClassName).removeClass(\"fancybox-slide--current\"); //.addClass(effectClassName);\r\n\r\n slide.$content.removeClass(\"fancybox-is-hidden\");\r\n\r\n // Force reflow\r\n forceRedraw($slide);\r\n\r\n if (slide.type !== \"image\") {\r\n slide.$content.hide().show(0);\r\n }\r\n\r\n $.fancybox.animate(\r\n $slide,\r\n \"fancybox-slide--current\",\r\n duration,\r\n function () {\r\n $slide.removeClass(effectClassName).css({\r\n transform: \"\",\r\n opacity: \"\"\r\n });\r\n\r\n if (slide.pos === self.currPos) {\r\n self.complete();\r\n }\r\n },\r\n true\r\n );\r\n },\r\n\r\n // Check if we can and have to zoom from thumbnail\r\n //================================================\r\n\r\n getThumbPos: function (slide) {\r\n var rez = false,\r\n $thumb = slide.$thumb,\r\n thumbPos,\r\n btw,\r\n brw,\r\n bbw,\r\n blw;\r\n\r\n if (!$thumb || !inViewport($thumb[0])) {\r\n return false;\r\n }\r\n\r\n thumbPos = $.fancybox.getTranslate($thumb);\r\n\r\n btw = parseFloat($thumb.css(\"border-top-width\") || 0);\r\n brw = parseFloat($thumb.css(\"border-right-width\") || 0);\r\n bbw = parseFloat($thumb.css(\"border-bottom-width\") || 0);\r\n blw = parseFloat($thumb.css(\"border-left-width\") || 0);\r\n\r\n rez = {\r\n top: thumbPos.top + btw,\r\n left: thumbPos.left + blw,\r\n width: thumbPos.width - brw - blw,\r\n height: thumbPos.height - btw - bbw,\r\n scaleX: 1,\r\n scaleY: 1\r\n };\r\n\r\n return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;\r\n },\r\n\r\n // Final adjustments after current gallery item is moved to position\r\n // and it`s content is loaded\r\n // ==================================================================\r\n\r\n complete: function () {\r\n var self = this,\r\n current = self.current,\r\n slides = {},\r\n $el;\r\n\r\n if (self.isMoved() || !current.isLoaded) {\r\n return;\r\n }\r\n\r\n if (!current.isComplete) {\r\n current.isComplete = true;\r\n\r\n current.$slide.siblings().trigger(\"onReset\");\r\n\r\n self.preload(\"inline\");\r\n\r\n // Trigger any CSS transiton inside the slide\r\n forceRedraw(current.$slide);\r\n\r\n current.$slide.addClass(\"fancybox-slide--complete\");\r\n\r\n // Remove unnecessary slides\r\n $.each(self.slides, function (key, slide) {\r\n if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {\r\n slides[slide.pos] = slide;\r\n } else if (slide) {\r\n $.fancybox.stop(slide.$slide);\r\n\r\n slide.$slide.off().remove();\r\n }\r\n });\r\n\r\n self.slides = slides;\r\n }\r\n\r\n self.isAnimating = false;
109\r\n\r\n self.updateCursor();\r\n\r\n self.trigger(\"afterShow\");\r\n\r\n // Autoplay first html5 video/audio\r\n if (!!current.opts.video.autoStart) {\r\n current.$slide\r\n .find(\"video,audio\")\r\n .filter(\":visible:first\")\r\n .trigger(\"play\")\r\n .one(\"ended\", function () {\r\n if (Document.exitFullscreen) {\r\n Document.exitFullscreen();\r\n } else if (this.webkitExitFullscreen) {\r\n this.webkitExitFullscreen();\r\n }\r\n\r\n self.next();\r\n });\r\n }\r\n\r\n // Try to focus on the first focusable element\r\n if (current.opts.autoFocus && current.contentType === \"html\") {\r\n // Look for the first input with autofocus attribute\r\n $el = current.$content.find(\"input[autofocus]:enabled:visible:first\");\r\n\r\n if ($el.length) {\r\n $el.trigger(\"focus\");\r\n } else {\r\n self.focus(null, true);\r\n }\r\n }\r\n\r\n // Avoid jumping\r\n current.$slide.scrollTop(0).scrollLeft(0);\r\n },\r\n\r\n // Preload next and previous slides\r\n // ================================\r\n\r\n preload: function (type) {\r\n var self = this,\r\n prev,\r\n next;\r\n\r\n if (self.group.length < 2) {\r\n return;\r\n }\r\n\r\n next = self.slides[self.currPos + 1];\r\n prev = self.slides[self.currPos - 1];\r\n\r\n if (prev && prev.type === type) {\r\n self.loadSlide(prev);\r\n }\r\n\r\n if (next && next.type === type) {\r\n self.loadSlide(next);\r\n }\r\n },\r\n\r\n // Try to find and focus on the first focusable element\r\n // ====================================================\r\n\r\n focus: function (e, firstRun) {\r\n var self = this,\r\n focusableStr = [\r\n \"a[href]\",\r\n \"area[href]\",\r\n 'input:not([disabled]):not([type=\"hidden\"]):not([aria-hidden])',\r\n \"select:not([disabled]):not([aria-hidden])\",\r\n \"textarea:not([disabled]):not([aria-hidden])\",\r\n \"button:not([disabled]):not([aria-hidden])\",\r\n \"iframe\",\r\n \"object\",\r\n \"embed\",\r\n \"video\",\r\n \"audio\",\r\n \"[contenteditable]\",\r\n '[tabindex]:not([tabindex^=\"-\"])'\r\n ].join(\",\"),\r\n focusableItems,\r\n focusedItemIndex;\r\n\r\n if (self.isClosing) {\r\n return;\r\n }\r\n\r\n if (e || !self.current || !self.current.isComplete) {\r\n // Focus on any element inside fancybox\r\n focusableItems = self.$refs.container.find(\"*:visible\");\r\n } else {\r\n // Focus inside current slide\r\n focusableItems = self.current.$slide.find(\"*:visible\" + (firstRun ? \":not(.fancybox-close-small)\" : \"\"));\r\n }\r\n\r\n focusableItems = focusableItems.filter(focusableStr).filter(function () {\r\n return $(this).css(\"visibility\") !== \"hidden\" && !$(this).hasClass(\"disabled\");\r\n });\r\n\r\n if (focusableItems.length) {\r\n focusedItemIndex = focusableItems.index(document.activeElement);\r\n\r\n if (e && e.shiftKey) {\r\n // Back tab\r\n if (focusedItemIndex < 0 || focusedItemIndex == 0) {\r\n e.preventDefault();\r\n\r\n focusableItems.eq(focusableItems.length - 1).trigger(\"focus\");\r\n }\r\n } else {\r\n // Outside or Forward tab\r\n if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {\r\n if (e) {\r\n e.preventDefault();\r\n }\r\n\r\n focusableItems.eq(0).trigger(\"focus\");\r\n }\r\n }\r\n } else {\r\n self.$refs.container.trigger(\"focus\");\r\n }\r\n },\r\n\r\n // Activates current instance - brings container to the front and enables keyboard,\r\n // notifies other instances about deactivating\r\n // =================================================================================\r\n\r\n activate: function () {\r\n var self = this;\r\n\r\n // Deactivate all instances\r\n $(\".fancybox-container\").each(function () {\r\n var instance = $(this).data(\"FancyBox\");\r\n\r\n // Skip self and closing instances\r\n if (instance && instance.id !== self.id && !instance.isClosing) {\r\n instance.trigger(\"onDeactivate\");\r\n\r\n instance.removeEvents();\r\n\r\n instance.isVisible = false;\r\n }\r\n });\r\n\r\n self.isVisible = true;\r\n\r\n if (self.current || self.isIdle) {\r\n self.update(
109);\r\n\r\n self.updateControls();\r\n }\r\n\r\n self.trigger(\"onActivate\");\r\n\r\n self.addEvents();\r\n },\r\n\r\n // Start closing procedure\r\n // This will start \"zoom-out\" animation if needed and clean everything up afterwards\r\n // =================================================================================\r\n\r\n close: function (e, d) {\r\n var self = this,\r\n current = self.current,\r\n effect,\r\n duration,\r\n $content,\r\n domRect,\r\n opacity,\r\n start,\r\n end;\r\n\r\n var done = function () {\r\n self.cleanUp(e);\r\n };\r\n\r\n if (self.isClosing) {\r\n return false;\r\n }\r\n\r\n self.isClosing = true;\r\n\r\n // If beforeClose callback prevents closing, make sure content is centered\r\n if (self.trigger(\"beforeClose\", e) === false) {\r\n self.isClosing = false;\r\n\r\n requestAFrame(function () {\r\n self.update();\r\n });\r\n\r\n return false;\r\n }\r\n\r\n // Remove all events\r\n // If there are multiple instances, they will be set again by \"activate\" method\r\n self.removeEvents();\r\n\r\n $content = current.$content;\r\n effect = current.opts.animationEffect;\r\n duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;\r\n\r\n current.$slide.removeClass(\"fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated\");\r\n\r\n if (e !== true) {\r\n $.fancybox.stop(current.$slide);\r\n } else {\r\n effect = false;\r\n }\r\n\r\n // Remove other slides\r\n current.$slide\r\n .siblings()\r\n .trigger(\"onReset\")\r\n .remove();\r\n\r\n // Trigger animations\r\n if (duration) {\r\n self.$refs.container\r\n .removeClass(\"fancybox-is-open\")\r\n .addClass(\"fancybox-is-closing\")\r\n .css(\"transition-duration\", duration + \"ms\");\r\n }\r\n\r\n // Clean up\r\n self.hideLoading(current);\r\n\r\n self.hideControls(true);\r\n\r\n self.updateCursor();\r\n\r\n // Check if possible to zoom-out\r\n if (\r\n effect === \"zoom\" &&\r\n !($content && duration && current.type === \"image\" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))\r\n ) {\r\n effect = \"fade\";\r\n }\r\n\r\n if (effect === \"zoom\") {\r\n $.fancybox.stop($content);\r\n\r\n domRect = $.fancybox.getTranslate($content);\r\n\r\n start = {\r\n top: domRect.top,\r\n left: domRect.left,\r\n scaleX: domRect.width / end.width,\r\n scaleY: domRect.height / end.height,\r\n width: end.width,\r\n height: end.height\r\n };\r\n\r\n // Check if we need to animate opacity\r\n opacity = current.opts.zoomOpacity;\r\n\r\n if (opacity == \"auto\") {\r\n opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;\r\n }\r\n\r\n if (opacity) {\r\n end.opacity = 0;\r\n }\r\n\r\n $.fancybox.setTranslate($content, start);\r\n\r\n forceRedraw($content);\r\n\r\n $.fancybox.animate($content, end, duration, done);\r\n\r\n return true;\r\n }\r\n\r\n if (effect && duration) {\r\n $.fancybox.animate(\r\n current.$slide.addClass(\"fancybox-slide--previous\").removeClass(\"fancybox-slide--current\"),\r\n \"fancybox-animated fancybox-fx-\" + effect,\r\n duration,\r\n done\r\n );\r\n } else {\r\n // If skip animation\r\n if (e === true) {\r\n setTimeout(done, duration);\r\n } else {\r\n done();\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n\r\n // Final adjustments after removing the instance\r\n // =============================================\r\n\r\n cleanUp: function (e) {\r\n var self = this,\r\n instance,\r\n $focus = self.current.opts.$orig,\r\n x,\r\n y;\r\n\r\n self.current.$slide.trigger(\"onReset\");\r\n\r\n self.$refs.container.empty().remove();\r\n\r\n self.trigger(\"afterClose\", e);\r\n\r\n // Place back focus\r\n if (!!self.current.opts.backFocus) {\r\n if (!$focus || !$focus.length || !$focus.is(\":visible\")) {\r\n $focus = self.$trigger;\r\n }\r\n\r\n if ($focus && $focus.length) {\r\n x = window.scrollX;\r\n y = window.scrollY;\r\n\r\n $focus.trigger(\"focus\");\r\n\r\n $(\"html, body\")\r\n .scrollTop(y)\r\n .scrollLeft(x);\r\n }\r\n }\r\n\r\n self.current = null;\r\n\r\n // Check if there are other instances\r\n instance = $.fancybox.getInstance();\r\n\r\n if (instance) {\r\n instance.activate();\r\n } else {\r\n $(\"body\").removeClass(\"fancybox-active compensate-for-scrollbar\");\r\n\r\n $(\"#fancybox-style-noscroll\").remove();\r\n }\r\n },\r\n\r\n // Call callback and trigger an event\r\n // ==================================\r\n\r\n trigger: function (name, slide) {\r\n var args = Array.prototype.slice.call(arguments, 1),\r\n self = this,\r\n obj = slide && slide.opts ? slide : self.current,\r\n rez;\r\n\r\n if (obj) {\r\n args.unshift(obj);\r\n } else {\r\n obj = self;\r\n }\r\n\r\n args.unshift(self);\r\n\r\n if ($.isFunction(obj.opts[name])) {\r\n rez = obj.opts[name].apply(obj, args);\r\n }\r\n\r\n if (rez === false) {\r\n return rez;\r\n }\r\n\r\n if (name === \"afterClose\" || !self.$refs) {\r\n $D.trigger(name + \".fb\", args);\r\n } else {\r\n self.$refs.container.trigger(name + \".fb\", args);\r\n }\r\n },\r\n\r\n // Update infobar values, navigation button states and reveal caption\r\n // ==================================================================\r\n\r\n updateControls: function () {\r\n var self = this,\r\n current = self.current,\r\n index = current.index,\r\n $container = self.$refs.container,\r\n $caption = self.$refs.caption,\r\n caption = current.opts.caption;\r\n\r\n // Recalculate content dimensions\r\n current.$slide.trigger(\"refresh\");\r\n\r\n // Set caption\r\n if (caption && caption.length) {\r\n self.$caption = $caption;\r\n\r\n $caption\r\n .children()\r\n .eq(0)\r\n .html(caption);\r\n } else {\r\n self.$caption = null;\r\n }
109\r\n\r\n if (!self.hasHiddenControls && !self.isIdle) {\r\n self.showControls();\r\n }\r\n\r\n // Update info and navigation elements\r\n $container.find(\"[data-fancybox-count]\").html(self.group.length);\r\n $container.find(\"[data-fancybox-index]\").html(index + 1);\r\n\r\n $container.find(\"[data-fancybox-prev]\").prop(\"disabled\", !current.opts.loop && index <= 0);\r\n $container.find(\"[data-fancybox-next]\").prop(\"disabled\", !current.opts.loop && index >= self.group.length - 1);\r\n\r\n if (current.type === \"image\") {\r\n // Re-enable buttons; update download button source\r\n $container\r\n .find(\"[data-fancybox-zoom]\")\r\n .show()\r\n .end()\r\n .find(\"[data-fancybox-download]\")\r\n .attr(\"href\", current.opts.image.src || current.src)\r\n .show();\r\n } else if (current.opts.toolbar) {\r\n $container.find(\"[data-fancybox-download],[data-fancybox-zoom]\").hide();\r\n }\r\n\r\n // Make sure focus is not on disabled button/element\r\n if ($(document.activeElement).is(\":hidden,[disabled]\")) {\r\n self.$refs.container.trigger(\"focus\");\r\n }\r\n },\r\n\r\n // Hide toolbar and caption\r\n // ========================\r\n\r\n hideControls: function (andCaption) {\r\n var self = this,\r\n arr = [\"infobar\", \"toolbar\", \"nav\"];\r\n\r\n if (andCaption || !self.current.opts.preventCaptionOverlap) {\r\n arr.push(\"caption\");\r\n }\r\n\r\n this.$refs.container.removeClass(\r\n arr\r\n .map(function (i) {\r\n return \"fancybox-show-\" + i;\r\n })\r\n .join(\" \")\r\n );\r\n\r\n this.hasHiddenControls = true;\r\n },\r\n\r\n showControls: function () {\r\n var self = this,\r\n opts = self.current ? self.current.opts : self.opts,\r\n $container = self.$refs.container;\r\n\r\n self.hasHiddenControls = false;\r\n self.idleSecondsCounter = 0;\r\n\r\n $container\r\n .toggleClass(\"fancybox-show-toolbar\", !!(opts.toolbar && opts.buttons))\r\n .toggleClass(\"fancybox-show-infobar\", !!(opts.infobar && self.group.length > 1))\r\n .toggleClass(\"fancybox-show-caption\", !!self.$caption)\r\n .toggleClass(\"fancybox-show-nav\", !!(opts.arrows && self.group.length > 1))\r\n .toggleClass(\"fancybox-is-modal\", !!opts.modal);\r\n },\r\n\r\n // Toggle toolbar and caption\r\n // ==========================\r\n\r\n toggleControls: function () {\r\n if (this.hasHiddenControls) {\r\n this.showControls();\r\n } else {\r\n this.hideControls();\r\n }\r\n }\r\n });\r\n\r\n $.fancybox = {\r\n version: \"3.5.7\",\r\n defaults: defaults,\r\n\r\n // Get current instance and execute a command.\r\n //\r\n // Examples of usage:\r\n //\r\n // $instance = $.fancybox.getInstance();\r\n // $.fancybox.getInstance().jumpTo( 1 );\r\n // $.fancybox.getInstance( 'jumpTo', 1 );\r\n // $.fancybox.getInstance( function() {\r\n // console.info( this.currIndex );\r\n // });\r\n // ======================================================\r\n\r\n getInstance: function (command) {\r\n var instance = $('.fancybox-container:not(\".fancybox-is-closing\"):last').data(\"FancyBox\"),\r\n args = Array.prototype.slice.call(arguments, 1);\r\n\r\n if (instance instanceof FancyBox) {\r\n if ($.type(command) === \"string\") {\r\n instance[command].apply(instance, args);\r\n } else if ($.type(command) === \"function\") {\r\n command.apply(instance, args);\r\n }\r\n\r\n return instance;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n // Create new instance\r\n // ===================\r\n\r\n open: function (items, opts, index) {\r\n return new FancyBox(items, opts, index);\r\n },\r\n\r\n // Close current or all instances\r\n // ==============================\r\n\r\n close: function (all) {\r\n var instance = this.getInstance();\r\n\r\n if (instance) {\r\n instance.close();\r\n\r\n // Try to find and close next instance\r\n if (all === true) {\r\n this.close(all);\r\n }\r\n }\r\n },\r\n\r\n // Close all instances and unbind all events\r\n // =========================================\r\n\r\n destroy: function () {\r\n this.close(true);\r\n\r\n $D.add(\"body\").off(\"click.fb-start\", \"**\");\r\n },\r\n\r\n // Try to detect mobile devices\r\n // ============================\r\n\r\n isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),\r\n\r\n // Detect if 'translate3d' support is available\r\n // ============================================\r\n\r\n use3d: (function () {\r\n var div = document.createElement(\"div\");\r\n\r\n return (\r\n window.getComputedStyle &&\r\n window.getComputedStyle(div) &&\r\n window.getComputedStyle(div).getPropertyValue(\"transform\") &&\r\n !(document.documentMode && document.documentMode < 11)\r\n );\r\n })(),\r\n\r\n // Helper function to get current visual state of an element\r\n // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]\r\n // =====================================================================\r\n\r\n getTranslate: function ($el) {\r\n var domRect;\r\n\r\n if (!$el || !$el.length) {\r\n return false;\r\n }\r\n\r\n domRect = $el[0].getBoundingClientRect();\r\n\r\n return {\r\n top: domRect.top || 0,\r\n left: domRect.left || 0,\r\n width: domRect.width,\r\n height: domRect.height,\r\n opacity: parseFloat($el.css(\"opacity\"))\r\n };\r\n },\r\n\r\n // Shortcut for setting \"translate3d\" properties for element\r\n // Can set be used to set opacity, too\r\n // ========================================================\r\n\r\n setTranslate: function ($el, props) {\r\n var str = \"\",\r\n css = {};\r\n\r\n if (!$el || !props) {\r\n return;\r\n }\r\n\r\n if (props.left !== undefined || props.top !== undefined) {\r\n str =\r\n (props.left === undefined ? $el.position().left : props.left) +\r\n \"px, \" +\r\n (props.top === undefined ? $el.position().top : props.top) +\r\n \"px\";\r\n\r\n if (this.use3d) {\r\n str = \"translate3d(\" + str + \", 0px)\";\r\n } else {\r\n str = \"translate(\" + str + \")\";\r\n }\r\n }\r\n\r\n if (props.scaleX !== undefined && props.scaleY !== undefined) {\r\n str += \" scale(\" + props.scaleX + \", \" + props.scaleY + \")\";\r\n } else if (props.scaleX !== undefined) {\r\n str += \" scaleX(\" + props.scaleX + \")\";\r\n }\r\n\r\n if (str.length) {\r\n css.transform = str;\r\n }\r\n\r\n if (props.opacity !== undefined) {\r\n css.opacity = props.opacity;\r\n }\r\n\r\n if (props.width !== undefined) {\r\n css.width = props.width;\r\n }\r\n\r\n if (props.height !== undefined) {\r\n css.height = props.height;\r\n }\r\n\r\n return $el.css(css);\r\n },\r\n\r\n // Simple CSS transition handler\r\n // =============================\r\n\r\n animate: function ($el, to, duration, callback, leaveAnimationName) {\r\n var self = this,\r\n from;\r\n\r\n if ($.isFunction(duration)) {\r\n callback = duration;\r\n duration = null;\r\n }\r\n\r\n self.stop($el);\r\n\r\n from = self.getTranslate($el);\r\n\r\n $el.on(transitionEnd, function (e) {\r\n // Skip events from child elements and z-index change\r\n if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == \"z-index\")) {\r\n return;\r\n }\r\n\r\n self.stop($el);\r\n\r\n if ($.isNumeric(duration)) {\r\n $el.css(\"transition-duration\", \"\");\r\n }\r\n\r\n if ($.isPlainObject(to)) {\r\n if (to.scaleX !== undefined && to.scaleY !== undefined) {\r\n self.setTranslate($el, {\r\n top: to.top,\r\n left: to.left,\r\n width: from.width * to.scaleX,\r\n height: from.height * to.scaleY,\r\n scaleX: 1,\r\n scaleY: 1\r\n });\r\n }\r\n } else if (leaveAnimationName !== true) {\r\n $el.removeClass(to);\r\n }\r\n\r\n if ($.isFunction(callback)) {\r\n callback(e);\r\n }\r\n });\r\n\r\n if ($.isNumeric(duration)) {\r\n $el.css(\"transition-duration\", duration + \"ms\");\r\n }\r\n\r\n // Start animation by changing CSS properties or class name\r\n if ($.isPlainObject(to)) {\r\n if (to.scaleX !== undefined && to.scaleY !== undefined) {\r\n delete to.width;\r\n delete to.height;\r\n\r\n if ($el.parent().hasClass(\"fancybox-slide--image\")) {\r\n $el.parent().addClass(\"fancybox-is-scaling\");\r\n }\r\n }\r\n\r\n $.fancybox.setTranslate($el, to);\r\n } else {\r\n $el.addClass(to);\r\n }\r\n\r\n // Make sure that `transitionend` callback gets fired\r\n $el.data(\r\n \"timer\",\r\n setTimeout(function () {\r\n $el.trigger(transitionEnd);\r\n }, duration + 33)\r\n );\r\n }
109,\r\n\r\n stop: function ($el, callCallback) {\r\n if ($el && $el.length) {\r\n clearTimeout($el.data(\"timer\"));\r\n\r\n if (callCallback) {\r\n $el.trigger(transitionEnd);\r\n }\r\n\r\n $el.off(transitionEnd).css(\"transition-duration\", \"\");\r\n\r\n $el.parent().removeClass(\"fancybox-is-scaling\");\r\n }\r\n }\r\n };\r\n\r\n // Default click handler for \"fancyboxed\" links\r\n // ============================================\r\n\r\n function _run(e, opts) {\r\n var items = [],\r\n index = 0,\r\n $target,\r\n value,\r\n instance;\r\n\r\n // Avoid opening multiple times\r\n if (e && e.isDefaultPrevented()) {\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n\r\n opts = opts || {};\r\n\r\n if (e && e.data) {\r\n opts = mergeOpts(e.data.options, opts);\r\n }\r\n\r\n $target = opts.$target || $(e.currentTarget).trigger(\"blur\");\r\n instance = $.fancybox.getInstance();\r\n\r\n if (instance && instance.$trigger && instance.$trigger.is($target)) {\r\n return;\r\n }\r\n\r\n if (opts.selector) {\r\n items = $(opts.selector);\r\n } else {\r\n // Get all related items and find index for clicked one\r\n value = $target.attr(\"data-fancybox\") || \"\";\r\n\r\n if (value) {\r\n items = e.data ? e.data.items : [];\r\n items = items.length ? items.filter('[data-fancybox=\"' + value + '\"]') : $('[data-fancybox=\"' + value + '\"]');\r\n } else {\r\n items = [$target];\r\n }\r\n }\r\n\r\n index = $(items).index($target);\r\n\r\n // Sometimes current item can not be found\r\n if (index < 0) {\r\n index = 0;\r\n }\r\n\r\n instance = $.fancybox.open(items, opts, index);\r\n\r\n // Save last active element\r\n instance.$trigger = $target;\r\n }\r\n\r\n // Create a jQuery plugin\r\n // ======================\r\n\r\n $.fn.fancybox = function (options) {\r\n var selector;\r\n\r\n options = options || {};\r\n selector = options.selector || false;\r\n\r\n if (selector) {\r\n // Use body element instead of document so it executes first\r\n $(\"body\")\r\n .off(\"click.fb-start\", selector)\r\n .on(\"click.fb-start\", selector, {\r\n options: options\r\n }, _run);\r\n } else {\r\n this.off(\"click.fb-start\").on(\r\n \"click.fb-start\", {\r\n items: this,\r\n options: options\r\n },\r\n _run\r\n );\r\n }\r\n\r\n return this;\r\n };\r\n\r\n // Self initializing plugin for all elements having `data-fancybox` attribute\r\n // ==========================================================================\r\n\r\n $D.on(\"click.fb-start\", \"[data-fancybox]\", _run);\r\n\r\n // Enable \"trigger elements\"\r\n // =========================\r\n\r\n $D.on(\"click.fb-start\", \"[data-fancybox-trigger]\", function (e) {\r\n $('[data-fancybox=\"' + $(this).attr(\"data-fancybox-trigger\") + '\"]')\r\n .eq($(this).attr(\"data-fancybox-index\") || 0)\r\n .trigger(\"click.fb-start\", {\r\n $trigger: $(this)\r\n });\r\n });\r\n\r\n // Track focus event for better accessibility styling\r\n // ==================================================\r\n (function () {\r\n var buttonStr = \".fancybox-button\",\r\n focusStr = \"fancybox-focus\",\r\n $pressed = null;\r\n\r\n $D.on(\"mousedown mouseup focus blur\", buttonStr, function (e) {\r\n switch (e.type) {\r\n case \"mousedown\":\r\n $pressed = $(this);\r\n break;\r\n case \"mouseup\":\r\n $pressed = null;\r\n break;\r\n case \"focusin\":\r\n $(buttonStr).removeClass(focusStr);\r\n\r\n if (!$(this).is($pressed) && !$(this).is(\"[disabled]\")) {\r\n $(this).addClass(focusStr);\r\n }\r\n break;\r\n case \"focusout\":\r\n $(buttonStr).removeClass(focusStr);\r\n break;\r\n }\r\n });\r\n })();\r\n})(window, document, jQuery);\n// ==========================================================================\r\n//\r\n// Media\r\n// Adds additional media type support\r\n//\r\n// ==========================================================================\r\n(function ($) {\r\n \"use strict\";\r\n\r\n // Object containing properties for each media type\r\n var defaults = {\r\n youtube: {\r\n matcher: /(youtube\\.com|youtu\\.be|youtube\\-nocookie\\.com)\\/(watch\\?(.*&)?v=|v\\/|u\\/|embed\\/?)?(videoseries\\?list=(.*)|[\\w-]{11}|\\?listType=(.*)&list=(.*))(.*)/i,\r\n params: {\r\n autoplay: 1,\r\n autohide: 1,\r\n fs: 1,\r\n rel: 0,\r\n hd: 1,\r\n wmode: \"transparent\",\r\n enablejsapi: 1,\r\n html5: 1\r\n },\r\n paramPlace: 8,\r\n type: \"iframe\",\r\n url: \"https://www.youtube-nocookie.com/embed/$4\",\r\n thumb: \"https://img.youtube.com/vi/$4/hqdefault.jpg\"\r\n },\r\n\r\n vimeo: {\r\n matcher: /^.+vimeo.com\\/(.*\\/)?([\\d]+)(.*)?/,\r\n params: {\r\n autoplay: 1,\r\n hd: 1,\r\n show_title: 1,\r\n show_byline: 1,\r\n show_portrait: 0,\r\n fullscreen: 1\r\n },\r\n paramPlace: 3,\r\n type: \"iframe\",\r\n url: \"//player.vimeo.com/video/$2\"\r\n },\r\n\r\n instagram: {\r\n matcher: /(instagr\\.am|instagram\\.com)\\/p\\/([a-zA-Z0-9_\\-]+)\\/?/i,\r\n type: \"image\",\r\n url: \"//$1/p/$2/media/?size=l\"\r\n },\r\n\r\n // Examples:\r\n // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16\r\n // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z\r\n // https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en\r\n // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572\r\n gmap_place: {\r\n matcher: /(maps\\.)?google\\.([a-z]{2,3}(\\.[a-z]{2})?)\\/(((maps\\/(place\\/(.*)\\/)?\\@(.*),(\\d+.?\\d+?)z))|(\\?ll=)
109)(.*)?/i,\r\n type: \"iframe\",\r\n url: function (rez) {\r\n return (\r\n \"//maps.google.\" +\r\n rez[2] +\r\n \"/?ll=\" +\r\n (rez[9] ? rez[9] + \"&z=\" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\\//, \"&\") : \"\") : rez[12] + \"\").replace(/\\?/, \"&\") +\r\n \"&output=\" +\r\n (rez[12] && rez[12].indexOf(\"layer=c\") > 0 ? \"svembed\" : \"embed\")\r\n );\r\n }\r\n },\r\n\r\n // Examples:\r\n // https://www.google.com/maps/search/Empire+State+Building/\r\n // https://www.google.com/maps/search/?api=1&query=centurylink+field\r\n // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393\r\n gmap_search: {\r\n matcher: /(maps\\.)?google\\.([a-z]{2,3}(\\.[a-z]{2})?)\\/(maps\\/search\\/)(.*)/i,\r\n type: \"iframe\",\r\n url: function (rez) {\r\n return \"//maps.google.\" + rez[2] + \"/maps?q=\" + rez[5].replace(\"query=\", \"q=\").replace(\"api=1\", \"\") + \"&output=embed\";\r\n }\r\n }\r\n };\r\n\r\n // Formats matching url to final form\r\n var format = function (url, rez, params) {\r\n if (!url) {\r\n return;\r\n }\r\n\r\n params = params || \"\";\r\n\r\n if ($.type(params) === \"object\") {\r\n params = $.param(params, true);\r\n }\r\n\r\n $.each(rez, function (key, value) {\r\n url = url.replace(\"$\" + key, value || \"\");\r\n });\r\n\r\n if (params.length) {\r\n url += (url.indexOf(\"?\") > 0 ? \"&\" : \"?\") + params;\r\n }\r\n\r\n return url;\r\n };\r\n\r\n $(document).on(\"objectNeedsType.fb\", function (e, instance, item) {\r\n var url = item.src || \"\",\r\n type = false,\r\n media,\r\n thumb,\r\n rez,\r\n params,\r\n urlParams,\r\n paramObj,\r\n provider;\r\n\r\n media = $.extend(true, {}, defaults, item.opts.media);\r\n\r\n // Look for any matching media type\r\n $.each(media, function (providerName, providerOpts) {\r\n rez = url.match(providerOpts.matcher);\r\n\r\n if (!rez) {\r\n return;\r\n }\r\n\r\n type = providerOpts.type;\r\n provider = providerName;\r\n paramObj = {};\r\n\r\n if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {\r\n urlParams = rez[providerOpts.paramPlace];\r\n\r\n if (urlParams[0] == \"?\") {\r\n urlParams = urlParams.substring(1);\r\n }\r\n\r\n urlParams = urlParams.split(\"&\");\r\n\r\n for (var m = 0; m < urlParams.length; ++m) {\r\n var p = urlParams[m].split(\"=\", 2);\r\n\r\n if (p.length == 2) {\r\n paramObj[p[0]] = decodeURIComponent(p[1].replace(/\\+/g, \" \"));\r\n }\r\n }\r\n }\r\n\r\n params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);\r\n\r\n url =\r\n $.type(providerOpts.url) === \"function\" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);\r\n\r\n thumb =\r\n $.type(providerOpts.thumb) === \"function\" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);\r\n\r\n if (providerName === \"youtube\") {\r\n url = url.replace(/&t=((\\d+)m)?(\\d+)s/, function (match, p1, m, s) {\r\n return \"&start=\" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));\r\n });\r\n } else if (providerName === \"vimeo\") {\r\n url = url.replace(\"&%23\", \"#\");\r\n }\r\n\r\n return false;\r\n });\r\n\r\n // If it is found, then change content type and update the url\r\n\r\n if (type) {\r\n if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {\r\n item.opts.thumb = thumb;\r\n }\r\n\r\n if (type === \"iframe\") {\r\n item.opts = $.extend(true, item.opts, {\r\n iframe: {\r\n preload: false,\r\n attr: {\r\n scrolling: \"no\"\r\n }\r\n }\r\n });\r\n }\r\n\r\n $.extend(item, {\r\n type: type,\r\n src: url,\r\n origSrc: item.src,\r\n contentSource: provider,\r\n contentType: type === \"image\" ? \"image\" : provider == \"gmap_place\" || provider == \"gmap_search\" ? \"map\" : \"video\"\r\n });\r\n } else if (url) {\r\n item.type = item.opts.defaultType;\r\n }\r\n });\r\n\r\n // Load YouTube/Video API on request to detect when video finished playing\r\n var VideoAPILoader = {\r\n youtube: {\r\n src: \"https://www.youtube.com/iframe_api\",\r\n class: \"YT\",\r\n loading: false,\r\n loaded: false\r\n },\r\n\r\n vimeo: {\r\n src: \"https://player.vimeo.com/api/player.js\",\r\n class: \"Vimeo\",\r\n loading: false,\r\n loaded: false\r\n },\r\n\r\n load: function (vendor) {\r\n var _this = this,\r\n script;\r\n\r\n if (this[vendor].loaded) {\r\n setTimeout(function () {\r\n _this.done(vendor);\r\n });\r\n return;\r\n }\r\n\r\n if (this[vendor].loading) {\r\n return;\r\n }\r\n\r\n this[vendor].loading = true;\r\n\r\n script = document.createElement(\"script\");\r\n script.type = \"text/javascript\";\r\n script.src = this[vendor].src;\r\n\r\n if (vendor === \"youtube\") {\r\n window.onYouTubeIframeAPIReady = function () {\r\n _this[vendor].loaded = true;\r\n _this.done(vendor);\r\n };\r\n } else {\r\n script.onload = function () {\r\n _this[vendor].loaded = true;\r\n _this.done(vendor);\r\n };\r\n }\r\n\r\n document.body.appendChild(script);\r\n },\r\n done: function (vendor) {\r\n var instance, $el, player;\r\n\r\n if (vendor === \"youtube\") {\r\n delete window.onYouTubeIframeAPIReady;\r\n }\r\n\r\n instance = $.fancybox.getInstance();\r\n\r\n if (instance) {\r\n $el = instance.current.$content.find(\"iframe\");\r\n\r\n if (vendor === \"youtube\" && YT !== undefined && YT) {\r\n player = new YT.Player($el.attr(\"id\"), {\r\n events: {\r\n onStateChange: function (e) {\r\n if (e.data == 0) {\r\n instance.next();\r\n }\r\n }\r\n }\r\n });\r\n } else if (vendor === \"vimeo\" && Vimeo !== undefined && Vimeo) {\r\n player = new Vimeo.Player($el);\r\n\r\n player.on(\"ended\", function () {\r\n instance.next();\r\n });\r\n }\r\n }\r\n }\r\n };\r\n\r\n $(document).on({\r\n \"afterShow.fb\": function (e, instance, current) {\r\n if (instance.group.length > 1 && (current.contentSource === \"youtube\" || current.contentSource === \"vimeo\")) {\r\n VideoAPILoader.load(current.contentSource);\r\n }\r\n }\r\n });\r\n})(jQuery);\n// ==========================================================================\r\n//\r\n// Guestures\r\n// Adds touch guestures, handles click and tap events\r\n//\r\n// ==========================================================================\r\n(function (window, document, $) {\r\n \"use strict\";\r\n\r\n var requestAFrame = (function () {\r\n return (\r\n window.requestAnimationFrame ||\r\n window.webkitRequestAnimationFrame ||\r\n window.mozRequestAnimationFrame ||\r\n window.oRequestAnimationFrame ||\r\n // if all else fails, use setTimeout\r\n function (callback) {\r\n return window.setTimeout(callback, 1000 / 60);\r\n }\r\n );\r\n })();\r\n\r\n var cancelAFrame = (function () {\r\n return (\r\n window.cancelAnimationFrame ||\r\n window.webkitCancelAnimationFrame ||\r\n window.mozCancelAnimationFrame ||\r\n window.oCancelAnimationFrame ||\r\n function (id) {\r\n window.clearTimeout(id);\r\n }\r\n );\r\n })();\r\n\r\n var getPointerXY = function (e) {\r\n var result = [];\r\n\r\n e = e.originalEvent || e || window.e;\r\n e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];\r\n\r\n for (var key in e) {\r\n if (e[key].pageX) {\r\n result.push({\r\n x: e[key].pageX,\r\n y: e[ke
109y].pageY\r\n });\r\n } else if (e[key].clientX) {\r\n result.push({\r\n x: e[key].clientX,\r\n y: e[key].clientY\r\n });\r\n }\r\n }\r\n\r\n return result;\r\n };\r\n\r\n var distance = function (point2, point1, what) {\r\n if (!point1 || !point2) {\r\n return 0;\r\n }\r\n\r\n if (what === \"x\") {\r\n return point2.x - point1.x;\r\n } else if (what === \"y\") {\r\n return point2.y - point1.y;\r\n }\r\n\r\n return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));\r\n };\r\n\r\n var isClickable = function ($el) {\r\n if (\r\n $el.is('a,area,button,[role=\"button\"],input,label,select,summary,textarea,video,audio,iframe') ||\r\n $.isFunction($el.get(0).onclick) ||\r\n $el.data(\"selectable\")\r\n ) {\r\n return true;\r\n }\r\n\r\n // Check for attributes like data-fancybox-next or data-fancybox-close\r\n for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {\r\n if (atts[i].nodeName.substr(0, 14) === \"data-fancybox-\") {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n\r\n var hasScrollbars = function (el) {\r\n var overflowY = window.getComputedStyle(el)[\"overflow-y\"],\r\n overflowX = window.getComputedStyle(el)[\"overflow-x\"],\r\n vertical = (overflowY === \"scroll\" || overflowY === \"auto\") && el.scrollHeight > el.clientHeight,\r\n horizontal = (overflowX === \"scroll\" || overflowX === \"auto\") && el.scrollWidth > el.clientWidth;\r\n\r\n return vertical || horizontal;\r\n };\r\n\r\n var isScrollable = function ($el) {\r\n var rez = false;\r\n\r\n while (true) {\r\n rez = hasScrollbars($el.get(0));\r\n\r\n if (rez) {\r\n break;\r\n }\r\n\r\n $el = $el.parent();\r\n\r\n if (!$el.length || $el.hasClass(\"fancybox-stage\") || $el.is(\"body\")) {\r\n break;\r\n }\r\n }\r\n\r\n return rez;\r\n };\r\n\r\n var Guestures = function (instance) {\r\n var self = this;\r\n\r\n self.instance = instance;\r\n\r\n self.$bg = instance.$refs.bg;\r\n self.$stage = instance.$refs.stage;\r\n self.$container = instance.$refs.container;\r\n\r\n self.destroy();\r\n\r\n self.$container.on(\"touchstart.fb.touch mousedown.fb.touch\", $.proxy(self, \"ontouchstart\"));\r\n };\r\n\r\n Guestures.prototype.destroy = function () {\r\n var self = this;\r\n\r\n self.$container.off(\".fb.touch\");\r\n\r\n $(document).off(\".fb.touch\");\r\n\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n self.requestId = null;\r\n }\r\n\r\n if (self.tapped) {\r\n clearTimeout(self.tapped);\r\n self.tapped = null;\r\n }\r\n };\r\n\r\n Guestures.prototype.ontouchstart = function (e) {\r\n var self = this,\r\n $target = $(e.target),\r\n instance = self.instance,\r\n current = instance.current,\r\n $slide = current.$slide,\r\n $content = current.$content,\r\n isTouchDevice = e.type == \"touchstart\";\r\n\r\n // Do not respond to both (touch and mouse) events\r\n if (isTouchDevice) {\r\n self.$container.off(\"mousedown.fb.touch\");\r\n }\r\n\r\n // Ignore right click\r\n if (e.originalEvent && e.originalEvent.button == 2) {\r\n return;\r\n }\r\n\r\n // Ignore taping on links, buttons, input elements\r\n if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {\r\n return;\r\n }\r\n // Ignore clicks on the scrollbar\r\n if (!$target.is(\"img\") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {\r\n return;\r\n }\r\n\r\n // Ignore clicks while zooming or closing\r\n if (!current || instance.isAnimating || current.$slide.hasClass(\"fancybox-animated\")) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n return;\r\n }\r\n\r\n self.realPoints = self.startPoints = getPointerXY(e);\r\n\r\n if (!self.startPoints.length) {\r\n return;\r\n }\r\n\r\n // Allow other scripts to catch touch event if \"touch\" is set to false\r\n if (current.touch) {\r\n e.stopPropagation();\r\n }\r\n\r\n self.startEvent = e;\r\n\r\n self.canTap = true;\r\n self.$target = $target;\r\n self.$content = $content;\r\n self.opts = current.opts.touch;\r\n\r\n self.isPanning = false;\r\n self.isSwiping = false;\r\n self.isZooming = false;\r\n self.isScrolling = false;\r\n self.canPan = instance.canPan();\r\n\r\n self.startTime = new Date().getTime();\r\n self.distanceX = self.distanceY = self.distance = 0;\r\n\r\n self.canvasWidth = Math.round($slide[0].clientWidth);\r\n self.canvasHeight = Math.round($slide[0].clientHeight);\r\n\r\n self.contentLastPos = null;\r\n self.contentStartPos = $.fancybox.getTranslate(self.$content) || {\r\n top: 0,\r\n left: 0\r\n };\r\n self.sliderStartPos = $.fancybox.getTranslate($slide);\r\n\r\n // Since position will be absolute, but we need to make it relative to the stage\r\n self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);\r\n\r\n self.sliderStartPos.top -= self.stagePos.top;\r\n self.sliderStartPos.left -= self.stagePos.left;\r\n\r\n self.contentStartPos.top -= self.stagePos.top;\r\n self.contentStartPos.left -= self.stagePos.left;\r\n\r\n $(document)\r\n .off(\".fb.touch\")\r\n .on(isTouchDevice ? \"touchend.fb.touch touchcancel.fb.touch\" : \"mouseup.fb.touch mouseleave.fb.touch\", $.proxy(self, \"ontouchend\"))\r\n .on(isTouchDevice ? \"touchmove.fb.touch\" : \"mousemove.fb.touch\", $.proxy(self, \"ontouchmove\"));\r\n\r\n if ($.fancybox.isMobile) {\r\n document.addEventListener(\"scroll\", self.onscroll, true);\r\n }\r\n\r\n // Skip if clicked outside the sliding area\r\n if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {\r\n if ($target.is(\".fancybox-image\")) {\r\n e.preventDefault();\r\n }\r\n\r\n if (!($.fancybox.isMobile && $target.parents(\".fancybox-caption\").length)) {\r\n return;\r\n }\r\n }\r\n\r\n self.isScrollable = isScrollable($target) || isScrollable($target.parent());\r\n\r\n // Check if element is scrollable and try to prevent default behavior (scrolling)\r\n if (!($.fancybox.isMobile && self.isScrollable)) {\r\n e.preventDefault();\r\n }\r\n\r\n // One finger or mouse click - swipe or pan an image\r\n if (self.startPoints.length === 1 || current.hasError) {\r\n if (self.canPan) {\r\n $.fancybox.stop(self.$content);\r\n\r\n self.isPanning = true;\r\n } else {\r\n self.isSwiping = true;\r\n }\r\n\r\n self.$container.addClass(\"fancybox-is-grabbing\");\r\n }\r\n\r\n // Two fingers - zoom image\r\n if (self.startPoints.length === 2 && current.type === \"image\" && (current.isLoaded || current.$ghost)) {\r\n self.canTap = false;\r\n self.isSwiping = false;\r\n self.isPanning = false;\r\n\r\n self.isZooming = true;\r\n\r\n $.fancybox.stop(self.$content);\r\n\r\n self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();\r\n self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();\r\n\r\n self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;\r\n self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;\r\n\r\n self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);\r\n }\r\n };\r\n\r\n Guestures.prototype.onscroll = function (e) {\r\n var self = this;\r\n\r\n self.isScrolling = true;\r\n\r\n document.removeEventListener(\"scroll\", self.onscroll, true);\r\n };\r\n\r\n Guestures.prototype.ontouchmove = function (e) {\r\n var self = this;\r\n\r\n // Make sure user has not released over iframe or disabled element\r\n if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {\r\n self.ontouchend(e);\r\n return;\r\n }\r\n\r\n if (self.isScrolling) {\r\n self.canTap = false;\r\n return;\r\n }\r\n\r\n self.newPoints = getPointerXY(e);\r\n\r\n if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {\r\n return;\r\n }\r\n\r\n if (!(self.isSwiping && self.isSwiping === true)) {\r\n e.preventDefault();\r\n }\r\n\r\n self.distanceX = distance(self.newPoints[0], self.startPoints[0], \"x\");\r\n self.distanceY = distance(self.newPoints[0], self.startPoints[0], \"y\");\r\n\r\n self.distance = distance(self.newPoints[0], self.startPoints[0]);\r\n\r\n // Skip false ontouchmove events (Chrome)\r\n if (self.distance > 0) {\r\n if (self.isSwiping) {\r\n self.onSwipe(e);\r\n } else if (self.isPanning) {\r\n self.onPan();\r\n } else if (self.isZooming) {\r\n self.onZoom();\r\n }\r\n }\r\n };\r\n\r\n Guestures.prototype.onSwipe = function (e) {\r\n var self = this,\r\n instance = self.instance,\r\n swiping = self.isSwiping,\r\n left = self.sliderStartPos.left || 0,\r\n angle;\r\n\r\n // If direction is not yet determined\r\n if (swiping === true) {\r\n // We need at least 10px distance to correctly calculate an angle\r\n if (Math.abs(self.distance) > 10) {\r\n self.canTap = false;\r\n\r\n if (instance.group.length < 2 && self.opts.vertical) {\r\n self.isSwiping = \"y\";\r\n } else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === \"auto\" && $(window).width() > 800)) {\r\n self.isSwiping = \"x\";\r\n } else {\r\n angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);\r\n\r\n self.isSwiping = angle > 45 && angle < 135 ? \"y\" : \"x\";\r\n }\r\n\r\n if (self.isSwiping === \"y\" && $.fancybox.isMobile && self.isScrollable) {\r\n self.isScrolling = true;\r\n\r\n return;\r\n }\r\n\r\n instance.isDragging = self.isSwiping;\r\n\r\n // Reset points to avoid jumping, because we dropped first swipes to calculate the angle\r\n self.startPoints = self.newPoints;\r\n\r\n $.each(instance.slides, function (index, slide) {\r\n var slidePos, stagePos;\r\n\r\n $.fancybox.stop(slide.$slide);\r\n\r\n slidePos = $.fancybox.getTranslate(slide.$slide);\r\n stagePos = $.fancybox.getTranslate(instance.$refs.stage);\r\n\r\n slide.$slide\r\n .css({\r\n transform: \"\",\r\n opacity: \"\",\r\n \"transition-duration\": \"\"\r\n })\r\n .removeClass(\"fancybox-animated\")\r\n .removeClass(function (index, className) {\r\n return (className.match(/(^|\\s)fancybox-fx-\\S+/g) || []).join(\" \");\r\n });\r\n\r\n if (slide.pos === instance.current.pos) {\r\n self.sliderStartPos.top = slidePos.top - stagePos.top;\r\n self.sliderStartPos.left = slidePos.left - stagePos.left;\r\n }\r\n\r\n $.fancybox.setTranslate(slide.$slide, {\r\n top: slidePos.top - stagePos.top,\r\n left: slidePos.left - stagePos.left\r\n });\r\n });\r\n\r\n // Stop slideshow\r\n if (instance.SlideShow && instance.SlideShow.isActive) {\r\n instance.SlideShow.stop();\r\n }\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Sticky edges\r\n if (swiping == \"x\") {\r\n if (\r\n self.distanceX > 0 &&\r\n (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))\r\n ) {\r\n left = left + Math.pow(self.distanceX, 0.8);\r\n } else if (\r\n self.distanceX < 0 &&\r\n (self.instance.group.length < 2 ||\r\n (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))\r\n ) {\r\n left = left - Math.pow(-self.distanceX, 0.8);\r\n } else {\r\n left = left + self.distanceX;\r\n }\r\n }\r\n\r\n self.sliderLastPos = {\r\n top: swiping == \"x\" ? 0 : self.sliderStartPos.top + self.distanceY,\r\n left: left\r\n };\r\n\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n\r\n self.requestId = null;\r\n }\r\n\r\n self.requestId = requestAFrame(function () {\r\n if (self.sliderLastPos) {\r\n $.each(self.instance.slides, function (index, slide) {\r\n var pos = slide.pos - self.instance.currPos;\r\n\r\n $.fancybox.setTranslate(slide.$slide, {\r\n top: self.sliderLastPos.top,\r\n left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter\r\n });\r\n });\r\n\r\n self.$container.addClass(\"fancybox-is-sliding\");\r\n }\r\n });\r\n };\r\n\r\n Guestures.prototype.onPan = function () {\r\n var self = this;\r\n\r\n // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)\r\n if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {\r\n self.startPoints = self.newPoints;\r\n return;\r\n }\r\n\r\n self.canTap = false;\r\n\r\n self.contentLastPos = self.limitMovement();\r\n\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n }\r\n\r\n self.requestId = requestAFrame(function () {\r\n $.fancybox.setTranslate(self.$content, self.contentLastPos);\r\n });\r\n };\r\n\r\n // Make panning sticky to the edges\r\n Guestures.prototype.limitMovement = function () {\r\n var self = this;\r\n\r\n var canvasWidth = self.canvasWidth;\r\n var canvasHeight = self.canvasHeight;\r\n\r\n var distanceX = self.distanceX;\r\n var distanceY = self.distanceY;\r\n\r\n var contentStartPos = self.contentStartPos;\r\n\r\n var currentOffsetX = contentStartPos.left;\r\n var currentOffsetY = contentStartPos.top;\r\n\r\n var currentWidth = contentStartPos.width;\r\n var currentHeight = contentStartPos.height;\r\n\r\n var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;\r\n\r\n if (currentWidth > canvasWidth) {\r\n newOffsetX = currentOffsetX + distanceX;\r\n } else {\r\n newOffsetX = currentOffsetX;\r\n }\r\n\r\n newOffsetY = currentOffsetY + distanceY;\r\n\r\n // Slow down proportionally to traveled distance\r\n minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);\r\n minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);\r\n\r\n maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);\r\n maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);\r\n\r\n // ->\r\n if (distanceX > 0 && newOffsetX > minTranslateX) {\r\n newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;\r\n }\r\n\r\n // <-\r\n if (distanceX < 0 && newOffsetX < maxTranslateX) {\r\n newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;\r\n }\r\n\r\n // \\/\r\n if (distanceY > 0 && newOffsetY > minTranslateY) {\r\n newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;\r\n }\r\n\r\n // /\\\r\n if (distanceY < 0 && newOffsetY < maxTranslateY) {\r\n newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;\r\n }\r\n\r\n return {\r\n top: newOffsetY,\r\n left: newOffsetX\r\n };\r\n };\r\n\r\n Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {\r\n var self = this;\r\n\r\n var canvasWidth = self.canvasWidth;\r\n var canvasHeight = self.canvasHeight;\r\n\r\n if (newWidth > canvasWidth) {\r\n
109 newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;\r\n newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;\r\n } else {\r\n // Center horizontally\r\n newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);\r\n }\r\n\r\n if (newHeight > canvasHeight) {\r\n newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;\r\n newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;\r\n } else {\r\n // Center vertically\r\n newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);\r\n }\r\n\r\n return {\r\n top: newOffsetY,\r\n left: newOffsetX\r\n };\r\n };\r\n\r\n Guestures.prototype.onZoom = function () {\r\n var self = this;\r\n\r\n // Calculate current distance between points to get pinch ratio and new width and height\r\n var contentStartPos = self.contentStartPos;\r\n\r\n var currentWidth = contentStartPos.width;\r\n var currentHeight = contentStartPos.height;\r\n\r\n var currentOffsetX = contentStartPos.left;\r\n var currentOffsetY = contentStartPos.top;\r\n\r\n var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);\r\n\r\n var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;\r\n\r\n var newWidth = Math.floor(currentWidth * pinchRatio);\r\n var newHeight = Math.floor(currentHeight * pinchRatio);\r\n\r\n // This is the translation due to pinch-zooming\r\n var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;\r\n var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;\r\n\r\n // Point between the two touches\r\n var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();\r\n var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();\r\n\r\n // And this is the translation due to translation of the centerpoint\r\n // between the two fingers\r\n var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;\r\n var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;\r\n\r\n // The new offset is the old/current one plus the total translation\r\n var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);\r\n var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);\r\n\r\n var newPos = {\r\n top: newOffsetY,\r\n left: newOffsetX,\r\n scaleX: pinchRatio,\r\n scaleY: pinchRatio\r\n };\r\n\r\n self.canTap = false;\r\n\r\n self.newWidth = newWidth;\r\n self.newHeight = newHeight;\r\n\r\n self.contentLastPos = newPos;\r\n\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n }\r\n\r\n self.requestId = requestAFrame(function () {\r\n $.fancybox.setTranslate(self.$content, self.contentLastPos);\r\n });\r\n };\r\n\r\n Guestures.prototype.ontouchend = function (e) {\r\n var self = this;\r\n\r\n var swiping = self.isSwiping;\r\n var panning = self.isPanning;\r\n var zooming = self.isZooming;\r\n var scrolling = self.isScrolling;\r\n\r\n self.endPoints = getPointerXY(e);\r\n self.dMs = Math.max(new Date().getTime() - self.startTime, 1);\r\n\r\n self.$container.removeClass(\"fancybox-is-grabbing\");\r\n\r\n $(document).off(\".fb.touch\");\r\n\r\n document.removeEventListener(\"scroll\", self.onscroll, true);\r\n\r\n if (self.requestId) {\r\n cancelAFrame(self.requestId);\r\n\r\n self.requestId = null;\r\n }\r\n\r\n self.isSwiping = false;\r\n self.isPanning = false;\r\n self.isZooming = false;\r\n self.isScrolling = false;\r\n\r\n self.instance.isDragging = false;\r\n\r\n if (self.canTap) {\r\n return self.onTap(e);\r\n }\r\n\r\n self.speed = 100;\r\n\r\n // Speed in px/ms\r\n self.velocityX = (self.distanceX / self.dMs) * 0.5;\r\n self.velocityY = (self.distanceY / self.dMs) * 0.5;\r\n\r\n if (panning) {\r\n self.endPanning();\r\n } else if (zooming) {\r\n self.endZooming();\r\n } else {\r\n self.endSwiping(swiping, scrolling);\r\n }\r\n\r\n return;\r\n };\r\n\r\n Guestures.prototype.endSwiping = function (swiping, scrolling) {\r\n var self = this,\r\n ret = false,\r\n len = self.instance.group.length,\r\n distanceX = Math.abs(self.distanceX),\r\n canAdvance = swiping == \"x\" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),\r\n speedX = 300;\r\n\r\n self.sliderLastPos = null;\r\n\r\n // Close if swiped vertically / navigate if horizontally\r\n if (swiping == \"y\" && !scrolling && Math.abs(self.distanceY) > 50) {\r\n // Continue vertical movement\r\n $.fancybox.animate(\r\n self.instance.current.$slide, {\r\n top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,\r\n opacity: 0\r\n },\r\n 200\r\n );\r\n ret = self.instance.close(true, 250);\r\n } else if (canAdvance && self.distanceX > 0) {\r\n ret = self.instance.previous(speedX);\r\n } else if (canAdvance && self.distanceX < 0) {\r\n ret = self.instance.next(speedX);\r\n }\r\n\r\n if (ret === false && (swiping == \"x\" || swiping == \"y\")) {\r\n self.instance.centerSlide(200);\r\n }\r\n\r\n self.$container.removeClass(\"fancybox-is-sliding\");\r\n };\r\n\r\n // Limit panning from edges\r\n // ========================\r\n Guestures.prototype.endPanning = function () {\r\n var self = this,\r\n newOffsetX,\r\n newOffsetY,\r\n newPos;\r\n\r\n if (!self.contentLastPos) {\r\n return;\r\n }\r\n\r\n if (self.opts.momentum === false || self.dMs > 350) {\r\n newOffsetX = self.contentLastPos.left;\r\n newOffsetY = self.contentLastPos.top;\r\n } else {\r\n // Continue movement\r\n newOffsetX = self.contentLastPos.left + self.velocityX * 500;\r\n newOffsetY = self.contentLastPos.top + self.velocityY * 500;\r\n }\r\n\r\n newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);\r\n\r\n newPos.width = self.contentStartPos.width;\r\n newPos.height = self.contentStartPos.height;\r\n\r\n $.fancybox.animate(self.$content, newPos, 366);\r\n };\r\n\r\n Guestures.prototype.endZooming = function () {\r\n var self = this;\r\n\r\n var current = self.instance.current;\r\n\r\n var newOffsetX, newOffsetY, newPos, reset;\r\n\r\n var newWidth = self.newWidth;\r\n var newHeight = self.newHeight;\r\n\r\n if (!self.contentLastPos) {\r\n return;\r\n }\r\n\r\n newOffsetX = self.contentLastPos.left;\r\n newOffsetY = self.contentLastPos.top;\r\n\r\n reset = {\r\n top: newOffsetY,\r\n left: newOffsetX,\r\n width: newWidth,\r\n height: newHeight,\r\n scaleX: 1,\r\n scaleY: 1\r\n };\r\n\r\n // Reset scalex/scaleY values; this helps for perfomance and does not break animation\r\n $.fancybox.setTranslate(self.$content, reset);\r\n\r\n if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {\r\n self.instance.scaleToFit(150);\r\n } else if (newWidth > current.width || newHeight > current.height) {\r\n self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);\r\n } else {\r\n newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);\r\n\r\n $.fancybox.animate(self.$content, newPos, 150);\r\n }\r\n };\r\n\r\n Guestures.prototype.onTap = function (e) {\r\n var self = this;\r\n var $target = $(e.target);\r\n\r\n var instance = self.instance;\r\n var current = instance.current;\r\n\r\n var endPoints = (e && getPointerXY(e)) || self.startPoints;
109\r\n\r\n var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;\r\n var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;\r\n\r\n var where;\r\n\r\n var process = function (prefix) {\r\n var action = current.opts[prefix];\r\n\r\n if ($.isFunction(action)) {\r\n action = action.apply(instance, [current, e]);\r\n }\r\n\r\n if (!action) {\r\n return;\r\n }\r\n\r\n switch (action) {\r\n case \"close\":\r\n instance.close(self.startEvent);\r\n\r\n break;\r\n\r\n case \"toggleControls\":\r\n instance.toggleControls();\r\n\r\n break;\r\n\r\n case \"next\":\r\n instance.next();\r\n\r\n break;\r\n\r\n case \"nextOrClose\":\r\n if (instance.group.length > 1) {\r\n instance.next();\r\n } else {\r\n instance.close(self.startEvent);\r\n }\r\n\r\n break;\r\n\r\n case \"zoom\":\r\n if (current.type == \"image\" && (current.isLoaded || current.$ghost)) {\r\n if (instance.canPan()) {\r\n instance.scaleToFit();\r\n } else if (instance.isScaledDown()) {\r\n instance.scaleToActual(tapX, tapY);\r\n } else if (instance.group.length < 2) {\r\n instance.close(self.startEvent);\r\n }\r\n }\r\n\r\n break;\r\n }\r\n };\r\n\r\n // Ignore right click\r\n if (e.originalEvent && e.originalEvent.button == 2) {\r\n return;\r\n }\r\n\r\n // Skip if clicked on the scrollbar\r\n if (!$target.is(\"img\") && tapX > $target[0].clientWidth + $target.offset().left) {\r\n return;\r\n }\r\n\r\n // Check where is clicked\r\n if ($target.is(\".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container\")) {\r\n where = \"Outside\";\r\n } else if ($target.is(\".fancybox-slide\")) {\r\n where = \"Slide\";\r\n } else if (\r\n instance.current.$content &&\r\n instance.current.$content\r\n .find($target)\r\n .addBack()\r\n .filter($target).length\r\n ) {\r\n where = \"Content\";\r\n } else {\r\n return;\r\n }\r\n\r\n // Check if this is a double tap\r\n if (self.tapped) {\r\n // Stop previously created single tap\r\n clearTimeout(self.tapped);\r\n self.tapped = null;\r\n\r\n // Skip if distance between taps is too big\r\n if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {\r\n return this;\r\n }\r\n\r\n // OK, now we assume that this is a double-tap\r\n process(\"dblclick\" + where);\r\n } else {\r\n // Single tap will be processed if user has not clicked second time within 300ms\r\n // or there is no need to wait for double-tap\r\n self.tapX = tapX;\r\n self.tapY = tapY;\r\n\r\n if (current.opts[\"dblclick\" + where] && current.opts[\"dblclick\" + where] !== current.opts[\"click\" + where]) {\r\n self.tapped = setTimeout(function () {\r\n self.tapped = null;\r\n\r\n if (!instance.isAnimating) {\r\n process(\"click\" + where);\r\n }\r\n }, 500);\r\n } else {\r\n process(\"click\" + where);\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n $(document)\r\n .on(\"onActivate.fb\", function (e, instance) {\r\n if (instance && !instance.Guestures) {\r\n instance.Guestures = new Guestures(instance);\r\n }\r\n })\r\n .on(\"beforeClose.fb\", function (e, instance) {\r\n if (instance && instance.Guestures) {\r\n instance.Guestures.destroy();\r\n }\r\n });\r\n})(window, document, jQuery);\n// ==========================================================================\r\n//\r\n// SlideShow\r\n// Enables slideshow functionality\r\n//\r\n// Example of usage:\r\n// $.fancybox.getInstance().SlideShow.start()\r\n//\r\n// ==========================================================================\r\n(function (document, $) {\r\n \"use strict\";\r\n\r\n $.extend(true, $.fancybox.defaults, {\r\n btnTpl: {\r\n slideShow: '<button data-fancybox-play class=\"fancybox-button fancybox-button--play\" title=\"{{PLAY_START}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M6.5 5.4v13.2l11-6.6z\"/></svg>
109' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z\"/></svg>' +\r\n \"</button>\"\r\n },\r\n slideShow: {\r\n autoStart: false,\r\n speed: 3000,\r\n progress: true\r\n }\r\n });\r\n\r\n var SlideShow = function (instance) {\r\n this.instance = instance;\r\n this.init();\r\n };\r\n\r\n $.extend(SlideShow.prototype, {\r\n timer: null,\r\n isActive: false,\r\n $button: null,\r\n\r\n init: function () {\r\n var self = this,\r\n instance = self.instance,\r\n opts = instance.group[instance.currIndex].opts.slideShow;\r\n\r\n self.$button = instance.$refs.toolbar.find(\"[data-fancybox-play]\").on(\"click\", function () {\r\n self.toggle();\r\n });\r\n\r\n if (instance.group.length < 2 || !opts) {\r\n self.$button.hide();\r\n } else if (opts.progress) {\r\n self.$progress = $('<div class=\"fancybox-progress\"></div>').appendTo(instance.$refs.inner);\r\n }\r\n },\r\n\r\n set: function (force) {\r\n var self = this,\r\n instance = self.instance,\r\n current = instance.current;\r\n\r\n // Check if reached last element\r\n if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {\r\n if (self.isActive && current.contentType !== \"video\") {\r\n if (self.$progress) {\r\n $.fancybox.animate(self.$progress.show(), {\r\n scaleX: 1\r\n }, current.opts.slideShow.speed);\r\n }\r\n\r\n self.timer = setTimeout(function () {\r\n if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {\r\n instance.jumpTo(0);\r\n } else {\r\n instance.next();\r\n }\r\n }, current.opts.slideShow.speed);\r\n }\r\n } else {\r\n self.stop();\r\n instance.idleSecondsCounter = 0;\r\n instance.showControls();\r\n }\r\n },\r\n\r\n clear: function () {\r\n var self = this;\r\n\r\n clearTimeout(self.timer);\r\n\r\n self.timer = null;\r\n\r\n if (self.$progress) {\r\n self.$progress.removeAttr(\"style\").hide();\r\n }\r\n },\r\n\r\n start: function () {\r\n var self = this,\r\n current = self.instance.current;\r\n\r\n if (current) {\r\n self.$button\r\n .attr(\"title\", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP)\r\n .removeClass(\"fancybox-button--play\")\r\n .addClass(\"fancybox-button--pause\");\r\n\r\n self.isActive = true;\r\n\r\n if (current.isComplete) {\r\n self.set(true);\r\n }\r\n\r\n self.instance.trigger(\"onSlideShowChange\", true);\r\n }\r\n },\r\n\r\n stop: function () {\r\n var self = this,\r\n current = self.instance.current;\r\n\r\n self.clear();\r\n\r\n self.$button\r\n .attr(\"title\", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START)\r\n .removeClass(\"fancybox-button--pause\")\r\n .addClass(\"fancybox-button--play\");\r\n\r\n self.isActive = false;\r\n\r\n self.instance.trigger(\"onSlideShowChange\", false);\r\n\r\n if (self.$progress) {\r\n self.$progress.removeAttr(\"style\").hide();\r\n }\r\n },\r\n\r\n toggle: function () {\r\n var self = this;\r\n\r\n if (self.isActive) {\r\n self.stop();\r\n } else {\r\n self.start();\r\n }\r\n }\r\n });\r\n\r\n $(document).on({\r\n \"onInit.fb\": function (e, instance) {\r\n if (instance && !instance.SlideShow) {\r\n instance.SlideShow = new SlideShow(instance);\r\n }\r\n },\r\n\r\n \"beforeShow.fb\": function (e, instance, current, firstRun) {\r\n var SlideShow = instance && instance.SlideShow;\r\n\r\n if (firstRun) {\r\n if (SlideShow && current.opts.slideShow.autoStart) {\r\n SlideShow.start();\r\n }\r\n } else if (SlideShow && SlideShow.isActive) {\r\n SlideShow.clear();\r\n }\r\n },\r\n\r\n \"afterShow.fb\": function (e, instance, current) {\r\n var SlideShow = instance && instance.SlideShow;\r\n\r\n if (SlideShow && SlideShow.isActive) {\r\n SlideShow.set();\r\n }\r\n },\r\n\r\n \"afterKeydown.fb\": function (e, instance, current, keypress, keycode) {\r\n var SlideShow = instance && instance.SlideShow;\r\n\r\n // \"P\" or Spacebar\r\n if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is(\"button,a,input\")) {\r\n keypress.preventDefault();\r\n\r\n SlideShow.toggle();\r\n }\r\n },\r\n\r\n \"beforeClose.fb onDeactivate.fb\": function (e, instance) {\r\n var SlideShow = instance && instance.SlideShow;\r\n\r\n if (SlideShow) {\r\n SlideShow.stop();\r\n }\r\n }\r\n });\r\n\r\n // Page Visibility API to pause slideshow when window is not active\r\n $(document).on(\"visibilitychange\", function () {\r\n var instance = $.fancybox.getInstance(),\r\n SlideShow = instance && instance.SlideShow;\r\n\r\n if (SlideShow && SlideShow.isActive) {\r\n if (document.hidden) {\r\n SlideShow.clear();\r\n } else {\r\n SlideShow.set();\r\n }\r\n }\r\n });\r\n})(document, jQuery);\n// ==========================================================================\r\n//\r\n// FullScreen\r\n// Adds fullscreen functionality\r\n//\r\n// ==========================================================================\r\n(function (document, $) {\r\n \"use strict\";\r\n\r\n // Collection of methods supported by user browser\r\n var fn = (function () {\r\n var fnMap = [\r\n [\"requestFullscreen\", \"exitFullscreen\", \"fullscreenElement\", \"fullscreenEnabled\", \"fullscreenchange\", \"fullscreenerror\"],\r\n // new WebKit\r\n [\r\n \"webkitRequestFullscreen\",\r\n \"webkitExitFullscreen\",\r\n \"webkitFullscreenElement\",\r\n \"webkitFullscreenEnabled\",\r\n \"webkitfullscreenchange\",\r\n \"webkitfullscreenerror\"\r\n ],\r\n // old WebKit (Safari 5.1)\r\n [\r\n \"webkitRequestFullScreen\",\r\n \"webkitCancelFullScreen\",\r\n \"webkitCurrentFullScreenElement\",\r\n \"webkitCancelFullScreen\",\r\n \"webkitfullscreenchange\",\r\n \"webkitfullscreenerror\"\r\n ],\r\n [\r\n \"mozRequestFullScreen\",\r\n \"mozCancelFullScreen\",\r\n \"mozFullScreenElement\",\r\n \"mozFullScreenEnabled\",\r\n \"mozfullscreenchange\",\r\n \"mozfullscreenerror\"\r\n ],\r\n [\"msRequestFullscreen\", \"msExitFullscreen\", \"msFullscreenElement\", \"msFullscreenEnabled\", \"MSFullscreenChange\", \"MSFullscreenError\"]\r\n ];\r\n\r\n var ret = {};\r\n\r\n for (var i = 0; i < fnMap.length; i++) {\r\n var val = fnMap[i];\r\n\r\n if (val && val[1] in document) {\r\n for (var j = 0; j < val.length; j++) {\r\n ret[fnMap[0][j]] = val[j];\r\n }\r\n\r\n return ret;\r\n }\r\n }\r\n\r\n return false;\r\n })();\r\n\r\n if (fn) {\r\n var FullScreen = {\r\n request: function (elem) {\r\n elem = elem || document.documentElement;\r\n\r\n elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);\r\n },\r\n exit: function () {\r\n document[fn.exitFullscreen]();\r\n },\r\n toggle: function (elem) {\r\n elem = elem || document.documentElement;\r\n\r\n if (this.isFullscreen()) {\r\n this.exit();\r\n } else {\r\n this.request(elem);\r\n }\r\n },\r\n isFullscreen: function () {\r\n return Boolean(document[fn.fullscreenElement]);\r\n },\r\n enabled: function () {\r\n return Boolean(document[fn.fullscreenEnabled]);\r\n }\r\n };\r\n\r\n $.extend(true, $.fancybox.defaults, {\r\n btnTpl: {\r\n fullScreen: '<button data-fancybox-fullscreen class=\"fancybox-button fancybox-button--fsenter\" title=\"{{FULL_SCREEN}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/></svg>
109' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z\"/></svg>' +\r\n \"</button>\"\r\n },\r\n fullScreen: {\r\n autoStart: false\r\n }\r\n });\r\n\r\n $(document).on(fn.fullscreenchange, function () {\r\n var isFullscreen = FullScreen.isFullscreen(),\r\n instance = $.fancybox.getInstance();\r\n\r\n if (instance) {\r\n // If image is zooming, then force to stop and reposition properly\r\n if (instance.current && instance.current.type === \"image\" && instance.isAnimating) {\r\n instance.isAnimating = false;\r\n\r\n instance.update(true, true, 0);\r\n\r\n if (!instance.isComplete) {\r\n instance.complete();\r\n }\r\n }\r\n\r\n instance.trigger(\"onFullscreenChange\", isFullscreen);\r\n\r\n instance.$refs.container.toggleClass(\"fancybox-is-fullscreen\", isFullscreen);\r\n\r\n instance.$refs.toolbar\r\n .find(\"[data-fancybox-fullscreen]\")\r\n .toggleClass(\"fancybox-button--fsenter\", !isFullscreen)\r\n .toggleClass(\"fancybox-button--fsexit\", isFullscreen);\r\n }\r\n });\r\n }\r\n\r\n $(document).on({\r\n \"onInit.fb\": function (e, instance) {\r\n var $container;\r\n\r\n if (!fn) {\r\n instance.$refs.toolbar.find(\"[data-fancybox-fullscreen]\").remove();\r\n\r\n return;\r\n }\r\n\r\n if (instance && instance.group[instance.currIndex].opts.fullScreen) {\r\n $container = instance.$refs.container;\r\n\r\n $container.on(\"click.fb-fullscreen\", \"[data-fancybox-fullscreen]\", function (e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n\r\n FullScreen.toggle();\r\n });\r\n\r\n if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {\r\n FullScreen.request();\r\n }\r\n\r\n // Expose API\r\n instance.FullScreen = FullScreen;\r\n } else if (instance) {\r\n instance.$refs.toolbar.find(\"[data-fancybox-fullscreen]\").hide();\r\n }\r\n },\r\n\r\n \"afterKeydown.fb\": function (e, instance, current, keypress, keycode) {\r\n // \"F\"\r\n if (instance && instance.FullScreen && keycode === 70) {\r\n keypress.preventDefault();\r\n\r\n instance.FullScreen.toggle();\r\n }\r\n },\r\n\r\n \"beforeClose.fb\": function (e, instance) {\r\n if (instance && instance.FullScreen && instance.$refs.container.hasClass(\"fancybox-is-fullscreen\")) {\r\n FullScreen.exit();\r\n }\r\n }\r\n });\r\n})(document, jQuery);\n// ==========================================================================\r\n//\r\n// Thumbs\r\n// Displays thumbnails in a grid\r\n//\r\n// ==========================================================================\r\n(function (document, $) {\r\n \"use strict\";\r\n\r\n var CLASS = \"fancybox-thumbs\",\r\n CLASS_ACTIVE = CLASS + \"-active\";\r\n\r\n // Make sure there are default values\r\n $.fancybox.defaults = $.extend(\r\n true, {\r\n btnTpl: {\r\n thumbs: '<button data-fancybox-thumbs class=\"fancybox-button fancybox-button--thumbs\" title=\"{{THUMBS}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z\"/></svg>' +\r\n \"</button>\"\r\n },\r\n thumbs: {\r\n autoStart: false, // Display thumbnails on opening\r\n hideOnClose: true, // Hide thumbnail grid when closing animation starts\r\n parentEl: \".fancybox-container\", // Container is injected into this element\r\n axis: \"y\" // Vertical (y) or horizontal (x) scrolling\r\n }\r\n },\r\n $.fancybox.defaults\r\n );\r\n\r\n var FancyThumbs = function (instance) {\r\n this.init(instance);\r\n };\r\n\r\n $.extend(FancyThumbs.prototype, {\r\n $button: null,\r\n $grid: null,\r\n $list: null,\r\n isVisible: false,\r\n isActive: false,\r\n\r\n init: function (instance) {\r\n var self = this,\r\n group = instance.group,\r\n enabled = 0;\r\n\r\n self.instance = instance;\r\n self.opts = group[instance.currIndex].opts.thumbs;\r\n\r\n instance.Thumbs = self;\r\n\r\n self.$button = instance.$refs.toolbar.find(\"[data-fancybox-thumbs]\");\r\n\r\n // Enable thumbs if at least two group items have thumbnails\r\n for (var i = 0, len = group.length; i < len; i++) {\r\n if (group[i].thumb) {\r\n enabled++;\r\n }\r\n\r\n if (enabled > 1) {\r\n break;\r\n }\r\n }\r\n\r\n if (enabled > 1 && !!self.opts) {\r\n self.$button.removeAttr(\"style\").on(\"click\", function () {\r\n self.toggle(
109);\r\n });\r\n\r\n self.isActive = true;\r\n } else {\r\n self.$button.hide();\r\n }\r\n },\r\n\r\n create: function () {\r\n var self = this,\r\n instance = self.instance,\r\n parentEl = self.opts.parentEl,\r\n list = [],\r\n src;\r\n\r\n if (!self.$grid) {\r\n // Create main element\r\n self.$grid = $('<div class=\"' + CLASS + \" \" + CLASS + \"-\" + self.opts.axis + '\"></div>').appendTo(\r\n instance.$refs.container\r\n .find(parentEl)\r\n .addBack()\r\n .filter(parentEl)\r\n );\r\n\r\n // Add \"click\" event that performs gallery navigation\r\n self.$grid.on(\"click\", \"a\", function () {\r\n instance.jumpTo($(this).attr(\"data-index\"));\r\n });\r\n }\r\n\r\n // Build the list\r\n if (!self.$list) {\r\n self.$list = $('<div class=\"' + CLASS + '__list\">').appendTo(self.$grid);\r\n }\r\n\r\n $.each(instance.group, function (i, item) {\r\n src = item.thumb;\r\n\r\n if (!src && item.type === \"image\") {\r\n src = item.src;\r\n }\r\n\r\n list.push(\r\n '<a href=\"javascript:;\" tabindex=\"0\" data-index=\"' +\r\n i +\r\n '\"' +\r\n (src && src.length ? ' style=\"background-image:url(' + src + ')\"' : 'class=\"fancybox-thumbs-missing\"') +\r\n \"></a>\"\r\n );\r\n });\r\n\r\n self.$list[0].innerHTML = list.join(\"\");\r\n\r\n if (self.opts.axis === \"x\") {\r\n // Set fixed width for list element to enable horizontal scrolling\r\n self.$list.width(\r\n parseInt(self.$grid.css(\"padding-right\"), 10) +\r\n instance.group.length *\r\n self.$list\r\n .children()\r\n .eq(0)\r\n .outerWidth(true)\r\n );\r\n }\r\n },\r\n\r\n focus: function (duration) {\r\n var self = this,\r\n $list = self.$list,\r\n $grid = self.$grid,\r\n thumb,\r\n thumbPos;\r\n\r\n if (!self.instance.current) {\r\n return;\r\n }\r\n\r\n thumb = $list\r\n .children()\r\n .removeClass(CLASS_ACTIVE)\r\n .filter('[data-index=\"' + self.instance.current.index + '\"]')\r\n .addClass(CLASS_ACTIVE);\r\n\r\n thumbPos = thumb.position();\r\n\r\n // Check if need to scroll to make current thumb visible\r\n if (self.opts.axis === \"y\" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {\r\n $list.stop().animate({\r\n scrollTop: $list.scrollTop() + thumbPos.top\r\n },\r\n duration\r\n );\r\n } else if (\r\n self.opts.axis === \"x\" &&\r\n (thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))\r\n ) {\r\n $list\r\n .parent()\r\n .stop()\r\n .animate({\r\n scrollLeft: thumbPos.left\r\n },\r\n duration\r\n );\r\n }\r\n },\r\n\r\n update: function () {\r\n var that = this;\r\n that.instance.$refs.container.toggleClass(\"fancybox-show-thumbs\", this.isVisible);\r\n\r\n if (that.isVisible) {\r\n if (!that.$grid) {\r\n that.create();\r\n }\r\n\r\n that.instance.trigger(\"onThumbsShow\");\r\n\r\n that.focus(0);\r\n } else if (that.$grid) {\r\n that.instance.trigger(\"onThumbsHide\");\r\n }\r\n\r\n // Update content position\r\n that.instance.update();\r\n },\r\n\r\n hide: function () {\r\n this.isVisible = false;\r\n this.update();\r\n },\r\n\r\n show: function () {\r\n this.isVisible = true;\r\n this.update();\r\n },\r\n\r\n toggle: function () {\r\n this.isVisible = !this.isVisible;\r\n this.update();\r\n }\r\n });\r\n\r\n $(document).on({\r\n \"onInit.fb\": function (e, instance) {\r\n var Thumbs;\r\n\r\n if (instance && !instance.Thumbs) {\r\n Thumbs = new FancyThumbs(instance);\r\n\r\n if (Thumbs.isActive && Thumbs.opts.autoStart === true) {\r\n Thumbs.show();\r\n }\r\n }\r\n },\r\n\r\n \"beforeShow.fb\": function (e, instance, item, firstRun) {\r\n var Thumbs = instance && instance.Thumbs;\r\n\r\n if (Thumbs && Thumbs.isVisible) {\r\n Thumbs.focus(firstRun ? 0 : 250);\r\n }\r\n },\r\n\r\n \"afterKeydown.fb\": function (e, instance, current, keypress, keycode) {\r\n var Thumbs = instance && instance.Thumbs;\r\n\r\n // \"G\"\r\n if (Thumbs && Thumbs.isActive && keycode === 71) {\r\n keypress.preventDefault();\r\n\r\n Thumbs.toggle();\r\n }\r\n },\r\n\r\n \"beforeClose.fb\": function (e, instance) {\r\n var Thumbs = instance && instance.Thumbs;\r\n\r\n if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {\r\n Thumbs.$grid.hide();\r\n }\r\n }\r\n });\r\n})(document, jQuery);\n//// ==========================================================================\r\n//\r\n// Share\r\n// Displays simple form for sharing current url\r\n//\r\n// ==========================================================================\r\n(function (document, $) {\r\n \"use strict\";\r\n\r\n $.extend(true, $.fancybox.defaults, {\r\n btnTpl: {\r\n share: '<button data-fancybox-share class=\"fancybox-button fancybox-button--share\" title=\"{{SHARE}}\">' +\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z\"/></svg>
109' +\r\n \"</button>\"\r\n },\r\n share: {\r\n url: function (instance, item) {\r\n return (\r\n (!instance.currentHash && !(item.type === \"inline\" || item.type === \"html\") ? item.origSrc || item.src : false) || window.location\r\n );\r\n },\r\n tpl: '<div class=\"fancybox-share\">' +\r\n \"<h1>{{SHARE}}</h1>\" +\r\n \"<p>\" +\r\n '<a class=\"fancybox-share__button fancybox-share__button--fb\" href=\"https://www.facebook.com/sharer/sharer.php?u={{url}}\">' +\r\n '<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196\" /></svg>' +\r\n \"<span>Facebook</span>\" +\r\n \"</a>\" +\r\n '<a class=\"fancybox-share__button fancybox-share__button--tw\" href=\"https://twitter.com/intent/tweet?url={{url}}&text={{descr}}\">' +\r\n '<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z\" /></svg>' +\r\n \"<span>Twitter</span>\" +\r\n \"</a>\" +\r\n '<a class=\"fancybox-share__button fancybox-share__button--pt\" href=\"https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}\">' +\r\n '<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z\" fill=\"#fff\"/></svg>' +\r\n \"<span>Pinterest</span>\" +\r\n \"</a>\" +\r\n \"</p>\" +\r\n '<p><input class=\"fancybox-share__input\" type=\"text\" value=\"{{url_raw}}\" onclick=\"select()\" /></p>' +\r\n \"</div>\"\r\n }\r\n });\r\n\r\n function escapeHtml(string) {\r\n var entityMap = {\r\n \"&\": \"&\",\r\n \"<\": \"<\",\r\n \">\": \">\",\r\n '\"': \""\",\r\n \"'\": \"'\",\r\n \"/\": \"/\",\r\n \"`\": \"`\",\r\n \"=\": \"=\"\r\n };\r\n\r\n return String(string).replace(/[&<>\"'`=\\/]/g, function (s) {\r\n return entityMap[s];\r\n });\r\n }\r\n\r\n $(document).on(\"click\", \"[data-fancybox-share]\", function () {\r\n var instance = $.fancybox.getInstance(),\r\n current = instance.current || null,\r\n url,\r\n tpl;\r\n\r\n if (!current) {\r\n return;\r\n }\r\n\r\n if ($.type(current.opts.share.url) === \"function\") {\r\n url = current.opts.share.url.apply(current, [instance, current]);\r\n }\r\n\r\n tpl = current.opts.share.tpl\r\n .replace(/\\{\\{media\\}\\}/g, current.type === \"image\" ? encodeURIComponent(current.src) : \"\")\r\n .replace(/\\{\\{url\\}\\}/g, encodeURIComponent(url))\r\n .replace(/\\{\\{url_raw\\}\\}/g, escapeHtml(url))\r\n .replace(/\\{\\{descr\\}\\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : \"\");\r\n\r\n $.fancybox.open({\r\n src: instance.translate(instance, tpl),\r\n type: \"html\",\r\n opts: {\r\n touch: false,\r\n animationEffect: false,\r\n afterLoad: function (shareInstance, shareCurrent) {\r\n // Close self if parent instance is closing\r\n instance.$refs.container.one(\"beforeClose.fb\", function () {\r\n shareInstance.close(null, 0);\r\n });\r\n\r\n // Opening links in a popup window\r\n shareCurrent.$content.find(\".fancybox-share__button\").click(function () {\r\n window.open(this.href, \"Share\", \"width=550, height=450\");\r\n return false;\r\n });\r\n },\r\n mobile: {\r\n autoFocus: false\r\n }\r\n }\r\n });\r\n });\r\n})(document, jQuery);\n// ==========================================================================\r\n//\r\n// Hash\r\n// Enables linking to each modal\r\n//\r\n// ==========================================================================\r\n(function (window, document, $) {\r\n \"use strict\";\r\n\r\n // Simple $.escapeSelector polyfill (for jQuery prior v3)\r\n if (!$.escapeSelector) {\r\n $.escapeSelector = function (sel) {\r\n var rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g;\r\n var fcssescape = function (ch, asCodePoint) {\r\n if (asCodePoint) {\r\n // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\r\n if (ch === \"\\0\") {\r\n return \"\\uFFFD\";\r\n }\r\n\r\n // Control characters and (dependent upon position) numbers get escaped as code points\r\n return ch.slice(0, -1) + \"\\\\\" + ch.charCo
109deAt(ch.length - 1).toString(16) + \" \";\r\n }\r\n\r\n // Other potentially-special ASCII characters get backslash-escaped\r\n return \"\\\\\" + ch;\r\n };\r\n\r\n return (sel + \"\").replace(rcssescape, fcssescape);\r\n };\r\n }\r\n\r\n // Get info about gallery name and current index from url\r\n function parseUrl() {\r\n var hash = window.location.hash.substr(1),\r\n rez = hash.split(\"-\"),\r\n index = rez.length > 1 && /^\\+?\\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,\r\n gallery = rez.join(\"-\");\r\n\r\n return {\r\n hash: hash,\r\n /* Index is starting from 1 */\r\n index: index < 1 ? 1 : index,\r\n gallery: gallery\r\n };\r\n }\r\n\r\n // Trigger click evnt on links to open new fancyBox instance\r\n function triggerFromUrl(url) {\r\n if (url.gallery !== \"\") {\r\n // If we can find element matching 'data-fancybox' atribute,\r\n // then triggering click event should start fancyBox\r\n $(\"[data-fancybox='\" + $.escapeSelector(url.gallery) + \"']\")\r\n .eq(url.index - 1)\r\n .focus()\r\n .trigger(\"click.fb-start\");\r\n }\r\n }\r\n\r\n // Get gallery name from current instance\r\n function getGalleryID(instance) {\r\n var opts, ret;\r\n\r\n if (!instance) {\r\n return false;\r\n }\r\n\r\n opts = instance.current ? instance.current.opts : instance.opts;\r\n ret = opts.hash || (opts.$orig ? opts.$orig.data(\"fancybox\") || opts.$orig.data(\"fancybox-trigger\") : \"\");\r\n\r\n return ret === \"\" ? false : ret;\r\n }\r\n\r\n // Start when DOM becomes ready\r\n $(function () {\r\n // Check if user has disabled this module\r\n if ($.fancybox.defaults.hash === false) {\r\n return;\r\n }\r\n\r\n // Update hash when opening/closing fancyBox\r\n $(document).on({\r\n \"onInit.fb\": function (e, instance) {\r\n var url, gallery;\r\n\r\n if (instance.group[instance.currIndex].opts.hash === false) {\r\n return;\r\n }\r\n\r\n url = parseUrl();\r\n gallery = getGalleryID(instance);\r\n\r\n // Make sure gallery start index matches index from hash\r\n if (gallery && url.gallery && gallery == url.gallery) {\r\n instance.currIndex = url.index - 1;\r\n }\r\n },\r\n\r\n \"beforeShow.fb\": function (e, instance, current, firstRun) {\r\n var gallery;\r\n\r\n if (!current || current.opts.hash === false) {\r\n return;\r\n }\r\n\r\n // Check if need to update window hash\r\n gallery = getGalleryID(instance);\r\n\r\n if (!gallery) {\r\n return;\r\n }\r\n\r\n // Variable containing last hash value set by fancyBox\r\n // It will be used to determine if fancyBox needs to close after hash change is detected\r\n instance.currentHash = gallery + (instance.group.length > 1 ? \"-\" + (current.index + 1) : \"\");\r\n\r\n // If current hash is the same (this instance most likely is opened by hashchange), then do nothing\r\n if (window.location.hash === \"#\" + instance.currentHash) {\r\n return;\r\n }\r\n\r\n if (firstRun && !instance.origHash) {\r\n instance.origHash = window.location.hash;\r\n }\r\n\r\n if (instance.hashTimer) {\r\n clearTimeout(instance.hashTimer);\r\n }\r\n\r\n // Update hash\r\n instance.hashTimer = setTimeout(function () {\r\n if (\"replaceState\" in window.history) {\r\n window.history[firstRun ? \"pushState\" : \"replaceState\"]({},\r\n document.title,\r\n window.location.pathname + window.location.search + \"#\" + instance.currentHash\r\n );\r\n\r\n if (firstRun) {\r\n instance.hasCreatedHistory = true;\r\n }\r\n } else {\r\n window.location.hash = instance.currentHash;\r\n }\r\n\r\n instance.hashTimer = null;\r\n }, 300);\r\n },\r\n\r\n \"beforeClose.fb\": function (e, instance, current) {\r\n if (!current || current.opts.hash === false) {\r\n return;\r\n }\r\n\r\n clearTimeout(instance.hashTimer);\r\n\r\n // Goto previous history entry\r\n if (instance.currentHash && instance.hasCreatedHistory) {\r\n window.history.back();\r\n } else if (instance.currentHash) {\r\n if (\"replaceState\" in window.history) {\r\n window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || \"\"));\r\n } else {\r\n window.location.hash = instance.origHash;\r\n }\r\n }\r\n\r\n instance.currentHash = null;\r\n }\r\n });\r\n\r\n // Check if need to start/close after url has changed\r\n $(window).on(\"hashchange.fb\", function () {\r\n var url = parseUrl(),\r\n fb = null;\r\n\r\n // Find last fancyBox instance that has \"hash\"\r\n $.each(\r\n $(\".fancybox-container\")\r\n .get()\r\n .reverse(),\r\n function (index, value) {\r\n var tmp = $(value).data(\"FancyBox\");\r\n\r\n if (tmp && tmp.currentHash) {\r\n fb = tmp;\r\n return false;\r\n }\r\n }\r\n );\r\n\r\n if (fb) {\r\n // Now, compare hash values\r\n if (fb.currentHash !== url.gallery + \"-\" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {\r\n fb.currentHash = null;\r\n\r\n fb.close();\r\n }\r\n } else if (url.gallery !== \"\") {\r\n triggerFromUrl(url);\r\n }\r\n });\r\n\r\n // Check current hash and trigger click event on matching element to start fancyBox, if needed\r\n setTimeout(function () {\r\n if (!$.fancybox.getInstance()) {\r\n triggerFromUrl(parseUrl());\r\n }\r\n }, 50);\r\n });\r\n})(window, document, jQuery);\n// ==========================================================================\r\n//\r\n// Wheel\r\n// Basic mouse weheel support for gallery navigation\r\n//\r\n// ==========================================================================\r\n(function (document, $) {\r\n \"use strict\";\r\n\r\n var prevTime = new Date().getTime();\r\n\r\n $(document).on({\r\n \"onInit.fb\": function (e, instance, current) {\r\n instance.$refs.stage.on(\"mousewheel DOMMouseScroll wheel MozMousePixelScroll\", function (e) {\r\n var current = instance.current,\r\n currTime = new Date().getTime();\r\n\r\n if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === \"auto\" && current.type !== \"image\")) {\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n if (current.$slide.hasClass(\"fancybox-animated\")) {\r\n return;\r\n }\r\n\r\n e = e.originalEvent || e;\r\n\r\n if (currTime - prevTime < 250) {\r\n return;\r\n }\r\n\r\n prevTime = currTime;\r\n\r\n instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? \"next\" : \"previous\"]();\r\n });\r\n }\r\n });\r\n})(document, jQuery);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AZmFuY3lhcHBzL2ZhbmN5Ym94L2Rpc3QvanF1
109ZXJ5LmZhbmN5Ym94LmpzPzY1MWUiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIGZhbmN5Qm94IHYzLjUuN1xuLy9cbi8vIExpY2Vuc2VkIEdQTHYzIGZvciBvcGVuIHNvdXJjZSB1c2Vcbi8vIG9yIGZhbmN5Qm94IENvbW1lcmNpYWwgTGljZW5zZSBmb3IgY29tbWVyY2lhbCB1c2Vcbi8vXG4vLyBodHRwOi8vZmFuY3lhcHBzLmNvbS9mYW5jeWJveC9cbi8vIENvcHlyaWdodCAyMDE5IGZhbmN5QXBwc1xuLy9cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4oZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQsICQsIHVuZGVmaW5lZCkge1xyXG4gIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICB3aW5kb3cuY29uc29sZSA9IHdpbmRvdy5jb25zb2xlIHx8IHtcclxuICAgIGluZm86IGZ1bmN0aW9uIChzdHVmZikge31cclxuICB9O1xyXG5cclxuICAvLyBJZiB0aGVyZSdzIG5vIGpRdWVyeSwgZmFuY3lCb3ggY2FuJ3Qgd29ya1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIGlmICghJCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gQ2hlY2sgaWYgZmFuY3lCb3ggaXMgYWxyZWFkeSBpbml0aWFsaXplZFxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgaWYgKCQuZm4uZmFuY3lib3gpIHtcclxuICAgIGNvbnNvbGUuaW5mbyhcImZhbmN5Qm94IGFscmVhZHkgaW5pdGlhbGl6ZWRcIik7XHJcblxyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gUHJpdmF0ZSBkZWZhdWx0IHNldHRpbmdzXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHZhciBkZWZhdWx0cyA9IHtcclxuICAgIC8vIENsb3NlIGV4aXN0aW5nIG1vZGFsc1xyXG4gICAgLy8gU2V0IHRoaXMgdG8gZmFsc2UgaWYgeW91IGRvIG5vdCBuZWVkIHRvIHN0YWNrIG11bHRpcGxlIGluc3RhbmNlc1xyXG4gICAgY2xvc2VFeGlzdGluZzogZmFsc2UsXHJcblxyXG4gICAgLy8gRW5hYmxlIGluZmluaXRlIGdhbGxlcnkgbmF2aWdhdGlvblxyXG4gICAgbG9vcDogZmFsc2UsXHJcblxyXG4gICAgLy8gSG9yaXpvbnRhbCBzcGFjZSBiZXR3ZWVuIHNsaWRlc1xyXG4gICAgZ3V0dGVyOiA1MCxcclxuXHJcbiAgICAvLyBFbmFibGUga2V5Ym9hcmQgbmF2aWdhdGlvblxyXG4gICAga2V5Ym9hcmQ6IHRydWUsXHJcblxyXG4gICAgLy8gU2hvdWxkIGFsbG93IGNhcHRpb24gdG8gb3ZlcmxhcCB0aGUgY29udGVudFxyXG4gICAgcHJldmVudENhcHRpb25PdmVybGFwOiB0cnVlLFxyXG5cclxuICAgIC8vIFNob3VsZCBkaXNwbGF5IG5hdmlnYXRpb24gYXJyb3dzIGF0IHRoZSBzY3JlZW4gZWRnZXNcclxuICAgIGFycm93czogdHJ1ZSxcclxuXHJcbiAgICAvLyBTaG91bGQgZGlzcGxheSBjb3VudGVyIGF0IHRoZSB0b3AgbGVmdCBjb3JuZXJcclxuICAgIGluZm9iYXI6IHRydWUsXHJcblxyXG4gICAgLy8gU2hvdWxkIGRpc3BsYXkgY2xvc2UgYnV0dG9uICh1c2luZyBgYnRuVHBsLnNtYWxsQnRuYCB0ZW1wbGF0ZSkgb3ZlciB0aGUgY29udGVudFxyXG4gICAgLy8gQ2FuIGJlIHRydWUsIGZhbHNlLCBcImF1dG9cIlxyXG4gICAgLy8gSWYgXCJhdXRvXCIgLSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZW5hYmxlZCBmb3IgXCJodG1sXCIsIFwiaW5saW5lXCIgb3IgXCJhamF4XCIgaXRlbXNcclxuICAgIHNtYWxsQnRuOiBcImF1dG9cIixcclxuXHJcbiAgICAvLyBTaG91bGQgZGlzcGxheSB0b29sYmFyIChidXR0b25zIGF0IHRoZSB0b3ApXHJcbiAgICAvLyBDYW4gYmUgdHJ1ZSwgZmFsc2UsIFwiYXV0b1wiXHJcbiAgICAvLyBJZiBcImF1dG9cIiAtIHdpbGwgYmUgYXV0b21hdGljYWxseSBoaWRkZW4gaWYgXCJzbWFsbEJ0blwiIGlzIGVuYWJsZWRcclxuICAgIHRvb2xiYXI6IFwiYXV0b1wiLFxyXG5cclxuICAgIC8vIFdoYXQgYnV0dG9ucyBzaG91bGQgYXBwZWFyIGluIHRoZSB0b3AgcmlnaHQgY29ybmVyLlxyXG4gICAgLy8gQnV0dG9ucyB3aWxsIGJlIGNyZWF0ZWQgdXNpbmcgdGVtcGxhdGVzIGZyb20gYGJ0blRwbGAgb3B0aW9uXHJcbiAgICAvLyBhbmQgdGhleSB3aWxsIGJlIHBsYWNlZCBpbnRvIHRvb2xiYXIgKGNsYXNzPVwiZmFuY3lib3gtdG9vbGJhclwiYCBlbGVtZW50KVxyXG4gICAgYnV0dG9uczogW1xyXG4gICAgICBcInpvb21cIixcclxuICAgICAgLy9cInNoYXJlXCIsXHJcbiAgICAgIFwic2xpZGVTaG93XCIsXHJcbiAgICAgIC8vXCJmdWxsU2NyZWVuXCIsXHJcbiAgICAgIC8vXCJkb3dubG9hZFwiLFxyXG4gICAgICBcInRodW1ic1wiLFxyXG4gICAgICBcImNsb3NlXCJcclxuICAgIF0sXHJcblxyXG4gICAgLy8gRGV0ZWN0IFwiaWRsZVwiIHRpbWUgaW4gc2Vjb25kc1xyXG4gICAgaWRsZVRpbWU6IDMsXHJcblxyXG4gICAgLy8gRGlzYWJsZSByaWdodC1jbGljayBhbmQgdXNlIHNpbXBsZSBpbWFnZSBwcm90ZWN0aW9uIGZvciBpbWFnZXNcclxuICAgIHByb3RlY3Q6IGZhbHNlLFxyXG5cclxuICAgIC8vIFNob3J0Y3V0IHRvIG1ha2UgY29udGVudCBcIm1vZGFsXCIgLSBkaXNhYmxlIGtleWJvYXJkIG5hdmlndGlvbiwgaGlkZSBidXR0b25zLCBldGNcclxuICAgIG1vZGFsOiBmYWxzZSxcclxuXHJcbiAgICBpbWFnZToge1xyXG4gICAgICAvLyBXYWl0IGZvciBpbWFnZXMgdG8gbG9hZCBiZWZvcmUgZGlzcGxheWluZ1xyXG4gICAgICAvLyAgIHRydWUgIC0gd2FpdCBmb3IgaW1hZ2UgdG8gbG9hZCBhbmQgdGhlbiBkaXNwbGF5O1xyXG4gICAgICAvLyAgIGZhbHNlIC0gZGlzcGxheSB0aHVtYm5haWwgYW5kIGxvYWQgdGhlIGZ1bGwtc2l6ZWQgaW1hZ2Ugb3ZlciB0b3AsX
109HJcbiAgICAgIC8vICAgICAgICAgICByZXF1aXJlcyBwcmVkZWZpbmVkIGltYWdlIGRpbWVuc2lvbnMgKGBkYXRhLXdpZHRoYCBhbmQgYGRhdGEtaGVpZ2h0YCBhdHRyaWJ1dGVzKVxyXG4gICAgICBwcmVsb2FkOiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICBhamF4OiB7XHJcbiAgICAgIC8vIE9iamVjdCBjb250YWluaW5nIHNldHRpbmdzIGZvciBhamF4IHJlcXVlc3RcclxuICAgICAgc2V0dGluZ3M6IHtcclxuICAgICAgICAvLyBUaGlzIGhlbHBzIHRvIGluZGljYXRlIHRoYXQgcmVxdWVzdCBjb21lcyBmcm9tIHRoZSBtb2RhbFxyXG4gICAgICAgIC8vIEZlZWwgZnJlZSB0byBjaGFuZ2UgbmFtaW5nXHJcbiAgICAgICAgZGF0YToge1xyXG4gICAgICAgICAgZmFuY3lib3g6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgaWZyYW1lOiB7XHJcbiAgICAgIC8vIElmcmFtZSB0ZW1wbGF0ZVxyXG4gICAgICB0cGw6ICc8aWZyYW1lIGlkPVwiZmFuY3lib3gtZnJhbWV7cm5kfVwiIG5hbWU9XCJmYW5jeWJveC1mcmFtZXtybmR9XCIgY2xhc3M9XCJmYW5jeWJveC1pZnJhbWVcIiBhbGxvd2Z1bGxzY3JlZW49XCJhbGxvd2Z1bGxzY3JlZW5cIiBhbGxvdz1cImF1dG9wbGF5OyBmdWxsc2NyZWVuXCIgc3JjPVwiXCI+PC9pZnJhbWU+JyxcclxuXHJcbiAgICAgIC8vIFByZWxvYWQgaWZyYW1lIGJlZm9yZSBkaXNwbGF5aW5nIGl0XHJcbiAgICAgIC8vIFRoaXMgYWxsb3dzIHRvIGNhbGN1bGF0ZSBpZnJhbWUgY29udGVudCB3aWR0aCBhbmQgaGVpZ2h0XHJcbiAgICAgIC8vIChub3RlOiBEdWUgdG8gXCJTYW1lIE9yaWdpbiBQb2xpY3lcIiwgeW91IGNhbid0IGdldCBjcm9zcyBkb21haW4gZGF0YSkuXHJcbiAgICAgIHByZWxvYWQ6IHRydWUsXHJcblxyXG4gICAgICAvLyBDdXN0b20gQ1NTIHN0eWxpbmcgZm9yIGlmcmFtZSB3cmFwcGluZyBlbGVtZW50XHJcbiAgICAgIC8vIFlvdSBjYW4gdXNlIHRoaXMgdG8gc2V0IGN1c3RvbSBpZnJhbWUgZGltZW5zaW9uc1xyXG4gICAgICBjc3M6IHt9LFxyXG5cclxuICAgICAgLy8gSWZyYW1lIHRhZyBhdHRyaWJ1dGVzXHJcbiAgICAgIGF0dHI6IHtcclxuICAgICAgICBzY3JvbGxpbmc6IFwiYXV0b1wiXHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gRm9yIEhUTUw1IHZpZGVvIG9ubHlcclxuICAgIHZpZGVvOiB7XHJcbiAgICAgIHRwbDogJzx2aWRlbyBjbGFzcz1cImZhbmN5Ym94LXZpZGVvXCIgY29udHJvbHMgY29udHJvbHNMaXN0PVwibm9kb3dubG9hZFwiIHBvc3Rlcj1cInt7cG9zdGVyfX1cIj4nICtcclxuICAgICAgICAnPHNvdXJjZSBzcmM9XCJ7e3NyY319XCIgdHlwZT1cInt7Zm9ybWF0fX1cIiAvPicgK1xyXG4gICAgICAgICdTb3JyeSwgeW91ciBicm93c2VyIGRvZXNuXFwndCBzdXBwb3J0IGVtYmVkZGVkIHZpZGVvcywgPGEgaHJlZj1cInt7c3JjfX1cIj5kb3dubG9hZDwvYT4gYW5kIHdhdGNoIHdpdGggeW91ciBmYXZvcml0ZSB2aWRlbyBwbGF5ZXIhJyArXHJcbiAgICAgICAgXCI8L3ZpZGVvPlwiLFxyXG4gICAgICBmb3JtYXQ6IFwiXCIsIC8vIGN1c3RvbSB2aWRlbyBmb3JtYXRcclxuICAgICAgYXV0b1N0YXJ0OiB0cnVlXHJcbiAgICB9LFxyXG5cclxuICAgIC8vIERlZmF1bHQgY29udGVudCB0eXBlIGlmIGNhbm5vdCBiZSBkZXRlY3RlZCBhdXRvbWF0aWNhbGx5XHJcbiAgICBkZWZhdWx0VHlwZTogXCJpbWFnZVwiLFxyXG5cclxuICAgIC8vIE9wZW4vY2xvc2UgYW5pbWF0aW9uIHR5cGVcclxuICAgIC8vIFBvc3NpYmxlIHZhbHVlczpcclxuICAgIC8vICAgZmFsc2UgICAgICAgICAgICAtIGRpc2FibGVcclxuICAgIC8vICAgXCJ6b29tXCIgICAgICAgICAgIC0gem9vbSBpbWFnZXMgZnJvbS90byB0aHVtYm5haWxcclxuICAgIC8vICAgXCJmYWRlXCJcclxuICAgIC8vICAgXCJ6b29tLWluLW91dFwiXHJcbiAgICAvL1xyXG4gICAgYW5pbWF0aW9uRWZmZWN0OiBcInpvb21cIixcclxuXHJcbiAgICAvLyBEdXJhdGlvbiBpbiBtcyBmb3Igb3Blbi9jbG9zZSBhbmltYXRpb25cclxuICAgIGFuaW1hdGlvbkR1cmF0aW9uOiAzNjYsXHJcblxyXG4gICAgLy8gU2hvdWxkIGltYWdlIGNoYW5nZSBvcGFjaXR5IHdoaWxlIHpvb21pbmdcclxuICAgIC8vIElmIG9wYWNpdHkgaXMgXCJhdXRvXCIsIHRoZW4gb3BhY2l0eSB3aWxsIGJlIGNoYW5nZWQgaWYgaW1hZ2UgYW5kIHRodW1ibmFpbCBoYXZlIGRpZmZlcmVudCBhc3BlY3QgcmF0aW9zXHJcbiAgICB6b29tT3BhY2l0eTogXCJhdXRvXCIsXHJcblxyXG4gICAgLy8gVHJhbnNpdGlvbiBlZmZlY3QgYmV0d2VlbiBzbGlkZXNcclxuICAgIC8vXHJcbiAgICAvLyBQb3NzaWJsZSB2YWx1ZXM6XHJcbiAgICAvLyAgIGZhbHNlICAgICAgICAgICAgLSBkaXNhYmxlXHJcbiAgICAvLyAgIFwiZmFkZSdcclxuICAgIC8vICAgXCJzbGlkZSdcclxuICAgIC8vICAgXCJjaXJjdWxhcidcclxuICAgIC8vICAgXCJ0dWJlJ1xyXG4gICAgLy8gICBcInpvb20taW4tb3V0J1xyXG4gICAgLy8gICBcInJvdGF0ZSdcclxuICAgIC8vXHJcbiAgICB0cmFuc2l0aW9uRWZmZWN0OiBcImZhZGVcIixcclxuXHJcbiAgICAvLyBEdXJhdGlvbiBpbiBtcyBmb3IgdHJhbnNpdGlvbiBhbmltYXRpb25cclxuICAgIHRyYW5zaXRpb25EdXJhdGlvbjogMzY2LFxyXG5cclxuICAgIC8vIEN1c3RvbSBDU1MgY2xhc3MgZm9yIHNsaWRlIGVsZW1lbnRcclxuICAgIHNsaWRlQ2xhc3M6IFwiXCIsXHJcblxyXG4gICAgLy8gQ3VzdG9tIENTUyBjbGFzcyBmb3IgbGF5b3V0XHJcbiAgICBiYXNlQ2xhc3M6IFwiXCIsXHJcblxyXG4gICAgLy8gQmFzZSB0ZW1wbGF0ZSBmb3IgbGF5b3V0XHJcbiAgICBiYXNlVHBsOiAnPGRpdiBjbGFzcz1cImZhbmN5Ym94LWNvbnRhaW5lclwiIHJvbGU9XCJkaWFsb2dcIiB0YWJpbmRleD1cIi0xXCI+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtYmdcIj48L2Rpdj4nICtcclxuICAgICAgJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1pbm5lclwiPicgK1xyXG4gICAgICAnPGRpdiBjbGFzcz1cImZhbmN5Ym94LWluZm9iYXJcIj48c3BhbiBkYXRhLWZhbmN5Ym94LWluZGV4Pjwvc3Bhbj4mbmJzcDsvJm5ic3A7PHNwYW4gZGF0YS1mYW5jeWJveC1jb3VudD48L3NwYW4+PC9kaXY+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtdG9vbGJhclwiPnt7YnV0dG9uc319PC9kaXY+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtbmF2aWdhdGlvblwiPnt7YXJyb3dzfX08L2Rpdj4nICtcclxuICAgICAgJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1zdGFnZVwiPjwvZGl2PicgK1xyXG4gICAgICAnPGRpdiBjbGFzcz1cImZhbmN5Ym94LWNhcHRpb25cIj48ZGl2IGNsYXNzPVwiZmFuY3lib3gtY2FwdGlvbl9fYm9keVwiPjwvZGl2PjwvZGl2PicgK1xyXG4gICAgICBcIjwvZGl2PlwiICtcclxuICAgICAgXCI8L2Rpdj5cIixcclxuXHJcbiAgICAvLyBMb2FkaW5nIGluZGljYXRvciB0ZW1wbGF0ZVxyXG4gICAgc3Bpbm5lclRwbDogJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1sb2FkaW5nXCI+PC9kaXY+JyxcclxuXHJcbiAgICAvLyBFcnJvciBtZXNzYWdlIHRlbXBsYXRlXHJcbiAgICBlcnJvclRwbDogJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1lcnJvclwiPjxwPnt7RVJST1J9fTwvcD48L2Rpdj4nLFxyXG5cclxuICAgIGJ0blRwbDoge1xyXG4gICAgICBkb3dubG9hZDogJzxhIGRvd25sb2FkIGRhdGEtZmFuY3lib3gtZG93bmxvYWQgY2xhc3M9XCJmYW5jeWJveC1idXR0b24gZmFuY3lib3gtYnV0dG9uLS1kb3dubG9hZFwiIHRpdGxlPVwie3tET1dOTE9BRH19XCIgaHJlZj1cImphdmFzY3JpcHQ6O1wiPicgK1xyXG4gICAgICAgICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk0xOC42MiAxNy4wOVYxOUg1LjM4di0xLjkxem0tMi45Ny02Ljk2TDE3IDExLjQ1bC01IDQuODctNS00Ljg3IDEuMzYtMS4zMiAyLjY4IDIuNjRWNWgxLjkydjcuNzd6XCIvPjwvc3ZnPicgK1xyXG4gICAgICAgIFwiPC9hPlwiLFxyXG5cclxuICAgICAgem9vbTogJzxidXR0b24gZGF0YS1mYW5jeWJveC16b29tIGNsYXNzPVwiZmFuY3lib3gtYnV0dG9uIGZhbmN5Ym94LWJ1dHRvbi0tem9vbVwiIHRpdGxlPVwie3taT09NfX1cIj4nICtcclxuICAgICAgICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPjxwYXRoIGQ9XCJNMTguNyAxNy4zbC0zLTNhNS45IDUuOSAwIDAgMC0uNi03LjYgNS45IDUuOSAwIDAgMC04LjQgMCA1LjkgNS45IDAgMCAwIDAgOC40IDUuOSA1LjkgMCAwIDAgNy43LjdsMyAzYTEgMSAwIDAgMCAxLjMgMGMuNC0uNS40LTEgMC0xLjV6TTguMSAxMy44YTQgNCAwIDAgMSAwLTUuNyA0IDQgMCAwIDEgNS43IDAgNCA0IDAgMCAxIDAgNS43IDQgNCAwIDAgMS01LjcgMHpcIi8+PC9zdmc+JyArXHJcbiAgICAgICAgXCI8L2J1dHRvbj5cIixcclxuXHJcbiAgICAgIGNsb3NlOiAnPGJ1dHRvbiBkYXRhLWZhbmN5Ym94LWNsb3NlIGNsYXNzPVwiZmFuY3lib3gtYnV0dG9uIGZhbmN5Ym94LWJ1dHRvbi0tY2xvc2VcIiB0aXRsZT1cInt7Q0xPU0V9fVwiPicgK1xyXG4gICAgICAgICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk0xMiAxMC42TDYuNiA1LjIgNS4yIDYuNmw1LjQgNS40LTUuNCA1LjQgMS40IDEuNCA1LjQtNS40IDUuNCA1LjQgMS40LTEuNC01LjQtNS40IDUuNC01LjQtMS40LTEuNC01LjQgNS40elwiLz48L3N2Zz4nICtcclxuICAgICAgICBcIjwvYnV0dG9uPlwiLFxyXG5cclxuICAgICAgLy8gQXJyb3dzXHJcbiAgICAgIGFycm93TGVmdDogJzxidXR0b24gZGF0YS1mYW5jeWJveC1wcmV2IGNsYXNzPVwiZmFuY3lib3gtYnV0dG9uIGZhbmN5Ym94LWJ1dHRvbi0tYXJyb3dfbGVmdFwiIHRpdGxlPVwie3tQUkVWfX1cIj4nICtcclxuICAgICAgICAnPGRpdj48c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk0xMS4yOCAxNS43bC0xLjM0IDEuMzdMNSAxMmw0Ljk0LTUuMDcgMS4zNCAxLjM4LTIuNjggMi43MkgxOXYxLjk0SDguNnpcIi8+PC9zdmc+PC9kaXY+JyArXHJcbiAgICAgICAgXCI8L2J1dHRvbj5cIixcclxuXHJcbiAgICAgIGFycm93UmlnaHQ6ICc8YnV0dG9uIGRhdGEtZmFuY3lib3gtbmV4dCBjbGFzcz1cImZhbmN5Ym94LWJ1dHRvbiBmYW5jeWJveC1idXR0b24tLWFycm93X3JpZ2h0XCIgdGl0bGU9XCJ7e05FWFR9fVwiPicgK1xyXG4gICAgICAgICc8ZGl2PjxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj48cGF0aCBkPVwiTTE1LjQgMTIuOTdsLTIuNjggMi43MiAxLjM0IDEuMzhMMTkgMTJsLTQuOTQtNS4wNy0xLjM0IDEuMzggMi42OCAyLjcySDV2MS45NHpcIi8+PC9zdmc+PC9kaXY+JyArXHJcbiAgICAgICAgXCI8L2J1dHRvbj5cIixcclxuXHJcbiAgICAgIC8vIFRoaXMgc21hbGwgY2xvc2UgYnV0dG9uIHdpbGwgYmUgYXBwZW5kZWQgdG8geW91ciBodG1sL2lubGluZS9hamF4IGNvbnRlbnQgYnkgZGVmYXVsdCxcclxuICAgICAgLy8gaWYgXCJzbWFsbEJ0blwiIG9wdGlvbiBpcyBub3Qgc2V0IHRvIGZhbHNlXHJcbiAgICAgIHNtYWxsQnRuOiAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1mYW5jeWJveC1jbG9zZSBjbGFzcz1cImZhbmN5Ym94LWJ1dHRvbiBmYW5jeWJveC1jbG9zZS1zbWFsbFwiIHRpdGxlPVwie3tDTE9TRX19XCI+JyArXHJcbiAgICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZlcnNpb249XCIxXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPjxwYXRoIGQ9XCJNMTMgMTJsNS01LTEtMS01IDUtNS01LTEgMSA1IDUtNSA1IDEgMSA1LTUgNSA1IDEtMXpcIi8+PC9zdmc+JyArXHJcbiAgICAgICAgXCI8L2J1dHRvbj5cIlxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDb250YWluZXIgaXMgaW5qZWN0ZWQgaW50byB0aGlzIGVsZW1lbnRcclxuICAgIHBhcmVudEVsOiBcImJvZHlcIixcclxuXHJcbiAgICAvLyBIaWRlIGJyb3dzZXIgdmVydGljYWwgc2Nyb2xsYmFyczsgdXNlIGF0IHlvdXIgb3duIHJpc2tcclxuICAgIGhpZGVTY3JvbGxiYXI6IHRydWUsXHJcblxyXG4gICAgLy8gRm9jdXMgaGFuZGxpbmdcclxuICAgIC8vID09PT09PT09PT09PT09XHJcblxyXG4gICAgLy8gVHJ5IHRvIGZvY3VzIG9uIHRoZSBmaXJzdCBmb2N1c2FibGUgZWxlbWVudCBhZnRlciBvcGVuaW5nXHJcbiAgICBhdXRvRm9jdXM6IHRydWUsXHJcblxyXG4gICAgLy8gUHV0IGZvY3VzIGJhY2
109sgdG8gYWN0aXZlIGVsZW1lbnQgYWZ0ZXIgY2xvc2luZ1xyXG4gICAgYmFja0ZvY3VzOiB0cnVlLFxyXG5cclxuICAgIC8vIERvIG5vdCBsZXQgdXNlciB0byBmb2N1cyBvbiBlbGVtZW50IG91dHNpZGUgbW9kYWwgY29udGVudFxyXG4gICAgdHJhcEZvY3VzOiB0cnVlLFxyXG5cclxuICAgIC8vIE1vZHVsZSBzcGVjaWZpYyBvcHRpb25zXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGZ1bGxTY3JlZW46IHtcclxuICAgICAgYXV0b1N0YXJ0OiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBTZXQgYHRvdWNoOiBmYWxzZWAgdG8gZGlzYWJsZSBwYW5uaW5nL3N3aXBpbmdcclxuICAgIHRvdWNoOiB7XHJcbiAgICAgIHZlcnRpY2FsOiB0cnVlLCAvLyBBbGxvdyB0byBkcmFnIGNvbnRlbnQgdmVydGljYWxseVxyXG4gICAgICBtb21lbnR1bTogdHJ1ZSAvLyBDb250aW51ZSBtb3ZlbWVudCBhZnRlciByZWxlYXNpbmcgbW91c2UvdG91Y2ggd2hlbiBwYW5uaW5nXHJcbiAgICB9LFxyXG5cclxuICAgIC8vIEhhc2ggdmFsdWUgd2hlbiBpbml0aWFsaXppbmcgbWFudWFsbHksXHJcbiAgICAvLyBzZXQgYGZhbHNlYCB0byBkaXNhYmxlIGhhc2ggY2hhbmdlXHJcbiAgICBoYXNoOiBudWxsLFxyXG5cclxuICAgIC8vIEN1c3RvbWl6ZSBvciBhZGQgbmV3IG1lZGlhIHR5cGVzXHJcbiAgICAvLyBFeGFtcGxlOlxyXG4gICAgLypcclxuICAgICAgbWVkaWEgOiB7XHJcbiAgICAgICAgeW91dHViZSA6IHtcclxuICAgICAgICAgIHBhcmFtcyA6IHtcclxuICAgICAgICAgICAgYXV0b3BsYXkgOiAwXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAqL1xyXG4gICAgbWVkaWE6IHt9LFxyXG5cclxuICAgIHNsaWRlU2hvdzoge1xyXG4gICAgICBhdXRvU3RhcnQ6IGZhbHNlLFxyXG4gICAgICBzcGVlZDogMzAwMFxyXG4gICAgfSxcclxuXHJcbiAgICB0aHVtYnM6IHtcclxuICAgICAgYXV0b1N0YXJ0OiBmYWxzZSwgLy8gRGlzcGxheSB0aHVtYm5haWxzIG9uIG9wZW5pbmdcclxuICAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIEhpZGUgdGh1bWJuYWlsIGdyaWQgd2hlbiBjbG9zaW5nIGFuaW1hdGlvbiBzdGFydHNcclxuICAgICAgcGFyZW50RWw6IFwiLmZhbmN5Ym94LWNvbnRhaW5lclwiLCAvLyBDb250YWluZXIgaXMgaW5qZWN0ZWQgaW50byB0aGlzIGVsZW1lbnRcclxuICAgICAgYXhpczogXCJ5XCIgLy8gVmVydGljYWwgKHkpIG9yIGhvcml6b250YWwgKHgpIHNjcm9sbGluZ1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBVc2UgbW91c2V3aGVlbCB0byBuYXZpZ2F0ZSBnYWxsZXJ5XHJcbiAgICAvLyBJZiAnYXV0bycgLSBlbmFibGVkIGZvciBpbWFnZXMgb25seVxyXG4gICAgd2hlZWw6IFwiYXV0b1wiLFxyXG5cclxuICAgIC8vIENhbGxiYWNrc1xyXG4gICAgLy89PT09PT09PT09XHJcblxyXG4gICAgLy8gU2VlIERvY3VtZW50YXRpb24vQVBJL0V2ZW50cyBmb3IgbW9yZSBpbmZvcm1hdGlvblxyXG4gICAgLy8gRXhhbXBsZTpcclxuICAgIC8qXHJcbiAgICAgIGFmdGVyU2hvdzogZnVuY3Rpb24oIGluc3RhbmNlLCBjdXJyZW50ICkge1xyXG4gICAgICAgIGNvbnNvbGUuaW5mbyggJ0NsaWNrZWQgZWxlbWVudDonICk7XHJcbiAgICAgICAgY29uc29sZS5pbmZvKCBjdXJyZW50Lm9wdHMuJG9yaWcgKTtcclxuICAgICAgfVxyXG4gICAgKi9cclxuXHJcbiAgICBvbkluaXQ6ICQubm9vcCwgLy8gV2hlbiBpbnN0YW5jZSBoYXMgYmVlbiBpbml0aWFsaXplZFxyXG5cclxuICAgIGJlZm9yZUxvYWQ6ICQubm9vcCwgLy8gQmVmb3JlIHRoZSBjb250ZW50IG9mIGEgc2xpZGUgaXMgYmVpbmcgbG9hZGVkXHJcbiAgICBhZnRlckxvYWQ6ICQubm9vcCwgLy8gV2hlbiB0aGUgY29udGVudCBvZiBhIHNsaWRlIGlzIGRvbmUgbG9hZGluZ1xyXG5cclxuICAgIGJlZm9yZVNob3c6ICQubm9vcCwgLy8gQmVmb3JlIG9wZW4gYW5pbWF0aW9uIHN0YXJ0c1xyXG4gICAgYWZ0ZXJTaG93OiAkLm5vb3AsIC8vIFdoZW4gY29udGVudCBpcyBkb25lIGxvYWRpbmcgYW5kIGFuaW1hdGluZ1xyXG5cclxuICAgIGJlZm9yZUNsb3NlOiAkLm5vb3AsIC8vIEJlZm9yZSB0aGUgaW5zdGFuY2UgYXR0ZW1wdHMgdG8gY2xvc2UuIFJldHVybiBmYWxzZSB0byBjYW5jZWwgdGhlIGNsb3NlLlxyXG4gICAgYWZ0ZXJDbG9zZTogJC5ub29wLCAvLyBBZnRlciBpbnN0YW5jZSBoYXMgYmVlbiBjbG9zZWRcclxuXHJcbiAgICBvbkFjdGl2YXRlOiAkLm5vb3AsIC8vIFdoZW4gaW5zdGFuY2UgaXMgYnJvdWdodCB0byBmcm9udFxyXG4gICAgb25EZWFjdGl2YXRlOiAkLm5vb3AsIC8vIFdoZW4gb3RoZXIgaW5zdGFuY2UgaGFzIGJlZW4gYWN0aXZhdGVkXHJcblxyXG4gICAgLy8gSW50ZXJhY3Rpb25cclxuICAgIC8vID09PT09PT09PT09XHJcblxyXG4gICAgLy8gVXNlIG9wdGlvbnMgYmVsb3cgdG8gY3VzdG9taXplIHRha2VuIGFjdGlvbiB3aGVuIHVzZXIgY2xpY2tzIG9yIGRvdWJsZSBjbGlja3Mgb24gdGhlIGZhbmN5Qm94IGFyZWEsXHJcbiAgICAvLyBlYWNoIG9wdGlvbiBjYW4gYmUgc3RyaW5nIG9yIG1ldGhvZCB0aGF0IHJldHVybnMgdmFsdWUuXHJcbiAgICAvL1xyXG4gICAgLy8gUG9zc2libGUgdmFsdWVzOlxyXG4gICAgLy8gICBcImNsb3NlXCIgICAgICAgICAgIC0gY2xvc2UgaW5zdGFuY2VcclxuICAgIC8vICAgXCJuZXh0XCIgICAgICAgICAgICAtIG1vdmUgdG8gbmV4dCBnYWxsZXJ5IGl0ZW1cclxuICAgIC8vICAgXCJuZXh0T3JDbG9zZVwiICAgICAtIG1vdmUgdG8gbmV4dCBnYWxsZXJ5IGl0ZW0gb3IgY2xvc2UgaWYgZ2FsbGVyeSBoYXMgb25seSBvbmUgaXRlbVxyXG4gICAgLy8gICBcInRvZ2dsZUNvbnRyb2xzXCIgIC0gc2hvdy9oaWRlIGNvbnRyb2xzXHJcbiAgICAvLyAgIFwiem9vbVwiICAgICAgICAgICAgLSB6b29tIGltYWdlIChpZiBsb2FkZWQpXHJcbiAgICAvLyAgIGZhbHNlICAgICAgICAgICAgIC0gZG8gbm90aGluZ1xyXG5cclxuICAgIC8vIENsaWNrZWQgb24gdGhlIGNvbnRlbnRcclxuICAgIGNsaWNrQ29udGVudDogZnVuY3Rpb24gKGN1cnJlbnQsIGV2ZW50KSB7XHJcbiAgICAgIHJldHVybi
109BjdXJyZW50LnR5cGUgPT09IFwiaW1hZ2VcIiA/IFwiem9vbVwiIDogZmFsc2U7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENsaWNrZWQgb24gdGhlIHNsaWRlXHJcbiAgICBjbGlja1NsaWRlOiBcImNsb3NlXCIsXHJcblxyXG4gICAgLy8gQ2xpY2tlZCBvbiB0aGUgYmFja2dyb3VuZCAoYmFja2Ryb3ApIGVsZW1lbnQ7XHJcbiAgICAvLyBpZiB5b3UgaGF2ZSBub3QgY2hhbmdlZCB0aGUgbGF5b3V0LCB0aGVuIG1vc3QgbGlrZWx5IHlvdSBuZWVkIHRvIHVzZSBgY2xpY2tTbGlkZWAgb3B0aW9uXHJcbiAgICBjbGlja091dHNpZGU6IFwiY2xvc2VcIixcclxuXHJcbiAgICAvLyBTYW1lIGFzIHByZXZpb3VzIHR3bywgYnV0IGZvciBkb3VibGUgY2xpY2tcclxuICAgIGRibGNsaWNrQ29udGVudDogZmFsc2UsXHJcbiAgICBkYmxjbGlja1NsaWRlOiBmYWxzZSxcclxuICAgIGRibGNsaWNrT3V0c2lkZTogZmFsc2UsXHJcblxyXG4gICAgLy8gQ3VzdG9tIG9wdGlvbnMgd2hlbiBtb2JpbGUgZGV2aWNlIGlzIGRldGVjdGVkXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBtb2JpbGU6IHtcclxuICAgICAgcHJldmVudENhcHRpb25PdmVybGFwOiBmYWxzZSxcclxuICAgICAgaWRsZVRpbWU6IGZhbHNlLFxyXG4gICAgICBjbGlja0NvbnRlbnQ6IGZ1bmN0aW9uIChjdXJyZW50LCBldmVudCkge1xyXG4gICAgICAgIHJldHVybiBjdXJyZW50LnR5cGUgPT09IFwiaW1hZ2VcIiA/IFwidG9nZ2xlQ29udHJvbHNcIiA6IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgICBjbGlja1NsaWRlOiBmdW5jdGlvbiAoY3VycmVudCwgZXZlbnQpIHtcclxuICAgICAgICByZXR1cm4gY3VycmVudC50eXBlID09PSBcImltYWdlXCIgPyBcInRvZ2dsZUNvbnRyb2xzXCIgOiBcImNsb3NlXCI7XHJcbiAgICAgIH0sXHJcbiAgICAgIGRibGNsaWNrQ29udGVudDogZnVuY3Rpb24gKGN1cnJlbnQsIGV2ZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQudHlwZSA9PT0gXCJpbWFnZVwiID8gXCJ6b29tXCIgOiBmYWxzZTtcclxuICAgICAgfSxcclxuICAgICAgZGJsY2xpY2tTbGlkZTogZnVuY3Rpb24gKGN1cnJlbnQsIGV2ZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQudHlwZSA9PT0gXCJpbWFnZVwiID8gXCJ6b29tXCIgOiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBJbnRlcm5hdGlvbmFsaXphdGlvblxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBsYW5nOiBcImVuXCIsXHJcbiAgICBpMThuOiB7XHJcbiAgICAgIGVuOiB7XHJcbiAgICAgICAgQ0xPU0U6IFwiQ2xvc2VcIixcclxuICAgICAgICBORVhUOiBcIk5leHRcIixcclxuICAgICAgICBQUkVWOiBcIlByZXZpb3VzXCIsXHJcbiAgICAgICAgRVJST1I6IFwiVGhlIHJlcXVlc3RlZCBjb250ZW50IGNhbm5vdCBiZSBsb2FkZWQuIDxici8+IFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsXHJcbiAgICAgICAgUExBWV9TVEFSVDogXCJTdGFydCBzbGlkZXNob3dcIixcclxuICAgICAgICBQTEFZX1NUT1A6IFwiUGF1c2Ugc2xpZGVzaG93XCIsXHJcbiAgICAgICAgRlVMTF9TQ1JFRU46IFwiRnVsbCBzY3JlZW5cIixcclxuICAgICAgICBUSFVNQlM6IFwiVGh1bWJuYWlsc1wiLFxyXG4gICAgICAgIERPV05MT0FEOiBcIkRvd25sb2FkXCIsXHJcbiAgICAgICAgU0hBUkU6IFwiU2hhcmVcIixcclxuICAgICAgICBaT09NOiBcIlpvb21cIlxyXG4gICAgICB9LFxyXG4gICAgICBkZToge1xyXG4gICAgICAgIENMT1NFOiBcIlNjaGxpZSZzemxpZztlblwiLFxyXG4gICAgICAgIE5FWFQ6IFwiV2VpdGVyXCIsXHJcbiAgICAgICAgUFJFVjogXCJadXImdXVtbDtja1wiLFxyXG4gICAgICAgIEVSUk9SOiBcIkRpZSBhbmdlZm9yZGVydGVuIERhdGVuIGtvbm50ZW4gbmljaHQgZ2VsYWRlbiB3ZXJkZW4uIDxici8+IEJpdHRlIHZlcnN1Y2hlbiBTaWUgZXMgc3AmYXVtbDt0ZXIgbm9jaG1hbC5cIixcclxuICAgICAgICBQTEFZX1NUQVJUOiBcIkRpYXNjaGF1IHN0YXJ0ZW5cIixcclxuICAgICAgICBQTEFZX1NUT1A6IFwiRGlhc2NoYXUgYmVlbmRlblwiLFxyXG4gICAgICAgIEZVTExfU0NSRUVOOiBcIlZvbGxiaWxkXCIsXHJcbiAgICAgICAgVEhVTUJTOiBcIlZvcnNjaGF1YmlsZGVyXCIsXHJcbiAgICAgICAgRE9XTkxPQUQ6IFwiSGVydW50ZXJsYWRlblwiLFxyXG4gICAgICAgIFNIQVJFOiBcIlRlaWxlblwiLFxyXG4gICAgICAgIFpPT006IFwiVmVyZ3Imb3VtbDsmc3psaWc7ZXJuXCJcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIC8vIEZldyB1c2VmdWwgdmFyaWFibGVzIGFuZCBtZXRob2RzXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgdmFyICRXID0gJCh3aW5kb3cpO1xyXG4gIHZhciAkRCA9ICQoZG9jdW1lbnQpO1xyXG5cclxuICB2YXIgY2FsbGVkID0gMDtcclxuXHJcbiAgLy8gQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgalF1ZXJ5IG9iamVjdCBhbmQgbm90IGEgbmF0aXZlIEphdmFTY3JpcHQgb2JqZWN0XHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgdmFyIGlzUXVlcnkgPSBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICByZXR1cm4gb2JqICYmIG9iai5oYXNPd25Qcm9wZXJ0eSAmJiBvYmogaW5zdGFuY2VvZiAkO1xyXG4gIH07XHJcblxyXG4gIC8vIEhhbmRsZSBtdWx0aXBsZSBicm93c2VycyBmb3IgXCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIiBhbmQgXCJjYW5jZWxBbmltYXRpb25GcmFtZVwiXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIHZhciByZXF1ZXN0QUZyYW1lID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxyXG4gICAgICB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIHdpbmRvdy5vUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIC8vIGlmIGFsbCBlbHNlIGZhaWxzLCB1c2Ugc2V0VGltZW91dFxyXG4gICAgICBmdW5jdGlvbiAoY2FsbGJhY2spIHtcclxuICAgICAgICByZXR1cm4gd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfSkoKTtcclxuXHJcbiAgdmFyIGNhbmNlbEFGcmFtZSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgd2luZG93LndlYmtpdENhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIHdpbmRvdy5tb3pDYW5jZWxBbmltYXRpb25GcmFtZSB8fFxyXG4gICAgICB3aW5kb3cub0NhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIGZ1bmN0aW9uIChpZCkge1xyXG4gICAgICAgI
109HdpbmRvdy5jbGVhclRpbWVvdXQoaWQpO1xyXG4gICAgICB9XHJcbiAgICApO1xyXG4gIH0pKCk7XHJcblxyXG4gIC8vIERldGVjdCB0aGUgc3VwcG9ydGVkIHRyYW5zaXRpb24tZW5kIGV2ZW50IHByb3BlcnR5IG5hbWVcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgdmFyIHRyYW5zaXRpb25FbmQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZha2VlbGVtZW50XCIpLFxyXG4gICAgICB0O1xyXG5cclxuICAgIHZhciB0cmFuc2l0aW9ucyA9IHtcclxuICAgICAgdHJhbnNpdGlvbjogXCJ0cmFuc2l0aW9uZW5kXCIsXHJcbiAgICAgIE9UcmFuc2l0aW9uOiBcIm9UcmFuc2l0aW9uRW5kXCIsXHJcbiAgICAgIE1velRyYW5zaXRpb246IFwidHJhbnNpdGlvbmVuZFwiLFxyXG4gICAgICBXZWJraXRUcmFuc2l0aW9uOiBcIndlYmtpdFRyYW5zaXRpb25FbmRcIlxyXG4gICAgfTtcclxuXHJcbiAgICBmb3IgKHQgaW4gdHJhbnNpdGlvbnMpIHtcclxuICAgICAgaWYgKGVsLnN0eWxlW3RdICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gdHJhbnNpdGlvbnNbdF07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gXCJ0cmFuc2l0aW9uZW5kXCI7XHJcbiAgfSkoKTtcclxuXHJcbiAgLy8gRm9yY2UgcmVkcmF3IG9uIGFuIGVsZW1lbnQuXHJcbiAgLy8gVGhpcyBoZWxwcyBpbiBjYXNlcyB3aGVyZSB0aGUgYnJvd3NlciBkb2Vzbid0IHJlZHJhdyBhbiB1cGRhdGVkIGVsZW1lbnQgcHJvcGVybHlcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIHZhciBmb3JjZVJlZHJhdyA9IGZ1bmN0aW9uICgkZWwpIHtcclxuICAgIHJldHVybiAkZWwgJiYgJGVsLmxlbmd0aCAmJiAkZWxbMF0ub2Zmc2V0SGVpZ2h0O1xyXG4gIH07XHJcblxyXG4gIC8vIEV4Y2x1ZGUgYXJyYXkgKGBidXR0b25zYCkgb3B0aW9ucyBmcm9tIGRlZXAgbWVyZ2luZ1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIHZhciBtZXJnZU9wdHMgPSBmdW5jdGlvbiAob3B0czEsIG9wdHMyKSB7XHJcbiAgICB2YXIgcmV6ID0gJC5leHRlbmQodHJ1ZSwge30sIG9wdHMxLCBvcHRzMik7XHJcblxyXG4gICAgJC5lYWNoKG9wdHMyLCBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG4gICAgICBpZiAoJC5pc0FycmF
1095KHZhbHVlKSkge1xyXG4gICAgICAgIHJleltrZXldID0gdmFsdWU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXo7XHJcbiAgfTtcclxuXHJcbiAgLy8gSG93IG11Y2ggb2YgYW4gZWxlbWVudCBpcyB2aXNpYmxlIGluIHZpZXdwb3J0XHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHZhciBpblZpZXdwb3J0ID0gZnVuY3Rpb24gKGVsZW0pIHtcclxuICAgIHZhciBlbGVtQ2VudGVyLCByZXo7XHJcblxyXG4gICAgaWYgKCFlbGVtIHx8IGVsZW0ub3duZXJEb2N1bWVudCAhPT0gZG9jdW1lbnQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgICQoXCIuZmFuY3lib3gtY29udGFpbmVyXCIpLmNzcyhcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcclxuXHJcbiAgICBlbGVtQ2VudGVyID0ge1xyXG4gICAgICB4OiBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKyBlbGVtLm9mZnNldFdpZHRoIC8gMixcclxuICAgICAgeTogZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgKyBlbGVtLm9mZnNldEhlaWdodCAvIDJcclxuICAgIH07XHJcblxyXG4gICAgcmV6ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlbGVtQ2VudGVyLngsIGVsZW1DZW50ZXIueSkgPT09IGVsZW07XHJcblxyXG4gICAgJChcIi5mYW5jeWJveC1jb250YWluZXJcIikuY3NzKFwicG9pbnRlci1ldmVudHNcIiwgXCJcIik7XHJcblxyXG4gICAgcmV0dXJuIHJlejtcclxuICB9O1xyXG5cclxuICAvLyBDbGFzcyBkZWZpbml0aW9uXHJcbiAgLy8gPT09PT09PT09PT09PT09PVxyXG5cclxuICB2YXIgRmFuY3lCb3ggPSBmdW5jdGlvbiAoY29udGVudCwgb3B0cywgaW5kZXgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICBzZWxmLm9wdHMgPSBtZXJnZU9wdHMoe1xyXG4gICAgICBpbmRleDogaW5kZXhcclxuICAgIH0sICQuZmFuY3lib3guZGVmYXVsdHMpO1xyXG5cclxuICAgIGlmICgkLmlzUGxhaW5PYmplY3Qob3B0cykpIHtcclxuICAgICAgc2VsZi5vcHRzID0gbWVyZ2VPcHRzKHNlbGYub3B0cywgb3B0cyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCQuZmFuY3lib3guaXNNb2JpbGUpIHtcclxuICAgICAgc2VsZi5vcHRzID0gbWVyZ2VPcHRzKHNlbGYub3B0cywgc2VsZi5vcHRzLm1vYmlsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5pZCA9IHNlbGYub3B0cy5pZCB8fCArK2NhbGxlZDtcclxuXHJcbiAgICBzZWxmLmN1cnJJbmRleCA9IHBhcnNlSW50KHNlbGYub3B0cy5pbmRleCwgMTApIHx8IDA7XHJcbiAgICBzZWxmLnByZXZJbmRleCA9IG51bGw7XHJcblxyXG4gICAgc2VsZi5wcmV2UG9zID0gbnVsbDtcclxuICAgIHNlbGYuY3VyclBvcyA9IDA7XHJcblxyXG4gICAgc2VsZi5maXJzdFJ1biA9IHRydWU7XHJcblxyXG4gICAgLy8gQWxsIGdyb3VwIGl0ZW1zXHJcbiAgICBzZWxmLmdyb3VwID0gW107XHJcblxyXG4gICAgLy8gRXhpc3Rpbmcgc2xpZGVzIChmb3IgY3VycmVudCwgbmV4dCBhbmQgcHJldmlvdXMgZ2FsbGVyeSBpdGVtcylcclxuICAgIHNlbGYuc2xpZGVzID0ge307XHJcblxyXG4gICAgLy8gQ3JlYXRlIGdyb3VwIGVsZW1lbnRzXHJcbiAgICBzZWxmLmFkZENvbnRlbnQoY29udGVudCk7XHJcblxyXG4gICAgaWYgKCFzZWxmLmdyb3VwLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5pbml0KCk7XHJcbiAgfTtcclxuXHJcbiAgJC5leHRlbmQoRmFuY3lCb3gucHJvdG90eXBlLCB7XHJcbiAgICAvLyBDcmVhdGUgRE9NIHN0cnVjdHVyZVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBmaXJzdEl0ZW0gPSBzZWxmLmdyb3VwW3NlbGYuY3VyckluZGV4XSxcclxuICAgICAgICBmaXJzdEl0ZW1PcHRzID0gZmlyc3RJdGVtLm9wdHMsXHJcbiAgICAgICAgJGNvbnRhaW5lcixcclxuICAgICAgICBidXR0b25TdHI7XHJcblxyXG4gICAgICBpZiAoZmlyc3RJdGVtT3B0cy5jbG9zZUV4aXN0aW5nKSB7XHJcbiAgICAgICAgJC5mYW5jeWJveC5jbG9zZSh0cnVlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gSGlkZSBzY3JvbGxiYXJzXHJcbiAgICAgIC8vID09PT09PT09PT09PT09PVxyXG5cclxuICAgICAgJChcImJvZHlcIikuYWRkQ2xhc3MoXCJmYW5jeWJveC1hY3RpdmVcIik7XHJcblxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgISQuZmFuY3lib3guZ2V0SW5zdGFuY2UoKSAmJlxyXG4gICAgICAgIGZpcnN0SXRlbU9wdHMuaGlkZVNjcm9sbGJhciAhPT0gZmFsc2UgJiZcclxuICAgICAgICAhJC5mYW5jeWJveC5pc01vYmlsZSAmJlxyXG4gICAgICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0ID4gd2luZG93LmlubmVySGVpZ2h0XHJcbiAgICAgICkge1xyXG4gICAgICAgICQoXCJoZWFkXCIpLmFwcGVuZChcclxuICAgICAgICAgICc8c3R5bGUgaWQ9XCJmYW5jeWJveC1zdHlsZS1ub3Njcm9sbFwiIHR5cGU9XCJ0ZXh0L2Nzc1wiPi5jb21wZW5zYXRlLWZvci1zY3JvbGxiYXJ7bWFyZ2luLXJpZ2h0OicgK1xyXG4gICAgICAgICAgKHdpbmRvdy5pbm5lcldpZHRoIC0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKSArXHJcbiAgICAgICAgICBcInB4O308L3N0eWxlPlwiXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgJChcImJvZHlcIikuYWRkQ2xhc3MoXCJjb21wZW5zYXRlLWZvci1zY3JvbGxiYXJcIik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEJ1aWxkIGh0bWwgbWFya3VwIGFuZCBzZXQgcmVmZXJlbmNlc1xyXG4gICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICAgIC8vIEJ1aWxkIGh0bWwgY29kZSBmb3IgYnV0dG9ucyBhbmQgaW5zZXJ0IGludG8gbWFpbiB0ZW1wbGF0ZVxyXG4gICAgICBidXR0b25TdHIgPSBcIlwiO1xyXG5cclxuICAgICAgJC5lYWNoKGZpcnN0SXRlbU9wdHMuYnV0dG9ucywgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkge1xyXG4gICAgICAgIGJ1dHRvblN0ciArPSBmaXJzdEl0ZW1PcHRzLmJ0blRwbFt2YWx1ZV0gfHwgXCJcIjtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBDcmVhdGUgbWFya3VwIGZyb20gYmFzZSB0ZW1wbGF0ZSwgaXQgd2lsbCBiZSBpbml0aWFsbHkgaGlkZGVuIHRvXHJcbiAgICAgIC8vIGF2b2lkIHVubmVjZXNzYXJ5IHdvcmsgbGlrZSBwYWludGluZyB3aGlsZSBpbml0aWFsaXppbmcgaXMgbm90IGNvbXBsZXRlXHJcbiAgICAgICRjb250YWluZXIgPSAkKFxyXG4gICAgICAgICAgc2VsZi50cmFuc2xhdGUoXHJcbiAgICAgICAgICAgI
109HNlbGYsXHJcbiAgICAgICAgICAgIGZpcnN0SXRlbU9wdHMuYmFzZVRwbFxyXG4gICAgICAgICAgICAucmVwbGFjZShcInt7YnV0dG9uc319XCIsIGJ1dHRvblN0cilcclxuICAgICAgICAgICAgLnJlcGxhY2UoXCJ7e2Fycm93c319XCIsIGZpcnN0SXRlbU9wdHMuYnRuVHBsLmFycm93TGVmdCArIGZpcnN0SXRlbU9wdHMuYnRuVHBsLmFycm93UmlnaHQpXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5hdHRyKFwiaWRcIiwgXCJmYW5jeWJveC1jb250YWluZXItXCIgKyBzZWxmLmlkKVxyXG4gICAgICAgIC5hZGRDbGFzcyhmaXJzdEl0ZW1PcHRzLmJhc2VDbGFzcylcclxuICAgICAgICAuZGF0YShcIkZhbmN5Qm94XCIsIHNlbGYpXHJcbiAgICAgICAgLmFwcGVuZFRvKGZpcnN0SXRlbU9wdHMucGFyZW50RWwpO1xyXG5cclxuICAgICAgLy8gQ3JlYXRlIG9iamVjdCBob2xkaW5nIHJlZmVyZW5jZXMgdG8galF1ZXJ5IHdyYXBwZWQgbm9kZXNcclxuICAgICAgc2VsZi4kcmVmcyA9IHtcclxuICAgICAgICBjb250YWluZXI6ICRjb250YWluZXJcclxuICAgICAgfTtcclxuXHJcbiAgICAgIFtcImJnXCIsIFwiaW5uZXJcIiwgXCJpbmZvYmFyXCIsIFwidG9vbGJhclwiLCBcInN0YWdlXCIsIFwiY2FwdGlvblwiLCBcIm5hdmlnYXRpb25cIl0uZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIHNlbGYuJHJlZnNbaXRlbV0gPSAkY29udGFpbmVyLmZpbmQoXCIuZmFuY3lib3gtXCIgKyBpdGVtKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBzZWxmLnRyaWdnZXIoXCJvbkluaXRcIik7XHJcblxyXG4gICAgICAvLyBFbmFibGUgZXZlbnRzLCBkZWFjdGl2ZSBwcmV2aW91cyBpbnN0YW5jZXNcclxuICAgICAgc2VsZi5hY3RpdmF0ZSgpO1xyXG5cclxuICAgICAgLy8gQnVpbGQgc2xpZGVzLCBsb2FkIGFuZCByZXZlYWwgY29udGVudFxyXG4gICAgICBzZWxmLmp1bXBUbyhzZWxmLmN1cnJJbmRleCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFNpbXBsZSBpMThuIHN1cHBvcnQgLSByZXBsYWNlcyBvYmplY3Qga2V5cyBmb3VuZCBpbiB0ZW1wbGF0ZVxyXG4gICAgLy8gd2l0aCBjb3JyZXNwb25kaW5nIHZhbHVlc1xyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgdHJhbnNsYXRlOiBmdW5jdGlvbiAob2JqLCBzdHIpIHtcclxuICAgICAgdmFyIGFyciA9IG9iai5vcHRzLmkxOG5bb2JqLm9wdHMubGFuZ10gfHwgb2JqLm9wdHMuaTE4bi5lbjtcclxuXHJcbiAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvXFx7XFx7KFxcdyspXFx9XFx9L2csIGZ1bmN0aW9uIChtYXRjaCwgbikge1xyXG4gICAgICAgIHJldHVybiBhcnJbbl0gPT09IHVuZGVmaW5lZCA/IG1hdGNoIDogYXJyW25dO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gUG9wdWxhdGUgY3VycmVudCBncm91cCB3aXRoIGZyZXNoIGNvbnRlbnRcclxuICAgIC8vIENoZWNrIGlmIGVhY2ggb2JqZWN0IGhhcyB2YWxpZCB0eXBlIGFuZCBjb250ZW50XHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGFkZENvbnRlbnQ6IGZ1bmN0aW9uIChjb250ZW50KSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBpdGVtcyA9ICQubWFrZUFycmF5KGNvbnRlbnQpLFxyXG4gICAgICAgIHRodW1icztcclxuXHJcbiAgICAgICQuZWFjaChpdGVtcywgZnVuY3Rpb24gKGksIGl0ZW0pIHtcclxuICAgICAgICB2Y
109XIgb2JqID0ge30sXHJcbiAgICAgICAgICBvcHRzID0ge30sXHJcbiAgICAgICAgICAkaXRlbSxcclxuICAgICAgICAgIHR5cGUsXHJcbiAgICAgICAgICBmb3VuZCxcclxuICAgICAgICAgIHNyYyxcclxuICAgICAgICAgIHNyY1BhcnRzO1xyXG5cclxuICAgICAgICAvLyBTdGVwIDEgLSBNYWtlIHN1cmUgd2UgaGF2ZSBhbiBvYmplY3RcclxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICAgICAgaWYgKCQuaXNQbGFpbk9iamVjdChpdGVtKSkge1xyXG4gICAgICAgICAgLy8gV2UgcHJvYmFibHkgaGF2ZSBtYW51YWwgdXNhZ2UgaGVyZSwgc29tZXRoaW5nIGxpa2VcclxuICAgICAgICAgIC8vICQuZmFuY3lib3gub3BlbiggWyB7IHNyYyA6IFwiaW1hZ2UuanBnXCIsIHR5cGUgOiBcImltYWdlXCIgfSBdIClcclxuXHJcbiAgICAgICAgICBvYmogPSBpdGVtO1xyXG4gICAgICAgICAgb3B0cyA9IGl0ZW0ub3B0cyB8fCBpdGVtO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoJC50eXBlKGl0ZW0pID09PSBcIm9iamVjdFwiICYmICQoaXRlbSkubGVuZ3RoKSB7XHJcbiAgICAgICAgICAvLyBIZXJlIHdlIHByb2JhYmx5IGhhdmUgalF1ZXJ5IGNvbGxlY3Rpb24gcmV0dXJuZWQgYnkgc29tZSBzZWxlY3RvclxyXG4gICAgICAgICAgJGl0ZW0gPSAkKGl0ZW0pO1xyXG5cclxuICAgICAgICAgIC8vIFN1cHBvcnQgYXR0cmlidXRlcyBsaWtlIGBkYXRhLW9wdGlvbnM9J3tcInRvdWNoXCIgOiBmYWxzZX0nYCBhbmQgYGRhdGEtdG91Y2g9J2ZhbHNlJ2BcclxuICAgICAgICAgIG9wdHMgPSAkaXRlbS5kYXRhKCkgfHwge307XHJcbiAgICAgICAgICBvcHRzID0gJC5leHRlbmQodHJ1ZSwge30sIG9wdHMsIG9wdHMub3B0aW9ucyk7XHJcblxyXG4gICAgICAgICAgLy8gSGVyZSB3ZSBzdG9yZSBjbGlja2VkIGVsZW1lbnRcclxuICAgICAgICAgIG9wdHMuJG9yaWcgPSAkaXRlbTtcclxuXHJcbiAgICAgICAgICBvYmouc3JjID0gc2VsZi5vcHRzLnNyYyB8fCBvcHRzLnNyYyB8fCAkaXRlbS5hdHRyKFwiaHJlZlwiKTtcclxuXHJcbiAgICAgICAgICAvLyBBc3N1bWUgdGhhdCBzaW1wbGUgc3ludGF4IGlzIHVzZWQsIGZvciBleGFtcGxlOlxyXG4gICAgICAgICAgLy8gICBgJC5mYW5jeWJveC5vcGVuKCAkKFwiI3Rlc3RcIiksIHt9ICk7YFxyXG4gICAgICAgICAgaWYgKCFvYmoudHlwZSAmJiAhb2JqLnNyYykge1xyXG4gICAgICAgICAgICBvYmoudHlwZSA9IFwiaW5saW5lXCI7XHJcbiAgICAgICAgICAgIG9iai5zcmMgPSBpdGVtO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBBc3N1bWUgd2UgaGF2ZSBhIHNpbXBsZSBodG1sIGNvZGUsIGZvciBleGFtcGxlOlxyXG4gICAgICAgICAgLy8gICAkLmZhbmN5Ym94Lm9wZW4oICc8ZGl2PjxoMT5IaSE8L2gxPjwvZGl2PicgKTtcclxuICAgICAgICAgIG9iaiA9IHtcclxuICAgICAgICAgICAgdHlwZTogXCJodG1sXCIsXHJcbiAgICAgICAgICAgIHNyYzogaXRlbSArIFwiXCJcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBFYWNoIGdhbGxlcnkgb2JqZWN0IGhhcyBmdWxsIGNvbGxlY3Rpb24gb2Ygb3B0aW9uc1xyXG4gICAgICAgIG9iai5vcHRzID0gJC5leHRlbmQodHJ1ZSwge30sIHNlbGYub3B0cywgb3B0cyk7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBtZXJnZSBidXR0b25zIGFycmF5XHJcbiAgICAgICAgaWYgKCQuaXNBcnJheShvcHRzLmJ1dHRvbnMpKSB7XHJcbiAgICAgICAgICBvYmoub3B0cy5idXR0b25zID0gb3B0cy5idXR0b25zO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCQuZmFuY3lib3guaXNNb2JpbGUgJiYgb2JqLm9wdHMubW9iaWxlKSB7XHJcbiAgICAgICAgICBvYmoub3B0cyA9IG1lcmdlT3B0cyhvYmoub3B0cywgb2JqLm9wdHMubW9iaWxlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFN0ZXAgMiAtIE1ha2Ugc3VyZSB3ZSBoYXZlIGNvbnRlbnQgdHlwZSwgaWYgbm90IC0gdHJ5IHRvIGd1ZXNzXHJcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICAgICAgdHlwZSA9IG9iai50eXBlIHx8IG9iai5vcHRzLnR5cGU7XHJcbiAgICAgICAgc3JjID0gb2JqLnNyYyB8fCBcIlwiO1xyXG5cclxuICAgICAgICBpZiAoIXR5cGUgJiYgc3JjKSB7XHJcbiAgICAgICAgICBpZiAoKGZvdW5kID0gc3JjLm1hdGNoKC9cXC4obXA0fG1vdnxvZ3Z8d2VibSkoKFxcP3wjKS4qKT8kL2kpKSkge1xyXG4gICAgICAgICAgICB0eXBlID0gXCJ2aWRlb1wiO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFvYmoub3B0cy52aWRlby5mb3JtYXQpIHtcclxuICAgICAgICAgICAgICBvYmoub3B0cy52aWRlby5mb3JtYXQgPSBcInZpZGVvL1wiICsgKGZvdW5kWzFdID09PSBcIm9ndlwiID8gXCJvZ2dcIiA6IGZvdW5kWzFdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIGlmIChzcmMubWF0Y2goLyheZGF0YTppbWFnZVxcL1thLXowLTkrXFwvPV0qLCl8KFxcLihqcChlfGd8ZWcpfGdpZnxwbmd8Ym1wfHdlYnB8c3ZnfGljbykoKFxcP3wjKS4qKT8kKS9pKSkge1xyXG4gICAgICAgICAgICB0eXBlID0gXCJpbWFnZVwiO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChzcmMubWF0Y2goL1xcLihwZGYpKChcXD98IykuKik/JC9pKSkge1xyXG4gICAgICAgICAgICB0eXBlID0gXCJpZnJhbWVcIjtcclxuICAgICAgICAgICAgb2JqID0gJC5leHRlbmQodHJ1ZSwgb2JqLCB7XHJcbiAgICAgICAgICAgICAgY29udGVudFR5cGU6IFwicGRmXCIsXHJcbiAgICAgICAgICAgICAgb3B0czoge1xyXG4gICAgICAgICAgICAgICAgaWZyYW1lOiB7XHJcbiAgICAgICAgICAgICAgICAgIHByZWxvYWQ6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoc3JjLmNoYXJBdCgwKSA9PT0gXCIjXCIpIHtcclxuICAgICAgICAgICAgdHlwZSA9IFwiaW5saW5lXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodHlwZSkge1xyXG4gICAgICAgICAgb2JqLnR5cGUgPSB0eXBlO1xyXG4gICAgICAgI
109H0gZWxzZSB7XHJcbiAgICAgICAgICBzZWxmLnRyaWdnZXIoXCJvYmplY3ROZWVkc1R5cGVcIiwgb2JqKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghb2JqLmNvbnRlbnRUeXBlKSB7XHJcbiAgICAgICAgICBvYmouY29udGVudFR5cGUgPSAkLmluQXJyYXkob2JqLnR5cGUsIFtcImh0bWxcIiwgXCJpbmxpbmVcIiwgXCJhamF4XCJdKSA+IC0xID8gXCJodG1sXCIgOiBvYmoudHlwZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFN0ZXAgMyAtIFNvbWUgYWRqdXN0bWVudHNcclxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgICAgIG9iai5pbmRleCA9IHNlbGYuZ3JvdXAubGVuZ3RoO1xyXG5cclxuICAgICAgICBpZiAob2JqLm9wdHMuc21hbGxCdG4gPT0gXCJhdXRvXCIpIHtcclxuICAgICAgICAgIG9iai5vcHRzLnNtYWxsQnRuID0gJC5pbkFycmF5KG9iai50eXBlLCBbXCJodG1sXCIsIFwiaW5saW5lXCIsIFwiYWpheFwiXSkgPiAtMTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvYmoub3B0cy50b29sYmFyID09PSBcImF1dG9cIikge1xyXG4gICAgICAgICAgb2JqLm9wdHMudG9vbGJhciA9ICFvYmoub3B0cy5zbWFsbEJ0bjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEZpbmQgdGh1bWJuYWlsIGltYWdlLCBjaGVjayBpZiBleGlzdHMgYW5kIGlmIGlzIGluIHRoZSB2aWV3cG9ydFxyXG4gICAgICAgIG9iai4kdGh1bWIgPSBvYmoub3B0cy4kdGh1bWIgfHwgbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKG9iai5vcHRzLiR0cmlnZ2VyICYmIG9iai5pbmRleCA9PT0gc2VsZi5vcHRzLmluZGV4KSB7XHJcbiAgICAgICAgICBvYmouJHRodW1iID0gb2JqLm9wdHMuJHRyaWdnZXIuZmluZChcImltZzpmaXJzdFwiKTtcclxuXHJcbiAgICAgICAgICBpZiAob2JqLiR0aHVtYi5sZW5ndGgpIHtcclxuICAgICAgICAgICAgb2JqLm9wdHMuJG9yaWcgPSBvYmoub3B0cy4kdHJpZ2dlcjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghKG9iai4kdGh1bWIgJiYgb2JqLiR0aHVtYi5sZW5ndGgpICYmIG9iai5vcHRzLiRvcmlnKSB7XHJcbiAgICAgICAgICBvYmouJHRodW1iID0gb2JqLm9wdHMuJG9yaWcuZmluZChcImltZzpmaXJzdFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvYmouJHRodW1iICYmICFvYmouJHRodW1iLmxlbmd0aCkge1xyXG4gICAgICAgICAgb2JqLiR0aHVtYiA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBvYmoudGh1bWIgPSBvYmoub3B0cy50aHVtYiB8fCAob2JqLiR0aHVtYiA/IG9iai4kdGh1bWJbMF0uc3JjIDogbnVsbCk7XHJcblxyXG4gICAgICAgIC8vIFwiY2FwdGlvblwiIGlzIGEgXCJzcGVjaWFsXCIgb3B0aW9uLCBpdCBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgY2FwdGlvbiBwZXIgZ2FsbGVyeSBpdGVtXHJcbiAgICAgICAgaWYgKCQudHlwZShvYmoub3B0cy5jYXB0aW9uKSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICBvYmoub3B0cy5jYXB0aW9uID0gb2JqLm9wdHMuY2FwdGlvbi5hcHBseShpdGVtLCBbc2VsZiwgb2JqXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoJC50eXBlKHNlbGYub3B0cy5jYXB0aW9uKSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICBvYmoub3B0cy5jYXB0aW9uID0gc2VsZi5vcHRzLmNhcHRpb24uYXBwbHkoaXRlbSwgW3NlbGYsIG9ial0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGhhdmUgY2FwdGlvbiBhcyBhIHN0cmluZyBvciBqUXVlcnkgb2JqZWN0XHJcbiAgICAgICAgaWYgKCEob2JqLm9wdHMuY2FwdGlvbiBpbnN0YW5jZW9mICQpKSB7XHJcbiAgICAgICAgICBvYmoub3B0cy5jYXB0aW9uID0gb2JqLm9wdHMuY2FwdGlvbiA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IG9iai5vcHRzLmNhcHRpb24gKyBcIlwiO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgdXJsIGNvbnRhaW5zIFwiZmlsdGVyXCIgdXNlZCB0byBmaWx0ZXIgdGhlIGNvbnRlbnRcclxuICAgICAgICAvLyBFeGFtcGxlOiBcImFqYXguaHRtbCAjc29tZXRoaW5nXCJcclxuICAgICAgICBpZiAob2JqLnR5cGUgPT09IFwiYWpheFwiKSB7XHJcbiAgICAgICAgICBzcmNQYXJ0cyA9IHNyYy5zcGxpdCgvXFxzKy8sIDIpO1xyXG5cclxuICAgICAgICAgIGlmIChzcmNQYXJ0cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIG9iai5zcmMgPSBzcmNQYXJ0cy5zaGlmdCgpO1xyXG5cclxuICAgICAgICAgICAgb2JqLm9wdHMuZmlsdGVyID0gc3JjUGFydHMuc2hpZnQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEhpZGUgYWxsIGJ1dHRvbnMgYW5kIGRpc2FibGUgaW50ZXJhY3Rpdml0eSBmb3IgbW9kYWwgaXRlbXNcclxuICAgICAgICBpZiAob2JqLm9wdHMubW9kYWwpIHtcclxuICAgICAgICAgIG9iai5vcHRzID0gJC5leHRlbmQodHJ1ZSwgb2JqLm9wdHMsIHtcclxuICAgICAgICAgICAgdHJhcEZvY3VzOiB0cnVlLFxyXG4gICAgICAgICAgICAvLyBSZW1vdmUgYnV0dG9uc1xyXG4gICAgICAgICAgICBpbmZvYmFyOiAwLFxyXG4gICAgICAgICAgICB0b29sYmFyOiAwLFxyXG5cclxuICAgICAgICAgICAgc21hbGxCdG46IDAsXHJcblxyXG4gICAgICAgICAgICAvLyBEaXNhYmxlIGtleWJvYXJkIG5hdmlnYXRpb25cclxuICAgICAgICAgICAga2V5Ym9hcmQ6IDAsXHJcblxyXG4gICAgICAgICAgICAvLyBEaXNhYmxlIHNvbWUgbW9kdWxlc1xyXG4gICAgICAgICAgICBzbGlkZVNob3c6IDAsXHJcbiAgICAgICAgICAgIGZ1bGxTY3JlZW46IDAsXHJcbiAgICAgICAgICAgIHRodW1iczogMCxcclxuICAgICAgICAgICAgdG91Y2g6IDAsXHJcblxyXG4gICAgICAgICAgICAvLyBEaXNhYmxlIGNsaWNrIGV2ZW50IGhhbmRsZXJzXHJcbiAgICAgICAgICAgIGNsaWNrQ29udGVudDogZmFsc2UsXHJcbiAgICAgICAgICAgIGNsaWNrU2xpZGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBjbGlja091dHNpZGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBkYmxjbGlja0NvbnRlbnQ6IGZhbHNlLFxyXG4gICAgICAgICAgICBkYmxjbGlja1NsaWRlOiBmYWxzZSxcclxuICAgICAgICAgICAgZGJsY2xpY2tPdXRzaWRlOiBmYWxzZVxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTdGVwIDQgLSBBZGQgcHJvY2Vzc2VkIG9iamVjdCB0byBncm91cFxyXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgICAgI
109HNlbGYuZ3JvdXAucHVzaChvYmopO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIFVwZGF0ZSBjb250cm9scyBpZiBnYWxsZXJ5IGlzIGFscmVhZHkgb3BlbmVkXHJcbiAgICAgIGlmIChPYmplY3Qua2V5cyhzZWxmLnNsaWRlcykubGVuZ3RoKSB7XHJcbiAgICAgICAgc2VsZi51cGRhdGVDb250cm9scygpO1xyXG5cclxuICAgICAgICAvLyBVcGRhdGUgdGh1bWJuYWlscywgaWYgbmVlZGVkXHJcbiAgICAgICAgdGh1bWJzID0gc2VsZi5UaHVtYnM7XHJcblxyXG4gICAgICAgIGlmICh0aHVtYnMgJiYgdGh1bWJzLmlzQWN0aXZlKSB7XHJcbiAgICAgICAgICB0aHVtYnMuY3JlYXRlKCk7XHJcblxyXG4gICAgICAgICAgdGh1bWJzLmZvY3VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIEF0dGFjaCBhbiBldmVudCBoYW5kbGVyIGZ1bmN0aW9ucyBmb3I6XHJcbiAgICAvLyAgIC0gbmF2aWdhdGlvbiBidXR0b25zXHJcbiAgICAvLyAgIC0gYnJvd3NlciBzY3JvbGxpbmcsIHJlc2l6aW5nO1xyXG4gICAgLy8gICAtIGZvY3VzaW5nXHJcbiAgICAvLyAgIC0ga2V5Ym9hcmRcclxuICAgIC8vICAgLSBkZXRlY3RpbmcgaW5hY3Rpdml0eVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBhZGRFdmVudHM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgc2VsZi5yZW1vdmVFdmVudHMoKTtcclxuXHJcbiAgICAgIC8vIE1ha2UgbmF2aWdhdGlvbiBlbGVtZW50cyBjbGlja2FibGVcclxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgICAgc2VsZi4kcmVmcy5jb250YWluZXJcclxuICAgICAgICAub24oXCJjbGljay5mYi1jbG9zZVwiLCBcIltkYXRhLWZhbmN5Ym94LWNsb3NlXVwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBzZWxmLmNsb3NlKGUpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKFwidG91Y2hzdGFydC5mYi1wcmV2IGNsaWNrLmZiLXByZXZcIiwgXCJbZGF0YS1mYW5jeWJveC1wcmV2XVwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBzZWxmLnByZXZpb3VzKCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oXCJ0b3VjaHN0YXJ0LmZiLW5leHQgY2xpY2suZmItbmV4dFwiLCBcIltkYXRhLWZhbmN5Ym94LW5leHRdXCIsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAgIHNlbGYubmV4dCgpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKFwiY2xpY2suZmJcIiwgXCJbZGF0YS1mYW5jeWJveC16b29tXVwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgLy8gQ2xpY2sgaGFuZGxlciBmb3Igem9vbSBidXR0b25cclxuICAgICAgICAgIHNlbGZbc2VsZi5pc1NjYWxlZERvd24oKSA/IFwic2NhbGVUb0FjdHVhbFwiIDogXCJzY2FsZVRvRml0XCJdKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBIYW5kbGUgcGFnZSBzY3JvbGxpbmcgYW5kIGJyb3dzZXIgcmVzaXppbmdcclxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgICAkVy5vbihcIm9yaWVudGF0aW9uY2hhbmdlLmZiIHJlc2l6ZS5mYlwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGlmIChlICYmIGUub3JpZ2luYWxFdmVudCAmJiBlLm9yaWdpbmFsRXZlbnQudHlwZSA9PT0gXCJyZXNpemVcIikge1xyXG4gICAgICAgICAgaWYgKHNlbGYucmVxdWVzdElkKSB7XHJcbiAgICAgICAgICAgIGNhbmNlbEFGcmFtZShzZWxmLnJlcXVlc3RJZCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgc2VsZi5yZXF1ZXN0SWQgPSByZXF1ZXN0QUZyYW1lKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgc2VsZi51cGRhdGUoZSk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKHNlbGYuY3VycmVudCAmJiBzZWxmLmN1cnJlbnQudHlwZSA9PT0gXCJpZnJhbWVcIikge1xyXG4gICAgICAgICAgICBzZWxmLiRyZWZzLnN0YWdlLmhpZGUoKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzZXRUaW1lb3V0KFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgc2VsZi4kcmVmcy5zdGFnZS5zaG93KCk7XHJcblxyXG4gICAgICAgICAgICAgIHNlbGYudXBkYXRlKGUpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAkLmZhbmN5Ym94LmlzTW9iaWxlID8gNjAwIDogMjUwXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICAkRC5vbihcImtleWRvd24uZmJcIiwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICB2Y
109XIgaW5zdGFuY2UgPSAkLmZhbmN5Ym94ID8gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpIDogbnVsbCxcclxuICAgICAgICAgIGN1cnJlbnQgPSBpbnN0YW5jZS5jdXJyZW50LFxyXG4gICAgICAgICAga2V5Y29kZSA9IGUua2V5Q29kZSB8fCBlLndoaWNoO1xyXG5cclxuICAgICAgICAvLyBUcmFwIGtleWJvYXJkIGZvY3VzIGluc2lkZSBvZiB0aGUgbW9kYWxcclxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICAgICAgaWYgKGtleWNvZGUgPT0gOSkge1xyXG4gICAgICAgICAgaWYgKGN1cnJlbnQub3B0cy50cmFwRm9jdXMpIHtcclxuICAgICAgICAgICAgc2VsZi5mb2N1cyhlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBFbmFibGUga2V5Ym9hcmQgbmF2aWdhdGlvblxyXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgICAgIGlmICghY3VycmVudC5vcHRzLmtleWJvYXJkIHx8IGUuY3RybEtleSB8fCBlLmFsdEtleSB8fCBlLnNoaWZ0S2V5IHx8ICQoZS50YXJnZXQpLmlzKFwiaW5wdXQsdGV4dGFyZWEsdmlkZW8sYXVkaW8sc2VsZWN0XCIpKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBCYWNrc3BhY2UgYW5kIEVzYyBrZXlzXHJcbiAgICAgICAgaWYgKGtleWNvZGUgPT09IDggfHwga2V5Y29kZSA9PT0gMjcpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBzZWxmLmNsb3NlKGUpO1xyXG5cclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIExlZnQgYXJyb3cgYW5kIFVwIGFycm93XHJcbiAgICAgICAgaWYgKGtleWNvZGUgPT09IDM3IHx8IGtleWNvZGUgPT09IDM4KSB7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgICAgc2VsZi5wcmV2aW91cygpO1xyXG5cclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJpZ2ggYXJyb3cgYW5kIERvd24gYXJyb3dcclxuICAgICAgICBpZiAoa2V5Y29kZSA9PT0gMzkgfHwga2V5Y29kZSA9PT0gNDApIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBzZWxmLm5leHQoKTtcclxuXHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLnRyaWdnZXIoXCJhZnRlcktleWRvd25cIiwgZSwga2V5Y29kZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gSGlkZSBjb250cm9scyBhZnRlciBzb21lIGluYWN0aXZpdHkgcGVyaW9kXHJcbiAgICAgIGlmIChzZWxmLmdyb3VwW3NlbGYuY3VyckluZGV4XS5vcHRzLmlkbGVUaW1lKSB7XHJcbiAgICAgICAgc2VsZi5pZGxlU2Vjb25kc0NvdW50ZXIgPSAwO1xyXG5cclxuICAgICAgICAkRC5vbihcclxuICAgICAgICAgIFwibW91c2Vtb3ZlLmZiLWlkbGUgbW91c2VsZWF2ZS5mYi1pZGxlIG1vdXNlZG93bi5mYi1pZGxlIHRvdWNoc3RhcnQuZmItaWRsZSB0b3VjaG1vdmUuZmItaWRsZSBzY3JvbGwuZmItaWRsZSBrZXlkb3duLmZiLWlkbGVcIixcclxuICAgICAgICAgIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaWRsZVNlY29uZHNDb3VudGVyID0gMDtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZWxmLmlzSWRsZSkge1xyXG4gICAgICAgICAgICAgIHNlbGYuc2hvd0NvbnRyb2xzKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHNlbGYuaXNJZGxlID0gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgc2VsZi5pZGxlSW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi5pZGxlU2Vjb25kc0NvdW50ZXIrKztcclxuXHJcbiAgICAgICAgICBpZiAoc2VsZi5pZGxlU2Vjb25kc0NvdW50ZXIgPj0gc2VsZi5ncm91cFtzZWxmLmN1cnJJbmRleF0ub3B0cy5pZGxlVGltZSAmJiAhc2VsZi5pc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaXNJZGxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VsZi5pZGxlU2Vjb25kc0NvdW50ZXIgPSAwO1xyXG5cclxuICAgICAgICAgICAgc2VsZi5oaWRlQ29udHJvbHMoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LCAxMDAwKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBSZW1vdmUgZXZlbnRzIGFkZGVkIGJ5IHRoZSBjb3JlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgcmVtb3ZlRXZlbnRzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgICRXLm9mZihcIm9yaWVudGF0aW9uY2hhbmdlLmZiIHJlc2l6ZS5mYlwiKTtcclxuICAgICAgJEQub2ZmKFwia2V5ZG93bi5mYiAuZmItaWRsZVwiKTtcclxuXHJcbiAgICAgIHRoaXMuJHJlZnMuY29udGFpbmVyLm9mZihcIi5mYi1jbG9zZSAuZmItcHJldiAuZmItbmV4dFwiKTtcclxuXHJcbiAgICAgIGlmIChzZWxmLmlkbGVJbnRlcnZhbCkge1xyXG4gICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHNlbGYuaWRsZUludGVydmFsKTtcclxuXHJcbiAgICAgICAgc2VsZi5pZGxlSW50ZXJ2YWwgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENoYW5nZSB0byBwcmV2aW91cyBnYWxsZXJ5IGl0ZW1cclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBwcmV2aW91czogZnVuY3Rpb24gKGR1cmF0aW9uKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmp1bXBUbyh0aGlzLmN1cnJQb3MgLSAxLCBkdXJhdGlvbik7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENoYW5nZSB0byBuZXh0IGdhbGxlcnkgaXRlbVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgbmV4dDogZnVuY3Rpb24gKGR1cmF0aW9uKSB7XHJcbiAgICAgIHJldHVybi
109B0aGlzLmp1bXBUbyh0aGlzLmN1cnJQb3MgKyAxLCBkdXJhdGlvbik7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFN3aXRjaCB0byBzZWxlY3RlZCBnYWxsZXJ5IGl0ZW1cclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBqdW1wVG86IGZ1bmN0aW9uIChwb3MsIGR1cmF0aW9uKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBncm91cExlbiA9IHNlbGYuZ3JvdXAubGVuZ3RoLFxyXG4gICAgICAgIGZpcnN0UnVuLFxyXG4gICAgICAgIGlzTW92ZWQsXHJcbiAgICAgICAgbG9vcCxcclxuICAgICAgICBjdXJyZW50LFxyXG4gICAgICAgIHByZXZpb3VzLFxyXG4gICAgICAgIHNsaWRlUG9zLFxyXG4gICAgICAgIHN0YWdlUG9zLFxyXG4gICAgICAgIHByb3AsXHJcbiAgICAgICAgZGlmZjtcclxuXHJcbiAgICAgIGlmIChzZWxmLmlzRHJhZ2dpbmcgfHwgc2VsZi5pc0Nsb3NpbmcgfHwgKHNlbGYuaXNBbmltYXRpbmcgJiYgc2VsZi5maXJzdFJ1bikpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFNob3VsZCBsb29wP1xyXG4gICAgICBwb3MgPSBwYXJzZUludChwb3MsIDEwKTtcclxuICAgICAgbG9vcCA9IHNlbGYuY3VycmVudCA/IHNlbGYuY3VycmVudC5vcHRzLmxvb3AgOiBzZWxmLm9wdHMubG9vcDtcclxuXHJcbiAgICAgIGlmICghbG9vcCAmJiAocG9zIDwgMCB8fCBwb3MgPj0gZ3JvdXBMZW4pKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDaGVjayBpZiBvcGVuaW5nIGZvciB0aGUgZmlyc3QgdGltZTsgdGhpcyBoZWxwcyB0byBzcGVlZCB0aGluZ3MgdXBcclxuICAgICAgZmlyc3RSdW4gPSBzZWxmLmZpcnN0UnVuID0gIU9iamVjdC5rZXlzKHNlbGYuc2xpZGVzKS5sZW5ndGg7XHJcblxyXG4gICAgICAvLyBDcmVhdGUgc2xpZGVzXHJcbiAgICAgIHByZXZpb3VzID0gc2VsZi5jdXJyZW50O1xyXG5cclxuICAgICAgc2VsZi5wcmV2SW5kZXggPSBzZWxmLmN1cnJJbmRleDtcclxuICAgICAgc2VsZi5wcmV2UG9zID0gc2VsZi5jdXJyUG9zO1xyXG5cclxuICAgICAgY3VycmVudCA9IHNlbGYuY3JlYXRlU2xpZGUocG9zKTtcclxuXHJcbiAgICAgIGlmIChncm91cExlbiA+IDEpIHtcclxuICAgICAgICBpZiAobG9vcCB8fCBjdXJyZW50LmluZGV4IDwgZ3JvdXBMZW4gLSAxKSB7XHJcbiAgICAgICAgICBzZWxmLmNyZWF0ZVNsaWRlKHBvcyArIDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGxvb3AgfHwgY3VycmVudC5pbmRleCA+IDApIHtcclxuICAgICAgICAgIHNlbGYuY3JlYXRlU2xpZGUocG9zIC0gMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLmN1cnJlbnQgPSBjdXJyZW50O1xyXG4gICAgICBzZWxmLmN1cnJJbmRleCA9IGN1cnJlbnQuaW5kZXg7XHJcbiAgICAgIHNlbGYuY3VyclBvcyA9IGN1cnJlbnQucG9zO1xyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKFwiYmVmb3JlU2hvd1wiLCBmaXJzdFJ1bik7XHJcblxyXG4gICAgICBzZWxmLnVwZGF0ZUNvbnRyb2xzKCk7XHJcblxyXG4gICAgICAvLyBWYWxpZGF0ZSBkdXJhdGlvbiBsZW5ndGhcclxuICAgICAgY3VycmVudC5mb3JjZWREdXJhdGlvbiA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIGlmICgkLmlzTnVtZXJpYyhkdXJhdGlvbikpIHtcclxuICAgICAgICBjdXJyZW50LmZvcmNlZER1cmF0aW9uID0gZHVyYXRpb247XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZHVyYXRpb24gPSBjdXJyZW50Lm9wdHNbZmlyc3RSdW4gPyBcImFuaW1hdGlvbkR1cmF0aW9uXCIgOiBcInRyYW5zaXRpb25EdXJhdGlvblwiXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZHVyYXRpb24gPSBwYXJzZUludChkdXJhdGlvbiwgMTApO1xyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgdXNlciBoYXMgc3dpcGVkIHRoZSBzbGlkZXMgb3IgaWYgc3RpbGwgYW5pbWF0aW5nXHJcbiAgICAgIGlzTW92ZWQgPSBzZWxmLmlzTW92ZWQoY3VycmVudCk7XHJcblxyXG4gICAgICAvLyBNYWtlIHN1cmUgY3VycmVudCBzbGlkZSBpcyB2aXNpYmxlXHJcbiAgICAgIGN1cnJlbnQuJHNsaWRlLmFkZENsYXNzKFwiZmFuY3lib3gtc2xpZGUtLWN1cnJlbnRcIik7XHJcblxyXG4gICAgICAvLyBGcmVzaCBzdGFydCAtIHJldmVhbCBjb250YWluZXIsIGN1cnJlbnQgc2xpZGUgYW5kIHN0YXJ0IGxvYWRpbmcgY29udGVudFxyXG4gICAgICBpZiAoZmlyc3RSdW4pIHtcclxuICAgICAgICBpZiAoY3VycmVudC5vcHRzLmFuaW1hdGlvbkVmZmVjdCAmJiBkdXJhdGlvbikge1xyXG4gICAgICAgICAgc2VsZi4kcmVmcy5jb250YWluZXIuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLCBkdXJhdGlvbiArIFwibXNcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLiRyZWZzLmNvbnRhaW5lci5hZGRDbGFzcyhcImZhbmN5Ym94LWlzLW9wZW5cIikudHJpZ2dlcihcImZvY3VzXCIpO1xyXG5cclxuICAgICAgICAvLyBBdHRlbXB0IHRvIGxvYWQgY29udGVudCBpbnRvIHNsaWRlXHJcbiAgICAgICAgLy8gVGhpcyB3aWxsIGxhdGVyIGNhbGwgYGFmdGVyTG9hZGAgLT4gYHJldmVhbENvbnRlbnRgXHJcbiAgICAgICAgc2VsZi5sb2FkU2xpZGUoY3VycmVudCk7XHJcblxyXG4gICAgICAgIHNlbGYucHJlbG9hZChcImltYWdlXCIpO1xyXG5cclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEdldCBhY3R1YWwgc2xpZGUvc3RhZ2UgcG9zaXRpb25zIChiZWZvcmUgY2xlYW5pbmcgdXApXHJcbiAgICAgIHNsaWRlUG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUocHJldmlvdXMuJHNsaWRlKTtcclxuICAgICAgc3RhZ2VQb3MgPSAkLmZhbmN5Ym94LmdldFRyYW5zbGF0ZShzZWxmLiRyZWZzLnN0YWdlKTtcclxuXHJcbiAgICAgIC8vIENsZWFuIHVwIGFsbCBzbGlkZXNcclxuICAgICAgJC5lYWNoKHNlbGYuc2xpZGVzLCBmdW5jdGlvbiAoaW5kZXgsIHNsaWRlKSB7XHJcbiAgICAgICAgJC5mYW5jeWJveC5zdG9wKHNsaWRlLiRzbGlkZSwgdHJ1ZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKHByZXZpb3VzLnBvcyAhPT0gY3VycmVudC5wb3MpIHtcclxuICAgICAgICBwcmV2aW91cy5pc0NvbXBsZXRlID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHByZXZpb3VzLiRzbGlkZS5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1jb21wbGV0ZSBmYW5jeWJveC1zbGlkZS0tY3VycmVudFwiKTtcclxuXHJcbiAgICAgIC8vIElmIHNsaWRlcyBhcmUgb3V0IG9mIHBsYWNlLCB0aGVuIGFuaW1hdGUgdGhlbSB0byBjb3JyZWN0IHBvc2l0aW9uXHJcbiAgICAgIGlmIChpc01vdmVkKSB7XHJcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGhvcml6b250YWwgc3dpcGUgZGlzdGFuY2VcclxuICAgICAgICBkaWZmID0gc2xpZGVQb3MubGVmdCAtIChwcmV2aW91cy5wb3MgKiBzbGlkZVBvcy53aWR0aCArIHByZXZpb3VzLnBvcyAqIHByZXZpb3VzLm9wdHMuZ3V0dGVyKTtcclxuXHJcbiAgICAgICAgJC5lYWNoKHNlbGYuc2xpZGVzLCBmdW5jdGlvbiAoaW5kZXgsIHNsaWRlKSB7XHJcbiAgICAgICAgICBzbGlkZS4kc2xpZGUucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1hbmltYXRlZFwiKS5yZW1vdmVDbGFzcyhmdW5jdGlvbiAoaW5kZXgsIGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gKGNsYXNzTmFtZS5tYXRjaCgvKF58XFxzKWZhbmN5Ym94LWZ4LVxcUysvZykgfHwgW10pLmpvaW4oXCIgXCIpO1xyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgZWFjaCBzbGlkZSBpcyBpbiBlcXVhbCBkaXN0YW5jZVxyXG4gICAgICAgICAgLy8gVGhpcyBpcyBtb3N0bHkgbmVlZGVkIGZvciBmcmVzaGx5IGFkZGVkIHNsaWRlcywgYmVjYXVzZSB0aGV5IGFyZSBub3QgeWV0IHBvc2l0aW9uZWRcclxuICAgICAgICAgI
109HZhciBsZWZ0UG9zID0gc2xpZGUucG9zICogc2xpZGVQb3Mud2lkdGggKyBzbGlkZS5wb3MgKiBzbGlkZS5vcHRzLmd1dHRlcjtcclxuXHJcbiAgICAgICAgICAkLmZhbmN5Ym94LnNldFRyYW5zbGF0ZShzbGlkZS4kc2xpZGUsIHtcclxuICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICBsZWZ0OiBsZWZ0UG9zIC0gc3RhZ2VQb3MubGVmdCArIGRpZmZcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIGlmIChzbGlkZS5wb3MgIT09IGN1cnJlbnQucG9zKSB7XHJcbiAgICAgICAgICAgIHNsaWRlLiRzbGlkZS5hZGRDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1cIiArIChzbGlkZS5wb3MgPiBjdXJyZW50LnBvcyA/IFwibmV4dFwiIDogXCJwcmV2aW91c1wiKSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy8gUmVkcmF3IHRvIG1ha2Ugc3VyZSB0aGF0IHRyYW5zaXRpb24gd2lsbCBzdGFydFxyXG4gICAgICAgICAgZm9yY2VSZWRyYXcoc2xpZGUuJHNsaWRlKTtcclxuXHJcbiAgICAgICAgICAvLyBBbmltYXRlIHRoZSBzbGlkZVxyXG4gICAgICAgICAgJC5mYW5jeWJveC5hbmltYXRlKFxyXG4gICAgICAgICAgICBzbGlkZS4kc2xpZGUsIHtcclxuICAgICAgICAgICAgICB0b3A6IDAsXHJcbiAgICAgICAgICAgICAgbGVmdDogKHNsaWRlLnBvcyAtIGN1cnJlbnQucG9zKSAqIHNsaWRlUG9zLndpZHRoICsgKHNsaWRlLnBvcyAtIGN1cnJlbnQucG9zKSAqIHNsaWRlLm9wdHMuZ3V0dGVyXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGR1cmF0aW9uLFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgc2xpZGUuJHNsaWRlXHJcbiAgICAgICAgICAgICAgICAuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBcIlwiLFxyXG4gICAgICAgICAgICAgICAgICBvcGFjaXR5OiBcIlwiXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtc2xpZGUtLW5leHQgZmFuY3lib3gtc2xpZGUtLXByZXZpb3VzXCIpO1xyXG5cclxuICAgICAgICAgICAgICBpZiAoc2xpZGUucG9zID09PSBzZWxmLmN1cnJQb3MpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoZHVyYXRpb24gJiYgY3VycmVudC5vcHRzLnRyYW5zaXRpb25FZmZlY3QpIHtcclxuICAgICAgICAvLyBTZXQgdHJhbnNpdGlvbiBlZmZlY3QgZm9yIHByZXZpb3VzbHkgYWN0aXZlIHNsaWRlXHJcbiAgICAgICAgcHJvcCA9IFwiZmFuY3lib3gtYW5pbWF0ZWQgZmFuY3lib3gtZngtXCIgKyBjdXJyZW50Lm9wdHMudHJhbnNpdGlvbkVmZmVjdDtcclxuXHJcbiAgICAgICAgcHJldmlvdXMuJHNsaWRlLmFkZENsYXNzKFwiZmFuY3lib3gtc2xpZGUtLVwiICsgKHByZXZpb3VzLnBvcyA+IGN1cnJlbnQucG9zID8gXCJuZXh0XCIgOiBcInByZXZpb3VzXCIpKTtcclxuXHJcbiAgICAgICAgJC5mYW5jeWJveC5hbmltYXRlKFxyXG4gICAgICAgICAgcHJldmlvdXMuJHNsaWRlLFxyXG4gICAgICAgICAgcHJvcCxcclxuICAgICAgICAgIGR1cmF0aW9uLFxyXG4gICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBwcmV2aW91cy4kc2xpZGUucmVtb3ZlQ2xhc3MocHJvcCkucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1zbGlkZS0tbmV4dCBmYW5jeWJveC1zbGlkZS0tcHJldmlvdXNcIik7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgZmFsc2VcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoY3VycmVudC5pc0xvYWRlZCkge1xyXG4gICAgICAgIHNlbGYucmV2ZWFsQ29udGVudChjdXJyZW50KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzZWxmLmxvYWRTbGlkZShjdXJyZW50KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi5wcmVsb2FkKFwiaW1hZ2VcIik7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENyZWF0ZSBuZXcgXCJzbGlkZVwiIGVsZW1lbnRcclxuICAgIC8vIFRoZXNlIGFyZSBnYWxsZXJ5IGl0ZW1zICB0aGF0IGFyZSBhY3R1YWxseSBhZGRlZCB0byBET01cclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBjcmVhdGVTbGlkZTogZnVuY3Rpb24gKHBvcykge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgJHNsaWRlLFxyXG4gICAgICAgIGluZGV4O1xyXG5cclxuICAgICAgaW5kZXggPSBwb3MgJSBzZWxmLmdyb3VwLmxlbmd0aDtcclxuICAgICAgaW5kZXggPSBpbmRleCA8IDAgPyBzZWxmLmdyb3VwLmxlbmd0aCArIGluZGV4IDogaW5kZXg7XHJcblxyXG4gICAgICBpZiAoIXNlbGYuc2xpZGVzW3Bvc10gJiYgc2VsZi5ncm91cFtpbmRleF0pIHtcclxuICAgICAgICAkc2xpZGUgPSAkKCc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtc2xpZGVcIj48L2Rpdj4nKS5hcHBlbmRUbyhzZWxmLiRyZWZzLnN0YWdlKTtcclxuXHJcbiAgICAgICAgc2VsZi5zbGlkZXNbcG9zXSA9ICQuZXh0ZW5kKHRydWUsIHt9LCBzZWxmLmdyb3VwW2luZGV4XSwge1xyXG4gICAgICAgICAgcG9zOiBwb3MsXHJcbiAgICAgICAgICAkc2xpZGU6ICRzbGlkZSxcclxuICAgICAgICAgIGlzTG9hZGVkOiBmYWxzZVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBzZWxmLnVwZGF0ZVNsaWRlKHNlbGYuc2xpZGVzW3Bvc10pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc2VsZi5zbGlkZXNbcG9zXTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gU2NhbGUgaW1hZ2UgdG8gdGhlIGFjdHVhbCBzaXplIG9mIHRoZSBpbWFnZTtcclxuICAgIC8vIHggYW5kIHkgdmFsdWVzIHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGUgc2xpZGVcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBzY2FsZVRvQWN0dWFsOiBmdW5jdGlvbiAoeCwgeSwgZHVyYXRpb24pIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGN1cnJlbnQgPSBzZWxmLmN1cnJlbnQsXHJcbiAgICAgICAgJGNvbnRlbnQgPSBjdXJyZW50LiRjb250ZW50LFxyXG4gICAgICAgIGNhbnZhc1dpZHRoID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoY3VycmVudC4kc2xpZGUpLndpZHRoLFxyXG4gICAgICAgIGNhbnZhc0hlaWdodCA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKGN1cnJlbnQuJHNsaWRlKS5oZWlnaHQsXHJcbiAgICAgICAgbmV3SW1nV2lkdGggPSBjdXJyZW50LndpZHRoLFxyXG4gICAgICAgIG5ld0ltZ0hlaWdodCA9IGN1cnJlbnQuaGVpZ2h0LFxyXG4gICAgICAgIGltZ1BvcyxcclxuICAgICAgICBwb3NYLFxyXG4gICAgICAgIHBvc1ksXHJcbiAgICAgICAgc2NhbGVYLFxyXG4gICAgICAgIHNjYWxlWTtcclxuXHJcbiAgICAgIGlmIChzZWxmLmlzQW5pbWF0aW5nIHx8IHNlbGYuaXNNb3ZlZCgpIHx8ICEkY29udGVudCB8fCAhKGN1cnJlbnQudHlwZSA9PSBcImltYWdlXCIgJiYgY3VycmVudC5pc0xvYWRlZCAmJiAhY3VycmVudC5oYXNFcnJvcikpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYuaXNBbmltYXRpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgJC5mYW5jeWJveC5zdG9wKCRjb250ZW50KTtcclxuXHJcbiAgICAgIHggPSB4ID09PSB1bmRlZmluZWQgPyBjYW52YXNXaWR0aCAqIDAuNSA6IHg7XHJcbiAgICAgIHkgPSB5ID09PSB1bmRlZmluZWQgPyBjYW52YXNIZWlnaHQgKiAwLjUgOiB5O1xyXG5cclxuICAgICAgaW1nUG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoJGNvbnRlbnQpO1xyXG5cclxuICAgICAgaW1nUG9zLnRvcCAtPSAkLmZhbmN5Ym94LmdldFRyYW5zbGF0ZShjdXJyZW50LiRzbGlkZSkudG9wO1xyXG4gICAgICBpbWdQb3MubGVmdCAtPSAkLmZhbmN5Ym94LmdldFRyYW5zbGF0ZShjdXJyZW50LiRzbGlkZSkubGVmdDtcclxuXHJcbiAgICAgIHNjYWxlWCA9IG5ld0ltZ1dpZHRoIC8gaW1nUG9zLndpZHRoO1xyXG4gICAgICBzY2FsZVkgPSBuZXdJbWdIZWlnaHQgLyBpbWdQb3MuaGVpZ2h0O1xyXG5cclxuICAgICAgLy8gR2V0IGNlbnRlciBwb3NpdGlvbiBmb3Igb3JpZ2luYWwgaW1hZ2VcclxuICAgICAgcG9zWCA9IGNhbnZhc1dpZHRoICogMC41IC0gbmV3SW1nV2lkdGggKiAwLjU7XHJcbiAgICAgIHBvc1kgPSBjYW52YXNIZWlnaHQgKiAwLjUgLSBuZXdJbWdIZWlnaHQgKiAwLjU7XHJcblxyXG4gICAgICAvLyBNYWtlIHN1cmUgaW1hZ2UgZG9lcyBub3QgbW92ZSBhd2F5IGZyb20gZWRnZXNcclxuICAgICAgaWYgKG5ld0ltZ1dpZHRoID4gY2FudmFzV2lkdGgpIHtcclxuICAgICAgICBwb3NYID0gaW1nUG9zLmxlZnQgKiBzY2FsZVggLSAoeCAqIHNjYWxlWCAtIHgpO1xyXG5cclxuICAgICAgICBpZiAocG9zWCA+IDApIHtcclxuICAgICAgICAgIHBvc1ggPSAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvc1ggPCBjYW52YXNXaWR0aCAtIG5ld0ltZ1dpZHRoKSB7XHJcbiAgICAgICAgICBwb3NYID0gY2FudmFzV2lkdGggLSBuZXdJbWdXaWR0aDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChuZXdJbWdIZWlnaHQgPiBjYW52YXNIZWlnaHQpIHtcclxuICAgICAgICBwb3NZID0gaW1nUG9zLnRvcCAqIHNjYWxlWSAtICh5ICogc2NhbGVZIC0geSk7XHJcblxyXG4gICAgICAgIGlmIChwb3NZID4gMCkge1xyXG4gICAgICAgICAgcG9zWSA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocG9zWSA8IGNhbnZhc0hlaWdodCAtIG5ld0ltZ0hlaWdodCkge1xyXG4gICAgICAgICAgcG9zWSA9IGNhbnZhc0hlaWdodCAtIG5ld0ltZ0hlaWdodDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYudXBkYXRlQ3Vyc29yKG5ld0ltZ1dpZHRoLCBuZXdJbWdIZWlnaHQpO1xyXG5cclxuICAgICAgJC5mYW5jeWJveC5hbmltYXRlKFxyXG4gICAgICAgICRjb250ZW50LCB7XHJcbiAgICAgICAgICB0b3A6IHBvc1ksXHJcbiAgICAgICAgICBsZWZ0OiBwb3NYLFxyXG4gICAgICAgICAgc2NhbGVYOiBzY2FsZVgsXHJcbiAgICAgICAgICBzY2FsZVk6IHNjYWxlWVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZHVyYXRpb24gfHwgMzY2LFxyXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYuaXNBbmltYXRpbmcgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBTdG9wIHNsaWRlc2hvd1xyXG4gICAgICBpZiAoc2VsZi5TbGlkZVNob3cgJiYgc2VsZi5TbGlkZVNob3cuaXNBY3RpdmUpIHtcclxuICAgICAgICBzZWxmLlNsaWRlU2hvdy5zdG9wKCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gU2NhbGUgaW1hZ2UgdG8gZml0IGluc2lkZSBwYXJlbnQgZWxlbWVudFxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHNjYWxlVG9GaXQ6IGZ1bmN0aW9uIChkdXJhdGlvbikge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuY3VycmVudCxcclxuICAgICAgICAkY29udGVudCA9IGN1cnJlbnQuJGNvbnRlbnQsXHJcbiAgICAgICAgZW5kO1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNBbmltYXRpbmcgfHwgc2VsZi5pc01vdmVkKCkgfHwgISRjb250ZW50IHx8ICEoY3VycmVudC50eXBlID09IFwiaW1hZ2VcIiAmJiBjdXJyZW50LmlzTG9hZGVkICYmICFjdXJyZW50Lmhhc0Vycm9yKSkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi5pc0FuaW1hdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAkLmZhbmN5Ym94LnN0b3AoJGNvbnRlbnQpO1xyXG5cclxuICAgICAgZW5kID0gc2VsZi5nZXRGaXRQb3MoY3VycmVudCk7XHJcblxyXG4gICAgICBzZWxmLnVwZGF0ZUN1cnNvcihlbmQud2lkdGgsIGVuZC5oZWlnaHQpO1xyXG5cclxuICAgICAgJC5mYW5jeWJveC5hbmltYXRlKFxyXG4gICAgICAgICRjb250ZW50LCB7XHJcbiAgICAgICAgICB0b3A6IGVuZC50b3AsXHJcbiAgICAgICAgICBsZWZ0OiBlbmQubGVmdCxcclxuICAgICAgICAgIHNjYWxlWDogZW5kLndpZHRoIC8gJGNvbnRlbnQud2lkdGgoKSxcclxuICAgICAgICAgIHNjYWxlWTogZW5kLmhlaWdodCAvICRjb250ZW50LmhlaWdodCgpXHJcbiAgICAgICAgfSxcclxuICAgICAgICBkdXJhdGlvbiB8fCAzNjYsXHJcbiAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi5pc0FuaW1hdGluZyA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIGltYWdlIHNpemUgdG8gZml0IGluc2lkZSB2aWV3cG9ydFxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGdldEZpdFBvczogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAkY29udGVudCA9IHNsaWRlLiRjb250ZW50LFxyXG4gICAgICAgICRzbGlkZSA9IHNsaWRlLiRzbGlkZSxcclxuICAgICAgICB3aWR0aCA9IHNsaWRlLndpZHRoIHx8IHNsaWRlLm9wdHMud2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0ID0gc2xpZGUuaGVpZ2h0IHx8IHNsaWRlLm9wdHMuaGVpZ2h0LFxyXG4gICAgICAgIG1heFdpZHRoLFxyXG4gICAgICAgIG1heEhlaWdodCxcclxuICAgICAgICBtaW5SYXRpbyxcclxuICAgICAgICBhc3BlY3RSYXRpbyxcclxuICAgICAgICByZXogPSB7fTtcclxuXHJcbiAgICAgIGlmICghc2xpZGUuaXNMb2FkZWQgfHwgISRjb250ZW50IHx8ICEkY29udGVudC5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIG1heFdpZHRoID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoc2VsZi4kcmVmcy5zdGFnZSkud2lkdGg7XHJcbiAgICAgIG1heEhlaWdodCA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKHNlbGYuJHJlZnMuc3RhZ2UpLmhlaWdodDtcclxuXHJcbiAgICAgIG1heFdpZHRoIC09XHJcbiAgICAgICAgcGFyc2VGbG9hdCgkc2xpZGUuY3NzKFwicGFkZGluZ0xlZnRcIikpICtcclxuICAgICAgICBwYXJzZUZsb2F0KCRzbGlkZS5jc3MoXCJwYWRkaW5nUmlnaHRcIikpICtcclxuICAgICAgICBwYXJzZUZsb2F0KCRjb250ZW50LmNzcyhcIm1hcmdpbkxlZnRcIikpICtcclxuICAgICAgICBwYXJzZUZsb2F0KCRjb250ZW50LmNzcyhcIm1hcmdpblJpZ2h0XCIpKTtcclxuXHJcbiAgICAgIG1heEhlaWdodCAtPVxyXG4gICAgICAgIHBhcnNlRmxvYXQoJHNsaWRlLmNzcyhcInBhZGRpbmdUb3BcIikpICtcclxuICAgICAgICBwYXJzZUZsb2F0KCRzbGlkZS5jc3MoXCJwYWRkaW5nQm90dG9tXCIpKSArXHJcbiAgICAgICAgcGFyc2VGbG9hdCgkY29udGVudC5jc3MoXCJtYXJnaW5Ub3BcIikpICtcclxuICAgICAgICBwYXJzZUZsb2F0KCRjb250ZW50LmNzcyhcIm1hcmdpbkJvdHRvbVwiKSk7XHJcblxyXG4gICAgICBpZiAoIXdpZHRoIHx8ICFoZWlnaHQpIHtcclxuICAgICAgICB3aWR0aCA9IG1heFdpZHRoO1xyXG4gICAgICAgIGhlaWdodCA9IG1heEhlaWdodDtcclxuICAgICAgfVxyXG5cclxuICAgICAgbWluUmF0aW8gPSBNYXRoLm1pbigxLCBtYXhXaWR0aCAvIHdpZHRoLCBtYXhIZWlnaHQgLyBoZWlnaHQpO1xyXG5cclxuICAgICAgd2lkdGggPSBtaW5SYXRpbyAqIHdpZHRoO1xyXG4gICAgICBoZWlnaHQgPSBtaW5SYXRpbyAqIGhlaWdodDtcclxuXHJcbiAgICAgIC8vIEFkanVzdCB3aWR0aC9oZWlnaHQgdG8gcHJlY2lzZWx5IGZpdCBpbnRvIGNvbnRhaW5lclxyXG4gICAgICBpZiAod2lkdGggPiBtYXhXaWR0aCAtIDAuNSkge1xyXG4gICAgICAgIHdpZHRoID0gbWF4V2lkdGg7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChoZWlnaHQgPiBtYXhIZWlnaHQgLSAwLjUpIHtcclxuICAgICAgICBoZWlnaHQgPSBtYXhIZWlnaHQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzbGlkZS50eXBlID09PSBcImltYWdlXCIpIHtcclxuICAgICAgICByZXoudG9wID0gTWF0aC5mbG9vcigobWF4SGVpZ2h0IC0gaGVpZ2h0KSAqIDAuNSkgKyBwYXJzZUZsb2F0KCRzbGlkZS5jc3MoXCJwYWRkaW5nVG9wXCIpKTtcclxuICAgICAgICByZXoubGVmdCA9IE1hdGguZmxvb3IoKG1heFdpZHRoIC0gd2lkdGgpICogMC41KSArIHBhcnNlRmxvYXQoJHNsaWRlLmNzcyhcInBhZGRpbmdMZWZ0XCIpKTtcclxuICAgICAgfSBlbHNlIGlmIChzbGlkZS5jb250ZW50VHlwZSA9PT0gXCJ2aWRlb1wiKSB7XHJcbiAgICAgICAgLy8gRm9yY2UgYXNwZWN0IHJhdGlvIGZvciB0aGUgdmlkZW9cclxuICAgICAgICAvLyBcIkkgc2F5IHRoZSB3aG9sZSB3b3JsZCBtdXN0IGxlYXJuIG9mIG91ciBwZWFjZWZ1bCB3YXlz4oCmIGJ5IGZvcmNlIVwiXHJcbiAgICAgICAgYXNwZWN0UmF0aW8gPSBzbGlkZS5vcHRzLndpZHRoICYmIHNsaWRlLm9wdHMuaGVpZ2h0ID8gd2lkdGggLyBoZWlnaHQgOiBzbGlkZS5vcHRzLnJhdGlvIHx8IDE2IC8gOTtcclxuXHJcbiAgICAgICAgaWYgKGhlaWdodCA+IHdpZHRoIC8gYXNwZWN0UmF0aW8pIHtcclxuICAgICAgICAgIGhlaWdodCA9IHdpZHRoIC8gYXNwZWN0UmF0aW87XHJcbiAgICAgICAgfSBlbHNlIGlmICh3aWR0aCA+IGhlaWdodCAqIGFzcGVjdFJhdGlvKSB7XHJcbiAgICAgICAgICB3aWR0aCA9IGhlaWdodCAqIGFzcGVjdFJhdGlvO1xyXG4gICAgICAgI
109H1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV6LndpZHRoID0gd2lkdGg7XHJcbiAgICAgIHJlei5oZWlnaHQgPSBoZWlnaHQ7XHJcblxyXG4gICAgICByZXR1cm4gcmV6O1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBVcGRhdGUgY29udGVudCBzaXplIGFuZCBwb3NpdGlvbiBmb3IgYWxsIHNsaWRlc1xyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHVwZGF0ZTogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgJC5lYWNoKHNlbGYuc2xpZGVzLCBmdW5jdGlvbiAoa2V5LCBzbGlkZSkge1xyXG4gICAgICAgIHNlbGYudXBkYXRlU2xpZGUoc2xpZGUsIGUpO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gVXBkYXRlIHNsaWRlIGNvbnRlbnQgcG9zaXRpb24gYW5kIHNpemVcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgdXBkYXRlU2xpZGU6IGZ1bmN0aW9uIChzbGlkZSwgZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgJGNvbnRlbnQgPSBzbGlkZSAmJiBzbGlkZS4kY29udGVudCxcclxuICAgICAgICB3aWR0aCA9IHNsaWRlLndpZHRoIHx8IHNsaWRlLm9wdHMud2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0ID0gc2xpZGUuaGVpZ2h0IHx8IHNsaWRlLm9wdHMuaGVpZ2h0LFxyXG4gICAgICAgICRzbGlkZSA9IHNsaWRlLiRzbGlkZTtcclxuXHJcbiAgICAgIC8vIEZpcnN0LCBwcmV2ZW50IGNhcHRpb24gb3ZlcmxhcCwgaWYgbmVlZGVkXHJcbiAgICAgIHNlbGYuYWRqdXN0Q2FwdGlvbihzbGlkZSk7XHJcblxyXG4gICAgICAvLyBUaGVuIHJlc2l6ZSBjb250ZW50IHRvIGZpdCBpbnNpZGUgdGhlIHNsaWRlXHJcbiAgICAgIGlmICgkY29udGVudCAmJiAod2lkdGggfHwgaGVpZ2h0IHx8IHNsaWRlLmNvbnRlbnRUeXBlID09PSBcInZpZGVvXCIpICYmICFzbGlkZS5oYXNFcnJvcikge1xyXG4gICAgICAgICQuZmFuY3lib3guc3RvcCgkY29udGVudCk7XHJcblxyXG4gICAgICAgICQuZmFuY3lib3guc2V0VHJhbnNsYXRlKCRjb250ZW50LCBzZWxmLmdldEZpdFBvcyhzbGlkZSkpO1xyXG5cclxuICAgICAgICBpZiAoc2xpZGUucG9zID09PSBzZWxmLmN1cnJQb3MpIHtcclxuICAgICAgICAgIHNlbGYuaXNBbmltYXRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICBzZWxmLnVwZGF0ZUN1cnNvcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gVGhlbiBzb21lIGFkanVzdG1lbnRzXHJcbiAgICAgIHNlbGYuYWRqdXN0TGF5b3V0KHNsaWRlKTtcclxuXHJcbiAgICAgIGlmICgkc2xpZGUubGVuZ3RoKSB7XHJcbiAgICAgICAgJHNsaWRlLnRyaWdnZXIoXCJyZWZyZXNoXCIpO1xyXG5cclxuICAgICAgICBpZiAoc2xpZGUucG9zID09PSBzZWxmLmN1cnJQb3MpIHtcclxuICAgICAgICAgIHNlbGYuJHJlZnMudG9vbGJhclxyXG4gICAgICAgICAgICAuYWRkKHNlbGYuJHJlZnMubmF2aWdhdGlvbi5maW5kKFwiLmZhbmN5Ym94LWJ1dHRvbi0tYXJyb3dfcmlnaHRcIikpXHJcbiAgICAgICAgICAgIC50b2dnbGVDbGFzcyhcImNvbXBlbnNhdGUtZm9yLXNjcm9sbGJhclwiLCAkc2xpZGUuZ2V0KDApLnNjcm9sbEhlaWdodCA+ICRzbGlkZS5nZXQoMCkuY2xpZW50SGVpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYudHJpZ2dlcihcIm9uVXBkYXRlXCIsIHNsaWRlLCBlKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gSG9yaXpvbnRhbGx5IGNlbnRlciBzbGlkZVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGNlbnRlclNsaWRlOiBmdW5jdGlvbiAoZHVyYXRpb24pIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGN1cnJlbnQgPSBzZWxmLmN1cnJlbnQsXHJcbiAgICAgICAgJHNsaWRlID0gY3VycmVudC4kc2xpZGU7XHJcblxyXG4gICAgICBpZiAoc2VsZi5pc0Nsb3NpbmcgfHwgIWN1cnJlbnQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICRzbGlkZS5zaWJsaW5ncygpLmNzcyh7XHJcbiAgICAgICAgdHJhbnNmb3JtOiBcIlwiLFxyXG4gICAgICAgIG9wYWNpdHk6IFwiXCJcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAkc2xpZGVcclxuICAgICAgICAucGFyZW50KClcclxuICAgICAgICAuY2hpbGRyZW4oKVxyXG4gICAgICAgIC5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1wcmV2aW91cyBmYW5jeWJveC1zbGlkZS0tbmV4dFwiKTtcclxuXHJcbiAgICAgICQuZmFuY3lib3guYW5pbWF0ZShcclxuICAgICAgICAkc2xpZGUsIHtcclxuICAgICAgICAgIHRvcDogMCxcclxuICAgICAgICAgIGxlZnQ6IDAsXHJcbiAgICAgICAgICBvcGFjaXR5OiAxXHJcbiAgICAgICAgfSxcclxuICAgICAgICBkdXJhdGlvbiA9PT0gdW5kZWZpbmVkID8gMCA6IGR1cmF0aW9uLFxyXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIC8vIENsZWFuIHVwXHJcbiAgICAgICAgICAkc2xpZGUuY3NzKHtcclxuICAgICAgICAgICAgdHJhbnNmb3JtOiBcIlwiLFxyXG4gICAgICAgICAgICBvcGFjaXR5OiBcIlwiXHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICBpZiAoIWN1cnJlbnQuaXNDb21wbGV0ZSkge1xyXG4gICAgICAgICAgICBzZWxmLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBmYWxzZVxyXG4gICAgICApO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDaGVjayBpZiBjdXJyZW50IHNsaWRlIGlzIG1vdmVkIChzd2lwZWQpXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgaXNNb3ZlZDogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBjdXJyZW50ID0gc2xpZGUgfHwgdGhpcy5jdXJyZW50LFxyXG4gICAgICAgIHNsaWRlUG9zLFxyXG4gICAgICAgIHN0YWdlUG9zO1xyXG5cclxuICAgICAgaWYgKCFjdXJyZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzdGFnZVBvcyA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKHRoaXMuJHJlZnMuc3RhZ2UpO1xyXG4gICAgICBzbGlkZVBvcyA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKGN1cnJlbnQuJHNsaWRlKTtcclxuXHJcbiAgICAgIHJldHVybiAoXHJcbiAgICAgICAgIWN1cnJlbnQuJHNsaWRlLmhhc0NsYXNzKFwiZmFuY3lib3gtYW5pbWF0ZWRcIikgJiZcclxuICAgICAgICAoTWF0aC5hYnMoc2xpZGVQb3MudG9wIC0gc3RhZ2
109VQb3MudG9wKSA+IDAuNSB8fCBNYXRoLmFicyhzbGlkZVBvcy5sZWZ0IC0gc3RhZ2VQb3MubGVmdCkgPiAwLjUpXHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFVwZGF0ZSBjdXJzb3Igc3R5bGUgZGVwZW5kaW5nIGlmIGNvbnRlbnQgY2FuIGJlIHpvb21lZFxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgdXBkYXRlQ3Vyc29yOiBmdW5jdGlvbiAobmV4dFdpZHRoLCBuZXh0SGVpZ2h0KSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBjdXJyZW50ID0gc2VsZi5jdXJyZW50LFxyXG4gICAgICAgICRjb250YWluZXIgPSBzZWxmLiRyZWZzLmNvbnRhaW5lcixcclxuICAgICAgICBjYW5QYW4sXHJcbiAgICAgICAgaXNab29tYWJsZTtcclxuXHJcbiAgICAgIGlmICghY3VycmVudCB8fCBzZWxmLmlzQ2xvc2luZyB8fCAhc2VsZi5HdWVzdHVyZXMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICRjb250YWluZXIucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1pcy16b29tYWJsZSBmYW5jeWJveC1jYW4tem9vbUluIGZhbmN5Ym94LWNhbi16b29tT3V0IGZhbmN5Ym94LWNhbi1zd2lwZSBmYW5jeWJveC1jYW4tcGFuXCIpO1xyXG5cclxuICAgICAgY2FuUGFuID0gc2VsZi5jYW5QYW4obmV4dFdpZHRoLCBuZXh0SGVpZ2h0KTtcclxuXHJcbiAgICAgIGlzWm9vbWFibGUgPSBjYW5QYW4gPyB0cnVlIDogc2VsZi5pc1pvb21hYmxlKCk7XHJcblxyXG4gICAgICAkY29udGFpbmVyLnRvZ2dsZUNsYXNzKFwiZmFuY3lib3gtaXMtem9vbWFibGVcIiwgaXNab29tYWJsZSk7XHJcblxyXG4gICAgICAkKFwiW2RhdGEtZmFuY3lib3gtem9vbV1cIikucHJvcChcImRpc2FibGVkXCIsICFpc1pvb21hYmxlKTtcclxuXHJcbiAgICAgIGlmIChjYW5QYW4pIHtcclxuICAgICAgICAkY29udGFpbmVyLmFkZENsYXNzKFwiZmFuY3lib3gtY2FuLXBhblwiKTtcclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICBpc1pvb21hYmxlICYmXHJcbiAgICAgICAgKGN1cnJlbnQub3B0cy5jbGlja0NvbnRlbnQgPT09IFwiem9vbVwiIHx8ICgkLmlzRnVuY3Rpb24oY3VycmVudC5vcHRzLmNsaWNrQ29udGVudCkgJiYgY3VycmVudC5vcHRzLmNsaWNrQ29udGVudChjdXJyZW50KSA9PSBcInpvb21cIikpXHJcbiAgICAgICkge1xyXG4gICAgICAgICRjb250YWluZXIuYWRkQ2xhc3MoXCJmYW5jeWJveC1jYW4tem9vbUluXCIpO1xyXG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnQub3B0cy50b3VjaCAmJiAoY3VycmVudC5vcHRzLnRvdWNoLnZlcnRpY2FsIHx8IHNlbGYuZ3JvdXAubGVuZ3RoID4gMSkgJiYgY3VycmVudC5jb250ZW50VHlwZSAhPT0gXCJ2aWRlb1wiKSB7XHJcbiAgICAgICAgJGNvbnRhaW5lci5hZGRDbGFzcyhcImZhbmN5Ym94LWNhbi1zd2lwZVwiKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDaGVjayBpZiBjdXJyZW50IHNsaWRlIGlzIHpvb21hYmxlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgaXNab29tYWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuY3VycmVudCxcclxuICAgICAgICBmaXRQb3M7XHJcblxyXG4gICAgICAvLyBBc3N1bWUgdGhhdCBzbGlkZSBpcyB6b29tYWJsZSBpZjpcclxuICAgICAgLy8gICAtIGltYWdlIGlzIHN0aWxsIGxvYWRpbmdcclxuICAgICAgLy8gICAtIGFjdHVhbCBzaXplIG9mIHRoZSBpbWFnZSBpcyBzbWFsbGVyIHRoYW4gYXZhaWxhYmxlIGFyZWFcclxuICAgICAgaWYgKGN1cnJlbnQgJiYgIXNlbGYuaXNDbG9zaW5nICYmIGN1cnJlbnQudHlwZSA9PT0gXCJpbWFnZVwiICYmICFjdXJyZW50Lmhhc0Vycm9yKSB7XHJcbiAgICAgICAgaWYgKCFjdXJyZW50LmlzTG9hZGVkKSB7XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZpdFBvcyA9IHNlbGYuZ2V0Rml0UG9zKGN1cnJlbnQpO1xyXG5cclxuICAgICAgICBpZiAoZml0UG9zICYmIChjdXJyZW50LndpZHRoID4gZml0UG9zLndpZHRoIHx8IGN1cnJlbnQuaGVpZ2h0ID4gZml0UG9zLmhlaWdodCkpIHtcclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDaGVjayBpZiBjdXJyZW50IGltYWdlIGRpbWVuc2lvbnMgYXJlIHNtYWxsZXIgdGhhbiBhY3R1YWxcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGlzU2NhbGVkRG93bjogZnVuY3Rpb24gKG5leHRXaWR0aCwgbmV4dEhlaWdodCkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgcmV6ID0gZmFsc2UsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuY3VycmVudCxcclxuICAgICAgICAkY29udGVudCA9IGN1cnJlbnQuJGNvbnRlbnQ7XHJcblxyXG4gICAgICBpZiAobmV4dFdpZHRoICE9PSB1bmRlZmluZWQgJiYgbmV4dEhlaWdodCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV6ID0gbmV4dFdpZHRoIDwgY3VycmVudC53aWR0aCAmJiBuZXh0SGVpZ2h0IDwgY3VycmVudC5oZWlnaHQ7XHJcbiAgICAgIH0gZWxzZSBpZiAoJGNvbnRlbnQpIHtcclxuICAgICAgICByZXogPSAkLmZhbmN5Ym94LmdldFRyYW5zbGF0ZSgkY29udGVudCk7XHJcbiAgICAgICAgcmV6ID0gcmV6LndpZHRoIDwgY3VycmVudC53aWR0aCAmJiByZXouaGVpZ2h0IDwgY3VycmVudC5oZWlnaHQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiByZXo7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENoZWNrIGlmIGltYWdlIGRpbWVuc2lvbnMgZXhjZWVkIHBhcmVudCBlbGVtZW50XHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGNhblBhbjogZnVuY3Rpb24gKG5leHRXaWR0aCwgbmV4dEhlaWdodCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuY3VycmVudCxcclxuICAgICAgICBwb3MgPSBudWxsLFxyXG4gICAgICAgIHJleiA9IGZhbHNlO1xyXG5cclxuICAgICAgaWYgKGN1cnJlbnQudHlwZSA9PT0gXCJpbWFnZVwiICYmIChjdXJyZW50LmlzQ29tcGxldGUgfHwgKG5leHRXaWR0aCAmJiBuZXh0SGVpZ2h0KSkgJiYgIWN1cnJlbnQuaGFzRXJyb3IpIHtcclxuICAgICAgICByZXogPSBzZWxmLmdldEZpdFBvcyhjdXJyZW50KTtcclxuXHJcbiAgICAgICAgaWYgKG5leHRXaWR0aCAhPT0gdW5kZWZpbmVkICYmIG5leHRIZWlnaHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgcG9zID0ge1xyXG4gICAgICAgICAgICB3aWR0aDogbmV4dFdpZHRoLFxyXG4gICAgICAgICAgICBoZWlnaHQ6IG5leHRIZWlnaHRcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50LmlzQ29tcGxldGUpIHtcclxuICAgICAgICAgIHBvcyA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKGN1cnJlbnQuJGNvbnRlbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvcyAmJiByZXopIHtcclxuICAgICAgICAgIHJleiA9IE1hdGguYWJzKHBvcy53aWR0aCAtIHJlei53aWR0aCkgPiAxLjUgfHwgTWF0aC5hYnMocG9zLmhlaWdodCAtIHJlei5oZWlnaHQpID4gMS41O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHJlejtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gTG9hZCBjb250ZW50IGludG8gdGhlIHNsaWRlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBsb2FkU2xpZGU6IGZ1bmN0aW9uIChzbGlkZSkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgdHlwZSxcclxuICAgICAgICAkc2xpZGUsXHJcbiAgICAgICAgYWpheExvYWQ7XHJcblxyXG4gICAgICBpZiAoc2xpZGUuaXNMb2FkaW5nIHx8IHNsaWRlLmlzTG9hZGVkKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzbGlkZS5pc0xvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgaWYgKHNlbGYudHJpZ2dlcihcImJlZm9yZUxvYWRcIiwgc2xpZGUpID09PSBmYWxzZSkge1xyXG4gICAgICAgIHNsaWRlLmlzTG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHR5cGUgPSBzbGlkZS50eXBlO1xyXG4gICAgICAkc2xpZGUgPSBzbGlkZS4kc2xpZGU7XHJcblxyXG4gICAgICAkc2xpZGVcclxuICAgICAgICAub2ZmKFwicmVmcmVzaFwiKVxyXG4gICAgICAgIC50cmlnZ2VyKFwib25SZXNldFwiKVxyXG4gICAgICAgIC5hZGRDbGFzcyhzbGlkZS5vcHRzLnNsaWRlQ2xhc3MpO1xyXG5cclxuICAgICAgLy8gQ3JlYXRlIGNvbnRlbnQgZGVwZW5kaW5nIG9uIHRoZSB0eXBlXHJcbiAgICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgIGNhc2UgXCJpbWFnZVwiOlxyXG4gICAgICAgICAgc2VsZi5zZXRJbWFnZShzbGlkZSk7XHJcblxyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgXCJpZnJhbWVcIjpcclxuICAgICAgICAgIHNlbGYuc2V0SWZyYW1lKHNsaWRlKTtcclxuXHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBcImh0bWxcIjpcclxuICAgICAgICAgIHNlbGYuc2V0Q29udGVudChzbGlkZSwgc2xpZGUuc3JjIHx8IHNsaWRlLmNvbnRlbnQpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFwidmlkZW9cIjpcclxuICAgICAgICAgIHNlbGYuc2V0Q29udGVudChcclxuICAgICAgICAgICAgc2xpZGUsXHJcbiAgICAgICAgICAgIHNsaWRlLm9wdHMudmlkZW8udHBsXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXHtcXHtzcmNcXH1cXH0vZ2ksIHNsaWRlLnNyYylcclxuICAgICAgICAgICAgLnJlcGxhY2UoXCJ7e2Zvcm1hdH19XCIsIHNsaWRlLm9wdHMudmlkZW9Gb3JtYXQgfHwgc2xpZGUub3B0cy52aWRlby5mb3JtYXQgfHwgXCJcIilcclxuICAgICAgICAgICAgLnJlcGxhY2UoXCJ7e3Bvc3Rlcn19XCIsIHNsaWRlLnRodW1iIHx8IFwiXCIpXHJcbiAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFwiaW5saW5lXCI6XHJcbiAgICAgICAgICBpZiAoJChzbGlkZS5zcmMpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBzZWxmLnNldENvbnRlbnQoc2xpZGUsICQoc2xpZGUuc3JjKSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzZWxmLnNldEVycm9yKHNsaWRlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBcImFqYXhcIjpcclxuICAgICAgICAgIHNlbGYuc2hvd0xvYWRpbmcoc2xpZGUpO1xyXG5cclxuICAgICAgICAgIGFqYXhMb2FkID0gJC5hamF4KFxyXG4gICAgICAgICAgICAkLmV4dGVuZCh7fSwgc2xpZGUub3B0cy5hamF4LnNldHRpbmdzLCB7XHJcbiAgICAgICAgICAgICAgdXJsOiBzbGlkZS5zcmMsXHJcbiAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGRhdGEsIHRleHRTdGF0dXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0ZXh0U3RhdHVzID09PSBcInN1Y2Nlc3NcIikge1xyXG4gICAgICAgICAgICAgICAgICBzZWxmLnNldENvbnRlbnQoc2xpZGUsIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChqcVhIUiwgdGV4dFN0YXR1cykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGpxWEhSICYmIHRleHRTdGF0dXMgIT09IFwiYWJvcnRcIikge1xyXG4gICAgICAgICAgICAgICAgICBzZWxmLnNldEVycm9yKHNsaWRlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICRzbGlkZS5vbmUoXCJvblJlc2V0XCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgYWpheExvYWQuYWJvcnQoKTtcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgc2VsZi5zZXRFcnJvcihzbGlkZSk7XHJcblxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBVc2UgdGh1bWJuYWlsIGltYWdlLCBpZiBwb3NzaWJsZVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBzZXRJbWFnZTogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBnaG9zdDtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIG5lZWQgdG8gc2hvdyBsb2FkaW5nIGljb25cclxuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyICRpbWcgPSBzbGlkZS4kaW1hZ2U7XHJcblxyXG4gICAgICAgIGlmICghc2VsZi5pc0Nsb3NpbmcgJiYgc2xpZGUuaXNMb2FkaW5nICYmICghJGltZyB8fCAhJGltZy5sZW5ndGggfHwgISRpbWdbMF0uY29tcGxldGUpICYmICFzbGlkZS5oYXNFcnJvcikge1xyXG4gICAgICAgICAgc2VsZi5zaG93TG9hZGluZyhzbGlkZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCA1MCk7XHJcblxyXG4gICAgICAvL0NoZWNrIGlmIGltYWdlIGhhcyBzcmNzZXRcclxuICAgICAgc2VsZi5jaGVja1NyY3NldChzbGlkZSk7XHJcblxyXG4gICAgICAvLyBUaGlzIHdpbGwgYmUgd3JhcHBlciBjb250YWluaW5nIGJvdGggZ2hvc3QgYW5kIGFjdHVhbCBpbWFnZVxyXG4gICAgICBzbGlkZS4kY29udGVudCA9ICQoJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1jb250ZW50XCI+PC9kaXY+JylcclxuICAgICAgICAuYWRkQ2xhc3MoXCJmYW5jeWJveC1pcy1oaWRkZW5cIilcclxuICAgICAgICAuYXBwZW5kVG8oc2xpZGUuJHNsaWRlLmFkZENsYXNzKFwiZmFuY3lib3gtc2xpZGUtLWltYWdlXCIpKTtcclxuXHJcbiAgICAgIC8vIElmIHdlIGhhdmUgYSB0aHVtYm5haWwsIHdlIGNhbiBkaXNwbGF5IGl0IHdoaWxlIGFjdHVhbCBpbWFnZSBpcyBsb2FkaW5nXHJcbiAgICAgIC8vIFVzZXJzIHdpbGwgbm90IHN0YXJlIGF0IGJsYWNrIHNjcmVlbiBhbmQgYWN0dWFsIGltYWdlIHdpbGwgYXBwZWFyIGdyYWR1YWxseV
109xyXG4gICAgICBpZiAoc2xpZGUub3B0cy5wcmVsb2FkICE9PSBmYWxzZSAmJiBzbGlkZS5vcHRzLndpZHRoICYmIHNsaWRlLm9wdHMuaGVpZ2h0ICYmIHNsaWRlLnRodW1iKSB7XHJcbiAgICAgICAgc2xpZGUud2lkdGggPSBzbGlkZS5vcHRzLndpZHRoO1xyXG4gICAgICAgIHNsaWRlLmhlaWdodCA9IHNsaWRlLm9wdHMuaGVpZ2h0O1xyXG5cclxuICAgICAgICBnaG9zdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XHJcblxyXG4gICAgICAgIGdob3N0Lm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAkKHRoaXMpLnJlbW92ZSgpO1xyXG5cclxuICAgICAgICAgIHNsaWRlLiRnaG9zdCA9IG51bGw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZ2hvc3Qub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi5hZnRlckxvYWQoc2xpZGUpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHNsaWRlLiRnaG9zdCA9ICQoZ2hvc3QpXHJcbiAgICAgICAgICAuYWRkQ2xhc3MoXCJmYW5jeWJveC1pbWFnZVwiKVxyXG4gICAgICAgICAgLmFwcGVuZFRvKHNsaWRlLiRjb250ZW50KVxyXG4gICAgICAgICAgLmF0dHIoXCJzcmNcIiwgc2xpZGUudGh1bWIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBTdGFydCBsb2FkaW5nIGFjdHVhbCBpbWFnZVxyXG4gICAgICBzZWxmLnNldEJpZ0ltYWdlKHNsaWRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgaW1hZ2UgaGFzIHNyY3NldCBhbmQgZ2V0IHRoZSBzb3VyY2VcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgICBjaGVja1NyY3NldDogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBzcmNzZXQgPSBzbGlkZS5vcHRzLnNyY3NldCB8fCBzbGlkZS5vcHRzLmltYWdlLnNyY3NldCxcclxuICAgICAgICBmb3VuZCxcclxuICAgICAgICB0ZW1wLFxyXG4gICAgICAgIHB4UmF0aW8sXHJcbiAgICAgICAgd2luZG93V2lkdGg7XHJcblxyXG4gICAgICAvLyBJZiB3ZSBoYXZlIFwic3Jjc2V0XCIsIHRoZW4gd2UgbmVlZCB0byBmaW5kIGZpcnN0IG1hdGNoaW5nIFwic3JjXCIgdmFsdWUuXHJcbiAgICAgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5LCBiZWNhdXNlIHdoZW4geW91IHNldCBhbiBzcmMgYXR0cmlidXRlLCB0aGUgYnJvd3NlciB3aWxsIHByZWxvYWQgdGhlIGltYWdlXHJcbiAgICAgIC8vIGJlZm9yZSBhbnkgamF2YXNjcmlwdCBvciBldmVuIENTUyBpcyBhcHBsaWVkLlxyXG4gICAgICBpZiAoc3Jjc2V0KSB7XHJcbiAgICAgICAgcHhSYXRpbyA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XHJcbiAgICAgICAgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aCAqIHB4UmF0aW87XHJcblxyXG4gICAgICAgIHRlbXAgPSBzcmNzZXQuc3BsaXQoXCIsXCIpLm1hcChmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgIHZhciByZXQgPSB7fTtcclxuXHJcbiAgICAgICAgICBlbC50cmltKClcclxuICAgICAgICAgICAgLnNwbGl0KC9cXHMrLylcclxuICAgICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGVsLCBpKSB7XHJcbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gcGFyc2VJbnQoZWwuc3Vic3RyaW5nKDAsIGVsLmxlbmd0aCAtIDEpLCAxMCk7XHJcblxyXG4gICAgICAgICAgICAgIGlmIChpID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHJldC51cmwgPSBlbCk7XHJcbiAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHJldC52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgcmV0LnBvc3RmaXggPSBlbFtlbC5sZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIHJldHVybiByZXQ7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIFNvcnQgYnkgdmFsdWVcclxuICAgICAgICB0ZW1wLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcclxuICAgICAgICAgIHJldHVybiBhLnZhbHVlIC0gYi52YWx1ZTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gT2ssIG5vdyB3ZSBoYXZlIGFuIGFycmF5IG9mIGFsbCBzcmNzZXQgdmFsdWVzXHJcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB0ZW1wLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICB2Y
109XIgZWwgPSB0ZW1wW2pdO1xyXG5cclxuICAgICAgICAgIGlmICgoZWwucG9zdGZpeCA9PT0gXCJ3XCIgJiYgZWwudmFsdWUgPj0gd2luZG93V2lkdGgpIHx8IChlbC5wb3N0Zml4ID09PSBcInhcIiAmJiBlbC52YWx1ZSA+PSBweFJhdGlvKSkge1xyXG4gICAgICAgICAgICBmb3VuZCA9IGVsO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIElmIG5vdCBmb3VuZCwgdGFrZSB0aGUgbGFzdCBvbmVcclxuICAgICAgICBpZiAoIWZvdW5kICYmIHRlbXAubGVuZ3RoKSB7XHJcbiAgICAgICAgICBmb3VuZCA9IHRlbXBbdGVtcC5sZW5ndGggLSAxXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgICAgc2xpZGUuc3JjID0gZm91bmQudXJsO1xyXG5cclxuICAgICAgICAgIC8vIElmIHdlIGhhdmUgZGVmYXVsdCB3aWR0aC9oZWlnaHQgdmFsdWVzLCB3ZSBjYW4gY2FsY3VsYXRlIGhlaWdodCBmb3IgbWF0Y2hpbmcgc291cmNlXHJcbiAgICAgICAgICBpZiAoc2xpZGUud2lkdGggJiYgc2xpZGUuaGVpZ2h0ICYmIGZvdW5kLnBvc3RmaXggPT0gXCJ3XCIpIHtcclxuICAgICAgICAgICAgc2xpZGUuaGVpZ2h0ID0gKHNsaWRlLndpZHRoIC8gc2xpZGUuaGVpZ2h0KSAqIGZvdW5kLnZhbHVlO1xyXG4gICAgICAgICAgICBzbGlkZS53aWR0aCA9IGZvdW5kLnZhbHVlO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHNsaWRlLm9wdHMuc3Jjc2V0ID0gc3Jjc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDcmVhdGUgZnVsbC1zaXplIGltYWdlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgc2V0QmlnSW1hZ2U6IGZ1bmN0aW9uIChzbGlkZSkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKSxcclxuICAgICAgICAkaW1nID0gJChpbWcpO1xyXG5cclxuICAgICAgc2xpZGUuJGltYWdlID0gJGltZ1xyXG4gICAgICAgIC5vbmUoXCJlcnJvclwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBzZWxmLnNldEVycm9yKHNsaWRlKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbmUoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHZhciBzaXplcztcclxuXHJcbiAgICAgICAgICBpZiAoIXNsaWRlLiRnaG9zdCkge1xyXG4gICAgICAgICAgICBzZWxmLnJlc29sdmVJbWFnZVNsaWRlU2l6ZShzbGlkZSwgdGhpcy5uYXR1cmFsV2lkdGgsIHRoaXMubmF0dXJhbEhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICBzZWxmLmFmdGVyTG9hZChzbGlkZSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKHNlbGYuaXNDbG9zaW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoc2xpZGUub3B0cy5zcmNzZXQpIHtcclxuICAgICAgICAgICAgc2l6ZXMgPSBzbGlkZS5vcHRzLnNpemVzO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzaXplcyB8fCBzaXplcyA9PT0gXCJhdXRvXCIpIHtcclxuICAgICAgICAgICAgICBzaXplcyA9XHJcbiAgICAgICAgICAgICAgICAoc2xpZGUud2lkdGggLyBzbGlkZS5oZWlnaHQgPiAxICYmICRXLndpZHRoKCkgLyAkVy5oZWlnaHQoKSA+IDEgPyBcIjEwMFwiIDogTWF0aC5yb3VuZCgoc2xpZGUud2lkdGggLyBzbGlkZS5oZWlnaHQpICogMTAwKSkgK1xyXG4gICAgICAgICAgICAgICAgXCJ2d1wiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAkaW1nLmF0dHIoXCJzaXplc1wiLCBzaXplcykuYXR0cihcInNyY3NldFwiLCBzbGlkZS5vcHRzLnNyY3NldCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy8gSGlkZSB0ZW1wb3JhcnkgaW1hZ2UgYWZ0ZXIgc29tZSBkZWxheVxyXG4gICAgICAgICAgaWYgKHNsaWRlLiRnaG9zdCkge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICBpZiAoc2xpZGUuJGdob3N0ICYmICFzZWxmLmlzQ2xvc2luZykge1xyXG4gICAgICAgICAgICAgICAgc2xpZGUuJGdob3N0LmhpZGUoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIE1hdGgubWluKDMwMCwgTWF0aC5tYXgoMTAwMCwgc2xpZGUuaGVpZ2h0IC8gMTYwMCkpKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzZWxmLmhpZGVMb2FkaW5nKHNsaWRlKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5hZGRDbGFzcyhcImZhbmN5Ym94LWltYWdlXCIpXHJcbiAgICAgICAgLmF0dHIoXCJzcmNcIiwgc2xpZGUuc3JjKVxyXG4gICAgICAgIC5hcHBlbmRUbyhzbGlkZS4kY29udGVudCk7XHJcblxyXG4gICAgICBpZiAoKGltZy5jb21wbGV0ZSB8fCBpbWcucmVhZHlTdGF0ZSA9PSBcImNvbXBsZXRlXCIpICYmICRpbWcubmF0dXJhbFdpZHRoICYmICRpbWcubmF0dXJhbEhlaWdodCkge1xyXG4gICAgICAgICRpbWcudHJpZ2dlcihcImxvYWRcIik7XHJcbiAgICAgIH0gZWxzZSBpZiAoaW1nLmVycm9yKSB7XHJcbiAgICAgICAgJGltZy50cmlnZ2VyKFwiZXJyb3JcIik7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gQ29tcHV0ZXMgdGhlIHNsaWRlIHNpemUgZnJvbSBpbWFnZSBzaXplIGFuZCBtYXhXaWR0aC9tYXhIZWlnaHRcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgcmVzb2x2ZUltYWdlU2xpZGVTaXplOiBmdW5jdGlvbiAoc2xpZGUsIGltZ1dpZHRoLCBpbWdIZWlnaHQpIHtcclxuICAgICAgdmFyIG1heFdpZHRoID0gcGFyc2VJbnQoc2xpZGUub3B0cy53aWR0aCwgMTApLFxyXG4gICAgICAgIG1heEhlaWdodCA9IHBhcnNlSW50KHNsaWRlLm9wdHMuaGVpZ2h0LCAxMCk7XHJcblxyXG4gICAgICAvLyBTZXRzIHRoZSBkZWZhdWx0IHZhbHVlcyBmcm9tIHRoZSBpbWFnZVxyXG4gICAgICBzbGlkZS53aWR0aCA9IGltZ1dpZHRoO1xyXG4gICAgICBzbGlkZS5oZWlnaHQgPSBpbWdIZWlnaHQ7XHJcblxyXG4gICAgICBpZiAobWF4V2lkdGggPiAwKSB7XHJcbiAgICAgICAgc2xpZGUud2lkdGggPSBtYXhXaWR0aDtcclxuICAgICAgICBzbGlkZS5oZWlnaHQgPSBNYXRoLmZsb29yKChtYXhXaWR0aCAqIGltZ0hlaWdodCkgLyBpbWdXaWR0aCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChtYXhIZWlnaHQgPiAwKSB7XHJcbiAgICAgICAgc2xpZGUud2lkdGggPSBNYXRoLmZsb29yKChtYXhIZWlnaHQgKiBpbWdXaWR0aCkgLyBpbWdIZWlnaHQpO1xyXG4gICAgICAgIHNsaWRlLmhlaWdodCA9IG1heEhlaWdodDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDcmVhdGUgaWZyYW1lIHdyYXBwZXIsIGlmcmFtZSBhbmQgYmluZGluZ3NcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHNldElmcmFtZTogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBvcHRzID0gc2xpZGUub3B0cy5pZnJhbWUsXHJcbiAgICAgICAgJHNsaWRlID0gc2xpZGUuJHNsaWRlLFxyXG4gICAgICAgICRpZnJhbWU7XHJcblxyXG4gICAgICBzbGlkZS4kY29udGVudCA9ICQoJzxkaXYgY2xhc3M9XCJmYW5jeWJveC1jb250ZW50JyArIChvcHRzLnByZWxvYWQgPyBcIiBmYW5jeWJveC1pcy1oaWRkZW5cIiA6IFwiXCIpICsgJ1wiPjwvZGl2PicpXHJcbiAgICAgICAgLmNzcyhvcHRzLmNzcylcclxuICAgICAgICAuYXBwZW5kVG8oJHNsaWRlKTtcclxuXHJcbiAgICAgICRzbGlkZS5hZGRDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1cIiArIHNsaWRlLmNvbnRlbnRUeXBlKTtcclxuXHJcbiAgICAgIHNsaWRlLiRpZnJhbWUgPSAkaWZyYW1lID0gJChvcHRzLnRwb
109C5yZXBsYWNlKC9cXHtybmRcXH0vZywgbmV3IERhdGUoKS5nZXRUaW1lKCkpKVxyXG4gICAgICAgIC5hdHRyKG9wdHMuYXR0cilcclxuICAgICAgICAuYXBwZW5kVG8oc2xpZGUuJGNvbnRlbnQpO1xyXG5cclxuICAgICAgaWYgKG9wdHMucHJlbG9hZCkge1xyXG4gICAgICAgIHNlbGYuc2hvd0xvYWRpbmcoc2xpZGUpO1xyXG5cclxuICAgICAgICAvLyBVbmZvcnR1bmF0ZWx5LCBpdCBpcyBub3QgYWx3YXlzIHBvc3NpYmxlIHRvIGRldGVybWluZSBpZiBpZnJhbWUgaXMgc3VjY2Vzc2Z1bGx5IGxvYWRlZFxyXG4gICAgICAgIC8vIChkdWUgdG8gYnJvd3NlciBzZWN1cml0eSBwb2xpY3kpXHJcblxyXG4gICAgICAgICRpZnJhbWUub24oXCJsb2FkLmZiIGVycm9yLmZiXCIsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICB0aGlzLmlzUmVhZHkgPSAxO1xyXG5cclxuICAgICAgICAgIHNsaWRlLiRzbGlkZS50cmlnZ2VyKFwicmVmcmVzaFwiKTtcclxuXHJcbiAgICAgICAgICBzZWxmLmFmdGVyTG9hZChzbGlkZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIFJlY2FsY3VsYXRlIGlmcmFtZSBjb250ZW50IHNpemVcclxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgICAgICRzbGlkZS5vbihcInJlZnJlc2guZmJcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgdmFyICRjb250ZW50ID0gc2xpZGUuJGNvbnRlbnQsXHJcbiAgICAgICAgICAgIGZyYW1lV2lkdGggPSBvcHRzLmNzcy53aWR0aCxcclxuICAgICAgICAgICAgZnJhbWVIZWlnaHQgPSBvcHRzLmNzcy5oZWlnaHQsXHJcbiAgICAgICAgICAgICRjb250ZW50cyxcclxuICAgICAgICAgICAgJGJvZHk7XHJcblxyXG4gICAgICAgICAgaWYgKCRpZnJhbWVbMF0uaXNSZWFkeSAhPT0gMSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgJGNvbnRlbnRzID0gJGlmcmFtZS5jb250ZW50cygpO1xyXG4gICAgICAgICAgICAkYm9keSA9ICRjb250ZW50cy5maW5kKFwiYm9keVwiKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cclxuXHJcbiAgICAgICAgICAvLyBDYWxjdWxhdGUgY29udGVudCBkaW1lbnNpb25zLCBpZiBpdCBpcyBhY2Nlc3NpYmxlXHJcbiAgICAgICAgICBpZiAoJGJvZHkgJiYgJGJvZHkubGVuZ3RoICYmICRib2R5LmNoaWxkcmVuKCkubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIC8vIEF2b2lkIHNjcm9sbGluZyB0byB0b3AgKGlmIG11bHRpcGxlIGluc3RhbmNlcylcclxuICAgICAgICAgICAgJHNsaWRlLmNzcyhcIm92ZXJmbG93XCIsIFwidmlzaWJsZVwiKTtcclxuXHJcbiAgICAgICAgICAgICRjb250ZW50LmNzcyh7XHJcbiAgICAgICAgICAgICAgd2lkdGg6IFwiMTAwJVwiLFxyXG4gICAgICAgICAgICAgIFwibWF4LXdpZHRoXCI6IFwiMTAwJVwiLFxyXG4gICAgICAgICAgICAgIGhlaWdodDogXCI5OTk5cHhcIlxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmIChmcmFtZVdpZHRoID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICBmcmFtZVdpZHRoID0gTWF0aC5jZWlsKE1hdGgubWF4KCRib2R5WzBdLmNsaWVudFdpZHRoLCAkYm9keS5vdXRlcldpZHRoKHRydWUpKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICRjb250ZW50LmNzcyhcIndpZHRoXCIsIGZyYW1lV2lkdGggPyBmcmFtZVdpZHRoIDogXCJcIikuY3NzKFwibWF4LXdpZHRoXCIsIFwiXCIpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGZyYW1lSGVpZ2h0ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICBmcmFtZUhlaWdodCA9IE1hdGguY2VpbChNYXRoLm1heCgkYm9keVswXS5jbGllbnRIZWlnaHQsICRib2R5Lm91dGVySGVpZ2h0KHRydWUpKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICRjb250ZW50LmNzcyhcImhlaWdodFwiLCBmcmFtZUhlaWdodCA/IGZyYW1lSGVpZ2h0IDogXCJcIik7XHJcblxyXG4gICAgICAgICAgICAkc2xpZGUuY3NzKFwib3ZlcmZsb3dcIiwgXCJhdXRvXCIpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICRjb250ZW50LnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtaXMtaGlkZGVuXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNlbGYuYWZ0ZXJMb2FkKHNsaWRlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgJGlmcmFtZS5hdHRyKFwic3JjXCIsIHNsaWRlLnNyYyk7XHJcblxyXG4gICAgICAvLyBSZW1vdmUgaWZyYW1lIGlmIGNsb3Npbmcgb3IgY2hhbmdpbmcgZ2FsbGVyeSBpdGVtXHJcbiAgICAgICRzbGlkZS5vbmUoXCJvblJlc2V0XCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBUaGlzIGhlbHBzIElFIG5vdCB0byB0aHJvdyBlcnJvcnMgd2hlbiBjbG9zaW5nXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICQodGhpcylcclxuICAgICAgICAgICAgLmZpbmQoXCJpZnJhbWVcIilcclxuICAgICAgICAgICAgLmhpZGUoKVxyXG4gICAgICAgICAgICAudW5iaW5kKClcclxuICAgICAgICAgICAgLmF0dHIoXCJzcmNcIiwgXCIvL2Fib3V0OmJsYW5rXCIpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cclxuXHJcbiAgICAgICAgJCh0aGlzKVxyXG4gICAgICAgICAgLm9mZihcInJlZnJlc2guZmJcIilcclxuICAgICAgICAgIC5lbXB0eSgpO1xyXG5cclxuICAgICAgICBzbGlkZS5pc0xvYWRlZCA9IGZhbHNlO1xyXG4gICAgICAgIHNsaWRlLmlzUmV2ZWFsZWQgPSBmYWxzZTtcclxuICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFdyYXAgYW5kIGFwcGVuZCBjb250ZW50IHRvIHRoZSBzbGlkZVxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBzZXRDb250ZW50OiBmdW5jdGlvbiAoc2xpZGUsIGNvbnRlbnQpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNDbG9zaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLmhpZGVMb2FkaW5nKHNsaWRlKTtcclxuXHJcbiAgICAgIGlmIChzbGlkZS4kY29udGVudCkge1xyXG4gICAgICAgICQuZmFuY3lib3guc3RvcChzbGlkZS4kY29udGVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNsaWRlLiRzbGlkZS5lbXB0eSgpO1xyXG5cclxuICAgICAgLy8gSWYgY29udGVudCBpcyBhIGpRdWVyeSBvYmplY3QsIHRoZW4gaXQgd2lsbCBiZSBtb3ZlZCB0byB0aGUgc2xpZGUuXHJcbiAgICAgIC8vIFRoZSBwbGFjZWhvbGRlciBpcyBjcmVhdGVkIHNvIHdlIHdpbGwga25vdyB3aGVyZSB0byBwdXQgaXQgYmFjay5cclxuICAgICAgaWYgKGlzUXVlcnkoY29udGVudCkgJiYgY29udGVudC5wYXJlbnQoKS5sZW5ndGgpIHtcclxuICAgICAgICAvLyBNYWtlIHN1cmUgY29udGVudCBpcyBub3QgYWxyZWFkeSBtb3ZlZCB0byBmYW5jeUJveFxyXG4gICAgICAgIGlmIChjb250ZW50Lmhhc0NsYXNzKFwiZmFuY3lib3gtY29udGVudFwiKSB8fCBjb250ZW50LnBhcmVudCgpLmhhc0NsYXNzKFwiZmFuY3lib3gtY29udGVudFwiKSkge1xyXG4gICAgICAgICAgY29udGVudC5wYXJlbnRzKFwiLmZhbmN5Ym94LXNsaWRlXCIpLnRyaWdnZXIoXCJvblJlc2V0XCIpO1xyXG4gICAgICAgI
109H1cclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRlbXBvcmFyeSBlbGVtZW50IG1hcmtpbmcgb3JpZ2luYWwgcGxhY2Ugb2YgdGhlIGNvbnRlbnRcclxuICAgICAgICBzbGlkZS4kcGxhY2Vob2xkZXIgPSAkKFwiPGRpdj5cIilcclxuICAgICAgICAgIC5oaWRlKClcclxuICAgICAgICAgIC5pbnNlcnRBZnRlcihjb250ZW50KTtcclxuXHJcbiAgICAgICAgLy8gTWFrZSBzdXJlIGNvbnRlbnQgaXMgdmlzaWJsZVxyXG4gICAgICAgIGNvbnRlbnQuY3NzKFwiZGlzcGxheVwiLCBcImlubGluZS1ibG9ja1wiKTtcclxuICAgICAgfSBlbHNlIGlmICghc2xpZGUuaGFzRXJyb3IpIHtcclxuICAgICAgICAvLyBJZiBjb250ZW50IGlzIGp1c3QgYSBwbGFpbiB0ZXh0LCB0cnkgdG8gY29udmVydCBpdCB0byBodG1sXHJcbiAgICAgICAgaWYgKCQudHlwZShjb250ZW50KSA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgY29udGVudCA9ICQoXCI8ZGl2PlwiKVxyXG4gICAgICAgICAgICAuYXBwZW5kKCQudHJpbShjb250ZW50KSlcclxuICAgICAgICAgICAgLmNvbnRlbnRzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBcImZpbHRlclwiIG9wdGlvbiBpcyBwcm92aWRlZCwgdGhlbiBmaWx0ZXIgY29udGVudFxyXG4gICAgICAgIGlmIChzbGlkZS5vcHRzLmZpbHRlcikge1xyXG4gICAgICAgICAgY29udGVudCA9ICQoXCI8ZGl2PlwiKVxyXG4gICAgICAgICAgICAuaHRtbChjb250ZW50KVxyXG4gICAgICAgICAgICAuZmluZChzbGlkZS5vcHRzLmZpbHRlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBzbGlkZS4kc2xpZGUub25lKFwib25SZXNldFwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gUGF1c2UgYWxsIGh0bWw1IHZpZGVvL2F1ZGlvXHJcbiAgICAgICAgJCh0aGlzKVxyXG4gICAgICAgICAgLmZpbmQoXCJ2aWRlbyxhdWRpb1wiKVxyXG4gICAgICAgICAgLnRyaWdnZXIoXCJwYXVzZVwiKTtcclxuXHJcbiAgICAgICAgLy8gUHV0IGNvbnRlbnQgYmFja1xyXG4gICAgICAgIGlmIChzbGlkZS4kcGxhY2Vob2xkZXIpIHtcclxuICAgICAgICAgIHNsaWRlLiRwbGFjZWhvbGRlci5hZnRlcihjb250ZW50LnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtY29udGVudFwiKS5oaWRlKCkpLnJlbW92ZSgpO1xyXG5cclxuICAgICAgICAgIHNsaWRlLiRwbGFjZWhvbGRlciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZW1vdmUgY3VzdG9tIGNsb3NlIGJ1dHRvblxyXG4gICAgICAgIGlmIChzbGlkZS4kc21hbGxCdG4pIHtcclxuICAgICAgICAgIHNsaWRlLiRzbWFsbEJ0bi5yZW1vdmUoKTtcclxuXHJcbiAgICAgICAgICBzbGlkZS4kc21hbGxCdG4gPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGNvbnRlbnQgYW5kIG1hcmsgc2xpZGUgYXMgbm90IGxvYWRlZFxyXG4gICAgICAgIGlmICghc2xpZGUuaGFzRXJyb3IpIHtcclxuICAgICAgICAgICQodGhpcykuZW1wdHkoKTtcclxuXHJcbiAgICAgICAgICBzbGlkZS5pc0xvYWRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgc2xpZGUuaXNSZXZlYWxlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICAkKGNvbnRlbnQpLmFwcGVuZFRvKHNsaWRlLiRzbGlkZSk7XHJcblxyXG4gICAgICBpZiAoJChjb250ZW50KS5pcyhcInZpZGVvLGF1ZGlvXCIpKSB7XHJcbiAgICAgICAgJChjb250ZW50KS5hZGRDbGFzcyhcImZhbmN5Ym94LXZpZGVvXCIpO1xyXG5cclxuICAgICAgICAkKGNvbnRlbnQpLndyYXAoXCI8ZGl2PjwvZGl2PlwiKTtcclxuXHJcbiAgICAgICAgc2xpZGUuY29udGVudFR5cGUgPSBcInZpZGVvXCI7XHJcblxyXG4gICAgICAgIHNsaWRlLm9wdHMud2lkdGggPSBzbGlkZS5vcHRzLndpZHRoIHx8ICQoY29udGVudCkuYXR0cihcIndpZHRoXCIpO1xyXG4gICAgICAgIHNsaWRlLm9wdHMuaGVpZ2h0ID0gc2xpZGUub3B0cy5oZWlnaHQgfHwgJChjb250ZW50KS5hdHRyKFwiaGVpZ2h0XCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzbGlkZS4kY29udGVudCA9IHNsaWRlLiRzbGlkZVxyXG4gICAgICAgIC5jaGlsZHJlbigpXHJcbiAgICAgICAgLmZpbHRlcihcImRpdixmb3JtLG1haW4sdmlkZW8sYXVkaW8sYXJ0aWNsZSwuZmFuY3lib3gtY29udGVudFwiKVxyXG4gICAgICAgIC5maXJzdCgpO1xyXG5cclxuICAgICAgc2xpZGUuJGNvbnRlbnQuc2libGluZ3MoKS5oaWRlKCk7XHJcblxyXG4gICAgICAvLyBSZS1jaGVjayBpZiB0aGVyZSBpcyBhIHZhbGlkIGNvbnRlbnRcclxuICAgICAgLy8gKGluIHNvbWUgY2FzZXMsIGFqYXggcmVzcG9uc2UgY2FuIGNvbnRhaW4gdmFyaW91cyBlbGVtZW50cyBvciBwbGFpbiB0ZXh0KVxyXG4gICAgICBpZiAoIXNsaWRlLiRjb250ZW50Lmxlbmd0aCkge1xyXG4gICAgICAgIHNsaWRlLiRjb250ZW50ID0gc2xpZGUuJHNsaWRlXHJcbiAgICAgICAgICAud3JhcElubmVyKFwiPGRpdj48L2Rpdj5cIilcclxuICAgICAgICAgIC5jaGlsZHJlbigpXHJcbiAgICAgICAgICAuZmlyc3QoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2xpZGUuJGNvbnRlbnQuYWRkQ2xhc3MoXCJmYW5jeWJveC1jb250ZW50XCIpO1xyXG5cclxuICAgICAgc2xpZGUuJHNsaWRlLmFkZENsYXNzKFwiZmFuY3lib3gtc2xpZGUtLVwiICsgc2xpZGUuY29udGVudFR5cGUpO1xyXG5cclxuICAgICAgc2VsZi5hZnRlckxvYWQoc2xpZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBEaXNwbGF5IGVycm9yIG1lc3NhZ2VcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHNldEVycm9yOiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgc2xpZGUuaGFzRXJyb3IgPSB0cnVlO1xyXG5cclxuICAgICAgc2xpZGUuJHNsaWRlXHJcbiAgICAgICAgLnRyaWdnZXIoXCJvblJlc2V0XCIpXHJcbiAgICAgICAgLnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtc2xpZGUtLVwiICsgc2xpZGUuY29udGVudFR5cGUpXHJcbiAgICAgICAgLmFkZENsYXNzKFwiZmFuY3lib3gtc2xpZGUtLWVycm9yXCIpO1xyXG5cclxuICAgICAgc2xpZGUuY29udGVudFR5cGUgPSBcImh0bWxcIjtcclxuXHJcbiAgICAgIHRoaXMuc2V0Q29udGVudChzbGlkZSwgdGhpcy50cmFuc2xhdGUoc2xpZGUsIHNsaWRlLm9wdHMuZXJyb3JUcGwpKTtcclxuXHJcbiAgICAgIGlmIChzbGlkZS5wb3MgPT09IHRoaXMuY3VyclBvcykge1xyXG4gICAgICAgI
109HRoaXMuaXNBbmltYXRpbmcgPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBTaG93IGxvYWRpbmcgaWNvbiBpbnNpZGUgdGhlIHNsaWRlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgc2hvd0xvYWRpbmc6IGZ1bmN0aW9uIChzbGlkZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICBzbGlkZSA9IHNsaWRlIHx8IHNlbGYuY3VycmVudDtcclxuXHJcbiAgICAgIGlmIChzbGlkZSAmJiAhc2xpZGUuJHNwaW5uZXIpIHtcclxuICAgICAgICBzbGlkZS4kc3Bpbm5lciA9ICQoc2VsZi50cmFuc2xhdGUoc2VsZiwgc2VsZi5vcHRzLnNwaW5uZXJUcGwpKVxyXG4gICAgICAgICAgLmFwcGVuZFRvKHNsaWRlLiRzbGlkZSlcclxuICAgICAgICAgIC5oaWRlKClcclxuICAgICAgICAgIC5mYWRlSW4oXCJmYXN0XCIpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFJlbW92ZSBsb2FkaW5nIGljb24gZnJvbSB0aGUgc2xpZGVcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBoaWRlTG9hZGluZzogZnVuY3Rpb24gKHNsaWRlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgIHNsaWRlID0gc2xpZGUgfHwgc2VsZi5jdXJyZW50O1xyXG5cclxuICAgICAgaWYgKHNsaWRlICYmIHNsaWRlLiRzcGlubmVyKSB7XHJcbiAgICAgICAgc2xpZGUuJHNwaW5uZXIuc3RvcCgpLnJlbW92ZSgpO1xyXG5cclxuICAgICAgICBkZWxldGUgc2xpZGUuJHNwaW5uZXI7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gQWRqdXN0bWVudHMgYWZ0ZXIgc2xpZGUgY29udGVudCBoYXMgYmVlbiBsb2FkZWRcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgYWZ0ZXJMb2FkOiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNDbG9zaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzbGlkZS5pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgc2xpZGUuaXNMb2FkZWQgPSB0cnVlO1xyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKFwiYWZ0ZXJMb2FkXCIsIHNsaWRlKTtcclxuXHJcbiAgICAgIHNlbGYuaGlkZUxvYWRpbmcoc2xpZGUpO1xyXG5cclxuICAgICAgLy8gQWRkIHNtYWxsIGNsb3NlIGJ1dHRvblxyXG4gICAgICBpZiAoc2xpZGUub3B0cy5zbWFsbEJ0biAmJiAoIXNsaWRlLiRzbWFsbEJ0biB8fCAhc2xpZGUuJHNtYWxsQnRuLmxlbmd0aCkpIHtcclxuICAgICAgICBzbGlkZS4kc21hbGxCdG4gPSAkKHNlbGYudHJhbnNsYXRlKHNsaWRlLCBzbGlkZS5vcHRzLmJ0blRwbC5zbWFsbEJ0bikpLmFwcGVuZFRvKHNsaWRlLiRjb250ZW50KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRGlzYWJsZSByaWdodCBjbGlja1xyXG4gICAgICBpZiAoc2xpZGUub3B0cy5wcm90ZWN0ICYmIHNsaWRlLiRjb250ZW50ICYmICFzbGlkZS5oYXNFcnJvcikge1xyXG4gICAgICAgIHNsaWRlLiRjb250ZW50Lm9uKFwiY29udGV4dG1lbnUuZmJcIiwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGlmIChlLmJ1dHRvbiA9PSAyKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gQWRkIGZha2UgZWxlbWVudCBvbiB0b3Agb2YgdGhlIGltYWdlXHJcbiAgICAgICAgLy8gVGhpcyBtYWtlcyBhIGJpdCBoYXJkZXIgZm9yIHVzZXIgdG8gc2VsZWN0IGltYWdlXHJcbiAgICAgICAgaWYgKHNsaWRlLnR5cGUgPT09IFwiaW1hZ2VcIikge1xyXG4gICAgICAgICAgJCgnPGRpdiBjbGFzcz1cImZhbmN5Ym94LXNwYWNlYmFsbFwiPjwvZGl2PicpLmFwcGVuZFRvKHNsaWRlLiRjb250ZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYuYWRqdXN0Q2FwdGlvbihzbGlkZSk7XHJcblxyXG4gICAgICBzZWxmLmFkanVzdExheW91dChzbGlkZSk7XHJcblxyXG4gICAgICBpZiAoc2xpZGUucG9zID09PSBzZWxmLmN1cnJQb3MpIHtcclxuICAgICAgICBzZWxmLnVwZGF0ZUN1cnNvcigpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnJldmVhbENvbnRlbnQoc2xpZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBQcmV2ZW50IGNhcHRpb24gb3ZlcmxhcCxcclxuICAgIC8vIGZpeCBjc3MgaW5jb25zaXN0ZW5jeSBhY3Jvc3MgYnJvd3NlcnNcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBhZGp1c3RDYXB0aW9uOiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGN1cnJlbnQgPSBzbGlkZSB8fCBzZWxmLmN1cnJlbnQsXHJcbiAgICAgICAgY2FwdGlvbiA9IGN1cnJlbnQub3B0cy5jYXB0aW9uLFxyXG4gICAgICAgIHByZXZlbnRPdmVybGFwID0gY3VycmVudC5vcHRzLnByZXZlbnRDYXB0aW9uT3ZlcmxhcCxcclxuICAgICAgICAkY2FwdGlvbiA9IHNlbGYuJHJlZnMuY2FwdGlvbixcclxuICAgICAgICAkY2xvbmUsXHJcbiAgICAgICAgY2FwdGlvbkggPSBmYWxzZTtcclxuXHJcbiAgICAgICRjYXB0aW9uLnRvZ2dsZUNsYXNzKFwiZmFuY3lib3gtY2FwdGlvbi0tc2VwYXJhdGVcIiwgcHJldmVudE92ZXJsYXApO1xyXG5cclxuICAgICAgaWYgKHByZXZlbnRPdmVybGFwICYmIGNhcHRpb24gJiYgY2FwdGlvbi5sZW5ndGgpIHtcclxuICAgICAgICBpZiAoY3VycmVudC5wb3MgIT09IHNlbGYuY3VyclBvcykge1xyXG4gICAgICAgICAgJGNsb25lID0gJGNhcHRpb24uY2xvbmUoKS5hcHBlbmRUbygkY2FwdGlvbi5wYXJlbnQoKSk7XHJcblxyXG4gICAgICAgICAgJGNsb25lXHJcbiAgICAgICAgICAgIC5jaGlsZHJlbigpXHJcbiAgICAgICAgICAgIC5lcSgwKVxyXG4gICAgICAgICAgICAuZW1wdHkoKVxyXG4gICAgICAgICAgICAuaHRtbChjYXB0aW9uKTtcclxuXHJcbiAgICAgICAgICBjYXB0aW9uSCA9ICRjbG9uZS5vdXRlckhlaWdodCh0cnVlKTtcclxuXHJcbiAgICAgICAgICAkY2xvbmUuZW1wdHkoKS5yZW1vdmUoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHNlbGYuJGNhcHRpb24pIHtcclxuICAgICAgICAgIGNhcHRpb25I
109ID0gc2VsZi4kY2FwdGlvbi5vdXRlckhlaWdodCh0cnVlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN1cnJlbnQuJHNsaWRlLmNzcyhcInBhZGRpbmctYm90dG9tXCIsIGNhcHRpb25IIHx8IFwiXCIpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFNpbXBsZSBoYWNrIHRvIGZpeCBpbmNvbnNpc3RlbmN5IGFjcm9zcyBicm93c2VycywgZGVzY3JpYmVkIGhlcmUgKGFmZmVjdHMgRWRnZSwgdG9vKTpcclxuICAgIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTc0ODUxOFxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgYWRqdXN0TGF5b3V0OiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGN1cnJlbnQgPSBzbGlkZSB8fCBzZWxmLmN1cnJlbnQsXHJcbiAgICAgICAgc2Nyb2xsSGVpZ2h0LFxyXG4gICAgICAgIG1hcmdpbkJvdHRvbSxcclxuICAgICAgICBpbmxpbmVQYWRkaW5nLFxyXG4gICAgICAgIGFjdHVhbFBhZGRpbmc7XHJcblxyXG4gICAgICBpZiAoY3VycmVudC5pc0xvYWRlZCAmJiBjdXJyZW50Lm9wdHMuZGlzYWJsZUxheW91dEZpeCAhPT0gdHJ1ZSkge1xyXG4gICAgICAgIGN1cnJlbnQuJGNvbnRlbnQuY3NzKFwibWFyZ2luLWJvdHRvbVwiLCBcIlwiKTtcclxuXHJcbiAgICAgICAgLy8gSWYgd2Ugd291bGQgYWx3YXlzIHNldCBtYXJnaW4tYm90dG9tIGZvciB0aGUgY29udGVudCxcclxuICAgICAgICAvLyB0aGVuIGl0IHdvdWxkIHBvdGVudGlhbGx5IGJyZWFrIHZlcnRpY2FsIGFsaWduXHJcbiAgICAgICAgaWYgKGN1cnJlbnQuJGNvbnRlbnQub3V0ZXJIZWlnaHQoKSA+IGN1cnJlbnQuJHNsaWRlLmhlaWdodCgpICsgMC41KSB7XHJcbiAgICAgICAgICBpbmxpbmVQYWRkaW5nID0gY3VycmVudC4kc2xpZGVbMF0uc3R5bGVbXCJwYWRkaW5nLWJvdHRvbVwiXTtcclxuICAgICAgICAgIGFjdHVhbFBhZGRpbmcgPSBjdXJyZW50LiRzbGlkZS5jc3MoXCJwYWRkaW5nLWJvdHRvbVwiKTtcclxuXHJcbiAgICAgICAgICBpZiAocGFyc2VGbG9hdChhY3R1YWxQYWRkaW5nKSA+IDApIHtcclxuICAgICAgICAgICAgc2Nyb2xsSGVpZ2h0ID0gY3VycmVudC4kc2xpZGVbMF0uc2Nyb2xsSGVpZ2h0O1xyXG5cclxuICAgICAgICAgICAgY3VycmVudC4kc2xpZGUuY3NzKFwicGFkZGluZy1ib3R0b21cIiwgMCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoc2Nyb2xsSGVpZ2h0IC0gY3VycmVudC4kc2xpZGVbMF0uc2Nyb2xsSGVpZ2h0KSA8IDEpIHtcclxuICAgICAgICAgICAgICBtYXJnaW5Cb3R0b20gPSBhY3R1YWxQYWRkaW5nO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50LiRzbGlkZS5jc3MoXCJwYWRkaW5nLWJvdHRvbVwiLCBpbmxpbmVQYWRkaW5nKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN1cnJlbnQuJGNvbnRlbnQuY3NzKFwibWFyZ2luLWJvdHRvbVwiLCBtYXJnaW5Cb3R0b20pO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIE1ha2UgY29udGVudCB2aXNpYmxlXHJcbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgcmlnaHQgYWZ0ZXIgY29udGVudCBoYXMgYmVlbiBsb2FkZWQgb3JcclxuICAgIC8vIHVzZXIgbmF2aWdhdGVzIGdhbGxlcnkgYW5kIHRyYW5zaXRpb24gc2hvdWxkIHN0YXJ0XHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICByZXZlYWxDb250ZW50OiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICRzbGlkZSA9IHNsaWRlLiRzbGlkZSxcclxuICAgICAgICBlbmQgPSBmYWxzZSxcclxuICAgICAgICBzdGFydCA9IGZhbHNlLFxyXG4gICAgICAgIGlzTW92ZWQgPSBzZWxmLmlzTW92ZWQoc2xpZGUpLFxyXG4gICAgICAgIGlzUmV2ZWFsZWQgPSBzbGlkZS5pc1JldmVhbGVkLFxyXG4gICAgICAgIGVmZmVjdCxcclxuICAgICAgICBlZmZlY3RDbGFzc05hbWUsXHJcbiAgICAgICAgZHVyYXRpb24sXHJcbiAgICAgICAgb3BhY2l0eTtcclxuXHJcbiAgICAgIHNsaWRlLmlzUmV2ZWFsZWQgPSB0cnVlO1xyXG5cclxuICAgICAgZWZmZWN0ID0gc2xpZGUub3B0c1tzZWxmLmZpcnN0UnVuID8gXCJhbmltYXRpb25FZmZlY3RcIiA6IFwidHJhbnNpdGlvbkVmZmVjdFwiXTtcclxuICAgICAgZHVyYXRpb24gPSBzbGlkZS5vcHRzW3NlbGYuZmlyc3RSdW4gPyBcImFuaW1hdGlvbkR1cmF0aW9uXCIgOiBcInRyYW5zaXRpb25EdXJhdGlvblwiXTtcclxuXHJcbiAgICAgIGR1cmF0aW9uID0gcGFyc2VJbnQoc2xpZGUuZm9yY2VkRHVyYXRpb24gPT09IHVuZGVmaW5lZCA/IGR1cmF0aW9uIDogc2xpZGUuZm9yY2VkRHVyYXRpb24sIDEwKTtcclxuXHJcbiAgICAgIGlmIChpc01vdmVkIHx8IHNsaWRlLnBvcyAhPT0gc2VsZi5jdXJyUG9zIHx8ICFkdXJhdGlvbikge1xyXG4gICAgICAgIGVmZmVjdCA9IGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDaGVjayBpZiBjYW4gem9vbVxyXG4gICAgICBpZiAoZWZmZWN0ID09PSBcInpvb21cIikge1xyXG4gICAgICAgIGlmIChzbGlkZS5wb3MgPT09IHNlbGYuY3VyclBvcyAmJiBkdXJhdGlvbiAmJiBzbGlkZS50eXBlID09PSBcImltYWdlXCIgJiYgIXNsaWRlLmhhc0Vycm9yICYmIChzdGFydCA9IHNlbGYuZ2V0VGh1bWJQb3Moc2xpZGUpKSkge1xyXG4gICAgICAgICAgZW5kID0gc2VsZi5nZXRGaXRQb3Moc2xpZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBlZmZlY3QgPSBcImZhZGVcIjtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFpvb20gYW5pbWF0aW9uXHJcbiAgICAgIC8vID09PT09PT09PT09PT09XHJcbiAgICAgIGlmIChlZmZlY3QgPT09IFwiem9vbVwiKSB7XHJcbiAgICAgICAgc2VsZi5pc0FuaW1hdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIGVuZC5zY2FsZVggPSBlbmQud2lkdGggLyBzdGFydC53aWR0aDtcclxuICAgICAgICBlbmQuc2NhbGVZID0gZW5kLmhlaWdodCAvIHN0YXJ0LmhlaWdodDtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byBhbmltYXRlIG9wYWNpdHlcclxuICAgICAgICBvcGFjaXR5ID0gc2xpZGUub3B0cy56b29tT3BhY2l0eTtcclxuXHJcbiAgICAgICAgaWYgKG9wYWNpdHkgPT0gXCJhdXRvXCIpIHtcclxuICAgICAgICAgIG9wYWNpdHkgPSBNYXRoLmFicyhzbGlkZS53aWR0aCAvIHNsaWRlLmhlaWdodCAtIHN0YXJ0LndpZHRoIC8gc3RhcnQuaGVpZ2h0KSA+IDAuMTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvcGFjaXR5KSB7XHJcbiAgICAgICAgICBzdGFydC5vcGFjaXR5ID0gMC4xO1xyXG4gICAgICAgICAgZW5kLm9wYWNpdHkgPSAxO1xyXG4gICAgICAgI
109H1cclxuXHJcbiAgICAgICAgLy8gRHJhdyBpbWFnZSBhdCBzdGFydCBwb3NpdGlvblxyXG4gICAgICAgICQuZmFuY3lib3guc2V0VHJhbnNsYXRlKHNsaWRlLiRjb250ZW50LnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtaXMtaGlkZGVuXCIpLCBzdGFydCk7XHJcblxyXG4gICAgICAgIGZvcmNlUmVkcmF3KHNsaWRlLiRjb250ZW50KTtcclxuXHJcbiAgICAgICAgLy8gU3RhcnQgYW5pbWF0aW9uXHJcbiAgICAgICAgJC5mYW5jeWJveC5hbmltYXRlKHNsaWRlLiRjb250ZW50LCBlbmQsIGR1cmF0aW9uLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBzZWxmLmlzQW5pbWF0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgc2VsZi5jb21wbGV0ZSgpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYudXBkYXRlU2xpZGUoc2xpZGUpO1xyXG5cclxuICAgICAgLy8gU2ltcGx5IHNob3cgY29udGVudCBpZiBubyBlZmZlY3RcclxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAgICAgaWYgKCFlZmZlY3QpIHtcclxuICAgICAgICBzbGlkZS4kY29udGVudC5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LWlzLWhpZGRlblwiKTtcclxuXHJcbiAgICAgICAgaWYgKCFpc1JldmVhbGVkICYmIGlzTW92ZWQgJiYgc2xpZGUudHlwZSA9PT0gXCJpbWFnZVwiICYmICFzbGlkZS5oYXNFcnJvcikge1xyXG4gICAgICAgICAgc2xpZGUuJGNvbnRlbnQuaGlkZSgpLmZhZGVJbihcImZhc3RcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc2xpZGUucG9zID09PSBzZWxmLmN1cnJQb3MpIHtcclxuICAgICAgICAgIHNlbGYuY29tcGxldGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gUHJlcGFyZSBmb3IgQ1NTIHRyYW5zaXRvblxyXG4gICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgICAgICQuZmFuY3lib3guc3RvcCgkc2xpZGUpO1xyXG5cclxuICAgICAgLy9lZmZlY3RDbGFzc05hbWUgPSBcImZhbmN5Ym94LWFuaW1hdGVkIGZhbmN5Ym94LXNsaWRlLS1cIiArIChzbGlkZS5wb3MgPj0gc2VsZi5wcmV2UG9zID8gXCJuZXh0XCIgOiBcInByZXZpb3VzXCIpICsgXCIgZmFuY3lib3gtZngtXCIgKyBlZmZlY3Q7XHJcbiAgICAgIGVmZmVjdENsYXNzTmFtZSA9IFwiZmFuY3lib3gtc2xpZGUtLVwiICsgKHNsaWRlLnBvcyA+PSBzZWxmLnByZXZQb3MgPyBcIm5leHRcIiA6IFwicHJldmlvdXNcIikgKyBcIiBmYW5jeWJveC1hbmltYXRlZCBmYW5jeWJveC1meC1cIiArIGVmZmVjdDtcclxuXHJcbiAgICAgICRzbGlkZS5hZGRDbGFzcyhlZmZlY3RDbGFzc05hbWUpLnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtc2xpZGUtLWN1cnJlbnRcIik7IC8vLmFkZENsYXNzKGVmZmVjdENsYXNzTmFtZSk7XHJcblxyXG4gICAgICBzbGlkZS4kY29udGVudC5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LWlzLWhpZGRlblwiKTtcclxuXHJcbiAgICAgIC8vIEZvcmNlIHJlZmxvd1xyXG4gICAgICBmb3JjZVJlZHJhdygkc2xpZGUpO1xyXG5cclxuICAgICAgaWYgKHNsaWRlLnR5cGUgIT09IFwiaW1hZ2VcIikge1xyXG4gICAgICAgIHNsaWRlLiRjb250ZW50LmhpZGUoKS5zaG93KDApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkLmZhbmN5Ym94LmFuaW1hdGUoXHJcbiAgICAgICAgJHNsaWRlLFxyXG4gICAgICAgIFwiZmFuY3lib3gtc2xpZGUtLWN1cnJlbnRcIixcclxuICAgICAgICBkdXJhdGlvbixcclxuICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAkc2xpZGUucmVtb3ZlQ2xhc3MoZWZmZWN0Q2xhc3NOYW1lKS5jc3Moe1xyXG4gICAgICAgICAgICB0cmFuc2Zvcm06IFwiXCIsXHJcbiAgICAgICAgICAgIG9wYWNpdHk6IFwiXCJcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIGlmIChzbGlkZS5wb3MgPT09IHNlbGYuY3VyclBvcykge1xyXG4gICAgICAgICAgICBzZWxmLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICB0cnVlXHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENoZWNrIGlmIHdlIGNhbiBhbmQgaGF2ZSB0byB6b29tIGZyb20gdGh1bWJuYWlsXHJcbiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGdldFRodW1iUG9zOiBmdW5jdGlvbiAoc2xpZGUpIHtcclxuICAgICAgdmFyIHJleiA9IGZhbHNlLFxyXG4gICAgICAgICR0aHVtYiA9IHNsaWRlLiR0aHVtYixcclxuICAgICAgICB0aHVtYlBvcyxcclxuICAgICAgICBidHcsXHJcbiAgICAgICAgYnJ3LFxyXG4gICAgICAgIGJidyxcclxuICAgICAgICBibHc7XHJcblxyXG4gICAgICBpZiAoISR0aHVtYiB8fCAhaW5WaWV3cG9ydCgkdGh1bWJbMF0pKSB7X
109HJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aHVtYlBvcyA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKCR0aHVtYik7XHJcblxyXG4gICAgICBidHcgPSBwYXJzZUZsb2F0KCR0aHVtYi5jc3MoXCJib3JkZXItdG9wLXdpZHRoXCIpIHx8IDApO1xyXG4gICAgICBicncgPSBwYXJzZUZsb2F0KCR0aHVtYi5jc3MoXCJib3JkZXItcmlnaHQtd2lkdGhcIikgfHwgMCk7XHJcbiAgICAgIGJidyA9IHBhcnNlRmxvYXQoJHRodW1iLmNzcyhcImJvcmRlci1ib3R0b20td2lkdGhcIikgfHwgMCk7XHJcbiAgICAgIGJsdyA9IHBhcnNlRmxvYXQoJHRodW1iLmNzcyhcImJvcmRlci1sZWZ0LXdpZHRoXCIpIHx8IDApO1xyXG5cclxuICAgICAgcmV6ID0ge1xyXG4gICAgICAgIHRvcDogdGh1bWJQb3MudG9wICsgYnR3LFxyXG4gICAgICAgIGxlZnQ6IHRodW1iUG9zLmxlZnQgKyBibHcsXHJcbiAgICAgICAgd2lkdGg6IHRodW1iUG9zLndpZHRoIC0gYnJ3IC0gYmx3LFxyXG4gICAgICAgIGhlaWdodDogdGh1bWJQb3MuaGVpZ2h0IC0gYnR3IC0gYmJ3LFxyXG4gICAgICAgIHNjYWxlWDogMSxcclxuICAgICAgICBzY2FsZVk6IDFcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiB0aHVtYlBvcy53aWR0aCA+IDAgJiYgdGh1bWJQb3MuaGVpZ2h0ID4gMCA/IHJleiA6IGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBGaW5hbCBhZGp1c3RtZW50cyBhZnRlciBjdXJyZW50IGdhbGxlcnkgaXRlbSBpcyBtb3ZlZCB0byBwb3NpdGlvblxyXG4gICAgLy8gYW5kIGl0YHMgY29udGVudCBpcyBsb2FkZWRcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGNvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBjdXJyZW50ID0gc2VsZi5jdXJyZW50LFxyXG4gICAgICAgIHNsaWRlcyA9IHt9LFxyXG4gICAgICAgICRlbDtcclxuXHJcbiAgICAgIGlmIChzZWxmLmlzTW92ZWQoKSB8fCAhY3VycmVudC5pc0xvYWRlZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFjdXJyZW50LmlzQ29tcGxldGUpIHtcclxuICAgICAgICBjdXJyZW50LmlzQ29tcGxldGUgPSB0cnVlO1xyXG5cclxuICAgICAgICBjdXJyZW50LiRzbGlkZS5zaWJsaW5ncygpLnRyaWdnZXIoXCJvblJlc2V0XCIpO1xyXG5cclxuICAgICAgICBzZWxmLnByZWxvYWQoXCJpbmxpbmVcIik7XHJcblxyXG4gICAgICAgIC8vIFRyaWdnZXIgYW55IENTUyB0cmFuc2l0b24gaW5zaWRlIHRoZSBzbGlkZVxyXG4gICAgICAgIGZvcmNlUmVkcmF3KGN1cnJlbnQuJHNsaWRlKTtcclxuXHJcbiAgICAgICAgY3VycmVudC4kc2xpZGUuYWRkQ2xhc3MoXCJmYW5jeWJveC1zbGlkZS0tY29tcGxldGVcIik7XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSB1bm5lY2Vzc2FyeSBzbGlkZXNcclxuICAgICAgICAkLmVhY2goc2VsZi5zbGlkZXMsIGZ1bmN0aW9uIChrZXksIHNsaWRlKSB7XHJcbiAgICAgICAgICBpZiAoc2xpZGUucG9zID49IHNlbGYuY3VyclBvcyAtIDEgJiYgc2xpZGUucG9zIDw9IHNlbGYuY3VyclBvcyArIDEpIHtcclxuICAgICAgICAgICAgc2xpZGVzW3NsaWRlLnBvc10gPSBzbGlkZTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoc2xpZGUpIHtcclxuICAgICAgICAgICAgJC5mYW5jeWJveC5zdG9wKHNsaWRlLiRzbGlkZSk7XHJcblxyXG4gICAgICAgICAgICBzbGlkZS4kc2xpZGUub2ZmKCkucmVtb3ZlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHNlbGYuc2xpZGVzID0gc2xpZGVzO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLmlzQW5pbWF0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICBzZWxmLnVwZGF0ZUN1cnNvcigpO1xyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKFwiYWZ0ZXJTaG93XCIpO1xyXG5cclxuICAgICAgLy8gQXV0b3BsYXkgZmlyc3QgaHRtbDUgdmlkZW8vYXVkaW9cclxuICAgICAgaWYgKCEhY3VycmVudC5vcHRzLnZpZGVvLmF1dG9TdGFydCkge1xyXG4gICAgICAgIGN1cnJlbnQuJHNsaWRlXHJcbiAgICAgICAgICAuZmluZChcInZpZGVvLGF1ZGlvXCIpXHJcbiAgICAgICAgICAuZmlsdGVyKFwiOnZpc2libGU6Zmlyc3RcIilcclxuICAgICAgICAgIC50cmlnZ2VyKFwicGxheVwiKVxyXG4gICAgICAgICAgLm9uZShcImVuZGVkXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKERvY3VtZW50LmV4aXRGdWxsc2NyZWVuKSB7XHJcbiAgICAgICAgICAgICAgRG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLndlYmtpdEV4aXRGdWxsc2NyZWVuKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy53ZWJraXRFeGl0RnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzZWxmLm5leHQoKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBUcnkgdG8gZm9jdXMgb24gdGhlIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50XHJcbiAgICAgIGlmIChjdXJyZW50Lm9wdHMuYXV0b0ZvY3VzICYmIGN1cnJlbnQuY29udGVudFR5cGUgPT09IFwiaHRtbFwiKSB7XHJcbiAgICAgICAgLy8gTG9vayBmb3IgdGhlIGZpcnN0IGlucHV0IHdpdGggYXV0b2ZvY3VzIGF0dHJpYnV0ZVxyXG4gICAgICAgICRlbCA9IGN1cnJlbnQuJGNvbnRlbnQuZmluZChcImlucHV0W2F1dG9mb2N1c106ZW5hYmxlZDp2aXNpYmxlOmZpcnN0XCIpO1xyXG5cclxuICAgICAgICBpZiAoJGVsLmxlbmd0aCkge1xyXG4gICAgICAgICAgJGVsLnRyaWdnZXIoXCJmb2N1c1wiKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2VsZi5mb2N1cy
109hudWxsLCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEF2b2lkIGp1bXBpbmdcclxuICAgICAgY3VycmVudC4kc2xpZGUuc2Nyb2xsVG9wKDApLnNjcm9sbExlZnQoMCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFByZWxvYWQgbmV4dCBhbmQgcHJldmlvdXMgc2xpZGVzXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHByZWxvYWQ6IGZ1bmN0aW9uICh0eXBlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBwcmV2LFxyXG4gICAgICAgIG5leHQ7XHJcblxyXG4gICAgICBpZiAoc2VsZi5ncm91cC5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBuZXh0ID0gc2VsZi5zbGlkZXNbc2VsZi5jdXJyUG9zICsgMV07XHJcbiAgICAgIHByZXYgPSBzZWxmLnNsaWRlc1tzZWxmLmN1cnJQb3MgLSAxXTtcclxuXHJcbiAgICAgIGlmIChwcmV2ICYmIHByZXYudHlwZSA9PT0gdHlwZSkge1xyXG4gICAgICAgIHNlbGYubG9hZFNsaWRlKHByZXYpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAobmV4dCAmJiBuZXh0LnR5cGUgPT09IHR5cGUpIHtcclxuICAgICAgICBzZWxmLmxvYWRTbGlkZShuZXh0KTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBUcnkgdG8gZmluZCBhbmQgZm9jdXMgb24gdGhlIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50XHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgZm9jdXM6IGZ1bmN0aW9uIChlLCBmaXJzdFJ1bikge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgZm9jdXNhYmxlU3RyID0gW1xyXG4gICAgICAgICAgXCJhW2hyZWZdXCIsXHJcbiAgICAgICAgICBcImFyZWFbaHJlZl1cIixcclxuICAgICAgICAgICdpbnB1dDpub3QoW2Rpc2FibGVkXSk6bm90KFt0eXBlPVwiaGlkZGVuXCJdKTpub3QoW2FyaWEtaGlkZGVuXSknLFxyXG4gICAgICAgICAgXCJzZWxlY3Q6bm90KFtkaXNhYmxlZF0pOm5vdChbYXJpYS1oaWRkZW5dKVwiLFxyXG4gICAgICAgICAgXCJ0ZXh0YXJlYTpub3QoW2Rpc2FibGVkXSk6bm90KFthcmlhLWhpZGRlbl0pXCIsXHJcbiAgICAgICAgICBcImJ1dHRvbjpub3QoW2Rpc2FibGVkXSk6bm90KFthcmlhLWhpZGRlbl0pXCIsXHJcbiAgICAgICAgICBcImlmcmFtZVwiLFxyXG4gICAgICAgICAgXCJvYmplY3RcIixcclxuICAgICAgICAgIFwiZW1iZWRcIixcclxuICAgICAgICAgIFwidmlkZW9cIixcclxuICAgICAgICAgIFwiYXVkaW9cIixcclxuICAgICAgICAgIFwiW2NvbnRlbnRlZGl0YWJsZV1cIixcclxuICAgICAgICAgICdbdGFiaW5kZXhdOm5vdChbdGFiaW5kZXhePVwiLVwiXSknXHJcbiAgICAgICAgXS5qb2luKFwiLFwiKSxcclxuICAgICAgICBmb2N1c2FibGVJdGVtcyxcclxuICAgICAgICBmb2N1c2VkSXRlbUluZGV4O1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNDbG9zaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoZSB8fCAhc2VsZi5jdXJyZW50IHx8ICFzZWxmLmN1cnJlbnQuaXNDb21wbGV0ZSkge1xyXG4gICAgICAgIC8vIEZvY3VzIG9uIGFueSBlbGVtZW50IGluc2lkZSBmYW5jeWJveFxyXG4gICAgICAgIGZvY3VzYWJsZUl0ZW1zID0gc2VsZi4kcmVmcy5jb250YWluZXIuZmluZChcIio6dmlzaWJsZVwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBGb2N1cyBpbnNpZGUgY3VycmVudCBzbGlkZVxyXG4gICAgICAgIGZvY3VzYWJsZUl0ZW1zID0gc2VsZi5jdXJyZW50LiRzbGlkZS5maW5kKFwiKjp2aXNpYmxlXCIgKyAoZmlyc3RSdW4gPyBcIjpub3QoLmZhbmN5Ym94LWNsb3NlLXNtYWxsKVwiIDogXCJcIikpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBmb2N1c2FibGVJdGVtcyA9IGZvY3VzYWJsZUl0ZW1zLmZpbHRlcihmb2N1c2FibGVTdHIpLmZpbHRlcihmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuICQodGhpcykuY3NzKFwidmlzaWJpbGl0eVwiKSAhPT0gXCJoaWRkZW5cIiAmJiAhJCh0aGlzKS5oYXNDbGFzcyhcImRpc2FibGVkXCIpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmIChmb2N1c2FibGVJdGVtcy5sZW5ndGgpIHtcclxuICAgICAgICBmb2N1c2VkSXRlbUluZGV4ID0gZm9jdXNhYmxlSXRlbXMuaW5kZXgoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCk7XHJcblxyXG4gICAgICAgIGlmIChlICYmIGUuc2hpZnRLZXkpIHtcclxuICAgICAgICAgIC8vIEJhY2sgdGFiXHJcbiAgICAgICAgICBpZiAoZm9jdXNlZEl0ZW1JbmRleCA8IDAgfHwgZm9jdXNlZEl0ZW1JbmRleCA9PSAwKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgIGZvY3VzYWJsZUl0ZW1zLmVxKGZvY3VzYWJsZUl0ZW1zLmxlbmd0aCAtIDEpLnRyaWdnZXIoXCJmb2N1c1wiKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gT3V0c2lkZSBvciBGb3J3YXJkIHRhYlxyXG4gICAgICAgICAgaWYgKGZvY3VzZWRJdGVtSW5kZXggPCAwIHx8IGZvY3VzZWRJdGVtSW5kZXggPT0gZm9jdXNhYmxlSXRlbXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICBpZiAoZSkge1xyXG4gICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9jdXNhYmxlSXRlbXMuZXEoMCkudHJpZ2dlcihcImZvY3VzXCIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzZWxmLiRyZWZzLmNvbnRhaW5lci50cmlnZ2VyKFwiZm9jdXNcIik7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gQWN0aXZhdGVzIGN1cnJlbnQgaW5zdGFuY2UgLSBicmluZ3MgY29udGFpbmVyIHRvIHRoZSBmcm9udCBhbmQgZW5hYmxlcyBrZXlib2FyZCxcclxuICAgIC8vIG5vdGlmaWVzIG90aGVyIGluc3RhbmNlcyBhYm91dCBkZWFjdGl2YXRpbmdcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGFjdGl2YXRlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgIC8vIERlYWN0aXZhdGUgYWxsIGluc3RhbmNlc1xyXG4gICAgICAkKFwiLmZhbmN5Ym94LWNvbnRhaW5lclwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
109XIgaW5zdGFuY2UgPSAkKHRoaXMpLmRhdGEoXCJGYW5jeUJveFwiKTtcclxuXHJcbiAgICAgICAgLy8gU2tpcCBzZWxmIGFuZCBjbG9zaW5nIGluc3RhbmNlc1xyXG4gICAgICAgIGlmIChpbnN0YW5jZSAmJiBpbnN0YW5jZS5pZCAhPT0gc2VsZi5pZCAmJiAhaW5zdGFuY2UuaXNDbG9zaW5nKSB7XHJcbiAgICAgICAgICBpbnN0YW5jZS50cmlnZ2VyKFwib25EZWFjdGl2YXRlXCIpO1xyXG5cclxuICAgICAgICAgIGluc3RhbmNlLnJlbW92ZUV2ZW50cygpO1xyXG5cclxuICAgICAgICAgIGluc3RhbmNlLmlzVmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICBzZWxmLmlzVmlzaWJsZSA9IHRydWU7XHJcblxyXG4gICAgICBpZiAoc2VsZi5jdXJyZW50IHx8IHNlbGYuaXNJZGxlKSB7XHJcbiAgICAgICAgc2VsZi51cGRhdGUoKTtcclxuXHJcbiAgICAgICAgc2VsZi51cGRhdGVDb250cm9scygpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnRyaWdnZXIoXCJvbkFjdGl2YXRlXCIpO1xyXG5cclxuICAgICAgc2VsZi5hZGRFdmVudHMoKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gU3RhcnQgY2xvc2luZyBwcm9jZWR1cmVcclxuICAgIC8vIFRoaXMgd2lsbCBzdGFydCBcInpvb20tb3V0XCIgYW5pbWF0aW9uIGlmIG5lZWRlZCBhbmQgY2xlYW4gZXZlcnl0aGluZyB1cCBhZnRlcndhcmRzXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBjbG9zZTogZnVuY3Rpb24gKGUsIGQpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGN1cnJlbnQgPSBzZWxmLmN1cnJlbnQsXHJcbiAgICAgICAgZWZmZWN0LFxyXG4gICAgICAgIGR1cmF0aW9uLFxyXG4gICAgICAgICRjb250ZW50LFxyXG4gICAgICAgIGRvbVJlY3QsXHJcbiAgICAgICAgb3BhY2l0eSxcclxuICAgICAgICBzdGFydCxcclxuICAgICAgICBlbmQ7XHJcblxyXG4gICAgICB2Y
109XIgZG9uZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBzZWxmLmNsZWFuVXAoZSk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoc2VsZi5pc0Nsb3NpbmcpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYuaXNDbG9zaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgIC8vIElmIGJlZm9yZUNsb3NlIGNhbGxiYWNrIHByZXZlbnRzIGNsb3NpbmcsIG1ha2Ugc3VyZSBjb250ZW50IGlzIGNlbnRlcmVkXHJcbiAgICAgIGlmIChzZWxmLnRyaWdnZXIoXCJiZWZvcmVDbG9zZVwiLCBlKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICBzZWxmLmlzQ2xvc2luZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICByZXF1ZXN0QUZyYW1lKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYudXBkYXRlKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHNcclxuICAgICAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGluc3RhbmNlcywgdGhleSB3aWxsIGJlIHNldCBhZ2FpbiBieSBcImFjdGl2YXRlXCIgbWV0aG9kXHJcbiAgICAgIHNlbGYucmVtb3ZlRXZlbnRzKCk7XHJcblxyXG4gICAgICAkY29udGVudCA9IGN1cnJlbnQuJGNvbnRlbnQ7XHJcbiAgICAgIGVmZmVjdCA9IGN1cnJlbnQub3B0cy5hbmltYXRpb25FZmZlY3Q7XHJcbiAgICAgIGR1cmF0aW9uID0gJC5pc051bWVyaWMoZCkgPyBkIDogZWZmZWN0ID8gY3VycmVudC5vcHRzLmFuaW1hdGlvbkR1cmF0aW9uIDogMDtcclxuXHJcbiAgICAgIGN1cnJlbnQuJHNsaWRlLnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtc2xpZGUtLWNvbXBsZXRlIGZhbmN5Ym94LXNsaWRlLS1uZXh0IGZhbmN5Ym94LXNsaWRlLS1wcmV2aW91cyBmYW5jeWJveC1hbmltYXRlZFwiKTtcclxuXHJcbiAgICAgIGlmIChlICE9PSB0cnVlKSB7XHJcbiAgICAgICAgJC5mYW5jeWJveC5zdG9wKGN1cnJlbnQuJHNsaWRlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlZmZlY3QgPSBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gUmVtb3ZlIG90aGVyIHNsaWRlc1xyXG4gICAgICBjdXJyZW50LiRzbGlkZVxyXG4gICAgICAgIC5zaWJsaW5ncygpXHJcbiAgICAgICAgLnRyaWdnZXIoXCJvblJlc2V0XCIpXHJcbiAgICAgICAgLnJlbW92ZSgpO1xyXG5cclxuICAgICAgLy8gVHJpZ2dlciBhbmltYXRpb25zXHJcbiAgICAgIGlmIChkdXJhdGlvbikge1xyXG4gICAgICAgIHNlbGYuJHJlZnMuY29udGFpbmVyXHJcbiAgICAgICAgICAucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1pcy1vcGVuXCIpXHJcbiAgICAgICAgICAuYWRkQ2xhc3MoXCJmYW5jeWJveC1pcy1jbG9zaW5nXCIpXHJcbiAgICAgICAgICAuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLCBkdXJhdGlvbiArIFwibXNcIik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIENsZWFuIHVwXHJcbiAgICAgIHNlbGYuaGlkZUxvYWRpbmcoY3VycmVudCk7XHJcblxyXG4gICAgICBzZWxmLmhpZGVDb250cm9scyh0cnVlKTtcclxuXHJcbiAgICAgIHNlbGYudXBkYXRlQ3Vyc29yKCk7XHJcblxyXG4gICAgICAvLyBDaGVjayBpZiBwb3NzaWJsZSB0byB6b29tLW91dFxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgZWZmZWN0ID09PSBcInpvb21cIiAmJlxyXG4gICAgICAgICEoJGNvbnRlbnQgJiYgZHVyYXRpb24gJiYgY3VycmVudC50eXBlID09PSBcImltYWdlXCIgJiYgIXNlbGYuaXNNb3ZlZCgpICYmICFjdXJyZW50Lmhhc0Vycm9yICYmIChlbmQgPSBzZWxmLmdldFRodW1iUG9zKGN1cnJlbnQpKSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgZWZmZWN0ID0gXCJmYWRlXCI7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlZmZlY3QgPT09IFwiem9vbVwiKSB7XHJcbiAgICAgICAgJC5mYW5jeWJveC5zdG9wKCRjb250ZW50KTtcclxuXHJcbiAgICAgICAgZG9tUmVjdCA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKCRjb250ZW50KTtcclxuXHJcbiAgICAgICAgc3RhcnQgPSB7XHJcbiAgICAgICAgICB0b3A6IGRvbVJlY3QudG9wLFxyXG4gICAgICAgICAgbGVmdDogZG9tUmVjdC5sZWZ0LFxyXG4gICAgICAgICAgc2NhbGVYOiBkb21SZWN0LndpZHRoIC8gZW5kLndpZHRoLFxyXG4gICAgICAgICAgc2NhbGVZOiBkb21SZWN0LmhlaWdodCAvIGVuZC5oZWlnaHQsXHJcbiAgICAgICAgICB3aWR0aDogZW5kLndpZHRoLFxyXG4gICAgICAgICAgaGVpZ2h0OiBlbmQuaGVpZ2h0XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byBhbmltYXRlIG9wYWNpdHlcclxuICAgICAgICBvcGFjaXR5ID0gY3VycmVudC5vcHRzLnpvb21PcGFjaXR5O1xyXG5cclxuICAgICAgICBpZiAob3BhY2l0eSA9PSBcImF1dG9cIikge1xyXG4gICAgICAgICAgb3BhY2l0eSA9IE1hdGguYWJzKGN1cnJlbnQud2lkdGggLyBjdXJyZW50LmhlaWdodCAtIGVuZC53aWR0aCAvIGVuZC5oZWlnaHQpID4gMC4xO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9wYWNpdHkpIHtcclxuICAgICAgICAgIGVuZC5vcGFjaXR5ID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQuZmFuY3lib3guc2V0VHJhbnNsYXRlKCRjb250ZW50LCBzdGFydCk7XHJcblxyXG4gICAgICAgIGZvcmNlUmVkcmF3KCRjb250ZW50KTtcclxuXHJcbiAgICAgICAgJC5mYW5jeWJveC5hbmltYXRlKCRjb250ZW50LCBlbmQsIGR1cmF0aW9uLCBkb25lKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlZmZlY3QgJiYgZHVyYXRpb24pIHtcclxuICAgICAgICAkLmZhbmN5Ym94LmFuaW1hdGUoXHJcbiAgICAgICAgICBjdXJyZW50LiRzbGlkZS5hZGRDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1wcmV2aW91c1wiKS5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LXNsaWRlLS1jdXJyZW50XCIpLFxyXG4gICAgICAgICAgXCJmYW5jeWJveC1hbmltYXRlZCBmYW5jeWJveC1meC1cIiArIGVmZmVjdCxcclxuICAgICAgICAgIGR1cmF0aW9uLFxyXG4gICAgICAgICAgZG9uZVxyXG4gICAgICAgICk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gSWYgc2tpcCBhbmltYXRpb25cclxuICAgICAgICBpZiAoZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgc2V0VGltZW91dChkb25lLCBkdXJhdGlvbik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGRvbmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybi
109B0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBGaW5hbCBhZGp1c3RtZW50cyBhZnRlciByZW1vdmluZyB0aGUgaW5zdGFuY2VcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGNsZWFuVXA6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBpbnN0YW5jZSxcclxuICAgICAgICAkZm9jdXMgPSBzZWxmLmN1cnJlbnQub3B0cy4kb3JpZyxcclxuICAgICAgICB4LFxyXG4gICAgICAgIHk7XHJcblxyXG4gICAgICBzZWxmLmN1cnJlbnQuJHNsaWRlLnRyaWdnZXIoXCJvblJlc2V0XCIpO1xyXG5cclxuICAgICAgc2VsZi4kcmVmcy5jb250YWluZXIuZW1wdHkoKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgIHNlbGYudHJpZ2dlcihcImFmdGVyQ2xvc2VcIiwgZSk7XHJcblxyXG4gICAgICAvLyBQbGFjZSBiYWNrIGZvY3VzXHJcbiAgICAgIGlmICghIXNlbGYuY3VycmVudC5vcHRzLmJhY2tGb2N1cykge1xyXG4gICAgICAgIGlmICghJGZvY3VzIHx8ICEkZm9jdXMubGVuZ3RoIHx8ICEkZm9jdXMuaXMoXCI6dmlzaWJsZVwiKSkge1xyXG4gICAgICAgICAgJGZvY3VzID0gc2VsZi4kdHJpZ2dlcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICgkZm9jdXMgJiYgJGZvY3VzLmxlbmd0aCkge1xyXG4gICAgICAgICAgeCA9IHdpbmRvdy5zY3JvbGxYO1xyXG4gICAgICAgICAgeSA9IHdpbmRvdy5zY3JvbGxZO1xyXG5cclxuICAgICAgICAgICRmb2N1cy50cmlnZ2VyKFwiZm9jdXNcIik7XHJcblxyXG4gICAgICAgICAgJChcImh0bWwsIGJvZHlcIilcclxuICAgICAgICAgICAgLnNjcm9sbFRvcCh5KVxyXG4gICAgICAgICAgICAuc2Nyb2xsTGVmdCh4KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYuY3VycmVudCA9IG51bGw7XHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGVyZSBhcmUgb3RoZXIgaW5zdGFuY2VzXHJcbiAgICAgIGluc3RhbmNlID0gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuYWN0aXZhdGUoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAkKFwiYm9keVwiKS5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LWFjdGl2ZSBjb21wZW5zYXRlLWZvci1zY3JvbGxiYXJcIik7XHJcblxyXG4gICAgICAgICQoXCIjZmFuY3lib3gtc3R5bGUtbm9zY3JvbGxcIikucmVtb3ZlKCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gQ2FsbCBjYWxsYmFjayBhbmQgdHJpZ2dlciBhbiBldmVudFxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHRyaWdnZXI6IGZ1bmN0aW9uIChuYW1lLCBzbGlkZSkge1xyXG4gICAgICB2Y
109XIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXHJcbiAgICAgICAgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgb2JqID0gc2xpZGUgJiYgc2xpZGUub3B0cyA/IHNsaWRlIDogc2VsZi5jdXJyZW50LFxyXG4gICAgICAgIHJlejtcclxuXHJcbiAgICAgIGlmIChvYmopIHtcclxuICAgICAgICBhcmdzLnVuc2hpZnQob2JqKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvYmogPSBzZWxmO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhcmdzLnVuc2hpZnQoc2VsZik7XHJcblxyXG4gICAgICBpZiAoJC5pc0Z1bmN0aW9uKG9iai5vcHRzW25hbWVdKSkge1xyXG4gICAgICAgIHJleiA9IG9iai5vcHRzW25hbWVdLmFwcGx5KG9iaiwgYXJncyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChyZXogPT09IGZhbHNlKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlejtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG5hbWUgPT09IFwiYWZ0ZXJDbG9zZVwiIHx8ICFzZWxmLiRyZWZzKSB7XHJcbiAgICAgICAgJEQudHJpZ2dlcihuYW1lICsgXCIuZmJcIiwgYXJncyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc2VsZi4kcmVmcy5jb250YWluZXIudHJpZ2dlcihuYW1lICsgXCIuZmJcIiwgYXJncyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gVXBkYXRlIGluZm9iYXIgdmFsdWVzLCBuYXZpZ2F0aW9uIGJ1dHRvbiBzdGF0ZXMgYW5kIHJldmVhbCBjYXB0aW9uXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICB1cGRhdGVDb250cm9sczogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuY3VycmVudCxcclxuICAgICAgICBpbmRleCA9IGN1cnJlbnQuaW5kZXgsXHJcbiAgICAgICAgJGNvbnRhaW5lciA9IHNlbGYuJHJlZnMuY29udGFpbmVyLFxyXG4gICAgICAgICRjYXB0aW9uID0gc2VsZi4kcmVmcy5jYXB0aW9uLFxyXG4gICAgICAgIGNhcHRpb24gPSBjdXJyZW50Lm9wdHMuY2FwdGlvbjtcclxuXHJcbiAgICAgIC8vIFJlY2FsY3VsYXRlIGNvbnRlbnQgZGltZW5zaW9uc1xyXG4gICAgICBjdXJyZW50LiRzbGlkZS50cmlnZ2VyKFwicmVmcmVzaFwiKTtcclxuXHJcbiAgICAgIC8vIFNldCBjYXB0aW9uXHJcbiAgICAgIGlmIChjYXB0aW9uICYmIGNhcHRpb24ubGVuZ3RoKSB7XHJcbiAgICAgICAgc2VsZi4kY2FwdGlvbiA9ICRjYXB0aW9uO1xyXG5cclxuICAgICAgICAkY2FwdGlvblxyXG4gICAgICAgICAgLmNoaWxkcmVuKClcclxuICAgICAgICAgIC5lcSgwKVxyXG4gICAgICAgICAgLmh0bWwoY2FwdGlvbik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc2VsZi4kY2FwdGlvbiA9IG51bGw7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghc2VsZi5oYXNIaWRkZW5Db250cm9scyAmJiAhc2VsZi5pc0lkbGUpIHtcclxuICAgICAgICBzZWxmLnNob3dDb250cm9scygpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBVcGRhdGUgaW5mbyBhbmQgbmF2aWdhdGlvbiBlbGVtZW50c1xyXG4gICAgICAkY29udGFpbmVyLmZpbmQoXCJbZGF0YS1mYW5jeWJveC1jb3VudF1cIikuaHRtbChzZWxmLmdyb3VwLmxlbmd0aCk7XHJcbiAgICAgICRjb250YWluZXIuZmluZChcIltkYXRhLWZhbmN5Ym94LWluZGV4XVwiKS5odG1sKGluZGV4ICsgMSk7XHJcblxyXG4gICAgICAkY29udGFpbmVyLmZpbmQoXCJbZGF0YS1mYW5jeWJveC1wcmV2XVwiKS5wcm9wKFwiZGlzYWJsZWRcIiwgIWN1cnJlbnQub3B0cy5sb29wICYmIGluZGV4IDw9IDApO1xyXG4gICAgICAkY29udGFpbmVyLmZpbmQoXCJbZGF0YS1mYW5jeWJveC1uZXh0XVwiKS5wcm9wKFwiZGlzYWJsZWRcIiwgIWN1cnJlbnQub3B0cy5sb29wICYmIGluZGV4ID49IHNlbGYuZ3JvdXAubGVuZ3RoIC0gMSk7XHJcblxyXG4gICAgICBpZiAoY3VycmVudC50eXBlID09PSBcImltYWdlXCIpIHtcclxuICAgICAgICAvLyBSZS1lbmFibGUgYnV0dG9uczsgdXBkYXRlIGRvd25sb2FkIGJ1dHRvbiBzb3VyY2VcclxuICAgICAgICAkY29udGFpbmVyXHJcbiAgICAgICAgICAuZmluZChcIltkYXRhLWZhbmN5Ym94LXpvb21dXCIpXHJcbiAgICAgICAgICAuc2hvdygpXHJcbiAgICAgICAgICAuZW5kKClcclxuICAgICAgICAgIC5maW5kKFwiW2RhdGEtZmFuY3lib3gtZG93bmxvYWRdXCIpXHJcbiAgICAgICAgICAuYXR0cihcImhyZWZcIiwgY3VycmVudC5vcHRzLmltYWdlLnNyYyB8fCBjdXJyZW50LnNyYylcclxuICAgICAgICAgIC5zaG93KCk7XHJcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5vcHRzLnRvb2xiYXIpIHtcclxuICAgICAgICAkY29udGFpbmVyLmZpbmQoXCJbZGF0YS1mYW5jeWJveC1kb3dubG9hZF0sW2RhdGEtZmFuY3lib3gtem9vbV1cIikuaGlkZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBNYWtlIHN1cmUgZm9jdXMgaXMgbm90IG9uIGRpc2FibGVkIGJ1dHRvbi9lbGVtZW50XHJcbiAgICAgIGlmICgkKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpLmlzKFwiOmhpZGRlbixbZGlzYWJsZWRdXCIpKSB7XHJcbiAgICAgICAgc2VsZi4kcmVmcy5jb250YWluZXIudHJpZ2dlcihcImZvY3VzXCIpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIEhpZGUgdG9vbGJhciBhbmQgY2FwdGlvblxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgaGlkZUNvbnRyb2xzOiBmdW5jdGlvbiAoYW5kQ2FwdGlvbikge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgYXJyID0gW1wiaW5mb2JhclwiLCBcInRvb2xiYXJcIiwgXCJuYXZcIl07XHJcblxyXG4gICAgICBpZiAoYW5kQ2FwdGlvbiB8fCAhc2VsZi5jdXJyZW50Lm9wdHMucHJldmVudENhcHRpb25PdmVybGFwKSB7XHJcbiAgICAgICAgYXJyLnB1c2goXCJjYXB0aW9uXCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLiRyZWZzLmNvbnRhaW5lci5yZW1vdmVDbGFzcyhcclxuICAgICAgICBhcnJcclxuICAgICAgICAubWFwKGZ1bmN0aW9uIChpKSB7XHJcbiAgICAgICAgICByZXR1cm4gXCJmYW5jeWJveC1zaG93LVwiICsgaTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5qb2luKFwiIFwiKVxyXG4gICAgICApO1xyXG5cclxuICAgICAgdGhpcy5oYXNIaWRkZW5Db250cm9scyA9IHRydWU7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3dDb250cm9sczogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgb3B0cyA9IHNlbGYuY3VycmVudCA/IHNlbGYuY3VycmVudC5vcHRzIDogc2VsZi5vcHRzLFxyXG4gICAgICAgICRjb250YWluZXIgPSBzZWxmLiRyZWZzLmNvbnRhaW5lcjtcclxuXHJcbiAgICAgIHNlbGYuaGFzSGlkZGVuQ29udHJvbHMgPSBmYWxzZTtcclxuICAgICAgc2VsZi5pZGxlU2Vjb25kc0NvdW50ZXIgPSAwO1xyXG5cclxuICAgICAgJGNvbnRhaW5lclxyXG4gICAgICAgIC50b2dnbGVDbGFzcyhcImZhbmN5Ym94LXNob3ctdG9vbGJhclwiLCAhIShvcHRzLnRvb2xiYXIgJiYgb3B0cy5idXR0b25zKSlcclxuICAgICAgICAudG9nZ2xlQ2xhc3MoXCJmYW5jeWJveC1zaG93LWluZm9iYXJcIiwgISEob3B0cy5pbmZvYmFyICYmIHNlbGYuZ3JvdXAubGVuZ3RoID4gMSkpXHJcbiAgICAgICAgLnRvZ2dsZUNsYXNzKFwiZmFuY3lib3gtc2hvdy1jYXB0aW9uXCIsICEhc2VsZi4kY2FwdGlvbilcclxuICAgICAgICAudG9nZ2xlQ2xhc3MoXCJmYW5jeWJveC1zaG93LW5hdlwiLCAhIShvcHRzLmFycm93cyAmJiBzZWxmLmdyb3VwLmxlbmd0aCA+IDEpKVxyXG4gICAgICAgIC50b2dnbGVDbGFzcyhcImZhbmN5Ym94LWlzLW1vZGFsXCIsICEhb3B0cy5tb2RhbCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFRvZ2dsZSB0b29sYmFyIGFuZCBjYXB0aW9uXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIHRvZ2dsZUNvbnRyb2xzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICh0aGlzLmhhc0hpZGRlbkNvbnRyb2xzKSB7XHJcbiAgICAgICAgdGhpcy5zaG93Q29udHJvbHMoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmhpZGVDb250cm9scygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gICQuZmFuY3lib3ggPSB7XHJcbiAgICB2ZXJzaW9uOiBcIjMuNS43XCIsXHJcbiAgICBkZWZhdWx0czogZGVmYXVsdHMsXHJcblxyXG4gICAgLy8gR2V0IGN1cnJlbnQgaW5zdGFuY2UgYW5kIGV4ZWN1dGUgYSBjb21tYW5kLlxyXG4gICAgLy9cclxuICAgIC8vIEV4YW1wbGVzIG9mIHVzYWdlOlxyXG4gICAgLy9cclxuICAgIC8vICAgJGluc3RhbmNlID0gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpO1xyXG4gICAgLy8gICAkLmZhbmN5Ym94LmdldEluc3RhbmNlKCkuanVtcFRvKCAxICk7XHJcbiAgICAvLyAgICQuZmFuY3lib3guZ2V0SW5zdGFuY2UoICdqdW1wVG8nLCAxICk7XHJcbiAgICAvLyAgICQuZmFuY3lib3guZ2V0SW5zdGFuY2UoIGZ1bmN0aW9uKCkge1xyXG4gICAgLy8gICAgICAgY29uc29sZS5pbmZvKCB0aGlzLmN1cnJJbmRleCApO1xyXG4gICAgLy8gICB9KTtcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGdldEluc3RhbmNlOiBmdW5jdGlvbiAoY29tbWFuZCkge1xyXG4gICAgICB2Y
109XIgaW5zdGFuY2UgPSAkKCcuZmFuY3lib3gtY29udGFpbmVyOm5vdChcIi5mYW5jeWJveC1pcy1jbG9zaW5nXCIpOmxhc3QnKS5kYXRhKFwiRmFuY3lCb3hcIiksXHJcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcblxyXG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBGYW5jeUJveCkge1xyXG4gICAgICAgIGlmICgkLnR5cGUoY29tbWFuZCkgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgIGluc3RhbmNlW2NvbW1hbmRdLmFwcGx5KGluc3RhbmNlLCBhcmdzKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCQudHlwZShjb21tYW5kKSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICBjb21tYW5kLmFwcGx5KGluc3RhbmNlLCBhcmdzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBDcmVhdGUgbmV3IGluc3RhbmNlXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgb3BlbjogZnVuY3Rpb24gKGl0ZW1zLCBvcHRzLCBpbmRleCkge1xyXG4gICAgICByZXR1cm4gbmV3IEZhbmN5Qm94KGl0ZW1zLCBvcHRzLCBpbmRleCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENsb3NlIGN1cnJlbnQgb3IgYWxsIGluc3RhbmNlc1xyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgY2xvc2U6IGZ1bmN0aW9uIChhbGwpIHtcclxuICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTtcclxuXHJcbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgYW5kIGNsb3NlIG5leHQgaW5zdGFuY2VcclxuICAgICAgICBpZiAoYWxsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICB0aGlzLmNsb3NlKGFsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIENsb3NlIGFsbCBpbnN0YW5jZXMgYW5kIHVuYmluZCBhbGwgZXZlbnRzXHJcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5jbG9zZSh0cnVlKTtcclxuXHJcbiAgICAgICRELmFkZChcImJvZHlcIikub2ZmKFwiY2xpY2suZmItc3RhcnRcIiwgXCIqKlwiKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gVHJ5IHRvIGRldGVjdCBtb2JpbGUgZGV2aWNlc1xyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGlzTW9iaWxlOiAvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBhZHxpUG9kfEJsYWNrQmVycnl8SUVNb2JpbGV8T3BlcmEgTWluaS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksXHJcblxyXG4gICAgLy8gRGV0ZWN0IGlmICd0cmFuc2xhdGUzZCcgc3VwcG9ydCBpcyBhdmFpbGFibGVcclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgdXNlM2Q6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG5cclxuICAgICAgcmV0dXJuIChcclxuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSAmJlxyXG4gICAgICAgIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGRpdikgJiZcclxuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkaXYpLmdldFByb3BlcnR5VmFsdWUoXCJ0cmFuc2Zvcm1cIikgJiZcclxuICAgICAgICAhKGRvY3VtZW50LmRvY3VtZW50TW9kZSAmJiBkb2N1bWVudC5kb2N1bWVudE1vZGUgPCAxMSlcclxuICAgICAgKTtcclxuICAgIH0pKCksXHJcblxyXG4gICAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGdldCBjdXJyZW50IHZpc3VhbCBzdGF0ZSBvZiBhbiBlbGVtZW50XHJcbiAgICAvLyByZXR1cm5zIGFycmF5WyB0b3AsIGxlZnQsIGhvcml6b250YWwtc2NhbGUsIHZlcnRpY2FsLXNjYWxlLCBvcGFjaXR5IF1cclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAgIGdldFRyYW5zbGF0ZTogZnVuY3Rpb24gKCRlbCkge1xyXG4gICAgICB2Y
109XIgZG9tUmVjdDtcclxuXHJcbiAgICAgIGlmICghJGVsIHx8ICEkZWwubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkb21SZWN0ID0gJGVsWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0b3A6IGRvbVJlY3QudG9wIHx8IDAsXHJcbiAgICAgICAgbGVmdDogZG9tUmVjdC5sZWZ0IHx8IDAsXHJcbiAgICAgICAgd2lkdGg6IGRvbVJlY3Qud2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0OiBkb21SZWN0LmhlaWdodCxcclxuICAgICAgICBvcGFjaXR5OiBwYXJzZUZsb2F0KCRlbC5jc3MoXCJvcGFjaXR5XCIpKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBTaG9ydGN1dCBmb3Igc2V0dGluZyBcInRyYW5zbGF0ZTNkXCIgcHJvcGVydGllcyBmb3IgZWxlbWVudFxyXG4gICAgLy8gQ2FuIHNldCBiZSB1c2VkIHRvIHNldCBvcGFjaXR5LCB0b29cclxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICAgc2V0VHJhbnNsYXRlOiBmdW5jdGlvbiAoJGVsLCBwcm9wcykge1xyXG4gICAgICB2YXIgc3RyID0gXCJcIixcclxuICAgICAgICBjc3MgPSB7fTtcclxuXHJcbiAgICAgIGlmICghJGVsIHx8ICFwcm9wcykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHByb3BzLmxlZnQgIT09IHVuZGVmaW5lZCB8fCBwcm9wcy50b3AgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHN0ciA9XHJcbiAgICAgICAgICAocHJvcHMubGVmdCA9PT0gdW5kZWZpbmVkID8gJGVsLnBvc2l0aW9uKCkubGVmdCA6IHByb3BzLmxlZnQpICtcclxuICAgICAgICAgIFwicHgsIFwiICtcclxuICAgICAgICAgIChwcm9wcy50b3AgPT09IHVuZGVmaW5lZCA/ICRlbC5wb3NpdGlvbigpLnRvcCA6IHByb3BzLnRvcCkgK1xyXG4gICAgICAgICAgXCJweFwiO1xyXG5cclxuICAgICAgICBpZiAodGhpcy51c2UzZCkge1xyXG4gICAgICAgICAgc3RyID0gXCJ0cmFuc2xhdGUzZChcIiArIHN0ciArIFwiLCAwcHgpXCI7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHN0ciA9IFwidHJhbnNsYXRlKFwiICsgc3RyICsgXCIpXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMuc2NhbGVYICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuc2NhbGVZICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICBzdHIgKz0gXCIgc2NhbGUoXCIgKyBwcm9wcy5zY2FsZVggKyBcIiwgXCIgKyBwcm9wcy5zY2FsZVkgKyBcIilcIjtcclxuICAgICAgfSBlbHNlIGlmIChwcm9wcy5zY2FsZVggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHN0ciArPSBcIiBzY2FsZVgoXCIgKyBwcm9wcy5zY2FsZVggKyBcIilcIjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHN0ci5sZW5ndGgpIHtcclxuICAgICAgICBjc3MudHJhbnNmb3JtID0gc3RyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMub3BhY2l0eSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgY3NzLm9wYWNpdHkgPSBwcm9wcy5vcGFjaXR5O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMud2lkdGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGNzcy53aWR0aCA9IHByb3BzLndpZHRoO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMuaGVpZ2h0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICBjc3MuaGVpZ2h0ID0gcHJvcHMuaGVpZ2h0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gJGVsLmNzcyhjc3MpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBTaW1wbGUgQ1NTIHRyYW5zaXRpb24gaGFuZGxlclxyXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgICBhbmltYXRlOiBmdW5jdGlvbiAoJGVsLCB0bywgZHVyYXRpb24sIGNhbGxiYWNrLCBsZWF2ZUFuaW1hdGlvbk5hbWUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGZyb207XHJcblxyXG4gICAgICBpZiAoJC5pc0Z1bmN0aW9uKGR1cmF0aW9uKSkge1xyXG4gICAgICAgIGNhbGxiYWNrID0gZHVyYXRpb247XHJcbiAgICAgICAgZHVyYXRpb24gPSBudWxsO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnN0b3AoJGVsKTtcclxuXHJcbiAgICAgIGZyb20gPSBzZWxmLmdldFRyYW5zbGF0ZSgkZWwpO1xyXG5cclxuICAgICAgJGVsLm9uKHRyYW5zaXRpb25FbmQsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgLy8gU2tpcCBldmVudHMgZnJvbSBjaGlsZCBlbGVtZW50cyBhbmQgei1pbmRleCBjaGFuZ2VcclxuICAgICAgICBpZiAoZSAmJiBlLm9yaWdpbmFsRXZlbnQgJiYgKCEkZWwuaXMoZS5vcmlnaW5hbEV2ZW50LnRhcmdldCkgfHwgZS5vcmlnaW5hbEV2ZW50LnByb3BlcnR5TmFtZSA9PSBcInotaW5kZXhcIikpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNlbGYuc3RvcCgkZWwpO1xyXG5cclxuICAgICAgICBpZiAoJC5pc051bWVyaWMoZHVyYXRpb24pKSB7XHJcbiAgICAgICAgICAkZWwuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLCBcIlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICgkLmlzUGxhaW5PYmplY3QodG8pKSB7XHJcbiAgICAgICAgICBpZiAodG8uc2NhbGVYICE9PSB1bmRlZmluZWQgJiYgdG8uc2NhbGVZICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgc2VsZi5zZXRUcmFuc2xhdGUoJGVsLCB7XHJcbiAgICAgICAgICAgICAgdG9wOiB0by50b3AsXHJcbiAgICAgICAgICAgICAgbGVmdDogdG8ubGVmdCxcclxuICAgICAgICAgICAgICB3aWR0aDogZnJvbS53aWR0aCAqIHRvLnNjYWxlWCxcclxuICAgICAgICAgICAgICBoZWlnaHQ6IGZyb20uaGVpZ2h0ICogdG8uc2NhbGVZLFxyXG4gICAgICAgICAgICAgIHNjYWxlWDogMSxcclxuICAgICAgICAgICAgICBzY2FsZVk6IDFcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChsZWF2ZUFuaW1hdGlvbk5hbWUgIT09IHRydWUpIHtcclxuICAgICAgICAgICRlbC5yZW1vdmVDbGFzcyh0byk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoJC5pc0Z1bmN0aW9uKGNhbGxiYWNrKSkge1xyXG4gICAgICAgICAgY2FsbGJhY2soZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmICgkLmlzTnVtZXJpYyhkdXJhdGlvbikpIHtcclxuICAgICAgICAkZWwuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLCBkdXJhdGlvbiArIFwibXNcIik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFN0YXJ0IGFuaW1hdGlvbiBieSBjaGFuZ2luZyBDU1MgcHJv
109cGVydGllcyBvciBjbGFzcyBuYW1lXHJcbiAgICAgIGlmICgkLmlzUGxhaW5PYmplY3QodG8pKSB7XHJcbiAgICAgICAgaWYgKHRvLnNjYWxlWCAhPT0gdW5kZWZpbmVkICYmIHRvLnNjYWxlWSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICBkZWxldGUgdG8ud2lkdGg7XHJcbiAgICAgICAgICBkZWxldGUgdG8uaGVpZ2h0O1xyXG5cclxuICAgICAgICAgIGlmICgkZWwucGFyZW50KCkuaGFzQ2xhc3MoXCJmYW5jeWJveC1zbGlkZS0taW1hZ2VcIikpIHtcclxuICAgICAgICAgICAgJGVsLnBhcmVudCgpLmFkZENsYXNzKFwiZmFuY3lib3gtaXMtc2NhbGluZ1wiKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQuZmFuY3lib3guc2V0VHJhbnNsYXRlKCRlbCwgdG8pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgICRlbC5hZGRDbGFzcyh0byk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGB0cmFuc2l0aW9uZW5kYCBjYWxsYmFjayBnZXRzIGZpcmVkXHJcbiAgICAgICRlbC5kYXRhKFxyXG4gICAgICAgIFwidGltZXJcIixcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICRlbC50cmlnZ2VyKHRyYW5zaXRpb25FbmQpO1xyXG4gICAgICAgIH0sIGR1cmF0aW9uICsgMzMpXHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIHN0b3A6IGZ1bmN0aW9uICgkZWwsIGNhbGxDYWxsYmFjaykge1xyXG4gICAgICBpZiAoJGVsICYmICRlbC5sZW5ndGgpIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQoJGVsLmRhdGEoXCJ0aW1lclwiKSk7XHJcblxyXG4gICAgICAgIGlmIChjYWxsQ2FsbGJhY2spIHtcclxuICAgICAgICAgICRlbC50cmlnZ2VyKHRyYW5zaXRpb25FbmQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJGVsLm9mZih0cmFuc2l0aW9uRW5kKS5jc3MoXCJ0cmFuc2l0aW9uLWR1cmF0aW9uXCIsIFwiXCIpO1xyXG5cclxuICAgICAgICAkZWwucGFyZW50KCkucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1pcy1zY2FsaW5nXCIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLy8gRGVmYXVsdCBjbGljayBoYW5kbGVyIGZvciBcImZhbmN5Ym94ZWRcIiBsaW5rc1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIGZ1bmN0aW9uIF9ydW4oZSwgb3B0cykge1xyXG4gICAgdmFyIGl0ZW1zID0gW10sXHJcbiAgICAgIGluZGV4ID0gMCxcclxuICAgICAgJHRhcmdldCxcclxuICAgICAgdmFsdWUsXHJcbiAgICAgIGluc3RhbmNlO1xyXG5cclxuICAgIC8vIEF2b2lkIG9wZW5pbmcgbXVsdGlwbGUgdGltZXNcclxuICAgIGlmIChlICYmIGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcclxuXHJcbiAgICBpZiAoZSAmJiBlLmRhdGEpIHtcclxuICAgICAgb3B0cyA9IG1lcmdlT3B0cyhlLmRhdGEub3B0aW9ucywgb3B0cyk7XHJcbiAgICB9XHJcblxyXG4gICAgJHRhcmdldCA9IG9wdHMuJHRhcmdldCB8fCAkKGUuY3VycmVudFRhcmdldCkudHJpZ2dlcihcImJsdXJcIik7XHJcbiAgICBpbnN0YW5jZSA9ICQuZmFuY3lib3guZ2V0SW5zdGFuY2UoKTtcclxuXHJcbiAgICBpZiAoaW5zdGFuY2UgJiYgaW5zdGFuY2UuJHRyaWdnZXIgJiYgaW5zdGFuY2UuJHRyaWdnZXIuaXMoJHRhcmdldCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRzLnNlbGVjdG9yKSB7XHJcbiAgICAgIGl0ZW1zID0gJChvcHRzLnNlbGVjdG9yKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIEdldCBhbGwgcmVsYXRlZCBpdGVtcyBhbmQgZmluZCBpbmRleCBmb3IgY2xpY2tlZCBvbmVcclxuICAgICAgdmFsdWUgPSAkdGFyZ2V0LmF0dHIoXCJkYXRhLWZhbmN5Ym94XCIpIHx8IFwiXCI7XHJcblxyXG4gICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICBpdGVtcyA9IGUuZGF0YSA/IGUuZGF0YS5pdGVtcyA6IFtdO1xyXG4gICAgICAgIGl0ZW1zID0gaXRlbXMubGVuZ3RoID8gaXRlbXMuZmlsdGVyKCdbZGF0YS1mYW5jeWJveD1cIicgKyB2YWx1ZSArICdcIl0nKSA6ICQoJ1tkYXRhLWZhbmN5Ym94PVwiJyArIHZhbHVlICsgJ1wiXScpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGl0ZW1zID0gWyR0YXJnZXRdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaW5kZXggPSAkKGl0ZW1zKS5pbmRleCgkdGFyZ2V0KTtcclxuXHJcbiAgICAvLyBTb21ldGltZXMgY3VycmVudCBpdGVtIGNhbiBub3QgYmUgZm91bmRcclxuICAgIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgaW5kZXggPSAwO1xyXG4gICAgfVxyXG5cclxuICAgIGluc3RhbmNlID0gJC5mYW5jeWJveC5vcGVuKGl0ZW1zLCBvcHRzLCBpbmRleCk7XHJcblxyXG4gICAgLy8gU2F2ZSBsYXN0IGFjdGl2ZSBlbGVtZW50XHJcbiAgICBpbnN0YW5jZS4kdHJpZ2dlciA9ICR0YXJnZXQ7XHJcbiAgfVxyXG5cclxuICAvLyBDcmVhdGUgYSBqUXVlcnkgcGx1Z2luXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAkLmZuLmZhbmN5Ym94ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgIHZhciBzZWxlY3RvcjtcclxuXHJcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgIHNlbGVjdG9yID0gb3B0aW9ucy5zZWxlY3RvciB8fCBmYWxzZTtcclxuXHJcbiAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgLy8gVXNlIGJvZHkgZWxlbWVudCBpbnN0ZWFkIG9mIGRvY3VtZW50IHNvIGl0IGV4ZWN1dGVzIGZpcnN0XHJcbiAgICAgICQoXCJib2R5XCIpXHJcbiAgICAgICAgLm9mZihcImNsaWNrLmZiLXN0YXJ0XCIsIHNlbGVjdG9yKVxyXG4gICAgICAgIC5vbihcImNsaWNrLmZiLXN0YXJ0XCIsIHNlbGVjdG9yLCB7XHJcbiAgICAgICAgICBvcHRpb25zOiBvcHRpb25zXHJcbiAgICAgICAgfSwgX3J1bik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm9mZihcImNsaWNrLmZiLXN0YXJ0XCIpLm9uKFxyXG4gICAgICAgIFwiY2xpY2suZmItc3RhcnRcIiwge1xyXG4gICAgICAgICAgaXRlbXM6IHRoaXMsXHJcbiAgICAgICAgICBvcHRpb25zOiBvcHRpb25zXHJcbiAgICAgICAgfSxcclxuICAgICAgICBfcnVuXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgLy8gU2VsZiBpbml0aWFsaXppbmcgcGx1Z2luIGZvciBhbGwgZWxlbWVudHMgaGF2aW5nIGBkYXRhLWZhbmN5Ym94YCBhdHRyaWJ1dGVcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAkRC5vbihcImNsaWNrLmZiLXN0YXJ0XCIsIFwiW2Rh
109dGEtZmFuY3lib3hdXCIsIF9ydW4pO1xyXG5cclxuICAvLyBFbmFibGUgXCJ0cmlnZ2VyIGVsZW1lbnRzXCJcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gICRELm9uKFwiY2xpY2suZmItc3RhcnRcIiwgXCJbZGF0YS1mYW5jeWJveC10cmlnZ2VyXVwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgJCgnW2RhdGEtZmFuY3lib3g9XCInICsgJCh0aGlzKS5hdHRyKFwiZGF0YS1mYW5jeWJveC10cmlnZ2VyXCIpICsgJ1wiXScpXHJcbiAgICAgIC5lcSgkKHRoaXMpLmF0dHIoXCJkYXRhLWZhbmN5Ym94LWluZGV4XCIpIHx8IDApXHJcbiAgICAgIC50cmlnZ2VyKFwiY2xpY2suZmItc3RhcnRcIiwge1xyXG4gICAgICAgICR0cmlnZ2VyOiAkKHRoaXMpXHJcbiAgICAgIH0pO1xyXG4gIH0pO1xyXG5cclxuICAvLyBUcmFjayBmb2N1cyBldmVudCBmb3IgYmV0dGVyIGFjY2Vzc2liaWxpdHkgc3R5bGluZ1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBidXR0b25TdHIgPSBcIi5mYW5jeWJveC1idXR0b25cIixcclxuICAgICAgZm9jdXNTdHIgPSBcImZhbmN5Ym94LWZvY3VzXCIsXHJcbiAgICAgICRwcmVzc2VkID0gbnVsbDtcclxuXHJcbiAgICAkRC5vbihcIm1vdXNlZG93biBtb3VzZXVwIGZvY3VzIGJsdXJcIiwgYnV0dG9uU3RyLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICBzd2l0Y2ggKGUudHlwZSkge1xyXG4gICAgICAgIGNhc2UgXCJtb3VzZWRvd25cIjpcclxuICAgICAgICAgICRwcmVzc2VkID0gJCh0aGlzKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgXCJtb3VzZXVwXCI6XHJcbiAgICAgICAgICAkcHJlc3NlZCA9IG51bGw7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFwiZm9jdXNpblwiOlxyXG4gICAgICAgICAgJChidXR0b25TdHIpLnJlbW92ZUNsYXNzKGZvY3VzU3RyKTtcclxuXHJcbiAgICAgICAgICBpZiAoISQodGhpcykuaXMoJHByZXNzZWQpICYmICEkKHRoaXMpLmlzKFwiW2Rpc2FibGVkXVwiKSkge1xyXG4gICAgICAgICAgICAkKHRoaXMpLmFkZENsYXNzKGZvY3VzU3RyKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgXCJmb2N1c291dFwiOlxyXG4gICAgICAgICAgJChidXR0b25TdHIpLnJlbW92ZUNsYXNzKGZvY3VzU3RyKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KSgpO1xyXG59KSh3aW5kb3csIGRvY3VtZW50LCBqUXVlcnkpO1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuLy9cclxuLy8gTWVkaWFcclxuLy8gQWRkcyBhZGRpdGlvbmFsIG1lZGlhIHR5cGUgc3VwcG9ydFxyXG4vL1xyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4oZnVuY3Rpb24gKCQpIHtcclxuICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgLy8gT2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcyBmb3IgZWFjaCBtZWRpYSB0eXBlXHJcbiAgdmFyIGRlZmF1bHRzID0ge1xyXG4gICAgeW91dHViZToge1xyXG4gICAgICBtYXRjaGVyOiAvKHlvdXR1YmVcXC5jb218eW91dHVcXC5iZXx5b3V0dWJlXFwtbm9jb29raWVcXC5jb20pXFwvKHdhdGNoXFw/KC4qJik/dj18dlxcL3x1XFwvfGVtYmVkXFwvPyk/KHZpZGVvc2VyaWVzXFw/bGlzdD0oLiopfFtcXHctXXsxMX18XFw/bGlzdFR5cGU9KC4qKSZsaXN0PSguKikpKC4qKS9pLFxyXG4gICAgICBwYXJhbXM6IHtcclxuICAgICAgICBhdXRvcGxheTogMSxcclxuICAgICAgICBhdXRvaGlkZTogMSxcclxuICAgICAgICBmczogMSxcclxuICAgICAgICByZWw6IDAsXHJcbiAgICAgICAgaGQ6IDEsXHJcbiAgICAgICAgd21vZGU6IFwidHJhbnNwYXJlbnRcIixcclxuICAgICAgICBlbmFibGVqc2FwaTogMSxcclxuICAgICAgICBodG1sNTogMVxyXG4gICAgICB9LFxyXG4gICAgICBwYXJhbVBsYWNlOiA4LFxyXG4gICAgICB0eXBlOiBcImlmcmFtZVwiLFxyXG4gICAgICB1cmw6IFwiaHR0cHM6Ly93d3cueW91dHViZS1ub2Nvb2tpZS5jb20vZW1iZWQvJDRcIixcclxuICAgICAgdGh1bWI6IFwiaHR0cHM6Ly9pbWcueW91dHViZS5jb20vdmkvJDQvaHFkZWZhdWx0LmpwZ1wiXHJcbiAgICB9LFxyXG5cclxuICAgIHZpbWVvOiB7XHJcbiAgICAgIG1hdGNoZXI6IC9eLit2aW1lby5jb21cXC8oLipcXC8pPyhbXFxkXSspKC4qKT8vLFxyXG4gICAgICBwYXJhbXM6IHtcclxuICAgICAgICBhdXRvcGxheTogMSxcclxuICAgICAgICBoZDogMSxcclxuICAgICAgICBzaG93X3RpdGxlOiAxLFxyXG4gICAgICAgIHNob3dfYnlsaW5lOiAxLFxyXG4gICAgICAgIHNob3dfcG9ydHJhaXQ6IDAsXHJcbiAgICAgICAgZnVsbHNjcmVlbjogMVxyXG4gICAgICB9LFxyXG4gICAgICBwYXJhbVBsYWNlOiAzLFxyXG4gICAgICB0eXBlOiBcImlmcmFtZVwiLFxyXG4gICAgICB1cmw6IFwiLy9wbGF5ZXIudmltZW8uY29tL3ZpZGVvLyQyXCJcclxuICAgIH0sXHJcblxyXG4gICAgaW5zdGFncmFtOiB7XHJcbiAgICAgIG1hdGNoZXI6IC8oaW5zdGFnclxcLmFtfGluc3RhZ3JhbVxcLmNvbSlcXC9wXFwvKFthLXpBLVowLTlfXFwtXSspXFwvPy9pLFxyXG4gICAgICB0eXBlOiBcImltYWdlXCIsXHJcbiAgICAgIHVybDogXCIvLyQxL3AvJDIvbWVkaWEvP3NpemU9bFwiXHJcbiAgICB9LFxyXG5cclxuICAgIC8vIEV4YW1wbGVzOlxyXG4gICAgLy8gaHR0cDovL21hcHMuZ29vZ2xlLmNvbS8/bGw9NDguODU3OTk1LDIuMjk0Mjk3JnNwbj0wLjAwNzY2NiwwLjAyMTEzNiZ0PW0mej0xNlxyXG4gICAgLy8gaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9tYXBzL0AzNy43ODUyMDA2LC0xMjIuNDE0NjM1NSwxNC42NXpcclxuICAgIC8vIGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbWFwcy9ANTIuMjExMTEyMywyLjkyMzc1NDIsNi42MXo/aGw9ZW5cclxuICAgIC8vIGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbWFwcy9wbGFjZS9Hb29nbGVwbGV4L0AzNy40MjIwMDQxLC0xMjIuMDgzMzQ5NCwxN3ovZGF0YT0hNG01ITNtNCExczB4MDoweDZjMjk2YzY2NjE5MzY3ZTAhOG0yITNkMzcuNDIxOTk5OCE0ZC0xMjIuMDg0MDU3MlxyXG4gICAgZ21hcF9
109wbGFjZToge1xyXG4gICAgICBtYXRjaGVyOiAvKG1hcHNcXC4pP2dvb2dsZVxcLihbYS16XXsyLDN9KFxcLlthLXpdezJ9KT8pXFwvKCgobWFwc1xcLyhwbGFjZVxcLyguKilcXC8pP1xcQCguKiksKFxcZCsuP1xcZCs/KXopKXwoXFw/bGw9KSkoLiopPy9pLFxyXG4gICAgICB0eXBlOiBcImlmcmFtZVwiLFxyXG4gICAgICB1cmw6IGZ1bmN0aW9uIChyZXopIHtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgXCIvL21hcHMuZ29vZ2xlLlwiICtcclxuICAgICAgICAgIHJlelsyXSArXHJcbiAgICAgICAgICBcIi8/bGw9XCIgK1xyXG4gICAgICAgICAgKHJlels5XSA/IHJlels5XSArIFwiJno9XCIgKyBNYXRoLmZsb29yKHJlelsxMF0pICsgKHJlelsxMl0gPyByZXpbMTJdLnJlcGxhY2UoL15cXC8vLCBcIiZcIikgOiBcIlwiKSA6IHJlelsxMl0gKyBcIlwiKS5yZXBsYWNlKC9cXD8vLCBcIiZcIikgK1xyXG4gICAgICAgICAgXCImb3V0cHV0PVwiICtcclxuICAgICAgICAgIChyZXpbMTJdICYmIHJlelsxMl0uaW5kZXhPZihcImxheWVyPWNcIikgPiAwID8gXCJzdmVtYmVkXCIgOiBcImVtYmVkXCIpXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBFeGFtcGxlczpcclxuICAgIC8vIGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbWFwcy9zZWFyY2gvRW1waXJlK1N0YXRlK0J1aWxkaW5nL1xyXG4gICAgLy8gaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9tYXBzL3NlYXJjaC8/YXBpPTEmcXVlcnk9Y2VudHVyeWxpbmsrZmllbGRcclxuICAgIC8vIGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vbWFwcy9zZWFyY2gvP2FwaT0xJnF1ZXJ5PTQ3LjU5NTE1MTgsLTEyMi4zMzE2MzkzXHJcbiAgICBnbWFwX3NlYXJjaDoge1xyXG4gICAgICBtYXRjaGVyOiAvKG1hcHNcXC4pP2dvb2dsZVxcLihbYS16XXsyLDN9KFxcLlthLXpdezJ9KT8pXFwvKG1hcHNcXC9zZWFyY2hcXC8pKC4qKS9pLFxyXG4gICAgICB0eXBlOiBcImlmcmFtZVwiLFxyXG4gICAgICB1cmw6IGZ1bmN0aW9uIChyZXopIHtcclxuICAgICAgICByZXR1cm4gXCIvL21hcHMuZ29vZ2xlLlwiICsgcmV6WzJdICsgXCIvbWFwcz9xPVwiICsgcmV6WzVdLnJlcGxhY2UoXCJxdWVyeT1cIiwgXCJxPVwiKS5yZXBsYWNlKFwiYXBpPTFcIiwgXCJcIikgKyBcIiZvdXRwdXQ9ZW1iZWRcIjtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIC8vIEZvcm1hdHMgbWF0Y2hpbmcgdXJsIHRvIGZpbmFsIGZvcm1cclxuICB2YXIgZm9ybWF0ID0gZnVuY3Rpb24gKHVybCwgcmV6LCBwYXJhbXMpIHtcclxuICAgIGlmICghdXJsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBwYXJhbXMgPSBwYXJhbXMgfHwgXCJcIjtcclxuXHJcbiAgICBpZiAoJC50eXBlKHBhcmFtcykgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgcGFyYW1zID0gJC5wYXJhbShwYXJhbXMsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgICQuZWFjaChyZXosIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlKFwiJFwiICsga2V5LCB2YWx1ZSB8fCBcIlwiKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGlmIChwYXJhbXMubGVuZ3RoKSB7XHJcbiAgICAgIHVybCArPSAodXJsLmluZGV4T2YoXCI/XCIpID4gMCA/IFwiJlwiIDogXCI/XCIpICsgcGFyYW1zO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB1cmw7XHJcbiAgfTtcclxuXHJcbiAgJChkb2N1bWVudCkub24oXCJvYmplY3ROZWVkc1R5cGUuZmJcIiwgZnVuY3Rpb24gKGUsIGluc3RhbmNlLCBpdGVtKSB7XHJcbiAgICB2YXIgdXJsID0gaXRlbS5zcmMgfHwgXCJcIixcclxuICAgICAgdHlwZSA9IGZhbHNlLFxyXG4gICAgICBtZWRpYSxcclxuICAgICAgdGh1bWIsXHJcbiAgICAgIHJleixcclxuICAgICAgcGFyYW1zLFxyXG4gICAgICB1cmxQYXJhbXMsXHJcbiAgICAgIHBhcmFtT2JqLFxyXG4gICAgICBwcm92aWRlcjtcclxuXHJcbiAgICBtZWRpYSA9ICQuZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgaXRlbS5vcHRzLm1lZGlhKTtcclxuXHJcbiAgICAvLyBMb29rIGZvciBhbnkgbWF0Y2hpbmcgbWVkaWEgdHlwZVxyXG4gICAgJC5lYWNoKG1lZGlhLCBmdW5jdGlvbiAocHJvdmlkZXJOYW1lLCBwcm92aWRlck9wdHMpIHtcclxuICAgICAgcmV6ID0gdXJsLm1hdGNoKHByb3ZpZGVyT3B0cy5tYXRjaGVyKTtcclxuXHJcbiAgICAgIGlmICghcmV6KSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0eXBlID0gcHJvdmlkZXJPcHRzLnR5cGU7XHJcbiAgICAgIHByb3ZpZGVyID0gcHJvdmlkZXJOYW1lO1xyXG4gICAgICBwYXJhbU9iaiA9IHt9O1xyXG5cclxuICAgICAgaWYgKHByb3ZpZGVyT3B0cy5wYXJhbVBsYWNlICYmIHJleltwcm92aWRlck9wdHMucGFyYW1QbGFjZV0pIHtcclxuICAgICAgICB1cmxQYXJhbXMgPSByZXpbcHJvdmlkZXJPcHRzLnBhcmFtUGxhY2VdO1xyXG5cclxuICAgICAgICBpZiAodXJsUGFyYW1zWzBdID09IFwiP1wiKSB7XHJcbiAgICAgICAgICB1cmxQYXJhbXMgPSB1cmxQYXJhbXMuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdXJsUGFyYW1zID0gdXJsUGFyYW1zLnNwbGl0KFwiJlwiKTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgbSA9IDA7IG0gPCB1cmxQYXJhbXMubGVuZ3RoOyArK20pIHtcclxuICAgICAgICAgIHZhciBwID0gdXJsUGFyYW1zW21dLnNwbGl0KFwiPVwiLCAyKTtcclxuXHJcbiAgICAgICAgICBpZiAocC5sZW5ndGggPT0gMikge1xyXG4gICAgICAgICAgICBwYXJhbU9ialtwWzBdXSA9IGRlY29kZVVSSUNvbXBvbmVudChwWzFdLnJlcGxhY2UoL1xcKy9nLCBcIiBcIikpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcGFyYW1zID0gJC5leHRlbmQodHJ1ZSwge30sIHByb3ZpZGVyT3B0cy5wYXJhbXMsIGl0ZW0ub3B0c1twcm92aWRlck5hbWVdLCBwYXJhbU9iaik7XHJcblxyXG4gICAgICB1cmwgPVxyXG4gICAgICAgICQudHlwZShwcm92aWRlck9wdHMudXJsKSA9PT0gXCJmdW5jdGlvblwiID8gcHJvdmlkZXJPcHRzLnVybC5jYWxsKHRoaXMsIHJleiwgcGFyYW1zLCBpdGVtKSA6IGZvcm1hdChwcm92aWRlck9wdHMudXJsLCByZXosIHBhcmFtcyk7XHJcblxyXG4gICAgICB0aHVtYiA9XHJcbiAgICAgICAgJC50eXBlKHByb3ZpZGVyT3B0cy50aHVtYikgPT09IFwiZnVuY3Rpb25cIiA/IHByb3ZpZGVyT3B0cy50aHVtYi5jYWxsKHRoaXMsIHJleiwgcGFyYW1zLCBpdGVtKSA6IGZvcm1hdChwcm92aWRlck9wdHMudGh1bWIsIHJleik7XHJcblxyXG4gICAgICBpZiAocHJvdmlkZXJOYW1lID09PSBcInlvdXR1YmVcIikge1xyXG4gICAgICAgI
109HVybCA9IHVybC5yZXBsYWNlKC8mdD0oKFxcZCspbSk/KFxcZCspcy8sIGZ1bmN0aW9uIChtYXRjaCwgcDEsIG0sIHMpIHtcclxuICAgICAgICAgIHJldHVybiBcIiZzdGFydD1cIiArICgobSA/IHBhcnNlSW50KG0sIDEwKSAqIDYwIDogMCkgKyBwYXJzZUludChzLCAxMCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2UgaWYgKHByb3ZpZGVyTmFtZSA9PT0gXCJ2aW1lb1wiKSB7XHJcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoXCImJTIzXCIsIFwiI1wiKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gSWYgaXQgaXMgZm91bmQsIHRoZW4gY2hhbmdlIGNvbnRlbnQgdHlwZSBhbmQgdXBkYXRlIHRoZSB1cmxcclxuXHJcbiAgICBpZiAodHlwZSkge1xyXG4gICAgICBpZiAoIWl0ZW0ub3B0cy50aHVtYiAmJiAhKGl0ZW0ub3B0cy4kdGh1bWIgJiYgaXRlbS5vcHRzLiR0aHVtYi5sZW5ndGgpKSB7XHJcbiAgICAgICAgaXRlbS5vcHRzLnRodW1iID0gdGh1bWI7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0eXBlID09PSBcImlmcmFtZVwiKSB7XHJcbiAgICAgICAgaXRlbS5vcHRzID0gJC5leHRlbmQodHJ1ZSwgaXRlbS5vcHRzLCB7XHJcbiAgICAgICAgICBpZnJhbWU6IHtcclxuICAgICAgICAgICAgcHJlbG9hZDogZmFsc2UsXHJcbiAgICAgICAgICAgIGF0dHI6IHtcclxuICAgICAgICAgICAgICBzY3JvbGxpbmc6IFwibm9cIlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICQuZXh0ZW5kKGl0ZW0sIHtcclxuICAgICAgICB0eXBlOiB0eXBlLFxyXG4gICAgICAgIHNyYzogdXJsLFxyXG4gICAgICAgIG9yaWdTcmM6IGl0ZW0uc3JjLFxyXG4gICAgICAgIGNvbnRlbnRTb3VyY2U6IHByb3ZpZGVyLFxyXG4gICAgICAgIGNvbnRlbnRUeXBlOiB0eXBlID09PSBcImltYWdlXCIgPyBcImltYWdlXCIgOiBwcm92aWRlciA9PSBcImdtYXBfcGxhY2VcIiB8fCBwcm92aWRlciA9PSBcImdtYXBfc2VhcmNoXCIgPyBcIm1hcFwiIDogXCJ2aWRlb1wiXHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmICh1cmwpIHtcclxuICAgICAgaXRlbS50eXBlID0gaXRlbS5vcHRzLmRlZmF1bHRUeXBlO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBMb2FkIFlvdVR1YmUvVmlkZW8gQVBJIG9uIHJlcXVlc3QgdG8gZGV0ZWN0IHdoZW4gdmlkZW8gZmluaXNoZWQgcGxheWluZ1xyXG4gIHZhciBWaWRlb0FQSUxvYWRlciA9IHtcclxuICAgIHlvdXR1YmU6IHtcclxuICAgICAgc3JjOiBcImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2lmcmFtZV9hcGlcIixcclxuICAgICAgY2xhc3M6IFwiWVRcIixcclxuICAgICAgbG9hZGluZzogZmFsc2UsXHJcbiAgICAgIGxvYWRlZDogZmFsc2VcclxuICAgIH0sXHJcblxyXG4gICAgdmltZW86IHtcclxuICAgICAgc3JjOiBcImh0dHBzOi8vcGxheWVyLnZpbWVvLmNvbS9hcGkvcGxheWVyLmpzXCIsXHJcbiAgICAgIGNsYXNzOiBcIlZpbWVvXCIsXHJcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxyXG4gICAgICBsb2FkZWQ6IGZhbHNlXHJcbiAgICB9LFxyXG5cclxuICAgIGxvYWQ6IGZ1bmN0aW9uICh2ZW5kb3IpIHtcclxuICAgICAgdmFyIF90aGlzID0gdGhpcyxcclxuICAgICAgICBzY3JpcHQ7XHJcblxyXG4gICAgICBpZiAodGhpc1t2ZW5kb3JdLmxvYWRlZCkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgX3RoaXMuZG9uZSh2ZW5kb3IpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRoaXNbdmVuZG9yXS5sb2FkaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzW3ZlbmRvcl0ubG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xyXG4gICAgICBzY3JpcHQudHlwZSA9IFwidGV4dC9qYXZhc2NyaXB0XCI7XHJcbiAgICAgIHNjcmlwdC5zcmMgPSB0aGlzW3ZlbmRvcl0uc3JjO1xyXG5cclxuICAgICAgaWYgKHZlbmRvciA9PT0gXCJ5b3V0dWJlXCIpIHtcclxuICAgICAgICB3aW5kb3cub25Zb3VUdWJlSWZyYW1lQVBJUmVhZHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBfdGhpc1t2ZW5kb3JdLmxvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgICBfdGhpcy5kb25lKHZlbmRvcik7XHJcbiAgICAgICAgfTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzY3JpcHQub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgX3RoaXNbdmVuZG9yXS5sb2FkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgX3RoaXMuZG9uZSh2ZW5kb3IpO1xyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcclxuICAgIH0sXHJcbiAgICBkb25lOiBmdW5jdGlvbiAodmVuZG9yKSB7XHJcbiAgICAgIHZhciBpbnN0YW5jZSwgJGVsLCBwbGF5ZXI7XHJcblxyXG4gICAgICBpZiAodmVuZG9yID09PSBcInlvdXR1YmVcIikge1xyXG4gICAgICAgIGRlbGV0ZSB3aW5kb3cub25Zb3VUdWJlSWZyYW1lQVBJUmVhZHk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGluc3RhbmNlID0gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgJGVsID0gaW5zdGFuY2UuY3VycmVudC4kY29udGVudC5maW5kKFwiaWZyYW1lXCIpO1xyXG5cclxuICAgICAgICBpZiAodmVuZG9yID09PSBcInlvdXR1YmVcIiAmJiBZVCAhPT0gdW5kZWZpbmVkICYmIFlUKSB7XHJcbiAgICAgICAgICBwbGF5ZXIgPSBuZXcgWVQuUGxheWVyKCRlbC5hdHRyKFwiaWRcIiksIHtcclxuICAgICAgICAgICAgZXZlbnRzOiB7XHJcbiAgICAgICAgICAgICAgb25TdGF0ZUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlLmRhdGEgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICBpbnN0YW5jZS5uZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2UgaWYgKHZlbmRvciA9PT0gXCJ2aW1lb1wiICYmIFZpbWVvICE9PSB1bmRlZmluZWQgJiYgVmltZW8pIHtcclxuICAgICAgICAgI
109HBsYXllciA9IG5ldyBWaW1lby5QbGF5ZXIoJGVsKTtcclxuXHJcbiAgICAgICAgICBwbGF5ZXIub24oXCJlbmRlZFwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLm5leHQoKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gICQoZG9jdW1lbnQpLm9uKHtcclxuICAgIFwiYWZ0ZXJTaG93LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCkge1xyXG4gICAgICBpZiAoaW5zdGFuY2UuZ3JvdXAubGVuZ3RoID4gMSAmJiAoY3VycmVudC5jb250ZW50U291cmNlID09PSBcInlvdXR1YmVcIiB8fCBjdXJyZW50LmNvbnRlbnRTb3VyY2UgPT09IFwidmltZW9cIikpIHtcclxuICAgICAgICBWaWRlb0FQSUxvYWRlci5sb2FkKGN1cnJlbnQuY29udGVudFNvdXJjZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxufSkoalF1ZXJ5KTtcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbi8vXHJcbi8vIEd1ZXN0dXJlc1xyXG4vLyBBZGRzIHRvdWNoIGd1ZXN0dXJlcywgaGFuZGxlcyBjbGljayBhbmQgdGFwIGV2ZW50c1xyXG4vL1xyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4oZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQsICQpIHtcclxuICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgdmFyIHJlcXVlc3RBRnJhbWUgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxyXG4gICAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgLy8gaWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBzZXRUaW
1091lb3V0XHJcbiAgICAgIGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDYwKTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9KSgpO1xyXG5cclxuICB2YXIgY2FuY2VsQUZyYW1lID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSB8fFxyXG4gICAgICB3aW5kb3cud2Via2l0Q2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgd2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XHJcbiAgICAgIHdpbmRvdy5vQ2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgZnVuY3Rpb24gKGlkKSB7XHJcbiAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChpZCk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfSkoKTtcclxuXHJcbiAgdmFyIGdldFBvaW50ZXJYWSA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICB2YXIgcmVzdWx0ID0gW107XHJcblxyXG4gICAgZSA9IGUub3JpZ2luYWxFdmVudCB8fCBlIHx8IHdpbmRvdy5lO1xyXG4gICAgZSA9IGUudG91Y2hlcyAmJiBlLnRvdWNoZXMubGVuZ3RoID8gZS50b3VjaGVzIDogZS5jaGFuZ2VkVG91Y2hlcyAmJiBlLmNoYW5nZWRUb3VjaGVzLmxlbmd0aCA/IGUuY2hhbmdlZFRvdWNoZXMgOiBbZV07XHJcblxyXG4gICAgZm9yICh2YXIga2V5IGluIGUpIHtcclxuICAgICAgaWYgKGVba2V5XS5wYWdlWCkge1xyXG4gICAgICAgIHJlc3VsdC5wdXNoKHtcclxuICAgICAgICAgIHg6IGVba2V5XS5wYWdlWCxcclxuICAgICAgICAgIHk6IGVba2V5XS5wYWdlWVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2UgaWYgKGVba2V5XS5jbGllbnRYKSB7XHJcbiAgICAgICAgcmVzdWx0LnB1c2goe1xyXG4gICAgICAgICAgeDogZVtrZXldLmNsaWVudFgsXHJcbiAgICAgICAgICB5OiBlW2tleV0uY2xpZW50WVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9O1xyXG5cclxuICB2YXIgZGlzdGFuY2UgPSBmdW5jdGlvbiAocG9pbnQyLCBwb2ludDEsIHdoYXQpIHtcclxuICAgIGlmICghcG9pbnQxIHx8ICFwb2ludDIpIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHdoYXQgPT09IFwieFwiKSB7XHJcbiAgICAgIHJldHVybiBwb2ludDIueCAtIHBvaW50MS54O1xyXG4gICAgfSBlbHNlIGlmICh3aGF0ID09PSBcInlcIikge1xyXG4gICAgICByZXR1cm4gcG9pbnQyLnkgLSBwb2ludDEueTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHBvaW50Mi54IC0gcG9pbnQxLngsIDIpICsgTWF0aC5wb3cocG9pbnQyLnkgLSBwb2ludDEueSwgMikpO1xyXG4gIH07XHJcblxyXG4gIHZhciBpc0NsaWNrYWJsZSA9IGZ1bmN0aW9uICgkZWwpIHtcclxuICAgIGlmIChcclxuICAgICAgJGVsLmlzKCdhLGFyZWEsYnV0dG9uLFtyb2xlPVwiYnV0dG9uXCJdLGlucHV0LGxhYmVsLHNlbGVjdCxzdW1tYXJ5LHRleHRhcmVhLHZpZGVvLGF1ZGlvLGlmcmFtZScpIHx8XHJcbiAgICAgICQuaXNGdW5jdGlvbigkZWwuZ2V0KDApLm9uY2xpY2spIHx8XHJcbiAgICAgICRlbC5kYXRhKFwic2VsZWN0YWJsZVwiKVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGZvciBhdHRyaWJ1dGVzIGxpa2UgZGF0YS1mYW5jeWJveC1uZXh0IG9yIGRhdGEtZmFuY3lib3gtY2xvc2VcclxuICAgIGZvciAodmFyIGkgPSAwLCBhdHRzID0gJGVsWzBdLmF0dHJpYnV0ZXMsIG4gPSBhdHRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICBpZiAoYXR0c1tpXS5ub2RlTmFtZS5zdWJzdHIoMCwgMTQpID09PSBcImRhdGEtZmFuY3lib3gtXCIpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9O1xyXG5cclxuICB2YXIgaGFzU2Nyb2xsYmFycyA9IGZ1bmN0aW9uIChlbCkge1xyXG4gICAgdmFyIG92ZXJmbG93WSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKVtcIm92ZXJmbG93LXlcIl0sXHJcbiAgICAgIG92ZXJmbG93WCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKVtcIm92ZXJmbG93LXhcIl0sXHJcbiAgICAgIHZlcnRpY2FsID0gKG92ZXJmbG93WSA9PT0gXCJzY3JvbGxcIiB8fCBvdmVyZmxvd1kgPT09IFwiYXV0b1wiKSAmJiBlbC5zY3JvbGxIZWlnaHQgPiBlbC5jbGllbnRIZWlnaHQsXHJcbiAgICAgIGhvcml6b250YWwgPSAob3ZlcmZsb3dYID09PSBcInNjcm9sbFwiIHx8IG92ZXJmbG93WCA9PT0gXCJhdXRvXCIpICYmIGVsLnNjcm9sbFdpZHR
109oID4gZWwuY2xpZW50V2lkdGg7XHJcblxyXG4gICAgcmV0dXJuIHZlcnRpY2FsIHx8IGhvcml6b250YWw7XHJcbiAgfTtcclxuXHJcbiAgdmFyIGlzU2Nyb2xsYWJsZSA9IGZ1bmN0aW9uICgkZWwpIHtcclxuICAgIHZhciByZXogPSBmYWxzZTtcclxuXHJcbiAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICByZXogPSBoYXNTY3JvbGxiYXJzKCRlbC5nZXQoMCkpO1xyXG5cclxuICAgICAgaWYgKHJleikge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkZWwgPSAkZWwucGFyZW50KCk7XHJcblxyXG4gICAgICBpZiAoISRlbC5sZW5ndGggfHwgJGVsLmhhc0NsYXNzKFwiZmFuY3lib3gtc3RhZ2VcIikgfHwgJGVsLmlzKFwiYm9keVwiKSkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlejtcclxuICB9O1xyXG5cclxuICB2YXIgR3Vlc3R1cmVzID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgc2VsZi5pbnN0YW5jZSA9IGluc3RhbmNlO1xyXG5cclxuICAgIHNlbGYuJGJnID0gaW5zdGFuY2UuJHJlZnMuYmc7XHJcbiAgICBzZWxmLiRzdGFnZSA9IGluc3RhbmNlLiRyZWZzLnN0YWdlO1xyXG4gICAgc2VsZi4kY29udGFpbmVyID0gaW5zdGFuY2UuJHJlZnMuY29udGFpbmVyO1xyXG5cclxuICAgIHNlbGYuZGVzdHJveSgpO1xyXG5cclxuICAgIHNlbGYuJGNvbnRhaW5lci5vbihcInRvdWNoc3RhcnQuZmIudG91Y2ggbW91c2Vkb3duLmZiLnRvdWNoXCIsICQucHJveHkoc2VsZiwgXCJvbnRvdWNoc3RhcnRcIikpO1xyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICBzZWxmLiRjb250YWluZXIub2ZmKFwiLmZiLnRvdWNoXCIpO1xyXG5cclxuICAgICQoZG9jdW1lbnQpLm9mZihcIi5mYi50b3VjaFwiKTtcclxuXHJcbiAgICBpZiAoc2VsZi5yZXF1ZXN0SWQpIHtcclxuICAgICAgY2FuY2VsQUZyYW1lKHNlbGYucmVxdWVzdElkKTtcclxuICAgICAgc2VsZi5yZXF1ZXN0SWQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZWxmLnRhcHBlZCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi50YXBwZWQpO1xyXG4gICAgICBzZWxmLnRhcHBlZCA9IG51bGw7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgR3Vlc3R1cmVzLnByb3RvdHlwZS5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAkdGFyZ2V0ID0gJChlLnRhcmdldCksXHJcbiAgICAgIGluc3RhbmNlID0gc2VsZi5pbnN0YW5jZSxcclxuICAgICAgY3VycmVudCA9IGluc3RhbmNlLmN1cnJlbnQsXHJcbiAgICAgICRzbGlkZSA9IGN1cnJlbnQuJHNsaWRlLFxyXG4gICAgICAkY29udGVudCA9IGN1cnJlbnQuJGNvbnRlbnQsXHJcbiAgICAgIGlzVG91Y2hEZXZpY2UgPSBlLnR5cGUgPT0gXCJ0b3VjaHN0YXJ0XCI7XHJcblxyXG4gICAgLy8gRG8gbm90IHJlc3BvbmQgdG8gYm90aCAodG91Y2ggYW5kIG1vdXNlKSBldmVudHNcclxuICAgIGlmIChpc1RvdWNoRGV2aWNlKSB7XHJcbiAgICAgIHNlbGYuJGNvbnRhaW5lci5vZmYoXCJtb3VzZWRvd24uZmIudG91Y2hcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWdub3JlIHJpZ2h0IGNsaWNrXHJcbiAgICBpZiAoZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5idXR0b24gPT0gMikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWdub3JlIHRhcGluZyBvbiBsaW5rcywgYnV0dG9ucywgaW5wdXQgZWxlbWVudHNcclxuICAgIGlmICghJHNsaWRlLmxlbmd0aCB8fCAhJHRhcmdldC5sZW5ndGggfHwgaXNDbGlja2FibGUoJHRhcmdldCkgfHwgaXNDbGlja2FibGUoJHRhcmdldC5wYXJlbnQoKSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgLy8gSWdub3JlIGNsaWNrcyBvbiB0aGUgc2Nyb2xsYmFyXHJcbiAgICBpZiAoISR0YXJnZXQuaXMoXCJpbWdcIikgJiYgZS5vcmlnaW5hbEV2ZW50LmNsaWVudFggPiAkdGFyZ2V0WzBdLmNsaWVudFdpZHRoICsgJHRhcmdldC5vZmZzZXQoKS5sZWZ0KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBJZ25vcmUgY2xpY2tzIHdoaWxlIHpvb21pbmcgb3IgY2xvc2luZ1xyXG4gICAgaWYgKCFjdXJyZW50IHx8IGluc3RhbmNlLmlzQW5pbWF0aW5nIHx8IGN1cnJlbnQuJHNsaWRlLmhhc0NsYXNzKFwiZmFuY3lib3gtYW5pbWF0ZWRcIikpIHtcclxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHNlbGYucmVhbFBvaW50cyA9IHNlbGYuc3RhcnRQb2ludHMgPSBnZXRQb2ludGVyWFkoZSk7XHJcblxyXG4gICAgaWYgKCFzZWxmLnN0YXJ0UG9pbnRzLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWxsb3cgb3RoZXIgc2NyaXB0cyB0byBjYXRjaCB0b3VjaCBldmVudCBpZiBcInRvdWNoXCIgaXMgc2V0IHRvIGZhbHNlXHJcbiAgICBpZiAoY3VycmVudC50b3VjaCkge1xyXG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIHNlbGYuc3RhcnRFdmVudCA9IGU7XHJcblxyXG4gICAgc2VsZi5jYW5UYXAgPSB0cnVlO1xyXG4gICAgc2VsZi4kdGFyZ2V0ID0gJHRhcmdldDtcclxuICAgIHNlbGYuJGNvbnRlbnQgPSAkY29udGVudDtcclxuICAgIHNlbGYub3B0cyA9IGN1cnJlbnQub3B0cy50b3VjaDtcclxuXHJcbiAgICBzZWxmLmlzUGFubmluZyA9IGZhbHNlO1xyXG4gICAgc2VsZi5pc1N3aXBpbmcgPSBmYWxzZTtcclxuICAgIHNlbGYuaXNab29taW5nID0gZmFsc2U7XHJcbiAgICBzZWxmLmlzU2Nyb2xsaW5nID0gZmFsc2U7XHJcbiAgICBzZWxmLmNhblBhbiA9IGluc3RhbmNlLmNhblBhbigpO1xyXG5cclxuICAgIHNlbGYuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICBzZWxmLmRpc3RhbmNlWCA9IHNlbGYuZGlzdGFuY2VZID0gc2VsZi5kaXN0YW5jZSA9IDA7XHJcblxyXG4gICAgc2VsZi5jYW52YXNXaWR0aCA9IE1hdGgucm91bmQoJHNsaWRlWzBdLmNsaWVudFdpZHRoKTtcclxuICAgIHNlbGYuY2FudmFzSGVpZ2h0ID0gTWF0aC5yb3VuZCgkc2xpZGVbMF0uY2xpZW50SGVpZ2h0KTtcclxuXHJcbiAgICBzZWxmLmNvbnRlbn
109RMYXN0UG9zID0gbnVsbDtcclxuICAgIHNlbGYuY29udGVudFN0YXJ0UG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoc2VsZi4kY29udGVudCkgfHwge1xyXG4gICAgICB0b3A6IDAsXHJcbiAgICAgIGxlZnQ6IDBcclxuICAgIH07XHJcbiAgICBzZWxmLnNsaWRlclN0YXJ0UG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoJHNsaWRlKTtcclxuXHJcbiAgICAvLyBTaW5jZSBwb3NpdGlvbiB3aWxsIGJlIGFic29sdXRlLCBidXQgd2UgbmVlZCB0byBtYWtlIGl0IHJlbGF0aXZlIHRvIHRoZSBzdGFnZVxyXG4gICAgc2VsZi5zdGFnZVBvcyA9ICQuZmFuY3lib3guZ2V0VHJhbnNsYXRlKGluc3RhbmNlLiRyZWZzLnN0YWdlKTtcclxuXHJcbiAgICBzZWxmLnNsaWRlclN0YXJ0UG9zLnRvcCAtPSBzZWxmLnN0YWdlUG9zLnRvcDtcclxuICAgIHNlbGYuc2xpZGVyU3RhcnRQb3MubGVmdCAtPSBzZWxmLnN0YWdlUG9zLmxlZnQ7XHJcblxyXG4gICAgc2VsZi5jb250ZW50U3RhcnRQb3MudG9wIC09IHNlbGYuc3RhZ2VQb3MudG9wO1xyXG4gICAgc2VsZi5jb250ZW50U3RhcnRQb3MubGVmdCAtPSBzZWxmLnN0YWdlUG9zLmxlZnQ7XHJcblxyXG4gICAgJChkb2N1bWVudClcclxuICAgICAgLm9mZihcIi5mYi50b3VjaFwiKVxyXG4gICAgICAub24oaXNUb3VjaERldmljZSA/IFwidG91Y2hlbmQuZmIudG91Y2ggdG91Y2hjYW5jZWwuZmIudG91Y2hcIiA6IFwibW91c2V1cC5mYi50b3VjaCBtb3VzZWxlYXZlLmZiLnRvdWNoXCIsICQucHJveHkoc2VsZiwgXCJvbnRvdWNoZW5kXCIpKVxyXG4gICAgICAub24oaXNUb3VjaERldmljZSA/IFwidG91Y2htb3ZlLmZiLnRvdWNoXCIgOiBcIm1vdXNlbW92ZS5mYi50b3VjaFwiLCAkLnByb3h5KHNlbGYsIFwib250b3VjaG1vdmVcIikpO1xyXG5cclxuICAgIGlmICgkLmZhbmN5Ym94LmlzTW9iaWxlKSB7XHJcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgc2VsZi5vbnNjcm9sbCwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2tpcCBpZiBjbGlja2VkIG91dHNpZGUgdGhlIHNsaWRpbmcgYXJlYVxyXG4gICAgaWYgKCEoc2VsZi5vcHRzIHx8IHNlbGYuY2FuUGFuKSB8fCAhKCR0YXJnZXQuaXMoc2VsZi4kc3RhZ2UpIHx8IHNlbGYuJHN0YWdlLmZpbmQoJHRhcmdldCkubGVuZ3RoKSkge1xyXG4gICAgICBpZiAoJHRhcmdldC5pcyhcIi5mYW5jeWJveC1pbWFnZVwiKSkge1xyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCEoJC5mYW5jeWJveC5pc01vYmlsZSAmJiAkdGFyZ2V0LnBhcmVudHMoXCIuZmFuY3lib3gtY2FwdGlvblwiKS5sZW5ndGgpKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5pc1Njcm9sbGFibGUgPSBpc1Njcm9sbGFibGUoJHRhcmdldCkgfHwgaXNTY3JvbGxhYmxlKCR0YXJnZXQucGFyZW50KCkpO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIGVsZW1lbnQgaXMgc2Nyb2xsYWJsZSBhbmQgdHJ5IHRvIHByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciAoc2Nyb2xsaW5nKVxyXG4gICAgaWYgKCEoJC5mYW5jeWJveC5pc01vYmlsZSAmJiBzZWxmLmlzU2Nyb2xsYWJsZSkpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE9uZSBmaW5nZXIgb3IgbW91c2UgY2xpY2sgLSBzd2lwZSBvciBwYW4gYW4gaW1hZ2VcclxuICAgIGlmIChzZWxmLnN0YXJ0UG9pbnRzLmxlbmd0aCA9PT0gMSB8fCBjdXJyZW50Lmhhc0Vycm9yKSB7XHJcbiAgICAgIGlmIChzZWxmLmNhblBhbikge1xyXG4gICAgICAgICQuZmFuY3lib3guc3RvcChzZWxmLiRjb250ZW50KTtcclxuXHJcbiAgICAgICAgc2VsZi5pc1Bhbm5pbmcgPSB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNlbGYuaXNTd2lwaW5nID0gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi4kY29udGFpbmVyLmFkZENsYXNzKFwiZmFuY3lib3gtaXMtZ3JhYmJpbmdcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVHdvIGZpbmdlcnMgLSB6b29tIGltYWdlXHJcbiAgICBpZiAoc2VsZi5zdGFydFBvaW50cy5sZW5ndGggPT09IDIgJiYgY3VycmVudC50eXBlID09PSBcImltYWdlXCIgJiYgKGN1cnJlbnQuaXNMb2FkZWQgfHwgY3VycmVudC4kZ2hvc3QpKSB7XHJcbiAgICAgIHNlbGYuY2FuVGFwID0gZmFsc2U7XHJcbiAgICAgIHNlbGYuaXNTd2lwaW5nID0gZmFsc2U7XHJcbiAgICAgIHNlbGYuaXNQYW5uaW5nID0gZmFsc2U7XHJcblxyXG4gICAgICBzZWxmLmlzWm9vbWluZyA9IHRydWU7XHJcblxyXG4gICAgICAkLmZhbmN5Ym94LnN0b3Aoc2VsZi4kY29udGVudCk7XHJcblxyXG4gICAgICBzZWxmLmNlbnRlclBvaW50U3RhcnRYID0gKHNlbGYuc3RhcnRQb2ludHNbMF0ueCArIHNlbGYuc3RhcnRQb2ludHNbMV0ueCkgKiAwLjUgLSAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpO1xyXG4gICAgICBzZWxmLmNlbnRlclBvaW50U3RhcnRZID0gKHNlbGYuc3RhcnRQb2ludHNbMF0ueSArIHNlbGYuc3RhcnRQb2ludHNbMV0ueSkgKiAwLjUgLSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XHJcblxyXG4gICAgICBzZWxmLnBlcmNlbnRhZ2VPZkltYWdlQXRQaW5jaFBvaW50WCA9IChzZWxmLmNlbnRlclBvaW50U3RhcnRYIC0gc2VsZi5jb250ZW50U3RhcnRQb3MubGVmdCkgLyBzZWxmLmNvbnRlbnRTdGFydFBvcy53aWR0aDtcclxuICAgICAgc2VsZi5wZXJjZW50YWdlT2ZJbWFnZUF0UGluY2hQb2ludFkgPSAoc2VsZi5jZW50ZXJQb2ludFN0YXJ0WSAtIHNlbGYuY29udGVudFN0YXJ0UG9zLnRvcCkgLyBzZWxmLmNvbnRlbnRTdGFydFBvcy5oZWlnaHQ7XHJcblxyXG4gICAgICBzZWxmLnN0YXJ0RGlzdGFuY2VCZXR3ZWVuRmluZ2VycyA9IGRpc3RhbmNlKHNlbGYuc3RhcnRQb2ludHNbMF0sIHNlbGYuc3RhcnRQb2ludHNbMV0pO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUub25zY3JvbGwgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHNlbGYuaXNTY3JvbGxpbmcgPSB0cnVlO1xyXG5cclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgc2VsZi5vbnNjcm9sbCwgdHJ1ZSk7XHJcbiAgfTtcclxuXHJcbiAgR3Vlc3R1cmVzLnByb3RvdHlwZS5vbnRvdWNobW92ZSA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgLy8gTWFrZSBzdXJlIHVzZXIgaGFzIG5vdCByZWxlYXNlZCBvdmVyIGlmcmFtZSBvciBkaXNhYmxlZCBlbGVtZW50XHJcbiAgICBpZiAoZS5vcmlnaW5hbEV2ZW50LmJ1dHRvbnMgIT09IHVuZGVmaW5lZCAmJiBlLm9yaWdpbmFsRXZlbnQuYnV0dG9ucyA9PT0gMCkge1xyXG4gICAgICBzZWxmLm9udG91Y2hlbmQoZSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc2VsZi5pc1Njcm9sbGluZykge1xyXG4gICAgICBzZWxmLmNhblRhcCA9IGZhbHNlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5uZXdQb2ludHMgPSBnZXRQb2ludGVyWFkoZSk7XHJcblxyXG4gICAgaWYgKCEoc2VsZi5vcHRzIHx8IHNlbGYuY2FuUGFuKSB8fCAhc2VsZi5uZXdQb2ludHMubGVuZ3RoIHx8ICFzZWxmLm5ld1BvaW50cy5sZW5ndGgpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghKHNlbGYuaXNTd2lwaW5nICYmIHNlbGYuaXNTd2lwaW5nID09PSB0cnVlKSkge1xyXG4gICAgICBlLnByZXZlbn
109REZWZhdWx0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5kaXN0YW5jZVggPSBkaXN0YW5jZShzZWxmLm5ld1BvaW50c1swXSwgc2VsZi5zdGFydFBvaW50c1swXSwgXCJ4XCIpO1xyXG4gICAgc2VsZi5kaXN0YW5jZVkgPSBkaXN0YW5jZShzZWxmLm5ld1BvaW50c1swXSwgc2VsZi5zdGFydFBvaW50c1swXSwgXCJ5XCIpO1xyXG5cclxuICAgIHNlbGYuZGlzdGFuY2UgPSBkaXN0YW5jZShzZWxmLm5ld1BvaW50c1swXSwgc2VsZi5zdGFydFBvaW50c1swXSk7XHJcblxyXG4gICAgLy8gU2tpcCBmYWxzZSBvbnRvdWNobW92ZSBldmVudHMgKENocm9tZSlcclxuICAgIGlmIChzZWxmLmRpc3RhbmNlID4gMCkge1xyXG4gICAgICBpZiAoc2VsZi5pc1N3aXBpbmcpIHtcclxuICAgICAgICBzZWxmLm9uU3dpcGUoZSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoc2VsZi5pc1Bhbm5pbmcpIHtcclxuICAgICAgICBzZWxmLm9uUGFuKCk7XHJcbiAgICAgIH0gZWxzZSBpZiAoc2VsZi5pc1pvb21pbmcpIHtcclxuICAgICAgICBzZWxmLm9uWm9vbSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgR3Vlc3R1cmVzLnByb3RvdHlwZS5vblN3aXBlID0gZnVuY3Rpb24gKGUpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgaW5zdGFuY2UgPSBzZWxmLmluc3RhbmNlLFxyXG4gICAgICBzd2lwaW5nID0gc2VsZi5pc1N3aXBpbmcsXHJcbiAgICAgIGxlZnQgPSBzZWxmLnNsaWRlclN0YXJ0UG9zLmxlZnQgfHwgMCxcclxuICAgICAgYW5nbGU7XHJcblxyXG4gICAgLy8gSWYgZGlyZWN0aW9uIGlzIG5vdCB5ZXQgZGV0ZXJtaW5lZFxyXG4gICAgaWYgKHN3aXBpbmcgPT09IHRydWUpIHtcclxuICAgICAgLy8gV2UgbmVlZCBhdCBsZWFzdCAxMHB4IGRpc3RhbmNlIHRvIGNvcnJlY3RseSBjYWxjdWxhdGUgYW4gYW5nbGVcclxuICAgICAgaWYgKE1hdGguYWJzKHNlbGYuZGlzdGFuY2UpID4gMTApIHtcclxuICAgICAgICBzZWxmLmNhblRhcCA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAoaW5zdGFuY2UuZ3JvdXAubGVuZ3RoIDwgMiAmJiBzZWxmLm9wdHMudmVydGljYWwpIHtcclxuICAgICAgICAgIHNlbGYuaXNTd2lwaW5nID0gXCJ5XCI7XHJcbiAgICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5pc0RyYWdnaW5nIHx8IHNlbGYub3B0cy52ZXJ0aWNhbCA9PT0gZmFsc2UgfHwgKHNlbGYub3B0cy52ZXJ0aWNhbCA9PT0gXCJhdXRvXCIgJiYgJCh3aW5kb3cpLndpZHRoKCkgPiA4MDApKSB7XHJcbiAgICAgICAgICBzZWxmLmlzU3dpcGluZyA9IFwieFwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBhbmdsZSA9IE1hdGguYWJzKChNYXRoLmF0YW4yKHNlbGYuZGlzdGFuY2VZLCBzZWxmLmRpc3RhbmNlWCkgKiAxODApIC8gTWF0aC5QSSk7XHJcblxyXG4gICAgICAgICAgc2VsZi5pc1N3aXBpbmcgPSBhbmdsZSA+IDQ1ICYmIGFuZ2xlIDwgMTM1ID8gXCJ5XCIgOiBcInhcIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzZWxmLmlzU3dpcGluZyA9PT0gXCJ5XCIgJiYgJC5mYW5jeWJveC5pc01vYmlsZSAmJiBzZWxmLmlzU2Nyb2xsYWJsZSkge1xyXG4gICAgICAgICAgc2VsZi5pc1Njcm9sbGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW5zdGFuY2UuaXNEcmFnZ2luZyA9IHNlbGYuaXNTd2lwaW5nO1xyXG5cclxuICAgICAgICAvLyBSZXNldCBwb2ludHMgdG8gYXZvaWQganVtcGluZywgYmVjYXVzZSB3ZSBkcm9wcGVkIGZpcnN0IHN3aXBlcyB0byBjYWxjdWxhdGUgdGhlIGFuZ2xlXHJcbiAgICAgICAgc2VsZi5zdGFydFBvaW50cyA9IHNlbGYubmV3UG9pbnRzO1xyXG5cclxuICAgICAgICAkLmVhY2goaW5zdGFuY2Uuc2xpZGVzLCBmdW5jdGlvbiAoaW5kZXgsIHNsaWRlKSB7XHJcbiAgICAgICAgICB2Y
109XIgc2xpZGVQb3MsIHN0YWdlUG9zO1xyXG5cclxuICAgICAgICAgICQuZmFuY3lib3guc3RvcChzbGlkZS4kc2xpZGUpO1xyXG5cclxuICAgICAgICAgIHNsaWRlUG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoc2xpZGUuJHNsaWRlKTtcclxuICAgICAgICAgIHN0YWdlUG9zID0gJC5mYW5jeWJveC5nZXRUcmFuc2xhdGUoaW5zdGFuY2UuJHJlZnMuc3RhZ2UpO1xyXG5cclxuICAgICAgICAgIHNsaWRlLiRzbGlkZVxyXG4gICAgICAgICAgICAuY3NzKHtcclxuICAgICAgICAgICAgICB0cmFuc2Zvcm06IFwiXCIsXHJcbiAgICAgICAgICAgICAgb3BhY2l0eTogXCJcIixcclxuICAgICAgICAgICAgICBcInRyYW5zaXRpb24tZHVyYXRpb25cIjogXCJcIlxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1hbmltYXRlZFwiKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoZnVuY3Rpb24gKGluZGV4LCBjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gKGNsYXNzTmFtZS5tYXRjaCgvKF58XFxzKWZhbmN5Ym94LWZ4LVxcUysvZykgfHwgW10pLmpvaW4oXCIgXCIpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICBpZiAoc2xpZGUucG9zID09PSBpbnN0YW5jZS5jdXJyZW50LnBvcykge1xyXG4gICAgICAgICAgICBzZWxmLnNsaWRlclN0YXJ0UG9zLnRvcCA9IHNsaWRlUG9zLnRvcCAtIHN0YWdlUG9zLnRvcDtcclxuICAgICAgICAgICAgc2VsZi5zbGlkZXJTdGFydFBvcy5sZWZ0ID0gc2xpZGVQb3MubGVmdCAtIHN0YWdlUG9zLmxlZnQ7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgJC5mYW5jeWJveC5zZXRUcmFuc2xhdGUoc2xpZGUuJHNsaWRlLCB7XHJcbiAgICAgICAgICAgIHRvcDogc2xpZGVQb3MudG9wIC0gc3RhZ2VQb3MudG9wLFxyXG4gICAgICAgICAgICBsZWZ0OiBzbGlkZVBvcy5sZWZ0IC0gc3RhZ2VQb3MubGVmdFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIFN0b3Agc2xpZGVzaG93XHJcbiAgICAgICAgaWYgKGluc3RhbmNlLlNsaWRlU2hvdyAmJiBpbnN0YW5jZS5TbGlkZVNob3cuaXNBY3RpdmUpIHtcclxuICAgICAgICAgIGluc3RhbmNlLlNsaWRlU2hvdy5zdG9wKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU3RpY2t5IGVkZ2VzXHJcbiAgICBpZiAoc3dpcGluZyA9PSBcInhcIikge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgc2VsZi5kaXN0YW5jZVggPiAwICYmXHJcbiAgICAgICAgKHNlbGYuaW5zdGFuY2UuZ3JvdXAubGVuZ3RoIDwgMiB8fCAoc2VsZi5pbnN0YW5jZS5jdXJyZW50LmluZGV4ID09PSAwICYmICFzZWxmLmluc3RhbmNlLmN1cnJlbnQub3B0cy5sb29wKSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgbGVmdCA9IGxlZnQgKyBNYXRoLnBvdyhzZWxmLmRpc3RhbmNlWCwgMC44KTtcclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICBzZWxmLmRpc3RhbmNlWCA8IDAgJiZcclxuICAgICAgICAoc2VsZi5pbnN0YW5jZS5ncm91cC5sZW5ndGggPCAyIHx8XHJcbiAgICAgICAgICAoc2VsZi5pbnN0YW5jZS5jdXJyZW50LmluZGV4ID09PSBzZWxmLmluc3RhbmNlLmdyb3VwLmxlbmd0aCAtIDEgJiYgIXNlbGYuaW5zdGFuY2UuY3VycmVudC5vcHRzLmxvb3ApKVxyXG4gICAgICApIHtcclxuICAgICAgICBsZWZ0ID0gbGVmdCAtIE1hdGgucG93KC1zZWxmLmRpc3RhbmNlWCwgMC44KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZWZ0ID0gbGVmdCArIHNlbGYuZGlzdGFuY2VYO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5zbGlkZXJMYXN0UG9zID0ge1xyXG4gICAgICB0b3A6IHN3aXBpbmcgPT0gXCJ4XCIgPyAwIDogc2VsZi5zbGlkZXJTdGFydFBvcy50b3AgKyBzZWxmLmRpc3RhbmNlWSxcclxuICAgICAgbGVmdDogbGVmdFxyXG4gICAgfTtcclxuXHJcbiAgICBpZiAoc2VsZi5yZXF1ZXN0SWQpIHtcclxuICAgICAgY2FuY2VsQUZyYW1lKHNlbGYucmVxdWVzdElkKTtcclxuXHJcbiAgICAgIHNlbGYucmVxdWVzdElkID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBzZWxmLnJlcXVlc3RJZCA9IHJlcXVlc3RBRnJhbWUoZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAoc2VsZi5zbGlkZXJMYXN0UG9zKSB7XHJcbiAgICAgICAgJC5lYWNoKHNlbGYuaW5zdGFuY2Uuc2xpZGVzLCBmdW5jdGlvbiAoaW5kZXgsIHNsaWRlKSB7XHJcbiAgICAgICAgICB2Y
109XIgcG9zID0gc2xpZGUucG9zIC0gc2VsZi5pbnN0YW5jZS5jdXJyUG9zO1xyXG5cclxuICAgICAgICAgICQuZmFuY3lib3guc2V0VHJhbnNsYXRlKHNsaWRlLiRzbGlkZSwge1xyXG4gICAgICAgICAgICB0b3A6IHNlbGYuc2xpZGVyTGFzdFBvcy50b3AsXHJcbiAgICAgICAgICAgIGxlZnQ6IHNlbGYuc2xpZGVyTGFzdFBvcy5sZWZ0ICsgcG9zICogc2VsZi5jYW52YXNXaWR0aCArIHBvcyAqIHNsaWRlLm9wdHMuZ3V0dGVyXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2VsZi4kY29udGFpbmVyLmFkZENsYXNzKFwiZmFuY3lib3gtaXMtc2xpZGluZ1wiKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgR3Vlc3R1cmVzLnByb3RvdHlwZS5vblBhbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAvLyBQcmV2ZW50IGFjY2lkZW50YWwgbW92ZW1lbnQgKHNvbWV0aW1lcywgd2hlbiB0YXBwaW5nIGNhc3VhbGx5LCBmaW5nZXIgY2FuIG1vdmUgYSBiaXQpXHJcbiAgICBpZiAoZGlzdGFuY2Uoc2VsZi5uZXdQb2ludHNbMF0sIHNlbGYucmVhbFBvaW50c1swXSkgPCAoJC5mYW5jeWJveC5pc01vYmlsZSA/IDEwIDogNSkpIHtcclxuICAgICAgc2VsZi5zdGFydFBvaW50cyA9IHNlbGYubmV3UG9pbnRzO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5jYW5UYXAgPSBmYWxzZTtcclxuXHJcbiAgICBzZWxmLmNvbnRlbnRMYXN0UG9zID0gc2VsZi5saW1pdE1vdmVtZW50KCk7XHJcblxyXG4gICAgaWYgKHNlbGYucmVxdWVzdElkKSB7XHJcbiAgICAgIGNhbmNlbEFGcmFtZShzZWxmLnJlcXVlc3RJZCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5yZXF1ZXN0SWQgPSByZXF1ZXN0QUZyYW1lKGZ1bmN0aW9uICgpIHtcclxuICAgICAgJC5mYW5jeWJveC5zZXRUcmFuc2xhdGUoc2VsZi4kY29udGVudCwgc2VsZi5jb250ZW50TGFzdFBvcyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvLyBNYWtlIHBhbm5pbmcgc3RpY2t5IHRvIHRoZSBlZGdlc1xyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUubGltaXRNb3ZlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgY2FudmFzV2lkdGggPSBzZWxmLmNhbnZhc1dpZHRoO1xyXG4gICAgdmFyIGNhbnZhc0hlaWdodCA9IHNlbGYuY2FudmFzSGVpZ2h0O1xyXG5cclxuICAgIHZhciBkaXN0YW5jZVggPSBzZWxmLmRpc3RhbmNlWDtcclxuICAgIHZhciBkaXN0YW5jZVkgPSBzZWxmLmRpc3RhbmNlWTtcclxuXHJcbiAgICB2YXIgY29udGVudFN0YXJ0UG9zID0gc2VsZi5jb250ZW50U3RhcnRQb3M7XHJcblxyXG4gICAgdmFyIGN1cnJlbnRPZmZzZXRYID0gY29udGVudFN0YXJ0UG9zLmxlZnQ7XHJcbiAgICB2YXIgY3VycmVudE9mZnNldFkgPSBjb250ZW50U3RhcnRQb3MudG9wO1xyXG5cclxuICAgIHZhciBjdXJyZW50V2lkdGggPSBjb250ZW50U3RhcnRQb3Mud2lkdGg7XHJcbiAgICB2YXIgY3VycmVudEhlaWdodCA9IGNvbnRlbnRTdGFydFBvcy5oZWlnaHQ7XHJcblxyXG4gICAgdmFyIG1pblRyYW5zbGF0ZVgsIG1pblRyYW5zbGF0ZVksIG1heFRyYW5zbGF0ZVgsIG1heFRyYW5zbGF0ZVksIG5ld09mZnNldFgsIG5ld09mZnNldFk7XHJcblxyXG4gICAgaWYgKGN1cnJlbnRXaWR0aCA+IGNhbnZhc1dpZHRoKSB7XHJcbiAgICAgIG5ld09mZnNldFggPSBjdXJyZW50T2Zmc2V0WCArIGRpc3RhbmNlWDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5ld09mZnNldFggPSBjdXJyZW50T2Zmc2V0WDtcclxuICAgIH1cclxuXHJcbiAgICBuZXdPZmZzZXRZID0gY3VycmVudE9mZnNldFkgKyBkaXN0YW5jZVk7XHJcblxyXG4gICAgLy8gU2xvdyBkb3duIHByb3BvcnRpb25hbGx5IHRvIHRyYXZlbGVkIGRpc3RhbmNlXHJcbiAgICBtaW5UcmFuc2xhdGVYID0gTWF0aC5tYXgoMCwgY2FudmFzV2lkdGggKiAwLjUgLSBjdXJyZW50V2lkdGggKiAwLjUpO1xyXG4gICAgbWluVHJhbnNsYXRlWSA9IE1hdGgubWF4KDAsIGNhbnZhc0hlaWdodCAqIDAuNSAtIGN1cnJlbnRIZWlnaHQgKiAwLjUpO1xyXG5cclxuICAgIG1heFRyYW5zbGF0ZVggPSBNYXRoLm1pbihjYW52YXNXaWR0aCAtIGN1cnJlbnRXaWR0aCwgY2FudmFzV2lkdGggKiAwLjUgLSBjdXJyZW50V2lkdGggKiAwLjUpO1xyXG4gICAgbWF4VHJhbnNsYXRlWSA9IE1hdGgubWluKGNhbnZhc0hlaWdodCAtIGN1cnJlbnRIZWlnaHQsIGNhbnZhc0hlaWdodCAqIDAuNSAtIGN1cnJlbnRIZWlnaHQgKiAwLjUpO1xyXG5cclxuICAgIC8vICAgLT5cclxuICAgIGlmIChkaXN0YW5jZVggPiAwICYmIG5ld09mZnNldFggPiBtaW5UcmFuc2xhdGVYKSB7XHJcbiAgICAgIG5ld09mZnNldFggPSBtaW5UcmFuc2xhdGVYIC0gMSArIE1hdGgucG93KC1taW5UcmFuc2xhdGVYICsgY3VycmVudE9mZnNldFggKyBkaXN0YW5jZVgsIDAuOCkgfHwgMDtcclxuICAgIH1cclxuXHJcbiAgICAvLyAgICA8LVxyXG4gICAgaWYgKGRpc3RhbmNlWCA8IDAgJiYgbmV3T2Zmc2V0WCA8IG1heFRyYW5zbGF0ZVgpIHtcclxuICAgICAgbmV3T2Zmc2V0WCA9IG1heFRyYW5zbGF0ZVggKyAxIC0gTWF0aC5wb3cobWF4VHJhbnNsYXRlWCAtIGN1cnJlbnRPZmZzZXRYIC0gZGlzdGFuY2VYLCAwLjgpIHx8IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gICBcXC9cclxuICAgIGlmIChkaXN0YW5jZVkgPiAwICYmIG5ld09mZnNldFkgPiBtaW5UcmFuc2xhdGVZKSB7XHJcbiAgICAgIG5ld09mZnNldFkgPSBtaW5UcmFuc2xhdGVZIC0gMSArIE1hdGgucG93KC1taW5UcmFuc2xhdGVZICsgY3VycmVudE9mZnNldFkgKyBkaXN0YW5jZVksIDAuOCkgfHwgMDtcclxuICAgIH1cclxuXHJcbiAgICAvLyAgIC9cXFxyXG4gICAgaWYgKGRpc3RhbmNlWSA8IDAgJiYgbmV3T2Zmc2V0WSA8IG1heFRyYW5zbGF0ZVkpIHtcclxuICAgICAgbmV3T2Zmc2V0WSA9IG1heFRyYW5zbGF0ZVkgKyAxIC0gTWF0aC5wb3cobWF4VHJhbnNsYXRlWSAtIGN1cnJlbnRPZmZzZXRZIC0gZGlzdGFuY2VZLCAwLjgpIHx8IDA7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdG9wOiBuZXdPZmZzZXRZLFxyXG4gICAgICBsZWZ0OiBuZXdPZmZzZXRYXHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUubGltaXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChuZXdPZmZzZXRYLCBuZXdPZmZzZXRZLCBuZXdXaWR0aCwgbmV3SGVpZ2h0KSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdmFyIGNhbnZhc1dpZHRoID0gc2VsZi5jYW52YXNXaWR0aDtcclxuICAgIHZhciBjYW52YXNIZWlnaHQgPSBzZWxmLmNhbnZhc0hlaWdodDtcclxuXHJcbiAgICBpZiAobmV3V2lkdGggPiBjYW52YXNXaWR0aCkge1xyXG4gICAgICBuZXdPZmZzZXRYID0gbmV3T2Zmc2V0WCA+IDAgPyAwIDogbmV3T2Zmc2V0WDtcclxuICAgICAgbmV3T2Zmc2V0WCA9IG5ld09mZnNldFggPCBjYW52YXNXaWR0aCAtIG5ld1dpZHRoID8gY2FudmFzV2lkdGggLSBuZXdXaWR0aCA6IG5ld09mZnNldFg7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBDZW50ZXIgaG9yaXpvbn
109RhbGx5XHJcbiAgICAgIG5ld09mZnNldFggPSBNYXRoLm1heCgwLCBjYW52YXNXaWR0aCAvIDIgLSBuZXdXaWR0aCAvIDIpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZXdIZWlnaHQgPiBjYW52YXNIZWlnaHQpIHtcclxuICAgICAgbmV3T2Zmc2V0WSA9IG5ld09mZnNldFkgPiAwID8gMCA6IG5ld09mZnNldFk7XHJcbiAgICAgIG5ld09mZnNldFkgPSBuZXdPZmZzZXRZIDwgY2FudmFzSGVpZ2h0IC0gbmV3SGVpZ2h0ID8gY2FudmFzSGVpZ2h0IC0gbmV3SGVpZ2h0IDogbmV3T2Zmc2V0WTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIENlbnRlciB2ZXJ0aWNhbGx5XHJcbiAgICAgIG5ld09mZnNldFkgPSBNYXRoLm1heCgwLCBjYW52YXNIZWlnaHQgLyAyIC0gbmV3SGVpZ2h0IC8gMik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdG9wOiBuZXdPZmZzZXRZLFxyXG4gICAgICBsZWZ0OiBuZXdPZmZzZXRYXHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUub25ab29tID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIC8vIENhbGN1bGF0ZSBjdXJyZW50IGRpc3RhbmNlIGJldHdlZW4gcG9pbnRzIHRvIGdldCBwaW5jaCByYXRpbyBhbmQgbmV3IHdpZHRoIGFuZCBoZWlnaHRcclxuICAgIHZhciBjb250ZW50U3RhcnRQb3MgPSBzZWxmLmNvbnRlbnRTdGFydFBvcztcclxuXHJcbiAgICB2YXIgY3VycmVudFdpZHRoID0gY29udGVudFN0YXJ0UG9zLndpZHRoO1xyXG4gICAgdmFyIGN1cnJlbnRIZWlnaHQgPSBjb250ZW50U3RhcnRQb3MuaGVpZ2h0O1xyXG5cclxuICAgIHZhciBjdXJyZW50T2Zmc2V0WCA9IGNvbnRlbnRTdGFydFBvcy5sZWZ0O1xyXG4gICAgdmFyIGN1cnJlbnRPZmZzZXRZID0gY29udGVudFN0YXJ0UG9zLnRvcDtcclxuXHJcbiAgICB2YXIgZW5kRGlzdGFuY2VCZXR3ZWVuRmluZ2VycyA9IGRpc3RhbmNlKHNlbGYubmV3UG9pbnRzWzBdLCBzZWxmLm5ld1BvaW50c1sxXSk7XHJcblxyXG4gICAgdmFyIHBpbmNoUmF0aW8gPSBlbmREaXN0YW5jZUJldHdlZW5GaW5nZXJzIC8gc2VsZi5zdGFydERpc3RhbmNlQmV0d2VlbkZpbmdlcnM7XHJcblxyXG4gICAgdmFyIG5ld1dpZHRoID0gTWF0aC5mbG9vcihjdXJyZW50V2lkdGggKiBwaW5jaFJhdGlvKTtcclxuICAgIHZhciBuZXdIZWlnaHQgPSBNYXRoLmZsb29yKGN1cnJlbnRIZWlnaHQgKiBwaW5jaFJhdGlvKTtcclxuXHJcbiAgICAvLyBUaGlzIGlzIHRoZSB0cmFuc2xhdGlvbiBkdWUgdG8gcGluY2gtem9vbWluZ1xyXG4gICAgdmFyIHRyYW5zbGF0ZUZyb21ab29taW5nWCA9IChjdXJyZW50V2lkdGggLSBuZXdXaWR0aCkgKiBzZWxmLnBlcmNlbnRhZ2VPZkltYWdlQXRQaW5jaFBvaW50WDtcclxuICAgIHZhciB0cmFuc2xhdGVGcm9tWm9vbWluZ1kgPSAoY3VycmVudEhlaWdodCAtIG5ld0hlaWdodCkgKiBzZWxmLnBlcmNlbnRhZ2VPZkltYWdlQXRQaW5jaFBvaW50WTtcclxuXHJcbiAgICAvLyBQb2ludCBiZXR3ZWVuIHRoZSB0d28gdG91Y2hlc1xyXG4gICAgdmFyIGNlbnRlclBvaW50RW5kWCA9IChzZWxmLm5ld1BvaW50c1swXS54ICsgc2VsZi5uZXdQb2ludHNbMV0ueCkgLyAyIC0gJCh3aW5kb3cpLnNjcm9sbExlZnQoKTtcclxuICAgIHZhciBjZW50ZXJQb2ludEVuZFkgPSAoc2VsZi5uZXdQb2ludHNbMF0ueSArIHNlbGYubmV3UG9pbnRzWzFdLnkpIC8gMiAtICQod2luZG93KS5zY3JvbGxUb3AoKTtcclxuXHJcbiAgICAvLyBBbmQgdGhpcyBpcyB0aGUgdHJhbnNsYXRpb24gZHVlIHRvIHRyYW5zbGF0aW9uIG9mIHRoZSBjZW50ZXJwb2ludFxyXG4gICAgLy8gYmV0d2VlbiB0aGUgdHdvIGZpbmdlcnNcclxuICAgIHZhciB0cmFuc2xhdGVGcm9tVHJhbnNsYXRpbmdYID0gY2VudGVyUG9pbnRFbmRYIC0gc2VsZi5jZW50ZXJQb2ludFN0YXJ0WDtcclxuICAgIHZhciB0cmFuc2xhdGVGcm9tVHJhbnNsYXRpbmdZID0gY2VudGVyUG9pbnRFbmRZIC0gc2VsZi5jZW50ZXJQb2ludFN0YXJ0WTtcclxuXHJcbiAgICAvLyBUaGUgbmV3IG9mZnNldCBpcyB0aGUgb2xkL2N1cnJlbnQgb25lIHBsdXMgdGhlIHRvdGFsIHRyYW5zbGF0aW9uXHJcbiAgICB2YXIgbmV3T2Zmc2V0WCA9IGN1cnJlbnRPZmZzZXRYICsgKHRyYW5zbGF0ZUZyb21ab29taW5nWCArIHRyYW5zbGF0ZUZyb21UcmFuc2xhdGluZ1gpO1xyXG4gICAgdmFyIG5ld09mZnNldFkgPSBjdXJyZW50T2Zmc2V0WSArICh0cmFuc2xhdGVGcm9tWm9vbWluZ1kgKyB0cmFuc2xhdGVGcm9tVHJhbnNsYXRpbmdZKTtcclxuXHJcbiAgICB2YXIgbmV3UG9zID0ge1xyXG4gICAgICB0b3A6IG5ld09mZnNldFksXHJcbiAgICAgIGxlZnQ6IG5ld09mZnNldFgsXHJcbiAgICAgIHNjYWxlWDogcGluY2hSYXRpbyxcclxuICAgICAgc2NhbGVZOiBwaW5jaFJhdGlvXHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYuY2FuVGFwID0gZmFsc2U7XHJcblxyXG4gICAgc2VsZi5uZXdXaWR0aCA9IG5ld1dpZHRoO1xyXG4gICAgc2VsZi5uZXdIZWlnaHQgPSBuZXdIZWlnaHQ7XHJcblxyXG4gICAgc2VsZi5jb250ZW50TGFzdFBvcyA9IG5ld1BvcztcclxuXHJcbiAgICBpZiAoc2VsZi5yZXF1ZXN0SWQpIHtcclxuICAgICAgY2FuY2VsQUZyYW1lKHNlbGYucmVxdWVzdElkKTtcclxuICAgIH1cclxuXHJcbiAgICBzZWxmLnJlcXVlc3RJZCA9IHJlcXVlc3RBRnJhbWUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAkLmZhbmN5Ym94LnNldFRyYW5zbGF0ZShzZWxmLiRjb250ZW50LCBzZWxmLmNvbnRlbnRMYXN0UG9zKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUub250b3VjaGVuZCA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdmFyIHN3aXBpbmcgPSBzZWxmLmlzU3dpcGluZztcclxuICAgIHZhciBwYW5uaW5nID0gc2VsZi5pc1Bhbm5pbmc7XHJcbiAgICB2YXIgem9vbWluZyA9IHNlbGYuaXNab29taW5nO1xyXG4gICAgdmFyIHNjcm9sbGluZyA9IHNlbGYuaXNTY3JvbGxpbmc7XHJcblxyXG4gICAgc2VsZi5lbmRQb2ludHMgPSBnZXRQb2ludGVyWFkoZSk7XHJcbiAgICBzZWxmLmRNcyA9IE1hdGgubWF4KG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc2VsZi5zdGFydFRpbWUsIDEpO1xyXG5cclxuICAgIHNlbGYuJGNvbn
109RhaW5lci5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LWlzLWdyYWJiaW5nXCIpO1xyXG5cclxuICAgICQoZG9jdW1lbnQpLm9mZihcIi5mYi50b3VjaFwiKTtcclxuXHJcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHNlbGYub25zY3JvbGwsIHRydWUpO1xyXG5cclxuICAgIGlmIChzZWxmLnJlcXVlc3RJZCkge1xyXG4gICAgICBjYW5jZWxBRnJhbWUoc2VsZi5yZXF1ZXN0SWQpO1xyXG5cclxuICAgICAgc2VsZi5yZXF1ZXN0SWQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHNlbGYuaXNTd2lwaW5nID0gZmFsc2U7XHJcbiAgICBzZWxmLmlzUGFubmluZyA9IGZhbHNlO1xyXG4gICAgc2VsZi5pc1pvb21pbmcgPSBmYWxzZTtcclxuICAgIHNlbGYuaXNTY3JvbGxpbmcgPSBmYWxzZTtcclxuXHJcbiAgICBzZWxmLmluc3RhbmNlLmlzRHJhZ2dpbmcgPSBmYWxzZTtcclxuXHJcbiAgICBpZiAoc2VsZi5jYW5UYXApIHtcclxuICAgICAgcmV0dXJuIHNlbGYub25UYXAoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5zcGVlZCA9IDEwMDtcclxuXHJcbiAgICAvLyBTcGVlZCBpbiBweC9tc1xyXG4gICAgc2VsZi52ZWxvY2l0eVggPSAoc2VsZi5kaXN0YW5jZVggLyBzZWxmLmRNcykgKiAwLjU7XHJcbiAgICBzZWxmLnZlbG9jaXR5WSA9IChzZWxmLmRpc3RhbmNlWSAvIHNlbGYuZE1zKSAqIDAuNTtcclxuXHJcbiAgICBpZiAocGFubmluZykge1xyXG4gICAgICBzZWxmLmVuZFBhbm5pbmcoKTtcclxuICAgIH0gZWxzZSBpZiAoem9vbWluZykge1xyXG4gICAgICBzZWxmLmVuZFpvb21pbmcoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNlbGYuZW5kU3dpcGluZyhzd2lwaW5nLCBzY3JvbGxpbmcpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybjtcclxuICB9O1xyXG5cclxuICBHdWVzdHVyZXMucHJvdG90eXBlLmVuZFN3aXBpbmcgPSBmdW5jdGlvbiAoc3dpcGluZywgc2Nyb2xsaW5nKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgIHJldCA9IGZhbHNlLFxyXG4gICAgICBsZW4gPSBzZWxmLmluc3RhbmNlLmdyb3VwLmxlbmd0aCxcclxuICAgICAgZGlzdGFuY2VYID0gTWF0aC5hYnMoc2VsZi5kaXN0YW5jZVgpLFxyXG4gICAgICBjYW5BZHZhbmNlID0gc3dpcGluZyA9PSBcInhcIiAmJiBsZW4gPiAxICYmICgoc2VsZi5kTXMgPiAxMzAgJiYgZGlzdGFuY2VYID4gMTApIHx8IGRpc3RhbmNlWCA+IDUwKSxcclxuICAgICAgc3BlZWRYID0gMzAwO1xyXG5cclxuICAgIHNlbGYuc2xpZGVyTGFzdFBvcyA9IG51bGw7XHJcblxyXG4gICAgLy8gQ2xvc2UgaWYgc3dpcGVkIHZlcnRpY2FsbHkgLyBuYXZpZ2F0ZSBpZiBob3Jpem9udGFsbHlcclxuICAgIGlmIChzd2lwaW5nID09IFwieVwiICYmICFzY3JvbGxpbmcgJiYgTWF0aC5hYnMoc2VsZi5kaXN0YW5jZVkpID4gNTApIHtcclxuICAgICAgLy8gQ29udGludWUgdmVydGljYWwgbW92ZW1lbnRcclxuICAgICAgJC5mYW5jeWJveC5hbmltYXRlKFxyXG4gICAgICAgIHNlbGYuaW5zdGFuY2UuY3VycmVudC4kc2xpZGUsIHtcclxuICAgICAgICAgIHRvcDogc2VsZi5zbGlkZXJTdGFydFBvcy50b3AgKyBzZWxmLmRpc3RhbmNlWSArIHNlbGYudmVsb2NpdHlZICogMTUwLFxyXG4gICAgICAgICAgb3BhY2l0eTogMFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgMjAwXHJcbiAgICAgICk7XHJcbiAgICAgIHJldCA9IHNlbGYuaW5zdGFuY2UuY2xvc2UodHJ1ZSwgMjUwKTtcclxuICAgIH0gZWxzZSBpZiAoY2FuQWR2YW5jZSAmJiBzZWxmLmRpc3RhbmNlWCA+IDApIHtcclxuICAgICAgcmV0ID0gc2VsZi5pbnN0YW5jZS5wcmV2aW91cyhzcGVlZFgpO1xyXG4gICAgfSBlbHNlIGlmIChjYW5BZHZhbmNlICYmIHNlbGYuZGlzdGFuY2VYIDwgMCkge1xyXG4gICAgICByZXQgPSBzZWxmLmluc3RhbmNlLm5leHQoc3BlZWRYKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocmV0ID09PSBmYWxzZSAmJiAoc3dpcGluZyA9PSBcInhcIiB8fCBzd2lwaW5nID09IFwieVwiKSkge1xyXG4gICAgICBzZWxmLmluc3RhbmNlLmNlbnRlclNsaWRlKDIwMCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi4kY29udGFpbmVyLnJlbW92ZUNsYXNzKFwiZmFuY3lib3gtaXMtc2xpZGluZ1wiKTtcclxuICB9O1xyXG5cclxuICAvLyBMaW1pdCBwYW5uaW5nIGZyb20gZWRnZXNcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT1cclxuICBHdWVzdHVyZXMucHJvdG90eXBlLmVuZFBhbm5pbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgIG5ld09mZnNldFgsXHJcbiAgICAgIG5ld09mZnNldFksXHJcbiAgICAgIG5ld1BvcztcclxuXHJcbiAgICBpZiAoIXNlbGYuY29udGVudExhc3RQb3MpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZWxmLm9wdHMubW9tZW50dW0gPT09IGZhbHNlIHx8IHNlbGYuZE1zID4gMzUwKSB7XHJcbiAgICAgIG5ld09mZnNldFggPSBzZWxmLmNvbnRlbnRMYXN0UG9zLmxlZnQ7XHJcbiAgICAgIG5ld09mZnNldFkgPSBzZWxmLmNvbnRlbnRMYXN0UG9zLnRvcDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIENvbnRpbnVlIG1vdmVtZW50XHJcbiAgICAgIG5ld09mZnNldFggPSBzZWxmLmNvbnRlbnRMYXN0UG9zLmxlZnQgKyBzZWxmLnZlbG9jaXR5WCAqIDUwMDtcclxuICAgICAgbmV3T2Zmc2V0WSA9IHNlbGYuY29udGVudExhc3RQb3MudG9wICsgc2VsZi52ZWxvY2l0eVkgKiA1MDA7XHJcbiAgICB9XHJcblxyXG4gICAgbmV3UG9zID0gc2VsZi5saW1pdFBvc2l0aW9uKG5ld09mZnNldFgsIG5ld09mZnNldFksIHNlbGYuY29udGVudFN0YXJ0UG9zLndpZHRoLCBzZWxmLmNvbnRlbnRTdGFydFBvcy5oZWlnaHQpO1xyXG5cclxuICAgIG5ld1Bvcy53aWR0aCA9IHNlbGYuY29udGVudFN0YXJ0UG9zLndpZHRoO1xyXG4gICAgbmV3UG9zLmhlaWdodCA9IHNlbGYuY29udGVudFN0YXJ0UG9zLmhlaWdodDtcclxuXHJcbiAgICAkLmZhbmN5Ym94LmFuaW1hdGUoc2VsZi4kY29udGVudCwgbmV3UG9zLCAzNjYpO1xyXG4gIH07XHJcblxyXG4gIEd1ZXN0dXJlcy5wcm90b3R5cGUuZW5kWm9vbWluZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgY3VycmVudCA9IHNlbGYuaW5zdGFuY2UuY3VycmVudDtcclxuXHJcbiAgICB2YXIgbmV3T2Zmc2V0WCwgbmV3T2Zmc2V0WSwgbmV3UG9zLCByZXNldDtcclxuXHJcbiAgICB2YXIgbmV3V2lkdGggPSBzZWxmLm5ld1dpZHRoO1xyXG4gICAgdmFyIG5ld0hlaWdodCA9IHNlbGYubmV3SGVpZ2h0O1xyXG5cclxuICAgIGlmICghc2VsZi5jb250ZW50TGFzdFBvcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgbmV3T2Zmc2V0WCA9IHNlbGYuY29udGVudExhc3RQb3MubGVmdDtcclxuICAgIG5ld09mZnNldFkgPSBzZWxmLmNvbnRlbn
109RMYXN0UG9zLnRvcDtcclxuXHJcbiAgICByZXNldCA9IHtcclxuICAgICAgdG9wOiBuZXdPZmZzZXRZLFxyXG4gICAgICBsZWZ0OiBuZXdPZmZzZXRYLFxyXG4gICAgICB3aWR0aDogbmV3V2lkdGgsXHJcbiAgICAgIGhlaWdodDogbmV3SGVpZ2h0LFxyXG4gICAgICBzY2FsZVg6IDEsXHJcbiAgICAgIHNjYWxlWTogMVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBSZXNldCBzY2FsZXgvc2NhbGVZIHZhbHVlczsgdGhpcyBoZWxwcyBmb3IgcGVyZm9tYW5jZSBhbmQgZG9lcyBub3QgYnJlYWsgYW5pbWF0aW9uXHJcbiAgICAkLmZhbmN5Ym94LnNldFRyYW5zbGF0ZShzZWxmLiRjb250ZW50LCByZXNldCk7XHJcblxyXG4gICAgaWYgKG5ld1dpZHRoIDwgc2VsZi5jYW52YXNXaWR0aCAmJiBuZXdIZWlnaHQgPCBzZWxmLmNhbnZhc0hlaWdodCkge1xyXG4gICAgICBzZWxmLmluc3RhbmNlLnNjYWxlVG9GaXQoMTUwKTtcclxuICAgIH0gZWxzZSBpZiAobmV3V2lkdGggPiBjdXJyZW50LndpZHRoIHx8IG5ld0hlaWdodCA+IGN1cnJlbnQuaGVpZ2h0KSB7XHJcbiAgICAgIHNlbGYuaW5zdGFuY2Uuc2NhbGVUb0FjdHVhbChzZWxmLmNlbnRlclBvaW50U3RhcnRYLCBzZWxmLmNlbnRlclBvaW50U3RhcnRZLCAxNTApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbmV3UG9zID0gc2VsZi5saW1pdFBvc2l0aW9uKG5ld09mZnNldFgsIG5ld09mZnNldFksIG5ld1dpZHRoLCBuZXdIZWlnaHQpO1xyXG5cclxuICAgICAgJC5mYW5jeWJveC5hbmltYXRlKHNlbGYuJGNvbnRlbnQsIG5ld1BvcywgMTUwKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBHdWVzdHVyZXMucHJvdG90eXBlLm9uVGFwID0gZnVuY3Rpb24gKGUpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgIHZhciAkdGFyZ2V0ID0gJChlLnRhcmdldCk7XHJcblxyXG4gICAgdmFyIGluc3RhbmNlID0gc2VsZi5pbnN0YW5jZTtcclxuICAgIHZhciBjdXJyZW50ID0gaW5zdGFuY2UuY3VycmVudDtcclxuXHJcbiAgICB2YXIgZW5kUG9pbnRzID0gKGUgJiYgZ2V0UG9pbnRlclhZKGUpKSB8fCBzZWxmLnN0YXJ0UG9pbnRzO1xyXG5cclxuICAgIHZhciB0YXBYID0gZW5kUG9pbnRzWzBdID8gZW5kUG9pbnRzWzBdLnggLSAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpIC0gc2VsZi5zdGFnZVBvcy5sZWZ0IDogMDtcclxuICAgIHZhciB0YXBZID0gZW5kUG9pbnRzWzBdID8gZW5kUG9pbnRzWzBdLnkgLSAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgLSBzZWxmLnN0YWdlUG9zLnRvcCA6IDA7XHJcblxyXG4gICAgdmFyIHdoZXJlO1xyXG5cclxuICAgIHZhciBwcm9jZXNzID0gZnVuY3Rpb24gKHByZWZpeCkge1xyXG4gICAgICB2Y
109XIgYWN0aW9uID0gY3VycmVudC5vcHRzW3ByZWZpeF07XHJcblxyXG4gICAgICBpZiAoJC5pc0Z1bmN0aW9uKGFjdGlvbikpIHtcclxuICAgICAgICBhY3Rpb24gPSBhY3Rpb24uYXBwbHkoaW5zdGFuY2UsIFtjdXJyZW50LCBlXSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghYWN0aW9uKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzd2l0Y2ggKGFjdGlvbikge1xyXG4gICAgICAgIGNhc2UgXCJjbG9zZVwiOlxyXG4gICAgICAgICAgaW5zdGFuY2UuY2xvc2Uoc2VsZi5zdGFydEV2ZW50KTtcclxuXHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBcInRvZ2dsZUNvbnRyb2xzXCI6XHJcbiAgICAgICAgICBpbnN0YW5jZS50b2dnbGVDb250cm9scygpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFwibmV4dFwiOlxyXG4gICAgICAgICAgaW5zdGFuY2UubmV4dCgpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFwibmV4dE9yQ2xvc2VcIjpcclxuICAgICAgICAgIGlmIChpbnN0YW5jZS5ncm91cC5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLm5leHQoKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKHNlbGYuc3RhcnRFdmVudCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgXCJ6b29tXCI6XHJcbiAgICAgICAgICBpZiAoY3VycmVudC50eXBlID09IFwiaW1hZ2VcIiAmJiAoY3VycmVudC5pc0xvYWRlZCB8fCBjdXJyZW50LiRnaG9zdCkpIHtcclxuICAgICAgICAgICAgaWYgKGluc3RhbmNlLmNhblBhbigpKSB7XHJcbiAgICAgICAgICAgICAgaW5zdGFuY2Uuc2NhbGVUb0ZpdCgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmlzU2NhbGVkRG93bigpKSB7XHJcbiAgICAgICAgICAgICAgaW5zdGFuY2Uuc2NhbGVUb0FjdHVhbCh0YXBYLCB0YXBZKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ncm91cC5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2Uoc2VsZi5zdGFydEV2ZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIElnbm9yZSByaWdodCBjbGlja1xyXG4gICAgaWYgKGUub3JpZ2luYWxFdmVudCAmJiBlLm9yaWdpbmFsRXZlbnQuYnV0dG9uID09IDIpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFNraXAgaWYgY2xpY2tlZCBvbiB0aGUgc2Nyb2xsYmFyXHJcbiAgICBpZiAoISR0YXJnZXQuaXMoXCJpbWdcIikgJiYgdGFwWCA+ICR0YXJnZXRbMF0uY2xpZW50V2lkdGggKyAkdGFyZ2V0Lm9mZnNldCgpLmxlZnQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIHdoZXJlIGlzIGNsaWNrZWRcclxuICAgIGlmICgkdGFyZ2V0LmlzKFwiLmZhbmN5Ym94LWJnLC5mYW5jeWJveC1pbm5lciwuZmFuY3lib3gtb3V0ZXIsLmZhbmN5Ym94LWNvbnRhaW5lclwiKSkge1xyXG4gICAgICB3aGVyZSA9IFwiT3V0c2lkZVwiO1xyXG4gICAgfSBlbHNlIGlmICgkdGFyZ2V0LmlzKFwiLmZhbmN5Ym94LXNsaWRlXCIpKSB7XHJcbiAgICAgIHdoZXJlID0gXCJTbGlkZVwiO1xyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgaW5zdGFuY2UuY3VycmVudC4kY29udGVudCAmJlxyXG4gICAgICBpbnN0YW5jZS5jdXJyZW50LiRjb250ZW50XHJcbiAgICAgIC5maW5kKCR0YXJnZXQpXHJcbiAgICAgIC5hZGRCYWNrKClcclxuICAgICAgLmZpbHRlcigkdGFyZ2V0KS5sZW5ndGhcclxuICAgICkge1xyXG4gICAgICB3aGVyZSA9IFwiQ29udGVudFwiO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBkb3VibGUgdGFwXHJcbiAgICBpZiAoc2VsZi50YXBwZWQpIHtcclxuICAgICAgLy8gU3RvcCBwcmV2aW91c2x5IGNyZWF0ZWQgc2luZ2xlIHRhcFxyXG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi50YXBwZWQpO1xyXG4gICAgICBzZWxmLnRhcHBlZCA9IG51bGw7XHJcblxyXG4gICAgICAvLyBTa2lwIGlmIGRpc3RhbmNlIGJldHdlZW4gdGFwcyBpcyB0b28gYmlnXHJcbiAgICAgIGlmIChNYXRoLmFicyh0YXBYIC0gc2VsZi50YXBYKSA+IDUwIHx8IE1hdGguYWJzKHRhcFkgLSBzZWxmLnRhcFkpID4gNTApIHtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gT0ssIG5vdyB3ZSBhc3N1bWUgdGhhdCB0aGlzIGlzIGEgZG91YmxlLXRhcFxyXG4gICAgICBwcm9jZXNzKFwiZGJsY2xpY2tcIiArIHdoZXJlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFNpbmdsZSB0YXAgd2lsbCBiZSBwcm9jZXNzZWQgaWYgdXNlciBoYXMgbm90IGNsaWNrZWQgc2Vjb25kIHRpbWUgd2l0aGluIDMwMG1zXHJcbiAgICAgIC8vIG9yIHRoZXJlIGlzIG5vIG5lZWQgdG8gd2FpdCBmb3IgZG91YmxlLXRhcFxyXG4gICAgICBzZWxmLnRhcFggPSB0YXBYO1xyXG4gICAgICBzZWxmLnRhcFkgPSB0YXBZO1xyXG5cclxuICAgICAgaWYgKGN1cnJlbnQub3B0c1tcImRibGNsaWNrXCIgKyB3aGVyZV0gJiYgY3VycmVudC5vcHRzW1wiZGJsY2xpY2tcIiArIHdoZXJlXSAhPT0gY3VycmVudC5vcHRzW1wiY2xpY2tcIiArIHdoZXJlXSkge1xyXG4gICAgICAgIHNlbGYudGFwcGVkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBzZWxmLnRhcHBlZCA9IG51bGw7XHJcblxyXG4gICAgICAgICAgaWYgKCFpbnN0YW5jZS5pc0FuaW1hdGluZykge1xyXG4gICAgICAgICAgICBwcm9jZXNzKFwiY2xpY2tcIiArIHdoZXJlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LCA1MDApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHByb2Nlc3MoXCJjbGlja1wiICsgd2hlcmUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgJChkb2N1bWVudClcclxuICAgIC5vbihcIm9uQWN0aXZhdGUuZmJcIiwgZnVuY3Rpb24gKGUsIGluc3RhbmNlKSB7XHJcbiAgICAgIGlmIChpbnN0YW5jZSAmJiAhaW5zdGFuY2UuR3Vlc3R1cmVzKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuR3Vlc3R1cmVzID0gbmV3IEd1ZXN0dXJlcyhpbnN0YW5jZSk7XHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgICAub24oXCJiZWZvcmVDbG9zZS5mYlwiLCBmdW5jdGlvbiAoZSwgaW5zdGFuY2UpIHtcclxuICAgICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLkd1ZXN0dXJlcykge1xyXG4gICAgICAgIGluc3RhbmNlLkd1ZXN0dXJlcy5kZXN0cm95KCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG59KSh3aW5kb3csIGRvY3VtZW50LCBqUXVlcnkpO1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuLy9cclxuLy8gU2xpZGVTaG93XHJcbi8vIEVuYWJsZXMgc2xpZGVzaG93IGZ1bmN0aW9uYWxpdHlcclxuLy9cclxuLy8gRXhhbXBsZSBvZiB1c2FnZTpcclxuLy8gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpLlNsaWRlU2hvdy5zdGFydCgpXHJcbi8vXHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbihmdW5jdGlvbiAoZG9jdW1lbnQsICQpIHtcclxuICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgJC5leHRlbmQodHJ1ZSwgJC5mYW5jeWJveC5kZWZhdWx0cywge1xyXG4gICAgYnRuVHBsOiB7XHJcbiAgICAgIHNsaWRlU2hvdzogJzxidXR0b24gZGF0YS1mYW5jeWJveC1wbGF5IGNsYXNzPVwiZmFuY3lib3gtYnV0dG9uIGZhbmN5Ym94LWJ1dHRvbi0tcGxheVwiIHRpdGxlPVwie3tQTEFZX1NUQVJUfX1cIj4nICtcclxuICAgICAgICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPjxwYXRoIGQ9XCJNNi41IDUuNHYxMy4ybDExLTYuNnpcIi8+PC9zdmc+JyArXHJcbiAgICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj48cGF0aCBkPVwiTTguMzMgNS43NWgyLjJ2MTIuNWgtMi4yVjUuNzV6bTUuMTUgMGgyLjJ2MTIuNWgtMi4yVjUuNzV6XCIvPjwvc3ZnPicgK1xyXG4gICAgICAgIFwiPC9idXR0b24+XCJcclxuICAgIH0sXHJcbiAgICBzbGlkZVNob3c6IHtcclxuICAgICAgYXV0b1N0YXJ0Oi
109BmYWxzZSxcclxuICAgICAgc3BlZWQ6IDMwMDAsXHJcbiAgICAgIHByb2dyZXNzOiB0cnVlXHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIHZhciBTbGlkZVNob3cgPSBmdW5jdGlvbiAoaW5zdGFuY2UpIHtcclxuICAgIHRoaXMuaW5zdGFuY2UgPSBpbnN0YW5jZTtcclxuICAgIHRoaXMuaW5pdCgpO1xyXG4gIH07XHJcblxyXG4gICQuZXh0ZW5kKFNsaWRlU2hvdy5wcm90b3R5cGUsIHtcclxuICAgIHRpbWVyOiBudWxsLFxyXG4gICAgaXNBY3RpdmU6IGZhbHNlLFxyXG4gICAgJGJ1dHRvbjogbnVsbCxcclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBpbnN0YW5jZSA9IHNlbGYuaW5zdGFuY2UsXHJcbiAgICAgICAgb3B0cyA9IGluc3RhbmNlLmdyb3VwW2luc3RhbmNlLmN1cnJJbmRleF0ub3B0cy5zbGlkZVNob3c7XHJcblxyXG4gICAgICBzZWxmLiRidXR0b24gPSBpbnN0YW5jZS4kcmVmcy50b29sYmFyLmZpbmQoXCJbZGF0YS1mYW5jeWJveC1wbGF5XVwiKS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBzZWxmLnRvZ2dsZSgpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmIChpbnN0YW5jZS5ncm91cC5sZW5ndGggPCAyIHx8ICFvcHRzKSB7XHJcbiAgICAgICAgc2VsZi4kYnV0dG9uLmhpZGUoKTtcclxuICAgICAgfSBlbHNlIGlmIChvcHRzLnByb2dyZXNzKSB7XHJcbiAgICAgICAgc2VsZi4kcHJvZ3Jlc3MgPSAkKCc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtcHJvZ3Jlc3NcIj48L2Rpdj4nKS5hcHBlbmRUbyhpbnN0YW5jZS4kcmVmcy5pbm5lcik7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbiAoZm9yY2UpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGluc3RhbmNlID0gc2VsZi5pbnN0YW5jZSxcclxuICAgICAgICBjdXJyZW50ID0gaW5zdGFuY2UuY3VycmVudDtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHJlYWNoZWQgbGFzdCBlbGVtZW50XHJcbiAgICAgIGlmIChjdXJyZW50ICYmIChmb3JjZSA9PT0gdHJ1ZSB8fCBjdXJyZW50Lm9wdHMubG9vcCB8fCBpbnN0YW5jZS5jdXJySW5kZXggPCBpbnN0YW5jZS5ncm91cC5sZW5ndGggLSAxKSkge1xyXG4gICAgICAgIGlmIChzZWxmLmlzQWN0aXZlICYmIGN1cnJlbnQuY29udGVudFR5cGUgIT09IFwidmlkZW9cIikge1xyXG4gICAgICAgICAgaWYgKHNlbGYuJHByb2dyZXNzKSB7XHJcbiAgICAgICAgICAgICQuZmFuY3lib3guYW5pbWF0ZShzZWxmLiRwcm9ncmVzcy5zaG93KCksIHtcclxuICAgICAgICAgICAgICBzY2FsZVg6IDFcclxuICAgICAgICAgICAgfSwgY3VycmVudC5vcHRzLnNsaWRlU2hvdy5zcGVlZCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgc2VsZi50aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIWluc3RhbmNlLmN1cnJlbnQub3B0cy5sb29wICYmIGluc3RhbmNlLmN1cnJlbnQuaW5kZXggPT0gaW5zdGFuY2UuZ3JvdXAubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgIGluc3RhbmNlLmp1bXBUbygwKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBpbnN0YW5jZS5uZXh0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sIGN1cnJlbnQub3B0cy5zbGlkZVNob3cuc3BlZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzZWxmLnN0b3AoKTtcclxuICAgICAgICBpbnN0YW5jZS5pZGxlU2Vjb25kc0NvdW50ZXIgPSAwO1xyXG4gICAgICAgIGluc3RhbmNlLnNob3dDb250cm9scygpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGNsZWFyOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVyKTtcclxuXHJcbiAgICAgIHNlbGYudGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHNlbGYuJHByb2dyZXNzKSB7XHJcbiAgICAgICAgc2VsZi4kcHJvZ3Jlc3MucmVtb3ZlQXR0cihcInN0eWxlXCIpLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzdGFydDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2Y
109XIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuaW5zdGFuY2UuY3VycmVudDtcclxuXHJcbiAgICAgIGlmIChjdXJyZW50KSB7XHJcbiAgICAgICAgc2VsZi4kYnV0dG9uXHJcbiAgICAgICAgICAuYXR0cihcInRpdGxlXCIsIChjdXJyZW50Lm9wdHMuaTE4bltjdXJyZW50Lm9wdHMubGFuZ10gfHwgY3VycmVudC5vcHRzLmkxOG4uZW4pLlBMQVlfU1RPUClcclxuICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImZhbmN5Ym94LWJ1dHRvbi0tcGxheVwiKVxyXG4gICAgICAgICAgLmFkZENsYXNzKFwiZmFuY3lib3gtYnV0dG9uLS1wYXVzZVwiKTtcclxuXHJcbiAgICAgICAgc2VsZi5pc0FjdGl2ZSA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmIChjdXJyZW50LmlzQ29tcGxldGUpIHtcclxuICAgICAgICAgIHNlbGYuc2V0KHRydWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2VsZi5pbnN0YW5jZS50cmlnZ2VyKFwib25TbGlkZVNob3dDaGFuZ2VcIiwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc3RvcDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgY3VycmVudCA9IHNlbGYuaW5zdGFuY2UuY3VycmVudDtcclxuXHJcbiAgICAgIHNlbGYuY2xlYXIoKTtcclxuXHJcbiAgICAgIHNlbGYuJGJ1dHRvblxyXG4gICAgICAgIC5hdHRyKFwidGl0bGVcIiwgKGN1cnJlbnQub3B0cy5pMThuW2N1cnJlbnQub3B0cy5sYW5nXSB8fCBjdXJyZW50Lm9wdHMuaTE4bi5lbikuUExBWV9TVEFSVClcclxuICAgICAgICAucmVtb3ZlQ2xhc3MoXCJmYW5jeWJveC1idXR0b24tLXBhdXNlXCIpXHJcbiAgICAgICAgLmFkZENsYXNzKFwiZmFuY3lib3gtYnV0dG9uLS1wbGF5XCIpO1xyXG5cclxuICAgICAgc2VsZi5pc0FjdGl2ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgc2VsZi5pbnN0YW5jZS50cmlnZ2VyKFwib25TbGlkZVNob3dDaGFuZ2VcIiwgZmFsc2UpO1xyXG5cclxuICAgICAgaWYgKHNlbGYuJHByb2dyZXNzKSB7XHJcbiAgICAgICAgc2VsZi4kcHJvZ3Jlc3MucmVtb3ZlQXR0cihcInN0eWxlXCIpLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICB0b2dnbGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNBY3RpdmUpIHtcclxuICAgICAgICBzZWxmLnN0b3AoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzZWxmLnN0YXJ0KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgJChkb2N1bWVudCkub24oe1xyXG4gICAgXCJvbkluaXQuZmJcIjogZnVuY3Rpb24gKGUsIGluc3RhbmNlKSB7XHJcbiAgICAgIGlmIChpbnN0YW5jZSAmJiAhaW5zdGFuY2UuU2xpZGVTaG93KSB7XHJcbiAgICAgICAgaW5zdGFuY2UuU2xpZGVTaG93ID0gbmV3IFNsaWRlU2hvdyhpbnN0YW5jZSk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgXCJiZWZvcmVTaG93LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCwgZmlyc3RSdW4pIHtcclxuICAgICAgdmFyIFNsaWRlU2hvdyA9IGluc3RhbmNlICYmIGluc3RhbmNlLlNsaWRlU2hvdztcclxuXHJcbiAgICAgIGlmIChmaXJzdFJ1bikge1xyXG4gICAgICAgIGlmIChTbGlkZVNob3cgJiYgY3VycmVudC5vcHRzLnNsaWRlU2hvdy5hdXRvU3RhcnQpIHtcclxuICAgICAgICAgIFNsaWRlU2hvdy5zdGFydCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmIChTbGlkZVNob3cgJiYgU2xpZGVTaG93LmlzQWN0aXZlKSB7XHJcbiAgICAgICAgU2xpZGVTaG93LmNsZWFyKCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgXCJhZnRlclNob3cuZmJcIjogZnVuY3Rpb24gKGUsIGluc3RhbmNlLCBjdXJyZW50KSB7XHJcbiAgICAgIHZhciBTbGlkZVNob3cgPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5TbGlkZVNob3c7XHJcblxyXG4gICAgICBpZiAoU2xpZGVTaG93ICYmIFNsaWRlU2hvdy5pc0FjdGl2ZSkge1xyXG4gICAgICAgIFNsaWRlU2hvdy5zZXQoKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBcImFmdGVyS2V5ZG93bi5mYlwiOiBmdW5jdGlvbiAoZSwgaW5zdGFuY2UsIGN1cnJlbnQsIGtleXByZXNzLCBrZXljb2RlKSB7XHJcbiAgICAgIHZhciBTbGlkZVNob3cgPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5TbGlkZVNob3c7XHJcblxyXG4gICAgICAvLyBcIlBcIiBvciBTcGFjZWJhclxyXG4gICAgICBpZiAoU2xpZGVTaG93ICYmIGN1cnJlbnQub3B0cy5zbGlkZVNob3cgJiYgKGtleWNvZGUgPT09IDgwIHx8IGtleWNvZGUgPT09IDMyKSAmJiAhJChkb2N1bWVudC5hY3RpdmVFbGVtZW50KS5pcyhcImJ1dHRvbixhLGlucHV0XCIpKSB7XHJcbiAgICAgICAga2V5cHJlc3MucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgU2xpZGVTaG93LnRvZ2dsZSgpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIFwiYmVmb3JlQ2xvc2UuZmIgb25EZWFjdGl2YXRlLmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSkge1xyXG4gICAgICB2Y
109XIgU2xpZGVTaG93ID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UuU2xpZGVTaG93O1xyXG5cclxuICAgICAgaWYgKFNsaWRlU2hvdykge1xyXG4gICAgICAgIFNsaWRlU2hvdy5zdG9wKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gUGFnZSBWaXNpYmlsaXR5IEFQSSB0byBwYXVzZSBzbGlkZXNob3cgd2hlbiB3aW5kb3cgaXMgbm90IGFjdGl2ZVxyXG4gICQoZG9jdW1lbnQpLm9uKFwidmlzaWJpbGl0eWNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgaW5zdGFuY2UgPSAkLmZhbmN5Ym94LmdldEluc3RhbmNlKCksXHJcbiAgICAgIFNsaWRlU2hvdyA9IGluc3RhbmNlICYmIGluc3RhbmNlLlNsaWRlU2hvdztcclxuXHJcbiAgICBpZiAoU2xpZGVTaG93ICYmIFNsaWRlU2hvdy5pc0FjdGl2ZSkge1xyXG4gICAgICBpZiAoZG9jdW1lbnQuaGlkZGVuKSB7XHJcbiAgICAgICAgU2xpZGVTaG93LmNsZWFyKCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgU2xpZGVTaG93LnNldCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcbn0pKGRvY3VtZW50LCBqUXVlcnkpO1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuLy9cclxuLy8gRnVsbFNjcmVlblxyXG4vLyBBZGRzIGZ1bGxzY3JlZW4gZnVuY3Rpb25hbGl0eVxyXG4vL1xyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4oZnVuY3Rpb24gKGRvY3VtZW50LCAkKSB7XHJcbiAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gIC8vIENvbGxlY3Rpb24gb2YgbWV0aG9kcyBzdXBwb3J0ZWQgYnkgdXNlciBicm93c2VyXHJcbiAgdmFyIGZuID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBmbk1hcCA9IFtcclxuICAgICAgW1wicmVxdWVzdEZ1bGxzY3JlZW5cIiwgXCJleGl0RnVsbHNjcmVlblwiLCBcImZ1bGxzY3JlZW5FbGVtZW50XCIsIFwiZnVsbHNjcmVlbkVuYWJsZWRcIiwgXCJmdWxsc2NyZWVuY2hhbmdlXCIsIFwiZnVsbHNjcmVlbmVycm9yXCJdLFxyXG4gICAgICAvLyBuZXcgV2ViS2l0XHJcbiAgICAgIFtcclxuICAgICAgICBcIndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuXCIsXHJcbiAgICAgICAgXCJ3ZWJraXRFeGl0RnVsbHNjcmVlblwiLFxyXG4gICAgICAgIFwid2Via2l0RnVsbHNjcmVlbkVsZW1lbnRcIixcclxuICAgICAgICBcIndlYmtpdEZ1bGxzY3JlZW5FbmFibGVkXCIsXHJcbiAgICAgICAgXCJ3ZWJraXRmdWxsc2NyZWVuY2hhbmdlXCIsXHJcbiAgICAgICAgXCJ3ZWJraXRmdWxsc2NyZWVuZXJyb3JcIlxyXG4gICAgICBdLFxyXG4gICAgICAvLyBvbGQgV2ViS2l0IChTYWZhcmkgNS4xKVxyXG4gICAgICBbXHJcbiAgICAgICAgXCJ3ZWJraXRSZXF1ZXN0RnVsbFNjcmVlblwiLFxyXG4gICAgICAgIFwid2Via2l0Q2FuY2VsRnVsbFNjcmVlblwiLFxyXG4gICAgICAgIFwid2Via2l0Q3VycmVudEZ1bGxTY3JlZW5FbGVtZW50XCIsXHJcbiAgICAgICAgXCJ3ZWJraXRDYW5jZWxGdWxsU2NyZWVuXCIsXHJcbiAgICAgICAgXCJ3ZWJraXRmdWxsc2NyZWVuY2hhbmdlXCIsXHJcbiAgICAgICAgXCJ3ZWJraXRmdWxsc2NyZWVuZXJyb3JcIlxyXG4gICAgICBdLFxyXG4gICAgICBbXHJcbiAgICAgICAgXCJtb3pSZXF1ZXN0RnVsbFNjcmVlblwiLFxyXG4gICAgICAgIFwibW96Q2FuY2VsRnVsbFNjcmVlblwiLFxyXG4gICAgICAgIFwibW96RnVsbFNjcmVlbkVsZW1lbnRcIixcclxuICAgICAgICBcIm1vekZ1bGxTY3JlZW5FbmFibGVkXCIsXHJcbiAgICAgICAgXCJtb3pmdWxsc2NyZWVuY2hhbmdlXCIsXHJcbiAgICAgICAgXCJtb3pmdWxsc2NyZWVuZXJyb3JcIlxyXG4gICAgICBdLFxyXG4gICAgICBbXCJtc1JlcXVlc3RGdWxsc2NyZWVuXCIsIFwibXNFeGl0RnVsbHNjcmVlblwiLCBcIm1zRnVsbHNjcmVlbkVsZW1lbnRcIiwgXCJtc0Z1bGxzY3JlZW5FbmFibGVkXCIsIFwiTVNGdWxsc2NyZWVuQ2hhbmdlXCIsIFwiTVNGdWxsc2NyZWVuRXJyb3JcIl1cclxuICAgIF07XHJcblxyXG4gICAgdmFyIHJldCA9IHt9O1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZm5NYXAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIHZhbCA9IGZuTWFwW2ldO1xyXG5cclxuICAgICAgaWYgKHZhbCAmJiB2YWxbMV0gaW4gZG9jdW1lbnQpIHtcclxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgcmV0W2ZuTWFwWzBdW2pdXSA9IHZhbFtqXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSkoKTtcclxuXHJcbiAgaWYgKGZuKSB7XHJcbiAgICB2YXIgRnVsbFNjcmVlbiA9IHtcclxuICAgICAgcmVxdWVzdDogZnVuY3Rpb24gKGVsZW0pIHtcclxuICAgICAgICBlbGVtID0gZWxlbSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG4gICAgICAgIGVsZW1bZm4ucmVxdWVzdEZ1bGxzY3JlZW5dKGVsZW0uQUxMT1dfS0VZQk9BUkRfSU5QVVQpO1xyXG4gICAgICB9LFxyXG4gICAgICBleGl0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZG9jdW1lbnRbZm4uZXhpdEZ1bGxzY3JlZW5dKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIHRvZ2dsZTogZnVuY3Rpb24gKGVsZW0pIHtcclxuICAgICAgICBlbGVtID0gZWxlbSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzRnVsbHNjcmVlbigpKSB7XHJcbiAgICAgICAgICB0aGlzLmV4aXQoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5yZXF1ZXN0KGVsZW0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgaXNGdWxsc2NyZWVuOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4oZG9jdW1lbnRbZm4uZnVsbHNjcmVlbkVsZW1lbnRdKTtcclxuICAgICAgfSxcclxuICAgICAgZW5hYmxlZDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgI
109HJldHVybiBCb29sZWFuKGRvY3VtZW50W2ZuLmZ1bGxzY3JlZW5FbmFibGVkXSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgJC5leHRlbmQodHJ1ZSwgJC5mYW5jeWJveC5kZWZhdWx0cywge1xyXG4gICAgICBidG5UcGw6IHtcclxuICAgICAgICBmdWxsU2NyZWVuOiAnPGJ1dHRvbiBkYXRhLWZhbmN5Ym94LWZ1bGxzY3JlZW4gY2xhc3M9XCJmYW5jeWJveC1idXR0b24gZmFuY3lib3gtYnV0dG9uLS1mc2VudGVyXCIgdGl0bGU9XCJ7e0ZVTExfU0NSRUVOfX1cIj4nICtcclxuICAgICAgICAgICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk03IDE0SDV2NWg1di0ySDd2LTN6bS0yLTRoMlY3aDNWNUg1djV6bTEyIDdoLTN2Mmg1di01aC0ydjN6TTE0IDV2MmgzdjNoMlY1aC01elwiLz48L3N2Zz4nICtcclxuICAgICAgICAgICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PHBhdGggZD1cIk01IDE2aDN2M2gydi01SDV6bTMtOEg1djJoNVY1SDh6bTYgMTFoMnYtM2gzdi0yaC01em0yLTExVjVoLTJ2NWg1Vjh6XCIvPjwvc3ZnPicgK1xyXG4gICAgICAgICAgXCI8L2J1dHRvbj5cIlxyXG4gICAgICB9LFxyXG4gICAgICBmdWxsU2NyZWVuOiB7XHJcbiAgICAgICAgYXV0b1N0YXJ0OiBmYWxzZVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKGRvY3VtZW50KS5vbihmbi5mdWxsc2NyZWVuY2hhbmdlLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBpc0Z1bGxzY3JlZW4gPSBGdWxsU2NyZWVuLmlzRnVsbHNjcmVlbigpLFxyXG4gICAgICAgIGluc3RhbmNlID0gJC5mYW5jeWJveC5nZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgLy8gSWYgaW1hZ2UgaXMgem9vbWluZywgdGhlbiBmb3JjZSB0byBzdG9wIGFuZCByZXBvc2l0aW9uIHByb3Blcmx5XHJcbiAgICAgICAgaWYgKGluc3RhbmNlLmN1cnJlbnQgJiYgaW5zdGFuY2UuY3VycmVudC50eXBlID09PSBcImltYWdlXCIgJiYgaW5zdGFuY2UuaXNBbmltYXRpbmcpIHtcclxuICAgICAgICAgIGluc3RhbmNlLmlzQW5pbWF0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgaW5zdGFuY2UudXBkYXRlKHRydWUsIHRydWUsIDApO1xyXG5cclxuICAgICAgICAgIGlmICghaW5zdGFuY2UuaXNDb21wbGV0ZSkge1xyXG4gICAgICAgICAgICBpbnN0YW5jZS5jb21wbGV0ZSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW5zdGFuY2UudHJpZ2dlcihcIm9uRnVsbHNjcmVlbkNoYW5nZVwiLCBpc0Z1bGxzY3JlZW4pO1xyXG5cclxuICAgICAgICBpbnN0YW5jZS4kcmVmcy5jb250YWluZXIudG9nZ2xlQ2xhc3MoXCJmYW5jeWJveC1pcy1mdWxsc2NyZWVuXCIsIGlzRnVsbHNjcmVlbik7XHJcblxyXG4gICAgICAgIGluc3RhbmNlLiRyZWZzLnRvb2xiYXJcclxuICAgICAgICAgIC5maW5kKFwiW2RhdGEtZmFuY3lib3gtZnVsbHNjcmVlbl1cIilcclxuICAgICAgICAgIC50b2dnbGVDbGFzcyhcImZhbmN5Ym94LWJ1dHRvbi0tZnNlbnRlclwiLCAhaXNGdWxsc2NyZWVuKVxyXG4gICAgICAgICAgLnRvZ2dsZUNsYXNzKFwiZmFuY3lib3gtYnV0dG9uLS1mc2V4aXRcIiwgaXNGdWxsc2NyZWVuKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAkKGRvY3VtZW50KS5vbih7XHJcbiAgICBcIm9uSW5pdC5mYlwiOiBmdW5jdGlvbiAoZSwgaW5zdGFuY2UpIHtcclxuICAgICAgdmFyICRjb250YWluZXI7XHJcblxyXG4gICAgICBpZiAoIWZuKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuJHJlZnMudG9vbGJhci5maW5kKFwiW2RhdGEtZmFuY3lib3gtZnVsbHNjcmVlbl1cIikucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLmdyb3VwW2luc3RhbmNlLmN1cnJJbmRleF0ub3B0cy5mdWxsU2NyZWVuKSB7XHJcbiAgICAgICAgJGNvbnRhaW5lciA9IGluc3RhbmNlLiRyZWZzLmNvbnRhaW5lcjtcclxuXHJcbiAgICAgICAgJGNvbnRhaW5lci5vbihcImNsaWNrLmZiLWZ1bGxzY3JlZW5cIiwgXCJbZGF0YS1mYW5jeWJveC1mdWxsc2NyZWVuXVwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBGdWxsU2NyZWVuLnRvZ2dsZSgpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoaW5zdGFuY2Uub3B0cy5mdWxsU2NyZWVuICYmIGluc3RhbmNlLm9wdHMuZnVsbFNjcmVlbi5hdXRvU3RhcnQgPT09IHRydWUpIHtcclxuICAgICAgICAgIEZ1bGxTY3JlZW4ucmVxdWVzdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRXhwb3NlIEFQSVxyXG4gICAgICAgIGluc3RhbmNlLkZ1bGxTY3JlZW4gPSBGdWxsU2NyZWVuO1xyXG4gICAgICB9IGVsc2UgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuJHJlZnMudG9vbGJhci5maW5kKFwiW2RhdGEtZmFuY3lib3gtZnVsbHNjcmVlbl1cIikuaGlkZSgpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIFwiYWZ0ZXJLZXlkb3duLmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCwga2V5cHJlc3MsIGtleWNvZGUpIHtcclxuICAgICAgLy8gXCJGXCJcclxuICAgICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLkZ1bGxTY3JlZW4gJiYga2V5Y29kZSA9PT0gNzApIHtcclxuICAgICAgICBrZXlwcmVzcy5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICBpbnN0YW5jZS5GdWxsU2NyZWVuLnRvZ2dsZSgpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIFwiYmVmb3JlQ2xvc2UuZmJcIjogZnVuY3Rpb24gKGUsIGluc3RhbmNlKSB7XHJcbiAgICAgIGlmIChpbnN0YW5jZSAmJiBpbnN0YW5jZS5GdWxsU2NyZWVuICYmIGluc3RhbmNlLiRyZWZzLmNvbnRhaW5lci5oYXNDbGFzcyhcImZhbmN5Ym94LWlzLWZ1bGxzY3JlZW5cIikpIHtcclxuICAgICAgICBGdWxsU2NyZWVuLmV4aXQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG59KShkb2N1bWVudCwgalF1ZXJ5KTtcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbi8vXHJcbi8vIFRodW1ic1xyXG4vLyBEaXNwbGF5cyB0aHVtYm5haWxzIGluIGEgZ3JpZFxyXG4vL1xyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4oZnVuY3Rpb24gKGRvY3VtZW50LCAkKSB7XHJcbiAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gIHZhciBDTEFTUyA9IFwiZmFuY3lib3gtdGh1bWJzXCIsXHJcbiAgICBDTEFTU19BQ1RJVkUgPSBDTEFTUyArIFwiLWFjdGl2ZVwiO1xyXG5cclxuICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIGRlZmF1bHQgdmFsdWVzXHJcbiAgJC5mYW5jeWJveC5kZWZhdWx0cyA9ICQuZXh0ZW5kKFxyXG4gICAgdHJ1ZSwge1xyXG4gICAgICBidG5UcGw6IHtcclxuICAgICAgICB0aHVtYnM6ICc8YnV0dG9uIGRhdGEtZmFuY3lib3gtdGh1bWJzIGNsYXNzPVwiZmFuY3lib3gtYnV0dG9uIGZhbmN5Ym94LWJ1dHRvbi0tdGh1bWJzXCIgdGl0bGU9XCJ7e1RIVU1CU319XCI+JyArXHJcbiAgICAgICAgICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPjxwYXRoIGQ9XCJNMTQuNTkgMTQuNTloMy43NnYzLjc2aC0zLjc2di0zLjc2em0tNC40NyAwaDMuNzZ2My43NmgtMy43NnYtMy43NnptLTQuNDcgMGgzLjc2djMuNzZINS42NXYtMy43NnptOC45NC00LjQ3aDMuNzZ2My43NmgtMy43NnYtMy43NnptLTQuNDcgMGgzLjc2djMuNzZoLTMuNzZ2LTMuNzZ6bS00LjQ3IDBoMy43NnYzLjc2SDUuNjV2LTMuNzZ6bTguOTQtNC40N2gzLjc2djMuNzZoLTMuNzZWNS42NXptLTQuNDcgMGgzLjc2djMuNzZoLTMuNzZWNS42NXptLTQuNDcgMGgzLjc2djMuNzZINS42NVY1LjY1elwiLz48L3N2Zz4nICtcclxuICAgICAgICAgIFwiPC9idXR0b24+XCJcclxuICAgICAgfSxcclxuICAgICAgdGh1bWJzOiB7XHJcbiAgICAgICAgYXV0b1N0YXJ0Oi
109BmYWxzZSwgLy8gRGlzcGxheSB0aHVtYm5haWxzIG9uIG9wZW5pbmdcclxuICAgICAgICBoaWRlT25DbG9zZTogdHJ1ZSwgLy8gSGlkZSB0aHVtYm5haWwgZ3JpZCB3aGVuIGNsb3NpbmcgYW5pbWF0aW9uIHN0YXJ0c1xyXG4gICAgICAgIHBhcmVudEVsOiBcIi5mYW5jeWJveC1jb250YWluZXJcIiwgLy8gQ29udGFpbmVyIGlzIGluamVjdGVkIGludG8gdGhpcyBlbGVtZW50XHJcbiAgICAgICAgYXhpczogXCJ5XCIgLy8gVmVydGljYWwgKHkpIG9yIGhvcml6b250YWwgKHgpIHNjcm9sbGluZ1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgJC5mYW5jeWJveC5kZWZhdWx0c1xyXG4gICk7XHJcblxyXG4gIHZhciBGYW5jeVRodW1icyA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgdGhpcy5pbml0KGluc3RhbmNlKTtcclxuICB9O1xyXG5cclxuICAkLmV4dGVuZChGYW5jeVRodW1icy5wcm90b3R5cGUsIHtcclxuICAgICRidXR0b246IG51bGwsXHJcbiAgICAkZ3JpZDogbnVsbCxcclxuICAgICRsaXN0OiBudWxsLFxyXG4gICAgaXNWaXNpYmxlOiBmYWxzZSxcclxuICAgIGlzQWN0aXZlOiBmYWxzZSxcclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbiAoaW5zdGFuY2UpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGdyb3VwID0gaW5zdGFuY2UuZ3JvdXAsXHJcbiAgICAgICAgZW5hYmxlZCA9IDA7XHJcblxyXG4gICAgICBzZWxmLmluc3RhbmNlID0gaW5zdGFuY2U7XHJcbiAgICAgIHNlbGYub3B0cyA9IGdyb3VwW2luc3RhbmNlLmN1cnJJbmRleF0ub3B0cy50aHVtYnM7XHJcblxyXG4gICAgICBpbnN0YW5jZS5UaHVtYnMgPSBzZWxmO1xyXG5cclxuICAgICAgc2VsZi4kYnV0dG9uID0gaW5zdGFuY2UuJHJlZnMudG9vbGJhci5maW5kKFwiW2RhdGEtZmFuY3lib3gtdGh1bWJzXVwiKTtcclxuXHJcbiAgICAgIC8vIEVuYWJsZSB0aHVtYnMgaWYgYXQgbGVhc3QgdHdvIGdyb3VwIGl0ZW1zIGhhdmUgdGh1bWJuYWlsc1xyXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZ3JvdXAubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICBpZiAoZ3JvdXBbaV0udGh1bWIpIHtcclxuICAgICAgICAgIGVuYWJsZWQrKztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChlbmFibGVkID4gMSkge1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoZW5hYmxlZCA+IDEgJiYgISFzZWxmLm9wdHMpIHtcclxuICAgICAgICBzZWxmLiRidXR0b24ucmVtb3ZlQXR0cihcInN0eWxlXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi50b2dnbGUoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2VsZi5pc0FjdGl2ZSA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc2VsZi4kYnV0dG9uLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBjcmVhdGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgIGluc3RhbmNlID0gc2VsZi5pbnN0YW5jZSxcclxuICAgICAgICBwYXJlbnRFbCA9IHNlbGYub3B0cy5wYXJlbnRFbCxcclxuICAgICAgICBsaXN0ID0gW10sXHJcbiAgICAgICAgc3JjO1xyXG5cclxuICAgICAgaWYgKCFzZWxmLiRncmlkKSB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIG1haW4gZWxlbWVudFxyXG4gICAgICAgIHNlbGYuJGdyaWQgPSAkKCc8ZGl2IGNsYXNzPVwiJyArIENMQVNTICsgXCIgXCIgKyBDTEFTUyArIFwiLVwiICsgc2VsZi5vcHRzLmF4aXMgKyAnXCI+PC9kaXY+JykuYXBwZW5kVG8oXHJcbiAgICAgICAgICBpbnN0YW5jZS4kcmVmcy5jb250YWluZXJcclxuICAgICAgICAgIC5maW5kKHBhcmVudEVsKVxyXG4gICAgICAgICAgLmFkZEJhY2soKVxyXG4gICAgICAgICAgLmZpbHRlcihwYXJlbnRFbClcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBBZGQgXCJjbGlja1wiIGV2ZW50IHRoYXQgcGVyZm9ybXMgZ2FsbGVyeSBuYXZpZ2F0aW9uXHJcbiAgICAgICAgc2VsZi4kZ3JpZC5vbihcImNsaWNrXCIsIFwiYVwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBpbnN0YW5jZS5qdW1wVG8oJCh0aGlzKS5hdHRyKFwiZGF0YS1pbmRleFwiKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEJ1aWxkIHRoZSBsaXN0XHJcbiAgICAgIGlmICghc2VsZi4kbGlzdCkge1xyXG4gICAgICAgIHNlbGYuJGxpc3QgPSAkKCc8ZGl2IGNsYXNzPVwiJyArIENMQVNTICsgJ19fbGlzdFwiPicpLmFwcGVuZFRvKHNlbGYuJGdyaWQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkLmVhY2goaW5zdGFuY2UuZ3JvdXAsIGZ1bmN0aW9uIChpLCBpdGVtKSB7XHJcbiAgICAgICAgc3JjID0gaXRlbS50aHVtYjtcclxuXHJcbiAgICAgICAgaWYgKCFzcmMgJiYgaXRlbS50eXBlID09PSBcImltYWdlXCIpIHtcclxuICAgICAgICAgIHNyYyA9IGl0ZW0uc3JjO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGlzdC5wdXNoKFxyXG4gICAgICAgICAgJzxhIGhyZWY9XCJqYXZhc2NyaXB0OjtcIiB0YWJpbmRleD1cIjBcIiBkYXRhLWluZGV4PVwiJyArXHJcbiAgICAgICAgICBpICtcclxuICAgICAgICAgICdcIicgK1xyXG4gICAgICAgICAgKHNyYyAmJiBzcmMubGVuZ3RoID8gJyBzdHlsZT1cImJhY2tncm91bmQtaW1hZ2U6dXJsKCcgKyBzcmMgKyAnKVwiJyA6ICdjbGFzcz1cImZhbmN5Ym94LXRodW1icy1taXNzaW5nXCInKSArXHJcbiAgICAgICAgICBcIj48L2E+XCJcclxuICAgICAgICApO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHNlbGYuJGxpc3RbMF0uaW5uZXJIVE1MID0gbGlzdC5qb2luKFwiXCIpO1xyXG5cclxuICAgICAgaWYgKHNlbGYub3B0cy5heGlzID09PSBcInhcIikge1xyXG4gICAgICAgIC8vIFNldCBmaXhlZCB3aWR0aCBmb3IgbGlzdCBlbGVtZW50IHRvIGVuYWJsZSBob3Jpem9udGFsIHNjcm9sbGluZ1xyXG4gICAgICAgIHNlbGYuJGxpc3Qud2lkdGgoXHJcbiAgICAgICAgICBwYXJzZUludChzZWxmLiRncmlkLmNzcyhcInBhZGRpbmctcmlnaHRcIiksIDEwKSArXHJcbiAgICAgICAgICBpbnN0YW5jZS5ncm91cC5sZW5ndGggKlxyXG4gICAgICAgICAgc2VsZi4kbGlzdFxyXG4gICAgICAgICAgLmNoaWxkcmVuKClcclxuICAgICAgICAgIC5lcSgwKVxyXG4gICAgICAgICAgLm91dGVyV2lkdGgodHJ1ZSlcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGZvY3VzOiBmdW5jdGlvbiAoZHVyYXRpb24pIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICRsaXN0ID0gc2VsZi4kbGlzdCxcclxuICAgICAgICAkZ3JpZCA9IHNlbGYuJGdyaWQsXHJcbiAgICAgICAgdGh1bWIsXHJcbiAgICAgICAgdGh1bWJQb3M7XHJcblxyXG4gICAgICBpZiAoIXNlbGYuaW5zdGFuY2UuY3VycmVudCkge1xyXG4gICAgICAgI
109HJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGh1bWIgPSAkbGlzdFxyXG4gICAgICAgIC5jaGlsZHJlbigpXHJcbiAgICAgICAgLnJlbW92ZUNsYXNzKENMQVNTX0FDVElWRSlcclxuICAgICAgICAuZmlsdGVyKCdbZGF0YS1pbmRleD1cIicgKyBzZWxmLmluc3RhbmNlLmN1cnJlbnQuaW5kZXggKyAnXCJdJylcclxuICAgICAgICAuYWRkQ2xhc3MoQ0xBU1NfQUNUSVZFKTtcclxuXHJcbiAgICAgIHRodW1iUG9zID0gdGh1bWIucG9zaXRpb24oKTtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIG5lZWQgdG8gc2Nyb2xsIHRvIG1ha2UgY3VycmVudCB0aHVtYiB2aXNpYmxlXHJcbiAgICAgIGlmIChzZWxmLm9wdHMuYXhpcyA9PT0gXCJ5XCIgJiYgKHRodW1iUG9zLnRvcCA8IDAgfHwgdGh1bWJQb3MudG9wID4gJGxpc3QuaGVpZ2h0KCkgLSB0aHVtYi5vdXRlckhlaWdodCgpKSkge1xyXG4gICAgICAgICRsaXN0LnN0b3AoKS5hbmltYXRlKHtcclxuICAgICAgICAgICAgc2Nyb2xsVG9wOiAkbGlzdC5zY3JvbGxUb3AoKSArIHRodW1iUG9zLnRvcFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIGR1cmF0aW9uXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICBzZWxmLm9wdHMuYXhpcyA9PT0gXCJ4XCIgJiZcclxuICAgICAgICAodGh1bWJQb3MubGVmdCA8ICRncmlkLnNjcm9sbExlZnQoKSB8fCB0aHVtYlBvcy5sZWZ0ID4gJGdyaWQuc2Nyb2xsTGVmdCgpICsgKCRncmlkLndpZHRoKCkgLSB0aHVtYi5vdXRlcldpZHRoKCkpKVxyXG4gICAgICApIHtcclxuICAgICAgICAkbGlzdFxyXG4gICAgICAgICAgLnBhcmVudCgpXHJcbiAgICAgICAgICAuc3RvcCgpXHJcbiAgICAgICAgICAuYW5pbWF0ZSh7XHJcbiAgICAgICAgICAgICAgc2Nyb2xsTGVmdDogdGh1bWJQb3MubGVmdFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBkdXJhdGlvblxyXG4gICAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xyXG4gICAgICB0aGF0Lmluc3RhbmNlLiRyZWZzLmNvbnRhaW5lci50b2dnbGVDbGFzcyhcImZhbmN5Ym94LXNob3ctdGh1bWJzXCIsIHRoaXMuaXNWaXNpYmxlKTtcclxuXHJcbiAgICAgIGlmICh0aGF0LmlzVmlzaWJsZSkge1xyXG4gICAgICAgIGlmICghdGhhdC4kZ3JpZCkge1xyXG4gICAgICAgICAgdGhhdC5jcmVhdGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoYXQuaW5zdGFuY2UudHJpZ2dlcihcIm9uVGh1bWJzU2hvd1wiKTtcclxuXHJcbiAgICAgICAgdGhhdC5mb2N1cygwKTtcclxuICAgICAgfSBlbHNlIGlmICh0aGF0LiRncmlkKSB7XHJcbiAgICAgICAgdGhhdC5pbnN0YW5jZS50cmlnZ2VyKFwib25UaHVtYnNIaWRlXCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBVcGRhdGUgY29udGVudCBwb3NpdGlvblxyXG4gICAgICB0aGF0Lmluc3RhbmNlLnVwZGF0ZSgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuaXNWaXNpYmxlID0gZmFsc2U7XHJcbiAgICAgIHRoaXMudXBkYXRlKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5pc1Zpc2libGUgPSB0cnVlO1xyXG4gICAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gICAgfSxcclxuXHJcbiAgICB0b2dnbGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5pc1Zpc2libGUgPSAhdGhpcy5pc1Zpc2libGU7XHJcbiAgICAgIHRoaXMudXBkYXRlKCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gICQoZG9jdW1lbnQpLm9uKHtcclxuICAgIFwib25Jbml0LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSkge1xyXG4gICAgICB2Y
109XIgVGh1bWJzO1xyXG5cclxuICAgICAgaWYgKGluc3RhbmNlICYmICFpbnN0YW5jZS5UaHVtYnMpIHtcclxuICAgICAgICBUaHVtYnMgPSBuZXcgRmFuY3lUaHVtYnMoaW5zdGFuY2UpO1xyXG5cclxuICAgICAgICBpZiAoVGh1bWJzLmlzQWN0aXZlICYmIFRodW1icy5vcHRzLmF1dG9TdGFydCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgVGh1bWJzLnNob3coKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgXCJiZWZvcmVTaG93LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgaXRlbSwgZmlyc3RSdW4pIHtcclxuICAgICAgdmFyIFRodW1icyA9IGluc3RhbmNlICYmIGluc3RhbmNlLlRodW1icztcclxuXHJcbiAgICAgIGlmIChUaHVtYnMgJiYgVGh1bWJzLmlzVmlzaWJsZSkge1xyXG4gICAgICAgIFRodW1icy5mb2N1cyhmaXJzdFJ1biA/IDAgOiAyNTApO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIFwiYWZ0ZXJLZXlkb3duLmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCwga2V5cHJlc3MsIGtleWNvZGUpIHtcclxuICAgICAgdmFyIFRodW1icyA9IGluc3RhbmNlICYmIGluc3RhbmNlLlRodW1icztcclxuXHJcbiAgICAgIC8vIFwiR1wiXHJcbiAgICAgIGlmIChUaHVtYnMgJiYgVGh1bWJzLmlzQWN0aXZlICYmIGtleWNvZGUgPT09IDcxKSB7XHJcbiAgICAgICAga2V5cHJlc3MucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgVGh1bWJzLnRvZ2dsZSgpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIFwiYmVmb3JlQ2xvc2UuZmJcIjogZnVuY3Rpb24gKGUsIGluc3RhbmNlKSB7XHJcbiAgICAgIHZhciBUaHVtYnMgPSBpbnN0YW5jZSAmJiBpbnN0YW5jZS5UaHVtYnM7XHJcblxyXG4gICAgICBpZiAoVGh1bWJzICYmIFRodW1icy5pc1Zpc2libGUgJiYgVGh1bWJzLm9wdHMuaGlkZU9uQ2xvc2UgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgVGh1bWJzLiRncmlkLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG59KShkb2N1bWVudCwgalF1ZXJ5KTtcbi8vLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuLy9cclxuLy8gU2hhcmVcclxuLy8gRGlzcGxheXMgc2ltcGxlIGZvcm0gZm9yIHNoYXJpbmcgY3VycmVudCB1cmxcclxuLy9cclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuKGZ1bmN0aW9uIChkb2N1bWVudCwgJCkge1xyXG4gIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAkLmV4dGVuZCh0cnVlLCAkLmZhbmN5Ym94LmRlZmF1bHRzLCB7XHJcbiAgICBidG5UcGw6IHtcclxuICAgICAgc2hhcmU6ICc8YnV0dG9uIGRhdGEtZmFuY3lib3gtc2hhcmUgY2xhc3M9XCJmYW5jeWJveC1idXR0b24gZmFuY3lib3gtYnV0dG9uLS1zaGFyZVwiIHRpdGxlPVwie3tTSEFSRX19XCI+JyArXHJcbiAgICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj48cGF0aCBkPVwiTTIuNTUgMTljMS40LTguNCA5LjEtOS44IDExLjktOS44VjVsNyA3LTcgNi4zdi0zLjVjLTIuOCAwLTEwLjUgMi4xLTExLjkgNC4yelwiLz48L3N2Zz4nICtcclxuICAgICAgICBcIjwvYnV0dG9uPlwiXHJcbiAgICB9LFxyXG4gICAgc2hhcmU6IHtcclxuICAgICAgdXJsOiBmdW5jdGlvbiAoaW5zdGFuY2UsIGl0ZW0pIHtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgKCFpbnN0YW5jZS5jdXJyZW50SGFzaCAmJiAhKGl0ZW0udHlwZSA9PT0gXCJpbmxpbmVcIiB8fCBpdGVtLnR5cGUgPT09IFwiaHRtbFwiKSA/IGl0ZW0ub3JpZ1NyYyB8fCBpdGVtLnNyYyA6IGZhbHNlKSB8fCB3aW5kb3cubG9jYXRpb25cclxuICAgICAgICApO1xyXG4gICAgICB9LFxyXG4gICAgICB0cGw6ICc8ZGl2IGNsYXNzPVwiZmFuY3lib3gtc2hhcmVcIj4nICtcclxuICAgICAgICBcIjxoMT57e1NIQVJFfX08L2gxPlwiICtcclxuICAgICAgICBcIjxwPlwiICtcclxuICAgICAgICAnPGEgY2xhc3M9XCJmYW5jeWJveC1zaGFyZV9fYnV0dG9uIGZhbmN5Ym94LXNoYXJlX19idXR0b24tLWZiXCIgaHJlZj1cImh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zaGFyZXIvc2hhcmVyLnBocD91PXt7dXJsfX1cIj4nICtcclxuICAgICAgICAnPHN2ZyB2aWV3Qm94PVwiMCAwIDUxMiA1MTJcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIm0yODcgNDU2di0yOTljMC0yMSA2LTM1IDM1LTM1aDM4di02M2MtNy0xLTI5LTMtNTUtMy01NCAwLTkxIDMzLTkxIDk0djMwNm0xNDMtMjU0aC0yMDV2NzJoMTk2XCIgLz48L3N2Zz4nICtcclxuICAgICAgICBcIjxzcGFuPkZhY2Vib29rPC9zcGFuPlwiICtcclxuICAgICAgICBcIjwvYT5cIiArXHJcbiAgICAgICAgJzxhIGNsYXNzPVwiZmFuY3lib3gtc2hhcmVfX2J1dHRvbiBmYW5jeWJveC1zaGFyZV9fYnV0dG9uLS10d1wiIGhyZWY9XCJodHRwczovL3R3aXR0ZXIuY29tL2ludGVudC90d2VldD91cmw9e3t1cmx9fSZ0ZXh0PXt7ZGVzY3J9fVwiPicgK1xyXG4gICAgICAgICc8c3ZnIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj48cGF0aCBkPVwibTQ1NiAxMzNjLTE0IDctMzEgMTEtNDcgMTMgMTctMTAgMzAtMjcgMzctNDYtMTUgMTAtMzQgMTYtNTIgMjAtNjEtNjItMTU3LTctMTQxIDc1LTY4LTMtMTI5LTM1LTE2OS04NS0yMiAzNy0xMSA4NiAyNiAxMDktMTMgMC0yNi00LTM3LTkgMCAzOSAyOCA3MiA2NSA4MC0xMiAzLTI1IDQtMzcgMiAxMCAzMyA0MSA1NyA3NyA1Ny00MiAzMC03NyAzOC0xMjIgMzQgMTcwIDExMSAzNzgtMzIgMzU5LTIwOCAxNi0xMSAzMC0yNSA0MS00MnpcIiAvPjwvc3ZnPicgK1xyXG4gICAgICAgIFwiPHNwYW4+VHdpdHRlcjwvc3Bhbj5cIiArXHJcbiAgICAgICAgXCI8L2E+XCIgK1xyXG4gICAgICAgICc8YSBjbGFzcz1cImZhbmN5Ym94LXNoYXJlX19idXR0b24gZmFuY3lib3gtc2hhcmVfX2J1dHRvbi0tcHRcIiBocmVmPVwiaHR0cHM6Ly93d3cucGludGVyZXN0LmNvbS9waW4vY3JlYXRlL2J1dHRvbi8/dXJsPXt7dXJsfX0mZGVzY3JpcHRpb249e3tkZXNjcn19Jm1lZGlhPXt7bWVkaWF9fVwiPicgK1xyXG4gICAgICAgICc8c3ZnIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj48cGF0aCBkPVwibTI2NSA1NmMtMTA5IDAtMTY0IDc4LTE2NCAxNDQgMCAzOSAxNSA3NCA0NyA4NyA1
109IDIgMTAgMCAxMi01bDQtMTljMi02IDEtOC0zLTEzLTktMTEtMTUtMjUtMTUtNDUgMC01OCA0My0xMTAgMTEzLTExMCA2MiAwIDk2IDM4IDk2IDg4IDAgNjctMzAgMTIyLTczIDEyMi0yNCAwLTQyLTE5LTM2LTQ0IDYtMjkgMjAtNjAgMjAtODEgMC0xOS0xMC0zNS0zMS0zNS0yNSAwLTQ0IDI2LTQ0IDYwIDAgMjEgNyAzNiA3IDM2bC0zMCAxMjVjLTggMzctMSA4MyAwIDg3IDAgMyA0IDQgNSAyIDItMyAzMi0zOSA0Mi03NWwxNi02NGM4IDE2IDMxIDI5IDU2IDI5IDc0IDAgMTI0LTY3IDEyNC0xNTcgMC02OS01OC0xMzItMTQ2LTEzMnpcIiBmaWxsPVwiI2ZmZlwiLz48L3N2Zz4nICtcclxuICAgICAgICBcIjxzcGFuPlBpbnRlcmVzdDwvc3Bhbj5cIiArXHJcbiAgICAgICAgXCI8L2E+XCIgK1xyXG4gICAgICAgIFwiPC9wPlwiICtcclxuICAgICAgICAnPHA+PGlucHV0IGNsYXNzPVwiZmFuY3lib3gtc2hhcmVfX2lucHV0XCIgdHlwZT1cInRleHRcIiB2YWx1ZT1cInt7dXJsX3Jhd319XCIgb25jbGljaz1cInNlbGVjdCgpXCIgLz48L3A+JyArXHJcbiAgICAgICAgXCI8L2Rpdj5cIlxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICBmdW5jdGlvbiBlc2NhcGVIdG1sKHN0cmluZykge1xyXG4gICAgdmFyIGVudGl0eU1hcCA9IHtcclxuICAgICAgXCImXCI6IFwiJmFtcDtcIixcclxuICAgICAgXCI8XCI6IFwiJmx0O1wiLFxyXG4gICAgICBcIj5cIjogXCImZ3Q7XCIsXHJcbiAgICAgICdcIic6IFwiJnF1b3Q7XCIsXHJcbiAgICAgIFwiJ1wiOiBcIiYjMzk7XCIsXHJcbiAgICAgIFwiL1wiOiBcIiYjeDJGO1wiLFxyXG4gICAgICBcImBcIjogXCImI3g2MDtcIixcclxuICAgICAgXCI9XCI6IFwiJiN4M0Q7XCJcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIFN0cmluZyhzdHJpbmcpLnJlcGxhY2UoL1smPD5cIidgPVxcL10vZywgZnVuY3Rpb24gKHMpIHtcclxuICAgICAgcmV0dXJuIGVudGl0eU1hcFtzXTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIltkYXRhLWZhbmN5Ym94LXNoYXJlXVwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgaW5zdGFuY2UgPSAkLmZhbmN5Ym94LmdldEluc3RhbmNlKCksXHJcbiAgICAgIGN1cnJlbnQgPSBpbnN0YW5jZS5jdXJyZW50IHx8IG51bGwsXHJcbiAgICAgIHVybCxcclxuICAgICAgdHBsO1xyXG5cclxuICAgIGlmICghY3VycmVudCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCQudHlwZShjdXJyZW50Lm9wdHMuc2hhcmUudXJsKSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgIHVybCA9IGN1cnJlbnQub3B0cy5zaGFyZS51cmwuYXBwbHkoY3VycmVudCwgW2luc3RhbmNlLCBjdXJyZW50XSk7XHJcbiAgICB9XHJcblxyXG4gICAgdHBsID0gY3VycmVudC5vcHRzLnNoYXJlLnRwbFxyXG4gICAgICAucmVwbGFjZSgvXFx7XFx7bWVkaWFcXH1cXH0vZywgY3VycmVudC50eXBlID09PSBcImltYWdlXCIgPyBlbmNvZGVVUklDb21wb25lbnQoY3VycmVudC5zcmMpIDogXCJcIilcclxuICAgICAgLnJlcGxhY2UoL1xce1xce3VybFxcfVxcfS9nLCBlbmNvZGVVUklDb21wb25lbnQodXJsKSlcclxuICAgICAgLnJlcGxhY2UoL1xce1xce3VybF9yYXdcXH1cXH0vZywgZXNjYXBlSHRtbCh1cmwpKVxyXG4gICAgICAucmVwbGFjZSgvXFx7XFx7ZGVzY3JcXH1cXH0vZywgaW5zdGFuY2UuJGNhcHRpb24gPyBlbmNvZGVVUklDb21wb25lbnQoaW5zdGFuY2UuJGNhcHRpb24udGV4dCgpKSA6IFwiXCIpO1xyXG5cclxuICAgICQuZmFuY3lib3gub3Blbih7XHJcbiAgICAgIHNyYzogaW5zdGFuY2UudHJhbnNsYXRlKGluc3RhbmNlLCB0cGwpLFxyXG4gICAgICB0eXBlOiBcImh0bWxcIixcclxuICAgICAgb3B0czoge1xyXG4gICAgICAgIHRvdWNoOiBmYWxzZSxcclxuICAgICAgICBhbmltYXRpb25FZmZlY3Q6IGZhbHNlLFxyXG4gICAgICAgIGFmdGVyTG9hZDogZnVuY3Rpb24gKHNoYXJlSW5zdGFuY2UsIHNoYXJlQ3VycmVudCkge1xyXG4gICAgICAgICAgLy8gQ2xvc2Ugc2VsZiBpZiBwYXJlbnQgaW5zdGFuY2UgaXMgY2xvc2luZ1xyXG4gICAgICAgICAgaW5zdGFuY2UuJHJlZnMuY29udGFpbmVyLm9uZShcImJlZm9yZUNsb3NlLmZiXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgc2hhcmVJbnN0YW5jZS5jbG9zZShudWxsLCAwKTtcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIC8vIE9wZW5pbmcgbGlua3MgaW4gYSBwb3B1cCB3aW5kb3dcclxuICAgICAgICAgIHNoYXJlQ3VycmVudC4kY29udGVudC5maW5kKFwiLmZhbmN5Ym94LXNoYXJlX19idXR0b25cIikuY2xpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB3aW5kb3cub3Blbih0aGlzLmhyZWYsIFwiU2hhcmVcIiwgXCJ3aWR0aD01NTAsIGhlaWdodD00NTBcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbW9iaWxlOiB7XHJcbiAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxufSkoZG9jdW1lbnQsIGpRdWVyeSk7XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4vL1xyXG4vLyBIYXNoXHJcbi8vIEVuYWJsZXMgbGlua2luZyB0byBlYWNoIG1vZGFsXHJcbi8vXHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbihmdW5jdGlvbiAod2luZG93LCBkb2N1bWVudCwgJCkge1xyXG4gIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAvLyBTaW1wbGUgJC5lc2NhcGVTZWxlY3RvciBwb2x5ZmlsbCAoZm9yIGpRdWVyeSBwcmlvciB2MylcclxuICBpZiAoISQuZXNjYXBlU2VsZWN0b3IpIHtcclxuICAgICQuZXNjYXBlU2VsZWN0b3IgPSBmdW5jdGlvbiAoc2VsKSB7XHJcbiAgICAgIHZhciByY3NzZXNjYXBlID0gLyhbXFwwLVxceDFmXFx4N2ZdfF4tP1xcZCl8Xi0kfFteXFx4ODAtXFx1RkZGRlxcdy1dL2c7XHJcbiAgICAgIHZhciBmY3NzZXNjYXBlID0gZnVuY3Rpb24gKGNoLCBhc0NvZGVQb2ludCkge1xyXG4gICAgICAgIGlmIChhc0NvZGVQb2ludCkge1xyXG4gICAgICAgICAgLy8gVSswMDAwIE5VTEwgYmVjb21lcyBVK0ZGRkQgUkVQTEFDRU1FTlQgQ0hBUkFDVEVSXHJcbiAgICAgICAgICBpZiAoY2ggPT
10909IFwiXFwwXCIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiXFx1RkZGRFwiO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIC8vIENvbnRyb2wgY2hhcmFjdGVycyBhbmQgKGRlcGVuZGVudCB1cG9uIHBvc2l0aW9uKSBudW1iZXJzIGdldCBlc2NhcGVkIGFzIGNvZGUgcG9pbnRzXHJcbiAgICAgICAgICByZXR1cm4gY2guc2xpY2UoMCwgLTEpICsgXCJcXFxcXCIgKyBjaC5jaGFyQ29kZUF0KGNoLmxlbmd0aCAtIDEpLnRvU3RyaW5nKDE2KSArIFwiIFwiO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXIgcG90ZW50aWFsbHktc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzIGdldCBiYWNrc2xhc2gtZXNjYXBlZFxyXG4gICAgICAgIHJldHVybiBcIlxcXFxcIiArIGNoO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0dXJuIChzZWwgKyBcIlwiKS5yZXBsYWNlKHJjc3Nlc2NhcGUsIGZjc3Nlc2NhcGUpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIEdldCBpbmZvIGFib3V0IGdhbGxlcnkgbmFtZSBhbmQgY3VycmVudCBpbmRleCBmcm9tIHVybFxyXG4gIGZ1bmN0aW9uIHBhcnNlVXJsKCkge1xyXG4gICAgdmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaC5zdWJzdHIoMSksXHJcbiAgICAgIHJleiA9IGhhc2guc3BsaXQoXCItXCIpLFxyXG4gICAgICBpbmRleCA9IHJlei5sZW5ndGggPiAxICYmIC9eXFwrP1xcZCskLy50ZXN0KHJleltyZXoubGVuZ3RoIC0gMV0pID8gcGFyc2VJbnQocmV6LnBvcCgtMSksIDEwKSB8fCAxIDogMSxcclxuICAgICAgZ2FsbGVyeSA9IHJlei5qb2luKFwiLVwiKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBoYXNoOiBoYXNoLFxyXG4gICAgICAvKiBJbmRleCBpcyBzdGFydGluZyBmcm9tIDEgKi9cclxuICAgICAgaW5kZXg6IGluZGV4IDwgMSA/IDEgOiBpbmRleCxcclxuICAgICAgZ2FsbGVyeTogZ2FsbGVyeVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIFRyaWdnZXIgY2xpY2sgZXZudCBvbiBsaW5rcyB0byBvcGVuIG5ldyBmYW5jeUJveCBpbnN0YW5jZVxyXG4gIGZ1bmN0aW9uIHRyaWdnZXJGcm9tVXJsKHVybCkge1xyXG4gICAgaWYgKHVybC5nYWxsZXJ5ICE9PSBcIlwiKSB7XHJcbiAgICAgIC8vIElmIHdlIGNhbiBmaW5kIGVsZW1lbnQgbWF0Y2hpbmcgJ2RhdGEtZmFuY3lib3gnIGF0cmlidXRlLFxyXG4gICAgICAvLyB0aGVuIHRyaWdnZXJpbmcgY2xpY2sgZXZlbnQgc2hvdWxkIHN0YXJ0IGZhbmN5Qm94XHJcbiAgICAgICQoXCJbZGF0YS1mYW5jeWJveD0nXCIgKyAkLmVzY2FwZVNlbGVjdG9yKHVybC5nYWxsZXJ5KSArIFwiJ11cIilcclxuICAgICAgICAuZXEodXJsLmluZGV4IC0gMSlcclxuICAgICAgICAuZm9jdXMoKVxyXG4gICAgICAgIC50cmlnZ2VyKFwiY2xpY2suZmItc3RhcnRcIik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBHZXQgZ2FsbGVyeSBuYW1lIGZyb20gY3VycmVudCBpbnN0YW5jZVxyXG4gIGZ1bmN0aW9uIGdldEdhbGxlcnlJRChpbnN0YW5jZSkge1xyXG4gICAgdmFyIG9wdHMsIHJldDtcclxuXHJcbiAgICBpZiAoIWluc3RhbmNlKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBvcHRzID0gaW5zdGFuY2UuY3VycmVudCA/IGluc3RhbmNlLmN1cnJlbnQub3B0cyA6IGluc3RhbmNlLm9wdHM7XHJcbiAgICByZXQgPSBvcHRzLmhhc2ggfHwgKG9wdHMuJG9yaWcgPyBvcHRzLiRvcmlnLmRhdGEoXCJmYW5jeWJveFwiKSB8fCBvcHRzLiRvcmlnLmRhdGEoXCJmYW5jeWJveC10cmlnZ2VyXCIpIDogXCJcIik7XHJcblxyXG4gICAgcmV0dXJuIHJldCA9PT0gXCJcIiA/IGZhbHNlIDogcmV0O1xyXG4gIH1cclxuXHJcbiAgLy8gU3RhcnQgd2hlbiBET00gYmVjb21lcyByZWFkeVxyXG4gICQoZnVuY3Rpb24gKCkge1xyXG4gICAgLy8gQ2hlY2sgaWYgdXNlciBoYXMgZGlzYWJsZWQgdGhpcyBtb2R1bGVcclxuICAgIGlmICgkLmZhbmN5Ym94LmRlZmF1bHRzLmhhc2ggPT09IGZhbHNlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBVcGRhdGUgaGFzaCB3aGVuIG9wZW5pbmcvY2xvc2luZyBmYW5jeUJveFxyXG4gICAgJChkb2N1bWVudCkub24oe1xyXG4gICAgICBcIm9uSW5pdC5mYlwiOiBmdW5jdGlvbiAoZSwgaW5zdGFuY2UpIHtcclxuICAgICAgICB2Y
109XIgdXJsLCBnYWxsZXJ5O1xyXG5cclxuICAgICAgICBpZiAoaW5zdGFuY2UuZ3JvdXBbaW5zdGFuY2UuY3VyckluZGV4XS5vcHRzLmhhc2ggPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cmwgPSBwYXJzZVVybCgpO1xyXG4gICAgICAgIGdhbGxlcnkgPSBnZXRHYWxsZXJ5SUQoaW5zdGFuY2UpO1xyXG5cclxuICAgICAgICAvLyBNYWtlIHN1cmUgZ2FsbGVyeSBzdGFydCBpbmRleCBtYXRjaGVzIGluZGV4IGZyb20gaGFzaFxyXG4gICAgICAgIGlmIChnYWxsZXJ5ICYmIHVybC5nYWxsZXJ5ICYmIGdhbGxlcnkgPT0gdXJsLmdhbGxlcnkpIHtcclxuICAgICAgICAgIGluc3RhbmNlLmN1cnJJbmRleCA9IHVybC5pbmRleCAtIDE7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG5cclxuICAgICAgXCJiZWZvcmVTaG93LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCwgZmlyc3RSdW4pIHtcclxuICAgICAgICB2YXIgZ2FsbGVyeTtcclxuXHJcbiAgICAgICAgaWYgKCFjdXJyZW50IHx8IGN1cnJlbnQub3B0cy5oYXNoID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgbmVlZCB0byB1cGRhdGUgd2luZG93IGhhc2hcclxuICAgICAgICBnYWxsZXJ5ID0gZ2V0R2FsbGVyeUlEKGluc3RhbmNlKTtcclxuXHJcbiAgICAgICAgaWYgKCFnYWxsZXJ5KSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBWYXJpYWJsZSBjb250YWluaW5nIGxhc3QgaGFzaCB2YWx1ZSBzZXQgYnkgZmFuY3lCb3hcclxuICAgICAgICAvLyBJdCB3aWxsIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGZhbmN5Qm94IG5lZWRzIHRvIGNsb3NlIGFmdGVyIGhhc2ggY2hhbmdlIGlzIGRldGVjdGVkXHJcbiAgICAgICAgaW5zdGFuY2UuY3VycmVudEhhc2ggPSBnYWxsZXJ5ICsgKGluc3RhbmNlLmdyb3VwLmxlbmd0aCA+IDEgPyBcIi1cIiArIChjdXJyZW50LmluZGV4ICsgMSkgOiBcIlwiKTtcclxuXHJcbiAgICAgICAgLy8gSWYgY3VycmVudCBoYXNoIGlzIHRoZSBzYW1lICh0aGlzIGluc3RhbmNlIG1vc3QgbGlrZWx5IGlzIG9wZW5lZCBieSBoYXNoY2hhbmdlKSwgdGhlbiBkbyBub3RoaW5nXHJcbiAgICAgICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoID09PSBcIiNcIiArIGluc3RhbmNlLmN1cnJlbnRIYXNoKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZmlyc3RSdW4gJiYgIWluc3RhbmNlLm9yaWdIYXNoKSB7XHJcbiAgICAgICAgICBpbnN0YW5jZS5vcmlnSGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGluc3RhbmNlLmhhc2hUaW1lcikge1xyXG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGluc3RhbmNlLmhhc2hUaW1lcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBVcGRhdGUgaGFzaFxyXG4gICAgICAgIGluc3RhbmNlLmhhc2hUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgaWYgKFwicmVwbGFjZVN0YXRlXCIgaW4gd2luZG93Lmhpc3RvcnkpIHtcclxuICAgICAgICAgICAgd2luZG93Lmhpc3RvcnlbZmlyc3RSdW4gPyBcInB1c2hTdGF0ZVwiIDogXCJyZXBsYWNlU3RhdGVcIl0oe30sXHJcbiAgICAgICAgICAgICAgZG9jdW1lbnQudGl0bGUsXHJcbiAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lICsgd2luZG93LmxvY2F0aW9uLnNlYXJjaCArIFwiI1wiICsgaW5zdGFuY2UuY3VycmVudEhhc2hcclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChmaXJzdFJ1bikge1xyXG4gICAgICAgICAgICAgIGluc3RhbmNlLmhhc0NyZWF0ZWRIaXN0b3J5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBpbnN0YW5jZS5jdXJyZW50SGFzaDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpbnN0YW5jZS5oYXNoVGltZXIgPSBudWxsO1xyXG4gICAgICAgIH0sIDMwMCk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBcImJlZm9yZUNsb3NlLmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCkge1xyXG4gICAgICAgIGlmICghY3VycmVudCB8fCBjdXJyZW50Lm9wdHMuaGFzaCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNsZWFyVGltZW91dChpbnN0YW5jZS5oYXNoVGltZXIpO1xyXG5cclxuICAgICAgICAvLyBHb3RvIHByZXZpb3VzIGhpc3RvcnkgZW50cnlcclxuICAgICAgICBpZiAoaW5zdGFuY2UuY3VycmVudEhhc2ggJiYgaW5zdGFuY2UuaGFzQ3JlYXRlZEhpc3RvcnkpIHtcclxuICAgICAgICAgIHdpbmRvdy5oaXN0b3J5LmJhY2soKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmN1cnJlbnRIYXNoKSB7XHJcbiAgICAgICAgICBpZiAoXCJyZXBsYWNlU3RhdGVcIiBpbiB3aW5kb3cuaGlzdG9yeSkge1xyXG4gICAgICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIGRvY3VtZW50LnRpdGxlLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUgKyB3aW5kb3cubG9jYXRpb24uc2VhcmNoICsgKGluc3RhbmNlLm9yaWdIYXNoIHx8IFwiXCIpKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gaW5zdGFuY2Uub3JpZ0hhc2g7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbnN0YW5jZS5jdXJyZW50SGFzaCA9IG51bGw7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIG5lZWQgdG8gc3RhcnQvY2xvc2UgYWZ0ZXIgdXJsIGhhcyBjaGFuZ2VkXHJcbiAgICAkKHdpbmRvdykub24oXCJoYXNoY2hhbmdlLmZiXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHVybCA9IHBhcnNlVXJsKCksXHJcbiAgICAgICAgZmIgPSBudWxsO1xyXG5cclxuICAgICAgLy8gRmluZCBsYXN0IGZhbmN5Qm94IGluc3RhbmNlIHRoYXQgaGFzIFwiaGFzaFwiXHJcbiAgICAgICQuZWFjaChcclxuICAgICAgICAkKFwiLmZhbmN5Ym94LWNvbnRhaW5lclwiKVxyXG4gICAgICAgIC5nZXQoKVxyXG4gICAgICAgIC5yZXZlcnNlKCksXHJcbiAgICAgICAgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkge1xyXG4gICAgICAgICAgdmFyIHRtcCA9ICQodmFsdWUpLmRhdGEoXCJGYW5jeUJveFwiKTtcclxuXHJcbiAgICAgICAgICBpZiAodG1wICYmIHRtcC5jdXJyZW50SGFzaCkge1xyXG4gICAgICAgICAgICBmYiA9IHRt
109cDtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmIChmYikge1xyXG4gICAgICAgIC8vIE5vdywgY29tcGFyZSBoYXNoIHZhbHVlc1xyXG4gICAgICAgIGlmIChmYi5jdXJyZW50SGFzaCAhPT0gdXJsLmdhbGxlcnkgKyBcIi1cIiArIHVybC5pbmRleCAmJiAhKHVybC5pbmRleCA9PT0gMSAmJiBmYi5jdXJyZW50SGFzaCA9PSB1cmwuZ2FsbGVyeSkpIHtcclxuICAgICAgICAgIGZiLmN1cnJlbnRIYXNoID0gbnVsbDtcclxuXHJcbiAgICAgICAgICBmYi5jbG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmICh1cmwuZ2FsbGVyeSAhPT0gXCJcIikge1xyXG4gICAgICAgIHRyaWdnZXJGcm9tVXJsKHVybCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIENoZWNrIGN1cnJlbnQgaGFzaCBhbmQgdHJpZ2dlciBjbGljayBldmVudCBvbiBtYXRjaGluZyBlbGVtZW50IHRvIHN0YXJ0IGZhbmN5Qm94LCBpZiBuZWVkZWRcclxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAoISQuZmFuY3lib3guZ2V0SW5zdGFuY2UoKSkge1xyXG4gICAgICAgIHRyaWdnZXJGcm9tVXJsKHBhcnNlVXJsKCkpO1xyXG4gICAgICB9XHJcbiAgICB9LCA1MCk7XHJcbiAgfSk7XHJcbn0pKHdpbmRvdywgZG9jdW1lbnQsIGpRdWVyeSk7XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4vL1xyXG4vLyBXaGVlbFxyXG4vLyBCYXNpYyBtb3VzZSB3ZWhlZWwgc3VwcG9ydCBmb3IgZ2FsbGVyeSBuYXZpZ2F0aW9uXHJcbi8vXHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbihmdW5jdGlvbiAoZG9jdW1lbnQsICQpIHtcclxuICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgdmFyIHByZXZUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICQoZG9jdW1lbnQpLm9uKHtcclxuICAgIFwib25Jbml0LmZiXCI6IGZ1bmN0aW9uIChlLCBpbnN0YW5jZSwgY3VycmVudCkge1xyXG4gICAgICBpbnN0YW5jZS4kcmVmcy5zdGFnZS5vbihcIm1vdXNld2hlZWwgRE9NTW91c2VTY3JvbGwgd2hlZWwgTW96TW91c2VQaXhlbFNjcm9sbFwiLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHZhciBjdXJyZW50ID0gaW5zdGFuY2UuY3VycmVudCxcclxuICAgICAgICAgIGN1cnJUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICAgICAgIGlmIChpbnN0YW5jZS5ncm91cC5sZW5ndGggPCAyIHx8IGN1cnJlbnQub3B0cy53aGVlbCA9PT0gZmFsc2UgfHwgKGN1cnJlbnQub3B0cy53aGVlbCA9PT0gXCJhdXRvXCIgJiYgY3VycmVudC50eXBlICE9PSBcImltYWdlXCIpKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgICAgaWYgKGN1cnJlbnQuJHNsaWRlLmhhc0NsYXNzKFwiZmFuY3lib3gtYW5pbWF0ZWRcIikpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGUgPSBlLm9yaWdpbmFsRXZlbnQgfHwgZTtcclxuXHJcbiAgICAgICAgaWYgKGN1cnJUaW1lIC0gcHJldlRpbW
109UgPCAyNTApIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByZXZUaW1lID0gY3VyclRpbWU7XHJcblxyXG4gICAgICAgIGluc3RhbmNlWygtZS5kZWx0YVkgfHwgLWUuZGVsdGFYIHx8IGUud2hlZWxEZWx0YSB8fCAtZS5kZXRhaWwpIDwgMCA/IFwibmV4dFwiIDogXCJwcmV2aW91c1wiXSgpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxufSkoZG9jdW1lbnQsIGpRdWVyeSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvQGZhbmN5YXBwcy9mYW5jeWJveC9kaXN0L2pxdWVyeS5mYW5jeWJveC5qc1xuLy8gbW9kdWxlIGlkID0gM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQT
109tBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU
109NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3\n"); 110 111/***/ }), 112/* 4 */ 113/*!***********************************************!*\ 114 !*** ./node_modules/swiper/swiper-bundle.css ***! 115 \***********************************************/ 116/*! dynamic exports provided */ 117/*! all exports used */
118/***/ (function(module, exports) { 119 120eval("// removed by extract-text-webpack-plugin//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc3dpcGVyLWJ1bmRsZS5jc3M/MjhiNCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyByZW1vdmVkIGJ5IGV4dHJhY3QtdGV4dC13ZWJwYWNrLXBsdWdpblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3N3aXBlci9zd2lwZXItYnVuZGxlLmNzc1xuLy8gbW9kdWxlIGlkID0gNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4\n"); 121 122/***/ }), 123/* 5 */ 124/*!**************************!*\ 125 !*** ./src/js/search.js ***! 126 \**************************/ 127/*! dynamic exports provided */ 128/*! all exports used */ 129/***/ (function(module, exports, __webpack_require__) { 130 131"use strict"; 132eval("\n\nvar mainSearchInput = document.getElementById('popup-search');\nif (mainSearchInput != null) {\n mainSearchInput.onkeypress = function (e) {\n if (!e) e = window.event;\n var keyCode = e.keyCode || e.which;\n if (keyCode == '13') {\n\n var searchValue = $(this).val();\n //console.log(searchValue);\n\n window.location.href = '/Shop?SearchValue=' + searchValue;\n return false;\n }\n };\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9zcmMvanMvc2VhcmNoLmpzPzkyMmMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIG1haW5TZWFyY2hJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwb3B1cC1zZWFyY2gnKTtcclxuaWYgKG1haW5TZWFyY2hJbnB1dCAhPSBudWxsKSB7XHJcbiAgICBtYWluU2VhcmNoSW5wdXQub25rZXlwcmVzcyA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgaWYgKCFlKSBlID0gd2luZG93LmV2ZW50O1xyXG4gICAgICAgIHZhciBrZXlDb2RlID0gZS5rZXlDb2RlIHx8IGUud2hpY2g7XHJcbiAgICAgICAgaWYgKGtleUNvZGUgPT0gJzEzJykge1xyXG5cclxuICAgICAgICAgICAgdmFyIHNlYXJjaFZhbHVlID0gJCh0aGlzKS52YWwoKTtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhzZWFyY2hWYWx1ZSk7XHJcblxyXG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9ICcvU2hvcD9TZWFyY2hWYWx1ZT0nICsgc2VhcmNoVmFsdWU7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBzcmMvanMvc2VhcmNoLmpzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5\n"); 133 134/***/ }), 135/* 6 */ 136/*!****************************!*\ 137 !*** ./src/js/megamenu.js ***! 138 \****************************/ 139/*! dynamic exports provided */ 140/*! all exports used */ 141/***/ (function(module, exports, __webpack_require__) { 142 143"use strict"; 144eval("\n\n/*global $ */\n$(document).ready(function () {\n\n \"use strict\";\n\n $('.menu > ul > li:has( > ul)').addClass('menu-dropdown-icon');\n //Checks if li has sub (ul) and adds class for toggle icon - just an UI\n\n $('.menu > ul > li > ul:not(:has(ul))').addClass('normal-sub');\n //Checks if drodown menu's li elements have anothere level (ul), if not the dropdown is shown as regular dropdown, not a mega menu (thanks Luka Kladaric)\n\n $(\".menu > ul\").before(\"<a href=\\\"#\\\" class=\\\"menu-mobile\\\">Navigation</a>\");\n\n //Adds menu-mobile class (for mobile toggle menu) before the normal menu\n //Mobile menu is hidden if width is more then 959px, but normal menu is displayed\n //Normal menu is hidden if width is below 959px, and jquery adds mobile menu\n //Done this way so it can be used with wordpress without any trouble\n\n $(\".menu > ul > li\").hover(function (e) {\n if ($(window).width() > 943) {\n $(this).children(\"ul\").stop(true, false).fadeToggle(150);\n e.preventDefault();\n }\n });\n //If width is more than 943px dropdowns are displayed on hover\n\n $(\".menu > ul > li\").click(function () {\n if ($(window).width() <= 943) {\n $(this).children(\"ul\").fadeToggle(150);\n }\n });\n //If width is less or equal to 943px dropdowns are displayed on click (thanks Aman Jain from stackoverflow)\n\n $(\".menu-mobile\").click(function (e) {\n $(\".menu > ul\").toggleClass('show-on-mobile');\n e.preventDefault();\n });\n //when clicked on mobile-menu, normal menu is shown as a list, classic rwd menu story (thanks mwl from stackoverflow)\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9zcmMvanMvbWVnYW1lbnUuanM/YmFkNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCAkICovXHJcbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCkge1xyXG5cclxuICAgIFwidXNlIHN0cmljdFwiO1xyXG4gIFxyXG4gICAgJCgnLm1lbnUgPiB1bCA+IGxpOmhhcyggPiB1bCknKS5hZGRDbGFzcygnbWVudS1kcm9wZG93bi1pY29uJyk7XHJcbiAgICAvL0NoZWNrcyBpZiBsaSBoYXMgc3ViICh1bCkgYW5kIGFkZHMgY2xhc3MgZm9yIHRvZ2dsZSBpY29uIC0ganVzdCBhbiBVSVxyXG4gIFxyXG4gICAgJCgnLm1lbnUgPiB1bCA+IGxpID4gdWw6bm90KDpoYXModWwpKScpLmFkZENsYXNzKCdub3JtYWwtc3ViJyk7XHJcbiAgICAvL0NoZWNrcyBpZiBkcm9kb3duIG1lbnUncyBsaSBlbGVtZW50cyBoYXZlIGFub3RoZXJlIGxldmVsICh1bCksIGlmIG5vdCB0aGUgZHJvcGRvd24gaXMgc2hvd24gYXMgcmVndWxhciBkcm9wZG93biwgbm90IGEgbWVnYSBtZW51ICh0aGFua3MgTHVrYSBLbGFkYXJpYylcclxuICBcclxuICAgICQoXCIubWVudSA+IHVsXCIpLmJlZm9yZShcIjxhIGhyZWY9XFxcIiNcXFwiIGNsYXNzPVxcXCJtZW51LW1vYmlsZVxcXCI+TmF2aWdhdGlvbjwvYT5cIik7XHJcbiAgXHJcbiAgICAvL0FkZHMgbWVudS1tb2JpbGUgY2xhc3MgKGZvciBtb2JpbGUgdG9nZ2xlIG1lbnUpIGJlZm9yZSB0aGUgbm9ybWFsIG1lbnVcclxuICAgIC8vTW9iaWxlIG1lbnUgaXMgaGlkZGVuIGlmIHdpZHRoIGlzIG1vcmUgdGhlbiA5NTlweCwgYnV0IG5vcm1hbCBtZW51IGlzIGRpc3BsYXllZFxyXG4gICAgLy9Ob3JtYWwgbWVudSBpcyBoaWRkZW4gaWYgd2lkdGggaXMgYmVsb3cgOTU5cHgsIGFuZCBqcXVlcnkgYWRkcyBtb2JpbGUgbWVudVxyXG4gICAgLy9Eb25lIHRoaXMgd2F5IHNvIGl0IGNhbiBiZSB1c2VkIHdpdGggd29yZHByZXNzIHdpdGhvdXQgYW55IHRyb3VibGVcclxuICBcclxuICAgICQoXCIubWVudSA+IHVsID4gbGlcIikuaG92ZXIoZnVuY3Rpb24oZSkge1xyXG4gICAgICBpZiAoJCh3aW5kb3cpLndpZHRoKCkgPiA5NDMpIHtcclxuICAgICAgICAkKHRoaXMpLmNoaWxkcmVuKFwidWxcIikuc3RvcCh0cnVlLCBmYWxzZSkuZmFkZVRvZ2dsZSgxNTApO1xyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICAvL0lmIHdpZHRoIGlzIG1vcmUgdGhhbiA5NDNweCBkcm9wZG93bnMgYXJlIGRpc3BsYXllZCBvbiBob3ZlclxyXG4gIFxyXG4gICAgJChcIi5tZW51ID4gdWwgPiBsaVwiKS5jbGljayhmdW5jdGlvbigpIHtcclxuICAgICAgaWYgKCQod2luZG93KS53aWR0aCgpIDw9IDk0Mykge1xyXG4gICAgICAgICQo
144dGhpcykuY2hpbGRyZW4oXCJ1bFwiKS5mYWRlVG9nZ2xlKDE1MCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgLy9JZiB3aWR0aCBpcyBsZXNzIG9yIGVxdWFsIHRvIDk0M3B4IGRyb3Bkb3ducyBhcmUgZGlzcGxheWVkIG9uIGNsaWNrICh0aGFua3MgQW1hbiBKYWluIGZyb20gc3RhY2tvdmVyZmxvdylcclxuICBcclxuICAgICQoXCIubWVudS1tb2JpbGVcIikuY2xpY2soZnVuY3Rpb24oZSkge1xyXG4gICAgICAkKFwiLm1lbnUgPiB1bFwiKS50b2dnbGVDbGFzcygnc2hvdy1vbi1tb2JpbGUnKTtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfSk7XHJcbiAgICAvL3doZW4gY2xpY2tlZCBvbiBtb2JpbGUtbWVudSwgbm9ybWFsIG1lbnUgaXMgc2hvd24gYXMgYSBsaXN0LCBjbGFzc2ljIHJ3ZCBtZW51IHN0b3J5ICh0aGFua3MgbXdsIGZyb20gc3RhY2tvdmVyZmxvdylcclxuICBcclxuICB9KTtcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gc3JjL2pzL21lZ2FtZW51LmpzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6\n"); 145 146/***/ }), 147/* 7 */ 148/*!***************************************!*\ 149 !*** ./node_modules/noty/lib/noty.js ***! 150 \***************************************/ 151/*! dynamic exports provided */ 152/*! all exports used */ 153/***/ (function(module, exports, __webpack_require__) { 154 155eval("/* \r\n @package NOTY - Dependency-free notification library \r\n @version version: 3.2.0-beta \r\n @contributors https://github.com/needim/noty/graphs/contributors \r\n @documentation Examples and Documentation - https://ned.im/noty \r\n @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php \r\n*/\r\n\r\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"Noty\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Noty\"] = factory();\n\telse\n\t\troot[\"Noty\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 6);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";
155\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.css = exports.deepExtend = exports.animationEndEvents = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nexports.inArray = inArray;\nexports.stopPropagation = stopPropagation;\nexports.generateID = generateID;\nexports.outerHeight = outerHeight;\nexports.addListener = addListener;\nexports.hasClass = hasClass;\nexports.addClass = addClass;\nexports.removeClass = removeClass;\nexports.remove = remove;\nexports.classList = classList;\nexports.visibilityChangeFlow = visibilityChangeFlow;\nexports.createAudioElements = createAudioElements;\n\nvar _api = __webpack_require__(1);\n\nvar API = _interopRequireWildcard(_api);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nvar animationEndEvents = exports.animationEndEvents = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';\n\nfunction inArray(needle, haystack, argStrict) {\n var key = void 0;\n var strict = !!argStrict;\n\n if (strict) {\n for (key in haystack) {\n if (haystack.hasOwnProperty(key) && haystack[key] === needle) {\n return true;\n }\n }\n } else {\n for (key in haystack) {\n if (haystack.hasOwnProperty(key) && haystack[key] === needle) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction stopPropagation(evt) {\n evt = evt || window.event;\n\n if (typeof evt.stopPropagation !== 'undefined') {\n evt.stopPropagation();\n } else {\n evt.cancelBubble = true;\n }\n}\n\nvar deepExtend = exports.deepExtend = function deepExtend(out) {\n out = out || {};\n\n for (var i = 1; i < arguments.length; i++) {\n var obj = arguments[i];\n\n if (!obj) continue;\n\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n if (Array.isArray(obj[key])) {\n out[key] = obj[key];\n } else if (_typeof(obj[key]) === 'object' && obj[key] !== null) {\n out[key] = deepExtend(out[key], obj[key]);\n } else {\n out[key] = obj[key];\n }\n }\n }\n }\n\n return out;\n};\n\nfunction generateID() {\n var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n\n var id = 'noty_' + prefix + '_';\n\n id += 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0;\n var v = c === 'x' ? r : r & 0x3 | 0x8;\n return v.toString(16);\n });\n\n return id;\n}\n\nfunction outerHeight(el) {\n var height = el.offsetHeight;\n var style = window.getComputedStyle(el);\n\n height += parseInt(style.marginTop) + parseInt(style.marginBottom);\n return height;\n}\n\nvar css = exports.css = function () {\n var cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'];\n var cssProps = {};\n\n function camelCase(string) {\n return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function (match, letter) {\n return letter.toUpperCase();\n });\n }\n\n function getVendorProp(name) {\n var style = document.body.style;\n if (name in style) return name;\n\n var i = cssPrefixes.length;\n var capName = name.charAt(0).toUpperCase() + name.slice(1);\n var vendorName = void 0;\n\n while (i--) {\n vendorName = cssPrefixes[i] + capName;\n if (vendorName in style) return vendorName;\n }\n\n return name;\n }\n\n function getStyleProp(name) {\n name = camelCase(name);\n return cssProps[name] || (cssProps[name] = getVendorProp(name));\n }\n\n function applyCss(element, prop, value) {\n prop = getStyleProp(prop);\n element.style[prop] = value;\n }\n\n return function (element, properties) {\n var args = arguments;\n var prop = void 0;\n var value = void 0;\n\n if (args.length === 2) {\n for (prop in properties) {\n if (properties.hasOwnProperty(prop)) {\n value = properties[prop];\n if (value !== undefined && properties.hasOwnProperty(prop)) {\n applyCss(element, prop, value);\n }\n }\n }\n }
155 else {\n applyCss(element, args[1], args[2]);\n }\n };\n}();\n\nfunction addListener(el, events, cb) {\n var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n\n events = events.split(' ');\n for (var i = 0; i < events.length; i++) {\n if (document.addEventListener) {\n el.addEventListener(events[i], cb, useCapture);\n } else if (document.attachEvent) {\n el.attachEvent('on' + events[i], cb);\n }\n }\n}\n\nfunction hasClass(element, name) {\n var list = typeof element === 'string' ? element : classList(element);\n return list.indexOf(' ' + name + ' ') >= 0;\n}\n\nfunction addClass(element, name) {\n var oldList = classList(element);\n var newList = oldList + name;\n\n if (hasClass(oldList, name)) return;\n\n // Trim the opening space.\n element.className = newList.substring(1);\n}\n\nfunction removeClass(element, name) {\n var oldList = classList(element);\n var newList = void 0;\n\n if (!hasClass(element, name)) return;\n\n // Replace the class name.\n newList = oldList.replace(' ' + name + ' ', ' ');
155\n\n // Trim the opening and closing spaces.\n element.className = newList.substring(1, newList.length - 1);\n}\n\nfunction remove(element) {\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n}\n\nfunction classList(element) {\n return (' ' + (element && element.className || '') + ' ').replace(/\\s+/gi, ' ');\n}\n\nfunction visibilityChangeFlow() {\n var hidden = void 0;\n var visibilityChange = void 0;\n if (typeof document.hidden !== 'undefined') {\n // Opera 12.10 and Firefox 18 and later support\n hidden = 'hidden';\n visibilityChange = 'visibilitychange';\n } else if (typeof document.msHidden !== 'undefined') {\n hidden = 'msHidden';\n visibilityChange = 'msvisibilitychange';\n } else if (typeof document.webkitHidden !== 'undefined') {\n hidden = 'webkitHidden';\n visibilityChange = 'webkitvisibilitychange';\n }\n\n function onVisibilityChange() {\n API.PageHidden = document[hidden];\n handleVisibilityChange();\n }\n\n function onBlur() {\n API.PageHidden = true;\n handleVisibilityChange();\n }\n\n function onFocus() {\n API.PageHidden = false;\n handleVisibilityChange();\n }\n\n function handleVisibilityChange() {\n if (API.PageHidden) stopAll();else resumeAll();\n }\n\n function stopAll() {\n setTimeout(function () {\n Object.keys(API.Store).forEach(function (id) {\n if (API.Store.hasOwnProperty(id)) {\n if (API.Store[id].options.visibilityControl) {\n API.Store[id].stop();\n }\n }\n });\n }, 100);\n }\n\n function resumeAll() {\n setTimeout(function () {\n Object.keys(API.Store).forEach(function (id) {\n if (API.Store.hasOwnProperty(id)) {\n if (API.Store[id].options.visibilityControl) {\n API.Store[id].resume();\n }\n }\n });\n API.queueRenderAll();\n }, 100);\n }\n\n if (visibilityChange) {\n addListener(document, visibilityChange, onVisibilityChange);\n }\n\n addListener(window, 'blur', onBlur);\n addListener(window, 'focus', onFocus);\n}\n\nfunction createAudioElements(ref) {\n if (ref.hasSound) {\n var audioElement = document.createElement('audio');\n\n ref.options.sounds.sources.forEach(function (s) {\n var source = document.createElement('source');\n source.src = s;\n source.type = 'audio/' + getExtension(s);\n audioElement.appendChild(source);\n });\n\n if (ref.barDom) {\n ref.barDom.appendChild(audioElement);\n } else {\n document.querySelector('body').appendChild(audioElement);\n }\n\n audioElement.volume = ref.options.sounds.volume;\n\n if (!ref.soundPlayed) {\n audioElement.play();\n ref.soundPlayed = true;\n }\n\n audioElement.onended = function () {\n remove(audioElement);\n };\n }\n}\n\nfunction getExtension(fileName) {\n return fileName.match(/\\.([^.]+)$/)[1];\n}\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});
155\nexports.Defaults = exports.Store = exports.Queues = exports.DefaultMaxVisible = exports.docTitle = exports.DocModalCount = exports.PageHidden = undefined;\nexports.getQueueCounts = getQueueCounts;\nexports.addToQueue = addToQueue;\nexports.removeFromQueue = removeFromQueue;\nexports.queueRender = queueRender;\nexports.queueRenderAll = queueRenderAll;\nexports.ghostFix = ghostFix;\nexports.build = build;\nexports.hasButtons = hasButtons;\nexports.handleModal = handleModal;\nexports.handleModalClose = handleModalClose;\nexports.queueClose = queueClose;\nexports.dequeueClose = dequeueClose;\nexports.fire = fire;\nexports.openFlow = openFlow;\nexports.closeFlow = closeFlow;\n\nvar _utils = __webpack_require__(0);\n\nvar Utils = _interopRequireWildcard(_utils);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nvar PageHidden = exports.PageHidden = false;\nvar DocModalCount = exports.DocModalCount = 0;\n\nvar DocTitleProps = {\n originalTitle: null,\n count: 0,\n changed: false,\n timer: -1\n};\n\nvar docTitle = exports.docTitle = {\n increment: function increment() {\n DocTitleProps.count++;\n\n docTitle._update();\n },\n\n decrement: function decrement() {\n DocTitleProps.count--;\n\n if (DocTitleProps.count <= 0) {\n docTitle._clear();\n return;\n }\n\n docTitle._update();\n },\n\n _update: function _update() {\n var title = document.title;\n\n if (!DocTitleProps.changed) {\n DocTitleProps.originalTitle = title;\n document.title = '(' + DocTitleProps.count + ') ' + title;\n DocTitleProps.changed = true;\n } else {\n document.title = '(' + DocTitleProps.count + ') ' + DocTitleProps.originalTitle;\n }\n },\n\n _clear: function _clear() {\n if (DocTitleProps.changed) {\n DocTitleProps.count = 0;\n document.title = DocTitleProps.originalTitle;\n DocTitleProps.changed = false;\n }\n }\n};\n\nvar DefaultMaxVisible = exports.DefaultMaxVisible = 5;
155\n\nvar Queues = exports.Queues = {\n global: {\n maxVisible: DefaultMaxVisible,\n queue: []\n }\n};\n\nvar Store = exports.Store = {};\n\nvar Defaults = exports.Defaults = {\n type: 'alert',\n layout: 'topRight',\n theme: 'mint',\n text: '',\n timeout: false,\n progressBar: true,\n closeWith: ['click'],\n animation: {\n open: 'noty_effects_open',\n close: 'noty_effects_close'\n },\n id: false,\n force: false,\n killer: false,\n queue: 'global',\n container: false,\n buttons: [],\n callbacks: {\n beforeShow: null,\n onShow: null,\n afterShow: null,\n onClose: null,\n afterClose: null,\n onClick: null,\n onHover: null,\n onTemplate: null\n },\n sounds: {\n sources: [],\n volume: 1,\n conditions: []\n },\n titleCount: {\n conditions: []\n },\n modal: false,\n visibilityControl: false\n\n /**\r\n * @param {string} queueName\r\n * @return {object}\r\n */\n};function getQueueCounts() {\n var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global';\n\n var count = 0;\n var max = DefaultMaxVisible;\n\n if (Queues.hasOwnProperty(queueName)) {\n max = Queues[queueName].maxVisible;\n Object.keys(Store).forEach(function (i) {\n if (Store[i].options.queue === queueName && !Store[i].closed) count++;\n });\n }\n\n return {\n current: count,\n maxVisible: max\n };\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction addToQueue(ref) {\n if (!Queues.hasOwnProperty(ref.options.queue)) {\n Queues[ref.options.queue] = { maxVisible: DefaultMaxVisible, queue: [] };\n }\n\n Queues[ref.options.queue].queue.push(ref);\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction removeFromQueue(ref) {\n if (Queues.hasOwnProperty(ref.options.queue)) {\n var queue = [];\n Object.keys(Queues[ref.options.queue].queue).forEach(function (i) {\n if (Queues[ref.options.queue].queue[i].id !== ref.id) {\n queue.push(Queues[ref.options.queue].queue[i]);\n }\n });\n Queues[ref.options.queue].queue = queue;\n }\n}\n\n/**\r\n * @param {string} queueName\r\n * @return {void}\r\n */\nfunction queueRender() {\n var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global';\n\n if (Queues.hasOwnProperty(queueName)) {\n var noty = Queues[queueName].queue.shift();\n\n if (noty) noty.show();\n }\n}\n\n/**\r\n * @return {void}\r\n */\nfunction queueRenderAll() {\n Object.keys(Queues).forEach(function (queueName) {\n queueRender(queueName);\n });\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction ghostFix(ref) {\n var ghostID = Utils.generateID('ghost');\n var ghost = document.createElement('div');\n ghost.setAttribute('id', ghostID);\n Utils.css(ghost, {\n height: Utils.outerHeight(ref.barDom) + 'px'\n });\n\n ref.barDom.insertAdjacentHTML('afterend', ghost.outerHTML);\n\n Utils.remove(ref.barDom);\n ghost = document.getElementById(ghostID);\n Utils.addClass(ghost, 'noty_fix_effects_height');\n Utils.addListener(ghost, Utils.animationEndEvents, function () {\n Utils.remove(ghost);\n });\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction build(ref) {\n findOrCreateContainer(ref);\n\n var markup = '<div class=\"noty_body\">' + ref.options.text + '</div>' + buildButtons(ref) + '<div class=\"noty_progressbar\"></div>';\n\n ref.barDom = document.createElement('div');\n ref.barDom.setAttribute('id', ref.id);\n Utils.addClass(ref.barDom, 'noty_bar noty_type__' + ref.options.type + ' noty_theme__' + ref.options.theme);\n\n ref.barDom.innerHTML = markup;\n\n fire(ref, 'onTemplate');\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {boolean}\r\n */\nfunction hasButtons(ref) {\n return !!(ref.options.buttons && Object.keys(ref.options.buttons).length);\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {string}\r\n */\nfunction buildButtons(ref) {\n if (hasButtons(ref)) {\n var buttons = document.createElement('div');\n Utils.addClass(buttons, 'noty_buttons');
155\n\n Object.keys(ref.options.buttons).forEach(function (key) {\n buttons.appendChild(ref.options.buttons[key].dom);\n });\n\n ref.options.buttons.forEach(function (btn) {\n buttons.appendChild(btn.dom);\n });\n return buttons.outerHTML;\n }\n return '';\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction handleModal(ref) {\n if (ref.options.modal) {\n if (DocModalCount === 0) {\n createModal(ref);\n }\n\n exports.DocModalCount = DocModalCount += 1;\n }\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction handleModalClose(ref) {\n if (ref.options.modal && DocModalCount > 0) {\n exports.DocModalCount = DocModalCount -= 1;\n\n if (DocModalCount <= 0) {\n var modal = document.querySelector('.noty_modal');\n\n if (modal) {\n Utils.removeClass(modal, 'noty_modal_open');\n Utils.addClass(modal, 'noty_modal_close');\n Utils.addListener(modal, Utils.animationEndEvents, function () {\n Utils.remove(modal);\n });\n }\n }\n }\n}\n\n/**\r\n * @return {void}\r\n */\nfunction createModal() {\n var body = document.querySelector('body');\n var modal = document.createElement('div');\n Utils.addClass(modal, 'noty_modal');\n body.insertBefore(modal, body.firstChild);\n Utils.addClass(modal, 'noty_modal_open');\n\n Utils.addListener(modal, Utils.animationEndEvents, function () {\n Utils.removeClass(modal, 'noty_modal_open');\n });\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction findOrCreateContainer(ref) {\n if (ref.options.container) {\n ref.layoutDom = document.querySelector(ref.options.container);\n return;\n }\n\n var layoutID = 'noty_layout__' + ref.options.layout;\n ref.layoutDom = document.querySelector('div#' + layoutID);\n\n if (!ref.layoutDom) {\n ref.layoutDom = document.createElement('div');\n ref.layoutDom.setAttribute('id', layoutID);\n ref.layoutDom.setAttribute('role', 'alert');\n ref.layoutDom.setAttribute('aria-live', 'polite');\n Utils.addClass(ref.layoutDom, 'noty_layout');\n document.querySelector('body').appendChild(ref.layoutDom);\n }\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction queueClose(ref) {\n if (ref.options.timeout) {\n if (ref.options.progressBar && ref.progressDom) {\n Utils.css(ref.progressDom, {\n transition: 'width ' + ref.options.timeout + 'ms linear',\n width: '0%'\n });\n }\n\n clearTimeout(ref.closeTimer);\n\n ref.closeTimer = setTimeout(function () {\n ref.close();\n }, ref.options.timeout);\n }\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction dequeueClose(ref) {\n if (ref.options.timeout && ref.closeTimer) {\n clearTimeout(ref.closeTimer);\n ref.closeTimer = -1;\n\n if (ref.options.progressBar && ref.progressDom) {\n Utils.css(ref.progressDom, {\n transition: 'width 0ms linear',\n width: '100%'\n });\n }\n }\n}\n\n/**\r\n * @param {Noty} ref\r\n * @param {string} eventName\r\n * @return {void}\r\n */\nfunction fire(ref, eventName) {\n if (ref.listeners.hasOwnProperty(eventName)) {\n ref.listeners[eventName].forEach(function (cb) {\n if (typeof cb === 'function') {\n cb.apply(ref);\n }\n });\n }\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction openFlow(ref) {\n fire(ref, 'afterShow');\n queueClose(ref);\n\n Utils.addListener(ref.barDom, 'mouseenter', function () {\n dequeueClose(ref);\n });\n\n Utils.addListener(ref.barDom, 'mouseleave', function () {\n queueClose(ref);\n });\n}\n\n/**\r\n * @param {Noty} ref\r\n * @return {void}\r\n */\nfunction closeFlow(ref) {\n delete Store[ref.id];\n ref.closing = false;\n fire(ref, 'afterClose');\n\n Utils.remove(ref.barDom);\n\n if (ref.layoutDom.querySelectorAll('.noty_bar').length === 0 && !ref.options.container) {\n Utils.remove(ref.layoutDom);\n }\n\n if (Utils.inArray('docVisible', ref.options.titleCount.conditions) || Utils.inArray('docHidden', ref.options.titleCount.conditions)) {\n docTitle.decrement
155();\n }\n\n queueRender(ref.options.queue);\n}\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.NotyButton = undefined;\n\nvar _utils = __webpack_require__(0);\n\nvar Utils = _interopRequireWildcard(_utils);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar NotyButton = exports.NotyButton = function NotyButton(html, classes, cb) {\n var _this = this;\n\n var attributes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n\n _classCallCheck(this, NotyButton);\n\n this.dom = document.createElement('button');\n this.dom.innerHTML = html;\n this.id = attributes.id = attributes.id || Utils.generateID('button');\n this.cb = cb;\n Object.keys(attributes).forEach(function (propertyName) {\n _this.dom.setAttribute(propertyName, attributes[propertyName]);\n });\n Utils.addClass(this.dom, classes || 'noty_btn');\n\n return this;\n};\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Push = exports.Push = function () {\n function Push() {\n var workerPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/service-worker.js';\n\n _classCallCheck(this, Push);\n\n this.subData = {};\n this.workerPath = workerPath;\n this.listeners = {\n onPermissionGranted: [],\n onPermissionDenied: [],\n onSubscriptionSuccess: [],\n onSubscriptionCancel: [],\n onWorkerError: [],\n onWorkerSuccess: [],\n onWorkerNotSupported: []\n };\n return this;\n }\n\n /**\r\n * @param {string} eventName\r\n * @param {function} cb\r\n * @return {Push}\r\n */\n\n\n _createClass(Push, [{\n key: 'on',\n value: function on(eventName) {\n var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};\n\n if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) {\n this.listeners[eventName].push(cb);\n }\n\n return this;\n }\n }, {\n key: 'fire',\n value: function fire(eventName) {\n var _this = this;\n\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n if (this.listeners.hasOwnProperty(eventName)) {\n this.listeners[eventName].forEach(function (cb) {\n if (typeof cb === 'function') {\n cb.apply(_this, params);\n }\n });\n }\n }\n }, {\n key: 'create',\n value: function create() {\n console.log('NOT IMPLEMENTED YET');\n }\n\n /**\r\n * @return {boolean}\r\n */\n\n }, {\n key: 'isSupported',\n value: function isSupported() {\n var result = false;\n\n try {\n result = window.Notification || window.webkitNotifications || navigator.mozNotification || window.external && window.external.msIsSiteMode() !== undefined;\n } catch (e) {}\n\n return result;\n }\n\n /**\r\n * @return {string}\r\n */\n\n }, {\n key: 'getPermissionStatus',\n value: function getPermissionStatus() {\n var perm = 'default';\n\n if (window.Notification && window.Notification.permissionLevel) {\n perm = window.Notification.permissionLevel;\n } else if (window.webkitNotifications && window.webkitNotifications.checkPermission) {\n switch (window.webkitNotifications.checkPermission()) {\n case 1:\n perm = 'default';\n break;\n case 0:\n perm = 'granted';\n break;\n default:\n perm = 'denied';\n }\n } else if (window.Notification && window.Notification.permission) {\n perm = window.Notification.permission;\n } else if (navigator.mozNotification) {\n perm = 'granted';\n } else if (window.external && window.external.msIsSiteMode() !== undefined) {\n perm = window.external.msIsSiteMode() ? 'granted' : 'default';\n }\n\n return perm.toString().toLowerCase();\n }\n\n /**\r\n * @return {string}\r\n */\n\n }, {\n key: 'getEndpoint',\n value: function getEndpoint(subscription) {\n var endpoint = subscription.endpoint;\n var subscriptionId = subscription.subscriptionId;\n\n // fix for Chrome < 45\n if (subscriptionId && endpoint.indexOf(subscriptionId) === -1) {\n endpoint += '/' + subscriptionId;\n }\n\n return endpoint;\n }\n\n /**\r\n * @return {boolean}\r\n */\n\n }, {\n key: 'isSWRegistered',\n value: function isSWRegistered() {\
155n try {\n return navigator.serviceWorker.controller.state === 'activated';\n } catch (e) {\n return false;\n }\n }\n\n /**\r\n * @return {void}\r\n */\n\n }, {\n key: 'unregisterWorker',\n value: function unregisterWorker() {\n var self = this;\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.getRegistrations().then(function (registrations) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = registrations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var registration = _step.value;\n\n registration.unregister();\n self.fire('onSubscriptionCancel');\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n });\n }\n }\n\n /**\r\n * @return {void}\r\n */\n\n }, {\n key: 'requestSubscription',\n value: function requestSubscription() {\n var _this2 = this;\n\n var userVisibleOnly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n var self = this;\n var current = this.getPermissionStatus();\n var cb = function cb(result) {\n if (result === 'granted') {\n _this2.fire('onPermissionGranted');\n\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.register(_this2.workerPath).then(function () {\n navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {\n self.fire('onWorkerSuccess');\n serviceWorkerRegistration.pushManager.subscribe({\n userVisibleOnly: userVisibleOnly\n }).then(function (subscription) {\n var key = subscription.getKey('p256dh');\n var token = subscription.getKey('auth');\n\n self.subData = {\n endpoint: self.getEndpoint(subscription),\n p256dh: key ? window.btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,\n auth: token ? window.btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null\n };\n\n self.fire('onSubscriptionSuccess', [self.subData]);\n }).catch(function (err) {\n self.fire('onWorkerError', [err]);\n });\n });\n });\n } else {\n self.fire('onWorkerNotSupported');\n }\n } else if (result === 'denied') {\n _this2.fire('onPermissionDenied');\n _this2.unregisterWorker();\n }\n };\n\n if (current === 'default') {\n if (window.Notification && window.Notification.requestPermission) {\n window.Notification.requestPermission(cb);\n } else if (window.webkitNotifications && window.webkitNotifications.checkPermission) {\n window.webkitNotifications.requestPermission(cb);\n }\n } else {\n cb(current);\n }\n }\n }]);\n\n return Push;\n}();\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(process, global) {var require;/*!\n * @overview es6-promise - a tiny implementation of Promises/A+.\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)\n * @license Licensed under MIT license\n * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE\n * @version 4.1.1\n */\n\n(function (global, factory) {\n\t true ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.ES6Promise = factory());\n}(this, (function () { 'use strict';\n\nfunction objectOrFunction(x) {\n var type = typeof x;\n return x !== null && (type === 'object' || type === 'function');\n}\n\nfunction isFunction(x) {\n return typeof x === 'function';\n}\n\nvar _isArray = undefined;\nif (Array.isArray) {\n _isArray = Array.isArray;\n} else {\n _isArray = function (x) {\n return Object.prototype.toString.call(x) === '[object Array]';\n };\n}\n\nvar isArray = _isArray;\n\nvar len = 0;\nvar vertxNext = undefined;\nvar customSchedulerFn = undefined;\n\nvar asap = function asap(callback, arg) {\n queue[len] = callback;\n queue[len + 1] = arg;\n len += 2;\n if (len === 2) {\n // If len is 2, that means that we need to schedule an async flush.\n // If additional callbacks are queued before the queue is flushed, they\n // will be processed by this flush that we are scheduling.\n if (customSchedulerFn) {\n customSchedulerFn(flush);\n } else {\n scheduleFlush();\n }\n }\n};\n\nfunction setScheduler(scheduleFn) {\n customSchedulerFn = scheduleFn;\n}\n\nfunction setAsap(asapFn) {\n asap = asapFn;\n}\n\nvar browserWindow = typeof window !== 'undefined' ? window : undefined;\nvar browserGlobal = browserWindow || {};\nvar BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;\nvar isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';\n\n// test for web worker but not in IE10\nvar isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
155\n\n// node\nfunction useNextTick() {\n // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n // see https://github.com/cujojs/when/issues/410 for details\n return function () {\n return process.nextTick(flush);\n };\n}\n\n// vertx\nfunction useVertxTimer() {\n if (typeof vertxNext !== 'undefined') {\n return function () {\n vertxNext(flush);\n };\n }\n\n return useSetTimeout();\n}\n\nfunction useMutationObserver() {\n var iterations = 0;\n var observer = new BrowserMutationObserver(flush);\n var node = document.createTextNode('');\n observer.observe(node, { characterData: true });\n\n return function () {\n node.data = iterations = ++iterations % 2;\n };\n}\n\n// web worker\nfunction useMessageChannel() {\n var channel = new MessageChannel();\n channel.port1.onmessage = flush;\n return function () {\n return channel.port2.postMessage(0);\n };\n}\n\nfunction useSetTimeout() {\n // Store setTimeout reference so es6-promise will be unaffected by\n // other code modifying setTimeout (like sinon.useFakeTimers())\n var globalSetTimeout = setTimeout;\n return function () {\n return globalSetTimeout(flush, 1);\n };\n}\n\nvar queue = new Array(1000);\nfunction flush() {\n for (var i = 0; i < len; i += 2) {\n var callback = queue[i];\n var arg = queue[i + 1];\n\n callback(arg);\n\n queue[i] = undefined;\n queue[i + 1] = undefined;\n }\n\n len = 0;\n}\n\nfunction attemptVertx() {\n try {\n var r = require;\n var vertx = __webpack_require__(9);\n vertxNext = vertx.runOnLoop || vertx.runOnContext;\n return useVertxTimer();\n } catch (e) {\n return useSetTimeout();\n }\n}\n\nvar scheduleFlush = undefined;\n// Decide what async method to use to triggering processing of queued callbacks:\nif (isNode) {\n scheduleFlush = useNextTick();\n} else if (BrowserMutationObserver) {\n scheduleFlush = useMutationObserver();\n} else if (isWorker) {\n scheduleFlush = useMessageChannel();\n} else if (browserWindow === undefined && \"function\" === 'function') {\n scheduleFlush = attemptVertx();\n} else {\n scheduleFlush = useSetTimeout();\n}\n\nfunction then(onFulfillment, onRejection) {\n var _arguments = arguments;\n\n var parent = this;\n\n var child = new this.constructor(noop);\n\n if (child[PROMISE_ID] === undefined) {\n makePromise(child);\n }\n\n var _state = parent._state;\n\n if (_state) {\n (function () {\n var callback = _arguments[_state - 1];\n asap(function () {\n return invokeCallback(_state, child, callback, parent._result);\n });\n })();\n } else {\n subscribe(parent, child, onFulfillment, onRejection);\n }\n\n return child;\n}\n\n/**\n `Promise.resolve` returns a promise that will become resolved with the\n passed `value`. It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n resolve(1);\n });\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.resolve(1);\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n @method resolve\n @static\n @param {Any} value value that the returned promise will be resolved with\n Useful for tooling.\n @return {Promise} a promise that will become fulfilled with the given\n `value`\n*/\nfunction resolve$1(object) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (object && typeof object === 'object' && object.constructor === Constructor) {\n return object;\n }\n\n var promise = new Constructor(noop);\n resolve(promise, object);\n return promise;\n}\n\nvar PROMISE_ID = Math.random().toString(36).substring(16);\n\nfunction noop() {}\n\nvar PENDING = void 0;\nvar FULFILLED = 1;\nvar REJECTED = 2;\n\nvar GET_THEN_ERROR = new ErrorObject();\n\nfunction selfFulfillment() {\n return new TypeError(\"You cannot resolve a promise with itself\");\n}\n\nfunction cannotReturnOwn() {\n return new TypeError('A promises callback cannot return that same promise.');\n}\n\nfunction getThen(promise) {\n try {\n return promise.then;\n } catch (error) {\n GET_THEN_ERROR.error = error;\n return GET_THEN_ERROR;\n }\n}\n\nfunction tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {\n try {\n then$$1.call(value, fulfillmentHandler, rejectionHandler);\n } catch (e) {\n return e;\n }\n}\n\nfunction handleForeignThenable(promise, thenable, then$$1) {\n asap(function (promise) {\n var sealed = false;\n var error = tryThen(then$$1, thenable, function (value) {\n if (sealed) {\
155n return;\n }\n sealed = true;\n if (thenable !== value) {\n resolve(promise, value);\n } else {\n fulfill(promise, value);\n }\n }, function (reason) {\n if (sealed) {\n return;\n }\n sealed = true;\n\n reject(promise, reason);\n }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n if (!sealed && error) {\n sealed = true;\n reject(promise, error);\n }\n }, promise);\n}\n\nfunction handleOwnThenable(promise, thenable) {\n if (thenable._state === FULFILLED) {\n fulfill(promise, thenable._result);\n } else if (thenable._state === REJECTED) {\n reject(promise, thenable._result);\n } else {\n subscribe(thenable, undefined, function (value) {\n return resolve(promise, value);\n }, function (reason) {\n return reject(promise, reason);\n });\n }\n}\n\nfunction handleMaybeThenable(promise, maybeThenable, then$$1) {\n if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {\n handleOwnThenable(promise, maybeThenable);\n } else {\n if (then$$1 === GET_THEN_ERROR) {\n reject(promise, GET_THEN_ERROR.error);\n GET_THEN_ERROR.error = null;\n } else if (then$$1 === undefined) {\n fulfill(promise, maybeThenable);\n } else if (isFunction(then$$1)) {\n handleForeignThenable(promise, maybeThenable, then$$1);\n } else {\n fulfill(promise, maybeThenable);\n }\n }\n}\n\nfunction resolve(promise, value) {\n if (promise === value) {\n reject(promise, selfFulfillment());\n } else if (objectOrFunction(value)) {\n handleMaybeThenable(promise, value, getThen(value));\n } else {\n fulfill(promise, value);\n }\n}\n\nfunction publishRejection(promise) {\n if (promise._onerror) {\n promise._onerror
155(promise._result);\n }\n\n publish(promise);\n}\n\nfunction fulfill(promise, value) {\n if (promise._state !== PENDING) {\n return;\n }\n\n promise._result = value;\n promise._state = FULFILLED;\n\n if (promise._subscribers.length !== 0) {\n asap(publish, promise);\n }\n}\n\nfunction reject(promise, reason) {\n if (promise._state !== PENDING) {\n return;\n }\n promise._state = REJECTED;\n promise._result = reason;\n\n asap(publishRejection, promise);\n}\n\nfunction subscribe(parent, child, onFulfillment, onRejection) {\n var _subscribers = parent._subscribers;\n var length = _subscribers.length;\n\n parent._onerror = null;\n\n _subscribers[length] = child;\n _subscribers[length + FULFILLED] = onFulfillment;\n _subscribers[length + REJECTED] = onRejection;\n\n if (length === 0 && parent._state) {\n asap(publish, parent);\n }\n}\n\nfunction publish(promise) {\n var subscribers = promise._subscribers;\n var settled = promise._state;\n\n if (subscribers.length === 0) {\n return;\n }\n\n var child = undefined,\n callback = undefined,\n detail = promise._result;\n\n for (var i = 0; i < subscribers.length; i += 3) {\n child = subscribers[i];\n callback = subscribers[i + settled];\n\n if (child) {\n invokeCallback(settled, child, callback, detail);\n } else {\n callback(detail);\n }\n }\n\n promise._subscribers.length = 0;\n}\n\nfunction ErrorObject() {\n this.error = null;\n}\n\nvar TRY_CATCH_ERROR = new ErrorObject();\n\nfunction tryCatch(callback, detail) {\n try {\n return callback(detail);\n } catch (e) {\n TRY_CATCH_ERROR.error = e;\n return TRY_CATCH_ERROR;\n }\n}\n\nfunction invokeCallback(settled, promise, callback, detail) {\n var hasCallback = isFunction(callback),\n value = undefined,\n error = undefined,\n succeeded = undefined,\n failed = undefined;\n\n if (hasCallback) {\n value = tryCatch(callback, detail);\n\n if (value === TRY_CATCH_ERROR) {\n failed = true;\n error = value.error;\n value.error = null;\n } else {\n succeeded = true;\n }\n\n if (promise === value) {\n reject(promise, cannotReturnOwn());\n return;\n }\n } else {\n value = detail;\n succeeded = true;\n }\n\n if (promise._state !== PENDING) {\n // noop\n } else if (hasCallback && succeeded) {\n resolve(promise, value);\n } else if (failed) {\n reject(promise, error);\n } else if (settled === FULFILLED) {\n fulfill(promise, value);\n } else if (settled === REJECTED) {\n reject(promise, value);\n }\n}\n\nfunction initializePromise(promise, resolver) {\n try {\n resolver(function resolvePromise(value) {\n resolve(promise, value);\n }, function rejectPromise(reason) {\n reject(promise, reason);\n });\n } catch (e) {\n reject(promise, e);\n }\n}\n\nvar id = 0;\nfunction nextId() {\n return id++;\n}\n\nfunction makePromise(promise) {\n promise[PROMISE_ID] = id++;\n promise._state = undefined;\n promise._result = undefined;\n promise._subscribers = [];\n}\n\nfunction Enumerator$1(Constructor, input) {\n this._instanceConstructor = Constructor;\n this.promise = new Constructor(noop);\n\n if (!this.promise[PROMISE_ID]) {\n makePromise(this.promise);\n }\n\n if (isArray(input)) {\n this.length = input.length;\n this._remaining = input.length;\n\n this._result = new Array(this.length);\n\n if (this.length === 0) {\n fulfill(this.promise, this._result);\n } else {\n this.length = this.length || 0;\n this._enumerate(input);\n if (this._remaining === 0) {\n fulfill(this.promise, this._result);\n }\n }\n } else {\n reject(this.promise, validationError());\n }\n}\n\nfunction validationError() {\n return new Error('Array Methods must be provided an Array');\n}\n\nEnumerator$1.prototype._enumerate = function (input) {\n for (var i = 0; this._state === PENDING && i < input.length; i++) {\n this._eachEntry(input[i], i);\n }\n};\n\nEnumerator$1.prototype._eachEntry = function (entry, i) {\n var c = this._instanceConstructor;\n var resolve$$1 = c.resolve;\n\n if (resolve$$1 === resolve$1) {\n var _then = getThen(entry);\n\n if (_then === then && entry._state !== PENDING) {\n this._settledAt(entry._state, i, entry._result);\n } else if (typeof _then !== 'function') {\n this._remaining--;\n this._result[i] = entry;\n } else if (c === Promise$2) {\n var promise = new c(noop);\n handleMaybeThenable(promise, entry, _then);\n this._willSettleAt(promise, i);\n }
155 else {\n this._willSettleAt(new c(function (resolve$$1) {\n return resolve$$1(entry);\n }), i);\n }\n } else {\n this._willSettleAt(resolve$$1(entry), i);\n }\n};\n\nEnumerator$1.prototype._settledAt = function (state, i, value) {\n var promise = this.promise;\n\n if (promise._state === PENDING) {\n this._remaining--;\n\n if (state === REJECTED) {\n reject(promise, value);\n } else {\n this._result[i] = value;\n }\n }\n\n if (this._remaining === 0) {\n fulfill(promise, this._result);\n }\n};\n\nEnumerator$1.prototype._willSettleAt = function (promise, i) {\n var enumerator = this;\n\n subscribe(promise, undefined, function (value) {\n return enumerator._settledAt(FULFILLED, i, value);\n }, function (reason) {\n return enumerator._settledAt(REJECTED, i, reason);\n });\n};\n\n/**\n `Promise.all` accepts an array of promises, and returns a new promise which\n is fulfilled with an array of fulfillment values for the passed promises, or\n rejected with the reason of the first passed promise to be rejected. It casts all\n elements of the passed iterable to promises as it runs this algorithm.\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = resolve(2);\n let promise3 = resolve(3);\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // The array here would be [ 1, 2, 3 ];\n });\n ```\n\n If any of the `promises` given to `all` are rejected, the first promise\n that is rejected will be given as an argument to the returned promises's\n rejection handler. For example:\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = reject(new Error(\"2\"));\n let promise3 = reject(new Error(\"3\"));\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // Code here never runs because there are rejected promises!\n }, function(error) {\n // error.message === \"2\"\n });\n ```\n\n @method all\n @static\n @param {Array} entries array of promises\n @param {String} label optional string for labeling the promise.\n Useful for tooling.\n @return {Promise} promise that is fulfilled when all `promises` have been\n fulfilled, or rejected if any of them become rejected.\n @static\n*/\nfunction all$1(entries) {\n return new Enumerator$1(this, entries).promise;\n}\n\n/**\n `Promise.race` returns a new promise which is settled in the same way as the\n first passed promise to settle.\n\n Example:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 1');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 2');\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // result === 'promise 2' because it was resolved before promise1\n // was resolved.\n });\n ```\n\n `Promise.race` is deterministic in that only the state of the first\n settled promise matters. For example, even if other promises given to the\n `promises` array argument are resolved, but the first settled promise has\n become rejected before the other promises became fulfilled, the returned\n promise will become rejected:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 1');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n reject(new Error('promise 2'));\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // Code here never runs\n }, function(reason){\n // reason.message === 'promise 2' because promise 2 be
155came rejected before\n // promise 1 became fulfilled\n });\n ```\n\n An example real-world use case is implementing timeouts:\n\n ```javascript\n Promise.race([ajax('foo.json'), timeout(5000)])\n ```\n\n @method race\n @static\n @param {Array} promises array of promises to observe\n Useful for tooling.\n @return {Promise} a promise which settles in the same way as the first passed\n promise to settle.\n*/\nfunction race$1(entries) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (!isArray(entries)) {\n return new Constructor(function (_, reject) {\n return reject(new TypeError('You must pass an array to race.'));\n });\n } else {\n return new Constructor(function (resolve, reject) {\n var length = entries.length;\n for (var i = 0; i < length; i++) {\n Constructor.resolve(entries[i]).then(resolve, reject);\n }\n });\n }\n}\n\n/**\n `Promise.reject` returns a promise rejected with the passed `reason`.\n It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n reject(new Error('WHOOPS'));\n });\n\n promise.then(function(value){\n // Code here doesn't run because the promise is rejected!\n }, function(reason){\n // reason.message === 'WHOOPS'\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.reject(new Error('WHOOPS'));\n\n promise.then(function(value){\n // Code here doesn't run because the promise is rejected!\n }, function(reason){\n // reason.message === 'WHOOPS'\n });\n ```\n\n @method reject\n @static\n @param {Any} reason value that the returned promise will be rejected with.\n Useful for tooling.\n @return {Promise} a promise rejected with the given `reason`.\n*/\nfunction reject$1(reason) {\n /*jshint validthis:true */\n var Constructor = this;\n var promise = new Constructor(noop);\n reject(promise, reason);\n return promise;\n}\n\nfunction needsResolver() {\n throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n}\n\nfunction needsNew() {\n throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object c
155onstructor cannot be called as a function.\");\n}\n\n/**\n Promise objects represent the eventual result of an asynchronous operation. The\n primary way of interacting with a promise is through its `then` method, which\n registers callbacks to receive either a promise's eventual value or the reason\n why the promise cannot be fulfilled.\n\n Terminology\n -----------\n\n - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n - `thenable` is an object or function that defines a `then` method.\n - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n - `exception` is a value that is thrown using the throw statement.\n - `reason` is a value that indicates why a promise was rejected.\n - `settled` the final resting state of a promise, fulfilled or rejected.\n\n A promise can be in one of three states: pending, fulfilled, or rejected.\n\n Promises that are fulfilled have a fulfillment value and are in the fulfilled\n state. Promises that are rejected have a rejection reason and are in the\n rejected state. A fulfillment value is never a thenable.\n\n Promises can also be said to *resolve* a value. If this value is also a\n promise, then the original promise's settled state will match the value's\n settled state. So a promise that *resolves* a promise that rejects will\n itself reject, and a promise that *resolves* a promise that fulfills will\n itself fulfill.\n\n\n Basic Usage:\n ------------\n\n ```js\n let promise = new Promise(function(resolve, reject) {\n // on success\n resolve(value);\n\n // on failure\n reject(reason);\n });\n\n promise.then(function(value) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Advanced Usage:\n ---------------\n\n Promises shine when abstracting away asynchronous interactions such as\n `XMLHttpRequest`s.\n\n ```js\n function getJSON(url) {\n return new Promise(function(resolve, reject){\n let xhr = new XMLHttpRequest();\n\n xhr.open('GET', url);\n xhr.onreadystatechange = handler;\n xhr.responseType = 'json';\n xhr.setRequestHeader('Accept', 'application/json');\n xhr.send();\n\n function handler() {\n if (this.readyState === this.DONE) {\n if (this.status === 200) {\n resolve(this.response);\n } else {\n reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));\n }\n }\n };\n });\n }\n\n getJSON('/posts.json').then(function(json) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Unlike callbacks, promises are great composable primitives.\n\n ```js\n Promise.all([\n getJSON('/posts'),\n getJSON('/comments')\n ]).then(function(values){\n values[0] // => postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise$2(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise$2 ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise$2.all = all$1;\nPromise$2.race = race$1;\nPromise$2.resolve = resolve$1;\nPromise$2.reject = reject$1;\nPromise$2._setScheduler = setScheduler;\nPromise$2._setAsap = setAsap;\nPromise$2._asap = asap;\n\nPromise$2.prototype = {\n constructor: Promise$2,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });
155\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\n/*global self*/\nfunction polyfill$1() {\n var local = undefined;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise$2;\n}\n\n// Strange compat..\nPromise$2.polyfill = polyfill$1;\nPromise$2.Promise = Promise$2;\n\nreturn Promise$2;\n\n})));\n\n//# sourceMappingURL=es6-promise.map\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7), __webpack_require__(8)))\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global VERSION */\n\n__webpack_require__(5);\n\nvar _es6Promise = __webpack_require__(4);
155\n\nvar _es6Promise2 = _interopRequireDefault(_es6Promise);\n\nvar _utils = __webpack_require__(0);\n\nvar Utils = _interopRequireWildcard(_utils);\n\nvar _api = __webpack_require__(1);\n\nvar API = _interopRequireWildcard(_api);\n\nvar _button = __webpack_require__(2);\n\nvar _push = __webpack_require__(3);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Noty = function () {\n /**\n * @param {object} options\n * @return {Noty}\n */\n function Noty() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n _classCallCheck(this, Noty);\n\n this.options = Utils.deepExtend({}, API.Defaults, options);\n\n if (API.Store[this.options.id]) {\n return API.Store[this.options.id];\n }\n\n this.id = this.options.id || Utils.generateID('bar');\n this.closeTimer = -1;\n this.barDom = null;\n this.layoutDom = null;\n this.progressDom = null;\n this.showing = false;\n this.shown = false;\n this.closed = false;\n this.closing = false;\n this.killable = this.options.timeout || this.options.closeWith.length > 0;\n this.hasSound = this.options.sounds.sources.length > 0;\n this.soundPlayed = false;\n this.listeners = {\n beforeShow: [],\n onShow: [],\n afterShow: [],\n onClose: [],\n afterClose: [],\n onClick: [],\n onHover: [],\n onTemplate: []\n };\n this.promises = {\n show: null,\n close: null\n };\n this.on('beforeShow', this.options.callbacks.beforeShow);\n this.on('onShow', this.options.callbacks.onShow);\n this.on('afterShow', this.options.callbacks.afterShow);\n this.on('onClose', this.options.callbacks.onClose);\n this.on('afterClose', this.options.callbacks.afterClose);\n this.on('onClick', this.options.callbacks.onClick);\n this.on('onHover', this.options.callbacks.onHover);\n this.on('onTemplate', this.options.callbacks.onTemplate);\n\n return this;\n }\n\n /**\n * @param {string} eventName\n * @param {function} cb\n * @return {Noty}\n */\n\n\n _createClass(Noty, [{\n key: 'on',\n value: function on(eventName) {\n var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};\n\n if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) {\n this.listeners[eventName].push(cb);\n }\n\n return this;\n }\n\n /**\n * @return {Noty}\n */\n\n }, {\n key: 'show',\n value: function show() {\n var _this = this;\n\n if (this.showing || this.shown) {\n return this; // preventing multiple show\n }\n\n if (this.options.killer === true) {\n Noty.closeAll();\n } else if (typeof this.options.killer === 'string') {\n Noty.closeAll(this.options.killer);\n }\n\n var queueCounts = API.getQueueCounts(this.options.queue);\n\n if (queueCounts.current >= queueCounts.maxVisible || API.PageHidden && this.options.visibilityControl) {\n API.addToQueue(this);\n\n if (API.PageHidden && this.hasSound && Utils.inArray('docHidden', this.options.sounds.conditions)) {\n Utils.createAudioElements(this);\n }\n\n if (API.PageHidden && Utils.inArray('docHidden', this.options.titleCount.conditions)) {\n API.docTitle.increment();\n }\n\n return this;\n }\n\n API.Store[this.id] = this;\n\n API.fire(this, 'beforeShow');\n\n this.showing = true;\n\n if (this.closing) {\n this.showing = false;\n return this;\n }\n\n API.build(this);\n API.handleModal(this);\n\n if (this.options.force) {\n this.layoutDom.insertBefore(this.barDom, this.layoutDom.firstChild);\n } else {\n this.layoutDom.appendChild(this.barDom);\n }\n\n if (this.hasSound && !this.soundPlayed && Utils.inArray('docVisible', this.options.sounds.conditions)) {\n Utils.createAudioElements(this);\n }\n\n if (Utils.inArray('docVisible', this.options.titleCount.conditions)) {\n API.docTitle.increment();\n }\n\n this.shown = true;\n this.closed = false;\n\n // bind button events if any\n if (API.hasButtons(this)) {\n Object.keys(this.options.buttons).forEac
155h(function (key) {\n var btn = _this.barDom.querySelector('#' + _this.options.buttons[key].id);\n Utils.addListener(btn, 'click', function (e) {\n Utils.stopPropagation(e);\n _this.options.buttons[key].cb(_this);\n });\n });\n }\n\n this.progressDom = this.barDom.querySelector('.noty_progressbar');\n\n if (Utils.inArray('click', this.options.closeWith)) {\n Utils.addClass(this.barDom, 'noty_close_with_click');\n Utils.addListener(this.barDom, 'click', function (e) {\n Utils.stopPropagation(e);\n API.fire(_this, 'onClick');\n _this.close();\n }, false);\n }\n\n Utils.addListener(this.barDom, 'mouseenter', function () {\n API.fire(_this, 'onHover');\n }, false);\n\n if (this.options.timeout) Utils.addClass(this.barDom, 'noty_has_timeout');\n if (this.options.progressBar) {\n Utils.addClass(this.barDom, 'noty_has_progressbar');\n }\n\n if (Utils.inArray('button', this.options.closeWith)) {\n Utils.addClass(this.barDom, 'noty_close_with_button');\n\n var closeButton = document.createElement('div');\n Utils.addClass(closeButton, 'noty_close_button');\n closeButton.innerHTML = '×';\n this.barDom.appendChild(closeButton);\n\n Utils.addListener(closeButton, 'click', function (e) {\n Utils.stopPropagation(e);\n _this.close();\n }, false);\n }\n\n API.fire(this, 'onShow');\n\n if (this.options.animation.open === null) {\n this.promises.show = new _es6Promise2.default(function (resolve) {\n resolve();\n });\n } else if (typeof this.options.animation.open === 'function') {\n this.promises.show = new _es6Promise2.default(this.options.animation.open.bind(this));\n } else {\n Utils.addClass(this.barDom, this.options.animation.open);\n this.promises.show = new _es6Promise2.default(function (resolve) {\n Utils.addListener(_this.barDom, Utils.animationEndEvents, function () {\n Utils.removeClass(_this.barDom, _this.options.animation.open);\n resolve();\n });\n });\n }\n\n this.promises.show.then(function () {\n var _t = _this;\n setTimeout(function () {\n API.openFlow(_t);\n }, 100);\n });\n\n return this;\n }\n\n /**\n * @return {Noty}\n */\n\n }, {\n key: 'stop',\n value: function stop() {\n API.dequeueClose(this);\n return this;\n }\n\n /**\n * @return {Noty}\n */\n\n }, {\n key: 'resume',\n value: function resume() {\n API.queueClose(this);\n return this;\n }\n\n /**\n * @param {int|boolean} ms\n * @return {Noty}\n */\n\n }, {\n key: 'setTimeout',\n value: function (_setTimeout) {\n function setTimeout(_x) {\n return _setTimeout.apply(this, arguments);\n }\n\n setTimeout.toString = function () {\n return _setTimeout.toString();\n };\n\n return setTimeout;\n }(function (ms) {\n this.stop();\n this.options.timeout = ms;\n\n if (this.barDom) {\n if (this.options.timeout) {\n Utils.addClass(this.barDom, 'noty_has_timeout');\n } else {\n Utils.removeClass(this.barDom, 'noty_has_timeout');\n }\n\n var _t = this;\n setTimeout(function () {\n // ugly fix for progressbar display bug\n _t.resume();\n }, 100);\n }\n\n return this;\n })\n\n /**\n * @param {string} html\n * @param {boolean} optionsOverride\n * @return {Noty}\n */\n\n }, {\n key: 'setText',\n value: function setText(html) {\n var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (this.barDom) {\n this.barDom.querySelector('.noty_body').innerHTML = html;\n }\n\n if (optionsOverride) this.options.text = html;\n\n return this;\n }\n\n /**\n * @param {string} type\n * @param {boolean} optionsOverride\n * @return {Noty}\n */\n\n }, {\n key: 'setType',\n value: function setType(type) {\n var _this2 = this;\n\n var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (this.barDom) {\n var classList = Utils.classList(this.barDom).split(' ');\n\n classList.forEach(function (c) {\n if (c.substring(0, 11) === 'noty_type__') {\n Utils.removeClass(_this2.barDom, c);\n }\n });\n\n Utils.addClass(this.barDom, 'noty_type__' + type);\n }\n\n if (optionsOverride) this.options.type = type;\n\n return this;\n }\n\n /**\n * @param {string} theme\n * @param {boolean} optionsOverride\n * @return {Noty}\n */\n\n }, {\n key: 'setTheme',\n value: function setTheme(theme) {\n var _this3 = this;\n\n var optionsOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (this.barDom) {\n var classList = Utils.classList(this.barDom).split(' ');\n\n classList.forEach(function (c) {\n if (c.substring(0, 12) === 'noty_theme__') {\n Utils.removeClass(_this3.barDom, c);\n }\n });\n\n Utils.addClass(this.barDom, 'noty_theme__' + theme);\n }\n\n if (optionsOverride) this.options.theme = theme;\n\n return this;\n }\n\n /**\n * @return {Noty}\n */\n\n }, {\n key: 'close',\n value: function close() {\n var _this4 = this;\n\n if (this.closed) return this;\n\n if (!this.shown) {\n // it's in the queue\n API.removeFromQueue(this);\n return this;\n }\n\n API.fire(this, 'onClose');\n\n this.closing = true;\n\n if (this.options.animation.close === null || this.options.animation.close === false) {\n this.promises.close = new _es6Promise2.default(function (resolve) {\n resolve();\n });\n } else if (typeof this.options.animation.close === 'function') {\n this.promises.close = new _es6Promise2.default(this.options.animation.close.bind(this));\n } else {\n Utils.addClass(this.barDom, this.options.animation.close);\n this.promises.close = new _es6Promise2.default(function (resolve) {\n Utils.addListener(_this4.barDom, Utils.animationEndEvents, function () {\n if (_this4.options.force) {\n Utils.remove(_this4.barDom);\n } else {\n API.ghostFix(_this4);\n }\n resolve();\n });\n });\n }\n\n this.promises.close.then(function () {\n API.closeFlow(_this4);\n API.handleModalClose(_this4);\n });\n\n this.closed = true;\n\n return this;\n }\n\n // API functions\n\n /**\n * @param {boolean|string} queueName\n * @return {Noty}\n */\n\n }], [{\n key: 'closeAll',\n value: function closeAll() {\n var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n\n Object.keys(API.Store).forEach(function (id) {\n if (queueName) {\n if (API.Store[id].options.queue === queueName && API.Store[id].killable) {\n API.Store[id].close();\n }\n } else if (API.Store[id].killable) {\n API.Store[id].close();\n }\n });\n return this;\n }\n\n /**\n * @param {string} queueName\n * @return {Noty}\n */\n\n }, {\n key: 'clearQueue',\n value: function clearQueue() {\n var queueName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'global';
155\n\n if (API.Queues.hasOwnProperty(queueName)) {\n API.Queues[queueName].queue = [];\n }\n return this;\n }\n\n /**\n * @return {API.Queues}\n */\n\n }, {\n key: 'overrideDefaults',\n\n\n /**\n * @param {Object} obj\n * @return {Noty}\n */\n value: function overrideDefaults(obj) {\n API.Defaults = Utils.deepExtend({}, API.Defaults, obj);\n return this;\n }\n\n /**\n * @param {int} amount\n * @param {string} queueName\n * @return {Noty}\n */\n\n }, {\n key: 'setMaxVisible',\n value: function setMaxVisible() {\n var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : API.DefaultMaxVisible;\n var queueName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'global';\n\n if (!API.Queues.hasOwnProperty(queueName)) {\n API.Queues[queueName] = { maxVisible: amount, queue: [] };\n }\n\n API.Queues[queueName].maxVisible = amount;\n return this;\n }\n\n /**\n * @param {string} innerHtml\n * @param {String} classes\n * @param {Function} cb\n * @param {Object} attributes\n * @return {NotyButton}\n */\n\n }, {\n key: 'button',\n value: function button(innerHtml) {\n var classes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n var cb = arguments[2];\n var attributes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n\n return new _button.NotyButton(innerHtml, classes, cb, attributes);\n }\n\n /**\n * @return {string}\n */\n\n }, {\n key: 'version',\n value: function version() {\n return \"3.2.0-beta\";\n }\n\n /**\n * @param {String} workerPath\n * @return {Push}\n */\n\n }, {\n key: 'Push',\n value: function Push(workerPath) {\n return new _push.Push(workerPath);\n }\n }, {\n key: 'Queues',\n get: function get() {\n return API.Queues;\n }\n\n /**\n * @return {API.PageHidden}\n */\n\n }, {\n key: 'PageHidden',\n get: function get() {\n return API.PageHidden;\n }\n }]);\n\n return Noty;\n}();\n\n// Document visibility change controller\n\n\nexports.default = Noty;\nif (typeof window !== 'undefined') {\n Utils.visibilityChangeFlow();\n}\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;
155\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\nvar g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports) {\n\n/* (ignored) */\n\n/***/ })\n/******/ ]);\n});\n//# sourceMappingURL=noty.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9ub3R5L2xpYi9ub3R5LmpzP2NiZjMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogXHJcbiAgQHBhY2thZ2UgTk9UWSAtIERlcGVuZGVuY3ktZnJlZSBub3RpZmljYXRpb24gbGlicmFyeSBcclxuICBAdmVyc2lvbiB2ZXJzaW9uOiAzLjIuMC1iZXRhIFxyXG4gIEBjb250cmlidXRvcnMgaHR0cHM6Ly9naXRodWIuY29tL25lZWRpbS9ub3R5L2dyYXBocy9jb250cmlidXRvcnMgXHJcbiAgQGRvY3VtZW50YXRpb24gRXhhbXBsZXMgYW5kIERvY3VtZW50YXRpb24gLSBodHRwczovL25lZC5pbS9ub3R5IFxyXG4gIEBsaWNlbnNlIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZXM6IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwIFxyXG4qL1xyXG5cclxuKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoXCJOb3R5XCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIk5vdHlcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wiTm9
1550eVwiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0aTogbW9kdWxlSWQsXG4vKioqKioqLyBcdFx0XHRsOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbi8qKioqKiovIFx0XHRtb2R1bGUubCA9IHRydWU7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBpZGVudGl0eSBmdW5jdGlvbiBmb3IgY2FsbGluZyBoYXJtb255IGltcG9ydHMgd2l0aCB0aGUgY29ycmVjdCBjb250ZXh0XG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uaSA9IGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbi8qKioqKiovIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuLyoqKioqKi8gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuLyoqKioqKi8gXHRcdFx0XHRnZXQ6IGdldHRlclxuLyoqKioqKi8gXHRcdFx0fSk7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4vKioqKioqLyBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbi8qKioqKiovIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4vKioqKioqLyBcdFx0cmV0dXJuIGdldHRlcjtcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDYpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jc3MgPSBleHBvcnRzLmRlZXBFeHRlbmQgPSBleHBvcnRzLmFuaW1hdGlvbkVuZEV2ZW50cyA9IHVuZGVmaW5lZDtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybi
155BvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmluQXJyYXkgPSBpbkFycmF5O1xuZXhwb3J0cy5zdG9wUHJvcGFnYXRpb24gPSBzdG9wUHJvcGFnYXRpb247XG5leHBvcnRzLmdlbmVyYXRlSUQgPSBnZW5lcmF0ZUlEO1xuZXhwb3J0cy5vdXRlckhlaWdodCA9IG91dGVySGVpZ2h0O1xuZXhwb3J0cy5hZGRMaXN0ZW5lciA9IGFkZExpc3RlbmVyO1xuZXhwb3J0cy5oYXNDbGFzcyA9IGhhc0NsYXNzO1xuZXhwb3J0cy5hZGRDbGFzcyA9IGFkZENsYXNzO1xuZXhwb3J0cy5yZW1vdmVDbGFzcyA9IHJlbW92ZUNsYXNzO1xuZXhwb3J0cy5yZW1vdmUgPSByZW1vdmU7XG5leHBvcnRzLmNsYXNzTGlzdCA9IGNsYXNzTGlzdDtcbmV4cG9ydHMudmlzaWJpbGl0eUNoYW5nZUZsb3cgPSB2aXNpYmlsaXR5Q2hhbmdlRmxvdztcbmV4cG9ydHMuY3JlYXRlQXVkaW9FbGVtZW50cyA9IGNyZWF0ZUF1ZGlvRWxlbWVudHM7XG5cbnZhciBfYXBpID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcblxudmFyIEFQSSA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9hcGkpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfVxuXG52YXIgYW5pbWF0aW9uRW5kRXZlbnRzID0gZXhwb3J0cy5hbmltYXRpb25FbmRFdmVudHMgPSAnd2Via2l0QW5pbWF0aW9uRW5kIG1vekFuaW1hdGlvbkVuZCBNU0FuaW1hdGlvbkVuZCBvYW5pbWF0aW9uZW5kIGFuaW1hdGlvbmVuZCc7XG5cbmZ1bmN0aW9uIGluQXJyYXkobmVlZGxlLCBoYXlzdGFjaywgYXJnU3RyaWN0KSB7XG4gIHZhciBrZXkgPSB2b2lkIDA7XG4gIHZhciBzdHJpY3QgPSAhIWFyZ1N0cmljdDtcblxuICBpZiAoc3RyaWN0KSB7XG4gICAgZm9yIChrZXkgaW4gaGF5c3RhY2spIHtcbiAgICAgIGlmIChoYXlzdGFjay5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGhheXN0YWNrW2tleV0gPT09IG5lZWRsZSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChrZXkgaW4gaGF5c3RhY2spIHtcbiAgICAgIGlmIChoYXlzdGFjay5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGhheXN0YWNrW2tleV0gPT09IG5lZWRsZSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzdG9wUHJvcGFnYXRpb24oZXZ0KSB7XG4gIGV2dCA9IGV2dCB8fCB3aW5kb3cuZXZlbnQ7XG5cbiAgaWYgKHR5cGVvZiBldnQuc3RvcFByb3BhZ2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSBlbHNlIHtcbiAgICBldnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgfVxufVxuXG52YXIgZGVlcEV4dGVuZCA9IGV4cG9ydHMuZGVlcEV4dGVuZCA9IGZ1bmN0aW9uIGRlZXBFeHRlbmQob3V0KSB7XG4gIG91dCA9IG91dCB8fCB7fTtcblxuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBvYmogPSBhcmd1bWVudHNbaV07XG5cbiAgICBpZiAoIW9iaikgY29udGludWU7XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqW2tleV0pKSB7XG4gICAgICAgICAgb3V0W2tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgfSBlbHNlIGlmIChfdHlwZW9mKG9ialtrZXldKSA9PT0gJ29iamVjdCcgJiYgb2JqW2tleV0gIT09IG51bGwpIHtcbiAgICAgICAgICBvdXRba2V5XSA9IGRlZXBFeHRlbmQob3V0W2tleV0sIG9ialtrZXldKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXRba2V5XSA9IG9ialtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKSB7XG4gIHZhciBwcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICcnO1xuXG4gIHZhciBpZCA9ICdub3R5XycgKyBwcmVmaXggKyAnXyc7XG5cbiAgaWQgKz0gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbiAoYykge1xuICAgIHZhciByID0gTWF0aC5yYW5kb20oKSAqIDE2IHwgMDtcbiAgICB2YXIgdiA9IGMgPT09ICd4JyA/IHIgOiByICYgMHgzIHwgMHg4O1xuICAgIHJldHVybiB2LnRvU3RyaW5nKDE2KTtcbiAgfSk7XG5cbiAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiBvdXRlckhlaWdodChlbCkge1xuICB2YXIgaGVpZ2h0ID0gZWwub2Zmc2V0SGVpZ2h0O1xuICB2YXIgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG5cbiAgaGVpZ2h0ICs9IHBhcnNlSW50KHN0eWxlLm1hcmdpblRvcCkgKyBwYXJzZUludChzdHlsZS5tYXJnaW5Cb3R0b20pO1xuICByZXR1cm4gaGVpZ2h0O1xufVxuXG52YXIgY3NzID0gZXhwb3J0cy5jc3MgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjc3NQcmVmaXhlcyA9IFsnV2Via2l0JywgJ08nLCAnTW96JywgJ21zJ107XG4gIHZhciBjc3NQcm9wcyA9IHt9O1xuXG4gIGZ1bmN0aW9uIGNhbWVsQ2FzZShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL14tbXMtLywgJ21zLScpLnJlcGxhY2UoLy0oW1xcZGEtel0pL2dpLCBmdW5jdGlvbiAobWF0Y2gsIGxldHRlcikge1xuICAgICAgcmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VmVuZG9yUHJvcChuYW1lKSB7XG4gICAgdmFyIHN0eWxlID0gZG9jdW1lbnQuYm9keS5zdHlsZTtcbiAgICBpZiAobmFtZSBpbiBzdHlsZSkgcmV0dXJuIG5hbWU7XG5cbiAgICB2YXIgaSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcbiAgICB2YXIgY2FwTmFtZSA9IG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpO1xuICAgIHZhciB2ZW5kb3JOYW1lID0gdm9pZCAwO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdmVuZG9yTmFtZSA9IGNzc1ByZWZpeGVzW2ldICsgY2FwTmFtZTtcbiAgICAgIGlmICh2ZW5kb3JOYW1lIGluIHN0eWxlKSByZXR1cm4gdmVuZG9yTmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmFtZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFN0eWxlUHJvcChuYW1lKSB7XG4gICAgbmFtZSA9IGNhbWVsQ2FzZShuYW1lKTtcbiAgICByZXR1cm4gY3NzUHJvcHNbbmFtZV0gfHwgKGNzc1Byb3BzW25hbWVdID0gZ2V0VmVuZG9yUHJvcChuYW1lKSk7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBseUNzcyhlbGVtZW50LCBwcm9wLCB2YWx1ZSkge1xuICAgIHByb3AgPSBnZXRTdHlsZVByb3AocHJvcCk7XG4gICAgZWxlbWVudC5zdHlsZVtwcm9wXSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChlbGVtZW50LCBwcm9wZXJ0aWVzKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgdmFyIHByb3AgPSB2b2lkIDA7XG4gICAgdmFyIHZhbHVlID0gdm9pZCAwO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICBmb3IgKHByb3AgaW4gcHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xuICAgICAgICAgI
155HZhbHVlID0gcHJvcGVydGllc1twcm9wXTtcbiAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiBwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICBhcHBseUNzcyhlbGVtZW50LCBwcm9wLCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGx5Q3NzKGVsZW1lbnQsIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIH1cbiAgfTtcbn0oKTtcblxuZnVuY3Rpb24gYWRkTGlzdGVuZXIoZWwsIGV2ZW50cywgY2IpIHtcbiAgdmFyIHVzZUNhcHR1cmUgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6IGZhbHNlO1xuXG4gIGV2ZW50cyA9IGV2ZW50cy5zcGxpdCgnICcpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50c1tpXSwgY2IsIHVzZUNhcHR1cmUpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQuYXR0YWNoRXZlbnQpIHtcbiAgICAgIGVsLmF0dGFjaEV2ZW50KCdvbicgKyBldmVudHNbaV0sIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgbmFtZSkge1xuICB2YXIgbGlzdCA9IHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJyA/IGVsZW1lbnQgOiBjbGFzc0xpc3QoZWxlbWVudCk7XG4gIHJldHVybiBsaXN0LmluZGV4T2YoJyAnICsgbmFtZSArICcgJykgPj0gMDtcbn1cblxuZnVuY3Rpb24gYWRkQ2xhc3MoZWxlbWVudCwgbmFtZSkge1xuICB2YXIgb2xkTGlzdCA9IGNsYXNzTGlzdChlbGVtZW50KTtcbiAgdmFyIG5ld0xpc3QgPSBvbGRMaXN0ICsgbmFtZTtcblxuICBpZiAoaGFzQ2xhc3Mob2xkTGlzdCwgbmFtZSkpIHJldHVybjtcblxuICAvLyBUcmltIHRoZSBvcGVuaW5nIHNwYWNlLlxuICBlbGVtZW50LmNsYXNzTmFtZSA9IG5ld0xpc3Quc3Vic3RyaW5nKDEpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVDbGFzcyhlbGVtZW50LCBuYW1lKSB7XG4gIHZhciBvbGRMaXN0ID0gY2xhc3NMaXN0KGVsZW1lbnQpO1xuICB2YXIgbmV3TGlzdCA9IHZvaWQgMDtcblxuICBpZiAoIWhhc0NsYXNzKGVsZW1lbnQsIG5hbWUpKSByZXR1cm47XG5cbiAgLy8gUmVwbGFjZSB0aGUgY2xhc3MgbmFtZS5cbiAgbmV3TGlzdCA9IG9sZExpc3QucmVwbGFjZSgnICcgKyBuYW1lICsgJyAnLCAnICcpO1xuXG4gIC8vIFRyaW0gdGhlIG9wZW5pbmcgYW5kIGNsb3Npbmcgc3BhY2VzLlxuICBlbGVtZW50LmNsYXNzTmFtZSA9IG5ld0xpc3Quc3Vic3RyaW5nKDEsIG5ld0xpc3QubGVuZ3RoIC0gMSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShlbGVtZW50KSB7XG4gIGlmIChlbGVtZW50LnBhcmVudE5vZGUpIHtcbiAgICBlbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xhc3NMaXN0KGVsZW1lbnQpIHtcbiAgcmV0dXJuICgnICcgKyAoZWxlbWVudCAmJiBlbGVtZW50LmNsYXNzTmFtZSB8fCAnJykgKyAnICcpLnJlcGxhY2UoL1xccysvZ2ksICcgJyk7XG59XG5cbmZ1bmN0aW9uIHZpc2liaWxpdHlDaGFuZ2VGbG93KCkge1xuICB2YXIgaGlkZGVuID0gdm9pZCAwO1xuICB2YXIgdmlzaWJpbGl0eUNoYW5nZSA9IHZvaWQgMDtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudC5oaWRkZW4gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gT3BlcmEgMTIuMTAgYW5kIEZpcmVmb3ggMTggYW5kIGxhdGVyIHN1cHBvcnRcbiAgICBoaWRkZW4gPSAnaGlkZGVuJztcbiAgICB2aXNpYmlsaXR5Q2hhbmdlID0gJ3Zpc2liaWxpdHljaGFuZ2UnO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBkb2N1bWVudC5tc0hpZGRlbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBoaWRkZW4gPSAnbXNIaWRkZW4nO1xuICAgIHZpc2liaWxpdHlDaGFuZ2UgPSAnbXN2aXNpYmlsaXR5Y2hhbmdlJztcbiAgfSBlbHNlIGlmICh0eXBlb2YgZG9jdW1lbnQud2Via2l0SGlkZGVuICE9PSAndW5kZWZpbmVkJykge1xuICAgIGhpZGRlbiA9ICd3ZWJraXRIaWRkZW4nO1xuICAgIHZpc2liaWxpdHlDaGFuZ2UgPSAnd2Via2l0dmlzaWJpbGl0eWNoYW5nZSc7XG4gIH1cblxuICBmdW5jdGlvbiBvblZpc2liaWxpdHlDaGFuZ2UoKSB7XG4gICAgQVBJLlBhZ2VIaWRkZW4gPSBkb2N1bWVudFtoaWRkZW5dO1xuICAgIGhhbmRsZVZpc2liaWxpdHlDaGFuZ2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uQmx1cigpIHtcbiAgICBBUEkuUGFnZUhpZGRlbiA9IHRydWU7XG4gICAgaGFuZGxlVmlzaWJpbGl0eUNoYW5nZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Gb2N1cygpIHtcbiAgICBBUEkuUGFnZUhpZGRlbiA9IGZhbHNlO1xuICAgIGhhbmRsZVZpc2liaWxpdHlDaGFuZ2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVZpc2liaWxpdHlDaGFuZ2UoKSB7XG4gICAgaWYgKEFQSS5QYWdlSGlkZGVuKSBzdG9wQWxsKCk7ZWxzZSByZXN1bWVBbGwoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3BBbGwoKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3Qua2V5cyhBUEkuU3RvcmUpLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIGlmIChBUEkuU3RvcmUuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgICAgICAgaWYgKEFQSS5TdG9yZVtpZF0ub3B0aW9ucy52aXNpYmlsaXR5Q29udHJvbCkge1xuICAgICAgICAgICAgQVBJLlN0b3JlW2lkXS5zdG9wKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9LCAxMDApO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzdW1lQWxsKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgT2JqZWN0LmtleXMoQVBJLlN0b3JlKS5mb3JFYWNoKGZ1bmN0aW9uIChpZCkge1xuICAgICAgICBpZiAoQVBJLlN0b3JlLmhhc093blByb3BlcnR5KGlkKSkge1xuICAgICAgICAgIGlmIChBUEkuU3RvcmVbaWRdLm9wdGlvbnMudmlzaWJpbGl0eUNvbnRyb2wpIHtcbiAgICAgICAgICAgIEFQSS5TdG9yZVtpZF0ucmVzdW1lKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIEFQSS5xdWV1ZVJlbmRlckFsbCgpO1xuICAgIH0sIDEwMCk7XG4gIH1cblxuICBpZiAodmlzaWJpbGl0eUNoYW5nZSkge1xuICAgIGFkZExpc3RlbmVyKGRvY3VtZW50LCB2aXNpYmlsaXR5Q2hhbmdlLCBvblZpc2liaWxpdHlDaGFuZ2UpO1xuICB9XG5cbiAgYWRkTGlzdGVuZXIod2luZG93LCAnYmx1cicsIG9uQmx1cik7XG4gIGFkZExpc3RlbmVyKHdpbmRvdywgJ2ZvY3VzJywgb25Gb2N1cyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF1ZGlvRWxlbWVudHMocmVm
155KSB7XG4gIGlmIChyZWYuaGFzU291bmQpIHtcbiAgICB2YXIgYXVkaW9FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYXVkaW8nKTtcblxuICAgIHJlZi5vcHRpb25zLnNvdW5kcy5zb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgIHZhciBzb3VyY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzb3VyY2UnKTtcbiAgICAgIHNvdXJjZS5zcmMgPSBzO1xuICAgICAgc291cmNlLnR5cGUgPSAnYXVkaW8vJyArIGdldEV4dGVuc2lvbihzKTtcbiAgICAgIGF1ZGlvRWxlbWVudC5hcHBlbmRDaGlsZChzb3VyY2UpO1xuICAgIH0pO1xuXG4gICAgaWYgKHJlZi5iYXJEb20pIHtcbiAgICAgIHJlZi5iYXJEb20uYXBwZW5kQ2hpbGQoYXVkaW9FbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmFwcGVuZENoaWxkKGF1ZGlvRWxlbWVudCk7XG4gICAgfVxuXG4gICAgYXVkaW9FbGVtZW50LnZvbHVtZSA9IHJlZi5vcHRpb25zLnNvdW5kcy52b2x1bWU7XG5cbiAgICBpZiAoIXJlZi5zb3VuZFBsYXllZCkge1xuICAgICAgYXVkaW9FbGVtZW50LnBsYXkoKTtcbiAgICAgIHJlZi5zb3VuZFBsYXllZCA9IHRydWU7XG4gICAgfVxuXG4gICAgYXVkaW9FbGVtZW50Lm9uZW5kZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZW1vdmUoYXVkaW9FbGVtZW50KTtcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEV4dGVuc2lvbihmaWxlTmFtZSkge1xuICByZXR1cm4gZmlsZU5hbWUubWF0Y2goL1xcLihbXi5dKykkLylbMV07XG59XG5cbi8qKiovIH0pLFxuLyogMSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5EZWZhdWx0cyA9IGV4cG9ydHMuU3RvcmUgPSBleHBvcnRzLlF1ZXVlcyA9IGV4cG9ydHMuRGVmYXVsdE1heFZpc2libGUgPSBleHBvcnRzLmRvY1RpdGxlID0gZXhwb3J0cy5Eb2NNb2RhbENvdW50ID0gZXhwb3J0cy5QYWdlSGlkZGVuID0gdW5kZWZpbmVkO1xuZXhwb3J0cy5nZXRRdWV1ZUNvdW50cyA9IGdldFF1ZXVlQ291bnRzO1xuZXhwb3J0cy5hZGRUb1F1ZXVlID0gYWRkVG9RdWV1ZTtcbmV4cG9ydHMucmVtb3ZlRnJvbVF1ZXVlID0gcmVtb3ZlRnJvbVF1ZXVlO1xuZXhwb3J0cy5xdWV1ZVJlbmRlciA9IHF1ZXVlUmVuZGVyO1xuZXhwb3J0cy5xdWV1ZVJlbmRlckFsbCA9IHF1ZXVlUmVuZGVyQWxsO1xuZXhwb3J0cy5naG9zdEZpeCA9IGdob3N0Rml4O1xuZXhwb3J0cy5idWlsZCA9IGJ1aWxkO1xuZXhwb3J0cy5oYXNCdXR0b25zID0gaGFzQnV0dG9ucztcbmV4cG9ydHMuaGFuZGxlTW9kYWwgPSBoYW5kbGVNb2RhbDtcbmV4cG9ydHMuaGFuZGxlTW9kYWxDbG9zZSA9IGhhbmRsZU1vZGFsQ2xvc2U7XG5leHBvcnRzLnF1ZXVlQ2xvc2UgPSBxdWV1ZUNsb3NlO1xuZXhwb3J0cy5kZXF1ZXVlQ2xvc2UgPSBkZXF1ZXVlQ2xvc2U7XG5leHBvcnRzLmZpcmUgPSBmaXJlO1xuZXhwb3J0cy5vcGVuRmxvdyA9IG9wZW5GbG93O1xuZXhwb3J0cy5jbG9zZUZsb3cgPSBjbG9zZUZsb3c7XG5cbnZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xuXG52YXIgVXRpbHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfdXRpbHMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfVxuXG52YXIgUGFnZUhpZGRlbiA9IGV4cG9ydHMuUGFnZUhpZGRlbiA9IGZhbHNlO1xudmFyIERvY01vZGFsQ291bnQgPSBleHBvcnRzLkRvY01vZGFsQ291bnQgPSAwO1xuXG52YXIgRG9jVGl0bGVQcm9wcyA9IHtcbiAgb3JpZ2luYWxUaXRsZTogbnVsbCxcbiAgY291bnQ6IDAsXG4gIGNoYW5nZWQ6IGZhbHNlLFxuICB0aW1lcjogLTFcbn07XG5cbnZhciBkb2NUaXRsZSA9IGV4cG9ydHMuZG9jVGl0bGUgPSB7XG4gIGluY3JlbWVudDogZnVuY3Rpb24gaW5jcmVtZW50KCkge1xuICAgIERvY1RpdGxlUHJvcHMuY291bnQrKztcblxuICAgIGRvY1RpdGxlLl91cGRhdGUoKTtcbiAgfSxcblxuICBkZWNyZW1lbnQ6IGZ1bmN0aW9uIGRlY3JlbWVudCgpIHtcbiAgICBEb2NUaXRsZVByb3BzLmNvdW50LS07XG5cbiAgICBpZiAoRG9jVGl0bGVQcm9wcy5jb3VudCA8PSAwKSB7XG4gICAgICBkb2
155NUaXRsZS5fY2xlYXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkb2NUaXRsZS5fdXBkYXRlKCk7XG4gIH0sXG5cbiAgX3VwZGF0ZTogZnVuY3Rpb24gX3VwZGF0ZSgpIHtcbiAgICB2YXIgdGl0bGUgPSBkb2N1bWVudC50aXRsZTtcblxuICAgIGlmICghRG9jVGl0bGVQcm9wcy5jaGFuZ2VkKSB7XG4gICAgICBEb2NUaXRsZVByb3BzLm9yaWdpbmFsVGl0bGUgPSB0aXRsZTtcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gJygnICsgRG9jVGl0bGVQcm9wcy5jb3VudCArICcpICcgKyB0aXRsZTtcbiAgICAgIERvY1RpdGxlUHJvcHMuY2hhbmdlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gJygnICsgRG9jVGl0bGVQcm9wcy5jb3VudCArICcpICcgKyBEb2NUaXRsZVByb3BzLm9yaWdpbmFsVGl0bGU7XG4gICAgfVxuICB9LFxuXG4gIF9jbGVhcjogZnVuY3Rpb24gX2NsZWFyKCkge1xuICAgIGlmIChEb2NUaXRsZVByb3BzLmNoYW5nZWQpIHtcbiAgICAgIERvY1RpdGxlUHJvcHMuY291bnQgPSAwO1xuICAgICAgZG9jdW1lbnQudGl0bGUgPSBEb2NUaXRsZVByb3BzLm9yaWdpbmFsVGl0bGU7XG4gICAgICBEb2NUaXRsZVByb3BzLmNoYW5nZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBEZWZhdWx0TWF4VmlzaWJsZSA9IGV4cG9ydHMuRGVmYXVsdE1heFZpc2libGUgPSA1O1xuXG52YXIgUXVldWVzID0gZXhwb3J0cy5RdWV1ZXMgPSB7XG4gIGdsb2JhbDoge1xuICAgIG1heFZpc2libGU6IERlZmF1bHRNYXhWaXNpYmxlLFxuICAgIHF1ZXVlOiBbXVxuICB9XG59O1xuXG52YXIgU3RvcmUgPSBleHBvcnRzLlN0b3JlID0ge307XG5cbnZhciBEZWZhdWx0cyA9IGV4cG9ydHMuRGVmYXVsdHMgPSB7XG4gIHR5cGU6ICdhbGVydCcsXG4gIGxheW91dDogJ3RvcFJpZ2h0JyxcbiAgdGhlbWU6ICdtaW50JyxcbiAgdGV4dDogJycsXG4gIHRpbWVvdXQ6IGZhbHNlLFxuICBwcm9ncmVzc0JhcjogdHJ1ZSxcbiAgY2xvc2VXaXRoOiBbJ2NsaWNrJ10sXG4gIGFuaW1hdGlvbjoge1xuICAgIG9wZW46ICdub3R5X2VmZmVjdHNfb3BlbicsXG4gICAgY2xvc2U6ICdub3R5X2VmZmVjdHNfY2xvc2UnXG4gIH0sXG4gIGlkOiBmYWxzZSxcbiAgZm9yY2U6IGZhbHNlLFxuICBraWxsZXI6IGZhbHNlLFxuICBxdWV1ZTogJ2dsb2JhbCcsXG4gIGNvbnRhaW5lcjogZmFsc2UsXG4gIGJ1dHRvbnM6IFtdLFxuICBjYWxsYmFja3M6IHtcbiAgICBiZWZvcmVTaG93OiBudWxsLFxuICAgIG9uU2hvdzogbnVsbCxcbiAgICBhZnRlclNob3c6IG51bGwsXG4gICAgb25DbG9zZTogbnVsbCxcbiAgICBhZnRlckNsb3NlOiBudWxsLFxuICAgIG9uQ2xpY2s6IG51bGwsXG4gICAgb25Ib3ZlcjogbnVsbCxcbiAgICBvblRlbXBsYXRlOiBudWxsXG4gIH0sXG4gIHNvdW5kczoge1xuICAgIHNvdXJjZXM6IFtdLFxuICAgIHZvbHVtZTogMSxcbiAgICBjb25kaXRpb25zOiBbXVxuICB9LFxuICB0aXRsZUNvdW50OiB7XG4gICAgY29uZGl0aW9uczogW11cbiAgfSxcbiAgbW9kYWw6IGZhbHNlLFxuICB2aXNpYmlsaXR5Q29udHJvbDogZmFsc2VcblxuICAvKipcclxuICAgKiBAcGFyYW0ge3N0cmluZ30gcXVldWVOYW1lXHJcbiAgICogQHJldHVybiB7b2JqZWN0fVxyXG4gICAqL1xufTtmdW5jdGlvbiBnZXRRdWV1ZUNvdW50cygpIHtcbiAgdmFyIHF1ZXVlTmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ2dsb2JhbCc7XG5cbiAgdmFyIGNvdW50ID0gMDtcbiAgdmFyIG1heCA9IERlZmF1bHRNYXhWaXNpYmxlO1xuXG4gIGlmIChRdWV1ZXMuaGFzT3duUHJvcGVydHkocXVldWVOYW1lKSkge1xuICAgIG1heCA9IFF1ZXVlc1txdWV1ZU5hbWVdLm1heFZpc2libGU7XG4gICAgT2JqZWN0LmtleXMoU3RvcmUpLmZvckVhY2goZnVuY3Rpb24gKGkpIHtcbiAgICAgIGlmIChTdG9yZVtpXS5vcHRpb25zLnF1ZXVlID09PSBxdWV1ZU5hbWUgJiYgIVN0b3JlW2ldLmNsb3NlZCkgY291bnQrKztcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY3VycmVudDogY291bnQsXG4gICAgbWF4VmlzaWJsZTogbWF4XG4gIH07XG59XG5cbi8qKlxyXG4gKiBAcGFyYW0ge05vdHl9IHJlZlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIGFkZFRvUXVldWUocmVmKSB7XG4gIGlmICghUXVldWVzLmhhc093blByb3BlcnR5KHJlZi5vcHRpb25zLnF1ZXVlKSkge1xuICAgIFF1ZXVlc1tyZWYub3B0aW9ucy5xdWV1ZV0gPSB7IG1heFZpc2libGU6IERlZmF1bHRNYXhWaXNpYmxlLCBxdWV1ZTogW10gfTtcbiAgfVxuXG4gIFF1ZXVlc1tyZWYub3B0aW9ucy5xdWV1ZV0ucXVldWUucHVzaChyZWYpO1xufVxuXG4vKipcclxuICogQHBhcmFtIHtOb3R5fSByZWZcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXG5mdW5jdGlvbiByZW1vdmVGcm9tUXVldWUocmVmKSB7XG4gIGlmIChRdWV1ZXMuaGFzT3duUHJvcGVydHkocmVmLm9wdGlvbnMucXVldWUpKSB7XG4gICAgdmFyIHF1ZXVlID0gW107XG4gICAgT2JqZWN0LmtleXMoUXVldWVzW3JlZi5vcHRpb25zLnF1ZXVlXS5xdWV1ZSkuZm9yRWFjaChmdW5jdGlvbiAoaSkge1xuICAgICAgaWYgKFF1ZXVlc1tyZWYub3B0aW9ucy5xdWV1ZV0ucXVldWVbaV0uaWQgIT09IHJlZi5pZCkge1xuICAgICAgICBxdWV1ZS5wdXNoKFF1ZXVlc1tyZWYub3B0aW9ucy5xdWV1ZV0ucXVldWVbaV0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIFF1ZXVlc1tyZWYub3B0aW9ucy5xdWV1ZV0ucXVldWUgPSBxdWV1ZTtcbiAgfVxufVxuXG4vKipcclxuICogQHBhcmFtIHtzdHJpbmd9IHF1ZXVlTmFtZVxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlUmVuZGVyKCkge1xuICB2YXIgcXVldWVOYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnZ2xvYmFsJztcblxuICBpZiAoUXVldWVzLmhhc093blByb3BlcnR5KHF1ZXVlTmFtZSkpIHtcbiAgICB2YXIgbm90eSA9IFF1ZXVlc1txdWV1ZU
1555hbWVdLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgICBpZiAobm90eSkgbm90eS5zaG93KCk7XG4gIH1cbn1cblxuLyoqXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xuZnVuY3Rpb24gcXVldWVSZW5kZXJBbGwoKSB7XG4gIE9iamVjdC5rZXlzKFF1ZXVlcykuZm9yRWFjaChmdW5jdGlvbiAocXVldWVOYW1lKSB7XG4gICAgcXVldWVSZW5kZXIocXVldWVOYW1lKTtcbiAgfSk7XG59XG5cbi8qKlxyXG4gKiBAcGFyYW0ge05vdHl9IHJlZlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIGdob3N0Rml4KHJlZikge1xuICB2YXIgZ2hvc3RJRCA9IFV0aWxzLmdlbmVyYXRlSUQoJ2dob3N0Jyk7XG4gIHZhciBnaG9zdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBnaG9zdC5zZXRBdHRyaWJ1dGUoJ2lkJywgZ2hvc3RJRCk7XG4gIFV0aWxzLmNzcyhnaG9zdCwge1xuICAgIGhlaWdodDogVXRpbHMub3V0ZXJIZWlnaHQocmVmLmJhckRvbSkgKyAncHgnXG4gIH0pO1xuXG4gIHJlZi5iYXJEb20uaW5zZXJ0QWRqYWNlbnRIVE1MKCdhZnRlcmVuZCcsIGdob3N0Lm91dGVySFRNTCk7XG5cbiAgVXRpbHMucmVtb3ZlKHJlZi5iYXJEb20pO1xuICBnaG9zdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGdob3N0SUQpO1xuICBVdGlscy5hZGRDbGFzcyhnaG9zdCwgJ25vdHlfZml4X2VmZmVjdHNfaGVpZ2h0Jyk7XG4gIFV0aWxzLmFkZExpc3RlbmVyKGdob3N0LCBVdGlscy5hbmltYXRpb25FbmRFdmVudHMsIGZ1bmN0aW9uICgpIHtcbiAgICBVdGlscy5yZW1vdmUoZ2hvc3QpO1xuICB9KTtcbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xuZnVuY3Rpb24gYnVpbGQocmVmKSB7XG4gIGZpbmRPckNyZWF0ZUNvbnRhaW5lcihyZWYpO1xuXG4gIHZhciBtYXJrdXAgPSAnPGRpdiBjbGFzcz1cIm5vdHlfYm9keVwiPicgKyByZWYub3B0aW9ucy50ZXh0ICsgJzwvZGl2PicgKyBidWlsZEJ1dHRvbnMocmVmKSArICc8ZGl2IGNsYXNzPVwibm90eV9wcm9ncmVzc2JhclwiPjwvZGl2Pic7XG5cbiAgcmVmLmJhckRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICByZWYuYmFyRG9tLnNldEF0dHJpYnV0ZSgnaWQnLCByZWYuaWQpO1xuICBVdGlscy5hZGRDbGFzcyhyZWYuYmFyRG9tLCAnbm90eV9iYXIgbm90eV90eXBlX18nICsgcmVmLm9wdGlvbnMudHlwZSArICcgbm90eV90aGVtZV9fJyArIHJlZi5vcHRpb25zLnRoZW1lKTtcblxuICByZWYuYmFyRG9tLmlubmVySFRNTCA9IG1hcmt1cDtcblxuICBmaXJlKHJlZiwgJ29uVGVtcGxhdGUnKTtcbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XHJcbiAqL1xuZnVuY3Rpb24gaGFzQnV0dG9ucyhyZWYpIHtcbiAgcmV0dXJuICEhKHJlZi5vcHRpb25zLmJ1dHRvbnMgJiYgT2JqZWN0LmtleXMocmVmLm9wdGlvbnMuYnV0dG9ucykubGVuZ3RoKTtcbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEByZXR1cm4ge3N0cmluZ31cclxuICovXG5mdW5jdGlvbiBidWlsZEJ1dHRvbnMocmVmKSB7XG4gIGlmIChoYXNCdXR0b25zKHJlZikpIHtcbiAgICB2YXIgYnV0dG9ucyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIFV0aWxzLmFkZENsYXNzKGJ1dHRvbnMsICdub3R5X2J1dHRvbnMnKTtcblxuICAgIE9iamVjdC5rZXlzKHJlZi5vcHRpb25zLmJ1dHRvbnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgYnV0dG9ucy5hcHBlbmRDaGlsZChyZWYub3B0aW9ucy5idXR0b25zW2tleV0uZG9tKTtcbiAgICB9KTtcblxuICAgIHJlZi5vcHRpb25zLmJ1dHRvbnMuZm9yRWFjaChmdW5jdGlvbiAoYnRuKSB7XG4gICAgICBidXR0b25zLmFwcGVuZENoaWxkKGJ0bi5kb20pO1xuICAgIH0pO1xuICAgIHJldHVybiBidXR0b25zLm91dGVySFRNTDtcbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbi8qKlxyXG4gKiBAcGFyYW0ge05vdHl9IHJlZlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZU1vZGFsKHJlZikge1xuICBpZiAocmVmLm9wdGlvbnMubW9kYWwpIHtcbiAgICBpZiAoRG9jTW9kYWxDb3VudCA9PT0gMCkge1xuICAgICAgY3JlYXRlTW9kYWwocmVmKTtcbiAgICB9XG5cbiAgICBleHBvcnRzLkRvY01vZGFsQ291bnQgPSBEb2NNb2RhbENvdW50ICs9IDE7XG4gIH1cbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xuZnVuY3Rpb24gaGFuZGxlTW9kYWxDbG9zZShyZWYpIHtcbiAgaWYgKHJlZi5vcHRpb25zLm1vZGFsICYmIERvY01vZGFsQ291bnQgPiAwKSB7XG4gICAgZXhwb3J0cy5Eb2NNb2RhbENvdW50ID0gRG9jTW9kYWxDb3VudCAtPSAxO1xuXG4gICAgaWYgKERvY01vZGFsQ291bnQgPD0gMCkge1xuICAgICAgdmFyIG1vZGFsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm5vdHlfbW9kYWwnKTtcblxuICAgICAgaWYgKG1vZGFsKSB7XG4gICAgICAgIFV0aWxzLnJlbW92ZUNsYXNzKG1vZGFsLCAnbm90eV9tb2RhbF9vcGVuJyk7XG4gICAgICAgIFV0aWxzLmFkZENsYXNzKG1vZGFsLCAnbm90eV9tb2RhbF9jbG9zZScpO1xuICAgICAgICBVdGlscy5hZGRMaXN0ZW5lcihtb2RhbCwgVXRpbHMuYW5pbWF0aW9uRW5kRXZlbnRzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgVXRpbHMucmVtb3ZlKG1vZGFsKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU1vZGFsKCkge1xuICB2YXIgYm9keSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKTtcbiAgdmFyIG1vZGFsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIFV0aWxzLmFkZENsYXNzKG1vZGFsLCAnbm90eV9tb2RhbCcpO1xuICBib2R5Lmluc2VydEJlZm9yZShtb2RhbCwgYm9keS5maXJzdENoaWxkKTtcbiAgVXRpbHMuYWRkQ2xhc3MobW9kYWwsICdub3R5X21vZGFsX29wZW4nKTtcblxuICBVdGlscy5hZGRMaXN0ZW5lcihtb2R
155hbCwgVXRpbHMuYW5pbWF0aW9uRW5kRXZlbnRzLCBmdW5jdGlvbiAoKSB7XG4gICAgVXRpbHMucmVtb3ZlQ2xhc3MobW9kYWwsICdub3R5X21vZGFsX29wZW4nKTtcbiAgfSk7XG59XG5cbi8qKlxyXG4gKiBAcGFyYW0ge05vdHl9IHJlZlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIGZpbmRPckNyZWF0ZUNvbnRhaW5lcihyZWYpIHtcbiAgaWYgKHJlZi5vcHRpb25zLmNvbnRhaW5lcikge1xuICAgIHJlZi5sYXlvdXREb20gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHJlZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGxheW91dElEID0gJ25vdHlfbGF5b3V0X18nICsgcmVmLm9wdGlvbnMubGF5b3V0O1xuICByZWYubGF5b3V0RG9tID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZGl2IycgKyBsYXlvdXRJRCk7XG5cbiAgaWYgKCFyZWYubGF5b3V0RG9tKSB7XG4gICAgcmVmLmxheW91dERvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHJlZi5sYXlvdXREb20uc2V0QXR0cmlidXRlKCdpZCcsIGxheW91dElEKTtcbiAgICByZWYubGF5b3V0RG9tLnNldEF0dHJpYnV0ZSgncm9sZScsICdhbGVydCcpO1xuICAgIHJlZi5sYXlvdXREb20uc2V0QXR0cmlidXRlKCdhcmlhLWxpdmUnLCAncG9saXRlJyk7XG4gICAgVXRpbHMuYWRkQ2xhc3MocmVmLmxheW91dERvbSwgJ25vdHlfbGF5b3V0Jyk7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmFwcGVuZENoaWxkKHJlZi5sYXlvdXREb20pO1xuICB9XG59XG5cbi8qKlxyXG4gKiBAcGFyYW0ge05vdHl9IHJlZlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlQ2xvc2UocmVmKSB7XG4gIGlmIChyZWYub3B0aW9ucy50aW1lb3V0KSB7XG4gICAgaWYgKHJlZi5vcHRpb25zLnByb2dyZXNzQmFyICYmIHJlZi5wcm9ncmVzc0RvbSkge1xuICAgICAgVXRpbHMuY3NzKHJlZi5wcm9ncmVzc0RvbSwge1xuICAgICAgICB0cmFuc2l0aW9uOiAnd2lkdGggJyArIHJlZi5vcHRpb25zLnRpbWVvdXQgKyAnbXMgbGluZWFyJyxcbiAgICAgICAgd2lkdGg6ICcwJSdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNsZWFyVGltZW91dChyZWYuY2xvc2VUaW1lcik7XG5cbiAgICByZWYuY2xvc2VUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmVmLmNsb3NlKCk7XG4gICAgfSwgcmVmLm9wdGlvbnMudGltZW91dCk7XG4gIH1cbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xuZnVuY3Rpb24gZGVxdWV1ZUNsb3NlKHJlZikge1xuICBpZiAocmVmLm9wdGlvbnMudGltZW91dCAmJiByZWYuY2xvc2VUaW1lcikge1xuICAgIGNsZWFyVGltZW91dChyZWYuY2xvc2VUaW1lcik7XG4gICAgcmVmLmNsb3NlVGltZXIgPSAtMTtcblxuICAgIGlmIChyZWYub3B0aW9ucy5wcm9ncmVzc0JhciAmJiByZWYucHJvZ3Jlc3NEb20pIHtcbiAgICAgIFV0aWxzLmNzcyhyZWYucHJvZ3Jlc3NEb20sIHtcbiAgICAgICAgdHJhbnNpdGlvbjogJ3dpZHRoIDBtcyBsaW5lYXInLFxuICAgICAgICB3aWR0aDogJzEwMCUnXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXHJcbiAqIEBwYXJhbSB7Tm90eX0gcmVmXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXG5mdW5jdGlvbiBmaXJlKHJlZiwgZXZlbnROYW1lKSB7XG4gIGlmIChyZWYubGlzdGVuZXJzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICByZWYubGlzdGVuZXJzW2V2ZW50TmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoY2IpIHtcbiAgICAgIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2IuYXBwbHkocmVmKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vKipcclxuICogQHBhcmFtIHtOb3R5fSByZWZcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXG5mdW5jdGlvbiBvcGVuRmxvdyhyZWYpIHtcbiAgZmlyZShyZWYsICdhZnRlclNob3cnKTtcbiAgcXVldWVDbG9zZShyZWYpO1xuXG4gIFV0aWxzLmFkZExpc3RlbmVyKHJlZi5iYXJEb20sICdtb3VzZWVudGVyJywgZnVuY3Rpb24gKCkge1xuICAgIGRlcXVldWVDbG9zZShyZWYpO1xuICB9KTtcblxuICBVdGlscy5hZGRMaXN0ZW5lcihyZWYuYmFyRG9tLCAnbW91c2VsZWF2ZScsIGZ1bmN0aW9uICgpIHtcbiAgICBxdWV1ZUNsb3NlKHJlZik7XG4gIH0pO1xufVxuXG4vKipcclxuICogQHBhcmFtIHtOb3R5fSByZWZcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXG5mdW5jdGlvbiBjbG9zZUZsb3cocmVmKSB7XG4gIGRlbGV0ZSBTdG9yZVtyZWYuaWRdO1xuICByZWYuY2xvc2luZyA9IGZhbHNlO1xuICBmaXJlKHJlZiwgJ2FmdGVyQ2xvc2UnKTtcblxuICBVdGlscy5yZW1vdmUocmVmLmJhckRvbSk7XG5cbiAgaWYgKHJlZi5sYXlvdXREb20ucXVlcnlTZWxlY3RvckFsbCgnLm5vdHlfYmFyJykubGVuZ3RoID09PSAwICYmICFyZWYub3B0aW9ucy5jb250YWluZXIpIHtcbiAgICBVdGlscy5yZW1vdmUocmVmLmxheW91dERvbSk7XG4gIH1cblxuICBpZiAoVXRpbHMuaW5BcnJheSgnZG9jVmlzaWJsZScsIHJlZi5vcHRpb25zLnRpdGxlQ291bnQuY29uZGl0aW9ucykgfHwgVXRpbHMuaW5BcnJheSgnZG9jSGlkZGVuJywgcmVmLm9wdGlvbnMudGl0bGVDb3VudC5jb25kaXRpb25zKSkge1xuICAgIGRvY1RpdGxlLmRlY3JlbWVudCgpO1xuICB9XG5cbiAgcXVldWVSZW5kZXIocmVmLm9wdGlvbnMucXVldWUpO1xufVxuXG4vKioqLyB9KSxcbi8qIDIgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuTm90eUJ1dHRvbiA9IHVuZGVmaW5lZDtcblxudmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cbnZhciBVdGlscyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF91dGlscyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybi
155BvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBOb3R5QnV0dG9uID0gZXhwb3J0cy5Ob3R5QnV0dG9uID0gZnVuY3Rpb24gTm90eUJ1dHRvbihodG1sLCBjbGFzc2VzLCBjYikge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciBhdHRyaWJ1dGVzID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcblxuICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTm90eUJ1dHRvbik7XG5cbiAgdGhpcy5kb20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgdGhpcy5kb20uaW5uZXJIVE1MID0gaHRtbDtcbiAgdGhpcy5pZCA9IGF0dHJpYnV0ZXMuaWQgPSBhdHRyaWJ1dGVzLmlkIHx8IFV0aWxzLmdlbmVyYXRlSUQoJ2J1dHRvbicpO1xuICB0aGlzLmNiID0gY2I7XG4gIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkge1xuICAgIF90aGlzLmRvbS5zZXRBdHRyaWJ1dGUocHJvcGVydHlOYW1lLCBhdHRyaWJ1dGVzW3Byb3BlcnR5TmFtZV0pO1xuICB9KTtcbiAgVXRpbHMuYWRkQ2xhc3ModGhpcy5kb20sIGNsYXNzZXMgfHwgJ25vdHlfYnRuJyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKioqLyB9KSxcbi8qIDMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci
1555lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIFB1c2ggPSBleHBvcnRzLlB1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFB1c2goKSB7XG4gICAgdmFyIHdvcmtlclBhdGggPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICcvc2VydmljZS13b3JrZXIuanMnO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFB1c2gpO1xuXG4gICAgdGhpcy5zdWJEYXRhID0ge307XG4gICAgdGhpcy53b3JrZXJQYXRoID0gd29ya2VyUGF0aDtcbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcbiAgICAgIG9uUGVybWlzc2lvbkdyYW50ZWQ6IFtdLFxuICAgICAgb25QZXJtaXNzaW9uRGVuaWVkOiBbXSxcbiAgICAgIG9uU3Vic2NyaXB0aW9uU3VjY2VzczogW10sXG4gICAgICBvblN1YnNjcmlwdGlvbkNhbmNlbDogW10sXG4gICAgICBvbldvcmtlckVycm9yOiBbXSxcbiAgICAgIG9uV29ya2VyU3VjY2VzczogW10sXG4gICAgICBvbldvcmtlck5vdFN1cHBvcnRlZDogW11cbiAgICB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNiXHJcbiAgICogQHJldHVybiB7UHVzaH1cclxuICAgKi9cblxuXG4gIF9jcmVhdGVDbGFzcyhQdXNoLCBbe1xuICAgIGtleTogJ29uJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gb24oZXZlbnROYW1lKSB7XG4gICAgICB2Y
155XIgY2IgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nICYmIHRoaXMubGlzdGVuZXJzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoKGNiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZmlyZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZpcmUoZXZlbnROYW1lKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB2YXIgcGFyYW1zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBbXTtcblxuICAgICAgaWYgKHRoaXMubGlzdGVuZXJzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbZXZlbnROYW1lXS5mb3JFYWNoKGZ1bmN0aW9uIChjYikge1xuICAgICAgICAgIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNiLmFwcGx5KF90aGlzLCBwYXJhbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnY3JlYXRlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgY29uc29sZS5sb2coJ05PVCBJTVBMRU1FTlRFRCBZRVQnKTtcbiAgICB9XG5cbiAgICAvKipcclxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnaXNTdXBwb3J0ZWQnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc1N1cHBvcnRlZCgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBmYWxzZTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gd2luZG93Lk5vdGlmaWNhdGlvbiB8fCB3aW5kb3cud2Via2l0Tm90aWZpY2F0aW9ucyB8fCBuYXZpZ2F0b3IubW96Tm90aWZpY2F0aW9uIHx8IHdpbmRvdy5leHRlcm5hbCAmJiB3aW5kb3cuZXh0ZXJuYWwubXNJc1NpdGVNb2RlKCkgIT09IHVuZGVmaW5lZDtcbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnZ2V0UGVybWlzc2lvblN0YXR1cycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBlcm1pc3Npb25TdGF0dXMoKSB7XG4gICAgICB2Y
155XIgcGVybSA9ICdkZWZhdWx0JztcblxuICAgICAgaWYgKHdpbmRvdy5Ob3RpZmljYXRpb24gJiYgd2luZG93Lk5vdGlmaWNhdGlvbi5wZXJtaXNzaW9uTGV2ZWwpIHtcbiAgICAgICAgcGVybSA9IHdpbmRvdy5Ob3RpZmljYXRpb24ucGVybWlzc2lvbkxldmVsO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cud2Via2l0Tm90aWZpY2F0aW9ucyAmJiB3aW5kb3cud2Via2l0Tm90aWZpY2F0aW9ucy5jaGVja1Blcm1pc3Npb24pIHtcbiAgICAgICAgc3dpdGNoICh3aW5kb3cud2Via2l0Tm90aWZpY2F0aW9ucy5jaGVja1Blcm1pc3Npb24oKSkge1xuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHBlcm0gPSAnZGVmYXVsdCc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICBwZXJtID0gJ2dyYW50ZWQnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHBlcm0gPSAnZGVuaWVkJztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh3aW5kb3cuTm90aWZpY2F0aW9uICYmIHdpbmRvdy5Ob3RpZmljYXRpb24ucGVybWlzc2lvbikge1xuICAgICAgICBwZXJtID0gd2luZG93Lk5vdGlmaWNhdGlvbi5wZXJtaXNzaW9uO1xuICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IubW96Tm90aWZpY2F0aW9uKSB7XG4gICAgICAgIHBlcm0gPSAnZ3JhbnRlZCc7XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy5leHRlcm5hbCAmJiB3aW5kb3cuZXh0ZXJuYWwubXNJc1NpdGVNb2RlKCkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwZXJtID0gd2luZG93LmV4dGVybmFsLm1zSXNTaXRlTW9kZSgpID8gJ2dyYW50ZWQnIDogJ2RlZmF1bHQnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGVybS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnZ2V0RW5kcG9pbnQnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRFbmRwb2ludChzdWJzY3JpcHRpb24pIHtcbiAgICAgIHZhciBlbmRwb2ludCA9IHN1YnNjcmlwdGlvbi5lbmRwb2ludDtcbiAgICAgIHZhciBzdWJzY3JpcHRpb25JZCA9IHN1YnNjcmlwdGlvbi5zdWJzY3JpcHRpb25JZDtcblxuICAgICAgLy8gZml4IGZvciBDaHJvbWUgPCA0NVxuICAgICAgaWYgKHN1YnNjcmlwdGlvbklkICYmIGVuZHBvaW50LmluZGV4T2Yoc3Vic2NyaXB0aW9uSWQpID09PSAtMSkge1xuICAgICAgICBlbmRwb2ludCArPSAnLycgKyBzdWJzY3JpcHRpb25JZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVuZHBvaW50O1xuICAgIH1cblxuICAgIC8qKlxyXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cclxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdpc1NXUmVnaXN0ZXJlZCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzU1dSZWdpc3RlcmVkKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5hdmlnYXRvci5zZXJ2aWNlV29ya2VyLmNvbnRyb2xsZXIuc3RhdGUgPT09ICdhY3RpdmF0ZWQnO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogJ3VucmVnaXN0ZXJXb3JrZXInLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1bnJlZ2lzdGVyV29ya2VyKCkge1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgaWYgKCdzZXJ2aWNlV29ya2VyJyBpbiBuYXZpZ2F0b3IpIHtcbiAgICAgICAgbmF2aWdhdG9yLnNlcnZpY2VXb3JrZXIuZ2V0UmVnaXN0cmF0aW9ucygpLnRoZW4oZnVuY3Rpb24gKHJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICB2Y
155XIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yID0gZmFsc2U7XG4gICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHJlZ2lzdHJhdGlvbnNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7XG4gICAgICAgICAgICAgIHZhciByZWdpc3RyYXRpb24gPSBfc3RlcC52YWx1ZTtcblxuICAgICAgICAgICAgICByZWdpc3RyYXRpb24udW5yZWdpc3RlcigpO1xuICAgICAgICAgICAgICBzZWxmLmZpcmUoJ29uU3Vic2NyaXB0aW9uQ2FuY2VsJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvciA9IHRydWU7XG4gICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IGVycjtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uICYmIF9pdGVyYXRvci5yZXR1cm4pIHtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcclxuICAgICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAncmVxdWVzdFN1YnNjcmlwdGlvbicsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlcXVlc3RTdWJzY3JpcHRpb24oKSB7XG4gICAgICB2Y
155XIgX3RoaXMyID0gdGhpcztcblxuICAgICAgdmFyIHVzZXJWaXNpYmxlT25seSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdHJ1ZTtcblxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLmdldFBlcm1pc3Npb25TdGF0dXMoKTtcbiAgICAgIHZhciBjYiA9IGZ1bmN0aW9uIGNiKHJlc3VsdCkge1xuICAgICAgICBpZiAocmVzdWx0ID09PSAnZ3JhbnRlZCcpIHtcbiAgICAgICAgICBfdGhpczIuZmlyZSgnb25QZXJtaXNzaW9uR3JhbnRlZCcpO1xuXG4gICAgICAgICAgaWYgKCdzZXJ2aWNlV29ya2VyJyBpbiBuYXZpZ2F0b3IpIHtcbiAgICAgICAgICAgIG5hdmlnYXRvci5zZXJ2aWNlV29ya2VyLnJlZ2lzdGVyKF90aGlzMi53b3JrZXJQYXRoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgbmF2aWdhdG9yLnNlcnZpY2VXb3JrZXIucmVhZHkudGhlbihmdW5jdGlvbiAoc2VydmljZVdvcmtlclJlZ2lzdHJhdGlvbikge1xuICAgICAgICAgICAgICAgIHNlbGYuZmlyZSgnb25Xb3JrZXJTdWNjZXNzJyk7XG4gICAgICAgICAgICAgICAgc2VydmljZVdvcmtlclJlZ2lzdHJhdGlvbi5wdXNoTWFuYWdlci5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgICAgdXNlclZpc2libGVPbmx5OiB1c2VyVmlzaWJsZU9ubHlcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChzdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBzdWJzY3JpcHRpb24uZ2V0S2V5KCdwMjU2ZGgnKTtcbiAgICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IHN1YnNjcmlwdGlvbi5nZXRLZXkoJ2F1dGgnKTtcblxuICAgICAgICAgICAgICAgICAgc2VsZi5zdWJEYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludDogc2VsZi5nZXRFbmRwb2ludChzdWJzY3JpcHRpb24pLFxuICAgICAgICAgICAgICAgICAgICBwMjU2ZGg6IGtleSA/IHdpbmRvdy5idG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkoa2V5KSkpIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgYXV0aDogdG9rZW4gPyB3aW5kb3cuYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHRva2VuKSkpIDogbnVsbFxuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgc2VsZi5maXJlKCdvblN1YnNjcmlwdGlvblN1Y2Nlc3MnLCBbc2VsZi5zdWJEYXRhXSk7XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgc2VsZi5maXJlKCdvbldvcmtlckVycm9yJywgW2Vycl0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLmZpcmUoJ29uV29ya2VyTm90U3VwcG9ydGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gJ2RlbmllZCcpIHtcbiAgICAgICAgICBfdGhpczIuZmlyZSgnb25QZXJtaXNzaW9uRGVuaWVkJyk7XG4gICAgICAgICAgX3RoaXMyLnVucmVnaXN0ZXJXb3JrZXIoKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgaWYgKGN1cnJlbnQgPT09ICdkZWZhdWx0Jykge1xuICAgICAgICBpZiAod2luZG93Lk5vdGlmaWNhdGlvbiAmJiB3aW5kb3cuTm90aWZpY2F0aW9uLnJlcXVlc3RQZXJtaXNzaW9uKSB7XG4gICAgICAgICAgd2luZG93Lk5vdGlmaWNhdGlvbi5yZXF1ZXN0UGVybWlzc2lvbihjYik7XG4gICAgICAgIH0gZWxzZSBpZiAod2luZG93LndlYmtpdE5vdGlmaWNhdGlvbnMgJiYgd2luZG93LndlYmtpdE5vdGlmaWNhdGlvbnMuY2hlY2tQZXJtaXNzaW9uKSB7XG4gICAgICAgICAgd2luZG93LndlYmtpdE5vdGlmaWNhdGlvbnMucmVxdWVzdFBlcm1pc3Npb24oY2IpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYihjdXJyZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUHVzaDtcbn0oKTtcblxuLyoqKi8gfSksXG4vKiA0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbi8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqLyhmdW5jdGlvbihwcm9jZXNzLCBnbG9iYWwpIHt2YXIgcmVxdWlyZTsvKiFcbiAqIEBvdmVydmlldyBlczYtcHJvbWlzZSAtIGEgdGlueSBpbXBsZW1lbnRhdGlvbiBvZiBQcm9taXNlcy9BKy5cbiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDE0IFllaHVkYSBLYXR6LCBUb20gRGFsZSwgU3RlZmFuIFBlbm5lciBhbmQgY29udHJpYnV0b3JzIChDb252ZXJzaW9uIHRvIEVTNiBBUEkgYnkgSmFrZSBBcmNoaWJhbGQpXG4gKiBAbGljZW5zZSAgIExpY2Vuc2VkIHVuZGVyIE1JVCBsaWNlbnNlXG4gKiAgICAgICAgICAgIFNlZSBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3RlZmFucGVubmVyL2VzNi1wcm9taXNlL21hc3Rlci9MSUNFTlNFXG4gKiBAdmVyc2lvbiAgIDQuMS4xXG4gKi9cblxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0IHRydWUgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG5cdChnbG9iYWwuRVM2UHJvbWlzZSA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb2JqZWN0T3JGdW5jdGlvbih4KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHg7XG4gIHJldHVybiB4ICE9PSBudWxsICYmICh0eXBlID09PSAnb2JqZWN0JyB8fCB0eXBlID09PSAnZnVuY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih4KSB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxudmFyIF9pc0FycmF5ID0gdW5kZWZpbmVkO1xuaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF
1555O1xufSBlbHNlIHtcbiAgX2lzQXJyYXkgPSBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gIH07XG59XG5cbnZhciBpc0FycmF5ID0gX2lzQXJyYXk7XG5cbnZhciBsZW4gPSAwO1xudmFyIHZlcnR4TmV4dCA9IHVuZGVmaW5lZDtcbnZhciBjdXN0b21TY2hlZHVsZXJGbiA9IHVuZGVmaW5lZDtcblxudmFyIGFzYXAgPSBmdW5jdGlvbiBhc2FwKGNhbGxiYWNrLCBhcmcpIHtcbiAgcXVldWVbbGVuXSA9IGNhbGxiYWNrO1xuICBxdWV1ZVtsZW4gKyAxXSA9IGFyZztcbiAgbGVuICs9IDI7XG4gIGlmIChsZW4gPT09IDIpIHtcbiAgICAvLyBJZiBsZW4gaXMgMiwgdGhhdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gc2NoZWR1bGUgYW4gYXN5bmMgZmx1c2guXG4gICAgLy8gSWYgYWRkaXRpb25hbCBjYWxsYmFja3MgYXJlIHF1ZXVlZCBiZWZvcmUgdGhlIHF1ZXVlIGlzIGZsdXNoZWQsIHRoZXlcbiAgICAvLyB3aWxsIGJlIHByb2Nlc3NlZCBieSB0aGlzIGZsdXNoIHRoYXQgd2UgYXJlIHNjaGVkdWxpbmcuXG4gICAgaWYgKGN1c3RvbVNjaGVkdWxlckZuKSB7XG4gICAgICBjdXN0b21TY2hlZHVsZXJGbihmbHVzaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjaGVkdWxlRmx1c2goKTtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHNldFNjaGVkdWxlcihzY2hlZHVsZUZuKSB7XG4gIGN1c3RvbVNjaGVkdWxlckZuID0gc2NoZWR1bGVGbjtcbn1cblxuZnVuY3Rpb24gc2V0QXNhcChhc2FwRm4pIHtcbiAgYXNhcCA9IGFzYXBGbjtcbn1cblxudmFyIGJyb3dzZXJXaW5kb3cgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHVuZGVmaW5lZDtcbnZhciBicm93c2VyR2xvYmFsID0gYnJvd3NlcldpbmRvdyB8fCB7fTtcbnZhciBCcm93c2VyTXV0YXRpb25PYnNlcnZlciA9IGJyb3dzZXJHbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBicm93c2VyR2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgaXNOb2RlID0gdHlwZW9mIHNlbGYgPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiAoe30pLnRvU3RyaW5nLmNhbGwocHJvY2VzcykgPT09ICdbb2JqZWN0IHByb2Nlc3NdJztcblxuLy8gdGVzdCBmb3Igd2ViIHdvcmtlciBidXQgbm90IGluIElFMTBcbnZhciBpc1dvcmtlciA9IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGltcG9ydFNjcmlwdHMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCc7XG5cbi8vIG5vZGVcbmZ1bmN0aW9uIHVzZU5leHRUaWNrKCkge1xuICAvLyBub2RlIHZlcnNpb24gMC4xMC54IGRpc3BsYXlzIGEgZGVwcmVjYXRpb24gd2FybmluZyB3aGVuIG5leHRUaWNrIGlzIHVzZWQgcmVjdXJzaXZlbHlcbiAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jdWpvanMvd2hlbi9pc3N1ZXMvNDEwIGZvciBkZXRhaWxzXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICB9O1xufVxuXG4vLyB2ZXJ0eFxuZnVuY3Rpb24gdXNlVmVydHhUaW1lcigpIHtcbiAgaWYgKHR5cGVvZiB2ZXJ0eE5leHQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZlcnR4TmV4dChmbHVzaCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB1c2VTZXRUaW1lb3V0KCk7XG59XG5cbmZ1bmN0aW9uIHVzZU11dGF0aW9uT2JzZXJ2ZXIoKSB7XG4gIHZhciBpdGVyYXRpb25zID0gMDtcbiAgdmFyIG9ic2VydmVyID0gbmV3IEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyKGZsdXNoKTtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gIG9ic2VydmVyLm9ic2VydmUobm9kZSwgeyBjaGFyYWN0ZXJEYXRhOiB0cnVlIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgbm9kZS5kYXRhID0gaXRlcmF0aW9ucyA9ICsraXRlcmF0aW9ucyAlIDI7XG4gIH07XG59XG5cbi8vIHdlYiB3b3JrZXJcbmZ1bmN0aW9uIHVzZU1lc3NhZ2VDaGFubmVsKCkge1xuICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZsdXNoO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuICB9O1xufVxuXG5mdW5jdGlvbiB1c2VTZXRUaW1lb3V0KCkge1xuICAvLyBTdG9yZSBzZXRUaW1lb3V0IHJlZmVyZW5jZSBzbyBlczYtcHJvbWlzZSB3aWxsIGJlIHVuYWZmZWN0ZWQgYnlcbiAgLy8gb3RoZXIgY29kZSBtb2RpZnlpbmcgc2V0VGltZW91dCAobGlrZSBzaW5vbi51c2VGYWtlVGltZXJzKCkpXG4gIHZhciBnbG9iYWxTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZ2xvYmFsU2V0VGltZW91dChmbHVzaCwgMSk7XG4gIH07XG59XG5cbnZhciBxdWV1ZSA9IG5ldyBBcnJheSgxMDAwKTtcbmZ1bmN0aW9uIGZsdXNoKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgdmFyIGNhbGxiYWNrID0gcXVldWVbaV07XG4gICAgdmFyIGFyZyA9IHF1ZXVlW2kgKyAxXTtcblxuICAgIGNhbGxiYWNrKGFyZyk7XG5cbiAgICBxdWV1ZVtpXSA9IHVuZGVmaW5lZDtcbiAgICBxdWV1ZVtpICsgMV0gPSB1bmRlZmluZWQ7XG4gIH1cblxuICBsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0VmVydHgoKSB7XG4gIHRyeSB7XG4gICAgdmFyIHIgPSByZXF1aXJlO1xuICAgIHZhciB2ZXJ0eCA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XG4gICAgdmVydHhOZXh0ID0gdmVydHgucnVuT25Mb29wIHx8IHZlcnR4LnJ1bk9uQ29udGV4dDtcbiAgICByZXR1cm4gdXNlVmVydHhUaW1lcigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHVzZVNldFRpbWVvdXQoKTtcbiAgfVxufVxuXG52YXIgc2NoZWR1bGVGbHVzaCA9IHVuZGVmaW5lZDtcbi8vIERlY2lkZSB3aGF0IGFzeW5jIG1ldGhvZCB0byB1c2UgdG8gdHJpZ2dlcmluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlZCBjYWxsYmFja3M6XG5pZiAoaXNOb2RlKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VOZXh0VGljaygpO1xufSBlbHNlIGlmIChCcm93c2VyTXV0YXRpb25PYnNlcnZlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTXV0YXRpb25PYnNlcnZlcigpO1xufSBlbHNlIGlmIChpc1dvcmtlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTWVzc2FnZUNoYW5uZWwoKTtcbn0gZWxzZSBpZiAoYnJvd3NlcldpbmRvdyA9PT0gdW5kZWZpbmVkICYmIFwiZnVuY3Rpb25cIiA9PT0gJ2Z1bmN0aW9uJykge1xuICBzY2hlZHVsZUZsdXNoID0gYXR0ZW1wdFZlcnR4KCk7XG59IGVsc2Uge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlU2V0VGltZW91dCgpO1xufVxuXG5mdW5jdGlvbiB0aGVuKG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKSB7XG4gIHZhciBfYXJndW1lbnRzID0gYXJndW1lbnRzO1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzO1xuXG4gIHZhciBjaGlsZCA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKG5vb3ApO1xuXG4gIGlmIChjaGlsZFtQUk9NSVNFX0lEXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbWFrZVByb21pc2UoY2hpbGQpO1xuICB9XG5cbiAgdmFyIF9zdGF0ZSA9IHBhcmVudC5fc3RhdGU7XG5cbiAgaWYgKF9zdGF0ZSkge1xuICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICB2Y
155XIgY2FsbGJhY2sgPSBfYXJndW1lbnRzW19zdGF0ZSAtIDFdO1xuICAgICAgYXNhcChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBpbnZva2VDYWxsYmFjayhfc3RhdGUsIGNoaWxkLCBjYWxsYmFjaywgcGFyZW50Ll9yZXN1bHQpO1xuICAgICAgfSk7XG4gICAgfSkoKTtcbiAgfSBlbHNlIHtcbiAgICBzdWJzY3JpYmUocGFyZW50LCBjaGlsZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAgYFByb21pc2UucmVzb2x2ZWAgcmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlY29tZSByZXNvbHZlZCB3aXRoIHRoZVxuICBwYXNzZWQgYHZhbHVlYC4gSXQgaXMgc2hvcnRoYW5kIGZvciB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHJlc29sdmUoMSk7XG4gIH0pO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gdmFsdWUgPT09IDFcbiAgfSk7XG4gIGBgYFxuXG4gIEluc3RlYWQgb2Ygd3JpdGluZyB0aGUgYWJvdmUsIHlvdXIgY29kZSBub3cgc2ltcGx5IGJlY29tZXMgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKDEpO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gdmFsdWUgPT09IDFcbiAgfSk7XG4gIGBgYFxuXG4gIEBtZXRob2QgcmVzb2x2ZVxuICBAc3RhdGljXG4gIEBwYXJhbSB7QW55fSB2YWx1ZSB2YWx1ZSB0aGF0IHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVzb2x2ZWQgd2l0aFxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHdpbGwgYmVjb21lIGZ1bGZpbGxlZCB3aXRoIHRoZSBnaXZlblxuICBgdmFsdWVgXG4qL1xuZnVuY3Rpb24gcmVzb2x2ZSQxKG9iamVjdCkge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuXG4gIGlmIChvYmplY3QgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0LmNvbnN0cnVjdG9yID09PSBDb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICB2YXIgcHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcbiAgcmVzb2x2ZShwcm9taXNlLCBvYmplY3QpO1xuICByZXR1cm4gcHJvbWlzZTtcbn1cblxudmFyIFBST01JU0VfSUQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMTYpO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxudmFyIFBFTkRJTkcgPSB2b2lkIDA7XG52YXIgRlVMRklMTEVEID0gMTtcbnZhciBSRUpFQ1RFRCA9IDI7XG5cbnZhciBHRVRfVEhFTl9FUlJPUiA9IG5ldyBFcnJvck9iamVjdCgpO1xuXG5mdW5jdGlvbiBzZWxmRnVsZmlsbG1lbnQoKSB7XG4gIHJldHVybiBuZXcgVHlwZUVycm9yKFwiWW91IGNhbm5vdCByZXNvbHZlIGEgcHJvbWlzZSB3aXRoIGl0c2VsZlwiKTtcbn1cblxuZnVuY3Rpb24gY2Fubm90UmV0dXJuT3duKCkge1xuICByZXR1cm4gbmV3IFR5cGVFcnJvcignQSBwcm9taXNlcyBjYWxsYmFjayBjYW5ub3QgcmV0dXJuIHRoYXQgc2FtZSBwcm9taXNlLicpO1xufVxuXG5mdW5jdGlvbiBnZXRUaGVuKHByb21pc2UpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcHJvbWlzZS50aGVuO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIEdFVF9USEVOX0VSUk9SLmVycm9yID0gZXJyb3I7XG4gICAgcmV0dXJuIEdFVF9USEVOX0VSUk9SO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRyeVRoZW4odGhlbiQkMSwgdmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICB0cnkge1xuICAgIHRoZW4kJDEuY2FsbCh2YWx1ZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSwgdGhlbiQkMSkge1xuICBhc2FwKGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgdmFyIHNlYWxlZCA9IGZhbHNlO1xuICAgIHZhciBlcnJvciA9IHRyeVRoZW4odGhlbiQkMSwgdGhlbmFibGUsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHNlYWxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgaWYgKHRoZW5hYmxlICE9PSB2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIGlmIChzZWFsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2VhbGVkID0gdHJ1ZTtcblxuICAgICAgcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSwgJ1NldHRsZTogJyArIChwcm9taXNlLl9sYWJlbCB8fCAnIHVua25vd24gcHJvbWlzZScpKTtcblxuICAgIGlmICghc2VhbGVkICYmIGVycm9yKSB7XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICB9XG4gIH0sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVPd25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSkge1xuICBpZiAodGhlbmFibGUuX3N0YXRlID09PSBGVUxGSUxMRUQpIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICB9IGVsc2UgaWYgKHRoZW5hYmxlLl9zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICByZWplY3QocHJvbWlzZSwgdGhlbmFibGUuX3Jlc3VsdCk7XG4gIH0gZWxzZSB7XG4gICAgc3Vic2NyaWJlKHRoZW5hYmxlLCB1bmRlZmluZWQsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHJldHVybi
155ByZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUsIHRoZW4kJDEpIHtcbiAgaWYgKG1heWJlVGhlbmFibGUuY29uc3RydWN0b3IgPT09IHByb21pc2UuY29uc3RydWN0b3IgJiYgdGhlbiQkMSA9PT0gdGhlbiAmJiBtYXliZVRoZW5hYmxlLmNvbnN0cnVjdG9yLnJlc29sdmUgPT09IHJlc29sdmUkMSkge1xuICAgIGhhbmRsZU93blRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICB9IGVsc2Uge1xuICAgIGlmICh0aGVuJCQxID09PSBHRVRfVEhFTl9FUlJPUikge1xuICAgICAgcmVqZWN0KHByb21pc2UsIEdFVF9USEVOX0VSUk9SLmVycm9yKTtcbiAgICAgIEdFVF9USEVOX0VSUk9SLmVycm9yID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKHRoZW4kJDEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24odGhlbiQkMSkpIHtcbiAgICAgIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlLCB0aGVuJCQxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICByZWplY3QocHJvbWlzZSwgc2VsZkZ1bGZpbGxtZW50KCkpO1xuICB9IGVsc2UgaWYgKG9iamVjdE9yRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCB2YWx1ZSwgZ2V0VGhlbih2YWx1ZSkpO1xuICB9IGVsc2Uge1xuICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2hSZWplY3Rpb24ocHJvbWlzZSkge1xuICBpZiAocHJvbWlzZS5fb25lcnJvcikge1xuICAgIHByb21pc2UuX29uZXJyb3IocHJvbWlzZS5fcmVzdWx0KTtcbiAgfVxuXG4gIHB1Ymxpc2gocHJvbWlzZSk7XG59XG5cbmZ1bmN0aW9uIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvbWlzZS5fcmVzdWx0ID0gdmFsdWU7XG4gIHByb21pc2UuX3N0YXRlID0gRlVMRklMTEVEO1xuXG4gIGlmIChwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggIT09IDApIHtcbiAgICBhc2FwKHB1Ymxpc2gsIHByb21pc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlamVjdChwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHByb21pc2UuX3N0YXRlID0gUkVKRUNURUQ7XG4gIHByb21pc2UuX3Jlc3VsdCA9IHJlYXNvbjtcblxuICBhc2FwKHB1Ymxpc2hSZWplY3Rpb24sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBzdWJzY3JpYmUocGFyZW50LCBjaGlsZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcbiAgdmFyIF9zdWJzY3JpYmVycyA9IHBhcmVudC5fc3Vic2NyaWJlcnM7XG4gIHZhciBsZW5ndGggPSBfc3Vic2NyaWJlcnMubGVuZ3RoO1xuXG4gIHBhcmVudC5fb25lcnJvciA9IG51bGw7XG5cbiAgX3N1YnNjcmliZXJzW2xlbmd0aF0gPSBjaGlsZDtcbiAgX3N1YnNjcmliZXJzW2xlbmd0aCArIEZVTEZJTExFRF0gPSBvbkZ1bGZpbGxtZW50O1xuICBfc3Vic2NyaWJlcnNbbGVuZ3RoICsgUkVKRUNURURdID0gb25SZWplY3Rpb247XG5cbiAgaWYgKGxlbmd0aCA9PT0gMCAmJiBwYXJlbnQuX3N0YXRlKSB7XG4gICAgYXNhcChwdWJsaXNoLCBwYXJlbnQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2gocHJvbWlzZSkge1xuICB2YXIgc3Vic2NyaWJlcnMgPSBwcm9taXNlLl9zdWJzY3JpYmVycztcbiAgdmFyIHNldHRsZWQgPSBwcm9taXNlLl9zdGF0ZTtcblxuICBpZiAoc3Vic2NyaWJlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gdW5kZWZpbmVkLFxuICAgICAgY2FsbGJhY2sgPSB1bmRlZmluZWQsXG4gICAgICBkZXRhaWwgPSBwcm9taXNlLl9yZXN1bHQ7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzY3JpYmVycy5sZW5ndGg7IGkgKz0gMykge1xuICAgIGNoaWxkID0gc3Vic2NyaWJlcnNbaV07XG4gICAgY2FsbGJhY2sgPSBzdWJzY3JpYmVyc1tpICsgc2V0dGxlZF07XG5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGludm9rZUNhbGxiYWNrKHNldHRsZWQsIGNoaWxkLCBjYWxsYmFjaywgZGV0YWlsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2soZGV0YWlsKTtcbiAgICB9XG4gIH1cblxuICBwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggPSAwO1xufVxuXG5mdW5jdGlvbiBFcnJvck9iamVjdCgpIHtcbiAgdGhpcy5lcnJvciA9IG51bGw7XG59XG5cbnZhciBUUllfQ0FUQ0hfRVJST1IgPSBuZXcgRXJyb3JPYmplY3QoKTtcblxuZnVuY3Rpb24gdHJ5Q2F0Y2goY2FsbGJhY2ssIGRldGFpbCkge1xuICB0cnkge1xuICAgIHJldHVybiBjYWxsYmFjayhkZXRhaWwpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgVFJZX0NBVENIX0VSUk9SLmVycm9yID0gZTtcbiAgICByZXR1cm4gVFJZX0NBVENIX0VSUk9SO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUNhbGxiYWNrKHNldHRsZWQsIHByb21pc2UsIGNhbGxiYWNrLCBkZXRhaWwpIHtcbiAgdmFyIGhhc0NhbGxiYWNrID0gaXNGdW5jdGlvbihjYWxsYmFjayksXG4gICAgICB2YWx1ZSA9IHVuZGVmaW5lZCxcbiAgICAgIGVycm9yID0gdW5kZWZpbmVkLFxuICAgICAgc3VjY2VlZGVkID0gdW5kZWZpbmVkLFxuICAgICAgZmFpbGVkID0gdW5kZWZpbmVkO1xuXG4gIGlmIChoYXNDYWxsYmFjaykge1xuICAgIHZhbHVlID0gdHJ5Q2F0Y2goY2FsbGJhY2ssIGRldGFpbCk7XG5cbiAgICBpZiAodmFsdWUgPT09IFRSWV9DQVRDSF9FUlJPUikge1xuICAgICAgZmFpbGVkID0gdHJ1ZTtcbiAgICAgIGVycm9yID0gdmFsdWUuZXJyb3I7XG4gICAgICB2YWx1ZS
1555lcnJvciA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1Y2NlZWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB7XG4gICAgICByZWplY3QocHJvbWlzZSwgY2Fubm90UmV0dXJuT3duKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IGRldGFpbDtcbiAgICBzdWNjZWVkZWQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgLy8gbm9vcFxuICB9IGVsc2UgaWYgKGhhc0NhbGxiYWNrICYmIHN1Y2NlZWRlZCkge1xuICAgICAgcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChmYWlsZWQpIHtcbiAgICAgIHJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgfSBlbHNlIGlmIChzZXR0bGVkID09PSBGVUxGSUxMRUQpIHtcbiAgICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoc2V0dGxlZCA9PT0gUkVKRUNURUQpIHtcbiAgICAgIHJlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplUHJvbWlzZShwcm9taXNlLCByZXNvbHZlcikge1xuICB0cnkge1xuICAgIHJlc29sdmVyKGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHZhbHVlKSB7XG4gICAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiByZWplY3RQcm9taXNlKHJlYXNvbikge1xuICAgICAgcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZWplY3QocHJvbWlzZSwgZSk7XG4gIH1cbn1cblxudmFyIGlkID0gMDtcbmZ1bmN0aW9uIG5leHRJZCgpIHtcbiAgcmV0dXJuIGlkKys7XG59XG5cbmZ1bmN0aW9uIG1ha2VQcm9taXNlKHByb21pc2UpIHtcbiAgcHJvbWlzZVtQUk9NSVNFX0lEXSA9IGlkKys7XG4gIHByb21pc2UuX3N0YXRlID0gdW5kZWZpbmVkO1xuICBwcm9taXNlLl9yZXN1bHQgPSB1bmRlZmluZWQ7XG4gIHByb21pc2UuX3N1YnNjcmliZXJzID0gW107XG59XG5cbmZ1bmN0aW9uIEVudW1lcmF0b3IkMShDb25zdHJ1Y3RvciwgaW5wdXQpIHtcbiAgdGhpcy5faW5zdGFuY2VDb25zdHJ1Y3RvciA9IENvbnN0cnVjdG9yO1xuICB0aGlzLnByb21pc2UgPSBuZXcgQ29uc3RydWN0b3Iobm9vcCk7XG5cbiAgaWYgKCF0aGlzLnByb21pc2VbUFJPTUlTRV9JRF0pIHtcbiAgICBtYWtlUHJvbWlzZSh0aGlzLnByb21pc2UpO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgdGhpcy5sZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgdGhpcy5fcmVtYWluaW5nID0gaW5wdXQubGVuZ3RoO1xuXG4gICAgdGhpcy5fcmVzdWx0ID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy5sZW5ndGggfHwgMDtcbiAgICAgIHRoaXMuX2VudW1lcmF0ZShpbnB1dCk7XG4gICAgICBpZiAodGhpcy5fcmVtYWluaW5nID09PSAwKSB7XG4gICAgICAgIGZ1bGZpbGwodGhpcy5wcm9taXNlLCB0aGlzLl9yZXN1bHQpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZWplY3QodGhpcy5wcm9taXNlLCB2YWxpZGF0aW9uRXJyb3IoKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGlvbkVycm9yKCkge1xuICByZXR1cm4gbmV3IEVycm9yKCdBcnJheSBNZXRob2RzIG11c3QgYmUgcHJvdmlkZWQgYW4gQXJyYXknKTtcbn1cblxuRW51bWVyYXRvciQxLnByb3RvdHlwZS5fZW51bWVyYXRlID0gZnVuY3Rpb24gKGlucHV0KSB7XG4gIGZvciAodmFyIGkgPSAwOyB0aGlzLl9zdGF0ZSA9PT0gUEVORElORyAmJiBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLl9lYWNoRW50cnkoaW5wdXRbaV0sIGkpO1xuICB9XG59O1xuXG5FbnVtZXJhdG9yJDEucHJvdG90eXBlLl9lYWNoRW50cnkgPSBmdW5jdGlvbiAoZW50cnksIGkpIHtcbiAgdmFyIGMgPSB0aGlzLl9pbnN0YW5jZUNvbnN0cnVjdG9yO1xuICB2YXIgcmVzb2x2ZSQkMSA9IGMucmVzb2x2ZTtcblxuICBpZiAocmVzb2x2ZSQkMSA9PT0gcmVzb2x2ZSQxKSB7XG4gICAgdmFyIF90aGVuID0gZ2V0VGhlbihlbnRyeSk7XG5cbiAgICBpZiAoX3RoZW4gPT09IHRoZW4gJiYgZW50cnkuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgICB0aGlzLl9zZXR0bGVkQXQoZW50cnkuX3N0YXRlLCBpLCBlbnRyeS5fcmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBfdGhlbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5fcmVtYWluaW5nLS07XG4gICAgICB0aGlzLl9yZXN1bHRbaV0gPSBlbnRyeTtcbiAgICB9IGVsc2UgaWYgKGMgPT09IFByb21pc2UkMikge1xuICAgICAgdmFyIHByb21pc2UgPSBuZXcgYyhub29wKTtcbiAgICAgIGhhbmRsZU1heWJlVGhlbmFibGUocHJvbWlzZSwgZW50cnksIF90aGVuKTtcbiAgICAgIHRoaXMuX3dpbGxTZXR0bGVBdChwcm9taXNlLCBpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fd2lsbFNldHRsZUF0KG5ldyBjKGZ1bmN0aW9uIChyZXNvbHZlJCQxKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlJCQxKGVudHJ5KTtcbiAgICAgIH0pLCBpKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fd2lsbFNldHRsZUF0KHJlc29sdmUkJDEoZW50cnkpLCBpKTtcbiAgfVxufTtcblxuRW51bWVyYXRvciQxLnByb3RvdHlwZS5fc2V0dGxlZEF0ID0gZnVuY3Rpb24gKHN0YXRlLCBpLCB2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcblxuICBpZiAocHJvbWlzZS5fc3RhdGUgPT09IFBFTkRJTkcpIHtcbiAgICB0aGlzLl9yZW1haW5pbmctLTtcblxuICAgIGlmIChzdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICAgIHJlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3Jlc3VsdFtpXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHR
155oaXMuX3Jlc3VsdCk7XG4gIH1cbn07XG5cbkVudW1lcmF0b3IkMS5wcm90b3R5cGUuX3dpbGxTZXR0bGVBdCA9IGZ1bmN0aW9uIChwcm9taXNlLCBpKSB7XG4gIHZhciBlbnVtZXJhdG9yID0gdGhpcztcblxuICBzdWJzY3JpYmUocHJvbWlzZSwgdW5kZWZpbmVkLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gZW51bWVyYXRvci5fc2V0dGxlZEF0KEZVTEZJTExFRCwgaSwgdmFsdWUpO1xuICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgcmV0dXJuIGVudW1lcmF0b3IuX3NldHRsZWRBdChSRUpFQ1RFRCwgaSwgcmVhc29uKTtcbiAgfSk7XG59O1xuXG4vKipcbiAgYFByb21pc2UuYWxsYCBhY2NlcHRzIGFuIGFycmF5IG9mIHByb21pc2VzLCBhbmQgcmV0dXJucyBhIG5ldyBwcm9taXNlIHdoaWNoXG4gIGlzIGZ1bGZpbGxlZCB3aXRoIGFuIGFycmF5IG9mIGZ1bGZpbGxtZW50IHZhbHVlcyBmb3IgdGhlIHBhc3NlZCBwcm9taXNlcywgb3JcbiAgcmVqZWN0ZWQgd2l0aCB0aGUgcmVhc29uIG9mIHRoZSBmaXJzdCBwYXNzZWQgcHJvbWlzZSB0byBiZSByZWplY3RlZC4gSXQgY2FzdHMgYWxsXG4gIGVsZW1lbnRzIG9mIHRoZSBwYXNzZWQgaXRlcmFibGUgdG8gcHJvbWlzZXMgYXMgaXQgcnVucyB0aGlzIGFsZ29yaXRobS5cblxuICBFeGFtcGxlOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gcmVzb2x2ZSgxKTtcbiAgbGV0IHByb21pc2UyID0gcmVzb2x2ZSgyKTtcbiAgbGV0IHByb21pc2UzID0gcmVzb2x2ZSgzKTtcbiAgbGV0IHByb21pc2VzID0gWyBwcm9taXNlMSwgcHJvbWlzZTIsIHByb21pc2UzIF07XG5cbiAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24oYXJyYXkpe1xuICAgIC8vIFRoZSBhcnJheSBoZXJlIHdvdWxkIGJlIFsgMSwgMiwgMyBdO1xuICB9KTtcbiAgYGBgXG5cbiAgSWYgYW55IG9mIHRoZSBgcHJvbWlzZXNgIGdpdmVuIHRvIGBhbGxgIGFyZSByZWplY3RlZCwgdGhlIGZpcnN0IHByb21pc2VcbiAgdGhhdCBpcyByZWplY3RlZCB3aWxsIGJlIGdpdmVuIGFzIGFuIGFyZ3VtZW50IHRvIHRoZSByZXR1cm5lZCBwcm9taXNlcydzXG4gIHJlamVjdGlvbiBoYW5kbGVyLiBGb3IgZXhhbXBsZTpcblxuICBFeGFtcGxlOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gcmVzb2x2ZSgxKTtcbiAgbGV0IHByb21pc2UyID0gcmVqZWN0KG5ldyBFcnJvcihcIjJcIikpO1xuICBsZXQgcHJvbWlzZTMgPSByZWplY3QobmV3IEVycm9yKFwiM1wiKSk7XG4gIGxldCBwcm9taXNlcyA9IFsgcHJvbWlzZTEsIHByb21pc2UyLCBwcm9taXNlMyBdO1xuXG4gIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKGZ1bmN0aW9uKGFycmF5KXtcbiAgICAvLyBDb2RlIGhlcmUgbmV2ZXIgcnVucyBiZWNhdXNlIHRoZXJlIGFyZSByZWplY3RlZCBwcm9taXNlcyFcbiAgfSwgZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAvLyBlcnJvci5tZXNzYWdlID09PSBcIjJcIlxuICB9KTtcbiAgYGBgXG5cbiAgQG1ldGhvZCBhbGxcbiAgQHN0YXRpY1xuICBAcGFyYW0ge0FycmF5fSBlbnRyaWVzIGFycmF5IG9mIHByb21pc2VzXG4gIEBwYXJhbSB7U3RyaW5nfSBsYWJlbCBvcHRpb25hbCBzdHJpbmcgZm9yIGxhYmVsaW5nIHRoZSBwcm9taXNlLlxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgd2hlbiBhbGwgYHByb21pc2VzYCBoYXZlIGJlZW5cbiAgZnVsZmlsbGVkLCBvciByZWplY3RlZCBpZiBhbnkgb2YgdGhlbSBiZWNvbWUgcmVqZWN0ZWQuXG4gIEBzdGF0aWNcbiovXG5mdW5jdGlvbiBhbGwkMShlbnRyaWVzKSB7XG4gIHJldHVybiBuZXcgRW51bWVyYXRvciQxKHRoaXMsIGVudHJpZXMpLnByb21pc2U7XG59XG5cbi8qKlxuICBgUHJvbWlzZS5yYWNlYCByZXR1cm5zIGEgbmV3IHByb21pc2Ugd2hpY2ggaXMgc2V0dGxlZCBpbiB0aGUgc2FtZSB3YXkgYXMgdGhlXG4gIGZpcnN0IHBhc3NlZCBwcm9taXNlIHRvIHNldHRsZS5cblxuICBFeGFtcGxlOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDEnKTtcbiAgICB9LCAyMDApO1xuICB9KTtcblxuICBsZXQgcHJvbWlzZTIgPSBuZXcgUHJvbWlzZS
155hmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlc29sdmUoJ3Byb21pc2UgMicpO1xuICAgIH0sIDEwMCk7XG4gIH0pO1xuXG4gIFByb21pc2UucmFjZShbcHJvbWlzZTEsIHByb21pc2UyXSkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgIC8vIHJlc3VsdCA9PT0gJ3Byb21pc2UgMicgYmVjYXVzZSBpdCB3YXMgcmVzb2x2ZWQgYmVmb3JlIHByb21pc2UxXG4gICAgLy8gd2FzIHJlc29sdmVkLlxuICB9KTtcbiAgYGBgXG5cbiAgYFByb21pc2UucmFjZWAgaXMgZGV0ZXJtaW5pc3RpYyBpbiB0aGF0IG9ubHkgdGhlIHN0YXRlIG9mIHRoZSBmaXJzdFxuICBzZXR0bGVkIHByb21pc2UgbWF0dGVycy4gRm9yIGV4YW1wbGUsIGV2ZW4gaWYgb3RoZXIgcHJvbWlzZXMgZ2l2ZW4gdG8gdGhlXG4gIGBwcm9taXNlc2AgYXJyYXkgYXJndW1lbnQgYXJlIHJlc29sdmVkLCBidXQgdGhlIGZpcnN0IHNldHRsZWQgcHJvbWlzZSBoYXNcbiAgYmVjb21lIHJlamVjdGVkIGJlZm9yZSB0aGUgb3RoZXIgcHJvbWlzZXMgYmVjYW1lIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gIHByb21pc2Ugd2lsbCBiZWNvbWUgcmVqZWN0ZWQ6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlc29sdmUoJ3Byb21pc2UgMScpO1xuICAgIH0sIDIwMCk7XG4gIH0pO1xuXG4gIGxldCBwcm9taXNlMiA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcigncHJvbWlzZSAyJykpO1xuICAgIH0sIDEwMCk7XG4gIH0pO1xuXG4gIFByb21pc2UucmFjZShbcHJvbWlzZTEsIHByb21pc2UyXSkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgIC8vIENvZGUgaGVyZSBuZXZlciBydW5zXG4gIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgLy8gcmVhc29uLm1lc3NhZ2UgPT09ICdwcm9taXNlIDInIGJlY2F1c2UgcHJvbWlzZSAyIGJlY2FtZSByZWplY3RlZCBiZWZvcmVcbiAgICAvLyBwcm9taXNlIDEgYmVjYW1lIGZ1bGZpbGxlZFxuICB9KTtcbiAgYGBgXG5cbiAgQW4gZXhhbXBsZSByZWFsLXdvcmxkIHVzZSBjYXNlIGlzIGltcGxlbWVudGluZyB0aW1lb3V0czpcblxuICBgYGBqYXZhc2NyaXB0XG4gIFByb21pc2UucmFjZShbYWpheCgnZm9vLmpzb24nKSwgdGltZW91dCg1MDAwKV0pXG4gIGBgYFxuXG4gIEBtZXRob2QgcmFjZVxuICBAc3RhdGljXG4gIEBwYXJhbSB7QXJyYXl9IHByb21pc2VzIGFycmF5IG9mIHByb21pc2VzIHRvIG9ic2VydmVcbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2Ugd2hpY2ggc2V0dGxlcyBpbiB0aGUgc2FtZSB3YXkgYXMgdGhlIGZpcnN0IHBhc3NlZFxuICBwcm9taXNlIHRvIHNldHRsZS5cbiovXG5mdW5jdGlvbiByYWNlJDEoZW50cmllcykge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuXG4gIGlmICghaXNBcnJheShlbnRyaWVzKSkge1xuICAgIHJldHVybiBuZXcgQ29uc3RydWN0b3IoZnVuY3Rpb24gKF8sIHJlamVjdCkge1xuICAgICAgcmV0dXJuIHJlamVjdChuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGFuIGFycmF5IHRvIHJhY2UuJykpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgQ29uc3RydWN0b3IoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGVudHJpZXMubGVuZ3RoO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBDb25zdHJ1Y3Rvci5yZXNvbHZlKGVudHJpZXNbaV0pLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAgYFByb21pc2UucmVqZWN0YCByZXR1cm5zIGEgcHJvbWlzZSByZWplY3RlZCB3aXRoIHRoZSBwYXNzZWQgYHJlYXNvbmAuXG4gIEl0IGlzIHNob3J0aGFuZCBmb3IgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICByZWplY3QobmV3IEVycm9yKCdXSE9PUFMnKSk7XG4gIH0pO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gQ29kZSBoZXJlIGRvZXNuJ3QgcnVuIGJlY2F1c2UgdGhlIHByb21pc2UgaXMgcmVqZWN0ZWQhXG4gIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgLy8gcmVhc29uLm1lc3NhZ2UgPT09ICdXSE9PUFMnXG4gIH0pO1xuICBgYGBcblxuICBJbnN0ZWFkIG9mIHdyaXRpbmcgdGhlIGFib3ZlLCB5b3VyIGNvZGUgbm93IHNpbXBseSBiZWNvbWVzIHRoZSBmb2xsb3dpbmc6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZSA9IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignV0hPT1BTJykpO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gQ29kZSBoZXJlIGRvZXNuJ3QgcnVuIGJlY2F1c2UgdGhlIHByb21pc2UgaXMgcmVqZWN0ZWQhXG4gIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgLy8gcmVhc29uLm1lc3NhZ2UgPT09ICdXSE9PUFMnXG4gIH0pO1xuICBgYGBcblxuICBAbWV0aG9kIHJlamVjdFxuICBAc3RhdGljXG4gIEBwYXJhbSB7QW55fSByZWFzb24gdmFsdWUgdGhhdCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGguXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHJlamVjdGVkIHdpdGggdGhlIGdpdmVuIGByZWFzb25gLlxuKi9cbmZ1bmN0aW9uIHJlamVjdCQxKHJlYXNvbikge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuICB2YXIgcHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcbiAg
vendor: 4,535 bytes, line 155
155cmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBuZWVkc1Jlc29sdmVyKCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGEgcmVzb2x2ZXIgZnVuY3Rpb24gYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBwcm9taXNlIGNvbnN0cnVjdG9yJyk7XG59XG5cbmZ1bmN0aW9uIG5lZWRzTmV3KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnUHJvbWlzZSc6IFBsZWFzZSB1c2UgdGhlICduZXcnIG9wZXJhdG9yLCB0aGlzIG9iamVjdCBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIGFzIGEgZnVuY3Rpb24uXCIpO1xufVxuXG4vKipcbiAgUHJvbWlzZSBvYmplY3RzIHJlcHJlc2VudCB0aGUgZXZlbnR1YWwgcmVzdWx0IG9mIGFuIGFzeW5jaHJvbm91cyBvcGVyYXRpb24uIFRoZVxuICBwcmltYXJ5IHdheSBvZiBpbnRlcmFjdGluZyB3aXRoIGEgcHJvbWlzZSBpcyB0aHJvdWdoIGl0cyBgdGhlbmAgbWV0aG9kLCB3aGljaFxuICByZWdpc3RlcnMgY2FsbGJhY2tzIHRvIHJlY2VpdmUgZWl0aGVyIGEgcHJvbWlzZSdzIGV2ZW50dWFsIHZhbHVlIG9yIHRoZSByZWFzb25cbiAgd2h5IHRoZSBwcm9taXNlIGNhbm5vdCBiZSBmdWxmaWxsZWQuXG5cbiAgVGVybWlub2xvZ3lcbiAgLS0tLS0tLS0tLS1cblxuICAtIGBwcm9taXNlYCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gd2l0aCBhIGB0aGVuYCBtZXRob2Qgd2hvc2UgYmVoYXZpb3IgY29uZm9ybXMgdG8gdGhpcyBzcGVjaWZpY2F0aW9uLlxuICAtIGB0aGVuYWJsZWAgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHRoYXQgZGVmaW5lcyBhIGB0aGVuYCBtZXRob2QuXG4gIC0gYHZhbHVlYCBpcyBhbnkgbGVnYWwgSmF2YVNjcmlwdCB2YWx1ZSAoaW5jbHVkaW5nIHVuZGVmaW5lZCwgYSB0aGVuYWJsZSwgb3IgYSBwcm9taXNlKS5cbiAgLSBgZXhjZXB0aW9uYCBpcyBhIHZhbHVlIHRoYXQgaXMgdGhyb3duIHVzaW5nIHRoZSB0aHJvdyBzdGF0ZW1lbnQuXG4gIC0gYHJlYXNvbmAgaXMgYSB2YWx1ZSB0aGF0IGluZGljYXRlcyB3aHkgYSBwcm9taXNlIHdhcyByZWplY3RlZC5cbiAgLSBgc2V0dGxlZGAgdGhlIGZpbmFsIHJlc3Rpbmcgc3RhdGUgb2YgYSBwcm9taXNlLCBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG5cbiAgQSBwcm9taXNlIGNhbiBiZSBpbiBvbmUgb2YgdGhyZWUgc3RhdGVzOiBwZW5kaW5nLCBmdWxmaWxsZWQsIG9yIHJlamVjdGVkLlxuXG4gIFByb21pc2VzIHRoYXQgYXJlIGZ1bGZpbGxlZCBoYXZlIGEgZnVsZmlsbG1lbnQgdmFsdWUgYW5kIGFyZSBpbiB0aGUgZnVsZmlsbGVkXG4gIHN0YXRlLiAgUHJvbWlzZXMgdGhhdCBhcmUgcmVqZWN0ZWQgaGF2ZSBhIHJlamVjdGlvbiByZWFzb24gYW5kIGFyZSBpbiB0aGVcbiAgcmVqZWN0ZWQgc3RhdGUuICBBIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5ldmVyIGEgdGhlbmFibGUuXG5cbiAgUHJvbWlzZXMgY2FuIGFsc28gYmUgc2FpZCB0byAqcmVzb2x2ZSogYSB2YWx1ZS4gIElmIHRoaXMgdmFsdWUgaXMgYWxzbyBhXG4gIHByb21pc2UsIHRoZW4gdGhlIG9yaWdpbmFsIHByb21pc2UncyBzZXR0bGVkIHN0YXRlIHdpbGwgbWF0Y2ggdGhlIHZhbHVlJ3NcbiAgc2V0dGxlZCBzdGF0ZS4gIFNvIGEgcHJvbWlzZSB0aGF0ICpyZXNvbHZlcyogYSBwcm9taXNlIHRoYXQgcmVqZWN0cyB3aWxsXG4gIGl0c2VsZiByZWplY3QsIGFuZCBhIHByb21pc2UgdGhhdCAqcmVzb2x2ZXMqIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIHdpbGxcbiAgaXRzZWxmIGZ1bGZpbGwuXG5cblxuICBCYXNpYyBVc2FnZTpcbiAgLS0tLS0tLS0tLS0tXG5cbiAgYGBganNcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAvLyBvbiBzdWNjZXNzXG4gICAgcmVzb2x2ZSh2YWx1ZSk7XG5cbiAgICAvLyBvbiBmYWlsdXJlXG4gICAgcmVqZWN0KHJlYXNvbik7XG4gIH0pO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIG9uIGZ1bGZpbGxtZW50XG4gIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIC8vIG9uIHJlamVjdGlvblxuICB9KTtcbiAgYGBgXG5cbiAgQWR2YW5jZWQgVXNhZ2U6XG4gIC0tLS0tLS0tLS0tLS0tLVxuXG4gIFByb21pc2VzIHNoaW5lIHdoZW4gYWJzdHJhY3RpbmcgYXdheSBhc3luY2hyb25vdXMgaW50ZXJhY3Rpb25zIHN1Y2ggYXNcbiAgYFhNTEh0dHBSZXF1ZXN0YHMuXG5cbiAgYGBganNcbiAgZnVuY3Rpb24gZ2V0SlNPTih1cmwpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICAgIGxldCB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgICAgeGhyLm9wZW4oJ0dFVCcsIHVybCk7XG4gICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gaGFuZGxlcjtcbiAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnanNvbic7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgIHhoci5zZW5kKCk7XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IHRoaXMuRE9ORSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICByZXNvbHZlKHRoaXMucmVzcG9uc2UpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdnZXRKU09OOiBgJyArIHVybCArICdgIGZhaWxlZCB3aXRoIHN0YXR1czogWycgKyB0aGlzLnN0YXR1cyArICddJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEpTT04oJy9wb3N0cy5qc29uJykudGhlbihmdW5jdGlvbihqc29uKSB7XG4gICAgLy8gb24gZnVsZmlsbG1lbnRcbiAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgLy8gb24gcmVqZWN0aW9uXG4gIH0pO1xuICBgYGBcblxuICBVbmxpa2UgY2FsbGJhY2tzLCBwcm9taXNlcyBhcmUgZ3JlYXQgY29tcG9zYWJsZSBwcmltaXRpdmVzLlxuXG4gIGBgYGpzXG4gIFByb21pc2UuYWxsKFtcbiAgICBnZXRKU09OKCcvcG9zdHMnKSxcbiAgICBnZXRKU09OKCcvY29tbWVudHMnKVxuICBdKS50aGVuKGZ1bmN0aW9uKHZhbHVlcyl7XG4gICAgdmFsdWVzWzBdIC8vID0+IHBvc3RzSlNPTlxuICAgIHZhbHVlc1sxXSAvLyA9PiBjb21tZW50c0pTT05cblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH0pO1xuICBgYGBcblxuICBAY2xhc3MgUHJvbWlzZVxuICBAcGFyYW0ge2Z1bmN0aW9ufSByZXNvbHZlclxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEBjb25zdHJ1Y3RvclxuKi9cbmZ1bmN0aW9uIFByb21pc2U
155kMihyZXNvbHZlcikge1xuICB0aGlzW1BST01JU0VfSURdID0gbmV4dElkKCk7XG4gIHRoaXMuX3Jlc3VsdCA9IHRoaXMuX3N0YXRlID0gdW5kZWZpbmVkO1xuICB0aGlzLl9zdWJzY3JpYmVycyA9IFtdO1xuXG4gIGlmIChub29wICE9PSByZXNvbHZlcikge1xuICAgIHR5cGVvZiByZXNvbHZlciAhPT0gJ2Z1bmN0aW9uJyAmJiBuZWVkc1Jlc29sdmVyKCk7XG4gICAgdGhpcyBpbnN0YW5jZW9mIFByb21pc2UkMiA/IGluaXRpYWxpemVQcm9taXNlKHRoaXMsIHJlc29sdmVyKSA6IG5lZWRzTmV3KCk7XG4gIH1cbn1cblxuUHJvbWlzZSQyLmFsbCA9IGFsbCQxO1xuUHJvbWlzZSQyLnJhY2UgPSByYWNlJDE7XG5Qcm9taXNlJDIucmVzb2x2ZSA9IHJlc29sdmUkMTtcblByb21pc2UkMi5yZWplY3QgPSByZWplY3QkMTtcblByb21pc2UkMi5fc2V0U2NoZWR1bGVyID0gc2V0U2NoZWR1bGVyO1xuUHJvbWlzZSQyLl9zZXRBc2FwID0gc2V0QXNhcDtcblByb21pc2UkMi5fYXNhcCA9IGFzYXA7XG5cblByb21pc2UkMi5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBQcm9taXNlJDIsXG5cbiAgLyoqXG4gICAgVGhlIHByaW1hcnkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggYSBwcm9taXNlIGlzIHRocm91Z2ggaXRzIGB0aGVuYCBtZXRob2QsXG4gICAgd2hpY2ggcmVnaXN0ZXJzIGNhbGxiYWNrcyB0byByZWNlaXZlIGVpdGhlciBhIHByb21pc2UncyBldmVudHVhbCB2YWx1ZSBvciB0aGVcbiAgICByZWFzb24gd2h5IHRoZSBwcm9taXNlIGNhbm5vdCBiZSBmdWxmaWxsZWQuXG4gIFxuICAgIGBgYGpzXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uKHVzZXIpe1xuICAgICAgLy8gdXNlciBpcyBhdmFpbGFibGVcbiAgICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgICAgLy8gdXNlciBpcyB1bmF2YWlsYWJsZSwgYW5kIHlvdSBhcmUgZ2l2ZW4gdGhlIHJlYXNvbiB3aHlcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQ2hhaW5pbmdcbiAgICAtLS0tLS0tLVxuICBcbiAgICBUaGUgcmV0dXJuIHZhbHVlIG9mIGB0aGVuYCBpcyBpdHNlbGYgYSBwcm9taXNlLiAgVGhpcyBzZWNvbmQsICdkb3duc3RyZWFtJ1xuICAgIHByb21pc2UgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBmaXJzdCBwcm9taXNlJ3MgZnVsZmlsbG1lbnRcbiAgICBvciByZWplY3Rpb24gaGFuZGxlciwgb3IgcmVqZWN0ZWQgaWYgdGhlIGhhbmRsZXIgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgXG4gICAgYGBganNcbiAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgIHJldHVybiB1c2VyLm5hbWU7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgcmV0dXJuICdkZWZhdWx0IG5hbWUnO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKHVzZXJOYW1lKSB7XG4gICAgICAvLyBJZiBgZmluZFVzZXJgIGZ1bGZpbGxlZCwgYHVzZXJOYW1lYCB3aWxsIGJlIHRoZSB1c2VyJ3MgbmFtZSwgb3RoZXJ3aXNlIGl0XG4gICAgICAvLyB3aWxsIGJlIGAnZGVmYXVsdCBuYW1lJ2BcbiAgICB9KTtcbiAgXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIHVzZXIsIGJ1dCBzdGlsbCB1bmhhcHB5Jyk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgZmluZFVzZXJgIHJlamVjdGVkIGFuZCB3ZSdyZSB1bmhhcHB5Jyk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAvLyBpZiBgZmluZFVzZXJgIGZ1bGZpbGxlZCwgYHJlYXNvbmAgd2lsbCBiZSAnRm91bmQgdXNlciwgYnV0IHN0aWxsIHVuaGFwcHknLlxuICAgICAgLy8gSWYgYGZpbmRVc2VyYCByZWplY3RlZCwgYHJlYXNvbmAgd2lsbCBiZSAnYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScuXG4gICAgfSk7XG4gICAgYGBgXG4gICAgSWYgdGhlIGRvd25zdHJlYW0gcHJvbWlzZSBkb2VzIG5vdCBzcGVjaWZ5IGEgcmVqZWN0aW9uIGhhbmRsZXIsIHJlamVjdGlvbiByZWFzb25zIHdpbGwgYmUgcHJvcGFnYXRlZCBmdXJ0aGVyIGRvd25zdHJlYW0uXG4gIFxuICAgIGBgYGpzXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGVkYWdvZ2ljYWxFeGNlcHRpb24oJ1Vwc3RyZWFtIGVycm9yJyk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICB9KS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgLy8gbmV2ZXIgcmVhY2hlZFxuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIC8vIFRoZSBgUGVkZ2Fnb2NpYWxFeGNlcHRpb25gIGlzIHByb3BhZ2F0ZWQgYWxsIHRoZSB3YXkgZG93biB0byBoZXJlXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIEFzc2ltaWxhdGlvblxuICAgIC0tLS0tLS0tLS0tLVxuICBcbiAgICBTb21ldGltZXMgdGhlIHZhbHVlIHlvdSB3YW50IHRvIHByb3BhZ2F0ZSB0byBhIGRvd25zdHJlYW0gcHJvbWlzZSBjYW4gb25seSBiZVxuICAgIHJldHJpZXZlZCBhc3luY2hyb25vdXNseS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkgcmV0dXJuaW5nIGEgcHJvbWlzZSBpbiB0aGVcbiAgICBmdWxmaWxsbWVudCBvciByZWplY3Rpb24gaGFuZGxlci4gVGhlIGRvd25zdHJlYW0gcHJvbWlzZSB3aWxsIHRoZW4gYmUgcGVuZGluZ1xuICAgIHVudGlsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIHNldHRsZWQuIFRoaXMgaXMgY2FsbGVkICphc3NpbWlsYXRpb24qLlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgcmV0dXJuIGZpbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKGNvbW1lbnRzKSB7XG4gICAgICAvLyBUaGUgdXNlcidzIGNvbW1lbnRzIGFyZSBub3cgYXZhaWxhYmxlXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIElmIHRoZSBhc3NpbWxpYXRlZCBwcm9taXNlIHJlamVjdHMsIHRoZW4gdGhlIGRvd25zdHJlYW0gcHJvbWlzZSB3aWxsIGFsc28gcmVqZWN0LlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgcmV0dXJuIGZ
155pbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKGNvbW1lbnRzKSB7XG4gICAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIGZ1bGZpbGxzLCB3ZSdsbCBoYXZlIHRoZSB2YWx1ZSBoZXJlXG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgLy8gSWYgYGZpbmRDb21tZW50c0J5QXV0aG9yYCByZWplY3RzLCB3ZSdsbCBoYXZlIHRoZSByZWFzb24gaGVyZVxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBTaW1wbGUgRXhhbXBsZVxuICAgIC0tLS0tLS0tLS0tLS0tXG4gIFxuICAgIFN5bmNocm9ub3VzIEV4YW1wbGVcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGxldCByZXN1bHQ7XG4gIFxuICAgIHRyeSB7XG4gICAgICByZXN1bHQgPSBmaW5kUmVzdWx0KCk7XG4gICAgICAvLyBzdWNjZXNzXG4gICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9XG4gICAgYGBgXG4gIFxuICAgIEVycmJhY2sgRXhhbXBsZVxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRSZXN1bHQoZnVuY3Rpb24ocmVzdWx0LCBlcnIpe1xuICAgICAgaWYgKGVycikge1xuICAgICAgICAvLyBmYWlsdXJlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzdWNjZXNzXG4gICAgICB9XG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIFByb21pc2UgRXhhbXBsZTtcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGZpbmRSZXN1bHQoKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCl7XG4gICAgICAvLyBzdWNjZXNzXG4gICAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQWR2YW5jZWQgRXhhbXBsZVxuICAgIC0tLS0tLS0tLS0tLS0tXG4gIFxuICAgIFN5bmNocm9ub3VzIEV4YW1wbGVcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGxldCBhdXRob3IsIGJvb2tzO1xuICBcbiAgICB0cnkge1xuICAgICAgYXV0aG9yID0gZmluZEF1dGhvcigpO1xuICAgICAgYm9va3MgID0gZmluZEJvb2tzQnlBdXRob3IoYXV0aG9yKTtcbiAgICAgIC8vIHN1Y2Nlc3NcbiAgICB9IGNhdGNoKHJlYXNvbikge1xuICAgICAgLy8gZmFpbHVyZVxuICAgIH1cbiAgICBgYGBcbiAgXG4gICAgRXJyYmFjayBFeGFtcGxlXG4gIFxuICAgIGBgYGpzXG4gIFxuICAgIGZ1bmN0aW9uIGZvdW5kQm9va3MoYm9va3MpIHtcbiAgXG4gICAgfVxuICBcbiAgICBmdW5jdGlvbiBmYWlsdXJlKHJlYXNvbikge1xuICBcbiAgICB9XG4gIFxuICAgIGZpbmRBdXRob3IoZnVuY3Rpb24oYXV0aG9yLCBlcnIpe1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgIC8vIGZhaWx1cmVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZmluZEJvb29rc0J5QXV0aG9yKGF1dGhvciwgZnVuY3Rpb24oYm9va3MsIGVycikge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZvdW5kQm9va3MoYm9va3MpO1xuICAgICAgICAgICAgICB9IGNhdGNoKHJlYXNvbikge1xuICAgICAgICAgICAgICAgIGZhaWx1cmUocmVhc29uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgZmFpbHVyZShlcnIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgIH1cbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgUHJvbWlzZSBFeGFtcGxlO1xuICBcbiAgICBgYGBqYXZhc2NyaXB0XG4gICAgZmluZEF1dGhvcigpLlxuICAgICAgdGhlbihmaW5kQm9va3NCeUF1dGhvcikuXG4gICAgICB0aGVuKGZ1bmN0aW9uKGJvb2tzKXtcbiAgICAgICAgLy8gZm91bmQgYm9va3NcbiAgICB9KS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQG1ldGhvZCB0aGVuXG4gICAgQHBhcmFtIHtGdW5jdGlvbn0gb25GdWxmaWxsZWRcbiAgICBAcGFyYW0ge0Z1bmN0aW9ufSBvblJlamVjdGVkXG4gICAgVXNlZnVsIGZvciB0b29saW5nLlxuICAgIEByZXR1cm4ge1Byb21pc2V9XG4gICovXG4gIHRoZW46IHRoZW4sXG5cbiAgLyoqXG4gICAgYGNhdGNoYCBpcyBzaW1wbHkgc3VnYXIgZm9yIGB0aGVuKHVuZGVmaW5lZCwgb25SZWplY3Rpb24pYCB3aGljaCBtYWtlcyBpdCB0aGUgc2FtZVxuICAgIGFzIHRoZSBjYXRjaCBibG9jayBvZiBhIHRyeS9jYXRjaCBzdGF0ZW1lbnQuXG4gIFxuICAgIGBgYGpzXG4gICAgZnVuY3Rpb24gZmluZEF1dGhvcigpe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZG4ndCBmaW5kIHRoYXQgYXV0aG9yJyk7XG4gICAgfVxuICBcbiAgICAvLyBzeW5jaHJvbm91c1xuICAgIHRyeSB7XG4gICAgICBmaW5kQXV0aG9yKCk7XG4gICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgfVxuICBcbiAgICAvLyBhc3luYyB3aXRoIHByb21pc2VzXG4gICAgZmluZEF1dGhvcigpLmNhdGNoKGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBAbWV0aG9kIGNhdGNoXG4gICAgQHBhcmFtIHtGdW5jdGlvbn0gb25SZWplY3Rpb25cbiAgICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gICAgQHJldHVybiB7UHJvbWlzZX1cbiAgKi9cbiAgJ2NhdGNoJzogZnVuY3Rpb24gX2NhdGNoKG9uUmVqZWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGlvbik7XG4gIH1cbn07XG5cbi8qZ2xvYmFsIHNlbGYqL1xuZnVuY3Rpb24gcG9seWZpbGwkMSgpIHtcbiAgICB2YXIgbG9jYWwgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbG9jYWwgPSBnbG9iYWw7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbG9jYWwgP
155SBzZWxmO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2NhbCA9IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncG9seWZpbGwgZmFpbGVkIGJlY2F1c2UgZ2xvYmFsIG9iamVjdCBpcyB1bmF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50Jyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgUCA9IGxvY2FsLlByb21pc2U7XG5cbiAgICBpZiAoUCkge1xuICAgICAgICB2YXIgcHJvbWlzZVRvU3RyaW5nID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb21pc2VUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChQLnJlc29sdmUoKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIHNpbGVudGx5IGlnbm9yZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9taXNlVG9TdHJpbmcgPT09ICdbb2JqZWN0IFByb21pc2VdJyAmJiAhUC5jYXN0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsb2NhbC5Qcm9taXNlID0gUHJvbWlzZSQyO1xufVxuXG4vLyBTdHJhbmdlIGNvbXBhdC4uXG5Qcm9taXNlJDIucG9seWZpbGwgPSBwb2x5ZmlsbCQxO1xuUHJvbWlzZSQyLlByb21pc2UgPSBQcm9taXNlJDI7XG5cbnJldHVybiBQcm9taXNlJDI7XG5cbn0pKSk7XG5cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVzNi1wcm9taXNlLm1hcFxuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyg3KSwgX193ZWJwYWNrX3JlcXVpcmVfXyg4KSkpXG5cbi8qKiovIH0pLFxuLyogNSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyByZW1vdmVkIGJ5IGV4dHJhY3QtdGV4dC13ZWJwYWNrLXBsdWdpblxuXG4vKioqLyB9KSxcbi8qIDYgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci
1555lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTsgLyogZ2xvYmFsIFZFUlNJT04gKi9cblxuX193ZWJwYWNrX3JlcXVpcmVfXyg1KTtcblxudmFyIF9lczZQcm9taXNlID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblxudmFyIF9lczZQcm9taXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VzNlByb21pc2UpO1xuXG52YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxudmFyIFV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX3V0aWxzKTtcblxudmFyIF9hcGkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXG52YXIgQVBJID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX2FwaSk7XG5cbnZhciBfYnV0dG9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblxudmFyIF9wdXNoID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIE5vdHkgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgKi9cbiAgZnVuY3Rpb24gTm90eSgpIHtcbiAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTm90eSk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBVdGlscy5kZWVwRXh0ZW5kKHt9LCBBUEkuRGVmYXVsdHMsIG9wdGlvbnMpO1xuXG4gICAgaWYgKEFQSS5TdG9yZVt0aGlzLm9wdGlvbnMuaWRdKSB7XG4gICAgICByZXR1cm4gQVBJLlN0b3JlW3RoaXMub3B0aW9ucy5pZF07XG4gICAgfVxuXG4gICAgdGhpcy5pZCA9IHRoaXMub3B0aW9ucy5pZCB8fCBVdGlscy5nZW5lcmF0ZUlEKCdiYXInKTtcbiAgICB0aGlzLmNsb3NlVGltZXIgPSAtMTtcbiAgICB0aGlzLmJhckRvbSA9IG51bGw7XG4gICAgdGhpcy5sYXlvdXREb20gPSBudWxsO1xuICAgIHRoaXMucHJvZ3Jlc3NEb20gPSBudWxsO1xuICAgIHRoaXMuc2hvd2luZyA9IGZhbHNlO1xuICAgIHRoaXMuc2hvd24gPSBmYWxzZTtcbiAgICB0aGlzLmNsb3NlZCA9IGZhbHNlO1xuICAgIHRoaXMuY2xvc2luZyA9IGZhbHNlO1xuICAgIHRoaXMua2lsbGFibGUgPSB0aGlzLm9wdGlvbnMudGltZW91dCB8fCB0aGlzLm9wdGlvbnMuY2xvc2VXaXRoLmxlbmd0aCA+IDA7XG4gICAgdGhpcy5oYXNTb3VuZCA9IHRoaXMub3B0aW9ucy5zb3VuZHMuc291cmNlcy5sZW5ndGggPiAwO1xuICAgIHRoaXMuc291bmRQbGF5ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcbiAgICAgIGJlZm9yZVNob3c6IFtdLFxuICAgICAgb25TaG93OiBbXSxcbiAgICAgIGFmdGVyU2hvdzogW10sXG4gICAgICBvbkNsb3NlOiBbXSxcbiAgICAgIGFmdGVyQ2xvc2U6IFtdLFxuICAgICAgb25DbGljazogW10sXG4gICAgICBvbkhvdmVyOiBbXSxcbiAgICAgIG9uVGVtcGxhdGU6IFtdXG4gICAgfTtcbiAgICB0aGlzLnByb21pc2VzID0ge1xuICAgICAgc2hvdzogbnVsbCxcbiAgICAgIGNsb3NlOiBudWxsXG4gICAgfTtcbiAgICB0aGlzLm9uKCdiZWZvcmVTaG93JywgdGhpcy5vcHRpb25zLmNhbGxiYWNrcy5iZWZvcmVTaG93KTtcbiAgICB0aGlzLm9uKCdvblNob3cnLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLm9uU2hvdyk7XG4gICAgdGhpcy5vbignYWZ0ZXJTaG93JywgdGhpcy5vcHRpb25zLmNhbGxiYWNrcy5hZnRlclNob3cpO1xuICAgIHRoaXMub24oJ29uQ2xvc2UnLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLm9uQ2xvc2UpO1xuICAgIHRoaXMub24oJ2FmdGVyQ2xvc2UnLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLmFmdGVyQ2xvc2UpO1xuICAgIHRoaXMub24oJ29uQ2xpY2snLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLm9uQ2xpY2spO1xuICAgIHRoaXMub24oJ29uSG92ZXInLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLm9uSG92ZXIpO1xuICAgIHRoaXMub24oJ29uVGVtcGxhdGUnLCB0aGlzLm9wdGlvbnMuY2FsbGJhY2tzLm9uVGVtcGxhdGUpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYlxuICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgKi9cblxuXG4gIF9jcmVhdGVDbGFzcyhOb3R5LCBbe1xuICAgIGtleTogJ29uJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gb24oZXZlbnROYW1lKSB7XG4gICAgICB2Y
155XIgY2IgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nICYmIHRoaXMubGlzdGVuZXJzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoKGNiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnc2hvdycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNob3coKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICBpZiAodGhpcy5zaG93aW5nIHx8IHRoaXMuc2hvd24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7IC8vIHByZXZlbnRpbmcgbXVsdGlwbGUgc2hvd1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmtpbGxlciA9PT0gdHJ1ZSkge1xuICAgICAgICBOb3R5LmNsb3NlQWxsKCk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMua2lsbGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBOb3R5LmNsb3NlQWxsKHRoaXMub3B0aW9ucy5raWxsZXIpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcXVldWVDb3VudHMgPSBBUEkuZ2V0UXVldWVDb3VudHModGhpcy5vcHRpb25zLnF1ZXVlKTtcblxuICAgICAgaWYgKHF1ZXVlQ291bnRzLmN1cnJlbnQgPj0gcXVldWVDb3VudHMubWF4VmlzaWJsZSB8fCBBUEkuUGFnZUhpZGRlbiAmJiB0aGlzLm9wdGlvbnMudmlzaWJpbGl0eUNvbnRyb2wpIHtcbiAgICAgICAgQVBJLmFkZFRvUXVldWUodGhpcyk7XG5cbiAgICAgICAgaWYgKEFQSS5QYWdlSGlkZGVuICYmIHRoaXMuaGFzU291bmQgJiYgVXRpbHMuaW5BcnJheSgnZG9jSGlkZGVuJywgdGhpcy5vcHRpb25zLnNvdW5kcy5jb25kaXRpb25zKSkge1xuICAgICAgICAgIFV0aWxzLmNyZWF0ZUF1ZGlvRWxlbWVudHModGhpcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQVBJLlBhZ2VIaWRkZW4gJiYgVXRpbHMuaW5BcnJheSgnZG9jSGlkZGVuJywgdGhpcy5vcHRpb25zLnRpdGxlQ291bnQuY29uZGl0aW9ucykpIHtcbiAgICAgICAgICBBUEkuZG9jVGl0bGUuaW5jcmVtZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgQVBJLlN0b3JlW3RoaXMuaWRdID0gdGhpcztcblxuICAgICAgQVBJLmZpcmUodGhpcywgJ2JlZm9yZVNob3cnKTtcblxuICAgICAgdGhpcy5zaG93aW5nID0gdHJ1ZTtcblxuICAgICAgaWYgKHRoaXMuY2xvc2luZykge1xuICAgICAgICB0aGlzLnNob3dpbmcgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIEFQSS5idWlsZCh0aGlzKTtcbiAgICAgIEFQSS5oYW5kbGVNb2RhbCh0aGlzKTtcblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5mb3JjZSkge1xuICAgICAgICB0aGlzLmxheW91dERvbS5pbnNlcnRCZWZvcmUodGhpcy5iYXJEb20sIHR
155oaXMubGF5b3V0RG9tLmZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sYXlvdXREb20uYXBwZW5kQ2hpbGQodGhpcy5iYXJEb20pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5oYXNTb3VuZCAmJiAhdGhpcy5zb3VuZFBsYXllZCAmJiBVdGlscy5pbkFycmF5KCdkb2NWaXNpYmxlJywgdGhpcy5vcHRpb25zLnNvdW5kcy5jb25kaXRpb25zKSkge1xuICAgICAgICBVdGlscy5jcmVhdGVBdWRpb0VsZW1lbnRzKHRoaXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoVXRpbHMuaW5BcnJheSgnZG9jVmlzaWJsZScsIHRoaXMub3B0aW9ucy50aXRsZUNvdW50LmNvbmRpdGlvbnMpKSB7XG4gICAgICAgIEFQSS5kb2NUaXRsZS5pbmNyZW1lbnQoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zaG93biA9IHRydWU7XG4gICAgICB0aGlzLmNsb3NlZCA9IGZhbHNlO1xuXG4gICAgICAvLyBiaW5kIGJ1dHRvbiBldmVudHMgaWYgYW55XG4gICAgICBpZiAoQVBJLmhhc0J1dHRvbnModGhpcykpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5vcHRpb25zLmJ1dHRvbnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgIHZhciBidG4gPSBfdGhpcy5iYXJEb20ucXVlcnlTZWxlY3RvcignIycgKyBfdGhpcy5vcHRpb25zLmJ1dHRvbnNba2V5XS5pZCk7XG4gICAgICAgICAgVXRpbHMuYWRkTGlzdGVuZXIoYnRuLCAnY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgVXRpbHMuc3RvcFByb3BhZ2F0aW9uKGUpO1xuICAgICAgICAgICAgX3RoaXMub3B0aW9ucy5idXR0b25zW2tleV0uY2IoX3RoaXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wcm9ncmVzc0RvbSA9IHRoaXMuYmFyRG9tLnF1ZXJ5U2VsZWN0b3IoJy5ub3R5X3Byb2dyZXNzYmFyJyk7XG5cbiAgICAgIGlmIChVdGlscy5pbkFycmF5KCdjbGljaycsIHRoaXMub3B0aW9ucy5jbG9zZVdpdGgpKSB7XG4gICAgICAgIFV0aWxzLmFkZENsYXNzKHRoaXMuYmFyRG9tLCAnbm90eV9jbG9zZV93aXRoX2NsaWNrJyk7XG4gICAgICAgIFV0aWxzLmFkZExpc3RlbmVyKHRoaXMuYmFyRG9tLCAnY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgIFV0aWxzLnN0b3BQcm9wYWdhdGlvbihlKTtcbiAgICAgICAgICBBUEkuZmlyZShfdGhpcywgJ29uQ2xpY2snKTtcbiAgICAgICAgICBfdGhpcy5jbG9zZSgpO1xuICAgICAgICB9LCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIFV0aWxzLmFkZExpc3RlbmVyKHRoaXMuYmFyRG9tLCAnbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgQVBJLmZpcmUoX3RoaXMsICdvbkhvdmVyJyk7XG4gICAgICB9LCBmYWxzZSk7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMudGltZW91dCkgVXRpbHMuYWRkQ2xhc3ModGhpcy5iYXJEb20sICdub3R5X2hhc190aW1lb3V0Jyk7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnByb2dyZXNzQmFyKSB7XG4gICAgICAgIFV0aWxzLmFkZENsYXNzKHRoaXMuYmFyRG9tLCAnbm90eV9oYXNfcHJvZ3Jlc3NiYXInKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFV0aWxzLmluQXJyYXkoJ2J1dHRvbicsIHRoaXMub3B0aW9ucy5jbG9zZVdpdGgpKSB7XG4gICAgICAgIFV0aWxzLmFkZENsYXNzKHRoaXMuYmFyRG9tLCAnbm90eV9jbG9zZV93aXRoX2J1dHRvbicpO1xuXG4gICAgICAgIHZhciBjbG9zZUJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBVdGlscy5hZGRDbGFzcyhjbG9zZUJ1dHRvbiwgJ25vdHlfY2xvc2VfYnV0dG9uJyk7XG4gICAgICAgIGNsb3NlQnV0dG9uLmlubmVySFRNTCA9ICfDlyc7XG4gICAgICAgIHRoaXMuYmFyRG9tLmFwcGVuZENoaWxkKGNsb3NlQnV0dG9uKTtcblxuICAgICAgICBVdGlscy5hZGRMaXN0ZW5lcihjbG9zZUJ1dHRvbiwgJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICBVdGlscy5zdG9wUHJvcGFnYXRpb24oZSk7XG4gICAgICAgICAgX3RoaXMuY2xvc2UoKTtcbiAgICAgICAgfSwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICBBUEkuZmlyZSh0aGlzLCAnb25TaG93Jyk7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW4gPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5wcm9taXNlcy5zaG93ID0gbmV3IF9lczZQcm9taXNlMi5kZWZhdWx0KGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5hbmltYXRpb24ub3BlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnByb21pc2VzLnNob3cgPSBuZXcgX2VzNlByb21pc2UyLmRlZmF1bHQodGhpcy5vcHRpb25zLmFuaW1hdGlvbi5vcGVuLmJpbmQodGhpcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgVXRpbHMuYWRkQ2xhc3ModGhpcy5iYXJEb20sIHR
155oaXMub3B0aW9ucy5hbmltYXRpb24ub3Blbik7XG4gICAgICAgIHRoaXMucHJvbWlzZXMuc2hvdyA9IG5ldyBfZXM2UHJvbWlzZTIuZGVmYXVsdChmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIFV0aWxzLmFkZExpc3RlbmVyKF90aGlzLmJhckRvbSwgVXRpbHMuYW5pbWF0aW9uRW5kRXZlbnRzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBVdGlscy5yZW1vdmVDbGFzcyhfdGhpcy5iYXJEb20sIF90aGlzLm9wdGlvbnMuYW5pbWF0aW9uLm9wZW4pO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wcm9taXNlcy5zaG93LnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3QgPSBfdGhpcztcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgQVBJLm9wZW5GbG93KF90KTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdzdG9wJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgIEFQSS5kZXF1ZXVlQ2xvc2UodGhpcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdyZXN1bWUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZXN1bWUoKSB7XG4gICAgICBBUEkucXVldWVDbG9zZSh0aGlzKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW50fGJvb2xlYW59IG1zXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnc2V0VGltZW91dCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIChfc2V0VGltZW91dCkge1xuICAgICAgZnVuY3Rpb24gc2V0VGltZW91dChfeCkge1xuICAgICAgICByZXR1cm4gX3NldFRpbWVvdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgc2V0VGltZW91dC50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIF9zZXRUaW1lb3V0LnRvU3RyaW5nKCk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2V0VGltZW91dDtcbiAgICB9KGZ1bmN0aW9uIChtcykge1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICB0aGlzLm9wdGlvbnMudGltZW91dCA9IG1zO1xuXG4gICAgICBpZiAodGhpcy5iYXJEb20pIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50aW1lb3V0KSB7XG4gICAgICAgICAgVXRpbHMuYWRkQ2xhc3ModGhpcy5iYXJEb20sICdub3R5X2hhc190aW1lb3V0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgVXRpbHMucmVtb3ZlQ2xhc3ModGhpcy5iYXJEb20sICdub3R5X2hhc190aW1lb3V0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICB2Y
155XIgX3QgPSB0aGlzO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyB1Z2x5IGZpeCBmb3IgcHJvZ3Jlc3NiYXIgZGlzcGxheSBidWdcbiAgICAgICAgICBfdC5yZXN1bWUoKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSlcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zT3ZlcnJpZGVcbiAgICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdzZXRUZXh0JyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0VGV4dChodG1sKSB7XG4gICAgICB2YXIgb3B0aW9uc092ZXJyaWRlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBmYWxzZTtcblxuICAgICAgaWYgKHRoaXMuYmFyRG9tKSB7XG4gICAgICAgIHRoaXMuYmFyRG9tLnF1ZXJ5U2VsZWN0b3IoJy5ub3R5X2JvZHknKS5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9uc092ZXJyaWRlKSB0aGlzLm9wdGlvbnMudGV4dCA9IGh0bWw7XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zT3ZlcnJpZGVcbiAgICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdzZXRUeXBlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0VHlwZSh0eXBlKSB7XG4gICAgICB2Y
155XIgX3RoaXMyID0gdGhpcztcblxuICAgICAgdmFyIG9wdGlvbnNPdmVycmlkZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLmJhckRvbSkge1xuICAgICAgICB2YXIgY2xhc3NMaXN0ID0gVXRpbHMuY2xhc3NMaXN0KHRoaXMuYmFyRG9tKS5zcGxpdCgnICcpO1xuXG4gICAgICAgIGNsYXNzTGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgaWYgKGMuc3Vic3RyaW5nKDAsIDExKSA9PT0gJ25vdHlfdHlwZV9fJykge1xuICAgICAgICAgICAgVXRpbHMucmVtb3ZlQ2xhc3MoX3RoaXMyLmJhckRvbSwgYyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBVdGlscy5hZGRDbGFzcyh0aGlzLmJhckRvbSwgJ25vdHlfdHlwZV9fJyArIHR5cGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9uc092ZXJyaWRlKSB0aGlzLm9wdGlvbnMudHlwZSA9IHR5cGU7XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aGVtZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0aW9uc092ZXJyaWRlXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnc2V0VGhlbWUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRUaGVtZSh0aGVtZSkge1xuICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgIHZhciBvcHRpb25zT3ZlcnJpZGUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgICBpZiAodGhpcy5iYXJEb20pIHtcbiAgICAgICAgdmFyIGNsYXNzTGlzdCA9IFV0aWxzLmNsYXNzTGlzdCh0aGlzLmJhckRvbSkuc3BsaXQoJyAnKTtcblxuICAgICAgICBjbGFzc0xpc3QuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgICAgIGlmIChjLnN1YnN0cmluZygwLCAxMikgPT09ICdub3R5X3RoZW1lX18nKSB7XG4gICAgICAgICAgICBVdGlscy5yZW1vdmVDbGFzcyhfdGhpczMuYmFyRG9tLCBjKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFV0aWxzLmFkZENsYXNzKHRoaXMuYmFyRG9tLCAnbm90eV90aGVtZV9fJyArIHRoZW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnNPdmVycmlkZSkgdGhpcy5vcHRpb25zLnRoZW1lID0gdGhlbWU7XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge05vdHl9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogJ2Nsb3NlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgICB2Y
155XIgX3RoaXM0ID0gdGhpcztcblxuICAgICAgaWYgKHRoaXMuY2xvc2VkKSByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKCF0aGlzLnNob3duKSB7XG4gICAgICAgIC8vIGl0J3MgaW4gdGhlIHF1ZXVlXG4gICAgICAgIEFQSS5yZW1vdmVGcm9tUXVldWUodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBBUEkuZmlyZSh0aGlzLCAnb25DbG9zZScpO1xuXG4gICAgICB0aGlzLmNsb3NpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFuaW1hdGlvbi5jbG9zZSA9PT0gbnVsbCB8fCB0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLnByb21pc2VzLmNsb3NlID0gbmV3IF9lczZQcm9taXNlMi5kZWZhdWx0KGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5hbmltYXRpb24uY2xvc2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5wcm9taXNlcy5jbG9zZSA9IG5ldyBfZXM2UHJvbWlzZTIuZGVmYXVsdCh0aGlzLm9wdGlvbnMuYW5pbWF0aW9uLmNsb3NlLmJpbmQodGhpcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgVXRpbHMuYWRkQ2xhc3ModGhpcy5iYXJEb20sIHRoaXMub3B0aW9ucy5hbmltYXRpb24uY2xvc2UpO1xuICAgICAgICB0aGlzLnByb21pc2VzLmNsb3NlID0gbmV3IF9lczZQcm9taXNlMi5kZWZhdWx0KGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgVXRpbHMuYWRkTGlzdGVuZXIoX3RoaXM0LmJhckRvbSwgVXRpbHMuYW5pbWF0aW9uRW5kRXZlbnRzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXM0Lm9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgICAgICAgVXRpbHMucmVtb3ZlKF90aGlzNC5iYXJEb20pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgQVBJLmdob3N0Rml4KF90aGlzNCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnByb21pc2VzLmNsb3NlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBBUEkuY2xvc2VGbG93KF90aGlzNCk7XG4gICAgICAgIEFQSS5oYW5kbGVNb2RhbENsb3NlKF90aGlzNCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBBUEkgZnVuY3Rpb25zXG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58c3RyaW5nfSBxdWV1ZU5hbWVcbiAgICAgKiBAcmV0dXJuIHtOb3R5fVxuICAgICAqL1xuXG4gIH1dLCBbe1xuICAgIGtleTogJ2Nsb3NlQWxsJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xvc2VBbGwoKSB7XG4gICAgICB2Y
155XIgcXVldWVOYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBmYWxzZTtcblxuICAgICAgT2JqZWN0LmtleXMoQVBJLlN0b3JlKS5mb3JFYWNoKGZ1bmN0aW9uIChpZCkge1xuICAgICAgICBpZiAocXVldWVOYW1lKSB7XG4gICAgICAgICAgaWYgKEFQSS5TdG9yZVtpZF0ub3B0aW9ucy5xdWV1ZSA9PT0gcXVldWVOYW1lICYmIEFQSS5TdG9yZVtpZF0ua2lsbGFibGUpIHtcbiAgICAgICAgICAgIEFQSS5TdG9yZVtpZF0uY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoQVBJLlN0b3JlW2lkXS5raWxsYWJsZSkge1xuICAgICAgICAgIEFQSS5TdG9yZVtpZF0uY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcXVldWVOYW1lXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnY2xlYXJRdWV1ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNsZWFyUXVldWUoKSB7XG4gICAgICB2YXIgcXVldWVOYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnZ2xvYmFsJztcblxuICAgICAgaWYgKEFQSS5RdWV1ZXMuaGFzT3duUHJvcGVydHkocXVldWVOYW1lKSkge1xuICAgICAgICBBUEkuUXVldWVzW3F1ZXVlTmFtZV0ucXVldWUgPSBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FQSS5RdWV1ZXN9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogJ292ZXJyaWRlRGVmYXVsdHMnLFxuXG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cbiAgICB2YWx1ZTogZnVuY3Rpb24gb3ZlcnJpZGVEZWZhdWx0cyhvYmopIHtcbiAgICAgIEFQSS5EZWZhdWx0cyA9IFV0aWxzLmRlZXBFeHRlbmQoe30sIEFQSS5EZWZhdWx0cywgb2JqKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW50fSBhbW91bnRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcXVldWVOYW1lXG4gICAgICogQHJldHVybiB7Tm90eX1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiAnc2V0TWF4VmlzaWJsZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldE1heFZpc2libGUoKSB7XG4gICAgICB2Y
155XIgYW1vdW50ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBBUEkuRGVmYXVsdE1heFZpc2libGU7XG4gICAgICB2YXIgcXVldWVOYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnZ2xvYmFsJztcblxuICAgICAgaWYgKCFBUEkuUXVldWVzLmhhc093blByb3BlcnR5KHF1ZXVlTmFtZSkpIHtcbiAgICAgICAgQVBJLlF1ZXVlc1txdWV1ZU5hbWVdID0geyBtYXhWaXNpYmxlOiBhbW91bnQsIHF1ZXVlOiBbXSB9O1xuICAgICAgfVxuXG4gICAgICBBUEkuUXVldWVzW3F1ZXVlTmFtZV0ubWF4VmlzaWJsZSA9IGFtb3VudDtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpbm5lckh0bWxcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY2xhc3Nlc1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJpYnV0ZXNcbiAgICAgKiBAcmV0dXJuIHtOb3R5QnV0dG9ufVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICdidXR0b24nLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBidXR0b24oaW5uZXJIdG1sKSB7XG4gICAgICB2YXIgY2xhc3NlcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogbnVsbDtcbiAgICAgIHZhciBjYiA9IGFyZ3VtZW50c1syXTtcbiAgICAgIHZhciBhdHRyaWJ1dGVzID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcblxuICAgICAgcmV0dXJuIG5ldyBfYnV0dG9uLk5vdHlCdXR0b24oaW5uZXJIdG1sLCBjbGFzc2VzLCBjYiwgYXR0cmlidXRlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6ICd2ZXJzaW9uJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gdmVyc2lvbigpIHtcbiAgICAgIHJldHVybiBcIjMuMi4wLWJldGFcIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gd29ya2VyUGF0aFxuICAgICAqIEByZXR1cm4ge1B1c2h9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogJ1B1c2gnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBQdXNoKHdvcmtlclBhdGgpIHtcbiAgICAgIHJldHVybiBuZXcgX3B1c2guUHVzaCh3b3JrZXJQYXRoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdRdWV1ZXMnLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIEFQSS5RdWV1ZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QVBJLlBhZ2VIaWRkZW59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogJ1BhZ2VIaWRkZW4nLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIEFQSS5QYWdlSGlkZGVuO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBOb3R5O1xufSgpO1xuXG4vLyBEb2N1bWVudCB2aXNpYmlsaXR5IGNoYW5nZSBjb250cm9sbGVyXG5cblxuZXhwb3J0cy5kZWZh
155dWx0ID0gTm90eTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICBVdGlscy52aXNpYmlsaXR5Q2hhbmdlRmxvdygpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG5cbi8qKiovIH0pLFxuLyogNyAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgI
155HJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cbi8qKiovIH0pLFxuLyogOCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG52YXIgZztcclxuXHJcbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXHJcbmcgPSAoZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXM7XHJcbn0pKCk7XHJcblxyXG50cnkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxyXG5cdGcgPSBnIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSB8fCAoMSxldmFsKShcInRoaXNcIik7XHJcbn0gY2F0Y2goZSkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXHJcblx0aWYodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIilcclxuXHRcdGcgPSB3aW5kb3c7XHJcbn1cclxuXHJcbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cclxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3NcclxuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnO1xyXG5cblxuLyoqKi8gfSksXG4vKiA5ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbi8qIChpZ25vcmVkKSAqL1xuXG4vKioqLyB9KVxuLyoqKioqKi8gXSk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5vdHkuanMubWFwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvbm90eS9saWIvbm90eS5qc1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ
1550E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7\n"); 156 157/***/ }), 158/* 8 */ 159/*!**********************************************!*\ 160 !*** ./node_modules/swiper/swiper-bundle.js ***! 161 \**********************************************/ 162/*! dynamic exports provided */ 163/*! all exports used */ 164/***/ (function(module, exports, __webpack_require__) { 165 166eval("/**\n * Swiper 6.1.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * http://swiperjs.com\n *\n * Copyright 2014-2020 Vladimir Kharlampidi\n *\n * Released under the MIT License\n *\n * Released on: July 31, 2020\n */\n\n(function (global, factory) {\n true ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.Swiper = factory());\n}(this, (function () { 'use strict';\n\n function _defineProperties(target, props) {\n for (var i = 0; i < props.length;
166 i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n }\n\n function _extends() {\n _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n }\n\n /**\n * SSR Window 3.0.0-alpha.4\n * Better handling for window object in SSR environment\n * https://github.com/nolimits4web/ssr-window\n *\n * Copyright 2020, Vladimir Kharlampidi\n *\n * Licensed under MIT\n *\n * Released on: May 20, 2020\n */\n\n /* eslint-disable no-param-reassign */\n function isObject(obj) {\n return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;\n }\n\n function extend(target, src) {\n if (target === void 0) {\n target = {};\n }\n\n if (src === void 0) {\n src = {};\n }\n\n Object.keys(src).forEach(function (key) {\n if (typeof target[key] === 'undefined') target[key] = src[key];else if (isObject(src[key]) && isObject(target[key]) && Object.keys(src[key]).length > 0) {\n extend(target[key], src[key]);\n }\n });\n }\n\n var ssrDocument = {\n body: {},\n addEventListener: function addEventListener() {},\n removeEventListener: function removeEventListener() {},\n activeElement: {\n blur: function blur() {},\n nodeName: ''\n },\n querySelector: function querySelector() {\n return null;\n },\n querySelectorAll: function querySelectorAll() {\n return [];\n },\n getElementById: function getElementById() {\n return null;\n },\n createEvent: function createEvent() {\n return {\n initEvent: function initEvent() {}\n };\n },\n createElement: function createElement() {\n return {\n children: [],\n childNodes: [],\n style: {},\n setAttribute: function setAttribute() {},\n getElementsByTagName: function getElementsByTagName() {\n return [];\n }\n };\n },\n createElementNS: function createElementNS() {\n return {};\n },\n importNode: function importNode() {\n return null;\n },\n location: {\n hash: '',\n host: '',\n hostname: '',\n href: '',\n origin: '',\n pathname: '',\n protocol: '',\n search: ''\n }\n };\n\n function getDocument() {\n var doc = typeof document !== 'undefined' ? document : {};\n extend(doc, ssrDocument);\n return doc;\n }\n\n var ssrWindow = {\n document: ssrDocument,\n navigator: {\n userAgent: ''\n },\n location: {\n hash: '',\n host: '',\n hostname: '',\n href: '',\n origin: '',\n pathname: '',\n protocol: '',\n search: ''\n },\n history: {\n replaceState: function replaceState() {},\n pushState: function pushState() {},\n go: function go() {},\n back: function back() {}\n },\n CustomEvent: function CustomEvent() {\n return this;\n },\n addEventListener: function addEventListener() {},\n removeEventListener: function removeEventListener() {},\n getComputedStyle: function getComputedStyle() {\n return {\n getPropertyValue: function getPropertyValue() {\n return '';\n }\n };\n },\n Image: function Image() {},\n Date: function Date() {},\n screen: {},\n setTimeout: function setTimeout() {},\n clearTimeout: function clearTimeout() {},\n matchMedia: function matchMedia() {\n return {};\n },\n requestAnimationFrame: function requestAnimationFrame(callback) {\n if (typeof setTimeout === 'undefined') {\n callback();\n return null;\n }\n\n return setTimeout(callback, 0);\n },\n cancelAnimationFrame: function cancelAnimationFrame(id) {\n if (typeof setTimeout === 'undefined') {\n return;\n }\n\n clearTimeout(id);\n }\n };
166\n\n function getWindow() {\n var win = typeof window !== 'undefined' ? window : {};\n extend(win, ssrWindow);\n return win;\n }\n\n /**\n * Dom7 3.0.0-alpha.7\n * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API\n * https://framework7.io/docs/dom7.html\n *\n * Copyright 2020, Vladimir Kharlampidi\n *\n * Licensed under MIT\n *\n * Released on: July 14, 2020\n */\n\n function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n }\n\n function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n }\n\n function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n }\n\n function _isNativeReflectConstruct() {\n if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === \"function\") return true;\n\n try {\n Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n }\n\n function _construct(Parent, args, Class) {\n if (_isNativeReflectConstruct()) {\n _construct = Reflect.construct;\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) _setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n }\n\n return _construct.apply(null, arguments);\n }\n\n function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf(\"[native code]\") !== -1;\n }\n\n function _wrapNativeSuper(Class) {\n var _cache = typeof Map === \"function\" ? new Map() : undefined;\n\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !_isNativeFunction(Class)) return Class;\n\n if (typeof Class !== \"function\") {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n if (typeof _cache !== \"undefined\") {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return _construct(Class, arguments, _getPrototypeOf(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return _setPrototypeOf(Wrapper, Class);\n };\n\n return _wrapNativeSuper(Class);\n }\n\n function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n }\n /* eslint-disable no-proto */\n\n\n function makeReactive(obj) {\n var proto = obj.__proto__;\n Object.defineProperty(obj, '__proto__', {\n get: function get() {\n return proto;\n },\n set: function set(value) {\n proto.__proto__ = value;\n }\n });\n }\n\n var Dom7 = /*#__PURE__*/function (_Array) {\n _inheritsLoose(Dom7, _Array);\n\n function Dom7(items) {\n var _this;\n\n _this = _Array.call.apply(_Array, [this].concat(items)) || this;\n makeReactive(_assertThisInitialized(_this));\n return _this;\n }\n\n return Dom7;\n }( /*#__PURE__*/_wrapNativeSuper(Array));\n\n function arrayFlat(arr) {\n if (arr === void 0) {\n arr = [];\n }\n\n var res = [];\n arr.forEach(function (el) {\n if (Array.isArray(el)) {\n res.push.apply(res, arrayFlat(el));\n } else {\n res.push(el);\n }\n });\n return res;\n }\n\n function arrayFilter(arr, callback) {\n return Array.prototype.filter.call(arr, callback);\n }\n\n function arrayUnique(arr) {\n var uniqueArray = [];\n\n for (var i = 0; i < arr.length;
166 i += 1) {\n if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]);\n }\n\n return uniqueArray;\n }\n\n function qsa(selector, context) {\n if (typeof selector !== 'string') {\n return [selector];\n }\n\n var a = [];\n var res = context.querySelectorAll(selector);\n\n for (var i = 0; i < res.length; i += 1) {\n a.push(res[i]);\n }\n\n return a;\n }\n\n function $(selector, context) {\n var window = getWindow();\n var document = getDocument();\n var arr = [];\n\n if (!context && selector instanceof Dom7) {\n return selector;\n }\n\n if (!selector) {\n return new Dom7(arr);\n }\n\n if (typeof selector === 'string') {\n var html = selector.trim();\n\n if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n var toCreate = 'div';\n if (html.indexOf('<li') === 0) toCreate = 'ul';\n if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n if (html.indexOf('<tbody') === 0) toCreate = 'table';\n if (html.indexOf('<option') === 0) toCreate = 'select';\n var tempParent = document.createElement(toCreate);\n tempParent.innerHTML = html;\n\n for (var i = 0; i < tempParent.childNodes.length; i += 1) {\n arr.push(tempParent.childNodes[i]);\n }\n } else {\n arr = qsa(selector.trim(), context || document);\n } // arr = qsa(selector, document);\n\n } else if (selector.nodeType || selector === window || selector === document) {\n arr.push(selector);\n } else if (Array.isArray(selector)) {\n if (selector instanceof Dom7) return selector;\n arr = selector;\n }\n\n return new Dom7(arrayUnique(arr));\n }\n\n $.fn = Dom7.prototype;\n\n function addClass() {\n for (var _len = arguments.length, classes = new Array(_len), _key = 0; _key < _len; _key++) {\n classes[_key] = arguments[_key];\n }\n\n var classNames = arrayFlat(classes.map(function (c) {\n return c.split(' ');\n }));\n this.forEach(function (el) {\n var _el$classList;\n\n (_el$classList = el.classList).add.apply(_el$classList, classNames);\n });\n return this;\n }\n\n function removeClass() {\n for (var _len2 = arguments.length, classes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n classes[_key2] = arguments[_key2];\n }\n\n var classNames = arrayFlat(classes.map(function (c) {\n return c.split(' ');\n }));\n this.forEach(function (el) {\n var _el$classList2;\n\n (_el$classList2 = el.classList).remove.apply(_el$classList2, classNames);\n });\n return this;\n }\n\n function toggleClass() {\n for (var _len3 = arguments.length, classes = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n classes[_key3] = arguments[_key3];\n }\n\n var classNames = arrayFlat(classes.map(function (c) {\n return c.split(' ');\n }));\n this.forEach(function (el) {\n classNames.forEach(function (className) {\n el.classList.toggle(className);\n });\n });\n }\n\n function hasClass() {\n for (var _len4 = arguments.length, classes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n classes[_key4] = arguments[_key4];\n }\n\n var classNames = arrayFlat(classes.map(function (c) {\n return c.split(' ');\n }));\n return arrayFilter(this, function (el) {\n return classNames.filter(function (className) {\n return el.classList.contains(className);\n }).length > 0;\n }).length > 0;\n }\n\n function attr(attrs, value) {\n if (arguments.length === 1 && typeof attrs === 'string') {\n // Get attr\n if (this[0]) return this[0].getAttribute(attrs);\n return undefined;\n } // Set attrs\n\n\n for (var i = 0; i < this.length; i += 1) {\n if (arguments.length === 2) {\n // String\n this[i].setAttribute(attrs, value);\n } else {\n // Object\n for (var attrName in attrs) {\n this[i][attrName] = attrs[attrName];\n this[i].setAttribute(attrName, attrs[attrName]);\n }\n }\n }\n\n return this;\n }\n\n function removeAttr(attr) {\n for (var i = 0; i < this.length; i += 1) {\n this[i].removeAttribute(attr);\n }\n\n return this;\n }\n\n function transform(transform) {\n for (var i = 0; i < this.length; i += 1) {\n this[i].style.transform = transform;\n }\n\n return this;\n }\n\n function transition(duration) {\n for (var i = 0; i < this.length; i += 1) {\n this[i].style.transition = typeof duration !== 'string' ? duration + \"ms\" : duration;\n }\n\n return this;\n }\n\n function on() {\n for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5;
166 _key5++) {\n args[_key5] = arguments[_key5];\n }\n\n var eventType = args[0],\n targetSelector = args[1],\n listener = args[2],\n capture = args[3];\n\n if (typeof args[1] === 'function') {\n eventType = args[0];\n listener = args[1];\n capture = args[2];\n targetSelector = undefined;\n }\n\n if (!capture) capture = false;\n\n function handleLiveEvent(e) {\n var target = e.target;\n if (!target) return;\n var eventData = e.target.dom7EventData || [];\n\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n\n if ($(target).is(targetSelector)) listener.apply(target, eventData);else {\n var _parents = $(target).parents(); // eslint-disable-line\n\n\n for (var k = 0; k < _parents.length; k += 1) {\n if ($(_parents[k]).is(targetSelector)) listener.apply(_parents[k], eventData);\n }\n }\n }\n\n function handleEvent(e) {\n var eventData = e && e.target ? e.target.dom7EventData || [] : [];\n\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n\n listener.apply(this, eventData);\n }\n\n var events = eventType.split(' ');\n var j;\n\n for (var i = 0; i < this.length; i += 1) {\n var el = this[i];\n\n if (!targetSelector) {\n for (j = 0; j < events.length; j += 1) {\n var event = events[j];\n if (!el.dom7Listeners) el.dom7Listeners = {};\n if (!el.dom7Listeners[event]) el.dom7Listeners[event] = [];\n el.dom7Listeners[event].push({\n listener: listener,\n proxyListener: handleEvent\n });\n el.addEventListener(event, handleEvent, capture);\n }\n } else {\n // Live events\n for (j = 0; j < events.length; j += 1) {\n var _event = events[j];\n if (!el.dom7LiveListeners) el.dom7LiveListeners = {};\n if (!el.dom7LiveListeners[_event]) el.dom7LiveListeners[_event] = [];\n\n el.dom7LiveListeners[_event].push({\n listener: listener,\n proxyListener: handleLiveEvent\n });\n\n el.addEventListener(_event, handleLiveEvent, capture);\n }\n }\n }\n\n return this;\n }\n\n function off() {\n for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n args[_key6] = arguments[_key6];\n }\n\n var eventType = args[0],\n targetSelector = args[1],\n listener = args[2],\n capture = args[3];\n\n if (typeof args[1] === 'function') {\n eventType = args[0];\n listener = args[1];\n capture = args[2];\n targetSelector = undefined;\n }\n\n if (!capture) capture = false;\n var events = eventType.split(' ');\n\n for (var i = 0; i < events.length; i += 1) {\n var event = events[i];\n\n for (var j = 0; j < this.length; j += 1) {\n var el = this[j];\n var handlers = void 0;\n\n if (!targetSelector && el.dom7Listeners) {\n handlers = el.dom7Listeners[event];\n } else if (targetSelector && el.dom7LiveListeners) {\n handlers = el.dom7LiveListeners[event];\n }\n\n if (handlers && handlers.length) {\n for (var k = handlers.length - 1; k >= 0; k -= 1) {\n var handler = handlers[k];\n\n if (listener && handler.listener === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (!listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n }\n }\n }\n }\n }\n\n return this;\n }\n\n function trigger() {\n var window = getWindow();\n\n for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {\n args[_key9] = arguments[_key9];\n }\n\n var events = args[0].split(' ');\n var eventData = args[1];\n\n for (var i = 0; i < events.length; i += 1) {\n var event = events[i];\n\n for (var j = 0; j < this.length; j += 1) {\n var el = this[j];\n\n if (window.CustomEvent) {\n var evt = new window.CustomEvent(event, {\n detail: eventData,\n bubbles: true,\n cancelable: true\n });\n el.dom7EventData = args.filter(function (data, dataIndex) {\n return dataIndex > 0;\n });\n el.dispatchEvent(evt);\n el.dom7EventData = [];\n delete el.dom7EventData;\n }\n }\n }\n\n return this;\n }\n\n function transitionEnd(callback) {\n var dom = this;\n\n function fireCallBack(e) {\n if (e.target !== this) return;\n callback.call(this, e);\n dom.off('transitionend', fireCallBack);\n }\n\n if (callback) {\n dom.on('transitionend', fireCallBack);\n }\n\n return this;\n }\n\n function outerWidth(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n var _styles = this.styles();\n\n return this[0].offsetWidth + parseFloat(_styles.getPropertyValue('margin-right')) + parseFloat(_styles.getPropertyValue('margin-left'));\n }\n\n return this[0].offsetWidth;\n }\n\n return null;\n }\n\n function outerHeight(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n var _styles2 = this.styles();\n\n return this[0].offsetHeight + parseFloat(_styles2.getPropertyValue('margin-top')) + parseFloat(_styles2.getPropertyValue('margin-bottom'));\n }\n\n return this[0].offsetHeight;\n }\n\n return null;\n }\n\n function offset() {\n if (this.length > 0) {\n var window = getWindow();\n var document = getDocument();\n var el = this[0];\n var box = el.getBoundingClientRect();\n var body = document.body;\n var clientTop = el.clientTop || body.clientTop || 0;\n var clientLeft = el.clientLeft || body.clientLeft || 0;\n var scrollTop = el === window ? window.scrollY : el.scrollTop;\n var scrollLeft = el === window ? window.scrollX : el.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n }\n\n return null;\n }\n\n function styles() {\n var window = getWindow();\n if (this[0]) return window.getComputedStyle(this[0], null);\n return {};\n }\n\n function css(props, value) {\n var window = getWindow();\n var i;\n\n if (arguments.length === 1) {\n if (typeof props === 'string') {\n // .css('width')\n if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n } else {\n // .css({ width: '100px' })\n for (i = 0; i < this.length; i += 1) {\n for (var _prop in props) {\n this[i].style[_prop] = props[_prop];\n }\n }\n\n return this;\n }\n }\n\n if (arguments.length === 2 && typeof props === 'string') {\n // .css('width', '100px')\n for (i = 0; i < this.length; i += 1) {\n this[i].style[props] = value;\n }\n\n return this;\n }\n\n return this;\n }\n\n function each(callback) {\n if (!callback) return this;\n this.forEach(function (el, index) {\n callback.apply(el, [el, index]);\n });\n return this;\n }\n\n function filter(callback) {\n var result = arrayFilter(this, callback);\n return $(result);\n }\n\n function html(html) {\n if (typeof html === 'undefined') {\n return this[0] ? this[0].innerHTML : null;\n }\n\n for (var i = 0; i < this.length; i += 1) {\n this[i].innerHTML = html;\n }\n\n return this;\n }\n\n function text(text) {\n if (typeof text === 'undefined') {\n return this[0] ? this[0].textContent.trim() : null;\n }\n\n for (var i = 0; i < this.length; i += 1) {\n this[i].textContent = text;\n }\n\n return this;\n }\n\n function is(selector) {\n var window = getWindow();\n var document = getDocument();\n var el = this[0];\n var compareWith;\n var i;\n if (!el || typeof selector === 'undefined') return false;\n\n if (typeof selector === 'string') {\n if (el.matches) return el.matches(selector);\n if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
166\n if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n compareWith = $(selector);\n\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) return true;\n }\n\n return false;\n }\n\n if (selector === document) {\n return el === document;\n }\n\n if (selector === window) {\n return el === window;\n }\n\n if (selector.nodeType || selector instanceof Dom7) {\n compareWith = selector.nodeType ? [selector] : selector;\n\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) return true;\n }\n\n return false;\n }\n\n return false;\n }\n\n function index() {\n var child = this[0];\n var i;\n\n if (child) {\n i = 0; // eslint-disable-next-line\n\n while ((child = child.previousSibling) !== null) {\n if (child.nodeType === 1) i += 1;\n }\n\n return i;\n }\n\n return undefined;\n }\n\n function eq(index) {\n if (typeof index === 'undefined') return this;\n var length = this.length;\n\n if (index > length - 1) {\n return $([]);\n }\n\n if (index < 0) {\n var returnIndex = length + index;\n if (returnIndex < 0) return $([]);\n return $([this[returnIndex]]);\n }\n\n return $([this[index]]);\n }\n\n function append() {\n var newChild;\n var document = getDocument();\n\n for (var k = 0; k < arguments.length; k += 1) {\n newChild = k < 0 || arguments.length <= k ? undefined : arguments[k];\n\n for (var i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n\n while (tempDiv.firstChild) {\n this[i].appendChild(tempDiv.firstChild);\n }\n } else if (newChild instanceof Dom7) {\n for (var j = 0; j < newChild.length; j += 1) {\n this[i].appendChild(newChild[j]);\n }\n } else {\n this[i].appendChild(newChild);\n }\n }\n }\n\n return this;\n }\n\n function prepend(newChild) {\n var document = getDocument();\n var i;\n var j;\n\n for (i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n var tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n\n for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {\n this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n }\n } else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j += 1) {\n this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n }\n } else {\n this[i].insertBefore(newChild, this[i].childNodes[0]);\n }\n }\n\n return this;\n }\n\n function next(selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {\n return $([this[0].nextElementSibling]);\n }\n\n return $([]);\n }\n\n if (this[0].nextElementSibling) return $([this[0].nextElementSibling]);\n return $([]);\n }\n\n return $([]);\n }\n\n function nextAll(selector) {\n var nextEls = [];\n var el = this[0];\n if (!el) return $([]);\n\n while (el.nextElementSibling) {\n var _next = el.nextElementSibling; // eslint-disable-line\n\n if (selector) {\n if ($(_next).is(selector)) nextEls.push(_next);\n } else nextEls.push(_next);\n\n el = _next;\n }\n\n return $(nextEls);\n }\n\n function prev(selector) {\n if (this.length > 0) {\n var el = this[0];\n\n if (selector) {\n if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {\n return $([el.previousElementSibling]);\n }\n\n return $([]);\n }\n\n if (el.previousElementSibling) return $([el.previousElementSibling]);\n return $([]);\n }\n\n return $([]);\n }\n\n function prevAll(selector) {\n var prevEls = [];\n var el = this[0];\n if (!el) return $([]);\n\n while (el.previousElementSibling) {\n var _prev = el.previousElementSibling; // eslint-disable-line\n\n if (selector) {\n if ($(_prev).is(selector)) prevEls.push(_prev);\n } else prevEls.push(_prev);\n\n el = _prev;\n }\n\n return $(prevEls);\n }\n\n function parent(selector) {\n var parents = []; // eslint-disable-line\n\n for (var i = 0; i < this.length; i += 1) {\n if (this[i].parentNode !== null) {\n if (selector) {\n if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n } else {\n parents.push(this[i].parentNode);\n }\n }\n }\n\n return $(parents);\n }\n\n function parents(selector) {\n var parents = []; // eslint-disable-line\n\n for (var i = 0; i < this.length; i += 1) {\n var _parent = this[i].parentNode; // eslint-disable-line\n\n while (_parent) {\n if (selector) {\n if ($(_parent).is(selector)) parents.push(_parent);\n } else {\n parents.push(_parent);\n }\n\n _parent = _parent.parentNode;\n }\n }\n\n return $(parents);\n }\n\n function closest(selector) {\n var closest = this; // eslint-disable-line\n\n if (typeof selector === 'undefined') {\n return $([]);\n }
166\n\n if (!closest.is(selector)) {\n closest = closest.parents(selector).eq(0);\n }\n\n return closest;\n }\n\n function find(selector) {\n var foundElements = [];\n\n for (var i = 0; i < this.length; i += 1) {\n var found = this[i].querySelectorAll(selector);\n\n for (var j = 0; j < found.length; j += 1) {\n foundElements.push(found[j]);\n }\n }\n\n return $(foundElements);\n }\n\n function children(selector) {\n var children = []; // eslint-disable-line\n\n for (var i = 0; i < this.length; i += 1) {\n var childNodes = this[i].children;\n\n for (var j = 0; j < childNodes.length; j += 1) {\n if (!selector || $(childNodes[j]).is(selector)) {\n children.push(childNodes[j]);\n }\n }\n }\n\n return $(children);\n }\n\n function remove() {\n for (var i = 0; i < this.length; i += 1) {\n if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n }\n\n return this;\n }\n\n var Methods = {\n addClass: addClass,\n removeClass: removeClass,\n hasClass: hasClass,\n toggleClass: toggleClass,\n attr: attr,\n removeAttr: removeAttr,\n transform: transform,\n transition: transition,\n on: on,\n off: off,\n trigger: trigger,\n transitionEnd: transitionEnd,\n outerWidth: outerWidth,\n outerHeight: outerHeight,\n styles: styles,\n offset: offset,\n css: css,\n each: each,\n html: html,\n text: text,\n is: is,\n index: index,\n eq: eq,\n append: append,\n prepend: prepend,\n next: next,\n nextAll: nextAll,\n prev: prev,\n prevAll: prevAll,\n parent: parent,\n parents: parents,\n closest: closest,\n find: find,\n children: children,\n filter: filter,\n remove: remove\n };\n Object.keys(Methods).forEach(function (methodName) {\n $.fn[methodName] = Methods[methodName];\n });\n\n function deleteProps(obj) {\n var object = obj;\n Object.keys(object).forEach(function (key) {\n try {\n object[key] = null;\n } catch (e) {// no getter for object\n }
166\n\n try {\n delete object[key];\n } catch (e) {// something got wrong\n }\n });\n }\n\n function nextTick(callback, delay) {\n if (delay === void 0) {\n delay = 0;\n }\n\n return setTimeout(callback, delay);\n }\n\n function now() {\n return Date.now();\n }\n\n function getTranslate(el, axis) {\n if (axis === void 0) {\n axis = 'x';\n }\n\n var window = getWindow();\n var matrix;\n var curTransform;\n var transformMatrix;\n var curStyle = window.getComputedStyle(el, null);\n\n if (window.WebKitCSSMatrix) {\n curTransform = curStyle.transform || curStyle.webkitTransform;\n\n if (curTransform.split(',').length > 6) {\n curTransform = curTransform.split(', ').map(function (a) {\n return a.replace(',', '.');\n }).join(', ');\n } // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n\n\n transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n } else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n\n if (axis === 'x') {\n // Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; // Crazy IE10 Matrix\n else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); // Normal Browsers\n else curTransform = parseFloat(matrix[4]);\n }\n\n if (axis === 'y') {\n // Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; // Crazy IE10 Matrix\n else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); // Normal Browsers\n else curTransform = parseFloat(matrix[5]);\n }\n\n return curTransform || 0;\n }\n\n function isObject$1(o) {\n return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;\n }\n\n function extend$1() {\n var to = Object(arguments.length <= 0 ? undefined : arguments[0]);\n\n for (var i = 1; i < arguments.length; i += 1) {\n var nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];\n\n if (nextSource !== undefined && nextSource !== null) {\n var keysArray = Object.keys(Object(nextSource));\n\n for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {\n var nextKey = keysArray[nextIndex];\n var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);\n\n if (desc !== undefined && desc.enumerable) {\n if (isObject$1(to[nextKey]) && isObject$1(nextSource[nextKey])) {\n extend$1(to[nextKey], nextSource[nextKey]);\n } else if (!isObject$1(to[nextKey]) && isObject$1(nextSource[nextKey])) {\n to[nextKey] = {};\n extend$1(to[nextKey], nextSource[nextKey]);\n } else {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n }\n\n return to;\n }\n\n function bindModuleMethods(instance, obj) {\n Object.keys(obj).forEach(function (key) {\n if (isObject$1(obj[key])) {\n Object.keys(obj[key]).forEach(function (subKey) {\n if (typeof obj[key][subKey] === 'function') {\n obj[key][subKey] = obj[key][subKey].bind(instance);\n }\n });\n }\n\n instance[key] = obj[key];\n });\n }\n\n var support;\n\n function calcSupport() {\n var window = getWindow();\n var document = getDocument();\n return {\n touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch),\n pointerEvents: !!window.PointerEvent && 'maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints >= 0,\n observer: function checkObserver() {\n return 'MutationObserver' in window || 'WebkitMutationObserver' in window;\n }(),\n passiveListener: function checkPassiveListener() {\n var supportsPassive = false;\n\n try {\n var opts = Object.defineProperty({}, 'passive', {\n // eslint-disable-next-line\n get: function get() {\n supportsPassive = true;\n }\n });\n window.addEventListener('testPassiveListener', null, opts);\n } catch (e) {// No support\n }\n\n return supportsPassive;\n }(),\n gestures: function checkGestures() {\n return 'ongesturestart' in window;\n }()\n };\n }
166\n\n function getSupport() {\n if (!support) {\n support = calcSupport();\n }\n\n return support;\n }\n\n var device;\n\n function calcDevice(_temp) {\n var _ref = _temp === void 0 ? {} : _temp,\n userAgent = _ref.userAgent;\n\n var support = getSupport();\n var window = getWindow();\n var platform = window.navigator.platform;\n var ua = userAgent || window.navigator.userAgent;\n var device = {\n ios: false,\n android: false\n };\n var screenWidth = window.screen.width;\n var screenHeight = window.screen.height;\n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/); // eslint-disable-line\n\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n var iphone = !ipad && ua.match(/(iPhone\\sOS|iOS)\\s([\\d_]+)/);\n var windows = platform === 'Win32';\n var macos = platform === 'MacIntel'; // iPadOs 13 fix\n\n var iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768'];\n\n if (!ipad && macos && support.touch && iPadScreens.indexOf(screenWidth + \"x\" + screenHeight) >= 0) {\n ipad = ua.match(/(Version)\\/([\\d.]+)/);\n if (!ipad) ipad = [0, 1, '13_0_0'];\n macos = false;\n } // Android\n\n\n if (android && !windows) {\n device.os = 'android';\n device.android = true;\n }\n\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n } // Export object\n\n\n return device;\n }\n\n function getDevice(overrides) {\n if (overrides === void 0) {\n overrides = {};\n }\n\n if (!device) {\n device = calcDevice(overrides);\n }\n\n return device;\n }\n\n var browser;\n\n function calcBrowser() {\n var window = getWindow();\n\n function isSafari() {\n var ua = window.navigator.userAgent.toLowerCase();\n return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;\n }\n\n return {\n isEdge: !!window.navigator.userAgent.match(/Edge/g),\n isSafari: isSafari(),\n isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent)\n };\n }\n\n function getBrowser() {\n if (!browser) {\n browser = calcBrowser();\n }\n\n return browser;\n }\n\n var Resize = {\n name: 'resize',\n create: function create() {\n var swiper = this;\n extend$1(swiper, {\n resize: {\n resizeHandler: function resizeHandler() {\n if (!swiper || swiper.destroyed || !swiper.initialized) return;\n swiper.emit('beforeResize');\n swiper.emit('resize');\n },\n orientationChangeHandler: function orientationChangeHandler() {\n if (!swiper || swiper.destroyed || !swiper.initialized) return;\n swiper.emit('orientationchange');\n }\n }\n });\n },\n on: {\n init: function init(swiper) {\n var window = getWindow(); // Emit resize\n\n window.addEventListener('resize', swiper.resize.resizeHandler); // Emit orientationchange\n\n window.addEventListener('orientationchange', swiper.resize.orientationChangeHandler);\n },\n destroy: function destroy(swiper) {\n var window = getWindow();\n window.removeEventListener('resize', swiper.resize.resizeHandler);\n window.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler);\n }\n }\n };\n\n var Observer = {\n attach: function attach(target, options) {\n if (options === void 0) {\n options = {};\n }\n\n var window = getWindow();\n var swiper = this;\n var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n var observer = new ObserverFunc(function (mutations) {\n // The observerUpdate event should only be triggered\n // once despite the number of mutations. Additional\n // triggers are redundant and are very costly\n if (mutations.length === 1) {\n swiper.emit('observerUpdate', mutations[0]);\n return;\n }\n\n var observerUpdate = function observerUpdate() {\n swiper.emit('observerUpdate', mutations[0]);\n };\n\n if (window.requestAnimationFrame) {\n window.requestAnimationFrame(observerUpdate);\n } else {\n window.setTimeout(observerUpdate, 0);\n }\n });\n observer.observe(target, {\n attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n childList: typeof options.childList === 'undefined' ? true : options.childList,\n characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n });\n swiper.observer.observers.push(observer);\n }
166,\n init: function init() {\n var swiper = this;\n if (!swiper.support.observer || !swiper.params.observer) return;\n\n if (swiper.params.observeParents) {\n var containerParents = swiper.$el.parents();\n\n for (var i = 0; i < containerParents.length; i += 1) {\n swiper.observer.attach(containerParents[i]);\n }\n } // Observe container\n\n\n swiper.observer.attach(swiper.$el[0], {\n childList: swiper.params.observeSlideChildren\n }); // Observe wrapper\n\n swiper.observer.attach(swiper.$wrapperEl[0], {\n attributes: false\n });\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.observer.observers.forEach(function (observer) {\n observer.disconnect();\n });\n swiper.observer.observers = [];\n }\n };\n var Observer$1 = {\n name: 'observer',\n params: {\n observer: false,\n observeParents: false,\n observeSlideChildren: false\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n observer: _extends(_extends({}, Observer), {}, {\n observers: []\n })\n });\n },\n on: {\n init: function init(swiper) {\n swiper.observer.init();\n },\n destroy: function destroy(swiper) {\n swiper.observer.destroy();\n }\n }\n };\n\n var modular = {\n useParams: function useParams(instanceParams) {\n var instance = this;\n if (!instance.modules) return;\n Object.keys(instance.modules).forEach(function (moduleName) {\n var module = instance.modules[moduleName]; // Extend params\n\n if (module.params) {\n extend$1(instanceParams, module.params);\n }\n });\n },\n useModules: function useModules(modulesParams) {\n if (modulesParams === void 0) {\n modulesParams = {};\n }\n\n var instance = this;\n if (!instance.modules) return;\n Object.keys(instance.modules).forEach(function (moduleName) {\n var module = instance.modules[moduleName];\n var moduleParams = modulesParams[moduleName] || {}; // Add event listeners\n\n if (module.on && instance.on) {\n Object.keys(module.on).forEach(function (moduleEventName) {\n instance.on(moduleEventName, module.on[moduleEventName]);\n });\n } // Module create callback\n\n\n if (module.create) {\n module.create.bind(instance)(moduleParams);\n }\n });\n }\n };\n\n /* eslint-disable no-underscore-dangle */\n var eventsEmitter = {\n on: function on(events, handler, priority) {\n var self = this;\n if (typeof handler !== 'function') return self;\n var method = priority ? 'unshift' : 'push';\n events.split(' ').forEach(function (event) {\n if (!self.eventsListeners[event]) self.eventsListeners[event] = [];\n self.eventsListeners[event][method](handler);\n });\n return self;\n },\n once: function once(events, handler, priority) {\n var self = this;\n if (typeof handler !== 'function') return self;\n\n function onceHandler() {\n self.off(events, onceHandler);\n\n if (onceHandler.__emitterProxy) {\n delete onceHandler.__emitterProxy;\n }\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n handler.apply(self, args);\n }\n\n onceHandler.__emitterProxy = handler;\n return self.on(events, onceHandler, priority);\n },\n onAny: function onAny(handler, priority) {\n var self = this;\n if (typeof handler !== 'function') return self;\n var method = priority ? 'unshift' : 'push';\n\n if (self.eventsAnyListeners.indexOf(handler) < 0) {\n self.eventsAnyListeners[method](handler);\n }\n\n return self;\n },\n offAny: function offAny(handler) {\n var self = this;\n if (!self.eventsAnyListeners) return self;\n var index = self.eventsAnyListeners.indexOf(handler);\n\n if (index >= 0) {\n self.eventsAnyListeners.splice(index, 1);\n }\n\n return self;\n },\n off: function off(events, handler) {\n var self = this;\n if (!self.eventsListeners) return self;\n events.split(' ').forEach(function (event) {\n if (typeof handler === 'undefined') {\n self.eventsListeners[event] = [];\n } else if (self.eventsListeners[event]) {\n self.eventsListeners[event].forEach(function (eventHandler, index) {\n if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {\n self.eventsListeners[event].splice(index, 1);\n }\n });\n }\n });\n return self;\n },\n emit: function emit() {\n var self = this;\n if (!self.eventsListeners) return self;\n var events;\n var data;\n var context;\n\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n if (typeof args[0] === 'string' || Array.isArray(args[0])) {\n events = args[0];\n data = args.slice(1, args.length);\n context = self;\n } else {\n events = args[0].events;\n data = args[0].data;
166\n context = args[0].context || self;\n }\n\n data.unshift(context);\n var eventsArray = Array.isArray(events) ? events : events.split(' ');\n eventsArray.forEach(function (event) {\n if (self.eventsListeners && self.eventsListeners[event]) {\n var handlers = [];\n self.eventsListeners[event].forEach(function (eventHandler) {\n handlers.push(eventHandler);\n });\n handlers.forEach(function (eventHandler) {\n eventHandler.apply(context, data);\n });\n }\n });\n return self;\n }\n };\n\n function updateSize() {\n var swiper = this;\n var width;\n var height;\n var $el = swiper.$el;\n\n if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {\n width = swiper.params.width;\n } else {\n width = $el[0].clientWidth;\n }\n\n if (typeof swiper.params.height !== 'undefined' && swiper.params.width !== null) {\n height = swiper.params.height;\n } else {\n height = $el[0].clientHeight;\n }\n\n if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {\n return;\n } // Subtract paddings\n\n\n width = width - parseInt($el.css('padding-left') || 0, 10) - parseInt($el.css('padding-right') || 0, 10);\n height = height - parseInt($el.css('padding-top') || 0, 10) - parseInt($el.css('padding-bottom') || 0, 10);\n if (Number.isNaN(width)) width = 0;\n if (Number.isNaN(height)) height = 0;\n extend$1(swiper, {\n width: width,\n height: height,\n size: swiper.isHorizontal() ? width : height\n });\n }\n\n function updateSlides() {\n var swiper = this;\n var window = getWindow();\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl,\n swiperSize = swiper.size,\n rtl = swiper.rtlTranslate,\n wrongRTL = swiper.wrongRTL;\n var isVirtual = swiper.virtual && params.virtual.enabled;\n var previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;\n var slides = $wrapperEl.children(\".\" + swiper.params.slideClass);\n var slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;\n var snapGrid = [];\n var slidesGrid = [];\n var slidesSizesGrid = [];\n\n function slidesForMargin(slideEl, slideIndex) {\n if (!params.cssMode) return true;\n\n if (slideIndex === slides.length - 1) {\n return false;\n }\n\n return true;\n }\n\n var offsetBefore = params.slidesOffsetBefore;\n\n if (typeof offsetBefore === 'function') {\n offsetBefore = params.slidesOffsetBefore.call(swiper);\n }\n\n var offsetAfter = params.slidesOffsetAfter;\n\n if (typeof offsetAfter === 'function') {\n offsetAfter = params.slidesOffsetAfter.call(swiper);\n }\n\n var previousSnapGridLength = swiper.snapGrid.length;\n var previousSlidesGridLength = swiper.snapGrid.length;\n var spaceBetween = params.spaceBetween;\n var slidePosition = -offsetBefore;\n var prevSlideSize = 0;\n var index = 0;\n\n if (typeof swiperSize === 'undefined') {\n return;\n }\n\n if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;\n }\n\n swiper.virtualSize = -spaceBetween; // reset margins\n\n if (rtl) slides.css({\n marginLeft: '',\n marginTop: ''\n });else slides.css({\n marginRight: '',\n marginBottom: ''\n });\n var slidesNumberEvenToRows;\n\n if (params.slidesPerColumn > 1) {\n if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) {\n slidesNumberEvenToRows = slidesLength;\n } else {\n slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn;\n }\n\n if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') {\n slidesNumberEvenToRows = Math.max(slidesNumber
166EvenToRows, params.slidesPerView * params.slidesPerColumn);\n }\n } // Calc slides\n\n\n var slideSize;\n var slidesPerColumn = params.slidesPerColumn;\n var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n var numFullColumns = Math.floor(slidesLength / params.slidesPerColumn);\n\n for (var i = 0; i < slidesLength; i += 1) {\n slideSize = 0;\n var slide = slides.eq(i);\n\n if (params.slidesPerColumn > 1) {\n // Set slides order\n var newSlideOrderIndex = void 0;\n var column = void 0;\n var row = void 0;\n\n if (params.slidesPerColumnFill === 'row' && params.slidesPerGroup > 1) {\n var groupIndex = Math.floor(i / (params.slidesPerGroup * params.slidesPerColumn));\n var slideIndexInGroup = i - params.slidesPerColumn * params.slidesPerGroup * groupIndex;\n var columnsInGroup = groupIndex === 0 ? params.slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * slidesPerColumn * params.slidesPerGroup) / slidesPerColumn), params.slidesPerGroup);\n row = Math.floor(slideIndexInGroup / columnsInGroup);\n column = slideIndexInGroup - row * columnsInGroup + groupIndex * params.slidesPerGroup;\n newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n slide.css({\n '-webkit-box-ordinal-group': newSlideOrderIndex,\n '-moz-box-ordinal-group': newSlideOrderIndex,\n '-ms-flex-order': newSlideOrderIndex,\n '-webkit-order': newSlideOrderIndex,\n order: newSlideOrderIndex\n });\n } else if (params.slidesPerColumnFill === 'column') {\n column = Math.floor(i / slidesPerColumn);\n row = i - column * slidesPerColumn;\n\n if (column > numFullColumns || column === numFullColumns && row === slidesPerColumn - 1) {\n row += 1;\n\n if (row >= slidesPerColumn) {\n row = 0;\n column += 1;\n }\n }\n } else {\n row = Math.floor(i / slidesPerRow);\n column = i - row * slidesPerRow;\n }\n\n slide.css(\"margin-\" + (swiper.isHorizontal() ? 'top' : 'left'), row !== 0 && params.spaceBetween && params.spaceBetween + \"px\");\n }\n\n if (slide.css('display') === 'none') continue; // eslint-disable-line\n\n if (params.slidesPerView === 'auto') {\n var slideStyles = window.getComputedStyle(slide[0], null);\n var currentTransform = slide[0].style.transform;\n var currentWebKitTransform = slide[0].style.webkitTransform;\n\n if (currentTransform) {\n slide[0].style.transform = 'none';\n }\n\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = 'none';\n }\n\n if (params.roundLengths) {\n slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n } else {\n // eslint-disable-next-line\n if (swiper.isHorizontal()) {\n var width = parseFloat(slideStyles.getPropertyValue('width') || 0);\n var paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left') || 0);\n var paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right') || 0);\n var marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left') || 0);\n var marginRight = parseFloat(slideStyles.getPropertyValue('margin-right') || 0);\n var boxSizing = slideStyles.getPropertyValue('box-sizing');\n\n if (boxSizing && boxSizing === 'border-box') {\n slideSize = width + marginLeft + marginRight;\n } else {\n slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight;\n }\n } else {\n var height = parseFloat(slideStyles.getPropertyValue('height') || 0);\n var paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top') || 0);\n var paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom') || 0);\n var marginTop = parseFloat(slideStyles.getPropertyValue('margin-top') || 0);\n var marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom') || 0);\n\n var _boxSizing = slideStyles.getPropertyValue('box-sizing');\n\n if (_boxSizing && _boxSizing === 'border-box') {\n slideSize = height + marginTop + marginBottom;\n } else {\n slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom;\n }\n }\n }\n\n if (currentTransform) {\n slide[0].style.transform = currentTransform;\n }\n\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = currentWebKitTransform;\n }\n\n if (params.roundLengths) slideSize = Math.floor(slideSize);\n } else {\n slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;\n if (params.roundLengths) slideSize = Math.floor(slideSize);\n\n if (slides[i]) {\n if (swiper.isHorizontal()) {\n slides[i].style.width = slideSize + \"px\";\n } else {\n slides[i].style.height = slideSize + \"px\";\n }\n }\n }\n\n if (slides[i]) {\n slides[i].swiperSlideSize = slideSize;\n }\n\n slidesSizesGrid.push(slideSize);\n\n if (params.centeredSlides) {\n slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;\n if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;\n if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n if (params.roundLengths) slidePosition = Math.floor(slidePosition);\n if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);\n slidesGrid.push(slidePosition);\n } else {\n if (params.roundLengths) slidePosition = Math.floor(slidePosition);\n if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);\n slidesGrid.push(slidePosition);\n slidePosition = slidePosition + slideSize + spaceBetween;\n }\n\n swiper.virtualSize += slideSize + spaceBetween;\n prevSlideSize = slideSize;\n index += 1;\n }\n\n swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;\n var newSlidesGrid;\n\n if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {\n $wrapperEl.css({\n width: swiper.virtualSize + params.spaceBetween + \"px\"\n });\n }\n\n if (params.setWrapperSize) {\n if (swiper.isHorizontal()) $wrapperEl.css({\n width: swiper.virtualSize + params.spaceBetween + \"px\"\n });else $wrapperEl.css({\n height: swiper.virtualSize + params.spaceBetween + \"px\"\n });\n }\n\n if (params.slidesPerColumn > 1) {\n swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumber
166EvenToRows;\n swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween;\n if (swiper.isHorizontal()) $wrapperEl.css({\n width: swiper.virtualSize + params.spaceBetween + \"px\"\n });else $wrapperEl.css({\n height: swiper.virtualSize + params.spaceBetween + \"px\"\n });\n\n if (params.centeredSlides) {\n newSlidesGrid = [];\n\n for (var _i = 0; _i < snapGrid.length; _i += 1) {\n var slidesGridItem = snapGrid[_i];\n if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);\n if (snapGrid[_i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);\n }\n\n snapGrid = newSlidesGrid;\n }\n } // Remove last grid elements depending on width\n\n\n if (!params.centeredSlides) {\n newSlidesGrid = [];\n\n for (var _i2 = 0; _i2 < snapGrid.length; _i2 += 1) {\n var _slidesGridItem = snapGrid[_i2];\n if (params.roundLengths) _slidesGridItem = Math.floor(_slidesGridItem);\n\n if (snapGrid[_i2] <= swiper.virtualSize - swiperSize) {\n newSlidesGrid.push(_slidesGridItem);\n }\n }\n\n snapGrid = newSlidesGrid;\n\n if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {\n snapGrid.push(swiper.virtualSize - swiperSize);\n }\n }\n\n if (snapGrid.length === 0) snapGrid = [0];\n\n if (params.spaceBetween !== 0) {\n if (swiper.isHorizontal()) {\n if (rtl) slides.filter(slidesForMargin).css({\n marginLeft: spaceBetween + \"px\"\n });else slides.filter(slidesForMargin).css({\n marginRight: spaceBetween + \"px\"\n });\n } else slides.filter(slidesForMargin).css({\n marginBottom: spaceBetween + \"px\"\n });\n }\n\n if (params.centeredSlides && params.centeredSlidesBounds) {\n var allSlidesSize = 0;\n slidesSizesGrid.forEach(function (slideSizeValue) {\n allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);\n });\n allSlidesSize -= params.spaceBetween;\n var maxSnap = allSlidesSize - swiperSize;\n snapGrid = snapGrid.map(function (snap) {\n if (snap < 0) return -offsetBefore;\n if (snap > maxSnap) return maxSnap + offsetAfter;\n return snap;\n });\n }\n\n if (params.centerInsufficientSlides) {\n var _allSlidesSize = 0;\n slidesSizesGrid.forEach(function (slideSizeValue) {\n _allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);\n });\n _allSlidesSize -= params.spaceBetween;\n\n if (_allSlidesSize < swiperSize) {\n var allSlidesOffset = (swiperSize - _allSlidesSize) / 2;\n snapGrid.forEach(function (snap, snapIndex) {\n snapGrid[snapIndex] = snap - allSlidesOffset;\n });\n slidesGrid.forEach(function (snap, snapIndex) {\n slidesGrid[snapIndex] = snap + allSlidesOffset;\n });\n }\n }\n\n extend$1(swiper, {\n slides: slides,\n snapGrid: snapGrid,\n slidesGrid: slidesGrid,\n slidesSizesGrid: slidesSizesGrid\n });\n\n if (slidesLength !== previousSlidesLength) {\n swiper.emit('slidesLengthChange');\n }\n\n if (snapGrid.length !== previousSnapGridLength) {\n if (swiper.params.watchOverflow) swiper.checkOverflow();\n swiper.emit('snapGridLengthChange');\n }\n\n if (slidesGrid.length !== previousSlidesGridLength) {\n swiper.emit('slidesGridLengthChange');\n }\n\n if (params.watchSlidesProgress || params.watchSlidesVisibility) {\n swiper.updateSlidesOffset();\n }\n }\n\n function updateAutoHeight(speed) {\n var swiper = this;\n var activeSlides = [];\n var newHeight = 0;\n var i;\n\n if (typeof speed === 'number') {\n swiper.setTransition(speed);\n } else if (speed === true) {\n swiper.setTransition(swiper.params.speed);\n } // Find slides currently in view\n\n\n if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {\n if (swiper.params.centeredSlides) {\n swiper.visibleSlides.each(function (slide) {\n activeSlides.push(slide);\n });\n } else {\n for (i = 0;
166 i < Math.ceil(swiper.params.slidesPerView); i += 1) {\n var index = swiper.activeIndex + i;\n if (index > swiper.slides.length) break;\n activeSlides.push(swiper.slides.eq(index)[0]);\n }\n }\n } else {\n activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]);\n } // Find new height from highest slide in view\n\n\n for (i = 0; i < activeSlides.length; i += 1) {\n if (typeof activeSlides[i] !== 'undefined') {\n var height = activeSlides[i].offsetHeight;\n newHeight = height > newHeight ? height : newHeight;\n }\n } // Update Height\n\n\n if (newHeight) swiper.$wrapperEl.css('height', newHeight + \"px\");\n }\n\n function updateSlidesOffset() {\n var swiper = this;\n var slides = swiper.slides;\n\n for (var i = 0; i < slides.length; i += 1) {\n slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop;\n }\n }\n\n function updateSlidesProgress(translate) {\n if (translate === void 0) {\n translate = this && this.translate || 0;\n }\n\n var swiper = this;\n var params = swiper.params;\n var slides = swiper.slides,\n rtl = swiper.rtlTranslate;\n if (slides.length === 0) return;\n if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();\n var offsetCenter = -translate;\n if (rtl) offsetCenter = translate; // Visible Slides\n\n slides.removeClass(params.slideVisibleClass);\n swiper.visibleSlidesIndexes = [];\n swiper.visibleSlides = [];\n\n for (var i = 0; i < slides.length; i += 1) {\n var slide = slides[i];\n var slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + params.spaceBetween);\n\n if (params.watchSlidesVisibility || params.centeredSlides && params.autoHeight) {\n var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n var slideAfter = slideBefore + swiper.slidesSizesGrid[i];\n var isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;\n\n if (isVisible) {\n swiper.visibleSlides.push(slide);\n swiper.visibleSlidesIndexes.push(i);\n slides.eq(i).addClass(params.slideVisibleClass);\n }\n }\n\n slide.progress = rtl ? -slideProgress : slideProgress;\n }\n\n swiper.visibleSlides = $(swiper.visibleSlides);\n }\n\n function updateProgress(translate) {\n var swiper = this;\n\n if (typeof translate === 'undefined') {\n var multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line\n\n translate = swiper && swiper.translate && swiper.translate * multiplier || 0;\n }\n\n var params = swiper.params;\n var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n var progress = swiper.progress,\n isBeginning = swiper.isBeginning,\n isEnd = swiper.isEnd;\n var wasBeginning = isBeginning;\n var wasEnd = isEnd;\n\n if (translatesDiff === 0) {\n progress = 0;\n isBeginning = true;\n isEnd = true;\n } else {\n progress = (translate - swiper.minTranslate()) / translatesDiff;\n isBeginning = progress <= 0;\n isEnd = progress >= 1;\n }\n\n extend$1(swiper, {\n progress: progress,\n isBeginning: isBeginning,\n isEnd: isEnd\n });\n if (params.watchSlidesProgress || params.watchSlidesVisibility || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);\n\n if (isBeginning && !wasBeginning) {\n swiper.emit('reachBeginning toEdge');\n }\n\n if (isEnd && !wasEnd) {\n swiper.emit('reachEnd toEdge');\n }\n\n if (wasBeginning && !isBeginning || wasEnd && !isEnd) {\n swiper.emit('fromEdge');\n }\n\n swiper.emit('progress', progress);\n }\n\n function updateSlidesClasses() {\n var swiper = this;\n var slides = swiper.slides,\n params = swiper.params,\n $wrapperEl = swiper.$wrapperEl,\n activeIndex = swiper.activeIndex,\n realIndex = swiper.realIndex;\n var isVirtual = swiper.virtual && params.virtual.enabled;\n slides.removeClass(params.slideActiveClass + \" \" + params.slideNextClass + \" \" + params.slidePrevClass + \" \" + params.slideDuplicateActiveClass + \" \" + params.slideDuplicateNextClass + \" \" + params.slideDuplicatePrevClass);\n var activeSlide;\n\n if (isVirtual) {\n activeSlide = swiper.$wrapperEl.find(\".\" + params.slideClass + \"[data-swiper-slide-index=\\\"\" + activeIndex + \"\\\"]\");\n } else {\n activeSlide = slides.eq(activeIndex);\n } // Active classes\n\n\n activeSlide.addClass(params.slideActiveClass);\n\n if (params.loop) {\n // Duplicate to all looped slides\n if (activeSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(\".\" + params.slideClass + \":not(.\" + params.slideDuplicateClass + \")[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]\").addClass(params.slideDuplicateActiveClass);\n } else {\n $wrapperEl.children(\".\" + params.slideClass + \".\" + params.slideDuplicateClass + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]\").addClass(params.slideDuplicateActiveClass);\n }\n } // Next Slide\n\n\n var nextSlide = activeSlide.nextAll(\".\" + params.slideClass).eq(0).addClass(params.slideNextClass);\n\n if (params.loop && nextSlide.length === 0) {\n nextSlide = slides.eq(0);\n nextSlide.addClass(params.slideNextClass);\n } // Prev Slide\n\n\n var prevSlide = activeSlide.prevAll(\".\" + params.slideClass).eq(0).addClass(params.slidePrevClass);\n\n if (params.loop && prevSlide.length === 0) {\n prevSlide = slides.eq(-1);\n prevSlide.addClass(params.slidePrevClass);\n }\n\n if (params.loop) {\n // Duplicate to all looped slides\n if (nextSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(\".\" + params.slideClass + \":not(.\" + params.slideDuplicateClass + \")[data-swiper-slide-index=\\\"\" + nextSlide.attr('data-swiper-slide-index') + \"\\\"]\").addClass(params.slideDuplicateNextClass);\n } else {\n $wrapperEl.children(\".\" + params.slideClass + \".\" + params.slideDuplicateClass + \"[data-swiper-slide-index=\\\"\" + nextSlide.attr('data-swiper-slide-index') + \"\\\"]\").addClass(params.slideDuplicateNextClass);\n }\n\n if (prevSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(\".\" + params.slideClass + \":not(.\" + params.slideDuplicateClass + \")[data-swiper-slide-index=\\\"\" + prevSlide.attr('data-swiper-slide-index') + \"\\\"]\").addClass(params.slideDuplicatePrevClass);\n } else {\n $wrapperEl.children(\".\" + params.slideClass + \".\" + params.slideDuplicateClass + \"[data-swiper-slide-index=\\\"\" + prevSlide.attr('data-swiper-slide-index') + \"\\\"]\").addClass(params.slideDuplicatePrevClass);\n }\n }\n\n swiper.emitSlidesClasses();\n }\n\n function updateActiveIndex(newActiveIndex) {\n var swiper = this;\n var translate = swiper.rtlTranslate ? swiper.translate : -swi
166per.translate;\n var slidesGrid = swiper.slidesGrid,\n snapGrid = swiper.snapGrid,\n params = swiper.params,\n previousIndex = swiper.activeIndex,\n previousRealIndex = swiper.realIndex,\n previousSnapIndex = swiper.snapIndex;\n var activeIndex = newActiveIndex;\n var snapIndex;\n\n if (typeof activeIndex === 'undefined') {\n for (var i = 0; i < slidesGrid.length; i += 1) {\n if (typeof slidesGrid[i + 1] !== 'undefined') {\n if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {\n activeIndex = i;\n } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {\n activeIndex = i + 1;\n }\n } else if (translate >= slidesGrid[i]) {\n activeIndex = i;\n }\n } // Normalize slideIndex\n\n\n if (params.normalizeSlideIndex) {\n if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;\n }\n }\n\n if (snapGrid.indexOf(translate) >= 0) {\n snapIndex = snapGrid.indexOf(translate);\n } else {\n var skip = Math.min(params.slidesPerGroupSkip, activeIndex);\n snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);\n }\n\n if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;\n\n if (activeIndex === previousIndex) {\n if (snapIndex !== previousSnapIndex) {\n swiper.snapIndex = snapIndex;\n swiper.emit('snapIndexChange');\n }\n\n return;\n } // Get real index\n\n\n var realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10);\n extend$1(swiper, {\n snapIndex: snapIndex,\n realIndex: realIndex,\n previousIndex: previousIndex,\n activeIndex: activeIndex\n });\n swiper.emit('activeIndexChange');\n swiper.emit('snapIndexChange');\n\n if (previousRealIndex !== realIndex) {\n swiper.emit('realIndexChange');\n }\n\n if (swiper.initialized || swiper.params.runCallbacksOnInit) {\n swiper.emit('slideChange');\n }\n }\n\n function updateClickedSlide(e) {\n var swiper = this;\n var params = swiper.params;\n var slide = $(e.target).closest(\".\" + params.slideClass)[0];\n var slideFound = false;\n\n if (slide) {\n for (var i = 0; i < swiper.slides.length; i += 1) {\n if (swiper.slides[i] === slide) slideFound = true;\n }\n }\n\n if (slide && slideFound) {\n swiper.clickedSlide = slide;\n\n if (swiper.virtual && swiper.params.virtual.enabled) {\n swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10);\n } else {\n swiper.clickedIndex = $(slide).index();\n }\n } else {\n swiper.clickedSlide = undefined;\n swiper.clickedIndex = undefined;\n return;\n }\n\n if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {\n swiper.slideToClickedSlide();\n }\n }\n\n var update = {\n updateSize: updateSize,\n updateSlides: updateSlides,\n updateAutoHeight: updateAutoHeight,\n updateSlidesOffset: updateSlidesOffset,\n updateSlidesProgress: updateSlidesProgress,\n updateProgress: updateProgress,\n updateSlidesClasses: updateSlidesClasses,\n updateActiveIndex: updateActiveIndex,\n updateClickedSlide: updateClickedSlide\n };\n\n function getSwiperTranslate(axis) {\n if (axis === void 0) {\n axis = this.isHorizontal() ? 'x' : 'y';\n }\n\n var swiper = this;\n var params = swiper.params,\n rtl = swiper.rtlTranslate,\n translate = swiper.translate,\n $wrapperEl = swiper.$wrapperEl;\n\n if (params.virtualTranslate) {\n return rtl ? -translate : translate;\n }\n\n if (params.cssMode) {\n return translate;\n }\n\n var currentTranslate = getTranslate($wrapperEl[0], axis);\n if (rtl) currentTranslate = -currentTranslate;\n return currentTranslate || 0;\n }\n\n function setTranslate(translate, byController) {\n var swiper = this;\n var rtl = swiper.rtlTranslate,\n params = swiper.params,\n $wrapperEl = swiper.$wrapperEl,\n wrapperEl = swiper.wrapperEl,\n progress = swiper.progress;\n var x = 0;\n var y = 0;\n var z = 0;\n\n if (swiper.isHorizontal()) {\n x = rtl ? -translate : translate;\n } else {\n y = translate;\n }\n\n if (params.roundLengths) {\n x = Math.floor(x);\n y = Math.floor(y);\n }\n\n if (params.cssMode) {\n wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;\n } else if (!params.virtualTranslate) {\n $wrapperEl.transform(\"translate3d(\" + x + \"px, \" + y + \"px, \" + z + \"px)\");\n }\n\n swiper.previousTranslate = swiper.translate;\n swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress\n\n var newProgress;\n var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n\n if (translatesDiff === 0) {\n newProgress = 0;\n } else {\n newProgress = (translate - swiper.minTranslate()) / translatesDiff;\n }\n\n if (newProgress !== progress) {\n swiper.updateProgress(translate);\n }\n\n swiper.emit('setTranslate', swiper.translate, byController);\n }\n\n function minTranslate() {\n return -this.snapGrid[0];\n }\n\n function maxTranslate() {\n return -this.snapGrid[this.snapGrid.length - 1];\n }\n\n function translateTo(translate, speed, runCallbacks, translateBounds, internal) {\n if (translate === void 0) {\n translate = 0;\n }\n\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n if (translateBounds === void 0) {\n translateBounds = true;\n }\n\n var swiper = this;\n var params = swiper.params,\n wrapperEl = swiper.wrapperEl;\n\n if (swiper.animating && params.preventInteractionOnTransition) {\n return false;\n }\n\n var minTranslate = swiper.minTranslate();\n var maxTranslate = swiper.maxTranslate();\n var newTranslate;\n if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate; // Update progress\n\n swiper.updateProgress(newTranslate);\n\n if (params.cssMode) {\n var isH = swiper.isHorizontal();\n\n if (speed === 0) {\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;\n } else {\n // eslint-disable-next-line\n if (wrapperEl.scrollTo) {\n var _wrapperEl$scrollTo;\n\n wrapperEl.scrollTo((_wrapperEl$scrollTo = {}, _wrapperEl$scrollTo[isH ? 'left' : 'top'] = -newTranslate, _wrapperEl$scrollTo.behavior = 'smooth', _wrapperEl$scrollTo));\n } else {\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;\n }\n }\n\n return true;\n }\n\n if (speed === 0) {\n swiper.setTransition(0);\n swiper.setTranslate(newTranslate);\n\n if (runCallbacks) {\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.emit('transitionEnd');\n }\n } else {\n swiper.setTransition(speed);\n swiper.setTranslate(newTranslate);\n\n if (runCallbacks) {\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.emit('transitionStart');\n }\n\n if (!swiper.animating) {\n swiper.animating = true;\n\n if (!swiper.onTranslateToWrapperTransitionEnd) {\n swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {\n if (!swiper || swiper.destroyed) return;\n if (e.target !== this) return;\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);\n swiper.onTranslateToWrapperTransitionEnd = null;\n delete swiper.onTranslateToWrapperTransitionEnd;\n\n if (runCallbacks) {\n swiper.emit('transitionEnd');\n }\n };\n }\n\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);\n }\n }\n\n return true;\n }\n\n var translate = {\n getTranslate: getSwiperTranslate,\n setTranslate: setTranslate,\n minTranslate: minTranslate,\n maxTranslate: maxTranslate,\n translateTo: translateTo\n };\n\n function setTransition(duration, byController) {\n var swiper = this;\n\n if (!swiper.params.cssMode) {\n swiper.$wrapperEl.transition(duration);\n }\n\n swiper.emit('setTransition', duration, byController);\n }\n\n function transitionStart(runCallbacks, direction) {\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var activeIndex = swiper.activeIndex,\n params = swiper.params,\n previousIndex = swiper.previousIndex;\n if (params.cssMode) return;\n\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n\n var dir = direction;\n\n if (!dir) {\n if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';\n }\n\n swiper.emit('transitionStart');\n\n if (runCallbacks && activeIndex !== previousIndex) {\n if (dir === 'reset') {\n swiper.emit('slideResetTransitionStart');\n return;\n }\n\n swiper.emit('slideChangeTransitionStart');\n\n if (dir === 'next') {\n swiper.emit('slideNextTransitionStart');\n } else {\n swiper.emit('slidePrevTransitionStart');\n }\n }\n }\n\n function transitionEnd$1(runCallbacks, direction) {\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var activeIndex = swiper.activeIndex,\n previousIndex = swiper.previousIndex,\n params = swiper.params;\n swiper.animating = false;\n if (params.cssMode) return;\n swiper.setTransition(0);\n var dir = direction;\n\n if (!dir) {\n if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';\n }\n\n swiper.emit('transitionEnd');\n\n if (runCallbacks && activeIndex !== previousIndex) {\n if (dir === 'reset') {\n swiper.emit('slideResetTransitionEnd');\n return;\n }\n\n swiper.emit('slideChangeTransitionEnd');\n\n if (dir === 'next') {\n swiper.emit('slideNextTransitionEnd');\n } else {\n swiper.emit('slidePrevTransitionEnd');\n }\n }\n }\n\n var transition$1 = {\n setTransition: setTransition,\n transitionStart: transitionStart,\n transitionEnd: transitionEnd$1\n };\n\n function slideTo(index, speed, runCallbacks, internal) {\n if (index === void 0) {\n index = 0;\n }\n\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var slideIndex = index;\n if (slideIndex < 0) slideIndex = 0;\n var params = swiper.params,\n snapGrid = swiper.snapGrid,\n slidesGrid = swiper.slidesGrid,\n previousIndex = swiper.previousIndex,\n activeIndex = swiper.activeIndex,\n rtl = swiper.rtlTranslate,\n wrapperEl = swiper.wrapperEl;\n\n if (swiper.animating && params.preventInteractionOnTransition) {\n return false;\n }\n\n var skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);\n var snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);\n if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;\n\n if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {\n swiper.emit('beforeSlideChangeStart');\n }
166\n\n var translate = -snapGrid[snapIndex]; // Update progress\n\n swiper.updateProgress(translate); // Normalize slideIndex\n\n if (params.normalizeSlideIndex) {\n for (var i = 0; i < slidesGrid.length; i += 1) {\n if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) {\n slideIndex = i;\n }\n }\n } // Directions locks\n\n\n if (swiper.initialized && slideIndex !== activeIndex) {\n if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {\n return false;\n }\n\n if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {\n if ((activeIndex || 0) !== slideIndex) return false;\n }\n }\n\n var direction;\n if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; // Update Index\n\n if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {\n swiper.updateActiveIndex(slideIndex); // Update Height\n\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n\n swiper.updateSlidesClasses();\n\n if (params.effect !== 'slide') {\n swiper.setTranslate(translate);\n }\n\n if (direction !== 'reset') {\n swiper.transitionStart(runCallbacks, direction);\n swiper.transitionEnd(runCallbacks, direction);\n }\n\n return false;\n }\n\n if (params.cssMode) {\n var isH = swiper.isHorizontal();\n var t = -translate;\n\n if (rtl) {\n t = wrapperEl.scrollWidth - wrapperEl.offsetWidth - t;\n }\n\n if (speed === 0) {\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;\n } else {\n // eslint-disable-next-line\n if (wrapperEl.scrollTo) {\n var _wrapperEl$scrollTo;\n\n wrapperEl.scrollTo((_wrapperEl$scrollTo = {}, _wrapperEl$scrollTo[isH ? 'left' : 'top'] = t, _wrapperEl$scrollTo.behavior = 'smooth', _wrapperEl$scrollTo));\n } else {\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;\n }\n }\n\n return true;\n }\n\n if (speed === 0) {\n swiper.setTransition(0);\n swiper.setTranslate(translate);\n swiper.updateActiveIndex(slideIndex);\n swiper.updateSlidesClasses();\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.transitionStart(runCallbacks, direction);\n swiper.transitionEnd(runCallbacks, direction);\n } else {\n swiper.setTransition(speed);\n swiper.setTranslate(translate);\n swiper.updateActiveIndex(slideIndex);\n swiper.updateSlidesClasses();\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.transitionStart(runCallbacks, direction);\n\n if (!swiper.animating) {\n swiper.animating = true;\n\n if (!swiper.onSlideToWrapperTransitionEnd) {\n swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {\n if (!swiper || swiper.destroyed) return;\n if (e.target !== this) return;\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n swiper.onSlideToWrapperTransitionEnd = null;\n delete swiper.onSlideToWrapperTransitionEnd;\n swiper.transitionEnd(runCallbacks, direction);\n };\n }\n\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n }\n }\n\n return true;\n }\n\n function slideToLoop(index, speed, runCallbacks, internal) {\n if (index === void 0) {\n index = 0;\n }\n\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var newIndex = index;\n\n if (swiper.params.loop) {\n newIndex += swiper.loopedSlides;\n }\n\n return swiper.slideTo(newIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideNext(speed, runCallbacks, internal) {\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var params = swiper.params,\n animating = swiper.animating;\n var increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup;\n\n if (params.loop) {\n if (animating && params.loopPreventsSlide) return false;\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n }\n\n return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slidePrev(speed, runCallbacks, internal) {\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n var params = swiper.params,\n animating = swiper.animating,\n snapGrid = swiper.snapGrid,\n slidesGrid = swiper.slidesGrid,\n rtlTranslate = swiper.rtlTranslate;\n\n if (params.loop) {\n if (animating && params.loopPreventsSlide) return false;\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n }
166\n\n var translate = rtlTranslate ? swiper.translate : -swiper.translate;\n\n function normalize(val) {\n if (val < 0) return -Math.floor(Math.abs(val));\n return Math.floor(val);\n }\n\n var normalizedTranslate = normalize(translate);\n var normalizedSnapGrid = snapGrid.map(function (val) {\n return normalize(val);\n });\n var currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)];\n var prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];\n\n if (typeof prevSnap === 'undefined' && params.cssMode) {\n snapGrid.forEach(function (snap) {\n if (!prevSnap && normalizedTranslate >= snap) prevSnap = snap;\n });\n }\n\n var prevIndex;\n\n if (typeof prevSnap !== 'undefined') {\n prevIndex = slidesGrid.indexOf(prevSnap);\n if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;\n }\n\n return swiper.slideTo(prevIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideReset(speed, runCallbacks, internal) {\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n var swiper = this;\n return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideToClosest(speed, runCallbacks, internal, threshold) {\n if (speed === void 0) {\n speed = this.params.speed;\n }\n\n if (runCallbacks === void 0) {\n runCallbacks = true;\n }\n\n if (threshold === void 0) {\n threshold = 0.5;\n }\n\n var swiper = this;\n var index = swiper.activeIndex;\n var skip = Math.min(swiper.params.slidesPerGroupSkip, index);\n var snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);\n var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;\n\n if (translate >= swiper.snapGrid[snapIndex]) {\n // The current translate is on or after the current snap index, so the choice\n // is between the current index and the one after it.\n var currentSnap = swiper.snapGrid[snapIndex];\n var nextSnap = swiper.snapGrid[snapIndex + 1];\n\n if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {\n index += swiper.params.slidesPerGroup;\n }\n } else {\n // The current translate is before the current snap index, so the choice\n // is between the current index and the one before it.\n var prevSnap = swiper.snapGrid[snapIndex - 1];\n var _currentSnap = swiper.snapGrid[snapIndex];\n\n if (translate - prevSnap <= (_currentSnap - prevSnap) * threshold) {\n index -= swiper.params.slidesPerGroup;\n }\n }\n\n index = Math.max(index, 0);\n index = Math.min(index, swiper.slidesGrid.length - 1);\n return swiper.slideTo(index, speed, runCallbacks, internal);\n }\n\n function slideToClickedSlide() {\n var swiper = this;\n var params = swiper.params,\n $wrapperEl = swiper.$wrapperEl;\n var slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;\n var slideToIndex = swiper.clickedIndex;\n var realIndex;\n\n if (params.loop) {\n if (swiper.animating) return;\n realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n\n if (params.centeredSlides) {\n if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {\n swiper.loopFix();\n slideToIndex = $wrapperEl.children(\".\" + params.slideClass + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]:not(.\" + params.slideDuplicateClass + \")\").eq(0).index();\n nextTick(function () {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else if (slideToIndex > swiper.slides.length - slidesPerView) {\n swiper.loopFix();\n slideToIndex = $wrapperEl.children(\".\" + params.slideClass + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]:not(.\" + params.slideDuplicateClass + \")\").eq(0).index();\n nextTick(function () {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else {\n swiper.slideTo(slideToIndex);\n }\n }\n\n var slide = {\n slideTo: slideTo,\n slideToLoop: slideToLoop,\n slideNext: slideNext,\n slidePrev: slidePrev,\n slideReset: slideReset,\n slideToClosest: slideToClosest,\n slideToClickedSlide: slideToClickedSlide\n };\n\n function loopCreate() {\n var swiper = this;\n var document = getDocument();\n var params = swiper.params,\n $wrapperEl = swiper.$wrapperEl; // Remove duplicated slides\n\n $wrapperEl.children(\".\" + params.slideClass + \".\" + params.slideDuplicateClass).remove();\n var slides = $wrapperEl.children(\".\" + params.slideClass);
166\n\n if (params.loopFillGroupWithBlank) {\n var blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup;\n\n if (blankSlidesNum !== params.slidesPerGroup) {\n for (var i = 0; i < blankSlidesNum; i += 1) {\n var blankNode = $(document.createElement('div')).addClass(params.slideClass + \" \" + params.slideBlankClass);\n $wrapperEl.append(blankNode);\n }\n\n slides = $wrapperEl.children(\".\" + params.slideClass);\n }\n }\n\n if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;\n swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));\n swiper.loopedSlides += params.loopAdditionalSlides;\n\n if (swiper.loopedSlides > slides.length) {\n swiper.loopedSlides = slides.length;\n }\n\n var prependSlides = [];\n var appendSlides = [];\n slides.each(function (el, index) {\n var slide = $(el);\n\n if (index < swiper.loopedSlides) {\n appendSlides.push(el);\n }\n\n if (index < slides.length && index >= slides.length - swiper.loopedSlides) {\n prependSlides.push(el);\n }\n\n slide.attr('data-swiper-slide-index', index);\n });\n\n for (var _i = 0; _i < appendSlides.length; _i += 1) {\n $wrapperEl.append($(appendSlides[_i].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n\n for (var _i2 = prependSlides.length - 1; _i2 >= 0; _i2 -= 1) {\n $wrapperEl.prepend($(prependSlides[_i2].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n }\n\n function loopFix() {\n var swiper = this;\n swiper.emit('beforeLoopFix');\n var activeIndex = swiper.activeIndex,\n slides = swiper.slides,\n loopedSlides = swiper.loopedSlides,\n allowSlidePrev = swiper.allowSlidePrev,\n allowSlideNext = swiper.allowSlideNext,\n snapGrid = swiper.snapGrid,\n rtl = swiper.rtlTranslate;\n var newIndex;\n swiper.allowSlidePrev = true;\n swiper.allowSlideNext = true;\n var snapTranslate = -snapGrid[activeIndex];\n var diff = snapTranslate - swiper.getTranslate(); // Fix For Negative Oversliding\n\n if (activeIndex < loopedSlides) {\n newIndex = slides.length - loopedSlides * 3 + activeIndex;\n newIndex += loopedSlides;\n var slideChanged = swiper.slideTo(newIndex, 0, false, true);\n\n if (slideChanged && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n } else if (activeIndex >= slides.length - loopedSlides) {\n // Fix For Positive Oversliding\n newIndex = -slides.length + activeIndex + loopedSlides;\n newIndex += loopedSlides;\n\n var _slideChanged = swiper.slideTo(newIndex, 0, false, true);\n\n if (_slideChanged && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n }\n\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n swiper.emit('loopFix');\n }\n\n function loopDestroy() {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl,\n params = swiper.params,\n slides = swiper.slides;\n $wrapperEl.children(\".\" + params.slideClass + \".\" + params.slideDuplicateClass + \",.\" + params.slideClass + \".\" + params.slideBlankClass).remove();\n slides.removeAttr('data-swiper-slide-index');\n }\n\n var loop = {\n loopCreate: loopCreate,\n loopFix: loopFix,\n loopDestroy: loopDestroy\n };\n\n function setGrabCursor(moving) {\n var swiper = this;\n if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;\n var el = swiper.el;\n el.style.cursor = 'move';\n el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';\n el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab';\n el.style.cursor = moving ? 'grabbing' : 'grab';\n }\n\n function unsetGrabCursor() {\n var swiper = this;\n\n if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {\n return;\n }\n\n swiper.el.style.cursor = '';\n }\n\n var grabCursor = {\n setGrabCursor: setGrabCursor,\n unsetGrabCursor: unsetGrabCursor\n };\n\n function appendSlide(slides) {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl,\n params = swiper.params;\n\n if (params.loop) {\n swiper.loopDestroy();\n }\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) $wrapperEl.append(slides[i]);\n }\n } else {\n $wrapperEl.append(slides);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!(params.observer && swiper.support.observer)) {\n swiper.update(
166);\n }\n }\n\n function prependSlide(slides) {\n var swiper = this;\n var params = swiper.params,\n $wrapperEl = swiper.$wrapperEl,\n activeIndex = swiper.activeIndex;\n\n if (params.loop) {\n swiper.loopDestroy();\n }\n\n var newActiveIndex = activeIndex + 1;\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) $wrapperEl.prepend(slides[i]);\n }\n\n newActiveIndex = activeIndex + slides.length;\n } else {\n $wrapperEl.prepend(slides);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!(params.observer && swiper.support.observer)) {\n swiper.update();\n }\n\n swiper.slideTo(newActiveIndex, 0, false);\n }\n\n function addSlide(index, slides) {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl,\n params = swiper.params,\n activeIndex = swiper.activeIndex;\n var activeIndexBuffer = activeIndex;\n\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children(\".\" + params.slideClass);\n }\n\n var baseLength = swiper.slides.length;\n\n if (index <= 0) {\n swiper.prependSlide(slides);\n return;\n }\n\n if (index >= baseLength) {\n swiper.appendSlide(slides);\n return;\n }\n\n var newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;\n var slidesBuffer = [];\n\n for (var i = baseLength - 1; i >= index; i -= 1) {\n var currentSlide = swiper.slides.eq(i);\n currentSlide.remove();\n slidesBuffer.unshift(currentSlide);\n }\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (var _i = 0; _i < slides.length; _i += 1) {\n if (slides[_i]) $wrapperEl.append(slides[_i]);\n }\n\n newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;\n } else {\n $wrapperEl.append(slides);\n }\n\n for (var _i2 = 0; _i2 < slidesBuffer.length; _i2 += 1) {\n $wrapperEl.append(slidesBuffer[_i2]);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!(params.observer && swiper.support.observer)) {\n swiper.update();\n }\n\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n }\n\n function removeSlide(slidesIndexes) {\n var swiper = this;\n var params = swiper.params,\n $wrapperEl = swiper.$wrapperEl,\n activeIndex = swiper.activeIndex;\n var activeIndexBuffer = activeIndex;\n\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children(\".\" + params.slideClass);\n }\n\n var newActiveIndex = activeIndexBuffer;\n var indexToRemove;\n\n if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {\n for (var i = 0; i < slidesIndexes.length; i += 1) {\n indexToRemove = slidesIndexes[i];\n if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex -= 1;\n }\n\n newActiveIndex = Math.max(newActiveIndex, 0);\n } else {\n indexToRemove = slidesIndexes;\n if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex -= 1;\n newActiveIndex = Math.max(newActiveIndex, 0);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!(params.observer && swiper.support.observer)) {\n swiper.update();\n }\n\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n }\n\n function removeAllSlides() {\n var swiper = this;\n var slidesIndexes = [];\n\n for (var i = 0; i < swiper.slides.length; i += 1) {\n slidesIndexes.push(i);\n }\n\n swiper.removeSlide(slidesIndexes);\n }\n\n var manipulation = {\n appendSlide: appendSlide,\n prependSlide: prependSlide,\n addSlide: addSlide,\n removeSlide: removeSlide,\n removeAllSlides: removeAllSlides\n };\n\n function onTouchStart(event) {\n var swiper = this;\n var document = getDocument();\n var window = getWindow();\n var data = swiper.touchEventsData;\n var params = swiper.params,\n touches = swiper.touches;\n\n if (swiper.animating && params.preventInteractionOnTransition) {\n return;\n }\n\n var e = event;\n if (e.originalEvent) e = e.originalEvent;\n var $targetEl = $(e.target);\n\n if (params.touchEventsTarget === 'wrapper') {\n if (!$targetEl.closest(swi
166per.wrapperEl).length) return;\n }\n\n data.isTouchEvent = e.type === 'touchstart';\n if (!data.isTouchEvent && 'which' in e && e.which === 3) return;\n if (!data.isTouchEvent && 'button' in e && e.button > 0) return;\n if (data.isTouched && data.isMoved) return;\n\n if (params.noSwiping && $targetEl.closest(params.noSwipingSelector ? params.noSwipingSelector : \".\" + params.noSwipingClass)[0]) {\n swiper.allowClick = true;\n return;\n }\n\n if (params.swipeHandler) {\n if (!$targetEl.closest(params.swipeHandler)[0]) return;\n }\n\n touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n var startX = touches.currentX;\n var startY = touches.currentY; // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore\n\n var edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;\n var edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;\n\n if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.screen.width - edgeSwipeThreshold)) {\n return;\n }\n\n extend$1(data, {\n isTouched: true,\n isMoved: false,\n allowTouchCallbacks: true,\n isScrolling: undefined,\n startMoving: undefined\n });\n touches.startX = startX;\n touches.startY = startY;\n data.touchStartTime = now();\n swiper.allowClick = true;\n swiper.updateSize();\n swiper.swipeDirection = undefined;\n if (params.threshold > 0) data.allowThresholdMove = false;\n\n if (e.type !== 'touchstart') {\n var preventDefault = true;\n if ($targetEl.is(data.formElements)) preventDefault = false;\n\n if (document.activeElement && $(document.activeElement).is(data.formElements) && document.activeElement !== $targetEl[0]) {\n document.activeElement.blur();\n }\n\n var shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;\n\n if (params.touchStartForcePreventDefault || shouldPreventDefault) {\n e.preventDefault();\n }\n }\n\n swiper.emit('touchStart', e);\n }\n\n function onTouchMove(event) {\n var document = getDocument();\n var swiper = this;\n var data = swiper.touchEventsData;\n var params = swiper.params,\n touches = swiper.touches,\n rtl = swiper.rtlTranslate;\n var e = event;\n if (e.originalEvent) e = e.originalEvent;\n\n if (!data.isTouched) {\n if (data.startMoving && data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n\n return;\n }\n\n if (data.isTouchEvent && e.type !== 'touchmove') return;\n var targetTouch = e.type === 'touchmove' && e.targetTouches && (e.targetTouches[0] || e.changedTouches[0]);\n var pageX = e.type === 'touchmove' ? targetTouch.pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? targetTouch.pageY : e.pageY;\n\n if (e.preventedByNestedSwiper) {\n touches.startX = pageX;\n touches.startY = pageY;\n return;\n }\n\n if (!swiper.allowTouchMove) {\n // isMoved = true;\n swiper.allowClick = false;\n\n if (data.isTouched) {\n extend$1(touches, {\n startX: pageX,\n startY: pageY,\n currentX: pageX,\n currentY: pageY\n });\n data.touchStartTime = now();\n }\n\n return;\n }\n\n if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {\n if (swiper.isVertical()) {\n // Vertical\n if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {\n data.isTouched = false;\n data.isMoved = false;\n return;\n }\n } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {\n return;\n }\n }\n\n if (data.isTouchEvent && document.activeElement) {\n if (e.target === document.activeElement && $(e.target).is(data.formElements)) {\n data.isMoved = true;\n swiper.allowClick = false;\n return;\n }\n }\n\n if (data.allowTouchCallbacks) {\n swiper.emit('touchMove', e);\n }\n\n if (e.targetTouches && e.targetTouches.length > 1) return;\n touches.currentX = pageX;\n touches.currentY = pageY;\n var diffX = touches.currentX - touches.startX;\n var diffY = touches.currentY - touches.startY;\n if (swiper.params.threshold && Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2)) < swiper.params.threshold) return;\n\n if (typeof data.isScrolling === 'undefined') {\n var touchAngle;\n\n if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {\n data.isScrolling = false;\n } else {\n // eslint-disable-next-line\n if (diffX * diffX + diffY * diffY >= 25) {\n touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;\n data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;\n }\n }\n }\n\n if (data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n\n if (typeof data.startMoving === 'undefined') {\n if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {\n data.startMoving = true;\n }\n }\n\n if (data.isScrolling) {\n data.isTouched = false;\n return;\n }\n\n if (!data.startMoving) {\n return;\n }\n\n swiper.allowClick = false;\n\n if (!params.cssMode && e.cancelable) {\n e.preventDefault();\n }\n\n if (params.touchMoveStopPropagation && !params.nested) {\n e.stopPropagation();\n }\n\n if (!data.isMoved) {\n if (params.loop) {\n swiper.loopFix();\n }\n\n data.startTranslate = swiper.getTranslate();\n swiper.setTransition(0);\n\n if (swiper.animating) {\n swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend');\n }\n\n data.allowMomentumBounce = false; // Grab Cursor\n\n if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(true);\n }\n\n swiper.emit('sliderFirstMove', e);\n }\n\n swiper.emit('sliderMove', e);\n data.isMoved = true;\n var diff = swiper.isHorizontal() ? diffX : diffY;\n touches.diff = diff;\n diff *= params.touchRatio;\n if (rtl) diff = -diff;\n swiper.swipeDirection = diff > 0 ? 'prev' : 'next';\n data.currentTranslate = diff + data.startTranslate;\n var disableParentSwiper = true;\n var resistanceRatio = params.resistanceRatio;\n\n if (params.touchReleaseOnEdges) {\n resistanceRatio = 0;\n }\n\n if (diff > 0 && data.currentTranslate > swiper.minTranslate()) {\n disableParentSwiper = false;\n if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + Math.pow(-swiper.minTranslate() + data.startTranslate + diff, resistanceRatio);\n } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {\n disableParentSwiper = false;\n if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - Math.pow(swiper.maxTranslate() - data.startTranslate - diff, resistanceRatio);\n }\n\n if (disableParentSwiper) {\n e.preventedByNestedSwiper = true;\n } // Directions locks\n\n\n if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n }\n\n if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n } // Threshold\n\n\n if (params.threshold > 0) {\n if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {\n if (!data.allowThresholdMove) {\n data.allowThresholdMove = true;\n touches.startX = touches.currentX;\n touches.startY = touches.currentY;\n data.currentTranslate = data.startTranslate;\n touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;\n return;\n }\n } else {\n data.currentTranslate = data.startTranslate;\n return;\n }\n }\n\n if (!params.followFinger || params.cssMode) return; // Update active index in free mode\n\n if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) {\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n if (params.freeMode) {\n // Velocity\n if (data.velocities.length === 0) {\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],\n time: data.touchStartTime\n });\n }\n\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],\n time: now()\n });\n } // Update progress\n\n\n swiper.updateProgress(data.currentTranslate); // Update translate\n\n swiper.setTranslate(data.currentTranslate);\n }\n\n function onTouchEnd(event) {\n var swiper = this;\n var data = swiper.touchEventsData;\n var params = swiper.params,\n touches = swiper.touches,\n rtl = swiper.rtlTranslate,\n $wrapperEl = swiper.$wrapperEl,\n slidesGrid = swiper.slidesGrid,\n snapGrid = swiper.snapGrid;\n var e = event;\n if (e.originalEvent) e = e.originalEvent;\n\n if (data.allowTouchCallbacks) {\n swiper.emit('touchEnd', e);\n }\n\n data.allowTouchCallbacks = false;\n\n if (!data.isTouched) {\n if (data.isMoved && params.grabCursor) {\n swiper.setGrabCursor(false);\n }\n\n data.isMoved = false;\n data.startMoving = false;\n return;\n } // Return Grab Cursor\n\n\n if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(false);\n } // Time diff\n\n\n var touchEndTime = now();\n var timeDiff = touchEndTime - data.touchStartTime;
166 // Tap, doubleTap, Click\n\n if (swiper.allowClick) {\n swiper.updateClickedSlide(e);\n swiper.emit('tap click', e);\n\n if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {\n swiper.emit('doubleTap doubleClick', e);\n }\n }\n\n data.lastClickTime = now();\n nextTick(function () {\n if (!swiper.destroyed) swiper.allowClick = true;\n });\n\n if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n return;\n }\n\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n var currentPos;\n\n if (params.followFinger) {\n currentPos = rtl ? swiper.translate : -swiper.translate;\n } else {\n currentPos = -data.currentTranslate;\n }\n\n if (params.cssMode) {\n return;\n }\n\n if (params.freeMode) {\n if (currentPos < -swi
166per.minTranslate()) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n if (currentPos > -swiper.maxTranslate()) {\n if (swiper.slides.length < snapGrid.length) {\n swiper.slideTo(snapGrid.length - 1);\n } else {\n swiper.slideTo(swiper.slides.length - 1);\n }\n\n return;\n }\n\n if (params.freeModeMomentum) {\n if (data.velocities.length > 1) {\n var lastMoveEvent = data.velocities.pop();\n var velocityEvent = data.velocities.pop();\n var distance = lastMoveEvent.position - velocityEvent.position;\n var time = lastMoveEvent.time - velocityEvent.time;\n swiper.velocity = distance / time;\n swiper.velocity /= 2;\n\n if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) {\n swiper.velocity = 0;\n } // this implies that the user stopped moving a finger then released.\n // There would be no events with distance zero, so the last event is stale.\n\n\n if (time > 150 || now() - lastMoveEvent.time > 300) {\n swiper.velocity = 0;\n }\n } else {\n swiper.velocity = 0;\n }\n\n swiper.velocity *= params.freeModeMomentumVelocityRatio;\n data.velocities.length = 0;\n var momentumDuration = 1000 * params.freeModeMomentumRatio;\n var momentumDistance = swiper.velocity * momentumDuration;\n var newPosition = swiper.translate + momentumDistance;\n if (rtl) newPosition = -newPosition;\n var doBounce = false;\n var afterBouncePosition;\n var bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio;\n var needsLoopFix;\n\n if (newPosition < swiper.maxTranslate()) {\n if (params.freeModeMomentumBounce) {\n if (newPosition + swiper.maxTranslate() < -bounceAmount) {\n newPosition = swiper.maxTranslate() - bounceAmount;\n }\n\n afterBouncePosition = swiper.maxTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.maxTranslate();\n }\n\n if (params.loop && params.centeredSlides) needsLoopFix = true;\n } else if (newPosition > swiper.minTranslate()) {\n if (params.freeModeMomentumBounce) {\n if (newPosition - swiper.minTranslate() > bounceAmount) {\n newPosition = swiper.minTranslate() + bounceAmount;\n }\n\n afterBouncePosition = swiper.minTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.minTranslate();\n }\n\n if (params.loop && params.centeredSlides) needsLoopFix = true;\n } else if (params.freeModeSticky) {\n var nextSlide;\n\n for (var j = 0; j < snapGrid.length; j += 1) {\n if (snapGrid[j] > -newPosition) {\n nextSlide = j;\n break;\n }\n }\n\n if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {\n newPosition = snapGrid[nextSlide];\n } else {\n newPosition = snapGrid[nextSlide - 1];\n }\n\n newPosition = -newPosition;\n }\n\n if (needsLoopFix) {\n swiper.once('transitionEnd', function () {\n swiper.loopFix();\n });\n } // Fix duration\n\n\n if (swiper.velocity !== 0) {\n if (rtl) {\n momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);\n } else {\n momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);\n }\n\n if (params.freeModeSticky) {\n // If freeModeSticky is active and the user ends a swipe with a slow-velocity\n // event, then durations can be 20+ seconds to slide one (or zero!) slides.\n // It's easy to see this when simulating touch with mouse events. To fix this,\n // limit single-slide swipes to the default slide duration. This also has the\n // nice side effect of matching slide speed if the user stopped moving before\n // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.\n // For faster swipes, also apply limits (albeit higher ones).\n var moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);\n var currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];\n\n if (moveDistance < currentSlideSize) {\n momentumDuration = params.speed;\n } else if (moveDistance < 2 * currentSlideSize) {\n momentumDuration = params.speed * 1.5;\n } else {\n momentumDuration = params.speed * 2.5;\n }\n }\n } else if (params.freeModeSticky) {\n swiper.slideToClosest();\n return;\n }\n\n if (params.freeModeMomentumBounce && doBounce) {\n swiper.updateProgress(afterBouncePosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n swiper.animating = true;\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;\n swiper.emit('momentumBounce');\n swiper.setTransition(params.speed);\n setTimeout(function () {\n swiper.setTranslate(afterBouncePosition);\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed) return;\n swiper.transitionEnd();\n });\n }, 0);\n });\n } else if (swiper.velocity) {\n swiper.updateProgress(newPosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n\n if (!swiper.animating) {\n swiper.animating = true;\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed) return;\n swiper.transitionEnd();\n });\n }\n } else {\n swiper.updateProgress(newPosition);\n }\n\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n } else if (params.freeModeSticky) {\n swiper.slideToClosest();\n return;\n }\n\n if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) {\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n return;\n } // Find current slide\n\n\n var stopIndex = 0;\n var groupSize = swiper.slidesSizesGrid[0];\n\n for (var i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {\n var _increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;\n\n if (typeof slidesGrid[i + _increment] !== 'undefined') {\n if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + _increment]) {\n stopIndex = i;\n groupSize = slidesGrid[i + _increment] - slidesGrid[i];\n }\n } else if (currentPos >= slidesGrid[i]) {\n stopIndex = i;\n groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];\n }\n } // Find current slide size\n\n\n var ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;\n var increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;\n\n if (timeDiff > params.longSwipesMs) {\n // Long touches\n if (!params.longSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n if (swiper.swipeDirection === 'next') {\n if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + increment);else swiper.slideTo(stopIndex);\n }\n\n if (swiper.swipeDirection === 'prev') {\n if (ratio > 1 - params.longSwipesRatio) swiper.slideTo(stopIndex + increment);else swiper.slideTo(stopIndex);\n }\n } else {\n // Short swipes\n if (!params.shortSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n var isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);\n\n if (!isNavButtonTarget) {\n if (swiper.swipeDirection === 'next') {\n swiper.slideTo(stopIndex + increment);\n }\n\n if (swiper.swipeDirection === 'prev') {\n swiper.slideTo(stopIndex);\n }\n } else if (e.target === swiper.navigation.nextEl) {\n swiper.slideTo(stopIndex + increment);\n } else {\n swiper.slideTo(stopIndex);\n }\n }\n }\n\n function onResize() {\n var swiper = this;\n var params = swiper.params,\n el = swiper.el;\n if (el && el.offsetWidth === 0) return;
166 // Breakpoints\n\n if (params.breakpoints) {\n swiper.setBreakpoint();\n } // Save locks\n\n\n var allowSlideNext = swiper.allowSlideNext,\n allowSlidePrev = swiper.allowSlidePrev,\n snapGrid = swiper.snapGrid; // Disable locks on resize\n\n swiper.allowSlideNext = true;\n swiper.allowSlidePrev = true;\n swiper.updateSize();\n swiper.updateSlides();\n swiper.updateSlidesClasses();\n\n if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {\n swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n\n if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {\n swiper.autoplay.run();\n } // Return locks after resize\n\n\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n\n if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n }\n\n function onClick(e) {\n var swiper = this;\n\n if (!swiper.allowClick) {\n if (swiper.params.preventClicks) e.preventDefault();\n\n if (swiper.params.preventClicksPropagation && swiper.animating) {\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n }\n\n function onScroll() {\n var swiper = this;\n var wrapperEl = swiper.wrapperEl,\n rtlTranslate = swiper.rtlTranslate;\n swiper.previousTranslate = swiper.translate;\n\n if (swiper.isHorizontal()) {\n if (rtlTranslate) {\n swiper.translate = wrapperEl.scrollWidth - wrapperEl.offsetWidth - wrapperEl.scrollLeft;\n } else {\n swiper.translate = -wrapperEl.scrollLeft;\n }\n } else {\n swiper.translate = -wrapperEl.scrollTop;\n } // eslint-disable-next-line\n\n\n if (swiper.translate === -0) swiper.translate = 0;\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n var newProgress;\n var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n\n if (translatesDiff === 0) {\n newProgress = 0;\n } else {\n newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;\n }\n\n if (newProgress !== swiper.progress) {\n swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);\n }\n\n swiper.emit('setTranslate', swiper.translate, false);\n }\n\n var dummyEventAttached = false;\n\n function dummyEventListener() {}\n\n function attachEvents() {\n var swiper = this;\n var document = getDocument();\n var params = swiper.params,\n touchEvents = swiper.touchEvents,\n el = swiper.el,\n wrapperEl = swiper.wrapperEl,\n device = swiper.device,\n support = swiper.support;\n swiper.onTouchStart = onTouchStart.bind(swiper);\n swiper.onTouchMove = onTouchMove.bind(swiper);\n swiper.onTouchEnd = onTouchEnd.bind(swiper);\n\n if (params.cssMode) {\n swiper.onScroll = onScroll.bind(swiper);\n }\n\n swiper.onClick = onClick.bind(swiper);\n var capture = !!params.nested; // Touch Events\n\n if (!support.touch && support.pointerEvents) {\n el.addEventListener(touchEvents.start, swiper.onTouchStart, false);\n document.addEventListener(touchEvents.move, swiper.onTouchMove, capture);\n document.addEventListener(touchEvents.end, swiper.onTouchEnd, false);\n } else {\n if (support.touch) {\n var passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n el.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);\n el.addEventListener(touchEvents.move, swiper.onTouchMove, support.passiveListener ? {\n passive: false,\n capture: capture\n } : capture);\n el.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);\n\n if (touchEvents.cancel) {\n el.addEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);\n }\n\n if (!dummyEventAttached) {\n document.addEventListener('touchstart', dummyEventListener);\n dummyEventAttached = true;\n }\n }\n\n if (params.simulateTouch && !device.ios && !device.android || params.simulateTouch && !support.touch && device.ios) {\
166n el.addEventListener('mousedown', swiper.onTouchStart, false);\n document.addEventListener('mousemove', swiper.onTouchMove, capture);\n document.addEventListener('mouseup', swiper.onTouchEnd, false);\n }\n } // Prevent Links Clicks\n\n\n if (params.preventClicks || params.preventClicksPropagation) {\n el.addEventListener('click', swiper.onClick, true);\n }\n\n if (params.cssMode) {\n wrapperEl.addEventListener('scroll', swiper.onScroll);\n } // Resize handler\n\n\n if (params.updateOnWindowResize) {\n swiper.on(device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);\n } else {\n swiper.on('observerUpdate', onResize, true);\n }\n }\n\n function detachEvents() {\n var swiper = this;\n var document = getDocument();\n var params = swiper.params,\n touchEvents = swiper.touchEvents,\n el = swiper.el,\n wrapperEl = swiper.wrapperEl,\n device = swiper.device,\n support = swiper.support;\n var capture = !!params.nested; // Touch Events\n\n if (!support.touch && support.pointerEvents) {\n el.removeEventListener(touchEvents.start, swiper.onTouchStart, false);\n document.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);\n document.removeEventListener(touchEvents.end, swiper.onTouchEnd, false);\n } else {\n if (support.touch) {\n var passiveListener = touchEvents.start === 'onTouchStart' && support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n el.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);\n el.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);\n el.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);\n\n if (touchEvents.cancel) {\n el.removeEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);\n }\n }\n\n if (params.simulateTouch && !device.ios && !device.android || params.simulateTouch && !support.touch && device.ios) {\n el.removeEventListener('mousedown', swiper.onTouchStart, false);\n document.removeEventListener('mousemove', swiper.onTouchMove, capture);\n document.removeEventListener('mouseup', swiper.onTouchEnd, false);\n }\n } // Prevent Links Clicks\n\n\n if (params.preventClicks || params.preventClicksPropagation) {\n el.removeEventListener('click', swiper.onClick, true);\n }\n\n if (params.cssMode) {\n wrapperEl.removeEventListener('scroll', swiper.onScroll);\n } // Resize handler\n\n\n swiper.off(device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize);\n }\n\n var events = {\n attachEvents: attachEvents,\n detachEvents: detachEvents\n };\n\n function setBreakpoint() {\n var swiper = this;\n var activeIndex = swiper.activeIndex,\n initialized = swiper.initialized,\n _swiper$loopedSlides = swiper.loopedSlides,\n loopedSlides = _swiper$loopedSlides === void 0 ? 0 : _swiper$loopedSlides,\n params = swiper.params,\n $el = swiper.$el;\n var breakpoints = params.breakpoints;\n if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return; // Get breakpoint for window width and update parameters\n\n var breakpoint = swiper.getBreakpoint(breakpoints);\n\n if (breakpoint && swiper.currentBreakpoint !== breakpoint) {\n var breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;\n\n if (breakpointOnlyParams) {\n ['slidesPerView', 'spaceBetween', 'slidesPerGroup', 'slidesPerGroupSkip', 'slidesPerColumn'].forEach(function (param) {\n var paramValue = breakpointOnlyParams[param];\n if (typeof paramValue === 'undefined') return;\n\n if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) {\n breakpointOnlyParams[param] = 'auto';\n } else if (param === 'slidesPerView') {\n breakpointOnlyParams[param] = parseFloat(paramValue);\n } else {\n breakpointOnlyParams[param] = parseInt(paramValue, 10);\n }\n });\n }\n\n var breakpointParams = breakpointOnlyParams || swiper.originalParams;\n var wasMultiRow = params.slidesPerColumn > 1;\n var isMultiRow = breakpointParams.slidesPerColumn > 1;\n\n if (wasMultiRow && !isMultiRow) {\n $el.removeClass(params.containerModifierClass + \"multirow \" + params.containerModifierClass + \"multirow-column\");\n swiper.emitContainerClasses();\n } else if (!wasMultiRow && isMultiRow) {\n $el.addClass(params.containerModifierClass + \"multirow\");\n\n if (breakpointParams.slidesPerColumnFill === 'column') {\n $el.addClass(params.containerModifierClass + \"multirow-column\");\n }\n\n swiper.emitContainerClasses();\n }\n\n var directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;\n var needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);\n\n if (directionChanged && initialized) {\n swiper.changeDirection();\n }\n\n extend$1(swiper.params, breakpointParams);\n extend$1(swiper, {\n allowTouchMove: swiper.params.allowTouchMove,\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev\
166n });\n swiper.currentBreakpoint = breakpoint;\n\n if (needsReLoop && initialized) {\n swiper.loopDestroy();\n swiper.loopCreate();\n swiper.updateSlides();\n swiper.slideTo(activeIndex - loopedSlides + swiper.loopedSlides, 0, false);\n }\n\n swiper.emit('breakpoint', breakpointParams);\n }\n }\n\n function getBreakpoints(breakpoints) {\n var window = getWindow(); // Get breakpoint for window width\n\n if (!breakpoints) return undefined;\n var breakpoint = false;\n var points = Object.keys(breakpoints).map(function (point) {\n if (typeof point === 'string' && point.indexOf('@') === 0) {\n var minRatio = parseFloat(point.substr(1));\n var value = window.innerHeight * minRatio;\n return {\n value: value,\n point: point\n };\n }\n\n return {\n value: point,\n point: point\n };\n });\n points.sort(function (a, b) {\n return parseInt(a.value, 10) - parseInt(b.value, 10);\n });\n\n for (var i = 0; i < points.length; i += 1) {\n var _points$i = points[i],\n point = _points$i.point,\n value = _points$i.value;\n\n if (value <= window.innerWidth) {\n breakpoint = point;\n }\n }\n\n return breakpoint || 'max';\n }\n\n var breakpoints = {\n setBreakpoint: setBreakpoint,\n getBreakpoint: getBreakpoints\n };\n\n function addClasses() {\n var swiper = this;\n var classNames = swiper.classNames,\n params = swiper.params,\n rtl = swiper.rtl,\n $el = swiper.$el,\n device = swiper.device;\n var suffixes = [];\n suffixes.push('initialized');\n suffixes.push(params.direction);\n\n if (params.freeMode) {\n suffixes.push('free-mode');\n }\n\n if (params.autoHeight) {\n suffixes.push('autoheight');\n }\n\n if (rtl) {\n suffixes.push('rtl');\n }\n\n if (params.slidesPerColumn > 1) {\n suffixes.push('multirow');\n\n if (params.slidesPerColumnFill === 'column') {\n suffixes.push('multirow-column');\n }\n }\n\n if (device.android) {\n suffixes.push('android');\n }\n\n if (device.ios) {\n suffixes.push('ios');\n }\n\n if (params.cssMode) {\n suffixes.push('css-mode');\n }\n\n suffixes.forEach(function (suffix) {\n classNames.push(params.containerModifierClass + suffix);\n });\n $el.addClass(classNames.join(' '));\n swiper.emitContainerClasses();\n }\n\n function removeClasses() {\n var swiper = this;\n var $el = swiper.$el,\n classNames = swiper.classNames;\n $el.removeClass(classNames.join(' '));\n swiper.emitContainerClasses();\n }\n\n var classes = {\n addClasses: addClasses,\n removeClasses: removeClasses\n };\n\n function loadImage(imageEl, src, srcset, sizes, checkForComplete, callback) {\n var window = getWindow();\n var image;\n\n function onReady() {\n if (callback) callback();\n }\n\n var isPicture = $(imageEl).parent('picture')[0];\n\n if (!isPicture && (!imageEl.complete || !checkForComplete)) {\n if (src) {\n image = new window.Image();\n image.onload = onReady;\n image.onerror = onReady;\n\n if (sizes) {\n image.sizes = sizes;\n }\n\n if (srcset) {\n image.srcset = srcset;\n }\n\n if (src) {\n image.src = src;\n }\n } else {\n onReady();\n }\n } else {\n // image already loaded...\n onReady();\n }\n }\n\n function preloadImages() {\n var swiper = this;\n swiper.imagesToLoad = swiper.$el.find('img');\n\n function onReady() {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return;\n if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1;\n\n if (swiper.imagesLoaded === swiper.imagesToLoad.length) {\n if (swiper.params.updateOnImagesReady) swiper.update();\n swiper.emit('imagesReady');\n }\n }\n\n for (var i = 0; i < swiper.imagesToLoad.length; i += 1) {\n var imageEl = swiper.imagesToLoad[i];\n swiper.loadImage(imageEl, imageEl.currentSrc || imageEl.getAttribute('src'), imageEl.srcset || imageEl.getAttribute('srcset'), imageEl.sizes || imageEl.getAttribute('sizes'), true, onReady);\n }\n }\n\n var images = {\n loadImage: loadImage,\n preloadImages: preloadImages\n };\n\n function checkOverflow() {\n var swiper = this;\n var params = swiper.params;
166\n var wasLocked = swiper.isLocked;\n var lastSlidePosition = swiper.slides.length > 0 && params.slidesOffsetBefore + params.spaceBetween * (swiper.slides.length - 1) + swiper.slides[0].offsetWidth * swiper.slides.length;\n\n if (params.slidesOffsetBefore && params.slidesOffsetAfter && lastSlidePosition) {\n swiper.isLocked = lastSlidePosition <= swiper.size;\n } else {\n swiper.isLocked = swiper.snapGrid.length === 1;\n }\n\n swiper.allowSlideNext = !swiper.isLocked;\n swiper.allowSlidePrev = !swiper.isLocked; // events\n\n if (wasLocked !== swiper.isLocked) swiper.emit(swiper.isLocked ? 'lock' : 'unlock');\n\n if (wasLocked && wasLocked !== swiper.isLocked) {\n swiper.isEnd = false;\n if (swiper.navigation) swiper.navigation.update();\n }\n }\n\n var checkOverflow$1 = {\n checkOverflow: checkOverflow\n };\n\n var defaults = {\n init: true,\n direction: 'horizontal',\n touchEventsTarget: 'container',\n initialSlide: 0,\n speed: 300,\n cssMode: false,\n updateOnWindowResize: true,\n // Overrides\n width: null,\n height: null,\n //\n preventInteractionOnTransition: false,\n // ssr\n userAgent: null,\n url: null,\n // To support iOS's swipe-to-go-back gesture (when being used in-app).\n edgeSwipeDetection: false,\n edgeSwipeThreshold: 20,\n // Free mode\n freeMode: false,\n freeModeMomentum: true,\n freeModeMomentumRatio: 1,\n freeModeMomentumBounce: true,\n freeModeMomentumBounceRatio: 1,\n freeModeMomentumVelocityRatio: 1,\n freeModeSticky: false,\n freeModeMinimumVelocity: 0.02,\n // Autoheight\n autoHeight: false,\n // Set wrapper width\n setWrapperSize: false,\n // Virtual Translate\n virtualTranslate: false,\n // Effects\n effect: 'slide',\n // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n // Breakp
166oints\n breakpoints: undefined,\n // Slides grid\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerColumnFill: 'column',\n slidesPerGroup: 1,\n slidesPerGroupSkip: 0,\n centeredSlides: false,\n centeredSlidesBounds: false,\n slidesOffsetBefore: 0,\n // in px\n slidesOffsetAfter: 0,\n // in px\n normalizeSlideIndex: true,\n centerInsufficientSlides: false,\n // Disable swiper and hide navigation when container not overflow\n watchOverflow: false,\n // Round length\n roundLengths: false,\n // Touches\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n allowTouchMove: true,\n threshold: 0,\n touchMoveStopPropagation: false,\n touchStartPreventDefault: true,\n touchStartForcePreventDefault: false,\n touchReleaseOnEdges: false,\n // Unique Navigation Elements\n uniqueNavElements: true,\n // Resistance\n resistance: true,\n resistanceRatio: 0.85,\n // Progress\n watchSlidesProgress: false,\n watchSlidesVisibility: false,\n // Cursor\n grabCursor: false,\n // Clicks\n preventClicks: true,\n preventClicksPropagation: true,\n slideToClickedSlide: false,\n // Images\n preloadImages: true,\n updateOnImagesReady: true,\n // loop\n loop: false,\n loopAdditionalSlides: 0,\n loopedSlides: null,\n loopFillGroupWithBlank: false,\n loopPreventsSlide: true,\n // Swiping/no swiping\n allowSlidePrev: true,\n allowSlideNext: true,\n swipeHandler: null,\n // '.swipe-handler',\n noSwiping: true,\n noSwipingClass: 'swiper-no-swiping',\n noSwipingSelector: null,\n // Passive Listeners\n passiveListeners: true,\n // NS\n containerModifierClass: 'swiper-container-',\n // NEW\n slideClass: 'swiper-slide',\n slideBlankClass: 'swiper-slide-invisible-blank',\n slideActiveClass: 'swiper-slide-active',\n slideDuplicateActiveClass: 'swiper-slide-duplicate-active',\n slideVisibleClass: 'swiper-slide-visible',\n slideDuplicateClass: 'swiper-slide-duplicate',\n slideNextClass: 'swiper-slide-next',\n slideDuplicateNextClass: 'swiper-slide-duplicate-next',\n slidePrevClass: 'swiper-slide-prev',\n slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',\n wrapperClass: 'swiper-wrapper',\n // Callbacks\n runCallbacksOnInit: true,\n // Internals\n _emitClasses: false\n };\n\n var prototypes = {\n modular: modular,\n eventsEmitter: eventsEmitter,\n update: update,\n translate: translate,\n transition: transition$1,\n slide: slide,\n loop: loop,\n grabCursor: grabCursor,\n manipulation: manipulation,\n events: events,\n breakpoints: breakpoints,\n checkOverflow: checkOverflow$1,\n classes: classes,\n images: images\n };\n var extendedDefaults = {};\n\n var Swiper = /*#__PURE__*/function () {\n function Swiper() {\n var el;\n var params;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n if (args.length === 1 && args[0].constructor && args[0].constructor === Object) {\n params = args[0];\n } else {\n el = args[0];\n params = args[1];\n }\n\n if (!params) params = {};\n params = extend$1({}, params);\n if (el && !params.el) params.el = el; // Swiper Instance\n\n var swiper = this;
166\n swiper.support = getSupport();\n swiper.device = getDevice({\n userAgent: params.userAgent\n });\n swiper.browser = getBrowser();\n swiper.eventsListeners = {};\n swiper.eventsAnyListeners = [];\n Object.keys(prototypes).forEach(function (prototypeGroup) {\n Object.keys(prototypes[prototypeGroup]).forEach(function (protoMethod) {\n if (!Swiper.prototype[protoMethod]) {\n Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];\n }\n });\n });\n\n if (typeof swiper.modules === 'undefined') {\n swiper.modules = {};\n }\n\n Object.keys(swiper.modules).forEach(function (moduleName) {\n var module = swiper.modules[moduleName];\n\n if (module.params) {\n var moduleParamName = Object.keys(module.params)[0];\n var moduleParams = module.params[moduleParamName];\n if (typeof moduleParams !== 'object' || moduleParams === null) return;\n if (!(moduleParamName in params && 'enabled' in moduleParams)) return;\n\n if (params[moduleParamName] === true) {\n params[moduleParamName] = {\n enabled: true\n };\n }\n\n if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {\n params[moduleParamName].enabled = true;\n }\n\n if (!params[moduleParamName]) params[moduleParamName] = {\n enabled: false\n };\n }\n }); // Extend defaults with modules params\n\n var swiperParams = extend$1({}, defaults);\n swiper.useParams(swiperParams); // Extend defaults with passed params\n\n swiper.params = extend$1({}, swiperParams, extendedDefaults, params);\n swiper.originalParams = extend$1({}, swiper.params);\n swiper.passedParams = extend$1({}, params); // add event listeners\n\n if (swiper.params && swiper.params.on) {\n Object.keys(swiper.params.on).forEac
166h(function (eventName) {\n swiper.on(eventName, swiper.params.on[eventName]);\n });\n } // Save Dom lib\n\n\n swiper.$ = $; // Find el\n\n var $el = $(swiper.params.el);\n el = $el[0];\n\n if (!el) {\n return undefined;\n }\n\n if ($el.length > 1) {\n var swipers = [];\n $el.each(function (containerEl) {\n var newParams = extend$1({}, params, {\n el: containerEl\n });\n swipers.push(new Swiper(newParams));\n });\n return swipers;\n }\n\n el.swiper = swiper; // Find Wrapper\n\n var $wrapperEl;\n\n if (el && el.shadowRoot && el.shadowRoot.querySelector) {\n $wrapperEl = $(el.shadowRoot.querySelector(\".\" + swiper.params.wrapperClass)); // Children needs to return slot items\n\n $wrapperEl.children = function (options) {\n return $el.children(options);\n };\n } else {\n $wrapperEl = $el.children(\".\" + swiper.params.wrapperClass);\n } // Extend Swiper\n\n\n extend$1(swiper, {\n $el: $el,\n el: el,\n $wrapperEl: $wrapperEl,\n wrapperEl: $wrapperEl[0],\n // Classes\n classNames: [],\n // Slides\n slides: $(),\n slidesGrid: [],\n snapGrid: [],\n slidesSizesGrid: [],\n // isDirection\n isHorizontal: function isHorizontal() {\n return swiper.params.direction === 'horizontal';\n },\n isVertical: function isVertical() {\n return swiper.params.direction === 'vertical';\n },\n // RTL\n rtl: el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl',\n rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),\n wrongRTL: $wrapperEl.css('display') === '-webkit-box',\n // Indexes\n activeIndex: 0,\n realIndex: 0,\n //\n isBeginning: true,\n isEnd: false,\n // Props\n translate: 0,\n previousTranslate: 0,\n progress: 0,\n velocity: 0,\n animating: false,\n // Locks\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev,\n // Touch Events\n touchEvents: function touchEvents() {\n var touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];\n var desktop = ['mousedown', 'mousemove', 'mouseup'];\n\n if (swiper.support.pointerEvents) {\n desktop = ['pointerdown', 'pointermove', 'pointerup'];\n }\n\n swiper.touchEventsTouch = {\n start: touch[0],\n move: touch[1],\n end: touch[2],\n cancel: touch[3]\n };\n swiper.touchEventsDesktop = {\n start: desktop[0],\n move: desktop[1],\n end: desktop[2]\n };\n return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;\n }(),\n touchEventsData: {\n isTouched: undefined,\n isMoved: undefined,\n allowTouchCallbacks: undefined,\n touchStartTime: undefined,\n isScrolling: undefined,\n currentTranslate: undefined,\n startTranslate: undefined,\n allowThresholdMove: undefined,\n // Form elements to match\n formElements: 'input, select, option, textarea, button, video, label',\n // Last click time\n lastClickTime: now(),\n clickTimeout: undefined,\n // Velocities\n velocities: [],\n allowMomentumBounce: undefined,\n isTouchEvent: undefined,\n startMoving: undefined\n },\n // Clicks\n allowClick: true,\n // Touches\n allowTouchMove: swiper.params.allowTouchMove,\n touches: {\n startX: 0,\n startY: 0,\n currentX: 0,\n currentY: 0,\n diff: 0\n },\n // Images\n imagesToLoad: [],\n imagesLoaded: 0\n }); // Install Modules\n\n swiper.useModules();\n swiper.emit('_swiper'); // Init\n\n if (swiper.params.init) {\n swiper.init();\n } // Return app instance\n\n\n return swiper;\n }\n\n var _proto = Swiper.prototype;\n\n _proto.emitContainerClasses = function emitContainerClasses() {\n var swiper = this;\n if (!swiper.params._emitClasses || !swiper.el) return;\n var classes = swiper.el.className.split(' ').filter(function (className) {\n return className.indexOf('swiper-container') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;\n });\n swiper.emit('_containerClasses', classes.join(' '));\n };\n\n _proto.emitSlidesClasses = function emitSlidesClasses() {\n var swiper = this;\n if (!swiper.params._emitClasses || !swiper.el) return;\n swiper.slides.each(function (slideEl) {\n var classes = slideEl.className.split(' ').filter(function (className) {\n return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;\n });\n swiper.emit('_slideClass', slideEl, classes.join(' '));\n });\n };\n\n _proto.slidesPerViewDynamic = function slidesPerViewDynamic() {\n var swiper = this;\n var params = swiper.params,\n slides = swiper.slides,\n slidesGrid = swiper.slidesGrid,\n swiperSize = swiper.size,\n activeIndex = swiper.activeIndex;\n var spv = 1;\n\n if (params.centeredSlides) {\n var slideSize = slides[activeIndex].swiperSlideSize;\n var breakLoop;\n\n for (var i = activeIndex + 1; i < slides.length; i += 1) {\n if (slides[i] && !breakLoop) {\n slideSize += slides[i].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) breakLoop = true;\n }\n }\n\n for (var _i = activeIndex - 1; _i >= 0; _i -= 1) {\n if (slides[_i] && !breakLoop) {\n slideSize += slides[_i].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) breakLoop = true;\n }\n }\n } else {\n for (var _i2 = activeIndex + 1; _i2 < slides.length; _i2 += 1) {\n if (slidesGrid[_i2] - slidesGrid[activeIndex] < swiperSize) {\n spv += 1;\n }\n }\n }\n\n return spv;\n };
166\n\n _proto.update = function update() {\n var swiper = this;\n if (!swiper || swiper.destroyed) return;\n var snapGrid = swiper.snapGrid,\n params = swiper.params; // Breakpoints\n\n if (params.breakpoints) {\n swiper.setBreakpoint();\n }\n\n swiper.updateSize();\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n\n function setTranslate() {\n var translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;\n var newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());\n swiper.setTranslate(newTranslate);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n var translated;\n\n if (swiper.params.freeMode) {\n setTranslate();\n\n if (swiper.params.autoHeight) {\n swiper.updateAutoHeight();\n }\n } else {\n if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {\n translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n translated = swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n\n if (!translated) {\n setTranslate();\n }\n }\n\n if (params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n\n swiper.emit('update');\n };\n\n _proto.changeDirection = function changeDirection(newDirection, needUpdate) {\n if (needUpdate === void 0) {\n needUpdate = true;\n }\n\n var swiper = this;\n var currentDirection = swiper.params.direction;\n\n if (!newDirection) {\n // eslint-disable-next-line\n newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';\n }\n\n if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {\n return swiper;\n }\n\n swiper.$el.removeClass(\"\" + swiper.params.containerModifierClass + currentDirection).addClass(\"\" + swiper.params.containerModifierClass + newDirection);\n swiper.emitContainerClasses();\n swiper.params.direction = newDirection;\n swiper.slides.each(function (slideEl) {\n if (newDirection === 'vertical') {\n slideEl.style.width = '';\n } else {\n slideEl.style.height = '';\n }\n });\n swiper.emit('changeDirection');\n if (needUpdate) swiper.update();\n return swiper;\n };\n\n _proto.init = function init() {\n var swiper = this;\n if (swiper.initialized) return;\n swiper.emit('beforeInit'); // Set breakpoint\n\n if (swiper.params.breakpoints) {\n swiper.setBreakpoint();\n } // Add Classes\n\n\n swiper.addClasses(); // Create loop\n\n if (swiper.params.loop) {\n swiper.loopCreate();\n } // Update size\n\n\n swiper.updateSize(); // Update slides\n\n swiper.updateSlides();\n\n if (swiper.params.watchOverflow) {\n swiper.checkOverflow();\n } // Set Grab Cursor\n\n\n if (swiper.params.grabCursor) {\n swiper.setGrabCursor();\n }\n\n if (swiper.params.preloadImages) {\n swiper.preloadImages();\n } // Slide To Initial Slide\n\n\n if (swiper.params.loop) {\n swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit);\n } else {\n swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit);\n } // Attach events\n\n\n swiper.attachEvents(); // Init Flag\n\n swiper.initialized = true; // Emit\n\n swiper.emit('init');\n };\n\n _proto.destroy = function destroy(deleteInstance, cleanStyles) {\n if (deleteInstance === void 0) {\n deleteInstance = true;\n }\n\n if (cleanStyles === void 0) {\n cleanStyles = true;\n }\n\n var swiper = this;\n var params = swiper.params,\n $el = swiper.$el,\n $wrapperEl = swiper.$wrapperEl,\n slides = swiper.slides;\n\n if (typeof swiper.params === 'undefined' || swiper.destroyed) {\n return null;\n }\n\n swiper.emit('beforeDestroy'); // Init Flag\n\n swiper.initialized = false; // Detach events\n\n swiper.detachEvents(); // Destroy loop\n\n if (params.loop) {\n swiper.loopDestroy();\n } // Cleanup styles\n\n\n if (cleanStyles) {\n swiper.removeClasses();\n $el.removeAttr('style');\n $wrapperEl.removeAttr('style');\n\n if (slides && slides.length) {\n slides.removeClass([params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-slide-index');\n }\n }\n\n swiper.emit('destroy'); // Detach emitter events\n\n Object.keys(swiper.eventsListeners).forEac
166h(function (eventName) {\n swiper.off(eventName);\n });\n\n if (deleteInstance !== false) {\n swiper.$el[0].swiper = null;\n deleteProps(swiper);\n }\n\n swiper.destroyed = true;\n return null;\n };\n\n Swiper.extendDefaults = function extendDefaults(newDefaults) {\n extend$1(extendedDefaults, newDefaults);\n };\n\n Swiper.installModule = function installModule(module) {\n if (!Swiper.prototype.modules) Swiper.prototype.modules = {};\n var name = module.name || Object.keys(Swiper.prototype.modules).length + \"_\" + now();\n Swiper.prototype.modules[name] = module;\n };\n\n Swiper.use = function use(module) {\n if (Array.isArray(module)) {\n module.forEach(function (m) {\n return Swiper.installModule(m);\n });\n return Swiper;\n }\n\n Swiper.installModule(module);\n return Swiper;\n };\n\n _createClass(Swiper, null, [{\n key: \"extendedDefaults\",\n get: function get() {\n return extendedDefaults;\n }\n }, {\n key: \"defaults\",\n get: function get() {\n return defaults;\n }\n }]);\n\n return Swiper;\n }();\n\n Swiper.use([Resize, Observer$1]);\n\n var Virtual = {\n update: function update(force) {\n var swiper = this;\n var _swiper$params = swiper.params,\n slidesPerView = _swiper$params.slidesPerView,\n slidesPerGroup = _swiper$params.slidesPerGroup,\n centeredSlides = _swiper$params.centeredSlides;\n var _swiper$params$virtua = swiper.params.virtual,\n addSlidesBefore = _swiper$params$virtua.addSlidesBefore,\n addSlidesAfter = _swiper$params$virtua.addSlidesAfter;\n var _swiper$virtual = swiper.virtual,\n previousFrom = _swiper$virtual.from,\n previousTo = _swiper$virtual.to,\n slides = _swiper$virtual.slides,\n previousSlidesGrid = _swiper$virtual.slidesGrid,\n renderSlide = _swiper$virtual.renderSlide,\n previousOffset = _swiper$virtual.offset;\n swiper.updateActiveIndex();\n var activeIndex = swiper.activeIndex || 0;\n var offsetProp;\n if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';\n var slidesAfter;\n var slidesBefore;\n\n if (centeredSlides) {\n slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;\n slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;\n } else {\n slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;\n slidesBefore = slidesPerGroup + addSlidesBefore;\n }\n\n var from = Math.max((activeIndex || 0) - slidesBefore, 0);\n var to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);\n var offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);\n extend$1(swiper.virtual, {\n from: from,\n to: to,\n offset: offset,\n slidesGrid: swiper.slidesGrid\n });\n\n function onRendered() {\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n\n if (swiper.lazy && swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n }\n\n if (previousFrom === from && previousTo === to && !force) {\n if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {\n swiper.slides.css(offsetProp, offset + \"px\");\n }\n\n swiper.updateProgress();\n return;\n }\n\n if (swiper.params.virtual.renderExternal) {\n swiper.params.virtual.renderExternal.call(swiper, {\n offset: offset,\n from: from,\n to: to,\n slides: function getSlides() {\n var slidesToRender = [];\n\n for (var i = from; i <= to; i += 1) {\n slidesToRender.push(slides[i]);\n }\n\n return slidesToRender;\n }()\n });\n\n if (swiper.params.virtual.renderExternalUpdate) {\n onRendered();\n }\n\n return;\n }\n\n var prependIndexes = [];\n var appendIndexes = [];\n\n if (force) {\n swiper.$wrapperEl.find(\".\" + swiper.params.slideClass).remove();\n } else {\n for (var i = previousFrom; i <= previousTo; i += 1) {\n if (i < from || i > to) {\n swiper.$wrapperEl.find(\".\" + swiper.params.slideClass + \"[data-swiper-slide-index=\\\"\" + i + \"\\\"]\").remove();\n }\n }\n }\n\n for (var _i = 0; _i < slides.length; _i += 1) {\n if (_i >= from && _i <= to) {\n if (typeof previousTo === 'undefined' || force) {\n appendIndexes.push(_i);\n } else {\n if (_i > previousTo) appendIndexes.push(_i);
166\n if (_i < previousFrom) prependIndexes.push(_i);\n }\n }\n }\n\n appendIndexes.forEach(function (index) {\n swiper.$wrapperEl.append(renderSlide(slides[index], index));\n });\n prependIndexes.sort(function (a, b) {\n return b - a;\n }).forEach(function (index) {\n swiper.$wrapperEl.prepend(renderSlide(slides[index], index));\n });\n swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, offset + \"px\");\n onRendered();\n },\n renderSlide: function renderSlide(slide, index) {\n var swiper = this;\n var params = swiper.params.virtual;\n\n if (params.cache && swiper.virtual.cache[index]) {\n return swiper.virtual.cache[index];\n }\n\n var $slideEl = params.renderSlide ? $(params.renderSlide.call(swiper, slide, index)) : $(\"<div class=\\\"\" + swiper.params.slideClass + \"\\\" data-swiper-slide-index=\\\"\" + index + \"\\\">\" + slide + \"</div>\");\n if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);\n if (params.cache) swiper.virtual.cache[index] = $slideEl;\n return $slideEl;\n },\n appendSlide: function appendSlide(slides) {\n var swiper = this;\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) swiper.virtual.slides.push(slides[i]);\n }\n } else {\n swiper.virtual.slides.push(slides);\n }\n\n swiper.virtual.update(true);\n },\n prependSlide: function prependSlide(slides) {\n var swiper = this;\n var activeIndex = swiper.activeIndex;\n var newActiveIndex = activeIndex + 1;\n var numberOfNewSlides = 1;\n\n if (Array.isArray(slides)) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) swiper.virtual.slides.unshift(slides[i]);\n }\n\n newActiveIndex = activeIndex + slides.length;\n numberOfNewSlides = slides.length;\n } else {\n swiper.virtual.slides.unshift(slides);\n }\n\n if (swiper.params.virtual.cache) {\n var cache = swiper.virtual.cache;\n var newCache = {};\n Object.keys(cache).forEach(function (cachedIndex) {\n var $cachedEl = cache[cachedIndex];\n var cachedElIndex = $cachedEl.attr('data-swiper-slide-index');\n\n if (cachedElIndex) {\n $cachedEl.attr('data-swiper-slide-index', parseInt(cachedElIndex, 10) + 1);\n }\n\n newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;\n });\n swiper.virtual.cache = newCache;\n }\n\n swiper.virtual.update(true);\n swiper.slideTo(newActiveIndex, 0);\n },\n removeSlide: function removeSlide(slidesIndexes) {\n var swiper = this;\n if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;\n var activeIndex = swiper.activeIndex;\n\n if (Array.isArray(slidesIndexes)) {\n for (var i = slidesIndexes.length - 1; i >= 0; i -= 1) {\n swiper.virtual.slides.splice(slidesIndexes[i], 1);\n\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes[i]];\n }\n\n if (slidesIndexes[i] < activeIndex) activeIndex -= 1;\n activeIndex = Math.max(activeIndex, 0);\n }\n } else {\n swiper.virtual.slides.splice(slidesIndexes, 1);\n\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes];\n }\n\n if (slidesIndexes < activeIndex) activeIndex -= 1;\n activeIndex = Math.max(activeIndex, 0);\n }\n\n swiper.virtual.update(true);\n swiper.slideTo(activeIndex, 0);\n },\n removeAllSlides: function removeAllSlides() {\n var swiper = this;\n swiper.virtual.slides = [];\n\n if (swiper.params.virtual.cache) {\n swiper.virtual.cache = {};\n }\n\n swiper.virtual.update(true);\n swiper.slideTo(0, 0);\n }\n };\n var Virtual$1 = {\n name: 'virtual',\n params: {\n virtual: {\n enabled: false,\n slides: [],\n cache: true,\n renderSlide: null,\n renderExternal: null,\n renderExternalUpdate: true,\n addSlidesBefore: 0,\n addSlidesAfter: 0\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n virtual: _extends(_extends({}, Virtual), {}, {\n slides: swiper.params.virtual.slides,\n cache: {}\n })\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (!swiper.params.virtual.enabled) return;\n swiper.classNames.push(swiper.params.containerModifierClass + \"virtual\");\n var overwriteParams = {\n watchSlidesProgress: true\n };\n extend$1(swiper.params, overwriteParams);\n extend$1(swiper.originalParams, overwriteParams);\n\n if (!swiper.params.initialSlide) {\n swiper.virtual.update(
166);\n }\n },\n setTranslate: function setTranslate(swiper) {\n if (!swiper.params.virtual.enabled) return;\n swiper.virtual.update();\n }\n }\n };\n\n var Keyboard = {\n handle: function handle(event) {\n var swiper = this;\n var window = getWindow();\n var document = getDocument();\n var rtl = swiper.rtlTranslate;\n var e = event;\n if (e.originalEvent) e = e.originalEvent; // jquery fix\n\n var kc = e.keyCode || e.charCode;\n var pageUpDown = swiper.params.keyboard.pageUpDown;\n var isPageUp = pageUpDown && kc === 33;\n var isPageDown = pageUpDown && kc === 34;\n var isArrowLeft = kc === 37;\n var isArrowRight = kc === 39;\n var isArrowUp = kc === 38;\n var isArrowDown = kc === 40; // Directions locks\n\n if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {\n return false;\n }\n\n if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {\n return false;\n }\n\n if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n return undefined;\n }\n\n if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n return undefined;\n }\n\n if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {\n var inView = false; // Check that swiper should be inside of visible area of window\n\n if (swiper.$el.parents(\".\" + swiper.params.slideClass).length > 0 && swiper.$el.parents(\".\" + swiper.params.slideActiveClass).length === 0) {\n return undefined;\n }\n\n var windowWidth = window.innerWidth;\n var windowHeight = window.innerHeight;\n var swiperOffset = swiper.$el.offset();\n if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;\n var swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiper.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiper.height], [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height]];\n\n for (var i = 0; i < swiperCoord.length; i += 1) {\n var point = swiperCoord[i];\n\n if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {\n inView = true;\n }\n }\n\n if (!inView) return undefined;\n }\n\n if (swiper.isHorizontal()) {\n if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n }\n\n if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();\n if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();\n } else {\n if (isPageUp || isPageDown || isArrowUp || isArrowDown) {\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n }\n\n if (isPageDown || isArrowDown) swiper.slideNext();\n if (isPageUp || isArrowUp) swiper.slidePrev();\n }\n\n swiper.emit('keyPress', kc);\n return undefined;\n },\n enable: function enable() {\n var swiper = this;\n var document = getDocument();\n if (swiper.keyboard.enabled) return;\n $(document).on('keydown', swiper.keyboard.handle);\n swiper.keyboard.enabled = true;\n },\n disable: function disable() {\n var swiper = this;\n var document = getDocument();\n if (!swiper.keyboard.enabled) return;\n $(document).off('keydown', swiper.keyboard.handle);\n swiper.keyboard.enabled = false;\n }\n };\n var Keyboard$1 = {\n name: 'keyboard',\n params: {\n keyboard: {\n enabled: false,\n onlyInViewport: true,\n pageUpDown: true\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n keyboard: _extends({\n enabled: false\n }, Keyboard)\n });\n },\n on: {\n init: function init(swiper) {\n if (swiper.params.keyboard.enabled) {\n swiper.keyboard.enable();\n }\n },\n destroy: function destroy(swiper) {\n if (swiper.keyboard.enabled) {\n swiper.keyboard.disable();\n }\n }\n }\n };
166\n\n function isEventSupported() {\n var document = getDocument();\n var eventName = 'onwheel';\n var isSupported = (eventName in document);\n\n if (!isSupported) {\n var element = document.createElement('div');\n element.setAttribute(eventName, 'return;');\n isSupported = typeof element[eventName] === 'function';\n }\n\n if (!isSupported && document.implementation && document.implementation.hasFeature && // always returns true in newer browsers as per the standard.\n // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n document.implementation.hasFeature('', '') !== true) {\n // This is the only way to test support for the `wheel` event in IE9+.\n isSupported = document.implementation.hasFeature('Events.wheel', '3.0');\n }\n\n return isSupported;\n }\n\n var Mousewheel = {\n lastScrollTime: now(),\n lastEventBeforeSnap: undefined,\n recentWheelEvents: [],\n event: function event() {\n var window = getWindow();\n if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll';\n return isEventSupported() ? 'wheel' : 'mousewheel';\n },\n normalize: function normalize(e) {\n // Reasonable defaults\n var PIXEL_STEP = 10;\n var LINE_HEIGHT = 40;\n var PAGE_HEIGHT = 800;\n var sX = 0;\n var sY = 0; // spinX, spinY\n\n var pX = 0;\n var pY = 0; // pixelX, pixelY\n // Legacy\n\n if ('detail' in e) {\n sY = e.detail;\n }\n\n if ('wheelDelta' in e) {\n sY = -e.wheelDelta / 120;\n }\n\n if ('wheelDeltaY' in e) {\n sY = -e.wheelDeltaY / 120;\n }\n\n if ('wheelDeltaX' in e) {\n sX = -e.wheelDeltaX / 120;\n } // side scrolling on FF with DOMMouseScroll\n\n\n if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {\n sX = sY;\n sY = 0;\n }\n\n pX = sX * PIXEL_STEP;\n pY = sY * PIXEL_STEP;\n\n if ('deltaY' in e) {\n pY = e.deltaY;\n }\n\n if ('deltaX' in e) {\n pX = e.deltaX;\n }\n\n if (e.shiftKey && !pX) {\n // if user scrolls with shift he wants horizontal scroll\n pX = pY;\n pY = 0;\n }\n\n if ((pX || pY) && e.deltaMode) {\n if (e.deltaMode === 1) {\n // delta in LINE units\n pX *= LINE_HEIGHT;\n pY *= LINE_HEIGHT;\n } else {\n // delta in PAGE units\n pX *= PAGE_HEIGHT;\n pY *= PAGE_HEIGHT;\n }\n } // Fall-back if spin cannot be determined\n\n\n if (pX && !sX) {\n sX = pX < 1 ? -1 : 1;\n }\n\n if (pY && !sY) {\n sY = pY < 1 ? -1 : 1;\n }\n\n return {\n spinX: sX,\n spinY: sY,\n pixelX: pX,\n pixelY: pY\n };\n },\n handleMouseEnter: function handleMouseEnter() {\n var swiper = this;\n swiper.mouseEntered = true;\n },\n handleMouseLeave: function handleMouseLeave() {\n var swiper = this;\n swiper.mouseEntered = false;\n },\n handle: function handle(event) {\n var e = event;\n var swiper = this;\n var params = swiper.params.mousewheel;\n\n if (swiper.params.cssMode) {\n e.preventDefault();\n }\n\n var target = swiper.$el;\n\n if (swiper.params.mousewheel.eventsTarget !== 'container') {\n target = $(swiper.params.mousewheel.eventsTarget);\n }\n\n if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;\n if (e.originalEvent) e = e.originalEvent; // jquery fix\n\n var delta = 0;\n var rtlFactor = swiper.rtlTranslate ? -1 : 1;\n var data = Mousewheel.normalize(e);\n\n if (params.forceToAxis) {\n if (swiper.isHorizontal()) {\n if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;\n } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;\n } else {\n delta = Math.abs(data.pixelX) >
166 Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;\n }\n\n if (delta === 0) return true;\n if (params.invert) delta = -delta;\n\n if (!swiper.params.freeMode) {\n // Register the new event in a variable which stores the relevant data\n var newEvent = {\n time: now(),\n delta: Math.abs(delta),\n direction: Math.sign(delta),\n raw: event\n }; // Keep the most recent events\n\n var recentWheelEvents = swiper.mousewheel.recentWheelEvents;\n\n if (recentWheelEvents.length >= 2) {\n recentWheelEvents.shift(); // only store the last N events\n }\n\n var prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;\n recentWheelEvents.push(newEvent); // If there is at least one previous recorded event:\n // If direction has changed or\n // if the scroll is quicker than the previous one:\n // Animate the slider.\n // Else (this is the first time the wheel is moved):\n // Animate the slider.\n\n if (prevEvent) {\n if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {\n swiper.mousewheel.animateSlider(newEvent);\n }\n } else {\n swiper.mousewheel.animateSlider(newEvent);\n } // If it's time to release the scroll:\n // Return now so you don't hit the preventDefault.\n\n\n if (swiper.mousewheel.releaseScroll(newEvent)) {\n return true;\n }\n } else {\n // Freemode or scrollContainer:\n // If we recently snapped after a momentum scroll, then ignore wheel events\n // to give time for the deceleration to finish. Stop ignoring after 500 msecs\n // or if it's a new scroll (larger delta or inverse sign as last event before\n // an end-of-momentum snap).\n var _newEvent = {\n time: now(),\n delta: Math.abs(delta),\n direction: Math.sign(delta)\n };\n var lastEventBeforeSnap = swiper.mousewheel.lastEventBeforeSnap;\n var ignoreWheelEvents = lastEventBeforeSnap && _newEvent.time < lastEventBeforeSnap.time + 500 && _newEvent.delta <= lastEventBeforeSnap.delta && _newEvent.direction === lastEventBeforeSnap.direction;\n\n if (!ignoreWheelEvents) {\n swiper.mousewheel.lastEventBeforeSnap = undefined;\n\n if (swiper.params.loop) {\n swiper.loopFix();\n }\n\n var position = swiper.getTranslate() + delta * params.sensitivity;\n var wasBeginning = swiper.isBeginning;\n var wasEnd = swiper.isEnd;\n if (position >= swiper.minTranslate()) position = swiper.minTranslate();\n if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();\n swiper.setTransition(0);\n swiper.setTranslate(position);\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n\n if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {\n swiper.updateSlidesClasses();\n }\n\n if (swiper.params.freeModeSticky) {\n // When wheel scrolling starts with sticky (aka snap) enabled, then detect\n // the end of a momentum scroll by storing recent (N=15?) wheel events.\n // 1. do all N events have decreasing or same (absolute value) delta?\n // 2. did all N events arrive in the last M (M=500?) msecs?\n // 3. does the earliest event have an (absolute value) delta that's\n // at least P (P=1?) larger than the most recent event's delta?\n // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?\n // If 1-4 are \"yes\" then we're near the end of a momuntum scroll deceleration.\n // Snap immediately and ignore remaining wheel events in this scroll.\n // See comment above for \"remaining wheel events in this scroll\" determination.\n // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.\n clearTimeout(swiper.mousewheel.timeout);\n swiper.mousewheel.timeout = undefined;\n var _recentWheelEvents = swiper.mousewheel.recentWheelEvents;\n\n if (_recentWheelEvents.length >= 15) {\n _recentWheelEvents.shift(); // only store the last N events\n\n }\n\n var _prevEvent = _recentWheelEvents.length ? _recentWheelEvents[_recentWheelEvents.length - 1] : undefined;\n\n var firstEvent = _recentWheelEvents[0];\n\n _recentWheelEvents.push(_newEvent);\n\n if (_prevEvent && (_newEvent.delta > _prevEvent.delta || _newEvent.direction !== _prevEvent.direction)) {\n // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.\n _recentWheelEvents.splice(0);\n } else if (_recentWheelEvents.length >= 15 && _newEvent.time - firstEvent.time < 500 && firstEvent.delta - _newEvent.delta >= 1 && _newEvent.delta <= 6) {\n // We're at the end of the deceleration of a momentum scroll, so there's no need\n // to wait for more events. Snap ASAP on the next tick.\n // Also, because there's some remaining momentum we'll bias the snap in the\n // direction of the ongoing scroll because it's better UX for the scroll to snap\n // in the same direction as the scroll instead of reversing to snap. Therefore,\n // if it's already scrolled more than 20% in the current direction, keep going.\n var snapToThreshold = delta > 0 ? 0.8 : 0.2;\n swiper.mousewheel.lastEventBeforeSnap = _newEvent;\n\n _recentWheelEvents.splice(0);\n\n swiper.mousewheel.timeout = nextTick(function () {\n swiper.slideToClosest(swi
166per.params.speed, true, undefined, snapToThreshold);\n }, 0); // no delay; move on next tick\n }\n\n if (!swiper.mousewheel.timeout) {\n // if we get here, then we haven't detected the end of a momentum scroll, so\n // we'll consider a scroll \"complete\" when there haven't been any wheel events\n // for 500ms.\n swiper.mousewheel.timeout = nextTick(function () {\n var snapToThreshold = 0.5;\n swiper.mousewheel.lastEventBeforeSnap = _newEvent;\n\n _recentWheelEvents.splice(0);\n\n swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);\n }, 500);\n }\n } // Emit event\n\n\n if (!ignoreWheelEvents) swiper.emit('scroll', e); // Stop autoplay\n\n if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); // Return page scroll on edge positions\n\n if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;\n }\n }\n\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n return false;\n },\n animateSlider: function animateSlider(newEvent) {\n var swiper = this;\n var window = getWindow();\n\n if (this.params.mousewheel.thresholdDelta && newEvent.delta < this.params.mousewheel.thresholdDelta) {\n // Prevent if delta of wheel scroll delta is below configured threshold\n return false;\n }\n\n if (this.params.mousewheel.thresholdTime && now() - swiper.mousewheel.lastScrollTime < this.params.mousewheel.thresholdTime) {\n // Prevent if time between scrolls is below configured threshold\n return false;\n } // If the movement is NOT big enough and\n // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):\n // Don't go any further (avoid insignificant scroll movement).\n\n\n if (newEvent.delta >= 6 && now() - swiper.mousewheel.lastScrollTime < 60) {\n // Return false as a default\n return true;\n } // If user is scrolling towards the end:\n // If the slider hasn't hit the latest slide or\n // if the slider is a loop and\n // if the slider isn't moving right now:\n // Go to next slide and\n // emit a scroll event.\n // Else (the user is scrolling towards the beginning) and\n // if the slider hasn't hit the first slide or\n // if the slider is a loop and\n // if the slider isn't moving right now:\n // Go to prev slide and\n // emit a scroll event.\n\n\n if (newEvent.direction < 0) {\n if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {\n swiper.slideNext();\n swiper.emit('scroll', newEvent.raw);\n }\n } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {\n swiper.slidePrev();\n swiper.emit('scroll', newEvent.raw);\n } // If you got here is because an animation has been triggered so store the current time\n\n\n swiper.mousewheel.lastScrollTime = new window.Date().getTime(); // Return false as a default\n\n return false;\n },\n releaseScroll: function releaseScroll(newEvent) {\n var swiper = this;\n var params = swiper.params.mousewheel;\n\n if (newEvent.direction < 0) {\n if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {\n // Return true to animate scroll on edges\n return true;\n }\n } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {\n // Return true to animate scroll on edges\n return true;\n }\n\n return false;\n },\n enable: function enable() {\n var swiper = this;\n var event = Mousewheel.event();\n\n if (swiper.params.cssMode) {\n swiper.wrapperEl.removeEventListener(event, swiper.mousewheel.handle);\n return true;\n }\n\n if (!event) return false;\n if (swiper.mousewheel.enabled) return false;\n var target = swiper.$el;\n\n if (swiper.params.mousewheel.eventsTarget !== 'container') {\n target = $(swiper.params.mousewheel.eventsTarget);\n }\n\n target.on('mouseenter', swiper.mousewheel.handleMouseEnter);\n target.on('mouseleave', swiper.mousewheel.handleMouseLeave);\n target.on(event, swiper.mousewheel.handle);\n swiper.mousewheel.enabled = true;\n return true;\n },\n disable: function disable() {\n var swiper = this;\n var event = Mousewheel.event();\n\n if (swiper.params.cssMode) {\n swiper.wrapperEl.addEventListener(event, swiper.mousewheel.handle);\n return true;\n }\n\n if (!event) return false;\n if (!swiper.mousewheel.enabled) return false;\n var target = swiper.$el;\n\n if (swiper.params.mousewheel.eventsTarget !== 'container') {\n target = $(swiper.params.mousewheel.eventsTarget);\n }\n\n target.off(event, swiper.mousewheel.handle);\n swiper.mousewheel.enabled = false;\n return true;\n }\n };\n var Mousewheel$1 = {\n name: 'mousewheel',\n params: {\n mousewheel: {\n enabled: false,\n releaseOnEdges: false,\n invert: false,\n forceToAxis: fal
166se,\n sensitivity: 1,\n eventsTarget: 'container',\n thresholdDelta: null,\n thresholdTime: null\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n mousewheel: {\n enabled: false,\n lastScrollTime: now(),\n lastEventBeforeSnap: undefined,\n recentWheelEvents: [],\n enable: Mousewheel.enable,\n disable: Mousewheel.disable,\n handle: Mousewheel.handle,\n handleMouseEnter: Mousewheel.handleMouseEnter,\n handleMouseLeave: Mousewheel.handleMouseLeave,\n animateSlider: Mousewheel.animateSlider,\n releaseScroll: Mousewheel.releaseScroll\n }\n });\n },\n on: {\n init: function init(swiper) {\n if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {\n swiper.mousewheel.disable();\n }\n\n if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable();\n },\n destroy: function destroy(swiper) {\n if (swiper.params.cssMode) {\n swiper.mousewheel.enable();\n }\n\n if (swiper.mousewheel.enabled) swiper.mousewheel.disable();\n }\n }\n };\n\n var Navigation = {\n update: function update() {\n // Update Navigation Buttons\n var swiper = this;\n var params = swiper.params.navigation;\n if (swiper.params.loop) return;\n var _swiper$navigation = swiper.navigation,\n $nextEl = _swiper$navigation.$nextEl,\n $prevEl = _swiper$navigation.$prevEl;\n\n if ($prevEl && $prevEl.length > 0) {\n if (swiper.isBeginning) {\n $prevEl.addClass(params.disabledClass);\n } else {\n $prevEl.removeClass(params.disabledClass);\n }\n\n $prevEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n\n if ($nextEl && $nextEl.length > 0) {\n if (swiper.isEnd) {\n $nextEl.addClass(params.disabledClass);\n } else {\n $nextEl.removeClass(params.disabledClass);\n }\n\n $nextEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n },\n onPrevClick: function onPrevClick(e) {\n var swiper = this;\n e.preventDefault();\n if (swiper.isBeginning && !swiper.params.loop) return;\n swiper.slidePrev();\n },\n onNextClick: function onNextClick(e) {\n var swiper = this;\n e.preventDefault();\n if (swiper.isEnd && !swiper.params.loop) return;\n swiper.slideNext();\n },\n init: function init() {\n var swiper = this;\n var params = swiper.params.navigation;\n if (!(params.nextEl || params.prevEl)) return;\n var $nextEl;\n var $prevEl;\n\n if (params.nextEl) {\n $nextEl = $(params.nextEl);\n\n if (swiper.params.uniqueNavElements && typeof params.nextEl === 'string' && $nextEl.length > 1 && swiper.$el.find(params.nextEl).length === 1) {\n $nextEl = swiper.$el.find(params.nextEl);\n }\n }\n\n if (params.prevEl) {\n $prevEl = $(params.prevEl);\n\n if (swiper.params.uniqueNavElements && typeof params.prevEl === 'string' && $prevEl.length > 1 && swiper.$el.find(params.prevEl).length === 1) {\n $prevEl = swiper.$el.find(params.prevEl);\n }\n }\n\n if ($nextEl && $nextEl.length > 0) {\n $nextEl.on('click', swiper.navigation.onNextClick);\n }\n\n if ($prevEl && $prevEl.length > 0) {\n $prevEl.on('click', swiper.navigation.onPrevClick);\n }\n\n extend$1(swiper.navigation, {\n $nextEl: $nextEl,\n nextEl: $nextEl && $nextEl[0],\n $prevEl: $prevEl,\n prevEl: $prevEl && $prevEl[0]\n });\n },\n destroy: function destroy() {\n var swiper = this;\n var _swiper$navigation2 = swiper.navigation,\n $nextEl = _swiper$navigation2.$nextEl,\n $prevEl = _swiper$navigation2.$prevEl;\n\n if ($nextEl && $nextEl.length) {\n $nextEl.off('click', swiper.navigation.onNextClick);\n $nextEl.removeClass(swiper.params.navigation.disabledClass);\n }\n\n if ($prevEl && $prevEl.length) {\n $prevEl.off('click', swiper.navigation.onPrevClick);\n $prevEl.removeClass(swiper.params.navigation.disabledClass);\n }\n }\n };\n var Navigation$1 = {\n name: 'navigation',\n params: {\n navigation: {\n nextEl: null,\n prevEl: null,\n hideOnClick: false,\n disabledClass: 'swiper-button-disabled',\n hiddenClass: 'swiper-button-hidden',\n lockClass: 'swiper-button-lock'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n navigation: _extends({}, Navigation)\n });\n },\n on: {\n init: function init(swiper) {\n swiper.navigation.init();\n swiper.navigation.update();\n },\n toEdge: function toEdge(swiper) {\n swiper.navigation.update();\n }
166,\n fromEdge: function fromEdge(swiper) {\n swiper.navigation.update();\n },\n destroy: function destroy(swiper) {\n swiper.navigation.destroy();\n },\n click: function click(swiper, e) {\n var _swiper$navigation3 = swiper.navigation,\n $nextEl = _swiper$navigation3.$nextEl,\n $prevEl = _swiper$navigation3.$prevEl;\n\n if (swiper.params.navigation.hideOnClick && !$(e.target).is($prevEl) && !$(e.target).is($nextEl)) {\n var isHidden;\n\n if ($nextEl) {\n isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);\n } else if ($prevEl) {\n isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);\n }\n\n if (isHidden === true) {\n swiper.emit('navigationShow');\n } else {\n swiper.emit('navigationHide');\n }\n\n if ($nextEl) {\n $nextEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n\n if ($prevEl) {\n $prevEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n }\n }\n }\n };\n\n var Pagination = {\n update: function update() {\n // Render || Update Pagination bullets/items\n var swiper = this;\n var rtl = swiper.rtl;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;\n var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n var $el = swiper.pagination.$el; // Current/Total\n\n var current;\n var total = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n\n if (swiper.params.loop) {\n current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);\n\n if (current > slidesLength - 1 - swiper.loopedSlides * 2) {\n current -= slidesLength - swiper.loopedSlides * 2;\n }\n\n if (current > total - 1) current -= total;\n if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;\n } else if (typeof swiper.snapIndex !== 'undefined') {\n current = swiper.snapIndex;\n } else {\n current = swiper.activeIndex || 0;\n } // Types\n\n\n if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {\n var bullets = swiper.pagination.bullets;\n var firstIndex;\n var lastIndex;\n var midIndex;\n\n if (params.dynamicBullets) {\n swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);\n $el.css(swiper.isHorizontal() ? 'width' : 'height', swiper.pagination.bulletSize * (params.dynamicMainBullets + 4) + \"px\");\n\n if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {\n swiper.pagination.dynamicBulletIndex += current - swiper.previousIndex;\n\n if (swiper.pagination.dynamicBulletIndex > params.dynamicMainBullets - 1) {\n swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1;\n } else if (swiper.pagination.dynamicBulletIndex < 0) {\n swiper.pagination.dynamicBulletIndex = 0;\n }\n }\n\n firstIndex = current - swiper.pagination.dynamicBulletIndex;\n lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);\n midIndex = (lastIndex + firstIndex) / 2;\n }\n\n bullets.removeClass(params.bulletActiveClass + \" \" + params.bulletActiveClass + \"-next \" + params.bulletActiveClass + \"-next-next \" + params.bulletActiveClass + \"-prev \" + params.bulletActiveClass + \"-prev-prev \" + params.bulletActiveClass + \"-main\");\n\n if ($el.length > 1) {\n bullets.each(function (bullet) {\n var $bullet = $(bullet);\n var bulletIndex = $bullet.index();\n\n if (bulletIndex === current) {\n $bullet.addClass(params.bulletActiveClass);\n }\n\n if (params.dynamicBullets) {\n if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {\n $bullet.addClass(params.bulletActiveClass + \"-main\");\n }\n\n if (bulletIndex === firstIndex) {\n $bullet.prev().addClass(params.bulletActiveClass + \"-prev\").prev().addClass(params.bulletActiveClass + \"-prev-prev\");\n }\n\n if (bulletIndex === lastIndex) {\n $bullet.next().addClass(params.bulletActiveClass + \"-next\").next().addClass(params.bulletActiveClass + \"-next-next\");\n }\n }\n });\n } else {\n var $bullet = bullets.eq(current);\n var bulletIndex = $bullet.index();\n $bullet.addClass(params.bulletActiveClass);\n\n if (params.dynamicBullets) {\n var $firstDisplayedBullet = bullets.eq(firstIndex);\n var $lastDisplayedBullet = bullets.eq(lastIndex);\n\n for (var i = firstIndex; i <= lastIndex; i += 1) {\n bullets.eq(i).addClass(params.bulletActiveClass + \"-main\");\n }\n\n if (swiper.params.loop) {\n if (bulletIndex >= bullets.length - params.dynamicMainBullets) {\n for (var _i = params.dynamicMainBullets; _i >= 0; _i -= 1) {\n bullets.eq(bullets.length - _i).addClass(params.bulletActiveClass + \"-main\");\n }\n\n bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(params.bulletActiveClass + \"-prev\");\n } else {\n $firstDisplayedBullet.prev().addClass(params.bulletActiveClass + \"-prev\").prev().addClass(params.bulletActiveClass + \"-prev-prev\");\n $lastDisplayedBullet.next().addClass(params.bulletActiveClass + \"-next\").next().addClass(params.bulletActiveClass + \"-next-next\");\n }\n } else {\n $firstDisplayedBullet.prev().addClass(params.bulletActiveClass + \"-prev\").prev().addClass(params.bulletActiveClass + \"-prev-prev\");\n $lastDisplayedBullet.next().addClass(params.bulletActiveClass + \"-next\").next().addClass(params.bulletActiveClass + \"-next-next\");\n }\n }\n }\n\n if (params.dynamicBullets) {\n var dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);\n var bulletsOffset = (swiper.pagination.bulletSize * dynamicBulletsLength - swiper.pagination.bulletSize) / 2 - midIndex * swiper.pagination.bulletSize;\n var offsetProp = rtl ? 'right' : 'left';\n bullets.css(swiper.isHorizontal() ? offsetProp : 'top', bulletsOffset + \"px\");\n }\n }\n\n if (params.type === 'fraction') {\n $el.find(\".\" + params.currentClass).text(params.formatFractionCurrent(current + 1));\n $el.find(\".\" + params.totalClass).text(params.formatFractionTotal(total));\n }\n\n if (params.type === 'progressbar') {\n var progressbarDirection;\n\n if (params.progressbarOpposite) {\n progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';\n } else {\n progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';\n }\n\n var scale = (current + 1) / total;\n var scaleX = 1;\n var scaleY = 1;\n\n if (progressbarDirection === 'horizontal') {\n scaleX = scale;\n } else {\n scaleY = scale;\n }\n\n $el.find(\".\" + params.progressbarFillClass).transform(\"translate3d(0,
1660,0) scaleX(\" + scaleX + \") scaleY(\" + scaleY + \")\").transition(swiper.params.speed);\n }\n\n if (params.type === 'custom' && params.renderCustom) {\n $el.html(params.renderCustom(swiper, current + 1, total));\n swiper.emit('paginationRender', $el[0]);\n } else {\n swiper.emit('paginationUpdate', $el[0]);\n }\n\n $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n },\n render: function render() {\n // Render Container\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;\n var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n var $el = swiper.pagination.$el;\n var paginationHTML = '';\n\n if (params.type === 'bullets') {\n var numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n\n for (var i = 0; i < numberOfBullets; i += 1) {\n if (params.renderBullet) {\n paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);\n } else {\n paginationHTML += \"<\" + params.bulletElement + \" class=\\\"\" + params.bulletClass + \"\\\"></\" + params.bulletElement + \">\";\n }\n }\n\n $el.html(paginationHTML);\n swiper.pagination.bullets = $el.find(\".\" + params.bulletClass);\n }\n\n if (params.type === 'fraction') {\n if (params.renderFraction) {\n paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);\n } else {\n paginationHTML = \"<span class=\\\"\" + params.currentClass + \"\\\"></span>\" + ' / ' + (\"<span class=\\\"\" + params.totalClass + \"\\\"></span>\");\n }\n\n $el.html(paginationHTML);\n }\n\n if (params.type === 'progressbar') {\n if (params.renderProgressbar) {\n paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);\n } else {\n paginationHTML = \"<span class=\\\"\" + params.progressbarFillClass + \"\\\"></span>\";\n }\n\n $el.html(paginationHTML);\n }\n\n if (params.type !== 'custom') {\n swiper.emit('paginationRender', swiper.pagination.$el[0]);\n }\n },\n init: function init() {\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el) return;\n var $el = $(params.el);\n if ($el.length === 0) return;\n\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1) {\n $el = swiper.$el.find(params.el);\n }\n\n if (params.type === 'bullets' && params.clickable) {\n $el.addClass(params.clickableClass);\n }\n\n $el.addClass(params.modifierClass + params.type);\n\n if (params.type === 'bullets' && params.dynamicBullets) {\n $el.addClass(\"\" + params.modifierClass + params.type + \"-dynamic\");\n swiper.pagination.dynamicBulletIndex = 0;\n\n if (params.dynamicMainBullets < 1) {\n params.dynamicMainBullets = 1;\n }\n }\n\n if (params.type === 'progressbar' && params.progressbarOpposite) {\n $el.addClass(params.progressbarOppositeClass);\n }\n\n if (params.clickable) {\n $el.on('click', \".\" + params.bulletClass, function onClick(e) {\n e.preventDefault();\n var index = $(this).index() * swiper.params.slidesPerGroup;\n if (swiper.params.loop) index += swiper.loopedSlides;\n swiper.slideTo(index);\n });\n }\n\n extend$1(swiper.pagination, {\n $el: $el,\n el: $el[0]\n });\n },\n destroy: function destroy() {\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;\n var $el = swiper.pagination.$el;\n $el.removeClass(params.hiddenClass);\n $el.removeClass(params.modifierClass + params.type);\n if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass);\n\n if (params.clickable) {\n $el.off('click', \".\" + params.bulletClass);\n }\n }\n };\n var Pagination$1 = {\n name: 'pagination',\n params: {\n pagination: {\n el: null,\n bulletElement: 'span',\n clickable: false,\n hideOnClick: false,\n renderBullet: null,\n renderProgressbar: null,\n renderFraction: null,\n renderCustom: null,\n progressbarOpposite: false,\n type: 'bullets',\n // 'bullets' or 'progressbar' or 'fraction' or 'custom'\n dynamicBullets: false,\n dynamicMainBullets: 1,\n formatFractionCurrent: function formatFractionCurrent(number) {\n return number;\n },\n formatFractionTotal: function formatFractionTotal(number) {\n return number;\n },\n bulletClass: 'swiper-pagination-bullet',\n bulletActiveClass: 'swiper-pagination-bullet-active',\n modifierClass: 'swiper-pagination-',\n // NEW\n currentClass: 'swiper-pagination-current',\n totalClass: 'swiper-pagination-total',\n hiddenClass: 'swiper-pagination-hidden',\n progressbarFillClass: 'swiper-pagination-progressbar-fill',\n progressbarOppositeClass: 'swiper-pagination-progressbar-opposite',\n clickableClass: 'swiper-pagination-clickable',\n // NEW\n lockClass: 'swiper-pagination-lock'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n pagination: _extends({\n dynamicBulletIndex: 0\n }, Pagination)\n });\n },\n on: {\n init: function init(swiper) {\n swiper.pagination.init();\n swiper.pagination.render();\n swiper.pagination.update();\n },\n activeIndexChange: function activeIndexChange(swiper) {\n if (swiper.params.loop) {\n swiper.pagination.update();\n } else if (typeof swiper.snapIndex === 'undefined') {\n swiper.pagination.update();\n }\n },\n snapIndexChange: function snapIndexChange(swiper) {\n if (!swiper.params.loop) {\n swiper.pagination.update();\n }\n },\n slidesLengthChange: function slidesLengthChange(swiper) {\n if (swiper.params.loop) {\n swiper.pagination.render();\n swiper.pagination.update();\n }\n },\n snapGridLengthChange: function snapGridLengthChange(swiper) {\n if (!swiper.params.loop) {\n swiper.pagination.render();\n swiper.pagination.update();\n }\n },\n destroy: function destroy(swiper) {\n swiper.pagination.destroy();\n },\n click: function click(swiper, e) {\n if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && swiper.pagination.$el.length > 0 && !$(e.target).hasClass(swiper.params.pagination.bulletClass)) {\n var isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass);\n\n if (isHidden === true) {\n swiper.emit('paginationShow');\n } else {\n swiper.emit('paginationHide');\n }\n\n swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass);\n }\n }\n }\n };\n\n var Scrollbar = {\n setTranslate: function setTranslate() {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n var scrollbar = swiper.scrollbar,\n rtl = swiper.rtlTranslate,\n progress = swiper.progress;\n var dragSize = scrollbar.dragSize,\n trackSize = scrollbar.trackSize,\n $dragEl = scrollbar.$dragEl,\n $el = scrollbar.$el;\n var params = swiper.params.scrollbar;\n var newSize = dragSize;\n var newPos = (trackSize - dragSize) * progress;\n\n if (rtl) {\n newPos = -newPos;\n\n if (newPos > 0) {\n newSize = dragSize - newPos;\n newPos = 0;\n } else if (-newPos + dragSize > trackSize) {\n newSize = trackSize + newPos;\n }\n } else if (newPos < 0) {\n newSize = dragSize + newPos;\n newPos = 0;\n } else if (newPos + dragSize > trackSize) {\n newSize = trackSize - newPos;\n }\n\n if (swiper.isHorizontal()) {\n $dragEl.transform(\"translate3d(\" + newPos + \"px, 0, 0)\");\n $dragEl[0].style.width = newSize + \"px\";\n } else {\n $dragEl.transform(\"translate3d(0px, \" + newPos + \"px, 0)\");\n $dragEl[0].style.height = newSize + \"px\";\n }\n\n if (params.hide) {\n clearTimeout(swiper.scrollbar.timeout);\n $el[0].style.opacity = 1;\n swiper.scrollbar.timeout = setTimeout(function () {\n $el[0].style.opacity = 0;\n $el.transition(400);\n }, 1000);\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n swiper.scrollbar.$dragEl.transition(duration);\n },\n updateSize: function updateSize() {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n var scrollbar = swiper.scrollbar;\n var $dragEl = scrollbar.$dragEl,\n $el = scrollbar.$el;\n $dragEl[0].style.width = '';\n $dragEl[0].style.height = '';\n var trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight;\n var divider = swiper.size / swiper.virtualSize;\n var moveDivider = divider * (trackSize / swiper.size);\n var dragSize;\n\n if (swiper.params.scrollbar.dragSize === 'auto') {\n dragSize = trackSize * divider;\n } else {\n dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);\n }\n\n if (swiper.isHorizontal()) {\n $dragEl[0].style.width = dragSize + \"px\";\n } else {\n $dragEl[0].style.height = dragSize + \"px\";\n }\n\n if (divider >= 1) {\n $el[0].style.display = 'none';\n } else {\n $el[0].style.display = '';\n }\n\n if (swiper.params.scrollbar.hide) {\n $el[0].style.opacity = 0;\n }\n\n extend$1(scrollbar, {\n trackSize: trackSize,\n divider: divider,\n moveDivider: moveDivider,\n dragSize: dragSize\n });\n scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass);\n },\n getPointerPosition: function getPointerPosition(e) {\n var swiper = this;\n\n if (swiper.isHorizontal()) {\n return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientX : e.clientX;\n }\n\n return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientY : e.clientY;\n },\n setDragPosition: function setDragPosition(e) {\n var swiper = this;\n var scrollbar = swiper.scrollbar,\n rtl = swiper.rtlTranslate;\n var $el = scrollbar.$el,\n dragSize = scrollbar.dragSize,\n trackSize = scrollbar.trackSize,\n dragStartPos = scrollbar.dragStartPos;\n var positionRatio;\n positionRatio = (scrollbar.getPointerPosition(e) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);\n positionRatio = Math.max(Math.min(positionRatio, 1), 0);\n\n if (rtl) {\n positionRatio = 1 - positionRatio;\n }\n\n var position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;\n swiper.updateProgress(position);\n swiper.setTranslate(position);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n },\n onDragStart: function onDragStart(e) {\n var swiper = this;\n var params = swiper.params.scrollbar;\n var scrollbar = swiper.scrollbar,\n $wrapperEl = swiper.$wrapperEl;\n var $el = scrollbar.$el,\n $dragEl = scrollbar.$dragEl;\n swiper.scrollbar.isTouched = true;\n swiper.scrollbar.dragStartPos = e.target === $dragEl[0] || e.target === $dragEl ? scrollbar.getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;\n e.preventDefault();\n e.stopPropagation();\n $wrapperEl.transition(100);\n $dragEl.transition(100);\n scrollbar.setDragPosition(e);\n clearTimeout(swiper.scrollbar.dragTimeout);\n $el.transition(0);\n\n if (params.hide) {\n $el.css('opacity', 1);\n }\n\n if (swiper.params.cssMode) {\n swiper.$wrapperEl.css('scroll-snap-type', 'none');\n }\n\n swiper.emit('scrollbarDragStart', e);\n },\n onDragMove: function onDragMove(e) {\n var swiper = this;\n var scrollbar = swiper.scrollbar,\n $wrapperEl = swiper.$wrapperEl;\n var $el = scrollbar.$el,\n $dragEl = scrollbar.$dragEl;\n if (!swiper.scrollbar.isTouched) return;\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n scrollbar.setDragPosition(e);\n $wrapperEl.transition(0);\n $el.transition(0);\n $dragEl.transition(0);\n swiper.emit('scrollbarDragMove', e);\n },\n onDragEnd: function onDragEnd(e) {\n var swiper = this;\n var params = swiper.params.scrollbar;\n var scrollbar = swiper.scrollbar,\n $wrapperEl = swiper.$wrapperEl;\n var $el = scrollbar.$el;\n if (!swiper.scrollbar.isTouched) return;\n swiper.scrollbar.isTouched = false;\n\n if (swiper.params.cssMode) {\n swiper.$wrapperEl.css('scroll-snap-type', '');\n $wrapperEl.transition('');\n }\n\n if (params.hide) {\n clearTimeout(swiper.scrollbar.dragTimeout);\n swiper.scrollbar.dragTimeout = nextTick(function () {\n $el.css('opacity', 0);\n $el.transition(400);\n }, 1000);\n }\n\n swiper.emit('scrollbarDragEnd', e);\n\n if (params.snapOnRelease) {\n swiper.slideToClosest();\n }\n },\n enableDraggable: function enableDraggable() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) return;\n var document = getDocument();\n var scrollbar = swiper.scrollbar,\n touchEventsTouch = swiper.touchEventsTouch,\n touchEventsDesktop = swiper.touchEventsDesktop,\n params = swiper.params,\n support = swiper.support;\n var $el = scrollbar.$el;\n var target = $el[0];\n var activeListener = support.passiveListener && params.passiveListeners ? {\n passive: false,\n capture: false\n } : false;\n var passiveListener = support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n\n if (!support.touch) {\n target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);\n document.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);\n document.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);\n } else {\n target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);\n target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);\n target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);\n }\n },\n disableDraggable: function disableDraggable() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) return;\n var document = getDocument();\n var scrollbar = swiper.scrollbar,\n touchEventsTouch = swiper.touchEventsTouch,\n touchEventsDesktop = swiper.touchEventsDesktop,\n
166 params = swiper.params,\n support = swiper.support;\n var $el = scrollbar.$el;\n var target = $el[0];\n var activeListener = support.passiveListener && params.passiveListeners ? {\n passive: false,\n capture: false\n } : false;\n var passiveListener = support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n\n if (!support.touch) {\n target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);\n document.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);\n document.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);\n } else {\n target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);\n target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);\n target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);\n }\n },\n init: function init() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) return;\n var scrollbar = swiper.scrollbar,\n $swiperEl = swiper.$el;\n var params = swiper.params.scrollbar;\n var $el = $(params.el);\n\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) {\n $el = $swiperEl.find(params.el);\n }\n\n var $dragEl = $el.find(\".\" + swiper.params.scrollbar.dragClass);\n\n if ($dragEl.length === 0) {\n $dragEl = $(\"<div class=\\\"\" + swiper.params.scrollbar.dragClass + \"\\\"></div>\");\n $el.append($dragEl);\n }\n\n extend$1(scrollbar, {\n $el: $el,\n el: $el[0],\n $dragEl: $dragEl,\n dragEl: $dragEl[0]\n });\n\n if (params.draggable) {\n scrollbar.enableDraggable();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.scrollbar.disableDraggable();\n }\n };\n var Scrollbar$1 = {\n name: 'scrollbar',\n params: {\n scrollbar: {\n el: null,\n dragSize: 'auto',\n hide: false,\n draggable: false,\n snapOnRelease: true,\n lockClass: 'swiper-scrollbar-lock',\n dragClass: 'swiper-scrollbar-drag'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n scrollbar: _extends({\n isTouched: false,\n timeout: null,\n dragTimeout: null\n }, Scrollbar)\n });\n },\n on: {\n init: function init(swiper) {\n swiper.scrollbar.init();\n swiper.scrollbar.updateSize();\n swiper.scrollbar.setTranslate();\n },\n update: function update(swiper) {\n swiper.scrollbar.updateSize();\n },\n resize: function resize(swiper) {\n swiper.scrollbar.updateSize();\n },\n observerUpdate: function observerUpdate(swiper) {\n swiper.scrollbar.updateSize();\n },\n setTranslate: function setTranslate(swiper) {\n swiper.scrollbar.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n swiper.scrollbar.setTransition(duration);\n },\n destroy: function destroy(swiper) {\n swiper.scrollbar.destroy();\n }\n }\n };\n\n var Parallax = {\n setTransform: function setTransform(el, progress) {\n var swiper = this;\n var rtl = swiper.rtl;\n var $el = $(el);\n var rtlFactor = rtl ? -1 : 1;\n var p = $el.attr('data-swiper-parallax') || '0';\n var x = $el.attr('data-swiper-parallax-x');\n var y = $el.attr('data-swiper-parallax-y');\n var scale = $el.attr('data-swiper-parallax-scale');\n var opacity = $el.attr('data-swiper-parallax-opacity');\n\n if (x || y) {\n x = x || '0';\n y = y || '0';\n } else if (swiper.isHorizontal()) {\n x = p;\n y = '0';\n } else {\n y = p;\n x = '0';\n }\n\n if (x.indexOf('%') >= 0) {\n x = parseInt(x, 10) * progress * rtlFactor + \"%\";\n } else {\n x = x * progress * rtlFactor + \"px\";\n }\n\n if (y.indexOf('%') >= 0) {\n y = parseInt(y, 10) * progress + \"%\";\n } else {\n y = y * progress + \"px\";\n }\n\n if (typeof opacity !== 'undefined' && opacity !== null) {\n var currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));\n $el[0].style.opacity = currentOpacity;\n }\n\n if (typeof scale === 'undefined' || scale === null) {\n $el.transform(\"translate3d(\" + x + \", \" + y + \", 0px)\");\n } else {\n var currentScale = scale - (scale - 1) * (1 - Math.abs(progress));\n $el.transform(\"translate3d(\" + x + \", \" + y + \", 0px) scale(\" + currentScale + \")\");\n }\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n var $el = swiper.$el,\n slides = swiper.slides,\n progress = swiper.progress,\n snapGrid = swiper.snapGrid;\n $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (el) {\n swiper.parallax.setTransform(el, progress);\n });\n slides.each(function (slideEl, slideIndex) {\n var slideProgress = slideEl.progress;\n\n if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {\n slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);\n }\n\n slideProgress = Math.min(Math.max(slideProgress, -1), 1);\n $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (el) {\n swiper.parallax.setTransform(el, slideProgress);\n });\n });\n },\n setTransition: function setTransition(duration) {\n if (duration === void 0) {\n duration = this.params.speed;\n }\n\n var swiper = this;\n var $el = swiper.$el;\n $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (parallaxEl) {\n var $parallaxEl = $(parallaxEl);\n var parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;\n if (duration === 0) parallaxDuration = 0;\n $parallaxEl.transition(parallaxDuration);\n });\n }\n };\n var Parallax$1 = {\n name: 'parallax',\n params: {\n parallax: {\n enabled: false\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n parallax: _extends({}, Parallax)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (!swiper.params.parallax.enabled) return;\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n },\n init: function init(swiper) {\n if (!swiper.params.parallax.enabled) return;\n swiper.parallax.setTranslate();\n },\n setTranslate: function setTranslate(swiper) {\n if (!swiper.params.parallax.enabled) return;\n swiper.parallax.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n if (!swiper.params.parallax.enabled) return;\n swiper.parallax.setTransition(duration);\n }\n }\n };
166\n\n var Zoom = {\n // Calc Scale From Multi-touches\n getDistanceBetweenTouches: function getDistanceBetweenTouches(e) {\n if (e.targetTouches.length < 2) return 1;\n var x1 = e.targetTouches[0].pageX;\n var y1 = e.targetTouches[0].pageY;\n var x2 = e.targetTouches[1].pageX;\n var y2 = e.targetTouches[1].pageY;\n var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));\n return distance;\n },\n // Events\n onGestureStart: function onGestureStart(e) {\n var swiper = this;\n var support = swiper.support;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n zoom.fakeGestureTouched = false;\n zoom.fakeGestureMoved = false;\n\n if (!support.gestures) {\n if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {\n return;\n }\n\n zoom.fakeGestureTouched = true;\n gesture.scaleStart = Zoom.getDistanceBetweenTouches(e);\n }\n\n if (!gesture.$slideEl || !gesture.$slideEl.length) {\n gesture.$slideEl = $(e.target).closest(\".\" + swiper.params.slideClass);\n if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');\n gesture.$imageWrapEl = gesture.$imageEl.parent(\".\" + params.containerClass);\n gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n\n if (gesture.$imageWrapEl.length === 0) {\n gesture.$imageEl = undefined;\n return;\n }\n }\n\n if (gesture.$imageEl) {\n gesture.$imageEl.transition(0);\n }\n\n swiper.zoom.isScaling = true;\n },\n onGestureChange: function onGestureChange(e) {\n var swiper = this;\n var support = swiper.support;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n\n if (!support.gestures) {\n if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {\n return;\n }\n\n zoom.fakeGestureMoved = true;\n gesture.scaleMove = Zoom.getDistanceBetweenTouches(e);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) {\n if (e.type === 'gesturechange') zoom.onGestureStart(e);\n return;\n }\n\n if (support.gestures) {\n zoom.scale = e.scale * zoom.currentScale;\n } else {\n zoom.scale = gesture.scaleMove / gesture.scaleStart * zoom.currentScale;\n }\n\n if (zoom.scale > gesture.maxRatio) {\n zoom.scale = gesture.maxRatio - 1 + Math.pow(zoom.scale - gesture.maxRatio + 1, 0.5);\n }\n\n if (zoom.scale < params.minRatio) {\n zoom.scale = params.minRatio + 1 - Math.pow(params.minRatio - zoom.scale + 1, 0.5);\n }\n\n gesture.$imageEl.transform(\"translate3d(0,0,0) scale(\" + zoom.scale + \")\");\n },\n onGestureEnd: function onGestureEnd(e) {\n var swiper = this;\n var device = swiper.device;\n var support = swiper.support;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n\n if (!support.gestures) {\n if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) {\n return;\n }\n\n if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2 && !device.android) {\n return;\n }\n\n zoom.fakeGestureTouched = false;\n zoom.fakeGestureMoved = false;\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);\n gesture.$imageEl.transition(swiper.params.speed).transform(\"translate3d(0,0,0) scale(\" + zoom.scale + \")\");\n zoom.currentScale = zoom.scale;\n zoom.isScaling = false;\n if (zoom.scale === 1) gesture.$slideEl = undefined;\n },\n onTouchStart: function onTouchStart(e) {\n var swiper = this;\n var device = swiper.device;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture,\n image = zoom.image;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n if (image.isTouched) return;\n if (device.android && e.cancelable) e.preventDefault();\n image.isTouched = true;\n image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n },\n onTouchMove: function onTouchMove(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture,\n image = zoom.image,\n velocity = zoom.velocity;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n swiper.allowClick = false;\n if (!image.isTouched || !gesture.$slideEl) return;\n\n if (!image.isMoved) {\n image.width = gesture.$imageEl[0].offsetWidth;\n image.height = gesture.$imageEl[0].offsetHeight;\n image.startX = getTranslate(gesture.$imageWrapEl[0], 'x') || 0;\n image.startY = getTranslate(gesture.$imageWrapEl[0], 'y') || 0;\n gesture.slideWidth = gesture.$slideEl[0].offsetWidth;\n gesture.slideHeight = gesture.$slideEl[0].offsetHeight;\n gesture.$imageWrapEl.transition(0);\n\n if (swiper.rtl) {\n image.startX = -image.startX;\n image.startY = -image.startY;\n }\n } // Define if we need image drag\n\n\n var scaledWidth = image.width * zoom.scale;\n var scaledHeight = image.height * zoom.scale;\n if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n\n if (!image.isMoved && !zoom.isScaling) {\n if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {\n image.isTouched = false;\n return;\n }\n\n if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {\n image.isTouched = false;\n return;\n }\n }\n\n if (e.cancelable) {\n e.preventDefault();\n }\n\n e.stopPropagation();\n image.isMoved = true;\n image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX;\n image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY;
166\n\n if (image.currentX < image.minX) {\n image.currentX = image.minX + 1 - Math.pow(image.minX - image.currentX + 1, 0.8);\n }\n\n if (image.currentX > image.maxX) {\n image.currentX = image.maxX - 1 + Math.pow(image.currentX - image.maxX + 1, 0.8);\n }\n\n if (image.currentY < image.minY) {\n image.currentY = image.minY + 1 - Math.pow(image.minY - image.currentY + 1, 0.8);\n }\n\n if (image.currentY > image.maxY) {\n image.currentY = image.maxY - 1 + Math.pow(image.currentY - image.maxY + 1, 0.8);\n } // Velocity\n\n\n if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;\n if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;\n if (!velocity.prevTime) velocity.prevTime = Date.now();\n velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;\n velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;\n if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;\n if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;\n velocity.prevPositionX = image.touchesCurrent.x;\n velocity.prevPositionY = image.touchesCurrent.y;\n velocity.prevTime = Date.now();\n gesture.$imageWrapEl.transform(\"translate3d(\" + image.currentX + \"px, \" + image.currentY + \"px,0)\");\n },\n onTouchEnd: function onTouchEnd() {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture,\n image = zoom.image,\n velocity = zoom.velocity;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n\n if (!image.isTouched || !image.isMoved) {\n image.isTouched = false;\n image.isMoved = false;\n return;\n }\n\n image.isTouched = false;\n image.isMoved = false;\n var momentumDurationX = 300;\n var momentumDurationY = 300;\n var momentumDistanceX = velocity.x * momentumDurationX;\n var newPositionX = image.currentX + momentumDistanceX;\n var momentumDistanceY = velocity.y * momentumDurationY;\n var newPositionY = image.currentY + momentumDistanceY; // Fix duration\n\n if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);\n if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);\n var momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n image.currentX = newPositionX;\n image.currentY = newPositionY; // Define if we need image drag\n\n var scaledWidth = image.width * zoom.scale;\n var scaledHeight = image.height * zoom.scale;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);\n image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);\n gesture.$imageWrapEl.transition(momentumDuration).transform(\"translate3d(\" + image.currentX + \"px, \" + image.currentY + \"px,0)\");\n },\n onTransitionEnd: function onTransitionEnd() {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n\n if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) {\n if (gesture.$imageEl) {\n gesture.$imageEl.transform('translate3d(0,0,0) scale(1)');\n }\n\n if (gesture.$imageWrapEl) {\n gesture.$imageWrapEl.transform('translate3d(0,0,0)');\n }\n\n zoom.scale = 1;\n zoom.currentScale = 1;\n gesture.$slideEl = undefined;\n gesture.$imageEl = undefined;\n gesture.$imageWrapEl = undefined;\n }\n },\n // Toggle Zoom\n toggle: function toggle(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n\n if (zoom.scale && zoom.scale !== 1) {\n // Zoom Out\n zoom.out();\n } else {\n // Zoom In\n zoom.in(e);\n }\n },\n in: function _in(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n var params = swiper.params.zoom;\n var gesture = zoom.gesture,\n image = zoom.image;\n\n if (!gesture.$slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.$slideEl = swiper.$wrapperEl.children(\".\" + swiper.params.slideActiveClass);\n } else {\n gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n }\n\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');\n gesture.$imageWrapEl = gesture.$imageEl.parent(\".\" + params.containerClass);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n gesture.$slideEl.addClass(\"\" + params.zoomedSlideClass);\n var touchX;\n var touchY;\n var offsetX;\n var offsetY;\n var diffX;\n var diffY;\n var translateX;\n var translateY;\n var imageWidth;\n var imageHeight;\n var scaledWidth;\n var scaledHeight;\n var translateMinX;\n var translateMinY;\n var translateMaxX;\n var translateMaxY;\n var slideWidth;\n var slideHeight;\n\n if (typeof image.touchesStart.x === 'undefined' && e) {\n touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;\n touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;\n } else {\n touchX = image.touchesStart.x;\n touchY = image.touchesStart.y;\n }\n\n zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n\n if (e) {\n slideWidth = gesture.$slideEl[0].offsetWidth;\n slideHeight = gesture.$slideEl[0].offsetHeight;\n offsetX = gesture.$slideEl.offset().left;\n offsetY = gesture.$slideEl.offset().top;\n diffX = offsetX + slideWidth / 2 - touchX;\n diffY = offsetY + slideHeight / 2 - touchY;\n imageWidth = gesture.$imageEl[0].offsetWidth;\n imageHeight = gesture.$imageEl[0].offsetHeight;\n scaledWidth = imageWidth * zoom.scale;\n scaledHeight = imageHeight * zoom.scale;\n translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);\n translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);\n translateMaxX = -translateMinX;\n translateMaxY = -translateMinY;\n translateX = diffX * zoom.scale;\n translateY = diffY * zoom.scale;\n\n if (translateX < translateMinX) {\n translateX = translateMinX;\n }\n\n if (translateX > translateMaxX) {\n translateX = translateMaxX;\n }\n\n if (translateY < translateMinY) {\n translateY = translateMinY;\n }\n\n if (translateY > translateMaxY) {\n translateY = translateMaxY;\n }\n } else {\n translateX = 0;\n translateY = 0;\n }\n\n gesture.$imageWrapEl.transition(300).transform(\"translate3d(\" + translateX + \"px, \" + translateY + \"px,0)\");\n gesture.$imageEl.transition(300).transform(\"translate3d(0,
1660,0) scale(\" + zoom.scale + \")\");\n },\n out: function out() {\n var swiper = this;\n var zoom = swiper.zoom;\n var params = swiper.params.zoom;\n var gesture = zoom.gesture;\n\n if (!gesture.$slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.$slideEl = swiper.$wrapperEl.children(\".\" + swiper.params.slideActiveClass);\n } else {\n gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n }\n\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');\n gesture.$imageWrapEl = gesture.$imageEl.parent(\".\" + params.containerClass);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n zoom.scale = 1;\n zoom.currentScale = 1;\n gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)');\n gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)');\n gesture.$slideEl.removeClass(\"\" + params.zoomedSlideClass);\n gesture.$slideEl = undefined;\n },\n toggleGestures: function toggleGestures(method) {\n var swiper = this;\n var zoom = swiper.zoom;\n var selector = zoom.slideSelector,\n passive = zoom.passiveListener;\n swiper.$wrapperEl[method]('gesturestart', selector, zoom.onGestureStart, passive);\n swiper.$wrapperEl[method]('gesturechange', selector, zoom.onGestureChange, passive);\n swiper.$wrapperEl[method]('gestureend', selector, zoom.onGestureEnd, passive);\n },\n enableGestures: function enableGestures() {\n if (this.zoom.gesturesEnabled) return;\n this.zoom.gesturesEnabled = true;\n this.zoom.toggleGestures('on');\n },\n disableGestures: function disableGestures() {\n if (!this.zoom.gesturesEnabled) return;\n this.zoom.gesturesEnabled = false;\n this.zoom.toggleGestures('off');\n },\n // Attach/Detach Events\n enable: function enable() {\n var swiper = this;\n var support = swiper.support;\n var zoom = swiper.zoom;\n if (zoom.enabled) return;\n zoom.enabled = true;\n var passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n var activeListenerWithCapture = support.passiveListener ? {\n passive: false,\n capture: true\n } : true;\n var slideSelector = \".\" + swiper.params.slideClass;\n swiper.zoom.passiveListener = passiveListener;\n swiper.zoom.slideSelector = slideSelector; // Scale image\n\n if (support.gestures) {\n swiper.$wrapperEl.on(swiper.touchEvents.start, swiper.zoom.enableGestures, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.end, swiper.zoom.disableGestures, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.on(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);\n swiper.$wrapperEl.on(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);\n\n if (swiper.touchEvents.cancel) {\n swiper.$wrapperEl.on(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);\n }\n } // Move image\n\n\n swiper.$wrapperEl.on(swiper.touchEvents.move, \".\" + swiper.params.zoom.containerClass, zoom.onTouchMove, activeListenerWithCapture);\n },\n disable: function disable() {\n var swiper = this;\n var zoom = swiper.zoom;\n if (!zoom.enabled) return;\n var support = swiper.support;\n swiper.zoom.enabled = false;\n var passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n var activeListenerWithCapture = support.passiveListener ? {\n passive: false,\n capture: true\n } : true;\n var slideSelector = \".\" + swiper.params.slideClass; // Scale image\n\n if (support.gestures) {\n swiper.$wrapperEl.off(swiper.touchEvents.start, swiper.zoom.enableGestures, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.end, swiper.zoom.disableGestures, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.off(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);\n swiper.$wrapperEl.off(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);\n\n if (swiper.touchEvents.cancel) {\n swiper.$wrapperEl.off(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);\n }\n } // Move image\n\n\n swiper.$wrapperEl.off(swiper.touchEvents.move, \".\" + swiper.params.zoom.containerClass, zoom.onTouchMove, activeListenerWithCapture);\n }\n };\n var Zoom$1 = {\n name: 'zoom',\n params: {\n zoom: {\n enabled: false,\n maxRatio: 3,\n minRatio: 1,\n toggle: true,\n containerClass: 'swiper-zoom-container',\n zoomedSlideClass: 'swiper-slide-zoomed'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n zoom: _extends({\n enabled: false,\n scale: 1,\n currentScale: 1,\n isScaling: false,\n gesture: {\n $slideEl: undefined,\n slideWidth: undefined,\n slideHeight: undefined,\n $imageEl: undefined,\n $imageWrapEl: undefined,\n maxRatio: 3\n },\n image: {\n isTouched: undefined,\n isMoved: undefined,\n currentX: undefined,\n currentY: undefined,\n minX: undefined,\n minY: undefined,\n maxX: undefined,\n maxY: undefined,\n width: undefined,\n height: undefined,\n startX: undefined,\n startY: undefined,\n touchesStart: {},\n touchesCurrent: {}\n },\n velocity: {\n x: undefined,\n y: undefined,\n prevPositionX: undefined,\n prevPositionY: undefined,\n prevTime: undefined\n }\n }, Zoom)\n });\n var scale = 1;\n Object.defineProperty(swiper.zoom, 'scale', {\n get: function get() {\n return scale;\n },\n set: function set(value) {\n if (scale !== value) {\n var imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined;\n var slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined;\n swiper.emit('zoomChange', value, imageEl, slideEl);\n }\n\n scale = value;\n }\n });\n },\n on: {\n init: function init(swiper) {\n if (swiper.params.zoom.enabled) {\n swiper.zoom.enable();\n }\n },\n destroy: function destroy(swiper) {\n swiper.zoom.disable();\n },\n touchStart: function touchStart(swiper, e) {\n if (!swiper.zoom.enabled) return;\n swiper.zoom.onTouchStart(e);\n },\n touchEnd: function touchEnd(swiper, e) {\n if (!swiper.zoom.enabled) return;\n swiper.zoom.onTouchEnd(e);\n },\n doubleTap: function doubleTap(swiper, e) {\n if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {\n swiper.zoom.toggle(e);\n }\n },\n transitionEnd: function transitionEnd(swiper) {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled) {\n swiper.zoom.onTransitionEnd();\n }\n },\n slideChange: function slideChange(swiper) {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {\n swiper.zoom.onTransitionEnd();\n }\n }\n }\n };\n\n var Lazy = {\n loadInSlide: function loadInSlide(index, loadInDupl
166icate) {\n if (loadInDuplicate === void 0) {\n loadInDuplicate = true;\n }\n\n var swiper = this;\n var params = swiper.params.lazy;\n if (typeof index === 'undefined') return;\n if (swiper.slides.length === 0) return;\n var isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n var $slideEl = isVirtual ? swiper.$wrapperEl.children(\".\" + swiper.params.slideClass + \"[data-swiper-slide-index=\\\"\" + index + \"\\\"]\") : swiper.slides.eq(index);\n var $images = $slideEl.find(\".\" + params.elementClass + \":not(.\" + params.loadedClass + \"):not(.\" + params.loadingClass + \")\");\n\n if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {\n $images.push($slideEl[0]);\n }\n\n if ($images.length === 0) return;\n $images.each(function (imageEl) {\n var $imageEl = $(imageEl);\n $imageEl.addClass(params.loadingClass);\n var background = $imageEl.attr('data-background');\n var src = $imageEl.attr('data-src');\n var srcset = $imageEl.attr('data-srcset');\n var sizes = $imageEl.attr('data-sizes');\n var $pictureEl = $imageEl.parent('picture');\n swiper.loadImage($imageEl[0], src || background, srcset, sizes, false, function () {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper && !swiper.params || swiper.destroyed) return;\n\n if (background) {\n $imageEl.css('background-image', \"url(\\\"\" + background + \"\\\")\");\n $imageEl.removeAttr('data-background');\n } else {\n if (srcset) {\n $imageEl.attr('srcset', srcset);\n $imageEl.removeAttr('data-srcset');\n }\n\n if (sizes) {\n $imageEl.attr('sizes', sizes);\n $imageEl.removeAttr('data-sizes');\n }\n\n if ($pictureEl.length) {\n $pictureEl.children('source').each(function (sourceEl) {\n var $source = $(sourceEl);\n\n if ($source.attr('data-srcset')) {\n $source.attr('srcset', $source.attr('data-srcset'));\n $source.removeAttr('data-srcset');\n }\n });\n }\n\n if (src) {\n $imageEl.attr('src', src);\n $imageEl.removeAttr('data-src');\n }\n }\n\n $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);\n $slideEl.find(\".\" + params.preloaderClass).remove();\n\n if (swiper.params.loop && loadInDuplicate) {\n var slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');\n\n if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {\n var originalSlide = swiper.$wrapperEl.children(\"[data-swiper-slide-index=\\\"\" + slideOriginalIndex + \"\\\"]:not(.\" + swiper.params.slideDuplicateClass + \")\");\n swiper.lazy.loadInSlide(originalSlide.index(), false);\n } else {\n var duplicatedSlide = swiper.$wrapperEl.children(\".\" + swiper.params.slideDuplicateClass + \"[data-swiper-slide-index=\\\"\" + slideOriginalIndex + \"\\\"]\");\n swiper.lazy.loadInSlide(duplicatedSlide.index(), false);\n }\n }\n\n swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);\n\n if (swiper.params.autoHeight) {\n swiper.updateAutoHeight();\n }\n });\n swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);\n });\n },\n load: function load() {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl,\n swiperParams = swiper.params,\n slides = swiper.slides,\n activeIndex = swiper.activeIndex;\n var isVirtual = swiper.virtual && swiperParams.virtual.enabled;\n var params = swiperParams.lazy;\n var slidesPerView = swiperParams.slidesPerView;\n\n if (slidesPerView === 'auto') {\n slidesPerView = 0;\n }\n\n function slideExist(index) {\n if (isVirtual) {\n if ($wrapperEl.children(\".\" + swiperParams.slideClass + \"[data-swiper-slide-index=\\\"\" + index + \"\\\"]\").length) {\n return true;\n }\n } else if (slides[index]) return true;\n\n return false;\n }\n\n function slideIndex(slideEl) {\n if (isVirtual) {\n return $(slideEl).attr('data-swiper-slide-index');\n }\n\n return $(slideEl).index();\n }\n\n if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true;\n\n if (swiper.params.watchSlidesVisibility) {\n $wrapperEl.children(\".\" + swiperParams.slideVisibleClass).each(function (slideEl) {\n var index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index();\n swiper.lazy.loadInSlide(index);\n });\n } else if (slidesPerView > 1) {\n for (var i = activeIndex; i < activeIndex + slidesPerView; i += 1) {\n if (slideExist(i)) swiper.lazy.loadInSlide(i);\n }\n } else {\n swiper.lazy.loadInSlide(activeIndex);\n }\n\n if (params.loadPrevNext) {\n if (slidesPerView > 1 || params.loadPrevNextAmount && params.loadPrevNextAmount > 1) {\n var amount = params.loadPrevNextAmount;\n var spv = slidesPerView;\n var maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);\n var minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); // Next Slides\n\n for (var _i = activeIndex + slidesPerView; _i < maxIndex; _i += 1) {\n if (slideExist(_i)) swiper.lazy.loadInSlide(_i);\n } // Prev Slides\n\n\n for (var _i2 = minIndex; _i2 < activeIndex; _i2 += 1) {\n if (slideExist(_i2)) swiper.lazy.loadInSlide(_i2);\n }\n } else {\n var nextSlide = $wrapperEl.children(\".\" + swiperParams.slideNextClass);\n if (nextSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(nextSlide));\n var prevSlide = $wrapperEl.children(\".\" + swiperParams.slidePrevClass);\n if (prevSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(prevSlide));\n }\n }\n }\n };\n var Lazy$1 = {\n name: 'lazy',\n params: {\n lazy: {\n enabled: false,\n loadPrevNext: false,\n loadPrevNextAmount: 1,\n loadOnTransitionStart: false,\n elementClass: 'swiper-lazy',\n loadingClass: 'swiper-lazy-loading',\n loadedClass: 'swiper-lazy-loaded',\n preloaderClass: 'swiper-lazy-preloader'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n lazy: _extends({\n initialImageLoaded: false\n }, Lazy)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (swiper.params.lazy.enabled && swiper.params.preloadImages) {\n swiper.params.preloadImages = false;\n }\n },\n init: function init(swiper) {\n if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {\n swiper.lazy.load();\n }\n },\n scroll: function scroll(swiper) {\n if (swiper.params.freeMode && !swiper.params.freeModeSticky) {\n swiper.lazy.load();\n }\n },\n resize: function resize(swiper) {\n if (swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n },\n scrollbarDragMove: function scrollbarDragMove(swiper) {\n if (swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n },\n transitionStart: function transitionStart(swiper) {\n if (swiper.params.lazy.enabled) {\n if (swiper.params.lazy.loadOnTransitionStart || !swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded) {\n swiper.lazy.load();\n }\n }\n },\n transitionEnd: function transitionEnd(swiper) {\n if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {\n swiper.lazy.load();\n }\n },\n slideChange: function slideChange(swiper) {\n if (swiper.params.lazy.enabled && swiper.params.cssMode) {\n swiper.lazy.load();\n }\n }\n }\n };\n\n var Controller = {\n LinearSpline: function LinearSpline(x, y) {\n var binarySearch = function search() {\n var maxIndex;\n var minIndex;\n var guess;\n return function (array, val) {\n minIndex = -1;\n maxIndex = array.length;\n\n while (maxIndex - minIndex >
166 1) {\n guess = maxIndex + minIndex >> 1;\n\n if (array[guess] <= val) {\n minIndex = guess;\n } else {\n maxIndex = guess;\n }\n }\n\n return maxIndex;\n };\n }();\n\n this.x = x;\n this.y = y;\n this.lastIndex = x.length - 1; // Given an x value (x2), return the expected y2 value:\n // (x1,y1) is the known point before given value,\n // (x3,y3) is the known point after given value.\n\n var i1;\n var i3;\n\n this.interpolate = function interpolate(x2) {\n if (!x2) return 0; // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n\n i3 = binarySearch(this.x, x2);\n i1 = i3 - 1; // We have our indexes i1 & i3, so we can calculate already:\n // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n\n return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];\n };\n\n return this;\n },\n // xxx: for now i will just save one spline function to to\n getInterpolateFunction: function getInterpolateFunction(c) {\n var swiper = this;\n\n if (!swiper.controller.spline) {\n swiper.controller.spline = swiper.params.loop ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid);\n }\n },\n setTranslate: function setTranslate(_setTranslate, byController) {\n var swiper = this;\n var controlled = swiper.controller.control;\n var multiplier;\n var controlledTranslate;\n var Swiper = swiper.constructor;\n\n function setControlledTranslate(c) {\n // this will create an Interpolate function based on the snapGrids\n // x is the Grid of the scrolled scroller and y will be the controlled scroller\n // it makes sense to create this only once and recall it for the interpolation\n // the function does a lot of value caching for performance\n var translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;\n\n if (swiper.params.controller.by === 'slide') {\n swiper.controller.getInterpolateFunction(c); // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n // but it did not work out\n\n controlledTranslate = -swiper.controller.spline.interpolate(-translate);\n }\n\n if (!controlledTranslate || swiper.params.controller.by === 'container') {\n multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());\n controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();\n }\n\n if (swiper.params.controller.inverse) {\n controlledTranslate = c.maxTranslate() - controlledTranslate;\n }\n\n c.updateProgress(controlledTranslate);\n c.setTranslate(controlledTranslate, swiper);\n c.updateActiveIndex();\n c.updateSlidesClasses();\n }\n\n if (Array.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTranslate(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTranslate(controlled);\n }\n },\n setTransition: function setTransition(duration, byController) {\n var swiper = this;\n var Swiper = swiper.constructor;\n var controlled = swiper.controller.control;\n var i;\n\n function setControlledTransition(c) {\n c.setTransition(duration, swiper);\n\n if (duration !== 0) {\n c.transitionStart();\n\n if (c.params.autoHeight) {\n nextTick(function () {\n c.updateAutoHeight();\n });\n }\n\n c.$wrapperEl.transitionEnd(function () {\n if (!controlled) return;\n\n if (c.params.loop && swiper.params.controller.by === 'slide') {\n c.loopFix();\n }\n\n c.transitionEnd();\n });\n }\n }\n\n if (Array.isArray(controlled)) {\n for (i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTransition(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTransition(controlled);\n }\n }\n };\n var Controller$1 = {\n name: 'controller',\n params: {\n controller: {\n control: undefined,\n inverse: false,\n by: 'slide' // or 'container'\n\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n controller: _extends({\n control: swiper.params.controller.control\n }, Controller)\n });\n },\n on: {\n update: function update(swiper) {\n if (!swiper.controller.control) return;\n\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n resize: function resize(swiper) {\n if (!swiper.controller.control) return;\n\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n observerUpdate: function observerUpdate(swiper) {\n if (!swiper.controller.control) return;\n\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n setTranslate: function setTranslate(swiper, translate, byController) {\n if (!swiper.controller.control) return;\n swiper.controller.setTranslate(translate, byController);\n },\n setTransition: function setTransition(swiper, duration, byController) {\n if (!swiper.controller.control) return;\n swiper.controller.setTransition(duration, byController);\n }\n }\n };\n\n var A11y = {\n makeElFocusable: function makeElFocusable($el) {\n $el.attr('tabIndex', '0');\n return $el;\n },\n makeElNotFocusable: function makeElNotFocusable($el) {\n $el.attr('tabIndex', '-1');\n return $el;\n },\n addElRole: function addElRole($el, role) {\n $el.attr('role', role);\n return $el;\n },\n addElLabel: function addElLabel($el, label) {\n $el.attr('aria-label', label);\n return $el;\n },\n disableEl: function disableEl($el) {\n $el.attr('aria-disabled', true);\n return $el;\n },\n enableEl: function enableEl($el) {\n $el.attr('aria-disabled', false);\n return $el;\n },\n onEnterKey: function onEnterKey(e) {\n var swiper = this;\n var params = swiper.params.a11y;\n if (e.keyCode !== 13) return;\n var $targetEl = $(e.target);\n\n if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) {\n if (!(swiper.isEnd && !swiper.params.loop)) {\n swiper.slideNext();\n }\n\n if (swiper.isEnd) {\n swiper.a11y.notify(params.lastSlideMessage);\n } else {\n swiper.a11y.notify(params.nextSlideMessage);\n }\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) {\n if (!(swiper.isBeginning && !swiper.params.loop)) {\n swiper.slidePrev();\n }\n\n if (swiper.isBeginning) {\n swiper.a11y.notify(params.firstSlideMessage);\n } else {\n swiper.a11y.notify(params.prevSlideMessage);\n }\n }\n\n if (swiper.pagination && $targetEl.is(\".\" + swiper.params.pagination.bulletClass)) {\n $targetEl[0].click();\n }\n },\n notify: function notify(message) {\n var swiper = this;\n var notification = swiper.a11y.liveRegion;\n if (notification.length === 0) return;\n notification.html('');\n notification.html(message);\n }
166,\n updateNavigation: function updateNavigation() {\n var swiper = this;\n if (swiper.params.loop || !swiper.navigation) return;\n var _swiper$navigation = swiper.navigation,\n $nextEl = _swiper$navigation.$nextEl,\n $prevEl = _swiper$navigation.$prevEl;\n\n if ($prevEl && $prevEl.length > 0) {\n if (swiper.isBeginning) {\n swiper.a11y.disableEl($prevEl);\n swiper.a11y.makeElNotFocusable($prevEl);\n } else {\n swiper.a11y.enableEl($prevEl);\n swiper.a11y.makeElFocusable($prevEl);\n }\n }\n\n if ($nextEl && $nextEl.length > 0) {\n if (swiper.isEnd) {\n swiper.a11y.disableEl($nextEl);\n swiper.a11y.makeElNotFocusable($nextEl);\n } else {\n swiper.a11y.enableEl($nextEl);\n swiper.a11y.makeElFocusable($nextEl);\n }\n }\n },\n updatePagination: function updatePagination() {\n var swiper = this;\n var params = swiper.params.a11y;\n\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.bullets.each(function (bulletEl) {\n var $bulletEl = $(bulletEl);\n swiper.a11y.makeElFocusable($bulletEl);\n swiper.a11y.addElRole($bulletEl, 'button');\n swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/\\{\\{index\\}\\}/, $bulletEl.index() + 1));\n });\n }\n },\n init: function init() {\n var swiper = this;\n swiper.$el.append(swiper.a11y.liveRegion); // Navigation\n\n var params = swiper.params.a11y;\n var $nextEl;\n var $prevEl;\n\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n\n if ($nextEl) {\n swiper.a11y.makeElFocusable($nextEl);\n swiper.a11y.addElRole($nextEl, 'button');\n swiper.a11y.addElLabel($nextEl, params.nextSlideMessage);\n $nextEl.on('keydown', swiper.a11y.onEnterKey);\n }\n\n if ($prevEl) {\n swiper.a11y.makeElFocusable($prevEl);\n swiper.a11y.addElRole($prevEl, 'button');\n swiper.a11y.addElLabel($prevEl, params.prevSlideMessage);\n $prevEl.on('keydown', swiper.a11y.onEnterKey);\n } // Pagination\n\n\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.$el.on('keydown', \".\" + swiper.params.pagination.bulletClass, swiper.a11y.onEnterKey);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) swiper.a11y.liveRegion.remove();\n var $nextEl;\n var $prevEl;\n\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n\n if ($nextEl) {\n $nextEl.off('keydown', swiper.a11y.onEnterKey);\n }\n\n if ($prevEl) {\n $prevEl.off('keydown', swiper.a11y.onEnterKey);\n } // Pagination\n\n\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.$el.off('keydown', \".\" + swiper.params.pagination.bulletClass, swiper.a11y.onEnterKey);\n }\n }\n };\n var A11y$1 = {\n name: 'a11y',\n params: {\n a11y: {\n enabled: true,\n notificationClass: 'swiper-notification',\n prevSlideMessage: 'Previous slide',\n nextSlideMessage: 'Next slide',\n firstSlideMessage: 'This is the first slide',\n lastSlideMessage: 'This is the last slide',\n paginationBulletMessage: 'Go to slide {{index}}'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n a11y: _extends(_extends({}, A11y), {}, {\n liveRegion: $(\"<span class=\\\"\" + swiper.params.a11y.notificationClass + \"\\\" aria-live=\\\"assertive\\\" aria-atomic=\\\"true\\\"></span>\")\n })\n });\n },\n on: {\n init: function init(swiper) {\n if (!swiper.params.a11y.enabled) return;\n swiper.a11y.init();\n swiper.a11y.updateNavigation();\n },\n toEdge: function toEdge(swiper) {\n if (!swiper.params.a11y.enabled) return;\n swiper.a11y.updateNavigation();\n }
166,\n fromEdge: function fromEdge(swiper) {\n if (!swiper.params.a11y.enabled) return;\n swiper.a11y.updateNavigation();\n },\n paginationUpdate: function paginationUpdate(swiper) {\n if (!swiper.params.a11y.enabled) return;\n swiper.a11y.updatePagination();\n },\n destroy: function destroy(swiper) {\n if (!swiper.params.a11y.enabled) return;\n swiper.a11y.destroy();\n }\n }\n };\n\n var History = {\n init: function init() {\n var swiper = this;\n var window = getWindow();\n if (!swiper.params.history) return;\n\n if (!window.history || !window.history.pushState) {\n swiper.params.history.enabled = false;\n swiper.params.hashNavigation.enabled = true;\n return;\n }\n\n var history = swiper.history;\n history.initialized = true;\n history.paths = History.getPathValues(swiper.params.url);\n if (!history.paths.key && !history.paths.value) return;\n history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit);\n\n if (!swiper.params.history.replaceState) {\n window.addEventListener('popstate', swiper.history.setHistoryPopState);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n var window = getWindow();\n\n if (!swiper.params.history.replaceState) {\n window.removeEventListener('popstate', swiper.history.setHistoryPopState);\n }\n },\n setHistoryPopState: function setHistoryPopState() {\n var swiper = this;\n swiper.history.paths = History.getPathValues(swiper.params.url);\n swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false);\n },\n getPathValues: function getPathValues(urlOverride) {\n var window = getWindow();\n var location;\n\n if (urlOverride) {\n location = new URL(urlOverride);\n } else {\n location = window.location;\n }\n\n var pathArray = location.pathname.slice(1).split('/').filter(function (part) {\n return part !== '';\n });\n var total = pathArray.length;\n var key = pathArray[total - 2];\n var value = pathArray[total - 1];\n return {\n key: key,\n value: value\n };\n },\n setHistory: function setHistory(key, index) {\n var swiper = this;\n var window = getWindow();\n if (!swiper.history.initialized || !swiper.params.history.enabled) return;\n var location;\n\n if (swiper.params.url) {\n location = new URL(swiper.params.url);\n } else {\n location = window.location;\n }\n\n var slide = swiper.slides.eq(index);\n var value = History.slugify(slide.attr('data-history'));\n\n if (!location.pathname.includes(key)) {\n value = key + \"/\" + value;\n }\n\n var currentState = window.history.state;\n\n if (currentState && currentState.value === value) {\n return;\n }\n\n if (swiper.params.history.replaceState) {\n window.history.replaceState({\n value: value\n }, null, value);\n } else {\n window.history.pushState({\n value: value\n }, null, value);\n }\n },\n slugify: function slugify(text) {\n return text.toString().replace(/\\s+/g, '-').replace(/[^\\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');\n },\n scrollToSlide: function scrollToSlide(speed, value, runCallbacks) {\n var swiper = this;\n\n if (value) {\n for (var i = 0, length = swiper.slides.length; i < length; i += 1) {\n var slide = swiper.slides.eq(i);\n var slideHistory = History.slugify(slide.attr('data-history'));\n\n if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n var index = slide.index();\n swiper.slideTo(index, speed, runCallbacks);\n }\n }\n } else {\n swiper.slideTo(0, speed, runCallbacks);\n }\n }\n };\n var History$1 = {\n name: 'history',\n params: {\n history: {\n enabled: false,\n replaceState: false,\n key: 'slides'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n history: _extends({}, History)\n });\n },\n on: {\n init: function init(swiper) {\n if (swiper.params.history.enabled) {\n swiper.history.init();\n }\n },\n destroy: function destroy(swiper) {\n if (swiper.params.history.enabled) {\n swiper.history.destroy();\n }\n },\n transitionEnd: function transitionEnd(swiper) {\n if (swiper.history.initialized) {\n swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex);\n }\n },\n slideChange: function slideChange(swiper) {\n if (swiper.history.initialized && swiper.params.cssMode) {\n swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex);\n }\n }\n }\n };\n\n var HashNavigation = {\n onHashCange: function onHashCange() {\n var swiper = this;\n var document = getDocument();\n swiper.emit('hashChange');\n var newHash = document.location.hash.replace('#', '');\n var activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash');\n\n if (newHash !== activeSlideHash) {\n var newIndex = swiper.$wrapperEl.children(\".\" + swiper.params.slideClass + \"[data-hash=\\\"\" + newHash + \"\\\"]\").index();\n if (typeof newIndex === 'undefined') return;\n swiper.slideTo(newIndex);\n }\n },\n setHash: function setHash() {\n var swiper = this;\n var window = getWindow();\n var document = getDocument();\n if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) return;\n\n if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {\n window.history.replaceState(null, null, \"#\" + swiper.slides.eq(swiper.activeIndex).attr('data-hash') || '');\n swiper.emit('hashSet');\n } else {\n var slide = swiper.slides.eq(swiper.activeIndex);\n var hash = slide.attr('data-hash') || slide.attr('data-history');\n document.location.hash = hash || '';\n swiper.emit('hashSet');\n }\n }
166,\n init: function init() {\n var swiper = this;\n var document = getDocument();\n var window = getWindow();\n if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;\n swiper.hashNavigation.initialized = true;\n var hash = document.location.hash.replace('#', '');\n\n if (hash) {\n var speed = 0;\n\n for (var i = 0, length = swiper.slides.length; i < length; i += 1) {\n var slide = swiper.slides.eq(i);\n var slideHash = slide.attr('data-hash') || slide.attr('data-history');\n\n if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n var index = slide.index();\n swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true);\n }\n }\n }\n\n if (swiper.params.hashNavigation.watchState) {\n $(window).on('hashchange', swiper.hashNavigation.onHashCange);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n var window = getWindow();\n\n if (swiper.params.hashNavigation.watchState) {\n $(window).off('hashchange', swiper.hashNavigation.onHashCange);\n }\n }\n };\n var HashNavigation$1 = {\n name: 'hash-navigation',\n params: {\n hashNavigation: {\n enabled: false,\n replaceState: false,\n watchState: false\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n hashNavigation: _extends({\n initialized: false\n }, HashNavigation)\n });\n },\n on: {\n init: function init(swiper) {\n if (swiper.params.hashNavigation.enabled) {\n swiper.hashNavigation.init();\n }\n },\n destroy: function destroy(swiper) {\n if (swiper.params.hashNavigation.enabled) {\n swiper.hashNavigation.destroy();\n }\n },\n transitionEnd: function transitionEnd(swiper) {\n if (swiper.hashNavigation.initialized) {\n swiper.hashNavigation.setHash();\n }\n },\n slideChange: function slideChange(swiper) {\n if (swiper.hashNavigation.initialized && swiper.params.cssMode) {\n swiper.hashNavigation.setHash();\n }\n }\n }\n };\n\n var Autoplay = {\n run: function run() {\n var swiper = this;\n var $activeSlideEl = swiper.slides.eq(swiper.activeIndex);\n var delay = swiper.params.autoplay.delay;\n\n if ($activeSlideEl.attr('data-swiper-autoplay')) {\n delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;\n }\n\n clearTimeout(swiper.autoplay.timeout);\n swiper.autoplay.timeout = nextTick(function () {\n if (swiper.params.autoplay.reverseDirection) {\n if (swiper.params.loop) {\n swiper.loopFix();\n swiper.slidePrev(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.isBeginning) {\n swiper.slidePrev(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else {\n swiper.autoplay.stop();\n }\n } else if (swiper.params.loop) {\n swiper.loopFix();\n swiper.slideNext(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.isEnd) {\n swiper.slideNext(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(0, swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else {\n swiper.autoplay.stop();\n }\n\n if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();\n }, delay);\n },\n start: function start() {\n var swiper = this;\n if (typeof swiper.autoplay.timeout !== 'undefined') return false;\n if (swiper.autoplay.running) return false;\n swiper.autoplay.running = true;\n swiper.emit('autoplayStart');\n swiper.autoplay.run();\n return true;\n },\n stop: function stop() {\n var swiper = this;\n if (!swiper.autoplay.running) return false;\n if (typeof swiper.autoplay.timeout === 'undefined') return false;\n\n if (swiper.autoplay.timeout) {\n clearTimeout(swiper.autoplay.timeout);\n swiper.autoplay.timeout = undefined;\n }\n\n swiper.autoplay.running = false;\n swiper.emit('autoplayStop');\n return true;\n },\n pause: function pause(speed) {\n var swiper = this;\n if (!swiper.autoplay.running) return;\n if (swiper.autoplay.paused) return;\n if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);\n swiper.autoplay.paused = true;\n\n if (speed === 0 || !swiper.params.autoplay.waitForTransition) {\n swiper.autoplay.paused = false;\n swiper.autoplay.run();\n } else {\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);\n }\n },\n onVisibilityChange: function onVisibilityChange() {\n var swiper = this;\n var document = getDocument();\n\n if (document.visibilityState === 'hidden' && swiper.autoplay.running) {\n swiper.autoplay.pause();\n }\n\n if (document.visibilityState === 'visible' && swiper.autoplay.paused) {\n swiper.autoplay.run();\n swiper.autoplay.paused = false;\n }\n },\n onTransitionEnd: function onTransitionEnd(e) {\n var swiper = this;\n if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;\n if (e.target !== swiper.$wrapperEl[0]) return;\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);\n swiper.autoplay.paused = false;\n\n if (!swiper.autoplay.running) {\n swiper.autoplay.stop();\n } else {\n swiper.autoplay.run();\n }\n }\n };
166\n var Autoplay$1 = {\n name: 'autoplay',\n params: {\n autoplay: {\n enabled: false,\n delay: 3000,\n waitForTransition: true,\n disableOnInteraction: true,\n stopOnLastSlide: false,\n reverseDirection: false\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n autoplay: _extends(_extends({}, Autoplay), {}, {\n running: false,\n paused: false\n })\n });\n },\n on: {\n init: function init(swiper) {\n if (swiper.params.autoplay.enabled) {\n swiper.autoplay.start();\n var document = getDocument();\n document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);\n }\n },\n beforeTransitionStart: function beforeTransitionStart(swiper, speed, internal) {\n if (swiper.autoplay.running) {\n if (internal || !swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.pause(speed);\n } else {\n swiper.autoplay.stop();\n }\n }\n },\n sliderFirstMove: function sliderFirstMove(swiper) {\n if (swiper.autoplay.running) {\n if (swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.stop();\n } else {\n swiper.autoplay.pause();\n }\n }\n },\n touchEnd: function touchEnd(swiper) {\n if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.run();\n }\n },\n destroy: function destroy(swiper) {\n if (swiper.autoplay.running) {\n swiper.autoplay.stop();\n }\n\n var document = getDocument();\n document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);\n }\n }\n };\n\n var Fade = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var slides = swiper.slides;\n\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = swiper.slides.eq(i);\n var offset = $slideEl[0].swiperSlideOffset;\n var tx = -offset;\n if (!swiper.params.virtualTranslate) tx -= swiper.translate;\n var ty = 0;\n\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n }\n\n var slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl[0].progress), 0) : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0);\n $slideEl.css({\n opacity: slideOpacity\n }).transform(\"translate3d(\" + tx + \"px, \" + ty + \"px, 0px)\");\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var slides = swiper.slides,\n $wrapperEl = swiper.$wrapperEl;\n slides.transition(duration);\n\n if (swiper.params.virtualTranslate && duration !== 0) {\n var eventTriggered = false;\n slides.transitionEnd(function () {\n if (eventTriggered) return;\n if (!swiper || swiper.destroyed) return;\n eventTriggered = true;\n swiper.animating = false;\n var triggerEvents = ['webkitTransitionEnd', 'transitionend'];\n\n for (var i = 0; i < triggerEvents.length; i += 1) {\n $wrapperEl.trigger(triggerEvents[i]);\n }\n });\n }\n }\n };\n var EffectFade = {\n name: 'effect-fade',\n params: {\n fadeEffect: {\n crossFade: false\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n fadeEffect: _extends({}, Fade)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (swiper.params.effect !== 'fade') return;\n swiper.classNames.push(swiper.params.containerModifierClass + \"fade\");\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: true\n };\n extend$1(swiper.params, overwriteParams);\n extend$1(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate(swiper) {\n if (swiper.params.effect !== 'fade') return;\n swiper.fadeEffect.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n if (swiper.params.effect !== 'fade') return;\n swiper.fadeEffect.setTransition(duration);\n }\n }\n };\n\n var Cube = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var $el = swiper.$el,\n $wrapperEl = swiper.$wrapperEl,\n slides = swiper.slides,\n swiperWidth = swiper.width,\n swiperHeight = swiper.height,\n rtl = swiper.rtlTranslate,\n swiperSize = swiper.size,\n browser = swiper.browser;\n var params = swiper.params.cubeEffect;\n var isHorizontal = swiper.isHorizontal();\n var isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n var wrapperRotate = 0;\n var $cubeShadowEl;\n\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');\n\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = $('<
166div class=\"swiper-cube-shadow\"></div>');\n $wrapperEl.append($cubeShadowEl);\n }\n\n $cubeShadowEl.css({\n height: swiperWidth + \"px\"\n });\n } else {\n $cubeShadowEl = $el.find('.swiper-cube-shadow');\n\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = $('<div class=\"swiper-cube-shadow\"></div>');\n $el.append($cubeShadowEl);\n }\n }\n }\n\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = slides.eq(i);\n var slideIndex = i;\n\n if (isVirtual) {\n slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10);\n }\n\n var slideAngle = slideIndex * 90;\n var round = Math.floor(slideAngle / 360);\n\n if (rtl) {\n slideAngle = -slideAngle;\n round = Math.floor(-slideAngle / 360);\n }\n\n var progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n var tx = 0;\n var ty = 0;\n var tz = 0;\n\n if (slideIndex % 4 === 0) {\n tx = -round * 4 * swiperSize;\n tz = 0;\n } else if ((slideIndex - 1) % 4 === 0) {\n tx = 0;\n tz = -round * 4 * swiperSize;\n } else if ((slideIndex - 2) % 4 === 0) {\n tx = swiperSize + round * 4 * swiperSize;\n tz = swiperSize;\n } else if ((slideIndex - 3) % 4 === 0) {\n tx = -swiperSize;\n tz = 3 * swiperSize + swiperSize * 4 * round;\n }\n\n if (rtl) {\n tx = -tx;\n }\n\n if (!isHorizontal) {\n ty = tx;\n tx = 0;\n }\n\n var transform = \"rotateX(\" + (isHorizontal ? 0 : -slideAngle) + \"deg) rotateY(\" + (isHorizontal ? slideAngle : 0) + \"deg) translate3d(\" + tx + \"px, \" + ty + \"px, \" + tz + \"px)\";\n\n if (progress <= 1 && progress > -1) {\n wrapperRotate = slideIndex * 90 + progress * 90;\n if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;\n }\n\n $slideEl.transform(transform);\n\n if (params.slideShadows) {\n // Set shadows\n var shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if (shadowBefore.length === 0) {\n shadowBefore = $(\"<div class=\\\"swiper-slide-shadow-\" + (isHorizontal ? 'left' : 'top') + \"\\\"></div>\");\n $slideEl.append(shadowBefore);\n }\n\n if (shadowAfter.length === 0) {\n shadowAfter = $(\"<div class=\\\"swiper-slide-shadow-\" + (isHorizontal ? 'right' : 'bottom') + \"\\\"></div>\");\n $slideEl.append(shadowAfter);\n }\n\n if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n }\n }\n\n $wrapperEl.css({\n '-webkit-transform-origin': \"50% 50% -\" + swiperSize / 2 + \"px\",\n '-moz-transform-origin': \"50% 50% -\" + swiperSize / 2 + \"px\",\n '-ms-transform-origin': \"50% 50% -\" + swiperSize / 2 + \"px\",\n 'transform-origin': \"50% 50% -\" + swiperSize / 2 + \"px\"\n });\n\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl.transform(\"translate3d(0px, \" + (swiperWidth / 2 + params.shadowOffset) + \"px, \" + -swiperWidth / 2 + \"px) rotateX(90deg) rotateZ(0deg) scale(\" + params.shadowScale + \")\");\n } else {\n var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n var scale1 = params.shadowScale;\n var scale2 = params.shadowScale / multiplier;\n var offset = params.shadowOffset;\n $cubeShadowEl.transform(\"scale3d(\" + scale1 + \", 1, \" + scale2 + \") translate3d(0px, \" + (swiperHeight / 2 + offset) + \"px, \" + -swiperHeight / 2 / scale2 + \"px) rotateX(-90deg)\");\n }\n }\n\n var zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;\n $wrapperEl.transform(\"translate3d(0px,0,\" + zFactor + \"px) rotateX(\" + (swiper.isHorizontal() ? 0 : wrapperRotate) + \"deg) rotateY(\" + (swiper.isHorizontal() ? -wrapperRotate : 0) + \"deg)\");\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var $el = swiper.$el,\n slides = swiper.slides;\n slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n\n if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {\n $el.find('.swiper-cube-shadow').transition(duration);\n }\n }\n };\n var EffectCube = {\n name: 'effect-cube',\n params: {\n cubeEffect: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n cubeEffect: _extends({}
166, Cube)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (swiper.params.effect !== 'cube') return;\n swiper.classNames.push(swiper.params.containerModifierClass + \"cube\");\n swiper.classNames.push(swiper.params.containerModifierClass + \"3d\");\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n resistanceRatio: 0,\n spaceBetween: 0,\n centeredSlides: false,\n virtualTranslate: true\n };\n extend$1(swiper.params, overwriteParams);\n extend$1(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate(swiper) {\n if (swiper.params.effect !== 'cube') return;\n swiper.cubeEffect.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n if (swiper.params.effect !== 'cube') return;\n swiper.cubeEffect.setTransition(duration);\n }\n }\n };\n\n var Flip = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var slides = swiper.slides,\n rtl = swiper.rtlTranslate;\n\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = slides.eq(i);\n var progress = $slideEl[0].progress;\n\n if (swiper.params.flipEffect.limitRotation) {\n progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n }\n\n var offset = $slideEl[0].swiperSlideOffset;\n var rotate = -180 * progress;\n var rotateY = rotate;\n var rotateX = 0;\n var tx = -offset;\n var ty = 0;\n\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n rotateX = -rotateY;\n rotateY = 0;\n } else if (rtl) {\n rotateY = -rotateY;\n }\n\n $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length;\n\n if (swiper.params.flipEffect.slideShadows) {\n // Set shadows\n var shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if (shadowBefore.length === 0) {\n shadowBefore = $(\"<div class=\\\"swiper-slide-shadow-\" + (swiper.isHorizontal() ? 'left' : 'top') + \"\\\"></div>\");\n $slideEl.append(shadowBefore);\n }\n\n if (shadowAfter.length === 0) {\n shadowAfter = $(\"<div class=\\\"swiper-slide-shadow-\" + (swiper.isHorizontal() ? 'right' : 'bottom') + \"\\\"></div>\");\n $slideEl.append(shadowAfter);\n }\n\n if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n }\n\n $slideEl.transform(\"translate3d(\" + tx + \"px, \" + ty + \"px, 0px) rotateX(\" + rotateX + \"deg) rotateY(\" + rotateY + \"deg)\");\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var slides = swiper.slides,\n activeIndex = swiper.activeIndex,\n $wrapperEl = swiper.$wrapperEl;\n slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n\n if (swiper.params.virtualTranslate && duration !== 0) {\n var eventTriggered = false; // eslint-disable-next-line\n\n slides.eq(activeIndex).transitionEnd(function onTransitionEnd() {\n if (eventTriggered) return;\n if (!swiper || swiper.destroyed) return; // if (!$(this).hasClass(swiper.params.slideActiveClass)) return;\n\n eventTriggered = true;\n swiper.animating = false;\n var triggerEvents = ['webkitTransitionEnd', 'transitionend'];\n\n for (var i = 0; i < triggerEvents.length; i += 1) {\n $wrapperEl.trigger(triggerEvents[i]);\n }\n });\n }\n }\n };\n var EffectFlip = {\n name: 'effect-flip',\n params: {\n flipEffect: {\n slideShadows: true,\n limitRotation: true\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n flipEffect: _extends({}, Flip)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (swiper.params.effect !== 'flip') return;\n swiper.classNames.push(swiper.params.containerModifierClass + \"flip\");\n swiper.classNames.push(swiper.params.containerModifierClass + \"3d\");\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: true\n };\n extend$1(swiper.params, overwriteParams);\n extend$1(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate(swiper) {\n if (swiper.params.effect !== 'flip') return;\n swiper.flipEffect.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n if (swiper.params.effect !== 'flip') return;\n swiper.flipEffect.setTransition(duration);\n }\n }\n };\n\n var Coverflow = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var swiperWidth = swiper.width,\n swiperHeight = swiper.height,\n slides = swiper.slides,\n slidesSizesGrid = swiper.slidesSizesGrid;\n var params = swiper.params.coverflowEffect;\n var isHorizontal = swiper.isHorizontal();\n var transform = swiper.translate;\n var center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;\n var rotate = isHorizontal ? params.rotate : -params.rotate;\n var translate = params.depth; // Each slide offset from center\n\n for (var i = 0, length = slides.length; i < length; i += 1) {\n var $slideEl = slides.eq(i);\n var slideSize = slidesSizesGrid[i];\n var slideOffset = $slideEl[0].swiperSlideOffset;\n var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;\n var rotateY = isHorizontal ? rotate * offsetMultiplier : 0;\n var rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0\n\n var translateZ = -translate * Math.abs(offsetMultiplier);\n var stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders\n\n if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {\n stretch = parseFloat(params.stretch) / 100 * slideSize;\n }\n\n var translateY = isHorizontal ? 0 : stretch * offsetMultiplier;\n var translateX = isHorizontal ? stretch * offsetMultiplier : 0;\n var scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values\n\n if (Math.abs(translateX) < 0.001) translateX = 0;\n if (Math.abs(translateY) < 0.001) translateY = 0;\n if (Math.abs(translateZ) < 0.001) translateZ = 0;\n if (Math.abs(rotateY) < 0.001) rotateY = 0;\n if (Math.abs(rotateX) < 0.001) rotateX = 0;\n if (Math.abs(scale) < 0.001) scale = 0;\n var slideTransform = \"translate3d(\" + translateX + \"px,\" + translateY + \"px,\" + translateZ + \"px) rotateX(\" + rotateX + \"deg) rotateY(\" + rotateY + \"deg) scale(\" + scale + \")\";\n $slideEl.transform(slideTransform);\n $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n\n if (params.slideShadows) {\n // Set shadows\n var $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if ($shadowBeforeEl.length === 0) {\n $shadowBeforeEl = $(\"<div class=\\\"swiper-slide-shadow-\" + (isHorizontal ? 'left' : 'top') + \"\\\"></div>\");\n $slideEl.append($shadowBeforeEl);\n }\n\n if ($shadowAfterEl.length === 0) {\n $shadowAfterEl = $(\"<div class=\\\"swiper-slide-shadow-\" + (isHorizontal ? 'right' : 'bottom') + \"\\\"></div>\");\n $slideEl.append($shadowAfterEl);\n }\n\n if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;\n }\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n swiper.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n }\n };\n var EffectCoverflow = {\n name: 'effect-coverflow',\n params: {\n coverflowEffect: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n scale: 1,\n modifier: 1,\n slideShadows: true\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n coverflowEffect: _extends({}
166, Coverflow)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n if (swiper.params.effect !== 'coverflow') return;\n swiper.classNames.push(swiper.params.containerModifierClass + \"coverflow\");\n swiper.classNames.push(swiper.params.containerModifierClass + \"3d\");\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n },\n setTranslate: function setTranslate(swiper) {\n if (swiper.params.effect !== 'coverflow') return;\n swiper.coverflowEffect.setTranslate();\n },\n setTransition: function setTransition(swiper, duration) {\n if (swiper.params.effect !== 'coverflow') return;\n swiper.coverflowEffect.setTransition(duration);\n }\n }\n };\n\n var Thumbs = {\n init: function init() {\n var swiper = this;\n var thumbsParams = swiper.params.thumbs;\n if (swiper.thumbs.initialized) return false;\n swiper.thumbs.initialized = true;\n var SwiperClass = swiper.constructor;\n\n if (thumbsParams.swiper instanceof SwiperClass) {\n swiper.thumbs.swiper = thumbsParams.swiper;\n extend$1(swiper.thumbs.swiper.originalParams, {\n watchSlidesProgress: true,\n slideToClickedSlide: false\n });\n extend$1(swiper.thumbs.swiper.params, {\n watchSlidesProgress: true,\n slideToClickedSlide: false\n });\n } else if (isObject$1(thumbsParams.swiper)) {\n swiper.thumbs.swiper = new SwiperClass(extend$1({}, thumbsParams.swiper, {\n watchSlidesVisibility: true,\n watchSlidesProgress: true,\n slideToClickedSlide: false\n }));\n swiper.thumbs.swiperCreated = true;\n }\n\n swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);\n swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick);\n return true;\n },\n onThumbClick: function onThumbClick() {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) return;\n var clickedIndex = thumbsSwiper.clickedIndex;\n var clickedSlide = thumbsSwiper.clickedSlide;\n if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return;\n if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;\n var slideToIndex;\n\n if (thumbsSwiper.params.loop) {\n slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n } else {\n slideToIndex = clickedIndex;\n }\n\n if (swiper.params.loop) {\n var currentIndex = swiper.activeIndex;\n\n if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n currentIndex = swiper.activeIndex;\n }\n\n var prevIndex = swiper.slides.eq(currentIndex).prevAll(\"[data-swiper-slide-index=\\\"\" + slideToIndex + \"\\\"]\").eq(0).index();\n var nextIndex = swiper.slides.eq(currentIndex).nextAll(\"[data-swiper-slide-index=\\\"\" + slideToIndex + \"\\\"]\").eq(0).index();\n if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;else slideToIndex = prevIndex;\n }\n\n swiper.slideTo(slideToIndex);\n },\n update: function update(initial) {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) return;\n var slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;\n var autoScrollOffset = swiper.params.thumbs.autoScrollOffset;\n var useOffset = autoScrollOffset && !thumbsSwiper.params.loop;\n\n if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {\n var currentThumbsIndex = thumbsSwiper.activeIndex;\n var newThumbsIndex;\n var direction;\n\n if (thumbsSwiper.params.loop) {\n if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) {\n thumbsSwiper.loopFix(); // eslint-disable-next-line\n\n thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;\n currentThumbsIndex = thumbsSwiper.activeIndex;\n } // Find actual thumbs index to slide to\n\n\n var prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(\"[data-swiper-slide-index=\\\"\" + swiper.realIndex + \"\\\"]\").eq(0).index();\n var nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(\"[data-swiper-slide-index=\\\"\" + swiper.realIndex + \"\\\"]\").eq(0).index();\n if (typeof prevThumbsIndex === 'undefined') newThumbsIndex = nextThumbsIndex;else if (typeof nextThumbsIndex === 'undefined') newThumbsIndex = prevThumbsIndex;else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) newThumbsIndex = currentThumbsIndex;else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) newThumbsIndex = nextThumbsIndex;else newThumbsIndex = prevThumbsIndex;\n direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';\n } else {\n newThumbsIndex = swiper.realIndex;\n direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';\n }\n\n if (useOffset) {\n newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;\n }\n\n if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {\n if (thumbsSwiper.params.centeredSlides) {\n if (newThumbsIndex > currentThumbsIndex) {\n newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;\n } else {\n newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;\n }\n } else if (newThumbsIndex > currentThumbsIndex) {\n newThumbsIndex = newThumbsIndex - slidesPerView + 1;\n }\n\n thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);\n }\n } // Activate thumbs\n\n\n var thumbsToActivate = 1;\n var thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;\n\n if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {\n thumbsToActivate = swiper.params.slidesPerView;\n }
166\n\n if (!swiper.params.thumbs.multipleActiveThumbs) {\n thumbsToActivate = 1;\n }\n\n thumbsToActivate = Math.floor(thumbsToActivate);\n thumbsSwiper.slides.removeClass(thumbActiveClass);\n\n if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {\n for (var i = 0; i < thumbsToActivate; i += 1) {\n thumbsSwiper.$wrapperEl.children(\"[data-swiper-slide-index=\\\"\" + (swiper.realIndex + i) + \"\\\"]\").addClass(thumbActiveClass);\n }\n } else {\n for (var _i = 0; _i < thumbsToActivate; _i += 1) {\n thumbsSwiper.slides.eq(swiper.realIndex + _i).addClass(thumbActiveClass);\n }\n }\n }\n };\n var Thumbs$1 = {\n name: 'thumbs',\n params: {\n thumbs: {\n swiper: null,\n multipleActiveThumbs: true,\n autoScrollOffset: 0,\n slideThumbActiveClass: 'swiper-slide-thumb-active',\n thumbsContainerClass: 'swiper-container-thumbs'\n }\n },\n create: function create() {\n var swiper = this;\n bindModuleMethods(swiper, {\n thumbs: _extends({\n swiper: null,\n initialized: false\n }, Thumbs)\n });\n },\n on: {\n beforeInit: function beforeInit(swiper) {\n var thumbs = swiper.params.thumbs;\n if (!thumbs || !thumbs.swiper) return;\n swiper.thumbs.init();\n swiper.thumbs.update(true);\n },\n slideChange: function slideChange(swiper) {\n if (!swiper.thumbs.swiper) return;\n swiper.thumbs.update();\n },\n update: function update(swiper) {\n if (!swiper.thumbs.swiper) return;\n swiper.thumbs.update();\n },\n resize: function resize(swiper) {\n if (!swiper.thumbs.swiper) return;\n swiper.thumbs.update();\n },\n observerUpdate: function observerUpdate(swiper) {\n if (!swiper.thumbs.swiper) return;\n swiper.thumbs.update();\n },\n setTransition: function setTransition(swiper, duration) {\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) return;\n thumbsSwiper.setTransition(duration);\n },\n beforeDestroy: function beforeDestroy(swiper) {\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) return;\n\n if (swiper.thumbs.swiperCreated && thumbsSwiper) {\n thumbsSwiper.destroy();\n }\n }\n }\n };\n\n // Swiper Class\n var components = [Virtual$1, Keyboard$1, Mousewheel$1, Navigation$1, Pagination$1, Scrollbar$1, Parallax$1, Zoom$1, Lazy$1, Controller$1, A11y$1, History$1, HashNavigation$1, Autoplay$1, EffectFade, EffectCube, EffectFlip, EffectCoverflow, Thumbs$1];\n Swiper.use(components);\n\n return Swiper;\n\n})));\n//# sourceMappingURL=swiper-bundle.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc3dpcGVyLWJ1bmRsZS5qcz82ZGQwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3dpcGVyIDYuMS4xXG4gKiBNb3N0IG1vZGVybiBtb2JpbGUgdG91Y2ggc2xpZGVyIGFuZCBmcmFtZXdvcmsgd2l0aCBoYXJkd2FyZSBhY2NlbGVyYXRlZCB0cmFuc2l0aW9uc1xuICogaHR0cDovL3N3aXBlcmpzLmNvbVxuICpcbiAqIENvcHlyaWdodCAyMDE0LTIwMjAgVmxhZGltaXIgS2hhcmxhbXBpZGlcbiAqXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqXG4gKiBSZWxlYXNlZCBvbjogSnVseSAzMSwgMjAyMFxuICovXG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuU3dpcGVyID0gZmFjdG9yeSgpKTtcbn0odGhpcywgKGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
166XIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlO1xuICAgICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gICAgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7XG4gICAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICAgIHJldHVybiBDb25zdHJ1Y3RvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICAgIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogU1NSIFdpbmRvdyAzLjAuMC1hbHBoYS40XG4gICAqIEJldHRlciBoYW5kbGluZyBmb3Igd2luZG93IG9iamVjdCBpbiBTU1IgZW52aXJvbm1lbnRcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL25vbGltaXRzNHdlYi9zc3Itd2luZG93XG4gICAqXG4gICAqIENvcHlyaWdodCAyMDIwLCBWbGFkaW1pciBLaGFybGFtcGlkaVxuICAgKlxuICAgKiBMaWNlbnNlZCB1bmRlciBNSVRcbiAgICpcbiAgICogUmVsZWFzZWQgb246IE1heSAyMCwgMjAyMFxuICAgKi9cblxuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1wYXJhbS1yZWFzc2lnbiAqL1xuICBmdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmICdjb25zdHJ1Y3RvcicgaW4gb2JqICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0O1xuICB9XG5cbiAgZnVuY3Rpb24gZXh0ZW5kKHRhcmdldCwgc3JjKSB7XG4gICAgaWYgKHRhcmdldCA9PT0gdm9pZCAwKSB7XG4gICAgICB0YXJnZXQgPSB7fTtcbiAgICB9XG5cbiAgICBpZiAoc3JjID09PSB2b2lkIDApIHtcbiAgICAgIHNyYyA9IHt9O1xuICAgIH1cblxuICAgIE9iamVjdC5rZXlzKHNyYykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAodHlwZW9mIHRhcmdldFtrZXldID09PSAndW5kZWZpbmVkJykgdGFyZ2V0W2tleV0gPSBzcmNba2V5XTtlbHNlIGlmIChpc09iamVjdChzcmNba2V5XSkgJiYgaXNPYmplY3QodGFyZ2V0W2tleV0pICYmIE9iamVjdC5rZXlzKHNyY1trZXldKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGV4dGVuZCh0YXJnZXRba2V5XSwgc3JjW2tleV0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdmFyIHNzckRvY3VtZW50ID0ge1xuICAgIGJvZHk6IHt9LFxuICAgIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIoKSB7fSxcbiAgICByZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKCkge30sXG4gICAgYWN0aXZlRWxlbWVudDoge1xuICAgICAgYmx1cjogZnVuY3Rpb24gYmx1cigpIHt9LFxuICAgICAgbm9kZU5hbWU6ICcnXG4gICAgfSxcbiAgICBxdWVyeVNlbGVjdG9yOiBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yKCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBxdWVyeVNlbGVjdG9yQWxsOiBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yQWxsKCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0sXG4gICAgZ2V0RWxlbWVudEJ5SWQ6IGZ1bmN0aW9uIGdldEVsZW1lbnRCeUlkKCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBjcmVhdGVFdmVudDogZnVuY3Rpb24gY3JlYXRlRXZlbnQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbml0RXZlbnQ6IGZ1bmN0aW9uIGluaXRFdmVudCgpIHt9XG4gICAgICB9O1xuICAgIH0sXG4gICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNoaWxkcmVuOiBbXSxcbiAgICAgICAgY2hpbGROb2RlczogW10sXG4gICAgICAgIHN0eWxlOiB7fSxcbiAgICAgICAgc2V0QXR0cmlidXRlOiBmdW5jdGlvbiBzZXRBdHRyaWJ1dGUoKSB7fSxcbiAgICAgICAgZ2V0RWxlbWVudHNCeVRhZ05hbWU6IGZ1bmN0aW9uIGdldEVsZW1lbnRzQnlUYWdOYW1lKCkge1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9LFxuICAgIGNyZWF0ZUVsZW1lbnROUzogZnVuY3Rpb24gY3JlYXRlRWxlbWVudE5TKCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH0sXG4gICAgaW1wb3J0Tm9kZTogZnVuY3Rpb24gaW1wb3J0Tm9kZSgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgbG9jYXRpb246IHtcbiAgICAgIGhhc2g6ICcnLFxuICAgICAgaG9zdDogJycsXG4gICAgICBob3N0bmFtZTogJycsXG4gICAgICBocmVmOiAnJyxcbiAgICAgIG9yaWdpbjogJycsXG4gICAgICBwYXRobmFtZTogJycsXG4gICAgICBwcm90b2NvbDogJycsXG4gICAgICBzZWFyY2g6ICcnXG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIGdldERvY3VtZW50KCkge1xuICAgIHZhciBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQgOiB7fTtcbiAgICBleHRlbmQoZG9jLCBzc3JEb2N1bWVudCk7XG4gICAgcmV0dXJuIGRvYztcbiAgfVxuXG4gIHZhciBz
166c3JXaW5kb3cgPSB7XG4gICAgZG9jdW1lbnQ6IHNzckRvY3VtZW50LFxuICAgIG5hdmlnYXRvcjoge1xuICAgICAgdXNlckFnZW50OiAnJ1xuICAgIH0sXG4gICAgbG9jYXRpb246IHtcbiAgICAgIGhhc2g6ICcnLFxuICAgICAgaG9zdDogJycsXG4gICAgICBob3N0bmFtZTogJycsXG4gICAgICBocmVmOiAnJyxcbiAgICAgIG9yaWdpbjogJycsXG4gICAgICBwYXRobmFtZTogJycsXG4gICAgICBwcm90b2NvbDogJycsXG4gICAgICBzZWFyY2g6ICcnXG4gICAgfSxcbiAgICBoaXN0b3J5OiB7XG4gICAgICByZXBsYWNlU3RhdGU6IGZ1bmN0aW9uIHJlcGxhY2VTdGF0ZSgpIHt9LFxuICAgICAgcHVzaFN0YXRlOiBmdW5jdGlvbiBwdXNoU3RhdGUoKSB7fSxcbiAgICAgIGdvOiBmdW5jdGlvbiBnbygpIHt9LFxuICAgICAgYmFjazogZnVuY3Rpb24gYmFjaygpIHt9XG4gICAgfSxcbiAgICBDdXN0b21FdmVudDogZnVuY3Rpb24gQ3VzdG9tRXZlbnQoKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIoKSB7fSxcbiAgICByZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKCkge30sXG4gICAgZ2V0Q29tcHV0ZWRTdHlsZTogZnVuY3Rpb24gZ2V0Q29tcHV0ZWRTdHlsZSgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGdldFByb3BlcnR5VmFsdWU6IGZ1bmN0aW9uIGdldFByb3BlcnR5VmFsdWUoKSB7XG4gICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0sXG4gICAgSW1hZ2U6IGZ1bmN0aW9uIEltYWdlKCkge30sXG4gICAgRGF0ZTogZnVuY3Rpb24gRGF0ZSgpIHt9LFxuICAgIHNjcmVlbjoge30sXG4gICAgc2V0VGltZW91dDogZnVuY3Rpb24gc2V0VGltZW91dCgpIHt9LFxuICAgIGNsZWFyVGltZW91dDogZnVuY3Rpb24gY2xlYXJUaW1lb3V0KCkge30sXG4gICAgbWF0Y2hNZWRpYTogZnVuY3Rpb24gbWF0Y2hNZWRpYSgpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9LFxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZTogZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNhbGxiYWNrKSB7XG4gICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2V0VGltZW91dChjYWxsYmFjaywgMCk7XG4gICAgfSxcbiAgICBjYW5jZWxBbmltYXRpb25GcmFtZTogZnVuY3Rpb24gY2FuY2VsQW5pbWF0aW9uRnJhbWUoaWQpIHtcbiAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjbGVhclRpbWVvdXQoaWQpO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBnZXRXaW5kb3coKSB7XG4gICAgdmFyIHdpbiA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDoge307XG4gICAgZXh0ZW5kKHdpbiwgc3NyV2luZG93KTtcbiAgICByZXR1cm4gd2luO1xuICB9XG5cbiAgLyoqXG4gICAqIERvbTcgMy4wLjAtYWxwaGEuN1xuICAgKiBNaW5pbWFsaXN0aWMgSmF2YVNjcmlwdCBsaWJyYXJ5IGZvciBET00gbWFuaXB1bGF0aW9uLCB3aXRoIGEgalF1ZXJ5LWNvbXBhdGlibGUgQVBJXG4gICAqIGh0dHBzOi8vZnJhbWV3b3JrNy5pby9kb2NzL2RvbTcuaHRtbFxuICAgKlxuICAgKiBDb3B5cmlnaHQgMjAyMCwgVmxhZGltaXIgS2hhcmxhbXBpZGlcbiAgICpcbiAgICogTGljZW5zZWQgdW5kZXIgTUlUXG4gICAqXG4gICAqIFJlbGVhc2VkIG9uOiBKdWx5IDE0LCAyMDIwXG4gICAqL1xuXG4gIGZ1bmN0aW9uIF9pbmhlcml0c0xvb3NlKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gICAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzLnByb3RvdHlwZSk7XG4gICAgc3ViQ2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gc3ViQ2xhc3M7XG4gICAgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzcztcbiAgfVxuXG4gIGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gICAgX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgICAgIHJldHVybiBvLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gICAgfTtcbiAgICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xuICB9XG5cbiAgZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgICBfc2V0UHJvdG90eXBlT2YgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgICAgIG8uX19wcm90b19fID0gcDtcbiAgICAgIHJldHVybiBvO1xuICAgIH07XG5cbiAgICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xuICB9XG5cbiAgZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHtcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTtcbiAgICBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoRGF0ZSwgW10sIGZ1bmN0aW9uICgpIHt9KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gICAgaWYgKF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSkge1xuICAgICAgX2NvbnN0cnVjdCA9IFJlZmxlY3QuY29uc3RydWN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBfY29uc3RydWN0ID0gZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gICAgICAgI
166HZhciBhID0gW251bGxdO1xuICAgICAgICBhLnB1c2guYXBwbHkoYSwgYXJncyk7XG4gICAgICAgIHZhciBDb25zdHJ1Y3RvciA9IEZ1bmN0aW9uLmJpbmQuYXBwbHkoUGFyZW50LCBhKTtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbmV3IENvbnN0cnVjdG9yKCk7XG4gICAgICAgIGlmIChDbGFzcykgX3NldFByb3RvdHlwZU9mKGluc3RhbmNlLCBDbGFzcy5wcm90b3R5cGUpO1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBfY29uc3RydWN0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBmdW5jdGlvbiBfaXNOYXRpdmVGdW5jdGlvbihmbikge1xuICAgIHJldHVybiBGdW5jdGlvbi50b1N0cmluZy5jYWxsKGZuKS5pbmRleE9mKFwiW25hdGl2ZSBjb2RlXVwiKSAhPT0gLTE7XG4gIH1cblxuICBmdW5jdGlvbiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKSB7XG4gICAgdmFyIF9jYWNoZSA9IHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIiA/IG5ldyBNYXAoKSA6IHVuZGVmaW5lZDtcblxuICAgIF93cmFwTmF0aXZlU3VwZXIgPSBmdW5jdGlvbiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKSB7XG4gICAgICBpZiAoQ2xhc3MgPT09IG51bGwgfHwgIV9pc05hdGl2ZUZ1bmN0aW9uKENsYXNzKSkgcmV0dXJuIENsYXNzO1xuXG4gICAgICBpZiAodHlwZW9mIENsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIF9jYWNoZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAoX2NhY2hlLmhhcyhDbGFzcykpIHJldHVybiBfY2FjaGUuZ2V0KENsYXNzKTtcblxuICAgICAgICBfY2FjaGUuc2V0KENsYXNzLCBXcmFwcGVyKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gV3JhcHBlcigpIHtcbiAgICAgICAgcmV0dXJuIF9jb25zdHJ1Y3QoQ2xhc3MsIGFyZ3VtZW50cywgX2dldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yKTtcbiAgICAgIH1cblxuICAgICAgV3JhcHBlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKENsYXNzLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBXcmFwcGVyLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBfc2V0UHJvdG90eXBlT2YoV3JhcHBlciwgQ2xhc3MpO1xuICAgIH07XG5cbiAgICByZXR1cm4gX3dyYXBOYXRpdmVTdXBlcihDbGFzcyk7XG4gIH1cblxuICBmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgICBpZiAoc2VsZiA9PT0gdm9pZCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG4gIH1cbiAgLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuXG4gIGZ1bmN0aW9uIG1ha2VSZWFjdGl2ZShvYmopIHtcbiAgICB2YXIgcHJvdG8gPSBvYmouX19wcm90b19fO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosICdfX3Byb3RvX18nLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG4gICAgICAgIHByb3RvLl9fcHJvdG9fXyA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdmFyIERvbTcgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9BcnJheSkge1xuICAgIF9pbmhlcml0c0xvb3NlKERvbTcsIF9BcnJheSk7XG5cbiAgICBmdW5jdGlvbiBEb203KGl0ZW1zKSB7XG4gICAgICB2Y
166XIgX3RoaXM7XG5cbiAgICAgIF90aGlzID0gX0FycmF5LmNhbGwuYXBwbHkoX0FycmF5LCBbdGhpc10uY29uY2F0KGl0ZW1zKSkgfHwgdGhpcztcbiAgICAgIG1ha2VSZWFjdGl2ZShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSk7XG4gICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIERvbTc7XG4gIH0oIC8qI19fUFVSRV9fKi9fd3JhcE5hdGl2ZVN1cGVyKEFycmF5KSk7XG5cbiAgZnVuY3Rpb24gYXJyYXlGbGF0KGFycikge1xuICAgIGlmIChhcnIgPT09IHZvaWQgMCkge1xuICAgICAgYXJyID0gW107XG4gICAgfVxuXG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGFyci5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZWwpKSB7XG4gICAgICAgIHJlcy5wdXNoLmFwcGx5KHJlcywgYXJyYXlGbGF0KGVsKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXMucHVzaChlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5RmlsdGVyKGFyciwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmZpbHRlci5jYWxsKGFyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlVbmlxdWUoYXJyKSB7XG4gICAgdmFyIHVuaXF1ZUFycmF5ID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKHVuaXF1ZUFycmF5LmluZGV4T2YoYXJyW2ldKSA9PT0gLTEpIHVuaXF1ZUFycmF5LnB1c2goYXJyW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlQXJyYXk7XG4gIH1cblxuICBmdW5jdGlvbiBxc2Eoc2VsZWN0b3IsIGNvbnRleHQpIHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFtzZWxlY3Rvcl07XG4gICAgfVxuXG4gICAgdmFyIGEgPSBbXTtcbiAgICB2YXIgcmVzID0gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBhLnB1c2gocmVzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfVxuXG4gIGZ1bmN0aW9uICQoc2VsZWN0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICB2YXIgYXJyID0gW107XG5cbiAgICBpZiAoIWNvbnRleHQgJiYgc2VsZWN0b3IgaW5zdGFuY2VvZiBEb203KSB7XG4gICAgICByZXR1cm4gc2VsZWN0b3I7XG4gICAgfVxuXG4gICAgaWYgKCFzZWxlY3Rvcikge1xuICAgICAgcmV0dXJuIG5ldyBEb203KGFycik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhciBodG1sID0gc2VsZWN0b3IudHJpbSgpO1xuXG4gICAgICBpZiAoaHRtbC5pbmRleE9mKCc8JykgPj0gMCAmJiBodG1sLmluZGV4T2YoJz4nKSA+PSAwKSB7XG4gICAgICAgIHZhciB0b0NyZWF0ZSA9ICdkaXYnO1xuICAgICAgICBpZiAoaHRtbC5pbmRleE9mKCc8bGknKSA9PT0gMCkgdG9DcmVhdGUgPSAndWwnO1xuICAgICAgICBpZiAoaHRtbC5pbmRleE9mKCc8dHInKSA9PT0gMCkgdG9DcmVhdGUgPSAndGJvZHknO1xuICAgICAgICBpZiAoaHRtbC5pbmRleE9mKCc8dGQnKSA9PT0gMCB8fCBodG1sLmluZGV4T2YoJzx0aCcpID09PSAwKSB0b0NyZWF0ZSA9ICd0cic7XG4gICAgICAgIGlmIChodG1sLmluZGV4T2YoJzx0Ym9keScpID09PSAwKSB0b0NyZWF0ZSA9ICd0YWJsZSc7XG4gICAgICAgIGlmIChodG1sLmluZGV4T2YoJzxvcHRpb24nKSA9PT0gMCkgdG9DcmVhdGUgPSAnc2VsZWN0JztcbiAgICAgICAgdmFyIHRlbXBQYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRvQ3JlYXRlKTtcbiAgICAgICAgdGVtcFBhcmVudC5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGVtcFBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgYXJyLnB1c2godGVtcFBhcmVudC5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXJyID0gcXNhKHNlbGVjdG9yLnRyaW0oKSwgY29udGV4dCB8fCBkb2N1bWVudCk7XG4gICAgICB9IC8vIGFyciA9IHFzYShzZWxlY3RvciwgZG9jdW1lbnQpO1xuXG4gICAgfSBlbHNlIGlmIChzZWxlY3Rvci5ub2RlVHlwZSB8fCBzZWxlY3RvciA9PT0gd2luZG93IHx8IHNlbGVjdG9yID09PSBkb2N1bWVudCkge1xuICAgICAgYXJyLnB1c2goc2VsZWN0b3IpO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RvcikpIHtcbiAgICAgIGlmIChzZWxlY3RvciBpbnN0YW5jZW9mIERvbTcpIHJldHVybiBzZWxlY3RvcjtcbiAgICAgIGFyciA9IHNlbGVjdG9yO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRG9tNyhhcnJheVVuaXF1ZShhcnIpKTtcbiAgfVxuXG4gICQuZm4gPSBEb203LnByb3RvdHlwZTtcblxuICBmdW5jdGlvbiBhZGRDbGFzcygpIHtcbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgY2xhc3NlcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGNsYXNzZXNbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgdmFyIGNsYXNzTmFtZXMgPSBhcnJheUZsYXQoY2xhc3Nlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBjLnNwbGl0KCcgJyk7XG4gICAgfSkpO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgIHZhciBfZWwkY2xhc3NMaXN0O1xuXG4gICAgICAoX2VsJGNsYXNzTGlzdCA9IGVsLmNsYXNzTGlzdCkuYWRkLmFwcGx5KF9lbCRjbGFzc0xpc3QsIGNsYXNzTmFtZXMpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQ2xhc3MoKSB7XG4gICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBjbGFzc2VzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICBjbGFzc2VzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgfVxuXG4gICAgdmFyIGNsYXNzTmFtZXMgPSBhcnJheUZsYXQoY2xhc3Nlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybi
166BjLnNwbGl0KCcgJyk7XG4gICAgfSkpO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgIHZhciBfZWwkY2xhc3NMaXN0MjtcblxuICAgICAgKF9lbCRjbGFzc0xpc3QyID0gZWwuY2xhc3NMaXN0KS5yZW1vdmUuYXBwbHkoX2VsJGNsYXNzTGlzdDIsIGNsYXNzTmFtZXMpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlQ2xhc3MoKSB7XG4gICAgZm9yICh2YXIgX2xlbjMgPSBhcmd1bWVudHMubGVuZ3RoLCBjbGFzc2VzID0gbmV3IEFycmF5KF9sZW4zKSwgX2tleTMgPSAwOyBfa2V5MyA8IF9sZW4zOyBfa2V5MysrKSB7XG4gICAgICBjbGFzc2VzW19rZXkzXSA9IGFyZ3VtZW50c1tfa2V5M107XG4gICAgfVxuXG4gICAgdmFyIGNsYXNzTmFtZXMgPSBhcnJheUZsYXQoY2xhc3Nlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBjLnNwbGl0KCcgJyk7XG4gICAgfSkpO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgIGNsYXNzTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG4gICAgICAgIGVsLmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzQ2xhc3MoKSB7XG4gICAgZm9yICh2YXIgX2xlbjQgPSBhcmd1bWVudHMubGVuZ3RoLCBjbGFzc2VzID0gbmV3IEFycmF5KF9sZW40KSwgX2tleTQgPSAwOyBfa2V5NCA8IF9sZW40OyBfa2V5NCsrKSB7XG4gICAgICBjbGFzc2VzW19rZXk0XSA9IGFyZ3VtZW50c1tfa2V5NF07XG4gICAgfVxuXG4gICAgdmFyIGNsYXNzTmFtZXMgPSBhcnJheUZsYXQoY2xhc3Nlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBjLnNwbGl0KCcgJyk7XG4gICAgfSkpO1xuICAgIHJldHVybiBhcnJheUZpbHRlcih0aGlzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgIHJldHVybiBjbGFzc05hbWVzLmZpbHRlcihmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG4gICAgICAgIHJldHVybiBlbC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKTtcbiAgICAgIH0pLmxlbmd0aCA+IDA7XG4gICAgfSkubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGF0dHIoYXR0cnMsIHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGF0dHJzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gR2V0IGF0dHJcbiAgICAgIGlmICh0aGlzWzBdKSByZXR1cm4gdGhpc1swXS5nZXRBdHRyaWJ1dGUoYXR0cnMpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9IC8vIFNldCBhdHRyc1xuXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIC8vIFN0cmluZ1xuICAgICAgICB0aGlzW2ldLnNldEF0dHJpYnV0ZShhdHRycywgdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gT2JqZWN0XG4gICAgICAgIGZvciAodmFyIGF0dHJOYW1lIGluIGF0dHJzKSB7XG4gICAgICAgICAgdGhpc1tpXVthdHRyTmFtZV0gPSBhdHRyc1thdHRyTmFtZV07XG4gICAgICAgICAgdGhpc1tpXS5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIGF0dHJzW2F0dHJOYW1lXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUF0dHIoYXR0cikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdGhpc1tpXS5yZW1vdmVBdHRyaWJ1dGUoYXR0cik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB0aGlzW2ldLnN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zaXRpb24oZHVyYXRpb24pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHRoaXNbaV0uc3R5bGUudHJhbnNpdGlvbiA9IHR5cGVvZiBkdXJhdGlvbiAhPT0gJ3N0cmluZycgPyBkdXJhdGlvbiArIFwibXNcIiA6IGR1cmF0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgZm9yICh2YXIgX2xlbjUgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW41KSwgX2tleTUgPSAwOyBfa2V5NSA8IF9sZW41OyBfa2V5NSsrKSB7XG4gICAgICBhcmdzW19rZXk1XSA9IGFyZ3VtZW50c1tfa2V5NV07XG4gICAgfVxuXG4gICAgdmFyIGV2ZW50VHlwZSA9IGFyZ3NbMF0sXG4gICAgICAgIHRhcmdldFNlbGVjdG9yID0gYXJnc1sxXSxcbiAgICAgICAgbGlzdGVuZXIgPSBhcmdzWzJdLFxuICAgICAgICBjYXB0dXJlID0gYXJnc1szXTtcblxuICAgIGlmICh0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXZlbnRUeXBlID0gYXJnc1swXTtcbiAgICAgIGxpc3RlbmVyID0gYXJnc1sxXTtcbiAgICAgIGNhcHR1cmUgPSBhcmdzWzJdO1xuICAgICAgdGFyZ2V0U2VsZWN0b3IgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFjYXB0dXJlKSBjYXB0dXJlID0gZmFsc2U7XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVMaXZlRXZlbnQoZSkge1xuICAgICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgaWYgKCF0YXJnZXQpIHJldHVybjtcbiAgICAgIHZhciBldmVudERhdGEgPSBlLnRhcmdldC5kb203RXZlbnREYXRhIHx8IFtdO1xuXG4gICAgICBpZiAoZXZlbnREYXRhLmluZGV4T2YoZSkgPCAwKSB7XG4gICAgICAgIGV2ZW50RGF0YS51bnNoaWZ0KGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoJCh0YXJnZXQpLmlzKHRhcmdldFNlbGVjdG9yKSkgbGlzdGVuZXIuYXBwbHkodGFyZ2V0LCBldmVudERhdGEpO2Vsc2Uge1xuICAgICAgICB2Y
166XIgX3BhcmVudHMgPSAkKHRhcmdldCkucGFyZW50cygpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cblxuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IF9wYXJlbnRzLmxlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgaWYgKCQoX3BhcmVudHNba10pLmlzKHRhcmdldFNlbGVjdG9yKSkgbGlzdGVuZXIuYXBwbHkoX3BhcmVudHNba10sIGV2ZW50RGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVFdmVudChlKSB7XG4gICAgICB2YXIgZXZlbnREYXRhID0gZSAmJiBlLnRhcmdldCA/IGUudGFyZ2V0LmRvbTdFdmVudERhdGEgfHwgW10gOiBbXTtcblxuICAgICAgaWYgKGV2ZW50RGF0YS5pbmRleE9mKGUpIDwgMCkge1xuICAgICAgICBldmVudERhdGEudW5zaGlmdChlKTtcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgZXZlbnREYXRhKTtcbiAgICB9XG5cbiAgICB2YXIgZXZlbnRzID0gZXZlbnRUeXBlLnNwbGl0KCcgJyk7XG4gICAgdmFyIGo7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHZhciBlbCA9IHRoaXNbaV07XG5cbiAgICAgIGlmICghdGFyZ2V0U2VsZWN0b3IpIHtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IGV2ZW50cy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgIHZhciBldmVudCA9IGV2ZW50c1tqXTtcbiAgICAgICAgICBpZiAoIWVsLmRvbTdMaXN0ZW5lcnMpIGVsLmRvbTdMaXN0ZW5lcnMgPSB7fTtcbiAgICAgICAgICBpZiAoIWVsLmRvbTdMaXN0ZW5lcnNbZXZlbnRdKSBlbC5kb203TGlzdGVuZXJzW2V2ZW50XSA9IFtdO1xuICAgICAgICAgIGVsLmRvbTdMaXN0ZW5lcnNbZXZlbnRdLnB1c2goe1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgcHJveHlMaXN0ZW5lcjogaGFuZGxlRXZlbnRcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVFdmVudCwgY2FwdHVyZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIExpdmUgZXZlbnRzXG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBldmVudHMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICB2Y
166XIgX2V2ZW50ID0gZXZlbnRzW2pdO1xuICAgICAgICAgIGlmICghZWwuZG9tN0xpdmVMaXN0ZW5lcnMpIGVsLmRvbTdMaXZlTGlzdGVuZXJzID0ge307XG4gICAgICAgICAgaWYgKCFlbC5kb203TGl2ZUxpc3RlbmVyc1tfZXZlbnRdKSBlbC5kb203TGl2ZUxpc3RlbmVyc1tfZXZlbnRdID0gW107XG5cbiAgICAgICAgICBlbC5kb203TGl2ZUxpc3RlbmVyc1tfZXZlbnRdLnB1c2goe1xuICAgICAgICAgICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgICAgICAgICAgcHJveHlMaXN0ZW5lcjogaGFuZGxlTGl2ZUV2ZW50XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKF9ldmVudCwgaGFuZGxlTGl2ZUV2ZW50LCBjYXB0dXJlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnVuY3Rpb24gb2ZmKCkge1xuICAgIGZvciAodmFyIF9sZW42ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuNiksIF9rZXk2ID0gMDsgX2tleTYgPCBfbGVuNjsgX2tleTYrKykge1xuICAgICAgYXJnc1tfa2V5Nl0gPSBhcmd1bWVudHNbX2tleTZdO1xuICAgIH1cblxuICAgIHZhciBldmVudFR5cGUgPSBhcmdzWzBdLFxuICAgICAgICB0YXJnZXRTZWxlY3RvciA9IGFyZ3NbMV0sXG4gICAgICAgIGxpc3RlbmVyID0gYXJnc1syXSxcbiAgICAgICAgY2FwdHVyZSA9IGFyZ3NbM107XG5cbiAgICBpZiAodHlwZW9mIGFyZ3NbMV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGV2ZW50VHlwZSA9IGFyZ3NbMF07XG4gICAgICBsaXN0ZW5lciA9IGFyZ3NbMV07XG4gICAgICBjYXB0dXJlID0gYXJnc1syXTtcbiAgICAgIHRhcmdldFNlbGVjdG9yID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICghY2FwdHVyZSkgY2FwdHVyZSA9IGZhbHNlO1xuICAgIHZhciBldmVudHMgPSBldmVudFR5cGUuc3BsaXQoJyAnKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2Y
166XIgZXZlbnQgPSBldmVudHNbaV07XG5cbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICB2YXIgZWwgPSB0aGlzW2pdO1xuICAgICAgICB2YXIgaGFuZGxlcnMgPSB2b2lkIDA7XG5cbiAgICAgICAgaWYgKCF0YXJnZXRTZWxlY3RvciAmJiBlbC5kb203TGlzdGVuZXJzKSB7XG4gICAgICAgICAgaGFuZGxlcnMgPSBlbC5kb203TGlzdGVuZXJzW2V2ZW50XTtcbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRTZWxlY3RvciAmJiBlbC5kb203TGl2ZUxpc3RlbmVycykge1xuICAgICAgICAgIGhhbmRsZXJzID0gZWwuZG9tN0xpdmVMaXN0ZW5lcnNbZXZlbnRdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhbmRsZXJzICYmIGhhbmRsZXJzLmxlbmd0aCkge1xuICAgICAgICAgIGZvciAodmFyIGsgPSBoYW5kbGVycy5sZW5ndGggLSAxOyBrID49IDA7IGsgLT0gMSkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZXIgPSBoYW5kbGVyc1trXTtcblxuICAgICAgICAgICAgaWYgKGxpc3RlbmVyICYmIGhhbmRsZXIubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIucHJveHlMaXN0ZW5lciwgY2FwdHVyZSk7XG4gICAgICAgICAgICAgIGhhbmRsZXJzLnNwbGljZShrLCAxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgaGFuZGxlci5saXN0ZW5lciAmJiBoYW5kbGVyLmxpc3RlbmVyLmRvbTdwcm94eSAmJiBoYW5kbGVyLmxpc3RlbmVyLmRvbTdwcm94eSA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlci5wcm94eUxpc3RlbmVyLCBjYXB0dXJlKTtcbiAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGssIDEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghbGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlci5wcm94eUxpc3RlbmVyLCBjYXB0dXJlKTtcbiAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGssIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJpZ2dlcigpIHtcbiAgICB2YXIgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgICBmb3IgKHZhciBfbGVuOSA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjkpLCBfa2V5OSA9IDA7IF9rZXk5IDwgX2xlbjk7IF9rZXk5KyspIHtcbiAgICAgIGFyZ3NbX2tleTldID0gYXJndW1lbnRzW19rZXk5XTtcbiAgICB9XG5cbiAgICB2YXIgZXZlbnRzID0gYXJnc1swXS5zcGxpdCgnICcpO1xuICAgIHZhciBldmVudERhdGEgPSBhcmdzWzFdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHZhciBldmVudCA9IGV2ZW50c1tpXTtcblxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIHZhciBlbCA9IHRoaXNbal07XG5cbiAgICAgICAgaWYgKHdpbmRvdy5DdXN0b21FdmVudCkge1xuICAgICAgICAgIHZhciBldnQgPSBuZXcgd2luZG93LkN1c3RvbUV2ZW50KGV2ZW50LCB7XG4gICAgICAgICAgICBkZXRhaWw6IGV2ZW50RGF0YSxcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZWwuZG9tN0V2ZW50RGF0YSA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uIChkYXRhLCBkYXRhSW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhSW5kZXggPiAwO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoZXZ0KTtcbiAgICAgICAgICBlbC5kb203RXZlbnREYXRhID0gW107XG4gICAgICAgICAgZGVsZXRlIGVsLmRvbTdFdmVudERhdGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoY2FsbGJhY2spIHtcbiAgICB2YXIgZG9tID0gdGhpcztcblxuICAgIGZ1bmN0aW9uIGZpcmVDYWxsQmFjayhlKSB7XG4gICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcbiAgICAgIGNhbGxiYWNrLmNhbGwodGhpcywgZSk7XG4gICAgICBkb20ub2ZmKCd0cmFuc2l0aW9uZW5kJywgZmlyZUNhbGxCYWNrKTtcbiAgICB9XG5cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIGRvbS5vbigndHJhbnNpdGlvbmVuZCcsIGZpcmVDYWxsQmFjayk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiBvdXRlcldpZHRoKGluY2x1ZGVNYXJnaW5zKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGluY2x1ZGVNYXJnaW5zKSB7XG4gICAgICAgIHZhciBfc3R5bGVzID0gdGhpcy5zdHlsZXMoKTtcblxuICAgICAgICByZXR1cm4gdGhpc1swXS5vZmZzZXRXaWR0aCArIHBhcnNlRmxvYXQoX3N0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdtYXJnaW4tcmlnaHQnKSkgKyBwYXJzZUZsb2F0KF9zdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnbWFyZ2luLWxlZnQnKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzWzBdLm9mZnNldFdpZHRoO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gb3V0ZXJIZWlnaHQoaW5jbHVkZU1hcmdpbnMpIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoaW5jbHVkZU1hcmdpbnMpIHtcbiAgICAgICAgdmFyIF9zdHlsZXMyID0gdGhpcy5zdHlsZXMoKTtcblxuICAgICAgICByZXR1cm4gdGhpc1swXS5vZmZzZXRIZWlnaHQgKyBwYXJzZUZsb2F0KF9zdHlsZXMyLmdldFByb3BlcnR5VmFsdWUoJ21hcmdpbi10b3AnKSkgKyBwYXJzZUZsb2F0KF9zdHlsZXMyLmdldFByb3BlcnR5VmFsdWUoJ21hcmdpbi1ib3R0b20nKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybi
166B0aGlzWzBdLm9mZnNldEhlaWdodDtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9mZnNldCgpIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgICB2YXIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgdmFyIGVsID0gdGhpc1swXTtcbiAgICAgIHZhciBib3ggPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHZhciBib2R5ID0gZG9jdW1lbnQuYm9keTtcbiAgICAgIHZhciBjbGllbnRUb3AgPSBlbC5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMDtcbiAgICAgIHZhciBjbGllbnRMZWZ0ID0gZWwuY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMDtcbiAgICAgIHZhciBzY3JvbGxUb3AgPSBlbCA9PT0gd2luZG93ID8gd2luZG93LnNjcm9sbFkgOiBlbC5zY3JvbGxUb3A7XG4gICAgICB2YXIgc2Nyb2xsTGVmdCA9IGVsID09PSB3aW5kb3cgPyB3aW5kb3cuc2Nyb2xsWCA6IGVsLnNjcm9sbExlZnQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IGJveC50b3AgKyBzY3JvbGxUb3AgLSBjbGllbnRUb3AsXG4gICAgICAgIGxlZnQ6IGJveC5sZWZ0ICsgc2Nyb2xsTGVmdCAtIGNsaWVudExlZnRcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBzdHlsZXMoKSB7XG4gICAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIGlmICh0aGlzWzBdKSByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpc1swXSwgbnVsbCk7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgZnVuY3Rpb24gY3NzKHByb3BzLCB2YWx1ZSkge1xuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICB2YXIgaTtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBpZiAodHlwZW9mIHByb3BzID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyAuY3NzKCd3aWR0aCcpXG4gICAgICAgIGlmICh0aGlzWzBdKSByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpc1swXSwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyAuY3NzKHsgd2lkdGg6ICcxMDBweCcgfSlcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBmb3IgKHZhciBfcHJvcCBpbiBwcm9wcykge1xuICAgICAgICAgICAgdGhpc1tpXS5zdHlsZVtfcHJvcF0gPSBwcm9wc1tfcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiYgdHlwZW9mIHByb3BzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gLmNzcygnd2lkdGgnLCAnMTAwcHgnKVxuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdGhpc1tpXS5zdHlsZVtwcm9wc10gPSB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiBlYWNoKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCwgaW5kZXgpIHtcbiAgICAgIGNhbGxiYWNrLmFwcGx5KGVsLCBbZWwsIGluZGV4XSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2spIHtcbiAgICB2YXIgcmVzdWx0ID0gYXJyYXlGaWx0ZXIodGhpcywgY2FsbGJhY2spO1xuICAgIHJldHVybiAkKHJlc3VsdCk7XG4gIH1cblxuICBmdW5jdGlvbiBodG1sKGh0bWwpIHtcbiAgICBpZiAodHlwZW9mIGh0bWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gdGhpc1swXSA/IHRoaXNbMF0uaW5uZXJIVE1MIDogbnVsbDtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHRoaXNbaV0uaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRleHQodGV4dCkge1xuICAgIGlmICh0eXBlb2YgdGV4dCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB0aGlzWzBdID8gdGhpc1swXS50ZXh0Q29udGVudC50cmltKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdGhpc1tpXS50ZXh0Q29udGVudCA9IHRleHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiBpcyhzZWxlY3Rvcikge1xuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIHZhciBlbCA9IHRoaXNbMF07XG4gICAgdmFyIGNvbXBhcmVXaXRoO1xuICAgIHZhciBpO1xuICAgIGlmICghZWwgfHwgdHlwZW9mIHNlbGVjdG9yID09PSAndW5kZWZpbmVkJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChlbC5tYXRjaGVzKSByZXR1cm4gZWwubWF0Y2hlcyhzZWxlY3Rvcik7XG4gICAgICBpZiAoZWwud2Via2l0TWF0Y2hlc1NlbGVjdG9yKSByZXR1cm4gZWwud2Via2l0TWF0Y2hlc1NlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgIGlmIChlbC5tc01hdGNoZXNTZWxlY3RvcikgcmV0dXJuIGVsLm1zTWF0Y2hlc1NlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgIGNvbXBhcmVXaXRoID0gJChzZWxlY3Rvcik7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjb21wYXJlV2l0aC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoY29tcGFyZVdpdGhbaV0gPT09IGVsKSByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzZWxlY3RvciA9PT0gZG9jdW1lbnQpIHtcbiAgICAgIHJldHVybi
166BlbCA9PT0gZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgaWYgKHNlbGVjdG9yID09PSB3aW5kb3cpIHtcbiAgICAgIHJldHVybiBlbCA9PT0gd2luZG93O1xuICAgIH1cblxuICAgIGlmIChzZWxlY3Rvci5ub2RlVHlwZSB8fCBzZWxlY3RvciBpbnN0YW5jZW9mIERvbTcpIHtcbiAgICAgIGNvbXBhcmVXaXRoID0gc2VsZWN0b3Iubm9kZVR5cGUgPyBbc2VsZWN0b3JdIDogc2VsZWN0b3I7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjb21wYXJlV2l0aC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoY29tcGFyZVdpdGhbaV0gPT09IGVsKSByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluZGV4KCkge1xuICAgIHZhciBjaGlsZCA9IHRoaXNbMF07XG4gICAgdmFyIGk7XG5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGkgPSAwOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgd2hpbGUgKChjaGlsZCA9IGNoaWxkLnByZXZpb3VzU2libGluZykgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKSBpICs9IDE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBpO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBlcShpbmRleCkge1xuICAgIGlmICh0eXBlb2YgaW5kZXggPT09ICd1bmRlZmluZWQnKSByZXR1cm4gdGhpcztcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBpZiAoaW5kZXggPiBsZW5ndGggLSAxKSB7XG4gICAgICByZXR1cm4gJChbXSk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgdmFyIHJldHVybkluZGV4ID0gbGVuZ3RoICsgaW5kZXg7XG4gICAgICBpZiAocmV0dXJuSW5kZXggPCAwKSByZXR1cm4gJChbXSk7XG4gICAgICByZXR1cm4gJChbdGhpc1tyZXR1cm5JbmRleF1dKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJChbdGhpc1tpbmRleF1dKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGVuZCgpIHtcbiAgICB2YXIgbmV3Q2hpbGQ7XG4gICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgYXJndW1lbnRzLmxlbmd0aDsgayArPSAxKSB7XG4gICAgICBuZXdDaGlsZCA9IGsgPCAwIHx8IGFyZ3VtZW50cy5sZW5ndGggPD0gayA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1trXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIHRlbXBEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICB0ZW1wRGl2LmlubmVySFRNTCA9IG5ld0NoaWxkO1xuXG4gICAgICAgICAgd2hpbGUgKHRlbXBEaXYuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgdGhpc1tpXS5hcHBlbmRDaGlsZCh0ZW1wRGl2LmZpcnN0Q2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChuZXdDaGlsZCBpbnN0YW5jZW9mIERvbTcpIHtcbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG5ld0NoaWxkLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICB0aGlzW2ldLmFwcGVuZENoaWxkKG5ld0NoaWxkW2pdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpc1tpXS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXBlbmQobmV3Q2hpbGQpIHtcbiAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIHZhciBpO1xuICAgIHZhciBqO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciB0ZW1wRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHRlbXBEaXYuaW5uZXJIVE1MID0gbmV3Q2hpbGQ7XG5cbiAgICAgICAgZm9yIChqID0gdGVtcERpdi5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGogPj0gMDsgaiAtPSAxKSB7XG4gICAgICAgICAgdGhpc1tpXS5pbnNlcnRCZWZvcmUodGVtcERpdi5jaGlsZE5vZGVzW2pdLCB0aGlzW2ldLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5ld0NoaWxkIGluc3RhbmNlb2YgRG9tNykge1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbmV3Q2hpbGQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICB0aGlzW2ldLmluc2VydEJlZm9yZShuZXdDaGlsZFtqXSwgdGhpc1tpXS5jaGlsZE5vZGVzWzBdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpc1tpXS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHRoaXNbaV0uY2hpbGROb2Rlc1swXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmdW5jdGlvbiBuZXh0KHNlbGVjdG9yKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgIGlmICh0aGlzWzBdLm5leHRFbGVtZW50U2libGluZyAmJiAkKHRoaXNbMF0ubmV4dEVsZW1lbnRTaWJsaW5nKS5pcyhzZWxlY3RvcikpIHtcbiAgICAgICAgICByZXR1cm4gJChbdGhpc1swXS5uZXh0RWxlbWVudFNpYmxpbmddKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAkKFtdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXNbMF0ubmV4dEVsZW1lbnRTaWJsaW5nKSByZXR1cm4gJChbdGhpc1swXS5uZXh0RWxlbWVudFNpYmxpbmddKTtcbiAgICAgIHJldHVybiAkKFtdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJChbXSk7XG4gIH1cblxuICBmdW5jdGlvbiBuZXh0QWxsKHNlbGVjdG9yKSB7XG4gICAgdmFyIG5leHRFbHMgPSBbXTtcbiAgICB2YXIgZWwgPSB0aGlzWzBdO1xuICAgIGlmICghZWwpIHJldHVybiAkKFtdKTtcblxuICAgI
166HdoaWxlIChlbC5uZXh0RWxlbWVudFNpYmxpbmcpIHtcbiAgICAgIHZhciBfbmV4dCA9IGVsLm5leHRFbGVtZW50U2libGluZzsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgICAgaWYgKCQoX25leHQpLmlzKHNlbGVjdG9yKSkgbmV4dEVscy5wdXNoKF9uZXh0KTtcbiAgICAgIH0gZWxzZSBuZXh0RWxzLnB1c2goX25leHQpO1xuXG4gICAgICBlbCA9IF9uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiAkKG5leHRFbHMpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJldihzZWxlY3Rvcikge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBlbCA9IHRoaXNbMF07XG5cbiAgICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgICBpZiAoZWwucHJldmlvdXNFbGVtZW50U2libGluZyAmJiAkKGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpLmlzKHNlbGVjdG9yKSkge1xuICAgICAgICAgIHJldHVybiAkKFtlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gJChbXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSByZXR1cm4gJChbZWwucHJldmlvdXNFbGVtZW50U2libGluZ10pO1xuICAgICAgcmV0dXJuICQoW10pO1xuICAgIH1cblxuICAgIHJldHVybiAkKFtdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXZBbGwoc2VsZWN0b3IpIHtcbiAgICB2YXIgcHJldkVscyA9IFtdO1xuICAgIHZhciBlbCA9IHRoaXNbMF07XG4gICAgaWYgKCFlbCkgcmV0dXJuICQoW10pO1xuXG4gICAgd2hpbGUgKGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpIHtcbiAgICAgIHZhciBfcHJldiA9IGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgIGlmICgkKF9wcmV2KS5pcyhzZWxlY3RvcikpIHByZXZFbHMucHVzaChfcHJldik7XG4gICAgICB9IGVsc2UgcHJldkVscy5wdXNoKF9wcmV2KTtcblxuICAgICAgZWwgPSBfcHJldjtcbiAgICB9XG5cbiAgICByZXR1cm4gJChwcmV2RWxzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcmVudChzZWxlY3Rvcikge1xuICAgIHZhciBwYXJlbnRzID0gW107IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKHRoaXNbaV0ucGFyZW50Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgICAgICBpZiAoJCh0aGlzW2ldLnBhcmVudE5vZGUpLmlzKHNlbGVjdG9yKSkgcGFyZW50cy5wdXNoKHRoaXNbaV0ucGFyZW50Tm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50cy5wdXNoKHRoaXNbaV0ucGFyZW50Tm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gJChwYXJlbnRzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcmVudHMoc2VsZWN0b3IpIHtcbiAgICB2YXIgcGFyZW50cyA9IFtdOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHZhciBfcGFyZW50ID0gdGhpc1tpXS5wYXJlbnROb2RlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICAgIHdoaWxlIChfcGFyZW50KSB7XG4gICAgICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgICAgIGlmICgkKF9wYXJlbnQpLmlzKHNlbGVjdG9yKSkgcGFyZW50cy5wdXNoKF9wYXJlbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcmVudHMucHVzaChfcGFyZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9wYXJlbnQgPSBfcGFyZW50LnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICQocGFyZW50cyk7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9zZXN0KHNlbGVjdG9yKSB7XG4gICAgdmFyIGNsb3Nlc3QgPSB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuICQoW10pO1xuICAgIH1cblxuICAgIGlmICghY2xvc2VzdC5pcyhzZWxlY3RvcikpIHtcbiAgICAgIGNsb3Nlc3QgPSBjbG9zZXN0LnBhcmVudHMoc2VsZWN0b3IpLmVxKDApO1xuICAgIH1cblxuICAgIHJldHVybiBjbG9zZXN0O1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZChzZWxlY3Rvcikge1xuICAgIHZhciBmb3VuZEVsZW1lbnRzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHZhciBmb3VuZCA9IHRoaXNbaV0ucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZm91bmQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgZm91bmRFbGVtZW50cy5wdXNoKGZvdW5kW2pdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gJChmb3VuZEVsZW1lbnRzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNoaWxkcmVuKHNlbGVjdG9yKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gW107IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdmFyIGNoaWxkTm9kZXMgPSB0aGlzW2ldLmNoaWxkcmVuO1xuXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNoaWxkTm9kZXMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgaWYgKCFzZWxlY3RvciB8fCAkKGNoaWxkTm9kZXNbal0pLmlzKHNlbGVjdG9yKSkge1xuICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hpbGROb2Rlc1tqXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gJChjaGlsZHJlbik7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAodGhpc1tpXS5wYXJlbnROb2RlKSB0aGlzW2ldLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2Y
166XIgTWV0aG9kcyA9IHtcbiAgICBhZGRDbGFzczogYWRkQ2xhc3MsXG4gICAgcmVtb3ZlQ2xhc3M6IHJlbW92ZUNsYXNzLFxuICAgIGhhc0NsYXNzOiBoYXNDbGFzcyxcbiAgICB0b2dnbGVDbGFzczogdG9nZ2xlQ2xhc3MsXG4gICAgYXR0cjogYXR0cixcbiAgICByZW1vdmVBdHRyOiByZW1vdmVBdHRyLFxuICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtLFxuICAgIHRyYW5zaXRpb246IHRyYW5zaXRpb24sXG4gICAgb246IG9uLFxuICAgIG9mZjogb2ZmLFxuICAgIHRyaWdnZXI6IHRyaWdnZXIsXG4gICAgdHJhbnNpdGlvbkVuZDogdHJhbnNpdGlvbkVuZCxcbiAgICBvdXRlcldpZHRoOiBvdXRlcldpZHRoLFxuICAgIG91dGVySGVpZ2h0OiBvdXRlckhlaWdodCxcbiAgICBzdHlsZXM6IHN0eWxlcyxcbiAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICBjc3M6IGNzcyxcbiAgICBlYWNoOiBlYWNoLFxuICAgIGh0bWw6IGh0bWwsXG4gICAgdGV4dDogdGV4dCxcbiAgICBpczogaXMsXG4gICAgaW5kZXg6IGluZGV4LFxuICAgIGVxOiBlcSxcbiAgICBhcHBlbmQ6IGFwcGVuZCxcbiAgICBwcmVwZW5kOiBwcmVwZW5kLFxuICAgIG5leHQ6IG5leHQsXG4gICAgbmV4dEFsbDogbmV4dEFsbCxcbiAgICBwcmV2OiBwcmV2LFxuICAgIHByZXZBbGw6IHByZXZBbGwsXG4gICAgcGFyZW50OiBwYXJlbnQsXG4gICAgcGFyZW50czogcGFyZW50cyxcbiAgICBjbG9zZXN0OiBjbG9zZXN0LFxuICAgIGZpbmQ6IGZpbmQsXG4gICAgY2hpbGRyZW46IGNoaWxkcmVuLFxuICAgIGZpbHRlcjogZmlsdGVyLFxuICAgIHJlbW92ZTogcmVtb3ZlXG4gIH07XG4gIE9iamVjdC5rZXlzKE1ldGhvZHMpLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICAkLmZuW21ldGhvZE5hbWVdID0gTWV0aG9kc1ttZXRob2ROYW1lXTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gZGVsZXRlUHJvcHMob2JqKSB7XG4gICAgdmFyIG9iamVjdCA9IG9iajtcbiAgICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgb2JqZWN0W2tleV0gPSBudWxsO1xuICAgICAgfSBjYXRjaCAoZSkgey8vIG5vIGdldHRlciBmb3Igb2JqZWN0XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsvLyBzb21ldGhpbmcgZ290IHdyb25nXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBuZXh0VGljayhjYWxsYmFjaywgZGVsYXkpIHtcbiAgICBpZiAoZGVsYXkgPT09IHZvaWQgMCkge1xuICAgICAgZGVsYXkgPSAwO1xuICAgIH1cblxuICAgIHJldHVybiBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkZWxheSk7XG4gIH1cblxuICBmdW5jdGlvbiBub3coKSB7XG4gICAgcmV0dXJuIERhdGUubm93KCk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRUcmFuc2xhdGUoZWwsIGF4aXMpIHtcbiAgICBpZiAoYXhpcyA9PT0gdm9pZCAwKSB7XG4gICAgICBheGlzID0gJ3gnO1xuICAgIH1cblxuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICB2YXIgbWF0cml4O1xuICAgIHZhciBjdXJUcmFuc2Zvcm07XG4gICAgdmFyIHRyYW5zZm9ybU1hdHJpeDtcbiAgICB2YXIgY3VyU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgbnVsbCk7XG5cbiAgICBpZiAod2luZG93LldlYktpdENTU01hdHJpeCkge1xuICAgICAgY3VyVHJhbnNmb3JtID0gY3VyU3R5bGUudHJhbnNmb3JtIHx8IGN1clN0eWxlLndlYmtpdFRyYW5zZm9ybTtcblxuICAgICAgaWYgKGN1clRyYW5zZm9ybS5zcGxpdCgnLCcpLmxlbmd0aCA+IDYpIHtcbiAgICAgICAgY3VyVHJhbnNmb3JtID0gY3VyVHJhbnNmb3JtLnNwbGl0KCcsICcpLm1hcChmdW5jdGlvbiAoYSkge1xuICAgICAgICAgIHJldHVybiBhLnJlcGxhY2UoJywnLCAnLicpO1xuICAgICAgICB9KS5qb2luKCcsICcpO1xuICAgICAgfSAvLyBTb21lIG9sZCB2ZXJzaW9ucyBvZiBXZWJraXQgY2hva2Ugd2hlbiAnbm9uZScgaXMgcGFzc2VkOyBwYXNzXG4gICAgICAvLyBlbXB0eSBzdHJpbmcgaW5zdGVhZCBpbiB0aGlzIGNhc2VcblxuXG4gICAgICB0cmFuc2Zvcm1NYXRyaXggPSBuZXcgd2luZG93LldlYktpdENTU01hdHJpeChjdXJUcmFuc2Zvcm0gPT09ICdub25lJyA/ICcnIDogY3VyVHJhbnNmb3JtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJhbnNmb3JtTWF0cml4ID0gY3VyU3R5bGUuTW96VHJhbnNmb3JtIHx8IGN1clN0eWxlLk9UcmFuc2Zvcm0gfHwgY3VyU3R5bGUuTXNUcmFuc2Zvcm0gfHwgY3VyU3R5bGUubXNUcmFuc2Zvcm0gfHwgY3VyU3R5bGUudHJhbnNmb3JtIHx8IGN1clN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ3RyYW5zZm9ybScpLnJlcGxhY2UoJ3RyYW5zbGF0ZSgnLCAnbWF0cml4KDEsIDAsIDAsIDEsJyk7XG4gICAgICBtYXRyaXggPSB0cmFuc2Zvcm1NYXRyaXgudG9TdHJpbmcoKS5zcGxpdCgnLCcpO1xuICAgIH1cblxuICAgIGlmIChheGlzID09PSAneCcpIHtcbiAgICAgIC8vIExhdGVzdCBDaHJvbWUgYW5kIHdlYmtpdHMgRml4XG4gICAgICBpZiAod2luZG93LldlYktpdENTU01hdHJpeCkgY3VyVHJhbnNmb3JtID0gdHJhbnNmb3JtTWF0cml4Lm00MTsgLy8gQ3JhenkgSUUxMCBNYXRyaXhcbiAgICAgIGVsc2UgaWYgKG1hdHJpeC5sZW5ndGggPT09IDE2KSBjdXJUcmFuc2Zvcm0gPSBwYXJzZUZsb2F0KG1hdHJpeFsxMl0pOyAvLyBOb3JtYWwgQnJvd3NlcnNcbiAgICAgICAgZWxzZSBjdXJUcmFuc2Zvcm0gPSBwYXJzZUZsb2F0KG1hdHJpeFs0XSk7XG4gICAgfVxuXG4gICAgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgICAgLy8gTGF0ZXN0IENocm9tZSBhbmQgd2Via2l0cyBGaXhcbiAgICAgIGlmICh3aW5kb3cuV2ViS2l0Q1NTTWF0cml4KSBjdXJUcmFuc2Zvcm0gPSB0cmFuc2Zvcm1NYXRyaXgubTQyOyAvLyBDcmF6eSBJRTEwIE1hdHJpeFxuICAgICAgZWxzZSBpZiAobWF0cml4Lmxlbmd0aCA9PT0gMTYpIGN1clRyYW5zZm9ybSA9IHBhcnNlRmxvYXQobWF0cml4WzEzXSk7IC8vIE5vcm1hbCBCcm93c2Vyc1xuICAgICAgICBlbHNlIGN1clRyYW5zZm9ybSA9IHBhcnNlRmxvYXQobWF0cml4WzVdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VyVHJhbnNmb3JtIHx8IDA7XG4gIH1cblxuICBmdW5jdGlvbiBpc09iamVjdCQxKG8pIHtcbiAgICByZXR1cm4gdHlwZW9mIG8gPT09ICdvYmplY3QnICYmIG8gIT09IG51bGwgJiYgby5jb25zdHJ1Y3RvciAmJiBvLmNvbnN0cnVjdG9yID09PSBPYmplY3Q7XG4gIH1cblxuICBmdW5jdGlvbiBleHRlbmQkMSgpIHtcbiAgICB2YXIgdG8gPSBPYmplY3QoYXJndW1lbnRzLmxlbmd0aCA8PSAwID8gdW5kZWZpbmVkIDogYXJndW1lbnRzWzBdKTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2Y
166XIgbmV4dFNvdXJjZSA9IGkgPCAwIHx8IGFyZ3VtZW50cy5sZW5ndGggPD0gaSA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1tpXTtcblxuICAgICAgaWYgKG5leHRTb3VyY2UgIT09IHVuZGVmaW5lZCAmJiBuZXh0U291cmNlICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBrZXlzQXJyYXkgPSBPYmplY3Qua2V5cyhPYmplY3QobmV4dFNvdXJjZSkpO1xuXG4gICAgICAgIGZvciAodmFyIG5leHRJbmRleCA9IDAsIGxlbiA9IGtleXNBcnJheS5sZW5ndGg7IG5leHRJbmRleCA8IGxlbjsgbmV4dEluZGV4ICs9IDEpIHtcbiAgICAgICAgICB2YXIgbmV4dEtleSA9IGtleXNBcnJheVtuZXh0SW5kZXhdO1xuICAgICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihuZXh0U291cmNlLCBuZXh0S2V5KTtcblxuICAgICAgICAgIGlmIChkZXNjICE9PSB1bmRlZmluZWQgJiYgZGVzYy5lbnVtZXJhYmxlKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QkMSh0b1tuZXh0S2V5XSkgJiYgaXNPYmplY3QkMShuZXh0U291cmNlW25leHRLZXldKSkge1xuICAgICAgICAgICAgICBleHRlbmQkMSh0b1tuZXh0S2V5XSwgbmV4dFNvdXJjZVtuZXh0S2V5XSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFpc09iamVjdCQxKHRvW25leHRLZXldKSAmJiBpc09iamVjdCQxKG5leHRTb3VyY2VbbmV4dEtleV0pKSB7XG4gICAgICAgICAgICAgIHRvW25leHRLZXldID0ge307XG4gICAgICAgICAgICAgIGV4dGVuZCQxKHRvW25leHRLZXldLCBuZXh0U291cmNlW25leHRLZXldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRvW25leHRLZXldID0gbmV4dFNvdXJjZVtuZXh0S2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdG87XG4gIH1cblxuICBmdW5jdGlvbiBiaW5kTW9kdWxlTWV0aG9kcyhpbnN0YW5jZSwgb2JqKSB7XG4gICAgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGlmIChpc09iamVjdCQxKG9ialtrZXldKSkge1xuICAgICAgICBPYmplY3Qua2V5cyhvYmpba2V5XSkuZm9yRWFjaChmdW5jdGlvbiAoc3ViS2V5KSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmpba2V5XVtzdWJLZXldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBvYmpba2V5XVtzdWJLZXldID0gb2JqW2tleV1bc3ViS2V5XS5iaW5kKGluc3RhbmNlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpbnN0YW5jZVtrZXldID0gb2JqW2tleV07XG4gICAgfSk7XG4gIH1cblxuICB2YXIgc3VwcG9ydDtcblxuICBmdW5jdGlvbiBjYWxjU3VwcG9ydCgpIHtcbiAgICB2YXIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG91Y2g6ICEhKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCB3aW5kb3cuRG9jdW1lbnRUb3VjaCAmJiBkb2N1bWVudCBpbnN0YW5jZW9mIHdpbmRvdy5Eb2N1bWVudFRvdWNoKSxcbiAgICAgIHBvaW50ZXJFdmVudHM6ICEhd2luZG93LlBvaW50ZXJFdmVudCAmJiAnbWF4VG91Y2hQb2ludHMnIGluIHdpbmRvdy5uYXZpZ2F0b3IgJiYgd2luZG93Lm5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyA+PSAwLFxuICAgICAgb2JzZXJ2ZXI6IGZ1bmN0aW9uIGNoZWNrT2JzZXJ2ZXIoKSB7XG4gICAgICAgIHJldHVybiAnTXV0YXRpb25PYnNlcnZlcicgaW4gd2luZG93IHx8ICdXZWJraXRNdXRhdGlvbk9ic2VydmVyJyBpbiB3aW5kb3c7XG4gICAgICB9KCksXG4gICAgICBwYXNzaXZlTGlzdGVuZXI6IGZ1bmN0aW9uIGNoZWNrUGFzc2l2ZUxpc3RlbmVyKCkge1xuICAgICAgICB2Y
166XIgc3VwcG9ydHNQYXNzaXZlID0gZmFsc2U7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YXIgb3B0cyA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ3Bhc3NpdmUnLCB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgICAgICBzdXBwb3J0c1Bhc3NpdmUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0UGFzc2l2ZUxpc3RlbmVyJywgbnVsbCwgb3B0cyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHsvLyBObyBzdXBwb3J0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc3VwcG9ydHNQYXNzaXZlO1xuICAgICAgfSgpLFxuICAgICAgZ2VzdHVyZXM6IGZ1bmN0aW9uIGNoZWNrR2VzdHVyZXMoKSB7XG4gICAgICAgIHJldHVybiAnb25nZXN0dXJlc3RhcnQnIGluIHdpbmRvdztcbiAgICAgIH0oKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTdXBwb3J0KCkge1xuICAgIGlmICghc3VwcG9ydCkge1xuICAgICAgc3VwcG9ydCA9IGNhbGNTdXBwb3J0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1cHBvcnQ7XG4gIH1cblxuICB2YXIgZGV2aWNlO1xuXG4gIGZ1bmN0aW9uIGNhbGNEZXZpY2UoX3RlbXApIHtcbiAgICB2YXIgX3JlZiA9IF90ZW1wID09PSB2b2lkIDAgPyB7fSA6IF90ZW1wLFxuICAgICAgICB1c2VyQWdlbnQgPSBfcmVmLnVzZXJBZ2VudDtcblxuICAgIHZhciBzdXBwb3J0ID0gZ2V0U3VwcG9ydCgpO1xuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICB2YXIgcGxhdGZvcm0gPSB3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtO1xuICAgIHZhciB1YSA9IHVzZXJBZ2VudCB8fCB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICB2YXIgZGV2aWNlID0ge1xuICAgICAgaW9zOiBmYWxzZSxcbiAgICAgIGFuZHJvaWQ6IGZhbHNlXG4gICAgfTtcbiAgICB2YXIgc2NyZWVuV2lkdGggPSB3aW5kb3cuc2NyZWVuLndpZHRoO1xuICAgIHZhciBzY3JlZW5IZWlnaHQgPSB3aW5kb3cuc2NyZWVuLmhlaWdodDtcbiAgICB2YXIgYW5kcm9pZCA9IHVhLm1hdGNoKC8oQW5kcm9pZCk7P1tcXHNcXC9dKyhbXFxkLl0rKT8vKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgdmFyIGlwYWQgPSB1YS5tYXRjaCgvKGlQYWQpLipPU1xccyhbXFxkX10rKS8pO1xuICAgIHZhciBpcG9kID0gdWEubWF0Y2goLyhpUG9kKSguKk9TXFxzKFtcXGRfXSspKT8vKTtcbiAgICB2YXIgaXBob25lID0gIWlwYWQgJiYgdWEubWF0Y2goLyhpUGhvbmVcXHNPU3xpT1MpXFxzKFtcXGRfXSspLyk7XG4gICAgdmFyIHdpbmRvd3MgPSBwbGF0Zm9ybSA9PT0gJ1dpbjMyJztcbiAgICB2YXIgbWFjb3MgPSBwbGF0Zm9ybSA9PT0gJ01hY0ludGVsJzsgLy8gaVBhZE9zIDEzIGZpeFxuXG4gICAgdmFyIGlQYWRTY3JlZW5zID0gWycxMDI0eDEzNjYnLCAnMTM2NngxMDI0JywgJzgzNHgxMTk0JywgJzExOTR4ODM0JywgJzgzNHgxMTEyJywgJzExMTJ4ODM0JywgJzc2OHgxMDI0JywgJzEwMjR4NzY4J107XG5cbiAgICBpZiAoIWlwYWQgJiYgbWFjb3MgJiYgc3VwcG9ydC50b3VjaCAmJiBpUGFkU2NyZWVucy5pbmRleE9mKHNjcmVlbldpZHRoICsgXCJ4XCIgKyBzY3JlZW5IZWlnaHQpID49IDApIHtcbiAgICAgIGlwYWQgPSB1YS5tYXRjaCgvKFZlcnNpb24pXFwvKFtcXGQuXSspLyk7XG4gICAgICBpZiAoIWlwYWQpIGlwYWQgPSBbMCwgMSwgJzEzXzBfMCddO1xuICAgICAgbWFjb3MgPSBmYWxzZTtcbiAgICB9IC8vIEFuZHJvaWRcblxuXG4gICAgaWYgKGFuZHJvaWQgJiYgIXdpbmRvd3MpIHtcbiAgICAgIGRldmljZS5vcyA9ICdhbmRyb2lkJztcbiAgICAgIGRldmljZS5hbmRyb2lkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXBhZCB8fCBpcGhvbmUgfHwgaXBvZCkge1xuICAgICAgZGV2aWNlLm9zID0gJ2lvcyc7XG4gICAgICBkZXZpY2UuaW9zID0gdHJ1ZTtcbiAgICB9IC8vIEV4cG9ydCBvYmplY3RcblxuXG4gICAgcmV0dXJuIGRldmljZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERldmljZShvdmVycmlkZXMpIHtcbiAgICBpZiAob3ZlcnJpZGVzID09PSB2b2lkIDApIHtcbiAgICAgIG92ZXJyaWRlcyA9IHt9O1xuICAgIH1cblxuICAgIGlmICghZGV2aWNlKSB7XG4gICAgICBkZXZpY2UgPSBjYWxjRGV2aWNlKG92ZXJyaWRlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRldmljZTtcbiAgfVxuXG4gIHZhciBicm93c2VyO1xuXG4gIGZ1bmN0aW9uIGNhbGNCcm93c2VyKCkge1xuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcblxuICAgIGZ1bmN0aW9uIGlzU2FmYXJpKCkge1xuICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiB1YS5pbmRleE9mKCdzYWZhcmknKSA+PSAwICYmIHVhLmluZGV4T2YoJ2Nocm9tZScpIDwgMCAmJiB1YS5pbmRleE9mKCdhbmRyb2lkJykgPCAwO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpc0VkZ2U6ICEhd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0VkZ2UvZyksXG4gICAgICBpc1NhZmFyaTogaXNTYWZhcmkoKSxcbiAgICAgIGlzV2ViVmlldzogLyhpUGhvbmV8aVBvZHxpUGFkKS4qQXBwbGVXZWJLaXQoPyEuKlNhZmFyaSkvaS50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRCcm93c2VyKCkge1xuICAgIGlmICghYnJvd3Nlcikge1xuICAgICAgYnJvd3NlciA9IGNhbGNCcm93c2VyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJyb3dzZXI7XG4gIH1cblxuICB2YXIgUmVzaXplID0ge1xuICAgIG5hbWU6ICdyZXNpemUnLFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBleHRlbmQkMShzd2lwZXIsIHtcbiAgICAgICAgcmVzaXplOiB7XG4gICAgICAgICAgcmVzaXplSGFuZGxlcjogZnVuY3Rpb24gcmVzaXplSGFuZGxlcigpIHtcbiAgICAgICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuO1xuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ2JlZm9yZVJlc2l6ZScpO1xuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ3Jlc2l6ZScpO1xuICAgICAgICAgI
166H0sXG4gICAgICAgICAgb3JpZW50YXRpb25DaGFuZ2VIYW5kbGVyOiBmdW5jdGlvbiBvcmllbnRhdGlvbkNoYW5nZUhhbmRsZXIoKSB7XG4gICAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkIHx8ICFzd2lwZXIuaW5pdGlhbGl6ZWQpIHJldHVybjtcbiAgICAgICAgICAgIHN3aXBlci5lbWl0KCdvcmllbnRhdGlvbmNoYW5nZScpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIpIHtcbiAgICAgICAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdygpOyAvLyBFbWl0IHJlc2l6ZVxuXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzd2lwZXIucmVzaXplLnJlc2l6ZUhhbmRsZXIpOyAvLyBFbWl0IG9yaWVudGF0aW9uY2hhbmdlXG5cbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgc3dpcGVyLnJlc2l6ZS5vcmllbnRhdGlvbkNoYW5nZUhhbmRsZXIpO1xuICAgICAgfSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koc3dpcGVyKSB7XG4gICAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHN3aXBlci5yZXNpemUucmVzaXplSGFuZGxlcik7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIHN3aXBlci5yZXNpemUub3JpZW50YXRpb25DaGFuZ2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIE9ic2VydmVyID0ge1xuICAgIGF0dGFjaDogZnVuY3Rpb24gYXR0YWNoKHRhcmdldCwgb3B0aW9ucykge1xuICAgICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgICAgICBvcHRpb25zID0ge307XG4gICAgICB9XG5cbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIE9ic2VydmVyRnVuYyA9IHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyIHx8IHdpbmRvdy5XZWJraXRNdXRhdGlvbk9ic2VydmVyO1xuICAgICAgdmFyIG9ic2VydmVyID0gbmV3IE9ic2VydmVyRnVuYyhmdW5jdGlvbiAobXV0YXRpb25zKSB7XG4gICAgICAgIC8vIFRoZSBvYnNlcnZlclVwZGF0ZSBldmVudCBzaG91bGQgb25seSBiZSB0cmlnZ2VyZWRcbiAgICAgICAgLy8gb25jZSBkZXNwaXRlIHRoZSBudW1iZXIgb2YgbXV0YXRpb25zLiAgQWRkaXRpb25hbFxuICAgICAgICAvLyB0cmlnZ2VycyBhcmUgcmVkdW5kYW50IGFuZCBhcmUgdmVyeSBjb3N0bHlcbiAgICAgICAgaWYgKG11dGF0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBzd2lwZXIuZW1pdCgnb2JzZXJ2ZXJVcGRhdGUnLCBtdXRhdGlvbnNbMF0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvYnNlcnZlclVwZGF0ZSA9IGZ1bmN0aW9uIG9ic2VydmVyVXBkYXRlKCkge1xuICAgICAgICAgIHN3aXBlci5lbWl0KCdvYnNlcnZlclVwZGF0ZScsIG11dGF0aW9uc1swXSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKG9ic2VydmVyVXBkYXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChvYnNlcnZlclVwZGF0ZSwgMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0YXJnZXQsIHtcbiAgICAgICAgYXR0cmlidXRlczogdHlwZW9mIG9wdGlvbnMuYXR0cmlidXRlcyA9PT0gJ3VuZGVmaW5lZCcgPyB0cnVlIDogb3B0aW9ucy5hdHRyaWJ1dGVzLFxuICAgICAgICBjaGlsZExpc3Q6IHR5cGVvZiBvcHRpb25zLmNoaWxkTGlzdCA9PT0gJ3VuZGVmaW5lZCcgPyB0cnVlIDogb3B0aW9ucy5jaGlsZExpc3QsXG4gICAgICAgIGNoYXJhY3RlckRhdGE6IHR5cGVvZiBvcHRpb25zLmNoYXJhY3RlckRhdGEgPT09ICd1bmRlZmluZWQnID8gdHJ1ZSA6IG9wdGlvbnMuY2hhcmFjdGVyRGF0YVxuICAgICAgfSk7XG4gICAgICBzd2lwZXIub2JzZXJ2ZXIub2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xuICAgIH0sXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKCFzd2lwZXIuc3VwcG9ydC5vYnNlcnZlciB8fCAhc3dpcGVyLnBhcmFtcy5vYnNlcnZlcikgcmV0dXJuO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5vYnNlcnZlUGFyZW50cykge1xuICAgICAgICB2Y
166XIgY29udGFpbmVyUGFyZW50cyA9IHN3aXBlci4kZWwucGFyZW50cygpO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29udGFpbmVyUGFyZW50cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHN3aXBlci5vYnNlcnZlci5hdHRhY2goY29udGFpbmVyUGFyZW50c1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gT2JzZXJ2ZSBjb250YWluZXJcblxuXG4gICAgICBzd2lwZXIub2JzZXJ2ZXIuYXR0YWNoKHN3aXBlci4kZWxbMF0sIHtcbiAgICAgICAgY2hpbGRMaXN0OiBzd2lwZXIucGFyYW1zLm9ic2VydmVTbGlkZUNoaWxkcmVuXG4gICAgICB9KTsgLy8gT2JzZXJ2ZSB3cmFwcGVyXG5cbiAgICAgIHN3aXBlci5vYnNlcnZlci5hdHRhY2goc3dpcGVyLiR3cmFwcGVyRWxbMF0sIHtcbiAgICAgICAgYXR0cmlidXRlczogZmFsc2VcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgc3dpcGVyLm9ic2VydmVyLm9ic2VydmVycy5mb3JFYWNoKGZ1bmN0aW9uIChvYnNlcnZlcikge1xuICAgICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB9KTtcbiAgICAgIHN3aXBlci5vYnNlcnZlci5vYnNlcnZlcnMgPSBbXTtcbiAgICB9XG4gIH07XG4gIHZhciBPYnNlcnZlciQxID0ge1xuICAgIG5hbWU6ICdvYnNlcnZlcicsXG4gICAgcGFyYW1zOiB7XG4gICAgICBvYnNlcnZlcjogZmFsc2UsXG4gICAgICBvYnNlcnZlUGFyZW50czogZmFsc2UsXG4gICAgICBvYnNlcnZlU2xpZGVDaGlsZHJlbjogZmFsc2VcbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgb2JzZXJ2ZXI6IF9leHRlbmRzKF9leHRlbmRzKHt9LCBPYnNlcnZlciksIHt9LCB7XG4gICAgICAgICAgb2JzZXJ2ZXJzOiBbXVxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgc3dpcGVyLm9ic2VydmVyLmluaXQoKTtcbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBzd2lwZXIub2JzZXJ2ZXIuZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgbW9kdWxhciA9IHtcbiAgICB1c2VQYXJhbXM6IGZ1bmN0aW9uIHVzZVBhcmFtcyhpbnN0YW5jZVBhcmFtcykge1xuICAgICAgdmFyIGluc3RhbmNlID0gdGhpcztcbiAgICAgIGlmICghaW5zdGFuY2UubW9kdWxlcykgcmV0dXJuO1xuICAgICAgT2JqZWN0LmtleXMoaW5zdGFuY2UubW9kdWxlcykuZm9yRWFjaChmdW5jdGlvbiAobW9kdWxlTmFtZSkge1xuICAgICAgICB2YXIgbW9kdWxlID0gaW5zdGFuY2UubW9kdWxlc1ttb2R1bGVOYW1lXTsgLy8gRXh0ZW5kIHBhcmFtc1xuXG4gICAgICAgIGlmIChtb2R1bGUucGFyYW1zKSB7XG4gICAgICAgICAgZXh0ZW5kJDEoaW5zdGFuY2VQYXJhbXMsIG1vZHVsZS5wYXJhbXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHVzZU1vZHVsZXM6IGZ1bmN0aW9uIHVzZU1vZHVsZXMobW9kdWxlc1BhcmFtcykge1xuICAgICAgaWYgKG1vZHVsZXNQYXJhbXMgPT09IHZvaWQgMCkge1xuICAgICAgICBtb2R1bGVzUGFyYW1zID0ge307XG4gICAgICB9XG5cbiAgICAgIHZhciBpbnN0YW5jZSA9IHRoaXM7XG4gICAgICBpZiAoIWluc3RhbmNlLm1vZHVsZXMpIHJldHVybjtcbiAgICAgIE9iamVjdC5rZXlzKGluc3RhbmNlLm1vZHVsZXMpLmZvckVhY2goZnVuY3Rpb24gKG1vZHVsZU5hbWUpIHtcbiAgICAgICAgdmFyIG1vZHVsZSA9IGluc3RhbmNlLm1vZHVsZXNbbW9kdWxlTmFtZV07XG4gICAgICAgIHZhciBtb2R1bGVQYXJhbXMgPSBtb2R1bGVzUGFyYW1zW21vZHVsZU5hbWVdIHx8IHt9OyAvLyBBZGQgZXZlbnQgbGlzdGVuZXJzXG5cbiAgICAgICAgaWYgKG1vZHVsZS5vbiAmJiBpbnN0YW5jZS5vbikge1xuICAgICAgICAgIE9iamVjdC5rZXlzKG1vZHVsZS5vbikuZm9yRWFjaChmdW5jdGlvbiAobW9kdWxlRXZlbnROYW1lKSB7XG4gICAgICAgICAgICBpbnN0YW5jZS5vbihtb2R1bGVFdmVudE5hbWUsIG1vZHVsZS5vblttb2R1bGVFdmVudE5hbWVdKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSAvLyBNb2R1bGUgY3JlYXRlIGNhbGxiYWNrXG5cblxuICAgICAgICBpZiAobW9kdWxlLmNyZWF0ZSkge1xuICAgICAgICAgIG1vZHVsZS5jcmVhdGUuYmluZChpbnN0YW5jZSkobW9kdWxlUGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlICovXG4gIHZhciBldmVudHNFbWl0dGVyID0ge1xuICAgIG9uOiBmdW5jdGlvbiBvbihldmVudHMsIGhhbmRsZXIsIHByaW9yaXR5KSB7XG4gICAgICB2Y
166XIgc2VsZiA9IHRoaXM7XG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBzZWxmO1xuICAgICAgdmFyIG1ldGhvZCA9IHByaW9yaXR5ID8gJ3Vuc2hpZnQnIDogJ3B1c2gnO1xuICAgICAgZXZlbnRzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0pIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSA9IFtdO1xuICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF1bbWV0aG9kXShoYW5kbGVyKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfSxcbiAgICBvbmNlOiBmdW5jdGlvbiBvbmNlKGV2ZW50cywgaGFuZGxlciwgcHJpb3JpdHkpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHNlbGY7XG5cbiAgICAgIGZ1bmN0aW9uIG9uY2VIYW5kbGVyKCkge1xuICAgICAgICBzZWxmLm9mZihldmVudHMsIG9uY2VIYW5kbGVyKTtcblxuICAgICAgICBpZiAob25jZUhhbmRsZXIuX19lbWl0dGVyUHJveHkpIHtcbiAgICAgICAgICBkZWxldGUgb25jZUhhbmRsZXIuX19lbWl0dGVyUHJveHk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgaGFuZGxlci5hcHBseShzZWxmLCBhcmdzKTtcbiAgICAgIH1cblxuICAgICAgb25jZUhhbmRsZXIuX19lbWl0dGVyUHJveHkgPSBoYW5kbGVyO1xuICAgICAgcmV0dXJuIHNlbGYub24oZXZlbnRzLCBvbmNlSGFuZGxlciwgcHJpb3JpdHkpO1xuICAgIH0sXG4gICAgb25Bbnk6IGZ1bmN0aW9uIG9uQW55KGhhbmRsZXIsIHByaW9yaXR5KSB7XG4gICAgICB2Y
166XIgc2VsZiA9IHRoaXM7XG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBzZWxmO1xuICAgICAgdmFyIG1ldGhvZCA9IHByaW9yaXR5ID8gJ3Vuc2hpZnQnIDogJ3B1c2gnO1xuXG4gICAgICBpZiAoc2VsZi5ldmVudHNBbnlMaXN0ZW5lcnMuaW5kZXhPZihoYW5kbGVyKSA8IDApIHtcbiAgICAgICAgc2VsZi5ldmVudHNBbnlMaXN0ZW5lcnNbbWV0aG9kXShoYW5kbGVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfSxcbiAgICBvZmZBbnk6IGZ1bmN0aW9uIG9mZkFueShoYW5kbGVyKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICBpZiAoIXNlbGYuZXZlbnRzQW55TGlzdGVuZXJzKSByZXR1cm4gc2VsZjtcbiAgICAgIHZhciBpbmRleCA9IHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLmluZGV4T2YoaGFuZGxlcik7XG5cbiAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgIHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH0sXG4gICAgb2ZmOiBmdW5jdGlvbiBvZmYoZXZlbnRzLCBoYW5kbGVyKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzKSByZXR1cm4gc2VsZjtcbiAgICAgIGV2ZW50cy5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0gPSBbXTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0pIHtcbiAgICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0uZm9yRWFjaChmdW5jdGlvbiAoZXZlbnRIYW5kbGVyLCBpbmRleCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50SGFuZGxlciA9PT0gaGFuZGxlciB8fCBldmVudEhhbmRsZXIuX19lbWl0dGVyUHJveHkgJiYgZXZlbnRIYW5kbGVyLl9fZW1pdHRlclByb3h5ID09PSBoYW5kbGVyKSB7XG4gICAgICAgICAgICAgIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH0sXG4gICAgZW1pdDogZnVuY3Rpb24gZW1pdCgpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMpIHJldHVybiBzZWxmO1xuICAgICAgdmFyIGV2ZW50cztcbiAgICAgIHZhciBkYXRhO1xuICAgICAgdmFyIGNvbnRleHQ7XG5cbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiksIF9rZXkyID0gMDsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ3N0cmluZycgfHwgQXJyYXkuaXNBcnJheShhcmdzWzBdKSkge1xuICAgICAgICBldmVudHMgPSBhcmdzWzBdO1xuICAgICAgICBkYXRhID0gYXJncy5zbGljZSgxLCBhcmdzLmxlbmd0aCk7XG4gICAgICAgIGNvbnRleHQgPSBzZWxmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXZlbnRzID0gYXJnc1swXS5ldmVudHM7XG4gICAgICAgIGRhdGEgPSBhcmdzWzBdLmRhdGE7XG4gICAgICAgIGNvbnRleHQgPSBhcmdzWzBdLmNvbnRleHQgfHwgc2VsZjtcbiAgICAgIH1cblxuICAgICAgZGF0YS51bnNoaWZ0KGNvbnRleHQpO1xuICAgICAgdmFyIGV2ZW50c0FycmF5ID0gQXJyYXkuaXNBcnJheShldmVudHMpID8gZXZlbnRzIDogZXZlbnRzLnNwbGl0KCcgJyk7XG4gICAgICBldmVudHNBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoc2VsZi5ldmVudHNMaXN0ZW5lcnMgJiYgc2VsZi5ldmVudHNMaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgICAgdmFyIGhhbmRsZXJzID0gW107XG4gICAgICAgICAgc2VsZi5ldmVudHNMaXN0ZW5lcnNbZXZlbnRdLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50SGFuZGxlcikge1xuICAgICAgICAgICAgaGFuZGxlcnMucHVzaChldmVudEhhbmRsZXIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGhhbmRsZXJzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50SGFuZGxlcikge1xuICAgICAgICAgICAgZXZlbnRIYW5kbGVyLmFwcGx5KGNvbnRleHQsIGRhdGEpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiB1cGRhdGVTaXplKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciB3aWR0aDtcbiAgICB2YXIgaGVpZ2h0O1xuICAgIHZhciAkZWwgPSBzd2lwZXIuJGVsO1xuXG4gICAgaWYgKHR5cGVvZiBzd2lwZXIucGFyYW1zLndpZHRoICE9PSAndW5kZWZpbmVkJyAmJiBzd2lwZXIucGFyYW1zLndpZHRoICE9PSBudWxsKSB7XG4gICAgICB3aWR0aCA9IHN3aXBlci5wYXJhbXMud2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpZHRoID0gJGVsWzBdLmNsaWVudFdpZHRoO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc3dpcGVyLnBhcmFtcy5oZWlnaHQgIT09ICd1bmRlZmluZWQnICYmIHN3aXBlci5wYXJhbXMud2lkdGggIT09IG51bGwpIHtcbiAgICAgIGhlaWdodCA9IHN3aXBlci5wYXJhbXMuaGVpZ2h0O1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWlnaHQgPSAkZWxbMF0uY2xpZW50SGVpZ2h0O1xuICAgIH1cblxuICAgIGlmICh3aWR0aCA9PT0gMCAmJiBzd2lwZXIuaXNIb3Jpem9udGFsKCkgfHwgaGVpZ2h0ID09PSAwICYmIHN3aXBlci5pc1ZlcnRpY2FsKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIFN1YnRyYWN0IHBhZGRpbmdzXG5cblxuICAgIHdpZHRoID0gd2lkdGggLSBwYXJzZUludCgkZWwuY3NzKCdwYWRkaW5nLWxlZnQnKSB8fCAwLCAxMCkgLSBwYXJzZUludCgkZWwuY3NzKCdwYWRkaW5nLXJpZ2h0JykgfHwgMCwgMTApO1xuICAgIGhlaWdodCA9IGhlaWdodCAtIHBhcnNlSW50KCRlbC5jc3MoJ3BhZGRpbmctdG9wJykgfHwgMCwgMTApIC0gcGFyc2VJbnQoJGVsLmNzcygncGFkZGluZy1ib3R0b20nKSB8fCAwLCAxMCk7XG4gICAgaWYgKE51bWJlci5pc05hTih3aWR0aCkpIHdpZHRoID0gMDtcbiAgICBpZiAoTnVtYmVyLmlzTmFOKGhlaWdodCkpIGhlaWdodCA9IDA7XG4gICAgZXh0ZW5kJDEoc3dpcGVyLCB7XG4gICAgICB3aWR0aDogd2lkdGgsXG4gICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgIHNpemU6IHN3aXBlci5pc0hvcml6b250YWwoKSA/IHdpZHRoIDogaGVpZ2h0XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTbGlkZXMoKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xuICAgIHZhciAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgI
166HN3aXBlclNpemUgPSBzd2lwZXIuc2l6ZSxcbiAgICAgICAgcnRsID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSxcbiAgICAgICAgd3JvbmdSVEwgPSBzd2lwZXIud3JvbmdSVEw7XG4gICAgdmFyIGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHBhcmFtcy52aXJ0dWFsLmVuYWJsZWQ7XG4gICAgdmFyIHByZXZpb3VzU2xpZGVzTGVuZ3RoID0gaXNWaXJ0dWFsID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xuICAgIHZhciBzbGlkZXMgPSAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzKTtcbiAgICB2YXIgc2xpZGVzTGVuZ3RoID0gaXNWaXJ0dWFsID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHNsaWRlcy5sZW5ndGg7XG4gICAgdmFyIHNuYXBHcmlkID0gW107XG4gICAgdmFyIHNsaWRlc0dyaWQgPSBbXTtcbiAgICB2YXIgc2xpZGVzU2l6ZXNHcmlkID0gW107XG5cbiAgICBmdW5jdGlvbiBzbGlkZXNGb3JNYXJnaW4oc2xpZGVFbCwgc2xpZGVJbmRleCkge1xuICAgICAgaWYgKCFwYXJhbXMuY3NzTW9kZSkgcmV0dXJuIHRydWU7XG5cbiAgICAgIGlmIChzbGlkZUluZGV4ID09PSBzbGlkZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvZmZzZXRCZWZvcmUgPSBwYXJhbXMuc2xpZGVzT2Zmc2V0QmVmb3JlO1xuXG4gICAgaWYgKHR5cGVvZiBvZmZzZXRCZWZvcmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG9mZnNldEJlZm9yZSA9IHBhcmFtcy5zbGlkZXNPZmZzZXRCZWZvcmUuY2FsbChzd2lwZXIpO1xuICAgIH1cblxuICAgIHZhciBvZmZzZXRBZnRlciA9IHBhcmFtcy5zbGlkZXNPZmZzZXRBZnRlcjtcblxuICAgIGlmICh0eXBlb2Ygb2Zmc2V0QWZ0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG9mZnNldEFmdGVyID0gcGFyYW1zLnNsaWRlc09mZnNldEFmdGVyLmNhbGwoc3dpcGVyKTtcbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNTbmFwR3JpZExlbmd0aCA9IHN3aXBlci5zbmFwR3JpZC5sZW5ndGg7XG4gICAgdmFyIHByZXZpb3VzU2xpZGVzR3JpZExlbmd0aCA9IHN3aXBlci5zbmFwR3JpZC5sZW5ndGg7XG4gICAgdmFyIHNwYWNlQmV0d2VlbiA9IHBhcmFtcy5zcGFjZUJldHdlZW47XG4gICAgdmFyIHNsaWRlUG9zaXRpb24gPSAtb2Zmc2V0QmVmb3JlO1xuICAgIHZhciBwcmV2U2xpZGVTaXplID0gMDtcbiAgICB2YXIgaW5kZXggPSAwO1xuXG4gICAgaWYgKHR5cGVvZiBzd2lwZXJTaXplID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc3BhY2VCZXR3ZWVuID09PSAnc3RyaW5nJyAmJiBzcGFjZUJldHdlZW4uaW5kZXhPZignJScpID49IDApIHtcbiAgICAgIHNwYWNlQmV0d2VlbiA9IHBhcnNlRmxvYXQoc3BhY2VCZXR3ZWVuLnJlcGxhY2UoJyUnLCAnJykpIC8gMTAwICogc3dpcGVyU2l6ZTtcbiAgICB9XG5cbiAgICBzd2lwZXIudmlydHVhbFNpemUgPSAtc3BhY2VCZXR3ZWVuOyAvLyByZXNldCBtYXJnaW5zXG5cbiAgICBpZiAocnRsKSBzbGlkZXMuY3NzKHtcbiAgICAgIG1hcmdpbkxlZnQ6ICcnLFxuICAgICAgbWFyZ2luVG9wOiAnJ1xuICAgIH0pO2Vsc2Ugc2xpZGVzLmNzcyh7XG4gICAgICBtYXJnaW5SaWdodDogJycsXG4gICAgICBtYXJnaW5Cb3R0b206ICcnXG4gICAgfSk7XG4gICAgdmFyIHNsaWRlc051bWJlckV2ZW5Ub1Jvd3M7XG5cbiAgICBpZiAocGFyYW1zLnNsaWRlc1BlckNvbHVtbiA+IDEpIHtcbiAgICAgIGlmIChNYXRoLmZsb29yKHNsaWRlc0xlbmd0aCAvIHBhcmFtcy5zbGlkZXNQZXJDb2x1bW4pID09PSBzbGlkZXNMZW5ndGggLyBzd2lwZXIucGFyYW1zLnNsaWRlc1BlckNvbHVtbikge1xuICAgICAgICBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzID0gc2xpZGVzTGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2xpZGVzTnVtYmVyRXZlblRvUm93cyA9IE1hdGguY2VpbChzbGlkZXNMZW5ndGggLyBwYXJhbXMuc2xpZGVzUGVyQ29sdW1uKSAqIHBhcmFtcy5zbGlkZXNQZXJDb2x1bW47XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMuc2xpZGVzUGVyVmlldyAhPT0gJ2F1dG8nICYmIHBhcmFtcy5zbGlkZXNQZXJDb2x1bW5GaWxsID09PSAncm93Jykge1xuICAgICAgICBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzID0gTWF0aC5tYXgoc2xpZGVzTnVtYmVyRXZlblRvUm93cywgcGFyYW1zLnNsaWRlc1BlclZpZXcgKiBwYXJhbXMuc2xpZGVzUGVyQ29sdW1uKTtcbiAgICAgIH1cbiAgICB9IC8vIENhbGMgc2xpZGVzXG5cblxuICAgIHZhciBzbGlkZVNpemU7XG4gICAgdmFyIHNsaWRlc1BlckNvbHVtbiA9IHBhcmFtcy5zbGlkZXNQZXJDb2x1bW47XG4gICAgdmFyIHNsaWRlc1BlclJvdyA9IHNsaWRlc051bWJlckV2ZW5Ub1Jvd3MgLyBzbGlkZXNQZXJDb2x1bW47XG4gICAgdmFyIG51bUZ1bGxDb2x1bW5zID0gTWF0aC5mbG9vcihzbGlkZXNMZW5ndGggLyBwYXJhbXMuc2xpZGVzUGVyQ29sdW1uKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpZGVzTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHNsaWRlU2l6ZSA9IDA7XG4gICAgICB2Y
166XIgc2xpZGUgPSBzbGlkZXMuZXEoaSk7XG5cbiAgICAgIGlmIChwYXJhbXMuc2xpZGVzUGVyQ29sdW1uID4gMSkge1xuICAgICAgICAvLyBTZXQgc2xpZGVzIG9yZGVyXG4gICAgICAgIHZhciBuZXdTbGlkZU9yZGVySW5kZXggPSB2b2lkIDA7XG4gICAgICAgIHZhciBjb2x1bW4gPSB2b2lkIDA7XG4gICAgICAgIHZhciByb3cgPSB2b2lkIDA7XG5cbiAgICAgICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJDb2x1bW5GaWxsID09PSAncm93JyAmJiBwYXJhbXMuc2xpZGVzUGVyR3JvdXAgPiAxKSB7XG4gICAgICAgICAgdmFyIGdyb3VwSW5kZXggPSBNYXRoLmZsb29yKGkgLyAocGFyYW1zLnNsaWRlc1Blckdyb3VwICogcGFyYW1zLnNsaWRlc1BlckNvbHVtbikpO1xuICAgICAgICAgIHZhciBzbGlkZUluZGV4SW5Hcm91cCA9IGkgLSBwYXJhbXMuc2xpZGVzUGVyQ29sdW1uICogcGFyYW1zLnNsaWRlc1Blckdyb3VwICogZ3JvdXBJbmRleDtcbiAgICAgICAgICB2YXIgY29sdW1uc0luR3JvdXAgPSBncm91cEluZGV4ID09PSAwID8gcGFyYW1zLnNsaWRlc1Blckdyb3VwIDogTWF0aC5taW4oTWF0aC5jZWlsKChzbGlkZXNMZW5ndGggLSBncm91cEluZGV4ICogc2xpZGVzUGVyQ29sdW1uICogcGFyYW1zLnNsaWRlc1Blckdyb3VwKSAvIHNsaWRlc1BlckNvbHVtbiksIHBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XG4gICAgICAgICAgcm93ID0gTWF0aC5mbG9vcihzbGlkZUluZGV4SW5Hcm91cCAvIGNvbHVtbnNJbkdyb3VwKTtcbiAgICAgICAgICBjb2x1bW4gPSBzbGlkZUluZGV4SW5Hcm91cCAtIHJvdyAqIGNvbHVtbnNJbkdyb3VwICsgZ3JvdXBJbmRleCAqIHBhcmFtcy5zbGlkZXNQZXJHcm91cDtcbiAgICAgICAgICBuZXdTbGlkZU9yZGVySW5kZXggPSBjb2x1bW4gKyByb3cgKiBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzIC8gc2xpZGVzUGVyQ29sdW1uO1xuICAgICAgICAgIHNsaWRlLmNzcyh7XG4gICAgICAgICAgICAnLXdlYmtpdC1ib3gtb3JkaW5hbC1ncm91cCc6IG5ld1NsaWRlT3JkZXJJbmRleCxcbiAgICAgICAgICAgICctbW96LWJveC1vcmRpbmFsLWdyb3VwJzogbmV3U2xpZGVPcmRlckluZGV4LFxuICAgICAgICAgICAgJy1tcy1mbGV4LW9yZGVyJzogbmV3U2xpZGVPcmRlckluZGV4LFxuICAgICAgICAgICAgJy13ZWJraXQtb3JkZXInOiBuZXdTbGlkZU9yZGVySW5kZXgsXG4gICAgICAgICAgICBvcmRlcjogbmV3U2xpZGVPcmRlckluZGV4XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW1zLnNsaWRlc1BlckNvbHVtbkZpbGwgPT09ICdjb2x1bW4nKSB7XG4gICAgICAgICAgY29sdW1uID0gTWF0aC5mbG9vcihpIC8gc2xpZGVzUGVyQ29sdW1uKTtcbiAgICAgICAgICByb3cgPSBpIC0gY29sdW1uICogc2xpZGVzUGVyQ29sdW1uO1xuXG4gICAgICAgICAgaWYgKGNvbHVtbiA+IG51bUZ1bGxDb2x1bW5zIHx8IGNvbHVtbiA9PT0gbnVtRnVsbENvbHVtbnMgJiYgcm93ID09PSBzbGlkZXNQZXJDb2x1bW4gLSAxKSB7XG4gICAgICAgICAgICByb3cgKz0gMTtcblxuICAgICAgICAgICAgaWYgKHJvdyA+PSBzbGlkZXNQZXJDb2x1bW4pIHtcbiAgICAgICAgICAgICAgcm93ID0gMDtcbiAgICAgICAgICAgICAgY29sdW1uICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJvdyA9IE1hdGguZmxvb3IoaSAvIHNsaWRlc1BlclJvdyk7XG4gICAgICAgICAgY29sdW1uID0gaSAtIHJvdyAqIHNsaWRlc1BlclJvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHNsaWRlLmNzcyhcIm1hcmdpbi1cIiArIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAndG9wJyA6ICdsZWZ0JyksIHJvdyAhPT0gMCAmJiBwYXJhbXMuc3BhY2VCZXR3ZWVuICYmIHBhcmFtcy5zcGFjZUJldHdlZW4gKyBcInB4XCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2xpZGUuY3NzKCdkaXNwbGF5J
166ykgPT09ICdub25lJykgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycpIHtcbiAgICAgICAgdmFyIHNsaWRlU3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoc2xpZGVbMF0sIG51bGwpO1xuICAgICAgICB2YXIgY3VycmVudFRyYW5zZm9ybSA9IHNsaWRlWzBdLnN0eWxlLnRyYW5zZm9ybTtcbiAgICAgICAgdmFyIGN1cnJlbnRXZWJLaXRUcmFuc2Zvcm0gPSBzbGlkZVswXS5zdHlsZS53ZWJraXRUcmFuc2Zvcm07XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUcmFuc2Zvcm0pIHtcbiAgICAgICAgICBzbGlkZVswXS5zdHlsZS50cmFuc2Zvcm0gPSAnbm9uZSc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudFdlYktpdFRyYW5zZm9ybSkge1xuICAgICAgICAgIHNsaWRlWzBdLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICdub25lJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSB7XG4gICAgICAgICAgc2xpZGVTaXplID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gc2xpZGUub3V0ZXJXaWR0aCh0cnVlKSA6IHNsaWRlLm91dGVySGVpZ2h0KHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnd2lkdGgnKSB8fCAwKTtcbiAgICAgICAgICAgIHZhciBwYWRkaW5nTGVmdCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy1sZWZ0JykgfHwgMCk7XG4gICAgICAgICAgICB2Y
166XIgcGFkZGluZ1JpZ2h0ID0gcGFyc2VGbG9hdChzbGlkZVN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdwYWRkaW5nLXJpZ2h0JykgfHwgMCk7XG4gICAgICAgICAgICB2YXIgbWFyZ2luTGVmdCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnbWFyZ2luLWxlZnQnKSB8fCAwKTtcbiAgICAgICAgICAgIHZhciBtYXJnaW5SaWdodCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnbWFyZ2luLXJpZ2h0JykgfHwgMCk7XG4gICAgICAgICAgICB2YXIgYm94U2l6aW5nID0gc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnYm94LXNpemluZycpO1xuXG4gICAgICAgICAgICBpZiAoYm94U2l6aW5nICYmIGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKSB7XG4gICAgICAgICAgICAgIHNsaWRlU2l6ZSA9IHdpZHRoICsgbWFyZ2luTGVmdCArIG1hcmdpblJpZ2h0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc2xpZGVTaXplID0gd2lkdGggKyBwYWRkaW5nTGVmdCArIHBhZGRpbmdSaWdodCArIG1hcmdpbkxlZnQgKyBtYXJnaW5SaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGhlaWdodCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnaGVpZ2h0JykgfHwgMCk7XG4gICAgICAgICAgICB2YXIgcGFkZGluZ1RvcCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy10b3AnKSB8fCAwKTtcbiAgICAgICAgICAgIHZhciBwYWRkaW5nQm90dG9tID0gcGFyc2VGbG9hdChzbGlkZVN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdwYWRkaW5nLWJvdHRvbScpIHx8IDApO1xuICAgICAgICAgICAgdmFyIG1hcmdpblRvcCA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnbWFyZ2luLXRvcCcpIHx8IDApO1xuICAgICAgICAgICAgdmFyIG1hcmdpbkJvdHRvbSA9IHBhcnNlRmxvYXQoc2xpZGVTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnbWFyZ2luLWJvdHRvbScpIHx8IDApO1xuXG4gICAgICAgICAgICB2Y
166XIgX2JveFNpemluZyA9IHNsaWRlU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoJ2JveC1zaXppbmcnKTtcblxuICAgICAgICAgICAgaWYgKF9ib3hTaXppbmcgJiYgX2JveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKSB7XG4gICAgICAgICAgICAgIHNsaWRlU2l6ZSA9IGhlaWdodCArIG1hcmdpblRvcCArIG1hcmdpbkJvdHRvbTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHNsaWRlU2l6ZSA9IGhlaWdodCArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tICsgbWFyZ2luVG9wICsgbWFyZ2luQm90dG9tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50VHJhbnNmb3JtKSB7XG4gICAgICAgICAgc2xpZGVbMF0uc3R5bGUudHJhbnNmb3JtID0gY3VycmVudFRyYW5zZm9ybTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50V2ViS2l0VHJhbnNmb3JtKSB7XG4gICAgICAgICAgc2xpZGVbMF0uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gY3VycmVudFdlYktpdFRyYW5zZm9ybTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSBzbGlkZVNpemUgPSBNYXRoLmZsb29yKHNsaWRlU2l6ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZVNpemUgPSAoc3dpcGVyU2l6ZSAtIChwYXJhbXMuc2xpZGVzUGVyVmlldyAtIDEpICogc3BhY2VCZXR3ZWVuKSAvIHBhcmFtcy5zbGlkZXNQZXJWaWV3O1xuICAgICAgICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykgc2xpZGVTaXplID0gTWF0aC5mbG9vcihzbGlkZVNpemUpO1xuXG4gICAgICAgIGlmIChzbGlkZXNbaV0pIHtcbiAgICAgICAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICBzbGlkZXNbaV0uc3R5bGUud2lkdGggPSBzbGlkZVNpemUgKyBcInB4XCI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNsaWRlc1tpXS5zdHlsZS5oZWlnaHQgPSBzbGlkZVNpemUgKyBcInB4XCI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzbGlkZXNbaV0pIHtcbiAgICAgICAgc2xpZGVzW2ldLnN3aXBlclNsaWRlU2l6ZSA9IHNsaWRlU2l6ZTtcbiAgICAgIH1cblxuICAgICAgc2xpZGVzU2l6ZXNHcmlkLnB1c2goc2xpZGVTaXplKTtcblxuICAgICAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgICBzbGlkZVBvc2l0aW9uID0gc2xpZGVQb3NpdGlvbiArIHNsaWRlU2l6ZSAvIDIgKyBwcmV2U2xpZGVTaXplIC8gMiArIHNwYWNlQmV0d2VlbjtcbiAgICAgICAgaWYgKHByZXZTbGlkZVNpemUgPT09IDAgJiYgaSAhPT0gMCkgc2xpZGVQb3NpdGlvbiA9IHNsaWRlUG9zaXRpb24gLSBzd2lwZXJTaXplIC8gMiAtIHNwYWNlQmV0d2VlbjtcbiAgICAgICAgaWYgKGkgPT09IDApIHNsaWRlUG9zaXRpb24gPSBzbGlkZVBvc2l0aW9uIC0gc3dpcGVyU2l6ZSAvIDIgLSBzcGFjZUJldHdlZW47XG4gICAgICAgIGlmIChNYXRoLmFicyhzbGlkZVBvc2l0aW9uKSA8IDEgLyAxMDAwKSBzbGlkZVBvc2l0aW9uID0gMDtcbiAgICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlUG9zaXRpb24gPSBNYXRoLmZsb29yKHNsaWRlUG9zaXRpb24pO1xuICAgICAgICBpZiAoaW5kZXggJSBwYXJhbXMuc2xpZGVzUGVyR3JvdXAgPT09IDApIHNuYXBHcmlkLnB1c2goc2xpZGVQb3NpdGlvbik7XG4gICAgICAgIHNsaWRlc0dyaWQucHVzaChzbGlkZVBvc2l0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSBzbGlkZVBvc2l0aW9uID0gTWF0aC5mbG9vcihzbGlkZVBvc2l0aW9uKTtcbiAgICAgICAgaWYgKChpbmRleCAtIE1hdGgubWluKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwLCBpbmRleCkpICUgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA9PT0gMCkgc25hcEdyaWQucHVzaChzbGlkZVBvc2l0aW9uKTtcbiAgICAgICAgc2xpZGVzR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xuICAgICAgICBzbGlkZVBvc2l0aW9uID0gc2xpZGVQb3NpdGlvbiArIHNsaWRlU2l6ZSArIHNwYWNlQmV0d2VlbjtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLnZpcnR1YWxTaXplICs9IHNsaWRlU2l6ZSArIHNwYWNlQmV0d2VlbjtcbiAgICAgIHByZXZTbGlkZVNpemUgPSBzbGlkZVNpemU7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cblxuICAgIHN3aXBlci52aXJ0dWFsU2l6ZSA9IE1hdGgubWF4KHN3aXBlci52aXJ0dWFsU2l6ZSwgc3dpcGVyU2l6ZSkgKyBvZmZzZXRBZnRlcjtcbiAgICB2YXIgbmV3U2xpZGVzR3JpZDtcblxuICAgIGlmIChydGwgJiYgd3JvbmdSVEwgJiYgKHBhcmFtcy5lZmZlY3QgPT09ICdzbGlkZScgfHwgcGFyYW1zLmVmZmVjdCA9PT0gJ2NvdmVyZmxvdycpKSB7XG4gICAgICAkd3JhcHBlckVsLmNzcyh7XG4gICAgICAgIHdpZHRoOiBzd2lwZXIudmlydHVhbFNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVuICsgXCJweFwiXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnNldFdyYXBwZXJTaXplKSB7XG4gICAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSAkd3JhcHBlckVsLmNzcyh7XG4gICAgICAgIHdpZHRoOiBzd2lwZXIudmlydHVhbFNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVuICsgXCJweFwiXG4gICAgICB9KTtlbHNlICR3cmFwcGVyRWwuY3NzKHtcbiAgICAgICAgaGVpZ2h0OiBzd2lwZXIudmlydHVhbFNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVuICsgXCJweFwiXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnNsaWRlc1BlckNvbHVtbiA+IDEpIHtcbiAgICAgIHN3aXBlci52aXJ0dWFsU2l6ZSA9IChzbGlkZVNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVuKSAqIHNsaWRlc051bWJlckV2ZW5Ub1Jvd3M7XG4gICAgICBzd2lwZXIudmlydHVhbFNpemUgPSBNYXRoLmNlaWwoc3dpcGVyLnZpcnR1YWxTaXplIC8gcGFyYW1zLnNsaWRlc1BlckNvbHVtbikgLSBwYXJhbXMuc3BhY2VCZXR3ZWVuO1xuICAgICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkgJHdyYXBwZXJFbC5jc3Moe1xuICAgICAgICB3aWR0aDogc3dpcGVyLnZpcnR1YWxTaXplICsgcGFyYW1zLnNwYWNlQmV0d2VlbiArIFwicHhcIlxuICAgICAgfSk7ZWxzZSAkd3JhcHBlckVsLmNzcyh7XG4gICAgICAgIGhlaWdodDogc3dpcGVyLnZpcnR1YWxTaXplICsgcGFyYW1zLnNwYWNlQmV0d2VlbiArIFwicHhcIlxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgICAgbmV3
166U2xpZGVzR3JpZCA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBzbmFwR3JpZC5sZW5ndGg7IF9pICs9IDEpIHtcbiAgICAgICAgICB2YXIgc2xpZGVzR3JpZEl0ZW0gPSBzbmFwR3JpZFtfaV07XG4gICAgICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlc0dyaWRJdGVtID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkSXRlbSk7XG4gICAgICAgICAgaWYgKHNuYXBHcmlkW19pXSA8IHN3aXBlci52aXJ0dWFsU2l6ZSArIHNuYXBHcmlkWzBdKSBuZXdTbGlkZXNHcmlkLnB1c2goc2xpZGVzR3JpZEl0ZW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgc25hcEdyaWQgPSBuZXdTbGlkZXNHcmlkO1xuICAgICAgfVxuICAgIH0gLy8gUmVtb3ZlIGxhc3QgZ3JpZCBlbGVtZW50cyBkZXBlbmRpbmcgb24gd2lkdGhcblxuXG4gICAgaWYgKCFwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgIG5ld1NsaWRlc0dyaWQgPSBbXTtcblxuICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc25hcEdyaWQubGVuZ3RoOyBfaTIgKz0gMSkge1xuICAgICAgICB2YXIgX3NsaWRlc0dyaWRJdGVtID0gc25hcEdyaWRbX2kyXTtcbiAgICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIF9zbGlkZXNHcmlkSXRlbSA9IE1hdGguZmxvb3IoX3NsaWRlc0dyaWRJdGVtKTtcblxuICAgICAgICBpZiAoc25hcEdyaWRbX2kyXSA8PSBzd2lwZXIudmlydHVhbFNpemUgLSBzd2lwZXJTaXplKSB7XG4gICAgICAgICAgbmV3U2xpZGVzR3JpZC5wdXNoKF9zbGlkZXNHcmlkSXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc25hcEdyaWQgPSBuZXdTbGlkZXNHcmlkO1xuXG4gICAgICBpZiAoTWF0aC5mbG9vcihzd2lwZXIudmlydHVhbFNpemUgLSBzd2lwZXJTaXplKSAtIE1hdGguZmxvb3Ioc25hcEdyaWRbc25hcEdyaWQubGVuZ3RoIC0gMV0pID4gMSkge1xuICAgICAgICBzbmFwR3JpZC5wdXNoKHN3aXBlci52aXJ0dWFsU2l6ZSAtIHN3aXBlclNpemUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzbmFwR3JpZC5sZW5ndGggPT09IDApIHNuYXBHcmlkID0gWzBdO1xuXG4gICAgaWYgKHBhcmFtcy5zcGFjZUJldHdlZW4gIT09IDApIHtcbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgaWYgKHJ0bCkgc2xpZGVzLmZpbHRlcihzbGlkZXNGb3JNYXJnaW4pLmNzcyh7XG4gICAgICAgICAgbWFyZ2luTGVmdDogc3BhY2VCZXR3ZWVuICsgXCJweFwiXG4gICAgICAgIH0pO2Vsc2Ugc2xpZGVzLmZpbHRlcihzbGlkZXNGb3JNYXJnaW4pLmNzcyh7XG4gICAgICAgICAgbWFyZ2luUmlnaHQ6IHNwYWNlQmV0d2VlbiArIFwicHhcIlxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBzbGlkZXMuZmlsdGVyKHNsaWRlc0Zvck1hcmdpbikuY3NzKHtcbiAgICAgICAgbWFyZ2luQm90dG9tOiBzcGFjZUJldHdlZW4gKyBcInB4XCJcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzQm91bmRzKSB7XG4gICAgICB2Y
166XIgYWxsU2xpZGVzU2l6ZSA9IDA7XG4gICAgICBzbGlkZXNTaXplc0dyaWQuZm9yRWFjaChmdW5jdGlvbiAoc2xpZGVTaXplVmFsdWUpIHtcbiAgICAgICAgYWxsU2xpZGVzU2l6ZSArPSBzbGlkZVNpemVWYWx1ZSArIChwYXJhbXMuc3BhY2VCZXR3ZWVuID8gcGFyYW1zLnNwYWNlQmV0d2VlbiA6IDApO1xuICAgICAgfSk7XG4gICAgICBhbGxTbGlkZXNTaXplIC09IHBhcmFtcy5zcGFjZUJldHdlZW47XG4gICAgICB2YXIgbWF4U25hcCA9IGFsbFNsaWRlc1NpemUgLSBzd2lwZXJTaXplO1xuICAgICAgc25hcEdyaWQgPSBzbmFwR3JpZC5tYXAoZnVuY3Rpb24gKHNuYXApIHtcbiAgICAgICAgaWYgKHNuYXAgPCAwKSByZXR1cm4gLW9mZnNldEJlZm9yZTtcbiAgICAgICAgaWYgKHNuYXAgPiBtYXhTbmFwKSByZXR1cm4gbWF4U25hcCArIG9mZnNldEFmdGVyO1xuICAgICAgICByZXR1cm4gc25hcDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY2VudGVySW5zdWZmaWNpZW50U2xpZGVzKSB7XG4gICAgICB2YXIgX2FsbFNsaWRlc1NpemUgPSAwO1xuICAgICAgc2xpZGVzU2l6ZXNHcmlkLmZvckVhY2goZnVuY3Rpb24gKHNsaWRlU2l6ZVZhbHVlKSB7XG4gICAgICAgIF9hbGxTbGlkZXNTaXplICs9IHNsaWRlU2l6ZVZhbHVlICsgKHBhcmFtcy5zcGFjZUJldHdlZW4gPyBwYXJhbXMuc3BhY2VCZXR3ZWVuIDogMCk7XG4gICAgICB9KTtcbiAgICAgIF9hbGxTbGlkZXNTaXplIC09IHBhcmFtcy5zcGFjZUJldHdlZW47XG5cbiAgICAgIGlmIChfYWxsU2xpZGVzU2l6ZSA8IHN3aXBlclNpemUpIHtcbiAgICAgICAgdmFyIGFsbFNsaWRlc09mZnNldCA9IChzd2lwZXJTaXplIC0gX2FsbFNsaWRlc1NpemUpIC8gMjtcbiAgICAgICAgc25hcEdyaWQuZm9yRWFjaChmdW5jdGlvbiAoc25hcCwgc25hcEluZGV4KSB7XG4gICAgICAgICAgc25hcEdyaWRbc25hcEluZGV4XSA9IHNuYXAgLSBhbGxTbGlkZXNPZmZzZXQ7XG4gICAgICAgIH0pO1xuICAgICAgICBzbGlkZXNHcmlkLmZvckVhY2goZnVuY3Rpb24gKHNuYXAsIHNuYXBJbmRleCkge1xuICAgICAgICAgIHNsaWRlc0dyaWRbc25hcEluZGV4XSA9IHNuYXAgKyBhbGxTbGlkZXNPZmZzZXQ7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGV4dGVuZCQxKHN3aXBlciwge1xuICAgICAgc2xpZGVzOiBzbGlkZXMsXG4gICAgICBzbmFwR3JpZDogc25hcEdyaWQsXG4gICAgICBzbGlkZXNHcmlkOiBzbGlkZXNHcmlkLFxuICAgICAgc2xpZGVzU2l6ZXNHcmlkOiBzbGlkZXNTaXplc0dyaWRcbiAgICB9KTtcblxuICAgIGlmIChzbGlkZXNMZW5ndGggIT09IHByZXZpb3VzU2xpZGVzTGVuZ3RoKSB7XG4gICAgICBzd2lwZXIuZW1pdCgnc2xpZGVzTGVuZ3RoQ2hhbmdlJyk7XG4gICAgfVxuXG4gICAgaWYgKHNuYXBHcmlkLmxlbmd0aCAhPT0gcHJldmlvdXNTbmFwR3JpZExlbmd0aCkge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdykgc3dpcGVyLmNoZWNrT3ZlcmZsb3coKTtcbiAgICAgIHN3aXBlci5lbWl0KCdzbmFwR3JpZExlbmd0aENoYW5nZScpO1xuICAgIH1cblxuICAgIGlmIChzbGlkZXNHcmlkLmxlbmd0aCAhPT0gcHJldmlvdXNTbGlkZXNHcmlkTGVuZ3RoKSB7XG4gICAgICBzd2lwZXIuZW1pdCgnc2xpZGVzR3JpZExlbmd0aENoYW5nZScpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyB8fCBwYXJhbXMud2F0Y2hTbGlkZXNWaXNpYmlsaXR5KSB7XG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzT2Zmc2V0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQXV0b0hlaWdodChzcGVlZCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBhY3RpdmVTbGlkZXMgPSBbXTtcbiAgICB2YXIgbmV3SGVpZ2h0ID0gMDtcbiAgICB2YXIgaTtcblxuICAgIGlmICh0eXBlb2Ygc3BlZWQgPT09ICdudW1iZXInKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihzcGVlZCk7XG4gICAgfSBlbHNlIGlmIChzcGVlZCA9PT0gdHJ1ZSkge1xuICAgICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCk7XG4gICAgfSAvLyBGaW5kIHNsaWRlcyBjdXJyZW50bHkgaW4gdmlld1xuXG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSAnYXV0bycgJiYgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgICAgc3dpcGVyLnZpc2libGVTbGlkZXMuZWFjaChmdW5jdGlvbiAoc2xpZGUpIHtcbiAgICAgICAgICBhY3RpdmVTbGlkZXMucHVzaChzbGlkZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1hdGguY2VpbChzd2lwZXIucGFyYW1zLnNsaWRlc1BlclZpZXcpOyBpICs9IDEpIHtcbiAgICAgICAgICB2Y
166XIgaW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXggKyBpO1xuICAgICAgICAgIGlmIChpbmRleCA+IHN3aXBlci5zbGlkZXMubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICBhY3RpdmVTbGlkZXMucHVzaChzd2lwZXIuc2xpZGVzLmVxKGluZGV4KVswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYWN0aXZlU2xpZGVzLnB1c2goc3dpcGVyLnNsaWRlcy5lcShzd2lwZXIuYWN0aXZlSW5kZXgpWzBdKTtcbiAgICB9IC8vIEZpbmQgbmV3IGhlaWdodCBmcm9tIGhpZ2hlc3Qgc2xpZGUgaW4gdmlld1xuXG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgYWN0aXZlU2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAodHlwZW9mIGFjdGl2ZVNsaWRlc1tpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdmFyIGhlaWdodCA9IGFjdGl2ZVNsaWRlc1tpXS5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCA+IG5ld0hlaWdodCA/IGhlaWdodCA6IG5ld0hlaWdodDtcbiAgICAgIH1cbiAgICB9IC8vIFVwZGF0ZSBIZWlnaHRcblxuXG4gICAgaWYgKG5ld0hlaWdodCkgc3dpcGVyLiR3cmFwcGVyRWwuY3NzKCdoZWlnaHQnLCBuZXdIZWlnaHQgKyBcInB4XCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2xpZGVzT2Zmc2V0KCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHNsaWRlc1tpXS5zd2lwZXJTbGlkZU9mZnNldCA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/IHNsaWRlc1tpXS5vZmZzZXRMZWZ0IDogc2xpZGVzW2ldLm9mZnNldFRvcDtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTbGlkZXNQcm9ncmVzcyh0cmFuc2xhdGUpIHtcbiAgICBpZiAodHJhbnNsYXRlID09PSB2b2lkIDApIHtcbiAgICAgIHRyYW5zbGF0ZSA9IHRoaXMgJiYgdGhpcy50cmFuc2xhdGUgfHwgMDtcbiAgICB9XG5cbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcztcbiAgICB2YXIgc2xpZGVzID0gc3dpcGVyLnNsaWRlcyxcbiAgICAgICAgcnRsID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZTtcbiAgICBpZiAoc2xpZGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGlmICh0eXBlb2Ygc2xpZGVzWzBdLnN3aXBlclNsaWRlT2Zmc2V0ID09PSAndW5kZWZpbmVkJykgc3dpcGVyLnVwZGF0ZVNsaWRlc09mZnNldCgpO1xuICAgIHZhciBvZmZzZXRDZW50ZXIgPSAtdHJhbnNsYXRlO1xuICAgIGlmIChydGwpIG9mZnNldENlbnRlciA9IHRyYW5zbGF0ZTsgLy8gVmlzaWJsZSBTbGlkZXNcblxuICAgIHNsaWRlcy5yZW1vdmVDbGFzcyhwYXJhbXMuc2xpZGVWaXNpYmxlQ2xhc3MpO1xuICAgIHN3aXBlci52aXNpYmxlU2xpZGVzSW5kZXhlcyA9IFtdO1xuICAgIHN3aXBlci52aXNpYmxlU2xpZGVzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdmFyIHNsaWRlID0gc2xpZGVzW2ldO1xuICAgICAgdmFyIHNsaWRlUHJvZ3Jlc3MgPSAob2Zmc2V0Q2VudGVyICsgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyA/IHN3aXBlci5taW5UcmFuc2xhdGUoKSA6IDApIC0gc2xpZGUuc3dpcGVyU2xpZGVPZmZzZXQpIC8gKHNsaWRlLnN3aXBlclNsaWRlU2l6ZSArIHBhcmFtcy5zcGFjZUJldHdlZW4pO1xuXG4gICAgICBpZiAocGFyYW1zLndhdGNoU2xpZGVzVmlzaWJpbGl0eSB8fCBwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgICAgdmFyIHNsaWRlQmVmb3JlID0gLShvZmZzZXRDZW50ZXIgLSBzbGlkZS5zd2lwZXJTbGlkZU9mZnNldCk7XG4gICAgICAgIHZhciBzbGlkZUFmdGVyID0gc2xpZGVCZWZvcmUgKyBzd2lwZXIuc2xpZGVzU2l6ZXNHcmlkW2ldO1xuICAgICAgICB2Y
166XIgaXNWaXNpYmxlID0gc2xpZGVCZWZvcmUgPj0gMCAmJiBzbGlkZUJlZm9yZSA8IHN3aXBlci5zaXplIC0gMSB8fCBzbGlkZUFmdGVyID4gMSAmJiBzbGlkZUFmdGVyIDw9IHN3aXBlci5zaXplIHx8IHNsaWRlQmVmb3JlIDw9IDAgJiYgc2xpZGVBZnRlciA+PSBzd2lwZXIuc2l6ZTtcblxuICAgICAgICBpZiAoaXNWaXNpYmxlKSB7XG4gICAgICAgICAgc3dpcGVyLnZpc2libGVTbGlkZXMucHVzaChzbGlkZSk7XG4gICAgICAgICAgc3dpcGVyLnZpc2libGVTbGlkZXNJbmRleGVzLnB1c2goaSk7XG4gICAgICAgICAgc2xpZGVzLmVxKGkpLmFkZENsYXNzKHBhcmFtcy5zbGlkZVZpc2libGVDbGFzcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc2xpZGUucHJvZ3Jlc3MgPSBydGwgPyAtc2xpZGVQcm9ncmVzcyA6IHNsaWRlUHJvZ3Jlc3M7XG4gICAgfVxuXG4gICAgc3dpcGVyLnZpc2libGVTbGlkZXMgPSAkKHN3aXBlci52aXNpYmxlU2xpZGVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVByb2dyZXNzKHRyYW5zbGF0ZSkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiB0cmFuc2xhdGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgbXVsdGlwbGllciA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyAtMSA6IDE7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG4gICAgICB0cmFuc2xhdGUgPSBzd2lwZXIgJiYgc3dpcGVyLnRyYW5zbGF0ZSAmJiBzd2lwZXIudHJhbnNsYXRlICogbXVsdGlwbGllciB8fCAwO1xuICAgIH1cblxuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xuICAgIHZhciB0cmFuc2xhdGVzRGlmZiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKTtcbiAgICB2YXIgcHJvZ3Jlc3MgPSBzd2lwZXIucHJvZ3Jlc3MsXG4gICAgICAgIGlzQmVnaW5uaW5nID0gc3dpcGVyLmlzQmVnaW5uaW5nLFxuICAgICAgICBpc0VuZCA9IHN3aXBlci5pc0VuZDtcbiAgICB2YXIgd2FzQmVnaW5uaW5nID0gaXNCZWdpbm5pbmc7XG4gICAgdmFyIHdhc0VuZCA9IGlzRW5kO1xuXG4gICAgaWYgKHRyYW5zbGF0ZXNEaWZmID09PSAwKSB7XG4gICAgICBwcm9ncmVzcyA9IDA7XG4gICAgICBpc0JlZ2lubmluZyA9IHRydWU7XG4gICAgICBpc0VuZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2dyZXNzID0gKHRyYW5zbGF0ZSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKSkgLyB0cmFuc2xhdGVzRGlmZjtcbiAgICAgIGlzQmVnaW5uaW5nID0gcHJvZ3Jlc3MgPD0gMDtcbiAgICAgIGlzRW5kID0gcHJvZ3Jlc3MgPj0gMTtcbiAgICB9XG5cbiAgICBleHRlbmQkMShzd2lwZXIsIHtcbiAgICAgIHByb2dyZXNzOiBwcm9ncmVzcyxcbiAgICAgIGlzQmVnaW5uaW5nOiBpc0JlZ2lubmluZyxcbiAgICAgIGlzRW5kOiBpc0VuZFxuICAgIH0pO1xuICAgIGlmIChwYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyB8fCBwYXJhbXMud2F0Y2hTbGlkZXNWaXNpYmlsaXR5IHx8IHBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiBwYXJhbXMuYXV0b0hlaWdodCkgc3dpcGVyLnVwZGF0ZVNsaWRlc1Byb2dyZXNzKHRyYW5zbGF0ZSk7XG5cbiAgICBpZiAoaXNCZWdpbm5pbmcgJiYgIXdhc0JlZ2lubmluZykge1xuICAgICAgc3dpcGVyLmVtaXQoJ3JlYWNoQmVnaW5uaW5nIHRvRWRnZScpO1xuICAgIH1cblxuICAgIGlmIChpc0VuZCAmJiAhd2FzRW5kKSB7XG4gICAgICBzd2lwZXIuZW1pdCgncmVhY2hFbmQgdG9FZGdlJyk7XG4gICAgfVxuXG4gICAgaWYgKHdhc0JlZ2lubmluZyAmJiAhaXNCZWdpbm5pbmcgfHwgd2FzRW5kICYmICFpc0VuZCkge1xuICAgICAgc3dpcGVyLmVtaXQoJ2Zyb21FZGdlJyk7XG4gICAgfVxuXG4gICAgc3dpcGVyLmVtaXQoJ3Byb2dyZXNzJywgcHJvZ3Jlc3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2xpZGVzQ2xhc3NlcygpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgc2xpZGVzID0gc3dpcGVyLnNsaWRlcyxcbiAgICAgICAgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsLFxuICAgICAgICBhY3RpdmVJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleCxcbiAgICAgICAgcmVhbEluZGV4ID0gc3dpcGVyLnJlYWxJbmRleDtcbiAgICB2YXIgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgcGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgICBzbGlkZXMucmVtb3ZlQ2xhc3MocGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MgKyBcIiBcIiArIHBhcmFtcy5zbGlkZU5leHRDbGFzcyArIFwiIFwiICsgcGFyYW1zLnNsaWRlUHJldkNsYXNzICsgXCIgXCIgKyBwYXJhbXMuc2xpZGVEdXBsaWNhdGVBY3RpdmVDbGFzcyArIFwiIFwiICsgcGFyYW1zLnNsaWRlRHVwbGljYXRlTmV4dENsYXNzICsgXCIgXCIgKyBwYXJhbXMuc2xpZGVEdXBsaWNhdGVQcmV2Q2xhc3MpO1xuICAgIHZhciBhY3RpdmVTbGlkZTtcblxuICAgIGlmIChpc1ZpcnR1YWwpIHtcbiAgICAgIGFjdGl2ZVNsaWRlID0gc3dpcGVyLiR3cmFwcGVyRWwuZmluZChcIi5cIiArIHBhcmFtcy5zbGlkZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgYWN0aXZlSW5kZXggKyBcIlxcXCJdXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY3RpdmVTbGlkZSA9IHNsaWRlcy5lcShhY3RpdmVJbmRleCk7XG4gICAgfSAvLyBBY3RpdmUgY2xhc3Nlc1xuXG5cbiAgICBhY3RpdmVTbGlkZS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVBY3RpdmVDbGFzcyk7XG5cbiAgICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICAgIC8vIER1cGxpY2F0ZSB0byBhbGwgbG9vcGVkIHNsaWRlc1xuICAgICAgaWYgKGFjdGl2ZVNsaWRlLmhhc0NsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIjpub3QoLlwiICsgcGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MgKyBcIilbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgcmVhbEluZGV4ICsgXCJcXFwiXVwiKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVEdXBsaWNhdGVBY3RpdmVDbGFzcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIi
1665cIiArIHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgcmVhbEluZGV4ICsgXCJcXFwiXVwiKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVEdXBsaWNhdGVBY3RpdmVDbGFzcyk7XG4gICAgICB9XG4gICAgfSAvLyBOZXh0IFNsaWRlXG5cblxuICAgIHZhciBuZXh0U2xpZGUgPSBhY3RpdmVTbGlkZS5uZXh0QWxsKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MpLmVxKDApLmFkZENsYXNzKHBhcmFtcy5zbGlkZU5leHRDbGFzcyk7XG5cbiAgICBpZiAocGFyYW1zLmxvb3AgJiYgbmV4dFNsaWRlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbmV4dFNsaWRlID0gc2xpZGVzLmVxKDApO1xuICAgICAgbmV4dFNsaWRlLmFkZENsYXNzKHBhcmFtcy5zbGlkZU5leHRDbGFzcyk7XG4gICAgfSAvLyBQcmV2IFNsaWRlXG5cblxuICAgIHZhciBwcmV2U2xpZGUgPSBhY3RpdmVTbGlkZS5wcmV2QWxsKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MpLmVxKDApLmFkZENsYXNzKHBhcmFtcy5zbGlkZVByZXZDbGFzcyk7XG5cbiAgICBpZiAocGFyYW1zLmxvb3AgJiYgcHJldlNsaWRlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcHJldlNsaWRlID0gc2xpZGVzLmVxKC0xKTtcbiAgICAgIHByZXZTbGlkZS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVQcmV2Q2xhc3MpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgLy8gRHVwbGljYXRlIHRvIGFsbCBsb29wZWQgc2xpZGVzXG4gICAgICBpZiAobmV4dFNsaWRlLmhhc0NsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIjpub3QoLlwiICsgcGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MgKyBcIilbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgbmV4dFNsaWRlLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JykgKyBcIlxcXCJdXCIpLmFkZENsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZU5leHRDbGFzcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIi5cIiArIHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgbmV4dFNsaWRlLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JykgKyBcIlxcXCJdXCIpLmFkZENsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZU5leHRDbGFzcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcmV2U2xpZGUuaGFzQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKSB7XG4gICAgICAgICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyArIFwiOm5vdCguXCIgKyBwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcyArIFwiKVtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cXFwiXCIgKyBwcmV2U2xpZGUuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSArIFwiXFxcIl1cIikuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlUHJldkNsYXNzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyArIFwiLlwiICsgcGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MgKyBcIltkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cXFwiXCIgKyBwcmV2U2xpZGUuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSArIFwiXFxcIl1cIikuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlUHJldkNsYXNzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2lwZXIuZW1pdFNsaWRlc0NsYXNzZXMoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUFjdGl2ZUluZGV4KG5ld0FjdGl2ZUluZGV4KSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIHRyYW5zbGF0ZSA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGU7XG4gICAgdmFyIHNsaWRlc0dyaWQgPSBzd2lwZXIuc2xpZGVzR3JpZCxcbiAgICAgICAgc25hcEdyaWQgPSBzd2lwZXIuc25hcEdyaWQsXG4gICAgICAgIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgIHByZXZpb3VzSW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXgsXG4gICAgICAgIHByZXZpb3VzUmVhbEluZGV4ID0gc3dpcGVyLnJlYWxJbmRleCxcbiAgICAgICAgcHJldmlvdXNTbmFwSW5kZXggPSBzd2lwZXIuc25hcEluZGV4O1xuICAgIHZhciBhY3RpdmVJbmRleCA9IG5ld0FjdGl2ZUluZGV4O1xuICAgIHZhciBzbmFwSW5kZXg7XG5cbiAgICBpZiAodHlwZW9mIGFjdGl2ZUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXNHcmlkLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2xpZGVzR3JpZFtpICsgMV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgaWYgKHRyYW5zbGF0ZSA+PSBzbGlkZXNHcmlkW2ldICYmIHRyYW5zbGF0ZSA8IHNsaWRlc0dyaWRbaSArIDFdIC0gKHNsaWRlc0dyaWRbaSArIDFdIC0gc2xpZGVzR3JpZFtpXSkgLyAyKSB7XG4gICAgICAgICAgICBhY3RpdmVJbmRleCA9IGk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0cmFuc2xhdGUgPj0gc2xpZGVzR3JpZFtpXSAmJiB0cmFuc2xhdGUgPCBzbGlkZXNHcmlkW2kgKyAxXSkge1xuICAgICAgICAgICAgYWN0aXZlSW5kZXggPSBpICsgMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHJhbnNsYXRlID49IHNsaWRlc0dyaWRbaV0pIHtcbiAgICAgICAgICBhY3RpdmVJbmRleCA9IGk7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gTm9ybWFsaXplIHNsaWRlSW5kZXhcblxuXG4gICAgICBpZiAocGFyYW1zLm5vcm1hbGl6ZVNsaWRlSW5kZXgpIHtcbiAgICAgICAgaWYgKGFjdGl2ZUluZGV4IDwgMCB8fCB0eXBlb2YgYWN0aXZlSW5kZXggPT09ICd1bmRlZmluZWQnKSBhY3RpdmVJbmRleCA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNuYXBHcmlkLmluZGV4T2YodHJhbnNsYXRlKSA+PSAwKSB7XG4gICAgICBzbmFwSW5kZXggPSBzbmFwR3JpZC5pbmRleE9mKHRyYW5zbGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBza2lwID0gTWF0aC5taW4ocGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCwgYWN0aXZlSW5kZXgpO1xuICAgICAgc25hcEluZGV4ID0gc2tpcCArIE1hdGguZmxvb3IoKGFjdGl2ZUluZGV4IC0gc2tpcCkgLyBwYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xuICAgIH1cblxuICAgIGlmIChzbmFwSW5kZXggPj0gc25hcEdyaWQubGVuZ3RoKSBzbmFwSW5kZXggPSBzbmFwR3JpZC5sZW5ndGggLSAxO1xuXG4gICAgaWYgKGFjdGl2ZUluZGV4ID09PSBwcmV2aW91c0luZGV4KSB7XG4gICAgICBpZiAoc25hcEluZGV4ICE9PSBwcmV2aW91c1NuYXBJbmRleCkge1xuICAgICAgICBzd2lwZXIuc25hcEluZGV4ID0gc25hcEluZGV4O1xuICAgICAgICBzd2lwZXIuZW1pdCgnc25hcEluZGV4Q2hhbmdlJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEdldCByZWFsIGluZGV4XG5cblxuICAgI
166HZhciByZWFsSW5kZXggPSBwYXJzZUludChzd2lwZXIuc2xpZGVzLmVxKGFjdGl2ZUluZGV4KS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpIHx8IGFjdGl2ZUluZGV4LCAxMCk7XG4gICAgZXh0ZW5kJDEoc3dpcGVyLCB7XG4gICAgICBzbmFwSW5kZXg6IHNuYXBJbmRleCxcbiAgICAgIHJlYWxJbmRleDogcmVhbEluZGV4LFxuICAgICAgcHJldmlvdXNJbmRleDogcHJldmlvdXNJbmRleCxcbiAgICAgIGFjdGl2ZUluZGV4OiBhY3RpdmVJbmRleFxuICAgIH0pO1xuICAgIHN3aXBlci5lbWl0KCdhY3RpdmVJbmRleENoYW5nZScpO1xuICAgIHN3aXBlci5lbWl0KCdzbmFwSW5kZXhDaGFuZ2UnKTtcblxuICAgIGlmIChwcmV2aW91c1JlYWxJbmRleCAhPT0gcmVhbEluZGV4KSB7XG4gICAgICBzd2lwZXIuZW1pdCgncmVhbEluZGV4Q2hhbmdlJyk7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5pbml0aWFsaXplZCB8fCBzd2lwZXIucGFyYW1zLnJ1bkNhbGxiYWNrc09uSW5pdCkge1xuICAgICAgc3dpcGVyLmVtaXQoJ3NsaWRlQ2hhbmdlJyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQ2xpY2tlZFNsaWRlKGUpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcztcbiAgICB2YXIgc2xpZGUgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MpWzBdO1xuICAgIHZhciBzbGlkZUZvdW5kID0gZmFsc2U7XG5cbiAgICBpZiAoc2xpZGUpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3dpcGVyLnNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc3dpcGVyLnNsaWRlc1tpXSA9PT0gc2xpZGUpIHNsaWRlRm91bmQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzbGlkZSAmJiBzbGlkZUZvdW5kKSB7XG4gICAgICBzd2lwZXIuY2xpY2tlZFNsaWRlID0gc2xpZGU7XG5cbiAgICAgIGlmIChzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xuICAgICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gcGFyc2VJbnQoJChzbGlkZSkuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSwgMTApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpcGVyLmNsaWNrZWRJbmRleCA9ICQoc2xpZGUpLmluZGV4KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci5jbGlja2VkU2xpZGUgPSB1bmRlZmluZWQ7XG4gICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuc2xpZGVUb0NsaWNrZWRTbGlkZSAmJiBzd2lwZXIuY2xpY2tlZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgc3dpcGVyLmNsaWNrZWRJbmRleCAhPT0gc3dpcGVyLmFjdGl2ZUluZGV4KSB7XG4gICAgICBzd2lwZXIuc2xpZGVUb0NsaWNrZWRTbGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB1cGRhdGUgPSB7XG4gICAgdXBkYXRlU2l6ZTogdXBkYXRlU2l6ZSxcbiAgICB1cGRhdGVTbGlkZXM6IHVwZGF0ZVNsaWRlcyxcbiAgICB1cGRhdGVBdXRvSGVpZ2h0OiB1cGRhdGVBdXRvSGVpZ2h0LFxuICAgIHVwZGF0ZVNsaWRlc09mZnNldDogdXBkYXRlU2xpZGVzT2Zmc2V0LFxuICAgIHVwZGF0ZVNsaWRlc1Byb2dyZXNzOiB1cGRhdGVTbGlkZXNQcm9ncmVzcyxcbiAgICB1cGRhdGVQcm9ncmVzczogdXBkYXRlUHJvZ3Jlc3MsXG4gICAgdXBkYXRlU2xpZGVzQ2xhc3NlczogdXBkYXRlU2xpZGVzQ2xhc3NlcyxcbiAgICB1cGRhdGVBY3RpdmVJbmRleDogdXBkYXRlQWN0aXZlSW5kZXgsXG4gICAgdXBkYXRlQ2xpY2tlZFNsaWRlOiB1cGRhdGVDbGlja2VkU2xpZGVcbiAgfTtcblxuICBmdW5jdGlvbiBnZXRTd2lwZXJUcmFuc2xhdGUoYXhpcykge1xuICAgIGlmIChheGlzID09PSB2b2lkIDApIHtcbiAgICAgIGF4aXMgPSB0aGlzLmlzSG9yaXpvbnRhbCgpID8gJ3gnIDogJ3knO1xuICAgIH1cblxuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlLFxuICAgICAgICB0cmFuc2xhdGUgPSBzd2lwZXIudHJhbnNsYXRlLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWw7XG5cbiAgICBpZiAocGFyYW1zLnZpcnR1YWxUcmFuc2xhdGUpIHtcbiAgICAgIHJldHVybiBydGwgPyAtdHJhbnNsYXRlIDogdHJhbnNsYXRlO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY3NzTW9kZSkge1xuICAgICAgcmV0dXJuIHRyYW5zbGF0ZTtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudFRyYW5zbGF0ZSA9IGdldFRyYW5zbGF0ZSgkd3JhcHBlckVsWzBdLCBheGlzKTtcbiAgICBpZiAocnRsKSBjdXJyZW50VHJhbnNsYXRlID0gLWN1cnJlbnRUcmFuc2xhdGU7XG4gICAgcmV0dXJuIGN1cnJlbnRUcmFuc2xhdGUgfHwgMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSh0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcikge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlLFxuICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgIHdyYXBwZXJFbCA9IHN3aXBlci53cmFwcGVyRWwsXG4gICAgICAgIHByb2dyZXNzID0gc3dpcGVyLnByb2dyZXNzO1xuICAgIHZhciB4ID0gMDtcbiAgICB2YXIgeSA9IDA7XG4gICAgdmFyIHogPSAwO1xuXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgeCA9IHJ0bCA/IC10cmFuc2xhdGUgOiB0cmFuc2xhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkgPSB0cmFuc2xhdGU7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHtcbiAgICAgIHggPSBNYXRoLmZsb29yKHgpO1xuICAgICAgeSA9IE1hdGguZmxvb3IoeSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICB3cmFwcGVyRWxbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gc3dpcGVyLmlzSG9yaXpvbn
166RhbCgpID8gLXggOiAteTtcbiAgICB9IGVsc2UgaWYgKCFwYXJhbXMudmlydHVhbFRyYW5zbGF0ZSkge1xuICAgICAgJHdyYXBwZXJFbC50cmFuc2Zvcm0oXCJ0cmFuc2xhdGUzZChcIiArIHggKyBcInB4LCBcIiArIHkgKyBcInB4LCBcIiArIHogKyBcInB4KVwiKTtcbiAgICB9XG5cbiAgICBzd2lwZXIucHJldmlvdXNUcmFuc2xhdGUgPSBzd2lwZXIudHJhbnNsYXRlO1xuICAgIHN3aXBlci50cmFuc2xhdGUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyB4IDogeTsgLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byB1cGRhdGUgcHJvZ3Jlc3NcblxuICAgIHZhciBuZXdQcm9ncmVzcztcbiAgICB2YXIgdHJhbnNsYXRlc0RpZmYgPSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XG5cbiAgICBpZiAodHJhbnNsYXRlc0RpZmYgPT09IDApIHtcbiAgICAgIG5ld1Byb2dyZXNzID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3UHJvZ3Jlc3MgPSAodHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAvIHRyYW5zbGF0ZXNEaWZmO1xuICAgIH1cblxuICAgIGlmIChuZXdQcm9ncmVzcyAhPT0gcHJvZ3Jlc3MpIHtcbiAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyh0cmFuc2xhdGUpO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCdzZXRUcmFuc2xhdGUnLCBzd2lwZXIudHJhbnNsYXRlLCBieUNvbnRyb2xsZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWluVHJhbnNsYXRlKCkge1xuICAgIHJldHVybiAtdGhpcy5zbmFwR3JpZFswXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1heFRyYW5zbGF0ZSgpIHtcbiAgICByZXR1cm4gLXRoaXMuc25hcEdyaWRbdGhpcy5zbmFwR3JpZC5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zbGF0ZVRvKHRyYW5zbGF0ZSwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgdHJhbnNsYXRlQm91bmRzLCBpbnRlcm5hbCkge1xuICAgIGlmICh0cmFuc2xhdGUgPT09IHZvaWQgMCkge1xuICAgICAgdHJhbnNsYXRlID0gMDtcbiAgICB9XG5cbiAgICBpZiAoc3BlZWQgPT09IHZvaWQgMCkge1xuICAgICAgc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZDtcbiAgICB9XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHRyYW5zbGF0ZUJvdW5kcyA9PT0gdm9pZCAwKSB7XG4gICAgICB0cmFuc2xhdGVCb3VuZHMgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICB3cmFwcGVyRWwgPSBzd2lwZXIud3JhcHBlckVsO1xuXG4gICAgaWYgKHN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLnByZXZlbnRJbnRlcmFjdGlvbk9uVHJhbnNpdGlvbikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBtaW5UcmFuc2xhdGUgPSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XG4gICAgdmFyIG1heFRyYW5zbGF0ZSA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcbiAgICB2YXIgbmV3VHJhbnNsYXRlO1xuICAgIGlmICh0cmFuc2xhdGVCb3VuZHMgJiYgdHJhbnNsYXRlID4gbWluVHJhbnNsYXRlKSBuZXdUcmFuc2xhdGUgPSBtaW5UcmFuc2xhdGU7ZWxzZSBpZiAodHJhbnNsYXRlQm91bmRzICYmIHRyYW5zbGF0ZSA8IG1heFRyYW5zbGF0ZSkgbmV3VHJhbnNsYXRlID0gbWF4VHJhbnNsYXRlO2Vsc2UgbmV3VHJhbnNsYXRlID0gdHJhbnNsYXRlOyAvLyBVcGRhdGUgcHJvZ3Jlc3NcblxuICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhuZXdUcmFuc2xhdGUpO1xuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICB2Y
166XIgaXNIID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuXG4gICAgICBpZiAoc3BlZWQgPT09IDApIHtcbiAgICAgICAgd3JhcHBlckVsW2lzSCA/ICdzY3JvbGxMZWZ0JyA6ICdzY3JvbGxUb3AnXSA9IC1uZXdUcmFuc2xhdGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgaWYgKHdyYXBwZXJFbC5zY3JvbGxUbykge1xuICAgICAgICAgIHZhciBfd3JhcHBlckVsJHNjcm9sbFRvO1xuXG4gICAgICAgICAgd3JhcHBlckVsLnNjcm9sbFRvKChfd3JhcHBlckVsJHNjcm9sbFRvID0ge30sIF93cmFwcGVyRWwkc2Nyb2xsVG9baXNIID8gJ2xlZnQnIDogJ3RvcCddID0gLW5ld1RyYW5zbGF0ZSwgX3dyYXBwZXJFbCRzY3JvbGxUby5iZWhhdmlvciA9ICdzbW9vdGgnLCBfd3JhcHBlckVsJHNjcm9sbFRvKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd3JhcHBlckVsW2lzSCA/ICdzY3JvbGxMZWZ0JyA6ICdzY3JvbGxUb3AnXSA9IC1uZXdUcmFuc2xhdGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHNwZWVkID09PSAwKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUobmV3VHJhbnNsYXRlKTtcblxuICAgICAgaWYgKHJ1bkNhbGxiYWNrcykge1xuICAgICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25FbmQnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3BlZWQpO1xuICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdUcmFuc2xhdGUpO1xuXG4gICAgICBpZiAocnVuQ2FsbGJhY2tzKSB7XG4gICAgICAgIHN3aXBlci5lbWl0KCdiZWZvcmVUcmFuc2l0aW9uU3RhcnQnLCBzcGVlZCwgaW50ZXJuYWwpO1xuICAgICAgICBzd2lwZXIuZW1pdCgndHJhbnNpdGlvblN0YXJ0Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc3dpcGVyLmFuaW1hdGluZykge1xuICAgICAgICBzd2lwZXIuYW5pbWF0aW5nID0gdHJ1ZTtcblxuICAgICAgICBpZiAoIXN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpIHtcbiAgICAgICAgICBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kID0gZnVuY3Rpb24gdHJhbnNpdGlvbkVuZChlKSB7XG4gICAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcbiAgICAgICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKTtcbiAgICAgICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKTtcbiAgICAgICAgICAgIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQgPSBudWxsO1xuICAgICAgICAgICAgZGVsZXRlIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQ7XG5cbiAgICAgICAgICAgIGlmIChydW5DYWxsYmFja3MpIHtcbiAgICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25FbmQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5hZGRFdmVudExpc3RlbmVyKCd3ZWJraXRUcmFuc2l0aW9uRW5kJywgc3dpcGVyLm9uVHJhbnNsYXRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB2YXIgdHJhbnNsYXRlID0ge1xuICAgIGdldFRyYW5zbGF0ZTogZ2V0U3dpcGVyVHJhbnNsYXRlLFxuICAgIHNldFRyYW5zbGF0ZTogc2V0VHJhbnNsYXRlLFxuICAgIG1pblRyYW5zbGF0ZTogbWluVHJhbnNsYXRlLFxuICAgIG1heFRyYW5zbGF0ZTogbWF4VHJhbnNsYXRlLFxuICAgIHRyYW5zbGF0ZVRvOiB0cmFuc2xhdGVUb1xuICB9O1xuXG4gIGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcikge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCdzZXRUcmFuc2l0aW9uJywgZHVyYXRpb24sIGJ5Q29udHJvbGxlcik7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pIHtcbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4LFxuICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICBwcmV2aW91c0luZGV4ID0gc3dpcGVyLnByZXZpb3VzSW5kZXg7XG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSByZXR1cm47XG5cbiAgICBpZiAocGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgIHN3aXBlci51cGRhdGVBdXRvSGVpZ2h0KCk7XG4gICAgfVxuXG4gICAgdmFyIGRpciA9IGRpcmVjdGlvbjtcblxuICAgIGlmICghZGlyKSB7XG4gICAgICBpZiAoYWN0aXZlSW5kZXggPiBwcmV2aW91c0luZGV4KSBkaXIgPSAnbmV4dCc7ZWxzZSBpZiAoYWN0aXZlSW5kZXggPCBwcmV2aW91c0luZGV4KSBkaXIgPSAncHJldic7ZWxzZSBkaXIgPSAncmVzZXQnO
1661xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCd0cmFuc2l0aW9uU3RhcnQnKTtcblxuICAgIGlmIChydW5DYWxsYmFja3MgJiYgYWN0aXZlSW5kZXggIT09IHByZXZpb3VzSW5kZXgpIHtcbiAgICAgIGlmIChkaXIgPT09ICdyZXNldCcpIHtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ3NsaWRlUmVzZXRUcmFuc2l0aW9uU3RhcnQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuZW1pdCgnc2xpZGVDaGFuZ2VUcmFuc2l0aW9uU3RhcnQnKTtcblxuICAgICAgaWYgKGRpciA9PT0gJ25leHQnKSB7XG4gICAgICAgIHN3aXBlci5lbWl0KCdzbGlkZU5leHRUcmFuc2l0aW9uU3RhcnQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5lbWl0KCdzbGlkZVByZXZUcmFuc2l0aW9uU3RhcnQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2l0aW9uRW5kJDEocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pIHtcbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4LFxuICAgICAgICBwcmV2aW91c0luZGV4ID0gc3dpcGVyLnByZXZpb3VzSW5kZXgsXG4gICAgICAgIHBhcmFtcyA9IHN3aXBlci5wYXJhbXM7XG4gICAgc3dpcGVyLmFuaW1hdGluZyA9IGZhbHNlO1xuICAgIGlmIChwYXJhbXMuY3NzTW9kZSkgcmV0dXJuO1xuICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKDApO1xuICAgIHZhciBkaXIgPSBkaXJlY3Rpb247XG5cbiAgICBpZiAoIWRpcikge1xuICAgICAgaWYgKGFjdGl2ZUluZGV4ID4gcHJldmlvdXNJbmRleCkgZGlyID0gJ25leHQnO2Vsc2UgaWYgKGFjdGl2ZUluZGV4IDwgcHJldmlvdXNJbmRleCkgZGlyID0gJ3ByZXYnO2Vsc2UgZGlyID0gJ3Jlc2V0JztcbiAgICB9XG5cbiAgICBzd2lwZXIuZW1pdCgndHJhbnNpdGlvbkVuZCcpO1xuXG4gICAgaWYgKHJ1bkNhbGxiYWNrcyAmJiBhY3RpdmVJbmRleCAhPT0gcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKGRpciA9PT0gJ3Jlc2V0Jykge1xuICAgICAgICBzd2lwZXIuZW1pdCgnc2xpZGVSZXNldFRyYW5zaXRpb25FbmQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuZW1pdCgnc2xpZGVDaGFuZ2VUcmFuc2l0aW9uRW5kJyk7XG5cbiAgICAgIGlmIChkaXIgPT09ICduZXh0Jykge1xuICAgICAgICBzd2lwZXIuZW1pdCgnc2xpZGVOZXh0VHJhbnNpdGlvbkVuZCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ3NsaWRlUHJldlRyYW5zaXRpb25FbmQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgdHJhbnNpdGlvbiQxID0ge1xuICAgIHNldFRyYW5zaXRpb246IHNldFRyYW5zaXRpb24sXG4gICAgdHJhbnNpdGlvblN0YXJ0OiB0cmFuc2l0aW9uU3RhcnQsXG4gICAgdHJhbnNpdGlvbkVuZDogdHJhbnNpdGlvbkVuZCQxXG4gIH07XG5cbiAgZnVuY3Rpb24gc2xpZGVUbyhpbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpIHtcbiAgICBpZiAoaW5kZXggPT09IHZvaWQgMCkge1xuICAgICAgaW5kZXggPSAwO1xuICAgIH1cblxuICAgIGlmIChzcGVlZCA9PT0gdm9pZCAwKSB7XG4gICAgICBzcGVlZCA9IHRoaXMucGFyYW1zLnNwZWVkO1xuICAgIH1cblxuICAgIGlmIChydW5DYWxsYmFja3MgPT09IHZvaWQgMCkge1xuICAgICAgcnVuQ2FsbGJhY2tzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgc2xpZGVJbmRleCA9IGluZGV4O1xuICAgIGlmIChzbGlkZUluZGV4IDwgMCkgc2xpZGVJbmRleCA9IDA7XG4gICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgIHNuYXBHcmlkID0gc3dpcGVyLnNuYXBHcmlkLFxuICAgICAgICBzbGlkZXNHcmlkID0gc3dpcGVyLnNsaWRlc0dyaWQsXG4gICAgICAgIHByZXZpb3VzSW5kZXggPSBzd2lwZXIucHJldmlvdXNJbmRleCxcbiAgICAgICAgYWN0aXZlSW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXgsXG4gICAgICAgIHJ0bCA9IHN3aXBlci5ydGxUcmFuc2xhdGUsXG4gICAgICAgIHdyYXBwZXJFbCA9IHN3aXBlci53cmFwcGVyRWw7XG5cbiAgICBpZiAoc3dpcGVyLmFuaW1hdGluZyAmJiBwYXJhbXMucHJldmVudEludGVyYWN0aW9uT25UcmFuc2l0aW9uKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHNraXAgPSBNYXRoLm1pbihzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCwgc2xpZGVJbmRleCk7XG4gICAgdmFyIHNuYXBJbmRleCA9IHNraXAgKyBNYXRoLmZsb29yKChzbGlkZUluZGV4IC0gc2tpcCkgLyBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwKTtcbiAgICBpZiAoc25hcEluZGV4ID49IHNuYXBHcmlkLmxlbmd0aCkgc25hcEluZGV4ID0gc25hcEdyaWQubGVuZ3RoIC0gMTtcblxuICAgIGlmICgoYWN0aXZlSW5kZXggfHwgcGFyYW1zLmluaXRpYWxTbGlkZSB8fCAwKSA9PT0gKHByZXZpb3VzSW5kZXggfHwgMCkgJiYgcnVuQ2FsbGJhY2tzKSB7XG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlU2xpZGVDaGFuZ2VTdGFydCcpO1xuICAgIH1cblxuICAgIHZhciB0cmFuc2xhdGUgPSAtc25hcEdyaWRbc25hcEluZGV4XTsgLy8gVXBkYXRlIHByb2dyZXNzXG5cbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3ModHJhbnNsYXRlKTsgLy8gTm9ybWFsaXplIHNsaWRlSW5kZXhcblxuICAgIGlmIChwYXJhbXMubm9ybWFsaXplU2xpZGVJbmRleCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXNHcmlkLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGlmICgtTWF0aC5mbG9vcih0cmFuc2xhdGUgKiAxMDApID49IE1hdGguZmxvb3Ioc2xpZGVzR3JpZFtpXSAqIDEwMCkpIHtcbiAgICAgICAgICBzbGlkZUluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gRGlyZWN0aW9ucyBsb2Nrc1xuXG5cbiAgICBpZiAoc3dpcGVyLmluaXRpYWxpemVkICYmIHNsaWRlSW5kZXggIT09IGFjdGl2ZUluZGV4KSB7XG4gICAgICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJiB0cmFuc2xhdGUgPC
166Bzd2lwZXIudHJhbnNsYXRlICYmIHRyYW5zbGF0ZSA8IHN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmIHRyYW5zbGF0ZSA+IHN3aXBlci50cmFuc2xhdGUgJiYgdHJhbnNsYXRlID4gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSB7XG4gICAgICAgIGlmICgoYWN0aXZlSW5kZXggfHwgMCkgIT09IHNsaWRlSW5kZXgpIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGlyZWN0aW9uO1xuICAgIGlmIChzbGlkZUluZGV4ID4gYWN0aXZlSW5kZXgpIGRpcmVjdGlvbiA9ICduZXh0JztlbHNlIGlmIChzbGlkZUluZGV4IDwgYWN0aXZlSW5kZXgpIGRpcmVjdGlvbiA9ICdwcmV2JztlbHNlIGRpcmVjdGlvbiA9ICdyZXNldCc7IC8vIFVwZGF0ZSBJbmRleFxuXG4gICAgaWYgKHJ0bCAmJiAtdHJhbnNsYXRlID09PSBzd2lwZXIudHJhbnNsYXRlIHx8ICFydGwgJiYgdHJhbnNsYXRlID09PSBzd2lwZXIudHJhbnNsYXRlKSB7XG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoc2xpZGVJbmRleCk7IC8vIFVwZGF0ZSBIZWlnaHRcblxuICAgICAgaWYgKHBhcmFtcy5hdXRvSGVpZ2h0KSB7XG4gICAgICAgIHN3aXBlci51cGRhdGVBdXRvSGVpZ2h0KCk7XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG5cbiAgICAgIGlmIChwYXJhbXMuZWZmZWN0ICE9PSAnc2xpZGUnKSB7XG4gICAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiAhPT0gJ3Jlc2V0Jykge1xuICAgICAgICBzd2lwZXIudHJhbnNpdGlvblN0YXJ0KHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcbiAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25FbmQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICB2Y
166XIgaXNIID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuICAgICAgdmFyIHQgPSAtdHJhbnNsYXRlO1xuXG4gICAgICBpZiAocnRsKSB7XG4gICAgICAgIHQgPSB3cmFwcGVyRWwuc2Nyb2xsV2lkdGggLSB3cmFwcGVyRWwub2Zmc2V0V2lkdGggLSB0O1xuICAgICAgfVxuXG4gICAgICBpZiAoc3BlZWQgPT09IDApIHtcbiAgICAgICAgd3JhcHBlckVsW2lzSCA/ICdzY3JvbGxMZWZ0JyA6ICdzY3JvbGxUb3AnXSA9IHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgaWYgKHdyYXBwZXJFbC5zY3JvbGxUbykge1xuICAgICAgICAgIHZhciBfd3JhcHBlckVsJHNjcm9sbFRvO1xuXG4gICAgICAgICAgd3JhcHBlckVsLnNjcm9sbFRvKChfd3JhcHBlckVsJHNjcm9sbFRvID0ge30sIF93cmFwcGVyRWwkc2Nyb2xsVG9baXNIID8gJ2xlZnQnIDogJ3RvcCddID0gdCwgX3dyYXBwZXJFbCRzY3JvbGxUby5iZWhhdmlvciA9ICdzbW9vdGgnLCBfd3JhcHBlckVsJHNjcm9sbFRvKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd3JhcHBlckVsW2lzSCA/ICdzY3JvbGxMZWZ0JyA6ICdzY3JvbGxUb3AnXSA9IHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHNwZWVkID09PSAwKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlKTtcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleChzbGlkZUluZGV4KTtcbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcbiAgICAgIHN3aXBlci50cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pO1xuICAgICAgc3dpcGVyLnRyYW5zaXRpb25FbmQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihzcGVlZCk7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHRyYW5zbGF0ZSk7XG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoc2xpZGVJbmRleCk7XG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICAgICAgc3dpcGVyLmVtaXQoJ2JlZm9yZVRyYW5zaXRpb25TdGFydCcsIHNwZWVkLCBpbnRlcm5hbCk7XG4gICAgICBzd2lwZXIudHJhbnNpdGlvblN0YXJ0KHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcblxuICAgICAgaWYgKCFzd2lwZXIuYW5pbWF0aW5nKSB7XG4gICAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xuXG4gICAgICAgIGlmICghc3dpcGVyLm9uU2xpZGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKSB7XG4gICAgICAgICAgc3dpcGVyLm9uU2xpZGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kID0gZnVuY3Rpb24gdHJhbnNpdGlvbkVuZChlKSB7XG4gICAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcbiAgICAgICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xuICAgICAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgICAgICAgICBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQgPSBudWxsO1xuICAgICAgICAgICAgZGVsZXRlIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZDtcbiAgICAgICAgICAgIHN3aXBlci50cmFuc2l0aW9uRW5kKHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2xpZGVUb0xvb3AoaW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKSB7XG4gICAgaWYgKGluZGV4ID09PSB2b2lkIDApIHtcbiAgICAgIGluZGV4ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoc3BlZWQgPT09IHZvaWQgMCkge1xuICAgICAgc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZDtcbiAgICB9XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIG5ld0luZGV4ID0gaW5kZXg7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICBuZXdJbmRleCArPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xuICAgIH1cblxuICAgIHJldHVybiBzd2lwZXIuc2xpZGVUbyhuZXdJbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xuICB9XG5cbiAgLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXG4gIGZ1bmN0aW9uIHNsaWRlTmV4dChzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCkge1xuICAgIGlmIChzcGVlZCA9PT0gdm9pZCAwKSB7XG4gICAgICBzcGVlZCA9IHRoaXMucGFyYW1zLnNwZWVkO1xuICAgIH1cblxuICAgIGlmIChydW5DYWxsYmFja3MgPT09IHZvaWQgMCkge1xuICAgICAgcnVuQ2FsbGJhY2tzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgYW5pbWF0aW5nID0gc3dpcGVyLmFuaW1hdGluZztcbiAgICB2YXIgaW5jcmVtZW50ID0gc3dpcGVyLmFjdGl2ZUluZGV4IDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCA/IDEgOiBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XG5cbiAgICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICAgIGlmIChhbmltYXRpbmcgJiYgcGFyYW1zLmxvb3BQcmV2ZW50c1NsaWRlKSByZXR1cm4gZmFsc2U7XG4gICAgICBzd2lwZXIubG9vcEZpeCgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgc3dpcGVyLl9jbGllbnRMZWZ0ID0gc3dpcGVyLiR3cmFwcGVyRWxbMF0uY2xpZW50TGVmdDtcbiAgICB9XG5cbiAgICByZXR1cm4gc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4ICsgaW5jcmVtZW50LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XG4gIH1cblxuICAvKiBlc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIgKi9cbiAgZnVuY3Rpb24gc2xpZGVQcmV2KHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKSB7XG4gICAgaWYgKHNwZWVkID09PSB2b2lkIDApIHtcbiAgICAgIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQ7XG4gICAgfVxuXG4gICAgaWYgKHJ1bkNhbGxiYWNrcyA9PT0gdm9pZCAwKSB7XG4gICAgICBydW5DYWxsYmFja3MgPSB0cnVlO1xuICAgIH1cblxuICAgI
166HZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICBhbmltYXRpbmcgPSBzd2lwZXIuYW5pbWF0aW5nLFxuICAgICAgICBzbmFwR3JpZCA9IHN3aXBlci5zbmFwR3JpZCxcbiAgICAgICAgc2xpZGVzR3JpZCA9IHN3aXBlci5zbGlkZXNHcmlkLFxuICAgICAgICBydGxUcmFuc2xhdGUgPSBzd2lwZXIucnRsVHJhbnNsYXRlO1xuXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgICBpZiAoYW5pbWF0aW5nICYmIHBhcmFtcy5sb29wUHJldmVudHNTbGlkZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgc3dpcGVyLmxvb3BGaXgoKTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cbiAgICAgIHN3aXBlci5fY2xpZW50TGVmdCA9IHN3aXBlci4kd3JhcHBlckVsWzBdLmNsaWVudExlZnQ7XG4gICAgfVxuXG4gICAgdmFyIHRyYW5zbGF0ZSA9IHJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgOiAtc3dpcGVyLnRyYW5zbGF0ZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZSh2YWwpIHtcbiAgICAgIGlmICh2YWwgPCAwKSByZXR1cm4gLU1hdGguZmxvb3IoTWF0aC5hYnModmFsKSk7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcih2YWwpO1xuICAgIH1cblxuICAgIHZhciBub3JtYWxpemVkVHJhbnNsYXRlID0gbm9ybWFsaXplKHRyYW5zbGF0ZSk7XG4gICAgdmFyIG5vcm1hbGl6ZWRTbmFwR3JpZCA9IHNuYXBHcmlkLm1hcChmdW5jdGlvbiAodmFsKSB7XG4gICAgICByZXR1cm4gbm9ybWFsaXplKHZhbCk7XG4gICAgfSk7XG4gICAgdmFyIGN1cnJlbnRTbmFwID0gc25hcEdyaWRbbm9ybWFsaXplZFNuYXBHcmlkLmluZGV4T2Yobm9ybWFsaXplZFRyYW5zbGF0ZSldO1xuICAgIHZhciBwcmV2U25hcCA9IHNuYXBHcmlkW25vcm1hbGl6ZWRTbmFwR3JpZC5pbmRleE9mKG5vcm1hbGl6ZWRUcmFuc2xhdGUpIC0gMV07XG5cbiAgICBpZiAodHlwZW9mIHByZXZTbmFwID09PSAndW5kZWZpbmVkJyAmJiBwYXJhbXMuY3NzTW9kZSkge1xuICAgICAgc25hcEdyaWQuZm9yRWFjaChmdW5jdGlvbiAoc25hcCkge1xuICAgICAgICBpZiAoIXByZXZTbmFwICYmIG5vcm1hbGl6ZWRUcmFuc2xhdGUgPj0gc25hcCkgcHJldlNuYXAgPSBzbmFwO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHByZXZJbmRleDtcblxuICAgIGlmICh0eXBlb2YgcHJldlNuYXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBwcmV2SW5kZXggPSBzbGlkZXNHcmlkLmluZGV4T2YocHJldlNuYXApO1xuICAgICAgaWYgKHByZXZJbmRleCA8IDApIHByZXZJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleCAtIDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN3aXBlci5zbGlkZVRvKHByZXZJbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xuICB9XG5cbiAgLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXG4gIGZ1bmN0aW9uIHNsaWRlUmVzZXQoc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpIHtcbiAgICBpZiAoc3BlZWQgPT09IHZvaWQgMCkge1xuICAgICAgc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZDtcbiAgICB9XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgcmV0dXJuIHN3aXBlci5zbGlkZVRvKHN3aXBlci5hY3RpdmVJbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xuICB9XG5cbiAgLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXG4gIGZ1bmN0aW9uIHNsaWRlVG9DbG9zZXN0KHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsLCB0aHJlc2hvbGQpIHtcbiAgICBpZiAoc3BlZWQgPT09IHZvaWQgMCkge1xuICAgICAgc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZDtcbiAgICB9XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcbiAgICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHRocmVzaG9sZCA9PT0gdm9pZCAwKSB7XG4gICAgICB0aHJlc2hvbGQgPSAwLjU7XG4gICAgfVxuXG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIGluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgIHZhciBza2lwID0gTWF0aC5taW4oc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAsIGluZGV4KTtcbiAgICB2YXIgc25hcEluZGV4ID0gc2tpcCArIE1hdGguZmxvb3IoKGluZGV4IC0gc2tpcCkgLyBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwKTtcbiAgICB2YXIgdHJhbnNsYXRlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgOiAtc3dpcGVyLnRyYW5zbGF0ZTtcblxuICAgIGlmICh0cmFuc2xhdGUgPj0gc3dpcGVyLnNuYXBHcmlkW3NuYXBJbmRleF0pIHtcbiAgICAgIC8vIFRoZSBjdXJyZW50IHRyYW5zbGF0ZSBpcyBvbiBvciBhZnRlciB0aGUgY3VycmVudCBzbmFwIGluZGV4LCBzbyB0aGUgY2hvaWNlXG4gICAgICAvLyBpcyBiZXR3ZWVuIHRoZSBjdXJyZW50IGluZGV4IGFuZCB0aGUgb25lIGFmdGVyIGl0LlxuICAgICAgdmFyIGN1cnJlbnRTbmFwID0gc3dpcGVyLnNuYXBHcmlkW3NuYXBJbmRleF07XG4gICAgICB2Y
166XIgbmV4dFNuYXAgPSBzd2lwZXIuc25hcEdyaWRbc25hcEluZGV4ICsgMV07XG5cbiAgICAgIGlmICh0cmFuc2xhdGUgLSBjdXJyZW50U25hcCA+IChuZXh0U25hcCAtIGN1cnJlbnRTbmFwKSAqIHRocmVzaG9sZCkge1xuICAgICAgICBpbmRleCArPSBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGUgY3VycmVudCB0cmFuc2xhdGUgaXMgYmVmb3JlIHRoZSBjdXJyZW50IHNuYXAgaW5kZXgsIHNvIHRoZSBjaG9pY2VcbiAgICAgIC8vIGlzIGJldHdlZW4gdGhlIGN1cnJlbnQgaW5kZXggYW5kIHRoZSBvbmUgYmVmb3JlIGl0LlxuICAgICAgdmFyIHByZXZTbmFwID0gc3dpcGVyLnNuYXBHcmlkW3NuYXBJbmRleCAtIDFdO1xuICAgICAgdmFyIF9jdXJyZW50U25hcCA9IHN3aXBlci5zbmFwR3JpZFtzbmFwSW5kZXhdO1xuXG4gICAgICBpZiAodHJhbnNsYXRlIC0gcHJldlNuYXAgPD0gKF9jdXJyZW50U25hcCAtIHByZXZTbmFwKSAqIHRocmVzaG9sZCkge1xuICAgICAgICBpbmRleCAtPSBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwO1xuICAgICAgfVxuICAgIH1cblxuICAgIGluZGV4ID0gTWF0aC5tYXgoaW5kZXgsIDApO1xuICAgIGluZGV4ID0gTWF0aC5taW4oaW5kZXgsIHN3aXBlci5zbGlkZXNHcmlkLmxlbmd0aCAtIDEpO1xuICAgIHJldHVybiBzd2lwZXIuc2xpZGVUbyhpbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2xpZGVUb0NsaWNrZWRTbGlkZSgpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsO1xuICAgIHZhciBzbGlkZXNQZXJWaWV3ID0gcGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyA/IHN3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygpIDogcGFyYW1zLnNsaWRlc1BlclZpZXc7XG4gICAgdmFyIHNsaWRlVG9JbmRleCA9IHN3aXBlci5jbGlja2VkSW5kZXg7XG4gICAgdmFyIHJlYWxJbmRleDtcblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgaWYgKHN3aXBlci5hbmltYXRpbmcpIHJldHVybjtcbiAgICAgIHJlYWxJbmRleCA9IHBhcnNlSW50KCQoc3dpcGVyLmNsaWNrZWRTbGlkZSkuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSwgMTApO1xuXG4gICAgICBpZiAocGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XG4gICAgICAgIGlmIChzbGlkZVRvSW5kZXggPCBzd2lwZXIubG9vcGVkU2xpZGVzIC0gc2xpZGVzUGVyVmlldyAvIDIgfHwgc2xpZGVUb0luZGV4ID4gc3dpcGVyLnNsaWRlcy5sZW5ndGggLSBzd2lwZXIubG9vcGVkU2xpZGVzICsgc2xpZGVzUGVyVmlldyAvIDIpIHtcbiAgICAgICAgICBzd2lwZXIubG9vcEZpeCgpO1xuICAgICAgICAgIHNsaWRlVG9JbmRleCA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyArIFwiW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVxcXCJcIiArIHJlYWxJbmRleCArIFwiXFxcIl06bm90KC5cIiArIHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzICsgXCIpXCIpLmVxKDApLmluZGV4KCk7XG4gICAgICAgICAgbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNsaWRlVG9JbmRleCA+IHN3aXBlci5zbGlkZXMubGVuZ3RoIC0gc2xpZGVzUGVyVmlldykge1xuICAgICAgICBzd2lwZXIubG9vcEZpeCgpO1xuICAgICAgICBzbGlkZVRvSW5kZXggPSAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIltkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cXFwiXCIgKyByZWFsSW5kZXggKyBcIlxcXCJdOm5vdCguXCIgKyBwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcyArIFwiKVwiKS5lcSgwKS5pbmRleCgpO1xuICAgICAgICBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzbGlkZSA9IHtcbiAgICBzbGlkZVRvOiBzbGlkZVRvLFxuICAgIHNsaWRlVG9Mb29wOiBzbGlkZVRvTG9vcCxcbiAgICBzbGlkZU5leHQ6IHNsaWRlTmV4dCxcbiAgICBzbGlkZVByZXY6IHNsaWRlUHJldixcbiAgICBzbGlkZVJlc2V0OiBzbGlkZVJlc2V0LFxuICAgIHNsaWRlVG9DbG9zZXN0OiBzbGlkZVRvQ2xvc2VzdCxcbiAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBzbGlkZVRvQ2xpY2tlZFNsaWRlXG4gIH07XG5cbiAgZnVuY3Rpb24gbG9vcENyZWF0ZSgpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWw7IC8vIFJlbW92ZSBkdXBsaWNhdGVkIHNsaWRlc1xuXG4gICAgJHdyYXBwZXJFbC5jaGlsZHJlbihcIi5cIiArIHBhcmFtcy5zbGlkZUNsYXNzICsgXCIuXCIgKyBwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcykucmVtb3ZlKCk7XG4gICAgdmFyIHNsaWRlcyA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyk7XG5cbiAgICBpZiAocGFyYW1zLmxvb3BGaWxsR3JvdXBXaXRoQmxhbmspIHtcbiAgICAgIHZhciBibGFua1NsaWRlc051bSA9IHBhcmFtcy5zbGlkZXNQZXJHcm91cCAtIHNsaWRlcy5sZW5ndGggJSBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XG5cbiAgICAgIGlmIChibGFua1NsaWRlc051bSAhPT0gcGFyYW1zLnNsaWRlc1Blckdyb3VwKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxhbmtTbGlkZXNOdW07IGkgKz
1660gMSkge1xuICAgICAgICAgIHZhciBibGFua05vZGUgPSAkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVDbGFzcyArIFwiIFwiICsgcGFyYW1zLnNsaWRlQmxhbmtDbGFzcyk7XG4gICAgICAgICAgJHdyYXBwZXJFbC5hcHBlbmQoYmxhbmtOb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNsaWRlcyA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycgJiYgIXBhcmFtcy5sb29wZWRTbGlkZXMpIHBhcmFtcy5sb29wZWRTbGlkZXMgPSBzbGlkZXMubGVuZ3RoO1xuICAgIHN3aXBlci5sb29wZWRTbGlkZXMgPSBNYXRoLmNlaWwocGFyc2VGbG9hdChwYXJhbXMubG9vcGVkU2xpZGVzIHx8IHBhcmFtcy5zbGlkZXNQZXJWaWV3LCAxMCkpO1xuICAgIHN3aXBlci5sb29wZWRTbGlkZXMgKz0gcGFyYW1zLmxvb3BBZGRpdGlvbmFsU2xpZGVzO1xuXG4gICAgaWYgKHN3aXBlci5sb29wZWRTbGlkZXMgPiBzbGlkZXMubGVuZ3RoKSB7XG4gICAgICBzd2lwZXIubG9vcGVkU2xpZGVzID0gc2xpZGVzLmxlbmd0aDtcbiAgICB9XG5cbiAgICB2YXIgcHJlcGVuZFNsaWRlcyA9IFtdO1xuICAgIHZhciBhcHBlbmRTbGlkZXMgPSBbXTtcbiAgICBzbGlkZXMuZWFjaChmdW5jdGlvbiAoZWwsIGluZGV4KSB7XG4gICAgICB2YXIgc2xpZGUgPSAkKGVsKTtcblxuICAgICAgaWYgKGluZGV4IDwgc3dpcGVyLmxvb3BlZFNsaWRlcykge1xuICAgICAgICBhcHBlbmRTbGlkZXMucHVzaChlbCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleCA8IHNsaWRlcy5sZW5ndGggJiYgaW5kZXggPj0gc2xpZGVzLmxlbmd0aCAtIHN3aXBlci5sb29wZWRTbGlkZXMpIHtcbiAgICAgICAgcHJlcGVuZFNsaWRlcy5wdXNoKGVsKTtcbiAgICAgIH1cblxuICAgICAgc2xpZGUuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBpbmRleCk7XG4gICAgfSk7XG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXBwZW5kU2xpZGVzLmxlbmd0aDsgX2kgKz0gMSkge1xuICAgICAgJHdyYXBwZXJFbC5hcHBlbmQoJChhcHBlbmRTbGlkZXNbX2ldLmNsb25lTm9kZSh0cnVlKSkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBfaTIgPSBwcmVwZW5kU2xpZGVzLmxlbmd0aCAtIDE7IF9pMiA+PSAwOyBfaTIgLT0gMSkge1xuICAgICAgJHdyYXBwZXJFbC5wcmVwZW5kKCQocHJlcGVuZFNsaWRlc1tfaTJdLmNsb25lTm9kZSh0cnVlKSkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBsb29wRml4KCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHN3aXBlci5lbWl0KCdiZWZvcmVMb29wRml4Jyk7XG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4LFxuICAgICAgICBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzLFxuICAgICAgICBsb29wZWRTbGlkZXMgPSBzd2lwZXIubG9vcGVkU2xpZGVzLFxuICAgICAgICBhbGxvd1NsaWRlUHJldiA9IHN3aXBlci5hbGxvd1NsaWRlUHJldixcbiAgICAgICAgYWxsb3dTbGlkZU5leHQgPSBzd2lwZXIuYWxsb3dTbGlkZU5leHQsXG4gICAgICAgIHNuYXBHcmlkID0gc3dpcGVyLnNuYXBHcmlkLFxuICAgICAgICBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlO1xuICAgIHZhciBuZXdJbmRleDtcbiAgICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSB0cnVlO1xuICAgIHN3aXBlci5hbGxvd1NsaWRlTmV4dCA9IHRydWU7XG4gICAgdmFyIHNuYXBUcmFuc2xhdGUgPSAtc25hcEdyaWRbYWN0aXZlSW5kZXhdO1xuICAgIHZhciBkaWZmID0gc25hcFRyYW5zbGF0ZSAtIHN3aXBlci5nZXRUcmFuc2xhdGUoKTsgLy8gRml4IEZvciBOZWdhdGl2ZSBPdmVyc2xpZGluZ1xuXG4gICAgaWYgKGFjdGl2ZUluZGV4IDwgbG9vcGVkU2xpZGVzKSB7XG4gICAgICBuZXdJbmRleCA9IHNsaWRlcy5sZW5ndGggLSBsb29wZWRTbGlkZXMgKiAzICsgYWN0aXZlSW5kZXg7XG4gICAgICBuZXdJbmRleCArPSBsb29wZWRTbGlkZXM7XG4gICAgICB2Y
166XIgc2xpZGVDaGFuZ2VkID0gc3dpcGVyLnNsaWRlVG8obmV3SW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcblxuICAgICAgaWYgKHNsaWRlQ2hhbmdlZCAmJiBkaWZmICE9PSAwKSB7XG4gICAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUoKHJ0bCA/IC1zd2lwZXIudHJhbnNsYXRlIDogc3dpcGVyLnRyYW5zbGF0ZSkgLSBkaWZmKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGFjdGl2ZUluZGV4ID49IHNsaWRlcy5sZW5ndGggLSBsb29wZWRTbGlkZXMpIHtcbiAgICAgIC8vIEZpeCBGb3IgUG9zaXRpdmUgT3ZlcnNsaWRpbmdcbiAgICAgIG5ld0luZGV4ID0gLXNsaWRlcy5sZW5ndGggKyBhY3RpdmVJbmRleCArIGxvb3BlZFNsaWRlcztcbiAgICAgIG5ld0luZGV4ICs9IGxvb3BlZFNsaWRlcztcblxuICAgICAgdmFyIF9zbGlkZUNoYW5nZWQgPSBzd2lwZXIuc2xpZGVUbyhuZXdJbmRleCwgMCwgZmFsc2UsIHRydWUpO1xuXG4gICAgICBpZiAoX3NsaWRlQ2hhbmdlZCAmJiBkaWZmICE9PSAwKSB7XG4gICAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUoKHJ0bCA/IC1zd2lwZXIudHJhbnNsYXRlIDogc3dpcGVyLnRyYW5zbGF0ZSkgLSBkaWZmKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSBhbGxvd1NsaWRlUHJldjtcbiAgICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSBhbGxvd1NsaWRlTmV4dDtcbiAgICBzd2lwZXIuZW1pdCgnbG9vcEZpeCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gbG9vcERlc3Ryb3koKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyICR3cmFwcGVyRWwgPSBzd2lwZXIuJHdyYXBwZXJFbCxcbiAgICAgICAgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgc2xpZGVzID0gc3dpcGVyLnNsaWRlcztcbiAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIi5cIiArIHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzICsgXCIsLlwiICsgcGFyYW1zLnNsaWRlQ2xhc3MgKyBcIi5cIiArIHBhcmFtcy5zbGlkZUJsYW5rQ2xhc3MpLnJlbW92ZSgpO1xuICAgIHNsaWRlcy5yZW1vdmVBdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpO1xuICB9XG5cbiAgdmFyIGxvb3AgPSB7XG4gICAgbG9vcENyZWF0ZTogbG9vcENyZWF0ZSxcbiAgICBsb29wRml4OiBsb29wRml4LFxuICAgIGxvb3BEZXN0cm95OiBsb29wRGVzdHJveVxuICB9O1xuXG4gIGZ1bmN0aW9uIHNldEdyYWJDdXJzb3IobW92aW5nKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgaWYgKHN3aXBlci5zdXBwb3J0LnRvdWNoIHx8ICFzd2lwZXIucGFyYW1zLnNpbXVsYXRlVG91Y2ggfHwgc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5pc0xvY2tlZCB8fCBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJldHVybjtcbiAgICB2YXIgZWwgPSBzd2lwZXIuZWw7XG4gICAgZWwuc3R5bGUuY3Vyc29yID0gJ21vdmUnO1xuICAgIGVsLnN0eWxlLmN1cnNvciA9IG1vdmluZyA/ICctd2Via2l0LWdyYWJiaW5nJyA6ICctd2Via2l0LWdyYWInO1xuICAgIGVsLnN0eWxlLmN1cnNvciA9IG1vdmluZyA/ICctbW96LWdyYWJiaW4nIDogJy1tb3otZ3JhYic7XG4gICAgZWwuc3R5bGUuY3Vyc29yID0gbW92aW5nID8gJ2dyYWJiaW5nJyA6ICdncmFiJztcbiAgfVxuXG4gIGZ1bmN0aW9uIHVuc2V0R3JhYkN1cnNvcigpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcblxuICAgIGlmIChzd2lwZXIuc3VwcG9ydC50b3VjaCB8fCBzd2lwZXIucGFyYW1zLndhdGNoT3ZlcmZsb3cgJiYgc3dpcGVyLmlzTG9ja2VkIHx8IHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXBlci5lbC5zdHlsZS5jdXJzb3IgPSAnJztcbiAgfVxuXG4gIHZhciBncmFiQ3Vyc29yID0ge1xuICAgIHNldEdyYWJDdXJzb3I6IHNldEdyYWJDdXJzb3IsXG4gICAgdW5zZXRHcmFiQ3Vyc29yOiB1bnNldEdyYWJDdXJzb3JcbiAgfTtcblxuICBmdW5jdGlvbiBhcHBlbmRTbGlkZShzbGlkZXMpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsLFxuICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xuXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNsaWRlcyA9PT0gJ29iamVjdCcgJiYgJ2xlbmd0aCcgaW4gc2xpZGVzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc2xpZGVzW2ldKSAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXNbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXMpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgICB9XG5cbiAgICBpZiAoIShwYXJhbXMub2JzZXJ2ZXIgJiYgc3dpcGVyLnN1cHBvcnQub2JzZXJ2ZXIpKSB7XG4gICAgICBzd2lwZXIudXBkYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcHJlcGVuZFNsaWRlKHNsaWRlcykge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleCArIDE7XG5cbiAgICBpZiAodHlwZW9mIHNsaWRlcyA9PT0gJ29iamVjdCcgJiYgJ2xlbmd0aCcgaW4gc2xpZGVzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc2xpZGVzW2ldKSAkd3JhcHBlckVsLnByZXBlbmQoc2xpZGVzW2ldKTtcbiAgICAgIH1cblxuICAgICAgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleCArIHNsaWRlcy5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICR3cmFwcGVyRWwucHJlcGVuZChzbGlkZXMpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgICB9XG5cbiAgICBpZiAoIShwYXJhbXMub2JzZXJ2ZXIgJiYgc3dpcGVyLnN1cHBvcnQub2JzZXJ2ZXIpKSB7XG4gICAgICBzd2lwZXIudXBkYXRlKCk7XG4gICAgfVxuXG4gICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXgsIDAsIGZhbHNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFNsaWRlKGluZGV4LCBzbGlkZXMpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsLFxuICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICBhY3RpdmVJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleDtcbiAgICB2YXIgYWN0aXZlSW5kZXhCdWZmZXIgPSBhY3RpdmVJbmRleDtcblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgYWN0aXZlSW5kZXhCdWZmZXIgLT0gc3dpcGVyLmxvb3BlZFNsaWRlcztcbiAgICAgIHN3aXBlci5sb29wRGVzdHJveSgpO1xuICAgICAgc3dpcGVyLnNsaWRlcyA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBwYXJhbXMuc2xpZGVDbGFzcyk7XG4gICAgfVxuXG4gICAgdmFyIGJhc2VMZW5ndGggPSBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcblxuICAgIGlmIChpbmRleCA8PSAwKSB7XG4gICAgICBzd2lwZXIucHJlcGVuZFNsaWRlKHNsaWRlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IGJhc2VMZW5ndGgpIHtcbiAgICAgIHN3aXBlci5hcHBlbmRTbGlkZShzbGlkZXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgI
166HZhciBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4QnVmZmVyID4gaW5kZXggPyBhY3RpdmVJbmRleEJ1ZmZlciArIDEgOiBhY3RpdmVJbmRleEJ1ZmZlcjtcbiAgICB2YXIgc2xpZGVzQnVmZmVyID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gYmFzZUxlbmd0aCAtIDE7IGkgPj0gaW5kZXg7IGkgLT0gMSkge1xuICAgICAgdmFyIGN1cnJlbnRTbGlkZSA9IHN3aXBlci5zbGlkZXMuZXEoaSk7XG4gICAgICBjdXJyZW50U2xpZGUucmVtb3ZlKCk7XG4gICAgICBzbGlkZXNCdWZmZXIudW5zaGlmdChjdXJyZW50U2xpZGUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc2xpZGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXMpIHtcbiAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBzbGlkZXMubGVuZ3RoOyBfaSArPSAxKSB7XG4gICAgICAgIGlmIChzbGlkZXNbX2ldKSAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXNbX2ldKTtcbiAgICAgIH1cblxuICAgICAgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleEJ1ZmZlciA+IGluZGV4ID8gYWN0aXZlSW5kZXhCdWZmZXIgKyBzbGlkZXMubGVuZ3RoIDogYWN0aXZlSW5kZXhCdWZmZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICR3cmFwcGVyRWwuYXBwZW5kKHNsaWRlcyk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc2xpZGVzQnVmZmVyLmxlbmd0aDsgX2kyICs9IDEpIHtcbiAgICAgICR3cmFwcGVyRWwuYXBwZW5kKHNsaWRlc0J1ZmZlcltfaTJdKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICAgIHN3aXBlci5sb29wQ3JlYXRlKCk7XG4gICAgfVxuXG4gICAgaWYgKCEocGFyYW1zLm9ic2VydmVyICYmIHN3aXBlci5zdXBwb3J0Lm9ic2VydmVyKSkge1xuICAgICAgc3dpcGVyLnVwZGF0ZSgpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXggKyBzd2lwZXIubG9vcGVkU2xpZGVzLCAwLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci5zbGlkZVRvKG5ld0FjdGl2ZUluZGV4LCAwLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlU2xpZGUoc2xpZGVzSW5kZXhlcykge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgIHZhciBhY3RpdmVJbmRleEJ1ZmZlciA9IGFjdGl2ZUluZGV4O1xuXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgICBhY3RpdmVJbmRleEJ1ZmZlciAtPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xuICAgICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XG4gICAgICBzd2lwZXIuc2xpZGVzID0gJHdyYXBwZXJFbC5jaGlsZHJlbihcIi5cIiArIHBhcmFtcy5zbGlkZUNsYXNzKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleEJ1ZmZlcjtcbiAgICB2YXIgaW5kZXhUb1JlbW92ZTtcblxuICAgIGlmICh0eXBlb2Ygc2xpZGVzSW5kZXhlcyA9PT0gJ29iamVjdCcgJiYgJ2xlbmd0aCcgaW4gc2xpZGVzSW5kZXhlcykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXNJbmRleGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGluZGV4VG9SZW1vdmUgPSBzbGlkZXNJbmRleGVzW2ldO1xuICAgICAgICBpZiAoc3dpcGVyLnNsaWRlc1tpbmRleFRvUmVtb3ZlXSkgc3dpcGVyLnNsaWRlcy5lcShpbmRleFRvUmVtb3ZlKS5yZW1vdmUoKTtcbiAgICAgICAgaWYgKGluZGV4VG9SZW1vdmUgPCBuZXdBY3RpdmVJbmRleCkgbmV3QWN0aXZlSW5kZXggLT0gMTtcbiAgICAgIH1cblxuICAgICAgbmV3QWN0aXZlSW5kZXggPSBNYXRoLm1heChuZXdBY3RpdmVJbmRleCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGluZGV4VG9SZW1vdmUgPSBzbGlkZXNJbmRleGVzO1xuICAgICAgaWYgKHN3aXBlci5zbGlkZXNbaW5kZXhUb1JlbW92ZV0pIHN3aXBlci5zbGlkZXMuZXEoaW5kZXhUb1JlbW92ZSkucmVtb3ZlKCk7XG4gICAgICBpZiAoaW5kZXhUb1JlbW92ZSA8IG5ld0FjdGl2ZUluZGV4KSBuZXdBY3RpdmVJbmRleCAtPSAxO1xuICAgICAgbmV3QWN0aXZlSW5kZXggPSBNYXRoLm1heChuZXdBY3RpdmVJbmRleCwgMCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgICBzd2lwZXIubG9vcENyZWF0ZSgpO1xuICAgIH1cblxuICAgIGlmICghKHBhcmFtcy5vYnNlcnZlciAmJiBzd2lwZXIuc3VwcG9ydC5vYnNlcnZlcikpIHtcbiAgICAgIHN3aXBlci51cGRhdGUoKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICAgIHN3aXBlci5zbGlkZVRvKG5ld0FjdGl2ZUluZGV4ICsgc3dpcGVyLmxvb3BlZFNsaWRlcywgMCwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCwgMCwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUFsbFNsaWRlcygpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgc2xpZGVzSW5kZXhlcyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzd2lwZXIuc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBzbGlkZXNJbmRleGVzLnB1c2goaSk7XG4gICAgfVxuXG4gICAgc3dpcGVyLnJlbW92ZVNsaWRlKHNsaWRlc0luZGV4ZXMpO1xuICB9XG5cbiAgdmFyIG1hbmlwdWxhdGlvbiA9IHtcbiAgICBhcHBlbmRTbGlkZTogYXBwZW5kU2xpZGUsXG4gICAgcHJlcGVuZFNsaWRlOiBwcmVwZW5kU2xpZGUsXG4gICAgYWRkU2xpZGU6IGFkZFNsaWRlLFxuICAgIHJlbW92ZVNsaWRlOiByZW1vdmVTbGlkZSxcbiAgICByZW1vdmVBbGxTbGlkZXM6IHJlbW92ZUFsbFNsaWRlc1xuICB9O1xuXG4gIGZ1bmN0aW9uIG9uVG91Y2hTdGFydChldmVudCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIHZhciBkYXRhID0gc3dpcGVyLnRvdWNoRXZlbnRzRGF0YTtcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgdG91Y2hlcyA9IHN3aXBlci50b3VjaGVzO1xuXG4gICAgaWYgKHN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLnByZX
166ZlbnRJbnRlcmFjdGlvbk9uVHJhbnNpdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlID0gZXZlbnQ7XG4gICAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcbiAgICB2YXIgJHRhcmdldEVsID0gJChlLnRhcmdldCk7XG5cbiAgICBpZiAocGFyYW1zLnRvdWNoRXZlbnRzVGFyZ2V0ID09PSAnd3JhcHBlcicpIHtcbiAgICAgIGlmICghJHRhcmdldEVsLmNsb3Nlc3Qoc3dpcGVyLndyYXBwZXJFbCkubGVuZ3RoKSByZXR1cm47XG4gICAgfVxuXG4gICAgZGF0YS5pc1RvdWNoRXZlbnQgPSBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JztcbiAgICBpZiAoIWRhdGEuaXNUb3VjaEV2ZW50ICYmICd3aGljaCcgaW4gZSAmJiBlLndoaWNoID09PSAzKSByZXR1cm47XG4gICAgaWYgKCFkYXRhLmlzVG91Y2hFdmVudCAmJiAnYnV0dG9uJyBpbiBlICYmIGUuYnV0dG9uID4gMCkgcmV0dXJuO1xuICAgIGlmIChkYXRhLmlzVG91Y2hlZCAmJiBkYXRhLmlzTW92ZWQpIHJldHVybjtcblxuICAgIGlmIChwYXJhbXMubm9Td2lwaW5nICYmICR0YXJnZXRFbC5jbG9zZXN0KHBhcmFtcy5ub1N3aXBpbmdTZWxlY3RvciA/IHBhcmFtcy5ub1N3aXBpbmdTZWxlY3RvciA6IFwiLlwiICsgcGFyYW1zLm5vU3dpcGluZ0NsYXNzKVswXSkge1xuICAgICAgc3dpcGVyLmFsbG93Q2xpY2sgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuc3dpcGVIYW5kbGVyKSB7XG4gICAgICBpZiAoISR0YXJnZXRFbC5jbG9zZXN0KHBhcmFtcy5zd2lwZUhhbmRsZXIpWzBdKSByZXR1cm47XG4gICAgfVxuXG4gICAgdG91Y2hlcy5jdXJyZW50WCA9IGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYIDogZS5wYWdlWDtcbiAgICB0b3VjaGVzLmN1cnJlbnRZID0gZS50eXBlID09PSAndG91Y2hzdGFydCcgPyBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkgOiBlLnBhZ2VZO1xuICAgIHZhciBzdGFydFggPSB0b3VjaGVzLmN1cnJlbnRYO1xuICAgIHZhciBzdGFydFkgPSB0b3VjaGVzLmN1cnJlbnRZOyAvLyBEbyBOT1Qgc3RhcnQgaWYgaU9TIGVkZ2Ugc3dpcGUgaXMgZGV0ZWN0ZWQuIE90aGVyd2lzZSBpT1MgYXBwIGNhbm5vdCBzd2lwZS10by1nby1iYWNrIGFueW1vcmVcblxuICAgI
166HZhciBlZGdlU3dpcGVEZXRlY3Rpb24gPSBwYXJhbXMuZWRnZVN3aXBlRGV0ZWN0aW9uIHx8IHBhcmFtcy5pT1NFZGdlU3dpcGVEZXRlY3Rpb247XG4gICAgdmFyIGVkZ2VTd2lwZVRocmVzaG9sZCA9IHBhcmFtcy5lZGdlU3dpcGVUaHJlc2hvbGQgfHwgcGFyYW1zLmlPU0VkZ2VTd2lwZVRocmVzaG9sZDtcblxuICAgIGlmIChlZGdlU3dpcGVEZXRlY3Rpb24gJiYgKHN0YXJ0WCA8PSBlZGdlU3dpcGVUaHJlc2hvbGQgfHwgc3RhcnRYID49IHdpbmRvdy5zY3JlZW4ud2lkdGggLSBlZGdlU3dpcGVUaHJlc2hvbGQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXh0ZW5kJDEoZGF0YSwge1xuICAgICAgaXNUb3VjaGVkOiB0cnVlLFxuICAgICAgaXNNb3ZlZDogZmFsc2UsXG4gICAgICBhbGxvd1RvdWNoQ2FsbGJhY2tzOiB0cnVlLFxuICAgICAgaXNTY3JvbGxpbmc6IHVuZGVmaW5lZCxcbiAgICAgIHN0YXJ0TW92aW5nOiB1bmRlZmluZWRcbiAgICB9KTtcbiAgICB0b3VjaGVzLnN0YXJ0WCA9IHN0YXJ0WDtcbiAgICB0b3VjaGVzLnN0YXJ0WSA9IHN0YXJ0WTtcbiAgICBkYXRhLnRvdWNoU3RhcnRUaW1lID0gbm93KCk7XG4gICAgc3dpcGVyLmFsbG93Q2xpY2sgPSB0cnVlO1xuICAgIHN3aXBlci51cGRhdGVTaXplKCk7XG4gICAgc3dpcGVyLnN3aXBlRGlyZWN0aW9uID0gdW5kZWZpbmVkO1xuICAgIGlmIChwYXJhbXMudGhyZXNob2xkID4gMCkgZGF0YS5hbGxvd1RocmVzaG9sZE1vdmUgPSBmYWxzZTtcblxuICAgIGlmIChlLnR5cGUgIT09ICd0b3VjaHN0YXJ0Jykge1xuICAgICAgdmFyIHByZXZlbnREZWZhdWx0ID0gdHJ1ZTtcbiAgICAgIGlmICgkdGFyZ2V0RWwuaXMoZGF0YS5mb3JtRWxlbWVudHMpKSBwcmV2ZW50RGVmYXVsdCA9IGZhbHNlO1xuXG4gICAgICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJiAkKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpLmlzKGRhdGEuZm9ybUVsZW1lbnRzKSAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSAkdGFyZ2V0RWxbMF0pIHtcbiAgICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ibHVyKCk7XG4gICAgICB9XG5cbiAgICAgIHZhciBzaG91bGRQcmV2ZW50RGVmYXVsdCA9IHByZXZlbnREZWZhdWx0ICYmIHN3aXBlci5hbGxvd1RvdWNoTW92ZSAmJiBwYXJhbXMudG91Y2hTdGFydFByZXZlbnREZWZhdWx0O1xuXG4gICAgICBpZiAocGFyYW1zLnRvdWNoU3RhcnRGb3JjZVByZXZlbnREZWZhdWx0IHx8IHNob3VsZFByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2lwZXIuZW1pdCgndG91Y2hTdGFydCcsIGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Ub3VjaE1vdmUoZXZlbnQpIHtcbiAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBkYXRhID0gc3dpcGVyLnRvdWNoRXZlbnRzRGF0YTtcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgdG91Y2hlcyA9IHN3aXBlci50b3VjaGVzLFxuICAgICAgICBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlO1xuICAgIHZhciBlID0gZXZlbnQ7XG4gICAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcblxuICAgIGlmICghZGF0YS5pc1RvdWNoZWQpIHtcbiAgICAgIGlmIChkYXRhLnN0YXJ0TW92aW5nICYmIGRhdGEuaXNTY3JvbGxpbmcpIHtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ3RvdWNoTW92ZU9wcG9zaXRlJywgZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5pc1RvdWNoRXZlbnQgJiYgZS50eXBlICE9PSAndG91Y2htb3ZlJykgcmV0dXJuO1xuICAgIHZhciB0YXJnZXRUb3VjaCA9IGUudHlwZSA9PT0gJ3RvdWNobW92ZScgJiYgZS50YXJnZXRUb3VjaGVzICYmIChlLnRhcmdldFRvdWNoZXNbMF0gfHwgZS5jaGFuZ2VkVG91Y2hlc1swXSk7XG4gICAgdmFyIHBhZ2VYID0gZS50eXBlID09PSAndG91Y2htb3ZlJyA/IHRhcmdldFRvdWNoLnBhZ2VYIDogZS5wYWdlWDtcbiAgICB2YXIgcGFn
166ZVkgPSBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gdGFyZ2V0VG91Y2gucGFnZVkgOiBlLnBhZ2VZO1xuXG4gICAgaWYgKGUucHJldmVudGVkQnlOZXN0ZWRTd2lwZXIpIHtcbiAgICAgIHRvdWNoZXMuc3RhcnRYID0gcGFnZVg7XG4gICAgICB0b3VjaGVzLnN0YXJ0WSA9IHBhZ2VZO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghc3dpcGVyLmFsbG93VG91Y2hNb3ZlKSB7XG4gICAgICAvLyBpc01vdmVkID0gdHJ1ZTtcbiAgICAgIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XG5cbiAgICAgIGlmIChkYXRhLmlzVG91Y2hlZCkge1xuICAgICAgICBleHRlbmQkMSh0b3VjaGVzLCB7XG4gICAgICAgICAgc3RhcnRYOiBwYWdlWCxcbiAgICAgICAgICBzdGFydFk6IHBhZ2VZLFxuICAgICAgICAgIGN1cnJlbnRYOiBwYWdlWCxcbiAgICAgICAgICBjdXJyZW50WTogcGFnZVlcbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEudG91Y2hTdGFydFRpbWUgPSBub3coKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChkYXRhLmlzVG91Y2hFdmVudCAmJiBwYXJhbXMudG91Y2hSZWxlYXNlT25FZGdlcyAmJiAhcGFyYW1zLmxvb3ApIHtcbiAgICAgIGlmIChzd2lwZXIuaXNWZXJ0aWNhbCgpKSB7XG4gICAgICAgIC8vIFZlcnRpY2FsXG4gICAgICAgIGlmIChwYWdlWSA8IHRvdWNoZXMuc3RhcnRZICYmIHN3aXBlci50cmFuc2xhdGUgPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIHx8IHBhZ2VZID4gdG91Y2hlcy5zdGFydFkgJiYgc3dpcGVyLnRyYW5zbGF0ZSA+PSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcbiAgICAgICAgICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xuICAgICAgICAgIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYWdlWCA8IHRvdWNoZXMuc3RhcnRYICYmIHN3aXBlci50cmFuc2xhdGUgPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIHx8IHBhZ2VYID4gdG91Y2hlcy5zdGFydFggJiYgc3dpcGVyLnRyYW5zbGF0ZSA+PSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkYXRhLmlzVG91Y2hFdmVudCAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoZS50YXJnZXQgPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgJChlLnRhcmdldCkuaXMoZGF0YS5mb3JtRWxlbWVudHMpKSB7XG4gICAgICAgIGRhdGEuaXNNb3ZlZCA9IHRydWU7XG4gICAgICAgIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzKSB7XG4gICAgICBzd2lwZXIuZW1pdCgndG91Y2hNb3ZlJywgZSk7XG4gICAgfVxuXG4gICAgaWYgKGUudGFyZ2V0VG91Y2hlcyAmJiBlLnRhcmdldFRvdWNoZXMubGVuZ3RoID4gMSkgcmV0dXJuO1xuICAgIHRvdWNoZXMuY3VycmVudFggPSBwYWdlWDtcbiAgICB0b3VjaGVzLmN1cnJlbnRZID0gcGFnZVk7XG4gICAgdmFyIGRpZmZYID0gdG91Y2hlcy5jdXJyZW50WCAtIHRvdWNoZXMuc3RhcnRYO1xuICAgIHZhciBkaWZmWSA9IHRvdWNoZXMuY3VycmVudFkgLSB0b3VjaGVzLnN0YXJ0WTtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy50aHJlc2hvbGQgJiYgTWF0aC5zcXJ0KE1hdGgucG93KGRpZmZYLCAyKSArIE1hdGgucG93KGRpZmZZLCAyKSkgPCBzd2lwZXIucGFyYW1zLnRocmVzaG9sZCkgcmV0dXJuO1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhLmlzU2Nyb2xsaW5nID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIHRvdWNoQW5nbGU7XG5cbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgJiYgdG91Y2hlcy5jdXJyZW50WSA9PT0gdG91Y2hlcy5zdGFydFkgfHwgc3dpcGVyLmlzVmVydGljYWwoKSAmJi
166B0b3VjaGVzLmN1cnJlbnRYID09PSB0b3VjaGVzLnN0YXJ0WCkge1xuICAgICAgICBkYXRhLmlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgaWYgKGRpZmZYICogZGlmZlggKyBkaWZmWSAqIGRpZmZZID49IDI1KSB7XG4gICAgICAgICAgdG91Y2hBbmdsZSA9IE1hdGguYXRhbjIoTWF0aC5hYnMoZGlmZlkpLCBNYXRoLmFicyhkaWZmWCkpICogMTgwIC8gTWF0aC5QSTtcbiAgICAgICAgICBkYXRhLmlzU2Nyb2xsaW5nID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gdG91Y2hBbmdsZSA+IHBhcmFtcy50b3VjaEFuZ2xlIDogOTAgLSB0b3VjaEFuZ2xlID4gcGFyYW1zLnRvdWNoQW5nbGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGF0YS5pc1Njcm9sbGluZykge1xuICAgICAgc3dpcGVyLmVtaXQoJ3RvdWNoTW92ZU9wcG9zaXRlJywgZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhLnN0YXJ0TW92aW5nID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHRvdWNoZXMuY3VycmVudFggIT09IHRvdWNoZXMuc3RhcnRYIHx8IHRvdWNoZXMuY3VycmVudFkgIT09IHRvdWNoZXMuc3RhcnRZKSB7XG4gICAgICAgIGRhdGEuc3RhcnRNb3ZpbmcgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkYXRhLmlzU2Nyb2xsaW5nKSB7XG4gICAgICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghZGF0YS5zdGFydE1vdmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XG5cbiAgICBpZiAoIXBhcmFtcy5jc3NNb2RlICYmIGUuY2FuY2VsYWJsZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMudG91Y2hNb3ZlU3RvcFByb3BhZ2F0aW9uICYmICFwYXJhbXMubmVzdGVkKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIGlmICghZGF0YS5pc01vdmVkKSB7XG4gICAgICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgICAgIH1cblxuICAgICAgZGF0YS5zdGFydFRyYW5zbGF0ZSA9IHN3aXBlci5nZXRUcmFuc2xhdGUoKTtcbiAgICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKDApO1xuXG4gICAgICBpZiAoc3dpcGVyLmFuaW1hdGluZykge1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC50cmlnZ2VyKCd3ZWJraXRUcmFuc2l0aW9uRW5kIHRyYW5zaXRpb25lbmQnKTtcbiAgICAgIH1cblxuICAgICAgZGF0YS5hbGxvd01vbWVudHVtQm91bmNlID0gZmFsc2U7IC8vIEdyYWIgQ3Vyc29yXG5cbiAgICAgIGlmIChwYXJhbXMuZ3JhYkN1cnNvciAmJiAoc3dpcGVyLmFsbG93U2xpZGVOZXh0ID09PSB0cnVlIHx8IHN3aXBlci5hbGxvd1NsaWRlUHJldiA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgc3dpcGVyLnNldEdyYWJDdXJzb3IodHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci5lbWl0KCdzbGlkZXJGaXJzdE1vdmUnLCBlKTtcbiAgICB9XG5cbiAgICBzd2lwZXIuZW1pdCgnc2xpZGVyTW92ZScsIGUpO1xuICAgIGRhdGEuaXNNb3ZlZCA9IHRydWU7XG4gICAgdmFyIGRpZmYgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBkaWZmWCA6IGRpZmZZO1xuICAgIHRvdWNoZXMuZGlmZiA9IGRpZmY7XG4gICAgZGlmZiAqPSBwYXJhbXMudG91Y2hSYXRpbztcbiAgICBpZiAocnRsKSBkaWZmID0gLWRpZmY7XG4gICAgc3dpcGVyLnN3aXBlRGlyZWN0aW9uID0gZGlmZiA+IDAgPyAncHJldicgOiAnbmV4dCc7XG4gICAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gZGlmZiArIGRhdGEuc3RhcnRUcmFuc2xhdGU7XG4gICAgdmFyIGRpc2FibGVQYXJlbnRTd2lwZXIgPSB0cnVlO1xuICAgIHZhciByZXNpc3RhbmNlUmF0aW8gPSBwYXJhbXMucmVzaXN0YW5jZVJhdGlvO1xuXG4gICAgaWYgKHBhcmFtcy50b3VjaFJlbGVhc2VPbkVkZ2VzKSB7XG4gICAgICByZXNpc3RhbmNlUmF0aW8gPSAwO1xuICAgIH1cblxuICAgIGlmIChkaWZmID4gMCAmJiBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPiBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcbiAgICAgIGRpc2FibGVQYXJlbnRTd2lwZXIgPSBmYWxzZTtcbiAgICAgIGlmIChwYXJhbXMucmVzaXN0YW5jZSkgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpIC0gMSArIE1hdGgucG93KC1zd2lwZXIubWluVHJhbnNsYXRlKCkgKyBkYXRhLnN0YXJ0VHJhbnNsYXRlICsgZGlmZiwgcmVzaXN0YW5jZVJhdGlvKTtcbiAgICB9IGVsc2UgaWYgKGRpZmYgPCAwICYmIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA8IHN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xuICAgICAgZGlzYWJsZVBhcmVudFN3aXBlciA9IGZhbHNlO1xuICAgICAgaWYgKHBhcmFtcy5yZXNpc3RhbmNlKSBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgKyAxIC0gTWF0aC5wb3coc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gZGF0YS5zdGFydFRyYW5zbGF0ZSAtIGRpZmYsIHJlc2lzdGFuY2VSYXRpbyk7XG4gICAgfVxuXG4gICAgaWYgKGRpc2FibGVQYXJlbnRTd2lwZXIpIHtcbiAgICAgIGUucHJldmVudGVkQnlOZXN0ZWRTd2lwZXIgPSB0cnVlO1xuICAgIH0gLy8gRGlyZWN0aW9ucyBsb2Nrc1xuXG5cbiAgICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJiBzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICduZXh0JyAmJiBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPCBkYXRhLnN0YXJ0VHJhbnNsYXRlKSB7XG4gICAgICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBkYXRhLnN0YXJ0VHJhbnNsYXRlO1xuICAgIH1cblxuICAgIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmIHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ3ByZXYnICYmIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA+IGRhdGEuc3RhcnRUcmFuc2xhdGUpIHtcbiAgICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XG4gICAgfSAvLyBUaHJlc2hvbGRcblxuXG4gICAgaWYgKHBhcmFtcy50aHJlc2hvbGQgPiAwKSB7XG4gICAgICBpZiAoTWF0aC5hYnMoZGlmZikgPiBwYXJhbXMudGhyZXNob2xkIHx8IGRhdGEuYWxsb3dUaHJlc2hvbGRNb3ZlKSB7XG4gICAgICAgIGlmICghZGF0YS5hbGxvd1RocmVzaG9sZE1vdmUpIHtcbiAgICAgICAgICBkYXRhLmFsbG93VGhyZXNob2xkTW92ZSA9IHRydWU7XG4gICAgICAgICAgdG91Y2hlcy5zdGFydFggPSB0b3VjaGVzLmN1cnJlbnRYO1xuICAgICAgICAgI
166HRvdWNoZXMuc3RhcnRZID0gdG91Y2hlcy5jdXJyZW50WTtcbiAgICAgICAgICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBkYXRhLnN0YXJ0VHJhbnNsYXRlO1xuICAgICAgICAgIHRvdWNoZXMuZGlmZiA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/IHRvdWNoZXMuY3VycmVudFggLSB0b3VjaGVzLnN0YXJ0WCA6IHRvdWNoZXMuY3VycmVudFkgLSB0b3VjaGVzLnN0YXJ0WTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5mb2xsb3dGaW5nZXIgfHwgcGFyYW1zLmNzc01vZGUpIHJldHVybjsgLy8gVXBkYXRlIGFjdGl2ZSBpbmRleCBpbiBmcmVlIG1vZGVcblxuICAgIGlmIChwYXJhbXMuZnJlZU1vZGUgfHwgcGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MgfHwgcGFyYW1zLndhdGNoU2xpZGVzVmlzaWJpbGl0eSkge1xuICAgICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZnJlZU1vZGUpIHtcbiAgICAgIC8vIFZlbG9jaXR5XG4gICAgICBpZiAoZGF0YS52ZWxvY2l0aWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBkYXRhLnZlbG9jaXRpZXMucHVzaCh7XG4gICAgICAgICAgcG9zaXRpb246IHRvdWNoZXNbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3N0YXJ0WCcgOiAnc3RhcnRZJ10sXG4gICAgICAgICAgdGltZTogZGF0YS50b3VjaFN0YXJ0VGltZVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgZGF0YS52ZWxvY2l0aWVzLnB1c2goe1xuICAgICAgICBwb3NpdGlvbjogdG91Y2hlc1tzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnY3VycmVudFgnIDogJ2N1cnJlbnRZJ10sXG4gICAgICAgIHRpbWU6IG5vdygpXG4gICAgICB9KTtcbiAgICB9IC8vIFVwZGF0ZSBwcm9ncmVzc1xuXG5cbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoZGF0YS5jdXJyZW50VHJhbnNsYXRlKTsgLy8gVXBkYXRlIHRyYW5zbGF0ZVxuXG4gICAgc3dpcGVyLnNldFRyYW5zbGF0ZShkYXRhLmN1cnJlbnRUcmFuc2xhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Ub3VjaEVuZChldmVudCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBkYXRhID0gc3dpcGVyLnRvdWNoRXZlbnRzRGF0YTtcbiAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgdG91Y2hlcyA9IHN3aXBlci50b3VjaGVzLFxuICAgICAgICBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlLFxuICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgIHNsaWRlc0dyaWQgPSBzd2lwZXIuc2xpZGVzR3JpZCxcbiAgICAgICAgc25hcEdyaWQgPSBzd2lwZXIuc25hcEdyaWQ7XG4gICAgdmFyIGUgPSBldmVudDtcbiAgICBpZiAoZS5vcmlnaW5hbEV2ZW50KSBlID0gZS5vcmlnaW5hbEV2ZW50O1xuXG4gICAgaWYgKGRhdGEuYWxsb3dUb3VjaENhbGxiYWNrcykge1xuICAgICAgc3dpcGVyLmVtaXQoJ3RvdWNoRW5kJywgZSk7XG4gICAgfVxuXG4gICAgZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzID0gZmFsc2U7XG5cbiAgICBpZiAoIWRhdGEuaXNUb3VjaGVkKSB7XG4gICAgICBpZiAoZGF0YS5pc01vdmVkICYmIHBhcmFtcy5ncmFiQ3Vyc29yKSB7XG4gICAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKGZhbHNlKTtcbiAgICAgIH1cblxuICAgICAgZGF0YS5pc01vdmVkID0gZmFsc2U7XG4gICAgICBkYXRhLnN0YXJ0TW92aW5nID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBSZXR1cm4gR3JhYiBDdXJzb3JcblxuXG4gICAgaWYgKHBhcmFtcy5ncmFiQ3Vyc29yICYmIGRhdGEuaXNNb3ZlZCAmJiBkYXRhLmlzVG91Y2hlZCAmJiAoc3dpcGVyLmFsbG93U2xpZGVOZXh0ID09PSB0cnVlIHx8IHN3aXBlci5hbGxvd1NsaWRlUHJldiA9PT0gdHJ1ZSkpIHtcbiAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKGZhbHNlKTtcbiAgICB9IC8vIFRpbWUgZGlmZlxuXG5cbiAgICB2YXIgdG91Y2hFbmRUaW1lID0gbm93KCk7XG4gICAgdmFyIHRpbWVEaWZmID0gdG91Y2hFbmRUaW1lIC0gZGF0YS50b3VjaFN0YXJ0VGltZTsgLy8gVGFwLCBkb3VibGVUYXAsIENsaWNrXG5cbiAgICBpZiAoc3dpcGVyLmFsbG93Q2xpY2spIHtcbiAgICAgIHN3aXBlci51cGRhdGVDbGlja2VkU2xpZGUoZSk7XG4gICAgICBzd2lwZXIuZW1pdCgndGFwIGNsaWNrJywgZSk7XG5cbiAgICAgIGlmICh0aW1lRGlmZiA8IDMwMCAmJiB0b3VjaEVuZFRpbWUgLSBkYXRhLmxhc3RDbGlja1RpbWUgPCAzMDApIHtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ2RvdWJsZVRhcCBkb3VibGVDbGljaycsIGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGRhdGEubGFzdENsaWNrVGltZSA9IG5vdygpO1xuICAgIG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghc3dpcGVyLmRlc3Ryb3llZCkgc3dpcGVyLmFsbG93Q2xpY2sgPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgaWYgKCFkYXRhLmlzVG91Y2hlZCB8fCAhZGF0YS5pc01vdmVkIHx8ICFzd2lwZXIuc3dpcGVEaXJlY3Rpb24gfHwgdG91Y2hlcy5kaWZmID09PSAwIHx8IGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9PT0gZGF0YS5zdGFydFRyYW5zbGF0ZSkge1xuICAgICAgZGF0YS5pc1RvdWNoZWQgPSBmYWxzZTtcbiAgICAgIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xuICAgICAgZGF0YS5zdGFydE1vdmluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRhdGEuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgZGF0YS5pc01vdmVkID0gZmFsc2U7XG4gICAgZGF0YS5zdGFydE1vdmluZyA9IGZhbHNlO1xuICAgIHZhciBjdXJyZW50UG9zO1xuXG4gICAgaWYgKHBhcmFtcy5mb2xsb3dGaW5nZXIpIHtcbiAgICAgIGN1cnJlbnRQb3MgPSBydGwgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRQb3MgPSAtZGF0YS5jdXJyZW50VHJhbnNsYXRlO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY3NzTW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZnJlZU1vZGUpIHtcbiAgICAgIGlmIChjdXJyZW50UG9zIDwgLXN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50UG9zID4gLXN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xuICAgICAgICBpZiAoc3dpcGVyLnNsaWRlcy5sZW5ndGggPCBzbmFwR3JpZC5sZW5ndGgpIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbmFwR3JpZC5sZW5ndGggLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLmZyZWVNb2RlTW9tZW50dW0pIHtcbiAgICAgICAgaWYgKGRhdGEudmVsb2NpdGllcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdmFyIGxhc3RNb3ZlRXZlbnQgPSBkYXRhLnZlbG9jaXRpZXMucG9wKCk7XG4gICAgICAgICAgdmFyIHZlbG9jaXR5RXZlbnQgPSBkYXRhLnZlbG9jaXRpZXMucG9wKCk7XG4gICAgICAgICAgdmFyIGRpc3R
166hbmNlID0gbGFzdE1vdmVFdmVudC5wb3NpdGlvbiAtIHZlbG9jaXR5RXZlbnQucG9zaXRpb247XG4gICAgICAgICAgdmFyIHRpbWUgPSBsYXN0TW92ZUV2ZW50LnRpbWUgLSB2ZWxvY2l0eUV2ZW50LnRpbWU7XG4gICAgICAgICAgc3dpcGVyLnZlbG9jaXR5ID0gZGlzdGFuY2UgLyB0aW1lO1xuICAgICAgICAgIHN3aXBlci52ZWxvY2l0eSAvPSAyO1xuXG4gICAgICAgICAgaWYgKE1hdGguYWJzKHN3aXBlci52ZWxvY2l0eSkgPCBwYXJhbXMuZnJlZU1vZGVNaW5pbXVtVmVsb2NpdHkpIHtcbiAgICAgICAgICAgIHN3aXBlci52ZWxvY2l0eSA9IDA7XG4gICAgICAgICAgfSAvLyB0aGlzIGltcGxpZXMgdGhhdCB0aGUgdXNlciBzdG9wcGVkIG1vdmluZyBhIGZpbmdlciB0aGVuIHJlbGVhc2VkLlxuICAgICAgICAgIC8vIFRoZXJlIHdvdWxkIGJlIG5vIGV2ZW50cyB3aXRoIGRpc3RhbmNlIHplcm8sIHNvIHRoZSBsYXN0IGV2ZW50IGlzIHN0YWxlLlxuXG5cbiAgICAgICAgICBpZiAodGltZSA+IDE1MCB8fCBub3coKSAtIGxhc3RNb3ZlRXZlbnQudGltZSA+IDMwMCkge1xuICAgICAgICAgICAgc3dpcGVyLnZlbG9jaXR5ID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3dpcGVyLnZlbG9jaXR5ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXBlci52ZWxvY2l0eSAqPSBwYXJhbXMuZnJlZU1vZGVNb21lbnR1bVZlbG9jaXR5UmF0aW87XG4gICAgICAgIGRhdGEudmVsb2NpdGllcy5sZW5ndGggPSAwO1xuICAgICAgICB2YXIgbW9tZW50dW1EdXJhdGlvbiA9IDEwMDAgKiBwYXJhbXMuZnJlZU1vZGVNb21lbnR1bVJhdGlvO1xuICAgICAgICB2Y
166XIgbW9tZW50dW1EaXN0YW5jZSA9IHN3aXBlci52ZWxvY2l0eSAqIG1vbWVudHVtRHVyYXRpb247XG4gICAgICAgIHZhciBuZXdQb3NpdGlvbiA9IHN3aXBlci50cmFuc2xhdGUgKyBtb21lbnR1bURpc3RhbmNlO1xuICAgICAgICBpZiAocnRsKSBuZXdQb3NpdGlvbiA9IC1uZXdQb3NpdGlvbjtcbiAgICAgICAgdmFyIGRvQm91bmNlID0gZmFsc2U7XG4gICAgICAgIHZhciBhZnRlckJvdW5jZVBvc2l0aW9uO1xuICAgICAgICB2YXIgYm91bmNlQW1vdW50ID0gTWF0aC5hYnMoc3dpcGVyLnZlbG9jaXR5KSAqIDIwICogcGFyYW1zLmZyZWVNb2RlTW9tZW50dW1Cb3VuY2VSYXRpbztcbiAgICAgICAgdmFyIG5lZWRzTG9vcEZpeDtcblxuICAgICAgICBpZiAobmV3UG9zaXRpb24gPCBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHtcbiAgICAgICAgICBpZiAocGFyYW1zLmZyZWVNb2RlTW9tZW50dW1Cb3VuY2UpIHtcbiAgICAgICAgICAgIGlmIChuZXdQb3NpdGlvbiArIHN3aXBlci5tYXhUcmFuc2xhdGUoKSA8IC1ib3VuY2VBbW91bnQpIHtcbiAgICAgICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBib3VuY2VBbW91bnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFmdGVyQm91bmNlUG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCk7XG4gICAgICAgICAgICBkb0JvdW5jZSA9IHRydWU7XG4gICAgICAgICAgICBkYXRhLmFsbG93TW9tZW50dW1Cb3VuY2UgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdQb3NpdGlvbiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGFyYW1zLmxvb3AgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzKSBuZWVkc0xvb3BGaXggPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKG5ld1Bvc2l0aW9uID4gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSB7XG4gICAgICAgICAgaWYgKHBhcmFtcy5mcmVlTW9kZU1vbWVudHVtQm91bmNlKSB7XG4gICAgICAgICAgICBpZiAobmV3UG9zaXRpb24gLSBzd2lwZXIubWluVHJhbnNsYXRlKCkgPiBib3VuY2VBbW91bnQpIHtcbiAgICAgICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWluVHJhbnNsYXRlKCkgKyBib3VuY2VBbW91bnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFmdGVyQm91bmNlUG9zaXRpb24gPSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XG4gICAgICAgICAgICBkb0JvdW5jZSA9IHRydWU7XG4gICAgICAgICAgICBkYXRhLmFsbG93TW9tZW50dW1Cb3VuY2UgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdQb3NpdGlvbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGFyYW1zLmxvb3AgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzKSBuZWVkc0xvb3BGaXggPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtcy5mcmVlTW9kZVN0aWNreSkge1xuICAgICAgICAgIHZhciBuZXh0U2xpZGU7XG5cbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHNuYXBHcmlkLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICBpZiAoc25hcEdyaWRbal0gPiAtbmV3UG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgbmV4dFNsaWRlID0gajtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKE1hdGguYWJzKHNuYXBHcmlkW25leHRTbGlkZV0gLSBuZXdQb3NpdGlvbikgPCBNYXRoLmFicyhzbmFwR3JpZFtuZXh0U2xpZGUgLSAxXSAtIG5ld1Bvc2l0aW9uKSB8fCBzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICduZXh0Jykge1xuICAgICAgICAgICAgbmV3UG9zaXRpb24gPSBzbmFwR3JpZFtuZXh0U2xpZGVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdQb3NpdGlvbiA9IHNuYXBHcmlkW25leHRTbGlkZSAtIDFdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG5ld1Bvc2l0aW9uID0gLW5ld1Bvc2l0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5lZWRzTG9vcEZpeCkge1xuICAgICAgICAgIHN3aXBlci5vbmNlKCd0cmFuc2l0aW9uRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSAvLyBGaXggZHVyYXRpb25cblxuXG4gICAgICAgIGlmIChzd2lwZXIudmVsb2NpdHkgIT09IDApIHtcbiAgICAgICAgICBpZiAocnRsKSB7XG4gICAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gTWF0aC5hYnMoKC1uZXdQb3NpdGlvbiAtIHN3aXBlci50cmFuc2xhdGUpIC8gc3dpcGVyLnZlbG9jaXR5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbW9tZW50dW1EdXJhdGlvbiA9IE1hdGguYWJzKChuZXdQb3NpdGlvbiAtIHN3aXBlci50cmFuc2xhdGUpIC8gc3dpcGVyLnZlbG9jaXR5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGFyYW1zLmZyZWVNb2RlU3RpY2t5KSB7XG4gICAgICAgICAgICAvLyBJZiBmcmVlTW9kZVN0aWNreSBpcyBhY3RpdmUgYW5kIHRoZSB1c2VyIGVuZHMgYSBzd2lwZSB3aXRoIGEgc2xvdy12ZWxvY2l0eVxuICAgICAgICAgICAgLy8gZXZlbnQsIHRoZW4gZHVyYXRpb25zIGNhbiBiZSAyMCsgc2Vjb25kcyB0byBzbGlkZSBvbmUgKG9yIHplcm8hKSBzbGlkZXMuXG4gICAgICAgICAgICAvLyBJdCdzIGVhc3kgdG8gc2VlIHRoaXMgd2hlbiBzaW11bGF0aW5nIHRvdWNoIHdpdGggbW91c2UgZXZlbnRzLiBUbyBmaXggdGhpcyxcbiAgICAgICAgICAgIC8vIGxpbWl0IHNpbmdsZS1zbGlkZSBzd2lwZXMgdG8gdGhlIGRlZmF1bHQgc2xpZGUgZHVyYXRpb24uIFRoaXMgYWxzbyBoYXMgdGhlXG4gICAgICAgICAgICAvLyBuaWNlIHNpZGUgZWZmZWN0IG9mIG1hdGNoaW5nIHNsaWRlIHNwZWVkIGlmIHRoZSB1c2VyIHN0b3BwZWQgbW92aW5nIGJlZm9yZVxuICAgICAgICAgICAgLy8gbGlmdGluZyBmaW5nZXIgb3IgbW91c2UgdnMuIG1vdmluZyBzbG93bHkgYmVmb3JlIGxpZnRpbmcgdGhlIGZpbmdlci9tb3VzZS5cbiAgICAgICAgICAgIC8vIEZvciBmYXN0ZXIgc3dpcGVzLCBhbHNvIGFwcGx5IGxpbWl0cyAoYWxiZWl0IGhpZ2hlciBvbmVzKS5cbiAgICAgICAgICAgI
166HZhciBtb3ZlRGlzdGFuY2UgPSBNYXRoLmFicygocnRsID8gLW5ld1Bvc2l0aW9uIDogbmV3UG9zaXRpb24pIC0gc3dpcGVyLnRyYW5zbGF0ZSk7XG4gICAgICAgICAgICB2YXIgY3VycmVudFNsaWRlU2l6ZSA9IHN3aXBlci5zbGlkZXNTaXplc0dyaWRbc3dpcGVyLmFjdGl2ZUluZGV4XTtcblxuICAgICAgICAgICAgaWYgKG1vdmVEaXN0YW5jZSA8IGN1cnJlbnRTbGlkZVNpemUpIHtcbiAgICAgICAgICAgICAgbW9tZW50dW1EdXJhdGlvbiA9IHBhcmFtcy5zcGVlZDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobW92ZURpc3RhbmNlIDwgMiAqIGN1cnJlbnRTbGlkZVNpemUpIHtcbiAgICAgICAgICAgICAgbW9tZW50dW1EdXJhdGlvbiA9IHBhcmFtcy5zcGVlZCAqIDEuNTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG1vbWVudHVtRHVyYXRpb24gPSBwYXJhbXMuc3BlZWQgKiAyLjU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtcy5mcmVlTW9kZVN0aWNreSkge1xuICAgICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMuZnJlZU1vZGVNb21lbnR1bUJvdW5jZSAmJiBkb0JvdW5jZSkge1xuICAgICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhhZnRlckJvdW5jZVBvc2l0aW9uKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihtb21lbnR1bUR1cmF0aW9uKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1Bvc2l0aW9uKTtcbiAgICAgICAgICBzd2lwZXIudHJhbnNpdGlvblN0YXJ0KHRydWUsIHN3aXBlci5zd2lwZURpcmVjdGlvbik7XG4gICAgICAgICAgc3dpcGVyLmFuaW1hdGluZyA9IHRydWU7XG4gICAgICAgICAgJHdyYXBwZXJFbC50cmFuc2l0aW9uRW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIWRhdGEuYWxsb3dNb21lbnR1bUJvdW5jZSkgcmV0dXJuO1xuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ21vbWVudHVtQm91bmNlJyk7XG4gICAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihwYXJhbXMuc3BlZWQpO1xuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUoYWZ0ZXJCb3VuY2VQb3NpdGlvbik7XG4gICAgICAgICAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbkVuZChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHN3aXBlci50cmFuc2l0aW9uRW5kKCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3dpcGVyLnZlbG9jaXR5KSB7XG4gICAgICAgICAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKG5ld1Bvc2l0aW9uKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihtb21lbnR1bUR1cmF0aW9uKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1Bvc2l0aW9uKTtcbiAgICAgICAgICBzd2lwZXIudHJhbnNpdGlvblN0YXJ0KHRydWUsIHN3aXBlci5zd2lwZURpcmVjdGlvbik7XG5cbiAgICAgICAgICBpZiAoIXN3aXBlci5hbmltYXRpbmcpIHtcbiAgICAgICAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgJHdyYXBwZXJFbC50cmFuc2l0aW9uRW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgICAgICAgICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhuZXdQb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW1zLmZyZWVNb2RlU3RpY2t5KSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghcGFyYW1zLmZyZWVNb2RlTW9tZW50dW0gfHwgdGltZURpZmYgPj0gcGFyYW1zLmxvbmdTd2lwZXNNcykge1xuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XG4gICAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEZpbmQgY3VycmVudCBzbGlkZVxuXG5cbiAgICB2YXIgc3RvcEluZGV4ID0gMDtcbiAgICB2YXIgZ3JvdXBTaXplID0gc3dpcGVyLnNsaWRlc1NpemVzR3JpZFswXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpZGVzR3JpZC5sZW5ndGg7IGkgKz0gaSA8IHBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAgPyAxIDogcGFyYW1zLnNsaWRlc1Blckdyb3VwKSB7XG4gICAgICB2Y
166XIgX2luY3JlbWVudCA9IGkgPCBwYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwIC0gMSA/IDEgOiBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XG5cbiAgICAgIGlmICh0eXBlb2Ygc2xpZGVzR3JpZFtpICsgX2luY3JlbWVudF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChjdXJyZW50UG9zID49IHNsaWRlc0dyaWRbaV0gJiYgY3VycmVudFBvcyA8IHNsaWRlc0dyaWRbaSArIF9pbmNyZW1lbnRdKSB7XG4gICAgICAgICAgc3RvcEluZGV4ID0gaTtcbiAgICAgICAgICBncm91cFNpemUgPSBzbGlkZXNHcmlkW2kgKyBfaW5jcmVtZW50XSAtIHNsaWRlc0dyaWRbaV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFBvcyA+PSBzbGlkZXNHcmlkW2ldKSB7XG4gICAgICAgIHN0b3BJbmRleCA9IGk7XG4gICAgICAgIGdyb3VwU2l6ZSA9IHNsaWRlc0dyaWRbc2xpZGVzR3JpZC5sZW5ndGggLSAxXSAtIHNsaWRlc0dyaWRbc2xpZGVzR3JpZC5sZW5ndGggLSAyXTtcbiAgICAgIH1cbiAgICB9IC8vIEZpbmQgY3VycmVudCBzbGlkZSBzaXplXG5cblxuICAgIHZhciByYXRpbyA9IChjdXJyZW50UG9zIC0gc2xpZGVzR3JpZFtzdG9wSW5kZXhdKSAvIGdyb3VwU2l6ZTtcbiAgICB2YXIgaW5jcmVtZW50ID0gc3RvcEluZGV4IDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCAtIDEgPyAxIDogcGFyYW1zLnNsaWRlc1Blckdyb3VwO1xuXG4gICAgaWYgKHRpbWVEaWZmID4gcGFyYW1zLmxvbmdTd2lwZXNNcykge1xuICAgICAgLy8gTG9uZyB0b3VjaGVzXG4gICAgICBpZiAoIXBhcmFtcy5sb25nU3dpcGVzKSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnKSB7XG4gICAgICAgIGlmIChyYXRpbyA+PSBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKSBzd2lwZXIuc2xpZGVUbyhzdG9wSW5kZXggKyBpbmNyZW1lbnQpO2Vsc2Ugc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ3ByZXYnKSB7XG4gICAgICAgIGlmIChyYXRpbyA+IDEgLSBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKSBzd2lwZXIuc2xpZGVUbyhzdG9wSW5kZXggKyBpbmNyZW1lbnQpO2Vsc2Ugc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2hvcnQgc3dpcGVzXG4gICAgICBpZiAoIXBhcmFtcy5zaG9ydFN3aXBlcykge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBpc05hdkJ1dHRvblRhcmdldCA9IHN3aXBlci5uYXZpZ2F0aW9uICYmIChlLnRhcmdldCA9PT0gc3dpcGVyLm5hdmlnYXRpb24ubmV4dEVsIHx8IGUudGFyZ2V0ID09PSBzd2lwZXIubmF2aWdhdGlvbi5wcmV2RWwpO1xuXG4gICAgICBpZiAoIWlzTmF2QnV0dG9uVGFyZ2V0KSB7XG4gICAgICAgIGlmIChzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICduZXh0Jykge1xuICAgICAgICAgIHN3aXBlci5zbGlkZVRvKHN0b3BJbmRleCArIGluY3JlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3dpcGVyLnN3aXBlRGlyZWN0aW9uID09PSAncHJldicpIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhzdG9wSW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGUudGFyZ2V0ID09PSBzd2lwZXIubmF2aWdhdGlvbi5uZXh0RWwpIHtcbiAgICAgICAgc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4ICsgaW5jcmVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN0b3BJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25SZXNpemUoKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgIGVsID0gc3dpcGVyLmVsO1xuICAgIGlmIChlbCAmJiBlbC5vZmZzZXRXaWR0aCA9PT0gMCkgcmV0dXJuOyAvLyBCcmVha3BvaW50c1xuXG4gICAgaWYgKHBhcmFtcy5icmVha3BvaW50cykge1xuICAgICAgc3dpcGVyLnNldEJyZWFrcG9pbnQoKTtcbiAgICB9IC8vIFNhdmUgbG9ja3NcblxuXG4gICAgdmFyIGFsbG93U2xpZGVOZXh0ID0gc3dpcGVyLmFsbG93U2xpZGVOZXh0LFxuICAgICAgICBhbGxvd1NsaWRlUHJldiA9IHN3aXBlci5hbGxvd1NsaWRlUHJldixcbiAgICAgICAgc25hcEdyaWQgPSBzd2lwZXIuc25hcEdyaWQ7IC8vIERpc2FibGUgbG9ja3Mgb24gcmVzaXplXG5cbiAgICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSB0cnVlO1xuICAgIHN3aXBlci5hbGxvd1NsaWRlUHJldiA9IHRydWU7XG4gICAgc3dpcGVyLnVwZGF0ZVNpemUoKTtcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcblxuICAgIGlmICgocGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyB8fCBwYXJhbXMuc2xpZGVzUGVyVmlldyA+IDEpICYmIHN3aXBlci5pc0VuZCAmJiAhc3dpcGVyLmlzQmVnaW5uaW5nICYmICFzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XG4gICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4LCAwLCBmYWxzZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5hdXRvcGxheSAmJiBzd2lwZXIuYXV0b3BsYXkucnVubmluZyAmJiBzd2lwZXIuYXV0b3BsYXkucGF1c2VkKSB7XG4gICAgICBzd2lwZXIuYXV0b3BsYXkucnVuKCk7XG4gICAgfSAvLyBSZXR1cm4gbG9ja3MgYWZ0ZXIgcmVzaXplXG5cblxuICAgIHN3aXBlci5hbGxvd1NsaWRlUHJldiA9IGFsbG93U2xpZGVQcmV2O1xuICAgIHN3aXBlci5hbGxvd1NsaWRlTmV4dCA9IGFsbG93U2xpZGVOZXh0O1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzbmFwR3JpZCAhPT0gc3dpcGVyLnNuYXBHcmlkKSB7XG4gICAgICBzd2lwZXIuY2hlY2tPdmVyZmxvdygpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uQ2xpY2soZSkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuXG4gICAgaWYgKCFzd2lwZXIuYWxsb3dDbGljaykge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMucHJldmVudENsaWNrcykgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5wcmV2ZW50Q2xpY2tzUHJvcGFnYXRpb24gJiYgc3dpcGVyLmFuaW1hdGluZykge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uU2Nyb2xsKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciB3cmFwcGVyRWwgPSBzd2lwZXIud3JhcHBlckVsLFxuICAgICAgICBydGxUcmFuc2xhdGUgPSBzd2lwZXIucnRsVHJhbnNsYXRlO1xuICAgIHN3aXBlci5wcmV2aW91c1RyYW5zbGF0ZSA9IHN3aXBlci50cmFuc2xhdGU7XG5cbiAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbn
166RhbCgpKSB7XG4gICAgICBpZiAocnRsVHJhbnNsYXRlKSB7XG4gICAgICAgIHN3aXBlci50cmFuc2xhdGUgPSB3cmFwcGVyRWwuc2Nyb2xsV2lkdGggLSB3cmFwcGVyRWwub2Zmc2V0V2lkdGggLSB3cmFwcGVyRWwuc2Nyb2xsTGVmdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci50cmFuc2xhdGUgPSAtd3JhcHBlckVsLnNjcm9sbExlZnQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci50cmFuc2xhdGUgPSAtd3JhcHBlckVsLnNjcm9sbFRvcDtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG5cbiAgICBpZiAoc3dpcGVyLnRyYW5zbGF0ZSA9PT0gLTApIHN3aXBlci50cmFuc2xhdGUgPSAwO1xuICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gICAgdmFyIG5ld1Byb2dyZXNzO1xuICAgIHZhciB0cmFuc2xhdGVzRGlmZiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKTtcblxuICAgIGlmICh0cmFuc2xhdGVzRGlmZiA9PT0gMCkge1xuICAgICAgbmV3UHJvZ3Jlc3MgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdQcm9ncmVzcyA9IChzd2lwZXIudHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAvIHRyYW5zbGF0ZXNEaWZmO1xuICAgIH1cblxuICAgIGlmIChuZXdQcm9ncmVzcyAhPT0gc3dpcGVyLnByb2dyZXNzKSB7XG4gICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MocnRsVHJhbnNsYXRlID8gLXN3aXBlci50cmFuc2xhdGUgOiBzd2lwZXIudHJhbnNsYXRlKTtcbiAgICB9XG5cbiAgICBzd2lwZXIuZW1pdCgnc2V0VHJhbnNsYXRlJywgc3dpcGVyLnRyYW5zbGF0ZSwgZmFsc2UpO1xuICB9XG5cbiAgdmFyIGR1bW15RXZlbnRBdHRhY2hlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGR1bW15RXZlbnRMaXN0ZW5lcigpIHt9XG5cbiAgZnVuY3Rpb24gYXR0YWNoRXZlbnRzKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgIHRvdWNoRXZlbnRzID0gc3dpcGVyLnRvdWNoRXZlbnRzLFxuICAgICAgICBlbCA9IHN3aXBlci5lbCxcbiAgICAgICAgd3JhcHBlckVsID0gc3dpcGVyLndyYXBwZXJFbCxcbiAgICAgICAgZGV2aWNlID0gc3dpcGVyLmRldmljZSxcbiAgICAgICAgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgIHN3aXBlci5vblRvdWNoU3RhcnQgPSBvblRvdWNoU3RhcnQuYmluZChzd2lwZXIpO1xuICAgIHN3aXBlci5vblRvdWNoTW92ZSA9IG9uVG91Y2hNb3ZlLmJpbmQoc3dpcGVyKTtcbiAgICBzd2lwZXIub25Ub3VjaEVuZCA9IG9uVG91Y2hFbmQuYmluZChzd2lwZXIpO1xuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBzd2lwZXIub25TY3JvbGwgPSBvblNjcm9sbC5iaW5kKHN3aXBlcik7XG4gICAgfVxuXG4gICAgc3dpcGVyLm9uQ2xpY2sgPSBvbkNsaWNrLmJpbmQoc3dpcGVyKTtcbiAgICB2YXIgY2FwdHVyZSA9ICEhcGFyYW1zLm5lc3RlZDsgLy8gVG91Y2ggRXZlbnRzXG5cbiAgICBpZiAoIXN1cHBvcnQudG91Y2ggJiYgc3VwcG9ydC5wb2ludGVyRXZlbnRzKSB7XG4gICAgICBlbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLnN0YXJ0LCBzd2lwZXIub25Ub3VjaFN0YXJ0LCBmYWxzZSk7XG4gICAgICBkb2
166N1bWVudC5hZGRFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLm1vdmUsIHN3aXBlci5vblRvdWNoTW92ZSwgY2FwdHVyZSk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLmVuZCwgc3dpcGVyLm9uVG91Y2hFbmQsIGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN1cHBvcnQudG91Y2gpIHtcbiAgICAgICAgdmFyIHBhc3NpdmVMaXN0ZW5lciA9IHRvdWNoRXZlbnRzLnN0YXJ0ID09PSAndG91Y2hzdGFydCcgJiYgc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnMgPyB7XG4gICAgICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgICAgICBjYXB0dXJlOiBmYWxzZVxuICAgICAgICB9IDogZmFsc2U7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHMuc3RhcnQsIHN3aXBlci5vblRvdWNoU3RhcnQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHMubW92ZSwgc3dpcGVyLm9uVG91Y2hNb3ZlLCBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciA/IHtcbiAgICAgICAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICAgICAgICBjYXB0dXJlOiBjYXB0dXJlXG4gICAgICAgIH0gOiBjYXB0dXJlKTtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50cy5lbmQsIHN3aXBlci5vblRvdWNoRW5kLCBwYXNzaXZlTGlzdGVuZXIpO1xuXG4gICAgICAgIGlmICh0b3VjaEV2ZW50cy5jYW5jZWwpIHtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLmNhbmNlbCwgc3dpcGVyLm9uVG91Y2hFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWR1bW15RXZlbnRBdHRhY2hlZCkge1xuICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBkdW1teUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgIGR1bW15RXZlbnRBdHRhY2hlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtcy5zaW11bGF0ZVRvdWNoICYmICFkZXZpY2UuaW9zICYmICFkZXZpY2UuYW5kcm9pZCB8fCBwYXJhbXMuc2ltdWxhdGVUb3VjaCAmJiAhc3VwcG9ydC50b3VjaCAmJiBkZXZpY2UuaW9zKSB7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHN3aXBlci5vblRvdWNoU3RhcnQsIGZhbHNlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgc3dpcGVyLm9uVG91Y2hNb3ZlLCBjYXB0dXJlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHN3aXBlci5vblRvdWNoRW5kLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfSAvLyBQcmV2ZW50IExpbmtzIENsaWNrc1xuXG5cbiAgICBpZiAocGFyYW1zLnByZXZlbnRDbGlja3MgfHwgcGFyYW1zLnByZXZlbnRDbGlja3NQcm9wYWdhdGlvbikge1xuICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzd2lwZXIub25DbGljaywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICB3cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgc3dpcGVyLm9uU2Nyb2xsKTtcbiAgICB9IC8vIFJlc2l6ZSBoYW5kbGVyXG5cblxuICAgIGlmIChwYXJhbXMudXBkYXRlT25XaW5kb3dSZXNpemUpIHtcbiAgICAgIHN3aXBlci5vbihkZXZpY2UuaW9zIHx8IGRldmljZS5hbmRyb2lkID8gJ3Jlc2l6ZSBvcmllbnRhdGlvbmNoYW5nZSBvYnNlcnZlclVwZGF0ZScgOiAncmVzaXplIG9ic2VydmVyVXBkYXRlJywgb25SZXNpemUsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIub24oJ29ic2VydmVyVXBkYXRlJywgb25SZXNpemUsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRldGFjaEV2ZW50cygpIHtcbiAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICB0b3VjaEV2ZW50cyA9IHN3aXBlci50b3VjaEV2ZW50cyxcbiAgICAgICAgZWwgPSBzd2lwZXIuZWwsXG4gICAgICAgIHdyYXBwZXJFbCA9IHN3aXBlci53cmFwcGVyRWwsXG4gICAgICAgIGRldmljZSA9IHN3aXBlci5kZXZpY2UsXG4gICAgICAgIHN1cHBvcnQgPSBzd2lwZXIuc3VwcG9ydDtcbiAgICB2YXIgY2FwdHVyZSA9ICEhcGFyYW1zLm5lc3RlZDsgLy8gVG91Y2ggRXZlbnRzXG5cbiAgICBpZiAoIXN1cHBvcnQudG91Y2ggJiYgc3VwcG9ydC5wb2ludGVyRXZlbnRzKSB7XG4gICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLnN0YXJ0LCBzd2lwZXIub25Ub3VjaFN0YXJ0LCBmYWxzZSk7XG4gICAgICBkb2
166N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLm1vdmUsIHN3aXBlci5vblRvdWNoTW92ZSwgY2FwdHVyZSk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLmVuZCwgc3dpcGVyLm9uVG91Y2hFbmQsIGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN1cHBvcnQudG91Y2gpIHtcbiAgICAgICAgdmFyIHBhc3NpdmVMaXN0ZW5lciA9IHRvdWNoRXZlbnRzLnN0YXJ0ID09PSAnb25Ub3VjaFN0YXJ0JyAmJiBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciAmJiBwYXJhbXMucGFzc2l2ZUxpc3RlbmVycyA/IHtcbiAgICAgICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgICAgIGNhcHR1cmU6IGZhbHNlXG4gICAgICAgIH0gOiBmYWxzZTtcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50cy5zdGFydCwgc3dpcGVyLm9uVG91Y2hTdGFydCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50cy5tb3ZlLCBzd2lwZXIub25Ub3VjaE1vdmUsIGNhcHR1cmUpO1xuICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzLmVuZCwgc3dpcGVyLm9uVG91Y2hFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG5cbiAgICAgICAgaWYgKHRvdWNoRXZlbnRzLmNhbmNlbCkge1xuICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHMuY2FuY2VsLCBzd2lwZXIub25Ub3VjaEVuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLnNpbXVsYXRlVG91Y2ggJiYgIWRldmljZS5pb3MgJiYgIWRldmljZS5hbmRyb2lkIHx8IHBhcmFtcy5zaW11bGF0ZVRvdWNoICYmICFzdXBwb3J0LnRvdWNoICYmIGRldmljZS5pb3MpIHtcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgc3dpcGVyLm9uVG91Y2hTdGFydCwgZmFsc2UpO1xuICAgICAgICBkb2
166N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzd2lwZXIub25Ub3VjaE1vdmUsIGNhcHR1cmUpO1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgc3dpcGVyLm9uVG91Y2hFbmQsIGZhbHNlKTtcbiAgICAgIH1cbiAgICB9IC8vIFByZXZlbnQgTGlua3MgQ2xpY2tzXG5cblxuICAgIGlmIChwYXJhbXMucHJldmVudENsaWNrcyB8fCBwYXJhbXMucHJldmVudENsaWNrc1Byb3BhZ2F0aW9uKSB7XG4gICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHN3aXBlci5vbkNsaWNrLCB0cnVlKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHdyYXBwZXJFbC5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzd2lwZXIub25TY3JvbGwpO1xuICAgIH0gLy8gUmVzaXplIGhhbmRsZXJcblxuXG4gICAgc3dpcGVyLm9mZihkZXZpY2UuaW9zIHx8IGRldmljZS5hbmRyb2lkID8gJ3Jlc2l6ZSBvcmllbnRhdGlvbmNoYW5nZSBvYnNlcnZlclVwZGF0ZScgOiAncmVzaXplIG9ic2VydmVyVXBkYXRlJywgb25SZXNpemUpO1xuICB9XG5cbiAgdmFyIGV2ZW50cyA9IHtcbiAgICBhdHRhY2hFdmVudHM6IGF0dGFjaEV2ZW50cyxcbiAgICBkZXRhY2hFdmVudHM6IGRldGFjaEV2ZW50c1xuICB9O1xuXG4gIGZ1bmN0aW9uIHNldEJyZWFrcG9pbnQoKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4LFxuICAgICAgICBpbml0aWFsaXplZCA9IHN3aXBlci5pbml0aWFsaXplZCxcbiAgICAgICAgX3N3aXBlciRsb29wZWRTbGlkZXMgPSBzd2lwZXIubG9vcGVkU2xpZGVzLFxuICAgICAgICBsb29wZWRTbGlkZXMgPSBfc3dpcGVyJGxvb3BlZFNsaWRlcyA9PT0gdm9pZCAwID8gMCA6IF9zd2lwZXIkbG9vcGVkU2xpZGVzLFxuICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAkZWwgPSBzd2lwZXIuJGVsO1xuICAgIHZhciBicmVha3BvaW50cyA9IHBhcmFtcy5icmVha3BvaW50cztcbiAgICBpZiAoIWJyZWFrcG9pbnRzIHx8IGJyZWFrcG9pbnRzICYmIE9iamVjdC5rZXlzKGJyZWFrcG9pbnRzKS5sZW5ndGggPT09IDApIHJldHVybjsgLy8gR2V0IGJyZWFrcG9pbnQgZm9yIHdpbmRvdyB3aWR0aCBhbmQgdXBkYXRlIHBhcmFtZXRlcnNcblxuICAgIHZhciBicmVha3BvaW50ID0gc3dpcGVyLmdldEJyZWFrcG9pbnQoYnJlYWtwb2ludHMpO1xuXG4gICAgaWYgKGJyZWFrcG9pbnQgJiYgc3dpcGVyLmN1cnJlbnRCcmVha3BvaW50ICE9PSBicmVha3BvaW50KSB7XG4gICAgICB2Y
166XIgYnJlYWtwb2ludE9ubHlQYXJhbXMgPSBicmVha3BvaW50IGluIGJyZWFrcG9pbnRzID8gYnJlYWtwb2ludHNbYnJlYWtwb2ludF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChicmVha3BvaW50T25seVBhcmFtcykge1xuICAgICAgICBbJ3NsaWRlc1BlclZpZXcnLCAnc3BhY2VCZXR3ZWVuJywgJ3NsaWRlc1Blckdyb3VwJywgJ3NsaWRlc1Blckdyb3VwU2tpcCcsICdzbGlkZXNQZXJDb2x1bW4nXS5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgICAgICAgIHZhciBwYXJhbVZhbHVlID0gYnJlYWtwb2ludE9ubHlQYXJhbXNbcGFyYW1dO1xuICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1WYWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcblxuICAgICAgICAgIGlmIChwYXJhbSA9PT0gJ3NsaWRlc1BlclZpZXcnICYmIChwYXJhbVZhbHVlID09PSAnQVVUTycgfHwgcGFyYW1WYWx1ZSA9PT0gJ2F1dG8nKSkge1xuICAgICAgICAgICAgYnJlYWtwb2ludE9ubHlQYXJhbXNbcGFyYW1dID0gJ2F1dG8nO1xuICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0gPT09ICdzbGlkZXNQZXJWaWV3Jykge1xuICAgICAgICAgICAgYnJlYWtwb2ludE9ubHlQYXJhbXNbcGFyYW1dID0gcGFyc2VGbG9hdChwYXJhbVZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWtwb2ludE9ubHlQYXJhbXNbcGFyYW1dID0gcGFyc2VJbnQocGFyYW1WYWx1ZSwgMTApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBicmVha3BvaW50UGFyYW1zID0gYnJlYWtwb2ludE9ubHlQYXJhbXMgfHwgc3dpcGVyLm9yaWdpbmFsUGFyYW1zO1xuICAgICAgdmFyIHdhc011bHRpUm93ID0gcGFyYW1zLnNsaWRlc1BlckNvbHVtbiA+IDE7XG4gICAgICB2Y
166XIgaXNNdWx0aVJvdyA9IGJyZWFrcG9pbnRQYXJhbXMuc2xpZGVzUGVyQ29sdW1uID4gMTtcblxuICAgICAgaWYgKHdhc011bHRpUm93ICYmICFpc011bHRpUm93KSB7XG4gICAgICAgICRlbC5yZW1vdmVDbGFzcyhwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwibXVsdGlyb3cgXCIgKyBwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwibXVsdGlyb3ctY29sdW1uXCIpO1xuICAgICAgICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcbiAgICAgIH0gZWxzZSBpZiAoIXdhc011bHRpUm93ICYmIGlzTXVsdGlSb3cpIHtcbiAgICAgICAgJGVsLmFkZENsYXNzKHBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzICsgXCJtdWx0aXJvd1wiKTtcblxuICAgICAgICBpZiAoYnJlYWtwb2ludFBhcmFtcy5zbGlkZXNQZXJDb2x1bW5GaWxsID09PSAnY29sdW1uJykge1xuICAgICAgICAgICRlbC5hZGRDbGFzcyhwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwibXVsdGlyb3ctY29sdW1uXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpcGVyLmVtaXRDb250YWluZXJDbGFzc2VzKCk7XG4gICAgICB9XG5cbiAgICAgIHZhciBkaXJlY3Rpb25DaGFuZ2VkID0gYnJlYWtwb2ludFBhcmFtcy5kaXJlY3Rpb24gJiYgYnJlYWtwb2ludFBhcmFtcy5kaXJlY3Rpb24gIT09IHBhcmFtcy5kaXJlY3Rpb247XG4gICAgICB2YXIgbmVlZHNSZUxvb3AgPSBwYXJhbXMubG9vcCAmJiAoYnJlYWtwb2ludFBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSBwYXJhbXMuc2xpZGVzUGVyVmlldyB8fCBkaXJlY3Rpb25DaGFuZ2VkKTtcblxuICAgICAgaWYgKGRpcmVjdGlvbkNoYW5nZWQgJiYgaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgc3dpcGVyLmNoYW5nZURpcmVjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICBleHRlbmQkMShzd2lwZXIucGFyYW1zLCBicmVha3BvaW50UGFyYW1zKTtcbiAgICAgIGV4dGVuZCQxKHN3aXBlciwge1xuICAgICAgICBhbGxvd1RvdWNoTW92ZTogc3dpcGVyLnBhcmFtcy5hbGxvd1RvdWNoTW92ZSxcbiAgICAgICAgYWxsb3dTbGlkZU5leHQ6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZU5leHQsXG4gICAgICAgIGFsbG93U2xpZGVQcmV2OiBzd2lwZXIucGFyYW1zLmFsbG93U2xpZGVQcmV2XG4gICAgICB9KTtcbiAgICAgIHN3aXBlci5jdXJyZW50QnJlYWtwb2ludCA9IGJyZWFrcG9pbnQ7XG5cbiAgICAgIGlmIChuZWVkc1JlTG9vcCAmJiBpbml0aWFsaXplZCkge1xuICAgICAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgICAgICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhhY3RpdmVJbmRleCAtIGxvb3BlZFNsaWRlcyArIHN3aXBlci5sb29wZWRTbGlkZXMsIDAsIGZhbHNlKTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLmVtaXQoJ2JyZWFrcG9pbnQnLCBicmVha3BvaW50UGFyYW1zKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRCcmVha3BvaW50cyhicmVha3BvaW50cykge1xuICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTsgLy8gR2V0IGJyZWFrcG9pbnQgZm9yIHdpbmRvdyB3aWR0aFxuXG4gICAgaWYgKCFicmVha3BvaW50cykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB2YXIgYnJlYWtwb2ludCA9IGZhbHNlO1xuICAgIHZhciBwb2ludHMgPSBPYmplY3Qua2V5cyhicmVha3BvaW50cykubWFwKGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgaWYgKHR5cGVvZiBwb2ludCA9PT0gJ3N0cmluZycgJiYgcG9pbnQuaW5kZXhPZignQCcpID09PSAwKSB7XG4gICAgICAgIHZhciBtaW5SYXRpbyA9IHBhcnNlRmxvYXQocG9pbnQuc3Vic3RyKDEpKTtcbiAgICAgICAgdmFyIHZhbHVlID0gd2luZG93LmlubmVySGVpZ2h0ICogbWluUmF0aW87XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgIHBvaW50OiBwb2ludFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogcG9pbnQsXG4gICAgICAgIHBvaW50OiBwb2ludFxuICAgICAgfTtcbiAgICB9KTtcbiAgICBwb2ludHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGEudmFsdWUsIDEwKSAtIHBhcnNlSW50KGIudmFsdWUsIDEwKTtcbiAgICB9KTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2Y
166XIgX3BvaW50cyRpID0gcG9pbnRzW2ldLFxuICAgICAgICAgIHBvaW50ID0gX3BvaW50cyRpLnBvaW50LFxuICAgICAgICAgIHZhbHVlID0gX3BvaW50cyRpLnZhbHVlO1xuXG4gICAgICBpZiAodmFsdWUgPD0gd2luZG93LmlubmVyV2lkdGgpIHtcbiAgICAgICAgYnJlYWtwb2ludCA9IHBvaW50O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBicmVha3BvaW50IHx8ICdtYXgnO1xuICB9XG5cbiAgdmFyIGJyZWFrcG9pbnRzID0ge1xuICAgIHNldEJyZWFrcG9pbnQ6IHNldEJyZWFrcG9pbnQsXG4gICAgZ2V0QnJlYWtwb2ludDogZ2V0QnJlYWtwb2ludHNcbiAgfTtcblxuICBmdW5jdGlvbiBhZGRDbGFzc2VzKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciBjbGFzc05hbWVzID0gc3dpcGVyLmNsYXNzTmFtZXMsXG4gICAgICAgIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgIHJ0bCA9IHN3aXBlci5ydGwsXG4gICAgICAgICRlbCA9IHN3aXBlci4kZWwsXG4gICAgICAgIGRldmljZSA9IHN3aXBlci5kZXZpY2U7XG4gICAgdmFyIHN1ZmZpeGVzID0gW107XG4gICAgc3VmZml4ZXMucHVzaCgnaW5pdGlhbGl6ZWQnKTtcbiAgICBzdWZmaXhlcy5wdXNoKHBhcmFtcy5kaXJlY3Rpb24pO1xuXG4gICAgaWYgKHBhcmFtcy5mcmVlTW9kZSkge1xuICAgICAgc3VmZml4ZXMucHVzaCgnZnJlZS1tb2RlJyk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5hdXRvSGVpZ2h0KSB7XG4gICAgICBzdWZmaXhlcy5wdXNoKCdhdXRvaGVpZ2h0Jyk7XG4gICAgfVxuXG4gICAgaWYgKHJ0bCkge1xuICAgICAgc3VmZml4ZXMucHVzaCgncnRsJyk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJDb2x1bW4gPiAxKSB7XG4gICAgICBzdWZmaXhlcy5wdXNoKCdtdWx0aXJvdycpO1xuXG4gICAgICBpZiAocGFyYW1zLnNsaWRlc1BlckNvbHVtbkZpbGwgPT09ICdjb2x1bW4nKSB7XG4gICAgICAgIHN1ZmZpeGVzLnB1c2goJ211bHRpcm93LWNvbHVtbicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZXZpY2UuYW5kcm9pZCkge1xuICAgICAgc3VmZml4ZXMucHVzaCgnYW5kcm9pZCcpO1xuICAgIH1cblxuICAgIGlmIChkZXZpY2UuaW9zKSB7XG4gICAgICBzdWZmaXhlcy5wdXNoKCdpb3MnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHN1ZmZpeGVzLnB1c2goJ2Nzcy1tb2RlJyk7XG4gICAgfVxuXG4gICAgc3VmZml4ZXMuZm9yRWFjaChmdW5jdGlvbiAoc3VmZml4KSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2gocGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBzdWZmaXgpO1xuICAgIH0pO1xuICAgICRlbC5hZGRDbGFzcyhjbGFzc05hbWVzLmpvaW4oJyAnKSk7XG4gICAgc3dpcGVyLmVtaXRDb250YWluZXJDbGFzc2VzKCk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVDbGFzc2VzKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHZhciAkZWwgPSBzd2lwZXIuJGVsLFxuICAgICAgICBjbGFzc05hbWVzID0gc3dpcGVyLmNsYXNzTmFtZXM7XG4gICAgJGVsLnJlbW92ZUNsYXNzKGNsYXNzTmFtZXMuam9pbignICcpKTtcbiAgICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcbiAgfVxuXG4gIHZhciBjbGFzc2VzID0ge1xuICAgIGFkZENsYXNzZXM6IGFkZENsYXNzZXMsXG4gICAgcmVtb3ZlQ2xhc3NlczogcmVtb3ZlQ2xhc3Nlc1xuICB9O1xuXG4gIGZ1bmN0aW9uIGxvYWRJbWFnZShpbWFnZUVsLCBzcmMsIHNyY3NldCwgc2l6ZXMsIGNoZWNrRm9yQ29tcGxldGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIHZhciBpbWFnZTtcblxuICAgIGZ1bmN0aW9uIG9uUmVhZHkoKSB7XG4gICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgdmFyIGlzUGljdHVyZSA9ICQoaW1hZ2VFbCkucGFyZW50KCdwaWN0dXJlJylbMF07XG5cbiAgICBpZiAoIWlzUGljdHVyZSAmJiAoIWltYWdlRWwuY29tcGxldGUgfHwgIWNoZWNrRm9yQ29tcGxldGUpKSB7XG4gICAgICBpZiAoc3JjKSB7XG4gICAgICAgIGltYWdlID0gbmV3IHdpbmRvdy5JbWFnZSgpO1xuICAgICAgICBpbWFnZS5vbmxvYWQgPSBvblJlYWR5O1xuICAgICAgICBpbWFnZS5vbmVycm9yID0gb25SZWFkeTtcblxuICAgICAgICBpZiAoc2l6ZXMpIHtcbiAgICAgICAgICBpbWFnZS5zaXplcyA9IHNpemVzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNyY3NldCkge1xuICAgICAgICAgIGltYWdlLnNyY3NldCA9IHNyY3NldDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgICBpbWFnZS5zcmMgPSBzcmM7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uUmVhZHkoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaW1hZ2UgYWxyZWFkeSBsb2FkZWQuLi5cbiAgICAgIG9uUmVhZHkoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBwcmVsb2FkSW1hZ2VzKCkge1xuICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgIHN3aXBlci5pbWFnZXNUb0xvYWQgPSBzd2lwZXIuJGVsLmZpbmQoJ2ltZycpO1xuXG4gICAgZnVuY3Rpb24gb25SZWFkeSgpIHtcbiAgICAgIGlmICh0eXBlb2Ygc3dpcGVyID09PSAndW5kZWZpbmVkJyB8fCBzd2lwZXIgPT09IG51bGwgfHwgIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICBpZiAoc3dpcGVyLmltYWdlc0xvYWRlZCAhPT0gdW5kZWZpbmVkKSBzd2lwZXIuaW1hZ2VzTG9hZGVkICs9IDE7XG5cbiAgICAgIGlmIChzd2lwZXIuaW1hZ2VzTG9hZGVkID09PSBzd2lwZXIuaW1hZ2VzVG9Mb2FkLmxlbmd0aCkge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy51cGRhdGVPbkltYWdlc1JlYWR5KSBzd2lwZXIudXBkYXRlKCk7XG4gICAgICAgIHN3aXBlci5lbWl0KCdpbWFnZXNSZWFkeScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3dpcGVyLmltYWdlc1RvTG9hZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdmFyIGltYWdlRWwgPSBzd2lwZXIuaW1hZ2VzVG9Mb2FkW2ldO1xuICAgICAgc3dpcGVyLmxvYWRJbWFnZShpbWFnZUVsLCBpbWFnZUVsLmN1cnJlbnRTcmMgfHwgaW1hZ2VFbC5nZXRBdHRyaWJ1dGUoJ3NyYycpLCBpbWFnZUVsLnNyY3NldCB8fCBpbWFnZUVsLmdldEF0dHJpYnV0ZSgnc3Jjc2V0JyksIGltYWdlRWwuc2l6ZXMgfHwgaW1hZ2VFbC5nZXRBdHRyaWJ1dGUoJ3NpemVzJyksIHRydWUsIG9uUmVhZHkpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpbWFnZXMgPSB7XG4gICAgbG9hZEltYWdlOiBsb2FkSW1hZ2UsXG4gICAgcHJlbG9hZEltYWdlczogcHJlbG9hZEltYWdlc1xuICB9O1xuXG4gIGZ1bmN0aW9uIGNoZWNrT3ZlcmZsb3coKSB7XG4gICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXM7XG4gICAgdmFyIHdhc0xvY2tlZCA9IHN3aXBlci5pc0xvY2tlZDtcbiAgICB2YXIgbGFzdFNsaWRlUG9zaXRpb24gPSBzd2lwZXIuc2xpZGVzLmxlbmd0aCA+IDAgJiYgcGFyYW1zLnNsaWRlc09mZnNldEJlZm9yZSArIHBhcmFtcy5zcGFjZUJldHdlZW4gKiAoc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxKSArIHN3aXBlci5zbGlkZXNbMF0ub2Zmc2V0V2lkdGggKiBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcblxuICAgIGlmIChwYXJhbXMuc2xpZGVzT2Zmc2V0QmVmb3JlICYmIHBhcmFtcy5zbGlkZXNPZmZzZXRBZnRlciAmJiBsYXN0U2xpZGVQb3NpdGlvbikge1xuICAgICAgc3dpcGVyLmlzTG9ja2VkID0gbGFzdFNsaWRlUG9zaXRpb24gPD0gc3dpcGVyLnNpemU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci5pc0xvY2tlZCA9IHN3aXBlci5zbmFwR3JpZC5sZW5ndGggPT09IDE7XG4gICAgfVxuXG4gICAgc3dpcGVyLmFsbG93U2xpZGVOZXh0ID0gIXN3aXBlci5pc0xvY2tlZDtcbiAgICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSAhc3dpcGVyLmlzTG9ja2VkOyAvLyBldmVudHNcblxuICAgIGlmICh3YXNMb2NrZWQgIT09I
166HN3aXBlci5pc0xvY2tlZCkgc3dpcGVyLmVtaXQoc3dpcGVyLmlzTG9ja2VkID8gJ2xvY2snIDogJ3VubG9jaycpO1xuXG4gICAgaWYgKHdhc0xvY2tlZCAmJiB3YXNMb2NrZWQgIT09IHN3aXBlci5pc0xvY2tlZCkge1xuICAgICAgc3dpcGVyLmlzRW5kID0gZmFsc2U7XG4gICAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24pIHN3aXBlci5uYXZpZ2F0aW9uLnVwZGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjaGVja092ZXJmbG93JDEgPSB7XG4gICAgY2hlY2tPdmVyZmxvdzogY2hlY2tPdmVyZmxvd1xuICB9O1xuXG4gIHZhciBkZWZhdWx0cyA9IHtcbiAgICBpbml0OiB0cnVlLFxuICAgIGRpcmVjdGlvbjogJ2hvcml6b250YWwnLFxuICAgIHRvdWNoRXZlbnRzVGFyZ2V0OiAnY29udGFpbmVyJyxcbiAgICBpbml0aWFsU2xpZGU6IDAsXG4gICAgc3BlZWQ6IDMwMCxcbiAgICBjc3NNb2RlOiBmYWxzZSxcbiAgICB1cGRhdGVPbldpbmRvd1Jlc2l6ZTogdHJ1ZSxcbiAgICAvLyBPdmVycmlkZXNcbiAgICB3aWR0aDogbnVsbCxcbiAgICBoZWlnaHQ6IG51bGwsXG4gICAgLy9cbiAgICBwcmV2ZW50SW50ZXJhY3Rpb25PblRyYW5zaXRpb246IGZhbHNlLFxuICAgIC8vIHNzclxuICAgIHVzZXJBZ2VudDogbnVsbCxcbiAgICB1cmw6IG51bGwsXG4gICAgLy8gVG8gc3VwcG9ydCBpT1MncyBzd2lwZS10by1nby1iYWNrIGdlc3R1cmUgKHdoZW4gYmVpbmcgdXNlZCBpbi1hcHApLlxuICAgIGVkZ2VTd2lwZURldGVjdGlvbjogZmFsc2UsXG4gICAgZWRnZVN3aXBlVGhyZXNob2xkOiAyMCxcbiAgICAvLyBGcmVlIG1vZGVcbiAgICBmcmVlTW9kZTogZmFsc2UsXG4gICAgZnJlZU1vZGVNb21lbnR1bTogdHJ1ZSxcbiAgICBmcmVlTW9kZU1vbWVudHVtUmF0aW86IDEsXG4gICAgZnJlZU1vZGVNb21lbnR1bUJvdW5jZTogdHJ1ZSxcbiAgICBmcmVlTW9kZU1vbWVudHVtQm91bmNlUmF0aW86IDEsXG4gICAgZnJlZU1vZGVNb21lbnR1bVZlbG9jaXR5UmF0aW86IDEsXG4gICAgZnJlZU1vZGVTdGlja3k6IGZhbHNlLFxuICAgIGZyZWVNb2RlTWluaW11bVZlbG9jaXR5OiAwLjAyLFxuICAgIC8vIEF1dG9oZWlnaHRcbiAgICBhdXRvSGVpZ2h0OiBmYWxzZSxcbiAgICAvLyBTZXQgd3JhcHBlciB3aWR0aFxuICAgIHNldFdyYXBwZXJTaXplOiBmYWxzZSxcbiAgICAvLyBWaXJ0dWFsIFRyYW5zbGF0ZVxuICAgIHZpcnR1YWxUcmFuc2xhdGU6IGZhbHNlLFxuICAgIC8vIEVmZmVjdHNcbiAgICBlZmZlY3Q6ICdzbGlkZScsXG4gICAgLy8gJ3NsaWRlJyBvciAnZmFkZScgb3IgJ2N1YmUnIG9yICdjb3ZlcmZsb3cnIG9yICdmbGlwJ1xuICAgIC8vIEJyZWFrcG9pbnRzXG4gICAgYnJlYWtwb2ludHM6IHVuZGVmaW5lZCxcbiAgICAvLyBTbGlkZXMgZ3JpZFxuICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgIHNsaWRlc1BlckNvbHVtbjogMSxcbiAgICBzbGlkZXNQZXJDb2x1bW5GaWxsOiAnY29sdW1uJyxcbiAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICBzbGlkZXNQZXJHcm91cFNraXA6IDAsXG4gICAgY2VudGVyZWRTbGlkZXM6IGZhbHNlLFxuICAgIGNlbnRlcmVkU2xpZGVzQm91bmRzOiBmYWxzZSxcbiAgICBzbGlkZXNPZmZzZXRCZWZvcmU6IDAsXG4gICAgLy8gaW4gcHhcbiAgICBzbGlkZXNPZmZzZXRBZnRlcjogMCxcbiAgICAvLyBpbiBweFxuICAgIG5vcm1hbGl6ZVNsaWRlSW5kZXg6IHRydWUsXG4gICAgY2VudGVySW5zdWZmaWNpZW50U2xpZGVzOiBmYWxzZSxcbiAgICAvLyBEaXNhYmxlIHN3aXBlciBhbmQgaGlkZSBuYXZpZ2F0aW9uIHdoZW4gY29udGFpbmVyIG5vdCBvdmVyZmxvd1xuICAgIHdhdGNoT3ZlcmZsb3c6IGZhbHNlLFxuICAgIC8vIFJvdW5kIGxlbmd0aFxuICAgIHJvdW5kTGVuZ3RoczogZmFsc2UsXG4gICAgLy8gVG91Y2hlc1xuICAgIHRvdWNoUmF0aW86IDEsXG4gICAgdG91Y2hBbmdsZTogNDUsXG4gICAgc2ltdWxhdGVUb3VjaDogdHJ1ZSxcbiAgICBzaG9ydFN3aXBlczogdHJ1ZSxcbiAgICBsb25nU3dpcGVzOiB0cnVlLFxuICAgIGxvbmdTd2lwZXNSYXRpbzogMC41LFxuICAgIGxvbmdTd2lwZXNNczogMzAwLFxuICAgIGZvbGxvd0ZpbmdlcjogdHJ1ZSxcbiAgICBhbGxvd1RvdWNoTW92ZTogdHJ1ZSxcbiAgICB0aHJlc2hvbGQ6IDAsXG4gICAgdG91Y2hNb3ZlU3RvcFByb3BhZ2F0aW9uOiBmYWxzZSxcbiAgICB0b3VjaFN0YXJ0UHJldmVudERlZmF1bHQ6IHRydWUsXG4gICAgdG91Y2hTdGFydEZvcmNlUHJldmVudERlZmF1bHQ6IGZhbHNlLFxuICAgIHRvdWNoUmVsZWFzZU9uRWRnZXM6IGZhbHNlLFxuICAgIC8vIFVuaXF1ZSBOYXZpZ2F0aW9uIEVsZW1lbnRzXG4gICAgdW5pcXVlTmF2RWxlbWVudHM6IHRydWUsXG4gICAgLy8gUmVzaXN0YW5jZVxuICAgIHJlc2lzdGFuY2U6IHRydWUsXG4gICAgcmVzaXN0YW5jZVJhdGlvOiAwLjg1LFxuICAgIC8vIFByb2dyZXNzXG4gICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogZmFsc2UsXG4gICAgd2F0Y2hTbGlkZXNWaXNpYmlsaXR5OiBmYWxzZSxcbiAgICAvLyBDdXJzb3JcbiAgICBncmFiQ3Vyc29yOiBmYWxzZSxcbiAgICAvLyBDbGlja3NcbiAgICBwcmV2ZW50Q2xpY2tzOiB0cnVlLFxuICAgIHByZXZlbnRDbGlja3NQcm9wYWdhdGlvbjogdHJ1ZSxcbiAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZSxcbiAgICAvLyBJbWFnZXNcbiAgICBwcmVsb2FkSW1hZ2VzOiB0cnVlLFxuICAgIHVwZGF0ZU9uSW1hZ2VzUmVhZHk6IHRydWUsXG4gICAgLy8gbG9vcFxuICAgIGxvb3A6IGZhbHNlLFxuICAgIGxvb3BBZGRpdGlvbmFsU2xpZGVzOiAwLFxuICAgIGxvb3BlZFNsaWRlczogbnVsbCxcbiAgICBsb29wRmlsbEdyb3VwV2l0aEJsYW5rOiBmYWxzZSxcbiAgICBsb29wUHJldmVudHNTbGlkZTogdHJ1ZSxcbiAgICAvLyBTd2lwaW5nL25vIHN3aXBpbmdcbiAgICBhbGxvd1NsaWRlUHJldjogdHJ1ZSxcbiAgICBhbGxvd1NsaWRlTmV4dDogdHJ1ZSxcbiAgICBzd2lwZUhhbmRsZXI6IG51bGwsXG4gICAgLy8gJy5zd2lwZS1oYW5kbGVyJyxcbiAgICBub1N3aXBpbmc6IHRydWUsXG4gICAgbm9Td2lwaW5nQ2xhc3M6ICdzd2lwZXItbm8tc3dpcGluZycsXG4gICAgbm9Td2lwaW5nU2VsZWN0b3I6IG51bGwsXG4gICAgLy8gUGFzc2l2ZSBMaXN0ZW5lcnNcbiAgICBwYXNzaXZlTGlzdGVuZXJzOiB0cnVlLFxuICAgIC8vIE5TXG4gICAgY29udGFpbmVyTW9kaWZpZXJDbGFzczogJ3N3aXBlci1jb250YWluZXItJyxcbiAgICAvLyBORVdcbiAgICBzbGlkZUNsYXNzOiAnc3dpcGVyLXNsaWRlJyxcbiAgICBzbGlkZUJsYW5rQ2xhc3M6ICdzd2lwZXItc2xpZGUtaW52aXNpYmxlLWJsYW5rJyxcbiAgICBzbGlkZUFjdGl2ZUNsYXNzOiAnc3dpcGVyLXNsaWRlLWFjdGl2ZScsXG4gICAgc2xpZGVEdXBsaWNhdGVBY3RpdmVDbGFzczogJ3N3aXBlci1zbGlkZS1kdXBsaWNhdGUtYWN0aXZlJyxcbiAgICBzbGlkZVZpc2libGVDbGFzczogJ3N3aXBlci1zbGlkZS12aXNpYmxlJyxcbiAgICBzbGlkZUR1cGxpY2F0ZUNsYXNzOiAnc3dpcGVyLXNsaWRlLWR1cGxpY2F0ZScsXG4gICAgc2xpZGVOZXh0Q2xhc3M6ICdzd2lwZXItc2xpZGUtbmV4dCcsXG4gICAgc2xpZGVEdXBsaWNhdGVOZXh0Q2xhc3M6ICdzd2lwZXItc2xpZGUtZHVwbGljYXRlLW5leHQnLFxuICAgIHNsaWRlUHJldkNsYXNzOiAnc3dpcGVyLXNsaWRlLXByZXYnLFxuICAgIHNsaWRlRHVwbGljYXRlUHJldkNsYXNzOiAnc3dpcGVyLXNsaWRlLWR1cGxpY2F0ZS1wcmV2JyxcbiAgICB3cmFwcGVyQ2xhc3M6ICdzd2lwZXItd3JhcHBlcicsXG4gICAgLy8gQ2FsbGJhY2tzXG4gICAgcnVuQ2FsbGJhY2tzT25Jbml0OiB0cnVlLFxuICAgIC8vIEludGVybmFsc1xuICAgIF9lbWl0Q2xhc3NlczogZmFsc2VcbiAgfTtcblxuICB2Y
166XIgcHJvdG90eXBlcyA9IHtcbiAgICBtb2R1bGFyOiBtb2R1bGFyLFxuICAgIGV2ZW50c0VtaXR0ZXI6IGV2ZW50c0VtaXR0ZXIsXG4gICAgdXBkYXRlOiB1cGRhdGUsXG4gICAgdHJhbnNsYXRlOiB0cmFuc2xhdGUsXG4gICAgdHJhbnNpdGlvbjogdHJhbnNpdGlvbiQxLFxuICAgIHNsaWRlOiBzbGlkZSxcbiAgICBsb29wOiBsb29wLFxuICAgIGdyYWJDdXJzb3I6IGdyYWJDdXJzb3IsXG4gICAgbWFuaXB1bGF0aW9uOiBtYW5pcHVsYXRpb24sXG4gICAgZXZlbnRzOiBldmVudHMsXG4gICAgYnJlYWtwb2ludHM6IGJyZWFrcG9pbnRzLFxuICAgIGNoZWNrT3ZlcmZsb3c6IGNoZWNrT3ZlcmZsb3ckMSxcbiAgICBjbGFzc2VzOiBjbGFzc2VzLFxuICAgIGltYWdlczogaW1hZ2VzXG4gIH07XG4gIHZhciBleHRlbmRlZERlZmF1bHRzID0ge307XG5cbiAgdmFyIFN3aXBlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gU3dpcGVyKCkge1xuICAgICAgdmFyIGVsO1xuICAgICAgdmFyIHBhcmFtcztcblxuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiBhcmdzWzBdLmNvbnN0cnVjdG9yICYmIGFyZ3NbMF0uY29uc3RydWN0b3IgPT09IE9iamVjdCkge1xuICAgICAgICBwYXJhbXMgPSBhcmdzWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWwgPSBhcmdzWzBdO1xuICAgICAgICBwYXJhbXMgPSBhcmdzWzFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXBhcmFtcykgcGFyYW1zID0ge307XG4gICAgICBwYXJhbXMgPSBleHRlbmQkMSh7fSwgcGFyYW1zKTtcbiAgICAgIGlmIChlbCAmJiAhcGFyYW1zLmVsKSBwYXJhbXMuZWwgPSBlbDsgLy8gU3dpcGVyIEluc3RhbmNlXG5cbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgc3dpcGVyLnN1cHBvcnQgPSBnZXRTdXBwb3J0KCk7XG4gICAgICBzd2lwZXIuZGV2aWNlID0gZ2V0RGV2aWNlKHtcbiAgICAgICAgdXNlckFnZW50OiBwYXJhbXMudXNlckFnZW50XG4gICAgICB9KTtcbiAgICAgIHN3aXBlci5icm93c2VyID0gZ2V0QnJvd3NlcigpO1xuICAgICAgc3dpcGVyLmV2ZW50c0xpc3RlbmVycyA9IHt9O1xuICAgICAgc3dpcGVyLmV2ZW50c0FueUxpc3RlbmVycyA9IFtdO1xuICAgICAgT2JqZWN0LmtleXMocHJvdG90eXBlcykuZm9yRWFjaChmdW5jdGlvbiAocHJvdG90eXBlR3JvdXApIHtcbiAgICAgICAgT2JqZWN0LmtleXMocHJvdG90eXBlc1twcm90b3R5cGVHcm91cF0pLmZvckVhY2goZnVuY3Rpb24gKHByb3RvTWV0aG9kKSB7XG4gICAgICAgICAgaWYgKCFTd2lwZXIucHJvdG90eXBlW3Byb3RvTWV0aG9kXSkge1xuICAgICAgICAgICAgU3dpcGVyLnByb3RvdHlwZVtwcm90b01ldGhvZF0gPSBwcm90b3R5cGVzW3Byb3RvdHlwZUdyb3VwXVtwcm90b01ldGhvZF07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodHlwZW9mIHN3aXBlci5tb2R1bGVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzd2lwZXIubW9kdWxlcyA9IHt9O1xuICAgICAgfVxuXG4gICAgICBPYmplY3Qua2V5cyhzd2lwZXIubW9kdWxlcykuZm9yRWFjaChmdW5jdGlvbiAobW9kdWxlTmFtZSkge1xuICAgICAgICB2Y
166XIgbW9kdWxlID0gc3dpcGVyLm1vZHVsZXNbbW9kdWxlTmFtZV07XG5cbiAgICAgICAgaWYgKG1vZHVsZS5wYXJhbXMpIHtcbiAgICAgICAgICB2YXIgbW9kdWxlUGFyYW1OYW1lID0gT2JqZWN0LmtleXMobW9kdWxlLnBhcmFtcylbMF07XG4gICAgICAgICAgdmFyIG1vZHVsZVBhcmFtcyA9IG1vZHVsZS5wYXJhbXNbbW9kdWxlUGFyYW1OYW1lXTtcbiAgICAgICAgICBpZiAodHlwZW9mIG1vZHVsZVBhcmFtcyAhPT0gJ29iamVjdCcgfHwgbW9kdWxlUGFyYW1zID09PSBudWxsKSByZXR1cm47XG4gICAgICAgICAgaWYgKCEobW9kdWxlUGFyYW1OYW1lIGluIHBhcmFtcyAmJiAnZW5hYmxlZCcgaW4gbW9kdWxlUGFyYW1zKSkgcmV0dXJuO1xuXG4gICAgICAgICAgaWYgKHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdID09PSB0cnVlKSB7XG4gICAgICAgICAgICBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9IHtcbiAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdID09PSAnb2JqZWN0JyAmJiAhKCdlbmFibGVkJyBpbiBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSkpIHtcbiAgICAgICAgICAgIHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0pIHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdID0ge1xuICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTsgLy8gRXh0ZW5kIGRlZmF1bHRzIHdpdGggbW9kdWxlcyBwYXJhbXNcblxuICAgICAgdmFyIHN3aXBlclBhcmFtcyA9IGV4dGVuZCQxKHt9LCBkZWZhdWx0cyk7XG4gICAgICBzd2lwZXIudXNlUGFyYW1zKHN3aXBlclBhcmFtcyk7IC8vIEV4dGVuZCBkZWZhdWx0cyB3aXRoIHBhc3NlZCBwYXJhbXNcblxuICAgICAgc3dpcGVyLnBhcmFtcyA9IGV4dGVuZCQxKHt9LCBzd2lwZXJQYXJhbXMsIGV4dGVuZGVkRGVmYXVsdHMsIHBhcmFtcyk7XG4gICAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMgPSBleHRlbmQkMSh7fSwgc3dpcGVyLnBhcmFtcyk7XG4gICAgICBzd2lwZXIucGFzc2VkUGFyYW1zID0gZXh0ZW5kJDEoe30sIHBhcmFtcyk7IC8vIGFkZCBldmVudCBsaXN0ZW5lcnNcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMgJiYgc3dpcGVyLnBhcmFtcy5vbikge1xuICAgICAgICBPYmplY3Qua2V5cyhzd2lwZXIucGFyYW1zLm9uKS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgICAgICBzd2lwZXIub24oZXZlbnROYW1lLCBzd2lwZXIucGFyYW1zLm9uW2V2ZW50TmFtZV0pO1xuICAgICAgICB9KTtcbiAgICAgIH0gLy8gU2F2ZSBEb20gbGliXG5cblxuICAgICAgc3dpcGVyLiQgPSAkOyAvLyBGaW5kIGVsXG5cbiAgICAgIHZhciAkZWwgPSAkKHN3aXBlci5wYXJhbXMuZWwpO1xuICAgICAgZWwgPSAkZWxbMF07XG5cbiAgICAgIGlmICghZWwpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgaWYgKCRlbC5sZW5ndGggPiAxKSB7XG4gICAgICAgIHZhciBzd2lwZXJzID0gW107XG4gICAgICAgICRlbC5lYWNoKGZ1bmN0aW9uIChjb250YWluZXJFbCkge1xuICAgICAgICAgIHZhciBuZXdQYXJhbXMgPSBleHRlbmQkMSh7fSwgcGFyYW1zLCB7XG4gICAgICAgICAgICBlbDogY29udGFpbmVyRWxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzd2lwZXJzLnB1c2gobmV3IFN3aXBlcihuZXdQYXJhbXMpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzd2lwZXJzO1xuICAgICAgfVxuXG4gICAgICBlbC5zd2lwZXIgPSBzd2lwZXI7IC8vIEZpbmQgV3JhcHBlclxuXG4gICAgICB2Y
166XIgJHdyYXBwZXJFbDtcblxuICAgICAgaWYgKGVsICYmIGVsLnNoYWRvd1Jvb3QgJiYgZWwuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKSB7XG4gICAgICAgICR3cmFwcGVyRWwgPSAkKGVsLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcIi5cIiArIHN3aXBlci5wYXJhbXMud3JhcHBlckNsYXNzKSk7IC8vIENoaWxkcmVuIG5lZWRzIHRvIHJldHVybiBzbG90IGl0ZW1zXG5cbiAgICAgICAgJHdyYXBwZXJFbC5jaGlsZHJlbiA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgcmV0dXJuICRlbC5jaGlsZHJlbihvcHRpb25zKTtcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICR3cmFwcGVyRWwgPSAkZWwuY2hpbGRyZW4oXCIuXCIgKyBzd2lwZXIucGFyYW1zLndyYXBwZXJDbGFzcyk7XG4gICAgICB9IC8vIEV4dGVuZCBTd2lwZXJcblxuXG4gICAgICBleHRlbmQkMShzd2lwZXIsIHtcbiAgICAgICAgJGVsOiAkZWwsXG4gICAgICAgIGVsOiBlbCxcbiAgICAgICAgJHdyYXBwZXJFbDogJHdyYXBwZXJFbCxcbiAgICAgICAgd3JhcHBlckVsOiAkd3JhcHBlckVsWzBdLFxuICAgICAgICAvLyBDbGFzc2VzXG4gICAgICAgIGNsYXNzTmFtZXM6IFtdLFxuICAgICAgICAvLyBTbGlkZXNcbiAgICAgICAgc2xpZGVzOiAkKCksXG4gICAgICAgIHNsaWRlc0dyaWQ6IFtdLFxuICAgICAgICBzbmFwR3JpZDogW10sXG4gICAgICAgIHNsaWRlc1NpemVzR3JpZDogW10sXG4gICAgICAgIC8vIGlzRGlyZWN0aW9uXG4gICAgICAgIGlzSG9yaXpvbnRhbDogZnVuY3Rpb24gaXNIb3Jpem9udGFsKCkge1xuICAgICAgICAgIHJldHVybiBzd2lwZXIucGFyYW1zLmRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnO1xuICAgICAgICB9LFxuICAgICAgICBpc1ZlcnRpY2FsOiBmdW5jdGlvbiBpc1ZlcnRpY2FsKCkge1xuICAgICAgICAgIHJldHVybiBzd2lwZXIucGFyYW1zLmRpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJztcbiAgICAgICAgfSxcbiAgICAgICAgLy8gUlRMXG4gICAgICAgIHJ0bDogZWwuZGlyLnRvTG93ZXJDYXNlKCkgPT09ICdydGwnIHx8ICRlbC5jc3MoJ2RpcmVjdGlvbicpID09PSAncnRsJyxcbiAgICAgICAgcnRsVHJhbnNsYXRlOiBzd2lwZXIucGFyYW1zLmRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnICYmIChlbC5kaXIudG9Mb3dlckNhc2UoKSA9PT0gJ3J0bCcgfHwgJGVsLmNzcygnZGlyZWN0aW9uJykgPT09ICdydGwnKSxcbiAgICAgICAgd3JvbmdSVEw6ICR3cmFwcGVyRWwuY3NzKCdkaXNwbGF5J
166ykgPT09ICctd2Via2l0LWJveCcsXG4gICAgICAgIC8vIEluZGV4ZXNcbiAgICAgICAgYWN0aXZlSW5kZXg6IDAsXG4gICAgICAgIHJlYWxJbmRleDogMCxcbiAgICAgICAgLy9cbiAgICAgICAgaXNCZWdpbm5pbmc6IHRydWUsXG4gICAgICAgIGlzRW5kOiBmYWxzZSxcbiAgICAgICAgLy8gUHJvcHNcbiAgICAgICAgdHJhbnNsYXRlOiAwLFxuICAgICAgICBwcmV2aW91c1RyYW5zbGF0ZTogMCxcbiAgICAgICAgcHJvZ3Jlc3M6IDAsXG4gICAgICAgIHZlbG9jaXR5OiAwLFxuICAgICAgICBhbmltYXRpbmc6IGZhbHNlLFxuICAgICAgICAvLyBMb2Nrc1xuICAgICAgICBhbGxvd1NsaWRlTmV4dDogc3dpcGVyLnBhcmFtcy5hbGxvd1NsaWRlTmV4dCxcbiAgICAgICAgYWxsb3dTbGlkZVByZXY6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZVByZXYsXG4gICAgICAgIC8vIFRvdWNoIEV2ZW50c1xuICAgICAgICB0b3VjaEV2ZW50czogZnVuY3Rpb24gdG91Y2hFdmVudHMoKSB7XG4gICAgICAgICAgdmFyIHRvdWNoID0gWyd0b3VjaHN0YXJ0JywgJ3RvdWNobW92ZScsICd0b3VjaGVuZCcsICd0b3VjaGNhbmNlbCddO1xuICAgICAgICAgIHZhciBkZXNrdG9wID0gWydtb3VzZWRvd24nLCAnbW91c2Vtb3ZlJywgJ21vdXNldXAnXTtcblxuICAgICAgICAgIGlmIChzd2lwZXIuc3VwcG9ydC5wb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICBkZXNrdG9wID0gWydwb2ludGVyZG93bicsICdwb2ludGVybW92ZScsICdwb2ludGVydXAnXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2lwZXIudG91Y2hFdmVudHNUb3VjaCA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB0b3VjaFswXSxcbiAgICAgICAgICAgIG1vdmU6IHRvdWNoWzFdLFxuICAgICAgICAgICAgZW5kOiB0b3VjaFsyXSxcbiAgICAgICAgICAgIGNhbmNlbDogdG91Y2hbM11cbiAgICAgICAgICB9O1xuICAgICAgICAgIHN3aXBlci50b3VjaEV2ZW50c0Rlc2t0b3AgPSB7XG4gICAgICAgICAgICBzdGFydDogZGVza3RvcFswXSxcbiAgICAgICAgICAgIG1vdmU6IGRlc2t0b3BbMV0sXG4gICAgICAgICAgICBlbmQ6IGRlc2t0b3BbMl1cbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBzd2lwZXIuc3VwcG9ydC50b3VjaCB8fCAhc3dpcGVyLnBhcmFtcy5zaW11bGF0ZVRvdWNoID8gc3dpcGVyLnRvdWNoRXZlbnRzVG91Y2ggOiBzd2lwZXIudG91Y2hFdmVudHNEZXNrdG9wO1xuICAgICAgICB9KCksXG4gICAgICAgIHRvdWNoRXZlbnRzRGF0YToge1xuICAgICAgICAgIGlzVG91Y2hlZDogdW5kZWZpbmVkLFxuICAgICAgICAgIGlzTW92ZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBhbGxvd1RvdWNoQ2FsbGJhY2tzOiB1bmRlZmluZWQsXG4gICAgICAgICAgdG91Y2hTdGFydFRpbWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICBpc1Njcm9sbGluZzogdW5kZWZpbmVkLFxuICAgICAgICAgIGN1cnJlbnRUcmFuc2xhdGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzdGFydFRyYW5zbGF0ZTogdW5kZWZpbmVkLFxuICAgICAgICAgIGFsbG93VGhyZXNob2xkTW92ZTogdW5kZWZpbmVkLFxuICAgICAgICAgIC8vIEZvcm0gZWxlbWVudHMgdG8gbWF0Y2hcbiAgICAgICAgICBmb3JtRWxlbWVudHM6ICdpbnB1dCwgc2VsZWN0LCBvcHRpb24sIHRleHRhcmVhLCBidXR0b24sIHZpZGVvLCBsYWJlbCcsXG4gICAgICAgICAgLy8gTGFzdCBjbGljayB0aW1lXG4gICAgICAgICAgbGFzdENsaWNrVGltZTogbm93KCksXG4gICAgICAgICAgY2xpY2tUaW1lb3V0OiB1bmRlZmluZWQsXG4gICAgICAgICAgLy8gVmVsb2NpdGllc1xuICAgICAgICAgIHZlbG9jaXRpZXM6IFtdLFxuICAgICAgICAgIGFsbG93TW9tZW50dW1Cb3VuY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBpc1RvdWNoRXZlbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzdGFydE1vdmluZzogdW5kZWZpbmVkXG4gICAgICAgIH0sXG4gICAgICAgIC8vIENsaWNrc1xuICAgICAgICBhbGxvd0NsaWNrOiB0cnVlLFxuICAgICAgICAvLyBUb3VjaGVzXG4gICAgICAgIGFsbG93VG91Y2hNb3ZlOiBzd2lwZXIucGFyYW1zLmFsbG93VG91Y2hNb3ZlLFxuICAgICAgICB0b3VjaGVzOiB7XG4gICAgICAgICAgc3RhcnRYOiAwLFxuICAgICAgICAgIHN0YXJ0WTogMCxcbiAgICAgICAgICBjdXJyZW50WDogMCxcbiAgICAgICAgICBjdXJyZW50WTogMCxcbiAgICAgICAgICBkaWZmOiAwXG4gICAgICAgIH0sXG4gICAgICAgIC8vIEltYWdlc1xuICAgICAgICBpbWFnZXNUb0xvYWQ6IFtdLFxuICAgICAgICBpbWFnZXNMb2FkZWQ6IDBcbiAgICAgIH0pOyAvLyBJbnN0YWxsIE1vZHVsZXNcblxuICAgICAgc3dpcGVyLnVzZU1vZHVsZXMoKTtcbiAgICAgIHN3aXBlci5lbWl0KCdfc3dpcGVyJyk7IC8vIEluaXRcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuaW5pdCkge1xuICAgICAgICBzd2lwZXIuaW5pdCgpO1xuICAgICAgfSAvLyBSZXR1cm4gYXBwIGluc3RhbmNlXG5cblxuICAgICAgcmV0dXJuIHN3aXBlcjtcbiAgICB9XG5cbiAgICB2YXIgX3Byb3RvID0gU3dpcGVyLnByb3RvdHlwZTtcblxuICAgIF9wcm90by5lbWl0Q29udGFpbmVyQ2xhc3NlcyA9IGZ1bmN0aW9uIGVtaXRDb250YWluZXJDbGFzc2VzKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBpZiAoIXN3aXBlci5wYXJhbXMuX2VtaXRDbGFzc2VzIHx8ICFzd2lwZXIuZWwpIHJldHVybjtcbiAgICAgIHZhciBjbGFzc2VzID0gc3dpcGVyLmVsLmNsYXNzTmFtZS5zcGxpdCgnICcpLmZpbHRlcihmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG4gICAgICAgIHJldHVybiBjbGFzc05hbWUuaW5kZXhPZignc3dpcGVyLWNvbnRhaW5lcicpID09PSAwIHx8IGNsYXNzTmFtZS5pbmRleE9mKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcykgPT09IDA7XG4gICAgICB9KTtcbiAgICAgIHN3aXBlci5lbWl0KCdfY29udGFpbmVyQ2xhc3NlcycsIGNsYXNzZXMuam9pbignICcpKTtcbiAgICB9O1xuXG4gICAgX3Byb3RvLmVtaXRTbGlkZXNDbGFzc2VzID0gZnVuY3Rpb24gZW1pdFNsaWRlc0NsYXNzZXMoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5fZW1pdENsYXNzZXMgfHwgIXN3aXBlci5lbCkgcmV0dXJuO1xuICAgICAgc3dpcGVyLnNsaWRlcy5lYWNoKGZ1bmN0aW9uIChzbGlkZUVsKSB7XG4gICAgICAgIHZhciBjbGFzc2VzID0gc2xpZGVFbC5jbGFzc05hbWUuc3BsaXQoJyAnKS5maWx0ZXIoZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xuICAgICAgICAgIHJldHVybiBjbGFzc05hbWUuaW5kZXhPZignc3dpcGVyLXNsaWRlJykgPT09IDAgfHwgY2xhc3NOYW1lLmluZGV4T2Yoc3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzKSA9PT0gMDtcbiAgICAgICAgfSk7XG4gICAgICAgIHN3aXBlci5lbWl0KCdfc2xpZGVDbGFzcycsIHNsaWRlRWwsIGNsYXNzZXMuam9pbignICcpKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBfcHJvdG8uc2xpZGVzUGVyVmlld0R5bmFtaWMgPSBmdW5jdGlvbiBzbGlkZXNQZXJWaWV3RHluYW1pYygpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgICAgc2xpZGVzID0gc3dpcGVyLnNsaWRlcyxcbiAgICAgICAgICBzbGlkZXNHcmlkID0gc3dpcGVyLnNsaWRlc0dyaWQsXG4gICAgICAgICAgc3dpcGVyU2l6ZSA9IHN3aXBlci5zaXplLFxuICAgICAgICAgIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgdmFyIHNwdiA9IDE7XG5cbiAgICAgIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgICAgdmFyIHNsaWRlU2l6ZSA9IHNsaWRlc1thY3RpdmVJbmRleF0uc3dpcGVyU2xpZGVTaXplO1xuICAgICAgICB2Y
166XIgYnJlYWtMb29wO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSBhY3RpdmVJbmRleCArIDE7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBpZiAoc2xpZGVzW2ldICYmICFicmVha0xvb3ApIHtcbiAgICAgICAgICAgIHNsaWRlU2l6ZSArPSBzbGlkZXNbaV0uc3dpcGVyU2xpZGVTaXplO1xuICAgICAgICAgICAgc3B2ICs9IDE7XG4gICAgICAgICAgICBpZiAoc2xpZGVTaXplID4gc3dpcGVyU2l6ZSkgYnJlYWtMb29wID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBfaSA9IGFjdGl2ZUluZGV4IC0gMTsgX2kgPj0gMDsgX2kgLT0gMSkge1xuICAgICAgICAgIGlmIChzbGlkZXNbX2ldICYmICFicmVha0xvb3ApIHtcbiAgICAgICAgICAgIHNsaWRlU2l6ZSArPSBzbGlkZXNbX2ldLnN3aXBlclNsaWRlU2l6ZTtcbiAgICAgICAgICAgIHNwdiArPSAxO1xuICAgICAgICAgICAgaWYgKHNsaWRlU2l6ZSA+IHN3aXBlclNpemUpIGJyZWFrTG9vcCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBfaTIgPSBhY3RpdmVJbmRleCArIDE7IF9pMiA8IHNsaWRlcy5sZW5ndGg7IF9pMiArPSAxKSB7XG4gICAgICAgICAgaWYgKHNsaWRlc0dyaWRbX2kyXSAtIHNsaWRlc0dyaWRbYWN0aXZlSW5kZXhdIDwgc3dpcGVyU2l6ZSkge1xuICAgICAgICAgICAgc3B2ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzcHY7XG4gICAgfTtcblxuICAgIF9wcm90by51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcbiAgICAgIHZhciBzbmFwR3JpZCA9IHN3aXBlci5zbmFwR3JpZCxcbiAgICAgICAgICBwYXJhbXMgPSBzd2lwZXIucGFyYW1zOyAvLyBCcmVha3BvaW50c1xuXG4gICAgICBpZiAocGFyYW1zLmJyZWFrcG9pbnRzKSB7XG4gICAgICAgIHN3aXBlci5zZXRCcmVha3BvaW50KCk7XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci51cGRhdGVTaXplKCk7XG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XG4gICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSgpIHtcbiAgICAgICAgdmFyIHRyYW5zbGF0ZVZhbHVlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgKiAtMSA6IHN3aXBlci50cmFuc2xhdGU7XG4gICAgICAgIHZhciBuZXdUcmFuc2xhdGUgPSBNYXRoLm1pbihNYXRoLm1heCh0cmFuc2xhdGVWYWx1ZSwgc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSwgc3dpcGVyLm1pblRyYW5zbGF0ZSgpKTtcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdUcmFuc2xhdGUpO1xuICAgICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRyYW5zbGF0ZWQ7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmZyZWVNb2RlKSB7XG4gICAgICAgIHNldFRyYW5zbGF0ZSgpO1xuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlQXV0b0hlaWdodCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nIHx8IHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA+IDEpICYmIHN3aXBlci5pc0VuZCAmJiAhc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgICAgIHRyYW5zbGF0ZWQgPSBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cmFuc2xhdGVkID0gc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4LCAwLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRyYW5zbGF0ZWQpIHtcbiAgICAgICAgICBzZXRUcmFuc2xhdGUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLndhdGNoT3ZlcmZsb3cgJiYgc25hcEdyaWQgIT09I
166HN3aXBlci5zbmFwR3JpZCkge1xuICAgICAgICBzd2lwZXIuY2hlY2tPdmVyZmxvdygpO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuZW1pdCgndXBkYXRlJyk7XG4gICAgfTtcblxuICAgIF9wcm90by5jaGFuZ2VEaXJlY3Rpb24gPSBmdW5jdGlvbiBjaGFuZ2VEaXJlY3Rpb24obmV3RGlyZWN0aW9uLCBuZWVkVXBkYXRlKSB7XG4gICAgICBpZiAobmVlZFVwZGF0ZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgIG5lZWRVcGRhdGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBjdXJyZW50RGlyZWN0aW9uID0gc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb247XG5cbiAgICAgIGlmICghbmV3RGlyZWN0aW9uKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICBuZXdEaXJlY3Rpb24gPSBjdXJyZW50RGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV3RGlyZWN0aW9uID09PSBjdXJyZW50RGlyZWN0aW9uIHx8IG5ld0RpcmVjdGlvbiAhPT0gJ2hvcml6b250YWwnICYmIG5ld0RpcmVjdGlvbiAhPT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICByZXR1cm4gc3dpcGVyO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuJGVsLnJlbW92ZUNsYXNzKFwiXCIgKyBzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBjdXJyZW50RGlyZWN0aW9uKS5hZGRDbGFzcyhcIlwiICsgc3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzICsgbmV3RGlyZWN0aW9uKTtcbiAgICAgIHN3aXBlci5lbWl0Q29udGFpbmVyQ2xhc3NlcygpO1xuICAgICAgc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPSBuZXdEaXJlY3Rpb247XG4gICAgICBzd2lwZXIuc2xpZGVzLmVhY2goZnVuY3Rpb24gKHNsaWRlRWwpIHtcbiAgICAgICAgaWYgKG5ld0RpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgIHNsaWRlRWwuc3R5bGUud2lkdGggPSAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzbGlkZUVsLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHN3aXBlci5lbWl0KCdjaGFuZ2VEaXJlY3Rpb24nKTtcbiAgICAgIGlmIChuZWVkVXBkYXRlKSBzd2lwZXIudXBkYXRlKCk7XG4gICAgICByZXR1cm4gc3dpcGVyO1xuICAgIH07XG5cbiAgICBfcHJvdG8uaW5pdCA9IGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmIChzd2lwZXIuaW5pdGlhbGl6ZWQpIHJldHVybjtcbiAgICAgIHN3aXBlci5lbWl0KCdiZWZvcmVJbml0Jyk7IC8vIFNldCBicmVha3BvaW50XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmJyZWFrcG9pbnRzKSB7XG4gICAgICAgIHN3aXBlci5zZXRCcmVha3BvaW50KCk7XG4gICAgICB9IC8vIEFkZCBDbGFzc2VzXG5cblxuICAgICAgc3dpcGVyLmFkZENsYXNzZXMoKTsgLy8gQ3JlYXRlIGxvb3BcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICBzd2lwZXIubG9vcENyZWF0ZSgpO1xuICAgICAgfSAvLyBVcGRhdGUgc2l6ZVxuXG5cbiAgICAgIHN3aXBlci51cGRhdGVTaXplKCk7IC8vIFVwZGF0ZSBzbGlkZXNcblxuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93KSB7XG4gICAgICAgIHN3aXBlci5jaGVja092ZXJmbG93KCk7XG4gICAgICB9IC8vIFNldCBHcmFiIEN1cnNvclxuXG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmdyYWJDdXJzb3IpIHtcbiAgICAgICAgc3dpcGVyLnNldEdyYWJDdXJzb3IoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMucHJlbG9hZEltYWdlcykge1xuICAgICAgICBzd2lwZXIucHJlbG9hZEltYWdlcygpO1xuICAgICAgfSAvLyBTbGlkZSBUbyBJbml0aWFsIFNsaWRlXG5cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIucGFyYW1zLmluaXRpYWxTbGlkZSArIHN3aXBlci5sb29wZWRTbGlkZXMsIDAsIHN3aXBlci5wYXJhbXMucnVuQ2FsbGJhY2tzT25Jbml0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5wYXJhbXMuaW5pdGlhbFNsaWRlLCAwLCBzd2lwZXIucGFyYW1zLnJ1bkNhbGxiYWNrc09uSW5pdCk7XG4gICAgICB9IC8vIEF0dGFjaCBldmVudHNcblxuXG4gICAgICBzd2lwZXIuYXR0YWNoRXZlbnRzKCk7IC8vIEluaXQgRmxhZ1xuXG4gICAgICBzd2lwZXIuaW5pdGlhbGl6ZWQgPSB0cnVlOyAvLyBFbWl0XG5cbiAgICAgIHN3aXBlci5lbWl0KCdpbml0Jyk7XG4gICAgfTtcblxuICAgIF9wcm90by5kZXN0cm95ID0gZnVuY3Rpb24gZGVzdHJveShkZWxldGVJbnN0YW5jZSwgY2xlYW5TdHlsZXMpIHtcbiAgICAgIGlmIChkZWxldGVJbnN0YW5jZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgIGRlbGV0ZUluc3RhbmNlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNsZWFuU3R5bGVzID09PSB2b2lkIDApIHtcbiAgICAgICAgY2xlYW5TdHlsZXMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLFxuICAgICAgICAgICRlbCA9IHN3aXBlci4kZWwsXG4gICAgICAgICAgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsLFxuICAgICAgICAgIHNsaWRlcyA9IHN3aXBlci5zbGlkZXM7XG5cbiAgICAgIGlmICh0eXBlb2Ygc3dpcGVyLnBhcmFtcyA9PT0gJ3VuZGVmaW5lZCcgfHwgc3dpcGVyLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLmVtaXQoJ2JlZm9yZURlc3Ryb3knKTsgLy8gSW5pdCBGbGFnXG5cbiAgICAgIHN3aXBlci5pbml0aWFsaXplZCA9IGZhbHNlOyAvLyBEZXRhY2ggZXZlbnRzXG5cbiAgICAgIHN3aXBlci5kZXRhY2hFdmVudHMoKTsgLy8gRGVzdHJveSBsb29wXG5cbiAgICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgICAgIH0gLy8gQ2xlYW51cCBzdHlsZXNcblxuXG4gICAgICBpZiAoY2xlYW5TdHlsZXMpIHtcbiAgICAgICAgc3dpcGVyLnJlbW92ZUNsYXNzZXMoKTtcbiAgICAgICAgJGVsLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XG4gICAgICAgICR3cmFwcGVyRWwucmVtb3ZlQXR0cignc3R5bGUnKTtcblxuICAgICAgICBpZiAoc2xpZGVzICYmIHNsaWRlcy5sZW5ndGgpIHtcbiAgICAgICAgICBzbGlkZXMucmVtb3ZlQ2xhc3MoW3BhcmFtcy5zbGlkZVZpc2libGVDbGFzcywgcGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MsIHBhcmFtcy5zbGlkZU5leHRDbGFzcywgcGFyYW1zLnNsaWRlUHJldkNsYXNzXS5qb2luKCcgJykpLnJlbW92ZUF0dHIoJ3N0eWxlJykucmVtb3ZlQXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzd2lwZXIuZW1pdCgnZGVzdHJveScpOyAvLyBEZXRhY2ggZW1pdHRlciBldmVudHNcblxuICAgICAgT2JqZWN0LmtleXMoc3dpcGVyLmV2ZW50c0xpc3RlbmVycykuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgIHN3aXBlci5vZmYoZXZlbnROYW1lKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZGVsZXRlSW5zdGFuY2UgIT09IGZhbHNlKSB7XG4gICAgICAgIHN3aXBlci4kZWxbMF0uc3dpcGVyID0gbnVsbDtcbiAgICAgICAgZGVsZXRlUHJvcHMoc3dpcGVyKTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgU3dpcGVyLmV4dGVuZERlZmF1bHRzID0gZnVuY3Rpb24gZXh0ZW5kRGVmYXVsdHMobmV3RGVmYXVsdHMpIHtcbiAgICAgIGV4dGVuZCQxKGV4dGVuZGVkRGVmYXVsdHMsIG5ld0RlZmF1bHRzKTtcbiAgICB9O1xuXG4gICAgU3dpcGVyLmluc3RhbGxNb2R1bGUgPSBmdW5jdGlvbiBpbnN0YWxsTW9kdWxlKG1vZHVsZSkge1xuICAgICAgaWYgKCFTd2lwZXIucHJvdG90eXBlLm1vZHVsZXMpIFN3aXBlci5wcm90b3R5cGUubW9kdWxlcyA9IHt9O1xuICAgICAgdmFyIG5hbWUgPSBtb2R1bGUubmFtZSB8fCBPYmplY3Qua2V5cyhTd2lwZXIucHJvdG90eXBlLm1vZHVsZXMpLmxlbmd0aCArIFwiX1wiICsgbm93KCk7XG4gICAgICBTd2lwZXIucHJvdG90eXBlLm1vZHVsZXNbbmFtZV0gPSBtb2R1bGU7XG4gICAgfTtcblxuICAgIFN3aXBlci51c2UgPSBmdW5jdGlvbiB1c2UobW9kdWxlKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShtb2R1bGUpKSB7XG4gICAgICAgIG1vZHVsZS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgcmV0dXJuIFN3aXBlci5pbnN0YWxsTW9kdWxlKG0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFN3aXBlcjtcbiAgICAgIH1cblxuICAgICAgU3dpcGVyLmluc3RhbGxNb2R1bGUobW9kdWxlKTtcbiAgICAgIHJldHVybiBTd2lwZXI7XG4gICAgfTtcblxuICAgIF9jcmVhdGVDbGFzcyhTd2lwZXIsIG51bGwsIFt7XG4gICAgICBrZXk6IFwiZXh0ZW5kZWREZWZhdWx0c1wiLFxuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmRlZERlZmF1bHRzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJkZWZhdWx0c1wiLFxuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gU3dpcGVyO1xuICB9KCk7XG5cbiAgU3dpcGVyLnVzZShbUmVzaXplLCBPYnNlcnZlciQxXSk7XG5cbiAgdmFyIFZpcnR1YWwgPSB7XG4gICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUoZm9yY2UpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIF9zd2lwZXIkcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3ID0gX3N3aXBlciRwYXJhbXMuc2xpZGVzUGVyVmlldyxcbiAgICAgICAgICBzbGlkZXNQZXJHcm91cCA9IF9zd2lwZXIkcGFyYW1zLnNsaWRlc1Blckdyb3VwLFxuICAgICAgICAgIGNlbnRlcmVkU2xpZGVzID0gX3N3aXBlciRwYXJhbXMuY2VudGVyZWRTbGlkZXM7XG4gICAgICB2Y
166XIgX3N3aXBlciRwYXJhbXMkdmlydHVhID0gc3dpcGVyLnBhcmFtcy52aXJ0dWFsLFxuICAgICAgICAgIGFkZFNsaWRlc0JlZm9yZSA9IF9zd2lwZXIkcGFyYW1zJHZpcnR1YS5hZGRTbGlkZXNCZWZvcmUsXG4gICAgICAgICAgYWRkU2xpZGVzQWZ0ZXIgPSBfc3dpcGVyJHBhcmFtcyR2aXJ0dWEuYWRkU2xpZGVzQWZ0ZXI7XG4gICAgICB2YXIgX3N3aXBlciR2aXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwsXG4gICAgICAgICAgcHJldmlvdXNGcm9tID0gX3N3aXBlciR2aXJ0dWFsLmZyb20sXG4gICAgICAgICAgcHJldmlvdXNUbyA9IF9zd2lwZXIkdmlydHVhbC50byxcbiAgICAgICAgICBzbGlkZXMgPSBfc3dpcGVyJHZpcnR1YWwuc2xpZGVzLFxuICAgICAgICAgIHByZXZpb3VzU2xpZGVzR3JpZCA9IF9zd2lwZXIkdmlydHVhbC5zbGlkZXNHcmlkLFxuICAgICAgICAgIHJlbmRlclNsaWRlID0gX3N3aXBlciR2aXJ0dWFsLnJlbmRlclNsaWRlLFxuICAgICAgICAgIHByZXZpb3VzT2Zmc2V0ID0gX3N3aXBlciR2aXJ0dWFsLm9mZnNldDtcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4IHx8IDA7XG4gICAgICB2YXIgb2Zmc2V0UHJvcDtcbiAgICAgIGlmIChzd2lwZXIucnRsVHJhbnNsYXRlKSBvZmZzZXRQcm9wID0gJ3JpZ2h0JztlbHNlIG9mZnNldFByb3AgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnbGVmdCcgOiAndG9wJztcbiAgICAgIHZhciBzbGlkZXNBZnRlcjtcbiAgICAgIHZhciBzbGlkZXNCZWZvcmU7XG5cbiAgICAgIGlmIChjZW50ZXJlZFNsaWRlcykge1xuICAgICAgICBzbGlkZXNBZnRlciA9IE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpICsgc2xpZGVzUGVyR3JvdXAgKyBhZGRTbGlkZXNBZnRlcjtcbiAgICAgICAgc2xpZGVzQmVmb3JlID0gTWF0aC5mbG9vcihzbGlkZXNQZXJWaWV3IC8gMikgKyBzbGlkZXNQZXJHcm91cCArIGFkZFNsaWRlc0JlZm9yZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNsaWRlc0FmdGVyID0gc2xpZGVzUGVyVmlldyArIChzbGlkZXNQZXJHcm91cCAtIDEpICsgYWRkU2xpZGVzQWZ0ZXI7XG4gICAgICAgIHNsaWRlc0JlZm9yZSA9IHNsaWRlc1Blckdyb3VwICsgYWRkU2xpZGVzQmVmb3JlO1xuICAgICAgfVxuXG4gICAgICB2Y
166XIgZnJvbSA9IE1hdGgubWF4KChhY3RpdmVJbmRleCB8fCAwKSAtIHNsaWRlc0JlZm9yZSwgMCk7XG4gICAgICB2YXIgdG8gPSBNYXRoLm1pbigoYWN0aXZlSW5kZXggfHwgMCkgKyBzbGlkZXNBZnRlciwgc2xpZGVzLmxlbmd0aCAtIDEpO1xuICAgICAgdmFyIG9mZnNldCA9IChzd2lwZXIuc2xpZGVzR3JpZFtmcm9tXSB8fCAwKSAtIChzd2lwZXIuc2xpZGVzR3JpZFswXSB8fCAwKTtcbiAgICAgIGV4dGVuZCQxKHN3aXBlci52aXJ0dWFsLCB7XG4gICAgICAgIGZyb206IGZyb20sXG4gICAgICAgIHRvOiB0byxcbiAgICAgICAgb2Zmc2V0OiBvZmZzZXQsXG4gICAgICAgIHNsaWRlc0dyaWQ6IHN3aXBlci5zbGlkZXNHcmlkXG4gICAgICB9KTtcblxuICAgICAgZnVuY3Rpb24gb25SZW5kZXJlZCgpIHtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcblxuICAgICAgICBpZiAoc3dpcGVyLmxhenkgJiYgc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQpIHtcbiAgICAgICAgICBzd2lwZXIubGF6eS5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHByZXZpb3VzRnJvbSA9PT0gZnJvbSAmJiBwcmV2aW91c1RvID09PSB0byAmJiAhZm9yY2UpIHtcbiAgICAgICAgaWYgKHN3aXBlci5zbGlkZXNHcmlkICE9PSBwcmV2aW91c1NsaWRlc0dyaWQgJiYgb2Zmc2V0ICE9PSBwcmV2aW91c09mZnNldCkge1xuICAgICAgICAgIHN3aXBlci5zbGlkZXMuY3NzKG9mZnNldFByb3AsIG9mZnNldCArIFwicHhcIik7XG4gICAgICAgIH1cblxuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLnJlbmRlckV4dGVybmFsKSB7XG4gICAgICAgIHN3aXBlci5wYXJhbXMudmlydHVhbC5yZW5kZXJFeHRlcm5hbC5jYWxsKHN3aXBlciwge1xuICAgICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICAgIGZyb206IGZyb20sXG4gICAgICAgICAgdG86IHRvLFxuICAgICAgICAgIHNsaWRlczogZnVuY3Rpb24gZ2V0U2xpZGVzKCkge1xuICAgICAgICAgICAgdmFyIHNsaWRlc1RvUmVuZGVyID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBmcm9tOyBpIDw9IHRvOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgc2xpZGVzVG9SZW5kZXIucHVzaChzbGlkZXNbaV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gc2xpZGVzVG9SZW5kZXI7XG4gICAgICAgICAgfSgpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwucmVuZGVyRXh0ZXJuYWxVcGRhdGUpIHtcbiAgICAgICAgICBvblJlbmRlcmVkKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBwcmVwZW5kSW5kZXhlcyA9IFtdO1xuICAgICAgdmFyIGFwcGVuZEluZGV4ZXMgPSBbXTtcblxuICAgICAgaWYgKGZvcmNlKSB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLmZpbmQoXCIuXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3MpLnJlbW92ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IHByZXZpb3VzRnJvbTsgaSA8PSBwcmV2aW91c1RvOyBpICs9IDEpIHtcbiAgICAgICAgICBpZiAoaSA8IGZyb20gfHwgaSA+IHRvKSB7XG4gICAgICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC5maW5kKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgaSArIFwiXFxcIl1cIikucmVtb3ZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBzbGlkZXMubGVuZ3RoOyBfaSArPSAxKSB7XG4gICAgICAgIGlmIChfaSA+PSBmcm9tICYmIF9pIDw9IHRvKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwcmV2aW91c1RvID09PSAndW5kZWZpbmVkJyB8fCBmb3JjZSkge1xuICAgICAgICAgICAgYXBwZW5kSW5kZXhlcy5wdXNoKF9pKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKF9pID4gcHJldmlvdXNUbykgYXBwZW5kSW5kZXhlcy5wdXNoKF9pKTtcbiAgICAgICAgICAgIGlmIChfaSA8IHByZXZpb3VzRnJvbSkgcHJlcGVuZEluZGV4ZXMucHVzaChfaSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGFwcGVuZEluZGV4ZXMuZm9yRWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwuYXBwZW5kKHJlbmRlclNsaWRlKHNsaWRlc1tpbmRleF0sIGluZGV4KSk7XG4gICAgICB9KTtcbiAgICAgIHByZXBlbmRJbmRleGVzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGIgLSBhO1xuICAgICAgfSkuZm9yRWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwucHJlcGVuZChyZW5kZXJTbGlkZShzbGlkZXNbaW5kZXhdLCBpbmRleCkpO1xuICAgICAgfSk7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5jaGlsZHJlbignLnN3aXBlci1zbGlkZScpLmNzcyhvZmZzZXRQcm9wLCBvZmZzZXQgKyBcInB4XCIpO1xuICAgICAgb25SZW5kZXJlZCgpO1xuICAgIH0sXG4gICAgcmVuZGVyU2xpZGU6IGZ1bmN0aW9uIHJlbmRlclNsaWRlKHNsaWRlLCBpbmRleCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy52aXJ0dWFsO1xuXG4gICAgICBpZiAocGFyYW1zLmNhY2hlICYmIHN3aXBlci52aXJ0dWFsLmNhY2hlW2luZGV4XSkge1xuICAgICAgICByZXR1cm4gc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdO1xuICAgICAgfVxuXG4gICAgICB2YXIgJHNsaWRlRWwgPSBwYXJhbXMucmVuZGVyU2xpZGUgPyAkKHBhcmFtcy5yZW5kZXJTbGlkZS5jYWxsKHN3aXBlciwgc2xpZGUsIGluZGV4KSkgOiAkKFwiPGRpdiBjbGFzcz1cXFwiXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3MgKyBcIlxcXCIgZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgaW5kZXggKyBcIlxcXCI+XCIgKyBzbGlkZSArIFwiPC9kaXY+XCIpO1xuICAgICAgaWYgKCEkc2xpZGVFbC5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpKSAkc2xpZGVFbC5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcsIGluZGV4KTtcbiAgICAgIGlmIChwYXJhbXMuY2FjaGUpIHN3aXBlci52aXJ0dWFsLmNhY2hlW2luZGV4XSA9ICRzbGlkZUVsO1xuICAgICAgcmV0dXJuICRzbGlkZUVsO1xuICAgIH0sXG4gICAgYXBwZW5kU2xpZGU6IGZ1bmN0aW9uIGFwcGVuZFNsaWRlKHNsaWRlcykge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG5cbiAgICAgIGlmICh0eXBlb2Ygc2xpZGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBpZiAoc2xpZGVzW2ldKSBzd2lwZXIudmlydHVhbC5zbGlkZXMucHVzaChzbGlkZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMucHVzaChzbGlkZXMpO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIudmlydHVhbC51cGRhdGUodHJ1ZSk7XG4gICAgfSxcbiAgICBwcmVwZW5kU2xpZGU6IGZ1bmN0aW9uIHByZXBlbmRTbGlkZShzbGlkZXMpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgdmFyIG5ld0FjdGl2ZUluZGV4ID0gYWN0aXZlSW5kZXggKyAxO1xuICAgICAgdmFyIG51bWJlck9mTmV3U2xpZGVzID0gMTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2xpZGVzKSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIGlmIChzbGlkZXNbaV0pIHN3aXBlci52aXJ0dWFsLnNsaWRlcy51bnNoaWZ0KHNsaWRlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgc2xpZGVzLmxlbmd0aDtcbiAgICAgICAgbnVtYmVyT2ZOZXdTbGlkZXMgPSBzbGlkZXMubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnVuc2hpZnQoc2xpZGVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbC5jYWNoZSkge1xuICAgICAgICB2Y
166XIgY2FjaGUgPSBzd2lwZXIudmlydHVhbC5jYWNoZTtcbiAgICAgICAgdmFyIG5ld0NhY2hlID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKGNhY2hlKS5mb3JFYWNoKGZ1bmN0aW9uIChjYWNoZWRJbmRleCkge1xuICAgICAgICAgIHZhciAkY2FjaGVkRWwgPSBjYWNoZVtjYWNoZWRJbmRleF07XG4gICAgICAgICAgdmFyIGNhY2hlZEVsSW5kZXggPSAkY2FjaGVkRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKTtcblxuICAgICAgICAgIGlmIChjYWNoZWRFbEluZGV4KSB7XG4gICAgICAgICAgICAkY2FjaGVkRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBwYXJzZUludChjYWNoZWRFbEluZGV4LCAxMCkgKyAxKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXdDYWNoZVtwYXJzZUludChjYWNoZWRJbmRleCwgMTApICsgbnVtYmVyT2ZOZXdTbGlkZXNdID0gJGNhY2hlZEVsO1xuICAgICAgICB9KTtcbiAgICAgICAgc3dpcGVyLnZpcnR1YWwuY2FjaGUgPSBuZXdDYWNoZTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLnZpcnR1YWwudXBkYXRlKHRydWUpO1xuICAgICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXgsIDApO1xuICAgIH0sXG4gICAgcmVtb3ZlU2xpZGU6IGZ1bmN0aW9uIHJlbW92ZVNsaWRlKHNsaWRlc0luZGV4ZXMpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKHR5cGVvZiBzbGlkZXNJbmRleGVzID09PSAndW5kZWZpbmVkJyB8fCBzbGlkZXNJbmRleGVzID09PSBudWxsKSByZXR1cm47XG4gICAgICB2Y
166XIgYWN0aXZlSW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHNsaWRlc0luZGV4ZXMpKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSBzbGlkZXNJbmRleGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICAgICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnNwbGljZShzbGlkZXNJbmRleGVzW2ldLCAxKTtcblxuICAgICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwuY2FjaGUpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBzd2lwZXIudmlydHVhbC5jYWNoZVtzbGlkZXNJbmRleGVzW2ldXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2xpZGVzSW5kZXhlc1tpXSA8IGFjdGl2ZUluZGV4KSBhY3RpdmVJbmRleCAtPSAxO1xuICAgICAgICAgIGFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoYWN0aXZlSW5kZXgsIDApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMuc3BsaWNlKHNsaWRlc0luZGV4ZXMsIDEpO1xuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwuY2FjaGUpIHtcbiAgICAgICAgICBkZWxldGUgc3dpcGVyLnZpcnR1YWwuY2FjaGVbc2xpZGVzSW5kZXhlc107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2xpZGVzSW5kZXhlcyA8IGFjdGl2ZUluZGV4KSBhY3RpdmVJbmRleCAtPSAxO1xuICAgICAgICBhY3RpdmVJbmRleCA9IE1hdGgubWF4KGFjdGl2ZUluZGV4LCAwKTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLnZpcnR1YWwudXBkYXRlKHRydWUpO1xuICAgICAgc3dpcGVyLnNsaWRlVG8oYWN0aXZlSW5kZXgsIDApO1xuICAgIH0sXG4gICAgcmVtb3ZlQWxsU2xpZGVzOiBmdW5jdGlvbiByZW1vdmVBbGxTbGlkZXMoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHN3aXBlci52aXJ0dWFsLnNsaWRlcyA9IFtdO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmNhY2hlKSB7XG4gICAgICAgIHN3aXBlci52aXJ0dWFsLmNhY2hlID0ge307XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci52aXJ0dWFsLnVwZGF0ZSh0cnVlKTtcbiAgICAgIHN3aXBlci5zbGlkZVRvKDAsIDApO1xuICAgIH1cbiAgfTtcbiAgdmFyIFZpcnR1YWwkMSA9IHtcbiAgICBuYW1lOiAndmlydHVhbCcsXG4gICAgcGFyYW1zOiB7XG4gICAgICB2aXJ0dWFsOiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBzbGlkZXM6IFtdLFxuICAgICAgICBjYWNoZTogdHJ1ZSxcbiAgICAgICAgcmVuZGVyU2xpZGU6IG51bGwsXG4gICAgICAgIHJlbmRlckV4dGVybmFsOiBudWxsLFxuICAgICAgICByZW5kZXJFeHRlcm5hbFVwZGF0ZTogdHJ1ZSxcbiAgICAgICAgYWRkU2xpZGVzQmVmb3JlOiAwLFxuICAgICAgICBhZGRTbGlkZXNBZnRlcjogMFxuICAgICAgfVxuICAgIH0sXG4gICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGJpbmRNb2R1bGVNZXRob2RzKHN3aXBlciwge1xuICAgICAgICB2aXJ0dWFsOiBfZXh0ZW5kcyhfZXh0ZW5kcyh7fSwgVmlydHVhbCksIHt9LCB7XG4gICAgICAgICAgc2xpZGVzOiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuc2xpZGVzLFxuICAgICAgICAgIGNhY2hlOiB7fVxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgYmVmb3JlSW5pdDogZnVuY3Rpb24gYmVmb3JlSW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwidmlydHVhbFwiKTtcbiAgICAgICAgdmFyIG92ZXJ3cml0ZVBhcmFtcyA9IHtcbiAgICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5wYXJhbXMsIG92ZXJ3cml0ZVBhcmFtcyk7XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5vcmlnaW5hbFBhcmFtcywgb3ZlcndyaXRlUGFyYW1zKTtcblxuICAgICAgICBpZiAoIXN3aXBlci5wYXJhbXMuaW5pdGlhbFNsaWRlKSB7XG4gICAgICAgICAgc3dpcGVyLnZpcnR1YWwudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIudmlydHVhbC51cGRhdGUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIEtleWJvYXJkID0ge1xuICAgIGhhbmRsZTogZnVuY3Rpb24gaGFuZGxlKGV2ZW50KSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgIHZhciBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgICB2YXIgcnRsID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZTtcbiAgICAgIHZhciBlID0gZXZlbnQ7XG4gICAgICBpZiAoZS5vcmlnaW5hbEV2ZW50KSBlID0gZS5vcmlnaW5hbEV2ZW50OyAvLyBqcXVlcnkgZml4XG5cbiAgICAgIHZhciBrYyA9IGUua2V5Q29kZSB8fCBlLmNoYXJDb2RlO1xuICAgICAgdmFyIHBhZ2VVcERvd24gPSBzd2lwZXIucGFyYW1zLmtleWJvYXJkLnBhZ2VVcERvd247XG4gICAgICB2Y
166XIgaXNQYWdlVXAgPSBwYWdlVXBEb3duICYmIGtjID09PSAzMztcbiAgICAgIHZhciBpc1BhZ2VEb3duID0gcGFnZVVwRG93biAmJiBrYyA9PT0gMzQ7XG4gICAgICB2YXIgaXNBcnJvd0xlZnQgPSBrYyA9PT0gMzc7XG4gICAgICB2YXIgaXNBcnJvd1JpZ2h0ID0ga2MgPT09IDM5O1xuICAgICAgdmFyIGlzQXJyb3dVcCA9IGtjID09PSAzODtcbiAgICAgIHZhciBpc0Fycm93RG93biA9IGtjID09PSA0MDsgLy8gRGlyZWN0aW9ucyBsb2Nrc1xuXG4gICAgICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpICYmIGlzQXJyb3dSaWdodCB8fCBzd2lwZXIuaXNWZXJ0aWNhbCgpICYmIGlzQXJyb3dEb3duIHx8IGlzUGFnZURvd24pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFzd2lwZXIuYWxsb3dTbGlkZVByZXYgJiYgKHN3aXBlci5pc0hvcml6b250YWwoKSAmJiBpc0Fycm93TGVmdCB8fCBzd2lwZXIuaXNWZXJ0aWNhbCgpICYmIGlzQXJyb3dVcCB8fCBpc1BhZ2VVcCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZS5zaGlmdEtleSB8fCBlLmFsdEtleSB8fCBlLmN0cmxLZXkgfHwgZS5tZXRhS2V5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQubm9kZU5hbWUgJiYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyB8fCBkb2N1bWVudC5hY3RpdmVFbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICd0ZXh0YXJlYScpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmtleWJvYXJkLm9ubHlJblZpZXdwb3J0ICYmIChpc1BhZ2VVcCB8fCBpc1BhZ2VEb3duIHx8IGlzQXJyb3dMZWZ0IHx8IGlzQXJyb3dSaWdodCB8fCBpc0Fycm93VXAgfHwgaXNBcnJvd0Rvd24pKSB7XG4gICAgICAgIHZhciBpblZpZXcgPSBmYWxzZTsgLy8gQ2hlY2sgdGhhdCBzd2lwZXIgc2hvdWxkIGJlIGluc2lkZSBvZiB2aXNpYmxlIGFyZWEgb2Ygd2luZG93XG5cbiAgICAgICAgaWYgKHN3aXBlci4kZWwucGFyZW50cyhcIi5cIiArIHN3aXBlci5wYXJhbXMuc2xpZGVDbGFzcykubGVuZ3RoID4gMCAmJiBzd2lwZXIuJGVsLnBhcmVudHMoXCIuXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICB2Y
166XIgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgICAgdmFyIHN3aXBlck9mZnNldCA9IHN3aXBlci4kZWwub2Zmc2V0KCk7XG4gICAgICAgIGlmIChydGwpIHN3aXBlck9mZnNldC5sZWZ0IC09IHN3aXBlci4kZWxbMF0uc2Nyb2xsTGVmdDtcbiAgICAgICAgdmFyIHN3aXBlckNvb3JkID0gW1tzd2lwZXJPZmZzZXQubGVmdCwgc3dpcGVyT2Zmc2V0LnRvcF0sIFtzd2lwZXJPZmZzZXQubGVmdCArIHN3aXBlci53aWR0aCwgc3dpcGVyT2Zmc2V0LnRvcF0sIFtzd2lwZXJPZmZzZXQubGVmdCwgc3dpcGVyT2Zmc2V0LnRvcCArIHN3aXBlci5oZWlnaHRdLCBbc3dpcGVyT2Zmc2V0LmxlZnQgKyBzd2lwZXIud2lkdGgsIHN3aXBlck9mZnNldC50b3AgKyBzd2lwZXIuaGVpZ2h0XV07XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzd2lwZXJDb29yZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHZhciBwb2ludCA9IHN3aXBlckNvb3JkW2ldO1xuXG4gICAgICAgICAgaWYgKHBvaW50WzBdID49IDAgJiYgcG9pbnRbMF0gPD0gd2luZG93V2lkdGggJiYgcG9pbnRbMV0gPj0gMCAmJiBwb2ludFsxXSA8PSB3aW5kb3dIZWlnaHQpIHtcbiAgICAgICAgICAgIGluVmlldyA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpblZpZXcpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgaWYgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd0xlZnQgfHwgaXNBcnJvd1JpZ2h0KSB7XG4gICAgICAgICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtlbHNlIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNQYWdlRG93biB8fCBpc0Fycm93UmlnaHQpICYmICFydGwgfHwgKGlzUGFnZVVwIHx8IGlzQXJyb3dMZWZ0KSAmJiBydGwpIHN3aXBlci5zbGlkZU5leHQoKTtcbiAgICAgICAgaWYgKChpc1BhZ2VVcCB8fCBpc0Fycm93TGVmdCkgJiYgIXJ0bCB8fCAoaXNQYWdlRG93biB8fCBpc0Fycm93UmlnaHQpICYmIHJ0bCkgc3dpcGVyLnNsaWRlUHJldigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd1VwIHx8IGlzQXJyb3dEb3duKSB7XG4gICAgICAgICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtlbHNlIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1BhZ2VEb3duIHx8IGlzQXJyb3dEb3duKSBzd2lwZXIuc2xpZGVOZXh0KCk7XG4gICAgICAgIGlmIChpc1BhZ2VVcCB8fCBpc0Fycm93VXApIHN3aXBlci5zbGlkZVByZXYoKTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLmVtaXQoJ2tleVByZXNzJywga2MpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9LFxuICAgIGVuYWJsZTogZnVuY3Rpb24gZW5hYmxlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgaWYgKHN3aXBlci5rZXlib2FyZC5lbmFibGVkKSByZXR1cm47XG4gICAgICAkKGRvY3VtZW50KS5vbigna2V5ZG93bicsIHN3aXBlci5rZXlib2FyZC5oYW5kbGUpO1xuICAgICAgc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQgPSB0cnVlO1xuICAgIH0sXG4gICAgZGlzYWJsZTogZnVuY3Rpb24gZGlzYWJsZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgIGlmICghc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQpIHJldHVybjtcbiAgICAgICQoZG9jdW1lbnQpLm9mZigna2V5ZG93bicsIHN3aXBlci5rZXlib2FyZC5oYW5kbGUpO1xuICAgICAgc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gIH07XG4gIHZhciBLZXlib2FyZCQxID0ge1xuICAgIG5hbWU6ICdrZXlib2FyZCcsXG4gICAgcGFyYW1zOiB7XG4gICAgICBrZXlib2FyZDoge1xuICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgb25seUluVmlld3BvcnQ6IHRydWUsXG4gICAgICAgIHBhZ2VVcERvd246IHRydWVcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAga2V5Ym9hcmQ6IF9leHRlbmRzKHtcbiAgICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgICB9LCBLZXlib2FyZClcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmtleWJvYXJkLmVuYWJsZWQpIHtcbiAgICAgICAgICBzd2lwZXIua2V5Ym9hcmQuZW5hYmxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQpIHtcbiAgICAgICAgICBzd2lwZXIua2V5Ym9hcmQuZGlzYWJsZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIGlzRXZlbnRTdXBwb3J0ZWQoKSB7XG4gICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICB2YXIgZXZlbnROYW1lID0gJ29ud2hlZWwnO1xuICAgIHZhciBpc1N1cHBvcnRlZCA9IChldmVudE5hbWUgaW4gZG9jdW1lbnQpO1xuXG4gICAgaWYgKCFpc1N1cHBvcnRlZCkge1xuICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGV2ZW50TmFtZSwgJ3JldHVybjsnKTtcbiAgICAgIGlzU3VwcG9ydGVkID0gdHlwZW9mIGVsZW1lbnRbZXZlbnROYW1lXSA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9XG5cbiAgICBpZiAoIWlzU3VwcG9ydGVkICYmIGRvY3VtZW50LmltcGxlbWVudGF0aW9uICYmIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUgJiYgLy8gYWx3YXlzIHJldHVybnMgdHJ1ZSBpbiBuZXdlciBicm93c2VycyBhcyBwZXIgdGhlIHN0YW5kYXJkLlxuICAgIC8vIEBzZWUgaHR0cDovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2RvbS1kb21pbXBsZW1lbnRhdGlvbi1oYXNmZWF0dXJlXG4gICAgZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZSgnJywgJycpICE9PSB0cnVlKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBvbmx5IHdheSB0byB0ZXN0IHN1cHBvcnQgZm9yIHRoZSBgd2hlZWxgIGV2ZW50IGluIElFOSsuXG4gICAgICBpc1N1cHBvcnRlZCA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoJ0V2ZW50cy53aGVlbCcsICczLjAnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXNTdXBwb3J0ZWQ7XG4gIH1cblxuICB2YXIgTW91c2V3aGVlbCA9IHtcbiAgICBsYXN0U2Nyb2xsVGltZTogbm93KCksXG4gICAgbGFzdEV2ZW50QmVmb3JlU25hcDogdW5kZWZpbmVkLFxuICAgIHJlY2VudFdoZWVsRXZlbnRzOiBbXSxcbiAgICBldmVudDogZnVuY3Rpb24gZXZlbnQoKSB7XG4gICAgICB2Y
166XIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgICBpZiAod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignZmlyZWZveCcpID4gLTEpIHJldHVybiAnRE9NTW91c2VTY3JvbGwnO1xuICAgICAgcmV0dXJuIGlzRXZlbnRTdXBwb3J0ZWQoKSA/ICd3aGVlbCcgOiAnbW91c2V3aGVlbCc7XG4gICAgfSxcbiAgICBub3JtYWxpemU6IGZ1bmN0aW9uIG5vcm1hbGl6ZShlKSB7XG4gICAgICAvLyBSZWFzb25hYmxlIGRlZmF1bHRzXG4gICAgICB2YXIgUElYRUxfU1RFUCA9IDEwO1xuICAgICAgdmFyIExJTkVfSEVJR0hUID0gNDA7XG4gICAgICB2YXIgUEFHRV9IRUlHSFQgPSA4MDA7XG4gICAgICB2YXIgc1ggPSAwO1xuICAgICAgdmFyIHNZID0gMDsgLy8gc3BpblgsIHNwaW5ZXG5cbiAgICAgIHZhciBwWCA9IDA7XG4gICAgICB2YXIgcFkgPSAwOyAvLyBwaXhlbFgsIHBpeGVsWVxuICAgICAgLy8gTGVnYWN5XG5cbiAgICAgIGlmICgnZGV0YWlsJyBpbiBlKSB7XG4gICAgICAgIHNZID0gZS5kZXRhaWw7XG4gICAgICB9XG5cbiAgICAgIGlmICgnd2hlZWxEZWx0YScgaW4gZSkge1xuICAgICAgICBzWSA9IC1lLndoZWVsRGVsdGEgLyAxMjA7XG4gICAgICB9XG5cbiAgICAgIGlmICgnd2hlZWxEZWx0YVknIGluIGUpIHtcbiAgICAgICAgc1kgPSAtZS53aGVlbERlbHRhWSAvIDEyMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCd3aGVlbERlbHRhWCcgaW4gZSkge1xuICAgICAgICBzWCA9IC1lLndoZWVsRGVsdGFYIC8gMTIwO1xuICAgICAgfSAvLyBzaWRlIHNjcm9sbGluZyBvbiBGRiB3aXRoIERPTU1vdXNlU2Nyb2xsXG5cblxuICAgICAgaWYgKCdheGlzJyBpbiBlICYmIGUuYXhpcyA9PT0gZS5IT1JJWk9OVEFMX0FYSVMpIHtcbiAgICAgICAgc1ggPSBzWTtcbiAgICAgICAgc1kgPSAwO1xuICAgICAgfVxuXG4gICAgICBwWCA9IHNYICogUElYRUxfU1RFUDtcbiAgICAgIHBZID0gc1kgKiBQSVhFTF9TVEVQO1xuXG4gICAgICBpZiAoJ2RlbHRhWScgaW4gZSkge1xuICAgICAgICBwWSA9IGUuZGVsdGFZO1xuICAgICAgfVxuXG4gICAgICBpZiAoJ2RlbHRhWCcgaW4gZSkge1xuICAgICAgICBwWCA9IGUuZGVsdGFYO1xuICAgICAgfVxuXG4gICAgICBpZiAoZS5zaGlmdEtleSAmJiAhcFgpIHtcbiAgICAgICAgLy8gaWYgdXNlciBzY3JvbGxzIHdpdGggc2hpZnQgaGUgd2FudHMgaG9yaXpvbnRhbCBzY3JvbGxcbiAgICAgICAgcFggPSBwWTtcbiAgICAgICAgcFkgPSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoKHBYIHx8IHBZKSAmJiBlLmRlbHRhTW9kZSkge1xuICAgICAgICBpZiAoZS5kZWx0YU1vZGUgPT09IDEpIHtcbiAgICAgICAgICAvLyBkZWx0YSBpbiBMSU5FIHVuaXRzXG4gICAgICAgICAgcFggKj0gTElORV9IRUlHSFQ7XG4gICAgICAgICAgcFkgKj0gTElORV9IRUlHSFQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZGVsdGEgaW4gUEFHRSB1bml0c1xuICAgICAgICAgIHBYICo9IFBBR0VfSEVJR0hUO1xuICAgICAgICAgIHBZICo9IFBBR0VfSEVJR0hUO1xuICAgICAgICB9XG4gICAgICB9IC8vIEZhbGwtYmFjayBpZiBzcGluIGNhbm5vdCBiZSBkZXRlcm1pbmVkXG5cblxuICAgICAgaWYgKHBYICYmICFzWCkge1xuICAgICAgICBzWCA9IHBYIDwgMSA/IC0xIDogMTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBZICYmICFzWSkge1xuICAgICAgICBzWSA9IHBZIDwgMSA/IC0xIDogMTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3Bpblg6IHNYLFxuICAgICAgICBzcGluWTogc1ksXG4gICAgICAgIHBpeGVsWDogcFgsXG4gICAgICAgIHBpeGVsWTogcFlcbiAgICAgIH07XG4gICAgfSxcbiAgICBoYW5kbGVNb3VzZUVudGVyOiBmdW5jdGlvbiBoYW5kbGVNb3VzZUVudGVyKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBzd2lwZXIubW91c2VFbnRlcmVkID0gdHJ1ZTtcbiAgICB9LFxuICAgIGhhbmRsZU1vdXNlTGVhdmU6IGZ1bmN0aW9uIGhhbmRsZU1vdXNlTGVhdmUoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHN3aXBlci5tb3VzZUVudGVyZWQgPSBmYWxzZTtcbiAgICB9LFxuICAgIGhhbmRsZTogZnVuY3Rpb24gaGFuZGxlKGV2ZW50KSB7XG4gICAgICB2YXIgZSA9IGV2ZW50O1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRhcmdldCA9IHN3aXBlci4kZWw7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZXZlbnRzVGFyZ2V0ICE9PSAnY29udGFpbmVyJykge1xuICAgICAgICB0YXJnZXQgPSAkKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5ldmVudHNUYXJnZXQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXN3aXBlci5tb3VzZUVudGVyZWQgJiYgIXRhcmdldFswXS5jb250YWlucyhlLnRhcmdldCkgJiYgIXBhcmFtcy5yZWxlYXNlT25FZGdlcykgcmV0dXJuIHRydWU7XG4gICAgICBpZiAoZS5vcmlnaW5hbEV2ZW50KSBlID0gZS5vcmlnaW5hbEV2ZW50OyAvLyBqcXVlcnkgZml4XG5cbiAgICAgIHZhciBkZWx0YSA9IDA7XG4gICAgICB2YXIgcnRsRmFjdG9yID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IC0xIDogMTtcbiAgICAgIHZhciBkYXRhID0gTW91c2V3aGVlbC5ub3JtYWxpemUoZSk7XG5cbiAgICAgIGlmIChwYXJhbXMuZm9yY2VUb0F4aXMpIHtcbiAgICAgICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgIGlmIChNYXRoLmFicyhkYXRhLnBpeGVsWCkgPiBNYXRoLmFicyhkYXRhLnBpeGVsWSkpIGRlbHRhID0gLWRhdGEucGl4ZWxYICogcnRsRmFjdG9yO2Vsc2UgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoTWF0aC5hYnMoZGF0YS5waXhlbFkpID4gTWF0aC5hYnMoZGF0YS5waXhlbFgpKSBkZWx0YSA9IC1kYXRhLnBpeGVsWTtlbHNlIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsdGEgPSBNYXRoLmFicyhkYXRhLnBpeGVsWCkgPiBNYXRoLmFicyhkYXRhLnBpeGVsWSkgPyAtZGF0YS5waXhlbFggKiBydGxGYWN0b3IgOiAtZGF0YS5waXhlbFk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWx0YSA9PT0gMCkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAocGFyYW1zLmludmVydCkgZGVsdGEgPSAtZGVsdGE7XG5cbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSkge1xuICAgICAgICAvLyBSZWdpc3RlciB0aGUgbmV3IGV2ZW50IGluIGEgdmFyaWFibGUgd2hpY2ggc3RvcmVzIHRoZSByZWxldmFudCBkYXRhXG4gICAgICAgIHZhciBuZXdFdmVudCA9IHtcbiAgICAgICAgICB0aW1lOiBub3coKSxcbiAgICAgICAgICBkZWx0YTogTWF0aC5hYnMoZGVsdGEpLFxuICAgICAgICAgIGRpcmVjdGlvbjogTWF0aC5zaWduKGRlbHRhKSxcbiAgICAgICAgICByYXc6IGV2ZW50XG4gICAgICAgIH07IC8vIEtlZXAgdGhlIG1vc3QgcmVjZW50IGV2ZW50c1xuXG4gICAgICAgIHZhciByZWNlbnRXaGVlbEV2ZW50cyA9IHN3aXBlci5tb3VzZXdoZWVsLnJlY2VudFdoZWVsRXZlbnRzO1xuXG4gICAgICAgIGlmIChyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgIHJlY2VudFdoZWVsRXZlbnRzLnNoaWZ0KCk7IC8vIG9ubHkgc3RvcmUgdGhlIGxhc3QgTiBldmVudHNcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcmV2RXZlbnQgPSByZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPyByZWNlbnRXaGVlbEV2ZW50c1tyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmVjZW50V2hlZWxFdmVudHMucHVzaChuZXdFdmVudCk7IC8vIElmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBwcmV2aW91cyByZWNvcmRlZCBldmVudDpcbiAgICAgICAgLy8gICBJZiBkaXJlY3Rpb24gaGFzIGNoYW5nZWQgb3JcbiAgICAgICAgLy8gICBpZiB0aGUgc2Nyb2xsIGlzIHF1aWNrZXIgdGhhbiB0aGUgcHJldmlvdXMgb25lOlxuICAgICAgICAvLyAgICAgQW5pbWF0ZSB0aGUgc2xpZGVyLlxuICAgICAgICAvLyBFbHNlICh0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIHRoZSB3aGVlbCBpcyBtb3ZlZCk6XG4gICAgICAgIC8vICAgICBBbmltYXRlIHRoZSBzbGlkZXIuXG5cbiAgICAgICAgaWYgKHByZXZFdmVudCkge1xuICAgICAgICAgIGlmIChuZXdFdmVudC5kaXJlY3Rpb24gIT09IHByZXZFdmVudC5kaXJlY3Rpb24gfHwgbmV3RXZlbnQuZGVsdGEgPiBwcmV2RXZlbnQuZGVsdGEgfHwgbmV3RXZlbnQudGltZSA+IHByZXZFdmVudC50aW1lICsgMTUwKSB7XG4gICAgICAgICAgICBzd2lwZXIubW91c2V3aGVlbC5hbmltYXRlU2xpZGVyKG5ld0V2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3dpcGVyLm1vdXNld2hlZWwuYW5pbWF0ZVNsaWRlcihuZXdFdmVudCk7XG4gICAgICAgIH0gLy8gSWYgaXQncyB0aW1lIH
166RvIHJlbGVhc2UgdGhlIHNjcm9sbDpcbiAgICAgICAgLy8gICBSZXR1cm4gbm93IHNvIHlvdSBkb24ndCBoaXQgdGhlIHByZXZlbnREZWZhdWx0LlxuXG5cbiAgICAgICAgaWYgKHN3aXBlci5tb3VzZXdoZWVsLnJlbGVhc2VTY3JvbGwobmV3RXZlbnQpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZyZWVtb2RlIG9yIHNjcm9sbENvbnRhaW5lcjpcbiAgICAgICAgLy8gSWYgd2UgcmVjZW50bHkgc25hcHBlZCBhZnRlciBhIG1vbWVudHVtIHNjcm9sbCwgdGhlbiBpZ25vcmUgd2hlZWwgZXZlbnRzXG4gICAgICAgIC8vIHRvIGdpdmUgdGltZSBmb3IgdGhlIGRlY2VsZXJhdGlvbiB0byBmaW5pc2guIFN0b3AgaWdub3JpbmcgYWZ0ZXIgNTAwIG1zZWNzXG4gICAgICAgIC8vIG9yIGlmIGl0J3MgYSBuZXcgc2Nyb2xsIChsYXJnZXIgZGVsdGEgb3IgaW52ZXJzZSBzaWduIGFzIGxhc3QgZXZlbnQgYmVmb3JlXG4gICAgICAgIC8vIGFuIGVuZC1vZi1tb21lbnR1bSBzbmFwKS5cbiAgICAgICAgdmFyIF9uZXdFdmVudCA9IHtcbiAgICAgICAgICB0aW1lOiBub3coKSxcbiAgICAgICAgICBkZWx0YTogTWF0aC5hYnMoZGVsdGEpLFxuICAgICAgICAgIGRpcmVjdGlvbjogTWF0aC5zaWduKGRlbHRhKVxuICAgICAgICB9O1xuICAgICAgICB2YXIgbGFzdEV2ZW50QmVmb3JlU25hcCA9IHN3aXBlci5tb3VzZXdoZWVsLmxhc3RFdmVudEJlZm9yZVNuYXA7XG4gICAgICAgIHZhciBpZ25vcmVXaGVlbEV2ZW50cyA9IGxhc3RFdmVudEJlZm9yZVNuYXAgJiYgX25ld0V2ZW50LnRpbWUgPCBsYXN0RXZlbnRCZWZvcmVTbmFwLnRpbWUgKyA1
166MDAgJiYgX25ld0V2ZW50LmRlbHRhIDw9IGxhc3RFdmVudEJlZm9yZVNuYXAuZGVsdGEgJiYgX25ld0V2ZW50LmRpcmVjdGlvbiA9PT0gbGFzdEV2ZW50QmVmb3JlU25hcC5kaXJlY3Rpb247XG5cbiAgICAgICAgaWYgKCFpZ25vcmVXaGVlbEV2ZW50cykge1xuICAgICAgICAgIHN3aXBlci5tb3VzZXdoZWVsLmxhc3RFdmVudEJlZm9yZVNuYXAgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgICBzd2lwZXIubG9vcEZpeCgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBwb3NpdGlvbiA9IHN3aXBlci5nZXRUcmFuc2xhdGUoKSArIGRlbHRhICogcGFyYW1zLnNlbnNpdGl2aXR5O1xuICAgICAgICAgIHZhciB3YXNCZWdpbm5pbmcgPSBzd2lwZXIuaXNCZWdpbm5pbmc7XG4gICAgICAgICAgdmFyIHdhc0VuZCA9IHN3aXBlci5pc0VuZDtcbiAgICAgICAgICBpZiAocG9zaXRpb24gPj0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSBwb3NpdGlvbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKTtcbiAgICAgICAgICBpZiAocG9zaXRpb24gPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSBwb3NpdGlvbiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHBvc2l0aW9uKTtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuXG4gICAgICAgICAgaWYgKCF3YXNCZWdpbm5pbmcgJiYgc3dpcGVyLmlzQmVnaW5uaW5nIHx8ICF3YXNFbmQgJiYgc3dpcGVyLmlzRW5kKSB7XG4gICAgICAgICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmZyZWVNb2RlU3RpY2t5KSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdoZWVsIHNjcm9sbGluZyBzdGFydHMgd2l0aCBzdGlja3kgKGFrYSBzbmFwKSBlbmFibGVkLCB0aGVuIGRldGVjdFxuICAgICAgICAgICAgLy8gdGhlIGVuZCBvZiBhIG1vbWVudHVtIHNjcm9sbCBieSBzdG9yaW5nIHJlY2VudCAoTj0xNT8pIHdoZWVsIGV2ZW50cy5cbiAgICAgICAgICAgIC8vIDEuIGRvIGFsbCBOIGV2ZW50cyBoYXZlIGRlY3JlYXNpbmcgb3Igc2FtZSAoYWJzb2x1dGUgdmFsdWUpIGRlbHRhP1xuICAgICAgICAgICAgLy8gMi4gZGlkIGFsbCBOIGV2ZW50cyBhcnJpdmUgaW4gdGhlIGxhc3QgTSAoTT01MDA/KSBtc2Vjcz9cbiAgICAgICAgICAgIC8vIDMuIGRvZXMgdGhlIGVhcmxpZXN0IGV2ZW50IGhhdmUgYW4gKGFic29sdXRlIHZhbHVlKSBkZWx0YSB0aGF0J3NcbiAgICAgICAgICAgIC8vICAgIGF0IGxlYXN0IFAgKFA9MT8pIGxhcmdlciB0aGFuIHRoZSBtb3N0IHJlY2VudCBldmVudCdzIGRlbHRhP1xuICAgICAgICAgICAgLy8gNC4gZG9lcyB0aGUgbGF0ZXN0IGV2ZW50IGhhdmUgYSBkZWx0YSB0aGF0J3Mgc21hbGxlciB0aGFuIFEgKFE9Nj8pIHBpeGVscz9cbiAgICAgICAgICAgIC8vIElmIDEtNCBhcmUgXCJ5ZXNcIiB0aGVuIHdlJ3JlIG5lYXIgdGhlIGVuZCBvZiBhIG1vbXVudHVtIHNjcm9sbCBkZWNlbGVyYXRpb24uXG4gICAgICAgICAgICAvLyBTbmFwIGltbWVkaWF0ZWx5IGFuZCBpZ25vcmUgcmVtYWluaW5nIHdoZWVsIGV2ZW50cyBpbiB0aGlzIHNjcm9sbC5cbiAgICAgICAgICAgIC8vIFNlZSBjb21tZW50IGFib3ZlIGZvciBcInJlbWFpbmluZyB3aGVlbCBldmVudHMgaW4gdGhpcyBzY3JvbGxcIiBkZXRlcm1pbmF0aW9uLlxuICAgICAgICAgICAgLy8gSWYgMS00IGFyZW4ndCBzYXRpc2ZpZWQsIHRoZW4gd2FpdCB0byBzbmFwIHVudGlsIDUwMG1zIGFmdGVyIHRoZSBsYXN0IGV2ZW50LlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHN3aXBlci5tb3VzZXdoZWVsLnRpbWVvdXQpO1xuICAgICAgICAgICAgc3dpcGVyLm1vdXNld2hlZWwudGltZW91dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBfcmVjZW50V2hlZWxFdmVudHMgPSBzd2lwZXIubW91c2V3aGVlbC5yZWNlbnRXaGVlbEV2ZW50cztcblxuICAgICAgICAgICAgaWYgKF9yZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPj0gMTUpIHtcbiAgICAgICAgICAgICAgX3JlY2VudFdoZWVsRXZlbnRzLnNoaWZ0KCk7IC8vIG9ubHkgc3RvcmUgdGhlIGxhc3QgTiBldmVudHNcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2Y
166XIgX3ByZXZFdmVudCA9IF9yZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPyBfcmVjZW50V2hlZWxFdmVudHNbX3JlY2VudFdoZWVsRXZlbnRzLmxlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB2YXIgZmlyc3RFdmVudCA9IF9yZWNlbnRXaGVlbEV2ZW50c1swXTtcblxuICAgICAgICAgICAgX3JlY2VudFdoZWVsRXZlbnRzLnB1c2goX25ld0V2ZW50KTtcblxuICAgICAgICAgICAgaWYgKF9wcmV2RXZlbnQgJiYgKF9uZXdFdmVudC5kZWx0YSA+IF9wcmV2RXZlbnQuZGVsdGEgfHwgX25ld0V2ZW50LmRpcmVjdGlvbiAhPT0gX3ByZXZFdmVudC5kaXJlY3Rpb24pKSB7XG4gICAgICAgICAgICAgIC8vIEluY3JlYXNpbmcgb3IgcmV2ZXJzZS1zaWduIGRlbHRhIG1lYW5zIHRoZSB1c2VyIHN0YXJ0ZWQgc2Nyb2xsaW5nIGFnYWluLiBDbGVhciB0aGUgd2hlZWwgZXZlbnQgbG9nLlxuICAgICAgICAgICAgICBfcmVjZW50V2hlZWxFdmVudHMuc3BsaWNlKDApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChfcmVjZW50V2hlZWxFdmVudHMubGVuZ3RoID49IDE1ICYmIF9uZXdFdmVudC50aW1lIC0gZmlyc3RFdmVudC50aW1lIDwgNTAwICYmIGZpcnN0RXZlbnQuZGVsdGEgLSBfbmV3RXZlbnQuZGVsdGEgPj0gMSAmJiBfbmV3RXZlbnQuZGVsdGEgPD0gNikge1xuICAgICAgICAgICAgICAvLyBXZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSBkZWNlbGVyYXRpb24gb2YgYSBtb21lbnR1bSBzY3JvbGwsIHNvIHRoZXJlJ3Mgbm8gbmVlZFxuICAgICAgICAgICAgICAvLyB0byB3YWl0IGZvciBtb3JlIGV2ZW50cy4gU25hcCBBU0FQIG9uIHRoZSBuZXh0IHRpY2suXG4gICAgICAgICAgICAgIC8vIEFsc28sIGJlY2F1c2UgdGhlcmUncyBzb21lIHJlbWFpbmluZyBtb21lbnR1bSB3ZSdsbCBiaWFzIHRoZSBzbmFwIGluIHRoZVxuICAgICAgICAgICAgICAvLyBkaXJlY3Rpb24gb2YgdGhlIG9uZ29pbmcgc2Nyb2xsIGJlY2F1c2UgaXQncyBiZXR0ZXIgVVggZm9yIHRoZSBzY3JvbGwgdG8gc25hcFxuICAgICAgICAgICAgICAvLyBpbiB0aGUgc2FtZSBkaXJlY3Rpb24gYXMgdGhlIHNjcm9sbCBpbnN0ZWFkIG9mIHJldmVyc2luZyB0byBzbmFwLiAgVGhlcmVmb3JlLFxuICAgICAgICAgICAgICAvLyBpZiBpdCdzIGFscmVhZHkgc2Nyb2xsZWQgbW9yZSB0aGFuIDIwJSBpbiB0aGUgY3VycmVudCBkaXJlY3Rpb24sIGtlZXAgZ29pbmcuXG4gICAgICAgICAgICAgIHZhciBzbmFwVG9UaHJlc2hvbGQgPSBkZWx0YSA+IDAgPyAwLjggOiAwLjI7XG4gICAgICAgICAgICAgIHN3aXBlci5tb3VzZXdoZWVsLmxhc3RFdmVudEJlZm9yZVNuYXAgPSBfbmV3RXZlbnQ7XG5cbiAgICAgICAgICAgICAgX3JlY2VudFdoZWVsRXZlbnRzLnNwbGljZSgwKTtcblxuICAgICAgICAgICAgICBzd2lwZXIubW91c2V3aGVlbC50aW1lb3V0ID0gbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdChzd2lwZXIucGFyYW1zLnNwZWVkLCB0cnVlLCB1bmRlZmluZWQsIHNuYXBUb1RocmVzaG9sZCk7XG4gICAgICAgICAgICAgIH0sIDApOyAvLyBubyBkZWxheTsgbW92ZSBvbiBuZXh0IHRpY2tcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzd2lwZXIubW91c2V3aGVlbC50aW1lb3V0KSB7XG4gICAgICAgICAgICAgIC8vIGlmIHdlIGdldCBoZXJlLCB0aGVuIHdlIGhhdmVuJ3QgZGV0ZWN0ZWQgdGhlIGVuZCBvZiBhIG1vbWVudHVtIHNjcm9sbCwgc29cbiAgICAgICAgICAgICAgLy8gd2UnbGwgY29uc2lkZXIgYSBzY3JvbGwgXCJjb21wbGV0ZVwiIHdoZW4gdGhlcmUgaGF2ZW4ndCBiZWVuIGFueSB3aGVlbCBldmVudHNcbiAgICAgICAgICAgICAgLy8gZm9yIDUwMG1zLlxuICAgICAgICAgICAgICBzd2lwZXIubW91c2V3aGVlbC50aW1lb3V0ID0gbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBzbmFwVG9UaHJlc2hvbGQgPSAwLjU7XG4gICAgICAgICAgICAgICAgc3dpcGVyLm1vdXNld2hlZWwubGFzdEV2ZW50QmVmb3JlU25hcCA9IF9uZXdFdmVudDtcblxuICAgICAgICAgICAgICAgIF9yZWNlbnRXaGVlbEV2ZW50cy5zcGxpY2UoMCk7XG5cbiAgICAgICAgICAgICAgICBzd2lwZXIuc2xpZGVUb0Nsb3Nlc3Qoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdW5kZWZpbmVkLCBzbmFwVG9UaHJlc2hvbGQpO1xuICAgICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8gRW1pdCBldmVudFxuXG5cbiAgICAgICAgICBpZiAoIWlnbm9yZVdoZWVsRXZlbnRzKSBzd2lwZXIuZW1pdCgnc2Nyb2xsJywgZSk7IC8vIFN0b3AgYXV0b3BsYXlcblxuICAgICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9wbGF5ICYmIHN3aXBlci5wYXJhbXMuYXV0b3BsYXlEaXNhYmxlT25JbnRlcmFjdGlvbikgc3dpcGVyLmF1dG9wbGF5LnN0b3AoKTsgLy8gUmV0dXJuIHBhZ2Ugc2Nyb2xsIG9uIGVkZ2UgcG9zaXRpb25zXG5cbiAgICAgICAgICBpZiAocG9zaXRpb24gPT09IHN3aXBlci5taW5UcmFuc2xhdGUoKSB8fCBwb3NpdGlvbiA9PT0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO2Vsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICAgYW5pbWF0ZVNsaWRlcjogZnVuY3Rpb24gYW5pbWF0ZVNsaWRlcihuZXdFdmVudCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgICAgIGlmICh0aGlzLnBhcmFtcy5tb3VzZXdoZWVsLnRocmVzaG9sZERlbHRhICYmIG5ld0V2ZW50LmRlbHRhIDwgdGhpcy5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGREZWx0YSkge1xuICAgICAgICAvLyBQcmV2ZW50IGlmIGRlbHRhIG9mIHdoZWVsIHNjcm9sbCBkZWx0YSBpcyBiZWxvdyBjb25maWd1cmVkIHRocmVzaG9sZFxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhcmFtcy5tb3VzZXdoZWVsLnRocmVzaG9sZFRpbWUgJiYgbm93KCkgLSBzd2lwZXIubW91c2V3aGVlbC5sYXN0U2Nyb2xsVGltZSA8IHRoaXMucGFyYW1zLm1vdXNld2hlZWwudGhyZXNob2xkVGltZSkge1xuICAgICAgICAvLyBQcmV2ZW50IGlmIHRpbWUgYmV0d2VlbiBzY3JvbGxzIGlzIGJlbG93IGNvbmZpZ3VyZWQgdGhyZXNob2xkXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gLy8gSWYgdGhlIG1vdmVtZW50IGlzIE5PVCBiaWcgZW5vdWdoIGFuZFxuICAgICAgLy8gaWYgdGhlIGxhc3QgdGltZSB0aGUgdXNlciBzY3JvbGxlZCB3YXMgdG9vIGNsb3NlIHRvIHRoZSBjdXJyZW50IG9uZSAoYXZvaWQgY29udGludW91c2x5IHRyaWdnZXJpbmcgdGhlIHNsaWRlcik6XG4gICAgICAvLyAgIERvbid0IGdvIGFueSBmdXJ0aGVyIChhdm9pZCBpbnNpZ25pZmljYW50IHNjcm9sbCBtb3ZlbWVudCkuXG5cblxuICAgICAgaWYgKG5ld0V2ZW50LmRlbHRhID49IDYgJiYgbm93KCkgLSBzd2lwZXIubW91c2V3aGVlbC5sYXN0U2Nyb2xsVGltZSA8IDYwKSB7XG4gICAgICAgIC8vIFJldHVybiBmYWxzZSBhcyBhIGRlZmF1bHRcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IC8vIElmIHVzZXIgaXMgc2Nyb2xsaW5nIHRvd2FyZHMgdGhlIGVuZDpcbiAgICAgIC8vICAgSWYgdGhlIHNsaWRlciBoYXNuJ3QgaGl0IHRoZSBsYXRlc3Qgc2xpZGUgb3JcbiAgICAgIC8vICAgaWYgdGhlIHNsaWRlciBpcyBhIGxvb3AgYW5kXG4gICAgICAvLyAgIGlmIHRoZSBzbGlkZXIgaXNuJ3QgbW92aW5nIHJpZ2h0IG5vdzpcbiAgICAgIC8vICAgICBHbyB0byBuZXh0IHNsaWRlIGFuZFxuICAgICAgLy8gICAgIGVtaXQgYSBzY3JvbGwgZXZlbnQuXG4gICAgICAvLyBFbHNlICh0aGUgdXNlciBpcyBzY3JvbGxpbmcgdG93YXJkcyB0aGUgYmVnaW5uaW5nKSBhbmRcbiAgICAgIC8vIGlmIHRoZSBzbGlkZXIgaGFzbid0IGhpdCB0aGUgZmlyc3Qgc2xpZGUgb3JcbiAgICAgIC8vIGlmIHRoZSBzbGlkZXIgaXMgYSBsb29wIGFuZFxuICAgICAgLy8gaWYgdGhlIHNsaWRlciBpc24ndCBtb3ZpbmcgcmlnaHQgbm93OlxuICAgICAgLy8gICBHbyB0byBwcmV2IHNsaWRlIGFuZFxuICAgICAgLy8gICBlbWl0IGEgc2Nyb2xsIGV2ZW50LlxuXG5cbiAgICAgIGlmIChuZXdFdmVudC5kaXJlY3Rpb24gPCAwKSB7XG4gICAgICAgIGlmICgoIXN3aXBlci5pc0VuZCB8fCBzd2lwZXIucGFyYW1zLmxvb3ApICYmICFzd2lwZXIuYW5pbWF0aW5nKSB7XG4gICAgICAgICAgc3dpcGVyLnNsaWRlTmV4dCgpO1xuICAgICAgICAgIHN3aXBlci5lbWl0KCdzY3JvbGwnLCBuZXdFdmVudC5yYXcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCghc3dpcGVyLmlzQmVnaW5uaW5nIHx8IHN3aXBlci5wYXJhbXMubG9vcCkgJiYgIXN3aXBlci5hbmltYXRpbmcpIHtcbiAgICAgICAgc3dpcGVyLnNsaWRlUHJldigpO1xuICAgICAgICBzd2lwZXIuZW1pdCgnc2Nyb2xsJywgbmV3RXZlbnQucmF3KTtcbiAgICAgIH0gLy8gSWYgeW91IGdvdCBoZXJlIGlzIGJlY2F1c2UgYW4gYW5pbWF0aW9uIGhhcyBiZWVuIHRyaWdnZXJlZCBzbyBzdG9yZSB0aGUgY3VycmVudCB0aW1lXG5cblxuICAgICAgc3dpcGVyLm1vdXNld2hlZWwubGFzdFNjcm9sbFRpbWUgPSBuZXcgd2luZG93LkRhdGUoKS5nZXRUaW1lKCk7IC8vIFJldHVybiBmYWxzZSBhcyBhIGRlZmF1bHRcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICAgcmVsZWFzZVNjcm9sbDogZnVuY3Rpb24gcmVsZWFzZVNjcm9sbChuZXdFdmVudCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsO1xuXG4gICAgICBpZiAobmV3RXZlbnQuZGlyZWN0aW9uIDwgMCkge1xuICAgICAgICBpZiAoc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLmxvb3AgJiYgcGFyYW1zLnJlbGVhc2VPbkVkZ2VzKSB7XG4gICAgICAgICAgLy8gUmV0dXJuIHRydWUgdG8gYW5pbWF0ZSBzY3JvbGwgb24gZWRnZXNcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiBwYXJhbXMucmVsZWFzZU9uRWRnZXMpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRydWUgdG8gYW5pbWF0ZSBzY3JvbGwgb24gZWRnZXNcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuICAgIGVuYWJsZTogZnVuY3Rpb24gZW5hYmxlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgZXZlbnQgPSBNb3VzZXdoZWVsLmV2ZW50KCk7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgc3dpcGVyLndyYXBwZXJFbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBzd2lwZXIubW91c2V3aGVlbC5oYW5kbGUpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFldmVudCkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQpIHJldHVybiBmYWxzZTtcbiAgICAgIHZhciB0YXJnZXQgPSBzd2lwZXIuJGVsO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmV2ZW50c1RhcmdldCAhPT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgICAgdGFyZ2V0ID0gJChzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZXZlbnRzVGFyZ2V0KTtcbiAgICAgIH1cblxuICAgICAgdGFyZ2V0Lm9uKCdtb3VzZWVudGVyJywgc3dpcGVyLm1vdXNld2hlZWwuaGFuZGxlTW91c2VFbnRlcik7XG4gICAgICB0YXJnZXQub24oJ21vdXNlbGVhdmUnLCBzd2lwZXIubW91c2V3aGVlbC5oYW5kbGVNb3VzZUxlYXZlKTtcbiAgICAgIHRhcmdldC5vbihldmVudCwgc3dpcGVyLm1vdXNld2hlZWwuaGFuZGxlKTtcbiAgICAgIHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBkaXNhYmxlOiBmdW5jdGlvbiBkaXNhYmxlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgZXZlbnQgPSBNb3VzZXdoZWVsLmV2ZW50KCk7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgc3dpcGVyLndyYXBwZXJFbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBzd2lwZXIubW91c2V3aGVlbC5oYW5kbGUpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFldmVudCkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKCFzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkKSByZXR1cm4gZmFsc2U7XG4gICAgICB2YXIgdGFyZ2V0ID0gc3dpcGVyLiRlbDtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5ldmVudHNUYXJnZXQgIT09ICdjb250YWluZXInKSB7XG4gICAgICAgIHRhcmdldCA9ICQoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmV2ZW50c1RhcmdldCk7XG4gICAgICB9XG5cbiAgICAgIHRhcmdldC5vZmYoZXZlbnQsIHN3aXBlci5tb3VzZXdoZWVsLmhhbmRsZSk7XG4gICAgICBzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkID0gZmFsc2U7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG4gIHZhciBNb3VzZXdoZWVsJDEgPSB7XG4gICAgbmFtZTogJ21vdXNld2hlZWwnLFxuICAgIHBhcmFtczoge1xuICAgICAgbW91c2V3aGVlbDoge1xuICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgcmVsZWFzZU9uRWRnZXM6IGZhbHNlLFxuICAgICAgICBpbnZlcnQ6IGZhbHNlLFxuICAgICAgICBmb3JjZVRvQXhpczogZmFsc2UsXG4gICAgICAgIHNlbnNpdGl2aXR5OiAxLFxuICAgICAgICBldmVudHNUYXJnZXQ6ICdjb250YWluZXInLFxuICAgICAgICB0aHJlc2hvbGREZWx0YTogbnVsbCxcbiAgICAgICAgdGhyZXNob2xkVGltZTogbnVsbFxuICAgICAgfVxuICAgIH0sXG4gICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGJpbmRNb2R1bGVNZXRob2RzKHN3aXBlciwge1xuICAgICAgICBtb3VzZXdoZWVsOiB7XG4gICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgbGFzdFNjcm9sbFRpbWU6IG5vdygpLFxuICAgICAgICAgIGxhc3RFdmVudEJlZm9yZVNuYXA6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50czogW10sXG4gICAgICAgICAgZW5hYmxlOiBNb3VzZXdoZWVsLmVuYWJsZSxcbiAgICAgICAgICBkaXNhYmxlOiBNb3VzZXdoZWVsLmRpc2FibGUsXG4gICAgICAgICAgaGFuZGxlOiBNb3VzZXdoZWVsLmhhbmRsZSxcbiAgICAgICAgICBoYW5kbGVNb3VzZUVudGVyOiBNb3VzZXdoZWVsLmhhbmRsZU1vdXNlRW50ZXIsXG4gICAgICAgICAgaGFuZGxlTW91c2VMZWF2ZTogTW91c2V3aGVlbC5oYW5kbGVNb3VzZUxlYXZlLFxuICAgICAgICAgIGFuaW1hdGVTbGlkZXI6IE1vdXNld2hlZWwuYW5pbWF0ZVNsaWRlcixcbiAgICAgICAgICByZWxlYXNlU2Nyb2xsOiBNb3VzZXdoZWVsLnJlbGVhc2VTY3JvbGxcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZW5hYmxlZCAmJiBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgICBzd2lwZXIubW91c2V3aGVlbC5kaXNhYmxlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmVuYWJsZWQpIHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZSgpO1xuICAgICAgfSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgICBzd2lwZXIubW91c2V3aGVlbC5lbmFibGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkKSBzd2lwZXIubW91c2V3aGVlbC5kaXNhYmxlKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBOYXZpZ2F0aW9uID0ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgICAgLy8gVXBkYXRlIE5hdmlnYXRpb24gQnV0dG9uc1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uO1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkgcmV0dXJuO1xuICAgICAgdmFyIF9zd2lwZXIkbmF2aWdhdGlvbiA9IHN3aXBlci5uYXZpZ2F0aW9uLFxuICAgICAgICAgICRuZXh0RWwgPSBfc3dpcGVyJG5hdmlnYXRpb24uJG5leHRFbCxcbiAgICAgICAgICAkcHJldkVsID0gX3N3aXBlciRuYXZpZ2F0aW9uLiRwcmV2RWw7XG5cbiAgICAgIGlmICgkcHJldkVsICYmICRwcmV2RWwubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoc3dpcGVyLmlzQmVnaW5uaW5nKSB7XG4gICAgICAgICAgJHByZXZFbC5hZGRDbGFzcyhwYXJhbXMuZGlzYWJsZWRDbGFzcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgJHByZXZFbC5yZW1vdmVDbGFzcyhwYXJhbXMuZGlzYWJsZWRDbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAkcHJldkVsW3N3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10ocGFyYW1zLmxvY2tDbGFzcyk7XG4gICAgICB9XG5cbiAgICAgIGlmICgkbmV4dEVsICYmICRuZXh0RWwubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoc3dpcGVyLmlzRW5kKSB7XG4gICAgICAgICAgJG5leHRFbC5hZGRDbGFzcyhwYXJhbXMuZGlzYWJsZWRDbGFzcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgJG5leHRFbC5yZW1vdmVDbGFzcyhwYXJhbXMuZGlzYWJsZWRDbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAkbmV4dEVsW3N3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10ocGFyYW1zLmxvY2tDbGFzcyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBvblByZXZDbGljazogZnVuY3Rpb24gb25QcmV2Q2xpY2soZSkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoc3dpcGVyLmlzQmVnaW5uaW5nICYmICFzd2lwZXIucGFyYW1zLmxvb3ApIHJldHVybjtcbiAgICAgIHN3aXBlci5zbGlkZVByZXYoKTtcbiAgICB9LFxuICAgIG9uTmV4dENsaWNrOiBmdW5jdGlvbiBvbk5leHRDbGljayhlKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChzd2lwZXIuaXNFbmQgJiYgIXN3aXBlci5wYXJhbXMubG9vcCkgcmV0dXJuO1xuICAgICAgc3dpcGVyLnNsaWRlTmV4dCgpO1xuICAgIH0sXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMubmF2aWdhdGlvbjtcbiAgICAgIGlmICghKHBhcmFtcy5uZXh0RWwgfHwgcGFyYW1zLnByZXZFbCkpIHJldHVybjtcbiAgICAgIHZhciAkbmV4dEVsO1xuICAgICAgdmFyICRwcmV2RWw7XG5cbiAgICAgIGlmIChwYXJhbXMubmV4dEVsKSB7XG4gICAgICAgICRuZXh0RWwgPSAkKHBhcmFtcy5uZXh0RWwpO1xuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnVuaXF1ZU5hdkVsZW1lbnRzICYmIHR5cGVvZiBwYXJhbXMubmV4dEVsID09PSAnc3RyaW5nJyAmJiAkbmV4dEVsLmxlbmd0aCA+IDEgJiYgc3dpcGVyLiRlbC5maW5kKHBhcmFtcy5uZXh0RWwpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICRuZXh0RWwgPSBzd2lwZXIuJGVsLmZpbmQocGFyYW1zLm5leHRFbCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtcy5wcmV2RWwpIHtcbiAgICAgICAgJHByZXZFbCA9ICQocGFyYW1zLnByZXZFbCk7XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMudW5pcXVlTmF2RWxlbWVudHMgJiYgdHlwZW9mIHBhcmFtcy5wcmV2RWwgPT09ICdzdHJpbmcnICYmICRwcmV2RWwubGVuZ3RoID4gMSAmJiBzd2lwZXIuJGVsLmZpbmQocGFyYW1zLnByZXZFbCkubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgJHByZXZFbCA9IHN3aXBlci4kZWwuZmluZChwYXJhbXMucHJldkVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoJG5leHRFbCAmJiAkbmV4dEVsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgJG5leHRFbC5vbignY2xpY2snLCBzd2lwZXIubmF2aWdhdGlvbi5vbk5leHRDbGljayk7XG4gICAgICB9XG5cbiAgICAgIGlmICgkcHJldkVsICYmICRwcmV2RWwubGVuZ3RoID4gMCkge1xuICAgICAgICAkcHJldkVsLm9uKCdjbGljaycsIHN3aXBlci5uYXZpZ2F0aW9uLm9uUHJldkNsaWNrKTtcbiAgICAgIH1cblxuICAgICAgZXh0ZW5kJDEoc3dpcGVyLm5hdmlnYXRpb24sIHtcbiAgICAgICAgJG5leHRFbDogJG5leHRFbCxcbiAgICAgICAgbmV4dEVsOiAkbmV4dEVsICYmICRuZXh0RWxbMF0sXG4gICAgICAgICRwcmV2RWw6ICRwcmV2RWwsXG4gICAgICAgIHByZXZFbDogJHByZXZFbCAmJiAkcHJldkVsWzBdXG4gICAgICB9KTtcbiAgICB9LFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBfc3dpcGVyJG5hdmlnYXRpb24yID0gc3dpcGVyLm5hdmlnYXRpb24sXG4gICAgICAgICAgJG5leHRFbCA9IF9zd2lwZXIkbmF2aWdhdGlvbjIuJG5leHRFbCxcbiAgICAgICAgICAkcHJldkVsID0gX3N3aXBlciRuYXZpZ2F0aW9uMi4kcHJldkVsO1xuXG4gICAgICBpZiAoJG5leHRFbCAmJiAkbmV4dEVsLmxlbmd0aCkge1xuICAgICAgICAkbmV4dEVsLm9mZignY2xpY2snLCBzd2lwZXIubmF2aWdhdGlvbi5vbk5leHRDbGljayk7XG4gICAgICAgICRuZXh0RWwucmVtb3ZlQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmRpc2FibGVkQ2xhc3MpO1xuICAgICAgfVxuXG4gICAgICBpZiAoJHByZXZFbCAmJiAkcHJldkVsLmxlbmd0aCkge1xuICAgICAgICAkcHJldkVsLm9mZignY2xpY2snLCBzd2lwZXIubmF2aWdhdGlvbi5vblByZXZDbGljayk7XG4gICAgICAgICRwcmV2RWwucmVtb3ZlQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmRpc2FibGVkQ2xhc3MpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgdmFyIE5hdmlnYXRpb24kMSA9IHtcbiAgICBuYW1lOiAnbmF2aWdhdGlvbicsXG4gICAgcGFyYW1zOiB7XG4gICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgIG5leHRFbDogbnVsbCxcbiAgICAgICAgcHJldkVsOiBudWxsLFxuICAgICAgICBoaWRlT25DbGljazogZmFsc2UsXG4gICAgICAgIGRpc2FibGVkQ2xhc3M6ICdzd2lwZXItYnV0dG9uLWRpc2FibGVkJyxcbiAgICAgICAgaGlkZGVuQ2xhc3M6ICdzd2lwZXItYnV0dG9uLWhpZGRlbicsXG4gICAgICAgIGxvY2tDbGFzczogJ3N3aXBlci1idXR0b24tbG9jaydcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgbmF2aWdhdGlvbjogX2V4dGVuZHMoe30sIE5hdmlnYXRpb24pXG4gICAgICB9KTtcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBpbml0OiBmdW5jdGlvbiBpbml0KHN3aXBlcikge1xuICAgICAgICBzd2lwZXIubmF2aWdhdGlvbi5pbml0KCk7XG4gICAgICAgIHN3aXBlci5uYXZpZ2F0aW9uLnVwZGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIHRvRWRnZTogZnVuY3Rpb24gdG9FZGdlKHN3aXBlcikge1xuICAgICAgICBzd2lwZXIubmF2aWdhdGlvbi51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICBmcm9tRWRnZTogZnVuY3Rpb24gZnJvbUVkZ2Uoc3dpcGVyKSB7XG4gICAgICAgIHN3aXBlci5uYXZpZ2F0aW9uLnVwZGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koc3dpcGVyKSB7XG4gICAgICAgIHN3aXBlci5uYXZpZ2F0aW9uLmRlc3Ryb3koKTtcbiAgICAgIH0sXG4gICAgICBjbGljazogZnVuY3Rpb24gY2xpY2soc3dpcGVyLCBlKSB7XG4gICAgICAgIHZhciBfc3dpcGVyJG5hdmlnYXRpb24zID0gc3dpcGVyLm5hdmlnYXRpb24sXG4gICAgICAgICAgICAkbmV4dEVsID0gX3N3aXBlciRuYXZpZ2F0aW9uMy4kbmV4dEVsLFxuICAgICAgICAgICAgJHByZXZFbCA9IF9zd2lwZXIkbmF2aWdhdGlvbjMuJHByZXZFbDtcblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGVPbkNsaWNrICYmICEkKGUudGFyZ2V0KS5pcygkcHJldkVsKSAmJiAhJChlLnRhcmdldCkuaXMoJG5leHRFbCkpIHtcbiAgICAgICAgICB2Y
166XIgaXNIaWRkZW47XG5cbiAgICAgICAgICBpZiAoJG5leHRFbCkge1xuICAgICAgICAgICAgaXNIaWRkZW4gPSAkbmV4dEVsLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMubmF2aWdhdGlvbi5oaWRkZW5DbGFzcyk7XG4gICAgICAgICAgfSBlbHNlIGlmICgkcHJldkVsKSB7XG4gICAgICAgICAgICBpc0hpZGRlbiA9ICRwcmV2RWwuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGRlbkNsYXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNIaWRkZW4gPT09IHRydWUpIHtcbiAgICAgICAgICAgIHN3aXBlci5lbWl0KCduYXZpZ2F0aW9uU2hvdycpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzd2lwZXIuZW1pdCgnbmF2aWdhdGlvbkhpZGUnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoJG5leHRFbCkge1xuICAgICAgICAgICAgJG5leHRFbC50b2dnbGVDbGFzcyhzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uaGlkZGVuQ2xhc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICgkcHJldkVsKSB7XG4gICAgICAgICAgICAkcHJldkVsLnRvZ2dsZUNsYXNzKHN3aXBlci5wYXJhbXMubmF2aWdhdGlvbi5oaWRkZW5DbGFzcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBQYWdpbmF0aW9uID0ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgICAgLy8gUmVuZGVyIHx8IFVwZGF0ZSBQYWdpbmF0aW9uIGJ1bGxldHMvaXRlbXNcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHJ0bCA9IHN3aXBlci5ydGw7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uO1xuICAgICAgaWYgKCFwYXJhbXMuZWwgfHwgIXN3aXBlci5wYWdpbmF0aW9uLmVsIHx8ICFzd2lwZXIucGFnaW5hdGlvbi4kZWwgfHwgc3dpcGVyLnBhZ2luYXRpb24uJGVsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdmFyIHNsaWRlc0xlbmd0aCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xuICAgICAgdmFyICRlbCA9IHN3aXBlci5wYWdpbmF0aW9uLiRlbDsgLy8gQ3VycmVudC9Ub3RhbFxuXG4gICAgICB2YXIgY3VycmVudDtcbiAgICAgIHZhciB0b3RhbCA9IHN3aXBlci5wYXJhbXMubG9vcCA/IE1hdGguY2VpbCgoc2xpZGVzTGVuZ3RoIC0gc3dpcGVyLmxvb3BlZFNsaWRlcyAqIDIpIC8gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCkgOiBzd2lwZXIuc25hcEdyaWQubGVuZ3RoO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgIGN1cnJlbnQgPSBNYXRoLmNlaWwoKHN3aXBlci5hY3RpdmVJbmRleCAtIHN3aXBlci5sb29wZWRTbGlkZXMpIC8gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgPiBzbGlkZXNMZW5ndGggLSAxIC0gc3dpcGVyLmxvb3BlZFNsaWRlcyAqIDIpIHtcbiAgICAgICAgICBjdXJyZW50IC09IHNsaWRlc0xlbmd0aCAtIHN3aXBlci5sb29wZWRTbGlkZXMgKiAyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgPiB0b3RhbCAtIDEpIGN1cnJlbnQgLT0gdG90YWw7XG4gICAgICAgIGlmIChjdXJyZW50IDwgMCAmJiBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb25UeXBlICE9PSAnYnVsbGV0cycpIGN1cnJlbnQgPSB0b3RhbCArIGN1cnJlbnQ7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzd2lwZXIuc25hcEluZGV4ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjdXJyZW50ID0gc3dpcGVyLnNuYXBJbmRleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQgPSBzd2lwZXIuYWN0aXZlSW5kZXggfHwgMDtcbiAgICAgIH0gLy8gVHlwZXNcblxuXG4gICAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdidWxsZXRzJyAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMubGVuZ3RoID4gMCkge1xuICAgICAgICB2Y
166XIgYnVsbGV0cyA9IHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHM7XG4gICAgICAgIHZhciBmaXJzdEluZGV4O1xuICAgICAgICB2YXIgbGFzdEluZGV4O1xuICAgICAgICB2YXIgbWlkSW5kZXg7XG5cbiAgICAgICAgaWYgKHBhcmFtcy5keW5hbWljQnVsbGV0cykge1xuICAgICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldFNpemUgPSBidWxsZXRzLmVxKDApW3N3aXBlci5pc0hvcml6b250YWwoKSA/ICdvdXRlcldpZHRoJyA6ICdvdXRlckhlaWdodCddKHRydWUpO1xuICAgICAgICAgICRlbC5jc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3dpZHRoJyA6ICdoZWlnaHQnLCBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRTaXplICogKHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgKyA0KSArIFwicHhcIik7XG5cbiAgICAgICAgICBpZiAocGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyA+IDEgJiYgc3dpcGVyLnByZXZpb3VzSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24uZHluYW1pY0J1bGxldEluZGV4ICs9IGN1cnJlbnQgLSBzd2lwZXIucHJldmlvdXNJbmRleDtcblxuICAgICAgICAgICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uLmR5bmFtaWNCdWxsZXRJbmRleCA+IHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgLSAxKSB7XG4gICAgICAgICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLmR5bmFtaWNCdWxsZXRJbmRleCA9IHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgLSAxO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzd2lwZXIucGFnaW5hdGlvbi5keW5hbWljQnVsbGV0SW5kZXggPCAwKSB7XG4gICAgICAgICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLmR5bmFtaWNCdWxsZXRJbmRleCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmlyc3RJbmRleCA9IGN1cnJlbnQgLSBzd2lwZXIucGFnaW5hdGlvbi5keW5hbWljQnVsbGV0SW5kZXg7XG4gICAgICAgICAgbGFzdEluZGV4ID0gZmlyc3RJbmRleCArIChNYXRoLm1pbihidWxsZXRzLmxlbmd0aCwgcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cykgLSAxKTtcbiAgICAgICAgICBtaWRJbmRleCA9IChsYXN0SW5kZXggKyBmaXJzdEluZGV4KSAvIDI7XG4gICAgICAgIH1cblxuICAgICAgICBidWxsZXRzLnJlbW92ZUNsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiIFwiICsgcGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItbmV4dCBcIiArIHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLW5leHQtbmV4dCBcIiArIHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLXByZXYgXCIgKyBwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1wcmV2LXByZXYgXCIgKyBwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1tYWluXCIpO1xuXG4gICAgICAgIGlmICgkZWwubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGJ1bGxldHMuZWFjaChmdW5jdGlvbiAoYnVsbGV0KSB7XG4gICAgICAgICAgICB2Y
166XIgJGJ1bGxldCA9ICQoYnVsbGV0KTtcbiAgICAgICAgICAgIHZhciBidWxsZXRJbmRleCA9ICRidWxsZXQuaW5kZXgoKTtcblxuICAgICAgICAgICAgaWYgKGJ1bGxldEluZGV4ID09PSBjdXJyZW50KSB7XG4gICAgICAgICAgICAgICRidWxsZXQuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBhcmFtcy5keW5hbWljQnVsbGV0cykge1xuICAgICAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPj0gZmlyc3RJbmRleCAmJiBidWxsZXRJbmRleCA8PSBsYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAkYnVsbGV0LmFkZENsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLW1haW5cIik7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPT09IGZpcnN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAkYnVsbGV0LnByZXYoKS5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1wcmV2XCIpLnByZXYoKS5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1wcmV2LXByZXZcIik7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPT09IGxhc3RJbmRleCkge1xuICAgICAgICAgICAgICAgICRidWxsZXQubmV4dCgpLmFkZENsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLW5leHRcIikubmV4dCgpLmFkZENsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLW5leHQtbmV4dFwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciAkYnVsbGV0ID0gYnVsbGV0cy5lcShjdXJyZW50KTtcbiAgICAgICAgICB2Y
166XIgYnVsbGV0SW5kZXggPSAkYnVsbGV0LmluZGV4KCk7XG4gICAgICAgICAgJGJ1bGxldC5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MpO1xuXG4gICAgICAgICAgaWYgKHBhcmFtcy5keW5hbWljQnVsbGV0cykge1xuICAgICAgICAgICAgdmFyICRmaXJzdERpc3BsYXllZEJ1bGxldCA9IGJ1bGxldHMuZXEoZmlyc3RJbmRleCk7XG4gICAgICAgICAgICB2YXIgJGxhc3REaXNwbGF5ZWRCdWxsZXQgPSBidWxsZXRzLmVxKGxhc3RJbmRleCk7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBmaXJzdEluZGV4OyBpIDw9IGxhc3RJbmRleDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgIGJ1bGxldHMuZXEoaSkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItbWFpblwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPj0gYnVsbGV0cy5sZW5ndGggLSBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzOyBfaSA+PSAwOyBfaSAtPSAxKSB7XG4gICAgICAgICAgICAgICAgICBidWxsZXRzLmVxKGJ1bGxldHMubGVuZ3RoIC0gX2kpLmFkZENsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyArIFwiLW1haW5cIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnVsbGV0cy5lcShidWxsZXRzLmxlbmd0aCAtIHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgLSAxKS5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1wcmV2XCIpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICRmaXJzdERpc3BsYXllZEJ1bGxldC5wcmV2KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItcHJldlwiKS5wcmV2KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItcHJldi1wcmV2XCIpO1xuICAgICAgICAgICAgICAgICRsYXN0RGlzcGxheWVkQnVsbGV0Lm5leHQoKS5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1uZXh0XCIpLm5leHQoKS5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MgKyBcIi1uZXh0LW5leHRcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICRmaXJzdERpc3BsYXllZEJ1bGxldC5wcmV2KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItcHJldlwiKS5wcmV2KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItcHJldi1wcmV2XCIpO1xuICAgICAgICAgICAgICAkbGFzdERpc3BsYXllZEJ1bGxldC5uZXh0KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItbmV4dFwiKS5uZXh0KCkuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzICsgXCItbmV4dC1uZXh0XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMuZHluYW1pY0J1bGxldHMpIHtcbiAgICAgICAgICB2Y
166XIgZHluYW1pY0J1bGxldHNMZW5ndGggPSBNYXRoLm1pbihidWxsZXRzLmxlbmd0aCwgcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyArIDQpO1xuICAgICAgICAgIHZhciBidWxsZXRzT2Zmc2V0ID0gKHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldFNpemUgKiBkeW5hbWljQnVsbGV0c0xlbmd0aCAtIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldFNpemUpIC8gMiAtIG1pZEluZGV4ICogc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0U2l6ZTtcbiAgICAgICAgICB2YXIgb2Zmc2V0UHJvcCA9IHJ0bCA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgICAgICAgYnVsbGV0cy5jc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gb2Zmc2V0UHJvcCA6ICd0b3AnLCBidWxsZXRzT2Zmc2V0ICsgXCJweFwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdmcmFjdGlvbicpIHtcbiAgICAgICAgJGVsLmZpbmQoXCIuXCIgKyBwYXJhbXMuY3VycmVudENsYXNzKS50ZXh0KHBhcmFtcy5mb3JtYXRGcmFjdGlvbkN1cnJlbnQoY3VycmVudCArIDEpKTtcbiAgICAgICAgJGVsLmZpbmQoXCIuXCIgKyBwYXJhbXMudG90YWxDbGFzcykudGV4dChwYXJhbXMuZm9ybWF0RnJhY3Rpb25Ub3RhbCh0b3RhbCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdwcm9ncmVzc2JhcicpIHtcbiAgICAgICAgdmFyIHByb2dyZXNzYmFyRGlyZWN0aW9uO1xuXG4gICAgICAgIGlmIChwYXJhbXMucHJvZ3Jlc3NiYXJPcHBvc2l0ZSkge1xuICAgICAgICAgIHByb2dyZXNzYmFyRGlyZWN0aW9uID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9ncmVzc2JhckRpcmVjdGlvbiA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICdob3Jpem9udGFsJyA6ICd2ZXJ0aWNhbCc7XG4gICAgICAgIH1cblxuICAgICAgICB2Y
166XIgc2NhbGUgPSAoY3VycmVudCArIDEpIC8gdG90YWw7XG4gICAgICAgIHZhciBzY2FsZVggPSAxO1xuICAgICAgICB2YXIgc2NhbGVZID0gMTtcblxuICAgICAgICBpZiAocHJvZ3Jlc3NiYXJEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICAgIHNjYWxlWCA9IHNjYWxlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNjYWxlWSA9IHNjYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgJGVsLmZpbmQoXCIuXCIgKyBwYXJhbXMucHJvZ3Jlc3NiYXJGaWxsQ2xhc3MpLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZVgoXCIgKyBzY2FsZVggKyBcIikgc2NhbGVZKFwiICsgc2NhbGVZICsgXCIpXCIpLnRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2N1c3RvbScgJiYgcGFyYW1zLnJlbmRlckN1c3RvbSkge1xuICAgICAgICAkZWwuaHRtbChwYXJhbXMucmVuZGVyQ3VzdG9tKHN3aXBlciwgY3VycmVudCArIDEsIHRvdGFsKSk7XG4gICAgICAgIHN3aXBlci5lbWl0KCdwYWdpbmF0aW9uUmVuZGVyJywgJGVsWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5lbWl0KCdwYWdpbmF0aW9uVXBkYXRlJywgJGVsWzBdKTtcbiAgICAgIH1cblxuICAgICAgJGVsW3N3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10ocGFyYW1zLmxvY2tDbGFzcyk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIC8vIFJlbmRlciBDb250YWluZXJcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbjtcbiAgICAgIGlmICghcGFyYW1zLmVsIHx8ICFzd2lwZXIucGFnaW5hdGlvbi5lbCB8fCAhc3dpcGVyLnBhZ2luYXRpb24uJGVsIHx8IHN3aXBlci5wYWdpbmF0aW9uLiRlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIHZhciBzbGlkZXNMZW5ndGggPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCA/IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggOiBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcbiAgICAgIHZhciAkZWwgPSBzd2lwZXIucGFnaW5hdGlvbi4kZWw7XG4gICAgICB2Y
166XIgcGFnaW5hdGlvbkhUTUwgPSAnJztcblxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycpIHtcbiAgICAgICAgdmFyIG51bWJlck9mQnVsbGV0cyA9IHN3aXBlci5wYXJhbXMubG9vcCA/IE1hdGguY2VpbCgoc2xpZGVzTGVuZ3RoIC0gc3dpcGVyLmxvb3BlZFNsaWRlcyAqIDIpIC8gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCkgOiBzd2lwZXIuc25hcEdyaWQubGVuZ3RoO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtYmVyT2ZCdWxsZXRzOyBpICs9IDEpIHtcbiAgICAgICAgICBpZiAocGFyYW1zLnJlbmRlckJ1bGxldCkge1xuICAgICAgICAgICAgcGFnaW5hdGlvbkhUTUwgKz0gcGFyYW1zLnJlbmRlckJ1bGxldC5jYWxsKHN3aXBlciwgaSwgcGFyYW1zLmJ1bGxldENsYXNzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFnaW5hdGlvbkhUTUwgKz0gXCI8XCIgKyBwYXJhbXMuYnVsbGV0RWxlbWVudCArIFwiIGNsYXNzPVxcXCJcIiArIHBhcmFtcy5idWxsZXRDbGFzcyArIFwiXFxcIj48L1wiICsgcGFyYW1zLmJ1bGxldEVsZW1lbnQgKyBcIj5cIjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAkZWwuaHRtbChwYWdpbmF0aW9uSFRNTCk7XG4gICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMgPSAkZWwuZmluZChcIi5cIiArIHBhcmFtcy5idWxsZXRDbGFzcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2ZyYWN0aW9uJykge1xuICAgICAgICBpZiAocGFyYW1zLnJlbmRlckZyYWN0aW9uKSB7XG4gICAgICAgICAgcGFnaW5hdGlvbkhUTUwgPSBwYXJhbXMucmVuZGVyRnJhY3Rpb24uY2FsbChzd2lwZXIsIHBhcmFtcy5jdXJyZW50Q2xhc3MsIHBhcmFtcy50b3RhbENsYXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IFwiPHNwYW4gY2xhc3M9XFxcIlwiICsgcGFyYW1zLmN1cnJlbnRDbGFzcyArIFwiXFxcIj48L3NwYW4+XCIgKyAnIC8gJyArIChcIjxzcGFuIGNsYXNzPVxcXCJcIiArIHBhcmFtcy50b3RhbENsYXNzICsgXCJcXFwiPjwvc3Bhbj5cIik7XG4gICAgICAgIH1cblxuICAgICAgICAkZWwuaHRtbChwYWdpbmF0aW9uSFRNTCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ3Byb2dyZXNzYmFyJykge1xuICAgICAgICBpZiAocGFyYW1zLnJlbmRlclByb2dyZXNzYmFyKSB7XG4gICAgICAgICAgcGFnaW5hdGlvbkhUTUwgPSBwYXJhbXMucmVuZGVyUHJvZ3Jlc3NiYXIuY2FsbChzd2lwZXIsIHBhcmFtcy5wcm9ncmVzc2JhckZpbGxDbGFzcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFnaW5hdGlvbkhUTUwgPSBcIjxzcGFuIGNsYXNzPVxcXCJcIiArIHBhcmFtcy5wcm9ncmVzc2JhckZpbGxDbGFzcyArIFwiXFxcIj48L3NwYW4+XCI7XG4gICAgICAgIH1cblxuICAgICAgICAkZWwuaHRtbChwYWdpbmF0aW9uSFRNTCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMudHlwZSAhPT0gJ2N1c3RvbScpIHtcbiAgICAgICAgc3dpcGVyLmVtaXQoJ3BhZ2luYXRpb25SZW5kZXInLCBzd2lwZXIucGFnaW5hdGlvbi4kZWxbMF0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbjtcbiAgICAgIGlmICghcGFyYW1zLmVsKSByZXR1cm47XG4gICAgICB2Y
166XIgJGVsID0gJChwYXJhbXMuZWwpO1xuICAgICAgaWYgKCRlbC5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMudW5pcXVlTmF2RWxlbWVudHMgJiYgdHlwZW9mIHBhcmFtcy5lbCA9PT0gJ3N0cmluZycgJiYgJGVsLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgJGVsID0gc3dpcGVyLiRlbC5maW5kKHBhcmFtcy5lbCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2J1bGxldHMnICYmIHBhcmFtcy5jbGlja2FibGUpIHtcbiAgICAgICAgJGVsLmFkZENsYXNzKHBhcmFtcy5jbGlja2FibGVDbGFzcyk7XG4gICAgICB9XG5cbiAgICAgICRlbC5hZGRDbGFzcyhwYXJhbXMubW9kaWZpZXJDbGFzcyArIHBhcmFtcy50eXBlKTtcblxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycgJiYgcGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XG4gICAgICAgICRlbC5hZGRDbGFzcyhcIlwiICsgcGFyYW1zLm1vZGlmaWVyQ2xhc3MgKyBwYXJhbXMudHlwZSArIFwiLWR5bmFtaWNcIik7XG4gICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLmR5bmFtaWNCdWxsZXRJbmRleCA9IDA7XG5cbiAgICAgICAgaWYgKHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgPCAxKSB7XG4gICAgICAgICAgcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyA9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAncHJvZ3Jlc3NiYXInICYmIHBhcmFtcy5wcm9ncmVzc2Jhck9wcG9zaXRlKSB7XG4gICAgICAgICRlbC5hZGRDbGFzcyhwYXJhbXMucHJvZ3Jlc3NiYXJPcHBvc2l0ZUNsYXNzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtcy5jbGlja2FibGUpIHtcbiAgICAgICAgJGVsLm9uKCdjbGljaycsIFwiLlwiICsgcGFyYW1zLmJ1bGxldENsYXNzLCBmdW5jdGlvbiBvbkNsaWNrKGUpIHtcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdmFyIGluZGV4ID0gJCh0aGlzKS5pbmRleCgpICogc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cDtcbiAgICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSBpbmRleCArPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xuICAgICAgICAgIHN3aXBlci5zbGlkZVRvKGluZGV4KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGV4dGVuZCQxKHN3aXBlci5wYWdpbmF0aW9uLCB7XG4gICAgICAgICRlbDogJGVsLFxuICAgICAgICBlbDogJGVsWzBdXG4gICAgICB9KTtcbiAgICB9LFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XG4gICAgICBpZiAoIXBhcmFtcy5lbCB8fCAhc3dpcGVyLnBhZ2luYXRpb24uZWwgfHwgIXN3aXBlci5wYWdpbmF0aW9uLiRlbCB8fCBzd2lwZXIucGFnaW5hdGlvbi4kZWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICB2YXIgJGVsID0gc3dpcGVyLnBhZ2luYXRpb24uJGVsO1xuICAgICAgJGVsLnJlbW92ZUNsYXNzKHBhcmFtcy5oaWRkZW5DbGFzcyk7XG4gICAgICAkZWwucmVtb3ZlQ2xhc3MocGFyYW1zLm1vZGlmaWVyQ2xhc3MgKyBwYXJhbXMudHlwZSk7XG4gICAgICBpZiAoc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cykgc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cy5yZW1vdmVDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MpO1xuXG4gICAgICBpZiAocGFyYW1zLmNsaWNrYWJsZSkge1xuICAgICAgICAkZWwub2ZmKCdjbGljaycsIFwiLlwiICsgcGFyYW1zLmJ1bGxldENsYXNzKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBQYWdpbmF0aW9uJDEgPSB7XG4gICAgbmFtZTogJ3BhZ2luYXRpb24nLFxuICAgIHBhcmFtczoge1xuICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICBlbDogbnVsbCxcbiAgICAgICAgYnVsbGV0RWxlbWVudDogJ3NwYW4nLFxuICAgICAgICBjbGlja2FibGU6IGZhbHNlLFxuICAgICAgICBoaWRlT25DbGljazogZmFsc2UsXG4gICAgICAgIHJlbmRlckJ1bGxldDogbnVsbCxcbiAgICAgICAgcmVuZGVyUHJvZ3Jlc3NiYXI6IG51bGwsXG4gICAgICAgIHJlbmRlckZyYWN0aW9uOiBudWxsLFxuICAgICAgICByZW5kZXJDdXN0b206IG51bGwsXG4gICAgICAgIHByb2dyZXNzYmFyT3Bwb3NpdGU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYnVsbGV0cycsXG4gICAgICAgIC8vICdidWxsZXRzJyBvciAncHJvZ3Jlc3NiYXInIG9yICdmcmFjdGlvbicgb3IgJ2N1c3RvbSdcbiAgICAgICAgZHluYW1pY0J1bGxldHM6IGZhbHNlLFxuICAgICAgICBkeW5hbWljTWFpbkJ1bGxldHM6IDEsXG4gICAgICAgIGZvcm1hdEZyYWN0aW9uQ3VycmVudDogZnVuY3Rpb24gZm9ybWF0RnJhY3Rpb25DdXJyZW50KG51bWJlcikge1xuICAgICAgICAgIHJldHVybiBudW1iZXI7XG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdEZyYWN0aW9uVG90YWw6IGZ1bmN0aW9uIGZvcm1hdEZyYWN0aW9uVG90YWwobnVtYmVyKSB7XG4gICAgICAgICAgcmV0dXJuIG51bWJlcjtcbiAgICAgICAgfSxcbiAgICAgICAgYnVsbGV0Q2xhc3M6ICdzd2lwZXItcGFnaW5hdGlvbi1idWxsZXQnLFxuICAgICAgICBidWxsZXRBY3RpdmVDbGFzczogJ3N3aXBlci1wYWdpbmF0aW9uLWJ1bGxldC1hY3RpdmUnLFxuICAgICAgICBtb2RpZmllckNsYXNzOiAnc3dpcGVyLXBhZ2luYXRpb24tJyxcbiAgICAgICAgLy8gTkVXXG4gICAgICAgIGN1cnJlbnRDbGFzczogJ3N3aXBlci1wYWdpbmF0aW9uLWN1cnJlbnQnLFxuICAgICAgICB0b3RhbENsYXNzOiAnc3dpcGVyLXBhZ2luYXRpb24tdG90YWwnLFxuICAgICAgICBoaWRkZW5DbGFzczogJ3N3aXBlci1wYWdpbmF0aW9uLWhpZGRlbicsXG4gICAgICAgIHByb2dyZXNzYmFyRmlsbENsYXNzOiAnc3dpcGVyLXBhZ2luYXRpb24tcHJvZ3Jlc3NiYXItZmlsbCcsXG4gICAgICAgIHByb2dyZXNzYmFyT3Bwb3NpdGVDbGFzczogJ3N3aXBlci1wYWdpbmF0aW9uLXByb2dyZXNzYmFyLW9wcG9zaXRlJyxcbiAgICAgICAgY2xpY2thYmxlQ2xhc3M6ICdzd2lwZXItcGFnaW5hdGlvbi1jbGlja2FibGUnLFxuICAgICAgICAvLyBORVdcbiAgICAgICAgbG9ja0NsYXNzOiAnc3dpcGVyLXBhZ2luYXRpb24tbG9jaydcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgcGFnaW5hdGlvbjogX2V4dGVuZHMoe1xuICAgICAgICAgIGR5bmFtaWNCdWxsZXRJbmRleDogMFxuICAgICAgICB9LCBQYWdpbmF0aW9uKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24uaW5pdCgpO1xuICAgICAgICBzd2lwZXIucGFnaW5hdGlvbi5yZW5kZXIoKTtcbiAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24udXBkYXRlKCk7XG4gICAgICB9LFxuICAgICAgYWN0aXZlSW5kZXhDaGFuZ2U6IGZ1bmN0aW9uIGFjdGl2ZUluZGV4Q2hhbmdlKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24udXBkYXRlKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN3aXBlci5zbmFwSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24udXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzbmFwSW5kZXhDaGFuZ2U6IGZ1bmN0aW9uIHNuYXBJbmRleENoYW5nZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgICAgICBzd2lwZXIucGFnaW5hdGlvbi51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNsaWRlc0xlbmd0aENoYW5nZTogZnVuY3Rpb24gc2xpZGVzTGVuZ3RoQ2hhbmdlKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24ucmVuZGVyKCk7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24udXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzbmFwR3JpZExlbmd0aENoYW5nZTogZnVuY3Rpb24gc25hcEdyaWRMZW5ndGhDaGFuZ2Uoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24ucmVuZGVyKCk7XG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24udXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBzd2lwZXIucGFnaW5hdGlvbi5kZXN0cm95KCk7XG4gICAgICB9LFxuICAgICAgY2xpY2s6IGZ1bmN0aW9uIGNsaWNrKHN3aXBlciwgZSkge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmVsICYmIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5oaWRlT25DbGljayAmJiBzd2lwZXIucGFnaW5hdGlvbi4kZWwubGVuZ3RoID4gMCAmJiAhJChlLnRhcmdldCkuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkge1xuICAgICAgICAgIHZhciBpc0hpZGRlbiA9IHN3aXBlci5wYWdpbmF0aW9uLiRlbC5oYXNDbGFzcyhzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uaGlkZGVuQ2xhc3MpO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzd2lwZXIuZW1pdCgncGFnaW5hdGlvblNob3cnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ3BhZ2luYXRpb25IaWRlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24uJGVsLnRvZ2dsZUNsYXNzKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5oaWRkZW5DbGFzcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIFNjcm9sbGJhciA9IHtcbiAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xuICAgICAgdmFyIHNjcm9sbGJhciA9IHN3aXBlci5zY3JvbGxiYXIsXG4gICAgICAgICAgcnRsID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSxcbiAgICAgICAgICBwcm9ncmVzcyA9IHN3aXBlci5wcm9ncmVzcztcbiAgICAgIHZhciBkcmFnU2l6ZSA9IHNjcm9sbGJhci5kcmFnU2l6ZSxcbiAgICAgICAgICB0cmFja1NpemUgPSBzY3JvbGxiYXIudHJhY2tTaXplLFxuICAgICAgICAgICRkcmFnRWwgPSBzY3JvbGxiYXIuJGRyYWdFbCxcbiAgICAgICAgICAkZWwgPSBzY3JvbGxiYXIuJGVsO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyO1xuICAgICAgdmFyIG5ld1NpemUgPSBkcmFnU2l6ZTtcbiAgICAgIHZhciBuZXdQb3MgPSAodHJhY2tTaXplIC0gZHJhZ1NpemUpICogcHJvZ3Jlc3M7XG5cbiAgICAgIGlmIChydGwpIHtcbiAgICAgICAgbmV3UG9zID0gLW5ld1BvcztcblxuICAgICAgICBpZiAobmV3UG9zID4gMCkge1xuICAgICAgICAgIG5ld1NpemUgPSBkcmFnU2l6ZSAtIG5ld1BvcztcbiAgICAgICAgICBuZXdQb3MgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKC1uZXdQb3MgKyBkcmFnU2l6ZSA+IHRyYWNrU2l6ZSkge1xuICAgICAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgKyBuZXdQb3M7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobmV3UG9zIDwgMCkge1xuICAgICAgICBuZXdTaXplID0gZHJhZ1NpemUgKyBuZXdQb3M7XG4gICAgICAgIG5ld1BvcyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKG5ld1BvcyArIGRyYWdTaXplID4gdHJhY2tTaXplKSB7XG4gICAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgLSBuZXdQb3M7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgJGRyYWdFbC50cmFuc2Zvcm0oXCJ0cmFuc2xhdGUzZChcIiArIG5ld1BvcyArIFwicHgsIDAsIDApXCIpO1xuICAgICAgICAkZHJhZ0VsWzBdLnN0eWxlLndpZHRoID0gbmV3U2l6ZSArIFwicHhcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICRkcmFnRWwudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoMHB4LCBcIiArIG5ld1BvcyArIFwicHgsIDApXCIpO1xuICAgICAgICAkZHJhZ0VsWzBdLnN0eWxlLmhlaWdodCA9IG5ld1NpemUgKyBcInB4XCI7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMuaGlkZSkge1xuICAgICAgICBjbGVhclRpbWVvdXQoc3dpcGVyLnNjcm9sbGJhci50aW1lb3V0KTtcbiAgICAgICAgJGVsWzBdLnN0eWxlLm9wYWNpdHkgPSAxO1xuICAgICAgICBzd2lwZXIuc2Nyb2xsYmFyLnRpbWVvdXQgP
166SBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAkZWxbMF0uc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgICAgICAgJGVsLnRyYW5zaXRpb24oNDAwKTtcbiAgICAgICAgfSwgMTAwMCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzZXRUcmFuc2l0aW9uOiBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwgfHwgIXN3aXBlci5zY3JvbGxiYXIuZWwpIHJldHVybjtcbiAgICAgIHN3aXBlci5zY3JvbGxiYXIuJGRyYWdFbC50cmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICB9LFxuICAgIHVwZGF0ZVNpemU6IGZ1bmN0aW9uIHVwZGF0ZVNpemUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwgfHwgIXN3aXBlci5zY3JvbGxiYXIuZWwpIHJldHVybjtcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyO1xuICAgICAgdmFyICRkcmFnRWwgPSBzY3JvbGxiYXIuJGRyYWdFbCxcbiAgICAgICAgICAkZWwgPSBzY3JvbGxiYXIuJGVsO1xuICAgICAgJGRyYWdFbFswXS5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgJGRyYWdFbFswXS5zdHlsZS5oZWlnaHQgPSAnJztcbiAgICAgIHZhciB0cmFja1NpemUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAkZWxbMF0ub2Zmc2V0V2lkdGggOiAkZWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgdmFyIGRpdmlkZXIgPSBzd2lwZXIuc2l6ZSAvIHN3aXBlci52aXJ0dWFsU2l6ZTtcbiAgICAgIHZhciBtb3ZlRGl2aWRlciA9IGRpdmlkZXIgKiAodHJhY2tTaXplIC8gc3dpcGVyLnNpemUpO1xuICAgICAgdmFyIGRyYWdTaXplO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZHJhZ1NpemUgPT09ICdhdXRvJykge1xuICAgICAgICBkcmFnU2l6ZSA9IHRyYWNrU2l6ZSAqIGRpdmlkZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcmFnU2l6ZSA9IHBhcnNlSW50KHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmRyYWdTaXplLCAxMCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgJGRyYWdFbFswXS5zdHlsZS53aWR0aCA9IGRyYWdTaXplICsgXCJweFwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJGRyYWdFbFswXS5zdHlsZS5oZWlnaHQgPSBkcmFnU2l6ZSArIFwicHhcIjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpdmlkZXIgPj0gMSkge1xuICAgICAgICAkZWxbMF0uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICRlbFswXS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5oaWRlKSB7XG4gICAgICAgICRlbFswXS5zdHlsZS5vcGFjaXR5ID0gMDtcbiAgICAgIH1cblxuICAgICAgZXh0ZW5kJDEoc2Nyb2xsYmFyLCB7XG4gICAgICAgIHRyYWNrU2l6ZTogdHJhY2tTaXplLFxuICAgICAgICBkaXZpZGVyOiBkaXZpZGVyLFxuICAgICAgICBtb3ZlRGl2aWRlcjogbW92ZURpdmlkZXIsXG4gICAgICAgIGRyYWdTaXplOiBkcmFnU2l6ZVxuICAgICAgfSk7XG4gICAgICBzY3JvbGxiYXIuJGVsW3N3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10oc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIubG9ja0NsYXNzKTtcbiAgICB9LFxuICAgIGdldFBvaW50ZXJQb3NpdGlvbjogZnVuY3Rpb24gZ2V0UG9pbnRlclBvc2l0aW9uKGUpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuXG4gICAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgIHJldHVybiBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyB8fCBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFggOiBlLmNsaWVudFg7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyB8fCBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFkgOiBlLmNsaWVudFk7XG4gICAgfSxcbiAgICBzZXREcmFnUG9zaXRpb246IGZ1bmN0aW9uIHNldERyYWdQb3NpdGlvbihlKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyLFxuICAgICAgICAgIHJ0bCA9IHN3aXBlci5ydGxUcmFuc2xhdGU7XG4gICAgICB2YXIgJGVsID0gc2Nyb2xsYmFyLiRlbCxcbiAgICAgICAgICBkcmFnU2l6ZSA9IHNjcm9sbGJhci5kcmFnU2l6ZSxcbiAgICAgICAgICB0cmFja1NpemUgPSBzY3JvbGxiYXIudHJhY2tTaXplLFxuICAgICAgICAgIGRyYWdTdGFydFBvcyA9IHNjcm9sbGJhci5kcmFnU3RhcnRQb3M7XG4gICAgICB2YXIgcG9zaXRpb25SYXRpbztcbiAgICAgIHBvc2l0aW9uUmF0aW8gPSAoc2Nyb2xsYmFyLmdldFBvaW50ZXJQb3NpdGlvbihlKSAtICRlbC5vZmZzZXQoKVtzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnbGVmdCcgOiAndG9wJ10gLSAoZHJhZ1N0YXJ0UG9zICE9PSBudWxsID8gZHJhZ1N0YXJ0UG9zIDogZHJhZ1NpemUgLyAyKSkgLyAodHJhY2tTaXplIC0gZHJhZ1NpemUpO1xuICAgICAgcG9zaXRpb25SYXRpbyA9IE1hdGgubWF4KE1hdGgubWluKHBvc2l0aW9uUmF0aW8sIDEpLCAwKTtcblxuICAgICAgaWYgKHJ0bCkge1xuICAgICAgICBwb3NpdGlvblJhdGlvID0gMSAtIHBvc2l0aW9uUmF0aW87XG4gICAgICB9XG5cbiAgICAgIHZhciBwb3NpdGlvbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKSArIChzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpICogcG9zaXRpb25SYXRpbztcbiAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhwb3NpdGlvbik7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHBvc2l0aW9uKTtcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICB9LFxuICAgIG9uRHJhZ1N0YXJ0OiBmdW5jdGlvbiBvbkRyYWdTdGFydChlKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyLFxuICAgICAgICAgICR3cmFwcGVyRWwgPSBzd2lwZXIuJHdyYXBwZXJFbDtcbiAgICAgIHZhciAkZWwgPSBzY3JvbGxiYXIuJGVsLFxuICAgICAgICAgICRkcmFnRWwgPSBzY3JvbGxiYXIuJGRyYWdFbDtcbiAgICAgIHN3aXBlci5zY3JvbGxiYXIuaXNUb3VjaGVkID0gdHJ1ZTtcbiAgICAgIHN3aXBlci5zY3JvbGxiYXIuZHJhZ1N0YXJ0UG9zID0gZS50YXJnZXQgPT09ICRkcmFnRWxbMF0gfHwgZS50YXJnZXQgPT09ICRkcmFnRWwgPyBzY3JvbGxiYXIuZ2V0UG9pbnRlclBvc2l0aW9uKGUpIC0gZS50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ2xlZnQnIDogJ3RvcCddIDogbnVsbDtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAkd3JhcHBlckVsLnRyYW5zaXRpb24oMTAwKTtcbiAgICAgICRkcmFnRWwudHJhbnNpdGlvbigxMDApO1xuICAgICAgc2Nyb2xsYmFyLnNldERyYWdQb3NpdGlvbihlKTtcbiAgICAgIGNsZWFyVGltZW91dChzd2lwZXIuc2Nyb2xsYmFyLmRyYWdUaW1lb3V0KTtcbiAgICAgICRlbC50cmFuc2l0aW9uKDApO1xuXG4gICAgICBpZiAocGFyYW1zLmhpZGUpIHtcbiAgICAgICAgJGVsLmNzcygnb3BhY2l0eScsIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLmNzcygnc2Nyb2xsLXNuYXAtdHlwZScsICdub25lJyk7XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci5lbWl0KCdzY3JvbGxiYXJEcmFnU3RhcnQnLCBlKTtcbiAgICB9LFxuICAgIG9uRHJhZ01vdmU6IGZ1bmN0aW9uIG9uRHJhZ01vdmUoZSkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgc2Nyb2xsYmFyID0gc3dpcGVyLnNjcm9sbGJhcixcbiAgICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWw7XG4gICAgICB2YXIgJGVsID0gc2Nyb2xsYmFyLiRlbCxcbiAgICAgICAgICAkZHJhZ0VsID0gc2Nyb2xsYmFyLiRkcmFnRWw7XG4gICAgICBpZiAoIXN3aXBlci5zY3JvbGxiYXIuaXNUb3VjaGVkKSByZXR1cm47XG4gICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO2Vsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgc2Nyb2xsYmFyLnNldERyYWdQb3NpdGlvbihlKTtcbiAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbigwKTtcbiAgICAgICRlbC50cmFuc2l0aW9uKDApO1xuICAgICAgJGRyYWdFbC50cmFuc2l0aW9uKDApO1xuICAgICAgc3dpcGVyLmVtaXQoJ3Njcm9sbGJhckRyYWdNb3ZlJywgZSk7XG4gICAgfSxcbiAgICBvbkRyYWdFbmQ6IGZ1bmN0aW9uIG9uRHJhZ0VuZChlKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyLFxuICAgICAgICAgICR3cmFwcGVyRWwgPSBzd2lwZXIuJHdyYXBwZXJFbDtcbiAgICAgIHZhciAkZWwgPSBzY3JvbGxiYXIuJGVsO1xuICAgICAgaWYgKCFzd2lwZXIuc2Nyb2xsYmFyLmlzVG91Y2hlZCkgcmV0dXJuO1xuICAgICAgc3dpcGVyLnNjcm9sbGJhci5pc1RvdWNoZWQgPSBmYWxzZTtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC5jc3MoJ3Njcm9sbC1zbmFwLXR5cGUnLCAnJyk7XG4gICAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbignJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMuaGlkZSkge1xuICAgICAgICBjbGVhclRpbWVvdXQoc3dpcGVyLnNjcm9sbGJhci5kcmFnVGltZW91dCk7XG4gICAgICAgIHN3aXBlci5zY3JvbGxiYXIuZHJhZ1RpbWVvdXQgPSBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgJGVsLmNzcygnb3BhY2l0eScsIDApO1xuICAgICAgICAgICRlbC50cmFuc2l0aW9uKDQwMCk7XG4gICAgICAgIH0sIDEwMDApO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuZW1pdCgnc2Nyb2xsYmFyRHJhZ0VuZCcsIGUpO1xuXG4gICAgICBpZiAocGFyYW1zLnNuYXBPblJlbGVhc2UpIHtcbiAgICAgICAgc3dpcGVyLnNsaWRlVG9DbG9zZXN0KCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBlbmFibGVEcmFnZ2FibGU6IGZ1bmN0aW9uIGVuYWJsZURyYWdnYWJsZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xuICAgICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyLFxuICAgICAgICAgIHRvdWNoRXZlbnRzVG91Y2ggPSBzd2lwZXIudG91Y2hFdmVudHNUb3VjaCxcbiAgICAgICAgICB0b3VjaEV2ZW50c0Rlc2t0b3AgPSBzd2lwZXIudG91Y2hFdmVudHNEZXNrdG9wLFxuICAgICAgICAgIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMsXG4gICAgICAgICAgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgICAgdmFyICRlbCA9IHNjcm9sbGJhci4kZWw7XG4gICAgICB2Y
166XIgdGFyZ2V0ID0gJGVsWzBdO1xuICAgICAgdmFyIGFjdGl2ZUxpc3RlbmVyID0gc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnMgPyB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgICBjYXB0dXJlOiBmYWxzZVxuICAgICAgfSA6IGZhbHNlO1xuICAgICAgdmFyIHBhc3NpdmVMaXN0ZW5lciA9IHN1cHBvcnQucGFzc2l2ZUxpc3RlbmVyICYmIHBhcmFtcy5wYXNzaXZlTGlzdGVuZXJzID8ge1xuICAgICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgICBjYXB0dXJlOiBmYWxzZVxuICAgICAgfSA6IGZhbHNlO1xuXG4gICAgICBpZiAoIXN1cHBvcnQudG91Y2gpIHtcbiAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHNEZXNrdG9wLnN0YXJ0LCBzd2lwZXIuc2Nyb2xsYmFyLm9uRHJhZ1N0YXJ0LCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHNEZXNrdG9wLm1vdmUsIHN3aXBlci5zY3JvbGxiYXIub25EcmFnTW92ZSwgYWN0aXZlTGlzdGVuZXIpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzRGVza3RvcC5lbmQsIHN3aXBlci5zY3JvbGxiYXIub25EcmFnRW5kLCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHNUb3VjaC5zdGFydCwgc3dpcGVyLnNjcm9sbGJhci5vbkRyYWdTdGFydCwgYWN0aXZlTGlzdGVuZXIpO1xuICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50c1RvdWNoLm1vdmUsIHN3aXBlci5zY3JvbGxiYXIub25EcmFnTW92ZSwgYWN0aXZlTGlzdGVuZXIpO1xuICAgICAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50c1RvdWNoLmVuZCwgc3dpcGVyLnNjcm9sbGJhci5vbkRyYWdFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNhYmxlRHJhZ2dhYmxlOiBmdW5jdGlvbiBkaXNhYmxlRHJhZ2dhYmxlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBpZiAoIXN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmVsKSByZXR1cm47XG4gICAgICB2Y
166XIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgdmFyIHNjcm9sbGJhciA9IHN3aXBlci5zY3JvbGxiYXIsXG4gICAgICAgICAgdG91Y2hFdmVudHNUb3VjaCA9IHN3aXBlci50b3VjaEV2ZW50c1RvdWNoLFxuICAgICAgICAgIHRvdWNoRXZlbnRzRGVza3RvcCA9IHN3aXBlci50b3VjaEV2ZW50c0Rlc2t0b3AsXG4gICAgICAgICAgcGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgICBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgICB2YXIgJGVsID0gc2Nyb2xsYmFyLiRlbDtcbiAgICAgIHZhciB0YXJnZXQgPSAkZWxbMF07XG4gICAgICB2YXIgYWN0aXZlTGlzdGVuZXIgPSBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciAmJiBwYXJhbXMucGFzc2l2ZUxpc3RlbmVycyA/IHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICAgIGNhcHR1cmU6IGZhbHNlXG4gICAgICB9IDogZmFsc2U7XG4gICAgICB2YXIgcGFzc2l2ZUxpc3RlbmVyID0gc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnMgPyB7XG4gICAgICAgIHBhc3NpdmU6IHRydWUsXG4gICAgICAgIGNhcHR1cmU6IGZhbHNlXG4gICAgICB9IDogZmFsc2U7XG5cbiAgICAgIGlmICghc3VwcG9ydC50b3VjaCkge1xuICAgICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50c0Rlc2t0b3Auc3RhcnQsIHN3aXBlci5zY3JvbGxiYXIub25EcmFnU3RhcnQsIGFjdGl2ZUxpc3RlbmVyKTtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50c0Rlc2t0b3AubW92ZSwgc3dpcGVyLnNjcm9sbGJhci5vbkRyYWdNb3ZlLCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodG91Y2hFdmVudHNEZXNrdG9wLmVuZCwgc3dpcGVyLnNjcm9sbGJhci5vbkRyYWdFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaEV2ZW50c1RvdWNoLnN0YXJ0LCBzd2lwZXIuc2Nyb2xsYmFyLm9uRHJhZ1N0YXJ0LCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzVG91Y2gubW92ZSwgc3dpcGVyLnNjcm9sbGJhci5vbkRyYWdNb3ZlLCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoRXZlbnRzVG91Y2guZW5kLCBzd2lwZXIuc2Nyb2xsYmFyLm9uRHJhZ0VuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwpIHJldHVybjtcbiAgICAgIHZhciBzY3JvbGxiYXIgPSBzd2lwZXIuc2Nyb2xsYmFyLFxuICAgICAgICAgICRzd2lwZXJFbCA9IHN3aXBlci4kZWw7XG4gICAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXI7XG4gICAgICB2YXIgJGVsID0gJChwYXJhbXMuZWwpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy51bmlxdWVOYXZFbGVtZW50cyAmJiB0eXBlb2YgcGFyYW1zLmVsID09PSAnc3RyaW5nJyAmJiAkZWwubGVuZ3RoID4gMSAmJiAkc3dpcGVyRWwuZmluZChwYXJhbXMuZWwpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAkZWwgPSAkc3dpcGVyRWwuZmluZChwYXJhbXMuZWwpO1xuICAgICAgfVxuXG4gICAgICB2YXIgJGRyYWdFbCA9ICRlbC5maW5kKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZHJhZ0NsYXNzKTtcblxuICAgICAgaWYgKCRkcmFnRWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICRkcmFnRWwgPSAkKFwiPGRpdiBjbGFzcz1cXFwiXCIgKyBzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnQ2xhc3MgKyBcIlxcXCI+PC9kaXY+XCIpO1xuICAgICAgICAkZWwuYXBwZW5kKCRkcmFnRWwpO1xuICAgICAgfVxuXG4gICAgICBleHRlbmQkMShzY3JvbGxiYXIsIHtcbiAgICAgICAgJGVsOiAkZWwsXG4gICAgICAgIGVsOiAkZWxbMF0sXG4gICAgICAgICRkcmFnRWw6ICRkcmFnRWwsXG4gICAgICAgIGRyYWdFbDogJGRyYWdFbFswXVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwYXJhbXMuZHJhZ2dhYmxlKSB7XG4gICAgICAgIHNjcm9sbGJhci5lbmFibGVEcmFnZ2FibGUoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHN3aXBlci5zY3JvbGxiYXIuZGlzYWJsZURyYWdnYWJsZSgpO1xuICAgIH1cbiAgfTtcbiAgdmFyIFNjcm9sbGJhciQxID0ge1xuICAgIG5hbWU6ICdzY3JvbGxiYXInLFxuICAgIHBhcmFtczoge1xuICAgICAgc2Nyb2xsYmFyOiB7XG4gICAgICAgIGVsOiBudWxsLFxuICAgICAgICBkcmFnU2l6ZTogJ2F1dG8nLFxuICAgICAgICBoaWRlOiBmYWxzZSxcbiAgICAgICAgZHJhZ2dhYmxlOiBmYWxzZSxcbiAgICAgICAgc25hcE9uUmVsZWFzZTogdHJ1ZSxcbiAgICAgICAgbG9ja0NsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1sb2NrJyxcbiAgICAgICAgZHJhZ0NsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1kcmFnJ1xuICAgICAgfVxuICAgIH0sXG4gICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGJpbmRNb2R1bGVNZXRob2RzKHN3aXBlciwge1xuICAgICAgICBzY3JvbGxiYXI6IF9leHRlbmRzKHtcbiAgICAgICAgICBpc1RvdWNoZWQ6IGZhbHNlLFxuICAgICAgICAgIHRpbWVvdXQ6IG51bGwsXG4gICAgICAgICAgZHJhZ1RpbWVvdXQ6IG51bGxcbiAgICAgICAgfSwgU2Nyb2xsYmFyKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIpIHtcbiAgICAgICAgc3dpcGVyLnNjcm9sbGJhci5pbml0KCk7XG4gICAgICAgIHN3aXBlci5zY3JvbGxiYXIudXBkYXRlU2l6ZSgpO1xuICAgICAgICBzd2lwZXIuc2Nyb2xsYmFyLnNldFRyYW5zbGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKHN3aXBlcikge1xuICAgICAgICBzd2lwZXIuc2Nyb2xsYmFyLnVwZGF0ZVNpemUoKTtcbiAgICAgIH0sXG4gICAgICByZXNpemU6IGZ1bmN0aW9uIHJlc2l6ZShzd2lwZXIpIHtcbiAgICAgICAgc3dpcGVyLnNjcm9sbGJhci51cGRhdGVTaXplKCk7XG4gICAgICB9LFxuICAgICAgb2JzZXJ2ZXJVcGRhdGU6IGZ1bmN0aW9uIG9ic2VydmVyVXBkYXRlKHN3aXBlcikge1xuICAgICAgICBzd2lwZXIuc2Nyb2xsYmFyLnVwZGF0ZVNpemUoKTtcbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZShzd2lwZXIpIHtcbiAgICAgICAgc3dpcGVyLnNjcm9sbGJhci5zZXRUcmFuc2xhdGUoKTtcbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2l0aW9uOiBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKHN3aXBlciwgZHVyYXRpb24pIHtcbiAgICAgICAgc3dpcGVyLnNjcm9sbGJhci5zZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBzd2lwZXIuc2Nyb2xsYmFyLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIFBhcmFsbGF4ID0ge1xuICAgIHNldFRyYW5zZm9ybTogZnVuY3Rpb24gc2V0VHJhbnNmb3JtKGVsLCBwcm9ncmVzcykge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgcnRsID0gc3dpcGVyLnJ0bDtcbiAgICAgIHZhciAkZWwgPSAkKGVsKTtcbiAgICAgIHZhciBydGxGYWN0b3IgPSBydGwgPyAtMSA6IDE7XG4gICAgICB2YXIgcCA9ICRlbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheCcpIHx8ICcwJztcbiAgICAgIHZhciB4ID0gJGVsLmF0dHIoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LXgnKTtcbiAgICAgIHZhciB5ID0gJGVsLmF0dHIoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LXknKTtcbiAgICAgIHZhciBzY2FsZSA9ICRlbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheC1zY2FsZScpO1xuICAgICAgdmFyIG9wYWNpdHkgPSAkZWwuYXR0cignZGF0YS1zd2lwZXItcGFyYWxsYXgtb3BhY2l0eScpO1xuXG4gICAgICBpZiAoeCB8fCB5KSB7XG4gICAgICAgIHggPSB4IHx8ICcwJztcbiAgICAgICAgeSA9IHkgfHwgJzAnO1xuICAgICAgfSBlbHNlIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgeCA9IHA7XG4gICAgICAgIHkgPSAnMCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB5ID0gcDtcbiAgICAgICAgeCA9ICcwJztcbiAgICAgIH1cblxuICAgICAgaWYgKHguaW5kZXhPZignJScpID49IDApIHtcbiAgICAgICAgeCA9IHBhcnNlSW50KHgsIDEwKSAqIHByb2dyZXNzICogcnRsRmFjdG9yICsgXCIlXCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4ID0geCAqIHByb2dyZXNzICogcnRsRmFjdG9yICsgXCJweFwiO1xuICAgICAgfVxuXG4gICAgICBpZiAoeS5pbmRleE9mKCclJykgPj0gMCkge1xuICAgICAgICB5ID0gcGFyc2VJbnQoeSwgMTApICogcHJvZ3Jlc3MgKyBcIiVcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHkgPSB5ICogcHJvZ3Jlc3MgKyBcInB4XCI7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2Ygb3BhY2l0eSAhPT0gJ3VuZGVmaW5lZCcgJiYgb3BhY2l0eSAhPT0gbnVsbCkge1xuICAgICAgICB2Y
166XIgY3VycmVudE9wYWNpdHkgPSBvcGFjaXR5IC0gKG9wYWNpdHkgLSAxKSAqICgxIC0gTWF0aC5hYnMocHJvZ3Jlc3MpKTtcbiAgICAgICAgJGVsWzBdLnN0eWxlLm9wYWNpdHkgPSBjdXJyZW50T3BhY2l0eTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBzY2FsZSA9PT0gJ3VuZGVmaW5lZCcgfHwgc2NhbGUgPT09IG51bGwpIHtcbiAgICAgICAgJGVsLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKFwiICsgeCArIFwiLCBcIiArIHkgKyBcIiwgMHB4KVwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBjdXJyZW50U2NhbGUgPSBzY2FsZSAtIChzY2FsZSAtIDEpICogKDEgLSBNYXRoLmFicyhwcm9ncmVzcykpO1xuICAgICAgICAkZWwudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCIsIFwiICsgeSArIFwiLCAwcHgpIHNjYWxlKFwiICsgY3VycmVudFNjYWxlICsgXCIpXCIpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2V0VHJhbnNsYXRlOiBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciAkZWwgPSBzd2lwZXIuJGVsLFxuICAgICAgICAgIHNsaWRlcyA9IHN3aXBlci5zbGlkZXMsXG4gICAgICAgICAgcHJvZ3Jlc3MgPSBzd2lwZXIucHJvZ3Jlc3MsXG4gICAgICAgICAgc25hcEdyaWQgPSBzd2lwZXIuc25hcEdyaWQ7XG4gICAgICAkZWwuY2hpbGRyZW4oJ1tkYXRhLXN3aXBlci1wYXJhbGxheF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC14XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LXldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtb3BhY2l0eV0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC1zY2FsZV0nKS5lYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICBzd2lwZXIucGFyYWxsYXguc2V0VHJhbnNmb3JtKGVsLCBwcm9ncmVzcyk7XG4gICAgICB9KTtcbiAgICAgIHNsaWRlcy5lYWNoKGZ1bmN0aW9uIChzbGlkZUVsLCBzbGlkZUluZGV4KSB7XG4gICAgICAgIHZhciBzbGlkZVByb2dyZXNzID0gc2xpZGVFbC5wcm9ncmVzcztcblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA+IDEgJiYgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSAnYXV0bycpIHtcbiAgICAgICAgICBzbGlkZVByb2dyZXNzICs9IE1hdGguY2VpbChzbGlkZUluZGV4IC8gMikgLSBwcm9ncmVzcyAqIChzbmFwR3JpZC5sZW5ndGggLSAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNsaWRlUHJvZ3Jlc3MgPSBNYXRoLm1pbihNYXRoLm1heChzbGlkZVByb2dyZXNzLCAtMSksIDEpO1xuICAgICAgICAkKHNsaWRlRWwpLmZpbmQoJ1tkYXRhLXN3aXBlci1wYXJhbGxheF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC14XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LXldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtb3BhY2l0eV0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC1zY2FsZV0nKS5lYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgIHN3aXBlci5wYXJhbGxheC5zZXRUcmFuc2Zvcm0oZWwsIHNsaWRlUHJvZ3Jlc3MpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihkdXJhdGlvbikge1xuICAgICAgaWYgKGR1cmF0aW9uID09PSB2b2lkIDApIHtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnBhcmFtcy5zcGVlZDtcbiAgICAgIH1cblxuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgJGVsID0gc3dpcGVyLiRlbDtcbiAgICAgICRlbC5maW5kKCdbZGF0YS1zd2lwZXItcGFyYWxsYXhdLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgteF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC15XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LW9wYWNpdHldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtc2NhbGVdJykuZWFjaChmdW5jdGlvbiAocGFyYWxsYXhFbCkge1xuICAgICAgICB2YXIgJHBhcmFsbGF4RWwgPSAkKHBhcmFsbGF4RWwpO1xuICAgICAgICB2YXIgcGFyYWxsYXhEdXJhdGlvbiA9IHBhcnNlSW50KCRwYXJhbGxheEVsLmF0dHIoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LWR1cmF0aW9uJyksIDEwKSB8fCBkdXJhdGlvbjtcbiAgICAgICAgaWYgKGR1cmF0aW9uID09PSAwKSBwYXJhbGxheER1cmF0aW9uID0gMDtcbiAgICAgICAgJHBhcmFsbGF4RWwudHJhbnNpdGlvbihwYXJhbGxheER1cmF0aW9uKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgdmFyIFBhcmFsbGF4JDEgPSB7XG4gICAgbmFtZTogJ3BhcmFsbGF4JyxcbiAgICBwYXJhbXM6IHtcbiAgICAgIHBhcmFsbGF4OiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIHBhcmFsbGF4OiBfZXh0ZW5kcyh7fSwgUGFyYWxsYXgpXG4gICAgICB9KTtcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBiZWZvcmVJbml0OiBmdW5jdGlvbiBiZWZvcmVJbml0KHN3aXBlcikge1xuICAgICAgICBpZiAoIXN3aXBlci5wYXJhbXMucGFyYWxsYXguZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIucGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyA9IHRydWU7XG4gICAgICB9LFxuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhcmFsbGF4LmVuYWJsZWQpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLnBhcmFsbGF4LnNldFRyYW5zbGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIHNldFRyYW5zbGF0ZTogZnVuY3Rpb24gc2V0VHJhbnNsYXRlKHN3aXBlcikge1xuICAgICAgICBpZiAoIXN3aXBlci5wYXJhbXMucGFyYWxsYXguZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIucGFyYWxsYXguc2V0VHJhbnNsYXRlKCk7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihzd2lwZXIsIGR1cmF0aW9uKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5wYXJhbGxheC5lbmFibGVkKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5wYXJhbGxheC5zZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIFpvb20gPSB7XG4gICAgLy8gQ2FsYyBTY2FsZSBGcm9tIE11bHRpLXRvdWNoZXNcbiAgICBnZXREaXN0YW5jZUJldHdlZW5Ub3VjaGVzOiBmdW5jdGlvbiBnZXREaXN0YW5jZUJldHdlZW5Ub3VjaGVzKGUpIHtcbiAgICAgIGlmIChlLnRhcmdldFRvdWNoZXMubGVuZ3RoIDwgMikgcmV0dXJuIDE7XG4gICAgICB2YXIgeDEgPSBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVg7XG4gICAgICB2YXIgeTEgPSBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVk7XG4gICAgICB2YXIgeDIgPSBlLnRhcmdldFRvdWNoZXNbMV0ucGFnZVg7XG4gICAgICB2YXIgeTIgPSBlLnRhcmdldFRvdWNoZXNbMV0ucGFnZVk7XG4gICAgICB2Y
166XIgZGlzdGFuY2UgPSBNYXRoLnNxcnQoTWF0aC5wb3coeDIgLSB4MSwgMikgKyBNYXRoLnBvdyh5MiAtIHkxLCAyKSk7XG4gICAgICByZXR1cm4gZGlzdGFuY2U7XG4gICAgfSxcbiAgICAvLyBFdmVudHNcbiAgICBvbkdlc3R1cmVTdGFydDogZnVuY3Rpb24gb25HZXN0dXJlU3RhcnQoZSkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgZ2VzdHVyZSA9IHpvb20uZ2VzdHVyZTtcbiAgICAgIHpvb20uZmFrZUdlc3R1cmVUb3VjaGVkID0gZmFsc2U7XG4gICAgICB6b29tLmZha2VHZXN0dXJlTW92ZWQgPSBmYWxzZTtcblxuICAgICAgaWYgKCFzdXBwb3J0Lmdlc3R1cmVzKSB7XG4gICAgICAgIGlmIChlLnR5cGUgIT09ICd0b3VjaHN0YXJ0JyB8fCBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyAmJiBlLnRhcmdldFRvdWNoZXMubGVuZ3RoIDwgMikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHpvb20uZmFrZUdlc3R1cmVUb3VjaGVkID0gdHJ1ZTtcbiAgICAgICAgZ2VzdHVyZS5zY2FsZVN0YXJ0ID0gWm9vbS5nZXREaXN0YW5jZUJldHdlZW5Ub3VjaGVzKGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWdlc3R1cmUuJHNsaWRlRWwgfHwgIWdlc3R1cmUuJHNsaWRlRWwubGVuZ3RoKSB7XG4gICAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzKTtcbiAgICAgICAgaWYgKGdlc3R1cmUuJHNsaWRlRWwubGVuZ3RoID09PSAwKSBnZXN0dXJlLiRzbGlkZUVsID0gc3dpcGVyLnNsaWRlcy5lcShzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgICAgICBnZXN0dXJlLiRpbWFnZUVsID0gZ2VzdHVyZS4kc2xpZGVFbC5maW5kKCdpbWcsIHN2ZywgY2FudmFzLCBwaWN0dXJlLCAuc3dpcGVyLXpvb20tdGFyZ2V0Jyk7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsID0gZ2VzdHVyZS4kaW1hZ2VFbC5wYXJlbnQoXCIuXCIgKyBwYXJhbXMuY29udGFpbmVyQ2xhc3MpO1xuICAgICAgICBnZXN0dXJlLm1heFJhdGlvID0gZ2VzdHVyZS4kaW1hZ2VXcmFwRWwuYXR0cignZGF0YS1zd2lwZXItem9vbScpIHx8IHBhcmFtcy5tYXhSYXRpbztcblxuICAgICAgICBpZiAoZ2VzdHVyZS4kaW1hZ2VXcmFwRWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgZ2VzdHVyZS4kaW1hZ2VFbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGdlc3R1cmUuJGltYWdlRWwpIHtcbiAgICAgICAgZ2VzdHVyZS4kaW1hZ2VFbC50cmFuc2l0aW9uKDApO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuem9vbS5pc1NjYWxpbmcgPSB0cnVlO1xuICAgIH0sXG4gICAgb25HZXN0dXJlQ2hhbmdlOiBmdW5jdGlvbiBvbkdlc3R1cmVDaGFuZ2UoZSkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgZ2VzdHVyZSA9IHpvb20uZ2VzdHVyZTtcblxuICAgICAgaWYgKCFzdXBwb3J0Lmdlc3R1cmVzKSB7XG4gICAgICAgIGlmIChlLnR5cGUgIT09ICd0b3VjaG1vdmUnIHx8IGUudHlwZSA9PT0gJ3RvdWNobW92ZScgJiYgZS50YXJnZXRUb3VjaGVzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB6b29tLmZha2VHZXN0dXJlTW92ZWQgPSB0cnVlO1xuICAgICAgICBnZXN0dXJlLnNjYWxlTW92ZSA9IFpvb20uZ2V0RGlzdGFuY2VCZXR3ZWVuVG91Y2hlcyhlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlmIChlLnR5cGUgPT09ICdnZXN0dXJlY2hhbmdlJykgem9vbS5vbkdlc3R1cmVTdGFydChlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3VwcG9ydC5nZXN0dXJlcykge1xuICAgICAgICB6b29tLnNjYWxlID0gZS5zY2FsZSAqIHpvb20uY3VycmVudFNjYWxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgem9vbS5zY2FsZSA9IGdlc3R1cmUuc2NhbGVNb3ZlIC8gZ2VzdHVyZS5zY2FsZVN0YXJ0ICogem9vbS5jdXJyZW50U2NhbGU7XG4gICAgICB9XG5cbiAgICAgIGlmICh6b29tLnNjYWxlID4gZ2VzdHVyZS5tYXhSYXRpbykge1xuICAgICAgICB6b29tLnNjYWxlID0gZ2VzdHVyZS5tYXhSYXRpbyAtIDEgKyBNYXRoLnBvdyh6b29tLnNjYWxlIC0gZ2VzdHVyZS5tYXhSYXRpbyArIDEsIDAuNSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh6b29tLnNjYWxlIDwgcGFyYW1zLm1pblJhdGlvKSB7XG4gICAgICAgIHpvb20uc2NhbGUgPSBwYXJhbXMubWluUmF0aW8gKyAxIC0gTWF0aC5wb3cocGFyYW1zLm1pblJhdGlvIC0gem9vbS5zY2FsZSArIDEsIDAuNSk7XG4gICAgICB9XG5cbiAgICAgIGdlc3R1cmUuJGltYWdlRWwudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKFwiICsgem9vbS5zY2FsZSArIFwiKVwiKTtcbiAgICB9LFxuICAgIG9uR2VzdHVyZUVuZDogZnVuY3Rpb24gb25HZXN0dXJlRW5kKGUpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGRldmljZSA9IHN3aXBlci5kZXZpY2U7XG4gICAgICB2Y
166XIgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgZ2VzdHVyZSA9IHpvb20uZ2VzdHVyZTtcblxuICAgICAgaWYgKCFzdXBwb3J0Lmdlc3R1cmVzKSB7XG4gICAgICAgIGlmICghem9vbS5mYWtlR2VzdHVyZVRvdWNoZWQgfHwgIXpvb20uZmFrZUdlc3R1cmVNb3ZlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlLnR5cGUgIT09ICd0b3VjaGVuZCcgfHwgZS50eXBlID09PSAndG91Y2hlbmQnICYmIGUuY2hhbmdlZFRvdWNoZXMubGVuZ3RoIDwgMiAmJiAhZGV2aWNlLmFuZHJvaWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB6b29tLmZha2VHZXN0dXJlVG91Y2hlZCA9IGZhbHNlO1xuICAgICAgICB6b29tLmZha2VHZXN0dXJlTW92ZWQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICB6b29tLnNjYWxlID0gTWF0aC5tYXgoTWF0aC5taW4oem9vbS5zY2FsZSwgZ2VzdHVyZS5tYXhSYXRpbyksIHBhcmFtcy5taW5SYXRpbyk7XG4gICAgICBnZXN0dXJlLiRpbWFnZUVsLnRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCkudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKFwiICsgem9vbS5zY2FsZSArIFwiKVwiKTtcbiAgICAgIHpvb20uY3VycmVudFNjYWxlID0gem9vbS5zY2FsZTtcbiAgICAgIHpvb20uaXNTY2FsaW5nID0gZmFsc2U7XG4gICAgICBpZiAoem9vbS5zY2FsZSA9PT0gMSkgZ2VzdHVyZS4kc2xpZGVFbCA9IHVuZGVmaW5lZDtcbiAgICB9LFxuICAgIG9uVG91Y2hTdGFydDogZnVuY3Rpb24gb25Ub3VjaFN0YXJ0KGUpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGRldmljZSA9IHN3aXBlci5kZXZpY2U7XG4gICAgICB2Y
166XIgem9vbSA9IHN3aXBlci56b29tO1xuICAgICAgdmFyIGdlc3R1cmUgPSB6b29tLmdlc3R1cmUsXG4gICAgICAgICAgaW1hZ2UgPSB6b29tLmltYWdlO1xuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICBpZiAoaW1hZ2UuaXNUb3VjaGVkKSByZXR1cm47XG4gICAgICBpZiAoZGV2aWNlLmFuZHJvaWQgJiYgZS5jYW5jZWxhYmxlKSBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpbWFnZS5pc1RvdWNoZWQgPSB0cnVlO1xuICAgICAgaW1hZ2UudG91Y2hlc1N0YXJ0LnggPSBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyA/IGUudGFyZ2V0VG91Y2hlc1swXS5wYWdlWCA6IGUucGFnZVg7XG4gICAgICBpbWFnZS50b3VjaGVzU3RhcnQueSA9IGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZIDogZS5wYWdlWTtcbiAgICB9LFxuICAgIG9uVG91Y2hNb3ZlOiBmdW5jdGlvbiBvblRvdWNoTW92ZShlKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgZ2VzdHVyZSA9IHpvb20uZ2VzdHVyZSxcbiAgICAgICAgICBpbWFnZSA9IHpvb20uaW1hZ2UsXG4gICAgICAgICAgdmVsb2NpdHkgPSB6b29tLnZlbG9jaXR5O1xuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICBzd2lwZXIuYWxsb3dDbGljayA9IGZhbHNlO1xuICAgICAgaWYgKCFpbWFnZS5pc1RvdWNoZWQgfHwgIWdlc3R1cmUuJHNsaWRlRWwpIHJldHVybjtcblxuICAgICAgaWYgKCFpbWFnZS5pc01vdmVkKSB7XG4gICAgICAgIGltYWdlLndpZHRoID0gZ2VzdHVyZS4kaW1hZ2VFbFswXS5vZmZzZXRXaWR0aDtcbiAgICAgICAgaW1hZ2UuaGVpZ2h0ID0gZ2VzdHVyZS4kaW1hZ2VFbFswXS5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIGltYWdlLnN0YXJ0WCA9IGdldFRyYW5zbGF0ZShnZXN0dXJlLiRpbWFnZVdyYXBFbFswXSwgJ3gnKSB8fCAwO1xuICAgICAgICBpbWFnZS5zdGFydFkgPSBnZXRUcmFuc2xhdGUoZ2VzdHVyZS4kaW1hZ2VXcmFwRWxbMF0sICd5JykgfHwgMDtcbiAgICAgICAgZ2VzdHVyZS5zbGlkZVdpZHRoID0gZ2VzdHVyZS4kc2xpZGVFbFswXS5vZmZzZXRXaWR0aDtcbiAgICAgICAgZ2VzdHVyZS5zbGlkZUhlaWdodCA9IGdlc3R1cmUuJHNsaWRlRWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbC50cmFuc2l0aW9uKDApO1xuXG4gICAgICAgIGlmIChzd2lwZXIucnRsKSB7XG4gICAgICAgICAgaW1hZ2Uuc3RhcnRYID0gLWltYWdlLnN0YXJ0WDtcbiAgICAgICAgICBpbWFnZS5zdGFydFkgPSAtaW1hZ2Uuc3RhcnRZO1xuICAgICAgICB9XG4gICAgICB9IC8vIERlZmluZSBpZiB3ZSBuZWVkIGltYWdlIGRyYWdcblxuXG4gICAgICB2Y
166XIgc2NhbGVkV2lkdGggPSBpbWFnZS53aWR0aCAqIHpvb20uc2NhbGU7XG4gICAgICB2YXIgc2NhbGVkSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0ICogem9vbS5zY2FsZTtcbiAgICAgIGlmIChzY2FsZWRXaWR0aCA8IGdlc3R1cmUuc2xpZGVXaWR0aCAmJiBzY2FsZWRIZWlnaHQgPCBnZXN0dXJlLnNsaWRlSGVpZ2h0KSByZXR1cm47XG4gICAgICBpbWFnZS5taW5YID0gTWF0aC5taW4oZ2VzdHVyZS5zbGlkZVdpZHRoIC8gMiAtIHNjYWxlZFdpZHRoIC8gMiwgMCk7XG4gICAgICBpbWFnZS5tYXhYID0gLWltYWdlLm1pblg7XG4gICAgICBpbWFnZS5taW5ZID0gTWF0aC5taW4oZ2VzdHVyZS5zbGlkZUhlaWdodCAvIDIgLSBzY2FsZWRIZWlnaHQgLyAyLCAwKTtcbiAgICAgIGltYWdlLm1heFkgPSAtaW1hZ2UubWluWTtcbiAgICAgIGltYWdlLnRvdWNoZXNDdXJyZW50LnggPSBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYIDogZS5wYWdlWDtcbiAgICAgIGltYWdlLnRvdWNoZXNDdXJyZW50LnkgPSBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZIDogZS5wYWdlWTtcblxuICAgICAgaWYgKCFpbWFnZS5pc01vdmVkICYmICF6b29tLmlzU2NhbGluZykge1xuICAgICAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpICYmIChNYXRoLmZsb29yKGltYWdlLm1pblgpID09PSBNYXRoLmZsb29yKGltYWdlLnN0YXJ0WCkgJiYgaW1hZ2UudG91Y2hlc0N1cnJlbnQueCA8IGltYWdlLnRvdWNoZXNTdGFydC54IHx8IE1hdGguZmxvb3IoaW1hZ2UubWF4WCkgPT09IE1hdGguZmxvb3IoaW1hZ2Uuc3RhcnRYKSAmJiBpbWFnZS50b3VjaGVzQ3VycmVudC54ID4gaW1hZ2UudG91Y2hlc1N0YXJ0LngpKSB7XG4gICAgICAgICAgaW1hZ2UuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzd2lwZXIuaXNIb3Jpem9udGFsKCkgJiYgKE1hdGguZmxvb3IoaW1hZ2UubWluWSkgPT09IE1hdGguZmxvb3IoaW1hZ2Uuc3RhcnRZKSAmJiBpbWFnZS50b3VjaGVzQ3VycmVudC55IDwgaW1hZ2UudG91Y2hlc1N0YXJ0LnkgfHwgTWF0aC5mbG9vcihpbWFnZS5tYXhZKSA9PT0gTWF0aC5mbG9vcihpbWFnZS5zdGFydFkpICYmIGltYWdlLnRvdWNoZXNDdXJyZW50LnkgPiBpbWFnZS50b3VjaGVzU3RhcnQueSkpIHtcbiAgICAgICAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUuY2FuY2VsYWJsZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBpbWFnZS5pc01vdmVkID0gdHJ1ZTtcbiAgICAgIGltYWdlLmN1cnJlbnRYID0gaW1hZ2UudG91Y2hlc0N1cnJlbnQueCAtIGltYWdlLnRvdWNoZXNTdGFydC54ICsgaW1hZ2Uuc3RhcnRYO1xuICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS50b3VjaGVzQ3VycmVudC55IC0gaW1hZ2UudG91Y2hlc1N0YXJ0LnkgKyBpbWFnZS5zdGFydFk7XG5cbiAgICAgIGlmIChpbWFnZS5jdXJyZW50WCA8IGltYWdlLm1pblgpIHtcbiAgICAgICAgaW1hZ2UuY3VycmVudFggPSBpbWFnZS5taW5YICsgMSAtIE1hdGgucG93KGltYWdlLm1pblggLSBpbWFnZS5jdXJyZW50WCArIDEsIDAuOCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZS5jdXJyZW50WCA+IGltYWdlLm1heFgpIHtcbiAgICAgICAgaW1hZ2UuY3VycmVudFggPSBpbWFnZS5tYXhYIC0gMSArIE1hdGgucG93KGltYWdlLmN1cnJlbnRYIC0gaW1hZ2UubWF4WCArIDEsIDAuOCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZS5jdXJyZW50WSA8IGltYWdlLm1pblkpIHtcbiAgICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS5taW5ZICsgMSAtIE1hdGgucG93KGltYWdlLm1pblkgLSBpbWFnZS5jdXJyZW50WSArIDEsIDAuOCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbWFnZS5jdXJyZW50WSA+IGltYWdlLm1heFkpIHtcbiAgICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS5tYXhZIC0gMSArIE1hdGgucG93KGltYWdlLmN1cnJlbnRZIC0gaW1hZ2UubWF4WSArIDEsIDAuOCk7XG4gICAgICB9IC8vIFZlbG9jaXR5XG5cblxuICAgICAgaWYgKCF2ZWxvY2l0eS5wcmV2UG9zaXRpb25YKSB2ZWxvY2l0eS5wcmV2UG9zaXRpb25YID0gaW1hZ2UudG91Y2hlc0N1cnJlbnQueDtcbiAgICAgIGlmICghdmVsb2NpdHkucHJldlBvc2l0aW9uWSkgdmVsb2NpdHkucHJldlBvc2l0aW9uWSA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lnk7XG4gICAgICBpZiAoIXZlbG9jaXR5LnByZXZUaW1lKSB2ZWxvY2l0eS5wcmV2VGltZSA9IERhdGUubm93KCk7XG4gICAgICB2ZWxvY2l0eS54ID0gKGltYWdlLnRvdWNoZXNDdXJyZW50LnggLSB2ZWxvY2l0eS5wcmV2UG9zaXRpb25YKSAvIChEYXRlLm5vdygpIC0gdmVsb2NpdHkucHJldlRpbWUpIC8gMjtcbiAgICAgIHZlbG9jaXR5LnkgPSAoaW1hZ2UudG91Y2hlc0N1cnJlbnQueSAtIHZlbG9jaXR5LnByZXZQb3NpdGlvblkpIC8gKERhdGUubm93KCkgLSB2ZWxvY2l0eS5wcmV2VGltZSkgLyAyO1xuICAgICAgaWYgKE1hdGguYWJzKGltYWdlLnRvdWNoZXNDdXJyZW50LnggLSB2ZWxvY2l0eS5wcmV2UG9zaXRpb25YKSA8IDIpIHZlbG9jaXR5LnggPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKGltYWdlLnRvdWNoZXNDdXJyZW50LnkgLSB2ZWxvY2l0eS5wcmV2UG9zaXRpb25ZKSA8IDIpIHZlbG9jaXR5LnkgPSAwO1xuICAgICAgdmVsb2NpdHkucHJldlBvc2l0aW9uWCA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lng7XG4gICAgICB2ZWxvY2l0eS5wcmV2UG9zaXRpb25ZID0gaW1hZ2UudG91Y2hlc0N1cnJlbnQueTtcbiAgICAgIHZlbG9jaXR5LnByZXZUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKFwiICsgaW1hZ2UuY3VycmVudFggKyBcInB4LCBcIiArIGltYWdlLmN1cnJlbnRZICsgXCJweCwwKVwiKTtcbiAgICB9LFxuICAgIG9uVG91Y2hFbmQ6IGZ1bmN0aW9uIG9uVG91Y2hFbmQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgZ2VzdHVyZSA9IHpvb20uZ2VzdHVyZSxcbiAgICAgICAgICBpbWFnZSA9IHpvb20uaW1hZ2UsXG4gICAgICAgICAgdmVsb2NpdHkgPSB6b29tLnZlbG9jaXR5O1xuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGlmICghaW1hZ2UuaXNUb3VjaGVkIHx8ICFpbWFnZS5pc01vdmVkKSB7XG4gICAgICAgIGltYWdlLmlzVG91Y2hlZCA9IGZhbHNlO1xuICAgICAgICBpbWFnZS5pc01vdmVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaW1hZ2UuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgICBpbWFnZS5pc01vdmVkID0gZmFsc2U7XG4gICAgICB2YXIgbW9tZW50dW1EdXJhdGlvblggPSAzMDA7XG4gICAgICB2YXIgbW9tZW50dW1EdXJhdGlvblkgPSAzMDA7XG4gICAgICB2YXIgbW9tZW50dW1EaXN0YW5jZVggPSB2ZWxvY2l0eS54ICogbW9tZW50dW1EdXJhdGlvblg7XG4gICAgICB2YXIgbmV3UG9zaXRpb25YID0gaW1hZ2UuY3VycmVudFggKyBtb21lbnR1bURpc3RhbmNlWDtcbiAgICAgIHZhciBtb21lbnR1bURpc3RhbmNlWSA9IHZlbG9jaXR5LnkgKiBtb21lbnR1bUR1cmF0aW9uWTtcbiAgICAgIHZhciBuZXdQb3NpdGlvblkgPSBpbWFnZS5jdXJyZW50WSArIG1vbWVudHVtRGlzdGFuY2VZOyAvLyBGaXggZHVyYXRpb25cblxuICAgICAgaWYgKHZlbG9jaXR5LnggIT09IDApIG1vbWVudHVtRHVyYXRpb25YID0gTWF0aC5hYnMoKG5ld1Bvc2l0aW9uWCAtIGltYWdlLmN1cnJlbnRYKSAvIHZlbG9jaXR5LngpO1xuICAgICAgaWYgKHZlbG9jaXR5LnkgIT09IDApIG1vbWVudHVtRHVyYXRpb25ZID0gTWF0aC5hYnMoKG5ld1Bvc2l0aW9uWSAtIGltYWdlLmN1cnJlbnRZKSAvIHZlbG9jaXR5LnkpO1xuICAgICAgdmFyIG1vbWVudHVtRHVyYXRpb24gPSBNYXRoLm1heChtb21lbnR1bUR1cmF0aW9uWCwgbW9tZW50dW1EdXJhdGlvblkpO1xuICAgICAgaW1hZ2UuY3VycmVudFggPSBuZXdQb3NpdGlvblg7XG4gICAgICBpbWFnZS5jdXJyZW50WSA9IG5ld1Bvc2l0aW9uWTsgLy8gRGVmaW5lIGlmIHdlIG5lZWQgaW1hZ2UgZHJhZ1xuXG4gICAgICB2Y
166XIgc2NhbGVkV2lkdGggPSBpbWFnZS53aWR0aCAqIHpvb20uc2NhbGU7XG4gICAgICB2YXIgc2NhbGVkSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0ICogem9vbS5zY2FsZTtcbiAgICAgIGltYWdlLm1pblggPSBNYXRoLm1pbihnZXN0dXJlLnNsaWRlV2lkdGggLyAyIC0gc2NhbGVkV2lkdGggLyAyLCAwKTtcbiAgICAgIGltYWdlLm1heFggPSAtaW1hZ2UubWluWDtcbiAgICAgIGltYWdlLm1pblkgPSBNYXRoLm1pbihnZXN0dXJlLnNsaWRlSGVpZ2h0IC8gMiAtIHNjYWxlZEhlaWdodCAvIDIsIDApO1xuICAgICAgaW1hZ2UubWF4WSA9IC1pbWFnZS5taW5ZO1xuICAgICAgaW1hZ2UuY3VycmVudFggPSBNYXRoLm1heChNYXRoLm1pbihpbWFnZS5jdXJyZW50WCwgaW1hZ2UubWF4WCksIGltYWdlLm1pblgpO1xuICAgICAgaW1hZ2UuY3VycmVudFkgPSBNYXRoLm1heChNYXRoLm1pbihpbWFnZS5jdXJyZW50WSwgaW1hZ2UubWF4WSksIGltYWdlLm1pblkpO1xuICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwudHJhbnNpdGlvbihtb21lbnR1bUR1cmF0aW9uKS50cmFuc2Zvcm0oXCJ0cmFuc2xhdGUzZChcIiArIGltYWdlLmN1cnJlbnRYICsgXCJweCwgXCIgKyBpbWFnZS5jdXJyZW50WSArIFwicHgsMClcIik7XG4gICAgfSxcbiAgICBvblRyYW5zaXRpb25FbmQ6IGZ1bmN0aW9uIG9uVHJhbnNpdGlvbkVuZCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHpvb20gPSBzd2lwZXIuem9vbTtcbiAgICAgIHZhciBnZXN0dXJlID0gem9vbS5nZXN0dXJlO1xuXG4gICAgICBpZiAoZ2VzdHVyZS4kc2xpZGVFbCAmJiBzd2lwZXIucHJldmlvdXNJbmRleCAhPT0gc3dpcGVyLmFjdGl2ZUluZGV4KSB7XG4gICAgICAgIGlmIChnZXN0dXJlLiRpbWFnZUVsKSB7XG4gICAgICAgICAgZ2VzdHVyZS4kaW1hZ2VFbC50cmFuc2Zvcm0oJ3RyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgxKScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdlc3R1cmUuJGltYWdlV3JhcEVsKSB7XG4gICAgICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwudHJhbnNmb3JtKCd0cmFuc2xhdGUzZCgwLDAsMCknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHpvb20uc2NhbGUgPSAxO1xuICAgICAgICB6b29tLmN1cnJlbnRTY2FsZSA9IDE7XG4gICAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlRWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gVG9nZ2xlIFpvb21cbiAgICB0b2dnbGU6IGZ1bmN0aW9uIHRvZ2dsZShlKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG5cbiAgICAgIGlmICh6b29tLnNjYWxlICYmIHpvb20uc2NhbGUgIT09IDEpIHtcbiAgICAgICAgLy8gWm9vbSBPdXRcbiAgICAgICAgem9vbS5vdXQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFpvb20gSW5cbiAgICAgICAgem9vbS5pbihlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGluOiBmdW5jdGlvbiBfaW4oZSkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgem9vbSA9IHN3aXBlci56b29tO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcbiAgICAgIHZhciBnZXN0dXJlID0gem9vbS5nZXN0dXJlLFxuICAgICAgICAgIGltYWdlID0gem9vbS5pbWFnZTtcblxuICAgICAgaWYgKCFnZXN0dXJlLiRzbGlkZUVsKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQgJiYgc3dpcGVyLnZpcnR1YWwpIHtcbiAgICAgICAgICBnZXN0dXJlLiRzbGlkZUVsID0gc3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICBnZXN0dXJlLiRpbWFnZUVsID0gZ2VzdHVyZS4kc2xpZGVFbC5maW5kKCdpbWcsIHN2ZywgY2FudmFzLCBwaWN0dXJlLCAuc3dpcGVyLXpvb20tdGFyZ2V0Jyk7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsID0gZ2VzdHVyZS4kaW1hZ2VFbC5wYXJlbnQoXCIuXCIgKyBwYXJhbXMuY29udGFpbmVyQ2xhc3MpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWdlc3R1cmUuJGltYWdlRWwgfHwgZ2VzdHVyZS4kaW1hZ2VFbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIGdlc3R1cmUuJHNsaWRlRWwuYWRkQ2xhc3MoXCJcIiArIHBhcmFtcy56b29tZWRTbGlkZUNsYXNzKTtcbiAgICAgIHZhciB0b3VjaFg7XG4gICAgICB2Y
166XIgdG91Y2hZO1xuICAgICAgdmFyIG9mZnNldFg7XG4gICAgICB2YXIgb2Zmc2V0WTtcbiAgICAgIHZhciBkaWZmWDtcbiAgICAgIHZhciBkaWZmWTtcbiAgICAgIHZhciB0cmFuc2xhdGVYO1xuICAgICAgdmFyIHRyYW5zbGF0ZVk7XG4gICAgICB2YXIgaW1hZ2VXaWR0aDtcbiAgICAgIHZhciBpbWFnZUhlaWdodDtcbiAgICAgIHZhciBzY2FsZWRXaWR0aDtcbiAgICAgIHZhciBzY2FsZWRIZWlnaHQ7XG4gICAgICB2YXIgdHJhbnNsYXRlTWluWDtcbiAgICAgIHZhciB0cmFuc2xhdGVNaW5ZO1xuICAgICAgdmFyIHRyYW5zbGF0ZU1heFg7XG4gICAgICB2YXIgdHJhbnNsYXRlTWF4WTtcbiAgICAgIHZhciBzbGlkZVdpZHRoO1xuICAgICAgdmFyIHNsaWRlSGVpZ2h0O1xuXG4gICAgICBpZiAodHlwZW9mIGltYWdlLnRvdWNoZXNTdGFydC54ID09PSAndW5kZWZpbmVkJyAmJiBlKSB7XG4gICAgICAgIHRvdWNoWCA9IGUudHlwZSA9PT0gJ3RvdWNoZW5kJyA/IGUuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVggOiBlLnBhZ2VYO1xuICAgICAgICB0b3VjaFkgPSBlLnR5cGUgPT09ICd0b3VjaGVuZCcgPyBlLmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VZIDogZS5wYWdlWTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvdWNoWCA9IGltYWdlLnRvdWNoZXNTdGFydC54O1xuICAgICAgICB0b3VjaFkgPSBpbWFnZS50b3VjaGVzU3RhcnQueTtcbiAgICAgIH1cblxuICAgICAgem9vbS5zY2FsZSA9IGdlc3R1cmUuJGltYWdlV3JhcEVsLmF0dHIoJ2RhdGEtc3dpcGVyLXpvb20nKSB8fCBwYXJhbXMubWF4UmF0aW87XG4gICAgICB6b29tLmN1cnJlbnRTY2FsZSA9IGdlc3R1cmUuJGltYWdlV3JhcEVsLmF0dHIoJ2RhdGEtc3dpcGVyLXpvb20nKSB8fCBwYXJhbXMubWF4UmF0aW87XG5cbiAgICAgIGlmIChlKSB7XG4gICAgICAgIHNsaWRlV2lkdGggPSBnZXN0dXJlLiRzbGlkZUVsWzBdLm9mZnNldFdpZHRoO1xuICAgICAgICBzbGlkZUhlaWdodCA9IGdlc3R1cmUuJHNsaWRlRWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBvZmZzZXRYID0gZ2VzdHVyZS4kc2xpZGVFbC5vZmZzZXQoKS5sZWZ0O1xuICAgICAgICBvZmZzZXRZID0gZ2VzdHVyZS4kc2xpZGVFbC5vZmZzZXQoKS50b3A7XG4gICAgICAgIGRpZmZYID0gb2Zmc2V0WCArIHNsaWRlV2lkdGggLyAyIC0gdG91Y2hYO1xuICAgICAgICBkaWZmWSA9IG9mZnNldFkgKyBzbGlkZUhlaWdodCAvIDIgLSB0b3VjaFk7XG4gICAgICAgIGltYWdlV2lkdGggPSBnZXN0dXJlLiRpbWFnZUVsWzBdLm9mZnNldFdpZHRoO1xuICAgICAgICBpbWFnZUhlaWdodCA9IGdlc3R1cmUuJGltYWdlRWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBzY2FsZWRXaWR0aCA9IGltYWdlV2lkdGggKiB6b29tLnNjYWxlO1xuICAgICAgICBzY2FsZWRIZWlnaHQgPSBpbWFnZUhlaWdodCAqIHpvb20uc2NhbGU7XG4gICAgICAgIHRyYW5zbGF0ZU1pblggPSBNYXRoLm1pbihzbGlkZVdpZHRoIC8gMiAtIHNjYWxlZFdpZHRoIC8gMiwgMCk7XG4gICAgICAgIHRyYW5zbGF0ZU1pblkgPSBNYXRoLm1pbihzbGlkZUhlaWdodCAvIDIgLSBzY2FsZWRIZWlnaHQgLyAyLCAwKTtcbiAgICAgICAgdHJhbnNsYXRlTWF4WCA9IC10cmFuc2xhdGVNaW5YO1xuICAgICAgICB0cmFuc2xhdGVNYXhZID0gLXRyYW5zbGF0ZU1pblk7XG4gICAgICAgIHRyYW5zbGF0ZVggPSBkaWZmWCAqIHpvb20uc2NhbGU7XG4gICAgICAgIHRyYW5zbGF0ZVkgPSBkaWZmWSAqIHpvb20uc2NhbGU7XG5cbiAgICAgICAgaWYgKHRyYW5zbGF0ZVggPCB0cmFuc2xhdGVNaW5YKSB7XG4gICAgICAgICAgdHJhbnNsYXRlWCA9IHRyYW5zbGF0ZU1pblg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHJhbnNsYXRlWCA+IHRyYW5zbGF0ZU1heFgpIHtcbiAgICAgICAgICB0cmFuc2xhdGVYID0gdHJhbnNsYXRlTWF4WDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0cmFuc2xhdGVZIDwgdHJhbnNsYXRlTWluWSkge1xuICAgICAgICAgIHRyYW5zbGF0ZVkgPSB0cmFuc2xhdGVNaW5ZO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRyYW5zbGF0ZVkgPiB0cmFuc2xhdGVNYXhZKSB7XG4gICAgICAgICAgdHJhbnNsYXRlWSA9IHRyYW5zbGF0ZU1heFk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zbGF0ZVggPSAwO1xuICAgICAgICB0cmFuc2xhdGVZID0gMDtcbiAgICAgIH1cblxuICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwudHJhbnNpdGlvbigzMDApLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKFwiICsgdHJhbnNsYXRlWCArIFwicHgsIFwiICsgdHJhbnNsYXRlWSArIFwicHgsMClcIik7XG4gICAgICBnZXN0dXJlLiRpbWFnZUVsLnRyYW5zaXRpb24oMzAwKS50cmFuc2Zvcm0oXCJ0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoXCIgKyB6b29tLnNjYWxlICsgXCIpXCIpO1xuICAgIH0sXG4gICAgb3V0OiBmdW5jdGlvbiBvdXQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy56b29tO1xuICAgICAgdmFyIGdlc3R1cmUgPSB6b29tLmdlc3R1cmU7XG5cbiAgICAgIGlmICghZ2VzdHVyZS4kc2xpZGVFbCkge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkICYmIHN3aXBlci52aXJ0dWFsKSB7XG4gICAgICAgICAgZ2VzdHVyZS4kc2xpZGVFbCA9IHN3aXBlci4kd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBnZXN0dXJlLiRzbGlkZUVsID0gc3dpcGVyLnNsaWRlcy5lcShzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZ2VzdHVyZS4kaW1hZ2VFbCA9IGdlc3R1cmUuJHNsaWRlRWwuZmluZCgnaW1nLCBzdmcsIGNhbnZhcywgcGljdHVyZSwgLnN3aXBlci16b29tLXRhcmdldCcpO1xuICAgICAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbCA9IGdlc3R1cmUuJGltYWdlRWwucGFyZW50KFwiLlwiICsgcGFyYW1zLmNvbnRhaW5lckNsYXNzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICB6b29tLnNjYWxlID0gMTtcbiAgICAgIHpvb20uY3VycmVudFNjYWxlID0gMTtcbiAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsLnRyYW5zaXRpb24oMzAwKS50cmFuc2Zvcm0oJ3RyYW5zbGF0ZTNkKDAsMCwwKScpO1xuICAgICAgZ2VzdHVyZS4kaW1hZ2VFbC50cmFuc2l0aW9uKDMwMCkudHJhbnNmb3JtKCd0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoMSknKTtcbiAgICAgIGdlc3R1cmUuJHNsaWRlRWwucmVtb3ZlQ2xhc3MoXCJcIiArIHBhcmFtcy56b29tZWRTbGlkZUNsYXNzKTtcbiAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSB1bmRlZmluZWQ7XG4gICAgfSxcbiAgICB0b2dnbGVHZXN0dXJlczogZnVuY3Rpb24gdG9nZ2xlR2VzdHVyZXMobWV0aG9kKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICB2YXIgc2VsZWN0b3IgPSB6b29tLnNsaWRlU2VsZWN0b3IsXG4gICAgICAgICAgcGFzc2l2ZSA9IHpvb20ucGFzc2l2ZUxpc3RlbmVyO1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbbWV0aG9kXSgnZ2VzdHVyZXN0YXJ0Jywgc2VsZWN0b3IsIHpvb20ub25HZXN0dXJlU3RhcnQsIHBhc3NpdmUpO1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbbWV0aG9kXSgnZ2VzdHVyZWNoYW5nZScsIHNlbGVjdG9yLCB6b29tLm9uR2VzdHVyZUNoYW5nZSwgcGFzc2l2ZSk7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbFttZXRob2RdKCdnZXN0dXJlZW5kJywgc2VsZWN0b3IsIHpvb20ub25HZXN0dXJlRW5kLCBwYXNzaXZlKTtcbiAgICB9LFxuICAgIGVuYWJsZUdlc3R1cmVzOiBmdW5jdGlvbiBlbmFibGVHZXN0dXJlcygpIHtcbiAgICAgIGlmICh0aGlzLnpvb20uZ2VzdHVyZXNFbmFibGVkKSByZXR1cm47XG4gICAgICB0aGlzLnpvb20uZ2VzdHVyZXNFbmFibGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuem9vbS50b2dnbGVHZXN0dXJlcygnb24nKTtcbiAgICB9LFxuICAgIGRpc2FibGVHZXN0dXJlczogZnVuY3Rpb24gZGlzYWJsZUdlc3R1cmVzKCkge1xuICAgICAgaWYgKCF0aGlzLnpvb20uZ2VzdHVyZXNFbmFibGVkKSByZXR1cm47XG4gICAgICB0aGlzLnpvb20uZ2VzdHVyZXNFbmFibGVkID0gZmFsc2U7XG4gICAgICB0aGlzLnpvb20udG9nZ2xlR2VzdHVyZXMoJ29mZicpO1xuICAgIH0sXG4gICAgLy8gQXR0YWNoL0RldGFjaCBFdmVudHNcbiAgICBlbmFibGU6IGZ1bmN0aW9uIGVuYWJsZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHN1cHBvcnQgPSBzd2lwZXIuc3VwcG9ydDtcbiAgICAgIHZhciB6b29tID0gc3dpcGVyLnpvb207XG4gICAgICBpZiAoem9vbS5lbmFibGVkKSByZXR1cm47XG4gICAgICB6b29tLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgdmFyIHBhc3NpdmVMaXN0ZW5lciA9IHN3aXBlci50b3VjaEV2ZW50cy5zdGFydCA9PT0gJ3RvdWNoc3RhcnQnICYmIHN1cHBvcnQucGFzc2l2ZUxpc3RlbmVyICYmIHN3aXBlci5wYXJhbXMucGFzc2l2ZUxpc3RlbmVycyA/IHtcbiAgICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgICAgY2FwdHVyZTogZmFsc2VcbiAgICAgIH0gOiBmYWxzZTtcbiAgICAgIHZhciBhY3RpdmVMaXN0ZW5lcldpdGhDYXB0dXJlID0gc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgPyB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgICBjYXB0dXJlOiB0cnVlXG4gICAgICB9IDogdHJ1ZTtcbiAgICAgIHZhciBzbGlkZVNlbGVjdG9yID0gXCIuXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3M7XG4gICAgICBzd2lwZXIuem9vbS5wYXNzaXZlTGlzdGVuZXIgPSBwYXNzaXZlTGlzdGVuZXI7XG4gICAgICBzd2lwZXIuem9vbS5zbGlkZVNlbGVjdG9yID0gc2xpZGVTZWxlY3RvcjsgLy8gU2NhbGUgaW1hZ2VcblxuICAgICAgaWYgKHN1cHBvcnQuZ2VzdHVyZXMpIHtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLnN0YXJ0LCBzd2lwZXIuem9vbS5lbmFibGVHZXN0dXJlcywgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLmVuZCwgc3dpcGVyLnpvb20uZGlzYWJsZUdlc3R1cmVzLCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIGlmIChzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQgPT09ICd0b3VjaHN0YXJ0Jykge1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vbihzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQsIHNsaWRlU2VsZWN0b3IsIHpvb20ub25HZXN0dXJlU3RhcnQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9uKHN3aXBlci50b3VjaEV2ZW50cy5tb3ZlLCBzbGlkZVNlbGVjdG9yLCB6b29tLm9uR2VzdHVyZUNoYW5nZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9uKHN3aXBlci50b3VjaEV2ZW50cy5lbmQsIHNsaWRlU2VsZWN0b3IsIHpvb20ub25HZXN0dXJlRW5kLCBwYXNzaXZlTGlzdGVuZXIpO1xuXG4gICAgICAgIGlmIChzd2lwZXIudG91Y2hFdmVudHMuY2FuY2VsKSB7XG4gICAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLmNhbmNlbCwgc2xpZGVTZWxlY3Rvciwgem9vbS5vbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gTW92ZSBpbWFnZVxuXG5cbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9uKHN3aXBlci50b3VjaEV2ZW50cy5tb3ZlLCBcIi5cIiArIHN3aXBlci5wYXJhbXMuem9vbS5jb250YWluZXJDbGFzcywgem9vbS5vblRvdWNoTW92ZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XG4gICAgfSxcbiAgICBkaXNhYmxlOiBmdW5jdGlvbiBkaXNhYmxlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgem9vbSA9IHN3aXBlci56b29tO1xuICAgICAgaWYgKCF6b29tLmVuYWJsZWQpIHJldHVybjtcbiAgICAgIHZhciBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgICBzd2lwZXIuem9vbS5lbmFibGVkID0gZmFsc2U7XG4gICAgICB2YXIgcGFzc2l2ZUxpc3RlbmVyID0gc3dpcGVyLnRvdWNoRXZlbnRzLnN0YXJ0ID09PSAndG91Y2hzdGFydCcgJiYgc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgc3dpcGVyLnBhcmFtcy5wYXNzaXZlTGlzdGVuZXJzID8ge1xuICAgICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgICBjYXB0dXJlOiBmYWxzZVxuICAgICAgfSA6IGZhbHNlO1xuICAgICAgdmFyIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUgPSBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciA/IHtcbiAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICAgIGNhcHR1cmU6IHRydWVcbiAgICAgIH0gOiB0cnVlO1xuICAgICAgdmFyIHNsaWRlU2VsZWN0b3IgPSBcIi5cIiArIHN3aXBlci5wYXJhbXMuc2xpZGVDbGFzczsgLy8gU2NhbGUgaW1hZ2VcblxuICAgICAgaWYgKHN1cHBvcnQuZ2VzdHVyZXMpIHtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub2ZmKHN3aXBlci50b3VjaEV2ZW50cy5zdGFydCwgc3dpcGVyLnpvb20uZW5hYmxlR2VzdHVyZXMsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMuZW5kLCBzd2lwZXIuem9vbS5kaXNhYmxlR2VzdHVyZXMsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICB9IGVsc2UgaWYgKHN3aXBlci50b3VjaEV2ZW50cy5zdGFydCA9PT0gJ3RvdWNoc3RhcnQnKSB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQsIHNsaWRlU2VsZWN0b3IsIHpvb20ub25HZXN0dXJlU3RhcnQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMubW92ZSwgc2xpZGVTZWxlY3Rvciwgem9vbS5vbkdlc3R1cmVDaGFuZ2UsIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUpO1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vZmYoc3dpcGVyLnRvdWNoRXZlbnRzLmVuZCwgc2xpZGVTZWxlY3Rvciwgem9vbS5vbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG5cbiAgICAgICAgaWYgKHN3aXBlci50b3VjaEV2ZW50cy5jYW5jZWwpIHtcbiAgICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vZmYoc3dpcGVyLnRvdWNoRXZlbnRzLmNhbmNlbCwgc2xpZGVTZWxlY3Rvciwgem9vbS5vbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gTW92ZSBpbWFnZVxuXG5cbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMubW92ZSwgXCIuXCIgKyBzd2lwZXIucGFyYW1zLnpvb20uY29udGFpbmVyQ2xhc3MsIHpvb20ub25Ub3VjaE1vdmUsIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUpO1xuICAgIH1cbiAgfTtcbiAgdmFyIFpvb20kMSA9IHtcbiAgICBuYW1lOiAnem9vbScsXG4gICAgcGFyYW1zOiB7XG4gICAgICB6b29tOiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBtYXhSYXRpbzogMyxcbiAgICAgICAgbWluUmF0aW86IDEsXG4gICAgICAgIHRvZ2dsZTogdHJ1ZSxcbiAgICAgICAgY29udGFpbmVyQ2xhc3M6ICdzd2lwZXItem9vbS1jb250YWluZXInLFxuICAgICAgICB6b29tZWRTbGlkZUNsYXNzOiAnc3dpcGVyLXNsaWRlLXpvb21lZCdcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgem9vbTogX2V4dGVuZHMoe1xuICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgIHNjYWxlOiAxLFxuICAgICAgICAgIGN1cnJlbnRTY2FsZTogMSxcbiAgICAgICAgICBpc1NjYWxpbmc6IGZhbHNlLFxuICAgICAgICAgIGdlc3R1cmU6IHtcbiAgICAgICAgICAgICRzbGlkZUVsOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBzbGlkZVdpZHRoOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBzbGlkZUhlaWdodDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgJGltYWdlRWw6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICRpbWFnZVdyYXBFbDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWF4UmF0aW86IDNcbiAgICAgICAgICB9LFxuICAgICAgICAgIGltYWdlOiB7XG4gICAgICAgICAgICBpc1RvdWNoZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzTW92ZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN1cnJlbnRYOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBjdXJyZW50WTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWluWDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWluWTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWF4WDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWF4WTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgd2lkdGg6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGhlaWdodDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc3RhcnRYOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBzdGFydFk6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHRvdWNoZXNTdGFydDoge30sXG4gICAgICAgICAgICB0b3VjaGVzQ3VycmVudDoge31cbiAgICAgICAgICB9LFxuICAgICAgICAgIHZlbG9jaXR5OiB7XG4gICAgICAgICAgICB4OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB5OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBwcmV2UG9zaXRpb25YOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBwcmV2UG9zaXRpb25ZOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBwcmV2VGltZTogdW5kZWZpbmVkXG4gICAgICAgICAgfVxuICAgICAgICB9LCBab29tKVxuICAgICAgfSk7XG4gICAgICB2Y
166XIgc2NhbGUgPSAxO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHN3aXBlci56b29tLCAnc2NhbGUnLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgIHJldHVybiBzY2FsZTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAgICAgICBpZiAoc2NhbGUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgaW1hZ2VFbCA9IHN3aXBlci56b29tLmdlc3R1cmUuJGltYWdlRWwgPyBzd2lwZXIuem9vbS5nZXN0dXJlLiRpbWFnZUVsWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIHNsaWRlRWwgPSBzd2lwZXIuem9vbS5nZXN0dXJlLiRzbGlkZUVsID8gc3dpcGVyLnpvb20uZ2VzdHVyZS4kc2xpZGVFbFswXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHN3aXBlci5lbWl0KCd6b29tQ2hhbmdlJywgdmFsdWUsIGltYWdlRWwsIHNsaWRlRWwpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNjYWxlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLnpvb20uZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci56b29tLmVuYWJsZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveShzd2lwZXIpIHtcbiAgICAgICAgc3dpcGVyLnpvb20uZGlzYWJsZSgpO1xuICAgICAgfSxcbiAgICAgIHRvdWNoU3RhcnQ6IGZ1bmN0aW9uIHRvdWNoU3RhcnQoc3dpcGVyLCBlKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnpvb20uZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuem9vbS5vblRvdWNoU3RhcnQoZSk7XG4gICAgICB9LFxuICAgICAgdG91Y2hFbmQ6IGZ1bmN0aW9uIHRvdWNoRW5kKHN3aXBlciwgZSkge1xuICAgICAgICBpZiAoIXN3aXBlci56b29tLmVuYWJsZWQpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLnpvb20ub25Ub3VjaEVuZChlKTtcbiAgICAgIH0sXG4gICAgICBkb3VibGVUYXA6IGZ1bmN0aW9uIGRvdWJsZVRhcChzd2lwZXIsIGUpIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkICYmIHN3aXBlci56b29tLmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy56b29tLnRvZ2dsZSkge1xuICAgICAgICAgIHN3aXBlci56b29tLnRvZ2dsZShlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRyYW5zaXRpb25FbmQ6IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkKSB7XG4gICAgICAgICAgc3dpcGVyLnpvb20ub25UcmFuc2l0aW9uRW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzbGlkZUNoYW5nZTogZnVuY3Rpb24gc2xpZGVDaGFuZ2Uoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgICAgIHN3aXBlci56b29tLm9uVHJhbnNpdGlvbkVuZCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBMYXp5ID0ge1xuICAgIGxvYWRJblNsaWRlOiBmdW5jdGlvbiBsb2FkSW5TbGlkZShpbmRleCwgbG9hZEluRHVwbGljYXRlKSB7XG4gICAgICBpZiAobG9hZEluRHVwbGljYXRlID09PSB2b2lkIDApIHtcbiAgICAgICAgbG9hZEluRHVwbGljYXRlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5sYXp5O1xuICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdmFyIGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkO1xuICAgICAgdmFyICRzbGlkZUVsID0gaXNWaXJ0dWFsID8gc3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3MgKyBcIltkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cXFwiXCIgKyBpbmRleCArIFwiXFxcIl1cIikgOiBzd2lwZXIuc2xpZGVzLmVxKGluZGV4KTtcbiAgICAgIHZhciAkaW1hZ2VzID0gJHNsaWRlRWwuZmluZChcIi5cIiArIHBhcmFtcy5lbGVtZW50Q2xhc3MgKyBcIjpub3QoLlwiICsgcGFyYW1zLmxvYWRlZENsYXNzICsgXCIpOm5vdCguXCIgKyBwYXJhbXMubG9hZGluZ0NsYXNzICsgXCIpXCIpO1xuXG4gICAgICBpZiAoJHNsaWRlRWwuaGFzQ2xhc3MocGFyYW1zLmVsZW1lbnRDbGFzcykgJiYgISRzbGlkZUVsLmhhc0NsYXNzKHBhcmFtcy5sb2FkZWRDbGFzcykgJiYgISRzbGlkZUVsLmhhc0NsYXNzKHBhcmFtcy5sb2FkaW5nQ2xhc3MpKSB7XG4gICAgICAgICRpbWFnZXMucHVzaCgkc2xpZGVFbFswXSk7XG4gICAgICB9XG5cbiAgICAgIGlmICgkaW1hZ2VzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgJGltYWdlcy5lYWNoKGZ1bmN0aW9uIChpbWFnZUVsKSB7XG4gICAgICAgIHZhciAkaW1hZ2VFbCA9ICQoaW1hZ2VFbCk7XG4gICAgICAgICRpbWFnZUVsLmFkZENsYXNzKHBhcmFtcy5sb2FkaW5nQ2xhc3MpO1xuICAgICAgICB2Y
166XIgYmFja2dyb3VuZCA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtYmFja2dyb3VuZCcpO1xuICAgICAgICB2YXIgc3JjID0gJGltYWdlRWwuYXR0cignZGF0YS1zcmMnKTtcbiAgICAgICAgdmFyIHNyY3NldCA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtc3Jjc2V0Jyk7XG4gICAgICAgIHZhciBzaXplcyA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtc2l6ZXMnKTtcbiAgICAgICAgdmFyICRwaWN0dXJlRWwgPSAkaW1hZ2VFbC5wYXJlbnQoJ3BpY3R1cmUnKTtcbiAgICAgICAgc3dpcGVyLmxvYWRJbWFnZSgkaW1hZ2VFbFswXSwgc3JjIHx8IGJhY2tncm91bmQsIHNyY3NldCwgc2l6ZXMsIGZhbHNlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBzd2lwZXIgPT09ICd1bmRlZmluZWQnIHx8IHN3aXBlciA9PT0gbnVsbCB8fCAhc3dpcGVyIHx8IHN3aXBlciAmJiAhc3dpcGVyLnBhcmFtcyB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICAgICAgICBpZiAoYmFja2dyb3VuZCkge1xuICAgICAgICAgICAgJGltYWdlRWwuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJywgXCJ1cmwoXFxcIlwiICsgYmFja2dyb3VuZCArIFwiXFxcIilcIik7XG4gICAgICAgICAgICAkaW1hZ2VFbC5yZW1vdmVBdHRyKCdkYXRhLWJhY2tncm91bmQnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHNyY3NldCkge1xuICAgICAgICAgICAgICAkaW1hZ2VFbC5hdHRyKCdzcmNzZXQnLCBzcmNzZXQpO1xuICAgICAgICAgICAgICAkaW1hZ2VFbC5yZW1vdmVBdHRyKCdkYXRhLXNyY3NldCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2l6ZXMpIHtcbiAgICAgICAgICAgICAgJGltYWdlRWwuYXR0cignc2l6ZXMnLCBzaXplcyk7XG4gICAgICAgICAgICAgICRpbWFnZUVsLnJlbW92ZUF0dHIoJ2RhdGEtc2l6ZXMnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCRwaWN0dXJlRWwubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICRwaWN0dXJlRWwuY2hpbGRyZW4oJ3NvdXJjZScpLmVhY2goZnVuY3Rpb24gKHNvdXJjZUVsKSB7XG4gICAgICAgICAgICAgICAgdmFyICRzb3VyY2UgPSAkKHNvdXJjZUVsKTtcblxuICAgICAgICAgICAgICAgIGlmICgkc291cmNlLmF0dHIoJ2RhdGEtc3Jjc2V0JykpIHtcbiAgICAgICAgICAgICAgICAgICRzb3VyY2UuYXR0cignc3Jjc2V0JywgJHNvdXJjZS5hdHRyKCdkYXRhLXNyY3NldCcpKTtcbiAgICAgICAgICAgICAgICAgICRzb3VyY2UucmVtb3ZlQXR0cignZGF0YS1zcmNzZXQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3JjKSB7XG4gICAgICAgICAgICAgICRpbWFnZUVsLmF0dHIoJ3NyYycsIHNyYyk7XG4gICAgICAgICAgICAgICRpbWFnZUVsLnJlbW92ZUF0dHIoJ2RhdGEtc3JjJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgJGltYWdlRWwuYWRkQ2xhc3MocGFyYW1zLmxvYWRlZENsYXNzKS5yZW1vdmVDbGFzcyhwYXJhbXMubG9hZGluZ0NsYXNzKTtcbiAgICAgICAgICAkc2xpZGVFbC5maW5kKFwiLlwiICsgcGFyYW1zLnByZWxvYWRlckNsYXNzKS5yZW1vdmUoKTtcblxuICAgICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3AgJiYgbG9hZEluRHVwbGljYXRlKSB7XG4gICAgICAgICAgICB2Y
166XIgc2xpZGVPcmlnaW5hbEluZGV4ID0gJHNsaWRlRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKTtcblxuICAgICAgICAgICAgaWYgKCRzbGlkZUVsLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcykpIHtcbiAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsU2xpZGUgPSBzd2lwZXIuJHdyYXBwZXJFbC5jaGlsZHJlbihcIltkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cXFwiXCIgKyBzbGlkZU9yaWdpbmFsSW5kZXggKyBcIlxcXCJdOm5vdCguXCIgKyBzd2lwZXIucGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MgKyBcIilcIik7XG4gICAgICAgICAgICAgIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKG9yaWdpbmFsU2xpZGUuaW5kZXgoKSwgZmFsc2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIGR1cGxpY2F0ZWRTbGlkZSA9IHN3aXBlci4kd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgc2xpZGVPcmlnaW5hbEluZGV4ICsgXCJcXFwiXVwiKTtcbiAgICAgICAgICAgICAgc3dpcGVyLmxhenkubG9hZEluU2xpZGUoZHVwbGljYXRlZFNsaWRlLmluZGV4KCksIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2lwZXIuZW1pdCgnbGF6eUltYWdlUmVhZHknLCAkc2xpZGVFbFswXSwgJGltYWdlRWxbMF0pO1xuXG4gICAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b0hlaWdodCkge1xuICAgICAgICAgICAgc3dpcGVyLnVwZGF0ZUF1dG9IZWlnaHQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzd2lwZXIuZW1pdCgnbGF6eUltYWdlTG9hZCcsICRzbGlkZUVsWzBdLCAkaW1hZ2VFbFswXSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGxvYWQ6IGZ1bmN0aW9uIGxvYWQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWwsXG4gICAgICAgICAgc3dpcGVyUGFyYW1zID0gc3dpcGVyLnBhcmFtcyxcbiAgICAgICAgICBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzLFxuICAgICAgICAgIGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgdmFyIGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlclBhcmFtcy52aXJ0dWFsLmVuYWJsZWQ7XG4gICAgICB2YXIgcGFyYW1zID0gc3dpcGVyUGFyYW1zLmxhenk7XG4gICAgICB2YXIgc2xpZGVzUGVyVmlldyA9IHN3aXBlclBhcmFtcy5zbGlkZXNQZXJWaWV3O1xuXG4gICAgICBpZiAoc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nKSB7XG4gICAgICAgIHNsaWRlc1BlclZpZXcgPSAwO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBzbGlkZUV4aXN0KGluZGV4KSB7XG4gICAgICAgIGlmIChpc1ZpcnR1YWwpIHtcbiAgICAgICAgICBpZiAoJHdyYXBwZXJFbC5jaGlsZHJlbihcIi5cIiArIHN3aXBlclBhcmFtcy5zbGlkZUNsYXNzICsgXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgaW5kZXggKyBcIlxcXCJdXCIpLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHNsaWRlc1tpbmRleF0pIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gc2xpZGVJbmRleChzbGlkZUVsKSB7XG4gICAgICAgIGlmIChpc1ZpcnR1YWwpIHtcbiAgICAgICAgICByZXR1cm4gJChzbGlkZUVsKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICQoc2xpZGVFbCkuaW5kZXgoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFzd2lwZXIubGF6eS5pbml0aWFsSW1hZ2VMb2FkZWQpIHN3aXBlci5sYXp5LmluaXRpYWxJbWFnZUxvYWRlZCA9IHRydWU7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLndhdGNoU2xpZGVzVmlzaWJpbGl0eSkge1xuICAgICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgc3dpcGVyUGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzKS5lYWNoKGZ1bmN0aW9uIChzbGlkZUVsKSB7XG4gICAgICAgICAgdmFyIGluZGV4ID0gaXNWaXJ0dWFsID8gJChzbGlkZUVsKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpIDogJChzbGlkZUVsKS5pbmRleCgpO1xuICAgICAgICAgIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKGluZGV4KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHNsaWRlc1BlclZpZXcgPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSBhY3RpdmVJbmRleDsgaSA8IGFjdGl2ZUluZGV4ICsgc2xpZGVzUGVyVmlldzsgaSArPSAxKSB7XG4gICAgICAgICAgaWYgKHNsaWRlRXhpc3QoaSkpIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIubGF6eS5sb2FkSW5TbGlkZShhY3RpdmVJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMubG9hZFByZXZOZXh0KSB7XG4gICAgICAgIGlmIChzbGlkZXNQZXJWaWV3ID4gMSB8fCBwYXJhbXMubG9hZFByZXZOZXh0QW1vdW50ICYmIHBhcmFtcy5sb2FkUHJldk5leHRBbW91bnQgPiAxKSB7XG4gICAgICAgICAgdmFyIGFtb3VudCA9IHBhcmFtcy5sb2FkUHJldk5leHRBbW91bnQ7XG4gICAgICAgICAgdmFyIHNwdiA9IHNsaWRlc1BlclZpZXc7XG4gICAgICAgICAgdmFyIG1heEluZGV4ID0gTWF0aC5taW4oYWN0aXZlSW5kZXggKyBzcHYgKyBNYXRoLm1heChhbW91bnQsIHNwdiksIHNsaWRlcy5sZW5ndGgpO1xuICAgICAgICAgIHZhciBtaW5JbmRleCA9IE1hdGgubWF4KGFjdGl2ZUluZGV4IC0gTWF0aC5tYXgoc3B2LCBhbW91bnQpLCAwKTsgLy8gTmV4dCBTbGlkZXNcblxuICAgICAgICAgIGZvciAodmFyIF9pID0gYWN0aXZlSW5kZXggKyBzbGlkZXNQZXJWaWV3OyBfaSA8IG1heEluZGV4OyBfaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAoc2xpZGVFeGlzdChfaSkpIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKF9pKTtcbiAgICAgICAgICB9IC8vIFByZXYgU2xpZGVzXG5cblxuICAgICAgICAgIGZvciAodmFyIF9pMiA9IG1pbkluZGV4OyBfaTIgPCBhY3RpdmVJbmRleDsgX2kyICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChzbGlkZUV4aXN0KF9pMikpIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKF9pMik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBuZXh0U2xpZGUgPSAkd3JhcHBlckVsLmNoaWxkcmVuKFwiLlwiICsgc3dpcGVyUGFyYW1zLnNsaWRlTmV4dENsYXNzKTtcbiAgICAgICAgICBpZiAobmV4dFNsaWRlLmxlbmd0aCA+IDApIHN3aXBlci5sYXp5LmxvYWRJblNsaWRlKHNsaWRlSW5kZXgobmV4dFNsaWRlKSk7XG4gICAgICAgICAgdmFyIHByZXZTbGlkZSA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oXCIuXCIgKyBzd2lwZXJQYXJhbXMuc2xpZGVQcmV2Q2xhc3MpO1xuICAgICAgICAgIGlmIChwcmV2U2xpZGUubGVuZ3RoID4gMCkgc3dpcGVyLmxhenkubG9hZEluU2xpZGUoc2xpZGVJbmRleChwcmV2U2xpZGUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgdmFyIExhenkkMSA9IHtcbiAgICBuYW1lOiAnbGF6eScsXG4gICAgcGFyYW1zOiB7XG4gICAgICBsYXp5OiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBsb2FkUHJldk5leHQ6IGZhbHNlLFxuICAgICAgICBsb2FkUHJldk5leHRBbW91bnQ6IDEsXG4gICAgICAgIGxvYWRPblRyYW5zaXRpb25TdGFydDogZmFsc2UsXG4gICAgICAgIGVsZW1lbnRDbGFzczogJ3N3aXBlci1sYXp5JyxcbiAgICAgICAgbG9hZGluZ0NsYXNzOiAnc3dpcGVyLWxhenktbG9hZGluZycsXG4gICAgICAgIGxvYWRlZENsYXNzOiAnc3dpcGVyLWxhenktbG9hZGVkJyxcbiAgICAgICAgcHJlbG9hZGVyQ2xhc3M6ICdzd2lwZXItbGF6eS1wcmVsb2FkZXInXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIGxhenk6IF9leHRlbmRzKHtcbiAgICAgICAgICBpbml0aWFsSW1hZ2VMb2FkZWQ6IGZhbHNlXG4gICAgICAgI
166H0sIExhenkpXG4gICAgICB9KTtcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBiZWZvcmVJbml0OiBmdW5jdGlvbiBiZWZvcmVJbml0KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy5wcmVsb2FkSW1hZ2VzKSB7XG4gICAgICAgICAgc3dpcGVyLnBhcmFtcy5wcmVsb2FkSW1hZ2VzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBpbml0OiBmdW5jdGlvbiBpbml0KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiBzd2lwZXIucGFyYW1zLmluaXRpYWxTbGlkZSA9PT0gMCkge1xuICAgICAgICAgIHN3aXBlci5sYXp5LmxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNjcm9sbDogZnVuY3Rpb24gc2Nyb2xsKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiAhc3dpcGVyLnBhcmFtcy5mcmVlTW9kZVN0aWNreSkge1xuICAgICAgICAgIHN3aXBlci5sYXp5LmxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlc2l6ZTogZnVuY3Rpb24gcmVzaXplKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQpIHtcbiAgICAgICAgICBzd2lwZXIubGF6eS5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzY3JvbGxiYXJEcmFnTW92ZTogZnVuY3Rpb24gc2Nyb2xsYmFyRHJhZ01vdmUoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxhenkuZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci5sYXp5LmxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRyYW5zaXRpb25TdGFydDogZnVuY3Rpb24gdHJhbnNpdGlvblN0YXJ0KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQpIHtcbiAgICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmxvYWRPblRyYW5zaXRpb25TdGFydCB8fCAhc3dpcGVyLnBhcmFtcy5sYXp5LmxvYWRPblRyYW5zaXRpb25TdGFydCAmJiAhc3dpcGVyLmxhenkuaW5pdGlhbEltYWdlTG9hZGVkKSB7XG4gICAgICAgICAgICBzd2lwZXIubGF6eS5sb2FkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdHJhbnNpdGlvbkVuZDogZnVuY3Rpb24gdHJhbnNpdGlvbkVuZChzd2lwZXIpIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMubGF6eS5lbmFibGVkICYmICFzd2lwZXIucGFyYW1zLmxhenkubG9hZE9uVHJhbnNpdGlvblN0YXJ0KSB7XG4gICAgICAgICAgc3dpcGVyLmxhenkubG9hZCgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc2xpZGVDaGFuZ2U6IGZ1bmN0aW9uIHNsaWRlQ2hhbmdlKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICAgICAgc3dpcGVyLmxhenkubG9hZCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBDb250cm9sbGVyID0ge1xuICAgIExpbmVhclNwbGluZTogZnVuY3Rpb24gTGluZWFyU3BsaW5lKHgsIHkpIHtcbiAgICAgIHZhciBiaW5hcnlTZWFyY2ggPSBmdW5jdGlvbiBzZWFyY2goKSB7XG4gICAgICAgIHZhciBtYXhJbmRleDtcbiAgICAgICAgdmFyIG1pbkluZGV4O1xuICAgICAgICB2Y
166XIgZ3Vlc3M7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJyYXksIHZhbCkge1xuICAgICAgICAgIG1pbkluZGV4ID0gLTE7XG4gICAgICAgICAgbWF4SW5kZXggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgICAgICB3aGlsZSAobWF4SW5kZXggLSBtaW5JbmRleCA+IDEpIHtcbiAgICAgICAgICAgIGd1ZXNzID0gbWF4SW5kZXggKyBtaW5JbmRleCA+PiAxO1xuXG4gICAgICAgICAgICBpZiAoYXJyYXlbZ3Vlc3NdIDw9IHZhbCkge1xuICAgICAgICAgICAgICBtaW5JbmRleCA9IGd1ZXNzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbWF4SW5kZXggPSBndWVzcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbWF4SW5kZXg7XG4gICAgICAgIH07XG4gICAgICB9KCk7XG5cbiAgICAgIHRoaXMueCA9IHg7XG4gICAgICB0aGlzLnkgPSB5O1xuICAgICAgdGhpcy5sYXN0SW5kZXggPSB4Lmxlbmd0aCAtIDE7IC8vIEdpdmVuIGFuIHggdmFsdWUgKHgyKSwgcmV0dXJuIHRoZSBleHBlY3RlZCB5MiB2YWx1ZTpcbiAgICAgIC8vICh4MSx5MSkgaXMgdGhlIGtub3duIHBvaW50IGJlZm9yZSBnaXZlbiB2YWx1ZSxcbiAgICAgIC8vICh4Myx5MykgaXMgdGhlIGtub3duIHBvaW50IGFmdGVyIGdpdmVuIHZhbHVlLlxuXG4gICAgICB2YXIgaTE7XG4gICAgICB2YXIgaTM7XG5cbiAgICAgIHRoaXMuaW50ZXJwb2xhdGUgPSBmdW5jdGlvbiBpbnRlcnBvbGF0ZSh4Mikge1xuICAgICAgICBpZiAoIXgyKSByZXR1cm4gMDsgLy8gR2V0IHRoZSBpbmRleGVzIG9mIHgxIGFuZCB4MyAodGhlIGFycmF5IGluZGV4ZXMgYmVmb3JlIGFuZCBhZnRlciBnaXZlbiB4Mik6XG5cbiAgICAgICAgaTMgPSBiaW5hcnlTZWFyY2godGhpcy54LCB4Mik7XG4gICAgICAgIGkxID0gaTMgLSAxOyAvLyBXZSBoYXZlIG91ciBpbmRleGVzIGkxICYgaTMsIHNvIHdlIGNhbiBjYWxjdWxhdGUgYWxyZWFkeTpcbiAgICAgICAgLy8geTIgOj0gKCh4MuKIkngxKSDDlyAoeTPiiJJ5MSkpIMO3ICh4M+KIkngxKSArIHkxXG5cbiAgICAgICAgcmV0dXJuICh4MiAtIHRoaXMueFtpMV0pICogKHRoaXMueVtpM10gLSB0aGlzLnlbaTFdKSAvICh0aGlzLnhbaTNdIC0gdGhpcy54W2kxXSkgKyB0aGlzLnlbaTFdO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICAvLyB4eHg6IGZvciBub3cgaSB3aWxsIGp1c3Qgc2F2ZSBvbmUgc3BsaW5lIGZ1bmN0aW9uIHRvIHRvXG4gICAgZ2V0SW50ZXJwb2xhdGVGdW5jdGlvbjogZnVuY3Rpb24gZ2V0SW50ZXJwb2xhdGVGdW5jdGlvbihjKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcblxuICAgICAgaWYgKCFzd2lwZXIuY29udHJvbGxlci5zcGxpbmUpIHtcbiAgICAgICAgc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lID0gc3dpcGVyLnBhcmFtcy5sb29wID8gbmV3IENvbnRyb2xsZXIuTGluZWFyU3BsaW5lKHN3aXBlci5zbGlkZXNHcmlkLCBjLnNsaWRlc0dyaWQpIDogbmV3IENvbnRyb2xsZXIuTGluZWFyU3BsaW5lKHN3aXBlci5zbmFwR3JpZCwgYy5zbmFwR3JpZCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZShfc2V0VHJhbnNsYXRlLCBieUNvbnRyb2xsZXIpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGNvbnRyb2xsZWQgPSBzd2lwZXIuY29udHJvbGxlci5jb250cm9sO1xuICAgICAgdmFyIG11bHRpcGxpZXI7XG4gICAgICB2YXIgY29udHJvbGxlZFRyYW5zbGF0ZTtcbiAgICAgIHZhciBTd2lwZXIgPSBzd2lwZXIuY29uc3RydWN0b3I7XG5cbiAgICAgIGZ1bmN0aW9uIHNldENvbnRyb2xsZWRUcmFuc2xhdGUoYykge1xuICAgICAgICAvLyB0aGlzIHdpbGwgY3JlYXRlIGFuIEludGVycG9sYXRlIGZ1bmN0aW9uIGJhc2VkIG9uIHRoZSBzbmFwR3JpZHNcbiAgICAgICAgLy8geCBpcyB0aGUgR3JpZCBvZiB0aGUgc2Nyb2xsZWQgc2Nyb2xsZXIgYW5kIHkgd2lsbCBiZSB0aGUgY29udHJvbGxlZCBzY3JvbGxlclxuICAgICAgICAvLyBpdCBtYWtlcyBzZW5zZSB0byBjcmVhdGUgdGhpcyBvbmx5IG9uY2UgYW5kIHJlY2FsbCBpdCBmb3IgdGhlIGludGVycG9sYXRpb25cbiAgICAgICAgLy8gdGhlIGZ1bmN0aW9uIGRvZXMgYSBsb3Qgb2YgdmFsdWUgY2FjaGluZyBmb3IgcGVyZm9ybWFuY2VcbiAgICAgICAgdmFyIHRyYW5zbGF0ZSA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyAtc3dpcGVyLnRyYW5zbGF0ZSA6IHN3aXBlci50cmFuc2xhdGU7XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ3NsaWRlJykge1xuICAgICAgICAgIHN3aXBlci5jb250cm9sbGVyLmdldEludGVycG9sYXRlRnVuY3Rpb24oYyk7IC8vIGkgYW0gbm90IHN1cmUgd2h5IHRoZSB2YWx1ZXMgaGF2ZSB0byBiZSBtdWx0aXBsaWNhdGVkIHRoaXMgd2F5LCB0cmllZCB0byBpbnZlcnQgdGhlIHNuYXBHcmlkXG4gICAgICAgICAgLy8gYnV0IGl0IGRpZCBub3Qgd29yayBvdXRcblxuICAgICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSAtc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lLmludGVycG9sYXRlKC10cmFuc2xhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjb250cm9sbGVkVHJhbnNsYXRlIHx8IHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgICAgICBtdWx0aXBsaWVyID0gKGMubWF4VHJhbnNsYXRlKCkgLSBjLm1pblRyYW5zbGF0ZSgpKSAvIChzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpO1xuICAgICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSAodHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAqIG11bHRpcGxpZXIgKyBjLm1pblRyYW5zbGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5pbnZlcnNlKSB7XG4gICAgICAgICAgY29udHJvbGxlZFRyYW5zbGF0ZSA9IGMubWF4VHJhbnNsYXRlKCkgLSBjb250cm9sbGVkVHJhbnNsYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgYy51cGRhdGVQcm9ncmVzcyhjb250cm9sbGVkVHJhbnNsYXRlKTtcbiAgICAgICAgYy5zZXRUcmFuc2xhdGUoY29udHJvbGxlZFRyYW5zbGF0ZSwgc3dpcGVyKTtcbiAgICAgICAgYy51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgICAgICBjLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udHJvbGxlZCkpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb250cm9sbGVkLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgaWYgKGNvbnRyb2xsZWRbaV0gIT09IGJ5Q29udHJvbGxlciAmJiBjb250cm9sbGVkW2ldIGluc3RhbmNlb2YgU3dpcGVyKSB7XG4gICAgICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGNvbnRyb2xsZWRbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjb250cm9sbGVkIGluc3RhbmNlb2YgU3dpcGVyICYmIGJ5Q29udHJvbGxlciAhPT0gY29udHJvbGxlZCkge1xuICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGNvbnRyb2xsZWQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihkdXJhdGlvbiwgYnlDb250cm9sbGVyKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBTd2lwZXIgPSBzd2lwZXIuY29uc3RydWN0b3I7XG4gICAgICB2YXIgY29udHJvbGxlZCA9IHN3aXBlci5jb250cm9sbGVyLmNvbnRyb2w7XG4gICAgICB2YXIgaTtcblxuICAgICAgZnVuY3Rpb24gc2V0Q29udHJvbGxlZFRyYW5zaXRpb24oYykge1xuICAgICAgICBjLnNldFRyYW5zaXRpb24oZHVyYXRpb24sIHN3aXBlcik7XG5cbiAgICAgICAgaWYgKGR1cmF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgYy50cmFuc2l0aW9uU3RhcnQoKTtcblxuICAgICAgICAgIGlmIChjLnBhcmFtcy5hdXRvSGVpZ2h0KSB7XG4gICAgICAgICAgICBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGMudXBkYXRlQXV0b0hlaWdodCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYy4kd3JhcHBlckVsLnRyYW5zaXRpb25FbmQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCFjb250cm9sbGVkKSByZXR1cm47XG5cbiAgICAgICAgICAgIGlmIChjLnBhcmFtcy5sb29wICYmIHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ3NsaWRlJykge1xuICAgICAgICAgICAgICBjLmxvb3BGaXgoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYy50cmFuc2l0aW9uRW5kKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udHJvbGxlZCkpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvbnRyb2xsZWQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBpZiAoY29udHJvbGxlZFtpXSAhPT0gYnlDb250cm9sbGVyICYmIGNvbnRyb2xsZWRbaV0gaW5zdGFuY2VvZiBTd2lwZXIpIHtcbiAgICAgICAgICAgIHNldENvbnRyb2xsZWRUcmFuc2l0aW9uKGNvbnRyb2xsZWRbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjb250cm9sbGVkIGluc3RhbmNlb2YgU3dpcGVyICYmIGJ5Q29udHJvbGxlciAhPT0gY29udHJvbGxlZCkge1xuICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNpdGlvbihjb250cm9sbGVkKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBDb250cm9sbGVyJDEgPSB7XG4gICAgbmFtZTogJ2NvbnRyb2xsZXInLFxuICAgIHBhcmFtczoge1xuICAgICAgY29udHJvbGxlcjoge1xuICAgICAgICBjb250cm9sOiB1bmRlZmluZWQsXG4gICAgICAgIGludmVyc2U6IGZhbHNlLFxuICAgICAgICBieTogJ3NsaWRlJyAvLyBvciAnY29udGFpbmVyJ1xuXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIGNvbnRyb2xsZXI6IF9leHRlbmRzKHtcbiAgICAgICAgICBjb250cm9sOiBzd2lwZXIucGFyYW1zLmNvbnRyb2xsZXIuY29udHJvbFxuICAgICAgICB9LCB
166Db250cm9sbGVyKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChzd2lwZXIuY29udHJvbGxlci5zcGxpbmUpIHtcbiAgICAgICAgICBzd2lwZXIuY29udHJvbGxlci5zcGxpbmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgZGVsZXRlIHN3aXBlci5jb250cm9sbGVyLnNwbGluZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlc2l6ZTogZnVuY3Rpb24gcmVzaXplKHN3aXBlcikge1xuICAgICAgICBpZiAoIXN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wpIHJldHVybjtcblxuICAgICAgICBpZiAoc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lKSB7XG4gICAgICAgICAgc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGRlbGV0ZSBzd2lwZXIuY29udHJvbGxlci5zcGxpbmU7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvYnNlcnZlclVwZGF0ZTogZnVuY3Rpb24gb2JzZXJ2ZXJVcGRhdGUoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChzd2lwZXIuY29udHJvbGxlci5zcGxpbmUpIHtcbiAgICAgICAgICBzd2lwZXIuY29udHJvbGxlci5zcGxpbmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgZGVsZXRlIHN3aXBlci5jb250cm9sbGVyLnNwbGluZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNldFRyYW5zbGF0ZTogZnVuY3Rpb24gc2V0VHJhbnNsYXRlKHN3aXBlciwgdHJhbnNsYXRlLCBieUNvbnRyb2xsZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIuY29udHJvbGxlci5jb250cm9sKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5jb250cm9sbGVyLnNldFRyYW5zbGF0ZSh0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcik7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihzd2lwZXIsIGR1cmF0aW9uLCBieUNvbnRyb2xsZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIuY29udHJvbGxlci5jb250cm9sKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5jb250cm9sbGVyLnNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBBMTF5ID0ge1xuICAgIG1ha2VFbEZvY3VzYWJsZTogZnVuY3Rpb24gbWFrZUVsRm9jdXNhYmxlKCRlbCkge1xuICAgICAgJGVsLmF0dHIoJ3RhYkluZGV4JywgJzAnKTtcbiAgICAgIHJldHVybiAkZWw7XG4gICAgfSxcbiAgICBtYWtlRWxOb3RGb2N1c2FibGU6IGZ1bmN0aW9uIG1ha2VFbE5vdEZvY3VzYWJsZSgkZWwpIHtcbiAgICAgICRlbC5hdHRyKCd0YWJJbmRleCcsICctMScpO1xuICAgICAgcmV0dXJuICRlbDtcbiAgICB9LFxuICAgIGFkZEVsUm9sZTogZnVuY3Rpb24gYWRkRWxSb2xlKCRlbCwgcm9sZSkge1xuICAgICAgJGVsLmF0dHIoJ3JvbGUnLCByb2xlKTtcbiAgICAgIHJldHVybiAkZWw7XG4gICAgfSxcbiAgICBhZGRFbExhYmVsOiBmdW5jdGlvbiBhZGRFbExhYmVsKCRlbCwgbGFiZWwpIHtcbiAgICAgICRlbC5hdHRyKCdhcmlhLWxhYmVsJywgbGFiZWwpO1xuICAgICAgcmV0dXJuICRlbDtcbiAgICB9LFxuICAgIGRpc2FibGVFbDogZnVuY3Rpb24gZGlzYWJsZUVsKCRlbCkge1xuICAgICAgJGVsLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgIHJldHVybiAkZWw7XG4gICAgfSxcbiAgICBlbmFibGVFbDogZnVuY3Rpb24gZW5hYmxlRWwoJGVsKSB7XG4gICAgICAkZWwuYXR0cignYXJpYS1kaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgIHJldHVybiAkZWw7XG4gICAgfSxcbiAgICBvbkVudGVyS2V5OiBmdW5jdGlvbiBvbkVudGVyS2V5KGUpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcbiAgICAgIGlmIChlLmtleUNvZGUgIT09IDEzKSByZXR1cm47XG4gICAgICB2Y
166XIgJHRhcmdldEVsID0gJChlLnRhcmdldCk7XG5cbiAgICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsICYmICR0YXJnZXRFbC5pcyhzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsKSkge1xuICAgICAgICBpZiAoIShzd2lwZXIuaXNFbmQgJiYgIXN3aXBlci5wYXJhbXMubG9vcCkpIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVOZXh0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3dpcGVyLmlzRW5kKSB7XG4gICAgICAgICAgc3dpcGVyLmExMXkubm90aWZ5KHBhcmFtcy5sYXN0U2xpZGVNZXNzYWdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzd2lwZXIuYTExeS5ub3RpZnkocGFyYW1zLm5leHRTbGlkZU1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi4kcHJldkVsICYmICR0YXJnZXRFbC5pcyhzd2lwZXIubmF2aWdhdGlvbi4kcHJldkVsKSkge1xuICAgICAgICBpZiAoIShzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMubG9vcCkpIHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVQcmV2KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3dpcGVyLmlzQmVnaW5uaW5nKSB7XG4gICAgICAgICAgc3dpcGVyLmExMXkubm90aWZ5KHBhcmFtcy5maXJzdFNsaWRlTWVzc2FnZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3dpcGVyLmExMXkubm90aWZ5KHBhcmFtcy5wcmV2U2xpZGVNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLnBhZ2luYXRpb24gJiYgJHRhcmdldEVsLmlzKFwiLlwiICsgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkge1xuICAgICAgICAkdGFyZ2V0RWxbMF0uY2xpY2soKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG5vdGlmeTogZnVuY3Rpb24gbm90aWZ5KG1lc3NhZ2UpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IHN3aXBlci5hMTF5LmxpdmVSZWdpb247XG4gICAgICBpZiAobm90aWZpY2F0aW9uLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgbm90aWZpY2F0aW9uLmh0bWwoJycpO1xuICAgICAgbm90aWZpY2F0aW9uLmh0bWwobWVzc2FnZSk7XG4gICAgfSxcbiAgICB1cGRhdGVOYXZpZ2F0aW9uOiBmdW5jdGlvbiB1cGRhdGVOYXZpZ2F0aW9uKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wIHx8ICFzd2lwZXIubmF2aWdhdGlvbikgcmV0dXJuO1xuICAgICAgdmFyIF9zd2lwZXIkbmF2aWdhdGlvbiA9IHN3aXBlci5uYXZpZ2F0aW9uLFxuICAgICAgICAgICRuZXh0RWwgPSBfc3dpcGVyJG5hdmlnYXRpb24uJG5leHRFbCxcbiAgICAgICAgICAkcHJldkVsID0gX3N3aXBlciRuYXZpZ2F0aW9uLiRwcmV2RWw7XG5cbiAgICAgIGlmICgkcHJldkVsICYmICRwcmV2RWwubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoc3dpcGVyLmlzQmVnaW5uaW5nKSB7XG4gICAgICAgICAgc3dpcGVyLmExMXkuZGlzYWJsZUVsKCRwcmV2RWwpO1xuICAgICAgICAgIHN3aXBlci5hMTF5Lm1ha2VFbE5vdEZvY3VzYWJsZSgkcHJldkVsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzd2lwZXIuYTExeS5lbmFibGVFbCgkcHJldkVsKTtcbiAgICAgICAgICBzd2lwZXIuYTExeS5tYWtlRWxGb2N1c2FibGUoJHByZXZFbCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCRuZXh0RWwgJiYgJG5leHRFbC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGlmIChzd2lwZXIuaXNFbmQpIHtcbiAgICAgICAgICBzd2lwZXIuYTExeS5kaXNhYmxlRWwoJG5leHRFbCk7XG4gICAgICAgICAgc3dpcGVyLmExMXkubWFrZUVsTm90Rm9jdXNhYmxlKCRuZXh0RWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN3aXBlci5hMTF5LmVuYWJsZUVsKCRuZXh0RWwpO1xuICAgICAgICAgIHN3aXBlci5hMTF5Lm1ha2VFbEZvY3VzYWJsZSgkbmV4dEVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgdXBkYXRlUGFnaW5hdGlvbjogZnVuY3Rpb24gdXBkYXRlUGFnaW5hdGlvbigpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcblxuICAgICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uICYmIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5jbGlja2FibGUgJiYgc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cyAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLmxlbmd0aCkge1xuICAgICAgICBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLmVhY2goZnVuY3Rpb24gKGJ1bGxldEVsKSB7XG4gICAgICAgICAgdmFyICRidWxsZXRFbCA9ICQoYnVsbGV0RWwpO1xuICAgICAgICAgIHN3aXBlci5hMTF5Lm1ha2VFbEZvY3VzYWJsZSgkYnVsbGV0RWwpO1xuICAgICAgICAgIHN3aXBlci5hMTF5LmFkZEVsUm9sZSgkYnVsbGV0RWwsICdidXR0b24nKTtcbiAgICAgICAgICBzd2lwZXIuYTExeS5hZGRFbExhYmVsKCRidWxsZXRFbCwgcGFyYW1zLnBhZ2luYXRpb25CdWxsZXRNZXNzYWdlLnJlcGxhY2UoL1xce1xce2luZGV4XFx9XFx9LywgJGJ1bGxldEVsLmluZGV4KCkgKyAxKSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgc3dpcGVyLiRlbC5hcHBlbmQoc3dpcGVyLmExMXkubGl2ZVJlZ2lvbik7IC8vIE5hdmlnYXRpb25cblxuICAgICAgdmFyIHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcbiAgICAgIHZhciAkbmV4dEVsO1xuICAgICAgdmFyICRwcmV2RWw7XG5cbiAgICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsKSB7XG4gICAgICAgICRuZXh0RWwgPSBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24gJiYgc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbCkge1xuICAgICAgICAkcHJldkVsID0gc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbDtcbiAgICAgIH1cblxuICAgICAgaWYgKCRuZXh0RWwpIHtcbiAgICAgICAgc3dpcGVyLmExMXkubWFrZUVsRm9jdXNhYmxlKCRuZXh0RWwpO1xuICAgICAgICBzd2lwZXIuYTExeS5hZGRFbFJvbGUoJG5leHRFbCwgJ2J1dHRvbicpO1xuICAgICAgICBzd2lwZXIuYTExeS5hZGRFbExhYmVsKCRuZXh0RWwsIHBhcmFtcy5uZXh0U2xpZGVNZXNzYWdlKTtcbiAgICAgICAgJG5leHRFbC5vbigna2V5ZG93bicsIHN3aXBlci5hMTF5Lm9uRW50ZXJLZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoJHByZXZFbCkge1xuICAgICAgICBzd2lwZXIuYTExeS5tYWtlRWxGb2N1c2FibGUoJHByZX
166ZFbCk7XG4gICAgICAgIHN3aXBlci5hMTF5LmFkZEVsUm9sZSgkcHJldkVsLCAnYnV0dG9uJyk7XG4gICAgICAgIHN3aXBlci5hMTF5LmFkZEVsTGFiZWwoJHByZXZFbCwgcGFyYW1zLnByZXZTbGlkZU1lc3NhZ2UpO1xuICAgICAgICAkcHJldkVsLm9uKCdrZXlkb3duJywgc3dpcGVyLmExMXkub25FbnRlcktleSk7XG4gICAgICB9IC8vIFBhZ2luYXRpb25cblxuXG4gICAgICBpZiAoc3dpcGVyLnBhZ2luYXRpb24gJiYgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmNsaWNrYWJsZSAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMubGVuZ3RoKSB7XG4gICAgICAgIHN3aXBlci5wYWdpbmF0aW9uLiRlbC5vbigna2V5ZG93bicsIFwiLlwiICsgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzLCBzd2lwZXIuYTExeS5vbkVudGVyS2V5KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmIChzd2lwZXIuYTExeS5saXZlUmVnaW9uICYmIHN3aXBlci5hMTF5LmxpdmVSZWdpb24ubGVuZ3RoID4gMCkgc3dpcGVyLmExMXkubGl2ZVJlZ2lvbi5yZW1vdmUoKTtcbiAgICAgIHZhciAkbmV4dEVsO1xuICAgICAgdmFyICRwcmV2RWw7XG5cbiAgICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsKSB7XG4gICAgICAgICRuZXh0RWwgPSBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24gJiYgc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbCkge1xuICAgICAgICAkcHJldkVsID0gc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbDtcbiAgICAgIH1cblxuICAgICAgaWYgKCRuZXh0RWwpIHtcbiAgICAgICAgJG5leHRFbC5vZmYoJ2tleWRvd24nLCBzd2lwZXIuYTExeS5vbkVudGVyS2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCRwcmV2RWwpIHtcbiAgICAgICAgJHByZXZFbC5vZmYoJ2tleWRvd24nLCBzd2lwZXIuYTExeS5vbkVudGVyS2V5KTtcbiAgICAgIH0gLy8gUGFnaW5hdGlvblxuXG5cbiAgICAgIGlmIChzd2lwZXIucGFnaW5hdGlvbiAmJiBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uY2xpY2thYmxlICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMgJiYgc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cy5sZW5ndGgpIHtcbiAgICAgICAgc3dpcGVyLnBhZ2luYXRpb24uJGVsLm9mZigna2V5ZG93bicsIFwiLlwiICsgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzLCBzd2lwZXIuYTExeS5vbkVudGVyS2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBBMTF5JDEgPSB7XG4gICAgbmFtZTogJ2ExMXknLFxuICAgIHBhcmFtczoge1xuICAgICAgYTExeToge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICBub3RpZmljYXRpb25DbGFzczogJ3N3aXBlci1ub3RpZmljYXRpb24nLFxuICAgICAgICBwcmV2U2xpZGVNZXNzYWdlOiAnUHJldmlvdXMgc2xpZGUnLFxuICAgICAgICBuZXh0U2xpZGVNZXNzYWdlOiAnTmV4dCBzbGlkZScsXG4gICAgICAgIGZpcnN0U2xpZGVNZXNzYWdlOiAnVGhpcyBpcyB0aGUgZmlyc3Qgc2xpZGUnLFxuICAgICAgICBsYXN0U2xpZGVNZXNzYWdlOiAnVGhpcyBpcyB0aGUgbGFzdCBzbGlkZScsXG4gICAgICAgIHBhZ2luYXRpb25CdWxsZXRNZXNzYWdlOiAnR28gdG8gc2xpZGUge3tpbmRleH19J1xuICAgICAgfVxuICAgIH0sXG4gICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIGJpbmRNb2R1bGVNZXRob2RzKHN3aXBlciwge1xuICAgICAgICBhMTF5OiBfZXh0ZW5kcyhfZXh0ZW5kcyh7fSwgQTExeSksIHt9LCB7XG4gICAgICAgICAgbGl2ZVJlZ2lvbjogJChcIjxzcGFuIGNsYXNzPVxcXCJcIiArIHN3aXBlci5wYXJhbXMuYTExeS5ub3RpZmljYXRpb25DbGFzcyArIFwiXFxcIiBhcmlhLWxpdmU9XFxcImFzc2VydGl2ZVxcXCIgYXJpYS1hdG9taWM9XFxcInRydWVcXFwiPjwvc3Bhbj5cIilcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmExMXkuaW5pdCgpO1xuICAgICAgICBzd2lwZXIuYTExeS51cGRhdGVOYXZpZ2F0aW9uKCk7XG4gICAgICB9LFxuICAgICAgdG9FZGdlOiBmdW5jdGlvbiB0b0VkZ2Uoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmExMXkudXBkYXRlTmF2aWdhdGlvbigpO1xuICAgICAgfSxcbiAgICAgIGZyb21FZGdlOiBmdW5jdGlvbiBmcm9tRWRnZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuYTExeS51cGRhdGVOYXZpZ2F0aW9uKCk7XG4gICAgICB9LFxuICAgICAgcGFnaW5hdGlvblVwZGF0ZTogZnVuY3Rpb24gcGFnaW5hdGlvblVwZGF0ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuYTExeS51cGRhdGVQYWdpbmF0aW9uKCk7XG4gICAgICB9LFxuICAgICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuYTExeS5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBIaXN0b3J5ID0ge1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5oaXN0b3J5KSByZXR1cm47XG5cbiAgICAgIGlmICghd2luZG93Lmhpc3RvcnkgfHwgIXdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSkge1xuICAgICAgICBzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICBzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gc3dpcGVyLmhpc3Rvcnk7XG4gICAgICBoaXN0b3J5LmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIGhpc3RvcnkucGF0aHMgPSBIaXN0b3J5LmdldFBhdGhWYWx1ZXMoc3dpcGVyLnBhcmFtcy51cmwpO1xuICAgICAgaWYgKCFoaXN0b3J5LnBhdGhzLmtleSAmJiAhaGlzdG9yeS5wYXRocy52YWx1ZSkgcmV0dXJuO1xuICAgICAgaGlzdG9yeS5zY3JvbGxUb1NsaWRlKDAsIGhpc3RvcnkucGF0aHMudmFsdWUsIHN3aXBlci5wYXJhbXMucnVuQ2FsbGJhY2tzT25Jbml0KTtcblxuICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIHN3aXBlci5oaXN0b3J5LnNldEhpc3RvcnlQb3BTdGF0ZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSkge1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBzd2lwZXIuaGlzdG9yeS5zZXRIaXN0b3J5UG9wU3RhdGUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2V0SGlzdG9yeVBvcFN0YXRlOiBmdW5jdGlvbiBzZXRIaXN0b3J5UG9wU3RhdGUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHN3aXBlci5oaXN0b3J5LnBhdGhzID0gSGlzdG9yeS5nZXRQYXRoVmFsdWVzKHN3aXBlci5wYXJhbXMudXJsKTtcbiAgICAgIHN3aXBlci5oaXN0b3J5LnNjcm9sbFRvU2xpZGUoc3dpcGVyLnBhcmFtcy5zcGVlZCwgc3dpcGVyLmhpc3RvcnkucGF0aHMudmFsdWUsIGZhbHNlKTtcbiAgICB9LFxuICAgIGdldFBhdGhWYWx1ZXM6IGZ1bmN0aW9uIGdldFBhdGhWYWx1ZXModXJsT3ZlcnJpZGUpIHtcbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgIHZhciBsb2NhdGlvbjtcblxuICAgICAgaWYgKHVybE92ZXJyaWRlKSB7XG4gICAgICAgIGxvY2F0aW9uID0gbmV3IFVSTCh1cmxPdmVycmlkZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIHBhdGhBcnJheSA9IGxvY2F0aW9uLnBhdGhuYW1lLnNsaWNlKDEpLnNwbGl0KCcvJykuZmlsdGVyKGZ1bmN0aW9uIChwYXJ0KSB7XG4gICAgICAgIHJldHVybiBwYXJ0ICE9PSAnJztcbiAgICAgIH0pO1xuICAgICAgdmFyIHRvdGFsID0gcGF0aEFycmF5Lmxlbmd0aDtcbiAgICAgIHZhciBrZXkgPSBwYXRoQXJyYXlbdG90YWwgLSAyXTtcbiAgICAgIHZhciB2YWx1ZSA9IHBhdGhBcnJheVt0b3RhbCAtIDFdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBrZXksXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9LFxuICAgIHNldEhpc3Rvcnk6IGZ1bmN0aW9uIHNldEhpc3Rvcnkoa2V5LCBpbmRleCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgICBpZiAoIXN3aXBlci5oaXN0b3J5LmluaXRpYWxpemVkIHx8ICFzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgdmFyIGxvY2F0aW9uO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy51cmwpIHtcbiAgICAgICAgbG9jYXRpb24gPSBuZXcgVVJMKHN3aXBlci5wYXJhbXMudXJsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKGluZGV4KTtcbiAgICAgIHZhciB2YWx1ZSA9IEhpc3Rvcnkuc2x1Z2lmeShzbGlkZS5hdHRyKCdkYXRhLWhpc3RvcnknKSk7XG5cbiAgICAgIGlmICghbG9jYXRpb24ucGF0aG5hbWUuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICB2YWx1ZSA9IGtleSArIFwiL1wiICsgdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBjdXJyZW50U3RhdGUgPSB3aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblxuICAgICAgaWYgKGN1cnJlbnRTdGF0ZSAmJiBjdXJyZW50U3RhdGUudmFsdWUgPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuaGlzdG9yeS5yZXBsYWNlU3RhdGUpIHtcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgfSwgbnVsbCwgdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgfSwgbnVsbCwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2x1Z2lmeTogZnVuY3Rpb24gc2x1Z2lmeSh0ZXh0KSB7XG4gICAgICByZXR1cm4gdGV4dC50b1N0cmluZygpLnJlcGxhY2UoL1xccysvZywgJy0nKS5yZXBsYWNlKC9bXlxcdy1dKy9nLCAnJykucmVwbGFjZSgvLS0rL2csICctJykucmVwbGFjZSgvXi0rLywgJycpLnJlcGxhY2UoLy0rJC8sICcnKTtcbiAgICB9LFxuICAgIHNjcm9sbFRvU2xpZGU6IGZ1bmN0aW9uIHNjcm9sbFRvU2xpZGUoc3BlZWQsIHZhbHVlLCBydW5DYWxsYmFja3MpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuXG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHN3aXBlci5zbGlkZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICB2Y
166XIgc2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKGkpO1xuICAgICAgICAgIHZhciBzbGlkZUhpc3RvcnkgPSBIaXN0b3J5LnNsdWdpZnkoc2xpZGUuYXR0cignZGF0YS1oaXN0b3J5JykpO1xuXG4gICAgICAgICAgaWYgKHNsaWRlSGlzdG9yeSA9PT0gdmFsdWUgJiYgIXNsaWRlLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcykpIHtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHNsaWRlLmluZGV4KCk7XG4gICAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhpbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbygwLCBzcGVlZCwgcnVuQ2FsbGJhY2tzKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBIaXN0b3J5JDEgPSB7XG4gICAgbmFtZTogJ2hpc3RvcnknLFxuICAgIHBhcmFtczoge1xuICAgICAgaGlzdG9yeToge1xuICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgcmVwbGFjZVN0YXRlOiBmYWxzZSxcbiAgICAgICAga2V5OiAnc2xpZGVzJ1xuICAgICAgfVxuICAgIH0sXG4gICAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGJpbmRNb2R1bGVNZXRob2RzKHN3aXBlciwge1xuICAgICAgICBoaXN0b3J5OiBfZXh0ZW5kcyh7fSwgSGlzdG9yeSlcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci5oaXN0b3J5LmluaXQoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci5oaXN0b3J5LmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRyYW5zaXRpb25FbmQ6IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIuaGlzdG9yeS5pbml0aWFsaXplZCkge1xuICAgICAgICAgIHN3aXBlci5oaXN0b3J5LnNldEhpc3Rvcnkoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmtleSwgc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNsaWRlQ2hhbmdlOiBmdW5jdGlvbiBzbGlkZUNoYW5nZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKHN3aXBlci5oaXN0b3J5LmluaXRpYWxpemVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgICAgIHN3aXBlci5oaXN0b3J5LnNldEhpc3Rvcnkoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmtleSwgc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgSGFzaE5hdmlnYXRpb24gPSB7XG4gICAgb25IYXNoQ2FuZ2U6IGZ1bmN0aW9uIG9uSGFzaENhbmdlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgc3dpcGVyLmVtaXQoJ2hhc2hDaGFuZ2UnKTtcbiAgICAgIHZhciBuZXdIYXNoID0gZG9jdW1lbnQubG9jYXRpb24uaGFzaC5yZXBsYWNlKCcjJywgJycpO1xuICAgICAgdmFyIGFjdGl2ZVNsaWRlSGFzaCA9IHN3aXBlci5zbGlkZXMuZXEoc3dpcGVyLmFjdGl2ZUluZGV4KS5hdHRyKCdkYXRhLWhhc2gnKTtcblxuICAgICAgaWYgKG5ld0hhc2ggIT09IGFjdGl2ZVNsaWRlSGFzaCkge1xuICAgICAgICB2YXIgbmV3SW5kZXggPSBzd2lwZXIuJHdyYXBwZXJFbC5jaGlsZHJlbihcIi5cIiArIHN3aXBlci5wYXJhbXMuc2xpZGVDbGFzcyArIFwiW2RhdGEtaGFzaD1cXFwiXCIgKyBuZXdIYXNoICsgXCJcXFwiXVwiKS5pbmRleCgpO1xuICAgICAgICBpZiAodHlwZW9mIG5ld0luZGV4ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhuZXdJbmRleCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzZXRIYXNoOiBmdW5jdGlvbiBzZXRIYXNoKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgICB2YXIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgaWYgKCFzd2lwZXIuaGFzaE5hdmlnYXRpb24uaW5pdGlhbGl6ZWQgfHwgIXN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZW5hYmxlZCkgcmV0dXJuO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5yZXBsYWNlU3RhdGUgJiYgd2luZG93Lmhpc3RvcnkgJiYgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBudWxsLCBcIiNcIiArIHN3aXBlci5zbGlkZXMuZXEoc3dpcGVyLmFjdGl2ZUluZGV4KS5hdHRyKCdkYXRhLWhhc2gnKSB8fCAnJyk7XG4gICAgICAgIHN3aXBlci5lbWl0KCdoYXNoU2V0Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2Y
166XIgc2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICAgIHZhciBoYXNoID0gc2xpZGUuYXR0cignZGF0YS1oYXNoJykgfHwgc2xpZGUuYXR0cignZGF0YS1oaXN0b3J5Jyk7XG4gICAgICAgIGRvY3VtZW50LmxvY2F0aW9uLmhhc2ggPSBoYXNoIHx8ICcnO1xuICAgICAgICBzd2lwZXIuZW1pdCgnaGFzaFNldCcpO1xuICAgICAgfVxuICAgIH0sXG4gICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5lbmFibGVkIHx8IHN3aXBlci5wYXJhbXMuaGlzdG9yeSAmJiBzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkgcmV0dXJuO1xuICAgICAgc3dpcGVyLmhhc2hOYXZpZ2F0aW9uLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHZhciBoYXNoID0gZG9jdW1lbnQubG9jYXRpb24uaGFzaC5yZXBsYWNlKCcjJywgJycpO1xuXG4gICAgICBpZiAoaGFzaCkge1xuICAgICAgICB2YXIgc3BlZWQgPSAwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBzd2lwZXIuc2xpZGVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIHNsaWRlID0gc3dpcGVyLnNsaWRlcy5lcShpKTtcbiAgICAgICAgICB2YXIgc2xpZGVIYXNoID0gc2xpZGUuYXR0cignZGF0YS1oYXNoJykgfHwgc2xpZGUuYXR0cignZGF0YS1oaXN0b3J5Jyk7XG5cbiAgICAgICAgICBpZiAoc2xpZGVIYXNoID09PSBoYXNoICYmICFzbGlkZS5oYXNDbGFzcyhzd2lwZXIucGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKSB7XG4gICAgICAgICAgICB2Y
166XIgaW5kZXggPSBzbGlkZS5pbmRleCgpO1xuICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG8oaW5kZXgsIHNwZWVkLCBzd2lwZXIucGFyYW1zLnJ1bkNhbGxiYWNrc09uSW5pdCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLndhdGNoU3RhdGUpIHtcbiAgICAgICAgJCh3aW5kb3cpLm9uKCdoYXNoY2hhbmdlJywgc3dpcGVyLmhhc2hOYXZpZ2F0aW9uLm9uSGFzaENhbmdlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coKTtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24ud2F0Y2hTdGF0ZSkge1xuICAgICAgICAkKHdpbmRvdykub2ZmKCdoYXNoY2hhbmdlJywgc3dpcGVyLmhhc2hOYXZpZ2F0aW9uLm9uSGFzaENhbmdlKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBIYXNoTmF2aWdhdGlvbiQxID0ge1xuICAgIG5hbWU6ICdoYXNoLW5hdmlnYXRpb24nLFxuICAgIHBhcmFtczoge1xuICAgICAgaGFzaE5hdmlnYXRpb246IHtcbiAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgIHJlcGxhY2VTdGF0ZTogZmFsc2UsXG4gICAgICAgIHdhdGNoU3RhdGU6IGZhbHNlXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIGhhc2hOYXZpZ2F0aW9uOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgaW5pdGlhbGl6ZWQ6IGZhbHNlXG4gICAgICAgIH0sIEhhc2hOYXZpZ2F0aW9uKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci5oYXNoTmF2aWdhdGlvbi5pbml0KCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5lbmFibGVkKSB7XG4gICAgICAgICAgc3dpcGVyLmhhc2hOYXZpZ2F0aW9uLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRyYW5zaXRpb25FbmQ6IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIuaGFzaE5hdmlnYXRpb24uaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICBzd2lwZXIuaGFzaE5hdmlnYXRpb24uc2V0SGFzaCgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc2xpZGVDaGFuZ2U6IGZ1bmN0aW9uIHNsaWRlQ2hhbmdlKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLmhhc2hOYXZpZ2F0aW9uLmluaXRpYWxpemVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgICAgIHN3aXBlci5oYXNoTmF2aWdhdGlvbi5zZXRIYXNoKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIEF1dG9wbGF5ID0ge1xuICAgIHJ1bjogZnVuY3Rpb24gcnVuKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2YXIgJGFjdGl2ZVNsaWRlRWwgPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICB2Y
166XIgZGVsYXkgPSBzd2lwZXIucGFyYW1zLmF1dG9wbGF5LmRlbGF5O1xuXG4gICAgICBpZiAoJGFjdGl2ZVNsaWRlRWwuYXR0cignZGF0YS1zd2lwZXItYXV0b3BsYXknKSkge1xuICAgICAgICBkZWxheSA9ICRhY3RpdmVTbGlkZUVsLmF0dHIoJ2RhdGEtc3dpcGVyLWF1dG9wbGF5JykgfHwgc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kZWxheTtcbiAgICAgIH1cblxuICAgICAgY2xlYXJUaW1lb3V0KHN3aXBlci5hdXRvcGxheS50aW1lb3V0KTtcbiAgICAgIHN3aXBlci5hdXRvcGxheS50aW1lb3V0ID0gbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5yZXZlcnNlRGlyZWN0aW9uKSB7XG4gICAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgICAgICAgICAgIHN3aXBlci5zbGlkZVByZXYoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICBzd2lwZXIuZW1pdCgnYXV0b3BsYXknKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFzd2lwZXIuaXNCZWdpbm5pbmcpIHtcbiAgICAgICAgICAgIHN3aXBlci5zbGlkZVByZXYoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICBzd2lwZXIuZW1pdCgnYXV0b3BsYXknKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFzd2lwZXIucGFyYW1zLmF1dG9wbGF5LnN0b3BPbkxhc3RTbGlkZSkge1xuICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxLCBzd2lwZXIucGFyYW1zLnNwZWVkLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgICAgIHN3aXBlci5lbWl0KCdhdXRvcGxheScpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzd2lwZXIuYXV0b3BsYXkuc3RvcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgICAgICBzd2lwZXIubG9vcEZpeCgpO1xuICAgICAgICAgIHN3aXBlci5zbGlkZU5leHQoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgc3dpcGVyLmVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXN3aXBlci5pc0VuZCkge1xuICAgICAgICAgIHN3aXBlci5zbGlkZU5leHQoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgc3dpcGVyLmVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkuc3RvcE9uTGFzdFNsaWRlKSB7XG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oMCwgc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgc3dpcGVyLmVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnN0b3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUgJiYgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHN3aXBlci5hdXRvcGxheS5ydW4oKTtcbiAgICAgIH0sIGRlbGF5KTtcbiAgICB9LFxuICAgIHN0YXJ0OiBmdW5jdGlvbiBzdGFydCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKHR5cGVvZiBzd2lwZXIuYXV0b3BsYXkudGltZW91dCAhPT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcbiAgICAgIGlmIChzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcmV0dXJuIGZhbHNlO1xuICAgICAgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcgPSB0cnVlO1xuICAgICAgc3dpcGVyLmVtaXQoJ2F1dG9wbGF5U3RhcnQnKTtcbiAgICAgIHN3aXBlci5hdXRvcGxheS5ydW4oKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG4gICAgc3RvcDogZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKCFzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHR5cGVvZiBzd2lwZXIuYXV0b3BsYXkudGltZW91dCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcblxuICAgICAgaWYgKHN3aXBlci5hdXRvcGxheS50aW1lb3V0KSB7XG4gICAgICAgIGNsZWFyVGltZW91dChzd2lwZXIuYXV0b3BsYXkudGltZW91dCk7XG4gICAgICAgIHN3aXBlci5hdXRvcGxheS50aW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIuYXV0b3BsYXkucnVubmluZyA9IGZhbHNlO1xuICAgICAgc3dpcGVyLmVtaXQoJ2F1dG9wbGF5U3RvcCcpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBwYXVzZTogZnVuY3Rpb24gcGF1c2Uoc3BlZWQpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgaWYgKCFzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcmV0dXJuO1xuICAgICAgaWYgKHN3aXBlci5hdXRvcGxheS5wYXVzZWQpIHJldHVybjtcbiAgICAgIGlmIChzd2lwZXIuYXV0b3BsYXkudGltZW91dCkgY2xlYXJUaW1lb3V0KHN3aXBlci5hdXRvcGxheS50aW1lb3V0KTtcbiAgICAgIHN3aXBlci5hdXRvcGxheS5wYXVzZWQgPSB0cnVlO1xuXG4gICAgICBpZiAoc3BlZWQgPT09IDAgfHwgIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkud2FpdEZvclRyYW5zaXRpb24pIHtcbiAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCA9IGZhbHNlO1xuICAgICAgICBzd2lwZXIuYXV0b3BsYXkucnVuKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgc3dpcGVyLmF1dG9wbGF5Lm9uVHJhbnNpdGlvbkVuZCk7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCBzd2lwZXIuYXV0b3BsYXkub25UcmFuc2l0aW9uRW5kKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9uVmlzaWJpbGl0eUNoYW5nZTogZnVuY3Rpb24gb25WaXNpYmlsaXR5Q2hhbmdlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgICBpZiAoZG9jdW1lbnQudmlzaWJpbGl0eVN0YXRlID09PSAnaGlkZGVuJyAmJiBzd2lwZXIuYXV0b3BsYXkucnVubmluZykge1xuICAgICAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2UoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gJ3Zpc2libGUnICYmIHN3aXBlci5hdXRvcGxheS5wYXVzZWQpIHtcbiAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnJ1bigpO1xuICAgICAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcbiAgICBvblRyYW5zaXRpb25FbmQ6IGZ1bmN0aW9uIG9uVHJhbnNpdGlvbkVuZChlKSB7XG4gICAgICB2YXIgc3dpcGVyID0gdGhpcztcbiAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci4kd3JhcHBlckVsKSByZXR1cm47XG4gICAgICBpZiAoZS50YXJnZXQgIT09IHN3aXBlci4kd3JhcHBlckVsWzBdKSByZXR1cm47XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgc3dpcGVyLmF1dG9wbGF5Lm9uVHJhbnNpdGlvbkVuZCk7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJraXRUcmFuc2l0aW9uRW5kJywgc3dpcGVyLmF1dG9wbGF5Lm9uVHJhbnNpdGlvbkVuZCk7XG4gICAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gZmFsc2U7XG5cbiAgICAgIGlmICghc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHtcbiAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnN0b3AoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5hdXRvcGxheS5ydW4oKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBBdXRvcGxheSQxID0ge1xuICAgIG5hbWU6ICdhdXRvcGxheScsXG4gICAgcGFyYW1zOiB7XG4gICAgICBhdXRvcGxheToge1xuICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgZGVsYXk6IDMwMDAsXG4gICAgICAgIHdhaXRGb3JUcmFuc2l0aW9uOiB0cnVlLFxuICAgICAgICBkaXNhYmxlT25JbnRlcmFjdGlvbjogdHJ1ZSxcbiAgICAgICAgc3RvcE9uTGFzdFNsaWRlOiBmYWxzZSxcbiAgICAgICAgcmV2ZXJzZURpcmVjdGlvbjogZmFsc2VcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgYXV0b3BsYXk6IF9leHRlbmRzKF9leHRlbmRzKHt9LCBBdXRvcGxheSksIHt9LCB7XG4gICAgICAgICAgcnVubmluZzogZmFsc2UsXG4gICAgICAgICAgcGF1c2VkOiBmYWxzZVxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZW5hYmxlZCkge1xuICAgICAgICAgIHN3aXBlci5hdXRvcGxheS5zdGFydCgpO1xuICAgICAgICAgIHZhciBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndmlzaWJpbGl0eWNoYW5nZScsIHN3aXBlci5hdXRvcGxheS5vblZpc2liaWxpdHlDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYmVmb3JlVHJhbnNpdGlvblN0YXJ0OiBmdW5jdGlvbiBiZWZvcmVUcmFuc2l0aW9uU3RhcnQoc3dpcGVyLCBzcGVlZCwgaW50ZXJuYWwpIHtcbiAgICAgICAgaWYgKHN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSB7XG4gICAgICAgICAgaWYgKGludGVybmFsIHx8ICFzd2lwZXIucGFyYW1zLmF1dG9wbGF5LmRpc2FibGVPbkludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2Uoc3BlZWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzd2lwZXIuYXV0b3BsYXkuc3RvcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNsaWRlckZpcnN0TW92ZTogZnVuY3Rpb24gc2xpZGVyRmlyc3RNb3ZlKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHtcbiAgICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kaXNhYmxlT25JbnRlcmFjdGlvbikge1xuICAgICAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnN0b3AoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdG91Y2hFbmQ6IGZ1bmN0aW9uIHRvdWNoRW5kKHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlICYmIHN3aXBlci5hdXRvcGxheS5wYXVzZWQgJiYgIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcbiAgICAgICAgICBzd2lwZXIuYXV0b3BsYXkucnVuKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHtcbiAgICAgICAgICBzd2lwZXIuYXV0b3BsYXkuc3RvcCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndmlzaWJpbGl0eWNoYW5nZScsIHN3aXBlci5hdXRvcGxheS5vblZpc2liaWxpdHlDaGFuZ2UpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgRmFkZSA9IHtcbiAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHNsaWRlcyA9IHN3aXBlci5zbGlkZXM7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHZhciAkc2xpZGVFbCA9IHN3aXBlci5zbGlkZXMuZXEoaSk7XG4gICAgICAgIHZhciBvZmZzZXQgPSAkc2xpZGVFbFswXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgICAgdmFyIHR4ID0gLW9mZnNldDtcbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnZpcnR1YWxUcmFuc2xhdGUpIHR4IC09IHN3aXBlci50cmFuc2xhdGU7XG4gICAgICAgIHZhciB0eSA9IDA7XG5cbiAgICAgICAgaWYgKCFzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgICB0eSA9IHR4O1xuICAgICAgICAgIHR4ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzbGlkZU9wYWNpdHkgPSBzd2lwZXIucGFyYW1zLmZhZGVFZmZlY3QuY3Jvc3NGYWRlID8gTWF0aC5tYXgoMSAtIE1hdGguYWJzKCRzbGlkZUVsWzBdLnByb2dyZXNzKSwgMCkgOiAxICsgTWF0aC5taW4oTWF0aC5tYXgoJHNsaWRlRWxbMF0ucHJvZ3Jlc3MsIC0xKSwgMCk7XG4gICAgICAgICRzbGlkZUVsLmNzcyh7XG4gICAgICAgICAgb3BhY2l0eTogc2xpZGVPcGFjaXR5XG4gICAgICAgIH0pLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKFwiICsgdHggKyBcInB4LCBcIiArIHR5ICsgXCJweCwgMHB4KVwiKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHNldFRyYW5zaXRpb246IGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24pIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHNsaWRlcyA9IHN3aXBlci5zbGlkZXMsXG4gICAgICAgICAgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsO1xuICAgICAgc2xpZGVzLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsVHJhbnNsYXRlICYmIGR1cmF0aW9uICE9PSAwKSB7XG4gICAgICAgIHZhciBldmVudFRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICBzbGlkZXMudHJhbnNpdGlvbkVuZChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKGV2ZW50VHJpZ2dlcmVkKSByZXR1cm47XG4gICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgICAgICAgIGV2ZW50VHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgICAgICBzd2lwZXIuYW5pbWF0aW5nID0gZmFsc2U7XG4gICAgICAgICAgdmFyIHRyaWdnZXJFdmVudHMgPSBbJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCAndHJhbnNpdGlvbmVuZCddO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0cmlnZ2VyRXZlbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAkd3JhcHBlckVsLnRyaWdnZXIodHJpZ2dlckV2ZW50c1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHZhciBFZmZlY3RGYWRlID0ge1xuICAgIG5hbWU6ICdlZmZlY3QtZmFkZScsXG4gICAgcGFyYW1zOiB7XG4gICAgICBmYWRlRWZmZWN0OiB7XG4gICAgICAgIGNyb3NzRmFkZTogZmFsc2VcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgZmFkZUVmZmVjdDogX2V4dGVuZHMoe30sIEZhZGUpXG4gICAgICB9KTtcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBiZWZvcmVJbml0OiBmdW5jdGlvbiBiZWZvcmVJbml0KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5lZmZlY3QgIT09ICdmYWRlJykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwiZmFkZVwiKTtcbiAgICAgICAgdmFyIG92ZXJ3cml0ZVBhcmFtcyA9IHtcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgI
166HNsaWRlc1BlckNvbHVtbjogMSxcbiAgICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICB2aXJ0dWFsVHJhbnNsYXRlOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5wYXJhbXMsIG92ZXJ3cml0ZVBhcmFtcyk7XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5vcmlnaW5hbFBhcmFtcywgb3ZlcndyaXRlUGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSAnZmFkZScpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmZhZGVFZmZlY3Quc2V0VHJhbnNsYXRlKCk7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihzd2lwZXIsIGR1cmF0aW9uKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gJ2ZhZGUnKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5mYWRlRWZmZWN0LnNldFRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgQ3ViZSA9IHtcbiAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyICRlbCA9IHN3aXBlci4kZWwsXG4gICAgICAgICAgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsLFxuICAgICAgICAgIHNsaWRlcyA9IHN3aXBlci5zbGlkZXMsXG4gICAgICAgICAgc3dpcGVyV2lkdGggPSBzd2lwZXIud2lkdGgsXG4gICAgICAgICAgc3dpcGVySGVpZ2h0ID0gc3dpcGVyLmhlaWdodCxcbiAgICAgICAgICBydGwgPSBzd2lwZXIucnRsVHJhbnNsYXRlLFxuICAgICAgICAgIHN3aXBlclNpemUgPSBzd2lwZXIuc2l6ZSxcbiAgICAgICAgICBicm93c2VyID0gc3dpcGVyLmJyb3dzZXI7XG4gICAgICB2Y
166XIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0O1xuICAgICAgdmFyIGlzSG9yaXpvbnRhbCA9IHN3aXBlci5pc0hvcml6b250YWwoKTtcbiAgICAgIHZhciBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgICAgIHZhciB3cmFwcGVyUm90YXRlID0gMDtcbiAgICAgIHZhciAkY3ViZVNoYWRvd0VsO1xuXG4gICAgICBpZiAocGFyYW1zLnNoYWRvdykge1xuICAgICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICAgJGN1YmVTaGFkb3dFbCA9ICR3cmFwcGVyRWwuZmluZCgnLnN3aXBlci1jdWJlLXNoYWRvdycpO1xuXG4gICAgICAgICAgaWYgKCRjdWJlU2hhZG93RWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkY3ViZVNoYWRvd0VsID0gJCgnPGRpdiBjbGFzcz1cInN3aXBlci1jdWJlLXNoYWRvd1wiPjwvZGl2PicpO1xuICAgICAgICAgICAgJHdyYXBwZXJFbC5hcHBlbmQoJGN1YmVTaGFkb3dFbCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgJGN1YmVTaGFkb3dFbC5jc3Moe1xuICAgICAgICAgICAgaGVpZ2h0OiBzd2lwZXJXaWR0aCArIFwicHhcIlxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICRjdWJlU2hhZG93RWwgPSAkZWwuZmluZCgnLnN3aXBlci1jdWJlLXNoYWRvdycpO1xuXG4gICAgICAgICAgaWYgKCRjdWJlU2hhZG93RWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkY3ViZVNoYWRvd0VsID0gJCgnPGRpdiBjbGFzcz1cInN3aXBlci1jdWJlLXNoYWRvd1wiPjwvZGl2PicpO1xuICAgICAgICAgICAgJGVsLmFwcGVuZCgkY3ViZVNoYWRvd0VsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdmFyICRzbGlkZUVsID0gc2xpZGVzLmVxKGkpO1xuICAgICAgICB2Y
166XIgc2xpZGVJbmRleCA9IGk7XG5cbiAgICAgICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgICAgIHNsaWRlSW5kZXggPSBwYXJzZUludCgkc2xpZGVFbC5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2xpZGVBbmdsZSA9IHNsaWRlSW5kZXggKiA5MDtcbiAgICAgICAgdmFyIHJvdW5kID0gTWF0aC5mbG9vcihzbGlkZUFuZ2xlIC8gMzYwKTtcblxuICAgICAgICBpZiAocnRsKSB7XG4gICAgICAgICAgc2xpZGVBbmdsZSA9IC1zbGlkZUFuZ2xlO1xuICAgICAgICAgIHJvdW5kID0gTWF0aC5mbG9vcigtc2xpZGVBbmdsZSAvIDM2MCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbigkc2xpZGVFbFswXS5wcm9ncmVzcywgMSksIC0xKTtcbiAgICAgICAgdmFyIHR4ID0gMDtcbiAgICAgICAgdmFyIHR5ID0gMDtcbiAgICAgICAgdmFyIHR6ID0gMDtcblxuICAgICAgICBpZiAoc2xpZGVJbmRleCAlIDQgPT09IDApIHtcbiAgICAgICAgICB0eCA9IC1yb3VuZCAqIDQgKiBzd2lwZXJTaXplO1xuICAgICAgICAgIHR6ID0gMDtcbiAgICAgICAgfSBlbHNlIGlmICgoc2xpZGVJbmRleCAtIDEpICUgNCA9PT0gMCkge1xuICAgICAgICAgIHR4ID0gMDtcbiAgICAgICAgICB0eiA9IC1yb3VuZCAqIDQgKiBzd2lwZXJTaXplO1xuICAgICAgICB9IGVsc2UgaWYgKChzbGlkZUluZGV4IC0gMikgJSA0ID09PSAwKSB7XG4gICAgICAgICAgdHggPSBzd2lwZXJTaXplICsgcm91bmQgKiA0ICogc3dpcGVyU2l6ZTtcbiAgICAgICAgICB0eiA9IHN3aXBlclNpemU7XG4gICAgICAgIH0gZWxzZSBpZiAoKHNsaWRlSW5kZXggLSAzKSAlIDQgPT09IDApIHtcbiAgICAgICAgICB0eCA9IC1zd2lwZXJTaXplO1xuICAgICAgICAgIHR6ID0gMyAqIHN3aXBlclNpemUgKyBzd2lwZXJTaXplICogNCAqIHJvdW5kO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJ0bCkge1xuICAgICAgICAgIHR4ID0gLXR4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc0hvcml6b250YWwpIHtcbiAgICAgICAgICB0eSA9IHR4O1xuICAgICAgICAgIHR4ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0cmFuc2Zvcm0gPSBcInJvdGF0ZVgoXCIgKyAoaXNIb3Jpem9udGFsID8gMCA6IC1zbGlkZUFuZ2xlKSArIFwiZGVnKSByb3RhdGVZKFwiICsgKGlzSG9yaXpvbnRhbCA/IHNsaWRlQW5nbGUgOiAwKSArIFwiZGVnKSB0cmFuc2xhdGUzZChcIiArIHR4ICsgXCJweCwgXCIgKyB0eSArIFwicHgsIFwiICsgdHogKyBcInB4KVwiO1xuXG4gICAgICAgIGlmIChwcm9ncmVzcyA8PSAxICYmIHByb2dyZXNzID4gLTEpIHtcbiAgICAgICAgICB3cmFwcGVyUm90YXRlID0gc2xpZGVJbmRleCAqIDkwICsgcHJvZ3Jlc3MgKiA5MDtcbiAgICAgICAgICBpZiAocnRsKSB3cmFwcGVyUm90YXRlID0gLXNsaWRlSW5kZXggKiA5MCAtIHByb2dyZXNzICogOTA7XG4gICAgICAgIH1cblxuICAgICAgICAkc2xpZGVFbC50cmFuc2Zvcm0odHJhbnNmb3JtKTtcblxuICAgICAgICBpZiAocGFyYW1zLnNsaWRlU2hhZG93cykge1xuICAgICAgICAgIC8vIFNldCBzaGFkb3dzXG4gICAgICAgICAgdmFyIHNoYWRvd0JlZm9yZSA9IGlzSG9yaXpvbnRhbCA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKSA6ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCcpO1xuICAgICAgICAgIHZhciBzaGFkb3dBZnRlciA9IGlzSG9yaXpvbnRhbCA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0JykgOiAkc2xpZGVFbC5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcblxuICAgICAgICAgIGlmIChzaGFkb3dCZWZvcmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBzaGFkb3dCZWZvcmUgPSAkKFwiPGRpdiBjbGFzcz1cXFwic3dpcGVyLXNsaWRlLXNoYWRvdy1cIiArIChpc0hvcml6b250YWwgPyAnbGVmdCcgOiAndG9wJykgKyBcIlxcXCI+PC9kaXY+XCIpO1xuICAgICAgICAgICAgJHNsaWRlRWwuYXBwZW5kKHNoYWRvd0JlZm9yZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNoYWRvd0FmdGVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc2hhZG93QWZ0ZXIgPSAkKFwiPGRpdiBjbGFzcz1cXFwic3dpcGVyLXNsaWRlLXNoYWRvdy1cIiArIChpc0hvcml6b250YWwgPyAncmlnaHQnIDogJ2JvdHRvbScpICsgXCJcXFwiPjwvZGl2PlwiKTtcbiAgICAgICAgICAgICRzbGlkZUVsLmFwcGVuZChzaGFkb3dBZnRlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNoYWRvd0JlZm9yZS5sZW5ndGgpIHNoYWRvd0JlZm9yZVswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgoLXByb2dyZXNzLCAwKTtcbiAgICAgICAgICBpZiAoc2hhZG93QWZ0ZXIubGVuZ3RoKSBzaGFkb3dBZnRlclswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgocHJvZ3Jlc3MsIDApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgICR3cmFwcGVyRWwuY3NzKHtcbiAgICAgICAgJy13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbic6IFwiNTAlIDUwJSAtXCIgKyBzd2lwZXJTaXplIC8gMiArIFwicHhcIixcbiAgICAgICAgJy1tb3otdHJhbnNmb3JtLW9yaWdpbic6IFwiNTAlIDUwJSAtXCIgKyBzd2lwZXJTaXplIC8gMiArIFwicHhcIixcbiAgICAgICAgJy1tcy10cmFuc2Zvcm0tb3JpZ2luJzogXCI1MCUgNTAlIC1cIiArIHN3aXBlclNpemUgLyAyICsgXCJweFwiLFxuICAgICAgICAndHJhbnNmb3JtLW9yaWdpbic6IFwiNTAlIDUwJSAtXCIgKyBzd2lwZXJTaXplIC8gMiArIFwicHhcIlxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwYXJhbXMuc2hhZG93KSB7XG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICAkY3ViZVNoYWRvd0VsLnRyYW5zZm9ybShcInRyYW5zbGF0ZTNkKDBweCwgXCIgKyAoc3dpcGVyV2lkdGggLyAyICsgcGFyYW1zLnNoYWRvd09mZnNldCkgKyBcInB4LCBcIiArIC1zd2lwZXJXaWR0aCAvIDIgKyBcInB4KSByb3RhdGVYKDkwZGVnKSByb3RhdGVaKDBkZWcpIHNjYWxlKFwiICsgcGFyYW1zLnNoYWRvd1NjYWxlICsgXCIpXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgI
166HZhciBzaGFkb3dBbmdsZSA9IE1hdGguYWJzKHdyYXBwZXJSb3RhdGUpIC0gTWF0aC5mbG9vcihNYXRoLmFicyh3cmFwcGVyUm90YXRlKSAvIDkwKSAqIDkwO1xuICAgICAgICAgIHZhciBtdWx0aXBsaWVyID0gMS41IC0gKE1hdGguc2luKHNoYWRvd0FuZ2xlICogMiAqIE1hdGguUEkgLyAzNjApIC8gMiArIE1hdGguY29zKHNoYWRvd0FuZ2xlICogMiAqIE1hdGguUEkgLyAzNjApIC8gMik7XG4gICAgICAgICAgdmFyIHNjYWxlMSA9IHBhcmFtcy5zaGFkb3dTY2FsZTtcbiAgICAgICAgICB2YXIgc2NhbGUyID0gcGFyYW1zLnNoYWRvd1NjYWxlIC8gbXVsdGlwbGllcjtcbiAgICAgICAgICB2YXIgb2Zmc2V0ID0gcGFyYW1zLnNoYWRvd09mZnNldDtcbiAgICAgICAgICAkY3ViZVNoYWRvd0VsLnRyYW5zZm9ybShcInNjYWxlM2QoXCIgKyBzY2FsZTEgKyBcIiwgMSwgXCIgKyBzY2FsZTIgKyBcIikgdHJhbnNsYXRlM2QoMHB4LCBcIiArIChzd2lwZXJIZWlnaHQgLyAyICsgb2Zmc2V0KSArIFwicHgsIFwiICsgLXN3aXBlckhlaWdodCAvIDIgLyBzY2FsZTIgKyBcInB4KSByb3RhdGVYKC05MGRlZylcIik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHpGYWN0b3IgPSBicm93c2VyLmlzU2FmYXJpIHx8IGJyb3dzZXIuaXNXZWJWaWV3ID8gLXN3aXBlclNpemUgLyAyIDogMDtcbiAgICAgICR3cmFwcGVyRWwudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoMHB4LDAsXCIgKyB6RmFjdG9yICsgXCJweCkgcm90YXRlWChcIiArIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAwIDogd3JhcHBlclJvdGF0ZSkgKyBcImRlZykgcm90YXRlWShcIiArIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAtd3JhcHBlclJvdGF0ZSA6IDApICsgXCJkZWcpXCIpO1xuICAgIH0sXG4gICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihkdXJhdGlvbikge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgJGVsID0gc3dpcGVyLiRlbCxcbiAgICAgICAgICBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzO1xuICAgICAgc2xpZGVzLnRyYW5zaXRpb24oZHVyYXRpb24pLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctcmlnaHQsIC5zd2lwZXItc2xpZGUtc2hhZG93LWJvdHRvbSwgLnN3aXBlci1zbGlkZS1zaGFkb3ctbGVmdCcpLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0LnNoYWRvdyAmJiAhc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICRlbC5maW5kKCcuc3dpcGVyLWN1YmUtc2hhZG93JykudHJhbnNpdGlvbihkdXJhdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICB2YXIgRWZmZWN0Q3ViZSA9IHtcbiAgICBuYW1lOiAnZWZmZWN0LWN1YmUnLFxuICAgIHBhcmFtczoge1xuICAgICAgY3ViZUVmZmVjdDoge1xuICAgICAgICBzbGlkZVNoYWRvd3M6IHRydWUsXG4gICAgICAgIHNoYWRvdzogdHJ1ZSxcbiAgICAgICAgc2hhZG93T2Zmc2V0OiAyMCxcbiAgICAgICAgc2hhZG93U2NhbGU6IDAuOTRcbiAgICAgIH1cbiAgICB9LFxuICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICBiaW5kTW9kdWxlTWV0aG9kcyhzd2lwZXIsIHtcbiAgICAgICAgY3ViZUVmZmVjdDogX2V4dGVuZHMoe30sIEN1YmUpXG4gICAgICB9KTtcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBiZWZvcmVJbml0OiBmdW5jdGlvbiBiZWZvcmVJbml0KHN3aXBlcikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5lZmZlY3QgIT09ICdjdWJlJykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcyArIFwiY3ViZVwiKTtcbiAgICAgICAgc3dpcGVyLmNsYXNzTmFtZXMucHVzaChzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBcIjNkXCIpO1xuICAgICAgICB2Y
166XIgb3ZlcndyaXRlUGFyYW1zID0ge1xuICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDEsXG4gICAgICAgICAgc2xpZGVzUGVyQ29sdW1uOiAxLFxuICAgICAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxuICAgICAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXG4gICAgICAgICAgcmVzaXN0YW5jZVJhdGlvOiAwLFxuICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICBjZW50ZXJlZFNsaWRlczogZmFsc2UsXG4gICAgICAgICAgdmlydHVhbFRyYW5zbGF0ZTogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBleHRlbmQkMShzd2lwZXIucGFyYW1zLCBvdmVyd3JpdGVQYXJhbXMpO1xuICAgICAgICBleHRlbmQkMShzd2lwZXIub3JpZ2luYWxQYXJhbXMsIG92ZXJ3cml0ZVBhcmFtcyk7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNsYXRlOiBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gJ2N1YmUnKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5jdWJlRWZmZWN0LnNldFRyYW5zbGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIHNldFRyYW5zaXRpb246IGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oc3dpcGVyLCBkdXJhdGlvbikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5lZmZlY3QgIT09ICdjdWJlJykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuY3ViZUVmZmVjdC5zZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIEZsaXAgPSB7XG4gICAgc2V0VHJhbnNsYXRlOiBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzLFxuICAgICAgICAgIHJ0bCA9IHN3aXBlci5ydGxUcmFuc2xhdGU7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHZhciAkc2xpZGVFbCA9IHNsaWRlcy5lcShpKTtcbiAgICAgICAgdmFyIHByb2dyZXNzID0gJHNsaWRlRWxbMF0ucHJvZ3Jlc3M7XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZmxpcEVmZmVjdC5saW1pdFJvdGF0aW9uKSB7XG4gICAgICAgICAgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbigkc2xpZGVFbFswXS5wcm9ncmVzcywgMSksIC0xKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvZmZzZXQgPSAkc2xpZGVFbFswXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgICAgdmFyIHJvdGF0ZSA9IC0xODAgKiBwcm9ncmVzcztcbiAgICAgICAgdmFyIHJvdGF0ZVkgPSByb3RhdGU7XG4gICAgICAgIHZhciByb3RhdGVYID0gMDtcbiAgICAgICAgdmFyIHR4ID0gLW9mZnNldDtcbiAgICAgICAgdmFyIHR5ID0gMDtcblxuICAgICAgICBpZiAoIXN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgIHR5ID0gdHg7XG4gICAgICAgICAgdHggPSAwO1xuICAgICAgICAgIHJvdGF0ZVggPSAtcm90YXRlWTtcbiAgICAgICAgICByb3RhdGVZID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChydGwpIHtcbiAgICAgICAgICByb3RhdGVZID0gLXJvdGF0ZVk7XG4gICAgICAgIH1cblxuICAgICAgICAkc2xpZGVFbFswXS5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChwcm9ncmVzcykpICsgc2xpZGVzLmxlbmd0aDtcblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0LnNsaWRlU2hhZG93cykge1xuICAgICAgICAgIC8vIFNldCBzaGFkb3dzXG4gICAgICAgICAgdmFyIHNoYWRvd0JlZm9yZSA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKSA6ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCcpO1xuICAgICAgICAgIHZhciBzaGFkb3dBZnRlciA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0JykgOiAkc2xpZGVFbC5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcblxuICAgICAgICAgIGlmIChzaGFkb3dCZWZvcmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBzaGFkb3dCZWZvcmUgPSAkKFwiPGRpdiBjbGFzcz1cXFwic3dpcGVyLXNsaWRlLXNoYWRvdy1cIiArIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnbGVmdCcgOiAndG9wJykgKyBcIlxcXCI+PC9kaXY+XCIpO1xuICAgICAgICAgICAgJHNsaWRlRWwuYXBwZW5kKHNoYWRvd0JlZm9yZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNoYWRvd0FmdGVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc2hhZG93QWZ0ZXIgPSAkKFwiPGRpdiBjbGFzcz1cXFwic3dpcGVyLXNsaWRlLXNoYWRvdy1cIiArIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAncmlnaHQnIDogJ2JvdHRvbScpICsgXCJcXFwiPjwvZGl2PlwiKTtcbiAgICAgICAgICAgICRzbGlkZUVsLmFwcGVuZChzaGFkb3dBZnRlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNoYWRvd0JlZm9yZS5sZW5ndGgpIHNoYWRvd0JlZm9yZVswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgoLXByb2dyZXNzLCAwKTtcbiAgICAgICAgICBpZiAoc2hhZG93QWZ0ZXIubGVuZ3RoKSBzaGFkb3dBZnRlclswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgocHJvZ3Jlc3MsIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgJHNsaWRlRWwudHJhbnNmb3JtKFwidHJhbnNsYXRlM2QoXCIgKyB0eCArIFwicHgsIFwiICsgdHkgKyBcInB4LCAwcHgpIHJvdGF0ZVgoXCIgKyByb3RhdGVYICsgXCJkZWcpIHJvdGF0ZVkoXCIgKyByb3RhdGVZICsgXCJkZWcpXCIpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihkdXJhdGlvbikge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgc2xpZGVzID0gc3dpcGVyLnNsaWRlcyxcbiAgICAgICAgICBhY3RpdmVJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleCxcbiAgICAgICAgICAkd3JhcHBlckVsID0gc3dpcGVyLiR3cmFwcGVyRWw7XG4gICAgICBzbGlkZXMudHJhbnNpdGlvbihkdXJhdGlvbikuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0JykudHJhbnNpdGlvbihkdXJhdGlvbik7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWxUcmFuc2xhdGUgJiYgZHVyYXRpb24gIT09IDApIHtcbiAgICAgICAgdmFyIGV2ZW50VHJpZ2dlcmVkID0gZmFsc2U7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG4gICAgICAgIHNsaWRlcy5lcShhY3RpdmVJbmRleCkudHJhbnNpdGlvbkVuZChmdW5jdGlvbiBvblRyYW5zaXRpb25FbmQoKSB7XG4gICAgICAgICAgaWYgKGV2ZW50VHJpZ2dlcmVkKSByZXR1cm47XG4gICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuOyAvLyBpZiAoISQodGhpcykuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzKSkgcmV0dXJuO1xuXG4gICAgICAgICAgZXZlbnRUcmlnZ2VyZWQgPSB0cnVlO1xuICAgICAgICAgIHN3aXBlci5hbmltYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICB2YXIgdHJpZ2dlckV2ZW50cyA9IFsnd2Via2l0VHJhbnNpdGlvbkVuZCcsICd0cmFuc2l0aW9uZW5kJ107XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRyaWdnZXJFdmVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICR3cmFwcGVyRWwudHJpZ2dlcih0cmlnZ2VyRXZlbnRzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgdmFyIEVmZmVjdEZsaXAgPSB7XG4gICAgbmFtZTogJ2VmZmVjdC1mbGlwJyxcbiAgICBwYXJhbXM6IHtcbiAgICAgIGZsaXBFZmZlY3Q6IHtcbiAgICAgICAgc2xpZGVTaGFkb3dzOiB0cnVlLFxuICAgICAgICBsaW1pdFJvdGF0aW9uOiB0cnVlXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIGZsaXBFZmZlY3Q6IF9leHRlbmRzKHt9LCBGbGlwKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgYmVmb3JlSW5pdDogZnVuY3Rpb24gYmVmb3JlSW5pdChzd2lwZXIp
166IHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSAnZmxpcCcpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmNsYXNzTmFtZXMucHVzaChzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBcImZsaXBcIik7XG4gICAgICAgIHN3aXBlci5jbGFzc05hbWVzLnB1c2goc3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzICsgXCIzZFwiKTtcbiAgICAgICAgdmFyIG92ZXJ3cml0ZVBhcmFtcyA9IHtcbiAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgIHNsaWRlc1BlckNvbHVtbjogMSxcbiAgICAgICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICB2aXJ0dWFsVHJhbnNsYXRlOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5wYXJhbXMsIG92ZXJ3cml0ZVBhcmFtcyk7XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci5vcmlnaW5hbFBhcmFtcywgb3ZlcndyaXRlUGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2xhdGU6IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSAnZmxpcCcpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmZsaXBFZmZlY3Quc2V0VHJhbnNsYXRlKCk7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNpdGlvbjogZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihzd2lwZXIsIGR1cmF0aW9uKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gJ2ZsaXAnKSByZXR1cm47XG4gICAgICAgIHN3aXBlci5mbGlwRWZmZWN0LnNldFRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgQ292ZXJmbG93ID0ge1xuICAgIHNldFRyYW5zbGF0ZTogZnVuY3Rpb24gc2V0VHJhbnNsYXRlKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgc3dpcGVyV2lkdGggPSBzd2lwZXIud2lkdGgsXG4gICAgICAgICAgc3dpcGVySGVpZ2h0ID0gc3dpcGVyLmhlaWdodCxcbiAgICAgICAgICBzbGlkZXMgPSBzd2lwZXIuc2xpZGVzLFxuICAgICAgICAgIHNsaWRlc1NpemVzR3JpZCA9IHN3aXBlci5zbGlkZXNTaXplc0dyaWQ7XG4gICAgICB2YXIgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jb3ZlcmZsb3dFZmZlY3Q7XG4gICAgICB2YXIgaXNIb3Jpem9udGFsID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuICAgICAgdmFyIHRyYW5zZm9ybSA9IHN3aXBlci50cmFuc2xhdGU7XG4gICAgICB2YXIgY2VudGVyID0gaXNIb3Jpem9udGFsID8gLXRyYW5zZm9ybSArIHN3aXBlcldpZHRoIC8gMiA6IC10cmFuc2Zvcm0gKyBzd2lwZXJIZWlnaHQgLyAyO1xuICAgICAgdmFyIHJvdGF0ZSA9IGlzSG9yaXpvbnRhbCA/IHBhcmFtcy5yb3RhdGUgOiAtcGFyYW1zLnJvdGF0ZTtcbiAgICAgIHZhciB0cmFuc2xhdGUgPSBwYXJhbXMuZGVwdGg7IC8vIEVhY2ggc2xpZGUgb2Zmc2V0IGZyb20gY2VudGVyXG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBzbGlkZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdmFyICRzbGlkZUVsID0gc2xpZGVzLmVxKGkpO1xuICAgICAgICB2YXIgc2xpZGVTaXplID0gc2xpZGVzU2l6ZXNHcmlkW2ldO1xuICAgICAgICB2YXIgc2xpZGVPZmZzZXQgPSAkc2xpZGVFbFswXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgICAgdmFyIG9mZnNldE11bHRpcGxpZXIgPSAoY2VudGVyIC0gc2xpZGVPZmZzZXQgLSBzbGlkZVNpemUgLyAyKSAvIHNsaWRlU2l6ZSAqIHBhcmFtcy5tb2RpZmllcjtcbiAgICAgICAgdmFyIHJvdGF0ZVkgPSBpc0hvcml6b250YWwgPyByb3RhdGUgKiBvZmZzZXRNdWx0aXBsaWVyIDogMDtcbiAgICAgICAgdmFyIHJvdGF0ZVggPSBpc0hvcml6b250YWwgPyAwIDogcm90YXRlICogb2Zmc2V0TXVsdGlwbGllcjsgLy8gdmFyIHJvdGF0ZVogPSAwXG5cbiAgICAgICAgdmFyIHRyYW5zbGF0ZVogPSAtdHJhbnNsYXRlICogTWF0aC5hYnMob2Zmc2V0TXVsdGlwbGllcik7XG4gICAgICAgIHZhciBzdHJldGNoID0gcGFyYW1zLnN0cmV0Y2g7IC8vIEFsbG93IHBlcmNlbnRhZ2UgdG8gbWFrZSBhIHJlbGF0aXZlIHN0cmV0Y2ggZm9yIHJlc3BvbnNpdmUgc2xpZGVyc1xuXG4gICAgICAgIGlmICh0eXBlb2Ygc3RyZXRjaCA9PT0gJ3N0cmluZycgJiYgc3RyZXRjaC5pbmRleE9mKCclJykgIT09IC0xKSB7XG4gICAgICAgICAgc3RyZXRjaCA9IHBhcnNlRmxvYXQocGFyYW1zLnN0cmV0Y2gpIC8gMTAwICogc2xpZGVTaXplO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRyYW5zbGF0ZVkgPSBpc0hvcml6b250YWwgPyAwIDogc3RyZXRjaCAqIG9mZnNldE11bHRpcGxpZXI7XG4gICAgICAgIHZhciB0cmFuc2xhdGVYID0gaXNIb3Jpem9udGFsID8gc3RyZXRjaCAqIG9mZnNldE11bHRpcGxpZXIgOiAwO1xuICAgICAgICB2Y
166XIgc2NhbGUgPSAxIC0gKDEgLSBwYXJhbXMuc2NhbGUpICogTWF0aC5hYnMob2Zmc2V0TXVsdGlwbGllcik7IC8vIEZpeCBmb3IgdWx0cmEgc21hbGwgdmFsdWVzXG5cbiAgICAgICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVgpIDwgMC4wMDEpIHRyYW5zbGF0ZVggPSAwO1xuICAgICAgICBpZiAoTWF0aC5hYnModHJhbnNsYXRlWSkgPCAwLjAwMSkgdHJhbnNsYXRlWSA9IDA7XG4gICAgICAgIGlmIChNYXRoLmFicyh0cmFuc2xhdGVaKSA8IDAuMDAxKSB0cmFuc2xhdGVaID0gMDtcbiAgICAgICAgaWYgKE1hdGguYWJzKHJvdGF0ZVkpIDwgMC4wMDEpIHJvdGF0ZVkgPSAwO1xuICAgICAgICBpZiAoTWF0aC5hYnMocm90YXRlWCkgPCAwLjAwMSkgcm90YXRlWCA9IDA7XG4gICAgICAgIGlmIChNYXRoLmFicyhzY2FsZSkgPCAwLjAwMSkgc2NhbGUgPSAwO1xuICAgICAgICB2YXIgc2xpZGVUcmFuc2Zvcm0gPSBcInRyYW5zbGF0ZTNkKFwiICsgdHJhbnNsYXRlWCArIFwicHgsXCIgKyB0cmFuc2xhdGVZICsgXCJweCxcIiArIHRyYW5zbGF0ZVogKyBcInB4KSAgcm90YXRlWChcIiArIHJvdGF0ZVggKyBcImRlZykgcm90YXRlWShcIiArIHJvdGF0ZVkgKyBcImRlZykgc2NhbGUoXCIgKyBzY2FsZSArIFwiKVwiO1xuICAgICAgICAkc2xpZGVFbC50cmFuc2Zvcm0oc2xpZGVUcmFuc2Zvcm0pO1xuICAgICAgICAkc2xpZGVFbFswXS5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChvZmZzZXRNdWx0aXBsaWVyKSkgKyAxO1xuXG4gICAgICAgIGlmIChwYXJhbXMuc2xpZGVTaGFkb3dzKSB7XG4gICAgICAgICAgLy8gU2V0IHNoYWRvd3NcbiAgICAgICAgICB2Y
166XIgJHNoYWRvd0JlZm9yZUVsID0gaXNIb3Jpem9udGFsID8gJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctbGVmdCcpIDogJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wJyk7XG4gICAgICAgICAgdmFyICRzaGFkb3dBZnRlckVsID0gaXNIb3Jpem9udGFsID8gJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctcmlnaHQnKSA6ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LWJvdHRvbScpO1xuXG4gICAgICAgICAgaWYgKCRzaGFkb3dCZWZvcmVFbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICRzaGFkb3dCZWZvcmVFbCA9ICQoXCI8ZGl2IGNsYXNzPVxcXCJzd2lwZXItc2xpZGUtc2hhZG93LVwiICsgKGlzSG9yaXpvbnRhbCA/ICdsZWZ0JyA6ICd0b3AnKSArIFwiXFxcIj48L2Rpdj5cIik7XG4gICAgICAgICAgICAkc2xpZGVFbC5hcHBlbmQoJHNoYWRvd0JlZm9yZUVsKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoJHNoYWRvd0FmdGVyRWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkc2hhZG93QWZ0ZXJFbCA9ICQoXCI8ZGl2IGNsYXNzPVxcXCJzd2lwZXItc2xpZGUtc2hhZG93LVwiICsgKGlzSG9yaXpvbnRhbCA/ICdyaWdodCcgOiAnYm90dG9tJykgKyBcIlxcXCI+PC9kaXY+XCIpO1xuICAgICAgICAgICAgJHNsaWRlRWwuYXBwZW5kKCRzaGFkb3dBZnRlckVsKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoJHNoYWRvd0JlZm9yZUVsLmxlbmd0aCkgJHNoYWRvd0JlZm9yZUVsWzBdLnN0eWxlLm9wYWNpdHkgPSBvZmZzZXRNdWx0aXBsaWVyID4gMCA/IG9mZnNldE11bHRpcGxpZXIgOiAwO1xuICAgICAgICAgIGlmICgkc2hhZG93QWZ0ZXJFbC5sZW5ndGgpICRzaGFkb3dBZnRlckVsWzBdLnN0eWxlLm9wYWNpdHkgPSAtb2Zmc2V0TXVsdGlwbGllciA+IDAgPyAtb2Zmc2V0TXVsdGlwbGllciA6IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIHNldFRyYW5zaXRpb246IGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24pIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgc3dpcGVyLnNsaWRlcy50cmFuc2l0aW9uKGR1cmF0aW9uKS5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AsIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKS50cmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICB9XG4gIH07XG4gIHZhciBFZmZlY3RDb3ZlcmZsb3cgPSB7XG4gICAgbmFtZTogJ2VmZmVjdC1jb3ZlcmZsb3cnLFxuICAgIHBhcmFtczoge1xuICAgICAgY292ZXJmbG93RWZmZWN0OiB7XG4gICAgICAgIHJvdGF0ZTogNTAsXG4gICAgICAgIHN0cmV0Y2g6IDAsXG4gICAgICAgIGRlcHRoOiAxMDAsXG4gICAgICAgIHNjYWxlOiAxLFxuICAgICAgICBtb2RpZmllcjogMSxcbiAgICAgICAgc2xpZGVTaGFkb3dzOiB0cnVlXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIGNvdmVyZmxvd0VmZmVjdDogX2V4dGVuZHMoe30sIENvdmVyZmxvdylcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb246IHtcbiAgICAgIGJlZm9yZUluaXQ6IGZ1bmN0aW9uIGJlZm9yZUluaXQoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gJ2NvdmVyZmxvdycpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmNsYXNzTmFtZXMucHVzaChzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBcImNvdmVyZmxvd1wiKTtcbiAgICAgICAgc3dpcGVyLmNsYXNzTmFtZXMucHVzaChzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MgKyBcIjNkXCIpO1xuICAgICAgICBzd2lwZXIucGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyA9IHRydWU7XG4gICAgICB9LFxuICAgICAgc2V0VHJhbnNsYXRlOiBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoc3dpcGVyKSB7XG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gJ2NvdmVyZmxvdycpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLmNvdmVyZmxvd0VmZmVjdC5zZXRUcmFuc2xhdGUoKTtcbiAgICAgIH0sXG4gICAgICBzZXRUcmFuc2l0aW9uOiBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKHN3aXBlciwgZHVyYXRpb24pIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSAnY292ZXJmbG93JykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuY292ZXJmbG93RWZmZWN0LnNldFRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgVGh1bWJzID0ge1xuICAgIGluaXQ6IGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgICB2Y
166XIgc3dpcGVyID0gdGhpcztcbiAgICAgIHZhciB0aHVtYnNQYXJhbXMgPSBzd2lwZXIucGFyYW1zLnRodW1icztcbiAgICAgIGlmIChzd2lwZXIudGh1bWJzLmluaXRpYWxpemVkKSByZXR1cm4gZmFsc2U7XG4gICAgICBzd2lwZXIudGh1bWJzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHZhciBTd2lwZXJDbGFzcyA9IHN3aXBlci5jb25zdHJ1Y3RvcjtcblxuICAgICAgaWYgKHRodW1ic1BhcmFtcy5zd2lwZXIgaW5zdGFuY2VvZiBTd2lwZXJDbGFzcykge1xuICAgICAgICBzd2lwZXIudGh1bWJzLnN3aXBlciA9IHRodW1ic1BhcmFtcy5zd2lwZXI7XG4gICAgICAgIGV4dGVuZCQxKHN3aXBlci50aHVtYnMuc3dpcGVyLm9yaWdpbmFsUGFyYW1zLCB7XG4gICAgICAgICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogdHJ1ZSxcbiAgICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZXh0ZW5kJDEoc3dpcGVyLnRodW1icy5zd2lwZXIucGFyYW1zLCB7XG4gICAgICAgICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogdHJ1ZSxcbiAgICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QkMSh0aHVtYnNQYXJhbXMuc3dpcGVyKSkge1xuICAgICAgICBzd2lwZXIudGh1bWJzLnN3aXBlciA9IG5ldyBTd2lwZXJDbGFzcyhleHRlbmQkMSh7fSwgdGh1bWJzUGFyYW1zLnN3aXBlciwge1xuICAgICAgICAgIHdhdGNoU2xpZGVzVmlzaWJpbGl0eTogdHJ1ZSxcbiAgICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICAgIHNsaWRlVG9DbGlja2VkU2xpZGU6IGZhbHNlXG4gICAgICAgIH0pKTtcbiAgICAgICAgc3dpcGVyLnRodW1icy5zd2lwZXJDcmVhdGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLnRodW1icy5zd2lwZXIuJGVsLmFkZENsYXNzKHN3aXBlci5wYXJhbXMudGh1bWJzLnRodW1ic0NvbnRhaW5lckNsYXNzKTtcbiAgICAgIHN3aXBlci50aHVtYnMuc3dpcGVyLm9uKCd0YXAnLCBzd2lwZXIudGh1bWJzLm9uVGh1bWJDbGljayk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuICAgIG9uVGh1bWJDbGljazogZnVuY3Rpb24gb25UaHVtYkNsaWNrKCkge1xuICAgICAgdmFyIHN3aXBlciA9IHRoaXM7XG4gICAgICB2Y
166XIgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgICBpZiAoIXRodW1ic1N3aXBlcikgcmV0dXJuO1xuICAgICAgdmFyIGNsaWNrZWRJbmRleCA9IHRodW1ic1N3aXBlci5jbGlja2VkSW5kZXg7XG4gICAgICB2YXIgY2xpY2tlZFNsaWRlID0gdGh1bWJzU3dpcGVyLmNsaWNrZWRTbGlkZTtcbiAgICAgIGlmIChjbGlja2VkU2xpZGUgJiYgJChjbGlja2VkU2xpZGUpLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMudGh1bWJzLnNsaWRlVGh1bWJBY3RpdmVDbGFzcykpIHJldHVybjtcbiAgICAgIGlmICh0eXBlb2YgY2xpY2tlZEluZGV4ID09PSAndW5kZWZpbmVkJyB8fCBjbGlja2VkSW5kZXggPT09IG51bGwpIHJldHVybjtcbiAgICAgIHZhciBzbGlkZVRvSW5kZXg7XG5cbiAgICAgIGlmICh0aHVtYnNTd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgICAgc2xpZGVUb0luZGV4ID0gcGFyc2VJbnQoJCh0aHVtYnNTd2lwZXIuY2xpY2tlZFNsaWRlKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZVRvSW5kZXggPSBjbGlja2VkSW5kZXg7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgICAgdmFyIGN1cnJlbnRJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleDtcblxuICAgICAgICBpZiAoc3dpcGVyLnNsaWRlcy5lcShjdXJyZW50SW5kZXgpLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcykpIHtcbiAgICAgICAgICBzd2lwZXIubG9vcEZpeCgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgICAgIHN3aXBlci5fY2xpZW50TGVmdCA9IHN3aXBlci4kd3JhcHBlckVsWzBdLmNsaWVudExlZnQ7XG4gICAgICAgICAgY3VycmVudEluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHByZXZJbmRleCA9IHN3aXBlci5zbGlkZXMuZXEoY3VycmVudEluZGV4KS5wcmV2QWxsKFwiW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVxcXCJcIiArIHNsaWRlVG9JbmRleCArIFwiXFxcIl1cIikuZXEoMCkuaW5kZXgoKTtcbiAgICAgICAgdmFyIG5leHRJbmRleCA9IHN3aXBlci5zbGlkZXMuZXEoY3VycmVudEluZGV4KS5uZXh0QWxsKFwiW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVxcXCJcIiArIHNsaWRlVG9JbmRleCArIFwiXFxcIl1cIikuZXEoMCkuaW5kZXgoKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcmV2SW5kZXggPT09ICd1bmRlZmluZWQnKSBzbGlkZVRvSW5kZXggPSBuZXh0SW5kZXg7ZWxzZSBpZiAodHlwZW9mIG5leHRJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHNsaWRlVG9JbmRleCA9IHByZXZJbmRleDtlbHNlIGlmIChuZXh0SW5kZXggLSBjdXJyZW50SW5kZXggPCBjdXJyZW50SW5kZXggLSBwcmV2SW5kZXgpIHNsaWRlVG9JbmRleCA9IG5leHRJbmRleDtlbHNlIHNsaWRlVG9JbmRleCA9IHByZXZJbmRleDtcbiAgICAgIH1cblxuICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcbiAgICB9LFxuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKGluaXRpYWwpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgdmFyIHRodW1ic1N3aXBlciA9IHN3aXBlci50aHVtYnMuc3dpcGVyO1xuICAgICAgaWYgKCF0aHVtYnNTd2lwZXIpIHJldHVybjtcbiAgICAgIHZhciBzbGlkZXNQZXJWaWV3ID0gdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycgPyB0aHVtYnNTd2lwZXIuc2xpZGVzUGVyVmlld0R5bmFtaWMoKSA6IHRodW1ic1N3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldztcbiAgICAgIHZhciBhdXRvU2Nyb2xsT2Zmc2V0ID0gc3dpcGVyLnBhcmFtcy50aHVtYnMuYXV0b1Njcm9sbE9mZnNldDtcbiAgICAgIHZhciB1c2VPZmZzZXQgPSBhdXRvU2Nyb2xsT2Zmc2V0ICYmICF0aHVtYnNTd2lwZXIucGFyYW1zLmxvb3A7XG5cbiAgICAgIGlmIChzd2lwZXIucmVhbEluZGV4ICE9PSB0aHVtYnNTd2lwZXIucmVhbEluZGV4IHx8IHVzZU9mZnNldCkge1xuICAgICAgICB2Y
166XIgY3VycmVudFRodW1ic0luZGV4ID0gdGh1bWJzU3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgICB2YXIgbmV3VGh1bWJzSW5kZXg7XG4gICAgICAgIHZhciBkaXJlY3Rpb247XG5cbiAgICAgICAgaWYgKHRodW1ic1N3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICAgIGlmICh0aHVtYnNTd2lwZXIuc2xpZGVzLmVxKGN1cnJlbnRUaHVtYnNJbmRleCkuaGFzQ2xhc3ModGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgICAgICAgdGh1bWJzU3dpcGVyLmxvb3BGaXgoKTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cbiAgICAgICAgICAgIHRodW1ic1N3aXBlci5fY2xpZW50TGVmdCA9IHRodW1ic1N3aXBlci4kd3JhcHBlckVsWzBdLmNsaWVudExlZnQ7XG4gICAgICAgICAgICBjdXJyZW50VGh1bWJzSW5kZXggPSB0aHVtYnNTd2lwZXIuYWN0aXZlSW5kZXg7XG4gICAgICAgICAgfSAvLyBGaW5kIGFjdHVhbCB0aHVtYnMgaW5kZXggdG8gc2xpZGUgdG9cblxuXG4gICAgICAgICAgdmFyIHByZXZUaHVtYnNJbmRleCA9IHRodW1ic1N3aXBlci5zbGlkZXMuZXEoY3VycmVudFRodW1ic0luZGV4KS5wcmV2QWxsKFwiW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVxcXCJcIiArIHN3aXBlci5yZWFsSW5kZXggKyBcIlxcXCJdXCIpLmVxKDApLmluZGV4KCk7XG4gICAgICAgICAgdmFyIG5leHRUaHVtYnNJbmRleCA9IHRodW1ic1N3aXBlci5zbGlkZXMuZXEoY3VycmVudFRodW1ic0luZGV4KS5uZXh0QWxsKFwiW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVxcXCJcIiArIHN3aXBlci5yZWFsSW5kZXggKyBcIlxcXCJdXCIpLmVxKDApLmluZGV4KCk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwcmV2VGh1bWJzSW5kZXggPT09ICd1bmRlZmluZWQnKSBuZXdUaHVtYnNJbmRleCA9IG5leHRUaHVtYnNJbmRleDtlbHNlIGlmICh0eXBlb2YgbmV4dFRodW1ic0luZGV4ID09PSAndW5kZWZpbmVkJykgbmV3VGh1bWJzSW5kZXggPSBwcmV2VGh1bWJzSW5kZXg7ZWxzZSBpZiAobmV4dFRodW1ic0luZGV4IC0gY3VycmVudFRodW1ic0luZGV4ID09PSBjdXJyZW50VGh1bWJzSW5kZXggLSBwcmV2VGh1bWJzSW5kZXgpIG5ld1RodW1ic0luZGV4ID0gY3VycmVudFRodW1ic0luZGV4O2Vsc2UgaWYgKG5leHRUaHVtYnNJbmRleCAtIGN1cnJlbnRUaHVtYnNJbmRleCA8IGN1cnJlbnRUaHVtYnNJbmRleCAtIHByZXZUaHVtYnNJbmRleCkgbmV3VGh1bWJzSW5kZXggPSBuZXh0VGh1bWJzSW5kZXg7ZWxzZSBuZXdUaHVtYnNJbmRleCA9IHByZXZUaHVtYnNJbmRleDtcbiAgICAgICAgICBkaXJlY3Rpb24gPSBzd2lwZXIuYWN0aXZlSW5kZXggPiBzd2lwZXIucHJldmlvdXNJbmRleCA/ICduZXh0JyA6ICdwcmV2JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdUaHVtYnNJbmRleCA9IHN3aXBlci5yZWFsSW5kZXg7XG4gICAgICAgICAgZGlyZWN0aW9uID0gbmV3VGh1bWJzSW5kZXggPiBzd2lwZXIucHJldmlvdXNJbmRleCA/ICduZXh0JyA6ICdwcmV2JztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1c2VPZmZzZXQpIHtcbiAgICAgICAgICBuZXdUaHVtYnNJbmRleCArPSBkaXJlY3Rpb24gPT09ICduZXh0JyA/IGF1dG9TY3JvbGxPZmZzZXQgOiAtMSAqIGF1dG9TY3JvbGxPZmZzZXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGh1bWJzU3dpcGVyLnZpc2libGVTbGlkZXNJbmRleGVzICYmIHRodW1ic1N3aXBlci52aXNpYmxlU2xpZGVzSW5kZXhlcy5pbmRleE9mKG5ld1RodW1ic0luZGV4KSA8IDApIHtcbiAgICAgICAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgICAgICAgaWYgKG5ld1RodW1ic0luZGV4ID4gY3VycmVudFRodW1ic0luZGV4KSB7XG4gICAgICAgICAgICAgIG5ld1RodW1ic0luZGV4ID0gbmV3VGh1bWJzSW5kZXggLSBNYXRoLmZsb29yKHNsaWRlc1BlclZpZXcgLyAyKSArIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBuZXdUaHVtYnNJbmRleCA9IG5ld1RodW1ic0luZGV4ICsgTWF0aC5mbG9vcihzbGlkZXNQZXJWaWV3IC8gMikgLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAobmV3VGh1bWJzSW5kZXggPiBjdXJyZW50VGh1bWJzSW5kZXgpIHtcbiAgICAgICAgICAgIG5ld1RodW1ic0luZGV4ID0gbmV3VGh1bWJzSW5kZXggLSBzbGlkZXNQZXJWaWV3ICsgMTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aHVtYnNTd2lwZXIuc2xpZGVUbyhuZXdUaHVtYnNJbmRleCwgaW5pdGlhbCA/IDAgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICB9IC8vIEFjdGl2YXRlIHRodW1ic1xuXG5cbiAgICAgIHZhciB0aHVtYnNUb0FjdGl2YXRlID0gMTtcbiAgICAgIHZhciB0aHVtYkFjdGl2ZUNsYXNzID0gc3dpcGVyLnBhcmFtcy50aHVtYnMuc2xpZGVUaHVtYkFjdGl2ZUNsYXNzO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSAmJiAhc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgICB0aHVtYnNUb0FjdGl2YXRlID0gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3O1xuICAgICAgfVxuXG4gICAgICBpZiAoIXN3aXBlci5wYXJhbXMudGh1bWJzLm11bHRpcGxlQWN0aXZlVGh1bWJzKSB7XG4gICAgICAgIHRodW1ic1RvQWN0aXZhdGUgPSAxO1xuICAgICAgfVxuXG4gICAgICB0aHVtYnNUb0FjdGl2YXRlID0gTWF0aC5mbG9vcih0aHVtYnNUb0FjdGl2YXRlKTtcbiAgICAgIHRodW1ic1N3aXBlci5zbGlkZXMucmVtb3ZlQ2xhc3ModGh1bWJBY3RpdmVDbGFzcyk7XG5cbiAgICAgIGlmICh0aHVtYnNTd2lwZXIucGFyYW1zLmxvb3AgfHwgdGh1bWJzU3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHRodW1ic1N3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGh1bWJzVG9BY3RpdmF0ZTsgaSArPSAxKSB7XG4gICAgICAgICAgdGh1bWJzU3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oXCJbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XFxcIlwiICsgKHN3aXBlci5yZWFsSW5kZXggKyBpKSArIFwiXFxcIl1cIikuYWRkQ2xhc3ModGh1bWJBY3RpdmVDbGFzcyk7XG4gICAgICAgI
166H1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCB0aHVtYnNUb0FjdGl2YXRlOyBfaSArPSAxKSB7XG4gICAgICAgICAgdGh1bWJzU3dpcGVyLnNsaWRlcy5lcShzd2lwZXIucmVhbEluZGV4ICsgX2kpLmFkZENsYXNzKHRodW1iQWN0aXZlQ2xhc3MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuICB2YXIgVGh1bWJzJDEgPSB7XG4gICAgbmFtZTogJ3RodW1icycsXG4gICAgcGFyYW1zOiB7XG4gICAgICB0aHVtYnM6IHtcbiAgICAgICAgc3dpcGVyOiBudWxsLFxuICAgICAgICBtdWx0aXBsZUFjdGl2ZVRodW1iczogdHJ1ZSxcbiAgICAgICAgYXV0b1Njcm9sbE9mZnNldDogMCxcbiAgICAgICAgc2xpZGVUaHVtYkFjdGl2ZUNsYXNzOiAnc3dpcGVyLXNsaWRlLXRodW1iLWFjdGl2ZScsXG4gICAgICAgIHRodW1ic0NvbnRhaW5lckNsYXNzOiAnc3dpcGVyLWNvbnRhaW5lci10aHVtYnMnXG4gICAgICB9XG4gICAgfSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICAgIHZhciBzd2lwZXIgPSB0aGlzO1xuICAgICAgYmluZE1vZHVsZU1ldGhvZHMoc3dpcGVyLCB7XG4gICAgICAgIHRodW1iczogX2V4dGVuZHMoe1xuICAgICAgICAgIHN3aXBlcjogbnVsbCxcbiAgICAgICAgICBpbml0aWFsaXplZDogZmFsc2VcbiAgICAgICAgfSwgVGh1bWJzKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgYmVmb3JlSW5pdDogZnVuY3Rpb24gYmVmb3JlSW5pdChzd2lwZXIpIHtcbiAgICAgICAgdmFyIHRodW1icyA9IHN3aXBlci5wYXJhbXMudGh1bWJzO1xuICAgICAgICBpZiAoIXRodW1icyB8fCAhdGh1bWJzLnN3aXBlcikgcmV0dXJuO1xuICAgICAgICBzd2lwZXIudGh1bWJzLmluaXQoKTtcbiAgICAgICAgc3dpcGVyLnRodW1icy51cGRhdGUodHJ1ZSk7XG4gICAgICB9LFxuICAgICAgc2xpZGVDaGFuZ2U6IGZ1bmN0aW9uIHNsaWRlQ2hhbmdlKHN3aXBlcikge1xuICAgICAgICBpZiAoIXN3aXBlci50aHVtYnMuc3dpcGVyKSByZXR1cm47XG4gICAgICAgIHN3aXBlci50aHVtYnMudXBkYXRlKCk7XG4gICAgICB9LFxuICAgICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUoc3dpcGVyKSB7XG4gICAgICAgIGlmICghc3dpcGVyLnRodW1icy5zd2lwZXIpIHJldHVybjtcbiAgICAgICAgc3dpcGVyLnRodW1icy51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICByZXNpemU6IGZ1bmN0aW9uIHJlc2l6ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIudGh1bWJzLnN3aXBlcikgcmV0dXJuO1xuICAgICAgICBzd2lwZXIudGh1bWJzLnVwZGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIG9ic2VydmVyVXBkYXRlOiBmdW5jdGlvbiBvYnNlcnZlclVwZGF0ZShzd2lwZXIpIHtcbiAgICAgICAgaWYgKCFzd2lwZXIudGh1bWJzLnN3aXBlcikgcmV0dXJuO1xuICAgICAgICBzd2lwZXIudGh1bWJzLnVwZGF0ZSgpO1xuICAgICAgfSxcbiAgICAgIHNldFRyYW5zaXRpb246IGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oc3dpcGVyLCBkdXJhdGlvbikge1xuICAgICAgICB2Y
166XIgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgICAgIGlmICghdGh1bWJzU3dpcGVyKSByZXR1cm47XG4gICAgICAgIHRodW1ic1N3aXBlci5zZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICAgIH0sXG4gICAgICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbiBiZWZvcmVEZXN0cm95KHN3aXBlcikge1xuICAgICAgICB2YXIgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgICAgIGlmICghdGh1bWJzU3dpcGVyKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHN3aXBlci50aHVtYnMuc3dpcGVyQ3JlYXRlZCAmJiB0aHVtYnNTd2lwZXIpIHtcbiAgICAgICAgICB0aHVtYnNTd2lwZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8vIFN3aXBlciBDbGFzc1xuICB2YXIgY29tcG9uZW50cyA9IFtWaXJ0dWFsJDEsIEtleWJvYXJkJDEsIE1vdXNld2hlZWwkMSwgTmF2aWdhdGlvbiQxLCBQYWdpbmF0aW9uJDEsIFNjcm9sbGJhciQxLCBQYXJhbGxheCQxLCBab29tJDEsIExhenkkMSwgQ29udHJvbGxlciQxLCBBMTF5JDEsIEhpc3RvcnkkMSwgSGFzaE5hdmlnYXRpb24kMSwgQXV0b3BsYXkkMSwgRWZmZWN0RmFkZSwgRWZmZWN0Q3ViZSwgRWZmZWN0RmxpcCwgRWZmZWN0Q292ZXJmbG93LCBUaHVtYnMkMV07XG4gIFN3aXBlci51c2UoY29tcG9uZW50cyk7XG5cbiAgcmV0dXJuIFN3aXBlcjtcblxufSkpKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN3aXBlci1idW5kbGUuanMubWFwXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9zd2lwZXIvc3dpcGVyLWJ1bmRsZS5qc1xuLy8gbW9kdWxlIGlkID0gOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQ
166TtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ
166UNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO
1660FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8\n"); 167 168/***/ }) 169/******/ ]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.