HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/wingssprayer.komma.pro/wwwroot/js/app.js
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["/js/app"],{

/***/ "./node_modules/@komma/kal/kal.js":
/*!****************************************!*\
  !*** ./node_modules/@komma/kal/kal.js ***!
  \****************************************/
/*! exports provided: KAL */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KAL", function() { return KAL; });
const KAL = {

    /**
     * The data attribute prefix we use for our animation library
     * @type string
     */
    dataPrefix: 'kal',

    /**
     * Define the class we used to set the states of the animations
     */
    startStateClass: 'is-kal-start',
    endStateClass: 'is-kal-end',

    /**
     * Empty basket for putting the NodeElements in
     */
    elements: [],

    /**
     * Default options
     */
    options: {
        root: null,
        rootMargin: '-48px 0px -48px 0px', // offset from the edge of the intersection root
        threshold: 0, // The visual percentage of component when animation is triggered
    },

    /**
     * Element default options
     */
    elementOptions: {
        once: true,
    },

    /** @type {IntersectionObserver} */
    intersectionObserver: null,

    init: function () {

        if(window.IntersectionObserver === undefined) {
            console.warn('IntersectionObserver is not supported');
            return;
        }

        KAL.elements = document.querySelectorAll('*[data-'+ KAL.dataPrefix +']');
        if(KAL.elements.length === 0 ) return;

        KAL.createIntersectionObserver();
    },

    /**
     * Create the Intersection Observer
     * and append the KAL elements into it.
     */
    createIntersectionObserver: function () {

        KAL.intersectionObserver = new IntersectionObserver(KAL.onIntersection, {
            root: KAL.options.root,
            rootMargin: KAL.options.rootMargin,
            threshold: KAL.options.threshold,
        });

        KAL.elements.forEach(function (element) {
            KAL.intersectionObserver.observe(element);
            element.classList.add(KAL.startStateClass);
        });
    },

    /**
     * IntersectionObserver callback
     * @param  {Array<IntersectionObserverEntry>} entries
     * @param  {IntersectionObserver} observer
     */
    onIntersection: function (entries, observer) {
        entries.forEach(function (entry) {

            // When element's is in viewport and within threshold,
            // Trigger animation!
            if (entry.intersectionRatio > KAL.options.threshold) {

                KAL.triggerAnimation(entry);

                if (KAL.getElementOption(entry.target, 'once')) {
                    observer.unobserve(entry.target);
                }
            } else if (!KAL.getElementOption(entry.target, 'once')) {

                // Reverse the animation if options is not once
                KAL.reverseAnimation(entry);
            }
        });
    },

    /**
     * Clear the intersection observer.
     */
    clearIntersectionObserver: function () {
      KAL.intersectionObserver.disconnect();
      KAL.intersectionObserver = null;
    },

    /**
     * Get an animation option of the element.
     *
     * @param element
     * @param attribute
     */
    getElementOption: function (element, attribute)
    {
        const option = element.getAttribute('data-'+ KAL.dataPrefix + '-' + attribute);

        if(option !== null){

            // Map the attributes values into the right type
            switch (attribute) {

                // Boolean attributes
                case 'once':
                    return (option == 'true');

                default:
                    return option;
            }
        }
        return KAL.elementOptions[attribute];
    },

    /**
     * Trigger animation
     * @param {IntersectionObserverEntry} entry
     */
    triggerAnimation: function (entry) {
        const element = entry.target;
        element.classList.remove(KAL.startStateClass);
        element.classList.add(KAL.endStateClass);
    },

    /**
     * Reverse animation
     * @param {IntersectionObserverEntry} entry
     */
    reverseAnimation: function (entry) {
        const element = entry.target;
        element.classList.add(KAL.startStateClass);
        element.classList.remove(KAL.endStateClass);
    },
};



/***/ }),

/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js&":
/*!*****************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js& ***!
  \*****************************************************************************************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _paybackPeriodIntake_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodIntake.vue */ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue");
/* harmony import */ var _paybackPeriodResult_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./paybackPeriodResult.vue */ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue");
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//



/* harmony default export */ __webpack_exports__["default"] = ({
  name: 'payback-period-calculator',
  components: {
    paybackPeriodIntake: _paybackPeriodIntake_vue__WEBPACK_IMPORTED_MODULE_1__["default"],
    paybackPeriodResultTable: _paybackPeriodResult_vue__WEBPACK_IMPORTED_MODULE_2__["default"]
  },
  props: {
    'translations': {
      'type': String
    },
    'config': {
      'type': String
    }
  },
  data: function data() {
    return {
      parsedTranslations: {},
      parsedConfig: {},
      results: {
        investmentCosts: 0,
        pesticideSavings: 0,
        paybackTime: 0
      }
    };
  },
  created: function created() {
    this.parsedTranslations = JSON.parse(this.translations);
    this.parsedConfig = JSON.parse(this.config);
  },
  methods: {
    updateResult: function updateResult(event) {
      this.calculate(event);
    },
    calculate: function calculate(event) {
      var investmentCosts = event.widthCalculated * 800;
      var pesticideSavings = event.savingsCalculated / 100 * event.costsCalculated;
      var paybackTime = investmentCosts / pesticideSavings;
      this.results.paybackTime = paybackTime;
      this.results.investmentCosts = investmentCosts;
      this.results.pesticideSavings = pesticideSavings;
    }
  }
});

/***/ }),

/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js&":
/*!*************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js& ***!
  \*************************************************************************************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _paybackPeriodTextInput_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodTextInput.vue */ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue");
/* harmony import */ var _formatUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./formatUtils */ "./resources/js/vue/paybackPeriod/formatUtils.js");
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//



/* harmony default export */ __webpack_exports__["default"] = ({
  name: 'payback-period-intake',
  components: {
    paybackPeriodTextInput: _paybackPeriodTextInput_vue__WEBPACK_IMPORTED_MODULE_1__["default"]
  },
  props: {
    'translations': {
      'type': String
    },
    'config': {
      'type': String
    },
    'onDark': {
      'type': Boolean
    },
    step: {
      type: Number,
      "default": 1
    }
  },
  data: function data() {
    return {
      parsedTranslations: {},
      parsedConfig: {},
      widthCalculated: 0,
      costsCalculated: 0,
      savingsCalculated: 0
    };
  },
  created: function created() {
    var uri = window.location.search.substring(1);
    var params = new URLSearchParams(uri);
    this.parsedTranslations = JSON.parse(this.translations);
    this.parsedConfig = JSON.parse(this.config);
    this.widthCalculated = parseInt(params.get("width")) || parseInt(this.parsedConfig.width.initial);
    this.costsCalculated = parseInt(params.get("costs")) || parseInt(this.parsedConfig.costs.initial);
    this.savingsCalculated = parseInt(params.get("savings")) || parseInt(this.parsedConfig.savings.initial);
    this.quantityInputChanged();
  },
  methods: {
    quantityInputChanged: function quantityInputChanged(event) {
      if (event) {
        switch (event.id) {
          case 'rangeSliderInputWidth':
            this.widthCalculated = event.value;
            break;

          case 'rangeSliderInputCosts':
            this.costsCalculated = event.value;
            break;

          case 'rangeSliderInputSavings':
            this.savingsCalculated = event.value;
            break;

          default:
        }
      }

      this.updateParents();
    },
    sliderChanged: function sliderChanged(event) {
      switch (event.target.id) {
        case 'rangeSliderWidth':
          this.widthCalculated = _formatUtils__WEBPACK_IMPORTED_MODULE_2__["default"].convertToInteger(event.target.value);
          break;

        case 'rangeSliderCosts':
          this.costsCalculated = _formatUtils__WEBPACK_IMPORTED_MODULE_2__["default"].convertToInteger(event.target.value);
          break;

        case 'rangeSliderSavings':
          this.savingsCalculated = _formatUtils__WEBPACK_IMPORTED_MODULE_2__["default"].convertToInteger(event.target.value);
          break;

        default:
      }

      this.updateParents();
    },
    updateParents: function updateParents() {
      this.$emit('inputsChanged', {
        widthCalculated: parseInt(this.widthCalculated),
        costsCalculated: parseInt(this.costsCalculated),
        savingsCalculated: parseInt(this.savingsCalculated)
      });
    }
  }
});

/***/ }),

/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js&":
/*!*************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js& ***!
  \*************************************************************************************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _formatUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./formatUtils */ "./resources/js/vue/paybackPeriod/formatUtils.js");
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//


/* harmony default export */ __webpack_exports__["default"] = ({
  name: 'payback-period-result-table',
  props: {
    'translations': {
      'type': String
    },
    'investmentCosts': {
      'type': Number
    },
    'pesticideSavings': {
      'type': Number
    },
    'paybackTime': {
      'type': Number
    }
  },
  data: function data() {
    return {
      parsedTranslations: {}
    };
  },
  created: function created() {
    this.parsedTranslations = JSON.parse(this.translations);
  },
  computed: {
    investmentCostsFormatted: function investmentCostsFormatted() {
      return _formatUtils__WEBPACK_IMPORTED_MODULE_1__["default"].insertDots(this.investmentCosts);
    },
    pesticideSavingsFormatted: function pesticideSavingsFormatted() {
      return _formatUtils__WEBPACK_IMPORTED_MODULE_1__["default"].insertDots(this.pesticideSavings.toFixed(0));
    },
    paybackTimeFormatted: function paybackTimeFormatted() {
      return this.paybackTime.toFixed(2).replace('.', ',');
    }
  }
});

/***/ }),

/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js&":
/*!****************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js& ***!
  \****************************************************************************************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _formatUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./formatUtils */ "./resources/js/vue/paybackPeriod/formatUtils.js");
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//

/* harmony default export */ __webpack_exports__["default"] = ({
  name: 'payback-period-text-input',
  props: {
    identifier: {
      type: String,
      required: true
    },
    value: {
      type: Number
    },
    min: {
      type: Number,
      "default": 1
    },
    max: {
      type: Number,
      "default": null
    },
    step: {
      type: Number,
      "default": 5
    },
    forCurrency: {
      type: Boolean,
      "default": false
    },
    labelText: {
      type: String,
      "default": ''
    }
  },
  data: function data() {
    return {};
  },
  methods: {
    keyPressed: function keyPressed(event) {
      if (event.key === 'ArrowUp') {
        this.modifyValue(this.step);
      } else if (event.key === 'ArrowDown') this.modifyValue(-this.step);
    },
    modifyValue: function modifyValue(amount) {
      var value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].convertToInteger(this.internalValue);
      value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].forceToBeInRangeOf(value += amount, this.min, this.max);
      if (this.forCurrency) value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].insertDots(value.toString(10), 3);
      this.$emit('change', {
        value: _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].convertToInteger(value),
        id: this.identifier
      });
    }
  },
  computed: {
    internalValue: function internalValue() {
      return this.value;
    },
    displayValue: {
      get: function get() {
        var value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].convertToInteger(this.value);
        value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].forceToBeInRangeOf(value, this.min, this.max);
        if (this.forCurrency) value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].insertDots(value.toString(10), 3);
        return value;
      },
      set: function set(newValue) {
        // eslint-disable-next-line no-unused-vars
        var value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].convertToInteger(newValue);
        value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].forceToBeInRangeOf(value, this.min, this.max);
        if (this.forCurrency) value = _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].insertDots(value.toString(10), 3); // this.internalValue = FormatUtils.convertToInteger(value);

        this.$emit('change', {
          value: _formatUtils__WEBPACK_IMPORTED_MODULE_0__["default"].convertToInteger(value),
          id: this.identifier
        });
        this.$forceUpdate();
      }
    }
  }
});

/***/ }),

/***/ "./node_modules/chocolat/dist/js/chocolat.esm.js":
/*!*******************************************************!*\
  !*** ./node_modules/chocolat/dist/js/chocolat.esm.js ***!
  \*******************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
let timerDebounce = undefined;
function debounce(duration, callback) {
  clearTimeout(timerDebounce);
  timerDebounce = setTimeout(function () {
    callback();
  }, duration);
  return timerDebounce;
}
function transitionAsPromise(triggeringFunc, el) {
  return new Promise(resolve => {
    const handleTransitionEnd = () => {
      el.removeEventListener('transitionend', handleTransitionEnd);
      resolve();
    };

    el.addEventListener('transitionend', handleTransitionEnd);
    const classesBefore = el.getAttribute('class');
    const stylesBefore = el.getAttribute('style');
    triggeringFunc();

    if (classesBefore === el.getAttribute('class') && stylesBefore === el.getAttribute('style')) {
      handleTransitionEnd();
    }

    if (parseFloat(getComputedStyle(el)['transitionDuration']) === 0) {
      handleTransitionEnd();
    }
  });
}
function loadImage({
  src,
  srcset,
  sizes
}) {
  const image = new Image();
  image.src = src;

  if (srcset) {
    image.srcset = srcset;
  }

  if (sizes) {
    image.sizes = sizes;
  }

  if ('decode' in image) {
    return new Promise((resolve, reject) => {
      image.decode().then(() => {
        resolve(image);
      }).catch(() => {
        reject(image);
      });
    });
  } else {
    return new Promise((resolve, reject) => {
      image.onload = resolve(image);
      image.onerror = reject(image);
    });
  }
}
function fit(options) {
  let height;
  let width;
  const {
    imgHeight,
    imgWidth,
    containerHeight,
    containerWidth,
    canvasWidth,
    canvasHeight,
    imageSize
  } = options;
  const canvasRatio = canvasHeight / canvasWidth;
  const containerRatio = containerHeight / containerWidth;
  const imgRatio = imgHeight / imgWidth;

  if (imageSize == 'cover') {
    if (imgRatio < containerRatio) {
      height = containerHeight;
      width = height / imgRatio;
    } else {
      width = containerWidth;
      height = width * imgRatio;
    }
  } else if (imageSize == 'native') {
    height = imgHeight;
    width = imgWidth;
  } else {
    if (imgRatio > canvasRatio) {
      height = canvasHeight;
      width = height / imgRatio;
    } else {
      width = canvasWidth;
      height = width * imgRatio;
    }

    if (imageSize === 'scale-down' && (width >= imgWidth || height >= imgHeight)) {
      width = imgWidth;
      height = imgHeight;
    }
  }

  return {
    height: height,
    width: width
  };
}
function openFullScreen(wrapper) {
  if (wrapper.requestFullscreen) {
    return wrapper.requestFullscreen();
  } else if (wrapper.webkitRequestFullscreen) {
    return wrapper.webkitRequestFullscreen();
  } else if (wrapper.msRequestFullscreen) {
    return wrapper.msRequestFullscreen();
  } else {
    return Promise.reject();
  }
}
function exitFullScreen() {
  if (document.exitFullscreen) {
    return document.exitFullscreen();
  } else if (document.webkitExitFullscreen) {
    return document.webkitExitFullscreen();
  } else if (document.msExitFullscreen) {
    return document.msExitFullscreen();
  } else {
    return Promise.reject();
  }
}

const defaults = {
  container: document.body,
  // window or element
  className: undefined,
  imageSize: 'scale-down',
  // 'scale-down', 'contain', 'cover' or 'native'
  fullScreen: false,
  loop: false,
  linkImages: true,
  setIndex: 0,
  firstImageIndex: 0,
  lastImageIndex: false,
  currentImageIndex: undefined,
  allowZoom: true,
  closeOnBackgroundClick: true,
  setTitle: function () {
    return '';
  },
  description: function () {
    return this.images[this.settings.currentImageIndex].title;
  },
  pagination: function () {
    const last = this.settings.lastImageIndex + 1;
    const position = this.settings.currentImageIndex + 1;
    return position + '/' + last;
  },

  afterInitialize() {},

  afterMarkup() {},

  afterImageLoad() {},

  afterClose() {},

  zoomedPaddingX: function (canvasWidth, imgWidth) {
    return 0;
  },
  zoomedPaddingY: function (canvasHeight, imgHeight) {
    return 0;
  }
};
class Chocolat {
  constructor(elements, settings) {
    this.settings = settings;
    this.elems = {};
    this.images = [];
    this.events = [];
    this.state = {
      fullScreenOpen: false,
      initialZoomState: null,
      initialized: false,
      timer: false,
      visible: false
    };
    this._cssClasses = ['chocolat-open', 'chocolat-in-container', 'chocolat-cover', 'chocolat-zoomable', 'chocolat-zoomed', 'chocolat-zooming-in', 'chocolat-zooming-out'];

    if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) {
      elements.forEach((el, i) => {
        this.images.push({
          title: el.getAttribute('title'),
          src: el.getAttribute('href'),
          srcset: el.getAttribute('data-srcset'),
          sizes: el.getAttribute('data-sizes')
        });
        this.off(el, 'click.chocolat');
        this.on(el, 'click.chocolat', e => {
          this.init(i);
          e.preventDefault();
        });
      });
    } else {
      this.images = elements;
    }

    if (this.settings.container instanceof Element || this.settings.container instanceof HTMLElement) {
      this.elems.container = this.settings.container;
    } else {
      this.elems.container = document.body;
    }

    this.api = {
      open: i => {
        i = parseInt(i) || 0;
        return this.init(i);
      },
      close: () => {
        return this.close();
      },
      next: () => {
        return this.change(1);
      },
      prev: () => {
        return this.change(-1);
      },
      goto: i => {
        return this.open(i);
      },
      current: () => {
        return this.settings.currentImageIndex;
      },
      position: () => {
        return this.position(this.elems.img);
      },
      destroy: () => {
        return this.destroy();
      },
      set: (property, value) => {
        this.settings[property] = value;
        return value;
      },
      get: property => {
        return this.settings[property];
      },
      getElem: name => {
        return this.elems[name];
      }
    };
  }

  init(i) {
    if (!this.state.initialized) {
      this.markup();
      this.attachListeners();
      this.settings.lastImageIndex = this.images.length - 1;
      this.state.initialized = true;
    }

    this.settings.afterInitialize.call(this);
    return this.load(i);
  }

  load(index) {
    if (!this.state.visible) {
      this.state.visible = true;
      setTimeout(() => {
        this.elems.overlay.classList.add('chocolat-visible');
        this.elems.wrapper.classList.add('chocolat-visible');
      }, 0);
      this.elems.container.classList.add('chocolat-open');
    }

    if (this.settings.fullScreen) {
      this.state.fullScreenOpen = openFullScreen(this.elems.wrapper);
    }

    if (this.settings.currentImageIndex === index) {
      return Promise.resolve();
    }

    let loaderTimer = setTimeout(() => {
      this.elems.loader.classList.add('chocolat-visible');
    }, 1000);
    let fadeOutPromise;
    let image;
    let fadeOutTimer = setTimeout(() => {
      fadeOutTimer = undefined;
      fadeOutPromise = transitionAsPromise(() => {
        this.elems.imageCanvas.classList.remove('chocolat-visible');
      }, this.elems.imageCanvas);
    }, 80);
    return loadImage(this.images[index]).then(loadedImage => {
      image = loadedImage;

      if (fadeOutTimer) {
        clearTimeout(fadeOutTimer);
        return Promise.resolve();
      } else {
        return fadeOutPromise;
      }
    }).then(() => {
      const nextIndex = index + 1;

      if (this.images[nextIndex] != undefined) {
        loadImage(this.images[nextIndex]);
      }

      this.settings.currentImageIndex = index;
      this.elems.description.textContent = this.settings.description.call(this);
      this.elems.pagination.textContent = this.settings.pagination.call(this);
      this.arrows();
      return this.position(image).then(() => {
        this.elems.loader.classList.remove('chocolat-visible');
        clearTimeout(loaderTimer);
        return this.appear(image);
      });
    }).then(() => {
      this.elems.container.classList.toggle('chocolat-zoomable', this.zoomable(image, this.elems.wrapper));
      this.settings.afterImageLoad.call(this);
    });
  }

  position({
    naturalHeight,
    naturalWidth
  }) {
    const fitOptions = {
      imgHeight: naturalHeight,
      imgWidth: naturalWidth,
      containerHeight: this.elems.container.clientHeight,
      containerWidth: this.elems.container.clientWidth,
      canvasWidth: this.elems.imageCanvas.clientWidth,
      canvasHeight: this.elems.imageCanvas.clientHeight,
      imageSize: this.settings.imageSize
    };
    const {
      width,
      height
    } = fit(fitOptions);
    return transitionAsPromise(() => {
      Object.assign(this.elems.imageWrapper.style, {
        width: width + 'px',
        height: height + 'px'
      });
    }, this.elems.imageWrapper);
  }

  appear(image) {
    this.elems.imageWrapper.removeChild(this.elems.img);
    this.elems.img = image;
    this.elems.img.setAttribute('class', 'chocolat-img');
    this.elems.imageWrapper.appendChild(this.elems.img);
    const fadeInPromise = transitionAsPromise(() => {
      this.elems.imageCanvas.classList.add('chocolat-visible');
    }, this.elems.imageCanvas);
    return fadeInPromise;
  }

  change(step) {
    if (!this.state.visible) {
      return;
    }

    if (!this.settings.linkImages) {
      return;
    }

    this.zoomOut();
    const requestedImage = this.settings.currentImageIndex + parseInt(step);

    if (requestedImage > this.settings.lastImageIndex) {
      if (this.settings.loop) {
        return this.load(this.settings.firstImageIndex);
      }
    } else if (requestedImage < this.settings.firstImageIndex) {
      if (this.settings.loop) {
        return this.load(this.settings.lastImageIndex);
      }
    } else {
      return this.load(requestedImage);
    }
  }

  arrows() {
    if (this.settings.loop) {
      this.elems.left.classList.add('active');
      this.elems.right.classList.add('active');
    } else if (this.settings.linkImages) {
      this.elems.right.classList.toggle('active', this.settings.currentImageIndex !== this.settings.lastImageIndex);
      this.elems.left.classList.toggle('active', this.settings.currentImageIndex !== this.settings.firstImageIndex);
    } else {
      this.elems.left.classList.remove('active');
      this.elems.right.classList.remove('active');
    }
  }

  close() {
    if (this.state.fullScreenOpen) {
      exitFullScreen();
      return;
    }

    this.state.visible = false;
    const promiseOverlay = transitionAsPromise(() => {
      this.elems.overlay.classList.remove('chocolat-visible');
    }, this.elems.overlay);
    const promiseWrapper = transitionAsPromise(() => {
      this.elems.wrapper.classList.remove('chocolat-visible');
    }, this.elems.wrapper);
    return Promise.all([promiseOverlay, promiseWrapper]).then(() => {
      this.elems.container.classList.remove('chocolat-open');
      this.settings.afterClose.call(this);
    });
  }

  destroy() {
    for (let i = this.events.length - 1; i >= 0; i--) {
      const {
        element,
        eventName
      } = this.events[i];
      this.off(element, eventName);
    }

    if (!this.state.initialized) {
      return;
    }

    if (this.state.fullScreenOpen) {
      this.state.fullScreenOpen = exitFullScreen();
    }

    this.settings.currentImageIndex = undefined;
    this.state.visible = false;
    this.state.initialized = false;
    this.elems.container.classList.remove(...this._cssClasses);
    this.elems.wrapper.parentNode.removeChild(this.elems.wrapper);
  }

  markup() {
    this.elems.container.classList.add('chocolat-open', this.settings.className);

    if (this.settings.imageSize == 'cover') {
      this.elems.container.classList.add('chocolat-cover');
    }

    if (this.elems.container !== document.body) {
      this.elems.container.classList.add('chocolat-in-container');
    }

    this.elems.wrapper = document.createElement('div');
    this.elems.wrapper.setAttribute('id', 'chocolat-content-' + this.settings.setIndex);
    this.elems.wrapper.setAttribute('class', 'chocolat-wrapper');
    this.elems.container.appendChild(this.elems.wrapper);
    this.elems.overlay = document.createElement('div');
    this.elems.overlay.setAttribute('class', 'chocolat-overlay');
    this.elems.wrapper.appendChild(this.elems.overlay);
    this.elems.loader = document.createElement('div');
    this.elems.loader.setAttribute('class', 'chocolat-loader');
    this.elems.wrapper.appendChild(this.elems.loader);
    this.elems.layout = document.createElement('div');
    this.elems.layout.setAttribute('class', 'chocolat-layout');
    this.elems.wrapper.appendChild(this.elems.layout);
    this.elems.top = document.createElement('div');
    this.elems.top.setAttribute('class', 'chocolat-top');
    this.elems.layout.appendChild(this.elems.top);
    this.elems.center = document.createElement('div');
    this.elems.center.setAttribute('class', 'chocolat-center');
    this.elems.layout.appendChild(this.elems.center);
    this.elems.left = document.createElement('div');
    this.elems.left.setAttribute('class', 'chocolat-left');
    this.elems.center.appendChild(this.elems.left);
    this.elems.imageCanvas = document.createElement('div');
    this.elems.imageCanvas.setAttribute('class', 'chocolat-image-canvas');
    this.elems.center.appendChild(this.elems.imageCanvas);
    this.elems.imageWrapper = document.createElement('div');
    this.elems.imageWrapper.setAttribute('class', 'chocolat-image-wrapper');
    this.elems.imageCanvas.appendChild(this.elems.imageWrapper);
    this.elems.img = document.createElement('img');
    this.elems.img.setAttribute('class', 'chocolat-img');
    this.elems.imageWrapper.appendChild(this.elems.img);
    this.elems.right = document.createElement('div');
    this.elems.right.setAttribute('class', 'chocolat-right');
    this.elems.center.appendChild(this.elems.right);
    this.elems.bottom = document.createElement('div');
    this.elems.bottom.setAttribute('class', 'chocolat-bottom');
    this.elems.layout.appendChild(this.elems.bottom);
    this.elems.close = document.createElement('span');
    this.elems.close.setAttribute('class', 'chocolat-close');
    this.elems.top.appendChild(this.elems.close);
    this.elems.description = document.createElement('span');
    this.elems.description.setAttribute('class', 'chocolat-description');
    this.elems.bottom.appendChild(this.elems.description);
    this.elems.pagination = document.createElement('span');
    this.elems.pagination.setAttribute('class', 'chocolat-pagination');
    this.elems.bottom.appendChild(this.elems.pagination);
    this.elems.setTitle = document.createElement('span');
    this.elems.setTitle.setAttribute('class', 'chocolat-set-title');
    this.elems.setTitle.textContent = this.settings.setTitle();
    this.elems.bottom.appendChild(this.elems.setTitle);
    this.elems.fullscreen = document.createElement('span');
    this.elems.fullscreen.setAttribute('class', 'chocolat-fullscreen');
    this.elems.bottom.appendChild(this.elems.fullscreen);
    this.settings.afterMarkup.call(this);
  }

  attachListeners() {
    this.off(document, 'keydown.chocolat');
    this.on(document, 'keydown.chocolat', e => {
      if (this.state.initialized) {
        if (e.keyCode == 37) {
          this.change(-1);
        } else if (e.keyCode == 39) {
          this.change(1);
        } else if (e.keyCode == 27) {
          this.close();
        }
      }
    });
    const right = this.elems.wrapper.querySelector('.chocolat-right');
    this.off(right, 'click.chocolat');
    this.on(right, 'click.chocolat', () => {
      this.change(+1);
    });
    const left = this.elems.wrapper.querySelector('.chocolat-left');
    this.off(left, 'click.chocolat');
    this.on(left, 'click.chocolat', () => {
      this.change(-1);
    });
    this.off(this.elems.close, 'click.chocolat');
    this.on(this.elems.close, 'click.chocolat', this.close.bind(this));
    this.off(this.elems.fullscreen, 'click.chocolat');
    this.on(this.elems.fullscreen, 'click.chocolat', () => {
      if (this.state.fullScreenOpen) {
        exitFullScreen();
        return;
      }

      openFullScreen(this.elems.wrapper);
    });
    this.off(document, 'fullscreenchange.chocolat');
    this.on(document, 'fullscreenchange.chocolat', () => {
      if (document.fullscreenElement) {
        this.state.fullScreenOpen = true;
      } else {
        this.state.fullScreenOpen = false;
      }
    });

    if (this.settings.closeOnBackgroundClick) {
      this.off(this.elems.overlay, 'click.chocolat');
      this.on(this.elems.overlay, 'click.chocolat', this.close.bind(this));
    }

    this.off(this.elems.wrapper, 'click.chocolat');
    this.on(this.elems.wrapper, 'click.chocolat', () => {
      if (this.state.initialZoomState === null || !this.state.visible) {
        return;
      }

      this.elems.container.classList.add('chocolat-zooming-out');
      this.zoomOut().then(() => {
        this.elems.container.classList.remove('chocolat-zoomed');
        this.elems.container.classList.remove('chocolat-zooming-out');
      });
    });
    this.off(this.elems.imageWrapper, 'click.chocolat');
    this.on(this.elems.imageWrapper, 'click.chocolat', e => {
      if (this.state.initialZoomState === null && this.elems.container.classList.contains('chocolat-zoomable')) {
        e.stopPropagation();
        this.elems.container.classList.add('chocolat-zooming-in');
        this.zoomIn(e).then(() => {
          this.elems.container.classList.add('chocolat-zoomed');
          this.elems.container.classList.remove('chocolat-zooming-in');
        });
      }
    });
    this.on(this.elems.wrapper, 'mousemove.chocolat', e => {
      if (this.state.initialZoomState === null || !this.state.visible) {
        return;
      }

      const rect = this.elems.wrapper.getBoundingClientRect();
      const pos = {
        top: rect.top + window.scrollY,
        left: rect.left + window.scrollX
      };
      const height = this.elems.wrapper.clientHeight;
      const width = this.elems.wrapper.clientWidth;
      const imgWidth = this.elems.img.width;
      const imgHeight = this.elems.img.height;
      const coord = [e.pageX - width / 2 - pos.left, e.pageY - height / 2 - pos.top];
      let mvtX = 0;

      if (imgWidth > width) {
        const paddingX = this.settings.zoomedPaddingX(imgWidth, width);
        mvtX = coord[0] / (width / 2);
        mvtX = ((imgWidth - width) / 2 + paddingX) * mvtX;
      }

      let mvtY = 0;

      if (imgHeight > height) {
        const paddingY = this.settings.zoomedPaddingY(imgHeight, height);
        mvtY = coord[1] / (height / 2);
        mvtY = ((imgHeight - height) / 2 + paddingY) * mvtY;
      }

      this.elems.img.style.marginLeft = -mvtX + 'px';
      this.elems.img.style.marginTop = -mvtY + 'px';
    });
    this.on(window, 'resize.chocolat', e => {
      if (!this.state.initialized || !this.state.visible) {
        return;
      }

      debounce(50, () => {
        const fitOptions = {
          imgHeight: this.elems.img.naturalHeight,
          imgWidth: this.elems.img.naturalWidth,
          containerHeight: this.elems.wrapper.clientHeight,
          containerWidth: this.elems.wrapper.clientWidth,
          canvasWidth: this.elems.imageCanvas.clientWidth,
          canvasHeight: this.elems.imageCanvas.clientHeight,
          imageSize: this.settings.imageSize
        };
        const {
          width,
          height
        } = fit(fitOptions);
        this.position(this.elems.img).then(() => {
          this.elems.container.classList.toggle('chocolat-zoomable', this.zoomable(this.elems.img, this.elems.wrapper));
        });
      });
    });
  }

  zoomable(image, wrapper) {
    const wrapperWidth = wrapper.clientWidth;
    const wrapperHeight = wrapper.clientHeight;
    const isImageZoomable = this.settings.allowZoom && (image.naturalWidth > wrapperWidth || image.naturalHeight > wrapperHeight) ? true : false;
    const isImageStretched = image.clientWidth > image.naturalWidth || image.clientHeight > image.naturalHeight;
    return isImageZoomable && !isImageStretched;
  }

  zoomIn(e) {
    this.state.initialZoomState = this.settings.imageSize;
    this.settings.imageSize = 'native';
    return this.position(this.elems.img);
  }

  zoomOut(e) {
    this.settings.imageSize = this.state.initialZoomState || this.settings.imageSize;
    this.state.initialZoomState = null;
    this.elems.img.style.margin = 0;
    return this.position(this.elems.img);
  }

  on(element, eventName, cb) {
    // const eventName = this.settings.setIndex + '-' + eventName
    const length = this.events.push({
      element,
      eventName,
      cb
    });
    element.addEventListener(eventName.split('.')[0], this.events[length - 1].cb);
  }

  off(element, eventName) {
    // const eventName = this.settings.setIndex + '-' + eventName
    const index = this.events.findIndex(event => {
      return event.element === element && event.eventName === eventName;
    });

    if (this.events[index]) {
      element.removeEventListener(eventName.split('.')[0], this.events[index].cb);
      this.events.splice(index, 1);
    }
  }

}

const instances = [];
function main_esm (elements, options) {
  const settings = Object.assign({}, defaults, {
    images: []
  }, options, {
    setIndex: instances.length
  });
  const instance = new Chocolat(elements, settings);
  instances.push(instance);
  return instance;
}

/* harmony default export */ __webpack_exports__["default"] = (main_esm);


/***/ }),

/***/ "./node_modules/process/browser.js":
/*!*****************************************!*\
  !*** ./node_modules/process/browser.js ***!
  \*****************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };


/***/ }),

/***/ "./node_modules/setimmediate/setImmediate.js":
/*!***************************************************!*\
  !*** ./node_modules/setimmediate/setImmediate.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
    "use strict";

    if (global.setImmediate) {
        return;
    }

    var nextHandle = 1; // Spec says greater than zero
    var tasksByHandle = {};
    var currentlyRunningATask = false;
    var doc = global.document;
    var registerImmediate;

    function setImmediate(callback) {
      // Callback can either be a function or a string
      if (typeof callback !== "function") {
        callback = new Function("" + callback);
      }
      // Copy function arguments
      var args = new Array(arguments.length - 1);
      for (var i = 0; i < args.length; i++) {
          args[i] = arguments[i + 1];
      }
      // Store and register the task
      var task = { callback: callback, args: args };
      tasksByHandle[nextHandle] = task;
      registerImmediate(nextHandle);
      return nextHandle++;
    }

    function clearImmediate(handle) {
        delete tasksByHandle[handle];
    }

    function run(task) {
        var callback = task.callback;
        var args = task.args;
        switch (args.length) {
        case 0:
            callback();
            break;
        case 1:
            callback(args[0]);
            break;
        case 2:
            callback(args[0], args[1]);
            break;
        case 3:
            callback(args[0], args[1], args[2]);
            break;
        default:
            callback.apply(undefined, args);
            break;
        }
    }

    function runIfPresent(handle) {
        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
        // So if we're currently running a task, we'll need to delay this invocation.
        if (currentlyRunningATask) {
            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
            // "too much recursion" error.
            setTimeout(runIfPresent, 0, handle);
        } else {
            var task = tasksByHandle[handle];
            if (task) {
                currentlyRunningATask = true;
                try {
                    run(task);
                } finally {
                    clearImmediate(handle);
                    currentlyRunningATask = false;
                }
            }
        }
    }

    function installNextTickImplementation() {
        registerImmediate = function(handle) {
            process.nextTick(function () { runIfPresent(handle); });
        };
    }

    function canUsePostMessage() {
        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
        // where `global.postMessage` means something completely different and can't be used for this purpose.
        if (global.postMessage && !global.importScripts) {
            var postMessageIsAsynchronous = true;
            var oldOnMessage = global.onmessage;
            global.onmessage = function() {
                postMessageIsAsynchronous = false;
            };
            global.postMessage("", "*");
            global.onmessage = oldOnMessage;
            return postMessageIsAsynchronous;
        }
    }

    function installPostMessageImplementation() {
        // Installs an event handler on `global` for the `message` event: see
        // * https://developer.mozilla.org/en/DOM/window.postMessage
        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

        var messagePrefix = "setImmediate$" + Math.random() + "$";
        var onGlobalMessage = function(event) {
            if (event.source === global &&
                typeof event.data === "string" &&
                event.data.indexOf(messagePrefix) === 0) {
                runIfPresent(+event.data.slice(messagePrefix.length));
            }
        };

        if (global.addEventListener) {
            global.addEventListener("message", onGlobalMessage, false);
        } else {
            global.attachEvent("onmessage", onGlobalMessage);
        }

        registerImmediate = function(handle) {
            global.postMessage(messagePrefix + handle, "*");
        };
    }

    function installMessageChannelImplementation() {
        var channel = new MessageChannel();
        channel.port1.onmessage = function(event) {
            var handle = event.data;
            runIfPresent(handle);
        };

        registerImmediate = function(handle) {
            channel.port2.postMessage(handle);
        };
    }

    function installReadyStateChangeImplementation() {
        var html = doc.documentElement;
        registerImmediate = function(handle) {
            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
            var script = doc.createElement("script");
            script.onreadystatechange = function () {
                runIfPresent(handle);
                script.onreadystatechange = null;
                html.removeChild(script);
                script = null;
            };
            html.appendChild(script);
        };
    }

    function installSetTimeoutImplementation() {
        registerImmediate = function(handle) {
            setTimeout(runIfPresent, 0, handle);
        };
    }

    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;

    // Don't get fooled by e.g. browserify environments.
    if ({}.toString.call(global.process) === "[object process]") {
        // For Node.js before 0.9
        installNextTickImplementation();

    } else if (canUsePostMessage()) {
        // For non-IE10 modern browsers
        installPostMessageImplementation();

    } else if (global.MessageChannel) {
        // For web workers, where supported
        installMessageChannelImplementation();

    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
        // For IE 6–8
        installReadyStateChangeImplementation();

    } else {
        // For older browsers
        installSetTimeoutImplementation();
    }

    attachTo.setImmediate = setImmediate;
    attachTo.clearImmediate = clearImmediate;
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))

/***/ }),

/***/ "./node_modules/timers-browserify/main.js":
/*!************************************************!*\
  !*** ./node_modules/timers-browserify/main.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) ||
            (typeof self !== "undefined" && self) ||
            window;
var apply = Function.prototype.apply;

// DOM APIs, for completeness

exports.setTimeout = function() {
  return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);
};
exports.setInterval = function() {
  return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);
};
exports.clearTimeout =
exports.clearInterval = function(timeout) {
  if (timeout) {
    timeout.close();
  }
};

function Timeout(id, clearFn) {
  this._id = id;
  this._clearFn = clearFn;
}
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
Timeout.prototype.close = function() {
  this._clearFn.call(scope, this._id);
};

// Does not start the time, just sets up the members needed.
exports.enroll = function(item, msecs) {
  clearTimeout(item._idleTimeoutId);
  item._idleTimeout = msecs;
};

exports.unenroll = function(item) {
  clearTimeout(item._idleTimeoutId);
  item._idleTimeout = -1;
};

exports._unrefActive = exports.active = function(item) {
  clearTimeout(item._idleTimeoutId);

  var msecs = item._idleTimeout;
  if (msecs >= 0) {
    item._idleTimeoutId = setTimeout(function onTimeout() {
      if (item._onTimeout)
        item._onTimeout();
    }, msecs);
  }
};

// setimmediate attaches itself to the global object
__webpack_require__(/*! setimmediate */ "./node_modules/setimmediate/setImmediate.js");
// On some exotic environments, it's not clear which object `setimmediate` was
// able to install onto.  Search each possibility in the same order as the
// `setimmediate` library.
exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
                       (typeof global !== "undefined" && global.setImmediate) ||
                       (this && this.setImmediate);
exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
                         (typeof global !== "undefined" && global.clearImmediate) ||
                         (this && this.clearImmediate);

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/url-search-params-polyfill/index.js":
/*!**********************************************************!*\
  !*** ./node_modules/url-search-params-polyfill/index.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {/**
 *
 *
 * @author Jerry Bendy <jerry@icewingcc.com>
 * @licence MIT
 *
 */

(function(self) {
    'use strict';

    var nativeURLSearchParams = (function() {
            // #41 Fix issue in RN
            try {
                if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') {
                    return self.URLSearchParams;
                }
            } catch (e) {}
            return null;
        })(),
        isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1',
        // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus.
        decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'),
        __URLSearchParams__ = "__URLSearchParams__",
        // Fix bug in Edge which cannot encode ' &' correctly
        encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() {
            var ampersandTest = new nativeURLSearchParams();
            ampersandTest.append('s', ' &');
            return ampersandTest.toString() === 's=+%26';
        })() : true,
        prototype = URLSearchParamsPolyfill.prototype,
        iterable = !!(self.Symbol && self.Symbol.iterator);

    if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) {
        return;
    }


    /**
     * Make a URLSearchParams instance
     *
     * @param {object|string|URLSearchParams} search
     * @constructor
     */
    function URLSearchParamsPolyfill(search) {
        search = search || "";

        // support construct object with another URLSearchParams instance
        if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {
            search = search.toString();
        }
        this [__URLSearchParams__] = parseToDict(search);
    }


    /**
     * Appends a specified key/value pair as a new search parameter.
     *
     * @param {string} name
     * @param {string} value
     */
    prototype.append = function(name, value) {
        appendTo(this [__URLSearchParams__], name, value);
    };

    /**
     * Deletes the given search parameter, and its associated value,
     * from the list of all search parameters.
     *
     * @param {string} name
     */
    prototype['delete'] = function(name) {
        delete this [__URLSearchParams__] [name];
    };

    /**
     * Returns the first value associated to the given search parameter.
     *
     * @param {string} name
     * @returns {string|null}
     */
    prototype.get = function(name) {
        var dict = this [__URLSearchParams__];
        return this.has(name) ? dict[name][0] : null;
    };

    /**
     * Returns all the values association with a given search parameter.
     *
     * @param {string} name
     * @returns {Array}
     */
    prototype.getAll = function(name) {
        var dict = this [__URLSearchParams__];
        return this.has(name) ? dict [name].slice(0) : [];
    };

    /**
     * Returns a Boolean indicating if such a search parameter exists.
     *
     * @param {string} name
     * @returns {boolean}
     */
    prototype.has = function(name) {
        return hasOwnProperty(this [__URLSearchParams__], name);
    };

    /**
     * Sets the value associated to a given search parameter to
     * the given value. If there were several values, delete the
     * others.
     *
     * @param {string} name
     * @param {string} value
     */
    prototype.set = function set(name, value) {
        this [__URLSearchParams__][name] = ['' + value];
    };

    /**
     * Returns a string containg a query string suitable for use in a URL.
     *
     * @returns {string}
     */
    prototype.toString = function() {
        var dict = this[__URLSearchParams__], query = [], i, key, name, value;
        for (key in dict) {
            name = encode(key);
            for (i = 0, value = dict[key]; i < value.length; i++) {
                query.push(name + '=' + encode(value[i]));
            }
        }
        return query.join('&');
    };

    // There is a bug in Safari 10.1 and `Proxy`ing it is not enough.
    var forSureUsePolyfill = !decodesPlusesCorrectly;
    var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy);
    /*
     * Apply polifill to global object and append other prototype into it
     */
    Object.defineProperty(self, 'URLSearchParams', {
        value: (useProxy ?
            // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0
            new Proxy(nativeURLSearchParams, {
                construct: function(target, args) {
                    return new target((new URLSearchParamsPolyfill(args[0]).toString()));
                }
            }) :
            URLSearchParamsPolyfill)
    });

    var USPProto = self.URLSearchParams.prototype;

    USPProto.polyfill = true;

    /**
     *
     * @param {function} callback
     * @param {object} thisArg
     */
    USPProto.forEach = USPProto.forEach || function(callback, thisArg) {
        var dict = parseToDict(this.toString());
        Object.getOwnPropertyNames(dict).forEach(function(name) {
            dict[name].forEach(function(value) {
                callback.call(thisArg, value, name, this);
            }, this);
        }, this);
    };

    /**
     * Sort all name-value pairs
     */
    USPProto.sort = USPProto.sort || function() {
        var dict = parseToDict(this.toString()), keys = [], k, i, j;
        for (k in dict) {
            keys.push(k);
        }
        keys.sort();

        for (i = 0; i < keys.length; i++) {
            this['delete'](keys[i]);
        }
        for (i = 0; i < keys.length; i++) {
            var key = keys[i], values = dict[key];
            for (j = 0; j < values.length; j++) {
                this.append(key, values[j]);
            }
        }
    };

    /**
     * Returns an iterator allowing to go through all keys of
     * the key/value pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.keys = USPProto.keys || function() {
        var items = [];
        this.forEach(function(item, name) {
            items.push(name);
        });
        return makeIterator(items);
    };

    /**
     * Returns an iterator allowing to go through all values of
     * the key/value pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.values = USPProto.values || function() {
        var items = [];
        this.forEach(function(item) {
            items.push(item);
        });
        return makeIterator(items);
    };

    /**
     * Returns an iterator allowing to go through all key/value
     * pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.entries = USPProto.entries || function() {
        var items = [];
        this.forEach(function(item, name) {
            items.push([name, item]);
        });
        return makeIterator(items);
    };


    if (iterable) {
        USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries;
    }


    function encode(str) {
        var replace = {
            '!': '%21',
            "'": '%27',
            '(': '%28',
            ')': '%29',
            '~': '%7E',
            '%20': '+',
            '%00': '\x00'
        };
        return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
            return replace[match];
        });
    }

    function decode(str) {
        return str
            .replace(/[ +]/g, '%20')
            .replace(/(%[a-f0-9]{2})+/ig, function(match) {
                return decodeURIComponent(match);
            });
    }

    function makeIterator(arr) {
        var iterator = {
            next: function() {
                var value = arr.shift();
                return {done: value === undefined, value: value};
            }
        };

        if (iterable) {
            iterator[self.Symbol.iterator] = function() {
                return iterator;
            };
        }

        return iterator;
    }

    function parseToDict(search) {
        var dict = {};

        if (typeof search === "object") {
            // if `search` is an array, treat it as a sequence
            if (isArray(search)) {
                for (var i = 0; i < search.length; i++) {
                    var item = search[i];
                    if (isArray(item) && item.length === 2) {
                        appendTo(dict, item[0], item[1]);
                    } else {
                        throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements");
                    }
                }

            } else {
                for (var key in search) {
                    if (search.hasOwnProperty(key)) {
                        appendTo(dict, key, search[key]);
                    }
                }
            }

        } else {
            // remove first '?'
            if (search.indexOf("?") === 0) {
                search = search.slice(1);
            }

            var pairs = search.split("&");
            for (var j = 0; j < pairs.length; j++) {
                var value = pairs [j],
                    index = value.indexOf('=');

                if (-1 < index) {
                    appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));

                } else {
                    if (value) {
                        appendTo(dict, decode(value), '');
                    }
                }
            }
        }

        return dict;
    }

    function appendTo(dict, name, value) {
        var val = typeof value === 'string' ? value : (
            value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)
        );

        // #47 Prevent using `hasOwnProperty` as a property name
        if (hasOwnProperty(dict, name)) {
            dict[name].push(val);
        } else {
            dict[name] = [val];
        }
    }

    function isArray(val) {
        return !!val && '[object Array]' === Object.prototype.toString.call(val);
    }

    function hasOwnProperty(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    }

})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this));

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8&":
/*!*********************************************************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8& ***!
  \*********************************************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; });
var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c("div", { staticClass: "o-calculate" }, [
    _c(
      "div",
      { staticClass: "o-calculate__main" },
      [
        _c("div", { staticClass: "o-calculate__controls" }, [
          _c("h2", { staticClass: "o-calculate__heading" }, [
            _vm._v(_vm._s(this.parsedTranslations.calculate_form.heading))
          ]),
          _vm._v(" "),
          _c(
            "div",
            { staticClass: "o-calculate__sliders" },
            [
              _c("payback-period-intake", {
                attrs: {
                  translations: this.translations,
                  config: this.config,
                  "on-dark": ""
                },
                on: { inputsChanged: _vm.updateResult }
              })
            ],
            1
          )
        ]),
        _vm._v(" "),
        _c(
          "payback-period-result-table",
          _vm._b(
            { attrs: { translations: this.translations } },
            "payback-period-result-table",
            this.results,
            false
          )
        ),
        _vm._v(" "),
        _vm._t("calculate-contact")
      ],
      2
    )
  ])
}
var staticRenderFns = []
render._withStripped = true



/***/ }),

/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746&":
/*!*****************************************************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746& ***!
  \*****************************************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; });
var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c(
    "div",
    { class: ["c-range-sliders", { "c-range-sliders--on-dark": _vm.onDark }] },
    [
      _c(
        "div",
        { staticClass: "c-range-sliders__row" },
        [
          _c(
            "label",
            {
              staticClass: "c-range-sliders__label",
              attrs: { for: "slider-value-width" }
            },
            [_vm._v(_vm._s(this.parsedTranslations.sliders.width.label))]
          ),
          _vm._v(" "),
          _c("div", { staticClass: "c-range-sliders__meter" }, [
            _c("input", {
              staticClass: "c-input-range",
              attrs: {
                id: "rangeSliderWidth",
                type: "range",
                step: "1",
                name: "width",
                min: this.parsedConfig.width.min,
                max: this.parsedConfig.width.max
              },
              domProps: { value: this.widthCalculated },
              on: { input: _vm.sliderChanged, change: _vm.sliderChanged }
            })
          ]),
          _vm._v(" "),
          _c("payback-period-text-input", {
            attrs: {
              identifier: "rangeSliderInputWidth",
              step: 1,
              value: _vm.widthCalculated,
              min: this.parsedConfig.width.min,
              max: this.parsedConfig.width.max,
              labelText: this.parsedTranslations.sliders.width.unit
            },
            on: { change: _vm.quantityInputChanged }
          })
        ],
        1
      ),
      _vm._v(" "),
      _c(
        "div",
        { staticClass: "c-range-sliders__row" },
        [
          _c("label", {
            staticClass: "c-range-sliders__label",
            attrs: { for: "slider-value-costs" },
            domProps: {
              innerHTML: _vm._s(this.parsedTranslations.sliders.costs.label)
            }
          }),
          _vm._v(" "),
          _c("div", { staticClass: "c-range-sliders__meter" }, [
            _c("input", {
              staticClass: "c-input-range",
              attrs: {
                id: "rangeSliderCosts",
                type: "range",
                step: "5000",
                name: "costs",
                min: this.parsedConfig.costs.min,
                max: this.parsedConfig.costs.max
              },
              domProps: { value: this.costsCalculated },
              on: { input: _vm.sliderChanged, change: _vm.sliderChanged }
            })
          ]),
          _vm._v(" "),
          _c("payback-period-text-input", {
            attrs: {
              identifier: "rangeSliderInputCosts",
              step: 5000,
              value: _vm.costsCalculated,
              min: this.parsedConfig.costs.min,
              max: this.parsedConfig.costs.max,
              forCurrency: true,
              labelText: this.parsedTranslations.sliders.costs.unit
            },
            on: { change: _vm.quantityInputChanged }
          })
        ],
        1
      ),
      _vm._v(" "),
      _c(
        "div",
        { staticClass: "c-range-sliders__row" },
        [
          _c(
            "label",
            {
              staticClass: "c-range-sliders__label",
              attrs: { for: "slider-value-savings" }
            },
            [_vm._v(_vm._s(this.parsedTranslations.sliders.savings.label))]
          ),
          _vm._v(" "),
          _c("div", { staticClass: "c-range-sliders__meter" }, [
            _c("input", {
              staticClass: "c-input-range",
              attrs: {
                id: "rangeSliderSavings",
                type: "range",
                step: "1",
                name: "savings",
                min: this.parsedConfig.savings.min,
                max: this.parsedConfig.savings.max
              },
              domProps: { value: this.savingsCalculated },
              on: { input: _vm.sliderChanged, change: _vm.sliderChanged }
            })
          ]),
          _vm._v(" "),
          _c("payback-period-text-input", {
            attrs: {
              identifier: "rangeSliderInputSavings",
              step: 1,
              value: _vm.savingsCalculated,
              min: this.parsedConfig.savings.min,
              max: this.parsedConfig.savings.max,
              labelText: this.parsedTranslations.sliders.savings.unit
            },
            on: { change: _vm.quantityInputChanged }
          })
        ],
        1
      )
    ]
  )
}
var staticRenderFns = []
render._withStripped = true



/***/ }),

/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092&":
/*!*****************************************************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092& ***!
  \*****************************************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; });
var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c(
    "div",
    { staticClass: "o-calculate__table", attrs: { role: "grid" } },
    [
      _c("div", { staticClass: "o-calculate__row", attrs: { role: "row" } }, [
        _c(
          "div",
          {
            staticClass: "o-calculate__label  u-fw-bold",
            attrs: { role: "gridcell" }
          },
          [_vm._v(_vm._s(this.parsedTranslations.table.title))]
        )
      ]),
      _vm._v(" "),
      _c("div", { staticClass: "o-calculate__row", attrs: { role: "row" } }, [
        _c(
          "div",
          { staticClass: "o-calculate__label", attrs: { role: "gridcell" } },
          [
            _c("span", [
              _vm._v(_vm._s(this.parsedTranslations.table.investmentCosts))
            ])
          ]
        ),
        _vm._v(" "),
        _c(
          "div",
          { staticClass: "o-calculate__value", attrs: { role: "gridcell" } },
          [
            _c("span", { staticClass: "u-fw-bold" }, [
              _vm._v("€ " + _vm._s(this.investmentCostsFormatted))
            ])
          ]
        )
      ]),
      _vm._v(" "),
      _c("div", { staticClass: "o-calculate__row", attrs: { role: "row" } }, [
        _c(
          "div",
          { staticClass: "o-calculate__label", attrs: { role: "gridcell" } },
          [_vm._v(_vm._s(this.parsedTranslations.table.pesticideSavings))]
        ),
        _vm._v(" "),
        _c(
          "div",
          { staticClass: "o-calculate__value", attrs: { role: "gridcell" } },
          [
            _c("span", { staticClass: "u-fw-bold" }, [
              _vm._v("€ " + _vm._s(this.pesticideSavingsFormatted))
            ]),
            _vm._v(" " + _vm._s(this.parsedTranslations.perYear) + "\n        ")
          ]
        )
      ]),
      _vm._v(" "),
      _c("div", { staticClass: "o-calculate__footer" }, [
        _c("div", { staticClass: "o-calculate__row", attrs: { role: "row" } }, [
          _c(
            "div",
            { staticClass: "o-calculate__label", attrs: { role: "gridcell" } },
            [_vm._v(_vm._s(this.parsedTranslations.table.paybackTime) + ":")]
          ),
          _vm._v(" "),
          _c(
            "div",
            { staticClass: "o-calculate__value", attrs: { role: "gridcell" } },
            [
              _c("span", { staticClass: "u-fw-bold" }, [
                _vm._v(_vm._s(this.paybackTimeFormatted))
              ]),
              _vm._v(
                " " + _vm._s(this.parsedTranslations.year) + "\n            "
              )
            ]
          )
        ])
      ])
    ]
  )
}
var staticRenderFns = []
render._withStripped = true



/***/ }),

/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a&":
/*!********************************************************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a& ***!
  \********************************************************************************************************************************************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return staticRenderFns; });
var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c("div", { staticClass: "c-range-sliders__details" }, [
    _c("input", {
      directives: [
        {
          name: "model",
          rawName: "v-model",
          value: _vm.displayValue,
          expression: "displayValue"
        }
      ],
      staticClass: "c-range-sliders__value",
      attrs: {
        disabled: true,
        id: _vm.identifier,
        "data-lpignore": "true",
        type: "text",
        autocomplete: "off"
      },
      domProps: { value: _vm.displayValue },
      on: {
        keydown: _vm.keyPressed,
        input: function($event) {
          if ($event.target.composing) {
            return
          }
          _vm.displayValue = $event.target.value
        }
      }
    }),
    _vm._v(" "),
    _c("label", {
      staticClass: "c-range-sliders__unit",
      attrs: { for: _vm.identifier },
      domProps: { innerHTML: _vm._s(this.labelText) }
    })
  ])
}
var staticRenderFns = []
render._withStripped = true



/***/ }),

/***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js":
/*!********************************************************************!*\
  !*** ./node_modules/vue-loader/lib/runtime/componentNormalizer.js ***!
  \********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return normalizeComponent; });
/* globals __VUE_SSR_CONTEXT__ */

// IMPORTANT: Do NOT use ES2015 features in this file (except for modules).
// This module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle.

function normalizeComponent (
  scriptExports,
  render,
  staticRenderFns,
  functionalTemplate,
  injectStyles,
  scopeId,
  moduleIdentifier, /* server only */
  shadowMode /* vue-cli only */
) {
  // Vue.extend constructor export interop
  var options = typeof scriptExports === 'function'
    ? scriptExports.options
    : scriptExports

  // render functions
  if (render) {
    options.render = render
    options.staticRenderFns = staticRenderFns
    options._compiled = true
  }

  // functional template
  if (functionalTemplate) {
    options.functional = true
  }

  // scopedId
  if (scopeId) {
    options._scopeId = 'data-v-' + scopeId
  }

  var hook
  if (moduleIdentifier) { // server build
    hook = function (context) {
      // 2.3 injection
      context =
        context || // cached call
        (this.$vnode && this.$vnode.ssrContext) || // stateful
        (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
      // 2.2 with runInNewContext: true
      if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
        context = __VUE_SSR_CONTEXT__
      }
      // inject component styles
      if (injectStyles) {
        injectStyles.call(this, context)
      }
      // register component module identifier for async chunk inferrence
      if (context && context._registeredComponents) {
        context._registeredComponents.add(moduleIdentifier)
      }
    }
    // used by ssr in case component is cached and beforeCreate
    // never gets called
    options._ssrRegister = hook
  } else if (injectStyles) {
    hook = shadowMode
      ? function () {
        injectStyles.call(
          this,
          (options.functional ? this.parent : this).$root.$options.shadowRoot
        )
      }
      : injectStyles
  }

  if (hook) {
    if (options.functional) {
      // for template-only hot-reload because in that case the render fn doesn't
      // go through the normalizer
      options._injectStyles = hook
      // register for functional component in vue file
      var originalRender = options.render
      options.render = function renderWithStyleInjection (h, context) {
        hook.call(context)
        return originalRender(h, context)
      }
    } else {
      // inject component registration as beforeCreate hook
      var existing = options.beforeCreate
      options.beforeCreate = existing
        ? [].concat(existing, hook)
        : [hook]
    }
  }

  return {
    exports: scriptExports,
    options: options
  }
}


/***/ }),

/***/ "./node_modules/vue/dist/vue.common.dev.js":
/*!*************************************************!*\
  !*** ./node_modules/vue/dist/vue.common.dev.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global, setImmediate) {/*!
 * Vue.js v2.6.12
 * (c) 2014-2020 Evan You
 * Released under the MIT License.
 */


/*  */

var emptyObject = Object.freeze({});

// These helpers produce better VM code in JS engines due to their
// explicitness and function inlining.
function isUndef (v) {
  return v === undefined || v === null
}

function isDef (v) {
  return v !== undefined && v !== null
}

function isTrue (v) {
  return v === true
}

function isFalse (v) {
  return v === false
}

/**
 * Check if value is primitive.
 */
function isPrimitive (value) {
  return (
    typeof value === 'string' ||
    typeof value === 'number' ||
    // $flow-disable-line
    typeof value === 'symbol' ||
    typeof value === 'boolean'
  )
}

/**
 * Quick object check - this is primarily used to tell
 * Objects from primitive values when we know the value
 * is a JSON-compliant type.
 */
function isObject (obj) {
  return obj !== null && typeof obj === 'object'
}

/**
 * Get the raw type string of a value, e.g., [object Object].
 */
var _toString = Object.prototype.toString;

function toRawType (value) {
  return _toString.call(value).slice(8, -1)
}

/**
 * Strict object type check. Only returns true
 * for plain JavaScript objects.
 */
function isPlainObject (obj) {
  return _toString.call(obj) === '[object Object]'
}

function isRegExp (v) {
  return _toString.call(v) === '[object RegExp]'
}

/**
 * Check if val is a valid array index.
 */
function isValidArrayIndex (val) {
  var n = parseFloat(String(val));
  return n >= 0 && Math.floor(n) === n && isFinite(val)
}

function isPromise (val) {
  return (
    isDef(val) &&
    typeof val.then === 'function' &&
    typeof val.catch === 'function'
  )
}

/**
 * Convert a value to a string that is actually rendered.
 */
function toString (val) {
  return val == null
    ? ''
    : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
      ? JSON.stringify(val, null, 2)
      : String(val)
}

/**
 * Convert an input value to a number for persistence.
 * If the conversion fails, return original string.
 */
function toNumber (val) {
  var n = parseFloat(val);
  return isNaN(n) ? val : n
}

/**
 * Make a map and return a function for checking if a key
 * is in that map.
 */
function makeMap (
  str,
  expectsLowerCase
) {
  var map = Object.create(null);
  var list = str.split(',');
  for (var i = 0; i < list.length; i++) {
    map[list[i]] = true;
  }
  return expectsLowerCase
    ? function (val) { return map[val.toLowerCase()]; }
    : function (val) { return map[val]; }
}

/**
 * Check if a tag is a built-in tag.
 */
var isBuiltInTag = makeMap('slot,component', true);

/**
 * Check if an attribute is a reserved attribute.
 */
var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');

/**
 * Remove an item from an array.
 */
function remove (arr, item) {
  if (arr.length) {
    var index = arr.indexOf(item);
    if (index > -1) {
      return arr.splice(index, 1)
    }
  }
}

/**
 * Check whether an object has the property.
 */
var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn (obj, key) {
  return hasOwnProperty.call(obj, key)
}

/**
 * Create a cached version of a pure function.
 */
function cached (fn) {
  var cache = Object.create(null);
  return (function cachedFn (str) {
    var hit = cache[str];
    return hit || (cache[str] = fn(str))
  })
}

/**
 * Camelize a hyphen-delimited string.
 */
var camelizeRE = /-(\w)/g;
var camelize = cached(function (str) {
  return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
});

/**
 * Capitalize a string.
 */
var capitalize = cached(function (str) {
  return str.charAt(0).toUpperCase() + str.slice(1)
});

/**
 * Hyphenate a camelCase string.
 */
var hyphenateRE = /\B([A-Z])/g;
var hyphenate = cached(function (str) {
  return str.replace(hyphenateRE, '-$1').toLowerCase()
});

/**
 * Simple bind polyfill for environments that do not support it,
 * e.g., PhantomJS 1.x. Technically, we don't need this anymore
 * since native bind is now performant enough in most browsers.
 * But removing it would mean breaking code that was able to run in
 * PhantomJS 1.x, so this must be kept for backward compatibility.
 */

/* istanbul ignore next */
function polyfillBind (fn, ctx) {
  function boundFn (a) {
    var l = arguments.length;
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)
        : fn.call(ctx, a)
      : fn.call(ctx)
  }

  boundFn._length = fn.length;
  return boundFn
}

function nativeBind (fn, ctx) {
  return fn.bind(ctx)
}

var bind = Function.prototype.bind
  ? nativeBind
  : polyfillBind;

/**
 * Convert an Array-like object to a real Array.
 */
function toArray (list, start) {
  start = start || 0;
  var i = list.length - start;
  var ret = new Array(i);
  while (i--) {
    ret[i] = list[i + start];
  }
  return ret
}

/**
 * Mix properties into target object.
 */
function extend (to, _from) {
  for (var key in _from) {
    to[key] = _from[key];
  }
  return to
}

/**
 * Merge an Array of Objects into a single Object.
 */
function toObject (arr) {
  var res = {};
  for (var i = 0; i < arr.length; i++) {
    if (arr[i]) {
      extend(res, arr[i]);
    }
  }
  return res
}

/* eslint-disable no-unused-vars */

/**
 * Perform no operation.
 * Stubbing args to make Flow happy without leaving useless transpiled code
 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/).
 */
function noop (a, b, c) {}

/**
 * Always return false.
 */
var no = function (a, b, c) { return false; };

/* eslint-enable no-unused-vars */

/**
 * Return the same value.
 */
var identity = function (_) { return _; };

/**
 * Generate a string containing static keys from compiler modules.
 */
function genStaticKeys (modules) {
  return modules.reduce(function (keys, m) {
    return keys.concat(m.staticKeys || [])
  }, []).join(',')
}

/**
 * Check if two values are loosely equal - that is,
 * if they are plain objects, do they have the same shape?
 */
function looseEqual (a, b) {
  if (a === b) { return true }
  var isObjectA = isObject(a);
  var isObjectB = isObject(b);
  if (isObjectA && isObjectB) {
    try {
      var isArrayA = Array.isArray(a);
      var isArrayB = Array.isArray(b);
      if (isArrayA && isArrayB) {
        return a.length === b.length && a.every(function (e, i) {
          return looseEqual(e, b[i])
        })
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime()
      } else if (!isArrayA && !isArrayB) {
        var keysA = Object.keys(a);
        var keysB = Object.keys(b);
        return keysA.length === keysB.length && keysA.every(function (key) {
          return looseEqual(a[key], b[key])
        })
      } else {
        /* istanbul ignore next */
        return false
      }
    } catch (e) {
      /* istanbul ignore next */
      return false
    }
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}

/**
 * Return the first index at which a loosely equal value can be
 * found in the array (if value is a plain object, the array must
 * contain an object of the same shape), or -1 if it is not present.
 */
function looseIndexOf (arr, val) {
  for (var i = 0; i < arr.length; i++) {
    if (looseEqual(arr[i], val)) { return i }
  }
  return -1
}

/**
 * Ensure a function is called only once.
 */
function once (fn) {
  var called = false;
  return function () {
    if (!called) {
      called = true;
      fn.apply(this, arguments);
    }
  }
}

var SSR_ATTR = 'data-server-rendered';

var ASSET_TYPES = [
  'component',
  'directive',
  'filter'
];

var LIFECYCLE_HOOKS = [
  'beforeCreate',
  'created',
  'beforeMount',
  'mounted',
  'beforeUpdate',
  'updated',
  'beforeDestroy',
  'destroyed',
  'activated',
  'deactivated',
  'errorCaptured',
  'serverPrefetch'
];

/*  */



var config = ({
  /**
   * Option merge strategies (used in core/util/options)
   */
  // $flow-disable-line
  optionMergeStrategies: Object.create(null),

  /**
   * Whether to suppress warnings.
   */
  silent: false,

  /**
   * Show production mode tip message on boot?
   */
  productionTip: "development" !== 'production',

  /**
   * Whether to enable devtools
   */
  devtools: "development" !== 'production',

  /**
   * Whether to record perf
   */
  performance: false,

  /**
   * Error handler for watcher errors
   */
  errorHandler: null,

  /**
   * Warn handler for watcher warns
   */
  warnHandler: null,

  /**
   * Ignore certain custom elements
   */
  ignoredElements: [],

  /**
   * Custom user key aliases for v-on
   */
  // $flow-disable-line
  keyCodes: Object.create(null),

  /**
   * Check if a tag is reserved so that it cannot be registered as a
   * component. This is platform-dependent and may be overwritten.
   */
  isReservedTag: no,

  /**
   * Check if an attribute is reserved so that it cannot be used as a component
   * prop. This is platform-dependent and may be overwritten.
   */
  isReservedAttr: no,

  /**
   * Check if a tag is an unknown element.
   * Platform-dependent.
   */
  isUnknownElement: no,

  /**
   * Get the namespace of an element
   */
  getTagNamespace: noop,

  /**
   * Parse the real tag name for the specific platform.
   */
  parsePlatformTagName: identity,

  /**
   * Check if an attribute must be bound using property, e.g. value
   * Platform-dependent.
   */
  mustUseProp: no,

  /**
   * Perform updates asynchronously. Intended to be used by Vue Test Utils
   * This will significantly reduce performance if set to false.
   */
  async: true,

  /**
   * Exposed for legacy reasons
   */
  _lifecycleHooks: LIFECYCLE_HOOKS
});

/*  */

/**
 * unicode letters used for parsing html tags, component names and property paths.
 * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
 * skipping \u10000-\uEFFFF due to it freezing up PhantomJS
 */
var unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;

/**
 * Check if a string starts with $ or _
 */
function isReserved (str) {
  var c = (str + '').charCodeAt(0);
  return c === 0x24 || c === 0x5F
}

/**
 * Define a property.
 */
function def (obj, key, val, enumerable) {
  Object.defineProperty(obj, key, {
    value: val,
    enumerable: !!enumerable,
    writable: true,
    configurable: true
  });
}

/**
 * Parse simple path.
 */
var bailRE = new RegExp(("[^" + (unicodeRegExp.source) + ".$_\\d]"));
function parsePath (path) {
  if (bailRE.test(path)) {
    return
  }
  var segments = path.split('.');
  return function (obj) {
    for (var i = 0; i < segments.length; i++) {
      if (!obj) { return }
      obj = obj[segments[i]];
    }
    return obj
  }
}

/*  */

// can we use __proto__?
var hasProto = '__proto__' in {};

// Browser environment sniffing
var inBrowser = typeof window !== 'undefined';
var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
var isIE = UA && /msie|trident/.test(UA);
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
var isEdge = UA && UA.indexOf('edge/') > 0;
var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
var isPhantomJS = UA && /phantomjs/.test(UA);
var isFF = UA && UA.match(/firefox\/(\d+)/);

// Firefox has a "watch" function on Object.prototype...
var nativeWatch = ({}).watch;

var supportsPassive = false;
if (inBrowser) {
  try {
    var opts = {};
    Object.defineProperty(opts, 'passive', ({
      get: function get () {
        /* istanbul ignore next */
        supportsPassive = true;
      }
    })); // https://github.com/facebook/flow/issues/285
    window.addEventListener('test-passive', null, opts);
  } catch (e) {}
}

// this needs to be lazy-evaled because vue may be required before
// vue-server-renderer can set VUE_ENV
var _isServer;
var isServerRendering = function () {
  if (_isServer === undefined) {
    /* istanbul ignore if */
    if (!inBrowser && !inWeex && typeof global !== 'undefined') {
      // detect presence of vue-server-renderer and avoid
      // Webpack shimming the process
      _isServer = global['process'] && global['process'].env.VUE_ENV === 'server';
    } else {
      _isServer = false;
    }
  }
  return _isServer
};

// detect devtools
var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;

/* istanbul ignore next */
function isNative (Ctor) {
  return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}

var hasSymbol =
  typeof Symbol !== 'undefined' && isNative(Symbol) &&
  typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);

var _Set;
/* istanbul ignore if */ // $flow-disable-line
if (typeof Set !== 'undefined' && isNative(Set)) {
  // use native Set when available.
  _Set = Set;
} else {
  // a non-standard Set polyfill that only works with primitive keys.
  _Set = /*@__PURE__*/(function () {
    function Set () {
      this.set = Object.create(null);
    }
    Set.prototype.has = function has (key) {
      return this.set[key] === true
    };
    Set.prototype.add = function add (key) {
      this.set[key] = true;
    };
    Set.prototype.clear = function clear () {
      this.set = Object.create(null);
    };

    return Set;
  }());
}

/*  */

var warn = noop;
var tip = noop;
var generateComponentTrace = (noop); // work around flow check
var formatComponentName = (noop);

{
  var hasConsole = typeof console !== 'undefined';
  var classifyRE = /(?:^|[-_])(\w)/g;
  var classify = function (str) { return str
    .replace(classifyRE, function (c) { return c.toUpperCase(); })
    .replace(/[-_]/g, ''); };

  warn = function (msg, vm) {
    var trace = vm ? generateComponentTrace(vm) : '';

    if (config.warnHandler) {
      config.warnHandler.call(null, msg, vm, trace);
    } else if (hasConsole && (!config.silent)) {
      console.error(("[Vue warn]: " + msg + trace));
    }
  };

  tip = function (msg, vm) {
    if (hasConsole && (!config.silent)) {
      console.warn("[Vue tip]: " + msg + (
        vm ? generateComponentTrace(vm) : ''
      ));
    }
  };

  formatComponentName = function (vm, includeFile) {
    if (vm.$root === vm) {
      return '<Root>'
    }
    var options = typeof vm === 'function' && vm.cid != null
      ? vm.options
      : vm._isVue
        ? vm.$options || vm.constructor.options
        : vm;
    var name = options.name || options._componentTag;
    var file = options.__file;
    if (!name && file) {
      var match = file.match(/([^/\\]+)\.vue$/);
      name = match && match[1];
    }

    return (
      (name ? ("<" + (classify(name)) + ">") : "<Anonymous>") +
      (file && includeFile !== false ? (" at " + file) : '')
    )
  };

  var repeat = function (str, n) {
    var res = '';
    while (n) {
      if (n % 2 === 1) { res += str; }
      if (n > 1) { str += str; }
      n >>= 1;
    }
    return res
  };

  generateComponentTrace = function (vm) {
    if (vm._isVue && vm.$parent) {
      var tree = [];
      var currentRecursiveSequence = 0;
      while (vm) {
        if (tree.length > 0) {
          var last = tree[tree.length - 1];
          if (last.constructor === vm.constructor) {
            currentRecursiveSequence++;
            vm = vm.$parent;
            continue
          } else if (currentRecursiveSequence > 0) {
            tree[tree.length - 1] = [last, currentRecursiveSequence];
            currentRecursiveSequence = 0;
          }
        }
        tree.push(vm);
        vm = vm.$parent;
      }
      return '\n\nfound in\n\n' + tree
        .map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)
            ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)")
            : formatComponentName(vm))); })
        .join('\n')
    } else {
      return ("\n\n(found in " + (formatComponentName(vm)) + ")")
    }
  };
}

/*  */

var uid = 0;

/**
 * A dep is an observable that can have multiple
 * directives subscribing to it.
 */
var Dep = function Dep () {
  this.id = uid++;
  this.subs = [];
};

Dep.prototype.addSub = function addSub (sub) {
  this.subs.push(sub);
};

Dep.prototype.removeSub = function removeSub (sub) {
  remove(this.subs, sub);
};

Dep.prototype.depend = function depend () {
  if (Dep.target) {
    Dep.target.addDep(this);
  }
};

Dep.prototype.notify = function notify () {
  // stabilize the subscriber list first
  var subs = this.subs.slice();
  if (!config.async) {
    // subs aren't sorted in scheduler if not running async
    // we need to sort them now to make sure they fire in correct
    // order
    subs.sort(function (a, b) { return a.id - b.id; });
  }
  for (var i = 0, l = subs.length; i < l; i++) {
    subs[i].update();
  }
};

// The current target watcher being evaluated.
// This is globally unique because only one watcher
// can be evaluated at a time.
Dep.target = null;
var targetStack = [];

function pushTarget (target) {
  targetStack.push(target);
  Dep.target = target;
}

function popTarget () {
  targetStack.pop();
  Dep.target = targetStack[targetStack.length - 1];
}

/*  */

var VNode = function VNode (
  tag,
  data,
  children,
  text,
  elm,
  context,
  componentOptions,
  asyncFactory
) {
  this.tag = tag;
  this.data = data;
  this.children = children;
  this.text = text;
  this.elm = elm;
  this.ns = undefined;
  this.context = context;
  this.fnContext = undefined;
  this.fnOptions = undefined;
  this.fnScopeId = undefined;
  this.key = data && data.key;
  this.componentOptions = componentOptions;
  this.componentInstance = undefined;
  this.parent = undefined;
  this.raw = false;
  this.isStatic = false;
  this.isRootInsert = true;
  this.isComment = false;
  this.isCloned = false;
  this.isOnce = false;
  this.asyncFactory = asyncFactory;
  this.asyncMeta = undefined;
  this.isAsyncPlaceholder = false;
};

var prototypeAccessors = { child: { configurable: true } };

// DEPRECATED: alias for componentInstance for backwards compat.
/* istanbul ignore next */
prototypeAccessors.child.get = function () {
  return this.componentInstance
};

Object.defineProperties( VNode.prototype, prototypeAccessors );

var createEmptyVNode = function (text) {
  if ( text === void 0 ) text = '';

  var node = new VNode();
  node.text = text;
  node.isComment = true;
  return node
};

function createTextVNode (val) {
  return new VNode(undefined, undefined, undefined, String(val))
}

// optimized shallow clone
// used for static nodes and slot nodes because they may be reused across
// multiple renders, cloning them avoids errors when DOM manipulations rely
// on their elm reference.
function cloneVNode (vnode) {
  var cloned = new VNode(
    vnode.tag,
    vnode.data,
    // #7975
    // clone children array to avoid mutating original in case of cloning
    // a child.
    vnode.children && vnode.children.slice(),
    vnode.text,
    vnode.elm,
    vnode.context,
    vnode.componentOptions,
    vnode.asyncFactory
  );
  cloned.ns = vnode.ns;
  cloned.isStatic = vnode.isStatic;
  cloned.key = vnode.key;
  cloned.isComment = vnode.isComment;
  cloned.fnContext = vnode.fnContext;
  cloned.fnOptions = vnode.fnOptions;
  cloned.fnScopeId = vnode.fnScopeId;
  cloned.asyncMeta = vnode.asyncMeta;
  cloned.isCloned = true;
  return cloned
}

/*
 * not type checking this file because flow doesn't play well with
 * dynamically accessing methods on Array prototype
 */

var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);

var methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
];

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
  // cache original method
  var original = arrayProto[method];
  def(arrayMethods, method, function mutator () {
    var args = [], len = arguments.length;
    while ( len-- ) args[ len ] = arguments[ len ];

    var result = original.apply(this, args);
    var ob = this.__ob__;
    var inserted;
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args;
        break
      case 'splice':
        inserted = args.slice(2);
        break
    }
    if (inserted) { ob.observeArray(inserted); }
    // notify change
    ob.dep.notify();
    return result
  });
});

/*  */

var arrayKeys = Object.getOwnPropertyNames(arrayMethods);

/**
 * In some cases we may want to disable observation inside a component's
 * update computation.
 */
var shouldObserve = true;

function toggleObserving (value) {
  shouldObserve = value;
}

/**
 * Observer class that is attached to each observed
 * object. Once attached, the observer converts the target
 * object's property keys into getter/setters that
 * collect dependencies and dispatch updates.
 */
var Observer = function Observer (value) {
  this.value = value;
  this.dep = new Dep();
  this.vmCount = 0;
  def(value, '__ob__', this);
  if (Array.isArray(value)) {
    if (hasProto) {
      protoAugment(value, arrayMethods);
    } else {
      copyAugment(value, arrayMethods, arrayKeys);
    }
    this.observeArray(value);
  } else {
    this.walk(value);
  }
};

/**
 * Walk through all properties and convert them into
 * getter/setters. This method should only be called when
 * value type is Object.
 */
Observer.prototype.walk = function walk (obj) {
  var keys = Object.keys(obj);
  for (var i = 0; i < keys.length; i++) {
    defineReactive$$1(obj, keys[i]);
  }
};

/**
 * Observe a list of Array items.
 */
Observer.prototype.observeArray = function observeArray (items) {
  for (var i = 0, l = items.length; i < l; i++) {
    observe(items[i]);
  }
};

// helpers

/**
 * Augment a target Object or Array by intercepting
 * the prototype chain using __proto__
 */
function protoAugment (target, src) {
  /* eslint-disable no-proto */
  target.__proto__ = src;
  /* eslint-enable no-proto */
}

/**
 * Augment a target Object or Array by defining
 * hidden properties.
 */
/* istanbul ignore next */
function copyAugment (target, src, keys) {
  for (var i = 0, l = keys.length; i < l; i++) {
    var key = keys[i];
    def(target, key, src[key]);
  }
}

/**
 * Attempt to create an observer instance for a value,
 * returns the new observer if successfully observed,
 * or the existing observer if the value already has one.
 */
function observe (value, asRootData) {
  if (!isObject(value) || value instanceof VNode) {
    return
  }
  var ob;
  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
    ob = value.__ob__;
  } else if (
    shouldObserve &&
    !isServerRendering() &&
    (Array.isArray(value) || isPlainObject(value)) &&
    Object.isExtensible(value) &&
    !value._isVue
  ) {
    ob = new Observer(value);
  }
  if (asRootData && ob) {
    ob.vmCount++;
  }
  return ob
}

/**
 * Define a reactive property on an Object.
 */
function defineReactive$$1 (
  obj,
  key,
  val,
  customSetter,
  shallow
) {
  var dep = new Dep();

  var property = Object.getOwnPropertyDescriptor(obj, key);
  if (property && property.configurable === false) {
    return
  }

  // cater for pre-defined getter/setters
  var getter = property && property.get;
  var setter = property && property.set;
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key];
  }

  var childOb = !shallow && observe(val);
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      var value = getter ? getter.call(obj) : val;
      if (Dep.target) {
        dep.depend();
        if (childOb) {
          childOb.dep.depend();
          if (Array.isArray(value)) {
            dependArray(value);
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      var value = getter ? getter.call(obj) : val;
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      /* eslint-enable no-self-compare */
      if (customSetter) {
        customSetter();
      }
      // #7981: for accessor properties without setter
      if (getter && !setter) { return }
      if (setter) {
        setter.call(obj, newVal);
      } else {
        val = newVal;
      }
      childOb = !shallow && observe(newVal);
      dep.notify();
    }
  });
}

/**
 * Set a property on an object. Adds the new property and
 * triggers change notification if the property doesn't
 * already exist.
 */
function set (target, key, val) {
  if (isUndef(target) || isPrimitive(target)
  ) {
    warn(("Cannot set reactive property on undefined, null, or primitive value: " + ((target))));
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key);
    target.splice(key, 1, val);
    return val
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val
  }
  var ob = (target).__ob__;
  if (target._isVue || (ob && ob.vmCount)) {
    warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    );
    return val
  }
  if (!ob) {
    target[key] = val;
    return val
  }
  defineReactive$$1(ob.value, key, val);
  ob.dep.notify();
  return val
}

/**
 * Delete a property and trigger change if necessary.
 */
function del (target, key) {
  if (isUndef(target) || isPrimitive(target)
  ) {
    warn(("Cannot delete reactive property on undefined, null, or primitive value: " + ((target))));
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.splice(key, 1);
    return
  }
  var ob = (target).__ob__;
  if (target._isVue || (ob && ob.vmCount)) {
    warn(
      'Avoid deleting properties on a Vue instance or its root $data ' +
      '- just set it to null.'
    );
    return
  }
  if (!hasOwn(target, key)) {
    return
  }
  delete target[key];
  if (!ob) {
    return
  }
  ob.dep.notify();
}

/**
 * Collect dependencies on array elements when the array is touched, since
 * we cannot intercept array element access like property getters.
 */
function dependArray (value) {
  for (var e = (void 0), i = 0, l = value.length; i < l; i++) {
    e = value[i];
    e && e.__ob__ && e.__ob__.dep.depend();
    if (Array.isArray(e)) {
      dependArray(e);
    }
  }
}

/*  */

/**
 * Option overwriting strategies are functions that handle
 * how to merge a parent option value and a child option
 * value into the final value.
 */
var strats = config.optionMergeStrategies;

/**
 * Options with restrictions
 */
{
  strats.el = strats.propsData = function (parent, child, vm, key) {
    if (!vm) {
      warn(
        "option \"" + key + "\" can only be used during instance " +
        'creation with the `new` keyword.'
      );
    }
    return defaultStrat(parent, child)
  };
}

/**
 * Helper that recursively merges two data objects together.
 */
function mergeData (to, from) {
  if (!from) { return to }
  var key, toVal, fromVal;

  var keys = hasSymbol
    ? Reflect.ownKeys(from)
    : Object.keys(from);

  for (var i = 0; i < keys.length; i++) {
    key = keys[i];
    // in case the object is already observed...
    if (key === '__ob__') { continue }
    toVal = to[key];
    fromVal = from[key];
    if (!hasOwn(to, key)) {
      set(to, key, fromVal);
    } else if (
      toVal !== fromVal &&
      isPlainObject(toVal) &&
      isPlainObject(fromVal)
    ) {
      mergeData(toVal, fromVal);
    }
  }
  return to
}

/**
 * Data
 */
function mergeDataOrFn (
  parentVal,
  childVal,
  vm
) {
  if (!vm) {
    // in a Vue.extend merge, both should be functions
    if (!childVal) {
      return parentVal
    }
    if (!parentVal) {
      return childVal
    }
    // when parentVal & childVal are both present,
    // we need to return a function that returns the
    // merged result of both functions... no need to
    // check if parentVal is a function here because
    // it has to be a function to pass previous merges.
    return function mergedDataFn () {
      return mergeData(
        typeof childVal === 'function' ? childVal.call(this, this) : childVal,
        typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
      )
    }
  } else {
    return function mergedInstanceDataFn () {
      // instance merge
      var instanceData = typeof childVal === 'function'
        ? childVal.call(vm, vm)
        : childVal;
      var defaultData = typeof parentVal === 'function'
        ? parentVal.call(vm, vm)
        : parentVal;
      if (instanceData) {
        return mergeData(instanceData, defaultData)
      } else {
        return defaultData
      }
    }
  }
}

strats.data = function (
  parentVal,
  childVal,
  vm
) {
  if (!vm) {
    if (childVal && typeof childVal !== 'function') {
      warn(
        'The "data" option should be a function ' +
        'that returns a per-instance value in component ' +
        'definitions.',
        vm
      );

      return parentVal
    }
    return mergeDataOrFn(parentVal, childVal)
  }

  return mergeDataOrFn(parentVal, childVal, vm)
};

/**
 * Hooks and props are merged as arrays.
 */
function mergeHook (
  parentVal,
  childVal
) {
  var res = childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : Array.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal;
  return res
    ? dedupeHooks(res)
    : res
}

function dedupeHooks (hooks) {
  var res = [];
  for (var i = 0; i < hooks.length; i++) {
    if (res.indexOf(hooks[i]) === -1) {
      res.push(hooks[i]);
    }
  }
  return res
}

LIFECYCLE_HOOKS.forEach(function (hook) {
  strats[hook] = mergeHook;
});

/**
 * Assets
 *
 * When a vm is present (instance creation), we need to do
 * a three-way merge between constructor options, instance
 * options and parent options.
 */
function mergeAssets (
  parentVal,
  childVal,
  vm,
  key
) {
  var res = Object.create(parentVal || null);
  if (childVal) {
    assertObjectType(key, childVal, vm);
    return extend(res, childVal)
  } else {
    return res
  }
}

ASSET_TYPES.forEach(function (type) {
  strats[type + 's'] = mergeAssets;
});

/**
 * Watchers.
 *
 * Watchers hashes should not overwrite one
 * another, so we merge them as arrays.
 */
strats.watch = function (
  parentVal,
  childVal,
  vm,
  key
) {
  // work around Firefox's Object.prototype.watch...
  if (parentVal === nativeWatch) { parentVal = undefined; }
  if (childVal === nativeWatch) { childVal = undefined; }
  /* istanbul ignore if */
  if (!childVal) { return Object.create(parentVal || null) }
  {
    assertObjectType(key, childVal, vm);
  }
  if (!parentVal) { return childVal }
  var ret = {};
  extend(ret, parentVal);
  for (var key$1 in childVal) {
    var parent = ret[key$1];
    var child = childVal[key$1];
    if (parent && !Array.isArray(parent)) {
      parent = [parent];
    }
    ret[key$1] = parent
      ? parent.concat(child)
      : Array.isArray(child) ? child : [child];
  }
  return ret
};

/**
 * Other object hashes.
 */
strats.props =
strats.methods =
strats.inject =
strats.computed = function (
  parentVal,
  childVal,
  vm,
  key
) {
  if (childVal && "development" !== 'production') {
    assertObjectType(key, childVal, vm);
  }
  if (!parentVal) { return childVal }
  var ret = Object.create(null);
  extend(ret, parentVal);
  if (childVal) { extend(ret, childVal); }
  return ret
};
strats.provide = mergeDataOrFn;

/**
 * Default strategy.
 */
var defaultStrat = function (parentVal, childVal) {
  return childVal === undefined
    ? parentVal
    : childVal
};

/**
 * Validate component names
 */
function checkComponents (options) {
  for (var key in options.components) {
    validateComponentName(key);
  }
}

function validateComponentName (name) {
  if (!new RegExp(("^[a-zA-Z][\\-\\.0-9_" + (unicodeRegExp.source) + "]*$")).test(name)) {
    warn(
      'Invalid component name: "' + name + '". Component names ' +
      'should conform to valid custom element name in html5 specification.'
    );
  }
  if (isBuiltInTag(name) || config.isReservedTag(name)) {
    warn(
      'Do not use built-in or reserved HTML elements as component ' +
      'id: ' + name
    );
  }
}

/**
 * Ensure all props option syntax are normalized into the
 * Object-based format.
 */
function normalizeProps (options, vm) {
  var props = options.props;
  if (!props) { return }
  var res = {};
  var i, val, name;
  if (Array.isArray(props)) {
    i = props.length;
    while (i--) {
      val = props[i];
      if (typeof val === 'string') {
        name = camelize(val);
        res[name] = { type: null };
      } else {
        warn('props must be strings when using array syntax.');
      }
    }
  } else if (isPlainObject(props)) {
    for (var key in props) {
      val = props[key];
      name = camelize(key);
      res[name] = isPlainObject(val)
        ? val
        : { type: val };
    }
  } else {
    warn(
      "Invalid value for option \"props\": expected an Array or an Object, " +
      "but got " + (toRawType(props)) + ".",
      vm
    );
  }
  options.props = res;
}

/**
 * Normalize all injections into Object-based format
 */
function normalizeInject (options, vm) {
  var inject = options.inject;
  if (!inject) { return }
  var normalized = options.inject = {};
  if (Array.isArray(inject)) {
    for (var i = 0; i < inject.length; i++) {
      normalized[inject[i]] = { from: inject[i] };
    }
  } else if (isPlainObject(inject)) {
    for (var key in inject) {
      var val = inject[key];
      normalized[key] = isPlainObject(val)
        ? extend({ from: key }, val)
        : { from: val };
    }
  } else {
    warn(
      "Invalid value for option \"inject\": expected an Array or an Object, " +
      "but got " + (toRawType(inject)) + ".",
      vm
    );
  }
}

/**
 * Normalize raw function directives into object format.
 */
function normalizeDirectives (options) {
  var dirs = options.directives;
  if (dirs) {
    for (var key in dirs) {
      var def$$1 = dirs[key];
      if (typeof def$$1 === 'function') {
        dirs[key] = { bind: def$$1, update: def$$1 };
      }
    }
  }
}

function assertObjectType (name, value, vm) {
  if (!isPlainObject(value)) {
    warn(
      "Invalid value for option \"" + name + "\": expected an Object, " +
      "but got " + (toRawType(value)) + ".",
      vm
    );
  }
}

/**
 * Merge two option objects into a new one.
 * Core utility used in both instantiation and inheritance.
 */
function mergeOptions (
  parent,
  child,
  vm
) {
  {
    checkComponents(child);
  }

  if (typeof child === 'function') {
    child = child.options;
  }

  normalizeProps(child, vm);
  normalizeInject(child, vm);
  normalizeDirectives(child);

  // Apply extends and mixins on the child options,
  // but only if it is a raw options object that isn't
  // the result of another mergeOptions call.
  // Only merged options has the _base property.
  if (!child._base) {
    if (child.extends) {
      parent = mergeOptions(parent, child.extends, vm);
    }
    if (child.mixins) {
      for (var i = 0, l = child.mixins.length; i < l; i++) {
        parent = mergeOptions(parent, child.mixins[i], vm);
      }
    }
  }

  var options = {};
  var key;
  for (key in parent) {
    mergeField(key);
  }
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key);
    }
  }
  function mergeField (key) {
    var strat = strats[key] || defaultStrat;
    options[key] = strat(parent[key], child[key], vm, key);
  }
  return options
}

/**
 * Resolve an asset.
 * This function is used because child instances need access
 * to assets defined in its ancestor chain.
 */
function resolveAsset (
  options,
  type,
  id,
  warnMissing
) {
  /* istanbul ignore if */
  if (typeof id !== 'string') {
    return
  }
  var assets = options[type];
  // check local registration variations first
  if (hasOwn(assets, id)) { return assets[id] }
  var camelizedId = camelize(id);
  if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }
  var PascalCaseId = capitalize(camelizedId);
  if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }
  // fallback to prototype chain
  var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
  if (warnMissing && !res) {
    warn(
      'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
      options
    );
  }
  return res
}

/*  */



function validateProp (
  key,
  propOptions,
  propsData,
  vm
) {
  var prop = propOptions[key];
  var absent = !hasOwn(propsData, key);
  var value = propsData[key];
  // boolean casting
  var booleanIndex = getTypeIndex(Boolean, prop.type);
  if (booleanIndex > -1) {
    if (absent && !hasOwn(prop, 'default')) {
      value = false;
    } else if (value === '' || value === hyphenate(key)) {
      // only cast empty string / same name to boolean if
      // boolean has higher priority
      var stringIndex = getTypeIndex(String, prop.type);
      if (stringIndex < 0 || booleanIndex < stringIndex) {
        value = true;
      }
    }
  }
  // check default value
  if (value === undefined) {
    value = getPropDefaultValue(vm, prop, key);
    // since the default value is a fresh copy,
    // make sure to observe it.
    var prevShouldObserve = shouldObserve;
    toggleObserving(true);
    observe(value);
    toggleObserving(prevShouldObserve);
  }
  {
    assertProp(prop, key, value, vm, absent);
  }
  return value
}

/**
 * Get the default value of a prop.
 */
function getPropDefaultValue (vm, prop, key) {
  // no default, return undefined
  if (!hasOwn(prop, 'default')) {
    return undefined
  }
  var def = prop.default;
  // warn against non-factory defaults for Object & Array
  if (isObject(def)) {
    warn(
      'Invalid default value for prop "' + key + '": ' +
      'Props with type Object/Array must use a factory function ' +
      'to return the default value.',
      vm
    );
  }
  // the raw prop value was also undefined from previous render,
  // return previous default value to avoid unnecessary watcher trigger
  if (vm && vm.$options.propsData &&
    vm.$options.propsData[key] === undefined &&
    vm._props[key] !== undefined
  ) {
    return vm._props[key]
  }
  // call factory function for non-Function types
  // a value is Function if its prototype is function even across different execution context
  return typeof def === 'function' && getType(prop.type) !== 'Function'
    ? def.call(vm)
    : def
}

/**
 * Assert whether a prop is valid.
 */
function assertProp (
  prop,
  name,
  value,
  vm,
  absent
) {
  if (prop.required && absent) {
    warn(
      'Missing required prop: "' + name + '"',
      vm
    );
    return
  }
  if (value == null && !prop.required) {
    return
  }
  var type = prop.type;
  var valid = !type || type === true;
  var expectedTypes = [];
  if (type) {
    if (!Array.isArray(type)) {
      type = [type];
    }
    for (var i = 0; i < type.length && !valid; i++) {
      var assertedType = assertType(value, type[i]);
      expectedTypes.push(assertedType.expectedType || '');
      valid = assertedType.valid;
    }
  }

  if (!valid) {
    warn(
      getInvalidTypeMessage(name, value, expectedTypes),
      vm
    );
    return
  }
  var validator = prop.validator;
  if (validator) {
    if (!validator(value)) {
      warn(
        'Invalid prop: custom validator check failed for prop "' + name + '".',
        vm
      );
    }
  }
}

var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;

function assertType (value, type) {
  var valid;
  var expectedType = getType(type);
  if (simpleCheckRE.test(expectedType)) {
    var t = typeof value;
    valid = t === expectedType.toLowerCase();
    // for primitive wrapper objects
    if (!valid && t === 'object') {
      valid = value instanceof type;
    }
  } else if (expectedType === 'Object') {
    valid = isPlainObject(value);
  } else if (expectedType === 'Array') {
    valid = Array.isArray(value);
  } else {
    valid = value instanceof type;
  }
  return {
    valid: valid,
    expectedType: expectedType
  }
}

/**
 * Use function string name to check built-in types,
 * because a simple equality check will fail when running
 * across different vms / iframes.
 */
function getType (fn) {
  var match = fn && fn.toString().match(/^\s*function (\w+)/);
  return match ? match[1] : ''
}

function isSameType (a, b) {
  return getType(a) === getType(b)
}

function getTypeIndex (type, expectedTypes) {
  if (!Array.isArray(expectedTypes)) {
    return isSameType(expectedTypes, type) ? 0 : -1
  }
  for (var i = 0, len = expectedTypes.length; i < len; i++) {
    if (isSameType(expectedTypes[i], type)) {
      return i
    }
  }
  return -1
}

function getInvalidTypeMessage (name, value, expectedTypes) {
  var message = "Invalid prop: type check failed for prop \"" + name + "\"." +
    " Expected " + (expectedTypes.map(capitalize).join(', '));
  var expectedType = expectedTypes[0];
  var receivedType = toRawType(value);
  var expectedValue = styleValue(value, expectedType);
  var receivedValue = styleValue(value, receivedType);
  // check if we need to specify expected value
  if (expectedTypes.length === 1 &&
      isExplicable(expectedType) &&
      !isBoolean(expectedType, receivedType)) {
    message += " with value " + expectedValue;
  }
  message += ", got " + receivedType + " ";
  // check if we need to specify received value
  if (isExplicable(receivedType)) {
    message += "with value " + receivedValue + ".";
  }
  return message
}

function styleValue (value, type) {
  if (type === 'String') {
    return ("\"" + value + "\"")
  } else if (type === 'Number') {
    return ("" + (Number(value)))
  } else {
    return ("" + value)
  }
}

function isExplicable (value) {
  var explicitTypes = ['string', 'number', 'boolean'];
  return explicitTypes.some(function (elem) { return value.toLowerCase() === elem; })
}

function isBoolean () {
  var args = [], len = arguments.length;
  while ( len-- ) args[ len ] = arguments[ len ];

  return args.some(function (elem) { return elem.toLowerCase() === 'boolean'; })
}

/*  */

function handleError (err, vm, info) {
  // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
  // See: https://github.com/vuejs/vuex/issues/1505
  pushTarget();
  try {
    if (vm) {
      var cur = vm;
      while ((cur = cur.$parent)) {
        var hooks = cur.$options.errorCaptured;
        if (hooks) {
          for (var i = 0; i < hooks.length; i++) {
            try {
              var capture = hooks[i].call(cur, err, vm, info) === false;
              if (capture) { return }
            } catch (e) {
              globalHandleError(e, cur, 'errorCaptured hook');
            }
          }
        }
      }
    }
    globalHandleError(err, vm, info);
  } finally {
    popTarget();
  }
}

function invokeWithErrorHandling (
  handler,
  context,
  args,
  vm,
  info
) {
  var res;
  try {
    res = args ? handler.apply(context, args) : handler.call(context);
    if (res && !res._isVue && isPromise(res) && !res._handled) {
      res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
      // issue #9511
      // avoid catch triggering multiple times when nested calls
      res._handled = true;
    }
  } catch (e) {
    handleError(e, vm, info);
  }
  return res
}

function globalHandleError (err, vm, info) {
  if (config.errorHandler) {
    try {
      return config.errorHandler.call(null, err, vm, info)
    } catch (e) {
      // if the user intentionally throws the original error in the handler,
      // do not log it twice
      if (e !== err) {
        logError(e, null, 'config.errorHandler');
      }
    }
  }
  logError(err, vm, info);
}

function logError (err, vm, info) {
  {
    warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm);
  }
  /* istanbul ignore else */
  if ((inBrowser || inWeex) && typeof console !== 'undefined') {
    console.error(err);
  } else {
    throw err
  }
}

/*  */

var isUsingMicroTask = false;

var callbacks = [];
var pending = false;

function flushCallbacks () {
  pending = false;
  var copies = callbacks.slice(0);
  callbacks.length = 0;
  for (var i = 0; i < copies.length; i++) {
    copies[i]();
  }
}

// Here we have async deferring wrappers using microtasks.
// In 2.5 we used (macro) tasks (in combination with microtasks).
// However, it has subtle problems when state is changed right before repaint
// (e.g. #6813, out-in transitions).
// Also, using (macro) tasks in event handler would cause some weird behaviors
// that cannot be circumvented (e.g. #7109, #7153, #7546, #7834, #8109).
// So we now use microtasks everywhere, again.
// A major drawback of this tradeoff is that there are some scenarios
// where microtasks have too high a priority and fire in between supposedly
// sequential events (e.g. #4521, #6690, which have workarounds)
// or even between bubbling of the same event (#6566).
var timerFunc;

// The nextTick behavior leverages the microtask queue, which can be accessed
// via either native Promise.then or MutationObserver.
// MutationObserver has wider support, however it is seriously bugged in
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
// completely stops working after triggering a few times... so, if native
// Promise is available, we will use it:
/* istanbul ignore next, $flow-disable-line */
if (typeof Promise !== 'undefined' && isNative(Promise)) {
  var p = Promise.resolve();
  timerFunc = function () {
    p.then(flushCallbacks);
    // In problematic UIWebViews, Promise.then doesn't completely break, but
    // it can get stuck in a weird state where callbacks are pushed into the
    // microtask queue but the queue isn't being flushed, until the browser
    // needs to do some other work, e.g. handle a timer. Therefore we can
    // "force" the microtask queue to be flushed by adding an empty timer.
    if (isIOS) { setTimeout(noop); }
  };
  isUsingMicroTask = true;
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
  isNative(MutationObserver) ||
  // PhantomJS and iOS 7.x
  MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
  // Use MutationObserver where native Promise is not available,
  // e.g. PhantomJS, iOS7, Android 4.4
  // (#6466 MutationObserver is unreliable in IE11)
  var counter = 1;
  var observer = new MutationObserver(flushCallbacks);
  var textNode = document.createTextNode(String(counter));
  observer.observe(textNode, {
    characterData: true
  });
  timerFunc = function () {
    counter = (counter + 1) % 2;
    textNode.data = String(counter);
  };
  isUsingMicroTask = true;
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
  // Fallback to setImmediate.
  // Technically it leverages the (macro) task queue,
  // but it is still a better choice than setTimeout.
  timerFunc = function () {
    setImmediate(flushCallbacks);
  };
} else {
  // Fallback to setTimeout.
  timerFunc = function () {
    setTimeout(flushCallbacks, 0);
  };
}

function nextTick (cb, ctx) {
  var _resolve;
  callbacks.push(function () {
    if (cb) {
      try {
        cb.call(ctx);
      } catch (e) {
        handleError(e, ctx, 'nextTick');
      }
    } else if (_resolve) {
      _resolve(ctx);
    }
  });
  if (!pending) {
    pending = true;
    timerFunc();
  }
  // $flow-disable-line
  if (!cb && typeof Promise !== 'undefined') {
    return new Promise(function (resolve) {
      _resolve = resolve;
    })
  }
}

/*  */

var mark;
var measure;

{
  var perf = inBrowser && window.performance;
  /* istanbul ignore if */
  if (
    perf &&
    perf.mark &&
    perf.measure &&
    perf.clearMarks &&
    perf.clearMeasures
  ) {
    mark = function (tag) { return perf.mark(tag); };
    measure = function (name, startTag, endTag) {
      perf.measure(name, startTag, endTag);
      perf.clearMarks(startTag);
      perf.clearMarks(endTag);
      // perf.clearMeasures(name)
    };
  }
}

/* not type checking this file because flow doesn't play well with Proxy */

var initProxy;

{
  var allowedGlobals = makeMap(
    'Infinity,undefined,NaN,isFinite,isNaN,' +
    'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
    'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
    'require' // for Webpack/Browserify
  );

  var warnNonPresent = function (target, key) {
    warn(
      "Property or method \"" + key + "\" is not defined on the instance but " +
      'referenced during render. Make sure that this property is reactive, ' +
      'either in the data option, or for class-based components, by ' +
      'initializing the property. ' +
      'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
      target
    );
  };

  var warnReservedPrefix = function (target, key) {
    warn(
      "Property \"" + key + "\" must be accessed with \"$data." + key + "\" because " +
      'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
      'prevent conflicts with Vue internals. ' +
      'See: https://vuejs.org/v2/api/#data',
      target
    );
  };

  var hasProxy =
    typeof Proxy !== 'undefined' && isNative(Proxy);

  if (hasProxy) {
    var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact');
    config.keyCodes = new Proxy(config.keyCodes, {
      set: function set (target, key, value) {
        if (isBuiltInModifier(key)) {
          warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key));
          return false
        } else {
          target[key] = value;
          return true
        }
      }
    });
  }

  var hasHandler = {
    has: function has (target, key) {
      var has = key in target;
      var isAllowed = allowedGlobals(key) ||
        (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data));
      if (!has && !isAllowed) {
        if (key in target.$data) { warnReservedPrefix(target, key); }
        else { warnNonPresent(target, key); }
      }
      return has || !isAllowed
    }
  };

  var getHandler = {
    get: function get (target, key) {
      if (typeof key === 'string' && !(key in target)) {
        if (key in target.$data) { warnReservedPrefix(target, key); }
        else { warnNonPresent(target, key); }
      }
      return target[key]
    }
  };

  initProxy = function initProxy (vm) {
    if (hasProxy) {
      // determine which proxy handler to use
      var options = vm.$options;
      var handlers = options.render && options.render._withStripped
        ? getHandler
        : hasHandler;
      vm._renderProxy = new Proxy(vm, handlers);
    } else {
      vm._renderProxy = vm;
    }
  };
}

/*  */

var seenObjects = new _Set();

/**
 * Recursively traverse an object to evoke all converted
 * getters, so that every nested property inside the object
 * is collected as a "deep" dependency.
 */
function traverse (val) {
  _traverse(val, seenObjects);
  seenObjects.clear();
}

function _traverse (val, seen) {
  var i, keys;
  var isA = Array.isArray(val);
  if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
    return
  }
  if (val.__ob__) {
    var depId = val.__ob__.dep.id;
    if (seen.has(depId)) {
      return
    }
    seen.add(depId);
  }
  if (isA) {
    i = val.length;
    while (i--) { _traverse(val[i], seen); }
  } else {
    keys = Object.keys(val);
    i = keys.length;
    while (i--) { _traverse(val[keys[i]], seen); }
  }
}

/*  */

var normalizeEvent = cached(function (name) {
  var passive = name.charAt(0) === '&';
  name = passive ? name.slice(1) : name;
  var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first
  name = once$$1 ? name.slice(1) : name;
  var capture = name.charAt(0) === '!';
  name = capture ? name.slice(1) : name;
  return {
    name: name,
    once: once$$1,
    capture: capture,
    passive: passive
  }
});

function createFnInvoker (fns, vm) {
  function invoker () {
    var arguments$1 = arguments;

    var fns = invoker.fns;
    if (Array.isArray(fns)) {
      var cloned = fns.slice();
      for (var i = 0; i < cloned.length; i++) {
        invokeWithErrorHandling(cloned[i], null, arguments$1, vm, "v-on handler");
      }
    } else {
      // return handler return value for single handlers
      return invokeWithErrorHandling(fns, null, arguments, vm, "v-on handler")
    }
  }
  invoker.fns = fns;
  return invoker
}

function updateListeners (
  on,
  oldOn,
  add,
  remove$$1,
  createOnceHandler,
  vm
) {
  var name, def$$1, cur, old, event;
  for (name in on) {
    def$$1 = cur = on[name];
    old = oldOn[name];
    event = normalizeEvent(name);
    if (isUndef(cur)) {
      warn(
        "Invalid handler for event \"" + (event.name) + "\": got " + String(cur),
        vm
      );
    } else if (isUndef(old)) {
      if (isUndef(cur.fns)) {
        cur = on[name] = createFnInvoker(cur, vm);
      }
      if (isTrue(event.once)) {
        cur = on[name] = createOnceHandler(event.name, cur, event.capture);
      }
      add(event.name, cur, event.capture, event.passive, event.params);
    } else if (cur !== old) {
      old.fns = cur;
      on[name] = old;
    }
  }
  for (name in oldOn) {
    if (isUndef(on[name])) {
      event = normalizeEvent(name);
      remove$$1(event.name, oldOn[name], event.capture);
    }
  }
}

/*  */

function mergeVNodeHook (def, hookKey, hook) {
  if (def instanceof VNode) {
    def = def.data.hook || (def.data.hook = {});
  }
  var invoker;
  var oldHook = def[hookKey];

  function wrappedHook () {
    hook.apply(this, arguments);
    // important: remove merged hook to ensure it's called only once
    // and prevent memory leak
    remove(invoker.fns, wrappedHook);
  }

  if (isUndef(oldHook)) {
    // no existing hook
    invoker = createFnInvoker([wrappedHook]);
  } else {
    /* istanbul ignore if */
    if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
      // already a merged invoker
      invoker = oldHook;
      invoker.fns.push(wrappedHook);
    } else {
      // existing plain hook
      invoker = createFnInvoker([oldHook, wrappedHook]);
    }
  }

  invoker.merged = true;
  def[hookKey] = invoker;
}

/*  */

function extractPropsFromVNodeData (
  data,
  Ctor,
  tag
) {
  // we are only extracting raw values here.
  // validation and default values are handled in the child
  // component itself.
  var propOptions = Ctor.options.props;
  if (isUndef(propOptions)) {
    return
  }
  var res = {};
  var attrs = data.attrs;
  var props = data.props;
  if (isDef(attrs) || isDef(props)) {
    for (var key in propOptions) {
      var altKey = hyphenate(key);
      {
        var keyInLowerCase = key.toLowerCase();
        if (
          key !== keyInLowerCase &&
          attrs && hasOwn(attrs, keyInLowerCase)
        ) {
          tip(
            "Prop \"" + keyInLowerCase + "\" is passed to component " +
            (formatComponentName(tag || Ctor)) + ", but the declared prop name is" +
            " \"" + key + "\". " +
            "Note that HTML attributes are case-insensitive and camelCased " +
            "props need to use their kebab-case equivalents when using in-DOM " +
            "templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"."
          );
        }
      }
      checkProp(res, props, key, altKey, true) ||
      checkProp(res, attrs, key, altKey, false);
    }
  }
  return res
}

function checkProp (
  res,
  hash,
  key,
  altKey,
  preserve
) {
  if (isDef(hash)) {
    if (hasOwn(hash, key)) {
      res[key] = hash[key];
      if (!preserve) {
        delete hash[key];
      }
      return true
    } else if (hasOwn(hash, altKey)) {
      res[key] = hash[altKey];
      if (!preserve) {
        delete hash[altKey];
      }
      return true
    }
  }
  return false
}

/*  */

// The template compiler attempts to minimize the need for normalization by
// statically analyzing the template at compile time.
//
// For plain HTML markup, normalization can be completely skipped because the
// generated render function is guaranteed to return Array<VNode>. There are
// two cases where extra normalization is needed:

// 1. When the children contains components - because a functional component
// may return an Array instead of a single root. In this case, just a simple
// normalization is needed - if any child is an Array, we flatten the whole
// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
// because functional components already normalize their own children.
function simpleNormalizeChildren (children) {
  for (var i = 0; i < children.length; i++) {
    if (Array.isArray(children[i])) {
      return Array.prototype.concat.apply([], children)
    }
  }
  return children
}

// 2. When the children contains constructs that always generated nested Arrays,
// e.g. <template>, <slot>, v-for, or when the children is provided by user
// with hand-written render functions / JSX. In such cases a full normalization
// is needed to cater to all possible types of children values.
function normalizeChildren (children) {
  return isPrimitive(children)
    ? [createTextVNode(children)]
    : Array.isArray(children)
      ? normalizeArrayChildren(children)
      : undefined
}

function isTextNode (node) {
  return isDef(node) && isDef(node.text) && isFalse(node.isComment)
}

function normalizeArrayChildren (children, nestedIndex) {
  var res = [];
  var i, c, lastIndex, last;
  for (i = 0; i < children.length; i++) {
    c = children[i];
    if (isUndef(c) || typeof c === 'boolean') { continue }
    lastIndex = res.length - 1;
    last = res[lastIndex];
    //  nested
    if (Array.isArray(c)) {
      if (c.length > 0) {
        c = normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i));
        // merge adjacent text nodes
        if (isTextNode(c[0]) && isTextNode(last)) {
          res[lastIndex] = createTextVNode(last.text + (c[0]).text);
          c.shift();
        }
        res.push.apply(res, c);
      }
    } else if (isPrimitive(c)) {
      if (isTextNode(last)) {
        // merge adjacent text nodes
        // this is necessary for SSR hydration because text nodes are
        // essentially merged when rendered to HTML strings
        res[lastIndex] = createTextVNode(last.text + c);
      } else if (c !== '') {
        // convert primitive to vnode
        res.push(createTextVNode(c));
      }
    } else {
      if (isTextNode(c) && isTextNode(last)) {
        // merge adjacent text nodes
        res[lastIndex] = createTextVNode(last.text + c.text);
      } else {
        // default key for nested array children (likely generated by v-for)
        if (isTrue(children._isVList) &&
          isDef(c.tag) &&
          isUndef(c.key) &&
          isDef(nestedIndex)) {
          c.key = "__vlist" + nestedIndex + "_" + i + "__";
        }
        res.push(c);
      }
    }
  }
  return res
}

/*  */

function initProvide (vm) {
  var provide = vm.$options.provide;
  if (provide) {
    vm._provided = typeof provide === 'function'
      ? provide.call(vm)
      : provide;
  }
}

function initInjections (vm) {
  var result = resolveInject(vm.$options.inject, vm);
  if (result) {
    toggleObserving(false);
    Object.keys(result).forEach(function (key) {
      /* istanbul ignore else */
      {
        defineReactive$$1(vm, key, result[key], function () {
          warn(
            "Avoid mutating an injected value directly since the changes will be " +
            "overwritten whenever the provided component re-renders. " +
            "injection being mutated: \"" + key + "\"",
            vm
          );
        });
      }
    });
    toggleObserving(true);
  }
}

function resolveInject (inject, vm) {
  if (inject) {
    // inject is :any because flow is not smart enough to figure out cached
    var result = Object.create(null);
    var keys = hasSymbol
      ? Reflect.ownKeys(inject)
      : Object.keys(inject);

    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      // #6574 in case the inject object is observed...
      if (key === '__ob__') { continue }
      var provideKey = inject[key].from;
      var source = vm;
      while (source) {
        if (source._provided && hasOwn(source._provided, provideKey)) {
          result[key] = source._provided[provideKey];
          break
        }
        source = source.$parent;
      }
      if (!source) {
        if ('default' in inject[key]) {
          var provideDefault = inject[key].default;
          result[key] = typeof provideDefault === 'function'
            ? provideDefault.call(vm)
            : provideDefault;
        } else {
          warn(("Injection \"" + key + "\" not found"), vm);
        }
      }
    }
    return result
  }
}

/*  */



/**
 * Runtime helper for resolving raw children VNodes into a slot object.
 */
function resolveSlots (
  children,
  context
) {
  if (!children || !children.length) {
    return {}
  }
  var slots = {};
  for (var i = 0, l = children.length; i < l; i++) {
    var child = children[i];
    var data = child.data;
    // remove slot attribute if the node is resolved as a Vue slot node
    if (data && data.attrs && data.attrs.slot) {
      delete data.attrs.slot;
    }
    // named slots should only be respected if the vnode was rendered in the
    // same context.
    if ((child.context === context || child.fnContext === context) &&
      data && data.slot != null
    ) {
      var name = data.slot;
      var slot = (slots[name] || (slots[name] = []));
      if (child.tag === 'template') {
        slot.push.apply(slot, child.children || []);
      } else {
        slot.push(child);
      }
    } else {
      (slots.default || (slots.default = [])).push(child);
    }
  }
  // ignore slots that contains only whitespace
  for (var name$1 in slots) {
    if (slots[name$1].every(isWhitespace)) {
      delete slots[name$1];
    }
  }
  return slots
}

function isWhitespace (node) {
  return (node.isComment && !node.asyncFactory) || node.text === ' '
}

/*  */

function normalizeScopedSlots (
  slots,
  normalSlots,
  prevSlots
) {
  var res;
  var hasNormalSlots = Object.keys(normalSlots).length > 0;
  var isStable = slots ? !!slots.$stable : !hasNormalSlots;
  var key = slots && slots.$key;
  if (!slots) {
    res = {};
  } else if (slots._normalized) {
    // fast path 1: child component re-render only, parent did not change
    return slots._normalized
  } else if (
    isStable &&
    prevSlots &&
    prevSlots !== emptyObject &&
    key === prevSlots.$key &&
    !hasNormalSlots &&
    !prevSlots.$hasNormal
  ) {
    // fast path 2: stable scoped slots w/ no normal slots to proxy,
    // only need to normalize once
    return prevSlots
  } else {
    res = {};
    for (var key$1 in slots) {
      if (slots[key$1] && key$1[0] !== '$') {
        res[key$1] = normalizeScopedSlot(normalSlots, key$1, slots[key$1]);
      }
    }
  }
  // expose normal slots on scopedSlots
  for (var key$2 in normalSlots) {
    if (!(key$2 in res)) {
      res[key$2] = proxyNormalSlot(normalSlots, key$2);
    }
  }
  // avoriaz seems to mock a non-extensible $scopedSlots object
  // and when that is passed down this would cause an error
  if (slots && Object.isExtensible(slots)) {
    (slots)._normalized = res;
  }
  def(res, '$stable', isStable);
  def(res, '$key', key);
  def(res, '$hasNormal', hasNormalSlots);
  return res
}

function normalizeScopedSlot(normalSlots, key, fn) {
  var normalized = function () {
    var res = arguments.length ? fn.apply(null, arguments) : fn({});
    res = res && typeof res === 'object' && !Array.isArray(res)
      ? [res] // single vnode
      : normalizeChildren(res);
    return res && (
      res.length === 0 ||
      (res.length === 1 && res[0].isComment) // #9658
    ) ? undefined
      : res
  };
  // this is a slot using the new v-slot syntax without scope. although it is
  // compiled as a scoped slot, render fn users would expect it to be present
  // on this.$slots because the usage is semantically a normal slot.
  if (fn.proxy) {
    Object.defineProperty(normalSlots, key, {
      get: normalized,
      enumerable: true,
      configurable: true
    });
  }
  return normalized
}

function proxyNormalSlot(slots, key) {
  return function () { return slots[key]; }
}

/*  */

/**
 * Runtime helper for rendering v-for lists.
 */
function renderList (
  val,
  render
) {
  var ret, i, l, keys, key;
  if (Array.isArray(val) || typeof val === 'string') {
    ret = new Array(val.length);
    for (i = 0, l = val.length; i < l; i++) {
      ret[i] = render(val[i], i);
    }
  } else if (typeof val === 'number') {
    ret = new Array(val);
    for (i = 0; i < val; i++) {
      ret[i] = render(i + 1, i);
    }
  } else if (isObject(val)) {
    if (hasSymbol && val[Symbol.iterator]) {
      ret = [];
      var iterator = val[Symbol.iterator]();
      var result = iterator.next();
      while (!result.done) {
        ret.push(render(result.value, ret.length));
        result = iterator.next();
      }
    } else {
      keys = Object.keys(val);
      ret = new Array(keys.length);
      for (i = 0, l = keys.length; i < l; i++) {
        key = keys[i];
        ret[i] = render(val[key], key, i);
      }
    }
  }
  if (!isDef(ret)) {
    ret = [];
  }
  (ret)._isVList = true;
  return ret
}

/*  */

/**
 * Runtime helper for rendering <slot>
 */
function renderSlot (
  name,
  fallback,
  props,
  bindObject
) {
  var scopedSlotFn = this.$scopedSlots[name];
  var nodes;
  if (scopedSlotFn) { // scoped slot
    props = props || {};
    if (bindObject) {
      if (!isObject(bindObject)) {
        warn(
          'slot v-bind without argument expects an Object',
          this
        );
      }
      props = extend(extend({}, bindObject), props);
    }
    nodes = scopedSlotFn(props) || fallback;
  } else {
    nodes = this.$slots[name] || fallback;
  }

  var target = props && props.slot;
  if (target) {
    return this.$createElement('template', { slot: target }, nodes)
  } else {
    return nodes
  }
}

/*  */

/**
 * Runtime helper for resolving filters
 */
function resolveFilter (id) {
  return resolveAsset(this.$options, 'filters', id, true) || identity
}

/*  */

function isKeyNotMatch (expect, actual) {
  if (Array.isArray(expect)) {
    return expect.indexOf(actual) === -1
  } else {
    return expect !== actual
  }
}

/**
 * Runtime helper for checking keyCodes from config.
 * exposed as Vue.prototype._k
 * passing in eventKeyName as last argument separately for backwards compat
 */
function checkKeyCodes (
  eventKeyCode,
  key,
  builtInKeyCode,
  eventKeyName,
  builtInKeyName
) {
  var mappedKeyCode = config.keyCodes[key] || builtInKeyCode;
  if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
    return isKeyNotMatch(builtInKeyName, eventKeyName)
  } else if (mappedKeyCode) {
    return isKeyNotMatch(mappedKeyCode, eventKeyCode)
  } else if (eventKeyName) {
    return hyphenate(eventKeyName) !== key
  }
}

/*  */

/**
 * Runtime helper for merging v-bind="object" into a VNode's data.
 */
function bindObjectProps (
  data,
  tag,
  value,
  asProp,
  isSync
) {
  if (value) {
    if (!isObject(value)) {
      warn(
        'v-bind without argument expects an Object or Array value',
        this
      );
    } else {
      if (Array.isArray(value)) {
        value = toObject(value);
      }
      var hash;
      var loop = function ( key ) {
        if (
          key === 'class' ||
          key === 'style' ||
          isReservedAttribute(key)
        ) {
          hash = data;
        } else {
          var type = data.attrs && data.attrs.type;
          hash = asProp || config.mustUseProp(tag, type, key)
            ? data.domProps || (data.domProps = {})
            : data.attrs || (data.attrs = {});
        }
        var camelizedKey = camelize(key);
        var hyphenatedKey = hyphenate(key);
        if (!(camelizedKey in hash) && !(hyphenatedKey in hash)) {
          hash[key] = value[key];

          if (isSync) {
            var on = data.on || (data.on = {});
            on[("update:" + key)] = function ($event) {
              value[key] = $event;
            };
          }
        }
      };

      for (var key in value) loop( key );
    }
  }
  return data
}

/*  */

/**
 * Runtime helper for rendering static trees.
 */
function renderStatic (
  index,
  isInFor
) {
  var cached = this._staticTrees || (this._staticTrees = []);
  var tree = cached[index];
  // if has already-rendered static tree and not inside v-for,
  // we can reuse the same tree.
  if (tree && !isInFor) {
    return tree
  }
  // otherwise, render a fresh tree.
  tree = cached[index] = this.$options.staticRenderFns[index].call(
    this._renderProxy,
    null,
    this // for render fns generated for functional component templates
  );
  markStatic(tree, ("__static__" + index), false);
  return tree
}

/**
 * Runtime helper for v-once.
 * Effectively it means marking the node as static with a unique key.
 */
function markOnce (
  tree,
  index,
  key
) {
  markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true);
  return tree
}

function markStatic (
  tree,
  key,
  isOnce
) {
  if (Array.isArray(tree)) {
    for (var i = 0; i < tree.length; i++) {
      if (tree[i] && typeof tree[i] !== 'string') {
        markStaticNode(tree[i], (key + "_" + i), isOnce);
      }
    }
  } else {
    markStaticNode(tree, key, isOnce);
  }
}

function markStaticNode (node, key, isOnce) {
  node.isStatic = true;
  node.key = key;
  node.isOnce = isOnce;
}

/*  */

function bindObjectListeners (data, value) {
  if (value) {
    if (!isPlainObject(value)) {
      warn(
        'v-on without argument expects an Object value',
        this
      );
    } else {
      var on = data.on = data.on ? extend({}, data.on) : {};
      for (var key in value) {
        var existing = on[key];
        var ours = value[key];
        on[key] = existing ? [].concat(existing, ours) : ours;
      }
    }
  }
  return data
}

/*  */

function resolveScopedSlots (
  fns, // see flow/vnode
  res,
  // the following are added in 2.6
  hasDynamicKeys,
  contentHashKey
) {
  res = res || { $stable: !hasDynamicKeys };
  for (var i = 0; i < fns.length; i++) {
    var slot = fns[i];
    if (Array.isArray(slot)) {
      resolveScopedSlots(slot, res, hasDynamicKeys);
    } else if (slot) {
      // marker for reverse proxying v-slot without scope on this.$slots
      if (slot.proxy) {
        slot.fn.proxy = true;
      }
      res[slot.key] = slot.fn;
    }
  }
  if (contentHashKey) {
    (res).$key = contentHashKey;
  }
  return res
}

/*  */

function bindDynamicKeys (baseObj, values) {
  for (var i = 0; i < values.length; i += 2) {
    var key = values[i];
    if (typeof key === 'string' && key) {
      baseObj[values[i]] = values[i + 1];
    } else if (key !== '' && key !== null) {
      // null is a special value for explicitly removing a binding
      warn(
        ("Invalid value for dynamic directive argument (expected string or null): " + key),
        this
      );
    }
  }
  return baseObj
}

// helper to dynamically append modifier runtime markers to event names.
// ensure only append when value is already string, otherwise it will be cast
// to string and cause the type check to miss.
function prependModifier (value, symbol) {
  return typeof value === 'string' ? symbol + value : value
}

/*  */

function installRenderHelpers (target) {
  target._o = markOnce;
  target._n = toNumber;
  target._s = toString;
  target._l = renderList;
  target._t = renderSlot;
  target._q = looseEqual;
  target._i = looseIndexOf;
  target._m = renderStatic;
  target._f = resolveFilter;
  target._k = checkKeyCodes;
  target._b = bindObjectProps;
  target._v = createTextVNode;
  target._e = createEmptyVNode;
  target._u = resolveScopedSlots;
  target._g = bindObjectListeners;
  target._d = bindDynamicKeys;
  target._p = prependModifier;
}

/*  */

function FunctionalRenderContext (
  data,
  props,
  children,
  parent,
  Ctor
) {
  var this$1 = this;

  var options = Ctor.options;
  // ensure the createElement function in functional components
  // gets a unique context - this is necessary for correct named slot check
  var contextVm;
  if (hasOwn(parent, '_uid')) {
    contextVm = Object.create(parent);
    // $flow-disable-line
    contextVm._original = parent;
  } else {
    // the context vm passed in is a functional context as well.
    // in this case we want to make sure we are able to get a hold to the
    // real context instance.
    contextVm = parent;
    // $flow-disable-line
    parent = parent._original;
  }
  var isCompiled = isTrue(options._compiled);
  var needNormalization = !isCompiled;

  this.data = data;
  this.props = props;
  this.children = children;
  this.parent = parent;
  this.listeners = data.on || emptyObject;
  this.injections = resolveInject(options.inject, parent);
  this.slots = function () {
    if (!this$1.$slots) {
      normalizeScopedSlots(
        data.scopedSlots,
        this$1.$slots = resolveSlots(children, parent)
      );
    }
    return this$1.$slots
  };

  Object.defineProperty(this, 'scopedSlots', ({
    enumerable: true,
    get: function get () {
      return normalizeScopedSlots(data.scopedSlots, this.slots())
    }
  }));

  // support for compiled functional template
  if (isCompiled) {
    // exposing $options for renderStatic()
    this.$options = options;
    // pre-resolve slots for renderSlot()
    this.$slots = this.slots();
    this.$scopedSlots = normalizeScopedSlots(data.scopedSlots, this.$slots);
  }

  if (options._scopeId) {
    this._c = function (a, b, c, d) {
      var vnode = createElement(contextVm, a, b, c, d, needNormalization);
      if (vnode && !Array.isArray(vnode)) {
        vnode.fnScopeId = options._scopeId;
        vnode.fnContext = parent;
      }
      return vnode
    };
  } else {
    this._c = function (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); };
  }
}

installRenderHelpers(FunctionalRenderContext.prototype);

function createFunctionalComponent (
  Ctor,
  propsData,
  data,
  contextVm,
  children
) {
  var options = Ctor.options;
  var props = {};
  var propOptions = options.props;
  if (isDef(propOptions)) {
    for (var key in propOptions) {
      props[key] = validateProp(key, propOptions, propsData || emptyObject);
    }
  } else {
    if (isDef(data.attrs)) { mergeProps(props, data.attrs); }
    if (isDef(data.props)) { mergeProps(props, data.props); }
  }

  var renderContext = new FunctionalRenderContext(
    data,
    props,
    children,
    contextVm,
    Ctor
  );

  var vnode = options.render.call(null, renderContext._c, renderContext);

  if (vnode instanceof VNode) {
    return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext)
  } else if (Array.isArray(vnode)) {
    var vnodes = normalizeChildren(vnode) || [];
    var res = new Array(vnodes.length);
    for (var i = 0; i < vnodes.length; i++) {
      res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext);
    }
    return res
  }
}

function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) {
  // #7817 clone node before setting fnContext, otherwise if the node is reused
  // (e.g. it was from a cached normal slot) the fnContext causes named slots
  // that should not be matched to match.
  var clone = cloneVNode(vnode);
  clone.fnContext = contextVm;
  clone.fnOptions = options;
  {
    (clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext;
  }
  if (data.slot) {
    (clone.data || (clone.data = {})).slot = data.slot;
  }
  return clone
}

function mergeProps (to, from) {
  for (var key in from) {
    to[camelize(key)] = from[key];
  }
}

/*  */

/*  */

/*  */

/*  */

// inline hooks to be invoked on component VNodes during patch
var componentVNodeHooks = {
  init: function init (vnode, hydrating) {
    if (
      vnode.componentInstance &&
      !vnode.componentInstance._isDestroyed &&
      vnode.data.keepAlive
    ) {
      // kept-alive components, treat as a patch
      var mountedNode = vnode; // work around flow
      componentVNodeHooks.prepatch(mountedNode, mountedNode);
    } else {
      var child = vnode.componentInstance = createComponentInstanceForVnode(
        vnode,
        activeInstance
      );
      child.$mount(hydrating ? vnode.elm : undefined, hydrating);
    }
  },

  prepatch: function prepatch (oldVnode, vnode) {
    var options = vnode.componentOptions;
    var child = vnode.componentInstance = oldVnode.componentInstance;
    updateChildComponent(
      child,
      options.propsData, // updated props
      options.listeners, // updated listeners
      vnode, // new parent vnode
      options.children // new children
    );
  },

  insert: function insert (vnode) {
    var context = vnode.context;
    var componentInstance = vnode.componentInstance;
    if (!componentInstance._isMounted) {
      componentInstance._isMounted = true;
      callHook(componentInstance, 'mounted');
    }
    if (vnode.data.keepAlive) {
      if (context._isMounted) {
        // vue-router#1212
        // During updates, a kept-alive component's child components may
        // change, so directly walking the tree here may call activated hooks
        // on incorrect children. Instead we push them into a queue which will
        // be processed after the whole patch process ended.
        queueActivatedComponent(componentInstance);
      } else {
        activateChildComponent(componentInstance, true /* direct */);
      }
    }
  },

  destroy: function destroy (vnode) {
    var componentInstance = vnode.componentInstance;
    if (!componentInstance._isDestroyed) {
      if (!vnode.data.keepAlive) {
        componentInstance.$destroy();
      } else {
        deactivateChildComponent(componentInstance, true /* direct */);
      }
    }
  }
};

var hooksToMerge = Object.keys(componentVNodeHooks);

function createComponent (
  Ctor,
  data,
  context,
  children,
  tag
) {
  if (isUndef(Ctor)) {
    return
  }

  var baseCtor = context.$options._base;

  // plain options object: turn it into a constructor
  if (isObject(Ctor)) {
    Ctor = baseCtor.extend(Ctor);
  }

  // if at this stage it's not a constructor or an async component factory,
  // reject.
  if (typeof Ctor !== 'function') {
    {
      warn(("Invalid Component definition: " + (String(Ctor))), context);
    }
    return
  }

  // async component
  var asyncFactory;
  if (isUndef(Ctor.cid)) {
    asyncFactory = Ctor;
    Ctor = resolveAsyncComponent(asyncFactory, baseCtor);
    if (Ctor === undefined) {
      // return a placeholder node for async component, which is rendered
      // as a comment node but preserves all the raw information for the node.
      // the information will be used for async server-rendering and hydration.
      return createAsyncPlaceholder(
        asyncFactory,
        data,
        context,
        children,
        tag
      )
    }
  }

  data = data || {};

  // resolve constructor options in case global mixins are applied after
  // component constructor creation
  resolveConstructorOptions(Ctor);

  // transform component v-model data into props & events
  if (isDef(data.model)) {
    transformModel(Ctor.options, data);
  }

  // extract props
  var propsData = extractPropsFromVNodeData(data, Ctor, tag);

  // functional component
  if (isTrue(Ctor.options.functional)) {
    return createFunctionalComponent(Ctor, propsData, data, context, children)
  }

  // extract listeners, since these needs to be treated as
  // child component listeners instead of DOM listeners
  var listeners = data.on;
  // replace with listeners with .native modifier
  // so it gets processed during parent component patch.
  data.on = data.nativeOn;

  if (isTrue(Ctor.options.abstract)) {
    // abstract components do not keep anything
    // other than props & listeners & slot

    // work around flow
    var slot = data.slot;
    data = {};
    if (slot) {
      data.slot = slot;
    }
  }

  // install component management hooks onto the placeholder node
  installComponentHooks(data);

  // return a placeholder vnode
  var name = Ctor.options.name || tag;
  var vnode = new VNode(
    ("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')),
    data, undefined, undefined, undefined, context,
    { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children },
    asyncFactory
  );

  return vnode
}

function createComponentInstanceForVnode (
  vnode, // we know it's MountedComponentVNode but flow doesn't
  parent // activeInstance in lifecycle state
) {
  var options = {
    _isComponent: true,
    _parentVnode: vnode,
    parent: parent
  };
  // check inline-template render functions
  var inlineTemplate = vnode.data.inlineTemplate;
  if (isDef(inlineTemplate)) {
    options.render = inlineTemplate.render;
    options.staticRenderFns = inlineTemplate.staticRenderFns;
  }
  return new vnode.componentOptions.Ctor(options)
}

function installComponentHooks (data) {
  var hooks = data.hook || (data.hook = {});
  for (var i = 0; i < hooksToMerge.length; i++) {
    var key = hooksToMerge[i];
    var existing = hooks[key];
    var toMerge = componentVNodeHooks[key];
    if (existing !== toMerge && !(existing && existing._merged)) {
      hooks[key] = existing ? mergeHook$1(toMerge, existing) : toMerge;
    }
  }
}

function mergeHook$1 (f1, f2) {
  var merged = function (a, b) {
    // flow complains about extra args which is why we use any
    f1(a, b);
    f2(a, b);
  };
  merged._merged = true;
  return merged
}

// transform component v-model info (value and callback) into
// prop and event handler respectively.
function transformModel (options, data) {
  var prop = (options.model && options.model.prop) || 'value';
  var event = (options.model && options.model.event) || 'input'
  ;(data.attrs || (data.attrs = {}))[prop] = data.model.value;
  var on = data.on || (data.on = {});
  var existing = on[event];
  var callback = data.model.callback;
  if (isDef(existing)) {
    if (
      Array.isArray(existing)
        ? existing.indexOf(callback) === -1
        : existing !== callback
    ) {
      on[event] = [callback].concat(existing);
    }
  } else {
    on[event] = callback;
  }
}

/*  */

var SIMPLE_NORMALIZE = 1;
var ALWAYS_NORMALIZE = 2;

// wrapper function for providing a more flexible interface
// without getting yelled at by flow
function createElement (
  context,
  tag,
  data,
  children,
  normalizationType,
  alwaysNormalize
) {
  if (Array.isArray(data) || isPrimitive(data)) {
    normalizationType = children;
    children = data;
    data = undefined;
  }
  if (isTrue(alwaysNormalize)) {
    normalizationType = ALWAYS_NORMALIZE;
  }
  return _createElement(context, tag, data, children, normalizationType)
}

function _createElement (
  context,
  tag,
  data,
  children,
  normalizationType
) {
  if (isDef(data) && isDef((data).__ob__)) {
    warn(
      "Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" +
      'Always create fresh vnode data objects in each render!',
      context
    );
    return createEmptyVNode()
  }
  // object syntax in v-bind
  if (isDef(data) && isDef(data.is)) {
    tag = data.is;
  }
  if (!tag) {
    // in case of component :is set to falsy value
    return createEmptyVNode()
  }
  // warn against non-primitive key
  if (isDef(data) && isDef(data.key) && !isPrimitive(data.key)
  ) {
    {
      warn(
        'Avoid using non-primitive value as key, ' +
        'use string/number value instead.',
        context
      );
    }
  }
  // support single function children as default scoped slot
  if (Array.isArray(children) &&
    typeof children[0] === 'function'
  ) {
    data = data || {};
    data.scopedSlots = { default: children[0] };
    children.length = 0;
  }
  if (normalizationType === ALWAYS_NORMALIZE) {
    children = normalizeChildren(children);
  } else if (normalizationType === SIMPLE_NORMALIZE) {
    children = simpleNormalizeChildren(children);
  }
  var vnode, ns;
  if (typeof tag === 'string') {
    var Ctor;
    ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
    if (config.isReservedTag(tag)) {
      // platform built-in elements
      if (isDef(data) && isDef(data.nativeOn)) {
        warn(
          ("The .native modifier for v-on is only valid on components but it was used on <" + tag + ">."),
          context
        );
      }
      vnode = new VNode(
        config.parsePlatformTagName(tag), data, children,
        undefined, undefined, context
      );
    } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
      // component
      vnode = createComponent(Ctor, data, context, children, tag);
    } else {
      // unknown or unlisted namespaced elements
      // check at runtime because it may get assigned a namespace when its
      // parent normalizes children
      vnode = new VNode(
        tag, data, children,
        undefined, undefined, context
      );
    }
  } else {
    // direct component options / constructor
    vnode = createComponent(tag, data, context, children);
  }
  if (Array.isArray(vnode)) {
    return vnode
  } else if (isDef(vnode)) {
    if (isDef(ns)) { applyNS(vnode, ns); }
    if (isDef(data)) { registerDeepBindings(data); }
    return vnode
  } else {
    return createEmptyVNode()
  }
}

function applyNS (vnode, ns, force) {
  vnode.ns = ns;
  if (vnode.tag === 'foreignObject') {
    // use default namespace inside foreignObject
    ns = undefined;
    force = true;
  }
  if (isDef(vnode.children)) {
    for (var i = 0, l = vnode.children.length; i < l; i++) {
      var child = vnode.children[i];
      if (isDef(child.tag) && (
        isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {
        applyNS(child, ns, force);
      }
    }
  }
}

// ref #5318
// necessary to ensure parent re-render when deep bindings like :style and
// :class are used on slot nodes
function registerDeepBindings (data) {
  if (isObject(data.style)) {
    traverse(data.style);
  }
  if (isObject(data.class)) {
    traverse(data.class);
  }
}

/*  */

function initRender (vm) {
  vm._vnode = null; // the root of the child tree
  vm._staticTrees = null; // v-once cached trees
  var options = vm.$options;
  var parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree
  var renderContext = parentVnode && parentVnode.context;
  vm.$slots = resolveSlots(options._renderChildren, renderContext);
  vm.$scopedSlots = emptyObject;
  // bind the createElement fn to this instance
  // so that we get proper render context inside it.
  // args order: tag, data, children, normalizationType, alwaysNormalize
  // internal version is used by render functions compiled from templates
  vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); };
  // normalization is always applied for the public version, used in
  // user-written render functions.
  vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); };

  // $attrs & $listeners are exposed for easier HOC creation.
  // they need to be reactive so that HOCs using them are always updated
  var parentData = parentVnode && parentVnode.data;

  /* istanbul ignore else */
  {
    defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () {
      !isUpdatingChildComponent && warn("$attrs is readonly.", vm);
    }, true);
    defineReactive$$1(vm, '$listeners', options._parentListeners || emptyObject, function () {
      !isUpdatingChildComponent && warn("$listeners is readonly.", vm);
    }, true);
  }
}

var currentRenderingInstance = null;

function renderMixin (Vue) {
  // install runtime convenience helpers
  installRenderHelpers(Vue.prototype);

  Vue.prototype.$nextTick = function (fn) {
    return nextTick(fn, this)
  };

  Vue.prototype._render = function () {
    var vm = this;
    var ref = vm.$options;
    var render = ref.render;
    var _parentVnode = ref._parentVnode;

    if (_parentVnode) {
      vm.$scopedSlots = normalizeScopedSlots(
        _parentVnode.data.scopedSlots,
        vm.$slots,
        vm.$scopedSlots
      );
    }

    // set parent vnode. this allows render functions to have access
    // to the data on the placeholder node.
    vm.$vnode = _parentVnode;
    // render self
    var vnode;
    try {
      // There's no need to maintain a stack because all render fns are called
      // separately from one another. Nested component's render fns are called
      // when parent component is patched.
      currentRenderingInstance = vm;
      vnode = render.call(vm._renderProxy, vm.$createElement);
    } catch (e) {
      handleError(e, vm, "render");
      // return error render result,
      // or previous vnode to prevent render error causing blank component
      /* istanbul ignore else */
      if (vm.$options.renderError) {
        try {
          vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e);
        } catch (e) {
          handleError(e, vm, "renderError");
          vnode = vm._vnode;
        }
      } else {
        vnode = vm._vnode;
      }
    } finally {
      currentRenderingInstance = null;
    }
    // if the returned array contains only a single node, allow it
    if (Array.isArray(vnode) && vnode.length === 1) {
      vnode = vnode[0];
    }
    // return empty vnode in case the render function errored out
    if (!(vnode instanceof VNode)) {
      if (Array.isArray(vnode)) {
        warn(
          'Multiple root nodes returned from render function. Render function ' +
          'should return a single root node.',
          vm
        );
      }
      vnode = createEmptyVNode();
    }
    // set parent
    vnode.parent = _parentVnode;
    return vnode
  };
}

/*  */

function ensureCtor (comp, base) {
  if (
    comp.__esModule ||
    (hasSymbol && comp[Symbol.toStringTag] === 'Module')
  ) {
    comp = comp.default;
  }
  return isObject(comp)
    ? base.extend(comp)
    : comp
}

function createAsyncPlaceholder (
  factory,
  data,
  context,
  children,
  tag
) {
  var node = createEmptyVNode();
  node.asyncFactory = factory;
  node.asyncMeta = { data: data, context: context, children: children, tag: tag };
  return node
}

function resolveAsyncComponent (
  factory,
  baseCtor
) {
  if (isTrue(factory.error) && isDef(factory.errorComp)) {
    return factory.errorComp
  }

  if (isDef(factory.resolved)) {
    return factory.resolved
  }

  var owner = currentRenderingInstance;
  if (owner && isDef(factory.owners) && factory.owners.indexOf(owner) === -1) {
    // already pending
    factory.owners.push(owner);
  }

  if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
    return factory.loadingComp
  }

  if (owner && !isDef(factory.owners)) {
    var owners = factory.owners = [owner];
    var sync = true;
    var timerLoading = null;
    var timerTimeout = null

    ;(owner).$on('hook:destroyed', function () { return remove(owners, owner); });

    var forceRender = function (renderCompleted) {
      for (var i = 0, l = owners.length; i < l; i++) {
        (owners[i]).$forceUpdate();
      }

      if (renderCompleted) {
        owners.length = 0;
        if (timerLoading !== null) {
          clearTimeout(timerLoading);
          timerLoading = null;
        }
        if (timerTimeout !== null) {
          clearTimeout(timerTimeout);
          timerTimeout = null;
        }
      }
    };

    var resolve = once(function (res) {
      // cache resolved
      factory.resolved = ensureCtor(res, baseCtor);
      // invoke callbacks only if this is not a synchronous resolve
      // (async resolves are shimmed as synchronous during SSR)
      if (!sync) {
        forceRender(true);
      } else {
        owners.length = 0;
      }
    });

    var reject = once(function (reason) {
      warn(
        "Failed to resolve async component: " + (String(factory)) +
        (reason ? ("\nReason: " + reason) : '')
      );
      if (isDef(factory.errorComp)) {
        factory.error = true;
        forceRender(true);
      }
    });

    var res = factory(resolve, reject);

    if (isObject(res)) {
      if (isPromise(res)) {
        // () => Promise
        if (isUndef(factory.resolved)) {
          res.then(resolve, reject);
        }
      } else if (isPromise(res.component)) {
        res.component.then(resolve, reject);

        if (isDef(res.error)) {
          factory.errorComp = ensureCtor(res.error, baseCtor);
        }

        if (isDef(res.loading)) {
          factory.loadingComp = ensureCtor(res.loading, baseCtor);
          if (res.delay === 0) {
            factory.loading = true;
          } else {
            timerLoading = setTimeout(function () {
              timerLoading = null;
              if (isUndef(factory.resolved) && isUndef(factory.error)) {
                factory.loading = true;
                forceRender(false);
              }
            }, res.delay || 200);
          }
        }

        if (isDef(res.timeout)) {
          timerTimeout = setTimeout(function () {
            timerTimeout = null;
            if (isUndef(factory.resolved)) {
              reject(
                "timeout (" + (res.timeout) + "ms)"
              );
            }
          }, res.timeout);
        }
      }
    }

    sync = false;
    // return in case resolved synchronously
    return factory.loading
      ? factory.loadingComp
      : factory.resolved
  }
}

/*  */

function isAsyncPlaceholder (node) {
  return node.isComment && node.asyncFactory
}

/*  */

function getFirstComponentChild (children) {
  if (Array.isArray(children)) {
    for (var i = 0; i < children.length; i++) {
      var c = children[i];
      if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
        return c
      }
    }
  }
}

/*  */

/*  */

function initEvents (vm) {
  vm._events = Object.create(null);
  vm._hasHookEvent = false;
  // init parent attached events
  var listeners = vm.$options._parentListeners;
  if (listeners) {
    updateComponentListeners(vm, listeners);
  }
}

var target;

function add (event, fn) {
  target.$on(event, fn);
}

function remove$1 (event, fn) {
  target.$off(event, fn);
}

function createOnceHandler (event, fn) {
  var _target = target;
  return function onceHandler () {
    var res = fn.apply(null, arguments);
    if (res !== null) {
      _target.$off(event, onceHandler);
    }
  }
}

function updateComponentListeners (
  vm,
  listeners,
  oldListeners
) {
  target = vm;
  updateListeners(listeners, oldListeners || {}, add, remove$1, createOnceHandler, vm);
  target = undefined;
}

function eventsMixin (Vue) {
  var hookRE = /^hook:/;
  Vue.prototype.$on = function (event, fn) {
    var vm = this;
    if (Array.isArray(event)) {
      for (var i = 0, l = event.length; i < l; i++) {
        vm.$on(event[i], fn);
      }
    } else {
      (vm._events[event] || (vm._events[event] = [])).push(fn);
      // optimize hook:event cost by using a boolean flag marked at registration
      // instead of a hash lookup
      if (hookRE.test(event)) {
        vm._hasHookEvent = true;
      }
    }
    return vm
  };

  Vue.prototype.$once = function (event, fn) {
    var vm = this;
    function on () {
      vm.$off(event, on);
      fn.apply(vm, arguments);
    }
    on.fn = fn;
    vm.$on(event, on);
    return vm
  };

  Vue.prototype.$off = function (event, fn) {
    var vm = this;
    // all
    if (!arguments.length) {
      vm._events = Object.create(null);
      return vm
    }
    // array of events
    if (Array.isArray(event)) {
      for (var i$1 = 0, l = event.length; i$1 < l; i$1++) {
        vm.$off(event[i$1], fn);
      }
      return vm
    }
    // specific event
    var cbs = vm._events[event];
    if (!cbs) {
      return vm
    }
    if (!fn) {
      vm._events[event] = null;
      return vm
    }
    // specific handler
    var cb;
    var i = cbs.length;
    while (i--) {
      cb = cbs[i];
      if (cb === fn || cb.fn === fn) {
        cbs.splice(i, 1);
        break
      }
    }
    return vm
  };

  Vue.prototype.$emit = function (event) {
    var vm = this;
    {
      var lowerCaseEvent = event.toLowerCase();
      if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
        tip(
          "Event \"" + lowerCaseEvent + "\" is emitted in component " +
          (formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +
          "Note that HTML attributes are case-insensitive and you cannot use " +
          "v-on to listen to camelCase events when using in-DOM templates. " +
          "You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."
        );
      }
    }
    var cbs = vm._events[event];
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs;
      var args = toArray(arguments, 1);
      var info = "event handler for \"" + event + "\"";
      for (var i = 0, l = cbs.length; i < l; i++) {
        invokeWithErrorHandling(cbs[i], vm, args, vm, info);
      }
    }
    return vm
  };
}

/*  */

var activeInstance = null;
var isUpdatingChildComponent = false;

function setActiveInstance(vm) {
  var prevActiveInstance = activeInstance;
  activeInstance = vm;
  return function () {
    activeInstance = prevActiveInstance;
  }
}

function initLifecycle (vm) {
  var options = vm.$options;

  // locate first non-abstract parent
  var parent = options.parent;
  if (parent && !options.abstract) {
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent;
    }
    parent.$children.push(vm);
  }

  vm.$parent = parent;
  vm.$root = parent ? parent.$root : vm;

  vm.$children = [];
  vm.$refs = {};

  vm._watcher = null;
  vm._inactive = null;
  vm._directInactive = false;
  vm._isMounted = false;
  vm._isDestroyed = false;
  vm._isBeingDestroyed = false;
}

function lifecycleMixin (Vue) {
  Vue.prototype._update = function (vnode, hydrating) {
    var vm = this;
    var prevEl = vm.$el;
    var prevVnode = vm._vnode;
    var restoreActiveInstance = setActiveInstance(vm);
    vm._vnode = vnode;
    // Vue.prototype.__patch__ is injected in entry points
    // based on the rendering backend used.
    if (!prevVnode) {
      // initial render
      vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
    } else {
      // updates
      vm.$el = vm.__patch__(prevVnode, vnode);
    }
    restoreActiveInstance();
    // update __vue__ reference
    if (prevEl) {
      prevEl.__vue__ = null;
    }
    if (vm.$el) {
      vm.$el.__vue__ = vm;
    }
    // if parent is an HOC, update its $el as well
    if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
      vm.$parent.$el = vm.$el;
    }
    // updated hook is called by the scheduler to ensure that children are
    // updated in a parent's updated hook.
  };

  Vue.prototype.$forceUpdate = function () {
    var vm = this;
    if (vm._watcher) {
      vm._watcher.update();
    }
  };

  Vue.prototype.$destroy = function () {
    var vm = this;
    if (vm._isBeingDestroyed) {
      return
    }
    callHook(vm, 'beforeDestroy');
    vm._isBeingDestroyed = true;
    // remove self from parent
    var parent = vm.$parent;
    if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
      remove(parent.$children, vm);
    }
    // teardown watchers
    if (vm._watcher) {
      vm._watcher.teardown();
    }
    var i = vm._watchers.length;
    while (i--) {
      vm._watchers[i].teardown();
    }
    // remove reference from data ob
    // frozen object may not have observer.
    if (vm._data.__ob__) {
      vm._data.__ob__.vmCount--;
    }
    // call the last hook...
    vm._isDestroyed = true;
    // invoke destroy hooks on current rendered tree
    vm.__patch__(vm._vnode, null);
    // fire destroyed hook
    callHook(vm, 'destroyed');
    // turn off all instance listeners.
    vm.$off();
    // remove __vue__ reference
    if (vm.$el) {
      vm.$el.__vue__ = null;
    }
    // release circular reference (#6759)
    if (vm.$vnode) {
      vm.$vnode.parent = null;
    }
  };
}

function mountComponent (
  vm,
  el,
  hydrating
) {
  vm.$el = el;
  if (!vm.$options.render) {
    vm.$options.render = createEmptyVNode;
    {
      /* istanbul ignore if */
      if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
        vm.$options.el || el) {
        warn(
          'You are using the runtime-only build of Vue where the template ' +
          'compiler is not available. Either pre-compile the templates into ' +
          'render functions, or use the compiler-included build.',
          vm
        );
      } else {
        warn(
          'Failed to mount component: template or render function not defined.',
          vm
        );
      }
    }
  }
  callHook(vm, 'beforeMount');

  var updateComponent;
  /* istanbul ignore if */
  if (config.performance && mark) {
    updateComponent = function () {
      var name = vm._name;
      var id = vm._uid;
      var startTag = "vue-perf-start:" + id;
      var endTag = "vue-perf-end:" + id;

      mark(startTag);
      var vnode = vm._render();
      mark(endTag);
      measure(("vue " + name + " render"), startTag, endTag);

      mark(startTag);
      vm._update(vnode, hydrating);
      mark(endTag);
      measure(("vue " + name + " patch"), startTag, endTag);
    };
  } else {
    updateComponent = function () {
      vm._update(vm._render(), hydrating);
    };
  }

  // we set this to vm._watcher inside the watcher's constructor
  // since the watcher's initial patch may call $forceUpdate (e.g. inside child
  // component's mounted hook), which relies on vm._watcher being already defined
  new Watcher(vm, updateComponent, noop, {
    before: function before () {
      if (vm._isMounted && !vm._isDestroyed) {
        callHook(vm, 'beforeUpdate');
      }
    }
  }, true /* isRenderWatcher */);
  hydrating = false;

  // manually mounted instance, call mounted on self
  // mounted is called for render-created child components in its inserted hook
  if (vm.$vnode == null) {
    vm._isMounted = true;
    callHook(vm, 'mounted');
  }
  return vm
}

function updateChildComponent (
  vm,
  propsData,
  listeners,
  parentVnode,
  renderChildren
) {
  {
    isUpdatingChildComponent = true;
  }

  // determine whether component has slot children
  // we need to do this before overwriting $options._renderChildren.

  // check if there are dynamic scopedSlots (hand-written or compiled but with
  // dynamic slot names). Static scoped slots compiled from template has the
  // "$stable" marker.
  var newScopedSlots = parentVnode.data.scopedSlots;
  var oldScopedSlots = vm.$scopedSlots;
  var hasDynamicScopedSlot = !!(
    (newScopedSlots && !newScopedSlots.$stable) ||
    (oldScopedSlots !== emptyObject && !oldScopedSlots.$stable) ||
    (newScopedSlots && vm.$scopedSlots.$key !== newScopedSlots.$key)
  );

  // Any static slot children from the parent may have changed during parent's
  // update. Dynamic scoped slots may also have changed. In such cases, a forced
  // update is necessary to ensure correctness.
  var needsForceUpdate = !!(
    renderChildren ||               // has new static slots
    vm.$options._renderChildren ||  // has old static slots
    hasDynamicScopedSlot
  );

  vm.$options._parentVnode = parentVnode;
  vm.$vnode = parentVnode; // update vm's placeholder node without re-render

  if (vm._vnode) { // update child tree's parent
    vm._vnode.parent = parentVnode;
  }
  vm.$options._renderChildren = renderChildren;

  // update $attrs and $listeners hash
  // these are also reactive so they may trigger child update if the child
  // used them during render
  vm.$attrs = parentVnode.data.attrs || emptyObject;
  vm.$listeners = listeners || emptyObject;

  // update props
  if (propsData && vm.$options.props) {
    toggleObserving(false);
    var props = vm._props;
    var propKeys = vm.$options._propKeys || [];
    for (var i = 0; i < propKeys.length; i++) {
      var key = propKeys[i];
      var propOptions = vm.$options.props; // wtf flow?
      props[key] = validateProp(key, propOptions, propsData, vm);
    }
    toggleObserving(true);
    // keep a copy of raw propsData
    vm.$options.propsData = propsData;
  }

  // update listeners
  listeners = listeners || emptyObject;
  var oldListeners = vm.$options._parentListeners;
  vm.$options._parentListeners = listeners;
  updateComponentListeners(vm, listeners, oldListeners);

  // resolve slots + force update if has children
  if (needsForceUpdate) {
    vm.$slots = resolveSlots(renderChildren, parentVnode.context);
    vm.$forceUpdate();
  }

  {
    isUpdatingChildComponent = false;
  }
}

function isInInactiveTree (vm) {
  while (vm && (vm = vm.$parent)) {
    if (vm._inactive) { return true }
  }
  return false
}

function activateChildComponent (vm, direct) {
  if (direct) {
    vm._directInactive = false;
    if (isInInactiveTree(vm)) {
      return
    }
  } else if (vm._directInactive) {
    return
  }
  if (vm._inactive || vm._inactive === null) {
    vm._inactive = false;
    for (var i = 0; i < vm.$children.length; i++) {
      activateChildComponent(vm.$children[i]);
    }
    callHook(vm, 'activated');
  }
}

function deactivateChildComponent (vm, direct) {
  if (direct) {
    vm._directInactive = true;
    if (isInInactiveTree(vm)) {
      return
    }
  }
  if (!vm._inactive) {
    vm._inactive = true;
    for (var i = 0; i < vm.$children.length; i++) {
      deactivateChildComponent(vm.$children[i]);
    }
    callHook(vm, 'deactivated');
  }
}

function callHook (vm, hook) {
  // #7573 disable dep collection when invoking lifecycle hooks
  pushTarget();
  var handlers = vm.$options[hook];
  var info = hook + " hook";
  if (handlers) {
    for (var i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, null, vm, info);
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook);
  }
  popTarget();
}

/*  */

var MAX_UPDATE_COUNT = 100;

var queue = [];
var activatedChildren = [];
var has = {};
var circular = {};
var waiting = false;
var flushing = false;
var index = 0;

/**
 * Reset the scheduler's state.
 */
function resetSchedulerState () {
  index = queue.length = activatedChildren.length = 0;
  has = {};
  {
    circular = {};
  }
  waiting = flushing = false;
}

// Async edge case #6566 requires saving the timestamp when event listeners are
// attached. However, calling performance.now() has a perf overhead especially
// if the page has thousands of event listeners. Instead, we take a timestamp
// every time the scheduler flushes and use that for all event listeners
// attached during that flush.
var currentFlushTimestamp = 0;

// Async edge case fix requires storing an event listener's attach timestamp.
var getNow = Date.now;

// Determine what event timestamp the browser is using. Annoyingly, the
// timestamp can either be hi-res (relative to page load) or low-res
// (relative to UNIX epoch), so in order to compare time we have to use the
// same timestamp type when saving the flush timestamp.
// All IE versions use low-res event timestamps, and have problematic clock
// implementations (#9632)
if (inBrowser && !isIE) {
  var performance = window.performance;
  if (
    performance &&
    typeof performance.now === 'function' &&
    getNow() > document.createEvent('Event').timeStamp
  ) {
    // if the event timestamp, although evaluated AFTER the Date.now(), is
    // smaller than it, it means the event is using a hi-res timestamp,
    // and we need to use the hi-res version for event listener timestamps as
    // well.
    getNow = function () { return performance.now(); };
  }
}

/**
 * Flush both queues and run the watchers.
 */
function flushSchedulerQueue () {
  currentFlushTimestamp = getNow();
  flushing = true;
  var watcher, id;

  // Sort queue before flush.
  // This ensures that:
  // 1. Components are updated from parent to child. (because parent is always
  //    created before the child)
  // 2. A component's user watchers are run before its render watcher (because
  //    user watchers are created before the render watcher)
  // 3. If a component is destroyed during a parent component's watcher run,
  //    its watchers can be skipped.
  queue.sort(function (a, b) { return a.id - b.id; });

  // do not cache length because more watchers might be pushed
  // as we run existing watchers
  for (index = 0; index < queue.length; index++) {
    watcher = queue[index];
    if (watcher.before) {
      watcher.before();
    }
    id = watcher.id;
    has[id] = null;
    watcher.run();
    // in dev build, check and stop circular updates.
    if (has[id] != null) {
      circular[id] = (circular[id] || 0) + 1;
      if (circular[id] > MAX_UPDATE_COUNT) {
        warn(
          'You may have an infinite update loop ' + (
            watcher.user
              ? ("in watcher with expression \"" + (watcher.expression) + "\"")
              : "in a component render function."
          ),
          watcher.vm
        );
        break
      }
    }
  }

  // keep copies of post queues before resetting state
  var activatedQueue = activatedChildren.slice();
  var updatedQueue = queue.slice();

  resetSchedulerState();

  // call component updated and activated hooks
  callActivatedHooks(activatedQueue);
  callUpdatedHooks(updatedQueue);

  // devtool hook
  /* istanbul ignore if */
  if (devtools && config.devtools) {
    devtools.emit('flush');
  }
}

function callUpdatedHooks (queue) {
  var i = queue.length;
  while (i--) {
    var watcher = queue[i];
    var vm = watcher.vm;
    if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) {
      callHook(vm, 'updated');
    }
  }
}

/**
 * Queue a kept-alive component that was activated during patch.
 * The queue will be processed after the entire tree has been patched.
 */
function queueActivatedComponent (vm) {
  // setting _inactive to false here so that a render function can
  // rely on checking whether it's in an inactive tree (e.g. router-view)
  vm._inactive = false;
  activatedChildren.push(vm);
}

function callActivatedHooks (queue) {
  for (var i = 0; i < queue.length; i++) {
    queue[i]._inactive = true;
    activateChildComponent(queue[i], true /* true */);
  }
}

/**
 * Push a watcher into the watcher queue.
 * Jobs with duplicate IDs will be skipped unless it's
 * pushed when the queue is being flushed.
 */
function queueWatcher (watcher) {
  var id = watcher.id;
  if (has[id] == null) {
    has[id] = true;
    if (!flushing) {
      queue.push(watcher);
    } else {
      // if already flushing, splice the watcher based on its id
      // if already past its id, it will be run next immediately.
      var i = queue.length - 1;
      while (i > index && queue[i].id > watcher.id) {
        i--;
      }
      queue.splice(i + 1, 0, watcher);
    }
    // queue the flush
    if (!waiting) {
      waiting = true;

      if (!config.async) {
        flushSchedulerQueue();
        return
      }
      nextTick(flushSchedulerQueue);
    }
  }
}

/*  */



var uid$2 = 0;

/**
 * A watcher parses an expression, collects dependencies,
 * and fires callback when the expression value changes.
 * This is used for both the $watch() api and directives.
 */
var Watcher = function Watcher (
  vm,
  expOrFn,
  cb,
  options,
  isRenderWatcher
) {
  this.vm = vm;
  if (isRenderWatcher) {
    vm._watcher = this;
  }
  vm._watchers.push(this);
  // options
  if (options) {
    this.deep = !!options.deep;
    this.user = !!options.user;
    this.lazy = !!options.lazy;
    this.sync = !!options.sync;
    this.before = options.before;
  } else {
    this.deep = this.user = this.lazy = this.sync = false;
  }
  this.cb = cb;
  this.id = ++uid$2; // uid for batching
  this.active = true;
  this.dirty = this.lazy; // for lazy watchers
  this.deps = [];
  this.newDeps = [];
  this.depIds = new _Set();
  this.newDepIds = new _Set();
  this.expression = expOrFn.toString();
  // parse expression for getter
  if (typeof expOrFn === 'function') {
    this.getter = expOrFn;
  } else {
    this.getter = parsePath(expOrFn);
    if (!this.getter) {
      this.getter = noop;
      warn(
        "Failed watching path: \"" + expOrFn + "\" " +
        'Watcher only accepts simple dot-delimited paths. ' +
        'For full control, use a function instead.',
        vm
      );
    }
  }
  this.value = this.lazy
    ? undefined
    : this.get();
};

/**
 * Evaluate the getter, and re-collect dependencies.
 */
Watcher.prototype.get = function get () {
  pushTarget(this);
  var value;
  var vm = this.vm;
  try {
    value = this.getter.call(vm, vm);
  } catch (e) {
    if (this.user) {
      handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\""));
    } else {
      throw e
    }
  } finally {
    // "touch" every property so they are all tracked as
    // dependencies for deep watching
    if (this.deep) {
      traverse(value);
    }
    popTarget();
    this.cleanupDeps();
  }
  return value
};

/**
 * Add a dependency to this directive.
 */
Watcher.prototype.addDep = function addDep (dep) {
  var id = dep.id;
  if (!this.newDepIds.has(id)) {
    this.newDepIds.add(id);
    this.newDeps.push(dep);
    if (!this.depIds.has(id)) {
      dep.addSub(this);
    }
  }
};

/**
 * Clean up for dependency collection.
 */
Watcher.prototype.cleanupDeps = function cleanupDeps () {
  var i = this.deps.length;
  while (i--) {
    var dep = this.deps[i];
    if (!this.newDepIds.has(dep.id)) {
      dep.removeSub(this);
    }
  }
  var tmp = this.depIds;
  this.depIds = this.newDepIds;
  this.newDepIds = tmp;
  this.newDepIds.clear();
  tmp = this.deps;
  this.deps = this.newDeps;
  this.newDeps = tmp;
  this.newDeps.length = 0;
};

/**
 * Subscriber interface.
 * Will be called when a dependency changes.
 */
Watcher.prototype.update = function update () {
  /* istanbul ignore else */
  if (this.lazy) {
    this.dirty = true;
  } else if (this.sync) {
    this.run();
  } else {
    queueWatcher(this);
  }
};

/**
 * Scheduler job interface.
 * Will be called by the scheduler.
 */
Watcher.prototype.run = function run () {
  if (this.active) {
    var value = this.get();
    if (
      value !== this.value ||
      // Deep watchers and watchers on Object/Arrays should fire even
      // when the value is the same, because the value may
      // have mutated.
      isObject(value) ||
      this.deep
    ) {
      // set new value
      var oldValue = this.value;
      this.value = value;
      if (this.user) {
        try {
          this.cb.call(this.vm, value, oldValue);
        } catch (e) {
          handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\""));
        }
      } else {
        this.cb.call(this.vm, value, oldValue);
      }
    }
  }
};

/**
 * Evaluate the value of the watcher.
 * This only gets called for lazy watchers.
 */
Watcher.prototype.evaluate = function evaluate () {
  this.value = this.get();
  this.dirty = false;
};

/**
 * Depend on all deps collected by this watcher.
 */
Watcher.prototype.depend = function depend () {
  var i = this.deps.length;
  while (i--) {
    this.deps[i].depend();
  }
};

/**
 * Remove self from all dependencies' subscriber list.
 */
Watcher.prototype.teardown = function teardown () {
  if (this.active) {
    // remove self from vm's watcher list
    // this is a somewhat expensive operation so we skip it
    // if the vm is being destroyed.
    if (!this.vm._isBeingDestroyed) {
      remove(this.vm._watchers, this);
    }
    var i = this.deps.length;
    while (i--) {
      this.deps[i].removeSub(this);
    }
    this.active = false;
  }
};

/*  */

var sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: noop,
  set: noop
};

function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  };
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val;
  };
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

function initState (vm) {
  vm._watchers = [];
  var opts = vm.$options;
  if (opts.props) { initProps(vm, opts.props); }
  if (opts.methods) { initMethods(vm, opts.methods); }
  if (opts.data) {
    initData(vm);
  } else {
    observe(vm._data = {}, true /* asRootData */);
  }
  if (opts.computed) { initComputed(vm, opts.computed); }
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch);
  }
}

function initProps (vm, propsOptions) {
  var propsData = vm.$options.propsData || {};
  var props = vm._props = {};
  // cache prop keys so that future props updates can iterate using Array
  // instead of dynamic object key enumeration.
  var keys = vm.$options._propKeys = [];
  var isRoot = !vm.$parent;
  // root instance props should be converted
  if (!isRoot) {
    toggleObserving(false);
  }
  var loop = function ( key ) {
    keys.push(key);
    var value = validateProp(key, propsOptions, propsData, vm);
    /* istanbul ignore else */
    {
      var hyphenatedKey = hyphenate(key);
      if (isReservedAttribute(hyphenatedKey) ||
          config.isReservedAttr(hyphenatedKey)) {
        warn(
          ("\"" + hyphenatedKey + "\" is a reserved attribute and cannot be used as component prop."),
          vm
        );
      }
      defineReactive$$1(props, key, value, function () {
        if (!isRoot && !isUpdatingChildComponent) {
          warn(
            "Avoid mutating a prop directly since the value will be " +
            "overwritten whenever the parent component re-renders. " +
            "Instead, use a data or computed property based on the prop's " +
            "value. Prop being mutated: \"" + key + "\"",
            vm
          );
        }
      });
    }
    // static props are already proxied on the component's prototype
    // during Vue.extend(). We only need to proxy props defined at
    // instantiation here.
    if (!(key in vm)) {
      proxy(vm, "_props", key);
    }
  };

  for (var key in propsOptions) loop( key );
  toggleObserving(true);
}

function initData (vm) {
  var data = vm.$options.data;
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {};
  if (!isPlainObject(data)) {
    data = {};
    warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    );
  }
  // proxy data on instance
  var keys = Object.keys(data);
  var props = vm.$options.props;
  var methods = vm.$options.methods;
  var i = keys.length;
  while (i--) {
    var key = keys[i];
    {
      if (methods && hasOwn(methods, key)) {
        warn(
          ("Method \"" + key + "\" has already been defined as a data property."),
          vm
        );
      }
    }
    if (props && hasOwn(props, key)) {
      warn(
        "The data property \"" + key + "\" is already declared as a prop. " +
        "Use prop default value instead.",
        vm
      );
    } else if (!isReserved(key)) {
      proxy(vm, "_data", key);
    }
  }
  // observe data
  observe(data, true /* asRootData */);
}

function getData (data, vm) {
  // #7573 disable dep collection when invoking data getters
  pushTarget();
  try {
    return data.call(vm, vm)
  } catch (e) {
    handleError(e, vm, "data()");
    return {}
  } finally {
    popTarget();
  }
}

var computedWatcherOptions = { lazy: true };

function initComputed (vm, computed) {
  // $flow-disable-line
  var watchers = vm._computedWatchers = Object.create(null);
  // computed properties are just getters during SSR
  var isSSR = isServerRendering();

  for (var key in computed) {
    var userDef = computed[key];
    var getter = typeof userDef === 'function' ? userDef : userDef.get;
    if (getter == null) {
      warn(
        ("Getter is missing for computed property \"" + key + "\"."),
        vm
      );
    }

    if (!isSSR) {
      // create internal watcher for the computed property.
      watchers[key] = new Watcher(
        vm,
        getter || noop,
        noop,
        computedWatcherOptions
      );
    }

    // component-defined computed properties are already defined on the
    // component prototype. We only need to define computed properties defined
    // at instantiation here.
    if (!(key in vm)) {
      defineComputed(vm, key, userDef);
    } else {
      if (key in vm.$data) {
        warn(("The computed property \"" + key + "\" is already defined in data."), vm);
      } else if (vm.$options.props && key in vm.$options.props) {
        warn(("The computed property \"" + key + "\" is already defined as a prop."), vm);
      }
    }
  }
}

function defineComputed (
  target,
  key,
  userDef
) {
  var shouldCache = !isServerRendering();
  if (typeof userDef === 'function') {
    sharedPropertyDefinition.get = shouldCache
      ? createComputedGetter(key)
      : createGetterInvoker(userDef);
    sharedPropertyDefinition.set = noop;
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? shouldCache && userDef.cache !== false
        ? createComputedGetter(key)
        : createGetterInvoker(userDef.get)
      : noop;
    sharedPropertyDefinition.set = userDef.set || noop;
  }
  if (sharedPropertyDefinition.set === noop) {
    sharedPropertyDefinition.set = function () {
      warn(
        ("Computed property \"" + key + "\" was assigned to but it has no setter."),
        this
      );
    };
  }
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

function createComputedGetter (key) {
  return function computedGetter () {
    var watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate();
      }
      if (Dep.target) {
        watcher.depend();
      }
      return watcher.value
    }
  }
}

function createGetterInvoker(fn) {
  return function computedGetter () {
    return fn.call(this, this)
  }
}

function initMethods (vm, methods) {
  var props = vm.$options.props;
  for (var key in methods) {
    {
      if (typeof methods[key] !== 'function') {
        warn(
          "Method \"" + key + "\" has type \"" + (typeof methods[key]) + "\" in the component definition. " +
          "Did you reference the function correctly?",
          vm
        );
      }
      if (props && hasOwn(props, key)) {
        warn(
          ("Method \"" + key + "\" has already been defined as a prop."),
          vm
        );
      }
      if ((key in vm) && isReserved(key)) {
        warn(
          "Method \"" + key + "\" conflicts with an existing Vue instance method. " +
          "Avoid defining component methods that start with _ or $."
        );
      }
    }
    vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);
  }
}

function initWatch (vm, watch) {
  for (var key in watch) {
    var handler = watch[key];
    if (Array.isArray(handler)) {
      for (var i = 0; i < handler.length; i++) {
        createWatcher(vm, key, handler[i]);
      }
    } else {
      createWatcher(vm, key, handler);
    }
  }
}

function createWatcher (
  vm,
  expOrFn,
  handler,
  options
) {
  if (isPlainObject(handler)) {
    options = handler;
    handler = handler.handler;
  }
  if (typeof handler === 'string') {
    handler = vm[handler];
  }
  return vm.$watch(expOrFn, handler, options)
}

function stateMixin (Vue) {
  // flow somehow has problems with directly declared definition object
  // when using Object.defineProperty, so we have to procedurally build up
  // the object here.
  var dataDef = {};
  dataDef.get = function () { return this._data };
  var propsDef = {};
  propsDef.get = function () { return this._props };
  {
    dataDef.set = function () {
      warn(
        'Avoid replacing instance root $data. ' +
        'Use nested data properties instead.',
        this
      );
    };
    propsDef.set = function () {
      warn("$props is readonly.", this);
    };
  }
  Object.defineProperty(Vue.prototype, '$data', dataDef);
  Object.defineProperty(Vue.prototype, '$props', propsDef);

  Vue.prototype.$set = set;
  Vue.prototype.$delete = del;

  Vue.prototype.$watch = function (
    expOrFn,
    cb,
    options
  ) {
    var vm = this;
    if (isPlainObject(cb)) {
      return createWatcher(vm, expOrFn, cb, options)
    }
    options = options || {};
    options.user = true;
    var watcher = new Watcher(vm, expOrFn, cb, options);
    if (options.immediate) {
      try {
        cb.call(vm, watcher.value);
      } catch (error) {
        handleError(error, vm, ("callback for immediate watcher \"" + (watcher.expression) + "\""));
      }
    }
    return function unwatchFn () {
      watcher.teardown();
    }
  };
}

/*  */

var uid$3 = 0;

function initMixin (Vue) {
  Vue.prototype._init = function (options) {
    var vm = this;
    // a uid
    vm._uid = uid$3++;

    var startTag, endTag;
    /* istanbul ignore if */
    if (config.performance && mark) {
      startTag = "vue-perf-start:" + (vm._uid);
      endTag = "vue-perf-end:" + (vm._uid);
      mark(startTag);
    }

    // a flag to avoid this being observed
    vm._isVue = true;
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options);
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      );
    }
    /* istanbul ignore else */
    {
      initProxy(vm);
    }
    // expose real self
    vm._self = vm;
    initLifecycle(vm);
    initEvents(vm);
    initRender(vm);
    callHook(vm, 'beforeCreate');
    initInjections(vm); // resolve injections before data/props
    initState(vm);
    initProvide(vm); // resolve provide after data/props
    callHook(vm, 'created');

    /* istanbul ignore if */
    if (config.performance && mark) {
      vm._name = formatComponentName(vm, false);
      mark(endTag);
      measure(("vue " + (vm._name) + " init"), startTag, endTag);
    }

    if (vm.$options.el) {
      vm.$mount(vm.$options.el);
    }
  };
}

function initInternalComponent (vm, options) {
  var opts = vm.$options = Object.create(vm.constructor.options);
  // doing this because it's faster than dynamic enumeration.
  var parentVnode = options._parentVnode;
  opts.parent = options.parent;
  opts._parentVnode = parentVnode;

  var vnodeComponentOptions = parentVnode.componentOptions;
  opts.propsData = vnodeComponentOptions.propsData;
  opts._parentListeners = vnodeComponentOptions.listeners;
  opts._renderChildren = vnodeComponentOptions.children;
  opts._componentTag = vnodeComponentOptions.tag;

  if (options.render) {
    opts.render = options.render;
    opts.staticRenderFns = options.staticRenderFns;
  }
}

function resolveConstructorOptions (Ctor) {
  var options = Ctor.options;
  if (Ctor.super) {
    var superOptions = resolveConstructorOptions(Ctor.super);
    var cachedSuperOptions = Ctor.superOptions;
    if (superOptions !== cachedSuperOptions) {
      // super option changed,
      // need to resolve new options.
      Ctor.superOptions = superOptions;
      // check if there are any late-modified/attached options (#4976)
      var modifiedOptions = resolveModifiedOptions(Ctor);
      // update base extend options
      if (modifiedOptions) {
        extend(Ctor.extendOptions, modifiedOptions);
      }
      options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);
      if (options.name) {
        options.components[options.name] = Ctor;
      }
    }
  }
  return options
}

function resolveModifiedOptions (Ctor) {
  var modified;
  var latest = Ctor.options;
  var sealed = Ctor.sealedOptions;
  for (var key in latest) {
    if (latest[key] !== sealed[key]) {
      if (!modified) { modified = {}; }
      modified[key] = latest[key];
    }
  }
  return modified
}

function Vue (options) {
  if (!(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword');
  }
  this._init(options);
}

initMixin(Vue);
stateMixin(Vue);
eventsMixin(Vue);
lifecycleMixin(Vue);
renderMixin(Vue);

/*  */

function initUse (Vue) {
  Vue.use = function (plugin) {
    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    var args = toArray(arguments, 1);
    args.unshift(this);
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);
    }
    installedPlugins.push(plugin);
    return this
  };
}

/*  */

function initMixin$1 (Vue) {
  Vue.mixin = function (mixin) {
    this.options = mergeOptions(this.options, mixin);
    return this
  };
}

/*  */

function initExtend (Vue) {
  /**
   * Each instance constructor, including Vue, has a unique
   * cid. This enables us to create wrapped "child
   * constructors" for prototypal inheritance and cache them.
   */
  Vue.cid = 0;
  var cid = 1;

  /**
   * Class inheritance
   */
  Vue.extend = function (extendOptions) {
    extendOptions = extendOptions || {};
    var Super = this;
    var SuperId = Super.cid;
    var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
    if (cachedCtors[SuperId]) {
      return cachedCtors[SuperId]
    }

    var name = extendOptions.name || Super.options.name;
    if (name) {
      validateComponentName(name);
    }

    var Sub = function VueComponent (options) {
      this._init(options);
    };
    Sub.prototype = Object.create(Super.prototype);
    Sub.prototype.constructor = Sub;
    Sub.cid = cid++;
    Sub.options = mergeOptions(
      Super.options,
      extendOptions
    );
    Sub['super'] = Super;

    // For props and computed properties, we define the proxy getters on
    // the Vue instances at extension time, on the extended prototype. This
    // avoids Object.defineProperty calls for each instance created.
    if (Sub.options.props) {
      initProps$1(Sub);
    }
    if (Sub.options.computed) {
      initComputed$1(Sub);
    }

    // allow further extension/mixin/plugin usage
    Sub.extend = Super.extend;
    Sub.mixin = Super.mixin;
    Sub.use = Super.use;

    // create asset registers, so extended classes
    // can have their private assets too.
    ASSET_TYPES.forEach(function (type) {
      Sub[type] = Super[type];
    });
    // enable recursive self-lookup
    if (name) {
      Sub.options.components[name] = Sub;
    }

    // keep a reference to the super options at extension time.
    // later at instantiation we can check if Super's options have
    // been updated.
    Sub.superOptions = Super.options;
    Sub.extendOptions = extendOptions;
    Sub.sealedOptions = extend({}, Sub.options);

    // cache constructor
    cachedCtors[SuperId] = Sub;
    return Sub
  };
}

function initProps$1 (Comp) {
  var props = Comp.options.props;
  for (var key in props) {
    proxy(Comp.prototype, "_props", key);
  }
}

function initComputed$1 (Comp) {
  var computed = Comp.options.computed;
  for (var key in computed) {
    defineComputed(Comp.prototype, key, computed[key]);
  }
}

/*  */

function initAssetRegisters (Vue) {
  /**
   * Create asset registration methods.
   */
  ASSET_TYPES.forEach(function (type) {
    Vue[type] = function (
      id,
      definition
    ) {
      if (!definition) {
        return this.options[type + 's'][id]
      } else {
        /* istanbul ignore if */
        if (type === 'component') {
          validateComponentName(id);
        }
        if (type === 'component' && isPlainObject(definition)) {
          definition.name = definition.name || id;
          definition = this.options._base.extend(definition);
        }
        if (type === 'directive' && typeof definition === 'function') {
          definition = { bind: definition, update: definition };
        }
        this.options[type + 's'][id] = definition;
        return definition
      }
    };
  });
}

/*  */



function getComponentName (opts) {
  return opts && (opts.Ctor.options.name || opts.tag)
}

function matches (pattern, name) {
  if (Array.isArray(pattern)) {
    return pattern.indexOf(name) > -1
  } else if (typeof pattern === 'string') {
    return pattern.split(',').indexOf(name) > -1
  } else if (isRegExp(pattern)) {
    return pattern.test(name)
  }
  /* istanbul ignore next */
  return false
}

function pruneCache (keepAliveInstance, filter) {
  var cache = keepAliveInstance.cache;
  var keys = keepAliveInstance.keys;
  var _vnode = keepAliveInstance._vnode;
  for (var key in cache) {
    var cachedNode = cache[key];
    if (cachedNode) {
      var name = getComponentName(cachedNode.componentOptions);
      if (name && !filter(name)) {
        pruneCacheEntry(cache, key, keys, _vnode);
      }
    }
  }
}

function pruneCacheEntry (
  cache,
  key,
  keys,
  current
) {
  var cached$$1 = cache[key];
  if (cached$$1 && (!current || cached$$1.tag !== current.tag)) {
    cached$$1.componentInstance.$destroy();
  }
  cache[key] = null;
  remove(keys, key);
}

var patternTypes = [String, RegExp, Array];

var KeepAlive = {
  name: 'keep-alive',
  abstract: true,

  props: {
    include: patternTypes,
    exclude: patternTypes,
    max: [String, Number]
  },

  created: function created () {
    this.cache = Object.create(null);
    this.keys = [];
  },

  destroyed: function destroyed () {
    for (var key in this.cache) {
      pruneCacheEntry(this.cache, key, this.keys);
    }
  },

  mounted: function mounted () {
    var this$1 = this;

    this.$watch('include', function (val) {
      pruneCache(this$1, function (name) { return matches(val, name); });
    });
    this.$watch('exclude', function (val) {
      pruneCache(this$1, function (name) { return !matches(val, name); });
    });
  },

  render: function render () {
    var slot = this.$slots.default;
    var vnode = getFirstComponentChild(slot);
    var componentOptions = vnode && vnode.componentOptions;
    if (componentOptions) {
      // check pattern
      var name = getComponentName(componentOptions);
      var ref = this;
      var include = ref.include;
      var exclude = ref.exclude;
      if (
        // not included
        (include && (!name || !matches(include, name))) ||
        // excluded
        (exclude && name && matches(exclude, name))
      ) {
        return vnode
      }

      var ref$1 = this;
      var cache = ref$1.cache;
      var keys = ref$1.keys;
      var key = vnode.key == null
        // same constructor may get registered as different local components
        // so cid alone is not enough (#3269)
        ? componentOptions.Ctor.cid + (componentOptions.tag ? ("::" + (componentOptions.tag)) : '')
        : vnode.key;
      if (cache[key]) {
        vnode.componentInstance = cache[key].componentInstance;
        // make current key freshest
        remove(keys, key);
        keys.push(key);
      } else {
        cache[key] = vnode;
        keys.push(key);
        // prune oldest entry
        if (this.max && keys.length > parseInt(this.max)) {
          pruneCacheEntry(cache, keys[0], keys, this._vnode);
        }
      }

      vnode.data.keepAlive = true;
    }
    return vnode || (slot && slot[0])
  }
};

var builtInComponents = {
  KeepAlive: KeepAlive
};

/*  */

function initGlobalAPI (Vue) {
  // config
  var configDef = {};
  configDef.get = function () { return config; };
  {
    configDef.set = function () {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      );
    };
  }
  Object.defineProperty(Vue, 'config', configDef);

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  Vue.util = {
    warn: warn,
    extend: extend,
    mergeOptions: mergeOptions,
    defineReactive: defineReactive$$1
  };

  Vue.set = set;
  Vue.delete = del;
  Vue.nextTick = nextTick;

  // 2.6 explicit observable API
  Vue.observable = function (obj) {
    observe(obj);
    return obj
  };

  Vue.options = Object.create(null);
  ASSET_TYPES.forEach(function (type) {
    Vue.options[type + 's'] = Object.create(null);
  });

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue;

  extend(Vue.options.components, builtInComponents);

  initUse(Vue);
  initMixin$1(Vue);
  initExtend(Vue);
  initAssetRegisters(Vue);
}

initGlobalAPI(Vue);

Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
});

Object.defineProperty(Vue.prototype, '$ssrContext', {
  get: function get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
});

// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
});

Vue.version = '2.6.12';

/*  */

// these are reserved for web because they are directly compiled away
// during template compilation
var isReservedAttr = makeMap('style,class');

// attributes that should be using props for binding
var acceptValue = makeMap('input,textarea,option,select,progress');
var mustUseProp = function (tag, type, attr) {
  return (
    (attr === 'value' && acceptValue(tag)) && type !== 'button' ||
    (attr === 'selected' && tag === 'option') ||
    (attr === 'checked' && tag === 'input') ||
    (attr === 'muted' && tag === 'video')
  )
};

var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');

var isValidContentEditableValue = makeMap('events,caret,typing,plaintext-only');

var convertEnumeratedValue = function (key, value) {
  return isFalsyAttrValue(value) || value === 'false'
    ? 'false'
    // allow arbitrary string value for contenteditable
    : key === 'contenteditable' && isValidContentEditableValue(value)
      ? value
      : 'true'
};

var isBooleanAttr = makeMap(
  'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
  'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
  'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
  'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
  'required,reversed,scoped,seamless,selected,sortable,translate,' +
  'truespeed,typemustmatch,visible'
);

var xlinkNS = 'http://www.w3.org/1999/xlink';

var isXlink = function (name) {
  return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
};

var getXlinkProp = function (name) {
  return isXlink(name) ? name.slice(6, name.length) : ''
};

var isFalsyAttrValue = function (val) {
  return val == null || val === false
};

/*  */

function genClassForVnode (vnode) {
  var data = vnode.data;
  var parentNode = vnode;
  var childNode = vnode;
  while (isDef(childNode.componentInstance)) {
    childNode = childNode.componentInstance._vnode;
    if (childNode && childNode.data) {
      data = mergeClassData(childNode.data, data);
    }
  }
  while (isDef(parentNode = parentNode.parent)) {
    if (parentNode && parentNode.data) {
      data = mergeClassData(data, parentNode.data);
    }
  }
  return renderClass(data.staticClass, data.class)
}

function mergeClassData (child, parent) {
  return {
    staticClass: concat(child.staticClass, parent.staticClass),
    class: isDef(child.class)
      ? [child.class, parent.class]
      : parent.class
  }
}

function renderClass (
  staticClass,
  dynamicClass
) {
  if (isDef(staticClass) || isDef(dynamicClass)) {
    return concat(staticClass, stringifyClass(dynamicClass))
  }
  /* istanbul ignore next */
  return ''
}

function concat (a, b) {
  return a ? b ? (a + ' ' + b) : a : (b || '')
}

function stringifyClass (value) {
  if (Array.isArray(value)) {
    return stringifyArray(value)
  }
  if (isObject(value)) {
    return stringifyObject(value)
  }
  if (typeof value === 'string') {
    return value
  }
  /* istanbul ignore next */
  return ''
}

function stringifyArray (value) {
  var res = '';
  var stringified;
  for (var i = 0, l = value.length; i < l; i++) {
    if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {
      if (res) { res += ' '; }
      res += stringified;
    }
  }
  return res
}

function stringifyObject (value) {
  var res = '';
  for (var key in value) {
    if (value[key]) {
      if (res) { res += ' '; }
      res += key;
    }
  }
  return res
}

/*  */

var namespaceMap = {
  svg: 'http://www.w3.org/2000/svg',
  math: 'http://www.w3.org/1998/Math/MathML'
};

var isHTMLTag = makeMap(
  'html,body,base,head,link,meta,style,title,' +
  'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
  'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
  'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
  's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
  'embed,object,param,source,canvas,script,noscript,del,ins,' +
  'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
  'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
  'output,progress,select,textarea,' +
  'details,dialog,menu,menuitem,summary,' +
  'content,element,shadow,template,blockquote,iframe,tfoot'
);

// this map is intentionally selective, only covering SVG elements that may
// contain child elements.
var isSVG = makeMap(
  'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
  'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
  'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
  true
);

var isPreTag = function (tag) { return tag === 'pre'; };

var isReservedTag = function (tag) {
  return isHTMLTag(tag) || isSVG(tag)
};

function getTagNamespace (tag) {
  if (isSVG(tag)) {
    return 'svg'
  }
  // basic support for MathML
  // note it doesn't support other MathML elements being component roots
  if (tag === 'math') {
    return 'math'
  }
}

var unknownElementCache = Object.create(null);
function isUnknownElement (tag) {
  /* istanbul ignore if */
  if (!inBrowser) {
    return true
  }
  if (isReservedTag(tag)) {
    return false
  }
  tag = tag.toLowerCase();
  /* istanbul ignore if */
  if (unknownElementCache[tag] != null) {
    return unknownElementCache[tag]
  }
  var el = document.createElement(tag);
  if (tag.indexOf('-') > -1) {
    // http://stackoverflow.com/a/28210364/1070244
    return (unknownElementCache[tag] = (
      el.constructor === window.HTMLUnknownElement ||
      el.constructor === window.HTMLElement
    ))
  } else {
    return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))
  }
}

var isTextInputType = makeMap('text,number,password,search,email,tel,url');

/*  */

/**
 * Query an element selector if it's not an element already.
 */
function query (el) {
  if (typeof el === 'string') {
    var selected = document.querySelector(el);
    if (!selected) {
      warn(
        'Cannot find element: ' + el
      );
      return document.createElement('div')
    }
    return selected
  } else {
    return el
  }
}

/*  */

function createElement$1 (tagName, vnode) {
  var elm = document.createElement(tagName);
  if (tagName !== 'select') {
    return elm
  }
  // false or null will remove the attribute but undefined will not
  if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) {
    elm.setAttribute('multiple', 'multiple');
  }
  return elm
}

function createElementNS (namespace, tagName) {
  return document.createElementNS(namespaceMap[namespace], tagName)
}

function createTextNode (text) {
  return document.createTextNode(text)
}

function createComment (text) {
  return document.createComment(text)
}

function insertBefore (parentNode, newNode, referenceNode) {
  parentNode.insertBefore(newNode, referenceNode);
}

function removeChild (node, child) {
  node.removeChild(child);
}

function appendChild (node, child) {
  node.appendChild(child);
}

function parentNode (node) {
  return node.parentNode
}

function nextSibling (node) {
  return node.nextSibling
}

function tagName (node) {
  return node.tagName
}

function setTextContent (node, text) {
  node.textContent = text;
}

function setStyleScope (node, scopeId) {
  node.setAttribute(scopeId, '');
}

var nodeOps = /*#__PURE__*/Object.freeze({
  createElement: createElement$1,
  createElementNS: createElementNS,
  createTextNode: createTextNode,
  createComment: createComment,
  insertBefore: insertBefore,
  removeChild: removeChild,
  appendChild: appendChild,
  parentNode: parentNode,
  nextSibling: nextSibling,
  tagName: tagName,
  setTextContent: setTextContent,
  setStyleScope: setStyleScope
});

/*  */

var ref = {
  create: function create (_, vnode) {
    registerRef(vnode);
  },
  update: function update (oldVnode, vnode) {
    if (oldVnode.data.ref !== vnode.data.ref) {
      registerRef(oldVnode, true);
      registerRef(vnode);
    }
  },
  destroy: function destroy (vnode) {
    registerRef(vnode, true);
  }
};

function registerRef (vnode, isRemoval) {
  var key = vnode.data.ref;
  if (!isDef(key)) { return }

  var vm = vnode.context;
  var ref = vnode.componentInstance || vnode.elm;
  var refs = vm.$refs;
  if (isRemoval) {
    if (Array.isArray(refs[key])) {
      remove(refs[key], ref);
    } else if (refs[key] === ref) {
      refs[key] = undefined;
    }
  } else {
    if (vnode.data.refInFor) {
      if (!Array.isArray(refs[key])) {
        refs[key] = [ref];
      } else if (refs[key].indexOf(ref) < 0) {
        // $flow-disable-line
        refs[key].push(ref);
      }
    } else {
      refs[key] = ref;
    }
  }
}

/**
 * Virtual DOM patching algorithm based on Snabbdom by
 * Simon Friis Vindum (@paldepind)
 * Licensed under the MIT License
 * https://github.com/paldepind/snabbdom/blob/master/LICENSE
 *
 * modified by Evan You (@yyx990803)
 *
 * Not type-checking this because this file is perf-critical and the cost
 * of making flow understand it is not worth it.
 */

var emptyNode = new VNode('', {}, []);

var hooks = ['create', 'activate', 'update', 'remove', 'destroy'];

function sameVnode (a, b) {
  return (
    a.key === b.key && (
      (
        a.tag === b.tag &&
        a.isComment === b.isComment &&
        isDef(a.data) === isDef(b.data) &&
        sameInputType(a, b)
      ) || (
        isTrue(a.isAsyncPlaceholder) &&
        a.asyncFactory === b.asyncFactory &&
        isUndef(b.asyncFactory.error)
      )
    )
  )
}

function sameInputType (a, b) {
  if (a.tag !== 'input') { return true }
  var i;
  var typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;
  var typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;
  return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
}

function createKeyToOldIdx (children, beginIdx, endIdx) {
  var i, key;
  var map = {};
  for (i = beginIdx; i <= endIdx; ++i) {
    key = children[i].key;
    if (isDef(key)) { map[key] = i; }
  }
  return map
}

function createPatchFunction (backend) {
  var i, j;
  var cbs = {};

  var modules = backend.modules;
  var nodeOps = backend.nodeOps;

  for (i = 0; i < hooks.length; ++i) {
    cbs[hooks[i]] = [];
    for (j = 0; j < modules.length; ++j) {
      if (isDef(modules[j][hooks[i]])) {
        cbs[hooks[i]].push(modules[j][hooks[i]]);
      }
    }
  }

  function emptyNodeAt (elm) {
    return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
  }

  function createRmCb (childElm, listeners) {
    function remove$$1 () {
      if (--remove$$1.listeners === 0) {
        removeNode(childElm);
      }
    }
    remove$$1.listeners = listeners;
    return remove$$1
  }

  function removeNode (el) {
    var parent = nodeOps.parentNode(el);
    // element may have already been removed due to v-html / v-text
    if (isDef(parent)) {
      nodeOps.removeChild(parent, el);
    }
  }

  function isUnknownElement$$1 (vnode, inVPre) {
    return (
      !inVPre &&
      !vnode.ns &&
      !(
        config.ignoredElements.length &&
        config.ignoredElements.some(function (ignore) {
          return isRegExp(ignore)
            ? ignore.test(vnode.tag)
            : ignore === vnode.tag
        })
      ) &&
      config.isUnknownElement(vnode.tag)
    )
  }

  var creatingElmInVPre = 0;

  function createElm (
    vnode,
    insertedVnodeQueue,
    parentElm,
    refElm,
    nested,
    ownerArray,
    index
  ) {
    if (isDef(vnode.elm) && isDef(ownerArray)) {
      // This vnode was used in a previous render!
      // now it's used as a new node, overwriting its elm would cause
      // potential patch errors down the road when it's used as an insertion
      // reference node. Instead, we clone the node on-demand before creating
      // associated DOM element for it.
      vnode = ownerArray[index] = cloneVNode(vnode);
    }

    vnode.isRootInsert = !nested; // for transition enter check
    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
      return
    }

    var data = vnode.data;
    var children = vnode.children;
    var tag = vnode.tag;
    if (isDef(tag)) {
      {
        if (data && data.pre) {
          creatingElmInVPre++;
        }
        if (isUnknownElement$$1(vnode, creatingElmInVPre)) {
          warn(
            'Unknown custom element: <' + tag + '> - did you ' +
            'register the component correctly? For recursive components, ' +
            'make sure to provide the "name" option.',
            vnode.context
          );
        }
      }

      vnode.elm = vnode.ns
        ? nodeOps.createElementNS(vnode.ns, tag)
        : nodeOps.createElement(tag, vnode);
      setScope(vnode);

      /* istanbul ignore if */
      {
        createChildren(vnode, children, insertedVnodeQueue);
        if (isDef(data)) {
          invokeCreateHooks(vnode, insertedVnodeQueue);
        }
        insert(parentElm, vnode.elm, refElm);
      }

      if (data && data.pre) {
        creatingElmInVPre--;
      }
    } else if (isTrue(vnode.isComment)) {
      vnode.elm = nodeOps.createComment(vnode.text);
      insert(parentElm, vnode.elm, refElm);
    } else {
      vnode.elm = nodeOps.createTextNode(vnode.text);
      insert(parentElm, vnode.elm, refElm);
    }
  }

  function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
    var i = vnode.data;
    if (isDef(i)) {
      var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;
      if (isDef(i = i.hook) && isDef(i = i.init)) {
        i(vnode, false /* hydrating */);
      }
      // after calling the init hook, if the vnode is a child component
      // it should've created a child instance and mounted it. the child
      // component also has set the placeholder vnode's elm.
      // in that case we can just return the element and be done.
      if (isDef(vnode.componentInstance)) {
        initComponent(vnode, insertedVnodeQueue);
        insert(parentElm, vnode.elm, refElm);
        if (isTrue(isReactivated)) {
          reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
        }
        return true
      }
    }
  }

  function initComponent (vnode, insertedVnodeQueue) {
    if (isDef(vnode.data.pendingInsert)) {
      insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
      vnode.data.pendingInsert = null;
    }
    vnode.elm = vnode.componentInstance.$el;
    if (isPatchable(vnode)) {
      invokeCreateHooks(vnode, insertedVnodeQueue);
      setScope(vnode);
    } else {
      // empty component root.
      // skip all element-related modules except for ref (#3455)
      registerRef(vnode);
      // make sure to invoke the insert hook
      insertedVnodeQueue.push(vnode);
    }
  }

  function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
    var i;
    // hack for #4339: a reactivated component with inner transition
    // does not trigger because the inner node's created hooks are not called
    // again. It's not ideal to involve module-specific logic in here but
    // there doesn't seem to be a better way to do it.
    var innerNode = vnode;
    while (innerNode.componentInstance) {
      innerNode = innerNode.componentInstance._vnode;
      if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
        for (i = 0; i < cbs.activate.length; ++i) {
          cbs.activate[i](emptyNode, innerNode);
        }
        insertedVnodeQueue.push(innerNode);
        break
      }
    }
    // unlike a newly created component,
    // a reactivated keep-alive component doesn't insert itself
    insert(parentElm, vnode.elm, refElm);
  }

  function insert (parent, elm, ref$$1) {
    if (isDef(parent)) {
      if (isDef(ref$$1)) {
        if (nodeOps.parentNode(ref$$1) === parent) {
          nodeOps.insertBefore(parent, elm, ref$$1);
        }
      } else {
        nodeOps.appendChild(parent, elm);
      }
    }
  }

  function createChildren (vnode, children, insertedVnodeQueue) {
    if (Array.isArray(children)) {
      {
        checkDuplicateKeys(children);
      }
      for (var i = 0; i < children.length; ++i) {
        createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i);
      }
    } else if (isPrimitive(vnode.text)) {
      nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)));
    }
  }

  function isPatchable (vnode) {
    while (vnode.componentInstance) {
      vnode = vnode.componentInstance._vnode;
    }
    return isDef(vnode.tag)
  }

  function invokeCreateHooks (vnode, insertedVnodeQueue) {
    for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
      cbs.create[i$1](emptyNode, vnode);
    }
    i = vnode.data.hook; // Reuse variable
    if (isDef(i)) {
      if (isDef(i.create)) { i.create(emptyNode, vnode); }
      if (isDef(i.insert)) { insertedVnodeQueue.push(vnode); }
    }
  }

  // set scope id attribute for scoped CSS.
  // this is implemented as a special case to avoid the overhead
  // of going through the normal attribute patching process.
  function setScope (vnode) {
    var i;
    if (isDef(i = vnode.fnScopeId)) {
      nodeOps.setStyleScope(vnode.elm, i);
    } else {
      var ancestor = vnode;
      while (ancestor) {
        if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
          nodeOps.setStyleScope(vnode.elm, i);
        }
        ancestor = ancestor.parent;
      }
    }
    // for slot content they should also get the scopeId from the host instance.
    if (isDef(i = activeInstance) &&
      i !== vnode.context &&
      i !== vnode.fnContext &&
      isDef(i = i.$options._scopeId)
    ) {
      nodeOps.setStyleScope(vnode.elm, i);
    }
  }

  function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
    for (; startIdx <= endIdx; ++startIdx) {
      createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx);
    }
  }

  function invokeDestroyHook (vnode) {
    var i, j;
    var data = vnode.data;
    if (isDef(data)) {
      if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); }
      for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); }
    }
    if (isDef(i = vnode.children)) {
      for (j = 0; j < vnode.children.length; ++j) {
        invokeDestroyHook(vnode.children[j]);
      }
    }
  }

  function removeVnodes (vnodes, startIdx, endIdx) {
    for (; startIdx <= endIdx; ++startIdx) {
      var ch = vnodes[startIdx];
      if (isDef(ch)) {
        if (isDef(ch.tag)) {
          removeAndInvokeRemoveHook(ch);
          invokeDestroyHook(ch);
        } else { // Text node
          removeNode(ch.elm);
        }
      }
    }
  }

  function removeAndInvokeRemoveHook (vnode, rm) {
    if (isDef(rm) || isDef(vnode.data)) {
      var i;
      var listeners = cbs.remove.length + 1;
      if (isDef(rm)) {
        // we have a recursively passed down rm callback
        // increase the listeners count
        rm.listeners += listeners;
      } else {
        // directly removing
        rm = createRmCb(vnode.elm, listeners);
      }
      // recursively invoke hooks on child component root node
      if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
        removeAndInvokeRemoveHook(i, rm);
      }
      for (i = 0; i < cbs.remove.length; ++i) {
        cbs.remove[i](vnode, rm);
      }
      if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
        i(vnode, rm);
      } else {
        rm();
      }
    } else {
      removeNode(vnode.elm);
    }
  }

  function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
    var oldStartIdx = 0;
    var newStartIdx = 0;
    var oldEndIdx = oldCh.length - 1;
    var oldStartVnode = oldCh[0];
    var oldEndVnode = oldCh[oldEndIdx];
    var newEndIdx = newCh.length - 1;
    var newStartVnode = newCh[0];
    var newEndVnode = newCh[newEndIdx];
    var oldKeyToIdx, idxInOld, vnodeToMove, refElm;

    // removeOnly is a special flag used only by <transition-group>
    // to ensure removed elements stay in correct relative positions
    // during leaving transitions
    var canMove = !removeOnly;

    {
      checkDuplicateKeys(newCh);
    }

    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
      if (isUndef(oldStartVnode)) {
        oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left
      } else if (isUndef(oldEndVnode)) {
        oldEndVnode = oldCh[--oldEndIdx];
      } else if (sameVnode(oldStartVnode, newStartVnode)) {
        patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
        oldStartVnode = oldCh[++oldStartIdx];
        newStartVnode = newCh[++newStartIdx];
      } else if (sameVnode(oldEndVnode, newEndVnode)) {
        patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
        oldEndVnode = oldCh[--oldEndIdx];
        newEndVnode = newCh[--newEndIdx];
      } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
        patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx);
        canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));
        oldStartVnode = oldCh[++oldStartIdx];
        newEndVnode = newCh[--newEndIdx];
      } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
        patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
        canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
        oldEndVnode = oldCh[--oldEndIdx];
        newStartVnode = newCh[++newStartIdx];
      } else {
        if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); }
        idxInOld = isDef(newStartVnode.key)
          ? oldKeyToIdx[newStartVnode.key]
          : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
        if (isUndef(idxInOld)) { // New element
          createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
        } else {
          vnodeToMove = oldCh[idxInOld];
          if (sameVnode(vnodeToMove, newStartVnode)) {
            patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx);
            oldCh[idxInOld] = undefined;
            canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm);
          } else {
            // same key but different element. treat as new element
            createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx);
          }
        }
        newStartVnode = newCh[++newStartIdx];
      }
    }
    if (oldStartIdx > oldEndIdx) {
      refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
      addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
    } else if (newStartIdx > newEndIdx) {
      removeVnodes(oldCh, oldStartIdx, oldEndIdx);
    }
  }

  function checkDuplicateKeys (children) {
    var seenKeys = {};
    for (var i = 0; i < children.length; i++) {
      var vnode = children[i];
      var key = vnode.key;
      if (isDef(key)) {
        if (seenKeys[key]) {
          warn(
            ("Duplicate keys detected: '" + key + "'. This may cause an update error."),
            vnode.context
          );
        } else {
          seenKeys[key] = true;
        }
      }
    }
  }

  function findIdxInOld (node, oldCh, start, end) {
    for (var i = start; i < end; i++) {
      var c = oldCh[i];
      if (isDef(c) && sameVnode(node, c)) { return i }
    }
  }

  function patchVnode (
    oldVnode,
    vnode,
    insertedVnodeQueue,
    ownerArray,
    index,
    removeOnly
  ) {
    if (oldVnode === vnode) {
      return
    }

    if (isDef(vnode.elm) && isDef(ownerArray)) {
      // clone reused vnode
      vnode = ownerArray[index] = cloneVNode(vnode);
    }

    var elm = vnode.elm = oldVnode.elm;

    if (isTrue(oldVnode.isAsyncPlaceholder)) {
      if (isDef(vnode.asyncFactory.resolved)) {
        hydrate(oldVnode.elm, vnode, insertedVnodeQueue);
      } else {
        vnode.isAsyncPlaceholder = true;
      }
      return
    }

    // reuse element for static trees.
    // note we only do this if the vnode is cloned -
    // if the new node is not cloned it means the render functions have been
    // reset by the hot-reload-api and we need to do a proper re-render.
    if (isTrue(vnode.isStatic) &&
      isTrue(oldVnode.isStatic) &&
      vnode.key === oldVnode.key &&
      (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
    ) {
      vnode.componentInstance = oldVnode.componentInstance;
      return
    }

    var i;
    var data = vnode.data;
    if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
      i(oldVnode, vnode);
    }

    var oldCh = oldVnode.children;
    var ch = vnode.children;
    if (isDef(data) && isPatchable(vnode)) {
      for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); }
      if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); }
    }
    if (isUndef(vnode.text)) {
      if (isDef(oldCh) && isDef(ch)) {
        if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }
      } else if (isDef(ch)) {
        {
          checkDuplicateKeys(ch);
        }
        if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
        addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
      } else if (isDef(oldCh)) {
        removeVnodes(oldCh, 0, oldCh.length - 1);
      } else if (isDef(oldVnode.text)) {
        nodeOps.setTextContent(elm, '');
      }
    } else if (oldVnode.text !== vnode.text) {
      nodeOps.setTextContent(elm, vnode.text);
    }
    if (isDef(data)) {
      if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); }
    }
  }

  function invokeInsertHook (vnode, queue, initial) {
    // delay insert hooks for component root nodes, invoke them after the
    // element is really inserted
    if (isTrue(initial) && isDef(vnode.parent)) {
      vnode.parent.data.pendingInsert = queue;
    } else {
      for (var i = 0; i < queue.length; ++i) {
        queue[i].data.hook.insert(queue[i]);
      }
    }
  }

  var hydrationBailed = false;
  // list of modules that can skip create hook during hydration because they
  // are already rendered on the client or has no need for initialization
  // Note: style is excluded because it relies on initial clone for future
  // deep updates (#7063).
  var isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key');

  // Note: this is a browser-only function so we can assume elms are DOM nodes.
  function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
    var i;
    var tag = vnode.tag;
    var data = vnode.data;
    var children = vnode.children;
    inVPre = inVPre || (data && data.pre);
    vnode.elm = elm;

    if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
      vnode.isAsyncPlaceholder = true;
      return true
    }
    // assert node match
    {
      if (!assertNodeMatch(elm, vnode, inVPre)) {
        return false
      }
    }
    if (isDef(data)) {
      if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); }
      if (isDef(i = vnode.componentInstance)) {
        // child component. it should have hydrated its own tree.
        initComponent(vnode, insertedVnodeQueue);
        return true
      }
    }
    if (isDef(tag)) {
      if (isDef(children)) {
        // empty element, allow client to pick up and populate children
        if (!elm.hasChildNodes()) {
          createChildren(vnode, children, insertedVnodeQueue);
        } else {
          // v-html and domProps: innerHTML
          if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
            if (i !== elm.innerHTML) {
              /* istanbul ignore if */
              if (typeof console !== 'undefined' &&
                !hydrationBailed
              ) {
                hydrationBailed = true;
                console.warn('Parent: ', elm);
                console.warn('server innerHTML: ', i);
                console.warn('client innerHTML: ', elm.innerHTML);
              }
              return false
            }
          } else {
            // iterate and compare children lists
            var childrenMatch = true;
            var childNode = elm.firstChild;
            for (var i$1 = 0; i$1 < children.length; i$1++) {
              if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue, inVPre)) {
                childrenMatch = false;
                break
              }
              childNode = childNode.nextSibling;
            }
            // if childNode is not null, it means the actual childNodes list is
            // longer than the virtual children list.
            if (!childrenMatch || childNode) {
              /* istanbul ignore if */
              if (typeof console !== 'undefined' &&
                !hydrationBailed
              ) {
                hydrationBailed = true;
                console.warn('Parent: ', elm);
                console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
              }
              return false
            }
          }
        }
      }
      if (isDef(data)) {
        var fullInvoke = false;
        for (var key in data) {
          if (!isRenderedModule(key)) {
            fullInvoke = true;
            invokeCreateHooks(vnode, insertedVnodeQueue);
            break
          }
        }
        if (!fullInvoke && data['class']) {
          // ensure collecting deps for deep class bindings for future updates
          traverse(data['class']);
        }
      }
    } else if (elm.data !== vnode.text) {
      elm.data = vnode.text;
    }
    return true
  }

  function assertNodeMatch (node, vnode, inVPre) {
    if (isDef(vnode.tag)) {
      return vnode.tag.indexOf('vue-component') === 0 || (
        !isUnknownElement$$1(vnode, inVPre) &&
        vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
      )
    } else {
      return node.nodeType === (vnode.isComment ? 8 : 3)
    }
  }

  return function patch (oldVnode, vnode, hydrating, removeOnly) {
    if (isUndef(vnode)) {
      if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); }
      return
    }

    var isInitialPatch = false;
    var insertedVnodeQueue = [];

    if (isUndef(oldVnode)) {
      // empty mount (likely as component), create new root element
      isInitialPatch = true;
      createElm(vnode, insertedVnodeQueue);
    } else {
      var isRealElement = isDef(oldVnode.nodeType);
      if (!isRealElement && sameVnode(oldVnode, vnode)) {
        // patch existing root node
        patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly);
      } else {
        if (isRealElement) {
          // mounting to a real element
          // check if this is server-rendered content and if we can perform
          // a successful hydration.
          if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
            oldVnode.removeAttribute(SSR_ATTR);
            hydrating = true;
          }
          if (isTrue(hydrating)) {
            if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
              invokeInsertHook(vnode, insertedVnodeQueue, true);
              return oldVnode
            } else {
              warn(
                'The client-side rendered virtual DOM tree is not matching ' +
                'server-rendered content. This is likely caused by incorrect ' +
                'HTML markup, for example nesting block-level elements inside ' +
                '<p>, or missing <tbody>. Bailing hydration and performing ' +
                'full client-side render.'
              );
            }
          }
          // either not server-rendered, or hydration failed.
          // create an empty node and replace it
          oldVnode = emptyNodeAt(oldVnode);
        }

        // replacing existing element
        var oldElm = oldVnode.elm;
        var parentElm = nodeOps.parentNode(oldElm);

        // create new node
        createElm(
          vnode,
          insertedVnodeQueue,
          // extremely rare edge case: do not insert if old element is in a
          // leaving transition. Only happens when combining transition +
          // keep-alive + HOCs. (#4590)
          oldElm._leaveCb ? null : parentElm,
          nodeOps.nextSibling(oldElm)
        );

        // update parent placeholder node element, recursively
        if (isDef(vnode.parent)) {
          var ancestor = vnode.parent;
          var patchable = isPatchable(vnode);
          while (ancestor) {
            for (var i = 0; i < cbs.destroy.length; ++i) {
              cbs.destroy[i](ancestor);
            }
            ancestor.elm = vnode.elm;
            if (patchable) {
              for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
                cbs.create[i$1](emptyNode, ancestor);
              }
              // #6513
              // invoke insert hooks that may have been merged by create hooks.
              // e.g. for directives that uses the "inserted" hook.
              var insert = ancestor.data.hook.insert;
              if (insert.merged) {
                // start at index 1 to avoid re-invoking component mounted hook
                for (var i$2 = 1; i$2 < insert.fns.length; i$2++) {
                  insert.fns[i$2]();
                }
              }
            } else {
              registerRef(ancestor);
            }
            ancestor = ancestor.parent;
          }
        }

        // destroy old node
        if (isDef(parentElm)) {
          removeVnodes([oldVnode], 0, 0);
        } else if (isDef(oldVnode.tag)) {
          invokeDestroyHook(oldVnode);
        }
      }
    }

    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
    return vnode.elm
  }
}

/*  */

var directives = {
  create: updateDirectives,
  update: updateDirectives,
  destroy: function unbindDirectives (vnode) {
    updateDirectives(vnode, emptyNode);
  }
};

function updateDirectives (oldVnode, vnode) {
  if (oldVnode.data.directives || vnode.data.directives) {
    _update(oldVnode, vnode);
  }
}

function _update (oldVnode, vnode) {
  var isCreate = oldVnode === emptyNode;
  var isDestroy = vnode === emptyNode;
  var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);
  var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);

  var dirsWithInsert = [];
  var dirsWithPostpatch = [];

  var key, oldDir, dir;
  for (key in newDirs) {
    oldDir = oldDirs[key];
    dir = newDirs[key];
    if (!oldDir) {
      // new directive, bind
      callHook$1(dir, 'bind', vnode, oldVnode);
      if (dir.def && dir.def.inserted) {
        dirsWithInsert.push(dir);
      }
    } else {
      // existing directive, update
      dir.oldValue = oldDir.value;
      dir.oldArg = oldDir.arg;
      callHook$1(dir, 'update', vnode, oldVnode);
      if (dir.def && dir.def.componentUpdated) {
        dirsWithPostpatch.push(dir);
      }
    }
  }

  if (dirsWithInsert.length) {
    var callInsert = function () {
      for (var i = 0; i < dirsWithInsert.length; i++) {
        callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);
      }
    };
    if (isCreate) {
      mergeVNodeHook(vnode, 'insert', callInsert);
    } else {
      callInsert();
    }
  }

  if (dirsWithPostpatch.length) {
    mergeVNodeHook(vnode, 'postpatch', function () {
      for (var i = 0; i < dirsWithPostpatch.length; i++) {
        callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);
      }
    });
  }

  if (!isCreate) {
    for (key in oldDirs) {
      if (!newDirs[key]) {
        // no longer present, unbind
        callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);
      }
    }
  }
}

var emptyModifiers = Object.create(null);

function normalizeDirectives$1 (
  dirs,
  vm
) {
  var res = Object.create(null);
  if (!dirs) {
    // $flow-disable-line
    return res
  }
  var i, dir;
  for (i = 0; i < dirs.length; i++) {
    dir = dirs[i];
    if (!dir.modifiers) {
      // $flow-disable-line
      dir.modifiers = emptyModifiers;
    }
    res[getRawDirName(dir)] = dir;
    dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);
  }
  // $flow-disable-line
  return res
}

function getRawDirName (dir) {
  return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.')))
}

function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) {
  var fn = dir.def && dir.def[hook];
  if (fn) {
    try {
      fn(vnode.elm, dir, vnode, oldVnode, isDestroy);
    } catch (e) {
      handleError(e, vnode.context, ("directive " + (dir.name) + " " + hook + " hook"));
    }
  }
}

var baseModules = [
  ref,
  directives
];

/*  */

function updateAttrs (oldVnode, vnode) {
  var opts = vnode.componentOptions;
  if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {
    return
  }
  if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {
    return
  }
  var key, cur, old;
  var elm = vnode.elm;
  var oldAttrs = oldVnode.data.attrs || {};
  var attrs = vnode.data.attrs || {};
  // clone observed objects, as the user probably wants to mutate it
  if (isDef(attrs.__ob__)) {
    attrs = vnode.data.attrs = extend({}, attrs);
  }

  for (key in attrs) {
    cur = attrs[key];
    old = oldAttrs[key];
    if (old !== cur) {
      setAttr(elm, key, cur);
    }
  }
  // #4391: in IE9, setting type can reset value for input[type=radio]
  // #6666: IE/Edge forces progress value down to 1 before setting a max
  /* istanbul ignore if */
  if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {
    setAttr(elm, 'value', attrs.value);
  }
  for (key in oldAttrs) {
    if (isUndef(attrs[key])) {
      if (isXlink(key)) {
        elm.removeAttributeNS(xlinkNS, getXlinkProp(key));
      } else if (!isEnumeratedAttr(key)) {
        elm.removeAttribute(key);
      }
    }
  }
}

function setAttr (el, key, value) {
  if (el.tagName.indexOf('-') > -1) {
    baseSetAttr(el, key, value);
  } else if (isBooleanAttr(key)) {
    // set attribute for blank value
    // e.g. <option disabled>Select one</option>
    if (isFalsyAttrValue(value)) {
      el.removeAttribute(key);
    } else {
      // technically allowfullscreen is a boolean attribute for <iframe>,
      // but Flash expects a value of "true" when used on <embed> tag
      value = key === 'allowfullscreen' && el.tagName === 'EMBED'
        ? 'true'
        : key;
      el.setAttribute(key, value);
    }
  } else if (isEnumeratedAttr(key)) {
    el.setAttribute(key, convertEnumeratedValue(key, value));
  } else if (isXlink(key)) {
    if (isFalsyAttrValue(value)) {
      el.removeAttributeNS(xlinkNS, getXlinkProp(key));
    } else {
      el.setAttributeNS(xlinkNS, key, value);
    }
  } else {
    baseSetAttr(el, key, value);
  }
}

function baseSetAttr (el, key, value) {
  if (isFalsyAttrValue(value)) {
    el.removeAttribute(key);
  } else {
    // #7138: IE10 & 11 fires input event when setting placeholder on
    // <textarea>... block the first input event and remove the blocker
    // immediately.
    /* istanbul ignore if */
    if (
      isIE && !isIE9 &&
      el.tagName === 'TEXTAREA' &&
      key === 'placeholder' && value !== '' && !el.__ieph
    ) {
      var blocker = function (e) {
        e.stopImmediatePropagation();
        el.removeEventListener('input', blocker);
      };
      el.addEventListener('input', blocker);
      // $flow-disable-line
      el.__ieph = true; /* IE placeholder patched */
    }
    el.setAttribute(key, value);
  }
}

var attrs = {
  create: updateAttrs,
  update: updateAttrs
};

/*  */

function updateClass (oldVnode, vnode) {
  var el = vnode.elm;
  var data = vnode.data;
  var oldData = oldVnode.data;
  if (
    isUndef(data.staticClass) &&
    isUndef(data.class) && (
      isUndef(oldData) || (
        isUndef(oldData.staticClass) &&
        isUndef(oldData.class)
      )
    )
  ) {
    return
  }

  var cls = genClassForVnode(vnode);

  // handle transition classes
  var transitionClass = el._transitionClasses;
  if (isDef(transitionClass)) {
    cls = concat(cls, stringifyClass(transitionClass));
  }

  // set the class
  if (cls !== el._prevClass) {
    el.setAttribute('class', cls);
    el._prevClass = cls;
  }
}

var klass = {
  create: updateClass,
  update: updateClass
};

/*  */

var validDivisionCharRE = /[\w).+\-_$\]]/;

function parseFilters (exp) {
  var inSingle = false;
  var inDouble = false;
  var inTemplateString = false;
  var inRegex = false;
  var curly = 0;
  var square = 0;
  var paren = 0;
  var lastFilterIndex = 0;
  var c, prev, i, expression, filters;

  for (i = 0; i < exp.length; i++) {
    prev = c;
    c = exp.charCodeAt(i);
    if (inSingle) {
      if (c === 0x27 && prev !== 0x5C) { inSingle = false; }
    } else if (inDouble) {
      if (c === 0x22 && prev !== 0x5C) { inDouble = false; }
    } else if (inTemplateString) {
      if (c === 0x60 && prev !== 0x5C) { inTemplateString = false; }
    } else if (inRegex) {
      if (c === 0x2f && prev !== 0x5C) { inRegex = false; }
    } else if (
      c === 0x7C && // pipe
      exp.charCodeAt(i + 1) !== 0x7C &&
      exp.charCodeAt(i - 1) !== 0x7C &&
      !curly && !square && !paren
    ) {
      if (expression === undefined) {
        // first filter, end of expression
        lastFilterIndex = i + 1;
        expression = exp.slice(0, i).trim();
      } else {
        pushFilter();
      }
    } else {
      switch (c) {
        case 0x22: inDouble = true; break         // "
        case 0x27: inSingle = true; break         // '
        case 0x60: inTemplateString = true; break // `
        case 0x28: paren++; break                 // (
        case 0x29: paren--; break                 // )
        case 0x5B: square++; break                // [
        case 0x5D: square--; break                // ]
        case 0x7B: curly++; break                 // {
        case 0x7D: curly--; break                 // }
      }
      if (c === 0x2f) { // /
        var j = i - 1;
        var p = (void 0);
        // find first non-whitespace prev char
        for (; j >= 0; j--) {
          p = exp.charAt(j);
          if (p !== ' ') { break }
        }
        if (!p || !validDivisionCharRE.test(p)) {
          inRegex = true;
        }
      }
    }
  }

  if (expression === undefined) {
    expression = exp.slice(0, i).trim();
  } else if (lastFilterIndex !== 0) {
    pushFilter();
  }

  function pushFilter () {
    (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());
    lastFilterIndex = i + 1;
  }

  if (filters) {
    for (i = 0; i < filters.length; i++) {
      expression = wrapFilter(expression, filters[i]);
    }
  }

  return expression
}

function wrapFilter (exp, filter) {
  var i = filter.indexOf('(');
  if (i < 0) {
    // _f: resolveFilter
    return ("_f(\"" + filter + "\")(" + exp + ")")
  } else {
    var name = filter.slice(0, i);
    var args = filter.slice(i + 1);
    return ("_f(\"" + name + "\")(" + exp + (args !== ')' ? ',' + args : args))
  }
}

/*  */



/* eslint-disable no-unused-vars */
function baseWarn (msg, range) {
  console.error(("[Vue compiler]: " + msg));
}
/* eslint-enable no-unused-vars */

function pluckModuleFunction (
  modules,
  key
) {
  return modules
    ? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; })
    : []
}

function addProp (el, name, value, range, dynamic) {
  (el.props || (el.props = [])).push(rangeSetItem({ name: name, value: value, dynamic: dynamic }, range));
  el.plain = false;
}

function addAttr (el, name, value, range, dynamic) {
  var attrs = dynamic
    ? (el.dynamicAttrs || (el.dynamicAttrs = []))
    : (el.attrs || (el.attrs = []));
  attrs.push(rangeSetItem({ name: name, value: value, dynamic: dynamic }, range));
  el.plain = false;
}

// add a raw attr (use this in preTransforms)
function addRawAttr (el, name, value, range) {
  el.attrsMap[name] = value;
  el.attrsList.push(rangeSetItem({ name: name, value: value }, range));
}

function addDirective (
  el,
  name,
  rawName,
  value,
  arg,
  isDynamicArg,
  modifiers,
  range
) {
  (el.directives || (el.directives = [])).push(rangeSetItem({
    name: name,
    rawName: rawName,
    value: value,
    arg: arg,
    isDynamicArg: isDynamicArg,
    modifiers: modifiers
  }, range));
  el.plain = false;
}

function prependModifierMarker (symbol, name, dynamic) {
  return dynamic
    ? ("_p(" + name + ",\"" + symbol + "\")")
    : symbol + name // mark the event as captured
}

function addHandler (
  el,
  name,
  value,
  modifiers,
  important,
  warn,
  range,
  dynamic
) {
  modifiers = modifiers || emptyObject;
  // warn prevent and passive modifier
  /* istanbul ignore if */
  if (
    warn &&
    modifiers.prevent && modifiers.passive
  ) {
    warn(
      'passive and prevent can\'t be used together. ' +
      'Passive handler can\'t prevent default event.',
      range
    );
  }

  // normalize click.right and click.middle since they don't actually fire
  // this is technically browser-specific, but at least for now browsers are
  // the only target envs that have right/middle clicks.
  if (modifiers.right) {
    if (dynamic) {
      name = "(" + name + ")==='click'?'contextmenu':(" + name + ")";
    } else if (name === 'click') {
      name = 'contextmenu';
      delete modifiers.right;
    }
  } else if (modifiers.middle) {
    if (dynamic) {
      name = "(" + name + ")==='click'?'mouseup':(" + name + ")";
    } else if (name === 'click') {
      name = 'mouseup';
    }
  }

  // check capture modifier
  if (modifiers.capture) {
    delete modifiers.capture;
    name = prependModifierMarker('!', name, dynamic);
  }
  if (modifiers.once) {
    delete modifiers.once;
    name = prependModifierMarker('~', name, dynamic);
  }
  /* istanbul ignore if */
  if (modifiers.passive) {
    delete modifiers.passive;
    name = prependModifierMarker('&', name, dynamic);
  }

  var events;
  if (modifiers.native) {
    delete modifiers.native;
    events = el.nativeEvents || (el.nativeEvents = {});
  } else {
    events = el.events || (el.events = {});
  }

  var newHandler = rangeSetItem({ value: value.trim(), dynamic: dynamic }, range);
  if (modifiers !== emptyObject) {
    newHandler.modifiers = modifiers;
  }

  var handlers = events[name];
  /* istanbul ignore if */
  if (Array.isArray(handlers)) {
    important ? handlers.unshift(newHandler) : handlers.push(newHandler);
  } else if (handlers) {
    events[name] = important ? [newHandler, handlers] : [handlers, newHandler];
  } else {
    events[name] = newHandler;
  }

  el.plain = false;
}

function getRawBindingAttr (
  el,
  name
) {
  return el.rawAttrsMap[':' + name] ||
    el.rawAttrsMap['v-bind:' + name] ||
    el.rawAttrsMap[name]
}

function getBindingAttr (
  el,
  name,
  getStatic
) {
  var dynamicValue =
    getAndRemoveAttr(el, ':' + name) ||
    getAndRemoveAttr(el, 'v-bind:' + name);
  if (dynamicValue != null) {
    return parseFilters(dynamicValue)
  } else if (getStatic !== false) {
    var staticValue = getAndRemoveAttr(el, name);
    if (staticValue != null) {
      return JSON.stringify(staticValue)
    }
  }
}

// note: this only removes the attr from the Array (attrsList) so that it
// doesn't get processed by processAttrs.
// By default it does NOT remove it from the map (attrsMap) because the map is
// needed during codegen.
function getAndRemoveAttr (
  el,
  name,
  removeFromMap
) {
  var val;
  if ((val = el.attrsMap[name]) != null) {
    var list = el.attrsList;
    for (var i = 0, l = list.length; i < l; i++) {
      if (list[i].name === name) {
        list.splice(i, 1);
        break
      }
    }
  }
  if (removeFromMap) {
    delete el.attrsMap[name];
  }
  return val
}

function getAndRemoveAttrByRegex (
  el,
  name
) {
  var list = el.attrsList;
  for (var i = 0, l = list.length; i < l; i++) {
    var attr = list[i];
    if (name.test(attr.name)) {
      list.splice(i, 1);
      return attr
    }
  }
}

function rangeSetItem (
  item,
  range
) {
  if (range) {
    if (range.start != null) {
      item.start = range.start;
    }
    if (range.end != null) {
      item.end = range.end;
    }
  }
  return item
}

/*  */

/**
 * Cross-platform code generation for component v-model
 */
function genComponentModel (
  el,
  value,
  modifiers
) {
  var ref = modifiers || {};
  var number = ref.number;
  var trim = ref.trim;

  var baseValueExpression = '$$v';
  var valueExpression = baseValueExpression;
  if (trim) {
    valueExpression =
      "(typeof " + baseValueExpression + " === 'string'" +
      "? " + baseValueExpression + ".trim()" +
      ": " + baseValueExpression + ")";
  }
  if (number) {
    valueExpression = "_n(" + valueExpression + ")";
  }
  var assignment = genAssignmentCode(value, valueExpression);

  el.model = {
    value: ("(" + value + ")"),
    expression: JSON.stringify(value),
    callback: ("function (" + baseValueExpression + ") {" + assignment + "}")
  };
}

/**
 * Cross-platform codegen helper for generating v-model value assignment code.
 */
function genAssignmentCode (
  value,
  assignment
) {
  var res = parseModel(value);
  if (res.key === null) {
    return (value + "=" + assignment)
  } else {
    return ("$set(" + (res.exp) + ", " + (res.key) + ", " + assignment + ")")
  }
}

/**
 * Parse a v-model expression into a base path and a final key segment.
 * Handles both dot-path and possible square brackets.
 *
 * Possible cases:
 *
 * - test
 * - test[key]
 * - test[test1[key]]
 * - test["a"][key]
 * - xxx.test[a[a].test1[key]]
 * - test.xxx.a["asa"][test1[key]]
 *
 */

var len, str, chr, index$1, expressionPos, expressionEndPos;



function parseModel (val) {
  // Fix https://github.com/vuejs/vue/pull/7730
  // allow v-model="obj.val " (trailing whitespace)
  val = val.trim();
  len = val.length;

  if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
    index$1 = val.lastIndexOf('.');
    if (index$1 > -1) {
      return {
        exp: val.slice(0, index$1),
        key: '"' + val.slice(index$1 + 1) + '"'
      }
    } else {
      return {
        exp: val,
        key: null
      }
    }
  }

  str = val;
  index$1 = expressionPos = expressionEndPos = 0;

  while (!eof()) {
    chr = next();
    /* istanbul ignore if */
    if (isStringStart(chr)) {
      parseString(chr);
    } else if (chr === 0x5B) {
      parseBracket(chr);
    }
  }

  return {
    exp: val.slice(0, expressionPos),
    key: val.slice(expressionPos + 1, expressionEndPos)
  }
}

function next () {
  return str.charCodeAt(++index$1)
}

function eof () {
  return index$1 >= len
}

function isStringStart (chr) {
  return chr === 0x22 || chr === 0x27
}

function parseBracket (chr) {
  var inBracket = 1;
  expressionPos = index$1;
  while (!eof()) {
    chr = next();
    if (isStringStart(chr)) {
      parseString(chr);
      continue
    }
    if (chr === 0x5B) { inBracket++; }
    if (chr === 0x5D) { inBracket--; }
    if (inBracket === 0) {
      expressionEndPos = index$1;
      break
    }
  }
}

function parseString (chr) {
  var stringQuote = chr;
  while (!eof()) {
    chr = next();
    if (chr === stringQuote) {
      break
    }
  }
}

/*  */

var warn$1;

// in some cases, the event used has to be determined at runtime
// so we used some reserved tokens during compile.
var RANGE_TOKEN = '__r';
var CHECKBOX_RADIO_TOKEN = '__c';

function model (
  el,
  dir,
  _warn
) {
  warn$1 = _warn;
  var value = dir.value;
  var modifiers = dir.modifiers;
  var tag = el.tag;
  var type = el.attrsMap.type;

  {
    // inputs with type="file" are read only and setting the input's
    // value will throw an error.
    if (tag === 'input' && type === 'file') {
      warn$1(
        "<" + (el.tag) + " v-model=\"" + value + "\" type=\"file\">:\n" +
        "File inputs are read only. Use a v-on:change listener instead.",
        el.rawAttrsMap['v-model']
      );
    }
  }

  if (el.component) {
    genComponentModel(el, value, modifiers);
    // component v-model doesn't need extra runtime
    return false
  } else if (tag === 'select') {
    genSelect(el, value, modifiers);
  } else if (tag === 'input' && type === 'checkbox') {
    genCheckboxModel(el, value, modifiers);
  } else if (tag === 'input' && type === 'radio') {
    genRadioModel(el, value, modifiers);
  } else if (tag === 'input' || tag === 'textarea') {
    genDefaultModel(el, value, modifiers);
  } else if (!config.isReservedTag(tag)) {
    genComponentModel(el, value, modifiers);
    // component v-model doesn't need extra runtime
    return false
  } else {
    warn$1(
      "<" + (el.tag) + " v-model=\"" + value + "\">: " +
      "v-model is not supported on this element type. " +
      'If you are working with contenteditable, it\'s recommended to ' +
      'wrap a library dedicated for that purpose inside a custom component.',
      el.rawAttrsMap['v-model']
    );
  }

  // ensure runtime directive metadata
  return true
}

function genCheckboxModel (
  el,
  value,
  modifiers
) {
  var number = modifiers && modifiers.number;
  var valueBinding = getBindingAttr(el, 'value') || 'null';
  var trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
  var falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
  addProp(el, 'checked',
    "Array.isArray(" + value + ")" +
    "?_i(" + value + "," + valueBinding + ")>-1" + (
      trueValueBinding === 'true'
        ? (":(" + value + ")")
        : (":_q(" + value + "," + trueValueBinding + ")")
    )
  );
  addHandler(el, 'change',
    "var $$a=" + value + "," +
        '$$el=$event.target,' +
        "$$c=$$el.checked?(" + trueValueBinding + "):(" + falseValueBinding + ");" +
    'if(Array.isArray($$a)){' +
      "var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," +
          '$$i=_i($$a,$$v);' +
      "if($$el.checked){$$i<0&&(" + (genAssignmentCode(value, '$$a.concat([$$v])')) + ")}" +
      "else{$$i>-1&&(" + (genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')) + ")}" +
    "}else{" + (genAssignmentCode(value, '$$c')) + "}",
    null, true
  );
}

function genRadioModel (
  el,
  value,
  modifiers
) {
  var number = modifiers && modifiers.number;
  var valueBinding = getBindingAttr(el, 'value') || 'null';
  valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding;
  addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")"));
  addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);
}

function genSelect (
  el,
  value,
  modifiers
) {
  var number = modifiers && modifiers.number;
  var selectedVal = "Array.prototype.filter" +
    ".call($event.target.options,function(o){return o.selected})" +
    ".map(function(o){var val = \"_value\" in o ? o._value : o.value;" +
    "return " + (number ? '_n(val)' : 'val') + "})";

  var assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
  var code = "var $$selectedVal = " + selectedVal + ";";
  code = code + " " + (genAssignmentCode(value, assignment));
  addHandler(el, 'change', code, null, true);
}

function genDefaultModel (
  el,
  value,
  modifiers
) {
  var type = el.attrsMap.type;

  // warn if v-bind:value conflicts with v-model
  // except for inputs with v-bind:type
  {
    var value$1 = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];
    var typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
    if (value$1 && !typeBinding) {
      var binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';
      warn$1(
        binding + "=\"" + value$1 + "\" conflicts with v-model on the same element " +
        'because the latter already expands to a value binding internally',
        el.rawAttrsMap[binding]
      );
    }
  }

  var ref = modifiers || {};
  var lazy = ref.lazy;
  var number = ref.number;
  var trim = ref.trim;
  var needCompositionGuard = !lazy && type !== 'range';
  var event = lazy
    ? 'change'
    : type === 'range'
      ? RANGE_TOKEN
      : 'input';

  var valueExpression = '$event.target.value';
  if (trim) {
    valueExpression = "$event.target.value.trim()";
  }
  if (number) {
    valueExpression = "_n(" + valueExpression + ")";
  }

  var code = genAssignmentCode(value, valueExpression);
  if (needCompositionGuard) {
    code = "if($event.target.composing)return;" + code;
  }

  addProp(el, 'value', ("(" + value + ")"));
  addHandler(el, event, code, null, true);
  if (trim || number) {
    addHandler(el, 'blur', '$forceUpdate()');
  }
}

/*  */

// normalize v-model event tokens that can only be determined at runtime.
// it's important to place the event as the first in the array because
// the whole point is ensuring the v-model callback gets called before
// user-attached handlers.
function normalizeEvents (on) {
  /* istanbul ignore if */
  if (isDef(on[RANGE_TOKEN])) {
    // IE input[type=range] only supports `change` event
    var event = isIE ? 'change' : 'input';
    on[event] = [].concat(on[RANGE_TOKEN], on[event] || []);
    delete on[RANGE_TOKEN];
  }
  // This was originally intended to fix #4521 but no longer necessary
  // after 2.5. Keeping it for backwards compat with generated code from < 2.4
  /* istanbul ignore if */
  if (isDef(on[CHECKBOX_RADIO_TOKEN])) {
    on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []);
    delete on[CHECKBOX_RADIO_TOKEN];
  }
}

var target$1;

function createOnceHandler$1 (event, handler, capture) {
  var _target = target$1; // save current target element in closure
  return function onceHandler () {
    var res = handler.apply(null, arguments);
    if (res !== null) {
      remove$2(event, onceHandler, capture, _target);
    }
  }
}

// #9446: Firefox <= 53 (in particular, ESR 52) has incorrect Event.timeStamp
// implementation and does not fire microtasks in between event propagation, so
// safe to exclude.
var useMicrotaskFix = isUsingMicroTask && !(isFF && Number(isFF[1]) <= 53);

function add$1 (
  name,
  handler,
  capture,
  passive
) {
  // async edge case #6566: inner click event triggers patch, event handler
  // attached to outer element during patch, and triggered again. This
  // happens because browsers fire microtask ticks between event propagation.
  // the solution is simple: we save the timestamp when a handler is attached,
  // and the handler would only fire if the event passed to it was fired
  // AFTER it was attached.
  if (useMicrotaskFix) {
    var attachedTimestamp = currentFlushTimestamp;
    var original = handler;
    handler = original._wrapper = function (e) {
      if (
        // no bubbling, should always fire.
        // this is just a safety net in case event.timeStamp is unreliable in
        // certain weird environments...
        e.target === e.currentTarget ||
        // event is fired after handler attachment
        e.timeStamp >= attachedTimestamp ||
        // bail for environments that have buggy event.timeStamp implementations
        // #9462 iOS 9 bug: event.timeStamp is 0 after history.pushState
        // #9681 QtWebEngine event.timeStamp is negative value
        e.timeStamp <= 0 ||
        // #9448 bail if event is fired in another document in a multi-page
        // electron/nw.js app, since event.timeStamp will be using a different
        // starting reference
        e.target.ownerDocument !== document
      ) {
        return original.apply(this, arguments)
      }
    };
  }
  target$1.addEventListener(
    name,
    handler,
    supportsPassive
      ? { capture: capture, passive: passive }
      : capture
  );
}

function remove$2 (
  name,
  handler,
  capture,
  _target
) {
  (_target || target$1).removeEventListener(
    name,
    handler._wrapper || handler,
    capture
  );
}

function updateDOMListeners (oldVnode, vnode) {
  if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
    return
  }
  var on = vnode.data.on || {};
  var oldOn = oldVnode.data.on || {};
  target$1 = vnode.elm;
  normalizeEvents(on);
  updateListeners(on, oldOn, add$1, remove$2, createOnceHandler$1, vnode.context);
  target$1 = undefined;
}

var events = {
  create: updateDOMListeners,
  update: updateDOMListeners
};

/*  */

var svgContainer;

function updateDOMProps (oldVnode, vnode) {
  if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {
    return
  }
  var key, cur;
  var elm = vnode.elm;
  var oldProps = oldVnode.data.domProps || {};
  var props = vnode.data.domProps || {};
  // clone observed objects, as the user probably wants to mutate it
  if (isDef(props.__ob__)) {
    props = vnode.data.domProps = extend({}, props);
  }

  for (key in oldProps) {
    if (!(key in props)) {
      elm[key] = '';
    }
  }

  for (key in props) {
    cur = props[key];
    // ignore children if the node has textContent or innerHTML,
    // as these will throw away existing DOM nodes and cause removal errors
    // on subsequent patches (#3360)
    if (key === 'textContent' || key === 'innerHTML') {
      if (vnode.children) { vnode.children.length = 0; }
      if (cur === oldProps[key]) { continue }
      // #6601 work around Chrome version <= 55 bug where single textNode
      // replaced by innerHTML/textContent retains its parentNode property
      if (elm.childNodes.length === 1) {
        elm.removeChild(elm.childNodes[0]);
      }
    }

    if (key === 'value' && elm.tagName !== 'PROGRESS') {
      // store value as _value as well since
      // non-string values will be stringified
      elm._value = cur;
      // avoid resetting cursor position when value is the same
      var strCur = isUndef(cur) ? '' : String(cur);
      if (shouldUpdateValue(elm, strCur)) {
        elm.value = strCur;
      }
    } else if (key === 'innerHTML' && isSVG(elm.tagName) && isUndef(elm.innerHTML)) {
      // IE doesn't support innerHTML for SVG elements
      svgContainer = svgContainer || document.createElement('div');
      svgContainer.innerHTML = "<svg>" + cur + "</svg>";
      var svg = svgContainer.firstChild;
      while (elm.firstChild) {
        elm.removeChild(elm.firstChild);
      }
      while (svg.firstChild) {
        elm.appendChild(svg.firstChild);
      }
    } else if (
      // skip the update if old and new VDOM state is the same.
      // `value` is handled separately because the DOM value may be temporarily
      // out of sync with VDOM state due to focus, composition and modifiers.
      // This  #4521 by skipping the unnecessary `checked` update.
      cur !== oldProps[key]
    ) {
      // some property updates can throw
      // e.g. `value` on <progress> w/ non-finite value
      try {
        elm[key] = cur;
      } catch (e) {}
    }
  }
}

// check platforms/web/util/attrs.js acceptValue


function shouldUpdateValue (elm, checkVal) {
  return (!elm.composing && (
    elm.tagName === 'OPTION' ||
    isNotInFocusAndDirty(elm, checkVal) ||
    isDirtyWithModifiers(elm, checkVal)
  ))
}

function isNotInFocusAndDirty (elm, checkVal) {
  // return true when textbox (.number and .trim) loses focus and its value is
  // not equal to the updated value
  var notInFocus = true;
  // #6157
  // work around IE bug when accessing document.activeElement in an iframe
  try { notInFocus = document.activeElement !== elm; } catch (e) {}
  return notInFocus && elm.value !== checkVal
}

function isDirtyWithModifiers (elm, newVal) {
  var value = elm.value;
  var modifiers = elm._vModifiers; // injected by v-model runtime
  if (isDef(modifiers)) {
    if (modifiers.number) {
      return toNumber(value) !== toNumber(newVal)
    }
    if (modifiers.trim) {
      return value.trim() !== newVal.trim()
    }
  }
  return value !== newVal
}

var domProps = {
  create: updateDOMProps,
  update: updateDOMProps
};

/*  */

var parseStyleText = cached(function (cssText) {
  var res = {};
  var listDelimiter = /;(?![^(]*\))/g;
  var propertyDelimiter = /:(.+)/;
  cssText.split(listDelimiter).forEach(function (item) {
    if (item) {
      var tmp = item.split(propertyDelimiter);
      tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());
    }
  });
  return res
});

// merge static and dynamic style data on the same vnode
function normalizeStyleData (data) {
  var style = normalizeStyleBinding(data.style);
  // static style is pre-processed into an object during compilation
  // and is always a fresh object, so it's safe to merge into it
  return data.staticStyle
    ? extend(data.staticStyle, style)
    : style
}

// normalize possible array / string values into Object
function normalizeStyleBinding (bindingStyle) {
  if (Array.isArray(bindingStyle)) {
    return toObject(bindingStyle)
  }
  if (typeof bindingStyle === 'string') {
    return parseStyleText(bindingStyle)
  }
  return bindingStyle
}

/**
 * parent component style should be after child's
 * so that parent component's style could override it
 */
function getStyle (vnode, checkChild) {
  var res = {};
  var styleData;

  if (checkChild) {
    var childNode = vnode;
    while (childNode.componentInstance) {
      childNode = childNode.componentInstance._vnode;
      if (
        childNode && childNode.data &&
        (styleData = normalizeStyleData(childNode.data))
      ) {
        extend(res, styleData);
      }
    }
  }

  if ((styleData = normalizeStyleData(vnode.data))) {
    extend(res, styleData);
  }

  var parentNode = vnode;
  while ((parentNode = parentNode.parent)) {
    if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
      extend(res, styleData);
    }
  }
  return res
}

/*  */

var cssVarRE = /^--/;
var importantRE = /\s*!important$/;
var setProp = function (el, name, val) {
  /* istanbul ignore if */
  if (cssVarRE.test(name)) {
    el.style.setProperty(name, val);
  } else if (importantRE.test(val)) {
    el.style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important');
  } else {
    var normalizedName = normalize(name);
    if (Array.isArray(val)) {
      // Support values array created by autoprefixer, e.g.
      // {display: ["-webkit-box", "-ms-flexbox", "flex"]}
      // Set them one by one, and the browser will only set those it can recognize
      for (var i = 0, len = val.length; i < len; i++) {
        el.style[normalizedName] = val[i];
      }
    } else {
      el.style[normalizedName] = val;
    }
  }
};

var vendorNames = ['Webkit', 'Moz', 'ms'];

var emptyStyle;
var normalize = cached(function (prop) {
  emptyStyle = emptyStyle || document.createElement('div').style;
  prop = camelize(prop);
  if (prop !== 'filter' && (prop in emptyStyle)) {
    return prop
  }
  var capName = prop.charAt(0).toUpperCase() + prop.slice(1);
  for (var i = 0; i < vendorNames.length; i++) {
    var name = vendorNames[i] + capName;
    if (name in emptyStyle) {
      return name
    }
  }
});

function updateStyle (oldVnode, vnode) {
  var data = vnode.data;
  var oldData = oldVnode.data;

  if (isUndef(data.staticStyle) && isUndef(data.style) &&
    isUndef(oldData.staticStyle) && isUndef(oldData.style)
  ) {
    return
  }

  var cur, name;
  var el = vnode.elm;
  var oldStaticStyle = oldData.staticStyle;
  var oldStyleBinding = oldData.normalizedStyle || oldData.style || {};

  // if static style exists, stylebinding already merged into it when doing normalizeStyleData
  var oldStyle = oldStaticStyle || oldStyleBinding;

  var style = normalizeStyleBinding(vnode.data.style) || {};

  // store normalized style under a different key for next diff
  // make sure to clone it if it's reactive, since the user likely wants
  // to mutate it.
  vnode.data.normalizedStyle = isDef(style.__ob__)
    ? extend({}, style)
    : style;

  var newStyle = getStyle(vnode, true);

  for (name in oldStyle) {
    if (isUndef(newStyle[name])) {
      setProp(el, name, '');
    }
  }
  for (name in newStyle) {
    cur = newStyle[name];
    if (cur !== oldStyle[name]) {
      // ie9 setting to null has no effect, must use empty string
      setProp(el, name, cur == null ? '' : cur);
    }
  }
}

var style = {
  create: updateStyle,
  update: updateStyle
};

/*  */

var whitespaceRE = /\s+/;

/**
 * Add class with compatibility for SVG since classList is not supported on
 * SVG elements in IE
 */
function addClass (el, cls) {
  /* istanbul ignore if */
  if (!cls || !(cls = cls.trim())) {
    return
  }

  /* istanbul ignore else */
  if (el.classList) {
    if (cls.indexOf(' ') > -1) {
      cls.split(whitespaceRE).forEach(function (c) { return el.classList.add(c); });
    } else {
      el.classList.add(cls);
    }
  } else {
    var cur = " " + (el.getAttribute('class') || '') + " ";
    if (cur.indexOf(' ' + cls + ' ') < 0) {
      el.setAttribute('class', (cur + cls).trim());
    }
  }
}

/**
 * Remove class with compatibility for SVG since classList is not supported on
 * SVG elements in IE
 */
function removeClass (el, cls) {
  /* istanbul ignore if */
  if (!cls || !(cls = cls.trim())) {
    return
  }

  /* istanbul ignore else */
  if (el.classList) {
    if (cls.indexOf(' ') > -1) {
      cls.split(whitespaceRE).forEach(function (c) { return el.classList.remove(c); });
    } else {
      el.classList.remove(cls);
    }
    if (!el.classList.length) {
      el.removeAttribute('class');
    }
  } else {
    var cur = " " + (el.getAttribute('class') || '') + " ";
    var tar = ' ' + cls + ' ';
    while (cur.indexOf(tar) >= 0) {
      cur = cur.replace(tar, ' ');
    }
    cur = cur.trim();
    if (cur) {
      el.setAttribute('class', cur);
    } else {
      el.removeAttribute('class');
    }
  }
}

/*  */

function resolveTransition (def$$1) {
  if (!def$$1) {
    return
  }
  /* istanbul ignore else */
  if (typeof def$$1 === 'object') {
    var res = {};
    if (def$$1.css !== false) {
      extend(res, autoCssTransition(def$$1.name || 'v'));
    }
    extend(res, def$$1);
    return res
  } else if (typeof def$$1 === 'string') {
    return autoCssTransition(def$$1)
  }
}

var autoCssTransition = cached(function (name) {
  return {
    enterClass: (name + "-enter"),
    enterToClass: (name + "-enter-to"),
    enterActiveClass: (name + "-enter-active"),
    leaveClass: (name + "-leave"),
    leaveToClass: (name + "-leave-to"),
    leaveActiveClass: (name + "-leave-active")
  }
});

var hasTransition = inBrowser && !isIE9;
var TRANSITION = 'transition';
var ANIMATION = 'animation';

// Transition property/event sniffing
var transitionProp = 'transition';
var transitionEndEvent = 'transitionend';
var animationProp = 'animation';
var animationEndEvent = 'animationend';
if (hasTransition) {
  /* istanbul ignore if */
  if (window.ontransitionend === undefined &&
    window.onwebkittransitionend !== undefined
  ) {
    transitionProp = 'WebkitTransition';
    transitionEndEvent = 'webkitTransitionEnd';
  }
  if (window.onanimationend === undefined &&
    window.onwebkitanimationend !== undefined
  ) {
    animationProp = 'WebkitAnimation';
    animationEndEvent = 'webkitAnimationEnd';
  }
}

// binding to window is necessary to make hot reload work in IE in strict mode
var raf = inBrowser
  ? window.requestAnimationFrame
    ? window.requestAnimationFrame.bind(window)
    : setTimeout
  : /* istanbul ignore next */ function (fn) { return fn(); };

function nextFrame (fn) {
  raf(function () {
    raf(fn);
  });
}

function addTransitionClass (el, cls) {
  var transitionClasses = el._transitionClasses || (el._transitionClasses = []);
  if (transitionClasses.indexOf(cls) < 0) {
    transitionClasses.push(cls);
    addClass(el, cls);
  }
}

function removeTransitionClass (el, cls) {
  if (el._transitionClasses) {
    remove(el._transitionClasses, cls);
  }
  removeClass(el, cls);
}

function whenTransitionEnds (
  el,
  expectedType,
  cb
) {
  var ref = getTransitionInfo(el, expectedType);
  var type = ref.type;
  var timeout = ref.timeout;
  var propCount = ref.propCount;
  if (!type) { return cb() }
  var event = type === TRANSITION ? transitionEndEvent : animationEndEvent;
  var ended = 0;
  var end = function () {
    el.removeEventListener(event, onEnd);
    cb();
  };
  var onEnd = function (e) {
    if (e.target === el) {
      if (++ended >= propCount) {
        end();
      }
    }
  };
  setTimeout(function () {
    if (ended < propCount) {
      end();
    }
  }, timeout + 1);
  el.addEventListener(event, onEnd);
}

var transformRE = /\b(transform|all)(,|$)/;

function getTransitionInfo (el, expectedType) {
  var styles = window.getComputedStyle(el);
  // JSDOM may return undefined for transition properties
  var transitionDelays = (styles[transitionProp + 'Delay'] || '').split(', ');
  var transitionDurations = (styles[transitionProp + 'Duration'] || '').split(', ');
  var transitionTimeout = getTimeout(transitionDelays, transitionDurations);
  var animationDelays = (styles[animationProp + 'Delay'] || '').split(', ');
  var animationDurations = (styles[animationProp + 'Duration'] || '').split(', ');
  var animationTimeout = getTimeout(animationDelays, animationDurations);

  var type;
  var timeout = 0;
  var propCount = 0;
  /* istanbul ignore if */
  if (expectedType === TRANSITION) {
    if (transitionTimeout > 0) {
      type = TRANSITION;
      timeout = transitionTimeout;
      propCount = transitionDurations.length;
    }
  } else if (expectedType === ANIMATION) {
    if (animationTimeout > 0) {
      type = ANIMATION;
      timeout = animationTimeout;
      propCount = animationDurations.length;
    }
  } else {
    timeout = Math.max(transitionTimeout, animationTimeout);
    type = timeout > 0
      ? transitionTimeout > animationTimeout
        ? TRANSITION
        : ANIMATION
      : null;
    propCount = type
      ? type === TRANSITION
        ? transitionDurations.length
        : animationDurations.length
      : 0;
  }
  var hasTransform =
    type === TRANSITION &&
    transformRE.test(styles[transitionProp + 'Property']);
  return {
    type: type,
    timeout: timeout,
    propCount: propCount,
    hasTransform: hasTransform
  }
}

function getTimeout (delays, durations) {
  /* istanbul ignore next */
  while (delays.length < durations.length) {
    delays = delays.concat(delays);
  }

  return Math.max.apply(null, durations.map(function (d, i) {
    return toMs(d) + toMs(delays[i])
  }))
}

// Old versions of Chromium (below 61.0.3163.100) formats floating pointer numbers
// in a locale-dependent way, using a comma instead of a dot.
// If comma is not replaced with a dot, the input will be rounded down (i.e. acting
// as a floor function) causing unexpected behaviors
function toMs (s) {
  return Number(s.slice(0, -1).replace(',', '.')) * 1000
}

/*  */

function enter (vnode, toggleDisplay) {
  var el = vnode.elm;

  // call leave callback now
  if (isDef(el._leaveCb)) {
    el._leaveCb.cancelled = true;
    el._leaveCb();
  }

  var data = resolveTransition(vnode.data.transition);
  if (isUndef(data)) {
    return
  }

  /* istanbul ignore if */
  if (isDef(el._enterCb) || el.nodeType !== 1) {
    return
  }

  var css = data.css;
  var type = data.type;
  var enterClass = data.enterClass;
  var enterToClass = data.enterToClass;
  var enterActiveClass = data.enterActiveClass;
  var appearClass = data.appearClass;
  var appearToClass = data.appearToClass;
  var appearActiveClass = data.appearActiveClass;
  var beforeEnter = data.beforeEnter;
  var enter = data.enter;
  var afterEnter = data.afterEnter;
  var enterCancelled = data.enterCancelled;
  var beforeAppear = data.beforeAppear;
  var appear = data.appear;
  var afterAppear = data.afterAppear;
  var appearCancelled = data.appearCancelled;
  var duration = data.duration;

  // activeInstance will always be the <transition> component managing this
  // transition. One edge case to check is when the <transition> is placed
  // as the root node of a child component. In that case we need to check
  // <transition>'s parent for appear check.
  var context = activeInstance;
  var transitionNode = activeInstance.$vnode;
  while (transitionNode && transitionNode.parent) {
    context = transitionNode.context;
    transitionNode = transitionNode.parent;
  }

  var isAppear = !context._isMounted || !vnode.isRootInsert;

  if (isAppear && !appear && appear !== '') {
    return
  }

  var startClass = isAppear && appearClass
    ? appearClass
    : enterClass;
  var activeClass = isAppear && appearActiveClass
    ? appearActiveClass
    : enterActiveClass;
  var toClass = isAppear && appearToClass
    ? appearToClass
    : enterToClass;

  var beforeEnterHook = isAppear
    ? (beforeAppear || beforeEnter)
    : beforeEnter;
  var enterHook = isAppear
    ? (typeof appear === 'function' ? appear : enter)
    : enter;
  var afterEnterHook = isAppear
    ? (afterAppear || afterEnter)
    : afterEnter;
  var enterCancelledHook = isAppear
    ? (appearCancelled || enterCancelled)
    : enterCancelled;

  var explicitEnterDuration = toNumber(
    isObject(duration)
      ? duration.enter
      : duration
  );

  if (explicitEnterDuration != null) {
    checkDuration(explicitEnterDuration, 'enter', vnode);
  }

  var expectsCSS = css !== false && !isIE9;
  var userWantsControl = getHookArgumentsLength(enterHook);

  var cb = el._enterCb = once(function () {
    if (expectsCSS) {
      removeTransitionClass(el, toClass);
      removeTransitionClass(el, activeClass);
    }
    if (cb.cancelled) {
      if (expectsCSS) {
        removeTransitionClass(el, startClass);
      }
      enterCancelledHook && enterCancelledHook(el);
    } else {
      afterEnterHook && afterEnterHook(el);
    }
    el._enterCb = null;
  });

  if (!vnode.data.show) {
    // remove pending leave element on enter by injecting an insert hook
    mergeVNodeHook(vnode, 'insert', function () {
      var parent = el.parentNode;
      var pendingNode = parent && parent._pending && parent._pending[vnode.key];
      if (pendingNode &&
        pendingNode.tag === vnode.tag &&
        pendingNode.elm._leaveCb
      ) {
        pendingNode.elm._leaveCb();
      }
      enterHook && enterHook(el, cb);
    });
  }

  // start enter transition
  beforeEnterHook && beforeEnterHook(el);
  if (expectsCSS) {
    addTransitionClass(el, startClass);
    addTransitionClass(el, activeClass);
    nextFrame(function () {
      removeTransitionClass(el, startClass);
      if (!cb.cancelled) {
        addTransitionClass(el, toClass);
        if (!userWantsControl) {
          if (isValidDuration(explicitEnterDuration)) {
            setTimeout(cb, explicitEnterDuration);
          } else {
            whenTransitionEnds(el, type, cb);
          }
        }
      }
    });
  }

  if (vnode.data.show) {
    toggleDisplay && toggleDisplay();
    enterHook && enterHook(el, cb);
  }

  if (!expectsCSS && !userWantsControl) {
    cb();
  }
}

function leave (vnode, rm) {
  var el = vnode.elm;

  // call enter callback now
  if (isDef(el._enterCb)) {
    el._enterCb.cancelled = true;
    el._enterCb();
  }

  var data = resolveTransition(vnode.data.transition);
  if (isUndef(data) || el.nodeType !== 1) {
    return rm()
  }

  /* istanbul ignore if */
  if (isDef(el._leaveCb)) {
    return
  }

  var css = data.css;
  var type = data.type;
  var leaveClass = data.leaveClass;
  var leaveToClass = data.leaveToClass;
  var leaveActiveClass = data.leaveActiveClass;
  var beforeLeave = data.beforeLeave;
  var leave = data.leave;
  var afterLeave = data.afterLeave;
  var leaveCancelled = data.leaveCancelled;
  var delayLeave = data.delayLeave;
  var duration = data.duration;

  var expectsCSS = css !== false && !isIE9;
  var userWantsControl = getHookArgumentsLength(leave);

  var explicitLeaveDuration = toNumber(
    isObject(duration)
      ? duration.leave
      : duration
  );

  if (isDef(explicitLeaveDuration)) {
    checkDuration(explicitLeaveDuration, 'leave', vnode);
  }

  var cb = el._leaveCb = once(function () {
    if (el.parentNode && el.parentNode._pending) {
      el.parentNode._pending[vnode.key] = null;
    }
    if (expectsCSS) {
      removeTransitionClass(el, leaveToClass);
      removeTransitionClass(el, leaveActiveClass);
    }
    if (cb.cancelled) {
      if (expectsCSS) {
        removeTransitionClass(el, leaveClass);
      }
      leaveCancelled && leaveCancelled(el);
    } else {
      rm();
      afterLeave && afterLeave(el);
    }
    el._leaveCb = null;
  });

  if (delayLeave) {
    delayLeave(performLeave);
  } else {
    performLeave();
  }

  function performLeave () {
    // the delayed leave may have already been cancelled
    if (cb.cancelled) {
      return
    }
    // record leaving element
    if (!vnode.data.show && el.parentNode) {
      (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode;
    }
    beforeLeave && beforeLeave(el);
    if (expectsCSS) {
      addTransitionClass(el, leaveClass);
      addTransitionClass(el, leaveActiveClass);
      nextFrame(function () {
        removeTransitionClass(el, leaveClass);
        if (!cb.cancelled) {
          addTransitionClass(el, leaveToClass);
          if (!userWantsControl) {
            if (isValidDuration(explicitLeaveDuration)) {
              setTimeout(cb, explicitLeaveDuration);
            } else {
              whenTransitionEnds(el, type, cb);
            }
          }
        }
      });
    }
    leave && leave(el, cb);
    if (!expectsCSS && !userWantsControl) {
      cb();
    }
  }
}

// only used in dev mode
function checkDuration (val, name, vnode) {
  if (typeof val !== 'number') {
    warn(
      "<transition> explicit " + name + " duration is not a valid number - " +
      "got " + (JSON.stringify(val)) + ".",
      vnode.context
    );
  } else if (isNaN(val)) {
    warn(
      "<transition> explicit " + name + " duration is NaN - " +
      'the duration expression might be incorrect.',
      vnode.context
    );
  }
}

function isValidDuration (val) {
  return typeof val === 'number' && !isNaN(val)
}

/**
 * Normalize a transition hook's argument length. The hook may be:
 * - a merged hook (invoker) with the original in .fns
 * - a wrapped component method (check ._length)
 * - a plain function (.length)
 */
function getHookArgumentsLength (fn) {
  if (isUndef(fn)) {
    return false
  }
  var invokerFns = fn.fns;
  if (isDef(invokerFns)) {
    // invoker
    return getHookArgumentsLength(
      Array.isArray(invokerFns)
        ? invokerFns[0]
        : invokerFns
    )
  } else {
    return (fn._length || fn.length) > 1
  }
}

function _enter (_, vnode) {
  if (vnode.data.show !== true) {
    enter(vnode);
  }
}

var transition = inBrowser ? {
  create: _enter,
  activate: _enter,
  remove: function remove$$1 (vnode, rm) {
    /* istanbul ignore else */
    if (vnode.data.show !== true) {
      leave(vnode, rm);
    } else {
      rm();
    }
  }
} : {};

var platformModules = [
  attrs,
  klass,
  events,
  domProps,
  style,
  transition
];

/*  */

// the directive module should be applied last, after all
// built-in modules have been applied.
var modules = platformModules.concat(baseModules);

var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });

/**
 * Not type checking this file because flow doesn't like attaching
 * properties to Elements.
 */

/* istanbul ignore if */
if (isIE9) {
  // http://www.matts411.com/post/internet-explorer-9-oninput/
  document.addEventListener('selectionchange', function () {
    var el = document.activeElement;
    if (el && el.vmodel) {
      trigger(el, 'input');
    }
  });
}

var directive = {
  inserted: function inserted (el, binding, vnode, oldVnode) {
    if (vnode.tag === 'select') {
      // #6903
      if (oldVnode.elm && !oldVnode.elm._vOptions) {
        mergeVNodeHook(vnode, 'postpatch', function () {
          directive.componentUpdated(el, binding, vnode);
        });
      } else {
        setSelected(el, binding, vnode.context);
      }
      el._vOptions = [].map.call(el.options, getValue);
    } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
      el._vModifiers = binding.modifiers;
      if (!binding.modifiers.lazy) {
        el.addEventListener('compositionstart', onCompositionStart);
        el.addEventListener('compositionend', onCompositionEnd);
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        el.addEventListener('change', onCompositionEnd);
        /* istanbul ignore if */
        if (isIE9) {
          el.vmodel = true;
        }
      }
    }
  },

  componentUpdated: function componentUpdated (el, binding, vnode) {
    if (vnode.tag === 'select') {
      setSelected(el, binding, vnode.context);
      // in case the options rendered by v-for have changed,
      // it's possible that the value is out-of-sync with the rendered options.
      // detect such cases and filter out values that no longer has a matching
      // option in the DOM.
      var prevOptions = el._vOptions;
      var curOptions = el._vOptions = [].map.call(el.options, getValue);
      if (curOptions.some(function (o, i) { return !looseEqual(o, prevOptions[i]); })) {
        // trigger change event if
        // no matching option found for at least one value
        var needReset = el.multiple
          ? binding.value.some(function (v) { return hasNoMatchingOption(v, curOptions); })
          : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions);
        if (needReset) {
          trigger(el, 'change');
        }
      }
    }
  }
};

function setSelected (el, binding, vm) {
  actuallySetSelected(el, binding, vm);
  /* istanbul ignore if */
  if (isIE || isEdge) {
    setTimeout(function () {
      actuallySetSelected(el, binding, vm);
    }, 0);
  }
}

function actuallySetSelected (el, binding, vm) {
  var value = binding.value;
  var isMultiple = el.multiple;
  if (isMultiple && !Array.isArray(value)) {
    warn(
      "<select multiple v-model=\"" + (binding.expression) + "\"> " +
      "expects an Array value for its binding, but got " + (Object.prototype.toString.call(value).slice(8, -1)),
      vm
    );
    return
  }
  var selected, option;
  for (var i = 0, l = el.options.length; i < l; i++) {
    option = el.options[i];
    if (isMultiple) {
      selected = looseIndexOf(value, getValue(option)) > -1;
      if (option.selected !== selected) {
        option.selected = selected;
      }
    } else {
      if (looseEqual(getValue(option), value)) {
        if (el.selectedIndex !== i) {
          el.selectedIndex = i;
        }
        return
      }
    }
  }
  if (!isMultiple) {
    el.selectedIndex = -1;
  }
}

function hasNoMatchingOption (value, options) {
  return options.every(function (o) { return !looseEqual(o, value); })
}

function getValue (option) {
  return '_value' in option
    ? option._value
    : option.value
}

function onCompositionStart (e) {
  e.target.composing = true;
}

function onCompositionEnd (e) {
  // prevent triggering an input event for no reason
  if (!e.target.composing) { return }
  e.target.composing = false;
  trigger(e.target, 'input');
}

function trigger (el, type) {
  var e = document.createEvent('HTMLEvents');
  e.initEvent(type, true, true);
  el.dispatchEvent(e);
}

/*  */

// recursively search for possible transition defined inside the component root
function locateNode (vnode) {
  return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
    ? locateNode(vnode.componentInstance._vnode)
    : vnode
}

var show = {
  bind: function bind (el, ref, vnode) {
    var value = ref.value;

    vnode = locateNode(vnode);
    var transition$$1 = vnode.data && vnode.data.transition;
    var originalDisplay = el.__vOriginalDisplay =
      el.style.display === 'none' ? '' : el.style.display;
    if (value && transition$$1) {
      vnode.data.show = true;
      enter(vnode, function () {
        el.style.display = originalDisplay;
      });
    } else {
      el.style.display = value ? originalDisplay : 'none';
    }
  },

  update: function update (el, ref, vnode) {
    var value = ref.value;
    var oldValue = ref.oldValue;

    /* istanbul ignore if */
    if (!value === !oldValue) { return }
    vnode = locateNode(vnode);
    var transition$$1 = vnode.data && vnode.data.transition;
    if (transition$$1) {
      vnode.data.show = true;
      if (value) {
        enter(vnode, function () {
          el.style.display = el.__vOriginalDisplay;
        });
      } else {
        leave(vnode, function () {
          el.style.display = 'none';
        });
      }
    } else {
      el.style.display = value ? el.__vOriginalDisplay : 'none';
    }
  },

  unbind: function unbind (
    el,
    binding,
    vnode,
    oldVnode,
    isDestroy
  ) {
    if (!isDestroy) {
      el.style.display = el.__vOriginalDisplay;
    }
  }
};

var platformDirectives = {
  model: directive,
  show: show
};

/*  */

var transitionProps = {
  name: String,
  appear: Boolean,
  css: Boolean,
  mode: String,
  type: String,
  enterClass: String,
  leaveClass: String,
  enterToClass: String,
  leaveToClass: String,
  enterActiveClass: String,
  leaveActiveClass: String,
  appearClass: String,
  appearActiveClass: String,
  appearToClass: String,
  duration: [Number, String, Object]
};

// in case the child is also an abstract component, e.g. <keep-alive>
// we want to recursively retrieve the real component to be rendered
function getRealChild (vnode) {
  var compOptions = vnode && vnode.componentOptions;
  if (compOptions && compOptions.Ctor.options.abstract) {
    return getRealChild(getFirstComponentChild(compOptions.children))
  } else {
    return vnode
  }
}

function extractTransitionData (comp) {
  var data = {};
  var options = comp.$options;
  // props
  for (var key in options.propsData) {
    data[key] = comp[key];
  }
  // events.
  // extract listeners and pass them directly to the transition methods
  var listeners = options._parentListeners;
  for (var key$1 in listeners) {
    data[camelize(key$1)] = listeners[key$1];
  }
  return data
}

function placeholder (h, rawChild) {
  if (/\d-keep-alive$/.test(rawChild.tag)) {
    return h('keep-alive', {
      props: rawChild.componentOptions.propsData
    })
  }
}

function hasParentTransition (vnode) {
  while ((vnode = vnode.parent)) {
    if (vnode.data.transition) {
      return true
    }
  }
}

function isSameChild (child, oldChild) {
  return oldChild.key === child.key && oldChild.tag === child.tag
}

var isNotTextNode = function (c) { return c.tag || isAsyncPlaceholder(c); };

var isVShowDirective = function (d) { return d.name === 'show'; };

var Transition = {
  name: 'transition',
  props: transitionProps,
  abstract: true,

  render: function render (h) {
    var this$1 = this;

    var children = this.$slots.default;
    if (!children) {
      return
    }

    // filter out text nodes (possible whitespaces)
    children = children.filter(isNotTextNode);
    /* istanbul ignore if */
    if (!children.length) {
      return
    }

    // warn multiple elements
    if (children.length > 1) {
      warn(
        '<transition> can only be used on a single element. Use ' +
        '<transition-group> for lists.',
        this.$parent
      );
    }

    var mode = this.mode;

    // warn invalid mode
    if (mode && mode !== 'in-out' && mode !== 'out-in'
    ) {
      warn(
        'invalid <transition> mode: ' + mode,
        this.$parent
      );
    }

    var rawChild = children[0];

    // if this is a component root node and the component's
    // parent container node also has transition, skip.
    if (hasParentTransition(this.$vnode)) {
      return rawChild
    }

    // apply transition data to child
    // use getRealChild() to ignore abstract components e.g. keep-alive
    var child = getRealChild(rawChild);
    /* istanbul ignore if */
    if (!child) {
      return rawChild
    }

    if (this._leaving) {
      return placeholder(h, rawChild)
    }

    // ensure a key that is unique to the vnode type and to this transition
    // component instance. This key will be used to remove pending leaving nodes
    // during entering.
    var id = "__transition-" + (this._uid) + "-";
    child.key = child.key == null
      ? child.isComment
        ? id + 'comment'
        : id + child.tag
      : isPrimitive(child.key)
        ? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
        : child.key;

    var data = (child.data || (child.data = {})).transition = extractTransitionData(this);
    var oldRawChild = this._vnode;
    var oldChild = getRealChild(oldRawChild);

    // mark v-show
    // so that the transition module can hand over the control to the directive
    if (child.data.directives && child.data.directives.some(isVShowDirective)) {
      child.data.show = true;
    }

    if (
      oldChild &&
      oldChild.data &&
      !isSameChild(child, oldChild) &&
      !isAsyncPlaceholder(oldChild) &&
      // #6687 component root is a comment node
      !(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment)
    ) {
      // replace old child transition data with fresh one
      // important for dynamic transitions!
      var oldData = oldChild.data.transition = extend({}, data);
      // handle transition mode
      if (mode === 'out-in') {
        // return placeholder node and queue update when leave finishes
        this._leaving = true;
        mergeVNodeHook(oldData, 'afterLeave', function () {
          this$1._leaving = false;
          this$1.$forceUpdate();
        });
        return placeholder(h, rawChild)
      } else if (mode === 'in-out') {
        if (isAsyncPlaceholder(child)) {
          return oldRawChild
        }
        var delayedLeave;
        var performLeave = function () { delayedLeave(); };
        mergeVNodeHook(data, 'afterEnter', performLeave);
        mergeVNodeHook(data, 'enterCancelled', performLeave);
        mergeVNodeHook(oldData, 'delayLeave', function (leave) { delayedLeave = leave; });
      }
    }

    return rawChild
  }
};

/*  */

var props = extend({
  tag: String,
  moveClass: String
}, transitionProps);

delete props.mode;

var TransitionGroup = {
  props: props,

  beforeMount: function beforeMount () {
    var this$1 = this;

    var update = this._update;
    this._update = function (vnode, hydrating) {
      var restoreActiveInstance = setActiveInstance(this$1);
      // force removing pass
      this$1.__patch__(
        this$1._vnode,
        this$1.kept,
        false, // hydrating
        true // removeOnly (!important, avoids unnecessary moves)
      );
      this$1._vnode = this$1.kept;
      restoreActiveInstance();
      update.call(this$1, vnode, hydrating);
    };
  },

  render: function render (h) {
    var tag = this.tag || this.$vnode.data.tag || 'span';
    var map = Object.create(null);
    var prevChildren = this.prevChildren = this.children;
    var rawChildren = this.$slots.default || [];
    var children = this.children = [];
    var transitionData = extractTransitionData(this);

    for (var i = 0; i < rawChildren.length; i++) {
      var c = rawChildren[i];
      if (c.tag) {
        if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
          children.push(c);
          map[c.key] = c
          ;(c.data || (c.data = {})).transition = transitionData;
        } else {
          var opts = c.componentOptions;
          var name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag;
          warn(("<transition-group> children must be keyed: <" + name + ">"));
        }
      }
    }

    if (prevChildren) {
      var kept = [];
      var removed = [];
      for (var i$1 = 0; i$1 < prevChildren.length; i$1++) {
        var c$1 = prevChildren[i$1];
        c$1.data.transition = transitionData;
        c$1.data.pos = c$1.elm.getBoundingClientRect();
        if (map[c$1.key]) {
          kept.push(c$1);
        } else {
          removed.push(c$1);
        }
      }
      this.kept = h(tag, null, kept);
      this.removed = removed;
    }

    return h(tag, null, children)
  },

  updated: function updated () {
    var children = this.prevChildren;
    var moveClass = this.moveClass || ((this.name || 'v') + '-move');
    if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
      return
    }

    // we divide the work into three loops to avoid mixing DOM reads and writes
    // in each iteration - which helps prevent layout thrashing.
    children.forEach(callPendingCbs);
    children.forEach(recordPosition);
    children.forEach(applyTranslation);

    // force reflow to put everything in position
    // assign to this to avoid being removed in tree-shaking
    // $flow-disable-line
    this._reflow = document.body.offsetHeight;

    children.forEach(function (c) {
      if (c.data.moved) {
        var el = c.elm;
        var s = el.style;
        addTransitionClass(el, moveClass);
        s.transform = s.WebkitTransform = s.transitionDuration = '';
        el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
          if (e && e.target !== el) {
            return
          }
          if (!e || /transform$/.test(e.propertyName)) {
            el.removeEventListener(transitionEndEvent, cb);
            el._moveCb = null;
            removeTransitionClass(el, moveClass);
          }
        });
      }
    });
  },

  methods: {
    hasMove: function hasMove (el, moveClass) {
      /* istanbul ignore if */
      if (!hasTransition) {
        return false
      }
      /* istanbul ignore if */
      if (this._hasMove) {
        return this._hasMove
      }
      // Detect whether an element with the move class applied has
      // CSS transitions. Since the element may be inside an entering
      // transition at this very moment, we make a clone of it and remove
      // all other transition classes applied to ensure only the move class
      // is applied.
      var clone = el.cloneNode();
      if (el._transitionClasses) {
        el._transitionClasses.forEach(function (cls) { removeClass(clone, cls); });
      }
      addClass(clone, moveClass);
      clone.style.display = 'none';
      this.$el.appendChild(clone);
      var info = getTransitionInfo(clone);
      this.$el.removeChild(clone);
      return (this._hasMove = info.hasTransform)
    }
  }
};

function callPendingCbs (c) {
  /* istanbul ignore if */
  if (c.elm._moveCb) {
    c.elm._moveCb();
  }
  /* istanbul ignore if */
  if (c.elm._enterCb) {
    c.elm._enterCb();
  }
}

function recordPosition (c) {
  c.data.newPos = c.elm.getBoundingClientRect();
}

function applyTranslation (c) {
  var oldPos = c.data.pos;
  var newPos = c.data.newPos;
  var dx = oldPos.left - newPos.left;
  var dy = oldPos.top - newPos.top;
  if (dx || dy) {
    c.data.moved = true;
    var s = c.elm.style;
    s.transform = s.WebkitTransform = "translate(" + dx + "px," + dy + "px)";
    s.transitionDuration = '0s';
  }
}

var platformComponents = {
  Transition: Transition,
  TransitionGroup: TransitionGroup
};

/*  */

// install platform specific utils
Vue.config.mustUseProp = mustUseProp;
Vue.config.isReservedTag = isReservedTag;
Vue.config.isReservedAttr = isReservedAttr;
Vue.config.getTagNamespace = getTagNamespace;
Vue.config.isUnknownElement = isUnknownElement;

// install platform runtime directives & components
extend(Vue.options.directives, platformDirectives);
extend(Vue.options.components, platformComponents);

// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop;

// public mount method
Vue.prototype.$mount = function (
  el,
  hydrating
) {
  el = el && inBrowser ? query(el) : undefined;
  return mountComponent(this, el, hydrating)
};

// devtools global hook
/* istanbul ignore next */
if (inBrowser) {
  setTimeout(function () {
    if (config.devtools) {
      if (devtools) {
        devtools.emit('init', Vue);
      } else {
        console[console.info ? 'info' : 'log'](
          'Download the Vue Devtools extension for a better development experience:\n' +
          'https://github.com/vuejs/vue-devtools'
        );
      }
    }
    if (config.productionTip !== false &&
      typeof console !== 'undefined'
    ) {
      console[console.info ? 'info' : 'log'](
        "You are running Vue in development mode.\n" +
        "Make sure to turn on production mode when deploying for production.\n" +
        "See more tips at https://vuejs.org/guide/deployment.html"
      );
    }
  }, 0);
}

/*  */

var defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;

var buildRegex = cached(function (delimiters) {
  var open = delimiters[0].replace(regexEscapeRE, '\\$&');
  var close = delimiters[1].replace(regexEscapeRE, '\\$&');
  return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
});



function parseText (
  text,
  delimiters
) {
  var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
  if (!tagRE.test(text)) {
    return
  }
  var tokens = [];
  var rawTokens = [];
  var lastIndex = tagRE.lastIndex = 0;
  var match, index, tokenValue;
  while ((match = tagRE.exec(text))) {
    index = match.index;
    // push text token
    if (index > lastIndex) {
      rawTokens.push(tokenValue = text.slice(lastIndex, index));
      tokens.push(JSON.stringify(tokenValue));
    }
    // tag token
    var exp = parseFilters(match[1].trim());
    tokens.push(("_s(" + exp + ")"));
    rawTokens.push({ '@binding': exp });
    lastIndex = index + match[0].length;
  }
  if (lastIndex < text.length) {
    rawTokens.push(tokenValue = text.slice(lastIndex));
    tokens.push(JSON.stringify(tokenValue));
  }
  return {
    expression: tokens.join('+'),
    tokens: rawTokens
  }
}

/*  */

function transformNode (el, options) {
  var warn = options.warn || baseWarn;
  var staticClass = getAndRemoveAttr(el, 'class');
  if (staticClass) {
    var res = parseText(staticClass, options.delimiters);
    if (res) {
      warn(
        "class=\"" + staticClass + "\": " +
        'Interpolation inside attributes has been removed. ' +
        'Use v-bind or the colon shorthand instead. For example, ' +
        'instead of <div class="{{ val }}">, use <div :class="val">.',
        el.rawAttrsMap['class']
      );
    }
  }
  if (staticClass) {
    el.staticClass = JSON.stringify(staticClass);
  }
  var classBinding = getBindingAttr(el, 'class', false /* getStatic */);
  if (classBinding) {
    el.classBinding = classBinding;
  }
}

function genData (el) {
  var data = '';
  if (el.staticClass) {
    data += "staticClass:" + (el.staticClass) + ",";
  }
  if (el.classBinding) {
    data += "class:" + (el.classBinding) + ",";
  }
  return data
}

var klass$1 = {
  staticKeys: ['staticClass'],
  transformNode: transformNode,
  genData: genData
};

/*  */

function transformNode$1 (el, options) {
  var warn = options.warn || baseWarn;
  var staticStyle = getAndRemoveAttr(el, 'style');
  if (staticStyle) {
    /* istanbul ignore if */
    {
      var res = parseText(staticStyle, options.delimiters);
      if (res) {
        warn(
          "style=\"" + staticStyle + "\": " +
          'Interpolation inside attributes has been removed. ' +
          'Use v-bind or the colon shorthand instead. For example, ' +
          'instead of <div style="{{ val }}">, use <div :style="val">.',
          el.rawAttrsMap['style']
        );
      }
    }
    el.staticStyle = JSON.stringify(parseStyleText(staticStyle));
  }

  var styleBinding = getBindingAttr(el, 'style', false /* getStatic */);
  if (styleBinding) {
    el.styleBinding = styleBinding;
  }
}

function genData$1 (el) {
  var data = '';
  if (el.staticStyle) {
    data += "staticStyle:" + (el.staticStyle) + ",";
  }
  if (el.styleBinding) {
    data += "style:(" + (el.styleBinding) + "),";
  }
  return data
}

var style$1 = {
  staticKeys: ['staticStyle'],
  transformNode: transformNode$1,
  genData: genData$1
};

/*  */

var decoder;

var he = {
  decode: function decode (html) {
    decoder = decoder || document.createElement('div');
    decoder.innerHTML = html;
    return decoder.textContent
  }
};

/*  */

var isUnaryTag = makeMap(
  'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
  'link,meta,param,source,track,wbr'
);

// Elements that you can, intentionally, leave open
// (and which close themselves)
var canBeLeftOpenTag = makeMap(
  'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'
);

// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
var isNonPhrasingTag = makeMap(
  'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
  'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
  'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
  'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
  'title,tr,track'
);

/**
 * Not type-checking this file because it's mostly vendor code.
 */

// Regular Expressions for parsing tags and attributes
var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
var dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + (unicodeRegExp.source) + "]*";
var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
var startTagOpen = new RegExp(("^<" + qnameCapture));
var startTagClose = /^\s*(\/?)>/;
var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));
var doctype = /^<!DOCTYPE [^>]+>/i;
// #7298: escape - to avoid being passed as HTML comment when inlined in page
var comment = /^<!\--/;
var conditionalComment = /^<!\[/;

// Special Elements (can contain anything)
var isPlainTextElement = makeMap('script,style,textarea', true);
var reCache = {};

var decodingMap = {
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&amp;': '&',
  '&#10;': '\n',
  '&#9;': '\t',
  '&#39;': "'"
};
var encodedAttr = /&(?:lt|gt|quot|amp|#39);/g;
var encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#39|#10|#9);/g;

// #5992
var isIgnoreNewlineTag = makeMap('pre,textarea', true);
var shouldIgnoreFirstNewline = function (tag, html) { return tag && isIgnoreNewlineTag(tag) && html[0] === '\n'; };

function decodeAttr (value, shouldDecodeNewlines) {
  var re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr;
  return value.replace(re, function (match) { return decodingMap[match]; })
}

function parseHTML (html, options) {
  var stack = [];
  var expectHTML = options.expectHTML;
  var isUnaryTag$$1 = options.isUnaryTag || no;
  var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
  var index = 0;
  var last, lastTag;
  while (html) {
    last = html;
    // Make sure we're not in a plaintext content element like script/style
    if (!lastTag || !isPlainTextElement(lastTag)) {
      var textEnd = html.indexOf('<');
      if (textEnd === 0) {
        // Comment:
        if (comment.test(html)) {
          var commentEnd = html.indexOf('-->');

          if (commentEnd >= 0) {
            if (options.shouldKeepComment) {
              options.comment(html.substring(4, commentEnd), index, index + commentEnd + 3);
            }
            advance(commentEnd + 3);
            continue
          }
        }

        // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
        if (conditionalComment.test(html)) {
          var conditionalEnd = html.indexOf(']>');

          if (conditionalEnd >= 0) {
            advance(conditionalEnd + 2);
            continue
          }
        }

        // Doctype:
        var doctypeMatch = html.match(doctype);
        if (doctypeMatch) {
          advance(doctypeMatch[0].length);
          continue
        }

        // End tag:
        var endTagMatch = html.match(endTag);
        if (endTagMatch) {
          var curIndex = index;
          advance(endTagMatch[0].length);
          parseEndTag(endTagMatch[1], curIndex, index);
          continue
        }

        // Start tag:
        var startTagMatch = parseStartTag();
        if (startTagMatch) {
          handleStartTag(startTagMatch);
          if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
            advance(1);
          }
          continue
        }
      }

      var text = (void 0), rest = (void 0), next = (void 0);
      if (textEnd >= 0) {
        rest = html.slice(textEnd);
        while (
          !endTag.test(rest) &&
          !startTagOpen.test(rest) &&
          !comment.test(rest) &&
          !conditionalComment.test(rest)
        ) {
          // < in plain text, be forgiving and treat it as text
          next = rest.indexOf('<', 1);
          if (next < 0) { break }
          textEnd += next;
          rest = html.slice(textEnd);
        }
        text = html.substring(0, textEnd);
      }

      if (textEnd < 0) {
        text = html;
      }

      if (text) {
        advance(text.length);
      }

      if (options.chars && text) {
        options.chars(text, index - text.length, index);
      }
    } else {
      var endTagLength = 0;
      var stackedTag = lastTag.toLowerCase();
      var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'));
      var rest$1 = html.replace(reStackedTag, function (all, text, endTag) {
        endTagLength = endTag.length;
        if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
          text = text
            .replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298
            .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
        }
        if (shouldIgnoreFirstNewline(stackedTag, text)) {
          text = text.slice(1);
        }
        if (options.chars) {
          options.chars(text);
        }
        return ''
      });
      index += html.length - rest$1.length;
      html = rest$1;
      parseEndTag(stackedTag, index - endTagLength, index);
    }

    if (html === last) {
      options.chars && options.chars(html);
      if (!stack.length && options.warn) {
        options.warn(("Mal-formatted tag at end of template: \"" + html + "\""), { start: index + html.length });
      }
      break
    }
  }

  // Clean up any remaining tags
  parseEndTag();

  function advance (n) {
    index += n;
    html = html.substring(n);
  }

  function parseStartTag () {
    var start = html.match(startTagOpen);
    if (start) {
      var match = {
        tagName: start[1],
        attrs: [],
        start: index
      };
      advance(start[0].length);
      var end, attr;
      while (!(end = html.match(startTagClose)) && (attr = html.match(dynamicArgAttribute) || html.match(attribute))) {
        attr.start = index;
        advance(attr[0].length);
        attr.end = index;
        match.attrs.push(attr);
      }
      if (end) {
        match.unarySlash = end[1];
        advance(end[0].length);
        match.end = index;
        return match
      }
    }
  }

  function handleStartTag (match) {
    var tagName = match.tagName;
    var unarySlash = match.unarySlash;

    if (expectHTML) {
      if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
        parseEndTag(lastTag);
      }
      if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {
        parseEndTag(tagName);
      }
    }

    var unary = isUnaryTag$$1(tagName) || !!unarySlash;

    var l = match.attrs.length;
    var attrs = new Array(l);
    for (var i = 0; i < l; i++) {
      var args = match.attrs[i];
      var value = args[3] || args[4] || args[5] || '';
      var shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
        ? options.shouldDecodeNewlinesForHref
        : options.shouldDecodeNewlines;
      attrs[i] = {
        name: args[1],
        value: decodeAttr(value, shouldDecodeNewlines)
      };
      if (options.outputSourceRange) {
        attrs[i].start = args.start + args[0].match(/^\s*/).length;
        attrs[i].end = args.end;
      }
    }

    if (!unary) {
      stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end });
      lastTag = tagName;
    }

    if (options.start) {
      options.start(tagName, attrs, unary, match.start, match.end);
    }
  }

  function parseEndTag (tagName, start, end) {
    var pos, lowerCasedTagName;
    if (start == null) { start = index; }
    if (end == null) { end = index; }

    // Find the closest opened tag of the same type
    if (tagName) {
      lowerCasedTagName = tagName.toLowerCase();
      for (pos = stack.length - 1; pos >= 0; pos--) {
        if (stack[pos].lowerCasedTag === lowerCasedTagName) {
          break
        }
      }
    } else {
      // If no tag name is provided, clean shop
      pos = 0;
    }

    if (pos >= 0) {
      // Close all the open elements, up the stack
      for (var i = stack.length - 1; i >= pos; i--) {
        if (i > pos || !tagName &&
          options.warn
        ) {
          options.warn(
            ("tag <" + (stack[i].tag) + "> has no matching end tag."),
            { start: stack[i].start, end: stack[i].end }
          );
        }
        if (options.end) {
          options.end(stack[i].tag, start, end);
        }
      }

      // Remove the open elements from the stack
      stack.length = pos;
      lastTag = pos && stack[pos - 1].tag;
    } else if (lowerCasedTagName === 'br') {
      if (options.start) {
        options.start(tagName, [], true, start, end);
      }
    } else if (lowerCasedTagName === 'p') {
      if (options.start) {
        options.start(tagName, [], false, start, end);
      }
      if (options.end) {
        options.end(tagName, start, end);
      }
    }
  }
}

/*  */

var onRE = /^@|^v-on:/;
var dirRE = /^v-|^@|^:|^#/;
var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
var stripParensRE = /^\(|\)$/g;
var dynamicArgRE = /^\[.*\]$/;

var argRE = /:(.*)$/;
var bindRE = /^:|^\.|^v-bind:/;
var modifierRE = /\.[^.\]]+(?=[^\]]*$)/g;

var slotRE = /^v-slot(:|$)|^#/;

var lineBreakRE = /[\r\n]/;
var whitespaceRE$1 = /\s+/g;

var invalidAttributeRE = /[\s"'<>\/=]/;

var decodeHTMLCached = cached(he.decode);

var emptySlotScopeToken = "_empty_";

// configurable state
var warn$2;
var delimiters;
var transforms;
var preTransforms;
var postTransforms;
var platformIsPreTag;
var platformMustUseProp;
var platformGetTagNamespace;
var maybeComponent;

function createASTElement (
  tag,
  attrs,
  parent
) {
  return {
    type: 1,
    tag: tag,
    attrsList: attrs,
    attrsMap: makeAttrsMap(attrs),
    rawAttrsMap: {},
    parent: parent,
    children: []
  }
}

/**
 * Convert HTML string to AST.
 */
function parse (
  template,
  options
) {
  warn$2 = options.warn || baseWarn;

  platformIsPreTag = options.isPreTag || no;
  platformMustUseProp = options.mustUseProp || no;
  platformGetTagNamespace = options.getTagNamespace || no;
  var isReservedTag = options.isReservedTag || no;
  maybeComponent = function (el) { return !!el.component || !isReservedTag(el.tag); };

  transforms = pluckModuleFunction(options.modules, 'transformNode');
  preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
  postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');

  delimiters = options.delimiters;

  var stack = [];
  var preserveWhitespace = options.preserveWhitespace !== false;
  var whitespaceOption = options.whitespace;
  var root;
  var currentParent;
  var inVPre = false;
  var inPre = false;
  var warned = false;

  function warnOnce (msg, range) {
    if (!warned) {
      warned = true;
      warn$2(msg, range);
    }
  }

  function closeElement (element) {
    trimEndingWhitespace(element);
    if (!inVPre && !element.processed) {
      element = processElement(element, options);
    }
    // tree management
    if (!stack.length && element !== root) {
      // allow root elements with v-if, v-else-if and v-else
      if (root.if && (element.elseif || element.else)) {
        {
          checkRootConstraints(element);
        }
        addIfCondition(root, {
          exp: element.elseif,
          block: element
        });
      } else {
        warnOnce(
          "Component template should contain exactly one root element. " +
          "If you are using v-if on multiple elements, " +
          "use v-else-if to chain them instead.",
          { start: element.start }
        );
      }
    }
    if (currentParent && !element.forbidden) {
      if (element.elseif || element.else) {
        processIfConditions(element, currentParent);
      } else {
        if (element.slotScope) {
          // scoped slot
          // keep it in the children list so that v-else(-if) conditions can
          // find it as the prev node.
          var name = element.slotTarget || '"default"'
          ;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;
        }
        currentParent.children.push(element);
        element.parent = currentParent;
      }
    }

    // final children cleanup
    // filter out scoped slots
    element.children = element.children.filter(function (c) { return !(c).slotScope; });
    // remove trailing whitespace node again
    trimEndingWhitespace(element);

    // check pre state
    if (element.pre) {
      inVPre = false;
    }
    if (platformIsPreTag(element.tag)) {
      inPre = false;
    }
    // apply post-transforms
    for (var i = 0; i < postTransforms.length; i++) {
      postTransforms[i](element, options);
    }
  }

  function trimEndingWhitespace (el) {
    // remove trailing whitespace node
    if (!inPre) {
      var lastNode;
      while (
        (lastNode = el.children[el.children.length - 1]) &&
        lastNode.type === 3 &&
        lastNode.text === ' '
      ) {
        el.children.pop();
      }
    }
  }

  function checkRootConstraints (el) {
    if (el.tag === 'slot' || el.tag === 'template') {
      warnOnce(
        "Cannot use <" + (el.tag) + "> as component root element because it may " +
        'contain multiple nodes.',
        { start: el.start }
      );
    }
    if (el.attrsMap.hasOwnProperty('v-for')) {
      warnOnce(
        'Cannot use v-for on stateful component root element because ' +
        'it renders multiple elements.',
        el.rawAttrsMap['v-for']
      );
    }
  }

  parseHTML(template, {
    warn: warn$2,
    expectHTML: options.expectHTML,
    isUnaryTag: options.isUnaryTag,
    canBeLeftOpenTag: options.canBeLeftOpenTag,
    shouldDecodeNewlines: options.shouldDecodeNewlines,
    shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
    shouldKeepComment: options.comments,
    outputSourceRange: options.outputSourceRange,
    start: function start (tag, attrs, unary, start$1, end) {
      // check namespace.
      // inherit parent ns if there is one
      var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);

      // handle IE svg bug
      /* istanbul ignore if */
      if (isIE && ns === 'svg') {
        attrs = guardIESVGBug(attrs);
      }

      var element = createASTElement(tag, attrs, currentParent);
      if (ns) {
        element.ns = ns;
      }

      {
        if (options.outputSourceRange) {
          element.start = start$1;
          element.end = end;
          element.rawAttrsMap = element.attrsList.reduce(function (cumulated, attr) {
            cumulated[attr.name] = attr;
            return cumulated
          }, {});
        }
        attrs.forEach(function (attr) {
          if (invalidAttributeRE.test(attr.name)) {
            warn$2(
              "Invalid dynamic argument expression: attribute names cannot contain " +
              "spaces, quotes, <, >, / or =.",
              {
                start: attr.start + attr.name.indexOf("["),
                end: attr.start + attr.name.length
              }
            );
          }
        });
      }

      if (isForbiddenTag(element) && !isServerRendering()) {
        element.forbidden = true;
        warn$2(
          'Templates should only be responsible for mapping the state to the ' +
          'UI. Avoid placing tags with side-effects in your templates, such as ' +
          "<" + tag + ">" + ', as they will not be parsed.',
          { start: element.start }
        );
      }

      // apply pre-transforms
      for (var i = 0; i < preTransforms.length; i++) {
        element = preTransforms[i](element, options) || element;
      }

      if (!inVPre) {
        processPre(element);
        if (element.pre) {
          inVPre = true;
        }
      }
      if (platformIsPreTag(element.tag)) {
        inPre = true;
      }
      if (inVPre) {
        processRawAttrs(element);
      } else if (!element.processed) {
        // structural directives
        processFor(element);
        processIf(element);
        processOnce(element);
      }

      if (!root) {
        root = element;
        {
          checkRootConstraints(root);
        }
      }

      if (!unary) {
        currentParent = element;
        stack.push(element);
      } else {
        closeElement(element);
      }
    },

    end: function end (tag, start, end$1) {
      var element = stack[stack.length - 1];
      // pop stack
      stack.length -= 1;
      currentParent = stack[stack.length - 1];
      if (options.outputSourceRange) {
        element.end = end$1;
      }
      closeElement(element);
    },

    chars: function chars (text, start, end) {
      if (!currentParent) {
        {
          if (text === template) {
            warnOnce(
              'Component template requires a root element, rather than just text.',
              { start: start }
            );
          } else if ((text = text.trim())) {
            warnOnce(
              ("text \"" + text + "\" outside root element will be ignored."),
              { start: start }
            );
          }
        }
        return
      }
      // IE textarea placeholder bug
      /* istanbul ignore if */
      if (isIE &&
        currentParent.tag === 'textarea' &&
        currentParent.attrsMap.placeholder === text
      ) {
        return
      }
      var children = currentParent.children;
      if (inPre || text.trim()) {
        text = isTextTag(currentParent) ? text : decodeHTMLCached(text);
      } else if (!children.length) {
        // remove the whitespace-only node right after an opening tag
        text = '';
      } else if (whitespaceOption) {
        if (whitespaceOption === 'condense') {
          // in condense mode, remove the whitespace node if it contains
          // line break, otherwise condense to a single space
          text = lineBreakRE.test(text) ? '' : ' ';
        } else {
          text = ' ';
        }
      } else {
        text = preserveWhitespace ? ' ' : '';
      }
      if (text) {
        if (!inPre && whitespaceOption === 'condense') {
          // condense consecutive whitespaces into single space
          text = text.replace(whitespaceRE$1, ' ');
        }
        var res;
        var child;
        if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
          child = {
            type: 2,
            expression: res.expression,
            tokens: res.tokens,
            text: text
          };
        } else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {
          child = {
            type: 3,
            text: text
          };
        }
        if (child) {
          if (options.outputSourceRange) {
            child.start = start;
            child.end = end;
          }
          children.push(child);
        }
      }
    },
    comment: function comment (text, start, end) {
      // adding anything as a sibling to the root node is forbidden
      // comments should still be allowed, but ignored
      if (currentParent) {
        var child = {
          type: 3,
          text: text,
          isComment: true
        };
        if (options.outputSourceRange) {
          child.start = start;
          child.end = end;
        }
        currentParent.children.push(child);
      }
    }
  });
  return root
}

function processPre (el) {
  if (getAndRemoveAttr(el, 'v-pre') != null) {
    el.pre = true;
  }
}

function processRawAttrs (el) {
  var list = el.attrsList;
  var len = list.length;
  if (len) {
    var attrs = el.attrs = new Array(len);
    for (var i = 0; i < len; i++) {
      attrs[i] = {
        name: list[i].name,
        value: JSON.stringify(list[i].value)
      };
      if (list[i].start != null) {
        attrs[i].start = list[i].start;
        attrs[i].end = list[i].end;
      }
    }
  } else if (!el.pre) {
    // non root node in pre blocks with no attributes
    el.plain = true;
  }
}

function processElement (
  element,
  options
) {
  processKey(element);

  // determine whether this is a plain element after
  // removing structural attributes
  element.plain = (
    !element.key &&
    !element.scopedSlots &&
    !element.attrsList.length
  );

  processRef(element);
  processSlotContent(element);
  processSlotOutlet(element);
  processComponent(element);
  for (var i = 0; i < transforms.length; i++) {
    element = transforms[i](element, options) || element;
  }
  processAttrs(element);
  return element
}

function processKey (el) {
  var exp = getBindingAttr(el, 'key');
  if (exp) {
    {
      if (el.tag === 'template') {
        warn$2(
          "<template> cannot be keyed. Place the key on real elements instead.",
          getRawBindingAttr(el, 'key')
        );
      }
      if (el.for) {
        var iterator = el.iterator2 || el.iterator1;
        var parent = el.parent;
        if (iterator && iterator === exp && parent && parent.tag === 'transition-group') {
          warn$2(
            "Do not use v-for index as key on <transition-group> children, " +
            "this is the same as not using keys.",
            getRawBindingAttr(el, 'key'),
            true /* tip */
          );
        }
      }
    }
    el.key = exp;
  }
}

function processRef (el) {
  var ref = getBindingAttr(el, 'ref');
  if (ref) {
    el.ref = ref;
    el.refInFor = checkInFor(el);
  }
}

function processFor (el) {
  var exp;
  if ((exp = getAndRemoveAttr(el, 'v-for'))) {
    var res = parseFor(exp);
    if (res) {
      extend(el, res);
    } else {
      warn$2(
        ("Invalid v-for expression: " + exp),
        el.rawAttrsMap['v-for']
      );
    }
  }
}



function parseFor (exp) {
  var inMatch = exp.match(forAliasRE);
  if (!inMatch) { return }
  var res = {};
  res.for = inMatch[2].trim();
  var alias = inMatch[1].trim().replace(stripParensRE, '');
  var iteratorMatch = alias.match(forIteratorRE);
  if (iteratorMatch) {
    res.alias = alias.replace(forIteratorRE, '').trim();
    res.iterator1 = iteratorMatch[1].trim();
    if (iteratorMatch[2]) {
      res.iterator2 = iteratorMatch[2].trim();
    }
  } else {
    res.alias = alias;
  }
  return res
}

function processIf (el) {
  var exp = getAndRemoveAttr(el, 'v-if');
  if (exp) {
    el.if = exp;
    addIfCondition(el, {
      exp: exp,
      block: el
    });
  } else {
    if (getAndRemoveAttr(el, 'v-else') != null) {
      el.else = true;
    }
    var elseif = getAndRemoveAttr(el, 'v-else-if');
    if (elseif) {
      el.elseif = elseif;
    }
  }
}

function processIfConditions (el, parent) {
  var prev = findPrevElement(parent.children);
  if (prev && prev.if) {
    addIfCondition(prev, {
      exp: el.elseif,
      block: el
    });
  } else {
    warn$2(
      "v-" + (el.elseif ? ('else-if="' + el.elseif + '"') : 'else') + " " +
      "used on element <" + (el.tag) + "> without corresponding v-if.",
      el.rawAttrsMap[el.elseif ? 'v-else-if' : 'v-else']
    );
  }
}

function findPrevElement (children) {
  var i = children.length;
  while (i--) {
    if (children[i].type === 1) {
      return children[i]
    } else {
      if (children[i].text !== ' ') {
        warn$2(
          "text \"" + (children[i].text.trim()) + "\" between v-if and v-else(-if) " +
          "will be ignored.",
          children[i]
        );
      }
      children.pop();
    }
  }
}

function addIfCondition (el, condition) {
  if (!el.ifConditions) {
    el.ifConditions = [];
  }
  el.ifConditions.push(condition);
}

function processOnce (el) {
  var once$$1 = getAndRemoveAttr(el, 'v-once');
  if (once$$1 != null) {
    el.once = true;
  }
}

// handle content being passed to a component as slot,
// e.g. <template slot="xxx">, <div slot-scope="xxx">
function processSlotContent (el) {
  var slotScope;
  if (el.tag === 'template') {
    slotScope = getAndRemoveAttr(el, 'scope');
    /* istanbul ignore if */
    if (slotScope) {
      warn$2(
        "the \"scope\" attribute for scoped slots have been deprecated and " +
        "replaced by \"slot-scope\" since 2.5. The new \"slot-scope\" attribute " +
        "can also be used on plain elements in addition to <template> to " +
        "denote scoped slots.",
        el.rawAttrsMap['scope'],
        true
      );
    }
    el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope');
  } else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) {
    /* istanbul ignore if */
    if (el.attrsMap['v-for']) {
      warn$2(
        "Ambiguous combined usage of slot-scope and v-for on <" + (el.tag) + "> " +
        "(v-for takes higher priority). Use a wrapper <template> for the " +
        "scoped slot to make it clearer.",
        el.rawAttrsMap['slot-scope'],
        true
      );
    }
    el.slotScope = slotScope;
  }

  // slot="xxx"
  var slotTarget = getBindingAttr(el, 'slot');
  if (slotTarget) {
    el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget;
    el.slotTargetDynamic = !!(el.attrsMap[':slot'] || el.attrsMap['v-bind:slot']);
    // preserve slot as an attribute for native shadow DOM compat
    // only for non-scoped slots.
    if (el.tag !== 'template' && !el.slotScope) {
      addAttr(el, 'slot', slotTarget, getRawBindingAttr(el, 'slot'));
    }
  }

  // 2.6 v-slot syntax
  {
    if (el.tag === 'template') {
      // v-slot on <template>
      var slotBinding = getAndRemoveAttrByRegex(el, slotRE);
      if (slotBinding) {
        {
          if (el.slotTarget || el.slotScope) {
            warn$2(
              "Unexpected mixed usage of different slot syntaxes.",
              el
            );
          }
          if (el.parent && !maybeComponent(el.parent)) {
            warn$2(
              "<template v-slot> can only appear at the root level inside " +
              "the receiving component",
              el
            );
          }
        }
        var ref = getSlotName(slotBinding);
        var name = ref.name;
        var dynamic = ref.dynamic;
        el.slotTarget = name;
        el.slotTargetDynamic = dynamic;
        el.slotScope = slotBinding.value || emptySlotScopeToken; // force it into a scoped slot for perf
      }
    } else {
      // v-slot on component, denotes default slot
      var slotBinding$1 = getAndRemoveAttrByRegex(el, slotRE);
      if (slotBinding$1) {
        {
          if (!maybeComponent(el)) {
            warn$2(
              "v-slot can only be used on components or <template>.",
              slotBinding$1
            );
          }
          if (el.slotScope || el.slotTarget) {
            warn$2(
              "Unexpected mixed usage of different slot syntaxes.",
              el
            );
          }
          if (el.scopedSlots) {
            warn$2(
              "To avoid scope ambiguity, the default slot should also use " +
              "<template> syntax when there are other named slots.",
              slotBinding$1
            );
          }
        }
        // add the component's children to its default slot
        var slots = el.scopedSlots || (el.scopedSlots = {});
        var ref$1 = getSlotName(slotBinding$1);
        var name$1 = ref$1.name;
        var dynamic$1 = ref$1.dynamic;
        var slotContainer = slots[name$1] = createASTElement('template', [], el);
        slotContainer.slotTarget = name$1;
        slotContainer.slotTargetDynamic = dynamic$1;
        slotContainer.children = el.children.filter(function (c) {
          if (!c.slotScope) {
            c.parent = slotContainer;
            return true
          }
        });
        slotContainer.slotScope = slotBinding$1.value || emptySlotScopeToken;
        // remove children as they are returned from scopedSlots now
        el.children = [];
        // mark el non-plain so data gets generated
        el.plain = false;
      }
    }
  }
}

function getSlotName (binding) {
  var name = binding.name.replace(slotRE, '');
  if (!name) {
    if (binding.name[0] !== '#') {
      name = 'default';
    } else {
      warn$2(
        "v-slot shorthand syntax requires a slot name.",
        binding
      );
    }
  }
  return dynamicArgRE.test(name)
    // dynamic [name]
    ? { name: name.slice(1, -1), dynamic: true }
    // static name
    : { name: ("\"" + name + "\""), dynamic: false }
}

// handle <slot/> outlets
function processSlotOutlet (el) {
  if (el.tag === 'slot') {
    el.slotName = getBindingAttr(el, 'name');
    if (el.key) {
      warn$2(
        "`key` does not work on <slot> because slots are abstract outlets " +
        "and can possibly expand into multiple elements. " +
        "Use the key on a wrapping element instead.",
        getRawBindingAttr(el, 'key')
      );
    }
  }
}

function processComponent (el) {
  var binding;
  if ((binding = getBindingAttr(el, 'is'))) {
    el.component = binding;
  }
  if (getAndRemoveAttr(el, 'inline-template') != null) {
    el.inlineTemplate = true;
  }
}

function processAttrs (el) {
  var list = el.attrsList;
  var i, l, name, rawName, value, modifiers, syncGen, isDynamic;
  for (i = 0, l = list.length; i < l; i++) {
    name = rawName = list[i].name;
    value = list[i].value;
    if (dirRE.test(name)) {
      // mark element as dynamic
      el.hasBindings = true;
      // modifiers
      modifiers = parseModifiers(name.replace(dirRE, ''));
      // support .foo shorthand syntax for the .prop modifier
      if (modifiers) {
        name = name.replace(modifierRE, '');
      }
      if (bindRE.test(name)) { // v-bind
        name = name.replace(bindRE, '');
        value = parseFilters(value);
        isDynamic = dynamicArgRE.test(name);
        if (isDynamic) {
          name = name.slice(1, -1);
        }
        if (
          value.trim().length === 0
        ) {
          warn$2(
            ("The value for a v-bind expression cannot be empty. Found in \"v-bind:" + name + "\"")
          );
        }
        if (modifiers) {
          if (modifiers.prop && !isDynamic) {
            name = camelize(name);
            if (name === 'innerHtml') { name = 'innerHTML'; }
          }
          if (modifiers.camel && !isDynamic) {
            name = camelize(name);
          }
          if (modifiers.sync) {
            syncGen = genAssignmentCode(value, "$event");
            if (!isDynamic) {
              addHandler(
                el,
                ("update:" + (camelize(name))),
                syncGen,
                null,
                false,
                warn$2,
                list[i]
              );
              if (hyphenate(name) !== camelize(name)) {
                addHandler(
                  el,
                  ("update:" + (hyphenate(name))),
                  syncGen,
                  null,
                  false,
                  warn$2,
                  list[i]
                );
              }
            } else {
              // handler w/ dynamic event name
              addHandler(
                el,
                ("\"update:\"+(" + name + ")"),
                syncGen,
                null,
                false,
                warn$2,
                list[i],
                true // dynamic
              );
            }
          }
        }
        if ((modifiers && modifiers.prop) || (
          !el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
        )) {
          addProp(el, name, value, list[i], isDynamic);
        } else {
          addAttr(el, name, value, list[i], isDynamic);
        }
      } else if (onRE.test(name)) { // v-on
        name = name.replace(onRE, '');
        isDynamic = dynamicArgRE.test(name);
        if (isDynamic) {
          name = name.slice(1, -1);
        }
        addHandler(el, name, value, modifiers, false, warn$2, list[i], isDynamic);
      } else { // normal directives
        name = name.replace(dirRE, '');
        // parse arg
        var argMatch = name.match(argRE);
        var arg = argMatch && argMatch[1];
        isDynamic = false;
        if (arg) {
          name = name.slice(0, -(arg.length + 1));
          if (dynamicArgRE.test(arg)) {
            arg = arg.slice(1, -1);
            isDynamic = true;
          }
        }
        addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i]);
        if (name === 'model') {
          checkForAliasModel(el, value);
        }
      }
    } else {
      // literal attribute
      {
        var res = parseText(value, delimiters);
        if (res) {
          warn$2(
            name + "=\"" + value + "\": " +
            'Interpolation inside attributes has been removed. ' +
            'Use v-bind or the colon shorthand instead. For example, ' +
            'instead of <div id="{{ val }}">, use <div :id="val">.',
            list[i]
          );
        }
      }
      addAttr(el, name, JSON.stringify(value), list[i]);
      // #6887 firefox doesn't update muted state if set via attribute
      // even immediately after element creation
      if (!el.component &&
          name === 'muted' &&
          platformMustUseProp(el.tag, el.attrsMap.type, name)) {
        addProp(el, name, 'true', list[i]);
      }
    }
  }
}

function checkInFor (el) {
  var parent = el;
  while (parent) {
    if (parent.for !== undefined) {
      return true
    }
    parent = parent.parent;
  }
  return false
}

function parseModifiers (name) {
  var match = name.match(modifierRE);
  if (match) {
    var ret = {};
    match.forEach(function (m) { ret[m.slice(1)] = true; });
    return ret
  }
}

function makeAttrsMap (attrs) {
  var map = {};
  for (var i = 0, l = attrs.length; i < l; i++) {
    if (
      map[attrs[i].name] && !isIE && !isEdge
    ) {
      warn$2('duplicate attribute: ' + attrs[i].name, attrs[i]);
    }
    map[attrs[i].name] = attrs[i].value;
  }
  return map
}

// for script (e.g. type="x/template") or style, do not decode content
function isTextTag (el) {
  return el.tag === 'script' || el.tag === 'style'
}

function isForbiddenTag (el) {
  return (
    el.tag === 'style' ||
    (el.tag === 'script' && (
      !el.attrsMap.type ||
      el.attrsMap.type === 'text/javascript'
    ))
  )
}

var ieNSBug = /^xmlns:NS\d+/;
var ieNSPrefix = /^NS\d+:/;

/* istanbul ignore next */
function guardIESVGBug (attrs) {
  var res = [];
  for (var i = 0; i < attrs.length; i++) {
    var attr = attrs[i];
    if (!ieNSBug.test(attr.name)) {
      attr.name = attr.name.replace(ieNSPrefix, '');
      res.push(attr);
    }
  }
  return res
}

function checkForAliasModel (el, value) {
  var _el = el;
  while (_el) {
    if (_el.for && _el.alias === value) {
      warn$2(
        "<" + (el.tag) + " v-model=\"" + value + "\">: " +
        "You are binding v-model directly to a v-for iteration alias. " +
        "This will not be able to modify the v-for source array because " +
        "writing to the alias is like modifying a function local variable. " +
        "Consider using an array of objects and use v-model on an object property instead.",
        el.rawAttrsMap['v-model']
      );
    }
    _el = _el.parent;
  }
}

/*  */

function preTransformNode (el, options) {
  if (el.tag === 'input') {
    var map = el.attrsMap;
    if (!map['v-model']) {
      return
    }

    var typeBinding;
    if (map[':type'] || map['v-bind:type']) {
      typeBinding = getBindingAttr(el, 'type');
    }
    if (!map.type && !typeBinding && map['v-bind']) {
      typeBinding = "(" + (map['v-bind']) + ").type";
    }

    if (typeBinding) {
      var ifCondition = getAndRemoveAttr(el, 'v-if', true);
      var ifConditionExtra = ifCondition ? ("&&(" + ifCondition + ")") : "";
      var hasElse = getAndRemoveAttr(el, 'v-else', true) != null;
      var elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true);
      // 1. checkbox
      var branch0 = cloneASTElement(el);
      // process for on the main node
      processFor(branch0);
      addRawAttr(branch0, 'type', 'checkbox');
      processElement(branch0, options);
      branch0.processed = true; // prevent it from double-processed
      branch0.if = "(" + typeBinding + ")==='checkbox'" + ifConditionExtra;
      addIfCondition(branch0, {
        exp: branch0.if,
        block: branch0
      });
      // 2. add radio else-if condition
      var branch1 = cloneASTElement(el);
      getAndRemoveAttr(branch1, 'v-for', true);
      addRawAttr(branch1, 'type', 'radio');
      processElement(branch1, options);
      addIfCondition(branch0, {
        exp: "(" + typeBinding + ")==='radio'" + ifConditionExtra,
        block: branch1
      });
      // 3. other
      var branch2 = cloneASTElement(el);
      getAndRemoveAttr(branch2, 'v-for', true);
      addRawAttr(branch2, ':type', typeBinding);
      processElement(branch2, options);
      addIfCondition(branch0, {
        exp: ifCondition,
        block: branch2
      });

      if (hasElse) {
        branch0.else = true;
      } else if (elseIfCondition) {
        branch0.elseif = elseIfCondition;
      }

      return branch0
    }
  }
}

function cloneASTElement (el) {
  return createASTElement(el.tag, el.attrsList.slice(), el.parent)
}

var model$1 = {
  preTransformNode: preTransformNode
};

var modules$1 = [
  klass$1,
  style$1,
  model$1
];

/*  */

function text (el, dir) {
  if (dir.value) {
    addProp(el, 'textContent', ("_s(" + (dir.value) + ")"), dir);
  }
}

/*  */

function html (el, dir) {
  if (dir.value) {
    addProp(el, 'innerHTML', ("_s(" + (dir.value) + ")"), dir);
  }
}

var directives$1 = {
  model: model,
  text: text,
  html: html
};

/*  */

var baseOptions = {
  expectHTML: true,
  modules: modules$1,
  directives: directives$1,
  isPreTag: isPreTag,
  isUnaryTag: isUnaryTag,
  mustUseProp: mustUseProp,
  canBeLeftOpenTag: canBeLeftOpenTag,
  isReservedTag: isReservedTag,
  getTagNamespace: getTagNamespace,
  staticKeys: genStaticKeys(modules$1)
};

/*  */

var isStaticKey;
var isPlatformReservedTag;

var genStaticKeysCached = cached(genStaticKeys$1);

/**
 * Goal of the optimizer: walk the generated template AST tree
 * and detect sub-trees that are purely static, i.e. parts of
 * the DOM that never needs to change.
 *
 * Once we detect these sub-trees, we can:
 *
 * 1. Hoist them into constants, so that we no longer need to
 *    create fresh nodes for them on each re-render;
 * 2. Completely skip them in the patching process.
 */
function optimize (root, options) {
  if (!root) { return }
  isStaticKey = genStaticKeysCached(options.staticKeys || '');
  isPlatformReservedTag = options.isReservedTag || no;
  // first pass: mark all non-static nodes.
  markStatic$1(root);
  // second pass: mark static roots.
  markStaticRoots(root, false);
}

function genStaticKeys$1 (keys) {
  return makeMap(
    'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
    (keys ? ',' + keys : '')
  )
}

function markStatic$1 (node) {
  node.static = isStatic(node);
  if (node.type === 1) {
    // do not make component slot content static. this avoids
    // 1. components not able to mutate slot nodes
    // 2. static slot content fails for hot-reloading
    if (
      !isPlatformReservedTag(node.tag) &&
      node.tag !== 'slot' &&
      node.attrsMap['inline-template'] == null
    ) {
      return
    }
    for (var i = 0, l = node.children.length; i < l; i++) {
      var child = node.children[i];
      markStatic$1(child);
      if (!child.static) {
        node.static = false;
      }
    }
    if (node.ifConditions) {
      for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
        var block = node.ifConditions[i$1].block;
        markStatic$1(block);
        if (!block.static) {
          node.static = false;
        }
      }
    }
  }
}

function markStaticRoots (node, isInFor) {
  if (node.type === 1) {
    if (node.static || node.once) {
      node.staticInFor = isInFor;
    }
    // For a node to qualify as a static root, it should have children that
    // are not just static text. Otherwise the cost of hoisting out will
    // outweigh the benefits and it's better off to just always render it fresh.
    if (node.static && node.children.length && !(
      node.children.length === 1 &&
      node.children[0].type === 3
    )) {
      node.staticRoot = true;
      return
    } else {
      node.staticRoot = false;
    }
    if (node.children) {
      for (var i = 0, l = node.children.length; i < l; i++) {
        markStaticRoots(node.children[i], isInFor || !!node.for);
      }
    }
    if (node.ifConditions) {
      for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
        markStaticRoots(node.ifConditions[i$1].block, isInFor);
      }
    }
  }
}

function isStatic (node) {
  if (node.type === 2) { // expression
    return false
  }
  if (node.type === 3) { // text
    return true
  }
  return !!(node.pre || (
    !node.hasBindings && // no dynamic bindings
    !node.if && !node.for && // not v-if or v-for or v-else
    !isBuiltInTag(node.tag) && // not a built-in
    isPlatformReservedTag(node.tag) && // not a component
    !isDirectChildOfTemplateFor(node) &&
    Object.keys(node).every(isStaticKey)
  ))
}

function isDirectChildOfTemplateFor (node) {
  while (node.parent) {
    node = node.parent;
    if (node.tag !== 'template') {
      return false
    }
    if (node.for) {
      return true
    }
  }
  return false
}

/*  */

var fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/;
var fnInvokeRE = /\([^)]*?\);*$/;
var simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;

// KeyboardEvent.keyCode aliases
var keyCodes = {
  esc: 27,
  tab: 9,
  enter: 13,
  space: 32,
  up: 38,
  left: 37,
  right: 39,
  down: 40,
  'delete': [8, 46]
};

// KeyboardEvent.key aliases
var keyNames = {
  // #7880: IE11 and Edge use `Esc` for Escape key name.
  esc: ['Esc', 'Escape'],
  tab: 'Tab',
  enter: 'Enter',
  // #9112: IE11 uses `Spacebar` for Space key name.
  space: [' ', 'Spacebar'],
  // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
  up: ['Up', 'ArrowUp'],
  left: ['Left', 'ArrowLeft'],
  right: ['Right', 'ArrowRight'],
  down: ['Down', 'ArrowDown'],
  // #9112: IE11 uses `Del` for Delete key name.
  'delete': ['Backspace', 'Delete', 'Del']
};

// #4868: modifiers that prevent the execution of the listener
// need to explicitly return null so that we can determine whether to remove
// the listener for .once
var genGuard = function (condition) { return ("if(" + condition + ")return null;"); };

var modifierCode = {
  stop: '$event.stopPropagation();',
  prevent: '$event.preventDefault();',
  self: genGuard("$event.target !== $event.currentTarget"),
  ctrl: genGuard("!$event.ctrlKey"),
  shift: genGuard("!$event.shiftKey"),
  alt: genGuard("!$event.altKey"),
  meta: genGuard("!$event.metaKey"),
  left: genGuard("'button' in $event && $event.button !== 0"),
  middle: genGuard("'button' in $event && $event.button !== 1"),
  right: genGuard("'button' in $event && $event.button !== 2")
};

function genHandlers (
  events,
  isNative
) {
  var prefix = isNative ? 'nativeOn:' : 'on:';
  var staticHandlers = "";
  var dynamicHandlers = "";
  for (var name in events) {
    var handlerCode = genHandler(events[name]);
    if (events[name] && events[name].dynamic) {
      dynamicHandlers += name + "," + handlerCode + ",";
    } else {
      staticHandlers += "\"" + name + "\":" + handlerCode + ",";
    }
  }
  staticHandlers = "{" + (staticHandlers.slice(0, -1)) + "}";
  if (dynamicHandlers) {
    return prefix + "_d(" + staticHandlers + ",[" + (dynamicHandlers.slice(0, -1)) + "])"
  } else {
    return prefix + staticHandlers
  }
}

function genHandler (handler) {
  if (!handler) {
    return 'function(){}'
  }

  if (Array.isArray(handler)) {
    return ("[" + (handler.map(function (handler) { return genHandler(handler); }).join(',')) + "]")
  }

  var isMethodPath = simplePathRE.test(handler.value);
  var isFunctionExpression = fnExpRE.test(handler.value);
  var isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''));

  if (!handler.modifiers) {
    if (isMethodPath || isFunctionExpression) {
      return handler.value
    }
    return ("function($event){" + (isFunctionInvocation ? ("return " + (handler.value)) : handler.value) + "}") // inline statement
  } else {
    var code = '';
    var genModifierCode = '';
    var keys = [];
    for (var key in handler.modifiers) {
      if (modifierCode[key]) {
        genModifierCode += modifierCode[key];
        // left/right
        if (keyCodes[key]) {
          keys.push(key);
        }
      } else if (key === 'exact') {
        var modifiers = (handler.modifiers);
        genModifierCode += genGuard(
          ['ctrl', 'shift', 'alt', 'meta']
            .filter(function (keyModifier) { return !modifiers[keyModifier]; })
            .map(function (keyModifier) { return ("$event." + keyModifier + "Key"); })
            .join('||')
        );
      } else {
        keys.push(key);
      }
    }
    if (keys.length) {
      code += genKeyFilter(keys);
    }
    // Make sure modifiers like prevent and stop get executed after key filtering
    if (genModifierCode) {
      code += genModifierCode;
    }
    var handlerCode = isMethodPath
      ? ("return " + (handler.value) + "($event)")
      : isFunctionExpression
        ? ("return (" + (handler.value) + ")($event)")
        : isFunctionInvocation
          ? ("return " + (handler.value))
          : handler.value;
    return ("function($event){" + code + handlerCode + "}")
  }
}

function genKeyFilter (keys) {
  return (
    // make sure the key filters only apply to KeyboardEvents
    // #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
    // key events that do not have keyCode property...
    "if(!$event.type.indexOf('key')&&" +
    (keys.map(genFilterCode).join('&&')) + ")return null;"
  )
}

function genFilterCode (key) {
  var keyVal = parseInt(key, 10);
  if (keyVal) {
    return ("$event.keyCode!==" + keyVal)
  }
  var keyCode = keyCodes[key];
  var keyName = keyNames[key];
  return (
    "_k($event.keyCode," +
    (JSON.stringify(key)) + "," +
    (JSON.stringify(keyCode)) + "," +
    "$event.key," +
    "" + (JSON.stringify(keyName)) +
    ")"
  )
}

/*  */

function on (el, dir) {
  if (dir.modifiers) {
    warn("v-on without argument does not support modifiers.");
  }
  el.wrapListeners = function (code) { return ("_g(" + code + "," + (dir.value) + ")"); };
}

/*  */

function bind$1 (el, dir) {
  el.wrapData = function (code) {
    return ("_b(" + code + ",'" + (el.tag) + "'," + (dir.value) + "," + (dir.modifiers && dir.modifiers.prop ? 'true' : 'false') + (dir.modifiers && dir.modifiers.sync ? ',true' : '') + ")")
  };
}

/*  */

var baseDirectives = {
  on: on,
  bind: bind$1,
  cloak: noop
};

/*  */





var CodegenState = function CodegenState (options) {
  this.options = options;
  this.warn = options.warn || baseWarn;
  this.transforms = pluckModuleFunction(options.modules, 'transformCode');
  this.dataGenFns = pluckModuleFunction(options.modules, 'genData');
  this.directives = extend(extend({}, baseDirectives), options.directives);
  var isReservedTag = options.isReservedTag || no;
  this.maybeComponent = function (el) { return !!el.component || !isReservedTag(el.tag); };
  this.onceId = 0;
  this.staticRenderFns = [];
  this.pre = false;
};



function generate (
  ast,
  options
) {
  var state = new CodegenState(options);
  var code = ast ? genElement(ast, state) : '_c("div")';
  return {
    render: ("with(this){return " + code + "}"),
    staticRenderFns: state.staticRenderFns
  }
}

function genElement (el, state) {
  if (el.parent) {
    el.pre = el.pre || el.parent.pre;
  }

  if (el.staticRoot && !el.staticProcessed) {
    return genStatic(el, state)
  } else if (el.once && !el.onceProcessed) {
    return genOnce(el, state)
  } else if (el.for && !el.forProcessed) {
    return genFor(el, state)
  } else if (el.if && !el.ifProcessed) {
    return genIf(el, state)
  } else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
    return genChildren(el, state) || 'void 0'
  } else if (el.tag === 'slot') {
    return genSlot(el, state)
  } else {
    // component or element
    var code;
    if (el.component) {
      code = genComponent(el.component, el, state);
    } else {
      var data;
      if (!el.plain || (el.pre && state.maybeComponent(el))) {
        data = genData$2(el, state);
      }

      var children = el.inlineTemplate ? null : genChildren(el, state, true);
      code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")";
    }
    // module transforms
    for (var i = 0; i < state.transforms.length; i++) {
      code = state.transforms[i](el, code);
    }
    return code
  }
}

// hoist static sub-trees out
function genStatic (el, state) {
  el.staticProcessed = true;
  // Some elements (templates) need to behave differently inside of a v-pre
  // node.  All pre nodes are static roots, so we can use this as a location to
  // wrap a state change and reset it upon exiting the pre node.
  var originalPreState = state.pre;
  if (el.pre) {
    state.pre = el.pre;
  }
  state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}"));
  state.pre = originalPreState;
  return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")")
}

// v-once
function genOnce (el, state) {
  el.onceProcessed = true;
  if (el.if && !el.ifProcessed) {
    return genIf(el, state)
  } else if (el.staticInFor) {
    var key = '';
    var parent = el.parent;
    while (parent) {
      if (parent.for) {
        key = parent.key;
        break
      }
      parent = parent.parent;
    }
    if (!key) {
      state.warn(
        "v-once can only be used inside v-for that is keyed. ",
        el.rawAttrsMap['v-once']
      );
      return genElement(el, state)
    }
    return ("_o(" + (genElement(el, state)) + "," + (state.onceId++) + "," + key + ")")
  } else {
    return genStatic(el, state)
  }
}

function genIf (
  el,
  state,
  altGen,
  altEmpty
) {
  el.ifProcessed = true; // avoid recursion
  return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
}

function genIfConditions (
  conditions,
  state,
  altGen,
  altEmpty
) {
  if (!conditions.length) {
    return altEmpty || '_e()'
  }

  var condition = conditions.shift();
  if (condition.exp) {
    return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty)))
  } else {
    return ("" + (genTernaryExp(condition.block)))
  }

  // v-if with v-once should generate code like (a)?_m(0):_m(1)
  function genTernaryExp (el) {
    return altGen
      ? altGen(el, state)
      : el.once
        ? genOnce(el, state)
        : genElement(el, state)
  }
}

function genFor (
  el,
  state,
  altGen,
  altHelper
) {
  var exp = el.for;
  var alias = el.alias;
  var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';
  var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';

  if (state.maybeComponent(el) &&
    el.tag !== 'slot' &&
    el.tag !== 'template' &&
    !el.key
  ) {
    state.warn(
      "<" + (el.tag) + " v-for=\"" + alias + " in " + exp + "\">: component lists rendered with " +
      "v-for should have explicit keys. " +
      "See https://vuejs.org/guide/list.html#key for more info.",
      el.rawAttrsMap['v-for'],
      true /* tip */
    );
  }

  el.forProcessed = true; // avoid recursion
  return (altHelper || '_l') + "((" + exp + ")," +
    "function(" + alias + iterator1 + iterator2 + "){" +
      "return " + ((altGen || genElement)(el, state)) +
    '})'
}

function genData$2 (el, state) {
  var data = '{';

  // directives first.
  // directives may mutate the el's other properties before they are generated.
  var dirs = genDirectives(el, state);
  if (dirs) { data += dirs + ','; }

  // key
  if (el.key) {
    data += "key:" + (el.key) + ",";
  }
  // ref
  if (el.ref) {
    data += "ref:" + (el.ref) + ",";
  }
  if (el.refInFor) {
    data += "refInFor:true,";
  }
  // pre
  if (el.pre) {
    data += "pre:true,";
  }
  // record original tag name for components using "is" attribute
  if (el.component) {
    data += "tag:\"" + (el.tag) + "\",";
  }
  // module data generation functions
  for (var i = 0; i < state.dataGenFns.length; i++) {
    data += state.dataGenFns[i](el);
  }
  // attributes
  if (el.attrs) {
    data += "attrs:" + (genProps(el.attrs)) + ",";
  }
  // DOM props
  if (el.props) {
    data += "domProps:" + (genProps(el.props)) + ",";
  }
  // event handlers
  if (el.events) {
    data += (genHandlers(el.events, false)) + ",";
  }
  if (el.nativeEvents) {
    data += (genHandlers(el.nativeEvents, true)) + ",";
  }
  // slot target
  // only for non-scoped slots
  if (el.slotTarget && !el.slotScope) {
    data += "slot:" + (el.slotTarget) + ",";
  }
  // scoped slots
  if (el.scopedSlots) {
    data += (genScopedSlots(el, el.scopedSlots, state)) + ",";
  }
  // component v-model
  if (el.model) {
    data += "model:{value:" + (el.model.value) + ",callback:" + (el.model.callback) + ",expression:" + (el.model.expression) + "},";
  }
  // inline-template
  if (el.inlineTemplate) {
    var inlineTemplate = genInlineTemplate(el, state);
    if (inlineTemplate) {
      data += inlineTemplate + ",";
    }
  }
  data = data.replace(/,$/, '') + '}';
  // v-bind dynamic argument wrap
  // v-bind with dynamic arguments must be applied using the same v-bind object
  // merge helper so that class/style/mustUseProp attrs are handled correctly.
  if (el.dynamicAttrs) {
    data = "_b(" + data + ",\"" + (el.tag) + "\"," + (genProps(el.dynamicAttrs)) + ")";
  }
  // v-bind data wrap
  if (el.wrapData) {
    data = el.wrapData(data);
  }
  // v-on data wrap
  if (el.wrapListeners) {
    data = el.wrapListeners(data);
  }
  return data
}

function genDirectives (el, state) {
  var dirs = el.directives;
  if (!dirs) { return }
  var res = 'directives:[';
  var hasRuntime = false;
  var i, l, dir, needRuntime;
  for (i = 0, l = dirs.length; i < l; i++) {
    dir = dirs[i];
    needRuntime = true;
    var gen = state.directives[dir.name];
    if (gen) {
      // compile-time directive that manipulates AST.
      // returns true if it also needs a runtime counterpart.
      needRuntime = !!gen(el, dir, state.warn);
    }
    if (needRuntime) {
      hasRuntime = true;
      res += "{name:\"" + (dir.name) + "\",rawName:\"" + (dir.rawName) + "\"" + (dir.value ? (",value:(" + (dir.value) + "),expression:" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (",arg:" + (dir.isDynamicArg ? dir.arg : ("\"" + (dir.arg) + "\""))) : '') + (dir.modifiers ? (",modifiers:" + (JSON.stringify(dir.modifiers))) : '') + "},";
    }
  }
  if (hasRuntime) {
    return res.slice(0, -1) + ']'
  }
}

function genInlineTemplate (el, state) {
  var ast = el.children[0];
  if (el.children.length !== 1 || ast.type !== 1) {
    state.warn(
      'Inline-template components must have exactly one child element.',
      { start: el.start }
    );
  }
  if (ast && ast.type === 1) {
    var inlineRenderFns = generate(ast, state.options);
    return ("inlineTemplate:{render:function(){" + (inlineRenderFns.render) + "},staticRenderFns:[" + (inlineRenderFns.staticRenderFns.map(function (code) { return ("function(){" + code + "}"); }).join(',')) + "]}")
  }
}

function genScopedSlots (
  el,
  slots,
  state
) {
  // by default scoped slots are considered "stable", this allows child
  // components with only scoped slots to skip forced updates from parent.
  // but in some cases we have to bail-out of this optimization
  // for example if the slot contains dynamic names, has v-if or v-for on them...
  var needsForceUpdate = el.for || Object.keys(slots).some(function (key) {
    var slot = slots[key];
    return (
      slot.slotTargetDynamic ||
      slot.if ||
      slot.for ||
      containsSlotChild(slot) // is passing down slot from parent which may be dynamic
    )
  });

  // #9534: if a component with scoped slots is inside a conditional branch,
  // it's possible for the same component to be reused but with different
  // compiled slot content. To avoid that, we generate a unique key based on
  // the generated code of all the slot contents.
  var needsKey = !!el.if;

  // OR when it is inside another scoped slot or v-for (the reactivity may be
  // disconnected due to the intermediate scope variable)
  // #9438, #9506
  // TODO: this can be further optimized by properly analyzing in-scope bindings
  // and skip force updating ones that do not actually use scope variables.
  if (!needsForceUpdate) {
    var parent = el.parent;
    while (parent) {
      if (
        (parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||
        parent.for
      ) {
        needsForceUpdate = true;
        break
      }
      if (parent.if) {
        needsKey = true;
      }
      parent = parent.parent;
    }
  }

  var generatedSlots = Object.keys(slots)
    .map(function (key) { return genScopedSlot(slots[key], state); })
    .join(',');

  return ("scopedSlots:_u([" + generatedSlots + "]" + (needsForceUpdate ? ",null,true" : "") + (!needsForceUpdate && needsKey ? (",null,false," + (hash(generatedSlots))) : "") + ")")
}

function hash(str) {
  var hash = 5381;
  var i = str.length;
  while(i) {
    hash = (hash * 33) ^ str.charCodeAt(--i);
  }
  return hash >>> 0
}

function containsSlotChild (el) {
  if (el.type === 1) {
    if (el.tag === 'slot') {
      return true
    }
    return el.children.some(containsSlotChild)
  }
  return false
}

function genScopedSlot (
  el,
  state
) {
  var isLegacySyntax = el.attrsMap['slot-scope'];
  if (el.if && !el.ifProcessed && !isLegacySyntax) {
    return genIf(el, state, genScopedSlot, "null")
  }
  if (el.for && !el.forProcessed) {
    return genFor(el, state, genScopedSlot)
  }
  var slotScope = el.slotScope === emptySlotScopeToken
    ? ""
    : String(el.slotScope);
  var fn = "function(" + slotScope + "){" +
    "return " + (el.tag === 'template'
      ? el.if && isLegacySyntax
        ? ("(" + (el.if) + ")?" + (genChildren(el, state) || 'undefined') + ":undefined")
        : genChildren(el, state) || 'undefined'
      : genElement(el, state)) + "}";
  // reverse proxy v-slot without scope on this.$slots
  var reverseProxy = slotScope ? "" : ",proxy:true";
  return ("{key:" + (el.slotTarget || "\"default\"") + ",fn:" + fn + reverseProxy + "}")
}

function genChildren (
  el,
  state,
  checkSkip,
  altGenElement,
  altGenNode
) {
  var children = el.children;
  if (children.length) {
    var el$1 = children[0];
    // optimize single v-for
    if (children.length === 1 &&
      el$1.for &&
      el$1.tag !== 'template' &&
      el$1.tag !== 'slot'
    ) {
      var normalizationType = checkSkip
        ? state.maybeComponent(el$1) ? ",1" : ",0"
        : "";
      return ("" + ((altGenElement || genElement)(el$1, state)) + normalizationType)
    }
    var normalizationType$1 = checkSkip
      ? getNormalizationType(children, state.maybeComponent)
      : 0;
    var gen = altGenNode || genNode;
    return ("[" + (children.map(function (c) { return gen(c, state); }).join(',')) + "]" + (normalizationType$1 ? ("," + normalizationType$1) : ''))
  }
}

// determine the normalization needed for the children array.
// 0: no normalization needed
// 1: simple normalization needed (possible 1-level deep nested array)
// 2: full normalization needed
function getNormalizationType (
  children,
  maybeComponent
) {
  var res = 0;
  for (var i = 0; i < children.length; i++) {
    var el = children[i];
    if (el.type !== 1) {
      continue
    }
    if (needsNormalization(el) ||
        (el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) {
      res = 2;
      break
    }
    if (maybeComponent(el) ||
        (el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) {
      res = 1;
    }
  }
  return res
}

function needsNormalization (el) {
  return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'
}

function genNode (node, state) {
  if (node.type === 1) {
    return genElement(node, state)
  } else if (node.type === 3 && node.isComment) {
    return genComment(node)
  } else {
    return genText(node)
  }
}

function genText (text) {
  return ("_v(" + (text.type === 2
    ? text.expression // no need for () because already wrapped in _s()
    : transformSpecialNewlines(JSON.stringify(text.text))) + ")")
}

function genComment (comment) {
  return ("_e(" + (JSON.stringify(comment.text)) + ")")
}

function genSlot (el, state) {
  var slotName = el.slotName || '"default"';
  var children = genChildren(el, state);
  var res = "_t(" + slotName + (children ? ("," + children) : '');
  var attrs = el.attrs || el.dynamicAttrs
    ? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(function (attr) { return ({
        // slot props are camelized
        name: camelize(attr.name),
        value: attr.value,
        dynamic: attr.dynamic
      }); }))
    : null;
  var bind$$1 = el.attrsMap['v-bind'];
  if ((attrs || bind$$1) && !children) {
    res += ",null";
  }
  if (attrs) {
    res += "," + attrs;
  }
  if (bind$$1) {
    res += (attrs ? '' : ',null') + "," + bind$$1;
  }
  return res + ')'
}

// componentName is el.component, take it as argument to shun flow's pessimistic refinement
function genComponent (
  componentName,
  el,
  state
) {
  var children = el.inlineTemplate ? null : genChildren(el, state, true);
  return ("_c(" + componentName + "," + (genData$2(el, state)) + (children ? ("," + children) : '') + ")")
}

function genProps (props) {
  var staticProps = "";
  var dynamicProps = "";
  for (var i = 0; i < props.length; i++) {
    var prop = props[i];
    var value = transformSpecialNewlines(prop.value);
    if (prop.dynamic) {
      dynamicProps += (prop.name) + "," + value + ",";
    } else {
      staticProps += "\"" + (prop.name) + "\":" + value + ",";
    }
  }
  staticProps = "{" + (staticProps.slice(0, -1)) + "}";
  if (dynamicProps) {
    return ("_d(" + staticProps + ",[" + (dynamicProps.slice(0, -1)) + "])")
  } else {
    return staticProps
  }
}

// #3895, #4268
function transformSpecialNewlines (text) {
  return text
    .replace(/\u2028/g, '\\u2028')
    .replace(/\u2029/g, '\\u2029')
}

/*  */



// these keywords should not appear inside expressions, but operators like
// typeof, instanceof and in are allowed
var prohibitedKeywordRE = new RegExp('\\b' + (
  'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
  'super,throw,while,yield,delete,export,import,return,switch,default,' +
  'extends,finally,continue,debugger,function,arguments'
).split(',').join('\\b|\\b') + '\\b');

// these unary operators should not be used as property/method names
var unaryOperatorsRE = new RegExp('\\b' + (
  'delete,typeof,void'
).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)');

// strip strings in expressions
var stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;

// detect problematic expressions in a template
function detectErrors (ast, warn) {
  if (ast) {
    checkNode(ast, warn);
  }
}

function checkNode (node, warn) {
  if (node.type === 1) {
    for (var name in node.attrsMap) {
      if (dirRE.test(name)) {
        var value = node.attrsMap[name];
        if (value) {
          var range = node.rawAttrsMap[name];
          if (name === 'v-for') {
            checkFor(node, ("v-for=\"" + value + "\""), warn, range);
          } else if (name === 'v-slot' || name[0] === '#') {
            checkFunctionParameterExpression(value, (name + "=\"" + value + "\""), warn, range);
          } else if (onRE.test(name)) {
            checkEvent(value, (name + "=\"" + value + "\""), warn, range);
          } else {
            checkExpression(value, (name + "=\"" + value + "\""), warn, range);
          }
        }
      }
    }
    if (node.children) {
      for (var i = 0; i < node.children.length; i++) {
        checkNode(node.children[i], warn);
      }
    }
  } else if (node.type === 2) {
    checkExpression(node.expression, node.text, warn, node);
  }
}

function checkEvent (exp, text, warn, range) {
  var stripped = exp.replace(stripStringRE, '');
  var keywordMatch = stripped.match(unaryOperatorsRE);
  if (keywordMatch && stripped.charAt(keywordMatch.index - 1) !== '$') {
    warn(
      "avoid using JavaScript unary operator as property name: " +
      "\"" + (keywordMatch[0]) + "\" in expression " + (text.trim()),
      range
    );
  }
  checkExpression(exp, text, warn, range);
}

function checkFor (node, text, warn, range) {
  checkExpression(node.for || '', text, warn, range);
  checkIdentifier(node.alias, 'v-for alias', text, warn, range);
  checkIdentifier(node.iterator1, 'v-for iterator', text, warn, range);
  checkIdentifier(node.iterator2, 'v-for iterator', text, warn, range);
}

function checkIdentifier (
  ident,
  type,
  text,
  warn,
  range
) {
  if (typeof ident === 'string') {
    try {
      new Function(("var " + ident + "=_"));
    } catch (e) {
      warn(("invalid " + type + " \"" + ident + "\" in expression: " + (text.trim())), range);
    }
  }
}

function checkExpression (exp, text, warn, range) {
  try {
    new Function(("return " + exp));
  } catch (e) {
    var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);
    if (keywordMatch) {
      warn(
        "avoid using JavaScript keyword as property name: " +
        "\"" + (keywordMatch[0]) + "\"\n  Raw expression: " + (text.trim()),
        range
      );
    } else {
      warn(
        "invalid expression: " + (e.message) + " in\n\n" +
        "    " + exp + "\n\n" +
        "  Raw expression: " + (text.trim()) + "\n",
        range
      );
    }
  }
}

function checkFunctionParameterExpression (exp, text, warn, range) {
  try {
    new Function(exp, '');
  } catch (e) {
    warn(
      "invalid function parameter expression: " + (e.message) + " in\n\n" +
      "    " + exp + "\n\n" +
      "  Raw expression: " + (text.trim()) + "\n",
      range
    );
  }
}

/*  */

var range = 2;

function generateCodeFrame (
  source,
  start,
  end
) {
  if ( start === void 0 ) start = 0;
  if ( end === void 0 ) end = source.length;

  var lines = source.split(/\r?\n/);
  var count = 0;
  var res = [];
  for (var i = 0; i < lines.length; i++) {
    count += lines[i].length + 1;
    if (count >= start) {
      for (var j = i - range; j <= i + range || end > count; j++) {
        if (j < 0 || j >= lines.length) { continue }
        res.push(("" + (j + 1) + (repeat$1(" ", 3 - String(j + 1).length)) + "|  " + (lines[j])));
        var lineLength = lines[j].length;
        if (j === i) {
          // push underline
          var pad = start - (count - lineLength) + 1;
          var length = end > count ? lineLength - pad : end - start;
          res.push("   |  " + repeat$1(" ", pad) + repeat$1("^", length));
        } else if (j > i) {
          if (end > count) {
            var length$1 = Math.min(end - count, lineLength);
            res.push("   |  " + repeat$1("^", length$1));
          }
          count += lineLength + 1;
        }
      }
      break
    }
  }
  return res.join('\n')
}

function repeat$1 (str, n) {
  var result = '';
  if (n > 0) {
    while (true) { // eslint-disable-line
      if (n & 1) { result += str; }
      n >>>= 1;
      if (n <= 0) { break }
      str += str;
    }
  }
  return result
}

/*  */



function createFunction (code, errors) {
  try {
    return new Function(code)
  } catch (err) {
    errors.push({ err: err, code: code });
    return noop
  }
}

function createCompileToFunctionFn (compile) {
  var cache = Object.create(null);

  return function compileToFunctions (
    template,
    options,
    vm
  ) {
    options = extend({}, options);
    var warn$$1 = options.warn || warn;
    delete options.warn;

    /* istanbul ignore if */
    {
      // detect possible CSP restriction
      try {
        new Function('return 1');
      } catch (e) {
        if (e.toString().match(/unsafe-eval|CSP/)) {
          warn$$1(
            'It seems you are using the standalone build of Vue.js in an ' +
            'environment with Content Security Policy that prohibits unsafe-eval. ' +
            'The template compiler cannot work in this environment. Consider ' +
            'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
            'templates into render functions.'
          );
        }
      }
    }

    // check cache
    var key = options.delimiters
      ? String(options.delimiters) + template
      : template;
    if (cache[key]) {
      return cache[key]
    }

    // compile
    var compiled = compile(template, options);

    // check compilation errors/tips
    {
      if (compiled.errors && compiled.errors.length) {
        if (options.outputSourceRange) {
          compiled.errors.forEach(function (e) {
            warn$$1(
              "Error compiling template:\n\n" + (e.msg) + "\n\n" +
              generateCodeFrame(template, e.start, e.end),
              vm
            );
          });
        } else {
          warn$$1(
            "Error compiling template:\n\n" + template + "\n\n" +
            compiled.errors.map(function (e) { return ("- " + e); }).join('\n') + '\n',
            vm
          );
        }
      }
      if (compiled.tips && compiled.tips.length) {
        if (options.outputSourceRange) {
          compiled.tips.forEach(function (e) { return tip(e.msg, vm); });
        } else {
          compiled.tips.forEach(function (msg) { return tip(msg, vm); });
        }
      }
    }

    // turn code into functions
    var res = {};
    var fnGenErrors = [];
    res.render = createFunction(compiled.render, fnGenErrors);
    res.staticRenderFns = compiled.staticRenderFns.map(function (code) {
      return createFunction(code, fnGenErrors)
    });

    // check function generation errors.
    // this should only happen if there is a bug in the compiler itself.
    // mostly for codegen development use
    /* istanbul ignore if */
    {
      if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
        warn$$1(
          "Failed to generate render function:\n\n" +
          fnGenErrors.map(function (ref) {
            var err = ref.err;
            var code = ref.code;

            return ((err.toString()) + " in\n\n" + code + "\n");
        }).join('\n'),
          vm
        );
      }
    }

    return (cache[key] = res)
  }
}

/*  */

function createCompilerCreator (baseCompile) {
  return function createCompiler (baseOptions) {
    function compile (
      template,
      options
    ) {
      var finalOptions = Object.create(baseOptions);
      var errors = [];
      var tips = [];

      var warn = function (msg, range, tip) {
        (tip ? tips : errors).push(msg);
      };

      if (options) {
        if (options.outputSourceRange) {
          // $flow-disable-line
          var leadingSpaceLength = template.match(/^\s*/)[0].length;

          warn = function (msg, range, tip) {
            var data = { msg: msg };
            if (range) {
              if (range.start != null) {
                data.start = range.start + leadingSpaceLength;
              }
              if (range.end != null) {
                data.end = range.end + leadingSpaceLength;
              }
            }
            (tip ? tips : errors).push(data);
          };
        }
        // merge custom modules
        if (options.modules) {
          finalOptions.modules =
            (baseOptions.modules || []).concat(options.modules);
        }
        // merge custom directives
        if (options.directives) {
          finalOptions.directives = extend(
            Object.create(baseOptions.directives || null),
            options.directives
          );
        }
        // copy other options
        for (var key in options) {
          if (key !== 'modules' && key !== 'directives') {
            finalOptions[key] = options[key];
          }
        }
      }

      finalOptions.warn = warn;

      var compiled = baseCompile(template.trim(), finalOptions);
      {
        detectErrors(compiled.ast, warn);
      }
      compiled.errors = errors;
      compiled.tips = tips;
      return compiled
    }

    return {
      compile: compile,
      compileToFunctions: createCompileToFunctionFn(compile)
    }
  }
}

/*  */

// `createCompilerCreator` allows creating compilers that use alternative
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
// Here we just export a default compiler using the default parts.
var createCompiler = createCompilerCreator(function baseCompile (
  template,
  options
) {
  var ast = parse(template.trim(), options);
  if (options.optimize !== false) {
    optimize(ast, options);
  }
  var code = generate(ast, options);
  return {
    ast: ast,
    render: code.render,
    staticRenderFns: code.staticRenderFns
  }
});

/*  */

var ref$1 = createCompiler(baseOptions);
var compile = ref$1.compile;
var compileToFunctions = ref$1.compileToFunctions;

/*  */

// check whether current browser encodes a char inside attribute values
var div;
function getShouldDecode (href) {
  div = div || document.createElement('div');
  div.innerHTML = href ? "<a href=\"\n\"/>" : "<div a=\"\n\"/>";
  return div.innerHTML.indexOf('&#10;') > 0
}

// #3663: IE encodes newlines inside attribute values while other browsers don't
var shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false;
// #6828: chrome encodes content in a[href]
var shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false;

/*  */

var idToTemplate = cached(function (id) {
  var el = query(id);
  return el && el.innerHTML
});

var mount = Vue.prototype.$mount;
Vue.prototype.$mount = function (
  el,
  hydrating
) {
  el = el && query(el);

  /* istanbul ignore if */
  if (el === document.body || el === document.documentElement) {
    warn(
      "Do not mount Vue to <html> or <body> - mount to normal elements instead."
    );
    return this
  }

  var options = this.$options;
  // resolve template/el and convert to render function
  if (!options.render) {
    var template = options.template;
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template);
          /* istanbul ignore if */
          if (!template) {
            warn(
              ("Template element not found or is empty: " + (options.template)),
              this
            );
          }
        }
      } else if (template.nodeType) {
        template = template.innerHTML;
      } else {
        {
          warn('invalid template option:' + template, this);
        }
        return this
      }
    } else if (el) {
      template = getOuterHTML(el);
    }
    if (template) {
      /* istanbul ignore if */
      if (config.performance && mark) {
        mark('compile');
      }

      var ref = compileToFunctions(template, {
        outputSourceRange: "development" !== 'production',
        shouldDecodeNewlines: shouldDecodeNewlines,
        shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref,
        delimiters: options.delimiters,
        comments: options.comments
      }, this);
      var render = ref.render;
      var staticRenderFns = ref.staticRenderFns;
      options.render = render;
      options.staticRenderFns = staticRenderFns;

      /* istanbul ignore if */
      if (config.performance && mark) {
        mark('compile end');
        measure(("vue " + (this._name) + " compile"), 'compile', 'compile end');
      }
    }
  }
  return mount.call(this, el, hydrating)
};

/**
 * Get outerHTML of elements, taking care
 * of SVG elements in IE as well.
 */
function getOuterHTML (el) {
  if (el.outerHTML) {
    return el.outerHTML
  } else {
    var container = document.createElement('div');
    container.appendChild(el.cloneNode(true));
    return container.innerHTML
  }
}

Vue.compile = compileToFunctions;

module.exports = Vue;

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../../timers-browserify/main.js */ "./node_modules/timers-browserify/main.js").setImmediate))

/***/ }),

/***/ "./node_modules/vue/dist/vue.common.js":
/*!*********************************************!*\
  !*** ./node_modules/vue/dist/vue.common.js ***!
  \*********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

if (false) {} else {
  module.exports = __webpack_require__(/*! ./vue.common.dev.js */ "./node_modules/vue/dist/vue.common.dev.js")
}


/***/ }),

/***/ "./node_modules/webpack/buildin/global.js":
/*!***********************************!*\
  !*** (webpack)/buildin/global.js ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

var g;

// This works in non-strict mode
g = (function() {
	return this;
})();

try {
	// This works if eval is allowed (see CSP)
	g = g || new Function("return this")();
} catch (e) {
	// This works if the window reference is available
	if (typeof window === "object") g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


/***/ }),

/***/ "./resources/js/app.js":
/*!*****************************!*\
  !*** ./resources/js/app.js ***!
  \*****************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _components_GlobalisationService__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./components/GlobalisationService */ "./resources/js/components/GlobalisationService.js");
/* harmony import */ var _components_RegisterController__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/RegisterController */ "./resources/js/components/RegisterController.js");
/* harmony import */ var _components_validationService__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/validationService */ "./resources/js/components/validationService.js");
/* harmony import */ var _components_errorController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/errorController */ "./resources/js/components/errorController.js");
/* harmony import */ var _komma_kal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @komma/kal */ "./node_modules/@komma/kal/kal.js");
/** ==========================================================================
 *  Import ES6 Modules (https://webpack.js.org/api/module-methods/)
 *  =========================================================================*/




/** ==========================================================================
 *  Dependencies
 *  =========================================================================*/

/**
 * External
 */

__webpack_require__(/*! hammerjs */ "./node_modules/hammerjs/hammer.js");

__webpack_require__(/*! objectFitPolyfill */ "./node_modules/objectFitPolyfill/dist/objectFitPolyfill.min.js");

__webpack_require__(/*! url-search-params-polyfill */ "./node_modules/url-search-params-polyfill/index.js");
/** ==========================================================================
 *  Global functionalities
 *  =========================================================================*/


__webpack_require__(/*! ./global/polyfills/eventPolyFill */ "./resources/js/global/polyfills/eventPolyFill.js");

__webpack_require__(/*! ./global/polyfills/isInteger */ "./resources/js/global/polyfills/isInteger.js");

__webpack_require__(/*! ./global/polyfills/promise */ "./resources/js/global/polyfills/promise.js");

__webpack_require__(/*! ./global/helpers */ "./resources/js/global/helpers.js"); // Should be first


__webpack_require__(/*! ./global/browserHandler */ "./resources/js/global/browserHandler.js"); // require('./global/resizeHandler');


__webpack_require__(/*! ./global/scrollHandler */ "./resources/js/global/scrollHandler.js");
/** ==========================================================================
 *  Component functionalities
 *  =========================================================================*/


__webpack_require__(/*! ./components/chocolateFactory */ "./resources/js/components/chocolateFactory.js");

__webpack_require__(/*! ./components/cookieHandler */ "./resources/js/components/cookieHandler.js");

__webpack_require__(/*! ./components/contactSubjectHandler */ "./resources/js/components/contactSubjectHandler.js"); // require('./components/InputHandler');


__webpack_require__(/*! ./components/fileUploadHandler */ "./resources/js/components/fileUploadHandler.js");

__webpack_require__(/*! ./components/mapsHandler */ "./resources/js/components/mapsHandler.js");

__webpack_require__(/*! ./components/overlayMenuHandler */ "./resources/js/components/overlayMenuHandler.js");

__webpack_require__(/*! ./components/customerLogoSliderHandler */ "./resources/js/components/customerLogoSliderHandler.js");

__webpack_require__(/*! ./components/projectorHandler */ "./resources/js/components/projectorHandler.js");

__webpack_require__(/*! ./components/scrollToHandler */ "./resources/js/components/scrollToHandler.js");

__webpack_require__(/*! ./components/chocolatLightbox */ "./resources/js/components/chocolatLightbox.js"); // require('./components/searchHandler');
// require('./components/shareButtonsHandler');


__webpack_require__(/*! ./components/testimonialSliderHandler */ "./resources/js/components/testimonialSliderHandler.js");

__webpack_require__(/*! ./components/toggleHandler */ "./resources/js/components/toggleHandler.js");

__webpack_require__(/*! ./components/youtubeHandler */ "./resources/js/components/youtubeHandler.js"); // require('./components/youtubeModalHandler');

/** ==========================================================================
 *  Vue components
 *  =========================================================================*/


__webpack_require__(/*! ./vue/paybackPeriod/main */ "./resources/js/vue/paybackPeriod/main.js");


_komma_kal__WEBPACK_IMPORTED_MODULE_4__["KAL"].init();
var registerForm = document.getElementById('registerForm');
if (registerForm) new _components_RegisterController__WEBPACK_IMPORTED_MODULE_1__["RegisterController"](registerForm, new _components_GlobalisationService__WEBPACK_IMPORTED_MODULE_0__["GlobalisationService"]());

/***/ }),

/***/ "./resources/js/components/GlobalisationService.js":
/*!*********************************************************!*\
  !*** ./resources/js/components/GlobalisationService.js ***!
  \*********************************************************/
/*! exports provided: GlobalisationService */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlobalisationService", function() { return GlobalisationService; });
/* harmony import */ var _global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../global/models/errorResponse */ "./resources/js/global/models/errorResponse.js");
/* harmony import */ var _global_models_countryLanguagesResponse__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../global/models/countryLanguagesResponse */ "./resources/js/global/models/countryLanguagesResponse.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }




var GlobalisationService = /*#__PURE__*/function () {
  function GlobalisationService() {
    _classCallCheck(this, GlobalisationService);

    this._baseRoute = '/';
  }
  /**
   * Adds a product to the shopping cart
   *
   * @param {string} countryIso3
   */


  _createClass(GlobalisationService, [{
    key: "getLanguagesForCountryWithIso3",
    value: function getLanguagesForCountryWithIso3(countryIso3) {
      var self = this;
      return new Promise(function (resolve, reject) {
        Ajax.post(self._baseRoute + 'getLanguagesForCountryWithIso3', {
          countryIso3: countryIso3
        }, function (xhr) {
          // let response = JSON.parse(xhr.response);
          var isErrorResponse = _global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__["ErrorResponse"].is(xhr.response, false);
          var isCountryLanguagesResponse = _global_models_countryLanguagesResponse__WEBPACK_IMPORTED_MODULE_1__["CountryLanguagesResponse"].is(xhr.response, false);

          if (!isErrorResponse) {
            if (isCountryLanguagesResponse) {
              var countryLanguagesResponse = _global_models_countryLanguagesResponse__WEBPACK_IMPORTED_MODULE_1__["CountryLanguagesResponse"].fromJsonString(xhr.response);
              resolve(countryLanguagesResponse);
            } else {
              console.error('RegisterService:getLanguagesForCountryWithIso3 The response was not a valid CountryLanguagesResponse: ' + xhr.response);
              reject();
            }
          } else {
            var response = _global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__["ErrorResponse"].fromJsonString(xhr.response);
            reject(response);
          }
        });
      });
    }
  }]);

  return GlobalisationService;
}();



/***/ }),

/***/ "./resources/js/components/RegisterController.js":
/*!*******************************************************!*\
  !*** ./resources/js/components/RegisterController.js ***!
  \*******************************************************/
/*! exports provided: RegisterController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RegisterController", function() { return RegisterController; });
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var RegisterController = /*#__PURE__*/function () {
  /**
   * @param {HTMLDivElement} wrapper
   * @param {GlobalisationService} globalisationService
   */
  function RegisterController(wrapper, globalisationService) {
    _classCallCheck(this, RegisterController);

    this._wrapper = wrapper;

    if (!this._wrapper || this._wrapper.tagName !== "FORM") {
      console.error('RegisterController: The Register form must be a div element but was not or wasn\'t even specified.');
      return;
    }

    this._countrySelect = this._wrapper.querySelector('select[name="country"]');

    if (!this._countrySelect) {
      console.error('RegisterController: The Register form must have a select element with name "country" but did not have it.');
      return;
    }

    this._languageSelect = this._wrapper.querySelector('select[name="language"]');

    if (!this._countrySelect) {
      console.error('RegisterController: The Register form must have a select element with name "language" but did not have it.');
      return;
    }

    this._languageSelectWrapper = this._wrapper.querySelector('.js-language-wrapper');

    if (!this._languageSelectWrapper || this._languageSelectWrapper.tagName !== "DIV") {
      console.error('RegisterController: The Register form must have a wrapper DIV element with class "js-language-wrapper" but did not have it.');
      return;
    }

    this._globalisationService = globalisationService;

    if (!globalisationService) {
      console.error('RegisterController: The Register form was expected to get an instance of RegisterService, but did not get one.');
      return;
    }

    this._hiddenClass = 'u-hidden'; //The name of a class that can be applied to things to hide them.

    this._domParser = new DOMParser();
    this._countryChanged = this._countryChanged.bind(this);
    this.controlListeners(true);

    this._countryChanged();
  }

  _createClass(RegisterController, [{
    key: "controlListeners",
    value: function controlListeners() {
      var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

      this._countrySelect.removeEventListener('change', this._countryChanged);

      if (enable) {
        this._countrySelect.addEventListener('change', this._countryChanged);
      }
    }
    /**
     * @private
     */

  }, {
    key: "_countryChanged",
    value: function _countryChanged() {
      var countryIso3 = this._countrySelect.value;
      var self = this;

      this._globalisationService.getLanguagesForCountryWithIso3(countryIso3).then(
      /** @param { CountryLanguagesResponse } countryLanguagesResponse **/
      function (countryLanguagesResponse) {
        self._clearLanguageSelect();

        var languageCount = countryLanguagesResponse.languages.length;

        for (var index = 0; index < languageCount; index++) {
          var language = countryLanguagesResponse.languages[index];

          var optionElement = self._createHtmlElementFromString('<option value="' + language.threeLetterIsoLanguageName + '">' + language.nativeName + '</option>');

          self._languageSelect.appendChild(optionElement);
        }

        if (languageCount <= 1) {
          self._languageSelectWrapper.classList.add(self._hiddenClass);
        } else {
          self._languageSelectWrapper.classList.remove(self._hiddenClass);
        }
      })["catch"](
      /** @param { ErrorResponse } errorResponse **/
      function (errorResponse) {
        console.error(errorResponse);
      });
    }
    /**
     * @private
     */

  }, {
    key: "_clearLanguageSelect",
    value: function _clearLanguageSelect() {
      while (this._languageSelect.children.length) {
        this._languageSelect.removeChild(this._languageSelect.firstChild);
      }
    }
    /**
     * @private
     * @param {string} from
     * @return {HTMLElement}
     */

  }, {
    key: "_createHtmlElementFromString",
    value: function _createHtmlElementFromString(from) {
      var document = this._domParser.parseFromString(from, 'text/html');

      return document.body.firstChild;
    }
  }]);

  return RegisterController;
}();



/***/ }),

/***/ "./resources/js/components/chocolatLightbox.js":
/*!*****************************************************!*\
  !*** ./resources/js/components/chocolatLightbox.js ***!
  \*****************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var chocolat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! chocolat */ "./node_modules/chocolat/dist/js/chocolat.esm.js");

Object(chocolat__WEBPACK_IMPORTED_MODULE_0__["default"])(document.querySelectorAll('.js-lightbox'), {// options here
});

/***/ }),

/***/ "./resources/js/components/chocolateFactory.js":
/*!*****************************************************!*\
  !*** ./resources/js/components/chocolateFactory.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
 | Prevent Bots handler
 |
 | We named this chocolate factory and belonging confusing js hooks
 | to prevent smart bots from blocking these variable or functions.
 |
 ========================================================================== */
var ChocolateFactory = {
  bannedVisitor: [],

  /** Get all the chocolate factory and start
   *  Looping through those start flashing tickets
   */
  enter: function enter() {
    var chocolateFactories = document.querySelectorAll('.js-chocolate-factory');

    if (isset(chocolateFactories)) {
      var amountOfChocolateFactories = chocolateFactories.length;

      for (var i = 0; i < amountOfChocolateFactories; i++) {
        var ChocolateBar = chocolateFactories[i];

        ChocolateFactory._flashTicket(ChocolateBar);
      }
    }
  },

  /**
   * If factory has a golden ticket
   * Then we can make them go on the tour if there has been click on the ticket
   *
   * @param chocolateBar
   * @private
   */
  _flashTicket: function _flashTicket(chocolateBar) {
    // Try get the ticket from the chocolateBar
    var goldenTicket = chocolateBar.querySelector('.js-golden-ticket'); // Only continue if chocolate bar has a golden ticket

    if (isset(goldenTicket)) {
      goldenTicket.addEventListener('click', function () {
        ChocolateFactory.enjoyTheTour(chocolateBar);
      });
    } else {
      console.log('To bad, no golden tickets has been found.');
    }
  },

  /**
   * Start the tour through the factory
   * And get the names and properties of the members of the group
   * If there are members in the group of course
   *
   * @param chocolateFactory
   */
  enjoyTheTour: function enjoyTheTour(chocolateFactory) {
    // Ask for the tour group
    var tourGroup = chocolateFactory.querySelectorAll('input, textarea, select');

    if (isset(tourGroup)) {
      // For each visitor we want a belonging Oompa Loompa
      var oompaLoompas = {};
      var amountOfOompaLoompas = 0;
      var tourGroupSize = tourGroup.length;

      for (var i = 0; i < tourGroupSize; i++) {
        // Get the visitor from the group
        var visitor = tourGroup[i]; // Ask for its name

        var visitorName = visitor.getAttribute('name'); // Check if the visitor is banned

        if (ChocolateFactory._isVisitorBanned(visitorName)) continue;
        oompaLoompas[visitorName] = ChocolateFactory._getArrangement(visitor);
        amountOfOompaLoompas++;
      } // Check for insurance that there are oompa loompas


      if (amountOfOompaLoompas === 0) return; // Send submit request

      ChocolateFactory._finishTour(oompaLoompas, chocolateFactory);
    } else {
      console.log('To bad, no members to visit this factory');
    }
  },

  /**
   * Check if the visitor name isn't allow
   *
   * @param visitorName
   * @returns {boolean}
   * @private
   */
  _isVisitorBanned: function _isVisitorBanned(visitorName) {
    if (ChocolateFactory.bannedVisitor.indexOf(visitorName) !== -1) {
      return true;
    }

    return false;
  },

  /**
   * Most get visitor have a normal arrangement
   * But sometimes there are special cases
   * Like a Selector or checkbox
   *
   * @param visitor
   * @returns {*}
   * @private
   */
  _getArrangement: function _getArrangement(visitor) {
    var visitorType = visitor.nodeName;

    if (visitor.type === 'radio') {
      return document.querySelector('input[name="' + visitor.name + '"]:checked').value;
    }

    switch (visitorType) {
      default:
        return visitor.value;
    }
  },

  /**
   * Finish the tour
   * If successful show thanks message
   * Or show defined error message or fallback
   *
   * @param group
   * @param chocolateFactory
   * @returns {*|void}
   * @private
   */
  _finishTour: function _finishTour(group, chocolateFactory) {
    // Add willie to the group
    group = ChocolateFactory._addWillieWonka(group); // Get the gate for finish the tour

    var gate = '/contact/process';

    try {
      Ajax.post(gate, group, function (HttpRequest) {
        var response = JSON.parse(HttpRequest.response);

        switch (HttpRequest.status) {
          case 200:
            return ChocolateFactory._thanksForVisiting(response.redirectUrl);

          case 422:
            return ChocolateFactory._giveFeedbackToMembers(response.errors, chocolateFactory);

          default:
            break;
        }

        return ChocolateFactory._unknownGapInFactory(chocolateFactory);
      });
    } catch (e) {
      return ChocolateFactory._unknownGapInFactory(chocolateFactory);
    }
  },

  /**
   * Add willie wonka to the group
   * Ps... it actually the secret code!
   *
   * @param group
   * @returns {*}
   * @private
   */
  _addWillieWonka: function _addWillieWonka(group) {
    group._willie = 'wonka';
    return group;
  },

  /**
   * Add the feedback to the desired area.
   * Most likely to the visitor directly, but sometime to the factory desired feedback area
   *
   * @param errors
   * @param chocolateFactory
   * @private
   */
  _giveFeedbackToMembers: function _giveFeedbackToMembers(errors, chocolateFactory) {
    // Grab the factory feedback area
    var feedbackArea = chocolateFactory.querySelector('.js-error-area'); // Clear the current html

    if (isset(feedbackArea)) feedbackArea.innerHTML = ''; // Clear the previous marked jackets

    ChocolateFactory._clearPreviousMarkedJackets(chocolateFactory);

    Object.keys(errors).forEach(function (visitor) {
      var jacket = null;
      var visitorFeedbackArea = null; // Honey elements doesn't has a accessible element

      if (visitor !== '_honey' && visitor !== '_secretCode') {
        // Grab the visitor
        var visitorNode = chocolateFactory.querySelector('#' + visitor); // Find the jacket of a visitor

        jacket = ChocolateFactory._grabVisitorJacket(visitorNode); // If found get the desired area

        if (isset(jacket)) visitorFeedbackArea = jacket.querySelector('.js-form-element-error'); // Clear the current html

        if (isset(visitorFeedbackArea)) visitorFeedbackArea.innerHTML = '';
      } // Get the feedback for this visitor


      var visitorFeedback = errors[visitor]; // Spit out each line

      var visitorFeedbackAmount = visitorFeedback.length;

      for (var i = 0; i < visitorFeedbackAmount; i++) {
        var visitorFeedbackLine = visitorFeedback[i]; // Honey elements doesn't has a accessible element area

        if (visitor !== '_honey' && visitor !== '_secretCode') {
          // Mark the jacket
          if (isset(jacket)) jacket.classList.add('has-error'); // Append feedback to visitor feedback area if defined

          if (isset(visitorFeedbackArea)) {
            var currentFeedbackArea = visitorFeedbackArea.innerHTML;
            currentFeedbackArea += '<span>' + capitalizeFirstLetter(visitorFeedbackLine) + '</span>';
            visitorFeedbackArea.innerHTML = currentFeedbackArea;
          }
        } // Append feedback to factory feedback area if defined


        if (isset(feedbackArea)) {
          var _currentFeedbackArea = feedbackArea.innerHTML;
          _currentFeedbackArea += '<li>' + capitalizeFirstLetter(visitorFeedbackLine) + '</li>';
          feedbackArea.innerHTML = _currentFeedbackArea;
        }
      }
    });
    var top = bodyOffset(chocolateFactory).top - 140;
    window.scrollTo(0, top);
  },

  /**
   * Clear the previous marked jackets
   *
   * @param chocolateFactory
   * @private
   */
  _clearPreviousMarkedJackets: function _clearPreviousMarkedJackets(chocolateFactory) {
    var markedJackets = chocolateFactory.querySelectorAll('.has-error');
    var markedJacketsAmount = markedJackets.length;

    for (var i = 0; i < markedJacketsAmount; i++) {
      var markedJacket = markedJackets[i];
      markedJacket.classList.remove('has-error');
      var markedJacketMessage = markedJacket.querySelector('.js-form-element-error');
      if (isset(markedJacketMessage)) markedJacketMessage.innerHTML = '';
    }
  },

  /**
   * Grab the jacket of the visitor
   *
   * @param visitor
   * @returns {null|*|(() => (Node | null))|ActiveX.IXMLDOMNode|(Node & ParentNode)}
   * @private
   */
  _grabVisitorJacket: function _grabVisitorJacket(visitor) {
    // Check if visitor is defined
    if (!isset(visitor)) return null; // Do loop settings

    currentLayer = visitor;
    safetyBreak = 0; // Grab the next layer till it is the jacket (or safetyBreak has been reached

    do {
      safetyBreak++;
      currentLayer = currentLayer.parentNode;
      if (currentLayer.classList.contains('js-form-element')) return currentLayer;
    } while (currentLayer.tagName !== 'BODY' && safetyBreak <= 10);

    return null;
  },

  /**
   * Redirect the visitor to the thanks page
   *
   * @param nextStop
   * @private
   */
  _thanksForVisiting: function _thanksForVisiting(nextStop) {
    window.location = nextStop;
  },

  /**
   * Unknown error occurred, log the error
   *
   * @param chocolateFactory
   * @private
   */
  _unknownGapInFactory: function _unknownGapInFactory(chocolateFactory) {
    console.log(chocolateFactory);
    console.log('ChocolateFactory: Unkown Error');
  }
};
ChocolateFactory.enter();

/***/ }),

/***/ "./resources/js/components/contactSubjectHandler.js":
/*!**********************************************************!*\
  !*** ./resources/js/components/contactSubjectHandler.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var ContactSubjectHandler = {
  subjectOptions: null,
  subjectOptionalFields: null,
  showOptionalFieldsForSubjectOptions: ['orders', 'parts'],
  init: function init() {
    // Get the form inputs
    ContactSubjectHandler.subjectOptions = document.querySelectorAll('.js-contact-subject');
    ContactSubjectHandler.subjectOptionalFields = document.querySelector('.js-contact-subject-optional');
    var subjectOptionsLength = ContactSubjectHandler.subjectOptions.length;
    if (subjectOptionsLength <= 0 || !isset(ContactSubjectHandler.subjectOptionalFields)) return;

    for (var i = 0; i < subjectOptionsLength; i++) {
      var subjectOption = ContactSubjectHandler.subjectOptions[i];
      subjectOption.addEventListener('change', ContactSubjectHandler.subjectChanged);
    }
  },
  subjectChanged: function subjectChanged() {
    var selectOption = document.querySelector('.js-contact-subject:checked'); // Check if value is in the showOptionalFieldsForSubjectOptions

    if (ContactSubjectHandler.showOptionalFieldsForSubjectOptions.indexOf(selectOption.value) !== -1) {
      ContactSubjectHandler.subjectOptionalFields.classList.remove('is-hidden');
    } else {
      ContactSubjectHandler.subjectOptionalFields.classList.add('is-hidden');
    }
  }
};
ContactSubjectHandler.init();

/***/ }),

/***/ "./resources/js/components/cookieHandler.js":
/*!**************************************************!*\
  !*** ./resources/js/components/cookieHandler.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   Cookie handler
   - Primary usage for toggling the cookie message and/or switch
 ========================================================================== */
var CookieHandler = {
  cookieBar: null,
  cookieOverlay: null,
  cookieMessage: null,
  cookieSwitch: null,
  cookieFadeOutAnimationDuration: 400,
  acceptTracking: false,
  // Initialize cookie handler
  init: function init() {
    // Bind cookie bar or overlay to cookieMessage
    CookieHandler.cookieMessage = document.querySelector('.js-cookie-bar, .js-cookie-overlay'); // Bind cookie bar to cookieBar

    CookieHandler.cookieBar = document.querySelector('.js-cookie-bar'); // If isset init the functions for cookie bar

    if (isset(CookieHandler.cookieBar)) {
      CookieHandler.initCookieBar();
    } else {
      // Else try to connect cookie overlay with tracking to cookieOverlay
      CookieHandler.cookieOverlay = document.querySelector('.js-cookie-overlay'); // If isset init the functions for cookie overlay

      if (isset(CookieHandler.cookieOverlay)) {
        CookieHandler.initCookieOverlay();
      }
    } // If either type of cookie has been found check if settings are defined


    if (isset(CookieHandler.cookieMessage)) {
      CookieHandler.checkForCookieSettings();
    } // Bind cookie switch to Handler


    CookieHandler.cookieSwitch = document.querySelector('.js-cookie-switch'); // If isset init the functions for cookie switch

    if (isset(CookieHandler.cookieSwitch)) {
      CookieHandler.initCookieSwitch();
    }
  },
  // Init the cookie bar actions
  initCookieBar: function initCookieBar() {
    var closeButton = CookieHandler.cookieBar.querySelector('.js-disable-cookie-bar');

    if (isset(closeButton)) {
      closeButton.addEventListener('click', CookieHandler.closeCookieMessage);
    }
  },
  // Init the cookie overlay actions
  initCookieOverlay: function initCookieOverlay() {
    // Open the cookie settings event
    var openCookieSettingsButton = CookieHandler.cookieMessage.querySelector('.js-change-cookies-settings');

    if (isset(openCookieSettingsButton)) {
      openCookieSettingsButton.addEventListener('click', CookieHandler.openCookieSettings);
    } // Toggle of the tracking input


    var toggleTrackingInput = CookieHandler.cookieMessage.querySelector('.c-cookie-type__input--tracking');

    if (isset(toggleTrackingInput)) {
      if (toggleTrackingInput.checked === true) {
        CookieHandler.acceptTracking = true;
      }

      toggleTrackingInput.addEventListener('change', CookieHandler.toggleTrackingSetting);
    } // Accept / Save cookies button event


    var acceptButton = CookieHandler.cookieMessage.querySelector('.js-accept-cookies');

    if (isset(acceptButton)) {
      acceptButton.addEventListener('click', CookieHandler.setCookieSettings);
    }
  },
  // Init the cookie switch actions
  initCookieSwitch: function initCookieSwitch() {
    // Toggle of the tracking input
    var toggleTrackingInput = CookieHandler.cookieSwitch.querySelector('.c-cookie-type__input--tracking');

    if (isset(toggleTrackingInput)) {
      // Force the state of the cookie switch input because the pop-up is forced on checked
      // while the switch checks by php if the cookie really exist or not
      if (toggleTrackingInput.checked === true) {
        CookieHandler.acceptTracking = true;
      } else {
        CookieHandler.acceptTracking = false;
      }

      toggleTrackingInput.addEventListener('change', CookieHandler.toggleTrackingSetting);
    } // Save cookies button event


    var saveButton = CookieHandler.cookieSwitch.querySelector('.js-save-cookie-settings');

    if (isset(saveButton)) {
      saveButton.addEventListener('click', function () {
        CookieHandler.cookieFadeOutAnimationDuration = 0; // On the switch click we want no delay :)

        CookieHandler.setCookieSettings();
      });
    }
  },
  checkForCookieSettings: function checkForCookieSettings() {
    if (Cookie.get('cookieMessage')) {
      CookieHandler.cookieMessage.classList.add('is-accepted');
    } else {
      CookieHandler.cookieMessage.classList.remove('is-accepted');
      document.body.classList.add('is-cookie-bar-visible');
    }
  },
  closeCookieMessage: function closeCookieMessage() {
    Cookie.set('cookieMessage', true, 90);
    CookieHandler.cookieMessage.classList.add('is-transitioning-out');
    document.body.classList.remove('is-cookie-bar-visible');
  },
  openCookieSettings: function openCookieSettings() {
    CookieHandler.cookieOverlay.querySelector('.js-cookie-settings').classList.remove('is-hidden');
    CookieHandler.cookieOverlay.querySelector('.js-cookie-info').classList.add('is-hidden');
  },
  toggleTrackingSetting: function toggleTrackingSetting() {
    if (CookieHandler.acceptTracking) {
      CookieHandler.acceptTracking = false;
    } else {
      CookieHandler.acceptTracking = true;
    }
  },
  setCookieSettings: function setCookieSettings() {
    // Set tracking cookie or delete it if isset according to the desired settings
    if (CookieHandler.acceptTracking) {
      Cookie.set('trackingCookieAccepted', 'true', 90);
    } else {
      if (Cookie.get('trackingCookieAccepted')) {
        Cookie.erase('trackingCookieAccepted');
      }
    }

    CookieHandler.closeCookieMessage(); // Reload after animation to automatically trigger the tracking after accepting it

    setTimeout(function () {
      location.reload();
    }, CookieHandler.cookieFadeOutAnimationDuration);
  }
};
CookieHandler.init();

/***/ }),

/***/ "./resources/js/components/customerLogoSliderHandler.js":
/*!**************************************************************!*\
  !*** ./resources/js/components/customerLogoSliderHandler.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   // Copied from Rentman project, then edited slightly and added autoSlide

   Customer logos slider handler
   - Slide to next logo.
 ========================================================================== */
var CustomerLogoSliderHandler = {
  customerLogoSliderArea: null,
  customerLogoSlides: null,
  activeLogo: 2,
  autoSlideTimeoutHandle: null,
  autoSlideRestartTimeoutHandle: null,
  autoSlideInterval: 2000,
  autoSlideRestartInterval: 2000,
  init: function init() {
    CustomerLogoSliderHandler.customerLogoSliderArea = document.querySelector('.js-customer-logo-slider'); // Only continue the init if the customer logo area is found

    if (isset(CustomerLogoSliderHandler.customerLogoSliderArea)) {
      CustomerLogoSliderHandler.customerLogoSlides = CustomerLogoSliderHandler.customerLogoSliderArea.querySelectorAll('.js-customer-logo-slide');

      if (CustomerLogoSliderHandler.customerLogoSlides.length >= 5) {
        CustomerLogoSliderHandler.addEvents();
        CustomerLogoSliderHandler.resetLogosOrder();
        CustomerLogoSliderHandler.finishLoading();
      } else {
        console.log('CustomerLogoSlider: Add more customer logos to the slider');
      }
    }
  },
  addEvents: function addEvents() {
    var next = CustomerLogoSliderHandler.customerLogoSliderArea.querySelector('.js-slider-button.next');
    var previous = CustomerLogoSliderHandler.customerLogoSliderArea.querySelector('.js-slider-button.previous');
    next.addEventListener('click', function () {
      CustomerLogoSliderHandler.nextLogo();
      CustomerLogoSliderHandler.updateSlider();
      clearTimeout(CustomerLogoSliderHandler.autoSlideTimeoutHandle);
      CustomerLogoSliderHandler.resetAutoSliding();
    });
    previous.addEventListener('click', function () {
      CustomerLogoSliderHandler.previousLogo();
      CustomerLogoSliderHandler.updateSlider();
      clearTimeout(CustomerLogoSliderHandler.autoSlideTimeoutHandle);
      CustomerLogoSliderHandler.resetAutoSliding();
    }); // Swipe interaction

    var swipeGestures = new Hammer(CustomerLogoSliderHandler.customerLogoSliderArea);
    swipeGestures.on('swipeleft', function () {
      CustomerLogoSliderHandler.nextLogo();
      CustomerLogoSliderHandler.updateSlider();
      CustomerLogoSliderHandler.resetAutoSliding();
    });
    swipeGestures.on('swiperight', function () {
      CustomerLogoSliderHandler.previousLogo();
      CustomerLogoSliderHandler.updateSlider();
      CustomerLogoSliderHandler.resetAutoSliding();
    });
  },
  resetAutoSliding: function resetAutoSliding() {
    CustomerLogoSliderHandler.stopAutoSliding();
    CustomerLogoSliderHandler.startAutoSliding();
  },
  stopAutoSliding: function stopAutoSliding() {
    clearTimeout(CustomerLogoSliderHandler.autoSlideTimeoutHandle);
    clearTimeout(CustomerLogoSliderHandler.autoSlideRestartTimeoutHandle);
    CustomerLogoSliderHandler.autoSlideTimeoutHandle = null;
  },
  startAutoSliding: function startAutoSliding() {
    if (!CustomerLogoSliderHandler.autoSlideTimeoutHandle) CustomerLogoSliderHandler.autoSlideRestartTimeoutHandle = setTimeout(CustomerLogoSliderHandler.doAutoSlide, CustomerLogoSliderHandler.autoSlideRestartInterval);
  },
  getLogoIds: function getLogoIds() {
    var customerLogosLength = CustomerLogoSliderHandler.customerLogoSlides.length;
    var customerLogoIds = [];

    for (var i = 0; i < customerLogosLength; i++) {
      var customerLogo = CustomerLogoSliderHandler.customerLogoSlides[i];
      var customerLogoId = customerLogo.getAttribute('data-logo-id');
      customerLogoIds.push(customerLogoId);
    }

    return {
      ids: customerLogoIds
    };
  },
  finishLoading: function finishLoading() {
    CustomerLogoSliderHandler.customerLogoSliderArea.querySelector('.js-customer-logo-slide-container').classList.remove('is-loading');
    CustomerLogoSliderHandler.startAutoSliding();
  },
  doAutoSlide: function doAutoSlide() {
    CustomerLogoSliderHandler.autoSlideTimeoutHandle = setTimeout(CustomerLogoSliderHandler.doAutoSlide, CustomerLogoSliderHandler.autoSlideInterval);
    CustomerLogoSliderHandler.nextLogo();
    CustomerLogoSliderHandler.updateSlider();
  },
  nextLogo: function nextLogo() {
    // Increment active logo id
    CustomerLogoSliderHandler.activeLogo++; // If it's the same as length then reset it to zero

    if (CustomerLogoSliderHandler.activeLogo === CustomerLogoSliderHandler.customerLogoSlides.length) CustomerLogoSliderHandler.activeLogo = 0;
  },
  previousLogo: function previousLogo() {
    // Decrement active logo id
    CustomerLogoSliderHandler.activeLogo--; // If it's below zero reset it to last item

    if (CustomerLogoSliderHandler.activeLogo < 0) CustomerLogoSliderHandler.activeLogo = CustomerLogoSliderHandler.customerLogoSlides.length - 1;
  },
  resetLogosOrder: function resetLogosOrder() {
    CustomerLogoSliderHandler.customerLogoSlides = CustomerLogoSliderHandler.customerLogoSliderArea.querySelectorAll('.js-customer-logo-slide');
    var customerLogosLength = CustomerLogoSliderHandler.customerLogoSlides.length;

    for (var i = 0; i < customerLogosLength; i++) {
      var customerLogo = CustomerLogoSliderHandler.customerLogoSlides[i];
      customerLogo.setAttribute('data-slide-id', i);
    }

    CustomerLogoSliderHandler.updateSlider();
  },
  updateSlider: function updateSlider() {
    var previousLocator = CustomerLogoSliderHandler._calcPreviousPositions(3);

    var previouser = CustomerLogoSliderHandler._calcPreviousPositions(2);

    var previous = CustomerLogoSliderHandler._calcPreviousPositions(1);

    var next = CustomerLogoSliderHandler._calcNextPositions(1);

    var nexter = CustomerLogoSliderHandler._calcNextPositions(2);

    var nexterLocator = CustomerLogoSliderHandler._calcNextPositions(3);

    for (var i = 0; i < CustomerLogoSliderHandler.customerLogoSlides.length; i++) {
      var slide = CustomerLogoSliderHandler.customerLogoSlides[i]; // Reset all possible classes

      slide.classList.remove('c-customer-logo-slider__item--pre-previous');
      slide.classList.remove('c-customer-logo-slider__item--position-1');
      slide.classList.remove('c-customer-logo-slider__item--position-2');
      slide.classList.remove('c-customer-logo-slider__item--position-3');
      slide.classList.remove('c-customer-logo-slider__item--position-4');
      slide.classList.remove('c-customer-logo-slider__item--position-5');
      slide.classList.remove('c-customer-logo-slider__item--pre-next');
      slide.classList.remove('is-hidden');

      switch (i) {
        case previousLocator:
          slide.classList.add('c-customer-logo-slider__item--pre-previous');
          break;

        case previouser:
          slide.classList.add('c-customer-logo-slider__item--position-1');
          break;

        case previous:
          slide.classList.add('c-customer-logo-slider__item--position-2');
          break;

        case CustomerLogoSliderHandler.activeLogo:
          slide.classList.add('c-customer-logo-slider__item--position-3');
          break;

        case next:
          slide.classList.add('c-customer-logo-slider__item--position-4');
          break;

        case nexter:
          slide.classList.add('c-customer-logo-slider__item--position-5');
          break;

        case nexterLocator:
          slide.classList.add('c-customer-logo-slider__item--pre-next');
          break;

        default:
          slide.classList.add('is-hidden');
      }
    }
  },
  _calcPreviousPositions: function _calcPreviousPositions($amount) {
    var location = CustomerLogoSliderHandler.activeLogo - $amount;
    if (location < 0) return CustomerLogoSliderHandler.customerLogoSlides.length + location;
    return location;
  },
  _calcNextPositions: function _calcNextPositions($amount) {
    var location = CustomerLogoSliderHandler.activeLogo + $amount;
    if (location >= CustomerLogoSliderHandler.customerLogoSlides.length) return location - CustomerLogoSliderHandler.customerLogoSlides.length;
    return location;
  },
  _prepareCustomerLogoHtml: function _prepareCustomerLogoHtml(customerLogosHtml, customerLogo) {
    customerLogosHtml += '<a target="_blank" rel="nofollow noopener noreferrer" class="c-customer-logo-slider__item  js-customer-logo-slide" ';
    if (isset(customerLogo.url)) customerLogosHtml += 'href="' + customerLogo.url + '" aria-label="Go to our partners website: ' + customerLogo.url + '" ';
    customerLogosHtml += 'data-slide-id="" data-logo-id="' + customerLogo.id + '">' + '<div class="c-customer-logo-slider__logo" style="background-image: url(' + "'" + customerLogo.image + "'" + ')"></div>' + '</a>';
    return customerLogosHtml;
  }
};
CustomerLogoSliderHandler.init();

/***/ }),

/***/ "./resources/js/components/errorController.js":
/*!****************************************************!*\
  !*** ./resources/js/components/errorController.js ***!
  \****************************************************/
/*! exports provided: ErrorController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorController", function() { return ErrorController; });
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * Controls a div with an ul in it to show errors or not
 */
var ErrorController = /*#__PURE__*/function () {
  function ErrorController() {
    _classCallCheck(this, ErrorController);

    this._classToHide = 'u-hidden';
    this._errorElementIdSuffix = '-error';
  }
  /**
   * @param {string} fieldSelector
   * @param {string} error
   */


  _createClass(ErrorController, [{
    key: "setFieldError",
    value: function setFieldError(fieldSelector, error) {
      var selector = '#' + fieldSelector + this._errorElementIdSuffix;
      var errorElement = document.querySelector(selector);
      if (!errorElement) return;
      errorElement.classList.remove(this._classToHide);
      errorElement.innerText = error;
    }
    /**
     * @param {string} fieldSelector
     */

  }, {
    key: "clearFieldError",
    value: function clearFieldError(fieldSelector) {
      var selector = '#' + fieldSelector + this._errorElementIdSuffix;
      var errorElement = document.querySelector(selector);
      if (!errorElement) return;
      errorElement.classList.add(this._classToHide);
      errorElement.innerText = '';
    }
    /**
     * Clear all errors
     */

  }, {
    key: "clearAllErrors",
    value: function clearAllErrors() {
      var self = this;
      document.querySelectorAll('[id$=' + this._errorElementIdSuffix + ']').forEach(function (errorElement) {
        errorElement.classList.add(self._classToHide);
        errorElement.innerText = '';
      });
    }
  }]);

  return ErrorController;
}();



/***/ }),

/***/ "./resources/js/components/fileUploadHandler.js":
/*!******************************************************!*\
  !*** ./resources/js/components/fileUploadHandler.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   FileUpload handler
   - Handles the FileUpload component which has the proper classes.
   - Can only be used in conjunction with ChocolateFactory which handles the post.
 ========================================================================== */
var FileUploadHandler = {
  fileUploadWrapperClass: '.js-file-upload',
  fileUploadListClass: '.js-file-upload__list',
  fileUploadInputClass: '.js-file-upload__input',
  fileUploadButtonClass: '.js-file-upload__button',
  init: function init() {
    var fileUploads = document.querySelectorAll(FileUploadHandler.fileUploadWrapperClass);
    var fileUploadsCount = fileUploads.length;

    if (isset(fileUploads) && fileUploadsCount !== 0) {
      for (var i = 0; i < fileUploadsCount; i++) {
        var fileUpload = fileUploads[i];
        this.initFileUploadHandler(fileUpload);
      }
    }
  },
  addFile: function addFile(inputElement) {
    if (!inputElement) return;
    var node = inputElement.cloneNode();
    var list = inputElement.parentNode.parentNode.querySelector(FileUploadHandler.fileUploadListClass);
    var li = document.createElement('li');
    var remove = document.createElement('button');
    var textNode = document.createTextNode(inputElement.value.split("\\")[inputElement.value.split('\\').length - 1]);
    node.value = "";
    node.addEventListener('change', this.eventHandler);
    remove.setAttribute('type', 'button');
    remove.addEventListener('click', this.eventHandler);
    inputElement.parentNode.appendChild(node);
    inputElement.style.display = 'none';
    li.appendChild(inputElement);
    li.appendChild(textNode);
    li.appendChild(remove);
    list.appendChild(li);
  },
  removeFile: function removeFile(event) {
    event.target.parentNode.parentNode.removeChild(event.target.parentNode);
  },
  eventHandler: function eventHandler(event) {
    switch (event.type) {
      case 'click':
        if (event.target.classList.contains(FileUploadHandler.fileUploadButtonClass.substring(1))) {
          event.target.parentNode.querySelector(FileUploadHandler.fileUploadInputClass).click();
        } else {
          FileUploadHandler.removeFile(event);
        }

        break;

      case 'change':
        FileUploadHandler.addFile(event.target);
        break;
    }
  },
  initFileUploadHandler: function initFileUploadHandler(fileUpload) {
    var inputElement = fileUpload.querySelector(FileUploadHandler.fileUploadInputClass);
    var inputButtonElement = fileUpload.querySelector(FileUploadHandler.fileUploadButtonClass);
    inputButtonElement.addEventListener('click', this.eventHandler);
    inputElement.addEventListener('change', this.eventHandler);
  }
};
FileUploadHandler.init();

/***/ }),

/***/ "./resources/js/components/mapsHandler.js":
/*!************************************************!*\
  !*** ./resources/js/components/mapsHandler.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
    Google Maps handler
    - https://developers.google.com/maps/documentation/javascript/adding-a-google-map
 ========================================================================== */
var MapsHandler = {
  maps: [],
  key: 'AIzaSyDGoIyeTX10xLM8ZJLb-S6Htv-tEhAiYYM',
  init: function init() {
    // Get map elements
    var maps = document.querySelectorAll('.js-google-map'); // If there are map elements loop through them and draw the maps

    if (maps.length !== 0) {
      // Convert elements into object for callback when script as been loaded
      for (var i = 0; i < maps.length; i++) {
        // Get map from nodeList
        var map = maps[i];
        if (!map.hasAttribute('data-google-lat') || !map.hasAttribute('data-google-lng')) continue;
        var lat = parseFloat(map.getAttribute('data-google-lat'));
        var lng = parseFloat(map.getAttribute('data-google-lng'));
        MapsHandler.maps.push({
          node: map,
          location: {
            lat: lat,
            lng: lng
          },
          styles: MapsHandler.setCustomStyling()
        });
      } // See if google variable exists


      if (typeof google == 'undefined' || typeof google.maps == 'undefined') {
        // Load external script with drawMaps callback
        getScript('https://maps.googleapis.com/maps/api/js?key=' + MapsHandler.key, MapsHandler.drawMaps);
      } else {
        // If already loaded draw maps
        MapsHandler.drawMaps();
      }
    }
  },

  /**
   * Draw the google maps
   */
  drawMaps: function drawMaps() {
    for (var i = 0; i < MapsHandler.maps.length; i++) {
      var map = MapsHandler.maps[i]; // Create a map

      var googleMap = new google.maps.Map(map.node, {
        zoom: 11,
        center: map.location,
        disableDefaultUI: true,
        styles: map.styles
      }); // Add a marker

      var marker = new google.maps.Marker({
        position: map.location,
        map: googleMap
      });
    }
  },

  /**
   * Set the custom styling for the Google Maps
   *
   * @returns {*[]}
   */
  setCustomStyling: function setCustomStyling() {
    return [{
      "featureType": "poi",
      "elementType": "labels.text.fill",
      "stylers": [{
        "color": "#747474"
      }, {
        "lightness": "23"
      }]
    }, {
      "featureType": "poi.attraction",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#f38eb0"
      }]
    }, {
      "featureType": "poi.government",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#ced7db"
      }]
    }, {
      "featureType": "poi.medical",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#ffa5a8"
      }]
    }, {
      "featureType": "poi.park",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#c7e5c8"
      }]
    }, {
      "featureType": "poi.place_of_worship",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#d6cbc7"
      }]
    }, {
      "featureType": "poi.school",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#c4c9e8"
      }]
    }, {
      "featureType": "poi.sports_complex",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#b1eaf1"
      }]
    }, {
      "featureType": "road",
      "elementType": "geometry",
      "stylers": [{
        "lightness": "100"
      }]
    }, {
      "featureType": "road",
      "elementType": "labels",
      "stylers": [{
        "visibility": "off"
      }, {
        "lightness": "100"
      }]
    }, {
      "featureType": "road.highway",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#ffd4a5"
      }]
    }, {
      "featureType": "road.arterial",
      "elementType": "geometry.fill",
      "stylers": [{
        "color": "#ffe9d2"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "all",
      "stylers": [{
        "visibility": "simplified"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "geometry.fill",
      "stylers": [{
        "weight": "3.00"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "geometry.stroke",
      "stylers": [{
        "weight": "0.30"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "labels.text",
      "stylers": [{
        "visibility": "on"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "labels.text.fill",
      "stylers": [{
        "color": "#747474"
      }, {
        "lightness": "36"
      }]
    }, {
      "featureType": "road.local",
      "elementType": "labels.text.stroke",
      "stylers": [{
        "color": "#e9e5dc"
      }, {
        "lightness": "30"
      }]
    }, {
      "featureType": "transit.line",
      "elementType": "geometry",
      "stylers": [{
        "visibility": "on"
      }, {
        "lightness": "100"
      }]
    }, {
      "featureType": "water",
      "elementType": "all",
      "stylers": [{
        "color": "#d2e7f7"
      }]
    }];
  }
};
MapsHandler.init();

/***/ }),

/***/ "./resources/js/components/overlayMenuHandler.js":
/*!*******************************************************!*\
  !*** ./resources/js/components/overlayMenuHandler.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* ==========================================================================
   Navigation handler
   - Handles the showing and hiding of the overlay-menu component which has the proper classes.
 ========================================================================== */
var bodyScrollLock = __webpack_require__(/*! body-scroll-lock */ "./node_modules/body-scroll-lock/lib/bodyScrollLock.min.js");

var OverlayMenuHandler = {
  // init: function () {
  //     const overlayMenuTrigger = document.querySelector('.js-overlay-menu-trigger');
  //     OverlayMenuHandler.initOverlayMenu(overlayMenuTrigger);
  // },
  init: function init() {
    var overlayMenuTriggerList = document.querySelectorAll('.js-overlay-menu-trigger');
    var overlayMenuTriggerListCount = overlayMenuTriggerList.length;

    if (isset(overlayMenuTriggerList) && overlayMenuTriggerListCount !== 0) {
      for (var i = 0; i < overlayMenuTriggerListCount; i++) {
        var overlayMenuTrigger = overlayMenuTriggerList[i];
        OverlayMenuHandler.initOverlayMenu(overlayMenuTrigger);
      }
    }
  },
  initOverlayMenu: function initOverlayMenu(overlayMenuTrigger) {
    overlayMenuTrigger.addEventListener('click', OverlayMenuHandler.toggleOverlayMenu, false);
  },
  toggleOverlayMenu: function toggleOverlayMenu(event) {
    var overlayMenuNav = document.querySelector('.js-overlay-menu'); // const overlayMenuBody = overlayMenu.querySelector('.js-overlay-menu-persist-scrolling');
    // Bail if overlayMenu doesn't exist

    if (!overlayMenuNav) return; // Clear previously locked scroll on the body

    bodyScrollLock.enableBodyScroll(overlayMenuNav); // If the overlayMenu is already active, collapse it and quit

    if (document.body.classList.contains('is-overlay-menu-active')) {
      overlayMenuNav.querySelectorAll('[tabindex="0"]').forEach(function (elem) {
        elem.tabIndex = -1;
      });
      document.body.classList.remove('is-overlay-menu-active');
      return;
    } // Lock scrolling on the body


    bodyScrollLock.disableBodyScroll(overlayMenuNav);
    overlayMenuNav.querySelectorAll('[tabindex="-1"]').forEach(function (elem) {
      elem.tabIndex = 0;
    }); // Toggle active overlayMenu by setting a class on the body

    document.body.classList.toggle('is-overlay-menu-active');
    overlayMenuNav.hidden = false;
  }
};
OverlayMenuHandler.init();

/***/ }),

/***/ "./resources/js/components/projectorHandler.js":
/*!*****************************************************!*\
  !*** ./resources/js/components/projectorHandler.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/**
 * Created by Pascal on 06/12/17.
 * (Name changes by Rob on 18/03/18)
 */

/* Example

const headerImageSliderSetting = new ProjectorSetting({
    sliderProjectorId: 'header-image-slider',
    slideQuery: '#header-image-slider .placeholder figure',
    dots: '#header-image-slider .slider-navigation-labels .navigation span',
    captions: '#header-image-slider .slider-navigation-labels .caption p',
    autoSlide: true,
    sliderInterval: 4000
});
headerImageSliderSetting = headerImageSliderSetting.prepareParameters();

const headerImageSlider = new Projector(headerImageSliderSetting).init();

 */
var projectors = [];
var projectorContainers = document.querySelectorAll('.js-projector');
var projectorContainersLength = projectorContainers.length;

for (var i = 0; i < projectorContainersLength; i++) {
  var projector = projectorContainers[i];
  var projectorId = projector.getAttribute('id');

  if (projectorId !== null) {
    var projectorSetting = new ProjectorSetting({
      sliderId: projectorId,
      slideQuery: '#' + projectorId + ' .js-projector-slide',
      navigationButtons: '#' + projectorId + ' .js-projector-button',
      dots: '#' + projectorId + ' .js-projector-indicator',
      autoSlide: true,
      sliderInterval: 4000
    });
    projectors.push(new Projector(projectorSetting.prepareParameters()).init());
  } else console.log('An image slider has no id...');
}

function ProjectorSetting(settingsObject) {
  var self = this;
  this.sliderId = '';
  this.definedPreviousNext = true;
  this.autoSlide = false;
  this.sliderInterval = 4000;
  this.navigationButtons = '';
  this.dots = '';
  this.captions = '';
  this.slideQuery = '';

  this.setProjectorId = function (string) {
    this.sliderId = string;
    return this;
  };

  this.setDefinedPreviousNext = function (_boolean) {
    this.definedPreviousNext = _boolean;
    return this;
  };

  this.setAutoSlide = function (_boolean2) {
    this.autoSlide = _boolean2;
    return this;
  };

  this.setSliderInterval = function (integer) {
    this.sliderInterval = integer;
    return this;
  };

  this.setSlideQuery = function (string) {
    this.slideQuery = string;
    return this;
  };

  this.setNavigationButtons = function (string) {
    this.navigationButtons = string;
    return this;
  };

  this.setDots = function (string) {
    this.dots = string;
    return this;
  };

  this.setCaptions = function (string) {
    this.captions = string;
    return this;
  };

  this.getProjectorId = function () {
    return this.sliderId;
  };

  this.getDefinedPreviousNext = function () {
    return this.definedPreviousNext;
  };

  this.getAutoSlide = function () {
    return this.autoSlide;
  };

  this.getSliderInterval = function () {
    return this.sliderInterval;
  };

  this.getSlideQuery = function () {
    return this.slideQuery;
  };

  this.getNavigationButtons = function () {
    return this.navigationButtons;
  };

  this.getDots = function () {
    return this.dots;
  };

  this.getCaptions = function () {
    return this.captions;
  }; // Invert setters to getters


  this.prepareParameters = function () {
    return {
      sliderId: self.getProjectorId(),
      definedPreviousNext: self.getDefinedPreviousNext(),
      autoSlide: self.getAutoSlide(),
      sliderInterval: self.getSliderInterval(),
      navigationButtons: self.getNavigationButtons(),
      dots: self.getDots(),
      captions: self.getCaptions(),
      slideQuery: self.getSlideQuery()
    };
  }; // Mass assign settings


  this.fill = function () {
    // Object.keys(settingsObject).forEach(function (key) {
    //     self[key] = settingsObject[key];
    // });
    var settingsObjectKeys = Object.keys(settingsObject);
    var settingsObjectLength = settingsObjectKeys.length;

    for (var _i = 0; _i < settingsObjectLength; _i++) {
      var key = settingsObjectKeys[_i];
      self[key] = settingsObject[key];
    }
  };

  this.fill();
  return {
    sliderId: self.setProjectorId,
    definedPreviousNext: self.setDefinedPreviousNext,
    autoSlide: self.setAutoSlide,
    sliderInterval: self.setSliderInterval,
    navigationButtons: self.setNavigationButtons,
    dots: self.setDots,
    captions: self.setCaptions,
    slideQuery: self.setSlideQuery,
    prepareParameters: self.prepareParameters
  };
}

function Projector(settings) {
  //Define Projector object
  var self = this;
  this.sliderObject = ''; //SlideParameters

  this.activeSlideId = 0;
  this.previousSlideId = 0;
  this.nextSlideId = 0;
  this.availableSlides = 1;
  this.slides = [];
  this.autoSlideInterval = null;
  this.settings = {};

  this.init = function () {
    //Append settings to self
    this.settings = settings; //Assign needed elements and calculations

    this.sliderObject = document.getElementById(this.settings.sliderId);
    this.slides = document.querySelectorAll(this.settings.slideQuery);
    this.availableSlides = this.slides.length;
    this.activeSlideId = 0; //Define previous and next if we want to use those

    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide(); // Set active slide (and possible previous and next classes)

    this.setSlide(); // Swipe interaction

    var swipeGestures = new Hammer(this.sliderObject);
    swipeGestures.on('swipeleft', function () {
      self.resetAutoSlide();
      self.nextSlide();
      self.setSlide();
    });
    swipeGestures.on('swiperight', function () {
      self.resetAutoSlide();
      self.previousSlide();
      self.setSlide();
    });

    if (this.settings.navigationButtons !== '') {
      // Click interaction
      var navigationButtons = document.querySelectorAll(this.settings.navigationButtons);
      var navigationButtonsLength = navigationButtons.length;

      for (var _i2 = 0; _i2 < navigationButtonsLength; _i2++) {
        var navigationButton = navigationButtons[_i2];
        navigationButton.addEventListener('click', function () {
          self.clickNavigationButton(this);
        });
      }
    }

    if (this.settings.dots !== '') {
      // Click interaction
      var dots = document.querySelectorAll(this.settings.dots);
      var dotsLength = dots.length; // console.log(this.settings.dots);
      // console.log(dots);

      for (var _i3 = 0; _i3 < dotsLength; _i3++) {
        var dot = dots[_i3]; // console.log('hier');

        dot.addEventListener('click', function () {
          self.clickDot(this);
        });
      }
    }

    self.autoSlide();
  };

  this.autoSlide = function () {
    if (this.autoSlideInterval !== null) clearInterval(this.autoSlideInterval);

    if (this.settings.autoSlide && Number.isInteger(this.settings.sliderInterval)) {
      this.autoSlideInterval = setInterval(function () {
        self.nextSlide();
        self.setSlide();
      }, this.settings.sliderInterval);
    }
  };

  this.resetAutoSlide = self.autoSlide;

  this.nextSlide = function () {
    this.activeSlideId++;
    if (this.activeSlideId >= this.availableSlides) this.activeSlideId = 0;
    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
  };

  this.previousSlide = function () {
    this.activeSlideId--;
    if (this.activeSlideId < 0) this.activeSlideId = this.availableSlides - 1;
    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
  };

  this.setPreviousAndNextSlide = function () {
    this.nextSlideId = this.activeSlideId + 1;
    if (this.nextSlideId >= this.availableSlides) this.nextSlideId = 0;
    this.previousSlideId = this.activeSlideId - 1;
    if (this.previousSlideId < 0) this.previousSlideId = this.availableSlides - 1;
  };

  this.setSlide = function () {
    // Loop through the form elements
    var slidesLength = self.slides.length;

    for (var _i4 = 0; _i4 < slidesLength; _i4++) {
      var slide = self.slides[_i4]; // Convert data set attribute to desired type

      var slideOrder = parseInt(slide.getAttribute('data-order')); // Remove and set active for all slides

      if (slideOrder !== self.activeSlideId) slide.classList.remove('is-active');else slide.classList.add('is-active'); // If we use the previous and next, also set those classes

      if (self.settings.definedPreviousNext) {
        if (slideOrder !== self.previousSlideId) slide.classList.remove('previous');else slide.classList.add('previous');
        if (slideOrder !== self.nextSlideId) slide.classList.remove('next');else slide.classList.add('next');
      }
    }

    if (self.settings.dots !== '') {
      self.setActiveDot();
    }

    if (self.settings.captions !== '') {
      self.setActiveCaption();
    }
  };

  this.clickNavigationButton = function (navButton) {
    self.activeSlideId = parseInt(navButton.getAttribute('data-order'));
    if (self.settings.definedPreviousNext) self.setPreviousAndNextSlide();
    self.setSlide();
    var next = document.querySelector(self.settings.navigationButtons + '.next');
    var previous = document.querySelector(self.settings.navigationButtons + '.previous');
    next.setAttribute('data-order', self.nextSlideId);
    previous.setAttribute('data-order', self.previousSlideId);
    self.resetAutoSlide(); // next.querySelector('p').innerHTML = self.slides[self.nextSlideId].dataset.name;
    // previous.querySelector('p').innerHTML = self.slides[self.previousSlideId].dataset.name;
  };

  this.clickDot = function (clickedDot) {
    self.activeSlideId = parseInt(clickedDot.getAttribute('data-order'));
    self.setSlide();
    self.resetAutoSlide();
  };

  this.setActiveDot = function () {
    var dots = document.querySelectorAll(this.settings.dots);
    var dotsLength = dots.length;

    for (var _i5 = 0; _i5 < dotsLength; _i5++) {
      var dot = dots[_i5];
      dotOrder = parseInt(dot.getAttribute('data-order'));
      if (dotOrder !== self.activeSlideId) dot.classList.remove('is-active');else dot.classList.add('is-active');
    }
  };

  this.setActiveCaption = function () {
    var captions = document.querySelectorAll(this.settings.captions);
    var captionsLength = captions.length;

    for (var _i6 = 0; _i6 < captionsLength; _i6++) {
      var caption = captions[_i6];
      captionOrder = parseInt(caption.getAttribute('data-order'));
      if (captionOrder !== self.activeSlideId) caption.classList.remove('is-active');else caption.classList.add('is-active');
    }
  };
}

/***/ }),

/***/ "./resources/js/components/scrollToHandler.js":
/*!****************************************************!*\
  !*** ./resources/js/components/scrollToHandler.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
    Scroll To Click handler
 ========================================================================== */
var ScrollToHandler = {
  // Animation settings
  offset: 60,
  //pixel
  duration: 1400,
  //ms
  // Animation variables
  body: null,
  start: 0,
  change: 0,
  currentTime: 0,
  allowAnimation: false,
  scrollToAnimation: null,
  // Watch the EasingFunction helper for the available methods
  easing: 'easeInOutQuad',
  init: function init() {
    var anchorLinks = document.querySelectorAll('.js-scroll-to-target');
    var anchorLinksAmount = anchorLinks.length;

    for (var i = 0; i < anchorLinksAmount; i++) {
      var anchorLink = anchorLinks[i];
      anchorLink.addEventListener('click', function (event) {
        ScrollToHandler.prepareScrollTo(this.getAttribute('href'));
        event.preventDefault();
      });
    }
  },

  /**
   * Prepare the Handler for the animation
   */
  prepareScrollTo: function prepareScrollTo(elementId) {
    // Get the scroll to element
    elementId = elementId.substr(elementId.indexOf('#') + 1);
    var scrollToElement = document.getElementById(elementId);
    var scrollToElementPosition = scrollToElement.getBoundingClientRect(); // Reset or define the Handler variables

    ScrollToHandler.body = document.documentElement;
    ScrollToHandler.start = Math.max(ScrollToHandler.body.scrollTop, document.body.scrollTop, window.pageYOffset); //Use Math.max because safari doesn't support document.documentElement.scrollTop

    ScrollToHandler.change = scrollToElementPosition.top + ScrollToHandler.start - ScrollToHandler.start - ScrollToHandler.offset;
    ScrollToHandler.startTime = 'now' in window.performance ? performance.now() : new Date().getTime();
    ScrollToHandler.allowAnimation = true; // Trigger animation

    scrollToAnimation = requestAnimationFrame(ScrollToHandler.animateScroll); // Stop on scroll

    window.addEventListener('mousedown', ScrollToHandler.abortScrollAnimation);
    window.addEventListener('wheel', ScrollToHandler.abortScrollAnimation);
    window.addEventListener('DOMMouseScroll', ScrollToHandler.abortScrollAnimation);
    window.addEventListener('mousewheel', ScrollToHandler.abortScrollAnimation);
    window.addEventListener('keyup', ScrollToHandler.abortScrollAnimation);
    window.addEventListener('touchmove', ScrollToHandler.abortScrollAnimation);
  },

  /*
   * Animate the scroll position
   */
  animateScroll: function animateScroll(timestamp) {
    // Calculate progress from 0 - 1
    var progress = Math.min(1, (timestamp - ScrollToHandler.startTime) / ScrollToHandler.duration);
    if (progress < 0) progress = 0; // Convert progress with easing function

    progress = EasingFunctions[ScrollToHandler.easing](progress);
    var newScrollTop = ScrollToHandler.start + ScrollToHandler.change * progress;
    ScrollToHandler.body.scrollTop = newScrollTop;
    if (ScrollToHandler.body.scrollTop === 0) document.body.scrollTop = newScrollTop; // Safari doesn't support so if ScrollToHandler.body.scrollTop is 0 force the scroll position through document.body.scrollTop

    if (progress < 1 && ScrollToHandler.allowAnimation) {
      scrollToAnimation = requestAnimationFrame(ScrollToHandler.animateScroll);
    }
  },

  /*
   * Abort the scroll animation
   */
  abortScrollAnimation: function abortScrollAnimation(event) {
    ScrollToHandler.allowAnimation = false;
    cancelAnimationFrame(ScrollToHandler.scrollToAnimation);
  }
};
ScrollToHandler.init();

/***/ }),

/***/ "./resources/js/components/testimonialSliderHandler.js":
/*!*************************************************************!*\
  !*** ./resources/js/components/testimonialSliderHandler.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var testimonialSliders = [];
var testimonialSliderContainers = document.querySelectorAll('.js-testimonial-slider');
var testimonialSliderContainersLength = testimonialSliderContainers.length;

for (var i = 0; i < testimonialSliderContainersLength; i++) {
  var testimonialSlider = testimonialSliderContainers[i];
  var testimonialSliderId = testimonialSlider.getAttribute('id');

  if (testimonialSliderId !== null) {
    var testimonialSliderSetting = new ProjectorSetting({
      sliderId: testimonialSliderId,
      slideQuery: '#' + testimonialSliderId + ' .js-testimonial-slider-item',
      navigationButtons: '#' + testimonialSliderId + ' .js-testimonial-slider-button',
      autoSlide: true,
      sliderInterval: 10000
    });
    testimonialSliders.push(new Projector(testimonialSliderSetting.prepareParameters()).init());
  } else console.log('A testimonial-slider has no id...');
}

function ProjectorSetting(settingsObject) {
  var self = this;
  this.sliderId = '';
  this.definedPreviousNext = true;
  this.autoSlide = false;
  this.sliderInterval = 10000;
  this.navigationButtons = '';
  this.slideQuery = '';

  this.setProjectorId = function (string) {
    this.sliderId = string;
    return this;
  };

  this.setDefinedPreviousNext = function (_boolean) {
    this.definedPreviousNext = _boolean;
    return this;
  };

  this.setAutoSlide = function (_boolean2) {
    this.autoSlide = _boolean2;
    return this;
  };

  this.setSliderInterval = function (integer) {
    this.sliderInterval = integer;
    return this;
  };

  this.setSlideQuery = function (string) {
    this.slideQuery = string;
    return this;
  };

  this.setNavigationButtons = function (string) {
    this.navigationButtons = string;
    return this;
  };

  this.getProjectorId = function () {
    return this.sliderId;
  };

  this.getDefinedPreviousNext = function () {
    return this.definedPreviousNext;
  };

  this.getAutoSlide = function () {
    return this.autoSlide;
  };

  this.getSliderInterval = function () {
    return this.sliderInterval;
  };

  this.getSlideQuery = function () {
    return this.slideQuery;
  };

  this.getNavigationButtons = function () {
    return this.navigationButtons;
  }; // Invert setters to getters


  this.prepareParameters = function () {
    return {
      sliderId: self.getProjectorId(),
      definedPreviousNext: self.getDefinedPreviousNext(),
      autoSlide: self.getAutoSlide(),
      sliderInterval: self.getSliderInterval(),
      navigationButtons: self.getNavigationButtons(),
      slideQuery: self.getSlideQuery()
    };
  }; // Mass assign settings


  this.fill = function () {
    // Object.keys(settingsObject).forEach(function (key) {
    //     self[key] = settingsObject[key];
    // });
    var settingsObjectKeys = Object.keys(settingsObject);
    var settingsObjectLength = settingsObjectKeys.length;

    for (var _i = 0; _i < settingsObjectLength; _i++) {
      var key = settingsObjectKeys[_i];
      self[key] = settingsObject[key];
    }
  };

  this.fill();
  return {
    sliderId: self.setProjectorId,
    definedPreviousNext: self.setDefinedPreviousNext,
    autoSlide: self.setAutoSlide,
    sliderInterval: self.setSliderInterval,
    navigationButtons: self.setNavigationButtons,
    slideQuery: self.setSlideQuery,
    prepareParameters: self.prepareParameters
  };
}

function Projector(settings) {
  //Define Projector object
  var self = this;
  this.sliderObject = ''; //SlideParameters

  this.activeSlideId = 0;
  this.previousSlideId = 0;
  this.nextSlideId = 0;
  this.availableSlides = 1;
  this.slides = [];
  this.autoSlideInterval = null;
  this.settings = {};

  this.init = function () {
    //Append settings to self
    this.settings = settings; //Assign needed elements and calculations

    this.sliderObject = document.getElementById(this.settings.sliderId);
    this.slides = document.querySelectorAll(this.settings.slideQuery);
    this.availableSlides = this.slides.length;
    this.activeSlideId = 0; //Define previous and next if we want to use those

    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide(); // Set active slide (and possible previous and next classes)

    this.setSlide(); // Swipe interaction

    var swipeGestures = new Hammer(this.sliderObject);
    swipeGestures.on('swipeleft', function () {
      self.resetAutoSlide();
      self.nextSlide();
      self.setSlide();
    });
    swipeGestures.on('swiperight', function () {
      self.resetAutoSlide();
      self.previousSlide();
      self.setSlide();
    });

    if (this.settings.navigationButtons !== '') {
      // Click interaction
      var navigationButtons = document.querySelectorAll(this.settings.navigationButtons);
      var navigationButtonsLength = navigationButtons.length;

      for (var _i2 = 0; _i2 < navigationButtonsLength; _i2++) {
        var navigationButton = navigationButtons[_i2];
        navigationButton.addEventListener('click', function () {
          self.clickNavigationButton(this);
        });
      }
    }

    self.autoSlide();
  };

  this.autoSlide = function () {
    if (this.autoSlideInterval !== null) clearInterval(this.autoSlideInterval);

    if (this.settings.autoSlide && Number.isInteger(this.settings.sliderInterval)) {
      this.autoSlideInterval = setInterval(function () {
        self.nextSlide();
        self.setSlide();
      }, this.settings.sliderInterval);
    }
  };

  this.resetAutoSlide = self.autoSlide;

  this.nextSlide = function () {
    this.activeSlideId++;
    if (this.activeSlideId >= this.availableSlides) this.activeSlideId = 0;
    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
  };

  this.previousSlide = function () {
    this.activeSlideId--;
    if (this.activeSlideId < 0) this.activeSlideId = this.availableSlides - 1;
    if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
  };

  this.setPreviousAndNextSlide = function () {
    this.nextSlideId = this.activeSlideId + 1;
    if (this.nextSlideId >= this.availableSlides) this.nextSlideId = 0;
    this.previousSlideId = this.activeSlideId - 1;
    if (this.previousSlideId < 0) this.previousSlideId = this.availableSlides - 1;
  };

  this.setSlide = function () {
    // Loop through the form elements
    var slidesLength = self.slides.length;

    for (var _i3 = 0; _i3 < slidesLength; _i3++) {
      var slide = self.slides[_i3]; // Convert data set attribute to desired type

      var slideOrder = parseInt(slide.getAttribute('data-order')); // Remove and set active for all slides

      if (slideOrder !== self.activeSlideId) slide.classList.remove('is-active');else slide.classList.add('is-active'); // If we use the previous and next, also set those classes

      if (self.settings.definedPreviousNext) {
        if (slideOrder !== self.previousSlideId) slide.classList.remove('is-previous');else slide.classList.add('is-previous');
        if (slideOrder !== self.nextSlideId) slide.classList.remove('is-next');else slide.classList.add('is-next');
      }
    }

    var next = document.querySelector(self.settings.navigationButtons + '.is-next');
    var previous = document.querySelector(self.settings.navigationButtons + '.is-previous');
    next.setAttribute('data-order', self.nextSlideId);
    previous.setAttribute('data-order', self.previousSlideId);
  };

  this.clickNavigationButton = function (navButton) {
    self.activeSlideId = parseInt(navButton.getAttribute('data-order'));
    if (self.settings.definedPreviousNext) self.setPreviousAndNextSlide();
    self.setSlide();
    self.resetAutoSlide();
  };
}

/***/ }),

/***/ "./resources/js/components/toggleHandler.js":
/*!**************************************************!*\
  !*** ./resources/js/components/toggleHandler.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   Navigation handler
   - Handles the showing and hiding of the overlay-menu component which has the proper classes.
 ========================================================================== */
var ToggleHandler = {
  init: function init() {
    var toggleTriggers = document.querySelectorAll('.js-toggle-trigger');
    var toggleTriggersCount = toggleTriggers.length;

    if (isset(toggleTriggers) && toggleTriggersCount > 0) {
      for (var i = 0; i < toggleTriggersCount; i++) {
        var toggleTrigger = toggleTriggers[i];
        ToggleHandler.initToggle(toggleTrigger);
      }
    }
  },
  initToggle: function initToggle(toggleTrigger) {
    toggleTrigger.addEventListener('click', ToggleHandler.adjustToggle, false);
  },
  adjustToggle: function adjustToggle(event) {
    var id = event.currentTarget.getAttribute('data-toggle-id');
    var targetArray = [].slice.call(document.querySelectorAll('.js-toggle-target'));
    var target = null;

    for (var i = 0; i < targetArray.length; i++) {
      if (id === targetArray[i].getAttribute('data-toggle-id')) {
        target = targetArray[i];
      }
    } // Bail if toggle doesn't exist


    if (!target) return; // If the toggle is already active, collapse it and quit

    event.currentTarget.classList.toggle('is-toggled');
  }
};
ToggleHandler.init();

/***/ }),

/***/ "./resources/js/components/validationService.js":
/*!******************************************************!*\
  !*** ./resources/js/components/validationService.js ***!
  \******************************************************/
/*! exports provided: ValidationService */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationService", function() { return ValidationService; });
/* harmony import */ var _global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../global/models/errorResponse */ "./resources/js/global/models/errorResponse.js");
/* harmony import */ var _global_models_validationResponse__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../global/models/validationResponse */ "./resources/js/global/models/validationResponse.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }




var ValidationService = /*#__PURE__*/function () {
  function ValidationService() {
    _classCallCheck(this, ValidationService);
  }

  _createClass(ValidationService, [{
    key: "validateCheckoutForm",

    /**
     * @param {FormData} data
     * @return {Promise}
     */
    value: function validateCheckoutForm(data) {
      var self = this;

      if (!(data instanceof FormData)) {
        console.error('ValidationService:validateCheckoutForm could not validate form since no valid FormData instance was given.');
        return Promise.reject('ValidationService:validateCheckoutForm could not validate form since no valid FormData instance was given.');
      }

      return new Promise(function (resolve, reject) {
        Ajax.postFormData('/validation/form/checkout', data, function (xhr) {
          var isErrorResponse = _global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__["ErrorResponse"].is(xhr.response, false);

          if (!isErrorResponse) {
            resolve();
          } else {
            reject(_global_models_errorResponse__WEBPACK_IMPORTED_MODULE_0__["ErrorResponse"].fromJsonString(xhr.response));
          }
        });
      });
    }
  }]);

  return ValidationService;
}();



/***/ }),

/***/ "./resources/js/components/youtubeHandler.js":
/*!***************************************************!*\
  !*** ./resources/js/components/youtubeHandler.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
    Youtube handler
 ========================================================================== */
var YoutubeHandler = {
  youtubeClass: '.js-youtube-player',
  players: [],
  init: function init() {
    // Get the youtube players containers
    var youtubePlayers = document.querySelectorAll(YoutubeHandler.youtubeClass);
    var youtubePlayersAmount = youtubePlayers.length;

    for (var i = 0; i < youtubePlayersAmount; i++) {
      var youtubePlayer = youtubePlayers[i];
      var youtubePlayerId = youtubePlayer.getAttribute('id');

      if (youtubePlayerId !== null) {
        // Strip the necessary data from the html and create objects from it
        var youtubeElement = {
          id: youtubePlayer.getAttribute('id'),
          link: youtubePlayer.getAttribute('data-youtube-link'),
          autoPlay: parseInt(youtubePlayer.getAttribute('data-auto-play'))
        };
        YoutubeHandler.players.push(youtubeElement);
      } else {
        console.log("Element not include because there isn't a id on the player");
        console.log(youtubePlayer);
      }
    }

    if (youtubePlayersAmount >= 1) YoutubeHandler.initYoutube();
  },

  /**
   * Check if external script is loaded
   *
   */
  initYoutube: function initYoutube() {
    // See if YT variable exists
    if (typeof YT == 'undefined' || typeof YT.Player == 'undefined') {
      // Setup API ready function
      window.onYouTubePlayerAPIReady = function () {
        YoutubeHandler.loadPlayers();
      }; // Load external script


      getScript('https://www.youtube.com/iframe_api'); // If YT already exists load player
    } else {
      YoutubeHandler.loadPlayers();
    }
  },

  /**
   * Create the Youtube player(s) with parameters
   * And rewrite the players to key them by the element id
   *
   */
  loadPlayers: function loadPlayers() {
    var players = [];
    var youtubePlayersAmount = YoutubeHandler.players.length;

    for (var i = 0; i < youtubePlayersAmount; i++) {
      var youtubePlayer = YoutubeHandler.players[i]; // Load player

      youtubePlayer.player = new YT.Player(youtubePlayer.id, {
        height: 200,
        width: 200,
        videoId: youtubePlayer.link,
        host: 'https://www.youtube-nocookie.com',
        playerVars: {
          modestbranding: 1,
          rel: 0,
          disablekb: 1,
          autoplay: youtubePlayer.autoPlay
        },
        events: {
          // 'onReady': YoutubeHandler.onReady,
          'onStateChange': YoutubeHandler.onStateChange
        }
      });
      players[youtubePlayer.id] = youtubePlayer;
    }

    YoutubeHandler.players = players;
  },

  /**
   * When player is ready to play
   */
  onReady: function onReady(event) {
    var playerContainerId = event.target.getIframe().getAttribute('id');
    var player = YoutubeHandler.players[playerContainerId].player; // Show video
    // setTimeout(function(){ $('#' + playerContainerId).stop().animate({ opacity: 1 },1000) },800);
    // If not on tablet or mobile, play on high quality
    // player.mute();
    // player.playVideo();
    // player.setPlaybackQuality('hd1080');
  },

  /**
   * Listener for Youtube state change
   */
  onStateChange: function onStateChange(event) {
    var playerContainerId = event.target.getIframe().getAttribute('id');
    var player = YoutubeHandler.players[playerContainerId].player;
    var videoState = event.data; // Loop video

    if (event.data === YT.PlayerState.ENDED) {
      player.playVideo();
    }
  }
};
YoutubeHandler.init();

/***/ }),

/***/ "./resources/js/global/browserHandler.js":
/*!***********************************************!*\
  !*** ./resources/js/global/browserHandler.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   Browser Handler
 ========================================================================== */
var BrowserHandler = {
  userAgent: '',
  browserInfo: '',
  init: function init() {
    BrowserHandler.userAgent = window.navigator.userAgent;
    BrowserHandler.browserInfo = BrowserHandler.getBrowserInfo();
    BrowserHandler.handleIE();
    BrowserHandler.handleSafari();
  },
  handleIE: function handleIE() {
    // Detect versions below ie11
    var msie = BrowserHandler.userAgent.indexOf('MSIE ');
    var ielt11 = msie > 0; // Detect ie11

    var ie11 = !!navigator.userAgent.match(/Trident.*rv\:11\./); // If Internet Explorer

    if (ielt11 || ie11) {
      // Default version
      var version = '11'; // Way to detect version < 11

      if (ielt11) version = parseInt(BrowserHandler.userAgent.substring(msie + 5, BrowserHandler.userAgent.indexOf(".", msie))); // Append classes to HTML (we have to do this separately because else ie will fail)

      document.body.classList.add('ie');
      document.body.classList.add('v' + version);
    }
  },
  // Fallback for older safari version
  handleSafari: function handleSafari() {
    if (BrowserHandler.browserInfo.name === 'Safari' && BrowserHandler.browserInfo.version <= 10) {
      document.getElementsByTagName('html')[0].classList.add('ie');
    }
  },
  getBrowserInfo: function getBrowserInfo() {
    var ua = navigator.userAgent,
        tem,
        M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];

    if (/trident/i.test(M[1])) {
      tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
      return {
        name: 'IE ',
        version: tem[1] || ''
      };
    }

    if (M[1] === 'Chrome') {
      tem = ua.match(/\bOPR\/(\d+)/);

      if (tem != null) {
        return {
          name: 'Opera',
          version: tem[1]
        };
      }
    }

    M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];

    if ((tem = ua.match(/version\/(\d+)/i)) != null) {
      M.splice(1, 1, tem[1]);
    }

    return {
      name: M[0],
      version: M[1]
    };
  }
};
BrowserHandler.init();

/***/ }),

/***/ "./resources/js/global/helpers.js":
/*!****************************************!*\
  !*** ./resources/js/global/helpers.js ***!
  \****************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
    Helper functions
 ========================================================================== */

/*
 * Simple isset method for this does not exist in javascript
 */
window.isset = function (obj) {
  return typeof obj !== 'undefined' && obj !== null;
};
/*
 * Easing Functions - inspired from http://gizma.com/easing/
 * only considering the t value for the range [0, 1] => [0, 1]
 */


window.EasingFunctions = {
  // no easing, no acceleration
  linear: function linear(t) {
    return t;
  },
  // accelerating from zero velocity
  easeInQuad: function easeInQuad(t) {
    return t * t;
  },
  // decelerating to zero velocity
  easeOutQuad: function easeOutQuad(t) {
    return t * (2 - t);
  },
  // acceleration until halfway, then deceleration
  easeInOutQuad: function easeInOutQuad(t) {
    return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
  },
  // accelerating from zero velocity
  easeInCubic: function easeInCubic(t) {
    return t * t * t;
  },
  // decelerating to zero velocity
  easeOutCubic: function easeOutCubic(t) {
    return --t * t * t + 1;
  },
  // acceleration until halfway, then deceleration
  easeInOutCubic: function easeInOutCubic(t) {
    return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
  },
  // accelerating from zero velocity
  easeInQuart: function easeInQuart(t) {
    return t * t * t * t;
  },
  // decelerating to zero velocity
  easeOutQuart: function easeOutQuart(t) {
    return 1 - --t * t * t * t;
  },
  // acceleration until halfway, then deceleration
  easeInOutQuart: function easeInOutQuart(t) {
    return t < .5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
  },
  // accelerating from zero velocity
  easeInQuint: function easeInQuint(t) {
    return t * t * t * t * t;
  },
  // decelerating to zero velocity
  easeOutQuint: function easeOutQuint(t) {
    return 1 + --t * t * t * t * t;
  },
  // acceleration until halfway, then deceleration
  easeInOutQuint: function easeInOutQuint(t) {
    return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
  }
};
/*
 * Vanilla version of the $.getScript
 */

window.getScript = function (source, callback) {
  var script = document.createElement('script');
  script.async = 1;
  var scripts = document.getElementsByTagName('script');
  var prior = scripts[scripts.length - 1];

  script.onload = script.onreadystatechange = function (_, isAbort) {
    if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
      script.onload = script.onreadystatechange = null;
      script = undefined;

      if (!isAbort) {
        if (callback) callback();
      }
    }
  };

  script.src = source;
  prior.parentNode.insertBefore(script, prior);
};
/**
 * Returns a function, that, as long as it continues to be invoked, will not
 * be triggered. The function will be called after it stops being called for
 * N milliseconds. If `immediate` is passed, trigger the function on the
 * leading edge, instead of the trailing.
 * @param func
 * @param wait
 * @param immediate
 * @returns {Function}
 */


window.debounce = function (func, wait, immediate) {
  var timeout;
  return function () {
    var context = this,
        args = arguments;

    var later = function later() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};
/*
 * Cookie helper class
 */


window.Cookie = {
  set: function set(name, value, days) {
    var domain, domainParts, date, expires, host;

    if (days) {
      date = new Date();
      date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
      expires = "; expires=" + date.toGMTString();
    } else {
      expires = "";
    }

    host = location.host;

    if (host.split('.').length === 1) {
      // no "." in a domain - it's localhost or something similar
      document.cookie = name + "=" + value + expires + "; path=/";
    } else {
      // Remember the cookie on all sub domains.
      //
      // Start with trying to set cookie to the top domain.
      // (example: if user is on foo.com, try to set
      //  cookie to domain ".com")
      //
      // If the cookie will not be set, it means ".com"
      // is a top level domain and we need to
      // set the cookie to ".foo.com"
      domainParts = host.split('.');
      domainParts.shift();
      domain = '.' + domainParts.join('.'); // For development purpose, remove this when moving to production
      // domain = '.komma.pro';

      document.cookie = name + "=" + value + expires + "; path=/; domain=" + domain; // check if cookie was successfuly set to the given domain
      // (otherwise it was a Top-Level Domain)

      if (Cookie.get(name) == null || Cookie.get(name) != value) {
        // append "." to current domain
        domain = '.' + host;
        document.cookie = name + "=" + value + expires + "; path=/; domain=" + domain;
      }
    }
  },
  get: function get(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');

    for (var i = 0; i < ca.length; i++) {
      var c = ca[i];

      while (c.charAt(0) === ' ') {
        c = c.substring(1, c.length);
      }

      if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
    }

    return null;
  },
  erase: function erase(name) {
    Cookie.set(name, '', -1);
  }
};
/*
 * Javascript version of the number_format method of PHP
 */

window.number_format = function (number, decimals, dec_point, thousands_sep) {
  // Strip all characters but numerical ones.
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '');

  var n = !isFinite(+number) ? 0 : +number,
      prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
      sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep,
      dec = typeof dec_point === 'undefined' ? '.' : dec_point,
      s = '',
      toFixedFix = function toFixedFix(n, prec) {
    var k = Math.pow(10, prec);
    return '' + Math.round(n * k) / k;
  }; // Fix for IE parseFloat(0.55).toFixed(0) = 0;


  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');

  if (s[0].length > 3) {
    s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  }

  if ((s[1] || '').length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1).join('0');
  }

  return s.join(dec);
};
/**
 * Element.closest() polyfill
 * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
 */


if (!Element.prototype.closest) {
  if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
  }

  Element.prototype.closest = function (s) {
    var el = this;
    var ancestor = this;
    if (!document.documentElement.contains(el)) return null;

    do {
      if (ancestor.matches(s)) return ancestor;
      ancestor = ancestor.parentElement;
    } while (ancestor !== null);

    return null;
  };
}

window.Ajax = {
  //TODO: Can we create a prepare request function ??
  get: function get(url, callback) {
    var xhr = new XMLHttpRequest();
    var token = document.querySelector('meta[name="csrf-token"]').content;
    xhr.open('get', url, true);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.setRequestHeader('X-CSRF-TOKEN', token);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        callback(xhr);
      }
    };

    xhr.send();
  },
  post: function post(url, data, callback) {
    var xhr = new XMLHttpRequest();
    var token = document.querySelector('meta[name="csrf-token"]').content;
    xhr.open('post', url, true);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.setRequestHeader('X-CSRF-TOKEN', token);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        callback(xhr);
      }
    };

    xhr.send(JSON.stringify(data));
  },
  postFormData: function postFormData(url, data, callback) {
    var xhr = new XMLHttpRequest();
    var token = document.querySelector('meta[name="csrf-token"]').content;
    xhr.open('post', url, true);
    xhr.setRequestHeader('X-CSRF-TOKEN', token);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        callback(xhr);
      }
    };

    xhr.send(data);
  }
};
/**
 * Capitalize the first letter of the string
 * @param string
 * @returns {string}
 */

window.capitalizeFirstLetter = function (string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
};
/**
 * Convert snake case into camelcase
 *
 * @param string
 * @returns {*}
 */


window.snakeToCamel = function (string) {
  return string.replace(/(\-\w)/g, function (m) {
    return m[1].toUpperCase();
  });
};
/**
 * Get the index of an element inside its parent
 */


window.indexInParent = function (node) {
  var children = node.parentNode.childNodes;
  var num = 0;

  for (var i = 0; i < children.length; i++) {
    if (children[i] == node) return num;
    if (children[i].nodeType == 1) num++;
  }

  return -1;
};
/**
 * For security reasons iOS Safari only allows document.execCommand('copy') for text within a contentEditable container.
 * The workaround is to detect iOS Safari and quickly toggle contentEditable before executing document.execCommand('copy').
 * Wheb input or textarea is READONLY you can prevent the unwanted popup with copy/paste functions and the input keyboard
 * Code from: https://stackoverflow.com/a/46981847
 */


window.copyToClipboard = function (el) {
  // resolve the element
  el = typeof el === 'string' ? document.querySelector(el) : el; // handle iOS as a special case

  if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
    // save current contentEditable/readOnly status
    var editable = el.contentEditable;
    var readOnly = el.readOnly; // convert to editable with readonly to stop iOS keyboard opening

    el.contentEditable = true;
    el.readOnly = true; // create a selectable range

    var range = document.createRange();
    range.selectNodeContents(el); // select the range

    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    el.setSelectionRange(0, 999999); // restore contentEditable/readOnly to original state

    el.contentEditable = editable;
    el.readOnly = readOnly;
  } else {
    el.select();
  } // execute copy command


  document.execCommand('copy');
};
/**
 * Get the position of the element related to the body
 *
 * @param el
 * @returns {{top: number, left: number}}
 */


window.bodyOffset = function (el) {
  var rect = el.getBoundingClientRect(),
      scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
      scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  return {
    top: rect.top + scrollTop,
    left: rect.left + scrollLeft
  };
};

/***/ }),

/***/ "./resources/js/global/models/countryLanguagesResponse.js":
/*!****************************************************************!*\
  !*** ./resources/js/global/models/countryLanguagesResponse.js ***!
  \****************************************************************/
/*! exports provided: CountryLanguagesResponse */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CountryLanguagesResponse", function() { return CountryLanguagesResponse; });
/* harmony import */ var _language__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./language */ "./resources/js/global/models/language.js");
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * CountryLanguagesResponse.
 *
 * Represents a response that originates from
 */


var CountryLanguagesResponse = /*#__PURE__*/function () {
  function CountryLanguagesResponse() {
    _classCallCheck(this, CountryLanguagesResponse);

    this._languages = [];
  }
  /**
   * @param {string} json
   * @return {CountryLanguagesResponse|null}
   */


  _createClass(CountryLanguagesResponse, [{
    key: "_toJson",

    /**
     * @return {{valid: boolean, errors: Array}}
     * @private
     */
    value: function _toJson() {
      return {
        'languages': this._languages
      };
    }
    /**
     * @return {Language[]}
     */

  }, {
    key: "languages",
    get: function get() {
      return this._languages;
    }
  }], [{
    key: "fromJsonString",
    value: function fromJsonString(json) {
      if (!this.is(json)) {
        return null;
      }

      var jsonObject = JSON.parse(json);
      var instance = new this();
      var languageCount = jsonObject.languages.length;

      for (var index = 0; index < languageCount; index++) {
        var languageObject = jsonObject.languages[index];
        var language = new _language__WEBPACK_IMPORTED_MODULE_0__["Language"]();
        language.name = languageObject.name;
        language.displayName = languageObject.displayName;
        language.nativeName = languageObject.nativeName;
        language.twoLetterIsoLanguageName = languageObject.twoLetterIsoLanguageName;
        language.threeLetterIsoLanguageName = languageObject.threeLetterIsoLanguageName;

        instance._languages.push(language);
      }

      return instance;
    }
    /**
     * Checks that the given json string represents a ErrorResponse
     *
     * @param {string} json
     * @param {boolean} logErrors
     * @return {boolean}
     */

  }, {
    key: "is",
    value: function is(json) {
      var logErrors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var jsonObject = null;

      if (typeof json === 'string') {
        try {
          jsonObject = JSON.parse(json);
          if (!jsonObject) return false;
        } catch (e) {
          console.error('CountryLanguagesResponse: The given json does not represent a CountryLanguagesResponse since the json string was not a valid json. Object: ', jsonObject);
          return false;
        }
      } else {
        jsonObject = json;
      }

      if (!jsonObject.hasOwnProperty('languages') || !Array.isArray(jsonObject.languages)) {
        console.log('CountryLanguagesResponse: The given json must have a property called languages that is an Array, But did not have. Object: ', jsonObject);
        return false;
      }

      var languageCount = jsonObject.languages.length;

      for (var index = 0; index < languageCount; index++) {
        var languageObject = jsonObject.languages[index];

        if (_typeof(languageObject) !== 'object' || typeof languageObject === 'function' || !_language__WEBPACK_IMPORTED_MODULE_0__["Language"].is(languageObject)) {
          return false;
        }
      }

      return true;
    }
  }]);

  return CountryLanguagesResponse;
}();



/***/ }),

/***/ "./resources/js/global/models/errorResponse.js":
/*!*****************************************************!*\
  !*** ./resources/js/global/models/errorResponse.js ***!
  \*****************************************************/
/*! exports provided: ErrorResponse */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorResponse", function() { return ErrorResponse; });
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * A laravel error response
 */
var ErrorResponse = /*#__PURE__*/function () {
  function ErrorResponse() {
    _classCallCheck(this, ErrorResponse);

    this._message = '';
    this._errors = {};
  }
  /**
   * @param {string} json
   * @return {ErrorResponse|null}
   */


  _createClass(ErrorResponse, [{
    key: "message",

    /**
     * Retrurns a comprehensive error message for all the fields.
     *
     * @return {string}
     */
    get: function get() {
      return this._message;
    }
    /**
     * @return {Object} returns an object where the property are field names. and the values are arrays containing errors for those field names.
     */

  }, {
    key: "errors",
    get: function get() {
      return this._errors;
    }
  }], [{
    key: "fromJsonString",
    value: function fromJsonString(json) {
      if (!this.is(json)) {
        return null;
      }

      var jsonObject = JSON.parse(json);
      var instance = new this();
      instance._message = jsonObject.message;
      instance._errors = jsonObject.errors;
      return instance;
    }
    /**
     * Checks that the given json string represents a ErrorResponse
     *
     * @param {string} json
     * @param {boolean} logErrors
     * @return {boolean}
     */

  }, {
    key: "is",
    value: function is(json) {
      var logErrors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var jsonObject = null;

      try {
        jsonObject = JSON.parse(json);
        if (!jsonObject) return false;
      } catch (e) {
        if (logErrors) console.error('ErrorResponse: The given json does not represent a valid ErrorResponse since the json string was not a valid json');
        return false;
      }

      if (!jsonObject.hasOwnProperty('message') || typeof jsonObject.message !== 'string') {
        if (logErrors) console.error('ErrorResponse: The response object must have an message property that is a string. Object:', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('errors') || _typeof(jsonObject.errors) !== 'object') {
        if (logErrors) console.error('ErrorResponse: The response object must have an errors object that represents valid laravel field errors. Object:', jsonObject);
        return false;
      }

      for (var fieldName in jsonObject.errors) {
        if (jsonObject.errors.hasOwnProperty(fieldName) && !Array.isArray(jsonObject.errors[fieldName])) {
          if (logErrors) console.error('ErrorResponse: The property "' + fieldName + '" in the errors array must have have array as value containing errors strings. Object:', jsonObject);
          return false;
        }
      }

      return true;
    }
  }]);

  return ErrorResponse;
}();



/***/ }),

/***/ "./resources/js/global/models/language.js":
/*!************************************************!*\
  !*** ./resources/js/global/models/language.js ***!
  \************************************************/
/*! exports provided: Language */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Language", function() { return Language; });
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * Language.
 *
 * Represents a Language
 */
var Language = /*#__PURE__*/function () {
  function Language() {
    _classCallCheck(this, Language);

    this._name = '';
    this._displayName = '';
    this._nativeName = '';
    this._twoLetterIsoLanguageName = '';
    this._threeLetterIsoLanguageName = '';
  }
  /**
   * @param {string} json
   * @return {Language|null}
   */


  _createClass(Language, [{
    key: "_toJson",

    /**
     * @return {{valid: boolean, errors: Array}}
     * @private
     */
    value: function _toJson() {
      return {
        'name': this._name,
        'displayName': this._displayName,
        'nativeName': this._nativeName,
        'twoLetterIsoLanguageName': this._twoLetterIsoLanguageName,
        'threeLetterIsoLanguageName': this._threeLetterIsoLanguageName
      };
    }
  }, {
    key: "name",
    get: function get() {
      return this._name;
    },
    set: function set(value) {
      this._name = value;
    }
  }, {
    key: "displayName",
    get: function get() {
      return this._displayName;
    },
    set: function set(value) {
      this._displayName = value;
    }
  }, {
    key: "nativeName",
    get: function get() {
      return this._nativeName;
    },
    set: function set(value) {
      this._nativeName = value;
    }
  }, {
    key: "twoLetterIsoLanguageName",
    get: function get() {
      return this._twoLetterIsoLanguageName;
    },
    set: function set(value) {
      this._twoLetterIsoLanguageName = value;
    }
  }, {
    key: "threeLetterIsoLanguageName",
    get: function get() {
      return this._threeLetterIsoLanguageName;
    },
    set: function set(value) {
      this._threeLetterIsoLanguageName = value;
    }
  }], [{
    key: "fromJsonString",
    value: function fromJsonString(json) {
      if (!this.is(json)) {
        return null;
      }

      var jsonObject = JSON.parse(json);
      var instance = new this();
      instance._name = jsonObject.name;
      instance._displayName = jsonObject.displayName;
      instance._nativeName = jsonObject.nativeName;
      instance._twoLetterIsoLanguageName = jsonObject.twoLetterIsoLanguageName;
      instance._threeLetterIsoLanguageName = jsonObject.threeLetterIsoLanguageName;
      return instance;
    }
    /**
     * Checks that the given json string represents a ErrorResponse
     *
     * @param {string|object} json
     * @param {boolean} logErrors
     * @return {boolean}
     */

  }, {
    key: "is",
    value: function is(json) {
      var logErrors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var jsonObject = null;

      if (typeof json === 'string') {
        try {
          jsonObject = JSON.parse(json);
          if (!jsonObject) return false;
        } catch (e) {
          console.error('Language: The given json does not represent a Language since the json string was not a valid json. Object: ', jsonObject, json);
          return false;
        }
      } else {
        jsonObject = json;
      }

      if (!jsonObject.hasOwnProperty('name') || typeof jsonObject.displayName !== 'string') {
        if (logErrors) console.error('Language: The language object must have a property called name that is a string. Object: ', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('displayName') || typeof jsonObject.displayName !== 'string') {
        if (logErrors) console.error('Language: The language object must have a property called displayName that is a string. Object: ', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('nativeName') || typeof jsonObject.nativeName !== 'string') {
        if (logErrors) console.error('Language: The language object must have a property called nativeName that is a string. Object: ', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('twoLetterIsoLanguageName') || typeof jsonObject.twoLetterIsoLanguageName !== 'string') {
        if (logErrors) console.error('Language: The language object must have a property called twoLetterIsoLanguageName that is a string. Object: ', jsonObject.twoLetterIsoLanguageName);
        return false;
      }

      if (!jsonObject.hasOwnProperty('threeLetterIsoLanguageName') || typeof jsonObject.threeLetterIsoLanguageName !== 'string') {
        if (logErrors) console.error('Language: The language object must have a property called threeLetterIsoLanguageName that is a string. Object: ', jsonObject);
        return false;
      }

      return true;
    }
  }]);

  return Language;
}();



/***/ }),

/***/ "./resources/js/global/models/validationResponse.js":
/*!**********************************************************!*\
  !*** ./resources/js/global/models/validationResponse.js ***!
  \**********************************************************/
/*! exports provided: ValidationResponse */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationResponse", function() { return ValidationResponse; });
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * ValidationResponse.
 *
 * Represents a response that originates from
 */
var ValidationResponse = /*#__PURE__*/function () {
  function ValidationResponse() {
    _classCallCheck(this, ValidationResponse);

    this._valid = false;
    this._errors = [];
    this.toJSON = this._toJson.bind(this);
  }
  /**
   * @param {string} json
   * @return {ValidationResponse|null}
   */


  _createClass(ValidationResponse, [{
    key: "_toJson",

    /**
     * @return {{valid: boolean, errors: Array}}
     * @private
     */
    value: function _toJson() {
      return {
        'valid': this._valid,
        'errors': this._errors
      };
    }
    /**
     * @return {boolean}
     */

  }, {
    key: "valid",
    get: function get() {
      return this._valid;
    }
    /**
     * @return {Array}
     */

  }, {
    key: "errors",
    get: function get() {
      return this._errors;
    }
  }], [{
    key: "fromJsonString",
    value: function fromJsonString(json) {
      if (!this.is(json)) {
        return null;
      }

      var jsonObject = JSON.parse(json);
      var instance = new this();
      instance._valid = jsonObject.valid;
      instance._errors = jsonObject.errors;
      return instance;
    }
    /**
     * Checks that the given json string represents a ErrorResponse
     *
     * @param {string} json
     * @param {boolean} logErrors
     * @return {boolean}
     */

  }, {
    key: "is",
    value: function is(json) {
      var logErrors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var jsonObject = null;

      try {
        jsonObject = JSON.parse(json);
        if (!jsonObject) return false;
      } catch (e) {
        console.error('ValidationResponse: The given json does not represent a ValidationResponse since the json string was not a valid json. Object: ', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('valid')) {
        console.error('ValidationResponse: The given json object must have an "valid" property that is a string. But did not have one. Object: ', jsonObject);
        return false;
      }

      if (!jsonObject.hasOwnProperty('errors') || _typeof(!jsonObject.errors) == 'object') {
        console.error('ValidationResponse: The given json object must have an errors object. But did not have one. Object: ', jsonObject);
        return false;
      }

      return true;
    }
  }]);

  return ValidationResponse;
}();



/***/ }),

/***/ "./resources/js/global/polyfills/eventPolyFill.js":
/*!********************************************************!*\
  !*** ./resources/js/global/polyfills/eventPolyFill.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/**
 * Event semi polyfill. IE does not support new event. But does support document.createEvent.
 * Same thing for dispatching events. But then with createEvent and fireEvent.
 */
function createNewEvent(eventName) {
  var event;

  if (typeof Event === 'function') {
    //On ie it is typeOf object.
    event = new Event(eventName); //Non-ie
  } else {
    event = document.createEvent('Event'); //ie

    event.initEvent(eventName, true, true);
  }

  return event;
}

function dispatchEventForElement(element, event) {
  if (document.createEvent) {
    element.dispatchEvent(event);
  } else {
    element.fireEvent("on" + event.eventType, event);
  }
}

/***/ }),

/***/ "./resources/js/global/polyfills/isInteger.js":
/*!****************************************************!*\
  !*** ./resources/js/global/polyfills/isInteger.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

Number.isInteger = Number.isInteger || function (value) {
  return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};

/***/ }),

/***/ "./resources/js/global/polyfills/promise.js":
/*!**************************************************!*\
  !*** ./resources/js/global/polyfills/promise.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(setImmediate, global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

(function (global, factory) {
  ( false ? undefined : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory() :  true ? !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
				__WEBPACK_AMD_DEFINE_FACTORY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) : undefined;
})(this, function () {
  'use strict';
  /**
   * @this {Promise}
   */

  function finallyConstructor(callback) {
    var constructor = this.constructor;
    return this.then(function (value) {
      return constructor.resolve(callback()).then(function () {
        return value;
      });
    }, function (reason) {
      return constructor.resolve(callback()).then(function () {
        return constructor.reject(reason);
      });
    });
  } // Store setTimeout reference so promise-polyfill will be unaffected by
  // other code modifying setTimeout (like sinon.useFakeTimers())


  var setTimeoutFunc = setTimeout;

  function noop() {} // Polyfill for Function.prototype.bind


  function bind(fn, thisArg) {
    return function () {
      fn.apply(thisArg, arguments);
    };
  }
  /**
   * @constructor
   * @param {Function} fn
   */


  function Promise(fn) {
    if (!(this instanceof Promise)) throw new TypeError('Promises must be constructed via new');
    if (typeof fn !== 'function') throw new TypeError('not a function');
    /** @type {!number} */

    this._state = 0;
    /** @type {!boolean} */

    this._handled = false;
    /** @type {Promise|undefined} */

    this._value = undefined;
    /** @type {!Array<!Function>} */

    this._deferreds = [];
    doResolve(fn, this);
  }

  function handle(self, deferred) {
    while (self._state === 3) {
      self = self._value;
    }

    if (self._state === 0) {
      self._deferreds.push(deferred);

      return;
    }

    self._handled = true;

    Promise._immediateFn(function () {
      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;

      if (cb === null) {
        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
        return;
      }

      var ret;

      try {
        ret = cb(self._value);
      } catch (e) {
        reject(deferred.promise, e);
        return;
      }

      resolve(deferred.promise, ret);
    });
  }

  function resolve(self, newValue) {
    try {
      // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
      if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.');

      if (newValue && (_typeof(newValue) === 'object' || typeof newValue === 'function')) {
        var then = newValue.then;

        if (newValue instanceof Promise) {
          self._state = 3;
          self._value = newValue;
          finale(self);
          return;
        } else if (typeof then === 'function') {
          doResolve(bind(then, newValue), self);
          return;
        }
      }

      self._state = 1;
      self._value = newValue;
      finale(self);
    } catch (e) {
      reject(self, e);
    }
  }

  function reject(self, newValue) {
    self._state = 2;
    self._value = newValue;
    finale(self);
  }

  function finale(self) {
    if (self._state === 2 && self._deferreds.length === 0) {
      Promise._immediateFn(function () {
        if (!self._handled) {
          Promise._unhandledRejectionFn(self._value);
        }
      });
    }

    for (var i = 0, len = self._deferreds.length; i < len; i++) {
      handle(self, self._deferreds[i]);
    }

    self._deferreds = null;
  }
  /**
   * @constructor
   */


  function Handler(onFulfilled, onRejected, promise) {
    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
    this.onRejected = typeof onRejected === 'function' ? onRejected : null;
    this.promise = promise;
  }
  /**
   * Take a potentially misbehaving resolver function and make sure
   * onFulfilled and onRejected are only called once.
   *
   * Makes no guarantees about asynchrony.
   */


  function doResolve(fn, self) {
    var done = false;

    try {
      fn(function (value) {
        if (done) return;
        done = true;
        resolve(self, value);
      }, function (reason) {
        if (done) return;
        done = true;
        reject(self, reason);
      });
    } catch (ex) {
      if (done) return;
      done = true;
      reject(self, ex);
    }
  }

  Promise.prototype['catch'] = function (onRejected) {
    return this.then(null, onRejected);
  };

  Promise.prototype.then = function (onFulfilled, onRejected) {
    // @ts-ignore
    var prom = new this.constructor(noop);
    handle(this, new Handler(onFulfilled, onRejected, prom));
    return prom;
  };

  Promise.prototype['finally'] = finallyConstructor;

  Promise.all = function (arr) {
    return new Promise(function (resolve, reject) {
      if (!arr || typeof arr.length === 'undefined') throw new TypeError('Promise.all accepts an array');
      var args = Array.prototype.slice.call(arr);
      if (args.length === 0) return resolve([]);
      var remaining = args.length;

      function res(i, val) {
        try {
          if (val && (_typeof(val) === 'object' || typeof val === 'function')) {
            var then = val.then;

            if (typeof then === 'function') {
              then.call(val, function (val) {
                res(i, val);
              }, reject);
              return;
            }
          }

          args[i] = val;

          if (--remaining === 0) {
            resolve(args);
          }
        } catch (ex) {
          reject(ex);
        }
      }

      for (var i = 0; i < args.length; i++) {
        res(i, args[i]);
      }
    });
  };

  Promise.resolve = function (value) {
    if (value && _typeof(value) === 'object' && value.constructor === Promise) {
      return value;
    }

    return new Promise(function (resolve) {
      resolve(value);
    });
  };

  Promise.reject = function (value) {
    return new Promise(function (resolve, reject) {
      reject(value);
    });
  };

  Promise.race = function (values) {
    return new Promise(function (resolve, reject) {
      for (var i = 0, len = values.length; i < len; i++) {
        values[i].then(resolve, reject);
      }
    });
  }; // Use polyfill for setImmediate for performance gains


  Promise._immediateFn = typeof setImmediate === 'function' && function (fn) {
    setImmediate(fn);
  } || function (fn) {
    setTimeoutFunc(fn, 0);
  };

  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
    if (typeof console !== 'undefined' && console) {
      console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
    }
  };
  /** @suppress {undefinedVars} */


  var globalNS = function () {
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    if (typeof self !== 'undefined') {
      return self;
    }

    if (typeof window !== 'undefined') {
      return window;
    }

    if (typeof global !== 'undefined') {
      return global;
    }

    throw new Error('unable to locate global object');
  }();

  if (!('Promise' in globalNS)) {
    globalNS['Promise'] = Promise;
  } else if (!globalNS.Promise.prototype['finally']) {
    globalNS.Promise.prototype['finally'] = finallyConstructor;
  }
});
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../node_modules/timers-browserify/main.js */ "./node_modules/timers-browserify/main.js").setImmediate, __webpack_require__(/*! ./../../../../node_modules/webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./resources/js/global/scrollHandler.js":
/*!**********************************************!*\
  !*** ./resources/js/global/scrollHandler.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* ==========================================================================
   Scroll handler
   - Handler the objects which are bind on scroll events or visible in viewport
 ========================================================================== */
var ScrollHandler = {
  // Variables for debounce and throttle effects
  time: Date.now(),
  timeout: null,
  waitThrottle: 1000,
  waitDebounce: 300,
  // Variables for scroll direction
  lastScrollTopPosition: 0,
  scrollDirectionDown: true,
  scrollDirectionUp: false,
  //Initialisation
  init: function init() {
    // Trigger start on start up
    ScrollHandler.triggerOnInit(); // Throttle scroll

    window.addEventListener('scroll', function () {
      if (ScrollHandler.time + ScrollHandler.waitThrottle - Date.now() < 0) {
        ScrollHandler.triggerThrottle();
        ScrollHandler.time = Date.now();
      }
    }); // Smooth scroll

    window.addEventListener('scroll', function () {
      ScrollHandler.triggerSmooth();
    }); // Debounce scroll

    window.addEventListener('scroll', function () {
      if (isset(ScrollHandler.timeout)) clearTimeout(ScrollHandler.timeout);
      ScrollHandler.timeout = setTimeout(ScrollHandler.triggerDebounce, ScrollHandler.waitDebounce);
    });
  },
  // Trigger on start up
  triggerOnInit: function triggerOnInit() {
    ScrollHandler.triggerElementInViewportAnimation();
  },
  // Trigger scroll functions with throttle (preferred)
  triggerThrottle: function triggerThrottle() {
    // console.log('Throttled scroll');
    ScrollHandler.triggerElementInViewportAnimation();
  },
  // Trigger scroll on debounce
  triggerDebounce: function triggerDebounce() {// console.log('Debounce scroll');
  },
  // Trigger scroll on the flight
  triggerSmooth: function triggerSmooth() {
    // console.log('Smooth scroll');
    ScrollHandler.detectScrollDirection();
    ScrollHandler.toggleStickyHeader();
  },
  // Detect if part of a given element is visible in the viewport
  // El must be a node element
  detectIfElementIsPartlyInViewport: function detectIfElementIsPartlyInViewport(el) {
    if (isset(el)) {
      var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }

      var windowHeight = window.innerHeight || document.documentElement.clientHeight;
      var windowWidth = window.innerWidth || document.documentElement.clientWidth;
      var verticalInView = rect.top <= windowHeight && rect.top + rect.height >= 0;
      var horizontalInView = rect.left <= windowWidth && rect.left + rect.width >= 0;
      return verticalInView && horizontalInView;
    }
  },
  // Detect if a given element is fully visible in the viewport
  // El must be a node element
  detectIfElementIsFullyInViewport: function detectIfElementIsFullyInViewport(el) {
    if (isset(el)) {
      var rect = el.getBoundingClientRect();
      return rect.top >= 0 && rect.bottom <= window.innerHeight;
    }
  },
  detectScrollDirection: function detectScrollDirection() {
    var scrollTopPosition = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"

    if (scrollTopPosition >= ScrollHandler.lastScrollTopPosition) {
      ScrollHandler.scrollDirectionDown = true;
      ScrollHandler.scrollDirectionUp = false;
    } else {
      ScrollHandler.scrollDirectionDown = false;
      ScrollHandler.scrollDirectionUp = true;
    }

    ScrollHandler.lastScrollTopPosition = scrollTopPosition;
  },
  // Trigger animation on elements that have 'element-in-viewport' and that are in the viewport
  // These animation can only be triggered once, if you want more then that you should write an specific function for this
  triggerElementInViewportAnimation: function triggerElementInViewportAnimation() {
    var elements = document.querySelectorAll('.element-in-viewport');
    var elementsLength = elements.length;

    for (var e = 0; e < elementsLength; e++) {
      var element = elements[e];

      if (ScrollHandler.detectIfElementIsPartlyInViewport(element)) {
        element.classList.remove('element-in-viewport');
      }
    }
  },
  // ------------------------------ CUSTOM SCROLL HANDLERS ------------------------------------
  // Hide or show sticky navigation when header isn't visible
  toggleStickyHeader: function toggleStickyHeader() {
    var stickyHeader = document.querySelector('.js-sticky-header');
    var visibleStickyHeaderClass = 'is-sticky-header-visible';
    var subnavList = document.querySelectorAll('.js-subnav');
    var subNavIsVisible = false;
    stickyHeader.hidden = false;

    for (var i = 0; i < subnavList.length; i++) {
      if (window.getComputedStyle(subnavList[i], null).visibility == "visible") {
        return subNavIsVisible = true;
      }
    }

    if (isset(stickyHeader) && !subNavIsVisible) {
      // Hide when scrolling DOWN (OR within offset)
      if (ScrollHandler.scrollDirectionDown || ScrollHandler.lastScrollTopPosition < 110) {
        document.body.classList.remove(visibleStickyHeaderClass);
      } // Show when scrolling UP and outside of offset
      else {
          document.body.classList.add(visibleStickyHeaderClass);
        }
    }
  }
};
ScrollHandler.init();

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/formatUtils.js":
/*!*******************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/formatUtils.js ***!
  \*******************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return FormatUtils; });
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var FormatUtils = /*#__PURE__*/function () {
  function FormatUtils() {
    _classCallCheck(this, FormatUtils);
  }

  _createClass(FormatUtils, null, [{
    key: "insertDots",

    /**
     * Insert dots every x character, starting from the end
     *
     * @param input
     * @param every
     * @return {*|void|string}
     */
    value: function insertDots(input) {
      var every = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
      // eslint-disable-next-line no-useless-escape
      var regex = '(.{' + every + '})(?!$)';
      return FormatUtils.reverse(FormatUtils.reverse(input).replace(new RegExp(regex, 'g'), '$1.'));
    }
  }, {
    key: "reverse",

    /**
     * Reverses the input string
     * @param input
     * @return {string}
     */
    value: function reverse(input) {
      if (typeof input !== 'string') input = input.toString(10);
      return input.split('').reverse().join('');
    }
    /**
     * Removes all non digit characters from a string so the input becomes numeric.
     * Then converts it to an integer. If it then is not a number, the fallback value will be returned
     *
     * @param {string|number} input
     * @param {any} fallback A fallback value to use when the input could not be converted to a number
     * @return {any}
     */

  }, {
    key: "convertToInteger",
    value: function convertToInteger(input) {
      var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      if (typeof input !== 'string') input = input.toString(10); // eslint-disable-next-line no-useless-escape

      var number = parseInt(input.replace(/\D/g, ''));
      return !isNaN(number) ? number : fallback;
    }
  }, {
    key: "forceToBeInRangeOf",

    /**
     * Forces a value to be in the range of lower or upper.
     *
     * @param value
     * @param lower
     * @param upper
     * @return {number}
     */
    value: function forceToBeInRangeOf(value, lower, upper) {
      if (typeof value !== 'number') throw new Error('The value, lower and upper all must be a number but where respectively:' + _typeof(value) + ' ' + _typeof(lower) + ' ' + _typeof(upper));
      if (lower && value < lower) return lower;
      if (upper && value > upper) return upper;
      return value;
    }
  }]);

  return FormatUtils;
}();



/***/ }),

/***/ "./resources/js/vue/paybackPeriod/main.js":
/*!************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/main.js ***!
  \************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _paybackPeriodCalculator_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodCalculator.vue */ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue");
/* harmony import */ var _paybackPeriodIntake_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./paybackPeriodIntake.vue */ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue");




if (document.querySelector('#payback_period')) {
  new vue__WEBPACK_IMPORTED_MODULE_0___default.a({
    el: '#payback_period',
    components: {
      paybackPeriodCalculator: _paybackPeriodCalculator_vue__WEBPACK_IMPORTED_MODULE_1__["default"],
      paybackPeriodIntake: _paybackPeriodIntake_vue__WEBPACK_IMPORTED_MODULE_2__["default"]
    }
  });
}

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue":
/*!********************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue ***!
  \********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8& */ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8&");
/* harmony import */ var _paybackPeriodCalculator_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodCalculator.vue?vue&type=script&lang=js& */ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js");





/* normalize component */

var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])(
  _paybackPeriodCalculator_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"],
  _paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__["render"],
  _paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"],
  false,
  null,
  null,
  null
  
)

/* hot reload */
if (false) { var api; }
component.options.__file = "resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue"
/* harmony default export */ __webpack_exports__["default"] = (component.exports);

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js&":
/*!*********************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js& ***!
  \*********************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodCalculator_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib??ref--4-0!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodCalculator.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodCalculator_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); 

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8&":
/*!***************************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8& ***!
  \***************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodCalculator.vue?vue&type=template&id=82ae81c8&");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__["render"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodCalculator_vue_vue_type_template_id_82ae81c8___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; });



/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue":
/*!****************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue ***!
  \****************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./paybackPeriodIntake.vue?vue&type=template&id=7c59e746& */ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746&");
/* harmony import */ var _paybackPeriodIntake_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodIntake.vue?vue&type=script&lang=js& */ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js");





/* normalize component */

var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])(
  _paybackPeriodIntake_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"],
  _paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__["render"],
  _paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"],
  false,
  null,
  null,
  null
  
)

/* hot reload */
if (false) { var api; }
component.options.__file = "resources/js/vue/paybackPeriod/paybackPeriodIntake.vue"
/* harmony default export */ __webpack_exports__["default"] = (component.exports);

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js&":
/*!*****************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js& ***!
  \*****************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodIntake_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib??ref--4-0!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodIntake.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodIntake_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); 

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746&":
/*!***********************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746& ***!
  \***********************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodIntake.vue?vue&type=template&id=7c59e746& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodIntake.vue?vue&type=template&id=7c59e746&");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__["render"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodIntake_vue_vue_type_template_id_7c59e746___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; });



/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue":
/*!****************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodResult.vue ***!
  \****************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./paybackPeriodResult.vue?vue&type=template&id=cdaab092& */ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092&");
/* harmony import */ var _paybackPeriodResult_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodResult.vue?vue&type=script&lang=js& */ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js");





/* normalize component */

var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])(
  _paybackPeriodResult_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"],
  _paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__["render"],
  _paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"],
  false,
  null,
  null,
  null
  
)

/* hot reload */
if (false) { var api; }
component.options.__file = "resources/js/vue/paybackPeriod/paybackPeriodResult.vue"
/* harmony default export */ __webpack_exports__["default"] = (component.exports);

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js&":
/*!*****************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js& ***!
  \*****************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodResult_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib??ref--4-0!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodResult.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodResult_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); 

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092&":
/*!***********************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092& ***!
  \***********************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodResult.vue?vue&type=template&id=cdaab092& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodResult.vue?vue&type=template&id=cdaab092&");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__["render"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodResult_vue_vue_type_template_id_cdaab092___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; });



/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue":
/*!*******************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue ***!
  \*******************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a& */ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a&");
/* harmony import */ var _paybackPeriodTextInput_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./paybackPeriodTextInput.vue?vue&type=script&lang=js& */ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport *//* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js");





/* normalize component */

var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__["default"])(
  _paybackPeriodTextInput_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"],
  _paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__["render"],
  _paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"],
  false,
  null,
  null,
  null
  
)

/* hot reload */
if (false) { var api; }
component.options.__file = "resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue"
/* harmony default export */ __webpack_exports__["default"] = (component.exports);

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js&":
/*!********************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js& ***!
  \********************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodTextInput_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib??ref--4-0!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodTextInput.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=script&lang=js&");
/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodTextInput_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); 

/***/ }),

/***/ "./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a&":
/*!**************************************************************************************************!*\
  !*** ./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a& ***!
  \**************************************************************************************************/
/*! exports provided: render, staticRenderFns */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../node_modules/vue-loader/lib??vue-loader-options!./paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/vue/paybackPeriod/paybackPeriodTextInput.vue?vue&type=template&id=2e33b01a&");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__["render"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_paybackPeriodTextInput_vue_vue_type_template_id_2e33b01a___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; });



/***/ }),

/***/ "./resources/sass/style.scss":
/*!***********************************!*\
  !*** ./resources/sass/style.scss ***!
  \***********************************/
/*! no static exports found */
/***/ (function(module, exports) {

// removed by extract-text-webpack-plugin

/***/ }),

/***/ 0:
/*!***************************************************************!*\
  !*** multi ./resources/js/app.js ./resources/sass/style.scss ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! /Users/pascallemmen/Development/Wingssprayer/resources/js/app.js */"./resources/js/app.js");
module.exports = __webpack_require__(/*! /Users/pascallemmen/Development/Wingssprayer/resources/sass/style.scss */"./resources/sass/style.scss");


/***/ })

},[[0,"/js/manifest","/js/vendor"]]]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGtvbW1hL2thbC9rYWwuanMiLCJ3ZWJwYWNrOi8vL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kQ2FsY3VsYXRvci52dWUiLCJ3ZWJwYWNrOi8vL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kSW50YWtlLnZ1ZSIsIndlYnBhY2s6Ly8vcmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RSZXN1bHQudnVlIiwid2VicGFjazovLy9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Nob2NvbGF0L2Rpc3QvanMvY2hvY29sYXQuZXNtLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3VybC1zZWFyY2gtcGFyYW1zLXBvbHlmaWxsL2luZGV4LmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kQ2FsY3VsYXRvci52dWU/Mzg0ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZEludGFrZS52dWU/YmY4MyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFJlc3VsdC52dWU/MjczNiIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/OGVjZCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvcnVudGltZS9jb21wb25lbnROb3JtYWxpemVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy92dWUvZGlzdC92dWUuY29tbW9uLmRldi5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlL2Rpc3QvdnVlLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9hcHAuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvR2xvYmFsaXNhdGlvblNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvUmVnaXN0ZXJDb250cm9sbGVyLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9jb21wb25lbnRzL2Nob2NvbGF0TGlnaHRib3guanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvY2hvY29sYXRlRmFjdG9yeS5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9jb250YWN0U3ViamVjdEhhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvY29va2llSGFuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9jdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9jb21wb25lbnRzL2Vycm9yQ29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9maWxlVXBsb2FkSGFuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9tYXBzSGFuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9vdmVybGF5TWVudUhhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvcHJvamVjdG9ySGFuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvY29tcG9uZW50cy9zY3JvbGxUb0hhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvdGVzdGltb25pYWxTbGlkZXJIYW5kbGVyLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9jb21wb25lbnRzL3RvZ2dsZUhhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMvdmFsaWRhdGlvblNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2NvbXBvbmVudHMveW91dHViZUhhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9icm93c2VySGFuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvZ2xvYmFsL2hlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9tb2RlbHMvY291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9nbG9iYWwvbW9kZWxzL2Vycm9yUmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9tb2RlbHMvbGFuZ3VhZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9tb2RlbHMvdmFsaWRhdGlvblJlc3BvbnNlLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9nbG9iYWwvcG9seWZpbGxzL2V2ZW50UG9seUZpbGwuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9wb2x5ZmlsbHMvaXNJbnRlZ2VyLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy9nbG9iYWwvcG9seWZpbGxzL3Byb21pc2UuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL2dsb2JhbC9zY3JvbGxIYW5kbGVyLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9mb3JtYXRVdGlscy5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvbWFpbi5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZENhbGN1bGF0b3IudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kQ2FsY3VsYXRvci52dWU/ZWNlOCIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZENhbGN1bGF0b3IudnVlPzhkODkiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RJbnRha2UudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kSW50YWtlLnZ1ZT9mZDhjIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kSW50YWtlLnZ1ZT8zZWU4Iiwid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFJlc3VsdC52dWU/OWUxMyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFJlc3VsdC52dWU/ZGZjNSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RUZXh0SW5wdXQudnVlP2U2NGIiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RUZXh0SW5wdXQudnVlPzc2YjAiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL3Nhc3Mvc3R5bGUuc2Nzcz9jNjRkIl0sIm5hbWVzIjpbInJlcXVpcmUiLCJLQUwiLCJpbml0IiwicmVnaXN0ZXJGb3JtIiwiZG9jdW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsIlJlZ2lzdGVyQ29udHJvbGxlciIsIkdsb2JhbGlzYXRpb25TZXJ2aWNlIiwiX2Jhc2VSb3V0ZSIsImNvdW50cnlJc28zIiwic2VsZiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiQWpheCIsInBvc3QiLCJ4aHIiLCJpc0Vycm9yUmVzcG9uc2UiLCJFcnJvclJlc3BvbnNlIiwiaXMiLCJyZXNwb25zZSIsImlzQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIiwiQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIiwiY291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIiwiZnJvbUpzb25TdHJpbmciLCJjb25zb2xlIiwiZXJyb3IiLCJ3cmFwcGVyIiwiZ2xvYmFsaXNhdGlvblNlcnZpY2UiLCJfd3JhcHBlciIsInRhZ05hbWUiLCJfY291bnRyeVNlbGVjdCIsInF1ZXJ5U2VsZWN0b3IiLCJfbGFuZ3VhZ2VTZWxlY3QiLCJfbGFuZ3VhZ2VTZWxlY3RXcmFwcGVyIiwiX2dsb2JhbGlzYXRpb25TZXJ2aWNlIiwiX2hpZGRlbkNsYXNzIiwiX2RvbVBhcnNlciIsIkRPTVBhcnNlciIsIl9jb3VudHJ5Q2hhbmdlZCIsImJpbmQiLCJjb250cm9sTGlzdGVuZXJzIiwiZW5hYmxlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImFkZEV2ZW50TGlzdGVuZXIiLCJ2YWx1ZSIsImdldExhbmd1YWdlc0ZvckNvdW50cnlXaXRoSXNvMyIsInRoZW4iLCJfY2xlYXJMYW5ndWFnZVNlbGVjdCIsImxhbmd1YWdlQ291bnQiLCJsYW5ndWFnZXMiLCJsZW5ndGgiLCJpbmRleCIsImxhbmd1YWdlIiwib3B0aW9uRWxlbWVudCIsIl9jcmVhdGVIdG1sRWxlbWVudEZyb21TdHJpbmciLCJ0aHJlZUxldHRlcklzb0xhbmd1YWdlTmFtZSIsIm5hdGl2ZU5hbWUiLCJhcHBlbmRDaGlsZCIsImNsYXNzTGlzdCIsImFkZCIsInJlbW92ZSIsImVycm9yUmVzcG9uc2UiLCJjaGlsZHJlbiIsInJlbW92ZUNoaWxkIiwiZmlyc3RDaGlsZCIsImZyb20iLCJwYXJzZUZyb21TdHJpbmciLCJib2R5IiwiQ2hvY29sYXQiLCJxdWVyeVNlbGVjdG9yQWxsIiwiQ2hvY29sYXRlRmFjdG9yeSIsImJhbm5lZFZpc2l0b3IiLCJlbnRlciIsImNob2NvbGF0ZUZhY3RvcmllcyIsImlzc2V0IiwiYW1vdW50T2ZDaG9jb2xhdGVGYWN0b3JpZXMiLCJpIiwiQ2hvY29sYXRlQmFyIiwiX2ZsYXNoVGlja2V0IiwiY2hvY29sYXRlQmFyIiwiZ29sZGVuVGlja2V0IiwiZW5qb3lUaGVUb3VyIiwibG9nIiwiY2hvY29sYXRlRmFjdG9yeSIsInRvdXJHcm91cCIsIm9vbXBhTG9vbXBhcyIsImFtb3VudE9mT29tcGFMb29tcGFzIiwidG91ckdyb3VwU2l6ZSIsInZpc2l0b3IiLCJ2aXNpdG9yTmFtZSIsImdldEF0dHJpYnV0ZSIsIl9pc1Zpc2l0b3JCYW5uZWQiLCJfZ2V0QXJyYW5nZW1lbnQiLCJfZmluaXNoVG91ciIsImluZGV4T2YiLCJ2aXNpdG9yVHlwZSIsIm5vZGVOYW1lIiwidHlwZSIsIm5hbWUiLCJncm91cCIsIl9hZGRXaWxsaWVXb25rYSIsImdhdGUiLCJIdHRwUmVxdWVzdCIsIkpTT04iLCJwYXJzZSIsInN0YXR1cyIsIl90aGFua3NGb3JWaXNpdGluZyIsInJlZGlyZWN0VXJsIiwiX2dpdmVGZWVkYmFja1RvTWVtYmVycyIsImVycm9ycyIsIl91bmtub3duR2FwSW5GYWN0b3J5IiwiZSIsIl93aWxsaWUiLCJmZWVkYmFja0FyZWEiLCJpbm5lckhUTUwiLCJfY2xlYXJQcmV2aW91c01hcmtlZEphY2tldHMiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImphY2tldCIsInZpc2l0b3JGZWVkYmFja0FyZWEiLCJ2aXNpdG9yTm9kZSIsIl9ncmFiVmlzaXRvckphY2tldCIsInZpc2l0b3JGZWVkYmFjayIsInZpc2l0b3JGZWVkYmFja0Ftb3VudCIsInZpc2l0b3JGZWVkYmFja0xpbmUiLCJjdXJyZW50RmVlZGJhY2tBcmVhIiwiY2FwaXRhbGl6ZUZpcnN0TGV0dGVyIiwidG9wIiwiYm9keU9mZnNldCIsIndpbmRvdyIsInNjcm9sbFRvIiwibWFya2VkSmFja2V0cyIsIm1hcmtlZEphY2tldHNBbW91bnQiLCJtYXJrZWRKYWNrZXQiLCJtYXJrZWRKYWNrZXRNZXNzYWdlIiwiY3VycmVudExheWVyIiwic2FmZXR5QnJlYWsiLCJwYXJlbnROb2RlIiwiY29udGFpbnMiLCJuZXh0U3RvcCIsImxvY2F0aW9uIiwiQ29udGFjdFN1YmplY3RIYW5kbGVyIiwic3ViamVjdE9wdGlvbnMiLCJzdWJqZWN0T3B0aW9uYWxGaWVsZHMiLCJzaG93T3B0aW9uYWxGaWVsZHNGb3JTdWJqZWN0T3B0aW9ucyIsInN1YmplY3RPcHRpb25zTGVuZ3RoIiwic3ViamVjdE9wdGlvbiIsInN1YmplY3RDaGFuZ2VkIiwic2VsZWN0T3B0aW9uIiwiQ29va2llSGFuZGxlciIsImNvb2tpZUJhciIsImNvb2tpZU92ZXJsYXkiLCJjb29raWVNZXNzYWdlIiwiY29va2llU3dpdGNoIiwiY29va2llRmFkZU91dEFuaW1hdGlvbkR1cmF0aW9uIiwiYWNjZXB0VHJhY2tpbmciLCJpbml0Q29va2llQmFyIiwiaW5pdENvb2tpZU92ZXJsYXkiLCJjaGVja0ZvckNvb2tpZVNldHRpbmdzIiwiaW5pdENvb2tpZVN3aXRjaCIsImNsb3NlQnV0dG9uIiwiY2xvc2VDb29raWVNZXNzYWdlIiwib3BlbkNvb2tpZVNldHRpbmdzQnV0dG9uIiwib3BlbkNvb2tpZVNldHRpbmdzIiwidG9nZ2xlVHJhY2tpbmdJbnB1dCIsImNoZWNrZWQiLCJ0b2dnbGVUcmFja2luZ1NldHRpbmciLCJhY2NlcHRCdXR0b24iLCJzZXRDb29raWVTZXR0aW5ncyIsInNhdmVCdXR0b24iLCJDb29raWUiLCJnZXQiLCJzZXQiLCJlcmFzZSIsInNldFRpbWVvdXQiLCJyZWxvYWQiLCJDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyIiwiY3VzdG9tZXJMb2dvU2xpZGVyQXJlYSIsImN1c3RvbWVyTG9nb1NsaWRlcyIsImFjdGl2ZUxvZ28iLCJhdXRvU2xpZGVUaW1lb3V0SGFuZGxlIiwiYXV0b1NsaWRlUmVzdGFydFRpbWVvdXRIYW5kbGUiLCJhdXRvU2xpZGVJbnRlcnZhbCIsImF1dG9TbGlkZVJlc3RhcnRJbnRlcnZhbCIsImFkZEV2ZW50cyIsInJlc2V0TG9nb3NPcmRlciIsImZpbmlzaExvYWRpbmciLCJuZXh0IiwicHJldmlvdXMiLCJuZXh0TG9nbyIsInVwZGF0ZVNsaWRlciIsImNsZWFyVGltZW91dCIsInJlc2V0QXV0b1NsaWRpbmciLCJwcmV2aW91c0xvZ28iLCJzd2lwZUdlc3R1cmVzIiwiSGFtbWVyIiwib24iLCJzdG9wQXV0b1NsaWRpbmciLCJzdGFydEF1dG9TbGlkaW5nIiwiZG9BdXRvU2xpZGUiLCJnZXRMb2dvSWRzIiwiY3VzdG9tZXJMb2dvc0xlbmd0aCIsImN1c3RvbWVyTG9nb0lkcyIsImN1c3RvbWVyTG9nbyIsImN1c3RvbWVyTG9nb0lkIiwicHVzaCIsImlkcyIsInNldEF0dHJpYnV0ZSIsInByZXZpb3VzTG9jYXRvciIsIl9jYWxjUHJldmlvdXNQb3NpdGlvbnMiLCJwcmV2aW91c2VyIiwiX2NhbGNOZXh0UG9zaXRpb25zIiwibmV4dGVyIiwibmV4dGVyTG9jYXRvciIsInNsaWRlIiwiJGFtb3VudCIsIl9wcmVwYXJlQ3VzdG9tZXJMb2dvSHRtbCIsImN1c3RvbWVyTG9nb3NIdG1sIiwidXJsIiwiaWQiLCJpbWFnZSIsIkVycm9yQ29udHJvbGxlciIsIl9jbGFzc1RvSGlkZSIsIl9lcnJvckVsZW1lbnRJZFN1ZmZpeCIsImZpZWxkU2VsZWN0b3IiLCJzZWxlY3RvciIsImVycm9yRWxlbWVudCIsImlubmVyVGV4dCIsIkZpbGVVcGxvYWRIYW5kbGVyIiwiZmlsZVVwbG9hZFdyYXBwZXJDbGFzcyIsImZpbGVVcGxvYWRMaXN0Q2xhc3MiLCJmaWxlVXBsb2FkSW5wdXRDbGFzcyIsImZpbGVVcGxvYWRCdXR0b25DbGFzcyIsImZpbGVVcGxvYWRzIiwiZmlsZVVwbG9hZHNDb3VudCIsImZpbGVVcGxvYWQiLCJpbml0RmlsZVVwbG9hZEhhbmRsZXIiLCJhZGRGaWxlIiwiaW5wdXRFbGVtZW50Iiwibm9kZSIsImNsb25lTm9kZSIsImxpc3QiLCJsaSIsImNyZWF0ZUVsZW1lbnQiLCJ0ZXh0Tm9kZSIsImNyZWF0ZVRleHROb2RlIiwic3BsaXQiLCJldmVudEhhbmRsZXIiLCJzdHlsZSIsImRpc3BsYXkiLCJyZW1vdmVGaWxlIiwiZXZlbnQiLCJ0YXJnZXQiLCJzdWJzdHJpbmciLCJjbGljayIsImlucHV0QnV0dG9uRWxlbWVudCIsIk1hcHNIYW5kbGVyIiwibWFwcyIsImtleSIsIm1hcCIsImhhc0F0dHJpYnV0ZSIsImxhdCIsInBhcnNlRmxvYXQiLCJsbmciLCJzdHlsZXMiLCJzZXRDdXN0b21TdHlsaW5nIiwiZ29vZ2xlIiwiZ2V0U2NyaXB0IiwiZHJhd01hcHMiLCJnb29nbGVNYXAiLCJNYXAiLCJ6b29tIiwiY2VudGVyIiwiZGlzYWJsZURlZmF1bHRVSSIsIm1hcmtlciIsIk1hcmtlciIsInBvc2l0aW9uIiwiYm9keVNjcm9sbExvY2siLCJPdmVybGF5TWVudUhhbmRsZXIiLCJvdmVybGF5TWVudVRyaWdnZXJMaXN0Iiwib3ZlcmxheU1lbnVUcmlnZ2VyTGlzdENvdW50Iiwib3ZlcmxheU1lbnVUcmlnZ2VyIiwiaW5pdE92ZXJsYXlNZW51IiwidG9nZ2xlT3ZlcmxheU1lbnUiLCJvdmVybGF5TWVudU5hdiIsImVuYWJsZUJvZHlTY3JvbGwiLCJlbGVtIiwidGFiSW5kZXgiLCJkaXNhYmxlQm9keVNjcm9sbCIsInRvZ2dsZSIsImhpZGRlbiIsInByb2plY3RvcnMiLCJwcm9qZWN0b3JDb250YWluZXJzIiwicHJvamVjdG9yQ29udGFpbmVyc0xlbmd0aCIsInByb2plY3RvciIsInByb2plY3RvcklkIiwicHJvamVjdG9yU2V0dGluZyIsIlByb2plY3RvclNldHRpbmciLCJzbGlkZXJJZCIsInNsaWRlUXVlcnkiLCJuYXZpZ2F0aW9uQnV0dG9ucyIsImRvdHMiLCJhdXRvU2xpZGUiLCJzbGlkZXJJbnRlcnZhbCIsIlByb2plY3RvciIsInByZXBhcmVQYXJhbWV0ZXJzIiwic2V0dGluZ3NPYmplY3QiLCJkZWZpbmVkUHJldmlvdXNOZXh0IiwiY2FwdGlvbnMiLCJzZXRQcm9qZWN0b3JJZCIsInN0cmluZyIsInNldERlZmluZWRQcmV2aW91c05leHQiLCJib29sZWFuIiwic2V0QXV0b1NsaWRlIiwic2V0U2xpZGVySW50ZXJ2YWwiLCJpbnRlZ2VyIiwic2V0U2xpZGVRdWVyeSIsInNldE5hdmlnYXRpb25CdXR0b25zIiwic2V0RG90cyIsInNldENhcHRpb25zIiwiZ2V0UHJvamVjdG9ySWQiLCJnZXREZWZpbmVkUHJldmlvdXNOZXh0IiwiZ2V0QXV0b1NsaWRlIiwiZ2V0U2xpZGVySW50ZXJ2YWwiLCJnZXRTbGlkZVF1ZXJ5IiwiZ2V0TmF2aWdhdGlvbkJ1dHRvbnMiLCJnZXREb3RzIiwiZ2V0Q2FwdGlvbnMiLCJmaWxsIiwic2V0dGluZ3NPYmplY3RLZXlzIiwic2V0dGluZ3NPYmplY3RMZW5ndGgiLCJzZXR0aW5ncyIsInNsaWRlck9iamVjdCIsImFjdGl2ZVNsaWRlSWQiLCJwcmV2aW91c1NsaWRlSWQiLCJuZXh0U2xpZGVJZCIsImF2YWlsYWJsZVNsaWRlcyIsInNsaWRlcyIsInNldFByZXZpb3VzQW5kTmV4dFNsaWRlIiwic2V0U2xpZGUiLCJyZXNldEF1dG9TbGlkZSIsIm5leHRTbGlkZSIsInByZXZpb3VzU2xpZGUiLCJuYXZpZ2F0aW9uQnV0dG9uc0xlbmd0aCIsIm5hdmlnYXRpb25CdXR0b24iLCJjbGlja05hdmlnYXRpb25CdXR0b24iLCJkb3RzTGVuZ3RoIiwiZG90IiwiY2xpY2tEb3QiLCJjbGVhckludGVydmFsIiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwic2V0SW50ZXJ2YWwiLCJzbGlkZXNMZW5ndGgiLCJzbGlkZU9yZGVyIiwicGFyc2VJbnQiLCJzZXRBY3RpdmVEb3QiLCJzZXRBY3RpdmVDYXB0aW9uIiwibmF2QnV0dG9uIiwiY2xpY2tlZERvdCIsImRvdE9yZGVyIiwiY2FwdGlvbnNMZW5ndGgiLCJjYXB0aW9uIiwiY2FwdGlvbk9yZGVyIiwiU2Nyb2xsVG9IYW5kbGVyIiwib2Zmc2V0IiwiZHVyYXRpb24iLCJzdGFydCIsImNoYW5nZSIsImN1cnJlbnRUaW1lIiwiYWxsb3dBbmltYXRpb24iLCJzY3JvbGxUb0FuaW1hdGlvbiIsImVhc2luZyIsImFuY2hvckxpbmtzIiwiYW5jaG9yTGlua3NBbW91bnQiLCJhbmNob3JMaW5rIiwicHJlcGFyZVNjcm9sbFRvIiwicHJldmVudERlZmF1bHQiLCJlbGVtZW50SWQiLCJzdWJzdHIiLCJzY3JvbGxUb0VsZW1lbnQiLCJzY3JvbGxUb0VsZW1lbnRQb3NpdGlvbiIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsImRvY3VtZW50RWxlbWVudCIsIk1hdGgiLCJtYXgiLCJzY3JvbGxUb3AiLCJwYWdlWU9mZnNldCIsInN0YXJ0VGltZSIsInBlcmZvcm1hbmNlIiwibm93IiwiRGF0ZSIsImdldFRpbWUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJhbmltYXRlU2Nyb2xsIiwiYWJvcnRTY3JvbGxBbmltYXRpb24iLCJ0aW1lc3RhbXAiLCJwcm9ncmVzcyIsIm1pbiIsIkVhc2luZ0Z1bmN0aW9ucyIsIm5ld1Njcm9sbFRvcCIsImNhbmNlbEFuaW1hdGlvbkZyYW1lIiwidGVzdGltb25pYWxTbGlkZXJzIiwidGVzdGltb25pYWxTbGlkZXJDb250YWluZXJzIiwidGVzdGltb25pYWxTbGlkZXJDb250YWluZXJzTGVuZ3RoIiwidGVzdGltb25pYWxTbGlkZXIiLCJ0ZXN0aW1vbmlhbFNsaWRlcklkIiwidGVzdGltb25pYWxTbGlkZXJTZXR0aW5nIiwiVG9nZ2xlSGFuZGxlciIsInRvZ2dsZVRyaWdnZXJzIiwidG9nZ2xlVHJpZ2dlcnNDb3VudCIsInRvZ2dsZVRyaWdnZXIiLCJpbml0VG9nZ2xlIiwiYWRqdXN0VG9nZ2xlIiwiY3VycmVudFRhcmdldCIsInRhcmdldEFycmF5Iiwic2xpY2UiLCJjYWxsIiwiVmFsaWRhdGlvblNlcnZpY2UiLCJkYXRhIiwiRm9ybURhdGEiLCJwb3N0Rm9ybURhdGEiLCJZb3V0dWJlSGFuZGxlciIsInlvdXR1YmVDbGFzcyIsInBsYXllcnMiLCJ5b3V0dWJlUGxheWVycyIsInlvdXR1YmVQbGF5ZXJzQW1vdW50IiwieW91dHViZVBsYXllciIsInlvdXR1YmVQbGF5ZXJJZCIsInlvdXR1YmVFbGVtZW50IiwibGluayIsImF1dG9QbGF5IiwiaW5pdFlvdXR1YmUiLCJZVCIsIlBsYXllciIsIm9uWW91VHViZVBsYXllckFQSVJlYWR5IiwibG9hZFBsYXllcnMiLCJwbGF5ZXIiLCJoZWlnaHQiLCJ3aWR0aCIsInZpZGVvSWQiLCJob3N0IiwicGxheWVyVmFycyIsIm1vZGVzdGJyYW5kaW5nIiwicmVsIiwiZGlzYWJsZWtiIiwiYXV0b3BsYXkiLCJldmVudHMiLCJvblN0YXRlQ2hhbmdlIiwib25SZWFkeSIsInBsYXllckNvbnRhaW5lcklkIiwiZ2V0SWZyYW1lIiwidmlkZW9TdGF0ZSIsIlBsYXllclN0YXRlIiwiRU5ERUQiLCJwbGF5VmlkZW8iLCJCcm93c2VySGFuZGxlciIsInVzZXJBZ2VudCIsImJyb3dzZXJJbmZvIiwibmF2aWdhdG9yIiwiZ2V0QnJvd3NlckluZm8iLCJoYW5kbGVJRSIsImhhbmRsZVNhZmFyaSIsIm1zaWUiLCJpZWx0MTEiLCJpZTExIiwibWF0Y2giLCJ2ZXJzaW9uIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJ1YSIsInRlbSIsIk0iLCJ0ZXN0IiwiZXhlYyIsImFwcE5hbWUiLCJhcHBWZXJzaW9uIiwic3BsaWNlIiwib2JqIiwibGluZWFyIiwidCIsImVhc2VJblF1YWQiLCJlYXNlT3V0UXVhZCIsImVhc2VJbk91dFF1YWQiLCJlYXNlSW5DdWJpYyIsImVhc2VPdXRDdWJpYyIsImVhc2VJbk91dEN1YmljIiwiZWFzZUluUXVhcnQiLCJlYXNlT3V0UXVhcnQiLCJlYXNlSW5PdXRRdWFydCIsImVhc2VJblF1aW50IiwiZWFzZU91dFF1aW50IiwiZWFzZUluT3V0UXVpbnQiLCJzb3VyY2UiLCJjYWxsYmFjayIsInNjcmlwdCIsImFzeW5jIiwic2NyaXB0cyIsInByaW9yIiwib25sb2FkIiwib25yZWFkeXN0YXRlY2hhbmdlIiwiXyIsImlzQWJvcnQiLCJyZWFkeVN0YXRlIiwidW5kZWZpbmVkIiwic3JjIiwiaW5zZXJ0QmVmb3JlIiwiZGVib3VuY2UiLCJmdW5jIiwid2FpdCIsImltbWVkaWF0ZSIsInRpbWVvdXQiLCJjb250ZXh0IiwiYXJncyIsImFyZ3VtZW50cyIsImxhdGVyIiwiYXBwbHkiLCJjYWxsTm93IiwiZGF5cyIsImRvbWFpbiIsImRvbWFpblBhcnRzIiwiZGF0ZSIsImV4cGlyZXMiLCJzZXRUaW1lIiwidG9HTVRTdHJpbmciLCJjb29raWUiLCJzaGlmdCIsImpvaW4iLCJuYW1lRVEiLCJjYSIsImMiLCJjaGFyQXQiLCJudW1iZXJfZm9ybWF0IiwibnVtYmVyIiwiZGVjaW1hbHMiLCJkZWNfcG9pbnQiLCJ0aG91c2FuZHNfc2VwIiwicmVwbGFjZSIsIm4iLCJpc0Zpbml0ZSIsInByZWMiLCJhYnMiLCJzZXAiLCJkZWMiLCJzIiwidG9GaXhlZEZpeCIsImsiLCJwb3ciLCJyb3VuZCIsIkFycmF5IiwiRWxlbWVudCIsInByb3RvdHlwZSIsImNsb3Nlc3QiLCJtYXRjaGVzIiwibXNNYXRjaGVzU2VsZWN0b3IiLCJ3ZWJraXRNYXRjaGVzU2VsZWN0b3IiLCJlbCIsImFuY2VzdG9yIiwicGFyZW50RWxlbWVudCIsIlhNTEh0dHBSZXF1ZXN0IiwidG9rZW4iLCJjb250ZW50Iiwib3BlbiIsInNldFJlcXVlc3RIZWFkZXIiLCJzZW5kIiwic3RyaW5naWZ5IiwidG9VcHBlckNhc2UiLCJzbmFrZVRvQ2FtZWwiLCJtIiwiaW5kZXhJblBhcmVudCIsImNoaWxkTm9kZXMiLCJudW0iLCJub2RlVHlwZSIsImNvcHlUb0NsaXBib2FyZCIsImVkaXRhYmxlIiwiY29udGVudEVkaXRhYmxlIiwicmVhZE9ubHkiLCJyYW5nZSIsImNyZWF0ZVJhbmdlIiwic2VsZWN0Tm9kZUNvbnRlbnRzIiwic2VsZWN0aW9uIiwiZ2V0U2VsZWN0aW9uIiwicmVtb3ZlQWxsUmFuZ2VzIiwiYWRkUmFuZ2UiLCJzZXRTZWxlY3Rpb25SYW5nZSIsInNlbGVjdCIsImV4ZWNDb21tYW5kIiwicmVjdCIsInNjcm9sbExlZnQiLCJwYWdlWE9mZnNldCIsImxlZnQiLCJfbGFuZ3VhZ2VzIiwianNvbiIsImpzb25PYmplY3QiLCJpbnN0YW5jZSIsImxhbmd1YWdlT2JqZWN0IiwiTGFuZ3VhZ2UiLCJkaXNwbGF5TmFtZSIsInR3b0xldHRlcklzb0xhbmd1YWdlTmFtZSIsImxvZ0Vycm9ycyIsImhhc093blByb3BlcnR5IiwiaXNBcnJheSIsIl9tZXNzYWdlIiwiX2Vycm9ycyIsIm1lc3NhZ2UiLCJmaWVsZE5hbWUiLCJfbmFtZSIsIl9kaXNwbGF5TmFtZSIsIl9uYXRpdmVOYW1lIiwiX3R3b0xldHRlcklzb0xhbmd1YWdlTmFtZSIsIl90aHJlZUxldHRlcklzb0xhbmd1YWdlTmFtZSIsIlZhbGlkYXRpb25SZXNwb25zZSIsIl92YWxpZCIsInRvSlNPTiIsIl90b0pzb24iLCJ2YWxpZCIsImNyZWF0ZU5ld0V2ZW50IiwiZXZlbnROYW1lIiwiRXZlbnQiLCJjcmVhdGVFdmVudCIsImluaXRFdmVudCIsImRpc3BhdGNoRXZlbnRGb3JFbGVtZW50IiwiZWxlbWVudCIsImRpc3BhdGNoRXZlbnQiLCJmaXJlRXZlbnQiLCJldmVudFR5cGUiLCJmbG9vciIsImdsb2JhbCIsImZhY3RvcnkiLCJleHBvcnRzIiwibW9kdWxlIiwiZGVmaW5lIiwiZmluYWxseUNvbnN0cnVjdG9yIiwiY29uc3RydWN0b3IiLCJyZWFzb24iLCJzZXRUaW1lb3V0RnVuYyIsIm5vb3AiLCJmbiIsInRoaXNBcmciLCJUeXBlRXJyb3IiLCJfc3RhdGUiLCJfaGFuZGxlZCIsIl92YWx1ZSIsIl9kZWZlcnJlZHMiLCJkb1Jlc29sdmUiLCJoYW5kbGUiLCJkZWZlcnJlZCIsIl9pbW1lZGlhdGVGbiIsImNiIiwib25GdWxmaWxsZWQiLCJvblJlamVjdGVkIiwicHJvbWlzZSIsInJldCIsIm5ld1ZhbHVlIiwiZmluYWxlIiwiX3VuaGFuZGxlZFJlamVjdGlvbkZuIiwibGVuIiwiSGFuZGxlciIsImRvbmUiLCJleCIsInByb20iLCJhbGwiLCJhcnIiLCJyZW1haW5pbmciLCJyZXMiLCJ2YWwiLCJyYWNlIiwidmFsdWVzIiwic2V0SW1tZWRpYXRlIiwiZXJyIiwid2FybiIsImdsb2JhbE5TIiwiRXJyb3IiLCJTY3JvbGxIYW5kbGVyIiwidGltZSIsIndhaXRUaHJvdHRsZSIsIndhaXREZWJvdW5jZSIsImxhc3RTY3JvbGxUb3BQb3NpdGlvbiIsInNjcm9sbERpcmVjdGlvbkRvd24iLCJzY3JvbGxEaXJlY3Rpb25VcCIsInRyaWdnZXJPbkluaXQiLCJ0cmlnZ2VyVGhyb3R0bGUiLCJ0cmlnZ2VyU21vb3RoIiwidHJpZ2dlckRlYm91bmNlIiwidHJpZ2dlckVsZW1lbnRJblZpZXdwb3J0QW5pbWF0aW9uIiwiZGV0ZWN0U2Nyb2xsRGlyZWN0aW9uIiwidG9nZ2xlU3RpY2t5SGVhZGVyIiwiZGV0ZWN0SWZFbGVtZW50SXNQYXJ0bHlJblZpZXdwb3J0Iiwid2luZG93SGVpZ2h0IiwiaW5uZXJIZWlnaHQiLCJjbGllbnRIZWlnaHQiLCJ3aW5kb3dXaWR0aCIsImlubmVyV2lkdGgiLCJjbGllbnRXaWR0aCIsInZlcnRpY2FsSW5WaWV3IiwiaG9yaXpvbnRhbEluVmlldyIsImRldGVjdElmRWxlbWVudElzRnVsbHlJblZpZXdwb3J0IiwiYm90dG9tIiwic2Nyb2xsVG9wUG9zaXRpb24iLCJlbGVtZW50cyIsImVsZW1lbnRzTGVuZ3RoIiwic3RpY2t5SGVhZGVyIiwidmlzaWJsZVN0aWNreUhlYWRlckNsYXNzIiwic3VibmF2TGlzdCIsInN1Yk5hdklzVmlzaWJsZSIsImdldENvbXB1dGVkU3R5bGUiLCJ2aXNpYmlsaXR5IiwiRm9ybWF0VXRpbHMiLCJpbnB1dCIsImV2ZXJ5IiwicmVnZXgiLCJyZXZlcnNlIiwiUmVnRXhwIiwidG9TdHJpbmciLCJmYWxsYmFjayIsImlzTmFOIiwibG93ZXIiLCJ1cHBlciIsIlZ1ZSIsImNvbXBvbmVudHMiLCJwYXliYWNrUGVyaW9kQ2FsY3VsYXRvciIsInBheWJhY2tQZXJpb2RJbnRha2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTCxlQUFlLHFCQUFxQjtBQUNwQzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsZ0JBQWdCLGlDQUFpQztBQUNqRCxnQkFBZ0IscUJBQXFCO0FBQ3JDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSzs7QUFF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QTtBQUFBLEtBSkE7QUFLQTtBQUFBO0FBQUE7QUFBQSxLQUxBO0FBTUE7QUFBQTtBQUFBO0FBQUEsS0FOQTtBQU9BO0FBQUE7QUFBQTtBQUFBO0FBUEEsR0FGQTtBQVdBO0FBQ0E7QUFFQSxHQWRBO0FBZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUZBLE1BRUE7QUFDQSxLQUxBO0FBTUEsZUFOQSx1QkFNQSxNQU5BLEVBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBWEEsR0FmQTtBQTRCQTtBQUNBO0FBQ0E7QUFDQSxLQUhBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FOQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkhBSkEsQ0FLQTs7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFmQTtBQUpBO0FBNUJBLEc7Ozs7Ozs7Ozs7OztBQ25CQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUgsc0JBQXNCOztBQUV0QixrQkFBa0I7O0FBRWxCLHFCQUFxQjs7QUFFckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLHdDQUF3QyxRQUFRO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVlLHVFQUFRLEVBQUM7Ozs7Ozs7Ozs7OztBQ3RyQnhCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFVBQVU7Ozs7Ozs7Ozs7OztBQ3ZMdEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGlCQUFpQjtBQUN0QztBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMENBQTBDLHNCQUFzQixFQUFFO0FBQ2xFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOzs7Ozs7Ozs7Ozs7O0FDekxEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxtQkFBTyxDQUFDLGlFQUFjO0FBQ3RCO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIscUJBQXFCO0FBQ3hDLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssR0FBRztBQUNSO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsT0FBTztBQUN6QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsT0FBTztBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLGlCQUFpQjtBQUNsQztBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDJCQUEyQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxTQUFTO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZDQUE2QyxxQ0FBcUMsRUFBRTtBQUNwRjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0NBQW9DLHlDQUF5QyxFQUFFO0FBQy9FOztB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QUFDaEQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixxQkFBcUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWEscUJBQXFCO0FBQ2xDO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLE9BQU87QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGtFQUFrRTtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQixtQkFBbUI7QUFDekM7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsT0FBTztBQUN0QztBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0Esa0NBQWtDLE9BQU87QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEMsZUFBZTtBQUMzRCxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xELDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FB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RUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLHVGQUF1RjtBQUM1RjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBDQUEwQztBQUMxQyxpQkFBaUIseUJBQXlCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLCtCQUErQjtBQUNsQyxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILG9CQUFvQixvQkFBb0I7QUFDeEMsc0JBQXNCLDRCQUE0QjtBQUNsRDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QyxPQUFPO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLG1CQUFtQjtBQUNuQix5QkFBeUI7QUFDekI7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsNkNBQTZDO0FBQzlFO0FBQ0E7QUFDQSw2Q0FBNkMsNENBQTRDOztBQUV6RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSywyQ0FBMkMsOEJBQThCLEVBQUU7O0FBRWhGO0FBQ0Esd0NBQXdDLE9BQU87QUFDL0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLHFCQUFxQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxPQUFPO0FBQzlDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxTQUFTO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLE9BQU87QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCOztBQUUxQixrQkFBa0I7QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixxQkFBcUI7QUFDeEM7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIseUJBQXlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHlCQUF5QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLDBCQUEwQjtBQUNwRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsb0JBQW9CLEVBQUU7O0FBRXBEO0FBQ0E7QUFDQSxpQkFBaUIsc0JBQXNCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7O0FBSUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBLG9CQUFvQjtBQUNwQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGVBQWU7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRTtBQUN0RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQzs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEMsMkJBQTJCLEVBQUU7QUFDdkUsS0FBSztBQUNMO0FBQ0EsMENBQTBDLDRCQUE0QixFQUFFO0FBQ3hFLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxPQUFPO0FBQzFDO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixZQUFZO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isc0JBQXNCOztBQUVyRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9COztBQUVwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0NBQWdDOztBQUVoQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixhQUFhO0FBQ2pDO0FBQ0EscUJBQXFCLGNBQWM7QUFDbkM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGFBQWEsa0JBQWtCO0FBQy9CO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJEQUEyRDtBQUMzRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHlCQUF5QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixxQkFBcUI7QUFDMUM7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsZ0NBQWdDO0FBQ3RGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUJBQXVCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0QkFBNEIsNkJBQTZCO0FBQ3pEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELG1CQUFtQjtBQUMzRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixhQUFhO0FBQ3BDLHVCQUF1QixhQUFhO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlGQUFpRjtBQUNqRiw0QkFBNEI7QUFDNUI7QUFDQSwyQkFBMkI7QUFDM0Isd0JBQXdCLGlFQUFpRTtBQUN6RixZQUFZLDBGQUEwRjtBQUN0RyxNQUFNLEtBQUssMENBQTBDO0FBQ3JEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLGtCQUFrQjtBQUMvRCxzQkFBc0IsK0NBQStDO0FBQ3JFLGlEQUFpRDs7QUFFakQ7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLDJCQUEyQjtBQUN0RCxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sNkNBQTZDLEVBQUU7QUFDdEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsd0JBQXdCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCw0QkFBNEIsRUFBRTtBQUNsRixLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCwrQkFBK0IsRUFBRTtBQUNyRixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLGFBQWE7O0FBRTNEO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZEO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUMscUNBQXFDOztBQUV0RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsdUNBQXVDLEVBQUU7QUFDcEY7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLDJDQUEyQyxFQUFFO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLE9BQU87QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFDQUFxQyw4QkFBOEIsRUFBRTtBQUNyRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtDQUFrQyx1Q0FBdUM7O0FBRXpFLHFDQUFxQywwQkFBMEI7O0FBRS9EO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFO0FBQ2hFO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsT0FBTztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLG9CQUFvQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPLDRCQUE0QjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLE9BQU87QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsT0FBTztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0Msd0JBQXdCLEVBQUU7QUFDMUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsT0FBTztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLE9BQU87QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsV0FBVztBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0Ms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QTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBLDhDQUE4QyxtQkFBbUIsRUFBRTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsdUJBQXVCLEVBQUU7QUFDdkUsU0FBUztBQUNULGdEQUFnRCxxQkFBcUIsRUFBRTtBQUN2RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7Ozs7Ozs7Ozs7OztBQ3RyWEEsSUFBSSxLQUFxQyxFQUFFLEVBRTFDO0FBQ0QsbUJBQW1CLG1CQUFPLENBQUMsc0VBQXFCO0FBQ2hEOzs7Ozs7Ozs7Ozs7QUNKQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRDQUE0Qzs7QUFFNUM7Ozs7Ozs7Ozs7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7OztBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7QUFJQTs7OztBQUdBQSxtQkFBTyxDQUFDLG1EQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMseUZBQUQsQ0FBUDs7QUFDQUEsbUJBQU8sQ0FBQyxzRkFBRCxDQUFQO0FBRUE7Ozs7O0FBSUFBLG1CQUFPLENBQUMsMEZBQUQsQ0FBUDs7QUFDQUEsbUJBQU8sQ0FBQyxrRkFBRCxDQUFQOztBQUNBQSxtQkFBTyxDQUFDLDhFQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMsMERBQUQsQ0FBUCxDLENBQTZCOzs7QUFDN0JBLG1CQUFPLENBQUMsd0VBQUQsQ0FBUCxDLENBQ0E7OztBQUNBQSxtQkFBTyxDQUFDLHNFQUFELENBQVA7QUFHQTs7Ozs7QUFJQUEsbUJBQU8sQ0FBQyxvRkFBRCxDQUFQOztBQUNBQSxtQkFBTyxDQUFDLDhFQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMsOEZBQUQsQ0FBUCxDLENBQ0E7OztBQUNBQSxtQkFBTyxDQUFDLHNGQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMsMEVBQUQsQ0FBUDs7QUFDQUEsbUJBQU8sQ0FBQyx3RkFBRCxDQUFQOztBQUNBQSxtQkFBTyxDQUFDLHNHQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMsb0ZBQUQsQ0FBUDs7QUFDQUEsbUJBQU8sQ0FBQyxrRkFBRCxDQUFQOztBQUNBQSxtQkFBTyxDQUFDLG9GQUFELENBQVAsQyxDQUNBO0FBQ0E7OztBQUNBQSxtQkFBTyxDQUFDLG9HQUFELENBQVA7O0FBQ0FBLG1CQUFPLENBQUMsOEVBQUQsQ0FBUDs7QUFDQUEsbUJBQU8sQ0FBQyxnRkFBRCxDQUFQLEMsQ0FDQTs7QUFHQTs7Ozs7QUFJQUEsbUJBQU8sQ0FBQywwRUFBRCxDQUFQOztBQUdBO0FBQ0FDLDhDQUFHLENBQUNDLElBQUo7QUFFQSxJQUFJQyxZQUFZLEdBQUdDLFFBQVEsQ0FBQ0MsY0FBVCxDQUF3QixjQUF4QixDQUFuQjtBQUNBLElBQUdGLFlBQUgsRUFBaUIsSUFBSUcsaUZBQUosQ0FBdUJILFlBQXZCLEVBQXFDLElBQUlJLHFGQUFKLEVBQXJDLEU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuRWpCO0FBQ0E7O0lBRU1BLG9CO0FBRUYsa0NBQ0E7QUFBQTs7QUFDSSxTQUFLQyxVQUFMLEdBQWtCLEdBQWxCO0FBQ0g7QUFFRDs7Ozs7Ozs7O21EQUsrQkMsVyxFQUFhO0FBQ3hDLFVBQUlDLElBQUksR0FBRyxJQUFYO0FBRUEsYUFBTyxJQUFJQyxPQUFKLENBQVksVUFBU0MsT0FBVCxFQUFrQkMsTUFBbEIsRUFBMEI7QUFDekNDLFlBQUksQ0FBQ0MsSUFBTCxDQUNJTCxJQUFJLENBQUNGLFVBQUwsR0FBZ0IsZ0NBRHBCLEVBRUk7QUFBRUMscUJBQVcsRUFBRUE7QUFBZixTQUZKLEVBR0ksVUFBU08sR0FBVCxFQUFjO0FBQ1Y7QUFDQSxjQUFJQyxlQUFlLEdBQUdDLDBFQUFhLENBQUNDLEVBQWQsQ0FBaUJILEdBQUcsQ0FBQ0ksUUFBckIsRUFBK0IsS0FBL0IsQ0FBdEI7QUFDQSxjQUFJQywwQkFBMEIsR0FBR0MsZ0dBQXdCLENBQUNILEVBQXpCLENBQTRCSCxHQUFHLENBQUNJLFFBQWhDLEVBQTBDLEtBQTFDLENBQWpDOztBQUVBLGNBQUcsQ0FBQ0gsZUFBSixFQUFxQjtBQUNqQixnQkFBR0ksMEJBQUgsRUFBK0I7QUFDM0Isa0JBQUlFLHdCQUF3QixHQUFHRCxnR0FBd0IsQ0FBQ0UsY0FBekIsQ0FBd0NSLEdBQUcsQ0FBQ0ksUUFBNUMsQ0FBL0I7QUFDQVIscUJBQU8sQ0FBQ1csd0JBQUQsQ0FBUDtBQUNILGFBSEQsTUFJSztBQUNERSxxQkFBTyxDQUFDQyxLQUFSLENBQWMsMkdBQXlHVixHQUFHLENBQUNJLFFBQTNIO0FBQ0FQLG9CQUFNO0FBQ1Q7QUFDSixXQVRELE1BU087QUFDSCxnQkFBSU8sUUFBUSxHQUFHRiwwRUFBYSxDQUFDTSxjQUFkLENBQTZCUixHQUFHLENBQUNJLFFBQWpDLENBQWY7QUFDQVAsa0JBQU0sQ0FBQ08sUUFBRCxDQUFOO0FBQ0g7QUFDSixTQXJCTDtBQXVCSCxPQXhCTSxDQUFQO0FBeUJIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQzNDQ2Qsa0I7QUFDRjs7OztBQUlBLDhCQUFZcUIsT0FBWixFQUFxQkMsb0JBQXJCLEVBQTJDO0FBQUE7O0FBQ3ZDLFNBQUtDLFFBQUwsR0FBZ0JGLE9BQWhCOztBQUNBLFFBQUcsQ0FBQyxLQUFLRSxRQUFOLElBQWtCLEtBQUtBLFFBQUwsQ0FBY0MsT0FBZCxLQUEwQixNQUEvQyxFQUNBO0FBQ0lMLGFBQU8sQ0FBQ0MsS0FBUixDQUFjLG9HQUFkO0FBQ0E7QUFDSDs7QUFFRCxTQUFLSyxjQUFMLEdBQXNCLEtBQUtGLFFBQUwsQ0FBY0csYUFBZCxDQUE0Qix3QkFBNUIsQ0FBdEI7O0FBQ0EsUUFBRyxDQUFDLEtBQUtELGNBQVQsRUFBeUI7QUFDckJOLGFBQU8sQ0FBQ0MsS0FBUixDQUFjLDJHQUFkO0FBQ0E7QUFDSDs7QUFFRCxTQUFLTyxlQUFMLEdBQXVCLEtBQUtKLFFBQUwsQ0FBY0csYUFBZCxDQUE0Qix5QkFBNUIsQ0FBdkI7O0FBQ0EsUUFBRyxDQUFDLEtBQUtELGNBQVQsRUFBeUI7QUFDckJOLGFBQU8sQ0FBQ0MsS0FBUixDQUFjLDRHQUFkO0FBQ0E7QUFDSDs7QUFFRCxTQUFLUSxzQkFBTCxHQUE4QixLQUFLTCxRQUFMLENBQWNHLGFBQWQsQ0FBNEIsc0JBQTVCLENBQTlCOztBQUNBLFFBQUcsQ0FBQyxLQUFLRSxzQkFBTixJQUFnQyxLQUFLQSxzQkFBTCxDQUE0QkosT0FBNUIsS0FBd0MsS0FBM0UsRUFBa0Y7QUFDOUVMLGFBQU8sQ0FBQ0MsS0FBUixDQUFjLDZIQUFkO0FBQ0E7QUFDSDs7QUFHRCxTQUFLUyxxQkFBTCxHQUE2QlAsb0JBQTdCOztBQUNBLFFBQUcsQ0FBQ0Esb0JBQUosRUFBMEI7QUFDdEJILGFBQU8sQ0FBQ0MsS0FBUixDQUFjLGdIQUFkO0FBQ0E7QUFDSDs7QUFFRCxTQUFLVSxZQUFMLEdBQW9CLFVBQXBCLENBakN1QyxDQWlDUDs7QUFFaEMsU0FBS0MsVUFBTCxHQUFrQixJQUFJQyxTQUFKLEVBQWxCO0FBRUEsU0FBS0MsZUFBTCxHQUF1QixLQUFLQSxlQUFMLENBQXFCQyxJQUFyQixDQUEwQixJQUExQixDQUF2QjtBQUNBLFNBQUtDLGdCQUFMLENBQXNCLElBQXRCOztBQUVBLFNBQUtGLGVBQUw7QUFDSDs7Ozt1Q0FFK0I7QUFBQSxVQUFmRyxNQUFlLHVFQUFOLElBQU07O0FBQzVCLFdBQUtYLGNBQUwsQ0FBb0JZLG1CQUFwQixDQUF3QyxRQUF4QyxFQUFrRCxLQUFLSixlQUF2RDs7QUFFQSxVQUFHRyxNQUFILEVBQVc7QUFDUCxhQUFLWCxjQUFMLENBQW9CYSxnQkFBcEIsQ0FBcUMsUUFBckMsRUFBK0MsS0FBS0wsZUFBcEQ7QUFDSDtBQUNKO0FBRUQ7Ozs7OztzQ0FHa0I7QUFDZCxVQUFJOUIsV0FBVyxHQUFHLEtBQUtzQixjQUFMLENBQW9CYyxLQUF0QztBQUNBLFVBQUluQyxJQUFJLEdBQUcsSUFBWDs7QUFFQSxXQUFLeUIscUJBQUwsQ0FBMkJXLDhCQUEzQixDQUEwRHJDLFdBQTFELEVBQXVFc0MsSUFBdkU7QUFDSTtBQUNBLGdCQUFTeEIsd0JBQVQsRUFBbUM7QUFDL0JiLFlBQUksQ0FBQ3NDLG9CQUFMOztBQUNBLFlBQUlDLGFBQWEsR0FBRzFCLHdCQUF3QixDQUFDMkIsU0FBekIsQ0FBbUNDLE1BQXZEOztBQUNBLGFBQUksSUFBSUMsS0FBSyxHQUFHLENBQWhCLEVBQW1CQSxLQUFLLEdBQUdILGFBQTNCLEVBQTBDRyxLQUFLLEVBQS9DLEVBQ0E7QUFDSSxjQUFJQyxRQUFRLEdBQUc5Qix3QkFBd0IsQ0FBQzJCLFNBQXpCLENBQW1DRSxLQUFuQyxDQUFmOztBQUNBLGNBQUlFLGFBQWEsR0FBRzVDLElBQUksQ0FBQzZDLDRCQUFMLENBQWtDLG9CQUFrQkYsUUFBUSxDQUFDRywwQkFBM0IsR0FBc0QsSUFBdEQsR0FBMkRILFFBQVEsQ0FBQ0ksVUFBcEUsR0FBK0UsV0FBakgsQ0FBcEI7O0FBQ0EvQyxjQUFJLENBQUN1QixlQUFMLENBQXFCeUIsV0FBckIsQ0FBaUNKLGFBQWpDO0FBQ0g7O0FBRUQsWUFBR0wsYUFBYSxJQUFJLENBQXBCLEVBQXVCO0FBQ25CdkMsY0FBSSxDQUFDd0Isc0JBQUwsQ0FBNEJ5QixTQUE1QixDQUFzQ0MsR0FBdEMsQ0FBMENsRCxJQUFJLENBQUMwQixZQUEvQztBQUNILFNBRkQsTUFFTztBQUNIMUIsY0FBSSxDQUFDd0Isc0JBQUwsQ0FBNEJ5QixTQUE1QixDQUFzQ0UsTUFBdEMsQ0FBNkNuRCxJQUFJLENBQUMwQixZQUFsRDtBQUNIO0FBQ0osT0FqQkw7QUFtQkk7QUFDQSxnQkFBUzBCLGFBQVQsRUFBd0I7QUFDcEJyQyxlQUFPLENBQUNDLEtBQVIsQ0FBY29DLGFBQWQ7QUFDSCxPQXRCTDtBQXdCSDtBQUVEOzs7Ozs7MkNBSUE7QUFDSSxhQUFNLEtBQUs3QixlQUFMLENBQXFCOEIsUUFBckIsQ0FBOEJaLE1BQXBDLEVBQTRDO0FBQ3hDLGFBQUtsQixlQUFMLENBQXFCK0IsV0FBckIsQ0FBaUMsS0FBSy9CLGVBQUwsQ0FBcUJnQyxVQUF0RDtBQUNIO0FBQ0o7QUFFRDs7Ozs7Ozs7aURBSzZCQyxJLEVBQzdCO0FBQ0ksVUFBSTlELFFBQVEsR0FBRyxLQUFLaUMsVUFBTCxDQUFnQjhCLGVBQWhCLENBQWdDRCxJQUFoQyxFQUFzQyxXQUF0QyxDQUFmOztBQUNBLGFBQU85RCxRQUFRLENBQUNnRSxJQUFULENBQWNILFVBQXJCO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzVHTDtBQUFBO0FBQUE7QUFFQUksd0RBQVEsQ0FBQ2pFLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLGNBQTFCLENBQUQsRUFBNEMsQ0FDaEQ7QUFEZ0QsQ0FBNUMsQ0FBUixDOzs7Ozs7Ozs7OztBQ0ZBOzs7Ozs7O0FBUUEsSUFBTUMsZ0JBQWdCLEdBQUc7QUFFckJDLGVBQWEsRUFBRSxFQUZNOztBQUlyQjs7O0FBR0FDLE9BQUssRUFBRSxpQkFDUDtBQUVJLFFBQU1DLGtCQUFrQixHQUFHdEUsUUFBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsdUJBQTFCLENBQTNCOztBQUVBLFFBQUdLLEtBQUssQ0FBQ0Qsa0JBQUQsQ0FBUixFQUE2QjtBQUV6QixVQUFNRSwwQkFBMEIsR0FBR0Ysa0JBQWtCLENBQUN2QixNQUF0RDs7QUFDQSxXQUFJLElBQUkwQixDQUFDLEdBQUcsQ0FBWixFQUFlQSxDQUFDLEdBQUdELDBCQUFuQixFQUErQ0MsQ0FBQyxFQUFoRCxFQUFtRDtBQUUvQyxZQUFNQyxZQUFZLEdBQUdKLGtCQUFrQixDQUFDRyxDQUFELENBQXZDOztBQUNBTix3QkFBZ0IsQ0FBQ1EsWUFBakIsQ0FBOEJELFlBQTlCO0FBQ0g7QUFDSjtBQUNKLEdBckJvQjs7QUF1QnJCOzs7Ozs7O0FBT0FDLGNBQVksRUFBRSxzQkFBVUMsWUFBVixFQUF3QjtBQUVsQztBQUNBLFFBQU1DLFlBQVksR0FBR0QsWUFBWSxDQUFDaEQsYUFBYixDQUEyQixtQkFBM0IsQ0FBckIsQ0FIa0MsQ0FLbEM7O0FBQ0EsUUFBRzJDLEtBQUssQ0FBQ00sWUFBRCxDQUFSLEVBQXVCO0FBRW5CQSxrQkFBWSxDQUFDckMsZ0JBQWIsQ0FBOEIsT0FBOUIsRUFBdUMsWUFBWTtBQUMvQzJCLHdCQUFnQixDQUFDVyxZQUFqQixDQUE4QkYsWUFBOUI7QUFDSCxPQUZEO0FBR0gsS0FMRCxNQU1JO0FBQ0F2RCxhQUFPLENBQUMwRCxHQUFSLENBQVksMkNBQVo7QUFDSDtBQUNKLEdBN0NvQjs7QUErQ3JCOzs7Ozs7O0FBT0FELGNBdERxQix3QkFzRFJFLGdCQXREUSxFQXNEUztBQUUxQjtBQUNBLFFBQU1DLFNBQVMsR0FBR0QsZ0JBQWdCLENBQUNkLGdCQUFqQixDQUFrQyx5QkFBbEMsQ0FBbEI7O0FBRUEsUUFBR0ssS0FBSyxDQUFDVSxTQUFELENBQVIsRUFBb0I7QUFFaEI7QUFDQSxVQUFJQyxZQUFZLEdBQUcsRUFBbkI7QUFDQSxVQUFJQyxvQkFBb0IsR0FBRyxDQUEzQjtBQUVBLFVBQU1DLGFBQWEsR0FBR0gsU0FBUyxDQUFDbEMsTUFBaEM7O0FBQ0EsV0FBSSxJQUFJMEIsQ0FBQyxHQUFHLENBQVosRUFBZUEsQ0FBQyxHQUFHVyxhQUFuQixFQUFrQ1gsQ0FBQyxFQUFuQyxFQUFzQztBQUVsQztBQUNBLFlBQU1ZLE9BQU8sR0FBR0osU0FBUyxDQUFDUixDQUFELENBQXpCLENBSGtDLENBS2xDOztBQUNBLFlBQU1hLFdBQVcsR0FBR0QsT0FBTyxDQUFDRSxZQUFSLENBQXFCLE1BQXJCLENBQXBCLENBTmtDLENBUWxDOztBQUNBLFlBQUlwQixnQkFBZ0IsQ0FBQ3FCLGdCQUFqQixDQUFrQ0YsV0FBbEMsQ0FBSixFQUFvRDtBQUVwREosb0JBQVksQ0FBRUksV0FBRixDQUFaLEdBQThCbkIsZ0JBQWdCLENBQUNzQixlQUFqQixDQUFpQ0osT0FBakMsQ0FBOUI7QUFDQUYsNEJBQW9CO0FBQ3ZCLE9BcEJlLENBc0JoQjs7O0FBQ0EsVUFBR0Esb0JBQW9CLEtBQUssQ0FBNUIsRUFBK0IsT0F2QmYsQ0F5QmhCOztBQUNBaEIsc0JBQWdCLENBQUN1QixXQUFqQixDQUE2QlIsWUFBN0IsRUFBMkNGLGdCQUEzQztBQUNILEtBM0JELE1BNEJJO0FBQ0EzRCxhQUFPLENBQUMwRCxHQUFSLENBQVksMENBQVo7QUFDSDtBQUNKLEdBMUZvQjs7QUE0RnJCOzs7Ozs7O0FBT0FTLGtCQUFnQixFQUFFLDBCQUFTRixXQUFULEVBQXFCO0FBQ25DLFFBQUduQixnQkFBZ0IsQ0FBQ0MsYUFBakIsQ0FBK0J1QixPQUEvQixDQUF1Q0wsV0FBdkMsTUFBd0QsQ0FBQyxDQUE1RCxFQUE4RDtBQUMxRCxhQUFPLElBQVA7QUFDSDs7QUFDRCxXQUFPLEtBQVA7QUFDSCxHQXhHb0I7O0FBMEdyQjs7Ozs7Ozs7O0FBU0FHLGlCQUFlLEVBQUUseUJBQVNKLE9BQVQsRUFDakI7QUFFSSxRQUFNTyxXQUFXLEdBQUdQLE9BQU8sQ0FBQ1EsUUFBNUI7O0FBRUEsUUFBR1IsT0FBTyxDQUFDUyxJQUFSLEtBQWlCLE9BQXBCLEVBQTZCO0FBQ3pCLGFBQU85RixRQUFRLENBQUM0QixhQUFULENBQXVCLGlCQUFpQnlELE9BQU8sQ0FBQ1UsSUFBekIsR0FBZ0MsWUFBdkQsRUFBcUV0RCxLQUE1RTtBQUNIOztBQUVELFlBQVFtRCxXQUFSO0FBQ0k7QUFDSSxlQUFPUCxPQUFPLENBQUM1QyxLQUFmO0FBRlI7QUFJSCxHQWhJb0I7O0FBa0lyQjs7Ozs7Ozs7OztBQVVBaUQsYUFBVyxFQUFFLHFCQUFTTSxLQUFULEVBQWdCaEIsZ0JBQWhCLEVBQ2I7QUFDSTtBQUNBZ0IsU0FBSyxHQUFHN0IsZ0JBQWdCLENBQUM4QixlQUFqQixDQUFpQ0QsS0FBakMsQ0FBUixDQUZKLENBSUk7O0FBQ0EsUUFBTUUsSUFBSSxHQUFHLGtCQUFiOztBQUVBLFFBQUk7QUFDQXhGLFVBQUksQ0FBQ0MsSUFBTCxDQUFVdUYsSUFBVixFQUFnQkYsS0FBaEIsRUFBdUIsVUFBVUcsV0FBVixFQUF1QjtBQUUxQyxZQUFNbkYsUUFBUSxHQUFHb0YsSUFBSSxDQUFDQyxLQUFMLENBQVdGLFdBQVcsQ0FBQ25GLFFBQXZCLENBQWpCOztBQUVBLGdCQUFRbUYsV0FBVyxDQUFDRyxNQUFwQjtBQUNJLGVBQUssR0FBTDtBQUNJLG1CQUFPbkMsZ0JBQWdCLENBQUNvQyxrQkFBakIsQ0FBb0N2RixRQUFRLENBQUN3RixXQUE3QyxDQUFQOztBQUNKLGVBQUssR0FBTDtBQUNJLG1CQUFPckMsZ0JBQWdCLENBQUNzQyxzQkFBakIsQ0FBd0N6RixRQUFRLENBQUMwRixNQUFqRCxFQUF5RDFCLGdCQUF6RCxDQUFQOztBQUNKO0FBQ0k7QUFOUjs7QUFTQSxlQUFPYixnQkFBZ0IsQ0FBQ3dDLG9CQUFqQixDQUFzQzNCLGdCQUF0QyxDQUFQO0FBQ0gsT0FkRDtBQWVILEtBaEJELENBaUJBLE9BQU80QixDQUFQLEVBQVU7QUFDTixhQUFPekMsZ0JBQWdCLENBQUN3QyxvQkFBakIsQ0FBc0MzQixnQkFBdEMsQ0FBUDtBQUNIO0FBQ0osR0F4S29COztBQTBLckI7Ozs7Ozs7O0FBUUFpQixpQkFBZSxFQUFFLHlCQUFTRCxLQUFULEVBQWU7QUFDNUJBLFNBQUssQ0FBQ2EsT0FBTixHQUFnQixPQUFoQjtBQUNBLFdBQU9iLEtBQVA7QUFDSCxHQXJMb0I7O0FBdUxyQjs7Ozs7Ozs7QUFRQVMsd0JBQXNCLEVBQUUsZ0NBQVNDLE1BQVQsRUFBaUIxQixnQkFBakIsRUFBa0M7QUFFdEQ7QUFDQSxRQUFNOEIsWUFBWSxHQUFHOUIsZ0JBQWdCLENBQUNwRCxhQUFqQixDQUErQixnQkFBL0IsQ0FBckIsQ0FIc0QsQ0FLdEQ7O0FBQ0EsUUFBRzJDLEtBQUssQ0FBQ3VDLFlBQUQsQ0FBUixFQUF3QkEsWUFBWSxDQUFDQyxTQUFiLEdBQXlCLEVBQXpCLENBTjhCLENBUXREOztBQUNBNUMsb0JBQWdCLENBQUM2QywyQkFBakIsQ0FBNkNoQyxnQkFBN0M7O0FBRUFpQyxVQUFNLENBQUNDLElBQVAsQ0FBWVIsTUFBWixFQUFvQlMsT0FBcEIsQ0FBNEIsVUFBUzlCLE9BQVQsRUFBa0I7QUFFMUMsVUFBSStCLE1BQU0sR0FBRyxJQUFiO0FBQ0EsVUFBSUMsbUJBQW1CLEdBQUcsSUFBMUIsQ0FIMEMsQ0FLMUM7O0FBQ0EsVUFBR2hDLE9BQU8sS0FBSyxRQUFaLElBQXdCQSxPQUFPLEtBQUssYUFBdkMsRUFBc0Q7QUFFbEQ7QUFDQSxZQUFNaUMsV0FBVyxHQUFHdEMsZ0JBQWdCLENBQUNwRCxhQUFqQixDQUErQixNQUFNeUQsT0FBckMsQ0FBcEIsQ0FIa0QsQ0FLbEQ7O0FBQ0ErQixjQUFNLEdBQUdqRCxnQkFBZ0IsQ0FBQ29ELGtCQUFqQixDQUFvQ0QsV0FBcEMsQ0FBVCxDQU5rRCxDQVFsRDs7QUFDQSxZQUFHL0MsS0FBSyxDQUFDNkMsTUFBRCxDQUFSLEVBQWtCQyxtQkFBbUIsR0FBR0QsTUFBTSxDQUFDeEYsYUFBUCxDQUFxQix3QkFBckIsQ0FBdEIsQ0FUZ0MsQ0FXbEQ7O0FBQ0EsWUFBRzJDLEtBQUssQ0FBQzhDLG1CQUFELENBQVIsRUFBK0JBLG1CQUFtQixDQUFDTixTQUFwQixHQUFnQyxFQUFoQztBQUVsQyxPQXBCeUMsQ0FzQjFDOzs7QUFDQSxVQUFNUyxlQUFlLEdBQUdkLE1BQU0sQ0FBQ3JCLE9BQUQsQ0FBOUIsQ0F2QjBDLENBeUIxQzs7QUFDQSxVQUFNb0MscUJBQXFCLEdBQUdELGVBQWUsQ0FBQ3pFLE1BQTlDOztBQUNBLFdBQUksSUFBSTBCLENBQUMsR0FBRyxDQUFaLEVBQWVBLENBQUMsR0FBR2dELHFCQUFuQixFQUEwQ2hELENBQUMsRUFBM0MsRUFBOEM7QUFDMUMsWUFBTWlELG1CQUFtQixHQUFHRixlQUFlLENBQUMvQyxDQUFELENBQTNDLENBRDBDLENBRzFDOztBQUNBLFlBQUdZLE9BQU8sS0FBSyxRQUFaLElBQXdCQSxPQUFPLEtBQUssYUFBdkMsRUFBc0Q7QUFFbEQ7QUFDQSxjQUFHZCxLQUFLLENBQUM2QyxNQUFELENBQVIsRUFBa0JBLE1BQU0sQ0FBQzdELFNBQVAsQ0FBaUJDLEdBQWpCLENBQXFCLFdBQXJCLEVBSGdDLENBS2xEOztBQUNBLGNBQUdlLEtBQUssQ0FBQzhDLG1CQUFELENBQVIsRUFDQTtBQUNJLGdCQUFJTSxtQkFBbUIsR0FBR04sbUJBQW1CLENBQUNOLFNBQTlDO0FBQ0FZLCtCQUFtQixJQUFJLFdBQVdDLHFCQUFxQixDQUFDRixtQkFBRCxDQUFoQyxHQUF3RCxTQUEvRTtBQUNBTCwrQkFBbUIsQ0FBQ04sU0FBcEIsR0FBZ0NZLG1CQUFoQztBQUNIO0FBQ0osU0FoQnlDLENBa0IxQzs7O0FBQ0EsWUFBR3BELEtBQUssQ0FBQ3VDLFlBQUQsQ0FBUixFQUF1QjtBQUNuQixjQUFJYSxvQkFBbUIsR0FBR2IsWUFBWSxDQUFDQyxTQUF2QztBQUNBWSw4QkFBbUIsSUFBSSxTQUFTQyxxQkFBcUIsQ0FBQ0YsbUJBQUQsQ0FBOUIsR0FBc0QsT0FBN0U7QUFDQVosc0JBQVksQ0FBQ0MsU0FBYixHQUF5Qlksb0JBQXpCO0FBQ0g7QUFDSjtBQUNKLEtBcEREO0FBc0RBLFFBQU1FLEdBQUcsR0FBR0MsVUFBVSxDQUFDOUMsZ0JBQUQsQ0FBVixDQUE2QjZDLEdBQTdCLEdBQW1DLEdBQS9DO0FBQ0FFLFVBQU0sQ0FBQ0MsUUFBUCxDQUFnQixDQUFoQixFQUFtQkgsR0FBbkI7QUFDSCxHQWxRb0I7O0FBb1FyQjs7Ozs7O0FBTUFiLDZCQTFRcUIsdUNBMFFPaEMsZ0JBMVFQLEVBMFF5QjtBQUUxQyxRQUFNaUQsYUFBYSxHQUFHakQsZ0JBQWdCLENBQUNkLGdCQUFqQixDQUFrQyxZQUFsQyxDQUF0QjtBQUNBLFFBQU1nRSxtQkFBbUIsR0FBR0QsYUFBYSxDQUFDbEYsTUFBMUM7O0FBRUEsU0FBSSxJQUFJMEIsQ0FBQyxHQUFHLENBQVosRUFBZUEsQ0FBQyxHQUFHeUQsbUJBQW5CLEVBQXdDekQsQ0FBQyxFQUF6QyxFQUE0QztBQUV4QyxVQUFNMEQsWUFBWSxHQUFHRixhQUFhLENBQUN4RCxDQUFELENBQWxDO0FBQ0EwRCxrQkFBWSxDQUFDNUUsU0FBYixDQUF1QkUsTUFBdkIsQ0FBOEIsV0FBOUI7QUFFQSxVQUFNMkUsbUJBQW1CLEdBQUdELFlBQVksQ0FBQ3ZHLGFBQWIsQ0FBMkIsd0JBQTNCLENBQTVCO0FBQ0EsVUFBRzJDLEtBQUssQ0FBQzZELG1CQUFELENBQVIsRUFBK0JBLG1CQUFtQixDQUFDckIsU0FBcEIsR0FBZ0MsRUFBaEM7QUFDbEM7QUFDSixHQXZSb0I7O0FBeVJyQjs7Ozs7OztBQU9BUSxvQkFBa0IsRUFBRSw0QkFBU2xDLE9BQVQsRUFBaUI7QUFFakM7QUFDQSxRQUFJLENBQUNkLEtBQUssQ0FBQ2MsT0FBRCxDQUFWLEVBQXFCLE9BQU8sSUFBUCxDQUhZLENBS2pDOztBQUNBZ0QsZ0JBQVksR0FBR2hELE9BQWY7QUFDQWlELGVBQVcsR0FBRyxDQUFkLENBUGlDLENBU2pDOztBQUNBLE9BQUc7QUFDQ0EsaUJBQVc7QUFDWEQsa0JBQVksR0FBR0EsWUFBWSxDQUFDRSxVQUE1QjtBQUNBLFVBQUdGLFlBQVksQ0FBQzlFLFNBQWIsQ0FBdUJpRixRQUF2QixDQUFnQyxpQkFBaEMsQ0FBSCxFQUF1RCxPQUFPSCxZQUFQO0FBQzFELEtBSkQsUUFJU0EsWUFBWSxDQUFDM0csT0FBYixLQUF5QixNQUF6QixJQUFtQzRHLFdBQVcsSUFBSSxFQUozRDs7QUFNQSxXQUFPLElBQVA7QUFDSCxHQWpUb0I7O0FBbVRyQjs7Ozs7O0FBTUEvQixvQkFBa0IsRUFBRSw0QkFBVWtDLFFBQVYsRUFBb0I7QUFDcENWLFVBQU0sQ0FBQ1csUUFBUCxHQUFrQkQsUUFBbEI7QUFDSCxHQTNUb0I7O0FBNlRyQjs7Ozs7O0FBTUE5QixzQkFBb0IsRUFBRSw4QkFBVTNCLGdCQUFWLEVBQTRCO0FBQzlDM0QsV0FBTyxDQUFDMEQsR0FBUixDQUFZQyxnQkFBWjtBQUNBM0QsV0FBTyxDQUFDMEQsR0FBUixDQUFZLGdDQUFaO0FBQ0g7QUF0VW9CLENBQXpCO0FBeVVBWixnQkFBZ0IsQ0FBQ0UsS0FBakIsRzs7Ozs7Ozs7Ozs7QUNqVkEsSUFBTXNFLHFCQUFxQixHQUFHO0FBRTFCQyxnQkFBYyxFQUFFLElBRlU7QUFHMUJDLHVCQUFxQixFQUFFLElBSEc7QUFJMUJDLHFDQUFtQyxFQUFFLENBQUMsUUFBRCxFQUFXLE9BQVgsQ0FKWDtBQU0xQmhKLE1BQUksRUFBRyxnQkFDUDtBQUNJO0FBQ0E2SSx5QkFBcUIsQ0FBQ0MsY0FBdEIsR0FBdUM1SSxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixxQkFBMUIsQ0FBdkM7QUFDQXlFLHlCQUFxQixDQUFDRSxxQkFBdEIsR0FBOEM3SSxRQUFRLENBQUM0QixhQUFULENBQXVCLDhCQUF2QixDQUE5QztBQUVBLFFBQU1tSCxvQkFBb0IsR0FBR0oscUJBQXFCLENBQUNDLGNBQXRCLENBQXFDN0YsTUFBbEU7QUFDQSxRQUFHZ0csb0JBQW9CLElBQUksQ0FBeEIsSUFBNkIsQ0FBQ3hFLEtBQUssQ0FBQ29FLHFCQUFxQixDQUFDRSxxQkFBdkIsQ0FBdEMsRUFBcUY7O0FBRXJGLFNBQUksSUFBSXBFLENBQUMsR0FBRyxDQUFaLEVBQWVBLENBQUMsR0FBR3NFLG9CQUFuQixFQUF5Q3RFLENBQUMsRUFBMUMsRUFBNkM7QUFFekMsVUFBTXVFLGFBQWEsR0FBR0wscUJBQXFCLENBQUNDLGNBQXRCLENBQXFDbkUsQ0FBckMsQ0FBdEI7QUFDQXVFLG1CQUFhLENBQUN4RyxnQkFBZCxDQUErQixRQUEvQixFQUF5Q21HLHFCQUFxQixDQUFDTSxjQUEvRDtBQUNIO0FBQ0osR0FwQnlCO0FBc0IxQkEsZ0JBQWMsRUFBRSwwQkFBWTtBQUV4QixRQUFNQyxZQUFZLEdBQUdsSixRQUFRLENBQUM0QixhQUFULENBQXVCLDZCQUF2QixDQUFyQixDQUZ3QixDQUl4Qjs7QUFDQSxRQUFHK0cscUJBQXFCLENBQUNHLG1DQUF0QixDQUEwRG5ELE9BQTFELENBQWtFdUQsWUFBWSxDQUFDekcsS0FBL0UsTUFBMEYsQ0FBQyxDQUE5RixFQUFpRztBQUM3RmtHLDJCQUFxQixDQUFDRSxxQkFBdEIsQ0FBNEN0RixTQUE1QyxDQUFzREUsTUFBdEQsQ0FBNkQsV0FBN0Q7QUFDSCxLQUZELE1BR0s7QUFDRGtGLDJCQUFxQixDQUFDRSxxQkFBdEIsQ0FBNEN0RixTQUE1QyxDQUFzREMsR0FBdEQsQ0FBMEQsV0FBMUQ7QUFDSDtBQUNKO0FBakN5QixDQUE5QjtBQXFDQW1GLHFCQUFxQixDQUFDN0ksSUFBdEIsRzs7Ozs7Ozs7Ozs7QUNyQ0E7Ozs7QUFLQSxJQUFNcUosYUFBYSxHQUFHO0FBRWxCQyxXQUFTLEVBQUcsSUFGTTtBQUdsQkMsZUFBYSxFQUFHLElBSEU7QUFJbEJDLGVBQWEsRUFBRyxJQUpFO0FBTWxCQyxjQUFZLEVBQUcsSUFORztBQVFsQkMsZ0NBQThCLEVBQUcsR0FSZjtBQVNsQkMsZ0JBQWMsRUFBRyxLQVRDO0FBV2xCO0FBQ0EzSixNQUFJLEVBQUcsZ0JBQ1A7QUFDSTtBQUNBcUosaUJBQWEsQ0FBQ0csYUFBZCxHQUE4QnRKLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUIsb0NBQXZCLENBQTlCLENBRkosQ0FJSTs7QUFDQXVILGlCQUFhLENBQUNDLFNBQWQsR0FBMEJwSixRQUFRLENBQUM0QixhQUFULENBQXVCLGdCQUF2QixDQUExQixDQUxKLENBT0k7O0FBQ0EsUUFBRzJDLEtBQUssQ0FBQzRFLGFBQWEsQ0FBQ0MsU0FBZixDQUFSLEVBQWtDO0FBQzlCRCxtQkFBYSxDQUFDTyxhQUFkO0FBQ0gsS0FGRCxNQUdJO0FBQ0E7QUFDQVAsbUJBQWEsQ0FBQ0UsYUFBZCxHQUE4QnJKLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUIsb0JBQXZCLENBQTlCLENBRkEsQ0FJQTs7QUFDQSxVQUFHMkMsS0FBSyxDQUFDNEUsYUFBYSxDQUFDRSxhQUFmLENBQVIsRUFBc0M7QUFDbENGLHFCQUFhLENBQUNRLGlCQUFkO0FBQ0g7QUFDSixLQW5CTCxDQXFCSTs7O0FBQ0EsUUFBR3BGLEtBQUssQ0FBQzRFLGFBQWEsQ0FBQ0csYUFBZixDQUFSLEVBQXNDO0FBQ2xDSCxtQkFBYSxDQUFDUyxzQkFBZDtBQUNILEtBeEJMLENBMEJJOzs7QUFDQVQsaUJBQWEsQ0FBQ0ksWUFBZCxHQUE2QnZKLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUIsbUJBQXZCLENBQTdCLENBM0JKLENBNEJJOztBQUNBLFFBQUcyQyxLQUFLLENBQUM0RSxhQUFhLENBQUNJLFlBQWYsQ0FBUixFQUFxQztBQUNqQ0osbUJBQWEsQ0FBQ1UsZ0JBQWQ7QUFDSDtBQUNKLEdBN0NpQjtBQStDbEI7QUFDQUgsZUFBYSxFQUFFLHlCQUFVO0FBQ3JCLFFBQU1JLFdBQVcsR0FBR1gsYUFBYSxDQUFDQyxTQUFkLENBQXdCeEgsYUFBeEIsQ0FBc0Msd0JBQXRDLENBQXBCOztBQUNBLFFBQUcyQyxLQUFLLENBQUN1RixXQUFELENBQVIsRUFBc0I7QUFDbEJBLGlCQUFXLENBQUN0SCxnQkFBWixDQUE2QixPQUE3QixFQUFzQzJHLGFBQWEsQ0FBQ1ksa0JBQXBEO0FBQ0g7QUFDSixHQXJEaUI7QUF1RGxCO0FBQ0FKLG1CQUFpQixFQUFFLDZCQUFVO0FBRXpCO0FBQ0EsUUFBTUssd0JBQXdCLEdBQUdiLGFBQWEsQ0FBQ0csYUFBZCxDQUE0QjFILGFBQTVCLENBQTBDLDZCQUExQyxDQUFqQzs7QUFDQSxRQUFHMkMsS0FBSyxDQUFDeUYsd0JBQUQsQ0FBUixFQUFtQztBQUMvQkEsOEJBQXdCLENBQUN4SCxnQkFBekIsQ0FBMEMsT0FBMUMsRUFBbUQyRyxhQUFhLENBQUNjLGtCQUFqRTtBQUNILEtBTndCLENBUXpCOzs7QUFDQSxRQUFNQyxtQkFBbUIsR0FBR2YsYUFBYSxDQUFDRyxhQUFkLENBQTRCMUgsYUFBNUIsQ0FBMEMsaUNBQTFDLENBQTVCOztBQUNBLFFBQUcyQyxLQUFLLENBQUMyRixtQkFBRCxDQUFSLEVBQThCO0FBRTFCLFVBQUdBLG1CQUFtQixDQUFDQyxPQUFwQixLQUFnQyxJQUFuQyxFQUF5QztBQUNyQ2hCLHFCQUFhLENBQUNNLGNBQWQsR0FBK0IsSUFBL0I7QUFDSDs7QUFFRFMseUJBQW1CLENBQUMxSCxnQkFBcEIsQ0FBcUMsUUFBckMsRUFBK0MyRyxhQUFhLENBQUNpQixxQkFBN0Q7QUFDSCxLQWpCd0IsQ0FtQnpCOzs7QUFDQSxRQUFNQyxZQUFZLEdBQUdsQixhQUFhLENBQUNHLGFBQWQsQ0FBNEIxSCxhQUE1QixDQUEwQyxvQkFBMUMsQ0FBckI7O0FBQ0EsUUFBRzJDLEtBQUssQ0FBQzhGLFlBQUQsQ0FBUixFQUF1QjtBQUNuQkEsa0JBQVksQ0FBQzdILGdCQUFiLENBQThCLE9BQTlCLEVBQXVDMkcsYUFBYSxDQUFDbUIsaUJBQXJEO0FBQ0g7QUFFSixHQWpGaUI7QUFtRmxCO0FBQ0FULGtCQUFnQixFQUFFLDRCQUFVO0FBRXhCO0FBQ0EsUUFBTUssbUJBQW1CLEdBQUdmLGFBQWEsQ0FBQ0ksWUFBZCxDQUEyQjNILGFBQTNCLENBQXlDLGlDQUF6QyxDQUE1Qjs7QUFDQSxRQUFHMkMsS0FBSyxDQUFDMkYsbUJBQUQsQ0FBUixFQUE4QjtBQUUxQjtBQUNBO0FBQ0EsVUFBR0EsbUJBQW1CLENBQUNDLE9BQXBCLEtBQWdDLElBQW5DLEVBQXlDO0FBQ3JDaEIscUJBQWEsQ0FBQ00sY0FBZCxHQUErQixJQUEvQjtBQUNILE9BRkQsTUFHSTtBQUNBTixxQkFBYSxDQUFDTSxjQUFkLEdBQStCLEtBQS9CO0FBQ0g7O0FBRURTLHlCQUFtQixDQUFDMUgsZ0JBQXBCLENBQXFDLFFBQXJDLEVBQStDMkcsYUFBYSxDQUFDaUIscUJBQTdEO0FBQ0gsS0FoQnVCLENBa0J4Qjs7O0FBQ0EsUUFBTUcsVUFBVSxHQUFHcEIsYUFBYSxDQUFDSSxZQUFkLENBQTJCM0gsYUFBM0IsQ0FBeUMsMEJBQXpDLENBQW5COztBQUNBLFFBQUcyQyxLQUFLLENBQUNnRyxVQUFELENBQVIsRUFBcUI7QUFDakJBLGdCQUFVLENBQUMvSCxnQkFBWCxDQUE0QixPQUE1QixFQUFxQyxZQUFVO0FBQzNDMkcscUJBQWEsQ0FBQ0ssOEJBQWQsR0FBK0MsQ0FBL0MsQ0FEMkMsQ0FDTzs7QUFDbERMLHFCQUFhLENBQUNtQixpQkFBZDtBQUNILE9BSEQ7QUFJSDtBQUVKLEdBL0dpQjtBQWlIbEJWLHdCQUFzQixFQUFFLGtDQUFVO0FBQzlCLFFBQUlZLE1BQU0sQ0FBQ0MsR0FBUCxDQUFXLGVBQVgsQ0FBSixFQUFpQztBQUM3QnRCLG1CQUFhLENBQUNHLGFBQWQsQ0FBNEIvRixTQUE1QixDQUFzQ0MsR0FBdEMsQ0FBMEMsYUFBMUM7QUFDSCxLQUZELE1BR0s7QUFDRDJGLG1CQUFhLENBQUNHLGFBQWQsQ0FBNEIvRixTQUE1QixDQUFzQ0UsTUFBdEMsQ0FBNkMsYUFBN0M7QUFDQXpELGNBQVEsQ0FBQ2dFLElBQVQsQ0FBY1QsU0FBZCxDQUF3QkMsR0FBeEIsQ0FBNEIsdUJBQTVCO0FBQ0g7QUFDSixHQXpIaUI7QUEySGxCdUcsb0JBQWtCLEVBQUUsOEJBQVc7QUFDM0JTLFVBQU0sQ0FBQ0UsR0FBUCxDQUFXLGVBQVgsRUFBNEIsSUFBNUIsRUFBa0MsRUFBbEM7QUFDQXZCLGlCQUFhLENBQUNHLGFBQWQsQ0FBNEIvRixTQUE1QixDQUFzQ0MsR0FBdEMsQ0FBMEMsc0JBQTFDO0FBQ0F4RCxZQUFRLENBQUNnRSxJQUFULENBQWNULFNBQWQsQ0FBd0JFLE1BQXhCLENBQStCLHVCQUEvQjtBQUNILEdBL0hpQjtBQWlJbEJ3RyxvQkFBa0IsRUFBRSw4QkFBVztBQUMzQmQsaUJBQWEsQ0FBQ0UsYUFBZCxDQUE0QnpILGFBQTVCLENBQTBDLHFCQUExQyxFQUFpRTJCLFNBQWpFLENBQTJFRSxNQUEzRSxDQUFrRixXQUFsRjtBQUNBMEYsaUJBQWEsQ0FBQ0UsYUFBZCxDQUE0QnpILGFBQTVCLENBQTBDLGlCQUExQyxFQUE2RDJCLFNBQTdELENBQXVFQyxHQUF2RSxDQUEyRSxXQUEzRTtBQUNILEdBcElpQjtBQXNJbEI0Ryx1QkFBcUIsRUFBRSxpQ0FBVTtBQUM3QixRQUFHakIsYUFBYSxDQUFDTSxjQUFqQixFQUFnQztBQUM1Qk4sbUJBQWEsQ0FBQ00sY0FBZCxHQUErQixLQUEvQjtBQUNILEtBRkQsTUFHSTtBQUNBTixtQkFBYSxDQUFDTSxjQUFkLEdBQStCLElBQS9CO0FBQ0g7QUFDSixHQTdJaUI7QUErSWxCYSxtQkFBaUIsRUFBRSw2QkFBWTtBQUUzQjtBQUNBLFFBQUduQixhQUFhLENBQUNNLGNBQWpCLEVBQWdDO0FBQzVCZSxZQUFNLENBQUNFLEdBQVAsQ0FBVyx3QkFBWCxFQUFxQyxNQUFyQyxFQUE2QyxFQUE3QztBQUNILEtBRkQsTUFHSTtBQUNBLFVBQUdGLE1BQU0sQ0FBQ0MsR0FBUCxDQUFXLHdCQUFYLENBQUgsRUFBd0M7QUFDcENELGNBQU0sQ0FBQ0csS0FBUCxDQUFhLHdCQUFiO0FBQ0g7QUFDSjs7QUFFRHhCLGlCQUFhLENBQUNZLGtCQUFkLEdBWjJCLENBYzNCOztBQUNBYSxjQUFVLENBQUMsWUFBVTtBQUNqQmxDLGNBQVEsQ0FBQ21DLE1BQVQ7QUFDSCxLQUZTLEVBRVAxQixhQUFhLENBQUNLLDhCQUZQLENBQVY7QUFHSDtBQWpLaUIsQ0FBdEI7QUFxS0FMLGFBQWEsQ0FBQ3JKLElBQWQsRzs7Ozs7Ozs7Ozs7QUMxS0E7Ozs7OztBQU9BLElBQU1nTCx5QkFBeUIsR0FBRztBQUU5QkMsd0JBQXNCLEVBQUUsSUFGTTtBQUc5QkMsb0JBQWtCLEVBQUUsSUFIVTtBQUk5QkMsWUFBVSxFQUFFLENBSmtCO0FBSzlCQyx3QkFBc0IsRUFBRSxJQUxNO0FBTTlCQywrQkFBNkIsRUFBRSxJQU5EO0FBTzlCQyxtQkFBaUIsRUFBRSxJQVBXO0FBUTlCQywwQkFBd0IsRUFBRSxJQVJJO0FBVTlCdkwsTUFBSSxFQUFFLGdCQUFZO0FBRWRnTCw2QkFBeUIsQ0FBQ0Msc0JBQTFCLEdBQW1EL0ssUUFBUSxDQUFDNEIsYUFBVCxDQUF1QiwwQkFBdkIsQ0FBbkQsQ0FGYyxDQUtkOztBQUNBLFFBQUkyQyxLQUFLLENBQUN1Ryx5QkFBeUIsQ0FBQ0Msc0JBQTNCLENBQVQsRUFBNkQ7QUFFekRELCtCQUF5QixDQUFDRSxrQkFBMUIsR0FBK0NGLHlCQUF5QixDQUFDQyxzQkFBMUIsQ0FBaUQ3RyxnQkFBakQsQ0FBa0UseUJBQWxFLENBQS9DOztBQUVBLFVBQUk0Ryx5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDakksTUFBN0MsSUFBdUQsQ0FBM0QsRUFBOEQ7QUFFMUQrSCxpQ0FBeUIsQ0FBQ1EsU0FBMUI7QUFDQVIsaUNBQXlCLENBQUNTLGVBQTFCO0FBQ0FULGlDQUF5QixDQUFDVSxhQUExQjtBQUVILE9BTkQsTUFNTztBQUNIbkssZUFBTyxDQUFDMEQsR0FBUixDQUFZLDJEQUFaO0FBQ0g7QUFFSjtBQUNKLEdBL0I2QjtBQWlDOUJ1RyxXQUFTLEVBQUUscUJBQVk7QUFFbkIsUUFBTUcsSUFBSSxHQUFHWCx5QkFBeUIsQ0FBQ0Msc0JBQTFCLENBQWlEbkosYUFBakQsQ0FBK0Qsd0JBQS9ELENBQWI7QUFDQSxRQUFNOEosUUFBUSxHQUFHWix5QkFBeUIsQ0FBQ0Msc0JBQTFCLENBQWlEbkosYUFBakQsQ0FBK0QsNEJBQS9ELENBQWpCO0FBRUE2SixRQUFJLENBQUNqSixnQkFBTCxDQUFzQixPQUF0QixFQUErQixZQUFZO0FBQ3ZDc0ksK0JBQXlCLENBQUNhLFFBQTFCO0FBQ0FiLCtCQUF5QixDQUFDYyxZQUExQjtBQUNBQyxrQkFBWSxDQUFDZix5QkFBeUIsQ0FBQ0ksc0JBQTNCLENBQVo7QUFDQUosK0JBQXlCLENBQUNnQixnQkFBMUI7QUFDSCxLQUxEO0FBT0FKLFlBQVEsQ0FBQ2xKLGdCQUFULENBQTBCLE9BQTFCLEVBQW1DLFlBQVk7QUFDM0NzSSwrQkFBeUIsQ0FBQ2lCLFlBQTFCO0FBQ0FqQiwrQkFBeUIsQ0FBQ2MsWUFBMUI7QUFDQUMsa0JBQVksQ0FBQ2YseUJBQXlCLENBQUNJLHNCQUEzQixDQUFaO0FBQ0FKLCtCQUF5QixDQUFDZ0IsZ0JBQTFCO0FBQ0gsS0FMRCxFQVptQixDQW1CbkI7O0FBQ0EsUUFBTUUsYUFBYSxHQUFHLElBQUlDLE1BQUosQ0FBV25CLHlCQUF5QixDQUFDQyxzQkFBckMsQ0FBdEI7QUFDQWlCLGlCQUFhLENBQUNFLEVBQWQsQ0FBaUIsV0FBakIsRUFBOEIsWUFBWTtBQUN0Q3BCLCtCQUF5QixDQUFDYSxRQUExQjtBQUNBYiwrQkFBeUIsQ0FBQ2MsWUFBMUI7QUFDQWQsK0JBQXlCLENBQUNnQixnQkFBMUI7QUFDSCxLQUpEO0FBTUFFLGlCQUFhLENBQUNFLEVBQWQsQ0FBaUIsWUFBakIsRUFBK0IsWUFBWTtBQUN2Q3BCLCtCQUF5QixDQUFDaUIsWUFBMUI7QUFDQWpCLCtCQUF5QixDQUFDYyxZQUExQjtBQUNBZCwrQkFBeUIsQ0FBQ2dCLGdCQUExQjtBQUNILEtBSkQ7QUFNSCxHQWxFNkI7QUFvRTlCQSxrQkFBZ0IsRUFBRSw0QkFBVztBQUMzQmhCLDZCQUF5QixDQUFDcUIsZUFBMUI7QUFDQXJCLDZCQUF5QixDQUFDc0IsZ0JBQTFCO0FBQ0QsR0F2RTZCO0FBeUU5QkQsaUJBQWUsRUFBRSwyQkFBVztBQUN4Qk4sZ0JBQVksQ0FBQ2YseUJBQXlCLENBQUNJLHNCQUEzQixDQUFaO0FBQ0FXLGdCQUFZLENBQUNmLHlCQUF5QixDQUFDSyw2QkFBM0IsQ0FBWjtBQUNBTCw2QkFBeUIsQ0FBQ0ksc0JBQTFCLEdBQW1ELElBQW5EO0FBQ0gsR0E3RTZCO0FBK0U5QmtCLGtCQUFnQixFQUFFLDRCQUFXO0FBQ3pCLFFBQUcsQ0FBQ3RCLHlCQUF5QixDQUFDSSxzQkFBOUIsRUFDSUoseUJBQXlCLENBQUNLLDZCQUExQixHQUEwRFAsVUFBVSxDQUFDRSx5QkFBeUIsQ0FBQ3VCLFdBQTNCLEVBQXdDdkIseUJBQXlCLENBQUNPLHdCQUFsRSxDQUFwRTtBQUNQLEdBbEY2QjtBQW9GOUJpQixZQUFVLEVBQUUsc0JBQVc7QUFFbkIsUUFBTUMsbUJBQW1CLEdBQUd6Qix5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDakksTUFBekU7QUFDQSxRQUFJeUosZUFBZSxHQUFHLEVBQXRCOztBQUVBLFNBQUksSUFBSS9ILENBQUMsR0FBRSxDQUFYLEVBQWNBLENBQUMsR0FBRzhILG1CQUFsQixFQUF1QzlILENBQUMsRUFBeEMsRUFBNEM7QUFFeEMsVUFBTWdJLFlBQVksR0FBRzNCLHlCQUF5QixDQUFDRSxrQkFBMUIsQ0FBNkN2RyxDQUE3QyxDQUFyQjtBQUNBLFVBQU1pSSxjQUFjLEdBQUdELFlBQVksQ0FBQ2xILFlBQWIsQ0FBMEIsY0FBMUIsQ0FBdkI7QUFDQWlILHFCQUFlLENBQUNHLElBQWhCLENBQXFCRCxjQUFyQjtBQUNIOztBQUVELFdBQU87QUFBQ0UsU0FBRyxFQUFFSjtBQUFOLEtBQVA7QUFDSCxHQWpHNkI7QUFtRzlCaEIsZUFBYSxFQUFFLHlCQUFXO0FBQ3RCViw2QkFBeUIsQ0FBQ0Msc0JBQTFCLENBQWlEbkosYUFBakQsQ0FBK0QsbUNBQS9ELEVBQW9HMkIsU0FBcEcsQ0FBOEdFLE1BQTlHLENBQXFILFlBQXJIO0FBQ0FxSCw2QkFBeUIsQ0FBQ3NCLGdCQUExQjtBQUNILEdBdEc2QjtBQXdHOUJDLGFBQVcsRUFBRSx1QkFBVTtBQUNuQnZCLDZCQUF5QixDQUFDSSxzQkFBMUIsR0FBbUROLFVBQVUsQ0FBQ0UseUJBQXlCLENBQUN1QixXQUEzQixFQUF3Q3ZCLHlCQUF5QixDQUFDTSxpQkFBbEUsQ0FBN0Q7QUFFQU4sNkJBQXlCLENBQUNhLFFBQTFCO0FBQ0FiLDZCQUF5QixDQUFDYyxZQUExQjtBQUNILEdBN0c2QjtBQStHOUJELFVBQVEsRUFBRSxvQkFBWTtBQUNsQjtBQUNBYiw2QkFBeUIsQ0FBQ0csVUFBMUIsR0FGa0IsQ0FJbEI7O0FBQ0EsUUFBSUgseUJBQXlCLENBQUNHLFVBQTFCLEtBQXlDSCx5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDakksTUFBMUYsRUFBa0crSCx5QkFBeUIsQ0FBQ0csVUFBMUIsR0FBdUMsQ0FBdkM7QUFDckcsR0FySDZCO0FBdUg5QmMsY0FBWSxFQUFFLHdCQUFZO0FBRXRCO0FBQ0FqQiw2QkFBeUIsQ0FBQ0csVUFBMUIsR0FIc0IsQ0FLdEI7O0FBQ0EsUUFBSUgseUJBQXlCLENBQUNHLFVBQTFCLEdBQXVDLENBQTNDLEVBQThDSCx5QkFBeUIsQ0FBQ0csVUFBMUIsR0FBdUNILHlCQUF5QixDQUFDRSxrQkFBMUIsQ0FBNkNqSSxNQUE3QyxHQUFzRCxDQUE3RjtBQUVqRCxHQS9INkI7QUFpSTlCd0ksaUJBQWUsRUFBRSwyQkFBVztBQUV4QlQsNkJBQXlCLENBQUNFLGtCQUExQixHQUErQ0YseUJBQXlCLENBQUNDLHNCQUExQixDQUFpRDdHLGdCQUFqRCxDQUFrRSx5QkFBbEUsQ0FBL0M7QUFDQSxRQUFNcUksbUJBQW1CLEdBQUd6Qix5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDakksTUFBekU7O0FBQ0EsU0FBSSxJQUFJMEIsQ0FBQyxHQUFHLENBQVosRUFBZUEsQ0FBQyxHQUFHOEgsbUJBQW5CLEVBQXdDOUgsQ0FBQyxFQUF6QyxFQUE2QztBQUN6QyxVQUFNZ0ksWUFBWSxHQUFHM0IseUJBQXlCLENBQUNFLGtCQUExQixDQUE2Q3ZHLENBQTdDLENBQXJCO0FBQ0FnSSxrQkFBWSxDQUFDSSxZQUFiLENBQTBCLGVBQTFCLEVBQTJDcEksQ0FBM0M7QUFDSDs7QUFFRHFHLDZCQUF5QixDQUFDYyxZQUExQjtBQUVILEdBNUk2QjtBQThJOUJBLGNBQVksRUFBRSx3QkFBWTtBQUV0QixRQUFNa0IsZUFBZSxHQUFHaEMseUJBQXlCLENBQUNpQyxzQkFBMUIsQ0FBaUQsQ0FBakQsQ0FBeEI7O0FBQ0EsUUFBTUMsVUFBVSxHQUFHbEMseUJBQXlCLENBQUNpQyxzQkFBMUIsQ0FBaUQsQ0FBakQsQ0FBbkI7O0FBQ0EsUUFBTXJCLFFBQVEsR0FBR1oseUJBQXlCLENBQUNpQyxzQkFBMUIsQ0FBaUQsQ0FBakQsQ0FBakI7O0FBQ0EsUUFBTXRCLElBQUksR0FBR1gseUJBQXlCLENBQUNtQyxrQkFBMUIsQ0FBNkMsQ0FBN0MsQ0FBYjs7QUFDQSxRQUFNQyxNQUFNLEdBQUdwQyx5QkFBeUIsQ0FBQ21DLGtCQUExQixDQUE2QyxDQUE3QyxDQUFmOztBQUNBLFFBQU1FLGFBQWEsR0FBR3JDLHlCQUF5QixDQUFDbUMsa0JBQTFCLENBQTZDLENBQTdDLENBQXRCOztBQUVBLFNBQUssSUFBSXhJLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdxRyx5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDakksTUFBakUsRUFBeUUwQixDQUFDLEVBQTFFLEVBQThFO0FBRTFFLFVBQU0ySSxLQUFLLEdBQUd0Qyx5QkFBeUIsQ0FBQ0Usa0JBQTFCLENBQTZDdkcsQ0FBN0MsQ0FBZCxDQUYwRSxDQUkxRTs7QUFDQTJJLFdBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLDRDQUF2QjtBQUNBMkosV0FBSyxDQUFDN0osU0FBTixDQUFnQkUsTUFBaEIsQ0FBdUIsMENBQXZCO0FBQ0EySixXQUFLLENBQUM3SixTQUFOLENBQWdCRSxNQUFoQixDQUF1QiwwQ0FBdkI7QUFDQTJKLFdBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLDBDQUF2QjtBQUNBMkosV0FBSyxDQUFDN0osU0FBTixDQUFnQkUsTUFBaEIsQ0FBdUIsMENBQXZCO0FBQ0EySixXQUFLLENBQUM3SixTQUFOLENBQWdCRSxNQUFoQixDQUF1QiwwQ0FBdkI7QUFDQTJKLFdBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLHdDQUF2QjtBQUNBMkosV0FBSyxDQUFDN0osU0FBTixDQUFnQkUsTUFBaEIsQ0FBdUIsV0FBdkI7O0FBRUEsY0FBUWdCLENBQVI7QUFDSSxhQUFLcUksZUFBTDtBQUNJTSxlQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQiw0Q0FBcEI7QUFDQTs7QUFDSixhQUFLd0osVUFBTDtBQUNJSSxlQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQiwwQ0FBcEI7QUFDQTs7QUFDSixhQUFLa0ksUUFBTDtBQUNJMEIsZUFBSyxDQUFDN0osU0FBTixDQUFnQkMsR0FBaEIsQ0FBb0IsMENBQXBCO0FBQ0E7O0FBQ0osYUFBS3NILHlCQUF5QixDQUFDRyxVQUEvQjtBQUNJbUMsZUFBSyxDQUFDN0osU0FBTixDQUFnQkMsR0FBaEIsQ0FBb0IsMENBQXBCO0FBQ0E7O0FBQ0osYUFBS2lJLElBQUw7QUFDSTJCLGVBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JDLEdBQWhCLENBQW9CLDBDQUFwQjtBQUNBOztBQUNKLGFBQUswSixNQUFMO0FBQ0lFLGVBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JDLEdBQWhCLENBQW9CLDBDQUFwQjtBQUNBOztBQUNKLGFBQUsySixhQUFMO0FBQ0lDLGVBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JDLEdBQWhCLENBQW9CLHdDQUFwQjtBQUNBOztBQUNKO0FBQ0k0SixlQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQixXQUFwQjtBQXZCUjtBQTBCSDtBQUVKLEdBak02QjtBQW1NOUJ1Six3QkFBc0IsRUFBRSxnQ0FBU00sT0FBVCxFQUFrQjtBQUN0QyxRQUFJM0UsUUFBUSxHQUFHb0MseUJBQXlCLENBQUNHLFVBQTFCLEdBQXVDb0MsT0FBdEQ7QUFDQSxRQUFJM0UsUUFBUSxHQUFHLENBQWYsRUFBa0IsT0FBT29DLHlCQUF5QixDQUFDRSxrQkFBMUIsQ0FBNkNqSSxNQUE3QyxHQUFzRDJGLFFBQTdEO0FBQ2xCLFdBQU9BLFFBQVA7QUFDSCxHQXZNNkI7QUF5TTlCdUUsb0JBQWtCLEVBQUUsNEJBQVNJLE9BQVQsRUFBa0I7QUFDbEMsUUFBSTNFLFFBQVEsR0FBR29DLHlCQUF5QixDQUFDRyxVQUExQixHQUF1Q29DLE9BQXREO0FBQ0EsUUFBRzNFLFFBQVEsSUFBSW9DLHlCQUF5QixDQUFDRSxrQkFBMUIsQ0FBNkNqSSxNQUE1RCxFQUFvRSxPQUFPMkYsUUFBUSxHQUFHb0MseUJBQXlCLENBQUNFLGtCQUExQixDQUE2Q2pJLE1BQS9EO0FBQ3BFLFdBQU8yRixRQUFQO0FBRUgsR0E5TTZCO0FBZ045QjRFLDBCQUF3QixFQUFFLGtDQUFTQyxpQkFBVCxFQUE0QmQsWUFBNUIsRUFBMEM7QUFDaEVjLHFCQUFpQixJQUFJLHFIQUFyQjtBQUNBLFFBQUdoSixLQUFLLENBQUNrSSxZQUFZLENBQUNlLEdBQWQsQ0FBUixFQUE0QkQsaUJBQWlCLElBQUcsV0FBV2QsWUFBWSxDQUFDZSxHQUF4QixHQUE4Qiw0Q0FBOUIsR0FBNkVmLFlBQVksQ0FBQ2UsR0FBMUYsR0FBZ0csSUFBcEg7QUFDNUJELHFCQUFpQixJQUFJLG9DQUFvQ2QsWUFBWSxDQUFDZ0IsRUFBakQsR0FBc0QsSUFBdEQsR0FDakIseUVBRGlCLEdBQzJELEdBRDNELEdBQ2lFaEIsWUFBWSxDQUFDaUIsS0FEOUUsR0FDc0YsR0FEdEYsR0FDNEYsV0FENUYsR0FFakIsTUFGSjtBQUlBLFdBQU9ILGlCQUFQO0FBRUg7QUF6TjZCLENBQWxDO0FBNE5BekMseUJBQXlCLENBQUNoTCxJQUExQixHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25PQTs7O0lBR002TixlO0FBQ0YsNkJBQ0E7QUFBQTs7QUFDSSxTQUFLQyxZQUFMLEdBQW9CLFVBQXBCO0FBQ0EsU0FBS0MscUJBQUwsR0FBNkIsUUFBN0I7QUFDSDtBQUVEOzs7Ozs7OztrQ0FJY0MsYSxFQUFleE0sSyxFQUM3QjtBQUNJLFVBQUl5TSxRQUFRLEdBQUcsTUFBSUQsYUFBSixHQUFrQixLQUFLRCxxQkFBdEM7QUFDQSxVQUFJRyxZQUFZLEdBQUdoTyxRQUFRLENBQUM0QixhQUFULENBQXVCbU0sUUFBdkIsQ0FBbkI7QUFDQSxVQUFHLENBQUNDLFlBQUosRUFBa0I7QUFFbEJBLGtCQUFZLENBQUN6SyxTQUFiLENBQXVCRSxNQUF2QixDQUE4QixLQUFLbUssWUFBbkM7QUFDQUksa0JBQVksQ0FBQ0MsU0FBYixHQUF5QjNNLEtBQXpCO0FBQ0g7QUFFRDs7Ozs7O29DQUdnQndNLGEsRUFBZTtBQUMzQixVQUFJQyxRQUFRLEdBQUcsTUFBSUQsYUFBSixHQUFrQixLQUFLRCxxQkFBdEM7QUFDQSxVQUFJRyxZQUFZLEdBQUdoTyxRQUFRLENBQUM0QixhQUFULENBQXVCbU0sUUFBdkIsQ0FBbkI7QUFDQSxVQUFJLENBQUNDLFlBQUwsRUFBbUI7QUFFbkJBLGtCQUFZLENBQUN6SyxTQUFiLENBQXVCQyxHQUF2QixDQUEyQixLQUFLb0ssWUFBaEM7QUFDQUksa0JBQVksQ0FBQ0MsU0FBYixHQUF5QixFQUF6QjtBQUNIO0FBRUQ7Ozs7OztxQ0FHaUI7QUFDYixVQUFJM04sSUFBSSxHQUFHLElBQVg7QUFDQU4sY0FBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsVUFBUSxLQUFLMkoscUJBQWIsR0FBbUMsR0FBN0QsRUFBa0UxRyxPQUFsRSxDQUEwRSxVQUFTNkcsWUFBVCxFQUF1QjtBQUM3RkEsb0JBQVksQ0FBQ3pLLFNBQWIsQ0FBdUJDLEdBQXZCLENBQTJCbEQsSUFBSSxDQUFDc04sWUFBaEM7QUFDQUksb0JBQVksQ0FBQ0MsU0FBYixHQUF5QixFQUF6QjtBQUNILE9BSEQ7QUFJSDs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM3Q0w7Ozs7O0FBTUEsSUFBTUMsaUJBQWlCLEdBQUc7QUFDdEJDLHdCQUFzQixFQUFFLGlCQURGO0FBRXRCQyxxQkFBbUIsRUFBRSx1QkFGQztBQUd0QkMsc0JBQW9CLEVBQUUsd0JBSEE7QUFJdEJDLHVCQUFxQixFQUFFLHlCQUpEO0FBTXRCeE8sTUFBSSxFQUFFLGdCQUFZO0FBRWQsUUFBTXlPLFdBQVcsR0FBR3ZPLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCZ0ssaUJBQWlCLENBQUNDLHNCQUE1QyxDQUFwQjtBQUNBLFFBQU1LLGdCQUFnQixHQUFHRCxXQUFXLENBQUN4TCxNQUFyQzs7QUFFQSxRQUFHd0IsS0FBSyxDQUFDZ0ssV0FBRCxDQUFMLElBQXNCQyxnQkFBZ0IsS0FBSyxDQUE5QyxFQUFnRDtBQUM1QyxXQUFJLElBQUkvSixDQUFDLEdBQUcsQ0FBWixFQUFlQSxDQUFDLEdBQUcrSixnQkFBbkIsRUFBcUMvSixDQUFDLEVBQXRDLEVBQXlDO0FBQ3JDLFlBQU1nSyxVQUFVLEdBQUdGLFdBQVcsQ0FBQzlKLENBQUQsQ0FBOUI7QUFDQSxhQUFLaUsscUJBQUwsQ0FBMkJELFVBQTNCO0FBQ0g7QUFDSjtBQUNKLEdBakJxQjtBQW1CdEJFLFNBQU8sRUFBRSxpQkFBVUMsWUFBVixFQUF3QjtBQUM3QixRQUFHLENBQUNBLFlBQUosRUFBa0I7QUFFbEIsUUFBTUMsSUFBSSxHQUFHRCxZQUFZLENBQUNFLFNBQWIsRUFBYjtBQUNBLFFBQU1DLElBQUksR0FBR0gsWUFBWSxDQUFDckcsVUFBYixDQUF3QkEsVUFBeEIsQ0FBbUMzRyxhQUFuQyxDQUFpRHNNLGlCQUFpQixDQUFDRSxtQkFBbkUsQ0FBYjtBQUNBLFFBQUlZLEVBQUUsR0FBR2hQLFFBQVEsQ0FBQ2lQLGFBQVQsQ0FBdUIsSUFBdkIsQ0FBVDtBQUNBLFFBQUl4TCxNQUFNLEdBQUd6RCxRQUFRLENBQUNpUCxhQUFULENBQXVCLFFBQXZCLENBQWI7QUFDQSxRQUFJQyxRQUFRLEdBQUdsUCxRQUFRLENBQUNtUCxjQUFULENBQXdCUCxZQUFZLENBQUNuTSxLQUFiLENBQW1CMk0sS0FBbkIsQ0FBeUIsSUFBekIsRUFBK0JSLFlBQVksQ0FBQ25NLEtBQWIsQ0FBbUIyTSxLQUFuQixDQUF5QixJQUF6QixFQUErQnJNLE1BQS9CLEdBQXdDLENBQXZFLENBQXhCLENBQWY7QUFFQThMLFFBQUksQ0FBQ3BNLEtBQUwsR0FBYSxFQUFiO0FBQ0FvTSxRQUFJLENBQUNyTSxnQkFBTCxDQUFzQixRQUF0QixFQUFnQyxLQUFLNk0sWUFBckM7QUFFQTVMLFVBQU0sQ0FBQ29KLFlBQVAsQ0FBb0IsTUFBcEIsRUFBNEIsUUFBNUI7QUFDQXBKLFVBQU0sQ0FBQ2pCLGdCQUFQLENBQXdCLE9BQXhCLEVBQWlDLEtBQUs2TSxZQUF0QztBQUVBVCxnQkFBWSxDQUFDckcsVUFBYixDQUF3QmpGLFdBQXhCLENBQW9DdUwsSUFBcEM7QUFDQUQsZ0JBQVksQ0FBQ1UsS0FBYixDQUFtQkMsT0FBbkIsR0FBNkIsTUFBN0I7QUFFQVAsTUFBRSxDQUFDMUwsV0FBSCxDQUFlc0wsWUFBZjtBQUNBSSxNQUFFLENBQUMxTCxXQUFILENBQWU0TCxRQUFmO0FBQ0FGLE1BQUUsQ0FBQzFMLFdBQUgsQ0FBZUcsTUFBZjtBQUVBc0wsUUFBSSxDQUFDekwsV0FBTCxDQUFpQjBMLEVBQWpCO0FBQ0gsR0ExQ3FCO0FBNEN0QlEsWUFBVSxFQUFFLG9CQUFVQyxLQUFWLEVBQWlCO0FBQ3pCQSxTQUFLLENBQUNDLE1BQU4sQ0FBYW5ILFVBQWIsQ0FBd0JBLFVBQXhCLENBQW1DM0UsV0FBbkMsQ0FBK0M2TCxLQUFLLENBQUNDLE1BQU4sQ0FBYW5ILFVBQTVEO0FBQ0gsR0E5Q3FCO0FBZ0R0QjhHLGNBQVksRUFBRSxzQkFBVUksS0FBVixFQUFpQjtBQUMzQixZQUFRQSxLQUFLLENBQUMzSixJQUFkO0FBQ0ksV0FBSyxPQUFMO0FBQ0ksWUFBSTJKLEtBQUssQ0FBQ0MsTUFBTixDQUFhbk0sU0FBYixDQUF1QmlGLFFBQXZCLENBQWdDMEYsaUJBQWlCLENBQUNJLHFCQUFsQixDQUF3Q3FCLFNBQXhDLENBQWtELENBQWxELENBQWhDLENBQUosRUFBMkY7QUFDdkZGLGVBQUssQ0FBQ0MsTUFBTixDQUFhbkgsVUFBYixDQUF3QjNHLGFBQXhCLENBQXNDc00saUJBQWlCLENBQUNHLG9CQUF4RCxFQUE4RXVCLEtBQTlFO0FBQ0gsU0FGRCxNQUdLO0FBQ0QxQiwyQkFBaUIsQ0FBQ3NCLFVBQWxCLENBQTZCQyxLQUE3QjtBQUNIOztBQUVEOztBQUNKLFdBQUssUUFBTDtBQUNJdkIseUJBQWlCLENBQUNTLE9BQWxCLENBQTBCYyxLQUFLLENBQUNDLE1BQWhDO0FBQ0E7QUFaUjtBQWNILEdBL0RxQjtBQWlFdEJoQix1QkFBcUIsRUFBRSwrQkFBVUQsVUFBVixFQUFzQjtBQUN6QyxRQUFNRyxZQUFZLEdBQUdILFVBQVUsQ0FBQzdNLGFBQVgsQ0FBeUJzTSxpQkFBaUIsQ0FBQ0csb0JBQTNDLENBQXJCO0FBQ0EsUUFBTXdCLGtCQUFrQixHQUFHcEIsVUFBVSxDQUFDN00sYUFBWCxDQUF5QnNNLGlCQUFpQixDQUFDSSxxQkFBM0MsQ0FBM0I7QUFDQXVCLHNCQUFrQixDQUFDck4sZ0JBQW5CLENBQW9DLE9BQXBDLEVBQTZDLEtBQUs2TSxZQUFsRDtBQUNBVCxnQkFBWSxDQUFDcE0sZ0JBQWIsQ0FBOEIsUUFBOUIsRUFBd0MsS0FBSzZNLFlBQTdDO0FBQ0g7QUF0RXFCLENBQTFCO0FBMkVBbkIsaUJBQWlCLENBQUNwTyxJQUFsQixHOzs7Ozs7Ozs7OztBQ2pGQTs7OztBQUtBLElBQU1nUSxXQUFXLEdBQUc7QUFFaEJDLE1BQUksRUFBRSxFQUZVO0FBR2hCQyxLQUFHLEVBQUUseUNBSFc7QUFLaEJsUSxNQUFJLEVBQUUsZ0JBQVk7QUFFZDtBQUNBLFFBQU1pUSxJQUFJLEdBQUcvUCxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixnQkFBMUIsQ0FBYixDQUhjLENBS2Q7O0FBQ0EsUUFBRzZMLElBQUksQ0FBQ2hOLE1BQUwsS0FBZ0IsQ0FBbkIsRUFBdUI7QUFFbkI7QUFDQSxXQUFJLElBQUkwQixDQUFDLEdBQUcsQ0FBWixFQUFlQSxDQUFDLEdBQUdzTCxJQUFJLENBQUNoTixNQUF4QixFQUFnQzBCLENBQUMsRUFBakMsRUFBcUM7QUFFakM7QUFDQSxZQUFNd0wsR0FBRyxHQUFHRixJQUFJLENBQUN0TCxDQUFELENBQWhCO0FBRUEsWUFBRyxDQUFDd0wsR0FBRyxDQUFDQyxZQUFKLENBQWlCLGlCQUFqQixDQUFELElBQXdDLENBQUNELEdBQUcsQ0FBQ0MsWUFBSixDQUFpQixpQkFBakIsQ0FBNUMsRUFBaUY7QUFFakYsWUFBSUMsR0FBRyxHQUFHQyxVQUFVLENBQUNILEdBQUcsQ0FBQzFLLFlBQUosQ0FBaUIsaUJBQWpCLENBQUQsQ0FBcEI7QUFDQSxZQUFJOEssR0FBRyxHQUFHRCxVQUFVLENBQUNILEdBQUcsQ0FBQzFLLFlBQUosQ0FBaUIsaUJBQWpCLENBQUQsQ0FBcEI7QUFFQXVLLG1CQUFXLENBQUNDLElBQVosQ0FBaUJwRCxJQUFqQixDQUFzQjtBQUNsQmtDLGNBQUksRUFBRW9CLEdBRFk7QUFFbEJ2SCxrQkFBUSxFQUFFO0FBQ055SCxlQUFHLEVBQUVBLEdBREM7QUFFTkUsZUFBRyxFQUFFQTtBQUZDLFdBRlE7QUFNbEJDLGdCQUFNLEVBQUVSLFdBQVcsQ0FBQ1MsZ0JBQVo7QUFOVSxTQUF0QjtBQVFILE9BckJrQixDQXVCbkI7OztBQUNBLFVBQUksT0FBT0MsTUFBUCxJQUFrQixXQUFsQixJQUFpQyxPQUFPQSxNQUFNLENBQUNULElBQWQsSUFBdUIsV0FBNUQsRUFBeUU7QUFDckU7QUFDQVUsaUJBQVMsQ0FBQyxpREFBaURYLFdBQVcsQ0FBQ0UsR0FBOUQsRUFBbUVGLFdBQVcsQ0FBQ1ksUUFBL0UsQ0FBVDtBQUNILE9BSEQsTUFHTztBQUNIO0FBQ0FaLG1CQUFXLENBQUNZLFFBQVo7QUFDSDtBQUNKO0FBQ0osR0EzQ2U7O0FBNkNoQjs7O0FBR0FBLFVBQVEsRUFBRSxvQkFBWTtBQUVsQixTQUFLLElBQUlqTSxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHcUwsV0FBVyxDQUFDQyxJQUFaLENBQWlCaE4sTUFBckMsRUFBNkMwQixDQUFDLEVBQTlDLEVBQW1EO0FBRS9DLFVBQU13TCxHQUFHLEdBQUdILFdBQVcsQ0FBQ0MsSUFBWixDQUFpQnRMLENBQWpCLENBQVosQ0FGK0MsQ0FJL0M7O0FBQ0EsVUFBTWtNLFNBQVMsR0FBRyxJQUFJSCxNQUFNLENBQUNULElBQVAsQ0FBWWEsR0FBaEIsQ0FBb0JYLEdBQUcsQ0FBQ3BCLElBQXhCLEVBQThCO0FBQzVDZ0MsWUFBSSxFQUFFLEVBRHNDO0FBRTVDQyxjQUFNLEVBQUViLEdBQUcsQ0FBQ3ZILFFBRmdDO0FBRzVDcUksd0JBQWdCLEVBQUUsSUFIMEI7QUFJNUNULGNBQU0sRUFBRUwsR0FBRyxDQUFDSztBQUpnQyxPQUE5QixDQUFsQixDQUwrQyxDQVkvQzs7QUFDQSxVQUFNVSxNQUFNLEdBQUcsSUFBSVIsTUFBTSxDQUFDVCxJQUFQLENBQVlrQixNQUFoQixDQUF1QjtBQUNsQ0MsZ0JBQVEsRUFBRWpCLEdBQUcsQ0FBQ3ZILFFBRG9CO0FBRWxDdUgsV0FBRyxFQUFFVTtBQUY2QixPQUF2QixDQUFmO0FBSUg7QUFDSixHQXBFZTs7QUFzRWhCOzs7OztBQUtBSixrQkFBZ0IsRUFBRSw0QkFBWTtBQUUxQixXQUFPLENBQ0M7QUFDSSxxQkFBZSxLQURuQjtBQUVJLHFCQUFlLGtCQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxpQkFBUztBQURiLE9BRE8sRUFJUDtBQUNJLHFCQUFhO0FBRGpCLE9BSk87QUFIZixLQURELEVBYUM7QUFDSSxxQkFBZSxnQkFEbkI7QUFFSSxxQkFBZSxlQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxpQkFBUztBQURiLE9BRE87QUFIZixLQWJELEVBc0JDO0FBQ0kscUJBQWUsZ0JBRG5CO0FBRUkscUJBQWUsZUFGbkI7QUFHSSxpQkFBVyxDQUNQO0FBQ0ksaUJBQVM7QUFEYixPQURPO0FBSGYsS0F0QkQsRUErQkM7QUFDSSxxQkFBZSxhQURuQjtBQUVJLHFCQUFlLGVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGlCQUFTO0FBRGIsT0FETztBQUhmLEtBL0JELEVBd0NDO0FBQ0kscUJBQWUsVUFEbkI7QUFFSSxxQkFBZSxlQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxpQkFBUztBQURiLE9BRE87QUFIZixLQXhDRCxFQWlEQztBQUNJLHFCQUFlLHNCQURuQjtBQUVJLHFCQUFlLGVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGlCQUFTO0FBRGIsT0FETztBQUhmLEtBakRELEVBMERDO0FBQ0kscUJBQWUsWUFEbkI7QUFFSSxxQkFBZSxlQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxpQkFBUztBQURiLE9BRE87QUFIZixLQTFERCxFQW1FQztBQUNJLHFCQUFlLG9CQURuQjtBQUVJLHFCQUFlLGVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGlCQUFTO0FBRGIsT0FETztBQUhmLEtBbkVELEVBNEVDO0FBQ0kscUJBQWUsTUFEbkI7QUFFSSxxQkFBZSxVQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxxQkFBYTtBQURqQixPQURPO0FBSGYsS0E1RUQsRUFxRkM7QUFDSSxxQkFBZSxNQURuQjtBQUVJLHFCQUFlLFFBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLHNCQUFjO0FBRGxCLE9BRE8sRUFJUDtBQUNJLHFCQUFhO0FBRGpCLE9BSk87QUFIZixLQXJGRCxFQWlHQztBQUNJLHFCQUFlLGNBRG5CO0FBRUkscUJBQWUsZUFGbkI7QUFHSSxpQkFBVyxDQUNQO0FBQ0ksaUJBQVM7QUFEYixPQURPO0FBSGYsS0FqR0QsRUEwR0M7QUFDSSxxQkFBZSxlQURuQjtBQUVJLHFCQUFlLGVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGlCQUFTO0FBRGIsT0FETztBQUhmLEtBMUdELEVBbUhDO0FBQ0kscUJBQWUsWUFEbkI7QUFFSSxxQkFBZSxLQUZuQjtBQUdJLGlCQUFXLENBQ1A7QUFDSSxzQkFBYztBQURsQixPQURPO0FBSGYsS0FuSEQsRUE0SEM7QUFDSSxxQkFBZSxZQURuQjtBQUVJLHFCQUFlLGVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGtCQUFVO0FBRGQsT0FETztBQUhmLEtBNUhELEVBcUlDO0FBQ0kscUJBQWUsWUFEbkI7QUFFSSxxQkFBZSxpQkFGbkI7QUFHSSxpQkFBVyxDQUNQO0FBQ0ksa0JBQVU7QUFEZCxPQURPO0FBSGYsS0FySUQsRUE4SUM7QUFDSSxxQkFBZSxZQURuQjtBQUVJLHFCQUFlLGFBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLHNCQUFjO0FBRGxCLE9BRE87QUFIZixLQTlJRCxFQXVKQztBQUNJLHFCQUFlLFlBRG5CO0FBRUkscUJBQWUsa0JBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLGlCQUFTO0FBRGIsT0FETyxFQUlQO0FBQ0kscUJBQWE7QUFEakIsT0FKTztBQUhmLEtBdkpELEVBbUtDO0FBQ0kscUJBQWUsWUFEbkI7QUFFSSxxQkFBZSxvQkFGbkI7QUFHSSxpQkFBVyxDQUNQO0FBQ0ksaUJBQVM7QUFEYixPQURPLEVBSVA7QUFDSSxxQkFBYTtBQURqQixPQUpPO0FBSGYsS0FuS0QsRUErS0M7QUFDSSxxQkFBZSxjQURuQjtBQUVJLHFCQUFlLFVBRm5CO0FBR0ksaUJBQVcsQ0FDUDtBQUNJLHNCQUFjO0FBRGxCLE9BRE8sRUFJUDtBQUNJLHFCQUFhO0FBRGpCLE9BSk87QUFIZixLQS9LRCxFQTJMQztBQUNJLHFCQUFlLE9BRG5CO0FBRUkscUJBQWUsS0FGbkI7QUFHSSxpQkFBVyxDQUNQO0FBQ0ksaUJBQVM7QUFEYixPQURPO0FBSGYsS0EzTEQsQ0FBUDtBQXFNSDtBQWxSZSxDQUFwQjtBQXFSQVQsV0FBVyxDQUFDaFEsSUFBWixHOzs7Ozs7Ozs7OztBQzFSQTs7OztBQUtBLElBQU1xUixjQUFjLEdBQUd2UixtQkFBTyxDQUFDLG1GQUFELENBQTlCOztBQUVBLElBQU13UixrQkFBa0IsR0FBRztBQUV2QjtBQUNBO0FBQ0E7QUFDQTtBQUVBdFIsTUFBSSxFQUFFLGdCQUFZO0FBRWQsUUFBTXVSLHNCQUFzQixHQUFHclIsUUFBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsMEJBQTFCLENBQS9CO0FBQ0EsUUFBTW9OLDJCQUEyQixHQUFHRCxzQkFBc0IsQ0FBQ3RPLE1BQTNEOztBQUVBLFFBQUd3QixLQUFLLENBQUM4TSxzQkFBRCxDQUFMLElBQWlDQywyQkFBMkIsS0FBSyxDQUFwRSxFQUFzRTtBQUNsRSxXQUFJLElBQUk3TSxDQUFDLEdBQUcsQ0FBWixFQUFlQSxDQUFDLEdBQUc2TSwyQkFBbkIsRUFBZ0Q3TSxDQUFDLEVBQWpELEVBQW9EO0FBQ2hELFlBQU04TSxrQkFBa0IsR0FBR0Ysc0JBQXNCLENBQUM1TSxDQUFELENBQWpEO0FBQ0EyTSwwQkFBa0IsQ0FBQ0ksZUFBbkIsQ0FBbUNELGtCQUFuQztBQUNIO0FBQ0o7QUFDSixHQWxCc0I7QUFvQnZCQyxpQkFBZSxFQUFFLHlCQUFVRCxrQkFBVixFQUE4QjtBQUMzQ0Esc0JBQWtCLENBQUMvTyxnQkFBbkIsQ0FBb0MsT0FBcEMsRUFBNkM0TyxrQkFBa0IsQ0FBQ0ssaUJBQWhFLEVBQW1GLEtBQW5GO0FBQ0gsR0F0QnNCO0FBd0J2QkEsbUJBQWlCLEVBQUUsMkJBQVVoQyxLQUFWLEVBQWlCO0FBQ2hDLFFBQU1pQyxjQUFjLEdBQUcxUixRQUFRLENBQUM0QixhQUFULENBQXVCLGtCQUF2QixDQUF2QixDQURnQyxDQUVoQztBQUVBOztBQUNBLFFBQUksQ0FBQzhQLGNBQUwsRUFBcUIsT0FMVyxDQU9oQzs7QUFDQVAsa0JBQWMsQ0FBQ1EsZ0JBQWYsQ0FBZ0NELGNBQWhDLEVBUmdDLENBVWhDOztBQUNBLFFBQUkxUixRQUFRLENBQUNnRSxJQUFULENBQWNULFNBQWQsQ0FBd0JpRixRQUF4QixDQUFpQyx3QkFBakMsQ0FBSixFQUFnRTtBQUM1RGtKLG9CQUFjLENBQUN4TixnQkFBZixDQUFnQyxnQkFBaEMsRUFBa0RpRCxPQUFsRCxDQUEwRCxVQUFTeUssSUFBVCxFQUFlO0FBQ3JFQSxZQUFJLENBQUNDLFFBQUwsR0FBZ0IsQ0FBQyxDQUFqQjtBQUNILE9BRkQ7QUFJQTdSLGNBQVEsQ0FBQ2dFLElBQVQsQ0FBY1QsU0FBZCxDQUF3QkUsTUFBeEIsQ0FBK0Isd0JBQS9CO0FBQ0E7QUFDSCxLQWxCK0IsQ0FvQmhDOzs7QUFDQTBOLGtCQUFjLENBQUNXLGlCQUFmLENBQWlDSixjQUFqQztBQUVBQSxrQkFBYyxDQUFDeE4sZ0JBQWYsQ0FBZ0MsaUJBQWhDLEVBQW1EaUQsT0FBbkQsQ0FBMkQsVUFBU3lLLElBQVQsRUFBZTtBQUN0RUEsVUFBSSxDQUFDQyxRQUFMLEdBQWdCLENBQWhCO0FBQ0gsS0FGRCxFQXZCZ0MsQ0EyQmhDOztBQUNBN1IsWUFBUSxDQUFDZ0UsSUFBVCxDQUFjVCxTQUFkLENBQXdCd08sTUFBeEIsQ0FBK0Isd0JBQS9CO0FBQ0FMLGtCQUFjLENBQUNNLE1BQWYsR0FBd0IsS0FBeEI7QUFDSDtBQXREc0IsQ0FBM0I7QUF5REFaLGtCQUFrQixDQUFDdFIsSUFBbkIsRzs7Ozs7Ozs7Ozs7QUNoRUE7Ozs7O0FBS0E7Ozs7Ozs7Ozs7Ozs7OztBQWdCQSxJQUFJbVMsVUFBVSxHQUFHLEVBQWpCO0FBRUEsSUFBTUMsbUJBQW1CLEdBQUdsUyxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixlQUExQixDQUE1QjtBQUNBLElBQU1pTyx5QkFBeUIsR0FBR0QsbUJBQW1CLENBQUNuUCxNQUF0RDs7QUFFQSxLQUFJLElBQUkwQixDQUFDLEdBQUUsQ0FBWCxFQUFjQSxDQUFDLEdBQUcwTix5QkFBbEIsRUFBNkMxTixDQUFDLEVBQTlDLEVBQWlEO0FBRTdDLE1BQU0yTixTQUFTLEdBQUdGLG1CQUFtQixDQUFDek4sQ0FBRCxDQUFyQztBQUNBLE1BQU00TixXQUFXLEdBQUdELFNBQVMsQ0FBQzdNLFlBQVYsQ0FBdUIsSUFBdkIsQ0FBcEI7O0FBRUEsTUFBRzhNLFdBQVcsS0FBSyxJQUFuQixFQUF3QjtBQUVwQixRQUFNQyxnQkFBZ0IsR0FBRyxJQUFJQyxnQkFBSixDQUFxQjtBQUMxQ0MsY0FBUSxFQUFFSCxXQURnQztBQUUxQ0ksZ0JBQVUsRUFBRSxNQUFNSixXQUFOLEdBQW1CLHNCQUZXO0FBRzFDSyx1QkFBaUIsRUFBRSxNQUFNTCxXQUFOLEdBQW1CLHVCQUhJO0FBSTFDTSxVQUFJLEVBQUUsTUFBTU4sV0FBTixHQUFtQiwwQkFKaUI7QUFLMUNPLGVBQVMsRUFBRSxJQUwrQjtBQU0xQ0Msb0JBQWMsRUFBRTtBQU4wQixLQUFyQixDQUF6QjtBQVNBWixjQUFVLENBQUN0RixJQUFYLENBQWlCLElBQUltRyxTQUFKLENBQWNSLGdCQUFnQixDQUFDUyxpQkFBakIsRUFBZCxFQUFvRGpULElBQXBELEVBQWpCO0FBQ0gsR0FaRCxNQWFLdUIsT0FBTyxDQUFDMEQsR0FBUixDQUFZLDhCQUFaO0FBQ1I7O0FBR0QsU0FBU3dOLGdCQUFULENBQTBCUyxjQUExQixFQUEwQztBQUV0QyxNQUFNMVMsSUFBSSxHQUFHLElBQWI7QUFFQSxPQUFLa1MsUUFBTCxHQUFnQixFQUFoQjtBQUNBLE9BQUtTLG1CQUFMLEdBQTJCLElBQTNCO0FBQ0EsT0FBS0wsU0FBTCxHQUFpQixLQUFqQjtBQUNBLE9BQUtDLGNBQUwsR0FBc0IsSUFBdEI7QUFDQSxPQUFLSCxpQkFBTCxHQUF5QixFQUF6QjtBQUNBLE9BQUtDLElBQUwsR0FBWSxFQUFaO0FBQ0EsT0FBS08sUUFBTCxHQUFnQixFQUFoQjtBQUNBLE9BQUtULFVBQUwsR0FBa0IsRUFBbEI7O0FBRUEsT0FBS1UsY0FBTCxHQUFzQixVQUFVQyxNQUFWLEVBQWtCO0FBQ3BDLFNBQUtaLFFBQUwsR0FBZ0JZLE1BQWhCO0FBQ0EsV0FBTyxJQUFQO0FBQ0gsR0FIRDs7QUFJQSxPQUFLQyxzQkFBTCxHQUE4QixVQUFVQyxRQUFWLEVBQW1CO0FBQzdDLFNBQUtMLG1CQUFMLEdBQTJCSyxRQUEzQjtBQUNBLFdBQU8sSUFBUDtBQUNILEdBSEQ7O0FBSUEsT0FBS0MsWUFBTCxHQUFvQixVQUFVRCxTQUFWLEVBQW1CO0FBQ25DLFNBQUtWLFNBQUwsR0FBaUJVLFNBQWpCO0FBQ0EsV0FBTyxJQUFQO0FBQ0gsR0FIRDs7QUFJQSxPQUFLRSxpQkFBTCxHQUF5QixVQUFVQyxPQUFWLEVBQW1CO0FBQ3hDLFNBQUtaLGNBQUwsR0FBc0JZLE9BQXRCO0FBQ0EsV0FBTyxJQUFQO0FBQ0gsR0FIRDs7QUFJQSxPQUFLQyxhQUFMLEdBQXFCLFVBQVVOLE1BQVYsRUFBa0I7QUFDbkMsU0FBS1gsVUFBTCxHQUFrQlcsTUFBbEI7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtPLG9CQUFMLEdBQTRCLFVBQVVQLE1BQVYsRUFBa0I7QUFDMUMsU0FBS1YsaUJBQUwsR0FBeUJVLE1BQXpCO0FBQ0EsV0FBTyxJQUFQO0FBQ0gsR0FIRDs7QUFJQSxPQUFLUSxPQUFMLEdBQWUsVUFBVVIsTUFBVixFQUFrQjtBQUM3QixTQUFLVCxJQUFMLEdBQVlTLE1BQVo7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtTLFdBQUwsR0FBbUIsVUFBVVQsTUFBVixFQUFrQjtBQUNqQyxTQUFLRixRQUFMLEdBQWdCRSxNQUFoQjtBQUNBLFdBQU8sSUFBUDtBQUNILEdBSEQ7O0FBSUEsT0FBS1UsY0FBTCxHQUFzQixZQUFZO0FBQzlCLFdBQU8sS0FBS3RCLFFBQVo7QUFDSCxHQUZEOztBQUdBLE9BQUt1QixzQkFBTCxHQUE4QixZQUFZO0FBQ3RDLFdBQU8sS0FBS2QsbUJBQVo7QUFDSCxHQUZEOztBQUdBLE9BQUtlLFlBQUwsR0FBb0IsWUFBWTtBQUM1QixXQUFPLEtBQUtwQixTQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLcUIsaUJBQUwsR0FBeUIsWUFBWTtBQUNqQyxXQUFPLEtBQUtwQixjQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLcUIsYUFBTCxHQUFxQixZQUFZO0FBQzdCLFdBQU8sS0FBS3pCLFVBQVo7QUFDSCxHQUZEOztBQUdBLE9BQUswQixvQkFBTCxHQUE0QixZQUFZO0FBQ3BDLFdBQU8sS0FBS3pCLGlCQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLMEIsT0FBTCxHQUFlLFlBQVk7QUFDdkIsV0FBTyxLQUFLekIsSUFBWjtBQUNILEdBRkQ7O0FBR0EsT0FBSzBCLFdBQUwsR0FBbUIsWUFBWTtBQUMzQixXQUFPLEtBQUtuQixRQUFaO0FBQ0gsR0FGRCxDQWxFc0MsQ0F1RXRDOzs7QUFDQSxPQUFLSCxpQkFBTCxHQUF5QixZQUFZO0FBRWpDLFdBQU87QUFDSFAsY0FBUSxFQUFFbFMsSUFBSSxDQUFDd1QsY0FBTCxFQURQO0FBRUhiLHlCQUFtQixFQUFFM1MsSUFBSSxDQUFDeVQsc0JBQUwsRUFGbEI7QUFHSG5CLGVBQVMsRUFBRXRTLElBQUksQ0FBQzBULFlBQUwsRUFIUjtBQUlIbkIsb0JBQWMsRUFBRXZTLElBQUksQ0FBQzJULGlCQUFMLEVBSmI7QUFLSHZCLHVCQUFpQixFQUFFcFMsSUFBSSxDQUFDNlQsb0JBQUwsRUFMaEI7QUFNSHhCLFVBQUksRUFBRXJTLElBQUksQ0FBQzhULE9BQUwsRUFOSDtBQU9IbEIsY0FBUSxFQUFFNVMsSUFBSSxDQUFDK1QsV0FBTCxFQVBQO0FBUUg1QixnQkFBVSxFQUFFblMsSUFBSSxDQUFDNFQsYUFBTDtBQVJULEtBQVA7QUFXSCxHQWJELENBeEVzQyxDQXVGdEM7OztBQUNBLE9BQUtJLElBQUwsR0FBWSxZQUFZO0FBQ3BCO0FBQ0E7QUFDQTtBQUVBLFFBQU1DLGtCQUFrQixHQUFHdE4sTUFBTSxDQUFDQyxJQUFQLENBQVk4TCxjQUFaLENBQTNCO0FBQ0EsUUFBTXdCLG9CQUFvQixHQUFHRCxrQkFBa0IsQ0FBQ3hSLE1BQWhEOztBQUVBLFNBQUksSUFBSTBCLEVBQUMsR0FBRyxDQUFaLEVBQWVBLEVBQUMsR0FBRytQLG9CQUFuQixFQUF5Qy9QLEVBQUMsRUFBMUMsRUFBNkM7QUFDekMsVUFBTXVMLEdBQUcsR0FBR3VFLGtCQUFrQixDQUFDOVAsRUFBRCxDQUE5QjtBQUNBbkUsVUFBSSxDQUFDMFAsR0FBRCxDQUFKLEdBQVlnRCxjQUFjLENBQUNoRCxHQUFELENBQTFCO0FBQ0g7QUFFSixHQWJEOztBQWVBLE9BQUtzRSxJQUFMO0FBRUEsU0FBTztBQUNIOUIsWUFBUSxFQUFFbFMsSUFBSSxDQUFDNlMsY0FEWjtBQUVIRix1QkFBbUIsRUFBRTNTLElBQUksQ0FBQytTLHNCQUZ2QjtBQUdIVCxhQUFTLEVBQUV0UyxJQUFJLENBQUNpVCxZQUhiO0FBSUhWLGtCQUFjLEVBQUV2UyxJQUFJLENBQUNrVCxpQkFKbEI7QUFLSGQscUJBQWlCLEVBQUVwUyxJQUFJLENBQUNxVCxvQkFMckI7QUFNSGhCLFFBQUksRUFBRXJTLElBQUksQ0FBQ3NULE9BTlI7QUFPSFYsWUFBUSxFQUFFNVMsSUFBSSxDQUFDdVQsV0FQWjtBQVFIcEIsY0FBVSxFQUFFblMsSUFBSSxDQUFDb1QsYUFSZDtBQVNIWCxxQkFBaUIsRUFBRXpTLElBQUksQ0FBQ3lTO0FBVHJCLEdBQVA7QUFXSDs7QUFFRCxTQUFTRCxTQUFULENBQW1CMkIsUUFBbkIsRUFBNkI7QUFFekI7QUFDQSxNQUFNblUsSUFBSSxHQUFHLElBQWI7QUFDQSxPQUFLb1UsWUFBTCxHQUFvQixFQUFwQixDQUp5QixDQU16Qjs7QUFDQSxPQUFLQyxhQUFMLEdBQXFCLENBQXJCO0FBQ0EsT0FBS0MsZUFBTCxHQUF1QixDQUF2QjtBQUNBLE9BQUtDLFdBQUwsR0FBbUIsQ0FBbkI7QUFDQSxPQUFLQyxlQUFMLEdBQXVCLENBQXZCO0FBQ0EsT0FBS0MsTUFBTCxHQUFjLEVBQWQ7QUFDQSxPQUFLM0osaUJBQUwsR0FBeUIsSUFBekI7QUFFQSxPQUFLcUosUUFBTCxHQUFnQixFQUFoQjs7QUFFQSxPQUFLM1UsSUFBTCxHQUFZLFlBQVk7QUFFcEI7QUFDQSxTQUFLMlUsUUFBTCxHQUFnQkEsUUFBaEIsQ0FIb0IsQ0FLcEI7O0FBQ0EsU0FBS0MsWUFBTCxHQUFvQjFVLFFBQVEsQ0FBQ0MsY0FBVCxDQUF3QixLQUFLd1UsUUFBTCxDQUFjakMsUUFBdEMsQ0FBcEI7QUFDQSxTQUFLdUMsTUFBTCxHQUFjL1UsUUFBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsS0FBS3VRLFFBQUwsQ0FBY2hDLFVBQXhDLENBQWQ7QUFDQSxTQUFLcUMsZUFBTCxHQUF1QixLQUFLQyxNQUFMLENBQVloUyxNQUFuQztBQUNBLFNBQUs0UixhQUFMLEdBQXFCLENBQXJCLENBVG9CLENBV3BCOztBQUNBLFFBQUlyVSxJQUFJLENBQUNtVSxRQUFMLENBQWN4QixtQkFBbEIsRUFBdUMsS0FBSytCLHVCQUFMLEdBWm5CLENBY3BCOztBQUNBLFNBQUtDLFFBQUwsR0Fmb0IsQ0FpQnBCOztBQUNBLFFBQU1qSixhQUFhLEdBQUcsSUFBSUMsTUFBSixDQUFXLEtBQUt5SSxZQUFoQixDQUF0QjtBQUNBMUksaUJBQWEsQ0FBQ0UsRUFBZCxDQUFpQixXQUFqQixFQUE4QixZQUFZO0FBQ3RDNUwsVUFBSSxDQUFDNFUsY0FBTDtBQUNBNVUsVUFBSSxDQUFDNlUsU0FBTDtBQUNBN1UsVUFBSSxDQUFDMlUsUUFBTDtBQUNILEtBSkQ7QUFLQWpKLGlCQUFhLENBQUNFLEVBQWQsQ0FBaUIsWUFBakIsRUFBK0IsWUFBWTtBQUN2QzVMLFVBQUksQ0FBQzRVLGNBQUw7QUFDQTVVLFVBQUksQ0FBQzhVLGFBQUw7QUFDQTlVLFVBQUksQ0FBQzJVLFFBQUw7QUFDSCxLQUpEOztBQVFBLFFBQUksS0FBS1IsUUFBTCxDQUFjL0IsaUJBQWQsS0FBb0MsRUFBeEMsRUFBNEM7QUFFeEM7QUFDQSxVQUFNQSxpQkFBaUIsR0FBRzFTLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLEtBQUt1USxRQUFMLENBQWMvQixpQkFBeEMsQ0FBMUI7QUFDQSxVQUFNMkMsdUJBQXVCLEdBQUczQyxpQkFBaUIsQ0FBQzNQLE1BQWxEOztBQUNBLFdBQUksSUFBSTBCLEdBQUMsR0FBRyxDQUFaLEVBQWVBLEdBQUMsR0FBRzRRLHVCQUFuQixFQUE0QzVRLEdBQUMsRUFBN0MsRUFBZ0Q7QUFDNUMsWUFBTTZRLGdCQUFnQixHQUFHNUMsaUJBQWlCLENBQUNqTyxHQUFELENBQTFDO0FBQ0E2USx3QkFBZ0IsQ0FBQzlTLGdCQUFqQixDQUFrQyxPQUFsQyxFQUEyQyxZQUFZO0FBQ25EbEMsY0FBSSxDQUFDaVYscUJBQUwsQ0FBMkIsSUFBM0I7QUFDSCxTQUZEO0FBR0g7QUFFSjs7QUFFRCxRQUFJLEtBQUtkLFFBQUwsQ0FBYzlCLElBQWQsS0FBdUIsRUFBM0IsRUFBK0I7QUFDM0I7QUFDQSxVQUFNQSxJQUFJLEdBQUczUyxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixLQUFLdVEsUUFBTCxDQUFjOUIsSUFBeEMsQ0FBYjtBQUNBLFVBQU02QyxVQUFVLEdBQUc3QyxJQUFJLENBQUM1UCxNQUF4QixDQUgyQixDQUkzQjtBQUNBOztBQUNBLFdBQUksSUFBSTBCLEdBQUMsR0FBRyxDQUFaLEVBQWVBLEdBQUMsR0FBRytRLFVBQW5CLEVBQStCL1EsR0FBQyxFQUFoQyxFQUFtQztBQUMvQixZQUFNZ1IsR0FBRyxHQUFHOUMsSUFBSSxDQUFDbE8sR0FBRCxDQUFoQixDQUQrQixDQUUvQjs7QUFDQWdSLFdBQUcsQ0FBQ2pULGdCQUFKLENBQXFCLE9BQXJCLEVBQThCLFlBQVk7QUFDdENsQyxjQUFJLENBQUNvVixRQUFMLENBQWMsSUFBZDtBQUNILFNBRkQ7QUFHSDtBQUVKOztBQUVEcFYsUUFBSSxDQUFDc1MsU0FBTDtBQUNILEdBL0REOztBQWtFQSxPQUFLQSxTQUFMLEdBQWlCLFlBQVc7QUFFeEIsUUFBRyxLQUFLeEgsaUJBQUwsS0FBMkIsSUFBOUIsRUFBb0N1SyxhQUFhLENBQUMsS0FBS3ZLLGlCQUFOLENBQWI7O0FBRXBDLFFBQUcsS0FBS3FKLFFBQUwsQ0FBYzdCLFNBQWQsSUFBMkJnRCxNQUFNLENBQUNDLFNBQVAsQ0FBaUIsS0FBS3BCLFFBQUwsQ0FBYzVCLGNBQS9CLENBQTlCLEVBQThFO0FBRTFFLFdBQUt6SCxpQkFBTCxHQUF5QjBLLFdBQVcsQ0FBQyxZQUFXO0FBQ3hDeFYsWUFBSSxDQUFDNlUsU0FBTDtBQUNBN1UsWUFBSSxDQUFDMlUsUUFBTDtBQUNILE9BSCtCLEVBRzdCLEtBQUtSLFFBQUwsQ0FBYzVCLGNBSGUsQ0FBcEM7QUFLSDtBQUNKLEdBWkQ7O0FBY0EsT0FBS3FDLGNBQUwsR0FBc0I1VSxJQUFJLENBQUNzUyxTQUEzQjs7QUFHQSxPQUFLdUMsU0FBTCxHQUFpQixZQUFZO0FBQ3pCLFNBQUtSLGFBQUw7QUFDQSxRQUFJLEtBQUtBLGFBQUwsSUFBc0IsS0FBS0csZUFBL0IsRUFBZ0QsS0FBS0gsYUFBTCxHQUFxQixDQUFyQjtBQUVoRCxRQUFJclUsSUFBSSxDQUFDbVUsUUFBTCxDQUFjeEIsbUJBQWxCLEVBQXVDLEtBQUsrQix1QkFBTDtBQUMxQyxHQUxEOztBQU9BLE9BQUtJLGFBQUwsR0FBcUIsWUFBWTtBQUM3QixTQUFLVCxhQUFMO0FBQ0EsUUFBSSxLQUFLQSxhQUFMLEdBQXFCLENBQXpCLEVBQTRCLEtBQUtBLGFBQUwsR0FBcUIsS0FBS0csZUFBTCxHQUF1QixDQUE1QztBQUU1QixRQUFJeFUsSUFBSSxDQUFDbVUsUUFBTCxDQUFjeEIsbUJBQWxCLEVBQXVDLEtBQUsrQix1QkFBTDtBQUMxQyxHQUxEOztBQU9BLE9BQUtBLHVCQUFMLEdBQStCLFlBQVk7QUFDdkMsU0FBS0gsV0FBTCxHQUFtQixLQUFLRixhQUFMLEdBQXFCLENBQXhDO0FBQ0EsUUFBSSxLQUFLRSxXQUFMLElBQW9CLEtBQUtDLGVBQTdCLEVBQThDLEtBQUtELFdBQUwsR0FBbUIsQ0FBbkI7QUFFOUMsU0FBS0QsZUFBTCxHQUF1QixLQUFLRCxhQUFMLEdBQXFCLENBQTVDO0FBQ0EsUUFBSSxLQUFLQyxlQUFMLEdBQXVCLENBQTNCLEVBQThCLEtBQUtBLGVBQUwsR0FBdUIsS0FBS0UsZUFBTCxHQUF1QixDQUE5QztBQUNqQyxHQU5EOztBQVFBLE9BQUtHLFFBQUwsR0FBZ0IsWUFBWTtBQUV4QjtBQUNBLFFBQU1jLFlBQVksR0FBR3pWLElBQUksQ0FBQ3lVLE1BQUwsQ0FBWWhTLE1BQWpDOztBQUNBLFNBQUksSUFBSTBCLEdBQUMsR0FBRyxDQUFaLEVBQWVBLEdBQUMsR0FBR3NSLFlBQW5CLEVBQWlDdFIsR0FBQyxFQUFsQyxFQUFxQztBQUNqQyxVQUFNMkksS0FBSyxHQUFHOU0sSUFBSSxDQUFDeVUsTUFBTCxDQUFZdFEsR0FBWixDQUFkLENBRGlDLENBR2pDOztBQUNBLFVBQU11UixVQUFVLEdBQUdDLFFBQVEsQ0FBQzdJLEtBQUssQ0FBQzdILFlBQU4sQ0FBbUIsWUFBbkIsQ0FBRCxDQUEzQixDQUppQyxDQU1qQzs7QUFDQSxVQUFJeVEsVUFBVSxLQUFLMVYsSUFBSSxDQUFDcVUsYUFBeEIsRUFBdUN2SCxLQUFLLENBQUM3SixTQUFOLENBQWdCRSxNQUFoQixDQUF1QixXQUF2QixFQUF2QyxLQUNLMkosS0FBSyxDQUFDN0osU0FBTixDQUFnQkMsR0FBaEIsQ0FBb0IsV0FBcEIsRUFSNEIsQ0FVakM7O0FBQ0EsVUFBSWxELElBQUksQ0FBQ21VLFFBQUwsQ0FBY3hCLG1CQUFsQixFQUF1QztBQUVuQyxZQUFJK0MsVUFBVSxLQUFLMVYsSUFBSSxDQUFDc1UsZUFBeEIsRUFBeUN4SCxLQUFLLENBQUM3SixTQUFOLENBQWdCRSxNQUFoQixDQUF1QixVQUF2QixFQUF6QyxLQUNLMkosS0FBSyxDQUFDN0osU0FBTixDQUFnQkMsR0FBaEIsQ0FBb0IsVUFBcEI7QUFFTCxZQUFJd1MsVUFBVSxLQUFLMVYsSUFBSSxDQUFDdVUsV0FBeEIsRUFBcUN6SCxLQUFLLENBQUM3SixTQUFOLENBQWdCRSxNQUFoQixDQUF1QixNQUF2QixFQUFyQyxLQUNLMkosS0FBSyxDQUFDN0osU0FBTixDQUFnQkMsR0FBaEIsQ0FBb0IsTUFBcEI7QUFDUjtBQUNKOztBQUVELFFBQUlsRCxJQUFJLENBQUNtVSxRQUFMLENBQWM5QixJQUFkLEtBQXVCLEVBQTNCLEVBQStCO0FBQUVyUyxVQUFJLENBQUM0VixZQUFMO0FBQXNCOztBQUN2RCxRQUFJNVYsSUFBSSxDQUFDbVUsUUFBTCxDQUFjdkIsUUFBZCxLQUEyQixFQUEvQixFQUFtQztBQUFFNVMsVUFBSSxDQUFDNlYsZ0JBQUw7QUFBMEI7QUFDbEUsR0EzQkQ7O0FBNkJBLE9BQUtaLHFCQUFMLEdBQTZCLFVBQVVhLFNBQVYsRUFBcUI7QUFDOUM5VixRQUFJLENBQUNxVSxhQUFMLEdBQXFCc0IsUUFBUSxDQUFDRyxTQUFTLENBQUM3USxZQUFWLENBQXVCLFlBQXZCLENBQUQsQ0FBN0I7QUFDQSxRQUFJakYsSUFBSSxDQUFDbVUsUUFBTCxDQUFjeEIsbUJBQWxCLEVBQXVDM1MsSUFBSSxDQUFDMFUsdUJBQUw7QUFDdkMxVSxRQUFJLENBQUMyVSxRQUFMO0FBRUEsUUFBTXhKLElBQUksR0FBR3pMLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUJ0QixJQUFJLENBQUNtVSxRQUFMLENBQWMvQixpQkFBZCxHQUFrQyxPQUF6RCxDQUFiO0FBQ0EsUUFBTWhILFFBQVEsR0FBRzFMLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUJ0QixJQUFJLENBQUNtVSxRQUFMLENBQWMvQixpQkFBZCxHQUFrQyxXQUF6RCxDQUFqQjtBQUVBakgsUUFBSSxDQUFDb0IsWUFBTCxDQUFrQixZQUFsQixFQUFnQ3ZNLElBQUksQ0FBQ3VVLFdBQXJDO0FBQ0FuSixZQUFRLENBQUNtQixZQUFULENBQXNCLFlBQXRCLEVBQW9Ddk0sSUFBSSxDQUFDc1UsZUFBekM7QUFFQXRVLFFBQUksQ0FBQzRVLGNBQUwsR0FYOEMsQ0FhOUM7QUFDQTtBQUNILEdBZkQ7O0FBaUJBLE9BQUtRLFFBQUwsR0FBZ0IsVUFBVVcsVUFBVixFQUFzQjtBQUNsQy9WLFFBQUksQ0FBQ3FVLGFBQUwsR0FBcUJzQixRQUFRLENBQUNJLFVBQVUsQ0FBQzlRLFlBQVgsQ0FBd0IsWUFBeEIsQ0FBRCxDQUE3QjtBQUNBakYsUUFBSSxDQUFDMlUsUUFBTDtBQUNBM1UsUUFBSSxDQUFDNFUsY0FBTDtBQUNILEdBSkQ7O0FBTUEsT0FBS2dCLFlBQUwsR0FBb0IsWUFBWTtBQUU1QixRQUFNdkQsSUFBSSxHQUFHM1MsUUFBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsS0FBS3VRLFFBQUwsQ0FBYzlCLElBQXhDLENBQWI7QUFDQSxRQUFNNkMsVUFBVSxHQUFHN0MsSUFBSSxDQUFDNVAsTUFBeEI7O0FBQ0EsU0FBSSxJQUFJMEIsR0FBQyxHQUFHLENBQVosRUFBZUEsR0FBQyxHQUFHK1EsVUFBbkIsRUFBK0IvUSxHQUFDLEVBQWhDLEVBQW1DO0FBQy9CLFVBQU1nUixHQUFHLEdBQUc5QyxJQUFJLENBQUNsTyxHQUFELENBQWhCO0FBQ0E2UixjQUFRLEdBQUdMLFFBQVEsQ0FBQ1IsR0FBRyxDQUFDbFEsWUFBSixDQUFpQixZQUFqQixDQUFELENBQW5CO0FBRUEsVUFBRytRLFFBQVEsS0FBS2hXLElBQUksQ0FBQ3FVLGFBQXJCLEVBQW9DYyxHQUFHLENBQUNsUyxTQUFKLENBQWNFLE1BQWQsQ0FBcUIsV0FBckIsRUFBcEMsS0FDS2dTLEdBQUcsQ0FBQ2xTLFNBQUosQ0FBY0MsR0FBZCxDQUFrQixXQUFsQjtBQUNSO0FBQ0osR0FYRDs7QUFhQSxPQUFLMlMsZ0JBQUwsR0FBd0IsWUFBWTtBQUVoQyxRQUFNakQsUUFBUSxHQUFHbFQsUUFBUSxDQUFDa0UsZ0JBQVQsQ0FBMEIsS0FBS3VRLFFBQUwsQ0FBY3ZCLFFBQXhDLENBQWpCO0FBQ0EsUUFBTXFELGNBQWMsR0FBR3JELFFBQVEsQ0FBQ25RLE1BQWhDOztBQUNBLFNBQUksSUFBSTBCLEdBQUMsR0FBRyxDQUFaLEVBQWVBLEdBQUMsR0FBRzhSLGNBQW5CLEVBQW1DOVIsR0FBQyxFQUFwQyxFQUF1QztBQUNuQyxVQUFNK1IsT0FBTyxHQUFHdEQsUUFBUSxDQUFDek8sR0FBRCxDQUF4QjtBQUNBZ1Msa0JBQVksR0FBR1IsUUFBUSxDQUFDTyxPQUFPLENBQUNqUixZQUFSLENBQXFCLFlBQXJCLENBQUQsQ0FBdkI7QUFFQSxVQUFHa1IsWUFBWSxLQUFLblcsSUFBSSxDQUFDcVUsYUFBekIsRUFBd0M2QixPQUFPLENBQUNqVCxTQUFSLENBQWtCRSxNQUFsQixDQUF5QixXQUF6QixFQUF4QyxLQUNLK1MsT0FBTyxDQUFDalQsU0FBUixDQUFrQkMsR0FBbEIsQ0FBc0IsV0FBdEI7QUFDUjtBQUNKLEdBWEQ7QUFZSCxDOzs7Ozs7Ozs7OztBQzVXRDs7O0FBSUEsSUFBTWtULGVBQWUsR0FBRztBQUVwQjtBQUNBQyxRQUFNLEVBQUcsRUFIVztBQUdQO0FBQ2JDLFVBQVEsRUFBRyxJQUpTO0FBSUg7QUFFakI7QUFDQTVTLE1BQUksRUFBRyxJQVBhO0FBUXBCNlMsT0FBSyxFQUFHLENBUlk7QUFTcEJDLFFBQU0sRUFBRyxDQVRXO0FBVXBCQyxhQUFXLEVBQUcsQ0FWTTtBQVdwQkMsZ0JBQWMsRUFBRyxLQVhHO0FBWXBCQyxtQkFBaUIsRUFBRyxJQVpBO0FBY3BCO0FBQ0FDLFFBQU0sRUFBRSxlQWZZO0FBaUJwQnBYLE1BQUksRUFBRyxnQkFBVTtBQUViLFFBQU1xWCxXQUFXLEdBQUduWCxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixzQkFBMUIsQ0FBcEI7QUFDQSxRQUFNa1QsaUJBQWlCLEdBQUdELFdBQVcsQ0FBQ3BVLE1BQXRDOztBQUVBLFNBQUksSUFBSTBCLENBQUMsR0FBRyxDQUFaLEVBQWVBLENBQUMsR0FBRzJTLGlCQUFuQixFQUFzQzNTLENBQUMsRUFBdkMsRUFBMkM7QUFFdkMsVUFBTTRTLFVBQVUsR0FBR0YsV0FBVyxDQUFDMVMsQ0FBRCxDQUE5QjtBQUVBNFMsZ0JBQVUsQ0FBQzdVLGdCQUFYLENBQTRCLE9BQTVCLEVBQXFDLFVBQVVpTixLQUFWLEVBQWlCO0FBQ2xEaUgsdUJBQWUsQ0FBQ1ksZUFBaEIsQ0FBZ0MsS0FBSy9SLFlBQUwsQ0FBa0IsTUFBbEIsQ0FBaEM7QUFDQWtLLGFBQUssQ0FBQzhILGNBQU47QUFDSCxPQUhEO0FBSUg7QUFDSixHQS9CbUI7O0FBaUNwQjs7O0FBR0FELGlCQUFlLEVBQUcseUJBQVNFLFNBQVQsRUFBbUI7QUFFakM7QUFDQUEsYUFBUyxHQUFHQSxTQUFTLENBQUNDLE1BQVYsQ0FBaUJELFNBQVMsQ0FBQzdSLE9BQVYsQ0FBa0IsR0FBbEIsSUFBdUIsQ0FBeEMsQ0FBWjtBQUNBLFFBQU0rUixlQUFlLEdBQUcxWCxRQUFRLENBQUNDLGNBQVQsQ0FBd0J1WCxTQUF4QixDQUF4QjtBQUNBLFFBQU1HLHVCQUF1QixHQUFHRCxlQUFlLENBQUNFLHFCQUFoQixFQUFoQyxDQUxpQyxDQU9qQzs7QUFDQWxCLG1CQUFlLENBQUMxUyxJQUFoQixHQUF1QmhFLFFBQVEsQ0FBQzZYLGVBQWhDO0FBQ0FuQixtQkFBZSxDQUFDRyxLQUFoQixHQUF3QmlCLElBQUksQ0FBQ0MsR0FBTCxDQUFTckIsZUFBZSxDQUFDMVMsSUFBaEIsQ0FBcUJnVSxTQUE5QixFQUF5Q2hZLFFBQVEsQ0FBQ2dFLElBQVQsQ0FBY2dVLFNBQXZELEVBQWtFalEsTUFBTSxDQUFDa1EsV0FBekUsQ0FBeEIsQ0FUaUMsQ0FTOEU7O0FBQy9HdkIsbUJBQWUsQ0FBQ0ksTUFBaEIsR0FBMkJhLHVCQUF1QixDQUFDOVAsR0FBeEIsR0FBOEI2TyxlQUFlLENBQUNHLEtBQS9DLEdBQXdESCxlQUFlLENBQUNHLEtBQXpFLEdBQWtGSCxlQUFlLENBQUNDLE1BQTNIO0FBQ0FELG1CQUFlLENBQUN3QixTQUFoQixHQUE0QixTQUFTblEsTUFBTSxDQUFDb1EsV0FBaEIsR0FBOEJBLFdBQVcsQ0FBQ0MsR0FBWixFQUE5QixHQUFrRCxJQUFJQyxJQUFKLEdBQVdDLE9BQVgsRUFBOUU7QUFDQTVCLG1CQUFlLENBQUNNLGNBQWhCLEdBQWlDLElBQWpDLENBWmlDLENBY2pDOztBQUNBQyxxQkFBaUIsR0FBR3NCLHFCQUFxQixDQUFDN0IsZUFBZSxDQUFDOEIsYUFBakIsQ0FBekMsQ0FmaUMsQ0FpQmpDOztBQUNBelEsVUFBTSxDQUFDdkYsZ0JBQVAsQ0FBd0IsV0FBeEIsRUFBcUNrVSxlQUFlLENBQUMrQixvQkFBckQ7QUFDQTFRLFVBQU0sQ0FBQ3ZGLGdCQUFQLENBQXdCLE9BQXhCLEVBQWlDa1UsZUFBZSxDQUFDK0Isb0JBQWpEO0FBQ0ExUSxVQUFNLENBQUN2RixnQkFBUCxDQUF3QixnQkFBeEIsRUFBMENrVSxlQUFlLENBQUMrQixvQkFBMUQ7QUFDQTFRLFVBQU0sQ0FBQ3ZGLGdCQUFQLENBQXdCLFlBQXhCLEVBQXNDa1UsZUFBZSxDQUFDK0Isb0JBQXREO0FBQ0ExUSxVQUFNLENBQUN2RixnQkFBUCxDQUF3QixPQUF4QixFQUFpQ2tVLGVBQWUsQ0FBQytCLG9CQUFqRDtBQUNBMVEsVUFBTSxDQUFDdkYsZ0JBQVAsQ0FBd0IsV0FBeEIsRUFBcUNrVSxlQUFlLENBQUMrQixvQkFBckQ7QUFFSCxHQTdEbUI7O0FBK0RwQjs7O0FBR0FELGVBQWEsRUFBRyx1QkFBVUUsU0FBVixFQUFxQjtBQUVqQztBQUNBLFFBQUlDLFFBQVEsR0FBR2IsSUFBSSxDQUFDYyxHQUFMLENBQVMsQ0FBVCxFQUFZLENBQUNGLFNBQVMsR0FBSWhDLGVBQWUsQ0FBQ3dCLFNBQTlCLElBQTJDeEIsZUFBZSxDQUFDRSxRQUF2RSxDQUFmO0FBQ0EsUUFBRytCLFFBQVEsR0FBRyxDQUFkLEVBQWlCQSxRQUFRLEdBQUcsQ0FBWCxDQUpnQixDQU1qQzs7QUFDQUEsWUFBUSxHQUFHRSxlQUFlLENBQUNuQyxlQUFlLENBQUNRLE1BQWpCLENBQWYsQ0FBd0N5QixRQUF4QyxDQUFYO0FBRUEsUUFBTUcsWUFBWSxHQUFHcEMsZUFBZSxDQUFDRyxLQUFoQixHQUEwQkgsZUFBZSxDQUFDSSxNQUFoQixHQUF5QjZCLFFBQXhFO0FBRUFqQyxtQkFBZSxDQUFDMVMsSUFBaEIsQ0FBcUJnVSxTQUFyQixHQUFpQ2MsWUFBakM7QUFDQSxRQUFJcEMsZUFBZSxDQUFDMVMsSUFBaEIsQ0FBcUJnVSxTQUFyQixLQUFtQyxDQUF2QyxFQUEyQ2hZLFFBQVEsQ0FBQ2dFLElBQVQsQ0FBY2dVLFNBQWQsR0FBMEJjLFlBQTFCLENBWlYsQ0FZa0Q7O0FBRW5GLFFBQUdILFFBQVEsR0FBRyxDQUFYLElBQWdCakMsZUFBZSxDQUFDTSxjQUFuQyxFQUFrRDtBQUM5Q0MsdUJBQWlCLEdBQUdzQixxQkFBcUIsQ0FBQzdCLGVBQWUsQ0FBQzhCLGFBQWpCLENBQXpDO0FBQ0g7QUFFSixHQXBGbUI7O0FBc0ZwQjs7O0FBR0FDLHNCQUFvQixFQUFHLDhCQUFVaEosS0FBVixFQUFpQjtBQUNwQ2lILG1CQUFlLENBQUNNLGNBQWhCLEdBQWlDLEtBQWpDO0FBQ0ErQix3QkFBb0IsQ0FBQ3JDLGVBQWUsQ0FBQ08saUJBQWpCLENBQXBCO0FBQ0g7QUE1Rm1CLENBQXhCO0FBZ0dBUCxlQUFlLENBQUM1VyxJQUFoQixHOzs7Ozs7Ozs7OztBQ3BHQSxJQUFJa1osa0JBQWtCLEdBQUcsRUFBekI7QUFFQSxJQUFNQywyQkFBMkIsR0FBR2paLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLHdCQUExQixDQUFwQztBQUNBLElBQU1nVixpQ0FBaUMsR0FBR0QsMkJBQTJCLENBQUNsVyxNQUF0RTs7QUFFQSxLQUFJLElBQUkwQixDQUFDLEdBQUUsQ0FBWCxFQUFjQSxDQUFDLEdBQUd5VSxpQ0FBbEIsRUFBcUR6VSxDQUFDLEVBQXRELEVBQXlEO0FBRXJELE1BQU0wVSxpQkFBaUIsR0FBR0YsMkJBQTJCLENBQUN4VSxDQUFELENBQXJEO0FBQ0EsTUFBTTJVLG1CQUFtQixHQUFHRCxpQkFBaUIsQ0FBQzVULFlBQWxCLENBQStCLElBQS9CLENBQTVCOztBQUVBLE1BQUc2VCxtQkFBbUIsS0FBSyxJQUEzQixFQUFnQztBQUU1QixRQUFNQyx3QkFBd0IsR0FBRyxJQUFJOUcsZ0JBQUosQ0FBcUI7QUFDbERDLGNBQVEsRUFBRTRHLG1CQUR3QztBQUVsRDNHLGdCQUFVLEVBQUUsTUFBTTJHLG1CQUFOLEdBQTJCLDhCQUZXO0FBR2xEMUcsdUJBQWlCLEVBQUUsTUFBTTBHLG1CQUFOLEdBQTJCLGdDQUhJO0FBSWxEeEcsZUFBUyxFQUFFLElBSnVDO0FBS2xEQyxvQkFBYyxFQUFFO0FBTGtDLEtBQXJCLENBQWpDO0FBUUFtRyxzQkFBa0IsQ0FBQ3JNLElBQW5CLENBQXlCLElBQUltRyxTQUFKLENBQWN1Ryx3QkFBd0IsQ0FBQ3RHLGlCQUF6QixFQUFkLEVBQTREalQsSUFBNUQsRUFBekI7QUFDSCxHQVhELE1BWUt1QixPQUFPLENBQUMwRCxHQUFSLENBQVksbUNBQVo7QUFDUjs7QUFHRCxTQUFTd04sZ0JBQVQsQ0FBMEJTLGNBQTFCLEVBQTBDO0FBRXRDLE1BQU0xUyxJQUFJLEdBQUcsSUFBYjtBQUVBLE9BQUtrUyxRQUFMLEdBQWdCLEVBQWhCO0FBQ0EsT0FBS1MsbUJBQUwsR0FBMkIsSUFBM0I7QUFDQSxPQUFLTCxTQUFMLEdBQWlCLEtBQWpCO0FBQ0EsT0FBS0MsY0FBTCxHQUFzQixLQUF0QjtBQUNBLE9BQUtILGlCQUFMLEdBQXlCLEVBQXpCO0FBQ0EsT0FBS0QsVUFBTCxHQUFrQixFQUFsQjs7QUFFQSxPQUFLVSxjQUFMLEdBQXNCLFVBQVVDLE1BQVYsRUFBa0I7QUFDcEMsU0FBS1osUUFBTCxHQUFnQlksTUFBaEI7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtDLHNCQUFMLEdBQThCLFVBQVVDLFFBQVYsRUFBbUI7QUFDN0MsU0FBS0wsbUJBQUwsR0FBMkJLLFFBQTNCO0FBQ0EsV0FBTyxJQUFQO0FBQ0gsR0FIRDs7QUFJQSxPQUFLQyxZQUFMLEdBQW9CLFVBQVVELFNBQVYsRUFBbUI7QUFDbkMsU0FBS1YsU0FBTCxHQUFpQlUsU0FBakI7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtFLGlCQUFMLEdBQXlCLFVBQVVDLE9BQVYsRUFBbUI7QUFDeEMsU0FBS1osY0FBTCxHQUFzQlksT0FBdEI7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtDLGFBQUwsR0FBcUIsVUFBVU4sTUFBVixFQUFrQjtBQUNuQyxTQUFLWCxVQUFMLEdBQWtCVyxNQUFsQjtBQUNBLFdBQU8sSUFBUDtBQUNILEdBSEQ7O0FBSUEsT0FBS08sb0JBQUwsR0FBNEIsVUFBVVAsTUFBVixFQUFrQjtBQUMxQyxTQUFLVixpQkFBTCxHQUF5QlUsTUFBekI7QUFDQSxXQUFPLElBQVA7QUFDSCxHQUhEOztBQUlBLE9BQUtVLGNBQUwsR0FBc0IsWUFBWTtBQUM5QixXQUFPLEtBQUt0QixRQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLdUIsc0JBQUwsR0FBOEIsWUFBWTtBQUN0QyxXQUFPLEtBQUtkLG1CQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLZSxZQUFMLEdBQW9CLFlBQVk7QUFDNUIsV0FBTyxLQUFLcEIsU0FBWjtBQUNILEdBRkQ7O0FBR0EsT0FBS3FCLGlCQUFMLEdBQXlCLFlBQVk7QUFDakMsV0FBTyxLQUFLcEIsY0FBWjtBQUNILEdBRkQ7O0FBR0EsT0FBS3FCLGFBQUwsR0FBcUIsWUFBWTtBQUM3QixXQUFPLEtBQUt6QixVQUFaO0FBQ0gsR0FGRDs7QUFHQSxPQUFLMEIsb0JBQUwsR0FBNEIsWUFBWTtBQUNwQyxXQUFPLEtBQUt6QixpQkFBWjtBQUNILEdBRkQsQ0FsRHNDLENBdUR0Qzs7O0FBQ0EsT0FBS0ssaUJBQUwsR0FBeUIsWUFBWTtBQUVqQyxXQUFPO0FBQ0hQLGNBQVEsRUFBRWxTLElBQUksQ0FBQ3dULGNBQUwsRUFEUDtBQUVIYix5QkFBbUIsRUFBRTNTLElBQUksQ0FBQ3lULHNCQUFMLEVBRmxCO0FBR0huQixlQUFTLEVBQUV0UyxJQUFJLENBQUMwVCxZQUFMLEVBSFI7QUFJSG5CLG9CQUFjLEVBQUV2UyxJQUFJLENBQUMyVCxpQkFBTCxFQUpiO0FBS0h2Qix1QkFBaUIsRUFBRXBTLElBQUksQ0FBQzZULG9CQUFMLEVBTGhCO0FBTUgxQixnQkFBVSxFQUFFblMsSUFBSSxDQUFDNFQsYUFBTDtBQU5ULEtBQVA7QUFTSCxHQVhELENBeERzQyxDQXFFdEM7OztBQUNBLE9BQUtJLElBQUwsR0FBWSxZQUFZO0FBQ3BCO0FBQ0E7QUFDQTtBQUVBLFFBQU1DLGtCQUFrQixHQUFHdE4sTUFBTSxDQUFDQyxJQUFQLENBQVk4TCxjQUFaLENBQTNCO0FBQ0EsUUFBTXdCLG9CQUFvQixHQUFHRCxrQkFBa0IsQ0FBQ3hSLE1BQWhEOztBQUVBLFNBQUksSUFBSTBCLEVBQUMsR0FBRyxDQUFaLEVBQWVBLEVBQUMsR0FBRytQLG9CQUFuQixFQUF5Qy9QLEVBQUMsRUFBMUMsRUFBNkM7QUFDekMsVUFBTXVMLEdBQUcsR0FBR3VFLGtCQUFrQixDQUFDOVAsRUFBRCxDQUE5QjtBQUNBbkUsVUFBSSxDQUFDMFAsR0FBRCxDQUFKLEdBQVlnRCxjQUFjLENBQUNoRCxHQUFELENBQTFCO0FBQ0g7QUFFSixHQWJEOztBQWVBLE9BQUtzRSxJQUFMO0FBRUEsU0FBTztBQUNIOUIsWUFBUSxFQUFFbFMsSUFBSSxDQUFDNlMsY0FEWjtBQUVIRix1QkFBbUIsRUFBRTNTLElBQUksQ0FBQytTLHNCQUZ2QjtBQUdIVCxhQUFTLEVBQUV0UyxJQUFJLENBQUNpVCxZQUhiO0FBSUhWLGtCQUFjLEVBQUV2UyxJQUFJLENBQUNrVCxpQkFKbEI7QUFLSGQscUJBQWlCLEVBQUVwUyxJQUFJLENBQUNxVCxvQkFMckI7QUFNSGxCLGNBQVUsRUFBRW5TLElBQUksQ0FBQ29ULGFBTmQ7QUFPSFgscUJBQWlCLEVBQUV6UyxJQUFJLENBQUN5UztBQVByQixHQUFQO0FBU0g7O0FBRUQsU0FBU0QsU0FBVCxDQUFtQjJCLFFBQW5CLEVBQTZCO0FBRXpCO0FBQ0EsTUFBTW5VLElBQUksR0FBRyxJQUFiO0FBQ0EsT0FBS29VLFlBQUwsR0FBb0IsRUFBcEIsQ0FKeUIsQ0FNekI7O0FBQ0EsT0FBS0MsYUFBTCxHQUFxQixDQUFyQjtBQUNBLE9BQUtDLGVBQUwsR0FBdUIsQ0FBdkI7QUFDQSxPQUFLQyxXQUFMLEdBQW1CLENBQW5CO0FBQ0EsT0FBS0MsZUFBTCxHQUF1QixDQUF2QjtBQUNBLE9BQUtDLE1BQUwsR0FBYyxFQUFkO0FBQ0EsT0FBSzNKLGlCQUFMLEdBQXlCLElBQXpCO0FBRUEsT0FBS3FKLFFBQUwsR0FBZ0IsRUFBaEI7O0FBRUEsT0FBSzNVLElBQUwsR0FBWSxZQUFZO0FBRXBCO0FBQ0EsU0FBSzJVLFFBQUwsR0FBZ0JBLFFBQWhCLENBSG9CLENBS3BCOztBQUNBLFNBQUtDLFlBQUwsR0FBb0IxVSxRQUFRLENBQUNDLGNBQVQsQ0FBd0IsS0FBS3dVLFFBQUwsQ0FBY2pDLFFBQXRDLENBQXBCO0FBQ0EsU0FBS3VDLE1BQUwsR0FBYy9VLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLEtBQUt1USxRQUFMLENBQWNoQyxVQUF4QyxDQUFkO0FBQ0EsU0FBS3FDLGVBQUwsR0FBdUIsS0FBS0MsTUFBTCxDQUFZaFMsTUFBbkM7QUFDQSxTQUFLNFIsYUFBTCxHQUFxQixDQUFyQixDQVRvQixDQVdwQjs7QUFDQSxRQUFJclUsSUFBSSxDQUFDbVUsUUFBTCxDQUFjeEIsbUJBQWxCLEVBQXVDLEtBQUsrQix1QkFBTCxHQVpuQixDQWNwQjs7QUFDQSxTQUFLQyxRQUFMLEdBZm9CLENBaUJwQjs7QUFDQSxRQUFNakosYUFBYSxHQUFHLElBQUlDLE1BQUosQ0FBVyxLQUFLeUksWUFBaEIsQ0FBdEI7QUFDQTFJLGlCQUFhLENBQUNFLEVBQWQsQ0FBaUIsV0FBakIsRUFBOEIsWUFBWTtBQUN0QzVMLFVBQUksQ0FBQzRVLGNBQUw7QUFDQTVVLFVBQUksQ0FBQzZVLFNBQUw7QUFDQTdVLFVBQUksQ0FBQzJVLFFBQUw7QUFDSCxLQUpEO0FBS0FqSixpQkFBYSxDQUFDRSxFQUFkLENBQWlCLFlBQWpCLEVBQStCLFlBQVk7QUFDdkM1TCxVQUFJLENBQUM0VSxjQUFMO0FBQ0E1VSxVQUFJLENBQUM4VSxhQUFMO0FBQ0E5VSxVQUFJLENBQUMyVSxRQUFMO0FBQ0gsS0FKRDs7QUFRQSxRQUFJLEtBQUtSLFFBQUwsQ0FBYy9CLGlCQUFkLEtBQW9DLEVBQXhDLEVBQTRDO0FBRXhDO0FBQ0EsVUFBTUEsaUJBQWlCLEdBQUcxUyxRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixLQUFLdVEsUUFBTCxDQUFjL0IsaUJBQXhDLENBQTFCO0FBQ0EsVUFBTTJDLHVCQUF1QixHQUFHM0MsaUJBQWlCLENBQUMzUCxNQUFsRDs7QUFDQSxXQUFJLElBQUkwQixHQUFDLEdBQUcsQ0FBWixFQUFlQSxHQUFDLEdBQUc0USx1QkFBbkIsRUFBNEM1USxHQUFDLEVBQTdDLEVBQWdEO0FBQzVDLFlBQU02USxnQkFBZ0IsR0FBRzVDLGlCQUFpQixDQUFDak8sR0FBRCxDQUExQztBQUNBNlEsd0JBQWdCLENBQUM5UyxnQkFBakIsQ0FBa0MsT0FBbEMsRUFBMkMsWUFBWTtBQUNuRGxDLGNBQUksQ0FBQ2lWLHFCQUFMLENBQTJCLElBQTNCO0FBQ0gsU0FGRDtBQUdIO0FBRUo7O0FBRURqVixRQUFJLENBQUNzUyxTQUFMO0FBQ0gsR0EvQ0Q7O0FBa0RBLE9BQUtBLFNBQUwsR0FBaUIsWUFBVztBQUV4QixRQUFHLEtBQUt4SCxpQkFBTCxLQUEyQixJQUE5QixFQUFvQ3VLLGFBQWEsQ0FBQyxLQUFLdkssaUJBQU4sQ0FBYjs7QUFFcEMsUUFBRyxLQUFLcUosUUFBTCxDQUFjN0IsU0FBZCxJQUEyQmdELE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQixLQUFLcEIsUUFBTCxDQUFjNUIsY0FBL0IsQ0FBOUIsRUFBOEU7QUFFMUUsV0FBS3pILGlCQUFMLEdBQXlCMEssV0FBVyxDQUFDLFlBQVc7QUFDeEN4VixZQUFJLENBQUM2VSxTQUFMO0FBQ0E3VSxZQUFJLENBQUMyVSxRQUFMO0FBQ0gsT0FIK0IsRUFHN0IsS0FBS1IsUUFBTCxDQUFjNUIsY0FIZSxDQUFwQztBQUtIO0FBQ0osR0FaRDs7QUFjQSxPQUFLcUMsY0FBTCxHQUFzQjVVLElBQUksQ0FBQ3NTLFNBQTNCOztBQUdBLE9BQUt1QyxTQUFMLEdBQWlCLFlBQVk7QUFDekIsU0FBS1IsYUFBTDtBQUNBLFFBQUksS0FBS0EsYUFBTCxJQUFzQixLQUFLRyxlQUEvQixFQUFnRCxLQUFLSCxhQUFMLEdBQXFCLENBQXJCO0FBRWhELFFBQUlyVSxJQUFJLENBQUNtVSxRQUFMLENBQWN4QixtQkFBbEIsRUFBdUMsS0FBSytCLHVCQUFMO0FBQzFDLEdBTEQ7O0FBT0EsT0FBS0ksYUFBTCxHQUFxQixZQUFZO0FBQzdCLFNBQUtULGFBQUw7QUFDQSxRQUFJLEtBQUtBLGFBQUwsR0FBcUIsQ0FBekIsRUFBNEIsS0FBS0EsYUFBTCxHQUFxQixLQUFLRyxlQUFMLEdBQXVCLENBQTVDO0FBRTVCLFFBQUl4VSxJQUFJLENBQUNtVSxRQUFMLENBQWN4QixtQkFBbEIsRUFBdUMsS0FBSytCLHVCQUFMO0FBQzFDLEdBTEQ7O0FBT0EsT0FBS0EsdUJBQUwsR0FBK0IsWUFBWTtBQUN2QyxTQUFLSCxXQUFMLEdBQW1CLEtBQUtGLGFBQUwsR0FBcUIsQ0FBeEM7QUFDQSxRQUFJLEtBQUtFLFdBQUwsSUFBb0IsS0FBS0MsZUFBN0IsRUFBOEMsS0FBS0QsV0FBTCxHQUFtQixDQUFuQjtBQUU5QyxTQUFLRCxlQUFMLEdBQXVCLEtBQUtELGFBQUwsR0FBcUIsQ0FBNUM7QUFDQSxRQUFJLEtBQUtDLGVBQUwsR0FBdUIsQ0FBM0IsRUFBOEIsS0FBS0EsZUFBTCxHQUF1QixLQUFLRSxlQUFMLEdBQXVCLENBQTlDO0FBQ2pDLEdBTkQ7O0FBUUEsT0FBS0csUUFBTCxHQUFnQixZQUFZO0FBRXhCO0FBQ0EsUUFBTWMsWUFBWSxHQUFHelYsSUFBSSxDQUFDeVUsTUFBTCxDQUFZaFMsTUFBakM7O0FBQ0EsU0FBSSxJQUFJMEIsR0FBQyxHQUFHLENBQVosRUFBZUEsR0FBQyxHQUFHc1IsWUFBbkIsRUFBaUN0UixHQUFDLEVBQWxDLEVBQXFDO0FBQ2pDLFVBQU0ySSxLQUFLLEdBQUc5TSxJQUFJLENBQUN5VSxNQUFMLENBQVl0USxHQUFaLENBQWQsQ0FEaUMsQ0FHakM7O0FBQ0EsVUFBTXVSLFVBQVUsR0FBR0MsUUFBUSxDQUFDN0ksS0FBSyxDQUFDN0gsWUFBTixDQUFtQixZQUFuQixDQUFELENBQTNCLENBSmlDLENBTWpDOztBQUNBLFVBQUl5USxVQUFVLEtBQUsxVixJQUFJLENBQUNxVSxhQUF4QixFQUF1Q3ZILEtBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLFdBQXZCLEVBQXZDLEtBQ0sySixLQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQixXQUFwQixFQVI0QixDQVVqQzs7QUFDQSxVQUFJbEQsSUFBSSxDQUFDbVUsUUFBTCxDQUFjeEIsbUJBQWxCLEVBQXVDO0FBRW5DLFlBQUkrQyxVQUFVLEtBQUsxVixJQUFJLENBQUNzVSxlQUF4QixFQUF5Q3hILEtBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLGFBQXZCLEVBQXpDLEtBQ0sySixLQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQixhQUFwQjtBQUVMLFlBQUl3UyxVQUFVLEtBQUsxVixJQUFJLENBQUN1VSxXQUF4QixFQUFxQ3pILEtBQUssQ0FBQzdKLFNBQU4sQ0FBZ0JFLE1BQWhCLENBQXVCLFNBQXZCLEVBQXJDLEtBQ0sySixLQUFLLENBQUM3SixTQUFOLENBQWdCQyxHQUFoQixDQUFvQixTQUFwQjtBQUNSO0FBQ0o7O0FBQ0QsUUFBTWlJLElBQUksR0FBR3pMLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUJ0QixJQUFJLENBQUNtVSxRQUFMLENBQWMvQixpQkFBZCxHQUFrQyxVQUF6RCxDQUFiO0FBQ0EsUUFBTWhILFFBQVEsR0FBRzFMLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUJ0QixJQUFJLENBQUNtVSxRQUFMLENBQWMvQixpQkFBZCxHQUFrQyxjQUF6RCxDQUFqQjtBQUVBakgsUUFBSSxDQUFDb0IsWUFBTCxDQUFrQixZQUFsQixFQUFnQ3ZNLElBQUksQ0FBQ3VVLFdBQXJDO0FBQ0FuSixZQUFRLENBQUNtQixZQUFULENBQXNCLFlBQXRCLEVBQW9Ddk0sSUFBSSxDQUFDc1UsZUFBekM7QUFDSCxHQTdCRDs7QUErQkEsT0FBS1cscUJBQUwsR0FBNkIsVUFBVWEsU0FBVixFQUFxQjtBQUM5QzlWLFFBQUksQ0FBQ3FVLGFBQUwsR0FBcUJzQixRQUFRLENBQUNHLFNBQVMsQ0FBQzdRLFlBQVYsQ0FBdUIsWUFBdkIsQ0FBRCxDQUE3QjtBQUNBLFFBQUlqRixJQUFJLENBQUNtVSxRQUFMLENBQWN4QixtQkFBbEIsRUFBdUMzUyxJQUFJLENBQUMwVSx1QkFBTDtBQUN2QzFVLFFBQUksQ0FBQzJVLFFBQUw7QUFDQTNVLFFBQUksQ0FBQzRVLGNBQUw7QUFDSCxHQUxEO0FBT0gsQzs7Ozs7Ozs7Ozs7QUMzUUQ7Ozs7QUFLQSxJQUFNb0UsYUFBYSxHQUFHO0FBRWxCeFosTUFBSSxFQUFFLGdCQUFZO0FBQ2QsUUFBTXlaLGNBQWMsR0FBR3ZaLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLG9CQUExQixDQUF2QjtBQUNBLFFBQU1zVixtQkFBbUIsR0FBR0QsY0FBYyxDQUFDeFcsTUFBM0M7O0FBRUEsUUFBR3dCLEtBQUssQ0FBQ2dWLGNBQUQsQ0FBTCxJQUF5QkMsbUJBQW1CLEdBQUcsQ0FBbEQsRUFBb0Q7QUFDaEQsV0FBSSxJQUFJL1UsQ0FBQyxHQUFHLENBQVosRUFBZUEsQ0FBQyxHQUFHK1UsbUJBQW5CLEVBQXdDL1UsQ0FBQyxFQUF6QyxFQUE0QztBQUN4QyxZQUFNZ1YsYUFBYSxHQUFHRixjQUFjLENBQUM5VSxDQUFELENBQXBDO0FBQ0E2VSxxQkFBYSxDQUFDSSxVQUFkLENBQXlCRCxhQUF6QjtBQUNIO0FBQ0o7QUFDSixHQVppQjtBQWNsQkMsWUFBVSxFQUFFLG9CQUFVRCxhQUFWLEVBQXlCO0FBQ2pDQSxpQkFBYSxDQUFDalgsZ0JBQWQsQ0FBK0IsT0FBL0IsRUFBd0M4VyxhQUFhLENBQUNLLFlBQXRELEVBQW9FLEtBQXBFO0FBQ0gsR0FoQmlCO0FBa0JsQkEsY0FBWSxFQUFFLHNCQUFVbEssS0FBVixFQUFpQjtBQUMzQixRQUFNaEMsRUFBRSxHQUFHZ0MsS0FBSyxDQUFDbUssYUFBTixDQUFvQnJVLFlBQXBCLENBQWlDLGdCQUFqQyxDQUFYO0FBQ0EsUUFBTXNVLFdBQVcsR0FBRyxHQUFHQyxLQUFILENBQVNDLElBQVQsQ0FBYy9aLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLG1CQUExQixDQUFkLENBQXBCO0FBQ0EsUUFBSXdMLE1BQU0sR0FBRyxJQUFiOztBQUVBLFNBQUssSUFBSWpMLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdvVixXQUFXLENBQUM5VyxNQUFoQyxFQUF3QzBCLENBQUMsRUFBekMsRUFBNkM7QUFDekMsVUFBR2dKLEVBQUUsS0FBS29NLFdBQVcsQ0FBQ3BWLENBQUQsQ0FBWCxDQUFlYyxZQUFmLENBQTRCLGdCQUE1QixDQUFWLEVBQXdEO0FBQ3BEbUssY0FBTSxHQUFHbUssV0FBVyxDQUFDcFYsQ0FBRCxDQUFwQjtBQUNIO0FBQ0osS0FUMEIsQ0FXM0I7OztBQUNBLFFBQUksQ0FBQ2lMLE1BQUwsRUFBYSxPQVpjLENBYzNCOztBQUNBRCxTQUFLLENBQUNtSyxhQUFOLENBQW9CclcsU0FBcEIsQ0FBOEJ3TyxNQUE5QixDQUFxQyxZQUFyQztBQUNIO0FBbENpQixDQUF0QjtBQXFDQXVILGFBQWEsQ0FBQ3haLElBQWQsRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFDQTtBQUNBOztJQUVNa2EsaUI7Ozs7Ozs7O0FBQ0Y7Ozs7eUNBSXFCQyxJLEVBQU07QUFDdkIsVUFBSTNaLElBQUksR0FBRyxJQUFYOztBQUVBLFVBQUcsRUFBRTJaLElBQUksWUFBWUMsUUFBbEIsQ0FBSCxFQUFnQztBQUM1QjdZLGVBQU8sQ0FBQ0MsS0FBUixDQUFjLDRHQUFkO0FBQ0EsZUFBT2YsT0FBTyxDQUFDRSxNQUFSLENBQWUsNEdBQWYsQ0FBUDtBQUNIOztBQUVELGFBQU8sSUFBSUYsT0FBSixDQUFZLFVBQVNDLE9BQVQsRUFBa0JDLE1BQWxCLEVBQTBCO0FBQ3pDQyxZQUFJLENBQUN5WixZQUFMLENBQ0ksMkJBREosRUFFSUYsSUFGSixFQUdJLFVBQVNyWixHQUFULEVBQWM7QUFDVixjQUFJQyxlQUFlLEdBQUdDLDBFQUFhLENBQUNDLEVBQWQsQ0FBaUJILEdBQUcsQ0FBQ0ksUUFBckIsRUFBK0IsS0FBL0IsQ0FBdEI7O0FBRUEsY0FBRyxDQUFDSCxlQUFKLEVBQXFCO0FBQ2pCTCxtQkFBTztBQUNWLFdBRkQsTUFFTztBQUNIQyxrQkFBTSxDQUFDSywwRUFBYSxDQUFDTSxjQUFkLENBQTZCUixHQUFHLENBQUNJLFFBQWpDLENBQUQsQ0FBTjtBQUNIO0FBQ0osU0FYTDtBQWFILE9BZE0sQ0FBUDtBQWVIOzs7Ozs7Ozs7Ozs7Ozs7OztBQy9CTDs7O0FBSUEsSUFBTW9aLGNBQWMsR0FBRztBQUVuQkMsY0FBWSxFQUFHLG9CQUZJO0FBR25CQyxTQUFPLEVBQUUsRUFIVTtBQUtuQnhhLE1BQUksRUFBRyxnQkFDUDtBQUNJO0FBQ0EsUUFBTXlhLGNBQWMsR0FBR3ZhLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCa1csY0FBYyxDQUFDQyxZQUF6QyxDQUF2QjtBQUNBLFFBQU1HLG9CQUFvQixHQUFHRCxjQUFjLENBQUN4WCxNQUE1Qzs7QUFFQSxTQUFJLElBQUkwQixDQUFDLEdBQUcsQ0FBWixFQUFlQSxDQUFDLEdBQUcrVixvQkFBbkIsRUFBeUMvVixDQUFDLEVBQTFDLEVBQTZDO0FBRXpDLFVBQU1nVyxhQUFhLEdBQUdGLGNBQWMsQ0FBQzlWLENBQUQsQ0FBcEM7QUFHQSxVQUFNaVcsZUFBZSxHQUFHRCxhQUFhLENBQUNsVixZQUFkLENBQTJCLElBQTNCLENBQXhCOztBQUNBLFVBQUdtVixlQUFlLEtBQUssSUFBdkIsRUFDQTtBQUNJO0FBQ0EsWUFBTUMsY0FBYyxHQUFHO0FBQ25CbE4sWUFBRSxFQUFFZ04sYUFBYSxDQUFDbFYsWUFBZCxDQUEyQixJQUEzQixDQURlO0FBRW5CcVYsY0FBSSxFQUFFSCxhQUFhLENBQUNsVixZQUFkLENBQTJCLG1CQUEzQixDQUZhO0FBR25Cc1Ysa0JBQVEsRUFBRTVFLFFBQVEsQ0FBQ3dFLGFBQWEsQ0FBQ2xWLFlBQWQsQ0FBMkIsZ0JBQTNCLENBQUQ7QUFIQyxTQUF2QjtBQU1BNlUsc0JBQWMsQ0FBQ0UsT0FBZixDQUF1QjNOLElBQXZCLENBQTRCZ08sY0FBNUI7QUFDSCxPQVZELE1BV0k7QUFDQXRaLGVBQU8sQ0FBQzBELEdBQVIsQ0FBWSw0REFBWjtBQUNBMUQsZUFBTyxDQUFDMEQsR0FBUixDQUFZMFYsYUFBWjtBQUNIO0FBQ0o7O0FBRUQsUUFBR0Qsb0JBQW9CLElBQUksQ0FBM0IsRUFBOEJKLGNBQWMsQ0FBQ1UsV0FBZjtBQUVqQyxHQXBDa0I7O0FBc0NuQjs7OztBQUlBQSxhQUFXLEVBQUUsdUJBQVc7QUFDcEI7QUFDQSxRQUFJLE9BQU9DLEVBQVAsSUFBYyxXQUFkLElBQTZCLE9BQU9BLEVBQUUsQ0FBQ0MsTUFBVixJQUFxQixXQUF0RCxFQUFtRTtBQUMvRDtBQUNBalQsWUFBTSxDQUFDa1QsdUJBQVAsR0FBaUMsWUFBVztBQUN4Q2Isc0JBQWMsQ0FBQ2MsV0FBZjtBQUNILE9BRkQsQ0FGK0QsQ0FLL0Q7OztBQUNBekssZUFBUyxDQUFDLG9DQUFELENBQVQsQ0FOK0QsQ0FPL0Q7QUFDSCxLQVJELE1BUU87QUFDSDJKLG9CQUFjLENBQUNjLFdBQWY7QUFDSDtBQUNKLEdBdkRrQjs7QUF5RG5COzs7OztBQUtBQSxhQUFXLEVBQUUsdUJBQVc7QUFFcEIsUUFBSVosT0FBTyxHQUFHLEVBQWQ7QUFFQSxRQUFNRSxvQkFBb0IsR0FBR0osY0FBYyxDQUFDRSxPQUFmLENBQXVCdlgsTUFBcEQ7O0FBQ0EsU0FBSSxJQUFJMEIsQ0FBQyxHQUFHLENBQVosRUFBZUEsQ0FBQyxHQUFHK1Ysb0JBQW5CLEVBQXlDL1YsQ0FBQyxFQUExQyxFQUE2QztBQUV6QyxVQUFJZ1csYUFBYSxHQUFHTCxjQUFjLENBQUNFLE9BQWYsQ0FBdUI3VixDQUF2QixDQUFwQixDQUZ5QyxDQUl6Qzs7QUFDQWdXLG1CQUFhLENBQUNVLE1BQWQsR0FBdUIsSUFBSUosRUFBRSxDQUFDQyxNQUFQLENBQWNQLGFBQWEsQ0FBQ2hOLEVBQTVCLEVBQStCO0FBQ2xEMk4sY0FBTSxFQUFFLEdBRDBDO0FBRWxEQyxhQUFLLEVBQUUsR0FGMkM7QUFHbERDLGVBQU8sRUFBRWIsYUFBYSxDQUFDRyxJQUgyQjtBQUlsRFcsWUFBSSxFQUFFLGtDQUo0QztBQUtsREMsa0JBQVUsRUFBRTtBQUNSQyx3QkFBYyxFQUFFLENBRFI7QUFFUkMsYUFBRyxFQUFFLENBRkc7QUFHUkMsbUJBQVMsRUFBRSxDQUhIO0FBSVJDLGtCQUFRLEVBQUVuQixhQUFhLENBQUNJO0FBSmhCLFNBTHNDO0FBV2xEZ0IsY0FBTSxFQUFFO0FBQ0o7QUFDQSwyQkFBaUJ6QixjQUFjLENBQUMwQjtBQUY1QjtBQVgwQyxPQUEvQixDQUF2QjtBQWlCQXhCLGFBQU8sQ0FBQ0csYUFBYSxDQUFDaE4sRUFBZixDQUFQLEdBQTRCZ04sYUFBNUI7QUFFSDs7QUFFREwsa0JBQWMsQ0FBQ0UsT0FBZixHQUF5QkEsT0FBekI7QUFFSCxHQS9Ga0I7O0FBaUduQjs7O0FBR0F5QixTQUFPLEVBQUcsaUJBQVN0TSxLQUFULEVBQWdCO0FBRXRCLFFBQU11TSxpQkFBaUIsR0FBR3ZNLEtBQUssQ0FBQ0MsTUFBTixDQUFhdU0sU0FBYixHQUF5QjFXLFlBQXpCLENBQXNDLElBQXRDLENBQTFCO0FBQ0EsUUFBTTRWLE1BQU0sR0FBR2YsY0FBYyxDQUFDRSxPQUFmLENBQXVCMEIsaUJBQXZCLEVBQTBDYixNQUF6RCxDQUhzQixDQUt0QjtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDSCxHQWhIa0I7O0FBa0huQjs7O0FBR0FXLGVBQWEsRUFBRyx1QkFBU3JNLEtBQVQsRUFBZ0I7QUFFNUIsUUFBTXVNLGlCQUFpQixHQUFHdk0sS0FBSyxDQUFDQyxNQUFOLENBQWF1TSxTQUFiLEdBQXlCMVcsWUFBekIsQ0FBc0MsSUFBdEMsQ0FBMUI7QUFDQSxRQUFNNFYsTUFBTSxHQUFHZixjQUFjLENBQUNFLE9BQWYsQ0FBdUIwQixpQkFBdkIsRUFBMENiLE1BQXpEO0FBRUEsUUFBTWUsVUFBVSxHQUFHek0sS0FBSyxDQUFDd0ssSUFBekIsQ0FMNEIsQ0FPNUI7O0FBQ0EsUUFBSXhLLEtBQUssQ0FBQ3dLLElBQU4sS0FBZWMsRUFBRSxDQUFDb0IsV0FBSCxDQUFlQyxLQUFsQyxFQUEwQztBQUN0Q2pCLFlBQU0sQ0FBQ2tCLFNBQVA7QUFDSDtBQUNKO0FBaElrQixDQUF2QjtBQW1JQWpDLGNBQWMsQ0FBQ3RhLElBQWYsRzs7Ozs7Ozs7Ozs7QUN2SUE7OztBQUlBLElBQU13YyxjQUFjLEdBQUc7QUFFbkJDLFdBQVMsRUFBRSxFQUZRO0FBR25CQyxhQUFXLEVBQUUsRUFITTtBQU1uQjFjLE1BQUksRUFBRSxnQkFBWTtBQUNkd2Msa0JBQWMsQ0FBQ0MsU0FBZixHQUEyQnhVLE1BQU0sQ0FBQzBVLFNBQVAsQ0FBaUJGLFNBQTVDO0FBQ0FELGtCQUFjLENBQUNFLFdBQWYsR0FBNkJGLGNBQWMsQ0FBQ0ksY0FBZixFQUE3QjtBQUNBSixrQkFBYyxDQUFDSyxRQUFmO0FBQ0FMLGtCQUFjLENBQUNNLFlBQWY7QUFDSCxHQVhrQjtBQWFuQkQsVUFBUSxFQUFFLG9CQUFZO0FBRWxCO0FBQ0EsUUFBSUUsSUFBSSxHQUFHUCxjQUFjLENBQUNDLFNBQWYsQ0FBeUI1VyxPQUF6QixDQUFpQyxPQUFqQyxDQUFYO0FBQ0EsUUFBTW1YLE1BQU0sR0FBR0QsSUFBSSxHQUFHLENBQXRCLENBSmtCLENBTWxCOztBQUNBLFFBQU1FLElBQUksR0FBRyxDQUFDLENBQUNOLFNBQVMsQ0FBQ0YsU0FBVixDQUFvQlMsS0FBcEIsQ0FBMEIsbUJBQTFCLENBQWYsQ0FQa0IsQ0FTbEI7O0FBQ0EsUUFBSUYsTUFBTSxJQUFJQyxJQUFkLEVBQW9CO0FBQ2hCO0FBQ0EsVUFBSUUsT0FBTyxHQUFHLElBQWQsQ0FGZ0IsQ0FJaEI7O0FBQ0EsVUFBSUgsTUFBSixFQUFZRyxPQUFPLEdBQUdoSCxRQUFRLENBQUNxRyxjQUFjLENBQUNDLFNBQWYsQ0FBeUI1TSxTQUF6QixDQUMzQmtOLElBQUksR0FBRyxDQURvQixFQUUzQlAsY0FBYyxDQUFDQyxTQUFmLENBQXlCNVcsT0FBekIsQ0FBaUMsR0FBakMsRUFBc0NrWCxJQUF0QyxDQUYyQixDQUFELENBQWxCLENBTEksQ0FVaEI7O0FBQ0E3YyxjQUFRLENBQUNnRSxJQUFULENBQWNULFNBQWQsQ0FBd0JDLEdBQXhCLENBQTRCLElBQTVCO0FBQ0F4RCxjQUFRLENBQUNnRSxJQUFULENBQWNULFNBQWQsQ0FBd0JDLEdBQXhCLENBQTRCLE1BQUl5WixPQUFoQztBQUNIO0FBRUosR0F0Q2tCO0FBd0NuQjtBQUNBTCxjQUFZLEVBQUUsd0JBQVk7QUFFdEIsUUFBR04sY0FBYyxDQUFDRSxXQUFmLENBQTJCelcsSUFBM0IsS0FBb0MsUUFBcEMsSUFBZ0R1VyxjQUFjLENBQUNFLFdBQWYsQ0FBMkJTLE9BQTNCLElBQXNDLEVBQXpGLEVBQTRGO0FBQ3hGamQsY0FBUSxDQUFDa2Qsb0JBQVQsQ0FBOEIsTUFBOUIsRUFBc0MsQ0FBdEMsRUFBeUMzWixTQUF6QyxDQUFtREMsR0FBbkQsQ0FBdUQsSUFBdkQ7QUFDSDtBQUVKLEdBL0NrQjtBQWlEbkJrWixnQkFBYyxFQUFFLDBCQUFZO0FBQ3hCLFFBQUlTLEVBQUUsR0FBQ1YsU0FBUyxDQUFDRixTQUFqQjtBQUFBLFFBQTJCYSxHQUEzQjtBQUFBLFFBQStCQyxDQUFDLEdBQUNGLEVBQUUsQ0FBQ0gsS0FBSCxDQUFTLDhEQUFULEtBQTRFLEVBQTdHOztBQUNBLFFBQUcsV0FBV00sSUFBWCxDQUFnQkQsQ0FBQyxDQUFDLENBQUQsQ0FBakIsQ0FBSCxFQUF5QjtBQUNyQkQsU0FBRyxHQUFDLGtCQUFrQkcsSUFBbEIsQ0FBdUJKLEVBQXZCLEtBQThCLEVBQWxDO0FBQ0EsYUFBTztBQUFDcFgsWUFBSSxFQUFDLEtBQU47QUFBWWtYLGVBQU8sRUFBRUcsR0FBRyxDQUFDLENBQUQsQ0FBSCxJQUFRO0FBQTdCLE9BQVA7QUFDSDs7QUFDRCxRQUFHQyxDQUFDLENBQUMsQ0FBRCxDQUFELEtBQU8sUUFBVixFQUFtQjtBQUNmRCxTQUFHLEdBQUNELEVBQUUsQ0FBQ0gsS0FBSCxDQUFTLGNBQVQsQ0FBSjs7QUFDQSxVQUFHSSxHQUFHLElBQUUsSUFBUixFQUFnQjtBQUFDLGVBQU87QUFBQ3JYLGNBQUksRUFBQyxPQUFOO0FBQWVrWCxpQkFBTyxFQUFDRyxHQUFHLENBQUMsQ0FBRDtBQUExQixTQUFQO0FBQXVDO0FBQzNEOztBQUNEQyxLQUFDLEdBQUNBLENBQUMsQ0FBQyxDQUFELENBQUQsR0FBTSxDQUFDQSxDQUFDLENBQUMsQ0FBRCxDQUFGLEVBQU9BLENBQUMsQ0FBQyxDQUFELENBQVIsQ0FBTixHQUFvQixDQUFDWixTQUFTLENBQUNlLE9BQVgsRUFBb0JmLFNBQVMsQ0FBQ2dCLFVBQTlCLEVBQTBDLElBQTFDLENBQXRCOztBQUNBLFFBQUcsQ0FBQ0wsR0FBRyxHQUFDRCxFQUFFLENBQUNILEtBQUgsQ0FBUyxpQkFBVCxDQUFMLEtBQW1DLElBQXRDLEVBQTRDO0FBQUNLLE9BQUMsQ0FBQ0ssTUFBRixDQUFTLENBQVQsRUFBVyxDQUFYLEVBQWFOLEdBQUcsQ0FBQyxDQUFELENBQWhCO0FBQXNCOztBQUNuRSxXQUFPO0FBQ0hyWCxVQUFJLEVBQUVzWCxDQUFDLENBQUMsQ0FBRCxDQURKO0FBRUhKLGFBQU8sRUFBRUksQ0FBQyxDQUFDLENBQUQ7QUFGUCxLQUFQO0FBSUg7QUFqRWtCLENBQXZCO0FBb0VBZixjQUFjLENBQUN4YyxJQUFmLEc7Ozs7Ozs7Ozs7O0FDeEVBOzs7O0FBSUE7OztBQUdBaUksTUFBTSxDQUFDeEQsS0FBUCxHQUFlLFVBQVVvWixHQUFWLEVBQWU7QUFDMUIsU0FBTyxPQUFPQSxHQUFQLEtBQWUsV0FBZixJQUE4QkEsR0FBRyxLQUFLLElBQTdDO0FBQ0gsQ0FGRDtBQUlBOzs7Ozs7QUFJQTVWLE1BQU0sQ0FBQzhRLGVBQVAsR0FBeUI7QUFDckI7QUFDQStFLFFBQU0sRUFBRSxnQkFBVUMsQ0FBVixFQUFhO0FBQ2pCLFdBQU9BLENBQVA7QUFDSCxHQUpvQjtBQUtyQjtBQUNBQyxZQUFVLEVBQUUsb0JBQVVELENBQVYsRUFBYTtBQUNyQixXQUFPQSxDQUFDLEdBQUdBLENBQVg7QUFDSCxHQVJvQjtBQVNyQjtBQUNBRSxhQUFXLEVBQUUscUJBQVVGLENBQVYsRUFBYTtBQUN0QixXQUFPQSxDQUFDLElBQUksSUFBSUEsQ0FBUixDQUFSO0FBQ0gsR0Fab0I7QUFhckI7QUFDQUcsZUFBYSxFQUFFLHVCQUFVSCxDQUFWLEVBQWE7QUFDeEIsV0FBT0EsQ0FBQyxHQUFHLEVBQUosR0FBUyxJQUFJQSxDQUFKLEdBQVFBLENBQWpCLEdBQXFCLENBQUMsQ0FBRCxHQUFLLENBQUMsSUFBSSxJQUFJQSxDQUFULElBQWNBLENBQS9DO0FBQ0gsR0FoQm9CO0FBaUJyQjtBQUNBSSxhQUFXLEVBQUUscUJBQVVKLENBQVYsRUFBYTtBQUN0QixXQUFPQSxDQUFDLEdBQUdBLENBQUosR0FBUUEsQ0FBZjtBQUNILEdBcEJvQjtBQXFCckI7QUFDQUssY0FBWSxFQUFFLHNCQUFVTCxDQUFWLEVBQWE7QUFDdkIsV0FBUSxFQUFFQSxDQUFILEdBQVFBLENBQVIsR0FBWUEsQ0FBWixHQUFnQixDQUF2QjtBQUNILEdBeEJvQjtBQXlCckI7QUFDQU0sZ0JBQWMsRUFBRSx3QkFBVU4sQ0FBVixFQUFhO0FBQ3pCLFdBQU9BLENBQUMsR0FBRyxFQUFKLEdBQVMsSUFBSUEsQ0FBSixHQUFRQSxDQUFSLEdBQVlBLENBQXJCLEdBQXlCLENBQUNBLENBQUMsR0FBRyxDQUFMLEtBQVcsSUFBSUEsQ0FBSixHQUFRLENBQW5CLEtBQXlCLElBQUlBLENBQUosR0FBUSxDQUFqQyxJQUFzQyxDQUF0RTtBQUNILEdBNUJvQjtBQTZCckI7QUFDQU8sYUFBVyxFQUFFLHFCQUFVUCxDQUFWLEVBQWE7QUFDdEIsV0FBT0EsQ0FBQyxHQUFHQSxDQUFKLEdBQVFBLENBQVIsR0FBWUEsQ0FBbkI7QUFDSCxHQWhDb0I7QUFpQ3JCO0FBQ0FRLGNBQVksRUFBRSxzQkFBVVIsQ0FBVixFQUFhO0FBQ3ZCLFdBQU8sSUFBSyxFQUFFQSxDQUFILEdBQVFBLENBQVIsR0FBWUEsQ0FBWixHQUFnQkEsQ0FBM0I7QUFDSCxHQXBDb0I7QUFxQ3JCO0FBQ0FTLGdCQUFjLEVBQUUsd0JBQVVULENBQVYsRUFBYTtBQUN6QixXQUFPQSxDQUFDLEdBQUcsRUFBSixHQUFTLElBQUlBLENBQUosR0FBUUEsQ0FBUixHQUFZQSxDQUFaLEdBQWdCQSxDQUF6QixHQUE2QixJQUFJLElBQUssRUFBRUEsQ0FBUCxHQUFZQSxDQUFaLEdBQWdCQSxDQUFoQixHQUFvQkEsQ0FBNUQ7QUFDSCxHQXhDb0I7QUF5Q3JCO0FBQ0FVLGFBQVcsRUFBRSxxQkFBVVYsQ0FBVixFQUFhO0FBQ3RCLFdBQU9BLENBQUMsR0FBR0EsQ0FBSixHQUFRQSxDQUFSLEdBQVlBLENBQVosR0FBZ0JBLENBQXZCO0FBQ0gsR0E1Q29CO0FBNkNyQjtBQUNBVyxjQUFZLEVBQUUsc0JBQVVYLENBQVYsRUFBYTtBQUN2QixXQUFPLElBQUssRUFBRUEsQ0FBSCxHQUFRQSxDQUFSLEdBQVlBLENBQVosR0FBZ0JBLENBQWhCLEdBQW9CQSxDQUEvQjtBQUNILEdBaERvQjtBQWlEckI7QUFDQVksZ0JBQWMsRUFBRSx3QkFBVVosQ0FBVixFQUFhO0FBQ3pCLFdBQU9BLENBQUMsR0FBRyxFQUFKLEdBQVMsS0FBS0EsQ0FBTCxHQUFTQSxDQUFULEdBQWFBLENBQWIsR0FBaUJBLENBQWpCLEdBQXFCQSxDQUE5QixHQUFrQyxJQUFJLEtBQU0sRUFBRUEsQ0FBUixHQUFhQSxDQUFiLEdBQWlCQSxDQUFqQixHQUFxQkEsQ0FBckIsR0FBeUJBLENBQXRFO0FBQ0g7QUFwRG9CLENBQXpCO0FBdURBOzs7O0FBR0E5VixNQUFNLENBQUMwSSxTQUFQLEdBQW1CLFVBQVVpTyxNQUFWLEVBQWtCQyxRQUFsQixFQUE0QjtBQUMzQyxNQUFJQyxNQUFNLEdBQUc1ZSxRQUFRLENBQUNpUCxhQUFULENBQXVCLFFBQXZCLENBQWI7QUFDQTJQLFFBQU0sQ0FBQ0MsS0FBUCxHQUFlLENBQWY7QUFFQSxNQUFNQyxPQUFPLEdBQUc5ZSxRQUFRLENBQUNrZCxvQkFBVCxDQUE4QixRQUE5QixDQUFoQjtBQUNBLE1BQUk2QixLQUFLLEdBQUdELE9BQU8sQ0FBQ0EsT0FBTyxDQUFDL2IsTUFBUixHQUFpQixDQUFsQixDQUFuQjs7QUFFQTZiLFFBQU0sQ0FBQ0ksTUFBUCxHQUFnQkosTUFBTSxDQUFDSyxrQkFBUCxHQUE0QixVQUFVQyxDQUFWLEVBQWFDLE9BQWIsRUFBc0I7QUFDOUQsUUFBSUEsT0FBTyxJQUFJLENBQUNQLE1BQU0sQ0FBQ1EsVUFBbkIsSUFBaUMsa0JBQWtCOUIsSUFBbEIsQ0FBdUJzQixNQUFNLENBQUNRLFVBQTlCLENBQXJDLEVBQWdGO0FBQzVFUixZQUFNLENBQUNJLE1BQVAsR0FBZ0JKLE1BQU0sQ0FBQ0ssa0JBQVAsR0FBNEIsSUFBNUM7QUFDQUwsWUFBTSxHQUFHUyxTQUFUOztBQUVBLFVBQUksQ0FBQ0YsT0FBTCxFQUFjO0FBQ1YsWUFBSVIsUUFBSixFQUFjQSxRQUFRO0FBQ3pCO0FBQ0o7QUFDSixHQVREOztBQVdBQyxRQUFNLENBQUNVLEdBQVAsR0FBYVosTUFBYjtBQUNBSyxPQUFLLENBQUN4VyxVQUFOLENBQWlCZ1gsWUFBakIsQ0FBOEJYLE1BQTlCLEVBQXNDRyxLQUF0QztBQUNILENBcEJEO0FBc0JBOzs7Ozs7Ozs7Ozs7QUFVQWhYLE1BQU0sQ0FBQ3lYLFFBQVAsR0FBa0IsVUFBU0MsSUFBVCxFQUFlQyxJQUFmLEVBQXFCQyxTQUFyQixFQUFnQztBQUM5QyxNQUFJQyxPQUFKO0FBQ0EsU0FBTyxZQUFZO0FBQ2YsUUFBSUMsT0FBTyxHQUFHLElBQWQ7QUFBQSxRQUFvQkMsSUFBSSxHQUFHQyxTQUEzQjs7QUFDQSxRQUFJQyxLQUFLLEdBQUcsU0FBUkEsS0FBUSxHQUFZO0FBQ3BCSixhQUFPLEdBQUcsSUFBVjtBQUNBLFVBQUksQ0FBQ0QsU0FBTCxFQUFnQkYsSUFBSSxDQUFDUSxLQUFMLENBQVdKLE9BQVgsRUFBb0JDLElBQXBCO0FBQ25CLEtBSEQ7O0FBSUEsUUFBSUksT0FBTyxHQUFHUCxTQUFTLElBQUksQ0FBQ0MsT0FBNUI7QUFDQS9ULGdCQUFZLENBQUMrVCxPQUFELENBQVo7QUFDQUEsV0FBTyxHQUFHaFYsVUFBVSxDQUFDb1YsS0FBRCxFQUFRTixJQUFSLENBQXBCO0FBQ0EsUUFBSVEsT0FBSixFQUFhVCxJQUFJLENBQUNRLEtBQUwsQ0FBV0osT0FBWCxFQUFvQkMsSUFBcEI7QUFDaEIsR0FWRDtBQVdILENBYkQ7QUFlQTs7Ozs7QUFHQS9YLE1BQU0sQ0FBQ3lDLE1BQVAsR0FBZ0I7QUFDWkUsS0FBRyxFQUFFLGFBQVUzRSxJQUFWLEVBQWdCdEQsS0FBaEIsRUFBdUIwZCxJQUF2QixFQUE2QjtBQUM5QixRQUFJQyxNQUFKLEVBQVlDLFdBQVosRUFBeUJDLElBQXpCLEVBQStCQyxPQUEvQixFQUF3Q2hGLElBQXhDOztBQUVBLFFBQUk0RSxJQUFKLEVBQVU7QUFDTkcsVUFBSSxHQUFHLElBQUlqSSxJQUFKLEVBQVA7QUFDQWlJLFVBQUksQ0FBQ0UsT0FBTCxDQUFhRixJQUFJLENBQUNoSSxPQUFMLEtBQWtCNkgsSUFBSSxHQUFHLEVBQVAsR0FBWSxFQUFaLEdBQWlCLEVBQWpCLEdBQXNCLElBQXJEO0FBQ0FJLGFBQU8sR0FBRyxlQUFlRCxJQUFJLENBQUNHLFdBQUwsRUFBekI7QUFDSCxLQUpELE1BS0s7QUFDREYsYUFBTyxHQUFHLEVBQVY7QUFDSDs7QUFFRGhGLFFBQUksR0FBRzdTLFFBQVEsQ0FBQzZTLElBQWhCOztBQUNBLFFBQUlBLElBQUksQ0FBQ25NLEtBQUwsQ0FBVyxHQUFYLEVBQWdCck0sTUFBaEIsS0FBMkIsQ0FBL0IsRUFBa0M7QUFDOUI7QUFDQS9DLGNBQVEsQ0FBQzBnQixNQUFULEdBQWtCM2EsSUFBSSxHQUFHLEdBQVAsR0FBYXRELEtBQWIsR0FBcUI4ZCxPQUFyQixHQUErQixVQUFqRDtBQUNILEtBSEQsTUFJSztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBRixpQkFBVyxHQUFHOUUsSUFBSSxDQUFDbk0sS0FBTCxDQUFXLEdBQVgsQ0FBZDtBQUNBaVIsaUJBQVcsQ0FBQ00sS0FBWjtBQUNBUCxZQUFNLEdBQUcsTUFBTUMsV0FBVyxDQUFDTyxJQUFaLENBQWlCLEdBQWpCLENBQWYsQ0FaQyxDQWNEO0FBQ0E7O0FBRUE1Z0IsY0FBUSxDQUFDMGdCLE1BQVQsR0FBa0IzYSxJQUFJLEdBQUcsR0FBUCxHQUFhdEQsS0FBYixHQUFxQjhkLE9BQXJCLEdBQStCLG1CQUEvQixHQUFxREgsTUFBdkUsQ0FqQkMsQ0FtQkQ7QUFDQTs7QUFDQSxVQUFJNVYsTUFBTSxDQUFDQyxHQUFQLENBQVcxRSxJQUFYLEtBQW9CLElBQXBCLElBQTRCeUUsTUFBTSxDQUFDQyxHQUFQLENBQVcxRSxJQUFYLEtBQW9CdEQsS0FBcEQsRUFBMkQ7QUFDdkQ7QUFDQTJkLGNBQU0sR0FBRyxNQUFNN0UsSUFBZjtBQUNBdmIsZ0JBQVEsQ0FBQzBnQixNQUFULEdBQWtCM2EsSUFBSSxHQUFHLEdBQVAsR0FBYXRELEtBQWIsR0FBcUI4ZCxPQUFyQixHQUErQixtQkFBL0IsR0FBcURILE1BQXZFO0FBQ0g7QUFDSjtBQUNKLEdBN0NXO0FBK0NaM1YsS0FBRyxFQUFFLGFBQVUxRSxJQUFWLEVBQWdCO0FBQ2pCLFFBQU04YSxNQUFNLEdBQUc5YSxJQUFJLEdBQUcsR0FBdEI7QUFDQSxRQUFNK2EsRUFBRSxHQUFHOWdCLFFBQVEsQ0FBQzBnQixNQUFULENBQWdCdFIsS0FBaEIsQ0FBc0IsR0FBdEIsQ0FBWDs7QUFDQSxTQUFLLElBQUkzSyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHcWMsRUFBRSxDQUFDL2QsTUFBdkIsRUFBK0IwQixDQUFDLEVBQWhDLEVBQW9DO0FBQ2hDLFVBQUlzYyxDQUFDLEdBQUdELEVBQUUsQ0FBQ3JjLENBQUQsQ0FBVjs7QUFDQSxhQUFPc2MsQ0FBQyxDQUFDQyxNQUFGLENBQVMsQ0FBVCxNQUFnQixHQUF2QixFQUE0QjtBQUN4QkQsU0FBQyxHQUFHQSxDQUFDLENBQUNwUixTQUFGLENBQVksQ0FBWixFQUFlb1IsQ0FBQyxDQUFDaGUsTUFBakIsQ0FBSjtBQUNIOztBQUVELFVBQUlnZSxDQUFDLENBQUNwYixPQUFGLENBQVVrYixNQUFWLE1BQXNCLENBQTFCLEVBQTZCLE9BQU9FLENBQUMsQ0FBQ3BSLFNBQUYsQ0FBWWtSLE1BQU0sQ0FBQzlkLE1BQW5CLEVBQTJCZ2UsQ0FBQyxDQUFDaGUsTUFBN0IsQ0FBUDtBQUNoQzs7QUFDRCxXQUFPLElBQVA7QUFDSCxHQTNEVztBQTZEWjRILE9BQUssRUFBRSxlQUFVNUUsSUFBVixFQUFnQjtBQUNuQnlFLFVBQU0sQ0FBQ0UsR0FBUCxDQUFXM0UsSUFBWCxFQUFpQixFQUFqQixFQUFxQixDQUFDLENBQXRCO0FBQ0g7QUEvRFcsQ0FBaEI7QUFrRUE7Ozs7QUFHQWdDLE1BQU0sQ0FBQ2taLGFBQVAsR0FBdUIsVUFBVUMsTUFBVixFQUFrQkMsUUFBbEIsRUFBNEJDLFNBQTVCLEVBQXVDQyxhQUF2QyxFQUFzRDtBQUN6RTtBQUNBSCxRQUFNLEdBQUcsQ0FBQ0EsTUFBTSxHQUFHLEVBQVYsRUFBY0ksT0FBZCxDQUFzQixlQUF0QixFQUF1QyxFQUF2QyxDQUFUOztBQUNBLE1BQUlDLENBQUMsR0FBRyxDQUFDQyxRQUFRLENBQUMsQ0FBQ04sTUFBRixDQUFULEdBQXFCLENBQXJCLEdBQXlCLENBQUNBLE1BQWxDO0FBQUEsTUFDSU8sSUFBSSxHQUFHLENBQUNELFFBQVEsQ0FBQyxDQUFDTCxRQUFGLENBQVQsR0FBdUIsQ0FBdkIsR0FBMkJySixJQUFJLENBQUM0SixHQUFMLENBQVNQLFFBQVQsQ0FEdEM7QUFBQSxNQUVJUSxHQUFHLEdBQUksT0FBT04sYUFBUCxLQUF5QixXQUExQixHQUF5QyxHQUF6QyxHQUErQ0EsYUFGekQ7QUFBQSxNQUdJTyxHQUFHLEdBQUksT0FBT1IsU0FBUCxLQUFxQixXQUF0QixHQUFxQyxHQUFyQyxHQUEyQ0EsU0FIckQ7QUFBQSxNQUlJUyxDQUFDLEdBQUcsRUFKUjtBQUFBLE1BS0lDLFVBQVUsR0FBRyxTQUFiQSxVQUFhLENBQVVQLENBQVYsRUFBYUUsSUFBYixFQUFtQjtBQUM1QixRQUFJTSxDQUFDLEdBQUdqSyxJQUFJLENBQUNrSyxHQUFMLENBQVMsRUFBVCxFQUFhUCxJQUFiLENBQVI7QUFDQSxXQUFPLEtBQUszSixJQUFJLENBQUNtSyxLQUFMLENBQVdWLENBQUMsR0FBR1EsQ0FBZixJQUFvQkEsQ0FBaEM7QUFDSCxHQVJMLENBSHlFLENBWXpFOzs7QUFDQUYsR0FBQyxHQUFHLENBQUNKLElBQUksR0FBR0ssVUFBVSxDQUFDUCxDQUFELEVBQUlFLElBQUosQ0FBYixHQUF5QixLQUFLM0osSUFBSSxDQUFDbUssS0FBTCxDQUFXVixDQUFYLENBQW5DLEVBQWtEblMsS0FBbEQsQ0FBd0QsR0FBeEQsQ0FBSjs7QUFDQSxNQUFJeVMsQ0FBQyxDQUFDLENBQUQsQ0FBRCxDQUFLOWUsTUFBTCxHQUFjLENBQWxCLEVBQXFCO0FBQ2pCOGUsS0FBQyxDQUFDLENBQUQsQ0FBRCxHQUFPQSxDQUFDLENBQUMsQ0FBRCxDQUFELENBQUtQLE9BQUwsQ0FBYSx5QkFBYixFQUF3Q0ssR0FBeEMsQ0FBUDtBQUNIOztBQUNELE1BQUksQ0FBQ0UsQ0FBQyxDQUFDLENBQUQsQ0FBRCxJQUFRLEVBQVQsRUFBYTllLE1BQWIsR0FBc0IwZSxJQUExQixFQUFnQztBQUM1QkksS0FBQyxDQUFDLENBQUQsQ0FBRCxHQUFPQSxDQUFDLENBQUMsQ0FBRCxDQUFELElBQVEsRUFBZjtBQUNBQSxLQUFDLENBQUMsQ0FBRCxDQUFELElBQVEsSUFBSUssS0FBSixDQUFVVCxJQUFJLEdBQUdJLENBQUMsQ0FBQyxDQUFELENBQUQsQ0FBSzllLE1BQVosR0FBcUIsQ0FBL0IsRUFBa0M2ZCxJQUFsQyxDQUF1QyxHQUF2QyxDQUFSO0FBQ0g7O0FBQ0QsU0FBT2lCLENBQUMsQ0FBQ2pCLElBQUYsQ0FBT2dCLEdBQVAsQ0FBUDtBQUNILENBdEJEO0FBeUJBOzs7Ozs7QUFJQSxJQUFJLENBQUNPLE9BQU8sQ0FBQ0MsU0FBUixDQUFrQkMsT0FBdkIsRUFBZ0M7QUFDNUIsTUFBSSxDQUFDRixPQUFPLENBQUNDLFNBQVIsQ0FBa0JFLE9BQXZCLEVBQWdDO0FBQzVCSCxXQUFPLENBQUNDLFNBQVIsQ0FBa0JFLE9BQWxCLEdBQTRCSCxPQUFPLENBQUNDLFNBQVIsQ0FBa0JHLGlCQUFsQixJQUF1Q0osT0FBTyxDQUFDQyxTQUFSLENBQWtCSSxxQkFBckY7QUFDSDs7QUFDREwsU0FBTyxDQUFDQyxTQUFSLENBQWtCQyxPQUFsQixHQUE0QixVQUFVUixDQUFWLEVBQWE7QUFDckMsUUFBSVksRUFBRSxHQUFHLElBQVQ7QUFDQSxRQUFJQyxRQUFRLEdBQUcsSUFBZjtBQUNBLFFBQUksQ0FBQzFpQixRQUFRLENBQUM2WCxlQUFULENBQXlCclAsUUFBekIsQ0FBa0NpYSxFQUFsQyxDQUFMLEVBQTRDLE9BQU8sSUFBUDs7QUFDNUMsT0FBRztBQUNDLFVBQUlDLFFBQVEsQ0FBQ0osT0FBVCxDQUFpQlQsQ0FBakIsQ0FBSixFQUF5QixPQUFPYSxRQUFQO0FBQ3pCQSxjQUFRLEdBQUdBLFFBQVEsQ0FBQ0MsYUFBcEI7QUFDSCxLQUhELFFBR1NELFFBQVEsS0FBSyxJQUh0Qjs7QUFJQSxXQUFPLElBQVA7QUFDSCxHQVREO0FBVUg7O0FBRUQzYSxNQUFNLENBQUNySCxJQUFQLEdBQWM7QUFFVjtBQUVBK0osS0FBRyxFQUFFLGFBQVMrQyxHQUFULEVBQWNtUixRQUFkLEVBQXdCO0FBQ3pCLFFBQUkvZCxHQUFHLEdBQUcsSUFBSWdpQixjQUFKLEVBQVY7QUFDQSxRQUFJQyxLQUFLLEdBQUc3aUIsUUFBUSxDQUFDNEIsYUFBVCxDQUF1Qix5QkFBdkIsRUFBa0RraEIsT0FBOUQ7QUFFQWxpQixPQUFHLENBQUNtaUIsSUFBSixDQUFTLEtBQVQsRUFBZ0J2VixHQUFoQixFQUFxQixJQUFyQjtBQUNBNU0sT0FBRyxDQUFDb2lCLGdCQUFKLENBQXFCLGNBQXJCLEVBQXFDLGtCQUFyQztBQUNBcGlCLE9BQUcsQ0FBQ29pQixnQkFBSixDQUFxQixjQUFyQixFQUFxQ0gsS0FBckM7QUFDQWppQixPQUFHLENBQUNvaUIsZ0JBQUosQ0FBcUIsa0JBQXJCLEVBQXlDLGdCQUF6Qzs7QUFDQXBpQixPQUFHLENBQUNxZSxrQkFBSixHQUF5QixZQUFXO0FBQ2hDLFVBQUlyZSxHQUFHLENBQUN3ZSxVQUFKLEtBQW1CLENBQXZCLEVBQTBCO0FBQ3RCVCxnQkFBUSxDQUFDL2QsR0FBRCxDQUFSO0FBQ0g7QUFDSixLQUpEOztBQUtBQSxPQUFHLENBQUNxaUIsSUFBSjtBQUNILEdBbEJTO0FBb0JWdGlCLE1BQUksRUFBRSxjQUFTNk0sR0FBVCxFQUFjeU0sSUFBZCxFQUFvQjBFLFFBQXBCLEVBQThCO0FBQ2hDLFFBQUkvZCxHQUFHLEdBQUcsSUFBSWdpQixjQUFKLEVBQVY7QUFDQSxRQUFJQyxLQUFLLEdBQUc3aUIsUUFBUSxDQUFDNEIsYUFBVCxDQUF1Qix5QkFBdkIsRUFBa0RraEIsT0FBOUQ7QUFFQWxpQixPQUFHLENBQUNtaUIsSUFBSixDQUFTLE1BQVQsRUFBaUJ2VixHQUFqQixFQUFzQixJQUF0QjtBQUNBNU0sT0FBRyxDQUFDb2lCLGdCQUFKLENBQXFCLGNBQXJCLEVBQXFDLGtCQUFyQztBQUNBcGlCLE9BQUcsQ0FBQ29pQixnQkFBSixDQUFxQixjQUFyQixFQUFxQ0gsS0FBckM7QUFDQWppQixPQUFHLENBQUNvaUIsZ0JBQUosQ0FBcUIsa0JBQXJCLEVBQXlDLGdCQUF6Qzs7QUFDQXBpQixPQUFHLENBQUNxZSxrQkFBSixHQUF5QixZQUFXO0FBQ2hDLFVBQUlyZSxHQUFHLENBQUN3ZSxVQUFKLEtBQW1CLENBQXZCLEVBQTBCO0FBQ3RCVCxnQkFBUSxDQUFDL2QsR0FBRCxDQUFSO0FBQ0g7QUFDSixLQUpEOztBQUtBQSxPQUFHLENBQUNxaUIsSUFBSixDQUFVN2MsSUFBSSxDQUFDOGMsU0FBTCxDQUFlakosSUFBZixDQUFWO0FBQ0gsR0FsQ1M7QUFvQ1ZFLGNBQVksRUFBRSxzQkFBUzNNLEdBQVQsRUFBY3lNLElBQWQsRUFBb0IwRSxRQUFwQixFQUE4QjtBQUN4QyxRQUFJL2QsR0FBRyxHQUFHLElBQUlnaUIsY0FBSixFQUFWO0FBQ0EsUUFBSUMsS0FBSyxHQUFHN2lCLFFBQVEsQ0FBQzRCLGFBQVQsQ0FBdUIseUJBQXZCLEVBQWtEa2hCLE9BQTlEO0FBRUFsaUIsT0FBRyxDQUFDbWlCLElBQUosQ0FBUyxNQUFULEVBQWlCdlYsR0FBakIsRUFBc0IsSUFBdEI7QUFDQTVNLE9BQUcsQ0FBQ29pQixnQkFBSixDQUFxQixjQUFyQixFQUFxQ0gsS0FBckM7QUFDQWppQixPQUFHLENBQUNvaUIsZ0JBQUosQ0FBcUIsa0JBQXJCLEVBQXlDLGdCQUF6Qzs7QUFDQXBpQixPQUFHLENBQUNxZSxrQkFBSixHQUF5QixZQUFXO0FBQ2hDLFVBQUlyZSxHQUFHLENBQUN3ZSxVQUFKLEtBQW1CLENBQXZCLEVBQTBCO0FBQ3RCVCxnQkFBUSxDQUFDL2QsR0FBRCxDQUFSO0FBQ0g7QUFDSixLQUpEOztBQUtBQSxPQUFHLENBQUNxaUIsSUFBSixDQUFTaEosSUFBVDtBQUNIO0FBakRTLENBQWQ7QUFvREE7Ozs7OztBQUtBbFMsTUFBTSxDQUFDSCxxQkFBUCxHQUErQixVQUFVd0wsTUFBVixFQUFrQjtBQUM3QyxTQUFPQSxNQUFNLENBQUM0TixNQUFQLENBQWMsQ0FBZCxFQUFpQm1DLFdBQWpCLEtBQWlDL1AsTUFBTSxDQUFDMEcsS0FBUCxDQUFhLENBQWIsQ0FBeEM7QUFDSCxDQUZEO0FBSUE7Ozs7Ozs7O0FBTUEvUixNQUFNLENBQUNxYixZQUFQLEdBQXNCLFVBQVVoUSxNQUFWLEVBQWlCO0FBQ25DLFNBQU9BLE1BQU0sQ0FBQ2tPLE9BQVAsQ0FBZSxTQUFmLEVBQTBCLFVBQVMrQixDQUFULEVBQVc7QUFBQyxXQUFPQSxDQUFDLENBQUMsQ0FBRCxDQUFELENBQUtGLFdBQUwsRUFBUDtBQUEyQixHQUFqRSxDQUFQO0FBQ0gsQ0FGRDtBQUlBOzs7OztBQUdBcGIsTUFBTSxDQUFDdWIsYUFBUCxHQUFzQixVQUFVelUsSUFBVixFQUFnQjtBQUNsQyxNQUFNbEwsUUFBUSxHQUFHa0wsSUFBSSxDQUFDdEcsVUFBTCxDQUFnQmdiLFVBQWpDO0FBQ0EsTUFBSUMsR0FBRyxHQUFHLENBQVY7O0FBQ0EsT0FBSyxJQUFJL2UsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR2QsUUFBUSxDQUFDWixNQUE3QixFQUFxQzBCLENBQUMsRUFBdEMsRUFBMEM7QUFDdEMsUUFBSWQsUUFBUSxDQUFDYyxDQUFELENBQVIsSUFBZW9LLElBQW5CLEVBQXlCLE9BQU8yVSxHQUFQO0FBQ3pCLFFBQUk3ZixRQUFRLENBQUNjLENBQUQsQ0FBUixDQUFZZ2YsUUFBWixJQUF3QixDQUE1QixFQUErQkQsR0FBRztBQUNyQzs7QUFDRCxTQUFPLENBQUMsQ0FBUjtBQUNILENBUkQ7QUFVQTs7Ozs7Ozs7QUFNQXpiLE1BQU0sQ0FBQzJiLGVBQVAsR0FBeUIsVUFBVWpCLEVBQVYsRUFBYztBQUVuQztBQUNBQSxJQUFFLEdBQUksT0FBT0EsRUFBUCxLQUFjLFFBQWYsR0FBMkJ6aUIsUUFBUSxDQUFDNEIsYUFBVCxDQUF1QjZnQixFQUF2QixDQUEzQixHQUF3REEsRUFBN0QsQ0FIbUMsQ0FLbkM7O0FBQ0EsTUFBSWhHLFNBQVMsQ0FBQ0YsU0FBVixDQUFvQlMsS0FBcEIsQ0FBMEIsbUJBQTFCLENBQUosRUFBb0Q7QUFFaEQ7QUFDQSxRQUFNMkcsUUFBUSxHQUFHbEIsRUFBRSxDQUFDbUIsZUFBcEI7QUFDQSxRQUFNQyxRQUFRLEdBQUdwQixFQUFFLENBQUNvQixRQUFwQixDQUpnRCxDQU1oRDs7QUFDQXBCLE1BQUUsQ0FBQ21CLGVBQUgsR0FBcUIsSUFBckI7QUFDQW5CLE1BQUUsQ0FBQ29CLFFBQUgsR0FBYyxJQUFkLENBUmdELENBVWhEOztBQUNBLFFBQUlDLEtBQUssR0FBRzlqQixRQUFRLENBQUMrakIsV0FBVCxFQUFaO0FBQ0FELFNBQUssQ0FBQ0Usa0JBQU4sQ0FBeUJ2QixFQUF6QixFQVpnRCxDQWNoRDs7QUFDQSxRQUFNd0IsU0FBUyxHQUFHbGMsTUFBTSxDQUFDbWMsWUFBUCxFQUFsQjtBQUNBRCxhQUFTLENBQUNFLGVBQVY7QUFDQUYsYUFBUyxDQUFDRyxRQUFWLENBQW1CTixLQUFuQjtBQUNBckIsTUFBRSxDQUFDNEIsaUJBQUgsQ0FBcUIsQ0FBckIsRUFBd0IsTUFBeEIsRUFsQmdELENBb0JoRDs7QUFDQTVCLE1BQUUsQ0FBQ21CLGVBQUgsR0FBcUJELFFBQXJCO0FBQ0FsQixNQUFFLENBQUNvQixRQUFILEdBQWNBLFFBQWQ7QUFDSCxHQXZCRCxNQXdCSztBQUNEcEIsTUFBRSxDQUFDNkIsTUFBSDtBQUNILEdBaENrQyxDQWtDbkM7OztBQUNBdGtCLFVBQVEsQ0FBQ3VrQixXQUFULENBQXFCLE1BQXJCO0FBQ0gsQ0FwQ0Q7QUFzQ0E7Ozs7Ozs7O0FBTUF4YyxNQUFNLENBQUNELFVBQVAsR0FBb0IsVUFBVTJhLEVBQVYsRUFBYztBQUM5QixNQUFNK0IsSUFBSSxHQUFHL0IsRUFBRSxDQUFDN0sscUJBQUgsRUFBYjtBQUFBLE1BQ0k2TSxVQUFVLEdBQUcxYyxNQUFNLENBQUMyYyxXQUFQLElBQXNCMWtCLFFBQVEsQ0FBQzZYLGVBQVQsQ0FBeUI0TSxVQURoRTtBQUFBLE1BRUl6TSxTQUFTLEdBQUdqUSxNQUFNLENBQUNrUSxXQUFQLElBQXNCalksUUFBUSxDQUFDNlgsZUFBVCxDQUF5QkcsU0FGL0Q7QUFHQSxTQUFPO0FBQUVuUSxPQUFHLEVBQUUyYyxJQUFJLENBQUMzYyxHQUFMLEdBQVdtUSxTQUFsQjtBQUE2QjJNLFFBQUksRUFBRUgsSUFBSSxDQUFDRyxJQUFMLEdBQVlGO0FBQS9DLEdBQVA7QUFDSCxDQUxELEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDblhBOzs7OztBQUtBOztJQUVNdmpCLHdCO0FBQ0Ysc0NBQ0E7QUFBQTs7QUFDSSxTQUFLMGpCLFVBQUwsR0FBa0IsRUFBbEI7QUFDSDtBQUVEOzs7Ozs7Ozs7QUFxRUE7Ozs7OEJBSVU7QUFDTixhQUFPO0FBQ0gscUJBQWEsS0FBS0E7QUFEZixPQUFQO0FBR0g7QUFFRDs7Ozs7O3dCQUdnQjtBQUNaLGFBQU8sS0FBS0EsVUFBWjtBQUNIOzs7bUNBaEZxQkMsSSxFQUFNO0FBQ3hCLFVBQUcsQ0FBQyxLQUFLOWpCLEVBQUwsQ0FBUThqQixJQUFSLENBQUosRUFBbUI7QUFDZixlQUFPLElBQVA7QUFDSDs7QUFDRCxVQUFJQyxVQUFVLEdBQUcxZSxJQUFJLENBQUNDLEtBQUwsQ0FBV3dlLElBQVgsQ0FBakI7QUFFQSxVQUFJRSxRQUFRLEdBQUcsSUFBSSxJQUFKLEVBQWY7QUFDQSxVQUFJbGlCLGFBQWEsR0FBR2lpQixVQUFVLENBQUNoaUIsU0FBWCxDQUFxQkMsTUFBekM7O0FBQ0EsV0FBSSxJQUFJQyxLQUFLLEdBQUcsQ0FBaEIsRUFBbUJBLEtBQUssR0FBR0gsYUFBM0IsRUFBMENHLEtBQUssRUFBL0MsRUFDQTtBQUNJLFlBQUlnaUIsY0FBYyxHQUFHRixVQUFVLENBQUNoaUIsU0FBWCxDQUFxQkUsS0FBckIsQ0FBckI7QUFDQSxZQUFJQyxRQUFRLEdBQUcsSUFBSWdpQixrREFBSixFQUFmO0FBQ0FoaUIsZ0JBQVEsQ0FBQzhDLElBQVQsR0FBZ0JpZixjQUFjLENBQUNqZixJQUEvQjtBQUNBOUMsZ0JBQVEsQ0FBQ2lpQixXQUFULEdBQXVCRixjQUFjLENBQUNFLFdBQXRDO0FBQ0FqaUIsZ0JBQVEsQ0FBQ0ksVUFBVCxHQUFzQjJoQixjQUFjLENBQUMzaEIsVUFBckM7QUFDQUosZ0JBQVEsQ0FBQ2tpQix3QkFBVCxHQUFvQ0gsY0FBYyxDQUFDRyx3QkFBbkQ7QUFDQWxpQixnQkFBUSxDQUFDRywwQkFBVCxHQUFzQzRoQixjQUFjLENBQUM1aEIsMEJBQXJEOztBQUVBMmhCLGdCQUFRLENBQUNILFVBQVQsQ0FBb0JqWSxJQUFwQixDQUF5QjFKLFFBQXpCO0FBQ0g7O0FBRUQsYUFBTzhoQixRQUFQO0FBQ0g7QUFFRDs7Ozs7Ozs7Ozt1QkFPVUYsSSxFQUNWO0FBQUEsVUFEZ0JPLFNBQ2hCLHVFQUQ0QixJQUM1QjtBQUNJLFVBQUlOLFVBQVUsR0FBRyxJQUFqQjs7QUFFQSxVQUFHLE9BQU9ELElBQVAsS0FBZ0IsUUFBbkIsRUFBNkI7QUFDekIsWUFBSTtBQUNBQyxvQkFBVSxHQUFHMWUsSUFBSSxDQUFDQyxLQUFMLENBQVd3ZSxJQUFYLENBQWI7QUFDQSxjQUFJLENBQUNDLFVBQUwsRUFBaUIsT0FBTyxLQUFQO0FBQ3BCLFNBSEQsQ0FHRSxPQUFPbGUsQ0FBUCxFQUFVO0FBQ1J2RixpQkFBTyxDQUFDQyxLQUFSLENBQWMsNklBQWQsRUFBNkp3akIsVUFBN0o7QUFDQSxpQkFBTyxLQUFQO0FBQ0g7QUFDSixPQVJELE1BUU87QUFDSEEsa0JBQVUsR0FBR0QsSUFBYjtBQUNIOztBQUVELFVBQUcsQ0FBQ0MsVUFBVSxDQUFDTyxjQUFYLENBQTBCLFdBQTFCLENBQUQsSUFBMkMsQ0FBQ25ELEtBQUssQ0FBQ29ELE9BQU4sQ0FBY1IsVUFBVSxDQUFDaGlCLFNBQXpCLENBQS9DLEVBQW9GO0FBQ2hGekIsZUFBTyxDQUFDMEQsR0FBUixDQUFZLDZIQUFaLEVBQTJJK2YsVUFBM0k7QUFDQSxlQUFPLEtBQVA7QUFDSDs7QUFFRCxVQUFJamlCLGFBQWEsR0FBR2lpQixVQUFVLENBQUNoaUIsU0FBWCxDQUFxQkMsTUFBekM7O0FBQ0EsV0FBSSxJQUFJQyxLQUFLLEdBQUcsQ0FBaEIsRUFBbUJBLEtBQUssR0FBR0gsYUFBM0IsRUFBMENHLEtBQUssRUFBL0MsRUFDQTtBQUNJLFlBQUlnaUIsY0FBYyxHQUFHRixVQUFVLENBQUNoaUIsU0FBWCxDQUFxQkUsS0FBckIsQ0FBckI7O0FBQ0EsWUFBRyxRQUFPZ2lCLGNBQVAsTUFBMEIsUUFBMUIsSUFBc0MsT0FBT0EsY0FBUCxLQUEwQixVQUFoRSxJQUE4RSxDQUFDQyxrREFBUSxDQUFDbGtCLEVBQVQsQ0FBWWlrQixjQUFaLENBQWxGLEVBQStHO0FBQzNHLGlCQUFPLEtBQVA7QUFDSDtBQUNKOztBQUVELGFBQU8sSUFBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0VMOzs7SUFHTWxrQixhO0FBQ0YsMkJBQ0E7QUFBQTs7QUFDSSxTQUFLeWtCLFFBQUwsR0FBZ0IsRUFBaEI7QUFDQSxTQUFLQyxPQUFMLEdBQWUsRUFBZjtBQUNIO0FBRUQ7Ozs7Ozs7OztBQXVEQTs7Ozs7d0JBS2M7QUFDVixhQUFPLEtBQUtELFFBQVo7QUFDSDtBQUVEOzs7Ozs7d0JBR2E7QUFDVCxhQUFPLEtBQUtDLE9BQVo7QUFDSDs7O21DQWpFcUJYLEksRUFBTTtBQUN4QixVQUFHLENBQUMsS0FBSzlqQixFQUFMLENBQVE4akIsSUFBUixDQUFKLEVBQW1CO0FBQ2YsZUFBTyxJQUFQO0FBQ0g7O0FBQ0QsVUFBSUMsVUFBVSxHQUFHMWUsSUFBSSxDQUFDQyxLQUFMLENBQVd3ZSxJQUFYLENBQWpCO0FBRUEsVUFBSUUsUUFBUSxHQUFHLElBQUksSUFBSixFQUFmO0FBQ0FBLGNBQVEsQ0FBQ1EsUUFBVCxHQUFvQlQsVUFBVSxDQUFDVyxPQUEvQjtBQUNBVixjQUFRLENBQUNTLE9BQVQsR0FBbUJWLFVBQVUsQ0FBQ3BlLE1BQTlCO0FBRUEsYUFBT3FlLFFBQVA7QUFDSDtBQUVEOzs7Ozs7Ozs7O3VCQU9VRixJLEVBQ1Y7QUFBQSxVQURnQk8sU0FDaEIsdUVBRDRCLElBQzVCO0FBQ0ksVUFBSU4sVUFBVSxHQUFHLElBQWpCOztBQUNBLFVBQUk7QUFDQUEsa0JBQVUsR0FBRzFlLElBQUksQ0FBQ0MsS0FBTCxDQUFXd2UsSUFBWCxDQUFiO0FBQ0EsWUFBRyxDQUFDQyxVQUFKLEVBQWdCLE9BQU8sS0FBUDtBQUNuQixPQUhELENBR0UsT0FBT2xlLENBQVAsRUFBVTtBQUNSLFlBQUd3ZSxTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsbUhBQWQ7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFFRCxVQUFHLENBQUN3akIsVUFBVSxDQUFDTyxjQUFYLENBQTBCLFNBQTFCLENBQUQsSUFBeUMsT0FBT1AsVUFBVSxDQUFDVyxPQUFsQixLQUE4QixRQUExRSxFQUFvRjtBQUNoRixZQUFHTCxTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsNEZBQWQsRUFBNEd3akIsVUFBNUc7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFFRCxVQUFHLENBQUNBLFVBQVUsQ0FBQ08sY0FBWCxDQUEwQixRQUExQixDQUFELElBQXdDLFFBQU9QLFVBQVUsQ0FBQ3BlLE1BQWxCLE1BQTZCLFFBQXhFLEVBQWtGO0FBQzlFLFlBQUcwZSxTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsbUhBQWQsRUFBbUl3akIsVUFBbkk7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFFRCxXQUFJLElBQUlZLFNBQVIsSUFBcUJaLFVBQVUsQ0FBQ3BlLE1BQWhDLEVBQXdDO0FBQ3BDLFlBQUdvZSxVQUFVLENBQUNwZSxNQUFYLENBQWtCMmUsY0FBbEIsQ0FBaUNLLFNBQWpDLEtBQStDLENBQUN4RCxLQUFLLENBQUNvRCxPQUFOLENBQWNSLFVBQVUsQ0FBQ3BlLE1BQVgsQ0FBa0JnZixTQUFsQixDQUFkLENBQW5ELEVBQWdHO0FBQzVGLGNBQUdOLFNBQUgsRUFBYy9qQixPQUFPLENBQUNDLEtBQVIsQ0FBYyxrQ0FBZ0Nva0IsU0FBaEMsR0FBMEMsd0ZBQXhELEVBQWtKWixVQUFsSjtBQUNkLGlCQUFPLEtBQVA7QUFDSDtBQUNKOztBQUVELGFBQU8sSUFBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQy9ETDs7Ozs7SUFLTUcsUTtBQUNGLHNCQUNBO0FBQUE7O0FBQ0ksU0FBS1UsS0FBTCxHQUFhLEVBQWI7QUFDQSxTQUFLQyxZQUFMLEdBQW9CLEVBQXBCO0FBQ0EsU0FBS0MsV0FBTCxHQUFtQixFQUFuQjtBQUNBLFNBQUtDLHlCQUFMLEdBQWlDLEVBQWpDO0FBQ0EsU0FBS0MsMkJBQUwsR0FBbUMsRUFBbkM7QUFDSDtBQUVEOzs7Ozs7Ozs7QUFvRUE7Ozs7OEJBSVU7QUFDTixhQUFPO0FBQ0gsZ0JBQVEsS0FBS0osS0FEVjtBQUVILHVCQUFlLEtBQUtDLFlBRmpCO0FBR0gsc0JBQWMsS0FBS0MsV0FIaEI7QUFJSCxvQ0FBNEIsS0FBS0MseUJBSjlCO0FBS0gsc0NBQThCLEtBQUtDO0FBTGhDLE9BQVA7QUFPSDs7O3dCQUVVO0FBQ1AsYUFBTyxLQUFLSixLQUFaO0FBQ0gsSztzQkFFUWxqQixLLEVBQU87QUFDWixXQUFLa2pCLEtBQUwsR0FBYWxqQixLQUFiO0FBQ0g7Ozt3QkFFaUI7QUFDZCxhQUFPLEtBQUttakIsWUFBWjtBQUNILEs7c0JBRWVuakIsSyxFQUFPO0FBQ25CLFdBQUttakIsWUFBTCxHQUFvQm5qQixLQUFwQjtBQUNIOzs7d0JBRWdCO0FBQ2IsYUFBTyxLQUFLb2pCLFdBQVo7QUFDSCxLO3NCQUVjcGpCLEssRUFBTztBQUNsQixXQUFLb2pCLFdBQUwsR0FBbUJwakIsS0FBbkI7QUFDSDs7O3dCQUU4QjtBQUMzQixhQUFPLEtBQUtxakIseUJBQVo7QUFDSCxLO3NCQUU0QnJqQixLLEVBQU87QUFDaEMsV0FBS3FqQix5QkFBTCxHQUFpQ3JqQixLQUFqQztBQUNIOzs7d0JBRWdDO0FBQzdCLGFBQU8sS0FBS3NqQiwyQkFBWjtBQUNILEs7c0JBRThCdGpCLEssRUFBTztBQUNsQyxXQUFLc2pCLDJCQUFMLEdBQW1DdGpCLEtBQW5DO0FBQ0g7OzttQ0FwSHFCb2lCLEksRUFBTTtBQUN4QixVQUFHLENBQUMsS0FBSzlqQixFQUFMLENBQVE4akIsSUFBUixDQUFKLEVBQW1CO0FBQ2YsZUFBTyxJQUFQO0FBQ0g7O0FBQ0QsVUFBSUMsVUFBVSxHQUFHMWUsSUFBSSxDQUFDQyxLQUFMLENBQVd3ZSxJQUFYLENBQWpCO0FBRUEsVUFBSUUsUUFBUSxHQUFHLElBQUksSUFBSixFQUFmO0FBQ0FBLGNBQVEsQ0FBQ1ksS0FBVCxHQUFpQmIsVUFBVSxDQUFDL2UsSUFBNUI7QUFDQWdmLGNBQVEsQ0FBQ2EsWUFBVCxHQUF3QmQsVUFBVSxDQUFDSSxXQUFuQztBQUNBSCxjQUFRLENBQUNjLFdBQVQsR0FBdUJmLFVBQVUsQ0FBQ3poQixVQUFsQztBQUNBMGhCLGNBQVEsQ0FBQ2UseUJBQVQsR0FBcUNoQixVQUFVLENBQUNLLHdCQUFoRDtBQUNBSixjQUFRLENBQUNnQiwyQkFBVCxHQUF1Q2pCLFVBQVUsQ0FBQzFoQiwwQkFBbEQ7QUFFQSxhQUFPMmhCLFFBQVA7QUFDSDtBQUVEOzs7Ozs7Ozs7O3VCQU9VRixJLEVBQ1Y7QUFBQSxVQURnQk8sU0FDaEIsdUVBRDRCLElBQzVCO0FBQ0ksVUFBSU4sVUFBVSxHQUFHLElBQWpCOztBQUVBLFVBQUcsT0FBT0QsSUFBUCxLQUFnQixRQUFuQixFQUE2QjtBQUN6QixZQUFJO0FBQ0FDLG9CQUFVLEdBQUcxZSxJQUFJLENBQUNDLEtBQUwsQ0FBV3dlLElBQVgsQ0FBYjtBQUNBLGNBQUksQ0FBQ0MsVUFBTCxFQUFpQixPQUFPLEtBQVA7QUFDcEIsU0FIRCxDQUdFLE9BQU9sZSxDQUFQLEVBQVU7QUFDUnZGLGlCQUFPLENBQUNDLEtBQVIsQ0FBYyw2R0FBZCxFQUE2SHdqQixVQUE3SCxFQUF5SUQsSUFBekk7QUFDQSxpQkFBTyxLQUFQO0FBQ0g7QUFDSixPQVJELE1BUU87QUFDSEMsa0JBQVUsR0FBR0QsSUFBYjtBQUNIOztBQUVELFVBQUcsQ0FBQ0MsVUFBVSxDQUFDTyxjQUFYLENBQTBCLE1BQTFCLENBQUQsSUFBc0MsT0FBT1AsVUFBVSxDQUFDSSxXQUFsQixLQUFrQyxRQUEzRSxFQUFxRjtBQUNqRixZQUFHRSxTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsMkZBQWQsRUFBMkd3akIsVUFBM0c7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFDRCxVQUFHLENBQUNBLFVBQVUsQ0FBQ08sY0FBWCxDQUEwQixhQUExQixDQUFELElBQTZDLE9BQU9QLFVBQVUsQ0FBQ0ksV0FBbEIsS0FBa0MsUUFBbEYsRUFBNEY7QUFDeEYsWUFBR0UsU0FBSCxFQUFjL2pCLE9BQU8sQ0FBQ0MsS0FBUixDQUFjLGtHQUFkLEVBQWtId2pCLFVBQWxIO0FBQ2QsZUFBTyxLQUFQO0FBQ0g7O0FBQ0QsVUFBRyxDQUFDQSxVQUFVLENBQUNPLGNBQVgsQ0FBMEIsWUFBMUIsQ0FBRCxJQUE0QyxPQUFPUCxVQUFVLENBQUN6aEIsVUFBbEIsS0FBaUMsUUFBaEYsRUFBMEY7QUFDdEYsWUFBRytoQixTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsaUdBQWQsRUFBaUh3akIsVUFBakg7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFDRCxVQUFHLENBQUNBLFVBQVUsQ0FBQ08sY0FBWCxDQUEwQiwwQkFBMUIsQ0FBRCxJQUEwRCxPQUFPUCxVQUFVLENBQUNLLHdCQUFsQixLQUErQyxRQUE1RyxFQUFzSDtBQUNsSCxZQUFHQyxTQUFILEVBQWMvakIsT0FBTyxDQUFDQyxLQUFSLENBQWMsK0dBQWQsRUFBK0h3akIsVUFBVSxDQUFDSyx3QkFBMUk7QUFDZCxlQUFPLEtBQVA7QUFDSDs7QUFDRCxVQUFHLENBQUNMLFVBQVUsQ0FBQ08sY0FBWCxDQUEwQiw0QkFBMUIsQ0FBRCxJQUE0RCxPQUFPUCxVQUFVLENBQUMxaEIsMEJBQWxCLEtBQWlELFFBQWhILEVBQTBIO0FBQ3RILFlBQUdnaUIsU0FBSCxFQUFjL2pCLE9BQU8sQ0FBQ0MsS0FBUixDQUFjLGlIQUFkLEVBQWlJd2pCLFVBQWpJO0FBQ2QsZUFBTyxLQUFQO0FBQ0g7O0FBRUQsYUFBTyxJQUFQO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoRkw7Ozs7O0lBS01rQixrQjtBQUNGLGdDQUNBO0FBQUE7O0FBQ0ksU0FBS0MsTUFBTCxHQUFjLEtBQWQ7QUFDQSxTQUFLVCxPQUFMLEdBQWUsRUFBZjtBQUNBLFNBQUtVLE1BQUwsR0FBYyxLQUFLQyxPQUFMLENBQWEvakIsSUFBYixDQUFrQixJQUFsQixDQUFkO0FBQ0g7QUFFRDs7Ozs7Ozs7O0FBaURBOzs7OzhCQUlVO0FBQ04sYUFBTztBQUNILGlCQUFTLEtBQUs2akIsTUFEWDtBQUVILGtCQUFVLEtBQUtUO0FBRlosT0FBUDtBQUlIO0FBRUQ7Ozs7Ozt3QkFHWTtBQUNSLGFBQU8sS0FBS1MsTUFBWjtBQUNIO0FBRUQ7Ozs7Ozt3QkFHYTtBQUNULGFBQU8sS0FBS1QsT0FBWjtBQUNIOzs7bUNBcEVxQlgsSSxFQUFNO0FBQ3hCLFVBQUcsQ0FBQyxLQUFLOWpCLEVBQUwsQ0FBUThqQixJQUFSLENBQUosRUFBbUI7QUFDZixlQUFPLElBQVA7QUFDSDs7QUFDRCxVQUFJQyxVQUFVLEdBQUcxZSxJQUFJLENBQUNDLEtBQUwsQ0FBV3dlLElBQVgsQ0FBakI7QUFFQSxVQUFJRSxRQUFRLEdBQUcsSUFBSSxJQUFKLEVBQWY7QUFDQUEsY0FBUSxDQUFDa0IsTUFBVCxHQUFrQm5CLFVBQVUsQ0FBQ3NCLEtBQTdCO0FBQ0FyQixjQUFRLENBQUNTLE9BQVQsR0FBbUJWLFVBQVUsQ0FBQ3BlLE1BQTlCO0FBRUEsYUFBT3FlLFFBQVA7QUFDSDtBQUVEOzs7Ozs7Ozs7O3VCQU9VRixJLEVBQ1Y7QUFBQSxVQURnQk8sU0FDaEIsdUVBRDRCLElBQzVCO0FBQ0ksVUFBSU4sVUFBVSxHQUFHLElBQWpCOztBQUNBLFVBQUk7QUFDQUEsa0JBQVUsR0FBRzFlLElBQUksQ0FBQ0MsS0FBTCxDQUFXd2UsSUFBWCxDQUFiO0FBQ0EsWUFBRyxDQUFDQyxVQUFKLEVBQWdCLE9BQU8sS0FBUDtBQUNuQixPQUhELENBR0UsT0FBT2xlLENBQVAsRUFBVTtBQUNSdkYsZUFBTyxDQUFDQyxLQUFSLENBQWMsaUlBQWQsRUFBaUp3akIsVUFBako7QUFDQSxlQUFPLEtBQVA7QUFDSDs7QUFFRCxVQUFHLENBQUNBLFVBQVUsQ0FBQ08sY0FBWCxDQUEwQixPQUExQixDQUFKLEVBQXdDO0FBQ3BDaGtCLGVBQU8sQ0FBQ0MsS0FBUixDQUFjLDBIQUFkLEVBQTBJd2pCLFVBQTFJO0FBQ0EsZUFBTyxLQUFQO0FBQ0g7O0FBRUQsVUFBRyxDQUFDQSxVQUFVLENBQUNPLGNBQVgsQ0FBMEIsUUFBMUIsQ0FBRCxJQUF3QyxRQUFPLENBQUNQLFVBQVUsQ0FBQ3BlLE1BQW5CLEtBQTZCLFFBQXhFLEVBQWtGO0FBQzlFckYsZUFBTyxDQUFDQyxLQUFSLENBQWMsc0dBQWQsRUFBc0h3akIsVUFBdEg7QUFDQSxlQUFPLEtBQVA7QUFDSDs7QUFFRCxhQUFPLElBQVA7QUFDSDs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMzREw7Ozs7QUFNQSxTQUFTdUIsY0FBVCxDQUF3QkMsU0FBeEIsRUFBbUM7QUFDL0IsTUFBSTdXLEtBQUo7O0FBQ0EsTUFBSSxPQUFPOFcsS0FBUCxLQUFrQixVQUF0QixFQUFrQztBQUFFO0FBQ2hDOVcsU0FBSyxHQUFHLElBQUk4VyxLQUFKLENBQVVELFNBQVYsQ0FBUixDQUQ4QixDQUNBO0FBQ2pDLEdBRkQsTUFFTztBQUNIN1csU0FBSyxHQUFHelAsUUFBUSxDQUFDd21CLFdBQVQsQ0FBcUIsT0FBckIsQ0FBUixDQURHLENBQ29DOztBQUN2Qy9XLFNBQUssQ0FBQ2dYLFNBQU4sQ0FBZ0JILFNBQWhCLEVBQTJCLElBQTNCLEVBQWlDLElBQWpDO0FBQ0g7O0FBQ0QsU0FBTzdXLEtBQVA7QUFDSDs7QUFFRCxTQUFTaVgsdUJBQVQsQ0FBaUNDLE9BQWpDLEVBQTBDbFgsS0FBMUMsRUFDQTtBQUNJLE1BQUl6UCxRQUFRLENBQUN3bUIsV0FBYixFQUEwQjtBQUN0QkcsV0FBTyxDQUFDQyxhQUFSLENBQXNCblgsS0FBdEI7QUFDSCxHQUZELE1BRU87QUFDSGtYLFdBQU8sQ0FBQ0UsU0FBUixDQUFrQixPQUFPcFgsS0FBSyxDQUFDcVgsU0FBL0IsRUFBMENyWCxLQUExQztBQUNIO0FBQ0osQzs7Ozs7Ozs7Ozs7QUN4QkRtRyxNQUFNLENBQUNDLFNBQVAsR0FBbUJELE1BQU0sQ0FBQ0MsU0FBUCxJQUFvQixVQUFTcFQsS0FBVCxFQUFnQjtBQUNuRCxTQUFPLE9BQU9BLEtBQVAsS0FBaUIsUUFBakIsSUFDSCtlLFFBQVEsQ0FBQy9lLEtBQUQsQ0FETCxJQUVIcVYsSUFBSSxDQUFDaVAsS0FBTCxDQUFXdGtCLEtBQVgsTUFBc0JBLEtBRjFCO0FBR0gsQ0FKRCxDOzs7Ozs7Ozs7Ozs7O0FDQUMsV0FBVXVrQixNQUFWLEVBQWtCQyxPQUFsQixFQUEyQjtBQUN4QixnQ0FBT0MsT0FBUCxPQUFtQixRQUFuQixJQUErQixPQUFPQyxNQUFQLEtBQWtCLFdBQWpELEdBQStERixPQUFPLEVBQXRFLEdBQ0ksUUFBNkNHLG9DQUFPSCxPQUFEO0FBQUE7QUFBQTtBQUFBO0FBQUEsb0dBQW5ELEdBQ0tBLFNBRlQ7QUFHSCxDQUpBLEVBSUMsSUFKRCxFQUlRLFlBQVk7QUFBRTtBQUVuQjs7OztBQUdBLFdBQVNJLGtCQUFULENBQTRCMUksUUFBNUIsRUFBc0M7QUFDbEMsUUFBSTJJLFdBQVcsR0FBRyxLQUFLQSxXQUF2QjtBQUNBLFdBQU8sS0FBSzNrQixJQUFMLENBQ0gsVUFBU0YsS0FBVCxFQUFnQjtBQUNaLGFBQU82a0IsV0FBVyxDQUFDOW1CLE9BQVosQ0FBb0JtZSxRQUFRLEVBQTVCLEVBQWdDaGMsSUFBaEMsQ0FBcUMsWUFBVztBQUNuRCxlQUFPRixLQUFQO0FBQ0gsT0FGTSxDQUFQO0FBR0gsS0FMRSxFQU1ILFVBQVM4a0IsTUFBVCxFQUFpQjtBQUNiLGFBQU9ELFdBQVcsQ0FBQzltQixPQUFaLENBQW9CbWUsUUFBUSxFQUE1QixFQUFnQ2hjLElBQWhDLENBQXFDLFlBQVc7QUFDbkQsZUFBTzJrQixXQUFXLENBQUM3bUIsTUFBWixDQUFtQjhtQixNQUFuQixDQUFQO0FBQ0gsT0FGTSxDQUFQO0FBR0gsS0FWRSxDQUFQO0FBWUgsR0FuQmdCLENBcUJyQjtBQUNBOzs7QUFDSSxNQUFJQyxjQUFjLEdBQUc1YyxVQUFyQjs7QUFFQSxXQUFTNmMsSUFBVCxHQUFnQixDQUFFLENBekJELENBMkJyQjs7O0FBQ0ksV0FBU3JsQixJQUFULENBQWNzbEIsRUFBZCxFQUFrQkMsT0FBbEIsRUFBMkI7QUFDdkIsV0FBTyxZQUFXO0FBQ2RELFFBQUUsQ0FBQ3pILEtBQUgsQ0FBUzBILE9BQVQsRUFBa0I1SCxTQUFsQjtBQUNILEtBRkQ7QUFHSDtBQUVEOzs7Ozs7QUFJQSxXQUFTeGYsT0FBVCxDQUFpQm1uQixFQUFqQixFQUFxQjtBQUNqQixRQUFJLEVBQUUsZ0JBQWdCbm5CLE9BQWxCLENBQUosRUFDSSxNQUFNLElBQUlxbkIsU0FBSixDQUFjLHNDQUFkLENBQU47QUFDSixRQUFJLE9BQU9GLEVBQVAsS0FBYyxVQUFsQixFQUE4QixNQUFNLElBQUlFLFNBQUosQ0FBYyxnQkFBZCxDQUFOO0FBQzlCOztBQUNBLFNBQUtDLE1BQUwsR0FBYyxDQUFkO0FBQ0E7O0FBQ0EsU0FBS0MsUUFBTCxHQUFnQixLQUFoQjtBQUNBOztBQUNBLFNBQUtDLE1BQUwsR0FBYzFJLFNBQWQ7QUFDQTs7QUFDQSxTQUFLMkksVUFBTCxHQUFrQixFQUFsQjtBQUVBQyxhQUFTLENBQUNQLEVBQUQsRUFBSyxJQUFMLENBQVQ7QUFDSDs7QUFFRCxXQUFTUSxNQUFULENBQWdCNW5CLElBQWhCLEVBQXNCNm5CLFFBQXRCLEVBQWdDO0FBQzVCLFdBQU83bkIsSUFBSSxDQUFDdW5CLE1BQUwsS0FBZ0IsQ0FBdkIsRUFBMEI7QUFDdEJ2bkIsVUFBSSxHQUFHQSxJQUFJLENBQUN5bkIsTUFBWjtBQUNIOztBQUNELFFBQUl6bkIsSUFBSSxDQUFDdW5CLE1BQUwsS0FBZ0IsQ0FBcEIsRUFBdUI7QUFDbkJ2bkIsVUFBSSxDQUFDMG5CLFVBQUwsQ0FBZ0JyYixJQUFoQixDQUFxQndiLFFBQXJCOztBQUNBO0FBQ0g7O0FBQ0Q3bkIsUUFBSSxDQUFDd25CLFFBQUwsR0FBZ0IsSUFBaEI7O0FBQ0F2bkIsV0FBTyxDQUFDNm5CLFlBQVIsQ0FBcUIsWUFBVztBQUM1QixVQUFJQyxFQUFFLEdBQUcvbkIsSUFBSSxDQUFDdW5CLE1BQUwsS0FBZ0IsQ0FBaEIsR0FBb0JNLFFBQVEsQ0FBQ0csV0FBN0IsR0FBMkNILFFBQVEsQ0FBQ0ksVUFBN0Q7O0FBQ0EsVUFBSUYsRUFBRSxLQUFLLElBQVgsRUFBaUI7QUFDYixTQUFDL25CLElBQUksQ0FBQ3VuQixNQUFMLEtBQWdCLENBQWhCLEdBQW9Ccm5CLE9BQXBCLEdBQThCQyxNQUEvQixFQUF1QzBuQixRQUFRLENBQUNLLE9BQWhELEVBQXlEbG9CLElBQUksQ0FBQ3luQixNQUE5RDtBQUNBO0FBQ0g7O0FBQ0QsVUFBSVUsR0FBSjs7QUFDQSxVQUFJO0FBQ0FBLFdBQUcsR0FBR0osRUFBRSxDQUFDL25CLElBQUksQ0FBQ3luQixNQUFOLENBQVI7QUFDSCxPQUZELENBRUUsT0FBT25oQixDQUFQLEVBQVU7QUFDUm5HLGNBQU0sQ0FBQzBuQixRQUFRLENBQUNLLE9BQVYsRUFBbUI1aEIsQ0FBbkIsQ0FBTjtBQUNBO0FBQ0g7O0FBQ0RwRyxhQUFPLENBQUMybkIsUUFBUSxDQUFDSyxPQUFWLEVBQW1CQyxHQUFuQixDQUFQO0FBQ0gsS0FkRDtBQWVIOztBQUVELFdBQVNqb0IsT0FBVCxDQUFpQkYsSUFBakIsRUFBdUJvb0IsUUFBdkIsRUFBaUM7QUFDN0IsUUFBSTtBQUNBO0FBQ0EsVUFBSUEsUUFBUSxLQUFLcG9CLElBQWpCLEVBQ0ksTUFBTSxJQUFJc25CLFNBQUosQ0FBYywyQ0FBZCxDQUFOOztBQUNKLFVBQ0ljLFFBQVEsS0FDUCxRQUFPQSxRQUFQLE1BQW9CLFFBQXBCLElBQWdDLE9BQU9BLFFBQVAsS0FBb0IsVUFEN0MsQ0FEWixFQUdFO0FBQ0UsWUFBSS9sQixJQUFJLEdBQUcrbEIsUUFBUSxDQUFDL2xCLElBQXBCOztBQUNBLFlBQUkrbEIsUUFBUSxZQUFZbm9CLE9BQXhCLEVBQWlDO0FBQzdCRCxjQUFJLENBQUN1bkIsTUFBTCxHQUFjLENBQWQ7QUFDQXZuQixjQUFJLENBQUN5bkIsTUFBTCxHQUFjVyxRQUFkO0FBQ0FDLGdCQUFNLENBQUNyb0IsSUFBRCxDQUFOO0FBQ0E7QUFDSCxTQUxELE1BS08sSUFBSSxPQUFPcUMsSUFBUCxLQUFnQixVQUFwQixFQUFnQztBQUNuQ3NsQixtQkFBUyxDQUFDN2xCLElBQUksQ0FBQ08sSUFBRCxFQUFPK2xCLFFBQVAsQ0FBTCxFQUF1QnBvQixJQUF2QixDQUFUO0FBQ0E7QUFDSDtBQUNKOztBQUNEQSxVQUFJLENBQUN1bkIsTUFBTCxHQUFjLENBQWQ7QUFDQXZuQixVQUFJLENBQUN5bkIsTUFBTCxHQUFjVyxRQUFkO0FBQ0FDLFlBQU0sQ0FBQ3JvQixJQUFELENBQU47QUFDSCxLQXRCRCxDQXNCRSxPQUFPc0csQ0FBUCxFQUFVO0FBQ1JuRyxZQUFNLENBQUNILElBQUQsRUFBT3NHLENBQVAsQ0FBTjtBQUNIO0FBQ0o7O0FBRUQsV0FBU25HLE1BQVQsQ0FBZ0JILElBQWhCLEVBQXNCb29CLFFBQXRCLEVBQWdDO0FBQzVCcG9CLFFBQUksQ0FBQ3VuQixNQUFMLEdBQWMsQ0FBZDtBQUNBdm5CLFFBQUksQ0FBQ3luQixNQUFMLEdBQWNXLFFBQWQ7QUFDQUMsVUFBTSxDQUFDcm9CLElBQUQsQ0FBTjtBQUNIOztBQUVELFdBQVNxb0IsTUFBVCxDQUFnQnJvQixJQUFoQixFQUFzQjtBQUNsQixRQUFJQSxJQUFJLENBQUN1bkIsTUFBTCxLQUFnQixDQUFoQixJQUFxQnZuQixJQUFJLENBQUMwbkIsVUFBTCxDQUFnQmpsQixNQUFoQixLQUEyQixDQUFwRCxFQUF1RDtBQUNuRHhDLGFBQU8sQ0FBQzZuQixZQUFSLENBQXFCLFlBQVc7QUFDNUIsWUFBSSxDQUFDOW5CLElBQUksQ0FBQ3duQixRQUFWLEVBQW9CO0FBQ2hCdm5CLGlCQUFPLENBQUNxb0IscUJBQVIsQ0FBOEJ0b0IsSUFBSSxDQUFDeW5CLE1BQW5DO0FBQ0g7QUFDSixPQUpEO0FBS0g7O0FBRUQsU0FBSyxJQUFJdGpCLENBQUMsR0FBRyxDQUFSLEVBQVdva0IsR0FBRyxHQUFHdm9CLElBQUksQ0FBQzBuQixVQUFMLENBQWdCamxCLE1BQXRDLEVBQThDMEIsQ0FBQyxHQUFHb2tCLEdBQWxELEVBQXVEcGtCLENBQUMsRUFBeEQsRUFBNEQ7QUFDeER5akIsWUFBTSxDQUFDNW5CLElBQUQsRUFBT0EsSUFBSSxDQUFDMG5CLFVBQUwsQ0FBZ0J2akIsQ0FBaEIsQ0FBUCxDQUFOO0FBQ0g7O0FBQ0RuRSxRQUFJLENBQUMwbkIsVUFBTCxHQUFrQixJQUFsQjtBQUNIO0FBRUQ7Ozs7O0FBR0EsV0FBU2MsT0FBVCxDQUFpQlIsV0FBakIsRUFBOEJDLFVBQTlCLEVBQTBDQyxPQUExQyxFQUFtRDtBQUMvQyxTQUFLRixXQUFMLEdBQW1CLE9BQU9BLFdBQVAsS0FBdUIsVUFBdkIsR0FBb0NBLFdBQXBDLEdBQWtELElBQXJFO0FBQ0EsU0FBS0MsVUFBTCxHQUFrQixPQUFPQSxVQUFQLEtBQXNCLFVBQXRCLEdBQW1DQSxVQUFuQyxHQUFnRCxJQUFsRTtBQUNBLFNBQUtDLE9BQUwsR0FBZUEsT0FBZjtBQUNIO0FBRUQ7Ozs7Ozs7O0FBTUEsV0FBU1AsU0FBVCxDQUFtQlAsRUFBbkIsRUFBdUJwbkIsSUFBdkIsRUFBNkI7QUFDekIsUUFBSXlvQixJQUFJLEdBQUcsS0FBWDs7QUFDQSxRQUFJO0FBQ0FyQixRQUFFLENBQ0UsVUFBU2psQixLQUFULEVBQWdCO0FBQ1osWUFBSXNtQixJQUFKLEVBQVU7QUFDVkEsWUFBSSxHQUFHLElBQVA7QUFDQXZvQixlQUFPLENBQUNGLElBQUQsRUFBT21DLEtBQVAsQ0FBUDtBQUNILE9BTEgsRUFNRSxVQUFTOGtCLE1BQVQsRUFBaUI7QUFDYixZQUFJd0IsSUFBSixFQUFVO0FBQ1ZBLFlBQUksR0FBRyxJQUFQO0FBQ0F0b0IsY0FBTSxDQUFDSCxJQUFELEVBQU9pbkIsTUFBUCxDQUFOO0FBQ0gsT0FWSCxDQUFGO0FBWUgsS0FiRCxDQWFFLE9BQU95QixFQUFQLEVBQVc7QUFDVCxVQUFJRCxJQUFKLEVBQVU7QUFDVkEsVUFBSSxHQUFHLElBQVA7QUFDQXRvQixZQUFNLENBQUNILElBQUQsRUFBTzBvQixFQUFQLENBQU47QUFDSDtBQUNKOztBQUVEem9CLFNBQU8sQ0FBQzZoQixTQUFSLENBQWtCLE9BQWxCLElBQTZCLFVBQVNtRyxVQUFULEVBQXFCO0FBQzlDLFdBQU8sS0FBSzVsQixJQUFMLENBQVUsSUFBVixFQUFnQjRsQixVQUFoQixDQUFQO0FBQ0gsR0FGRDs7QUFJQWhvQixTQUFPLENBQUM2aEIsU0FBUixDQUFrQnpmLElBQWxCLEdBQXlCLFVBQVMybEIsV0FBVCxFQUFzQkMsVUFBdEIsRUFBa0M7QUFDdkQ7QUFDQSxRQUFJVSxJQUFJLEdBQUcsSUFBSSxLQUFLM0IsV0FBVCxDQUFxQkcsSUFBckIsQ0FBWDtBQUVBUyxVQUFNLENBQUMsSUFBRCxFQUFPLElBQUlZLE9BQUosQ0FBWVIsV0FBWixFQUF5QkMsVUFBekIsRUFBcUNVLElBQXJDLENBQVAsQ0FBTjtBQUNBLFdBQU9BLElBQVA7QUFDSCxHQU5EOztBQVFBMW9CLFNBQU8sQ0FBQzZoQixTQUFSLENBQWtCLFNBQWxCLElBQStCaUYsa0JBQS9COztBQUVBOW1CLFNBQU8sQ0FBQzJvQixHQUFSLEdBQWMsVUFBU0MsR0FBVCxFQUFjO0FBQ3hCLFdBQU8sSUFBSTVvQixPQUFKLENBQVksVUFBU0MsT0FBVCxFQUFrQkMsTUFBbEIsRUFBMEI7QUFDekMsVUFBSSxDQUFDMG9CLEdBQUQsSUFBUSxPQUFPQSxHQUFHLENBQUNwbUIsTUFBWCxLQUFzQixXQUFsQyxFQUNJLE1BQU0sSUFBSTZrQixTQUFKLENBQWMsOEJBQWQsQ0FBTjtBQUNKLFVBQUk5SCxJQUFJLEdBQUdvQyxLQUFLLENBQUNFLFNBQU4sQ0FBZ0J0SSxLQUFoQixDQUFzQkMsSUFBdEIsQ0FBMkJvUCxHQUEzQixDQUFYO0FBQ0EsVUFBSXJKLElBQUksQ0FBQy9jLE1BQUwsS0FBZ0IsQ0FBcEIsRUFBdUIsT0FBT3ZDLE9BQU8sQ0FBQyxFQUFELENBQWQ7QUFDdkIsVUFBSTRvQixTQUFTLEdBQUd0SixJQUFJLENBQUMvYyxNQUFyQjs7QUFFQSxlQUFTc21CLEdBQVQsQ0FBYTVrQixDQUFiLEVBQWdCNmtCLEdBQWhCLEVBQXFCO0FBQ2pCLFlBQUk7QUFDQSxjQUFJQSxHQUFHLEtBQUssUUFBT0EsR0FBUCxNQUFlLFFBQWYsSUFBMkIsT0FBT0EsR0FBUCxLQUFlLFVBQS9DLENBQVAsRUFBbUU7QUFDL0QsZ0JBQUkzbUIsSUFBSSxHQUFHMm1CLEdBQUcsQ0FBQzNtQixJQUFmOztBQUNBLGdCQUFJLE9BQU9BLElBQVAsS0FBZ0IsVUFBcEIsRUFBZ0M7QUFDNUJBLGtCQUFJLENBQUNvWCxJQUFMLENBQ0l1UCxHQURKLEVBRUksVUFBU0EsR0FBVCxFQUFjO0FBQ1ZELG1CQUFHLENBQUM1a0IsQ0FBRCxFQUFJNmtCLEdBQUosQ0FBSDtBQUNILGVBSkwsRUFLSTdvQixNQUxKO0FBT0E7QUFDSDtBQUNKOztBQUNEcWYsY0FBSSxDQUFDcmIsQ0FBRCxDQUFKLEdBQVU2a0IsR0FBVjs7QUFDQSxjQUFJLEVBQUVGLFNBQUYsS0FBZ0IsQ0FBcEIsRUFBdUI7QUFDbkI1b0IsbUJBQU8sQ0FBQ3NmLElBQUQsQ0FBUDtBQUNIO0FBQ0osU0FsQkQsQ0FrQkUsT0FBT2tKLEVBQVAsRUFBVztBQUNUdm9CLGdCQUFNLENBQUN1b0IsRUFBRCxDQUFOO0FBQ0g7QUFDSjs7QUFFRCxXQUFLLElBQUl2a0IsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR3FiLElBQUksQ0FBQy9jLE1BQXpCLEVBQWlDMEIsQ0FBQyxFQUFsQyxFQUFzQztBQUNsQzRrQixXQUFHLENBQUM1a0IsQ0FBRCxFQUFJcWIsSUFBSSxDQUFDcmIsQ0FBRCxDQUFSLENBQUg7QUFDSDtBQUNKLEtBbENNLENBQVA7QUFtQ0gsR0FwQ0Q7O0FBc0NBbEUsU0FBTyxDQUFDQyxPQUFSLEdBQWtCLFVBQVNpQyxLQUFULEVBQWdCO0FBQzlCLFFBQUlBLEtBQUssSUFBSSxRQUFPQSxLQUFQLE1BQWlCLFFBQTFCLElBQXNDQSxLQUFLLENBQUM2a0IsV0FBTixLQUFzQi9tQixPQUFoRSxFQUF5RTtBQUNyRSxhQUFPa0MsS0FBUDtBQUNIOztBQUVELFdBQU8sSUFBSWxDLE9BQUosQ0FBWSxVQUFTQyxPQUFULEVBQWtCO0FBQ2pDQSxhQUFPLENBQUNpQyxLQUFELENBQVA7QUFDSCxLQUZNLENBQVA7QUFHSCxHQVJEOztBQVVBbEMsU0FBTyxDQUFDRSxNQUFSLEdBQWlCLFVBQVNnQyxLQUFULEVBQWdCO0FBQzdCLFdBQU8sSUFBSWxDLE9BQUosQ0FBWSxVQUFTQyxPQUFULEVBQWtCQyxNQUFsQixFQUEwQjtBQUN6Q0EsWUFBTSxDQUFDZ0MsS0FBRCxDQUFOO0FBQ0gsS0FGTSxDQUFQO0FBR0gsR0FKRDs7QUFNQWxDLFNBQU8sQ0FBQ2dwQixJQUFSLEdBQWUsVUFBU0MsTUFBVCxFQUFpQjtBQUM1QixXQUFPLElBQUlqcEIsT0FBSixDQUFZLFVBQVNDLE9BQVQsRUFBa0JDLE1BQWxCLEVBQTBCO0FBQ3pDLFdBQUssSUFBSWdFLENBQUMsR0FBRyxDQUFSLEVBQVdva0IsR0FBRyxHQUFHVyxNQUFNLENBQUN6bUIsTUFBN0IsRUFBcUMwQixDQUFDLEdBQUdva0IsR0FBekMsRUFBOENwa0IsQ0FBQyxFQUEvQyxFQUFtRDtBQUMvQytrQixjQUFNLENBQUMva0IsQ0FBRCxDQUFOLENBQVU5QixJQUFWLENBQWVuQyxPQUFmLEVBQXdCQyxNQUF4QjtBQUNIO0FBQ0osS0FKTSxDQUFQO0FBS0gsR0FORCxDQTFPaUIsQ0FrUHJCOzs7QUFDSUYsU0FBTyxDQUFDNm5CLFlBQVIsR0FDSyxPQUFPcUIsWUFBUCxLQUF3QixVQUF4QixJQUNHLFVBQVMvQixFQUFULEVBQWE7QUFDVCtCLGdCQUFZLENBQUMvQixFQUFELENBQVo7QUFDSCxHQUhMLElBSUEsVUFBU0EsRUFBVCxFQUFhO0FBQ1RGLGtCQUFjLENBQUNFLEVBQUQsRUFBSyxDQUFMLENBQWQ7QUFDSCxHQVBMOztBQVNBbm5CLFNBQU8sQ0FBQ3FvQixxQkFBUixHQUFnQyxTQUFTQSxxQkFBVCxDQUErQmMsR0FBL0IsRUFBb0M7QUFDaEUsUUFBSSxPQUFPcm9CLE9BQVAsS0FBbUIsV0FBbkIsSUFBa0NBLE9BQXRDLEVBQStDO0FBQzNDQSxhQUFPLENBQUNzb0IsSUFBUixDQUFhLHVDQUFiLEVBQXNERCxHQUF0RCxFQUQyQyxDQUNpQjtBQUMvRDtBQUNKLEdBSkQ7QUFNQTs7O0FBQ0EsTUFBSUUsUUFBUSxHQUFJLFlBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsUUFBSSxPQUFPdHBCLElBQVAsS0FBZ0IsV0FBcEIsRUFBaUM7QUFDN0IsYUFBT0EsSUFBUDtBQUNIOztBQUNELFFBQUksT0FBT3lILE1BQVAsS0FBa0IsV0FBdEIsRUFBbUM7QUFDL0IsYUFBT0EsTUFBUDtBQUNIOztBQUNELFFBQUksT0FBT2lmLE1BQVAsS0FBa0IsV0FBdEIsRUFBbUM7QUFDL0IsYUFBT0EsTUFBUDtBQUNIOztBQUNELFVBQU0sSUFBSTZDLEtBQUosQ0FBVSxnQ0FBVixDQUFOO0FBQ0gsR0FkYyxFQUFmOztBQWdCQSxNQUFJLEVBQUUsYUFBYUQsUUFBZixDQUFKLEVBQThCO0FBQzFCQSxZQUFRLENBQUMsU0FBRCxDQUFSLEdBQXNCcnBCLE9BQXRCO0FBQ0gsR0FGRCxNQUVPLElBQUksQ0FBQ3FwQixRQUFRLENBQUNycEIsT0FBVCxDQUFpQjZoQixTQUFqQixDQUEyQixTQUEzQixDQUFMLEVBQTRDO0FBQy9Dd0gsWUFBUSxDQUFDcnBCLE9BQVQsQ0FBaUI2aEIsU0FBakIsQ0FBMkIsU0FBM0IsSUFBd0NpRixrQkFBeEM7QUFDSDtBQUVKLENBN1JBLENBQUQsQzs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7QUFLQSxJQUFNeUMsYUFBYSxHQUFHO0FBRWxCO0FBQ0FDLE1BQUksRUFBRTFSLElBQUksQ0FBQ0QsR0FBTCxFQUhZO0FBSWxCd0gsU0FBTyxFQUFFLElBSlM7QUFLbEJvSyxjQUFZLEVBQUUsSUFMSTtBQU1sQkMsY0FBWSxFQUFFLEdBTkk7QUFRbEI7QUFDQUMsdUJBQXFCLEVBQUUsQ0FUTDtBQVVsQkMscUJBQW1CLEVBQUUsSUFWSDtBQVdsQkMsbUJBQWlCLEVBQUUsS0FYRDtBQWFsQjtBQUNBdHFCLE1BQUksRUFBRSxnQkFBWTtBQUVkO0FBQ0FncUIsaUJBQWEsQ0FBQ08sYUFBZCxHQUhjLENBS2Q7O0FBQ0F0aUIsVUFBTSxDQUFDdkYsZ0JBQVAsQ0FBd0IsUUFBeEIsRUFBa0MsWUFBWTtBQUMxQyxVQUFLc25CLGFBQWEsQ0FBQ0MsSUFBZCxHQUFxQkQsYUFBYSxDQUFDRSxZQUFuQyxHQUFrRDNSLElBQUksQ0FBQ0QsR0FBTCxFQUFuRCxHQUFpRSxDQUFyRSxFQUF3RTtBQUNwRTBSLHFCQUFhLENBQUNRLGVBQWQ7QUFDQVIscUJBQWEsQ0FBQ0MsSUFBZCxHQUFxQjFSLElBQUksQ0FBQ0QsR0FBTCxFQUFyQjtBQUNIO0FBQ0osS0FMRCxFQU5jLENBYWQ7O0FBQ0FyUSxVQUFNLENBQUN2RixnQkFBUCxDQUF3QixRQUF4QixFQUFrQyxZQUFZO0FBQzFDc25CLG1CQUFhLENBQUNTLGFBQWQ7QUFDSCxLQUZELEVBZGMsQ0FrQmQ7O0FBQ0F4aUIsVUFBTSxDQUFDdkYsZ0JBQVAsQ0FBd0IsUUFBeEIsRUFBa0MsWUFBWTtBQUMxQyxVQUFHK0IsS0FBSyxDQUFDdWxCLGFBQWEsQ0FBQ2xLLE9BQWYsQ0FBUixFQUFpQy9ULFlBQVksQ0FBQ2llLGFBQWEsQ0FBQ2xLLE9BQWYsQ0FBWjtBQUNqQ2tLLG1CQUFhLENBQUNsSyxPQUFkLEdBQXdCaFYsVUFBVSxDQUFDa2YsYUFBYSxDQUFDVSxlQUFmLEVBQWdDVixhQUFhLENBQUNHLFlBQTlDLENBQWxDO0FBQ0gsS0FIRDtBQUlILEdBckNpQjtBQXVDbEI7QUFDQUksZUFBYSxFQUFFLHlCQUFZO0FBQ3ZCUCxpQkFBYSxDQUFDVyxpQ0FBZDtBQUNILEdBMUNpQjtBQTRDbEI7QUFDQUgsaUJBQWUsRUFBRSwyQkFBWTtBQUN6QjtBQUNBUixpQkFBYSxDQUFDVyxpQ0FBZDtBQUNILEdBaERpQjtBQWtEbEI7QUFDQUQsaUJBQWUsRUFBRSwyQkFBWSxDQUN6QjtBQUNILEdBckRpQjtBQXVEbEI7QUFDQUQsZUFBYSxFQUFFLHlCQUFZO0FBQ3ZCO0FBQ0FULGlCQUFhLENBQUNZLHFCQUFkO0FBQ0FaLGlCQUFhLENBQUNhLGtCQUFkO0FBQ0gsR0E1RGlCO0FBOERsQjtBQUNBO0FBQ0FDLG1DQUFpQyxFQUFFLDJDQUFTbkksRUFBVCxFQUNuQztBQUNJLFFBQUdsZSxLQUFLLENBQUNrZSxFQUFELENBQVIsRUFBYTtBQUVULFVBQU0rQixJQUFJLEdBQUcvQixFQUFFLENBQUM3SyxxQkFBSCxFQUFiLENBRlMsQ0FHVDs7QUFDQSxVQUFNaVQsWUFBWSxHQUFJOWlCLE1BQU0sQ0FBQytpQixXQUFQLElBQXNCOXFCLFFBQVEsQ0FBQzZYLGVBQVQsQ0FBeUJrVCxZQUFyRTtBQUNBLFVBQU1DLFdBQVcsR0FBSWpqQixNQUFNLENBQUNrakIsVUFBUCxJQUFxQmpyQixRQUFRLENBQUM2WCxlQUFULENBQXlCcVQsV0FBbkU7QUFFQSxVQUFNQyxjQUFjLEdBQUkzRyxJQUFJLENBQUMzYyxHQUFMLElBQWFnakIsWUFBZCxJQUFrQ3JHLElBQUksQ0FBQzNjLEdBQUwsR0FBVzJjLElBQUksQ0FBQ3BKLE1BQWpCLElBQTRCLENBQXBGO0FBQ0EsVUFBTWdRLGdCQUFnQixHQUFJNUcsSUFBSSxDQUFDRyxJQUFMLElBQWFxRyxXQUFkLElBQWdDeEcsSUFBSSxDQUFDRyxJQUFMLEdBQVlILElBQUksQ0FBQ25KLEtBQWxCLElBQTRCLENBQXBGO0FBRUEsYUFBUThQLGNBQWMsSUFBSUMsZ0JBQTFCO0FBQ0g7QUFDSixHQTlFaUI7QUFnRmxCO0FBQ0E7QUFDQUMsa0NBQWdDLEVBQUUsMENBQVM1SSxFQUFULEVBQ2xDO0FBQ0ksUUFBR2xlLEtBQUssQ0FBQ2tlLEVBQUQsQ0FBUixFQUFhO0FBQ1QsVUFBTStCLElBQUksR0FBRy9CLEVBQUUsQ0FBQzdLLHFCQUFILEVBQWI7QUFFQSxhQUNJNE0sSUFBSSxDQUFDM2MsR0FBTCxJQUFZLENBQVosSUFDQTJjLElBQUksQ0FBQzhHLE1BQUwsSUFBZXZqQixNQUFNLENBQUMraUIsV0FGMUI7QUFJSDtBQUNKLEdBNUZpQjtBQThGbEJKLHVCQUFxQixFQUFFLGlDQUFZO0FBQy9CLFFBQU1hLGlCQUFpQixHQUFHeGpCLE1BQU0sQ0FBQ2tRLFdBQVAsSUFBc0JqWSxRQUFRLENBQUM2WCxlQUFULENBQXlCRyxTQUF6RSxDQUQrQixDQUNxRDs7QUFDcEYsUUFBSXVULGlCQUFpQixJQUFJekIsYUFBYSxDQUFDSSxxQkFBdkMsRUFBNkQ7QUFDekRKLG1CQUFhLENBQUNLLG1CQUFkLEdBQW9DLElBQXBDO0FBQ0FMLG1CQUFhLENBQUNNLGlCQUFkLEdBQWtDLEtBQWxDO0FBQ0gsS0FIRCxNQUdPO0FBQ0hOLG1CQUFhLENBQUNLLG1CQUFkLEdBQW9DLEtBQXBDO0FBQ0FMLG1CQUFhLENBQUNNLGlCQUFkLEdBQWtDLElBQWxDO0FBQ0g7O0FBQ0ROLGlCQUFhLENBQUNJLHFCQUFkLEdBQXNDcUIsaUJBQXRDO0FBQ0gsR0F4R2lCO0FBMEdsQjtBQUNBO0FBQ0FkLG1DQUFpQyxFQUFFLDZDQUFZO0FBQzNDLFFBQU1lLFFBQVEsR0FBR3hyQixRQUFRLENBQUNrRSxnQkFBVCxDQUEwQixzQkFBMUIsQ0FBakI7QUFDQSxRQUFNdW5CLGNBQWMsR0FBR0QsUUFBUSxDQUFDem9CLE1BQWhDOztBQUVBLFNBQUksSUFBSTZELENBQUMsR0FBRyxDQUFaLEVBQWVBLENBQUMsR0FBRzZrQixjQUFuQixFQUFtQzdrQixDQUFDLEVBQXBDLEVBQXVDO0FBRW5DLFVBQU0rZixPQUFPLEdBQUc2RSxRQUFRLENBQUM1a0IsQ0FBRCxDQUF4Qjs7QUFDQSxVQUFHa2pCLGFBQWEsQ0FBQ2MsaUNBQWQsQ0FBZ0RqRSxPQUFoRCxDQUFILEVBQTREO0FBQ3hEQSxlQUFPLENBQUNwakIsU0FBUixDQUFrQkUsTUFBbEIsQ0FBeUIscUJBQXpCO0FBQ0g7QUFDSjtBQUVKLEdBeEhpQjtBQTBIbEI7QUFFQTtBQUNBa25CLG9CQUFrQixFQUFFLDhCQUFZO0FBQzVCLFFBQU1lLFlBQVksR0FBRzFyQixRQUFRLENBQUM0QixhQUFULENBQXVCLG1CQUF2QixDQUFyQjtBQUNBLFFBQU0rcEIsd0JBQXdCLEdBQUcsMEJBQWpDO0FBQ0EsUUFBTUMsVUFBVSxHQUFHNXJCLFFBQVEsQ0FBQ2tFLGdCQUFULENBQTBCLFlBQTFCLENBQW5CO0FBQ0EsUUFBSTJuQixlQUFlLEdBQUcsS0FBdEI7QUFDQUgsZ0JBQVksQ0FBQzFaLE1BQWIsR0FBc0IsS0FBdEI7O0FBRUEsU0FBSyxJQUFJdk4sQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR21uQixVQUFVLENBQUM3b0IsTUFBL0IsRUFBdUMwQixDQUFDLEVBQXhDLEVBQTRDO0FBQ3hDLFVBQUlzRCxNQUFNLENBQUMrakIsZ0JBQVAsQ0FBd0JGLFVBQVUsQ0FBQ25uQixDQUFELENBQWxDLEVBQXVDLElBQXZDLEVBQTZDc25CLFVBQTdDLElBQTJELFNBQS9ELEVBQTBFO0FBQ3RFLGVBQU9GLGVBQWUsR0FBRyxJQUF6QjtBQUNIO0FBQ0o7O0FBRUQsUUFBR3RuQixLQUFLLENBQUNtbkIsWUFBRCxDQUFMLElBQXVCLENBQUNHLGVBQTNCLEVBQTJDO0FBQ3ZDO0FBQ0EsVUFBRy9CLGFBQWEsQ0FBQ0ssbUJBQWQsSUFBcUNMLGFBQWEsQ0FBQ0kscUJBQWQsR0FBc0MsR0FBOUUsRUFBa0Y7QUFDOUVscUIsZ0JBQVEsQ0FBQ2dFLElBQVQsQ0FBY1QsU0FBZCxDQUF3QkUsTUFBeEIsQ0FBK0Jrb0Isd0JBQS9CO0FBQ0gsT0FGRCxDQUdBO0FBSEEsV0FJSztBQUNEM3JCLGtCQUFRLENBQUNnRSxJQUFULENBQWNULFNBQWQsQ0FBd0JDLEdBQXhCLENBQTRCbW9CLHdCQUE1QjtBQUNIO0FBQ0o7QUFDSjtBQXBKaUIsQ0FBdEI7QUF3SkE3QixhQUFhLENBQUNocUIsSUFBZCxHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lDN0pxQmtzQixXOzs7Ozs7OztBQUNqQjs7Ozs7OzsrQkFPbUJDLEssRUFBa0I7QUFBQSxVQUFYQyxLQUFXLHVFQUFILENBQUc7QUFDakM7QUFDQSxVQUFNQyxLQUFLLEdBQUcsUUFBUUQsS0FBUixHQUFnQixTQUE5QjtBQUNBLGFBQU9GLFdBQVcsQ0FBQ0ksT0FBWixDQUFvQkosV0FBVyxDQUFDSSxPQUFaLENBQW9CSCxLQUFwQixFQUEyQjNLLE9BQTNCLENBQW1DLElBQUkrSyxNQUFKLENBQVdGLEtBQVgsRUFBa0IsR0FBbEIsQ0FBbkMsRUFBMkQsS0FBM0QsQ0FBcEIsQ0FBUDtBQUNIOzs7O0FBRUQ7Ozs7OzRCQUtnQkYsSyxFQUFPO0FBQ25CLFVBQUksT0FBT0EsS0FBUCxLQUFpQixRQUFyQixFQUErQkEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFFBQU4sQ0FBZSxFQUFmLENBQVI7QUFDL0IsYUFBT0wsS0FBSyxDQUFDN2MsS0FBTixDQUFZLEVBQVosRUFBZ0JnZCxPQUFoQixHQUEwQnhMLElBQTFCLENBQStCLEVBQS9CLENBQVA7QUFDSDtBQUVEOzs7Ozs7Ozs7OztxQ0FReUJxTCxLLEVBQXFCO0FBQUEsVUFBZE0sUUFBYyx1RUFBSCxDQUFHO0FBQzFDLFVBQUksT0FBT04sS0FBUCxLQUFpQixRQUFyQixFQUErQkEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFFBQU4sQ0FBZSxFQUFmLENBQVIsQ0FEVyxDQUUxQzs7QUFDQSxVQUFNcEwsTUFBTSxHQUFHakwsUUFBUSxDQUFDZ1csS0FBSyxDQUFDM0ssT0FBTixDQUFjLEtBQWQsRUFBcUIsRUFBckIsQ0FBRCxDQUF2QjtBQUNBLGFBQVEsQ0FBQ2tMLEtBQUssQ0FBQ3RMLE1BQUQsQ0FBUCxHQUFtQkEsTUFBbkIsR0FBNEJxTCxRQUFuQztBQUNIOzs7O0FBRUQ7Ozs7Ozs7O3VDQVEyQjlwQixLLEVBQU9ncUIsSyxFQUFPQyxLLEVBQU87QUFDNUMsVUFBSSxPQUFPanFCLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsTUFBTSxJQUFJb25CLEtBQUosQ0FBVSxvRkFBb0ZwbkIsS0FBcEYsSUFBNkYsR0FBN0YsV0FBMkdncUIsS0FBM0csSUFBb0gsR0FBcEgsV0FBa0lDLEtBQWxJLENBQVYsQ0FBTjtBQUMvQixVQUFJRCxLQUFLLElBQUlocUIsS0FBSyxHQUFHZ3FCLEtBQXJCLEVBQTRCLE9BQU9BLEtBQVA7QUFDNUIsVUFBSUMsS0FBSyxJQUFJanFCLEtBQUssR0FBR2lxQixLQUFyQixFQUE0QixPQUFPQSxLQUFQO0FBQzVCLGFBQU9qcUIsS0FBUDtBQUNIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwREw7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTs7QUFFQSxJQUFHekMsUUFBUSxDQUFDNEIsYUFBVCxDQUF1QixpQkFBdkIsQ0FBSCxFQUE4QztBQUMxQyxNQUFJK3FCLDBDQUFKLENBQVE7QUFDSmxLLE1BQUUsRUFBRSxpQkFEQTtBQUVKbUssY0FBVSxFQUFFO0FBQ1JDLDZCQUF1QixFQUF2QkEsb0VBRFE7QUFFUkMseUJBQW1CLEVBQW5CQSxnRUFBbUJBO0FBRlg7QUFGUixHQUFSO0FBT0gsQzs7Ozs7Ozs7Ozs7O0FDWkQ7QUFBQTtBQUFBO0FBQUE7QUFBc0c7QUFDM0I7QUFDTDs7O0FBR3RFO0FBQ2dHO0FBQ2hHLGdCQUFnQiwyR0FBVTtBQUMxQixFQUFFLDZGQUFNO0FBQ1IsRUFBRSxrR0FBTTtBQUNSLEVBQUUsMkdBQWU7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxJQUFJLEtBQVUsRUFBRSxZQWlCZjtBQUNEO0FBQ2UsZ0Y7Ozs7Ozs7Ozs7OztBQ3RDZjtBQUFBO0FBQUEsd0NBQTZNLENBQWdCLG1RQUFHLEVBQUMsQzs7Ozs7Ozs7Ozs7O0FDQWpPO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7Ozs7Ozs7OztBQ0FBO0FBQUE7QUFBQTtBQUFBO0FBQWtHO0FBQzNCO0FBQ0w7OztBQUdsRTtBQUNnRztBQUNoRyxnQkFBZ0IsMkdBQVU7QUFDMUIsRUFBRSx5RkFBTTtBQUNSLEVBQUUsOEZBQU07QUFDUixFQUFFLHVHQUFlO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsSUFBSSxLQUFVLEVBQUUsWUFpQmY7QUFDRDtBQUNlLGdGOzs7Ozs7Ozs7Ozs7QUN0Q2Y7QUFBQTtBQUFBLHdDQUF5TSxDQUFnQiwrUEFBRyxFQUFDLEM7Ozs7Ozs7Ozs7OztBQ0E3TjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7Ozs7Ozs7QUNBQTtBQUFBO0FBQUE7QUFBQTtBQUFrRztBQUMzQjtBQUNMOzs7QUFHbEU7QUFDZ0c7QUFDaEcsZ0JBQWdCLDJHQUFVO0FBQzFCLEVBQUUseUZBQU07QUFDUixFQUFFLDhGQUFNO0FBQ1IsRUFBRSx1R0FBZTtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLElBQUksS0FBVSxFQUFFLFlBaUJmO0FBQ0Q7QUFDZSxnRjs7Ozs7Ozs7Ozs7O0FDdENmO0FBQUE7QUFBQSx3Q0FBeU0sQ0FBZ0IsK1BBQUcsRUFBQyxDOzs7Ozs7Ozs7Ozs7QUNBN047QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7Ozs7Ozs7Ozs7O0FDQUE7QUFBQTtBQUFBO0FBQUE7QUFBcUc7QUFDM0I7QUFDTDs7O0FBR3JFO0FBQ2dHO0FBQ2hHLGdCQUFnQiwyR0FBVTtBQUMxQixFQUFFLDRGQUFNO0FBQ1IsRUFBRSxpR0FBTTtBQUNSLEVBQUUsMEdBQWU7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxJQUFJLEtBQVUsRUFBRSxZQWlCZjtBQUNEO0FBQ2UsZ0Y7Ozs7Ozs7Ozs7OztBQ3RDZjtBQUFBO0FBQUEsd0NBQTRNLENBQWdCLGtRQUFHLEVBQUMsQzs7Ozs7Ozs7Ozs7O0FDQWhPO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7Ozs7Ozs7O0FDQUEseUMiLCJmaWxlIjoiL2pzL2FwcC5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IEtBTCA9IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGF0dHJpYnV0ZSBwcmVmaXggd2UgdXNlIGZvciBvdXIgYW5pbWF0aW9uIGxpYnJhcnlcbiAgICAgKiBAdHlwZSBzdHJpbmdcbiAgICAgKi9cbiAgICBkYXRhUHJlZml4OiAna2FsJyxcblxuICAgIC8qKlxuICAgICAqIERlZmluZSB0aGUgY2xhc3Mgd2UgdXNlZCB0byBzZXQgdGhlIHN0YXRlcyBvZiB0aGUgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIHN0YXJ0U3RhdGVDbGFzczogJ2lzLWthbC1zdGFydCcsXG4gICAgZW5kU3RhdGVDbGFzczogJ2lzLWthbC1lbmQnLFxuXG4gICAgLyoqXG4gICAgICogRW1wdHkgYmFza2V0IGZvciBwdXR0aW5nIHRoZSBOb2RlRWxlbWVudHMgaW5cbiAgICAgKi9cbiAgICBlbGVtZW50czogW10sXG5cbiAgICAvKipcbiAgICAgKiBEZWZhdWx0IG9wdGlvbnNcbiAgICAgKi9cbiAgICBvcHRpb25zOiB7XG4gICAgICAgIHJvb3Q6IG51bGwsXG4gICAgICAgIHJvb3RNYXJnaW46ICctNDhweCAwcHggLTQ4cHggMHB4JywgLy8gb2Zmc2V0IGZyb20gdGhlIGVkZ2Ugb2YgdGhlIGludGVyc2VjdGlvbiByb290XG4gICAgICAgIHRocmVzaG9sZDogMCwgLy8gVGhlIHZpc3VhbCBwZXJjZW50YWdlIG9mIGNvbXBvbmVudCB3aGVuIGFuaW1hdGlvbiBpcyB0cmlnZ2VyZWRcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRWxlbWVudCBkZWZhdWx0IG9wdGlvbnNcbiAgICAgKi9cbiAgICBlbGVtZW50T3B0aW9uczoge1xuICAgICAgICBvbmNlOiB0cnVlLFxuICAgIH0sXG5cbiAgICAvKiogQHR5cGUge0ludGVyc2VjdGlvbk9ic2VydmVyfSAqL1xuICAgIGludGVyc2VjdGlvbk9ic2VydmVyOiBudWxsLFxuXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGlmKHdpbmRvdy5JbnRlcnNlY3Rpb25PYnNlcnZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0ludGVyc2VjdGlvbk9ic2VydmVyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIEtBTC5lbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJypbZGF0YS0nKyBLQUwuZGF0YVByZWZpeCArJ10nKTtcbiAgICAgICAgaWYoS0FMLmVsZW1lbnRzLmxlbmd0aCA9PT0gMCApIHJldHVybjtcblxuICAgICAgICBLQUwuY3JlYXRlSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRoZSBJbnRlcnNlY3Rpb24gT2JzZXJ2ZXJcbiAgICAgKiBhbmQgYXBwZW5kIHRoZSBLQUwgZWxlbWVudHMgaW50byBpdC5cbiAgICAgKi9cbiAgICBjcmVhdGVJbnRlcnNlY3Rpb25PYnNlcnZlcjogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIEtBTC5pbnRlcnNlY3Rpb25PYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihLQUwub25JbnRlcnNlY3Rpb24sIHtcbiAgICAgICAgICAgIHJvb3Q6IEtBTC5vcHRpb25zLnJvb3QsXG4gICAgICAgICAgICByb290TWFyZ2luOiBLQUwub3B0aW9ucy5yb290TWFyZ2luLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBLQUwub3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIEtBTC5lbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICBLQUwuaW50ZXJzZWN0aW9uT2JzZXJ2ZXIub2JzZXJ2ZShlbGVtZW50KTtcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChLQUwuc3RhcnRTdGF0ZUNsYXNzKTtcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEludGVyc2VjdGlvbk9ic2VydmVyIGNhbGxiYWNrXG4gICAgICogQHBhcmFtICB7QXJyYXk8SW50ZXJzZWN0aW9uT2JzZXJ2ZXJFbnRyeT59IGVudHJpZXNcbiAgICAgKiBAcGFyYW0gIHtJbnRlcnNlY3Rpb25PYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICAgKi9cbiAgICBvbkludGVyc2VjdGlvbjogZnVuY3Rpb24gKGVudHJpZXMsIG9ic2VydmVyKSB7XG4gICAgICAgIGVudHJpZXMuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHtcblxuICAgICAgICAgICAgLy8gV2hlbiBlbGVtZW50J3MgaXMgaW4gdmlld3BvcnQgYW5kIHdpdGhpbiB0aHJlc2hvbGQsXG4gICAgICAgICAgICAvLyBUcmlnZ2VyIGFuaW1hdGlvbiFcbiAgICAgICAgICAgIGlmIChlbnRyeS5pbnRlcnNlY3Rpb25SYXRpbyA+IEtBTC5vcHRpb25zLnRocmVzaG9sZCkge1xuXG4gICAgICAgICAgICAgICAgS0FMLnRyaWdnZXJBbmltYXRpb24oZW50cnkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKEtBTC5nZXRFbGVtZW50T3B0aW9uKGVudHJ5LnRhcmdldCwgJ29uY2UnKSkge1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci51bm9ic2VydmUoZW50cnkudGFyZ2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFLQUwuZ2V0RWxlbWVudE9wdGlvbihlbnRyeS50YXJnZXQsICdvbmNlJykpIHtcblxuICAgICAgICAgICAgICAgIC8vIFJldmVyc2UgdGhlIGFuaW1hdGlvbiBpZiBvcHRpb25zIGlzIG5vdCBvbmNlXG4gICAgICAgICAgICAgICAgS0FMLnJldmVyc2VBbmltYXRpb24oZW50cnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2xlYXIgdGhlIGludGVyc2VjdGlvbiBvYnNlcnZlci5cbiAgICAgKi9cbiAgICBjbGVhckludGVyc2VjdGlvbk9ic2VydmVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICBLQUwuaW50ZXJzZWN0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgS0FMLmludGVyc2VjdGlvbk9ic2VydmVyID0gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGFuIGFuaW1hdGlvbiBvcHRpb24gb2YgdGhlIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZWxlbWVudFxuICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVcbiAgICAgKi9cbiAgICBnZXRFbGVtZW50T3B0aW9uOiBmdW5jdGlvbiAoZWxlbWVudCwgYXR0cmlidXRlKVxuICAgIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtJysgS0FMLmRhdGFQcmVmaXggKyAnLScgKyBhdHRyaWJ1dGUpO1xuXG4gICAgICAgIGlmKG9wdGlvbiAhPT0gbnVsbCl7XG5cbiAgICAgICAgICAgIC8vIE1hcCB0aGUgYXR0cmlidXRlcyB2YWx1ZXMgaW50byB0aGUgcmlnaHQgdHlwZVxuICAgICAgICAgICAgc3dpdGNoIChhdHRyaWJ1dGUpIHtcblxuICAgICAgICAgICAgICAgIC8vIEJvb2xlYW4gYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgIGNhc2UgJ29uY2UnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG9wdGlvbiA9PSAndHJ1ZScpO1xuXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gS0FMLmVsZW1lbnRPcHRpb25zW2F0dHJpYnV0ZV07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgYW5pbWF0aW9uXG4gICAgICogQHBhcmFtIHtJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5fSBlbnRyeVxuICAgICAqL1xuICAgIHRyaWdnZXJBbmltYXRpb246IGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZW50cnkudGFyZ2V0O1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoS0FMLnN0YXJ0U3RhdGVDbGFzcyk7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChLQUwuZW5kU3RhdGVDbGFzcyk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJldmVyc2UgYW5pbWF0aW9uXG4gICAgICogQHBhcmFtIHtJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5fSBlbnRyeVxuICAgICAqL1xuICAgIHJldmVyc2VBbmltYXRpb246IGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZW50cnkudGFyZ2V0O1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoS0FMLnN0YXJ0U3RhdGVDbGFzcyk7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShLQUwuZW5kU3RhdGVDbGFzcyk7XG4gICAgfSxcbn07XG5cbmV4cG9ydCB7IEtBTCB9IiwiPHRlbXBsYXRlPlxuICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX21haW5cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fY29udHJvbHNcIj5cbiAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJvLWNhbGN1bGF0ZV9faGVhZGluZ1wiPnt7IHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLmNhbGN1bGF0ZV9mb3JtLmhlYWRpbmcgfX08L2gyPlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm8tY2FsY3VsYXRlX19zbGlkZXJzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwYXliYWNrLXBlcmlvZC1pbnRha2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHYtYmluZDp0cmFuc2xhdGlvbnM9XCJ0aGlzLnRyYW5zbGF0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6Y29uZmlnPVwidGhpcy5jb25maWdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdi1vbjppbnB1dHNDaGFuZ2VkPVwidXBkYXRlUmVzdWx0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uLWRhcmtcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8cGF5YmFjay1wZXJpb2QtcmVzdWx0LXRhYmxlXG4gICAgICAgICAgICAgICAgdi1iaW5kOnRyYW5zbGF0aW9ucz1cInRoaXMudHJhbnNsYXRpb25zXCJcbiAgICAgICAgICAgICAgICB2LWJpbmQ9XCJ0aGlzLnJlc3VsdHNcIlxuICAgICAgICAgICAgLz5cblxuICAgICAgICAgICAgPHNsb3QgbmFtZT1cImNhbGN1bGF0ZS1jb250YWN0XCIvPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG4gICAgaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xuICAgIGltcG9ydCBwYXliYWNrUGVyaW9kSW50YWtlIGZyb20gJy4vcGF5YmFja1BlcmlvZEludGFrZS52dWUnXG4gICAgaW1wb3J0IHBheWJhY2tQZXJpb2RSZXN1bHRUYWJsZSBmcm9tICcuL3BheWJhY2tQZXJpb2RSZXN1bHQudnVlJ1xuXG4gICAgZXhwb3J0IGRlZmF1bHQge1xuICAgICAgICBuYW1lOiAncGF5YmFjay1wZXJpb2QtY2FsY3VsYXRvcicsXG4gICAgICAgIGNvbXBvbmVudHM6IHtcbiAgICAgICAgICAgIHBheWJhY2tQZXJpb2RJbnRha2UsXG4gICAgICAgICAgICBwYXliYWNrUGVyaW9kUmVzdWx0VGFibGVcbiAgICAgICAgfSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgICd0cmFuc2xhdGlvbnMnOiB7ICd0eXBlJzogU3RyaW5nfSxcbiAgICAgICAgICAgICdjb25maWcnOiB7ICd0eXBlJzogU3RyaW5nfVxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHBhcnNlZFRyYW5zbGF0aW9uczoge30sXG4gICAgICAgICAgICAgICAgcGFyc2VkQ29uZmlnOiB7fSxcbiAgICAgICAgICAgICAgICByZXN1bHRzOiB7XG4gICAgICAgICAgICAgICAgICAgIGludmVzdG1lbnRDb3N0czogMCxcbiAgICAgICAgICAgICAgICAgICAgcGVzdGljaWRlU2F2aW5nczogMCxcbiAgICAgICAgICAgICAgICAgICAgcGF5YmFja1RpbWU6IDAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY3JlYXRlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucyA9IEpTT04ucGFyc2UodGhpcy50cmFuc2xhdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5wYXJzZWRDb25maWcgPSBKU09OLnBhcnNlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgfSxcbiAgICAgICAgbWV0aG9kczoge1xuICAgICAgICAgICAgdXBkYXRlUmVzdWx0KGV2ZW50KXtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZShldmVudCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBjYWxjdWxhdGUoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgaW52ZXN0bWVudENvc3RzID0gKGV2ZW50LndpZHRoQ2FsY3VsYXRlZCAqIDgwMCk7XG4gICAgICAgICAgICAgICAgbGV0IHBlc3RpY2lkZVNhdmluZ3MgPSAoZXZlbnQuc2F2aW5nc0NhbGN1bGF0ZWQgLyAxMDApICogZXZlbnQuY29zdHNDYWxjdWxhdGVkO1xuICAgICAgICAgICAgICAgIGxldCBwYXliYWNrVGltZSA9IChpbnZlc3RtZW50Q29zdHMgLyBwZXN0aWNpZGVTYXZpbmdzKTtcblxuICAgICAgICAgICAgICAgIHRoaXMucmVzdWx0cy5wYXliYWNrVGltZSA9IHBheWJhY2tUaW1lO1xuICAgICAgICAgICAgICAgIHRoaXMucmVzdWx0cy5pbnZlc3RtZW50Q29zdHMgPSBpbnZlc3RtZW50Q29zdHM7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXN1bHRzLnBlc3RpY2lkZVNhdmluZ3MgPSBwZXN0aWNpZGVTYXZpbmdzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9O1xuPC9zY3JpcHQ+IiwiPHRlbXBsYXRlPlxuICAgIDxkaXYgdi1iaW5kOmNsYXNzPVwiWydjLXJhbmdlLXNsaWRlcnMnLCB7ICdjLXJhbmdlLXNsaWRlcnMtLW9uLWRhcmsnOm9uRGFyayB9XVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYy1yYW5nZS1zbGlkZXJzX19yb3dcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImMtcmFuZ2Utc2xpZGVyc19fbGFiZWxcIlxuICAgICAgICAgICAgICAgICAgIGZvcj1cInNsaWRlci12YWx1ZS13aWR0aFwiPnt7IHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMud2lkdGgubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImMtcmFuZ2Utc2xpZGVyc19fbWV0ZXJcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgIGNsYXNzPVwiYy1pbnB1dC1yYW5nZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInJhbmdlU2xpZGVyV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhbmdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ3aWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBAaW5wdXQ9XCJzbGlkZXJDaGFuZ2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9XCJzbGlkZXJDaGFuZ2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHYtYmluZDp2YWx1ZT10aGlzLndpZHRoQ2FsY3VsYXRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgdi1iaW5kOm1pbj1cInRoaXMucGFyc2VkQ29uZmlnLndpZHRoLm1pblwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6bWF4PVwidGhpcy5wYXJzZWRDb25maWcud2lkdGgubWF4XCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPHBheWJhY2stcGVyaW9kLXRleHQtaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcj1cInJhbmdlU2xpZGVySW5wdXRXaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgIHYtYmluZDpzdGVwPTFcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOnZhbHVlPXdpZHRoQ2FsY3VsYXRlZFxuICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6bWluPVwidGhpcy5wYXJzZWRDb25maWcud2lkdGgubWluXCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOm1heD1cInRoaXMucGFyc2VkQ29uZmlnLndpZHRoLm1heFwiXG4gICAgICAgICAgICAgICAgICAgIHYtYmluZDpsYWJlbFRleHQ9XCJ0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5zbGlkZXJzLndpZHRoLnVuaXRcIlxuICAgICAgICAgICAgICAgICAgICBAY2hhbmdlPVwicXVhbnRpdHlJbnB1dENoYW5nZWRcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX3Jvd1wiPlxuXG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX2xhYmVsXCJcbiAgICAgICAgICAgICAgICAgICBmb3I9XCJzbGlkZXItdmFsdWUtY29zdHNcIiB2LWh0bWw9XCJ0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5zbGlkZXJzLmNvc3RzLmxhYmVsXCI+PC9sYWJlbD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX21ldGVyXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0ICBjbGFzcz1cImMtaW5wdXQtcmFuZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJyYW5nZVNsaWRlckNvc3RzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJyYW5nZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGVwPVwiNTAwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiY29zdHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlucHV0PVwic2xpZGVyQ2hhbmdlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBAY2hhbmdlPVwic2xpZGVyQ2hhbmdlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6dmFsdWU9dGhpcy5jb3N0c0NhbGN1bGF0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHYtYmluZDptaW49XCJ0aGlzLnBhcnNlZENvbmZpZy5jb3N0cy5taW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgdi1iaW5kOm1heD1cInRoaXMucGFyc2VkQ29uZmlnLmNvc3RzLm1heFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8cGF5YmFjay1wZXJpb2QtdGV4dC1pbnB1dFxuICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyPVwicmFuZ2VTbGlkZXJJbnB1dENvc3RzXCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOnN0ZXA9NTAwMFxuICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6dmFsdWU9Y29zdHNDYWxjdWxhdGVkXG4gICAgICAgICAgICAgICAgICAgIHYtYmluZDptaW49XCJ0aGlzLnBhcnNlZENvbmZpZy5jb3N0cy5taW5cIlxuICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6bWF4PVwidGhpcy5wYXJzZWRDb25maWcuY29zdHMubWF4XCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOmZvckN1cnJlbmN5PXRydWVcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOmxhYmVsVGV4dD1cInRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMuY29zdHMudW5pdFwiXG4gICAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9XCJxdWFudGl0eUlucHV0Q2hhbmdlZFwiXG4gICAgICAgICAgICAvPlxuXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYy1yYW5nZS1zbGlkZXJzX19yb3dcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImMtcmFuZ2Utc2xpZGVyc19fbGFiZWxcIlxuICAgICAgICAgICAgICAgICAgIGZvcj1cInNsaWRlci12YWx1ZS1zYXZpbmdzXCI+e3sgdGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMuc2xpZGVycy5zYXZpbmdzLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX21ldGVyXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0ICBjbGFzcz1cImMtaW5wdXQtcmFuZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJyYW5nZVNsaWRlclNhdmluZ3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhbmdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzYXZpbmdzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpbnB1dD1cInNsaWRlckNoYW5nZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgQGNoYW5nZT1cInNsaWRlckNoYW5nZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdi1iaW5kOnZhbHVlPXRoaXMuc2F2aW5nc0NhbGN1bGF0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHYtYmluZDptaW49XCJ0aGlzLnBhcnNlZENvbmZpZy5zYXZpbmdzLm1pblwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6bWF4PVwidGhpcy5wYXJzZWRDb25maWcuc2F2aW5ncy5tYXhcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHBheWJhY2stcGVyaW9kLXRleHQtaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcj1cInJhbmdlU2xpZGVySW5wdXRTYXZpbmdzXCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOnN0ZXA9MVxuICAgICAgICAgICAgICAgICAgICB2LWJpbmQ6dmFsdWU9c2F2aW5nc0NhbGN1bGF0ZWRcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOm1pbj1cInRoaXMucGFyc2VkQ29uZmlnLnNhdmluZ3MubWluXCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOm1heD1cInRoaXMucGFyc2VkQ29uZmlnLnNhdmluZ3MubWF4XCJcbiAgICAgICAgICAgICAgICAgICAgdi1iaW5kOmxhYmVsVGV4dD1cInRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMuc2F2aW5ncy51bml0XCJcbiAgICAgICAgICAgICAgICAgICAgQGNoYW5nZT1cInF1YW50aXR5SW5wdXRDaGFuZ2VkXCJcbiAgICAgICAgICAgIC8+XG5cbiAgICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG4gICAgaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xuICAgIGltcG9ydCBwYXliYWNrUGVyaW9kVGV4dElucHV0IGZyb20gJy4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWUnXG4gICAgaW1wb3J0IEZvcm1hdFV0aWxzIGZyb20gXCIuL2Zvcm1hdFV0aWxzXCI7XG5cbiAgICBleHBvcnQgZGVmYXVsdHtcbiAgICAgICAgbmFtZTogJ3BheWJhY2stcGVyaW9kLWludGFrZScsXG4gICAgICAgIGNvbXBvbmVudHM6IHtcbiAgICAgICAgICAgIHBheWJhY2tQZXJpb2RUZXh0SW5wdXQsXG4gICAgICAgIH0sXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICAndHJhbnNsYXRpb25zJzogeyAndHlwZSc6IFN0cmluZ30sXG4gICAgICAgICAgICAnY29uZmlnJzogeyAndHlwZSc6IFN0cmluZ30sXG4gICAgICAgICAgICAnb25EYXJrJzogeyAndHlwZSc6IEJvb2xlYW59LFxuICAgICAgICAgICAgc3RlcDoge3R5cGU6IE51bWJlciwgZGVmYXVsdCA6IDF9LFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHBhcnNlZFRyYW5zbGF0aW9uczoge30sXG4gICAgICAgICAgICAgICAgcGFyc2VkQ29uZmlnOiB7fSxcbiAgICAgICAgICAgICAgICB3aWR0aENhbGN1bGF0ZWQ6IDAsXG4gICAgICAgICAgICAgICAgY29zdHNDYWxjdWxhdGVkOiAwLFxuICAgICAgICAgICAgICAgIHNhdmluZ3NDYWxjdWxhdGVkOiAwLFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGxldCB1cmkgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIGxldCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHVyaSk7XG4gICAgICAgICAgICB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucyA9IEpTT04ucGFyc2UodGhpcy50cmFuc2xhdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5wYXJzZWRDb25maWcgPSBKU09OLnBhcnNlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgICAgIHRoaXMud2lkdGhDYWxjdWxhdGVkID0gcGFyc2VJbnQocGFyYW1zLmdldChcIndpZHRoXCIpKSB8fCBwYXJzZUludCh0aGlzLnBhcnNlZENvbmZpZy53aWR0aC5pbml0aWFsKTtcbiAgICAgICAgICAgIHRoaXMuY29zdHNDYWxjdWxhdGVkID0gcGFyc2VJbnQocGFyYW1zLmdldChcImNvc3RzXCIpKSB8fCBwYXJzZUludCh0aGlzLnBhcnNlZENvbmZpZy5jb3N0cy5pbml0aWFsKTtcbiAgICAgICAgICAgIHRoaXMuc2F2aW5nc0NhbGN1bGF0ZWQgPSBwYXJzZUludChwYXJhbXMuZ2V0KFwic2F2aW5nc1wiKSkgfHwgcGFyc2VJbnQodGhpcy5wYXJzZWRDb25maWcuc2F2aW5ncy5pbml0aWFsKTtcbiAgICAgICAgICAgIHRoaXMucXVhbnRpdHlJbnB1dENoYW5nZWQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgbWV0aG9kczoge1xuICAgICAgICAgICAgcXVhbnRpdHlJbnB1dENoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBpZihldmVudCl7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JhbmdlU2xpZGVySW5wdXRXaWR0aCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53aWR0aENhbGN1bGF0ZWQgPSBldmVudC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JhbmdlU2xpZGVySW5wdXRDb3N0cyc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3N0c0NhbGN1bGF0ZWQgPSBldmVudC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JhbmdlU2xpZGVySW5wdXRTYXZpbmdzJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNhdmluZ3NDYWxjdWxhdGVkID0gZXZlbnQudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUGFyZW50cygpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNsaWRlckNoYW5nZWQoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnRhcmdldC5pZCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyYW5nZVNsaWRlcldpZHRoJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGhDYWxjdWxhdGVkID0gRm9ybWF0VXRpbHMuY29udmVydFRvSW50ZWdlcihldmVudC50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JhbmdlU2xpZGVyQ29zdHMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3N0c0NhbGN1bGF0ZWQgPSBGb3JtYXRVdGlscy5jb252ZXJ0VG9JbnRlZ2VyKGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmFuZ2VTbGlkZXJTYXZpbmdzJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2F2aW5nc0NhbGN1bGF0ZWQgPSBGb3JtYXRVdGlscy5jb252ZXJ0VG9JbnRlZ2VyKGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVQYXJlbnRzKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXBkYXRlUGFyZW50cygpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KCdpbnB1dHNDaGFuZ2VkJywge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aENhbGN1bGF0ZWQ6IHBhcnNlSW50KHRoaXMud2lkdGhDYWxjdWxhdGVkKSxcbiAgICAgICAgICAgICAgICAgICAgY29zdHNDYWxjdWxhdGVkOiBwYXJzZUludCh0aGlzLmNvc3RzQ2FsY3VsYXRlZCksXG4gICAgICAgICAgICAgICAgICAgIHNhdmluZ3NDYWxjdWxhdGVkOiBwYXJzZUludCh0aGlzLnNhdmluZ3NDYWxjdWxhdGVkKSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgfTtcbjwvc2NyaXB0PiIsIjx0ZW1wbGF0ZT5cbiAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX3RhYmxlXCIgcm9sZT1cImdyaWRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm8tY2FsY3VsYXRlX19yb3dcIiByb2xlPVwicm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX2xhYmVsICB1LWZ3LWJvbGRcIlxuICAgICAgICAgICAgICAgICByb2xlPVwiZ3JpZGNlbGxcIj57eyB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy50YWJsZS50aXRsZSB9fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX3Jvd1wiIHJvbGU9XCJyb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fbGFiZWxcIiByb2xlPVwiZ3JpZGNlbGxcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy50YWJsZS5pbnZlc3RtZW50Q29zdHMgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fdmFsdWVcIiByb2xlPVwiZ3JpZGNlbGxcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInUtZnctYm9sZFwiPiZldXJvOyB7eyB0aGlzLmludmVzdG1lbnRDb3N0c0Zvcm1hdHRlZCB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX3Jvd1wiIHJvbGU9XCJyb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fbGFiZWxcIiByb2xlPVwiZ3JpZGNlbGxcIj57eyB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy50YWJsZS5wZXN0aWNpZGVTYXZpbmdzIH19PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX3ZhbHVlXCIgcm9sZT1cImdyaWRjZWxsXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ1LWZ3LWJvbGRcIj4mZXVybzsge3sgdGhpcy5wZXN0aWNpZGVTYXZpbmdzRm9ybWF0dGVkIH19PC9zcGFuPiB7eyB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5wZXJZZWFyIH19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm8tY2FsY3VsYXRlX19mb290ZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fcm93XCIgcm9sZT1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvLWNhbGN1bGF0ZV9fbGFiZWxcIiByb2xlPVwiZ3JpZGNlbGxcIj57eyB0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy50YWJsZS5wYXliYWNrVGltZSB9fTo8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiby1jYWxjdWxhdGVfX3ZhbHVlXCIgcm9sZT1cImdyaWRjZWxsXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidS1mdy1ib2xkXCI+e3sgdGhpcy5wYXliYWNrVGltZUZvcm1hdHRlZCB9fTwvc3Bhbj4ge3sgdGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMueWVhciB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbiAgICBpbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XG4gICAgaW1wb3J0IEZvcm1hdFV0aWxzIGZyb20gXCIuL2Zvcm1hdFV0aWxzXCI7XG5cbiAgICBleHBvcnQgZGVmYXVsdCB7XG4gICAgICAgIG5hbWU6ICdwYXliYWNrLXBlcmlvZC1yZXN1bHQtdGFibGUnLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgJ3RyYW5zbGF0aW9ucyc6IHsgJ3R5cGUnOiBTdHJpbmd9LFxuICAgICAgICAgICAgJ2ludmVzdG1lbnRDb3N0cyc6IHsgJ3R5cGUnOiBOdW1iZXJ9LFxuICAgICAgICAgICAgJ3Blc3RpY2lkZVNhdmluZ3MnOiB7ICd0eXBlJzogTnVtYmVyfSxcbiAgICAgICAgICAgICdwYXliYWNrVGltZSc6IHsgJ3R5cGUnOiBOdW1iZXJ9LFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHBhcnNlZFRyYW5zbGF0aW9uczoge30sXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMgPSBKU09OLnBhcnNlKHRoaXMudHJhbnNsYXRpb25zKTtcbiAgICAgICAgfSxcbiAgICAgICAgY29tcHV0ZWQ6IHtcbiAgICAgICAgICAgIGludmVzdG1lbnRDb3N0c0Zvcm1hdHRlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZvcm1hdFV0aWxzLmluc2VydERvdHModGhpcy5pbnZlc3RtZW50Q29zdHMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBlc3RpY2lkZVNhdmluZ3NGb3JtYXR0ZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBGb3JtYXRVdGlscy5pbnNlcnREb3RzKHRoaXMucGVzdGljaWRlU2F2aW5ncy50b0ZpeGVkKDApKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXliYWNrVGltZUZvcm1hdHRlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGF5YmFja1RpbWUudG9GaXhlZCgyKS5yZXBsYWNlKCcuJywgJywnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICB9O1xuPC9zY3JpcHQ+IiwiPHRlbXBsYXRlPlxuICAgIDxkaXYgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX2RldGFpbHNcIj5cbiAgICAgICAgPGlucHV0ICBjbGFzcz1cImMtcmFuZ2Utc2xpZGVyc19fdmFsdWVcIlxuICAgICAgICAgICAgICAgIDpkaXNhYmxlZD1cInRydWVcIlxuICAgICAgICAgICAgICAgIDppZD1cImlkZW50aWZpZXJcIlxuICAgICAgICAgICAgICAgIGRhdGEtbHBpZ25vcmU9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgQGtleWRvd249XCJrZXlQcmVzc2VkXCJcbiAgICAgICAgICAgICAgICB2LW1vZGVsPVwiZGlzcGxheVZhbHVlXCJcbiAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAvPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJjLXJhbmdlLXNsaWRlcnNfX3VuaXRcIlxuICAgICAgICAgICAgICAgOmZvcj1cImlkZW50aWZpZXJcIiB2LWh0bWw9XCJ0aGlzLmxhYmVsVGV4dFwiPjwvbGFiZWw+XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuICAgIGltcG9ydCBGb3JtYXRVdGlscyBmcm9tICcuL2Zvcm1hdFV0aWxzJ1xuXG4gICAgZXhwb3J0IGRlZmF1bHQge1xuICAgICAgICBuYW1lOiAncGF5YmFjay1wZXJpb2QtdGV4dC1pbnB1dCcsXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBpZGVudGlmaWVyOiB7IHR5cGU6IFN0cmluZywgcmVxdWlyZWQ6IHRydWUgfSxcbiAgICAgICAgICAgIHZhbHVlOiB7IHR5cGU6IE51bWJlciB9LFxuICAgICAgICAgICAgbWluOiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogMSB9LFxuICAgICAgICAgICAgbWF4OiB7IHR5cGU6IE51bWJlciwgZGVmYXVsdDogbnVsbCB9LFxuICAgICAgICAgICAgc3RlcDogeyB0eXBlOiBOdW1iZXIsIGRlZmF1bHQ6IDUgfSxcbiAgICAgICAgICAgIGZvckN1cnJlbmN5OiB7IHR5cGU6IEJvb2xlYW4sIGRlZmF1bHQ6IGZhbHNlIH0sXG4gICAgICAgICAgICBsYWJlbFRleHQ6IHsgdHlwZTogU3RyaW5nLCBkZWZhdWx0OiAnJyB9LFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG1ldGhvZHM6IHtcbiAgICAgICAgICAgIGtleVByZXNzZWQ6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGlmeVZhbHVlKHRoaXMuc3RlcClcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93RG93bicpIHRoaXMubW9kaWZ5VmFsdWUoLXRoaXMuc3RlcClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtb2RpZnlWYWx1ZSAoYW1vdW50KSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gRm9ybWF0VXRpbHMuY29udmVydFRvSW50ZWdlcih0aGlzLmludGVybmFsVmFsdWUpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gRm9ybWF0VXRpbHMuZm9yY2VUb0JlSW5SYW5nZU9mKHZhbHVlICs9IGFtb3VudCwgdGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JDdXJyZW5jeSkgdmFsdWUgPSBGb3JtYXRVdGlscy5pbnNlcnREb3RzKHZhbHVlLnRvU3RyaW5nKDEwKSwgMyk7XG4gICAgICAgICAgICAgICAgdGhpcy4kZW1pdCgnY2hhbmdlJywge3ZhbHVlOiBGb3JtYXRVdGlscy5jb252ZXJ0VG9JbnRlZ2VyKHZhbHVlKSwgaWQ6IHRoaXMuaWRlbnRpZmllcn0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wdXRlZDoge1xuICAgICAgICAgICAgaW50ZXJuYWxWYWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwbGF5VmFsdWU6IHtcbiAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gRm9ybWF0VXRpbHMuY29udmVydFRvSW50ZWdlcih0aGlzLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBGb3JtYXRVdGlscy5mb3JjZVRvQmVJblJhbmdlT2YodmFsdWUsIHRoaXMubWluLCB0aGlzLm1heCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmZvckN1cnJlbmN5KSB2YWx1ZSA9IEZvcm1hdFV0aWxzLmluc2VydERvdHModmFsdWUudG9TdHJpbmcoMTApLCAzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gRm9ybWF0VXRpbHMuY29udmVydFRvSW50ZWdlcihuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gRm9ybWF0VXRpbHMuZm9yY2VUb0JlSW5SYW5nZU9mKHZhbHVlLCB0aGlzLm1pbiwgdGhpcy5tYXgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JDdXJyZW5jeSkgdmFsdWUgPSBGb3JtYXRVdGlscy5pbnNlcnREb3RzKHZhbHVlLnRvU3RyaW5nKDEwKSwgMyk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuaW50ZXJuYWxWYWx1ZSA9IEZvcm1hdFV0aWxzLmNvbnZlcnRUb0ludGVnZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KCdjaGFuZ2UnLCB7dmFsdWU6IEZvcm1hdFV0aWxzLmNvbnZlcnRUb0ludGVnZXIodmFsdWUpLCBpZDogdGhpcy5pZGVudGlmaWVyfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGZvcmNlVXBkYXRlKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgfTtcbjwvc2NyaXB0PiIsImxldCB0aW1lckRlYm91bmNlID0gdW5kZWZpbmVkO1xuZnVuY3Rpb24gZGVib3VuY2UoZHVyYXRpb24sIGNhbGxiYWNrKSB7XG4gIGNsZWFyVGltZW91dCh0aW1lckRlYm91bmNlKTtcbiAgdGltZXJEZWJvdW5jZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGNhbGxiYWNrKCk7XG4gIH0sIGR1cmF0aW9uKTtcbiAgcmV0dXJuIHRpbWVyRGVib3VuY2U7XG59XG5mdW5jdGlvbiB0cmFuc2l0aW9uQXNQcm9taXNlKHRyaWdnZXJpbmdGdW5jLCBlbCkge1xuICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgY29uc3QgaGFuZGxlVHJhbnNpdGlvbkVuZCA9ICgpID0+IHtcbiAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBoYW5kbGVUcmFuc2l0aW9uRW5kKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZVRyYW5zaXRpb25FbmQpO1xuICAgIGNvbnN0IGNsYXNzZXNCZWZvcmUgPSBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJyk7XG4gICAgY29uc3Qgc3R5bGVzQmVmb3JlID0gZWwuZ2V0QXR0cmlidXRlKCdzdHlsZScpO1xuICAgIHRyaWdnZXJpbmdGdW5jKCk7XG5cbiAgICBpZiAoY2xhc3Nlc0JlZm9yZSA9PT0gZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpICYmIHN0eWxlc0JlZm9yZSA9PT0gZWwuZ2V0QXR0cmlidXRlKCdzdHlsZScpKSB7XG4gICAgICBoYW5kbGVUcmFuc2l0aW9uRW5kKCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZShlbClbJ3RyYW5zaXRpb25EdXJhdGlvbiddKSA9PT0gMCkge1xuICAgICAgaGFuZGxlVHJhbnNpdGlvbkVuZCgpO1xuICAgIH1cbiAgfSk7XG59XG5mdW5jdGlvbiBsb2FkSW1hZ2Uoe1xuICBzcmMsXG4gIHNyY3NldCxcbiAgc2l6ZXNcbn0pIHtcbiAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgaW1hZ2Uuc3JjID0gc3JjO1xuXG4gIGlmIChzcmNzZXQpIHtcbiAgICBpbWFnZS5zcmNzZXQgPSBzcmNzZXQ7XG4gIH1cblxuICBpZiAoc2l6ZXMpIHtcbiAgICBpbWFnZS5zaXplcyA9IHNpemVzO1xuICB9XG5cbiAgaWYgKCdkZWNvZGUnIGluIGltYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGltYWdlLmRlY29kZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXNvbHZlKGltYWdlKTtcbiAgICAgIH0pLmNhdGNoKCgpID0+IHtcbiAgICAgICAgcmVqZWN0KGltYWdlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpbWFnZS5vbmxvYWQgPSByZXNvbHZlKGltYWdlKTtcbiAgICAgIGltYWdlLm9uZXJyb3IgPSByZWplY3QoaW1hZ2UpO1xuICAgIH0pO1xuICB9XG59XG5mdW5jdGlvbiBmaXQob3B0aW9ucykge1xuICBsZXQgaGVpZ2h0O1xuICBsZXQgd2lkdGg7XG4gIGNvbnN0IHtcbiAgICBpbWdIZWlnaHQsXG4gICAgaW1nV2lkdGgsXG4gICAgY29udGFpbmVySGVpZ2h0LFxuICAgIGNvbnRhaW5lcldpZHRoLFxuICAgIGNhbnZhc1dpZHRoLFxuICAgIGNhbnZhc0hlaWdodCxcbiAgICBpbWFnZVNpemVcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGNhbnZhc1JhdGlvID0gY2FudmFzSGVpZ2h0IC8gY2FudmFzV2lkdGg7XG4gIGNvbnN0IGNvbnRhaW5lclJhdGlvID0gY29udGFpbmVySGVpZ2h0IC8gY29udGFpbmVyV2lkdGg7XG4gIGNvbnN0IGltZ1JhdGlvID0gaW1nSGVpZ2h0IC8gaW1nV2lkdGg7XG5cbiAgaWYgKGltYWdlU2l6ZSA9PSAnY292ZXInKSB7XG4gICAgaWYgKGltZ1JhdGlvIDwgY29udGFpbmVyUmF0aW8pIHtcbiAgICAgIGhlaWdodCA9IGNvbnRhaW5lckhlaWdodDtcbiAgICAgIHdpZHRoID0gaGVpZ2h0IC8gaW1nUmF0aW87XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpZHRoID0gY29udGFpbmVyV2lkdGg7XG4gICAgICBoZWlnaHQgPSB3aWR0aCAqIGltZ1JhdGlvO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpbWFnZVNpemUgPT0gJ25hdGl2ZScpIHtcbiAgICBoZWlnaHQgPSBpbWdIZWlnaHQ7XG4gICAgd2lkdGggPSBpbWdXaWR0aDtcbiAgfSBlbHNlIHtcbiAgICBpZiAoaW1nUmF0aW8gPiBjYW52YXNSYXRpbykge1xuICAgICAgaGVpZ2h0ID0gY2FudmFzSGVpZ2h0O1xuICAgICAgd2lkdGggPSBoZWlnaHQgLyBpbWdSYXRpbztcbiAgICB9IGVsc2Uge1xuICAgICAgd2lkdGggPSBjYW52YXNXaWR0aDtcbiAgICAgIGhlaWdodCA9IHdpZHRoICogaW1nUmF0aW87XG4gICAgfVxuXG4gICAgaWYgKGltYWdlU2l6ZSA9PT0gJ3NjYWxlLWRvd24nICYmICh3aWR0aCA+PSBpbWdXaWR0aCB8fCBoZWlnaHQgPj0gaW1nSGVpZ2h0KSkge1xuICAgICAgd2lkdGggPSBpbWdXaWR0aDtcbiAgICAgIGhlaWdodCA9IGltZ0hlaWdodDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHdpZHRoOiB3aWR0aFxuICB9O1xufVxuZnVuY3Rpb24gb3BlbkZ1bGxTY3JlZW4od3JhcHBlcikge1xuICBpZiAod3JhcHBlci5yZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIHJldHVybiB3cmFwcGVyLnJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gIH0gZWxzZSBpZiAod3JhcHBlci53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIHJldHVybiB3cmFwcGVyLndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gIH0gZWxzZSBpZiAod3JhcHBlci5tc1JlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgcmV0dXJuIHdyYXBwZXIubXNSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgpO1xuICB9XG59XG5mdW5jdGlvbiBleGl0RnVsbFNjcmVlbigpIHtcbiAgaWYgKGRvY3VtZW50LmV4aXRGdWxsc2NyZWVuKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmV4aXRGdWxsc2NyZWVuKCk7XG4gIH0gZWxzZSBpZiAoZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4pIHtcbiAgICByZXR1cm4gZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5tc0V4aXRGdWxsc2NyZWVuKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoKTtcbiAgfVxufVxuXG5jb25zdCBkZWZhdWx0cyA9IHtcbiAgY29udGFpbmVyOiBkb2N1bWVudC5ib2R5LFxuICAvLyB3aW5kb3cgb3IgZWxlbWVudFxuICBjbGFzc05hbWU6IHVuZGVmaW5lZCxcbiAgaW1hZ2VTaXplOiAnc2NhbGUtZG93bicsXG4gIC8vICdzY2FsZS1kb3duJywgJ2NvbnRhaW4nLCAnY292ZXInIG9yICduYXRpdmUnXG4gIGZ1bGxTY3JlZW46IGZhbHNlLFxuICBsb29wOiBmYWxzZSxcbiAgbGlua0ltYWdlczogdHJ1ZSxcbiAgc2V0SW5kZXg6IDAsXG4gIGZpcnN0SW1hZ2VJbmRleDogMCxcbiAgbGFzdEltYWdlSW5kZXg6IGZhbHNlLFxuICBjdXJyZW50SW1hZ2VJbmRleDogdW5kZWZpbmVkLFxuICBhbGxvd1pvb206IHRydWUsXG4gIGNsb3NlT25CYWNrZ3JvdW5kQ2xpY2s6IHRydWUsXG4gIHNldFRpdGxlOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICcnO1xuICB9LFxuICBkZXNjcmlwdGlvbjogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlc1t0aGlzLnNldHRpbmdzLmN1cnJlbnRJbWFnZUluZGV4XS50aXRsZTtcbiAgfSxcbiAgcGFnaW5hdGlvbjogZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGxhc3QgPSB0aGlzLnNldHRpbmdzLmxhc3RJbWFnZUluZGV4ICsgMTtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggKyAxO1xuICAgIHJldHVybiBwb3NpdGlvbiArICcvJyArIGxhc3Q7XG4gIH0sXG5cbiAgYWZ0ZXJJbml0aWFsaXplKCkge30sXG5cbiAgYWZ0ZXJNYXJrdXAoKSB7fSxcblxuICBhZnRlckltYWdlTG9hZCgpIHt9LFxuXG4gIGFmdGVyQ2xvc2UoKSB7fSxcblxuICB6b29tZWRQYWRkaW5nWDogZnVuY3Rpb24gKGNhbnZhc1dpZHRoLCBpbWdXaWR0aCkge1xuICAgIHJldHVybiAwO1xuICB9LFxuICB6b29tZWRQYWRkaW5nWTogZnVuY3Rpb24gKGNhbnZhc0hlaWdodCwgaW1nSGVpZ2h0KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn07XG5jbGFzcyBDaG9jb2xhdCB7XG4gIGNvbnN0cnVjdG9yKGVsZW1lbnRzLCBzZXR0aW5ncykge1xuICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgICB0aGlzLmVsZW1zID0ge307XG4gICAgdGhpcy5pbWFnZXMgPSBbXTtcbiAgICB0aGlzLmV2ZW50cyA9IFtdO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBmdWxsU2NyZWVuT3BlbjogZmFsc2UsXG4gICAgICBpbml0aWFsWm9vbVN0YXRlOiBudWxsLFxuICAgICAgaW5pdGlhbGl6ZWQ6IGZhbHNlLFxuICAgICAgdGltZXI6IGZhbHNlLFxuICAgICAgdmlzaWJsZTogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMuX2Nzc0NsYXNzZXMgPSBbJ2Nob2NvbGF0LW9wZW4nLCAnY2hvY29sYXQtaW4tY29udGFpbmVyJywgJ2Nob2NvbGF0LWNvdmVyJywgJ2Nob2NvbGF0LXpvb21hYmxlJywgJ2Nob2NvbGF0LXpvb21lZCcsICdjaG9jb2xhdC16b29taW5nLWluJywgJ2Nob2NvbGF0LXpvb21pbmctb3V0J107XG5cbiAgICBpZiAoTm9kZUxpc3QucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoZWxlbWVudHMpIHx8IEhUTUxDb2xsZWN0aW9uLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGVsZW1lbnRzKSkge1xuICAgICAgZWxlbWVudHMuZm9yRWFjaCgoZWwsIGkpID0+IHtcbiAgICAgICAgdGhpcy5pbWFnZXMucHVzaCh7XG4gICAgICAgICAgdGl0bGU6IGVsLmdldEF0dHJpYnV0ZSgndGl0bGUnKSxcbiAgICAgICAgICBzcmM6IGVsLmdldEF0dHJpYnV0ZSgnaHJlZicpLFxuICAgICAgICAgIHNyY3NldDogZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXNyY3NldCcpLFxuICAgICAgICAgIHNpemVzOiBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc2l6ZXMnKVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vZmYoZWwsICdjbGljay5jaG9jb2xhdCcpO1xuICAgICAgICB0aGlzLm9uKGVsLCAnY2xpY2suY2hvY29sYXQnLCBlID0+IHtcbiAgICAgICAgICB0aGlzLmluaXQoaSk7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmltYWdlcyA9IGVsZW1lbnRzO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNldHRpbmdzLmNvbnRhaW5lciBpbnN0YW5jZW9mIEVsZW1lbnQgfHwgdGhpcy5zZXR0aW5ncy5jb250YWluZXIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgdGhpcy5lbGVtcy5jb250YWluZXIgPSB0aGlzLnNldHRpbmdzLmNvbnRhaW5lcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbGVtcy5jb250YWluZXIgPSBkb2N1bWVudC5ib2R5O1xuICAgIH1cblxuICAgIHRoaXMuYXBpID0ge1xuICAgICAgb3BlbjogaSA9PiB7XG4gICAgICAgIGkgPSBwYXJzZUludChpKSB8fCAwO1xuICAgICAgICByZXR1cm4gdGhpcy5pbml0KGkpO1xuICAgICAgfSxcbiAgICAgIGNsb3NlOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGFuZ2UoMSk7XG4gICAgICB9LFxuICAgICAgcHJldjogKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGFuZ2UoLTEpO1xuICAgICAgfSxcbiAgICAgIGdvdG86IGkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVuKGkpO1xuICAgICAgfSxcbiAgICAgIGN1cnJlbnQ6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXg7XG4gICAgICB9LFxuICAgICAgcG9zaXRpb246ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24odGhpcy5lbGVtcy5pbWcpO1xuICAgICAgfSxcbiAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVzdHJveSgpO1xuICAgICAgfSxcbiAgICAgIHNldDogKHByb3BlcnR5LCB2YWx1ZSkgPT4ge1xuICAgICAgICB0aGlzLnNldHRpbmdzW3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9LFxuICAgICAgZ2V0OiBwcm9wZXJ0eSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzW3Byb3BlcnR5XTtcbiAgICAgIH0sXG4gICAgICBnZXRFbGVtOiBuYW1lID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbXNbbmFtZV07XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGluaXQoaSkge1xuICAgIGlmICghdGhpcy5zdGF0ZS5pbml0aWFsaXplZCkge1xuICAgICAgdGhpcy5tYXJrdXAoKTtcbiAgICAgIHRoaXMuYXR0YWNoTGlzdGVuZXJzKCk7XG4gICAgICB0aGlzLnNldHRpbmdzLmxhc3RJbWFnZUluZGV4ID0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMTtcbiAgICAgIHRoaXMuc3RhdGUuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuc2V0dGluZ3MuYWZ0ZXJJbml0aWFsaXplLmNhbGwodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMubG9hZChpKTtcbiAgfVxuXG4gIGxvYWQoaW5kZXgpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUudmlzaWJsZSkge1xuICAgICAgdGhpcy5zdGF0ZS52aXNpYmxlID0gdHJ1ZTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmVsZW1zLm92ZXJsYXkuY2xhc3NMaXN0LmFkZCgnY2hvY29sYXQtdmlzaWJsZScpO1xuICAgICAgICB0aGlzLmVsZW1zLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgnY2hvY29sYXQtdmlzaWJsZScpO1xuICAgICAgfSwgMCk7XG4gICAgICB0aGlzLmVsZW1zLmNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdjaG9jb2xhdC1vcGVuJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuZnVsbFNjcmVlbikge1xuICAgICAgdGhpcy5zdGF0ZS5mdWxsU2NyZWVuT3BlbiA9IG9wZW5GdWxsU2NyZWVuKHRoaXMuZWxlbXMud3JhcHBlcik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggPT09IGluZGV4KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgbGV0IGxvYWRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmVsZW1zLmxvYWRlci5jbGFzc0xpc3QuYWRkKCdjaG9jb2xhdC12aXNpYmxlJyk7XG4gICAgfSwgMTAwMCk7XG4gICAgbGV0IGZhZGVPdXRQcm9taXNlO1xuICAgIGxldCBpbWFnZTtcbiAgICBsZXQgZmFkZU91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBmYWRlT3V0VGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICBmYWRlT3V0UHJvbWlzZSA9IHRyYW5zaXRpb25Bc1Byb21pc2UoKCkgPT4ge1xuICAgICAgICB0aGlzLmVsZW1zLmltYWdlQ2FudmFzLmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LXZpc2libGUnKTtcbiAgICAgIH0sIHRoaXMuZWxlbXMuaW1hZ2VDYW52YXMpO1xuICAgIH0sIDgwKTtcbiAgICByZXR1cm4gbG9hZEltYWdlKHRoaXMuaW1hZ2VzW2luZGV4XSkudGhlbihsb2FkZWRJbWFnZSA9PiB7XG4gICAgICBpbWFnZSA9IGxvYWRlZEltYWdlO1xuXG4gICAgICBpZiAoZmFkZU91dFRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChmYWRlT3V0VGltZXIpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFkZU91dFByb21pc2U7XG4gICAgICB9XG4gICAgfSkudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBuZXh0SW5kZXggPSBpbmRleCArIDE7XG5cbiAgICAgIGlmICh0aGlzLmltYWdlc1tuZXh0SW5kZXhdICE9IHVuZGVmaW5lZCkge1xuICAgICAgICBsb2FkSW1hZ2UodGhpcy5pbWFnZXNbbmV4dEluZGV4XSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggPSBpbmRleDtcbiAgICAgIHRoaXMuZWxlbXMuZGVzY3JpcHRpb24udGV4dENvbnRlbnQgPSB0aGlzLnNldHRpbmdzLmRlc2NyaXB0aW9uLmNhbGwodGhpcyk7XG4gICAgICB0aGlzLmVsZW1zLnBhZ2luYXRpb24udGV4dENvbnRlbnQgPSB0aGlzLnNldHRpbmdzLnBhZ2luYXRpb24uY2FsbCh0aGlzKTtcbiAgICAgIHRoaXMuYXJyb3dzKCk7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbihpbWFnZSkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuZWxlbXMubG9hZGVyLmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LXZpc2libGUnKTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGxvYWRlclRpbWVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwZWFyKGltYWdlKTtcbiAgICAgIH0pO1xuICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5lbGVtcy5jb250YWluZXIuY2xhc3NMaXN0LnRvZ2dsZSgnY2hvY29sYXQtem9vbWFibGUnLCB0aGlzLnpvb21hYmxlKGltYWdlLCB0aGlzLmVsZW1zLndyYXBwZXIpKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWZ0ZXJJbWFnZUxvYWQuY2FsbCh0aGlzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBvc2l0aW9uKHtcbiAgICBuYXR1cmFsSGVpZ2h0LFxuICAgIG5hdHVyYWxXaWR0aFxuICB9KSB7XG4gICAgY29uc3QgZml0T3B0aW9ucyA9IHtcbiAgICAgIGltZ0hlaWdodDogbmF0dXJhbEhlaWdodCxcbiAgICAgIGltZ1dpZHRoOiBuYXR1cmFsV2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQ6IHRoaXMuZWxlbXMuY29udGFpbmVyLmNsaWVudEhlaWdodCxcbiAgICAgIGNvbnRhaW5lcldpZHRoOiB0aGlzLmVsZW1zLmNvbnRhaW5lci5jbGllbnRXaWR0aCxcbiAgICAgIGNhbnZhc1dpZHRoOiB0aGlzLmVsZW1zLmltYWdlQ2FudmFzLmNsaWVudFdpZHRoLFxuICAgICAgY2FudmFzSGVpZ2h0OiB0aGlzLmVsZW1zLmltYWdlQ2FudmFzLmNsaWVudEhlaWdodCxcbiAgICAgIGltYWdlU2l6ZTogdGhpcy5zZXR0aW5ncy5pbWFnZVNpemVcbiAgICB9O1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0XG4gICAgfSA9IGZpdChmaXRPcHRpb25zKTtcbiAgICByZXR1cm4gdHJhbnNpdGlvbkFzUHJvbWlzZSgoKSA9PiB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMuZWxlbXMuaW1hZ2VXcmFwcGVyLnN0eWxlLCB7XG4gICAgICAgIHdpZHRoOiB3aWR0aCArICdweCcsXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgJ3B4J1xuICAgICAgfSk7XG4gICAgfSwgdGhpcy5lbGVtcy5pbWFnZVdyYXBwZXIpO1xuICB9XG5cbiAgYXBwZWFyKGltYWdlKSB7XG4gICAgdGhpcy5lbGVtcy5pbWFnZVdyYXBwZXIucmVtb3ZlQ2hpbGQodGhpcy5lbGVtcy5pbWcpO1xuICAgIHRoaXMuZWxlbXMuaW1nID0gaW1hZ2U7XG4gICAgdGhpcy5lbGVtcy5pbWcuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1pbWcnKTtcbiAgICB0aGlzLmVsZW1zLmltYWdlV3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLmltZyk7XG4gICAgY29uc3QgZmFkZUluUHJvbWlzZSA9IHRyYW5zaXRpb25Bc1Byb21pc2UoKCkgPT4ge1xuICAgICAgdGhpcy5lbGVtcy5pbWFnZUNhbnZhcy5jbGFzc0xpc3QuYWRkKCdjaG9jb2xhdC12aXNpYmxlJyk7XG4gICAgfSwgdGhpcy5lbGVtcy5pbWFnZUNhbnZhcyk7XG4gICAgcmV0dXJuIGZhZGVJblByb21pc2U7XG4gIH1cblxuICBjaGFuZ2Uoc3RlcCkge1xuICAgIGlmICghdGhpcy5zdGF0ZS52aXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLmxpbmtJbWFnZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnpvb21PdXQoKTtcbiAgICBjb25zdCByZXF1ZXN0ZWRJbWFnZSA9IHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggKyBwYXJzZUludChzdGVwKTtcblxuICAgIGlmIChyZXF1ZXN0ZWRJbWFnZSA+IHRoaXMuc2V0dGluZ3MubGFzdEltYWdlSW5kZXgpIHtcbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLmxvb3ApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZCh0aGlzLnNldHRpbmdzLmZpcnN0SW1hZ2VJbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXF1ZXN0ZWRJbWFnZSA8IHRoaXMuc2V0dGluZ3MuZmlyc3RJbWFnZUluZGV4KSB7XG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5sb29wKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvYWQodGhpcy5zZXR0aW5ncy5sYXN0SW1hZ2VJbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmxvYWQocmVxdWVzdGVkSW1hZ2UpO1xuICAgIH1cbiAgfVxuXG4gIGFycm93cygpIHtcbiAgICBpZiAodGhpcy5zZXR0aW5ncy5sb29wKSB7XG4gICAgICB0aGlzLmVsZW1zLmxlZnQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICB0aGlzLmVsZW1zLnJpZ2h0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5saW5rSW1hZ2VzKSB7XG4gICAgICB0aGlzLmVsZW1zLnJpZ2h0LmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggIT09IHRoaXMuc2V0dGluZ3MubGFzdEltYWdlSW5kZXgpO1xuICAgICAgdGhpcy5lbGVtcy5sZWZ0LmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIHRoaXMuc2V0dGluZ3MuY3VycmVudEltYWdlSW5kZXggIT09IHRoaXMuc2V0dGluZ3MuZmlyc3RJbWFnZUluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbGVtcy5sZWZ0LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgdGhpcy5lbGVtcy5yaWdodC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICB9XG4gIH1cblxuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZS5mdWxsU2NyZWVuT3Blbikge1xuICAgICAgZXhpdEZ1bGxTY3JlZW4oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlLnZpc2libGUgPSBmYWxzZTtcbiAgICBjb25zdCBwcm9taXNlT3ZlcmxheSA9IHRyYW5zaXRpb25Bc1Byb21pc2UoKCkgPT4ge1xuICAgICAgdGhpcy5lbGVtcy5vdmVybGF5LmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LXZpc2libGUnKTtcbiAgICB9LCB0aGlzLmVsZW1zLm92ZXJsYXkpO1xuICAgIGNvbnN0IHByb21pc2VXcmFwcGVyID0gdHJhbnNpdGlvbkFzUHJvbWlzZSgoKSA9PiB7XG4gICAgICB0aGlzLmVsZW1zLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgnY2hvY29sYXQtdmlzaWJsZScpO1xuICAgIH0sIHRoaXMuZWxlbXMud3JhcHBlcik7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtwcm9taXNlT3ZlcmxheSwgcHJvbWlzZVdyYXBwZXJdKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LW9wZW4nKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MuYWZ0ZXJDbG9zZS5jYWxsKHRoaXMpO1xuICAgIH0pO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5ldmVudHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAgZXZlbnROYW1lXG4gICAgICB9ID0gdGhpcy5ldmVudHNbaV07XG4gICAgICB0aGlzLm9mZihlbGVtZW50LCBldmVudE5hbWUpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdGF0ZS5pbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLmZ1bGxTY3JlZW5PcGVuKSB7XG4gICAgICB0aGlzLnN0YXRlLmZ1bGxTY3JlZW5PcGVuID0gZXhpdEZ1bGxTY3JlZW4oKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldHRpbmdzLmN1cnJlbnRJbWFnZUluZGV4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc3RhdGUudmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuc3RhdGUuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVsZW1zLmNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKC4uLnRoaXMuX2Nzc0NsYXNzZXMpO1xuICAgIHRoaXMuZWxlbXMud3JhcHBlci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZWxlbXMud3JhcHBlcik7XG4gIH1cblxuICBtYXJrdXAoKSB7XG4gICAgdGhpcy5lbGVtcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnY2hvY29sYXQtb3BlbicsIHRoaXMuc2V0dGluZ3MuY2xhc3NOYW1lKTtcblxuICAgIGlmICh0aGlzLnNldHRpbmdzLmltYWdlU2l6ZSA9PSAnY292ZXInKSB7XG4gICAgICB0aGlzLmVsZW1zLmNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdjaG9jb2xhdC1jb3ZlcicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmVsZW1zLmNvbnRhaW5lciAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgdGhpcy5lbGVtcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnY2hvY29sYXQtaW4tY29udGFpbmVyJyk7XG4gICAgfVxuXG4gICAgdGhpcy5lbGVtcy53cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy53cmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCAnY2hvY29sYXQtY29udGVudC0nICsgdGhpcy5zZXR0aW5ncy5zZXRJbmRleCk7XG4gICAgdGhpcy5lbGVtcy53cmFwcGVyLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnY2hvY29sYXQtd3JhcHBlcicpO1xuICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZWxlbXMud3JhcHBlcik7XG4gICAgdGhpcy5lbGVtcy5vdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5vdmVybGF5LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnY2hvY29sYXQtb3ZlcmxheScpO1xuICAgIHRoaXMuZWxlbXMud3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLm92ZXJsYXkpO1xuICAgIHRoaXMuZWxlbXMubG9hZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5sb2FkZXIuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1sb2FkZXInKTtcbiAgICB0aGlzLmVsZW1zLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5sb2FkZXIpO1xuICAgIHRoaXMuZWxlbXMubGF5b3V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5sYXlvdXQuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1sYXlvdXQnKTtcbiAgICB0aGlzLmVsZW1zLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5sYXlvdXQpO1xuICAgIHRoaXMuZWxlbXMudG9wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy50b3Auc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC10b3AnKTtcbiAgICB0aGlzLmVsZW1zLmxheW91dC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLnRvcCk7XG4gICAgdGhpcy5lbGVtcy5jZW50ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmVsZW1zLmNlbnRlci5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWNlbnRlcicpO1xuICAgIHRoaXMuZWxlbXMubGF5b3V0LmFwcGVuZENoaWxkKHRoaXMuZWxlbXMuY2VudGVyKTtcbiAgICB0aGlzLmVsZW1zLmxlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmVsZW1zLmxlZnQuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1sZWZ0Jyk7XG4gICAgdGhpcy5lbGVtcy5jZW50ZXIuYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5sZWZ0KTtcbiAgICB0aGlzLmVsZW1zLmltYWdlQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5pbWFnZUNhbnZhcy5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWltYWdlLWNhbnZhcycpO1xuICAgIHRoaXMuZWxlbXMuY2VudGVyLmFwcGVuZENoaWxkKHRoaXMuZWxlbXMuaW1hZ2VDYW52YXMpO1xuICAgIHRoaXMuZWxlbXMuaW1hZ2VXcmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5pbWFnZVdyYXBwZXIuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1pbWFnZS13cmFwcGVyJyk7XG4gICAgdGhpcy5lbGVtcy5pbWFnZUNhbnZhcy5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLmltYWdlV3JhcHBlcik7XG4gICAgdGhpcy5lbGVtcy5pbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICB0aGlzLmVsZW1zLmltZy5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWltZycpO1xuICAgIHRoaXMuZWxlbXMuaW1hZ2VXcmFwcGVyLmFwcGVuZENoaWxkKHRoaXMuZWxlbXMuaW1nKTtcbiAgICB0aGlzLmVsZW1zLnJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5lbGVtcy5yaWdodC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LXJpZ2h0Jyk7XG4gICAgdGhpcy5lbGVtcy5jZW50ZXIuYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5yaWdodCk7XG4gICAgdGhpcy5lbGVtcy5ib3R0b20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmVsZW1zLmJvdHRvbS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWJvdHRvbScpO1xuICAgIHRoaXMuZWxlbXMubGF5b3V0LmFwcGVuZENoaWxkKHRoaXMuZWxlbXMuYm90dG9tKTtcbiAgICB0aGlzLmVsZW1zLmNsb3NlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIHRoaXMuZWxlbXMuY2xvc2Uuc2V0QXR0cmlidXRlKCdjbGFzcycsICdjaG9jb2xhdC1jbG9zZScpO1xuICAgIHRoaXMuZWxlbXMudG9wLmFwcGVuZENoaWxkKHRoaXMuZWxlbXMuY2xvc2UpO1xuICAgIHRoaXMuZWxlbXMuZGVzY3JpcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdGhpcy5lbGVtcy5kZXNjcmlwdGlvbi5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWRlc2NyaXB0aW9uJyk7XG4gICAgdGhpcy5lbGVtcy5ib3R0b20uYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5kZXNjcmlwdGlvbik7XG4gICAgdGhpcy5lbGVtcy5wYWdpbmF0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIHRoaXMuZWxlbXMucGFnaW5hdGlvbi5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LXBhZ2luYXRpb24nKTtcbiAgICB0aGlzLmVsZW1zLmJvdHRvbS5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLnBhZ2luYXRpb24pO1xuICAgIHRoaXMuZWxlbXMuc2V0VGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdGhpcy5lbGVtcy5zZXRUaXRsZS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LXNldC10aXRsZScpO1xuICAgIHRoaXMuZWxlbXMuc2V0VGl0bGUudGV4dENvbnRlbnQgPSB0aGlzLnNldHRpbmdzLnNldFRpdGxlKCk7XG4gICAgdGhpcy5lbGVtcy5ib3R0b20uYXBwZW5kQ2hpbGQodGhpcy5lbGVtcy5zZXRUaXRsZSk7XG4gICAgdGhpcy5lbGVtcy5mdWxsc2NyZWVuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIHRoaXMuZWxlbXMuZnVsbHNjcmVlbi5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2Nob2NvbGF0LWZ1bGxzY3JlZW4nKTtcbiAgICB0aGlzLmVsZW1zLmJvdHRvbS5hcHBlbmRDaGlsZCh0aGlzLmVsZW1zLmZ1bGxzY3JlZW4pO1xuICAgIHRoaXMuc2V0dGluZ3MuYWZ0ZXJNYXJrdXAuY2FsbCh0aGlzKTtcbiAgfVxuXG4gIGF0dGFjaExpc3RlbmVycygpIHtcbiAgICB0aGlzLm9mZihkb2N1bWVudCwgJ2tleWRvd24uY2hvY29sYXQnKTtcbiAgICB0aGlzLm9uKGRvY3VtZW50LCAna2V5ZG93bi5jaG9jb2xhdCcsIGUgPT4ge1xuICAgICAgaWYgKHRoaXMuc3RhdGUuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PSAzNykge1xuICAgICAgICAgIHRoaXMuY2hhbmdlKC0xKTtcbiAgICAgICAgfSBlbHNlIGlmIChlLmtleUNvZGUgPT0gMzkpIHtcbiAgICAgICAgICB0aGlzLmNoYW5nZSgxKTtcbiAgICAgICAgfSBlbHNlIGlmIChlLmtleUNvZGUgPT0gMjcpIHtcbiAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCByaWdodCA9IHRoaXMuZWxlbXMud3JhcHBlci5xdWVyeVNlbGVjdG9yKCcuY2hvY29sYXQtcmlnaHQnKTtcbiAgICB0aGlzLm9mZihyaWdodCwgJ2NsaWNrLmNob2NvbGF0Jyk7XG4gICAgdGhpcy5vbihyaWdodCwgJ2NsaWNrLmNob2NvbGF0JywgKCkgPT4ge1xuICAgICAgdGhpcy5jaGFuZ2UoKzEpO1xuICAgIH0pO1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLmVsZW1zLndyYXBwZXIucXVlcnlTZWxlY3RvcignLmNob2NvbGF0LWxlZnQnKTtcbiAgICB0aGlzLm9mZihsZWZ0LCAnY2xpY2suY2hvY29sYXQnKTtcbiAgICB0aGlzLm9uKGxlZnQsICdjbGljay5jaG9jb2xhdCcsICgpID0+IHtcbiAgICAgIHRoaXMuY2hhbmdlKC0xKTtcbiAgICB9KTtcbiAgICB0aGlzLm9mZih0aGlzLmVsZW1zLmNsb3NlLCAnY2xpY2suY2hvY29sYXQnKTtcbiAgICB0aGlzLm9uKHRoaXMuZWxlbXMuY2xvc2UsICdjbGljay5jaG9jb2xhdCcsIHRoaXMuY2xvc2UuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5vZmYodGhpcy5lbGVtcy5mdWxsc2NyZWVuLCAnY2xpY2suY2hvY29sYXQnKTtcbiAgICB0aGlzLm9uKHRoaXMuZWxlbXMuZnVsbHNjcmVlbiwgJ2NsaWNrLmNob2NvbGF0JywgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc3RhdGUuZnVsbFNjcmVlbk9wZW4pIHtcbiAgICAgICAgZXhpdEZ1bGxTY3JlZW4oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBvcGVuRnVsbFNjcmVlbih0aGlzLmVsZW1zLndyYXBwZXIpO1xuICAgIH0pO1xuICAgIHRoaXMub2ZmKGRvY3VtZW50LCAnZnVsbHNjcmVlbmNoYW5nZS5jaG9jb2xhdCcpO1xuICAgIHRoaXMub24oZG9jdW1lbnQsICdmdWxsc2NyZWVuY2hhbmdlLmNob2NvbGF0JywgKCkgPT4ge1xuICAgICAgaWYgKGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50KSB7XG4gICAgICAgIHRoaXMuc3RhdGUuZnVsbFNjcmVlbk9wZW4gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5mdWxsU2NyZWVuT3BlbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuY2xvc2VPbkJhY2tncm91bmRDbGljaykge1xuICAgICAgdGhpcy5vZmYodGhpcy5lbGVtcy5vdmVybGF5LCAnY2xpY2suY2hvY29sYXQnKTtcbiAgICAgIHRoaXMub24odGhpcy5lbGVtcy5vdmVybGF5LCAnY2xpY2suY2hvY29sYXQnLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHRoaXMub2ZmKHRoaXMuZWxlbXMud3JhcHBlciwgJ2NsaWNrLmNob2NvbGF0Jyk7XG4gICAgdGhpcy5vbih0aGlzLmVsZW1zLndyYXBwZXIsICdjbGljay5jaG9jb2xhdCcsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLmluaXRpYWxab29tU3RhdGUgPT09IG51bGwgfHwgIXRoaXMuc3RhdGUudmlzaWJsZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2Nob2NvbGF0LXpvb21pbmctb3V0Jyk7XG4gICAgICB0aGlzLnpvb21PdXQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5lbGVtcy5jb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnY2hvY29sYXQtem9vbWVkJyk7XG4gICAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LXpvb21pbmctb3V0Jyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0aGlzLm9mZih0aGlzLmVsZW1zLmltYWdlV3JhcHBlciwgJ2NsaWNrLmNob2NvbGF0Jyk7XG4gICAgdGhpcy5vbih0aGlzLmVsZW1zLmltYWdlV3JhcHBlciwgJ2NsaWNrLmNob2NvbGF0JywgZSA9PiB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS5pbml0aWFsWm9vbVN0YXRlID09PSBudWxsICYmIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5jb250YWlucygnY2hvY29sYXQtem9vbWFibGUnKSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLmVsZW1zLmNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdjaG9jb2xhdC16b29taW5nLWluJyk7XG4gICAgICAgIHRoaXMuem9vbUluKGUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2Nob2NvbGF0LXpvb21lZCcpO1xuICAgICAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ2Nob2NvbGF0LXpvb21pbmctaW4nKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5vbih0aGlzLmVsZW1zLndyYXBwZXIsICdtb3VzZW1vdmUuY2hvY29sYXQnLCBlID0+IHtcbiAgICAgIGlmICh0aGlzLnN0YXRlLmluaXRpYWxab29tU3RhdGUgPT09IG51bGwgfHwgIXRoaXMuc3RhdGUudmlzaWJsZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLmVsZW1zLndyYXBwZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBwb3MgPSB7XG4gICAgICAgIHRvcDogcmVjdC50b3AgKyB3aW5kb3cuc2Nyb2xsWSxcbiAgICAgICAgbGVmdDogcmVjdC5sZWZ0ICsgd2luZG93LnNjcm9sbFhcbiAgICAgIH07XG4gICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmVsZW1zLndyYXBwZXIuY2xpZW50SGVpZ2h0O1xuICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLmVsZW1zLndyYXBwZXIuY2xpZW50V2lkdGg7XG4gICAgICBjb25zdCBpbWdXaWR0aCA9IHRoaXMuZWxlbXMuaW1nLndpZHRoO1xuICAgICAgY29uc3QgaW1nSGVpZ2h0ID0gdGhpcy5lbGVtcy5pbWcuaGVpZ2h0O1xuICAgICAgY29uc3QgY29vcmQgPSBbZS5wYWdlWCAtIHdpZHRoIC8gMiAtIHBvcy5sZWZ0LCBlLnBhZ2VZIC0gaGVpZ2h0IC8gMiAtIHBvcy50b3BdO1xuICAgICAgbGV0IG12dFggPSAwO1xuXG4gICAgICBpZiAoaW1nV2lkdGggPiB3aWR0aCkge1xuICAgICAgICBjb25zdCBwYWRkaW5nWCA9IHRoaXMuc2V0dGluZ3Muem9vbWVkUGFkZGluZ1goaW1nV2lkdGgsIHdpZHRoKTtcbiAgICAgICAgbXZ0WCA9IGNvb3JkWzBdIC8gKHdpZHRoIC8gMik7XG4gICAgICAgIG12dFggPSAoKGltZ1dpZHRoIC0gd2lkdGgpIC8gMiArIHBhZGRpbmdYKSAqIG12dFg7XG4gICAgICB9XG5cbiAgICAgIGxldCBtdnRZID0gMDtcblxuICAgICAgaWYgKGltZ0hlaWdodCA+IGhlaWdodCkge1xuICAgICAgICBjb25zdCBwYWRkaW5nWSA9IHRoaXMuc2V0dGluZ3Muem9vbWVkUGFkZGluZ1koaW1nSGVpZ2h0LCBoZWlnaHQpO1xuICAgICAgICBtdnRZID0gY29vcmRbMV0gLyAoaGVpZ2h0IC8gMik7XG4gICAgICAgIG12dFkgPSAoKGltZ0hlaWdodCAtIGhlaWdodCkgLyAyICsgcGFkZGluZ1kpICogbXZ0WTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5lbGVtcy5pbWcuc3R5bGUubWFyZ2luTGVmdCA9IC1tdnRYICsgJ3B4JztcbiAgICAgIHRoaXMuZWxlbXMuaW1nLnN0eWxlLm1hcmdpblRvcCA9IC1tdnRZICsgJ3B4JztcbiAgICB9KTtcbiAgICB0aGlzLm9uKHdpbmRvdywgJ3Jlc2l6ZS5jaG9jb2xhdCcsIGUgPT4ge1xuICAgICAgaWYgKCF0aGlzLnN0YXRlLmluaXRpYWxpemVkIHx8ICF0aGlzLnN0YXRlLnZpc2libGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBkZWJvdW5jZSg1MCwgKCkgPT4ge1xuICAgICAgICBjb25zdCBmaXRPcHRpb25zID0ge1xuICAgICAgICAgIGltZ0hlaWdodDogdGhpcy5lbGVtcy5pbWcubmF0dXJhbEhlaWdodCxcbiAgICAgICAgICBpbWdXaWR0aDogdGhpcy5lbGVtcy5pbWcubmF0dXJhbFdpZHRoLFxuICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogdGhpcy5lbGVtcy53cmFwcGVyLmNsaWVudEhlaWdodCxcbiAgICAgICAgICBjb250YWluZXJXaWR0aDogdGhpcy5lbGVtcy53cmFwcGVyLmNsaWVudFdpZHRoLFxuICAgICAgICAgIGNhbnZhc1dpZHRoOiB0aGlzLmVsZW1zLmltYWdlQ2FudmFzLmNsaWVudFdpZHRoLFxuICAgICAgICAgIGNhbnZhc0hlaWdodDogdGhpcy5lbGVtcy5pbWFnZUNhbnZhcy5jbGllbnRIZWlnaHQsXG4gICAgICAgICAgaW1hZ2VTaXplOiB0aGlzLnNldHRpbmdzLmltYWdlU2l6ZVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0XG4gICAgICAgIH0gPSBmaXQoZml0T3B0aW9ucyk7XG4gICAgICAgIHRoaXMucG9zaXRpb24odGhpcy5lbGVtcy5pbWcpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZWxlbXMuY29udGFpbmVyLmNsYXNzTGlzdC50b2dnbGUoJ2Nob2NvbGF0LXpvb21hYmxlJywgdGhpcy56b29tYWJsZSh0aGlzLmVsZW1zLmltZywgdGhpcy5lbGVtcy53cmFwcGVyKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICB6b29tYWJsZShpbWFnZSwgd3JhcHBlcikge1xuICAgIGNvbnN0IHdyYXBwZXJXaWR0aCA9IHdyYXBwZXIuY2xpZW50V2lkdGg7XG4gICAgY29uc3Qgd3JhcHBlckhlaWdodCA9IHdyYXBwZXIuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IGlzSW1hZ2Vab29tYWJsZSA9IHRoaXMuc2V0dGluZ3MuYWxsb3dab29tICYmIChpbWFnZS5uYXR1cmFsV2lkdGggPiB3cmFwcGVyV2lkdGggfHwgaW1hZ2UubmF0dXJhbEhlaWdodCA+IHdyYXBwZXJIZWlnaHQpID8gdHJ1ZSA6IGZhbHNlO1xuICAgIGNvbnN0IGlzSW1hZ2VTdHJldGNoZWQgPSBpbWFnZS5jbGllbnRXaWR0aCA+IGltYWdlLm5hdHVyYWxXaWR0aCB8fCBpbWFnZS5jbGllbnRIZWlnaHQgPiBpbWFnZS5uYXR1cmFsSGVpZ2h0O1xuICAgIHJldHVybiBpc0ltYWdlWm9vbWFibGUgJiYgIWlzSW1hZ2VTdHJldGNoZWQ7XG4gIH1cblxuICB6b29tSW4oZSkge1xuICAgIHRoaXMuc3RhdGUuaW5pdGlhbFpvb21TdGF0ZSA9IHRoaXMuc2V0dGluZ3MuaW1hZ2VTaXplO1xuICAgIHRoaXMuc2V0dGluZ3MuaW1hZ2VTaXplID0gJ25hdGl2ZSc7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24odGhpcy5lbGVtcy5pbWcpO1xuICB9XG5cbiAgem9vbU91dChlKSB7XG4gICAgdGhpcy5zZXR0aW5ncy5pbWFnZVNpemUgPSB0aGlzLnN0YXRlLmluaXRpYWxab29tU3RhdGUgfHwgdGhpcy5zZXR0aW5ncy5pbWFnZVNpemU7XG4gICAgdGhpcy5zdGF0ZS5pbml0aWFsWm9vbVN0YXRlID0gbnVsbDtcbiAgICB0aGlzLmVsZW1zLmltZy5zdHlsZS5tYXJnaW4gPSAwO1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uKHRoaXMuZWxlbXMuaW1nKTtcbiAgfVxuXG4gIG9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2IpIHtcbiAgICAvLyBjb25zdCBldmVudE5hbWUgPSB0aGlzLnNldHRpbmdzLnNldEluZGV4ICsgJy0nICsgZXZlbnROYW1lXG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy5ldmVudHMucHVzaCh7XG4gICAgICBlbGVtZW50LFxuICAgICAgZXZlbnROYW1lLFxuICAgICAgY2JcbiAgICB9KTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLnNwbGl0KCcuJylbMF0sIHRoaXMuZXZlbnRzW2xlbmd0aCAtIDFdLmNiKTtcbiAgfVxuXG4gIG9mZihlbGVtZW50LCBldmVudE5hbWUpIHtcbiAgICAvLyBjb25zdCBldmVudE5hbWUgPSB0aGlzLnNldHRpbmdzLnNldEluZGV4ICsgJy0nICsgZXZlbnROYW1lXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmV2ZW50cy5maW5kSW5kZXgoZXZlbnQgPT4ge1xuICAgICAgcmV0dXJuIGV2ZW50LmVsZW1lbnQgPT09IGVsZW1lbnQgJiYgZXZlbnQuZXZlbnROYW1lID09PSBldmVudE5hbWU7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5ldmVudHNbaW5kZXhdKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLnNwbGl0KCcuJylbMF0sIHRoaXMuZXZlbnRzW2luZGV4XS5jYik7XG4gICAgICB0aGlzLmV2ZW50cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG59XG5cbmNvbnN0IGluc3RhbmNlcyA9IFtdO1xuZnVuY3Rpb24gbWFpbl9lc20gKGVsZW1lbnRzLCBvcHRpb25zKSB7XG4gIGNvbnN0IHNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdHMsIHtcbiAgICBpbWFnZXM6IFtdXG4gIH0sIG9wdGlvbnMsIHtcbiAgICBzZXRJbmRleDogaW5zdGFuY2VzLmxlbmd0aFxuICB9KTtcbiAgY29uc3QgaW5zdGFuY2UgPSBuZXcgQ2hvY29sYXQoZWxlbWVudHMsIHNldHRpbmdzKTtcbiAgaW5zdGFuY2VzLnB1c2goaW5zdGFuY2UpO1xuICByZXR1cm4gaW5zdGFuY2U7XG59XG5cbmV4cG9ydCBkZWZhdWx0IG1haW5fZXNtO1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsLCB1bmRlZmluZWQpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIGlmIChnbG9iYWwuc2V0SW1tZWRpYXRlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbmV4dEhhbmRsZSA9IDE7IC8vIFNwZWMgc2F5cyBncmVhdGVyIHRoYW4gemVyb1xuICAgIHZhciB0YXNrc0J5SGFuZGxlID0ge307XG4gICAgdmFyIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgIHZhciBkb2MgPSBnbG9iYWwuZG9jdW1lbnQ7XG4gICAgdmFyIHJlZ2lzdGVySW1tZWRpYXRlO1xuXG4gICAgZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGNhbGxiYWNrKSB7XG4gICAgICAvLyBDYWxsYmFjayBjYW4gZWl0aGVyIGJlIGEgZnVuY3Rpb24gb3IgYSBzdHJpbmdcbiAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBjYWxsYmFjayA9IG5ldyBGdW5jdGlvbihcIlwiICsgY2FsbGJhY2spO1xuICAgICAgfVxuICAgICAgLy8gQ29weSBmdW5jdGlvbiBhcmd1bWVudHNcbiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaSArIDFdO1xuICAgICAgfVxuICAgICAgLy8gU3RvcmUgYW5kIHJlZ2lzdGVyIHRoZSB0YXNrXG4gICAgICB2YXIgdGFzayA9IHsgY2FsbGJhY2s6IGNhbGxiYWNrLCBhcmdzOiBhcmdzIH07XG4gICAgICB0YXNrc0J5SGFuZGxlW25leHRIYW5kbGVdID0gdGFzaztcbiAgICAgIHJlZ2lzdGVySW1tZWRpYXRlKG5leHRIYW5kbGUpO1xuICAgICAgcmV0dXJuIG5leHRIYW5kbGUrKztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShoYW5kbGUpIHtcbiAgICAgICAgZGVsZXRlIHRhc2tzQnlIYW5kbGVbaGFuZGxlXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW4odGFzaykge1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSB0YXNrLmNhbGxiYWNrO1xuICAgICAgICB2YXIgYXJncyA9IHRhc2suYXJncztcbiAgICAgICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIGNhbGxiYWNrKGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIGNhbGxiYWNrKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIGNhbGxiYWNrKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBjYWxsYmFjay5hcHBseSh1bmRlZmluZWQsIGFyZ3MpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW5JZlByZXNlbnQoaGFuZGxlKSB7XG4gICAgICAgIC8vIEZyb20gdGhlIHNwZWM6IFwiV2FpdCB1bnRpbCBhbnkgaW52b2NhdGlvbnMgb2YgdGhpcyBhbGdvcml0aG0gc3RhcnRlZCBiZWZvcmUgdGhpcyBvbmUgaGF2ZSBjb21wbGV0ZWQuXCJcbiAgICAgICAgLy8gU28gaWYgd2UncmUgY3VycmVudGx5IHJ1bm5pbmcgYSB0YXNrLCB3ZSdsbCBuZWVkIHRvIGRlbGF5IHRoaXMgaW52b2NhdGlvbi5cbiAgICAgICAgaWYgKGN1cnJlbnRseVJ1bm5pbmdBVGFzaykge1xuICAgICAgICAgICAgLy8gRGVsYXkgYnkgZG9pbmcgYSBzZXRUaW1lb3V0LiBzZXRJbW1lZGlhdGUgd2FzIHRyaWVkIGluc3RlYWQsIGJ1dCBpbiBGaXJlZm94IDcgaXQgZ2VuZXJhdGVkIGFcbiAgICAgICAgICAgIC8vIFwidG9vIG11Y2ggcmVjdXJzaW9uXCIgZXJyb3IuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJ1bklmUHJlc2VudCwgMCwgaGFuZGxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciB0YXNrID0gdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgICAgICAgICAgaWYgKHRhc2spIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bih0YXNrKTtcbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckltbWVkaWF0ZShoYW5kbGUpO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkgeyBydW5JZlByZXNlbnQoaGFuZGxlKTsgfSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuVXNlUG9zdE1lc3NhZ2UoKSB7XG4gICAgICAgIC8vIFRoZSB0ZXN0IGFnYWluc3QgYGltcG9ydFNjcmlwdHNgIHByZXZlbnRzIHRoaXMgaW1wbGVtZW50YXRpb24gZnJvbSBiZWluZyBpbnN0YWxsZWQgaW5zaWRlIGEgd2ViIHdvcmtlcixcbiAgICAgICAgLy8gd2hlcmUgYGdsb2JhbC5wb3N0TWVzc2FnZWAgbWVhbnMgc29tZXRoaW5nIGNvbXBsZXRlbHkgZGlmZmVyZW50IGFuZCBjYW4ndCBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChnbG9iYWwucG9zdE1lc3NhZ2UgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgICAgICAgICB2YXIgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgb2xkT25NZXNzYWdlID0gZ2xvYmFsLm9ubWVzc2FnZTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gZmFsc2U7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKFwiXCIsIFwiKlwiKTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBvbGRPbk1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICAvLyBJbnN0YWxscyBhbiBldmVudCBoYW5kbGVyIG9uIGBnbG9iYWxgIGZvciB0aGUgYG1lc3NhZ2VgIGV2ZW50OiBzZWVcbiAgICAgICAgLy8gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vd2luZG93LnBvc3RNZXNzYWdlXG4gICAgICAgIC8vICogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvY29tbXMuaHRtbCNjcm9zc0RvY3VtZW50TWVzc2FnZXNcblxuICAgICAgICB2YXIgbWVzc2FnZVByZWZpeCA9IFwic2V0SW1tZWRpYXRlJFwiICsgTWF0aC5yYW5kb20oKSArIFwiJFwiO1xuICAgICAgICB2YXIgb25HbG9iYWxNZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT09IGdsb2JhbCAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBldmVudC5kYXRhID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuZGF0YS5pbmRleE9mKG1lc3NhZ2VQcmVmaXgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KCtldmVudC5kYXRhLnNsaWNlKG1lc3NhZ2VQcmVmaXgubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWwuYXR0YWNoRXZlbnQoXCJvbm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBnbG9iYWwucG9zdE1lc3NhZ2UobWVzc2FnZVByZWZpeCArIGhhbmRsZSwgXCIqXCIpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKGhhbmRsZSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGh0bWwgPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgPHNjcmlwdD4gZWxlbWVudDsgaXRzIHJlYWR5c3RhdGVjaGFuZ2UgZXZlbnQgd2lsbCBiZSBmaXJlZCBhc3luY2hyb25vdXNseSBvbmNlIGl0IGlzIGluc2VydGVkXG4gICAgICAgICAgICAvLyBpbnRvIHRoZSBkb2N1bWVudC4gRG8gc28sIHRodXMgcXVldWluZyB1cCB0aGUgdGFzay4gUmVtZW1iZXIgdG8gY2xlYW4gdXAgb25jZSBpdCdzIGJlZW4gY2FsbGVkLlxuICAgICAgICAgICAgdmFyIHNjcmlwdCA9IGRvYy5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuICAgICAgICAgICAgc2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBydW5JZlByZXNlbnQoaGFuZGxlKTtcbiAgICAgICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHNjcmlwdCk7XG4gICAgICAgICAgICAgICAgc2NyaXB0ID0gbnVsbDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBodG1sLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQocnVuSWZQcmVzZW50LCAwLCBoYW5kbGUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIElmIHN1cHBvcnRlZCwgd2Ugc2hvdWxkIGF0dGFjaCB0byB0aGUgcHJvdG90eXBlIG9mIGdsb2JhbCwgc2luY2UgdGhhdCBpcyB3aGVyZSBzZXRUaW1lb3V0IGV0IGFsLiBsaXZlLlxuICAgIHZhciBhdHRhY2hUbyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsKTtcbiAgICBhdHRhY2hUbyA9IGF0dGFjaFRvICYmIGF0dGFjaFRvLnNldFRpbWVvdXQgPyBhdHRhY2hUbyA6IGdsb2JhbDtcblxuICAgIC8vIERvbid0IGdldCBmb29sZWQgYnkgZS5nLiBicm93c2VyaWZ5IGVudmlyb25tZW50cy5cbiAgICBpZiAoe30udG9TdHJpbmcuY2FsbChnbG9iYWwucHJvY2VzcykgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiKSB7XG4gICAgICAgIC8vIEZvciBOb2RlLmpzIGJlZm9yZSAwLjlcbiAgICAgICAgaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoY2FuVXNlUG9zdE1lc3NhZ2UoKSkge1xuICAgICAgICAvLyBGb3Igbm9uLUlFMTAgbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCkge1xuICAgICAgICAvLyBGb3Igd2ViIHdvcmtlcnMsIHdoZXJlIHN1cHBvcnRlZFxuICAgICAgICBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChkb2MgJiYgXCJvbnJlYWR5c3RhdGVjaGFuZ2VcIiBpbiBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKSkge1xuICAgICAgICAvLyBGb3IgSUUgNuKAkzhcbiAgICAgICAgaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIG9sZGVyIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKTtcbiAgICB9XG5cbiAgICBhdHRhY2hUby5zZXRJbW1lZGlhdGUgPSBzZXRJbW1lZGlhdGU7XG4gICAgYXR0YWNoVG8uY2xlYXJJbW1lZGlhdGUgPSBjbGVhckltbWVkaWF0ZTtcbn0odHlwZW9mIHNlbGYgPT09IFwidW5kZWZpbmVkXCIgPyB0eXBlb2YgZ2xvYmFsID09PSBcInVuZGVmaW5lZFwiID8gdGhpcyA6IGdsb2JhbCA6IHNlbGYpKTtcbiIsInZhciBzY29wZSA9ICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiICYmIGdsb2JhbCkgfHxcbiAgICAgICAgICAgICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmKSB8fFxuICAgICAgICAgICAgd2luZG93O1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuXG4vLyBET00gQVBJcywgZm9yIGNvbXBsZXRlbmVzc1xuXG5leHBvcnRzLnNldFRpbWVvdXQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0VGltZW91dCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHtcbiAgaWYgKHRpbWVvdXQpIHtcbiAgICB0aW1lb3V0LmNsb3NlKCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIFRpbWVvdXQoaWQsIGNsZWFyRm4pIHtcbiAgdGhpcy5faWQgPSBpZDtcbiAgdGhpcy5fY2xlYXJGbiA9IGNsZWFyRm47XG59XG5UaW1lb3V0LnByb3RvdHlwZS51bnJlZiA9IFRpbWVvdXQucHJvdG90eXBlLnJlZiA9IGZ1bmN0aW9uKCkge307XG5UaW1lb3V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9jbGVhckZuLmNhbGwoc2NvcGUsIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBzZXRpbW1lZGlhdGUgYXR0YWNoZXMgaXRzZWxmIHRvIHRoZSBnbG9iYWwgb2JqZWN0XG5yZXF1aXJlKFwic2V0aW1tZWRpYXRlXCIpO1xuLy8gT24gc29tZSBleG90aWMgZW52aXJvbm1lbnRzLCBpdCdzIG5vdCBjbGVhciB3aGljaCBvYmplY3QgYHNldGltbWVkaWF0ZWAgd2FzXG4vLyBhYmxlIHRvIGluc3RhbGwgb250by4gIFNlYXJjaCBlYWNoIHBvc3NpYmlsaXR5IGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZVxuLy8gYHNldGltbWVkaWF0ZWAgbGlicmFyeS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWwuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodGhpcyAmJiB0aGlzLnNldEltbWVkaWF0ZSk7XG5leHBvcnRzLmNsZWFySW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuY2xlYXJJbW1lZGlhdGUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgJiYgZ2xvYmFsLmNsZWFySW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzICYmIHRoaXMuY2xlYXJJbW1lZGlhdGUpO1xuIiwiLyoqXG4gKlxuICpcbiAqIEBhdXRob3IgSmVycnkgQmVuZHkgPGplcnJ5QGljZXdpbmdjYy5jb20+XG4gKiBAbGljZW5jZSBNSVRcbiAqXG4gKi9cblxuKGZ1bmN0aW9uKHNlbGYpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICB2YXIgbmF0aXZlVVJMU2VhcmNoUGFyYW1zID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gIzQxIEZpeCBpc3N1ZSBpbiBSTlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5VUkxTZWFyY2hQYXJhbXMgJiYgKG5ldyBzZWxmLlVSTFNlYXJjaFBhcmFtcygnZm9vPWJhcicpKS5nZXQoJ2ZvbycpID09PSAnYmFyJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5VUkxTZWFyY2hQYXJhbXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KSgpLFxuICAgICAgICBpc1N1cHBvcnRPYmplY3RDb25zdHJ1Y3RvciA9IG5hdGl2ZVVSTFNlYXJjaFBhcmFtcyAmJiAobmV3IG5hdGl2ZVVSTFNlYXJjaFBhcmFtcyh7YTogMX0pKS50b1N0cmluZygpID09PSAnYT0xJyxcbiAgICAgICAgLy8gVGhlcmUgaXMgYSBidWcgaW4gc2FmYXJpIDEwLjEgKGFuZCBlYXJsaWVyKSB0aGF0IGluY29ycmVjdGx5IGRlY29kZXMgYCUyQmAgYXMgYW4gZW1wdHkgc3BhY2UgYW5kIG5vdCBhIHBsdXMuXG4gICAgICAgIGRlY29kZXNQbHVzZXNDb3JyZWN0bHkgPSBuYXRpdmVVUkxTZWFyY2hQYXJhbXMgJiYgKG5ldyBuYXRpdmVVUkxTZWFyY2hQYXJhbXMoJ3M9JTJCJykuZ2V0KCdzJykgPT09ICcrJyksXG4gICAgICAgIF9fVVJMU2VhcmNoUGFyYW1zX18gPSBcIl9fVVJMU2VhcmNoUGFyYW1zX19cIixcbiAgICAgICAgLy8gRml4IGJ1ZyBpbiBFZGdlIHdoaWNoIGNhbm5vdCBlbmNvZGUgJyAmJyBjb3JyZWN0bHlcbiAgICAgICAgZW5jb2Rlc0FtcGVyc2FuZHNDb3JyZWN0bHkgPSBuYXRpdmVVUkxTZWFyY2hQYXJhbXMgPyAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgYW1wZXJzYW5kVGVzdCA9IG5ldyBuYXRpdmVVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgICAgIGFtcGVyc2FuZFRlc3QuYXBwZW5kKCdzJywgJyAmJyk7XG4gICAgICAgICAgICByZXR1cm4gYW1wZXJzYW5kVGVzdC50b1N0cmluZygpID09PSAncz0rJTI2JztcbiAgICAgICAgfSkoKSA6IHRydWUsXG4gICAgICAgIHByb3RvdHlwZSA9IFVSTFNlYXJjaFBhcmFtc1BvbHlmaWxsLnByb3RvdHlwZSxcbiAgICAgICAgaXRlcmFibGUgPSAhIShzZWxmLlN5bWJvbCAmJiBzZWxmLlN5bWJvbC5pdGVyYXRvcik7XG5cbiAgICBpZiAobmF0aXZlVVJMU2VhcmNoUGFyYW1zICYmIGlzU3VwcG9ydE9iamVjdENvbnN0cnVjdG9yICYmIGRlY29kZXNQbHVzZXNDb3JyZWN0bHkgJiYgZW5jb2Rlc0FtcGVyc2FuZHNDb3JyZWN0bHkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogTWFrZSBhIFVSTFNlYXJjaFBhcmFtcyBpbnN0YW5jZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R8c3RyaW5nfFVSTFNlYXJjaFBhcmFtc30gc2VhcmNoXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgZnVuY3Rpb24gVVJMU2VhcmNoUGFyYW1zUG9seWZpbGwoc2VhcmNoKSB7XG4gICAgICAgIHNlYXJjaCA9IHNlYXJjaCB8fCBcIlwiO1xuXG4gICAgICAgIC8vIHN1cHBvcnQgY29uc3RydWN0IG9iamVjdCB3aXRoIGFub3RoZXIgVVJMU2VhcmNoUGFyYW1zIGluc3RhbmNlXG4gICAgICAgIGlmIChzZWFyY2ggaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXMgfHwgc2VhcmNoIGluc3RhbmNlb2YgVVJMU2VhcmNoUGFyYW1zUG9seWZpbGwpIHtcbiAgICAgICAgICAgIHNlYXJjaCA9IHNlYXJjaC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMgW19fVVJMU2VhcmNoUGFyYW1zX19dID0gcGFyc2VUb0RpY3Qoc2VhcmNoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEFwcGVuZHMgYSBzcGVjaWZpZWQga2V5L3ZhbHVlIHBhaXIgYXMgYSBuZXcgc2VhcmNoIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAgICovXG4gICAgcHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIGFwcGVuZFRvKHRoaXMgW19fVVJMU2VhcmNoUGFyYW1zX19dLCBuYW1lLCB2YWx1ZSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlbGV0ZXMgdGhlIGdpdmVuIHNlYXJjaCBwYXJhbWV0ZXIsIGFuZCBpdHMgYXNzb2NpYXRlZCB2YWx1ZSxcbiAgICAgKiBmcm9tIHRoZSBsaXN0IG9mIGFsbCBzZWFyY2ggcGFyYW1ldGVycy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICovXG4gICAgcHJvdG90eXBlWydkZWxldGUnXSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMgW19fVVJMU2VhcmNoUGFyYW1zX19dIFtuYW1lXTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZmlyc3QgdmFsdWUgYXNzb2NpYXRlZCB0byB0aGUgZ2l2ZW4gc2VhcmNoIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfVxuICAgICAqL1xuICAgIHByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHZhciBkaWN0ID0gdGhpcyBbX19VUkxTZWFyY2hQYXJhbXNfX107XG4gICAgICAgIHJldHVybiB0aGlzLmhhcyhuYW1lKSA/IGRpY3RbbmFtZV1bMF0gOiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFsbCB0aGUgdmFsdWVzIGFzc29jaWF0aW9uIHdpdGggYSBnaXZlbiBzZWFyY2ggcGFyYW1ldGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAgICovXG4gICAgcHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgdmFyIGRpY3QgPSB0aGlzIFtfX1VSTFNlYXJjaFBhcmFtc19fXTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzKG5hbWUpID8gZGljdCBbbmFtZV0uc2xpY2UoMCkgOiBbXTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIEJvb2xlYW4gaW5kaWNhdGluZyBpZiBzdWNoIGEgc2VhcmNoIHBhcmFtZXRlciBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIHByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eSh0aGlzIFtfX1VSTFNlYXJjaFBhcmFtc19fXSwgbmFtZSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgdG8gYSBnaXZlbiBzZWFyY2ggcGFyYW1ldGVyIHRvXG4gICAgICogdGhlIGdpdmVuIHZhbHVlLiBJZiB0aGVyZSB3ZXJlIHNldmVyYWwgdmFsdWVzLCBkZWxldGUgdGhlXG4gICAgICogb3RoZXJzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICAgKi9cbiAgICBwcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gc2V0KG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMgW19fVVJMU2VhcmNoUGFyYW1zX19dW25hbWVdID0gWycnICsgdmFsdWVdO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5nIGEgcXVlcnkgc3RyaW5nIHN1aXRhYmxlIGZvciB1c2UgaW4gYSBVUkwuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZGljdCA9IHRoaXNbX19VUkxTZWFyY2hQYXJhbXNfX10sIHF1ZXJ5ID0gW10sIGksIGtleSwgbmFtZSwgdmFsdWU7XG4gICAgICAgIGZvciAoa2V5IGluIGRpY3QpIHtcbiAgICAgICAgICAgIG5hbWUgPSBlbmNvZGUoa2V5KTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIHZhbHVlID0gZGljdFtrZXldOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBxdWVyeS5wdXNoKG5hbWUgKyAnPScgKyBlbmNvZGUodmFsdWVbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcXVlcnkuam9pbignJicpO1xuICAgIH07XG5cbiAgICAvLyBUaGVyZSBpcyBhIGJ1ZyBpbiBTYWZhcmkgMTAuMSBhbmQgYFByb3h5YGluZyBpdCBpcyBub3QgZW5vdWdoLlxuICAgIHZhciBmb3JTdXJlVXNlUG9seWZpbGwgPSAhZGVjb2Rlc1BsdXNlc0NvcnJlY3RseTtcbiAgICB2YXIgdXNlUHJveHkgPSAoIWZvclN1cmVVc2VQb2x5ZmlsbCAmJiBuYXRpdmVVUkxTZWFyY2hQYXJhbXMgJiYgIWlzU3VwcG9ydE9iamVjdENvbnN0cnVjdG9yICYmIHNlbGYuUHJveHkpO1xuICAgIC8qXG4gICAgICogQXBwbHkgcG9saWZpbGwgdG8gZ2xvYmFsIG9iamVjdCBhbmQgYXBwZW5kIG90aGVyIHByb3RvdHlwZSBpbnRvIGl0XG4gICAgICovXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbGYsICdVUkxTZWFyY2hQYXJhbXMnLCB7XG4gICAgICAgIHZhbHVlOiAodXNlUHJveHkgP1xuICAgICAgICAgICAgLy8gU2FmYXJpIDEwLjAgZG9lc24ndCBzdXBwb3J0IFByb3h5LCBzbyBpdCB3b24ndCBleHRlbmQgVVJMU2VhcmNoUGFyYW1zIG9uIHNhZmFyaSAxMC4wXG4gICAgICAgICAgICBuZXcgUHJveHkobmF0aXZlVVJMU2VhcmNoUGFyYW1zLCB7XG4gICAgICAgICAgICAgICAgY29uc3RydWN0OiBmdW5jdGlvbih0YXJnZXQsIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB0YXJnZXQoKG5ldyBVUkxTZWFyY2hQYXJhbXNQb2x5ZmlsbChhcmdzWzBdKS50b1N0cmluZygpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkgOlxuICAgICAgICAgICAgVVJMU2VhcmNoUGFyYW1zUG9seWZpbGwpXG4gICAgfSk7XG5cbiAgICB2YXIgVVNQUHJvdG8gPSBzZWxmLlVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGU7XG5cbiAgICBVU1BQcm90by5wb2x5ZmlsbCA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtvYmplY3R9IHRoaXNBcmdcbiAgICAgKi9cbiAgICBVU1BQcm90by5mb3JFYWNoID0gVVNQUHJvdG8uZm9yRWFjaCB8fCBmdW5jdGlvbihjYWxsYmFjaywgdGhpc0FyZykge1xuICAgICAgICB2YXIgZGljdCA9IHBhcnNlVG9EaWN0KHRoaXMudG9TdHJpbmcoKSk7XG4gICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGRpY3QpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICAgICAgZGljdFtuYW1lXS5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwgbmFtZSwgdGhpcyk7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNvcnQgYWxsIG5hbWUtdmFsdWUgcGFpcnNcbiAgICAgKi9cbiAgICBVU1BQcm90by5zb3J0ID0gVVNQUHJvdG8uc29ydCB8fCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGRpY3QgPSBwYXJzZVRvRGljdCh0aGlzLnRvU3RyaW5nKCkpLCBrZXlzID0gW10sIGssIGksIGo7XG4gICAgICAgIGZvciAoayBpbiBkaWN0KSB7XG4gICAgICAgICAgICBrZXlzLnB1c2goayk7XG4gICAgICAgIH1cbiAgICAgICAga2V5cy5zb3J0KCk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXNbJ2RlbGV0ZSddKGtleXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXSwgdmFsdWVzID0gZGljdFtrZXldO1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHZhbHVlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIHRoaXMuYXBwZW5kKGtleSwgdmFsdWVzW2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIGFsbG93aW5nIHRvIGdvIHRocm91Z2ggYWxsIGtleXMgb2ZcbiAgICAgKiB0aGUga2V5L3ZhbHVlIHBhaXJzIGNvbnRhaW5lZCBpbiB0aGlzIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbn1cbiAgICAgKi9cbiAgICBVU1BQcm90by5rZXlzID0gVVNQUHJvdG8ua2V5cyB8fCBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGl0ZW1zID0gW107XG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBuYW1lKSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKG5hbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1ha2VJdGVyYXRvcihpdGVtcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3IgYWxsb3dpbmcgdG8gZ28gdGhyb3VnaCBhbGwgdmFsdWVzIG9mXG4gICAgICogdGhlIGtleS92YWx1ZSBwYWlycyBjb250YWluZWQgaW4gdGhpcyBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb259XG4gICAgICovXG4gICAgVVNQUHJvdG8udmFsdWVzID0gVVNQUHJvdG8udmFsdWVzIHx8IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbWFrZUl0ZXJhdG9yKGl0ZW1zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBpdGVyYXRvciBhbGxvd2luZyB0byBnbyB0aHJvdWdoIGFsbCBrZXkvdmFsdWVcbiAgICAgKiBwYWlycyBjb250YWluZWQgaW4gdGhpcyBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb259XG4gICAgICovXG4gICAgVVNQUHJvdG8uZW50cmllcyA9IFVTUFByb3RvLmVudHJpZXMgfHwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24oaXRlbSwgbmFtZSkge1xuICAgICAgICAgICAgaXRlbXMucHVzaChbbmFtZSwgaXRlbV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1ha2VJdGVyYXRvcihpdGVtcyk7XG4gICAgfTtcblxuXG4gICAgaWYgKGl0ZXJhYmxlKSB7XG4gICAgICAgIFVTUFByb3RvW3NlbGYuU3ltYm9sLml0ZXJhdG9yXSA9IFVTUFByb3RvW3NlbGYuU3ltYm9sLml0ZXJhdG9yXSB8fCBVU1BQcm90by5lbnRyaWVzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gZW5jb2RlKHN0cikge1xuICAgICAgICB2YXIgcmVwbGFjZSA9IHtcbiAgICAgICAgICAgICchJzogJyUyMScsXG4gICAgICAgICAgICBcIidcIjogJyUyNycsXG4gICAgICAgICAgICAnKCc6ICclMjgnLFxuICAgICAgICAgICAgJyknOiAnJTI5JyxcbiAgICAgICAgICAgICd+JzogJyU3RScsXG4gICAgICAgICAgICAnJTIwJzogJysnLFxuICAgICAgICAgICAgJyUwMCc6ICdcXHgwMCdcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpLnJlcGxhY2UoL1shJ1xcKFxcKX5dfCUyMHwlMDAvZywgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBsYWNlW21hdGNoXTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVjb2RlKHN0cikge1xuICAgICAgICByZXR1cm4gc3RyXG4gICAgICAgICAgICAucmVwbGFjZSgvWyArXS9nLCAnJTIwJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC8oJVthLWYwLTldezJ9KSsvaWcsIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChtYXRjaCk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlSXRlcmF0b3IoYXJyKSB7XG4gICAgICAgIHZhciBpdGVyYXRvciA9IHtcbiAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGFyci5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7ZG9uZTogdmFsdWUgPT09IHVuZGVmaW5lZCwgdmFsdWU6IHZhbHVlfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoaXRlcmFibGUpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yW3NlbGYuU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvcjtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaXRlcmF0b3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VUb0RpY3Qoc2VhcmNoKSB7XG4gICAgICAgIHZhciBkaWN0ID0ge307XG5cbiAgICAgICAgaWYgKHR5cGVvZiBzZWFyY2ggPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIC8vIGlmIGBzZWFyY2hgIGlzIGFuIGFycmF5LCB0cmVhdCBpdCBhcyBhIHNlcXVlbmNlXG4gICAgICAgICAgICBpZiAoaXNBcnJheShzZWFyY2gpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWFyY2gubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSBzZWFyY2hbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KGl0ZW0pICYmIGl0ZW0ubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbyhkaWN0LCBpdGVtWzBdLCBpdGVtWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGYWlsZWQgdG8gY29uc3RydWN0ICdVUkxTZWFyY2hQYXJhbXMnOiBTZXF1ZW5jZSBpbml0aWFsaXplciBtdXN0IG9ubHkgY29udGFpbiBwYWlyIGVsZW1lbnRzXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBzZWFyY2gpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbyhkaWN0LCBrZXksIHNlYXJjaFtrZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGZpcnN0ICc/J1xuICAgICAgICAgICAgaWYgKHNlYXJjaC5pbmRleE9mKFwiP1wiKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNlYXJjaCA9IHNlYXJjaC5zbGljZSgxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBhaXJzID0gc2VhcmNoLnNwbGl0KFwiJlwiKTtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFpcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBwYWlycyBbal0sXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdmFsdWUuaW5kZXhPZignPScpO1xuXG4gICAgICAgICAgICAgICAgaWYgKC0xIDwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG8oZGljdCwgZGVjb2RlKHZhbHVlLnNsaWNlKDAsIGluZGV4KSksIGRlY29kZSh2YWx1ZS5zbGljZShpbmRleCArIDEpKSk7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZFRvKGRpY3QsIGRlY29kZSh2YWx1ZSksICcnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkaWN0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGVuZFRvKGRpY3QsIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHZhciB2YWwgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiAoXG4gICAgICAgICAgICB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZS50b1N0cmluZyA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnRvU3RyaW5nKCkgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcbiAgICAgICAgKTtcblxuICAgICAgICAvLyAjNDcgUHJldmVudCB1c2luZyBgaGFzT3duUHJvcGVydHlgIGFzIGEgcHJvcGVydHkgbmFtZVxuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkoZGljdCwgbmFtZSkpIHtcbiAgICAgICAgICAgIGRpY3RbbmFtZV0ucHVzaCh2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGljdFtuYW1lXSA9IFt2YWxdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheSh2YWwpIHtcbiAgICAgICAgcmV0dXJuICEhdmFsICYmICdbb2JqZWN0IEFycmF5XScgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWwpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG4gICAgfVxuXG59KSh0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMpKTtcbiIsInZhciByZW5kZXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIF92bSA9IHRoaXNcbiAgdmFyIF9oID0gX3ZtLiRjcmVhdGVFbGVtZW50XG4gIHZhciBfYyA9IF92bS5fc2VsZi5fYyB8fCBfaFxuICByZXR1cm4gX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZVwiIH0sIFtcbiAgICBfYyhcbiAgICAgIFwiZGl2XCIsXG4gICAgICB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX19tYWluXCIgfSxcbiAgICAgIFtcbiAgICAgICAgX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fY29udHJvbHNcIiB9LCBbXG4gICAgICAgICAgX2MoXCJoMlwiLCB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX19oZWFkaW5nXCIgfSwgW1xuICAgICAgICAgICAgX3ZtLl92KF92bS5fcyh0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5jYWxjdWxhdGVfZm9ybS5oZWFkaW5nKSlcbiAgICAgICAgICBdKSxcbiAgICAgICAgICBfdm0uX3YoXCIgXCIpLFxuICAgICAgICAgIF9jKFxuICAgICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICAgIHsgc3RhdGljQ2xhc3M6IFwiby1jYWxjdWxhdGVfX3NsaWRlcnNcIiB9LFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICBfYyhcInBheWJhY2stcGVyaW9kLWludGFrZVwiLCB7XG4gICAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uczogdGhpcy50cmFuc2xhdGlvbnMsXG4gICAgICAgICAgICAgICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgICAgICAgICAgICAgXCJvbi1kYXJrXCI6IFwiXCJcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uOiB7IGlucHV0c0NoYW5nZWQ6IF92bS51cGRhdGVSZXN1bHQgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIDFcbiAgICAgICAgICApXG4gICAgICAgIF0pLFxuICAgICAgICBfdm0uX3YoXCIgXCIpLFxuICAgICAgICBfYyhcbiAgICAgICAgICBcInBheWJhY2stcGVyaW9kLXJlc3VsdC10YWJsZVwiLFxuICAgICAgICAgIF92bS5fYihcbiAgICAgICAgICAgIHsgYXR0cnM6IHsgdHJhbnNsYXRpb25zOiB0aGlzLnRyYW5zbGF0aW9ucyB9IH0sXG4gICAgICAgICAgICBcInBheWJhY2stcGVyaW9kLXJlc3VsdC10YWJsZVwiLFxuICAgICAgICAgICAgdGhpcy5yZXN1bHRzLFxuICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIF92bS5fdihcIiBcIiksXG4gICAgICAgIF92bS5fdChcImNhbGN1bGF0ZS1jb250YWN0XCIpXG4gICAgICBdLFxuICAgICAgMlxuICAgIClcbiAgXSlcbn1cbnZhciBzdGF0aWNSZW5kZXJGbnMgPSBbXVxucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5cbmV4cG9ydCB7IHJlbmRlciwgc3RhdGljUmVuZGVyRm5zIH0iLCJ2YXIgcmVuZGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBfdm0gPSB0aGlzXG4gIHZhciBfaCA9IF92bS4kY3JlYXRlRWxlbWVudFxuICB2YXIgX2MgPSBfdm0uX3NlbGYuX2MgfHwgX2hcbiAgcmV0dXJuIF9jKFxuICAgIFwiZGl2XCIsXG4gICAgeyBjbGFzczogW1wiYy1yYW5nZS1zbGlkZXJzXCIsIHsgXCJjLXJhbmdlLXNsaWRlcnMtLW9uLWRhcmtcIjogX3ZtLm9uRGFyayB9XSB9LFxuICAgIFtcbiAgICAgIF9jKFxuICAgICAgICBcImRpdlwiLFxuICAgICAgICB7IHN0YXRpY0NsYXNzOiBcImMtcmFuZ2Utc2xpZGVyc19fcm93XCIgfSxcbiAgICAgICAgW1xuICAgICAgICAgIF9jKFxuICAgICAgICAgICAgXCJsYWJlbFwiLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdGF0aWNDbGFzczogXCJjLXJhbmdlLXNsaWRlcnNfX2xhYmVsXCIsXG4gICAgICAgICAgICAgIGF0dHJzOiB7IGZvcjogXCJzbGlkZXItdmFsdWUtd2lkdGhcIiB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgW192bS5fdihfdm0uX3ModGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMuc2xpZGVycy53aWR0aC5sYWJlbCkpXVxuICAgICAgICAgICksXG4gICAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgICBfYyhcImRpdlwiLCB7IHN0YXRpY0NsYXNzOiBcImMtcmFuZ2Utc2xpZGVyc19fbWV0ZXJcIiB9LCBbXG4gICAgICAgICAgICBfYyhcImlucHV0XCIsIHtcbiAgICAgICAgICAgICAgc3RhdGljQ2xhc3M6IFwiYy1pbnB1dC1yYW5nZVwiLFxuICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIGlkOiBcInJhbmdlU2xpZGVyV2lkdGhcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcInJhbmdlXCIsXG4gICAgICAgICAgICAgICAgc3RlcDogXCIxXCIsXG4gICAgICAgICAgICAgICAgbmFtZTogXCJ3aWR0aFwiLFxuICAgICAgICAgICAgICAgIG1pbjogdGhpcy5wYXJzZWRDb25maWcud2lkdGgubWluLFxuICAgICAgICAgICAgICAgIG1heDogdGhpcy5wYXJzZWRDb25maWcud2lkdGgubWF4XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGRvbVByb3BzOiB7IHZhbHVlOiB0aGlzLndpZHRoQ2FsY3VsYXRlZCB9LFxuICAgICAgICAgICAgICBvbjogeyBpbnB1dDogX3ZtLnNsaWRlckNoYW5nZWQsIGNoYW5nZTogX3ZtLnNsaWRlckNoYW5nZWQgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICBdKSxcbiAgICAgICAgICBfdm0uX3YoXCIgXCIpLFxuICAgICAgICAgIF9jKFwicGF5YmFjay1wZXJpb2QtdGV4dC1pbnB1dFwiLCB7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICBpZGVudGlmaWVyOiBcInJhbmdlU2xpZGVySW5wdXRXaWR0aFwiLFxuICAgICAgICAgICAgICBzdGVwOiAxLFxuICAgICAgICAgICAgICB2YWx1ZTogX3ZtLndpZHRoQ2FsY3VsYXRlZCxcbiAgICAgICAgICAgICAgbWluOiB0aGlzLnBhcnNlZENvbmZpZy53aWR0aC5taW4sXG4gICAgICAgICAgICAgIG1heDogdGhpcy5wYXJzZWRDb25maWcud2lkdGgubWF4LFxuICAgICAgICAgICAgICBsYWJlbFRleHQ6IHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMud2lkdGgudW5pdFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uOiB7IGNoYW5nZTogX3ZtLnF1YW50aXR5SW5wdXRDaGFuZ2VkIH1cbiAgICAgICAgICB9KVxuICAgICAgICBdLFxuICAgICAgICAxXG4gICAgICApLFxuICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgIF9jKFxuICAgICAgICBcImRpdlwiLFxuICAgICAgICB7IHN0YXRpY0NsYXNzOiBcImMtcmFuZ2Utc2xpZGVyc19fcm93XCIgfSxcbiAgICAgICAgW1xuICAgICAgICAgIF9jKFwibGFiZWxcIiwge1xuICAgICAgICAgICAgc3RhdGljQ2xhc3M6IFwiYy1yYW5nZS1zbGlkZXJzX19sYWJlbFwiLFxuICAgICAgICAgICAgYXR0cnM6IHsgZm9yOiBcInNsaWRlci12YWx1ZS1jb3N0c1wiIH0sXG4gICAgICAgICAgICBkb21Qcm9wczoge1xuICAgICAgICAgICAgICBpbm5lckhUTUw6IF92bS5fcyh0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5zbGlkZXJzLmNvc3RzLmxhYmVsKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIF92bS5fdihcIiBcIiksXG4gICAgICAgICAgX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJjLXJhbmdlLXNsaWRlcnNfX21ldGVyXCIgfSwgW1xuICAgICAgICAgICAgX2MoXCJpbnB1dFwiLCB7XG4gICAgICAgICAgICAgIHN0YXRpY0NsYXNzOiBcImMtaW5wdXQtcmFuZ2VcIixcbiAgICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgICBpZDogXCJyYW5nZVNsaWRlckNvc3RzXCIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJyYW5nZVwiLFxuICAgICAgICAgICAgICAgIHN0ZXA6IFwiNTAwMFwiLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwiY29zdHNcIixcbiAgICAgICAgICAgICAgICBtaW46IHRoaXMucGFyc2VkQ29uZmlnLmNvc3RzLm1pbixcbiAgICAgICAgICAgICAgICBtYXg6IHRoaXMucGFyc2VkQ29uZmlnLmNvc3RzLm1heFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBkb21Qcm9wczogeyB2YWx1ZTogdGhpcy5jb3N0c0NhbGN1bGF0ZWQgfSxcbiAgICAgICAgICAgICAgb246IHsgaW5wdXQ6IF92bS5zbGlkZXJDaGFuZ2VkLCBjaGFuZ2U6IF92bS5zbGlkZXJDaGFuZ2VkIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXSksXG4gICAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgICBfYyhcInBheWJhY2stcGVyaW9kLXRleHQtaW5wdXRcIiwge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgaWRlbnRpZmllcjogXCJyYW5nZVNsaWRlcklucHV0Q29zdHNcIixcbiAgICAgICAgICAgICAgc3RlcDogNTAwMCxcbiAgICAgICAgICAgICAgdmFsdWU6IF92bS5jb3N0c0NhbGN1bGF0ZWQsXG4gICAgICAgICAgICAgIG1pbjogdGhpcy5wYXJzZWRDb25maWcuY29zdHMubWluLFxuICAgICAgICAgICAgICBtYXg6IHRoaXMucGFyc2VkQ29uZmlnLmNvc3RzLm1heCxcbiAgICAgICAgICAgICAgZm9yQ3VycmVuY3k6IHRydWUsXG4gICAgICAgICAgICAgIGxhYmVsVGV4dDogdGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMuc2xpZGVycy5jb3N0cy51bml0XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb246IHsgY2hhbmdlOiBfdm0ucXVhbnRpdHlJbnB1dENoYW5nZWQgfVxuICAgICAgICAgIH0pXG4gICAgICAgIF0sXG4gICAgICAgIDFcbiAgICAgICksXG4gICAgICBfdm0uX3YoXCIgXCIpLFxuICAgICAgX2MoXG4gICAgICAgIFwiZGl2XCIsXG4gICAgICAgIHsgc3RhdGljQ2xhc3M6IFwiYy1yYW5nZS1zbGlkZXJzX19yb3dcIiB9LFxuICAgICAgICBbXG4gICAgICAgICAgX2MoXG4gICAgICAgICAgICBcImxhYmVsXCIsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN0YXRpY0NsYXNzOiBcImMtcmFuZ2Utc2xpZGVyc19fbGFiZWxcIixcbiAgICAgICAgICAgICAgYXR0cnM6IHsgZm9yOiBcInNsaWRlci12YWx1ZS1zYXZpbmdzXCIgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFtfdm0uX3YoX3ZtLl9zKHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMuc2F2aW5ncy5sYWJlbCkpXVxuICAgICAgICAgICksXG4gICAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgICBfYyhcImRpdlwiLCB7IHN0YXRpY0NsYXNzOiBcImMtcmFuZ2Utc2xpZGVyc19fbWV0ZXJcIiB9LCBbXG4gICAgICAgICAgICBfYyhcImlucHV0XCIsIHtcbiAgICAgICAgICAgICAgc3RhdGljQ2xhc3M6IFwiYy1pbnB1dC1yYW5nZVwiLFxuICAgICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICAgIGlkOiBcInJhbmdlU2xpZGVyU2F2aW5nc1wiLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwicmFuZ2VcIixcbiAgICAgICAgICAgICAgICBzdGVwOiBcIjFcIixcbiAgICAgICAgICAgICAgICBuYW1lOiBcInNhdmluZ3NcIixcbiAgICAgICAgICAgICAgICBtaW46IHRoaXMucGFyc2VkQ29uZmlnLnNhdmluZ3MubWluLFxuICAgICAgICAgICAgICAgIG1heDogdGhpcy5wYXJzZWRDb25maWcuc2F2aW5ncy5tYXhcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZG9tUHJvcHM6IHsgdmFsdWU6IHRoaXMuc2F2aW5nc0NhbGN1bGF0ZWQgfSxcbiAgICAgICAgICAgICAgb246IHsgaW5wdXQ6IF92bS5zbGlkZXJDaGFuZ2VkLCBjaGFuZ2U6IF92bS5zbGlkZXJDaGFuZ2VkIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXSksXG4gICAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgICBfYyhcInBheWJhY2stcGVyaW9kLXRleHQtaW5wdXRcIiwge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgaWRlbnRpZmllcjogXCJyYW5nZVNsaWRlcklucHV0U2F2aW5nc1wiLFxuICAgICAgICAgICAgICBzdGVwOiAxLFxuICAgICAgICAgICAgICB2YWx1ZTogX3ZtLnNhdmluZ3NDYWxjdWxhdGVkLFxuICAgICAgICAgICAgICBtaW46IHRoaXMucGFyc2VkQ29uZmlnLnNhdmluZ3MubWluLFxuICAgICAgICAgICAgICBtYXg6IHRoaXMucGFyc2VkQ29uZmlnLnNhdmluZ3MubWF4LFxuICAgICAgICAgICAgICBsYWJlbFRleHQ6IHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnNsaWRlcnMuc2F2aW5ncy51bml0XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb246IHsgY2hhbmdlOiBfdm0ucXVhbnRpdHlJbnB1dENoYW5nZWQgfVxuICAgICAgICAgIH0pXG4gICAgICAgIF0sXG4gICAgICAgIDFcbiAgICAgIClcbiAgICBdXG4gIClcbn1cbnZhciBzdGF0aWNSZW5kZXJGbnMgPSBbXVxucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5cbmV4cG9ydCB7IHJlbmRlciwgc3RhdGljUmVuZGVyRm5zIH0iLCJ2YXIgcmVuZGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBfdm0gPSB0aGlzXG4gIHZhciBfaCA9IF92bS4kY3JlYXRlRWxlbWVudFxuICB2YXIgX2MgPSBfdm0uX3NlbGYuX2MgfHwgX2hcbiAgcmV0dXJuIF9jKFxuICAgIFwiZGl2XCIsXG4gICAgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fdGFibGVcIiwgYXR0cnM6IHsgcm9sZTogXCJncmlkXCIgfSB9LFxuICAgIFtcbiAgICAgIF9jKFwiZGl2XCIsIHsgc3RhdGljQ2xhc3M6IFwiby1jYWxjdWxhdGVfX3Jvd1wiLCBhdHRyczogeyByb2xlOiBcInJvd1wiIH0gfSwgW1xuICAgICAgICBfYyhcbiAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX19sYWJlbCAgdS1mdy1ib2xkXCIsXG4gICAgICAgICAgICBhdHRyczogeyByb2xlOiBcImdyaWRjZWxsXCIgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgW192bS5fdihfdm0uX3ModGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMudGFibGUudGl0bGUpKV1cbiAgICAgICAgKVxuICAgICAgXSksXG4gICAgICBfdm0uX3YoXCIgXCIpLFxuICAgICAgX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fcm93XCIsIGF0dHJzOiB7IHJvbGU6IFwicm93XCIgfSB9LCBbXG4gICAgICAgIF9jKFxuICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fbGFiZWxcIiwgYXR0cnM6IHsgcm9sZTogXCJncmlkY2VsbFwiIH0gfSxcbiAgICAgICAgICBbXG4gICAgICAgICAgICBfYyhcInNwYW5cIiwgW1xuICAgICAgICAgICAgICBfdm0uX3YoX3ZtLl9zKHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnRhYmxlLmludmVzdG1lbnRDb3N0cykpXG4gICAgICAgICAgICBdKVxuICAgICAgICAgIF1cbiAgICAgICAgKSxcbiAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgX2MoXG4gICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX192YWx1ZVwiLCBhdHRyczogeyByb2xlOiBcImdyaWRjZWxsXCIgfSB9LFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIF9jKFwic3BhblwiLCB7IHN0YXRpY0NsYXNzOiBcInUtZnctYm9sZFwiIH0sIFtcbiAgICAgICAgICAgICAgX3ZtLl92KFwi4oKsIFwiICsgX3ZtLl9zKHRoaXMuaW52ZXN0bWVudENvc3RzRm9ybWF0dGVkKSlcbiAgICAgICAgICAgIF0pXG4gICAgICAgICAgXVxuICAgICAgICApXG4gICAgICBdKSxcbiAgICAgIF92bS5fdihcIiBcIiksXG4gICAgICBfYyhcImRpdlwiLCB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX19yb3dcIiwgYXR0cnM6IHsgcm9sZTogXCJyb3dcIiB9IH0sIFtcbiAgICAgICAgX2MoXG4gICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX19sYWJlbFwiLCBhdHRyczogeyByb2xlOiBcImdyaWRjZWxsXCIgfSB9LFxuICAgICAgICAgIFtfdm0uX3YoX3ZtLl9zKHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnRhYmxlLnBlc3RpY2lkZVNhdmluZ3MpKV1cbiAgICAgICAgKSxcbiAgICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgICAgX2MoXG4gICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICB7IHN0YXRpY0NsYXNzOiBcIm8tY2FsY3VsYXRlX192YWx1ZVwiLCBhdHRyczogeyByb2xlOiBcImdyaWRjZWxsXCIgfSB9LFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIF9jKFwic3BhblwiLCB7IHN0YXRpY0NsYXNzOiBcInUtZnctYm9sZFwiIH0sIFtcbiAgICAgICAgICAgICAgX3ZtLl92KFwi4oKsIFwiICsgX3ZtLl9zKHRoaXMucGVzdGljaWRlU2F2aW5nc0Zvcm1hdHRlZCkpXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIF92bS5fdihcIiBcIiArIF92bS5fcyh0aGlzLnBhcnNlZFRyYW5zbGF0aW9ucy5wZXJZZWFyKSArIFwiXFxuICAgICAgICBcIilcbiAgICAgICAgICBdXG4gICAgICAgIClcbiAgICAgIF0pLFxuICAgICAgX3ZtLl92KFwiIFwiKSxcbiAgICAgIF9jKFwiZGl2XCIsIHsgc3RhdGljQ2xhc3M6IFwiby1jYWxjdWxhdGVfX2Zvb3RlclwiIH0sIFtcbiAgICAgICAgX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fcm93XCIsIGF0dHJzOiB7IHJvbGU6IFwicm93XCIgfSB9LCBbXG4gICAgICAgICAgX2MoXG4gICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fbGFiZWxcIiwgYXR0cnM6IHsgcm9sZTogXCJncmlkY2VsbFwiIH0gfSxcbiAgICAgICAgICAgIFtfdm0uX3YoX3ZtLl9zKHRoaXMucGFyc2VkVHJhbnNsYXRpb25zLnRhYmxlLnBheWJhY2tUaW1lKSArIFwiOlwiKV1cbiAgICAgICAgICApLFxuICAgICAgICAgIF92bS5fdihcIiBcIiksXG4gICAgICAgICAgX2MoXG4gICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgeyBzdGF0aWNDbGFzczogXCJvLWNhbGN1bGF0ZV9fdmFsdWVcIiwgYXR0cnM6IHsgcm9sZTogXCJncmlkY2VsbFwiIH0gfSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgX2MoXCJzcGFuXCIsIHsgc3RhdGljQ2xhc3M6IFwidS1mdy1ib2xkXCIgfSwgW1xuICAgICAgICAgICAgICAgIF92bS5fdihfdm0uX3ModGhpcy5wYXliYWNrVGltZUZvcm1hdHRlZCkpXG4gICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICBfdm0uX3YoXG4gICAgICAgICAgICAgICAgXCIgXCIgKyBfdm0uX3ModGhpcy5wYXJzZWRUcmFuc2xhdGlvbnMueWVhcikgKyBcIlxcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIF1cbiAgICAgICAgICApXG4gICAgICAgIF0pXG4gICAgICBdKVxuICAgIF1cbiAgKVxufVxudmFyIHN0YXRpY1JlbmRlckZucyA9IFtdXG5yZW5kZXIuX3dpdGhTdHJpcHBlZCA9IHRydWVcblxuZXhwb3J0IHsgcmVuZGVyLCBzdGF0aWNSZW5kZXJGbnMgfSIsInZhciByZW5kZXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIF92bSA9IHRoaXNcbiAgdmFyIF9oID0gX3ZtLiRjcmVhdGVFbGVtZW50XG4gIHZhciBfYyA9IF92bS5fc2VsZi5fYyB8fCBfaFxuICByZXR1cm4gX2MoXCJkaXZcIiwgeyBzdGF0aWNDbGFzczogXCJjLXJhbmdlLXNsaWRlcnNfX2RldGFpbHNcIiB9LCBbXG4gICAgX2MoXCJpbnB1dFwiLCB7XG4gICAgICBkaXJlY3RpdmVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm1vZGVsXCIsXG4gICAgICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG4gICAgICAgICAgdmFsdWU6IF92bS5kaXNwbGF5VmFsdWUsXG4gICAgICAgICAgZXhwcmVzc2lvbjogXCJkaXNwbGF5VmFsdWVcIlxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgc3RhdGljQ2xhc3M6IFwiYy1yYW5nZS1zbGlkZXJzX192YWx1ZVwiLFxuICAgICAgYXR0cnM6IHtcbiAgICAgICAgZGlzYWJsZWQ6IHRydWUsXG4gICAgICAgIGlkOiBfdm0uaWRlbnRpZmllcixcbiAgICAgICAgXCJkYXRhLWxwaWdub3JlXCI6IFwidHJ1ZVwiLFxuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgYXV0b2NvbXBsZXRlOiBcIm9mZlwiXG4gICAgICB9LFxuICAgICAgZG9tUHJvcHM6IHsgdmFsdWU6IF92bS5kaXNwbGF5VmFsdWUgfSxcbiAgICAgIG9uOiB7XG4gICAgICAgIGtleWRvd246IF92bS5rZXlQcmVzc2VkLFxuICAgICAgICBpbnB1dDogZnVuY3Rpb24oJGV2ZW50KSB7XG4gICAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG4gICAgICAgICAgX3ZtLmRpc3BsYXlWYWx1ZSA9ICRldmVudC50YXJnZXQudmFsdWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuICAgIF92bS5fdihcIiBcIiksXG4gICAgX2MoXCJsYWJlbFwiLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJjLXJhbmdlLXNsaWRlcnNfX3VuaXRcIixcbiAgICAgIGF0dHJzOiB7IGZvcjogX3ZtLmlkZW50aWZpZXIgfSxcbiAgICAgIGRvbVByb3BzOiB7IGlubmVySFRNTDogX3ZtLl9zKHRoaXMubGFiZWxUZXh0KSB9XG4gICAgfSlcbiAgXSlcbn1cbnZhciBzdGF0aWNSZW5kZXJGbnMgPSBbXVxucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5cbmV4cG9ydCB7IHJlbmRlciwgc3RhdGljUmVuZGVyRm5zIH0iLCIvKiBnbG9iYWxzIF9fVlVFX1NTUl9DT05URVhUX18gKi9cblxuLy8gSU1QT1JUQU5UOiBEbyBOT1QgdXNlIEVTMjAxNSBmZWF0dXJlcyBpbiB0aGlzIGZpbGUgKGV4Y2VwdCBmb3IgbW9kdWxlcykuXG4vLyBUaGlzIG1vZHVsZSBpcyBhIHJ1bnRpbWUgdXRpbGl0eSBmb3IgY2xlYW5lciBjb21wb25lbnQgbW9kdWxlIG91dHB1dCBhbmQgd2lsbFxuLy8gYmUgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIHdlYnBhY2sgdXNlciBidW5kbGUuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG5vcm1hbGl6ZUNvbXBvbmVudCAoXG4gIHNjcmlwdEV4cG9ydHMsXG4gIHJlbmRlcixcbiAgc3RhdGljUmVuZGVyRm5zLFxuICBmdW5jdGlvbmFsVGVtcGxhdGUsXG4gIGluamVjdFN0eWxlcyxcbiAgc2NvcGVJZCxcbiAgbW9kdWxlSWRlbnRpZmllciwgLyogc2VydmVyIG9ubHkgKi9cbiAgc2hhZG93TW9kZSAvKiB2dWUtY2xpIG9ubHkgKi9cbikge1xuICAvLyBWdWUuZXh0ZW5kIGNvbnN0cnVjdG9yIGV4cG9ydCBpbnRlcm9wXG4gIHZhciBvcHRpb25zID0gdHlwZW9mIHNjcmlwdEV4cG9ydHMgPT09ICdmdW5jdGlvbidcbiAgICA/IHNjcmlwdEV4cG9ydHMub3B0aW9uc1xuICAgIDogc2NyaXB0RXhwb3J0c1xuXG4gIC8vIHJlbmRlciBmdW5jdGlvbnNcbiAgaWYgKHJlbmRlcikge1xuICAgIG9wdGlvbnMucmVuZGVyID0gcmVuZGVyXG4gICAgb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnMgPSBzdGF0aWNSZW5kZXJGbnNcbiAgICBvcHRpb25zLl9jb21waWxlZCA9IHRydWVcbiAgfVxuXG4gIC8vIGZ1bmN0aW9uYWwgdGVtcGxhdGVcbiAgaWYgKGZ1bmN0aW9uYWxUZW1wbGF0ZSkge1xuICAgIG9wdGlvbnMuZnVuY3Rpb25hbCA9IHRydWVcbiAgfVxuXG4gIC8vIHNjb3BlZElkXG4gIGlmIChzY29wZUlkKSB7XG4gICAgb3B0aW9ucy5fc2NvcGVJZCA9ICdkYXRhLXYtJyArIHNjb3BlSWRcbiAgfVxuXG4gIHZhciBob29rXG4gIGlmIChtb2R1bGVJZGVudGlmaWVyKSB7IC8vIHNlcnZlciBidWlsZFxuICAgIGhvb2sgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgLy8gMi4zIGluamVjdGlvblxuICAgICAgY29udGV4dCA9XG4gICAgICAgIGNvbnRleHQgfHwgLy8gY2FjaGVkIGNhbGxcbiAgICAgICAgKHRoaXMuJHZub2RlICYmIHRoaXMuJHZub2RlLnNzckNvbnRleHQpIHx8IC8vIHN0YXRlZnVsXG4gICAgICAgICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudC4kdm5vZGUgJiYgdGhpcy5wYXJlbnQuJHZub2RlLnNzckNvbnRleHQpIC8vIGZ1bmN0aW9uYWxcbiAgICAgIC8vIDIuMiB3aXRoIHJ1bkluTmV3Q29udGV4dDogdHJ1ZVxuICAgICAgaWYgKCFjb250ZXh0ICYmIHR5cGVvZiBfX1ZVRV9TU1JfQ09OVEVYVF9fICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb250ZXh0ID0gX19WVUVfU1NSX0NPTlRFWFRfX1xuICAgICAgfVxuICAgICAgLy8gaW5qZWN0IGNvbXBvbmVudCBzdHlsZXNcbiAgICAgIGlmIChpbmplY3RTdHlsZXMpIHtcbiAgICAgICAgaW5qZWN0U3R5bGVzLmNhbGwodGhpcywgY29udGV4dClcbiAgICAgIH1cbiAgICAgIC8vIHJlZ2lzdGVyIGNvbXBvbmVudCBtb2R1bGUgaWRlbnRpZmllciBmb3IgYXN5bmMgY2h1bmsgaW5mZXJyZW5jZVxuICAgICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5fcmVnaXN0ZXJlZENvbXBvbmVudHMpIHtcbiAgICAgICAgY29udGV4dC5fcmVnaXN0ZXJlZENvbXBvbmVudHMuYWRkKG1vZHVsZUlkZW50aWZpZXIpXG4gICAgICB9XG4gICAgfVxuICAgIC8vIHVzZWQgYnkgc3NyIGluIGNhc2UgY29tcG9uZW50IGlzIGNhY2hlZCBhbmQgYmVmb3JlQ3JlYXRlXG4gICAgLy8gbmV2ZXIgZ2V0cyBjYWxsZWRcbiAgICBvcHRpb25zLl9zc3JSZWdpc3RlciA9IGhvb2tcbiAgfSBlbHNlIGlmIChpbmplY3RTdHlsZXMpIHtcbiAgICBob29rID0gc2hhZG93TW9kZVxuICAgICAgPyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGluamVjdFN0eWxlcy5jYWxsKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgKG9wdGlvbnMuZnVuY3Rpb25hbCA/IHRoaXMucGFyZW50IDogdGhpcykuJHJvb3QuJG9wdGlvbnMuc2hhZG93Um9vdFxuICAgICAgICApXG4gICAgICB9XG4gICAgICA6IGluamVjdFN0eWxlc1xuICB9XG5cbiAgaWYgKGhvb2spIHtcbiAgICBpZiAob3B0aW9ucy5mdW5jdGlvbmFsKSB7XG4gICAgICAvLyBmb3IgdGVtcGxhdGUtb25seSBob3QtcmVsb2FkIGJlY2F1c2UgaW4gdGhhdCBjYXNlIHRoZSByZW5kZXIgZm4gZG9lc24ndFxuICAgICAgLy8gZ28gdGhyb3VnaCB0aGUgbm9ybWFsaXplclxuICAgICAgb3B0aW9ucy5faW5qZWN0U3R5bGVzID0gaG9va1xuICAgICAgLy8gcmVnaXN0ZXIgZm9yIGZ1bmN0aW9uYWwgY29tcG9uZW50IGluIHZ1ZSBmaWxlXG4gICAgICB2YXIgb3JpZ2luYWxSZW5kZXIgPSBvcHRpb25zLnJlbmRlclxuICAgICAgb3B0aW9ucy5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXJXaXRoU3R5bGVJbmplY3Rpb24gKGgsIGNvbnRleHQpIHtcbiAgICAgICAgaG9vay5jYWxsKGNvbnRleHQpXG4gICAgICAgIHJldHVybiBvcmlnaW5hbFJlbmRlcihoLCBjb250ZXh0KVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBpbmplY3QgY29tcG9uZW50IHJlZ2lzdHJhdGlvbiBhcyBiZWZvcmVDcmVhdGUgaG9va1xuICAgICAgdmFyIGV4aXN0aW5nID0gb3B0aW9ucy5iZWZvcmVDcmVhdGVcbiAgICAgIG9wdGlvbnMuYmVmb3JlQ3JlYXRlID0gZXhpc3RpbmdcbiAgICAgICAgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGhvb2spXG4gICAgICAgIDogW2hvb2tdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBleHBvcnRzOiBzY3JpcHRFeHBvcnRzLFxuICAgIG9wdGlvbnM6IG9wdGlvbnNcbiAgfVxufVxuIiwiLyohXG4gKiBWdWUuanMgdjIuNi4xMlxuICogKGMpIDIwMTQtMjAyMCBFdmFuIFlvdVxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbi8qICAqL1xuXG52YXIgZW1wdHlPYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcblxuLy8gVGhlc2UgaGVscGVycyBwcm9kdWNlIGJldHRlciBWTSBjb2RlIGluIEpTIGVuZ2luZXMgZHVlIHRvIHRoZWlyXG4vLyBleHBsaWNpdG5lc3MgYW5kIGZ1bmN0aW9uIGlubGluaW5nLlxuZnVuY3Rpb24gaXNVbmRlZiAodikge1xuICByZXR1cm4gdiA9PT0gdW5kZWZpbmVkIHx8IHYgPT09IG51bGxcbn1cblxuZnVuY3Rpb24gaXNEZWYgKHYpIHtcbiAgcmV0dXJuIHYgIT09IHVuZGVmaW5lZCAmJiB2ICE9PSBudWxsXG59XG5cbmZ1bmN0aW9uIGlzVHJ1ZSAodikge1xuICByZXR1cm4gdiA9PT0gdHJ1ZVxufVxuXG5mdW5jdGlvbiBpc0ZhbHNlICh2KSB7XG4gIHJldHVybiB2ID09PSBmYWxzZVxufVxuXG4vKipcbiAqIENoZWNrIGlmIHZhbHVlIGlzIHByaW1pdGl2ZS5cbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUgKHZhbHVlKSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcbiAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdzeW1ib2wnIHx8XG4gICAgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbidcbiAgKVxufVxuXG4vKipcbiAqIFF1aWNrIG9iamVjdCBjaGVjayAtIHRoaXMgaXMgcHJpbWFyaWx5IHVzZWQgdG8gdGVsbFxuICogT2JqZWN0cyBmcm9tIHByaW1pdGl2ZSB2YWx1ZXMgd2hlbiB3ZSBrbm93IHRoZSB2YWx1ZVxuICogaXMgYSBKU09OLWNvbXBsaWFudCB0eXBlLlxuICovXG5mdW5jdGlvbiBpc09iamVjdCAob2JqKSB7XG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCdcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHJhdyB0eXBlIHN0cmluZyBvZiBhIHZhbHVlLCBlLmcuLCBbb2JqZWN0IE9iamVjdF0uXG4gKi9cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiB0b1Jhd1R5cGUgKHZhbHVlKSB7XG4gIHJldHVybiBfdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpXG59XG5cbi8qKlxuICogU3RyaWN0IG9iamVjdCB0eXBlIGNoZWNrLiBPbmx5IHJldHVybnMgdHJ1ZVxuICogZm9yIHBsYWluIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCAob2JqKSB7XG4gIHJldHVybiBfdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBPYmplY3RdJ1xufVxuXG5mdW5jdGlvbiBpc1JlZ0V4cCAodikge1xuICByZXR1cm4gX3RvU3RyaW5nLmNhbGwodikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdmFsIGlzIGEgdmFsaWQgYXJyYXkgaW5kZXguXG4gKi9cbmZ1bmN0aW9uIGlzVmFsaWRBcnJheUluZGV4ICh2YWwpIHtcbiAgdmFyIG4gPSBwYXJzZUZsb2F0KFN0cmluZyh2YWwpKTtcbiAgcmV0dXJuIG4gPj0gMCAmJiBNYXRoLmZsb29yKG4pID09PSBuICYmIGlzRmluaXRlKHZhbClcbn1cblxuZnVuY3Rpb24gaXNQcm9taXNlICh2YWwpIHtcbiAgcmV0dXJuIChcbiAgICBpc0RlZih2YWwpICYmXG4gICAgdHlwZW9mIHZhbC50aGVuID09PSAnZnVuY3Rpb24nICYmXG4gICAgdHlwZW9mIHZhbC5jYXRjaCA9PT0gJ2Z1bmN0aW9uJ1xuICApXG59XG5cbi8qKlxuICogQ29udmVydCBhIHZhbHVlIHRvIGEgc3RyaW5nIHRoYXQgaXMgYWN0dWFsbHkgcmVuZGVyZWQuXG4gKi9cbmZ1bmN0aW9uIHRvU3RyaW5nICh2YWwpIHtcbiAgcmV0dXJuIHZhbCA9PSBudWxsXG4gICAgPyAnJ1xuICAgIDogQXJyYXkuaXNBcnJheSh2YWwpIHx8IChpc1BsYWluT2JqZWN0KHZhbCkgJiYgdmFsLnRvU3RyaW5nID09PSBfdG9TdHJpbmcpXG4gICAgICA/IEpTT04uc3RyaW5naWZ5KHZhbCwgbnVsbCwgMilcbiAgICAgIDogU3RyaW5nKHZhbClcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIGlucHV0IHZhbHVlIHRvIGEgbnVtYmVyIGZvciBwZXJzaXN0ZW5jZS5cbiAqIElmIHRoZSBjb252ZXJzaW9uIGZhaWxzLCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiB0b051bWJlciAodmFsKSB7XG4gIHZhciBuID0gcGFyc2VGbG9hdCh2YWwpO1xuICByZXR1cm4gaXNOYU4obikgPyB2YWwgOiBuXG59XG5cbi8qKlxuICogTWFrZSBhIG1hcCBhbmQgcmV0dXJuIGEgZnVuY3Rpb24gZm9yIGNoZWNraW5nIGlmIGEga2V5XG4gKiBpcyBpbiB0aGF0IG1hcC5cbiAqL1xuZnVuY3Rpb24gbWFrZU1hcCAoXG4gIHN0cixcbiAgZXhwZWN0c0xvd2VyQ2FzZVxuKSB7XG4gIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB2YXIgbGlzdCA9IHN0ci5zcGxpdCgnLCcpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBtYXBbbGlzdFtpXV0gPSB0cnVlO1xuICB9XG4gIHJldHVybiBleHBlY3RzTG93ZXJDYXNlXG4gICAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsLnRvTG93ZXJDYXNlKCldOyB9XG4gICAgOiBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsXTsgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgdGFnIGlzIGEgYnVpbHQtaW4gdGFnLlxuICovXG52YXIgaXNCdWlsdEluVGFnID0gbWFrZU1hcCgnc2xvdCxjb21wb25lbnQnLCB0cnVlKTtcblxuLyoqXG4gKiBDaGVjayBpZiBhbiBhdHRyaWJ1dGUgaXMgYSByZXNlcnZlZCBhdHRyaWJ1dGUuXG4gKi9cbnZhciBpc1Jlc2VydmVkQXR0cmlidXRlID0gbWFrZU1hcCgna2V5LHJlZixzbG90LHNsb3Qtc2NvcGUsaXMnKTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gaXRlbSBmcm9tIGFuIGFycmF5LlxuICovXG5mdW5jdGlvbiByZW1vdmUgKGFyciwgaXRlbSkge1xuICBpZiAoYXJyLmxlbmd0aCkge1xuICAgIHZhciBpbmRleCA9IGFyci5pbmRleE9mKGl0ZW0pO1xuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICByZXR1cm4gYXJyLnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFuIG9iamVjdCBoYXMgdGhlIHByb3BlcnR5LlxuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaGFzT3duIChvYmosIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBjYWNoZWQgdmVyc2lvbiBvZiBhIHB1cmUgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhY2hlZCAoZm4pIHtcbiAgdmFyIGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIChmdW5jdGlvbiBjYWNoZWRGbiAoc3RyKSB7XG4gICAgdmFyIGhpdCA9IGNhY2hlW3N0cl07XG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpXG4gIH0pXG59XG5cbi8qKlxuICogQ2FtZWxpemUgYSBoeXBoZW4tZGVsaW1pdGVkIHN0cmluZy5cbiAqL1xudmFyIGNhbWVsaXplUkUgPSAvLShcXHcpL2c7XG52YXIgY2FtZWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgZnVuY3Rpb24gKF8sIGMpIHsgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJzsgfSlcbn0pO1xuXG4vKipcbiAqIENhcGl0YWxpemUgYSBzdHJpbmcuXG4gKi9cbnZhciBjYXBpdGFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKVxufSk7XG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqL1xudmFyIGh5cGhlbmF0ZVJFID0gL1xcQihbQS1aXSkvZztcbnZhciBoeXBoZW5hdGUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICctJDEnKS50b0xvd2VyQ2FzZSgpXG59KTtcblxuLyoqXG4gKiBTaW1wbGUgYmluZCBwb2x5ZmlsbCBmb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IHN1cHBvcnQgaXQsXG4gKiBlLmcuLCBQaGFudG9tSlMgMS54LiBUZWNobmljYWxseSwgd2UgZG9uJ3QgbmVlZCB0aGlzIGFueW1vcmVcbiAqIHNpbmNlIG5hdGl2ZSBiaW5kIGlzIG5vdyBwZXJmb3JtYW50IGVub3VnaCBpbiBtb3N0IGJyb3dzZXJzLlxuICogQnV0IHJlbW92aW5nIGl0IHdvdWxkIG1lYW4gYnJlYWtpbmcgY29kZSB0aGF0IHdhcyBhYmxlIHRvIHJ1biBpblxuICogUGhhbnRvbUpTIDEueCwgc28gdGhpcyBtdXN0IGJlIGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKi9cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIHBvbHlmaWxsQmluZCAoZm4sIGN0eCkge1xuICBmdW5jdGlvbiBib3VuZEZuIChhKSB7XG4gICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHJldHVybiBsXG4gICAgICA/IGwgPiAxXG4gICAgICAgID8gZm4uYXBwbHkoY3R4LCBhcmd1bWVudHMpXG4gICAgICAgIDogZm4uY2FsbChjdHgsIGEpXG4gICAgICA6IGZuLmNhbGwoY3R4KVxuICB9XG5cbiAgYm91bmRGbi5fbGVuZ3RoID0gZm4ubGVuZ3RoO1xuICByZXR1cm4gYm91bmRGblxufVxuXG5mdW5jdGlvbiBuYXRpdmVCaW5kIChmbiwgY3R4KSB7XG4gIHJldHVybiBmbi5iaW5kKGN0eClcbn1cblxudmFyIGJpbmQgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZFxuICA/IG5hdGl2ZUJpbmRcbiAgOiBwb2x5ZmlsbEJpbmQ7XG5cbi8qKlxuICogQ29udmVydCBhbiBBcnJheS1saWtlIG9iamVjdCB0byBhIHJlYWwgQXJyYXkuXG4gKi9cbmZ1bmN0aW9uIHRvQXJyYXkgKGxpc3QsIHN0YXJ0KSB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgMDtcbiAgdmFyIGkgPSBsaXN0Lmxlbmd0aCAtIHN0YXJ0O1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGkpO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgcmV0W2ldID0gbGlzdFtpICsgc3RhcnRdO1xuICB9XG4gIHJldHVybiByZXRcbn1cblxuLyoqXG4gKiBNaXggcHJvcGVydGllcyBpbnRvIHRhcmdldCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCAodG8sIF9mcm9tKSB7XG4gIGZvciAodmFyIGtleSBpbiBfZnJvbSkge1xuICAgIHRvW2tleV0gPSBfZnJvbVtrZXldO1xuICB9XG4gIHJldHVybiB0b1xufVxuXG4vKipcbiAqIE1lcmdlIGFuIEFycmF5IG9mIE9iamVjdHMgaW50byBhIHNpbmdsZSBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0IChhcnIpIHtcbiAgdmFyIHJlcyA9IHt9O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcnJbaV0pIHtcbiAgICAgIGV4dGVuZChyZXMsIGFycltpXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuLyoqXG4gKiBQZXJmb3JtIG5vIG9wZXJhdGlvbi5cbiAqIFN0dWJiaW5nIGFyZ3MgdG8gbWFrZSBGbG93IGhhcHB5IHdpdGhvdXQgbGVhdmluZyB1c2VsZXNzIHRyYW5zcGlsZWQgY29kZVxuICogd2l0aCAuLi5yZXN0IChodHRwczovL2Zsb3cub3JnL2Jsb2cvMjAxNy8wNS8wNy9TdHJpY3QtRnVuY3Rpb24tQ2FsbC1Bcml0eS8pLlxuICovXG5mdW5jdGlvbiBub29wIChhLCBiLCBjKSB7fVxuXG4vKipcbiAqIEFsd2F5cyByZXR1cm4gZmFsc2UuXG4gKi9cbnZhciBubyA9IGZ1bmN0aW9uIChhLCBiLCBjKSB7IHJldHVybiBmYWxzZTsgfTtcblxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xuXG4vKipcbiAqIFJldHVybiB0aGUgc2FtZSB2YWx1ZS5cbiAqL1xudmFyIGlkZW50aXR5ID0gZnVuY3Rpb24gKF8pIHsgcmV0dXJuIF87IH07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzdHJpbmcgY29udGFpbmluZyBzdGF0aWMga2V5cyBmcm9tIGNvbXBpbGVyIG1vZHVsZXMuXG4gKi9cbmZ1bmN0aW9uIGdlblN0YXRpY0tleXMgKG1vZHVsZXMpIHtcbiAgcmV0dXJuIG1vZHVsZXMucmVkdWNlKGZ1bmN0aW9uIChrZXlzLCBtKSB7XG4gICAgcmV0dXJuIGtleXMuY29uY2F0KG0uc3RhdGljS2V5cyB8fCBbXSlcbiAgfSwgW10pLmpvaW4oJywnKVxufVxuXG4vKipcbiAqIENoZWNrIGlmIHR3byB2YWx1ZXMgYXJlIGxvb3NlbHkgZXF1YWwgLSB0aGF0IGlzLFxuICogaWYgdGhleSBhcmUgcGxhaW4gb2JqZWN0cywgZG8gdGhleSBoYXZlIHRoZSBzYW1lIHNoYXBlP1xuICovXG5mdW5jdGlvbiBsb29zZUVxdWFsIChhLCBiKSB7XG4gIGlmIChhID09PSBiKSB7IHJldHVybiB0cnVlIH1cbiAgdmFyIGlzT2JqZWN0QSA9IGlzT2JqZWN0KGEpO1xuICB2YXIgaXNPYmplY3RCID0gaXNPYmplY3QoYik7XG4gIGlmIChpc09iamVjdEEgJiYgaXNPYmplY3RCKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBpc0FycmF5QSA9IEFycmF5LmlzQXJyYXkoYSk7XG4gICAgICB2YXIgaXNBcnJheUIgPSBBcnJheS5pc0FycmF5KGIpO1xuICAgICAgaWYgKGlzQXJyYXlBICYmIGlzQXJyYXlCKSB7XG4gICAgICAgIHJldHVybiBhLmxlbmd0aCA9PT0gYi5sZW5ndGggJiYgYS5ldmVyeShmdW5jdGlvbiAoZSwgaSkge1xuICAgICAgICAgIHJldHVybiBsb29zZUVxdWFsKGUsIGJbaV0pXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2UgaWYgKGEgaW5zdGFuY2VvZiBEYXRlICYmIGIgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBhLmdldFRpbWUoKSA9PT0gYi5nZXRUaW1lKClcbiAgICAgIH0gZWxzZSBpZiAoIWlzQXJyYXlBICYmICFpc0FycmF5Qikge1xuICAgICAgICB2YXIga2V5c0EgPSBPYmplY3Qua2V5cyhhKTtcbiAgICAgICAgdmFyIGtleXNCID0gT2JqZWN0LmtleXMoYik7XG4gICAgICAgIHJldHVybiBrZXlzQS5sZW5ndGggPT09IGtleXNCLmxlbmd0aCAmJiBrZXlzQS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgcmV0dXJuIGxvb3NlRXF1YWwoYVtrZXldLCBiW2tleV0pXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9IGVsc2UgaWYgKCFpc09iamVjdEEgJiYgIWlzT2JqZWN0Qikge1xuICAgIHJldHVybiBTdHJpbmcoYSkgPT09IFN0cmluZyhiKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBmaXJzdCBpbmRleCBhdCB3aGljaCBhIGxvb3NlbHkgZXF1YWwgdmFsdWUgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgYXJyYXkgKGlmIHZhbHVlIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGUgYXJyYXkgbXVzdFxuICogY29udGFpbiBhbiBvYmplY3Qgb2YgdGhlIHNhbWUgc2hhcGUpLCBvciAtMSBpZiBpdCBpcyBub3QgcHJlc2VudC5cbiAqL1xuZnVuY3Rpb24gbG9vc2VJbmRleE9mIChhcnIsIHZhbCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsb29zZUVxdWFsKGFycltpXSwgdmFsKSkgeyByZXR1cm4gaSB9XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKlxuICogRW5zdXJlIGEgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgb25jZS5cbiAqL1xuZnVuY3Rpb24gb25jZSAoZm4pIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFNTUl9BVFRSID0gJ2RhdGEtc2VydmVyLXJlbmRlcmVkJztcblxudmFyIEFTU0VUX1RZUEVTID0gW1xuICAnY29tcG9uZW50JyxcbiAgJ2RpcmVjdGl2ZScsXG4gICdmaWx0ZXInXG5dO1xuXG52YXIgTElGRUNZQ0xFX0hPT0tTID0gW1xuICAnYmVmb3JlQ3JlYXRlJyxcbiAgJ2NyZWF0ZWQnLFxuICAnYmVmb3JlTW91bnQnLFxuICAnbW91bnRlZCcsXG4gICdiZWZvcmVVcGRhdGUnLFxuICAndXBkYXRlZCcsXG4gICdiZWZvcmVEZXN0cm95JyxcbiAgJ2Rlc3Ryb3llZCcsXG4gICdhY3RpdmF0ZWQnLFxuICAnZGVhY3RpdmF0ZWQnLFxuICAnZXJyb3JDYXB0dXJlZCcsXG4gICdzZXJ2ZXJQcmVmZXRjaCdcbl07XG5cbi8qICAqL1xuXG5cblxudmFyIGNvbmZpZyA9ICh7XG4gIC8qKlxuICAgKiBPcHRpb24gbWVyZ2Ugc3RyYXRlZ2llcyAodXNlZCBpbiBjb3JlL3V0aWwvb3B0aW9ucylcbiAgICovXG4gIC8vICRmbG93LWRpc2FibGUtbGluZVxuICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IE9iamVjdC5jcmVhdGUobnVsbCksXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc3VwcHJlc3Mgd2FybmluZ3MuXG4gICAqL1xuICBzaWxlbnQ6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBTaG93IHByb2R1Y3Rpb24gbW9kZSB0aXAgbWVzc2FnZSBvbiBib290P1xuICAgKi9cbiAgcHJvZHVjdGlvblRpcDogXCJkZXZlbG9wbWVudFwiICE9PSAncHJvZHVjdGlvbicsXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZW5hYmxlIGRldnRvb2xzXG4gICAqL1xuICBkZXZ0b29sczogXCJkZXZlbG9wbWVudFwiICE9PSAncHJvZHVjdGlvbicsXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVjb3JkIHBlcmZcbiAgICovXG4gIHBlcmZvcm1hbmNlOiBmYWxzZSxcblxuICAvKipcbiAgICogRXJyb3IgaGFuZGxlciBmb3Igd2F0Y2hlciBlcnJvcnNcbiAgICovXG4gIGVycm9ySGFuZGxlcjogbnVsbCxcblxuICAvKipcbiAgICogV2FybiBoYW5kbGVyIGZvciB3YXRjaGVyIHdhcm5zXG4gICAqL1xuICB3YXJuSGFuZGxlcjogbnVsbCxcblxuICAvKipcbiAgICogSWdub3JlIGNlcnRhaW4gY3VzdG9tIGVsZW1lbnRzXG4gICAqL1xuICBpZ25vcmVkRWxlbWVudHM6IFtdLFxuXG4gIC8qKlxuICAgKiBDdXN0b20gdXNlciBrZXkgYWxpYXNlcyBmb3Igdi1vblxuICAgKi9cbiAgLy8gJGZsb3ctZGlzYWJsZS1saW5lXG4gIGtleUNvZGVzOiBPYmplY3QuY3JlYXRlKG51bGwpLFxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHRhZyBpcyByZXNlcnZlZCBzbyB0aGF0IGl0IGNhbm5vdCBiZSByZWdpc3RlcmVkIGFzIGFcbiAgICogY29tcG9uZW50LiBUaGlzIGlzIHBsYXRmb3JtLWRlcGVuZGVudCBhbmQgbWF5IGJlIG92ZXJ3cml0dGVuLlxuICAgKi9cbiAgaXNSZXNlcnZlZFRhZzogbm8sXG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFuIGF0dHJpYnV0ZSBpcyByZXNlcnZlZCBzbyB0aGF0IGl0IGNhbm5vdCBiZSB1c2VkIGFzIGEgY29tcG9uZW50XG4gICAqIHByb3AuIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50IGFuZCBtYXkgYmUgb3ZlcndyaXR0ZW4uXG4gICAqL1xuICBpc1Jlc2VydmVkQXR0cjogbm8sXG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgdGFnIGlzIGFuIHVua25vd24gZWxlbWVudC5cbiAgICogUGxhdGZvcm0tZGVwZW5kZW50LlxuICAgKi9cbiAgaXNVbmtub3duRWxlbWVudDogbm8sXG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbmFtZXNwYWNlIG9mIGFuIGVsZW1lbnRcbiAgICovXG4gIGdldFRhZ05hbWVzcGFjZTogbm9vcCxcblxuICAvKipcbiAgICogUGFyc2UgdGhlIHJlYWwgdGFnIG5hbWUgZm9yIHRoZSBzcGVjaWZpYyBwbGF0Zm9ybS5cbiAgICovXG4gIHBhcnNlUGxhdGZvcm1UYWdOYW1lOiBpZGVudGl0eSxcblxuICAvKipcbiAgICogQ2hlY2sgaWYgYW4gYXR0cmlidXRlIG11c3QgYmUgYm91bmQgdXNpbmcgcHJvcGVydHksIGUuZy4gdmFsdWVcbiAgICogUGxhdGZvcm0tZGVwZW5kZW50LlxuICAgKi9cbiAgbXVzdFVzZVByb3A6IG5vLFxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIHVwZGF0ZXMgYXN5bmNocm9ub3VzbHkuIEludGVuZGVkIHRvIGJlIHVzZWQgYnkgVnVlIFRlc3QgVXRpbHNcbiAgICogVGhpcyB3aWxsIHNpZ25pZmljYW50bHkgcmVkdWNlIHBlcmZvcm1hbmNlIGlmIHNldCB0byBmYWxzZS5cbiAgICovXG4gIGFzeW5jOiB0cnVlLFxuXG4gIC8qKlxuICAgKiBFeHBvc2VkIGZvciBsZWdhY3kgcmVhc29uc1xuICAgKi9cbiAgX2xpZmVjeWNsZUhvb2tzOiBMSUZFQ1lDTEVfSE9PS1Ncbn0pO1xuXG4vKiAgKi9cblxuLyoqXG4gKiB1bmljb2RlIGxldHRlcnMgdXNlZCBmb3IgcGFyc2luZyBodG1sIHRhZ3MsIGNvbXBvbmVudCBuYW1lcyBhbmQgcHJvcGVydHkgcGF0aHMuXG4gKiB1c2luZyBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUzL3NlbWFudGljcy1zY3JpcHRpbmcuaHRtbCNwb3RlbnRpYWxjdXN0b21lbGVtZW50bmFtZVxuICogc2tpcHBpbmcgXFx1MTAwMDAtXFx1RUZGRkYgZHVlIHRvIGl0IGZyZWV6aW5nIHVwIFBoYW50b21KU1xuICovXG52YXIgdW5pY29kZVJlZ0V4cCA9IC9hLXpBLVpcXHUwMEI3XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjAzRi1cXHUyMDQwXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZELztcblxuLyoqXG4gKiBDaGVjayBpZiBhIHN0cmluZyBzdGFydHMgd2l0aCAkIG9yIF9cbiAqL1xuZnVuY3Rpb24gaXNSZXNlcnZlZCAoc3RyKSB7XG4gIHZhciBjID0gKHN0ciArICcnKS5jaGFyQ29kZUF0KDApO1xuICByZXR1cm4gYyA9PT0gMHgyNCB8fCBjID09PSAweDVGXG59XG5cbi8qKlxuICogRGVmaW5lIGEgcHJvcGVydHkuXG4gKi9cbmZ1bmN0aW9uIGRlZiAob2JqLCBrZXksIHZhbCwgZW51bWVyYWJsZSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICB2YWx1ZTogdmFsLFxuICAgIGVudW1lcmFibGU6ICEhZW51bWVyYWJsZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbi8qKlxuICogUGFyc2Ugc2ltcGxlIHBhdGguXG4gKi9cbnZhciBiYWlsUkUgPSBuZXcgUmVnRXhwKChcIlteXCIgKyAodW5pY29kZVJlZ0V4cC5zb3VyY2UpICsgXCIuJF9cXFxcZF1cIikpO1xuZnVuY3Rpb24gcGFyc2VQYXRoIChwYXRoKSB7XG4gIGlmIChiYWlsUkUudGVzdChwYXRoKSkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmopIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIW9iaikgeyByZXR1cm4gfVxuICAgICAgb2JqID0gb2JqW3NlZ21lbnRzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIG9ialxuICB9XG59XG5cbi8qICAqL1xuXG4vLyBjYW4gd2UgdXNlIF9fcHJvdG9fXz9cbnZhciBoYXNQcm90byA9ICdfX3Byb3RvX18nIGluIHt9O1xuXG4vLyBCcm93c2VyIGVudmlyb25tZW50IHNuaWZmaW5nXG52YXIgaW5Ccm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgaW5XZWV4ID0gdHlwZW9mIFdYRW52aXJvbm1lbnQgIT09ICd1bmRlZmluZWQnICYmICEhV1hFbnZpcm9ubWVudC5wbGF0Zm9ybTtcbnZhciB3ZWV4UGxhdGZvcm0gPSBpbldlZXggJiYgV1hFbnZpcm9ubWVudC5wbGF0Zm9ybS50b0xvd2VyQ2FzZSgpO1xudmFyIFVBID0gaW5Ccm93c2VyICYmIHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG52YXIgaXNJRSA9IFVBICYmIC9tc2llfHRyaWRlbnQvLnRlc3QoVUEpO1xudmFyIGlzSUU5ID0gVUEgJiYgVUEuaW5kZXhPZignbXNpZSA5LjAnKSA+IDA7XG52YXIgaXNFZGdlID0gVUEgJiYgVUEuaW5kZXhPZignZWRnZS8nKSA+IDA7XG52YXIgaXNBbmRyb2lkID0gKFVBICYmIFVBLmluZGV4T2YoJ2FuZHJvaWQnKSA+IDApIHx8ICh3ZWV4UGxhdGZvcm0gPT09ICdhbmRyb2lkJyk7XG52YXIgaXNJT1MgPSAoVUEgJiYgL2lwaG9uZXxpcGFkfGlwb2R8aW9zLy50ZXN0KFVBKSkgfHwgKHdlZXhQbGF0Zm9ybSA9PT0gJ2lvcycpO1xudmFyIGlzQ2hyb21lID0gVUEgJiYgL2Nocm9tZVxcL1xcZCsvLnRlc3QoVUEpICYmICFpc0VkZ2U7XG52YXIgaXNQaGFudG9tSlMgPSBVQSAmJiAvcGhhbnRvbWpzLy50ZXN0KFVBKTtcbnZhciBpc0ZGID0gVUEgJiYgVUEubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKTtcblxuLy8gRmlyZWZveCBoYXMgYSBcIndhdGNoXCIgZnVuY3Rpb24gb24gT2JqZWN0LnByb3RvdHlwZS4uLlxudmFyIG5hdGl2ZVdhdGNoID0gKHt9KS53YXRjaDtcblxudmFyIHN1cHBvcnRzUGFzc2l2ZSA9IGZhbHNlO1xuaWYgKGluQnJvd3Nlcikge1xuICB0cnkge1xuICAgIHZhciBvcHRzID0ge307XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9wdHMsICdwYXNzaXZlJywgKHtcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0ICgpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgc3VwcG9ydHNQYXNzaXZlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KSk7IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8yODVcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdC1wYXNzaXZlJywgbnVsbCwgb3B0cyk7XG4gIH0gY2F0Y2ggKGUpIHt9XG59XG5cbi8vIHRoaXMgbmVlZHMgdG8gYmUgbGF6eS1ldmFsZWQgYmVjYXVzZSB2dWUgbWF5IGJlIHJlcXVpcmVkIGJlZm9yZVxuLy8gdnVlLXNlcnZlci1yZW5kZXJlciBjYW4gc2V0IFZVRV9FTlZcbnZhciBfaXNTZXJ2ZXI7XG52YXIgaXNTZXJ2ZXJSZW5kZXJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGlmIChfaXNTZXJ2ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghaW5Ccm93c2VyICYmICFpbldlZXggJiYgdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGRldGVjdCBwcmVzZW5jZSBvZiB2dWUtc2VydmVyLXJlbmRlcmVyIGFuZCBhdm9pZFxuICAgICAgLy8gV2VicGFjayBzaGltbWluZyB0aGUgcHJvY2Vzc1xuICAgICAgX2lzU2VydmVyID0gZ2xvYmFsWydwcm9jZXNzJ10gJiYgZ2xvYmFsWydwcm9jZXNzJ10uZW52LlZVRV9FTlYgPT09ICdzZXJ2ZXInO1xuICAgIH0gZWxzZSB7XG4gICAgICBfaXNTZXJ2ZXIgPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIF9pc1NlcnZlclxufTtcblxuLy8gZGV0ZWN0IGRldnRvb2xzXG52YXIgZGV2dG9vbHMgPSBpbkJyb3dzZXIgJiYgd2luZG93Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX187XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBpc05hdGl2ZSAoQ3Rvcikge1xuICByZXR1cm4gdHlwZW9mIEN0b3IgPT09ICdmdW5jdGlvbicgJiYgL25hdGl2ZSBjb2RlLy50ZXN0KEN0b3IudG9TdHJpbmcoKSlcbn1cblxudmFyIGhhc1N5bWJvbCA9XG4gIHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFN5bWJvbCkgJiZcbiAgdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFJlZmxlY3Qub3duS2V5cyk7XG5cbnZhciBfU2V0O1xuLyogaXN0YW5idWwgaWdub3JlIGlmICovIC8vICRmbG93LWRpc2FibGUtbGluZVxuaWYgKHR5cGVvZiBTZXQgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFNldCkpIHtcbiAgLy8gdXNlIG5hdGl2ZSBTZXQgd2hlbiBhdmFpbGFibGUuXG4gIF9TZXQgPSBTZXQ7XG59IGVsc2Uge1xuICAvLyBhIG5vbi1zdGFuZGFyZCBTZXQgcG9seWZpbGwgdGhhdCBvbmx5IHdvcmtzIHdpdGggcHJpbWl0aXZlIGtleXMuXG4gIF9TZXQgPSAvKkBfX1BVUkVfXyovKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTZXQgKCkge1xuICAgICAgdGhpcy5zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cbiAgICBTZXQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIGhhcyAoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRba2V5XSA9PT0gdHJ1ZVxuICAgIH07XG4gICAgU2V0LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQgKGtleSkge1xuICAgICAgdGhpcy5zZXRba2V5XSA9IHRydWU7XG4gICAgfTtcbiAgICBTZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gY2xlYXIgKCkge1xuICAgICAgdGhpcy5zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2V0O1xuICB9KCkpO1xufVxuXG4vKiAgKi9cblxudmFyIHdhcm4gPSBub29wO1xudmFyIHRpcCA9IG5vb3A7XG52YXIgZ2VuZXJhdGVDb21wb25lbnRUcmFjZSA9IChub29wKTsgLy8gd29yayBhcm91bmQgZmxvdyBjaGVja1xudmFyIGZvcm1hdENvbXBvbmVudE5hbWUgPSAobm9vcCk7XG5cbntcbiAgdmFyIGhhc0NvbnNvbGUgPSB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCc7XG4gIHZhciBjbGFzc2lmeVJFID0gLyg/Ol58Wy1fXSkoXFx3KS9nO1xuICB2YXIgY2xhc3NpZnkgPSBmdW5jdGlvbiAoc3RyKSB7IHJldHVybiBzdHJcbiAgICAucmVwbGFjZShjbGFzc2lmeVJFLCBmdW5jdGlvbiAoYykgeyByZXR1cm4gYy50b1VwcGVyQ2FzZSgpOyB9KVxuICAgIC5yZXBsYWNlKC9bLV9dL2csICcnKTsgfTtcblxuICB3YXJuID0gZnVuY3Rpb24gKG1zZywgdm0pIHtcbiAgICB2YXIgdHJhY2UgPSB2bSA/IGdlbmVyYXRlQ29tcG9uZW50VHJhY2Uodm0pIDogJyc7XG5cbiAgICBpZiAoY29uZmlnLndhcm5IYW5kbGVyKSB7XG4gICAgICBjb25maWcud2FybkhhbmRsZXIuY2FsbChudWxsLCBtc2csIHZtLCB0cmFjZSk7XG4gICAgfSBlbHNlIGlmIChoYXNDb25zb2xlICYmICghY29uZmlnLnNpbGVudCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoKFwiW1Z1ZSB3YXJuXTogXCIgKyBtc2cgKyB0cmFjZSkpO1xuICAgIH1cbiAgfTtcblxuICB0aXAgPSBmdW5jdGlvbiAobXNnLCB2bSkge1xuICAgIGlmIChoYXNDb25zb2xlICYmICghY29uZmlnLnNpbGVudCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIltWdWUgdGlwXTogXCIgKyBtc2cgKyAoXG4gICAgICAgIHZtID8gZ2VuZXJhdGVDb21wb25lbnRUcmFjZSh2bSkgOiAnJ1xuICAgICAgKSk7XG4gICAgfVxuICB9O1xuXG4gIGZvcm1hdENvbXBvbmVudE5hbWUgPSBmdW5jdGlvbiAodm0sIGluY2x1ZGVGaWxlKSB7XG4gICAgaWYgKHZtLiRyb290ID09PSB2bSkge1xuICAgICAgcmV0dXJuICc8Um9vdD4nXG4gICAgfVxuICAgIHZhciBvcHRpb25zID0gdHlwZW9mIHZtID09PSAnZnVuY3Rpb24nICYmIHZtLmNpZCAhPSBudWxsXG4gICAgICA/IHZtLm9wdGlvbnNcbiAgICAgIDogdm0uX2lzVnVlXG4gICAgICAgID8gdm0uJG9wdGlvbnMgfHwgdm0uY29uc3RydWN0b3Iub3B0aW9uc1xuICAgICAgICA6IHZtO1xuICAgIHZhciBuYW1lID0gb3B0aW9ucy5uYW1lIHx8IG9wdGlvbnMuX2NvbXBvbmVudFRhZztcbiAgICB2YXIgZmlsZSA9IG9wdGlvbnMuX19maWxlO1xuICAgIGlmICghbmFtZSAmJiBmaWxlKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBmaWxlLm1hdGNoKC8oW14vXFxcXF0rKVxcLnZ1ZSQvKTtcbiAgICAgIG5hbWUgPSBtYXRjaCAmJiBtYXRjaFsxXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgKG5hbWUgPyAoXCI8XCIgKyAoY2xhc3NpZnkobmFtZSkpICsgXCI+XCIpIDogXCI8QW5vbnltb3VzPlwiKSArXG4gICAgICAoZmlsZSAmJiBpbmNsdWRlRmlsZSAhPT0gZmFsc2UgPyAoXCIgYXQgXCIgKyBmaWxlKSA6ICcnKVxuICAgIClcbiAgfTtcblxuICB2YXIgcmVwZWF0ID0gZnVuY3Rpb24gKHN0ciwgbikge1xuICAgIHZhciByZXMgPSAnJztcbiAgICB3aGlsZSAobikge1xuICAgICAgaWYgKG4gJSAyID09PSAxKSB7IHJlcyArPSBzdHI7IH1cbiAgICAgIGlmIChuID4gMSkgeyBzdHIgKz0gc3RyOyB9XG4gICAgICBuID4+PSAxO1xuICAgIH1cbiAgICByZXR1cm4gcmVzXG4gIH07XG5cbiAgZ2VuZXJhdGVDb21wb25lbnRUcmFjZSA9IGZ1bmN0aW9uICh2bSkge1xuICAgIGlmICh2bS5faXNWdWUgJiYgdm0uJHBhcmVudCkge1xuICAgICAgdmFyIHRyZWUgPSBbXTtcbiAgICAgIHZhciBjdXJyZW50UmVjdXJzaXZlU2VxdWVuY2UgPSAwO1xuICAgICAgd2hpbGUgKHZtKSB7XG4gICAgICAgIGlmICh0cmVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB2YXIgbGFzdCA9IHRyZWVbdHJlZS5sZW5ndGggLSAxXTtcbiAgICAgICAgICBpZiAobGFzdC5jb25zdHJ1Y3RvciA9PT0gdm0uY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZSsrO1xuICAgICAgICAgICAgdm0gPSB2bS4kcGFyZW50O1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZSA+IDApIHtcbiAgICAgICAgICAgIHRyZWVbdHJlZS5sZW5ndGggLSAxXSA9IFtsYXN0LCBjdXJyZW50UmVjdXJzaXZlU2VxdWVuY2VdO1xuICAgICAgICAgICAgY3VycmVudFJlY3Vyc2l2ZVNlcXVlbmNlID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdHJlZS5wdXNoKHZtKTtcbiAgICAgICAgdm0gPSB2bS4kcGFyZW50O1xuICAgICAgfVxuICAgICAgcmV0dXJuICdcXG5cXG5mb3VuZCBpblxcblxcbicgKyB0cmVlXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKHZtLCBpKSB7IHJldHVybiAoXCJcIiArIChpID09PSAwID8gJy0tLT4gJyA6IHJlcGVhdCgnICcsIDUgKyBpICogMikpICsgKEFycmF5LmlzQXJyYXkodm0pXG4gICAgICAgICAgICA/ICgoZm9ybWF0Q29tcG9uZW50TmFtZSh2bVswXSkpICsgXCIuLi4gKFwiICsgKHZtWzFdKSArIFwiIHJlY3Vyc2l2ZSBjYWxscylcIilcbiAgICAgICAgICAgIDogZm9ybWF0Q29tcG9uZW50TmFtZSh2bSkpKTsgfSlcbiAgICAgICAgLmpvaW4oJ1xcbicpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAoXCJcXG5cXG4oZm91bmQgaW4gXCIgKyAoZm9ybWF0Q29tcG9uZW50TmFtZSh2bSkpICsgXCIpXCIpXG4gICAgfVxuICB9O1xufVxuXG4vKiAgKi9cblxudmFyIHVpZCA9IDA7XG5cbi8qKlxuICogQSBkZXAgaXMgYW4gb2JzZXJ2YWJsZSB0aGF0IGNhbiBoYXZlIG11bHRpcGxlXG4gKiBkaXJlY3RpdmVzIHN1YnNjcmliaW5nIHRvIGl0LlxuICovXG52YXIgRGVwID0gZnVuY3Rpb24gRGVwICgpIHtcbiAgdGhpcy5pZCA9IHVpZCsrO1xuICB0aGlzLnN1YnMgPSBbXTtcbn07XG5cbkRlcC5wcm90b3R5cGUuYWRkU3ViID0gZnVuY3Rpb24gYWRkU3ViIChzdWIpIHtcbiAgdGhpcy5zdWJzLnB1c2goc3ViKTtcbn07XG5cbkRlcC5wcm90b3R5cGUucmVtb3ZlU3ViID0gZnVuY3Rpb24gcmVtb3ZlU3ViIChzdWIpIHtcbiAgcmVtb3ZlKHRoaXMuc3Vicywgc3ViKTtcbn07XG5cbkRlcC5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHtcbiAgaWYgKERlcC50YXJnZXQpIHtcbiAgICBEZXAudGFyZ2V0LmFkZERlcCh0aGlzKTtcbiAgfVxufTtcblxuRGVwLnByb3RvdHlwZS5ub3RpZnkgPSBmdW5jdGlvbiBub3RpZnkgKCkge1xuICAvLyBzdGFiaWxpemUgdGhlIHN1YnNjcmliZXIgbGlzdCBmaXJzdFxuICB2YXIgc3VicyA9IHRoaXMuc3Vicy5zbGljZSgpO1xuICBpZiAoIWNvbmZpZy5hc3luYykge1xuICAgIC8vIHN1YnMgYXJlbid0IHNvcnRlZCBpbiBzY2hlZHVsZXIgaWYgbm90IHJ1bm5pbmcgYXN5bmNcbiAgICAvLyB3ZSBuZWVkIHRvIHNvcnQgdGhlbSBub3cgdG8gbWFrZSBzdXJlIHRoZXkgZmlyZSBpbiBjb3JyZWN0XG4gICAgLy8gb3JkZXJcbiAgICBzdWJzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEuaWQgLSBiLmlkOyB9KTtcbiAgfVxuICBmb3IgKHZhciBpID0gMCwgbCA9IHN1YnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgc3Vic1tpXS51cGRhdGUoKTtcbiAgfVxufTtcblxuLy8gVGhlIGN1cnJlbnQgdGFyZ2V0IHdhdGNoZXIgYmVpbmcgZXZhbHVhdGVkLlxuLy8gVGhpcyBpcyBnbG9iYWxseSB1bmlxdWUgYmVjYXVzZSBvbmx5IG9uZSB3YXRjaGVyXG4vLyBjYW4gYmUgZXZhbHVhdGVkIGF0IGEgdGltZS5cbkRlcC50YXJnZXQgPSBudWxsO1xudmFyIHRhcmdldFN0YWNrID0gW107XG5cbmZ1bmN0aW9uIHB1c2hUYXJnZXQgKHRhcmdldCkge1xuICB0YXJnZXRTdGFjay5wdXNoKHRhcmdldCk7XG4gIERlcC50YXJnZXQgPSB0YXJnZXQ7XG59XG5cbmZ1bmN0aW9uIHBvcFRhcmdldCAoKSB7XG4gIHRhcmdldFN0YWNrLnBvcCgpO1xuICBEZXAudGFyZ2V0ID0gdGFyZ2V0U3RhY2tbdGFyZ2V0U3RhY2subGVuZ3RoIC0gMV07XG59XG5cbi8qICAqL1xuXG52YXIgVk5vZGUgPSBmdW5jdGlvbiBWTm9kZSAoXG4gIHRhZyxcbiAgZGF0YSxcbiAgY2hpbGRyZW4sXG4gIHRleHQsXG4gIGVsbSxcbiAgY29udGV4dCxcbiAgY29tcG9uZW50T3B0aW9ucyxcbiAgYXN5bmNGYWN0b3J5XG4pIHtcbiAgdGhpcy50YWcgPSB0YWc7XG4gIHRoaXMuZGF0YSA9IGRhdGE7XG4gIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgdGhpcy5lbG0gPSBlbG07XG4gIHRoaXMubnMgPSB1bmRlZmluZWQ7XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuZm5Db250ZXh0ID0gdW5kZWZpbmVkO1xuICB0aGlzLmZuT3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgdGhpcy5mblNjb3BlSWQgPSB1bmRlZmluZWQ7XG4gIHRoaXMua2V5ID0gZGF0YSAmJiBkYXRhLmtleTtcbiAgdGhpcy5jb21wb25lbnRPcHRpb25zID0gY29tcG9uZW50T3B0aW9ucztcbiAgdGhpcy5jb21wb25lbnRJbnN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWQ7XG4gIHRoaXMucmF3ID0gZmFsc2U7XG4gIHRoaXMuaXNTdGF0aWMgPSBmYWxzZTtcbiAgdGhpcy5pc1Jvb3RJbnNlcnQgPSB0cnVlO1xuICB0aGlzLmlzQ29tbWVudCA9IGZhbHNlO1xuICB0aGlzLmlzQ2xvbmVkID0gZmFsc2U7XG4gIHRoaXMuaXNPbmNlID0gZmFsc2U7XG4gIHRoaXMuYXN5bmNGYWN0b3J5ID0gYXN5bmNGYWN0b3J5O1xuICB0aGlzLmFzeW5jTWV0YSA9IHVuZGVmaW5lZDtcbiAgdGhpcy5pc0FzeW5jUGxhY2Vob2xkZXIgPSBmYWxzZTtcbn07XG5cbnZhciBwcm90b3R5cGVBY2Nlc3NvcnMgPSB7IGNoaWxkOiB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH07XG5cbi8vIERFUFJFQ0FURUQ6IGFsaWFzIGZvciBjb21wb25lbnRJbnN0YW5jZSBmb3IgYmFja3dhcmRzIGNvbXBhdC5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5wcm90b3R5cGVBY2Nlc3NvcnMuY2hpbGQuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5jb21wb25lbnRJbnN0YW5jZVxufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIFZOb2RlLnByb3RvdHlwZSwgcHJvdG90eXBlQWNjZXNzb3JzICk7XG5cbnZhciBjcmVhdGVFbXB0eVZOb2RlID0gZnVuY3Rpb24gKHRleHQpIHtcbiAgaWYgKCB0ZXh0ID09PSB2b2lkIDAgKSB0ZXh0ID0gJyc7XG5cbiAgdmFyIG5vZGUgPSBuZXcgVk5vZGUoKTtcbiAgbm9kZS50ZXh0ID0gdGV4dDtcbiAgbm9kZS5pc0NvbW1lbnQgPSB0cnVlO1xuICByZXR1cm4gbm9kZVxufTtcblxuZnVuY3Rpb24gY3JlYXRlVGV4dFZOb2RlICh2YWwpIHtcbiAgcmV0dXJuIG5ldyBWTm9kZSh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBTdHJpbmcodmFsKSlcbn1cblxuLy8gb3B0aW1pemVkIHNoYWxsb3cgY2xvbmVcbi8vIHVzZWQgZm9yIHN0YXRpYyBub2RlcyBhbmQgc2xvdCBub2RlcyBiZWNhdXNlIHRoZXkgbWF5IGJlIHJldXNlZCBhY3Jvc3Ncbi8vIG11bHRpcGxlIHJlbmRlcnMsIGNsb25pbmcgdGhlbSBhdm9pZHMgZXJyb3JzIHdoZW4gRE9NIG1hbmlwdWxhdGlvbnMgcmVseVxuLy8gb24gdGhlaXIgZWxtIHJlZmVyZW5jZS5cbmZ1bmN0aW9uIGNsb25lVk5vZGUgKHZub2RlKSB7XG4gIHZhciBjbG9uZWQgPSBuZXcgVk5vZGUoXG4gICAgdm5vZGUudGFnLFxuICAgIHZub2RlLmRhdGEsXG4gICAgLy8gIzc5NzVcbiAgICAvLyBjbG9uZSBjaGlsZHJlbiBhcnJheSB0byBhdm9pZCBtdXRhdGluZyBvcmlnaW5hbCBpbiBjYXNlIG9mIGNsb25pbmdcbiAgICAvLyBhIGNoaWxkLlxuICAgIHZub2RlLmNoaWxkcmVuICYmIHZub2RlLmNoaWxkcmVuLnNsaWNlKCksXG4gICAgdm5vZGUudGV4dCxcbiAgICB2bm9kZS5lbG0sXG4gICAgdm5vZGUuY29udGV4dCxcbiAgICB2bm9kZS5jb21wb25lbnRPcHRpb25zLFxuICAgIHZub2RlLmFzeW5jRmFjdG9yeVxuICApO1xuICBjbG9uZWQubnMgPSB2bm9kZS5ucztcbiAgY2xvbmVkLmlzU3RhdGljID0gdm5vZGUuaXNTdGF0aWM7XG4gIGNsb25lZC5rZXkgPSB2bm9kZS5rZXk7XG4gIGNsb25lZC5pc0NvbW1lbnQgPSB2bm9kZS5pc0NvbW1lbnQ7XG4gIGNsb25lZC5mbkNvbnRleHQgPSB2bm9kZS5mbkNvbnRleHQ7XG4gIGNsb25lZC5mbk9wdGlvbnMgPSB2bm9kZS5mbk9wdGlvbnM7XG4gIGNsb25lZC5mblNjb3BlSWQgPSB2bm9kZS5mblNjb3BlSWQ7XG4gIGNsb25lZC5hc3luY01ldGEgPSB2bm9kZS5hc3luY01ldGE7XG4gIGNsb25lZC5pc0Nsb25lZCA9IHRydWU7XG4gIHJldHVybiBjbG9uZWRcbn1cblxuLypcbiAqIG5vdCB0eXBlIGNoZWNraW5nIHRoaXMgZmlsZSBiZWNhdXNlIGZsb3cgZG9lc24ndCBwbGF5IHdlbGwgd2l0aFxuICogZHluYW1pY2FsbHkgYWNjZXNzaW5nIG1ldGhvZHMgb24gQXJyYXkgcHJvdG90eXBlXG4gKi9cblxudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG52YXIgYXJyYXlNZXRob2RzID0gT2JqZWN0LmNyZWF0ZShhcnJheVByb3RvKTtcblxudmFyIG1ldGhvZHNUb1BhdGNoID0gW1xuICAncHVzaCcsXG4gICdwb3AnLFxuICAnc2hpZnQnLFxuICAndW5zaGlmdCcsXG4gICdzcGxpY2UnLFxuICAnc29ydCcsXG4gICdyZXZlcnNlJ1xuXTtcblxuLyoqXG4gKiBJbnRlcmNlcHQgbXV0YXRpbmcgbWV0aG9kcyBhbmQgZW1pdCBldmVudHNcbiAqL1xubWV0aG9kc1RvUGF0Y2guZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gIC8vIGNhY2hlIG9yaWdpbmFsIG1ldGhvZFxuICB2YXIgb3JpZ2luYWwgPSBhcnJheVByb3RvW21ldGhvZF07XG4gIGRlZihhcnJheU1ldGhvZHMsIG1ldGhvZCwgZnVuY3Rpb24gbXV0YXRvciAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB3aGlsZSAoIGxlbi0tICkgYXJnc1sgbGVuIF0gPSBhcmd1bWVudHNbIGxlbiBdO1xuXG4gICAgdmFyIHJlc3VsdCA9IG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIHZhciBvYiA9IHRoaXMuX19vYl9fO1xuICAgIHZhciBpbnNlcnRlZDtcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAncHVzaCc6XG4gICAgICBjYXNlICd1bnNoaWZ0JzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzO1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnc3BsaWNlJzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzLnNsaWNlKDIpO1xuICAgICAgICBicmVha1xuICAgIH1cbiAgICBpZiAoaW5zZXJ0ZWQpIHsgb2Iub2JzZXJ2ZUFycmF5KGluc2VydGVkKTsgfVxuICAgIC8vIG5vdGlmeSBjaGFuZ2VcbiAgICBvYi5kZXAubm90aWZ5KCk7XG4gICAgcmV0dXJuIHJlc3VsdFxuICB9KTtcbn0pO1xuXG4vKiAgKi9cblxudmFyIGFycmF5S2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFycmF5TWV0aG9kcyk7XG5cbi8qKlxuICogSW4gc29tZSBjYXNlcyB3ZSBtYXkgd2FudCB0byBkaXNhYmxlIG9ic2VydmF0aW9uIGluc2lkZSBhIGNvbXBvbmVudCdzXG4gKiB1cGRhdGUgY29tcHV0YXRpb24uXG4gKi9cbnZhciBzaG91bGRPYnNlcnZlID0gdHJ1ZTtcblxuZnVuY3Rpb24gdG9nZ2xlT2JzZXJ2aW5nICh2YWx1ZSkge1xuICBzaG91bGRPYnNlcnZlID0gdmFsdWU7XG59XG5cbi8qKlxuICogT2JzZXJ2ZXIgY2xhc3MgdGhhdCBpcyBhdHRhY2hlZCB0byBlYWNoIG9ic2VydmVkXG4gKiBvYmplY3QuIE9uY2UgYXR0YWNoZWQsIHRoZSBvYnNlcnZlciBjb252ZXJ0cyB0aGUgdGFyZ2V0XG4gKiBvYmplY3QncyBwcm9wZXJ0eSBrZXlzIGludG8gZ2V0dGVyL3NldHRlcnMgdGhhdFxuICogY29sbGVjdCBkZXBlbmRlbmNpZXMgYW5kIGRpc3BhdGNoIHVwZGF0ZXMuXG4gKi9cbnZhciBPYnNlcnZlciA9IGZ1bmN0aW9uIE9ic2VydmVyICh2YWx1ZSkge1xuICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIHRoaXMuZGVwID0gbmV3IERlcCgpO1xuICB0aGlzLnZtQ291bnQgPSAwO1xuICBkZWYodmFsdWUsICdfX29iX18nLCB0aGlzKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgaWYgKGhhc1Byb3RvKSB7XG4gICAgICBwcm90b0F1Z21lbnQodmFsdWUsIGFycmF5TWV0aG9kcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvcHlBdWdtZW50KHZhbHVlLCBhcnJheU1ldGhvZHMsIGFycmF5S2V5cyk7XG4gICAgfVxuICAgIHRoaXMub2JzZXJ2ZUFycmF5KHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndhbGsodmFsdWUpO1xuICB9XG59O1xuXG4vKipcbiAqIFdhbGsgdGhyb3VnaCBhbGwgcHJvcGVydGllcyBhbmQgY29udmVydCB0aGVtIGludG9cbiAqIGdldHRlci9zZXR0ZXJzLiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSBjYWxsZWQgd2hlblxuICogdmFsdWUgdHlwZSBpcyBPYmplY3QuXG4gKi9cbk9ic2VydmVyLnByb3RvdHlwZS53YWxrID0gZnVuY3Rpb24gd2FsayAob2JqKSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgZGVmaW5lUmVhY3RpdmUkJDEob2JqLCBrZXlzW2ldKTtcbiAgfVxufTtcblxuLyoqXG4gKiBPYnNlcnZlIGEgbGlzdCBvZiBBcnJheSBpdGVtcy5cbiAqL1xuT2JzZXJ2ZXIucHJvdG90eXBlLm9ic2VydmVBcnJheSA9IGZ1bmN0aW9uIG9ic2VydmVBcnJheSAoaXRlbXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBpdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvYnNlcnZlKGl0ZW1zW2ldKTtcbiAgfVxufTtcblxuLy8gaGVscGVyc1xuXG4vKipcbiAqIEF1Z21lbnQgYSB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGludGVyY2VwdGluZ1xuICogdGhlIHByb3RvdHlwZSBjaGFpbiB1c2luZyBfX3Byb3RvX19cbiAqL1xuZnVuY3Rpb24gcHJvdG9BdWdtZW50ICh0YXJnZXQsIHNyYykge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuICB0YXJnZXQuX19wcm90b19fID0gc3JjO1xuICAvKiBlc2xpbnQtZW5hYmxlIG5vLXByb3RvICovXG59XG5cbi8qKlxuICogQXVnbWVudCBhIHRhcmdldCBPYmplY3Qgb3IgQXJyYXkgYnkgZGVmaW5pbmdcbiAqIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICovXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gY29weUF1Z21lbnQgKHRhcmdldCwgc3JjLCBrZXlzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0ga2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICBkZWYodGFyZ2V0LCBrZXksIHNyY1trZXldKTtcbiAgfVxufVxuXG4vKipcbiAqIEF0dGVtcHQgdG8gY3JlYXRlIGFuIG9ic2VydmVyIGluc3RhbmNlIGZvciBhIHZhbHVlLFxuICogcmV0dXJucyB0aGUgbmV3IG9ic2VydmVyIGlmIHN1Y2Nlc3NmdWxseSBvYnNlcnZlZCxcbiAqIG9yIHRoZSBleGlzdGluZyBvYnNlcnZlciBpZiB0aGUgdmFsdWUgYWxyZWFkeSBoYXMgb25lLlxuICovXG5mdW5jdGlvbiBvYnNlcnZlICh2YWx1ZSwgYXNSb290RGF0YSkge1xuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCB2YWx1ZSBpbnN0YW5jZW9mIFZOb2RlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG9iO1xuICBpZiAoaGFzT3duKHZhbHVlLCAnX19vYl9fJykgJiYgdmFsdWUuX19vYl9fIGluc3RhbmNlb2YgT2JzZXJ2ZXIpIHtcbiAgICBvYiA9IHZhbHVlLl9fb2JfXztcbiAgfSBlbHNlIGlmIChcbiAgICBzaG91bGRPYnNlcnZlICYmXG4gICAgIWlzU2VydmVyUmVuZGVyaW5nKCkgJiZcbiAgICAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgaXNQbGFpbk9iamVjdCh2YWx1ZSkpICYmXG4gICAgT2JqZWN0LmlzRXh0ZW5zaWJsZSh2YWx1ZSkgJiZcbiAgICAhdmFsdWUuX2lzVnVlXG4gICkge1xuICAgIG9iID0gbmV3IE9ic2VydmVyKHZhbHVlKTtcbiAgfVxuICBpZiAoYXNSb290RGF0YSAmJiBvYikge1xuICAgIG9iLnZtQ291bnQrKztcbiAgfVxuICByZXR1cm4gb2Jcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSByZWFjdGl2ZSBwcm9wZXJ0eSBvbiBhbiBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGRlZmluZVJlYWN0aXZlJCQxIChcbiAgb2JqLFxuICBrZXksXG4gIHZhbCxcbiAgY3VzdG9tU2V0dGVyLFxuICBzaGFsbG93XG4pIHtcbiAgdmFyIGRlcCA9IG5ldyBEZXAoKTtcblxuICB2YXIgcHJvcGVydHkgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcbiAgaWYgKHByb3BlcnR5ICYmIHByb3BlcnR5LmNvbmZpZ3VyYWJsZSA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIGNhdGVyIGZvciBwcmUtZGVmaW5lZCBnZXR0ZXIvc2V0dGVyc1xuICB2YXIgZ2V0dGVyID0gcHJvcGVydHkgJiYgcHJvcGVydHkuZ2V0O1xuICB2YXIgc2V0dGVyID0gcHJvcGVydHkgJiYgcHJvcGVydHkuc2V0O1xuICBpZiAoKCFnZXR0ZXIgfHwgc2V0dGVyKSAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgdmFsID0gb2JqW2tleV07XG4gIH1cblxuICB2YXIgY2hpbGRPYiA9ICFzaGFsbG93ICYmIG9ic2VydmUodmFsKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiByZWFjdGl2ZUdldHRlciAoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXR0ZXIgPyBnZXR0ZXIuY2FsbChvYmopIDogdmFsO1xuICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgZGVwLmRlcGVuZCgpO1xuICAgICAgICBpZiAoY2hpbGRPYikge1xuICAgICAgICAgIGNoaWxkT2IuZGVwLmRlcGVuZCgpO1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgZGVwZW5kQXJyYXkodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHJlYWN0aXZlU2V0dGVyIChuZXdWYWwpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldHRlciA/IGdldHRlci5jYWxsKG9iaikgOiB2YWw7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1zZWxmLWNvbXBhcmUgKi9cbiAgICAgIGlmIChuZXdWYWwgPT09IHZhbHVlIHx8IChuZXdWYWwgIT09IG5ld1ZhbCAmJiB2YWx1ZSAhPT0gdmFsdWUpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1zZWxmLWNvbXBhcmUgKi9cbiAgICAgIGlmIChjdXN0b21TZXR0ZXIpIHtcbiAgICAgICAgY3VzdG9tU2V0dGVyKCk7XG4gICAgICB9XG4gICAgICAvLyAjNzk4MTogZm9yIGFjY2Vzc29yIHByb3BlcnRpZXMgd2l0aG91dCBzZXR0ZXJcbiAgICAgIGlmIChnZXR0ZXIgJiYgIXNldHRlcikgeyByZXR1cm4gfVxuICAgICAgaWYgKHNldHRlcikge1xuICAgICAgICBzZXR0ZXIuY2FsbChvYmosIG5ld1ZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWwgPSBuZXdWYWw7XG4gICAgICB9XG4gICAgICBjaGlsZE9iID0gIXNoYWxsb3cgJiYgb2JzZXJ2ZShuZXdWYWwpO1xuICAgICAgZGVwLm5vdGlmeSgpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogU2V0IGEgcHJvcGVydHkgb24gYW4gb2JqZWN0LiBBZGRzIHRoZSBuZXcgcHJvcGVydHkgYW5kXG4gKiB0cmlnZ2VycyBjaGFuZ2Ugbm90aWZpY2F0aW9uIGlmIHRoZSBwcm9wZXJ0eSBkb2Vzbid0XG4gKiBhbHJlYWR5IGV4aXN0LlxuICovXG5mdW5jdGlvbiBzZXQgKHRhcmdldCwga2V5LCB2YWwpIHtcbiAgaWYgKGlzVW5kZWYodGFyZ2V0KSB8fCBpc1ByaW1pdGl2ZSh0YXJnZXQpXG4gICkge1xuICAgIHdhcm4oKFwiQ2Fubm90IHNldCByZWFjdGl2ZSBwcm9wZXJ0eSBvbiB1bmRlZmluZWQsIG51bGwsIG9yIHByaW1pdGl2ZSB2YWx1ZTogXCIgKyAoKHRhcmdldCkpKSk7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkodGFyZ2V0KSAmJiBpc1ZhbGlkQXJyYXlJbmRleChrZXkpKSB7XG4gICAgdGFyZ2V0Lmxlbmd0aCA9IE1hdGgubWF4KHRhcmdldC5sZW5ndGgsIGtleSk7XG4gICAgdGFyZ2V0LnNwbGljZShrZXksIDEsIHZhbCk7XG4gICAgcmV0dXJuIHZhbFxuICB9XG4gIGlmIChrZXkgaW4gdGFyZ2V0ICYmICEoa2V5IGluIE9iamVjdC5wcm90b3R5cGUpKSB7XG4gICAgdGFyZ2V0W2tleV0gPSB2YWw7XG4gICAgcmV0dXJuIHZhbFxuICB9XG4gIHZhciBvYiA9ICh0YXJnZXQpLl9fb2JfXztcbiAgaWYgKHRhcmdldC5faXNWdWUgfHwgKG9iICYmIG9iLnZtQ291bnQpKSB7XG4gICAgd2FybihcbiAgICAgICdBdm9pZCBhZGRpbmcgcmVhY3RpdmUgcHJvcGVydGllcyB0byBhIFZ1ZSBpbnN0YW5jZSBvciBpdHMgcm9vdCAkZGF0YSAnICtcbiAgICAgICdhdCBydW50aW1lIC0gZGVjbGFyZSBpdCB1cGZyb250IGluIHRoZSBkYXRhIG9wdGlvbi4nXG4gICAgKTtcbiAgICByZXR1cm4gdmFsXG4gIH1cbiAgaWYgKCFvYikge1xuICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgIHJldHVybiB2YWxcbiAgfVxuICBkZWZpbmVSZWFjdGl2ZSQkMShvYi52YWx1ZSwga2V5LCB2YWwpO1xuICBvYi5kZXAubm90aWZ5KCk7XG4gIHJldHVybiB2YWxcbn1cblxuLyoqXG4gKiBEZWxldGUgYSBwcm9wZXJ0eSBhbmQgdHJpZ2dlciBjaGFuZ2UgaWYgbmVjZXNzYXJ5LlxuICovXG5mdW5jdGlvbiBkZWwgKHRhcmdldCwga2V5KSB7XG4gIGlmIChpc1VuZGVmKHRhcmdldCkgfHwgaXNQcmltaXRpdmUodGFyZ2V0KVxuICApIHtcbiAgICB3YXJuKChcIkNhbm5vdCBkZWxldGUgcmVhY3RpdmUgcHJvcGVydHkgb24gdW5kZWZpbmVkLCBudWxsLCBvciBwcmltaXRpdmUgdmFsdWU6IFwiICsgKCh0YXJnZXQpKSkpO1xuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkgJiYgaXNWYWxpZEFycmF5SW5kZXgoa2V5KSkge1xuICAgIHRhcmdldC5zcGxpY2Uoa2V5LCAxKTtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb2IgPSAodGFyZ2V0KS5fX29iX187XG4gIGlmICh0YXJnZXQuX2lzVnVlIHx8IChvYiAmJiBvYi52bUNvdW50KSkge1xuICAgIHdhcm4oXG4gICAgICAnQXZvaWQgZGVsZXRpbmcgcHJvcGVydGllcyBvbiBhIFZ1ZSBpbnN0YW5jZSBvciBpdHMgcm9vdCAkZGF0YSAnICtcbiAgICAgICctIGp1c3Qgc2V0IGl0IHRvIG51bGwuJ1xuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKCFoYXNPd24odGFyZ2V0LCBrZXkpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgZGVsZXRlIHRhcmdldFtrZXldO1xuICBpZiAoIW9iKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgb2IuZGVwLm5vdGlmeSgpO1xufVxuXG4vKipcbiAqIENvbGxlY3QgZGVwZW5kZW5jaWVzIG9uIGFycmF5IGVsZW1lbnRzIHdoZW4gdGhlIGFycmF5IGlzIHRvdWNoZWQsIHNpbmNlXG4gKiB3ZSBjYW5ub3QgaW50ZXJjZXB0IGFycmF5IGVsZW1lbnQgYWNjZXNzIGxpa2UgcHJvcGVydHkgZ2V0dGVycy5cbiAqL1xuZnVuY3Rpb24gZGVwZW5kQXJyYXkgKHZhbHVlKSB7XG4gIGZvciAodmFyIGUgPSAodm9pZCAwKSwgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBlID0gdmFsdWVbaV07XG4gICAgZSAmJiBlLl9fb2JfXyAmJiBlLl9fb2JfXy5kZXAuZGVwZW5kKCk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZSkpIHtcbiAgICAgIGRlcGVuZEFycmF5KGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBPcHRpb24gb3ZlcndyaXRpbmcgc3RyYXRlZ2llcyBhcmUgZnVuY3Rpb25zIHRoYXQgaGFuZGxlXG4gKiBob3cgdG8gbWVyZ2UgYSBwYXJlbnQgb3B0aW9uIHZhbHVlIGFuZCBhIGNoaWxkIG9wdGlvblxuICogdmFsdWUgaW50byB0aGUgZmluYWwgdmFsdWUuXG4gKi9cbnZhciBzdHJhdHMgPSBjb25maWcub3B0aW9uTWVyZ2VTdHJhdGVnaWVzO1xuXG4vKipcbiAqIE9wdGlvbnMgd2l0aCByZXN0cmljdGlvbnNcbiAqL1xue1xuICBzdHJhdHMuZWwgPSBzdHJhdHMucHJvcHNEYXRhID0gZnVuY3Rpb24gKHBhcmVudCwgY2hpbGQsIHZtLCBrZXkpIHtcbiAgICBpZiAoIXZtKSB7XG4gICAgICB3YXJuKFxuICAgICAgICBcIm9wdGlvbiBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgY2FuIG9ubHkgYmUgdXNlZCBkdXJpbmcgaW5zdGFuY2UgXCIgK1xuICAgICAgICAnY3JlYXRpb24gd2l0aCB0aGUgYG5ld2Aga2V5d29yZC4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdFN0cmF0KHBhcmVudCwgY2hpbGQpXG4gIH07XG59XG5cbi8qKlxuICogSGVscGVyIHRoYXQgcmVjdXJzaXZlbHkgbWVyZ2VzIHR3byBkYXRhIG9iamVjdHMgdG9nZXRoZXIuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YSAodG8sIGZyb20pIHtcbiAgaWYgKCFmcm9tKSB7IHJldHVybiB0byB9XG4gIHZhciBrZXksIHRvVmFsLCBmcm9tVmFsO1xuXG4gIHZhciBrZXlzID0gaGFzU3ltYm9sXG4gICAgPyBSZWZsZWN0Lm93bktleXMoZnJvbSlcbiAgICA6IE9iamVjdC5rZXlzKGZyb20pO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGtleSA9IGtleXNbaV07XG4gICAgLy8gaW4gY2FzZSB0aGUgb2JqZWN0IGlzIGFscmVhZHkgb2JzZXJ2ZWQuLi5cbiAgICBpZiAoa2V5ID09PSAnX19vYl9fJykgeyBjb250aW51ZSB9XG4gICAgdG9WYWwgPSB0b1trZXldO1xuICAgIGZyb21WYWwgPSBmcm9tW2tleV07XG4gICAgaWYgKCFoYXNPd24odG8sIGtleSkpIHtcbiAgICAgIHNldCh0bywga2V5LCBmcm9tVmFsKTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdG9WYWwgIT09IGZyb21WYWwgJiZcbiAgICAgIGlzUGxhaW5PYmplY3QodG9WYWwpICYmXG4gICAgICBpc1BsYWluT2JqZWN0KGZyb21WYWwpXG4gICAgKSB7XG4gICAgICBtZXJnZURhdGEodG9WYWwsIGZyb21WYWwpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdG9cbn1cblxuLyoqXG4gKiBEYXRhXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YU9yRm4gKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsLFxuICB2bVxuKSB7XG4gIGlmICghdm0pIHtcbiAgICAvLyBpbiBhIFZ1ZS5leHRlbmQgbWVyZ2UsIGJvdGggc2hvdWxkIGJlIGZ1bmN0aW9uc1xuICAgIGlmICghY2hpbGRWYWwpIHtcbiAgICAgIHJldHVybiBwYXJlbnRWYWxcbiAgICB9XG4gICAgaWYgKCFwYXJlbnRWYWwpIHtcbiAgICAgIHJldHVybiBjaGlsZFZhbFxuICAgIH1cbiAgICAvLyB3aGVuIHBhcmVudFZhbCAmIGNoaWxkVmFsIGFyZSBib3RoIHByZXNlbnQsXG4gICAgLy8gd2UgbmVlZCB0byByZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlXG4gICAgLy8gbWVyZ2VkIHJlc3VsdCBvZiBib3RoIGZ1bmN0aW9ucy4uLiBubyBuZWVkIHRvXG4gICAgLy8gY2hlY2sgaWYgcGFyZW50VmFsIGlzIGEgZnVuY3Rpb24gaGVyZSBiZWNhdXNlXG4gICAgLy8gaXQgaGFzIHRvIGJlIGEgZnVuY3Rpb24gdG8gcGFzcyBwcmV2aW91cyBtZXJnZXMuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG1lcmdlZERhdGFGbiAoKSB7XG4gICAgICByZXR1cm4gbWVyZ2VEYXRhKFxuICAgICAgICB0eXBlb2YgY2hpbGRWYWwgPT09ICdmdW5jdGlvbicgPyBjaGlsZFZhbC5jYWxsKHRoaXMsIHRoaXMpIDogY2hpbGRWYWwsXG4gICAgICAgIHR5cGVvZiBwYXJlbnRWYWwgPT09ICdmdW5jdGlvbicgPyBwYXJlbnRWYWwuY2FsbCh0aGlzLCB0aGlzKSA6IHBhcmVudFZhbFxuICAgICAgKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gbWVyZ2VkSW5zdGFuY2VEYXRhRm4gKCkge1xuICAgICAgLy8gaW5zdGFuY2UgbWVyZ2VcbiAgICAgIHZhciBpbnN0YW5jZURhdGEgPSB0eXBlb2YgY2hpbGRWYWwgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBjaGlsZFZhbC5jYWxsKHZtLCB2bSlcbiAgICAgICAgOiBjaGlsZFZhbDtcbiAgICAgIHZhciBkZWZhdWx0RGF0YSA9IHR5cGVvZiBwYXJlbnRWYWwgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBwYXJlbnRWYWwuY2FsbCh2bSwgdm0pXG4gICAgICAgIDogcGFyZW50VmFsO1xuICAgICAgaWYgKGluc3RhbmNlRGF0YSkge1xuICAgICAgICByZXR1cm4gbWVyZ2VEYXRhKGluc3RhbmNlRGF0YSwgZGVmYXVsdERhdGEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZGVmYXVsdERhdGFcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuc3RyYXRzLmRhdGEgPSBmdW5jdGlvbiAoXG4gIHBhcmVudFZhbCxcbiAgY2hpbGRWYWwsXG4gIHZtXG4pIHtcbiAgaWYgKCF2bSkge1xuICAgIGlmIChjaGlsZFZhbCAmJiB0eXBlb2YgY2hpbGRWYWwgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICdUaGUgXCJkYXRhXCIgb3B0aW9uIHNob3VsZCBiZSBhIGZ1bmN0aW9uICcgK1xuICAgICAgICAndGhhdCByZXR1cm5zIGEgcGVyLWluc3RhbmNlIHZhbHVlIGluIGNvbXBvbmVudCAnICtcbiAgICAgICAgJ2RlZmluaXRpb25zLicsXG4gICAgICAgIHZtXG4gICAgICApO1xuXG4gICAgICByZXR1cm4gcGFyZW50VmFsXG4gICAgfVxuICAgIHJldHVybiBtZXJnZURhdGFPckZuKHBhcmVudFZhbCwgY2hpbGRWYWwpXG4gIH1cblxuICByZXR1cm4gbWVyZ2VEYXRhT3JGbihwYXJlbnRWYWwsIGNoaWxkVmFsLCB2bSlcbn07XG5cbi8qKlxuICogSG9va3MgYW5kIHByb3BzIGFyZSBtZXJnZWQgYXMgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBtZXJnZUhvb2sgKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsXG4pIHtcbiAgdmFyIHJlcyA9IGNoaWxkVmFsXG4gICAgPyBwYXJlbnRWYWxcbiAgICAgID8gcGFyZW50VmFsLmNvbmNhdChjaGlsZFZhbClcbiAgICAgIDogQXJyYXkuaXNBcnJheShjaGlsZFZhbClcbiAgICAgICAgPyBjaGlsZFZhbFxuICAgICAgICA6IFtjaGlsZFZhbF1cbiAgICA6IHBhcmVudFZhbDtcbiAgcmV0dXJuIHJlc1xuICAgID8gZGVkdXBlSG9va3MocmVzKVxuICAgIDogcmVzXG59XG5cbmZ1bmN0aW9uIGRlZHVwZUhvb2tzIChob29rcykge1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaG9va3MubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAocmVzLmluZGV4T2YoaG9va3NbaV0pID09PSAtMSkge1xuICAgICAgcmVzLnB1c2goaG9va3NbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkxJRkVDWUNMRV9IT09LUy5mb3JFYWNoKGZ1bmN0aW9uIChob29rKSB7XG4gIHN0cmF0c1tob29rXSA9IG1lcmdlSG9vaztcbn0pO1xuXG4vKipcbiAqIEFzc2V0c1xuICpcbiAqIFdoZW4gYSB2bSBpcyBwcmVzZW50IChpbnN0YW5jZSBjcmVhdGlvbiksIHdlIG5lZWQgdG8gZG9cbiAqIGEgdGhyZWUtd2F5IG1lcmdlIGJldHdlZW4gY29uc3RydWN0b3Igb3B0aW9ucywgaW5zdGFuY2VcbiAqIG9wdGlvbnMgYW5kIHBhcmVudCBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBtZXJnZUFzc2V0cyAoXG4gIHBhcmVudFZhbCxcbiAgY2hpbGRWYWwsXG4gIHZtLFxuICBrZXlcbikge1xuICB2YXIgcmVzID0gT2JqZWN0LmNyZWF0ZShwYXJlbnRWYWwgfHwgbnVsbCk7XG4gIGlmIChjaGlsZFZhbCkge1xuICAgIGFzc2VydE9iamVjdFR5cGUoa2V5LCBjaGlsZFZhbCwgdm0pO1xuICAgIHJldHVybiBleHRlbmQocmVzLCBjaGlsZFZhbClcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVzXG4gIH1cbn1cblxuQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICBzdHJhdHNbdHlwZSArICdzJ10gPSBtZXJnZUFzc2V0cztcbn0pO1xuXG4vKipcbiAqIFdhdGNoZXJzLlxuICpcbiAqIFdhdGNoZXJzIGhhc2hlcyBzaG91bGQgbm90IG92ZXJ3cml0ZSBvbmVcbiAqIGFub3RoZXIsIHNvIHdlIG1lcmdlIHRoZW0gYXMgYXJyYXlzLlxuICovXG5zdHJhdHMud2F0Y2ggPSBmdW5jdGlvbiAoXG4gIHBhcmVudFZhbCxcbiAgY2hpbGRWYWwsXG4gIHZtLFxuICBrZXlcbikge1xuICAvLyB3b3JrIGFyb3VuZCBGaXJlZm94J3MgT2JqZWN0LnByb3RvdHlwZS53YXRjaC4uLlxuICBpZiAocGFyZW50VmFsID09PSBuYXRpdmVXYXRjaCkgeyBwYXJlbnRWYWwgPSB1bmRlZmluZWQ7IH1cbiAgaWYgKGNoaWxkVmFsID09PSBuYXRpdmVXYXRjaCkgeyBjaGlsZFZhbCA9IHVuZGVmaW5lZDsgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCFjaGlsZFZhbCkgeyByZXR1cm4gT2JqZWN0LmNyZWF0ZShwYXJlbnRWYWwgfHwgbnVsbCkgfVxuICB7XG4gICAgYXNzZXJ0T2JqZWN0VHlwZShrZXksIGNoaWxkVmFsLCB2bSk7XG4gIH1cbiAgaWYgKCFwYXJlbnRWYWwpIHsgcmV0dXJuIGNoaWxkVmFsIH1cbiAgdmFyIHJldCA9IHt9O1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBmb3IgKHZhciBrZXkkMSBpbiBjaGlsZFZhbCkge1xuICAgIHZhciBwYXJlbnQgPSByZXRba2V5JDFdO1xuICAgIHZhciBjaGlsZCA9IGNoaWxkVmFsW2tleSQxXTtcbiAgICBpZiAocGFyZW50ICYmICFBcnJheS5pc0FycmF5KHBhcmVudCkpIHtcbiAgICAgIHBhcmVudCA9IFtwYXJlbnRdO1xuICAgIH1cbiAgICByZXRba2V5JDFdID0gcGFyZW50XG4gICAgICA/IHBhcmVudC5jb25jYXQoY2hpbGQpXG4gICAgICA6IEFycmF5LmlzQXJyYXkoY2hpbGQpID8gY2hpbGQgOiBbY2hpbGRdO1xuICB9XG4gIHJldHVybiByZXRcbn07XG5cbi8qKlxuICogT3RoZXIgb2JqZWN0IGhhc2hlcy5cbiAqL1xuc3RyYXRzLnByb3BzID1cbnN0cmF0cy5tZXRob2RzID1cbnN0cmF0cy5pbmplY3QgPVxuc3RyYXRzLmNvbXB1dGVkID0gZnVuY3Rpb24gKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsLFxuICB2bSxcbiAga2V5XG4pIHtcbiAgaWYgKGNoaWxkVmFsICYmIFwiZGV2ZWxvcG1lbnRcIiAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgYXNzZXJ0T2JqZWN0VHlwZShrZXksIGNoaWxkVmFsLCB2bSk7XG4gIH1cbiAgaWYgKCFwYXJlbnRWYWwpIHsgcmV0dXJuIGNoaWxkVmFsIH1cbiAgdmFyIHJldCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIGV4dGVuZChyZXQsIHBhcmVudFZhbCk7XG4gIGlmIChjaGlsZFZhbCkgeyBleHRlbmQocmV0LCBjaGlsZFZhbCk7IH1cbiAgcmV0dXJuIHJldFxufTtcbnN0cmF0cy5wcm92aWRlID0gbWVyZ2VEYXRhT3JGbjtcblxuLyoqXG4gKiBEZWZhdWx0IHN0cmF0ZWd5LlxuICovXG52YXIgZGVmYXVsdFN0cmF0ID0gZnVuY3Rpb24gKHBhcmVudFZhbCwgY2hpbGRWYWwpIHtcbiAgcmV0dXJuIGNoaWxkVmFsID09PSB1bmRlZmluZWRcbiAgICA/IHBhcmVudFZhbFxuICAgIDogY2hpbGRWYWxcbn07XG5cbi8qKlxuICogVmFsaWRhdGUgY29tcG9uZW50IG5hbWVzXG4gKi9cbmZ1bmN0aW9uIGNoZWNrQ29tcG9uZW50cyAob3B0aW9ucykge1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucy5jb21wb25lbnRzKSB7XG4gICAgdmFsaWRhdGVDb21wb25lbnROYW1lKGtleSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVDb21wb25lbnROYW1lIChuYW1lKSB7XG4gIGlmICghbmV3IFJlZ0V4cCgoXCJeW2EtekEtWl1bXFxcXC1cXFxcLjAtOV9cIiArICh1bmljb2RlUmVnRXhwLnNvdXJjZSkgKyBcIl0qJFwiKSkudGVzdChuYW1lKSkge1xuICAgIHdhcm4oXG4gICAgICAnSW52YWxpZCBjb21wb25lbnQgbmFtZTogXCInICsgbmFtZSArICdcIi4gQ29tcG9uZW50IG5hbWVzICcgK1xuICAgICAgJ3Nob3VsZCBjb25mb3JtIHRvIHZhbGlkIGN1c3RvbSBlbGVtZW50IG5hbWUgaW4gaHRtbDUgc3BlY2lmaWNhdGlvbi4nXG4gICAgKTtcbiAgfVxuICBpZiAoaXNCdWlsdEluVGFnKG5hbWUpIHx8IGNvbmZpZy5pc1Jlc2VydmVkVGFnKG5hbWUpKSB7XG4gICAgd2FybihcbiAgICAgICdEbyBub3QgdXNlIGJ1aWx0LWluIG9yIHJlc2VydmVkIEhUTUwgZWxlbWVudHMgYXMgY29tcG9uZW50ICcgK1xuICAgICAgJ2lkOiAnICsgbmFtZVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBFbnN1cmUgYWxsIHByb3BzIG9wdGlvbiBzeW50YXggYXJlIG5vcm1hbGl6ZWQgaW50byB0aGVcbiAqIE9iamVjdC1iYXNlZCBmb3JtYXQuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzIChvcHRpb25zLCB2bSkge1xuICB2YXIgcHJvcHMgPSBvcHRpb25zLnByb3BzO1xuICBpZiAoIXByb3BzKSB7IHJldHVybiB9XG4gIHZhciByZXMgPSB7fTtcbiAgdmFyIGksIHZhbCwgbmFtZTtcbiAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgaSA9IHByb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB2YWwgPSBwcm9wc1tpXTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgICAgICBuYW1lID0gY2FtZWxpemUodmFsKTtcbiAgICAgICAgcmVzW25hbWVdID0geyB0eXBlOiBudWxsIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3YXJuKCdwcm9wcyBtdXN0IGJlIHN0cmluZ3Mgd2hlbiB1c2luZyBhcnJheSBzeW50YXguJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QocHJvcHMpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgICB2YWwgPSBwcm9wc1trZXldO1xuICAgICAgbmFtZSA9IGNhbWVsaXplKGtleSk7XG4gICAgICByZXNbbmFtZV0gPSBpc1BsYWluT2JqZWN0KHZhbClcbiAgICAgICAgPyB2YWxcbiAgICAgICAgOiB7IHR5cGU6IHZhbCB9O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB3YXJuKFxuICAgICAgXCJJbnZhbGlkIHZhbHVlIGZvciBvcHRpb24gXFxcInByb3BzXFxcIjogZXhwZWN0ZWQgYW4gQXJyYXkgb3IgYW4gT2JqZWN0LCBcIiArXG4gICAgICBcImJ1dCBnb3QgXCIgKyAodG9SYXdUeXBlKHByb3BzKSkgKyBcIi5cIixcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxuICBvcHRpb25zLnByb3BzID0gcmVzO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBhbGwgaW5qZWN0aW9ucyBpbnRvIE9iamVjdC1iYXNlZCBmb3JtYXRcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplSW5qZWN0IChvcHRpb25zLCB2bSkge1xuICB2YXIgaW5qZWN0ID0gb3B0aW9ucy5pbmplY3Q7XG4gIGlmICghaW5qZWN0KSB7IHJldHVybiB9XG4gIHZhciBub3JtYWxpemVkID0gb3B0aW9ucy5pbmplY3QgPSB7fTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoaW5qZWN0KSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5qZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBub3JtYWxpemVkW2luamVjdFtpXV0gPSB7IGZyb206IGluamVjdFtpXSB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KGluamVjdCkpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gaW5qZWN0KSB7XG4gICAgICB2YXIgdmFsID0gaW5qZWN0W2tleV07XG4gICAgICBub3JtYWxpemVkW2tleV0gPSBpc1BsYWluT2JqZWN0KHZhbClcbiAgICAgICAgPyBleHRlbmQoeyBmcm9tOiBrZXkgfSwgdmFsKVxuICAgICAgICA6IHsgZnJvbTogdmFsIH07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHdhcm4oXG4gICAgICBcIkludmFsaWQgdmFsdWUgZm9yIG9wdGlvbiBcXFwiaW5qZWN0XFxcIjogZXhwZWN0ZWQgYW4gQXJyYXkgb3IgYW4gT2JqZWN0LCBcIiArXG4gICAgICBcImJ1dCBnb3QgXCIgKyAodG9SYXdUeXBlKGluamVjdCkpICsgXCIuXCIsXG4gICAgICB2bVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgcmF3IGZ1bmN0aW9uIGRpcmVjdGl2ZXMgaW50byBvYmplY3QgZm9ybWF0LlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVEaXJlY3RpdmVzIChvcHRpb25zKSB7XG4gIHZhciBkaXJzID0gb3B0aW9ucy5kaXJlY3RpdmVzO1xuICBpZiAoZGlycykge1xuICAgIGZvciAodmFyIGtleSBpbiBkaXJzKSB7XG4gICAgICB2YXIgZGVmJCQxID0gZGlyc1trZXldO1xuICAgICAgaWYgKHR5cGVvZiBkZWYkJDEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZGlyc1trZXldID0geyBiaW5kOiBkZWYkJDEsIHVwZGF0ZTogZGVmJCQxIH07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydE9iamVjdFR5cGUgKG5hbWUsIHZhbHVlLCB2bSkge1xuICBpZiAoIWlzUGxhaW5PYmplY3QodmFsdWUpKSB7XG4gICAgd2FybihcbiAgICAgIFwiSW52YWxpZCB2YWx1ZSBmb3Igb3B0aW9uIFxcXCJcIiArIG5hbWUgKyBcIlxcXCI6IGV4cGVjdGVkIGFuIE9iamVjdCwgXCIgK1xuICAgICAgXCJidXQgZ290IFwiICsgKHRvUmF3VHlwZSh2YWx1ZSkpICsgXCIuXCIsXG4gICAgICB2bVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBNZXJnZSB0d28gb3B0aW9uIG9iamVjdHMgaW50byBhIG5ldyBvbmUuXG4gKiBDb3JlIHV0aWxpdHkgdXNlZCBpbiBib3RoIGluc3RhbnRpYXRpb24gYW5kIGluaGVyaXRhbmNlLlxuICovXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnMgKFxuICBwYXJlbnQsXG4gIGNoaWxkLFxuICB2bVxuKSB7XG4gIHtcbiAgICBjaGVja0NvbXBvbmVudHMoY2hpbGQpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBjaGlsZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNoaWxkID0gY2hpbGQub3B0aW9ucztcbiAgfVxuXG4gIG5vcm1hbGl6ZVByb3BzKGNoaWxkLCB2bSk7XG4gIG5vcm1hbGl6ZUluamVjdChjaGlsZCwgdm0pO1xuICBub3JtYWxpemVEaXJlY3RpdmVzKGNoaWxkKTtcblxuICAvLyBBcHBseSBleHRlbmRzIGFuZCBtaXhpbnMgb24gdGhlIGNoaWxkIG9wdGlvbnMsXG4gIC8vIGJ1dCBvbmx5IGlmIGl0IGlzIGEgcmF3IG9wdGlvbnMgb2JqZWN0IHRoYXQgaXNuJ3RcbiAgLy8gdGhlIHJlc3VsdCBvZiBhbm90aGVyIG1lcmdlT3B0aW9ucyBjYWxsLlxuICAvLyBPbmx5IG1lcmdlZCBvcHRpb25zIGhhcyB0aGUgX2Jhc2UgcHJvcGVydHkuXG4gIGlmICghY2hpbGQuX2Jhc2UpIHtcbiAgICBpZiAoY2hpbGQuZXh0ZW5kcykge1xuICAgICAgcGFyZW50ID0gbWVyZ2VPcHRpb25zKHBhcmVudCwgY2hpbGQuZXh0ZW5kcywgdm0pO1xuICAgIH1cbiAgICBpZiAoY2hpbGQubWl4aW5zKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNoaWxkLm1peGlucy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgcGFyZW50ID0gbWVyZ2VPcHRpb25zKHBhcmVudCwgY2hpbGQubWl4aW5zW2ldLCB2bSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9wdGlvbnMgPSB7fTtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gcGFyZW50KSB7XG4gICAgbWVyZ2VGaWVsZChrZXkpO1xuICB9XG4gIGZvciAoa2V5IGluIGNoaWxkKSB7XG4gICAgaWYgKCFoYXNPd24ocGFyZW50LCBrZXkpKSB7XG4gICAgICBtZXJnZUZpZWxkKGtleSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIG1lcmdlRmllbGQgKGtleSkge1xuICAgIHZhciBzdHJhdCA9IHN0cmF0c1trZXldIHx8IGRlZmF1bHRTdHJhdDtcbiAgICBvcHRpb25zW2tleV0gPSBzdHJhdChwYXJlbnRba2V5XSwgY2hpbGRba2V5XSwgdm0sIGtleSk7XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFuIGFzc2V0LlxuICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJlY2F1c2UgY2hpbGQgaW5zdGFuY2VzIG5lZWQgYWNjZXNzXG4gKiB0byBhc3NldHMgZGVmaW5lZCBpbiBpdHMgYW5jZXN0b3IgY2hhaW4uXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVBc3NldCAoXG4gIG9wdGlvbnMsXG4gIHR5cGUsXG4gIGlkLFxuICB3YXJuTWlzc2luZ1xuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodHlwZW9mIGlkICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBhc3NldHMgPSBvcHRpb25zW3R5cGVdO1xuICAvLyBjaGVjayBsb2NhbCByZWdpc3RyYXRpb24gdmFyaWF0aW9ucyBmaXJzdFxuICBpZiAoaGFzT3duKGFzc2V0cywgaWQpKSB7IHJldHVybiBhc3NldHNbaWRdIH1cbiAgdmFyIGNhbWVsaXplZElkID0gY2FtZWxpemUoaWQpO1xuICBpZiAoaGFzT3duKGFzc2V0cywgY2FtZWxpemVkSWQpKSB7IHJldHVybiBhc3NldHNbY2FtZWxpemVkSWRdIH1cbiAgdmFyIFBhc2NhbENhc2VJZCA9IGNhcGl0YWxpemUoY2FtZWxpemVkSWQpO1xuICBpZiAoaGFzT3duKGFzc2V0cywgUGFzY2FsQ2FzZUlkKSkgeyByZXR1cm4gYXNzZXRzW1Bhc2NhbENhc2VJZF0gfVxuICAvLyBmYWxsYmFjayB0byBwcm90b3R5cGUgY2hhaW5cbiAgdmFyIHJlcyA9IGFzc2V0c1tpZF0gfHwgYXNzZXRzW2NhbWVsaXplZElkXSB8fCBhc3NldHNbUGFzY2FsQ2FzZUlkXTtcbiAgaWYgKHdhcm5NaXNzaW5nICYmICFyZXMpIHtcbiAgICB3YXJuKFxuICAgICAgJ0ZhaWxlZCB0byByZXNvbHZlICcgKyB0eXBlLnNsaWNlKDAsIC0xKSArICc6ICcgKyBpZCxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuICB9XG4gIHJldHVybiByZXNcbn1cblxuLyogICovXG5cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3AgKFxuICBrZXksXG4gIHByb3BPcHRpb25zLFxuICBwcm9wc0RhdGEsXG4gIHZtXG4pIHtcbiAgdmFyIHByb3AgPSBwcm9wT3B0aW9uc1trZXldO1xuICB2YXIgYWJzZW50ID0gIWhhc093bihwcm9wc0RhdGEsIGtleSk7XG4gIHZhciB2YWx1ZSA9IHByb3BzRGF0YVtrZXldO1xuICAvLyBib29sZWFuIGNhc3RpbmdcbiAgdmFyIGJvb2xlYW5JbmRleCA9IGdldFR5cGVJbmRleChCb29sZWFuLCBwcm9wLnR5cGUpO1xuICBpZiAoYm9vbGVhbkluZGV4ID4gLTEpIHtcbiAgICBpZiAoYWJzZW50ICYmICFoYXNPd24ocHJvcCwgJ2RlZmF1bHQnKSkge1xuICAgICAgdmFsdWUgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnJyB8fCB2YWx1ZSA9PT0gaHlwaGVuYXRlKGtleSkpIHtcbiAgICAgIC8vIG9ubHkgY2FzdCBlbXB0eSBzdHJpbmcgLyBzYW1lIG5hbWUgdG8gYm9vbGVhbiBpZlxuICAgICAgLy8gYm9vbGVhbiBoYXMgaGlnaGVyIHByaW9yaXR5XG4gICAgICB2YXIgc3RyaW5nSW5kZXggPSBnZXRUeXBlSW5kZXgoU3RyaW5nLCBwcm9wLnR5cGUpO1xuICAgICAgaWYgKHN0cmluZ0luZGV4IDwgMCB8fCBib29sZWFuSW5kZXggPCBzdHJpbmdJbmRleCkge1xuICAgICAgICB2YWx1ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIGNoZWNrIGRlZmF1bHQgdmFsdWVcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICB2YWx1ZSA9IGdldFByb3BEZWZhdWx0VmFsdWUodm0sIHByb3AsIGtleSk7XG4gICAgLy8gc2luY2UgdGhlIGRlZmF1bHQgdmFsdWUgaXMgYSBmcmVzaCBjb3B5LFxuICAgIC8vIG1ha2Ugc3VyZSB0byBvYnNlcnZlIGl0LlxuICAgIHZhciBwcmV2U2hvdWxkT2JzZXJ2ZSA9IHNob3VsZE9ic2VydmU7XG4gICAgdG9nZ2xlT2JzZXJ2aW5nKHRydWUpO1xuICAgIG9ic2VydmUodmFsdWUpO1xuICAgIHRvZ2dsZU9ic2VydmluZyhwcmV2U2hvdWxkT2JzZXJ2ZSk7XG4gIH1cbiAge1xuICAgIGFzc2VydFByb3AocHJvcCwga2V5LCB2YWx1ZSwgdm0sIGFic2VudCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IHZhbHVlIG9mIGEgcHJvcC5cbiAqL1xuZnVuY3Rpb24gZ2V0UHJvcERlZmF1bHRWYWx1ZSAodm0sIHByb3AsIGtleSkge1xuICAvLyBubyBkZWZhdWx0LCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmICghaGFzT3duKHByb3AsICdkZWZhdWx0JykpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgdmFyIGRlZiA9IHByb3AuZGVmYXVsdDtcbiAgLy8gd2FybiBhZ2FpbnN0IG5vbi1mYWN0b3J5IGRlZmF1bHRzIGZvciBPYmplY3QgJiBBcnJheVxuICBpZiAoaXNPYmplY3QoZGVmKSkge1xuICAgIHdhcm4oXG4gICAgICAnSW52YWxpZCBkZWZhdWx0IHZhbHVlIGZvciBwcm9wIFwiJyArIGtleSArICdcIjogJyArXG4gICAgICAnUHJvcHMgd2l0aCB0eXBlIE9iamVjdC9BcnJheSBtdXN0IHVzZSBhIGZhY3RvcnkgZnVuY3Rpb24gJyArXG4gICAgICAndG8gcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLicsXG4gICAgICB2bVxuICAgICk7XG4gIH1cbiAgLy8gdGhlIHJhdyBwcm9wIHZhbHVlIHdhcyBhbHNvIHVuZGVmaW5lZCBmcm9tIHByZXZpb3VzIHJlbmRlcixcbiAgLy8gcmV0dXJuIHByZXZpb3VzIGRlZmF1bHQgdmFsdWUgdG8gYXZvaWQgdW5uZWNlc3Nhcnkgd2F0Y2hlciB0cmlnZ2VyXG4gIGlmICh2bSAmJiB2bS4kb3B0aW9ucy5wcm9wc0RhdGEgJiZcbiAgICB2bS4kb3B0aW9ucy5wcm9wc0RhdGFba2V5XSA9PT0gdW5kZWZpbmVkICYmXG4gICAgdm0uX3Byb3BzW2tleV0gIT09IHVuZGVmaW5lZFxuICApIHtcbiAgICByZXR1cm4gdm0uX3Byb3BzW2tleV1cbiAgfVxuICAvLyBjYWxsIGZhY3RvcnkgZnVuY3Rpb24gZm9yIG5vbi1GdW5jdGlvbiB0eXBlc1xuICAvLyBhIHZhbHVlIGlzIEZ1bmN0aW9uIGlmIGl0cyBwcm90b3R5cGUgaXMgZnVuY3Rpb24gZXZlbiBhY3Jvc3MgZGlmZmVyZW50IGV4ZWN1dGlvbiBjb250ZXh0XG4gIHJldHVybiB0eXBlb2YgZGVmID09PSAnZnVuY3Rpb24nICYmIGdldFR5cGUocHJvcC50eXBlKSAhPT0gJ0Z1bmN0aW9uJ1xuICAgID8gZGVmLmNhbGwodm0pXG4gICAgOiBkZWZcbn1cblxuLyoqXG4gKiBBc3NlcnQgd2hldGhlciBhIHByb3AgaXMgdmFsaWQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydFByb3AgKFxuICBwcm9wLFxuICBuYW1lLFxuICB2YWx1ZSxcbiAgdm0sXG4gIGFic2VudFxuKSB7XG4gIGlmIChwcm9wLnJlcXVpcmVkICYmIGFic2VudCkge1xuICAgIHdhcm4oXG4gICAgICAnTWlzc2luZyByZXF1aXJlZCBwcm9wOiBcIicgKyBuYW1lICsgJ1wiJyxcbiAgICAgIHZtXG4gICAgKTtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAodmFsdWUgPT0gbnVsbCAmJiAhcHJvcC5yZXF1aXJlZCkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciB0eXBlID0gcHJvcC50eXBlO1xuICB2YXIgdmFsaWQgPSAhdHlwZSB8fCB0eXBlID09PSB0cnVlO1xuICB2YXIgZXhwZWN0ZWRUeXBlcyA9IFtdO1xuICBpZiAodHlwZSkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0eXBlKSkge1xuICAgICAgdHlwZSA9IFt0eXBlXTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlLmxlbmd0aCAmJiAhdmFsaWQ7IGkrKykge1xuICAgICAgdmFyIGFzc2VydGVkVHlwZSA9IGFzc2VydFR5cGUodmFsdWUsIHR5cGVbaV0pO1xuICAgICAgZXhwZWN0ZWRUeXBlcy5wdXNoKGFzc2VydGVkVHlwZS5leHBlY3RlZFR5cGUgfHwgJycpO1xuICAgICAgdmFsaWQgPSBhc3NlcnRlZFR5cGUudmFsaWQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF2YWxpZCkge1xuICAgIHdhcm4oXG4gICAgICBnZXRJbnZhbGlkVHlwZU1lc3NhZ2UobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpLFxuICAgICAgdm1cbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIHZhciB2YWxpZGF0b3IgPSBwcm9wLnZhbGlkYXRvcjtcbiAgaWYgKHZhbGlkYXRvcikge1xuICAgIGlmICghdmFsaWRhdG9yKHZhbHVlKSkge1xuICAgICAgd2FybihcbiAgICAgICAgJ0ludmFsaWQgcHJvcDogY3VzdG9tIHZhbGlkYXRvciBjaGVjayBmYWlsZWQgZm9yIHByb3AgXCInICsgbmFtZSArICdcIi4nLFxuICAgICAgICB2bVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHNpbXBsZUNoZWNrUkUgPSAvXihTdHJpbmd8TnVtYmVyfEJvb2xlYW58RnVuY3Rpb258U3ltYm9sKSQvO1xuXG5mdW5jdGlvbiBhc3NlcnRUeXBlICh2YWx1ZSwgdHlwZSkge1xuICB2YXIgdmFsaWQ7XG4gIHZhciBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpO1xuICBpZiAoc2ltcGxlQ2hlY2tSRS50ZXN0KGV4cGVjdGVkVHlwZSkpIHtcbiAgICB2YXIgdCA9IHR5cGVvZiB2YWx1ZTtcbiAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIC8vIGZvciBwcmltaXRpdmUgd3JhcHBlciBvYmplY3RzXG4gICAgaWYgKCF2YWxpZCAmJiB0ID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XG4gICAgfVxuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ09iamVjdCcpIHtcbiAgICB2YWxpZCA9IGlzUGxhaW5PYmplY3QodmFsdWUpO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ0FycmF5Jykge1xuICAgIHZhbGlkID0gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogdmFsaWQsXG4gICAgZXhwZWN0ZWRUeXBlOiBleHBlY3RlZFR5cGVcbiAgfVxufVxuXG4vKipcbiAqIFVzZSBmdW5jdGlvbiBzdHJpbmcgbmFtZSB0byBjaGVjayBidWlsdC1pbiB0eXBlcyxcbiAqIGJlY2F1c2UgYSBzaW1wbGUgZXF1YWxpdHkgY2hlY2sgd2lsbCBmYWlsIHdoZW4gcnVubmluZ1xuICogYWNyb3NzIGRpZmZlcmVudCB2bXMgLyBpZnJhbWVzLlxuICovXG5mdW5jdGlvbiBnZXRUeXBlIChmbikge1xuICB2YXIgbWF0Y2ggPSBmbiAmJiBmbi50b1N0cmluZygpLm1hdGNoKC9eXFxzKmZ1bmN0aW9uIChcXHcrKS8pO1xuICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6ICcnXG59XG5cbmZ1bmN0aW9uIGlzU2FtZVR5cGUgKGEsIGIpIHtcbiAgcmV0dXJuIGdldFR5cGUoYSkgPT09IGdldFR5cGUoYilcbn1cblxuZnVuY3Rpb24gZ2V0VHlwZUluZGV4ICh0eXBlLCBleHBlY3RlZFR5cGVzKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShleHBlY3RlZFR5cGVzKSkge1xuICAgIHJldHVybiBpc1NhbWVUeXBlKGV4cGVjdGVkVHlwZXMsIHR5cGUpID8gMCA6IC0xXG4gIH1cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGV4cGVjdGVkVHlwZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoaXNTYW1lVHlwZShleHBlY3RlZFR5cGVzW2ldLCB0eXBlKSkge1xuICAgICAgcmV0dXJuIGlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbmZ1bmN0aW9uIGdldEludmFsaWRUeXBlTWVzc2FnZSAobmFtZSwgdmFsdWUsIGV4cGVjdGVkVHlwZXMpIHtcbiAgdmFyIG1lc3NhZ2UgPSBcIkludmFsaWQgcHJvcDogdHlwZSBjaGVjayBmYWlsZWQgZm9yIHByb3AgXFxcIlwiICsgbmFtZSArIFwiXFxcIi5cIiArXG4gICAgXCIgRXhwZWN0ZWQgXCIgKyAoZXhwZWN0ZWRUeXBlcy5tYXAoY2FwaXRhbGl6ZSkuam9pbignLCAnKSk7XG4gIHZhciBleHBlY3RlZFR5cGUgPSBleHBlY3RlZFR5cGVzWzBdO1xuICB2YXIgcmVjZWl2ZWRUeXBlID0gdG9SYXdUeXBlKHZhbHVlKTtcbiAgdmFyIGV4cGVjdGVkVmFsdWUgPSBzdHlsZVZhbHVlKHZhbHVlLCBleHBlY3RlZFR5cGUpO1xuICB2YXIgcmVjZWl2ZWRWYWx1ZSA9IHN0eWxlVmFsdWUodmFsdWUsIHJlY2VpdmVkVHlwZSk7XG4gIC8vIGNoZWNrIGlmIHdlIG5lZWQgdG8gc3BlY2lmeSBleHBlY3RlZCB2YWx1ZVxuICBpZiAoZXhwZWN0ZWRUeXBlcy5sZW5ndGggPT09IDEgJiZcbiAgICAgIGlzRXhwbGljYWJsZShleHBlY3RlZFR5cGUpICYmXG4gICAgICAhaXNCb29sZWFuKGV4cGVjdGVkVHlwZSwgcmVjZWl2ZWRUeXBlKSkge1xuICAgIG1lc3NhZ2UgKz0gXCIgd2l0aCB2YWx1ZSBcIiArIGV4cGVjdGVkVmFsdWU7XG4gIH1cbiAgbWVzc2FnZSArPSBcIiwgZ290IFwiICsgcmVjZWl2ZWRUeXBlICsgXCIgXCI7XG4gIC8vIGNoZWNrIGlmIHdlIG5lZWQgdG8gc3BlY2lmeSByZWNlaXZlZCB2YWx1ZVxuICBpZiAoaXNFeHBsaWNhYmxlKHJlY2VpdmVkVHlwZSkpIHtcbiAgICBtZXNzYWdlICs9IFwid2l0aCB2YWx1ZSBcIiArIHJlY2VpdmVkVmFsdWUgKyBcIi5cIjtcbiAgfVxuICByZXR1cm4gbWVzc2FnZVxufVxuXG5mdW5jdGlvbiBzdHlsZVZhbHVlICh2YWx1ZSwgdHlwZSkge1xuICBpZiAodHlwZSA9PT0gJ1N0cmluZycpIHtcbiAgICByZXR1cm4gKFwiXFxcIlwiICsgdmFsdWUgKyBcIlxcXCJcIilcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnTnVtYmVyJykge1xuICAgIHJldHVybiAoXCJcIiArIChOdW1iZXIodmFsdWUpKSlcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gKFwiXCIgKyB2YWx1ZSlcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0V4cGxpY2FibGUgKHZhbHVlKSB7XG4gIHZhciBleHBsaWNpdFR5cGVzID0gWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXTtcbiAgcmV0dXJuIGV4cGxpY2l0VHlwZXMuc29tZShmdW5jdGlvbiAoZWxlbSkgeyByZXR1cm4gdmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gZWxlbTsgfSlcbn1cblxuZnVuY3Rpb24gaXNCb29sZWFuICgpIHtcbiAgdmFyIGFyZ3MgPSBbXSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgd2hpbGUgKCBsZW4tLSApIGFyZ3NbIGxlbiBdID0gYXJndW1lbnRzWyBsZW4gXTtcblxuICByZXR1cm4gYXJncy5zb21lKGZ1bmN0aW9uIChlbGVtKSB7IHJldHVybiBlbGVtLnRvTG93ZXJDYXNlKCkgPT09ICdib29sZWFuJzsgfSlcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGhhbmRsZUVycm9yIChlcnIsIHZtLCBpbmZvKSB7XG4gIC8vIERlYWN0aXZhdGUgZGVwcyB0cmFja2luZyB3aGlsZSBwcm9jZXNzaW5nIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgcG9zc2libGUgaW5maW5pdGUgcmVuZGVyaW5nLlxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWV4L2lzc3Vlcy8xNTA1XG4gIHB1c2hUYXJnZXQoKTtcbiAgdHJ5IHtcbiAgICBpZiAodm0pIHtcbiAgICAgIHZhciBjdXIgPSB2bTtcbiAgICAgIHdoaWxlICgoY3VyID0gY3VyLiRwYXJlbnQpKSB7XG4gICAgICAgIHZhciBob29rcyA9IGN1ci4kb3B0aW9ucy5lcnJvckNhcHR1cmVkO1xuICAgICAgICBpZiAoaG9va3MpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhvb2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB2YXIgY2FwdHVyZSA9IGhvb2tzW2ldLmNhbGwoY3VyLCBlcnIsIHZtLCBpbmZvKSA9PT0gZmFsc2U7XG4gICAgICAgICAgICAgIGlmIChjYXB0dXJlKSB7IHJldHVybiB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGdsb2JhbEhhbmRsZUVycm9yKGUsIGN1ciwgJ2Vycm9yQ2FwdHVyZWQgaG9vaycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBnbG9iYWxIYW5kbGVFcnJvcihlcnIsIHZtLCBpbmZvKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBwb3BUYXJnZXQoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyAoXG4gIGhhbmRsZXIsXG4gIGNvbnRleHQsXG4gIGFyZ3MsXG4gIHZtLFxuICBpbmZvXG4pIHtcbiAgdmFyIHJlcztcbiAgdHJ5IHtcbiAgICByZXMgPSBhcmdzID8gaGFuZGxlci5hcHBseShjb250ZXh0LCBhcmdzKSA6IGhhbmRsZXIuY2FsbChjb250ZXh0KTtcbiAgICBpZiAocmVzICYmICFyZXMuX2lzVnVlICYmIGlzUHJvbWlzZShyZXMpICYmICFyZXMuX2hhbmRsZWQpIHtcbiAgICAgIHJlcy5jYXRjaChmdW5jdGlvbiAoZSkgeyByZXR1cm4gaGFuZGxlRXJyb3IoZSwgdm0sIGluZm8gKyBcIiAoUHJvbWlzZS9hc3luYylcIik7IH0pO1xuICAgICAgLy8gaXNzdWUgIzk1MTFcbiAgICAgIC8vIGF2b2lkIGNhdGNoIHRyaWdnZXJpbmcgbXVsdGlwbGUgdGltZXMgd2hlbiBuZXN0ZWQgY2FsbHNcbiAgICAgIHJlcy5faGFuZGxlZCA9IHRydWU7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgaGFuZGxlRXJyb3IoZSwgdm0sIGluZm8pO1xuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gZ2xvYmFsSGFuZGxlRXJyb3IgKGVyciwgdm0sIGluZm8pIHtcbiAgaWYgKGNvbmZpZy5lcnJvckhhbmRsZXIpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNvbmZpZy5lcnJvckhhbmRsZXIuY2FsbChudWxsLCBlcnIsIHZtLCBpbmZvKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGlmIHRoZSB1c2VyIGludGVudGlvbmFsbHkgdGhyb3dzIHRoZSBvcmlnaW5hbCBlcnJvciBpbiB0aGUgaGFuZGxlcixcbiAgICAgIC8vIGRvIG5vdCBsb2cgaXQgdHdpY2VcbiAgICAgIGlmIChlICE9PSBlcnIpIHtcbiAgICAgICAgbG9nRXJyb3IoZSwgbnVsbCwgJ2NvbmZpZy5lcnJvckhhbmRsZXInKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgbG9nRXJyb3IoZXJyLCB2bSwgaW5mbyk7XG59XG5cbmZ1bmN0aW9uIGxvZ0Vycm9yIChlcnIsIHZtLCBpbmZvKSB7XG4gIHtcbiAgICB3YXJuKChcIkVycm9yIGluIFwiICsgaW5mbyArIFwiOiBcXFwiXCIgKyAoZXJyLnRvU3RyaW5nKCkpICsgXCJcXFwiXCIpLCB2bSk7XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKChpbkJyb3dzZXIgfHwgaW5XZWV4KSAmJiB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgZXJyXG4gIH1cbn1cblxuLyogICovXG5cbnZhciBpc1VzaW5nTWljcm9UYXNrID0gZmFsc2U7XG5cbnZhciBjYWxsYmFja3MgPSBbXTtcbnZhciBwZW5kaW5nID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGZsdXNoQ2FsbGJhY2tzICgpIHtcbiAgcGVuZGluZyA9IGZhbHNlO1xuICB2YXIgY29waWVzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICBjYWxsYmFja3MubGVuZ3RoID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3BpZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb3BpZXNbaV0oKTtcbiAgfVxufVxuXG4vLyBIZXJlIHdlIGhhdmUgYXN5bmMgZGVmZXJyaW5nIHdyYXBwZXJzIHVzaW5nIG1pY3JvdGFza3MuXG4vLyBJbiAyLjUgd2UgdXNlZCAobWFjcm8pIHRhc2tzIChpbiBjb21iaW5hdGlvbiB3aXRoIG1pY3JvdGFza3MpLlxuLy8gSG93ZXZlciwgaXQgaGFzIHN1YnRsZSBwcm9ibGVtcyB3aGVuIHN0YXRlIGlzIGNoYW5nZWQgcmlnaHQgYmVmb3JlIHJlcGFpbnRcbi8vIChlLmcuICM2ODEzLCBvdXQtaW4gdHJhbnNpdGlvbnMpLlxuLy8gQWxzbywgdXNpbmcgKG1hY3JvKSB0YXNrcyBpbiBldmVudCBoYW5kbGVyIHdvdWxkIGNhdXNlIHNvbWUgd2VpcmQgYmVoYXZpb3JzXG4vLyB0aGF0IGNhbm5vdCBiZSBjaXJjdW12ZW50ZWQgKGUuZy4gIzcxMDksICM3MTUzLCAjNzU0NiwgIzc4MzQsICM4MTA5KS5cbi8vIFNvIHdlIG5vdyB1c2UgbWljcm90YXNrcyBldmVyeXdoZXJlLCBhZ2Fpbi5cbi8vIEEgbWFqb3IgZHJhd2JhY2sgb2YgdGhpcyB0cmFkZW9mZiBpcyB0aGF0IHRoZXJlIGFyZSBzb21lIHNjZW5hcmlvc1xuLy8gd2hlcmUgbWljcm90YXNrcyBoYXZlIHRvbyBoaWdoIGEgcHJpb3JpdHkgYW5kIGZpcmUgaW4gYmV0d2VlbiBzdXBwb3NlZGx5XG4vLyBzZXF1ZW50aWFsIGV2ZW50cyAoZS5nLiAjNDUyMSwgIzY2OTAsIHdoaWNoIGhhdmUgd29ya2Fyb3VuZHMpXG4vLyBvciBldmVuIGJldHdlZW4gYnViYmxpbmcgb2YgdGhlIHNhbWUgZXZlbnQgKCM2NTY2KS5cbnZhciB0aW1lckZ1bmM7XG5cbi8vIFRoZSBuZXh0VGljayBiZWhhdmlvciBsZXZlcmFnZXMgdGhlIG1pY3JvdGFzayBxdWV1ZSwgd2hpY2ggY2FuIGJlIGFjY2Vzc2VkXG4vLyB2aWEgZWl0aGVyIG5hdGl2ZSBQcm9taXNlLnRoZW4gb3IgTXV0YXRpb25PYnNlcnZlci5cbi8vIE11dGF0aW9uT2JzZXJ2ZXIgaGFzIHdpZGVyIHN1cHBvcnQsIGhvd2V2ZXIgaXQgaXMgc2VyaW91c2x5IGJ1Z2dlZCBpblxuLy8gVUlXZWJWaWV3IGluIGlPUyA+PSA5LjMuMyB3aGVuIHRyaWdnZXJlZCBpbiB0b3VjaCBldmVudCBoYW5kbGVycy4gSXRcbi8vIGNvbXBsZXRlbHkgc3RvcHMgd29ya2luZyBhZnRlciB0cmlnZ2VyaW5nIGEgZmV3IHRpbWVzLi4uIHNvLCBpZiBuYXRpdmVcbi8vIFByb21pc2UgaXMgYXZhaWxhYmxlLCB3ZSB3aWxsIHVzZSBpdDpcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0LCAkZmxvdy1kaXNhYmxlLWxpbmUgKi9cbmlmICh0eXBlb2YgUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNOYXRpdmUoUHJvbWlzZSkpIHtcbiAgdmFyIHAgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgdGltZXJGdW5jID0gZnVuY3Rpb24gKCkge1xuICAgIHAudGhlbihmbHVzaENhbGxiYWNrcyk7XG4gICAgLy8gSW4gcHJvYmxlbWF0aWMgVUlXZWJWaWV3cywgUHJvbWlzZS50aGVuIGRvZXNuJ3QgY29tcGxldGVseSBicmVhaywgYnV0XG4gICAgLy8gaXQgY2FuIGdldCBzdHVjayBpbiBhIHdlaXJkIHN0YXRlIHdoZXJlIGNhbGxiYWNrcyBhcmUgcHVzaGVkIGludG8gdGhlXG4gICAgLy8gbWljcm90YXNrIHF1ZXVlIGJ1dCB0aGUgcXVldWUgaXNuJ3QgYmVpbmcgZmx1c2hlZCwgdW50aWwgdGhlIGJyb3dzZXJcbiAgICAvLyBuZWVkcyB0byBkbyBzb21lIG90aGVyIHdvcmssIGUuZy4gaGFuZGxlIGEgdGltZXIuIFRoZXJlZm9yZSB3ZSBjYW5cbiAgICAvLyBcImZvcmNlXCIgdGhlIG1pY3JvdGFzayBxdWV1ZSB0byBiZSBmbHVzaGVkIGJ5IGFkZGluZyBhbiBlbXB0eSB0aW1lci5cbiAgICBpZiAoaXNJT1MpIHsgc2V0VGltZW91dChub29wKTsgfVxuICB9O1xuICBpc1VzaW5nTWljcm9UYXNrID0gdHJ1ZTtcbn0gZWxzZSBpZiAoIWlzSUUgJiYgdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgIT09ICd1bmRlZmluZWQnICYmIChcbiAgaXNOYXRpdmUoTXV0YXRpb25PYnNlcnZlcikgfHxcbiAgLy8gUGhhbnRvbUpTIGFuZCBpT1MgNy54XG4gIE11dGF0aW9uT2JzZXJ2ZXIudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgTXV0YXRpb25PYnNlcnZlckNvbnN0cnVjdG9yXSdcbikpIHtcbiAgLy8gVXNlIE11dGF0aW9uT2JzZXJ2ZXIgd2hlcmUgbmF0aXZlIFByb21pc2UgaXMgbm90IGF2YWlsYWJsZSxcbiAgLy8gZS5nLiBQaGFudG9tSlMsIGlPUzcsIEFuZHJvaWQgNC40XG4gIC8vICgjNjQ2NiBNdXRhdGlvbk9ic2VydmVyIGlzIHVucmVsaWFibGUgaW4gSUUxMSlcbiAgdmFyIGNvdW50ZXIgPSAxO1xuICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmbHVzaENhbGxiYWNrcyk7XG4gIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFN0cmluZyhjb3VudGVyKSk7XG4gIG9ic2VydmVyLm9ic2VydmUodGV4dE5vZGUsIHtcbiAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlXG4gIH0pO1xuICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgY291bnRlciA9IChjb3VudGVyICsgMSkgJSAyO1xuICAgIHRleHROb2RlLmRhdGEgPSBTdHJpbmcoY291bnRlcik7XG4gIH07XG4gIGlzVXNpbmdNaWNyb1Rhc2sgPSB0cnVlO1xufSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSAndW5kZWZpbmVkJyAmJiBpc05hdGl2ZShzZXRJbW1lZGlhdGUpKSB7XG4gIC8vIEZhbGxiYWNrIHRvIHNldEltbWVkaWF0ZS5cbiAgLy8gVGVjaG5pY2FsbHkgaXQgbGV2ZXJhZ2VzIHRoZSAobWFjcm8pIHRhc2sgcXVldWUsXG4gIC8vIGJ1dCBpdCBpcyBzdGlsbCBhIGJldHRlciBjaG9pY2UgdGhhbiBzZXRUaW1lb3V0LlxuICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgc2V0SW1tZWRpYXRlKGZsdXNoQ2FsbGJhY2tzKTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIEZhbGxiYWNrIHRvIHNldFRpbWVvdXQuXG4gIHRpbWVyRnVuYyA9IGZ1bmN0aW9uICgpIHtcbiAgICBzZXRUaW1lb3V0KGZsdXNoQ2FsbGJhY2tzLCAwKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbmV4dFRpY2sgKGNiLCBjdHgpIHtcbiAgdmFyIF9yZXNvbHZlO1xuICBjYWxsYmFja3MucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjYi5jYWxsKGN0eCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGhhbmRsZUVycm9yKGUsIGN0eCwgJ25leHRUaWNrJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChfcmVzb2x2ZSkge1xuICAgICAgX3Jlc29sdmUoY3R4KTtcbiAgICB9XG4gIH0pO1xuICBpZiAoIXBlbmRpbmcpIHtcbiAgICBwZW5kaW5nID0gdHJ1ZTtcbiAgICB0aW1lckZ1bmMoKTtcbiAgfVxuICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgaWYgKCFjYiAmJiB0eXBlb2YgUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIF9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB9KVxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgbWFyaztcbnZhciBtZWFzdXJlO1xuXG57XG4gIHZhciBwZXJmID0gaW5Ccm93c2VyICYmIHdpbmRvdy5wZXJmb3JtYW5jZTtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChcbiAgICBwZXJmICYmXG4gICAgcGVyZi5tYXJrICYmXG4gICAgcGVyZi5tZWFzdXJlICYmXG4gICAgcGVyZi5jbGVhck1hcmtzICYmXG4gICAgcGVyZi5jbGVhck1lYXN1cmVzXG4gICkge1xuICAgIG1hcmsgPSBmdW5jdGlvbiAodGFnKSB7IHJldHVybiBwZXJmLm1hcmsodGFnKTsgfTtcbiAgICBtZWFzdXJlID0gZnVuY3Rpb24gKG5hbWUsIHN0YXJ0VGFnLCBlbmRUYWcpIHtcbiAgICAgIHBlcmYubWVhc3VyZShuYW1lLCBzdGFydFRhZywgZW5kVGFnKTtcbiAgICAgIHBlcmYuY2xlYXJNYXJrcyhzdGFydFRhZyk7XG4gICAgICBwZXJmLmNsZWFyTWFya3MoZW5kVGFnKTtcbiAgICAgIC8vIHBlcmYuY2xlYXJNZWFzdXJlcyhuYW1lKVxuICAgIH07XG4gIH1cbn1cblxuLyogbm90IHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgZmxvdyBkb2Vzbid0IHBsYXkgd2VsbCB3aXRoIFByb3h5ICovXG5cbnZhciBpbml0UHJveHk7XG5cbntcbiAgdmFyIGFsbG93ZWRHbG9iYWxzID0gbWFrZU1hcChcbiAgICAnSW5maW5pdHksdW5kZWZpbmVkLE5hTixpc0Zpbml0ZSxpc05hTiwnICtcbiAgICAncGFyc2VGbG9hdCxwYXJzZUludCxkZWNvZGVVUkksZGVjb2RlVVJJQ29tcG9uZW50LGVuY29kZVVSSSxlbmNvZGVVUklDb21wb25lbnQsJyArXG4gICAgJ01hdGgsTnVtYmVyLERhdGUsQXJyYXksT2JqZWN0LEJvb2xlYW4sU3RyaW5nLFJlZ0V4cCxNYXAsU2V0LEpTT04sSW50bCwnICtcbiAgICAncmVxdWlyZScgLy8gZm9yIFdlYnBhY2svQnJvd3NlcmlmeVxuICApO1xuXG4gIHZhciB3YXJuTm9uUHJlc2VudCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHdhcm4oXG4gICAgICBcIlByb3BlcnR5IG9yIG1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgbm90IGRlZmluZWQgb24gdGhlIGluc3RhbmNlIGJ1dCBcIiArXG4gICAgICAncmVmZXJlbmNlZCBkdXJpbmcgcmVuZGVyLiBNYWtlIHN1cmUgdGhhdCB0aGlzIHByb3BlcnR5IGlzIHJlYWN0aXZlLCAnICtcbiAgICAgICdlaXRoZXIgaW4gdGhlIGRhdGEgb3B0aW9uLCBvciBmb3IgY2xhc3MtYmFzZWQgY29tcG9uZW50cywgYnkgJyArXG4gICAgICAnaW5pdGlhbGl6aW5nIHRoZSBwcm9wZXJ0eS4gJyArXG4gICAgICAnU2VlOiBodHRwczovL3Z1ZWpzLm9yZy92Mi9ndWlkZS9yZWFjdGl2aXR5Lmh0bWwjRGVjbGFyaW5nLVJlYWN0aXZlLVByb3BlcnRpZXMuJyxcbiAgICAgIHRhcmdldFxuICAgICk7XG4gIH07XG5cbiAgdmFyIHdhcm5SZXNlcnZlZFByZWZpeCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHdhcm4oXG4gICAgICBcIlByb3BlcnR5IFxcXCJcIiArIGtleSArIFwiXFxcIiBtdXN0IGJlIGFjY2Vzc2VkIHdpdGggXFxcIiRkYXRhLlwiICsga2V5ICsgXCJcXFwiIGJlY2F1c2UgXCIgK1xuICAgICAgJ3Byb3BlcnRpZXMgc3RhcnRpbmcgd2l0aCBcIiRcIiBvciBcIl9cIiBhcmUgbm90IHByb3hpZWQgaW4gdGhlIFZ1ZSBpbnN0YW5jZSB0byAnICtcbiAgICAgICdwcmV2ZW50IGNvbmZsaWN0cyB3aXRoIFZ1ZSBpbnRlcm5hbHMuICcgK1xuICAgICAgJ1NlZTogaHR0cHM6Ly92dWVqcy5vcmcvdjIvYXBpLyNkYXRhJyxcbiAgICAgIHRhcmdldFxuICAgICk7XG4gIH07XG5cbiAgdmFyIGhhc1Byb3h5ID1cbiAgICB0eXBlb2YgUHJveHkgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFByb3h5KTtcblxuICBpZiAoaGFzUHJveHkpIHtcbiAgICB2YXIgaXNCdWlsdEluTW9kaWZpZXIgPSBtYWtlTWFwKCdzdG9wLHByZXZlbnQsc2VsZixjdHJsLHNoaWZ0LGFsdCxtZXRhLGV4YWN0Jyk7XG4gICAgY29uZmlnLmtleUNvZGVzID0gbmV3IFByb3h5KGNvbmZpZy5rZXlDb2Rlcywge1xuICAgICAgc2V0OiBmdW5jdGlvbiBzZXQgKHRhcmdldCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoaXNCdWlsdEluTW9kaWZpZXIoa2V5KSkge1xuICAgICAgICAgIHdhcm4oKFwiQXZvaWQgb3ZlcndyaXRpbmcgYnVpbHQtaW4gbW9kaWZpZXIgaW4gY29uZmlnLmtleUNvZGVzOiAuXCIgKyBrZXkpKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHZhbHVlO1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHZhciBoYXNIYW5kbGVyID0ge1xuICAgIGhhczogZnVuY3Rpb24gaGFzICh0YXJnZXQsIGtleSkge1xuICAgICAgdmFyIGhhcyA9IGtleSBpbiB0YXJnZXQ7XG4gICAgICB2YXIgaXNBbGxvd2VkID0gYWxsb3dlZEdsb2JhbHMoa2V5KSB8fFxuICAgICAgICAodHlwZW9mIGtleSA9PT0gJ3N0cmluZycgJiYga2V5LmNoYXJBdCgwKSA9PT0gJ18nICYmICEoa2V5IGluIHRhcmdldC4kZGF0YSkpO1xuICAgICAgaWYgKCFoYXMgJiYgIWlzQWxsb3dlZCkge1xuICAgICAgICBpZiAoa2V5IGluIHRhcmdldC4kZGF0YSkgeyB3YXJuUmVzZXJ2ZWRQcmVmaXgodGFyZ2V0LCBrZXkpOyB9XG4gICAgICAgIGVsc2UgeyB3YXJuTm9uUHJlc2VudCh0YXJnZXQsIGtleSk7IH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXMgfHwgIWlzQWxsb3dlZFxuICAgIH1cbiAgfTtcblxuICB2YXIgZ2V0SGFuZGxlciA9IHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCAodGFyZ2V0LCBrZXkpIHtcbiAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyAmJiAhKGtleSBpbiB0YXJnZXQpKSB7XG4gICAgICAgIGlmIChrZXkgaW4gdGFyZ2V0LiRkYXRhKSB7IHdhcm5SZXNlcnZlZFByZWZpeCh0YXJnZXQsIGtleSk7IH1cbiAgICAgICAgZWxzZSB7IHdhcm5Ob25QcmVzZW50KHRhcmdldCwga2V5KTsgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRhcmdldFtrZXldXG4gICAgfVxuICB9O1xuXG4gIGluaXRQcm94eSA9IGZ1bmN0aW9uIGluaXRQcm94eSAodm0pIHtcbiAgICBpZiAoaGFzUHJveHkpIHtcbiAgICAgIC8vIGRldGVybWluZSB3aGljaCBwcm94eSBoYW5kbGVyIHRvIHVzZVxuICAgICAgdmFyIG9wdGlvbnMgPSB2bS4kb3B0aW9ucztcbiAgICAgIHZhciBoYW5kbGVycyA9IG9wdGlvbnMucmVuZGVyICYmIG9wdGlvbnMucmVuZGVyLl93aXRoU3RyaXBwZWRcbiAgICAgICAgPyBnZXRIYW5kbGVyXG4gICAgICAgIDogaGFzSGFuZGxlcjtcbiAgICAgIHZtLl9yZW5kZXJQcm94eSA9IG5ldyBQcm94eSh2bSwgaGFuZGxlcnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bS5fcmVuZGVyUHJveHkgPSB2bTtcbiAgICB9XG4gIH07XG59XG5cbi8qICAqL1xuXG52YXIgc2Vlbk9iamVjdHMgPSBuZXcgX1NldCgpO1xuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIGFuIG9iamVjdCB0byBldm9rZSBhbGwgY29udmVydGVkXG4gKiBnZXR0ZXJzLCBzbyB0aGF0IGV2ZXJ5IG5lc3RlZCBwcm9wZXJ0eSBpbnNpZGUgdGhlIG9iamVjdFxuICogaXMgY29sbGVjdGVkIGFzIGEgXCJkZWVwXCIgZGVwZW5kZW5jeS5cbiAqL1xuZnVuY3Rpb24gdHJhdmVyc2UgKHZhbCkge1xuICBfdHJhdmVyc2UodmFsLCBzZWVuT2JqZWN0cyk7XG4gIHNlZW5PYmplY3RzLmNsZWFyKCk7XG59XG5cbmZ1bmN0aW9uIF90cmF2ZXJzZSAodmFsLCBzZWVuKSB7XG4gIHZhciBpLCBrZXlzO1xuICB2YXIgaXNBID0gQXJyYXkuaXNBcnJheSh2YWwpO1xuICBpZiAoKCFpc0EgJiYgIWlzT2JqZWN0KHZhbCkpIHx8IE9iamVjdC5pc0Zyb3plbih2YWwpIHx8IHZhbCBpbnN0YW5jZW9mIFZOb2RlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHZhbC5fX29iX18pIHtcbiAgICB2YXIgZGVwSWQgPSB2YWwuX19vYl9fLmRlcC5pZDtcbiAgICBpZiAoc2Vlbi5oYXMoZGVwSWQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgc2Vlbi5hZGQoZGVwSWQpO1xuICB9XG4gIGlmIChpc0EpIHtcbiAgICBpID0gdmFsLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7IF90cmF2ZXJzZSh2YWxbaV0sIHNlZW4pOyB9XG4gIH0gZWxzZSB7XG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgaSA9IGtleXMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHsgX3RyYXZlcnNlKHZhbFtrZXlzW2ldXSwgc2Vlbik7IH1cbiAgfVxufVxuXG4vKiAgKi9cblxudmFyIG5vcm1hbGl6ZUV2ZW50ID0gY2FjaGVkKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBwYXNzaXZlID0gbmFtZS5jaGFyQXQoMCkgPT09ICcmJztcbiAgbmFtZSA9IHBhc3NpdmUgPyBuYW1lLnNsaWNlKDEpIDogbmFtZTtcbiAgdmFyIG9uY2UkJDEgPSBuYW1lLmNoYXJBdCgwKSA9PT0gJ34nOyAvLyBQcmVmaXhlZCBsYXN0LCBjaGVja2VkIGZpcnN0XG4gIG5hbWUgPSBvbmNlJCQxID8gbmFtZS5zbGljZSgxKSA6IG5hbWU7XG4gIHZhciBjYXB0dXJlID0gbmFtZS5jaGFyQXQoMCkgPT09ICchJztcbiAgbmFtZSA9IGNhcHR1cmUgPyBuYW1lLnNsaWNlKDEpIDogbmFtZTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBuYW1lLFxuICAgIG9uY2U6IG9uY2UkJDEsXG4gICAgY2FwdHVyZTogY2FwdHVyZSxcbiAgICBwYXNzaXZlOiBwYXNzaXZlXG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVGbkludm9rZXIgKGZucywgdm0pIHtcbiAgZnVuY3Rpb24gaW52b2tlciAoKSB7XG4gICAgdmFyIGFyZ3VtZW50cyQxID0gYXJndW1lbnRzO1xuXG4gICAgdmFyIGZucyA9IGludm9rZXIuZm5zO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGZucykpIHtcbiAgICAgIHZhciBjbG9uZWQgPSBmbnMuc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2xvbmVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGludm9rZVdpdGhFcnJvckhhbmRsaW5nKGNsb25lZFtpXSwgbnVsbCwgYXJndW1lbnRzJDEsIHZtLCBcInYtb24gaGFuZGxlclwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcmV0dXJuIGhhbmRsZXIgcmV0dXJuIHZhbHVlIGZvciBzaW5nbGUgaGFuZGxlcnNcbiAgICAgIHJldHVybiBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyhmbnMsIG51bGwsIGFyZ3VtZW50cywgdm0sIFwidi1vbiBoYW5kbGVyXCIpXG4gICAgfVxuICB9XG4gIGludm9rZXIuZm5zID0gZm5zO1xuICByZXR1cm4gaW52b2tlclxufVxuXG5mdW5jdGlvbiB1cGRhdGVMaXN0ZW5lcnMgKFxuICBvbixcbiAgb2xkT24sXG4gIGFkZCxcbiAgcmVtb3ZlJCQxLFxuICBjcmVhdGVPbmNlSGFuZGxlcixcbiAgdm1cbikge1xuICB2YXIgbmFtZSwgZGVmJCQxLCBjdXIsIG9sZCwgZXZlbnQ7XG4gIGZvciAobmFtZSBpbiBvbikge1xuICAgIGRlZiQkMSA9IGN1ciA9IG9uW25hbWVdO1xuICAgIG9sZCA9IG9sZE9uW25hbWVdO1xuICAgIGV2ZW50ID0gbm9ybWFsaXplRXZlbnQobmFtZSk7XG4gICAgaWYgKGlzVW5kZWYoY3VyKSkge1xuICAgICAgd2FybihcbiAgICAgICAgXCJJbnZhbGlkIGhhbmRsZXIgZm9yIGV2ZW50IFxcXCJcIiArIChldmVudC5uYW1lKSArIFwiXFxcIjogZ290IFwiICsgU3RyaW5nKGN1ciksXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaXNVbmRlZihvbGQpKSB7XG4gICAgICBpZiAoaXNVbmRlZihjdXIuZm5zKSkge1xuICAgICAgICBjdXIgPSBvbltuYW1lXSA9IGNyZWF0ZUZuSW52b2tlcihjdXIsIHZtKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1RydWUoZXZlbnQub25jZSkpIHtcbiAgICAgICAgY3VyID0gb25bbmFtZV0gPSBjcmVhdGVPbmNlSGFuZGxlcihldmVudC5uYW1lLCBjdXIsIGV2ZW50LmNhcHR1cmUpO1xuICAgICAgfVxuICAgICAgYWRkKGV2ZW50Lm5hbWUsIGN1ciwgZXZlbnQuY2FwdHVyZSwgZXZlbnQucGFzc2l2ZSwgZXZlbnQucGFyYW1zKTtcbiAgICB9IGVsc2UgaWYgKGN1ciAhPT0gb2xkKSB7XG4gICAgICBvbGQuZm5zID0gY3VyO1xuICAgICAgb25bbmFtZV0gPSBvbGQ7XG4gICAgfVxuICB9XG4gIGZvciAobmFtZSBpbiBvbGRPbikge1xuICAgIGlmIChpc1VuZGVmKG9uW25hbWVdKSkge1xuICAgICAgZXZlbnQgPSBub3JtYWxpemVFdmVudChuYW1lKTtcbiAgICAgIHJlbW92ZSQkMShldmVudC5uYW1lLCBvbGRPbltuYW1lXSwgZXZlbnQuY2FwdHVyZSk7XG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBtZXJnZVZOb2RlSG9vayAoZGVmLCBob29rS2V5LCBob29rKSB7XG4gIGlmIChkZWYgaW5zdGFuY2VvZiBWTm9kZSkge1xuICAgIGRlZiA9IGRlZi5kYXRhLmhvb2sgfHwgKGRlZi5kYXRhLmhvb2sgPSB7fSk7XG4gIH1cbiAgdmFyIGludm9rZXI7XG4gIHZhciBvbGRIb29rID0gZGVmW2hvb2tLZXldO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZWRIb29rICgpIHtcbiAgICBob29rLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgLy8gaW1wb3J0YW50OiByZW1vdmUgbWVyZ2VkIGhvb2sgdG8gZW5zdXJlIGl0J3MgY2FsbGVkIG9ubHkgb25jZVxuICAgIC8vIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrXG4gICAgcmVtb3ZlKGludm9rZXIuZm5zLCB3cmFwcGVkSG9vayk7XG4gIH1cblxuICBpZiAoaXNVbmRlZihvbGRIb29rKSkge1xuICAgIC8vIG5vIGV4aXN0aW5nIGhvb2tcbiAgICBpbnZva2VyID0gY3JlYXRlRm5JbnZva2VyKFt3cmFwcGVkSG9va10pO1xuICB9IGVsc2Uge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChpc0RlZihvbGRIb29rLmZucykgJiYgaXNUcnVlKG9sZEhvb2subWVyZ2VkKSkge1xuICAgICAgLy8gYWxyZWFkeSBhIG1lcmdlZCBpbnZva2VyXG4gICAgICBpbnZva2VyID0gb2xkSG9vaztcbiAgICAgIGludm9rZXIuZm5zLnB1c2god3JhcHBlZEhvb2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBleGlzdGluZyBwbGFpbiBob29rXG4gICAgICBpbnZva2VyID0gY3JlYXRlRm5JbnZva2VyKFtvbGRIb29rLCB3cmFwcGVkSG9va10pO1xuICAgIH1cbiAgfVxuXG4gIGludm9rZXIubWVyZ2VkID0gdHJ1ZTtcbiAgZGVmW2hvb2tLZXldID0gaW52b2tlcjtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGV4dHJhY3RQcm9wc0Zyb21WTm9kZURhdGEgKFxuICBkYXRhLFxuICBDdG9yLFxuICB0YWdcbikge1xuICAvLyB3ZSBhcmUgb25seSBleHRyYWN0aW5nIHJhdyB2YWx1ZXMgaGVyZS5cbiAgLy8gdmFsaWRhdGlvbiBhbmQgZGVmYXVsdCB2YWx1ZXMgYXJlIGhhbmRsZWQgaW4gdGhlIGNoaWxkXG4gIC8vIGNvbXBvbmVudCBpdHNlbGYuXG4gIHZhciBwcm9wT3B0aW9ucyA9IEN0b3Iub3B0aW9ucy5wcm9wcztcbiAgaWYgKGlzVW5kZWYocHJvcE9wdGlvbnMpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHJlcyA9IHt9O1xuICB2YXIgYXR0cnMgPSBkYXRhLmF0dHJzO1xuICB2YXIgcHJvcHMgPSBkYXRhLnByb3BzO1xuICBpZiAoaXNEZWYoYXR0cnMpIHx8IGlzRGVmKHByb3BzKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBwcm9wT3B0aW9ucykge1xuICAgICAgdmFyIGFsdEtleSA9IGh5cGhlbmF0ZShrZXkpO1xuICAgICAge1xuICAgICAgICB2YXIga2V5SW5Mb3dlckNhc2UgPSBrZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGtleSAhPT0ga2V5SW5Mb3dlckNhc2UgJiZcbiAgICAgICAgICBhdHRycyAmJiBoYXNPd24oYXR0cnMsIGtleUluTG93ZXJDYXNlKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aXAoXG4gICAgICAgICAgICBcIlByb3AgXFxcIlwiICsga2V5SW5Mb3dlckNhc2UgKyBcIlxcXCIgaXMgcGFzc2VkIHRvIGNvbXBvbmVudCBcIiArXG4gICAgICAgICAgICAoZm9ybWF0Q29tcG9uZW50TmFtZSh0YWcgfHwgQ3RvcikpICsgXCIsIGJ1dCB0aGUgZGVjbGFyZWQgcHJvcCBuYW1lIGlzXCIgK1xuICAgICAgICAgICAgXCIgXFxcIlwiICsga2V5ICsgXCJcXFwiLiBcIiArXG4gICAgICAgICAgICBcIk5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIGNhbWVsQ2FzZWQgXCIgK1xuICAgICAgICAgICAgXCJwcm9wcyBuZWVkIHRvIHVzZSB0aGVpciBrZWJhYi1jYXNlIGVxdWl2YWxlbnRzIHdoZW4gdXNpbmcgaW4tRE9NIFwiICtcbiAgICAgICAgICAgIFwidGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSBcXFwiXCIgKyBhbHRLZXkgKyBcIlxcXCIgaW5zdGVhZCBvZiBcXFwiXCIgKyBrZXkgKyBcIlxcXCIuXCJcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjaGVja1Byb3AocmVzLCBwcm9wcywga2V5LCBhbHRLZXksIHRydWUpIHx8XG4gICAgICBjaGVja1Byb3AocmVzLCBhdHRycywga2V5LCBhbHRLZXksIGZhbHNlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBjaGVja1Byb3AgKFxuICByZXMsXG4gIGhhc2gsXG4gIGtleSxcbiAgYWx0S2V5LFxuICBwcmVzZXJ2ZVxuKSB7XG4gIGlmIChpc0RlZihoYXNoKSkge1xuICAgIGlmIChoYXNPd24oaGFzaCwga2V5KSkge1xuICAgICAgcmVzW2tleV0gPSBoYXNoW2tleV07XG4gICAgICBpZiAoIXByZXNlcnZlKSB7XG4gICAgICAgIGRlbGV0ZSBoYXNoW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gZWxzZSBpZiAoaGFzT3duKGhhc2gsIGFsdEtleSkpIHtcbiAgICAgIHJlc1trZXldID0gaGFzaFthbHRLZXldO1xuICAgICAgaWYgKCFwcmVzZXJ2ZSkge1xuICAgICAgICBkZWxldGUgaGFzaFthbHRLZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qICAqL1xuXG4vLyBUaGUgdGVtcGxhdGUgY29tcGlsZXIgYXR0ZW1wdHMgdG8gbWluaW1pemUgdGhlIG5lZWQgZm9yIG5vcm1hbGl6YXRpb24gYnlcbi8vIHN0YXRpY2FsbHkgYW5hbHl6aW5nIHRoZSB0ZW1wbGF0ZSBhdCBjb21waWxlIHRpbWUuXG4vL1xuLy8gRm9yIHBsYWluIEhUTUwgbWFya3VwLCBub3JtYWxpemF0aW9uIGNhbiBiZSBjb21wbGV0ZWx5IHNraXBwZWQgYmVjYXVzZSB0aGVcbi8vIGdlbmVyYXRlZCByZW5kZXIgZnVuY3Rpb24gaXMgZ3VhcmFudGVlZCB0byByZXR1cm4gQXJyYXk8Vk5vZGU+LiBUaGVyZSBhcmVcbi8vIHR3byBjYXNlcyB3aGVyZSBleHRyYSBub3JtYWxpemF0aW9uIGlzIG5lZWRlZDpcblxuLy8gMS4gV2hlbiB0aGUgY2hpbGRyZW4gY29udGFpbnMgY29tcG9uZW50cyAtIGJlY2F1c2UgYSBmdW5jdGlvbmFsIGNvbXBvbmVudFxuLy8gbWF5IHJldHVybiBhbiBBcnJheSBpbnN0ZWFkIG9mIGEgc2luZ2xlIHJvb3QuIEluIHRoaXMgY2FzZSwganVzdCBhIHNpbXBsZVxuLy8gbm9ybWFsaXphdGlvbiBpcyBuZWVkZWQgLSBpZiBhbnkgY2hpbGQgaXMgYW4gQXJyYXksIHdlIGZsYXR0ZW4gdGhlIHdob2xlXG4vLyB0aGluZyB3aXRoIEFycmF5LnByb3RvdHlwZS5jb25jYXQuIEl0IGlzIGd1YXJhbnRlZWQgdG8gYmUgb25seSAxLWxldmVsIGRlZXBcbi8vIGJlY2F1c2UgZnVuY3Rpb25hbCBjb21wb25lbnRzIGFscmVhZHkgbm9ybWFsaXplIHRoZWlyIG93biBjaGlsZHJlbi5cbmZ1bmN0aW9uIHNpbXBsZU5vcm1hbGl6ZUNoaWxkcmVuIChjaGlsZHJlbikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGRyZW5baV0pKSB7XG4gICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgY2hpbGRyZW4pXG4gICAgfVxuICB9XG4gIHJldHVybiBjaGlsZHJlblxufVxuXG4vLyAyLiBXaGVuIHRoZSBjaGlsZHJlbiBjb250YWlucyBjb25zdHJ1Y3RzIHRoYXQgYWx3YXlzIGdlbmVyYXRlZCBuZXN0ZWQgQXJyYXlzLFxuLy8gZS5nLiA8dGVtcGxhdGU+LCA8c2xvdD4sIHYtZm9yLCBvciB3aGVuIHRoZSBjaGlsZHJlbiBpcyBwcm92aWRlZCBieSB1c2VyXG4vLyB3aXRoIGhhbmQtd3JpdHRlbiByZW5kZXIgZnVuY3Rpb25zIC8gSlNYLiBJbiBzdWNoIGNhc2VzIGEgZnVsbCBub3JtYWxpemF0aW9uXG4vLyBpcyBuZWVkZWQgdG8gY2F0ZXIgdG8gYWxsIHBvc3NpYmxlIHR5cGVzIG9mIGNoaWxkcmVuIHZhbHVlcy5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUNoaWxkcmVuIChjaGlsZHJlbikge1xuICByZXR1cm4gaXNQcmltaXRpdmUoY2hpbGRyZW4pXG4gICAgPyBbY3JlYXRlVGV4dFZOb2RlKGNoaWxkcmVuKV1cbiAgICA6IEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pXG4gICAgICA/IG5vcm1hbGl6ZUFycmF5Q2hpbGRyZW4oY2hpbGRyZW4pXG4gICAgICA6IHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBpc1RleHROb2RlIChub2RlKSB7XG4gIHJldHVybiBpc0RlZihub2RlKSAmJiBpc0RlZihub2RlLnRleHQpICYmIGlzRmFsc2Uobm9kZS5pc0NvbW1lbnQpXG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUFycmF5Q2hpbGRyZW4gKGNoaWxkcmVuLCBuZXN0ZWRJbmRleCkge1xuICB2YXIgcmVzID0gW107XG4gIHZhciBpLCBjLCBsYXN0SW5kZXgsIGxhc3Q7XG4gIGZvciAoaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgIGMgPSBjaGlsZHJlbltpXTtcbiAgICBpZiAoaXNVbmRlZihjKSB8fCB0eXBlb2YgYyA9PT0gJ2Jvb2xlYW4nKSB7IGNvbnRpbnVlIH1cbiAgICBsYXN0SW5kZXggPSByZXMubGVuZ3RoIC0gMTtcbiAgICBsYXN0ID0gcmVzW2xhc3RJbmRleF07XG4gICAgLy8gIG5lc3RlZFxuICAgIGlmIChBcnJheS5pc0FycmF5KGMpKSB7XG4gICAgICBpZiAoYy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGMgPSBub3JtYWxpemVBcnJheUNoaWxkcmVuKGMsICgobmVzdGVkSW5kZXggfHwgJycpICsgXCJfXCIgKyBpKSk7XG4gICAgICAgIC8vIG1lcmdlIGFkamFjZW50IHRleHQgbm9kZXNcbiAgICAgICAgaWYgKGlzVGV4dE5vZGUoY1swXSkgJiYgaXNUZXh0Tm9kZShsYXN0KSkge1xuICAgICAgICAgIHJlc1tsYXN0SW5kZXhdID0gY3JlYXRlVGV4dFZOb2RlKGxhc3QudGV4dCArIChjWzBdKS50ZXh0KTtcbiAgICAgICAgICBjLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnB1c2guYXBwbHkocmVzLCBjKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUHJpbWl0aXZlKGMpKSB7XG4gICAgICBpZiAoaXNUZXh0Tm9kZShsYXN0KSkge1xuICAgICAgICAvLyBtZXJnZSBhZGphY2VudCB0ZXh0IG5vZGVzXG4gICAgICAgIC8vIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBTU1IgaHlkcmF0aW9uIGJlY2F1c2UgdGV4dCBub2RlcyBhcmVcbiAgICAgICAgLy8gZXNzZW50aWFsbHkgbWVyZ2VkIHdoZW4gcmVuZGVyZWQgdG8gSFRNTCBzdHJpbmdzXG4gICAgICAgIHJlc1tsYXN0SW5kZXhdID0gY3JlYXRlVGV4dFZOb2RlKGxhc3QudGV4dCArIGMpO1xuICAgICAgfSBlbHNlIGlmIChjICE9PSAnJykge1xuICAgICAgICAvLyBjb252ZXJ0IHByaW1pdGl2ZSB0byB2bm9kZVxuICAgICAgICByZXMucHVzaChjcmVhdGVUZXh0Vk5vZGUoYykpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNUZXh0Tm9kZShjKSAmJiBpc1RleHROb2RlKGxhc3QpKSB7XG4gICAgICAgIC8vIG1lcmdlIGFkamFjZW50IHRleHQgbm9kZXNcbiAgICAgICAgcmVzW2xhc3RJbmRleF0gPSBjcmVhdGVUZXh0Vk5vZGUobGFzdC50ZXh0ICsgYy50ZXh0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlZmF1bHQga2V5IGZvciBuZXN0ZWQgYXJyYXkgY2hpbGRyZW4gKGxpa2VseSBnZW5lcmF0ZWQgYnkgdi1mb3IpXG4gICAgICAgIGlmIChpc1RydWUoY2hpbGRyZW4uX2lzVkxpc3QpICYmXG4gICAgICAgICAgaXNEZWYoYy50YWcpICYmXG4gICAgICAgICAgaXNVbmRlZihjLmtleSkgJiZcbiAgICAgICAgICBpc0RlZihuZXN0ZWRJbmRleCkpIHtcbiAgICAgICAgICBjLmtleSA9IFwiX192bGlzdFwiICsgbmVzdGVkSW5kZXggKyBcIl9cIiArIGkgKyBcIl9fXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnB1c2goYyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRQcm92aWRlICh2bSkge1xuICB2YXIgcHJvdmlkZSA9IHZtLiRvcHRpb25zLnByb3ZpZGU7XG4gIGlmIChwcm92aWRlKSB7XG4gICAgdm0uX3Byb3ZpZGVkID0gdHlwZW9mIHByb3ZpZGUgPT09ICdmdW5jdGlvbidcbiAgICAgID8gcHJvdmlkZS5jYWxsKHZtKVxuICAgICAgOiBwcm92aWRlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRJbmplY3Rpb25zICh2bSkge1xuICB2YXIgcmVzdWx0ID0gcmVzb2x2ZUluamVjdCh2bS4kb3B0aW9ucy5pbmplY3QsIHZtKTtcbiAgaWYgKHJlc3VsdCkge1xuICAgIHRvZ2dsZU9ic2VydmluZyhmYWxzZSk7XG4gICAgT2JqZWN0LmtleXMocmVzdWx0KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICB7XG4gICAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCBrZXksIHJlc3VsdFtrZXldLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgd2FybihcbiAgICAgICAgICAgIFwiQXZvaWQgbXV0YXRpbmcgYW4gaW5qZWN0ZWQgdmFsdWUgZGlyZWN0bHkgc2luY2UgdGhlIGNoYW5nZXMgd2lsbCBiZSBcIiArXG4gICAgICAgICAgICBcIm92ZXJ3cml0dGVuIHdoZW5ldmVyIHRoZSBwcm92aWRlZCBjb21wb25lbnQgcmUtcmVuZGVycy4gXCIgK1xuICAgICAgICAgICAgXCJpbmplY3Rpb24gYmVpbmcgbXV0YXRlZDogXFxcIlwiICsga2V5ICsgXCJcXFwiXCIsXG4gICAgICAgICAgICB2bVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRvZ2dsZU9ic2VydmluZyh0cnVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlSW5qZWN0IChpbmplY3QsIHZtKSB7XG4gIGlmIChpbmplY3QpIHtcbiAgICAvLyBpbmplY3QgaXMgOmFueSBiZWNhdXNlIGZsb3cgaXMgbm90IHNtYXJ0IGVub3VnaCB0byBmaWd1cmUgb3V0IGNhY2hlZFxuICAgIHZhciByZXN1bHQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBrZXlzID0gaGFzU3ltYm9sXG4gICAgICA/IFJlZmxlY3Qub3duS2V5cyhpbmplY3QpXG4gICAgICA6IE9iamVjdC5rZXlzKGluamVjdCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgLy8gIzY1NzQgaW4gY2FzZSB0aGUgaW5qZWN0IG9iamVjdCBpcyBvYnNlcnZlZC4uLlxuICAgICAgaWYgKGtleSA9PT0gJ19fb2JfXycpIHsgY29udGludWUgfVxuICAgICAgdmFyIHByb3ZpZGVLZXkgPSBpbmplY3Rba2V5XS5mcm9tO1xuICAgICAgdmFyIHNvdXJjZSA9IHZtO1xuICAgICAgd2hpbGUgKHNvdXJjZSkge1xuICAgICAgICBpZiAoc291cmNlLl9wcm92aWRlZCAmJiBoYXNPd24oc291cmNlLl9wcm92aWRlZCwgcHJvdmlkZUtleSkpIHtcbiAgICAgICAgICByZXN1bHRba2V5XSA9IHNvdXJjZS5fcHJvdmlkZWRbcHJvdmlkZUtleV07XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBzb3VyY2UgPSBzb3VyY2UuJHBhcmVudDtcbiAgICAgIH1cbiAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIGlmICgnZGVmYXVsdCcgaW4gaW5qZWN0W2tleV0pIHtcbiAgICAgICAgICB2YXIgcHJvdmlkZURlZmF1bHQgPSBpbmplY3Rba2V5XS5kZWZhdWx0O1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gdHlwZW9mIHByb3ZpZGVEZWZhdWx0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICA/IHByb3ZpZGVEZWZhdWx0LmNhbGwodm0pXG4gICAgICAgICAgICA6IHByb3ZpZGVEZWZhdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdhcm4oKFwiSW5qZWN0aW9uIFxcXCJcIiArIGtleSArIFwiXFxcIiBub3QgZm91bmRcIiksIHZtKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cbn1cblxuLyogICovXG5cblxuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciByZXNvbHZpbmcgcmF3IGNoaWxkcmVuIFZOb2RlcyBpbnRvIGEgc2xvdCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVTbG90cyAoXG4gIGNoaWxkcmVuLFxuICBjb250ZXh0XG4pIHtcbiAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cbiAgdmFyIHNsb3RzID0ge307XG4gIGZvciAodmFyIGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgdmFyIGRhdGEgPSBjaGlsZC5kYXRhO1xuICAgIC8vIHJlbW92ZSBzbG90IGF0dHJpYnV0ZSBpZiB0aGUgbm9kZSBpcyByZXNvbHZlZCBhcyBhIFZ1ZSBzbG90IG5vZGVcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmF0dHJzICYmIGRhdGEuYXR0cnMuc2xvdCkge1xuICAgICAgZGVsZXRlIGRhdGEuYXR0cnMuc2xvdDtcbiAgICB9XG4gICAgLy8gbmFtZWQgc2xvdHMgc2hvdWxkIG9ubHkgYmUgcmVzcGVjdGVkIGlmIHRoZSB2bm9kZSB3YXMgcmVuZGVyZWQgaW4gdGhlXG4gICAgLy8gc2FtZSBjb250ZXh0LlxuICAgIGlmICgoY2hpbGQuY29udGV4dCA9PT0gY29udGV4dCB8fCBjaGlsZC5mbkNvbnRleHQgPT09IGNvbnRleHQpICYmXG4gICAgICBkYXRhICYmIGRhdGEuc2xvdCAhPSBudWxsXG4gICAgKSB7XG4gICAgICB2YXIgbmFtZSA9IGRhdGEuc2xvdDtcbiAgICAgIHZhciBzbG90ID0gKHNsb3RzW25hbWVdIHx8IChzbG90c1tuYW1lXSA9IFtdKSk7XG4gICAgICBpZiAoY2hpbGQudGFnID09PSAndGVtcGxhdGUnKSB7XG4gICAgICAgIHNsb3QucHVzaC5hcHBseShzbG90LCBjaGlsZC5jaGlsZHJlbiB8fCBbXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbG90LnB1c2goY2hpbGQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAoc2xvdHMuZGVmYXVsdCB8fCAoc2xvdHMuZGVmYXVsdCA9IFtdKSkucHVzaChjaGlsZCk7XG4gICAgfVxuICB9XG4gIC8vIGlnbm9yZSBzbG90cyB0aGF0IGNvbnRhaW5zIG9ubHkgd2hpdGVzcGFjZVxuICBmb3IgKHZhciBuYW1lJDEgaW4gc2xvdHMpIHtcbiAgICBpZiAoc2xvdHNbbmFtZSQxXS5ldmVyeShpc1doaXRlc3BhY2UpKSB7XG4gICAgICBkZWxldGUgc2xvdHNbbmFtZSQxXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNsb3RzXG59XG5cbmZ1bmN0aW9uIGlzV2hpdGVzcGFjZSAobm9kZSkge1xuICByZXR1cm4gKG5vZGUuaXNDb21tZW50ICYmICFub2RlLmFzeW5jRmFjdG9yeSkgfHwgbm9kZS50ZXh0ID09PSAnICdcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNjb3BlZFNsb3RzIChcbiAgc2xvdHMsXG4gIG5vcm1hbFNsb3RzLFxuICBwcmV2U2xvdHNcbikge1xuICB2YXIgcmVzO1xuICB2YXIgaGFzTm9ybWFsU2xvdHMgPSBPYmplY3Qua2V5cyhub3JtYWxTbG90cykubGVuZ3RoID4gMDtcbiAgdmFyIGlzU3RhYmxlID0gc2xvdHMgPyAhIXNsb3RzLiRzdGFibGUgOiAhaGFzTm9ybWFsU2xvdHM7XG4gIHZhciBrZXkgPSBzbG90cyAmJiBzbG90cy4ka2V5O1xuICBpZiAoIXNsb3RzKSB7XG4gICAgcmVzID0ge307XG4gIH0gZWxzZSBpZiAoc2xvdHMuX25vcm1hbGl6ZWQpIHtcbiAgICAvLyBmYXN0IHBhdGggMTogY2hpbGQgY29tcG9uZW50IHJlLXJlbmRlciBvbmx5LCBwYXJlbnQgZGlkIG5vdCBjaGFuZ2VcbiAgICByZXR1cm4gc2xvdHMuX25vcm1hbGl6ZWRcbiAgfSBlbHNlIGlmIChcbiAgICBpc1N0YWJsZSAmJlxuICAgIHByZXZTbG90cyAmJlxuICAgIHByZXZTbG90cyAhPT0gZW1wdHlPYmplY3QgJiZcbiAgICBrZXkgPT09IHByZXZTbG90cy4ka2V5ICYmXG4gICAgIWhhc05vcm1hbFNsb3RzICYmXG4gICAgIXByZXZTbG90cy4kaGFzTm9ybWFsXG4gICkge1xuICAgIC8vIGZhc3QgcGF0aCAyOiBzdGFibGUgc2NvcGVkIHNsb3RzIHcvIG5vIG5vcm1hbCBzbG90cyB0byBwcm94eSxcbiAgICAvLyBvbmx5IG5lZWQgdG8gbm9ybWFsaXplIG9uY2VcbiAgICByZXR1cm4gcHJldlNsb3RzXG4gIH0gZWxzZSB7XG4gICAgcmVzID0ge307XG4gICAgZm9yICh2YXIga2V5JDEgaW4gc2xvdHMpIHtcbiAgICAgIGlmIChzbG90c1trZXkkMV0gJiYga2V5JDFbMF0gIT09ICckJykge1xuICAgICAgICByZXNba2V5JDFdID0gbm9ybWFsaXplU2NvcGVkU2xvdChub3JtYWxTbG90cywga2V5JDEsIHNsb3RzW2tleSQxXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIGV4cG9zZSBub3JtYWwgc2xvdHMgb24gc2NvcGVkU2xvdHNcbiAgZm9yICh2YXIga2V5JDIgaW4gbm9ybWFsU2xvdHMpIHtcbiAgICBpZiAoIShrZXkkMiBpbiByZXMpKSB7XG4gICAgICByZXNba2V5JDJdID0gcHJveHlOb3JtYWxTbG90KG5vcm1hbFNsb3RzLCBrZXkkMik7XG4gICAgfVxuICB9XG4gIC8vIGF2b3JpYXogc2VlbXMgdG8gbW9jayBhIG5vbi1leHRlbnNpYmxlICRzY29wZWRTbG90cyBvYmplY3RcbiAgLy8gYW5kIHdoZW4gdGhhdCBpcyBwYXNzZWQgZG93biB0aGlzIHdvdWxkIGNhdXNlIGFuIGVycm9yXG4gIGlmIChzbG90cyAmJiBPYmplY3QuaXNFeHRlbnNpYmxlKHNsb3RzKSkge1xuICAgIChzbG90cykuX25vcm1hbGl6ZWQgPSByZXM7XG4gIH1cbiAgZGVmKHJlcywgJyRzdGFibGUnLCBpc1N0YWJsZSk7XG4gIGRlZihyZXMsICcka2V5Jywga2V5KTtcbiAgZGVmKHJlcywgJyRoYXNOb3JtYWwnLCBoYXNOb3JtYWxTbG90cyk7XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplU2NvcGVkU2xvdChub3JtYWxTbG90cywga2V5LCBmbikge1xuICB2YXIgbm9ybWFsaXplZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzID0gYXJndW1lbnRzLmxlbmd0aCA/IGZuLmFwcGx5KG51bGwsIGFyZ3VtZW50cykgOiBmbih7fSk7XG4gICAgcmVzID0gcmVzICYmIHR5cGVvZiByZXMgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlcylcbiAgICAgID8gW3Jlc10gLy8gc2luZ2xlIHZub2RlXG4gICAgICA6IG5vcm1hbGl6ZUNoaWxkcmVuKHJlcyk7XG4gICAgcmV0dXJuIHJlcyAmJiAoXG4gICAgICByZXMubGVuZ3RoID09PSAwIHx8XG4gICAgICAocmVzLmxlbmd0aCA9PT0gMSAmJiByZXNbMF0uaXNDb21tZW50KSAvLyAjOTY1OFxuICAgICkgPyB1bmRlZmluZWRcbiAgICAgIDogcmVzXG4gIH07XG4gIC8vIHRoaXMgaXMgYSBzbG90IHVzaW5nIHRoZSBuZXcgdi1zbG90IHN5bnRheCB3aXRob3V0IHNjb3BlLiBhbHRob3VnaCBpdCBpc1xuICAvLyBjb21waWxlZCBhcyBhIHNjb3BlZCBzbG90LCByZW5kZXIgZm4gdXNlcnMgd291bGQgZXhwZWN0IGl0IHRvIGJlIHByZXNlbnRcbiAgLy8gb24gdGhpcy4kc2xvdHMgYmVjYXVzZSB0aGUgdXNhZ2UgaXMgc2VtYW50aWNhbGx5IGEgbm9ybWFsIHNsb3QuXG4gIGlmIChmbi5wcm94eSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub3JtYWxTbG90cywga2V5LCB7XG4gICAgICBnZXQ6IG5vcm1hbGl6ZWQsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuZnVuY3Rpb24gcHJveHlOb3JtYWxTbG90KHNsb3RzLCBrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNsb3RzW2tleV07IH1cbn1cblxuLyogICovXG5cbi8qKlxuICogUnVudGltZSBoZWxwZXIgZm9yIHJlbmRlcmluZyB2LWZvciBsaXN0cy5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyTGlzdCAoXG4gIHZhbCxcbiAgcmVuZGVyXG4pIHtcbiAgdmFyIHJldCwgaSwgbCwga2V5cywga2V5O1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpIHx8IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0ID0gbmV3IEFycmF5KHZhbC5sZW5ndGgpO1xuICAgIGZvciAoaSA9IDAsIGwgPSB2YWwubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICByZXRbaV0gPSByZW5kZXIodmFsW2ldLCBpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICByZXQgPSBuZXcgQXJyYXkodmFsKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdmFsOyBpKyspIHtcbiAgICAgIHJldFtpXSA9IHJlbmRlcihpICsgMSwgaSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbCkpIHtcbiAgICBpZiAoaGFzU3ltYm9sICYmIHZhbFtTeW1ib2wuaXRlcmF0b3JdKSB7XG4gICAgICByZXQgPSBbXTtcbiAgICAgIHZhciBpdGVyYXRvciA9IHZhbFtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgICB2YXIgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgd2hpbGUgKCFyZXN1bHQuZG9uZSkge1xuICAgICAgICByZXQucHVzaChyZW5kZXIocmVzdWx0LnZhbHVlLCByZXQubGVuZ3RoKSk7XG4gICAgICAgIHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgICByZXQgPSBuZXcgQXJyYXkoa2V5cy5sZW5ndGgpO1xuICAgICAgZm9yIChpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgIHJldFtpXSA9IHJlbmRlcih2YWxba2V5XSwga2V5LCBpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFpc0RlZihyZXQpKSB7XG4gICAgcmV0ID0gW107XG4gIH1cbiAgKHJldCkuX2lzVkxpc3QgPSB0cnVlO1xuICByZXR1cm4gcmV0XG59XG5cbi8qICAqL1xuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciByZW5kZXJpbmcgPHNsb3Q+XG4gKi9cbmZ1bmN0aW9uIHJlbmRlclNsb3QgKFxuICBuYW1lLFxuICBmYWxsYmFjayxcbiAgcHJvcHMsXG4gIGJpbmRPYmplY3Rcbikge1xuICB2YXIgc2NvcGVkU2xvdEZuID0gdGhpcy4kc2NvcGVkU2xvdHNbbmFtZV07XG4gIHZhciBub2RlcztcbiAgaWYgKHNjb3BlZFNsb3RGbikgeyAvLyBzY29wZWQgc2xvdFxuICAgIHByb3BzID0gcHJvcHMgfHwge307XG4gICAgaWYgKGJpbmRPYmplY3QpIHtcbiAgICAgIGlmICghaXNPYmplY3QoYmluZE9iamVjdCkpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnc2xvdCB2LWJpbmQgd2l0aG91dCBhcmd1bWVudCBleHBlY3RzIGFuIE9iamVjdCcsXG4gICAgICAgICAgdGhpc1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcHJvcHMgPSBleHRlbmQoZXh0ZW5kKHt9LCBiaW5kT2JqZWN0KSwgcHJvcHMpO1xuICAgIH1cbiAgICBub2RlcyA9IHNjb3BlZFNsb3RGbihwcm9wcykgfHwgZmFsbGJhY2s7XG4gIH0gZWxzZSB7XG4gICAgbm9kZXMgPSB0aGlzLiRzbG90c1tuYW1lXSB8fCBmYWxsYmFjaztcbiAgfVxuXG4gIHZhciB0YXJnZXQgPSBwcm9wcyAmJiBwcm9wcy5zbG90O1xuICBpZiAodGFyZ2V0KSB7XG4gICAgcmV0dXJuIHRoaXMuJGNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJywgeyBzbG90OiB0YXJnZXQgfSwgbm9kZXMpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGVzXG4gIH1cbn1cblxuLyogICovXG5cbi8qKlxuICogUnVudGltZSBoZWxwZXIgZm9yIHJlc29sdmluZyBmaWx0ZXJzXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGaWx0ZXIgKGlkKSB7XG4gIHJldHVybiByZXNvbHZlQXNzZXQodGhpcy4kb3B0aW9ucywgJ2ZpbHRlcnMnLCBpZCwgdHJ1ZSkgfHwgaWRlbnRpdHlcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGlzS2V5Tm90TWF0Y2ggKGV4cGVjdCwgYWN0dWFsKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGV4cGVjdCkpIHtcbiAgICByZXR1cm4gZXhwZWN0LmluZGV4T2YoYWN0dWFsKSA9PT0gLTFcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXhwZWN0ICE9PSBhY3R1YWxcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciBjaGVja2luZyBrZXlDb2RlcyBmcm9tIGNvbmZpZy5cbiAqIGV4cG9zZWQgYXMgVnVlLnByb3RvdHlwZS5fa1xuICogcGFzc2luZyBpbiBldmVudEtleU5hbWUgYXMgbGFzdCBhcmd1bWVudCBzZXBhcmF0ZWx5IGZvciBiYWNrd2FyZHMgY29tcGF0XG4gKi9cbmZ1bmN0aW9uIGNoZWNrS2V5Q29kZXMgKFxuICBldmVudEtleUNvZGUsXG4gIGtleSxcbiAgYnVpbHRJbktleUNvZGUsXG4gIGV2ZW50S2V5TmFtZSxcbiAgYnVpbHRJbktleU5hbWVcbikge1xuICB2YXIgbWFwcGVkS2V5Q29kZSA9IGNvbmZpZy5rZXlDb2Rlc1trZXldIHx8IGJ1aWx0SW5LZXlDb2RlO1xuICBpZiAoYnVpbHRJbktleU5hbWUgJiYgZXZlbnRLZXlOYW1lICYmICFjb25maWcua2V5Q29kZXNba2V5XSkge1xuICAgIHJldHVybiBpc0tleU5vdE1hdGNoKGJ1aWx0SW5LZXlOYW1lLCBldmVudEtleU5hbWUpXG4gIH0gZWxzZSBpZiAobWFwcGVkS2V5Q29kZSkge1xuICAgIHJldHVybiBpc0tleU5vdE1hdGNoKG1hcHBlZEtleUNvZGUsIGV2ZW50S2V5Q29kZSlcbiAgfSBlbHNlIGlmIChldmVudEtleU5hbWUpIHtcbiAgICByZXR1cm4gaHlwaGVuYXRlKGV2ZW50S2V5TmFtZSkgIT09IGtleVxuICB9XG59XG5cbi8qICAqL1xuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciBtZXJnaW5nIHYtYmluZD1cIm9iamVjdFwiIGludG8gYSBWTm9kZSdzIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGJpbmRPYmplY3RQcm9wcyAoXG4gIGRhdGEsXG4gIHRhZyxcbiAgdmFsdWUsXG4gIGFzUHJvcCxcbiAgaXNTeW5jXG4pIHtcbiAgaWYgKHZhbHVlKSB7XG4gICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICd2LWJpbmQgd2l0aG91dCBhcmd1bWVudCBleHBlY3RzIGFuIE9iamVjdCBvciBBcnJheSB2YWx1ZScsXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHRvT2JqZWN0KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHZhciBoYXNoO1xuICAgICAgdmFyIGxvb3AgPSBmdW5jdGlvbiAoIGtleSApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGtleSA9PT0gJ2NsYXNzJyB8fFxuICAgICAgICAgIGtleSA9PT0gJ3N0eWxlJyB8fFxuICAgICAgICAgIGlzUmVzZXJ2ZWRBdHRyaWJ1dGUoa2V5KVxuICAgICAgICApIHtcbiAgICAgICAgICBoYXNoID0gZGF0YTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgdHlwZSA9IGRhdGEuYXR0cnMgJiYgZGF0YS5hdHRycy50eXBlO1xuICAgICAgICAgIGhhc2ggPSBhc1Byb3AgfHwgY29uZmlnLm11c3RVc2VQcm9wKHRhZywgdHlwZSwga2V5KVxuICAgICAgICAgICAgPyBkYXRhLmRvbVByb3BzIHx8IChkYXRhLmRvbVByb3BzID0ge30pXG4gICAgICAgICAgICA6IGRhdGEuYXR0cnMgfHwgKGRhdGEuYXR0cnMgPSB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNhbWVsaXplZEtleSA9IGNhbWVsaXplKGtleSk7XG4gICAgICAgIHZhciBoeXBoZW5hdGVkS2V5ID0gaHlwaGVuYXRlKGtleSk7XG4gICAgICAgIGlmICghKGNhbWVsaXplZEtleSBpbiBoYXNoKSAmJiAhKGh5cGhlbmF0ZWRLZXkgaW4gaGFzaCkpIHtcbiAgICAgICAgICBoYXNoW2tleV0gPSB2YWx1ZVtrZXldO1xuXG4gICAgICAgICAgaWYgKGlzU3luYykge1xuICAgICAgICAgICAgdmFyIG9uID0gZGF0YS5vbiB8fCAoZGF0YS5vbiA9IHt9KTtcbiAgICAgICAgICAgIG9uWyhcInVwZGF0ZTpcIiArIGtleSldID0gZnVuY3Rpb24gKCRldmVudCkge1xuICAgICAgICAgICAgICB2YWx1ZVtrZXldID0gJGV2ZW50O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkgbG9vcCgga2V5ICk7XG4gICAgfVxuICB9XG4gIHJldHVybiBkYXRhXG59XG5cbi8qICAqL1xuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciByZW5kZXJpbmcgc3RhdGljIHRyZWVzLlxuICovXG5mdW5jdGlvbiByZW5kZXJTdGF0aWMgKFxuICBpbmRleCxcbiAgaXNJbkZvclxuKSB7XG4gIHZhciBjYWNoZWQgPSB0aGlzLl9zdGF0aWNUcmVlcyB8fCAodGhpcy5fc3RhdGljVHJlZXMgPSBbXSk7XG4gIHZhciB0cmVlID0gY2FjaGVkW2luZGV4XTtcbiAgLy8gaWYgaGFzIGFscmVhZHktcmVuZGVyZWQgc3RhdGljIHRyZWUgYW5kIG5vdCBpbnNpZGUgdi1mb3IsXG4gIC8vIHdlIGNhbiByZXVzZSB0aGUgc2FtZSB0cmVlLlxuICBpZiAodHJlZSAmJiAhaXNJbkZvcikge1xuICAgIHJldHVybiB0cmVlXG4gIH1cbiAgLy8gb3RoZXJ3aXNlLCByZW5kZXIgYSBmcmVzaCB0cmVlLlxuICB0cmVlID0gY2FjaGVkW2luZGV4XSA9IHRoaXMuJG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zW2luZGV4XS5jYWxsKFxuICAgIHRoaXMuX3JlbmRlclByb3h5LFxuICAgIG51bGwsXG4gICAgdGhpcyAvLyBmb3IgcmVuZGVyIGZucyBnZW5lcmF0ZWQgZm9yIGZ1bmN0aW9uYWwgY29tcG9uZW50IHRlbXBsYXRlc1xuICApO1xuICBtYXJrU3RhdGljKHRyZWUsIChcIl9fc3RhdGljX19cIiArIGluZGV4KSwgZmFsc2UpO1xuICByZXR1cm4gdHJlZVxufVxuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciB2LW9uY2UuXG4gKiBFZmZlY3RpdmVseSBpdCBtZWFucyBtYXJraW5nIHRoZSBub2RlIGFzIHN0YXRpYyB3aXRoIGEgdW5pcXVlIGtleS5cbiAqL1xuZnVuY3Rpb24gbWFya09uY2UgKFxuICB0cmVlLFxuICBpbmRleCxcbiAga2V5XG4pIHtcbiAgbWFya1N0YXRpYyh0cmVlLCAoXCJfX29uY2VfX1wiICsgaW5kZXggKyAoa2V5ID8gKFwiX1wiICsga2V5KSA6IFwiXCIpKSwgdHJ1ZSk7XG4gIHJldHVybiB0cmVlXG59XG5cbmZ1bmN0aW9uIG1hcmtTdGF0aWMgKFxuICB0cmVlLFxuICBrZXksXG4gIGlzT25jZVxuKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHRyZWUpKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0cmVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodHJlZVtpXSAmJiB0eXBlb2YgdHJlZVtpXSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWFya1N0YXRpY05vZGUodHJlZVtpXSwgKGtleSArIFwiX1wiICsgaSksIGlzT25jZSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG1hcmtTdGF0aWNOb2RlKHRyZWUsIGtleSwgaXNPbmNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrU3RhdGljTm9kZSAobm9kZSwga2V5LCBpc09uY2UpIHtcbiAgbm9kZS5pc1N0YXRpYyA9IHRydWU7XG4gIG5vZGUua2V5ID0ga2V5O1xuICBub2RlLmlzT25jZSA9IGlzT25jZTtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGJpbmRPYmplY3RMaXN0ZW5lcnMgKGRhdGEsIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmICghaXNQbGFpbk9iamVjdCh2YWx1ZSkpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICd2LW9uIHdpdGhvdXQgYXJndW1lbnQgZXhwZWN0cyBhbiBPYmplY3QgdmFsdWUnLFxuICAgICAgICB0aGlzXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgb24gPSBkYXRhLm9uID0gZGF0YS5vbiA/IGV4dGVuZCh7fSwgZGF0YS5vbikgOiB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICB2YXIgZXhpc3RpbmcgPSBvbltrZXldO1xuICAgICAgICB2YXIgb3VycyA9IHZhbHVlW2tleV07XG4gICAgICAgIG9uW2tleV0gPSBleGlzdGluZyA/IFtdLmNvbmNhdChleGlzdGluZywgb3VycykgOiBvdXJzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gcmVzb2x2ZVNjb3BlZFNsb3RzIChcbiAgZm5zLCAvLyBzZWUgZmxvdy92bm9kZVxuICByZXMsXG4gIC8vIHRoZSBmb2xsb3dpbmcgYXJlIGFkZGVkIGluIDIuNlxuICBoYXNEeW5hbWljS2V5cyxcbiAgY29udGVudEhhc2hLZXlcbikge1xuICByZXMgPSByZXMgfHwgeyAkc3RhYmxlOiAhaGFzRHluYW1pY0tleXMgfTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBmbnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc2xvdCA9IGZuc1tpXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzbG90KSkge1xuICAgICAgcmVzb2x2ZVNjb3BlZFNsb3RzKHNsb3QsIHJlcywgaGFzRHluYW1pY0tleXMpO1xuICAgIH0gZWxzZSBpZiAoc2xvdCkge1xuICAgICAgLy8gbWFya2VyIGZvciByZXZlcnNlIHByb3h5aW5nIHYtc2xvdCB3aXRob3V0IHNjb3BlIG9uIHRoaXMuJHNsb3RzXG4gICAgICBpZiAoc2xvdC5wcm94eSkge1xuICAgICAgICBzbG90LmZuLnByb3h5ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJlc1tzbG90LmtleV0gPSBzbG90LmZuO1xuICAgIH1cbiAgfVxuICBpZiAoY29udGVudEhhc2hLZXkpIHtcbiAgICAocmVzKS4ka2V5ID0gY29udGVudEhhc2hLZXk7XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gYmluZER5bmFtaWNLZXlzIChiYXNlT2JqLCB2YWx1ZXMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIga2V5ID0gdmFsdWVzW2ldO1xuICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyAmJiBrZXkpIHtcbiAgICAgIGJhc2VPYmpbdmFsdWVzW2ldXSA9IHZhbHVlc1tpICsgMV07XG4gICAgfSBlbHNlIGlmIChrZXkgIT09ICcnICYmIGtleSAhPT0gbnVsbCkge1xuICAgICAgLy8gbnVsbCBpcyBhIHNwZWNpYWwgdmFsdWUgZm9yIGV4cGxpY2l0bHkgcmVtb3ZpbmcgYSBiaW5kaW5nXG4gICAgICB3YXJuKFxuICAgICAgICAoXCJJbnZhbGlkIHZhbHVlIGZvciBkeW5hbWljIGRpcmVjdGl2ZSBhcmd1bWVudCAoZXhwZWN0ZWQgc3RyaW5nIG9yIG51bGwpOiBcIiArIGtleSksXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHJldHVybiBiYXNlT2JqXG59XG5cbi8vIGhlbHBlciB0byBkeW5hbWljYWxseSBhcHBlbmQgbW9kaWZpZXIgcnVudGltZSBtYXJrZXJzIHRvIGV2ZW50IG5hbWVzLlxuLy8gZW5zdXJlIG9ubHkgYXBwZW5kIHdoZW4gdmFsdWUgaXMgYWxyZWFkeSBzdHJpbmcsIG90aGVyd2lzZSBpdCB3aWxsIGJlIGNhc3Rcbi8vIHRvIHN0cmluZyBhbmQgY2F1c2UgdGhlIHR5cGUgY2hlY2sgdG8gbWlzcy5cbmZ1bmN0aW9uIHByZXBlbmRNb2RpZmllciAodmFsdWUsIHN5bWJvbCkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHN5bWJvbCArIHZhbHVlIDogdmFsdWVcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluc3RhbGxSZW5kZXJIZWxwZXJzICh0YXJnZXQpIHtcbiAgdGFyZ2V0Ll9vID0gbWFya09uY2U7XG4gIHRhcmdldC5fbiA9IHRvTnVtYmVyO1xuICB0YXJnZXQuX3MgPSB0b1N0cmluZztcbiAgdGFyZ2V0Ll9sID0gcmVuZGVyTGlzdDtcbiAgdGFyZ2V0Ll90ID0gcmVuZGVyU2xvdDtcbiAgdGFyZ2V0Ll9xID0gbG9vc2VFcXVhbDtcbiAgdGFyZ2V0Ll9pID0gbG9vc2VJbmRleE9mO1xuICB0YXJnZXQuX20gPSByZW5kZXJTdGF0aWM7XG4gIHRhcmdldC5fZiA9IHJlc29sdmVGaWx0ZXI7XG4gIHRhcmdldC5fayA9IGNoZWNrS2V5Q29kZXM7XG4gIHRhcmdldC5fYiA9IGJpbmRPYmplY3RQcm9wcztcbiAgdGFyZ2V0Ll92ID0gY3JlYXRlVGV4dFZOb2RlO1xuICB0YXJnZXQuX2UgPSBjcmVhdGVFbXB0eVZOb2RlO1xuICB0YXJnZXQuX3UgPSByZXNvbHZlU2NvcGVkU2xvdHM7XG4gIHRhcmdldC5fZyA9IGJpbmRPYmplY3RMaXN0ZW5lcnM7XG4gIHRhcmdldC5fZCA9IGJpbmREeW5hbWljS2V5cztcbiAgdGFyZ2V0Ll9wID0gcHJlcGVuZE1vZGlmaWVyO1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gRnVuY3Rpb25hbFJlbmRlckNvbnRleHQgKFxuICBkYXRhLFxuICBwcm9wcyxcbiAgY2hpbGRyZW4sXG4gIHBhcmVudCxcbiAgQ3RvclxuKSB7XG4gIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gIHZhciBvcHRpb25zID0gQ3Rvci5vcHRpb25zO1xuICAvLyBlbnN1cmUgdGhlIGNyZWF0ZUVsZW1lbnQgZnVuY3Rpb24gaW4gZnVuY3Rpb25hbCBjb21wb25lbnRzXG4gIC8vIGdldHMgYSB1bmlxdWUgY29udGV4dCAtIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBjb3JyZWN0IG5hbWVkIHNsb3QgY2hlY2tcbiAgdmFyIGNvbnRleHRWbTtcbiAgaWYgKGhhc093bihwYXJlbnQsICdfdWlkJykpIHtcbiAgICBjb250ZXh0Vm0gPSBPYmplY3QuY3JlYXRlKHBhcmVudCk7XG4gICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lXG4gICAgY29udGV4dFZtLl9vcmlnaW5hbCA9IHBhcmVudDtcbiAgfSBlbHNlIHtcbiAgICAvLyB0aGUgY29udGV4dCB2bSBwYXNzZWQgaW4gaXMgYSBmdW5jdGlvbmFsIGNvbnRleHQgYXMgd2VsbC5cbiAgICAvLyBpbiB0aGlzIGNhc2Ugd2Ugd2FudCB0byBtYWtlIHN1cmUgd2UgYXJlIGFibGUgdG8gZ2V0IGEgaG9sZCB0byB0aGVcbiAgICAvLyByZWFsIGNvbnRleHQgaW5zdGFuY2UuXG4gICAgY29udGV4dFZtID0gcGFyZW50O1xuICAgIC8vICRmbG93LWRpc2FibGUtbGluZVxuICAgIHBhcmVudCA9IHBhcmVudC5fb3JpZ2luYWw7XG4gIH1cbiAgdmFyIGlzQ29tcGlsZWQgPSBpc1RydWUob3B0aW9ucy5fY29tcGlsZWQpO1xuICB2YXIgbmVlZE5vcm1hbGl6YXRpb24gPSAhaXNDb21waWxlZDtcblxuICB0aGlzLmRhdGEgPSBkYXRhO1xuICB0aGlzLnByb3BzID0gcHJvcHM7XG4gIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMubGlzdGVuZXJzID0gZGF0YS5vbiB8fCBlbXB0eU9iamVjdDtcbiAgdGhpcy5pbmplY3Rpb25zID0gcmVzb2x2ZUluamVjdChvcHRpb25zLmluamVjdCwgcGFyZW50KTtcbiAgdGhpcy5zbG90cyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMkMS4kc2xvdHMpIHtcbiAgICAgIG5vcm1hbGl6ZVNjb3BlZFNsb3RzKFxuICAgICAgICBkYXRhLnNjb3BlZFNsb3RzLFxuICAgICAgICB0aGlzJDEuJHNsb3RzID0gcmVzb2x2ZVNsb3RzKGNoaWxkcmVuLCBwYXJlbnQpXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcyQxLiRzbG90c1xuICB9O1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnc2NvcGVkU2xvdHMnLCAoe1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQgKCkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZVNjb3BlZFNsb3RzKGRhdGEuc2NvcGVkU2xvdHMsIHRoaXMuc2xvdHMoKSlcbiAgICB9XG4gIH0pKTtcblxuICAvLyBzdXBwb3J0IGZvciBjb21waWxlZCBmdW5jdGlvbmFsIHRlbXBsYXRlXG4gIGlmIChpc0NvbXBpbGVkKSB7XG4gICAgLy8gZXhwb3NpbmcgJG9wdGlvbnMgZm9yIHJlbmRlclN0YXRpYygpXG4gICAgdGhpcy4kb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgLy8gcHJlLXJlc29sdmUgc2xvdHMgZm9yIHJlbmRlclNsb3QoKVxuICAgIHRoaXMuJHNsb3RzID0gdGhpcy5zbG90cygpO1xuICAgIHRoaXMuJHNjb3BlZFNsb3RzID0gbm9ybWFsaXplU2NvcGVkU2xvdHMoZGF0YS5zY29wZWRTbG90cywgdGhpcy4kc2xvdHMpO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuX3Njb3BlSWQpIHtcbiAgICB0aGlzLl9jID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQpIHtcbiAgICAgIHZhciB2bm9kZSA9IGNyZWF0ZUVsZW1lbnQoY29udGV4dFZtLCBhLCBiLCBjLCBkLCBuZWVkTm9ybWFsaXphdGlvbik7XG4gICAgICBpZiAodm5vZGUgJiYgIUFycmF5LmlzQXJyYXkodm5vZGUpKSB7XG4gICAgICAgIHZub2RlLmZuU2NvcGVJZCA9IG9wdGlvbnMuX3Njb3BlSWQ7XG4gICAgICAgIHZub2RlLmZuQ29udGV4dCA9IHBhcmVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2bm9kZVxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7IHJldHVybiBjcmVhdGVFbGVtZW50KGNvbnRleHRWbSwgYSwgYiwgYywgZCwgbmVlZE5vcm1hbGl6YXRpb24pOyB9O1xuICB9XG59XG5cbmluc3RhbGxSZW5kZXJIZWxwZXJzKEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0LnByb3RvdHlwZSk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUZ1bmN0aW9uYWxDb21wb25lbnQgKFxuICBDdG9yLFxuICBwcm9wc0RhdGEsXG4gIGRhdGEsXG4gIGNvbnRleHRWbSxcbiAgY2hpbGRyZW5cbikge1xuICB2YXIgb3B0aW9ucyA9IEN0b3Iub3B0aW9ucztcbiAgdmFyIHByb3BzID0ge307XG4gIHZhciBwcm9wT3B0aW9ucyA9IG9wdGlvbnMucHJvcHM7XG4gIGlmIChpc0RlZihwcm9wT3B0aW9ucykpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcE9wdGlvbnMpIHtcbiAgICAgIHByb3BzW2tleV0gPSB2YWxpZGF0ZVByb3Aoa2V5LCBwcm9wT3B0aW9ucywgcHJvcHNEYXRhIHx8IGVtcHR5T2JqZWN0KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGlzRGVmKGRhdGEuYXR0cnMpKSB7IG1lcmdlUHJvcHMocHJvcHMsIGRhdGEuYXR0cnMpOyB9XG4gICAgaWYgKGlzRGVmKGRhdGEucHJvcHMpKSB7IG1lcmdlUHJvcHMocHJvcHMsIGRhdGEucHJvcHMpOyB9XG4gIH1cblxuICB2YXIgcmVuZGVyQ29udGV4dCA9IG5ldyBGdW5jdGlvbmFsUmVuZGVyQ29udGV4dChcbiAgICBkYXRhLFxuICAgIHByb3BzLFxuICAgIGNoaWxkcmVuLFxuICAgIGNvbnRleHRWbSxcbiAgICBDdG9yXG4gICk7XG5cbiAgdmFyIHZub2RlID0gb3B0aW9ucy5yZW5kZXIuY2FsbChudWxsLCByZW5kZXJDb250ZXh0Ll9jLCByZW5kZXJDb250ZXh0KTtcblxuICBpZiAodm5vZGUgaW5zdGFuY2VvZiBWTm9kZSkge1xuICAgIHJldHVybiBjbG9uZUFuZE1hcmtGdW5jdGlvbmFsUmVzdWx0KHZub2RlLCBkYXRhLCByZW5kZXJDb250ZXh0LnBhcmVudCwgb3B0aW9ucywgcmVuZGVyQ29udGV4dClcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZub2RlKSkge1xuICAgIHZhciB2bm9kZXMgPSBub3JtYWxpemVDaGlsZHJlbih2bm9kZSkgfHwgW107XG4gICAgdmFyIHJlcyA9IG5ldyBBcnJheSh2bm9kZXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzW2ldID0gY2xvbmVBbmRNYXJrRnVuY3Rpb25hbFJlc3VsdCh2bm9kZXNbaV0sIGRhdGEsIHJlbmRlckNvbnRleHQucGFyZW50LCBvcHRpb25zLCByZW5kZXJDb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsb25lQW5kTWFya0Z1bmN0aW9uYWxSZXN1bHQgKHZub2RlLCBkYXRhLCBjb250ZXh0Vm0sIG9wdGlvbnMsIHJlbmRlckNvbnRleHQpIHtcbiAgLy8gIzc4MTcgY2xvbmUgbm9kZSBiZWZvcmUgc2V0dGluZyBmbkNvbnRleHQsIG90aGVyd2lzZSBpZiB0aGUgbm9kZSBpcyByZXVzZWRcbiAgLy8gKGUuZy4gaXQgd2FzIGZyb20gYSBjYWNoZWQgbm9ybWFsIHNsb3QpIHRoZSBmbkNvbnRleHQgY2F1c2VzIG5hbWVkIHNsb3RzXG4gIC8vIHRoYXQgc2hvdWxkIG5vdCBiZSBtYXRjaGVkIHRvIG1hdGNoLlxuICB2YXIgY2xvbmUgPSBjbG9uZVZOb2RlKHZub2RlKTtcbiAgY2xvbmUuZm5Db250ZXh0ID0gY29udGV4dFZtO1xuICBjbG9uZS5mbk9wdGlvbnMgPSBvcHRpb25zO1xuICB7XG4gICAgKGNsb25lLmRldnRvb2xzTWV0YSA9IGNsb25lLmRldnRvb2xzTWV0YSB8fCB7fSkucmVuZGVyQ29udGV4dCA9IHJlbmRlckNvbnRleHQ7XG4gIH1cbiAgaWYgKGRhdGEuc2xvdCkge1xuICAgIChjbG9uZS5kYXRhIHx8IChjbG9uZS5kYXRhID0ge30pKS5zbG90ID0gZGF0YS5zbG90O1xuICB9XG4gIHJldHVybiBjbG9uZVxufVxuXG5mdW5jdGlvbiBtZXJnZVByb3BzICh0bywgZnJvbSkge1xuICBmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuICAgIHRvW2NhbWVsaXplKGtleSldID0gZnJvbVtrZXldO1xuICB9XG59XG5cbi8qICAqL1xuXG4vKiAgKi9cblxuLyogICovXG5cbi8qICAqL1xuXG4vLyBpbmxpbmUgaG9va3MgdG8gYmUgaW52b2tlZCBvbiBjb21wb25lbnQgVk5vZGVzIGR1cmluZyBwYXRjaFxudmFyIGNvbXBvbmVudFZOb2RlSG9va3MgPSB7XG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQgKHZub2RlLCBoeWRyYXRpbmcpIHtcbiAgICBpZiAoXG4gICAgICB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSAmJlxuICAgICAgIXZub2RlLmNvbXBvbmVudEluc3RhbmNlLl9pc0Rlc3Ryb3llZCAmJlxuICAgICAgdm5vZGUuZGF0YS5rZWVwQWxpdmVcbiAgICApIHtcbiAgICAgIC8vIGtlcHQtYWxpdmUgY29tcG9uZW50cywgdHJlYXQgYXMgYSBwYXRjaFxuICAgICAgdmFyIG1vdW50ZWROb2RlID0gdm5vZGU7IC8vIHdvcmsgYXJvdW5kIGZsb3dcbiAgICAgIGNvbXBvbmVudFZOb2RlSG9va3MucHJlcGF0Y2gobW91bnRlZE5vZGUsIG1vdW50ZWROb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGNoaWxkID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZUZvclZub2RlKFxuICAgICAgICB2bm9kZSxcbiAgICAgICAgYWN0aXZlSW5zdGFuY2VcbiAgICAgICk7XG4gICAgICBjaGlsZC4kbW91bnQoaHlkcmF0aW5nID8gdm5vZGUuZWxtIDogdW5kZWZpbmVkLCBoeWRyYXRpbmcpO1xuICAgIH1cbiAgfSxcblxuICBwcmVwYXRjaDogZnVuY3Rpb24gcHJlcGF0Y2ggKG9sZFZub2RlLCB2bm9kZSkge1xuICAgIHZhciBvcHRpb25zID0gdm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgICB2YXIgY2hpbGQgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSA9IG9sZFZub2RlLmNvbXBvbmVudEluc3RhbmNlO1xuICAgIHVwZGF0ZUNoaWxkQ29tcG9uZW50KFxuICAgICAgY2hpbGQsXG4gICAgICBvcHRpb25zLnByb3BzRGF0YSwgLy8gdXBkYXRlZCBwcm9wc1xuICAgICAgb3B0aW9ucy5saXN0ZW5lcnMsIC8vIHVwZGF0ZWQgbGlzdGVuZXJzXG4gICAgICB2bm9kZSwgLy8gbmV3IHBhcmVudCB2bm9kZVxuICAgICAgb3B0aW9ucy5jaGlsZHJlbiAvLyBuZXcgY2hpbGRyZW5cbiAgICApO1xuICB9LFxuXG4gIGluc2VydDogZnVuY3Rpb24gaW5zZXJ0ICh2bm9kZSkge1xuICAgIHZhciBjb250ZXh0ID0gdm5vZGUuY29udGV4dDtcbiAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZTtcbiAgICBpZiAoIWNvbXBvbmVudEluc3RhbmNlLl9pc01vdW50ZWQpIHtcbiAgICAgIGNvbXBvbmVudEluc3RhbmNlLl9pc01vdW50ZWQgPSB0cnVlO1xuICAgICAgY2FsbEhvb2soY29tcG9uZW50SW5zdGFuY2UsICdtb3VudGVkJyk7XG4gICAgfVxuICAgIGlmICh2bm9kZS5kYXRhLmtlZXBBbGl2ZSkge1xuICAgICAgaWYgKGNvbnRleHQuX2lzTW91bnRlZCkge1xuICAgICAgICAvLyB2dWUtcm91dGVyIzEyMTJcbiAgICAgICAgLy8gRHVyaW5nIHVwZGF0ZXMsIGEga2VwdC1hbGl2ZSBjb21wb25lbnQncyBjaGlsZCBjb21wb25lbnRzIG1heVxuICAgICAgICAvLyBjaGFuZ2UsIHNvIGRpcmVjdGx5IHdhbGtpbmcgdGhlIHRyZWUgaGVyZSBtYXkgY2FsbCBhY3RpdmF0ZWQgaG9va3NcbiAgICAgICAgLy8gb24gaW5jb3JyZWN0IGNoaWxkcmVuLiBJbnN0ZWFkIHdlIHB1c2ggdGhlbSBpbnRvIGEgcXVldWUgd2hpY2ggd2lsbFxuICAgICAgICAvLyBiZSBwcm9jZXNzZWQgYWZ0ZXIgdGhlIHdob2xlIHBhdGNoIHByb2Nlc3MgZW5kZWQuXG4gICAgICAgIHF1ZXVlQWN0aXZhdGVkQ29tcG9uZW50KGNvbXBvbmVudEluc3RhbmNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjdGl2YXRlQ2hpbGRDb21wb25lbnQoY29tcG9uZW50SW5zdGFuY2UsIHRydWUgLyogZGlyZWN0ICovKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSAodm5vZGUpIHtcbiAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZTtcbiAgICBpZiAoIWNvbXBvbmVudEluc3RhbmNlLl9pc0Rlc3Ryb3llZCkge1xuICAgICAgaWYgKCF2bm9kZS5kYXRhLmtlZXBBbGl2ZSkge1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS4kZGVzdHJveSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KGNvbXBvbmVudEluc3RhbmNlLCB0cnVlIC8qIGRpcmVjdCAqLyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG52YXIgaG9va3NUb01lcmdlID0gT2JqZWN0LmtleXMoY29tcG9uZW50Vk5vZGVIb29rcyk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudCAoXG4gIEN0b3IsXG4gIGRhdGEsXG4gIGNvbnRleHQsXG4gIGNoaWxkcmVuLFxuICB0YWdcbikge1xuICBpZiAoaXNVbmRlZihDdG9yKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGJhc2VDdG9yID0gY29udGV4dC4kb3B0aW9ucy5fYmFzZTtcblxuICAvLyBwbGFpbiBvcHRpb25zIG9iamVjdDogdHVybiBpdCBpbnRvIGEgY29uc3RydWN0b3JcbiAgaWYgKGlzT2JqZWN0KEN0b3IpKSB7XG4gICAgQ3RvciA9IGJhc2VDdG9yLmV4dGVuZChDdG9yKTtcbiAgfVxuXG4gIC8vIGlmIGF0IHRoaXMgc3RhZ2UgaXQncyBub3QgYSBjb25zdHJ1Y3RvciBvciBhbiBhc3luYyBjb21wb25lbnQgZmFjdG9yeSxcbiAgLy8gcmVqZWN0LlxuICBpZiAodHlwZW9mIEN0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICB3YXJuKChcIkludmFsaWQgQ29tcG9uZW50IGRlZmluaXRpb246IFwiICsgKFN0cmluZyhDdG9yKSkpLCBjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBhc3luYyBjb21wb25lbnRcbiAgdmFyIGFzeW5jRmFjdG9yeTtcbiAgaWYgKGlzVW5kZWYoQ3Rvci5jaWQpKSB7XG4gICAgYXN5bmNGYWN0b3J5ID0gQ3RvcjtcbiAgICBDdG9yID0gcmVzb2x2ZUFzeW5jQ29tcG9uZW50KGFzeW5jRmFjdG9yeSwgYmFzZUN0b3IpO1xuICAgIGlmIChDdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIHJldHVybiBhIHBsYWNlaG9sZGVyIG5vZGUgZm9yIGFzeW5jIGNvbXBvbmVudCwgd2hpY2ggaXMgcmVuZGVyZWRcbiAgICAgIC8vIGFzIGEgY29tbWVudCBub2RlIGJ1dCBwcmVzZXJ2ZXMgYWxsIHRoZSByYXcgaW5mb3JtYXRpb24gZm9yIHRoZSBub2RlLlxuICAgICAgLy8gdGhlIGluZm9ybWF0aW9uIHdpbGwgYmUgdXNlZCBmb3IgYXN5bmMgc2VydmVyLXJlbmRlcmluZyBhbmQgaHlkcmF0aW9uLlxuICAgICAgcmV0dXJuIGNyZWF0ZUFzeW5jUGxhY2Vob2xkZXIoXG4gICAgICAgIGFzeW5jRmFjdG9yeSxcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgIHRhZ1xuICAgICAgKVxuICAgIH1cbiAgfVxuXG4gIGRhdGEgPSBkYXRhIHx8IHt9O1xuXG4gIC8vIHJlc29sdmUgY29uc3RydWN0b3Igb3B0aW9ucyBpbiBjYXNlIGdsb2JhbCBtaXhpbnMgYXJlIGFwcGxpZWQgYWZ0ZXJcbiAgLy8gY29tcG9uZW50IGNvbnN0cnVjdG9yIGNyZWF0aW9uXG4gIHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnMoQ3Rvcik7XG5cbiAgLy8gdHJhbnNmb3JtIGNvbXBvbmVudCB2LW1vZGVsIGRhdGEgaW50byBwcm9wcyAmIGV2ZW50c1xuICBpZiAoaXNEZWYoZGF0YS5tb2RlbCkpIHtcbiAgICB0cmFuc2Zvcm1Nb2RlbChDdG9yLm9wdGlvbnMsIGRhdGEpO1xuICB9XG5cbiAgLy8gZXh0cmFjdCBwcm9wc1xuICB2YXIgcHJvcHNEYXRhID0gZXh0cmFjdFByb3BzRnJvbVZOb2RlRGF0YShkYXRhLCBDdG9yLCB0YWcpO1xuXG4gIC8vIGZ1bmN0aW9uYWwgY29tcG9uZW50XG4gIGlmIChpc1RydWUoQ3Rvci5vcHRpb25zLmZ1bmN0aW9uYWwpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUZ1bmN0aW9uYWxDb21wb25lbnQoQ3RvciwgcHJvcHNEYXRhLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbilcbiAgfVxuXG4gIC8vIGV4dHJhY3QgbGlzdGVuZXJzLCBzaW5jZSB0aGVzZSBuZWVkcyB0byBiZSB0cmVhdGVkIGFzXG4gIC8vIGNoaWxkIGNvbXBvbmVudCBsaXN0ZW5lcnMgaW5zdGVhZCBvZiBET00gbGlzdGVuZXJzXG4gIHZhciBsaXN0ZW5lcnMgPSBkYXRhLm9uO1xuICAvLyByZXBsYWNlIHdpdGggbGlzdGVuZXJzIHdpdGggLm5hdGl2ZSBtb2RpZmllclxuICAvLyBzbyBpdCBnZXRzIHByb2Nlc3NlZCBkdXJpbmcgcGFyZW50IGNvbXBvbmVudCBwYXRjaC5cbiAgZGF0YS5vbiA9IGRhdGEubmF0aXZlT247XG5cbiAgaWYgKGlzVHJ1ZShDdG9yLm9wdGlvbnMuYWJzdHJhY3QpKSB7XG4gICAgLy8gYWJzdHJhY3QgY29tcG9uZW50cyBkbyBub3Qga2VlcCBhbnl0aGluZ1xuICAgIC8vIG90aGVyIHRoYW4gcHJvcHMgJiBsaXN0ZW5lcnMgJiBzbG90XG5cbiAgICAvLyB3b3JrIGFyb3VuZCBmbG93XG4gICAgdmFyIHNsb3QgPSBkYXRhLnNsb3Q7XG4gICAgZGF0YSA9IHt9O1xuICAgIGlmIChzbG90KSB7XG4gICAgICBkYXRhLnNsb3QgPSBzbG90O1xuICAgIH1cbiAgfVxuXG4gIC8vIGluc3RhbGwgY29tcG9uZW50IG1hbmFnZW1lbnQgaG9va3Mgb250byB0aGUgcGxhY2Vob2xkZXIgbm9kZVxuICBpbnN0YWxsQ29tcG9uZW50SG9va3MoZGF0YSk7XG5cbiAgLy8gcmV0dXJuIGEgcGxhY2Vob2xkZXIgdm5vZGVcbiAgdmFyIG5hbWUgPSBDdG9yLm9wdGlvbnMubmFtZSB8fCB0YWc7XG4gIHZhciB2bm9kZSA9IG5ldyBWTm9kZShcbiAgICAoXCJ2dWUtY29tcG9uZW50LVwiICsgKEN0b3IuY2lkKSArIChuYW1lID8gKFwiLVwiICsgbmFtZSkgOiAnJykpLFxuICAgIGRhdGEsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGNvbnRleHQsXG4gICAgeyBDdG9yOiBDdG9yLCBwcm9wc0RhdGE6IHByb3BzRGF0YSwgbGlzdGVuZXJzOiBsaXN0ZW5lcnMsIHRhZzogdGFnLCBjaGlsZHJlbjogY2hpbGRyZW4gfSxcbiAgICBhc3luY0ZhY3RvcnlcbiAgKTtcblxuICByZXR1cm4gdm5vZGVcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50SW5zdGFuY2VGb3JWbm9kZSAoXG4gIHZub2RlLCAvLyB3ZSBrbm93IGl0J3MgTW91bnRlZENvbXBvbmVudFZOb2RlIGJ1dCBmbG93IGRvZXNuJ3RcbiAgcGFyZW50IC8vIGFjdGl2ZUluc3RhbmNlIGluIGxpZmVjeWNsZSBzdGF0ZVxuKSB7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIF9pc0NvbXBvbmVudDogdHJ1ZSxcbiAgICBfcGFyZW50Vm5vZGU6IHZub2RlLFxuICAgIHBhcmVudDogcGFyZW50XG4gIH07XG4gIC8vIGNoZWNrIGlubGluZS10ZW1wbGF0ZSByZW5kZXIgZnVuY3Rpb25zXG4gIHZhciBpbmxpbmVUZW1wbGF0ZSA9IHZub2RlLmRhdGEuaW5saW5lVGVtcGxhdGU7XG4gIGlmIChpc0RlZihpbmxpbmVUZW1wbGF0ZSkpIHtcbiAgICBvcHRpb25zLnJlbmRlciA9IGlubGluZVRlbXBsYXRlLnJlbmRlcjtcbiAgICBvcHRpb25zLnN0YXRpY1JlbmRlckZucyA9IGlubGluZVRlbXBsYXRlLnN0YXRpY1JlbmRlckZucztcbiAgfVxuICByZXR1cm4gbmV3IHZub2RlLmNvbXBvbmVudE9wdGlvbnMuQ3RvcihvcHRpb25zKVxufVxuXG5mdW5jdGlvbiBpbnN0YWxsQ29tcG9uZW50SG9va3MgKGRhdGEpIHtcbiAgdmFyIGhvb2tzID0gZGF0YS5ob29rIHx8IChkYXRhLmhvb2sgPSB7fSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaG9va3NUb01lcmdlLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleSA9IGhvb2tzVG9NZXJnZVtpXTtcbiAgICB2YXIgZXhpc3RpbmcgPSBob29rc1trZXldO1xuICAgIHZhciB0b01lcmdlID0gY29tcG9uZW50Vk5vZGVIb29rc1trZXldO1xuICAgIGlmIChleGlzdGluZyAhPT0gdG9NZXJnZSAmJiAhKGV4aXN0aW5nICYmIGV4aXN0aW5nLl9tZXJnZWQpKSB7XG4gICAgICBob29rc1trZXldID0gZXhpc3RpbmcgPyBtZXJnZUhvb2skMSh0b01lcmdlLCBleGlzdGluZykgOiB0b01lcmdlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZUhvb2skMSAoZjEsIGYyKSB7XG4gIHZhciBtZXJnZWQgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIC8vIGZsb3cgY29tcGxhaW5zIGFib3V0IGV4dHJhIGFyZ3Mgd2hpY2ggaXMgd2h5IHdlIHVzZSBhbnlcbiAgICBmMShhLCBiKTtcbiAgICBmMihhLCBiKTtcbiAgfTtcbiAgbWVyZ2VkLl9tZXJnZWQgPSB0cnVlO1xuICByZXR1cm4gbWVyZ2VkXG59XG5cbi8vIHRyYW5zZm9ybSBjb21wb25lbnQgdi1tb2RlbCBpbmZvICh2YWx1ZSBhbmQgY2FsbGJhY2spIGludG9cbi8vIHByb3AgYW5kIGV2ZW50IGhhbmRsZXIgcmVzcGVjdGl2ZWx5LlxuZnVuY3Rpb24gdHJhbnNmb3JtTW9kZWwgKG9wdGlvbnMsIGRhdGEpIHtcbiAgdmFyIHByb3AgPSAob3B0aW9ucy5tb2RlbCAmJiBvcHRpb25zLm1vZGVsLnByb3ApIHx8ICd2YWx1ZSc7XG4gIHZhciBldmVudCA9IChvcHRpb25zLm1vZGVsICYmIG9wdGlvbnMubW9kZWwuZXZlbnQpIHx8ICdpbnB1dCdcbiAgOyhkYXRhLmF0dHJzIHx8IChkYXRhLmF0dHJzID0ge30pKVtwcm9wXSA9IGRhdGEubW9kZWwudmFsdWU7XG4gIHZhciBvbiA9IGRhdGEub24gfHwgKGRhdGEub24gPSB7fSk7XG4gIHZhciBleGlzdGluZyA9IG9uW2V2ZW50XTtcbiAgdmFyIGNhbGxiYWNrID0gZGF0YS5tb2RlbC5jYWxsYmFjaztcbiAgaWYgKGlzRGVmKGV4aXN0aW5nKSkge1xuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoZXhpc3RpbmcpXG4gICAgICAgID8gZXhpc3RpbmcuaW5kZXhPZihjYWxsYmFjaykgPT09IC0xXG4gICAgICAgIDogZXhpc3RpbmcgIT09IGNhbGxiYWNrXG4gICAgKSB7XG4gICAgICBvbltldmVudF0gPSBbY2FsbGJhY2tdLmNvbmNhdChleGlzdGluZyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG9uW2V2ZW50XSA9IGNhbGxiYWNrO1xuICB9XG59XG5cbi8qICAqL1xuXG52YXIgU0lNUExFX05PUk1BTElaRSA9IDE7XG52YXIgQUxXQVlTX05PUk1BTElaRSA9IDI7XG5cbi8vIHdyYXBwZXIgZnVuY3Rpb24gZm9yIHByb3ZpZGluZyBhIG1vcmUgZmxleGlibGUgaW50ZXJmYWNlXG4vLyB3aXRob3V0IGdldHRpbmcgeWVsbGVkIGF0IGJ5IGZsb3dcbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQgKFxuICBjb250ZXh0LFxuICB0YWcsXG4gIGRhdGEsXG4gIGNoaWxkcmVuLFxuICBub3JtYWxpemF0aW9uVHlwZSxcbiAgYWx3YXlzTm9ybWFsaXplXG4pIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkgfHwgaXNQcmltaXRpdmUoZGF0YSkpIHtcbiAgICBub3JtYWxpemF0aW9uVHlwZSA9IGNoaWxkcmVuO1xuICAgIGNoaWxkcmVuID0gZGF0YTtcbiAgICBkYXRhID0gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChpc1RydWUoYWx3YXlzTm9ybWFsaXplKSkge1xuICAgIG5vcm1hbGl6YXRpb25UeXBlID0gQUxXQVlTX05PUk1BTElaRTtcbiAgfVxuICByZXR1cm4gX2NyZWF0ZUVsZW1lbnQoY29udGV4dCwgdGFnLCBkYXRhLCBjaGlsZHJlbiwgbm9ybWFsaXphdGlvblR5cGUpXG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVFbGVtZW50IChcbiAgY29udGV4dCxcbiAgdGFnLFxuICBkYXRhLFxuICBjaGlsZHJlbixcbiAgbm9ybWFsaXphdGlvblR5cGVcbikge1xuICBpZiAoaXNEZWYoZGF0YSkgJiYgaXNEZWYoKGRhdGEpLl9fb2JfXykpIHtcbiAgICB3YXJuKFxuICAgICAgXCJBdm9pZCB1c2luZyBvYnNlcnZlZCBkYXRhIG9iamVjdCBhcyB2bm9kZSBkYXRhOiBcIiArIChKU09OLnN0cmluZ2lmeShkYXRhKSkgKyBcIlxcblwiICtcbiAgICAgICdBbHdheXMgY3JlYXRlIGZyZXNoIHZub2RlIGRhdGEgb2JqZWN0cyBpbiBlYWNoIHJlbmRlciEnLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUVtcHR5Vk5vZGUoKVxuICB9XG4gIC8vIG9iamVjdCBzeW50YXggaW4gdi1iaW5kXG4gIGlmIChpc0RlZihkYXRhKSAmJiBpc0RlZihkYXRhLmlzKSkge1xuICAgIHRhZyA9IGRhdGEuaXM7XG4gIH1cbiAgaWYgKCF0YWcpIHtcbiAgICAvLyBpbiBjYXNlIG9mIGNvbXBvbmVudCA6aXMgc2V0IHRvIGZhbHN5IHZhbHVlXG4gICAgcmV0dXJuIGNyZWF0ZUVtcHR5Vk5vZGUoKVxuICB9XG4gIC8vIHdhcm4gYWdhaW5zdCBub24tcHJpbWl0aXZlIGtleVxuICBpZiAoaXNEZWYoZGF0YSkgJiYgaXNEZWYoZGF0YS5rZXkpICYmICFpc1ByaW1pdGl2ZShkYXRhLmtleSlcbiAgKSB7XG4gICAge1xuICAgICAgd2FybihcbiAgICAgICAgJ0F2b2lkIHVzaW5nIG5vbi1wcmltaXRpdmUgdmFsdWUgYXMga2V5LCAnICtcbiAgICAgICAgJ3VzZSBzdHJpbmcvbnVtYmVyIHZhbHVlIGluc3RlYWQuJyxcbiAgICAgICAgY29udGV4dFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgLy8gc3VwcG9ydCBzaW5nbGUgZnVuY3Rpb24gY2hpbGRyZW4gYXMgZGVmYXVsdCBzY29wZWQgc2xvdFxuICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikgJiZcbiAgICB0eXBlb2YgY2hpbGRyZW5bMF0gPT09ICdmdW5jdGlvbidcbiAgKSB7XG4gICAgZGF0YSA9IGRhdGEgfHwge307XG4gICAgZGF0YS5zY29wZWRTbG90cyA9IHsgZGVmYXVsdDogY2hpbGRyZW5bMF0gfTtcbiAgICBjaGlsZHJlbi5sZW5ndGggPSAwO1xuICB9XG4gIGlmIChub3JtYWxpemF0aW9uVHlwZSA9PT0gQUxXQVlTX05PUk1BTElaRSkge1xuICAgIGNoaWxkcmVuID0gbm9ybWFsaXplQ2hpbGRyZW4oY2hpbGRyZW4pO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6YXRpb25UeXBlID09PSBTSU1QTEVfTk9STUFMSVpFKSB7XG4gICAgY2hpbGRyZW4gPSBzaW1wbGVOb3JtYWxpemVDaGlsZHJlbihjaGlsZHJlbik7XG4gIH1cbiAgdmFyIHZub2RlLCBucztcbiAgaWYgKHR5cGVvZiB0YWcgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIEN0b3I7XG4gICAgbnMgPSAoY29udGV4dC4kdm5vZGUgJiYgY29udGV4dC4kdm5vZGUubnMpIHx8IGNvbmZpZy5nZXRUYWdOYW1lc3BhY2UodGFnKTtcbiAgICBpZiAoY29uZmlnLmlzUmVzZXJ2ZWRUYWcodGFnKSkge1xuICAgICAgLy8gcGxhdGZvcm0gYnVpbHQtaW4gZWxlbWVudHNcbiAgICAgIGlmIChpc0RlZihkYXRhKSAmJiBpc0RlZihkYXRhLm5hdGl2ZU9uKSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIChcIlRoZSAubmF0aXZlIG1vZGlmaWVyIGZvciB2LW9uIGlzIG9ubHkgdmFsaWQgb24gY29tcG9uZW50cyBidXQgaXQgd2FzIHVzZWQgb24gPFwiICsgdGFnICsgXCI+LlwiKSxcbiAgICAgICAgICBjb250ZXh0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2bm9kZSA9IG5ldyBWTm9kZShcbiAgICAgICAgY29uZmlnLnBhcnNlUGxhdGZvcm1UYWdOYW1lKHRhZyksIGRhdGEsIGNoaWxkcmVuLFxuICAgICAgICB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCghZGF0YSB8fCAhZGF0YS5wcmUpICYmIGlzRGVmKEN0b3IgPSByZXNvbHZlQXNzZXQoY29udGV4dC4kb3B0aW9ucywgJ2NvbXBvbmVudHMnLCB0YWcpKSkge1xuICAgICAgLy8gY29tcG9uZW50XG4gICAgICB2bm9kZSA9IGNyZWF0ZUNvbXBvbmVudChDdG9yLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbiwgdGFnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdW5rbm93biBvciB1bmxpc3RlZCBuYW1lc3BhY2VkIGVsZW1lbnRzXG4gICAgICAvLyBjaGVjayBhdCBydW50aW1lIGJlY2F1c2UgaXQgbWF5IGdldCBhc3NpZ25lZCBhIG5hbWVzcGFjZSB3aGVuIGl0c1xuICAgICAgLy8gcGFyZW50IG5vcm1hbGl6ZXMgY2hpbGRyZW5cbiAgICAgIHZub2RlID0gbmV3IFZOb2RlKFxuICAgICAgICB0YWcsIGRhdGEsIGNoaWxkcmVuLFxuICAgICAgICB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gZGlyZWN0IGNvbXBvbmVudCBvcHRpb25zIC8gY29uc3RydWN0b3JcbiAgICB2bm9kZSA9IGNyZWF0ZUNvbXBvbmVudCh0YWcsIGRhdGEsIGNvbnRleHQsIGNoaWxkcmVuKTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheSh2bm9kZSkpIHtcbiAgICByZXR1cm4gdm5vZGVcbiAgfSBlbHNlIGlmIChpc0RlZih2bm9kZSkpIHtcbiAgICBpZiAoaXNEZWYobnMpKSB7IGFwcGx5TlModm5vZGUsIG5zKTsgfVxuICAgIGlmIChpc0RlZihkYXRhKSkgeyByZWdpc3RlckRlZXBCaW5kaW5ncyhkYXRhKTsgfVxuICAgIHJldHVybiB2bm9kZVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBjcmVhdGVFbXB0eVZOb2RlKClcbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBseU5TICh2bm9kZSwgbnMsIGZvcmNlKSB7XG4gIHZub2RlLm5zID0gbnM7XG4gIGlmICh2bm9kZS50YWcgPT09ICdmb3JlaWduT2JqZWN0Jykge1xuICAgIC8vIHVzZSBkZWZhdWx0IG5hbWVzcGFjZSBpbnNpZGUgZm9yZWlnbk9iamVjdFxuICAgIG5zID0gdW5kZWZpbmVkO1xuICAgIGZvcmNlID0gdHJ1ZTtcbiAgfVxuICBpZiAoaXNEZWYodm5vZGUuY2hpbGRyZW4pKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB2bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZCA9IHZub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgaWYgKGlzRGVmKGNoaWxkLnRhZykgJiYgKFxuICAgICAgICBpc1VuZGVmKGNoaWxkLm5zKSB8fCAoaXNUcnVlKGZvcmNlKSAmJiBjaGlsZC50YWcgIT09ICdzdmcnKSkpIHtcbiAgICAgICAgYXBwbHlOUyhjaGlsZCwgbnMsIGZvcmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gcmVmICM1MzE4XG4vLyBuZWNlc3NhcnkgdG8gZW5zdXJlIHBhcmVudCByZS1yZW5kZXIgd2hlbiBkZWVwIGJpbmRpbmdzIGxpa2UgOnN0eWxlIGFuZFxuLy8gOmNsYXNzIGFyZSB1c2VkIG9uIHNsb3Qgbm9kZXNcbmZ1bmN0aW9uIHJlZ2lzdGVyRGVlcEJpbmRpbmdzIChkYXRhKSB7XG4gIGlmIChpc09iamVjdChkYXRhLnN0eWxlKSkge1xuICAgIHRyYXZlcnNlKGRhdGEuc3R5bGUpO1xuICB9XG4gIGlmIChpc09iamVjdChkYXRhLmNsYXNzKSkge1xuICAgIHRyYXZlcnNlKGRhdGEuY2xhc3MpO1xuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0UmVuZGVyICh2bSkge1xuICB2bS5fdm5vZGUgPSBudWxsOyAvLyB0aGUgcm9vdCBvZiB0aGUgY2hpbGQgdHJlZVxuICB2bS5fc3RhdGljVHJlZXMgPSBudWxsOyAvLyB2LW9uY2UgY2FjaGVkIHRyZWVzXG4gIHZhciBvcHRpb25zID0gdm0uJG9wdGlvbnM7XG4gIHZhciBwYXJlbnRWbm9kZSA9IHZtLiR2bm9kZSA9IG9wdGlvbnMuX3BhcmVudFZub2RlOyAvLyB0aGUgcGxhY2Vob2xkZXIgbm9kZSBpbiBwYXJlbnQgdHJlZVxuICB2YXIgcmVuZGVyQ29udGV4dCA9IHBhcmVudFZub2RlICYmIHBhcmVudFZub2RlLmNvbnRleHQ7XG4gIHZtLiRzbG90cyA9IHJlc29sdmVTbG90cyhvcHRpb25zLl9yZW5kZXJDaGlsZHJlbiwgcmVuZGVyQ29udGV4dCk7XG4gIHZtLiRzY29wZWRTbG90cyA9IGVtcHR5T2JqZWN0O1xuICAvLyBiaW5kIHRoZSBjcmVhdGVFbGVtZW50IGZuIHRvIHRoaXMgaW5zdGFuY2VcbiAgLy8gc28gdGhhdCB3ZSBnZXQgcHJvcGVyIHJlbmRlciBjb250ZXh0IGluc2lkZSBpdC5cbiAgLy8gYXJncyBvcmRlcjogdGFnLCBkYXRhLCBjaGlsZHJlbiwgbm9ybWFsaXphdGlvblR5cGUsIGFsd2F5c05vcm1hbGl6ZVxuICAvLyBpbnRlcm5hbCB2ZXJzaW9uIGlzIHVzZWQgYnkgcmVuZGVyIGZ1bmN0aW9ucyBjb21waWxlZCBmcm9tIHRlbXBsYXRlc1xuICB2bS5fYyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7IHJldHVybiBjcmVhdGVFbGVtZW50KHZtLCBhLCBiLCBjLCBkLCBmYWxzZSk7IH07XG4gIC8vIG5vcm1hbGl6YXRpb24gaXMgYWx3YXlzIGFwcGxpZWQgZm9yIHRoZSBwdWJsaWMgdmVyc2lvbiwgdXNlZCBpblxuICAvLyB1c2VyLXdyaXR0ZW4gcmVuZGVyIGZ1bmN0aW9ucy5cbiAgdm0uJGNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAoYSwgYiwgYywgZCkgeyByZXR1cm4gY3JlYXRlRWxlbWVudCh2bSwgYSwgYiwgYywgZCwgdHJ1ZSk7IH07XG5cbiAgLy8gJGF0dHJzICYgJGxpc3RlbmVycyBhcmUgZXhwb3NlZCBmb3IgZWFzaWVyIEhPQyBjcmVhdGlvbi5cbiAgLy8gdGhleSBuZWVkIHRvIGJlIHJlYWN0aXZlIHNvIHRoYXQgSE9DcyB1c2luZyB0aGVtIGFyZSBhbHdheXMgdXBkYXRlZFxuICB2YXIgcGFyZW50RGF0YSA9IHBhcmVudFZub2RlICYmIHBhcmVudFZub2RlLmRhdGE7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAge1xuICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCAnJGF0dHJzJywgcGFyZW50RGF0YSAmJiBwYXJlbnREYXRhLmF0dHJzIHx8IGVtcHR5T2JqZWN0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAhaXNVcGRhdGluZ0NoaWxkQ29tcG9uZW50ICYmIHdhcm4oXCIkYXR0cnMgaXMgcmVhZG9ubHkuXCIsIHZtKTtcbiAgICB9LCB0cnVlKTtcbiAgICBkZWZpbmVSZWFjdGl2ZSQkMSh2bSwgJyRsaXN0ZW5lcnMnLCBvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnMgfHwgZW1wdHlPYmplY3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICFpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQgJiYgd2FybihcIiRsaXN0ZW5lcnMgaXMgcmVhZG9ubHkuXCIsIHZtKTtcbiAgICB9LCB0cnVlKTtcbiAgfVxufVxuXG52YXIgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gbnVsbDtcblxuZnVuY3Rpb24gcmVuZGVyTWl4aW4gKFZ1ZSkge1xuICAvLyBpbnN0YWxsIHJ1bnRpbWUgY29udmVuaWVuY2UgaGVscGVyc1xuICBpbnN0YWxsUmVuZGVySGVscGVycyhWdWUucHJvdG90eXBlKTtcblxuICBWdWUucHJvdG90eXBlLiRuZXh0VGljayA9IGZ1bmN0aW9uIChmbikge1xuICAgIHJldHVybiBuZXh0VGljayhmbiwgdGhpcylcbiAgfTtcblxuICBWdWUucHJvdG90eXBlLl9yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICB2YXIgcmVmID0gdm0uJG9wdGlvbnM7XG4gICAgdmFyIHJlbmRlciA9IHJlZi5yZW5kZXI7XG4gICAgdmFyIF9wYXJlbnRWbm9kZSA9IHJlZi5fcGFyZW50Vm5vZGU7XG5cbiAgICBpZiAoX3BhcmVudFZub2RlKSB7XG4gICAgICB2bS4kc2NvcGVkU2xvdHMgPSBub3JtYWxpemVTY29wZWRTbG90cyhcbiAgICAgICAgX3BhcmVudFZub2RlLmRhdGEuc2NvcGVkU2xvdHMsXG4gICAgICAgIHZtLiRzbG90cyxcbiAgICAgICAgdm0uJHNjb3BlZFNsb3RzXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIHNldCBwYXJlbnQgdm5vZGUuIHRoaXMgYWxsb3dzIHJlbmRlciBmdW5jdGlvbnMgdG8gaGF2ZSBhY2Nlc3NcbiAgICAvLyB0byB0aGUgZGF0YSBvbiB0aGUgcGxhY2Vob2xkZXIgbm9kZS5cbiAgICB2bS4kdm5vZGUgPSBfcGFyZW50Vm5vZGU7XG4gICAgLy8gcmVuZGVyIHNlbGZcbiAgICB2YXIgdm5vZGU7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBtYWludGFpbiBhIHN0YWNrIGJlY2F1c2UgYWxsIHJlbmRlciBmbnMgYXJlIGNhbGxlZFxuICAgICAgLy8gc2VwYXJhdGVseSBmcm9tIG9uZSBhbm90aGVyLiBOZXN0ZWQgY29tcG9uZW50J3MgcmVuZGVyIGZucyBhcmUgY2FsbGVkXG4gICAgICAvLyB3aGVuIHBhcmVudCBjb21wb25lbnQgaXMgcGF0Y2hlZC5cbiAgICAgIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IHZtO1xuICAgICAgdm5vZGUgPSByZW5kZXIuY2FsbCh2bS5fcmVuZGVyUHJveHksIHZtLiRjcmVhdGVFbGVtZW50KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBoYW5kbGVFcnJvcihlLCB2bSwgXCJyZW5kZXJcIik7XG4gICAgICAvLyByZXR1cm4gZXJyb3IgcmVuZGVyIHJlc3VsdCxcbiAgICAgIC8vIG9yIHByZXZpb3VzIHZub2RlIHRvIHByZXZlbnQgcmVuZGVyIGVycm9yIGNhdXNpbmcgYmxhbmsgY29tcG9uZW50XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHZtLiRvcHRpb25zLnJlbmRlckVycm9yKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdm5vZGUgPSB2bS4kb3B0aW9ucy5yZW5kZXJFcnJvci5jYWxsKHZtLl9yZW5kZXJQcm94eSwgdm0uJGNyZWF0ZUVsZW1lbnQsIGUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaGFuZGxlRXJyb3IoZSwgdm0sIFwicmVuZGVyRXJyb3JcIik7XG4gICAgICAgICAgdm5vZGUgPSB2bS5fdm5vZGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZub2RlID0gdm0uX3Zub2RlO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UgPSBudWxsO1xuICAgIH1cbiAgICAvLyBpZiB0aGUgcmV0dXJuZWQgYXJyYXkgY29udGFpbnMgb25seSBhIHNpbmdsZSBub2RlLCBhbGxvdyBpdFxuICAgIGlmIChBcnJheS5pc0FycmF5KHZub2RlKSAmJiB2bm9kZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZub2RlID0gdm5vZGVbMF07XG4gICAgfVxuICAgIC8vIHJldHVybiBlbXB0eSB2bm9kZSBpbiBjYXNlIHRoZSByZW5kZXIgZnVuY3Rpb24gZXJyb3JlZCBvdXRcbiAgICBpZiAoISh2bm9kZSBpbnN0YW5jZW9mIFZOb2RlKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodm5vZGUpKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgJ011bHRpcGxlIHJvb3Qgbm9kZXMgcmV0dXJuZWQgZnJvbSByZW5kZXIgZnVuY3Rpb24uIFJlbmRlciBmdW5jdGlvbiAnICtcbiAgICAgICAgICAnc2hvdWxkIHJldHVybiBhIHNpbmdsZSByb290IG5vZGUuJyxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdm5vZGUgPSBjcmVhdGVFbXB0eVZOb2RlKCk7XG4gICAgfVxuICAgIC8vIHNldCBwYXJlbnRcbiAgICB2bm9kZS5wYXJlbnQgPSBfcGFyZW50Vm5vZGU7XG4gICAgcmV0dXJuIHZub2RlXG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBlbnN1cmVDdG9yIChjb21wLCBiYXNlKSB7XG4gIGlmIChcbiAgICBjb21wLl9fZXNNb2R1bGUgfHxcbiAgICAoaGFzU3ltYm9sICYmIGNvbXBbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ01vZHVsZScpXG4gICkge1xuICAgIGNvbXAgPSBjb21wLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KGNvbXApXG4gICAgPyBiYXNlLmV4dGVuZChjb21wKVxuICAgIDogY29tcFxufVxuXG5mdW5jdGlvbiBjcmVhdGVBc3luY1BsYWNlaG9sZGVyIChcbiAgZmFjdG9yeSxcbiAgZGF0YSxcbiAgY29udGV4dCxcbiAgY2hpbGRyZW4sXG4gIHRhZ1xuKSB7XG4gIHZhciBub2RlID0gY3JlYXRlRW1wdHlWTm9kZSgpO1xuICBub2RlLmFzeW5jRmFjdG9yeSA9IGZhY3Rvcnk7XG4gIG5vZGUuYXN5bmNNZXRhID0geyBkYXRhOiBkYXRhLCBjb250ZXh0OiBjb250ZXh0LCBjaGlsZHJlbjogY2hpbGRyZW4sIHRhZzogdGFnIH07XG4gIHJldHVybiBub2RlXG59XG5cbmZ1bmN0aW9uIHJlc29sdmVBc3luY0NvbXBvbmVudCAoXG4gIGZhY3RvcnksXG4gIGJhc2VDdG9yXG4pIHtcbiAgaWYgKGlzVHJ1ZShmYWN0b3J5LmVycm9yKSAmJiBpc0RlZihmYWN0b3J5LmVycm9yQ29tcCkpIHtcbiAgICByZXR1cm4gZmFjdG9yeS5lcnJvckNvbXBcbiAgfVxuXG4gIGlmIChpc0RlZihmYWN0b3J5LnJlc29sdmVkKSkge1xuICAgIHJldHVybiBmYWN0b3J5LnJlc29sdmVkXG4gIH1cblxuICB2YXIgb3duZXIgPSBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2U7XG4gIGlmIChvd25lciAmJiBpc0RlZihmYWN0b3J5Lm93bmVycykgJiYgZmFjdG9yeS5vd25lcnMuaW5kZXhPZihvd25lcikgPT09IC0xKSB7XG4gICAgLy8gYWxyZWFkeSBwZW5kaW5nXG4gICAgZmFjdG9yeS5vd25lcnMucHVzaChvd25lcik7XG4gIH1cblxuICBpZiAoaXNUcnVlKGZhY3RvcnkubG9hZGluZykgJiYgaXNEZWYoZmFjdG9yeS5sb2FkaW5nQ29tcCkpIHtcbiAgICByZXR1cm4gZmFjdG9yeS5sb2FkaW5nQ29tcFxuICB9XG5cbiAgaWYgKG93bmVyICYmICFpc0RlZihmYWN0b3J5Lm93bmVycykpIHtcbiAgICB2YXIgb3duZXJzID0gZmFjdG9yeS5vd25lcnMgPSBbb3duZXJdO1xuICAgIHZhciBzeW5jID0gdHJ1ZTtcbiAgICB2YXIgdGltZXJMb2FkaW5nID0gbnVsbDtcbiAgICB2YXIgdGltZXJUaW1lb3V0ID0gbnVsbFxuXG4gICAgOyhvd25lcikuJG9uKCdob29rOmRlc3Ryb3llZCcsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlbW92ZShvd25lcnMsIG93bmVyKTsgfSk7XG5cbiAgICB2YXIgZm9yY2VSZW5kZXIgPSBmdW5jdGlvbiAocmVuZGVyQ29tcGxldGVkKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG93bmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgKG93bmVyc1tpXSkuJGZvcmNlVXBkYXRlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZW5kZXJDb21wbGV0ZWQpIHtcbiAgICAgICAgb3duZXJzLmxlbmd0aCA9IDA7XG4gICAgICAgIGlmICh0aW1lckxvYWRpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXJMb2FkaW5nKTtcbiAgICAgICAgICB0aW1lckxvYWRpbmcgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lclRpbWVvdXQgIT09IG51bGwpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXJUaW1lb3V0KTtcbiAgICAgICAgICB0aW1lclRpbWVvdXQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciByZXNvbHZlID0gb25jZShmdW5jdGlvbiAocmVzKSB7XG4gICAgICAvLyBjYWNoZSByZXNvbHZlZFxuICAgICAgZmFjdG9yeS5yZXNvbHZlZCA9IGVuc3VyZUN0b3IocmVzLCBiYXNlQ3Rvcik7XG4gICAgICAvLyBpbnZva2UgY2FsbGJhY2tzIG9ubHkgaWYgdGhpcyBpcyBub3QgYSBzeW5jaHJvbm91cyByZXNvbHZlXG4gICAgICAvLyAoYXN5bmMgcmVzb2x2ZXMgYXJlIHNoaW1tZWQgYXMgc3luY2hyb25vdXMgZHVyaW5nIFNTUilcbiAgICAgIGlmICghc3luYykge1xuICAgICAgICBmb3JjZVJlbmRlcih0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG93bmVycy5sZW5ndGggPSAwO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIHJlamVjdCA9IG9uY2UoZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgd2FybihcbiAgICAgICAgXCJGYWlsZWQgdG8gcmVzb2x2ZSBhc3luYyBjb21wb25lbnQ6IFwiICsgKFN0cmluZyhmYWN0b3J5KSkgK1xuICAgICAgICAocmVhc29uID8gKFwiXFxuUmVhc29uOiBcIiArIHJlYXNvbikgOiAnJylcbiAgICAgICk7XG4gICAgICBpZiAoaXNEZWYoZmFjdG9yeS5lcnJvckNvbXApKSB7XG4gICAgICAgIGZhY3RvcnkuZXJyb3IgPSB0cnVlO1xuICAgICAgICBmb3JjZVJlbmRlcih0cnVlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciByZXMgPSBmYWN0b3J5KHJlc29sdmUsIHJlamVjdCk7XG5cbiAgICBpZiAoaXNPYmplY3QocmVzKSkge1xuICAgICAgaWYgKGlzUHJvbWlzZShyZXMpKSB7XG4gICAgICAgIC8vICgpID0+IFByb21pc2VcbiAgICAgICAgaWYgKGlzVW5kZWYoZmFjdG9yeS5yZXNvbHZlZCkpIHtcbiAgICAgICAgICByZXMudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzUHJvbWlzZShyZXMuY29tcG9uZW50KSkge1xuICAgICAgICByZXMuY29tcG9uZW50LnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcblxuICAgICAgICBpZiAoaXNEZWYocmVzLmVycm9yKSkge1xuICAgICAgICAgIGZhY3RvcnkuZXJyb3JDb21wID0gZW5zdXJlQ3RvcihyZXMuZXJyb3IsIGJhc2VDdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0RlZihyZXMubG9hZGluZykpIHtcbiAgICAgICAgICBmYWN0b3J5LmxvYWRpbmdDb21wID0gZW5zdXJlQ3RvcihyZXMubG9hZGluZywgYmFzZUN0b3IpO1xuICAgICAgICAgIGlmIChyZXMuZGVsYXkgPT09IDApIHtcbiAgICAgICAgICAgIGZhY3RvcnkubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRpbWVyTG9hZGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICB0aW1lckxvYWRpbmcgPSBudWxsO1xuICAgICAgICAgICAgICBpZiAoaXNVbmRlZihmYWN0b3J5LnJlc29sdmVkKSAmJiBpc1VuZGVmKGZhY3RvcnkuZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgZmFjdG9yeS5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBmb3JjZVJlbmRlcihmYWxzZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHJlcy5kZWxheSB8fCAyMDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0RlZihyZXMudGltZW91dCkpIHtcbiAgICAgICAgICB0aW1lclRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRpbWVyVGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZihmYWN0b3J5LnJlc29sdmVkKSkge1xuICAgICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgICAgXCJ0aW1lb3V0IChcIiArIChyZXMudGltZW91dCkgKyBcIm1zKVwiXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgcmVzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3luYyA9IGZhbHNlO1xuICAgIC8vIHJldHVybiBpbiBjYXNlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICByZXR1cm4gZmFjdG9yeS5sb2FkaW5nXG4gICAgICA/IGZhY3RvcnkubG9hZGluZ0NvbXBcbiAgICAgIDogZmFjdG9yeS5yZXNvbHZlZFxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpc0FzeW5jUGxhY2Vob2xkZXIgKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUuaXNDb21tZW50ICYmIG5vZGUuYXN5bmNGYWN0b3J5XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBnZXRGaXJzdENvbXBvbmVudENoaWxkIChjaGlsZHJlbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IGNoaWxkcmVuW2ldO1xuICAgICAgaWYgKGlzRGVmKGMpICYmIChpc0RlZihjLmNvbXBvbmVudE9wdGlvbnMpIHx8IGlzQXN5bmNQbGFjZWhvbGRlcihjKSkpIHtcbiAgICAgICAgcmV0dXJuIGNcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXZlbnRzICh2bSkge1xuICB2bS5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdm0uX2hhc0hvb2tFdmVudCA9IGZhbHNlO1xuICAvLyBpbml0IHBhcmVudCBhdHRhY2hlZCBldmVudHNcbiAgdmFyIGxpc3RlbmVycyA9IHZtLiRvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnM7XG4gIGlmIChsaXN0ZW5lcnMpIHtcbiAgICB1cGRhdGVDb21wb25lbnRMaXN0ZW5lcnModm0sIGxpc3RlbmVycyk7XG4gIH1cbn1cblxudmFyIHRhcmdldDtcblxuZnVuY3Rpb24gYWRkIChldmVudCwgZm4pIHtcbiAgdGFyZ2V0LiRvbihldmVudCwgZm4pO1xufVxuXG5mdW5jdGlvbiByZW1vdmUkMSAoZXZlbnQsIGZuKSB7XG4gIHRhcmdldC4kb2ZmKGV2ZW50LCBmbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9uY2VIYW5kbGVyIChldmVudCwgZm4pIHtcbiAgdmFyIF90YXJnZXQgPSB0YXJnZXQ7XG4gIHJldHVybiBmdW5jdGlvbiBvbmNlSGFuZGxlciAoKSB7XG4gICAgdmFyIHJlcyA9IGZuLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHJlcyAhPT0gbnVsbCkge1xuICAgICAgX3RhcmdldC4kb2ZmKGV2ZW50LCBvbmNlSGFuZGxlcik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudExpc3RlbmVycyAoXG4gIHZtLFxuICBsaXN0ZW5lcnMsXG4gIG9sZExpc3RlbmVyc1xuKSB7XG4gIHRhcmdldCA9IHZtO1xuICB1cGRhdGVMaXN0ZW5lcnMobGlzdGVuZXJzLCBvbGRMaXN0ZW5lcnMgfHwge30sIGFkZCwgcmVtb3ZlJDEsIGNyZWF0ZU9uY2VIYW5kbGVyLCB2bSk7XG4gIHRhcmdldCA9IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZXZlbnRzTWl4aW4gKFZ1ZSkge1xuICB2YXIgaG9va1JFID0gL15ob29rOi87XG4gIFZ1ZS5wcm90b3R5cGUuJG9uID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGV2ZW50Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2bS4kb24oZXZlbnRbaV0sIGZuKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgKHZtLl9ldmVudHNbZXZlbnRdIHx8ICh2bS5fZXZlbnRzW2V2ZW50XSA9IFtdKSkucHVzaChmbik7XG4gICAgICAvLyBvcHRpbWl6ZSBob29rOmV2ZW50IGNvc3QgYnkgdXNpbmcgYSBib29sZWFuIGZsYWcgbWFya2VkIGF0IHJlZ2lzdHJhdGlvblxuICAgICAgLy8gaW5zdGVhZCBvZiBhIGhhc2ggbG9va3VwXG4gICAgICBpZiAoaG9va1JFLnRlc3QoZXZlbnQpKSB7XG4gICAgICAgIHZtLl9oYXNIb29rRXZlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdm1cbiAgfTtcblxuICBWdWUucHJvdG90eXBlLiRvbmNlID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgZnVuY3Rpb24gb24gKCkge1xuICAgICAgdm0uJG9mZihldmVudCwgb24pO1xuICAgICAgZm4uYXBwbHkodm0sIGFyZ3VtZW50cyk7XG4gICAgfVxuICAgIG9uLmZuID0gZm47XG4gICAgdm0uJG9uKGV2ZW50LCBvbik7XG4gICAgcmV0dXJuIHZtXG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS4kb2ZmID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgLy8gYWxsXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2bS5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIHJldHVybiB2bVxuICAgIH1cbiAgICAvLyBhcnJheSBvZiBldmVudHNcbiAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudCkpIHtcbiAgICAgIGZvciAodmFyIGkkMSA9IDAsIGwgPSBldmVudC5sZW5ndGg7IGkkMSA8IGw7IGkkMSsrKSB7XG4gICAgICAgIHZtLiRvZmYoZXZlbnRbaSQxXSwgZm4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZtXG4gICAgfVxuICAgIC8vIHNwZWNpZmljIGV2ZW50XG4gICAgdmFyIGNicyA9IHZtLl9ldmVudHNbZXZlbnRdO1xuICAgIGlmICghY2JzKSB7XG4gICAgICByZXR1cm4gdm1cbiAgICB9XG4gICAgaWYgKCFmbikge1xuICAgICAgdm0uX2V2ZW50c1tldmVudF0gPSBudWxsO1xuICAgICAgcmV0dXJuIHZtXG4gICAgfVxuICAgIC8vIHNwZWNpZmljIGhhbmRsZXJcbiAgICB2YXIgY2I7XG4gICAgdmFyIGkgPSBjYnMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNiID0gY2JzW2ldO1xuICAgICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHtcbiAgICAgICAgY2JzLnNwbGljZShpLCAxKTtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZtXG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS4kZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAge1xuICAgICAgdmFyIGxvd2VyQ2FzZUV2ZW50ID0gZXZlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgdm0uX2V2ZW50c1tsb3dlckNhc2VFdmVudF0pIHtcbiAgICAgICAgdGlwKFxuICAgICAgICAgIFwiRXZlbnQgXFxcIlwiICsgbG93ZXJDYXNlRXZlbnQgKyBcIlxcXCIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgXCIgK1xuICAgICAgICAgIChmb3JtYXRDb21wb25lbnROYW1lKHZtKSkgKyBcIiBidXQgdGhlIGhhbmRsZXIgaXMgcmVnaXN0ZXJlZCBmb3IgXFxcIlwiICsgZXZlbnQgKyBcIlxcXCIuIFwiICtcbiAgICAgICAgICBcIk5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIFwiICtcbiAgICAgICAgICBcInYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBcIiArXG4gICAgICAgICAgXCJZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSBcXFwiXCIgKyAoaHlwaGVuYXRlKGV2ZW50KSkgKyBcIlxcXCIgaW5zdGVhZCBvZiBcXFwiXCIgKyBldmVudCArIFwiXFxcIi5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgY2JzID0gdm0uX2V2ZW50c1tldmVudF07XG4gICAgaWYgKGNicykge1xuICAgICAgY2JzID0gY2JzLmxlbmd0aCA+IDEgPyB0b0FycmF5KGNicykgOiBjYnM7XG4gICAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzLCAxKTtcbiAgICAgIHZhciBpbmZvID0gXCJldmVudCBoYW5kbGVyIGZvciBcXFwiXCIgKyBldmVudCArIFwiXFxcIlwiO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGludm9rZVdpdGhFcnJvckhhbmRsaW5nKGNic1tpXSwgdm0sIGFyZ3MsIHZtLCBpbmZvKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZtXG4gIH07XG59XG5cbi8qICAqL1xuXG52YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsO1xudmFyIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBzZXRBY3RpdmVJbnN0YW5jZSh2bSkge1xuICB2YXIgcHJldkFjdGl2ZUluc3RhbmNlID0gYWN0aXZlSW5zdGFuY2U7XG4gIGFjdGl2ZUluc3RhbmNlID0gdm07XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgYWN0aXZlSW5zdGFuY2UgPSBwcmV2QWN0aXZlSW5zdGFuY2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdExpZmVjeWNsZSAodm0pIHtcbiAgdmFyIG9wdGlvbnMgPSB2bS4kb3B0aW9ucztcblxuICAvLyBsb2NhdGUgZmlyc3Qgbm9uLWFic3RyYWN0IHBhcmVudFxuICB2YXIgcGFyZW50ID0gb3B0aW9ucy5wYXJlbnQ7XG4gIGlmIChwYXJlbnQgJiYgIW9wdGlvbnMuYWJzdHJhY3QpIHtcbiAgICB3aGlsZSAocGFyZW50LiRvcHRpb25zLmFic3RyYWN0ICYmIHBhcmVudC4kcGFyZW50KSB7XG4gICAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDtcbiAgICB9XG4gICAgcGFyZW50LiRjaGlsZHJlbi5wdXNoKHZtKTtcbiAgfVxuXG4gIHZtLiRwYXJlbnQgPSBwYXJlbnQ7XG4gIHZtLiRyb290ID0gcGFyZW50ID8gcGFyZW50LiRyb290IDogdm07XG5cbiAgdm0uJGNoaWxkcmVuID0gW107XG4gIHZtLiRyZWZzID0ge307XG5cbiAgdm0uX3dhdGNoZXIgPSBudWxsO1xuICB2bS5faW5hY3RpdmUgPSBudWxsO1xuICB2bS5fZGlyZWN0SW5hY3RpdmUgPSBmYWxzZTtcbiAgdm0uX2lzTW91bnRlZCA9IGZhbHNlO1xuICB2bS5faXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgdm0uX2lzQmVpbmdEZXN0cm95ZWQgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gbGlmZWN5Y2xlTWl4aW4gKFZ1ZSkge1xuICBWdWUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAodm5vZGUsIGh5ZHJhdGluZykge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgdmFyIHByZXZFbCA9IHZtLiRlbDtcbiAgICB2YXIgcHJldlZub2RlID0gdm0uX3Zub2RlO1xuICAgIHZhciByZXN0b3JlQWN0aXZlSW5zdGFuY2UgPSBzZXRBY3RpdmVJbnN0YW5jZSh2bSk7XG4gICAgdm0uX3Zub2RlID0gdm5vZGU7XG4gICAgLy8gVnVlLnByb3RvdHlwZS5fX3BhdGNoX18gaXMgaW5qZWN0ZWQgaW4gZW50cnkgcG9pbnRzXG4gICAgLy8gYmFzZWQgb24gdGhlIHJlbmRlcmluZyBiYWNrZW5kIHVzZWQuXG4gICAgaWYgKCFwcmV2Vm5vZGUpIHtcbiAgICAgIC8vIGluaXRpYWwgcmVuZGVyXG4gICAgICB2bS4kZWwgPSB2bS5fX3BhdGNoX18odm0uJGVsLCB2bm9kZSwgaHlkcmF0aW5nLCBmYWxzZSAvKiByZW1vdmVPbmx5ICovKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdXBkYXRlc1xuICAgICAgdm0uJGVsID0gdm0uX19wYXRjaF9fKHByZXZWbm9kZSwgdm5vZGUpO1xuICAgIH1cbiAgICByZXN0b3JlQWN0aXZlSW5zdGFuY2UoKTtcbiAgICAvLyB1cGRhdGUgX192dWVfXyByZWZlcmVuY2VcbiAgICBpZiAocHJldkVsKSB7XG4gICAgICBwcmV2RWwuX192dWVfXyA9IG51bGw7XG4gICAgfVxuICAgIGlmICh2bS4kZWwpIHtcbiAgICAgIHZtLiRlbC5fX3Z1ZV9fID0gdm07XG4gICAgfVxuICAgIC8vIGlmIHBhcmVudCBpcyBhbiBIT0MsIHVwZGF0ZSBpdHMgJGVsIGFzIHdlbGxcbiAgICBpZiAodm0uJHZub2RlICYmIHZtLiRwYXJlbnQgJiYgdm0uJHZub2RlID09PSB2bS4kcGFyZW50Ll92bm9kZSkge1xuICAgICAgdm0uJHBhcmVudC4kZWwgPSB2bS4kZWw7XG4gICAgfVxuICAgIC8vIHVwZGF0ZWQgaG9vayBpcyBjYWxsZWQgYnkgdGhlIHNjaGVkdWxlciB0byBlbnN1cmUgdGhhdCBjaGlsZHJlbiBhcmVcbiAgICAvLyB1cGRhdGVkIGluIGEgcGFyZW50J3MgdXBkYXRlZCBob29rLlxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGZvcmNlVXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgaWYgKHZtLl93YXRjaGVyKSB7XG4gICAgICB2bS5fd2F0Y2hlci51cGRhdGUoKTtcbiAgICB9XG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS4kZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIGlmICh2bS5faXNCZWluZ0Rlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNhbGxIb29rKHZtLCAnYmVmb3JlRGVzdHJveScpO1xuICAgIHZtLl9pc0JlaW5nRGVzdHJveWVkID0gdHJ1ZTtcbiAgICAvLyByZW1vdmUgc2VsZiBmcm9tIHBhcmVudFxuICAgIHZhciBwYXJlbnQgPSB2bS4kcGFyZW50O1xuICAgIGlmIChwYXJlbnQgJiYgIXBhcmVudC5faXNCZWluZ0Rlc3Ryb3llZCAmJiAhdm0uJG9wdGlvbnMuYWJzdHJhY3QpIHtcbiAgICAgIHJlbW92ZShwYXJlbnQuJGNoaWxkcmVuLCB2bSk7XG4gICAgfVxuICAgIC8vIHRlYXJkb3duIHdhdGNoZXJzXG4gICAgaWYgKHZtLl93YXRjaGVyKSB7XG4gICAgICB2bS5fd2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH1cbiAgICB2YXIgaSA9IHZtLl93YXRjaGVycy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdm0uX3dhdGNoZXJzW2ldLnRlYXJkb3duKCk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgZnJvbSBkYXRhIG9iXG4gICAgLy8gZnJvemVuIG9iamVjdCBtYXkgbm90IGhhdmUgb2JzZXJ2ZXIuXG4gICAgaWYgKHZtLl9kYXRhLl9fb2JfXykge1xuICAgICAgdm0uX2RhdGEuX19vYl9fLnZtQ291bnQtLTtcbiAgICB9XG4gICAgLy8gY2FsbCB0aGUgbGFzdCBob29rLi4uXG4gICAgdm0uX2lzRGVzdHJveWVkID0gdHJ1ZTtcbiAgICAvLyBpbnZva2UgZGVzdHJveSBob29rcyBvbiBjdXJyZW50IHJlbmRlcmVkIHRyZWVcbiAgICB2bS5fX3BhdGNoX18odm0uX3Zub2RlLCBudWxsKTtcbiAgICAvLyBmaXJlIGRlc3Ryb3llZCBob29rXG4gICAgY2FsbEhvb2sodm0sICdkZXN0cm95ZWQnKTtcbiAgICAvLyB0dXJuIG9mZiBhbGwgaW5zdGFuY2UgbGlzdGVuZXJzLlxuICAgIHZtLiRvZmYoKTtcbiAgICAvLyByZW1vdmUgX192dWVfXyByZWZlcmVuY2VcbiAgICBpZiAodm0uJGVsKSB7XG4gICAgICB2bS4kZWwuX192dWVfXyA9IG51bGw7XG4gICAgfVxuICAgIC8vIHJlbGVhc2UgY2lyY3VsYXIgcmVmZXJlbmNlICgjNjc1OSlcbiAgICBpZiAodm0uJHZub2RlKSB7XG4gICAgICB2bS4kdm5vZGUucGFyZW50ID0gbnVsbDtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIG1vdW50Q29tcG9uZW50IChcbiAgdm0sXG4gIGVsLFxuICBoeWRyYXRpbmdcbikge1xuICB2bS4kZWwgPSBlbDtcbiAgaWYgKCF2bS4kb3B0aW9ucy5yZW5kZXIpIHtcbiAgICB2bS4kb3B0aW9ucy5yZW5kZXIgPSBjcmVhdGVFbXB0eVZOb2RlO1xuICAgIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKCh2bS4kb3B0aW9ucy50ZW1wbGF0ZSAmJiB2bS4kb3B0aW9ucy50ZW1wbGF0ZS5jaGFyQXQoMCkgIT09ICcjJykgfHxcbiAgICAgICAgdm0uJG9wdGlvbnMuZWwgfHwgZWwpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnWW91IGFyZSB1c2luZyB0aGUgcnVudGltZS1vbmx5IGJ1aWxkIG9mIFZ1ZSB3aGVyZSB0aGUgdGVtcGxhdGUgJyArXG4gICAgICAgICAgJ2NvbXBpbGVyIGlzIG5vdCBhdmFpbGFibGUuIEVpdGhlciBwcmUtY29tcGlsZSB0aGUgdGVtcGxhdGVzIGludG8gJyArXG4gICAgICAgICAgJ3JlbmRlciBmdW5jdGlvbnMsIG9yIHVzZSB0aGUgY29tcGlsZXItaW5jbHVkZWQgYnVpbGQuJyxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnRmFpbGVkIHRvIG1vdW50IGNvbXBvbmVudDogdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uIG5vdCBkZWZpbmVkLicsXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY2FsbEhvb2sodm0sICdiZWZvcmVNb3VudCcpO1xuXG4gIHZhciB1cGRhdGVDb21wb25lbnQ7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHtcbiAgICB1cGRhdGVDb21wb25lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgbmFtZSA9IHZtLl9uYW1lO1xuICAgICAgdmFyIGlkID0gdm0uX3VpZDtcbiAgICAgIHZhciBzdGFydFRhZyA9IFwidnVlLXBlcmYtc3RhcnQ6XCIgKyBpZDtcbiAgICAgIHZhciBlbmRUYWcgPSBcInZ1ZS1wZXJmLWVuZDpcIiArIGlkO1xuXG4gICAgICBtYXJrKHN0YXJ0VGFnKTtcbiAgICAgIHZhciB2bm9kZSA9IHZtLl9yZW5kZXIoKTtcbiAgICAgIG1hcmsoZW5kVGFnKTtcbiAgICAgIG1lYXN1cmUoKFwidnVlIFwiICsgbmFtZSArIFwiIHJlbmRlclwiKSwgc3RhcnRUYWcsIGVuZFRhZyk7XG5cbiAgICAgIG1hcmsoc3RhcnRUYWcpO1xuICAgICAgdm0uX3VwZGF0ZSh2bm9kZSwgaHlkcmF0aW5nKTtcbiAgICAgIG1hcmsoZW5kVGFnKTtcbiAgICAgIG1lYXN1cmUoKFwidnVlIFwiICsgbmFtZSArIFwiIHBhdGNoXCIpLCBzdGFydFRhZywgZW5kVGFnKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVwZGF0ZUNvbXBvbmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZtLl91cGRhdGUodm0uX3JlbmRlcigpLCBoeWRyYXRpbmcpO1xuICAgIH07XG4gIH1cblxuICAvLyB3ZSBzZXQgdGhpcyB0byB2bS5fd2F0Y2hlciBpbnNpZGUgdGhlIHdhdGNoZXIncyBjb25zdHJ1Y3RvclxuICAvLyBzaW5jZSB0aGUgd2F0Y2hlcidzIGluaXRpYWwgcGF0Y2ggbWF5IGNhbGwgJGZvcmNlVXBkYXRlIChlLmcuIGluc2lkZSBjaGlsZFxuICAvLyBjb21wb25lbnQncyBtb3VudGVkIGhvb2spLCB3aGljaCByZWxpZXMgb24gdm0uX3dhdGNoZXIgYmVpbmcgYWxyZWFkeSBkZWZpbmVkXG4gIG5ldyBXYXRjaGVyKHZtLCB1cGRhdGVDb21wb25lbnQsIG5vb3AsIHtcbiAgICBiZWZvcmU6IGZ1bmN0aW9uIGJlZm9yZSAoKSB7XG4gICAgICBpZiAodm0uX2lzTW91bnRlZCAmJiAhdm0uX2lzRGVzdHJveWVkKSB7XG4gICAgICAgIGNhbGxIb29rKHZtLCAnYmVmb3JlVXBkYXRlJyk7XG4gICAgICB9XG4gICAgfVxuICB9LCB0cnVlIC8qIGlzUmVuZGVyV2F0Y2hlciAqLyk7XG4gIGh5ZHJhdGluZyA9IGZhbHNlO1xuXG4gIC8vIG1hbnVhbGx5IG1vdW50ZWQgaW5zdGFuY2UsIGNhbGwgbW91bnRlZCBvbiBzZWxmXG4gIC8vIG1vdW50ZWQgaXMgY2FsbGVkIGZvciByZW5kZXItY3JlYXRlZCBjaGlsZCBjb21wb25lbnRzIGluIGl0cyBpbnNlcnRlZCBob29rXG4gIGlmICh2bS4kdm5vZGUgPT0gbnVsbCkge1xuICAgIHZtLl9pc01vdW50ZWQgPSB0cnVlO1xuICAgIGNhbGxIb29rKHZtLCAnbW91bnRlZCcpO1xuICB9XG4gIHJldHVybiB2bVxufVxuXG5mdW5jdGlvbiB1cGRhdGVDaGlsZENvbXBvbmVudCAoXG4gIHZtLFxuICBwcm9wc0RhdGEsXG4gIGxpc3RlbmVycyxcbiAgcGFyZW50Vm5vZGUsXG4gIHJlbmRlckNoaWxkcmVuXG4pIHtcbiAge1xuICAgIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IHRydWU7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgd2hldGhlciBjb21wb25lbnQgaGFzIHNsb3QgY2hpbGRyZW5cbiAgLy8gd2UgbmVlZCB0byBkbyB0aGlzIGJlZm9yZSBvdmVyd3JpdGluZyAkb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW4uXG5cbiAgLy8gY2hlY2sgaWYgdGhlcmUgYXJlIGR5bmFtaWMgc2NvcGVkU2xvdHMgKGhhbmQtd3JpdHRlbiBvciBjb21waWxlZCBidXQgd2l0aFxuICAvLyBkeW5hbWljIHNsb3QgbmFtZXMpLiBTdGF0aWMgc2NvcGVkIHNsb3RzIGNvbXBpbGVkIGZyb20gdGVtcGxhdGUgaGFzIHRoZVxuICAvLyBcIiRzdGFibGVcIiBtYXJrZXIuXG4gIHZhciBuZXdTY29wZWRTbG90cyA9IHBhcmVudFZub2RlLmRhdGEuc2NvcGVkU2xvdHM7XG4gIHZhciBvbGRTY29wZWRTbG90cyA9IHZtLiRzY29wZWRTbG90cztcbiAgdmFyIGhhc0R5bmFtaWNTY29wZWRTbG90ID0gISEoXG4gICAgKG5ld1Njb3BlZFNsb3RzICYmICFuZXdTY29wZWRTbG90cy4kc3RhYmxlKSB8fFxuICAgIChvbGRTY29wZWRTbG90cyAhPT0gZW1wdHlPYmplY3QgJiYgIW9sZFNjb3BlZFNsb3RzLiRzdGFibGUpIHx8XG4gICAgKG5ld1Njb3BlZFNsb3RzICYmIHZtLiRzY29wZWRTbG90cy4ka2V5ICE9PSBuZXdTY29wZWRTbG90cy4ka2V5KVxuICApO1xuXG4gIC8vIEFueSBzdGF0aWMgc2xvdCBjaGlsZHJlbiBmcm9tIHRoZSBwYXJlbnQgbWF5IGhhdmUgY2hhbmdlZCBkdXJpbmcgcGFyZW50J3NcbiAgLy8gdXBkYXRlLiBEeW5hbWljIHNjb3BlZCBzbG90cyBtYXkgYWxzbyBoYXZlIGNoYW5nZWQuIEluIHN1Y2ggY2FzZXMsIGEgZm9yY2VkXG4gIC8vIHVwZGF0ZSBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlIGNvcnJlY3RuZXNzLlxuICB2YXIgbmVlZHNGb3JjZVVwZGF0ZSA9ICEhKFxuICAgIHJlbmRlckNoaWxkcmVuIHx8ICAgICAgICAgICAgICAgLy8gaGFzIG5ldyBzdGF0aWMgc2xvdHNcbiAgICB2bS4kb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW4gfHwgIC8vIGhhcyBvbGQgc3RhdGljIHNsb3RzXG4gICAgaGFzRHluYW1pY1Njb3BlZFNsb3RcbiAgKTtcblxuICB2bS4kb3B0aW9ucy5fcGFyZW50Vm5vZGUgPSBwYXJlbnRWbm9kZTtcbiAgdm0uJHZub2RlID0gcGFyZW50Vm5vZGU7IC8vIHVwZGF0ZSB2bSdzIHBsYWNlaG9sZGVyIG5vZGUgd2l0aG91dCByZS1yZW5kZXJcblxuICBpZiAodm0uX3Zub2RlKSB7IC8vIHVwZGF0ZSBjaGlsZCB0cmVlJ3MgcGFyZW50XG4gICAgdm0uX3Zub2RlLnBhcmVudCA9IHBhcmVudFZub2RlO1xuICB9XG4gIHZtLiRvcHRpb25zLl9yZW5kZXJDaGlsZHJlbiA9IHJlbmRlckNoaWxkcmVuO1xuXG4gIC8vIHVwZGF0ZSAkYXR0cnMgYW5kICRsaXN0ZW5lcnMgaGFzaFxuICAvLyB0aGVzZSBhcmUgYWxzbyByZWFjdGl2ZSBzbyB0aGV5IG1heSB0cmlnZ2VyIGNoaWxkIHVwZGF0ZSBpZiB0aGUgY2hpbGRcbiAgLy8gdXNlZCB0aGVtIGR1cmluZyByZW5kZXJcbiAgdm0uJGF0dHJzID0gcGFyZW50Vm5vZGUuZGF0YS5hdHRycyB8fCBlbXB0eU9iamVjdDtcbiAgdm0uJGxpc3RlbmVycyA9IGxpc3RlbmVycyB8fCBlbXB0eU9iamVjdDtcblxuICAvLyB1cGRhdGUgcHJvcHNcbiAgaWYgKHByb3BzRGF0YSAmJiB2bS4kb3B0aW9ucy5wcm9wcykge1xuICAgIHRvZ2dsZU9ic2VydmluZyhmYWxzZSk7XG4gICAgdmFyIHByb3BzID0gdm0uX3Byb3BzO1xuICAgIHZhciBwcm9wS2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyB8fCBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIga2V5ID0gcHJvcEtleXNbaV07XG4gICAgICB2YXIgcHJvcE9wdGlvbnMgPSB2bS4kb3B0aW9ucy5wcm9wczsgLy8gd3RmIGZsb3c/XG4gICAgICBwcm9wc1trZXldID0gdmFsaWRhdGVQcm9wKGtleSwgcHJvcE9wdGlvbnMsIHByb3BzRGF0YSwgdm0pO1xuICAgIH1cbiAgICB0b2dnbGVPYnNlcnZpbmcodHJ1ZSk7XG4gICAgLy8ga2VlcCBhIGNvcHkgb2YgcmF3IHByb3BzRGF0YVxuICAgIHZtLiRvcHRpb25zLnByb3BzRGF0YSA9IHByb3BzRGF0YTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBsaXN0ZW5lcnNcbiAgbGlzdGVuZXJzID0gbGlzdGVuZXJzIHx8IGVtcHR5T2JqZWN0O1xuICB2YXIgb2xkTGlzdGVuZXJzID0gdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVycztcbiAgdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVycyA9IGxpc3RlbmVycztcbiAgdXBkYXRlQ29tcG9uZW50TGlzdGVuZXJzKHZtLCBsaXN0ZW5lcnMsIG9sZExpc3RlbmVycyk7XG5cbiAgLy8gcmVzb2x2ZSBzbG90cyArIGZvcmNlIHVwZGF0ZSBpZiBoYXMgY2hpbGRyZW5cbiAgaWYgKG5lZWRzRm9yY2VVcGRhdGUpIHtcbiAgICB2bS4kc2xvdHMgPSByZXNvbHZlU2xvdHMocmVuZGVyQ2hpbGRyZW4sIHBhcmVudFZub2RlLmNvbnRleHQpO1xuICAgIHZtLiRmb3JjZVVwZGF0ZSgpO1xuICB9XG5cbiAge1xuICAgIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzSW5JbmFjdGl2ZVRyZWUgKHZtKSB7XG4gIHdoaWxlICh2bSAmJiAodm0gPSB2bS4kcGFyZW50KSkge1xuICAgIGlmICh2bS5faW5hY3RpdmUpIHsgcmV0dXJuIHRydWUgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBhY3RpdmF0ZUNoaWxkQ29tcG9uZW50ICh2bSwgZGlyZWN0KSB7XG4gIGlmIChkaXJlY3QpIHtcbiAgICB2bS5fZGlyZWN0SW5hY3RpdmUgPSBmYWxzZTtcbiAgICBpZiAoaXNJbkluYWN0aXZlVHJlZSh2bSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgfSBlbHNlIGlmICh2bS5fZGlyZWN0SW5hY3RpdmUpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAodm0uX2luYWN0aXZlIHx8IHZtLl9pbmFjdGl2ZSA9PT0gbnVsbCkge1xuICAgIHZtLl9pbmFjdGl2ZSA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdm0uJGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KHZtLiRjaGlsZHJlbltpXSk7XG4gICAgfVxuICAgIGNhbGxIb29rKHZtLCAnYWN0aXZhdGVkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVhY3RpdmF0ZUNoaWxkQ29tcG9uZW50ICh2bSwgZGlyZWN0KSB7XG4gIGlmIChkaXJlY3QpIHtcbiAgICB2bS5fZGlyZWN0SW5hY3RpdmUgPSB0cnVlO1xuICAgIGlmIChpc0luSW5hY3RpdmVUcmVlKHZtKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICB9XG4gIGlmICghdm0uX2luYWN0aXZlKSB7XG4gICAgdm0uX2luYWN0aXZlID0gdHJ1ZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZtLiRjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgZGVhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KHZtLiRjaGlsZHJlbltpXSk7XG4gICAgfVxuICAgIGNhbGxIb29rKHZtLCAnZGVhY3RpdmF0ZWQnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWxsSG9vayAodm0sIGhvb2spIHtcbiAgLy8gIzc1NzMgZGlzYWJsZSBkZXAgY29sbGVjdGlvbiB3aGVuIGludm9raW5nIGxpZmVjeWNsZSBob29rc1xuICBwdXNoVGFyZ2V0KCk7XG4gIHZhciBoYW5kbGVycyA9IHZtLiRvcHRpb25zW2hvb2tdO1xuICB2YXIgaW5mbyA9IGhvb2sgKyBcIiBob29rXCI7XG4gIGlmIChoYW5kbGVycykge1xuICAgIGZvciAodmFyIGkgPSAwLCBqID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG4gICAgICBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyhoYW5kbGVyc1tpXSwgdm0sIG51bGwsIHZtLCBpbmZvKTtcbiAgICB9XG4gIH1cbiAgaWYgKHZtLl9oYXNIb29rRXZlbnQpIHtcbiAgICB2bS4kZW1pdCgnaG9vazonICsgaG9vayk7XG4gIH1cbiAgcG9wVGFyZ2V0KCk7XG59XG5cbi8qICAqL1xuXG52YXIgTUFYX1VQREFURV9DT1VOVCA9IDEwMDtcblxudmFyIHF1ZXVlID0gW107XG52YXIgYWN0aXZhdGVkQ2hpbGRyZW4gPSBbXTtcbnZhciBoYXMgPSB7fTtcbnZhciBjaXJjdWxhciA9IHt9O1xudmFyIHdhaXRpbmcgPSBmYWxzZTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xudmFyIGluZGV4ID0gMDtcblxuLyoqXG4gKiBSZXNldCB0aGUgc2NoZWR1bGVyJ3Mgc3RhdGUuXG4gKi9cbmZ1bmN0aW9uIHJlc2V0U2NoZWR1bGVyU3RhdGUgKCkge1xuICBpbmRleCA9IHF1ZXVlLmxlbmd0aCA9IGFjdGl2YXRlZENoaWxkcmVuLmxlbmd0aCA9IDA7XG4gIGhhcyA9IHt9O1xuICB7XG4gICAgY2lyY3VsYXIgPSB7fTtcbiAgfVxuICB3YWl0aW5nID0gZmx1c2hpbmcgPSBmYWxzZTtcbn1cblxuLy8gQXN5bmMgZWRnZSBjYXNlICM2NTY2IHJlcXVpcmVzIHNhdmluZyB0aGUgdGltZXN0YW1wIHdoZW4gZXZlbnQgbGlzdGVuZXJzIGFyZVxuLy8gYXR0YWNoZWQuIEhvd2V2ZXIsIGNhbGxpbmcgcGVyZm9ybWFuY2Uubm93KCkgaGFzIGEgcGVyZiBvdmVyaGVhZCBlc3BlY2lhbGx5XG4vLyBpZiB0aGUgcGFnZSBoYXMgdGhvdXNhbmRzIG9mIGV2ZW50IGxpc3RlbmVycy4gSW5zdGVhZCwgd2UgdGFrZSBhIHRpbWVzdGFtcFxuLy8gZXZlcnkgdGltZSB0aGUgc2NoZWR1bGVyIGZsdXNoZXMgYW5kIHVzZSB0aGF0IGZvciBhbGwgZXZlbnQgbGlzdGVuZXJzXG4vLyBhdHRhY2hlZCBkdXJpbmcgdGhhdCBmbHVzaC5cbnZhciBjdXJyZW50Rmx1c2hUaW1lc3RhbXAgPSAwO1xuXG4vLyBBc3luYyBlZGdlIGNhc2UgZml4IHJlcXVpcmVzIHN0b3JpbmcgYW4gZXZlbnQgbGlzdGVuZXIncyBhdHRhY2ggdGltZXN0YW1wLlxudmFyIGdldE5vdyA9IERhdGUubm93O1xuXG4vLyBEZXRlcm1pbmUgd2hhdCBldmVudCB0aW1lc3RhbXAgdGhlIGJyb3dzZXIgaXMgdXNpbmcuIEFubm95aW5nbHksIHRoZVxuLy8gdGltZXN0YW1wIGNhbiBlaXRoZXIgYmUgaGktcmVzIChyZWxhdGl2ZSB0byBwYWdlIGxvYWQpIG9yIGxvdy1yZXNcbi8vIChyZWxhdGl2ZSB0byBVTklYIGVwb2NoKSwgc28gaW4gb3JkZXIgdG8gY29tcGFyZSB0aW1lIHdlIGhhdmUgdG8gdXNlIHRoZVxuLy8gc2FtZSB0aW1lc3RhbXAgdHlwZSB3aGVuIHNhdmluZyB0aGUgZmx1c2ggdGltZXN0YW1wLlxuLy8gQWxsIElFIHZlcnNpb25zIHVzZSBsb3ctcmVzIGV2ZW50IHRpbWVzdGFtcHMsIGFuZCBoYXZlIHByb2JsZW1hdGljIGNsb2NrXG4vLyBpbXBsZW1lbnRhdGlvbnMgKCM5NjMyKVxuaWYgKGluQnJvd3NlciAmJiAhaXNJRSkge1xuICB2YXIgcGVyZm9ybWFuY2UgPSB3aW5kb3cucGVyZm9ybWFuY2U7XG4gIGlmIChcbiAgICBwZXJmb3JtYW5jZSAmJlxuICAgIHR5cGVvZiBwZXJmb3JtYW5jZS5ub3cgPT09ICdmdW5jdGlvbicgJiZcbiAgICBnZXROb3coKSA+IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpLnRpbWVTdGFtcFxuICApIHtcbiAgICAvLyBpZiB0aGUgZXZlbnQgdGltZXN0YW1wLCBhbHRob3VnaCBldmFsdWF0ZWQgQUZURVIgdGhlIERhdGUubm93KCksIGlzXG4gICAgLy8gc21hbGxlciB0aGFuIGl0LCBpdCBtZWFucyB0aGUgZXZlbnQgaXMgdXNpbmcgYSBoaS1yZXMgdGltZXN0YW1wLFxuICAgIC8vIGFuZCB3ZSBuZWVkIHRvIHVzZSB0aGUgaGktcmVzIHZlcnNpb24gZm9yIGV2ZW50IGxpc3RlbmVyIHRpbWVzdGFtcHMgYXNcbiAgICAvLyB3ZWxsLlxuICAgIGdldE5vdyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpOyB9O1xuICB9XG59XG5cbi8qKlxuICogRmx1c2ggYm90aCBxdWV1ZXMgYW5kIHJ1biB0aGUgd2F0Y2hlcnMuXG4gKi9cbmZ1bmN0aW9uIGZsdXNoU2NoZWR1bGVyUXVldWUgKCkge1xuICBjdXJyZW50Rmx1c2hUaW1lc3RhbXAgPSBnZXROb3coKTtcbiAgZmx1c2hpbmcgPSB0cnVlO1xuICB2YXIgd2F0Y2hlciwgaWQ7XG5cbiAgLy8gU29ydCBxdWV1ZSBiZWZvcmUgZmx1c2guXG4gIC8vIFRoaXMgZW5zdXJlcyB0aGF0OlxuICAvLyAxLiBDb21wb25lbnRzIGFyZSB1cGRhdGVkIGZyb20gcGFyZW50IHRvIGNoaWxkLiAoYmVjYXVzZSBwYXJlbnQgaXMgYWx3YXlzXG4gIC8vICAgIGNyZWF0ZWQgYmVmb3JlIHRoZSBjaGlsZClcbiAgLy8gMi4gQSBjb21wb25lbnQncyB1c2VyIHdhdGNoZXJzIGFyZSBydW4gYmVmb3JlIGl0cyByZW5kZXIgd2F0Y2hlciAoYmVjYXVzZVxuICAvLyAgICB1c2VyIHdhdGNoZXJzIGFyZSBjcmVhdGVkIGJlZm9yZSB0aGUgcmVuZGVyIHdhdGNoZXIpXG4gIC8vIDMuIElmIGEgY29tcG9uZW50IGlzIGRlc3Ryb3llZCBkdXJpbmcgYSBwYXJlbnQgY29tcG9uZW50J3Mgd2F0Y2hlciBydW4sXG4gIC8vICAgIGl0cyB3YXRjaGVycyBjYW4gYmUgc2tpcHBlZC5cbiAgcXVldWUuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYS5pZCAtIGIuaWQ7IH0pO1xuXG4gIC8vIGRvIG5vdCBjYWNoZSBsZW5ndGggYmVjYXVzZSBtb3JlIHdhdGNoZXJzIG1pZ2h0IGJlIHB1c2hlZFxuICAvLyBhcyB3ZSBydW4gZXhpc3Rpbmcgd2F0Y2hlcnNcbiAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgcXVldWUubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgd2F0Y2hlciA9IHF1ZXVlW2luZGV4XTtcbiAgICBpZiAod2F0Y2hlci5iZWZvcmUpIHtcbiAgICAgIHdhdGNoZXIuYmVmb3JlKCk7XG4gICAgfVxuICAgIGlkID0gd2F0Y2hlci5pZDtcbiAgICBoYXNbaWRdID0gbnVsbDtcbiAgICB3YXRjaGVyLnJ1bigpO1xuICAgIC8vIGluIGRldiBidWlsZCwgY2hlY2sgYW5kIHN0b3AgY2lyY3VsYXIgdXBkYXRlcy5cbiAgICBpZiAoaGFzW2lkXSAhPSBudWxsKSB7XG4gICAgICBjaXJjdWxhcltpZF0gPSAoY2lyY3VsYXJbaWRdIHx8IDApICsgMTtcbiAgICAgIGlmIChjaXJjdWxhcltpZF0gPiBNQVhfVVBEQVRFX0NPVU5UKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgJ1lvdSBtYXkgaGF2ZSBhbiBpbmZpbml0ZSB1cGRhdGUgbG9vcCAnICsgKFxuICAgICAgICAgICAgd2F0Y2hlci51c2VyXG4gICAgICAgICAgICAgID8gKFwiaW4gd2F0Y2hlciB3aXRoIGV4cHJlc3Npb24gXFxcIlwiICsgKHdhdGNoZXIuZXhwcmVzc2lvbikgKyBcIlxcXCJcIilcbiAgICAgICAgICAgICAgOiBcImluIGEgY29tcG9uZW50IHJlbmRlciBmdW5jdGlvbi5cIlxuICAgICAgICAgICksXG4gICAgICAgICAgd2F0Y2hlci52bVxuICAgICAgICApO1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGtlZXAgY29waWVzIG9mIHBvc3QgcXVldWVzIGJlZm9yZSByZXNldHRpbmcgc3RhdGVcbiAgdmFyIGFjdGl2YXRlZFF1ZXVlID0gYWN0aXZhdGVkQ2hpbGRyZW4uc2xpY2UoKTtcbiAgdmFyIHVwZGF0ZWRRdWV1ZSA9IHF1ZXVlLnNsaWNlKCk7XG5cbiAgcmVzZXRTY2hlZHVsZXJTdGF0ZSgpO1xuXG4gIC8vIGNhbGwgY29tcG9uZW50IHVwZGF0ZWQgYW5kIGFjdGl2YXRlZCBob29rc1xuICBjYWxsQWN0aXZhdGVkSG9va3MoYWN0aXZhdGVkUXVldWUpO1xuICBjYWxsVXBkYXRlZEhvb2tzKHVwZGF0ZWRRdWV1ZSk7XG5cbiAgLy8gZGV2dG9vbCBob29rXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoZGV2dG9vbHMgJiYgY29uZmlnLmRldnRvb2xzKSB7XG4gICAgZGV2dG9vbHMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWxsVXBkYXRlZEhvb2tzIChxdWV1ZSkge1xuICB2YXIgaSA9IHF1ZXVlLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIHZhciB3YXRjaGVyID0gcXVldWVbaV07XG4gICAgdmFyIHZtID0gd2F0Y2hlci52bTtcbiAgICBpZiAodm0uX3dhdGNoZXIgPT09IHdhdGNoZXIgJiYgdm0uX2lzTW91bnRlZCAmJiAhdm0uX2lzRGVzdHJveWVkKSB7XG4gICAgICBjYWxsSG9vayh2bSwgJ3VwZGF0ZWQnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBRdWV1ZSBhIGtlcHQtYWxpdmUgY29tcG9uZW50IHRoYXQgd2FzIGFjdGl2YXRlZCBkdXJpbmcgcGF0Y2guXG4gKiBUaGUgcXVldWUgd2lsbCBiZSBwcm9jZXNzZWQgYWZ0ZXIgdGhlIGVudGlyZSB0cmVlIGhhcyBiZWVuIHBhdGNoZWQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlQWN0aXZhdGVkQ29tcG9uZW50ICh2bSkge1xuICAvLyBzZXR0aW5nIF9pbmFjdGl2ZSB0byBmYWxzZSBoZXJlIHNvIHRoYXQgYSByZW5kZXIgZnVuY3Rpb24gY2FuXG4gIC8vIHJlbHkgb24gY2hlY2tpbmcgd2hldGhlciBpdCdzIGluIGFuIGluYWN0aXZlIHRyZWUgKGUuZy4gcm91dGVyLXZpZXcpXG4gIHZtLl9pbmFjdGl2ZSA9IGZhbHNlO1xuICBhY3RpdmF0ZWRDaGlsZHJlbi5wdXNoKHZtKTtcbn1cblxuZnVuY3Rpb24gY2FsbEFjdGl2YXRlZEhvb2tzIChxdWV1ZSkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgcXVldWVbaV0uX2luYWN0aXZlID0gdHJ1ZTtcbiAgICBhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KHF1ZXVlW2ldLCB0cnVlIC8qIHRydWUgKi8pO1xuICB9XG59XG5cbi8qKlxuICogUHVzaCBhIHdhdGNoZXIgaW50byB0aGUgd2F0Y2hlciBxdWV1ZS5cbiAqIEpvYnMgd2l0aCBkdXBsaWNhdGUgSURzIHdpbGwgYmUgc2tpcHBlZCB1bmxlc3MgaXQnc1xuICogcHVzaGVkIHdoZW4gdGhlIHF1ZXVlIGlzIGJlaW5nIGZsdXNoZWQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlV2F0Y2hlciAod2F0Y2hlcikge1xuICB2YXIgaWQgPSB3YXRjaGVyLmlkO1xuICBpZiAoaGFzW2lkXSA9PSBudWxsKSB7XG4gICAgaGFzW2lkXSA9IHRydWU7XG4gICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgcXVldWUucHVzaCh3YXRjaGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgYWxyZWFkeSBmbHVzaGluZywgc3BsaWNlIHRoZSB3YXRjaGVyIGJhc2VkIG9uIGl0cyBpZFxuICAgICAgLy8gaWYgYWxyZWFkeSBwYXN0IGl0cyBpZCwgaXQgd2lsbCBiZSBydW4gbmV4dCBpbW1lZGlhdGVseS5cbiAgICAgIHZhciBpID0gcXVldWUubGVuZ3RoIC0gMTtcbiAgICAgIHdoaWxlIChpID4gaW5kZXggJiYgcXVldWVbaV0uaWQgPiB3YXRjaGVyLmlkKSB7XG4gICAgICAgIGktLTtcbiAgICAgIH1cbiAgICAgIHF1ZXVlLnNwbGljZShpICsgMSwgMCwgd2F0Y2hlcik7XG4gICAgfVxuICAgIC8vIHF1ZXVlIHRoZSBmbHVzaFxuICAgIGlmICghd2FpdGluZykge1xuICAgICAgd2FpdGluZyA9IHRydWU7XG5cbiAgICAgIGlmICghY29uZmlnLmFzeW5jKSB7XG4gICAgICAgIGZsdXNoU2NoZWR1bGVyUXVldWUoKTtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBuZXh0VGljayhmbHVzaFNjaGVkdWxlclF1ZXVlKTtcbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cblxuXG52YXIgdWlkJDIgPSAwO1xuXG4vKipcbiAqIEEgd2F0Y2hlciBwYXJzZXMgYW4gZXhwcmVzc2lvbiwgY29sbGVjdHMgZGVwZW5kZW5jaWVzLFxuICogYW5kIGZpcmVzIGNhbGxiYWNrIHdoZW4gdGhlIGV4cHJlc3Npb24gdmFsdWUgY2hhbmdlcy5cbiAqIFRoaXMgaXMgdXNlZCBmb3IgYm90aCB0aGUgJHdhdGNoKCkgYXBpIGFuZCBkaXJlY3RpdmVzLlxuICovXG52YXIgV2F0Y2hlciA9IGZ1bmN0aW9uIFdhdGNoZXIgKFxuICB2bSxcbiAgZXhwT3JGbixcbiAgY2IsXG4gIG9wdGlvbnMsXG4gIGlzUmVuZGVyV2F0Y2hlclxuKSB7XG4gIHRoaXMudm0gPSB2bTtcbiAgaWYgKGlzUmVuZGVyV2F0Y2hlcikge1xuICAgIHZtLl93YXRjaGVyID0gdGhpcztcbiAgfVxuICB2bS5fd2F0Y2hlcnMucHVzaCh0aGlzKTtcbiAgLy8gb3B0aW9uc1xuICBpZiAob3B0aW9ucykge1xuICAgIHRoaXMuZGVlcCA9ICEhb3B0aW9ucy5kZWVwO1xuICAgIHRoaXMudXNlciA9ICEhb3B0aW9ucy51c2VyO1xuICAgIHRoaXMubGF6eSA9ICEhb3B0aW9ucy5sYXp5O1xuICAgIHRoaXMuc3luYyA9ICEhb3B0aW9ucy5zeW5jO1xuICAgIHRoaXMuYmVmb3JlID0gb3B0aW9ucy5iZWZvcmU7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5kZWVwID0gdGhpcy51c2VyID0gdGhpcy5sYXp5ID0gdGhpcy5zeW5jID0gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYiA9IGNiO1xuICB0aGlzLmlkID0gKyt1aWQkMjsgLy8gdWlkIGZvciBiYXRjaGluZ1xuICB0aGlzLmFjdGl2ZSA9IHRydWU7XG4gIHRoaXMuZGlydHkgPSB0aGlzLmxhenk7IC8vIGZvciBsYXp5IHdhdGNoZXJzXG4gIHRoaXMuZGVwcyA9IFtdO1xuICB0aGlzLm5ld0RlcHMgPSBbXTtcbiAgdGhpcy5kZXBJZHMgPSBuZXcgX1NldCgpO1xuICB0aGlzLm5ld0RlcElkcyA9IG5ldyBfU2V0KCk7XG4gIHRoaXMuZXhwcmVzc2lvbiA9IGV4cE9yRm4udG9TdHJpbmcoKTtcbiAgLy8gcGFyc2UgZXhwcmVzc2lvbiBmb3IgZ2V0dGVyXG4gIGlmICh0eXBlb2YgZXhwT3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuZ2V0dGVyID0gZXhwT3JGbjtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmdldHRlciA9IHBhcnNlUGF0aChleHBPckZuKTtcbiAgICBpZiAoIXRoaXMuZ2V0dGVyKSB7XG4gICAgICB0aGlzLmdldHRlciA9IG5vb3A7XG4gICAgICB3YXJuKFxuICAgICAgICBcIkZhaWxlZCB3YXRjaGluZyBwYXRoOiBcXFwiXCIgKyBleHBPckZuICsgXCJcXFwiIFwiICtcbiAgICAgICAgJ1dhdGNoZXIgb25seSBhY2NlcHRzIHNpbXBsZSBkb3QtZGVsaW1pdGVkIHBhdGhzLiAnICtcbiAgICAgICAgJ0ZvciBmdWxsIGNvbnRyb2wsIHVzZSBhIGZ1bmN0aW9uIGluc3RlYWQuJyxcbiAgICAgICAgdm1cbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHRoaXMudmFsdWUgPSB0aGlzLmxhenlcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogdGhpcy5nZXQoKTtcbn07XG5cbi8qKlxuICogRXZhbHVhdGUgdGhlIGdldHRlciwgYW5kIHJlLWNvbGxlY3QgZGVwZW5kZW5jaWVzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKCkge1xuICBwdXNoVGFyZ2V0KHRoaXMpO1xuICB2YXIgdmFsdWU7XG4gIHZhciB2bSA9IHRoaXMudm07XG4gIHRyeSB7XG4gICAgdmFsdWUgPSB0aGlzLmdldHRlci5jYWxsKHZtLCB2bSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAodGhpcy51c2VyKSB7XG4gICAgICBoYW5kbGVFcnJvcihlLCB2bSwgKFwiZ2V0dGVyIGZvciB3YXRjaGVyIFxcXCJcIiArICh0aGlzLmV4cHJlc3Npb24pICsgXCJcXFwiXCIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBcInRvdWNoXCIgZXZlcnkgcHJvcGVydHkgc28gdGhleSBhcmUgYWxsIHRyYWNrZWQgYXNcbiAgICAvLyBkZXBlbmRlbmNpZXMgZm9yIGRlZXAgd2F0Y2hpbmdcbiAgICBpZiAodGhpcy5kZWVwKSB7XG4gICAgICB0cmF2ZXJzZSh2YWx1ZSk7XG4gICAgfVxuICAgIHBvcFRhcmdldCgpO1xuICAgIHRoaXMuY2xlYW51cERlcHMoKTtcbiAgfVxuICByZXR1cm4gdmFsdWVcbn07XG5cbi8qKlxuICogQWRkIGEgZGVwZW5kZW5jeSB0byB0aGlzIGRpcmVjdGl2ZS5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUuYWRkRGVwID0gZnVuY3Rpb24gYWRkRGVwIChkZXApIHtcbiAgdmFyIGlkID0gZGVwLmlkO1xuICBpZiAoIXRoaXMubmV3RGVwSWRzLmhhcyhpZCkpIHtcbiAgICB0aGlzLm5ld0RlcElkcy5hZGQoaWQpO1xuICAgIHRoaXMubmV3RGVwcy5wdXNoKGRlcCk7XG4gICAgaWYgKCF0aGlzLmRlcElkcy5oYXMoaWQpKSB7XG4gICAgICBkZXAuYWRkU3ViKHRoaXMpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5jbGVhbnVwRGVwcyA9IGZ1bmN0aW9uIGNsZWFudXBEZXBzICgpIHtcbiAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgdmFyIGRlcCA9IHRoaXMuZGVwc1tpXTtcbiAgICBpZiAoIXRoaXMubmV3RGVwSWRzLmhhcyhkZXAuaWQpKSB7XG4gICAgICBkZXAucmVtb3ZlU3ViKHRoaXMpO1xuICAgIH1cbiAgfVxuICB2YXIgdG1wID0gdGhpcy5kZXBJZHM7XG4gIHRoaXMuZGVwSWRzID0gdGhpcy5uZXdEZXBJZHM7XG4gIHRoaXMubmV3RGVwSWRzID0gdG1wO1xuICB0aGlzLm5ld0RlcElkcy5jbGVhcigpO1xuICB0bXAgPSB0aGlzLmRlcHM7XG4gIHRoaXMuZGVwcyA9IHRoaXMubmV3RGVwcztcbiAgdGhpcy5uZXdEZXBzID0gdG1wO1xuICB0aGlzLm5ld0RlcHMubGVuZ3RoID0gMDtcbn07XG5cbi8qKlxuICogU3Vic2NyaWJlciBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCB3aGVuIGEgZGVwZW5kZW5jeSBjaGFuZ2VzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKCkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAodGhpcy5sYXp5KSB7XG4gICAgdGhpcy5kaXJ0eSA9IHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy5zeW5jKSB7XG4gICAgdGhpcy5ydW4oKTtcbiAgfSBlbHNlIHtcbiAgICBxdWV1ZVdhdGNoZXIodGhpcyk7XG4gIH1cbn07XG5cbi8qKlxuICogU2NoZWR1bGVyIGpvYiBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCBieSB0aGUgc2NoZWR1bGVyLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiBydW4gKCkge1xuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldCgpO1xuICAgIGlmIChcbiAgICAgIHZhbHVlICE9PSB0aGlzLnZhbHVlIHx8XG4gICAgICAvLyBEZWVwIHdhdGNoZXJzIGFuZCB3YXRjaGVycyBvbiBPYmplY3QvQXJyYXlzIHNob3VsZCBmaXJlIGV2ZW5cbiAgICAgIC8vIHdoZW4gdGhlIHZhbHVlIGlzIHRoZSBzYW1lLCBiZWNhdXNlIHRoZSB2YWx1ZSBtYXlcbiAgICAgIC8vIGhhdmUgbXV0YXRlZC5cbiAgICAgIGlzT2JqZWN0KHZhbHVlKSB8fFxuICAgICAgdGhpcy5kZWVwXG4gICAgKSB7XG4gICAgICAvLyBzZXQgbmV3IHZhbHVlXG4gICAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgaWYgKHRoaXMudXNlcikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuY2IuY2FsbCh0aGlzLnZtLCB2YWx1ZSwgb2xkVmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaGFuZGxlRXJyb3IoZSwgdGhpcy52bSwgKFwiY2FsbGJhY2sgZm9yIHdhdGNoZXIgXFxcIlwiICsgKHRoaXMuZXhwcmVzc2lvbikgKyBcIlxcXCJcIikpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNiLmNhbGwodGhpcy52bSwgdmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogRXZhbHVhdGUgdGhlIHZhbHVlIG9mIHRoZSB3YXRjaGVyLlxuICogVGhpcyBvbmx5IGdldHMgY2FsbGVkIGZvciBsYXp5IHdhdGNoZXJzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5ldmFsdWF0ZSA9IGZ1bmN0aW9uIGV2YWx1YXRlICgpIHtcbiAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0KCk7XG4gIHRoaXMuZGlydHkgPSBmYWxzZTtcbn07XG5cbi8qKlxuICogRGVwZW5kIG9uIGFsbCBkZXBzIGNvbGxlY3RlZCBieSB0aGlzIHdhdGNoZXIuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLmRlcGVuZCA9IGZ1bmN0aW9uIGRlcGVuZCAoKSB7XG4gIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIHRoaXMuZGVwc1tpXS5kZXBlbmQoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZW1vdmUgc2VsZiBmcm9tIGFsbCBkZXBlbmRlbmNpZXMnIHN1YnNjcmliZXIgbGlzdC5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUudGVhcmRvd24gPSBmdW5jdGlvbiB0ZWFyZG93biAoKSB7XG4gIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gdm0ncyB3YXRjaGVyIGxpc3RcbiAgICAvLyB0aGlzIGlzIGEgc29tZXdoYXQgZXhwZW5zaXZlIG9wZXJhdGlvbiBzbyB3ZSBza2lwIGl0XG4gICAgLy8gaWYgdGhlIHZtIGlzIGJlaW5nIGRlc3Ryb3llZC5cbiAgICBpZiAoIXRoaXMudm0uX2lzQmVpbmdEZXN0cm95ZWQpIHtcbiAgICAgIHJlbW92ZSh0aGlzLnZtLl93YXRjaGVycywgdGhpcyk7XG4gICAgfVxuICAgIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB0aGlzLmRlcHNbaV0ucmVtb3ZlU3ViKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG59O1xuXG4vKiAgKi9cblxudmFyIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbiA9IHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IG5vb3AsXG4gIHNldDogbm9vcFxufTtcblxuZnVuY3Rpb24gcHJveHkgKHRhcmdldCwgc291cmNlS2V5LCBrZXkpIHtcbiAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLmdldCA9IGZ1bmN0aW9uIHByb3h5R2V0dGVyICgpIHtcbiAgICByZXR1cm4gdGhpc1tzb3VyY2VLZXldW2tleV1cbiAgfTtcbiAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IGZ1bmN0aW9uIHByb3h5U2V0dGVyICh2YWwpIHtcbiAgICB0aGlzW3NvdXJjZUtleV1ba2V5XSA9IHZhbDtcbiAgfTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24pO1xufVxuXG5mdW5jdGlvbiBpbml0U3RhdGUgKHZtKSB7XG4gIHZtLl93YXRjaGVycyA9IFtdO1xuICB2YXIgb3B0cyA9IHZtLiRvcHRpb25zO1xuICBpZiAob3B0cy5wcm9wcykgeyBpbml0UHJvcHModm0sIG9wdHMucHJvcHMpOyB9XG4gIGlmIChvcHRzLm1ldGhvZHMpIHsgaW5pdE1ldGhvZHModm0sIG9wdHMubWV0aG9kcyk7IH1cbiAgaWYgKG9wdHMuZGF0YSkge1xuICAgIGluaXREYXRhKHZtKTtcbiAgfSBlbHNlIHtcbiAgICBvYnNlcnZlKHZtLl9kYXRhID0ge30sIHRydWUgLyogYXNSb290RGF0YSAqLyk7XG4gIH1cbiAgaWYgKG9wdHMuY29tcHV0ZWQpIHsgaW5pdENvbXB1dGVkKHZtLCBvcHRzLmNvbXB1dGVkKTsgfVxuICBpZiAob3B0cy53YXRjaCAmJiBvcHRzLndhdGNoICE9PSBuYXRpdmVXYXRjaCkge1xuICAgIGluaXRXYXRjaCh2bSwgb3B0cy53YXRjaCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdFByb3BzICh2bSwgcHJvcHNPcHRpb25zKSB7XG4gIHZhciBwcm9wc0RhdGEgPSB2bS4kb3B0aW9ucy5wcm9wc0RhdGEgfHwge307XG4gIHZhciBwcm9wcyA9IHZtLl9wcm9wcyA9IHt9O1xuICAvLyBjYWNoZSBwcm9wIGtleXMgc28gdGhhdCBmdXR1cmUgcHJvcHMgdXBkYXRlcyBjYW4gaXRlcmF0ZSB1c2luZyBBcnJheVxuICAvLyBpbnN0ZWFkIG9mIGR5bmFtaWMgb2JqZWN0IGtleSBlbnVtZXJhdGlvbi5cbiAgdmFyIGtleXMgPSB2bS4kb3B0aW9ucy5fcHJvcEtleXMgPSBbXTtcbiAgdmFyIGlzUm9vdCA9ICF2bS4kcGFyZW50O1xuICAvLyByb290IGluc3RhbmNlIHByb3BzIHNob3VsZCBiZSBjb252ZXJ0ZWRcbiAgaWYgKCFpc1Jvb3QpIHtcbiAgICB0b2dnbGVPYnNlcnZpbmcoZmFsc2UpO1xuICB9XG4gIHZhciBsb29wID0gZnVuY3Rpb24gKCBrZXkgKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gICAgdmFyIHZhbHVlID0gdmFsaWRhdGVQcm9wKGtleSwgcHJvcHNPcHRpb25zLCBwcm9wc0RhdGEsIHZtKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIHtcbiAgICAgIHZhciBoeXBoZW5hdGVkS2V5ID0gaHlwaGVuYXRlKGtleSk7XG4gICAgICBpZiAoaXNSZXNlcnZlZEF0dHJpYnV0ZShoeXBoZW5hdGVkS2V5KSB8fFxuICAgICAgICAgIGNvbmZpZy5pc1Jlc2VydmVkQXR0cihoeXBoZW5hdGVkS2V5KSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIChcIlxcXCJcIiArIGh5cGhlbmF0ZWRLZXkgKyBcIlxcXCIgaXMgYSByZXNlcnZlZCBhdHRyaWJ1dGUgYW5kIGNhbm5vdCBiZSB1c2VkIGFzIGNvbXBvbmVudCBwcm9wLlwiKSxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZGVmaW5lUmVhY3RpdmUkJDEocHJvcHMsIGtleSwgdmFsdWUsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFpc1Jvb3QgJiYgIWlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICBcIkF2b2lkIG11dGF0aW5nIGEgcHJvcCBkaXJlY3RseSBzaW5jZSB0aGUgdmFsdWUgd2lsbCBiZSBcIiArXG4gICAgICAgICAgICBcIm92ZXJ3cml0dGVuIHdoZW5ldmVyIHRoZSBwYXJlbnQgY29tcG9uZW50IHJlLXJlbmRlcnMuIFwiICtcbiAgICAgICAgICAgIFwiSW5zdGVhZCwgdXNlIGEgZGF0YSBvciBjb21wdXRlZCBwcm9wZXJ0eSBiYXNlZCBvbiB0aGUgcHJvcCdzIFwiICtcbiAgICAgICAgICAgIFwidmFsdWUuIFByb3AgYmVpbmcgbXV0YXRlZDogXFxcIlwiICsga2V5ICsgXCJcXFwiXCIsXG4gICAgICAgICAgICB2bVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBzdGF0aWMgcHJvcHMgYXJlIGFscmVhZHkgcHJveGllZCBvbiB0aGUgY29tcG9uZW50J3MgcHJvdG90eXBlXG4gICAgLy8gZHVyaW5nIFZ1ZS5leHRlbmQoKS4gV2Ugb25seSBuZWVkIHRvIHByb3h5IHByb3BzIGRlZmluZWQgYXRcbiAgICAvLyBpbnN0YW50aWF0aW9uIGhlcmUuXG4gICAgaWYgKCEoa2V5IGluIHZtKSkge1xuICAgICAgcHJveHkodm0sIFwiX3Byb3BzXCIsIGtleSk7XG4gICAgfVxuICB9O1xuXG4gIGZvciAodmFyIGtleSBpbiBwcm9wc09wdGlvbnMpIGxvb3AoIGtleSApO1xuICB0b2dnbGVPYnNlcnZpbmcodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGluaXREYXRhICh2bSkge1xuICB2YXIgZGF0YSA9IHZtLiRvcHRpb25zLmRhdGE7XG4gIGRhdGEgPSB2bS5fZGF0YSA9IHR5cGVvZiBkYXRhID09PSAnZnVuY3Rpb24nXG4gICAgPyBnZXREYXRhKGRhdGEsIHZtKVxuICAgIDogZGF0YSB8fCB7fTtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGRhdGEpKSB7XG4gICAgZGF0YSA9IHt9O1xuICAgIHdhcm4oXG4gICAgICAnZGF0YSBmdW5jdGlvbnMgc2hvdWxkIHJldHVybiBhbiBvYmplY3Q6XFxuJyArXG4gICAgICAnaHR0cHM6Ly92dWVqcy5vcmcvdjIvZ3VpZGUvY29tcG9uZW50cy5odG1sI2RhdGEtTXVzdC1CZS1hLUZ1bmN0aW9uJyxcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxuICAvLyBwcm94eSBkYXRhIG9uIGluc3RhbmNlXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7XG4gIHZhciBwcm9wcyA9IHZtLiRvcHRpb25zLnByb3BzO1xuICB2YXIgbWV0aG9kcyA9IHZtLiRvcHRpb25zLm1ldGhvZHM7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICB7XG4gICAgICBpZiAobWV0aG9kcyAmJiBoYXNPd24obWV0aG9kcywga2V5KSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIChcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIGFzIGEgZGF0YSBwcm9wZXJ0eS5cIiksXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByb3BzICYmIGhhc093bihwcm9wcywga2V5KSkge1xuICAgICAgd2FybihcbiAgICAgICAgXCJUaGUgZGF0YSBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgYWxyZWFkeSBkZWNsYXJlZCBhcyBhIHByb3AuIFwiICtcbiAgICAgICAgXCJVc2UgcHJvcCBkZWZhdWx0IHZhbHVlIGluc3RlYWQuXCIsXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoIWlzUmVzZXJ2ZWQoa2V5KSkge1xuICAgICAgcHJveHkodm0sIFwiX2RhdGFcIiwga2V5KTtcbiAgICB9XG4gIH1cbiAgLy8gb2JzZXJ2ZSBkYXRhXG4gIG9ic2VydmUoZGF0YSwgdHJ1ZSAvKiBhc1Jvb3REYXRhICovKTtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0YSAoZGF0YSwgdm0pIHtcbiAgLy8gIzc1NzMgZGlzYWJsZSBkZXAgY29sbGVjdGlvbiB3aGVuIGludm9raW5nIGRhdGEgZ2V0dGVyc1xuICBwdXNoVGFyZ2V0KCk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRhdGEuY2FsbCh2bSwgdm0pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBoYW5kbGVFcnJvcihlLCB2bSwgXCJkYXRhKClcIik7XG4gICAgcmV0dXJuIHt9XG4gIH0gZmluYWxseSB7XG4gICAgcG9wVGFyZ2V0KCk7XG4gIH1cbn1cblxudmFyIGNvbXB1dGVkV2F0Y2hlck9wdGlvbnMgPSB7IGxhenk6IHRydWUgfTtcblxuZnVuY3Rpb24gaW5pdENvbXB1dGVkICh2bSwgY29tcHV0ZWQpIHtcbiAgLy8gJGZsb3ctZGlzYWJsZS1saW5lXG4gIHZhciB3YXRjaGVycyA9IHZtLl9jb21wdXRlZFdhdGNoZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgLy8gY29tcHV0ZWQgcHJvcGVydGllcyBhcmUganVzdCBnZXR0ZXJzIGR1cmluZyBTU1JcbiAgdmFyIGlzU1NSID0gaXNTZXJ2ZXJSZW5kZXJpbmcoKTtcblxuICBmb3IgKHZhciBrZXkgaW4gY29tcHV0ZWQpIHtcbiAgICB2YXIgdXNlckRlZiA9IGNvbXB1dGVkW2tleV07XG4gICAgdmFyIGdldHRlciA9IHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nID8gdXNlckRlZiA6IHVzZXJEZWYuZ2V0O1xuICAgIGlmIChnZXR0ZXIgPT0gbnVsbCkge1xuICAgICAgd2FybihcbiAgICAgICAgKFwiR2V0dGVyIGlzIG1pc3NpbmcgZm9yIGNvbXB1dGVkIHByb3BlcnR5IFxcXCJcIiArIGtleSArIFwiXFxcIi5cIiksXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghaXNTU1IpIHtcbiAgICAgIC8vIGNyZWF0ZSBpbnRlcm5hbCB3YXRjaGVyIGZvciB0aGUgY29tcHV0ZWQgcHJvcGVydHkuXG4gICAgICB3YXRjaGVyc1trZXldID0gbmV3IFdhdGNoZXIoXG4gICAgICAgIHZtLFxuICAgICAgICBnZXR0ZXIgfHwgbm9vcCxcbiAgICAgICAgbm9vcCxcbiAgICAgICAgY29tcHV0ZWRXYXRjaGVyT3B0aW9uc1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBjb21wb25lbnQtZGVmaW5lZCBjb21wdXRlZCBwcm9wZXJ0aWVzIGFyZSBhbHJlYWR5IGRlZmluZWQgb24gdGhlXG4gICAgLy8gY29tcG9uZW50IHByb3RvdHlwZS4gV2Ugb25seSBuZWVkIHRvIGRlZmluZSBjb21wdXRlZCBwcm9wZXJ0aWVzIGRlZmluZWRcbiAgICAvLyBhdCBpbnN0YW50aWF0aW9uIGhlcmUuXG4gICAgaWYgKCEoa2V5IGluIHZtKSkge1xuICAgICAgZGVmaW5lQ29tcHV0ZWQodm0sIGtleSwgdXNlckRlZik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChrZXkgaW4gdm0uJGRhdGEpIHtcbiAgICAgICAgd2FybigoXCJUaGUgY29tcHV0ZWQgcHJvcGVydHkgXFxcIlwiICsga2V5ICsgXCJcXFwiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBkYXRhLlwiKSwgdm0pO1xuICAgICAgfSBlbHNlIGlmICh2bS4kb3B0aW9ucy5wcm9wcyAmJiBrZXkgaW4gdm0uJG9wdGlvbnMucHJvcHMpIHtcbiAgICAgICAgd2FybigoXCJUaGUgY29tcHV0ZWQgcHJvcGVydHkgXFxcIlwiICsga2V5ICsgXCJcXFwiIGlzIGFscmVhZHkgZGVmaW5lZCBhcyBhIHByb3AuXCIpLCB2bSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRlZmluZUNvbXB1dGVkIChcbiAgdGFyZ2V0LFxuICBrZXksXG4gIHVzZXJEZWZcbikge1xuICB2YXIgc2hvdWxkQ2FjaGUgPSAhaXNTZXJ2ZXJSZW5kZXJpbmcoKTtcbiAgaWYgKHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLmdldCA9IHNob3VsZENhY2hlXG4gICAgICA/IGNyZWF0ZUNvbXB1dGVkR2V0dGVyKGtleSlcbiAgICAgIDogY3JlYXRlR2V0dGVySW52b2tlcih1c2VyRGVmKTtcbiAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uc2V0ID0gbm9vcDtcbiAgfSBlbHNlIHtcbiAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uZ2V0ID0gdXNlckRlZi5nZXRcbiAgICAgID8gc2hvdWxkQ2FjaGUgJiYgdXNlckRlZi5jYWNoZSAhPT0gZmFsc2VcbiAgICAgICAgPyBjcmVhdGVDb21wdXRlZEdldHRlcihrZXkpXG4gICAgICAgIDogY3JlYXRlR2V0dGVySW52b2tlcih1c2VyRGVmLmdldClcbiAgICAgIDogbm9vcDtcbiAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uc2V0ID0gdXNlckRlZi5zZXQgfHwgbm9vcDtcbiAgfVxuICBpZiAoc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9PT0gbm9vcCkge1xuICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5zZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAoXCJDb21wdXRlZCBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgd2FzIGFzc2lnbmVkIHRvIGJ1dCBpdCBoYXMgbm8gc2V0dGVyLlwiKSxcbiAgICAgICAgdGhpc1xuICAgICAgKTtcbiAgICB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29tcHV0ZWRHZXR0ZXIgKGtleSkge1xuICByZXR1cm4gZnVuY3Rpb24gY29tcHV0ZWRHZXR0ZXIgKCkge1xuICAgIHZhciB3YXRjaGVyID0gdGhpcy5fY29tcHV0ZWRXYXRjaGVycyAmJiB0aGlzLl9jb21wdXRlZFdhdGNoZXJzW2tleV07XG4gICAgaWYgKHdhdGNoZXIpIHtcbiAgICAgIGlmICh3YXRjaGVyLmRpcnR5KSB7XG4gICAgICAgIHdhdGNoZXIuZXZhbHVhdGUoKTtcbiAgICAgIH1cbiAgICAgIGlmIChEZXAudGFyZ2V0KSB7XG4gICAgICAgIHdhdGNoZXIuZGVwZW5kKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd2F0Y2hlci52YWx1ZVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVHZXR0ZXJJbnZva2VyKGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBjb21wdXRlZEdldHRlciAoKSB7XG4gICAgcmV0dXJuIGZuLmNhbGwodGhpcywgdGhpcylcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0TWV0aG9kcyAodm0sIG1ldGhvZHMpIHtcbiAgdmFyIHByb3BzID0gdm0uJG9wdGlvbnMucHJvcHM7XG4gIGZvciAodmFyIGtleSBpbiBtZXRob2RzKSB7XG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBtZXRob2RzW2tleV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICBcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaGFzIHR5cGUgXFxcIlwiICsgKHR5cGVvZiBtZXRob2RzW2tleV0pICsgXCJcXFwiIGluIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbi4gXCIgK1xuICAgICAgICAgIFwiRGlkIHlvdSByZWZlcmVuY2UgdGhlIGZ1bmN0aW9uIGNvcnJlY3RseT9cIixcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHByb3BzICYmIGhhc093bihwcm9wcywga2V5KSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIChcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIGFzIGEgcHJvcC5cIiksXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICgoa2V5IGluIHZtKSAmJiBpc1Jlc2VydmVkKGtleSkpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICBcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgVnVlIGluc3RhbmNlIG1ldGhvZC4gXCIgK1xuICAgICAgICAgIFwiQXZvaWQgZGVmaW5pbmcgY29tcG9uZW50IG1ldGhvZHMgdGhhdCBzdGFydCB3aXRoIF8gb3IgJC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICB2bVtrZXldID0gdHlwZW9mIG1ldGhvZHNba2V5XSAhPT0gJ2Z1bmN0aW9uJyA/IG5vb3AgOiBiaW5kKG1ldGhvZHNba2V5XSwgdm0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRXYXRjaCAodm0sIHdhdGNoKSB7XG4gIGZvciAodmFyIGtleSBpbiB3YXRjaCkge1xuICAgIHZhciBoYW5kbGVyID0gd2F0Y2hba2V5XTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShoYW5kbGVyKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYW5kbGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNyZWF0ZVdhdGNoZXIodm0sIGtleSwgaGFuZGxlcltpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNyZWF0ZVdhdGNoZXIodm0sIGtleSwgaGFuZGxlcik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIgKFxuICB2bSxcbiAgZXhwT3JGbixcbiAgaGFuZGxlcixcbiAgb3B0aW9uc1xuKSB7XG4gIGlmIChpc1BsYWluT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgb3B0aW9ucyA9IGhhbmRsZXI7XG4gICAgaGFuZGxlciA9IGhhbmRsZXIuaGFuZGxlcjtcbiAgfVxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgaGFuZGxlciA9IHZtW2hhbmRsZXJdO1xuICB9XG4gIHJldHVybiB2bS4kd2F0Y2goZXhwT3JGbiwgaGFuZGxlciwgb3B0aW9ucylcbn1cblxuZnVuY3Rpb24gc3RhdGVNaXhpbiAoVnVlKSB7XG4gIC8vIGZsb3cgc29tZWhvdyBoYXMgcHJvYmxlbXMgd2l0aCBkaXJlY3RseSBkZWNsYXJlZCBkZWZpbml0aW9uIG9iamVjdFxuICAvLyB3aGVuIHVzaW5nIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSwgc28gd2UgaGF2ZSB0byBwcm9jZWR1cmFsbHkgYnVpbGQgdXBcbiAgLy8gdGhlIG9iamVjdCBoZXJlLlxuICB2YXIgZGF0YURlZiA9IHt9O1xuICBkYXRhRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RhdGEgfTtcbiAgdmFyIHByb3BzRGVmID0ge307XG4gIHByb3BzRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX3Byb3BzIH07XG4gIHtcbiAgICBkYXRhRGVmLnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICdBdm9pZCByZXBsYWNpbmcgaW5zdGFuY2Ugcm9vdCAkZGF0YS4gJyArXG4gICAgICAgICdVc2UgbmVzdGVkIGRhdGEgcHJvcGVydGllcyBpbnN0ZWFkLicsXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgfTtcbiAgICBwcm9wc0RlZi5zZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB3YXJuKFwiJHByb3BzIGlzIHJlYWRvbmx5LlwiLCB0aGlzKTtcbiAgICB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWdWUucHJvdG90eXBlLCAnJGRhdGEnLCBkYXRhRGVmKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckcHJvcHMnLCBwcm9wc0RlZik7XG5cbiAgVnVlLnByb3RvdHlwZS4kc2V0ID0gc2V0O1xuICBWdWUucHJvdG90eXBlLiRkZWxldGUgPSBkZWw7XG5cbiAgVnVlLnByb3RvdHlwZS4kd2F0Y2ggPSBmdW5jdGlvbiAoXG4gICAgZXhwT3JGbixcbiAgICBjYixcbiAgICBvcHRpb25zXG4gICkge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QoY2IpKSB7XG4gICAgICByZXR1cm4gY3JlYXRlV2F0Y2hlcih2bSwgZXhwT3JGbiwgY2IsIG9wdGlvbnMpXG4gICAgfVxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIG9wdGlvbnMudXNlciA9IHRydWU7XG4gICAgdmFyIHdhdGNoZXIgPSBuZXcgV2F0Y2hlcih2bSwgZXhwT3JGbiwgY2IsIG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zLmltbWVkaWF0ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2IuY2FsbCh2bSwgd2F0Y2hlci52YWx1ZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgdm0sIChcImNhbGxiYWNrIGZvciBpbW1lZGlhdGUgd2F0Y2hlciBcXFwiXCIgKyAod2F0Y2hlci5leHByZXNzaW9uKSArIFwiXFxcIlwiKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmdW5jdGlvbiB1bndhdGNoRm4gKCkge1xuICAgICAgd2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH1cbiAgfTtcbn1cblxuLyogICovXG5cbnZhciB1aWQkMyA9IDA7XG5cbmZ1bmN0aW9uIGluaXRNaXhpbiAoVnVlKSB7XG4gIFZ1ZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgLy8gYSB1aWRcbiAgICB2bS5fdWlkID0gdWlkJDMrKztcblxuICAgIHZhciBzdGFydFRhZywgZW5kVGFnO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykge1xuICAgICAgc3RhcnRUYWcgPSBcInZ1ZS1wZXJmLXN0YXJ0OlwiICsgKHZtLl91aWQpO1xuICAgICAgZW5kVGFnID0gXCJ2dWUtcGVyZi1lbmQ6XCIgKyAodm0uX3VpZCk7XG4gICAgICBtYXJrKHN0YXJ0VGFnKTtcbiAgICB9XG5cbiAgICAvLyBhIGZsYWcgdG8gYXZvaWQgdGhpcyBiZWluZyBvYnNlcnZlZFxuICAgIHZtLl9pc1Z1ZSA9IHRydWU7XG4gICAgLy8gbWVyZ2Ugb3B0aW9uc1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuX2lzQ29tcG9uZW50KSB7XG4gICAgICAvLyBvcHRpbWl6ZSBpbnRlcm5hbCBjb21wb25lbnQgaW5zdGFudGlhdGlvblxuICAgICAgLy8gc2luY2UgZHluYW1pYyBvcHRpb25zIG1lcmdpbmcgaXMgcHJldHR5IHNsb3csIGFuZCBub25lIG9mIHRoZVxuICAgICAgLy8gaW50ZXJuYWwgY29tcG9uZW50IG9wdGlvbnMgbmVlZHMgc3BlY2lhbCB0cmVhdG1lbnQuXG4gICAgICBpbml0SW50ZXJuYWxDb21wb25lbnQodm0sIG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bS4kb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhcbiAgICAgICAgcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyh2bS5jb25zdHJ1Y3RvciksXG4gICAgICAgIG9wdGlvbnMgfHwge30sXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIHtcbiAgICAgIGluaXRQcm94eSh2bSk7XG4gICAgfVxuICAgIC8vIGV4cG9zZSByZWFsIHNlbGZcbiAgICB2bS5fc2VsZiA9IHZtO1xuICAgIGluaXRMaWZlY3ljbGUodm0pO1xuICAgIGluaXRFdmVudHModm0pO1xuICAgIGluaXRSZW5kZXIodm0pO1xuICAgIGNhbGxIb29rKHZtLCAnYmVmb3JlQ3JlYXRlJyk7XG4gICAgaW5pdEluamVjdGlvbnModm0pOyAvLyByZXNvbHZlIGluamVjdGlvbnMgYmVmb3JlIGRhdGEvcHJvcHNcbiAgICBpbml0U3RhdGUodm0pO1xuICAgIGluaXRQcm92aWRlKHZtKTsgLy8gcmVzb2x2ZSBwcm92aWRlIGFmdGVyIGRhdGEvcHJvcHNcbiAgICBjYWxsSG9vayh2bSwgJ2NyZWF0ZWQnKTtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykge1xuICAgICAgdm0uX25hbWUgPSBmb3JtYXRDb21wb25lbnROYW1lKHZtLCBmYWxzZSk7XG4gICAgICBtYXJrKGVuZFRhZyk7XG4gICAgICBtZWFzdXJlKChcInZ1ZSBcIiArICh2bS5fbmFtZSkgKyBcIiBpbml0XCIpLCBzdGFydFRhZywgZW5kVGFnKTtcbiAgICB9XG5cbiAgICBpZiAodm0uJG9wdGlvbnMuZWwpIHtcbiAgICAgIHZtLiRtb3VudCh2bS4kb3B0aW9ucy5lbCk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBpbml0SW50ZXJuYWxDb21wb25lbnQgKHZtLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gdm0uJG9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKHZtLmNvbnN0cnVjdG9yLm9wdGlvbnMpO1xuICAvLyBkb2luZyB0aGlzIGJlY2F1c2UgaXQncyBmYXN0ZXIgdGhhbiBkeW5hbWljIGVudW1lcmF0aW9uLlxuICB2YXIgcGFyZW50Vm5vZGUgPSBvcHRpb25zLl9wYXJlbnRWbm9kZTtcbiAgb3B0cy5wYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgb3B0cy5fcGFyZW50Vm5vZGUgPSBwYXJlbnRWbm9kZTtcblxuICB2YXIgdm5vZGVDb21wb25lbnRPcHRpb25zID0gcGFyZW50Vm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgb3B0cy5wcm9wc0RhdGEgPSB2bm9kZUNvbXBvbmVudE9wdGlvbnMucHJvcHNEYXRhO1xuICBvcHRzLl9wYXJlbnRMaXN0ZW5lcnMgPSB2bm9kZUNvbXBvbmVudE9wdGlvbnMubGlzdGVuZXJzO1xuICBvcHRzLl9yZW5kZXJDaGlsZHJlbiA9IHZub2RlQ29tcG9uZW50T3B0aW9ucy5jaGlsZHJlbjtcbiAgb3B0cy5fY29tcG9uZW50VGFnID0gdm5vZGVDb21wb25lbnRPcHRpb25zLnRhZztcblxuICBpZiAob3B0aW9ucy5yZW5kZXIpIHtcbiAgICBvcHRzLnJlbmRlciA9IG9wdGlvbnMucmVuZGVyO1xuICAgIG9wdHMuc3RhdGljUmVuZGVyRm5zID0gb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnM7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyAoQ3Rvcikge1xuICB2YXIgb3B0aW9ucyA9IEN0b3Iub3B0aW9ucztcbiAgaWYgKEN0b3Iuc3VwZXIpIHtcbiAgICB2YXIgc3VwZXJPcHRpb25zID0gcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyhDdG9yLnN1cGVyKTtcbiAgICB2YXIgY2FjaGVkU3VwZXJPcHRpb25zID0gQ3Rvci5zdXBlck9wdGlvbnM7XG4gICAgaWYgKHN1cGVyT3B0aW9ucyAhPT0gY2FjaGVkU3VwZXJPcHRpb25zKSB7XG4gICAgICAvLyBzdXBlciBvcHRpb24gY2hhbmdlZCxcbiAgICAgIC8vIG5lZWQgdG8gcmVzb2x2ZSBuZXcgb3B0aW9ucy5cbiAgICAgIEN0b3Iuc3VwZXJPcHRpb25zID0gc3VwZXJPcHRpb25zO1xuICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgYXJlIGFueSBsYXRlLW1vZGlmaWVkL2F0dGFjaGVkIG9wdGlvbnMgKCM0OTc2KVxuICAgICAgdmFyIG1vZGlmaWVkT3B0aW9ucyA9IHJlc29sdmVNb2RpZmllZE9wdGlvbnMoQ3Rvcik7XG4gICAgICAvLyB1cGRhdGUgYmFzZSBleHRlbmQgb3B0aW9uc1xuICAgICAgaWYgKG1vZGlmaWVkT3B0aW9ucykge1xuICAgICAgICBleHRlbmQoQ3Rvci5leHRlbmRPcHRpb25zLCBtb2RpZmllZE9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgb3B0aW9ucyA9IEN0b3Iub3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhzdXBlck9wdGlvbnMsIEN0b3IuZXh0ZW5kT3B0aW9ucyk7XG4gICAgICBpZiAob3B0aW9ucy5uYW1lKSB7XG4gICAgICAgIG9wdGlvbnMuY29tcG9uZW50c1tvcHRpb25zLm5hbWVdID0gQ3RvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZU1vZGlmaWVkT3B0aW9ucyAoQ3Rvcikge1xuICB2YXIgbW9kaWZpZWQ7XG4gIHZhciBsYXRlc3QgPSBDdG9yLm9wdGlvbnM7XG4gIHZhciBzZWFsZWQgPSBDdG9yLnNlYWxlZE9wdGlvbnM7XG4gIGZvciAodmFyIGtleSBpbiBsYXRlc3QpIHtcbiAgICBpZiAobGF0ZXN0W2tleV0gIT09IHNlYWxlZFtrZXldKSB7XG4gICAgICBpZiAoIW1vZGlmaWVkKSB7IG1vZGlmaWVkID0ge307IH1cbiAgICAgIG1vZGlmaWVkW2tleV0gPSBsYXRlc3Rba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1vZGlmaWVkXG59XG5cbmZ1bmN0aW9uIFZ1ZSAob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVnVlKVxuICApIHtcbiAgICB3YXJuKCdWdWUgaXMgYSBjb25zdHJ1Y3RvciBhbmQgc2hvdWxkIGJlIGNhbGxlZCB3aXRoIHRoZSBgbmV3YCBrZXl3b3JkJyk7XG4gIH1cbiAgdGhpcy5faW5pdChvcHRpb25zKTtcbn1cblxuaW5pdE1peGluKFZ1ZSk7XG5zdGF0ZU1peGluKFZ1ZSk7XG5ldmVudHNNaXhpbihWdWUpO1xubGlmZWN5Y2xlTWl4aW4oVnVlKTtcbnJlbmRlck1peGluKFZ1ZSk7XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0VXNlIChWdWUpIHtcbiAgVnVlLnVzZSA9IGZ1bmN0aW9uIChwbHVnaW4pIHtcbiAgICB2YXIgaW5zdGFsbGVkUGx1Z2lucyA9ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zIHx8ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zID0gW10pKTtcbiAgICBpZiAoaW5zdGFsbGVkUGx1Z2lucy5pbmRleE9mKHBsdWdpbikgPiAtMSkge1xuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvLyBhZGRpdGlvbmFsIHBhcmFtZXRlcnNcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzLCAxKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgaWYgKHR5cGVvZiBwbHVnaW4uaW5zdGFsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcGx1Z2luLmluc3RhbGwuYXBwbHkocGx1Z2luLCBhcmdzKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwbHVnaW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBsdWdpbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9XG4gICAgaW5zdGFsbGVkUGx1Z2lucy5wdXNoKHBsdWdpbik7XG4gICAgcmV0dXJuIHRoaXNcbiAgfTtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRNaXhpbiQxIChWdWUpIHtcbiAgVnVlLm1peGluID0gZnVuY3Rpb24gKG1peGluKSB7XG4gICAgdGhpcy5vcHRpb25zID0gbWVyZ2VPcHRpb25zKHRoaXMub3B0aW9ucywgbWl4aW4pO1xuICAgIHJldHVybiB0aGlzXG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXh0ZW5kIChWdWUpIHtcbiAgLyoqXG4gICAqIEVhY2ggaW5zdGFuY2UgY29uc3RydWN0b3IsIGluY2x1ZGluZyBWdWUsIGhhcyBhIHVuaXF1ZVxuICAgKiBjaWQuIFRoaXMgZW5hYmxlcyB1cyB0byBjcmVhdGUgd3JhcHBlZCBcImNoaWxkXG4gICAqIGNvbnN0cnVjdG9yc1wiIGZvciBwcm90b3R5cGFsIGluaGVyaXRhbmNlIGFuZCBjYWNoZSB0aGVtLlxuICAgKi9cbiAgVnVlLmNpZCA9IDA7XG4gIHZhciBjaWQgPSAxO1xuXG4gIC8qKlxuICAgKiBDbGFzcyBpbmhlcml0YW5jZVxuICAgKi9cbiAgVnVlLmV4dGVuZCA9IGZ1bmN0aW9uIChleHRlbmRPcHRpb25zKSB7XG4gICAgZXh0ZW5kT3B0aW9ucyA9IGV4dGVuZE9wdGlvbnMgfHwge307XG4gICAgdmFyIFN1cGVyID0gdGhpcztcbiAgICB2YXIgU3VwZXJJZCA9IFN1cGVyLmNpZDtcbiAgICB2YXIgY2FjaGVkQ3RvcnMgPSBleHRlbmRPcHRpb25zLl9DdG9yIHx8IChleHRlbmRPcHRpb25zLl9DdG9yID0ge30pO1xuICAgIGlmIChjYWNoZWRDdG9yc1tTdXBlcklkXSkge1xuICAgICAgcmV0dXJuIGNhY2hlZEN0b3JzW1N1cGVySWRdXG4gICAgfVxuXG4gICAgdmFyIG5hbWUgPSBleHRlbmRPcHRpb25zLm5hbWUgfHwgU3VwZXIub3B0aW9ucy5uYW1lO1xuICAgIGlmIChuYW1lKSB7XG4gICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSk7XG4gICAgfVxuXG4gICAgdmFyIFN1YiA9IGZ1bmN0aW9uIFZ1ZUNvbXBvbmVudCAob3B0aW9ucykge1xuICAgICAgdGhpcy5faW5pdChvcHRpb25zKTtcbiAgICB9O1xuICAgIFN1Yi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN1cGVyLnByb3RvdHlwZSk7XG4gICAgU3ViLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFN1YjtcbiAgICBTdWIuY2lkID0gY2lkKys7XG4gICAgU3ViLm9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoXG4gICAgICBTdXBlci5vcHRpb25zLFxuICAgICAgZXh0ZW5kT3B0aW9uc1xuICAgICk7XG4gICAgU3ViWydzdXBlciddID0gU3VwZXI7XG5cbiAgICAvLyBGb3IgcHJvcHMgYW5kIGNvbXB1dGVkIHByb3BlcnRpZXMsIHdlIGRlZmluZSB0aGUgcHJveHkgZ2V0dGVycyBvblxuICAgIC8vIHRoZSBWdWUgaW5zdGFuY2VzIGF0IGV4dGVuc2lvbiB0aW1lLCBvbiB0aGUgZXh0ZW5kZWQgcHJvdG90eXBlLiBUaGlzXG4gICAgLy8gYXZvaWRzIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSBjYWxscyBmb3IgZWFjaCBpbnN0YW5jZSBjcmVhdGVkLlxuICAgIGlmIChTdWIub3B0aW9ucy5wcm9wcykge1xuICAgICAgaW5pdFByb3BzJDEoU3ViKTtcbiAgICB9XG4gICAgaWYgKFN1Yi5vcHRpb25zLmNvbXB1dGVkKSB7XG4gICAgICBpbml0Q29tcHV0ZWQkMShTdWIpO1xuICAgIH1cblxuICAgIC8vIGFsbG93IGZ1cnRoZXIgZXh0ZW5zaW9uL21peGluL3BsdWdpbiB1c2FnZVxuICAgIFN1Yi5leHRlbmQgPSBTdXBlci5leHRlbmQ7XG4gICAgU3ViLm1peGluID0gU3VwZXIubWl4aW47XG4gICAgU3ViLnVzZSA9IFN1cGVyLnVzZTtcblxuICAgIC8vIGNyZWF0ZSBhc3NldCByZWdpc3RlcnMsIHNvIGV4dGVuZGVkIGNsYXNzZXNcbiAgICAvLyBjYW4gaGF2ZSB0aGVpciBwcml2YXRlIGFzc2V0cyB0b28uXG4gICAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgICAgU3ViW3R5cGVdID0gU3VwZXJbdHlwZV07XG4gICAgfSk7XG4gICAgLy8gZW5hYmxlIHJlY3Vyc2l2ZSBzZWxmLWxvb2t1cFxuICAgIGlmIChuYW1lKSB7XG4gICAgICBTdWIub3B0aW9ucy5jb21wb25lbnRzW25hbWVdID0gU3ViO1xuICAgIH1cblxuICAgIC8vIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIHN1cGVyIG9wdGlvbnMgYXQgZXh0ZW5zaW9uIHRpbWUuXG4gICAgLy8gbGF0ZXIgYXQgaW5zdGFudGlhdGlvbiB3ZSBjYW4gY2hlY2sgaWYgU3VwZXIncyBvcHRpb25zIGhhdmVcbiAgICAvLyBiZWVuIHVwZGF0ZWQuXG4gICAgU3ViLnN1cGVyT3B0aW9ucyA9IFN1cGVyLm9wdGlvbnM7XG4gICAgU3ViLmV4dGVuZE9wdGlvbnMgPSBleHRlbmRPcHRpb25zO1xuICAgIFN1Yi5zZWFsZWRPcHRpb25zID0gZXh0ZW5kKHt9LCBTdWIub3B0aW9ucyk7XG5cbiAgICAvLyBjYWNoZSBjb25zdHJ1Y3RvclxuICAgIGNhY2hlZEN0b3JzW1N1cGVySWRdID0gU3ViO1xuICAgIHJldHVybiBTdWJcbiAgfTtcbn1cblxuZnVuY3Rpb24gaW5pdFByb3BzJDEgKENvbXApIHtcbiAgdmFyIHByb3BzID0gQ29tcC5vcHRpb25zLnByb3BzO1xuICBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHtcbiAgICBwcm94eShDb21wLnByb3RvdHlwZSwgXCJfcHJvcHNcIiwga2V5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0Q29tcHV0ZWQkMSAoQ29tcCkge1xuICB2YXIgY29tcHV0ZWQgPSBDb21wLm9wdGlvbnMuY29tcHV0ZWQ7XG4gIGZvciAodmFyIGtleSBpbiBjb21wdXRlZCkge1xuICAgIGRlZmluZUNvbXB1dGVkKENvbXAucHJvdG90eXBlLCBrZXksIGNvbXB1dGVkW2tleV0pO1xuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0QXNzZXRSZWdpc3RlcnMgKFZ1ZSkge1xuICAvKipcbiAgICogQ3JlYXRlIGFzc2V0IHJlZ2lzdHJhdGlvbiBtZXRob2RzLlxuICAgKi9cbiAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIFZ1ZVt0eXBlXSA9IGZ1bmN0aW9uIChcbiAgICAgIGlkLFxuICAgICAgZGVmaW5pdGlvblxuICAgICkge1xuICAgICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnNbdHlwZSArICdzJ11baWRdXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKHR5cGUgPT09ICdjb21wb25lbnQnKSB7XG4gICAgICAgICAgdmFsaWRhdGVDb21wb25lbnROYW1lKGlkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2NvbXBvbmVudCcgJiYgaXNQbGFpbk9iamVjdChkZWZpbml0aW9uKSkge1xuICAgICAgICAgIGRlZmluaXRpb24ubmFtZSA9IGRlZmluaXRpb24ubmFtZSB8fCBpZDtcbiAgICAgICAgICBkZWZpbml0aW9uID0gdGhpcy5vcHRpb25zLl9iYXNlLmV4dGVuZChkZWZpbml0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2RpcmVjdGl2ZScgJiYgdHlwZW9mIGRlZmluaXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBkZWZpbml0aW9uID0geyBiaW5kOiBkZWZpbml0aW9uLCB1cGRhdGU6IGRlZmluaXRpb24gfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnNbdHlwZSArICdzJ11baWRdID0gZGVmaW5pdGlvbjtcbiAgICAgICAgcmV0dXJuIGRlZmluaXRpb25cbiAgICAgIH1cbiAgICB9O1xuICB9KTtcbn1cblxuLyogICovXG5cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnROYW1lIChvcHRzKSB7XG4gIHJldHVybiBvcHRzICYmIChvcHRzLkN0b3Iub3B0aW9ucy5uYW1lIHx8IG9wdHMudGFnKVxufVxuXG5mdW5jdGlvbiBtYXRjaGVzIChwYXR0ZXJuLCBuYW1lKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHBhdHRlcm4pKSB7XG4gICAgcmV0dXJuIHBhdHRlcm4uaW5kZXhPZihuYW1lKSA+IC0xXG4gIH0gZWxzZSBpZiAodHlwZW9mIHBhdHRlcm4gPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHBhdHRlcm4uc3BsaXQoJywnKS5pbmRleE9mKG5hbWUpID4gLTFcbiAgfSBlbHNlIGlmIChpc1JlZ0V4cChwYXR0ZXJuKSkge1xuICAgIHJldHVybiBwYXR0ZXJuLnRlc3QobmFtZSlcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gcHJ1bmVDYWNoZSAoa2VlcEFsaXZlSW5zdGFuY2UsIGZpbHRlcikge1xuICB2YXIgY2FjaGUgPSBrZWVwQWxpdmVJbnN0YW5jZS5jYWNoZTtcbiAgdmFyIGtleXMgPSBrZWVwQWxpdmVJbnN0YW5jZS5rZXlzO1xuICB2YXIgX3Zub2RlID0ga2VlcEFsaXZlSW5zdGFuY2UuX3Zub2RlO1xuICBmb3IgKHZhciBrZXkgaW4gY2FjaGUpIHtcbiAgICB2YXIgY2FjaGVkTm9kZSA9IGNhY2hlW2tleV07XG4gICAgaWYgKGNhY2hlZE5vZGUpIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZShjYWNoZWROb2RlLmNvbXBvbmVudE9wdGlvbnMpO1xuICAgICAgaWYgKG5hbWUgJiYgIWZpbHRlcihuYW1lKSkge1xuICAgICAgICBwcnVuZUNhY2hlRW50cnkoY2FjaGUsIGtleSwga2V5cywgX3Zub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJ1bmVDYWNoZUVudHJ5IChcbiAgY2FjaGUsXG4gIGtleSxcbiAga2V5cyxcbiAgY3VycmVudFxuKSB7XG4gIHZhciBjYWNoZWQkJDEgPSBjYWNoZVtrZXldO1xuICBpZiAoY2FjaGVkJCQxICYmICghY3VycmVudCB8fCBjYWNoZWQkJDEudGFnICE9PSBjdXJyZW50LnRhZykpIHtcbiAgICBjYWNoZWQkJDEuY29tcG9uZW50SW5zdGFuY2UuJGRlc3Ryb3koKTtcbiAgfVxuICBjYWNoZVtrZXldID0gbnVsbDtcbiAgcmVtb3ZlKGtleXMsIGtleSk7XG59XG5cbnZhciBwYXR0ZXJuVHlwZXMgPSBbU3RyaW5nLCBSZWdFeHAsIEFycmF5XTtcblxudmFyIEtlZXBBbGl2ZSA9IHtcbiAgbmFtZTogJ2tlZXAtYWxpdmUnLFxuICBhYnN0cmFjdDogdHJ1ZSxcblxuICBwcm9wczoge1xuICAgIGluY2x1ZGU6IHBhdHRlcm5UeXBlcyxcbiAgICBleGNsdWRlOiBwYXR0ZXJuVHlwZXMsXG4gICAgbWF4OiBbU3RyaW5nLCBOdW1iZXJdXG4gIH0sXG5cbiAgY3JlYXRlZDogZnVuY3Rpb24gY3JlYXRlZCAoKSB7XG4gICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy5rZXlzID0gW107XG4gIH0sXG5cbiAgZGVzdHJveWVkOiBmdW5jdGlvbiBkZXN0cm95ZWQgKCkge1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmNhY2hlKSB7XG4gICAgICBwcnVuZUNhY2hlRW50cnkodGhpcy5jYWNoZSwga2V5LCB0aGlzLmtleXMpO1xuICAgIH1cbiAgfSxcblxuICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHRoaXMuJHdhdGNoKCdpbmNsdWRlJywgZnVuY3Rpb24gKHZhbCkge1xuICAgICAgcHJ1bmVDYWNoZSh0aGlzJDEsIGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBtYXRjaGVzKHZhbCwgbmFtZSk7IH0pO1xuICAgIH0pO1xuICAgIHRoaXMuJHdhdGNoKCdleGNsdWRlJywgZnVuY3Rpb24gKHZhbCkge1xuICAgICAgcHJ1bmVDYWNoZSh0aGlzJDEsIGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiAhbWF0Y2hlcyh2YWwsIG5hbWUpOyB9KTtcbiAgICB9KTtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlciAoKSB7XG4gICAgdmFyIHNsb3QgPSB0aGlzLiRzbG90cy5kZWZhdWx0O1xuICAgIHZhciB2bm9kZSA9IGdldEZpcnN0Q29tcG9uZW50Q2hpbGQoc2xvdCk7XG4gICAgdmFyIGNvbXBvbmVudE9wdGlvbnMgPSB2bm9kZSAmJiB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICAgIGlmIChjb21wb25lbnRPcHRpb25zKSB7XG4gICAgICAvLyBjaGVjayBwYXR0ZXJuXG4gICAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWUoY29tcG9uZW50T3B0aW9ucyk7XG4gICAgICB2YXIgcmVmID0gdGhpcztcbiAgICAgIHZhciBpbmNsdWRlID0gcmVmLmluY2x1ZGU7XG4gICAgICB2YXIgZXhjbHVkZSA9IHJlZi5leGNsdWRlO1xuICAgICAgaWYgKFxuICAgICAgICAvLyBub3QgaW5jbHVkZWRcbiAgICAgICAgKGluY2x1ZGUgJiYgKCFuYW1lIHx8ICFtYXRjaGVzKGluY2x1ZGUsIG5hbWUpKSkgfHxcbiAgICAgICAgLy8gZXhjbHVkZWRcbiAgICAgICAgKGV4Y2x1ZGUgJiYgbmFtZSAmJiBtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB2bm9kZVxuICAgICAgfVxuXG4gICAgICB2YXIgcmVmJDEgPSB0aGlzO1xuICAgICAgdmFyIGNhY2hlID0gcmVmJDEuY2FjaGU7XG4gICAgICB2YXIga2V5cyA9IHJlZiQxLmtleXM7XG4gICAgICB2YXIga2V5ID0gdm5vZGUua2V5ID09IG51bGxcbiAgICAgICAgLy8gc2FtZSBjb25zdHJ1Y3RvciBtYXkgZ2V0IHJlZ2lzdGVyZWQgYXMgZGlmZmVyZW50IGxvY2FsIGNvbXBvbmVudHNcbiAgICAgICAgLy8gc28gY2lkIGFsb25lIGlzIG5vdCBlbm91Z2ggKCMzMjY5KVxuICAgICAgICA/IGNvbXBvbmVudE9wdGlvbnMuQ3Rvci5jaWQgKyAoY29tcG9uZW50T3B0aW9ucy50YWcgPyAoXCI6OlwiICsgKGNvbXBvbmVudE9wdGlvbnMudGFnKSkgOiAnJylcbiAgICAgICAgOiB2bm9kZS5rZXk7XG4gICAgICBpZiAoY2FjaGVba2V5XSkge1xuICAgICAgICB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSA9IGNhY2hlW2tleV0uY29tcG9uZW50SW5zdGFuY2U7XG4gICAgICAgIC8vIG1ha2UgY3VycmVudCBrZXkgZnJlc2hlc3RcbiAgICAgICAgcmVtb3ZlKGtleXMsIGtleSk7XG4gICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FjaGVba2V5XSA9IHZub2RlO1xuICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgLy8gcHJ1bmUgb2xkZXN0IGVudHJ5XG4gICAgICAgIGlmICh0aGlzLm1heCAmJiBrZXlzLmxlbmd0aCA+IHBhcnNlSW50KHRoaXMubWF4KSkge1xuICAgICAgICAgIHBydW5lQ2FjaGVFbnRyeShjYWNoZSwga2V5c1swXSwga2V5cywgdGhpcy5fdm5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZub2RlLmRhdGEua2VlcEFsaXZlID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHZub2RlIHx8IChzbG90ICYmIHNsb3RbMF0pXG4gIH1cbn07XG5cbnZhciBidWlsdEluQ29tcG9uZW50cyA9IHtcbiAgS2VlcEFsaXZlOiBLZWVwQWxpdmVcbn07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0R2xvYmFsQVBJIChWdWUpIHtcbiAgLy8gY29uZmlnXG4gIHZhciBjb25maWdEZWYgPSB7fTtcbiAgY29uZmlnRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbmZpZzsgfTtcbiAge1xuICAgIGNvbmZpZ0RlZi5zZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAnRG8gbm90IHJlcGxhY2UgdGhlIFZ1ZS5jb25maWcgb2JqZWN0LCBzZXQgaW5kaXZpZHVhbCBmaWVsZHMgaW5zdGVhZC4nXG4gICAgICApO1xuICAgIH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZSwgJ2NvbmZpZycsIGNvbmZpZ0RlZik7XG5cbiAgLy8gZXhwb3NlZCB1dGlsIG1ldGhvZHMuXG4gIC8vIE5PVEU6IHRoZXNlIGFyZSBub3QgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJIC0gYXZvaWQgcmVseWluZyBvblxuICAvLyB0aGVtIHVubGVzcyB5b3UgYXJlIGF3YXJlIG9mIHRoZSByaXNrLlxuICBWdWUudXRpbCA9IHtcbiAgICB3YXJuOiB3YXJuLFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIG1lcmdlT3B0aW9uczogbWVyZ2VPcHRpb25zLFxuICAgIGRlZmluZVJlYWN0aXZlOiBkZWZpbmVSZWFjdGl2ZSQkMVxuICB9O1xuXG4gIFZ1ZS5zZXQgPSBzZXQ7XG4gIFZ1ZS5kZWxldGUgPSBkZWw7XG4gIFZ1ZS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4gIC8vIDIuNiBleHBsaWNpdCBvYnNlcnZhYmxlIEFQSVxuICBWdWUub2JzZXJ2YWJsZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBvYnNlcnZlKG9iaik7XG4gICAgcmV0dXJuIG9ialxuICB9O1xuXG4gIFZ1ZS5vcHRpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIFZ1ZS5vcHRpb25zW3R5cGUgKyAncyddID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfSk7XG5cbiAgLy8gdGhpcyBpcyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBcImJhc2VcIiBjb25zdHJ1Y3RvciB0byBleHRlbmQgYWxsIHBsYWluLW9iamVjdFxuICAvLyBjb21wb25lbnRzIHdpdGggaW4gV2VleCdzIG11bHRpLWluc3RhbmNlIHNjZW5hcmlvcy5cbiAgVnVlLm9wdGlvbnMuX2Jhc2UgPSBWdWU7XG5cbiAgZXh0ZW5kKFZ1ZS5vcHRpb25zLmNvbXBvbmVudHMsIGJ1aWx0SW5Db21wb25lbnRzKTtcblxuICBpbml0VXNlKFZ1ZSk7XG4gIGluaXRNaXhpbiQxKFZ1ZSk7XG4gIGluaXRFeHRlbmQoVnVlKTtcbiAgaW5pdEFzc2V0UmVnaXN0ZXJzKFZ1ZSk7XG59XG5cbmluaXRHbG9iYWxBUEkoVnVlKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckaXNTZXJ2ZXInLCB7XG4gIGdldDogaXNTZXJ2ZXJSZW5kZXJpbmdcbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlLnByb3RvdHlwZSwgJyRzc3JDb250ZXh0Jywge1xuICBnZXQ6IGZ1bmN0aW9uIGdldCAoKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gdGhpcy4kdm5vZGUgJiYgdGhpcy4kdm5vZGUuc3NyQ29udGV4dFxuICB9XG59KTtcblxuLy8gZXhwb3NlIEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0IGZvciBzc3IgcnVudGltZSBoZWxwZXIgaW5zdGFsbGF0aW9uXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlLCAnRnVuY3Rpb25hbFJlbmRlckNvbnRleHQnLCB7XG4gIHZhbHVlOiBGdW5jdGlvbmFsUmVuZGVyQ29udGV4dFxufSk7XG5cblZ1ZS52ZXJzaW9uID0gJzIuNi4xMic7XG5cbi8qICAqL1xuXG4vLyB0aGVzZSBhcmUgcmVzZXJ2ZWQgZm9yIHdlYiBiZWNhdXNlIHRoZXkgYXJlIGRpcmVjdGx5IGNvbXBpbGVkIGF3YXlcbi8vIGR1cmluZyB0ZW1wbGF0ZSBjb21waWxhdGlvblxudmFyIGlzUmVzZXJ2ZWRBdHRyID0gbWFrZU1hcCgnc3R5bGUsY2xhc3MnKTtcblxuLy8gYXR0cmlidXRlcyB0aGF0IHNob3VsZCBiZSB1c2luZyBwcm9wcyBmb3IgYmluZGluZ1xudmFyIGFjY2VwdFZhbHVlID0gbWFrZU1hcCgnaW5wdXQsdGV4dGFyZWEsb3B0aW9uLHNlbGVjdCxwcm9ncmVzcycpO1xudmFyIG11c3RVc2VQcm9wID0gZnVuY3Rpb24gKHRhZywgdHlwZSwgYXR0cikge1xuICByZXR1cm4gKFxuICAgIChhdHRyID09PSAndmFsdWUnICYmIGFjY2VwdFZhbHVlKHRhZykpICYmIHR5cGUgIT09ICdidXR0b24nIHx8XG4gICAgKGF0dHIgPT09ICdzZWxlY3RlZCcgJiYgdGFnID09PSAnb3B0aW9uJykgfHxcbiAgICAoYXR0ciA9PT0gJ2NoZWNrZWQnICYmIHRhZyA9PT0gJ2lucHV0JykgfHxcbiAgICAoYXR0ciA9PT0gJ211dGVkJyAmJiB0YWcgPT09ICd2aWRlbycpXG4gIClcbn07XG5cbnZhciBpc0VudW1lcmF0ZWRBdHRyID0gbWFrZU1hcCgnY29udGVudGVkaXRhYmxlLGRyYWdnYWJsZSxzcGVsbGNoZWNrJyk7XG5cbnZhciBpc1ZhbGlkQ29udGVudEVkaXRhYmxlVmFsdWUgPSBtYWtlTWFwKCdldmVudHMsY2FyZXQsdHlwaW5nLHBsYWludGV4dC1vbmx5Jyk7XG5cbnZhciBjb252ZXJ0RW51bWVyYXRlZFZhbHVlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpIHx8IHZhbHVlID09PSAnZmFsc2UnXG4gICAgPyAnZmFsc2UnXG4gICAgLy8gYWxsb3cgYXJiaXRyYXJ5IHN0cmluZyB2YWx1ZSBmb3IgY29udGVudGVkaXRhYmxlXG4gICAgOiBrZXkgPT09ICdjb250ZW50ZWRpdGFibGUnICYmIGlzVmFsaWRDb250ZW50RWRpdGFibGVWYWx1ZSh2YWx1ZSlcbiAgICAgID8gdmFsdWVcbiAgICAgIDogJ3RydWUnXG59O1xuXG52YXIgaXNCb29sZWFuQXR0ciA9IG1ha2VNYXAoXG4gICdhbGxvd2Z1bGxzY3JlZW4sYXN5bmMsYXV0b2ZvY3VzLGF1dG9wbGF5LGNoZWNrZWQsY29tcGFjdCxjb250cm9scyxkZWNsYXJlLCcgK1xuICAnZGVmYXVsdCxkZWZhdWx0Y2hlY2tlZCxkZWZhdWx0bXV0ZWQsZGVmYXVsdHNlbGVjdGVkLGRlZmVyLGRpc2FibGVkLCcgK1xuICAnZW5hYmxlZCxmb3Jtbm92YWxpZGF0ZSxoaWRkZW4saW5kZXRlcm1pbmF0ZSxpbmVydCxpc21hcCxpdGVtc2NvcGUsbG9vcCxtdWx0aXBsZSwnICtcbiAgJ211dGVkLG5vaHJlZixub3Jlc2l6ZSxub3NoYWRlLG5vdmFsaWRhdGUsbm93cmFwLG9wZW4scGF1c2VvbmV4aXQscmVhZG9ubHksJyArXG4gICdyZXF1aXJlZCxyZXZlcnNlZCxzY29wZWQsc2VhbWxlc3Msc2VsZWN0ZWQsc29ydGFibGUsdHJhbnNsYXRlLCcgK1xuICAndHJ1ZXNwZWVkLHR5cGVtdXN0bWF0Y2gsdmlzaWJsZSdcbik7XG5cbnZhciB4bGlua05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnO1xuXG52YXIgaXNYbGluayA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBuYW1lLmNoYXJBdCg1KSA9PT0gJzonICYmIG5hbWUuc2xpY2UoMCwgNSkgPT09ICd4bGluaydcbn07XG5cbnZhciBnZXRYbGlua1Byb3AgPSBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gaXNYbGluayhuYW1lKSA/IG5hbWUuc2xpY2UoNiwgbmFtZS5sZW5ndGgpIDogJydcbn07XG5cbnZhciBpc0ZhbHN5QXR0clZhbHVlID0gZnVuY3Rpb24gKHZhbCkge1xuICByZXR1cm4gdmFsID09IG51bGwgfHwgdmFsID09PSBmYWxzZVxufTtcblxuLyogICovXG5cbmZ1bmN0aW9uIGdlbkNsYXNzRm9yVm5vZGUgKHZub2RlKSB7XG4gIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgdmFyIHBhcmVudE5vZGUgPSB2bm9kZTtcbiAgdmFyIGNoaWxkTm9kZSA9IHZub2RlO1xuICB3aGlsZSAoaXNEZWYoY2hpbGROb2RlLmNvbXBvbmVudEluc3RhbmNlKSkge1xuICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZS5jb21wb25lbnRJbnN0YW5jZS5fdm5vZGU7XG4gICAgaWYgKGNoaWxkTm9kZSAmJiBjaGlsZE5vZGUuZGF0YSkge1xuICAgICAgZGF0YSA9IG1lcmdlQ2xhc3NEYXRhKGNoaWxkTm9kZS5kYXRhLCBkYXRhKTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKGlzRGVmKHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLnBhcmVudCkpIHtcbiAgICBpZiAocGFyZW50Tm9kZSAmJiBwYXJlbnROb2RlLmRhdGEpIHtcbiAgICAgIGRhdGEgPSBtZXJnZUNsYXNzRGF0YShkYXRhLCBwYXJlbnROb2RlLmRhdGEpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVuZGVyQ2xhc3MoZGF0YS5zdGF0aWNDbGFzcywgZGF0YS5jbGFzcylcbn1cblxuZnVuY3Rpb24gbWVyZ2VDbGFzc0RhdGEgKGNoaWxkLCBwYXJlbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBzdGF0aWNDbGFzczogY29uY2F0KGNoaWxkLnN0YXRpY0NsYXNzLCBwYXJlbnQuc3RhdGljQ2xhc3MpLFxuICAgIGNsYXNzOiBpc0RlZihjaGlsZC5jbGFzcylcbiAgICAgID8gW2NoaWxkLmNsYXNzLCBwYXJlbnQuY2xhc3NdXG4gICAgICA6IHBhcmVudC5jbGFzc1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNsYXNzIChcbiAgc3RhdGljQ2xhc3MsXG4gIGR5bmFtaWNDbGFzc1xuKSB7XG4gIGlmIChpc0RlZihzdGF0aWNDbGFzcykgfHwgaXNEZWYoZHluYW1pY0NsYXNzKSkge1xuICAgIHJldHVybiBjb25jYXQoc3RhdGljQ2xhc3MsIHN0cmluZ2lmeUNsYXNzKGR5bmFtaWNDbGFzcykpXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgcmV0dXJuICcnXG59XG5cbmZ1bmN0aW9uIGNvbmNhdCAoYSwgYikge1xuICByZXR1cm4gYSA/IGIgPyAoYSArICcgJyArIGIpIDogYSA6IChiIHx8ICcnKVxufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnlDbGFzcyAodmFsdWUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHN0cmluZ2lmeUFycmF5KHZhbHVlKVxuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gc3RyaW5naWZ5T2JqZWN0KHZhbHVlKVxuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgcmV0dXJuICcnXG59XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeUFycmF5ICh2YWx1ZSkge1xuICB2YXIgcmVzID0gJyc7XG4gIHZhciBzdHJpbmdpZmllZDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoaXNEZWYoc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlDbGFzcyh2YWx1ZVtpXSkpICYmIHN0cmluZ2lmaWVkICE9PSAnJykge1xuICAgICAgaWYgKHJlcykgeyByZXMgKz0gJyAnOyB9XG4gICAgICByZXMgKz0gc3RyaW5naWZpZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5T2JqZWN0ICh2YWx1ZSkge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICh2YWx1ZVtrZXldKSB7XG4gICAgICBpZiAocmVzKSB7IHJlcyArPSAnICc7IH1cbiAgICAgIHJlcyArPSBrZXk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuLyogICovXG5cbnZhciBuYW1lc3BhY2VNYXAgPSB7XG4gIHN2ZzogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgbWF0aDogJ2h0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwnXG59O1xuXG52YXIgaXNIVE1MVGFnID0gbWFrZU1hcChcbiAgJ2h0bWwsYm9keSxiYXNlLGhlYWQsbGluayxtZXRhLHN0eWxlLHRpdGxlLCcgK1xuICAnYWRkcmVzcyxhcnRpY2xlLGFzaWRlLGZvb3RlcixoZWFkZXIsaDEsaDIsaDMsaDQsaDUsaDYsaGdyb3VwLG5hdixzZWN0aW9uLCcgK1xuICAnZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsJyArXG4gICdhLGIsYWJicixiZGksYmRvLGJyLGNpdGUsY29kZSxkYXRhLGRmbixlbSxpLGtiZCxtYXJrLHEscnAscnQscnRjLHJ1YnksJyArXG4gICdzLHNhbXAsc21hbGwsc3BhbixzdHJvbmcsc3ViLHN1cCx0aW1lLHUsdmFyLHdicixhcmVhLGF1ZGlvLG1hcCx0cmFjayx2aWRlbywnICtcbiAgJ2VtYmVkLG9iamVjdCxwYXJhbSxzb3VyY2UsY2FudmFzLHNjcmlwdCxub3NjcmlwdCxkZWwsaW5zLCcgK1xuICAnY2FwdGlvbixjb2wsY29sZ3JvdXAsdGFibGUsdGhlYWQsdGJvZHksdGQsdGgsdHIsJyArXG4gICdidXR0b24sZGF0YWxpc3QsZmllbGRzZXQsZm9ybSxpbnB1dCxsYWJlbCxsZWdlbmQsbWV0ZXIsb3B0Z3JvdXAsb3B0aW9uLCcgK1xuICAnb3V0cHV0LHByb2dyZXNzLHNlbGVjdCx0ZXh0YXJlYSwnICtcbiAgJ2RldGFpbHMsZGlhbG9nLG1lbnUsbWVudWl0ZW0sc3VtbWFyeSwnICtcbiAgJ2NvbnRlbnQsZWxlbWVudCxzaGFkb3csdGVtcGxhdGUsYmxvY2txdW90ZSxpZnJhbWUsdGZvb3QnXG4pO1xuXG4vLyB0aGlzIG1hcCBpcyBpbnRlbnRpb25hbGx5IHNlbGVjdGl2ZSwgb25seSBjb3ZlcmluZyBTVkcgZWxlbWVudHMgdGhhdCBtYXlcbi8vIGNvbnRhaW4gY2hpbGQgZWxlbWVudHMuXG52YXIgaXNTVkcgPSBtYWtlTWFwKFxuICAnc3ZnLGFuaW1hdGUsY2lyY2xlLGNsaXBwYXRoLGN1cnNvcixkZWZzLGRlc2MsZWxsaXBzZSxmaWx0ZXIsZm9udC1mYWNlLCcgK1xuICAnZm9yZWlnbk9iamVjdCxnLGdseXBoLGltYWdlLGxpbmUsbWFya2VyLG1hc2ssbWlzc2luZy1nbHlwaCxwYXRoLHBhdHRlcm4sJyArXG4gICdwb2x5Z29uLHBvbHlsaW5lLHJlY3Qsc3dpdGNoLHN5bWJvbCx0ZXh0LHRleHRwYXRoLHRzcGFuLHVzZSx2aWV3JyxcbiAgdHJ1ZVxuKTtcblxudmFyIGlzUHJlVGFnID0gZnVuY3Rpb24gKHRhZykgeyByZXR1cm4gdGFnID09PSAncHJlJzsgfTtcblxudmFyIGlzUmVzZXJ2ZWRUYWcgPSBmdW5jdGlvbiAodGFnKSB7XG4gIHJldHVybiBpc0hUTUxUYWcodGFnKSB8fCBpc1NWRyh0YWcpXG59O1xuXG5mdW5jdGlvbiBnZXRUYWdOYW1lc3BhY2UgKHRhZykge1xuICBpZiAoaXNTVkcodGFnKSkge1xuICAgIHJldHVybiAnc3ZnJ1xuICB9XG4gIC8vIGJhc2ljIHN1cHBvcnQgZm9yIE1hdGhNTFxuICAvLyBub3RlIGl0IGRvZXNuJ3Qgc3VwcG9ydCBvdGhlciBNYXRoTUwgZWxlbWVudHMgYmVpbmcgY29tcG9uZW50IHJvb3RzXG4gIGlmICh0YWcgPT09ICdtYXRoJykge1xuICAgIHJldHVybiAnbWF0aCdcbiAgfVxufVxuXG52YXIgdW5rbm93bkVsZW1lbnRDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5mdW5jdGlvbiBpc1Vua25vd25FbGVtZW50ICh0YWcpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICghaW5Ccm93c2VyKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuICBpZiAoaXNSZXNlcnZlZFRhZyh0YWcpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgdGFnID0gdGFnLnRvTG93ZXJDYXNlKCk7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddICE9IG51bGwpIHtcbiAgICByZXR1cm4gdW5rbm93bkVsZW1lbnRDYWNoZVt0YWddXG4gIH1cbiAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICBpZiAodGFnLmluZGV4T2YoJy0nKSA+IC0xKSB7XG4gICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgyMTAzNjQvMTA3MDI0NFxuICAgIHJldHVybiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddID0gKFxuICAgICAgZWwuY29uc3RydWN0b3IgPT09IHdpbmRvdy5IVE1MVW5rbm93bkVsZW1lbnQgfHxcbiAgICAgIGVsLmNvbnN0cnVjdG9yID09PSB3aW5kb3cuSFRNTEVsZW1lbnRcbiAgICApKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddID0gL0hUTUxVbmtub3duRWxlbWVudC8udGVzdChlbC50b1N0cmluZygpKSlcbiAgfVxufVxuXG52YXIgaXNUZXh0SW5wdXRUeXBlID0gbWFrZU1hcCgndGV4dCxudW1iZXIscGFzc3dvcmQsc2VhcmNoLGVtYWlsLHRlbCx1cmwnKTtcblxuLyogICovXG5cbi8qKlxuICogUXVlcnkgYW4gZWxlbWVudCBzZWxlY3RvciBpZiBpdCdzIG5vdCBhbiBlbGVtZW50IGFscmVhZHkuXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5IChlbCkge1xuICBpZiAodHlwZW9mIGVsID09PSAnc3RyaW5nJykge1xuICAgIHZhciBzZWxlY3RlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWwpO1xuICAgIGlmICghc2VsZWN0ZWQpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICdDYW5ub3QgZmluZCBlbGVtZW50OiAnICsgZWxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB9XG4gICAgcmV0dXJuIHNlbGVjdGVkXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGVsXG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQkMSAodGFnTmFtZSwgdm5vZGUpIHtcbiAgdmFyIGVsbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gIGlmICh0YWdOYW1lICE9PSAnc2VsZWN0Jykge1xuICAgIHJldHVybiBlbG1cbiAgfVxuICAvLyBmYWxzZSBvciBudWxsIHdpbGwgcmVtb3ZlIHRoZSBhdHRyaWJ1dGUgYnV0IHVuZGVmaW5lZCB3aWxsIG5vdFxuICBpZiAodm5vZGUuZGF0YSAmJiB2bm9kZS5kYXRhLmF0dHJzICYmIHZub2RlLmRhdGEuYXR0cnMubXVsdGlwbGUgIT09IHVuZGVmaW5lZCkge1xuICAgIGVsbS5zZXRBdHRyaWJ1dGUoJ211bHRpcGxlJywgJ211bHRpcGxlJyk7XG4gIH1cbiAgcmV0dXJuIGVsbVxufVxuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50TlMgKG5hbWVzcGFjZSwgdGFnTmFtZSkge1xuICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZU1hcFtuYW1lc3BhY2VdLCB0YWdOYW1lKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVUZXh0Tm9kZSAodGV4dCkge1xuICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dClcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29tbWVudCAodGV4dCkge1xuICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCh0ZXh0KVxufVxuXG5mdW5jdGlvbiBpbnNlcnRCZWZvcmUgKHBhcmVudE5vZGUsIG5ld05vZGUsIHJlZmVyZW5jZU5vZGUpIHtcbiAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNoaWxkIChub2RlLCBjaGlsZCkge1xuICBub2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbn1cblxuZnVuY3Rpb24gYXBwZW5kQ2hpbGQgKG5vZGUsIGNoaWxkKSB7XG4gIG5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQpO1xufVxuXG5mdW5jdGlvbiBwYXJlbnROb2RlIChub2RlKSB7XG4gIHJldHVybiBub2RlLnBhcmVudE5vZGVcbn1cblxuZnVuY3Rpb24gbmV4dFNpYmxpbmcgKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUubmV4dFNpYmxpbmdcbn1cblxuZnVuY3Rpb24gdGFnTmFtZSAobm9kZSkge1xuICByZXR1cm4gbm9kZS50YWdOYW1lXG59XG5cbmZ1bmN0aW9uIHNldFRleHRDb250ZW50IChub2RlLCB0ZXh0KSB7XG4gIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xufVxuXG5mdW5jdGlvbiBzZXRTdHlsZVNjb3BlIChub2RlLCBzY29wZUlkKSB7XG4gIG5vZGUuc2V0QXR0cmlidXRlKHNjb3BlSWQsICcnKTtcbn1cblxudmFyIG5vZGVPcHMgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG4gIGNyZWF0ZUVsZW1lbnQ6IGNyZWF0ZUVsZW1lbnQkMSxcbiAgY3JlYXRlRWxlbWVudE5TOiBjcmVhdGVFbGVtZW50TlMsXG4gIGNyZWF0ZVRleHROb2RlOiBjcmVhdGVUZXh0Tm9kZSxcbiAgY3JlYXRlQ29tbWVudDogY3JlYXRlQ29tbWVudCxcbiAgaW5zZXJ0QmVmb3JlOiBpbnNlcnRCZWZvcmUsXG4gIHJlbW92ZUNoaWxkOiByZW1vdmVDaGlsZCxcbiAgYXBwZW5kQ2hpbGQ6IGFwcGVuZENoaWxkLFxuICBwYXJlbnROb2RlOiBwYXJlbnROb2RlLFxuICBuZXh0U2libGluZzogbmV4dFNpYmxpbmcsXG4gIHRhZ05hbWU6IHRhZ05hbWUsXG4gIHNldFRleHRDb250ZW50OiBzZXRUZXh0Q29udGVudCxcbiAgc2V0U3R5bGVTY29wZTogc2V0U3R5bGVTY29wZVxufSk7XG5cbi8qICAqL1xuXG52YXIgcmVmID0ge1xuICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSAoXywgdm5vZGUpIHtcbiAgICByZWdpc3RlclJlZih2bm9kZSk7XG4gIH0sXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlIChvbGRWbm9kZSwgdm5vZGUpIHtcbiAgICBpZiAob2xkVm5vZGUuZGF0YS5yZWYgIT09IHZub2RlLmRhdGEucmVmKSB7XG4gICAgICByZWdpc3RlclJlZihvbGRWbm9kZSwgdHJ1ZSk7XG4gICAgICByZWdpc3RlclJlZih2bm9kZSk7XG4gICAgfVxuICB9LFxuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95ICh2bm9kZSkge1xuICAgIHJlZ2lzdGVyUmVmKHZub2RlLCB0cnVlKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJSZWYgKHZub2RlLCBpc1JlbW92YWwpIHtcbiAgdmFyIGtleSA9IHZub2RlLmRhdGEucmVmO1xuICBpZiAoIWlzRGVmKGtleSkpIHsgcmV0dXJuIH1cblxuICB2YXIgdm0gPSB2bm9kZS5jb250ZXh0O1xuICB2YXIgcmVmID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgfHwgdm5vZGUuZWxtO1xuICB2YXIgcmVmcyA9IHZtLiRyZWZzO1xuICBpZiAoaXNSZW1vdmFsKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVmc1trZXldKSkge1xuICAgICAgcmVtb3ZlKHJlZnNba2V5XSwgcmVmKTtcbiAgICB9IGVsc2UgaWYgKHJlZnNba2V5XSA9PT0gcmVmKSB7XG4gICAgICByZWZzW2tleV0gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh2bm9kZS5kYXRhLnJlZkluRm9yKSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVmc1trZXldKSkge1xuICAgICAgICByZWZzW2tleV0gPSBbcmVmXTtcbiAgICAgIH0gZWxzZSBpZiAocmVmc1trZXldLmluZGV4T2YocmVmKSA8IDApIHtcbiAgICAgICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lXG4gICAgICAgIHJlZnNba2V5XS5wdXNoKHJlZik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZnNba2V5XSA9IHJlZjtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWaXJ0dWFsIERPTSBwYXRjaGluZyBhbGdvcml0aG0gYmFzZWQgb24gU25hYmJkb20gYnlcbiAqIFNpbW9uIEZyaWlzIFZpbmR1bSAoQHBhbGRlcGluZClcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZVxuICogaHR0cHM6Ly9naXRodWIuY29tL3BhbGRlcGluZC9zbmFiYmRvbS9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKlxuICogbW9kaWZpZWQgYnkgRXZhbiBZb3UgKEB5eXg5OTA4MDMpXG4gKlxuICogTm90IHR5cGUtY2hlY2tpbmcgdGhpcyBiZWNhdXNlIHRoaXMgZmlsZSBpcyBwZXJmLWNyaXRpY2FsIGFuZCB0aGUgY29zdFxuICogb2YgbWFraW5nIGZsb3cgdW5kZXJzdGFuZCBpdCBpcyBub3Qgd29ydGggaXQuXG4gKi9cblxudmFyIGVtcHR5Tm9kZSA9IG5ldyBWTm9kZSgnJywge30sIFtdKTtcblxudmFyIGhvb2tzID0gWydjcmVhdGUnLCAnYWN0aXZhdGUnLCAndXBkYXRlJywgJ3JlbW92ZScsICdkZXN0cm95J107XG5cbmZ1bmN0aW9uIHNhbWVWbm9kZSAoYSwgYikge1xuICByZXR1cm4gKFxuICAgIGEua2V5ID09PSBiLmtleSAmJiAoXG4gICAgICAoXG4gICAgICAgIGEudGFnID09PSBiLnRhZyAmJlxuICAgICAgICBhLmlzQ29tbWVudCA9PT0gYi5pc0NvbW1lbnQgJiZcbiAgICAgICAgaXNEZWYoYS5kYXRhKSA9PT0gaXNEZWYoYi5kYXRhKSAmJlxuICAgICAgICBzYW1lSW5wdXRUeXBlKGEsIGIpXG4gICAgICApIHx8IChcbiAgICAgICAgaXNUcnVlKGEuaXNBc3luY1BsYWNlaG9sZGVyKSAmJlxuICAgICAgICBhLmFzeW5jRmFjdG9yeSA9PT0gYi5hc3luY0ZhY3RvcnkgJiZcbiAgICAgICAgaXNVbmRlZihiLmFzeW5jRmFjdG9yeS5lcnJvcilcbiAgICAgIClcbiAgICApXG4gIClcbn1cblxuZnVuY3Rpb24gc2FtZUlucHV0VHlwZSAoYSwgYikge1xuICBpZiAoYS50YWcgIT09ICdpbnB1dCcpIHsgcmV0dXJuIHRydWUgfVxuICB2YXIgaTtcbiAgdmFyIHR5cGVBID0gaXNEZWYoaSA9IGEuZGF0YSkgJiYgaXNEZWYoaSA9IGkuYXR0cnMpICYmIGkudHlwZTtcbiAgdmFyIHR5cGVCID0gaXNEZWYoaSA9IGIuZGF0YSkgJiYgaXNEZWYoaSA9IGkuYXR0cnMpICYmIGkudHlwZTtcbiAgcmV0dXJuIHR5cGVBID09PSB0eXBlQiB8fCBpc1RleHRJbnB1dFR5cGUodHlwZUEpICYmIGlzVGV4dElucHV0VHlwZSh0eXBlQilcbn1cblxuZnVuY3Rpb24gY3JlYXRlS2V5VG9PbGRJZHggKGNoaWxkcmVuLCBiZWdpbklkeCwgZW5kSWR4KSB7XG4gIHZhciBpLCBrZXk7XG4gIHZhciBtYXAgPSB7fTtcbiAgZm9yIChpID0gYmVnaW5JZHg7IGkgPD0gZW5kSWR4OyArK2kpIHtcbiAgICBrZXkgPSBjaGlsZHJlbltpXS5rZXk7XG4gICAgaWYgKGlzRGVmKGtleSkpIHsgbWFwW2tleV0gPSBpOyB9XG4gIH1cbiAgcmV0dXJuIG1hcFxufVxuXG5mdW5jdGlvbiBjcmVhdGVQYXRjaEZ1bmN0aW9uIChiYWNrZW5kKSB7XG4gIHZhciBpLCBqO1xuICB2YXIgY2JzID0ge307XG5cbiAgdmFyIG1vZHVsZXMgPSBiYWNrZW5kLm1vZHVsZXM7XG4gIHZhciBub2RlT3BzID0gYmFja2VuZC5ub2RlT3BzO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBob29rcy5sZW5ndGg7ICsraSkge1xuICAgIGNic1tob29rc1tpXV0gPSBbXTtcbiAgICBmb3IgKGogPSAwOyBqIDwgbW9kdWxlcy5sZW5ndGg7ICsraikge1xuICAgICAgaWYgKGlzRGVmKG1vZHVsZXNbal1baG9va3NbaV1dKSkge1xuICAgICAgICBjYnNbaG9va3NbaV1dLnB1c2gobW9kdWxlc1tqXVtob29rc1tpXV0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGVtcHR5Tm9kZUF0IChlbG0pIHtcbiAgICByZXR1cm4gbmV3IFZOb2RlKG5vZGVPcHMudGFnTmFtZShlbG0pLnRvTG93ZXJDYXNlKCksIHt9LCBbXSwgdW5kZWZpbmVkLCBlbG0pXG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVSbUNiIChjaGlsZEVsbSwgbGlzdGVuZXJzKSB7XG4gICAgZnVuY3Rpb24gcmVtb3ZlJCQxICgpIHtcbiAgICAgIGlmICgtLXJlbW92ZSQkMS5saXN0ZW5lcnMgPT09IDApIHtcbiAgICAgICAgcmVtb3ZlTm9kZShjaGlsZEVsbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlbW92ZSQkMS5saXN0ZW5lcnMgPSBsaXN0ZW5lcnM7XG4gICAgcmV0dXJuIHJlbW92ZSQkMVxuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlTm9kZSAoZWwpIHtcbiAgICB2YXIgcGFyZW50ID0gbm9kZU9wcy5wYXJlbnROb2RlKGVsKTtcbiAgICAvLyBlbGVtZW50IG1heSBoYXZlIGFscmVhZHkgYmVlbiByZW1vdmVkIGR1ZSB0byB2LWh0bWwgLyB2LXRleHRcbiAgICBpZiAoaXNEZWYocGFyZW50KSkge1xuICAgICAgbm9kZU9wcy5yZW1vdmVDaGlsZChwYXJlbnQsIGVsKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1Vua25vd25FbGVtZW50JCQxICh2bm9kZSwgaW5WUHJlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICFpblZQcmUgJiZcbiAgICAgICF2bm9kZS5ucyAmJlxuICAgICAgIShcbiAgICAgICAgY29uZmlnLmlnbm9yZWRFbGVtZW50cy5sZW5ndGggJiZcbiAgICAgICAgY29uZmlnLmlnbm9yZWRFbGVtZW50cy5zb21lKGZ1bmN0aW9uIChpZ25vcmUpIHtcbiAgICAgICAgICByZXR1cm4gaXNSZWdFeHAoaWdub3JlKVxuICAgICAgICAgICAgPyBpZ25vcmUudGVzdCh2bm9kZS50YWcpXG4gICAgICAgICAgICA6IGlnbm9yZSA9PT0gdm5vZGUudGFnXG4gICAgICAgIH0pXG4gICAgICApICYmXG4gICAgICBjb25maWcuaXNVbmtub3duRWxlbWVudCh2bm9kZS50YWcpXG4gICAgKVxuICB9XG5cbiAgdmFyIGNyZWF0aW5nRWxtSW5WUHJlID0gMDtcblxuICBmdW5jdGlvbiBjcmVhdGVFbG0gKFxuICAgIHZub2RlLFxuICAgIGluc2VydGVkVm5vZGVRdWV1ZSxcbiAgICBwYXJlbnRFbG0sXG4gICAgcmVmRWxtLFxuICAgIG5lc3RlZCxcbiAgICBvd25lckFycmF5LFxuICAgIGluZGV4XG4gICkge1xuICAgIGlmIChpc0RlZih2bm9kZS5lbG0pICYmIGlzRGVmKG93bmVyQXJyYXkpKSB7XG4gICAgICAvLyBUaGlzIHZub2RlIHdhcyB1c2VkIGluIGEgcHJldmlvdXMgcmVuZGVyIVxuICAgICAgLy8gbm93IGl0J3MgdXNlZCBhcyBhIG5ldyBub2RlLCBvdmVyd3JpdGluZyBpdHMgZWxtIHdvdWxkIGNhdXNlXG4gICAgICAvLyBwb3RlbnRpYWwgcGF0Y2ggZXJyb3JzIGRvd24gdGhlIHJvYWQgd2hlbiBpdCdzIHVzZWQgYXMgYW4gaW5zZXJ0aW9uXG4gICAgICAvLyByZWZlcmVuY2Ugbm9kZS4gSW5zdGVhZCwgd2UgY2xvbmUgdGhlIG5vZGUgb24tZGVtYW5kIGJlZm9yZSBjcmVhdGluZ1xuICAgICAgLy8gYXNzb2NpYXRlZCBET00gZWxlbWVudCBmb3IgaXQuXG4gICAgICB2bm9kZSA9IG93bmVyQXJyYXlbaW5kZXhdID0gY2xvbmVWTm9kZSh2bm9kZSk7XG4gICAgfVxuXG4gICAgdm5vZGUuaXNSb290SW5zZXJ0ID0gIW5lc3RlZDsgLy8gZm9yIHRyYW5zaXRpb24gZW50ZXIgY2hlY2tcbiAgICBpZiAoY3JlYXRlQ29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgcmVmRWxtKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICAgIHZhciBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuO1xuICAgIHZhciB0YWcgPSB2bm9kZS50YWc7XG4gICAgaWYgKGlzRGVmKHRhZykpIHtcbiAgICAgIHtcbiAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5wcmUpIHtcbiAgICAgICAgICBjcmVhdGluZ0VsbUluVlByZSsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1Vua25vd25FbGVtZW50JCQxKHZub2RlLCBjcmVhdGluZ0VsbUluVlByZSkpIHtcbiAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgJ1Vua25vd24gY3VzdG9tIGVsZW1lbnQ6IDwnICsgdGFnICsgJz4gLSBkaWQgeW91ICcgK1xuICAgICAgICAgICAgJ3JlZ2lzdGVyIHRoZSBjb21wb25lbnQgY29ycmVjdGx5PyBGb3IgcmVjdXJzaXZlIGNvbXBvbmVudHMsICcgK1xuICAgICAgICAgICAgJ21ha2Ugc3VyZSB0byBwcm92aWRlIHRoZSBcIm5hbWVcIiBvcHRpb24uJyxcbiAgICAgICAgICAgIHZub2RlLmNvbnRleHRcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZub2RlLmVsbSA9IHZub2RlLm5zXG4gICAgICAgID8gbm9kZU9wcy5jcmVhdGVFbGVtZW50TlModm5vZGUubnMsIHRhZylcbiAgICAgICAgOiBub2RlT3BzLmNyZWF0ZUVsZW1lbnQodGFnLCB2bm9kZSk7XG4gICAgICBzZXRTY29wZSh2bm9kZSk7XG5cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAge1xuICAgICAgICBjcmVhdGVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICB9XG4gICAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5wcmUpIHtcbiAgICAgICAgY3JlYXRpbmdFbG1JblZQcmUtLTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzVHJ1ZSh2bm9kZS5pc0NvbW1lbnQpKSB7XG4gICAgICB2bm9kZS5lbG0gPSBub2RlT3BzLmNyZWF0ZUNvbW1lbnQodm5vZGUudGV4dCk7XG4gICAgICBpbnNlcnQocGFyZW50RWxtLCB2bm9kZS5lbG0sIHJlZkVsbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZub2RlLmVsbSA9IG5vZGVPcHMuY3JlYXRlVGV4dE5vZGUodm5vZGUudGV4dCk7XG4gICAgICBpbnNlcnQocGFyZW50RWxtLCB2bm9kZS5lbG0sIHJlZkVsbSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50ICh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSkge1xuICAgIHZhciBpID0gdm5vZGUuZGF0YTtcbiAgICBpZiAoaXNEZWYoaSkpIHtcbiAgICAgIHZhciBpc1JlYWN0aXZhdGVkID0gaXNEZWYodm5vZGUuY29tcG9uZW50SW5zdGFuY2UpICYmIGkua2VlcEFsaXZlO1xuICAgICAgaWYgKGlzRGVmKGkgPSBpLmhvb2spICYmIGlzRGVmKGkgPSBpLmluaXQpKSB7XG4gICAgICAgIGkodm5vZGUsIGZhbHNlIC8qIGh5ZHJhdGluZyAqLyk7XG4gICAgICB9XG4gICAgICAvLyBhZnRlciBjYWxsaW5nIHRoZSBpbml0IGhvb2ssIGlmIHRoZSB2bm9kZSBpcyBhIGNoaWxkIGNvbXBvbmVudFxuICAgICAgLy8gaXQgc2hvdWxkJ3ZlIGNyZWF0ZWQgYSBjaGlsZCBpbnN0YW5jZSBhbmQgbW91bnRlZCBpdC4gdGhlIGNoaWxkXG4gICAgICAvLyBjb21wb25lbnQgYWxzbyBoYXMgc2V0IHRoZSBwbGFjZWhvbGRlciB2bm9kZSdzIGVsbS5cbiAgICAgIC8vIGluIHRoYXQgY2FzZSB3ZSBjYW4ganVzdCByZXR1cm4gdGhlIGVsZW1lbnQgYW5kIGJlIGRvbmUuXG4gICAgICBpZiAoaXNEZWYodm5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7XG4gICAgICAgIGluaXRDb21wb25lbnQodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgICAgICAgaWYgKGlzVHJ1ZShpc1JlYWN0aXZhdGVkKSkge1xuICAgICAgICAgIHJlYWN0aXZhdGVDb21wb25lbnQodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdENvbXBvbmVudCAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIGlmIChpc0RlZih2bm9kZS5kYXRhLnBlbmRpbmdJbnNlcnQpKSB7XG4gICAgICBpbnNlcnRlZFZub2RlUXVldWUucHVzaC5hcHBseShpbnNlcnRlZFZub2RlUXVldWUsIHZub2RlLmRhdGEucGVuZGluZ0luc2VydCk7XG4gICAgICB2bm9kZS5kYXRhLnBlbmRpbmdJbnNlcnQgPSBudWxsO1xuICAgIH1cbiAgICB2bm9kZS5lbG0gPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZS4kZWw7XG4gICAgaWYgKGlzUGF0Y2hhYmxlKHZub2RlKSkge1xuICAgICAgaW52b2tlQ3JlYXRlSG9va3Modm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICBzZXRTY29wZSh2bm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGVtcHR5IGNvbXBvbmVudCByb290LlxuICAgICAgLy8gc2tpcCBhbGwgZWxlbWVudC1yZWxhdGVkIG1vZHVsZXMgZXhjZXB0IGZvciByZWYgKCMzNDU1KVxuICAgICAgcmVnaXN0ZXJSZWYodm5vZGUpO1xuICAgICAgLy8gbWFrZSBzdXJlIHRvIGludm9rZSB0aGUgaW5zZXJ0IGhvb2tcbiAgICAgIGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKHZub2RlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFjdGl2YXRlQ29tcG9uZW50ICh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSkge1xuICAgIHZhciBpO1xuICAgIC8vIGhhY2sgZm9yICM0MzM5OiBhIHJlYWN0aXZhdGVkIGNvbXBvbmVudCB3aXRoIGlubmVyIHRyYW5zaXRpb25cbiAgICAvLyBkb2VzIG5vdCB0cmlnZ2VyIGJlY2F1c2UgdGhlIGlubmVyIG5vZGUncyBjcmVhdGVkIGhvb2tzIGFyZSBub3QgY2FsbGVkXG4gICAgLy8gYWdhaW4uIEl0J3Mgbm90IGlkZWFsIHRvIGludm9sdmUgbW9kdWxlLXNwZWNpZmljIGxvZ2ljIGluIGhlcmUgYnV0XG4gICAgLy8gdGhlcmUgZG9lc24ndCBzZWVtIHRvIGJlIGEgYmV0dGVyIHdheSB0byBkbyBpdC5cbiAgICB2YXIgaW5uZXJOb2RlID0gdm5vZGU7XG4gICAgd2hpbGUgKGlubmVyTm9kZS5jb21wb25lbnRJbnN0YW5jZSkge1xuICAgICAgaW5uZXJOb2RlID0gaW5uZXJOb2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZTtcbiAgICAgIGlmIChpc0RlZihpID0gaW5uZXJOb2RlLmRhdGEpICYmIGlzRGVmKGkgPSBpLnRyYW5zaXRpb24pKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMuYWN0aXZhdGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBjYnMuYWN0aXZhdGVbaV0oZW1wdHlOb2RlLCBpbm5lck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKGlubmVyTm9kZSk7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICAgIC8vIHVubGlrZSBhIG5ld2x5IGNyZWF0ZWQgY29tcG9uZW50LFxuICAgIC8vIGEgcmVhY3RpdmF0ZWQga2VlcC1hbGl2ZSBjb21wb25lbnQgZG9lc24ndCBpbnNlcnQgaXRzZWxmXG4gICAgaW5zZXJ0KHBhcmVudEVsbSwgdm5vZGUuZWxtLCByZWZFbG0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zZXJ0IChwYXJlbnQsIGVsbSwgcmVmJCQxKSB7XG4gICAgaWYgKGlzRGVmKHBhcmVudCkpIHtcbiAgICAgIGlmIChpc0RlZihyZWYkJDEpKSB7XG4gICAgICAgIGlmIChub2RlT3BzLnBhcmVudE5vZGUocmVmJCQxKSA9PT0gcGFyZW50KSB7XG4gICAgICAgICAgbm9kZU9wcy5pbnNlcnRCZWZvcmUocGFyZW50LCBlbG0sIHJlZiQkMSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGVPcHMuYXBwZW5kQ2hpbGQocGFyZW50LCBlbG0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUNoaWxkcmVuICh2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAge1xuICAgICAgICBjaGVja0R1cGxpY2F0ZUtleXMoY2hpbGRyZW4pO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICBjcmVhdGVFbG0oY2hpbGRyZW5baV0sIGluc2VydGVkVm5vZGVRdWV1ZSwgdm5vZGUuZWxtLCBudWxsLCB0cnVlLCBjaGlsZHJlbiwgaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1ByaW1pdGl2ZSh2bm9kZS50ZXh0KSkge1xuICAgICAgbm9kZU9wcy5hcHBlbmRDaGlsZCh2bm9kZS5lbG0sIG5vZGVPcHMuY3JlYXRlVGV4dE5vZGUoU3RyaW5nKHZub2RlLnRleHQpKSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNQYXRjaGFibGUgKHZub2RlKSB7XG4gICAgd2hpbGUgKHZub2RlLmNvbXBvbmVudEluc3RhbmNlKSB7XG4gICAgICB2bm9kZSA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZTtcbiAgICB9XG4gICAgcmV0dXJuIGlzRGVmKHZub2RlLnRhZylcbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZUNyZWF0ZUhvb2tzICh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSB7XG4gICAgZm9yICh2YXIgaSQxID0gMDsgaSQxIDwgY2JzLmNyZWF0ZS5sZW5ndGg7ICsraSQxKSB7XG4gICAgICBjYnMuY3JlYXRlW2kkMV0oZW1wdHlOb2RlLCB2bm9kZSk7XG4gICAgfVxuICAgIGkgPSB2bm9kZS5kYXRhLmhvb2s7IC8vIFJldXNlIHZhcmlhYmxlXG4gICAgaWYgKGlzRGVmKGkpKSB7XG4gICAgICBpZiAoaXNEZWYoaS5jcmVhdGUpKSB7IGkuY3JlYXRlKGVtcHR5Tm9kZSwgdm5vZGUpOyB9XG4gICAgICBpZiAoaXNEZWYoaS5pbnNlcnQpKSB7IGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKHZub2RlKTsgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNldCBzY29wZSBpZCBhdHRyaWJ1dGUgZm9yIHNjb3BlZCBDU1MuXG4gIC8vIHRoaXMgaXMgaW1wbGVtZW50ZWQgYXMgYSBzcGVjaWFsIGNhc2UgdG8gYXZvaWQgdGhlIG92ZXJoZWFkXG4gIC8vIG9mIGdvaW5nIHRocm91Z2ggdGhlIG5vcm1hbCBhdHRyaWJ1dGUgcGF0Y2hpbmcgcHJvY2Vzcy5cbiAgZnVuY3Rpb24gc2V0U2NvcGUgKHZub2RlKSB7XG4gICAgdmFyIGk7XG4gICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5mblNjb3BlSWQpKSB7XG4gICAgICBub2RlT3BzLnNldFN0eWxlU2NvcGUodm5vZGUuZWxtLCBpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGFuY2VzdG9yID0gdm5vZGU7XG4gICAgICB3aGlsZSAoYW5jZXN0b3IpIHtcbiAgICAgICAgaWYgKGlzRGVmKGkgPSBhbmNlc3Rvci5jb250ZXh0KSAmJiBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZCkpIHtcbiAgICAgICAgICBub2RlT3BzLnNldFN0eWxlU2NvcGUodm5vZGUuZWxtLCBpKTtcbiAgICAgICAgfVxuICAgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gZm9yIHNsb3QgY29udGVudCB0aGV5IHNob3VsZCBhbHNvIGdldCB0aGUgc2NvcGVJZCBmcm9tIHRoZSBob3N0IGluc3RhbmNlLlxuICAgIGlmIChpc0RlZihpID0gYWN0aXZlSW5zdGFuY2UpICYmXG4gICAgICBpICE9PSB2bm9kZS5jb250ZXh0ICYmXG4gICAgICBpICE9PSB2bm9kZS5mbkNvbnRleHQgJiZcbiAgICAgIGlzRGVmKGkgPSBpLiRvcHRpb25zLl9zY29wZUlkKVxuICAgICkge1xuICAgICAgbm9kZU9wcy5zZXRTdHlsZVNjb3BlKHZub2RlLmVsbSwgaSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkVm5vZGVzIChwYXJlbnRFbG0sIHJlZkVsbSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4LCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBmb3IgKDsgc3RhcnRJZHggPD0gZW5kSWR4OyArK3N0YXJ0SWR4KSB7XG4gICAgICBjcmVhdGVFbG0odm5vZGVzW3N0YXJ0SWR4XSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSwgZmFsc2UsIHZub2Rlcywgc3RhcnRJZHgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZURlc3Ryb3lIb29rICh2bm9kZSkge1xuICAgIHZhciBpLCBqO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5kZXN0cm95KSkgeyBpKHZub2RlKTsgfVxuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5kZXN0cm95Lmxlbmd0aDsgKytpKSB7IGNicy5kZXN0cm95W2ldKHZub2RlKTsgfVxuICAgIH1cbiAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkcmVuKSkge1xuICAgICAgZm9yIChqID0gMDsgaiA8IHZub2RlLmNoaWxkcmVuLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGludm9rZURlc3Ryb3lIb29rKHZub2RlLmNoaWxkcmVuW2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVWbm9kZXMgKHZub2Rlcywgc3RhcnRJZHgsIGVuZElkeCkge1xuICAgIGZvciAoOyBzdGFydElkeCA8PSBlbmRJZHg7ICsrc3RhcnRJZHgpIHtcbiAgICAgIHZhciBjaCA9IHZub2Rlc1tzdGFydElkeF07XG4gICAgICBpZiAoaXNEZWYoY2gpKSB7XG4gICAgICAgIGlmIChpc0RlZihjaC50YWcpKSB7XG4gICAgICAgICAgcmVtb3ZlQW5kSW52b2tlUmVtb3ZlSG9vayhjaCk7XG4gICAgICAgICAgaW52b2tlRGVzdHJveUhvb2soY2gpO1xuICAgICAgICB9IGVsc2UgeyAvLyBUZXh0IG5vZGVcbiAgICAgICAgICByZW1vdmVOb2RlKGNoLmVsbSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVBbmRJbnZva2VSZW1vdmVIb29rICh2bm9kZSwgcm0pIHtcbiAgICBpZiAoaXNEZWYocm0pIHx8IGlzRGVmKHZub2RlLmRhdGEpKSB7XG4gICAgICB2YXIgaTtcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBjYnMucmVtb3ZlLmxlbmd0aCArIDE7XG4gICAgICBpZiAoaXNEZWYocm0pKSB7XG4gICAgICAgIC8vIHdlIGhhdmUgYSByZWN1cnNpdmVseSBwYXNzZWQgZG93biBybSBjYWxsYmFja1xuICAgICAgICAvLyBpbmNyZWFzZSB0aGUgbGlzdGVuZXJzIGNvdW50XG4gICAgICAgIHJtLmxpc3RlbmVycyArPSBsaXN0ZW5lcnM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBkaXJlY3RseSByZW1vdmluZ1xuICAgICAgICBybSA9IGNyZWF0ZVJtQ2Iodm5vZGUuZWxtLCBsaXN0ZW5lcnMpO1xuICAgICAgfVxuICAgICAgLy8gcmVjdXJzaXZlbHkgaW52b2tlIGhvb2tzIG9uIGNoaWxkIGNvbXBvbmVudCByb290IG5vZGVcbiAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UpICYmIGlzRGVmKGkgPSBpLl92bm9kZSkgJiYgaXNEZWYoaS5kYXRhKSkge1xuICAgICAgICByZW1vdmVBbmRJbnZva2VSZW1vdmVIb29rKGksIHJtKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMucmVtb3ZlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNicy5yZW1vdmVbaV0odm5vZGUsIHJtKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5yZW1vdmUpKSB7XG4gICAgICAgIGkodm5vZGUsIHJtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJtKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlbW92ZU5vZGUodm5vZGUuZWxtKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVDaGlsZHJlbiAocGFyZW50RWxtLCBvbGRDaCwgbmV3Q2gsIGluc2VydGVkVm5vZGVRdWV1ZSwgcmVtb3ZlT25seSkge1xuICAgIHZhciBvbGRTdGFydElkeCA9IDA7XG4gICAgdmFyIG5ld1N0YXJ0SWR4ID0gMDtcbiAgICB2YXIgb2xkRW5kSWR4ID0gb2xkQ2gubGVuZ3RoIC0gMTtcbiAgICB2YXIgb2xkU3RhcnRWbm9kZSA9IG9sZENoWzBdO1xuICAgIHZhciBvbGRFbmRWbm9kZSA9IG9sZENoW29sZEVuZElkeF07XG4gICAgdmFyIG5ld0VuZElkeCA9IG5ld0NoLmxlbmd0aCAtIDE7XG4gICAgdmFyIG5ld1N0YXJ0Vm5vZGUgPSBuZXdDaFswXTtcbiAgICB2YXIgbmV3RW5kVm5vZGUgPSBuZXdDaFtuZXdFbmRJZHhdO1xuICAgIHZhciBvbGRLZXlUb0lkeCwgaWR4SW5PbGQsIHZub2RlVG9Nb3ZlLCByZWZFbG07XG5cbiAgICAvLyByZW1vdmVPbmx5IGlzIGEgc3BlY2lhbCBmbGFnIHVzZWQgb25seSBieSA8dHJhbnNpdGlvbi1ncm91cD5cbiAgICAvLyB0byBlbnN1cmUgcmVtb3ZlZCBlbGVtZW50cyBzdGF5IGluIGNvcnJlY3QgcmVsYXRpdmUgcG9zaXRpb25zXG4gICAgLy8gZHVyaW5nIGxlYXZpbmcgdHJhbnNpdGlvbnNcbiAgICB2YXIgY2FuTW92ZSA9ICFyZW1vdmVPbmx5O1xuXG4gICAge1xuICAgICAgY2hlY2tEdXBsaWNhdGVLZXlzKG5ld0NoKTtcbiAgICB9XG5cbiAgICB3aGlsZSAob2xkU3RhcnRJZHggPD0gb2xkRW5kSWR4ICYmIG5ld1N0YXJ0SWR4IDw9IG5ld0VuZElkeCkge1xuICAgICAgaWYgKGlzVW5kZWYob2xkU3RhcnRWbm9kZSkpIHtcbiAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdOyAvLyBWbm9kZSBoYXMgYmVlbiBtb3ZlZCBsZWZ0XG4gICAgICB9IGVsc2UgaWYgKGlzVW5kZWYob2xkRW5kVm5vZGUpKSB7XG4gICAgICAgIG9sZEVuZFZub2RlID0gb2xkQ2hbLS1vbGRFbmRJZHhdO1xuICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHtcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRTdGFydFZub2RlLCBuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIG5ld0NoLCBuZXdTdGFydElkeCk7XG4gICAgICAgIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFsrK29sZFN0YXJ0SWR4XTtcbiAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkRW5kVm5vZGUsIG5ld0VuZFZub2RlKSkge1xuICAgICAgICBwYXRjaFZub2RlKG9sZEVuZFZub2RlLCBuZXdFbmRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBuZXdDaCwgbmV3RW5kSWR4KTtcbiAgICAgICAgb2xkRW5kVm5vZGUgPSBvbGRDaFstLW9sZEVuZElkeF07XG4gICAgICAgIG5ld0VuZFZub2RlID0gbmV3Q2hbLS1uZXdFbmRJZHhdO1xuICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3RW5kVm5vZGUpKSB7IC8vIFZub2RlIG1vdmVkIHJpZ2h0XG4gICAgICAgIHBhdGNoVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3RW5kVm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgbmV3Q2gsIG5ld0VuZElkeCk7XG4gICAgICAgIGNhbk1vdmUgJiYgbm9kZU9wcy5pbnNlcnRCZWZvcmUocGFyZW50RWxtLCBvbGRTdGFydFZub2RlLmVsbSwgbm9kZU9wcy5uZXh0U2libGluZyhvbGRFbmRWbm9kZS5lbG0pKTtcbiAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdO1xuICAgICAgICBuZXdFbmRWbm9kZSA9IG5ld0NoWy0tbmV3RW5kSWR4XTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZEVuZFZub2RlLCBuZXdTdGFydFZub2RlKSkgeyAvLyBWbm9kZSBtb3ZlZCBsZWZ0XG4gICAgICAgIHBhdGNoVm5vZGUob2xkRW5kVm5vZGUsIG5ld1N0YXJ0Vm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgbmV3Q2gsIG5ld1N0YXJ0SWR4KTtcbiAgICAgICAgY2FuTW92ZSAmJiBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIG9sZEVuZFZub2RlLmVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzVW5kZWYob2xkS2V5VG9JZHgpKSB7IG9sZEtleVRvSWR4ID0gY3JlYXRlS2V5VG9PbGRJZHgob2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpOyB9XG4gICAgICAgIGlkeEluT2xkID0gaXNEZWYobmV3U3RhcnRWbm9kZS5rZXkpXG4gICAgICAgICAgPyBvbGRLZXlUb0lkeFtuZXdTdGFydFZub2RlLmtleV1cbiAgICAgICAgICA6IGZpbmRJZHhJbk9sZChuZXdTdGFydFZub2RlLCBvbGRDaCwgb2xkU3RhcnRJZHgsIG9sZEVuZElkeCk7XG4gICAgICAgIGlmIChpc1VuZGVmKGlkeEluT2xkKSkgeyAvLyBOZXcgZWxlbWVudFxuICAgICAgICAgIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIGZhbHNlLCBuZXdDaCwgbmV3U3RhcnRJZHgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZub2RlVG9Nb3ZlID0gb2xkQ2hbaWR4SW5PbGRdO1xuICAgICAgICAgIGlmIChzYW1lVm5vZGUodm5vZGVUb01vdmUsIG5ld1N0YXJ0Vm5vZGUpKSB7XG4gICAgICAgICAgICBwYXRjaFZub2RlKHZub2RlVG9Nb3ZlLCBuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIG5ld0NoLCBuZXdTdGFydElkeCk7XG4gICAgICAgICAgICBvbGRDaFtpZHhJbk9sZF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgdm5vZGVUb01vdmUuZWxtLCBvbGRTdGFydFZub2RlLmVsbSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNhbWUga2V5IGJ1dCBkaWZmZXJlbnQgZWxlbWVudC4gdHJlYXQgYXMgbmV3IGVsZW1lbnRcbiAgICAgICAgICAgIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIGZhbHNlLCBuZXdDaCwgbmV3U3RhcnRJZHgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChvbGRTdGFydElkeCA+IG9sZEVuZElkeCkge1xuICAgICAgcmVmRWxtID0gaXNVbmRlZihuZXdDaFtuZXdFbmRJZHggKyAxXSkgPyBudWxsIDogbmV3Q2hbbmV3RW5kSWR4ICsgMV0uZWxtO1xuICAgICAgYWRkVm5vZGVzKHBhcmVudEVsbSwgcmVmRWxtLCBuZXdDaCwgbmV3U3RhcnRJZHgsIG5ld0VuZElkeCwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICB9IGVsc2UgaWYgKG5ld1N0YXJ0SWR4ID4gbmV3RW5kSWR4KSB7XG4gICAgICByZW1vdmVWbm9kZXMob2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNoZWNrRHVwbGljYXRlS2V5cyAoY2hpbGRyZW4pIHtcbiAgICB2YXIgc2VlbktleXMgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdm5vZGUgPSBjaGlsZHJlbltpXTtcbiAgICAgIHZhciBrZXkgPSB2bm9kZS5rZXk7XG4gICAgICBpZiAoaXNEZWYoa2V5KSkge1xuICAgICAgICBpZiAoc2VlbktleXNba2V5XSkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAoXCJEdXBsaWNhdGUga2V5cyBkZXRlY3RlZDogJ1wiICsga2V5ICsgXCInLiBUaGlzIG1heSBjYXVzZSBhbiB1cGRhdGUgZXJyb3IuXCIpLFxuICAgICAgICAgICAgdm5vZGUuY29udGV4dFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VlbktleXNba2V5XSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kSWR4SW5PbGQgKG5vZGUsIG9sZENoLCBzdGFydCwgZW5kKSB7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHZhciBjID0gb2xkQ2hbaV07XG4gICAgICBpZiAoaXNEZWYoYykgJiYgc2FtZVZub2RlKG5vZGUsIGMpKSB7IHJldHVybiBpIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBwYXRjaFZub2RlIChcbiAgICBvbGRWbm9kZSxcbiAgICB2bm9kZSxcbiAgICBpbnNlcnRlZFZub2RlUXVldWUsXG4gICAgb3duZXJBcnJheSxcbiAgICBpbmRleCxcbiAgICByZW1vdmVPbmx5XG4gICkge1xuICAgIGlmIChvbGRWbm9kZSA9PT0gdm5vZGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChpc0RlZih2bm9kZS5lbG0pICYmIGlzRGVmKG93bmVyQXJyYXkpKSB7XG4gICAgICAvLyBjbG9uZSByZXVzZWQgdm5vZGVcbiAgICAgIHZub2RlID0gb3duZXJBcnJheVtpbmRleF0gPSBjbG9uZVZOb2RlKHZub2RlKTtcbiAgICB9XG5cbiAgICB2YXIgZWxtID0gdm5vZGUuZWxtID0gb2xkVm5vZGUuZWxtO1xuXG4gICAgaWYgKGlzVHJ1ZShvbGRWbm9kZS5pc0FzeW5jUGxhY2Vob2xkZXIpKSB7XG4gICAgICBpZiAoaXNEZWYodm5vZGUuYXN5bmNGYWN0b3J5LnJlc29sdmVkKSkge1xuICAgICAgICBoeWRyYXRlKG9sZFZub2RlLmVsbSwgdm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2bm9kZS5pc0FzeW5jUGxhY2Vob2xkZXIgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gcmV1c2UgZWxlbWVudCBmb3Igc3RhdGljIHRyZWVzLlxuICAgIC8vIG5vdGUgd2Ugb25seSBkbyB0aGlzIGlmIHRoZSB2bm9kZSBpcyBjbG9uZWQgLVxuICAgIC8vIGlmIHRoZSBuZXcgbm9kZSBpcyBub3QgY2xvbmVkIGl0IG1lYW5zIHRoZSByZW5kZXIgZnVuY3Rpb25zIGhhdmUgYmVlblxuICAgIC8vIHJlc2V0IGJ5IHRoZSBob3QtcmVsb2FkLWFwaSBhbmQgd2UgbmVlZCB0byBkbyBhIHByb3BlciByZS1yZW5kZXIuXG4gICAgaWYgKGlzVHJ1ZSh2bm9kZS5pc1N0YXRpYykgJiZcbiAgICAgIGlzVHJ1ZShvbGRWbm9kZS5pc1N0YXRpYykgJiZcbiAgICAgIHZub2RlLmtleSA9PT0gb2xkVm5vZGUua2V5ICYmXG4gICAgICAoaXNUcnVlKHZub2RlLmlzQ2xvbmVkKSB8fCBpc1RydWUodm5vZGUuaXNPbmNlKSlcbiAgICApIHtcbiAgICAgIHZub2RlLmNvbXBvbmVudEluc3RhbmNlID0gb2xkVm5vZGUuY29tcG9uZW50SW5zdGFuY2U7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgaTtcbiAgICB2YXIgZGF0YSA9IHZub2RlLmRhdGE7XG4gICAgaWYgKGlzRGVmKGRhdGEpICYmIGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnByZXBhdGNoKSkge1xuICAgICAgaShvbGRWbm9kZSwgdm5vZGUpO1xuICAgIH1cblxuICAgIHZhciBvbGRDaCA9IG9sZFZub2RlLmNoaWxkcmVuO1xuICAgIHZhciBjaCA9IHZub2RlLmNoaWxkcmVuO1xuICAgIGlmIChpc0RlZihkYXRhKSAmJiBpc1BhdGNoYWJsZSh2bm9kZSkpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMudXBkYXRlLmxlbmd0aDsgKytpKSB7IGNicy51cGRhdGVbaV0ob2xkVm5vZGUsIHZub2RlKTsgfVxuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnVwZGF0ZSkpIHsgaShvbGRWbm9kZSwgdm5vZGUpOyB9XG4gICAgfVxuICAgIGlmIChpc1VuZGVmKHZub2RlLnRleHQpKSB7XG4gICAgICBpZiAoaXNEZWYob2xkQ2gpICYmIGlzRGVmKGNoKSkge1xuICAgICAgICBpZiAob2xkQ2ggIT09IGNoKSB7IHVwZGF0ZUNoaWxkcmVuKGVsbSwgb2xkQ2gsIGNoLCBpbnNlcnRlZFZub2RlUXVldWUsIHJlbW92ZU9ubHkpOyB9XG4gICAgICB9IGVsc2UgaWYgKGlzRGVmKGNoKSkge1xuICAgICAgICB7XG4gICAgICAgICAgY2hlY2tEdXBsaWNhdGVLZXlzKGNoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWYob2xkVm5vZGUudGV4dCkpIHsgbm9kZU9wcy5zZXRUZXh0Q29udGVudChlbG0sICcnKTsgfVxuICAgICAgICBhZGRWbm9kZXMoZWxtLCBudWxsLCBjaCwgMCwgY2gubGVuZ3RoIC0gMSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNEZWYob2xkQ2gpKSB7XG4gICAgICAgIHJlbW92ZVZub2RlcyhvbGRDaCwgMCwgb2xkQ2gubGVuZ3RoIC0gMSk7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVmKG9sZFZub2RlLnRleHQpKSB7XG4gICAgICAgIG5vZGVPcHMuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvbGRWbm9kZS50ZXh0ICE9PSB2bm9kZS50ZXh0KSB7XG4gICAgICBub2RlT3BzLnNldFRleHRDb250ZW50KGVsbSwgdm5vZGUudGV4dCk7XG4gICAgfVxuICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnBvc3RwYXRjaCkpIHsgaShvbGRWbm9kZSwgdm5vZGUpOyB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlSW5zZXJ0SG9vayAodm5vZGUsIHF1ZXVlLCBpbml0aWFsKSB7XG4gICAgLy8gZGVsYXkgaW5zZXJ0IGhvb2tzIGZvciBjb21wb25lbnQgcm9vdCBub2RlcywgaW52b2tlIHRoZW0gYWZ0ZXIgdGhlXG4gICAgLy8gZWxlbWVudCBpcyByZWFsbHkgaW5zZXJ0ZWRcbiAgICBpZiAoaXNUcnVlKGluaXRpYWwpICYmIGlzRGVmKHZub2RlLnBhcmVudCkpIHtcbiAgICAgIHZub2RlLnBhcmVudC5kYXRhLnBlbmRpbmdJbnNlcnQgPSBxdWV1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBxdWV1ZVtpXS5kYXRhLmhvb2suaW5zZXJ0KHF1ZXVlW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgaHlkcmF0aW9uQmFpbGVkID0gZmFsc2U7XG4gIC8vIGxpc3Qgb2YgbW9kdWxlcyB0aGF0IGNhbiBza2lwIGNyZWF0ZSBob29rIGR1cmluZyBoeWRyYXRpb24gYmVjYXVzZSB0aGV5XG4gIC8vIGFyZSBhbHJlYWR5IHJlbmRlcmVkIG9uIHRoZSBjbGllbnQgb3IgaGFzIG5vIG5lZWQgZm9yIGluaXRpYWxpemF0aW9uXG4gIC8vIE5vdGU6IHN0eWxlIGlzIGV4Y2x1ZGVkIGJlY2F1c2UgaXQgcmVsaWVzIG9uIGluaXRpYWwgY2xvbmUgZm9yIGZ1dHVyZVxuICAvLyBkZWVwIHVwZGF0ZXMgKCM3MDYzKS5cbiAgdmFyIGlzUmVuZGVyZWRNb2R1bGUgPSBtYWtlTWFwKCdhdHRycyxjbGFzcyxzdGF0aWNDbGFzcyxzdGF0aWNTdHlsZSxrZXknKTtcblxuICAvLyBOb3RlOiB0aGlzIGlzIGEgYnJvd3Nlci1vbmx5IGZ1bmN0aW9uIHNvIHdlIGNhbiBhc3N1bWUgZWxtcyBhcmUgRE9NIG5vZGVzLlxuICBmdW5jdGlvbiBoeWRyYXRlIChlbG0sIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIGluVlByZSkge1xuICAgIHZhciBpO1xuICAgIHZhciB0YWcgPSB2bm9kZS50YWc7XG4gICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICAgIHZhciBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuO1xuICAgIGluVlByZSA9IGluVlByZSB8fCAoZGF0YSAmJiBkYXRhLnByZSk7XG4gICAgdm5vZGUuZWxtID0gZWxtO1xuXG4gICAgaWYgKGlzVHJ1ZSh2bm9kZS5pc0NvbW1lbnQpICYmIGlzRGVmKHZub2RlLmFzeW5jRmFjdG9yeSkpIHtcbiAgICAgIHZub2RlLmlzQXN5bmNQbGFjZWhvbGRlciA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICAvLyBhc3NlcnQgbm9kZSBtYXRjaFxuICAgIHtcbiAgICAgIGlmICghYXNzZXJ0Tm9kZU1hdGNoKGVsbSwgdm5vZGUsIGluVlByZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLmluaXQpKSB7IGkodm5vZGUsIHRydWUgLyogaHlkcmF0aW5nICovKTsgfVxuICAgICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSkpIHtcbiAgICAgICAgLy8gY2hpbGQgY29tcG9uZW50LiBpdCBzaG91bGQgaGF2ZSBoeWRyYXRlZCBpdHMgb3duIHRyZWUuXG4gICAgICAgIGluaXRDb21wb25lbnQodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0RlZih0YWcpKSB7XG4gICAgICBpZiAoaXNEZWYoY2hpbGRyZW4pKSB7XG4gICAgICAgIC8vIGVtcHR5IGVsZW1lbnQsIGFsbG93IGNsaWVudCB0byBwaWNrIHVwIGFuZCBwb3B1bGF0ZSBjaGlsZHJlblxuICAgICAgICBpZiAoIWVsbS5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgICAgICBjcmVhdGVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdi1odG1sIGFuZCBkb21Qcm9wczogaW5uZXJIVE1MXG4gICAgICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhKSAmJiBpc0RlZihpID0gaS5kb21Qcm9wcykgJiYgaXNEZWYoaSA9IGkuaW5uZXJIVE1MKSkge1xuICAgICAgICAgICAgaWYgKGkgIT09IGVsbS5pbm5lckhUTUwpIHtcbiAgICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICAhaHlkcmF0aW9uQmFpbGVkXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGh5ZHJhdGlvbkJhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQYXJlbnQ6ICcsIGVsbSk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdzZXJ2ZXIgaW5uZXJIVE1MOiAnLCBpKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2NsaWVudCBpbm5lckhUTUw6ICcsIGVsbS5pbm5lckhUTUwpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBpdGVyYXRlIGFuZCBjb21wYXJlIGNoaWxkcmVuIGxpc3RzXG4gICAgICAgICAgICB2YXIgY2hpbGRyZW5NYXRjaCA9IHRydWU7XG4gICAgICAgICAgICB2YXIgY2hpbGROb2RlID0gZWxtLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBjaGlsZHJlbi5sZW5ndGg7IGkkMSsrKSB7XG4gICAgICAgICAgICAgIGlmICghY2hpbGROb2RlIHx8ICFoeWRyYXRlKGNoaWxkTm9kZSwgY2hpbGRyZW5baSQxXSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpblZQcmUpKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5NYXRjaCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2hpbGROb2RlID0gY2hpbGROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaWYgY2hpbGROb2RlIGlzIG5vdCBudWxsLCBpdCBtZWFucyB0aGUgYWN0dWFsIGNoaWxkTm9kZXMgbGlzdCBpc1xuICAgICAgICAgICAgLy8gbG9uZ2VyIHRoYW4gdGhlIHZpcnR1YWwgY2hpbGRyZW4gbGlzdC5cbiAgICAgICAgICAgIGlmICghY2hpbGRyZW5NYXRjaCB8fCBjaGlsZE5vZGUpIHtcbiAgICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICAhaHlkcmF0aW9uQmFpbGVkXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGh5ZHJhdGlvbkJhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQYXJlbnQ6ICcsIGVsbSk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdNaXNtYXRjaGluZyBjaGlsZE5vZGVzIHZzLiBWTm9kZXM6ICcsIGVsbS5jaGlsZE5vZGVzLCBjaGlsZHJlbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgICAgdmFyIGZ1bGxJbnZva2UgPSBmYWxzZTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICBpZiAoIWlzUmVuZGVyZWRNb2R1bGUoa2V5KSkge1xuICAgICAgICAgICAgZnVsbEludm9rZSA9IHRydWU7XG4gICAgICAgICAgICBpbnZva2VDcmVhdGVIb29rcyh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZnVsbEludm9rZSAmJiBkYXRhWydjbGFzcyddKSB7XG4gICAgICAgICAgLy8gZW5zdXJlIGNvbGxlY3RpbmcgZGVwcyBmb3IgZGVlcCBjbGFzcyBiaW5kaW5ncyBmb3IgZnV0dXJlIHVwZGF0ZXNcbiAgICAgICAgICB0cmF2ZXJzZShkYXRhWydjbGFzcyddKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZWxtLmRhdGEgIT09IHZub2RlLnRleHQpIHtcbiAgICAgIGVsbS5kYXRhID0gdm5vZGUudGV4dDtcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGZ1bmN0aW9uIGFzc2VydE5vZGVNYXRjaCAobm9kZSwgdm5vZGUsIGluVlByZSkge1xuICAgIGlmIChpc0RlZih2bm9kZS50YWcpKSB7XG4gICAgICByZXR1cm4gdm5vZGUudGFnLmluZGV4T2YoJ3Z1ZS1jb21wb25lbnQnKSA9PT0gMCB8fCAoXG4gICAgICAgICFpc1Vua25vd25FbGVtZW50JCQxKHZub2RlLCBpblZQcmUpICYmXG4gICAgICAgIHZub2RlLnRhZy50b0xvd2VyQ2FzZSgpID09PSAobm9kZS50YWdOYW1lICYmIG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpKVxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gKHZub2RlLmlzQ29tbWVudCA/IDggOiAzKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBwYXRjaCAob2xkVm5vZGUsIHZub2RlLCBoeWRyYXRpbmcsIHJlbW92ZU9ubHkpIHtcbiAgICBpZiAoaXNVbmRlZih2bm9kZSkpIHtcbiAgICAgIGlmIChpc0RlZihvbGRWbm9kZSkpIHsgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpOyB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgaXNJbml0aWFsUGF0Y2ggPSBmYWxzZTtcbiAgICB2YXIgaW5zZXJ0ZWRWbm9kZVF1ZXVlID0gW107XG5cbiAgICBpZiAoaXNVbmRlZihvbGRWbm9kZSkpIHtcbiAgICAgIC8vIGVtcHR5IG1vdW50IChsaWtlbHkgYXMgY29tcG9uZW50KSwgY3JlYXRlIG5ldyByb290IGVsZW1lbnRcbiAgICAgIGlzSW5pdGlhbFBhdGNoID0gdHJ1ZTtcbiAgICAgIGNyZWF0ZUVsbSh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGlzUmVhbEVsZW1lbnQgPSBpc0RlZihvbGRWbm9kZS5ub2RlVHlwZSk7XG4gICAgICBpZiAoIWlzUmVhbEVsZW1lbnQgJiYgc2FtZVZub2RlKG9sZFZub2RlLCB2bm9kZSkpIHtcbiAgICAgICAgLy8gcGF0Y2ggZXhpc3Rpbmcgcm9vdCBub2RlXG4gICAgICAgIHBhdGNoVm5vZGUob2xkVm5vZGUsIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIG51bGwsIG51bGwsIHJlbW92ZU9ubHkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzUmVhbEVsZW1lbnQpIHtcbiAgICAgICAgICAvLyBtb3VudGluZyB0byBhIHJlYWwgZWxlbWVudFxuICAgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgaXMgc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQgYW5kIGlmIHdlIGNhbiBwZXJmb3JtXG4gICAgICAgICAgLy8gYSBzdWNjZXNzZnVsIGh5ZHJhdGlvbi5cbiAgICAgICAgICBpZiAob2xkVm5vZGUubm9kZVR5cGUgPT09IDEgJiYgb2xkVm5vZGUuaGFzQXR0cmlidXRlKFNTUl9BVFRSKSkge1xuICAgICAgICAgICAgb2xkVm5vZGUucmVtb3ZlQXR0cmlidXRlKFNTUl9BVFRSKTtcbiAgICAgICAgICAgIGh5ZHJhdGluZyA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpc1RydWUoaHlkcmF0aW5nKSkge1xuICAgICAgICAgICAgaWYgKGh5ZHJhdGUob2xkVm5vZGUsIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpKSB7XG4gICAgICAgICAgICAgIGludm9rZUluc2VydEhvb2sodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgIHJldHVybiBvbGRWbm9kZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgd2FybihcbiAgICAgICAgICAgICAgICAnVGhlIGNsaWVudC1zaWRlIHJlbmRlcmVkIHZpcnR1YWwgRE9NIHRyZWUgaXMgbm90IG1hdGNoaW5nICcgK1xuICAgICAgICAgICAgICAgICdzZXJ2ZXItcmVuZGVyZWQgY29udGVudC4gVGhpcyBpcyBsaWtlbHkgY2F1c2VkIGJ5IGluY29ycmVjdCAnICtcbiAgICAgICAgICAgICAgICAnSFRNTCBtYXJrdXAsIGZvciBleGFtcGxlIG5lc3RpbmcgYmxvY2stbGV2ZWwgZWxlbWVudHMgaW5zaWRlICcgK1xuICAgICAgICAgICAgICAgICc8cD4sIG9yIG1pc3NpbmcgPHRib2R5Pi4gQmFpbGluZyBoeWRyYXRpb24gYW5kIHBlcmZvcm1pbmcgJyArXG4gICAgICAgICAgICAgICAgJ2Z1bGwgY2xpZW50LXNpZGUgcmVuZGVyLidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZWl0aGVyIG5vdCBzZXJ2ZXItcmVuZGVyZWQsIG9yIGh5ZHJhdGlvbiBmYWlsZWQuXG4gICAgICAgICAgLy8gY3JlYXRlIGFuIGVtcHR5IG5vZGUgYW5kIHJlcGxhY2UgaXRcbiAgICAgICAgICBvbGRWbm9kZSA9IGVtcHR5Tm9kZUF0KG9sZFZub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlcGxhY2luZyBleGlzdGluZyBlbGVtZW50XG4gICAgICAgIHZhciBvbGRFbG0gPSBvbGRWbm9kZS5lbG07XG4gICAgICAgIHZhciBwYXJlbnRFbG0gPSBub2RlT3BzLnBhcmVudE5vZGUob2xkRWxtKTtcblxuICAgICAgICAvLyBjcmVhdGUgbmV3IG5vZGVcbiAgICAgICAgY3JlYXRlRWxtKFxuICAgICAgICAgIHZub2RlLFxuICAgICAgICAgIGluc2VydGVkVm5vZGVRdWV1ZSxcbiAgICAgICAgICAvLyBleHRyZW1lbHkgcmFyZSBlZGdlIGNhc2U6IGRvIG5vdCBpbnNlcnQgaWYgb2xkIGVsZW1lbnQgaXMgaW4gYVxuICAgICAgICAgIC8vIGxlYXZpbmcgdHJhbnNpdGlvbi4gT25seSBoYXBwZW5zIHdoZW4gY29tYmluaW5nIHRyYW5zaXRpb24gK1xuICAgICAgICAgIC8vIGtlZXAtYWxpdmUgKyBIT0NzLiAoIzQ1OTApXG4gICAgICAgICAgb2xkRWxtLl9sZWF2ZUNiID8gbnVsbCA6IHBhcmVudEVsbSxcbiAgICAgICAgICBub2RlT3BzLm5leHRTaWJsaW5nKG9sZEVsbSlcbiAgICAgICAgKTtcblxuICAgICAgICAvLyB1cGRhdGUgcGFyZW50IHBsYWNlaG9sZGVyIG5vZGUgZWxlbWVudCwgcmVjdXJzaXZlbHlcbiAgICAgICAgaWYgKGlzRGVmKHZub2RlLnBhcmVudCkpIHtcbiAgICAgICAgICB2YXIgYW5jZXN0b3IgPSB2bm9kZS5wYXJlbnQ7XG4gICAgICAgICAgdmFyIHBhdGNoYWJsZSA9IGlzUGF0Y2hhYmxlKHZub2RlKTtcbiAgICAgICAgICB3aGlsZSAoYW5jZXN0b3IpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2JzLmRlc3Ryb3kubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgY2JzLmRlc3Ryb3lbaV0oYW5jZXN0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5jZXN0b3IuZWxtID0gdm5vZGUuZWxtO1xuICAgICAgICAgICAgaWYgKHBhdGNoYWJsZSkge1xuICAgICAgICAgICAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBjYnMuY3JlYXRlLmxlbmd0aDsgKytpJDEpIHtcbiAgICAgICAgICAgICAgICBjYnMuY3JlYXRlW2kkMV0oZW1wdHlOb2RlLCBhbmNlc3Rvcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gIzY1MTNcbiAgICAgICAgICAgICAgLy8gaW52b2tlIGluc2VydCBob29rcyB0aGF0IG1heSBoYXZlIGJlZW4gbWVyZ2VkIGJ5IGNyZWF0ZSBob29rcy5cbiAgICAgICAgICAgICAgLy8gZS5nLiBmb3IgZGlyZWN0aXZlcyB0aGF0IHVzZXMgdGhlIFwiaW5zZXJ0ZWRcIiBob29rLlxuICAgICAgICAgICAgICB2YXIgaW5zZXJ0ID0gYW5jZXN0b3IuZGF0YS5ob29rLmluc2VydDtcbiAgICAgICAgICAgICAgaWYgKGluc2VydC5tZXJnZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBzdGFydCBhdCBpbmRleCAxIHRvIGF2b2lkIHJlLWludm9raW5nIGNvbXBvbmVudCBtb3VudGVkIGhvb2tcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpJDIgPSAxOyBpJDIgPCBpbnNlcnQuZm5zLmxlbmd0aDsgaSQyKyspIHtcbiAgICAgICAgICAgICAgICAgIGluc2VydC5mbnNbaSQyXSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVnaXN0ZXJSZWYoYW5jZXN0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5jZXN0b3IgPSBhbmNlc3Rvci5wYXJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGVzdHJveSBvbGQgbm9kZVxuICAgICAgICBpZiAoaXNEZWYocGFyZW50RWxtKSkge1xuICAgICAgICAgIHJlbW92ZVZub2Rlcyhbb2xkVm5vZGVdLCAwLCAwKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50YWcpKSB7XG4gICAgICAgICAgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpc0luaXRpYWxQYXRjaCk7XG4gICAgcmV0dXJuIHZub2RlLmVsbVxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgZGlyZWN0aXZlcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVEaXJlY3RpdmVzLFxuICB1cGRhdGU6IHVwZGF0ZURpcmVjdGl2ZXMsXG4gIGRlc3Ryb3k6IGZ1bmN0aW9uIHVuYmluZERpcmVjdGl2ZXMgKHZub2RlKSB7XG4gICAgdXBkYXRlRGlyZWN0aXZlcyh2bm9kZSwgZW1wdHlOb2RlKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gdXBkYXRlRGlyZWN0aXZlcyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmIChvbGRWbm9kZS5kYXRhLmRpcmVjdGl2ZXMgfHwgdm5vZGUuZGF0YS5kaXJlY3RpdmVzKSB7XG4gICAgX3VwZGF0ZShvbGRWbm9kZSwgdm5vZGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF91cGRhdGUgKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgaXNDcmVhdGUgPSBvbGRWbm9kZSA9PT0gZW1wdHlOb2RlO1xuICB2YXIgaXNEZXN0cm95ID0gdm5vZGUgPT09IGVtcHR5Tm9kZTtcbiAgdmFyIG9sZERpcnMgPSBub3JtYWxpemVEaXJlY3RpdmVzJDEob2xkVm5vZGUuZGF0YS5kaXJlY3RpdmVzLCBvbGRWbm9kZS5jb250ZXh0KTtcbiAgdmFyIG5ld0RpcnMgPSBub3JtYWxpemVEaXJlY3RpdmVzJDEodm5vZGUuZGF0YS5kaXJlY3RpdmVzLCB2bm9kZS5jb250ZXh0KTtcblxuICB2YXIgZGlyc1dpdGhJbnNlcnQgPSBbXTtcbiAgdmFyIGRpcnNXaXRoUG9zdHBhdGNoID0gW107XG5cbiAgdmFyIGtleSwgb2xkRGlyLCBkaXI7XG4gIGZvciAoa2V5IGluIG5ld0RpcnMpIHtcbiAgICBvbGREaXIgPSBvbGREaXJzW2tleV07XG4gICAgZGlyID0gbmV3RGlyc1trZXldO1xuICAgIGlmICghb2xkRGlyKSB7XG4gICAgICAvLyBuZXcgZGlyZWN0aXZlLCBiaW5kXG4gICAgICBjYWxsSG9vayQxKGRpciwgJ2JpbmQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgaWYgKGRpci5kZWYgJiYgZGlyLmRlZi5pbnNlcnRlZCkge1xuICAgICAgICBkaXJzV2l0aEluc2VydC5wdXNoKGRpcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGV4aXN0aW5nIGRpcmVjdGl2ZSwgdXBkYXRlXG4gICAgICBkaXIub2xkVmFsdWUgPSBvbGREaXIudmFsdWU7XG4gICAgICBkaXIub2xkQXJnID0gb2xkRGlyLmFyZztcbiAgICAgIGNhbGxIb29rJDEoZGlyLCAndXBkYXRlJywgdm5vZGUsIG9sZFZub2RlKTtcbiAgICAgIGlmIChkaXIuZGVmICYmIGRpci5kZWYuY29tcG9uZW50VXBkYXRlZCkge1xuICAgICAgICBkaXJzV2l0aFBvc3RwYXRjaC5wdXNoKGRpcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRpcnNXaXRoSW5zZXJ0Lmxlbmd0aCkge1xuICAgIHZhciBjYWxsSW5zZXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXJzV2l0aEluc2VydC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjYWxsSG9vayQxKGRpcnNXaXRoSW5zZXJ0W2ldLCAnaW5zZXJ0ZWQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKGlzQ3JlYXRlKSB7XG4gICAgICBtZXJnZVZOb2RlSG9vayh2bm9kZSwgJ2luc2VydCcsIGNhbGxJbnNlcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsSW5zZXJ0KCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRpcnNXaXRoUG9zdHBhdGNoLmxlbmd0aCkge1xuICAgIG1lcmdlVk5vZGVIb29rKHZub2RlLCAncG9zdHBhdGNoJywgZnVuY3Rpb24gKCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXJzV2l0aFBvc3RwYXRjaC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjYWxsSG9vayQxKGRpcnNXaXRoUG9zdHBhdGNoW2ldLCAnY29tcG9uZW50VXBkYXRlZCcsIHZub2RlLCBvbGRWbm9kZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoIWlzQ3JlYXRlKSB7XG4gICAgZm9yIChrZXkgaW4gb2xkRGlycykge1xuICAgICAgaWYgKCFuZXdEaXJzW2tleV0pIHtcbiAgICAgICAgLy8gbm8gbG9uZ2VyIHByZXNlbnQsIHVuYmluZFxuICAgICAgICBjYWxsSG9vayQxKG9sZERpcnNba2V5XSwgJ3VuYmluZCcsIG9sZFZub2RlLCBvbGRWbm9kZSwgaXNEZXN0cm95KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGVtcHR5TW9kaWZpZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuZnVuY3Rpb24gbm9ybWFsaXplRGlyZWN0aXZlcyQxIChcbiAgZGlycyxcbiAgdm1cbikge1xuICB2YXIgcmVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgaWYgKCFkaXJzKSB7XG4gICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lXG4gICAgcmV0dXJuIHJlc1xuICB9XG4gIHZhciBpLCBkaXI7XG4gIGZvciAoaSA9IDA7IGkgPCBkaXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgZGlyID0gZGlyc1tpXTtcbiAgICBpZiAoIWRpci5tb2RpZmllcnMpIHtcbiAgICAgIC8vICRmbG93LWRpc2FibGUtbGluZVxuICAgICAgZGlyLm1vZGlmaWVycyA9IGVtcHR5TW9kaWZpZXJzO1xuICAgIH1cbiAgICByZXNbZ2V0UmF3RGlyTmFtZShkaXIpXSA9IGRpcjtcbiAgICBkaXIuZGVmID0gcmVzb2x2ZUFzc2V0KHZtLiRvcHRpb25zLCAnZGlyZWN0aXZlcycsIGRpci5uYW1lLCB0cnVlKTtcbiAgfVxuICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBnZXRSYXdEaXJOYW1lIChkaXIpIHtcbiAgcmV0dXJuIGRpci5yYXdOYW1lIHx8ICgoZGlyLm5hbWUpICsgXCIuXCIgKyAoT2JqZWN0LmtleXMoZGlyLm1vZGlmaWVycyB8fCB7fSkuam9pbignLicpKSlcbn1cblxuZnVuY3Rpb24gY2FsbEhvb2skMSAoZGlyLCBob29rLCB2bm9kZSwgb2xkVm5vZGUsIGlzRGVzdHJveSkge1xuICB2YXIgZm4gPSBkaXIuZGVmICYmIGRpci5kZWZbaG9va107XG4gIGlmIChmbikge1xuICAgIHRyeSB7XG4gICAgICBmbih2bm9kZS5lbG0sIGRpciwgdm5vZGUsIG9sZFZub2RlLCBpc0Rlc3Ryb3kpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGhhbmRsZUVycm9yKGUsIHZub2RlLmNvbnRleHQsIChcImRpcmVjdGl2ZSBcIiArIChkaXIubmFtZSkgKyBcIiBcIiArIGhvb2sgKyBcIiBob29rXCIpKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGJhc2VNb2R1bGVzID0gW1xuICByZWYsXG4gIGRpcmVjdGl2ZXNcbl07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB1cGRhdGVBdHRycyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIHZhciBvcHRzID0gdm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgaWYgKGlzRGVmKG9wdHMpICYmIG9wdHMuQ3Rvci5vcHRpb25zLmluaGVyaXRBdHRycyA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoaXNVbmRlZihvbGRWbm9kZS5kYXRhLmF0dHJzKSAmJiBpc1VuZGVmKHZub2RlLmRhdGEuYXR0cnMpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIGtleSwgY3VyLCBvbGQ7XG4gIHZhciBlbG0gPSB2bm9kZS5lbG07XG4gIHZhciBvbGRBdHRycyA9IG9sZFZub2RlLmRhdGEuYXR0cnMgfHwge307XG4gIHZhciBhdHRycyA9IHZub2RlLmRhdGEuYXR0cnMgfHwge307XG4gIC8vIGNsb25lIG9ic2VydmVkIG9iamVjdHMsIGFzIHRoZSB1c2VyIHByb2JhYmx5IHdhbnRzIHRvIG11dGF0ZSBpdFxuICBpZiAoaXNEZWYoYXR0cnMuX19vYl9fKSkge1xuICAgIGF0dHJzID0gdm5vZGUuZGF0YS5hdHRycyA9IGV4dGVuZCh7fSwgYXR0cnMpO1xuICB9XG5cbiAgZm9yIChrZXkgaW4gYXR0cnMpIHtcbiAgICBjdXIgPSBhdHRyc1trZXldO1xuICAgIG9sZCA9IG9sZEF0dHJzW2tleV07XG4gICAgaWYgKG9sZCAhPT0gY3VyKSB7XG4gICAgICBzZXRBdHRyKGVsbSwga2V5LCBjdXIpO1xuICAgIH1cbiAgfVxuICAvLyAjNDM5MTogaW4gSUU5LCBzZXR0aW5nIHR5cGUgY2FuIHJlc2V0IHZhbHVlIGZvciBpbnB1dFt0eXBlPXJhZGlvXVxuICAvLyAjNjY2NjogSUUvRWRnZSBmb3JjZXMgcHJvZ3Jlc3MgdmFsdWUgZG93biB0byAxIGJlZm9yZSBzZXR0aW5nIGEgbWF4XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoKGlzSUUgfHwgaXNFZGdlKSAmJiBhdHRycy52YWx1ZSAhPT0gb2xkQXR0cnMudmFsdWUpIHtcbiAgICBzZXRBdHRyKGVsbSwgJ3ZhbHVlJywgYXR0cnMudmFsdWUpO1xuICB9XG4gIGZvciAoa2V5IGluIG9sZEF0dHJzKSB7XG4gICAgaWYgKGlzVW5kZWYoYXR0cnNba2V5XSkpIHtcbiAgICAgIGlmIChpc1hsaW5rKGtleSkpIHtcbiAgICAgICAgZWxtLnJlbW92ZUF0dHJpYnV0ZU5TKHhsaW5rTlMsIGdldFhsaW5rUHJvcChrZXkpKTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzRW51bWVyYXRlZEF0dHIoa2V5KSkge1xuICAgICAgICBlbG0ucmVtb3ZlQXR0cmlidXRlKGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldEF0dHIgKGVsLCBrZXksIHZhbHVlKSB7XG4gIGlmIChlbC50YWdOYW1lLmluZGV4T2YoJy0nKSA+IC0xKSB7XG4gICAgYmFzZVNldEF0dHIoZWwsIGtleSwgdmFsdWUpO1xuICB9IGVsc2UgaWYgKGlzQm9vbGVhbkF0dHIoa2V5KSkge1xuICAgIC8vIHNldCBhdHRyaWJ1dGUgZm9yIGJsYW5rIHZhbHVlXG4gICAgLy8gZS5nLiA8b3B0aW9uIGRpc2FibGVkPlNlbGVjdCBvbmU8L29wdGlvbj5cbiAgICBpZiAoaXNGYWxzeUF0dHJWYWx1ZSh2YWx1ZSkpIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyB0ZWNobmljYWxseSBhbGxvd2Z1bGxzY3JlZW4gaXMgYSBib29sZWFuIGF0dHJpYnV0ZSBmb3IgPGlmcmFtZT4sXG4gICAgICAvLyBidXQgRmxhc2ggZXhwZWN0cyBhIHZhbHVlIG9mIFwidHJ1ZVwiIHdoZW4gdXNlZCBvbiA8ZW1iZWQ+IHRhZ1xuICAgICAgdmFsdWUgPSBrZXkgPT09ICdhbGxvd2Z1bGxzY3JlZW4nICYmIGVsLnRhZ05hbWUgPT09ICdFTUJFRCdcbiAgICAgICAgPyAndHJ1ZSdcbiAgICAgICAgOiBrZXk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzRW51bWVyYXRlZEF0dHIoa2V5KSkge1xuICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIGNvbnZlcnRFbnVtZXJhdGVkVmFsdWUoa2V5LCB2YWx1ZSkpO1xuICB9IGVsc2UgaWYgKGlzWGxpbmsoa2V5KSkge1xuICAgIGlmIChpc0ZhbHN5QXR0clZhbHVlKHZhbHVlKSkge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlTlMoeGxpbmtOUywgZ2V0WGxpbmtQcm9wKGtleSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXksIHZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgYmFzZVNldEF0dHIoZWwsIGtleSwgdmFsdWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2VTZXRBdHRyIChlbCwga2V5LCB2YWx1ZSkge1xuICBpZiAoaXNGYWxzeUF0dHJWYWx1ZSh2YWx1ZSkpIHtcbiAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTtcbiAgfSBlbHNlIHtcbiAgICAvLyAjNzEzODogSUUxMCAmIDExIGZpcmVzIGlucHV0IGV2ZW50IHdoZW4gc2V0dGluZyBwbGFjZWhvbGRlciBvblxuICAgIC8vIDx0ZXh0YXJlYT4uLi4gYmxvY2sgdGhlIGZpcnN0IGlucHV0IGV2ZW50IGFuZCByZW1vdmUgdGhlIGJsb2NrZXJcbiAgICAvLyBpbW1lZGlhdGVseS5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoXG4gICAgICBpc0lFICYmICFpc0lFOSAmJlxuICAgICAgZWwudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyAmJlxuICAgICAga2V5ID09PSAncGxhY2Vob2xkZXInICYmIHZhbHVlICE9PSAnJyAmJiAhZWwuX19pZXBoXG4gICAgKSB7XG4gICAgICB2YXIgYmxvY2tlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2lucHV0JywgYmxvY2tlcik7XG4gICAgICB9O1xuICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBibG9ja2VyKTtcbiAgICAgIC8vICRmbG93LWRpc2FibGUtbGluZVxuICAgICAgZWwuX19pZXBoID0gdHJ1ZTsgLyogSUUgcGxhY2Vob2xkZXIgcGF0Y2hlZCAqL1xuICAgIH1cbiAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG4gIH1cbn1cblxudmFyIGF0dHJzID0ge1xuICBjcmVhdGU6IHVwZGF0ZUF0dHJzLFxuICB1cGRhdGU6IHVwZGF0ZUF0dHJzXG59O1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdXBkYXRlQ2xhc3MgKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG4gIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgdmFyIG9sZERhdGEgPSBvbGRWbm9kZS5kYXRhO1xuICBpZiAoXG4gICAgaXNVbmRlZihkYXRhLnN0YXRpY0NsYXNzKSAmJlxuICAgIGlzVW5kZWYoZGF0YS5jbGFzcykgJiYgKFxuICAgICAgaXNVbmRlZihvbGREYXRhKSB8fCAoXG4gICAgICAgIGlzVW5kZWYob2xkRGF0YS5zdGF0aWNDbGFzcykgJiZcbiAgICAgICAgaXNVbmRlZihvbGREYXRhLmNsYXNzKVxuICAgICAgKVxuICAgIClcbiAgKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgY2xzID0gZ2VuQ2xhc3NGb3JWbm9kZSh2bm9kZSk7XG5cbiAgLy8gaGFuZGxlIHRyYW5zaXRpb24gY2xhc3Nlc1xuICB2YXIgdHJhbnNpdGlvbkNsYXNzID0gZWwuX3RyYW5zaXRpb25DbGFzc2VzO1xuICBpZiAoaXNEZWYodHJhbnNpdGlvbkNsYXNzKSkge1xuICAgIGNscyA9IGNvbmNhdChjbHMsIHN0cmluZ2lmeUNsYXNzKHRyYW5zaXRpb25DbGFzcykpO1xuICB9XG5cbiAgLy8gc2V0IHRoZSBjbGFzc1xuICBpZiAoY2xzICE9PSBlbC5fcHJldkNsYXNzKSB7XG4gICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIGNscyk7XG4gICAgZWwuX3ByZXZDbGFzcyA9IGNscztcbiAgfVxufVxuXG52YXIga2xhc3MgPSB7XG4gIGNyZWF0ZTogdXBkYXRlQ2xhc3MsXG4gIHVwZGF0ZTogdXBkYXRlQ2xhc3Ncbn07XG5cbi8qICAqL1xuXG52YXIgdmFsaWREaXZpc2lvbkNoYXJSRSA9IC9bXFx3KS4rXFwtXyRcXF1dLztcblxuZnVuY3Rpb24gcGFyc2VGaWx0ZXJzIChleHApIHtcbiAgdmFyIGluU2luZ2xlID0gZmFsc2U7XG4gIHZhciBpbkRvdWJsZSA9IGZhbHNlO1xuICB2YXIgaW5UZW1wbGF0ZVN0cmluZyA9IGZhbHNlO1xuICB2YXIgaW5SZWdleCA9IGZhbHNlO1xuICB2YXIgY3VybHkgPSAwO1xuICB2YXIgc3F1YXJlID0gMDtcbiAgdmFyIHBhcmVuID0gMDtcbiAgdmFyIGxhc3RGaWx0ZXJJbmRleCA9IDA7XG4gIHZhciBjLCBwcmV2LCBpLCBleHByZXNzaW9uLCBmaWx0ZXJzO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBleHAubGVuZ3RoOyBpKyspIHtcbiAgICBwcmV2ID0gYztcbiAgICBjID0gZXhwLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGluU2luZ2xlKSB7XG4gICAgICBpZiAoYyA9PT0gMHgyNyAmJiBwcmV2ICE9PSAweDVDKSB7IGluU2luZ2xlID0gZmFsc2U7IH1cbiAgICB9IGVsc2UgaWYgKGluRG91YmxlKSB7XG4gICAgICBpZiAoYyA9PT0gMHgyMiAmJiBwcmV2ICE9PSAweDVDKSB7IGluRG91YmxlID0gZmFsc2U7IH1cbiAgICB9IGVsc2UgaWYgKGluVGVtcGxhdGVTdHJpbmcpIHtcbiAgICAgIGlmIChjID09PSAweDYwICYmIHByZXYgIT09IDB4NUMpIHsgaW5UZW1wbGF0ZVN0cmluZyA9IGZhbHNlOyB9XG4gICAgfSBlbHNlIGlmIChpblJlZ2V4KSB7XG4gICAgICBpZiAoYyA9PT0gMHgyZiAmJiBwcmV2ICE9PSAweDVDKSB7IGluUmVnZXggPSBmYWxzZTsgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBjID09PSAweDdDICYmIC8vIHBpcGVcbiAgICAgIGV4cC5jaGFyQ29kZUF0KGkgKyAxKSAhPT0gMHg3QyAmJlxuICAgICAgZXhwLmNoYXJDb2RlQXQoaSAtIDEpICE9PSAweDdDICYmXG4gICAgICAhY3VybHkgJiYgIXNxdWFyZSAmJiAhcGFyZW5cbiAgICApIHtcbiAgICAgIGlmIChleHByZXNzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gZmlyc3QgZmlsdGVyLCBlbmQgb2YgZXhwcmVzc2lvblxuICAgICAgICBsYXN0RmlsdGVySW5kZXggPSBpICsgMTtcbiAgICAgICAgZXhwcmVzc2lvbiA9IGV4cC5zbGljZSgwLCBpKS50cmltKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwdXNoRmlsdGVyKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICBjYXNlIDB4MjI6IGluRG91YmxlID0gdHJ1ZTsgYnJlYWsgICAgICAgICAvLyBcIlxuICAgICAgICBjYXNlIDB4Mjc6IGluU2luZ2xlID0gdHJ1ZTsgYnJlYWsgICAgICAgICAvLyAnXG4gICAgICAgIGNhc2UgMHg2MDogaW5UZW1wbGF0ZVN0cmluZyA9IHRydWU7IGJyZWFrIC8vIGBcbiAgICAgICAgY2FzZSAweDI4OiBwYXJlbisrOyBicmVhayAgICAgICAgICAgICAgICAgLy8gKFxuICAgICAgICBjYXNlIDB4Mjk6IHBhcmVuLS07IGJyZWFrICAgICAgICAgICAgICAgICAvLyApXG4gICAgICAgIGNhc2UgMHg1Qjogc3F1YXJlKys7IGJyZWFrICAgICAgICAgICAgICAgIC8vIFtcbiAgICAgICAgY2FzZSAweDVEOiBzcXVhcmUtLTsgYnJlYWsgICAgICAgICAgICAgICAgLy8gXVxuICAgICAgICBjYXNlIDB4N0I6IGN1cmx5Kys7IGJyZWFrICAgICAgICAgICAgICAgICAvLyB7XG4gICAgICAgIGNhc2UgMHg3RDogY3VybHktLTsgYnJlYWsgICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgIH1cbiAgICAgIGlmIChjID09PSAweDJmKSB7IC8vIC9cbiAgICAgICAgdmFyIGogPSBpIC0gMTtcbiAgICAgICAgdmFyIHAgPSAodm9pZCAwKTtcbiAgICAgICAgLy8gZmluZCBmaXJzdCBub24td2hpdGVzcGFjZSBwcmV2IGNoYXJcbiAgICAgICAgZm9yICg7IGogPj0gMDsgai0tKSB7XG4gICAgICAgICAgcCA9IGV4cC5jaGFyQXQoaik7XG4gICAgICAgICAgaWYgKHAgIT09ICcgJykgeyBicmVhayB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFwIHx8ICF2YWxpZERpdmlzaW9uQ2hhclJFLnRlc3QocCkpIHtcbiAgICAgICAgICBpblJlZ2V4ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChleHByZXNzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICBleHByZXNzaW9uID0gZXhwLnNsaWNlKDAsIGkpLnRyaW0oKTtcbiAgfSBlbHNlIGlmIChsYXN0RmlsdGVySW5kZXggIT09IDApIHtcbiAgICBwdXNoRmlsdGVyKCk7XG4gIH1cblxuICBmdW5jdGlvbiBwdXNoRmlsdGVyICgpIHtcbiAgICAoZmlsdGVycyB8fCAoZmlsdGVycyA9IFtdKSkucHVzaChleHAuc2xpY2UobGFzdEZpbHRlckluZGV4LCBpKS50cmltKCkpO1xuICAgIGxhc3RGaWx0ZXJJbmRleCA9IGkgKyAxO1xuICB9XG5cbiAgaWYgKGZpbHRlcnMpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZmlsdGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgZXhwcmVzc2lvbiA9IHdyYXBGaWx0ZXIoZXhwcmVzc2lvbiwgZmlsdGVyc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGV4cHJlc3Npb25cbn1cblxuZnVuY3Rpb24gd3JhcEZpbHRlciAoZXhwLCBmaWx0ZXIpIHtcbiAgdmFyIGkgPSBmaWx0ZXIuaW5kZXhPZignKCcpO1xuICBpZiAoaSA8IDApIHtcbiAgICAvLyBfZjogcmVzb2x2ZUZpbHRlclxuICAgIHJldHVybiAoXCJfZihcXFwiXCIgKyBmaWx0ZXIgKyBcIlxcXCIpKFwiICsgZXhwICsgXCIpXCIpXG4gIH0gZWxzZSB7XG4gICAgdmFyIG5hbWUgPSBmaWx0ZXIuc2xpY2UoMCwgaSk7XG4gICAgdmFyIGFyZ3MgPSBmaWx0ZXIuc2xpY2UoaSArIDEpO1xuICAgIHJldHVybiAoXCJfZihcXFwiXCIgKyBuYW1lICsgXCJcXFwiKShcIiArIGV4cCArIChhcmdzICE9PSAnKScgPyAnLCcgKyBhcmdzIDogYXJncykpXG4gIH1cbn1cblxuLyogICovXG5cblxuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuZnVuY3Rpb24gYmFzZVdhcm4gKG1zZywgcmFuZ2UpIHtcbiAgY29uc29sZS5lcnJvcigoXCJbVnVlIGNvbXBpbGVyXTogXCIgKyBtc2cpKTtcbn1cbi8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuZnVuY3Rpb24gcGx1Y2tNb2R1bGVGdW5jdGlvbiAoXG4gIG1vZHVsZXMsXG4gIGtleVxuKSB7XG4gIHJldHVybiBtb2R1bGVzXG4gICAgPyBtb2R1bGVzLm1hcChmdW5jdGlvbiAobSkgeyByZXR1cm4gbVtrZXldOyB9KS5maWx0ZXIoZnVuY3Rpb24gKF8pIHsgcmV0dXJuIF87IH0pXG4gICAgOiBbXVxufVxuXG5mdW5jdGlvbiBhZGRQcm9wIChlbCwgbmFtZSwgdmFsdWUsIHJhbmdlLCBkeW5hbWljKSB7XG4gIChlbC5wcm9wcyB8fCAoZWwucHJvcHMgPSBbXSkpLnB1c2gocmFuZ2VTZXRJdGVtKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlLCBkeW5hbWljOiBkeW5hbWljIH0sIHJhbmdlKSk7XG4gIGVsLnBsYWluID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGFkZEF0dHIgKGVsLCBuYW1lLCB2YWx1ZSwgcmFuZ2UsIGR5bmFtaWMpIHtcbiAgdmFyIGF0dHJzID0gZHluYW1pY1xuICAgID8gKGVsLmR5bmFtaWNBdHRycyB8fCAoZWwuZHluYW1pY0F0dHJzID0gW10pKVxuICAgIDogKGVsLmF0dHJzIHx8IChlbC5hdHRycyA9IFtdKSk7XG4gIGF0dHJzLnB1c2gocmFuZ2VTZXRJdGVtKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlLCBkeW5hbWljOiBkeW5hbWljIH0sIHJhbmdlKSk7XG4gIGVsLnBsYWluID0gZmFsc2U7XG59XG5cbi8vIGFkZCBhIHJhdyBhdHRyICh1c2UgdGhpcyBpbiBwcmVUcmFuc2Zvcm1zKVxuZnVuY3Rpb24gYWRkUmF3QXR0ciAoZWwsIG5hbWUsIHZhbHVlLCByYW5nZSkge1xuICBlbC5hdHRyc01hcFtuYW1lXSA9IHZhbHVlO1xuICBlbC5hdHRyc0xpc3QucHVzaChyYW5nZVNldEl0ZW0oeyBuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWUgfSwgcmFuZ2UpKTtcbn1cblxuZnVuY3Rpb24gYWRkRGlyZWN0aXZlIChcbiAgZWwsXG4gIG5hbWUsXG4gIHJhd05hbWUsXG4gIHZhbHVlLFxuICBhcmcsXG4gIGlzRHluYW1pY0FyZyxcbiAgbW9kaWZpZXJzLFxuICByYW5nZVxuKSB7XG4gIChlbC5kaXJlY3RpdmVzIHx8IChlbC5kaXJlY3RpdmVzID0gW10pKS5wdXNoKHJhbmdlU2V0SXRlbSh7XG4gICAgbmFtZTogbmFtZSxcbiAgICByYXdOYW1lOiByYXdOYW1lLFxuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBhcmc6IGFyZyxcbiAgICBpc0R5bmFtaWNBcmc6IGlzRHluYW1pY0FyZyxcbiAgICBtb2RpZmllcnM6IG1vZGlmaWVyc1xuICB9LCByYW5nZSkpO1xuICBlbC5wbGFpbiA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBwcmVwZW5kTW9kaWZpZXJNYXJrZXIgKHN5bWJvbCwgbmFtZSwgZHluYW1pYykge1xuICByZXR1cm4gZHluYW1pY1xuICAgID8gKFwiX3AoXCIgKyBuYW1lICsgXCIsXFxcIlwiICsgc3ltYm9sICsgXCJcXFwiKVwiKVxuICAgIDogc3ltYm9sICsgbmFtZSAvLyBtYXJrIHRoZSBldmVudCBhcyBjYXB0dXJlZFxufVxuXG5mdW5jdGlvbiBhZGRIYW5kbGVyIChcbiAgZWwsXG4gIG5hbWUsXG4gIHZhbHVlLFxuICBtb2RpZmllcnMsXG4gIGltcG9ydGFudCxcbiAgd2FybixcbiAgcmFuZ2UsXG4gIGR5bmFtaWNcbikge1xuICBtb2RpZmllcnMgPSBtb2RpZmllcnMgfHwgZW1wdHlPYmplY3Q7XG4gIC8vIHdhcm4gcHJldmVudCBhbmQgcGFzc2l2ZSBtb2RpZmllclxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKFxuICAgIHdhcm4gJiZcbiAgICBtb2RpZmllcnMucHJldmVudCAmJiBtb2RpZmllcnMucGFzc2l2ZVxuICApIHtcbiAgICB3YXJuKFxuICAgICAgJ3Bhc3NpdmUgYW5kIHByZXZlbnQgY2FuXFwndCBiZSB1c2VkIHRvZ2V0aGVyLiAnICtcbiAgICAgICdQYXNzaXZlIGhhbmRsZXIgY2FuXFwndCBwcmV2ZW50IGRlZmF1bHQgZXZlbnQuJyxcbiAgICAgIHJhbmdlXG4gICAgKTtcbiAgfVxuXG4gIC8vIG5vcm1hbGl6ZSBjbGljay5yaWdodCBhbmQgY2xpY2subWlkZGxlIHNpbmNlIHRoZXkgZG9uJ3QgYWN0dWFsbHkgZmlyZVxuICAvLyB0aGlzIGlzIHRlY2huaWNhbGx5IGJyb3dzZXItc3BlY2lmaWMsIGJ1dCBhdCBsZWFzdCBmb3Igbm93IGJyb3dzZXJzIGFyZVxuICAvLyB0aGUgb25seSB0YXJnZXQgZW52cyB0aGF0IGhhdmUgcmlnaHQvbWlkZGxlIGNsaWNrcy5cbiAgaWYgKG1vZGlmaWVycy5yaWdodCkge1xuICAgIGlmIChkeW5hbWljKSB7XG4gICAgICBuYW1lID0gXCIoXCIgKyBuYW1lICsgXCIpPT09J2NsaWNrJz8nY29udGV4dG1lbnUnOihcIiArIG5hbWUgKyBcIilcIjtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdjbGljaycpIHtcbiAgICAgIG5hbWUgPSAnY29udGV4dG1lbnUnO1xuICAgICAgZGVsZXRlIG1vZGlmaWVycy5yaWdodDtcbiAgICB9XG4gIH0gZWxzZSBpZiAobW9kaWZpZXJzLm1pZGRsZSkge1xuICAgIGlmIChkeW5hbWljKSB7XG4gICAgICBuYW1lID0gXCIoXCIgKyBuYW1lICsgXCIpPT09J2NsaWNrJz8nbW91c2V1cCc6KFwiICsgbmFtZSArIFwiKVwiO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NsaWNrJykge1xuICAgICAgbmFtZSA9ICdtb3VzZXVwJztcbiAgICB9XG4gIH1cblxuICAvLyBjaGVjayBjYXB0dXJlIG1vZGlmaWVyXG4gIGlmIChtb2RpZmllcnMuY2FwdHVyZSkge1xuICAgIGRlbGV0ZSBtb2RpZmllcnMuY2FwdHVyZTtcbiAgICBuYW1lID0gcHJlcGVuZE1vZGlmaWVyTWFya2VyKCchJywgbmFtZSwgZHluYW1pYyk7XG4gIH1cbiAgaWYgKG1vZGlmaWVycy5vbmNlKSB7XG4gICAgZGVsZXRlIG1vZGlmaWVycy5vbmNlO1xuICAgIG5hbWUgPSBwcmVwZW5kTW9kaWZpZXJNYXJrZXIoJ34nLCBuYW1lLCBkeW5hbWljKTtcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKG1vZGlmaWVycy5wYXNzaXZlKSB7XG4gICAgZGVsZXRlIG1vZGlmaWVycy5wYXNzaXZlO1xuICAgIG5hbWUgPSBwcmVwZW5kTW9kaWZpZXJNYXJrZXIoJyYnLCBuYW1lLCBkeW5hbWljKTtcbiAgfVxuXG4gIHZhciBldmVudHM7XG4gIGlmIChtb2RpZmllcnMubmF0aXZlKSB7XG4gICAgZGVsZXRlIG1vZGlmaWVycy5uYXRpdmU7XG4gICAgZXZlbnRzID0gZWwubmF0aXZlRXZlbnRzIHx8IChlbC5uYXRpdmVFdmVudHMgPSB7fSk7XG4gIH0gZWxzZSB7XG4gICAgZXZlbnRzID0gZWwuZXZlbnRzIHx8IChlbC5ldmVudHMgPSB7fSk7XG4gIH1cblxuICB2YXIgbmV3SGFuZGxlciA9IHJhbmdlU2V0SXRlbSh7IHZhbHVlOiB2YWx1ZS50cmltKCksIGR5bmFtaWM6IGR5bmFtaWMgfSwgcmFuZ2UpO1xuICBpZiAobW9kaWZpZXJzICE9PSBlbXB0eU9iamVjdCkge1xuICAgIG5ld0hhbmRsZXIubW9kaWZpZXJzID0gbW9kaWZpZXJzO1xuICB9XG5cbiAgdmFyIGhhbmRsZXJzID0gZXZlbnRzW25hbWVdO1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKEFycmF5LmlzQXJyYXkoaGFuZGxlcnMpKSB7XG4gICAgaW1wb3J0YW50ID8gaGFuZGxlcnMudW5zaGlmdChuZXdIYW5kbGVyKSA6IGhhbmRsZXJzLnB1c2gobmV3SGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoaGFuZGxlcnMpIHtcbiAgICBldmVudHNbbmFtZV0gPSBpbXBvcnRhbnQgPyBbbmV3SGFuZGxlciwgaGFuZGxlcnNdIDogW2hhbmRsZXJzLCBuZXdIYW5kbGVyXTtcbiAgfSBlbHNlIHtcbiAgICBldmVudHNbbmFtZV0gPSBuZXdIYW5kbGVyO1xuICB9XG5cbiAgZWwucGxhaW4gPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0UmF3QmluZGluZ0F0dHIgKFxuICBlbCxcbiAgbmFtZVxuKSB7XG4gIHJldHVybiBlbC5yYXdBdHRyc01hcFsnOicgKyBuYW1lXSB8fFxuICAgIGVsLnJhd0F0dHJzTWFwWyd2LWJpbmQ6JyArIG5hbWVdIHx8XG4gICAgZWwucmF3QXR0cnNNYXBbbmFtZV1cbn1cblxuZnVuY3Rpb24gZ2V0QmluZGluZ0F0dHIgKFxuICBlbCxcbiAgbmFtZSxcbiAgZ2V0U3RhdGljXG4pIHtcbiAgdmFyIGR5bmFtaWNWYWx1ZSA9XG4gICAgZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJzonICsgbmFtZSkgfHxcbiAgICBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1iaW5kOicgKyBuYW1lKTtcbiAgaWYgKGR5bmFtaWNWYWx1ZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHBhcnNlRmlsdGVycyhkeW5hbWljVmFsdWUpXG4gIH0gZWxzZSBpZiAoZ2V0U3RhdGljICE9PSBmYWxzZSkge1xuICAgIHZhciBzdGF0aWNWYWx1ZSA9IGdldEFuZFJlbW92ZUF0dHIoZWwsIG5hbWUpO1xuICAgIGlmIChzdGF0aWNWYWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGljVmFsdWUpXG4gICAgfVxuICB9XG59XG5cbi8vIG5vdGU6IHRoaXMgb25seSByZW1vdmVzIHRoZSBhdHRyIGZyb20gdGhlIEFycmF5IChhdHRyc0xpc3QpIHNvIHRoYXQgaXRcbi8vIGRvZXNuJ3QgZ2V0IHByb2Nlc3NlZCBieSBwcm9jZXNzQXR0cnMuXG4vLyBCeSBkZWZhdWx0IGl0IGRvZXMgTk9UIHJlbW92ZSBpdCBmcm9tIHRoZSBtYXAgKGF0dHJzTWFwKSBiZWNhdXNlIHRoZSBtYXAgaXNcbi8vIG5lZWRlZCBkdXJpbmcgY29kZWdlbi5cbmZ1bmN0aW9uIGdldEFuZFJlbW92ZUF0dHIgKFxuICBlbCxcbiAgbmFtZSxcbiAgcmVtb3ZlRnJvbU1hcFxuKSB7XG4gIHZhciB2YWw7XG4gIGlmICgodmFsID0gZWwuYXR0cnNNYXBbbmFtZV0pICE9IG51bGwpIHtcbiAgICB2YXIgbGlzdCA9IGVsLmF0dHJzTGlzdDtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAobGlzdFtpXS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgIGxpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAocmVtb3ZlRnJvbU1hcCkge1xuICAgIGRlbGV0ZSBlbC5hdHRyc01hcFtuYW1lXTtcbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbmZ1bmN0aW9uIGdldEFuZFJlbW92ZUF0dHJCeVJlZ2V4IChcbiAgZWwsXG4gIG5hbWVcbikge1xuICB2YXIgbGlzdCA9IGVsLmF0dHJzTGlzdDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHZhciBhdHRyID0gbGlzdFtpXTtcbiAgICBpZiAobmFtZS50ZXN0KGF0dHIubmFtZSkpIHtcbiAgICAgIGxpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgcmV0dXJuIGF0dHJcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmFuZ2VTZXRJdGVtIChcbiAgaXRlbSxcbiAgcmFuZ2Vcbikge1xuICBpZiAocmFuZ2UpIHtcbiAgICBpZiAocmFuZ2Uuc3RhcnQgIT0gbnVsbCkge1xuICAgICAgaXRlbS5zdGFydCA9IHJhbmdlLnN0YXJ0O1xuICAgIH1cbiAgICBpZiAocmFuZ2UuZW5kICE9IG51bGwpIHtcbiAgICAgIGl0ZW0uZW5kID0gcmFuZ2UuZW5kO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaXRlbVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBDcm9zcy1wbGF0Zm9ybSBjb2RlIGdlbmVyYXRpb24gZm9yIGNvbXBvbmVudCB2LW1vZGVsXG4gKi9cbmZ1bmN0aW9uIGdlbkNvbXBvbmVudE1vZGVsIChcbiAgZWwsXG4gIHZhbHVlLFxuICBtb2RpZmllcnNcbikge1xuICB2YXIgcmVmID0gbW9kaWZpZXJzIHx8IHt9O1xuICB2YXIgbnVtYmVyID0gcmVmLm51bWJlcjtcbiAgdmFyIHRyaW0gPSByZWYudHJpbTtcblxuICB2YXIgYmFzZVZhbHVlRXhwcmVzc2lvbiA9ICckJHYnO1xuICB2YXIgdmFsdWVFeHByZXNzaW9uID0gYmFzZVZhbHVlRXhwcmVzc2lvbjtcbiAgaWYgKHRyaW0pIHtcbiAgICB2YWx1ZUV4cHJlc3Npb24gPVxuICAgICAgXCIodHlwZW9mIFwiICsgYmFzZVZhbHVlRXhwcmVzc2lvbiArIFwiID09PSAnc3RyaW5nJ1wiICtcbiAgICAgIFwiPyBcIiArIGJhc2VWYWx1ZUV4cHJlc3Npb24gKyBcIi50cmltKClcIiArXG4gICAgICBcIjogXCIgKyBiYXNlVmFsdWVFeHByZXNzaW9uICsgXCIpXCI7XG4gIH1cbiAgaWYgKG51bWJlcikge1xuICAgIHZhbHVlRXhwcmVzc2lvbiA9IFwiX24oXCIgKyB2YWx1ZUV4cHJlc3Npb24gKyBcIilcIjtcbiAgfVxuICB2YXIgYXNzaWdubWVudCA9IGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCB2YWx1ZUV4cHJlc3Npb24pO1xuXG4gIGVsLm1vZGVsID0ge1xuICAgIHZhbHVlOiAoXCIoXCIgKyB2YWx1ZSArIFwiKVwiKSxcbiAgICBleHByZXNzaW9uOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSksXG4gICAgY2FsbGJhY2s6IChcImZ1bmN0aW9uIChcIiArIGJhc2VWYWx1ZUV4cHJlc3Npb24gKyBcIikge1wiICsgYXNzaWdubWVudCArIFwifVwiKVxuICB9O1xufVxuXG4vKipcbiAqIENyb3NzLXBsYXRmb3JtIGNvZGVnZW4gaGVscGVyIGZvciBnZW5lcmF0aW5nIHYtbW9kZWwgdmFsdWUgYXNzaWdubWVudCBjb2RlLlxuICovXG5mdW5jdGlvbiBnZW5Bc3NpZ25tZW50Q29kZSAoXG4gIHZhbHVlLFxuICBhc3NpZ25tZW50XG4pIHtcbiAgdmFyIHJlcyA9IHBhcnNlTW9kZWwodmFsdWUpO1xuICBpZiAocmVzLmtleSA9PT0gbnVsbCkge1xuICAgIHJldHVybiAodmFsdWUgKyBcIj1cIiArIGFzc2lnbm1lbnQpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChcIiRzZXQoXCIgKyAocmVzLmV4cCkgKyBcIiwgXCIgKyAocmVzLmtleSkgKyBcIiwgXCIgKyBhc3NpZ25tZW50ICsgXCIpXCIpXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZSBhIHYtbW9kZWwgZXhwcmVzc2lvbiBpbnRvIGEgYmFzZSBwYXRoIGFuZCBhIGZpbmFsIGtleSBzZWdtZW50LlxuICogSGFuZGxlcyBib3RoIGRvdC1wYXRoIGFuZCBwb3NzaWJsZSBzcXVhcmUgYnJhY2tldHMuXG4gKlxuICogUG9zc2libGUgY2FzZXM6XG4gKlxuICogLSB0ZXN0XG4gKiAtIHRlc3Rba2V5XVxuICogLSB0ZXN0W3Rlc3QxW2tleV1dXG4gKiAtIHRlc3RbXCJhXCJdW2tleV1cbiAqIC0geHh4LnRlc3RbYVthXS50ZXN0MVtrZXldXVxuICogLSB0ZXN0Lnh4eC5hW1wiYXNhXCJdW3Rlc3QxW2tleV1dXG4gKlxuICovXG5cbnZhciBsZW4sIHN0ciwgY2hyLCBpbmRleCQxLCBleHByZXNzaW9uUG9zLCBleHByZXNzaW9uRW5kUG9zO1xuXG5cblxuZnVuY3Rpb24gcGFyc2VNb2RlbCAodmFsKSB7XG4gIC8vIEZpeCBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVlL3B1bGwvNzczMFxuICAvLyBhbGxvdyB2LW1vZGVsPVwib2JqLnZhbCBcIiAodHJhaWxpbmcgd2hpdGVzcGFjZSlcbiAgdmFsID0gdmFsLnRyaW0oKTtcbiAgbGVuID0gdmFsLmxlbmd0aDtcblxuICBpZiAodmFsLmluZGV4T2YoJ1snKSA8IDAgfHwgdmFsLmxhc3RJbmRleE9mKCddJykgPCBsZW4gLSAxKSB7XG4gICAgaW5kZXgkMSA9IHZhbC5sYXN0SW5kZXhPZignLicpO1xuICAgIGlmIChpbmRleCQxID4gLTEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGV4cDogdmFsLnNsaWNlKDAsIGluZGV4JDEpLFxuICAgICAgICBrZXk6ICdcIicgKyB2YWwuc2xpY2UoaW5kZXgkMSArIDEpICsgJ1wiJ1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleHA6IHZhbCxcbiAgICAgICAga2V5OiBudWxsXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RyID0gdmFsO1xuICBpbmRleCQxID0gZXhwcmVzc2lvblBvcyA9IGV4cHJlc3Npb25FbmRQb3MgPSAwO1xuXG4gIHdoaWxlICghZW9mKCkpIHtcbiAgICBjaHIgPSBuZXh0KCk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKGlzU3RyaW5nU3RhcnQoY2hyKSkge1xuICAgICAgcGFyc2VTdHJpbmcoY2hyKTtcbiAgICB9IGVsc2UgaWYgKGNociA9PT0gMHg1Qikge1xuICAgICAgcGFyc2VCcmFja2V0KGNocik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBleHA6IHZhbC5zbGljZSgwLCBleHByZXNzaW9uUG9zKSxcbiAgICBrZXk6IHZhbC5zbGljZShleHByZXNzaW9uUG9zICsgMSwgZXhwcmVzc2lvbkVuZFBvcylcbiAgfVxufVxuXG5mdW5jdGlvbiBuZXh0ICgpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQ29kZUF0KCsraW5kZXgkMSlcbn1cblxuZnVuY3Rpb24gZW9mICgpIHtcbiAgcmV0dXJuIGluZGV4JDEgPj0gbGVuXG59XG5cbmZ1bmN0aW9uIGlzU3RyaW5nU3RhcnQgKGNocikge1xuICByZXR1cm4gY2hyID09PSAweDIyIHx8IGNociA9PT0gMHgyN1xufVxuXG5mdW5jdGlvbiBwYXJzZUJyYWNrZXQgKGNocikge1xuICB2YXIgaW5CcmFja2V0ID0gMTtcbiAgZXhwcmVzc2lvblBvcyA9IGluZGV4JDE7XG4gIHdoaWxlICghZW9mKCkpIHtcbiAgICBjaHIgPSBuZXh0KCk7XG4gICAgaWYgKGlzU3RyaW5nU3RhcnQoY2hyKSkge1xuICAgICAgcGFyc2VTdHJpbmcoY2hyKTtcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChjaHIgPT09IDB4NUIpIHsgaW5CcmFja2V0Kys7IH1cbiAgICBpZiAoY2hyID09PSAweDVEKSB7IGluQnJhY2tldC0tOyB9XG4gICAgaWYgKGluQnJhY2tldCA9PT0gMCkge1xuICAgICAgZXhwcmVzc2lvbkVuZFBvcyA9IGluZGV4JDE7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVN0cmluZyAoY2hyKSB7XG4gIHZhciBzdHJpbmdRdW90ZSA9IGNocjtcbiAgd2hpbGUgKCFlb2YoKSkge1xuICAgIGNociA9IG5leHQoKTtcbiAgICBpZiAoY2hyID09PSBzdHJpbmdRdW90ZSkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbnZhciB3YXJuJDE7XG5cbi8vIGluIHNvbWUgY2FzZXMsIHRoZSBldmVudCB1c2VkIGhhcyB0byBiZSBkZXRlcm1pbmVkIGF0IHJ1bnRpbWVcbi8vIHNvIHdlIHVzZWQgc29tZSByZXNlcnZlZCB0b2tlbnMgZHVyaW5nIGNvbXBpbGUuXG52YXIgUkFOR0VfVE9LRU4gPSAnX19yJztcbnZhciBDSEVDS0JPWF9SQURJT19UT0tFTiA9ICdfX2MnO1xuXG5mdW5jdGlvbiBtb2RlbCAoXG4gIGVsLFxuICBkaXIsXG4gIF93YXJuXG4pIHtcbiAgd2FybiQxID0gX3dhcm47XG4gIHZhciB2YWx1ZSA9IGRpci52YWx1ZTtcbiAgdmFyIG1vZGlmaWVycyA9IGRpci5tb2RpZmllcnM7XG4gIHZhciB0YWcgPSBlbC50YWc7XG4gIHZhciB0eXBlID0gZWwuYXR0cnNNYXAudHlwZTtcblxuICB7XG4gICAgLy8gaW5wdXRzIHdpdGggdHlwZT1cImZpbGVcIiBhcmUgcmVhZCBvbmx5IGFuZCBzZXR0aW5nIHRoZSBpbnB1dCdzXG4gICAgLy8gdmFsdWUgd2lsbCB0aHJvdyBhbiBlcnJvci5cbiAgICBpZiAodGFnID09PSAnaW5wdXQnICYmIHR5cGUgPT09ICdmaWxlJykge1xuICAgICAgd2FybiQxKFxuICAgICAgICBcIjxcIiArIChlbC50YWcpICsgXCIgdi1tb2RlbD1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIiB0eXBlPVxcXCJmaWxlXFxcIj46XFxuXCIgK1xuICAgICAgICBcIkZpbGUgaW5wdXRzIGFyZSByZWFkIG9ubHkuIFVzZSBhIHYtb246Y2hhbmdlIGxpc3RlbmVyIGluc3RlYWQuXCIsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwWyd2LW1vZGVsJ11cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVsLmNvbXBvbmVudCkge1xuICAgIGdlbkNvbXBvbmVudE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgICAvLyBjb21wb25lbnQgdi1tb2RlbCBkb2Vzbid0IG5lZWQgZXh0cmEgcnVudGltZVxuICAgIHJldHVybiBmYWxzZVxuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3NlbGVjdCcpIHtcbiAgICBnZW5TZWxlY3QoZWwsIHZhbHVlLCBtb2RpZmllcnMpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2lucHV0JyAmJiB0eXBlID09PSAnY2hlY2tib3gnKSB7XG4gICAgZ2VuQ2hlY2tib3hNb2RlbChlbCwgdmFsdWUsIG1vZGlmaWVycyk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnaW5wdXQnICYmIHR5cGUgPT09ICdyYWRpbycpIHtcbiAgICBnZW5SYWRpb01vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdpbnB1dCcgfHwgdGFnID09PSAndGV4dGFyZWEnKSB7XG4gICAgZ2VuRGVmYXVsdE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgfSBlbHNlIGlmICghY29uZmlnLmlzUmVzZXJ2ZWRUYWcodGFnKSkge1xuICAgIGdlbkNvbXBvbmVudE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgICAvLyBjb21wb25lbnQgdi1tb2RlbCBkb2Vzbid0IG5lZWQgZXh0cmEgcnVudGltZVxuICAgIHJldHVybiBmYWxzZVxuICB9IGVsc2Uge1xuICAgIHdhcm4kMShcbiAgICAgIFwiPFwiICsgKGVsLnRhZykgKyBcIiB2LW1vZGVsPVxcXCJcIiArIHZhbHVlICsgXCJcXFwiPjogXCIgK1xuICAgICAgXCJ2LW1vZGVsIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBlbGVtZW50IHR5cGUuIFwiICtcbiAgICAgICdJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBjb250ZW50ZWRpdGFibGUsIGl0XFwncyByZWNvbW1lbmRlZCB0byAnICtcbiAgICAgICd3cmFwIGEgbGlicmFyeSBkZWRpY2F0ZWQgZm9yIHRoYXQgcHVycG9zZSBpbnNpZGUgYSBjdXN0b20gY29tcG9uZW50LicsXG4gICAgICBlbC5yYXdBdHRyc01hcFsndi1tb2RlbCddXG4gICAgKTtcbiAgfVxuXG4gIC8vIGVuc3VyZSBydW50aW1lIGRpcmVjdGl2ZSBtZXRhZGF0YVxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBnZW5DaGVja2JveE1vZGVsIChcbiAgZWwsXG4gIHZhbHVlLFxuICBtb2RpZmllcnNcbikge1xuICB2YXIgbnVtYmVyID0gbW9kaWZpZXJzICYmIG1vZGlmaWVycy5udW1iZXI7XG4gIHZhciB2YWx1ZUJpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3ZhbHVlJykgfHwgJ251bGwnO1xuICB2YXIgdHJ1ZVZhbHVlQmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAndHJ1ZS12YWx1ZScpIHx8ICd0cnVlJztcbiAgdmFyIGZhbHNlVmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdmYWxzZS12YWx1ZScpIHx8ICdmYWxzZSc7XG4gIGFkZFByb3AoZWwsICdjaGVja2VkJyxcbiAgICBcIkFycmF5LmlzQXJyYXkoXCIgKyB2YWx1ZSArIFwiKVwiICtcbiAgICBcIj9faShcIiArIHZhbHVlICsgXCIsXCIgKyB2YWx1ZUJpbmRpbmcgKyBcIik+LTFcIiArIChcbiAgICAgIHRydWVWYWx1ZUJpbmRpbmcgPT09ICd0cnVlJ1xuICAgICAgICA/IChcIjooXCIgKyB2YWx1ZSArIFwiKVwiKVxuICAgICAgICA6IChcIjpfcShcIiArIHZhbHVlICsgXCIsXCIgKyB0cnVlVmFsdWVCaW5kaW5nICsgXCIpXCIpXG4gICAgKVxuICApO1xuICBhZGRIYW5kbGVyKGVsLCAnY2hhbmdlJyxcbiAgICBcInZhciAkJGE9XCIgKyB2YWx1ZSArIFwiLFwiICtcbiAgICAgICAgJyQkZWw9JGV2ZW50LnRhcmdldCwnICtcbiAgICAgICAgXCIkJGM9JCRlbC5jaGVja2VkPyhcIiArIHRydWVWYWx1ZUJpbmRpbmcgKyBcIik6KFwiICsgZmFsc2VWYWx1ZUJpbmRpbmcgKyBcIik7XCIgK1xuICAgICdpZihBcnJheS5pc0FycmF5KCQkYSkpeycgK1xuICAgICAgXCJ2YXIgJCR2PVwiICsgKG51bWJlciA/ICdfbignICsgdmFsdWVCaW5kaW5nICsgJyknIDogdmFsdWVCaW5kaW5nKSArIFwiLFwiICtcbiAgICAgICAgICAnJCRpPV9pKCQkYSwkJHYpOycgK1xuICAgICAgXCJpZigkJGVsLmNoZWNrZWQpeyQkaTwwJiYoXCIgKyAoZ2VuQXNzaWdubWVudENvZGUodmFsdWUsICckJGEuY29uY2F0KFskJHZdKScpKSArIFwiKX1cIiArXG4gICAgICBcImVsc2V7JCRpPi0xJiYoXCIgKyAoZ2VuQXNzaWdubWVudENvZGUodmFsdWUsICckJGEuc2xpY2UoMCwkJGkpLmNvbmNhdCgkJGEuc2xpY2UoJCRpKzEpKScpKSArIFwiKX1cIiArXG4gICAgXCJ9ZWxzZXtcIiArIChnZW5Bc3NpZ25tZW50Q29kZSh2YWx1ZSwgJyQkYycpKSArIFwifVwiLFxuICAgIG51bGwsIHRydWVcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2VuUmFkaW9Nb2RlbCAoXG4gIGVsLFxuICB2YWx1ZSxcbiAgbW9kaWZpZXJzXG4pIHtcbiAgdmFyIG51bWJlciA9IG1vZGlmaWVycyAmJiBtb2RpZmllcnMubnVtYmVyO1xuICB2YXIgdmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICd2YWx1ZScpIHx8ICdudWxsJztcbiAgdmFsdWVCaW5kaW5nID0gbnVtYmVyID8gKFwiX24oXCIgKyB2YWx1ZUJpbmRpbmcgKyBcIilcIikgOiB2YWx1ZUJpbmRpbmc7XG4gIGFkZFByb3AoZWwsICdjaGVja2VkJywgKFwiX3EoXCIgKyB2YWx1ZSArIFwiLFwiICsgdmFsdWVCaW5kaW5nICsgXCIpXCIpKTtcbiAgYWRkSGFuZGxlcihlbCwgJ2NoYW5nZScsIGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCB2YWx1ZUJpbmRpbmcpLCBudWxsLCB0cnVlKTtcbn1cblxuZnVuY3Rpb24gZ2VuU2VsZWN0IChcbiAgZWwsXG4gIHZhbHVlLFxuICBtb2RpZmllcnNcbikge1xuICB2YXIgbnVtYmVyID0gbW9kaWZpZXJzICYmIG1vZGlmaWVycy5udW1iZXI7XG4gIHZhciBzZWxlY3RlZFZhbCA9IFwiQXJyYXkucHJvdG90eXBlLmZpbHRlclwiICtcbiAgICBcIi5jYWxsKCRldmVudC50YXJnZXQub3B0aW9ucyxmdW5jdGlvbihvKXtyZXR1cm4gby5zZWxlY3RlZH0pXCIgK1xuICAgIFwiLm1hcChmdW5jdGlvbihvKXt2YXIgdmFsID0gXFxcIl92YWx1ZVxcXCIgaW4gbyA/IG8uX3ZhbHVlIDogby52YWx1ZTtcIiArXG4gICAgXCJyZXR1cm4gXCIgKyAobnVtYmVyID8gJ19uKHZhbCknIDogJ3ZhbCcpICsgXCJ9KVwiO1xuXG4gIHZhciBhc3NpZ25tZW50ID0gJyRldmVudC50YXJnZXQubXVsdGlwbGUgPyAkJHNlbGVjdGVkVmFsIDogJCRzZWxlY3RlZFZhbFswXSc7XG4gIHZhciBjb2RlID0gXCJ2YXIgJCRzZWxlY3RlZFZhbCA9IFwiICsgc2VsZWN0ZWRWYWwgKyBcIjtcIjtcbiAgY29kZSA9IGNvZGUgKyBcIiBcIiArIChnZW5Bc3NpZ25tZW50Q29kZSh2YWx1ZSwgYXNzaWdubWVudCkpO1xuICBhZGRIYW5kbGVyKGVsLCAnY2hhbmdlJywgY29kZSwgbnVsbCwgdHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGdlbkRlZmF1bHRNb2RlbCAoXG4gIGVsLFxuICB2YWx1ZSxcbiAgbW9kaWZpZXJzXG4pIHtcbiAgdmFyIHR5cGUgPSBlbC5hdHRyc01hcC50eXBlO1xuXG4gIC8vIHdhcm4gaWYgdi1iaW5kOnZhbHVlIGNvbmZsaWN0cyB3aXRoIHYtbW9kZWxcbiAgLy8gZXhjZXB0IGZvciBpbnB1dHMgd2l0aCB2LWJpbmQ6dHlwZVxuICB7XG4gICAgdmFyIHZhbHVlJDEgPSBlbC5hdHRyc01hcFsndi1iaW5kOnZhbHVlJ10gfHwgZWwuYXR0cnNNYXBbJzp2YWx1ZSddO1xuICAgIHZhciB0eXBlQmluZGluZyA9IGVsLmF0dHJzTWFwWyd2LWJpbmQ6dHlwZSddIHx8IGVsLmF0dHJzTWFwWyc6dHlwZSddO1xuICAgIGlmICh2YWx1ZSQxICYmICF0eXBlQmluZGluZykge1xuICAgICAgdmFyIGJpbmRpbmcgPSBlbC5hdHRyc01hcFsndi1iaW5kOnZhbHVlJ10gPyAndi1iaW5kOnZhbHVlJyA6ICc6dmFsdWUnO1xuICAgICAgd2FybiQxKFxuICAgICAgICBiaW5kaW5nICsgXCI9XFxcIlwiICsgdmFsdWUkMSArIFwiXFxcIiBjb25mbGljdHMgd2l0aCB2LW1vZGVsIG9uIHRoZSBzYW1lIGVsZW1lbnQgXCIgK1xuICAgICAgICAnYmVjYXVzZSB0aGUgbGF0dGVyIGFscmVhZHkgZXhwYW5kcyB0byBhIHZhbHVlIGJpbmRpbmcgaW50ZXJuYWxseScsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwW2JpbmRpbmddXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHZhciByZWYgPSBtb2RpZmllcnMgfHwge307XG4gIHZhciBsYXp5ID0gcmVmLmxhenk7XG4gIHZhciBudW1iZXIgPSByZWYubnVtYmVyO1xuICB2YXIgdHJpbSA9IHJlZi50cmltO1xuICB2YXIgbmVlZENvbXBvc2l0aW9uR3VhcmQgPSAhbGF6eSAmJiB0eXBlICE9PSAncmFuZ2UnO1xuICB2YXIgZXZlbnQgPSBsYXp5XG4gICAgPyAnY2hhbmdlJ1xuICAgIDogdHlwZSA9PT0gJ3JhbmdlJ1xuICAgICAgPyBSQU5HRV9UT0tFTlxuICAgICAgOiAnaW5wdXQnO1xuXG4gIHZhciB2YWx1ZUV4cHJlc3Npb24gPSAnJGV2ZW50LnRhcmdldC52YWx1ZSc7XG4gIGlmICh0cmltKSB7XG4gICAgdmFsdWVFeHByZXNzaW9uID0gXCIkZXZlbnQudGFyZ2V0LnZhbHVlLnRyaW0oKVwiO1xuICB9XG4gIGlmIChudW1iZXIpIHtcbiAgICB2YWx1ZUV4cHJlc3Npb24gPSBcIl9uKFwiICsgdmFsdWVFeHByZXNzaW9uICsgXCIpXCI7XG4gIH1cblxuICB2YXIgY29kZSA9IGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCB2YWx1ZUV4cHJlc3Npb24pO1xuICBpZiAobmVlZENvbXBvc2l0aW9uR3VhcmQpIHtcbiAgICBjb2RlID0gXCJpZigkZXZlbnQudGFyZ2V0LmNvbXBvc2luZylyZXR1cm47XCIgKyBjb2RlO1xuICB9XG5cbiAgYWRkUHJvcChlbCwgJ3ZhbHVlJywgKFwiKFwiICsgdmFsdWUgKyBcIilcIikpO1xuICBhZGRIYW5kbGVyKGVsLCBldmVudCwgY29kZSwgbnVsbCwgdHJ1ZSk7XG4gIGlmICh0cmltIHx8IG51bWJlcikge1xuICAgIGFkZEhhbmRsZXIoZWwsICdibHVyJywgJyRmb3JjZVVwZGF0ZSgpJyk7XG4gIH1cbn1cblxuLyogICovXG5cbi8vIG5vcm1hbGl6ZSB2LW1vZGVsIGV2ZW50IHRva2VucyB0aGF0IGNhbiBvbmx5IGJlIGRldGVybWluZWQgYXQgcnVudGltZS5cbi8vIGl0J3MgaW1wb3J0YW50IHRvIHBsYWNlIHRoZSBldmVudCBhcyB0aGUgZmlyc3QgaW4gdGhlIGFycmF5IGJlY2F1c2Vcbi8vIHRoZSB3aG9sZSBwb2ludCBpcyBlbnN1cmluZyB0aGUgdi1tb2RlbCBjYWxsYmFjayBnZXRzIGNhbGxlZCBiZWZvcmVcbi8vIHVzZXItYXR0YWNoZWQgaGFuZGxlcnMuXG5mdW5jdGlvbiBub3JtYWxpemVFdmVudHMgKG9uKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoaXNEZWYob25bUkFOR0VfVE9LRU5dKSkge1xuICAgIC8vIElFIGlucHV0W3R5cGU9cmFuZ2VdIG9ubHkgc3VwcG9ydHMgYGNoYW5nZWAgZXZlbnRcbiAgICB2YXIgZXZlbnQgPSBpc0lFID8gJ2NoYW5nZScgOiAnaW5wdXQnO1xuICAgIG9uW2V2ZW50XSA9IFtdLmNvbmNhdChvbltSQU5HRV9UT0tFTl0sIG9uW2V2ZW50XSB8fCBbXSk7XG4gICAgZGVsZXRlIG9uW1JBTkdFX1RPS0VOXTtcbiAgfVxuICAvLyBUaGlzIHdhcyBvcmlnaW5hbGx5IGludGVuZGVkIHRvIGZpeCAjNDUyMSBidXQgbm8gbG9uZ2VyIG5lY2Vzc2FyeVxuICAvLyBhZnRlciAyLjUuIEtlZXBpbmcgaXQgZm9yIGJhY2t3YXJkcyBjb21wYXQgd2l0aCBnZW5lcmF0ZWQgY29kZSBmcm9tIDwgMi40XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoaXNEZWYob25bQ0hFQ0tCT1hfUkFESU9fVE9LRU5dKSkge1xuICAgIG9uLmNoYW5nZSA9IFtdLmNvbmNhdChvbltDSEVDS0JPWF9SQURJT19UT0tFTl0sIG9uLmNoYW5nZSB8fCBbXSk7XG4gICAgZGVsZXRlIG9uW0NIRUNLQk9YX1JBRElPX1RPS0VOXTtcbiAgfVxufVxuXG52YXIgdGFyZ2V0JDE7XG5cbmZ1bmN0aW9uIGNyZWF0ZU9uY2VIYW5kbGVyJDEgKGV2ZW50LCBoYW5kbGVyLCBjYXB0dXJlKSB7XG4gIHZhciBfdGFyZ2V0ID0gdGFyZ2V0JDE7IC8vIHNhdmUgY3VycmVudCB0YXJnZXQgZWxlbWVudCBpbiBjbG9zdXJlXG4gIHJldHVybiBmdW5jdGlvbiBvbmNlSGFuZGxlciAoKSB7XG4gICAgdmFyIHJlcyA9IGhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICBpZiAocmVzICE9PSBudWxsKSB7XG4gICAgICByZW1vdmUkMihldmVudCwgb25jZUhhbmRsZXIsIGNhcHR1cmUsIF90YXJnZXQpO1xuICAgIH1cbiAgfVxufVxuXG4vLyAjOTQ0NjogRmlyZWZveCA8PSA1MyAoaW4gcGFydGljdWxhciwgRVNSIDUyKSBoYXMgaW5jb3JyZWN0IEV2ZW50LnRpbWVTdGFtcFxuLy8gaW1wbGVtZW50YXRpb24gYW5kIGRvZXMgbm90IGZpcmUgbWljcm90YXNrcyBpbiBiZXR3ZWVuIGV2ZW50IHByb3BhZ2F0aW9uLCBzb1xuLy8gc2FmZSB0byBleGNsdWRlLlxudmFyIHVzZU1pY3JvdGFza0ZpeCA9IGlzVXNpbmdNaWNyb1Rhc2sgJiYgIShpc0ZGICYmIE51bWJlcihpc0ZGWzFdKSA8PSA1Myk7XG5cbmZ1bmN0aW9uIGFkZCQxIChcbiAgbmFtZSxcbiAgaGFuZGxlcixcbiAgY2FwdHVyZSxcbiAgcGFzc2l2ZVxuKSB7XG4gIC8vIGFzeW5jIGVkZ2UgY2FzZSAjNjU2NjogaW5uZXIgY2xpY2sgZXZlbnQgdHJpZ2dlcnMgcGF0Y2gsIGV2ZW50IGhhbmRsZXJcbiAgLy8gYXR0YWNoZWQgdG8gb3V0ZXIgZWxlbWVudCBkdXJpbmcgcGF0Y2gsIGFuZCB0cmlnZ2VyZWQgYWdhaW4uIFRoaXNcbiAgLy8gaGFwcGVucyBiZWNhdXNlIGJyb3dzZXJzIGZpcmUgbWljcm90YXNrIHRpY2tzIGJldHdlZW4gZXZlbnQgcHJvcGFnYXRpb24uXG4gIC8vIHRoZSBzb2x1dGlvbiBpcyBzaW1wbGU6IHdlIHNhdmUgdGhlIHRpbWVzdGFtcCB3aGVuIGEgaGFuZGxlciBpcyBhdHRhY2hlZCxcbiAgLy8gYW5kIHRoZSBoYW5kbGVyIHdvdWxkIG9ubHkgZmlyZSBpZiB0aGUgZXZlbnQgcGFzc2VkIHRvIGl0IHdhcyBmaXJlZFxuICAvLyBBRlRFUiBpdCB3YXMgYXR0YWNoZWQuXG4gIGlmICh1c2VNaWNyb3Rhc2tGaXgpIHtcbiAgICB2YXIgYXR0YWNoZWRUaW1lc3RhbXAgPSBjdXJyZW50Rmx1c2hUaW1lc3RhbXA7XG4gICAgdmFyIG9yaWdpbmFsID0gaGFuZGxlcjtcbiAgICBoYW5kbGVyID0gb3JpZ2luYWwuX3dyYXBwZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKFxuICAgICAgICAvLyBubyBidWJibGluZywgc2hvdWxkIGFsd2F5cyBmaXJlLlxuICAgICAgICAvLyB0aGlzIGlzIGp1c3QgYSBzYWZldHkgbmV0IGluIGNhc2UgZXZlbnQudGltZVN0YW1wIGlzIHVucmVsaWFibGUgaW5cbiAgICAgICAgLy8gY2VydGFpbiB3ZWlyZCBlbnZpcm9ubWVudHMuLi5cbiAgICAgICAgZS50YXJnZXQgPT09IGUuY3VycmVudFRhcmdldCB8fFxuICAgICAgICAvLyBldmVudCBpcyBmaXJlZCBhZnRlciBoYW5kbGVyIGF0dGFjaG1lbnRcbiAgICAgICAgZS50aW1lU3RhbXAgPj0gYXR0YWNoZWRUaW1lc3RhbXAgfHxcbiAgICAgICAgLy8gYmFpbCBmb3IgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSBidWdneSBldmVudC50aW1lU3RhbXAgaW1wbGVtZW50YXRpb25zXG4gICAgICAgIC8vICM5NDYyIGlPUyA5IGJ1ZzogZXZlbnQudGltZVN0YW1wIGlzIDAgYWZ0ZXIgaGlzdG9yeS5wdXNoU3RhdGVcbiAgICAgICAgLy8gIzk2ODEgUXRXZWJFbmdpbmUgZXZlbnQudGltZVN0YW1wIGlzIG5lZ2F0aXZlIHZhbHVlXG4gICAgICAgIGUudGltZVN0YW1wIDw9IDAgfHxcbiAgICAgICAgLy8gIzk0NDggYmFpbCBpZiBldmVudCBpcyBmaXJlZCBpbiBhbm90aGVyIGRvY3VtZW50IGluIGEgbXVsdGktcGFnZVxuICAgICAgICAvLyBlbGVjdHJvbi9udy5qcyBhcHAsIHNpbmNlIGV2ZW50LnRpbWVTdGFtcCB3aWxsIGJlIHVzaW5nIGEgZGlmZmVyZW50XG4gICAgICAgIC8vIHN0YXJ0aW5nIHJlZmVyZW5jZVxuICAgICAgICBlLnRhcmdldC5vd25lckRvY3VtZW50ICE9PSBkb2N1bWVudFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICB9XG4gICAgfTtcbiAgfVxuICB0YXJnZXQkMS5hZGRFdmVudExpc3RlbmVyKFxuICAgIG5hbWUsXG4gICAgaGFuZGxlcixcbiAgICBzdXBwb3J0c1Bhc3NpdmVcbiAgICAgID8geyBjYXB0dXJlOiBjYXB0dXJlLCBwYXNzaXZlOiBwYXNzaXZlIH1cbiAgICAgIDogY2FwdHVyZVxuICApO1xufVxuXG5mdW5jdGlvbiByZW1vdmUkMiAoXG4gIG5hbWUsXG4gIGhhbmRsZXIsXG4gIGNhcHR1cmUsXG4gIF90YXJnZXRcbikge1xuICAoX3RhcmdldCB8fCB0YXJnZXQkMSkucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICBuYW1lLFxuICAgIGhhbmRsZXIuX3dyYXBwZXIgfHwgaGFuZGxlcixcbiAgICBjYXB0dXJlXG4gICk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZURPTUxpc3RlbmVycyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmIChpc1VuZGVmKG9sZFZub2RlLmRhdGEub24pICYmIGlzVW5kZWYodm5vZGUuZGF0YS5vbikpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb24gPSB2bm9kZS5kYXRhLm9uIHx8IHt9O1xuICB2YXIgb2xkT24gPSBvbGRWbm9kZS5kYXRhLm9uIHx8IHt9O1xuICB0YXJnZXQkMSA9IHZub2RlLmVsbTtcbiAgbm9ybWFsaXplRXZlbnRzKG9uKTtcbiAgdXBkYXRlTGlzdGVuZXJzKG9uLCBvbGRPbiwgYWRkJDEsIHJlbW92ZSQyLCBjcmVhdGVPbmNlSGFuZGxlciQxLCB2bm9kZS5jb250ZXh0KTtcbiAgdGFyZ2V0JDEgPSB1bmRlZmluZWQ7XG59XG5cbnZhciBldmVudHMgPSB7XG4gIGNyZWF0ZTogdXBkYXRlRE9NTGlzdGVuZXJzLFxuICB1cGRhdGU6IHVwZGF0ZURPTUxpc3RlbmVyc1xufTtcblxuLyogICovXG5cbnZhciBzdmdDb250YWluZXI7XG5cbmZ1bmN0aW9uIHVwZGF0ZURPTVByb3BzIChvbGRWbm9kZSwgdm5vZGUpIHtcbiAgaWYgKGlzVW5kZWYob2xkVm5vZGUuZGF0YS5kb21Qcm9wcykgJiYgaXNVbmRlZih2bm9kZS5kYXRhLmRvbVByb3BzKSkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBrZXksIGN1cjtcbiAgdmFyIGVsbSA9IHZub2RlLmVsbTtcbiAgdmFyIG9sZFByb3BzID0gb2xkVm5vZGUuZGF0YS5kb21Qcm9wcyB8fCB7fTtcbiAgdmFyIHByb3BzID0gdm5vZGUuZGF0YS5kb21Qcm9wcyB8fCB7fTtcbiAgLy8gY2xvbmUgb2JzZXJ2ZWQgb2JqZWN0cywgYXMgdGhlIHVzZXIgcHJvYmFibHkgd2FudHMgdG8gbXV0YXRlIGl0XG4gIGlmIChpc0RlZihwcm9wcy5fX29iX18pKSB7XG4gICAgcHJvcHMgPSB2bm9kZS5kYXRhLmRvbVByb3BzID0gZXh0ZW5kKHt9LCBwcm9wcyk7XG4gIH1cblxuICBmb3IgKGtleSBpbiBvbGRQcm9wcykge1xuICAgIGlmICghKGtleSBpbiBwcm9wcykpIHtcbiAgICAgIGVsbVtrZXldID0gJyc7XG4gICAgfVxuICB9XG5cbiAgZm9yIChrZXkgaW4gcHJvcHMpIHtcbiAgICBjdXIgPSBwcm9wc1trZXldO1xuICAgIC8vIGlnbm9yZSBjaGlsZHJlbiBpZiB0aGUgbm9kZSBoYXMgdGV4dENvbnRlbnQgb3IgaW5uZXJIVE1MLFxuICAgIC8vIGFzIHRoZXNlIHdpbGwgdGhyb3cgYXdheSBleGlzdGluZyBET00gbm9kZXMgYW5kIGNhdXNlIHJlbW92YWwgZXJyb3JzXG4gICAgLy8gb24gc3Vic2VxdWVudCBwYXRjaGVzICgjMzM2MClcbiAgICBpZiAoa2V5ID09PSAndGV4dENvbnRlbnQnIHx8IGtleSA9PT0gJ2lubmVySFRNTCcpIHtcbiAgICAgIGlmICh2bm9kZS5jaGlsZHJlbikgeyB2bm9kZS5jaGlsZHJlbi5sZW5ndGggPSAwOyB9XG4gICAgICBpZiAoY3VyID09PSBvbGRQcm9wc1trZXldKSB7IGNvbnRpbnVlIH1cbiAgICAgIC8vICM2NjAxIHdvcmsgYXJvdW5kIENocm9tZSB2ZXJzaW9uIDw9IDU1IGJ1ZyB3aGVyZSBzaW5nbGUgdGV4dE5vZGVcbiAgICAgIC8vIHJlcGxhY2VkIGJ5IGlubmVySFRNTC90ZXh0Q29udGVudCByZXRhaW5zIGl0cyBwYXJlbnROb2RlIHByb3BlcnR5XG4gICAgICBpZiAoZWxtLmNoaWxkTm9kZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGVsbS5yZW1vdmVDaGlsZChlbG0uY2hpbGROb2Rlc1swXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGtleSA9PT0gJ3ZhbHVlJyAmJiBlbG0udGFnTmFtZSAhPT0gJ1BST0dSRVNTJykge1xuICAgICAgLy8gc3RvcmUgdmFsdWUgYXMgX3ZhbHVlIGFzIHdlbGwgc2luY2VcbiAgICAgIC8vIG5vbi1zdHJpbmcgdmFsdWVzIHdpbGwgYmUgc3RyaW5naWZpZWRcbiAgICAgIGVsbS5fdmFsdWUgPSBjdXI7XG4gICAgICAvLyBhdm9pZCByZXNldHRpbmcgY3Vyc29yIHBvc2l0aW9uIHdoZW4gdmFsdWUgaXMgdGhlIHNhbWVcbiAgICAgIHZhciBzdHJDdXIgPSBpc1VuZGVmKGN1cikgPyAnJyA6IFN0cmluZyhjdXIpO1xuICAgICAgaWYgKHNob3VsZFVwZGF0ZVZhbHVlKGVsbSwgc3RyQ3VyKSkge1xuICAgICAgICBlbG0udmFsdWUgPSBzdHJDdXI7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChrZXkgPT09ICdpbm5lckhUTUwnICYmIGlzU1ZHKGVsbS50YWdOYW1lKSAmJiBpc1VuZGVmKGVsbS5pbm5lckhUTUwpKSB7XG4gICAgICAvLyBJRSBkb2Vzbid0IHN1cHBvcnQgaW5uZXJIVE1MIGZvciBTVkcgZWxlbWVudHNcbiAgICAgIHN2Z0NvbnRhaW5lciA9IHN2Z0NvbnRhaW5lciB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHN2Z0NvbnRhaW5lci5pbm5lckhUTUwgPSBcIjxzdmc+XCIgKyBjdXIgKyBcIjwvc3ZnPlwiO1xuICAgICAgdmFyIHN2ZyA9IHN2Z0NvbnRhaW5lci5maXJzdENoaWxkO1xuICAgICAgd2hpbGUgKGVsbS5maXJzdENoaWxkKSB7XG4gICAgICAgIGVsbS5yZW1vdmVDaGlsZChlbG0uZmlyc3RDaGlsZCk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoc3ZnLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgZWxtLmFwcGVuZENoaWxkKHN2Zy5maXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgLy8gc2tpcCB0aGUgdXBkYXRlIGlmIG9sZCBhbmQgbmV3IFZET00gc3RhdGUgaXMgdGhlIHNhbWUuXG4gICAgICAvLyBgdmFsdWVgIGlzIGhhbmRsZWQgc2VwYXJhdGVseSBiZWNhdXNlIHRoZSBET00gdmFsdWUgbWF5IGJlIHRlbXBvcmFyaWx5XG4gICAgICAvLyBvdXQgb2Ygc3luYyB3aXRoIFZET00gc3RhdGUgZHVlIHRvIGZvY3VzLCBjb21wb3NpdGlvbiBhbmQgbW9kaWZpZXJzLlxuICAgICAgLy8gVGhpcyAgIzQ1MjEgYnkgc2tpcHBpbmcgdGhlIHVubmVjZXNzYXJ5IGBjaGVja2VkYCB1cGRhdGUuXG4gICAgICBjdXIgIT09IG9sZFByb3BzW2tleV1cbiAgICApIHtcbiAgICAgIC8vIHNvbWUgcHJvcGVydHkgdXBkYXRlcyBjYW4gdGhyb3dcbiAgICAgIC8vIGUuZy4gYHZhbHVlYCBvbiA8cHJvZ3Jlc3M+IHcvIG5vbi1maW5pdGUgdmFsdWVcbiAgICAgIHRyeSB7XG4gICAgICAgIGVsbVtrZXldID0gY3VyO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG4gIH1cbn1cblxuLy8gY2hlY2sgcGxhdGZvcm1zL3dlYi91dGlsL2F0dHJzLmpzIGFjY2VwdFZhbHVlXG5cblxuZnVuY3Rpb24gc2hvdWxkVXBkYXRlVmFsdWUgKGVsbSwgY2hlY2tWYWwpIHtcbiAgcmV0dXJuICghZWxtLmNvbXBvc2luZyAmJiAoXG4gICAgZWxtLnRhZ05hbWUgPT09ICdPUFRJT04nIHx8XG4gICAgaXNOb3RJbkZvY3VzQW5kRGlydHkoZWxtLCBjaGVja1ZhbCkgfHxcbiAgICBpc0RpcnR5V2l0aE1vZGlmaWVycyhlbG0sIGNoZWNrVmFsKVxuICApKVxufVxuXG5mdW5jdGlvbiBpc05vdEluRm9jdXNBbmREaXJ0eSAoZWxtLCBjaGVja1ZhbCkge1xuICAvLyByZXR1cm4gdHJ1ZSB3aGVuIHRleHRib3ggKC5udW1iZXIgYW5kIC50cmltKSBsb3NlcyBmb2N1cyBhbmQgaXRzIHZhbHVlIGlzXG4gIC8vIG5vdCBlcXVhbCB0byB0aGUgdXBkYXRlZCB2YWx1ZVxuICB2YXIgbm90SW5Gb2N1cyA9IHRydWU7XG4gIC8vICM2MTU3XG4gIC8vIHdvcmsgYXJvdW5kIElFIGJ1ZyB3aGVuIGFjY2Vzc2luZyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGluIGFuIGlmcmFtZVxuICB0cnkgeyBub3RJbkZvY3VzID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAhPT0gZWxtOyB9IGNhdGNoIChlKSB7fVxuICByZXR1cm4gbm90SW5Gb2N1cyAmJiBlbG0udmFsdWUgIT09IGNoZWNrVmFsXG59XG5cbmZ1bmN0aW9uIGlzRGlydHlXaXRoTW9kaWZpZXJzIChlbG0sIG5ld1ZhbCkge1xuICB2YXIgdmFsdWUgPSBlbG0udmFsdWU7XG4gIHZhciBtb2RpZmllcnMgPSBlbG0uX3ZNb2RpZmllcnM7IC8vIGluamVjdGVkIGJ5IHYtbW9kZWwgcnVudGltZVxuICBpZiAoaXNEZWYobW9kaWZpZXJzKSkge1xuICAgIGlmIChtb2RpZmllcnMubnVtYmVyKSB7XG4gICAgICByZXR1cm4gdG9OdW1iZXIodmFsdWUpICE9PSB0b051bWJlcihuZXdWYWwpXG4gICAgfVxuICAgIGlmIChtb2RpZmllcnMudHJpbSkge1xuICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKSAhPT0gbmV3VmFsLnRyaW0oKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWUgIT09IG5ld1ZhbFxufVxuXG52YXIgZG9tUHJvcHMgPSB7XG4gIGNyZWF0ZTogdXBkYXRlRE9NUHJvcHMsXG4gIHVwZGF0ZTogdXBkYXRlRE9NUHJvcHNcbn07XG5cbi8qICAqL1xuXG52YXIgcGFyc2VTdHlsZVRleHQgPSBjYWNoZWQoZnVuY3Rpb24gKGNzc1RleHQpIHtcbiAgdmFyIHJlcyA9IHt9O1xuICB2YXIgbGlzdERlbGltaXRlciA9IC87KD8hW14oXSpcXCkpL2c7XG4gIHZhciBwcm9wZXJ0eURlbGltaXRlciA9IC86KC4rKS87XG4gIGNzc1RleHQuc3BsaXQobGlzdERlbGltaXRlcikuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgIGlmIChpdGVtKSB7XG4gICAgICB2YXIgdG1wID0gaXRlbS5zcGxpdChwcm9wZXJ0eURlbGltaXRlcik7XG4gICAgICB0bXAubGVuZ3RoID4gMSAmJiAocmVzW3RtcFswXS50cmltKCldID0gdG1wWzFdLnRyaW0oKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc1xufSk7XG5cbi8vIG1lcmdlIHN0YXRpYyBhbmQgZHluYW1pYyBzdHlsZSBkYXRhIG9uIHRoZSBzYW1lIHZub2RlXG5mdW5jdGlvbiBub3JtYWxpemVTdHlsZURhdGEgKGRhdGEpIHtcbiAgdmFyIHN0eWxlID0gbm9ybWFsaXplU3R5bGVCaW5kaW5nKGRhdGEuc3R5bGUpO1xuICAvLyBzdGF0aWMgc3R5bGUgaXMgcHJlLXByb2Nlc3NlZCBpbnRvIGFuIG9iamVjdCBkdXJpbmcgY29tcGlsYXRpb25cbiAgLy8gYW5kIGlzIGFsd2F5cyBhIGZyZXNoIG9iamVjdCwgc28gaXQncyBzYWZlIHRvIG1lcmdlIGludG8gaXRcbiAgcmV0dXJuIGRhdGEuc3RhdGljU3R5bGVcbiAgICA/IGV4dGVuZChkYXRhLnN0YXRpY1N0eWxlLCBzdHlsZSlcbiAgICA6IHN0eWxlXG59XG5cbi8vIG5vcm1hbGl6ZSBwb3NzaWJsZSBhcnJheSAvIHN0cmluZyB2YWx1ZXMgaW50byBPYmplY3RcbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0eWxlQmluZGluZyAoYmluZGluZ1N0eWxlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGJpbmRpbmdTdHlsZSkpIHtcbiAgICByZXR1cm4gdG9PYmplY3QoYmluZGluZ1N0eWxlKVxuICB9XG4gIGlmICh0eXBlb2YgYmluZGluZ1N0eWxlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBwYXJzZVN0eWxlVGV4dChiaW5kaW5nU3R5bGUpXG4gIH1cbiAgcmV0dXJuIGJpbmRpbmdTdHlsZVxufVxuXG4vKipcbiAqIHBhcmVudCBjb21wb25lbnQgc3R5bGUgc2hvdWxkIGJlIGFmdGVyIGNoaWxkJ3NcbiAqIHNvIHRoYXQgcGFyZW50IGNvbXBvbmVudCdzIHN0eWxlIGNvdWxkIG92ZXJyaWRlIGl0XG4gKi9cbmZ1bmN0aW9uIGdldFN0eWxlICh2bm9kZSwgY2hlY2tDaGlsZCkge1xuICB2YXIgcmVzID0ge307XG4gIHZhciBzdHlsZURhdGE7XG5cbiAgaWYgKGNoZWNrQ2hpbGQpIHtcbiAgICB2YXIgY2hpbGROb2RlID0gdm5vZGU7XG4gICAgd2hpbGUgKGNoaWxkTm9kZS5jb21wb25lbnRJbnN0YW5jZSkge1xuICAgICAgY2hpbGROb2RlID0gY2hpbGROb2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZTtcbiAgICAgIGlmIChcbiAgICAgICAgY2hpbGROb2RlICYmIGNoaWxkTm9kZS5kYXRhICYmXG4gICAgICAgIChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEoY2hpbGROb2RlLmRhdGEpKVxuICAgICAgKSB7XG4gICAgICAgIGV4dGVuZChyZXMsIHN0eWxlRGF0YSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEodm5vZGUuZGF0YSkpKSB7XG4gICAgZXh0ZW5kKHJlcywgc3R5bGVEYXRhKTtcbiAgfVxuXG4gIHZhciBwYXJlbnROb2RlID0gdm5vZGU7XG4gIHdoaWxlICgocGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50KSkge1xuICAgIGlmIChwYXJlbnROb2RlLmRhdGEgJiYgKHN0eWxlRGF0YSA9IG5vcm1hbGl6ZVN0eWxlRGF0YShwYXJlbnROb2RlLmRhdGEpKSkge1xuICAgICAgZXh0ZW5kKHJlcywgc3R5bGVEYXRhKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKiAgKi9cblxudmFyIGNzc1ZhclJFID0gL14tLS87XG52YXIgaW1wb3J0YW50UkUgPSAvXFxzKiFpbXBvcnRhbnQkLztcbnZhciBzZXRQcm9wID0gZnVuY3Rpb24gKGVsLCBuYW1lLCB2YWwpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChjc3NWYXJSRS50ZXN0KG5hbWUpKSB7XG4gICAgZWwuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdmFsKTtcbiAgfSBlbHNlIGlmIChpbXBvcnRhbnRSRS50ZXN0KHZhbCkpIHtcbiAgICBlbC5zdHlsZS5zZXRQcm9wZXJ0eShoeXBoZW5hdGUobmFtZSksIHZhbC5yZXBsYWNlKGltcG9ydGFudFJFLCAnJyksICdpbXBvcnRhbnQnKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbm9ybWFsaXplZE5hbWUgPSBub3JtYWxpemUobmFtZSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgLy8gU3VwcG9ydCB2YWx1ZXMgYXJyYXkgY3JlYXRlZCBieSBhdXRvcHJlZml4ZXIsIGUuZy5cbiAgICAgIC8vIHtkaXNwbGF5OiBbXCItd2Via2l0LWJveFwiLCBcIi1tcy1mbGV4Ym94XCIsIFwiZmxleFwiXX1cbiAgICAgIC8vIFNldCB0aGVtIG9uZSBieSBvbmUsIGFuZCB0aGUgYnJvd3NlciB3aWxsIG9ubHkgc2V0IHRob3NlIGl0IGNhbiByZWNvZ25pemVcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB2YWwubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgZWwuc3R5bGVbbm9ybWFsaXplZE5hbWVdID0gdmFsW2ldO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zdHlsZVtub3JtYWxpemVkTmFtZV0gPSB2YWw7XG4gICAgfVxuICB9XG59O1xuXG52YXIgdmVuZG9yTmFtZXMgPSBbJ1dlYmtpdCcsICdNb3onLCAnbXMnXTtcblxudmFyIGVtcHR5U3R5bGU7XG52YXIgbm9ybWFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChwcm9wKSB7XG4gIGVtcHR5U3R5bGUgPSBlbXB0eVN0eWxlIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLnN0eWxlO1xuICBwcm9wID0gY2FtZWxpemUocHJvcCk7XG4gIGlmIChwcm9wICE9PSAnZmlsdGVyJyAmJiAocHJvcCBpbiBlbXB0eVN0eWxlKSkge1xuICAgIHJldHVybiBwcm9wXG4gIH1cbiAgdmFyIGNhcE5hbWUgPSBwcm9wLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcHJvcC5zbGljZSgxKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2ZW5kb3JOYW1lcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBuYW1lID0gdmVuZG9yTmFtZXNbaV0gKyBjYXBOYW1lO1xuICAgIGlmIChuYW1lIGluIGVtcHR5U3R5bGUpIHtcbiAgICAgIHJldHVybiBuYW1lXG4gICAgfVxuICB9XG59KTtcblxuZnVuY3Rpb24gdXBkYXRlU3R5bGUgKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgZGF0YSA9IHZub2RlLmRhdGE7XG4gIHZhciBvbGREYXRhID0gb2xkVm5vZGUuZGF0YTtcblxuICBpZiAoaXNVbmRlZihkYXRhLnN0YXRpY1N0eWxlKSAmJiBpc1VuZGVmKGRhdGEuc3R5bGUpICYmXG4gICAgaXNVbmRlZihvbGREYXRhLnN0YXRpY1N0eWxlKSAmJiBpc1VuZGVmKG9sZERhdGEuc3R5bGUpXG4gICkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGN1ciwgbmFtZTtcbiAgdmFyIGVsID0gdm5vZGUuZWxtO1xuICB2YXIgb2xkU3RhdGljU3R5bGUgPSBvbGREYXRhLnN0YXRpY1N0eWxlO1xuICB2YXIgb2xkU3R5bGVCaW5kaW5nID0gb2xkRGF0YS5ub3JtYWxpemVkU3R5bGUgfHwgb2xkRGF0YS5zdHlsZSB8fCB7fTtcblxuICAvLyBpZiBzdGF0aWMgc3R5bGUgZXhpc3RzLCBzdHlsZWJpbmRpbmcgYWxyZWFkeSBtZXJnZWQgaW50byBpdCB3aGVuIGRvaW5nIG5vcm1hbGl6ZVN0eWxlRGF0YVxuICB2YXIgb2xkU3R5bGUgPSBvbGRTdGF0aWNTdHlsZSB8fCBvbGRTdHlsZUJpbmRpbmc7XG5cbiAgdmFyIHN0eWxlID0gbm9ybWFsaXplU3R5bGVCaW5kaW5nKHZub2RlLmRhdGEuc3R5bGUpIHx8IHt9O1xuXG4gIC8vIHN0b3JlIG5vcm1hbGl6ZWQgc3R5bGUgdW5kZXIgYSBkaWZmZXJlbnQga2V5IGZvciBuZXh0IGRpZmZcbiAgLy8gbWFrZSBzdXJlIHRvIGNsb25lIGl0IGlmIGl0J3MgcmVhY3RpdmUsIHNpbmNlIHRoZSB1c2VyIGxpa2VseSB3YW50c1xuICAvLyB0byBtdXRhdGUgaXQuXG4gIHZub2RlLmRhdGEubm9ybWFsaXplZFN0eWxlID0gaXNEZWYoc3R5bGUuX19vYl9fKVxuICAgID8gZXh0ZW5kKHt9LCBzdHlsZSlcbiAgICA6IHN0eWxlO1xuXG4gIHZhciBuZXdTdHlsZSA9IGdldFN0eWxlKHZub2RlLCB0cnVlKTtcblxuICBmb3IgKG5hbWUgaW4gb2xkU3R5bGUpIHtcbiAgICBpZiAoaXNVbmRlZihuZXdTdHlsZVtuYW1lXSkpIHtcbiAgICAgIHNldFByb3AoZWwsIG5hbWUsICcnKTtcbiAgICB9XG4gIH1cbiAgZm9yIChuYW1lIGluIG5ld1N0eWxlKSB7XG4gICAgY3VyID0gbmV3U3R5bGVbbmFtZV07XG4gICAgaWYgKGN1ciAhPT0gb2xkU3R5bGVbbmFtZV0pIHtcbiAgICAgIC8vIGllOSBzZXR0aW5nIHRvIG51bGwgaGFzIG5vIGVmZmVjdCwgbXVzdCB1c2UgZW1wdHkgc3RyaW5nXG4gICAgICBzZXRQcm9wKGVsLCBuYW1lLCBjdXIgPT0gbnVsbCA/ICcnIDogY3VyKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHN0eWxlID0ge1xuICBjcmVhdGU6IHVwZGF0ZVN0eWxlLFxuICB1cGRhdGU6IHVwZGF0ZVN0eWxlXG59O1xuXG4vKiAgKi9cblxudmFyIHdoaXRlc3BhY2VSRSA9IC9cXHMrLztcblxuLyoqXG4gKiBBZGQgY2xhc3Mgd2l0aCBjb21wYXRpYmlsaXR5IGZvciBTVkcgc2luY2UgY2xhc3NMaXN0IGlzIG5vdCBzdXBwb3J0ZWQgb25cbiAqIFNWRyBlbGVtZW50cyBpbiBJRVxuICovXG5mdW5jdGlvbiBhZGRDbGFzcyAoZWwsIGNscykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCFjbHMgfHwgIShjbHMgPSBjbHMudHJpbSgpKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgIGlmIChjbHMuaW5kZXhPZignICcpID4gLTEpIHtcbiAgICAgIGNscy5zcGxpdCh3aGl0ZXNwYWNlUkUpLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGVsLmNsYXNzTGlzdC5hZGQoYyk7IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKGNscyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBjdXIgPSBcIiBcIiArIChlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgfHwgJycpICsgXCIgXCI7XG4gICAgaWYgKGN1ci5pbmRleE9mKCcgJyArIGNscyArICcgJykgPCAwKSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgKGN1ciArIGNscykudHJpbSgpKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgY2xhc3Mgd2l0aCBjb21wYXRpYmlsaXR5IGZvciBTVkcgc2luY2UgY2xhc3NMaXN0IGlzIG5vdCBzdXBwb3J0ZWQgb25cbiAqIFNWRyBlbGVtZW50cyBpbiBJRVxuICovXG5mdW5jdGlvbiByZW1vdmVDbGFzcyAoZWwsIGNscykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCFjbHMgfHwgIShjbHMgPSBjbHMudHJpbSgpKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgIGlmIChjbHMuaW5kZXhPZignICcpID4gLTEpIHtcbiAgICAgIGNscy5zcGxpdCh3aGl0ZXNwYWNlUkUpLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGVsLmNsYXNzTGlzdC5yZW1vdmUoYyk7IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKGNscyk7XG4gICAgfVxuICAgIGlmICghZWwuY2xhc3NMaXN0Lmxlbmd0aCkge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdjbGFzcycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgY3VyID0gXCIgXCIgKyAoZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnKSArIFwiIFwiO1xuICAgIHZhciB0YXIgPSAnICcgKyBjbHMgKyAnICc7XG4gICAgd2hpbGUgKGN1ci5pbmRleE9mKHRhcikgPj0gMCkge1xuICAgICAgY3VyID0gY3VyLnJlcGxhY2UodGFyLCAnICcpO1xuICAgIH1cbiAgICBjdXIgPSBjdXIudHJpbSgpO1xuICAgIGlmIChjdXIpIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBjdXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiByZXNvbHZlVHJhbnNpdGlvbiAoZGVmJCQxKSB7XG4gIGlmICghZGVmJCQxKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKHR5cGVvZiBkZWYkJDEgPT09ICdvYmplY3QnKSB7XG4gICAgdmFyIHJlcyA9IHt9O1xuICAgIGlmIChkZWYkJDEuY3NzICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5kKHJlcywgYXV0b0Nzc1RyYW5zaXRpb24oZGVmJCQxLm5hbWUgfHwgJ3YnKSk7XG4gICAgfVxuICAgIGV4dGVuZChyZXMsIGRlZiQkMSk7XG4gICAgcmV0dXJuIHJlc1xuICB9IGVsc2UgaWYgKHR5cGVvZiBkZWYkJDEgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGF1dG9Dc3NUcmFuc2l0aW9uKGRlZiQkMSlcbiAgfVxufVxuXG52YXIgYXV0b0Nzc1RyYW5zaXRpb24gPSBjYWNoZWQoZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnRlckNsYXNzOiAobmFtZSArIFwiLWVudGVyXCIpLFxuICAgIGVudGVyVG9DbGFzczogKG5hbWUgKyBcIi1lbnRlci10b1wiKSxcbiAgICBlbnRlckFjdGl2ZUNsYXNzOiAobmFtZSArIFwiLWVudGVyLWFjdGl2ZVwiKSxcbiAgICBsZWF2ZUNsYXNzOiAobmFtZSArIFwiLWxlYXZlXCIpLFxuICAgIGxlYXZlVG9DbGFzczogKG5hbWUgKyBcIi1sZWF2ZS10b1wiKSxcbiAgICBsZWF2ZUFjdGl2ZUNsYXNzOiAobmFtZSArIFwiLWxlYXZlLWFjdGl2ZVwiKVxuICB9XG59KTtcblxudmFyIGhhc1RyYW5zaXRpb24gPSBpbkJyb3dzZXIgJiYgIWlzSUU5O1xudmFyIFRSQU5TSVRJT04gPSAndHJhbnNpdGlvbic7XG52YXIgQU5JTUFUSU9OID0gJ2FuaW1hdGlvbic7XG5cbi8vIFRyYW5zaXRpb24gcHJvcGVydHkvZXZlbnQgc25pZmZpbmdcbnZhciB0cmFuc2l0aW9uUHJvcCA9ICd0cmFuc2l0aW9uJztcbnZhciB0cmFuc2l0aW9uRW5kRXZlbnQgPSAndHJhbnNpdGlvbmVuZCc7XG52YXIgYW5pbWF0aW9uUHJvcCA9ICdhbmltYXRpb24nO1xudmFyIGFuaW1hdGlvbkVuZEV2ZW50ID0gJ2FuaW1hdGlvbmVuZCc7XG5pZiAoaGFzVHJhbnNpdGlvbikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKHdpbmRvdy5vbnRyYW5zaXRpb25lbmQgPT09IHVuZGVmaW5lZCAmJlxuICAgIHdpbmRvdy5vbndlYmtpdHRyYW5zaXRpb25lbmQgIT09IHVuZGVmaW5lZFxuICApIHtcbiAgICB0cmFuc2l0aW9uUHJvcCA9ICdXZWJraXRUcmFuc2l0aW9uJztcbiAgICB0cmFuc2l0aW9uRW5kRXZlbnQgPSAnd2Via2l0VHJhbnNpdGlvbkVuZCc7XG4gIH1cbiAgaWYgKHdpbmRvdy5vbmFuaW1hdGlvbmVuZCA9PT0gdW5kZWZpbmVkICYmXG4gICAgd2luZG93Lm9ud2Via2l0YW5pbWF0aW9uZW5kICE9PSB1bmRlZmluZWRcbiAgKSB7XG4gICAgYW5pbWF0aW9uUHJvcCA9ICdXZWJraXRBbmltYXRpb24nO1xuICAgIGFuaW1hdGlvbkVuZEV2ZW50ID0gJ3dlYmtpdEFuaW1hdGlvbkVuZCc7XG4gIH1cbn1cblxuLy8gYmluZGluZyB0byB3aW5kb3cgaXMgbmVjZXNzYXJ5IHRvIG1ha2UgaG90IHJlbG9hZCB3b3JrIGluIElFIGluIHN0cmljdCBtb2RlXG52YXIgcmFmID0gaW5Ccm93c2VyXG4gID8gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZVxuICAgID8gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZS5iaW5kKHdpbmRvdylcbiAgICA6IHNldFRpbWVvdXRcbiAgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBmdW5jdGlvbiAoZm4pIHsgcmV0dXJuIGZuKCk7IH07XG5cbmZ1bmN0aW9uIG5leHRGcmFtZSAoZm4pIHtcbiAgcmFmKGZ1bmN0aW9uICgpIHtcbiAgICByYWYoZm4pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gYWRkVHJhbnNpdGlvbkNsYXNzIChlbCwgY2xzKSB7XG4gIHZhciB0cmFuc2l0aW9uQ2xhc3NlcyA9IGVsLl90cmFuc2l0aW9uQ2xhc3NlcyB8fCAoZWwuX3RyYW5zaXRpb25DbGFzc2VzID0gW10pO1xuICBpZiAodHJhbnNpdGlvbkNsYXNzZXMuaW5kZXhPZihjbHMpIDwgMCkge1xuICAgIHRyYW5zaXRpb25DbGFzc2VzLnB1c2goY2xzKTtcbiAgICBhZGRDbGFzcyhlbCwgY2xzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVUcmFuc2l0aW9uQ2xhc3MgKGVsLCBjbHMpIHtcbiAgaWYgKGVsLl90cmFuc2l0aW9uQ2xhc3Nlcykge1xuICAgIHJlbW92ZShlbC5fdHJhbnNpdGlvbkNsYXNzZXMsIGNscyk7XG4gIH1cbiAgcmVtb3ZlQ2xhc3MoZWwsIGNscyk7XG59XG5cbmZ1bmN0aW9uIHdoZW5UcmFuc2l0aW9uRW5kcyAoXG4gIGVsLFxuICBleHBlY3RlZFR5cGUsXG4gIGNiXG4pIHtcbiAgdmFyIHJlZiA9IGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpO1xuICB2YXIgdHlwZSA9IHJlZi50eXBlO1xuICB2YXIgdGltZW91dCA9IHJlZi50aW1lb3V0O1xuICB2YXIgcHJvcENvdW50ID0gcmVmLnByb3BDb3VudDtcbiAgaWYgKCF0eXBlKSB7IHJldHVybiBjYigpIH1cbiAgdmFyIGV2ZW50ID0gdHlwZSA9PT0gVFJBTlNJVElPTiA/IHRyYW5zaXRpb25FbmRFdmVudCA6IGFuaW1hdGlvbkVuZEV2ZW50O1xuICB2YXIgZW5kZWQgPSAwO1xuICB2YXIgZW5kID0gZnVuY3Rpb24gKCkge1xuICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uRW5kKTtcbiAgICBjYigpO1xuICB9O1xuICB2YXIgb25FbmQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLnRhcmdldCA9PT0gZWwpIHtcbiAgICAgIGlmICgrK2VuZGVkID49IHByb3BDb3VudCkge1xuICAgICAgICBlbmQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmIChlbmRlZCA8IHByb3BDb3VudCkge1xuICAgICAgZW5kKCk7XG4gICAgfVxuICB9LCB0aW1lb3V0ICsgMSk7XG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uRW5kKTtcbn1cblxudmFyIHRyYW5zZm9ybVJFID0gL1xcYih0cmFuc2Zvcm18YWxsKSgsfCQpLztcblxuZnVuY3Rpb24gZ2V0VHJhbnNpdGlvbkluZm8gKGVsLCBleHBlY3RlZFR5cGUpIHtcbiAgdmFyIHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgLy8gSlNET00gbWF5IHJldHVybiB1bmRlZmluZWQgZm9yIHRyYW5zaXRpb24gcHJvcGVydGllc1xuICB2YXIgdHJhbnNpdGlvbkRlbGF5cyA9IChzdHlsZXNbdHJhbnNpdGlvblByb3AgKyAnRGVsYXknXSB8fCAnJykuc3BsaXQoJywgJyk7XG4gIHZhciB0cmFuc2l0aW9uRHVyYXRpb25zID0gKHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdEdXJhdGlvbiddIHx8ICcnKS5zcGxpdCgnLCAnKTtcbiAgdmFyIHRyYW5zaXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dCh0cmFuc2l0aW9uRGVsYXlzLCB0cmFuc2l0aW9uRHVyYXRpb25zKTtcbiAgdmFyIGFuaW1hdGlvbkRlbGF5cyA9IChzdHlsZXNbYW5pbWF0aW9uUHJvcCArICdEZWxheSddIHx8ICcnKS5zcGxpdCgnLCAnKTtcbiAgdmFyIGFuaW1hdGlvbkR1cmF0aW9ucyA9IChzdHlsZXNbYW5pbWF0aW9uUHJvcCArICdEdXJhdGlvbiddIHx8ICcnKS5zcGxpdCgnLCAnKTtcbiAgdmFyIGFuaW1hdGlvblRpbWVvdXQgPSBnZXRUaW1lb3V0KGFuaW1hdGlvbkRlbGF5cywgYW5pbWF0aW9uRHVyYXRpb25zKTtcblxuICB2YXIgdHlwZTtcbiAgdmFyIHRpbWVvdXQgPSAwO1xuICB2YXIgcHJvcENvdW50ID0gMDtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChleHBlY3RlZFR5cGUgPT09IFRSQU5TSVRJT04pIHtcbiAgICBpZiAodHJhbnNpdGlvblRpbWVvdXQgPiAwKSB7XG4gICAgICB0eXBlID0gVFJBTlNJVElPTjtcbiAgICAgIHRpbWVvdXQgPSB0cmFuc2l0aW9uVGltZW91dDtcbiAgICAgIHByb3BDb3VudCA9IHRyYW5zaXRpb25EdXJhdGlvbnMubGVuZ3RoO1xuICAgIH1cbiAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09IEFOSU1BVElPTikge1xuICAgIGlmIChhbmltYXRpb25UaW1lb3V0ID4gMCkge1xuICAgICAgdHlwZSA9IEFOSU1BVElPTjtcbiAgICAgIHRpbWVvdXQgPSBhbmltYXRpb25UaW1lb3V0O1xuICAgICAgcHJvcENvdW50ID0gYW5pbWF0aW9uRHVyYXRpb25zLmxlbmd0aDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGltZW91dCA9IE1hdGgubWF4KHRyYW5zaXRpb25UaW1lb3V0LCBhbmltYXRpb25UaW1lb3V0KTtcbiAgICB0eXBlID0gdGltZW91dCA+IDBcbiAgICAgID8gdHJhbnNpdGlvblRpbWVvdXQgPiBhbmltYXRpb25UaW1lb3V0XG4gICAgICAgID8gVFJBTlNJVElPTlxuICAgICAgICA6IEFOSU1BVElPTlxuICAgICAgOiBudWxsO1xuICAgIHByb3BDb3VudCA9IHR5cGVcbiAgICAgID8gdHlwZSA9PT0gVFJBTlNJVElPTlxuICAgICAgICA/IHRyYW5zaXRpb25EdXJhdGlvbnMubGVuZ3RoXG4gICAgICAgIDogYW5pbWF0aW9uRHVyYXRpb25zLmxlbmd0aFxuICAgICAgOiAwO1xuICB9XG4gIHZhciBoYXNUcmFuc2Zvcm0gPVxuICAgIHR5cGUgPT09IFRSQU5TSVRJT04gJiZcbiAgICB0cmFuc2Zvcm1SRS50ZXN0KHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdQcm9wZXJ0eSddKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIHRpbWVvdXQ6IHRpbWVvdXQsXG4gICAgcHJvcENvdW50OiBwcm9wQ291bnQsXG4gICAgaGFzVHJhbnNmb3JtOiBoYXNUcmFuc2Zvcm1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUaW1lb3V0IChkZWxheXMsIGR1cmF0aW9ucykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICB3aGlsZSAoZGVsYXlzLmxlbmd0aCA8IGR1cmF0aW9ucy5sZW5ndGgpIHtcbiAgICBkZWxheXMgPSBkZWxheXMuY29uY2F0KGRlbGF5cyk7XG4gIH1cblxuICByZXR1cm4gTWF0aC5tYXguYXBwbHkobnVsbCwgZHVyYXRpb25zLm1hcChmdW5jdGlvbiAoZCwgaSkge1xuICAgIHJldHVybiB0b01zKGQpICsgdG9NcyhkZWxheXNbaV0pXG4gIH0pKVxufVxuXG4vLyBPbGQgdmVyc2lvbnMgb2YgQ2hyb21pdW0gKGJlbG93IDYxLjAuMzE2My4xMDApIGZvcm1hdHMgZmxvYXRpbmcgcG9pbnRlciBudW1iZXJzXG4vLyBpbiBhIGxvY2FsZS1kZXBlbmRlbnQgd2F5LCB1c2luZyBhIGNvbW1hIGluc3RlYWQgb2YgYSBkb3QuXG4vLyBJZiBjb21tYSBpcyBub3QgcmVwbGFjZWQgd2l0aCBhIGRvdCwgdGhlIGlucHV0IHdpbGwgYmUgcm91bmRlZCBkb3duIChpLmUuIGFjdGluZ1xuLy8gYXMgYSBmbG9vciBmdW5jdGlvbikgY2F1c2luZyB1bmV4cGVjdGVkIGJlaGF2aW9yc1xuZnVuY3Rpb24gdG9NcyAocykge1xuICByZXR1cm4gTnVtYmVyKHMuc2xpY2UoMCwgLTEpLnJlcGxhY2UoJywnLCAnLicpKSAqIDEwMDBcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGVudGVyICh2bm9kZSwgdG9nZ2xlRGlzcGxheSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG5cbiAgLy8gY2FsbCBsZWF2ZSBjYWxsYmFjayBub3dcbiAgaWYgKGlzRGVmKGVsLl9sZWF2ZUNiKSkge1xuICAgIGVsLl9sZWF2ZUNiLmNhbmNlbGxlZCA9IHRydWU7XG4gICAgZWwuX2xlYXZlQ2IoKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcmVzb2x2ZVRyYW5zaXRpb24odm5vZGUuZGF0YS50cmFuc2l0aW9uKTtcbiAgaWYgKGlzVW5kZWYoZGF0YSkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoaXNEZWYoZWwuX2VudGVyQ2IpIHx8IGVsLm5vZGVUeXBlICE9PSAxKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgY3NzID0gZGF0YS5jc3M7XG4gIHZhciB0eXBlID0gZGF0YS50eXBlO1xuICB2YXIgZW50ZXJDbGFzcyA9IGRhdGEuZW50ZXJDbGFzcztcbiAgdmFyIGVudGVyVG9DbGFzcyA9IGRhdGEuZW50ZXJUb0NsYXNzO1xuICB2YXIgZW50ZXJBY3RpdmVDbGFzcyA9IGRhdGEuZW50ZXJBY3RpdmVDbGFzcztcbiAgdmFyIGFwcGVhckNsYXNzID0gZGF0YS5hcHBlYXJDbGFzcztcbiAgdmFyIGFwcGVhclRvQ2xhc3MgPSBkYXRhLmFwcGVhclRvQ2xhc3M7XG4gIHZhciBhcHBlYXJBY3RpdmVDbGFzcyA9IGRhdGEuYXBwZWFyQWN0aXZlQ2xhc3M7XG4gIHZhciBiZWZvcmVFbnRlciA9IGRhdGEuYmVmb3JlRW50ZXI7XG4gIHZhciBlbnRlciA9IGRhdGEuZW50ZXI7XG4gIHZhciBhZnRlckVudGVyID0gZGF0YS5hZnRlckVudGVyO1xuICB2YXIgZW50ZXJDYW5jZWxsZWQgPSBkYXRhLmVudGVyQ2FuY2VsbGVkO1xuICB2YXIgYmVmb3JlQXBwZWFyID0gZGF0YS5iZWZvcmVBcHBlYXI7XG4gIHZhciBhcHBlYXIgPSBkYXRhLmFwcGVhcjtcbiAgdmFyIGFmdGVyQXBwZWFyID0gZGF0YS5hZnRlckFwcGVhcjtcbiAgdmFyIGFwcGVhckNhbmNlbGxlZCA9IGRhdGEuYXBwZWFyQ2FuY2VsbGVkO1xuICB2YXIgZHVyYXRpb24gPSBkYXRhLmR1cmF0aW9uO1xuXG4gIC8vIGFjdGl2ZUluc3RhbmNlIHdpbGwgYWx3YXlzIGJlIHRoZSA8dHJhbnNpdGlvbj4gY29tcG9uZW50IG1hbmFnaW5nIHRoaXNcbiAgLy8gdHJhbnNpdGlvbi4gT25lIGVkZ2UgY2FzZSB0byBjaGVjayBpcyB3aGVuIHRoZSA8dHJhbnNpdGlvbj4gaXMgcGxhY2VkXG4gIC8vIGFzIHRoZSByb290IG5vZGUgb2YgYSBjaGlsZCBjb21wb25lbnQuIEluIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGNoZWNrXG4gIC8vIDx0cmFuc2l0aW9uPidzIHBhcmVudCBmb3IgYXBwZWFyIGNoZWNrLlxuICB2YXIgY29udGV4dCA9IGFjdGl2ZUluc3RhbmNlO1xuICB2YXIgdHJhbnNpdGlvbk5vZGUgPSBhY3RpdmVJbnN0YW5jZS4kdm5vZGU7XG4gIHdoaWxlICh0cmFuc2l0aW9uTm9kZSAmJiB0cmFuc2l0aW9uTm9kZS5wYXJlbnQpIHtcbiAgICBjb250ZXh0ID0gdHJhbnNpdGlvbk5vZGUuY29udGV4dDtcbiAgICB0cmFuc2l0aW9uTm9kZSA9IHRyYW5zaXRpb25Ob2RlLnBhcmVudDtcbiAgfVxuXG4gIHZhciBpc0FwcGVhciA9ICFjb250ZXh0Ll9pc01vdW50ZWQgfHwgIXZub2RlLmlzUm9vdEluc2VydDtcblxuICBpZiAoaXNBcHBlYXIgJiYgIWFwcGVhciAmJiBhcHBlYXIgIT09ICcnKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgc3RhcnRDbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhckNsYXNzXG4gICAgPyBhcHBlYXJDbGFzc1xuICAgIDogZW50ZXJDbGFzcztcbiAgdmFyIGFjdGl2ZUNsYXNzID0gaXNBcHBlYXIgJiYgYXBwZWFyQWN0aXZlQ2xhc3NcbiAgICA/IGFwcGVhckFjdGl2ZUNsYXNzXG4gICAgOiBlbnRlckFjdGl2ZUNsYXNzO1xuICB2YXIgdG9DbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhclRvQ2xhc3NcbiAgICA/IGFwcGVhclRvQ2xhc3NcbiAgICA6IGVudGVyVG9DbGFzcztcblxuICB2YXIgYmVmb3JlRW50ZXJIb29rID0gaXNBcHBlYXJcbiAgICA/IChiZWZvcmVBcHBlYXIgfHwgYmVmb3JlRW50ZXIpXG4gICAgOiBiZWZvcmVFbnRlcjtcbiAgdmFyIGVudGVySG9vayA9IGlzQXBwZWFyXG4gICAgPyAodHlwZW9mIGFwcGVhciA9PT0gJ2Z1bmN0aW9uJyA/IGFwcGVhciA6IGVudGVyKVxuICAgIDogZW50ZXI7XG4gIHZhciBhZnRlckVudGVySG9vayA9IGlzQXBwZWFyXG4gICAgPyAoYWZ0ZXJBcHBlYXIgfHwgYWZ0ZXJFbnRlcilcbiAgICA6IGFmdGVyRW50ZXI7XG4gIHZhciBlbnRlckNhbmNlbGxlZEhvb2sgPSBpc0FwcGVhclxuICAgID8gKGFwcGVhckNhbmNlbGxlZCB8fCBlbnRlckNhbmNlbGxlZClcbiAgICA6IGVudGVyQ2FuY2VsbGVkO1xuXG4gIHZhciBleHBsaWNpdEVudGVyRHVyYXRpb24gPSB0b051bWJlcihcbiAgICBpc09iamVjdChkdXJhdGlvbilcbiAgICAgID8gZHVyYXRpb24uZW50ZXJcbiAgICAgIDogZHVyYXRpb25cbiAgKTtcblxuICBpZiAoZXhwbGljaXRFbnRlckR1cmF0aW9uICE9IG51bGwpIHtcbiAgICBjaGVja0R1cmF0aW9uKGV4cGxpY2l0RW50ZXJEdXJhdGlvbiwgJ2VudGVyJywgdm5vZGUpO1xuICB9XG5cbiAgdmFyIGV4cGVjdHNDU1MgPSBjc3MgIT09IGZhbHNlICYmICFpc0lFOTtcbiAgdmFyIHVzZXJXYW50c0NvbnRyb2wgPSBnZXRIb29rQXJndW1lbnRzTGVuZ3RoKGVudGVySG9vayk7XG5cbiAgdmFyIGNiID0gZWwuX2VudGVyQ2IgPSBvbmNlKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZXhwZWN0c0NTUykge1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCB0b0NsYXNzKTtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgYWN0aXZlQ2xhc3MpO1xuICAgIH1cbiAgICBpZiAoY2IuY2FuY2VsbGVkKSB7XG4gICAgICBpZiAoZXhwZWN0c0NTUykge1xuICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIHN0YXJ0Q2xhc3MpO1xuICAgICAgfVxuICAgICAgZW50ZXJDYW5jZWxsZWRIb29rICYmIGVudGVyQ2FuY2VsbGVkSG9vayhlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyRW50ZXJIb29rICYmIGFmdGVyRW50ZXJIb29rKGVsKTtcbiAgICB9XG4gICAgZWwuX2VudGVyQ2IgPSBudWxsO1xuICB9KTtcblxuICBpZiAoIXZub2RlLmRhdGEuc2hvdykge1xuICAgIC8vIHJlbW92ZSBwZW5kaW5nIGxlYXZlIGVsZW1lbnQgb24gZW50ZXIgYnkgaW5qZWN0aW5nIGFuIGluc2VydCBob29rXG4gICAgbWVyZ2VWTm9kZUhvb2sodm5vZGUsICdpbnNlcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcGFyZW50ID0gZWwucGFyZW50Tm9kZTtcbiAgICAgIHZhciBwZW5kaW5nTm9kZSA9IHBhcmVudCAmJiBwYXJlbnQuX3BlbmRpbmcgJiYgcGFyZW50Ll9wZW5kaW5nW3Zub2RlLmtleV07XG4gICAgICBpZiAocGVuZGluZ05vZGUgJiZcbiAgICAgICAgcGVuZGluZ05vZGUudGFnID09PSB2bm9kZS50YWcgJiZcbiAgICAgICAgcGVuZGluZ05vZGUuZWxtLl9sZWF2ZUNiXG4gICAgICApIHtcbiAgICAgICAgcGVuZGluZ05vZGUuZWxtLl9sZWF2ZUNiKCk7XG4gICAgICB9XG4gICAgICBlbnRlckhvb2sgJiYgZW50ZXJIb29rKGVsLCBjYik7XG4gICAgfSk7XG4gIH1cblxuICAvLyBzdGFydCBlbnRlciB0cmFuc2l0aW9uXG4gIGJlZm9yZUVudGVySG9vayAmJiBiZWZvcmVFbnRlckhvb2soZWwpO1xuICBpZiAoZXhwZWN0c0NTUykge1xuICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgc3RhcnRDbGFzcyk7XG4gICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBhY3RpdmVDbGFzcyk7XG4gICAgbmV4dEZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgc3RhcnRDbGFzcyk7XG4gICAgICBpZiAoIWNiLmNhbmNlbGxlZCkge1xuICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIHRvQ2xhc3MpO1xuICAgICAgICBpZiAoIXVzZXJXYW50c0NvbnRyb2wpIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZER1cmF0aW9uKGV4cGxpY2l0RW50ZXJEdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoY2IsIGV4cGxpY2l0RW50ZXJEdXJhdGlvbik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgdHlwZSwgY2IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHZub2RlLmRhdGEuc2hvdykge1xuICAgIHRvZ2dsZURpc3BsYXkgJiYgdG9nZ2xlRGlzcGxheSgpO1xuICAgIGVudGVySG9vayAmJiBlbnRlckhvb2soZWwsIGNiKTtcbiAgfVxuXG4gIGlmICghZXhwZWN0c0NTUyAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgIGNiKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbGVhdmUgKHZub2RlLCBybSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG5cbiAgLy8gY2FsbCBlbnRlciBjYWxsYmFjayBub3dcbiAgaWYgKGlzRGVmKGVsLl9lbnRlckNiKSkge1xuICAgIGVsLl9lbnRlckNiLmNhbmNlbGxlZCA9IHRydWU7XG4gICAgZWwuX2VudGVyQ2IoKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcmVzb2x2ZVRyYW5zaXRpb24odm5vZGUuZGF0YS50cmFuc2l0aW9uKTtcbiAgaWYgKGlzVW5kZWYoZGF0YSkgfHwgZWwubm9kZVR5cGUgIT09IDEpIHtcbiAgICByZXR1cm4gcm0oKVxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChpc0RlZihlbC5fbGVhdmVDYikpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHZhciBjc3MgPSBkYXRhLmNzcztcbiAgdmFyIHR5cGUgPSBkYXRhLnR5cGU7XG4gIHZhciBsZWF2ZUNsYXNzID0gZGF0YS5sZWF2ZUNsYXNzO1xuICB2YXIgbGVhdmVUb0NsYXNzID0gZGF0YS5sZWF2ZVRvQ2xhc3M7XG4gIHZhciBsZWF2ZUFjdGl2ZUNsYXNzID0gZGF0YS5sZWF2ZUFjdGl2ZUNsYXNzO1xuICB2YXIgYmVmb3JlTGVhdmUgPSBkYXRhLmJlZm9yZUxlYXZlO1xuICB2YXIgbGVhdmUgPSBkYXRhLmxlYXZlO1xuICB2YXIgYWZ0ZXJMZWF2ZSA9IGRhdGEuYWZ0ZXJMZWF2ZTtcbiAgdmFyIGxlYXZlQ2FuY2VsbGVkID0gZGF0YS5sZWF2ZUNhbmNlbGxlZDtcbiAgdmFyIGRlbGF5TGVhdmUgPSBkYXRhLmRlbGF5TGVhdmU7XG4gIHZhciBkdXJhdGlvbiA9IGRhdGEuZHVyYXRpb247XG5cbiAgdmFyIGV4cGVjdHNDU1MgPSBjc3MgIT09IGZhbHNlICYmICFpc0lFOTtcbiAgdmFyIHVzZXJXYW50c0NvbnRyb2wgPSBnZXRIb29rQXJndW1lbnRzTGVuZ3RoKGxlYXZlKTtcblxuICB2YXIgZXhwbGljaXRMZWF2ZUR1cmF0aW9uID0gdG9OdW1iZXIoXG4gICAgaXNPYmplY3QoZHVyYXRpb24pXG4gICAgICA/IGR1cmF0aW9uLmxlYXZlXG4gICAgICA6IGR1cmF0aW9uXG4gICk7XG5cbiAgaWYgKGlzRGVmKGV4cGxpY2l0TGVhdmVEdXJhdGlvbikpIHtcbiAgICBjaGVja0R1cmF0aW9uKGV4cGxpY2l0TGVhdmVEdXJhdGlvbiwgJ2xlYXZlJywgdm5vZGUpO1xuICB9XG5cbiAgdmFyIGNiID0gZWwuX2xlYXZlQ2IgPSBvbmNlKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZWwucGFyZW50Tm9kZSAmJiBlbC5wYXJlbnROb2RlLl9wZW5kaW5nKSB7XG4gICAgICBlbC5wYXJlbnROb2RlLl9wZW5kaW5nW3Zub2RlLmtleV0gPSBudWxsO1xuICAgIH1cbiAgICBpZiAoZXhwZWN0c0NTUykge1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZVRvQ2xhc3MpO1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTtcbiAgICB9XG4gICAgaWYgKGNiLmNhbmNlbGxlZCkge1xuICAgICAgaWYgKGV4cGVjdHNDU1MpIHtcbiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUNsYXNzKTtcbiAgICAgIH1cbiAgICAgIGxlYXZlQ2FuY2VsbGVkICYmIGxlYXZlQ2FuY2VsbGVkKGVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm0oKTtcbiAgICAgIGFmdGVyTGVhdmUgJiYgYWZ0ZXJMZWF2ZShlbCk7XG4gICAgfVxuICAgIGVsLl9sZWF2ZUNiID0gbnVsbDtcbiAgfSk7XG5cbiAgaWYgKGRlbGF5TGVhdmUpIHtcbiAgICBkZWxheUxlYXZlKHBlcmZvcm1MZWF2ZSk7XG4gIH0gZWxzZSB7XG4gICAgcGVyZm9ybUxlYXZlKCk7XG4gIH1cblxuICBmdW5jdGlvbiBwZXJmb3JtTGVhdmUgKCkge1xuICAgIC8vIHRoZSBkZWxheWVkIGxlYXZlIG1heSBoYXZlIGFscmVhZHkgYmVlbiBjYW5jZWxsZWRcbiAgICBpZiAoY2IuY2FuY2VsbGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgLy8gcmVjb3JkIGxlYXZpbmcgZWxlbWVudFxuICAgIGlmICghdm5vZGUuZGF0YS5zaG93ICYmIGVsLnBhcmVudE5vZGUpIHtcbiAgICAgIChlbC5wYXJlbnROb2RlLl9wZW5kaW5nIHx8IChlbC5wYXJlbnROb2RlLl9wZW5kaW5nID0ge30pKVsodm5vZGUua2V5KV0gPSB2bm9kZTtcbiAgICB9XG4gICAgYmVmb3JlTGVhdmUgJiYgYmVmb3JlTGVhdmUoZWwpO1xuICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQ2xhc3MpO1xuICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTtcbiAgICAgIG5leHRGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7XG4gICAgICAgIGlmICghY2IuY2FuY2VsbGVkKSB7XG4gICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZVRvQ2xhc3MpO1xuICAgICAgICAgIGlmICghdXNlcldhbnRzQ29udHJvbCkge1xuICAgICAgICAgICAgaWYgKGlzVmFsaWREdXJhdGlvbihleHBsaWNpdExlYXZlRHVyYXRpb24pKSB7XG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoY2IsIGV4cGxpY2l0TGVhdmVEdXJhdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB3aGVuVHJhbnNpdGlvbkVuZHMoZWwsIHR5cGUsIGNiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBsZWF2ZSAmJiBsZWF2ZShlbCwgY2IpO1xuICAgIGlmICghZXhwZWN0c0NTUyAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgICAgY2IoKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gb25seSB1c2VkIGluIGRldiBtb2RlXG5mdW5jdGlvbiBjaGVja0R1cmF0aW9uICh2YWwsIG5hbWUsIHZub2RlKSB7XG4gIGlmICh0eXBlb2YgdmFsICE9PSAnbnVtYmVyJykge1xuICAgIHdhcm4oXG4gICAgICBcIjx0cmFuc2l0aW9uPiBleHBsaWNpdCBcIiArIG5hbWUgKyBcIiBkdXJhdGlvbiBpcyBub3QgYSB2YWxpZCBudW1iZXIgLSBcIiArXG4gICAgICBcImdvdCBcIiArIChKU09OLnN0cmluZ2lmeSh2YWwpKSArIFwiLlwiLFxuICAgICAgdm5vZGUuY29udGV4dFxuICAgICk7XG4gIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkge1xuICAgIHdhcm4oXG4gICAgICBcIjx0cmFuc2l0aW9uPiBleHBsaWNpdCBcIiArIG5hbWUgKyBcIiBkdXJhdGlvbiBpcyBOYU4gLSBcIiArXG4gICAgICAndGhlIGR1cmF0aW9uIGV4cHJlc3Npb24gbWlnaHQgYmUgaW5jb3JyZWN0LicsXG4gICAgICB2bm9kZS5jb250ZXh0XG4gICAgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1ZhbGlkRHVyYXRpb24gKHZhbCkge1xuICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ251bWJlcicgJiYgIWlzTmFOKHZhbClcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgYSB0cmFuc2l0aW9uIGhvb2sncyBhcmd1bWVudCBsZW5ndGguIFRoZSBob29rIG1heSBiZTpcbiAqIC0gYSBtZXJnZWQgaG9vayAoaW52b2tlcikgd2l0aCB0aGUgb3JpZ2luYWwgaW4gLmZuc1xuICogLSBhIHdyYXBwZWQgY29tcG9uZW50IG1ldGhvZCAoY2hlY2sgLl9sZW5ndGgpXG4gKiAtIGEgcGxhaW4gZnVuY3Rpb24gKC5sZW5ndGgpXG4gKi9cbmZ1bmN0aW9uIGdldEhvb2tBcmd1bWVudHNMZW5ndGggKGZuKSB7XG4gIGlmIChpc1VuZGVmKGZuKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHZhciBpbnZva2VyRm5zID0gZm4uZm5zO1xuICBpZiAoaXNEZWYoaW52b2tlckZucykpIHtcbiAgICAvLyBpbnZva2VyXG4gICAgcmV0dXJuIGdldEhvb2tBcmd1bWVudHNMZW5ndGgoXG4gICAgICBBcnJheS5pc0FycmF5KGludm9rZXJGbnMpXG4gICAgICAgID8gaW52b2tlckZuc1swXVxuICAgICAgICA6IGludm9rZXJGbnNcbiAgICApXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChmbi5fbGVuZ3RoIHx8IGZuLmxlbmd0aCkgPiAxXG4gIH1cbn1cblxuZnVuY3Rpb24gX2VudGVyIChfLCB2bm9kZSkge1xuICBpZiAodm5vZGUuZGF0YS5zaG93ICE9PSB0cnVlKSB7XG4gICAgZW50ZXIodm5vZGUpO1xuICB9XG59XG5cbnZhciB0cmFuc2l0aW9uID0gaW5Ccm93c2VyID8ge1xuICBjcmVhdGU6IF9lbnRlcixcbiAgYWN0aXZhdGU6IF9lbnRlcixcbiAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUkJDEgKHZub2RlLCBybSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHZub2RlLmRhdGEuc2hvdyAhPT0gdHJ1ZSkge1xuICAgICAgbGVhdmUodm5vZGUsIHJtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm0oKTtcbiAgICB9XG4gIH1cbn0gOiB7fTtcblxudmFyIHBsYXRmb3JtTW9kdWxlcyA9IFtcbiAgYXR0cnMsXG4gIGtsYXNzLFxuICBldmVudHMsXG4gIGRvbVByb3BzLFxuICBzdHlsZSxcbiAgdHJhbnNpdGlvblxuXTtcblxuLyogICovXG5cbi8vIHRoZSBkaXJlY3RpdmUgbW9kdWxlIHNob3VsZCBiZSBhcHBsaWVkIGxhc3QsIGFmdGVyIGFsbFxuLy8gYnVpbHQtaW4gbW9kdWxlcyBoYXZlIGJlZW4gYXBwbGllZC5cbnZhciBtb2R1bGVzID0gcGxhdGZvcm1Nb2R1bGVzLmNvbmNhdChiYXNlTW9kdWxlcyk7XG5cbnZhciBwYXRjaCA9IGNyZWF0ZVBhdGNoRnVuY3Rpb24oeyBub2RlT3BzOiBub2RlT3BzLCBtb2R1bGVzOiBtb2R1bGVzIH0pO1xuXG4vKipcbiAqIE5vdCB0eXBlIGNoZWNraW5nIHRoaXMgZmlsZSBiZWNhdXNlIGZsb3cgZG9lc24ndCBsaWtlIGF0dGFjaGluZ1xuICogcHJvcGVydGllcyB0byBFbGVtZW50cy5cbiAqL1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbmlmIChpc0lFOSkge1xuICAvLyBodHRwOi8vd3d3Lm1hdHRzNDExLmNvbS9wb3N0L2ludGVybmV0LWV4cGxvcmVyLTktb25pbnB1dC9cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0aW9uY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBlbCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKGVsICYmIGVsLnZtb2RlbCkge1xuICAgICAgdHJpZ2dlcihlbCwgJ2lucHV0Jyk7XG4gICAgfVxuICB9KTtcbn1cblxudmFyIGRpcmVjdGl2ZSA9IHtcbiAgaW5zZXJ0ZWQ6IGZ1bmN0aW9uIGluc2VydGVkIChlbCwgYmluZGluZywgdm5vZGUsIG9sZFZub2RlKSB7XG4gICAgaWYgKHZub2RlLnRhZyA9PT0gJ3NlbGVjdCcpIHtcbiAgICAgIC8vICM2OTAzXG4gICAgICBpZiAob2xkVm5vZGUuZWxtICYmICFvbGRWbm9kZS5lbG0uX3ZPcHRpb25zKSB7XG4gICAgICAgIG1lcmdlVk5vZGVIb29rKHZub2RlLCAncG9zdHBhdGNoJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRpcmVjdGl2ZS5jb21wb25lbnRVcGRhdGVkKGVsLCBiaW5kaW5nLCB2bm9kZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLmNvbnRleHQpO1xuICAgICAgfVxuICAgICAgZWwuX3ZPcHRpb25zID0gW10ubWFwLmNhbGwoZWwub3B0aW9ucywgZ2V0VmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodm5vZGUudGFnID09PSAndGV4dGFyZWEnIHx8IGlzVGV4dElucHV0VHlwZShlbC50eXBlKSkge1xuICAgICAgZWwuX3ZNb2RpZmllcnMgPSBiaW5kaW5nLm1vZGlmaWVycztcbiAgICAgIGlmICghYmluZGluZy5tb2RpZmllcnMubGF6eSkge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbnN0YXJ0Jywgb25Db21wb3NpdGlvblN0YXJ0KTtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCBvbkNvbXBvc2l0aW9uRW5kKTtcbiAgICAgICAgLy8gU2FmYXJpIDwgMTAuMiAmIFVJV2ViVmlldyBkb2Vzbid0IGZpcmUgY29tcG9zaXRpb25lbmQgd2hlblxuICAgICAgICAvLyBzd2l0Y2hpbmcgZm9jdXMgYmVmb3JlIGNvbmZpcm1pbmcgY29tcG9zaXRpb24gY2hvaWNlXG4gICAgICAgIC8vIHRoaXMgYWxzbyBmaXhlcyB0aGUgaXNzdWUgd2hlcmUgc29tZSBicm93c2VycyBlLmcuIGlPUyBDaHJvbWVcbiAgICAgICAgLy8gZmlyZXMgXCJjaGFuZ2VcIiBpbnN0ZWFkIG9mIFwiaW5wdXRcIiBvbiBhdXRvY29tcGxldGUuXG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIG9uQ29tcG9zaXRpb25FbmQpO1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKGlzSUU5KSB7XG4gICAgICAgICAgZWwudm1vZGVsID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBjb21wb25lbnRVcGRhdGVkOiBmdW5jdGlvbiBjb21wb25lbnRVcGRhdGVkIChlbCwgYmluZGluZywgdm5vZGUpIHtcbiAgICBpZiAodm5vZGUudGFnID09PSAnc2VsZWN0Jykge1xuICAgICAgc2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLmNvbnRleHQpO1xuICAgICAgLy8gaW4gY2FzZSB0aGUgb3B0aW9ucyByZW5kZXJlZCBieSB2LWZvciBoYXZlIGNoYW5nZWQsXG4gICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHZhbHVlIGlzIG91dC1vZi1zeW5jIHdpdGggdGhlIHJlbmRlcmVkIG9wdGlvbnMuXG4gICAgICAvLyBkZXRlY3Qgc3VjaCBjYXNlcyBhbmQgZmlsdGVyIG91dCB2YWx1ZXMgdGhhdCBubyBsb25nZXIgaGFzIGEgbWF0Y2hpbmdcbiAgICAgIC8vIG9wdGlvbiBpbiB0aGUgRE9NLlxuICAgICAgdmFyIHByZXZPcHRpb25zID0gZWwuX3ZPcHRpb25zO1xuICAgICAgdmFyIGN1ck9wdGlvbnMgPSBlbC5fdk9wdGlvbnMgPSBbXS5tYXAuY2FsbChlbC5vcHRpb25zLCBnZXRWYWx1ZSk7XG4gICAgICBpZiAoY3VyT3B0aW9ucy5zb21lKGZ1bmN0aW9uIChvLCBpKSB7IHJldHVybiAhbG9vc2VFcXVhbChvLCBwcmV2T3B0aW9uc1tpXSk7IH0pKSB7XG4gICAgICAgIC8vIHRyaWdnZXIgY2hhbmdlIGV2ZW50IGlmXG4gICAgICAgIC8vIG5vIG1hdGNoaW5nIG9wdGlvbiBmb3VuZCBmb3IgYXQgbGVhc3Qgb25lIHZhbHVlXG4gICAgICAgIHZhciBuZWVkUmVzZXQgPSBlbC5tdWx0aXBsZVxuICAgICAgICAgID8gYmluZGluZy52YWx1ZS5zb21lKGZ1bmN0aW9uICh2KSB7IHJldHVybiBoYXNOb01hdGNoaW5nT3B0aW9uKHYsIGN1ck9wdGlvbnMpOyB9KVxuICAgICAgICAgIDogYmluZGluZy52YWx1ZSAhPT0gYmluZGluZy5vbGRWYWx1ZSAmJiBoYXNOb01hdGNoaW5nT3B0aW9uKGJpbmRpbmcudmFsdWUsIGN1ck9wdGlvbnMpO1xuICAgICAgICBpZiAobmVlZFJlc2V0KSB7XG4gICAgICAgICAgdHJpZ2dlcihlbCwgJ2NoYW5nZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzZXRTZWxlY3RlZCAoZWwsIGJpbmRpbmcsIHZtKSB7XG4gIGFjdHVhbGx5U2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZtKTtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChpc0lFIHx8IGlzRWRnZSkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgYWN0dWFsbHlTZXRTZWxlY3RlZChlbCwgYmluZGluZywgdm0pO1xuICAgIH0sIDApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFjdHVhbGx5U2V0U2VsZWN0ZWQgKGVsLCBiaW5kaW5nLCB2bSkge1xuICB2YXIgdmFsdWUgPSBiaW5kaW5nLnZhbHVlO1xuICB2YXIgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlO1xuICBpZiAoaXNNdWx0aXBsZSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB3YXJuKFxuICAgICAgXCI8c2VsZWN0IG11bHRpcGxlIHYtbW9kZWw9XFxcIlwiICsgKGJpbmRpbmcuZXhwcmVzc2lvbikgKyBcIlxcXCI+IFwiICtcbiAgICAgIFwiZXhwZWN0cyBhbiBBcnJheSB2YWx1ZSBmb3IgaXRzIGJpbmRpbmcsIGJ1dCBnb3QgXCIgKyAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKS5zbGljZSg4LCAtMSkpLFxuICAgICAgdm1cbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIHZhciBzZWxlY3RlZCwgb3B0aW9uO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IGVsLm9wdGlvbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgb3B0aW9uID0gZWwub3B0aW9uc1tpXTtcbiAgICBpZiAoaXNNdWx0aXBsZSkge1xuICAgICAgc2VsZWN0ZWQgPSBsb29zZUluZGV4T2YodmFsdWUsIGdldFZhbHVlKG9wdGlvbikpID4gLTE7XG4gICAgICBpZiAob3B0aW9uLnNlbGVjdGVkICE9PSBzZWxlY3RlZCkge1xuICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSBzZWxlY3RlZDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxvb3NlRXF1YWwoZ2V0VmFsdWUob3B0aW9uKSwgdmFsdWUpKSB7XG4gICAgICAgIGlmIChlbC5zZWxlY3RlZEluZGV4ICE9PSBpKSB7XG4gICAgICAgICAgZWwuc2VsZWN0ZWRJbmRleCA9IGk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmICghaXNNdWx0aXBsZSkge1xuICAgIGVsLnNlbGVjdGVkSW5kZXggPSAtMTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNOb01hdGNoaW5nT3B0aW9uICh2YWx1ZSwgb3B0aW9ucykge1xuICByZXR1cm4gb3B0aW9ucy5ldmVyeShmdW5jdGlvbiAobykgeyByZXR1cm4gIWxvb3NlRXF1YWwobywgdmFsdWUpOyB9KVxufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZSAob3B0aW9uKSB7XG4gIHJldHVybiAnX3ZhbHVlJyBpbiBvcHRpb25cbiAgICA/IG9wdGlvbi5fdmFsdWVcbiAgICA6IG9wdGlvbi52YWx1ZVxufVxuXG5mdW5jdGlvbiBvbkNvbXBvc2l0aW9uU3RhcnQgKGUpIHtcbiAgZS50YXJnZXQuY29tcG9zaW5nID0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gb25Db21wb3NpdGlvbkVuZCAoZSkge1xuICAvLyBwcmV2ZW50IHRyaWdnZXJpbmcgYW4gaW5wdXQgZXZlbnQgZm9yIG5vIHJlYXNvblxuICBpZiAoIWUudGFyZ2V0LmNvbXBvc2luZykgeyByZXR1cm4gfVxuICBlLnRhcmdldC5jb21wb3NpbmcgPSBmYWxzZTtcbiAgdHJpZ2dlcihlLnRhcmdldCwgJ2lucHV0Jyk7XG59XG5cbmZ1bmN0aW9uIHRyaWdnZXIgKGVsLCB0eXBlKSB7XG4gIHZhciBlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTtcbiAgZS5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIGVsLmRpc3BhdGNoRXZlbnQoZSk7XG59XG5cbi8qICAqL1xuXG4vLyByZWN1cnNpdmVseSBzZWFyY2ggZm9yIHBvc3NpYmxlIHRyYW5zaXRpb24gZGVmaW5lZCBpbnNpZGUgdGhlIGNvbXBvbmVudCByb290XG5mdW5jdGlvbiBsb2NhdGVOb2RlICh2bm9kZSkge1xuICByZXR1cm4gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgJiYgKCF2bm9kZS5kYXRhIHx8ICF2bm9kZS5kYXRhLnRyYW5zaXRpb24pXG4gICAgPyBsb2NhdGVOb2RlKHZub2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZSlcbiAgICA6IHZub2RlXG59XG5cbnZhciBzaG93ID0ge1xuICBiaW5kOiBmdW5jdGlvbiBiaW5kIChlbCwgcmVmLCB2bm9kZSkge1xuICAgIHZhciB2YWx1ZSA9IHJlZi52YWx1ZTtcblxuICAgIHZub2RlID0gbG9jYXRlTm9kZSh2bm9kZSk7XG4gICAgdmFyIHRyYW5zaXRpb24kJDEgPSB2bm9kZS5kYXRhICYmIHZub2RlLmRhdGEudHJhbnNpdGlvbjtcbiAgICB2YXIgb3JpZ2luYWxEaXNwbGF5ID0gZWwuX192T3JpZ2luYWxEaXNwbGF5ID1cbiAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPT09ICdub25lJyA/ICcnIDogZWwuc3R5bGUuZGlzcGxheTtcbiAgICBpZiAodmFsdWUgJiYgdHJhbnNpdGlvbiQkMSkge1xuICAgICAgdm5vZGUuZGF0YS5zaG93ID0gdHJ1ZTtcbiAgICAgIGVudGVyKHZub2RlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBvcmlnaW5hbERpc3BsYXk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IHZhbHVlID8gb3JpZ2luYWxEaXNwbGF5IDogJ25vbmUnO1xuICAgIH1cbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSAoZWwsIHJlZiwgdm5vZGUpIHtcbiAgICB2YXIgdmFsdWUgPSByZWYudmFsdWU7XG4gICAgdmFyIG9sZFZhbHVlID0gcmVmLm9sZFZhbHVlO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCF2YWx1ZSA9PT0gIW9sZFZhbHVlKSB7IHJldHVybiB9XG4gICAgdm5vZGUgPSBsb2NhdGVOb2RlKHZub2RlKTtcbiAgICB2YXIgdHJhbnNpdGlvbiQkMSA9IHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS50cmFuc2l0aW9uO1xuICAgIGlmICh0cmFuc2l0aW9uJCQxKSB7XG4gICAgICB2bm9kZS5kYXRhLnNob3cgPSB0cnVlO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGVudGVyKHZub2RlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fdk9yaWdpbmFsRGlzcGxheTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWF2ZSh2bm9kZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBlbC5fX3ZPcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7XG4gICAgfVxuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kIChcbiAgICBlbCxcbiAgICBiaW5kaW5nLFxuICAgIHZub2RlLFxuICAgIG9sZFZub2RlLFxuICAgIGlzRGVzdHJveVxuICApIHtcbiAgICBpZiAoIWlzRGVzdHJveSkge1xuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fdk9yaWdpbmFsRGlzcGxheTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBwbGF0Zm9ybURpcmVjdGl2ZXMgPSB7XG4gIG1vZGVsOiBkaXJlY3RpdmUsXG4gIHNob3c6IHNob3dcbn07XG5cbi8qICAqL1xuXG52YXIgdHJhbnNpdGlvblByb3BzID0ge1xuICBuYW1lOiBTdHJpbmcsXG4gIGFwcGVhcjogQm9vbGVhbixcbiAgY3NzOiBCb29sZWFuLFxuICBtb2RlOiBTdHJpbmcsXG4gIHR5cGU6IFN0cmluZyxcbiAgZW50ZXJDbGFzczogU3RyaW5nLFxuICBsZWF2ZUNsYXNzOiBTdHJpbmcsXG4gIGVudGVyVG9DbGFzczogU3RyaW5nLFxuICBsZWF2ZVRvQ2xhc3M6IFN0cmluZyxcbiAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLFxuICBsZWF2ZUFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhclRvQ2xhc3M6IFN0cmluZyxcbiAgZHVyYXRpb246IFtOdW1iZXIsIFN0cmluZywgT2JqZWN0XVxufTtcblxuLy8gaW4gY2FzZSB0aGUgY2hpbGQgaXMgYWxzbyBhbiBhYnN0cmFjdCBjb21wb25lbnQsIGUuZy4gPGtlZXAtYWxpdmU+XG4vLyB3ZSB3YW50IHRvIHJlY3Vyc2l2ZWx5IHJldHJpZXZlIHRoZSByZWFsIGNvbXBvbmVudCB0byBiZSByZW5kZXJlZFxuZnVuY3Rpb24gZ2V0UmVhbENoaWxkICh2bm9kZSkge1xuICB2YXIgY29tcE9wdGlvbnMgPSB2bm9kZSAmJiB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICBpZiAoY29tcE9wdGlvbnMgJiYgY29tcE9wdGlvbnMuQ3Rvci5vcHRpb25zLmFic3RyYWN0KSB7XG4gICAgcmV0dXJuIGdldFJlYWxDaGlsZChnZXRGaXJzdENvbXBvbmVudENoaWxkKGNvbXBPcHRpb25zLmNoaWxkcmVuKSlcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdm5vZGVcbiAgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0VHJhbnNpdGlvbkRhdGEgKGNvbXApIHtcbiAgdmFyIGRhdGEgPSB7fTtcbiAgdmFyIG9wdGlvbnMgPSBjb21wLiRvcHRpb25zO1xuICAvLyBwcm9wc1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucy5wcm9wc0RhdGEpIHtcbiAgICBkYXRhW2tleV0gPSBjb21wW2tleV07XG4gIH1cbiAgLy8gZXZlbnRzLlxuICAvLyBleHRyYWN0IGxpc3RlbmVycyBhbmQgcGFzcyB0aGVtIGRpcmVjdGx5IHRvIHRoZSB0cmFuc2l0aW9uIG1ldGhvZHNcbiAgdmFyIGxpc3RlbmVycyA9IG9wdGlvbnMuX3BhcmVudExpc3RlbmVycztcbiAgZm9yICh2YXIga2V5JDEgaW4gbGlzdGVuZXJzKSB7XG4gICAgZGF0YVtjYW1lbGl6ZShrZXkkMSldID0gbGlzdGVuZXJzW2tleSQxXTtcbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG5mdW5jdGlvbiBwbGFjZWhvbGRlciAoaCwgcmF3Q2hpbGQpIHtcbiAgaWYgKC9cXGQta2VlcC1hbGl2ZSQvLnRlc3QocmF3Q2hpbGQudGFnKSkge1xuICAgIHJldHVybiBoKCdrZWVwLWFsaXZlJywge1xuICAgICAgcHJvcHM6IHJhd0NoaWxkLmNvbXBvbmVudE9wdGlvbnMucHJvcHNEYXRhXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNQYXJlbnRUcmFuc2l0aW9uICh2bm9kZSkge1xuICB3aGlsZSAoKHZub2RlID0gdm5vZGUucGFyZW50KSkge1xuICAgIGlmICh2bm9kZS5kYXRhLnRyYW5zaXRpb24pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzU2FtZUNoaWxkIChjaGlsZCwgb2xkQ2hpbGQpIHtcbiAgcmV0dXJuIG9sZENoaWxkLmtleSA9PT0gY2hpbGQua2V5ICYmIG9sZENoaWxkLnRhZyA9PT0gY2hpbGQudGFnXG59XG5cbnZhciBpc05vdFRleHROb2RlID0gZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMudGFnIHx8IGlzQXN5bmNQbGFjZWhvbGRlcihjKTsgfTtcblxudmFyIGlzVlNob3dEaXJlY3RpdmUgPSBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC5uYW1lID09PSAnc2hvdyc7IH07XG5cbnZhciBUcmFuc2l0aW9uID0ge1xuICBuYW1lOiAndHJhbnNpdGlvbicsXG4gIHByb3BzOiB0cmFuc2l0aW9uUHJvcHMsXG4gIGFic3RyYWN0OiB0cnVlLFxuXG4gIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyIChoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLiRzbG90cy5kZWZhdWx0O1xuICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgdGV4dCBub2RlcyAocG9zc2libGUgd2hpdGVzcGFjZXMpXG4gICAgY2hpbGRyZW4gPSBjaGlsZHJlbi5maWx0ZXIoaXNOb3RUZXh0Tm9kZSk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIHdhcm4gbXVsdGlwbGUgZWxlbWVudHNcbiAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMSkge1xuICAgICAgd2FybihcbiAgICAgICAgJzx0cmFuc2l0aW9uPiBjYW4gb25seSBiZSB1c2VkIG9uIGEgc2luZ2xlIGVsZW1lbnQuIFVzZSAnICtcbiAgICAgICAgJzx0cmFuc2l0aW9uLWdyb3VwPiBmb3IgbGlzdHMuJyxcbiAgICAgICAgdGhpcy4kcGFyZW50XG4gICAgICApO1xuICAgIH1cblxuICAgIHZhciBtb2RlID0gdGhpcy5tb2RlO1xuXG4gICAgLy8gd2FybiBpbnZhbGlkIG1vZGVcbiAgICBpZiAobW9kZSAmJiBtb2RlICE9PSAnaW4tb3V0JyAmJiBtb2RlICE9PSAnb3V0LWluJ1xuICAgICkge1xuICAgICAgd2FybihcbiAgICAgICAgJ2ludmFsaWQgPHRyYW5zaXRpb24+IG1vZGU6ICcgKyBtb2RlLFxuICAgICAgICB0aGlzLiRwYXJlbnRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIHJhd0NoaWxkID0gY2hpbGRyZW5bMF07XG5cbiAgICAvLyBpZiB0aGlzIGlzIGEgY29tcG9uZW50IHJvb3Qgbm9kZSBhbmQgdGhlIGNvbXBvbmVudCdzXG4gICAgLy8gcGFyZW50IGNvbnRhaW5lciBub2RlIGFsc28gaGFzIHRyYW5zaXRpb24sIHNraXAuXG4gICAgaWYgKGhhc1BhcmVudFRyYW5zaXRpb24odGhpcy4kdm5vZGUpKSB7XG4gICAgICByZXR1cm4gcmF3Q2hpbGRcbiAgICB9XG5cbiAgICAvLyBhcHBseSB0cmFuc2l0aW9uIGRhdGEgdG8gY2hpbGRcbiAgICAvLyB1c2UgZ2V0UmVhbENoaWxkKCkgdG8gaWdub3JlIGFic3RyYWN0IGNvbXBvbmVudHMgZS5nLiBrZWVwLWFsaXZlXG4gICAgdmFyIGNoaWxkID0gZ2V0UmVhbENoaWxkKHJhd0NoaWxkKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIWNoaWxkKSB7XG4gICAgICByZXR1cm4gcmF3Q2hpbGRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbGVhdmluZykge1xuICAgICAgcmV0dXJuIHBsYWNlaG9sZGVyKGgsIHJhd0NoaWxkKVxuICAgIH1cblxuICAgIC8vIGVuc3VyZSBhIGtleSB0aGF0IGlzIHVuaXF1ZSB0byB0aGUgdm5vZGUgdHlwZSBhbmQgdG8gdGhpcyB0cmFuc2l0aW9uXG4gICAgLy8gY29tcG9uZW50IGluc3RhbmNlLiBUaGlzIGtleSB3aWxsIGJlIHVzZWQgdG8gcmVtb3ZlIHBlbmRpbmcgbGVhdmluZyBub2Rlc1xuICAgIC8vIGR1cmluZyBlbnRlcmluZy5cbiAgICB2YXIgaWQgPSBcIl9fdHJhbnNpdGlvbi1cIiArICh0aGlzLl91aWQpICsgXCItXCI7XG4gICAgY2hpbGQua2V5ID0gY2hpbGQua2V5ID09IG51bGxcbiAgICAgID8gY2hpbGQuaXNDb21tZW50XG4gICAgICAgID8gaWQgKyAnY29tbWVudCdcbiAgICAgICAgOiBpZCArIGNoaWxkLnRhZ1xuICAgICAgOiBpc1ByaW1pdGl2ZShjaGlsZC5rZXkpXG4gICAgICAgID8gKFN0cmluZyhjaGlsZC5rZXkpLmluZGV4T2YoaWQpID09PSAwID8gY2hpbGQua2V5IDogaWQgKyBjaGlsZC5rZXkpXG4gICAgICAgIDogY2hpbGQua2V5O1xuXG4gICAgdmFyIGRhdGEgPSAoY2hpbGQuZGF0YSB8fCAoY2hpbGQuZGF0YSA9IHt9KSkudHJhbnNpdGlvbiA9IGV4dHJhY3RUcmFuc2l0aW9uRGF0YSh0aGlzKTtcbiAgICB2YXIgb2xkUmF3Q2hpbGQgPSB0aGlzLl92bm9kZTtcbiAgICB2YXIgb2xkQ2hpbGQgPSBnZXRSZWFsQ2hpbGQob2xkUmF3Q2hpbGQpO1xuXG4gICAgLy8gbWFyayB2LXNob3dcbiAgICAvLyBzbyB0aGF0IHRoZSB0cmFuc2l0aW9uIG1vZHVsZSBjYW4gaGFuZCBvdmVyIHRoZSBjb250cm9sIHRvIHRoZSBkaXJlY3RpdmVcbiAgICBpZiAoY2hpbGQuZGF0YS5kaXJlY3RpdmVzICYmIGNoaWxkLmRhdGEuZGlyZWN0aXZlcy5zb21lKGlzVlNob3dEaXJlY3RpdmUpKSB7XG4gICAgICBjaGlsZC5kYXRhLnNob3cgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIG9sZENoaWxkICYmXG4gICAgICBvbGRDaGlsZC5kYXRhICYmXG4gICAgICAhaXNTYW1lQ2hpbGQoY2hpbGQsIG9sZENoaWxkKSAmJlxuICAgICAgIWlzQXN5bmNQbGFjZWhvbGRlcihvbGRDaGlsZCkgJiZcbiAgICAgIC8vICM2Njg3IGNvbXBvbmVudCByb290IGlzIGEgY29tbWVudCBub2RlXG4gICAgICAhKG9sZENoaWxkLmNvbXBvbmVudEluc3RhbmNlICYmIG9sZENoaWxkLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZS5pc0NvbW1lbnQpXG4gICAgKSB7XG4gICAgICAvLyByZXBsYWNlIG9sZCBjaGlsZCB0cmFuc2l0aW9uIGRhdGEgd2l0aCBmcmVzaCBvbmVcbiAgICAgIC8vIGltcG9ydGFudCBmb3IgZHluYW1pYyB0cmFuc2l0aW9ucyFcbiAgICAgIHZhciBvbGREYXRhID0gb2xkQ2hpbGQuZGF0YS50cmFuc2l0aW9uID0gZXh0ZW5kKHt9LCBkYXRhKTtcbiAgICAgIC8vIGhhbmRsZSB0cmFuc2l0aW9uIG1vZGVcbiAgICAgIGlmIChtb2RlID09PSAnb3V0LWluJykge1xuICAgICAgICAvLyByZXR1cm4gcGxhY2Vob2xkZXIgbm9kZSBhbmQgcXVldWUgdXBkYXRlIHdoZW4gbGVhdmUgZmluaXNoZXNcbiAgICAgICAgdGhpcy5fbGVhdmluZyA9IHRydWU7XG4gICAgICAgIG1lcmdlVk5vZGVIb29rKG9sZERhdGEsICdhZnRlckxlYXZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMkMS5fbGVhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMkMS4kZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwbGFjZWhvbGRlcihoLCByYXdDaGlsZClcbiAgICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2luLW91dCcpIHtcbiAgICAgICAgaWYgKGlzQXN5bmNQbGFjZWhvbGRlcihjaGlsZCkpIHtcbiAgICAgICAgICByZXR1cm4gb2xkUmF3Q2hpbGRcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVsYXllZExlYXZlO1xuICAgICAgICB2YXIgcGVyZm9ybUxlYXZlID0gZnVuY3Rpb24gKCkgeyBkZWxheWVkTGVhdmUoKTsgfTtcbiAgICAgICAgbWVyZ2VWTm9kZUhvb2soZGF0YSwgJ2FmdGVyRW50ZXInLCBwZXJmb3JtTGVhdmUpO1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhkYXRhLCAnZW50ZXJDYW5jZWxsZWQnLCBwZXJmb3JtTGVhdmUpO1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhvbGREYXRhLCAnZGVsYXlMZWF2ZScsIGZ1bmN0aW9uIChsZWF2ZSkgeyBkZWxheWVkTGVhdmUgPSBsZWF2ZTsgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhd0NoaWxkXG4gIH1cbn07XG5cbi8qICAqL1xuXG52YXIgcHJvcHMgPSBleHRlbmQoe1xuICB0YWc6IFN0cmluZyxcbiAgbW92ZUNsYXNzOiBTdHJpbmdcbn0sIHRyYW5zaXRpb25Qcm9wcyk7XG5cbmRlbGV0ZSBwcm9wcy5tb2RlO1xuXG52YXIgVHJhbnNpdGlvbkdyb3VwID0ge1xuICBwcm9wczogcHJvcHMsXG5cbiAgYmVmb3JlTW91bnQ6IGZ1bmN0aW9uIGJlZm9yZU1vdW50ICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHZhciB1cGRhdGUgPSB0aGlzLl91cGRhdGU7XG4gICAgdGhpcy5fdXBkYXRlID0gZnVuY3Rpb24gKHZub2RlLCBoeWRyYXRpbmcpIHtcbiAgICAgIHZhciByZXN0b3JlQWN0aXZlSW5zdGFuY2UgPSBzZXRBY3RpdmVJbnN0YW5jZSh0aGlzJDEpO1xuICAgICAgLy8gZm9yY2UgcmVtb3ZpbmcgcGFzc1xuICAgICAgdGhpcyQxLl9fcGF0Y2hfXyhcbiAgICAgICAgdGhpcyQxLl92bm9kZSxcbiAgICAgICAgdGhpcyQxLmtlcHQsXG4gICAgICAgIGZhbHNlLCAvLyBoeWRyYXRpbmdcbiAgICAgICAgdHJ1ZSAvLyByZW1vdmVPbmx5ICghaW1wb3J0YW50LCBhdm9pZHMgdW5uZWNlc3NhcnkgbW92ZXMpXG4gICAgICApO1xuICAgICAgdGhpcyQxLl92bm9kZSA9IHRoaXMkMS5rZXB0O1xuICAgICAgcmVzdG9yZUFjdGl2ZUluc3RhbmNlKCk7XG4gICAgICB1cGRhdGUuY2FsbCh0aGlzJDEsIHZub2RlLCBoeWRyYXRpbmcpO1xuICAgIH07XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIgKGgpIHtcbiAgICB2YXIgdGFnID0gdGhpcy50YWcgfHwgdGhpcy4kdm5vZGUuZGF0YS50YWcgfHwgJ3NwYW4nO1xuICAgIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBwcmV2Q2hpbGRyZW4gPSB0aGlzLnByZXZDaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG4gICAgdmFyIHJhd0NoaWxkcmVuID0gdGhpcy4kc2xvdHMuZGVmYXVsdCB8fCBbXTtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuID0gW107XG4gICAgdmFyIHRyYW5zaXRpb25EYXRhID0gZXh0cmFjdFRyYW5zaXRpb25EYXRhKHRoaXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYXdDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGMgPSByYXdDaGlsZHJlbltpXTtcbiAgICAgIGlmIChjLnRhZykge1xuICAgICAgICBpZiAoYy5rZXkgIT0gbnVsbCAmJiBTdHJpbmcoYy5rZXkpLmluZGV4T2YoJ19fdmxpc3QnKSAhPT0gMCkge1xuICAgICAgICAgIGNoaWxkcmVuLnB1c2goYyk7XG4gICAgICAgICAgbWFwW2Mua2V5XSA9IGNcbiAgICAgICAgICA7KGMuZGF0YSB8fCAoYy5kYXRhID0ge30pKS50cmFuc2l0aW9uID0gdHJhbnNpdGlvbkRhdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIG9wdHMgPSBjLmNvbXBvbmVudE9wdGlvbnM7XG4gICAgICAgICAgdmFyIG5hbWUgPSBvcHRzID8gKG9wdHMuQ3Rvci5vcHRpb25zLm5hbWUgfHwgb3B0cy50YWcgfHwgJycpIDogYy50YWc7XG4gICAgICAgICAgd2FybigoXCI8dHJhbnNpdGlvbi1ncm91cD4gY2hpbGRyZW4gbXVzdCBiZSBrZXllZDogPFwiICsgbmFtZSArIFwiPlwiKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJldkNoaWxkcmVuKSB7XG4gICAgICB2YXIga2VwdCA9IFtdO1xuICAgICAgdmFyIHJlbW92ZWQgPSBbXTtcbiAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IHByZXZDaGlsZHJlbi5sZW5ndGg7IGkkMSsrKSB7XG4gICAgICAgIHZhciBjJDEgPSBwcmV2Q2hpbGRyZW5baSQxXTtcbiAgICAgICAgYyQxLmRhdGEudHJhbnNpdGlvbiA9IHRyYW5zaXRpb25EYXRhO1xuICAgICAgICBjJDEuZGF0YS5wb3MgPSBjJDEuZWxtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBpZiAobWFwW2MkMS5rZXldKSB7XG4gICAgICAgICAga2VwdC5wdXNoKGMkMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVtb3ZlZC5wdXNoKGMkMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMua2VwdCA9IGgodGFnLCBudWxsLCBrZXB0KTtcbiAgICAgIHRoaXMucmVtb3ZlZCA9IHJlbW92ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGgodGFnLCBudWxsLCBjaGlsZHJlbilcbiAgfSxcblxuICB1cGRhdGVkOiBmdW5jdGlvbiB1cGRhdGVkICgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByZXZDaGlsZHJlbjtcbiAgICB2YXIgbW92ZUNsYXNzID0gdGhpcy5tb3ZlQ2xhc3MgfHwgKCh0aGlzLm5hbWUgfHwgJ3YnKSArICctbW92ZScpO1xuICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoIHx8ICF0aGlzLmhhc01vdmUoY2hpbGRyZW5bMF0uZWxtLCBtb3ZlQ2xhc3MpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyB3ZSBkaXZpZGUgdGhlIHdvcmsgaW50byB0aHJlZSBsb29wcyB0byBhdm9pZCBtaXhpbmcgRE9NIHJlYWRzIGFuZCB3cml0ZXNcbiAgICAvLyBpbiBlYWNoIGl0ZXJhdGlvbiAtIHdoaWNoIGhlbHBzIHByZXZlbnQgbGF5b3V0IHRocmFzaGluZy5cbiAgICBjaGlsZHJlbi5mb3JFYWNoKGNhbGxQZW5kaW5nQ2JzKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKHJlY29yZFBvc2l0aW9uKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGFwcGx5VHJhbnNsYXRpb24pO1xuXG4gICAgLy8gZm9yY2UgcmVmbG93IHRvIHB1dCBldmVyeXRoaW5nIGluIHBvc2l0aW9uXG4gICAgLy8gYXNzaWduIHRvIHRoaXMgdG8gYXZvaWQgYmVpbmcgcmVtb3ZlZCBpbiB0cmVlLXNoYWtpbmdcbiAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgICB0aGlzLl9yZWZsb3cgPSBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDtcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIGlmIChjLmRhdGEubW92ZWQpIHtcbiAgICAgICAgdmFyIGVsID0gYy5lbG07XG4gICAgICAgIHZhciBzID0gZWwuc3R5bGU7XG4gICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbW92ZUNsYXNzKTtcbiAgICAgICAgcy50cmFuc2Zvcm0gPSBzLldlYmtpdFRyYW5zZm9ybSA9IHMudHJhbnNpdGlvbkR1cmF0aW9uID0gJyc7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZEV2ZW50LCBlbC5fbW92ZUNiID0gZnVuY3Rpb24gY2IgKGUpIHtcbiAgICAgICAgICBpZiAoZSAmJiBlLnRhcmdldCAhPT0gZWwpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWUgfHwgL3RyYW5zZm9ybSQvLnRlc3QoZS5wcm9wZXJ0eU5hbWUpKSB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHRyYW5zaXRpb25FbmRFdmVudCwgY2IpO1xuICAgICAgICAgICAgZWwuX21vdmVDYiA9IG51bGw7XG4gICAgICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIG1vdmVDbGFzcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICBtZXRob2RzOiB7XG4gICAgaGFzTW92ZTogZnVuY3Rpb24gaGFzTW92ZSAoZWwsIG1vdmVDbGFzcykge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoIWhhc1RyYW5zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICh0aGlzLl9oYXNNb3ZlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYXNNb3ZlXG4gICAgICB9XG4gICAgICAvLyBEZXRlY3Qgd2hldGhlciBhbiBlbGVtZW50IHdpdGggdGhlIG1vdmUgY2xhc3MgYXBwbGllZCBoYXNcbiAgICAgIC8vIENTUyB0cmFuc2l0aW9ucy4gU2luY2UgdGhlIGVsZW1lbnQgbWF5IGJlIGluc2lkZSBhbiBlbnRlcmluZ1xuICAgICAgLy8gdHJhbnNpdGlvbiBhdCB0aGlzIHZlcnkgbW9tZW50LCB3ZSBtYWtlIGEgY2xvbmUgb2YgaXQgYW5kIHJlbW92ZVxuICAgICAgLy8gYWxsIG90aGVyIHRyYW5zaXRpb24gY2xhc3NlcyBhcHBsaWVkIHRvIGVuc3VyZSBvbmx5IHRoZSBtb3ZlIGNsYXNzXG4gICAgICAvLyBpcyBhcHBsaWVkLlxuICAgICAgdmFyIGNsb25lID0gZWwuY2xvbmVOb2RlKCk7XG4gICAgICBpZiAoZWwuX3RyYW5zaXRpb25DbGFzc2VzKSB7XG4gICAgICAgIGVsLl90cmFuc2l0aW9uQ2xhc3Nlcy5mb3JFYWNoKGZ1bmN0aW9uIChjbHMpIHsgcmVtb3ZlQ2xhc3MoY2xvbmUsIGNscyk7IH0pO1xuICAgICAgfVxuICAgICAgYWRkQ2xhc3MoY2xvbmUsIG1vdmVDbGFzcyk7XG4gICAgICBjbG9uZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgdGhpcy4kZWwuYXBwZW5kQ2hpbGQoY2xvbmUpO1xuICAgICAgdmFyIGluZm8gPSBnZXRUcmFuc2l0aW9uSW5mbyhjbG9uZSk7XG4gICAgICB0aGlzLiRlbC5yZW1vdmVDaGlsZChjbG9uZSk7XG4gICAgICByZXR1cm4gKHRoaXMuX2hhc01vdmUgPSBpbmZvLmhhc1RyYW5zZm9ybSlcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNhbGxQZW5kaW5nQ2JzIChjKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoYy5lbG0uX21vdmVDYikge1xuICAgIGMuZWxtLl9tb3ZlQ2IoKTtcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGMuZWxtLl9lbnRlckNiKSB7XG4gICAgYy5lbG0uX2VudGVyQ2IoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvcmRQb3NpdGlvbiAoYykge1xuICBjLmRhdGEubmV3UG9zID0gYy5lbG0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG59XG5cbmZ1bmN0aW9uIGFwcGx5VHJhbnNsYXRpb24gKGMpIHtcbiAgdmFyIG9sZFBvcyA9IGMuZGF0YS5wb3M7XG4gIHZhciBuZXdQb3MgPSBjLmRhdGEubmV3UG9zO1xuICB2YXIgZHggPSBvbGRQb3MubGVmdCAtIG5ld1Bvcy5sZWZ0O1xuICB2YXIgZHkgPSBvbGRQb3MudG9wIC0gbmV3UG9zLnRvcDtcbiAgaWYgKGR4IHx8IGR5KSB7XG4gICAgYy5kYXRhLm1vdmVkID0gdHJ1ZTtcbiAgICB2YXIgcyA9IGMuZWxtLnN0eWxlO1xuICAgIHMudHJhbnNmb3JtID0gcy5XZWJraXRUcmFuc2Zvcm0gPSBcInRyYW5zbGF0ZShcIiArIGR4ICsgXCJweCxcIiArIGR5ICsgXCJweClcIjtcbiAgICBzLnRyYW5zaXRpb25EdXJhdGlvbiA9ICcwcyc7XG4gIH1cbn1cblxudmFyIHBsYXRmb3JtQ29tcG9uZW50cyA9IHtcbiAgVHJhbnNpdGlvbjogVHJhbnNpdGlvbixcbiAgVHJhbnNpdGlvbkdyb3VwOiBUcmFuc2l0aW9uR3JvdXBcbn07XG5cbi8qICAqL1xuXG4vLyBpbnN0YWxsIHBsYXRmb3JtIHNwZWNpZmljIHV0aWxzXG5WdWUuY29uZmlnLm11c3RVc2VQcm9wID0gbXVzdFVzZVByb3A7XG5WdWUuY29uZmlnLmlzUmVzZXJ2ZWRUYWcgPSBpc1Jlc2VydmVkVGFnO1xuVnVlLmNvbmZpZy5pc1Jlc2VydmVkQXR0ciA9IGlzUmVzZXJ2ZWRBdHRyO1xuVnVlLmNvbmZpZy5nZXRUYWdOYW1lc3BhY2UgPSBnZXRUYWdOYW1lc3BhY2U7XG5WdWUuY29uZmlnLmlzVW5rbm93bkVsZW1lbnQgPSBpc1Vua25vd25FbGVtZW50O1xuXG4vLyBpbnN0YWxsIHBsYXRmb3JtIHJ1bnRpbWUgZGlyZWN0aXZlcyAmIGNvbXBvbmVudHNcbmV4dGVuZChWdWUub3B0aW9ucy5kaXJlY3RpdmVzLCBwbGF0Zm9ybURpcmVjdGl2ZXMpO1xuZXh0ZW5kKFZ1ZS5vcHRpb25zLmNvbXBvbmVudHMsIHBsYXRmb3JtQ29tcG9uZW50cyk7XG5cbi8vIGluc3RhbGwgcGxhdGZvcm0gcGF0Y2ggZnVuY3Rpb25cblZ1ZS5wcm90b3R5cGUuX19wYXRjaF9fID0gaW5Ccm93c2VyID8gcGF0Y2ggOiBub29wO1xuXG4vLyBwdWJsaWMgbW91bnQgbWV0aG9kXG5WdWUucHJvdG90eXBlLiRtb3VudCA9IGZ1bmN0aW9uIChcbiAgZWwsXG4gIGh5ZHJhdGluZ1xuKSB7XG4gIGVsID0gZWwgJiYgaW5Ccm93c2VyID8gcXVlcnkoZWwpIDogdW5kZWZpbmVkO1xuICByZXR1cm4gbW91bnRDb21wb25lbnQodGhpcywgZWwsIGh5ZHJhdGluZylcbn07XG5cbi8vIGRldnRvb2xzIGdsb2JhbCBob29rXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuaWYgKGluQnJvd3Nlcikge1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoY29uZmlnLmRldnRvb2xzKSB7XG4gICAgICBpZiAoZGV2dG9vbHMpIHtcbiAgICAgICAgZGV2dG9vbHMuZW1pdCgnaW5pdCcsIFZ1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlW2NvbnNvbGUuaW5mbyA/ICdpbmZvJyA6ICdsb2cnXShcbiAgICAgICAgICAnRG93bmxvYWQgdGhlIFZ1ZSBEZXZ0b29scyBleHRlbnNpb24gZm9yIGEgYmV0dGVyIGRldmVsb3BtZW50IGV4cGVyaWVuY2U6XFxuJyArXG4gICAgICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtZGV2dG9vbHMnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjb25maWcucHJvZHVjdGlvblRpcCAhPT0gZmFsc2UgJiZcbiAgICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJ1xuICAgICkge1xuICAgICAgY29uc29sZVtjb25zb2xlLmluZm8gPyAnaW5mbycgOiAnbG9nJ10oXG4gICAgICAgIFwiWW91IGFyZSBydW5uaW5nIFZ1ZSBpbiBkZXZlbG9wbWVudCBtb2RlLlxcblwiICtcbiAgICAgICAgXCJNYWtlIHN1cmUgdG8gdHVybiBvbiBwcm9kdWN0aW9uIG1vZGUgd2hlbiBkZXBsb3lpbmcgZm9yIHByb2R1Y3Rpb24uXFxuXCIgK1xuICAgICAgICBcIlNlZSBtb3JlIHRpcHMgYXQgaHR0cHM6Ly92dWVqcy5vcmcvZ3VpZGUvZGVwbG95bWVudC5odG1sXCJcbiAgICAgICk7XG4gICAgfVxuICB9LCAwKTtcbn1cblxuLyogICovXG5cbnZhciBkZWZhdWx0VGFnUkUgPSAvXFx7XFx7KCg/Oi58XFxyP1xcbikrPylcXH1cXH0vZztcbnZhciByZWdleEVzY2FwZVJFID0gL1stLiorP14ke30oKXxbXFxdXFwvXFxcXF0vZztcblxudmFyIGJ1aWxkUmVnZXggPSBjYWNoZWQoZnVuY3Rpb24gKGRlbGltaXRlcnMpIHtcbiAgdmFyIG9wZW4gPSBkZWxpbWl0ZXJzWzBdLnJlcGxhY2UocmVnZXhFc2NhcGVSRSwgJ1xcXFwkJicpO1xuICB2YXIgY2xvc2UgPSBkZWxpbWl0ZXJzWzFdLnJlcGxhY2UocmVnZXhFc2NhcGVSRSwgJ1xcXFwkJicpO1xuICByZXR1cm4gbmV3IFJlZ0V4cChvcGVuICsgJygoPzoufFxcXFxuKSs/KScgKyBjbG9zZSwgJ2cnKVxufSk7XG5cblxuXG5mdW5jdGlvbiBwYXJzZVRleHQgKFxuICB0ZXh0LFxuICBkZWxpbWl0ZXJzXG4pIHtcbiAgdmFyIHRhZ1JFID0gZGVsaW1pdGVycyA/IGJ1aWxkUmVnZXgoZGVsaW1pdGVycykgOiBkZWZhdWx0VGFnUkU7XG4gIGlmICghdGFnUkUudGVzdCh0ZXh0KSkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciB0b2tlbnMgPSBbXTtcbiAgdmFyIHJhd1Rva2VucyA9IFtdO1xuICB2YXIgbGFzdEluZGV4ID0gdGFnUkUubGFzdEluZGV4ID0gMDtcbiAgdmFyIG1hdGNoLCBpbmRleCwgdG9rZW5WYWx1ZTtcbiAgd2hpbGUgKChtYXRjaCA9IHRhZ1JFLmV4ZWModGV4dCkpKSB7XG4gICAgaW5kZXggPSBtYXRjaC5pbmRleDtcbiAgICAvLyBwdXNoIHRleHQgdG9rZW5cbiAgICBpZiAoaW5kZXggPiBsYXN0SW5kZXgpIHtcbiAgICAgIHJhd1Rva2Vucy5wdXNoKHRva2VuVmFsdWUgPSB0ZXh0LnNsaWNlKGxhc3RJbmRleCwgaW5kZXgpKTtcbiAgICAgIHRva2Vucy5wdXNoKEpTT04uc3RyaW5naWZ5KHRva2VuVmFsdWUpKTtcbiAgICB9XG4gICAgLy8gdGFnIHRva2VuXG4gICAgdmFyIGV4cCA9IHBhcnNlRmlsdGVycyhtYXRjaFsxXS50cmltKCkpO1xuICAgIHRva2Vucy5wdXNoKChcIl9zKFwiICsgZXhwICsgXCIpXCIpKTtcbiAgICByYXdUb2tlbnMucHVzaCh7ICdAYmluZGluZyc6IGV4cCB9KTtcbiAgICBsYXN0SW5kZXggPSBpbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgfVxuICBpZiAobGFzdEluZGV4IDwgdGV4dC5sZW5ndGgpIHtcbiAgICByYXdUb2tlbnMucHVzaCh0b2tlblZhbHVlID0gdGV4dC5zbGljZShsYXN0SW5kZXgpKTtcbiAgICB0b2tlbnMucHVzaChKU09OLnN0cmluZ2lmeSh0b2tlblZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBleHByZXNzaW9uOiB0b2tlbnMuam9pbignKycpLFxuICAgIHRva2VuczogcmF3VG9rZW5zXG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIHRyYW5zZm9ybU5vZGUgKGVsLCBvcHRpb25zKSB7XG4gIHZhciB3YXJuID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuO1xuICB2YXIgc3RhdGljQ2xhc3MgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAnY2xhc3MnKTtcbiAgaWYgKHN0YXRpY0NsYXNzKSB7XG4gICAgdmFyIHJlcyA9IHBhcnNlVGV4dChzdGF0aWNDbGFzcywgb3B0aW9ucy5kZWxpbWl0ZXJzKTtcbiAgICBpZiAocmVzKSB7XG4gICAgICB3YXJuKFxuICAgICAgICBcImNsYXNzPVxcXCJcIiArIHN0YXRpY0NsYXNzICsgXCJcXFwiOiBcIiArXG4gICAgICAgICdJbnRlcnBvbGF0aW9uIGluc2lkZSBhdHRyaWJ1dGVzIGhhcyBiZWVuIHJlbW92ZWQuICcgK1xuICAgICAgICAnVXNlIHYtYmluZCBvciB0aGUgY29sb24gc2hvcnRoYW5kIGluc3RlYWQuIEZvciBleGFtcGxlLCAnICtcbiAgICAgICAgJ2luc3RlYWQgb2YgPGRpdiBjbGFzcz1cInt7IHZhbCB9fVwiPiwgdXNlIDxkaXYgOmNsYXNzPVwidmFsXCI+LicsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwWydjbGFzcyddXG4gICAgICApO1xuICAgIH1cbiAgfVxuICBpZiAoc3RhdGljQ2xhc3MpIHtcbiAgICBlbC5zdGF0aWNDbGFzcyA9IEpTT04uc3RyaW5naWZ5KHN0YXRpY0NsYXNzKTtcbiAgfVxuICB2YXIgY2xhc3NCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdjbGFzcycsIGZhbHNlIC8qIGdldFN0YXRpYyAqLyk7XG4gIGlmIChjbGFzc0JpbmRpbmcpIHtcbiAgICBlbC5jbGFzc0JpbmRpbmcgPSBjbGFzc0JpbmRpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuRGF0YSAoZWwpIHtcbiAgdmFyIGRhdGEgPSAnJztcbiAgaWYgKGVsLnN0YXRpY0NsYXNzKSB7XG4gICAgZGF0YSArPSBcInN0YXRpY0NsYXNzOlwiICsgKGVsLnN0YXRpY0NsYXNzKSArIFwiLFwiO1xuICB9XG4gIGlmIChlbC5jbGFzc0JpbmRpbmcpIHtcbiAgICBkYXRhICs9IFwiY2xhc3M6XCIgKyAoZWwuY2xhc3NCaW5kaW5nKSArIFwiLFwiO1xuICB9XG4gIHJldHVybiBkYXRhXG59XG5cbnZhciBrbGFzcyQxID0ge1xuICBzdGF0aWNLZXlzOiBbJ3N0YXRpY0NsYXNzJ10sXG4gIHRyYW5zZm9ybU5vZGU6IHRyYW5zZm9ybU5vZGUsXG4gIGdlbkRhdGE6IGdlbkRhdGFcbn07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Ob2RlJDEgKGVsLCBvcHRpb25zKSB7XG4gIHZhciB3YXJuID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuO1xuICB2YXIgc3RhdGljU3R5bGUgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAnc3R5bGUnKTtcbiAgaWYgKHN0YXRpY1N0eWxlKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAge1xuICAgICAgdmFyIHJlcyA9IHBhcnNlVGV4dChzdGF0aWNTdHlsZSwgb3B0aW9ucy5kZWxpbWl0ZXJzKTtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICBcInN0eWxlPVxcXCJcIiArIHN0YXRpY1N0eWxlICsgXCJcXFwiOiBcIiArXG4gICAgICAgICAgJ0ludGVycG9sYXRpb24gaW5zaWRlIGF0dHJpYnV0ZXMgaGFzIGJlZW4gcmVtb3ZlZC4gJyArXG4gICAgICAgICAgJ1VzZSB2LWJpbmQgb3IgdGhlIGNvbG9uIHNob3J0aGFuZCBpbnN0ZWFkLiBGb3IgZXhhbXBsZSwgJyArXG4gICAgICAgICAgJ2luc3RlYWQgb2YgPGRpdiBzdHlsZT1cInt7IHZhbCB9fVwiPiwgdXNlIDxkaXYgOnN0eWxlPVwidmFsXCI+LicsXG4gICAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3N0eWxlJ11cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWwuc3RhdGljU3R5bGUgPSBKU09OLnN0cmluZ2lmeShwYXJzZVN0eWxlVGV4dChzdGF0aWNTdHlsZSkpO1xuICB9XG5cbiAgdmFyIHN0eWxlQmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAnc3R5bGUnLCBmYWxzZSAvKiBnZXRTdGF0aWMgKi8pO1xuICBpZiAoc3R5bGVCaW5kaW5nKSB7XG4gICAgZWwuc3R5bGVCaW5kaW5nID0gc3R5bGVCaW5kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdlbkRhdGEkMSAoZWwpIHtcbiAgdmFyIGRhdGEgPSAnJztcbiAgaWYgKGVsLnN0YXRpY1N0eWxlKSB7XG4gICAgZGF0YSArPSBcInN0YXRpY1N0eWxlOlwiICsgKGVsLnN0YXRpY1N0eWxlKSArIFwiLFwiO1xuICB9XG4gIGlmIChlbC5zdHlsZUJpbmRpbmcpIHtcbiAgICBkYXRhICs9IFwic3R5bGU6KFwiICsgKGVsLnN0eWxlQmluZGluZykgKyBcIiksXCI7XG4gIH1cbiAgcmV0dXJuIGRhdGFcbn1cblxudmFyIHN0eWxlJDEgPSB7XG4gIHN0YXRpY0tleXM6IFsnc3RhdGljU3R5bGUnXSxcbiAgdHJhbnNmb3JtTm9kZTogdHJhbnNmb3JtTm9kZSQxLFxuICBnZW5EYXRhOiBnZW5EYXRhJDFcbn07XG5cbi8qICAqL1xuXG52YXIgZGVjb2RlcjtcblxudmFyIGhlID0ge1xuICBkZWNvZGU6IGZ1bmN0aW9uIGRlY29kZSAoaHRtbCkge1xuICAgIGRlY29kZXIgPSBkZWNvZGVyIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRlY29kZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICByZXR1cm4gZGVjb2Rlci50ZXh0Q29udGVudFxuICB9XG59O1xuXG4vKiAgKi9cblxudmFyIGlzVW5hcnlUYWcgPSBtYWtlTWFwKFxuICAnYXJlYSxiYXNlLGJyLGNvbCxlbWJlZCxmcmFtZSxocixpbWcsaW5wdXQsaXNpbmRleCxrZXlnZW4sJyArXG4gICdsaW5rLG1ldGEscGFyYW0sc291cmNlLHRyYWNrLHdicidcbik7XG5cbi8vIEVsZW1lbnRzIHRoYXQgeW91IGNhbiwgaW50ZW50aW9uYWxseSwgbGVhdmUgb3BlblxuLy8gKGFuZCB3aGljaCBjbG9zZSB0aGVtc2VsdmVzKVxudmFyIGNhbkJlTGVmdE9wZW5UYWcgPSBtYWtlTWFwKFxuICAnY29sZ3JvdXAsZGQsZHQsbGksb3B0aW9ucyxwLHRkLHRmb290LHRoLHRoZWFkLHRyLHNvdXJjZSdcbik7XG5cbi8vIEhUTUw1IHRhZ3MgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvaW5kaWNlcy5odG1sI2VsZW1lbnRzLTNcbi8vIFBocmFzaW5nIENvbnRlbnQgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZG9tLmh0bWwjcGhyYXNpbmctY29udGVudFxudmFyIGlzTm9uUGhyYXNpbmdUYWcgPSBtYWtlTWFwKFxuICAnYWRkcmVzcyxhcnRpY2xlLGFzaWRlLGJhc2UsYmxvY2txdW90ZSxib2R5LGNhcHRpb24sY29sLGNvbGdyb3VwLGRkLCcgK1xuICAnZGV0YWlscyxkaWFsb2csZGl2LGRsLGR0LGZpZWxkc2V0LGZpZ2NhcHRpb24sZmlndXJlLGZvb3Rlcixmb3JtLCcgK1xuICAnaDEsaDIsaDMsaDQsaDUsaDYsaGVhZCxoZWFkZXIsaGdyb3VwLGhyLGh0bWwsbGVnZW5kLGxpLG1lbnVpdGVtLG1ldGEsJyArXG4gICdvcHRncm91cCxvcHRpb24scGFyYW0scnAscnQsc291cmNlLHN0eWxlLHN1bW1hcnksdGJvZHksdGQsdGZvb3QsdGgsdGhlYWQsJyArXG4gICd0aXRsZSx0cix0cmFjaydcbik7XG5cbi8qKlxuICogTm90IHR5cGUtY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgaXQncyBtb3N0bHkgdmVuZG9yIGNvZGUuXG4gKi9cblxuLy8gUmVndWxhciBFeHByZXNzaW9ucyBmb3IgcGFyc2luZyB0YWdzIGFuZCBhdHRyaWJ1dGVzXG52YXIgYXR0cmlidXRlID0gL15cXHMqKFteXFxzXCInPD5cXC89XSspKD86XFxzKig9KVxccyooPzpcIihbXlwiXSopXCIrfCcoW14nXSopJyt8KFteXFxzXCInPTw+YF0rKSkpPy87XG52YXIgZHluYW1pY0FyZ0F0dHJpYnV0ZSA9IC9eXFxzKigoPzp2LVtcXHctXSs6fEB8OnwjKVxcW1tePV0rXFxdW15cXHNcIic8PlxcLz1dKikoPzpcXHMqKD0pXFxzKig/OlwiKFteXCJdKilcIit8JyhbXiddKiknK3woW15cXHNcIic9PD5gXSspKSk/LztcbnZhciBuY25hbWUgPSBcIlthLXpBLVpfXVtcXFxcLVxcXFwuMC05X2EtekEtWlwiICsgKHVuaWNvZGVSZWdFeHAuc291cmNlKSArIFwiXSpcIjtcbnZhciBxbmFtZUNhcHR1cmUgPSBcIigoPzpcIiArIG5jbmFtZSArIFwiXFxcXDopP1wiICsgbmNuYW1lICsgXCIpXCI7XG52YXIgc3RhcnRUYWdPcGVuID0gbmV3IFJlZ0V4cCgoXCJePFwiICsgcW5hbWVDYXB0dXJlKSk7XG52YXIgc3RhcnRUYWdDbG9zZSA9IC9eXFxzKihcXC8/KT4vO1xudmFyIGVuZFRhZyA9IG5ldyBSZWdFeHAoKFwiXjxcXFxcL1wiICsgcW5hbWVDYXB0dXJlICsgXCJbXj5dKj5cIikpO1xudmFyIGRvY3R5cGUgPSAvXjwhRE9DVFlQRSBbXj5dKz4vaTtcbi8vICM3Mjk4OiBlc2NhcGUgLSB0byBhdm9pZCBiZWluZyBwYXNzZWQgYXMgSFRNTCBjb21tZW50IHdoZW4gaW5saW5lZCBpbiBwYWdlXG52YXIgY29tbWVudCA9IC9ePCFcXC0tLztcbnZhciBjb25kaXRpb25hbENvbW1lbnQgPSAvXjwhXFxbLztcblxuLy8gU3BlY2lhbCBFbGVtZW50cyAoY2FuIGNvbnRhaW4gYW55dGhpbmcpXG52YXIgaXNQbGFpblRleHRFbGVtZW50ID0gbWFrZU1hcCgnc2NyaXB0LHN0eWxlLHRleHRhcmVhJywgdHJ1ZSk7XG52YXIgcmVDYWNoZSA9IHt9O1xuXG52YXIgZGVjb2RpbmdNYXAgPSB7XG4gICcmbHQ7JzogJzwnLFxuICAnJmd0Oyc6ICc+JyxcbiAgJyZxdW90Oyc6ICdcIicsXG4gICcmYW1wOyc6ICcmJyxcbiAgJyYjMTA7JzogJ1xcbicsXG4gICcmIzk7JzogJ1xcdCcsXG4gICcmIzM5Oyc6IFwiJ1wiXG59O1xudmFyIGVuY29kZWRBdHRyID0gLyYoPzpsdHxndHxxdW90fGFtcHwjMzkpOy9nO1xudmFyIGVuY29kZWRBdHRyV2l0aE5ld0xpbmVzID0gLyYoPzpsdHxndHxxdW90fGFtcHwjMzl8IzEwfCM5KTsvZztcblxuLy8gIzU5OTJcbnZhciBpc0lnbm9yZU5ld2xpbmVUYWcgPSBtYWtlTWFwKCdwcmUsdGV4dGFyZWEnLCB0cnVlKTtcbnZhciBzaG91bGRJZ25vcmVGaXJzdE5ld2xpbmUgPSBmdW5jdGlvbiAodGFnLCBodG1sKSB7IHJldHVybiB0YWcgJiYgaXNJZ25vcmVOZXdsaW5lVGFnKHRhZykgJiYgaHRtbFswXSA9PT0gJ1xcbic7IH07XG5cbmZ1bmN0aW9uIGRlY29kZUF0dHIgKHZhbHVlLCBzaG91bGREZWNvZGVOZXdsaW5lcykge1xuICB2YXIgcmUgPSBzaG91bGREZWNvZGVOZXdsaW5lcyA/IGVuY29kZWRBdHRyV2l0aE5ld0xpbmVzIDogZW5jb2RlZEF0dHI7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKHJlLCBmdW5jdGlvbiAobWF0Y2gpIHsgcmV0dXJuIGRlY29kaW5nTWFwW21hdGNoXTsgfSlcbn1cblxuZnVuY3Rpb24gcGFyc2VIVE1MIChodG1sLCBvcHRpb25zKSB7XG4gIHZhciBzdGFjayA9IFtdO1xuICB2YXIgZXhwZWN0SFRNTCA9IG9wdGlvbnMuZXhwZWN0SFRNTDtcbiAgdmFyIGlzVW5hcnlUYWckJDEgPSBvcHRpb25zLmlzVW5hcnlUYWcgfHwgbm87XG4gIHZhciBjYW5CZUxlZnRPcGVuVGFnJCQxID0gb3B0aW9ucy5jYW5CZUxlZnRPcGVuVGFnIHx8IG5vO1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgbGFzdCwgbGFzdFRhZztcbiAgd2hpbGUgKGh0bWwpIHtcbiAgICBsYXN0ID0gaHRtbDtcbiAgICAvLyBNYWtlIHN1cmUgd2UncmUgbm90IGluIGEgcGxhaW50ZXh0IGNvbnRlbnQgZWxlbWVudCBsaWtlIHNjcmlwdC9zdHlsZVxuICAgIGlmICghbGFzdFRhZyB8fCAhaXNQbGFpblRleHRFbGVtZW50KGxhc3RUYWcpKSB7XG4gICAgICB2YXIgdGV4dEVuZCA9IGh0bWwuaW5kZXhPZignPCcpO1xuICAgICAgaWYgKHRleHRFbmQgPT09IDApIHtcbiAgICAgICAgLy8gQ29tbWVudDpcbiAgICAgICAgaWYgKGNvbW1lbnQudGVzdChodG1sKSkge1xuICAgICAgICAgIHZhciBjb21tZW50RW5kID0gaHRtbC5pbmRleE9mKCctLT4nKTtcblxuICAgICAgICAgIGlmIChjb21tZW50RW5kID49IDApIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3VsZEtlZXBDb21tZW50KSB7XG4gICAgICAgICAgICAgIG9wdGlvbnMuY29tbWVudChodG1sLnN1YnN0cmluZyg0LCBjb21tZW50RW5kKSwgaW5kZXgsIGluZGV4ICsgY29tbWVudEVuZCArIDMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWR2YW5jZShjb21tZW50RW5kICsgMyk7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uZGl0aW9uYWxfY29tbWVudCNEb3dubGV2ZWwtcmV2ZWFsZWRfY29uZGl0aW9uYWxfY29tbWVudFxuICAgICAgICBpZiAoY29uZGl0aW9uYWxDb21tZW50LnRlc3QoaHRtbCkpIHtcbiAgICAgICAgICB2YXIgY29uZGl0aW9uYWxFbmQgPSBodG1sLmluZGV4T2YoJ10+Jyk7XG5cbiAgICAgICAgICBpZiAoY29uZGl0aW9uYWxFbmQgPj0gMCkge1xuICAgICAgICAgICAgYWR2YW5jZShjb25kaXRpb25hbEVuZCArIDIpO1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb2N0eXBlOlxuICAgICAgICB2YXIgZG9jdHlwZU1hdGNoID0gaHRtbC5tYXRjaChkb2N0eXBlKTtcbiAgICAgICAgaWYgKGRvY3R5cGVNYXRjaCkge1xuICAgICAgICAgIGFkdmFuY2UoZG9jdHlwZU1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEVuZCB0YWc6XG4gICAgICAgIHZhciBlbmRUYWdNYXRjaCA9IGh0bWwubWF0Y2goZW5kVGFnKTtcbiAgICAgICAgaWYgKGVuZFRhZ01hdGNoKSB7XG4gICAgICAgICAgdmFyIGN1ckluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgYWR2YW5jZShlbmRUYWdNYXRjaFswXS5sZW5ndGgpO1xuICAgICAgICAgIHBhcnNlRW5kVGFnKGVuZFRhZ01hdGNoWzFdLCBjdXJJbmRleCwgaW5kZXgpO1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdGFydCB0YWc6XG4gICAgICAgIHZhciBzdGFydFRhZ01hdGNoID0gcGFyc2VTdGFydFRhZygpO1xuICAgICAgICBpZiAoc3RhcnRUYWdNYXRjaCkge1xuICAgICAgICAgIGhhbmRsZVN0YXJ0VGFnKHN0YXJ0VGFnTWF0Y2gpO1xuICAgICAgICAgIGlmIChzaG91bGRJZ25vcmVGaXJzdE5ld2xpbmUoc3RhcnRUYWdNYXRjaC50YWdOYW1lLCBodG1sKSkge1xuICAgICAgICAgICAgYWR2YW5jZSgxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgdGV4dCA9ICh2b2lkIDApLCByZXN0ID0gKHZvaWQgMCksIG5leHQgPSAodm9pZCAwKTtcbiAgICAgIGlmICh0ZXh0RW5kID49IDApIHtcbiAgICAgICAgcmVzdCA9IGh0bWwuc2xpY2UodGV4dEVuZCk7XG4gICAgICAgIHdoaWxlIChcbiAgICAgICAgICAhZW5kVGFnLnRlc3QocmVzdCkgJiZcbiAgICAgICAgICAhc3RhcnRUYWdPcGVuLnRlc3QocmVzdCkgJiZcbiAgICAgICAgICAhY29tbWVudC50ZXN0KHJlc3QpICYmXG4gICAgICAgICAgIWNvbmRpdGlvbmFsQ29tbWVudC50ZXN0KHJlc3QpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIDwgaW4gcGxhaW4gdGV4dCwgYmUgZm9yZ2l2aW5nIGFuZCB0cmVhdCBpdCBhcyB0ZXh0XG4gICAgICAgICAgbmV4dCA9IHJlc3QuaW5kZXhPZignPCcsIDEpO1xuICAgICAgICAgIGlmIChuZXh0IDwgMCkgeyBicmVhayB9XG4gICAgICAgICAgdGV4dEVuZCArPSBuZXh0O1xuICAgICAgICAgIHJlc3QgPSBodG1sLnNsaWNlKHRleHRFbmQpO1xuICAgICAgICB9XG4gICAgICAgIHRleHQgPSBodG1sLnN1YnN0cmluZygwLCB0ZXh0RW5kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRleHRFbmQgPCAwKSB7XG4gICAgICAgIHRleHQgPSBodG1sO1xuICAgICAgfVxuXG4gICAgICBpZiAodGV4dCkge1xuICAgICAgICBhZHZhbmNlKHRleHQubGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMuY2hhcnMgJiYgdGV4dCkge1xuICAgICAgICBvcHRpb25zLmNoYXJzKHRleHQsIGluZGV4IC0gdGV4dC5sZW5ndGgsIGluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGVuZFRhZ0xlbmd0aCA9IDA7XG4gICAgICB2YXIgc3RhY2tlZFRhZyA9IGxhc3RUYWcudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhciByZVN0YWNrZWRUYWcgPSByZUNhY2hlW3N0YWNrZWRUYWddIHx8IChyZUNhY2hlW3N0YWNrZWRUYWddID0gbmV3IFJlZ0V4cCgnKFtcXFxcc1xcXFxTXSo/KSg8LycgKyBzdGFja2VkVGFnICsgJ1tePl0qPiknLCAnaScpKTtcbiAgICAgIHZhciByZXN0JDEgPSBodG1sLnJlcGxhY2UocmVTdGFja2VkVGFnLCBmdW5jdGlvbiAoYWxsLCB0ZXh0LCBlbmRUYWcpIHtcbiAgICAgICAgZW5kVGFnTGVuZ3RoID0gZW5kVGFnLmxlbmd0aDtcbiAgICAgICAgaWYgKCFpc1BsYWluVGV4dEVsZW1lbnQoc3RhY2tlZFRhZykgJiYgc3RhY2tlZFRhZyAhPT0gJ25vc2NyaXB0Jykge1xuICAgICAgICAgIHRleHQgPSB0ZXh0XG4gICAgICAgICAgICAucmVwbGFjZSgvPCFcXC0tKFtcXHNcXFNdKj8pLS0+L2csICckMScpIC8vICM3Mjk4XG4gICAgICAgICAgICAucmVwbGFjZSgvPCFcXFtDREFUQVxcWyhbXFxzXFxTXSo/KV1dPi9nLCAnJDEnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSWdub3JlRmlyc3ROZXdsaW5lKHN0YWNrZWRUYWcsIHRleHQpKSB7XG4gICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2UoMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhcnMpIHtcbiAgICAgICAgICBvcHRpb25zLmNoYXJzKHRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnJ1xuICAgICAgfSk7XG4gICAgICBpbmRleCArPSBodG1sLmxlbmd0aCAtIHJlc3QkMS5sZW5ndGg7XG4gICAgICBodG1sID0gcmVzdCQxO1xuICAgICAgcGFyc2VFbmRUYWcoc3RhY2tlZFRhZywgaW5kZXggLSBlbmRUYWdMZW5ndGgsIGluZGV4KTtcbiAgICB9XG5cbiAgICBpZiAoaHRtbCA9PT0gbGFzdCkge1xuICAgICAgb3B0aW9ucy5jaGFycyAmJiBvcHRpb25zLmNoYXJzKGh0bWwpO1xuICAgICAgaWYgKCFzdGFjay5sZW5ndGggJiYgb3B0aW9ucy53YXJuKSB7XG4gICAgICAgIG9wdGlvbnMud2FybigoXCJNYWwtZm9ybWF0dGVkIHRhZyBhdCBlbmQgb2YgdGVtcGxhdGU6IFxcXCJcIiArIGh0bWwgKyBcIlxcXCJcIiksIHsgc3RhcnQ6IGluZGV4ICsgaHRtbC5sZW5ndGggfSk7XG4gICAgICB9XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIC8vIENsZWFuIHVwIGFueSByZW1haW5pbmcgdGFnc1xuICBwYXJzZUVuZFRhZygpO1xuXG4gIGZ1bmN0aW9uIGFkdmFuY2UgKG4pIHtcbiAgICBpbmRleCArPSBuO1xuICAgIGh0bWwgPSBodG1sLnN1YnN0cmluZyhuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlU3RhcnRUYWcgKCkge1xuICAgIHZhciBzdGFydCA9IGh0bWwubWF0Y2goc3RhcnRUYWdPcGVuKTtcbiAgICBpZiAoc3RhcnQpIHtcbiAgICAgIHZhciBtYXRjaCA9IHtcbiAgICAgICAgdGFnTmFtZTogc3RhcnRbMV0sXG4gICAgICAgIGF0dHJzOiBbXSxcbiAgICAgICAgc3RhcnQ6IGluZGV4XG4gICAgICB9O1xuICAgICAgYWR2YW5jZShzdGFydFswXS5sZW5ndGgpO1xuICAgICAgdmFyIGVuZCwgYXR0cjtcbiAgICAgIHdoaWxlICghKGVuZCA9IGh0bWwubWF0Y2goc3RhcnRUYWdDbG9zZSkpICYmIChhdHRyID0gaHRtbC5tYXRjaChkeW5hbWljQXJnQXR0cmlidXRlKSB8fCBodG1sLm1hdGNoKGF0dHJpYnV0ZSkpKSB7XG4gICAgICAgIGF0dHIuc3RhcnQgPSBpbmRleDtcbiAgICAgICAgYWR2YW5jZShhdHRyWzBdLmxlbmd0aCk7XG4gICAgICAgIGF0dHIuZW5kID0gaW5kZXg7XG4gICAgICAgIG1hdGNoLmF0dHJzLnB1c2goYXR0cik7XG4gICAgICB9XG4gICAgICBpZiAoZW5kKSB7XG4gICAgICAgIG1hdGNoLnVuYXJ5U2xhc2ggPSBlbmRbMV07XG4gICAgICAgIGFkdmFuY2UoZW5kWzBdLmxlbmd0aCk7XG4gICAgICAgIG1hdGNoLmVuZCA9IGluZGV4O1xuICAgICAgICByZXR1cm4gbWF0Y2hcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVTdGFydFRhZyAobWF0Y2gpIHtcbiAgICB2YXIgdGFnTmFtZSA9IG1hdGNoLnRhZ05hbWU7XG4gICAgdmFyIHVuYXJ5U2xhc2ggPSBtYXRjaC51bmFyeVNsYXNoO1xuXG4gICAgaWYgKGV4cGVjdEhUTUwpIHtcbiAgICAgIGlmIChsYXN0VGFnID09PSAncCcgJiYgaXNOb25QaHJhc2luZ1RhZyh0YWdOYW1lKSkge1xuICAgICAgICBwYXJzZUVuZFRhZyhsYXN0VGFnKTtcbiAgICAgIH1cbiAgICAgIGlmIChjYW5CZUxlZnRPcGVuVGFnJCQxKHRhZ05hbWUpICYmIGxhc3RUYWcgPT09IHRhZ05hbWUpIHtcbiAgICAgICAgcGFyc2VFbmRUYWcodGFnTmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHVuYXJ5ID0gaXNVbmFyeVRhZyQkMSh0YWdOYW1lKSB8fCAhIXVuYXJ5U2xhc2g7XG5cbiAgICB2YXIgbCA9IG1hdGNoLmF0dHJzLmxlbmd0aDtcbiAgICB2YXIgYXR0cnMgPSBuZXcgQXJyYXkobCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBhcmdzID0gbWF0Y2guYXR0cnNbaV07XG4gICAgICB2YXIgdmFsdWUgPSBhcmdzWzNdIHx8IGFyZ3NbNF0gfHwgYXJnc1s1XSB8fCAnJztcbiAgICAgIHZhciBzaG91bGREZWNvZGVOZXdsaW5lcyA9IHRhZ05hbWUgPT09ICdhJyAmJiBhcmdzWzFdID09PSAnaHJlZidcbiAgICAgICAgPyBvcHRpb25zLnNob3VsZERlY29kZU5ld2xpbmVzRm9ySHJlZlxuICAgICAgICA6IG9wdGlvbnMuc2hvdWxkRGVjb2RlTmV3bGluZXM7XG4gICAgICBhdHRyc1tpXSA9IHtcbiAgICAgICAgbmFtZTogYXJnc1sxXSxcbiAgICAgICAgdmFsdWU6IGRlY29kZUF0dHIodmFsdWUsIHNob3VsZERlY29kZU5ld2xpbmVzKVxuICAgICAgfTtcbiAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7XG4gICAgICAgIGF0dHJzW2ldLnN0YXJ0ID0gYXJncy5zdGFydCArIGFyZ3NbMF0ubWF0Y2goL15cXHMqLykubGVuZ3RoO1xuICAgICAgICBhdHRyc1tpXS5lbmQgPSBhcmdzLmVuZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXVuYXJ5KSB7XG4gICAgICBzdGFjay5wdXNoKHsgdGFnOiB0YWdOYW1lLCBsb3dlckNhc2VkVGFnOiB0YWdOYW1lLnRvTG93ZXJDYXNlKCksIGF0dHJzOiBhdHRycywgc3RhcnQ6IG1hdGNoLnN0YXJ0LCBlbmQ6IG1hdGNoLmVuZCB9KTtcbiAgICAgIGxhc3RUYWcgPSB0YWdOYW1lO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnN0YXJ0KSB7XG4gICAgICBvcHRpb25zLnN0YXJ0KHRhZ05hbWUsIGF0dHJzLCB1bmFyeSwgbWF0Y2guc3RhcnQsIG1hdGNoLmVuZCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VFbmRUYWcgKHRhZ05hbWUsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgcG9zLCBsb3dlckNhc2VkVGFnTmFtZTtcbiAgICBpZiAoc3RhcnQgPT0gbnVsbCkgeyBzdGFydCA9IGluZGV4OyB9XG4gICAgaWYgKGVuZCA9PSBudWxsKSB7IGVuZCA9IGluZGV4OyB9XG5cbiAgICAvLyBGaW5kIHRoZSBjbG9zZXN0IG9wZW5lZCB0YWcgb2YgdGhlIHNhbWUgdHlwZVxuICAgIGlmICh0YWdOYW1lKSB7XG4gICAgICBsb3dlckNhc2VkVGFnTmFtZSA9IHRhZ05hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGZvciAocG9zID0gc3RhY2subGVuZ3RoIC0gMTsgcG9zID49IDA7IHBvcy0tKSB7XG4gICAgICAgIGlmIChzdGFja1twb3NdLmxvd2VyQ2FzZWRUYWcgPT09IGxvd2VyQ2FzZWRUYWdOYW1lKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBubyB0YWcgbmFtZSBpcyBwcm92aWRlZCwgY2xlYW4gc2hvcFxuICAgICAgcG9zID0gMDtcbiAgICB9XG5cbiAgICBpZiAocG9zID49IDApIHtcbiAgICAgIC8vIENsb3NlIGFsbCB0aGUgb3BlbiBlbGVtZW50cywgdXAgdGhlIHN0YWNrXG4gICAgICBmb3IgKHZhciBpID0gc3RhY2subGVuZ3RoIC0gMTsgaSA+PSBwb3M7IGktLSkge1xuICAgICAgICBpZiAoaSA+IHBvcyB8fCAhdGFnTmFtZSAmJlxuICAgICAgICAgIG9wdGlvbnMud2FyblxuICAgICAgICApIHtcbiAgICAgICAgICBvcHRpb25zLndhcm4oXG4gICAgICAgICAgICAoXCJ0YWcgPFwiICsgKHN0YWNrW2ldLnRhZykgKyBcIj4gaGFzIG5vIG1hdGNoaW5nIGVuZCB0YWcuXCIpLFxuICAgICAgICAgICAgeyBzdGFydDogc3RhY2tbaV0uc3RhcnQsIGVuZDogc3RhY2tbaV0uZW5kIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmVuZCkge1xuICAgICAgICAgIG9wdGlvbnMuZW5kKHN0YWNrW2ldLnRhZywgc3RhcnQsIGVuZCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVtb3ZlIHRoZSBvcGVuIGVsZW1lbnRzIGZyb20gdGhlIHN0YWNrXG4gICAgICBzdGFjay5sZW5ndGggPSBwb3M7XG4gICAgICBsYXN0VGFnID0gcG9zICYmIHN0YWNrW3BvcyAtIDFdLnRhZztcbiAgICB9IGVsc2UgaWYgKGxvd2VyQ2FzZWRUYWdOYW1lID09PSAnYnInKSB7XG4gICAgICBpZiAob3B0aW9ucy5zdGFydCkge1xuICAgICAgICBvcHRpb25zLnN0YXJ0KHRhZ05hbWUsIFtdLCB0cnVlLCBzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxvd2VyQ2FzZWRUYWdOYW1lID09PSAncCcpIHtcbiAgICAgIGlmIChvcHRpb25zLnN0YXJ0KSB7XG4gICAgICAgIG9wdGlvbnMuc3RhcnQodGFnTmFtZSwgW10sIGZhbHNlLCBzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmVuZCkge1xuICAgICAgICBvcHRpb25zLmVuZCh0YWdOYW1lLCBzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbnZhciBvblJFID0gL15AfF52LW9uOi87XG52YXIgZGlyUkUgPSAvXnYtfF5AfF46fF4jLztcbnZhciBmb3JBbGlhc1JFID0gLyhbXFxzXFxTXSo/KVxccysoPzppbnxvZilcXHMrKFtcXHNcXFNdKikvO1xudmFyIGZvckl0ZXJhdG9yUkUgPSAvLChbXixcXH1cXF1dKikoPzosKFteLFxcfVxcXV0qKSk/JC87XG52YXIgc3RyaXBQYXJlbnNSRSA9IC9eXFwofFxcKSQvZztcbnZhciBkeW5hbWljQXJnUkUgPSAvXlxcWy4qXFxdJC87XG5cbnZhciBhcmdSRSA9IC86KC4qKSQvO1xudmFyIGJpbmRSRSA9IC9eOnxeXFwufF52LWJpbmQ6LztcbnZhciBtb2RpZmllclJFID0gL1xcLlteLlxcXV0rKD89W15cXF1dKiQpL2c7XG5cbnZhciBzbG90UkUgPSAvXnYtc2xvdCg6fCQpfF4jLztcblxudmFyIGxpbmVCcmVha1JFID0gL1tcXHJcXG5dLztcbnZhciB3aGl0ZXNwYWNlUkUkMSA9IC9cXHMrL2c7XG5cbnZhciBpbnZhbGlkQXR0cmlidXRlUkUgPSAvW1xcc1wiJzw+XFwvPV0vO1xuXG52YXIgZGVjb2RlSFRNTENhY2hlZCA9IGNhY2hlZChoZS5kZWNvZGUpO1xuXG52YXIgZW1wdHlTbG90U2NvcGVUb2tlbiA9IFwiX2VtcHR5X1wiO1xuXG4vLyBjb25maWd1cmFibGUgc3RhdGVcbnZhciB3YXJuJDI7XG52YXIgZGVsaW1pdGVycztcbnZhciB0cmFuc2Zvcm1zO1xudmFyIHByZVRyYW5zZm9ybXM7XG52YXIgcG9zdFRyYW5zZm9ybXM7XG52YXIgcGxhdGZvcm1Jc1ByZVRhZztcbnZhciBwbGF0Zm9ybU11c3RVc2VQcm9wO1xudmFyIHBsYXRmb3JtR2V0VGFnTmFtZXNwYWNlO1xudmFyIG1heWJlQ29tcG9uZW50O1xuXG5mdW5jdGlvbiBjcmVhdGVBU1RFbGVtZW50IChcbiAgdGFnLFxuICBhdHRycyxcbiAgcGFyZW50XG4pIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAxLFxuICAgIHRhZzogdGFnLFxuICAgIGF0dHJzTGlzdDogYXR0cnMsXG4gICAgYXR0cnNNYXA6IG1ha2VBdHRyc01hcChhdHRycyksXG4gICAgcmF3QXR0cnNNYXA6IHt9LFxuICAgIHBhcmVudDogcGFyZW50LFxuICAgIGNoaWxkcmVuOiBbXVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydCBIVE1MIHN0cmluZyB0byBBU1QuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlIChcbiAgdGVtcGxhdGUsXG4gIG9wdGlvbnNcbikge1xuICB3YXJuJDIgPSBvcHRpb25zLndhcm4gfHwgYmFzZVdhcm47XG5cbiAgcGxhdGZvcm1Jc1ByZVRhZyA9IG9wdGlvbnMuaXNQcmVUYWcgfHwgbm87XG4gIHBsYXRmb3JtTXVzdFVzZVByb3AgPSBvcHRpb25zLm11c3RVc2VQcm9wIHx8IG5vO1xuICBwbGF0Zm9ybUdldFRhZ05hbWVzcGFjZSA9IG9wdGlvbnMuZ2V0VGFnTmFtZXNwYWNlIHx8IG5vO1xuICB2YXIgaXNSZXNlcnZlZFRhZyA9IG9wdGlvbnMuaXNSZXNlcnZlZFRhZyB8fCBubztcbiAgbWF5YmVDb21wb25lbnQgPSBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuICEhZWwuY29tcG9uZW50IHx8ICFpc1Jlc2VydmVkVGFnKGVsLnRhZyk7IH07XG5cbiAgdHJhbnNmb3JtcyA9IHBsdWNrTW9kdWxlRnVuY3Rpb24ob3B0aW9ucy5tb2R1bGVzLCAndHJhbnNmb3JtTm9kZScpO1xuICBwcmVUcmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICdwcmVUcmFuc2Zvcm1Ob2RlJyk7XG4gIHBvc3RUcmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICdwb3N0VHJhbnNmb3JtTm9kZScpO1xuXG4gIGRlbGltaXRlcnMgPSBvcHRpb25zLmRlbGltaXRlcnM7XG5cbiAgdmFyIHN0YWNrID0gW107XG4gIHZhciBwcmVzZXJ2ZVdoaXRlc3BhY2UgPSBvcHRpb25zLnByZXNlcnZlV2hpdGVzcGFjZSAhPT0gZmFsc2U7XG4gIHZhciB3aGl0ZXNwYWNlT3B0aW9uID0gb3B0aW9ucy53aGl0ZXNwYWNlO1xuICB2YXIgcm9vdDtcbiAgdmFyIGN1cnJlbnRQYXJlbnQ7XG4gIHZhciBpblZQcmUgPSBmYWxzZTtcbiAgdmFyIGluUHJlID0gZmFsc2U7XG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiB3YXJuT25jZSAobXNnLCByYW5nZSkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgICAgd2FybiQyKG1zZywgcmFuZ2UpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlRWxlbWVudCAoZWxlbWVudCkge1xuICAgIHRyaW1FbmRpbmdXaGl0ZXNwYWNlKGVsZW1lbnQpO1xuICAgIGlmICghaW5WUHJlICYmICFlbGVtZW50LnByb2Nlc3NlZCkge1xuICAgICAgZWxlbWVudCA9IHByb2Nlc3NFbGVtZW50KGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvLyB0cmVlIG1hbmFnZW1lbnRcbiAgICBpZiAoIXN0YWNrLmxlbmd0aCAmJiBlbGVtZW50ICE9PSByb290KSB7XG4gICAgICAvLyBhbGxvdyByb290IGVsZW1lbnRzIHdpdGggdi1pZiwgdi1lbHNlLWlmIGFuZCB2LWVsc2VcbiAgICAgIGlmIChyb290LmlmICYmIChlbGVtZW50LmVsc2VpZiB8fCBlbGVtZW50LmVsc2UpKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBjaGVja1Jvb3RDb25zdHJhaW50cyhlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBhZGRJZkNvbmRpdGlvbihyb290LCB7XG4gICAgICAgICAgZXhwOiBlbGVtZW50LmVsc2VpZixcbiAgICAgICAgICBibG9jazogZWxlbWVudFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdhcm5PbmNlKFxuICAgICAgICAgIFwiQ29tcG9uZW50IHRlbXBsYXRlIHNob3VsZCBjb250YWluIGV4YWN0bHkgb25lIHJvb3QgZWxlbWVudC4gXCIgK1xuICAgICAgICAgIFwiSWYgeW91IGFyZSB1c2luZyB2LWlmIG9uIG11bHRpcGxlIGVsZW1lbnRzLCBcIiArXG4gICAgICAgICAgXCJ1c2Ugdi1lbHNlLWlmIHRvIGNoYWluIHRoZW0gaW5zdGVhZC5cIixcbiAgICAgICAgICB7IHN0YXJ0OiBlbGVtZW50LnN0YXJ0IH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGN1cnJlbnRQYXJlbnQgJiYgIWVsZW1lbnQuZm9yYmlkZGVuKSB7XG4gICAgICBpZiAoZWxlbWVudC5lbHNlaWYgfHwgZWxlbWVudC5lbHNlKSB7XG4gICAgICAgIHByb2Nlc3NJZkNvbmRpdGlvbnMoZWxlbWVudCwgY3VycmVudFBhcmVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZWxlbWVudC5zbG90U2NvcGUpIHtcbiAgICAgICAgICAvLyBzY29wZWQgc2xvdFxuICAgICAgICAgIC8vIGtlZXAgaXQgaW4gdGhlIGNoaWxkcmVuIGxpc3Qgc28gdGhhdCB2LWVsc2UoLWlmKSBjb25kaXRpb25zIGNhblxuICAgICAgICAgIC8vIGZpbmQgaXQgYXMgdGhlIHByZXYgbm9kZS5cbiAgICAgICAgICB2YXIgbmFtZSA9IGVsZW1lbnQuc2xvdFRhcmdldCB8fCAnXCJkZWZhdWx0XCInXG4gICAgICAgICAgOyhjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzIHx8IChjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzID0ge30pKVtuYW1lXSA9IGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudFBhcmVudC5jaGlsZHJlbi5wdXNoKGVsZW1lbnQpO1xuICAgICAgICBlbGVtZW50LnBhcmVudCA9IGN1cnJlbnRQYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZmluYWwgY2hpbGRyZW4gY2xlYW51cFxuICAgIC8vIGZpbHRlciBvdXQgc2NvcGVkIHNsb3RzXG4gICAgZWxlbWVudC5jaGlsZHJlbiA9IGVsZW1lbnQuY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uIChjKSB7IHJldHVybiAhKGMpLnNsb3RTY29wZTsgfSk7XG4gICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHdoaXRlc3BhY2Ugbm9kZSBhZ2FpblxuICAgIHRyaW1FbmRpbmdXaGl0ZXNwYWNlKGVsZW1lbnQpO1xuXG4gICAgLy8gY2hlY2sgcHJlIHN0YXRlXG4gICAgaWYgKGVsZW1lbnQucHJlKSB7XG4gICAgICBpblZQcmUgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtSXNQcmVUYWcoZWxlbWVudC50YWcpKSB7XG4gICAgICBpblByZSA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBhcHBseSBwb3N0LXRyYW5zZm9ybXNcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvc3RUcmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwb3N0VHJhbnNmb3Jtc1tpXShlbGVtZW50LCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cmltRW5kaW5nV2hpdGVzcGFjZSAoZWwpIHtcbiAgICAvLyByZW1vdmUgdHJhaWxpbmcgd2hpdGVzcGFjZSBub2RlXG4gICAgaWYgKCFpblByZSkge1xuICAgICAgdmFyIGxhc3ROb2RlO1xuICAgICAgd2hpbGUgKFxuICAgICAgICAobGFzdE5vZGUgPSBlbC5jaGlsZHJlbltlbC5jaGlsZHJlbi5sZW5ndGggLSAxXSkgJiZcbiAgICAgICAgbGFzdE5vZGUudHlwZSA9PT0gMyAmJlxuICAgICAgICBsYXN0Tm9kZS50ZXh0ID09PSAnICdcbiAgICAgICkge1xuICAgICAgICBlbC5jaGlsZHJlbi5wb3AoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjaGVja1Jvb3RDb25zdHJhaW50cyAoZWwpIHtcbiAgICBpZiAoZWwudGFnID09PSAnc2xvdCcgfHwgZWwudGFnID09PSAndGVtcGxhdGUnKSB7XG4gICAgICB3YXJuT25jZShcbiAgICAgICAgXCJDYW5ub3QgdXNlIDxcIiArIChlbC50YWcpICsgXCI+IGFzIGNvbXBvbmVudCByb290IGVsZW1lbnQgYmVjYXVzZSBpdCBtYXkgXCIgK1xuICAgICAgICAnY29udGFpbiBtdWx0aXBsZSBub2Rlcy4nLFxuICAgICAgICB7IHN0YXJ0OiBlbC5zdGFydCB9XG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZWwuYXR0cnNNYXAuaGFzT3duUHJvcGVydHkoJ3YtZm9yJykpIHtcbiAgICAgIHdhcm5PbmNlKFxuICAgICAgICAnQ2Fubm90IHVzZSB2LWZvciBvbiBzdGF0ZWZ1bCBjb21wb25lbnQgcm9vdCBlbGVtZW50IGJlY2F1c2UgJyArXG4gICAgICAgICdpdCByZW5kZXJzIG11bHRpcGxlIGVsZW1lbnRzLicsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwWyd2LWZvciddXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlSFRNTCh0ZW1wbGF0ZSwge1xuICAgIHdhcm46IHdhcm4kMixcbiAgICBleHBlY3RIVE1MOiBvcHRpb25zLmV4cGVjdEhUTUwsXG4gICAgaXNVbmFyeVRhZzogb3B0aW9ucy5pc1VuYXJ5VGFnLFxuICAgIGNhbkJlTGVmdE9wZW5UYWc6IG9wdGlvbnMuY2FuQmVMZWZ0T3BlblRhZyxcbiAgICBzaG91bGREZWNvZGVOZXdsaW5lczogb3B0aW9ucy5zaG91bGREZWNvZGVOZXdsaW5lcyxcbiAgICBzaG91bGREZWNvZGVOZXdsaW5lc0ZvckhyZWY6IG9wdGlvbnMuc2hvdWxkRGVjb2RlTmV3bGluZXNGb3JIcmVmLFxuICAgIHNob3VsZEtlZXBDb21tZW50OiBvcHRpb25zLmNvbW1lbnRzLFxuICAgIG91dHB1dFNvdXJjZVJhbmdlOiBvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlLFxuICAgIHN0YXJ0OiBmdW5jdGlvbiBzdGFydCAodGFnLCBhdHRycywgdW5hcnksIHN0YXJ0JDEsIGVuZCkge1xuICAgICAgLy8gY2hlY2sgbmFtZXNwYWNlLlxuICAgICAgLy8gaW5oZXJpdCBwYXJlbnQgbnMgaWYgdGhlcmUgaXMgb25lXG4gICAgICB2YXIgbnMgPSAoY3VycmVudFBhcmVudCAmJiBjdXJyZW50UGFyZW50Lm5zKSB8fCBwbGF0Zm9ybUdldFRhZ05hbWVzcGFjZSh0YWcpO1xuXG4gICAgICAvLyBoYW5kbGUgSUUgc3ZnIGJ1Z1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoaXNJRSAmJiBucyA9PT0gJ3N2ZycpIHtcbiAgICAgICAgYXR0cnMgPSBndWFyZElFU1ZHQnVnKGF0dHJzKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGVsZW1lbnQgPSBjcmVhdGVBU1RFbGVtZW50KHRhZywgYXR0cnMsIGN1cnJlbnRQYXJlbnQpO1xuICAgICAgaWYgKG5zKSB7XG4gICAgICAgIGVsZW1lbnQubnMgPSBucztcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkge1xuICAgICAgICAgIGVsZW1lbnQuc3RhcnQgPSBzdGFydCQxO1xuICAgICAgICAgIGVsZW1lbnQuZW5kID0gZW5kO1xuICAgICAgICAgIGVsZW1lbnQucmF3QXR0cnNNYXAgPSBlbGVtZW50LmF0dHJzTGlzdC5yZWR1Y2UoZnVuY3Rpb24gKGN1bXVsYXRlZCwgYXR0cikge1xuICAgICAgICAgICAgY3VtdWxhdGVkW2F0dHIubmFtZV0gPSBhdHRyO1xuICAgICAgICAgICAgcmV0dXJuIGN1bXVsYXRlZFxuICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgfVxuICAgICAgICBhdHRycy5mb3JFYWNoKGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICAgICAgaWYgKGludmFsaWRBdHRyaWJ1dGVSRS50ZXN0KGF0dHIubmFtZSkpIHtcbiAgICAgICAgICAgIHdhcm4kMihcbiAgICAgICAgICAgICAgXCJJbnZhbGlkIGR5bmFtaWMgYXJndW1lbnQgZXhwcmVzc2lvbjogYXR0cmlidXRlIG5hbWVzIGNhbm5vdCBjb250YWluIFwiICtcbiAgICAgICAgICAgICAgXCJzcGFjZXMsIHF1b3RlcywgPCwgPiwgLyBvciA9LlwiLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IGF0dHIuc3RhcnQgKyBhdHRyLm5hbWUuaW5kZXhPZihcIltcIiksXG4gICAgICAgICAgICAgICAgZW5kOiBhdHRyLnN0YXJ0ICsgYXR0ci5uYW1lLmxlbmd0aFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0ZvcmJpZGRlblRhZyhlbGVtZW50KSAmJiAhaXNTZXJ2ZXJSZW5kZXJpbmcoKSkge1xuICAgICAgICBlbGVtZW50LmZvcmJpZGRlbiA9IHRydWU7XG4gICAgICAgIHdhcm4kMihcbiAgICAgICAgICAnVGVtcGxhdGVzIHNob3VsZCBvbmx5IGJlIHJlc3BvbnNpYmxlIGZvciBtYXBwaW5nIHRoZSBzdGF0ZSB0byB0aGUgJyArXG4gICAgICAgICAgJ1VJLiBBdm9pZCBwbGFjaW5nIHRhZ3Mgd2l0aCBzaWRlLWVmZmVjdHMgaW4geW91ciB0ZW1wbGF0ZXMsIHN1Y2ggYXMgJyArXG4gICAgICAgICAgXCI8XCIgKyB0YWcgKyBcIj5cIiArICcsIGFzIHRoZXkgd2lsbCBub3QgYmUgcGFyc2VkLicsXG4gICAgICAgICAgeyBzdGFydDogZWxlbWVudC5zdGFydCB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIGFwcGx5IHByZS10cmFuc2Zvcm1zXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByZVRyYW5zZm9ybXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZWxlbWVudCA9IHByZVRyYW5zZm9ybXNbaV0oZWxlbWVudCwgb3B0aW9ucykgfHwgZWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpblZQcmUpIHtcbiAgICAgICAgcHJvY2Vzc1ByZShlbGVtZW50KTtcbiAgICAgICAgaWYgKGVsZW1lbnQucHJlKSB7XG4gICAgICAgICAgaW5WUHJlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBsYXRmb3JtSXNQcmVUYWcoZWxlbWVudC50YWcpKSB7XG4gICAgICAgIGluUHJlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpblZQcmUpIHtcbiAgICAgICAgcHJvY2Vzc1Jhd0F0dHJzKGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIGlmICghZWxlbWVudC5wcm9jZXNzZWQpIHtcbiAgICAgICAgLy8gc3RydWN0dXJhbCBkaXJlY3RpdmVzXG4gICAgICAgIHByb2Nlc3NGb3IoZWxlbWVudCk7XG4gICAgICAgIHByb2Nlc3NJZihlbGVtZW50KTtcbiAgICAgICAgcHJvY2Vzc09uY2UoZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByb290ID0gZWxlbWVudDtcbiAgICAgICAge1xuICAgICAgICAgIGNoZWNrUm9vdENvbnN0cmFpbnRzKHJvb3QpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghdW5hcnkpIHtcbiAgICAgICAgY3VycmVudFBhcmVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHN0YWNrLnB1c2goZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9zZUVsZW1lbnQoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGVuZDogZnVuY3Rpb24gZW5kICh0YWcsIHN0YXJ0LCBlbmQkMSkge1xuICAgICAgdmFyIGVsZW1lbnQgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIC8vIHBvcCBzdGFja1xuICAgICAgc3RhY2subGVuZ3RoIC09IDE7XG4gICAgICBjdXJyZW50UGFyZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG4gICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkge1xuICAgICAgICBlbGVtZW50LmVuZCA9IGVuZCQxO1xuICAgICAgfVxuICAgICAgY2xvc2VFbGVtZW50KGVsZW1lbnQpO1xuICAgIH0sXG5cbiAgICBjaGFyczogZnVuY3Rpb24gY2hhcnMgKHRleHQsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIGlmICghY3VycmVudFBhcmVudCkge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKHRleHQgPT09IHRlbXBsYXRlKSB7XG4gICAgICAgICAgICB3YXJuT25jZShcbiAgICAgICAgICAgICAgJ0NvbXBvbmVudCB0ZW1wbGF0ZSByZXF1aXJlcyBhIHJvb3QgZWxlbWVudCwgcmF0aGVyIHRoYW4ganVzdCB0ZXh0LicsXG4gICAgICAgICAgICAgIHsgc3RhcnQ6IHN0YXJ0IH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmICgodGV4dCA9IHRleHQudHJpbSgpKSkge1xuICAgICAgICAgICAgd2Fybk9uY2UoXG4gICAgICAgICAgICAgIChcInRleHQgXFxcIlwiICsgdGV4dCArIFwiXFxcIiBvdXRzaWRlIHJvb3QgZWxlbWVudCB3aWxsIGJlIGlnbm9yZWQuXCIpLFxuICAgICAgICAgICAgICB7IHN0YXJ0OiBzdGFydCB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8vIElFIHRleHRhcmVhIHBsYWNlaG9sZGVyIGJ1Z1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoaXNJRSAmJlxuICAgICAgICBjdXJyZW50UGFyZW50LnRhZyA9PT0gJ3RleHRhcmVhJyAmJlxuICAgICAgICBjdXJyZW50UGFyZW50LmF0dHJzTWFwLnBsYWNlaG9sZGVyID09PSB0ZXh0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICB2YXIgY2hpbGRyZW4gPSBjdXJyZW50UGFyZW50LmNoaWxkcmVuO1xuICAgICAgaWYgKGluUHJlIHx8IHRleHQudHJpbSgpKSB7XG4gICAgICAgIHRleHQgPSBpc1RleHRUYWcoY3VycmVudFBhcmVudCkgPyB0ZXh0IDogZGVjb2RlSFRNTENhY2hlZCh0ZXh0KTtcbiAgICAgIH0gZWxzZSBpZiAoIWNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAvLyByZW1vdmUgdGhlIHdoaXRlc3BhY2Utb25seSBub2RlIHJpZ2h0IGFmdGVyIGFuIG9wZW5pbmcgdGFnXG4gICAgICAgIHRleHQgPSAnJztcbiAgICAgIH0gZWxzZSBpZiAod2hpdGVzcGFjZU9wdGlvbikge1xuICAgICAgICBpZiAod2hpdGVzcGFjZU9wdGlvbiA9PT0gJ2NvbmRlbnNlJykge1xuICAgICAgICAgIC8vIGluIGNvbmRlbnNlIG1vZGUsIHJlbW92ZSB0aGUgd2hpdGVzcGFjZSBub2RlIGlmIGl0IGNvbnRhaW5zXG4gICAgICAgICAgLy8gbGluZSBicmVhaywgb3RoZXJ3aXNlIGNvbmRlbnNlIHRvIGEgc2luZ2xlIHNwYWNlXG4gICAgICAgICAgdGV4dCA9IGxpbmVCcmVha1JFLnRlc3QodGV4dCkgPyAnJyA6ICcgJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ZXh0ID0gJyAnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ID0gcHJlc2VydmVXaGl0ZXNwYWNlID8gJyAnIDogJyc7XG4gICAgICB9XG4gICAgICBpZiAodGV4dCkge1xuICAgICAgICBpZiAoIWluUHJlICYmIHdoaXRlc3BhY2VPcHRpb24gPT09ICdjb25kZW5zZScpIHtcbiAgICAgICAgICAvLyBjb25kZW5zZSBjb25zZWN1dGl2ZSB3aGl0ZXNwYWNlcyBpbnRvIHNpbmdsZSBzcGFjZVxuICAgICAgICAgIHRleHQgPSB0ZXh0LnJlcGxhY2Uod2hpdGVzcGFjZVJFJDEsICcgJyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlcztcbiAgICAgICAgdmFyIGNoaWxkO1xuICAgICAgICBpZiAoIWluVlByZSAmJiB0ZXh0ICE9PSAnICcgJiYgKHJlcyA9IHBhcnNlVGV4dCh0ZXh0LCBkZWxpbWl0ZXJzKSkpIHtcbiAgICAgICAgICBjaGlsZCA9IHtcbiAgICAgICAgICAgIHR5cGU6IDIsXG4gICAgICAgICAgICBleHByZXNzaW9uOiByZXMuZXhwcmVzc2lvbixcbiAgICAgICAgICAgIHRva2VuczogcmVzLnRva2VucyxcbiAgICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKHRleHQgIT09ICcgJyB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8IGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdLnRleHQgIT09ICcgJykge1xuICAgICAgICAgIGNoaWxkID0ge1xuICAgICAgICAgICAgdHlwZTogMyxcbiAgICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7XG4gICAgICAgICAgICBjaGlsZC5zdGFydCA9IHN0YXJ0O1xuICAgICAgICAgICAgY2hpbGQuZW5kID0gZW5kO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgY29tbWVudDogZnVuY3Rpb24gY29tbWVudCAodGV4dCwgc3RhcnQsIGVuZCkge1xuICAgICAgLy8gYWRkaW5nIGFueXRoaW5nIGFzIGEgc2libGluZyB0byB0aGUgcm9vdCBub2RlIGlzIGZvcmJpZGRlblxuICAgICAgLy8gY29tbWVudHMgc2hvdWxkIHN0aWxsIGJlIGFsbG93ZWQsIGJ1dCBpZ25vcmVkXG4gICAgICBpZiAoY3VycmVudFBhcmVudCkge1xuICAgICAgICB2YXIgY2hpbGQgPSB7XG4gICAgICAgICAgdHlwZTogMyxcbiAgICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICAgIGlzQ29tbWVudDogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkge1xuICAgICAgICAgIGNoaWxkLnN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgICAgY2hpbGQuZW5kID0gZW5kO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRQYXJlbnQuY2hpbGRyZW4ucHVzaChjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJvb3Rcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1ByZSAoZWwpIHtcbiAgaWYgKGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LXByZScpICE9IG51bGwpIHtcbiAgICBlbC5wcmUgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NSYXdBdHRycyAoZWwpIHtcbiAgdmFyIGxpc3QgPSBlbC5hdHRyc0xpc3Q7XG4gIHZhciBsZW4gPSBsaXN0Lmxlbmd0aDtcbiAgaWYgKGxlbikge1xuICAgIHZhciBhdHRycyA9IGVsLmF0dHJzID0gbmV3IEFycmF5KGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXR0cnNbaV0gPSB7XG4gICAgICAgIG5hbWU6IGxpc3RbaV0ubmFtZSxcbiAgICAgICAgdmFsdWU6IEpTT04uc3RyaW5naWZ5KGxpc3RbaV0udmFsdWUpXG4gICAgICB9O1xuICAgICAgaWYgKGxpc3RbaV0uc3RhcnQgIT0gbnVsbCkge1xuICAgICAgICBhdHRyc1tpXS5zdGFydCA9IGxpc3RbaV0uc3RhcnQ7XG4gICAgICAgIGF0dHJzW2ldLmVuZCA9IGxpc3RbaV0uZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICghZWwucHJlKSB7XG4gICAgLy8gbm9uIHJvb3Qgbm9kZSBpbiBwcmUgYmxvY2tzIHdpdGggbm8gYXR0cmlidXRlc1xuICAgIGVsLnBsYWluID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzRWxlbWVudCAoXG4gIGVsZW1lbnQsXG4gIG9wdGlvbnNcbikge1xuICBwcm9jZXNzS2V5KGVsZW1lbnQpO1xuXG4gIC8vIGRldGVybWluZSB3aGV0aGVyIHRoaXMgaXMgYSBwbGFpbiBlbGVtZW50IGFmdGVyXG4gIC8vIHJlbW92aW5nIHN0cnVjdHVyYWwgYXR0cmlidXRlc1xuICBlbGVtZW50LnBsYWluID0gKFxuICAgICFlbGVtZW50LmtleSAmJlxuICAgICFlbGVtZW50LnNjb3BlZFNsb3RzICYmXG4gICAgIWVsZW1lbnQuYXR0cnNMaXN0Lmxlbmd0aFxuICApO1xuXG4gIHByb2Nlc3NSZWYoZWxlbWVudCk7XG4gIHByb2Nlc3NTbG90Q29udGVudChlbGVtZW50KTtcbiAgcHJvY2Vzc1Nsb3RPdXRsZXQoZWxlbWVudCk7XG4gIHByb2Nlc3NDb21wb25lbnQoZWxlbWVudCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdHJhbnNmb3Jtcy5sZW5ndGg7IGkrKykge1xuICAgIGVsZW1lbnQgPSB0cmFuc2Zvcm1zW2ldKGVsZW1lbnQsIG9wdGlvbnMpIHx8IGVsZW1lbnQ7XG4gIH1cbiAgcHJvY2Vzc0F0dHJzKGVsZW1lbnQpO1xuICByZXR1cm4gZWxlbWVudFxufVxuXG5mdW5jdGlvbiBwcm9jZXNzS2V5IChlbCkge1xuICB2YXIgZXhwID0gZ2V0QmluZGluZ0F0dHIoZWwsICdrZXknKTtcbiAgaWYgKGV4cCkge1xuICAgIHtcbiAgICAgIGlmIChlbC50YWcgPT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgICAgd2FybiQyKFxuICAgICAgICAgIFwiPHRlbXBsYXRlPiBjYW5ub3QgYmUga2V5ZWQuIFBsYWNlIHRoZSBrZXkgb24gcmVhbCBlbGVtZW50cyBpbnN0ZWFkLlwiLFxuICAgICAgICAgIGdldFJhd0JpbmRpbmdBdHRyKGVsLCAna2V5JylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbC5mb3IpIHtcbiAgICAgICAgdmFyIGl0ZXJhdG9yID0gZWwuaXRlcmF0b3IyIHx8IGVsLml0ZXJhdG9yMTtcbiAgICAgICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudDtcbiAgICAgICAgaWYgKGl0ZXJhdG9yICYmIGl0ZXJhdG9yID09PSBleHAgJiYgcGFyZW50ICYmIHBhcmVudC50YWcgPT09ICd0cmFuc2l0aW9uLWdyb3VwJykge1xuICAgICAgICAgIHdhcm4kMihcbiAgICAgICAgICAgIFwiRG8gbm90IHVzZSB2LWZvciBpbmRleCBhcyBrZXkgb24gPHRyYW5zaXRpb24tZ3JvdXA+IGNoaWxkcmVuLCBcIiArXG4gICAgICAgICAgICBcInRoaXMgaXMgdGhlIHNhbWUgYXMgbm90IHVzaW5nIGtleXMuXCIsXG4gICAgICAgICAgICBnZXRSYXdCaW5kaW5nQXR0cihlbCwgJ2tleScpLFxuICAgICAgICAgICAgdHJ1ZSAvKiB0aXAgKi9cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGVsLmtleSA9IGV4cDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzUmVmIChlbCkge1xuICB2YXIgcmVmID0gZ2V0QmluZGluZ0F0dHIoZWwsICdyZWYnKTtcbiAgaWYgKHJlZikge1xuICAgIGVsLnJlZiA9IHJlZjtcbiAgICBlbC5yZWZJbkZvciA9IGNoZWNrSW5Gb3IoZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NGb3IgKGVsKSB7XG4gIHZhciBleHA7XG4gIGlmICgoZXhwID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZm9yJykpKSB7XG4gICAgdmFyIHJlcyA9IHBhcnNlRm9yKGV4cCk7XG4gICAgaWYgKHJlcykge1xuICAgICAgZXh0ZW5kKGVsLCByZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3YXJuJDIoXG4gICAgICAgIChcIkludmFsaWQgdi1mb3IgZXhwcmVzc2lvbjogXCIgKyBleHApLFxuICAgICAgICBlbC5yYXdBdHRyc01hcFsndi1mb3InXVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuXG5cbmZ1bmN0aW9uIHBhcnNlRm9yIChleHApIHtcbiAgdmFyIGluTWF0Y2ggPSBleHAubWF0Y2goZm9yQWxpYXNSRSk7XG4gIGlmICghaW5NYXRjaCkgeyByZXR1cm4gfVxuICB2YXIgcmVzID0ge307XG4gIHJlcy5mb3IgPSBpbk1hdGNoWzJdLnRyaW0oKTtcbiAgdmFyIGFsaWFzID0gaW5NYXRjaFsxXS50cmltKCkucmVwbGFjZShzdHJpcFBhcmVuc1JFLCAnJyk7XG4gIHZhciBpdGVyYXRvck1hdGNoID0gYWxpYXMubWF0Y2goZm9ySXRlcmF0b3JSRSk7XG4gIGlmIChpdGVyYXRvck1hdGNoKSB7XG4gICAgcmVzLmFsaWFzID0gYWxpYXMucmVwbGFjZShmb3JJdGVyYXRvclJFLCAnJykudHJpbSgpO1xuICAgIHJlcy5pdGVyYXRvcjEgPSBpdGVyYXRvck1hdGNoWzFdLnRyaW0oKTtcbiAgICBpZiAoaXRlcmF0b3JNYXRjaFsyXSkge1xuICAgICAgcmVzLml0ZXJhdG9yMiA9IGl0ZXJhdG9yTWF0Y2hbMl0udHJpbSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXMuYWxpYXMgPSBhbGlhcztcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NJZiAoZWwpIHtcbiAgdmFyIGV4cCA9IGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LWlmJyk7XG4gIGlmIChleHApIHtcbiAgICBlbC5pZiA9IGV4cDtcbiAgICBhZGRJZkNvbmRpdGlvbihlbCwge1xuICAgICAgZXhwOiBleHAsXG4gICAgICBibG9jazogZWxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZScpICE9IG51bGwpIHtcbiAgICAgIGVsLmVsc2UgPSB0cnVlO1xuICAgIH1cbiAgICB2YXIgZWxzZWlmID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZS1pZicpO1xuICAgIGlmIChlbHNlaWYpIHtcbiAgICAgIGVsLmVsc2VpZiA9IGVsc2VpZjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0lmQ29uZGl0aW9ucyAoZWwsIHBhcmVudCkge1xuICB2YXIgcHJldiA9IGZpbmRQcmV2RWxlbWVudChwYXJlbnQuY2hpbGRyZW4pO1xuICBpZiAocHJldiAmJiBwcmV2LmlmKSB7XG4gICAgYWRkSWZDb25kaXRpb24ocHJldiwge1xuICAgICAgZXhwOiBlbC5lbHNlaWYsXG4gICAgICBibG9jazogZWxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB3YXJuJDIoXG4gICAgICBcInYtXCIgKyAoZWwuZWxzZWlmID8gKCdlbHNlLWlmPVwiJyArIGVsLmVsc2VpZiArICdcIicpIDogJ2Vsc2UnKSArIFwiIFwiICtcbiAgICAgIFwidXNlZCBvbiBlbGVtZW50IDxcIiArIChlbC50YWcpICsgXCI+IHdpdGhvdXQgY29ycmVzcG9uZGluZyB2LWlmLlwiLFxuICAgICAgZWwucmF3QXR0cnNNYXBbZWwuZWxzZWlmID8gJ3YtZWxzZS1pZicgOiAndi1lbHNlJ11cbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRQcmV2RWxlbWVudCAoY2hpbGRyZW4pIHtcbiAgdmFyIGkgPSBjaGlsZHJlbi5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAoY2hpbGRyZW5baV0udHlwZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGNoaWxkcmVuW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjaGlsZHJlbltpXS50ZXh0ICE9PSAnICcpIHtcbiAgICAgICAgd2FybiQyKFxuICAgICAgICAgIFwidGV4dCBcXFwiXCIgKyAoY2hpbGRyZW5baV0udGV4dC50cmltKCkpICsgXCJcXFwiIGJldHdlZW4gdi1pZiBhbmQgdi1lbHNlKC1pZikgXCIgK1xuICAgICAgICAgIFwid2lsbCBiZSBpZ25vcmVkLlwiLFxuICAgICAgICAgIGNoaWxkcmVuW2ldXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjaGlsZHJlbi5wb3AoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkSWZDb25kaXRpb24gKGVsLCBjb25kaXRpb24pIHtcbiAgaWYgKCFlbC5pZkNvbmRpdGlvbnMpIHtcbiAgICBlbC5pZkNvbmRpdGlvbnMgPSBbXTtcbiAgfVxuICBlbC5pZkNvbmRpdGlvbnMucHVzaChjb25kaXRpb24pO1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzT25jZSAoZWwpIHtcbiAgdmFyIG9uY2UkJDEgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1vbmNlJyk7XG4gIGlmIChvbmNlJCQxICE9IG51bGwpIHtcbiAgICBlbC5vbmNlID0gdHJ1ZTtcbiAgfVxufVxuXG4vLyBoYW5kbGUgY29udGVudCBiZWluZyBwYXNzZWQgdG8gYSBjb21wb25lbnQgYXMgc2xvdCxcbi8vIGUuZy4gPHRlbXBsYXRlIHNsb3Q9XCJ4eHhcIj4sIDxkaXYgc2xvdC1zY29wZT1cInh4eFwiPlxuZnVuY3Rpb24gcHJvY2Vzc1Nsb3RDb250ZW50IChlbCkge1xuICB2YXIgc2xvdFNjb3BlO1xuICBpZiAoZWwudGFnID09PSAndGVtcGxhdGUnKSB7XG4gICAgc2xvdFNjb3BlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3Njb3BlJyk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHNsb3RTY29wZSkge1xuICAgICAgd2FybiQyKFxuICAgICAgICBcInRoZSBcXFwic2NvcGVcXFwiIGF0dHJpYnV0ZSBmb3Igc2NvcGVkIHNsb3RzIGhhdmUgYmVlbiBkZXByZWNhdGVkIGFuZCBcIiArXG4gICAgICAgIFwicmVwbGFjZWQgYnkgXFxcInNsb3Qtc2NvcGVcXFwiIHNpbmNlIDIuNS4gVGhlIG5ldyBcXFwic2xvdC1zY29wZVxcXCIgYXR0cmlidXRlIFwiICtcbiAgICAgICAgXCJjYW4gYWxzbyBiZSB1c2VkIG9uIHBsYWluIGVsZW1lbnRzIGluIGFkZGl0aW9uIHRvIDx0ZW1wbGF0ZT4gdG8gXCIgK1xuICAgICAgICBcImRlbm90ZSBzY29wZWQgc2xvdHMuXCIsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwWydzY29wZSddLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgIH1cbiAgICBlbC5zbG90U2NvcGUgPSBzbG90U2NvcGUgfHwgZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3Nsb3Qtc2NvcGUnKTtcbiAgfSBlbHNlIGlmICgoc2xvdFNjb3BlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3Nsb3Qtc2NvcGUnKSkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoZWwuYXR0cnNNYXBbJ3YtZm9yJ10pIHtcbiAgICAgIHdhcm4kMihcbiAgICAgICAgXCJBbWJpZ3VvdXMgY29tYmluZWQgdXNhZ2Ugb2Ygc2xvdC1zY29wZSBhbmQgdi1mb3Igb24gPFwiICsgKGVsLnRhZykgKyBcIj4gXCIgK1xuICAgICAgICBcIih2LWZvciB0YWtlcyBoaWdoZXIgcHJpb3JpdHkpLiBVc2UgYSB3cmFwcGVyIDx0ZW1wbGF0ZT4gZm9yIHRoZSBcIiArXG4gICAgICAgIFwic2NvcGVkIHNsb3QgdG8gbWFrZSBpdCBjbGVhcmVyLlwiLFxuICAgICAgICBlbC5yYXdBdHRyc01hcFsnc2xvdC1zY29wZSddLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgIH1cbiAgICBlbC5zbG90U2NvcGUgPSBzbG90U2NvcGU7XG4gIH1cblxuICAvLyBzbG90PVwieHh4XCJcbiAgdmFyIHNsb3RUYXJnZXQgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3Nsb3QnKTtcbiAgaWYgKHNsb3RUYXJnZXQpIHtcbiAgICBlbC5zbG90VGFyZ2V0ID0gc2xvdFRhcmdldCA9PT0gJ1wiXCInID8gJ1wiZGVmYXVsdFwiJyA6IHNsb3RUYXJnZXQ7XG4gICAgZWwuc2xvdFRhcmdldER5bmFtaWMgPSAhIShlbC5hdHRyc01hcFsnOnNsb3QnXSB8fCBlbC5hdHRyc01hcFsndi1iaW5kOnNsb3QnXSk7XG4gICAgLy8gcHJlc2VydmUgc2xvdCBhcyBhbiBhdHRyaWJ1dGUgZm9yIG5hdGl2ZSBzaGFkb3cgRE9NIGNvbXBhdFxuICAgIC8vIG9ubHkgZm9yIG5vbi1zY29wZWQgc2xvdHMuXG4gICAgaWYgKGVsLnRhZyAhPT0gJ3RlbXBsYXRlJyAmJiAhZWwuc2xvdFNjb3BlKSB7XG4gICAgICBhZGRBdHRyKGVsLCAnc2xvdCcsIHNsb3RUYXJnZXQsIGdldFJhd0JpbmRpbmdBdHRyKGVsLCAnc2xvdCcpKTtcbiAgICB9XG4gIH1cblxuICAvLyAyLjYgdi1zbG90IHN5bnRheFxuICB7XG4gICAgaWYgKGVsLnRhZyA9PT0gJ3RlbXBsYXRlJykge1xuICAgICAgLy8gdi1zbG90IG9uIDx0ZW1wbGF0ZT5cbiAgICAgIHZhciBzbG90QmluZGluZyA9IGdldEFuZFJlbW92ZUF0dHJCeVJlZ2V4KGVsLCBzbG90UkUpO1xuICAgICAgaWYgKHNsb3RCaW5kaW5nKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoZWwuc2xvdFRhcmdldCB8fCBlbC5zbG90U2NvcGUpIHtcbiAgICAgICAgICAgIHdhcm4kMihcbiAgICAgICAgICAgICAgXCJVbmV4cGVjdGVkIG1peGVkIHVzYWdlIG9mIGRpZmZlcmVudCBzbG90IHN5bnRheGVzLlwiLFxuICAgICAgICAgICAgICBlbFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLnBhcmVudCAmJiAhbWF5YmVDb21wb25lbnQoZWwucGFyZW50KSkge1xuICAgICAgICAgICAgd2FybiQyKFxuICAgICAgICAgICAgICBcIjx0ZW1wbGF0ZSB2LXNsb3Q+IGNhbiBvbmx5IGFwcGVhciBhdCB0aGUgcm9vdCBsZXZlbCBpbnNpZGUgXCIgK1xuICAgICAgICAgICAgICBcInRoZSByZWNlaXZpbmcgY29tcG9uZW50XCIsXG4gICAgICAgICAgICAgIGVsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVmID0gZ2V0U2xvdE5hbWUoc2xvdEJpbmRpbmcpO1xuICAgICAgICB2YXIgbmFtZSA9IHJlZi5uYW1lO1xuICAgICAgICB2YXIgZHluYW1pYyA9IHJlZi5keW5hbWljO1xuICAgICAgICBlbC5zbG90VGFyZ2V0ID0gbmFtZTtcbiAgICAgICAgZWwuc2xvdFRhcmdldER5bmFtaWMgPSBkeW5hbWljO1xuICAgICAgICBlbC5zbG90U2NvcGUgPSBzbG90QmluZGluZy52YWx1ZSB8fCBlbXB0eVNsb3RTY29wZVRva2VuOyAvLyBmb3JjZSBpdCBpbnRvIGEgc2NvcGVkIHNsb3QgZm9yIHBlcmZcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdi1zbG90IG9uIGNvbXBvbmVudCwgZGVub3RlcyBkZWZhdWx0IHNsb3RcbiAgICAgIHZhciBzbG90QmluZGluZyQxID0gZ2V0QW5kUmVtb3ZlQXR0ckJ5UmVnZXgoZWwsIHNsb3RSRSk7XG4gICAgICBpZiAoc2xvdEJpbmRpbmckMSkge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKCFtYXliZUNvbXBvbmVudChlbCkpIHtcbiAgICAgICAgICAgIHdhcm4kMihcbiAgICAgICAgICAgICAgXCJ2LXNsb3QgY2FuIG9ubHkgYmUgdXNlZCBvbiBjb21wb25lbnRzIG9yIDx0ZW1wbGF0ZT4uXCIsXG4gICAgICAgICAgICAgIHNsb3RCaW5kaW5nJDFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlbC5zbG90U2NvcGUgfHwgZWwuc2xvdFRhcmdldCkge1xuICAgICAgICAgICAgd2FybiQyKFxuICAgICAgICAgICAgICBcIlVuZXhwZWN0ZWQgbWl4ZWQgdXNhZ2Ugb2YgZGlmZmVyZW50IHNsb3Qgc3ludGF4ZXMuXCIsXG4gICAgICAgICAgICAgIGVsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZWwuc2NvcGVkU2xvdHMpIHtcbiAgICAgICAgICAgIHdhcm4kMihcbiAgICAgICAgICAgICAgXCJUbyBhdm9pZCBzY29wZSBhbWJpZ3VpdHksIHRoZSBkZWZhdWx0IHNsb3Qgc2hvdWxkIGFsc28gdXNlIFwiICtcbiAgICAgICAgICAgICAgXCI8dGVtcGxhdGU+IHN5bnRheCB3aGVuIHRoZXJlIGFyZSBvdGhlciBuYW1lZCBzbG90cy5cIixcbiAgICAgICAgICAgICAgc2xvdEJpbmRpbmckMVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWRkIHRoZSBjb21wb25lbnQncyBjaGlsZHJlbiB0byBpdHMgZGVmYXVsdCBzbG90XG4gICAgICAgIHZhciBzbG90cyA9IGVsLnNjb3BlZFNsb3RzIHx8IChlbC5zY29wZWRTbG90cyA9IHt9KTtcbiAgICAgICAgdmFyIHJlZiQxID0gZ2V0U2xvdE5hbWUoc2xvdEJpbmRpbmckMSk7XG4gICAgICAgIHZhciBuYW1lJDEgPSByZWYkMS5uYW1lO1xuICAgICAgICB2YXIgZHluYW1pYyQxID0gcmVmJDEuZHluYW1pYztcbiAgICAgICAgdmFyIHNsb3RDb250YWluZXIgPSBzbG90c1tuYW1lJDFdID0gY3JlYXRlQVNURWxlbWVudCgndGVtcGxhdGUnLCBbXSwgZWwpO1xuICAgICAgICBzbG90Q29udGFpbmVyLnNsb3RUYXJnZXQgPSBuYW1lJDE7XG4gICAgICAgIHNsb3RDb250YWluZXIuc2xvdFRhcmdldER5bmFtaWMgPSBkeW5hbWljJDE7XG4gICAgICAgIHNsb3RDb250YWluZXIuY2hpbGRyZW4gPSBlbC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICBpZiAoIWMuc2xvdFNjb3BlKSB7XG4gICAgICAgICAgICBjLnBhcmVudCA9IHNsb3RDb250YWluZXI7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNsb3RDb250YWluZXIuc2xvdFNjb3BlID0gc2xvdEJpbmRpbmckMS52YWx1ZSB8fCBlbXB0eVNsb3RTY29wZVRva2VuO1xuICAgICAgICAvLyByZW1vdmUgY2hpbGRyZW4gYXMgdGhleSBhcmUgcmV0dXJuZWQgZnJvbSBzY29wZWRTbG90cyBub3dcbiAgICAgICAgZWwuY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgLy8gbWFyayBlbCBub24tcGxhaW4gc28gZGF0YSBnZXRzIGdlbmVyYXRlZFxuICAgICAgICBlbC5wbGFpbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRTbG90TmFtZSAoYmluZGluZykge1xuICB2YXIgbmFtZSA9IGJpbmRpbmcubmFtZS5yZXBsYWNlKHNsb3RSRSwgJycpO1xuICBpZiAoIW5hbWUpIHtcbiAgICBpZiAoYmluZGluZy5uYW1lWzBdICE9PSAnIycpIHtcbiAgICAgIG5hbWUgPSAnZGVmYXVsdCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdhcm4kMihcbiAgICAgICAgXCJ2LXNsb3Qgc2hvcnRoYW5kIHN5bnRheCByZXF1aXJlcyBhIHNsb3QgbmFtZS5cIixcbiAgICAgICAgYmluZGluZ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGR5bmFtaWNBcmdSRS50ZXN0KG5hbWUpXG4gICAgLy8gZHluYW1pYyBbbmFtZV1cbiAgICA/IHsgbmFtZTogbmFtZS5zbGljZSgxLCAtMSksIGR5bmFtaWM6IHRydWUgfVxuICAgIC8vIHN0YXRpYyBuYW1lXG4gICAgOiB7IG5hbWU6IChcIlxcXCJcIiArIG5hbWUgKyBcIlxcXCJcIiksIGR5bmFtaWM6IGZhbHNlIH1cbn1cblxuLy8gaGFuZGxlIDxzbG90Lz4gb3V0bGV0c1xuZnVuY3Rpb24gcHJvY2Vzc1Nsb3RPdXRsZXQgKGVsKSB7XG4gIGlmIChlbC50YWcgPT09ICdzbG90Jykge1xuICAgIGVsLnNsb3ROYW1lID0gZ2V0QmluZGluZ0F0dHIoZWwsICduYW1lJyk7XG4gICAgaWYgKGVsLmtleSkge1xuICAgICAgd2FybiQyKFxuICAgICAgICBcImBrZXlgIGRvZXMgbm90IHdvcmsgb24gPHNsb3Q+IGJlY2F1c2Ugc2xvdHMgYXJlIGFic3RyYWN0IG91dGxldHMgXCIgK1xuICAgICAgICBcImFuZCBjYW4gcG9zc2libHkgZXhwYW5kIGludG8gbXVsdGlwbGUgZWxlbWVudHMuIFwiICtcbiAgICAgICAgXCJVc2UgdGhlIGtleSBvbiBhIHdyYXBwaW5nIGVsZW1lbnQgaW5zdGVhZC5cIixcbiAgICAgICAgZ2V0UmF3QmluZGluZ0F0dHIoZWwsICdrZXknKVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0NvbXBvbmVudCAoZWwpIHtcbiAgdmFyIGJpbmRpbmc7XG4gIGlmICgoYmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAnaXMnKSkpIHtcbiAgICBlbC5jb21wb25lbnQgPSBiaW5kaW5nO1xuICB9XG4gIGlmIChnZXRBbmRSZW1vdmVBdHRyKGVsLCAnaW5saW5lLXRlbXBsYXRlJykgIT0gbnVsbCkge1xuICAgIGVsLmlubGluZVRlbXBsYXRlID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQXR0cnMgKGVsKSB7XG4gIHZhciBsaXN0ID0gZWwuYXR0cnNMaXN0O1xuICB2YXIgaSwgbCwgbmFtZSwgcmF3TmFtZSwgdmFsdWUsIG1vZGlmaWVycywgc3luY0dlbiwgaXNEeW5hbWljO1xuICBmb3IgKGkgPSAwLCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBuYW1lID0gcmF3TmFtZSA9IGxpc3RbaV0ubmFtZTtcbiAgICB2YWx1ZSA9IGxpc3RbaV0udmFsdWU7XG4gICAgaWYgKGRpclJFLnRlc3QobmFtZSkpIHtcbiAgICAgIC8vIG1hcmsgZWxlbWVudCBhcyBkeW5hbWljXG4gICAgICBlbC5oYXNCaW5kaW5ncyA9IHRydWU7XG4gICAgICAvLyBtb2RpZmllcnNcbiAgICAgIG1vZGlmaWVycyA9IHBhcnNlTW9kaWZpZXJzKG5hbWUucmVwbGFjZShkaXJSRSwgJycpKTtcbiAgICAgIC8vIHN1cHBvcnQgLmZvbyBzaG9ydGhhbmQgc3ludGF4IGZvciB0aGUgLnByb3AgbW9kaWZpZXJcbiAgICAgIGlmIChtb2RpZmllcnMpIHtcbiAgICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZShtb2RpZmllclJFLCAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoYmluZFJFLnRlc3QobmFtZSkpIHsgLy8gdi1iaW5kXG4gICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoYmluZFJFLCAnJyk7XG4gICAgICAgIHZhbHVlID0gcGFyc2VGaWx0ZXJzKHZhbHVlKTtcbiAgICAgICAgaXNEeW5hbWljID0gZHluYW1pY0FyZ1JFLnRlc3QobmFtZSk7XG4gICAgICAgIGlmIChpc0R5bmFtaWMpIHtcbiAgICAgICAgICBuYW1lID0gbmFtZS5zbGljZSgxLCAtMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgd2FybiQyKFxuICAgICAgICAgICAgKFwiVGhlIHZhbHVlIGZvciBhIHYtYmluZCBleHByZXNzaW9uIGNhbm5vdCBiZSBlbXB0eS4gRm91bmQgaW4gXFxcInYtYmluZDpcIiArIG5hbWUgKyBcIlxcXCJcIilcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtb2RpZmllcnMpIHtcbiAgICAgICAgICBpZiAobW9kaWZpZXJzLnByb3AgJiYgIWlzRHluYW1pYykge1xuICAgICAgICAgICAgbmFtZSA9IGNhbWVsaXplKG5hbWUpO1xuICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdpbm5lckh0bWwnKSB7IG5hbWUgPSAnaW5uZXJIVE1MJzsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobW9kaWZpZXJzLmNhbWVsICYmICFpc0R5bmFtaWMpIHtcbiAgICAgICAgICAgIG5hbWUgPSBjYW1lbGl6ZShuYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG1vZGlmaWVycy5zeW5jKSB7XG4gICAgICAgICAgICBzeW5jR2VuID0gZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIFwiJGV2ZW50XCIpO1xuICAgICAgICAgICAgaWYgKCFpc0R5bmFtaWMpIHtcbiAgICAgICAgICAgICAgYWRkSGFuZGxlcihcbiAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICAoXCJ1cGRhdGU6XCIgKyAoY2FtZWxpemUobmFtZSkpKSxcbiAgICAgICAgICAgICAgICBzeW5jR2VuLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgd2FybiQyLFxuICAgICAgICAgICAgICAgIGxpc3RbaV1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGh5cGhlbmF0ZShuYW1lKSAhPT0gY2FtZWxpemUobmFtZSkpIHtcbiAgICAgICAgICAgICAgICBhZGRIYW5kbGVyKFxuICAgICAgICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICAgICAgICAoXCJ1cGRhdGU6XCIgKyAoaHlwaGVuYXRlKG5hbWUpKSksXG4gICAgICAgICAgICAgICAgICBzeW5jR2VuLFxuICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgd2FybiQyLFxuICAgICAgICAgICAgICAgICAgbGlzdFtpXVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGhhbmRsZXIgdy8gZHluYW1pYyBldmVudCBuYW1lXG4gICAgICAgICAgICAgIGFkZEhhbmRsZXIoXG4gICAgICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICAgICAgKFwiXFxcInVwZGF0ZTpcXFwiKyhcIiArIG5hbWUgKyBcIilcIiksXG4gICAgICAgICAgICAgICAgc3luY0dlbixcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIHdhcm4kMixcbiAgICAgICAgICAgICAgICBsaXN0W2ldLFxuICAgICAgICAgICAgICAgIHRydWUgLy8gZHluYW1pY1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoKG1vZGlmaWVycyAmJiBtb2RpZmllcnMucHJvcCkgfHwgKFxuICAgICAgICAgICFlbC5jb21wb25lbnQgJiYgcGxhdGZvcm1NdXN0VXNlUHJvcChlbC50YWcsIGVsLmF0dHJzTWFwLnR5cGUsIG5hbWUpXG4gICAgICAgICkpIHtcbiAgICAgICAgICBhZGRQcm9wKGVsLCBuYW1lLCB2YWx1ZSwgbGlzdFtpXSwgaXNEeW5hbWljKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRBdHRyKGVsLCBuYW1lLCB2YWx1ZSwgbGlzdFtpXSwgaXNEeW5hbWljKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChvblJFLnRlc3QobmFtZSkpIHsgLy8gdi1vblxuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKG9uUkUsICcnKTtcbiAgICAgICAgaXNEeW5hbWljID0gZHluYW1pY0FyZ1JFLnRlc3QobmFtZSk7XG4gICAgICAgIGlmIChpc0R5bmFtaWMpIHtcbiAgICAgICAgICBuYW1lID0gbmFtZS5zbGljZSgxLCAtMSk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkSGFuZGxlcihlbCwgbmFtZSwgdmFsdWUsIG1vZGlmaWVycywgZmFsc2UsIHdhcm4kMiwgbGlzdFtpXSwgaXNEeW5hbWljKTtcbiAgICAgIH0gZWxzZSB7IC8vIG5vcm1hbCBkaXJlY3RpdmVzXG4gICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoZGlyUkUsICcnKTtcbiAgICAgICAgLy8gcGFyc2UgYXJnXG4gICAgICAgIHZhciBhcmdNYXRjaCA9IG5hbWUubWF0Y2goYXJnUkUpO1xuICAgICAgICB2YXIgYXJnID0gYXJnTWF0Y2ggJiYgYXJnTWF0Y2hbMV07XG4gICAgICAgIGlzRHluYW1pYyA9IGZhbHNlO1xuICAgICAgICBpZiAoYXJnKSB7XG4gICAgICAgICAgbmFtZSA9IG5hbWUuc2xpY2UoMCwgLShhcmcubGVuZ3RoICsgMSkpO1xuICAgICAgICAgIGlmIChkeW5hbWljQXJnUkUudGVzdChhcmcpKSB7XG4gICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMSwgLTEpO1xuICAgICAgICAgICAgaXNEeW5hbWljID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYWRkRGlyZWN0aXZlKGVsLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSwgYXJnLCBpc0R5bmFtaWMsIG1vZGlmaWVycywgbGlzdFtpXSk7XG4gICAgICAgIGlmIChuYW1lID09PSAnbW9kZWwnKSB7XG4gICAgICAgICAgY2hlY2tGb3JBbGlhc01vZGVsKGVsLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbGl0ZXJhbCBhdHRyaWJ1dGVcbiAgICAgIHtcbiAgICAgICAgdmFyIHJlcyA9IHBhcnNlVGV4dCh2YWx1ZSwgZGVsaW1pdGVycyk7XG4gICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICB3YXJuJDIoXG4gICAgICAgICAgICBuYW1lICsgXCI9XFxcIlwiICsgdmFsdWUgKyBcIlxcXCI6IFwiICtcbiAgICAgICAgICAgICdJbnRlcnBvbGF0aW9uIGluc2lkZSBhdHRyaWJ1dGVzIGhhcyBiZWVuIHJlbW92ZWQuICcgK1xuICAgICAgICAgICAgJ1VzZSB2LWJpbmQgb3IgdGhlIGNvbG9uIHNob3J0aGFuZCBpbnN0ZWFkLiBGb3IgZXhhbXBsZSwgJyArXG4gICAgICAgICAgICAnaW5zdGVhZCBvZiA8ZGl2IGlkPVwie3sgdmFsIH19XCI+LCB1c2UgPGRpdiA6aWQ9XCJ2YWxcIj4uJyxcbiAgICAgICAgICAgIGxpc3RbaV1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhZGRBdHRyKGVsLCBuYW1lLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSksIGxpc3RbaV0pO1xuICAgICAgLy8gIzY4ODcgZmlyZWZveCBkb2Vzbid0IHVwZGF0ZSBtdXRlZCBzdGF0ZSBpZiBzZXQgdmlhIGF0dHJpYnV0ZVxuICAgICAgLy8gZXZlbiBpbW1lZGlhdGVseSBhZnRlciBlbGVtZW50IGNyZWF0aW9uXG4gICAgICBpZiAoIWVsLmNvbXBvbmVudCAmJlxuICAgICAgICAgIG5hbWUgPT09ICdtdXRlZCcgJiZcbiAgICAgICAgICBwbGF0Zm9ybU11c3RVc2VQcm9wKGVsLnRhZywgZWwuYXR0cnNNYXAudHlwZSwgbmFtZSkpIHtcbiAgICAgICAgYWRkUHJvcChlbCwgbmFtZSwgJ3RydWUnLCBsaXN0W2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tJbkZvciAoZWwpIHtcbiAgdmFyIHBhcmVudCA9IGVsO1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgaWYgKHBhcmVudC5mb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDtcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gcGFyc2VNb2RpZmllcnMgKG5hbWUpIHtcbiAgdmFyIG1hdGNoID0gbmFtZS5tYXRjaChtb2RpZmllclJFKTtcbiAgaWYgKG1hdGNoKSB7XG4gICAgdmFyIHJldCA9IHt9O1xuICAgIG1hdGNoLmZvckVhY2goZnVuY3Rpb24gKG0pIHsgcmV0W20uc2xpY2UoMSldID0gdHJ1ZTsgfSk7XG4gICAgcmV0dXJuIHJldFxuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VBdHRyc01hcCAoYXR0cnMpIHtcbiAgdmFyIG1hcCA9IHt9O1xuICBmb3IgKHZhciBpID0gMCwgbCA9IGF0dHJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChcbiAgICAgIG1hcFthdHRyc1tpXS5uYW1lXSAmJiAhaXNJRSAmJiAhaXNFZGdlXG4gICAgKSB7XG4gICAgICB3YXJuJDIoJ2R1cGxpY2F0ZSBhdHRyaWJ1dGU6ICcgKyBhdHRyc1tpXS5uYW1lLCBhdHRyc1tpXSk7XG4gICAgfVxuICAgIG1hcFthdHRyc1tpXS5uYW1lXSA9IGF0dHJzW2ldLnZhbHVlO1xuICB9XG4gIHJldHVybiBtYXBcbn1cblxuLy8gZm9yIHNjcmlwdCAoZS5nLiB0eXBlPVwieC90ZW1wbGF0ZVwiKSBvciBzdHlsZSwgZG8gbm90IGRlY29kZSBjb250ZW50XG5mdW5jdGlvbiBpc1RleHRUYWcgKGVsKSB7XG4gIHJldHVybiBlbC50YWcgPT09ICdzY3JpcHQnIHx8IGVsLnRhZyA9PT0gJ3N0eWxlJ1xufVxuXG5mdW5jdGlvbiBpc0ZvcmJpZGRlblRhZyAoZWwpIHtcbiAgcmV0dXJuIChcbiAgICBlbC50YWcgPT09ICdzdHlsZScgfHxcbiAgICAoZWwudGFnID09PSAnc2NyaXB0JyAmJiAoXG4gICAgICAhZWwuYXR0cnNNYXAudHlwZSB8fFxuICAgICAgZWwuYXR0cnNNYXAudHlwZSA9PT0gJ3RleHQvamF2YXNjcmlwdCdcbiAgICApKVxuICApXG59XG5cbnZhciBpZU5TQnVnID0gL154bWxuczpOU1xcZCsvO1xudmFyIGllTlNQcmVmaXggPSAvXk5TXFxkKzovO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gZ3VhcmRJRVNWR0J1ZyAoYXR0cnMpIHtcbiAgdmFyIHJlcyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGF0dHIgPSBhdHRyc1tpXTtcbiAgICBpZiAoIWllTlNCdWcudGVzdChhdHRyLm5hbWUpKSB7XG4gICAgICBhdHRyLm5hbWUgPSBhdHRyLm5hbWUucmVwbGFjZShpZU5TUHJlZml4LCAnJyk7XG4gICAgICByZXMucHVzaChhdHRyKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBjaGVja0ZvckFsaWFzTW9kZWwgKGVsLCB2YWx1ZSkge1xuICB2YXIgX2VsID0gZWw7XG4gIHdoaWxlIChfZWwpIHtcbiAgICBpZiAoX2VsLmZvciAmJiBfZWwuYWxpYXMgPT09IHZhbHVlKSB7XG4gICAgICB3YXJuJDIoXG4gICAgICAgIFwiPFwiICsgKGVsLnRhZykgKyBcIiB2LW1vZGVsPVxcXCJcIiArIHZhbHVlICsgXCJcXFwiPjogXCIgK1xuICAgICAgICBcIllvdSBhcmUgYmluZGluZyB2LW1vZGVsIGRpcmVjdGx5IHRvIGEgdi1mb3IgaXRlcmF0aW9uIGFsaWFzLiBcIiArXG4gICAgICAgIFwiVGhpcyB3aWxsIG5vdCBiZSBhYmxlIHRvIG1vZGlmeSB0aGUgdi1mb3Igc291cmNlIGFycmF5IGJlY2F1c2UgXCIgK1xuICAgICAgICBcIndyaXRpbmcgdG8gdGhlIGFsaWFzIGlzIGxpa2UgbW9kaWZ5aW5nIGEgZnVuY3Rpb24gbG9jYWwgdmFyaWFibGUuIFwiICtcbiAgICAgICAgXCJDb25zaWRlciB1c2luZyBhbiBhcnJheSBvZiBvYmplY3RzIGFuZCB1c2Ugdi1tb2RlbCBvbiBhbiBvYmplY3QgcHJvcGVydHkgaW5zdGVhZC5cIixcbiAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3YtbW9kZWwnXVxuICAgICAgKTtcbiAgICB9XG4gICAgX2VsID0gX2VsLnBhcmVudDtcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gcHJlVHJhbnNmb3JtTm9kZSAoZWwsIG9wdGlvbnMpIHtcbiAgaWYgKGVsLnRhZyA9PT0gJ2lucHV0Jykge1xuICAgIHZhciBtYXAgPSBlbC5hdHRyc01hcDtcbiAgICBpZiAoIW1hcFsndi1tb2RlbCddKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgdHlwZUJpbmRpbmc7XG4gICAgaWYgKG1hcFsnOnR5cGUnXSB8fCBtYXBbJ3YtYmluZDp0eXBlJ10pIHtcbiAgICAgIHR5cGVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICd0eXBlJyk7XG4gICAgfVxuICAgIGlmICghbWFwLnR5cGUgJiYgIXR5cGVCaW5kaW5nICYmIG1hcFsndi1iaW5kJ10pIHtcbiAgICAgIHR5cGVCaW5kaW5nID0gXCIoXCIgKyAobWFwWyd2LWJpbmQnXSkgKyBcIikudHlwZVwiO1xuICAgIH1cblxuICAgIGlmICh0eXBlQmluZGluZykge1xuICAgICAgdmFyIGlmQ29uZGl0aW9uID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtaWYnLCB0cnVlKTtcbiAgICAgIHZhciBpZkNvbmRpdGlvbkV4dHJhID0gaWZDb25kaXRpb24gPyAoXCImJihcIiArIGlmQ29uZGl0aW9uICsgXCIpXCIpIDogXCJcIjtcbiAgICAgIHZhciBoYXNFbHNlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZScsIHRydWUpICE9IG51bGw7XG4gICAgICB2YXIgZWxzZUlmQ29uZGl0aW9uID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZS1pZicsIHRydWUpO1xuICAgICAgLy8gMS4gY2hlY2tib3hcbiAgICAgIHZhciBicmFuY2gwID0gY2xvbmVBU1RFbGVtZW50KGVsKTtcbiAgICAgIC8vIHByb2Nlc3MgZm9yIG9uIHRoZSBtYWluIG5vZGVcbiAgICAgIHByb2Nlc3NGb3IoYnJhbmNoMCk7XG4gICAgICBhZGRSYXdBdHRyKGJyYW5jaDAsICd0eXBlJywgJ2NoZWNrYm94Jyk7XG4gICAgICBwcm9jZXNzRWxlbWVudChicmFuY2gwLCBvcHRpb25zKTtcbiAgICAgIGJyYW5jaDAucHJvY2Vzc2VkID0gdHJ1ZTsgLy8gcHJldmVudCBpdCBmcm9tIGRvdWJsZS1wcm9jZXNzZWRcbiAgICAgIGJyYW5jaDAuaWYgPSBcIihcIiArIHR5cGVCaW5kaW5nICsgXCIpPT09J2NoZWNrYm94J1wiICsgaWZDb25kaXRpb25FeHRyYTtcbiAgICAgIGFkZElmQ29uZGl0aW9uKGJyYW5jaDAsIHtcbiAgICAgICAgZXhwOiBicmFuY2gwLmlmLFxuICAgICAgICBibG9jazogYnJhbmNoMFxuICAgICAgfSk7XG4gICAgICAvLyAyLiBhZGQgcmFkaW8gZWxzZS1pZiBjb25kaXRpb25cbiAgICAgIHZhciBicmFuY2gxID0gY2xvbmVBU1RFbGVtZW50KGVsKTtcbiAgICAgIGdldEFuZFJlbW92ZUF0dHIoYnJhbmNoMSwgJ3YtZm9yJywgdHJ1ZSk7XG4gICAgICBhZGRSYXdBdHRyKGJyYW5jaDEsICd0eXBlJywgJ3JhZGlvJyk7XG4gICAgICBwcm9jZXNzRWxlbWVudChicmFuY2gxLCBvcHRpb25zKTtcbiAgICAgIGFkZElmQ29uZGl0aW9uKGJyYW5jaDAsIHtcbiAgICAgICAgZXhwOiBcIihcIiArIHR5cGVCaW5kaW5nICsgXCIpPT09J3JhZGlvJ1wiICsgaWZDb25kaXRpb25FeHRyYSxcbiAgICAgICAgYmxvY2s6IGJyYW5jaDFcbiAgICAgIH0pO1xuICAgICAgLy8gMy4gb3RoZXJcbiAgICAgIHZhciBicmFuY2gyID0gY2xvbmVBU1RFbGVtZW50KGVsKTtcbiAgICAgIGdldEFuZFJlbW92ZUF0dHIoYnJhbmNoMiwgJ3YtZm9yJywgdHJ1ZSk7XG4gICAgICBhZGRSYXdBdHRyKGJyYW5jaDIsICc6dHlwZScsIHR5cGVCaW5kaW5nKTtcbiAgICAgIHByb2Nlc3NFbGVtZW50KGJyYW5jaDIsIG9wdGlvbnMpO1xuICAgICAgYWRkSWZDb25kaXRpb24oYnJhbmNoMCwge1xuICAgICAgICBleHA6IGlmQ29uZGl0aW9uLFxuICAgICAgICBibG9jazogYnJhbmNoMlxuICAgICAgfSk7XG5cbiAgICAgIGlmIChoYXNFbHNlKSB7XG4gICAgICAgIGJyYW5jaDAuZWxzZSA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGVsc2VJZkNvbmRpdGlvbikge1xuICAgICAgICBicmFuY2gwLmVsc2VpZiA9IGVsc2VJZkNvbmRpdGlvbjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJyYW5jaDBcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xvbmVBU1RFbGVtZW50IChlbCkge1xuICByZXR1cm4gY3JlYXRlQVNURWxlbWVudChlbC50YWcsIGVsLmF0dHJzTGlzdC5zbGljZSgpLCBlbC5wYXJlbnQpXG59XG5cbnZhciBtb2RlbCQxID0ge1xuICBwcmVUcmFuc2Zvcm1Ob2RlOiBwcmVUcmFuc2Zvcm1Ob2RlXG59O1xuXG52YXIgbW9kdWxlcyQxID0gW1xuICBrbGFzcyQxLFxuICBzdHlsZSQxLFxuICBtb2RlbCQxXG5dO1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdGV4dCAoZWwsIGRpcikge1xuICBpZiAoZGlyLnZhbHVlKSB7XG4gICAgYWRkUHJvcChlbCwgJ3RleHRDb250ZW50JywgKFwiX3MoXCIgKyAoZGlyLnZhbHVlKSArIFwiKVwiKSwgZGlyKTtcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gaHRtbCAoZWwsIGRpcikge1xuICBpZiAoZGlyLnZhbHVlKSB7XG4gICAgYWRkUHJvcChlbCwgJ2lubmVySFRNTCcsIChcIl9zKFwiICsgKGRpci52YWx1ZSkgKyBcIilcIiksIGRpcik7XG4gIH1cbn1cblxudmFyIGRpcmVjdGl2ZXMkMSA9IHtcbiAgbW9kZWw6IG1vZGVsLFxuICB0ZXh0OiB0ZXh0LFxuICBodG1sOiBodG1sXG59O1xuXG4vKiAgKi9cblxudmFyIGJhc2VPcHRpb25zID0ge1xuICBleHBlY3RIVE1MOiB0cnVlLFxuICBtb2R1bGVzOiBtb2R1bGVzJDEsXG4gIGRpcmVjdGl2ZXM6IGRpcmVjdGl2ZXMkMSxcbiAgaXNQcmVUYWc6IGlzUHJlVGFnLFxuICBpc1VuYXJ5VGFnOiBpc1VuYXJ5VGFnLFxuICBtdXN0VXNlUHJvcDogbXVzdFVzZVByb3AsXG4gIGNhbkJlTGVmdE9wZW5UYWc6IGNhbkJlTGVmdE9wZW5UYWcsXG4gIGlzUmVzZXJ2ZWRUYWc6IGlzUmVzZXJ2ZWRUYWcsXG4gIGdldFRhZ05hbWVzcGFjZTogZ2V0VGFnTmFtZXNwYWNlLFxuICBzdGF0aWNLZXlzOiBnZW5TdGF0aWNLZXlzKG1vZHVsZXMkMSlcbn07XG5cbi8qICAqL1xuXG52YXIgaXNTdGF0aWNLZXk7XG52YXIgaXNQbGF0Zm9ybVJlc2VydmVkVGFnO1xuXG52YXIgZ2VuU3RhdGljS2V5c0NhY2hlZCA9IGNhY2hlZChnZW5TdGF0aWNLZXlzJDEpO1xuXG4vKipcbiAqIEdvYWwgb2YgdGhlIG9wdGltaXplcjogd2FsayB0aGUgZ2VuZXJhdGVkIHRlbXBsYXRlIEFTVCB0cmVlXG4gKiBhbmQgZGV0ZWN0IHN1Yi10cmVlcyB0aGF0IGFyZSBwdXJlbHkgc3RhdGljLCBpLmUuIHBhcnRzIG9mXG4gKiB0aGUgRE9NIHRoYXQgbmV2ZXIgbmVlZHMgdG8gY2hhbmdlLlxuICpcbiAqIE9uY2Ugd2UgZGV0ZWN0IHRoZXNlIHN1Yi10cmVlcywgd2UgY2FuOlxuICpcbiAqIDEuIEhvaXN0IHRoZW0gaW50byBjb25zdGFudHMsIHNvIHRoYXQgd2Ugbm8gbG9uZ2VyIG5lZWQgdG9cbiAqICAgIGNyZWF0ZSBmcmVzaCBub2RlcyBmb3IgdGhlbSBvbiBlYWNoIHJlLXJlbmRlcjtcbiAqIDIuIENvbXBsZXRlbHkgc2tpcCB0aGVtIGluIHRoZSBwYXRjaGluZyBwcm9jZXNzLlxuICovXG5mdW5jdGlvbiBvcHRpbWl6ZSAocm9vdCwgb3B0aW9ucykge1xuICBpZiAoIXJvb3QpIHsgcmV0dXJuIH1cbiAgaXNTdGF0aWNLZXkgPSBnZW5TdGF0aWNLZXlzQ2FjaGVkKG9wdGlvbnMuc3RhdGljS2V5cyB8fCAnJyk7XG4gIGlzUGxhdGZvcm1SZXNlcnZlZFRhZyA9IG9wdGlvbnMuaXNSZXNlcnZlZFRhZyB8fCBubztcbiAgLy8gZmlyc3QgcGFzczogbWFyayBhbGwgbm9uLXN0YXRpYyBub2Rlcy5cbiAgbWFya1N0YXRpYyQxKHJvb3QpO1xuICAvLyBzZWNvbmQgcGFzczogbWFyayBzdGF0aWMgcm9vdHMuXG4gIG1hcmtTdGF0aWNSb290cyhyb290LCBmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIGdlblN0YXRpY0tleXMkMSAoa2V5cykge1xuICByZXR1cm4gbWFrZU1hcChcbiAgICAndHlwZSx0YWcsYXR0cnNMaXN0LGF0dHJzTWFwLHBsYWluLHBhcmVudCxjaGlsZHJlbixhdHRycyxzdGFydCxlbmQscmF3QXR0cnNNYXAnICtcbiAgICAoa2V5cyA/ICcsJyArIGtleXMgOiAnJylcbiAgKVxufVxuXG5mdW5jdGlvbiBtYXJrU3RhdGljJDEgKG5vZGUpIHtcbiAgbm9kZS5zdGF0aWMgPSBpc1N0YXRpYyhub2RlKTtcbiAgaWYgKG5vZGUudHlwZSA9PT0gMSkge1xuICAgIC8vIGRvIG5vdCBtYWtlIGNvbXBvbmVudCBzbG90IGNvbnRlbnQgc3RhdGljLiB0aGlzIGF2b2lkc1xuICAgIC8vIDEuIGNvbXBvbmVudHMgbm90IGFibGUgdG8gbXV0YXRlIHNsb3Qgbm9kZXNcbiAgICAvLyAyLiBzdGF0aWMgc2xvdCBjb250ZW50IGZhaWxzIGZvciBob3QtcmVsb2FkaW5nXG4gICAgaWYgKFxuICAgICAgIWlzUGxhdGZvcm1SZXNlcnZlZFRhZyhub2RlLnRhZykgJiZcbiAgICAgIG5vZGUudGFnICE9PSAnc2xvdCcgJiZcbiAgICAgIG5vZGUuYXR0cnNNYXBbJ2lubGluZS10ZW1wbGF0ZSddID09IG51bGxcbiAgICApIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgbWFya1N0YXRpYyQxKGNoaWxkKTtcbiAgICAgIGlmICghY2hpbGQuc3RhdGljKSB7XG4gICAgICAgIG5vZGUuc3RhdGljID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChub2RlLmlmQ29uZGl0aW9ucykge1xuICAgICAgZm9yICh2YXIgaSQxID0gMSwgbCQxID0gbm9kZS5pZkNvbmRpdGlvbnMubGVuZ3RoOyBpJDEgPCBsJDE7IGkkMSsrKSB7XG4gICAgICAgIHZhciBibG9jayA9IG5vZGUuaWZDb25kaXRpb25zW2kkMV0uYmxvY2s7XG4gICAgICAgIG1hcmtTdGF0aWMkMShibG9jayk7XG4gICAgICAgIGlmICghYmxvY2suc3RhdGljKSB7XG4gICAgICAgICAgbm9kZS5zdGF0aWMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrU3RhdGljUm9vdHMgKG5vZGUsIGlzSW5Gb3IpIHtcbiAgaWYgKG5vZGUudHlwZSA9PT0gMSkge1xuICAgIGlmIChub2RlLnN0YXRpYyB8fCBub2RlLm9uY2UpIHtcbiAgICAgIG5vZGUuc3RhdGljSW5Gb3IgPSBpc0luRm9yO1xuICAgIH1cbiAgICAvLyBGb3IgYSBub2RlIHRvIHF1YWxpZnkgYXMgYSBzdGF0aWMgcm9vdCwgaXQgc2hvdWxkIGhhdmUgY2hpbGRyZW4gdGhhdFxuICAgIC8vIGFyZSBub3QganVzdCBzdGF0aWMgdGV4dC4gT3RoZXJ3aXNlIHRoZSBjb3N0IG9mIGhvaXN0aW5nIG91dCB3aWxsXG4gICAgLy8gb3V0d2VpZ2ggdGhlIGJlbmVmaXRzIGFuZCBpdCdzIGJldHRlciBvZmYgdG8ganVzdCBhbHdheXMgcmVuZGVyIGl0IGZyZXNoLlxuICAgIGlmIChub2RlLnN0YXRpYyAmJiBub2RlLmNoaWxkcmVuLmxlbmd0aCAmJiAhKFxuICAgICAgbm9kZS5jaGlsZHJlbi5sZW5ndGggPT09IDEgJiZcbiAgICAgIG5vZGUuY2hpbGRyZW5bMF0udHlwZSA9PT0gM1xuICAgICkpIHtcbiAgICAgIG5vZGUuc3RhdGljUm9vdCA9IHRydWU7XG4gICAgICByZXR1cm5cbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5zdGF0aWNSb290ID0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChub2RlLmNoaWxkcmVuKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIG1hcmtTdGF0aWNSb290cyhub2RlLmNoaWxkcmVuW2ldLCBpc0luRm9yIHx8ICEhbm9kZS5mb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9kZS5pZkNvbmRpdGlvbnMpIHtcbiAgICAgIGZvciAodmFyIGkkMSA9IDEsIGwkMSA9IG5vZGUuaWZDb25kaXRpb25zLmxlbmd0aDsgaSQxIDwgbCQxOyBpJDErKykge1xuICAgICAgICBtYXJrU3RhdGljUm9vdHMobm9kZS5pZkNvbmRpdGlvbnNbaSQxXS5ibG9jaywgaXNJbkZvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzU3RhdGljIChub2RlKSB7XG4gIGlmIChub2RlLnR5cGUgPT09IDIpIHsgLy8gZXhwcmVzc2lvblxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT09IDMpIHsgLy8gdGV4dFxuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuICEhKG5vZGUucHJlIHx8IChcbiAgICAhbm9kZS5oYXNCaW5kaW5ncyAmJiAvLyBubyBkeW5hbWljIGJpbmRpbmdzXG4gICAgIW5vZGUuaWYgJiYgIW5vZGUuZm9yICYmIC8vIG5vdCB2LWlmIG9yIHYtZm9yIG9yIHYtZWxzZVxuICAgICFpc0J1aWx0SW5UYWcobm9kZS50YWcpICYmIC8vIG5vdCBhIGJ1aWx0LWluXG4gICAgaXNQbGF0Zm9ybVJlc2VydmVkVGFnKG5vZGUudGFnKSAmJiAvLyBub3QgYSBjb21wb25lbnRcbiAgICAhaXNEaXJlY3RDaGlsZE9mVGVtcGxhdGVGb3Iobm9kZSkgJiZcbiAgICBPYmplY3Qua2V5cyhub2RlKS5ldmVyeShpc1N0YXRpY0tleSlcbiAgKSlcbn1cblxuZnVuY3Rpb24gaXNEaXJlY3RDaGlsZE9mVGVtcGxhdGVGb3IgKG5vZGUpIHtcbiAgd2hpbGUgKG5vZGUucGFyZW50KSB7XG4gICAgbm9kZSA9IG5vZGUucGFyZW50O1xuICAgIGlmIChub2RlLnRhZyAhPT0gJ3RlbXBsYXRlJykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmIChub2RlLmZvcikge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qICAqL1xuXG52YXIgZm5FeHBSRSA9IC9eKFtcXHckX10rfFxcKFteKV0qP1xcKSlcXHMqPT58XmZ1bmN0aW9uKD86XFxzK1tcXHckXSspP1xccypcXCgvO1xudmFyIGZuSW52b2tlUkUgPSAvXFwoW14pXSo/XFwpOyokLztcbnZhciBzaW1wbGVQYXRoUkUgPSAvXltBLVphLXpfJF1bXFx3JF0qKD86XFwuW0EtWmEtel8kXVtcXHckXSp8XFxbJ1teJ10qPyddfFxcW1wiW15cIl0qP1wiXXxcXFtcXGQrXXxcXFtbQS1aYS16XyRdW1xcdyRdKl0pKiQvO1xuXG4vLyBLZXlib2FyZEV2ZW50LmtleUNvZGUgYWxpYXNlc1xudmFyIGtleUNvZGVzID0ge1xuICBlc2M6IDI3LFxuICB0YWI6IDksXG4gIGVudGVyOiAxMyxcbiAgc3BhY2U6IDMyLFxuICB1cDogMzgsXG4gIGxlZnQ6IDM3LFxuICByaWdodDogMzksXG4gIGRvd246IDQwLFxuICAnZGVsZXRlJzogWzgsIDQ2XVxufTtcblxuLy8gS2V5Ym9hcmRFdmVudC5rZXkgYWxpYXNlc1xudmFyIGtleU5hbWVzID0ge1xuICAvLyAjNzg4MDogSUUxMSBhbmQgRWRnZSB1c2UgYEVzY2AgZm9yIEVzY2FwZSBrZXkgbmFtZS5cbiAgZXNjOiBbJ0VzYycsICdFc2NhcGUnXSxcbiAgdGFiOiAnVGFiJyxcbiAgZW50ZXI6ICdFbnRlcicsXG4gIC8vICM5MTEyOiBJRTExIHVzZXMgYFNwYWNlYmFyYCBmb3IgU3BhY2Uga2V5IG5hbWUuXG4gIHNwYWNlOiBbJyAnLCAnU3BhY2ViYXInXSxcbiAgLy8gIzc4MDY6IElFMTEgdXNlcyBrZXkgbmFtZXMgd2l0aG91dCBgQXJyb3dgIHByZWZpeCBmb3IgYXJyb3cga2V5cy5cbiAgdXA6IFsnVXAnLCAnQXJyb3dVcCddLFxuICBsZWZ0OiBbJ0xlZnQnLCAnQXJyb3dMZWZ0J10sXG4gIHJpZ2h0OiBbJ1JpZ2h0JywgJ0Fycm93UmlnaHQnXSxcbiAgZG93bjogWydEb3duJywgJ0Fycm93RG93biddLFxuICAvLyAjOTExMjogSUUxMSB1c2VzIGBEZWxgIGZvciBEZWxldGUga2V5IG5hbWUuXG4gICdkZWxldGUnOiBbJ0JhY2tzcGFjZScsICdEZWxldGUnLCAnRGVsJ11cbn07XG5cbi8vICM0ODY4OiBtb2RpZmllcnMgdGhhdCBwcmV2ZW50IHRoZSBleGVjdXRpb24gb2YgdGhlIGxpc3RlbmVyXG4vLyBuZWVkIHRvIGV4cGxpY2l0bHkgcmV0dXJuIG51bGwgc28gdGhhdCB3ZSBjYW4gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gcmVtb3ZlXG4vLyB0aGUgbGlzdGVuZXIgZm9yIC5vbmNlXG52YXIgZ2VuR3VhcmQgPSBmdW5jdGlvbiAoY29uZGl0aW9uKSB7IHJldHVybiAoXCJpZihcIiArIGNvbmRpdGlvbiArIFwiKXJldHVybiBudWxsO1wiKTsgfTtcblxudmFyIG1vZGlmaWVyQ29kZSA9IHtcbiAgc3RvcDogJyRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsnLFxuICBwcmV2ZW50OiAnJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7JyxcbiAgc2VsZjogZ2VuR3VhcmQoXCIkZXZlbnQudGFyZ2V0ICE9PSAkZXZlbnQuY3VycmVudFRhcmdldFwiKSxcbiAgY3RybDogZ2VuR3VhcmQoXCIhJGV2ZW50LmN0cmxLZXlcIiksXG4gIHNoaWZ0OiBnZW5HdWFyZChcIiEkZXZlbnQuc2hpZnRLZXlcIiksXG4gIGFsdDogZ2VuR3VhcmQoXCIhJGV2ZW50LmFsdEtleVwiKSxcbiAgbWV0YTogZ2VuR3VhcmQoXCIhJGV2ZW50Lm1ldGFLZXlcIiksXG4gIGxlZnQ6IGdlbkd1YXJkKFwiJ2J1dHRvbicgaW4gJGV2ZW50ICYmICRldmVudC5idXR0b24gIT09IDBcIiksXG4gIG1pZGRsZTogZ2VuR3VhcmQoXCInYnV0dG9uJyBpbiAkZXZlbnQgJiYgJGV2ZW50LmJ1dHRvbiAhPT0gMVwiKSxcbiAgcmlnaHQ6IGdlbkd1YXJkKFwiJ2J1dHRvbicgaW4gJGV2ZW50ICYmICRldmVudC5idXR0b24gIT09IDJcIilcbn07XG5cbmZ1bmN0aW9uIGdlbkhhbmRsZXJzIChcbiAgZXZlbnRzLFxuICBpc05hdGl2ZVxuKSB7XG4gIHZhciBwcmVmaXggPSBpc05hdGl2ZSA/ICduYXRpdmVPbjonIDogJ29uOic7XG4gIHZhciBzdGF0aWNIYW5kbGVycyA9IFwiXCI7XG4gIHZhciBkeW5hbWljSGFuZGxlcnMgPSBcIlwiO1xuICBmb3IgKHZhciBuYW1lIGluIGV2ZW50cykge1xuICAgIHZhciBoYW5kbGVyQ29kZSA9IGdlbkhhbmRsZXIoZXZlbnRzW25hbWVdKTtcbiAgICBpZiAoZXZlbnRzW25hbWVdICYmIGV2ZW50c1tuYW1lXS5keW5hbWljKSB7XG4gICAgICBkeW5hbWljSGFuZGxlcnMgKz0gbmFtZSArIFwiLFwiICsgaGFuZGxlckNvZGUgKyBcIixcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGljSGFuZGxlcnMgKz0gXCJcXFwiXCIgKyBuYW1lICsgXCJcXFwiOlwiICsgaGFuZGxlckNvZGUgKyBcIixcIjtcbiAgICB9XG4gIH1cbiAgc3RhdGljSGFuZGxlcnMgPSBcIntcIiArIChzdGF0aWNIYW5kbGVycy5zbGljZSgwLCAtMSkpICsgXCJ9XCI7XG4gIGlmIChkeW5hbWljSGFuZGxlcnMpIHtcbiAgICByZXR1cm4gcHJlZml4ICsgXCJfZChcIiArIHN0YXRpY0hhbmRsZXJzICsgXCIsW1wiICsgKGR5bmFtaWNIYW5kbGVycy5zbGljZSgwLCAtMSkpICsgXCJdKVwiXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHByZWZpeCArIHN0YXRpY0hhbmRsZXJzXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuSGFuZGxlciAoaGFuZGxlcikge1xuICBpZiAoIWhhbmRsZXIpIHtcbiAgICByZXR1cm4gJ2Z1bmN0aW9uKCl7fSdcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KGhhbmRsZXIpKSB7XG4gICAgcmV0dXJuIChcIltcIiArIChoYW5kbGVyLm1hcChmdW5jdGlvbiAoaGFuZGxlcikgeyByZXR1cm4gZ2VuSGFuZGxlcihoYW5kbGVyKTsgfSkuam9pbignLCcpKSArIFwiXVwiKVxuICB9XG5cbiAgdmFyIGlzTWV0aG9kUGF0aCA9IHNpbXBsZVBhdGhSRS50ZXN0KGhhbmRsZXIudmFsdWUpO1xuICB2YXIgaXNGdW5jdGlvbkV4cHJlc3Npb24gPSBmbkV4cFJFLnRlc3QoaGFuZGxlci52YWx1ZSk7XG4gIHZhciBpc0Z1bmN0aW9uSW52b2NhdGlvbiA9IHNpbXBsZVBhdGhSRS50ZXN0KGhhbmRsZXIudmFsdWUucmVwbGFjZShmbkludm9rZVJFLCAnJykpO1xuXG4gIGlmICghaGFuZGxlci5tb2RpZmllcnMpIHtcbiAgICBpZiAoaXNNZXRob2RQYXRoIHx8IGlzRnVuY3Rpb25FeHByZXNzaW9uKSB7XG4gICAgICByZXR1cm4gaGFuZGxlci52YWx1ZVxuICAgIH1cbiAgICByZXR1cm4gKFwiZnVuY3Rpb24oJGV2ZW50KXtcIiArIChpc0Z1bmN0aW9uSW52b2NhdGlvbiA/IChcInJldHVybiBcIiArIChoYW5kbGVyLnZhbHVlKSkgOiBoYW5kbGVyLnZhbHVlKSArIFwifVwiKSAvLyBpbmxpbmUgc3RhdGVtZW50XG4gIH0gZWxzZSB7XG4gICAgdmFyIGNvZGUgPSAnJztcbiAgICB2YXIgZ2VuTW9kaWZpZXJDb2RlID0gJyc7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gaGFuZGxlci5tb2RpZmllcnMpIHtcbiAgICAgIGlmIChtb2RpZmllckNvZGVba2V5XSkge1xuICAgICAgICBnZW5Nb2RpZmllckNvZGUgKz0gbW9kaWZpZXJDb2RlW2tleV07XG4gICAgICAgIC8vIGxlZnQvcmlnaHRcbiAgICAgICAgaWYgKGtleUNvZGVzW2tleV0pIHtcbiAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdleGFjdCcpIHtcbiAgICAgICAgdmFyIG1vZGlmaWVycyA9IChoYW5kbGVyLm1vZGlmaWVycyk7XG4gICAgICAgIGdlbk1vZGlmaWVyQ29kZSArPSBnZW5HdWFyZChcbiAgICAgICAgICBbJ2N0cmwnLCAnc2hpZnQnLCAnYWx0JywgJ21ldGEnXVxuICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5TW9kaWZpZXIpIHsgcmV0dXJuICFtb2RpZmllcnNba2V5TW9kaWZpZXJdOyB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAoa2V5TW9kaWZpZXIpIHsgcmV0dXJuIChcIiRldmVudC5cIiArIGtleU1vZGlmaWVyICsgXCJLZXlcIik7IH0pXG4gICAgICAgICAgICAuam9pbignfHwnKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlzLmxlbmd0aCkge1xuICAgICAgY29kZSArPSBnZW5LZXlGaWx0ZXIoa2V5cyk7XG4gICAgfVxuICAgIC8vIE1ha2Ugc3VyZSBtb2RpZmllcnMgbGlrZSBwcmV2ZW50IGFuZCBzdG9wIGdldCBleGVjdXRlZCBhZnRlciBrZXkgZmlsdGVyaW5nXG4gICAgaWYgKGdlbk1vZGlmaWVyQ29kZSkge1xuICAgICAgY29kZSArPSBnZW5Nb2RpZmllckNvZGU7XG4gICAgfVxuICAgIHZhciBoYW5kbGVyQ29kZSA9IGlzTWV0aG9kUGF0aFxuICAgICAgPyAoXCJyZXR1cm4gXCIgKyAoaGFuZGxlci52YWx1ZSkgKyBcIigkZXZlbnQpXCIpXG4gICAgICA6IGlzRnVuY3Rpb25FeHByZXNzaW9uXG4gICAgICAgID8gKFwicmV0dXJuIChcIiArIChoYW5kbGVyLnZhbHVlKSArIFwiKSgkZXZlbnQpXCIpXG4gICAgICAgIDogaXNGdW5jdGlvbkludm9jYXRpb25cbiAgICAgICAgICA/IChcInJldHVybiBcIiArIChoYW5kbGVyLnZhbHVlKSlcbiAgICAgICAgICA6IGhhbmRsZXIudmFsdWU7XG4gICAgcmV0dXJuIChcImZ1bmN0aW9uKCRldmVudCl7XCIgKyBjb2RlICsgaGFuZGxlckNvZGUgKyBcIn1cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5LZXlGaWx0ZXIgKGtleXMpIHtcbiAgcmV0dXJuIChcbiAgICAvLyBtYWtlIHN1cmUgdGhlIGtleSBmaWx0ZXJzIG9ubHkgYXBwbHkgdG8gS2V5Ym9hcmRFdmVudHNcbiAgICAvLyAjOTQ0MTogY2FuJ3QgdXNlICdrZXlDb2RlJyBpbiAkZXZlbnQgYmVjYXVzZSBDaHJvbWUgYXV0b2ZpbGwgZmlyZXMgZmFrZVxuICAgIC8vIGtleSBldmVudHMgdGhhdCBkbyBub3QgaGF2ZSBrZXlDb2RlIHByb3BlcnR5Li4uXG4gICAgXCJpZighJGV2ZW50LnR5cGUuaW5kZXhPZigna2V5JykmJlwiICtcbiAgICAoa2V5cy5tYXAoZ2VuRmlsdGVyQ29kZSkuam9pbignJiYnKSkgKyBcIilyZXR1cm4gbnVsbDtcIlxuICApXG59XG5cbmZ1bmN0aW9uIGdlbkZpbHRlckNvZGUgKGtleSkge1xuICB2YXIga2V5VmFsID0gcGFyc2VJbnQoa2V5LCAxMCk7XG4gIGlmIChrZXlWYWwpIHtcbiAgICByZXR1cm4gKFwiJGV2ZW50LmtleUNvZGUhPT1cIiArIGtleVZhbClcbiAgfVxuICB2YXIga2V5Q29kZSA9IGtleUNvZGVzW2tleV07XG4gIHZhciBrZXlOYW1lID0ga2V5TmFtZXNba2V5XTtcbiAgcmV0dXJuIChcbiAgICBcIl9rKCRldmVudC5rZXlDb2RlLFwiICtcbiAgICAoSlNPTi5zdHJpbmdpZnkoa2V5KSkgKyBcIixcIiArXG4gICAgKEpTT04uc3RyaW5naWZ5KGtleUNvZGUpKSArIFwiLFwiICtcbiAgICBcIiRldmVudC5rZXksXCIgK1xuICAgIFwiXCIgKyAoSlNPTi5zdHJpbmdpZnkoa2V5TmFtZSkpICtcbiAgICBcIilcIlxuICApXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBvbiAoZWwsIGRpcikge1xuICBpZiAoZGlyLm1vZGlmaWVycykge1xuICAgIHdhcm4oXCJ2LW9uIHdpdGhvdXQgYXJndW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmllcnMuXCIpO1xuICB9XG4gIGVsLndyYXBMaXN0ZW5lcnMgPSBmdW5jdGlvbiAoY29kZSkgeyByZXR1cm4gKFwiX2coXCIgKyBjb2RlICsgXCIsXCIgKyAoZGlyLnZhbHVlKSArIFwiKVwiKTsgfTtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGJpbmQkMSAoZWwsIGRpcikge1xuICBlbC53cmFwRGF0YSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgcmV0dXJuIChcIl9iKFwiICsgY29kZSArIFwiLCdcIiArIChlbC50YWcpICsgXCInLFwiICsgKGRpci52YWx1ZSkgKyBcIixcIiArIChkaXIubW9kaWZpZXJzICYmIGRpci5tb2RpZmllcnMucHJvcCA/ICd0cnVlJyA6ICdmYWxzZScpICsgKGRpci5tb2RpZmllcnMgJiYgZGlyLm1vZGlmaWVycy5zeW5jID8gJyx0cnVlJyA6ICcnKSArIFwiKVwiKVxuICB9O1xufVxuXG4vKiAgKi9cblxudmFyIGJhc2VEaXJlY3RpdmVzID0ge1xuICBvbjogb24sXG4gIGJpbmQ6IGJpbmQkMSxcbiAgY2xvYWs6IG5vb3Bcbn07XG5cbi8qICAqL1xuXG5cblxuXG5cbnZhciBDb2RlZ2VuU3RhdGUgPSBmdW5jdGlvbiBDb2RlZ2VuU3RhdGUgKG9wdGlvbnMpIHtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgdGhpcy53YXJuID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuO1xuICB0aGlzLnRyYW5zZm9ybXMgPSBwbHVja01vZHVsZUZ1bmN0aW9uKG9wdGlvbnMubW9kdWxlcywgJ3RyYW5zZm9ybUNvZGUnKTtcbiAgdGhpcy5kYXRhR2VuRm5zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICdnZW5EYXRhJyk7XG4gIHRoaXMuZGlyZWN0aXZlcyA9IGV4dGVuZChleHRlbmQoe30sIGJhc2VEaXJlY3RpdmVzKSwgb3B0aW9ucy5kaXJlY3RpdmVzKTtcbiAgdmFyIGlzUmVzZXJ2ZWRUYWcgPSBvcHRpb25zLmlzUmVzZXJ2ZWRUYWcgfHwgbm87XG4gIHRoaXMubWF5YmVDb21wb25lbnQgPSBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuICEhZWwuY29tcG9uZW50IHx8ICFpc1Jlc2VydmVkVGFnKGVsLnRhZyk7IH07XG4gIHRoaXMub25jZUlkID0gMDtcbiAgdGhpcy5zdGF0aWNSZW5kZXJGbnMgPSBbXTtcbiAgdGhpcy5wcmUgPSBmYWxzZTtcbn07XG5cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZSAoXG4gIGFzdCxcbiAgb3B0aW9uc1xuKSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBDb2RlZ2VuU3RhdGUob3B0aW9ucyk7XG4gIHZhciBjb2RlID0gYXN0ID8gZ2VuRWxlbWVudChhc3QsIHN0YXRlKSA6ICdfYyhcImRpdlwiKSc7XG4gIHJldHVybiB7XG4gICAgcmVuZGVyOiAoXCJ3aXRoKHRoaXMpe3JldHVybiBcIiArIGNvZGUgKyBcIn1cIiksXG4gICAgc3RhdGljUmVuZGVyRm5zOiBzdGF0ZS5zdGF0aWNSZW5kZXJGbnNcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5FbGVtZW50IChlbCwgc3RhdGUpIHtcbiAgaWYgKGVsLnBhcmVudCkge1xuICAgIGVsLnByZSA9IGVsLnByZSB8fCBlbC5wYXJlbnQucHJlO1xuICB9XG5cbiAgaWYgKGVsLnN0YXRpY1Jvb3QgJiYgIWVsLnN0YXRpY1Byb2Nlc3NlZCkge1xuICAgIHJldHVybiBnZW5TdGF0aWMoZWwsIHN0YXRlKVxuICB9IGVsc2UgaWYgKGVsLm9uY2UgJiYgIWVsLm9uY2VQcm9jZXNzZWQpIHtcbiAgICByZXR1cm4gZ2VuT25jZShlbCwgc3RhdGUpXG4gIH0gZWxzZSBpZiAoZWwuZm9yICYmICFlbC5mb3JQcm9jZXNzZWQpIHtcbiAgICByZXR1cm4gZ2VuRm9yKGVsLCBzdGF0ZSlcbiAgfSBlbHNlIGlmIChlbC5pZiAmJiAhZWwuaWZQcm9jZXNzZWQpIHtcbiAgICByZXR1cm4gZ2VuSWYoZWwsIHN0YXRlKVxuICB9IGVsc2UgaWYgKGVsLnRhZyA9PT0gJ3RlbXBsYXRlJyAmJiAhZWwuc2xvdFRhcmdldCAmJiAhc3RhdGUucHJlKSB7XG4gICAgcmV0dXJuIGdlbkNoaWxkcmVuKGVsLCBzdGF0ZSkgfHwgJ3ZvaWQgMCdcbiAgfSBlbHNlIGlmIChlbC50YWcgPT09ICdzbG90Jykge1xuICAgIHJldHVybiBnZW5TbG90KGVsLCBzdGF0ZSlcbiAgfSBlbHNlIHtcbiAgICAvLyBjb21wb25lbnQgb3IgZWxlbWVudFxuICAgIHZhciBjb2RlO1xuICAgIGlmIChlbC5jb21wb25lbnQpIHtcbiAgICAgIGNvZGUgPSBnZW5Db21wb25lbnQoZWwuY29tcG9uZW50LCBlbCwgc3RhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZGF0YTtcbiAgICAgIGlmICghZWwucGxhaW4gfHwgKGVsLnByZSAmJiBzdGF0ZS5tYXliZUNvbXBvbmVudChlbCkpKSB7XG4gICAgICAgIGRhdGEgPSBnZW5EYXRhJDIoZWwsIHN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNoaWxkcmVuID0gZWwuaW5saW5lVGVtcGxhdGUgPyBudWxsIDogZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlLCB0cnVlKTtcbiAgICAgIGNvZGUgPSBcIl9jKCdcIiArIChlbC50YWcpICsgXCInXCIgKyAoZGF0YSA/IChcIixcIiArIGRhdGEpIDogJycpICsgKGNoaWxkcmVuID8gKFwiLFwiICsgY2hpbGRyZW4pIDogJycpICsgXCIpXCI7XG4gICAgfVxuICAgIC8vIG1vZHVsZSB0cmFuc2Zvcm1zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS50cmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb2RlID0gc3RhdGUudHJhbnNmb3Jtc1tpXShlbCwgY29kZSk7XG4gICAgfVxuICAgIHJldHVybiBjb2RlXG4gIH1cbn1cblxuLy8gaG9pc3Qgc3RhdGljIHN1Yi10cmVlcyBvdXRcbmZ1bmN0aW9uIGdlblN0YXRpYyAoZWwsIHN0YXRlKSB7XG4gIGVsLnN0YXRpY1Byb2Nlc3NlZCA9IHRydWU7XG4gIC8vIFNvbWUgZWxlbWVudHMgKHRlbXBsYXRlcykgbmVlZCB0byBiZWhhdmUgZGlmZmVyZW50bHkgaW5zaWRlIG9mIGEgdi1wcmVcbiAgLy8gbm9kZS4gIEFsbCBwcmUgbm9kZXMgYXJlIHN0YXRpYyByb290cywgc28gd2UgY2FuIHVzZSB0aGlzIGFzIGEgbG9jYXRpb24gdG9cbiAgLy8gd3JhcCBhIHN0YXRlIGNoYW5nZSBhbmQgcmVzZXQgaXQgdXBvbiBleGl0aW5nIHRoZSBwcmUgbm9kZS5cbiAgdmFyIG9yaWdpbmFsUHJlU3RhdGUgPSBzdGF0ZS5wcmU7XG4gIGlmIChlbC5wcmUpIHtcbiAgICBzdGF0ZS5wcmUgPSBlbC5wcmU7XG4gIH1cbiAgc3RhdGUuc3RhdGljUmVuZGVyRm5zLnB1c2goKFwid2l0aCh0aGlzKXtyZXR1cm4gXCIgKyAoZ2VuRWxlbWVudChlbCwgc3RhdGUpKSArIFwifVwiKSk7XG4gIHN0YXRlLnByZSA9IG9yaWdpbmFsUHJlU3RhdGU7XG4gIHJldHVybiAoXCJfbShcIiArIChzdGF0ZS5zdGF0aWNSZW5kZXJGbnMubGVuZ3RoIC0gMSkgKyAoZWwuc3RhdGljSW5Gb3IgPyAnLHRydWUnIDogJycpICsgXCIpXCIpXG59XG5cbi8vIHYtb25jZVxuZnVuY3Rpb24gZ2VuT25jZSAoZWwsIHN0YXRlKSB7XG4gIGVsLm9uY2VQcm9jZXNzZWQgPSB0cnVlO1xuICBpZiAoZWwuaWYgJiYgIWVsLmlmUHJvY2Vzc2VkKSB7XG4gICAgcmV0dXJuIGdlbklmKGVsLCBzdGF0ZSlcbiAgfSBlbHNlIGlmIChlbC5zdGF0aWNJbkZvcikge1xuICAgIHZhciBrZXkgPSAnJztcbiAgICB2YXIgcGFyZW50ID0gZWwucGFyZW50O1xuICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgIGlmIChwYXJlbnQuZm9yKSB7XG4gICAgICAgIGtleSA9IHBhcmVudC5rZXk7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICAgIH1cbiAgICBpZiAoIWtleSkge1xuICAgICAgc3RhdGUud2FybihcbiAgICAgICAgXCJ2LW9uY2UgY2FuIG9ubHkgYmUgdXNlZCBpbnNpZGUgdi1mb3IgdGhhdCBpcyBrZXllZC4gXCIsXG4gICAgICAgIGVsLnJhd0F0dHJzTWFwWyd2LW9uY2UnXVxuICAgICAgKTtcbiAgICAgIHJldHVybiBnZW5FbGVtZW50KGVsLCBzdGF0ZSlcbiAgICB9XG4gICAgcmV0dXJuIChcIl9vKFwiICsgKGdlbkVsZW1lbnQoZWwsIHN0YXRlKSkgKyBcIixcIiArIChzdGF0ZS5vbmNlSWQrKykgKyBcIixcIiArIGtleSArIFwiKVwiKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBnZW5TdGF0aWMoZWwsIHN0YXRlKVxuICB9XG59XG5cbmZ1bmN0aW9uIGdlbklmIChcbiAgZWwsXG4gIHN0YXRlLFxuICBhbHRHZW4sXG4gIGFsdEVtcHR5XG4pIHtcbiAgZWwuaWZQcm9jZXNzZWQgPSB0cnVlOyAvLyBhdm9pZCByZWN1cnNpb25cbiAgcmV0dXJuIGdlbklmQ29uZGl0aW9ucyhlbC5pZkNvbmRpdGlvbnMuc2xpY2UoKSwgc3RhdGUsIGFsdEdlbiwgYWx0RW1wdHkpXG59XG5cbmZ1bmN0aW9uIGdlbklmQ29uZGl0aW9ucyAoXG4gIGNvbmRpdGlvbnMsXG4gIHN0YXRlLFxuICBhbHRHZW4sXG4gIGFsdEVtcHR5XG4pIHtcbiAgaWYgKCFjb25kaXRpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBhbHRFbXB0eSB8fCAnX2UoKSdcbiAgfVxuXG4gIHZhciBjb25kaXRpb24gPSBjb25kaXRpb25zLnNoaWZ0KCk7XG4gIGlmIChjb25kaXRpb24uZXhwKSB7XG4gICAgcmV0dXJuIChcIihcIiArIChjb25kaXRpb24uZXhwKSArIFwiKT9cIiArIChnZW5UZXJuYXJ5RXhwKGNvbmRpdGlvbi5ibG9jaykpICsgXCI6XCIgKyAoZ2VuSWZDb25kaXRpb25zKGNvbmRpdGlvbnMsIHN0YXRlLCBhbHRHZW4sIGFsdEVtcHR5KSkpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChcIlwiICsgKGdlblRlcm5hcnlFeHAoY29uZGl0aW9uLmJsb2NrKSkpXG4gIH1cblxuICAvLyB2LWlmIHdpdGggdi1vbmNlIHNob3VsZCBnZW5lcmF0ZSBjb2RlIGxpa2UgKGEpP19tKDApOl9tKDEpXG4gIGZ1bmN0aW9uIGdlblRlcm5hcnlFeHAgKGVsKSB7XG4gICAgcmV0dXJuIGFsdEdlblxuICAgICAgPyBhbHRHZW4oZWwsIHN0YXRlKVxuICAgICAgOiBlbC5vbmNlXG4gICAgICAgID8gZ2VuT25jZShlbCwgc3RhdGUpXG4gICAgICAgIDogZ2VuRWxlbWVudChlbCwgc3RhdGUpXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuRm9yIChcbiAgZWwsXG4gIHN0YXRlLFxuICBhbHRHZW4sXG4gIGFsdEhlbHBlclxuKSB7XG4gIHZhciBleHAgPSBlbC5mb3I7XG4gIHZhciBhbGlhcyA9IGVsLmFsaWFzO1xuICB2YXIgaXRlcmF0b3IxID0gZWwuaXRlcmF0b3IxID8gKFwiLFwiICsgKGVsLml0ZXJhdG9yMSkpIDogJyc7XG4gIHZhciBpdGVyYXRvcjIgPSBlbC5pdGVyYXRvcjIgPyAoXCIsXCIgKyAoZWwuaXRlcmF0b3IyKSkgOiAnJztcblxuICBpZiAoc3RhdGUubWF5YmVDb21wb25lbnQoZWwpICYmXG4gICAgZWwudGFnICE9PSAnc2xvdCcgJiZcbiAgICBlbC50YWcgIT09ICd0ZW1wbGF0ZScgJiZcbiAgICAhZWwua2V5XG4gICkge1xuICAgIHN0YXRlLndhcm4oXG4gICAgICBcIjxcIiArIChlbC50YWcpICsgXCIgdi1mb3I9XFxcIlwiICsgYWxpYXMgKyBcIiBpbiBcIiArIGV4cCArIFwiXFxcIj46IGNvbXBvbmVudCBsaXN0cyByZW5kZXJlZCB3aXRoIFwiICtcbiAgICAgIFwidi1mb3Igc2hvdWxkIGhhdmUgZXhwbGljaXQga2V5cy4gXCIgK1xuICAgICAgXCJTZWUgaHR0cHM6Ly92dWVqcy5vcmcvZ3VpZGUvbGlzdC5odG1sI2tleSBmb3IgbW9yZSBpbmZvLlwiLFxuICAgICAgZWwucmF3QXR0cnNNYXBbJ3YtZm9yJ10sXG4gICAgICB0cnVlIC8qIHRpcCAqL1xuICAgICk7XG4gIH1cblxuICBlbC5mb3JQcm9jZXNzZWQgPSB0cnVlOyAvLyBhdm9pZCByZWN1cnNpb25cbiAgcmV0dXJuIChhbHRIZWxwZXIgfHwgJ19sJykgKyBcIigoXCIgKyBleHAgKyBcIiksXCIgK1xuICAgIFwiZnVuY3Rpb24oXCIgKyBhbGlhcyArIGl0ZXJhdG9yMSArIGl0ZXJhdG9yMiArIFwiKXtcIiArXG4gICAgICBcInJldHVybiBcIiArICgoYWx0R2VuIHx8IGdlbkVsZW1lbnQpKGVsLCBzdGF0ZSkpICtcbiAgICAnfSknXG59XG5cbmZ1bmN0aW9uIGdlbkRhdGEkMiAoZWwsIHN0YXRlKSB7XG4gIHZhciBkYXRhID0gJ3snO1xuXG4gIC8vIGRpcmVjdGl2ZXMgZmlyc3QuXG4gIC8vIGRpcmVjdGl2ZXMgbWF5IG11dGF0ZSB0aGUgZWwncyBvdGhlciBwcm9wZXJ0aWVzIGJlZm9yZSB0aGV5IGFyZSBnZW5lcmF0ZWQuXG4gIHZhciBkaXJzID0gZ2VuRGlyZWN0aXZlcyhlbCwgc3RhdGUpO1xuICBpZiAoZGlycykgeyBkYXRhICs9IGRpcnMgKyAnLCc7IH1cblxuICAvLyBrZXlcbiAgaWYgKGVsLmtleSkge1xuICAgIGRhdGEgKz0gXCJrZXk6XCIgKyAoZWwua2V5KSArIFwiLFwiO1xuICB9XG4gIC8vIHJlZlxuICBpZiAoZWwucmVmKSB7XG4gICAgZGF0YSArPSBcInJlZjpcIiArIChlbC5yZWYpICsgXCIsXCI7XG4gIH1cbiAgaWYgKGVsLnJlZkluRm9yKSB7XG4gICAgZGF0YSArPSBcInJlZkluRm9yOnRydWUsXCI7XG4gIH1cbiAgLy8gcHJlXG4gIGlmIChlbC5wcmUpIHtcbiAgICBkYXRhICs9IFwicHJlOnRydWUsXCI7XG4gIH1cbiAgLy8gcmVjb3JkIG9yaWdpbmFsIHRhZyBuYW1lIGZvciBjb21wb25lbnRzIHVzaW5nIFwiaXNcIiBhdHRyaWJ1dGVcbiAgaWYgKGVsLmNvbXBvbmVudCkge1xuICAgIGRhdGEgKz0gXCJ0YWc6XFxcIlwiICsgKGVsLnRhZykgKyBcIlxcXCIsXCI7XG4gIH1cbiAgLy8gbW9kdWxlIGRhdGEgZ2VuZXJhdGlvbiBmdW5jdGlvbnNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5kYXRhR2VuRm5zLmxlbmd0aDsgaSsrKSB7XG4gICAgZGF0YSArPSBzdGF0ZS5kYXRhR2VuRm5zW2ldKGVsKTtcbiAgfVxuICAvLyBhdHRyaWJ1dGVzXG4gIGlmIChlbC5hdHRycykge1xuICAgIGRhdGEgKz0gXCJhdHRyczpcIiArIChnZW5Qcm9wcyhlbC5hdHRycykpICsgXCIsXCI7XG4gIH1cbiAgLy8gRE9NIHByb3BzXG4gIGlmIChlbC5wcm9wcykge1xuICAgIGRhdGEgKz0gXCJkb21Qcm9wczpcIiArIChnZW5Qcm9wcyhlbC5wcm9wcykpICsgXCIsXCI7XG4gIH1cbiAgLy8gZXZlbnQgaGFuZGxlcnNcbiAgaWYgKGVsLmV2ZW50cykge1xuICAgIGRhdGEgKz0gKGdlbkhhbmRsZXJzKGVsLmV2ZW50cywgZmFsc2UpKSArIFwiLFwiO1xuICB9XG4gIGlmIChlbC5uYXRpdmVFdmVudHMpIHtcbiAgICBkYXRhICs9IChnZW5IYW5kbGVycyhlbC5uYXRpdmVFdmVudHMsIHRydWUpKSArIFwiLFwiO1xuICB9XG4gIC8vIHNsb3QgdGFyZ2V0XG4gIC8vIG9ubHkgZm9yIG5vbi1zY29wZWQgc2xvdHNcbiAgaWYgKGVsLnNsb3RUYXJnZXQgJiYgIWVsLnNsb3RTY29wZSkge1xuICAgIGRhdGEgKz0gXCJzbG90OlwiICsgKGVsLnNsb3RUYXJnZXQpICsgXCIsXCI7XG4gIH1cbiAgLy8gc2NvcGVkIHNsb3RzXG4gIGlmIChlbC5zY29wZWRTbG90cykge1xuICAgIGRhdGEgKz0gKGdlblNjb3BlZFNsb3RzKGVsLCBlbC5zY29wZWRTbG90cywgc3RhdGUpKSArIFwiLFwiO1xuICB9XG4gIC8vIGNvbXBvbmVudCB2LW1vZGVsXG4gIGlmIChlbC5tb2RlbCkge1xuICAgIGRhdGEgKz0gXCJtb2RlbDp7dmFsdWU6XCIgKyAoZWwubW9kZWwudmFsdWUpICsgXCIsY2FsbGJhY2s6XCIgKyAoZWwubW9kZWwuY2FsbGJhY2spICsgXCIsZXhwcmVzc2lvbjpcIiArIChlbC5tb2RlbC5leHByZXNzaW9uKSArIFwifSxcIjtcbiAgfVxuICAvLyBpbmxpbmUtdGVtcGxhdGVcbiAgaWYgKGVsLmlubGluZVRlbXBsYXRlKSB7XG4gICAgdmFyIGlubGluZVRlbXBsYXRlID0gZ2VuSW5saW5lVGVtcGxhdGUoZWwsIHN0YXRlKTtcbiAgICBpZiAoaW5saW5lVGVtcGxhdGUpIHtcbiAgICAgIGRhdGEgKz0gaW5saW5lVGVtcGxhdGUgKyBcIixcIjtcbiAgICB9XG4gIH1cbiAgZGF0YSA9IGRhdGEucmVwbGFjZSgvLCQvLCAnJykgKyAnfSc7XG4gIC8vIHYtYmluZCBkeW5hbWljIGFyZ3VtZW50IHdyYXBcbiAgLy8gdi1iaW5kIHdpdGggZHluYW1pYyBhcmd1bWVudHMgbXVzdCBiZSBhcHBsaWVkIHVzaW5nIHRoZSBzYW1lIHYtYmluZCBvYmplY3RcbiAgLy8gbWVyZ2UgaGVscGVyIHNvIHRoYXQgY2xhc3Mvc3R5bGUvbXVzdFVzZVByb3AgYXR0cnMgYXJlIGhhbmRsZWQgY29ycmVjdGx5LlxuICBpZiAoZWwuZHluYW1pY0F0dHJzKSB7XG4gICAgZGF0YSA9IFwiX2IoXCIgKyBkYXRhICsgXCIsXFxcIlwiICsgKGVsLnRhZykgKyBcIlxcXCIsXCIgKyAoZ2VuUHJvcHMoZWwuZHluYW1pY0F0dHJzKSkgKyBcIilcIjtcbiAgfVxuICAvLyB2LWJpbmQgZGF0YSB3cmFwXG4gIGlmIChlbC53cmFwRGF0YSkge1xuICAgIGRhdGEgPSBlbC53cmFwRGF0YShkYXRhKTtcbiAgfVxuICAvLyB2LW9uIGRhdGEgd3JhcFxuICBpZiAoZWwud3JhcExpc3RlbmVycykge1xuICAgIGRhdGEgPSBlbC53cmFwTGlzdGVuZXJzKGRhdGEpO1xuICB9XG4gIHJldHVybiBkYXRhXG59XG5cbmZ1bmN0aW9uIGdlbkRpcmVjdGl2ZXMgKGVsLCBzdGF0ZSkge1xuICB2YXIgZGlycyA9IGVsLmRpcmVjdGl2ZXM7XG4gIGlmICghZGlycykgeyByZXR1cm4gfVxuICB2YXIgcmVzID0gJ2RpcmVjdGl2ZXM6Wyc7XG4gIHZhciBoYXNSdW50aW1lID0gZmFsc2U7XG4gIHZhciBpLCBsLCBkaXIsIG5lZWRSdW50aW1lO1xuICBmb3IgKGkgPSAwLCBsID0gZGlycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBkaXIgPSBkaXJzW2ldO1xuICAgIG5lZWRSdW50aW1lID0gdHJ1ZTtcbiAgICB2YXIgZ2VuID0gc3RhdGUuZGlyZWN0aXZlc1tkaXIubmFtZV07XG4gICAgaWYgKGdlbikge1xuICAgICAgLy8gY29tcGlsZS10aW1lIGRpcmVjdGl2ZSB0aGF0IG1hbmlwdWxhdGVzIEFTVC5cbiAgICAgIC8vIHJldHVybnMgdHJ1ZSBpZiBpdCBhbHNvIG5lZWRzIGEgcnVudGltZSBjb3VudGVycGFydC5cbiAgICAgIG5lZWRSdW50aW1lID0gISFnZW4oZWwsIGRpciwgc3RhdGUud2Fybik7XG4gICAgfVxuICAgIGlmIChuZWVkUnVudGltZSkge1xuICAgICAgaGFzUnVudGltZSA9IHRydWU7XG4gICAgICByZXMgKz0gXCJ7bmFtZTpcXFwiXCIgKyAoZGlyLm5hbWUpICsgXCJcXFwiLHJhd05hbWU6XFxcIlwiICsgKGRpci5yYXdOYW1lKSArIFwiXFxcIlwiICsgKGRpci52YWx1ZSA/IChcIix2YWx1ZTooXCIgKyAoZGlyLnZhbHVlKSArIFwiKSxleHByZXNzaW9uOlwiICsgKEpTT04uc3RyaW5naWZ5KGRpci52YWx1ZSkpKSA6ICcnKSArIChkaXIuYXJnID8gKFwiLGFyZzpcIiArIChkaXIuaXNEeW5hbWljQXJnID8gZGlyLmFyZyA6IChcIlxcXCJcIiArIChkaXIuYXJnKSArIFwiXFxcIlwiKSkpIDogJycpICsgKGRpci5tb2RpZmllcnMgPyAoXCIsbW9kaWZpZXJzOlwiICsgKEpTT04uc3RyaW5naWZ5KGRpci5tb2RpZmllcnMpKSkgOiAnJykgKyBcIn0sXCI7XG4gICAgfVxuICB9XG4gIGlmIChoYXNSdW50aW1lKSB7XG4gICAgcmV0dXJuIHJlcy5zbGljZSgwLCAtMSkgKyAnXSdcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5JbmxpbmVUZW1wbGF0ZSAoZWwsIHN0YXRlKSB7XG4gIHZhciBhc3QgPSBlbC5jaGlsZHJlblswXTtcbiAgaWYgKGVsLmNoaWxkcmVuLmxlbmd0aCAhPT0gMSB8fCBhc3QudHlwZSAhPT0gMSkge1xuICAgIHN0YXRlLndhcm4oXG4gICAgICAnSW5saW5lLXRlbXBsYXRlIGNvbXBvbmVudHMgbXVzdCBoYXZlIGV4YWN0bHkgb25lIGNoaWxkIGVsZW1lbnQuJyxcbiAgICAgIHsgc3RhcnQ6IGVsLnN0YXJ0IH1cbiAgICApO1xuICB9XG4gIGlmIChhc3QgJiYgYXN0LnR5cGUgPT09IDEpIHtcbiAgICB2YXIgaW5saW5lUmVuZGVyRm5zID0gZ2VuZXJhdGUoYXN0LCBzdGF0ZS5vcHRpb25zKTtcbiAgICByZXR1cm4gKFwiaW5saW5lVGVtcGxhdGU6e3JlbmRlcjpmdW5jdGlvbigpe1wiICsgKGlubGluZVJlbmRlckZucy5yZW5kZXIpICsgXCJ9LHN0YXRpY1JlbmRlckZuczpbXCIgKyAoaW5saW5lUmVuZGVyRm5zLnN0YXRpY1JlbmRlckZucy5tYXAoZnVuY3Rpb24gKGNvZGUpIHsgcmV0dXJuIChcImZ1bmN0aW9uKCl7XCIgKyBjb2RlICsgXCJ9XCIpOyB9KS5qb2luKCcsJykpICsgXCJdfVwiKVxuICB9XG59XG5cbmZ1bmN0aW9uIGdlblNjb3BlZFNsb3RzIChcbiAgZWwsXG4gIHNsb3RzLFxuICBzdGF0ZVxuKSB7XG4gIC8vIGJ5IGRlZmF1bHQgc2NvcGVkIHNsb3RzIGFyZSBjb25zaWRlcmVkIFwic3RhYmxlXCIsIHRoaXMgYWxsb3dzIGNoaWxkXG4gIC8vIGNvbXBvbmVudHMgd2l0aCBvbmx5IHNjb3BlZCBzbG90cyB0byBza2lwIGZvcmNlZCB1cGRhdGVzIGZyb20gcGFyZW50LlxuICAvLyBidXQgaW4gc29tZSBjYXNlcyB3ZSBoYXZlIHRvIGJhaWwtb3V0IG9mIHRoaXMgb3B0aW1pemF0aW9uXG4gIC8vIGZvciBleGFtcGxlIGlmIHRoZSBzbG90IGNvbnRhaW5zIGR5bmFtaWMgbmFtZXMsIGhhcyB2LWlmIG9yIHYtZm9yIG9uIHRoZW0uLi5cbiAgdmFyIG5lZWRzRm9yY2VVcGRhdGUgPSBlbC5mb3IgfHwgT2JqZWN0LmtleXMoc2xvdHMpLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBzbG90ID0gc2xvdHNba2V5XTtcbiAgICByZXR1cm4gKFxuICAgICAgc2xvdC5zbG90VGFyZ2V0RHluYW1pYyB8fFxuICAgICAgc2xvdC5pZiB8fFxuICAgICAgc2xvdC5mb3IgfHxcbiAgICAgIGNvbnRhaW5zU2xvdENoaWxkKHNsb3QpIC8vIGlzIHBhc3NpbmcgZG93biBzbG90IGZyb20gcGFyZW50IHdoaWNoIG1heSBiZSBkeW5hbWljXG4gICAgKVxuICB9KTtcblxuICAvLyAjOTUzNDogaWYgYSBjb21wb25lbnQgd2l0aCBzY29wZWQgc2xvdHMgaXMgaW5zaWRlIGEgY29uZGl0aW9uYWwgYnJhbmNoLFxuICAvLyBpdCdzIHBvc3NpYmxlIGZvciB0aGUgc2FtZSBjb21wb25lbnQgdG8gYmUgcmV1c2VkIGJ1dCB3aXRoIGRpZmZlcmVudFxuICAvLyBjb21waWxlZCBzbG90IGNvbnRlbnQuIFRvIGF2b2lkIHRoYXQsIHdlIGdlbmVyYXRlIGEgdW5pcXVlIGtleSBiYXNlZCBvblxuICAvLyB0aGUgZ2VuZXJhdGVkIGNvZGUgb2YgYWxsIHRoZSBzbG90IGNvbnRlbnRzLlxuICB2YXIgbmVlZHNLZXkgPSAhIWVsLmlmO1xuXG4gIC8vIE9SIHdoZW4gaXQgaXMgaW5zaWRlIGFub3RoZXIgc2NvcGVkIHNsb3Qgb3Igdi1mb3IgKHRoZSByZWFjdGl2aXR5IG1heSBiZVxuICAvLyBkaXNjb25uZWN0ZWQgZHVlIHRvIHRoZSBpbnRlcm1lZGlhdGUgc2NvcGUgdmFyaWFibGUpXG4gIC8vICM5NDM4LCAjOTUwNlxuICAvLyBUT0RPOiB0aGlzIGNhbiBiZSBmdXJ0aGVyIG9wdGltaXplZCBieSBwcm9wZXJseSBhbmFseXppbmcgaW4tc2NvcGUgYmluZGluZ3NcbiAgLy8gYW5kIHNraXAgZm9yY2UgdXBkYXRpbmcgb25lcyB0aGF0IGRvIG5vdCBhY3R1YWxseSB1c2Ugc2NvcGUgdmFyaWFibGVzLlxuICBpZiAoIW5lZWRzRm9yY2VVcGRhdGUpIHtcbiAgICB2YXIgcGFyZW50ID0gZWwucGFyZW50O1xuICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgIGlmIChcbiAgICAgICAgKHBhcmVudC5zbG90U2NvcGUgJiYgcGFyZW50LnNsb3RTY29wZSAhPT0gZW1wdHlTbG90U2NvcGVUb2tlbikgfHxcbiAgICAgICAgcGFyZW50LmZvclxuICAgICAgKSB7XG4gICAgICAgIG5lZWRzRm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgaWYgKHBhcmVudC5pZikge1xuICAgICAgICBuZWVkc0tleSA9IHRydWU7XG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICAgIH1cbiAgfVxuXG4gIHZhciBnZW5lcmF0ZWRTbG90cyA9IE9iamVjdC5rZXlzKHNsb3RzKVxuICAgIC5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZ2VuU2NvcGVkU2xvdChzbG90c1trZXldLCBzdGF0ZSk7IH0pXG4gICAgLmpvaW4oJywnKTtcblxuICByZXR1cm4gKFwic2NvcGVkU2xvdHM6X3UoW1wiICsgZ2VuZXJhdGVkU2xvdHMgKyBcIl1cIiArIChuZWVkc0ZvcmNlVXBkYXRlID8gXCIsbnVsbCx0cnVlXCIgOiBcIlwiKSArICghbmVlZHNGb3JjZVVwZGF0ZSAmJiBuZWVkc0tleSA/IChcIixudWxsLGZhbHNlLFwiICsgKGhhc2goZ2VuZXJhdGVkU2xvdHMpKSkgOiBcIlwiKSArIFwiKVwiKVxufVxuXG5mdW5jdGlvbiBoYXNoKHN0cikge1xuICB2YXIgaGFzaCA9IDUzODE7XG4gIHZhciBpID0gc3RyLmxlbmd0aDtcbiAgd2hpbGUoaSkge1xuICAgIGhhc2ggPSAoaGFzaCAqIDMzKSBeIHN0ci5jaGFyQ29kZUF0KC0taSk7XG4gIH1cbiAgcmV0dXJuIGhhc2ggPj4+IDBcbn1cblxuZnVuY3Rpb24gY29udGFpbnNTbG90Q2hpbGQgKGVsKSB7XG4gIGlmIChlbC50eXBlID09PSAxKSB7XG4gICAgaWYgKGVsLnRhZyA9PT0gJ3Nsb3QnKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICByZXR1cm4gZWwuY2hpbGRyZW4uc29tZShjb250YWluc1Nsb3RDaGlsZClcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gZ2VuU2NvcGVkU2xvdCAoXG4gIGVsLFxuICBzdGF0ZVxuKSB7XG4gIHZhciBpc0xlZ2FjeVN5bnRheCA9IGVsLmF0dHJzTWFwWydzbG90LXNjb3BlJ107XG4gIGlmIChlbC5pZiAmJiAhZWwuaWZQcm9jZXNzZWQgJiYgIWlzTGVnYWN5U3ludGF4KSB7XG4gICAgcmV0dXJuIGdlbklmKGVsLCBzdGF0ZSwgZ2VuU2NvcGVkU2xvdCwgXCJudWxsXCIpXG4gIH1cbiAgaWYgKGVsLmZvciAmJiAhZWwuZm9yUHJvY2Vzc2VkKSB7XG4gICAgcmV0dXJuIGdlbkZvcihlbCwgc3RhdGUsIGdlblNjb3BlZFNsb3QpXG4gIH1cbiAgdmFyIHNsb3RTY29wZSA9IGVsLnNsb3RTY29wZSA9PT0gZW1wdHlTbG90U2NvcGVUb2tlblxuICAgID8gXCJcIlxuICAgIDogU3RyaW5nKGVsLnNsb3RTY29wZSk7XG4gIHZhciBmbiA9IFwiZnVuY3Rpb24oXCIgKyBzbG90U2NvcGUgKyBcIil7XCIgK1xuICAgIFwicmV0dXJuIFwiICsgKGVsLnRhZyA9PT0gJ3RlbXBsYXRlJ1xuICAgICAgPyBlbC5pZiAmJiBpc0xlZ2FjeVN5bnRheFxuICAgICAgICA/IChcIihcIiArIChlbC5pZikgKyBcIik/XCIgKyAoZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlKSB8fCAndW5kZWZpbmVkJykgKyBcIjp1bmRlZmluZWRcIilcbiAgICAgICAgOiBnZW5DaGlsZHJlbihlbCwgc3RhdGUpIHx8ICd1bmRlZmluZWQnXG4gICAgICA6IGdlbkVsZW1lbnQoZWwsIHN0YXRlKSkgKyBcIn1cIjtcbiAgLy8gcmV2ZXJzZSBwcm94eSB2LXNsb3Qgd2l0aG91dCBzY29wZSBvbiB0aGlzLiRzbG90c1xuICB2YXIgcmV2ZXJzZVByb3h5ID0gc2xvdFNjb3BlID8gXCJcIiA6IFwiLHByb3h5OnRydWVcIjtcbiAgcmV0dXJuIChcIntrZXk6XCIgKyAoZWwuc2xvdFRhcmdldCB8fCBcIlxcXCJkZWZhdWx0XFxcIlwiKSArIFwiLGZuOlwiICsgZm4gKyByZXZlcnNlUHJveHkgKyBcIn1cIilcbn1cblxuZnVuY3Rpb24gZ2VuQ2hpbGRyZW4gKFxuICBlbCxcbiAgc3RhdGUsXG4gIGNoZWNrU2tpcCxcbiAgYWx0R2VuRWxlbWVudCxcbiAgYWx0R2VuTm9kZVxuKSB7XG4gIHZhciBjaGlsZHJlbiA9IGVsLmNoaWxkcmVuO1xuICBpZiAoY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgdmFyIGVsJDEgPSBjaGlsZHJlblswXTtcbiAgICAvLyBvcHRpbWl6ZSBzaW5nbGUgdi1mb3JcbiAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmXG4gICAgICBlbCQxLmZvciAmJlxuICAgICAgZWwkMS50YWcgIT09ICd0ZW1wbGF0ZScgJiZcbiAgICAgIGVsJDEudGFnICE9PSAnc2xvdCdcbiAgICApIHtcbiAgICAgIHZhciBub3JtYWxpemF0aW9uVHlwZSA9IGNoZWNrU2tpcFxuICAgICAgICA/IHN0YXRlLm1heWJlQ29tcG9uZW50KGVsJDEpID8gXCIsMVwiIDogXCIsMFwiXG4gICAgICAgIDogXCJcIjtcbiAgICAgIHJldHVybiAoXCJcIiArICgoYWx0R2VuRWxlbWVudCB8fCBnZW5FbGVtZW50KShlbCQxLCBzdGF0ZSkpICsgbm9ybWFsaXphdGlvblR5cGUpXG4gICAgfVxuICAgIHZhciBub3JtYWxpemF0aW9uVHlwZSQxID0gY2hlY2tTa2lwXG4gICAgICA/IGdldE5vcm1hbGl6YXRpb25UeXBlKGNoaWxkcmVuLCBzdGF0ZS5tYXliZUNvbXBvbmVudClcbiAgICAgIDogMDtcbiAgICB2YXIgZ2VuID0gYWx0R2VuTm9kZSB8fCBnZW5Ob2RlO1xuICAgIHJldHVybiAoXCJbXCIgKyAoY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjKSB7IHJldHVybiBnZW4oYywgc3RhdGUpOyB9KS5qb2luKCcsJykpICsgXCJdXCIgKyAobm9ybWFsaXphdGlvblR5cGUkMSA/IChcIixcIiArIG5vcm1hbGl6YXRpb25UeXBlJDEpIDogJycpKVxuICB9XG59XG5cbi8vIGRldGVybWluZSB0aGUgbm9ybWFsaXphdGlvbiBuZWVkZWQgZm9yIHRoZSBjaGlsZHJlbiBhcnJheS5cbi8vIDA6IG5vIG5vcm1hbGl6YXRpb24gbmVlZGVkXG4vLyAxOiBzaW1wbGUgbm9ybWFsaXphdGlvbiBuZWVkZWQgKHBvc3NpYmxlIDEtbGV2ZWwgZGVlcCBuZXN0ZWQgYXJyYXkpXG4vLyAyOiBmdWxsIG5vcm1hbGl6YXRpb24gbmVlZGVkXG5mdW5jdGlvbiBnZXROb3JtYWxpemF0aW9uVHlwZSAoXG4gIGNoaWxkcmVuLFxuICBtYXliZUNvbXBvbmVudFxuKSB7XG4gIHZhciByZXMgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGVsID0gY2hpbGRyZW5baV07XG4gICAgaWYgKGVsLnR5cGUgIT09IDEpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChuZWVkc05vcm1hbGl6YXRpb24oZWwpIHx8XG4gICAgICAgIChlbC5pZkNvbmRpdGlvbnMgJiYgZWwuaWZDb25kaXRpb25zLnNvbWUoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIG5lZWRzTm9ybWFsaXphdGlvbihjLmJsb2NrKTsgfSkpKSB7XG4gICAgICByZXMgPSAyO1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKG1heWJlQ29tcG9uZW50KGVsKSB8fFxuICAgICAgICAoZWwuaWZDb25kaXRpb25zICYmIGVsLmlmQ29uZGl0aW9ucy5zb21lKGZ1bmN0aW9uIChjKSB7IHJldHVybiBtYXliZUNvbXBvbmVudChjLmJsb2NrKTsgfSkpKSB7XG4gICAgICByZXMgPSAxO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIG5lZWRzTm9ybWFsaXphdGlvbiAoZWwpIHtcbiAgcmV0dXJuIGVsLmZvciAhPT0gdW5kZWZpbmVkIHx8IGVsLnRhZyA9PT0gJ3RlbXBsYXRlJyB8fCBlbC50YWcgPT09ICdzbG90J1xufVxuXG5mdW5jdGlvbiBnZW5Ob2RlIChub2RlLCBzdGF0ZSkge1xuICBpZiAobm9kZS50eXBlID09PSAxKSB7XG4gICAgcmV0dXJuIGdlbkVsZW1lbnQobm9kZSwgc3RhdGUpXG4gIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSAzICYmIG5vZGUuaXNDb21tZW50KSB7XG4gICAgcmV0dXJuIGdlbkNvbW1lbnQobm9kZSlcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2VuVGV4dChub2RlKVxuICB9XG59XG5cbmZ1bmN0aW9uIGdlblRleHQgKHRleHQpIHtcbiAgcmV0dXJuIChcIl92KFwiICsgKHRleHQudHlwZSA9PT0gMlxuICAgID8gdGV4dC5leHByZXNzaW9uIC8vIG5vIG5lZWQgZm9yICgpIGJlY2F1c2UgYWxyZWFkeSB3cmFwcGVkIGluIF9zKClcbiAgICA6IHRyYW5zZm9ybVNwZWNpYWxOZXdsaW5lcyhKU09OLnN0cmluZ2lmeSh0ZXh0LnRleHQpKSkgKyBcIilcIilcbn1cblxuZnVuY3Rpb24gZ2VuQ29tbWVudCAoY29tbWVudCkge1xuICByZXR1cm4gKFwiX2UoXCIgKyAoSlNPTi5zdHJpbmdpZnkoY29tbWVudC50ZXh0KSkgKyBcIilcIilcbn1cblxuZnVuY3Rpb24gZ2VuU2xvdCAoZWwsIHN0YXRlKSB7XG4gIHZhciBzbG90TmFtZSA9IGVsLnNsb3ROYW1lIHx8ICdcImRlZmF1bHRcIic7XG4gIHZhciBjaGlsZHJlbiA9IGdlbkNoaWxkcmVuKGVsLCBzdGF0ZSk7XG4gIHZhciByZXMgPSBcIl90KFwiICsgc2xvdE5hbWUgKyAoY2hpbGRyZW4gPyAoXCIsXCIgKyBjaGlsZHJlbikgOiAnJyk7XG4gIHZhciBhdHRycyA9IGVsLmF0dHJzIHx8IGVsLmR5bmFtaWNBdHRyc1xuICAgID8gZ2VuUHJvcHMoKGVsLmF0dHJzIHx8IFtdKS5jb25jYXQoZWwuZHluYW1pY0F0dHJzIHx8IFtdKS5tYXAoZnVuY3Rpb24gKGF0dHIpIHsgcmV0dXJuICh7XG4gICAgICAgIC8vIHNsb3QgcHJvcHMgYXJlIGNhbWVsaXplZFxuICAgICAgICBuYW1lOiBjYW1lbGl6ZShhdHRyLm5hbWUpLFxuICAgICAgICB2YWx1ZTogYXR0ci52YWx1ZSxcbiAgICAgICAgZHluYW1pYzogYXR0ci5keW5hbWljXG4gICAgICB9KTsgfSkpXG4gICAgOiBudWxsO1xuICB2YXIgYmluZCQkMSA9IGVsLmF0dHJzTWFwWyd2LWJpbmQnXTtcbiAgaWYgKChhdHRycyB8fCBiaW5kJCQxKSAmJiAhY2hpbGRyZW4pIHtcbiAgICByZXMgKz0gXCIsbnVsbFwiO1xuICB9XG4gIGlmIChhdHRycykge1xuICAgIHJlcyArPSBcIixcIiArIGF0dHJzO1xuICB9XG4gIGlmIChiaW5kJCQxKSB7XG4gICAgcmVzICs9IChhdHRycyA/ICcnIDogJyxudWxsJykgKyBcIixcIiArIGJpbmQkJDE7XG4gIH1cbiAgcmV0dXJuIHJlcyArICcpJ1xufVxuXG4vLyBjb21wb25lbnROYW1lIGlzIGVsLmNvbXBvbmVudCwgdGFrZSBpdCBhcyBhcmd1bWVudCB0byBzaHVuIGZsb3cncyBwZXNzaW1pc3RpYyByZWZpbmVtZW50XG5mdW5jdGlvbiBnZW5Db21wb25lbnQgKFxuICBjb21wb25lbnROYW1lLFxuICBlbCxcbiAgc3RhdGVcbikge1xuICB2YXIgY2hpbGRyZW4gPSBlbC5pbmxpbmVUZW1wbGF0ZSA/IG51bGwgOiBnZW5DaGlsZHJlbihlbCwgc3RhdGUsIHRydWUpO1xuICByZXR1cm4gKFwiX2MoXCIgKyBjb21wb25lbnROYW1lICsgXCIsXCIgKyAoZ2VuRGF0YSQyKGVsLCBzdGF0ZSkpICsgKGNoaWxkcmVuID8gKFwiLFwiICsgY2hpbGRyZW4pIDogJycpICsgXCIpXCIpXG59XG5cbmZ1bmN0aW9uIGdlblByb3BzIChwcm9wcykge1xuICB2YXIgc3RhdGljUHJvcHMgPSBcIlwiO1xuICB2YXIgZHluYW1pY1Byb3BzID0gXCJcIjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwcm9wID0gcHJvcHNbaV07XG4gICAgdmFyIHZhbHVlID0gdHJhbnNmb3JtU3BlY2lhbE5ld2xpbmVzKHByb3AudmFsdWUpO1xuICAgIGlmIChwcm9wLmR5bmFtaWMpIHtcbiAgICAgIGR5bmFtaWNQcm9wcyArPSAocHJvcC5uYW1lKSArIFwiLFwiICsgdmFsdWUgKyBcIixcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGljUHJvcHMgKz0gXCJcXFwiXCIgKyAocHJvcC5uYW1lKSArIFwiXFxcIjpcIiArIHZhbHVlICsgXCIsXCI7XG4gICAgfVxuICB9XG4gIHN0YXRpY1Byb3BzID0gXCJ7XCIgKyAoc3RhdGljUHJvcHMuc2xpY2UoMCwgLTEpKSArIFwifVwiO1xuICBpZiAoZHluYW1pY1Byb3BzKSB7XG4gICAgcmV0dXJuIChcIl9kKFwiICsgc3RhdGljUHJvcHMgKyBcIixbXCIgKyAoZHluYW1pY1Byb3BzLnNsaWNlKDAsIC0xKSkgKyBcIl0pXCIpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXRpY1Byb3BzXG4gIH1cbn1cblxuLy8gIzM4OTUsICM0MjY4XG5mdW5jdGlvbiB0cmFuc2Zvcm1TcGVjaWFsTmV3bGluZXMgKHRleHQpIHtcbiAgcmV0dXJuIHRleHRcbiAgICAucmVwbGFjZSgvXFx1MjAyOC9nLCAnXFxcXHUyMDI4JylcbiAgICAucmVwbGFjZSgvXFx1MjAyOS9nLCAnXFxcXHUyMDI5Jylcbn1cblxuLyogICovXG5cblxuXG4vLyB0aGVzZSBrZXl3b3JkcyBzaG91bGQgbm90IGFwcGVhciBpbnNpZGUgZXhwcmVzc2lvbnMsIGJ1dCBvcGVyYXRvcnMgbGlrZVxuLy8gdHlwZW9mLCBpbnN0YW5jZW9mIGFuZCBpbiBhcmUgYWxsb3dlZFxudmFyIHByb2hpYml0ZWRLZXl3b3JkUkUgPSBuZXcgUmVnRXhwKCdcXFxcYicgKyAoXG4gICdkbyxpZixmb3IsbGV0LG5ldyx0cnksdmFyLGNhc2UsZWxzZSx3aXRoLGF3YWl0LGJyZWFrLGNhdGNoLGNsYXNzLGNvbnN0LCcgK1xuICAnc3VwZXIsdGhyb3csd2hpbGUseWllbGQsZGVsZXRlLGV4cG9ydCxpbXBvcnQscmV0dXJuLHN3aXRjaCxkZWZhdWx0LCcgK1xuICAnZXh0ZW5kcyxmaW5hbGx5LGNvbnRpbnVlLGRlYnVnZ2VyLGZ1bmN0aW9uLGFyZ3VtZW50cydcbikuc3BsaXQoJywnKS5qb2luKCdcXFxcYnxcXFxcYicpICsgJ1xcXFxiJyk7XG5cbi8vIHRoZXNlIHVuYXJ5IG9wZXJhdG9ycyBzaG91bGQgbm90IGJlIHVzZWQgYXMgcHJvcGVydHkvbWV0aG9kIG5hbWVzXG52YXIgdW5hcnlPcGVyYXRvcnNSRSA9IG5ldyBSZWdFeHAoJ1xcXFxiJyArIChcbiAgJ2RlbGV0ZSx0eXBlb2Ysdm9pZCdcbikuc3BsaXQoJywnKS5qb2luKCdcXFxccypcXFxcKFteXFxcXCldKlxcXFwpfFxcXFxiJykgKyAnXFxcXHMqXFxcXChbXlxcXFwpXSpcXFxcKScpO1xuXG4vLyBzdHJpcCBzdHJpbmdzIGluIGV4cHJlc3Npb25zXG52YXIgc3RyaXBTdHJpbmdSRSA9IC8nKD86W14nXFxcXF18XFxcXC4pKid8XCIoPzpbXlwiXFxcXF18XFxcXC4pKlwifGAoPzpbXmBcXFxcXXxcXFxcLikqXFwkXFx7fFxcfSg/OlteYFxcXFxdfFxcXFwuKSpgfGAoPzpbXmBcXFxcXXxcXFxcLikqYC9nO1xuXG4vLyBkZXRlY3QgcHJvYmxlbWF0aWMgZXhwcmVzc2lvbnMgaW4gYSB0ZW1wbGF0ZVxuZnVuY3Rpb24gZGV0ZWN0RXJyb3JzIChhc3QsIHdhcm4pIHtcbiAgaWYgKGFzdCkge1xuICAgIGNoZWNrTm9kZShhc3QsIHdhcm4pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrTm9kZSAobm9kZSwgd2Fybikge1xuICBpZiAobm9kZS50eXBlID09PSAxKSB7XG4gICAgZm9yICh2YXIgbmFtZSBpbiBub2RlLmF0dHJzTWFwKSB7XG4gICAgICBpZiAoZGlyUkUudGVzdChuYW1lKSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBub2RlLmF0dHJzTWFwW25hbWVdO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmFuZ2UgPSBub2RlLnJhd0F0dHJzTWFwW25hbWVdO1xuICAgICAgICAgIGlmIChuYW1lID09PSAndi1mb3InKSB7XG4gICAgICAgICAgICBjaGVja0Zvcihub2RlLCAoXCJ2LWZvcj1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIlwiKSwgd2FybiwgcmFuZ2UpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3Ytc2xvdCcgfHwgbmFtZVswXSA9PT0gJyMnKSB7XG4gICAgICAgICAgICBjaGVja0Z1bmN0aW9uUGFyYW1ldGVyRXhwcmVzc2lvbih2YWx1ZSwgKG5hbWUgKyBcIj1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIlwiKSwgd2FybiwgcmFuZ2UpO1xuICAgICAgICAgIH0gZWxzZSBpZiAob25SRS50ZXN0KG5hbWUpKSB7XG4gICAgICAgICAgICBjaGVja0V2ZW50KHZhbHVlLCAobmFtZSArIFwiPVxcXCJcIiArIHZhbHVlICsgXCJcXFwiXCIpLCB3YXJuLCByYW5nZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNoZWNrRXhwcmVzc2lvbih2YWx1ZSwgKG5hbWUgKyBcIj1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIlwiKSwgd2FybiwgcmFuZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNoZWNrTm9kZShub2RlLmNoaWxkcmVuW2ldLCB3YXJuKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSAyKSB7XG4gICAgY2hlY2tFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbiwgbm9kZS50ZXh0LCB3YXJuLCBub2RlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0V2ZW50IChleHAsIHRleHQsIHdhcm4sIHJhbmdlKSB7XG4gIHZhciBzdHJpcHBlZCA9IGV4cC5yZXBsYWNlKHN0cmlwU3RyaW5nUkUsICcnKTtcbiAgdmFyIGtleXdvcmRNYXRjaCA9IHN0cmlwcGVkLm1hdGNoKHVuYXJ5T3BlcmF0b3JzUkUpO1xuICBpZiAoa2V5d29yZE1hdGNoICYmIHN0cmlwcGVkLmNoYXJBdChrZXl3b3JkTWF0Y2guaW5kZXggLSAxKSAhPT0gJyQnKSB7XG4gICAgd2FybihcbiAgICAgIFwiYXZvaWQgdXNpbmcgSmF2YVNjcmlwdCB1bmFyeSBvcGVyYXRvciBhcyBwcm9wZXJ0eSBuYW1lOiBcIiArXG4gICAgICBcIlxcXCJcIiArIChrZXl3b3JkTWF0Y2hbMF0pICsgXCJcXFwiIGluIGV4cHJlc3Npb24gXCIgKyAodGV4dC50cmltKCkpLFxuICAgICAgcmFuZ2VcbiAgICApO1xuICB9XG4gIGNoZWNrRXhwcmVzc2lvbihleHAsIHRleHQsIHdhcm4sIHJhbmdlKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tGb3IgKG5vZGUsIHRleHQsIHdhcm4sIHJhbmdlKSB7XG4gIGNoZWNrRXhwcmVzc2lvbihub2RlLmZvciB8fCAnJywgdGV4dCwgd2FybiwgcmFuZ2UpO1xuICBjaGVja0lkZW50aWZpZXIobm9kZS5hbGlhcywgJ3YtZm9yIGFsaWFzJywgdGV4dCwgd2FybiwgcmFuZ2UpO1xuICBjaGVja0lkZW50aWZpZXIobm9kZS5pdGVyYXRvcjEsICd2LWZvciBpdGVyYXRvcicsIHRleHQsIHdhcm4sIHJhbmdlKTtcbiAgY2hlY2tJZGVudGlmaWVyKG5vZGUuaXRlcmF0b3IyLCAndi1mb3IgaXRlcmF0b3InLCB0ZXh0LCB3YXJuLCByYW5nZSk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrSWRlbnRpZmllciAoXG4gIGlkZW50LFxuICB0eXBlLFxuICB0ZXh0LFxuICB3YXJuLFxuICByYW5nZVxuKSB7XG4gIGlmICh0eXBlb2YgaWRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgdHJ5IHtcbiAgICAgIG5ldyBGdW5jdGlvbigoXCJ2YXIgXCIgKyBpZGVudCArIFwiPV9cIikpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHdhcm4oKFwiaW52YWxpZCBcIiArIHR5cGUgKyBcIiBcXFwiXCIgKyBpZGVudCArIFwiXFxcIiBpbiBleHByZXNzaW9uOiBcIiArICh0ZXh0LnRyaW0oKSkpLCByYW5nZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrRXhwcmVzc2lvbiAoZXhwLCB0ZXh0LCB3YXJuLCByYW5nZSkge1xuICB0cnkge1xuICAgIG5ldyBGdW5jdGlvbigoXCJyZXR1cm4gXCIgKyBleHApKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciBrZXl3b3JkTWF0Y2ggPSBleHAucmVwbGFjZShzdHJpcFN0cmluZ1JFLCAnJykubWF0Y2gocHJvaGliaXRlZEtleXdvcmRSRSk7XG4gICAgaWYgKGtleXdvcmRNYXRjaCkge1xuICAgICAgd2FybihcbiAgICAgICAgXCJhdm9pZCB1c2luZyBKYXZhU2NyaXB0IGtleXdvcmQgYXMgcHJvcGVydHkgbmFtZTogXCIgK1xuICAgICAgICBcIlxcXCJcIiArIChrZXl3b3JkTWF0Y2hbMF0pICsgXCJcXFwiXFxuICBSYXcgZXhwcmVzc2lvbjogXCIgKyAodGV4dC50cmltKCkpLFxuICAgICAgICByYW5nZVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2FybihcbiAgICAgICAgXCJpbnZhbGlkIGV4cHJlc3Npb246IFwiICsgKGUubWVzc2FnZSkgKyBcIiBpblxcblxcblwiICtcbiAgICAgICAgXCIgICAgXCIgKyBleHAgKyBcIlxcblxcblwiICtcbiAgICAgICAgXCIgIFJhdyBleHByZXNzaW9uOiBcIiArICh0ZXh0LnRyaW0oKSkgKyBcIlxcblwiLFxuICAgICAgICByYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tGdW5jdGlvblBhcmFtZXRlckV4cHJlc3Npb24gKGV4cCwgdGV4dCwgd2FybiwgcmFuZ2UpIHtcbiAgdHJ5IHtcbiAgICBuZXcgRnVuY3Rpb24oZXhwLCAnJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB3YXJuKFxuICAgICAgXCJpbnZhbGlkIGZ1bmN0aW9uIHBhcmFtZXRlciBleHByZXNzaW9uOiBcIiArIChlLm1lc3NhZ2UpICsgXCIgaW5cXG5cXG5cIiArXG4gICAgICBcIiAgICBcIiArIGV4cCArIFwiXFxuXFxuXCIgK1xuICAgICAgXCIgIFJhdyBleHByZXNzaW9uOiBcIiArICh0ZXh0LnRyaW0oKSkgKyBcIlxcblwiLFxuICAgICAgcmFuZ2VcbiAgICApO1xuICB9XG59XG5cbi8qICAqL1xuXG52YXIgcmFuZ2UgPSAyO1xuXG5mdW5jdGlvbiBnZW5lcmF0ZUNvZGVGcmFtZSAoXG4gIHNvdXJjZSxcbiAgc3RhcnQsXG4gIGVuZFxuKSB7XG4gIGlmICggc3RhcnQgPT09IHZvaWQgMCApIHN0YXJ0ID0gMDtcbiAgaWYgKCBlbmQgPT09IHZvaWQgMCApIGVuZCA9IHNvdXJjZS5sZW5ndGg7XG5cbiAgdmFyIGxpbmVzID0gc291cmNlLnNwbGl0KC9cXHI/XFxuLyk7XG4gIHZhciBjb3VudCA9IDA7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvdW50ICs9IGxpbmVzW2ldLmxlbmd0aCArIDE7XG4gICAgaWYgKGNvdW50ID49IHN0YXJ0KSB7XG4gICAgICBmb3IgKHZhciBqID0gaSAtIHJhbmdlOyBqIDw9IGkgKyByYW5nZSB8fCBlbmQgPiBjb3VudDsgaisrKSB7XG4gICAgICAgIGlmIChqIDwgMCB8fCBqID49IGxpbmVzLmxlbmd0aCkgeyBjb250aW51ZSB9XG4gICAgICAgIHJlcy5wdXNoKChcIlwiICsgKGogKyAxKSArIChyZXBlYXQkMShcIiBcIiwgMyAtIFN0cmluZyhqICsgMSkubGVuZ3RoKSkgKyBcInwgIFwiICsgKGxpbmVzW2pdKSkpO1xuICAgICAgICB2YXIgbGluZUxlbmd0aCA9IGxpbmVzW2pdLmxlbmd0aDtcbiAgICAgICAgaWYgKGogPT09IGkpIHtcbiAgICAgICAgICAvLyBwdXNoIHVuZGVybGluZVxuICAgICAgICAgIHZhciBwYWQgPSBzdGFydCAtIChjb3VudCAtIGxpbmVMZW5ndGgpICsgMTtcbiAgICAgICAgICB2YXIgbGVuZ3RoID0gZW5kID4gY291bnQgPyBsaW5lTGVuZ3RoIC0gcGFkIDogZW5kIC0gc3RhcnQ7XG4gICAgICAgICAgcmVzLnB1c2goXCIgICB8ICBcIiArIHJlcGVhdCQxKFwiIFwiLCBwYWQpICsgcmVwZWF0JDEoXCJeXCIsIGxlbmd0aCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGogPiBpKSB7XG4gICAgICAgICAgaWYgKGVuZCA+IGNvdW50KSB7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoJDEgPSBNYXRoLm1pbihlbmQgLSBjb3VudCwgbGluZUxlbmd0aCk7XG4gICAgICAgICAgICByZXMucHVzaChcIiAgIHwgIFwiICsgcmVwZWF0JDEoXCJeXCIsIGxlbmd0aCQxKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvdW50ICs9IGxpbmVMZW5ndGggKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzLmpvaW4oJ1xcbicpXG59XG5cbmZ1bmN0aW9uIHJlcGVhdCQxIChzdHIsIG4pIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICBpZiAobiA+IDApIHtcbiAgICB3aGlsZSAodHJ1ZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICBpZiAobiAmIDEpIHsgcmVzdWx0ICs9IHN0cjsgfVxuICAgICAgbiA+Pj49IDE7XG4gICAgICBpZiAobiA8PSAwKSB7IGJyZWFrIH1cbiAgICAgIHN0ciArPSBzdHI7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuLyogICovXG5cblxuXG5mdW5jdGlvbiBjcmVhdGVGdW5jdGlvbiAoY29kZSwgZXJyb3JzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbihjb2RlKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvcnMucHVzaCh7IGVycjogZXJyLCBjb2RlOiBjb2RlIH0pO1xuICAgIHJldHVybiBub29wXG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29tcGlsZVRvRnVuY3Rpb25GbiAoY29tcGlsZSkge1xuICB2YXIgY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gIHJldHVybiBmdW5jdGlvbiBjb21waWxlVG9GdW5jdGlvbnMgKFxuICAgIHRlbXBsYXRlLFxuICAgIG9wdGlvbnMsXG4gICAgdm1cbiAgKSB7XG4gICAgb3B0aW9ucyA9IGV4dGVuZCh7fSwgb3B0aW9ucyk7XG4gICAgdmFyIHdhcm4kJDEgPSBvcHRpb25zLndhcm4gfHwgd2FybjtcbiAgICBkZWxldGUgb3B0aW9ucy53YXJuO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAge1xuICAgICAgLy8gZGV0ZWN0IHBvc3NpYmxlIENTUCByZXN0cmljdGlvblxuICAgICAgdHJ5IHtcbiAgICAgICAgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gMScpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoZS50b1N0cmluZygpLm1hdGNoKC91bnNhZmUtZXZhbHxDU1AvKSkge1xuICAgICAgICAgIHdhcm4kJDEoXG4gICAgICAgICAgICAnSXQgc2VlbXMgeW91IGFyZSB1c2luZyB0aGUgc3RhbmRhbG9uZSBidWlsZCBvZiBWdWUuanMgaW4gYW4gJyArXG4gICAgICAgICAgICAnZW52aXJvbm1lbnQgd2l0aCBDb250ZW50IFNlY3VyaXR5IFBvbGljeSB0aGF0IHByb2hpYml0cyB1bnNhZmUtZXZhbC4gJyArXG4gICAgICAgICAgICAnVGhlIHRlbXBsYXRlIGNvbXBpbGVyIGNhbm5vdCB3b3JrIGluIHRoaXMgZW52aXJvbm1lbnQuIENvbnNpZGVyICcgK1xuICAgICAgICAgICAgJ3JlbGF4aW5nIHRoZSBwb2xpY3kgdG8gYWxsb3cgdW5zYWZlLWV2YWwgb3IgcHJlLWNvbXBpbGluZyB5b3VyICcgK1xuICAgICAgICAgICAgJ3RlbXBsYXRlcyBpbnRvIHJlbmRlciBmdW5jdGlvbnMuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBjYWNoZVxuICAgIHZhciBrZXkgPSBvcHRpb25zLmRlbGltaXRlcnNcbiAgICAgID8gU3RyaW5nKG9wdGlvbnMuZGVsaW1pdGVycykgKyB0ZW1wbGF0ZVxuICAgICAgOiB0ZW1wbGF0ZTtcbiAgICBpZiAoY2FjaGVba2V5XSkge1xuICAgICAgcmV0dXJuIGNhY2hlW2tleV1cbiAgICB9XG5cbiAgICAvLyBjb21waWxlXG4gICAgdmFyIGNvbXBpbGVkID0gY29tcGlsZSh0ZW1wbGF0ZSwgb3B0aW9ucyk7XG5cbiAgICAvLyBjaGVjayBjb21waWxhdGlvbiBlcnJvcnMvdGlwc1xuICAgIHtcbiAgICAgIGlmIChjb21waWxlZC5lcnJvcnMgJiYgY29tcGlsZWQuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkge1xuICAgICAgICAgIGNvbXBpbGVkLmVycm9ycy5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB3YXJuJCQxKFxuICAgICAgICAgICAgICBcIkVycm9yIGNvbXBpbGluZyB0ZW1wbGF0ZTpcXG5cXG5cIiArIChlLm1zZykgKyBcIlxcblxcblwiICtcbiAgICAgICAgICAgICAgZ2VuZXJhdGVDb2RlRnJhbWUodGVtcGxhdGUsIGUuc3RhcnQsIGUuZW5kKSxcbiAgICAgICAgICAgICAgdm1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd2FybiQkMShcbiAgICAgICAgICAgIFwiRXJyb3IgY29tcGlsaW5nIHRlbXBsYXRlOlxcblxcblwiICsgdGVtcGxhdGUgKyBcIlxcblxcblwiICtcbiAgICAgICAgICAgIGNvbXBpbGVkLmVycm9ycy5tYXAoZnVuY3Rpb24gKGUpIHsgcmV0dXJuIChcIi0gXCIgKyBlKTsgfSkuam9pbignXFxuJykgKyAnXFxuJyxcbiAgICAgICAgICAgIHZtXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNvbXBpbGVkLnRpcHMgJiYgY29tcGlsZWQudGlwcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMub3V0cHV0U291cmNlUmFuZ2UpIHtcbiAgICAgICAgICBjb21waWxlZC50aXBzLmZvckVhY2goZnVuY3Rpb24gKGUpIHsgcmV0dXJuIHRpcChlLm1zZywgdm0pOyB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb21waWxlZC50aXBzLmZvckVhY2goZnVuY3Rpb24gKG1zZykgeyByZXR1cm4gdGlwKG1zZywgdm0pOyB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHR1cm4gY29kZSBpbnRvIGZ1bmN0aW9uc1xuICAgIHZhciByZXMgPSB7fTtcbiAgICB2YXIgZm5HZW5FcnJvcnMgPSBbXTtcbiAgICByZXMucmVuZGVyID0gY3JlYXRlRnVuY3Rpb24oY29tcGlsZWQucmVuZGVyLCBmbkdlbkVycm9ycyk7XG4gICAgcmVzLnN0YXRpY1JlbmRlckZucyA9IGNvbXBpbGVkLnN0YXRpY1JlbmRlckZucy5tYXAoZnVuY3Rpb24gKGNvZGUpIHtcbiAgICAgIHJldHVybiBjcmVhdGVGdW5jdGlvbihjb2RlLCBmbkdlbkVycm9ycylcbiAgICB9KTtcblxuICAgIC8vIGNoZWNrIGZ1bmN0aW9uIGdlbmVyYXRpb24gZXJyb3JzLlxuICAgIC8vIHRoaXMgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZXJlIGlzIGEgYnVnIGluIHRoZSBjb21waWxlciBpdHNlbGYuXG4gICAgLy8gbW9zdGx5IGZvciBjb2RlZ2VuIGRldmVsb3BtZW50IHVzZVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIHtcbiAgICAgIGlmICgoIWNvbXBpbGVkLmVycm9ycyB8fCAhY29tcGlsZWQuZXJyb3JzLmxlbmd0aCkgJiYgZm5HZW5FcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHdhcm4kJDEoXG4gICAgICAgICAgXCJGYWlsZWQgdG8gZ2VuZXJhdGUgcmVuZGVyIGZ1bmN0aW9uOlxcblxcblwiICtcbiAgICAgICAgICBmbkdlbkVycm9ycy5tYXAoZnVuY3Rpb24gKHJlZikge1xuICAgICAgICAgICAgdmFyIGVyciA9IHJlZi5lcnI7XG4gICAgICAgICAgICB2YXIgY29kZSA9IHJlZi5jb2RlO1xuXG4gICAgICAgICAgICByZXR1cm4gKChlcnIudG9TdHJpbmcoKSkgKyBcIiBpblxcblxcblwiICsgY29kZSArIFwiXFxuXCIpO1xuICAgICAgICB9KS5qb2luKCdcXG4nKSxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoY2FjaGVba2V5XSA9IHJlcylcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gY3JlYXRlQ29tcGlsZXJDcmVhdG9yIChiYXNlQ29tcGlsZSkge1xuICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlQ29tcGlsZXIgKGJhc2VPcHRpb25zKSB7XG4gICAgZnVuY3Rpb24gY29tcGlsZSAoXG4gICAgICB0ZW1wbGF0ZSxcbiAgICAgIG9wdGlvbnNcbiAgICApIHtcbiAgICAgIHZhciBmaW5hbE9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKGJhc2VPcHRpb25zKTtcbiAgICAgIHZhciBlcnJvcnMgPSBbXTtcbiAgICAgIHZhciB0aXBzID0gW107XG5cbiAgICAgIHZhciB3YXJuID0gZnVuY3Rpb24gKG1zZywgcmFuZ2UsIHRpcCkge1xuICAgICAgICAodGlwID8gdGlwcyA6IGVycm9ycykucHVzaChtc2cpO1xuICAgICAgfTtcblxuICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMub3V0cHV0U291cmNlUmFuZ2UpIHtcbiAgICAgICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgICAgICAgICB2YXIgbGVhZGluZ1NwYWNlTGVuZ3RoID0gdGVtcGxhdGUubWF0Y2goL15cXHMqLylbMF0ubGVuZ3RoO1xuXG4gICAgICAgICAgd2FybiA9IGZ1bmN0aW9uIChtc2csIHJhbmdlLCB0aXApIHtcbiAgICAgICAgICAgIHZhciBkYXRhID0geyBtc2c6IG1zZyB9O1xuICAgICAgICAgICAgaWYgKHJhbmdlKSB7XG4gICAgICAgICAgICAgIGlmIChyYW5nZS5zdGFydCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5zdGFydCA9IHJhbmdlLnN0YXJ0ICsgbGVhZGluZ1NwYWNlTGVuZ3RoO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChyYW5nZS5lbmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRhdGEuZW5kID0gcmFuZ2UuZW5kICsgbGVhZGluZ1NwYWNlTGVuZ3RoO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAodGlwID8gdGlwcyA6IGVycm9ycykucHVzaChkYXRhKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIG1lcmdlIGN1c3RvbSBtb2R1bGVzXG4gICAgICAgIGlmIChvcHRpb25zLm1vZHVsZXMpIHtcbiAgICAgICAgICBmaW5hbE9wdGlvbnMubW9kdWxlcyA9XG4gICAgICAgICAgICAoYmFzZU9wdGlvbnMubW9kdWxlcyB8fCBbXSkuY29uY2F0KG9wdGlvbnMubW9kdWxlcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbWVyZ2UgY3VzdG9tIGRpcmVjdGl2ZXNcbiAgICAgICAgaWYgKG9wdGlvbnMuZGlyZWN0aXZlcykge1xuICAgICAgICAgIGZpbmFsT3B0aW9ucy5kaXJlY3RpdmVzID0gZXh0ZW5kKFxuICAgICAgICAgICAgT2JqZWN0LmNyZWF0ZShiYXNlT3B0aW9ucy5kaXJlY3RpdmVzIHx8IG51bGwpLFxuICAgICAgICAgICAgb3B0aW9ucy5kaXJlY3RpdmVzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb3B5IG90aGVyIG9wdGlvbnNcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHtcbiAgICAgICAgICBpZiAoa2V5ICE9PSAnbW9kdWxlcycgJiYga2V5ICE9PSAnZGlyZWN0aXZlcycpIHtcbiAgICAgICAgICAgIGZpbmFsT3B0aW9uc1trZXldID0gb3B0aW9uc1trZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmaW5hbE9wdGlvbnMud2FybiA9IHdhcm47XG5cbiAgICAgIHZhciBjb21waWxlZCA9IGJhc2VDb21waWxlKHRlbXBsYXRlLnRyaW0oKSwgZmluYWxPcHRpb25zKTtcbiAgICAgIHtcbiAgICAgICAgZGV0ZWN0RXJyb3JzKGNvbXBpbGVkLmFzdCwgd2Fybik7XG4gICAgICB9XG4gICAgICBjb21waWxlZC5lcnJvcnMgPSBlcnJvcnM7XG4gICAgICBjb21waWxlZC50aXBzID0gdGlwcztcbiAgICAgIHJldHVybiBjb21waWxlZFxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb21waWxlOiBjb21waWxlLFxuICAgICAgY29tcGlsZVRvRnVuY3Rpb25zOiBjcmVhdGVDb21waWxlVG9GdW5jdGlvbkZuKGNvbXBpbGUpXG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG4vLyBgY3JlYXRlQ29tcGlsZXJDcmVhdG9yYCBhbGxvd3MgY3JlYXRpbmcgY29tcGlsZXJzIHRoYXQgdXNlIGFsdGVybmF0aXZlXG4vLyBwYXJzZXIvb3B0aW1pemVyL2NvZGVnZW4sIGUuZyB0aGUgU1NSIG9wdGltaXppbmcgY29tcGlsZXIuXG4vLyBIZXJlIHdlIGp1c3QgZXhwb3J0IGEgZGVmYXVsdCBjb21waWxlciB1c2luZyB0aGUgZGVmYXVsdCBwYXJ0cy5cbnZhciBjcmVhdGVDb21waWxlciA9IGNyZWF0ZUNvbXBpbGVyQ3JlYXRvcihmdW5jdGlvbiBiYXNlQ29tcGlsZSAoXG4gIHRlbXBsYXRlLFxuICBvcHRpb25zXG4pIHtcbiAgdmFyIGFzdCA9IHBhcnNlKHRlbXBsYXRlLnRyaW0oKSwgb3B0aW9ucyk7XG4gIGlmIChvcHRpb25zLm9wdGltaXplICE9PSBmYWxzZSkge1xuICAgIG9wdGltaXplKGFzdCwgb3B0aW9ucyk7XG4gIH1cbiAgdmFyIGNvZGUgPSBnZW5lcmF0ZShhc3QsIG9wdGlvbnMpO1xuICByZXR1cm4ge1xuICAgIGFzdDogYXN0LFxuICAgIHJlbmRlcjogY29kZS5yZW5kZXIsXG4gICAgc3RhdGljUmVuZGVyRm5zOiBjb2RlLnN0YXRpY1JlbmRlckZuc1xuICB9XG59KTtcblxuLyogICovXG5cbnZhciByZWYkMSA9IGNyZWF0ZUNvbXBpbGVyKGJhc2VPcHRpb25zKTtcbnZhciBjb21waWxlID0gcmVmJDEuY29tcGlsZTtcbnZhciBjb21waWxlVG9GdW5jdGlvbnMgPSByZWYkMS5jb21waWxlVG9GdW5jdGlvbnM7XG5cbi8qICAqL1xuXG4vLyBjaGVjayB3aGV0aGVyIGN1cnJlbnQgYnJvd3NlciBlbmNvZGVzIGEgY2hhciBpbnNpZGUgYXR0cmlidXRlIHZhbHVlc1xudmFyIGRpdjtcbmZ1bmN0aW9uIGdldFNob3VsZERlY29kZSAoaHJlZikge1xuICBkaXYgPSBkaXYgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGRpdi5pbm5lckhUTUwgPSBocmVmID8gXCI8YSBocmVmPVxcXCJcXG5cXFwiLz5cIiA6IFwiPGRpdiBhPVxcXCJcXG5cXFwiLz5cIjtcbiAgcmV0dXJuIGRpdi5pbm5lckhUTUwuaW5kZXhPZignJiMxMDsnKSA+IDBcbn1cblxuLy8gIzM2NjM6IElFIGVuY29kZXMgbmV3bGluZXMgaW5zaWRlIGF0dHJpYnV0ZSB2YWx1ZXMgd2hpbGUgb3RoZXIgYnJvd3NlcnMgZG9uJ3RcbnZhciBzaG91bGREZWNvZGVOZXdsaW5lcyA9IGluQnJvd3NlciA/IGdldFNob3VsZERlY29kZShmYWxzZSkgOiBmYWxzZTtcbi8vICM2ODI4OiBjaHJvbWUgZW5jb2RlcyBjb250ZW50IGluIGFbaHJlZl1cbnZhciBzaG91bGREZWNvZGVOZXdsaW5lc0ZvckhyZWYgPSBpbkJyb3dzZXIgPyBnZXRTaG91bGREZWNvZGUodHJ1ZSkgOiBmYWxzZTtcblxuLyogICovXG5cbnZhciBpZFRvVGVtcGxhdGUgPSBjYWNoZWQoZnVuY3Rpb24gKGlkKSB7XG4gIHZhciBlbCA9IHF1ZXJ5KGlkKTtcbiAgcmV0dXJuIGVsICYmIGVsLmlubmVySFRNTFxufSk7XG5cbnZhciBtb3VudCA9IFZ1ZS5wcm90b3R5cGUuJG1vdW50O1xuVnVlLnByb3RvdHlwZS4kbW91bnQgPSBmdW5jdGlvbiAoXG4gIGVsLFxuICBoeWRyYXRpbmdcbikge1xuICBlbCA9IGVsICYmIHF1ZXJ5KGVsKTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGVsID09PSBkb2N1bWVudC5ib2R5IHx8IGVsID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICB3YXJuKFxuICAgICAgXCJEbyBub3QgbW91bnQgVnVlIHRvIDxodG1sPiBvciA8Ym9keT4gLSBtb3VudCB0byBub3JtYWwgZWxlbWVudHMgaW5zdGVhZC5cIlxuICAgICk7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHZhciBvcHRpb25zID0gdGhpcy4kb3B0aW9ucztcbiAgLy8gcmVzb2x2ZSB0ZW1wbGF0ZS9lbCBhbmQgY29udmVydCB0byByZW5kZXIgZnVuY3Rpb25cbiAgaWYgKCFvcHRpb25zLnJlbmRlcikge1xuICAgIHZhciB0ZW1wbGF0ZSA9IG9wdGlvbnMudGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICBpZiAodHlwZW9mIHRlbXBsYXRlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAodGVtcGxhdGUuY2hhckF0KDApID09PSAnIycpIHtcbiAgICAgICAgICB0ZW1wbGF0ZSA9IGlkVG9UZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgaWYgKCF0ZW1wbGF0ZSkge1xuICAgICAgICAgICAgd2FybihcbiAgICAgICAgICAgICAgKFwiVGVtcGxhdGUgZWxlbWVudCBub3QgZm91bmQgb3IgaXMgZW1wdHk6IFwiICsgKG9wdGlvbnMudGVtcGxhdGUpKSxcbiAgICAgICAgICAgICAgdGhpc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGVtcGxhdGUubm9kZVR5cGUpIHtcbiAgICAgICAgdGVtcGxhdGUgPSB0ZW1wbGF0ZS5pbm5lckhUTUw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB7XG4gICAgICAgICAgd2FybignaW52YWxpZCB0ZW1wbGF0ZSBvcHRpb246JyArIHRlbXBsYXRlLCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZWwpIHtcbiAgICAgIHRlbXBsYXRlID0gZ2V0T3V0ZXJIVE1MKGVsKTtcbiAgICB9XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykge1xuICAgICAgICBtYXJrKCdjb21waWxlJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWYgPSBjb21waWxlVG9GdW5jdGlvbnModGVtcGxhdGUsIHtcbiAgICAgICAgb3V0cHV0U291cmNlUmFuZ2U6IFwiZGV2ZWxvcG1lbnRcIiAhPT0gJ3Byb2R1Y3Rpb24nLFxuICAgICAgICBzaG91bGREZWNvZGVOZXdsaW5lczogc2hvdWxkRGVjb2RlTmV3bGluZXMsXG4gICAgICAgIHNob3VsZERlY29kZU5ld2xpbmVzRm9ySHJlZjogc2hvdWxkRGVjb2RlTmV3bGluZXNGb3JIcmVmLFxuICAgICAgICBkZWxpbWl0ZXJzOiBvcHRpb25zLmRlbGltaXRlcnMsXG4gICAgICAgIGNvbW1lbnRzOiBvcHRpb25zLmNvbW1lbnRzXG4gICAgICB9LCB0aGlzKTtcbiAgICAgIHZhciByZW5kZXIgPSByZWYucmVuZGVyO1xuICAgICAgdmFyIHN0YXRpY1JlbmRlckZucyA9IHJlZi5zdGF0aWNSZW5kZXJGbnM7XG4gICAgICBvcHRpb25zLnJlbmRlciA9IHJlbmRlcjtcbiAgICAgIG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zID0gc3RhdGljUmVuZGVyRm5zO1xuXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykge1xuICAgICAgICBtYXJrKCdjb21waWxlIGVuZCcpO1xuICAgICAgICBtZWFzdXJlKChcInZ1ZSBcIiArICh0aGlzLl9uYW1lKSArIFwiIGNvbXBpbGVcIiksICdjb21waWxlJywgJ2NvbXBpbGUgZW5kJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBtb3VudC5jYWxsKHRoaXMsIGVsLCBoeWRyYXRpbmcpXG59O1xuXG4vKipcbiAqIEdldCBvdXRlckhUTUwgb2YgZWxlbWVudHMsIHRha2luZyBjYXJlXG4gKiBvZiBTVkcgZWxlbWVudHMgaW4gSUUgYXMgd2VsbC5cbiAqL1xuZnVuY3Rpb24gZ2V0T3V0ZXJIVE1MIChlbCkge1xuICBpZiAoZWwub3V0ZXJIVE1MKSB7XG4gICAgcmV0dXJuIGVsLm91dGVySFRNTFxuICB9IGVsc2Uge1xuICAgIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZWwuY2xvbmVOb2RlKHRydWUpKTtcbiAgICByZXR1cm4gY29udGFpbmVyLmlubmVySFRNTFxuICB9XG59XG5cblZ1ZS5jb21waWxlID0gY29tcGlsZVRvRnVuY3Rpb25zO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZ1ZTtcbiIsImlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi92dWUuY29tbW9uLnByb2QuanMnKVxufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3Z1ZS5jb21tb24uZGV2LmpzJylcbn1cbiIsInZhciBnO1xuXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxuZyA9IChmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXM7XG59KSgpO1xuXG50cnkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcblx0ZyA9IGcgfHwgbmV3IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKTtcbn0gY2F0Y2ggKGUpIHtcblx0Ly8gVGhpcyB3b3JrcyBpZiB0aGUgd2luZG93IHJlZmVyZW5jZSBpcyBhdmFpbGFibGVcblx0aWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpIGcgPSB3aW5kb3c7XG59XG5cbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXG4vLyBlYXNpZXIgdG8gaGFuZGxlIHRoaXMgY2FzZS4gaWYoIWdsb2JhbCkgeyAuLi59XG5cbm1vZHVsZS5leHBvcnRzID0gZztcbiIsIi8qKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogIEltcG9ydCBFUzYgTW9kdWxlcyAoaHR0cHM6Ly93ZWJwYWNrLmpzLm9yZy9hcGkvbW9kdWxlLW1ldGhvZHMvKVxuICogID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuaW1wb3J0IHsgR2xvYmFsaXNhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi9jb21wb25lbnRzL0dsb2JhbGlzYXRpb25TZXJ2aWNlXCI7XG5pbXBvcnQgeyBSZWdpc3RlckNvbnRyb2xsZXIgfSBmcm9tIFwiLi9jb21wb25lbnRzL1JlZ2lzdGVyQ29udHJvbGxlclwiO1xuXG5pbXBvcnQgeyBWYWxpZGF0aW9uU2VydmljZSB9IGZyb20gXCIuL2NvbXBvbmVudHMvdmFsaWRhdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IEVycm9yQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbXBvbmVudHMvZXJyb3JDb250cm9sbGVyXCI7XG5cbi8qKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogIERlcGVuZGVuY2llc1xuICogID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG4vKipcbiAqIEV4dGVybmFsXG4gKi9cbnJlcXVpcmUoJ2hhbW1lcmpzJyk7XG5yZXF1aXJlKCdvYmplY3RGaXRQb2x5ZmlsbCcpO1xucmVxdWlyZSgndXJsLXNlYXJjaC1wYXJhbXMtcG9seWZpbGwnKTtcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiAgR2xvYmFsIGZ1bmN0aW9uYWxpdGllc1xuICogID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5yZXF1aXJlKCcuL2dsb2JhbC9wb2x5ZmlsbHMvZXZlbnRQb2x5RmlsbCcpO1xucmVxdWlyZSgnLi9nbG9iYWwvcG9seWZpbGxzL2lzSW50ZWdlcicpO1xucmVxdWlyZSgnLi9nbG9iYWwvcG9seWZpbGxzL3Byb21pc2UnKTtcbnJlcXVpcmUoJy4vZ2xvYmFsL2hlbHBlcnMnKTsgLy8gU2hvdWxkIGJlIGZpcnN0XG5yZXF1aXJlKCcuL2dsb2JhbC9icm93c2VySGFuZGxlcicpO1xuLy8gcmVxdWlyZSgnLi9nbG9iYWwvcmVzaXplSGFuZGxlcicpO1xucmVxdWlyZSgnLi9nbG9iYWwvc2Nyb2xsSGFuZGxlcicpO1xuXG5cbi8qKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogIENvbXBvbmVudCBmdW5jdGlvbmFsaXRpZXNcbiAqICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxucmVxdWlyZSgnLi9jb21wb25lbnRzL2Nob2NvbGF0ZUZhY3RvcnknKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jb29raWVIYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY29udGFjdFN1YmplY3RIYW5kbGVyJyk7XG4vLyByZXF1aXJlKCcuL2NvbXBvbmVudHMvSW5wdXRIYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvZmlsZVVwbG9hZEhhbmRsZXInKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9tYXBzSGFuZGxlcicpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL292ZXJsYXlNZW51SGFuZGxlcicpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2N1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXInKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9wcm9qZWN0b3JIYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvc2Nyb2xsVG9IYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY2hvY29sYXRMaWdodGJveCcpO1xuLy8gcmVxdWlyZSgnLi9jb21wb25lbnRzL3NlYXJjaEhhbmRsZXInKTtcbi8vIHJlcXVpcmUoJy4vY29tcG9uZW50cy9zaGFyZUJ1dHRvbnNIYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdGVzdGltb25pYWxTbGlkZXJIYW5kbGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdG9nZ2xlSGFuZGxlcicpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3lvdXR1YmVIYW5kbGVyJyk7XG4vLyByZXF1aXJlKCcuL2NvbXBvbmVudHMveW91dHViZU1vZGFsSGFuZGxlcicpO1xuXG5cbi8qKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogIFZ1ZSBjb21wb25lbnRzXG4gKiAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cbnJlcXVpcmUoJy4vdnVlL3BheWJhY2tQZXJpb2QvbWFpbicpO1xuXG5cbmltcG9ydCB7S0FMfSBmcm9tICdAa29tbWEva2FsJztcbktBTC5pbml0KCk7XG5cbmxldCByZWdpc3RlckZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVnaXN0ZXJGb3JtJyk7XG5pZihyZWdpc3RlckZvcm0pIG5ldyBSZWdpc3RlckNvbnRyb2xsZXIocmVnaXN0ZXJGb3JtLCBuZXcgR2xvYmFsaXNhdGlvblNlcnZpY2UoKSk7XG5cblxuIiwiaW1wb3J0IHsgRXJyb3JSZXNwb25zZSB9IGZyb20gXCIuLi9nbG9iYWwvbW9kZWxzL2Vycm9yUmVzcG9uc2VcIjtcbmltcG9ydCB7IENvdW50cnlMYW5ndWFnZXNSZXNwb25zZSB9IGZyb20gXCIuLi9nbG9iYWwvbW9kZWxzL2NvdW50cnlMYW5ndWFnZXNSZXNwb25zZVwiO1xuXG5jbGFzcyBHbG9iYWxpc2F0aW9uU2VydmljZVxue1xuICAgIGNvbnN0cnVjdG9yKClcbiAgICB7XG4gICAgICAgIHRoaXMuX2Jhc2VSb3V0ZSA9ICcvJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcHJvZHVjdCB0byB0aGUgc2hvcHBpbmcgY2FydFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvdW50cnlJc28zXG4gICAgICovXG4gICAgZ2V0TGFuZ3VhZ2VzRm9yQ291bnRyeVdpdGhJc28zKGNvdW50cnlJc28zKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICBBamF4LnBvc3QoXG4gICAgICAgICAgICAgICAgc2VsZi5fYmFzZVJvdXRlKydnZXRMYW5ndWFnZXNGb3JDb3VudHJ5V2l0aElzbzMnLFxuICAgICAgICAgICAgICAgIHsgY291bnRyeUlzbzM6IGNvdW50cnlJc28zIH0sXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24oeGhyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxldCByZXNwb25zZSA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlzRXJyb3JSZXNwb25zZSA9IEVycm9yUmVzcG9uc2UuaXMoeGhyLnJlc3BvbnNlLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpc0NvdW50cnlMYW5ndWFnZXNSZXNwb25zZSA9IENvdW50cnlMYW5ndWFnZXNSZXNwb25zZS5pcyh4aHIucmVzcG9uc2UsIGZhbHNlKTtcblxuICAgICAgICAgICAgICAgICAgICBpZighaXNFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZihpc0NvdW50cnlMYW5ndWFnZXNSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UgPSBDb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UuZnJvbUpzb25TdHJpbmcoeGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGNvdW50cnlMYW5ndWFnZXNSZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSZWdpc3RlclNlcnZpY2U6Z2V0TGFuZ3VhZ2VzRm9yQ291bnRyeVdpdGhJc28zIFRoZSByZXNwb25zZSB3YXMgbm90IGEgdmFsaWQgQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlOiAnK3hoci5yZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBFcnJvclJlc3BvbnNlLmZyb21Kc29uU3RyaW5nKHhoci5yZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn1cblxuZXhwb3J0IHsgR2xvYmFsaXNhdGlvblNlcnZpY2UgfSIsImNsYXNzIFJlZ2lzdGVyQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtIVE1MRGl2RWxlbWVudH0gd3JhcHBlclxuICAgICAqIEBwYXJhbSB7R2xvYmFsaXNhdGlvblNlcnZpY2V9IGdsb2JhbGlzYXRpb25TZXJ2aWNlXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod3JhcHBlciwgZ2xvYmFsaXNhdGlvblNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5fd3JhcHBlciA9IHdyYXBwZXI7XG4gICAgICAgIGlmKCF0aGlzLl93cmFwcGVyIHx8IHRoaXMuX3dyYXBwZXIudGFnTmFtZSAhPT0gXCJGT1JNXCIpXG4gICAgICAgIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JlZ2lzdGVyQ29udHJvbGxlcjogVGhlIFJlZ2lzdGVyIGZvcm0gbXVzdCBiZSBhIGRpdiBlbGVtZW50IGJ1dCB3YXMgbm90IG9yIHdhc25cXCd0IGV2ZW4gc3BlY2lmaWVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY291bnRyeVNlbGVjdCA9IHRoaXMuX3dyYXBwZXIucXVlcnlTZWxlY3Rvcignc2VsZWN0W25hbWU9XCJjb3VudHJ5XCJdJyk7XG4gICAgICAgIGlmKCF0aGlzLl9jb3VudHJ5U2VsZWN0KSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSZWdpc3RlckNvbnRyb2xsZXI6IFRoZSBSZWdpc3RlciBmb3JtIG11c3QgaGF2ZSBhIHNlbGVjdCBlbGVtZW50IHdpdGggbmFtZSBcImNvdW50cnlcIiBidXQgZGlkIG5vdCBoYXZlIGl0LicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2VTZWxlY3QgPSB0aGlzLl93cmFwcGVyLnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdFtuYW1lPVwibGFuZ3VhZ2VcIl0nKTtcbiAgICAgICAgaWYoIXRoaXMuX2NvdW50cnlTZWxlY3QpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JlZ2lzdGVyQ29udHJvbGxlcjogVGhlIFJlZ2lzdGVyIGZvcm0gbXVzdCBoYXZlIGEgc2VsZWN0IGVsZW1lbnQgd2l0aCBuYW1lIFwibGFuZ3VhZ2VcIiBidXQgZGlkIG5vdCBoYXZlIGl0LicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2VTZWxlY3RXcmFwcGVyID0gdGhpcy5fd3JhcHBlci5xdWVyeVNlbGVjdG9yKCcuanMtbGFuZ3VhZ2Utd3JhcHBlcicpO1xuICAgICAgICBpZighdGhpcy5fbGFuZ3VhZ2VTZWxlY3RXcmFwcGVyIHx8IHRoaXMuX2xhbmd1YWdlU2VsZWN0V3JhcHBlci50YWdOYW1lICE9PSBcIkRJVlwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSZWdpc3RlckNvbnRyb2xsZXI6IFRoZSBSZWdpc3RlciBmb3JtIG11c3QgaGF2ZSBhIHdyYXBwZXIgRElWIGVsZW1lbnQgd2l0aCBjbGFzcyBcImpzLWxhbmd1YWdlLXdyYXBwZXJcIiBidXQgZGlkIG5vdCBoYXZlIGl0LicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cblxuICAgICAgICB0aGlzLl9nbG9iYWxpc2F0aW9uU2VydmljZSA9IGdsb2JhbGlzYXRpb25TZXJ2aWNlO1xuICAgICAgICBpZighZ2xvYmFsaXNhdGlvblNlcnZpY2UpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JlZ2lzdGVyQ29udHJvbGxlcjogVGhlIFJlZ2lzdGVyIGZvcm0gd2FzIGV4cGVjdGVkIHRvIGdldCBhbiBpbnN0YW5jZSBvZiBSZWdpc3RlclNlcnZpY2UsIGJ1dCBkaWQgbm90IGdldCBvbmUuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9oaWRkZW5DbGFzcyA9ICd1LWhpZGRlbic7IC8vVGhlIG5hbWUgb2YgYSBjbGFzcyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIHRoaW5ncyB0byBoaWRlIHRoZW0uXG5cbiAgICAgICAgdGhpcy5fZG9tUGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuXG4gICAgICAgIHRoaXMuX2NvdW50cnlDaGFuZ2VkID0gdGhpcy5fY291bnRyeUNoYW5nZWQuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb250cm9sTGlzdGVuZXJzKHRydWUpO1xuXG4gICAgICAgIHRoaXMuX2NvdW50cnlDaGFuZ2VkKCk7XG4gICAgfVxuXG4gICAgY29udHJvbExpc3RlbmVycyhlbmFibGUgPSB0cnVlKSB7XG4gICAgICAgIHRoaXMuX2NvdW50cnlTZWxlY3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fY291bnRyeUNoYW5nZWQpO1xuXG4gICAgICAgIGlmKGVuYWJsZSkge1xuICAgICAgICAgICAgdGhpcy5fY291bnRyeVNlbGVjdC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9jb3VudHJ5Q2hhbmdlZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9jb3VudHJ5Q2hhbmdlZCgpIHtcbiAgICAgICAgbGV0IGNvdW50cnlJc28zID0gdGhpcy5fY291bnRyeVNlbGVjdC52YWx1ZTtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIHRoaXMuX2dsb2JhbGlzYXRpb25TZXJ2aWNlLmdldExhbmd1YWdlc0ZvckNvdW50cnlXaXRoSXNvMyhjb3VudHJ5SXNvMykudGhlbihcbiAgICAgICAgICAgIC8qKiBAcGFyYW0geyBDb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UgfSBjb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UgKiovXG4gICAgICAgICAgICBmdW5jdGlvbihjb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9jbGVhckxhbmd1YWdlU2VsZWN0KCk7XG4gICAgICAgICAgICAgICAgbGV0IGxhbmd1YWdlQ291bnQgPSBjb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UubGFuZ3VhZ2VzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBmb3IobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsYW5ndWFnZUNvdW50OyBpbmRleCsrKVxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxhbmd1YWdlID0gY291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlLmxhbmd1YWdlc1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgIGxldCBvcHRpb25FbGVtZW50ID0gc2VsZi5fY3JlYXRlSHRtbEVsZW1lbnRGcm9tU3RyaW5nKCc8b3B0aW9uIHZhbHVlPVwiJytsYW5ndWFnZS50aHJlZUxldHRlcklzb0xhbmd1YWdlTmFtZSsnXCI+JytsYW5ndWFnZS5uYXRpdmVOYW1lKyc8L29wdGlvbj4nKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fbGFuZ3VhZ2VTZWxlY3QuYXBwZW5kQ2hpbGQob3B0aW9uRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYobGFuZ3VhZ2VDb3VudCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuX2xhbmd1YWdlU2VsZWN0V3JhcHBlci5jbGFzc0xpc3QuYWRkKHNlbGYuX2hpZGRlbkNsYXNzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9sYW5ndWFnZVNlbGVjdFdyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZShzZWxmLl9oaWRkZW5DbGFzcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApLmNhdGNoKFxuICAgICAgICAgICAgLyoqIEBwYXJhbSB7IEVycm9yUmVzcG9uc2UgfSBlcnJvclJlc3BvbnNlICoqL1xuICAgICAgICAgICAgZnVuY3Rpb24oZXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JSZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9jbGVhckxhbmd1YWdlU2VsZWN0KClcbiAgICB7XG4gICAgICAgIHdoaWxlKHRoaXMuX2xhbmd1YWdlU2VsZWN0LmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fbGFuZ3VhZ2VTZWxlY3QucmVtb3ZlQ2hpbGQodGhpcy5fbGFuZ3VhZ2VTZWxlY3QuZmlyc3RDaGlsZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmcm9tXG4gICAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gICAgICovXG4gICAgX2NyZWF0ZUh0bWxFbGVtZW50RnJvbVN0cmluZyhmcm9tKVxuICAgIHtcbiAgICAgICAgbGV0IGRvY3VtZW50ID0gdGhpcy5fZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhmcm9tLCAndGV4dC9odG1sJyk7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5ib2R5LmZpcnN0Q2hpbGQ7XG4gICAgfVxufVxuXG5leHBvcnQgeyBSZWdpc3RlckNvbnRyb2xsZXIgfSIsImltcG9ydCBDaG9jb2xhdCBmcm9tICdjaG9jb2xhdCdcblxuQ2hvY29sYXQoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmpzLWxpZ2h0Ym94JyksIHtcbiAgICAvLyBvcHRpb25zIGhlcmVcbn0pIiwiLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiB8IFByZXZlbnQgQm90cyBoYW5kbGVyXG4gfFxuIHwgV2UgbmFtZWQgdGhpcyBjaG9jb2xhdGUgZmFjdG9yeSBhbmQgYmVsb25naW5nIGNvbmZ1c2luZyBqcyBob29rc1xuIHwgdG8gcHJldmVudCBzbWFydCBib3RzIGZyb20gYmxvY2tpbmcgdGhlc2UgdmFyaWFibGUgb3IgZnVuY3Rpb25zLlxuIHxcbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5jb25zdCBDaG9jb2xhdGVGYWN0b3J5ID0ge1xuXG4gICAgYmFubmVkVmlzaXRvcjogW10sXG5cbiAgICAvKiogR2V0IGFsbCB0aGUgY2hvY29sYXRlIGZhY3RvcnkgYW5kIHN0YXJ0XG4gICAgICogIExvb3BpbmcgdGhyb3VnaCB0aG9zZSBzdGFydCBmbGFzaGluZyB0aWNrZXRzXG4gICAgICovXG4gICAgZW50ZXI6IGZ1bmN0aW9uKClcbiAgICB7XG5cbiAgICAgICAgY29uc3QgY2hvY29sYXRlRmFjdG9yaWVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmpzLWNob2NvbGF0ZS1mYWN0b3J5Jyk7XG5cbiAgICAgICAgaWYoaXNzZXQoY2hvY29sYXRlRmFjdG9yaWVzKSl7XG5cbiAgICAgICAgICAgIGNvbnN0IGFtb3VudE9mQ2hvY29sYXRlRmFjdG9yaWVzID0gY2hvY29sYXRlRmFjdG9yaWVzLmxlbmd0aDtcbiAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBhbW91bnRPZkNob2NvbGF0ZUZhY3RvcmllczsgaSsrKXtcblxuICAgICAgICAgICAgICAgIGNvbnN0IENob2NvbGF0ZUJhciA9IGNob2NvbGF0ZUZhY3Rvcmllc1tpXTtcbiAgICAgICAgICAgICAgICBDaG9jb2xhdGVGYWN0b3J5Ll9mbGFzaFRpY2tldChDaG9jb2xhdGVCYXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIElmIGZhY3RvcnkgaGFzIGEgZ29sZGVuIHRpY2tldFxuICAgICAqIFRoZW4gd2UgY2FuIG1ha2UgdGhlbSBnbyBvbiB0aGUgdG91ciBpZiB0aGVyZSBoYXMgYmVlbiBjbGljayBvbiB0aGUgdGlja2V0XG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hvY29sYXRlQmFyXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfZmxhc2hUaWNrZXQ6IGZ1bmN0aW9uIChjaG9jb2xhdGVCYXIpIHtcblxuICAgICAgICAvLyBUcnkgZ2V0IHRoZSB0aWNrZXQgZnJvbSB0aGUgY2hvY29sYXRlQmFyXG4gICAgICAgIGNvbnN0IGdvbGRlblRpY2tldCA9IGNob2NvbGF0ZUJhci5xdWVyeVNlbGVjdG9yKCcuanMtZ29sZGVuLXRpY2tldCcpO1xuXG4gICAgICAgIC8vIE9ubHkgY29udGludWUgaWYgY2hvY29sYXRlIGJhciBoYXMgYSBnb2xkZW4gdGlja2V0XG4gICAgICAgIGlmKGlzc2V0KGdvbGRlblRpY2tldCkpe1xuXG4gICAgICAgICAgICBnb2xkZW5UaWNrZXQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgQ2hvY29sYXRlRmFjdG9yeS5lbmpveVRoZVRvdXIoY2hvY29sYXRlQmFyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2V7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnVG8gYmFkLCBubyBnb2xkZW4gdGlja2V0cyBoYXMgYmVlbiBmb3VuZC4nKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgdG91ciB0aHJvdWdoIHRoZSBmYWN0b3J5XG4gICAgICogQW5kIGdldCB0aGUgbmFtZXMgYW5kIHByb3BlcnRpZXMgb2YgdGhlIG1lbWJlcnMgb2YgdGhlIGdyb3VwXG4gICAgICogSWYgdGhlcmUgYXJlIG1lbWJlcnMgaW4gdGhlIGdyb3VwIG9mIGNvdXJzZVxuICAgICAqXG4gICAgICogQHBhcmFtIGNob2NvbGF0ZUZhY3RvcnlcbiAgICAgKi9cbiAgICBlbmpveVRoZVRvdXIoY2hvY29sYXRlRmFjdG9yeSl7XG5cbiAgICAgICAgLy8gQXNrIGZvciB0aGUgdG91ciBncm91cFxuICAgICAgICBjb25zdCB0b3VyR3JvdXAgPSBjaG9jb2xhdGVGYWN0b3J5LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0LCB0ZXh0YXJlYSwgc2VsZWN0Jyk7XG5cbiAgICAgICAgaWYoaXNzZXQodG91ckdyb3VwKSl7XG5cbiAgICAgICAgICAgIC8vIEZvciBlYWNoIHZpc2l0b3Igd2Ugd2FudCBhIGJlbG9uZ2luZyBPb21wYSBMb29tcGFcbiAgICAgICAgICAgIGxldCBvb21wYUxvb21wYXMgPSB7fTtcbiAgICAgICAgICAgIGxldCBhbW91bnRPZk9vbXBhTG9vbXBhcyA9IDA7XG5cbiAgICAgICAgICAgIGNvbnN0IHRvdXJHcm91cFNpemUgPSB0b3VyR3JvdXAubGVuZ3RoO1xuICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRvdXJHcm91cFNpemU7IGkrKyl7XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHZpc2l0b3IgZnJvbSB0aGUgZ3JvdXBcbiAgICAgICAgICAgICAgICBjb25zdCB2aXNpdG9yID0gdG91ckdyb3VwW2ldO1xuXG4gICAgICAgICAgICAgICAgLy8gQXNrIGZvciBpdHMgbmFtZVxuICAgICAgICAgICAgICAgIGNvbnN0IHZpc2l0b3JOYW1lID0gdmlzaXRvci5nZXRBdHRyaWJ1dGUoJ25hbWUnKTtcblxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSB2aXNpdG9yIGlzIGJhbm5lZFxuICAgICAgICAgICAgICAgIGlmKCBDaG9jb2xhdGVGYWN0b3J5Ll9pc1Zpc2l0b3JCYW5uZWQodmlzaXRvck5hbWUpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIG9vbXBhTG9vbXBhc1sgdmlzaXRvck5hbWUgXSA9IENob2NvbGF0ZUZhY3RvcnkuX2dldEFycmFuZ2VtZW50KHZpc2l0b3IpO1xuICAgICAgICAgICAgICAgIGFtb3VudE9mT29tcGFMb29tcGFzKys7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGZvciBpbnN1cmFuY2UgdGhhdCB0aGVyZSBhcmUgb29tcGEgbG9vbXBhc1xuICAgICAgICAgICAgaWYoYW1vdW50T2ZPb21wYUxvb21wYXMgPT09IDApIHJldHVybjtcblxuICAgICAgICAgICAgLy8gU2VuZCBzdWJtaXQgcmVxdWVzdFxuICAgICAgICAgICAgQ2hvY29sYXRlRmFjdG9yeS5fZmluaXNoVG91cihvb21wYUxvb21wYXMsIGNob2NvbGF0ZUZhY3RvcnkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2V7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnVG8gYmFkLCBubyBtZW1iZXJzIHRvIHZpc2l0IHRoaXMgZmFjdG9yeScpXG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgdGhlIHZpc2l0b3IgbmFtZSBpc24ndCBhbGxvd1xuICAgICAqXG4gICAgICogQHBhcmFtIHZpc2l0b3JOYW1lXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfaXNWaXNpdG9yQmFubmVkOiBmdW5jdGlvbih2aXNpdG9yTmFtZSl7XG4gICAgICAgIGlmKENob2NvbGF0ZUZhY3RvcnkuYmFubmVkVmlzaXRvci5pbmRleE9mKHZpc2l0b3JOYW1lKSAhPT0gLTEpe1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBNb3N0IGdldCB2aXNpdG9yIGhhdmUgYSBub3JtYWwgYXJyYW5nZW1lbnRcbiAgICAgKiBCdXQgc29tZXRpbWVzIHRoZXJlIGFyZSBzcGVjaWFsIGNhc2VzXG4gICAgICogTGlrZSBhIFNlbGVjdG9yIG9yIGNoZWNrYm94XG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmlzaXRvclxuICAgICAqIEByZXR1cm5zIHsqfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2dldEFycmFuZ2VtZW50OiBmdW5jdGlvbih2aXNpdG9yKVxuICAgIHtcblxuICAgICAgICBjb25zdCB2aXNpdG9yVHlwZSA9IHZpc2l0b3Iubm9kZU5hbWU7XG5cbiAgICAgICAgaWYodmlzaXRvci50eXBlID09PSAncmFkaW8nKSB7XG4gICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cIicgKyB2aXNpdG9yLm5hbWUgKyAnXCJdOmNoZWNrZWQnKS52YWx1ZVxuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoICh2aXNpdG9yVHlwZSkge1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXRvci52YWx1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggdGhlIHRvdXJcbiAgICAgKiBJZiBzdWNjZXNzZnVsIHNob3cgdGhhbmtzIG1lc3NhZ2VcbiAgICAgKiBPciBzaG93IGRlZmluZWQgZXJyb3IgbWVzc2FnZSBvciBmYWxsYmFja1xuICAgICAqXG4gICAgICogQHBhcmFtIGdyb3VwXG4gICAgICogQHBhcmFtIGNob2NvbGF0ZUZhY3RvcnlcbiAgICAgKiBAcmV0dXJucyB7Knx2b2lkfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2ZpbmlzaFRvdXI6IGZ1bmN0aW9uKGdyb3VwLCBjaG9jb2xhdGVGYWN0b3J5KVxuICAgIHtcbiAgICAgICAgLy8gQWRkIHdpbGxpZSB0byB0aGUgZ3JvdXBcbiAgICAgICAgZ3JvdXAgPSBDaG9jb2xhdGVGYWN0b3J5Ll9hZGRXaWxsaWVXb25rYShncm91cCk7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBnYXRlIGZvciBmaW5pc2ggdGhlIHRvdXJcbiAgICAgICAgY29uc3QgZ2F0ZSA9ICcvY29udGFjdC9wcm9jZXNzJztcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgQWpheC5wb3N0KGdhdGUsIGdyb3VwLCBmdW5jdGlvbiAoSHR0cFJlcXVlc3QpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5wYXJzZShIdHRwUmVxdWVzdC5yZXNwb25zZSk7XG5cbiAgICAgICAgICAgICAgICBzd2l0Y2ggKEh0dHBSZXF1ZXN0LnN0YXR1cykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDIwMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDaG9jb2xhdGVGYWN0b3J5Ll90aGFua3NGb3JWaXNpdGluZyhyZXNwb25zZS5yZWRpcmVjdFVybCk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDIyOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENob2NvbGF0ZUZhY3RvcnkuX2dpdmVGZWVkYmFja1RvTWVtYmVycyhyZXNwb25zZS5lcnJvcnMsIGNob2NvbGF0ZUZhY3RvcnkpO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIENob2NvbGF0ZUZhY3RvcnkuX3Vua25vd25HYXBJbkZhY3RvcnkoY2hvY29sYXRlRmFjdG9yeSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIENob2NvbGF0ZUZhY3RvcnkuX3Vua25vd25HYXBJbkZhY3RvcnkoY2hvY29sYXRlRmFjdG9yeSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIHdpbGxpZSB3b25rYSB0byB0aGUgZ3JvdXBcbiAgICAgKiBQcy4uLiBpdCBhY3R1YWxseSB0aGUgc2VjcmV0IGNvZGUhXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZ3JvdXBcbiAgICAgKiBAcmV0dXJucyB7Kn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9hZGRXaWxsaWVXb25rYTogZnVuY3Rpb24oZ3JvdXApe1xuICAgICAgICBncm91cC5fd2lsbGllID0gJ3dvbmthJztcbiAgICAgICAgcmV0dXJuIGdyb3VwO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgdGhlIGZlZWRiYWNrIHRvIHRoZSBkZXNpcmVkIGFyZWEuXG4gICAgICogTW9zdCBsaWtlbHkgdG8gdGhlIHZpc2l0b3IgZGlyZWN0bHksIGJ1dCBzb21ldGltZSB0byB0aGUgZmFjdG9yeSBkZXNpcmVkIGZlZWRiYWNrIGFyZWFcbiAgICAgKlxuICAgICAqIEBwYXJhbSBlcnJvcnNcbiAgICAgKiBAcGFyYW0gY2hvY29sYXRlRmFjdG9yeVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2dpdmVGZWVkYmFja1RvTWVtYmVyczogZnVuY3Rpb24oZXJyb3JzLCBjaG9jb2xhdGVGYWN0b3J5KXtcblxuICAgICAgICAvLyBHcmFiIHRoZSBmYWN0b3J5IGZlZWRiYWNrIGFyZWFcbiAgICAgICAgY29uc3QgZmVlZGJhY2tBcmVhID0gY2hvY29sYXRlRmFjdG9yeS5xdWVyeVNlbGVjdG9yKCcuanMtZXJyb3ItYXJlYScpO1xuXG4gICAgICAgIC8vIENsZWFyIHRoZSBjdXJyZW50IGh0bWxcbiAgICAgICAgaWYoaXNzZXQoZmVlZGJhY2tBcmVhKSkgZmVlZGJhY2tBcmVhLmlubmVySFRNTCA9ICcnO1xuXG4gICAgICAgIC8vIENsZWFyIHRoZSBwcmV2aW91cyBtYXJrZWQgamFja2V0c1xuICAgICAgICBDaG9jb2xhdGVGYWN0b3J5Ll9jbGVhclByZXZpb3VzTWFya2VkSmFja2V0cyhjaG9jb2xhdGVGYWN0b3J5KTtcblxuICAgICAgICBPYmplY3Qua2V5cyhlcnJvcnMpLmZvckVhY2goZnVuY3Rpb24odmlzaXRvcikge1xuXG4gICAgICAgICAgICBsZXQgamFja2V0ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCB2aXNpdG9yRmVlZGJhY2tBcmVhID0gbnVsbDtcblxuICAgICAgICAgICAgLy8gSG9uZXkgZWxlbWVudHMgZG9lc24ndCBoYXMgYSBhY2Nlc3NpYmxlIGVsZW1lbnRcbiAgICAgICAgICAgIGlmKHZpc2l0b3IgIT09ICdfaG9uZXknICYmIHZpc2l0b3IgIT09ICdfc2VjcmV0Q29kZScpIHtcblxuICAgICAgICAgICAgICAgIC8vIEdyYWIgdGhlIHZpc2l0b3JcbiAgICAgICAgICAgICAgICBjb25zdCB2aXNpdG9yTm9kZSA9IGNob2NvbGF0ZUZhY3RvcnkucXVlcnlTZWxlY3RvcignIycgKyB2aXNpdG9yKTtcblxuICAgICAgICAgICAgICAgIC8vIEZpbmQgdGhlIGphY2tldCBvZiBhIHZpc2l0b3JcbiAgICAgICAgICAgICAgICBqYWNrZXQgPSBDaG9jb2xhdGVGYWN0b3J5Ll9ncmFiVmlzaXRvckphY2tldCh2aXNpdG9yTm9kZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBmb3VuZCBnZXQgdGhlIGRlc2lyZWQgYXJlYVxuICAgICAgICAgICAgICAgIGlmKGlzc2V0KGphY2tldCkpIHZpc2l0b3JGZWVkYmFja0FyZWEgPSBqYWNrZXQucXVlcnlTZWxlY3RvcignLmpzLWZvcm0tZWxlbWVudC1lcnJvcicpO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGN1cnJlbnQgaHRtbFxuICAgICAgICAgICAgICAgIGlmKGlzc2V0KHZpc2l0b3JGZWVkYmFja0FyZWEpKSB2aXNpdG9yRmVlZGJhY2tBcmVhLmlubmVySFRNTCA9ICcnO1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEdldCB0aGUgZmVlZGJhY2sgZm9yIHRoaXMgdmlzaXRvclxuICAgICAgICAgICAgY29uc3QgdmlzaXRvckZlZWRiYWNrID0gZXJyb3JzW3Zpc2l0b3JdO1xuXG4gICAgICAgICAgICAvLyBTcGl0IG91dCBlYWNoIGxpbmVcbiAgICAgICAgICAgIGNvbnN0IHZpc2l0b3JGZWVkYmFja0Ftb3VudCA9IHZpc2l0b3JGZWVkYmFjay5sZW5ndGg7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdmlzaXRvckZlZWRiYWNrQW1vdW50OyBpKyspe1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpc2l0b3JGZWVkYmFja0xpbmUgPSB2aXNpdG9yRmVlZGJhY2tbaV07XG5cbiAgICAgICAgICAgICAgICAvLyBIb25leSBlbGVtZW50cyBkb2Vzbid0IGhhcyBhIGFjY2Vzc2libGUgZWxlbWVudCBhcmVhXG4gICAgICAgICAgICAgICAgaWYodmlzaXRvciAhPT0gJ19ob25leScgJiYgdmlzaXRvciAhPT0gJ19zZWNyZXRDb2RlJykge1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIE1hcmsgdGhlIGphY2tldFxuICAgICAgICAgICAgICAgICAgICBpZihpc3NldChqYWNrZXQpKSBqYWNrZXQuY2xhc3NMaXN0LmFkZCgnaGFzLWVycm9yJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQXBwZW5kIGZlZWRiYWNrIHRvIHZpc2l0b3IgZmVlZGJhY2sgYXJlYSBpZiBkZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIGlmKGlzc2V0KHZpc2l0b3JGZWVkYmFja0FyZWEpKVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY3VycmVudEZlZWRiYWNrQXJlYSA9IHZpc2l0b3JGZWVkYmFja0FyZWEuaW5uZXJIVE1MO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZlZWRiYWNrQXJlYSArPSAnPHNwYW4+JyArIGNhcGl0YWxpemVGaXJzdExldHRlcih2aXNpdG9yRmVlZGJhY2tMaW5lKSArICc8L3NwYW4+JztcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0b3JGZWVkYmFja0FyZWEuaW5uZXJIVE1MID0gY3VycmVudEZlZWRiYWNrQXJlYTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFwcGVuZCBmZWVkYmFjayB0byBmYWN0b3J5IGZlZWRiYWNrIGFyZWEgaWYgZGVmaW5lZFxuICAgICAgICAgICAgICAgIGlmKGlzc2V0KGZlZWRiYWNrQXJlYSkpe1xuICAgICAgICAgICAgICAgICAgICBsZXQgY3VycmVudEZlZWRiYWNrQXJlYSA9IGZlZWRiYWNrQXJlYS5pbm5lckhUTUw7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGZWVkYmFja0FyZWEgKz0gJzxsaT4nICsgY2FwaXRhbGl6ZUZpcnN0TGV0dGVyKHZpc2l0b3JGZWVkYmFja0xpbmUpICsgJzwvbGk+JztcbiAgICAgICAgICAgICAgICAgICAgZmVlZGJhY2tBcmVhLmlubmVySFRNTCA9IGN1cnJlbnRGZWVkYmFja0FyZWE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0b3AgPSBib2R5T2Zmc2V0KGNob2NvbGF0ZUZhY3RvcnkpLnRvcCAtIDE0MDtcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHRvcCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBwcmV2aW91cyBtYXJrZWQgamFja2V0c1xuICAgICAqXG4gICAgICogQHBhcmFtIGNob2NvbGF0ZUZhY3RvcnlcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9jbGVhclByZXZpb3VzTWFya2VkSmFja2V0cyhjaG9jb2xhdGVGYWN0b3J5KSB7XG5cbiAgICAgICAgY29uc3QgbWFya2VkSmFja2V0cyA9IGNob2NvbGF0ZUZhY3RvcnkucXVlcnlTZWxlY3RvckFsbCgnLmhhcy1lcnJvcicpO1xuICAgICAgICBjb25zdCBtYXJrZWRKYWNrZXRzQW1vdW50ID0gbWFya2VkSmFja2V0cy5sZW5ndGg7XG5cbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IG1hcmtlZEphY2tldHNBbW91bnQ7IGkrKyl7XG5cbiAgICAgICAgICAgIGNvbnN0IG1hcmtlZEphY2tldCA9IG1hcmtlZEphY2tldHNbaV07XG4gICAgICAgICAgICBtYXJrZWRKYWNrZXQuY2xhc3NMaXN0LnJlbW92ZSgnaGFzLWVycm9yJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IG1hcmtlZEphY2tldE1lc3NhZ2UgPSBtYXJrZWRKYWNrZXQucXVlcnlTZWxlY3RvcignLmpzLWZvcm0tZWxlbWVudC1lcnJvcicpO1xuICAgICAgICAgICAgaWYoaXNzZXQobWFya2VkSmFja2V0TWVzc2FnZSkpIG1hcmtlZEphY2tldE1lc3NhZ2UuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR3JhYiB0aGUgamFja2V0IG9mIHRoZSB2aXNpdG9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmlzaXRvclxuICAgICAqIEByZXR1cm5zIHtudWxsfCp8KCgpID0+IChOb2RlIHwgbnVsbCkpfEFjdGl2ZVguSVhNTERPTU5vZGV8KE5vZGUgJiBQYXJlbnROb2RlKX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9ncmFiVmlzaXRvckphY2tldDogZnVuY3Rpb24odmlzaXRvcil7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdmlzaXRvciBpcyBkZWZpbmVkXG4gICAgICAgIGlmICghaXNzZXQodmlzaXRvcikpIHJldHVybiBudWxsO1xuXG4gICAgICAgIC8vIERvIGxvb3Agc2V0dGluZ3NcbiAgICAgICAgY3VycmVudExheWVyID0gdmlzaXRvcjtcbiAgICAgICAgc2FmZXR5QnJlYWsgPSAwO1xuXG4gICAgICAgIC8vIEdyYWIgdGhlIG5leHQgbGF5ZXIgdGlsbCBpdCBpcyB0aGUgamFja2V0IChvciBzYWZldHlCcmVhayBoYXMgYmVlbiByZWFjaGVkXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIHNhZmV0eUJyZWFrKys7XG4gICAgICAgICAgICBjdXJyZW50TGF5ZXIgPSBjdXJyZW50TGF5ZXIucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIGlmKGN1cnJlbnRMYXllci5jbGFzc0xpc3QuY29udGFpbnMoJ2pzLWZvcm0tZWxlbWVudCcpKSByZXR1cm4gY3VycmVudExheWVyO1xuICAgICAgICB9IHdoaWxlIChjdXJyZW50TGF5ZXIudGFnTmFtZSAhPT0gJ0JPRFknICYmIHNhZmV0eUJyZWFrIDw9IDEwKTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVkaXJlY3QgdGhlIHZpc2l0b3IgdG8gdGhlIHRoYW5rcyBwYWdlXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmV4dFN0b3BcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF90aGFua3NGb3JWaXNpdGluZzogZnVuY3Rpb24gKG5leHRTdG9wKSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IG5leHRTdG9wO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBVbmtub3duIGVycm9yIG9jY3VycmVkLCBsb2cgdGhlIGVycm9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hvY29sYXRlRmFjdG9yeVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3Vua25vd25HYXBJbkZhY3Rvcnk6IGZ1bmN0aW9uIChjaG9jb2xhdGVGYWN0b3J5KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNob2NvbGF0ZUZhY3RvcnkpO1xuICAgICAgICBjb25zb2xlLmxvZygnQ2hvY29sYXRlRmFjdG9yeTogVW5rb3duIEVycm9yJyk7XG4gICAgfSxcbn07XG5cbkNob2NvbGF0ZUZhY3RvcnkuZW50ZXIoKTsiLCJjb25zdCBDb250YWN0U3ViamVjdEhhbmRsZXIgPSB7XG5cbiAgICBzdWJqZWN0T3B0aW9uczogbnVsbCxcbiAgICBzdWJqZWN0T3B0aW9uYWxGaWVsZHM6IG51bGwsXG4gICAgc2hvd09wdGlvbmFsRmllbGRzRm9yU3ViamVjdE9wdGlvbnM6IFsnb3JkZXJzJywgJ3BhcnRzJ10sXG5cbiAgICBpbml0IDogZnVuY3Rpb24oKVxuICAgIHtcbiAgICAgICAgLy8gR2V0IHRoZSBmb3JtIGlucHV0c1xuICAgICAgICBDb250YWN0U3ViamVjdEhhbmRsZXIuc3ViamVjdE9wdGlvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuanMtY29udGFjdC1zdWJqZWN0Jyk7XG4gICAgICAgIENvbnRhY3RTdWJqZWN0SGFuZGxlci5zdWJqZWN0T3B0aW9uYWxGaWVsZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtY29udGFjdC1zdWJqZWN0LW9wdGlvbmFsJyk7XG5cbiAgICAgICAgY29uc3Qgc3ViamVjdE9wdGlvbnNMZW5ndGggPSBDb250YWN0U3ViamVjdEhhbmRsZXIuc3ViamVjdE9wdGlvbnMubGVuZ3RoO1xuICAgICAgICBpZihzdWJqZWN0T3B0aW9uc0xlbmd0aCA8PSAwIHx8ICFpc3NldChDb250YWN0U3ViamVjdEhhbmRsZXIuc3ViamVjdE9wdGlvbmFsRmllbGRzKSkgcmV0dXJuO1xuXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBzdWJqZWN0T3B0aW9uc0xlbmd0aDsgaSsrKXtcblxuICAgICAgICAgICAgY29uc3Qgc3ViamVjdE9wdGlvbiA9IENvbnRhY3RTdWJqZWN0SGFuZGxlci5zdWJqZWN0T3B0aW9uc1tpXTtcbiAgICAgICAgICAgIHN1YmplY3RPcHRpb24uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgQ29udGFjdFN1YmplY3RIYW5kbGVyLnN1YmplY3RDaGFuZ2VkKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzdWJqZWN0Q2hhbmdlZDogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdE9wdGlvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1jb250YWN0LXN1YmplY3Q6Y2hlY2tlZCcpO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIHZhbHVlIGlzIGluIHRoZSBzaG93T3B0aW9uYWxGaWVsZHNGb3JTdWJqZWN0T3B0aW9uc1xuICAgICAgICBpZihDb250YWN0U3ViamVjdEhhbmRsZXIuc2hvd09wdGlvbmFsRmllbGRzRm9yU3ViamVjdE9wdGlvbnMuaW5kZXhPZihzZWxlY3RPcHRpb24udmFsdWUpICE9PSAtMSkge1xuICAgICAgICAgICAgQ29udGFjdFN1YmplY3RIYW5kbGVyLnN1YmplY3RPcHRpb25hbEZpZWxkcy5jbGFzc0xpc3QucmVtb3ZlKCdpcy1oaWRkZW4nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIENvbnRhY3RTdWJqZWN0SGFuZGxlci5zdWJqZWN0T3B0aW9uYWxGaWVsZHMuY2xhc3NMaXN0LmFkZCgnaXMtaGlkZGVuJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG59O1xuXG5Db250YWN0U3ViamVjdEhhbmRsZXIuaW5pdCgpOyIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICBDb29raWUgaGFuZGxlclxuICAgLSBQcmltYXJ5IHVzYWdlIGZvciB0b2dnbGluZyB0aGUgY29va2llIG1lc3NhZ2UgYW5kL29yIHN3aXRjaFxuID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbmNvbnN0IENvb2tpZUhhbmRsZXIgPSB7XG5cbiAgICBjb29raWVCYXIgOiBudWxsLFxuICAgIGNvb2tpZU92ZXJsYXkgOiBudWxsLFxuICAgIGNvb2tpZU1lc3NhZ2UgOiBudWxsLFxuXG4gICAgY29va2llU3dpdGNoIDogbnVsbCxcblxuICAgIGNvb2tpZUZhZGVPdXRBbmltYXRpb25EdXJhdGlvbiA6IDQwMCxcbiAgICBhY2NlcHRUcmFja2luZyA6IGZhbHNlLFxuXG4gICAgLy8gSW5pdGlhbGl6ZSBjb29raWUgaGFuZGxlclxuICAgIGluaXQgOiBmdW5jdGlvbigpXG4gICAge1xuICAgICAgICAvLyBCaW5kIGNvb2tpZSBiYXIgb3Igb3ZlcmxheSB0byBjb29raWVNZXNzYWdlXG4gICAgICAgIENvb2tpZUhhbmRsZXIuY29va2llTWVzc2FnZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1jb29raWUtYmFyLCAuanMtY29va2llLW92ZXJsYXknKTtcblxuICAgICAgICAvLyBCaW5kIGNvb2tpZSBiYXIgdG8gY29va2llQmFyXG4gICAgICAgIENvb2tpZUhhbmRsZXIuY29va2llQmFyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWNvb2tpZS1iYXInKTtcblxuICAgICAgICAvLyBJZiBpc3NldCBpbml0IHRoZSBmdW5jdGlvbnMgZm9yIGNvb2tpZSBiYXJcbiAgICAgICAgaWYoaXNzZXQoQ29va2llSGFuZGxlci5jb29raWVCYXIpKXtcbiAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuaW5pdENvb2tpZUJhcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2V7XG4gICAgICAgICAgICAvLyBFbHNlIHRyeSB0byBjb25uZWN0IGNvb2tpZSBvdmVybGF5IHdpdGggdHJhY2tpbmcgdG8gY29va2llT3ZlcmxheVxuICAgICAgICAgICAgQ29va2llSGFuZGxlci5jb29raWVPdmVybGF5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWNvb2tpZS1vdmVybGF5Jyk7XG5cbiAgICAgICAgICAgIC8vIElmIGlzc2V0IGluaXQgdGhlIGZ1bmN0aW9ucyBmb3IgY29va2llIG92ZXJsYXlcbiAgICAgICAgICAgIGlmKGlzc2V0KENvb2tpZUhhbmRsZXIuY29va2llT3ZlcmxheSkpe1xuICAgICAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuaW5pdENvb2tpZU92ZXJsYXkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGVpdGhlciB0eXBlIG9mIGNvb2tpZSBoYXMgYmVlbiBmb3VuZCBjaGVjayBpZiBzZXR0aW5ncyBhcmUgZGVmaW5lZFxuICAgICAgICBpZihpc3NldChDb29raWVIYW5kbGVyLmNvb2tpZU1lc3NhZ2UpKXtcbiAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuY2hlY2tGb3JDb29raWVTZXR0aW5ncygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmluZCBjb29raWUgc3dpdGNoIHRvIEhhbmRsZXJcbiAgICAgICAgQ29va2llSGFuZGxlci5jb29raWVTd2l0Y2ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtY29va2llLXN3aXRjaCcpO1xuICAgICAgICAvLyBJZiBpc3NldCBpbml0IHRoZSBmdW5jdGlvbnMgZm9yIGNvb2tpZSBzd2l0Y2hcbiAgICAgICAgaWYoaXNzZXQoQ29va2llSGFuZGxlci5jb29raWVTd2l0Y2gpKXtcbiAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuaW5pdENvb2tpZVN3aXRjaCgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8vIEluaXQgdGhlIGNvb2tpZSBiYXIgYWN0aW9uc1xuICAgIGluaXRDb29raWVCYXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgIGNvbnN0IGNsb3NlQnV0dG9uID0gQ29va2llSGFuZGxlci5jb29raWVCYXIucXVlcnlTZWxlY3RvcignLmpzLWRpc2FibGUtY29va2llLWJhcicpO1xuICAgICAgICBpZihpc3NldChjbG9zZUJ1dHRvbikpe1xuICAgICAgICAgICAgY2xvc2VCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBDb29raWVIYW5kbGVyLmNsb3NlQ29va2llTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gSW5pdCB0aGUgY29va2llIG92ZXJsYXkgYWN0aW9uc1xuICAgIGluaXRDb29raWVPdmVybGF5OiBmdW5jdGlvbigpe1xuXG4gICAgICAgIC8vIE9wZW4gdGhlIGNvb2tpZSBzZXR0aW5ncyBldmVudFxuICAgICAgICBjb25zdCBvcGVuQ29va2llU2V0dGluZ3NCdXR0b24gPSBDb29raWVIYW5kbGVyLmNvb2tpZU1lc3NhZ2UucXVlcnlTZWxlY3RvcignLmpzLWNoYW5nZS1jb29raWVzLXNldHRpbmdzJyk7XG4gICAgICAgIGlmKGlzc2V0KG9wZW5Db29raWVTZXR0aW5nc0J1dHRvbikpe1xuICAgICAgICAgICAgb3BlbkNvb2tpZVNldHRpbmdzQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgQ29va2llSGFuZGxlci5vcGVuQ29va2llU2V0dGluZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVG9nZ2xlIG9mIHRoZSB0cmFja2luZyBpbnB1dFxuICAgICAgICBjb25zdCB0b2dnbGVUcmFja2luZ0lucHV0ID0gQ29va2llSGFuZGxlci5jb29raWVNZXNzYWdlLnF1ZXJ5U2VsZWN0b3IoJy5jLWNvb2tpZS10eXBlX19pbnB1dC0tdHJhY2tpbmcnKTtcbiAgICAgICAgaWYoaXNzZXQodG9nZ2xlVHJhY2tpbmdJbnB1dCkpe1xuXG4gICAgICAgICAgICBpZih0b2dnbGVUcmFja2luZ0lucHV0LmNoZWNrZWQgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBDb29raWVIYW5kbGVyLmFjY2VwdFRyYWNraW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdG9nZ2xlVHJhY2tpbmdJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBDb29raWVIYW5kbGVyLnRvZ2dsZVRyYWNraW5nU2V0dGluZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBY2NlcHQgLyBTYXZlIGNvb2tpZXMgYnV0dG9uIGV2ZW50XG4gICAgICAgIGNvbnN0IGFjY2VwdEJ1dHRvbiA9IENvb2tpZUhhbmRsZXIuY29va2llTWVzc2FnZS5xdWVyeVNlbGVjdG9yKCcuanMtYWNjZXB0LWNvb2tpZXMnKTtcbiAgICAgICAgaWYoaXNzZXQoYWNjZXB0QnV0dG9uKSl7XG4gICAgICAgICAgICBhY2NlcHRCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBDb29raWVIYW5kbGVyLnNldENvb2tpZVNldHRpbmdzKTtcbiAgICAgICAgfVxuXG4gICAgfSxcblxuICAgIC8vIEluaXQgdGhlIGNvb2tpZSBzd2l0Y2ggYWN0aW9uc1xuICAgIGluaXRDb29raWVTd2l0Y2g6IGZ1bmN0aW9uKCl7XG5cbiAgICAgICAgLy8gVG9nZ2xlIG9mIHRoZSB0cmFja2luZyBpbnB1dFxuICAgICAgICBjb25zdCB0b2dnbGVUcmFja2luZ0lucHV0ID0gQ29va2llSGFuZGxlci5jb29raWVTd2l0Y2gucXVlcnlTZWxlY3RvcignLmMtY29va2llLXR5cGVfX2lucHV0LS10cmFja2luZycpO1xuICAgICAgICBpZihpc3NldCh0b2dnbGVUcmFja2luZ0lucHV0KSl7XG5cbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBzdGF0ZSBvZiB0aGUgY29va2llIHN3aXRjaCBpbnB1dCBiZWNhdXNlIHRoZSBwb3AtdXAgaXMgZm9yY2VkIG9uIGNoZWNrZWRcbiAgICAgICAgICAgIC8vIHdoaWxlIHRoZSBzd2l0Y2ggY2hlY2tzIGJ5IHBocCBpZiB0aGUgY29va2llIHJlYWxseSBleGlzdCBvciBub3RcbiAgICAgICAgICAgIGlmKHRvZ2dsZVRyYWNraW5nSW5wdXQuY2hlY2tlZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuYWNjZXB0VHJhY2tpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZXtcbiAgICAgICAgICAgICAgICBDb29raWVIYW5kbGVyLmFjY2VwdFRyYWNraW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRvZ2dsZVRyYWNraW5nSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgQ29va2llSGFuZGxlci50b2dnbGVUcmFja2luZ1NldHRpbmcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzIGJ1dHRvbiBldmVudFxuICAgICAgICBjb25zdCBzYXZlQnV0dG9uID0gQ29va2llSGFuZGxlci5jb29raWVTd2l0Y2gucXVlcnlTZWxlY3RvcignLmpzLXNhdmUtY29va2llLXNldHRpbmdzJyk7XG4gICAgICAgIGlmKGlzc2V0KHNhdmVCdXR0b24pKXtcbiAgICAgICAgICAgIHNhdmVCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpe1xuICAgICAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuY29va2llRmFkZU91dEFuaW1hdGlvbkR1cmF0aW9uID0gMDsgLy8gT24gdGhlIHN3aXRjaCBjbGljayB3ZSB3YW50IG5vIGRlbGF5IDopXG4gICAgICAgICAgICAgICAgQ29va2llSGFuZGxlci5zZXRDb29raWVTZXR0aW5ncygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgIH0sXG5cbiAgICBjaGVja0ZvckNvb2tpZVNldHRpbmdzOiBmdW5jdGlvbigpe1xuICAgICAgICBpZiAoQ29va2llLmdldCgnY29va2llTWVzc2FnZScpKSB7XG4gICAgICAgICAgICBDb29raWVIYW5kbGVyLmNvb2tpZU1lc3NhZ2UuY2xhc3NMaXN0LmFkZCgnaXMtYWNjZXB0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIENvb2tpZUhhbmRsZXIuY29va2llTWVzc2FnZS5jbGFzc0xpc3QucmVtb3ZlKCdpcy1hY2NlcHRlZCcpO1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdpcy1jb29raWUtYmFyLXZpc2libGUnKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjbG9zZUNvb2tpZU1lc3NhZ2U6IGZ1bmN0aW9uICgpe1xuICAgICAgICBDb29raWUuc2V0KCdjb29raWVNZXNzYWdlJywgdHJ1ZSwgOTApO1xuICAgICAgICBDb29raWVIYW5kbGVyLmNvb2tpZU1lc3NhZ2UuY2xhc3NMaXN0LmFkZCgnaXMtdHJhbnNpdGlvbmluZy1vdXQnKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdpcy1jb29raWUtYmFyLXZpc2libGUnKTtcbiAgICB9LFxuXG4gICAgb3BlbkNvb2tpZVNldHRpbmdzOiBmdW5jdGlvbiAoKXtcbiAgICAgICAgQ29va2llSGFuZGxlci5jb29raWVPdmVybGF5LnF1ZXJ5U2VsZWN0b3IoJy5qcy1jb29raWUtc2V0dGluZ3MnKS5jbGFzc0xpc3QucmVtb3ZlKCdpcy1oaWRkZW4nKTtcbiAgICAgICAgQ29va2llSGFuZGxlci5jb29raWVPdmVybGF5LnF1ZXJ5U2VsZWN0b3IoJy5qcy1jb29raWUtaW5mbycpLmNsYXNzTGlzdC5hZGQoJ2lzLWhpZGRlbicpO1xuICAgIH0sXG5cbiAgICB0b2dnbGVUcmFja2luZ1NldHRpbmc6IGZ1bmN0aW9uKCl7XG4gICAgICAgIGlmKENvb2tpZUhhbmRsZXIuYWNjZXB0VHJhY2tpbmcpe1xuICAgICAgICAgICAgQ29va2llSGFuZGxlci5hY2NlcHRUcmFja2luZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2V7XG4gICAgICAgICAgICBDb29raWVIYW5kbGVyLmFjY2VwdFRyYWNraW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXRDb29raWVTZXR0aW5nczogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIC8vIFNldCB0cmFja2luZyBjb29raWUgb3IgZGVsZXRlIGl0IGlmIGlzc2V0IGFjY29yZGluZyB0byB0aGUgZGVzaXJlZCBzZXR0aW5nc1xuICAgICAgICBpZihDb29raWVIYW5kbGVyLmFjY2VwdFRyYWNraW5nKXtcbiAgICAgICAgICAgIENvb2tpZS5zZXQoJ3RyYWNraW5nQ29va2llQWNjZXB0ZWQnLCAndHJ1ZScsIDkwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNle1xuICAgICAgICAgICAgaWYoQ29va2llLmdldCgndHJhY2tpbmdDb29raWVBY2NlcHRlZCcpKXtcbiAgICAgICAgICAgICAgICBDb29raWUuZXJhc2UoJ3RyYWNraW5nQ29va2llQWNjZXB0ZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIENvb2tpZUhhbmRsZXIuY2xvc2VDb29raWVNZXNzYWdlKCk7XG5cbiAgICAgICAgLy8gUmVsb2FkIGFmdGVyIGFuaW1hdGlvbiB0byBhdXRvbWF0aWNhbGx5IHRyaWdnZXIgdGhlIHRyYWNraW5nIGFmdGVyIGFjY2VwdGluZyBpdFxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKVxuICAgICAgICB9LCBDb29raWVIYW5kbGVyLmNvb2tpZUZhZGVPdXRBbmltYXRpb25EdXJhdGlvbik7XG4gICAgfSxcblxufTtcblxuQ29va2llSGFuZGxlci5pbml0KCk7IiwiLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgIC8vIENvcGllZCBmcm9tIFJlbnRtYW4gcHJvamVjdCwgdGhlbiBlZGl0ZWQgc2xpZ2h0bHkgYW5kIGFkZGVkIGF1dG9TbGlkZVxuXG4gICBDdXN0b21lciBsb2dvcyBzbGlkZXIgaGFuZGxlclxuICAgLSBTbGlkZSB0byBuZXh0IGxvZ28uXG4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuY29uc3QgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlciA9IHtcblxuICAgIGN1c3RvbWVyTG9nb1NsaWRlckFyZWE6IG51bGwsXG4gICAgY3VzdG9tZXJMb2dvU2xpZGVzOiBudWxsLFxuICAgIGFjdGl2ZUxvZ286IDIsXG4gICAgYXV0b1NsaWRlVGltZW91dEhhbmRsZTogbnVsbCxcbiAgICBhdXRvU2xpZGVSZXN0YXJ0VGltZW91dEhhbmRsZTogbnVsbCxcbiAgICBhdXRvU2xpZGVJbnRlcnZhbDogMjAwMCxcbiAgICBhdXRvU2xpZGVSZXN0YXJ0SW50ZXJ2YWw6IDIwMDAsXG5cbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXJBcmVhID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWN1c3RvbWVyLWxvZ28tc2xpZGVyJyk7XG5cblxuICAgICAgICAvLyBPbmx5IGNvbnRpbnVlIHRoZSBpbml0IGlmIHRoZSBjdXN0b21lciBsb2dvIGFyZWEgaXMgZm91bmRcbiAgICAgICAgaWYgKGlzc2V0KEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVyQXJlYSkpIHtcblxuICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXMgPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmN1c3RvbWVyTG9nb1NsaWRlckFyZWEucXVlcnlTZWxlY3RvckFsbCgnLmpzLWN1c3RvbWVyLWxvZ28tc2xpZGUnKTtcblxuICAgICAgICAgICAgaWYgKEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVzLmxlbmd0aCA+PSA1KSB7XG5cbiAgICAgICAgICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmFkZEV2ZW50cygpO1xuICAgICAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIucmVzZXRMb2dvc09yZGVyKCk7XG4gICAgICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5maW5pc2hMb2FkaW5nKCk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0N1c3RvbWVyTG9nb1NsaWRlcjogQWRkIG1vcmUgY3VzdG9tZXIgbG9nb3MgdG8gdGhlIHNsaWRlcicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYWRkRXZlbnRzOiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3QgbmV4dCA9IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVyQXJlYS5xdWVyeVNlbGVjdG9yKCcuanMtc2xpZGVyLWJ1dHRvbi5uZXh0Jyk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXJBcmVhLnF1ZXJ5U2VsZWN0b3IoJy5qcy1zbGlkZXItYnV0dG9uLnByZXZpb3VzJyk7XG5cbiAgICAgICAgbmV4dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIubmV4dExvZ28oKTtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIudXBkYXRlU2xpZGVyKCk7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hdXRvU2xpZGVUaW1lb3V0SGFuZGxlKTtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIucmVzZXRBdXRvU2xpZGluZygpO1xuICAgICAgICB9KTtcblxuICAgICAgICBwcmV2aW91cy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIucHJldmlvdXNMb2dvKCk7XG4gICAgICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLnVwZGF0ZVNsaWRlcigpO1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYXV0b1NsaWRlVGltZW91dEhhbmRsZSk7XG4gICAgICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLnJlc2V0QXV0b1NsaWRpbmcoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3dpcGUgaW50ZXJhY3Rpb25cbiAgICAgICAgY29uc3Qgc3dpcGVHZXN0dXJlcyA9IG5ldyBIYW1tZXIoQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXJBcmVhKTtcbiAgICAgICAgc3dpcGVHZXN0dXJlcy5vbignc3dpcGVsZWZ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5uZXh0TG9nbygpO1xuICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci51cGRhdGVTbGlkZXIoKTtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIucmVzZXRBdXRvU2xpZGluZygpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzd2lwZUdlc3R1cmVzLm9uKCdzd2lwZXJpZ2h0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5wcmV2aW91c0xvZ28oKTtcbiAgICAgICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIudXBkYXRlU2xpZGVyKCk7XG4gICAgICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLnJlc2V0QXV0b1NsaWRpbmcoKTtcbiAgICAgICAgfSk7XG5cbiAgICB9LFxuXG4gICAgcmVzZXRBdXRvU2xpZGluZzogZnVuY3Rpb24oKSB7XG4gICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLnN0b3BBdXRvU2xpZGluZygpO1xuICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5zdGFydEF1dG9TbGlkaW5nKCk7XG4gICAgfSxcblxuICAgIHN0b3BBdXRvU2xpZGluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmF1dG9TbGlkZVRpbWVvdXRIYW5kbGUpO1xuICAgICAgICBjbGVhclRpbWVvdXQoQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hdXRvU2xpZGVSZXN0YXJ0VGltZW91dEhhbmRsZSk7XG4gICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYXV0b1NsaWRlVGltZW91dEhhbmRsZSA9IG51bGw7XG4gICAgfSxcblxuICAgIHN0YXJ0QXV0b1NsaWRpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZighQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hdXRvU2xpZGVUaW1lb3V0SGFuZGxlKVxuICAgICAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hdXRvU2xpZGVSZXN0YXJ0VGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5kb0F1dG9TbGlkZSwgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hdXRvU2xpZGVSZXN0YXJ0SW50ZXJ2YWwpO1xuICAgIH0sXG5cbiAgICBnZXRMb2dvSWRzOiBmdW5jdGlvbigpIHtcblxuICAgICAgICBjb25zdCBjdXN0b21lckxvZ29zTGVuZ3RoID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXMubGVuZ3RoO1xuICAgICAgICBsZXQgY3VzdG9tZXJMb2dvSWRzID0gW107XG5cbiAgICAgICAgZm9yKGxldCBpID0wOyBpIDwgY3VzdG9tZXJMb2dvc0xlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbWVyTG9nbyA9IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVzW2ldO1xuICAgICAgICAgICAgY29uc3QgY3VzdG9tZXJMb2dvSWQgPSBjdXN0b21lckxvZ28uZ2V0QXR0cmlidXRlKCdkYXRhLWxvZ28taWQnKTtcbiAgICAgICAgICAgIGN1c3RvbWVyTG9nb0lkcy5wdXNoKGN1c3RvbWVyTG9nb0lkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7aWRzOiBjdXN0b21lckxvZ29JZHN9O1xuICAgIH0sXG5cbiAgICBmaW5pc2hMb2FkaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXJBcmVhLnF1ZXJ5U2VsZWN0b3IoJy5qcy1jdXN0b21lci1sb2dvLXNsaWRlLWNvbnRhaW5lcicpLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWxvYWRpbmcnKTtcbiAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5zdGFydEF1dG9TbGlkaW5nKCk7XG4gICAgfSxcblxuICAgIGRvQXV0b1NsaWRlOiBmdW5jdGlvbigpe1xuICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmF1dG9TbGlkZVRpbWVvdXRIYW5kbGUgPSBzZXRUaW1lb3V0KEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuZG9BdXRvU2xpZGUsIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYXV0b1NsaWRlSW50ZXJ2YWwpO1xuXG4gICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIubmV4dExvZ28oKTtcbiAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci51cGRhdGVTbGlkZXIoKTtcbiAgICB9LFxuXG4gICAgbmV4dExvZ286IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gSW5jcmVtZW50IGFjdGl2ZSBsb2dvIGlkXG4gICAgICAgIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYWN0aXZlTG9nbysrO1xuXG4gICAgICAgIC8vIElmIGl0J3MgdGhlIHNhbWUgYXMgbGVuZ3RoIHRoZW4gcmVzZXQgaXQgdG8gemVyb1xuICAgICAgICBpZiAoQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hY3RpdmVMb2dvID09PSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmN1c3RvbWVyTG9nb1NsaWRlcy5sZW5ndGgpIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYWN0aXZlTG9nbyA9IDA7XG4gICAgfSxcblxuICAgIHByZXZpb3VzTG9nbzogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIC8vIERlY3JlbWVudCBhY3RpdmUgbG9nbyBpZFxuICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmFjdGl2ZUxvZ28tLTtcblxuICAgICAgICAvLyBJZiBpdCdzIGJlbG93IHplcm8gcmVzZXQgaXQgdG8gbGFzdCBpdGVtXG4gICAgICAgIGlmIChDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmFjdGl2ZUxvZ28gPCAwKSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmFjdGl2ZUxvZ28gPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmN1c3RvbWVyTG9nb1NsaWRlcy5sZW5ndGggLSAxO1xuXG4gICAgfSxcblxuICAgIHJlc2V0TG9nb3NPcmRlcjogZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXMgPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmN1c3RvbWVyTG9nb1NsaWRlckFyZWEucXVlcnlTZWxlY3RvckFsbCgnLmpzLWN1c3RvbWVyLWxvZ28tc2xpZGUnKTtcbiAgICAgICAgY29uc3QgY3VzdG9tZXJMb2dvc0xlbmd0aCA9IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVzLmxlbmd0aDtcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IGN1c3RvbWVyTG9nb3NMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY3VzdG9tZXJMb2dvID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXNbaV07XG4gICAgICAgICAgICBjdXN0b21lckxvZ28uc2V0QXR0cmlidXRlKCdkYXRhLXNsaWRlLWlkJywgaSk7XG4gICAgICAgIH1cblxuICAgICAgICBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLnVwZGF0ZVNsaWRlcigpO1xuXG4gICAgfSxcblxuICAgIHVwZGF0ZVNsaWRlcjogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGNvbnN0IHByZXZpb3VzTG9jYXRvciA9IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuX2NhbGNQcmV2aW91c1Bvc2l0aW9ucygzKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNlciA9IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuX2NhbGNQcmV2aW91c1Bvc2l0aW9ucygyKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLl9jYWxjUHJldmlvdXNQb3NpdGlvbnMoMSk7XG4gICAgICAgIGNvbnN0IG5leHQgPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLl9jYWxjTmV4dFBvc2l0aW9ucygxKTtcbiAgICAgICAgY29uc3QgbmV4dGVyID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5fY2FsY05leHRQb3NpdGlvbnMoMik7XG4gICAgICAgIGNvbnN0IG5leHRlckxvY2F0b3IgPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLl9jYWxjTmV4dFBvc2l0aW9ucygzKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuY3VzdG9tZXJMb2dvU2xpZGVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IHNsaWRlID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXNbaV07XG5cbiAgICAgICAgICAgIC8vIFJlc2V0IGFsbCBwb3NzaWJsZSBjbGFzc2VzXG4gICAgICAgICAgICBzbGlkZS5jbGFzc0xpc3QucmVtb3ZlKCdjLWN1c3RvbWVyLWxvZ28tc2xpZGVyX19pdGVtLS1wcmUtcHJldmlvdXMnKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTEnKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTInKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTMnKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTQnKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTUnKTtcbiAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXByZS1uZXh0Jyk7XG4gICAgICAgICAgICBzbGlkZS5jbGFzc0xpc3QucmVtb3ZlKCdpcy1oaWRkZW4nKTtcblxuICAgICAgICAgICAgc3dpdGNoIChpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBwcmV2aW91c0xvY2F0b3I6XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXByZS1wcmV2aW91cycpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIHByZXZpb3VzZXI6XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTEnKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBwcmV2aW91czpcbiAgICAgICAgICAgICAgICAgICAgc2xpZGUuY2xhc3NMaXN0LmFkZCgnYy1jdXN0b21lci1sb2dvLXNsaWRlcl9faXRlbS0tcG9zaXRpb24tMicpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuYWN0aXZlTG9nbzpcbiAgICAgICAgICAgICAgICAgICAgc2xpZGUuY2xhc3NMaXN0LmFkZCgnYy1jdXN0b21lci1sb2dvLXNsaWRlcl9faXRlbS0tcG9zaXRpb24tMycpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIG5leHQ6XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTQnKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBuZXh0ZXI6XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2MtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0tLXBvc2l0aW9uLTUnKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBuZXh0ZXJMb2NhdG9yOlxuICAgICAgICAgICAgICAgICAgICBzbGlkZS5jbGFzc0xpc3QuYWRkKCdjLWN1c3RvbWVyLWxvZ28tc2xpZGVyX19pdGVtLS1wcmUtbmV4dCcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBzbGlkZS5jbGFzc0xpc3QuYWRkKCdpcy1oaWRkZW4nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgX2NhbGNQcmV2aW91c1Bvc2l0aW9uczogZnVuY3Rpb24oJGFtb3VudCkge1xuICAgICAgICBsZXQgbG9jYXRpb24gPSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmFjdGl2ZUxvZ28gLSAkYW1vdW50O1xuICAgICAgICBpZiAobG9jYXRpb24gPCAwKSByZXR1cm4gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXMubGVuZ3RoICsgbG9jYXRpb247XG4gICAgICAgIHJldHVybiBsb2NhdGlvblxuICAgIH0sXG5cbiAgICBfY2FsY05leHRQb3NpdGlvbnM6IGZ1bmN0aW9uKCRhbW91bnQpIHtcbiAgICAgICAgbGV0IGxvY2F0aW9uID0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5hY3RpdmVMb2dvICsgJGFtb3VudDtcbiAgICAgICAgaWYobG9jYXRpb24gPj0gQ3VzdG9tZXJMb2dvU2xpZGVySGFuZGxlci5jdXN0b21lckxvZ29TbGlkZXMubGVuZ3RoKSByZXR1cm4gbG9jYXRpb24gLSBDdXN0b21lckxvZ29TbGlkZXJIYW5kbGVyLmN1c3RvbWVyTG9nb1NsaWRlcy5sZW5ndGg7XG4gICAgICAgIHJldHVybiBsb2NhdGlvbjtcblxuICAgIH0sXG5cbiAgICBfcHJlcGFyZUN1c3RvbWVyTG9nb0h0bWw6IGZ1bmN0aW9uKGN1c3RvbWVyTG9nb3NIdG1sLCBjdXN0b21lckxvZ28pIHtcbiAgICAgICAgY3VzdG9tZXJMb2dvc0h0bWwgKz0gJzxhIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vZm9sbG93IG5vb3BlbmVyIG5vcmVmZXJyZXJcIiBjbGFzcz1cImMtY3VzdG9tZXItbG9nby1zbGlkZXJfX2l0ZW0gIGpzLWN1c3RvbWVyLWxvZ28tc2xpZGVcIiAnO1xuICAgICAgICBpZihpc3NldChjdXN0b21lckxvZ28udXJsKSkgY3VzdG9tZXJMb2dvc0h0bWwrPSAnaHJlZj1cIicgKyBjdXN0b21lckxvZ28udXJsICsgJ1wiIGFyaWEtbGFiZWw9XCJHbyB0byBvdXIgcGFydG5lcnMgd2Vic2l0ZTogJyArIGN1c3RvbWVyTG9nby51cmwgKyAnXCIgJztcbiAgICAgICAgY3VzdG9tZXJMb2dvc0h0bWwgKz0gJ2RhdGEtc2xpZGUtaWQ9XCJcIiBkYXRhLWxvZ28taWQ9XCInICsgY3VzdG9tZXJMb2dvLmlkICsgJ1wiPicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJjLWN1c3RvbWVyLWxvZ28tc2xpZGVyX19sb2dvXCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJyArIFwiJ1wiICsgY3VzdG9tZXJMb2dvLmltYWdlICsgXCInXCIgKyAnKVwiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzwvYT4nO1xuXG4gICAgICAgIHJldHVybiBjdXN0b21lckxvZ29zSHRtbDtcblxuICAgIH1cbn07XG5cbkN1c3RvbWVyTG9nb1NsaWRlckhhbmRsZXIuaW5pdCgpOyIsIi8qKlxuICogQ29udHJvbHMgYSBkaXYgd2l0aCBhbiB1bCBpbiBpdCB0byBzaG93IGVycm9ycyBvciBub3RcbiAqL1xuY2xhc3MgRXJyb3JDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpXG4gICAge1xuICAgICAgICB0aGlzLl9jbGFzc1RvSGlkZSA9ICd1LWhpZGRlbic7XG4gICAgICAgIHRoaXMuX2Vycm9yRWxlbWVudElkU3VmZml4ID0gJy1lcnJvcic7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkU2VsZWN0b3JcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3JcbiAgICAgKi9cbiAgICBzZXRGaWVsZEVycm9yKGZpZWxkU2VsZWN0b3IsIGVycm9yKVxuICAgIHtcbiAgICAgICAgbGV0IHNlbGVjdG9yID0gJyMnK2ZpZWxkU2VsZWN0b3IrdGhpcy5fZXJyb3JFbGVtZW50SWRTdWZmaXg7XG4gICAgICAgIGxldCBlcnJvckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgaWYoIWVycm9yRWxlbWVudCkgcmV0dXJuO1xuXG4gICAgICAgIGVycm9yRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuX2NsYXNzVG9IaWRlKTtcbiAgICAgICAgZXJyb3JFbGVtZW50LmlubmVyVGV4dCA9IGVycm9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmaWVsZFNlbGVjdG9yXG4gICAgICovXG4gICAgY2xlYXJGaWVsZEVycm9yKGZpZWxkU2VsZWN0b3IpIHtcbiAgICAgICAgbGV0IHNlbGVjdG9yID0gJyMnK2ZpZWxkU2VsZWN0b3IrdGhpcy5fZXJyb3JFbGVtZW50SWRTdWZmaXg7XG4gICAgICAgIGxldCBlcnJvckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKCFlcnJvckVsZW1lbnQpIHJldHVybjtcblxuICAgICAgICBlcnJvckVsZW1lbnQuY2xhc3NMaXN0LmFkZCh0aGlzLl9jbGFzc1RvSGlkZSk7XG4gICAgICAgIGVycm9yRWxlbWVudC5pbm5lclRleHQgPSAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgZXJyb3JzXG4gICAgICovXG4gICAgY2xlYXJBbGxFcnJvcnMoKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2lkJD0nK3RoaXMuX2Vycm9yRWxlbWVudElkU3VmZml4KyddJykuZm9yRWFjaChmdW5jdGlvbihlcnJvckVsZW1lbnQpIHtcbiAgICAgICAgICAgIGVycm9yRWxlbWVudC5jbGFzc0xpc3QuYWRkKHNlbGYuX2NsYXNzVG9IaWRlKTtcbiAgICAgICAgICAgIGVycm9yRWxlbWVudC5pbm5lclRleHQgPSAnJztcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydCB7IEVycm9yQ29udHJvbGxlciB9IiwiLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgIEZpbGVVcGxvYWQgaGFuZGxlclxuICAgLSBIYW5kbGVzIHRoZSBGaWxlVXBsb2FkIGNvbXBvbmVudCB3aGljaCBoYXMgdGhlIHByb3BlciBjbGFzc2VzLlxuICAgLSBDYW4gb25seSBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggQ2hvY29sYXRlRmFjdG9yeSB3aGljaCBoYW5kbGVzIHRoZSBwb3N0LlxuID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbmNvbnN0IEZpbGVVcGxvYWRIYW5kbGVyID0ge1xuICAgIGZpbGVVcGxvYWRXcmFwcGVyQ2xhc3M6ICcuanMtZmlsZS11cGxvYWQnLFxuICAgIGZpbGVVcGxvYWRMaXN0Q2xhc3M6ICcuanMtZmlsZS11cGxvYWRfX2xpc3QnLFxuICAgIGZpbGVVcGxvYWRJbnB1dENsYXNzOiAnLmpzLWZpbGUtdXBsb2FkX19pbnB1dCcsXG4gICAgZmlsZVVwbG9hZEJ1dHRvbkNsYXNzOiAnLmpzLWZpbGUtdXBsb2FkX19idXR0b24nLFxuXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGNvbnN0IGZpbGVVcGxvYWRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChGaWxlVXBsb2FkSGFuZGxlci5maWxlVXBsb2FkV3JhcHBlckNsYXNzKTtcbiAgICAgICAgY29uc3QgZmlsZVVwbG9hZHNDb3VudCA9IGZpbGVVcGxvYWRzLmxlbmd0aDtcblxuICAgICAgICBpZihpc3NldChmaWxlVXBsb2FkcykgJiYgZmlsZVVwbG9hZHNDb3VudCAhPT0gMCl7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgZmlsZVVwbG9hZHNDb3VudDsgaSsrKXtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlVXBsb2FkID0gZmlsZVVwbG9hZHNbaV07XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0RmlsZVVwbG9hZEhhbmRsZXIoZmlsZVVwbG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYWRkRmlsZTogZnVuY3Rpb24gKGlucHV0RWxlbWVudCkge1xuICAgICAgICBpZighaW5wdXRFbGVtZW50KSByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgbm9kZSA9IGlucHV0RWxlbWVudC5jbG9uZU5vZGUoKTtcbiAgICAgICAgY29uc3QgbGlzdCA9IGlucHV0RWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihGaWxlVXBsb2FkSGFuZGxlci5maWxlVXBsb2FkTGlzdENsYXNzKTtcbiAgICAgICAgbGV0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGV0IHJlbW92ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICBsZXQgdGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShpbnB1dEVsZW1lbnQudmFsdWUuc3BsaXQoXCJcXFxcXCIpW2lucHV0RWxlbWVudC52YWx1ZS5zcGxpdCgnXFxcXCcpLmxlbmd0aCAtIDFdKTtcblxuICAgICAgICBub2RlLnZhbHVlID0gXCJcIjtcbiAgICAgICAgbm9kZS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLmV2ZW50SGFuZGxlcik7XG5cbiAgICAgICAgcmVtb3ZlLnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcbiAgICAgICAgcmVtb3ZlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5ldmVudEhhbmRsZXIpO1xuXG4gICAgICAgIGlucHV0RWxlbWVudC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICBpbnB1dEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgICAgICBsaS5hcHBlbmRDaGlsZChpbnB1dEVsZW1lbnQpO1xuICAgICAgICBsaS5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7XG4gICAgICAgIGxpLmFwcGVuZENoaWxkKHJlbW92ZSk7XG5cbiAgICAgICAgbGlzdC5hcHBlbmRDaGlsZChsaSk7XG4gICAgfSxcblxuICAgIHJlbW92ZUZpbGU6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBldmVudC50YXJnZXQucGFyZW50Tm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGV2ZW50LnRhcmdldC5wYXJlbnROb2RlKTtcbiAgICB9LFxuXG4gICAgZXZlbnRIYW5kbGVyOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdjbGljayc6XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoRmlsZVVwbG9hZEhhbmRsZXIuZmlsZVVwbG9hZEJ1dHRvbkNsYXNzLnN1YnN0cmluZygxKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0LnBhcmVudE5vZGUucXVlcnlTZWxlY3RvcihGaWxlVXBsb2FkSGFuZGxlci5maWxlVXBsb2FkSW5wdXRDbGFzcykuY2xpY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIEZpbGVVcGxvYWRIYW5kbGVyLnJlbW92ZUZpbGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnY2hhbmdlJzpcbiAgICAgICAgICAgICAgICBGaWxlVXBsb2FkSGFuZGxlci5hZGRGaWxlKGV2ZW50LnRhcmdldCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgaW5pdEZpbGVVcGxvYWRIYW5kbGVyOiBmdW5jdGlvbiAoZmlsZVVwbG9hZCkge1xuICAgICAgICBjb25zdCBpbnB1dEVsZW1lbnQgPSBmaWxlVXBsb2FkLnF1ZXJ5U2VsZWN0b3IoRmlsZVVwbG9hZEhhbmRsZXIuZmlsZVVwbG9hZElucHV0Q2xhc3MpO1xuICAgICAgICBjb25zdCBpbnB1dEJ1dHRvbkVsZW1lbnQgPSBmaWxlVXBsb2FkLnF1ZXJ5U2VsZWN0b3IoRmlsZVVwbG9hZEhhbmRsZXIuZmlsZVVwbG9hZEJ1dHRvbkNsYXNzKTtcbiAgICAgICAgaW5wdXRCdXR0b25FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5ldmVudEhhbmRsZXIpO1xuICAgICAgICBpbnB1dEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5ldmVudEhhbmRsZXIpO1xuICAgIH0sXG5cblxufTtcblxuRmlsZVVwbG9hZEhhbmRsZXIuaW5pdCgpOyIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgR29vZ2xlIE1hcHMgaGFuZGxlclxuICAgIC0gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvYWRkaW5nLWEtZ29vZ2xlLW1hcFxuID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbmNvbnN0IE1hcHNIYW5kbGVyID0ge1xuXG4gICAgbWFwczogW10sXG4gICAga2V5OiAnQUl6YVN5REdvSXllVFgxMHhMTThaSkxiLVM2SHR2LXRFaEFpWVlNJyxcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAvLyBHZXQgbWFwIGVsZW1lbnRzXG4gICAgICAgIGNvbnN0IG1hcHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuanMtZ29vZ2xlLW1hcCcpO1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGFyZSBtYXAgZWxlbWVudHMgbG9vcCB0aHJvdWdoIHRoZW0gYW5kIGRyYXcgdGhlIG1hcHNcbiAgICAgICAgaWYobWFwcy5sZW5ndGggIT09IDAgKSB7XG5cbiAgICAgICAgICAgIC8vIENvbnZlcnQgZWxlbWVudHMgaW50byBvYmplY3QgZm9yIGNhbGxiYWNrIHdoZW4gc2NyaXB0IGFzIGJlZW4gbG9hZGVkXG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgbWFwcy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICAgICAgLy8gR2V0IG1hcCBmcm9tIG5vZGVMaXN0XG4gICAgICAgICAgICAgICAgY29uc3QgbWFwID0gbWFwc1tpXTtcblxuICAgICAgICAgICAgICAgIGlmKCFtYXAuaGFzQXR0cmlidXRlKCdkYXRhLWdvb2dsZS1sYXQnKSB8fCAhbWFwLmhhc0F0dHJpYnV0ZSgnZGF0YS1nb29nbGUtbG5nJykpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICAgICAgbGV0IGxhdCA9IHBhcnNlRmxvYXQobWFwLmdldEF0dHJpYnV0ZSgnZGF0YS1nb29nbGUtbGF0JykpO1xuICAgICAgICAgICAgICAgIGxldCBsbmcgPSBwYXJzZUZsb2F0KG1hcC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZ29vZ2xlLWxuZycpKTtcblxuICAgICAgICAgICAgICAgIE1hcHNIYW5kbGVyLm1hcHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIG5vZGU6IG1hcCxcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhdDogbGF0LFxuICAgICAgICAgICAgICAgICAgICAgICAgbG5nOiBsbmcsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlczogTWFwc0hhbmRsZXIuc2V0Q3VzdG9tU3R5bGluZygpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlZSBpZiBnb29nbGUgdmFyaWFibGUgZXhpc3RzXG4gICAgICAgICAgICBpZiAodHlwZW9mKGdvb2dsZSkgPT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mKGdvb2dsZS5tYXBzKSA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIC8vIExvYWQgZXh0ZXJuYWwgc2NyaXB0IHdpdGggZHJhd01hcHMgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICBnZXRTY3JpcHQoJ2h0dHBzOi8vbWFwcy5nb29nbGVhcGlzLmNvbS9tYXBzL2FwaS9qcz9rZXk9JyArIE1hcHNIYW5kbGVyLmtleSwgTWFwc0hhbmRsZXIuZHJhd01hcHMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBhbHJlYWR5IGxvYWRlZCBkcmF3IG1hcHNcbiAgICAgICAgICAgICAgICBNYXBzSGFuZGxlci5kcmF3TWFwcygpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRHJhdyB0aGUgZ29vZ2xlIG1hcHNcbiAgICAgKi9cbiAgICBkcmF3TWFwczogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWFwc0hhbmRsZXIubWFwcy5sZW5ndGg7IGkrKykgIHtcblxuICAgICAgICAgICAgY29uc3QgbWFwID0gTWFwc0hhbmRsZXIubWFwc1tpXTtcblxuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbWFwXG4gICAgICAgICAgICBjb25zdCBnb29nbGVNYXAgPSBuZXcgZ29vZ2xlLm1hcHMuTWFwKG1hcC5ub2RlLCB7XG4gICAgICAgICAgICAgICAgem9vbTogMTEsXG4gICAgICAgICAgICAgICAgY2VudGVyOiBtYXAubG9jYXRpb24sXG4gICAgICAgICAgICAgICAgZGlzYWJsZURlZmF1bHRVSTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdHlsZXM6IG1hcC5zdHlsZXNcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBBZGQgYSBtYXJrZXJcbiAgICAgICAgICAgIGNvbnN0IG1hcmtlciA9IG5ldyBnb29nbGUubWFwcy5NYXJrZXIoe1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBtYXAubG9jYXRpb24sXG4gICAgICAgICAgICAgICAgbWFwOiBnb29nbGVNYXBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY3VzdG9tIHN0eWxpbmcgZm9yIHRoZSBHb29nbGUgTWFwc1xuICAgICAqXG4gICAgICogQHJldHVybnMgeypbXX1cbiAgICAgKi9cbiAgICBzZXRDdXN0b21TdHlsaW5nOiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJwb2lcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImxhYmVscy50ZXh0LmZpbGxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiIzc0NzQ3NFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibGlnaHRuZXNzXCI6IFwiMjNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJwb2kuYXR0cmFjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiZ2VvbWV0cnkuZmlsbFwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjZjM4ZWIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicG9pLmdvdmVybm1lbnRcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImdlb21ldHJ5LmZpbGxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiI2NlZDdkYlwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInBvaS5tZWRpY2FsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJnZW9tZXRyeS5maWxsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiNmZmE1YThcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJwb2kucGFya1wiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiZ2VvbWV0cnkuZmlsbFwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYzdlNWM4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicG9pLnBsYWNlX29mX3dvcnNoaXBcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImdlb21ldHJ5LmZpbGxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiI2Q2Y2JjN1wiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInBvaS5zY2hvb2xcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImdlb21ldHJ5LmZpbGxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiI2M0YzllOFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInBvaS5zcG9ydHNfY29tcGxleFwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiZ2VvbWV0cnkuZmlsbFwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYjFlYWYxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicm9hZFwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiZ2VvbWV0cnlcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImxpZ2h0bmVzc1wiOiBcIjEwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInJvYWRcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImxhYmVsc1wiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwidmlzaWJpbGl0eVwiOiBcIm9mZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibGlnaHRuZXNzXCI6IFwiMTAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicm9hZC5oaWdod2F5XCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJnZW9tZXRyeS5maWxsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiNmZmQ0YTVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJyb2FkLmFydGVyaWFsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJnZW9tZXRyeS5maWxsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiNmZmU5ZDJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJyb2FkLmxvY2FsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJhbGxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJzdHlsZXJzXCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInZpc2liaWxpdHlcIjogXCJzaW1wbGlmaWVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicm9hZC5sb2NhbFwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiZ2VvbWV0cnkuZmlsbFwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwid2VpZ2h0XCI6IFwiMy4wMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInJvYWQubG9jYWxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImdlb21ldHJ5LnN0cm9rZVwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwid2VpZ2h0XCI6IFwiMC4zMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJmZWF0dXJlVHlwZVwiOiBcInJvYWQubG9jYWxcIixcbiAgICAgICAgICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcImxhYmVscy50ZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ2aXNpYmlsaXR5XCI6IFwib25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJyb2FkLmxvY2FsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJsYWJlbHMudGV4dC5maWxsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiM3NDc0NzRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImxpZ2h0bmVzc1wiOiBcIjM2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwicm9hZC5sb2NhbFwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwibGFiZWxzLnRleHQuc3Ryb2tlXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiNlOWU1ZGNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImxpZ2h0bmVzc1wiOiBcIjMwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcImZlYXR1cmVUeXBlXCI6IFwidHJhbnNpdC5saW5lXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJnZW9tZXRyeVwiLFxuICAgICAgICAgICAgICAgICAgICBcInN0eWxlcnNcIjogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwidmlzaWJpbGl0eVwiOiBcIm9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJsaWdodG5lc3NcIjogXCIxMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiZmVhdHVyZVR5cGVcIjogXCJ3YXRlclwiLFxuICAgICAgICAgICAgICAgICAgICBcImVsZW1lbnRUeXBlXCI6IFwiYWxsXCIsXG4gICAgICAgICAgICAgICAgICAgIFwic3R5bGVyc1wiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjb2xvclwiOiBcIiNkMmU3ZjdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXTtcbiAgICB9XG59O1xuXG5NYXBzSGFuZGxlci5pbml0KCk7IiwiLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgIE5hdmlnYXRpb24gaGFuZGxlclxuICAgLSBIYW5kbGVzIHRoZSBzaG93aW5nIGFuZCBoaWRpbmcgb2YgdGhlIG92ZXJsYXktbWVudSBjb21wb25lbnQgd2hpY2ggaGFzIHRoZSBwcm9wZXIgY2xhc3Nlcy5cbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5jb25zdCBib2R5U2Nyb2xsTG9jayA9IHJlcXVpcmUoJ2JvZHktc2Nyb2xsLWxvY2snKTtcblxuY29uc3QgT3ZlcmxheU1lbnVIYW5kbGVyID0ge1xuXG4gICAgLy8gaW5pdDogZnVuY3Rpb24gKCkge1xuICAgIC8vICAgICBjb25zdCBvdmVybGF5TWVudVRyaWdnZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtb3ZlcmxheS1tZW51LXRyaWdnZXInKTtcbiAgICAvLyAgICAgT3ZlcmxheU1lbnVIYW5kbGVyLmluaXRPdmVybGF5TWVudShvdmVybGF5TWVudVRyaWdnZXIpO1xuICAgIC8vIH0sXG5cbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3Qgb3ZlcmxheU1lbnVUcmlnZ2VyTGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy1vdmVybGF5LW1lbnUtdHJpZ2dlcicpO1xuICAgICAgICBjb25zdCBvdmVybGF5TWVudVRyaWdnZXJMaXN0Q291bnQgPSBvdmVybGF5TWVudVRyaWdnZXJMaXN0Lmxlbmd0aDtcblxuICAgICAgICBpZihpc3NldChvdmVybGF5TWVudVRyaWdnZXJMaXN0KSAmJiBvdmVybGF5TWVudVRyaWdnZXJMaXN0Q291bnQgIT09IDApe1xuICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IG92ZXJsYXlNZW51VHJpZ2dlckxpc3RDb3VudDsgaSsrKXtcbiAgICAgICAgICAgICAgICBjb25zdCBvdmVybGF5TWVudVRyaWdnZXIgPSBvdmVybGF5TWVudVRyaWdnZXJMaXN0W2ldO1xuICAgICAgICAgICAgICAgIE92ZXJsYXlNZW51SGFuZGxlci5pbml0T3ZlcmxheU1lbnUob3ZlcmxheU1lbnVUcmlnZ2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBpbml0T3ZlcmxheU1lbnU6IGZ1bmN0aW9uIChvdmVybGF5TWVudVRyaWdnZXIpIHtcbiAgICAgICAgb3ZlcmxheU1lbnVUcmlnZ2VyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgT3ZlcmxheU1lbnVIYW5kbGVyLnRvZ2dsZU92ZXJsYXlNZW51LCBmYWxzZSk7XG4gICAgfSxcblxuICAgIHRvZ2dsZU92ZXJsYXlNZW51OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgY29uc3Qgb3ZlcmxheU1lbnVOYXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtb3ZlcmxheS1tZW51Jyk7XG4gICAgICAgIC8vIGNvbnN0IG92ZXJsYXlNZW51Qm9keSA9IG92ZXJsYXlNZW51LnF1ZXJ5U2VsZWN0b3IoJy5qcy1vdmVybGF5LW1lbnUtcGVyc2lzdC1zY3JvbGxpbmcnKTtcblxuICAgICAgICAvLyBCYWlsIGlmIG92ZXJsYXlNZW51IGRvZXNuJ3QgZXhpc3RcbiAgICAgICAgaWYgKCFvdmVybGF5TWVudU5hdikgcmV0dXJuO1xuXG4gICAgICAgIC8vIENsZWFyIHByZXZpb3VzbHkgbG9ja2VkIHNjcm9sbCBvbiB0aGUgYm9keVxuICAgICAgICBib2R5U2Nyb2xsTG9jay5lbmFibGVCb2R5U2Nyb2xsKG92ZXJsYXlNZW51TmF2KTtcblxuICAgICAgICAvLyBJZiB0aGUgb3ZlcmxheU1lbnUgaXMgYWxyZWFkeSBhY3RpdmUsIGNvbGxhcHNlIGl0IGFuZCBxdWl0XG4gICAgICAgIGlmIChkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5jb250YWlucygnaXMtb3ZlcmxheS1tZW51LWFjdGl2ZScpKSB7XG4gICAgICAgICAgICBvdmVybGF5TWVudU5hdi5xdWVyeVNlbGVjdG9yQWxsKCdbdGFiaW5kZXg9XCIwXCJdJykuZm9yRWFjaChmdW5jdGlvbihlbGVtKSB7XG4gICAgICAgICAgICAgICAgZWxlbS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnaXMtb3ZlcmxheS1tZW51LWFjdGl2ZScpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9jayBzY3JvbGxpbmcgb24gdGhlIGJvZHlcbiAgICAgICAgYm9keVNjcm9sbExvY2suZGlzYWJsZUJvZHlTY3JvbGwob3ZlcmxheU1lbnVOYXYpO1xuXG4gICAgICAgIG92ZXJsYXlNZW51TmF2LnF1ZXJ5U2VsZWN0b3JBbGwoJ1t0YWJpbmRleD1cIi0xXCJdJykuZm9yRWFjaChmdW5jdGlvbihlbGVtKSB7XG4gICAgICAgICAgICBlbGVtLnRhYkluZGV4ID0gMDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVG9nZ2xlIGFjdGl2ZSBvdmVybGF5TWVudSBieSBzZXR0aW5nIGEgY2xhc3Mgb24gdGhlIGJvZHlcbiAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QudG9nZ2xlKCdpcy1vdmVybGF5LW1lbnUtYWN0aXZlJyk7XG4gICAgICAgIG92ZXJsYXlNZW51TmF2LmhpZGRlbiA9IGZhbHNlO1xuICAgIH1cbn07XG5cbk92ZXJsYXlNZW51SGFuZGxlci5pbml0KCk7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IFBhc2NhbCBvbiAwNi8xMi8xNy5cbiAqIChOYW1lIGNoYW5nZXMgYnkgUm9iIG9uIDE4LzAzLzE4KVxuICovXG5cbi8qIEV4YW1wbGVcblxuY29uc3QgaGVhZGVySW1hZ2VTbGlkZXJTZXR0aW5nID0gbmV3IFByb2plY3RvclNldHRpbmcoe1xuICAgIHNsaWRlclByb2plY3RvcklkOiAnaGVhZGVyLWltYWdlLXNsaWRlcicsXG4gICAgc2xpZGVRdWVyeTogJyNoZWFkZXItaW1hZ2Utc2xpZGVyIC5wbGFjZWhvbGRlciBmaWd1cmUnLFxuICAgIGRvdHM6ICcjaGVhZGVyLWltYWdlLXNsaWRlciAuc2xpZGVyLW5hdmlnYXRpb24tbGFiZWxzIC5uYXZpZ2F0aW9uIHNwYW4nLFxuICAgIGNhcHRpb25zOiAnI2hlYWRlci1pbWFnZS1zbGlkZXIgLnNsaWRlci1uYXZpZ2F0aW9uLWxhYmVscyAuY2FwdGlvbiBwJyxcbiAgICBhdXRvU2xpZGU6IHRydWUsXG4gICAgc2xpZGVySW50ZXJ2YWw6IDQwMDBcbn0pO1xuaGVhZGVySW1hZ2VTbGlkZXJTZXR0aW5nID0gaGVhZGVySW1hZ2VTbGlkZXJTZXR0aW5nLnByZXBhcmVQYXJhbWV0ZXJzKCk7XG5cbmNvbnN0IGhlYWRlckltYWdlU2xpZGVyID0gbmV3IFByb2plY3RvcihoZWFkZXJJbWFnZVNsaWRlclNldHRpbmcpLmluaXQoKTtcblxuICovXG5cbmxldCBwcm9qZWN0b3JzID0gW107XG5cbmNvbnN0IHByb2plY3RvckNvbnRhaW5lcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuanMtcHJvamVjdG9yJyk7XG5jb25zdCBwcm9qZWN0b3JDb250YWluZXJzTGVuZ3RoID0gcHJvamVjdG9yQ29udGFpbmVycy5sZW5ndGg7XG5cbmZvcihsZXQgaSA9MDsgaSA8IHByb2plY3RvckNvbnRhaW5lcnNMZW5ndGg7IGkrKyl7XG5cbiAgICBjb25zdCBwcm9qZWN0b3IgPSBwcm9qZWN0b3JDb250YWluZXJzW2ldO1xuICAgIGNvbnN0IHByb2plY3RvcklkID0gcHJvamVjdG9yLmdldEF0dHJpYnV0ZSgnaWQnKTtcblxuICAgIGlmKHByb2plY3RvcklkICE9PSBudWxsKXtcblxuICAgICAgICBjb25zdCBwcm9qZWN0b3JTZXR0aW5nID0gbmV3IFByb2plY3RvclNldHRpbmcoe1xuICAgICAgICAgICAgc2xpZGVySWQ6IHByb2plY3RvcklkLFxuICAgICAgICAgICAgc2xpZGVRdWVyeTogJyMnICsgcHJvamVjdG9ySWQgKycgLmpzLXByb2plY3Rvci1zbGlkZScsXG4gICAgICAgICAgICBuYXZpZ2F0aW9uQnV0dG9uczogJyMnICsgcHJvamVjdG9ySWQgKycgLmpzLXByb2plY3Rvci1idXR0b24nICxcbiAgICAgICAgICAgIGRvdHM6ICcjJyArIHByb2plY3RvcklkICsnIC5qcy1wcm9qZWN0b3ItaW5kaWNhdG9yJyAsXG4gICAgICAgICAgICBhdXRvU2xpZGU6IHRydWUsXG4gICAgICAgICAgICBzbGlkZXJJbnRlcnZhbDogNDAwMFxuICAgICAgICB9KTtcblxuICAgICAgICBwcm9qZWN0b3JzLnB1c2goIG5ldyBQcm9qZWN0b3IocHJvamVjdG9yU2V0dGluZy5wcmVwYXJlUGFyYW1ldGVycygpKS5pbml0KCkgKTtcbiAgICB9XG4gICAgZWxzZSBjb25zb2xlLmxvZygnQW4gaW1hZ2Ugc2xpZGVyIGhhcyBubyBpZC4uLicpO1xufVxuXG5cbmZ1bmN0aW9uIFByb2plY3RvclNldHRpbmcoc2V0dGluZ3NPYmplY3QpIHtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgdGhpcy5zbGlkZXJJZCA9ICcnO1xuICAgIHRoaXMuZGVmaW5lZFByZXZpb3VzTmV4dCA9IHRydWU7XG4gICAgdGhpcy5hdXRvU2xpZGUgPSBmYWxzZTtcbiAgICB0aGlzLnNsaWRlckludGVydmFsID0gNDAwMDtcbiAgICB0aGlzLm5hdmlnYXRpb25CdXR0b25zID0gJyc7XG4gICAgdGhpcy5kb3RzID0gJyc7XG4gICAgdGhpcy5jYXB0aW9ucyA9ICcnO1xuICAgIHRoaXMuc2xpZGVRdWVyeSA9ICcnO1xuXG4gICAgdGhpcy5zZXRQcm9qZWN0b3JJZCA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zbGlkZXJJZCA9IHN0cmluZztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLnNldERlZmluZWRQcmV2aW91c05leHQgPSBmdW5jdGlvbiAoYm9vbGVhbikge1xuICAgICAgICB0aGlzLmRlZmluZWRQcmV2aW91c05leHQgPSBib29sZWFuO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHRoaXMuc2V0QXV0b1NsaWRlID0gZnVuY3Rpb24gKGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5hdXRvU2xpZGUgPSBib29sZWFuO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHRoaXMuc2V0U2xpZGVySW50ZXJ2YWwgPSBmdW5jdGlvbiAoaW50ZWdlcikge1xuICAgICAgICB0aGlzLnNsaWRlckludGVydmFsID0gaW50ZWdlcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLnNldFNsaWRlUXVlcnkgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2xpZGVRdWVyeSA9IHN0cmluZztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLnNldE5hdmlnYXRpb25CdXR0b25zID0gZnVuY3Rpb24gKHN0cmluZykge1xuICAgICAgICB0aGlzLm5hdmlnYXRpb25CdXR0b25zID0gc3RyaW5nO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHRoaXMuc2V0RG90cyA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5kb3RzID0gc3RyaW5nO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHRoaXMuc2V0Q2FwdGlvbnMgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FwdGlvbnMgPSBzdHJpbmc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgdGhpcy5nZXRQcm9qZWN0b3JJZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVySWQ7XG4gICAgfTtcbiAgICB0aGlzLmdldERlZmluZWRQcmV2aW91c05leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlZmluZWRQcmV2aW91c05leHQ7XG4gICAgfTtcbiAgICB0aGlzLmdldEF1dG9TbGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0b1NsaWRlO1xuICAgIH07XG4gICAgdGhpcy5nZXRTbGlkZXJJbnRlcnZhbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVySW50ZXJ2YWw7XG4gICAgfTtcbiAgICB0aGlzLmdldFNsaWRlUXVlcnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNsaWRlUXVlcnk7XG4gICAgfTtcbiAgICB0aGlzLmdldE5hdmlnYXRpb25CdXR0b25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uQnV0dG9ucztcbiAgICB9O1xuICAgIHRoaXMuZ2V0RG90cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG90cztcbiAgICB9O1xuICAgIHRoaXMuZ2V0Q2FwdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhcHRpb25zO1xuICAgIH07XG5cblxuICAgIC8vIEludmVydCBzZXR0ZXJzIHRvIGdldHRlcnNcbiAgICB0aGlzLnByZXBhcmVQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzbGlkZXJJZDogc2VsZi5nZXRQcm9qZWN0b3JJZCgpLFxuICAgICAgICAgICAgZGVmaW5lZFByZXZpb3VzTmV4dDogc2VsZi5nZXREZWZpbmVkUHJldmlvdXNOZXh0KCksXG4gICAgICAgICAgICBhdXRvU2xpZGU6IHNlbGYuZ2V0QXV0b1NsaWRlKCksXG4gICAgICAgICAgICBzbGlkZXJJbnRlcnZhbDogc2VsZi5nZXRTbGlkZXJJbnRlcnZhbCgpLFxuICAgICAgICAgICAgbmF2aWdhdGlvbkJ1dHRvbnM6IHNlbGYuZ2V0TmF2aWdhdGlvbkJ1dHRvbnMoKSxcbiAgICAgICAgICAgIGRvdHM6IHNlbGYuZ2V0RG90cygpLFxuICAgICAgICAgICAgY2FwdGlvbnM6IHNlbGYuZ2V0Q2FwdGlvbnMoKSxcbiAgICAgICAgICAgIHNsaWRlUXVlcnk6IHNlbGYuZ2V0U2xpZGVRdWVyeSgpXG4gICAgICAgIH1cblxuICAgIH07XG5cbiAgICAvLyBNYXNzIGFzc2lnbiBzZXR0aW5nc1xuICAgIHRoaXMuZmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gT2JqZWN0LmtleXMoc2V0dGluZ3NPYmplY3QpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAvLyAgICAgc2VsZltrZXldID0gc2V0dGluZ3NPYmplY3Rba2V5XTtcbiAgICAgICAgLy8gfSk7XG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3NPYmplY3RLZXlzID0gT2JqZWN0LmtleXMoc2V0dGluZ3NPYmplY3QpO1xuICAgICAgICBjb25zdCBzZXR0aW5nc09iamVjdExlbmd0aCA9IHNldHRpbmdzT2JqZWN0S2V5cy5sZW5ndGg7XG5cbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHNldHRpbmdzT2JqZWN0TGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gc2V0dGluZ3NPYmplY3RLZXlzW2ldO1xuICAgICAgICAgICAgc2VsZltrZXldID0gc2V0dGluZ3NPYmplY3Rba2V5XTtcbiAgICAgICAgfVxuXG4gICAgfTtcblxuICAgIHRoaXMuZmlsbCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgc2xpZGVySWQ6IHNlbGYuc2V0UHJvamVjdG9ySWQsXG4gICAgICAgIGRlZmluZWRQcmV2aW91c05leHQ6IHNlbGYuc2V0RGVmaW5lZFByZXZpb3VzTmV4dCxcbiAgICAgICAgYXV0b1NsaWRlOiBzZWxmLnNldEF1dG9TbGlkZSxcbiAgICAgICAgc2xpZGVySW50ZXJ2YWw6IHNlbGYuc2V0U2xpZGVySW50ZXJ2YWwsXG4gICAgICAgIG5hdmlnYXRpb25CdXR0b25zOiBzZWxmLnNldE5hdmlnYXRpb25CdXR0b25zLFxuICAgICAgICBkb3RzOiBzZWxmLnNldERvdHMsXG4gICAgICAgIGNhcHRpb25zOiBzZWxmLnNldENhcHRpb25zLFxuICAgICAgICBzbGlkZVF1ZXJ5OiBzZWxmLnNldFNsaWRlUXVlcnksXG4gICAgICAgIHByZXBhcmVQYXJhbWV0ZXJzOiBzZWxmLnByZXBhcmVQYXJhbWV0ZXJzXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gUHJvamVjdG9yKHNldHRpbmdzKSB7XG5cbiAgICAvL0RlZmluZSBQcm9qZWN0b3Igb2JqZWN0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5zbGlkZXJPYmplY3QgPSAnJztcblxuICAgIC8vU2xpZGVQYXJhbWV0ZXJzXG4gICAgdGhpcy5hY3RpdmVTbGlkZUlkID0gMDtcbiAgICB0aGlzLnByZXZpb3VzU2xpZGVJZCA9IDA7XG4gICAgdGhpcy5uZXh0U2xpZGVJZCA9IDA7XG4gICAgdGhpcy5hdmFpbGFibGVTbGlkZXMgPSAxO1xuICAgIHRoaXMuc2xpZGVzID0gW107XG4gICAgdGhpcy5hdXRvU2xpZGVJbnRlcnZhbCA9IG51bGw7XG5cbiAgICB0aGlzLnNldHRpbmdzID0ge307XG5cbiAgICB0aGlzLmluaXQgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgLy9BcHBlbmQgc2V0dGluZ3MgdG8gc2VsZlxuICAgICAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgICAgICAgLy9Bc3NpZ24gbmVlZGVkIGVsZW1lbnRzIGFuZCBjYWxjdWxhdGlvbnNcbiAgICAgICAgdGhpcy5zbGlkZXJPYmplY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnNldHRpbmdzLnNsaWRlcklkKTtcbiAgICAgICAgdGhpcy5zbGlkZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3Muc2xpZGVRdWVyeSk7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlU2xpZGVzID0gdGhpcy5zbGlkZXMubGVuZ3RoO1xuICAgICAgICB0aGlzLmFjdGl2ZVNsaWRlSWQgPSAwO1xuXG4gICAgICAgIC8vRGVmaW5lIHByZXZpb3VzIGFuZCBuZXh0IGlmIHdlIHdhbnQgdG8gdXNlIHRob3NlXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRlZmluZWRQcmV2aW91c05leHQpIHRoaXMuc2V0UHJldmlvdXNBbmROZXh0U2xpZGUoKTtcblxuICAgICAgICAvLyBTZXQgYWN0aXZlIHNsaWRlIChhbmQgcG9zc2libGUgcHJldmlvdXMgYW5kIG5leHQgY2xhc3NlcylcbiAgICAgICAgdGhpcy5zZXRTbGlkZSgpO1xuXG4gICAgICAgIC8vIFN3aXBlIGludGVyYWN0aW9uXG4gICAgICAgIGNvbnN0IHN3aXBlR2VzdHVyZXMgPSBuZXcgSGFtbWVyKHRoaXMuc2xpZGVyT2JqZWN0KTtcbiAgICAgICAgc3dpcGVHZXN0dXJlcy5vbignc3dpcGVsZWZ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2VsZi5yZXNldEF1dG9TbGlkZSgpO1xuICAgICAgICAgICAgc2VsZi5uZXh0U2xpZGUoKTtcbiAgICAgICAgICAgIHNlbGYuc2V0U2xpZGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHN3aXBlR2VzdHVyZXMub24oJ3N3aXBlcmlnaHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZWxmLnJlc2V0QXV0b1NsaWRlKCk7XG4gICAgICAgICAgICBzZWxmLnByZXZpb3VzU2xpZGUoKTtcbiAgICAgICAgICAgIHNlbGYuc2V0U2xpZGUoKTtcbiAgICAgICAgfSk7XG5cblxuXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICE9PSAnJykge1xuXG4gICAgICAgICAgICAvLyBDbGljayBpbnRlcmFjdGlvblxuICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3MubmF2aWdhdGlvbkJ1dHRvbnMpO1xuICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbnNMZW5ndGggPSBuYXZpZ2F0aW9uQnV0dG9ucy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgbmF2aWdhdGlvbkJ1dHRvbnNMZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbiA9IG5hdmlnYXRpb25CdXR0b25zW2ldO1xuICAgICAgICAgICAgICAgIG5hdmlnYXRpb25CdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xpY2tOYXZpZ2F0aW9uQnV0dG9uKHRoaXMpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5kb3RzICE9PSAnJykge1xuICAgICAgICAgICAgLy8gQ2xpY2sgaW50ZXJhY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IGRvdHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3MuZG90cyk7XG4gICAgICAgICAgICBjb25zdCBkb3RzTGVuZ3RoID0gZG90cy5sZW5ndGg7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyh0aGlzLnNldHRpbmdzLmRvdHMpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZG90cyk7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgZG90c0xlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICAgICBjb25zdCBkb3QgPSBkb3RzW2ldO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdoaWVyJyk7XG4gICAgICAgICAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmNsaWNrRG90KHRoaXMpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLmF1dG9TbGlkZSgpO1xuICAgIH07XG5cblxuICAgIHRoaXMuYXV0b1NsaWRlID0gZnVuY3Rpb24gKCl7XG5cbiAgICAgICAgaWYodGhpcy5hdXRvU2xpZGVJbnRlcnZhbCAhPT0gbnVsbCkgY2xlYXJJbnRlcnZhbCh0aGlzLmF1dG9TbGlkZUludGVydmFsKTtcblxuICAgICAgICBpZih0aGlzLnNldHRpbmdzLmF1dG9TbGlkZSAmJiBOdW1iZXIuaXNJbnRlZ2VyKHRoaXMuc2V0dGluZ3Muc2xpZGVySW50ZXJ2YWwpICl7XG5cbiAgICAgICAgICAgIHRoaXMuYXV0b1NsaWRlSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXh0U2xpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRTbGlkZSgpO1xuICAgICAgICAgICAgICAgIH0sIHRoaXMuc2V0dGluZ3Muc2xpZGVySW50ZXJ2YWxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yZXNldEF1dG9TbGlkZSA9IHNlbGYuYXV0b1NsaWRlO1xuXG5cbiAgICB0aGlzLm5leHRTbGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVTbGlkZUlkKys7XG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZVNsaWRlSWQgPj0gdGhpcy5hdmFpbGFibGVTbGlkZXMpIHRoaXMuYWN0aXZlU2xpZGVJZCA9IDA7XG5cbiAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3MuZGVmaW5lZFByZXZpb3VzTmV4dCkgdGhpcy5zZXRQcmV2aW91c0FuZE5leHRTbGlkZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnByZXZpb3VzU2xpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlU2xpZGVJZC0tO1xuICAgICAgICBpZiAodGhpcy5hY3RpdmVTbGlkZUlkIDwgMCkgdGhpcy5hY3RpdmVTbGlkZUlkID0gdGhpcy5hdmFpbGFibGVTbGlkZXMgLSAxO1xuXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRlZmluZWRQcmV2aW91c05leHQpIHRoaXMuc2V0UHJldmlvdXNBbmROZXh0U2xpZGUoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRQcmV2aW91c0FuZE5leHRTbGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5uZXh0U2xpZGVJZCA9IHRoaXMuYWN0aXZlU2xpZGVJZCArIDE7XG4gICAgICAgIGlmICh0aGlzLm5leHRTbGlkZUlkID49IHRoaXMuYXZhaWxhYmxlU2xpZGVzKSB0aGlzLm5leHRTbGlkZUlkID0gMDtcblxuICAgICAgICB0aGlzLnByZXZpb3VzU2xpZGVJZCA9IHRoaXMuYWN0aXZlU2xpZGVJZCAtIDE7XG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzU2xpZGVJZCA8IDApIHRoaXMucHJldmlvdXNTbGlkZUlkID0gdGhpcy5hdmFpbGFibGVTbGlkZXMgLSAxO1xuICAgIH07XG5cbiAgICB0aGlzLnNldFNsaWRlID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgZm9ybSBlbGVtZW50c1xuICAgICAgICBjb25zdCBzbGlkZXNMZW5ndGggPSBzZWxmLnNsaWRlcy5sZW5ndGg7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBzbGlkZXNMZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBzbGlkZSA9IHNlbGYuc2xpZGVzW2ldO1xuXG4gICAgICAgICAgICAvLyBDb252ZXJ0IGRhdGEgc2V0IGF0dHJpYnV0ZSB0byBkZXNpcmVkIHR5cGVcbiAgICAgICAgICAgIGNvbnN0IHNsaWRlT3JkZXIgPSBwYXJzZUludChzbGlkZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JkZXInKSk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbmQgc2V0IGFjdGl2ZSBmb3IgYWxsIHNsaWRlc1xuICAgICAgICAgICAgaWYgKHNsaWRlT3JkZXIgIT09IHNlbGYuYWN0aXZlU2xpZGVJZCkgc2xpZGUuY2xhc3NMaXN0LnJlbW92ZSgnaXMtYWN0aXZlJyk7XG4gICAgICAgICAgICBlbHNlIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2lzLWFjdGl2ZScpO1xuXG4gICAgICAgICAgICAvLyBJZiB3ZSB1c2UgdGhlIHByZXZpb3VzIGFuZCBuZXh0LCBhbHNvIHNldCB0aG9zZSBjbGFzc2VzXG4gICAgICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5kZWZpbmVkUHJldmlvdXNOZXh0KSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoc2xpZGVPcmRlciAhPT0gc2VsZi5wcmV2aW91c1NsaWRlSWQpIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ3ByZXZpb3VzJyk7XG4gICAgICAgICAgICAgICAgZWxzZSBzbGlkZS5jbGFzc0xpc3QuYWRkKCdwcmV2aW91cycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNsaWRlT3JkZXIgIT09IHNlbGYubmV4dFNsaWRlSWQpIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ25leHQnKTtcbiAgICAgICAgICAgICAgICBlbHNlIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ25leHQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRvdHMgIT09ICcnKSB7IHNlbGYuc2V0QWN0aXZlRG90KCk7IH1cbiAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3MuY2FwdGlvbnMgIT09ICcnKSB7IHNlbGYuc2V0QWN0aXZlQ2FwdGlvbigpOyB9XG4gICAgfTtcblxuICAgIHRoaXMuY2xpY2tOYXZpZ2F0aW9uQnV0dG9uID0gZnVuY3Rpb24gKG5hdkJ1dHRvbikge1xuICAgICAgICBzZWxmLmFjdGl2ZVNsaWRlSWQgPSBwYXJzZUludChuYXZCdXR0b24uZ2V0QXR0cmlidXRlKCdkYXRhLW9yZGVyJykpO1xuICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5kZWZpbmVkUHJldmlvdXNOZXh0KSBzZWxmLnNldFByZXZpb3VzQW5kTmV4dFNsaWRlKCk7XG4gICAgICAgIHNlbGYuc2V0U2xpZGUoKTtcblxuICAgICAgICBjb25zdCBuZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICsgJy5uZXh0Jyk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICsgJy5wcmV2aW91cycpO1xuXG4gICAgICAgIG5leHQuc2V0QXR0cmlidXRlKCdkYXRhLW9yZGVyJywgc2VsZi5uZXh0U2xpZGVJZCk7XG4gICAgICAgIHByZXZpb3VzLnNldEF0dHJpYnV0ZSgnZGF0YS1vcmRlcicsIHNlbGYucHJldmlvdXNTbGlkZUlkKTtcblxuICAgICAgICBzZWxmLnJlc2V0QXV0b1NsaWRlKCk7XG5cbiAgICAgICAgLy8gbmV4dC5xdWVyeVNlbGVjdG9yKCdwJykuaW5uZXJIVE1MID0gc2VsZi5zbGlkZXNbc2VsZi5uZXh0U2xpZGVJZF0uZGF0YXNldC5uYW1lO1xuICAgICAgICAvLyBwcmV2aW91cy5xdWVyeVNlbGVjdG9yKCdwJykuaW5uZXJIVE1MID0gc2VsZi5zbGlkZXNbc2VsZi5wcmV2aW91c1NsaWRlSWRdLmRhdGFzZXQubmFtZTtcbiAgICB9O1xuXG4gICAgdGhpcy5jbGlja0RvdCA9IGZ1bmN0aW9uIChjbGlja2VkRG90KSB7XG4gICAgICAgIHNlbGYuYWN0aXZlU2xpZGVJZCA9IHBhcnNlSW50KGNsaWNrZWREb3QuZ2V0QXR0cmlidXRlKCdkYXRhLW9yZGVyJykpO1xuICAgICAgICBzZWxmLnNldFNsaWRlKCk7XG4gICAgICAgIHNlbGYucmVzZXRBdXRvU2xpZGUoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRBY3RpdmVEb3QgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgY29uc3QgZG90cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwodGhpcy5zZXR0aW5ncy5kb3RzKTtcbiAgICAgICAgY29uc3QgZG90c0xlbmd0aCA9IGRvdHMubGVuZ3RoO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgZG90c0xlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgIGNvbnN0IGRvdCA9IGRvdHNbaV07XG4gICAgICAgICAgICBkb3RPcmRlciA9IHBhcnNlSW50KGRvdC5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JkZXInKSk7XG5cbiAgICAgICAgICAgIGlmKGRvdE9yZGVyICE9PSBzZWxmLmFjdGl2ZVNsaWRlSWQpIGRvdC5jbGFzc0xpc3QucmVtb3ZlKCdpcy1hY3RpdmUnKTtcbiAgICAgICAgICAgIGVsc2UgZG90LmNsYXNzTGlzdC5hZGQoJ2lzLWFjdGl2ZScpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuc2V0QWN0aXZlQ2FwdGlvbiA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBjb25zdCBjYXB0aW9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwodGhpcy5zZXR0aW5ncy5jYXB0aW9ucyk7XG4gICAgICAgIGNvbnN0IGNhcHRpb25zTGVuZ3RoID0gY2FwdGlvbnMubGVuZ3RoO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgY2FwdGlvbnNMZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBjYXB0aW9uID0gY2FwdGlvbnNbaV07XG4gICAgICAgICAgICBjYXB0aW9uT3JkZXIgPSBwYXJzZUludChjYXB0aW9uLmdldEF0dHJpYnV0ZSgnZGF0YS1vcmRlcicpKTtcblxuICAgICAgICAgICAgaWYoY2FwdGlvbk9yZGVyICE9PSBzZWxmLmFjdGl2ZVNsaWRlSWQpIGNhcHRpb24uY2xhc3NMaXN0LnJlbW92ZSgnaXMtYWN0aXZlJyk7XG4gICAgICAgICAgICBlbHNlIGNhcHRpb24uY2xhc3NMaXN0LmFkZCgnaXMtYWN0aXZlJyk7XG4gICAgICAgIH1cbiAgICB9O1xufSIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgU2Nyb2xsIFRvIENsaWNrIGhhbmRsZXJcbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5jb25zdCBTY3JvbGxUb0hhbmRsZXIgPSB7XG5cbiAgICAvLyBBbmltYXRpb24gc2V0dGluZ3NcbiAgICBvZmZzZXQgOiA2MCwgLy9waXhlbFxuICAgIGR1cmF0aW9uIDogMTQwMCwgLy9tc1xuXG4gICAgLy8gQW5pbWF0aW9uIHZhcmlhYmxlc1xuICAgIGJvZHkgOiBudWxsLFxuICAgIHN0YXJ0IDogMCxcbiAgICBjaGFuZ2UgOiAwLFxuICAgIGN1cnJlbnRUaW1lIDogMCxcbiAgICBhbGxvd0FuaW1hdGlvbiA6IGZhbHNlLFxuICAgIHNjcm9sbFRvQW5pbWF0aW9uIDogbnVsbCxcblxuICAgIC8vIFdhdGNoIHRoZSBFYXNpbmdGdW5jdGlvbiBoZWxwZXIgZm9yIHRoZSBhdmFpbGFibGUgbWV0aG9kc1xuICAgIGVhc2luZzogJ2Vhc2VJbk91dFF1YWQnLFxuXG4gICAgaW5pdCA6IGZ1bmN0aW9uKCl7XG5cbiAgICAgICAgY29uc3QgYW5jaG9yTGlua3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuanMtc2Nyb2xsLXRvLXRhcmdldCcpO1xuICAgICAgICBjb25zdCBhbmNob3JMaW5rc0Ftb3VudCA9IGFuY2hvckxpbmtzLmxlbmd0aDtcblxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgYW5jaG9yTGlua3NBbW91bnQ7IGkrKykge1xuXG4gICAgICAgICAgICBjb25zdCBhbmNob3JMaW5rID0gYW5jaG9yTGlua3NbaV07XG5cbiAgICAgICAgICAgIGFuY2hvckxpbmsuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBTY3JvbGxUb0hhbmRsZXIucHJlcGFyZVNjcm9sbFRvKHRoaXMuZ2V0QXR0cmlidXRlKCdocmVmJykpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBQcmVwYXJlIHRoZSBIYW5kbGVyIGZvciB0aGUgYW5pbWF0aW9uXG4gICAgICovXG4gICAgcHJlcGFyZVNjcm9sbFRvIDogZnVuY3Rpb24oZWxlbWVudElkKXtcblxuICAgICAgICAvLyBHZXQgdGhlIHNjcm9sbCB0byBlbGVtZW50XG4gICAgICAgIGVsZW1lbnRJZCA9IGVsZW1lbnRJZC5zdWJzdHIoZWxlbWVudElkLmluZGV4T2YoJyMnKSsxKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9FbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9FbGVtZW50UG9zaXRpb24gPSBzY3JvbGxUb0VsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgLy8gUmVzZXQgb3IgZGVmaW5lIHRoZSBIYW5kbGVyIHZhcmlhYmxlc1xuICAgICAgICBTY3JvbGxUb0hhbmRsZXIuYm9keSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgU2Nyb2xsVG9IYW5kbGVyLnN0YXJ0ID0gTWF0aC5tYXgoU2Nyb2xsVG9IYW5kbGVyLmJvZHkuc2Nyb2xsVG9wLCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCwgd2luZG93LnBhZ2VZT2Zmc2V0KTsgLy9Vc2UgTWF0aC5tYXggYmVjYXVzZSBzYWZhcmkgZG9lc24ndCBzdXBwb3J0IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3BcbiAgICAgICAgU2Nyb2xsVG9IYW5kbGVyLmNoYW5nZSA9ICgoc2Nyb2xsVG9FbGVtZW50UG9zaXRpb24udG9wICsgU2Nyb2xsVG9IYW5kbGVyLnN0YXJ0KSAtIFNjcm9sbFRvSGFuZGxlci5zdGFydCkgLSBTY3JvbGxUb0hhbmRsZXIub2Zmc2V0O1xuICAgICAgICBTY3JvbGxUb0hhbmRsZXIuc3RhcnRUaW1lID0gJ25vdycgaW4gd2luZG93LnBlcmZvcm1hbmNlID8gcGVyZm9ybWFuY2Uubm93KCkgOiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgU2Nyb2xsVG9IYW5kbGVyLmFsbG93QW5pbWF0aW9uID0gdHJ1ZTtcblxuICAgICAgICAvLyBUcmlnZ2VyIGFuaW1hdGlvblxuICAgICAgICBzY3JvbGxUb0FuaW1hdGlvbiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShTY3JvbGxUb0hhbmRsZXIuYW5pbWF0ZVNjcm9sbCk7XG5cbiAgICAgICAgLy8gU3RvcCBvbiBzY3JvbGxcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIFNjcm9sbFRvSGFuZGxlci5hYm9ydFNjcm9sbEFuaW1hdGlvbik7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsIFNjcm9sbFRvSGFuZGxlci5hYm9ydFNjcm9sbEFuaW1hdGlvbik7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdET01Nb3VzZVNjcm9sbCcsIFNjcm9sbFRvSGFuZGxlci5hYm9ydFNjcm9sbEFuaW1hdGlvbik7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXdoZWVsJywgU2Nyb2xsVG9IYW5kbGVyLmFib3J0U2Nyb2xsQW5pbWF0aW9uKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgU2Nyb2xsVG9IYW5kbGVyLmFib3J0U2Nyb2xsQW5pbWF0aW9uKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIFNjcm9sbFRvSGFuZGxlci5hYm9ydFNjcm9sbEFuaW1hdGlvbik7XG5cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBbmltYXRlIHRoZSBzY3JvbGwgcG9zaXRpb25cbiAgICAgKi9cbiAgICBhbmltYXRlU2Nyb2xsIDogZnVuY3Rpb24gKHRpbWVzdGFtcCkge1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSBwcm9ncmVzcyBmcm9tIDAgLSAxXG4gICAgICAgIGxldCBwcm9ncmVzcyA9IE1hdGgubWluKDEsICh0aW1lc3RhbXAgLSAgU2Nyb2xsVG9IYW5kbGVyLnN0YXJ0VGltZSkgLyBTY3JvbGxUb0hhbmRsZXIuZHVyYXRpb24pO1xuICAgICAgICBpZihwcm9ncmVzcyA8IDApIHByb2dyZXNzID0gMDtcblxuICAgICAgICAvLyBDb252ZXJ0IHByb2dyZXNzIHdpdGggZWFzaW5nIGZ1bmN0aW9uXG4gICAgICAgIHByb2dyZXNzID0gRWFzaW5nRnVuY3Rpb25zW1Njcm9sbFRvSGFuZGxlci5lYXNpbmddKHByb2dyZXNzKTtcblxuICAgICAgICBjb25zdCBuZXdTY3JvbGxUb3AgPSBTY3JvbGxUb0hhbmRsZXIuc3RhcnQgKyAoIFNjcm9sbFRvSGFuZGxlci5jaGFuZ2UgKiBwcm9ncmVzcyApO1xuXG4gICAgICAgIFNjcm9sbFRvSGFuZGxlci5ib2R5LnNjcm9sbFRvcCA9IG5ld1Njcm9sbFRvcDtcbiAgICAgICAgaWYoIFNjcm9sbFRvSGFuZGxlci5ib2R5LnNjcm9sbFRvcCA9PT0gMCApIGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wID0gbmV3U2Nyb2xsVG9wOyAvLyBTYWZhcmkgZG9lc24ndCBzdXBwb3J0IHNvIGlmIFNjcm9sbFRvSGFuZGxlci5ib2R5LnNjcm9sbFRvcCBpcyAwIGZvcmNlIHRoZSBzY3JvbGwgcG9zaXRpb24gdGhyb3VnaCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcFxuXG4gICAgICAgIGlmKHByb2dyZXNzIDwgMSAmJiBTY3JvbGxUb0hhbmRsZXIuYWxsb3dBbmltYXRpb24pe1xuICAgICAgICAgICAgc2Nyb2xsVG9BbmltYXRpb24gPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoU2Nyb2xsVG9IYW5kbGVyLmFuaW1hdGVTY3JvbGwpO1xuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBYm9ydCB0aGUgc2Nyb2xsIGFuaW1hdGlvblxuICAgICAqL1xuICAgIGFib3J0U2Nyb2xsQW5pbWF0aW9uIDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIFNjcm9sbFRvSGFuZGxlci5hbGxvd0FuaW1hdGlvbiA9IGZhbHNlO1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShTY3JvbGxUb0hhbmRsZXIuc2Nyb2xsVG9BbmltYXRpb24pO1xuICAgIH1cblxufTtcblxuU2Nyb2xsVG9IYW5kbGVyLmluaXQoKTsiLCJsZXQgdGVzdGltb25pYWxTbGlkZXJzID0gW107XG5cbmNvbnN0IHRlc3RpbW9uaWFsU2xpZGVyQ29udGFpbmVycyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy10ZXN0aW1vbmlhbC1zbGlkZXInKTtcbmNvbnN0IHRlc3RpbW9uaWFsU2xpZGVyQ29udGFpbmVyc0xlbmd0aCA9IHRlc3RpbW9uaWFsU2xpZGVyQ29udGFpbmVycy5sZW5ndGg7XG5cbmZvcihsZXQgaSA9MDsgaSA8IHRlc3RpbW9uaWFsU2xpZGVyQ29udGFpbmVyc0xlbmd0aDsgaSsrKXtcblxuICAgIGNvbnN0IHRlc3RpbW9uaWFsU2xpZGVyID0gdGVzdGltb25pYWxTbGlkZXJDb250YWluZXJzW2ldO1xuICAgIGNvbnN0IHRlc3RpbW9uaWFsU2xpZGVySWQgPSB0ZXN0aW1vbmlhbFNsaWRlci5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG5cbiAgICBpZih0ZXN0aW1vbmlhbFNsaWRlcklkICE9PSBudWxsKXtcblxuICAgICAgICBjb25zdCB0ZXN0aW1vbmlhbFNsaWRlclNldHRpbmcgPSBuZXcgUHJvamVjdG9yU2V0dGluZyh7XG4gICAgICAgICAgICBzbGlkZXJJZDogdGVzdGltb25pYWxTbGlkZXJJZCxcbiAgICAgICAgICAgIHNsaWRlUXVlcnk6ICcjJyArIHRlc3RpbW9uaWFsU2xpZGVySWQgKycgLmpzLXRlc3RpbW9uaWFsLXNsaWRlci1pdGVtJyxcbiAgICAgICAgICAgIG5hdmlnYXRpb25CdXR0b25zOiAnIycgKyB0ZXN0aW1vbmlhbFNsaWRlcklkICsnIC5qcy10ZXN0aW1vbmlhbC1zbGlkZXItYnV0dG9uJyAsXG4gICAgICAgICAgICBhdXRvU2xpZGU6IHRydWUsXG4gICAgICAgICAgICBzbGlkZXJJbnRlcnZhbDogMTAwMDBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGVzdGltb25pYWxTbGlkZXJzLnB1c2goIG5ldyBQcm9qZWN0b3IodGVzdGltb25pYWxTbGlkZXJTZXR0aW5nLnByZXBhcmVQYXJhbWV0ZXJzKCkpLmluaXQoKSApO1xuICAgIH1cbiAgICBlbHNlIGNvbnNvbGUubG9nKCdBIHRlc3RpbW9uaWFsLXNsaWRlciBoYXMgbm8gaWQuLi4nKTtcbn1cblxuXG5mdW5jdGlvbiBQcm9qZWN0b3JTZXR0aW5nKHNldHRpbmdzT2JqZWN0KSB7XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIHRoaXMuc2xpZGVySWQgPSAnJztcbiAgICB0aGlzLmRlZmluZWRQcmV2aW91c05leHQgPSB0cnVlO1xuICAgIHRoaXMuYXV0b1NsaWRlID0gZmFsc2U7XG4gICAgdGhpcy5zbGlkZXJJbnRlcnZhbCA9IDEwMDAwO1xuICAgIHRoaXMubmF2aWdhdGlvbkJ1dHRvbnMgPSAnJztcbiAgICB0aGlzLnNsaWRlUXVlcnkgPSAnJztcblxuICAgIHRoaXMuc2V0UHJvamVjdG9ySWQgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2xpZGVySWQgPSBzdHJpbmc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgdGhpcy5zZXREZWZpbmVkUHJldmlvdXNOZXh0ID0gZnVuY3Rpb24gKGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5kZWZpbmVkUHJldmlvdXNOZXh0ID0gYm9vbGVhbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLnNldEF1dG9TbGlkZSA9IGZ1bmN0aW9uIChib29sZWFuKSB7XG4gICAgICAgIHRoaXMuYXV0b1NsaWRlID0gYm9vbGVhbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLnNldFNsaWRlckludGVydmFsID0gZnVuY3Rpb24gKGludGVnZXIpIHtcbiAgICAgICAgdGhpcy5zbGlkZXJJbnRlcnZhbCA9IGludGVnZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgdGhpcy5zZXRTbGlkZVF1ZXJ5ID0gZnVuY3Rpb24gKHN0cmluZykge1xuICAgICAgICB0aGlzLnNsaWRlUXVlcnkgPSBzdHJpbmc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgdGhpcy5zZXROYXZpZ2F0aW9uQnV0dG9ucyA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5uYXZpZ2F0aW9uQnV0dG9ucyA9IHN0cmluZztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB0aGlzLmdldFByb2plY3RvcklkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zbGlkZXJJZDtcbiAgICB9O1xuICAgIHRoaXMuZ2V0RGVmaW5lZFByZXZpb3VzTmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVmaW5lZFByZXZpb3VzTmV4dDtcbiAgICB9O1xuICAgIHRoaXMuZ2V0QXV0b1NsaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRvU2xpZGU7XG4gICAgfTtcbiAgICB0aGlzLmdldFNsaWRlckludGVydmFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zbGlkZXJJbnRlcnZhbDtcbiAgICB9O1xuICAgIHRoaXMuZ2V0U2xpZGVRdWVyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGVRdWVyeTtcbiAgICB9O1xuICAgIHRoaXMuZ2V0TmF2aWdhdGlvbkJ1dHRvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hdmlnYXRpb25CdXR0b25zO1xuICAgIH07XG5cblxuICAgIC8vIEludmVydCBzZXR0ZXJzIHRvIGdldHRlcnNcbiAgICB0aGlzLnByZXBhcmVQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzbGlkZXJJZDogc2VsZi5nZXRQcm9qZWN0b3JJZCgpLFxuICAgICAgICAgICAgZGVmaW5lZFByZXZpb3VzTmV4dDogc2VsZi5nZXREZWZpbmVkUHJldmlvdXNOZXh0KCksXG4gICAgICAgICAgICBhdXRvU2xpZGU6IHNlbGYuZ2V0QXV0b1NsaWRlKCksXG4gICAgICAgICAgICBzbGlkZXJJbnRlcnZhbDogc2VsZi5nZXRTbGlkZXJJbnRlcnZhbCgpLFxuICAgICAgICAgICAgbmF2aWdhdGlvbkJ1dHRvbnM6IHNlbGYuZ2V0TmF2aWdhdGlvbkJ1dHRvbnMoKSxcbiAgICAgICAgICAgIHNsaWRlUXVlcnk6IHNlbGYuZ2V0U2xpZGVRdWVyeSgpXG4gICAgICAgIH1cblxuICAgIH07XG5cbiAgICAvLyBNYXNzIGFzc2lnbiBzZXR0aW5nc1xuICAgIHRoaXMuZmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gT2JqZWN0LmtleXMoc2V0dGluZ3NPYmplY3QpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAvLyAgICAgc2VsZltrZXldID0gc2V0dGluZ3NPYmplY3Rba2V5XTtcbiAgICAgICAgLy8gfSk7XG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3NPYmplY3RLZXlzID0gT2JqZWN0LmtleXMoc2V0dGluZ3NPYmplY3QpO1xuICAgICAgICBjb25zdCBzZXR0aW5nc09iamVjdExlbmd0aCA9IHNldHRpbmdzT2JqZWN0S2V5cy5sZW5ndGg7XG5cbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHNldHRpbmdzT2JqZWN0TGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gc2V0dGluZ3NPYmplY3RLZXlzW2ldO1xuICAgICAgICAgICAgc2VsZltrZXldID0gc2V0dGluZ3NPYmplY3Rba2V5XTtcbiAgICAgICAgfVxuXG4gICAgfTtcblxuICAgIHRoaXMuZmlsbCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgc2xpZGVySWQ6IHNlbGYuc2V0UHJvamVjdG9ySWQsXG4gICAgICAgIGRlZmluZWRQcmV2aW91c05leHQ6IHNlbGYuc2V0RGVmaW5lZFByZXZpb3VzTmV4dCxcbiAgICAgICAgYXV0b1NsaWRlOiBzZWxmLnNldEF1dG9TbGlkZSxcbiAgICAgICAgc2xpZGVySW50ZXJ2YWw6IHNlbGYuc2V0U2xpZGVySW50ZXJ2YWwsXG4gICAgICAgIG5hdmlnYXRpb25CdXR0b25zOiBzZWxmLnNldE5hdmlnYXRpb25CdXR0b25zLFxuICAgICAgICBzbGlkZVF1ZXJ5OiBzZWxmLnNldFNsaWRlUXVlcnksXG4gICAgICAgIHByZXBhcmVQYXJhbWV0ZXJzOiBzZWxmLnByZXBhcmVQYXJhbWV0ZXJzXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gUHJvamVjdG9yKHNldHRpbmdzKSB7XG5cbiAgICAvL0RlZmluZSBQcm9qZWN0b3Igb2JqZWN0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5zbGlkZXJPYmplY3QgPSAnJztcblxuICAgIC8vU2xpZGVQYXJhbWV0ZXJzXG4gICAgdGhpcy5hY3RpdmVTbGlkZUlkID0gMDtcbiAgICB0aGlzLnByZXZpb3VzU2xpZGVJZCA9IDA7XG4gICAgdGhpcy5uZXh0U2xpZGVJZCA9IDA7XG4gICAgdGhpcy5hdmFpbGFibGVTbGlkZXMgPSAxO1xuICAgIHRoaXMuc2xpZGVzID0gW107XG4gICAgdGhpcy5hdXRvU2xpZGVJbnRlcnZhbCA9IG51bGw7XG5cbiAgICB0aGlzLnNldHRpbmdzID0ge307XG5cbiAgICB0aGlzLmluaXQgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgLy9BcHBlbmQgc2V0dGluZ3MgdG8gc2VsZlxuICAgICAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgICAgICAgLy9Bc3NpZ24gbmVlZGVkIGVsZW1lbnRzIGFuZCBjYWxjdWxhdGlvbnNcbiAgICAgICAgdGhpcy5zbGlkZXJPYmplY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnNldHRpbmdzLnNsaWRlcklkKTtcbiAgICAgICAgdGhpcy5zbGlkZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3Muc2xpZGVRdWVyeSk7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlU2xpZGVzID0gdGhpcy5zbGlkZXMubGVuZ3RoO1xuICAgICAgICB0aGlzLmFjdGl2ZVNsaWRlSWQgPSAwO1xuXG4gICAgICAgIC8vRGVmaW5lIHByZXZpb3VzIGFuZCBuZXh0IGlmIHdlIHdhbnQgdG8gdXNlIHRob3NlXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRlZmluZWRQcmV2aW91c05leHQpIHRoaXMuc2V0UHJldmlvdXNBbmROZXh0U2xpZGUoKTtcblxuICAgICAgICAvLyBTZXQgYWN0aXZlIHNsaWRlIChhbmQgcG9zc2libGUgcHJldmlvdXMgYW5kIG5leHQgY2xhc3NlcylcbiAgICAgICAgdGhpcy5zZXRTbGlkZSgpO1xuXG4gICAgICAgIC8vIFN3aXBlIGludGVyYWN0aW9uXG4gICAgICAgIGNvbnN0IHN3aXBlR2VzdHVyZXMgPSBuZXcgSGFtbWVyKHRoaXMuc2xpZGVyT2JqZWN0KTtcbiAgICAgICAgc3dpcGVHZXN0dXJlcy5vbignc3dpcGVsZWZ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2VsZi5yZXNldEF1dG9TbGlkZSgpO1xuICAgICAgICAgICAgc2VsZi5uZXh0U2xpZGUoKTtcbiAgICAgICAgICAgIHNlbGYuc2V0U2xpZGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHN3aXBlR2VzdHVyZXMub24oJ3N3aXBlcmlnaHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZWxmLnJlc2V0QXV0b1NsaWRlKCk7XG4gICAgICAgICAgICBzZWxmLnByZXZpb3VzU2xpZGUoKTtcbiAgICAgICAgICAgIHNlbGYuc2V0U2xpZGUoKTtcbiAgICAgICAgfSk7XG5cblxuXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICE9PSAnJykge1xuXG4gICAgICAgICAgICAvLyBDbGljayBpbnRlcmFjdGlvblxuICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3MubmF2aWdhdGlvbkJ1dHRvbnMpO1xuICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbnNMZW5ndGggPSBuYXZpZ2F0aW9uQnV0dG9ucy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgbmF2aWdhdGlvbkJ1dHRvbnNMZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF2aWdhdGlvbkJ1dHRvbiA9IG5hdmlnYXRpb25CdXR0b25zW2ldO1xuICAgICAgICAgICAgICAgIG5hdmlnYXRpb25CdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xpY2tOYXZpZ2F0aW9uQnV0dG9uKHRoaXMpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLmF1dG9TbGlkZSgpO1xuICAgIH07XG5cblxuICAgIHRoaXMuYXV0b1NsaWRlID0gZnVuY3Rpb24gKCl7XG5cbiAgICAgICAgaWYodGhpcy5hdXRvU2xpZGVJbnRlcnZhbCAhPT0gbnVsbCkgY2xlYXJJbnRlcnZhbCh0aGlzLmF1dG9TbGlkZUludGVydmFsKTtcblxuICAgICAgICBpZih0aGlzLnNldHRpbmdzLmF1dG9TbGlkZSAmJiBOdW1iZXIuaXNJbnRlZ2VyKHRoaXMuc2V0dGluZ3Muc2xpZGVySW50ZXJ2YWwpICl7XG5cbiAgICAgICAgICAgIHRoaXMuYXV0b1NsaWRlSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXh0U2xpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRTbGlkZSgpO1xuICAgICAgICAgICAgICAgIH0sIHRoaXMuc2V0dGluZ3Muc2xpZGVySW50ZXJ2YWxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5yZXNldEF1dG9TbGlkZSA9IHNlbGYuYXV0b1NsaWRlO1xuXG5cbiAgICB0aGlzLm5leHRTbGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVTbGlkZUlkKys7XG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZVNsaWRlSWQgPj0gdGhpcy5hdmFpbGFibGVTbGlkZXMpIHRoaXMuYWN0aXZlU2xpZGVJZCA9IDA7XG5cbiAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3MuZGVmaW5lZFByZXZpb3VzTmV4dCkgdGhpcy5zZXRQcmV2aW91c0FuZE5leHRTbGlkZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLnByZXZpb3VzU2xpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlU2xpZGVJZC0tO1xuICAgICAgICBpZiAodGhpcy5hY3RpdmVTbGlkZUlkIDwgMCkgdGhpcy5hY3RpdmVTbGlkZUlkID0gdGhpcy5hdmFpbGFibGVTbGlkZXMgLSAxO1xuXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRlZmluZWRQcmV2aW91c05leHQpIHRoaXMuc2V0UHJldmlvdXNBbmROZXh0U2xpZGUoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRQcmV2aW91c0FuZE5leHRTbGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5uZXh0U2xpZGVJZCA9IHRoaXMuYWN0aXZlU2xpZGVJZCArIDE7XG4gICAgICAgIGlmICh0aGlzLm5leHRTbGlkZUlkID49IHRoaXMuYXZhaWxhYmxlU2xpZGVzKSB0aGlzLm5leHRTbGlkZUlkID0gMDtcblxuICAgICAgICB0aGlzLnByZXZpb3VzU2xpZGVJZCA9IHRoaXMuYWN0aXZlU2xpZGVJZCAtIDE7XG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzU2xpZGVJZCA8IDApIHRoaXMucHJldmlvdXNTbGlkZUlkID0gdGhpcy5hdmFpbGFibGVTbGlkZXMgLSAxO1xuICAgIH07XG5cbiAgICB0aGlzLnNldFNsaWRlID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgZm9ybSBlbGVtZW50c1xuICAgICAgICBjb25zdCBzbGlkZXNMZW5ndGggPSBzZWxmLnNsaWRlcy5sZW5ndGg7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBzbGlkZXNMZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBzbGlkZSA9IHNlbGYuc2xpZGVzW2ldO1xuXG4gICAgICAgICAgICAvLyBDb252ZXJ0IGRhdGEgc2V0IGF0dHJpYnV0ZSB0byBkZXNpcmVkIHR5cGVcbiAgICAgICAgICAgIGNvbnN0IHNsaWRlT3JkZXIgPSBwYXJzZUludChzbGlkZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JkZXInKSk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbmQgc2V0IGFjdGl2ZSBmb3IgYWxsIHNsaWRlc1xuICAgICAgICAgICAgaWYgKHNsaWRlT3JkZXIgIT09IHNlbGYuYWN0aXZlU2xpZGVJZCkgc2xpZGUuY2xhc3NMaXN0LnJlbW92ZSgnaXMtYWN0aXZlJyk7XG4gICAgICAgICAgICBlbHNlIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2lzLWFjdGl2ZScpO1xuXG4gICAgICAgICAgICAvLyBJZiB3ZSB1c2UgdGhlIHByZXZpb3VzIGFuZCBuZXh0LCBhbHNvIHNldCB0aG9zZSBjbGFzc2VzXG4gICAgICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5kZWZpbmVkUHJldmlvdXNOZXh0KSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoc2xpZGVPcmRlciAhPT0gc2VsZi5wcmV2aW91c1NsaWRlSWQpIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLXByZXZpb3VzJyk7XG4gICAgICAgICAgICAgICAgZWxzZSBzbGlkZS5jbGFzc0xpc3QuYWRkKCdpcy1wcmV2aW91cycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNsaWRlT3JkZXIgIT09IHNlbGYubmV4dFNsaWRlSWQpIHNsaWRlLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLW5leHQnKTtcbiAgICAgICAgICAgICAgICBlbHNlIHNsaWRlLmNsYXNzTGlzdC5hZGQoJ2lzLW5leHQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICsgJy5pcy1uZXh0Jyk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxmLnNldHRpbmdzLm5hdmlnYXRpb25CdXR0b25zICsgJy5pcy1wcmV2aW91cycpO1xuXG4gICAgICAgIG5leHQuc2V0QXR0cmlidXRlKCdkYXRhLW9yZGVyJywgc2VsZi5uZXh0U2xpZGVJZCk7XG4gICAgICAgIHByZXZpb3VzLnNldEF0dHJpYnV0ZSgnZGF0YS1vcmRlcicsIHNlbGYucHJldmlvdXNTbGlkZUlkKTtcbiAgICB9O1xuXG4gICAgdGhpcy5jbGlja05hdmlnYXRpb25CdXR0b24gPSBmdW5jdGlvbiAobmF2QnV0dG9uKSB7XG4gICAgICAgIHNlbGYuYWN0aXZlU2xpZGVJZCA9IHBhcnNlSW50KG5hdkJ1dHRvbi5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JkZXInKSk7XG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRlZmluZWRQcmV2aW91c05leHQpIHNlbGYuc2V0UHJldmlvdXNBbmROZXh0U2xpZGUoKTtcbiAgICAgICAgc2VsZi5zZXRTbGlkZSgpO1xuICAgICAgICBzZWxmLnJlc2V0QXV0b1NsaWRlKCk7XG4gICAgfTtcblxufSIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICBOYXZpZ2F0aW9uIGhhbmRsZXJcbiAgIC0gSGFuZGxlcyB0aGUgc2hvd2luZyBhbmQgaGlkaW5nIG9mIHRoZSBvdmVybGF5LW1lbnUgY29tcG9uZW50IHdoaWNoIGhhcyB0aGUgcHJvcGVyIGNsYXNzZXMuXG4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuY29uc3QgVG9nZ2xlSGFuZGxlciA9IHtcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdG9nZ2xlVHJpZ2dlcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuanMtdG9nZ2xlLXRyaWdnZXInKTtcbiAgICAgICAgY29uc3QgdG9nZ2xlVHJpZ2dlcnNDb3VudCA9IHRvZ2dsZVRyaWdnZXJzLmxlbmd0aDtcblxuICAgICAgICBpZihpc3NldCh0b2dnbGVUcmlnZ2VycykgJiYgdG9nZ2xlVHJpZ2dlcnNDb3VudCA+IDApe1xuICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRvZ2dsZVRyaWdnZXJzQ291bnQ7IGkrKyl7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9nZ2xlVHJpZ2dlciA9IHRvZ2dsZVRyaWdnZXJzW2ldO1xuICAgICAgICAgICAgICAgIFRvZ2dsZUhhbmRsZXIuaW5pdFRvZ2dsZSh0b2dnbGVUcmlnZ2VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBpbml0VG9nZ2xlOiBmdW5jdGlvbiAodG9nZ2xlVHJpZ2dlcikge1xuICAgICAgICB0b2dnbGVUcmlnZ2VyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgVG9nZ2xlSGFuZGxlci5hZGp1c3RUb2dnbGUsIGZhbHNlKTtcbiAgICB9LFxuXG4gICAgYWRqdXN0VG9nZ2xlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaWQgPSBldmVudC5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS10b2dnbGUtaWQnKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0QXJyYXkgPSBbXS5zbGljZS5jYWxsKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy10b2dnbGUtdGFyZ2V0JykpO1xuICAgICAgICBsZXQgdGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhcmdldEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZihpZCA9PT0gdGFyZ2V0QXJyYXlbaV0uZ2V0QXR0cmlidXRlKCdkYXRhLXRvZ2dsZS1pZCcpKXtcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXRBcnJheVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJhaWwgaWYgdG9nZ2xlIGRvZXNuJ3QgZXhpc3RcbiAgICAgICAgaWYgKCF0YXJnZXQpIHJldHVybjtcblxuICAgICAgICAvLyBJZiB0aGUgdG9nZ2xlIGlzIGFscmVhZHkgYWN0aXZlLCBjb2xsYXBzZSBpdCBhbmQgcXVpdFxuICAgICAgICBldmVudC5jdXJyZW50VGFyZ2V0LmNsYXNzTGlzdC50b2dnbGUoJ2lzLXRvZ2dsZWQnKTtcbiAgICB9XG59O1xuXG5Ub2dnbGVIYW5kbGVyLmluaXQoKTsiLCJpbXBvcnQgeyBFcnJvclJlc3BvbnNlIH0gZnJvbSBcIi4uL2dsb2JhbC9tb2RlbHMvZXJyb3JSZXNwb25zZVwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvblJlc3BvbnNlIH0gZnJvbSBcIi4uL2dsb2JhbC9tb2RlbHMvdmFsaWRhdGlvblJlc3BvbnNlXCI7XG5cbmNsYXNzIFZhbGlkYXRpb25TZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Zvcm1EYXRhfSBkYXRhXG4gICAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICB2YWxpZGF0ZUNoZWNrb3V0Rm9ybShkYXRhKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgICAgICBpZighKGRhdGEgaW5zdGFuY2VvZiBGb3JtRGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1ZhbGlkYXRpb25TZXJ2aWNlOnZhbGlkYXRlQ2hlY2tvdXRGb3JtIGNvdWxkIG5vdCB2YWxpZGF0ZSBmb3JtIHNpbmNlIG5vIHZhbGlkIEZvcm1EYXRhIGluc3RhbmNlIHdhcyBnaXZlbi4nKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnVmFsaWRhdGlvblNlcnZpY2U6dmFsaWRhdGVDaGVja291dEZvcm0gY291bGQgbm90IHZhbGlkYXRlIGZvcm0gc2luY2Ugbm8gdmFsaWQgRm9ybURhdGEgaW5zdGFuY2Ugd2FzIGdpdmVuLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgQWpheC5wb3N0Rm9ybURhdGEoXG4gICAgICAgICAgICAgICAgJy92YWxpZGF0aW9uL2Zvcm0vY2hlY2tvdXQnLFxuICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24oeGhyKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpc0Vycm9yUmVzcG9uc2UgPSBFcnJvclJlc3BvbnNlLmlzKHhoci5yZXNwb25zZSwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmKCFpc0Vycm9yUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvclJlc3BvbnNlLmZyb21Kc29uU3RyaW5nKHhoci5yZXNwb25zZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgeyBWYWxpZGF0aW9uU2VydmljZSB9IiwiLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICBZb3V0dWJlIGhhbmRsZXJcbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5jb25zdCBZb3V0dWJlSGFuZGxlciA9IHtcblxuICAgIHlvdXR1YmVDbGFzcyA6ICcuanMteW91dHViZS1wbGF5ZXInLFxuICAgIHBsYXllcnM6IFtdLFxuXG4gICAgaW5pdCA6IGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICAgIC8vIEdldCB0aGUgeW91dHViZSBwbGF5ZXJzIGNvbnRhaW5lcnNcbiAgICAgICAgY29uc3QgeW91dHViZVBsYXllcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFlvdXR1YmVIYW5kbGVyLnlvdXR1YmVDbGFzcyk7XG4gICAgICAgIGNvbnN0IHlvdXR1YmVQbGF5ZXJzQW1vdW50ID0geW91dHViZVBsYXllcnMubGVuZ3RoO1xuXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB5b3V0dWJlUGxheWVyc0Ftb3VudDsgaSsrKXtcblxuICAgICAgICAgICAgY29uc3QgeW91dHViZVBsYXllciA9IHlvdXR1YmVQbGF5ZXJzW2ldO1xuXG5cbiAgICAgICAgICAgIGNvbnN0IHlvdXR1YmVQbGF5ZXJJZCA9IHlvdXR1YmVQbGF5ZXIuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgICAgICAgICAgaWYoeW91dHViZVBsYXllcklkICE9PSBudWxsIClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAvLyBTdHJpcCB0aGUgbmVjZXNzYXJ5IGRhdGEgZnJvbSB0aGUgaHRtbCBhbmQgY3JlYXRlIG9iamVjdHMgZnJvbSBpdFxuICAgICAgICAgICAgICAgIGNvbnN0IHlvdXR1YmVFbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogeW91dHViZVBsYXllci5nZXRBdHRyaWJ1dGUoJ2lkJyksXG4gICAgICAgICAgICAgICAgICAgIGxpbms6IHlvdXR1YmVQbGF5ZXIuZ2V0QXR0cmlidXRlKCdkYXRhLXlvdXR1YmUtbGluaycpLFxuICAgICAgICAgICAgICAgICAgICBhdXRvUGxheTogcGFyc2VJbnQoeW91dHViZVBsYXllci5nZXRBdHRyaWJ1dGUoJ2RhdGEtYXV0by1wbGF5JykpLFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBZb3V0dWJlSGFuZGxlci5wbGF5ZXJzLnB1c2goeW91dHViZUVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZXtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkVsZW1lbnQgbm90IGluY2x1ZGUgYmVjYXVzZSB0aGVyZSBpc24ndCBhIGlkIG9uIHRoZSBwbGF5ZXJcIik7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coeW91dHViZVBsYXllcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZih5b3V0dWJlUGxheWVyc0Ftb3VudCA+PSAxKSBZb3V0dWJlSGFuZGxlci5pbml0WW91dHViZSgpO1xuXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGV4dGVybmFsIHNjcmlwdCBpcyBsb2FkZWRcbiAgICAgKlxuICAgICAqL1xuICAgIGluaXRZb3V0dWJlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gU2VlIGlmIFlUIHZhcmlhYmxlIGV4aXN0c1xuICAgICAgICBpZiAodHlwZW9mKFlUKSA9PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YoWVQuUGxheWVyKSA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gU2V0dXAgQVBJIHJlYWR5IGZ1bmN0aW9uXG4gICAgICAgICAgICB3aW5kb3cub25Zb3VUdWJlUGxheWVyQVBJUmVhZHkgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBZb3V0dWJlSGFuZGxlci5sb2FkUGxheWVycygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIExvYWQgZXh0ZXJuYWwgc2NyaXB0XG4gICAgICAgICAgICBnZXRTY3JpcHQoJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2lmcmFtZV9hcGknKTtcbiAgICAgICAgICAgIC8vIElmIFlUIGFscmVhZHkgZXhpc3RzIGxvYWQgcGxheWVyXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBZb3V0dWJlSGFuZGxlci5sb2FkUGxheWVycygpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB0aGUgWW91dHViZSBwbGF5ZXIocykgd2l0aCBwYXJhbWV0ZXJzXG4gICAgICogQW5kIHJld3JpdGUgdGhlIHBsYXllcnMgdG8ga2V5IHRoZW0gYnkgdGhlIGVsZW1lbnQgaWRcbiAgICAgKlxuICAgICAqL1xuICAgIGxvYWRQbGF5ZXJzOiBmdW5jdGlvbigpIHtcblxuICAgICAgICBsZXQgcGxheWVycyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IHlvdXR1YmVQbGF5ZXJzQW1vdW50ID0gWW91dHViZUhhbmRsZXIucGxheWVycy5sZW5ndGg7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB5b3V0dWJlUGxheWVyc0Ftb3VudDsgaSsrKXtcblxuICAgICAgICAgICAgbGV0IHlvdXR1YmVQbGF5ZXIgPSBZb3V0dWJlSGFuZGxlci5wbGF5ZXJzW2ldO1xuXG4gICAgICAgICAgICAvLyBMb2FkIHBsYXllclxuICAgICAgICAgICAgeW91dHViZVBsYXllci5wbGF5ZXIgPSBuZXcgWVQuUGxheWVyKHlvdXR1YmVQbGF5ZXIuaWQse1xuICAgICAgICAgICAgICAgIGhlaWdodDogMjAwLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAyMDAsXG4gICAgICAgICAgICAgICAgdmlkZW9JZDogeW91dHViZVBsYXllci5saW5rLFxuICAgICAgICAgICAgICAgIGhvc3Q6ICdodHRwczovL3d3dy55b3V0dWJlLW5vY29va2llLmNvbScsXG4gICAgICAgICAgICAgICAgcGxheWVyVmFyczoge1xuICAgICAgICAgICAgICAgICAgICBtb2Rlc3RicmFuZGluZzogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsOiAwLFxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxla2I6IDEsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9wbGF5OiB5b3V0dWJlUGxheWVyLmF1dG9QbGF5XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBldmVudHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gJ29uUmVhZHknOiBZb3V0dWJlSGFuZGxlci5vblJlYWR5LFxuICAgICAgICAgICAgICAgICAgICAnb25TdGF0ZUNoYW5nZSc6IFlvdXR1YmVIYW5kbGVyLm9uU3RhdGVDaGFuZ2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcGxheWVyc1t5b3V0dWJlUGxheWVyLmlkXSA9IHlvdXR1YmVQbGF5ZXI7XG5cbiAgICAgICAgfVxuXG4gICAgICAgIFlvdXR1YmVIYW5kbGVyLnBsYXllcnMgPSBwbGF5ZXJzO1xuXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdoZW4gcGxheWVyIGlzIHJlYWR5IHRvIHBsYXlcbiAgICAgKi9cbiAgICBvblJlYWR5IDogZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgICAgICBjb25zdCBwbGF5ZXJDb250YWluZXJJZCA9IGV2ZW50LnRhcmdldC5nZXRJZnJhbWUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICAgIGNvbnN0IHBsYXllciA9IFlvdXR1YmVIYW5kbGVyLnBsYXllcnNbcGxheWVyQ29udGFpbmVySWRdLnBsYXllcjtcblxuICAgICAgICAvLyBTaG93IHZpZGVvXG4gICAgICAgIC8vIHNldFRpbWVvdXQoZnVuY3Rpb24oKXsgJCgnIycgKyBwbGF5ZXJDb250YWluZXJJZCkuc3RvcCgpLmFuaW1hdGUoeyBvcGFjaXR5OiAxIH0sMTAwMCkgfSw4MDApO1xuXG4gICAgICAgIC8vIElmIG5vdCBvbiB0YWJsZXQgb3IgbW9iaWxlLCBwbGF5IG9uIGhpZ2ggcXVhbGl0eVxuICAgICAgICAvLyBwbGF5ZXIubXV0ZSgpO1xuICAgICAgICAvLyBwbGF5ZXIucGxheVZpZGVvKCk7XG4gICAgICAgIC8vIHBsYXllci5zZXRQbGF5YmFja1F1YWxpdHkoJ2hkMTA4MCcpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW5lciBmb3IgWW91dHViZSBzdGF0ZSBjaGFuZ2VcbiAgICAgKi9cbiAgICBvblN0YXRlQ2hhbmdlIDogZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgICAgICBjb25zdCBwbGF5ZXJDb250YWluZXJJZCA9IGV2ZW50LnRhcmdldC5nZXRJZnJhbWUoKS5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICAgIGNvbnN0IHBsYXllciA9IFlvdXR1YmVIYW5kbGVyLnBsYXllcnNbcGxheWVyQ29udGFpbmVySWRdLnBsYXllcjtcblxuICAgICAgICBjb25zdCB2aWRlb1N0YXRlID0gZXZlbnQuZGF0YTtcblxuICAgICAgICAvLyBMb29wIHZpZGVvXG4gICAgICAgIGlmIChldmVudC5kYXRhID09PSBZVC5QbGF5ZXJTdGF0ZS5FTkRFRCApIHtcbiAgICAgICAgICAgIHBsYXllci5wbGF5VmlkZW8oKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbllvdXR1YmVIYW5kbGVyLmluaXQoKTsiLCIvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgQnJvd3NlciBIYW5kbGVyXG4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuY29uc3QgQnJvd3NlckhhbmRsZXIgPSB7XG5cbiAgICB1c2VyQWdlbnQ6ICcnLFxuICAgIGJyb3dzZXJJbmZvOiAnJyxcblxuXG4gICAgaW5pdDogZnVuY3Rpb24gKCkge1xuICAgICAgICBCcm93c2VySGFuZGxlci51c2VyQWdlbnQgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgQnJvd3NlckhhbmRsZXIuYnJvd3NlckluZm8gPSBCcm93c2VySGFuZGxlci5nZXRCcm93c2VySW5mbygpO1xuICAgICAgICBCcm93c2VySGFuZGxlci5oYW5kbGVJRSgpO1xuICAgICAgICBCcm93c2VySGFuZGxlci5oYW5kbGVTYWZhcmkoKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlSUU6IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAvLyBEZXRlY3QgdmVyc2lvbnMgYmVsb3cgaWUxMVxuICAgICAgICBsZXQgbXNpZSA9IEJyb3dzZXJIYW5kbGVyLnVzZXJBZ2VudC5pbmRleE9mKCdNU0lFICcpO1xuICAgICAgICBjb25zdCBpZWx0MTEgPSBtc2llID4gMDtcblxuICAgICAgICAvLyBEZXRlY3QgaWUxMVxuICAgICAgICBjb25zdCBpZTExID0gISFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9UcmlkZW50LipydlxcOjExXFwuLyk7XG5cbiAgICAgICAgLy8gSWYgSW50ZXJuZXQgRXhwbG9yZXJcbiAgICAgICAgaWYgKGllbHQxMSB8fCBpZTExKSB7XG4gICAgICAgICAgICAvLyBEZWZhdWx0IHZlcnNpb25cbiAgICAgICAgICAgIGxldCB2ZXJzaW9uID0gJzExJztcblxuICAgICAgICAgICAgLy8gV2F5IHRvIGRldGVjdCB2ZXJzaW9uIDwgMTFcbiAgICAgICAgICAgIGlmIChpZWx0MTEpIHZlcnNpb24gPSBwYXJzZUludChCcm93c2VySGFuZGxlci51c2VyQWdlbnQuc3Vic3RyaW5nKFxuICAgICAgICAgICAgICAgIG1zaWUgKyA1LFxuICAgICAgICAgICAgICAgIEJyb3dzZXJIYW5kbGVyLnVzZXJBZ2VudC5pbmRleE9mKFwiLlwiLCBtc2llKVxuICAgICAgICAgICAgKSk7XG5cbiAgICAgICAgICAgIC8vIEFwcGVuZCBjbGFzc2VzIHRvIEhUTUwgKHdlIGhhdmUgdG8gZG8gdGhpcyBzZXBhcmF0ZWx5IGJlY2F1c2UgZWxzZSBpZSB3aWxsIGZhaWwpXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2llJyk7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ3YnK3ZlcnNpb24pO1xuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgLy8gRmFsbGJhY2sgZm9yIG9sZGVyIHNhZmFyaSB2ZXJzaW9uXG4gICAgaGFuZGxlU2FmYXJpOiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgaWYoQnJvd3NlckhhbmRsZXIuYnJvd3NlckluZm8ubmFtZSA9PT0gJ1NhZmFyaScgJiYgQnJvd3NlckhhbmRsZXIuYnJvd3NlckluZm8udmVyc2lvbiA8PSAxMCl7XG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaHRtbCcpWzBdLmNsYXNzTGlzdC5hZGQoJ2llJyk7XG4gICAgICAgIH1cblxuICAgIH0sXG5cbiAgICBnZXRCcm93c2VySW5mbzogZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgdWE9bmF2aWdhdG9yLnVzZXJBZ2VudCx0ZW0sTT11YS5tYXRjaCgvKG9wZXJhfGNocm9tZXxzYWZhcml8ZmlyZWZveHxtc2llfHRyaWRlbnQoPz1cXC8pKVxcLz9cXHMqKFxcZCspL2kpIHx8IFtdO1xuICAgICAgICBpZigvdHJpZGVudC9pLnRlc3QoTVsxXSkpe1xuICAgICAgICAgICAgdGVtPS9cXGJydlsgOl0rKFxcZCspL2cuZXhlYyh1YSkgfHwgW107XG4gICAgICAgICAgICByZXR1cm4ge25hbWU6J0lFICcsdmVyc2lvbjoodGVtWzFdfHwnJyl9O1xuICAgICAgICB9XG4gICAgICAgIGlmKE1bMV09PT0nQ2hyb21lJyl7XG4gICAgICAgICAgICB0ZW09dWEubWF0Y2goL1xcYk9QUlxcLyhcXGQrKS8pXG4gICAgICAgICAgICBpZih0ZW0hPW51bGwpICAge3JldHVybiB7bmFtZTonT3BlcmEnLCB2ZXJzaW9uOnRlbVsxXX07fVxuICAgICAgICB9XG4gICAgICAgIE09TVsyXT8gW01bMV0sIE1bMl1dOiBbbmF2aWdhdG9yLmFwcE5hbWUsIG5hdmlnYXRvci5hcHBWZXJzaW9uLCAnLT8nXTtcbiAgICAgICAgaWYoKHRlbT11YS5tYXRjaCgvdmVyc2lvblxcLyhcXGQrKS9pKSkhPW51bGwpIHtNLnNwbGljZSgxLDEsdGVtWzFdKTt9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lOiBNWzBdLFxuICAgICAgICAgICAgdmVyc2lvbjogTVsxXVxuICAgICAgICB9O1xuICAgIH1cbn07XG5cbkJyb3dzZXJIYW5kbGVyLmluaXQoKTsiLCIvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIEhlbHBlciBmdW5jdGlvbnNcbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKlxuICogU2ltcGxlIGlzc2V0IG1ldGhvZCBmb3IgdGhpcyBkb2VzIG5vdCBleGlzdCBpbiBqYXZhc2NyaXB0XG4gKi9cbndpbmRvdy5pc3NldCA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIG9iaiAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqICE9PSBudWxsO1xufTtcblxuLypcbiAqIEVhc2luZyBGdW5jdGlvbnMgLSBpbnNwaXJlZCBmcm9tIGh0dHA6Ly9naXptYS5jb20vZWFzaW5nL1xuICogb25seSBjb25zaWRlcmluZyB0aGUgdCB2YWx1ZSBmb3IgdGhlIHJhbmdlIFswLCAxXSA9PiBbMCwgMV1cbiAqL1xud2luZG93LkVhc2luZ0Z1bmN0aW9ucyA9IHtcbiAgICAvLyBubyBlYXNpbmcsIG5vIGFjY2VsZXJhdGlvblxuICAgIGxpbmVhcjogZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIHRcbiAgICB9LFxuICAgIC8vIGFjY2VsZXJhdGluZyBmcm9tIHplcm8gdmVsb2NpdHlcbiAgICBlYXNlSW5RdWFkOiBmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdCAqIHRcbiAgICB9LFxuICAgIC8vIGRlY2VsZXJhdGluZyB0byB6ZXJvIHZlbG9jaXR5XG4gICAgZWFzZU91dFF1YWQ6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0ICogKDIgLSB0KVxuICAgIH0sXG4gICAgLy8gYWNjZWxlcmF0aW9uIHVudGlsIGhhbGZ3YXksIHRoZW4gZGVjZWxlcmF0aW9uXG4gICAgZWFzZUluT3V0UXVhZDogZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIHQgPCAuNSA/IDIgKiB0ICogdCA6IC0xICsgKDQgLSAyICogdCkgKiB0XG4gICAgfSxcbiAgICAvLyBhY2NlbGVyYXRpbmcgZnJvbSB6ZXJvIHZlbG9jaXR5XG4gICAgZWFzZUluQ3ViaWM6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0ICogdCAqIHRcbiAgICB9LFxuICAgIC8vIGRlY2VsZXJhdGluZyB0byB6ZXJvIHZlbG9jaXR5XG4gICAgZWFzZU91dEN1YmljOiBmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gKC0tdCkgKiB0ICogdCArIDFcbiAgICB9LFxuICAgIC8vIGFjY2VsZXJhdGlvbiB1bnRpbCBoYWxmd2F5LCB0aGVuIGRlY2VsZXJhdGlvblxuICAgIGVhc2VJbk91dEN1YmljOiBmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdCA8IC41ID8gNCAqIHQgKiB0ICogdCA6ICh0IC0gMSkgKiAoMiAqIHQgLSAyKSAqICgyICogdCAtIDIpICsgMVxuICAgIH0sXG4gICAgLy8gYWNjZWxlcmF0aW5nIGZyb20gemVybyB2ZWxvY2l0eVxuICAgIGVhc2VJblF1YXJ0OiBmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdCAqIHQgKiB0ICogdFxuICAgIH0sXG4gICAgLy8gZGVjZWxlcmF0aW5nIHRvIHplcm8gdmVsb2NpdHlcbiAgICBlYXNlT3V0UXVhcnQ6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiAxIC0gKC0tdCkgKiB0ICogdCAqIHRcbiAgICB9LFxuICAgIC8vIGFjY2VsZXJhdGlvbiB1bnRpbCBoYWxmd2F5LCB0aGVuIGRlY2VsZXJhdGlvblxuICAgIGVhc2VJbk91dFF1YXJ0OiBmdW5jdGlvbiAodCkge1xuICAgICAgICByZXR1cm4gdCA8IC41ID8gOCAqIHQgKiB0ICogdCAqIHQgOiAxIC0gOCAqICgtLXQpICogdCAqIHQgKiB0XG4gICAgfSxcbiAgICAvLyBhY2NlbGVyYXRpbmcgZnJvbSB6ZXJvIHZlbG9jaXR5XG4gICAgZWFzZUluUXVpbnQ6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0ICogdCAqIHQgKiB0ICogdFxuICAgIH0sXG4gICAgLy8gZGVjZWxlcmF0aW5nIHRvIHplcm8gdmVsb2NpdHlcbiAgICBlYXNlT3V0UXVpbnQ6IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiAxICsgKC0tdCkgKiB0ICogdCAqIHQgKiB0XG4gICAgfSxcbiAgICAvLyBhY2NlbGVyYXRpb24gdW50aWwgaGFsZndheSwgdGhlbiBkZWNlbGVyYXRpb25cbiAgICBlYXNlSW5PdXRRdWludDogZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIHQgPCAuNSA/IDE2ICogdCAqIHQgKiB0ICogdCAqIHQgOiAxICsgMTYgKiAoLS10KSAqIHQgKiB0ICogdCAqIHRcbiAgICB9XG59O1xuXG4vKlxuICogVmFuaWxsYSB2ZXJzaW9uIG9mIHRoZSAkLmdldFNjcmlwdFxuICovXG53aW5kb3cuZ2V0U2NyaXB0ID0gZnVuY3Rpb24gKHNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICBsZXQgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgc2NyaXB0LmFzeW5jID0gMTtcblxuICAgIGNvbnN0IHNjcmlwdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG4gICAgbGV0IHByaW9yID0gc2NyaXB0c1tzY3JpcHRzLmxlbmd0aCAtIDFdO1xuXG4gICAgc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoXywgaXNBYm9ydCkge1xuICAgICAgICBpZiAoaXNBYm9ydCB8fCAhc2NyaXB0LnJlYWR5U3RhdGUgfHwgL2xvYWRlZHxjb21wbGV0ZS8udGVzdChzY3JpcHQucmVhZHlTdGF0ZSkpIHtcbiAgICAgICAgICAgIHNjcmlwdC5vbmxvYWQgPSBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgICAgIHNjcmlwdCA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgaWYgKCFpc0Fib3J0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIHNjcmlwdC5zcmMgPSBzb3VyY2U7XG4gICAgcHJpb3IucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2NyaXB0LCBwcmlvcik7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3RcbiAqIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3JcbiAqIE4gbWlsbGlzZWNvbmRzLiBJZiBgaW1tZWRpYXRlYCBpcyBwYXNzZWQsIHRyaWdnZXIgdGhlIGZ1bmN0aW9uIG9uIHRoZVxuICogbGVhZGluZyBlZGdlLCBpbnN0ZWFkIG9mIHRoZSB0cmFpbGluZy5cbiAqIEBwYXJhbSBmdW5jXG4gKiBAcGFyYW0gd2FpdFxuICogQHBhcmFtIGltbWVkaWF0ZVxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG53aW5kb3cuZGVib3VuY2UgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICBsZXQgdGltZW91dDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY29udGV4dCA9IHRoaXMsIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGxldCBsYXRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIH07XG4gICAgICAgIGxldCBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0KTtcbiAgICAgICAgaWYgKGNhbGxOb3cpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgfTtcbn07XG5cbi8qXG4gKiBDb29raWUgaGVscGVyIGNsYXNzXG4gKi9cbndpbmRvdy5Db29raWUgPSB7XG4gICAgc2V0OiBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIGRheXMpIHtcbiAgICAgICAgbGV0IGRvbWFpbiwgZG9tYWluUGFydHMsIGRhdGUsIGV4cGlyZXMsIGhvc3Q7XG5cbiAgICAgICAgaWYgKGRheXMpIHtcbiAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpICsgKGRheXMgKiAyNCAqIDYwICogNjAgKiAxMDAwKSk7XG4gICAgICAgICAgICBleHBpcmVzID0gXCI7IGV4cGlyZXM9XCIgKyBkYXRlLnRvR01UU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBleHBpcmVzID0gXCJcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIGhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuICAgICAgICBpZiAoaG9zdC5zcGxpdCgnLicpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gbm8gXCIuXCIgaW4gYSBkb21haW4gLSBpdCdzIGxvY2FsaG9zdCBvciBzb21ldGhpbmcgc2ltaWxhclxuICAgICAgICAgICAgZG9jdW1lbnQuY29va2llID0gbmFtZSArIFwiPVwiICsgdmFsdWUgKyBleHBpcmVzICsgXCI7IHBhdGg9L1wiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhlIGNvb2tpZSBvbiBhbGwgc3ViIGRvbWFpbnMuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gU3RhcnQgd2l0aCB0cnlpbmcgdG8gc2V0IGNvb2tpZSB0byB0aGUgdG9wIGRvbWFpbi5cbiAgICAgICAgICAgIC8vIChleGFtcGxlOiBpZiB1c2VyIGlzIG9uIGZvby5jb20sIHRyeSB0byBzZXRcbiAgICAgICAgICAgIC8vICBjb29raWUgdG8gZG9tYWluIFwiLmNvbVwiKVxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIElmIHRoZSBjb29raWUgd2lsbCBub3QgYmUgc2V0LCBpdCBtZWFucyBcIi5jb21cIlxuICAgICAgICAgICAgLy8gaXMgYSB0b3AgbGV2ZWwgZG9tYWluIGFuZCB3ZSBuZWVkIHRvXG4gICAgICAgICAgICAvLyBzZXQgdGhlIGNvb2tpZSB0byBcIi5mb28uY29tXCJcbiAgICAgICAgICAgIGRvbWFpblBhcnRzID0gaG9zdC5zcGxpdCgnLicpO1xuICAgICAgICAgICAgZG9tYWluUGFydHMuc2hpZnQoKTtcbiAgICAgICAgICAgIGRvbWFpbiA9ICcuJyArIGRvbWFpblBhcnRzLmpvaW4oJy4nKTtcblxuICAgICAgICAgICAgLy8gRm9yIGRldmVsb3BtZW50IHB1cnBvc2UsIHJlbW92ZSB0aGlzIHdoZW4gbW92aW5nIHRvIHByb2R1Y3Rpb25cbiAgICAgICAgICAgIC8vIGRvbWFpbiA9ICcua29tbWEucHJvJztcblxuICAgICAgICAgICAgZG9jdW1lbnQuY29va2llID0gbmFtZSArIFwiPVwiICsgdmFsdWUgKyBleHBpcmVzICsgXCI7IHBhdGg9LzsgZG9tYWluPVwiICsgZG9tYWluO1xuXG4gICAgICAgICAgICAvLyBjaGVjayBpZiBjb29raWUgd2FzIHN1Y2Nlc3NmdWx5IHNldCB0byB0aGUgZ2l2ZW4gZG9tYWluXG4gICAgICAgICAgICAvLyAob3RoZXJ3aXNlIGl0IHdhcyBhIFRvcC1MZXZlbCBEb21haW4pXG4gICAgICAgICAgICBpZiAoQ29va2llLmdldChuYW1lKSA9PSBudWxsIHx8IENvb2tpZS5nZXQobmFtZSkgIT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBhcHBlbmQgXCIuXCIgdG8gY3VycmVudCBkb21haW5cbiAgICAgICAgICAgICAgICBkb21haW4gPSAnLicgKyBob3N0O1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyBcIj1cIiArIHZhbHVlICsgZXhwaXJlcyArIFwiOyBwYXRoPS87IGRvbWFpbj1cIiArIGRvbWFpbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIGNvbnN0IG5hbWVFUSA9IG5hbWUgKyBcIj1cIjtcbiAgICAgICAgY29uc3QgY2EgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoJzsnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjYS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGMgPSBjYVtpXTtcbiAgICAgICAgICAgIHdoaWxlIChjLmNoYXJBdCgwKSA9PT0gJyAnKSB7XG4gICAgICAgICAgICAgICAgYyA9IGMuc3Vic3RyaW5nKDEsIGMubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGMuaW5kZXhPZihuYW1lRVEpID09PSAwKSByZXR1cm4gYy5zdWJzdHJpbmcobmFtZUVRLmxlbmd0aCwgYy5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG5cbiAgICBlcmFzZTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgQ29va2llLnNldChuYW1lLCAnJywgLTEpO1xuICAgIH1cbn07XG5cbi8qXG4gKiBKYXZhc2NyaXB0IHZlcnNpb24gb2YgdGhlIG51bWJlcl9mb3JtYXQgbWV0aG9kIG9mIFBIUFxuICovXG53aW5kb3cubnVtYmVyX2Zvcm1hdCA9IGZ1bmN0aW9uIChudW1iZXIsIGRlY2ltYWxzLCBkZWNfcG9pbnQsIHRob3VzYW5kc19zZXApIHtcbiAgICAvLyBTdHJpcCBhbGwgY2hhcmFjdGVycyBidXQgbnVtZXJpY2FsIG9uZXMuXG4gICAgbnVtYmVyID0gKG51bWJlciArICcnKS5yZXBsYWNlKC9bXjAtOStcXC1FZS5dL2csICcnKTtcbiAgICBsZXQgbiA9ICFpc0Zpbml0ZSgrbnVtYmVyKSA/IDAgOiArbnVtYmVyLFxuICAgICAgICBwcmVjID0gIWlzRmluaXRlKCtkZWNpbWFscykgPyAwIDogTWF0aC5hYnMoZGVjaW1hbHMpLFxuICAgICAgICBzZXAgPSAodHlwZW9mIHRob3VzYW5kc19zZXAgPT09ICd1bmRlZmluZWQnKSA/ICcsJyA6IHRob3VzYW5kc19zZXAsXG4gICAgICAgIGRlYyA9ICh0eXBlb2YgZGVjX3BvaW50ID09PSAndW5kZWZpbmVkJykgPyAnLicgOiBkZWNfcG9pbnQsXG4gICAgICAgIHMgPSAnJyxcbiAgICAgICAgdG9GaXhlZEZpeCA9IGZ1bmN0aW9uIChuLCBwcmVjKSB7XG4gICAgICAgICAgICB2YXIgayA9IE1hdGgucG93KDEwLCBwcmVjKTtcbiAgICAgICAgICAgIHJldHVybiAnJyArIE1hdGgucm91bmQobiAqIGspIC8gaztcbiAgICAgICAgfTtcbiAgICAvLyBGaXggZm9yIElFIHBhcnNlRmxvYXQoMC41NSkudG9GaXhlZCgwKSA9IDA7XG4gICAgcyA9IChwcmVjID8gdG9GaXhlZEZpeChuLCBwcmVjKSA6ICcnICsgTWF0aC5yb3VuZChuKSkuc3BsaXQoJy4nKTtcbiAgICBpZiAoc1swXS5sZW5ndGggPiAzKSB7XG4gICAgICAgIHNbMF0gPSBzWzBdLnJlcGxhY2UoL1xcQig/PSg/OlxcZHszfSkrKD8hXFxkKSkvZywgc2VwKTtcbiAgICB9XG4gICAgaWYgKChzWzFdIHx8ICcnKS5sZW5ndGggPCBwcmVjKSB7XG4gICAgICAgIHNbMV0gPSBzWzFdIHx8ICcnO1xuICAgICAgICBzWzFdICs9IG5ldyBBcnJheShwcmVjIC0gc1sxXS5sZW5ndGggKyAxKS5qb2luKCcwJyk7XG4gICAgfVxuICAgIHJldHVybiBzLmpvaW4oZGVjKTtcbn07XG5cblxuLyoqXG4gKiBFbGVtZW50LmNsb3Nlc3QoKSBwb2x5ZmlsbFxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnQvY2xvc2VzdCNQb2x5ZmlsbFxuICovXG5pZiAoIUVsZW1lbnQucHJvdG90eXBlLmNsb3Nlc3QpIHtcbiAgICBpZiAoIUVsZW1lbnQucHJvdG90eXBlLm1hdGNoZXMpIHtcbiAgICAgICAgRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcyA9IEVsZW1lbnQucHJvdG90eXBlLm1zTWF0Y2hlc1NlbGVjdG9yIHx8IEVsZW1lbnQucHJvdG90eXBlLndlYmtpdE1hdGNoZXNTZWxlY3RvcjtcbiAgICB9XG4gICAgRWxlbWVudC5wcm90b3R5cGUuY2xvc2VzdCA9IGZ1bmN0aW9uIChzKSB7XG4gICAgICAgIHZhciBlbCA9IHRoaXM7XG4gICAgICAgIHZhciBhbmNlc3RvciA9IHRoaXM7XG4gICAgICAgIGlmICghZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNvbnRhaW5zKGVsKSkgcmV0dXJuIG51bGw7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGlmIChhbmNlc3Rvci5tYXRjaGVzKHMpKSByZXR1cm4gYW5jZXN0b3I7XG4gICAgICAgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgIH0gd2hpbGUgKGFuY2VzdG9yICE9PSBudWxsKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbn1cblxud2luZG93LkFqYXggPSB7XG5cbiAgICAvL1RPRE86IENhbiB3ZSBjcmVhdGUgYSBwcmVwYXJlIHJlcXVlc3QgZnVuY3Rpb24gPz9cblxuICAgIGdldDogZnVuY3Rpb24odXJsLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIGxldCB0b2tlbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5jb250ZW50O1xuXG4gICAgICAgIHhoci5vcGVuKCdnZXQnLCB1cmwsIHRydWUpO1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtQ1NSRi1UT0tFTicsIHRva2VuKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKTtcbiAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soeGhyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgeGhyLnNlbmQoKTtcbiAgICB9LFxuXG4gICAgcG9zdDogZnVuY3Rpb24odXJsLCBkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIGxldCB0b2tlbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5jb250ZW50O1xuXG4gICAgICAgIHhoci5vcGVuKCdwb3N0JywgdXJsLCB0cnVlKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLUNTUkYtVE9LRU4nLCB0b2tlbik7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0Jyk7XG4gICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHhocik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHhoci5zZW5kKCBKU09OLnN0cmluZ2lmeShkYXRhKSk7XG4gICAgfSxcblxuICAgIHBvc3RGb3JtRGF0YTogZnVuY3Rpb24odXJsLCBkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIGxldCB0b2tlbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5jb250ZW50O1xuXG4gICAgICAgIHhoci5vcGVuKCdwb3N0JywgdXJsLCB0cnVlKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtQ1NSRi1UT0tFTicsIHRva2VuKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKTtcbiAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soeGhyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgeGhyLnNlbmQoZGF0YSk7XG4gICAgfVxufTtcblxuLyoqXG4gKiBDYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgb2YgdGhlIHN0cmluZ1xuICogQHBhcmFtIHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xud2luZG93LmNhcGl0YWxpemVGaXJzdExldHRlciA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyaW5nLnNsaWNlKDEpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0IHNuYWtlIGNhc2UgaW50byBjYW1lbGNhc2VcbiAqXG4gKiBAcGFyYW0gc3RyaW5nXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xud2luZG93LnNuYWtlVG9DYW1lbCA9IGZ1bmN0aW9uIChzdHJpbmcpe1xuICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSgvKFxcLVxcdykvZywgZnVuY3Rpb24obSl7cmV0dXJuIG1bMV0udG9VcHBlckNhc2UoKTt9KTtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBpbmRleCBvZiBhbiBlbGVtZW50IGluc2lkZSBpdHMgcGFyZW50XG4gKi9cbndpbmRvdy5pbmRleEluUGFyZW50PSBmdW5jdGlvbiAobm9kZSkge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gbm9kZS5wYXJlbnROb2RlLmNoaWxkTm9kZXM7XG4gICAgbGV0IG51bSA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoY2hpbGRyZW5baV0gPT0gbm9kZSkgcmV0dXJuIG51bTtcbiAgICAgICAgaWYgKGNoaWxkcmVuW2ldLm5vZGVUeXBlID09IDEpIG51bSsrO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG59O1xuXG4vKipcbiAqIEZvciBzZWN1cml0eSByZWFzb25zIGlPUyBTYWZhcmkgb25seSBhbGxvd3MgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKSBmb3IgdGV4dCB3aXRoaW4gYSBjb250ZW50RWRpdGFibGUgY29udGFpbmVyLlxuICogVGhlIHdvcmthcm91bmQgaXMgdG8gZGV0ZWN0IGlPUyBTYWZhcmkgYW5kIHF1aWNrbHkgdG9nZ2xlIGNvbnRlbnRFZGl0YWJsZSBiZWZvcmUgZXhlY3V0aW5nIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5JykuXG4gKiBXaGViIGlucHV0IG9yIHRleHRhcmVhIGlzIFJFQURPTkxZIHlvdSBjYW4gcHJldmVudCB0aGUgdW53YW50ZWQgcG9wdXAgd2l0aCBjb3B5L3Bhc3RlIGZ1bmN0aW9ucyBhbmQgdGhlIGlucHV0IGtleWJvYXJkXG4gKiBDb2RlIGZyb206IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80Njk4MTg0N1xuICovXG53aW5kb3cuY29weVRvQ2xpcGJvYXJkID0gZnVuY3Rpb24gKGVsKSB7XG5cbiAgICAvLyByZXNvbHZlIHRoZSBlbGVtZW50XG4gICAgZWwgPSAodHlwZW9mIGVsID09PSAnc3RyaW5nJykgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKSA6IGVsO1xuXG4gICAgLy8gaGFuZGxlIGlPUyBhcyBhIHNwZWNpYWwgY2FzZVxuICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pcGFkfGlwb2R8aXBob25lL2kpKSB7XG5cbiAgICAgICAgLy8gc2F2ZSBjdXJyZW50IGNvbnRlbnRFZGl0YWJsZS9yZWFkT25seSBzdGF0dXNcbiAgICAgICAgY29uc3QgZWRpdGFibGUgPSBlbC5jb250ZW50RWRpdGFibGU7XG4gICAgICAgIGNvbnN0IHJlYWRPbmx5ID0gZWwucmVhZE9ubHk7XG5cbiAgICAgICAgLy8gY29udmVydCB0byBlZGl0YWJsZSB3aXRoIHJlYWRvbmx5IHRvIHN0b3AgaU9TIGtleWJvYXJkIG9wZW5pbmdcbiAgICAgICAgZWwuY29udGVudEVkaXRhYmxlID0gdHJ1ZTtcbiAgICAgICAgZWwucmVhZE9ubHkgPSB0cnVlO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHNlbGVjdGFibGUgcmFuZ2VcbiAgICAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGVsKTtcblxuICAgICAgICAvLyBzZWxlY3QgdGhlIHJhbmdlXG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICAgICAgICBlbC5zZXRTZWxlY3Rpb25SYW5nZSgwLCA5OTk5OTkpO1xuXG4gICAgICAgIC8vIHJlc3RvcmUgY29udGVudEVkaXRhYmxlL3JlYWRPbmx5IHRvIG9yaWdpbmFsIHN0YXRlXG4gICAgICAgIGVsLmNvbnRlbnRFZGl0YWJsZSA9IGVkaXRhYmxlO1xuICAgICAgICBlbC5yZWFkT25seSA9IHJlYWRPbmx5O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZWwuc2VsZWN0KCk7XG4gICAgfVxuXG4gICAgLy8gZXhlY3V0ZSBjb3B5IGNvbW1hbmRcbiAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50IHJlbGF0ZWQgdG8gdGhlIGJvZHlcbiAqXG4gKiBAcGFyYW0gZWxcbiAqIEByZXR1cm5zIHt7dG9wOiBudW1iZXIsIGxlZnQ6IG51bWJlcn19XG4gKi9cbndpbmRvdy5ib2R5T2Zmc2V0ID0gZnVuY3Rpb24gKGVsKSB7XG4gICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICBzY3JvbGxMZWZ0ID0gd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgICAgICBzY3JvbGxUb3AgPSB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDtcbiAgICByZXR1cm4geyB0b3A6IHJlY3QudG9wICsgc2Nyb2xsVG9wLCBsZWZ0OiByZWN0LmxlZnQgKyBzY3JvbGxMZWZ0IH1cbn07IiwiLyoqXG4gKiBDb3VudHJ5TGFuZ3VhZ2VzUmVzcG9uc2UuXG4gKlxuICogUmVwcmVzZW50cyBhIHJlc3BvbnNlIHRoYXQgb3JpZ2luYXRlcyBmcm9tXG4gKi9cbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSBcIi4vbGFuZ3VhZ2VcIjtcblxuY2xhc3MgQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIHtcbiAgICBjb25zdHJ1Y3RvcigpXG4gICAge1xuICAgICAgICB0aGlzLl9sYW5ndWFnZXMgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ganNvblxuICAgICAqIEByZXR1cm4ge0NvdW50cnlMYW5ndWFnZXNSZXNwb25zZXxudWxsfVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tSnNvblN0cmluZyhqc29uKSB7XG4gICAgICAgIGlmKCF0aGlzLmlzKGpzb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQganNvbk9iamVjdCA9IEpTT04ucGFyc2UoanNvbik7XG5cbiAgICAgICAgbGV0IGluc3RhbmNlID0gbmV3IHRoaXM7XG4gICAgICAgIGxldCBsYW5ndWFnZUNvdW50ID0ganNvbk9iamVjdC5sYW5ndWFnZXMubGVuZ3RoO1xuICAgICAgICBmb3IobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsYW5ndWFnZUNvdW50OyBpbmRleCsrKVxuICAgICAgICB7XG4gICAgICAgICAgICBsZXQgbGFuZ3VhZ2VPYmplY3QgPSBqc29uT2JqZWN0Lmxhbmd1YWdlc1tpbmRleF07XG4gICAgICAgICAgICBsZXQgbGFuZ3VhZ2UgPSBuZXcgTGFuZ3VhZ2UoKTtcbiAgICAgICAgICAgIGxhbmd1YWdlLm5hbWUgPSBsYW5ndWFnZU9iamVjdC5uYW1lO1xuICAgICAgICAgICAgbGFuZ3VhZ2UuZGlzcGxheU5hbWUgPSBsYW5ndWFnZU9iamVjdC5kaXNwbGF5TmFtZTtcbiAgICAgICAgICAgIGxhbmd1YWdlLm5hdGl2ZU5hbWUgPSBsYW5ndWFnZU9iamVjdC5uYXRpdmVOYW1lO1xuICAgICAgICAgICAgbGFuZ3VhZ2UudHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lID0gbGFuZ3VhZ2VPYmplY3QudHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lO1xuICAgICAgICAgICAgbGFuZ3VhZ2UudGhyZWVMZXR0ZXJJc29MYW5ndWFnZU5hbWUgPSBsYW5ndWFnZU9iamVjdC50aHJlZUxldHRlcklzb0xhbmd1YWdlTmFtZTtcblxuICAgICAgICAgICAgaW5zdGFuY2UuX2xhbmd1YWdlcy5wdXNoKGxhbmd1YWdlKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB0aGF0IHRoZSBnaXZlbiBqc29uIHN0cmluZyByZXByZXNlbnRzIGEgRXJyb3JSZXNwb25zZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxvZ0Vycm9yc1xuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgc3RhdGljIGlzKGpzb24sIGxvZ0Vycm9ycyA9IHRydWUpXG4gICAge1xuICAgICAgICBsZXQganNvbk9iamVjdCA9IG51bGw7XG5cbiAgICAgICAgaWYodHlwZW9mIGpzb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGpzb25PYmplY3QgPSBKU09OLnBhcnNlKGpzb24pO1xuICAgICAgICAgICAgICAgIGlmICghanNvbk9iamVjdCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0NvdW50cnlMYW5ndWFnZXNSZXNwb25zZTogVGhlIGdpdmVuIGpzb24gZG9lcyBub3QgcmVwcmVzZW50IGEgQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIHNpbmNlIHRoZSBqc29uIHN0cmluZyB3YXMgbm90IGEgdmFsaWQganNvbi4gT2JqZWN0OiAnLCBqc29uT2JqZWN0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBqc29uT2JqZWN0ID0ganNvblxuICAgICAgICB9XG5cbiAgICAgICAgaWYoIWpzb25PYmplY3QuaGFzT3duUHJvcGVydHkoJ2xhbmd1YWdlcycpIHx8ICFBcnJheS5pc0FycmF5KGpzb25PYmplY3QubGFuZ3VhZ2VzKSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ0NvdW50cnlMYW5ndWFnZXNSZXNwb25zZTogVGhlIGdpdmVuIGpzb24gbXVzdCBoYXZlIGEgcHJvcGVydHkgY2FsbGVkIGxhbmd1YWdlcyB0aGF0IGlzIGFuIEFycmF5LCBCdXQgZGlkIG5vdCBoYXZlLiBPYmplY3Q6ICcsIGpzb25PYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxhbmd1YWdlQ291bnQgPSBqc29uT2JqZWN0Lmxhbmd1YWdlcy5sZW5ndGg7XG4gICAgICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxhbmd1YWdlQ291bnQ7IGluZGV4KyspXG4gICAgICAgIHtcbiAgICAgICAgICAgIGxldCBsYW5ndWFnZU9iamVjdCA9IGpzb25PYmplY3QubGFuZ3VhZ2VzW2luZGV4XTtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBsYW5ndWFnZU9iamVjdCAhPT0gJ29iamVjdCcgfHwgdHlwZW9mIGxhbmd1YWdlT2JqZWN0ID09PSAnZnVuY3Rpb24nIHx8ICFMYW5ndWFnZS5pcyhsYW5ndWFnZU9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3t2YWxpZDogYm9vbGVhbiwgZXJyb3JzOiBBcnJheX19XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdG9Kc29uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ2xhbmd1YWdlcyc6IHRoaXMuX2xhbmd1YWdlc1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGFuZ3VhZ2VbXX1cbiAgICAgKi9cbiAgICBnZXQgbGFuZ3VhZ2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGFuZ3VhZ2VzO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQ291bnRyeUxhbmd1YWdlc1Jlc3BvbnNlIH0iLCIvKipcbiAqIEEgbGFyYXZlbCBlcnJvciByZXNwb25zZVxuICovXG5jbGFzcyBFcnJvclJlc3BvbnNlIHtcbiAgICBjb25zdHJ1Y3RvcigpXG4gICAge1xuICAgICAgICB0aGlzLl9tZXNzYWdlID0gJyc7XG4gICAgICAgIHRoaXMuX2Vycm9ycyA9IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBqc29uXG4gICAgICogQHJldHVybiB7RXJyb3JSZXNwb25zZXxudWxsfVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tSnNvblN0cmluZyhqc29uKSB7XG4gICAgICAgIGlmKCF0aGlzLmlzKGpzb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQganNvbk9iamVjdCA9IEpTT04ucGFyc2UoanNvbik7XG5cbiAgICAgICAgbGV0IGluc3RhbmNlID0gbmV3IHRoaXM7XG4gICAgICAgIGluc3RhbmNlLl9tZXNzYWdlID0ganNvbk9iamVjdC5tZXNzYWdlO1xuICAgICAgICBpbnN0YW5jZS5fZXJyb3JzID0ganNvbk9iamVjdC5lcnJvcnM7XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB0aGF0IHRoZSBnaXZlbiBqc29uIHN0cmluZyByZXByZXNlbnRzIGEgRXJyb3JSZXNwb25zZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxvZ0Vycm9yc1xuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgc3RhdGljIGlzKGpzb24sIGxvZ0Vycm9ycyA9IHRydWUpXG4gICAge1xuICAgICAgICBsZXQganNvbk9iamVjdCA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBqc29uT2JqZWN0ID0gSlNPTi5wYXJzZShqc29uKTtcbiAgICAgICAgICAgIGlmKCFqc29uT2JqZWN0KSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmKGxvZ0Vycm9ycykgY29uc29sZS5lcnJvcignRXJyb3JSZXNwb25zZTogVGhlIGdpdmVuIGpzb24gZG9lcyBub3QgcmVwcmVzZW50IGEgdmFsaWQgRXJyb3JSZXNwb25zZSBzaW5jZSB0aGUganNvbiBzdHJpbmcgd2FzIG5vdCBhIHZhbGlkIGpzb24nKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFqc29uT2JqZWN0Lmhhc093blByb3BlcnR5KCdtZXNzYWdlJykgfHwgdHlwZW9mIGpzb25PYmplY3QubWVzc2FnZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmKGxvZ0Vycm9ycykgY29uc29sZS5lcnJvcignRXJyb3JSZXNwb25zZTogVGhlIHJlc3BvbnNlIG9iamVjdCBtdXN0IGhhdmUgYW4gbWVzc2FnZSBwcm9wZXJ0eSB0aGF0IGlzIGEgc3RyaW5nLiBPYmplY3Q6JywganNvbk9iamVjdCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZighanNvbk9iamVjdC5oYXNPd25Qcm9wZXJ0eSgnZXJyb3JzJykgfHwgdHlwZW9mIGpzb25PYmplY3QuZXJyb3JzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYobG9nRXJyb3JzKSBjb25zb2xlLmVycm9yKCdFcnJvclJlc3BvbnNlOiBUaGUgcmVzcG9uc2Ugb2JqZWN0IG11c3QgaGF2ZSBhbiBlcnJvcnMgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB2YWxpZCBsYXJhdmVsIGZpZWxkIGVycm9ycy4gT2JqZWN0OicsIGpzb25PYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yKGxldCBmaWVsZE5hbWUgaW4ganNvbk9iamVjdC5lcnJvcnMpIHtcbiAgICAgICAgICAgIGlmKGpzb25PYmplY3QuZXJyb3JzLmhhc093blByb3BlcnR5KGZpZWxkTmFtZSkgJiYgIUFycmF5LmlzQXJyYXkoanNvbk9iamVjdC5lcnJvcnNbZmllbGROYW1lXSkpIHtcbiAgICAgICAgICAgICAgICBpZihsb2dFcnJvcnMpIGNvbnNvbGUuZXJyb3IoJ0Vycm9yUmVzcG9uc2U6IFRoZSBwcm9wZXJ0eSBcIicrZmllbGROYW1lKydcIiBpbiB0aGUgZXJyb3JzIGFycmF5IG11c3QgaGF2ZSBoYXZlIGFycmF5IGFzIHZhbHVlIGNvbnRhaW5pbmcgZXJyb3JzIHN0cmluZ3MuIE9iamVjdDonLCBqc29uT2JqZWN0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXRydXJucyBhIGNvbXByZWhlbnNpdmUgZXJyb3IgbWVzc2FnZSBmb3IgYWxsIHRoZSBmaWVsZHMuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0IG1lc3NhZ2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZXNzYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gcmV0dXJucyBhbiBvYmplY3Qgd2hlcmUgdGhlIHByb3BlcnR5IGFyZSBmaWVsZCBuYW1lcy4gYW5kIHRoZSB2YWx1ZXMgYXJlIGFycmF5cyBjb250YWluaW5nIGVycm9ycyBmb3IgdGhvc2UgZmllbGQgbmFtZXMuXG4gICAgICovXG4gICAgZ2V0IGVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9ycztcbiAgICB9XG59XG5cbmV4cG9ydCB7IEVycm9yUmVzcG9uc2UgfSIsIi8qKlxuICogTGFuZ3VhZ2UuXG4gKlxuICogUmVwcmVzZW50cyBhIExhbmd1YWdlXG4gKi9cbmNsYXNzIExhbmd1YWdlIHtcbiAgICBjb25zdHJ1Y3RvcigpXG4gICAge1xuICAgICAgICB0aGlzLl9uYW1lID0gJyc7XG4gICAgICAgIHRoaXMuX2Rpc3BsYXlOYW1lID0gJyc7XG4gICAgICAgIHRoaXMuX25hdGl2ZU5hbWUgPSAnJztcbiAgICAgICAgdGhpcy5fdHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lID0gJyc7XG4gICAgICAgIHRoaXMuX3RocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lID0gJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcmV0dXJuIHtMYW5ndWFnZXxudWxsfVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tSnNvblN0cmluZyhqc29uKSB7XG4gICAgICAgIGlmKCF0aGlzLmlzKGpzb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQganNvbk9iamVjdCA9IEpTT04ucGFyc2UoanNvbik7XG5cbiAgICAgICAgbGV0IGluc3RhbmNlID0gbmV3IHRoaXM7XG4gICAgICAgIGluc3RhbmNlLl9uYW1lID0ganNvbk9iamVjdC5uYW1lO1xuICAgICAgICBpbnN0YW5jZS5fZGlzcGxheU5hbWUgPSBqc29uT2JqZWN0LmRpc3BsYXlOYW1lO1xuICAgICAgICBpbnN0YW5jZS5fbmF0aXZlTmFtZSA9IGpzb25PYmplY3QubmF0aXZlTmFtZTtcbiAgICAgICAgaW5zdGFuY2UuX3R3b0xldHRlcklzb0xhbmd1YWdlTmFtZSA9IGpzb25PYmplY3QudHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lO1xuICAgICAgICBpbnN0YW5jZS5fdGhyZWVMZXR0ZXJJc29MYW5ndWFnZU5hbWUgPSBqc29uT2JqZWN0LnRocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lO1xuXG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgdGhhdCB0aGUgZ2l2ZW4ganNvbiBzdHJpbmcgcmVwcmVzZW50cyBhIEVycm9yUmVzcG9uc2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0ganNvblxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbG9nRXJyb3JzXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzdGF0aWMgaXMoanNvbiwgbG9nRXJyb3JzID0gdHJ1ZSlcbiAgICB7XG4gICAgICAgIGxldCBqc29uT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgXG4gICAgICAgIGlmKHR5cGVvZiBqc29uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBqc29uT2JqZWN0ID0gSlNPTi5wYXJzZShqc29uKTtcbiAgICAgICAgICAgICAgICBpZiAoIWpzb25PYmplY3QpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdMYW5ndWFnZTogVGhlIGdpdmVuIGpzb24gZG9lcyBub3QgcmVwcmVzZW50IGEgTGFuZ3VhZ2Ugc2luY2UgdGhlIGpzb24gc3RyaW5nIHdhcyBub3QgYSB2YWxpZCBqc29uLiBPYmplY3Q6ICcsIGpzb25PYmplY3QsIGpzb24pO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpzb25PYmplY3QgPSBqc29uXG4gICAgICAgIH1cblxuICAgICAgICBpZighanNvbk9iamVjdC5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpIHx8IHR5cGVvZiBqc29uT2JqZWN0LmRpc3BsYXlOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWYobG9nRXJyb3JzKSBjb25zb2xlLmVycm9yKCdMYW5ndWFnZTogVGhlIGxhbmd1YWdlIG9iamVjdCBtdXN0IGhhdmUgYSBwcm9wZXJ0eSBjYWxsZWQgbmFtZSB0aGF0IGlzIGEgc3RyaW5nLiBPYmplY3Q6ICcsIGpzb25PYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmKCFqc29uT2JqZWN0Lmhhc093blByb3BlcnR5KCdkaXNwbGF5TmFtZScpIHx8IHR5cGVvZiBqc29uT2JqZWN0LmRpc3BsYXlOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWYobG9nRXJyb3JzKSBjb25zb2xlLmVycm9yKCdMYW5ndWFnZTogVGhlIGxhbmd1YWdlIG9iamVjdCBtdXN0IGhhdmUgYSBwcm9wZXJ0eSBjYWxsZWQgZGlzcGxheU5hbWUgdGhhdCBpcyBhIHN0cmluZy4gT2JqZWN0OiAnLCBqc29uT2JqZWN0KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZighanNvbk9iamVjdC5oYXNPd25Qcm9wZXJ0eSgnbmF0aXZlTmFtZScpIHx8IHR5cGVvZiBqc29uT2JqZWN0Lm5hdGl2ZU5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZihsb2dFcnJvcnMpIGNvbnNvbGUuZXJyb3IoJ0xhbmd1YWdlOiBUaGUgbGFuZ3VhZ2Ugb2JqZWN0IG11c3QgaGF2ZSBhIHByb3BlcnR5IGNhbGxlZCBuYXRpdmVOYW1lIHRoYXQgaXMgYSBzdHJpbmcuIE9iamVjdDogJywganNvbk9iamVjdCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYoIWpzb25PYmplY3QuaGFzT3duUHJvcGVydHkoJ3R3b0xldHRlcklzb0xhbmd1YWdlTmFtZScpIHx8IHR5cGVvZiBqc29uT2JqZWN0LnR3b0xldHRlcklzb0xhbmd1YWdlTmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmKGxvZ0Vycm9ycykgY29uc29sZS5lcnJvcignTGFuZ3VhZ2U6IFRoZSBsYW5ndWFnZSBvYmplY3QgbXVzdCBoYXZlIGEgcHJvcGVydHkgY2FsbGVkIHR3b0xldHRlcklzb0xhbmd1YWdlTmFtZSB0aGF0IGlzIGEgc3RyaW5nLiBPYmplY3Q6ICcsIGpzb25PYmplY3QudHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZighanNvbk9iamVjdC5oYXNPd25Qcm9wZXJ0eSgndGhyZWVMZXR0ZXJJc29MYW5ndWFnZU5hbWUnKSB8fCB0eXBlb2YganNvbk9iamVjdC50aHJlZUxldHRlcklzb0xhbmd1YWdlTmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmKGxvZ0Vycm9ycykgY29uc29sZS5lcnJvcignTGFuZ3VhZ2U6IFRoZSBsYW5ndWFnZSBvYmplY3QgbXVzdCBoYXZlIGEgcHJvcGVydHkgY2FsbGVkIHRocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lIHRoYXQgaXMgYSBzdHJpbmcuIE9iamVjdDogJywganNvbk9iamVjdCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge3t2YWxpZDogYm9vbGVhbiwgZXJyb3JzOiBBcnJheX19XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdG9Kc29uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ25hbWUnOiB0aGlzLl9uYW1lLFxuICAgICAgICAgICAgJ2Rpc3BsYXlOYW1lJzogdGhpcy5fZGlzcGxheU5hbWUsXG4gICAgICAgICAgICAnbmF0aXZlTmFtZSc6IHRoaXMuX25hdGl2ZU5hbWUsXG4gICAgICAgICAgICAndHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lJzogdGhpcy5fdHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lLFxuICAgICAgICAgICAgJ3RocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lJzogdGhpcy5fdGhyZWVMZXR0ZXJJc29MYW5ndWFnZU5hbWVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmFtZTtcbiAgICB9XG5cbiAgICBzZXQgbmFtZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9uYW1lID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IGRpc3BsYXlOYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzcGxheU5hbWU7XG4gICAgfVxuXG4gICAgc2V0IGRpc3BsYXlOYW1lKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2Rpc3BsYXlOYW1lID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IG5hdGl2ZU5hbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVOYW1lO1xuICAgIH1cblxuICAgIHNldCBuYXRpdmVOYW1lKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX25hdGl2ZU5hbWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBnZXQgdHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lO1xuICAgIH1cblxuICAgIHNldCB0d29MZXR0ZXJJc29MYW5ndWFnZU5hbWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fdHdvTGV0dGVySXNvTGFuZ3VhZ2VOYW1lID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IHRocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGhyZWVMZXR0ZXJJc29MYW5ndWFnZU5hbWU7XG4gICAgfVxuXG4gICAgc2V0IHRocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX3RocmVlTGV0dGVySXNvTGFuZ3VhZ2VOYW1lID0gdmFsdWU7XG4gICAgfVxufVxuXG5leHBvcnQgeyBMYW5ndWFnZSB9IiwiLyoqXG4gKiBWYWxpZGF0aW9uUmVzcG9uc2UuXG4gKlxuICogUmVwcmVzZW50cyBhIHJlc3BvbnNlIHRoYXQgb3JpZ2luYXRlcyBmcm9tXG4gKi9cbmNsYXNzIFZhbGlkYXRpb25SZXNwb25zZSB7XG4gICAgY29uc3RydWN0b3IoKVxuICAgIHtcbiAgICAgICAgdGhpcy5fdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZXJyb3JzID0gW107XG4gICAgICAgIHRoaXMudG9KU09OID0gdGhpcy5fdG9Kc29uLmJpbmQodGhpcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcmV0dXJuIHtWYWxpZGF0aW9uUmVzcG9uc2V8bnVsbH1cbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUpzb25TdHJpbmcoanNvbikge1xuICAgICAgICBpZighdGhpcy5pcyhqc29uKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGpzb25PYmplY3QgPSBKU09OLnBhcnNlKGpzb24pO1xuXG4gICAgICAgIGxldCBpbnN0YW5jZSA9IG5ldyB0aGlzO1xuICAgICAgICBpbnN0YW5jZS5fdmFsaWQgPSBqc29uT2JqZWN0LnZhbGlkO1xuICAgICAgICBpbnN0YW5jZS5fZXJyb3JzID0ganNvbk9iamVjdC5lcnJvcnM7XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB0aGF0IHRoZSBnaXZlbiBqc29uIHN0cmluZyByZXByZXNlbnRzIGEgRXJyb3JSZXNwb25zZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGpzb25cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxvZ0Vycm9yc1xuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgc3RhdGljIGlzKGpzb24sIGxvZ0Vycm9ycyA9IHRydWUpXG4gICAge1xuICAgICAgICBsZXQganNvbk9iamVjdCA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBqc29uT2JqZWN0ID0gSlNPTi5wYXJzZShqc29uKTtcbiAgICAgICAgICAgIGlmKCFqc29uT2JqZWN0KSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1ZhbGlkYXRpb25SZXNwb25zZTogVGhlIGdpdmVuIGpzb24gZG9lcyBub3QgcmVwcmVzZW50IGEgVmFsaWRhdGlvblJlc3BvbnNlIHNpbmNlIHRoZSBqc29uIHN0cmluZyB3YXMgbm90IGEgdmFsaWQganNvbi4gT2JqZWN0OiAnLCBqc29uT2JqZWN0KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFqc29uT2JqZWN0Lmhhc093blByb3BlcnR5KCd2YWxpZCcpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdWYWxpZGF0aW9uUmVzcG9uc2U6IFRoZSBnaXZlbiBqc29uIG9iamVjdCBtdXN0IGhhdmUgYW4gXCJ2YWxpZFwiIHByb3BlcnR5IHRoYXQgaXMgYSBzdHJpbmcuIEJ1dCBkaWQgbm90IGhhdmUgb25lLiBPYmplY3Q6ICcsIGpzb25PYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoIWpzb25PYmplY3QuaGFzT3duUHJvcGVydHkoJ2Vycm9ycycpIHx8IHR5cGVvZiAhanNvbk9iamVjdC5lcnJvcnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1ZhbGlkYXRpb25SZXNwb25zZTogVGhlIGdpdmVuIGpzb24gb2JqZWN0IG11c3QgaGF2ZSBhbiBlcnJvcnMgb2JqZWN0LiBCdXQgZGlkIG5vdCBoYXZlIG9uZS4gT2JqZWN0OiAnLCBqc29uT2JqZWN0KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7e3ZhbGlkOiBib29sZWFuLCBlcnJvcnM6IEFycmF5fX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF90b0pzb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAndmFsaWQnOiB0aGlzLl92YWxpZCxcbiAgICAgICAgICAgICdlcnJvcnMnOiB0aGlzLl9lcnJvcnNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IHZhbGlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICovXG4gICAgZ2V0IGVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9ycztcbiAgICB9XG59XG5cbmV4cG9ydCB7IFZhbGlkYXRpb25SZXNwb25zZSB9IiwiLyoqXG4gKiBFdmVudCBzZW1pIHBvbHlmaWxsLiBJRSBkb2VzIG5vdCBzdXBwb3J0IG5ldyBldmVudC4gQnV0IGRvZXMgc3VwcG9ydCBkb2N1bWVudC5jcmVhdGVFdmVudC5cbiAqIFNhbWUgdGhpbmcgZm9yIGRpc3BhdGNoaW5nIGV2ZW50cy4gQnV0IHRoZW4gd2l0aCBjcmVhdGVFdmVudCBhbmQgZmlyZUV2ZW50LlxuICovXG5cblxuZnVuY3Rpb24gY3JlYXRlTmV3RXZlbnQoZXZlbnROYW1lKSB7XG4gICAgbGV0IGV2ZW50O1xuICAgIGlmICh0eXBlb2YoRXZlbnQpID09PSAnZnVuY3Rpb24nKSB7IC8vT24gaWUgaXQgaXMgdHlwZU9mIG9iamVjdC5cbiAgICAgICAgZXZlbnQgPSBuZXcgRXZlbnQoZXZlbnROYW1lKTsgLy9Ob24taWVcbiAgICB9IGVsc2Uge1xuICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpOyAvL2llXG4gICAgICAgIGV2ZW50LmluaXRFdmVudChldmVudE5hbWUsIHRydWUsIHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gZXZlbnQ7XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoRXZlbnRGb3JFbGVtZW50KGVsZW1lbnQsIGV2ZW50KVxue1xuICAgIGlmIChkb2N1bWVudC5jcmVhdGVFdmVudCkge1xuICAgICAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuZmlyZUV2ZW50KFwib25cIiArIGV2ZW50LmV2ZW50VHlwZSwgZXZlbnQpO1xuICAgIH1cbn1cblxuIiwiTnVtYmVyLmlzSW50ZWdlciA9IE51bWJlci5pc0ludGVnZXIgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmXG4gICAgICAgIGlzRmluaXRlKHZhbHVlKSAmJlxuICAgICAgICBNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWU7XG59OyIsIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gICAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeSgpIDpcbiAgICAgICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICAgICAgICAgIChmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbiAgICAvKipcbiAgICAgKiBAdGhpcyB7UHJvbWlzZX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5hbGx5Q29uc3RydWN0b3IoY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gdGhpcy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgcmV0dXJuIHRoaXMudGhlbihcbiAgICAgICAgICAgIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yLnJlc29sdmUoY2FsbGJhY2soKSkudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvci5yZXNvbHZlKGNhbGxiYWNrKCkpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvci5yZWplY3QocmVhc29uKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbi8vIFN0b3JlIHNldFRpbWVvdXQgcmVmZXJlbmNlIHNvIHByb21pc2UtcG9seWZpbGwgd2lsbCBiZSB1bmFmZmVjdGVkIGJ5XG4vLyBvdGhlciBjb2RlIG1vZGlmeWluZyBzZXRUaW1lb3V0IChsaWtlIHNpbm9uLnVzZUZha2VUaW1lcnMoKSlcbiAgICB2YXIgc2V0VGltZW91dEZ1bmMgPSBzZXRUaW1lb3V0O1xuXG4gICAgZnVuY3Rpb24gbm9vcCgpIHt9XG5cbi8vIFBvbHlmaWxsIGZvciBGdW5jdGlvbi5wcm90b3R5cGUuYmluZFxuICAgIGZ1bmN0aW9uIGJpbmQoZm4sIHRoaXNBcmcpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFByb21pc2UoZm4pIHtcbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFByb21pc2UpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvbWlzZXMgbXVzdCBiZSBjb25zdHJ1Y3RlZCB2aWEgbmV3Jyk7XG4gICAgICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHRocm93IG5ldyBUeXBlRXJyb3IoJ25vdCBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIC8qKiBAdHlwZSB7IW51bWJlcn0gKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSAwO1xuICAgICAgICAvKiogQHR5cGUgeyFib29sZWFufSAqL1xuICAgICAgICB0aGlzLl9oYW5kbGVkID0gZmFsc2U7XG4gICAgICAgIC8qKiBAdHlwZSB7UHJvbWlzZXx1bmRlZmluZWR9ICovXG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAvKiogQHR5cGUgeyFBcnJheTwhRnVuY3Rpb24+fSAqL1xuICAgICAgICB0aGlzLl9kZWZlcnJlZHMgPSBbXTtcblxuICAgICAgICBkb1Jlc29sdmUoZm4sIHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZShzZWxmLCBkZWZlcnJlZCkge1xuICAgICAgICB3aGlsZSAoc2VsZi5fc3RhdGUgPT09IDMpIHtcbiAgICAgICAgICAgIHNlbGYgPSBzZWxmLl92YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZi5fc3RhdGUgPT09IDApIHtcbiAgICAgICAgICAgIHNlbGYuX2RlZmVycmVkcy5wdXNoKGRlZmVycmVkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLl9oYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgUHJvbWlzZS5faW1tZWRpYXRlRm4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgY2IgPSBzZWxmLl9zdGF0ZSA9PT0gMSA/IGRlZmVycmVkLm9uRnVsZmlsbGVkIDogZGVmZXJyZWQub25SZWplY3RlZDtcbiAgICAgICAgICAgIGlmIChjYiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIChzZWxmLl9zdGF0ZSA9PT0gMSA/IHJlc29sdmUgOiByZWplY3QpKGRlZmVycmVkLnByb21pc2UsIHNlbGYuX3ZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmV0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXQgPSBjYihzZWxmLl92YWx1ZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGRlZmVycmVkLnByb21pc2UsIGUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoZGVmZXJyZWQucHJvbWlzZSwgcmV0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZShzZWxmLCBuZXdWYWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gUHJvbWlzZSBSZXNvbHV0aW9uIFByb2NlZHVyZTogaHR0cHM6Ly9naXRodWIuY29tL3Byb21pc2VzLWFwbHVzL3Byb21pc2VzLXNwZWMjdGhlLXByb21pc2UtcmVzb2x1dGlvbi1wcm9jZWR1cmVcbiAgICAgICAgICAgIGlmIChuZXdWYWx1ZSA9PT0gc2VsZilcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBIHByb21pc2UgY2Fubm90IGJlIHJlc29sdmVkIHdpdGggaXRzZWxmLicpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG5ld1ZhbHVlICYmXG4gICAgICAgICAgICAgICAgKHR5cGVvZiBuZXdWYWx1ZSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIG5ld1ZhbHVlID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRoZW4gPSBuZXdWYWx1ZS50aGVuO1xuICAgICAgICAgICAgICAgIGlmIChuZXdWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fc3RhdGUgPSAzO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl92YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBmaW5hbGUoc2VsZik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvUmVzb2x2ZShiaW5kKHRoZW4sIG5ld1ZhbHVlKSwgc2VsZik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLl9zdGF0ZSA9IDE7XG4gICAgICAgICAgICBzZWxmLl92YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgZmluYWxlKHNlbGYpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZWplY3Qoc2VsZiwgZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZWplY3Qoc2VsZiwgbmV3VmFsdWUpIHtcbiAgICAgICAgc2VsZi5fc3RhdGUgPSAyO1xuICAgICAgICBzZWxmLl92YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICBmaW5hbGUoc2VsZik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmluYWxlKHNlbGYpIHtcbiAgICAgICAgaWYgKHNlbGYuX3N0YXRlID09PSAyICYmIHNlbGYuX2RlZmVycmVkcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIFByb21pc2UuX2ltbWVkaWF0ZUZuKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIGlmICghc2VsZi5faGFuZGxlZCkge1xuICAgICAgICAgICAgICAgICAgICBQcm9taXNlLl91bmhhbmRsZWRSZWplY3Rpb25GbihzZWxmLl92YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsZi5fZGVmZXJyZWRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBoYW5kbGUoc2VsZiwgc2VsZi5fZGVmZXJyZWRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLl9kZWZlcnJlZHMgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEhhbmRsZXIob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIHByb21pc2UpIHtcbiAgICAgICAgdGhpcy5vbkZ1bGZpbGxlZCA9IHR5cGVvZiBvbkZ1bGZpbGxlZCA9PT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogbnVsbDtcbiAgICAgICAgdGhpcy5vblJlamVjdGVkID0gdHlwZW9mIG9uUmVqZWN0ZWQgPT09ICdmdW5jdGlvbicgPyBvblJlamVjdGVkIDogbnVsbDtcbiAgICAgICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUYWtlIGEgcG90ZW50aWFsbHkgbWlzYmVoYXZpbmcgcmVzb2x2ZXIgZnVuY3Rpb24gYW5kIG1ha2Ugc3VyZVxuICAgICAqIG9uRnVsZmlsbGVkIGFuZCBvblJlamVjdGVkIGFyZSBvbmx5IGNhbGxlZCBvbmNlLlxuICAgICAqXG4gICAgICogTWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCBhc3luY2hyb255LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRvUmVzb2x2ZShmbiwgc2VsZikge1xuICAgICAgICB2YXIgZG9uZSA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm4oXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc2VsZiwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZWplY3Qoc2VsZiwgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHJldHVybjtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgcmVqZWN0KHNlbGYsIGV4KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFByb21pc2UucHJvdG90eXBlWydjYXRjaCddID0gZnVuY3Rpb24ob25SZWplY3RlZCkge1xuICAgICAgICByZXR1cm4gdGhpcy50aGVuKG51bGwsIG9uUmVqZWN0ZWQpO1xuICAgIH07XG5cbiAgICBQcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB2YXIgcHJvbSA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKG5vb3ApO1xuXG4gICAgICAgIGhhbmRsZSh0aGlzLCBuZXcgSGFuZGxlcihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcHJvbSkpO1xuICAgICAgICByZXR1cm4gcHJvbTtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5wcm90b3R5cGVbJ2ZpbmFsbHknXSA9IGZpbmFsbHlDb25zdHJ1Y3RvcjtcblxuICAgIFByb21pc2UuYWxsID0gZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGlmICghYXJyIHx8IHR5cGVvZiBhcnIubGVuZ3RoID09PSAndW5kZWZpbmVkJylcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlLmFsbCBhY2NlcHRzIGFuIGFycmF5Jyk7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFycik7XG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHJldHVybiByZXNvbHZlKFtdKTtcbiAgICAgICAgICAgIHZhciByZW1haW5pbmcgPSBhcmdzLmxlbmd0aDtcblxuICAgICAgICAgICAgZnVuY3Rpb24gcmVzKGksIHZhbCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWwgJiYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGhlbiA9IHZhbC50aGVuO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbi5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzKGksIHZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSB2YWw7XG4gICAgICAgICAgICAgICAgICAgIGlmICgtLXJlbWFpbmluZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICByZXMoaSwgYXJnc1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBQcm9taXNlLnJlc29sdmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5yZWplY3QgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICByZWplY3QodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB2YWx1ZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbaV0udGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4vLyBVc2UgcG9seWZpbGwgZm9yIHNldEltbWVkaWF0ZSBmb3IgcGVyZm9ybWFuY2UgZ2FpbnNcbiAgICBQcm9taXNlLl9pbW1lZGlhdGVGbiA9XG4gICAgICAgICh0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgICBmdW5jdGlvbihmbikge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbik7XG4gICAgICAgICAgICB9KSB8fFxuICAgICAgICBmdW5jdGlvbihmbikge1xuICAgICAgICAgICAgc2V0VGltZW91dEZ1bmMoZm4sIDApO1xuICAgICAgICB9O1xuXG4gICAgUHJvbWlzZS5fdW5oYW5kbGVkUmVqZWN0aW9uRm4gPSBmdW5jdGlvbiBfdW5oYW5kbGVkUmVqZWN0aW9uRm4oZXJyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uc29sZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdQb3NzaWJsZSBVbmhhbmRsZWQgUHJvbWlzZSBSZWplY3Rpb246JywgZXJyKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqIEBzdXBwcmVzcyB7dW5kZWZpbmVkVmFyc30gKi9cbiAgICB2YXIgZ2xvYmFsTlMgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIHRoZSBvbmx5IHJlbGlhYmxlIG1lYW5zIHRvIGdldCB0aGUgZ2xvYmFsIG9iamVjdCBpc1xuICAgICAgICAvLyBgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKWBcbiAgICAgICAgLy8gSG93ZXZlciwgdGhpcyBjYXVzZXMgQ1NQIHZpb2xhdGlvbnMgaW4gQ2hyb21lIGFwcHMuXG4gICAgICAgIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBzZWxmO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdztcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWw7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gbG9jYXRlIGdsb2JhbCBvYmplY3QnKTtcbiAgICB9KSgpO1xuXG4gICAgaWYgKCEoJ1Byb21pc2UnIGluIGdsb2JhbE5TKSkge1xuICAgICAgICBnbG9iYWxOU1snUHJvbWlzZSddID0gUHJvbWlzZTtcbiAgICB9IGVsc2UgaWYgKCFnbG9iYWxOUy5Qcm9taXNlLnByb3RvdHlwZVsnZmluYWxseSddKSB7XG4gICAgICAgIGdsb2JhbE5TLlByb21pc2UucHJvdG90eXBlWydmaW5hbGx5J10gPSBmaW5hbGx5Q29uc3RydWN0b3I7XG4gICAgfVxuXG59KSkpOyIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICBTY3JvbGwgaGFuZGxlclxuICAgLSBIYW5kbGVyIHRoZSBvYmplY3RzIHdoaWNoIGFyZSBiaW5kIG9uIHNjcm9sbCBldmVudHMgb3IgdmlzaWJsZSBpbiB2aWV3cG9ydFxuID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbmNvbnN0IFNjcm9sbEhhbmRsZXIgPSB7XG5cbiAgICAvLyBWYXJpYWJsZXMgZm9yIGRlYm91bmNlIGFuZCB0aHJvdHRsZSBlZmZlY3RzXG4gICAgdGltZTogRGF0ZS5ub3coKSxcbiAgICB0aW1lb3V0OiBudWxsLFxuICAgIHdhaXRUaHJvdHRsZTogMTAwMCxcbiAgICB3YWl0RGVib3VuY2U6IDMwMCxcblxuICAgIC8vIFZhcmlhYmxlcyBmb3Igc2Nyb2xsIGRpcmVjdGlvblxuICAgIGxhc3RTY3JvbGxUb3BQb3NpdGlvbjogMCxcbiAgICBzY3JvbGxEaXJlY3Rpb25Eb3duOiB0cnVlLFxuICAgIHNjcm9sbERpcmVjdGlvblVwOiBmYWxzZSxcblxuICAgIC8vSW5pdGlhbGlzYXRpb25cbiAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBzdGFydCBvbiBzdGFydCB1cFxuICAgICAgICBTY3JvbGxIYW5kbGVyLnRyaWdnZXJPbkluaXQoKTtcblxuICAgICAgICAvLyBUaHJvdHRsZSBzY3JvbGxcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICgoU2Nyb2xsSGFuZGxlci50aW1lICsgU2Nyb2xsSGFuZGxlci53YWl0VGhyb3R0bGUgLSBEYXRlLm5vdygpKSA8IDApIHtcbiAgICAgICAgICAgICAgICBTY3JvbGxIYW5kbGVyLnRyaWdnZXJUaHJvdHRsZSgpO1xuICAgICAgICAgICAgICAgIFNjcm9sbEhhbmRsZXIudGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNtb290aCBzY3JvbGxcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIFNjcm9sbEhhbmRsZXIudHJpZ2dlclNtb290aCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZWJvdW5jZSBzY3JvbGxcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmKGlzc2V0KFNjcm9sbEhhbmRsZXIudGltZW91dCkpIGNsZWFyVGltZW91dChTY3JvbGxIYW5kbGVyLnRpbWVvdXQpO1xuICAgICAgICAgICAgU2Nyb2xsSGFuZGxlci50aW1lb3V0ID0gc2V0VGltZW91dChTY3JvbGxIYW5kbGVyLnRyaWdnZXJEZWJvdW5jZSwgU2Nyb2xsSGFuZGxlci53YWl0RGVib3VuY2UpO1xuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgLy8gVHJpZ2dlciBvbiBzdGFydCB1cFxuICAgIHRyaWdnZXJPbkluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgU2Nyb2xsSGFuZGxlci50cmlnZ2VyRWxlbWVudEluVmlld3BvcnRBbmltYXRpb24oKTtcbiAgICB9LFxuXG4gICAgLy8gVHJpZ2dlciBzY3JvbGwgZnVuY3Rpb25zIHdpdGggdGhyb3R0bGUgKHByZWZlcnJlZClcbiAgICB0cmlnZ2VyVGhyb3R0bGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ1Rocm90dGxlZCBzY3JvbGwnKTtcbiAgICAgICAgU2Nyb2xsSGFuZGxlci50cmlnZ2VyRWxlbWVudEluVmlld3BvcnRBbmltYXRpb24oKTtcbiAgICB9LFxuXG4gICAgLy8gVHJpZ2dlciBzY3JvbGwgb24gZGVib3VuY2VcbiAgICB0cmlnZ2VyRGVib3VuY2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ0RlYm91bmNlIHNjcm9sbCcpO1xuICAgIH0sXG5cbiAgICAvLyBUcmlnZ2VyIHNjcm9sbCBvbiB0aGUgZmxpZ2h0XG4gICAgdHJpZ2dlclNtb290aDogZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBjb25zb2xlLmxvZygnU21vb3RoIHNjcm9sbCcpO1xuICAgICAgICBTY3JvbGxIYW5kbGVyLmRldGVjdFNjcm9sbERpcmVjdGlvbigpO1xuICAgICAgICBTY3JvbGxIYW5kbGVyLnRvZ2dsZVN0aWNreUhlYWRlcigpO1xuICAgIH0sXG5cbiAgICAvLyBEZXRlY3QgaWYgcGFydCBvZiBhIGdpdmVuIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiB0aGUgdmlld3BvcnRcbiAgICAvLyBFbCBtdXN0IGJlIGEgbm9kZSBlbGVtZW50XG4gICAgZGV0ZWN0SWZFbGVtZW50SXNQYXJ0bHlJblZpZXdwb3J0OiBmdW5jdGlvbihlbClcbiAgICB7XG4gICAgICAgIGlmKGlzc2V0KGVsKSl7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIC8vIERPTVJlY3QgeyB4OiA4LCB5OiA4LCB3aWR0aDogMTAwLCBoZWlnaHQ6IDEwMCwgdG9wOiA4LCByaWdodDogMTA4LCBib3R0b206IDEwOCwgbGVmdDogOCB9XG4gICAgICAgICAgICBjb25zdCB3aW5kb3dIZWlnaHQgPSAod2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpO1xuICAgICAgICAgICAgY29uc3Qgd2luZG93V2lkdGggPSAod2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKTtcblxuICAgICAgICAgICAgY29uc3QgdmVydGljYWxJblZpZXcgPSAocmVjdC50b3AgPD0gKHdpbmRvd0hlaWdodCkpICYmICgocmVjdC50b3AgKyByZWN0LmhlaWdodCkgPj0gMCk7XG4gICAgICAgICAgICBjb25zdCBob3Jpem9udGFsSW5WaWV3ID0gKHJlY3QubGVmdCA8PSB3aW5kb3dXaWR0aCkgJiYgKChyZWN0LmxlZnQgKyByZWN0LndpZHRoKSA+PSAwKTtcblxuICAgICAgICAgICAgcmV0dXJuICh2ZXJ0aWNhbEluVmlldyAmJiBob3Jpem9udGFsSW5WaWV3KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvLyBEZXRlY3QgaWYgYSBnaXZlbiBlbGVtZW50IGlzIGZ1bGx5IHZpc2libGUgaW4gdGhlIHZpZXdwb3J0XG4gICAgLy8gRWwgbXVzdCBiZSBhIG5vZGUgZWxlbWVudFxuICAgIGRldGVjdElmRWxlbWVudElzRnVsbHlJblZpZXdwb3J0OiBmdW5jdGlvbihlbClcbiAgICB7XG4gICAgICAgIGlmKGlzc2V0KGVsKSl7XG4gICAgICAgICAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgcmVjdC50b3AgPj0gMCAmJlxuICAgICAgICAgICAgICAgIHJlY3QuYm90dG9tIDw9IHdpbmRvdy5pbm5lckhlaWdodFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBkZXRlY3RTY3JvbGxEaXJlY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wUG9zaXRpb24gPSB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDsgLy8gQ3JlZGl0czogXCJodHRwczovL2dpdGh1Yi5jb20vcWVyZW15L3NvL2Jsb2IvbWFzdGVyL3NvLmRvbS5qcyNMNDI2XCJcbiAgICAgICAgaWYgKHNjcm9sbFRvcFBvc2l0aW9uID49IFNjcm9sbEhhbmRsZXIubGFzdFNjcm9sbFRvcFBvc2l0aW9uKXtcbiAgICAgICAgICAgIFNjcm9sbEhhbmRsZXIuc2Nyb2xsRGlyZWN0aW9uRG93biA9IHRydWU7XG4gICAgICAgICAgICBTY3JvbGxIYW5kbGVyLnNjcm9sbERpcmVjdGlvblVwID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBTY3JvbGxIYW5kbGVyLnNjcm9sbERpcmVjdGlvbkRvd24gPSBmYWxzZTtcbiAgICAgICAgICAgIFNjcm9sbEhhbmRsZXIuc2Nyb2xsRGlyZWN0aW9uVXAgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIFNjcm9sbEhhbmRsZXIubGFzdFNjcm9sbFRvcFBvc2l0aW9uID0gc2Nyb2xsVG9wUG9zaXRpb247XG4gICAgfSxcblxuICAgIC8vIFRyaWdnZXIgYW5pbWF0aW9uIG9uIGVsZW1lbnRzIHRoYXQgaGF2ZSAnZWxlbWVudC1pbi12aWV3cG9ydCcgYW5kIHRoYXQgYXJlIGluIHRoZSB2aWV3cG9ydFxuICAgIC8vIFRoZXNlIGFuaW1hdGlvbiBjYW4gb25seSBiZSB0cmlnZ2VyZWQgb25jZSwgaWYgeW91IHdhbnQgbW9yZSB0aGVuIHRoYXQgeW91IHNob3VsZCB3cml0ZSBhbiBzcGVjaWZpYyBmdW5jdGlvbiBmb3IgdGhpc1xuICAgIHRyaWdnZXJFbGVtZW50SW5WaWV3cG9ydEFuaW1hdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5lbGVtZW50LWluLXZpZXdwb3J0Jyk7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzTGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xuXG4gICAgICAgIGZvcihsZXQgZSA9IDA7IGUgPCBlbGVtZW50c0xlbmd0aDsgZSsrKXtcblxuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW2VdO1xuICAgICAgICAgICAgaWYoU2Nyb2xsSGFuZGxlci5kZXRlY3RJZkVsZW1lbnRJc1BhcnRseUluVmlld3BvcnQoZWxlbWVudCkpe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZWxlbWVudC1pbi12aWV3cG9ydCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENVU1RPTSBTQ1JPTEwgSEFORExFUlMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAvLyBIaWRlIG9yIHNob3cgc3RpY2t5IG5hdmlnYXRpb24gd2hlbiBoZWFkZXIgaXNuJ3QgdmlzaWJsZVxuICAgIHRvZ2dsZVN0aWNreUhlYWRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzdGlja3lIZWFkZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtc3RpY2t5LWhlYWRlcicpO1xuICAgICAgICBjb25zdCB2aXNpYmxlU3RpY2t5SGVhZGVyQ2xhc3MgPSAnaXMtc3RpY2t5LWhlYWRlci12aXNpYmxlJztcbiAgICAgICAgY29uc3Qgc3VibmF2TGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy1zdWJuYXYnKTtcbiAgICAgICAgdmFyIHN1Yk5hdklzVmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICBzdGlja3lIZWFkZXIuaGlkZGVuID0gZmFsc2U7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJuYXZMaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUoc3VibmF2TGlzdFtpXSwgbnVsbCkudmlzaWJpbGl0eSA9PSBcInZpc2libGVcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBzdWJOYXZJc1Zpc2libGUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYoaXNzZXQoc3RpY2t5SGVhZGVyKSAmJiAhc3ViTmF2SXNWaXNpYmxlKXtcbiAgICAgICAgICAgIC8vIEhpZGUgd2hlbiBzY3JvbGxpbmcgRE9XTiAoT1Igd2l0aGluIG9mZnNldClcbiAgICAgICAgICAgIGlmKFNjcm9sbEhhbmRsZXIuc2Nyb2xsRGlyZWN0aW9uRG93biB8fCBTY3JvbGxIYW5kbGVyLmxhc3RTY3JvbGxUb3BQb3NpdGlvbiA8IDExMCl7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKHZpc2libGVTdGlja3lIZWFkZXJDbGFzcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBTaG93IHdoZW4gc2Nyb2xsaW5nIFVQIGFuZCBvdXRzaWRlIG9mIG9mZnNldFxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKHZpc2libGVTdGlja3lIZWFkZXJDbGFzcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG59O1xuXG5TY3JvbGxIYW5kbGVyLmluaXQoKTsiLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBGb3JtYXRVdGlscyB7XG4gICAgLyoqXG4gICAgICogSW5zZXJ0IGRvdHMgZXZlcnkgeCBjaGFyYWN0ZXIsIHN0YXJ0aW5nIGZyb20gdGhlIGVuZFxuICAgICAqXG4gICAgICogQHBhcmFtIGlucHV0XG4gICAgICogQHBhcmFtIGV2ZXJ5XG4gICAgICogQHJldHVybiB7Knx2b2lkfHN0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgaW5zZXJ0RG90cyAoaW5wdXQsIGV2ZXJ5ID0gMykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcbiAgICAgICAgY29uc3QgcmVnZXggPSAnKC57JyArIGV2ZXJ5ICsgJ30pKD8hJCknO1xuICAgICAgICByZXR1cm4gRm9ybWF0VXRpbHMucmV2ZXJzZShGb3JtYXRVdGlscy5yZXZlcnNlKGlucHV0KS5yZXBsYWNlKG5ldyBSZWdFeHAocmVnZXgsICdnJyksICckMS4nKSlcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgdGhlIGlucHV0IHN0cmluZ1xuICAgICAqIEBwYXJhbSBpbnB1dFxuICAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgcmV2ZXJzZSAoaW5wdXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIGlucHV0ID0gaW5wdXQudG9TdHJpbmcoMTApO1xuICAgICAgICByZXR1cm4gaW5wdXQuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIG5vbiBkaWdpdCBjaGFyYWN0ZXJzIGZyb20gYSBzdHJpbmcgc28gdGhlIGlucHV0IGJlY29tZXMgbnVtZXJpYy5cbiAgICAgKiBUaGVuIGNvbnZlcnRzIGl0IHRvIGFuIGludGVnZXIuIElmIGl0IHRoZW4gaXMgbm90IGEgbnVtYmVyLCB0aGUgZmFsbGJhY2sgdmFsdWUgd2lsbCBiZSByZXR1cm5lZFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpbnB1dFxuICAgICAqIEBwYXJhbSB7YW55fSBmYWxsYmFjayBBIGZhbGxiYWNrIHZhbHVlIHRvIHVzZSB3aGVuIHRoZSBpbnB1dCBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvIGEgbnVtYmVyXG4gICAgICogQHJldHVybiB7YW55fVxuICAgICAqL1xuICAgIHN0YXRpYyBjb252ZXJ0VG9JbnRlZ2VyIChpbnB1dCwgZmFsbGJhY2sgPSAwKSB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgIT09ICdzdHJpbmcnKSBpbnB1dCA9IGlucHV0LnRvU3RyaW5nKDEwKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtZXNjYXBlXG4gICAgICAgIGNvbnN0IG51bWJlciA9IHBhcnNlSW50KGlucHV0LnJlcGxhY2UoL1xcRC9nLCAnJykpO1xuICAgICAgICByZXR1cm4gKCFpc05hTihudW1iZXIpKSA/IG51bWJlciA6IGZhbGxiYWNrXG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBhIHZhbHVlIHRvIGJlIGluIHRoZSByYW5nZSBvZiBsb3dlciBvciB1cHBlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZVxuICAgICAqIEBwYXJhbSBsb3dlclxuICAgICAqIEBwYXJhbSB1cHBlclxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZm9yY2VUb0JlSW5SYW5nZU9mICh2YWx1ZSwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKSB0aHJvdyBuZXcgRXJyb3IoJ1RoZSB2YWx1ZSwgbG93ZXIgYW5kIHVwcGVyIGFsbCBtdXN0IGJlIGEgbnVtYmVyIGJ1dCB3aGVyZSByZXNwZWN0aXZlbHk6JyArICh0eXBlb2YgdmFsdWUpICsgJyAnICsgKHR5cGVvZiBsb3dlcikgKyAnICcgKyAodHlwZW9mIHVwcGVyKSk7XG4gICAgICAgIGlmIChsb3dlciAmJiB2YWx1ZSA8IGxvd2VyKSByZXR1cm4gbG93ZXI7XG4gICAgICAgIGlmICh1cHBlciAmJiB2YWx1ZSA+IHVwcGVyKSByZXR1cm4gdXBwZXI7XG4gICAgICAgIHJldHVybiB2YWx1ZVxuICAgIH1cbn1cbiIsImltcG9ydCBWdWUgZnJvbSAndnVlJztcbmltcG9ydCBwYXliYWNrUGVyaW9kQ2FsY3VsYXRvciBmcm9tICcuL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZSdcbmltcG9ydCBwYXliYWNrUGVyaW9kSW50YWtlIGZyb20gJy4vcGF5YmFja1BlcmlvZEludGFrZS52dWUnXG5cbmlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwYXliYWNrX3BlcmlvZCcpKSB7XG4gICAgbmV3IFZ1ZSh7XG4gICAgICAgIGVsOiAnI3BheWJhY2tfcGVyaW9kJyxcbiAgICAgICAgY29tcG9uZW50czoge1xuICAgICAgICAgICAgcGF5YmFja1BlcmlvZENhbGN1bGF0b3IsXG4gICAgICAgICAgICBwYXliYWNrUGVyaW9kSW50YWtlXG4gICAgICAgIH1cbiAgICB9KTtcbn0iLCJpbXBvcnQgeyByZW5kZXIsIHN0YXRpY1JlbmRlckZucyB9IGZyb20gXCIuL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD04MmFlODFjOCZcIlxuaW1wb3J0IHNjcmlwdCBmcm9tIFwiLi9wYXliYWNrUGVyaW9kQ2FsY3VsYXRvci52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmXCJcbmV4cG9ydCAqIGZyb20gXCIuL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIlxuXG5cbi8qIG5vcm1hbGl6ZSBjb21wb25lbnQgKi9cbmltcG9ydCBub3JtYWxpemVyIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3J1bnRpbWUvY29tcG9uZW50Tm9ybWFsaXplci5qc1wiXG52YXIgY29tcG9uZW50ID0gbm9ybWFsaXplcihcbiAgc2NyaXB0LFxuICByZW5kZXIsXG4gIHN0YXRpY1JlbmRlckZucyxcbiAgZmFsc2UsXG4gIG51bGwsXG4gIG51bGwsXG4gIG51bGxcbiAgXG4pXG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7XG4gIHZhciBhcGkgPSByZXF1aXJlKFwiL1VzZXJzL3Bhc2NhbGxlbW1lbi9EZXZlbG9wbWVudC9XaW5nc3NwcmF5ZXIvbm9kZV9tb2R1bGVzL3Z1ZS1ob3QtcmVsb2FkLWFwaS9kaXN0L2luZGV4LmpzXCIpXG4gIGFwaS5pbnN0YWxsKHJlcXVpcmUoJ3Z1ZScpKVxuICBpZiAoYXBpLmNvbXBhdGlibGUpIHtcbiAgICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gICAgaWYgKCFhcGkuaXNSZWNvcmRlZCgnODJhZTgxYzgnKSkge1xuICAgICAgYXBpLmNyZWF0ZVJlY29yZCgnODJhZTgxYzgnLCBjb21wb25lbnQub3B0aW9ucylcbiAgICB9IGVsc2Uge1xuICAgICAgYXBpLnJlbG9hZCgnODJhZTgxYzgnLCBjb21wb25lbnQub3B0aW9ucylcbiAgICB9XG4gICAgbW9kdWxlLmhvdC5hY2NlcHQoXCIuL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD04MmFlODFjOCZcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgYXBpLnJlcmVuZGVyKCc4MmFlODFjOCcsIHtcbiAgICAgICAgcmVuZGVyOiByZW5kZXIsXG4gICAgICAgIHN0YXRpY1JlbmRlckZuczogc3RhdGljUmVuZGVyRm5zXG4gICAgICB9KVxuICAgIH0pXG4gIH1cbn1cbmNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwicmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZVwiXG5leHBvcnQgZGVmYXVsdCBjb21wb25lbnQuZXhwb3J0cyIsImltcG9ydCBtb2QgZnJvbSBcIi0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/P3JlZi0tNC0wIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8/dnVlLWxvYWRlci1vcHRpb25zIS4vcGF5YmFja1BlcmlvZENhbGN1bGF0b3IudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJlwiOyBleHBvcnQgZGVmYXVsdCBtb2Q7IGV4cG9ydCAqIGZyb20gXCItIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPz9yZWYtLTQtMCEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/P3Z1ZS1sb2FkZXItb3B0aW9ucyEuL3BheWJhY2tQZXJpb2RDYWxjdWxhdG9yLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIiIsImV4cG9ydCAqIGZyb20gXCItIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9sb2FkZXJzL3RlbXBsYXRlTG9hZGVyLmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi9wYXliYWNrUGVyaW9kQ2FsY3VsYXRvci52dWU/dnVlJnR5cGU9dGVtcGxhdGUmaWQ9ODJhZTgxYzgmXCIiLCJpbXBvcnQgeyByZW5kZXIsIHN0YXRpY1JlbmRlckZucyB9IGZyb20gXCIuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXRlbXBsYXRlJmlkPTdjNTllNzQ2JlwiXG5pbXBvcnQgc2NyaXB0IGZyb20gXCIuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJlwiXG5leHBvcnQgKiBmcm9tIFwiLi9wYXliYWNrUGVyaW9kSW50YWtlLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIlxuXG5cbi8qIG5vcm1hbGl6ZSBjb21wb25lbnQgKi9cbmltcG9ydCBub3JtYWxpemVyIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3J1bnRpbWUvY29tcG9uZW50Tm9ybWFsaXplci5qc1wiXG52YXIgY29tcG9uZW50ID0gbm9ybWFsaXplcihcbiAgc2NyaXB0LFxuICByZW5kZXIsXG4gIHN0YXRpY1JlbmRlckZucyxcbiAgZmFsc2UsXG4gIG51bGwsXG4gIG51bGwsXG4gIG51bGxcbiAgXG4pXG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7XG4gIHZhciBhcGkgPSByZXF1aXJlKFwiL1VzZXJzL3Bhc2NhbGxlbW1lbi9EZXZlbG9wbWVudC9XaW5nc3NwcmF5ZXIvbm9kZV9tb2R1bGVzL3Z1ZS1ob3QtcmVsb2FkLWFwaS9kaXN0L2luZGV4LmpzXCIpXG4gIGFwaS5pbnN0YWxsKHJlcXVpcmUoJ3Z1ZScpKVxuICBpZiAoYXBpLmNvbXBhdGlibGUpIHtcbiAgICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gICAgaWYgKCFhcGkuaXNSZWNvcmRlZCgnN2M1OWU3NDYnKSkge1xuICAgICAgYXBpLmNyZWF0ZVJlY29yZCgnN2M1OWU3NDYnLCBjb21wb25lbnQub3B0aW9ucylcbiAgICB9IGVsc2Uge1xuICAgICAgYXBpLnJlbG9hZCgnN2M1OWU3NDYnLCBjb21wb25lbnQub3B0aW9ucylcbiAgICB9XG4gICAgbW9kdWxlLmhvdC5hY2NlcHQoXCIuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXRlbXBsYXRlJmlkPTdjNTllNzQ2JlwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhcGkucmVyZW5kZXIoJzdjNTllNzQ2Jywge1xuICAgICAgICByZW5kZXI6IHJlbmRlcixcbiAgICAgICAgc3RhdGljUmVuZGVyRm5zOiBzdGF0aWNSZW5kZXJGbnNcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxufVxuY29tcG9uZW50Lm9wdGlvbnMuX19maWxlID0gXCJyZXNvdXJjZXMvanMvdnVlL3BheWJhY2tQZXJpb2QvcGF5YmFja1BlcmlvZEludGFrZS52dWVcIlxuZXhwb3J0IGRlZmF1bHQgY29tcG9uZW50LmV4cG9ydHMiLCJpbXBvcnQgbW9kIGZyb20gXCItIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPz9yZWYtLTQtMCEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/P3Z1ZS1sb2FkZXItb3B0aW9ucyEuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJlwiOyBleHBvcnQgZGVmYXVsdCBtb2Q7IGV4cG9ydCAqIGZyb20gXCItIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPz9yZWYtLTQtMCEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/P3Z1ZS1sb2FkZXItb3B0aW9ucyEuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJlwiIiwiZXhwb3J0ICogZnJvbSBcIi0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2xvYWRlcnMvdGVtcGxhdGVMb2FkZXIuanM/P3Z1ZS1sb2FkZXItb3B0aW9ucyEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/P3Z1ZS1sb2FkZXItb3B0aW9ucyEuL3BheWJhY2tQZXJpb2RJbnRha2UudnVlP3Z1ZSZ0eXBlPXRlbXBsYXRlJmlkPTdjNTllNzQ2JlwiIiwiaW1wb3J0IHsgcmVuZGVyLCBzdGF0aWNSZW5kZXJGbnMgfSBmcm9tIFwiLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD1jZGFhYjA5MiZcIlxuaW1wb3J0IHNjcmlwdCBmcm9tIFwiLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIlxuZXhwb3J0ICogZnJvbSBcIi4vcGF5YmFja1BlcmlvZFJlc3VsdC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmXCJcblxuXG4vKiBub3JtYWxpemUgY29tcG9uZW50ICovXG5pbXBvcnQgbm9ybWFsaXplciBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9ydW50aW1lL2NvbXBvbmVudE5vcm1hbGl6ZXIuanNcIlxudmFyIGNvbXBvbmVudCA9IG5vcm1hbGl6ZXIoXG4gIHNjcmlwdCxcbiAgcmVuZGVyLFxuICBzdGF0aWNSZW5kZXJGbnMsXG4gIGZhbHNlLFxuICBudWxsLFxuICBudWxsLFxuICBudWxsXG4gIFxuKVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkge1xuICB2YXIgYXBpID0gcmVxdWlyZShcIi9Vc2Vycy9wYXNjYWxsZW1tZW4vRGV2ZWxvcG1lbnQvV2luZ3NzcHJheWVyL25vZGVfbW9kdWxlcy92dWUtaG90LXJlbG9hZC1hcGkvZGlzdC9pbmRleC5qc1wiKVxuICBhcGkuaW5zdGFsbChyZXF1aXJlKCd2dWUnKSlcbiAgaWYgKGFwaS5jb21wYXRpYmxlKSB7XG4gICAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICAgIGlmICghYXBpLmlzUmVjb3JkZWQoJ2NkYWFiMDkyJykpIHtcbiAgICAgIGFwaS5jcmVhdGVSZWNvcmQoJ2NkYWFiMDkyJywgY29tcG9uZW50Lm9wdGlvbnMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZWxvYWQoJ2NkYWFiMDkyJywgY29tcG9uZW50Lm9wdGlvbnMpXG4gICAgfVxuICAgIG1vZHVsZS5ob3QuYWNjZXB0KFwiLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD1jZGFhYjA5MiZcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgYXBpLnJlcmVuZGVyKCdjZGFhYjA5MicsIHtcbiAgICAgICAgcmVuZGVyOiByZW5kZXIsXG4gICAgICAgIHN0YXRpY1JlbmRlckZuczogc3RhdGljUmVuZGVyRm5zXG4gICAgICB9KVxuICAgIH0pXG4gIH1cbn1cbmNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwicmVzb3VyY2VzL2pzL3Z1ZS9wYXliYWNrUGVyaW9kL3BheWJhY2tQZXJpb2RSZXN1bHQudnVlXCJcbmV4cG9ydCBkZWZhdWx0IGNvbXBvbmVudC5leHBvcnRzIiwiaW1wb3J0IG1vZCBmcm9tIFwiLSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcz8/cmVmLS00LTAhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIjsgZXhwb3J0IGRlZmF1bHQgbW9kOyBleHBvcnQgKiBmcm9tIFwiLSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcz8/cmVmLS00LTAhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyZcIiIsImV4cG9ydCAqIGZyb20gXCItIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9sb2FkZXJzL3RlbXBsYXRlTG9hZGVyLmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPz92dWUtbG9hZGVyLW9wdGlvbnMhLi9wYXliYWNrUGVyaW9kUmVzdWx0LnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD1jZGFhYjA5MiZcIiIsImltcG9ydCB7IHJlbmRlciwgc3RhdGljUmVuZGVyRm5zIH0gZnJvbSBcIi4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9dGVtcGxhdGUmaWQ9MmUzM2IwMWEmXCJcbmltcG9ydCBzY3JpcHQgZnJvbSBcIi4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmXCJcbmV4cG9ydCAqIGZyb20gXCIuL3BheWJhY2tQZXJpb2RUZXh0SW5wdXQudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJlwiXG5cblxuLyogbm9ybWFsaXplIGNvbXBvbmVudCAqL1xuaW1wb3J0IG5vcm1hbGl6ZXIgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvcnVudGltZS9jb21wb25lbnROb3JtYWxpemVyLmpzXCJcbnZhciBjb21wb25lbnQgPSBub3JtYWxpemVyKFxuICBzY3JpcHQsXG4gIHJlbmRlcixcbiAgc3RhdGljUmVuZGVyRm5zLFxuICBmYWxzZSxcbiAgbnVsbCxcbiAgbnVsbCxcbiAgbnVsbFxuICBcbilcblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHtcbiAgdmFyIGFwaSA9IHJlcXVpcmUoXCIvVXNlcnMvcGFzY2FsbGVtbWVuL0RldmVsb3BtZW50L1dpbmdzc3ByYXllci9ub2RlX21vZHVsZXMvdnVlLWhvdC1yZWxvYWQtYXBpL2Rpc3QvaW5kZXguanNcIilcbiAgYXBpLmluc3RhbGwocmVxdWlyZSgndnVlJykpXG4gIGlmIChhcGkuY29tcGF0aWJsZSkge1xuICAgIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgICBpZiAoIWFwaS5pc1JlY29yZGVkKCcyZTMzYjAxYScpKSB7XG4gICAgICBhcGkuY3JlYXRlUmVjb3JkKCcyZTMzYjAxYScsIGNvbXBvbmVudC5vcHRpb25zKVxuICAgIH0gZWxzZSB7XG4gICAgICBhcGkucmVsb2FkKCcyZTMzYjAxYScsIGNvbXBvbmVudC5vcHRpb25zKVxuICAgIH1cbiAgICBtb2R1bGUuaG90LmFjY2VwdChcIi4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9dGVtcGxhdGUmaWQ9MmUzM2IwMWEmXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFwaS5yZXJlbmRlcignMmUzM2IwMWEnLCB7XG4gICAgICAgIHJlbmRlcjogcmVuZGVyLFxuICAgICAgICBzdGF0aWNSZW5kZXJGbnM6IHN0YXRpY1JlbmRlckZuc1xuICAgICAgfSlcbiAgICB9KVxuICB9XG59XG5jb21wb25lbnQub3B0aW9ucy5fX2ZpbGUgPSBcInJlc291cmNlcy9qcy92dWUvcGF5YmFja1BlcmlvZC9wYXliYWNrUGVyaW9kVGV4dElucHV0LnZ1ZVwiXG5leHBvcnQgZGVmYXVsdCBjb21wb25lbnQuZXhwb3J0cyIsImltcG9ydCBtb2QgZnJvbSBcIi0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/P3JlZi0tNC0wIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8/dnVlLWxvYWRlci1vcHRpb25zIS4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmXCI7IGV4cG9ydCBkZWZhdWx0IG1vZDsgZXhwb3J0ICogZnJvbSBcIi0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/P3JlZi0tNC0wIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8/dnVlLWxvYWRlci1vcHRpb25zIS4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmXCIiLCJleHBvcnQgKiBmcm9tIFwiLSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvbG9hZGVycy90ZW1wbGF0ZUxvYWRlci5qcz8/dnVlLWxvYWRlci1vcHRpb25zIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8/dnVlLWxvYWRlci1vcHRpb25zIS4vcGF5YmFja1BlcmlvZFRleHRJbnB1dC52dWU/dnVlJnR5cGU9dGVtcGxhdGUmaWQ9MmUzM2IwMWEmXCIiLCIvLyByZW1vdmVkIGJ5IGV4dHJhY3QtdGV4dC13ZWJwYWNrLXBsdWdpbiJdLCJzb3VyY2VSb290IjoiIn0=