/*
 * ATTENTION: An "eval-source-map" devtool has been used.
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else {
		var a = factory();
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(self, function() {
return /******/ (function() { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ "./libs/perfect-scrollbar/perfect-scrollbar.js":
/*!*****************************************************!*\
  !*** ./libs/perfect-scrollbar/perfect-scrollbar.js ***!
  \*****************************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"PerfectScrollbar\": function() { return /* reexport default from dynamic */ perfect_scrollbar_dist_perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0___default.a; }\n/* harmony export */ });\n/* harmony import */ var perfect_scrollbar_dist_perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! perfect-scrollbar/dist/perfect-scrollbar */ \"./node_modules/perfect-scrollbar/dist/perfect-scrollbar.js\");\n/* harmony import */ var perfect_scrollbar_dist_perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(perfect_scrollbar_dist_perfect_scrollbar__WEBPACK_IMPORTED_MODULE_0__);\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9saWJzL3BlcmZlY3Qtc2Nyb2xsYmFyL3BlcmZlY3Qtc2Nyb2xsYmFyLmpzLmpzIiwibWFwcGluZ3MiOiI7Ozs7OztBQUF3RSIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbGlicy9wZXJmZWN0LXNjcm9sbGJhci9wZXJmZWN0LXNjcm9sbGJhci5qcz9iMmMzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQZXJmZWN0U2Nyb2xsYmFyIGZyb20gJ3BlcmZlY3Qtc2Nyb2xsYmFyL2Rpc3QvcGVyZmVjdC1zY3JvbGxiYXInO1xuXG5leHBvcnQgeyBQZXJmZWN0U2Nyb2xsYmFyIH07XG4iXSwibmFtZXMiOlsiUGVyZmVjdFNjcm9sbGJhciJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./libs/perfect-scrollbar/perfect-scrollbar.js\n");

/***/ }),

/***/ "./node_modules/perfect-scrollbar/dist/perfect-scrollbar.js":
/*!******************************************************************!*\
  !*** ./node_modules/perfect-scrollbar/dist/perfect-scrollbar.js ***!
  \******************************************************************/
/***/ (function(module) {

eval("/*!\n * perfect-scrollbar v1.5.3\n * Copyright 2021 Hyunje Jun, MDBootstrap and Contributors\n * Licensed under MIT\n */\n\n(function (global, factory) {\n   true ? module.exports = factory() :\n  0;\n}(this, (function () { 'use strict';\n\n  function get(element) {\n    return getComputedStyle(element);\n  }\n\n  function set(element, obj) {\n    for (var key in obj) {\n      var val = obj[key];\n      if (typeof val === 'number') {\n        val = val + \"px\";\n      }\n      element.style[key] = val;\n    }\n    return element;\n  }\n\n  function div(className) {\n    var div = document.createElement('div');\n    div.className = className;\n    return div;\n  }\n\n  var elMatches =\n    typeof Element !== 'undefined' &&\n    (Element.prototype.matches ||\n      Element.prototype.webkitMatchesSelector ||\n      Element.prototype.mozMatchesSelector ||\n      Element.prototype.msMatchesSelector);\n\n  function matches(element, query) {\n    if (!elMatches) {\n      throw new Error('No element matching method supported');\n    }\n\n    return elMatches.call(element, query);\n  }\n\n  function remove(element) {\n    if (element.remove) {\n      element.remove();\n    } else {\n      if (element.parentNode) {\n        element.parentNode.removeChild(element);\n      }\n    }\n  }\n\n  function queryChildren(element, selector) {\n    return Array.prototype.filter.call(element.children, function (child) { return matches(child, selector); }\n    );\n  }\n\n  var cls = {\n    main: 'ps',\n    rtl: 'ps__rtl',\n    element: {\n      thumb: function (x) { return (\"ps__thumb-\" + x); },\n      rail: function (x) { return (\"ps__rail-\" + x); },\n      consuming: 'ps__child--consume',\n    },\n    state: {\n      focus: 'ps--focus',\n      clicking: 'ps--clicking',\n      active: function (x) { return (\"ps--active-\" + x); },\n      scrolling: function (x) { return (\"ps--scrolling-\" + x); },\n    },\n  };\n\n  /*\n   * Helper methods\n   */\n  var scrollingClassTimeout = { x: null, y: null };\n\n  function addScrollingClass(i, x) {\n    var classList = i.element.classList;\n    var className = cls.state.scrolling(x);\n\n    if (classList.contains(className)) {\n      clearTimeout(scrollingClassTimeout[x]);\n    } else {\n      classList.add(className);\n    }\n  }\n\n  function removeScrollingClass(i, x) {\n    scrollingClassTimeout[x] = setTimeout(\n      function () { return i.isAlive && i.element.classList.remove(cls.state.scrolling(x)); },\n      i.settings.scrollingThreshold\n    );\n  }\n\n  function setScrollingClassInstantly(i, x) {\n    addScrollingClass(i, x);\n    removeScrollingClass(i, x);\n  }\n\n  var EventElement = function EventElement(element) {\n    this.element = element;\n    this.handlers = {};\n  };\n\n  var prototypeAccessors = { isEmpty: { configurable: true } };\n\n  EventElement.prototype.bind = function bind (eventName, handler) {\n    if (typeof this.handlers[eventName] === 'undefined') {\n      this.handlers[eventName] = [];\n    }\n    this.handlers[eventName].push(handler);\n    this.element.addEventListener(eventName, handler, false);\n  };\n\n  EventElement.prototype.unbind = function unbind (eventName, target) {\n      var this$1 = this;\n\n    this.handlers[eventName] = this.handlers[eventName].filter(function (handler) {\n      if (target && handler !== target) {\n        return true;\n      }\n      this$1.element.removeEventListener(eventName, handler, false);\n      return false;\n    });\n  };\n\n  EventElement.prototype.unbindAll = function unbindAll () {\n    for (var name in this.handlers) {\n      this.unbind(name);\n    }\n  };\n\n  prototypeAccessors.isEmpty.get = function () {\n      var this$1 = this;\n\n    return Object.keys(this.handlers).every(\n      function (key) { return this$1.handlers[key].length === 0; }\n    );\n  };\n\n  Object.defineProperties( EventElement.prototype, prototypeAccessors );\n\n  var EventManager = function EventManager() {\n    this.eventElements = [];\n  };\n\n  EventManager.prototype.eventElement = function eventElement (element) {\n    var ee = this.eventElements.filter(function (ee) { return ee.element === element; })[0];\n    if (!ee) {\n      ee = new EventElement(element);\n      this.eventElements.push(ee);\n    }\n    return ee;\n  };\n\n  EventManager.prototype.bind = function bind (element, eventName, handler) {\n    this.eventElement(element).bind(eventName, handler);\n  };\n\n  EventManager.prototype.unbind = function unbind (element, eventName, handler) {\n    var ee = this.eventElement(element);\n    ee.unbind(eventName, handler);\n\n    if (ee.isEmpty) {\n      // remove\n      this.eventElements.splice(this.eventElements.indexOf(ee), 1);\n    }\n  };\n\n  EventManager.prototype.unbindAll = function unbindAll () {\n    this.eventElements.forEach(function (e) { return e.unbindAll(); });\n    this.eventElements = [];\n  };\n\n  EventManager.prototype.once = function once (element, eventName, handler) {\n    var ee = this.eventElement(element);\n    var onceHandler = function (evt) {\n      ee.unbind(eventName, onceHandler);\n      handler(evt);\n    };\n    ee.bind(eventName, onceHandler);\n  };\n\n  function createEvent(name) {\n    if (typeof window.CustomEvent === 'function') {\n      return new CustomEvent(name);\n    } else {\n      var evt = document.createEvent('CustomEvent');\n      evt.initCustomEvent(name, false, false, undefined);\n      return evt;\n    }\n  }\n\n  function processScrollDiff(\n    i,\n    axis,\n    diff,\n    useScrollingClass,\n    forceFireReachEvent\n  ) {\n    if ( useScrollingClass === void 0 ) useScrollingClass = true;\n    if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;\n\n    var fields;\n    if (axis === 'top') {\n      fields = [\n        'contentHeight',\n        'containerHeight',\n        'scrollTop',\n        'y',\n        'up',\n        'down' ];\n    } else if (axis === 'left') {\n      fields = [\n        'contentWidth',\n        'containerWidth',\n        'scrollLeft',\n        'x',\n        'left',\n        'right' ];\n    } else {\n      throw new Error('A proper axis should be provided');\n    }\n\n    processScrollDiff$1(i, diff, fields, useScrollingClass, forceFireReachEvent);\n  }\n\n  function processScrollDiff$1(\n    i,\n    diff,\n    ref,\n    useScrollingClass,\n    forceFireReachEvent\n  ) {\n    var contentHeight = ref[0];\n    var containerHeight = ref[1];\n    var scrollTop = ref[2];\n    var y = ref[3];\n    var up = ref[4];\n    var down = ref[5];\n    if ( useScrollingClass === void 0 ) useScrollingClass = true;\n    if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;\n\n    var element = i.element;\n\n    // reset reach\n    i.reach[y] = null;\n\n    // 1 for subpixel rounding\n    if (element[scrollTop] < 1) {\n      i.reach[y] = 'start';\n    }\n\n    // 1 for subpixel rounding\n    if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) {\n      i.reach[y] = 'end';\n    }\n\n    if (diff) {\n      element.dispatchEvent(createEvent((\"ps-scroll-\" + y)));\n\n      if (diff < 0) {\n        element.dispatchEvent(createEvent((\"ps-scroll-\" + up)));\n      } else if (diff > 0) {\n        element.dispatchEvent(createEvent((\"ps-scroll-\" + down)));\n      }\n\n      if (useScrollingClass) {\n        setScrollingClassInstantly(i, y);\n      }\n    }\n\n    if (i.reach[y] && (diff || forceFireReachEvent)) {\n      element.dispatchEvent(createEvent((\"ps-\" + y + \"-reach-\" + (i.reach[y]))));\n    }\n  }\n\n  function toInt(x) {\n    return parseInt(x, 10) || 0;\n  }\n\n  function isEditable(el) {\n    return (\n      matches(el, 'input,[contenteditable]') ||\n      matches(el, 'select,[contenteditable]') ||\n      matches(el, 'textarea,[contenteditable]') ||\n      matches(el, 'button,[contenteditable]')\n    );\n  }\n\n  function outerWidth(element) {\n    var styles = get(element);\n    return (\n      toInt(styles.width) +\n      toInt(styles.paddingLeft) +\n      toInt(styles.paddingRight) +\n      toInt(styles.borderLeftWidth) +\n      toInt(styles.borderRightWidth)\n    );\n  }\n\n  var env = {\n    isWebKit:\n      typeof document !== 'undefined' &&\n      'WebkitAppearance' in document.documentElement.style,\n    supportsTouch:\n      typeof window !== 'undefined' &&\n      ('ontouchstart' in window ||\n        ('maxTouchPoints' in window.navigator &&\n          window.navigator.maxTouchPoints > 0) ||\n        (window.DocumentTouch && document instanceof window.DocumentTouch)),\n    supportsIePointer:\n      typeof navigator !== 'undefined' && navigator.msMaxTouchPoints,\n    isChrome:\n      typeof navigator !== 'undefined' &&\n      /Chrome/i.test(navigator && navigator.userAgent),\n  };\n\n  function updateGeometry(i) {\n    var element = i.element;\n    var roundedScrollTop = Math.floor(element.scrollTop);\n    var rect = element.getBoundingClientRect();\n\n    i.containerWidth = Math.round(rect.width);\n    i.containerHeight = Math.round(rect.height);\n\n    i.contentWidth = element.scrollWidth;\n    i.contentHeight = element.scrollHeight;\n\n    if (!element.contains(i.scrollbarXRail)) {\n      // clean up and append\n      queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); }\n      );\n      element.appendChild(i.scrollbarXRail);\n    }\n    if (!element.contains(i.scrollbarYRail)) {\n      // clean up and append\n      queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); }\n      );\n      element.appendChild(i.scrollbarYRail);\n    }\n\n    if (\n      !i.settings.suppressScrollX &&\n      i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth\n    ) {\n      i.scrollbarXActive = true;\n      i.railXWidth = i.containerWidth - i.railXMarginWidth;\n      i.railXRatio = i.containerWidth / i.railXWidth;\n      i.scrollbarXWidth = getThumbSize(\n        i,\n        toInt((i.railXWidth * i.containerWidth) / i.contentWidth)\n      );\n      i.scrollbarXLeft = toInt(\n        ((i.negativeScrollAdjustment + element.scrollLeft) *\n          (i.railXWidth - i.scrollbarXWidth)) /\n          (i.contentWidth - i.containerWidth)\n      );\n    } else {\n      i.scrollbarXActive = false;\n    }\n\n    if (\n      !i.settings.suppressScrollY &&\n      i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight\n    ) {\n      i.scrollbarYActive = true;\n      i.railYHeight = i.containerHeight - i.railYMarginHeight;\n      i.railYRatio = i.containerHeight / i.railYHeight;\n      i.scrollbarYHeight = getThumbSize(\n        i,\n        toInt((i.railYHeight * i.containerHeight) / i.contentHeight)\n      );\n      i.scrollbarYTop = toInt(\n        (roundedScrollTop * (i.railYHeight - i.scrollbarYHeight)) /\n          (i.contentHeight - i.containerHeight)\n      );\n    } else {\n      i.scrollbarYActive = false;\n    }\n\n    if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {\n      i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;\n    }\n    if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {\n      i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;\n    }\n\n    updateCss(element, i);\n\n    if (i.scrollbarXActive) {\n      element.classList.add(cls.state.active('x'));\n    } else {\n      element.classList.remove(cls.state.active('x'));\n      i.scrollbarXWidth = 0;\n      i.scrollbarXLeft = 0;\n      element.scrollLeft = i.isRtl === true ? i.contentWidth : 0;\n    }\n    if (i.scrollbarYActive) {\n      element.classList.add(cls.state.active('y'));\n    } else {\n      element.classList.remove(cls.state.active('y'));\n      i.scrollbarYHeight = 0;\n      i.scrollbarYTop = 0;\n      element.scrollTop = 0;\n    }\n  }\n\n  function getThumbSize(i, thumbSize) {\n    if (i.settings.minScrollbarLength) {\n      thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);\n    }\n    if (i.settings.maxScrollbarLength) {\n      thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);\n    }\n    return thumbSize;\n  }\n\n  function updateCss(element, i) {\n    var xRailOffset = { width: i.railXWidth };\n    var roundedScrollTop = Math.floor(element.scrollTop);\n\n    if (i.isRtl) {\n      xRailOffset.left =\n        i.negativeScrollAdjustment +\n        element.scrollLeft +\n        i.containerWidth -\n        i.contentWidth;\n    } else {\n      xRailOffset.left = element.scrollLeft;\n    }\n    if (i.isScrollbarXUsingBottom) {\n      xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop;\n    } else {\n      xRailOffset.top = i.scrollbarXTop + roundedScrollTop;\n    }\n    set(i.scrollbarXRail, xRailOffset);\n\n    var yRailOffset = { top: roundedScrollTop, height: i.railYHeight };\n    if (i.isScrollbarYUsingRight) {\n      if (i.isRtl) {\n        yRailOffset.right =\n          i.contentWidth -\n          (i.negativeScrollAdjustment + element.scrollLeft) -\n          i.scrollbarYRight -\n          i.scrollbarYOuterWidth -\n          9;\n      } else {\n        yRailOffset.right = i.scrollbarYRight - element.scrollLeft;\n      }\n    } else {\n      if (i.isRtl) {\n        yRailOffset.left =\n          i.negativeScrollAdjustment +\n          element.scrollLeft +\n          i.containerWidth * 2 -\n          i.contentWidth -\n          i.scrollbarYLeft -\n          i.scrollbarYOuterWidth;\n      } else {\n        yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;\n      }\n    }\n    set(i.scrollbarYRail, yRailOffset);\n\n    set(i.scrollbarX, {\n      left: i.scrollbarXLeft,\n      width: i.scrollbarXWidth - i.railBorderXWidth,\n    });\n    set(i.scrollbarY, {\n      top: i.scrollbarYTop,\n      height: i.scrollbarYHeight - i.railBorderYWidth,\n    });\n  }\n\n  function clickRail(i) {\n    var element = i.element;\n\n    i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); });\n    i.event.bind(i.scrollbarYRail, 'mousedown', function (e) {\n      var positionTop =\n        e.pageY -\n        window.pageYOffset -\n        i.scrollbarYRail.getBoundingClientRect().top;\n      var direction = positionTop > i.scrollbarYTop ? 1 : -1;\n\n      i.element.scrollTop += direction * i.containerHeight;\n      updateGeometry(i);\n\n      e.stopPropagation();\n    });\n\n    i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); });\n    i.event.bind(i.scrollbarXRail, 'mousedown', function (e) {\n      var positionLeft =\n        e.pageX -\n        window.pageXOffset -\n        i.scrollbarXRail.getBoundingClientRect().left;\n      var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;\n\n      i.element.scrollLeft += direction * i.containerWidth;\n      updateGeometry(i);\n\n      e.stopPropagation();\n    });\n  }\n\n  function dragThumb(i) {\n    bindMouseScrollHandler(i, [\n      'containerWidth',\n      'contentWidth',\n      'pageX',\n      'railXWidth',\n      'scrollbarX',\n      'scrollbarXWidth',\n      'scrollLeft',\n      'x',\n      'scrollbarXRail' ]);\n    bindMouseScrollHandler(i, [\n      'containerHeight',\n      'contentHeight',\n      'pageY',\n      'railYHeight',\n      'scrollbarY',\n      'scrollbarYHeight',\n      'scrollTop',\n      'y',\n      'scrollbarYRail' ]);\n  }\n\n  function bindMouseScrollHandler(\n    i,\n    ref\n  ) {\n    var containerHeight = ref[0];\n    var contentHeight = ref[1];\n    var pageY = ref[2];\n    var railYHeight = ref[3];\n    var scrollbarY = ref[4];\n    var scrollbarYHeight = ref[5];\n    var scrollTop = ref[6];\n    var y = ref[7];\n    var scrollbarYRail = ref[8];\n\n    var element = i.element;\n\n    var startingScrollTop = null;\n    var startingMousePageY = null;\n    var scrollBy = null;\n\n    function mouseMoveHandler(e) {\n      if (e.touches && e.touches[0]) {\n        e[pageY] = e.touches[0].pageY;\n      }\n      element[scrollTop] =\n        startingScrollTop + scrollBy * (e[pageY] - startingMousePageY);\n      addScrollingClass(i, y);\n      updateGeometry(i);\n\n      e.stopPropagation();\n      if (e.type.startsWith('touch') && e.changedTouches.length > 1) {\n        e.preventDefault();\n      }\n    }\n\n    function mouseUpHandler() {\n      removeScrollingClass(i, y);\n      i[scrollbarYRail].classList.remove(cls.state.clicking);\n      i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n    }\n\n    function bindMoves(e, touchMode) {\n      startingScrollTop = element[scrollTop];\n      if (touchMode && e.touches) {\n        e[pageY] = e.touches[0].pageY;\n      }\n      startingMousePageY = e[pageY];\n      scrollBy =\n        (i[contentHeight] - i[containerHeight]) /\n        (i[railYHeight] - i[scrollbarYHeight]);\n      if (!touchMode) {\n        i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);\n        i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);\n        e.preventDefault();\n      } else {\n        i.event.bind(i.ownerDocument, 'touchmove', mouseMoveHandler);\n      }\n\n      i[scrollbarYRail].classList.add(cls.state.clicking);\n\n      e.stopPropagation();\n    }\n\n    i.event.bind(i[scrollbarY], 'mousedown', function (e) {\n      bindMoves(e);\n    });\n    i.event.bind(i[scrollbarY], 'touchstart', function (e) {\n      bindMoves(e, true);\n    });\n  }\n\n  function keyboard(i) {\n    var element = i.element;\n\n    var elementHovered = function () { return matches(element, ':hover'); };\n    var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); };\n\n    function shouldPreventDefault(deltaX, deltaY) {\n      var scrollTop = Math.floor(element.scrollTop);\n      if (deltaX === 0) {\n        if (!i.scrollbarYActive) {\n          return false;\n        }\n        if (\n          (scrollTop === 0 && deltaY > 0) ||\n          (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)\n        ) {\n          return !i.settings.wheelPropagation;\n        }\n      }\n\n      var scrollLeft = element.scrollLeft;\n      if (deltaY === 0) {\n        if (!i.scrollbarXActive) {\n          return false;\n        }\n        if (\n          (scrollLeft === 0 && deltaX < 0) ||\n          (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)\n        ) {\n          return !i.settings.wheelPropagation;\n        }\n      }\n      return true;\n    }\n\n    i.event.bind(i.ownerDocument, 'keydown', function (e) {\n      if (\n        (e.isDefaultPrevented && e.isDefaultPrevented()) ||\n        e.defaultPrevented\n      ) {\n        return;\n      }\n\n      if (!elementHovered() && !scrollbarFocused()) {\n        return;\n      }\n\n      var activeElement = document.activeElement\n        ? document.activeElement\n        : i.ownerDocument.activeElement;\n      if (activeElement) {\n        if (activeElement.tagName === 'IFRAME') {\n          activeElement = activeElement.contentDocument.activeElement;\n        } else {\n          // go deeper if element is a webcomponent\n          while (activeElement.shadowRoot) {\n            activeElement = activeElement.shadowRoot.activeElement;\n          }\n        }\n        if (isEditable(activeElement)) {\n          return;\n        }\n      }\n\n      var deltaX = 0;\n      var deltaY = 0;\n\n      switch (e.which) {\n        case 37: // left\n          if (e.metaKey) {\n            deltaX = -i.contentWidth;\n          } else if (e.altKey) {\n            deltaX = -i.containerWidth;\n          } else {\n            deltaX = -30;\n          }\n          break;\n        case 38: // up\n          if (e.metaKey) {\n            deltaY = i.contentHeight;\n          } else if (e.altKey) {\n            deltaY = i.containerHeight;\n          } else {\n            deltaY = 30;\n          }\n          break;\n        case 39: // right\n          if (e.metaKey) {\n            deltaX = i.contentWidth;\n          } else if (e.altKey) {\n            deltaX = i.containerWidth;\n          } else {\n            deltaX = 30;\n          }\n          break;\n        case 40: // down\n          if (e.metaKey) {\n            deltaY = -i.contentHeight;\n          } else if (e.altKey) {\n            deltaY = -i.containerHeight;\n          } else {\n            deltaY = -30;\n          }\n          break;\n        case 32: // space bar\n          if (e.shiftKey) {\n            deltaY = i.containerHeight;\n          } else {\n            deltaY = -i.containerHeight;\n          }\n          break;\n        case 33: // page up\n          deltaY = i.containerHeight;\n          break;\n        case 34: // page down\n          deltaY = -i.containerHeight;\n          break;\n        case 36: // home\n          deltaY = i.contentHeight;\n          break;\n        case 35: // end\n          deltaY = -i.contentHeight;\n          break;\n        default:\n          return;\n      }\n\n      if (i.settings.suppressScrollX && deltaX !== 0) {\n        return;\n      }\n      if (i.settings.suppressScrollY && deltaY !== 0) {\n        return;\n      }\n\n      element.scrollTop -= deltaY;\n      element.scrollLeft += deltaX;\n      updateGeometry(i);\n\n      if (shouldPreventDefault(deltaX, deltaY)) {\n        e.preventDefault();\n      }\n    });\n  }\n\n  function wheel(i) {\n    var element = i.element;\n\n    function shouldPreventDefault(deltaX, deltaY) {\n      var roundedScrollTop = Math.floor(element.scrollTop);\n      var isTop = element.scrollTop === 0;\n      var isBottom =\n        roundedScrollTop + element.offsetHeight === element.scrollHeight;\n      var isLeft = element.scrollLeft === 0;\n      var isRight =\n        element.scrollLeft + element.offsetWidth === element.scrollWidth;\n\n      var hitsBound;\n\n      // pick axis with primary direction\n      if (Math.abs(deltaY) > Math.abs(deltaX)) {\n        hitsBound = isTop || isBottom;\n      } else {\n        hitsBound = isLeft || isRight;\n      }\n\n      return hitsBound ? !i.settings.wheelPropagation : true;\n    }\n\n    function getDeltaFromEvent(e) {\n      var deltaX = e.deltaX;\n      var deltaY = -1 * e.deltaY;\n\n      if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') {\n        // OS X Safari\n        deltaX = (-1 * e.wheelDeltaX) / 6;\n        deltaY = e.wheelDeltaY / 6;\n      }\n\n      if (e.deltaMode && e.deltaMode === 1) {\n        // Firefox in deltaMode 1: Line scrolling\n        deltaX *= 10;\n        deltaY *= 10;\n      }\n\n      if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) {\n        // IE in some mouse drivers\n        deltaX = 0;\n        deltaY = e.wheelDelta;\n      }\n\n      if (e.shiftKey) {\n        // reverse axis with shift key\n        return [-deltaY, -deltaX];\n      }\n      return [deltaX, deltaY];\n    }\n\n    function shouldBeConsumedByChild(target, deltaX, deltaY) {\n      // FIXME: this is a workaround for <select> issue in FF and IE #571\n      if (!env.isWebKit && element.querySelector('select:focus')) {\n        return true;\n      }\n\n      if (!element.contains(target)) {\n        return false;\n      }\n\n      var cursor = target;\n\n      while (cursor && cursor !== element) {\n        if (cursor.classList.contains(cls.element.consuming)) {\n          return true;\n        }\n\n        var style = get(cursor);\n\n        // if deltaY && vertical scrollable\n        if (deltaY && style.overflowY.match(/(scroll|auto)/)) {\n          var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;\n          if (maxScrollTop > 0) {\n            if (\n              (cursor.scrollTop > 0 && deltaY < 0) ||\n              (cursor.scrollTop < maxScrollTop && deltaY > 0)\n            ) {\n              return true;\n            }\n          }\n        }\n        // if deltaX && horizontal scrollable\n        if (deltaX && style.overflowX.match(/(scroll|auto)/)) {\n          var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth;\n          if (maxScrollLeft > 0) {\n            if (\n              (cursor.scrollLeft > 0 && deltaX < 0) ||\n              (cursor.scrollLeft < maxScrollLeft && deltaX > 0)\n            ) {\n              return true;\n            }\n          }\n        }\n\n        cursor = cursor.parentNode;\n      }\n\n      return false;\n    }\n\n    function mousewheelHandler(e) {\n      var ref = getDeltaFromEvent(e);\n      var deltaX = ref[0];\n      var deltaY = ref[1];\n\n      if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) {\n        return;\n      }\n\n      var shouldPrevent = false;\n      if (!i.settings.useBothWheelAxes) {\n        // deltaX will only be used for horizontal scrolling and deltaY will\n        // only be used for vertical scrolling - this is the default\n        element.scrollTop -= deltaY * i.settings.wheelSpeed;\n        element.scrollLeft += deltaX * i.settings.wheelSpeed;\n      } else if (i.scrollbarYActive && !i.scrollbarXActive) {\n        // only vertical scrollbar is active and useBothWheelAxes option is\n        // active, so let's scroll vertical bar using both mouse wheel axes\n        if (deltaY) {\n          element.scrollTop -= deltaY * i.settings.wheelSpeed;\n        } else {\n          element.scrollTop += deltaX * i.settings.wheelSpeed;\n        }\n        shouldPrevent = true;\n      } else if (i.scrollbarXActive && !i.scrollbarYActive) {\n        // useBothWheelAxes and only horizontal bar is active, so use both\n        // wheel axes for horizontal bar\n        if (deltaX) {\n          element.scrollLeft += deltaX * i.settings.wheelSpeed;\n        } else {\n          element.scrollLeft -= deltaY * i.settings.wheelSpeed;\n        }\n        shouldPrevent = true;\n      }\n\n      updateGeometry(i);\n\n      shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY);\n      if (shouldPrevent && !e.ctrlKey) {\n        e.stopPropagation();\n        e.preventDefault();\n      }\n    }\n\n    if (typeof window.onwheel !== 'undefined') {\n      i.event.bind(element, 'wheel', mousewheelHandler);\n    } else if (typeof window.onmousewheel !== 'undefined') {\n      i.event.bind(element, 'mousewheel', mousewheelHandler);\n    }\n  }\n\n  function touch(i) {\n    if (!env.supportsTouch && !env.supportsIePointer) {\n      return;\n    }\n\n    var element = i.element;\n\n    function shouldPrevent(deltaX, deltaY) {\n      var scrollTop = Math.floor(element.scrollTop);\n      var scrollLeft = element.scrollLeft;\n      var magnitudeX = Math.abs(deltaX);\n      var magnitudeY = Math.abs(deltaY);\n\n      if (magnitudeY > magnitudeX) {\n        // user is perhaps trying to swipe up/down the page\n\n        if (\n          (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) ||\n          (deltaY > 0 && scrollTop === 0)\n        ) {\n          // set prevent for mobile Chrome refresh\n          return window.scrollY === 0 && deltaY > 0 && env.isChrome;\n        }\n      } else if (magnitudeX > magnitudeY) {\n        // user is perhaps trying to swipe left/right across the page\n\n        if (\n          (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) ||\n          (deltaX > 0 && scrollLeft === 0)\n        ) {\n          return true;\n        }\n      }\n\n      return true;\n    }\n\n    function applyTouchMove(differenceX, differenceY) {\n      element.scrollTop -= differenceY;\n      element.scrollLeft -= differenceX;\n\n      updateGeometry(i);\n    }\n\n    var startOffset = {};\n    var startTime = 0;\n    var speed = {};\n    var easingLoop = null;\n\n    function getTouch(e) {\n      if (e.targetTouches) {\n        return e.targetTouches[0];\n      } else {\n        // Maybe IE pointer\n        return e;\n      }\n    }\n\n    function shouldHandle(e) {\n      if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) {\n        return false;\n      }\n      if (e.targetTouches && e.targetTouches.length === 1) {\n        return true;\n      }\n      if (\n        e.pointerType &&\n        e.pointerType !== 'mouse' &&\n        e.pointerType !== e.MSPOINTER_TYPE_MOUSE\n      ) {\n        return true;\n      }\n      return false;\n    }\n\n    function touchStart(e) {\n      if (!shouldHandle(e)) {\n        return;\n      }\n\n      var touch = getTouch(e);\n\n      startOffset.pageX = touch.pageX;\n      startOffset.pageY = touch.pageY;\n\n      startTime = new Date().getTime();\n\n      if (easingLoop !== null) {\n        clearInterval(easingLoop);\n      }\n    }\n\n    function shouldBeConsumedByChild(target, deltaX, deltaY) {\n      if (!element.contains(target)) {\n        return false;\n      }\n\n      var cursor = target;\n\n      while (cursor && cursor !== element) {\n        if (cursor.classList.contains(cls.element.consuming)) {\n          return true;\n        }\n\n        var style = get(cursor);\n\n        // if deltaY && vertical scrollable\n        if (deltaY && style.overflowY.match(/(scroll|auto)/)) {\n          var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;\n          if (maxScrollTop > 0) {\n            if (\n              (cursor.scrollTop > 0 && deltaY < 0) ||\n              (cursor.scrollTop < maxScrollTop && deltaY > 0)\n            ) {\n              return true;\n            }\n          }\n        }\n        // if deltaX && horizontal scrollable\n        if (deltaX && style.overflowX.match(/(scroll|auto)/)) {\n          var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth;\n          if (maxScrollLeft > 0) {\n            if (\n              (cursor.scrollLeft > 0 && deltaX < 0) ||\n              (cursor.scrollLeft < maxScrollLeft && deltaX > 0)\n            ) {\n              return true;\n            }\n          }\n        }\n\n        cursor = cursor.parentNode;\n      }\n\n      return false;\n    }\n\n    function touchMove(e) {\n      if (shouldHandle(e)) {\n        var touch = getTouch(e);\n\n        var currentOffset = { pageX: touch.pageX, pageY: touch.pageY };\n\n        var differenceX = currentOffset.pageX - startOffset.pageX;\n        var differenceY = currentOffset.pageY - startOffset.pageY;\n\n        if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) {\n          return;\n        }\n\n        applyTouchMove(differenceX, differenceY);\n        startOffset = currentOffset;\n\n        var currentTime = new Date().getTime();\n\n        var timeGap = currentTime - startTime;\n        if (timeGap > 0) {\n          speed.x = differenceX / timeGap;\n          speed.y = differenceY / timeGap;\n          startTime = currentTime;\n        }\n\n        if (shouldPrevent(differenceX, differenceY)) {\n          e.preventDefault();\n        }\n      }\n    }\n    function touchEnd() {\n      if (i.settings.swipeEasing) {\n        clearInterval(easingLoop);\n        easingLoop = setInterval(function() {\n          if (i.isInitialized) {\n            clearInterval(easingLoop);\n            return;\n          }\n\n          if (!speed.x && !speed.y) {\n            clearInterval(easingLoop);\n            return;\n          }\n\n          if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {\n            clearInterval(easingLoop);\n            return;\n          }\n\n          if (!i.element) {\n            clearInterval(easingLoop);\n            return;\n          }\n\n          applyTouchMove(speed.x * 30, speed.y * 30);\n\n          speed.x *= 0.8;\n          speed.y *= 0.8;\n        }, 10);\n      }\n    }\n\n    if (env.supportsTouch) {\n      i.event.bind(element, 'touchstart', touchStart);\n      i.event.bind(element, 'touchmove', touchMove);\n      i.event.bind(element, 'touchend', touchEnd);\n    } else if (env.supportsIePointer) {\n      if (window.PointerEvent) {\n        i.event.bind(element, 'pointerdown', touchStart);\n        i.event.bind(element, 'pointermove', touchMove);\n        i.event.bind(element, 'pointerup', touchEnd);\n      } else if (window.MSPointerEvent) {\n        i.event.bind(element, 'MSPointerDown', touchStart);\n        i.event.bind(element, 'MSPointerMove', touchMove);\n        i.event.bind(element, 'MSPointerUp', touchEnd);\n      }\n    }\n  }\n\n  var defaultSettings = function () { return ({\n    handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],\n    maxScrollbarLength: null,\n    minScrollbarLength: null,\n    scrollingThreshold: 1000,\n    scrollXMarginOffset: 0,\n    scrollYMarginOffset: 0,\n    suppressScrollX: false,\n    suppressScrollY: false,\n    swipeEasing: true,\n    useBothWheelAxes: false,\n    wheelPropagation: true,\n    wheelSpeed: 1,\n  }); };\n\n  var handlers = {\n    'click-rail': clickRail,\n    'drag-thumb': dragThumb,\n    keyboard: keyboard,\n    wheel: wheel,\n    touch: touch,\n  };\n\n  var PerfectScrollbar = function PerfectScrollbar(element, userSettings) {\n    var this$1 = this;\n    if ( userSettings === void 0 ) userSettings = {};\n\n    if (typeof element === 'string') {\n      element = document.querySelector(element);\n    }\n\n    if (!element || !element.nodeName) {\n      throw new Error('no element is specified to initialize PerfectScrollbar');\n    }\n\n    this.element = element;\n\n    element.classList.add(cls.main);\n\n    this.settings = defaultSettings();\n    for (var key in userSettings) {\n      this.settings[key] = userSettings[key];\n    }\n\n    this.containerWidth = null;\n    this.containerHeight = null;\n    this.contentWidth = null;\n    this.contentHeight = null;\n\n    var focus = function () { return element.classList.add(cls.state.focus); };\n    var blur = function () { return element.classList.remove(cls.state.focus); };\n\n    this.isRtl = get(element).direction === 'rtl';\n    if (this.isRtl === true) {\n      element.classList.add(cls.rtl);\n    }\n    this.isNegativeScroll = (function () {\n      var originalScrollLeft = element.scrollLeft;\n      var result = null;\n      element.scrollLeft = -1;\n      result = element.scrollLeft < 0;\n      element.scrollLeft = originalScrollLeft;\n      return result;\n    })();\n    this.negativeScrollAdjustment = this.isNegativeScroll\n      ? element.scrollWidth - element.clientWidth\n      : 0;\n    this.event = new EventManager();\n    this.ownerDocument = element.ownerDocument || document;\n\n    this.scrollbarXRail = div(cls.element.rail('x'));\n    element.appendChild(this.scrollbarXRail);\n    this.scrollbarX = div(cls.element.thumb('x'));\n    this.scrollbarXRail.appendChild(this.scrollbarX);\n    this.scrollbarX.setAttribute('tabindex', 0);\n    this.event.bind(this.scrollbarX, 'focus', focus);\n    this.event.bind(this.scrollbarX, 'blur', blur);\n    this.scrollbarXActive = null;\n    this.scrollbarXWidth = null;\n    this.scrollbarXLeft = null;\n    var railXStyle = get(this.scrollbarXRail);\n    this.scrollbarXBottom = parseInt(railXStyle.bottom, 10);\n    if (isNaN(this.scrollbarXBottom)) {\n      this.isScrollbarXUsingBottom = false;\n      this.scrollbarXTop = toInt(railXStyle.top);\n    } else {\n      this.isScrollbarXUsingBottom = true;\n    }\n    this.railBorderXWidth =\n      toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth);\n    // Set rail to display:block to calculate margins\n    set(this.scrollbarXRail, { display: 'block' });\n    this.railXMarginWidth =\n      toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight);\n    set(this.scrollbarXRail, { display: '' });\n    this.railXWidth = null;\n    this.railXRatio = null;\n\n    this.scrollbarYRail = div(cls.element.rail('y'));\n    element.appendChild(this.scrollbarYRail);\n    this.scrollbarY = div(cls.element.thumb('y'));\n    this.scrollbarYRail.appendChild(this.scrollbarY);\n    this.scrollbarY.setAttribute('tabindex', 0);\n    this.event.bind(this.scrollbarY, 'focus', focus);\n    this.event.bind(this.scrollbarY, 'blur', blur);\n    this.scrollbarYActive = null;\n    this.scrollbarYHeight = null;\n    this.scrollbarYTop = null;\n    var railYStyle = get(this.scrollbarYRail);\n    this.scrollbarYRight = parseInt(railYStyle.right, 10);\n    if (isNaN(this.scrollbarYRight)) {\n      this.isScrollbarYUsingRight = false;\n      this.scrollbarYLeft = toInt(railYStyle.left);\n    } else {\n      this.isScrollbarYUsingRight = true;\n    }\n    this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null;\n    this.railBorderYWidth =\n      toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth);\n    set(this.scrollbarYRail, { display: 'block' });\n    this.railYMarginHeight =\n      toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom);\n    set(this.scrollbarYRail, { display: '' });\n    this.railYHeight = null;\n    this.railYRatio = null;\n\n    this.reach = {\n      x:\n        element.scrollLeft <= 0\n          ? 'start'\n          : element.scrollLeft >= this.contentWidth - this.containerWidth\n          ? 'end'\n          : null,\n      y:\n        element.scrollTop <= 0\n          ? 'start'\n          : element.scrollTop >= this.contentHeight - this.containerHeight\n          ? 'end'\n          : null,\n    };\n\n    this.isAlive = true;\n\n    this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); });\n\n    this.lastScrollTop = Math.floor(element.scrollTop); // for onScroll only\n    this.lastScrollLeft = element.scrollLeft; // for onScroll only\n    this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); });\n    updateGeometry(this);\n  };\n\n  PerfectScrollbar.prototype.update = function update () {\n    if (!this.isAlive) {\n      return;\n    }\n\n    // Recalcuate negative scrollLeft adjustment\n    this.negativeScrollAdjustment = this.isNegativeScroll\n      ? this.element.scrollWidth - this.element.clientWidth\n      : 0;\n\n    // Recalculate rail margins\n    set(this.scrollbarXRail, { display: 'block' });\n    set(this.scrollbarYRail, { display: 'block' });\n    this.railXMarginWidth =\n      toInt(get(this.scrollbarXRail).marginLeft) +\n      toInt(get(this.scrollbarXRail).marginRight);\n    this.railYMarginHeight =\n      toInt(get(this.scrollbarYRail).marginTop) +\n      toInt(get(this.scrollbarYRail).marginBottom);\n\n    // Hide scrollbars not to affect scrollWidth and scrollHeight\n    set(this.scrollbarXRail, { display: 'none' });\n    set(this.scrollbarYRail, { display: 'none' });\n\n    updateGeometry(this);\n\n    processScrollDiff(this, 'top', 0, false, true);\n    processScrollDiff(this, 'left', 0, false, true);\n\n    set(this.scrollbarXRail, { display: '' });\n    set(this.scrollbarYRail, { display: '' });\n  };\n\n  PerfectScrollbar.prototype.onScroll = function onScroll (e) {\n    if (!this.isAlive) {\n      return;\n    }\n\n    updateGeometry(this);\n    processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop);\n    processScrollDiff(\n      this,\n      'left',\n      this.element.scrollLeft - this.lastScrollLeft\n    );\n\n    this.lastScrollTop = Math.floor(this.element.scrollTop);\n    this.lastScrollLeft = this.element.scrollLeft;\n  };\n\n  PerfectScrollbar.prototype.destroy = function destroy () {\n    if (!this.isAlive) {\n      return;\n    }\n\n    this.event.unbindAll();\n    remove(this.scrollbarX);\n    remove(this.scrollbarY);\n    remove(this.scrollbarXRail);\n    remove(this.scrollbarYRail);\n    this.removePsClasses();\n\n    // unset elements\n    this.element = null;\n    this.scrollbarX = null;\n    this.scrollbarY = null;\n    this.scrollbarXRail = null;\n    this.scrollbarYRail = null;\n\n    this.isAlive = false;\n  };\n\n  PerfectScrollbar.prototype.removePsClasses = function removePsClasses () {\n    this.element.className = this.element.className\n      .split(' ')\n      .filter(function (name) { return !name.match(/^ps([-_].+|)$/); })\n      .join(' ');\n  };\n\n  return PerfectScrollbar;\n\n})));\n//# sourceMappingURL=perfect-scrollbar.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvcGVyZmVjdC1zY3JvbGxiYXIvZGlzdC9wZXJmZWN0LXNjcm9sbGJhci5qcy5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRSxLQUE0RDtBQUM5RCxFQUFFLENBQzhEO0FBQ2hFLENBQUMsc0JBQXNCOztBQUV2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRFQUE0RTtBQUM1RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDRCQUE0QjtBQUN4RCwyQkFBMkIsMkJBQTJCO0FBQ3REO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQsZ0NBQWdDLGdDQUFnQztBQUNoRSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQix5RUFBeUU7QUFDN0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZCQUE2QixXQUFXOztBQUV4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1REFBdUQsZ0NBQWdDO0FBQ3ZGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4Q0FBOEMsdUJBQXVCO0FBQ3JFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRFQUE0RTtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3QkFBd0I7QUFDeEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBLDJEQUEyRCw2QkFBNkI7QUFDeEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMLDJEQUEyRCw2QkFBNkI7QUFDeEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQSx1Q0FBdUM7QUFDdkMseUNBQXlDOztBQUV6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDhCQUE4Qjs7QUFFOUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEI7QUFDOUIsNkJBQTZCOztBQUU3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0Isa0JBQWtCO0FBQ2pEO0FBQ0E7QUFDQSwrQkFBK0IsYUFBYTtBQUM1QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGtCQUFrQjtBQUNqRDtBQUNBO0FBQ0EsK0JBQStCLGFBQWE7QUFDNUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDREQUE0RCx1Q0FBdUM7O0FBRW5HLHdEQUF3RDtBQUN4RCw4Q0FBOEM7QUFDOUMsMkRBQTJELDRCQUE0QjtBQUN2RjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLGtCQUFrQjtBQUNqRCwrQkFBK0Isa0JBQWtCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtCQUErQixpQkFBaUI7QUFDaEQsK0JBQStCLGlCQUFpQjs7QUFFaEQ7O0FBRUE7QUFDQTs7QUFFQSwrQkFBK0IsYUFBYTtBQUM1QywrQkFBK0IsYUFBYTtBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxzQ0FBc0M7QUFDdEU7QUFDQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9WdWV4eS8uL25vZGVfbW9kdWxlcy9wZXJmZWN0LXNjcm9sbGJhci9kaXN0L3BlcmZlY3Qtc2Nyb2xsYmFyLmpzP2ViMmMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBwZXJmZWN0LXNjcm9sbGJhciB2MS41LjNcbiAqIENvcHlyaWdodCAyMDIxIEh5dW5qZSBKdW4sIE1EQm9vdHN0cmFwIGFuZCBDb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVFxuICovXG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuUGVyZmVjdFNjcm9sbGJhciA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICBmdW5jdGlvbiBnZXQoZWxlbWVudCkge1xuICAgIHJldHVybiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0KGVsZW1lbnQsIG9iaikge1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgICAgICB2YWwgPSB2YWwgKyBcInB4XCI7XG4gICAgICB9XG4gICAgICBlbGVtZW50LnN0eWxlW2tleV0gPSB2YWw7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gZGl2KGNsYXNzTmFtZSkge1xuICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIHJldHVybiBkaXY7XG4gIH1cblxuICB2YXIgZWxNYXRjaGVzID1cbiAgICB0eXBlb2YgRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAoRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcyB8fFxuICAgICAgRWxlbWVudC5wcm90b3R5cGUud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG4gICAgICBFbGVtZW50LnByb3RvdHlwZS5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcbiAgICAgIEVsZW1lbnQucHJvdG90eXBlLm1zTWF0Y2hlc1NlbGVjdG9yKTtcblxuICBmdW5jdGlvbiBtYXRjaGVzKGVsZW1lbnQsIHF1ZXJ5KSB7XG4gICAgaWYgKCFlbE1hdGNoZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gZWxlbWVudCBtYXRjaGluZyBtZXRob2Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsTWF0Y2hlcy5jYWxsKGVsZW1lbnQsIHF1ZXJ5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZShlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQucmVtb3ZlKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKSB7XG4gICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBxdWVyeUNoaWxkcmVuKGVsZW1lbnQsIHNlbGVjdG9yKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbChlbGVtZW50LmNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHsgcmV0dXJuIG1hdGNoZXMoY2hpbGQsIHNlbGVjdG9yKTsgfVxuICAgICk7XG4gIH1cblxuICB2YXIgY2xzID0ge1xuICAgIG1haW46ICdwcycsXG4gICAgcnRsOiAncHNfX3J0bCcsXG4gICAgZWxlbWVudDoge1xuICAgICAgdGh1bWI6IGZ1bmN0aW9uICh4KSB7IHJldHVybiAoXCJwc19fdGh1bWItXCIgKyB4KTsgfSxcbiAgICAgIHJhaWw6IGZ1bmN0aW9uICh4KSB7IHJldHVybiAoXCJwc19fcmFpbC1cIiArIHgpOyB9LFxuICAgICAgY29uc3VtaW5nOiAncHNfX2NoaWxkLS1jb25zdW1lJyxcbiAgICB9LFxuICAgIHN0YXRlOiB7XG4gICAgICBmb2N1czogJ3BzLS1mb2N1cycsXG4gICAgICBjbGlja2luZzogJ3BzLS1jbGlja2luZycsXG4gICAgICBhY3RpdmU6IGZ1bmN0aW9uICh4KSB7IHJldHVybiAoXCJwcy0tYWN0aXZlLVwiICsgeCk7IH0sXG4gICAgICBzY3JvbGxpbmc6IGZ1bmN0aW9uICh4KSB7IHJldHVybiAoXCJwcy0tc2Nyb2xsaW5nLVwiICsgeCk7IH0sXG4gICAgfSxcbiAgfTtcblxuICAvKlxuICAgKiBIZWxwZXIgbWV0aG9kc1xuICAgKi9cbiAgdmFyIHNjcm9sbGluZ0NsYXNzVGltZW91dCA9IHsgeDogbnVsbCwgeTogbnVsbCB9O1xuXG4gIGZ1bmN0aW9uIGFkZFNjcm9sbGluZ0NsYXNzKGksIHgpIHtcbiAgICB2YXIgY2xhc3NMaXN0ID0gaS5lbGVtZW50LmNsYXNzTGlzdDtcbiAgICB2YXIgY2xhc3NOYW1lID0gY2xzLnN0YXRlLnNjcm9sbGluZyh4KTtcblxuICAgIGlmIChjbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSkge1xuICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbGluZ0NsYXNzVGltZW91dFt4XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVTY3JvbGxpbmdDbGFzcyhpLCB4KSB7XG4gICAgc2Nyb2xsaW5nQ2xhc3NUaW1lb3V0W3hdID0gc2V0VGltZW91dChcbiAgICAgIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGkuaXNBbGl2ZSAmJiBpLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbHMuc3RhdGUuc2Nyb2xsaW5nKHgpKTsgfSxcbiAgICAgIGkuc2V0dGluZ3Muc2Nyb2xsaW5nVGhyZXNob2xkXG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFNjcm9sbGluZ0NsYXNzSW5zdGFudGx5KGksIHgpIHtcbiAgICBhZGRTY3JvbGxpbmdDbGFzcyhpLCB4KTtcbiAgICByZW1vdmVTY3JvbGxpbmdDbGFzcyhpLCB4KTtcbiAgfVxuXG4gIHZhciBFdmVudEVsZW1lbnQgPSBmdW5jdGlvbiBFdmVudEVsZW1lbnQoZWxlbWVudCkge1xuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5oYW5kbGVycyA9IHt9O1xuICB9O1xuXG4gIHZhciBwcm90b3R5cGVBY2Nlc3NvcnMgPSB7IGlzRW1wdHk6IHsgY29uZmlndXJhYmxlOiB0cnVlIH0gfTtcblxuICBFdmVudEVsZW1lbnQucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiBiaW5kIChldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuaGFuZGxlcnNbZXZlbnROYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuaGFuZGxlcnNbZXZlbnROYW1lXSA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmhhbmRsZXJzW2V2ZW50TmFtZV0ucHVzaChoYW5kbGVyKTtcbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgfTtcblxuICBFdmVudEVsZW1lbnQucHJvdG90eXBlLnVuYmluZCA9IGZ1bmN0aW9uIHVuYmluZCAoZXZlbnROYW1lLCB0YXJnZXQpIHtcbiAgICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgdGhpcy5oYW5kbGVyc1tldmVudE5hbWVdID0gdGhpcy5oYW5kbGVyc1tldmVudE5hbWVdLmZpbHRlcihmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgaWYgKHRhcmdldCAmJiBoYW5kbGVyICE9PSB0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzJDEuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgaGFuZGxlciwgZmFsc2UpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9O1xuXG4gIEV2ZW50RWxlbWVudC5wcm90b3R5cGUudW5iaW5kQWxsID0gZnVuY3Rpb24gdW5iaW5kQWxsICgpIHtcbiAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMuaGFuZGxlcnMpIHtcbiAgICAgIHRoaXMudW5iaW5kKG5hbWUpO1xuICAgIH1cbiAgfTtcblxuICBwcm90b3R5cGVBY2Nlc3NvcnMuaXNFbXB0eS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmhhbmRsZXJzKS5ldmVyeShcbiAgICAgIGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHRoaXMkMS5oYW5kbGVyc1trZXldLmxlbmd0aCA9PT0gMDsgfVxuICAgICk7XG4gIH07XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIEV2ZW50RWxlbWVudC5wcm90b3R5cGUsIHByb3RvdHlwZUFjY2Vzc29ycyApO1xuXG4gIHZhciBFdmVudE1hbmFnZXIgPSBmdW5jdGlvbiBFdmVudE1hbmFnZXIoKSB7XG4gICAgdGhpcy5ldmVudEVsZW1lbnRzID0gW107XG4gIH07XG5cbiAgRXZlbnRNYW5hZ2VyLnByb3RvdHlwZS5ldmVudEVsZW1lbnQgPSBmdW5jdGlvbiBldmVudEVsZW1lbnQgKGVsZW1lbnQpIHtcbiAgICB2YXIgZWUgPSB0aGlzLmV2ZW50RWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChlZSkgeyByZXR1cm4gZWUuZWxlbWVudCA9PT0gZWxlbWVudDsgfSlbMF07XG4gICAgaWYgKCFlZSkge1xuICAgICAgZWUgPSBuZXcgRXZlbnRFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgdGhpcy5ldmVudEVsZW1lbnRzLnB1c2goZWUpO1xuICAgIH1cbiAgICByZXR1cm4gZWU7XG4gIH07XG5cbiAgRXZlbnRNYW5hZ2VyLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gYmluZCAoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgdGhpcy5ldmVudEVsZW1lbnQoZWxlbWVudCkuYmluZChldmVudE5hbWUsIGhhbmRsZXIpO1xuICB9O1xuXG4gIEV2ZW50TWFuYWdlci5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24gdW5iaW5kIChlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICB2YXIgZWUgPSB0aGlzLmV2ZW50RWxlbWVudChlbGVtZW50KTtcbiAgICBlZS51bmJpbmQoZXZlbnROYW1lLCBoYW5kbGVyKTtcblxuICAgIGlmIChlZS5pc0VtcHR5KSB7XG4gICAgICAvLyByZW1vdmVcbiAgICAgIHRoaXMuZXZlbnRFbGVtZW50cy5zcGxpY2UodGhpcy5ldmVudEVsZW1lbnRzLmluZGV4T2YoZWUpLCAxKTtcbiAgICB9XG4gIH07XG5cbiAgRXZlbnRNYW5hZ2VyLnByb3RvdHlwZS51bmJpbmRBbGwgPSBmdW5jdGlvbiB1bmJpbmRBbGwgKCkge1xuICAgIHRoaXMuZXZlbnRFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7IHJldHVybiBlLnVuYmluZEFsbCgpOyB9KTtcbiAgICB0aGlzLmV2ZW50RWxlbWVudHMgPSBbXTtcbiAgfTtcblxuICBFdmVudE1hbmFnZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlIChlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICB2YXIgZWUgPSB0aGlzLmV2ZW50RWxlbWVudChlbGVtZW50KTtcbiAgICB2YXIgb25jZUhhbmRsZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBlZS51bmJpbmQoZXZlbnROYW1lLCBvbmNlSGFuZGxlcik7XG4gICAgICBoYW5kbGVyKGV2dCk7XG4gICAgfTtcbiAgICBlZS5iaW5kKGV2ZW50TmFtZSwgb25jZUhhbmRsZXIpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGNyZWF0ZUV2ZW50KG5hbWUpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdy5DdXN0b21FdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIG5ldyBDdXN0b21FdmVudChuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xuICAgICAgZXZ0LmluaXRDdXN0b21FdmVudChuYW1lLCBmYWxzZSwgZmFsc2UsIHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NTY3JvbGxEaWZmKFxuICAgIGksXG4gICAgYXhpcyxcbiAgICBkaWZmLFxuICAgIHVzZVNjcm9sbGluZ0NsYXNzLFxuICAgIGZvcmNlRmlyZVJlYWNoRXZlbnRcbiAgKSB7XG4gICAgaWYgKCB1c2VTY3JvbGxpbmdDbGFzcyA9PT0gdm9pZCAwICkgdXNlU2Nyb2xsaW5nQ2xhc3MgPSB0cnVlO1xuICAgIGlmICggZm9yY2VGaXJlUmVhY2hFdmVudCA9PT0gdm9pZCAwICkgZm9yY2VGaXJlUmVhY2hFdmVudCA9IGZhbHNlO1xuXG4gICAgdmFyIGZpZWxkcztcbiAgICBpZiAoYXhpcyA9PT0gJ3RvcCcpIHtcbiAgICAgIGZpZWxkcyA9IFtcbiAgICAgICAgJ2NvbnRlbnRIZWlnaHQnLFxuICAgICAgICAnY29udGFpbmVySGVpZ2h0JyxcbiAgICAgICAgJ3Njcm9sbFRvcCcsXG4gICAgICAgICd5JyxcbiAgICAgICAgJ3VwJyxcbiAgICAgICAgJ2Rvd24nIF07XG4gICAgfSBlbHNlIGlmIChheGlzID09PSAnbGVmdCcpIHtcbiAgICAgIGZpZWxkcyA9IFtcbiAgICAgICAgJ2NvbnRlbnRXaWR0aCcsXG4gICAgICAgICdjb250YWluZXJXaWR0aCcsXG4gICAgICAgICdzY3JvbGxMZWZ0JyxcbiAgICAgICAgJ3gnLFxuICAgICAgICAnbGVmdCcsXG4gICAgICAgICdyaWdodCcgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHByb3BlciBheGlzIHNob3VsZCBiZSBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIHByb2Nlc3NTY3JvbGxEaWZmJDEoaSwgZGlmZiwgZmllbGRzLCB1c2VTY3JvbGxpbmdDbGFzcywgZm9yY2VGaXJlUmVhY2hFdmVudCk7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9jZXNzU2Nyb2xsRGlmZiQxKFxuICAgIGksXG4gICAgZGlmZixcbiAgICByZWYsXG4gICAgdXNlU2Nyb2xsaW5nQ2xhc3MsXG4gICAgZm9yY2VGaXJlUmVhY2hFdmVudFxuICApIHtcbiAgICB2YXIgY29udGVudEhlaWdodCA9IHJlZlswXTtcbiAgICB2YXIgY29udGFpbmVySGVpZ2h0ID0gcmVmWzFdO1xuICAgIHZhciBzY3JvbGxUb3AgPSByZWZbMl07XG4gICAgdmFyIHkgPSByZWZbM107XG4gICAgdmFyIHVwID0gcmVmWzRdO1xuICAgIHZhciBkb3duID0gcmVmWzVdO1xuICAgIGlmICggdXNlU2Nyb2xsaW5nQ2xhc3MgPT09IHZvaWQgMCApIHVzZVNjcm9sbGluZ0NsYXNzID0gdHJ1ZTtcbiAgICBpZiAoIGZvcmNlRmlyZVJlYWNoRXZlbnQgPT09IHZvaWQgMCApIGZvcmNlRmlyZVJlYWNoRXZlbnQgPSBmYWxzZTtcblxuICAgIHZhciBlbGVtZW50ID0gaS5lbGVtZW50O1xuXG4gICAgLy8gcmVzZXQgcmVhY2hcbiAgICBpLnJlYWNoW3ldID0gbnVsbDtcblxuICAgIC8vIDEgZm9yIHN1YnBpeGVsIHJvdW5kaW5nXG4gICAgaWYgKGVsZW1lbnRbc2Nyb2xsVG9wXSA8IDEpIHtcbiAgICAgIGkucmVhY2hbeV0gPSAnc3RhcnQnO1xuICAgIH1cblxuICAgIC8vIDEgZm9yIHN1YnBpeGVsIHJvdW5kaW5nXG4gICAgaWYgKGVsZW1lbnRbc2Nyb2xsVG9wXSA+IGlbY29udGVudEhlaWdodF0gLSBpW2NvbnRhaW5lckhlaWdodF0gLSAxKSB7XG4gICAgICBpLnJlYWNoW3ldID0gJ2VuZCc7XG4gICAgfVxuXG4gICAgaWYgKGRpZmYpIHtcbiAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVhdGVFdmVudCgoXCJwcy1zY3JvbGwtXCIgKyB5KSkpO1xuXG4gICAgICBpZiAoZGlmZiA8IDApIHtcbiAgICAgICAgZWxlbWVudC5kaXNwYXRjaEV2ZW50KGNyZWF0ZUV2ZW50KChcInBzLXNjcm9sbC1cIiArIHVwKSkpO1xuICAgICAgfSBlbHNlIGlmIChkaWZmID4gMCkge1xuICAgICAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoKFwicHMtc2Nyb2xsLVwiICsgZG93bikpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHVzZVNjcm9sbGluZ0NsYXNzKSB7XG4gICAgICAgIHNldFNjcm9sbGluZ0NsYXNzSW5zdGFudGx5KGksIHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpLnJlYWNoW3ldICYmIChkaWZmIHx8IGZvcmNlRmlyZVJlYWNoRXZlbnQpKSB7XG4gICAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoY3JlYXRlRXZlbnQoKFwicHMtXCIgKyB5ICsgXCItcmVhY2gtXCIgKyAoaS5yZWFjaFt5XSkpKSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG9JbnQoeCkge1xuICAgIHJldHVybiBwYXJzZUludCh4LCAxMCkgfHwgMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRWRpdGFibGUoZWwpIHtcbiAgICByZXR1cm4gKFxuICAgICAgbWF0Y2hlcyhlbCwgJ2lucHV0LFtjb250ZW50ZWRpdGFibGVdJykgfHxcbiAgICAgIG1hdGNoZXMoZWwsICdzZWxlY3QsW2NvbnRlbnRlZGl0YWJsZV0nKSB8fFxuICAgICAgbWF0Y2hlcyhlbCwgJ3RleHRhcmVhLFtjb250ZW50ZWRpdGFibGVdJykgfHxcbiAgICAgIG1hdGNoZXMoZWwsICdidXR0b24sW2NvbnRlbnRlZGl0YWJsZV0nKVxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBvdXRlcldpZHRoKGVsZW1lbnQpIHtcbiAgICB2YXIgc3R5bGVzID0gZ2V0KGVsZW1lbnQpO1xuICAgIHJldHVybiAoXG4gICAgICB0b0ludChzdHlsZXMud2lkdGgpICtcbiAgICAgIHRvSW50KHN0eWxlcy5wYWRkaW5nTGVmdCkgK1xuICAgICAgdG9JbnQoc3R5bGVzLnBhZGRpbmdSaWdodCkgK1xuICAgICAgdG9JbnQoc3R5bGVzLmJvcmRlckxlZnRXaWR0aCkgK1xuICAgICAgdG9JbnQoc3R5bGVzLmJvcmRlclJpZ2h0V2lkdGgpXG4gICAgKTtcbiAgfVxuXG4gIHZhciBlbnYgPSB7XG4gICAgaXNXZWJLaXQ6XG4gICAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLFxuICAgIHN1cHBvcnRzVG91Y2g6XG4gICAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fFxuICAgICAgICAoJ21heFRvdWNoUG9pbnRzJyBpbiB3aW5kb3cubmF2aWdhdG9yICYmXG4gICAgICAgICAgd2luZG93Lm5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyA+IDApIHx8XG4gICAgICAgICh3aW5kb3cuRG9jdW1lbnRUb3VjaCAmJiBkb2N1bWVudCBpbnN0YW5jZW9mIHdpbmRvdy5Eb2N1bWVudFRvdWNoKSksXG4gICAgc3VwcG9ydHNJZVBvaW50ZXI6XG4gICAgICB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IubXNNYXhUb3VjaFBvaW50cyxcbiAgICBpc0Nocm9tZTpcbiAgICAgIHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAvQ2hyb21lL2kudGVzdChuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCksXG4gIH07XG5cbiAgZnVuY3Rpb24gdXBkYXRlR2VvbWV0cnkoaSkge1xuICAgIHZhciBlbGVtZW50ID0gaS5lbGVtZW50O1xuICAgIHZhciByb3VuZGVkU2Nyb2xsVG9wID0gTWF0aC5mbG9vcihlbGVtZW50LnNjcm9sbFRvcCk7XG4gICAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgaS5jb250YWluZXJXaWR0aCA9IE1hdGgucm91bmQocmVjdC53aWR0aCk7XG4gICAgaS5jb250YWluZXJIZWlnaHQgPSBNYXRoLnJvdW5kKHJlY3QuaGVpZ2h0KTtcblxuICAgIGkuY29udGVudFdpZHRoID0gZWxlbWVudC5zY3JvbGxXaWR0aDtcbiAgICBpLmNvbnRlbnRIZWlnaHQgPSBlbGVtZW50LnNjcm9sbEhlaWdodDtcblxuICAgIGlmICghZWxlbWVudC5jb250YWlucyhpLnNjcm9sbGJhclhSYWlsKSkge1xuICAgICAgLy8gY2xlYW4gdXAgYW5kIGFwcGVuZFxuICAgICAgcXVlcnlDaGlsZHJlbihlbGVtZW50LCBjbHMuZWxlbWVudC5yYWlsKCd4JykpLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7IHJldHVybiByZW1vdmUoZWwpOyB9XG4gICAgICApO1xuICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChpLnNjcm9sbGJhclhSYWlsKTtcbiAgICB9XG4gICAgaWYgKCFlbGVtZW50LmNvbnRhaW5zKGkuc2Nyb2xsYmFyWVJhaWwpKSB7XG4gICAgICAvLyBjbGVhbiB1cCBhbmQgYXBwZW5kXG4gICAgICBxdWVyeUNoaWxkcmVuKGVsZW1lbnQsIGNscy5lbGVtZW50LnJhaWwoJ3knKSkuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHsgcmV0dXJuIHJlbW92ZShlbCk7IH1cbiAgICAgICk7XG4gICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGkuc2Nyb2xsYmFyWVJhaWwpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICFpLnNldHRpbmdzLnN1cHByZXNzU2Nyb2xsWCAmJlxuICAgICAgaS5jb250YWluZXJXaWR0aCArIGkuc2V0dGluZ3Muc2Nyb2xsWE1hcmdpbk9mZnNldCA8IGkuY29udGVudFdpZHRoXG4gICAgKSB7XG4gICAgICBpLnNjcm9sbGJhclhBY3RpdmUgPSB0cnVlO1xuICAgICAgaS5yYWlsWFdpZHRoID0gaS5jb250YWluZXJXaWR0aCAtIGkucmFpbFhNYXJnaW5XaWR0aDtcbiAgICAgIGkucmFpbFhSYXRpbyA9IGkuY29udGFpbmVyV2lkdGggLyBpLnJhaWxYV2lkdGg7XG4gICAgICBpLnNjcm9sbGJhclhXaWR0aCA9IGdldFRodW1iU2l6ZShcbiAgICAgICAgaSxcbiAgICAgICAgdG9JbnQoKGkucmFpbFhXaWR0aCAqIGkuY29udGFpbmVyV2lkdGgpIC8gaS5jb250ZW50V2lkdGgpXG4gICAgICApO1xuICAgICAgaS5zY3JvbGxiYXJYTGVmdCA9IHRvSW50KFxuICAgICAgICAoKGkubmVnYXRpdmVTY3JvbGxBZGp1c3RtZW50ICsgZWxlbWVudC5zY3JvbGxMZWZ0KSAqXG4gICAgICAgICAgKGkucmFpbFhXaWR0aCAtIGkuc2Nyb2xsYmFyWFdpZHRoKSkgL1xuICAgICAgICAgIChpLmNvbnRlbnRXaWR0aCAtIGkuY29udGFpbmVyV2lkdGgpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpLnNjcm9sbGJhclhBY3RpdmUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAhaS5zZXR0aW5ncy5zdXBwcmVzc1Njcm9sbFkgJiZcbiAgICAgIGkuY29udGFpbmVySGVpZ2h0ICsgaS5zZXR0aW5ncy5zY3JvbGxZTWFyZ2luT2Zmc2V0IDwgaS5jb250ZW50SGVpZ2h0XG4gICAgKSB7XG4gICAgICBpLnNjcm9sbGJhcllBY3RpdmUgPSB0cnVlO1xuICAgICAgaS5yYWlsWUhlaWdodCA9IGkuY29udGFpbmVySGVpZ2h0IC0gaS5yYWlsWU1hcmdpbkhlaWdodDtcbiAgICAgIGkucmFpbFlSYXRpbyA9IGkuY29udGFpbmVySGVpZ2h0IC8gaS5yYWlsWUhlaWdodDtcbiAgICAgIGkuc2Nyb2xsYmFyWUhlaWdodCA9IGdldFRodW1iU2l6ZShcbiAgICAgICAgaSxcbiAgICAgICAgdG9JbnQoKGkucmFpbFlIZWlnaHQgKiBpLmNvbnRhaW5lckhlaWdodCkgLyBpLmNvbnRlbnRIZWlnaHQpXG4gICAgICApO1xuICAgICAgaS5zY3JvbGxiYXJZVG9wID0gdG9JbnQoXG4gICAgICAgIChyb3VuZGVkU2Nyb2xsVG9wICogKGkucmFpbFlIZWlnaHQgLSBpLnNjcm9sbGJhcllIZWlnaHQpKSAvXG4gICAgICAgICAgKGkuY29udGVudEhlaWdodCAtIGkuY29udGFpbmVySGVpZ2h0KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaS5zY3JvbGxiYXJZQWN0aXZlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGkuc2Nyb2xsYmFyWExlZnQgPj0gaS5yYWlsWFdpZHRoIC0gaS5zY3JvbGxiYXJYV2lkdGgpIHtcbiAgICAgIGkuc2Nyb2xsYmFyWExlZnQgPSBpLnJhaWxYV2lkdGggLSBpLnNjcm9sbGJhclhXaWR0aDtcbiAgICB9XG4gICAgaWYgKGkuc2Nyb2xsYmFyWVRvcCA+PSBpLnJhaWxZSGVpZ2h0IC0gaS5zY3JvbGxiYXJZSGVpZ2h0KSB7XG4gICAgICBpLnNjcm9sbGJhcllUb3AgPSBpLnJhaWxZSGVpZ2h0IC0gaS5zY3JvbGxiYXJZSGVpZ2h0O1xuICAgIH1cblxuICAgIHVwZGF0ZUNzcyhlbGVtZW50LCBpKTtcblxuICAgIGlmIChpLnNjcm9sbGJhclhBY3RpdmUpIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjbHMuc3RhdGUuYWN0aXZlKCd4JykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoY2xzLnN0YXRlLmFjdGl2ZSgneCcpKTtcbiAgICAgIGkuc2Nyb2xsYmFyWFdpZHRoID0gMDtcbiAgICAgIGkuc2Nyb2xsYmFyWExlZnQgPSAwO1xuICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0ID0gaS5pc1J0bCA9PT0gdHJ1ZSA/IGkuY29udGVudFdpZHRoIDogMDtcbiAgICB9XG4gICAgaWYgKGkuc2Nyb2xsYmFyWUFjdGl2ZSkge1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKGNscy5zdGF0ZS5hY3RpdmUoJ3knKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbHMuc3RhdGUuYWN0aXZlKCd5JykpO1xuICAgICAgaS5zY3JvbGxiYXJZSGVpZ2h0ID0gMDtcbiAgICAgIGkuc2Nyb2xsYmFyWVRvcCA9IDA7XG4gICAgICBlbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VGh1bWJTaXplKGksIHRodW1iU2l6ZSkge1xuICAgIGlmIChpLnNldHRpbmdzLm1pblNjcm9sbGJhckxlbmd0aCkge1xuICAgICAgdGh1bWJTaXplID0gTWF0aC5tYXgodGh1bWJTaXplLCBpLnNldHRpbmdzLm1pblNjcm9sbGJhckxlbmd0aCk7XG4gICAgfVxuICAgIGlmIChpLnNldHRpbmdzLm1heFNjcm9sbGJhckxlbmd0aCkge1xuICAgICAgdGh1bWJTaXplID0gTWF0aC5taW4odGh1bWJTaXplLCBpLnNldHRpbmdzLm1heFNjcm9sbGJhckxlbmd0aCk7XG4gICAgfVxuICAgIHJldHVybiB0aHVtYlNpemU7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVDc3MoZWxlbWVudCwgaSkge1xuICAgIHZhciB4UmFpbE9mZnNldCA9IHsgd2lkdGg6IGkucmFpbFhXaWR0aCB9O1xuICAgIHZhciByb3VuZGVkU2Nyb2xsVG9wID0gTWF0aC5mbG9vcihlbGVtZW50LnNjcm9sbFRvcCk7XG5cbiAgICBpZiAoaS5pc1J0bCkge1xuICAgICAgeFJhaWxPZmZzZXQubGVmdCA9XG4gICAgICAgIGkubmVnYXRpdmVTY3JvbGxBZGp1c3RtZW50ICtcbiAgICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0ICtcbiAgICAgICAgaS5jb250YWluZXJXaWR0aCAtXG4gICAgICAgIGkuY29udGVudFdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB4UmFpbE9mZnNldC5sZWZ0ID0gZWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIH1cbiAgICBpZiAoaS5pc1Njcm9sbGJhclhVc2luZ0JvdHRvbSkge1xuICAgICAgeFJhaWxPZmZzZXQuYm90dG9tID0gaS5zY3JvbGxiYXJYQm90dG9tIC0gcm91bmRlZFNjcm9sbFRvcDtcbiAgICB9IGVsc2Uge1xuICAgICAgeFJhaWxPZmZzZXQudG9wID0gaS5zY3JvbGxiYXJYVG9wICsgcm91bmRlZFNjcm9sbFRvcDtcbiAgICB9XG4gICAgc2V0KGkuc2Nyb2xsYmFyWFJhaWwsIHhSYWlsT2Zmc2V0KTtcblxuICAgIHZhciB5UmFpbE9mZnNldCA9IHsgdG9wOiByb3VuZGVkU2Nyb2xsVG9wLCBoZWlnaHQ6IGkucmFpbFlIZWlnaHQgfTtcbiAgICBpZiAoaS5pc1Njcm9sbGJhcllVc2luZ1JpZ2h0KSB7XG4gICAgICBpZiAoaS5pc1J0bCkge1xuICAgICAgICB5UmFpbE9mZnNldC5yaWdodCA9XG4gICAgICAgICAgaS5jb250ZW50V2lkdGggLVxuICAgICAgICAgIChpLm5lZ2F0aXZlU2Nyb2xsQWRqdXN0bWVudCArIGVsZW1lbnQuc2Nyb2xsTGVmdCkgLVxuICAgICAgICAgIGkuc2Nyb2xsYmFyWVJpZ2h0IC1cbiAgICAgICAgICBpLnNjcm9sbGJhcllPdXRlcldpZHRoIC1cbiAgICAgICAgICA5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeVJhaWxPZmZzZXQucmlnaHQgPSBpLnNjcm9sbGJhcllSaWdodCAtIGVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGkuaXNSdGwpIHtcbiAgICAgICAgeVJhaWxPZmZzZXQubGVmdCA9XG4gICAgICAgICAgaS5uZWdhdGl2ZVNjcm9sbEFkanVzdG1lbnQgK1xuICAgICAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCArXG4gICAgICAgICAgaS5jb250YWluZXJXaWR0aCAqIDIgLVxuICAgICAgICAgIGkuY29udGVudFdpZHRoIC1cbiAgICAgICAgICBpLnNjcm9sbGJhcllMZWZ0IC1cbiAgICAgICAgICBpLnNjcm9sbGJhcllPdXRlcldpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeVJhaWxPZmZzZXQubGVmdCA9IGkuc2Nyb2xsYmFyWUxlZnQgKyBlbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHNldChpLnNjcm9sbGJhcllSYWlsLCB5UmFpbE9mZnNldCk7XG5cbiAgICBzZXQoaS5zY3JvbGxiYXJYLCB7XG4gICAgICBsZWZ0OiBpLnNjcm9sbGJhclhMZWZ0LFxuICAgICAgd2lkdGg6IGkuc2Nyb2xsYmFyWFdpZHRoIC0gaS5yYWlsQm9yZGVyWFdpZHRoLFxuICAgIH0pO1xuICAgIHNldChpLnNjcm9sbGJhclksIHtcbiAgICAgIHRvcDogaS5zY3JvbGxiYXJZVG9wLFxuICAgICAgaGVpZ2h0OiBpLnNjcm9sbGJhcllIZWlnaHQgLSBpLnJhaWxCb3JkZXJZV2lkdGgsXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjbGlja1JhaWwoaSkge1xuICAgIHZhciBlbGVtZW50ID0gaS5lbGVtZW50O1xuXG4gICAgaS5ldmVudC5iaW5kKGkuc2Nyb2xsYmFyWSwgJ21vdXNlZG93bicsIGZ1bmN0aW9uIChlKSB7IHJldHVybiBlLnN0b3BQcm9wYWdhdGlvbigpOyB9KTtcbiAgICBpLmV2ZW50LmJpbmQoaS5zY3JvbGxiYXJZUmFpbCwgJ21vdXNlZG93bicsIGZ1bmN0aW9uIChlKSB7XG4gICAgICB2YXIgcG9zaXRpb25Ub3AgPVxuICAgICAgICBlLnBhZ2VZIC1cbiAgICAgICAgd2luZG93LnBhZ2VZT2Zmc2V0IC1cbiAgICAgICAgaS5zY3JvbGxiYXJZUmFpbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3A7XG4gICAgICB2YXIgZGlyZWN0aW9uID0gcG9zaXRpb25Ub3AgPiBpLnNjcm9sbGJhcllUb3AgPyAxIDogLTE7XG5cbiAgICAgIGkuZWxlbWVudC5zY3JvbGxUb3AgKz0gZGlyZWN0aW9uICogaS5jb250YWluZXJIZWlnaHQ7XG4gICAgICB1cGRhdGVHZW9tZXRyeShpKTtcblxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgIGkuZXZlbnQuYmluZChpLnNjcm9sbGJhclgsICdtb3VzZWRvd24nLCBmdW5jdGlvbiAoZSkgeyByZXR1cm4gZS5zdG9wUHJvcGFnYXRpb24oKTsgfSk7XG4gICAgaS5ldmVudC5iaW5kKGkuc2Nyb2xsYmFyWFJhaWwsICdtb3VzZWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICAgICAgdmFyIHBvc2l0aW9uTGVmdCA9XG4gICAgICAgIGUucGFnZVggLVxuICAgICAgICB3aW5kb3cucGFnZVhPZmZzZXQgLVxuICAgICAgICBpLnNjcm9sbGJhclhSYWlsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gICAgICB2YXIgZGlyZWN0aW9uID0gcG9zaXRpb25MZWZ0ID4gaS5zY3JvbGxiYXJYTGVmdCA/IDEgOiAtMTtcblxuICAgICAgaS5lbGVtZW50LnNjcm9sbExlZnQgKz0gZGlyZWN0aW9uICogaS5jb250YWluZXJXaWR0aDtcbiAgICAgIHVwZGF0ZUdlb21ldHJ5KGkpO1xuXG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhZ1RodW1iKGkpIHtcbiAgICBiaW5kTW91c2VTY3JvbGxIYW5kbGVyKGksIFtcbiAgICAgICdjb250YWluZXJXaWR0aCcsXG4gICAgICAnY29udGVudFdpZHRoJyxcbiAgICAgICdwYWdlWCcsXG4gICAgICAncmFpbFhXaWR0aCcsXG4gICAgICAnc2Nyb2xsYmFyWCcsXG4gICAgICAnc2Nyb2xsYmFyWFdpZHRoJyxcbiAgICAgICdzY3JvbGxMZWZ0JyxcbiAgICAgICd4JyxcbiAgICAgICdzY3JvbGxiYXJYUmFpbCcgXSk7XG4gICAgYmluZE1vdXNlU2Nyb2xsSGFuZGxlcihpLCBbXG4gICAgICAnY29udGFpbmVySGVpZ2h0JyxcbiAgICAgICdjb250ZW50SGVpZ2h0JyxcbiAgICAgICdwYWdlWScsXG4gICAgICAncmFpbFlIZWlnaHQnLFxuICAgICAgJ3Njcm9sbGJhclknLFxuICAgICAgJ3Njcm9sbGJhcllIZWlnaHQnLFxuICAgICAgJ3Njcm9sbFRvcCcsXG4gICAgICAneScsXG4gICAgICAnc2Nyb2xsYmFyWVJhaWwnIF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYmluZE1vdXNlU2Nyb2xsSGFuZGxlcihcbiAgICBpLFxuICAgIHJlZlxuICApIHtcbiAgICB2YXIgY29udGFpbmVySGVpZ2h0ID0gcmVmWzBdO1xuICAgIHZhciBjb250ZW50SGVpZ2h0ID0gcmVmWzFdO1xuICAgIHZhciBwYWdlWSA9IHJlZlsyXTtcbiAgICB2YXIgcmFpbFlIZWlnaHQgPSByZWZbM107XG4gICAgdmFyIHNjcm9sbGJhclkgPSByZWZbNF07XG4gICAgdmFyIHNjcm9sbGJhcllIZWlnaHQgPSByZWZbNV07XG4gICAgdmFyIHNjcm9sbFRvcCA9IHJlZls2XTtcbiAgICB2YXIgeSA9IHJlZls3XTtcbiAgICB2YXIgc2Nyb2xsYmFyWVJhaWwgPSByZWZbOF07XG5cbiAgICB2YXIgZWxlbWVudCA9IGkuZWxlbWVudDtcblxuICAgIHZhciBzdGFydGluZ1Njcm9sbFRvcCA9IG51bGw7XG4gICAgdmFyIHN0YXJ0aW5nTW91c2VQYWdlWSA9IG51bGw7XG4gICAgdmFyIHNjcm9sbEJ5ID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIG1vdXNlTW92ZUhhbmRsZXIoZSkge1xuICAgICAgaWYgKGUudG91Y2hlcyAmJiBlLnRvdWNoZXNbMF0pIHtcbiAgICAgICAgZVtwYWdlWV0gPSBlLnRvdWNoZXNbMF0ucGFnZVk7XG4gICAgICB9XG4gICAgICBlbGVtZW50W3Njcm9sbFRvcF0gPVxuICAgICAgICBzdGFydGluZ1Njcm9sbFRvcCArIHNjcm9sbEJ5ICogKGVbcGFnZVldIC0gc3RhcnRpbmdNb3VzZVBhZ2VZKTtcbiAgICAgIGFkZFNjcm9sbGluZ0NsYXNzKGksIHkpO1xuICAgICAgdXBkYXRlR2VvbWV0cnkoaSk7XG5cbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBpZiAoZS50eXBlLnN0YXJ0c1dpdGgoJ3RvdWNoJykgJiYgZS5jaGFuZ2VkVG91Y2hlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3VzZVVwSGFuZGxlcigpIHtcbiAgICAgIHJlbW92ZVNjcm9sbGluZ0NsYXNzKGksIHkpO1xuICAgICAgaVtzY3JvbGxiYXJZUmFpbF0uY2xhc3NMaXN0LnJlbW92ZShjbHMuc3RhdGUuY2xpY2tpbmcpO1xuICAgICAgaS5ldmVudC51bmJpbmQoaS5vd25lckRvY3VtZW50LCAnbW91c2Vtb3ZlJywgbW91c2VNb3ZlSGFuZGxlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYmluZE1vdmVzKGUsIHRvdWNoTW9kZSkge1xuICAgICAgc3RhcnRpbmdTY3JvbGxUb3AgPSBlbGVtZW50W3Njcm9sbFRvcF07XG4gICAgICBpZiAodG91Y2hNb2RlICYmIGUudG91Y2hlcykge1xuICAgICAgICBlW3BhZ2VZXSA9IGUudG91Y2hlc1swXS5wYWdlWTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0aW5nTW91c2VQYWdlWSA9IGVbcGFnZVldO1xuICAgICAgc2Nyb2xsQnkgPVxuICAgICAgICAoaVtjb250ZW50SGVpZ2h0XSAtIGlbY29udGFpbmVySGVpZ2h0XSkgL1xuICAgICAgICAoaVtyYWlsWUhlaWdodF0gLSBpW3Njcm9sbGJhcllIZWlnaHRdKTtcbiAgICAgIGlmICghdG91Y2hNb2RlKSB7XG4gICAgICAgIGkuZXZlbnQuYmluZChpLm93bmVyRG9jdW1lbnQsICdtb3VzZW1vdmUnLCBtb3VzZU1vdmVIYW5kbGVyKTtcbiAgICAgICAgaS5ldmVudC5vbmNlKGkub3duZXJEb2N1bWVudCwgJ21vdXNldXAnLCBtb3VzZVVwSGFuZGxlcik7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkuZXZlbnQuYmluZChpLm93bmVyRG9jdW1lbnQsICd0b3VjaG1vdmUnLCBtb3VzZU1vdmVIYW5kbGVyKTtcbiAgICAgIH1cblxuICAgICAgaVtzY3JvbGxiYXJZUmFpbF0uY2xhc3NMaXN0LmFkZChjbHMuc3RhdGUuY2xpY2tpbmcpO1xuXG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIGkuZXZlbnQuYmluZChpW3Njcm9sbGJhclldLCAnbW91c2Vkb3duJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGJpbmRNb3ZlcyhlKTtcbiAgICB9KTtcbiAgICBpLmV2ZW50LmJpbmQoaVtzY3JvbGxiYXJZXSwgJ3RvdWNoc3RhcnQnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgYmluZE1vdmVzKGUsIHRydWUpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24ga2V5Ym9hcmQoaSkge1xuICAgIHZhciBlbGVtZW50ID0gaS5lbGVtZW50O1xuXG4gICAgdmFyIGVsZW1lbnRIb3ZlcmVkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gbWF0Y2hlcyhlbGVtZW50LCAnOmhvdmVyJyk7IH07XG4gICAgdmFyIHNjcm9sbGJhckZvY3VzZWQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBtYXRjaGVzKGkuc2Nyb2xsYmFyWCwgJzpmb2N1cycpIHx8IG1hdGNoZXMoaS5zY3JvbGxiYXJZLCAnOmZvY3VzJyk7IH07XG5cbiAgICBmdW5jdGlvbiBzaG91bGRQcmV2ZW50RGVmYXVsdChkZWx0YVgsIGRlbHRhWSkge1xuICAgICAgdmFyIHNjcm9sbFRvcCA9IE1hdGguZmxvb3IoZWxlbWVudC5zY3JvbGxUb3ApO1xuICAgICAgaWYgKGRlbHRhWCA9PT0gMCkge1xuICAgICAgICBpZiAoIWkuc2Nyb2xsYmFyWUFjdGl2ZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgKHNjcm9sbFRvcCA9PT0gMCAmJiBkZWx0YVkgPiAwKSB8fFxuICAgICAgICAgIChzY3JvbGxUb3AgPj0gaS5jb250ZW50SGVpZ2h0IC0gaS5jb250YWluZXJIZWlnaHQgJiYgZGVsdGFZIDwgMClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuICFpLnNldHRpbmdzLndoZWVsUHJvcGFnYXRpb247XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHNjcm9sbExlZnQgPSBlbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICBpZiAoZGVsdGFZID09PSAwKSB7XG4gICAgICAgIGlmICghaS5zY3JvbGxiYXJYQWN0aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAoc2Nyb2xsTGVmdCA9PT0gMCAmJiBkZWx0YVggPCAwKSB8fFxuICAgICAgICAgIChzY3JvbGxMZWZ0ID49IGkuY29udGVudFdpZHRoIC0gaS5jb250YWluZXJXaWR0aCAmJiBkZWx0YVggPiAwKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gIWkuc2V0dGluZ3Mud2hlZWxQcm9wYWdhdGlvbjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaS5ldmVudC5iaW5kKGkub3duZXJEb2N1bWVudCwgJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKFxuICAgICAgICAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQgJiYgZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgfHxcbiAgICAgICAgZS5kZWZhdWx0UHJldmVudGVkXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnRIb3ZlcmVkKCkgJiYgIXNjcm9sbGJhckZvY3VzZWQoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBhY3RpdmVFbGVtZW50ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudFxuICAgICAgICA/IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRcbiAgICAgICAgOiBpLm93bmVyRG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgIGlmIChhY3RpdmVFbGVtZW50KSB7XG4gICAgICAgIGlmIChhY3RpdmVFbGVtZW50LnRhZ05hbWUgPT09ICdJRlJBTUUnKSB7XG4gICAgICAgICAgYWN0aXZlRWxlbWVudCA9IGFjdGl2ZUVsZW1lbnQuY29udGVudERvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZ28gZGVlcGVyIGlmIGVsZW1lbnQgaXMgYSB3ZWJjb21wb25lbnRcbiAgICAgICAgICB3aGlsZSAoYWN0aXZlRWxlbWVudC5zaGFkb3dSb290KSB7XG4gICAgICAgICAgICBhY3RpdmVFbGVtZW50ID0gYWN0aXZlRWxlbWVudC5zaGFkb3dSb290LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0VkaXRhYmxlKGFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBkZWx0YVggPSAwO1xuICAgICAgdmFyIGRlbHRhWSA9IDA7XG5cbiAgICAgIHN3aXRjaCAoZS53aGljaCkge1xuICAgICAgICBjYXNlIDM3OiAvLyBsZWZ0XG4gICAgICAgICAgaWYgKGUubWV0YUtleSkge1xuICAgICAgICAgICAgZGVsdGFYID0gLWkuY29udGVudFdpZHRoO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZS5hbHRLZXkpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IC1pLmNvbnRhaW5lcldpZHRoO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWx0YVggPSAtMzA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM4OiAvLyB1cFxuICAgICAgICAgIGlmIChlLm1ldGFLZXkpIHtcbiAgICAgICAgICAgIGRlbHRhWSA9IGkuY29udGVudEhlaWdodDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGUuYWx0S2V5KSB7XG4gICAgICAgICAgICBkZWx0YVkgPSBpLmNvbnRhaW5lckhlaWdodDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsdGFZID0gMzA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM5OiAvLyByaWdodFxuICAgICAgICAgIGlmIChlLm1ldGFLZXkpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGkuY29udGVudFdpZHRoO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZS5hbHRLZXkpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGkuY29udGFpbmVyV2lkdGg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IDMwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA0MDogLy8gZG93blxuICAgICAgICAgIGlmIChlLm1ldGFLZXkpIHtcbiAgICAgICAgICAgIGRlbHRhWSA9IC1pLmNvbnRlbnRIZWlnaHQ7XG4gICAgICAgICAgfSBlbHNlIGlmIChlLmFsdEtleSkge1xuICAgICAgICAgICAgZGVsdGFZID0gLWkuY29udGFpbmVySGVpZ2h0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWx0YVkgPSAtMzA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDMyOiAvLyBzcGFjZSBiYXJcbiAgICAgICAgICBpZiAoZS5zaGlmdEtleSkge1xuICAgICAgICAgICAgZGVsdGFZID0gaS5jb250YWluZXJIZWlnaHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlbHRhWSA9IC1pLmNvbnRhaW5lckhlaWdodDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzM6IC8vIHBhZ2UgdXBcbiAgICAgICAgICBkZWx0YVkgPSBpLmNvbnRhaW5lckhlaWdodDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzNDogLy8gcGFnZSBkb3duXG4gICAgICAgICAgZGVsdGFZID0gLWkuY29udGFpbmVySGVpZ2h0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM2OiAvLyBob21lXG4gICAgICAgICAgZGVsdGFZID0gaS5jb250ZW50SGVpZ2h0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM1OiAvLyBlbmRcbiAgICAgICAgICBkZWx0YVkgPSAtaS5jb250ZW50SGVpZ2h0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGkuc2V0dGluZ3Muc3VwcHJlc3NTY3JvbGxYICYmIGRlbHRhWCAhPT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoaS5zZXR0aW5ncy5zdXBwcmVzc1Njcm9sbFkgJiYgZGVsdGFZICE9PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZWxlbWVudC5zY3JvbGxUb3AgLT0gZGVsdGFZO1xuICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0ICs9IGRlbHRhWDtcbiAgICAgIHVwZGF0ZUdlb21ldHJ5KGkpO1xuXG4gICAgICBpZiAoc2hvdWxkUHJldmVudERlZmF1bHQoZGVsdGFYLCBkZWx0YVkpKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdoZWVsKGkpIHtcbiAgICB2YXIgZWxlbWVudCA9IGkuZWxlbWVudDtcblxuICAgIGZ1bmN0aW9uIHNob3VsZFByZXZlbnREZWZhdWx0KGRlbHRhWCwgZGVsdGFZKSB7XG4gICAgICB2YXIgcm91bmRlZFNjcm9sbFRvcCA9IE1hdGguZmxvb3IoZWxlbWVudC5zY3JvbGxUb3ApO1xuICAgICAgdmFyIGlzVG9wID0gZWxlbWVudC5zY3JvbGxUb3AgPT09IDA7XG4gICAgICB2YXIgaXNCb3R0b20gPVxuICAgICAgICByb3VuZGVkU2Nyb2xsVG9wICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgPT09IGVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xuICAgICAgdmFyIGlzTGVmdCA9IGVsZW1lbnQuc2Nyb2xsTGVmdCA9PT0gMDtcbiAgICAgIHZhciBpc1JpZ2h0ID1cbiAgICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0ICsgZWxlbWVudC5vZmZzZXRXaWR0aCA9PT0gZWxlbWVudC5zY3JvbGxXaWR0aDtcblxuICAgICAgdmFyIGhpdHNCb3VuZDtcblxuICAgICAgLy8gcGljayBheGlzIHdpdGggcHJpbWFyeSBkaXJlY3Rpb25cbiAgICAgIGlmIChNYXRoLmFicyhkZWx0YVkpID4gTWF0aC5hYnMoZGVsdGFYKSkge1xuICAgICAgICBoaXRzQm91bmQgPSBpc1RvcCB8fCBpc0JvdHRvbTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpdHNCb3VuZCA9IGlzTGVmdCB8fCBpc1JpZ2h0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaGl0c0JvdW5kID8gIWkuc2V0dGluZ3Mud2hlZWxQcm9wYWdhdGlvbiA6IHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0RGVsdGFGcm9tRXZlbnQoZSkge1xuICAgICAgdmFyIGRlbHRhWCA9IGUuZGVsdGFYO1xuICAgICAgdmFyIGRlbHRhWSA9IC0xICogZS5kZWx0YVk7XG5cbiAgICAgIGlmICh0eXBlb2YgZGVsdGFYID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgZGVsdGFZID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBPUyBYIFNhZmFyaVxuICAgICAgICBkZWx0YVggPSAoLTEgKiBlLndoZWVsRGVsdGFYKSAvIDY7XG4gICAgICAgIGRlbHRhWSA9IGUud2hlZWxEZWx0YVkgLyA2O1xuICAgICAgfVxuXG4gICAgICBpZiAoZS5kZWx0YU1vZGUgJiYgZS5kZWx0YU1vZGUgPT09IDEpIHtcbiAgICAgICAgLy8gRmlyZWZveCBpbiBkZWx0YU1vZGUgMTogTGluZSBzY3JvbGxpbmdcbiAgICAgICAgZGVsdGFYICo9IDEwO1xuICAgICAgICBkZWx0YVkgKj0gMTA7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWx0YVggIT09IGRlbHRhWCAmJiBkZWx0YVkgIT09IGRlbHRhWSAvKiBOYU4gY2hlY2tzICovKSB7XG4gICAgICAgIC8vIElFIGluIHNvbWUgbW91c2UgZHJpdmVyc1xuICAgICAgICBkZWx0YVggPSAwO1xuICAgICAgICBkZWx0YVkgPSBlLndoZWVsRGVsdGE7XG4gICAgICB9XG5cbiAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgIC8vIHJldmVyc2UgYXhpcyB3aXRoIHNoaWZ0IGtleVxuICAgICAgICByZXR1cm4gWy1kZWx0YVksIC1kZWx0YVhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtkZWx0YVgsIGRlbHRhWV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2hvdWxkQmVDb25zdW1lZEJ5Q2hpbGQodGFyZ2V0LCBkZWx0YVgsIGRlbHRhWSkge1xuICAgICAgLy8gRklYTUU6IHRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciA8c2VsZWN0PiBpc3N1ZSBpbiBGRiBhbmQgSUUgIzU3MVxuICAgICAgaWYgKCFlbnYuaXNXZWJLaXQgJiYgZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzZWxlY3Q6Zm9jdXMnKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFlbGVtZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3Vyc29yID0gdGFyZ2V0O1xuXG4gICAgICB3aGlsZSAoY3Vyc29yICYmIGN1cnNvciAhPT0gZWxlbWVudCkge1xuICAgICAgICBpZiAoY3Vyc29yLmNsYXNzTGlzdC5jb250YWlucyhjbHMuZWxlbWVudC5jb25zdW1pbmcpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3R5bGUgPSBnZXQoY3Vyc29yKTtcblxuICAgICAgICAvLyBpZiBkZWx0YVkgJiYgdmVydGljYWwgc2Nyb2xsYWJsZVxuICAgICAgICBpZiAoZGVsdGFZICYmIHN0eWxlLm92ZXJmbG93WS5tYXRjaCgvKHNjcm9sbHxhdXRvKS8pKSB7XG4gICAgICAgICAgdmFyIG1heFNjcm9sbFRvcCA9IGN1cnNvci5zY3JvbGxIZWlnaHQgLSBjdXJzb3IuY2xpZW50SGVpZ2h0O1xuICAgICAgICAgIGlmIChtYXhTY3JvbGxUb3AgPiAwKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIChjdXJzb3Iuc2Nyb2xsVG9wID4gMCAmJiBkZWx0YVkgPCAwKSB8fFxuICAgICAgICAgICAgICAoY3Vyc29yLnNjcm9sbFRvcCA8IG1heFNjcm9sbFRvcCAmJiBkZWx0YVkgPiAwKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBpZiBkZWx0YVggJiYgaG9yaXpvbnRhbCBzY3JvbGxhYmxlXG4gICAgICAgIGlmIChkZWx0YVggJiYgc3R5bGUub3ZlcmZsb3dYLm1hdGNoKC8oc2Nyb2xsfGF1dG8pLykpIHtcbiAgICAgICAgICB2YXIgbWF4U2Nyb2xsTGVmdCA9IGN1cnNvci5zY3JvbGxXaWR0aCAtIGN1cnNvci5jbGllbnRXaWR0aDtcbiAgICAgICAgICBpZiAobWF4U2Nyb2xsTGVmdCA+IDApIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgKGN1cnNvci5zY3JvbGxMZWZ0ID4gMCAmJiBkZWx0YVggPCAwKSB8fFxuICAgICAgICAgICAgICAoY3Vyc29yLnNjcm9sbExlZnQgPCBtYXhTY3JvbGxMZWZ0ICYmIGRlbHRhWCA+IDApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yID0gY3Vyc29yLnBhcmVudE5vZGU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3VzZXdoZWVsSGFuZGxlcihlKSB7XG4gICAgICB2YXIgcmVmID0gZ2V0RGVsdGFGcm9tRXZlbnQoZSk7XG4gICAgICB2YXIgZGVsdGFYID0gcmVmWzBdO1xuICAgICAgdmFyIGRlbHRhWSA9IHJlZlsxXTtcblxuICAgICAgaWYgKHNob3VsZEJlQ29uc3VtZWRCeUNoaWxkKGUudGFyZ2V0LCBkZWx0YVgsIGRlbHRhWSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2hvdWxkUHJldmVudCA9IGZhbHNlO1xuICAgICAgaWYgKCFpLnNldHRpbmdzLnVzZUJvdGhXaGVlbEF4ZXMpIHtcbiAgICAgICAgLy8gZGVsdGFYIHdpbGwgb25seSBiZSB1c2VkIGZvciBob3Jpem9udGFsIHNjcm9sbGluZyBhbmQgZGVsdGFZIHdpbGxcbiAgICAgICAgLy8gb25seSBiZSB1c2VkIGZvciB2ZXJ0aWNhbCBzY3JvbGxpbmcgLSB0aGlzIGlzIHRoZSBkZWZhdWx0XG4gICAgICAgIGVsZW1lbnQuc2Nyb2xsVG9wIC09IGRlbHRhWSAqIGkuc2V0dGluZ3Mud2hlZWxTcGVlZDtcbiAgICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0ICs9IGRlbHRhWCAqIGkuc2V0dGluZ3Mud2hlZWxTcGVlZDtcbiAgICAgIH0gZWxzZSBpZiAoaS5zY3JvbGxiYXJZQWN0aXZlICYmICFpLnNjcm9sbGJhclhBY3RpdmUpIHtcbiAgICAgICAgLy8gb25seSB2ZXJ0aWNhbCBzY3JvbGxiYXIgaXMgYWN0aXZlIGFuZCB1c2VCb3RoV2hlZWxBeGVzIG9wdGlvbiBpc1xuICAgICAgICAvLyBhY3RpdmUsIHNvIGxldCdzIHNjcm9sbCB2ZXJ0aWNhbCBiYXIgdXNpbmcgYm90aCBtb3VzZSB3aGVlbCBheGVzXG4gICAgICAgIGlmIChkZWx0YVkpIHtcbiAgICAgICAgICBlbGVtZW50LnNjcm9sbFRvcCAtPSBkZWx0YVkgKiBpLnNldHRpbmdzLndoZWVsU3BlZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZWxlbWVudC5zY3JvbGxUb3AgKz0gZGVsdGFYICogaS5zZXR0aW5ncy53aGVlbFNwZWVkO1xuICAgICAgICB9XG4gICAgICAgIHNob3VsZFByZXZlbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChpLnNjcm9sbGJhclhBY3RpdmUgJiYgIWkuc2Nyb2xsYmFyWUFjdGl2ZSkge1xuICAgICAgICAvLyB1c2VCb3RoV2hlZWxBeGVzIGFuZCBvbmx5IGhvcml6b250YWwgYmFyIGlzIGFjdGl2ZSwgc28gdXNlIGJvdGhcbiAgICAgICAgLy8gd2hlZWwgYXhlcyBmb3IgaG9yaXpvbnRhbCBiYXJcbiAgICAgICAgaWYgKGRlbHRhWCkge1xuICAgICAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCArPSBkZWx0YVggKiBpLnNldHRpbmdzLndoZWVsU3BlZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0IC09IGRlbHRhWSAqIGkuc2V0dGluZ3Mud2hlZWxTcGVlZDtcbiAgICAgICAgfVxuICAgICAgICBzaG91bGRQcmV2ZW50ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlR2VvbWV0cnkoaSk7XG5cbiAgICAgIHNob3VsZFByZXZlbnQgPSBzaG91bGRQcmV2ZW50IHx8IHNob3VsZFByZXZlbnREZWZhdWx0KGRlbHRhWCwgZGVsdGFZKTtcbiAgICAgIGlmIChzaG91bGRQcmV2ZW50ICYmICFlLmN0cmxLZXkpIHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygd2luZG93Lm9ud2hlZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpLmV2ZW50LmJpbmQoZWxlbWVudCwgJ3doZWVsJywgbW91c2V3aGVlbEhhbmRsZXIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdy5vbm1vdXNld2hlZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpLmV2ZW50LmJpbmQoZWxlbWVudCwgJ21vdXNld2hlZWwnLCBtb3VzZXdoZWVsSGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2goaSkge1xuICAgIGlmICghZW52LnN1cHBvcnRzVG91Y2ggJiYgIWVudi5zdXBwb3J0c0llUG9pbnRlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50ID0gaS5lbGVtZW50O1xuXG4gICAgZnVuY3Rpb24gc2hvdWxkUHJldmVudChkZWx0YVgsIGRlbHRhWSkge1xuICAgICAgdmFyIHNjcm9sbFRvcCA9IE1hdGguZmxvb3IoZWxlbWVudC5zY3JvbGxUb3ApO1xuICAgICAgdmFyIHNjcm9sbExlZnQgPSBlbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICB2YXIgbWFnbml0dWRlWCA9IE1hdGguYWJzKGRlbHRhWCk7XG4gICAgICB2YXIgbWFnbml0dWRlWSA9IE1hdGguYWJzKGRlbHRhWSk7XG5cbiAgICAgIGlmIChtYWduaXR1ZGVZID4gbWFnbml0dWRlWCkge1xuICAgICAgICAvLyB1c2VyIGlzIHBlcmhhcHMgdHJ5aW5nIHRvIHN3aXBlIHVwL2Rvd24gdGhlIHBhZ2VcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgKGRlbHRhWSA8IDAgJiYgc2Nyb2xsVG9wID09PSBpLmNvbnRlbnRIZWlnaHQgLSBpLmNvbnRhaW5lckhlaWdodCkgfHxcbiAgICAgICAgICAoZGVsdGFZID4gMCAmJiBzY3JvbGxUb3AgPT09IDApXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIHNldCBwcmV2ZW50IGZvciBtb2JpbGUgQ2hyb21lIHJlZnJlc2hcbiAgICAgICAgICByZXR1cm4gd2luZG93LnNjcm9sbFkgPT09IDAgJiYgZGVsdGFZID4gMCAmJiBlbnYuaXNDaHJvbWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobWFnbml0dWRlWCA+IG1hZ25pdHVkZVkpIHtcbiAgICAgICAgLy8gdXNlciBpcyBwZXJoYXBzIHRyeWluZyB0byBzd2lwZSBsZWZ0L3JpZ2h0IGFjcm9zcyB0aGUgcGFnZVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAoZGVsdGFYIDwgMCAmJiBzY3JvbGxMZWZ0ID09PSBpLmNvbnRlbnRXaWR0aCAtIGkuY29udGFpbmVyV2lkdGgpIHx8XG4gICAgICAgICAgKGRlbHRhWCA+IDAgJiYgc2Nyb2xsTGVmdCA9PT0gMClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXBwbHlUb3VjaE1vdmUoZGlmZmVyZW5jZVgsIGRpZmZlcmVuY2VZKSB7XG4gICAgICBlbGVtZW50LnNjcm9sbFRvcCAtPSBkaWZmZXJlbmNlWTtcbiAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCAtPSBkaWZmZXJlbmNlWDtcblxuICAgICAgdXBkYXRlR2VvbWV0cnkoaSk7XG4gICAgfVxuXG4gICAgdmFyIHN0YXJ0T2Zmc2V0ID0ge307XG4gICAgdmFyIHN0YXJ0VGltZSA9IDA7XG4gICAgdmFyIHNwZWVkID0ge307XG4gICAgdmFyIGVhc2luZ0xvb3AgPSBudWxsO1xuXG4gICAgZnVuY3Rpb24gZ2V0VG91Y2goZSkge1xuICAgICAgaWYgKGUudGFyZ2V0VG91Y2hlcykge1xuICAgICAgICByZXR1cm4gZS50YXJnZXRUb3VjaGVzWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTWF5YmUgSUUgcG9pbnRlclxuICAgICAgICByZXR1cm4gZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzaG91bGRIYW5kbGUoZSkge1xuICAgICAgaWYgKGUucG9pbnRlclR5cGUgJiYgZS5wb2ludGVyVHlwZSA9PT0gJ3BlbicgJiYgZS5idXR0b25zID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChlLnRhcmdldFRvdWNoZXMgJiYgZS50YXJnZXRUb3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgZS5wb2ludGVyVHlwZSAmJlxuICAgICAgICBlLnBvaW50ZXJUeXBlICE9PSAnbW91c2UnICYmXG4gICAgICAgIGUucG9pbnRlclR5cGUgIT09IGUuTVNQT0lOVEVSX1RZUEVfTU9VU0VcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b3VjaFN0YXJ0KGUpIHtcbiAgICAgIGlmICghc2hvdWxkSGFuZGxlKGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRvdWNoID0gZ2V0VG91Y2goZSk7XG5cbiAgICAgIHN0YXJ0T2Zmc2V0LnBhZ2VYID0gdG91Y2gucGFnZVg7XG4gICAgICBzdGFydE9mZnNldC5wYWdlWSA9IHRvdWNoLnBhZ2VZO1xuXG4gICAgICBzdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgaWYgKGVhc2luZ0xvb3AgIT09IG51bGwpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChlYXNpbmdMb29wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzaG91bGRCZUNvbnN1bWVkQnlDaGlsZCh0YXJnZXQsIGRlbHRhWCwgZGVsdGFZKSB7XG4gICAgICBpZiAoIWVsZW1lbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHZhciBjdXJzb3IgPSB0YXJnZXQ7XG5cbiAgICAgIHdoaWxlIChjdXJzb3IgJiYgY3Vyc29yICE9PSBlbGVtZW50KSB7XG4gICAgICAgIGlmIChjdXJzb3IuY2xhc3NMaXN0LmNvbnRhaW5zKGNscy5lbGVtZW50LmNvbnN1bWluZykpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdHlsZSA9IGdldChjdXJzb3IpO1xuXG4gICAgICAgIC8vIGlmIGRlbHRhWSAmJiB2ZXJ0aWNhbCBzY3JvbGxhYmxlXG4gICAgICAgIGlmIChkZWx0YVkgJiYgc3R5bGUub3ZlcmZsb3dZLm1hdGNoKC8oc2Nyb2xsfGF1dG8pLykpIHtcbiAgICAgICAgICB2YXIgbWF4U2Nyb2xsVG9wID0gY3Vyc29yLnNjcm9sbEhlaWdodCAtIGN1cnNvci5jbGllbnRIZWlnaHQ7XG4gICAgICAgICAgaWYgKG1heFNjcm9sbFRvcCA+IDApIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgKGN1cnNvci5zY3JvbGxUb3AgPiAwICYmIGRlbHRhWSA8IDApIHx8XG4gICAgICAgICAgICAgIChjdXJzb3Iuc2Nyb2xsVG9wIDwgbWF4U2Nyb2xsVG9wICYmIGRlbHRhWSA+IDApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGRlbHRhWCAmJiBob3Jpem9udGFsIHNjcm9sbGFibGVcbiAgICAgICAgaWYgKGRlbHRhWCAmJiBzdHlsZS5vdmVyZmxvd1gubWF0Y2goLyhzY3JvbGx8YXV0bykvKSkge1xuICAgICAgICAgIHZhciBtYXhTY3JvbGxMZWZ0ID0gY3Vyc29yLnNjcm9sbFdpZHRoIC0gY3Vyc29yLmNsaWVudFdpZHRoO1xuICAgICAgICAgIGlmIChtYXhTY3JvbGxMZWZ0ID4gMCkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAoY3Vyc29yLnNjcm9sbExlZnQgPiAwICYmIGRlbHRhWCA8IDApIHx8XG4gICAgICAgICAgICAgIChjdXJzb3Iuc2Nyb2xsTGVmdCA8IG1heFNjcm9sbExlZnQgJiYgZGVsdGFYID4gMClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3IgPSBjdXJzb3IucGFyZW50Tm9kZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvdWNoTW92ZShlKSB7XG4gICAgICBpZiAoc2hvdWxkSGFuZGxlKGUpKSB7XG4gICAgICAgIHZhciB0b3VjaCA9IGdldFRvdWNoKGUpO1xuXG4gICAgICAgIHZhciBjdXJyZW50T2Zmc2V0ID0geyBwYWdlWDogdG91Y2gucGFnZVgsIHBhZ2VZOiB0b3VjaC5wYWdlWSB9O1xuXG4gICAgICAgIHZhciBkaWZmZXJlbmNlWCA9IGN1cnJlbnRPZmZzZXQucGFnZVggLSBzdGFydE9mZnNldC5wYWdlWDtcbiAgICAgICAgdmFyIGRpZmZlcmVuY2VZID0gY3VycmVudE9mZnNldC5wYWdlWSAtIHN0YXJ0T2Zmc2V0LnBhZ2VZO1xuXG4gICAgICAgIGlmIChzaG91bGRCZUNvbnN1bWVkQnlDaGlsZChlLnRhcmdldCwgZGlmZmVyZW5jZVgsIGRpZmZlcmVuY2VZKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFwcGx5VG91Y2hNb3ZlKGRpZmZlcmVuY2VYLCBkaWZmZXJlbmNlWSk7XG4gICAgICAgIHN0YXJ0T2Zmc2V0ID0gY3VycmVudE9mZnNldDtcblxuICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgICB2YXIgdGltZUdhcCA9IGN1cnJlbnRUaW1lIC0gc3RhcnRUaW1lO1xuICAgICAgICBpZiAodGltZUdhcCA+IDApIHtcbiAgICAgICAgICBzcGVlZC54ID0gZGlmZmVyZW5jZVggLyB0aW1lR2FwO1xuICAgICAgICAgIHNwZWVkLnkgPSBkaWZmZXJlbmNlWSAvIHRpbWVHYXA7XG4gICAgICAgICAgc3RhcnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2hvdWxkUHJldmVudChkaWZmZXJlbmNlWCwgZGlmZmVyZW5jZVkpKSB7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHRvdWNoRW5kKCkge1xuICAgICAgaWYgKGkuc2V0dGluZ3Muc3dpcGVFYXNpbmcpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChlYXNpbmdMb29wKTtcbiAgICAgICAgZWFzaW5nTG9vcCA9IHNldEludGVydmFsKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChpLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoZWFzaW5nTG9vcCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFzcGVlZC54ICYmICFzcGVlZC55KSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGVhc2luZ0xvb3ApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChNYXRoLmFicyhzcGVlZC54KSA8IDAuMDEgJiYgTWF0aC5hYnMoc3BlZWQueSkgPCAwLjAxKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGVhc2luZ0xvb3ApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghaS5lbGVtZW50KSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGVhc2luZ0xvb3ApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFwcGx5VG91Y2hNb3ZlKHNwZWVkLnggKiAzMCwgc3BlZWQueSAqIDMwKTtcblxuICAgICAgICAgIHNwZWVkLnggKj0gMC44O1xuICAgICAgICAgIHNwZWVkLnkgKj0gMC44O1xuICAgICAgICB9LCAxMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudi5zdXBwb3J0c1RvdWNoKSB7XG4gICAgICBpLmV2ZW50LmJpbmQoZWxlbWVudCwgJ3RvdWNoc3RhcnQnLCB0b3VjaFN0YXJ0KTtcbiAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAndG91Y2htb3ZlJywgdG91Y2hNb3ZlKTtcbiAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAndG91Y2hlbmQnLCB0b3VjaEVuZCk7XG4gICAgfSBlbHNlIGlmIChlbnYuc3VwcG9ydHNJZVBvaW50ZXIpIHtcbiAgICAgIGlmICh3aW5kb3cuUG9pbnRlckV2ZW50KSB7XG4gICAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAncG9pbnRlcmRvd24nLCB0b3VjaFN0YXJ0KTtcbiAgICAgICAgaS5ldmVudC5iaW5kKGVsZW1lbnQsICdwb2ludGVybW92ZScsIHRvdWNoTW92ZSk7XG4gICAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAncG9pbnRlcnVwJywgdG91Y2hFbmQpO1xuICAgICAgfSBlbHNlIGlmICh3aW5kb3cuTVNQb2ludGVyRXZlbnQpIHtcbiAgICAgICAgaS5ldmVudC5iaW5kKGVsZW1lbnQsICdNU1BvaW50ZXJEb3duJywgdG91Y2hTdGFydCk7XG4gICAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAnTVNQb2ludGVyTW92ZScsIHRvdWNoTW92ZSk7XG4gICAgICAgIGkuZXZlbnQuYmluZChlbGVtZW50LCAnTVNQb2ludGVyVXAnLCB0b3VjaEVuZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGRlZmF1bHRTZXR0aW5ncyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh7XG4gICAgaGFuZGxlcnM6IFsnY2xpY2stcmFpbCcsICdkcmFnLXRodW1iJywgJ2tleWJvYXJkJywgJ3doZWVsJywgJ3RvdWNoJ10sXG4gICAgbWF4U2Nyb2xsYmFyTGVuZ3RoOiBudWxsLFxuICAgIG1pblNjcm9sbGJhckxlbmd0aDogbnVsbCxcbiAgICBzY3JvbGxpbmdUaHJlc2hvbGQ6IDEwMDAsXG4gICAgc2Nyb2xsWE1hcmdpbk9mZnNldDogMCxcbiAgICBzY3JvbGxZTWFyZ2luT2Zmc2V0OiAwLFxuICAgIHN1cHByZXNzU2Nyb2xsWDogZmFsc2UsXG4gICAgc3VwcHJlc3NTY3JvbGxZOiBmYWxzZSxcbiAgICBzd2lwZUVhc2luZzogdHJ1ZSxcbiAgICB1c2VCb3RoV2hlZWxBeGVzOiBmYWxzZSxcbiAgICB3aGVlbFByb3BhZ2F0aW9uOiB0cnVlLFxuICAgIHdoZWVsU3BlZWQ6IDEsXG4gIH0pOyB9O1xuXG4gIHZhciBoYW5kbGVycyA9IHtcbiAgICAnY2xpY2stcmFpbCc6IGNsaWNrUmFpbCxcbiAgICAnZHJhZy10aHVtYic6IGRyYWdUaHVtYixcbiAgICBrZXlib2FyZDoga2V5Ym9hcmQsXG4gICAgd2hlZWw6IHdoZWVsLFxuICAgIHRvdWNoOiB0b3VjaCxcbiAgfTtcblxuICB2YXIgUGVyZmVjdFNjcm9sbGJhciA9IGZ1bmN0aW9uIFBlcmZlY3RTY3JvbGxiYXIoZWxlbWVudCwgdXNlclNldHRpbmdzKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG4gICAgaWYgKCB1c2VyU2V0dGluZ3MgPT09IHZvaWQgMCApIHVzZXJTZXR0aW5ncyA9IHt9O1xuXG4gICAgaWYgKHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgaWYgKCFlbGVtZW50IHx8ICFlbGVtZW50Lm5vZGVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGVsZW1lbnQgaXMgc3BlY2lmaWVkIHRvIGluaXRpYWxpemUgUGVyZmVjdFNjcm9sbGJhcicpO1xuICAgIH1cblxuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xzLm1haW4pO1xuXG4gICAgdGhpcy5zZXR0aW5ncyA9IGRlZmF1bHRTZXR0aW5ncygpO1xuICAgIGZvciAodmFyIGtleSBpbiB1c2VyU2V0dGluZ3MpIHtcbiAgICAgIHRoaXMuc2V0dGluZ3Nba2V5XSA9IHVzZXJTZXR0aW5nc1trZXldO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSBudWxsO1xuICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gbnVsbDtcbiAgICB0aGlzLmNvbnRlbnRXaWR0aCA9IG51bGw7XG4gICAgdGhpcy5jb250ZW50SGVpZ2h0ID0gbnVsbDtcblxuICAgIHZhciBmb2N1cyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjbHMuc3RhdGUuZm9jdXMpOyB9O1xuICAgIHZhciBibHVyID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKGNscy5zdGF0ZS5mb2N1cyk7IH07XG5cbiAgICB0aGlzLmlzUnRsID0gZ2V0KGVsZW1lbnQpLmRpcmVjdGlvbiA9PT0gJ3J0bCc7XG4gICAgaWYgKHRoaXMuaXNSdGwgPT09IHRydWUpIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjbHMucnRsKTtcbiAgICB9XG4gICAgdGhpcy5pc05lZ2F0aXZlU2Nyb2xsID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvcmlnaW5hbFNjcm9sbExlZnQgPSBlbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCA9IC0xO1xuICAgICAgcmVzdWx0ID0gZWxlbWVudC5zY3JvbGxMZWZ0IDwgMDtcbiAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCA9IG9yaWdpbmFsU2Nyb2xsTGVmdDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSkoKTtcbiAgICB0aGlzLm5lZ2F0aXZlU2Nyb2xsQWRqdXN0bWVudCA9IHRoaXMuaXNOZWdhdGl2ZVNjcm9sbFxuICAgICAgPyBlbGVtZW50LnNjcm9sbFdpZHRoIC0gZWxlbWVudC5jbGllbnRXaWR0aFxuICAgICAgOiAwO1xuICAgIHRoaXMuZXZlbnQgPSBuZXcgRXZlbnRNYW5hZ2VyKCk7XG4gICAgdGhpcy5vd25lckRvY3VtZW50ID0gZWxlbWVudC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xuXG4gICAgdGhpcy5zY3JvbGxiYXJYUmFpbCA9IGRpdihjbHMuZWxlbWVudC5yYWlsKCd4JykpO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxiYXJYUmFpbCk7XG4gICAgdGhpcy5zY3JvbGxiYXJYID0gZGl2KGNscy5lbGVtZW50LnRodW1iKCd4JykpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWFJhaWwuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxiYXJYKTtcbiAgICB0aGlzLnNjcm9sbGJhclguc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsIDApO1xuICAgIHRoaXMuZXZlbnQuYmluZCh0aGlzLnNjcm9sbGJhclgsICdmb2N1cycsIGZvY3VzKTtcbiAgICB0aGlzLmV2ZW50LmJpbmQodGhpcy5zY3JvbGxiYXJYLCAnYmx1cicsIGJsdXIpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWEFjdGl2ZSA9IG51bGw7XG4gICAgdGhpcy5zY3JvbGxiYXJYV2lkdGggPSBudWxsO1xuICAgIHRoaXMuc2Nyb2xsYmFyWExlZnQgPSBudWxsO1xuICAgIHZhciByYWlsWFN0eWxlID0gZ2V0KHRoaXMuc2Nyb2xsYmFyWFJhaWwpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWEJvdHRvbSA9IHBhcnNlSW50KHJhaWxYU3R5bGUuYm90dG9tLCAxMCk7XG4gICAgaWYgKGlzTmFOKHRoaXMuc2Nyb2xsYmFyWEJvdHRvbSkpIHtcbiAgICAgIHRoaXMuaXNTY3JvbGxiYXJYVXNpbmdCb3R0b20gPSBmYWxzZTtcbiAgICAgIHRoaXMuc2Nyb2xsYmFyWFRvcCA9IHRvSW50KHJhaWxYU3R5bGUudG9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pc1Njcm9sbGJhclhVc2luZ0JvdHRvbSA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMucmFpbEJvcmRlclhXaWR0aCA9XG4gICAgICB0b0ludChyYWlsWFN0eWxlLmJvcmRlckxlZnRXaWR0aCkgKyB0b0ludChyYWlsWFN0eWxlLmJvcmRlclJpZ2h0V2lkdGgpO1xuICAgIC8vIFNldCByYWlsIHRvIGRpc3BsYXk6YmxvY2sgdG8gY2FsY3VsYXRlIG1hcmdpbnNcbiAgICBzZXQodGhpcy5zY3JvbGxiYXJYUmFpbCwgeyBkaXNwbGF5OiAnYmxvY2snIH0pO1xuICAgIHRoaXMucmFpbFhNYXJnaW5XaWR0aCA9XG4gICAgICB0b0ludChyYWlsWFN0eWxlLm1hcmdpbkxlZnQpICsgdG9JbnQocmFpbFhTdHlsZS5tYXJnaW5SaWdodCk7XG4gICAgc2V0KHRoaXMuc2Nyb2xsYmFyWFJhaWwsIHsgZGlzcGxheTogJycgfSk7XG4gICAgdGhpcy5yYWlsWFdpZHRoID0gbnVsbDtcbiAgICB0aGlzLnJhaWxYUmF0aW8gPSBudWxsO1xuXG4gICAgdGhpcy5zY3JvbGxiYXJZUmFpbCA9IGRpdihjbHMuZWxlbWVudC5yYWlsKCd5JykpO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxiYXJZUmFpbCk7XG4gICAgdGhpcy5zY3JvbGxiYXJZID0gZGl2KGNscy5lbGVtZW50LnRodW1iKCd5JykpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWVJhaWwuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxiYXJZKTtcbiAgICB0aGlzLnNjcm9sbGJhclkuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsIDApO1xuICAgIHRoaXMuZXZlbnQuYmluZCh0aGlzLnNjcm9sbGJhclksICdmb2N1cycsIGZvY3VzKTtcbiAgICB0aGlzLmV2ZW50LmJpbmQodGhpcy5zY3JvbGxiYXJZLCAnYmx1cicsIGJsdXIpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWUFjdGl2ZSA9IG51bGw7XG4gICAgdGhpcy5zY3JvbGxiYXJZSGVpZ2h0ID0gbnVsbDtcbiAgICB0aGlzLnNjcm9sbGJhcllUb3AgPSBudWxsO1xuICAgIHZhciByYWlsWVN0eWxlID0gZ2V0KHRoaXMuc2Nyb2xsYmFyWVJhaWwpO1xuICAgIHRoaXMuc2Nyb2xsYmFyWVJpZ2h0ID0gcGFyc2VJbnQocmFpbFlTdHlsZS5yaWdodCwgMTApO1xuICAgIGlmIChpc05hTih0aGlzLnNjcm9sbGJhcllSaWdodCkpIHtcbiAgICAgIHRoaXMuaXNTY3JvbGxiYXJZVXNpbmdSaWdodCA9IGZhbHNlO1xuICAgICAgdGhpcy5zY3JvbGxiYXJZTGVmdCA9IHRvSW50KHJhaWxZU3R5bGUubGVmdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNTY3JvbGxiYXJZVXNpbmdSaWdodCA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMuc2Nyb2xsYmFyWU91dGVyV2lkdGggPSB0aGlzLmlzUnRsID8gb3V0ZXJXaWR0aCh0aGlzLnNjcm9sbGJhclkpIDogbnVsbDtcbiAgICB0aGlzLnJhaWxCb3JkZXJZV2lkdGggPVxuICAgICAgdG9JbnQocmFpbFlTdHlsZS5ib3JkZXJUb3BXaWR0aCkgKyB0b0ludChyYWlsWVN0eWxlLmJvcmRlckJvdHRvbVdpZHRoKTtcbiAgICBzZXQodGhpcy5zY3JvbGxiYXJZUmFpbCwgeyBkaXNwbGF5OiAnYmxvY2snIH0pO1xuICAgIHRoaXMucmFpbFlNYXJnaW5IZWlnaHQgPVxuICAgICAgdG9JbnQocmFpbFlTdHlsZS5tYXJnaW5Ub3ApICsgdG9JbnQocmFpbFlTdHlsZS5tYXJnaW5Cb3R0b20pO1xuICAgIHNldCh0aGlzLnNjcm9sbGJhcllSYWlsLCB7IGRpc3BsYXk6ICcnIH0pO1xuICAgIHRoaXMucmFpbFlIZWlnaHQgPSBudWxsO1xuICAgIHRoaXMucmFpbFlSYXRpbyA9IG51bGw7XG5cbiAgICB0aGlzLnJlYWNoID0ge1xuICAgICAgeDpcbiAgICAgICAgZWxlbWVudC5zY3JvbGxMZWZ0IDw9IDBcbiAgICAgICAgICA/ICdzdGFydCdcbiAgICAgICAgICA6IGVsZW1lbnQuc2Nyb2xsTGVmdCA+PSB0aGlzLmNvbnRlbnRXaWR0aCAtIHRoaXMuY29udGFpbmVyV2lkdGhcbiAgICAgICAgICA/ICdlbmQnXG4gICAgICAgICAgOiBudWxsLFxuICAgICAgeTpcbiAgICAgICAgZWxlbWVudC5zY3JvbGxUb3AgPD0gMFxuICAgICAgICAgID8gJ3N0YXJ0J1xuICAgICAgICAgIDogZWxlbWVudC5zY3JvbGxUb3AgPj0gdGhpcy5jb250ZW50SGVpZ2h0IC0gdGhpcy5jb250YWluZXJIZWlnaHRcbiAgICAgICAgICA/ICdlbmQnXG4gICAgICAgICAgOiBudWxsLFxuICAgIH07XG5cbiAgICB0aGlzLmlzQWxpdmUgPSB0cnVlO1xuXG4gICAgdGhpcy5zZXR0aW5ncy5oYW5kbGVycy5mb3JFYWNoKGZ1bmN0aW9uIChoYW5kbGVyTmFtZSkgeyByZXR1cm4gaGFuZGxlcnNbaGFuZGxlck5hbWVdKHRoaXMkMSk7IH0pO1xuXG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gTWF0aC5mbG9vcihlbGVtZW50LnNjcm9sbFRvcCk7IC8vIGZvciBvblNjcm9sbCBvbmx5XG4gICAgdGhpcy5sYXN0U2Nyb2xsTGVmdCA9IGVsZW1lbnQuc2Nyb2xsTGVmdDsgLy8gZm9yIG9uU2Nyb2xsIG9ubHlcbiAgICB0aGlzLmV2ZW50LmJpbmQodGhpcy5lbGVtZW50LCAnc2Nyb2xsJywgZnVuY3Rpb24gKGUpIHsgcmV0dXJuIHRoaXMkMS5vblNjcm9sbChlKTsgfSk7XG4gICAgdXBkYXRlR2VvbWV0cnkodGhpcyk7XG4gIH07XG5cbiAgUGVyZmVjdFNjcm9sbGJhci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlICgpIHtcbiAgICBpZiAoIXRoaXMuaXNBbGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlY2FsY3VhdGUgbmVnYXRpdmUgc2Nyb2xsTGVmdCBhZGp1c3RtZW50XG4gICAgdGhpcy5uZWdhdGl2ZVNjcm9sbEFkanVzdG1lbnQgPSB0aGlzLmlzTmVnYXRpdmVTY3JvbGxcbiAgICAgID8gdGhpcy5lbGVtZW50LnNjcm9sbFdpZHRoIC0gdGhpcy5lbGVtZW50LmNsaWVudFdpZHRoXG4gICAgICA6IDA7XG5cbiAgICAvLyBSZWNhbGN1bGF0ZSByYWlsIG1hcmdpbnNcbiAgICBzZXQodGhpcy5zY3JvbGxiYXJYUmFpbCwgeyBkaXNwbGF5OiAnYmxvY2snIH0pO1xuICAgIHNldCh0aGlzLnNjcm9sbGJhcllSYWlsLCB7IGRpc3BsYXk6ICdibG9jaycgfSk7XG4gICAgdGhpcy5yYWlsWE1hcmdpbldpZHRoID1cbiAgICAgIHRvSW50KGdldCh0aGlzLnNjcm9sbGJhclhSYWlsKS5tYXJnaW5MZWZ0KSArXG4gICAgICB0b0ludChnZXQodGhpcy5zY3JvbGxiYXJYUmFpbCkubWFyZ2luUmlnaHQpO1xuICAgIHRoaXMucmFpbFlNYXJnaW5IZWlnaHQgPVxuICAgICAgdG9JbnQoZ2V0KHRoaXMuc2Nyb2xsYmFyWVJhaWwpLm1hcmdpblRvcCkgK1xuICAgICAgdG9JbnQoZ2V0KHRoaXMuc2Nyb2xsYmFyWVJhaWwpLm1hcmdpbkJvdHRvbSk7XG5cbiAgICAvLyBIaWRlIHNjcm9sbGJhcnMgbm90IHRvIGFmZmVjdCBzY3JvbGxXaWR0aCBhbmQgc2Nyb2xsSGVpZ2h0XG4gICAgc2V0KHRoaXMuc2Nyb2xsYmFyWFJhaWwsIHsgZGlzcGxheTogJ25vbmUnIH0pO1xuICAgIHNldCh0aGlzLnNjcm9sbGJhcllSYWlsLCB7IGRpc3BsYXk6ICdub25lJyB9KTtcblxuICAgIHVwZGF0ZUdlb21ldHJ5KHRoaXMpO1xuXG4gICAgcHJvY2Vzc1Njcm9sbERpZmYodGhpcywgJ3RvcCcsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICBwcm9jZXNzU2Nyb2xsRGlmZih0aGlzLCAnbGVmdCcsIDAsIGZhbHNlLCB0cnVlKTtcblxuICAgIHNldCh0aGlzLnNjcm9sbGJhclhSYWlsLCB7IGRpc3BsYXk6ICcnIH0pO1xuICAgIHNldCh0aGlzLnNjcm9sbGJhcllSYWlsLCB7IGRpc3BsYXk6ICcnIH0pO1xuICB9O1xuXG4gIFBlcmZlY3RTY3JvbGxiYXIucHJvdG90eXBlLm9uU2Nyb2xsID0gZnVuY3Rpb24gb25TY3JvbGwgKGUpIHtcbiAgICBpZiAoIXRoaXMuaXNBbGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVwZGF0ZUdlb21ldHJ5KHRoaXMpO1xuICAgIHByb2Nlc3NTY3JvbGxEaWZmKHRoaXMsICd0b3AnLCB0aGlzLmVsZW1lbnQuc2Nyb2xsVG9wIC0gdGhpcy5sYXN0U2Nyb2xsVG9wKTtcbiAgICBwcm9jZXNzU2Nyb2xsRGlmZihcbiAgICAgIHRoaXMsXG4gICAgICAnbGVmdCcsXG4gICAgICB0aGlzLmVsZW1lbnQuc2Nyb2xsTGVmdCAtIHRoaXMubGFzdFNjcm9sbExlZnRcbiAgICApO1xuXG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gTWF0aC5mbG9vcih0aGlzLmVsZW1lbnQuc2Nyb2xsVG9wKTtcbiAgICB0aGlzLmxhc3RTY3JvbGxMZWZ0ID0gdGhpcy5lbGVtZW50LnNjcm9sbExlZnQ7XG4gIH07XG5cbiAgUGVyZmVjdFNjcm9sbGJhci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGlmICghdGhpcy5pc0FsaXZlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5ldmVudC51bmJpbmRBbGwoKTtcbiAgICByZW1vdmUodGhpcy5zY3JvbGxiYXJYKTtcbiAgICByZW1vdmUodGhpcy5zY3JvbGxiYXJZKTtcbiAgICByZW1vdmUodGhpcy5zY3JvbGxiYXJYUmFpbCk7XG4gICAgcmVtb3ZlKHRoaXMuc2Nyb2xsYmFyWVJhaWwpO1xuICAgIHRoaXMucmVtb3ZlUHNDbGFzc2VzKCk7XG5cbiAgICAvLyB1bnNldCBlbGVtZW50c1xuICAgIHRoaXMuZWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5zY3JvbGxiYXJYID0gbnVsbDtcbiAgICB0aGlzLnNjcm9sbGJhclkgPSBudWxsO1xuICAgIHRoaXMuc2Nyb2xsYmFyWFJhaWwgPSBudWxsO1xuICAgIHRoaXMuc2Nyb2xsYmFyWVJhaWwgPSBudWxsO1xuXG4gICAgdGhpcy5pc0FsaXZlID0gZmFsc2U7XG4gIH07XG5cbiAgUGVyZmVjdFNjcm9sbGJhci5wcm90b3R5cGUucmVtb3ZlUHNDbGFzc2VzID0gZnVuY3Rpb24gcmVtb3ZlUHNDbGFzc2VzICgpIHtcbiAgICB0aGlzLmVsZW1lbnQuY2xhc3NOYW1lID0gdGhpcy5lbGVtZW50LmNsYXNzTmFtZVxuICAgICAgLnNwbGl0KCcgJylcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuICFuYW1lLm1hdGNoKC9ecHMoWy1fXS4rfCkkLyk7IH0pXG4gICAgICAuam9pbignICcpO1xuICB9O1xuXG4gIHJldHVybiBQZXJmZWN0U2Nyb2xsYmFyO1xuXG59KSkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGVyZmVjdC1zY3JvbGxiYXIuanMubWFwXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/perfect-scrollbar/dist/perfect-scrollbar.js\n");

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	!function() {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = function(module) {
/******/ 			var getter = module && module.__esModule ?
/******/ 				function() { return module['default']; } :
/******/ 				function() { return module; };
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	}();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	!function() {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = function(exports, definition) {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	}();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	!function() {
/******/ 		__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ 	}();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	!function() {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = function(exports) {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	}();
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module can't be inlined because the eval-source-map devtool is used.
/******/ 	var __webpack_exports__ = __webpack_require__("./libs/perfect-scrollbar/perfect-scrollbar.js");
/******/ 	
/******/ 	return __webpack_exports__;
/******/ })()
;
});