PageSourceSearch

https://www.cht.com.tw/home/web/js/assets/home.1.js?v=39

js cht.com.tw collected 2026-10-01 09:05:13 UTC 834,105 bytes, 9,266 lines download raw bytes

1/******/ (() => { // webpackBootstrap
2/******/ 	"use strict";
3/******/ 	var __webpack_modules__ = ({
4
vendor: 4,065 bytes, lines 5-189
5/***/ "./src/assets/scripts/swiper-9.4.1.js":
6/*!********************************************!*\
7  !*** ./src/assets/scripts/swiper-9.4.1.js ***!
8  \********************************************/
9/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10
11__webpack_require__.r(__webpack_exports__);
12/* harmony export */ __webpack_require__.d(__webpack_exports__, {
13/* harmony export */   Swiper: () => (/* binding */ Swiper),
14/* harmony export */   "default": () => (/* binding */ Swiper)
15/* harmony export */ });
16/**
17 * Swiper 9.4.1
18 * Most modern mobile touch slider and framework with hardware accelerated transitions
19 * https://swiperjs.com
20 *
21 * Copyright 2014-2023 Vladimir Kharlampidi
22 *
23 * Released under the MIT License
24 *
25 * Released on: June 13, 2023
26 */
27
28/**
29 * SSR Window 4.0.2
30 * Better handling for window object in SSR environment
31 * https://github.com/nolimits4web/ssr-window
32 *
33 * Copyright 2021, Vladimir Kharlampidi
34 *
35 * Licensed under MIT
36 *
37 * Released on: December 13, 2021
38 */
39/* eslint-disable no-param-reassign */
40function isObject$1(obj) {
41  return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
42}
43function extend$1(target, src) {
44  if (target === void 0) {
45    target = {};
46  }
47  if (src === void 0) {
48    src = {};
49  }
50  Object.keys(src).forEach((key) => {
51    if (typeof target[key] === 'undefined') target[key] = src[key];
52    else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) {
53      extend$1(target[key], src[key]);
54    }
55  });
56}
57const ssrDocument = {
58  body: {},
59  addEventListener() {},
60  removeEventListener() {},
61  activeElement: {
62    blur() {},
63    nodeName: '',
64  },
65  querySelector() {
66    return null;
67  },
68  querySelectorAll() {
69    return [];
70  },
71  getElementById() {
72    return null;
73  },
74  createEvent() {
75    return {
76      initEvent() {},
77    };
78  },
79  createElement() {
80    return {
81      children: [],
82      childNodes: [],
83      style: {},
84      setAttribute() {},
85      getElementsByTagName() {
86        return [];
87      },
88    };
89  },
90  createElementNS() {
91    return {};
92  },
93  importNode() {
94    return null;
95  },
96  location: {
97    hash: '',
98    host: '',
99    hostname: '',
100    href: '',
101    origin: '',
102    pathname: '',
103    protocol: '',
104    search: '',
105  },
106};
107function getDocument() {
108  const doc = typeof document !== 'undefined' ? document : {};
109  extend$1(doc, ssrDocument);
110  return doc;
111}
112const ssrWindow = {
113  document: ssrDocument,
114  navigator: {
115    userAgent: '',
116  },
117  location: {
118    hash: '',
119    host: '',
120    hostname: '',
121    href: '',
122    origin: '',
123    pathname: '',
124    protocol: '',
125    search: '',
126  },
127  history: {
128    replaceState() {},
129    pushState() {},
130    go() {},
131    back() {},
132  },
133  CustomEvent: function CustomEvent() {
134    return this;
135  },
136  addEventListener() {},
137  removeEventListener() {},
138  getComputedStyle() {
139    return {
140      getPropertyValue() {
141        return '';
142      },
143    };
144  },
145  Image() {},
146  Date() {},
147  screen: {},
148  setTimeout() {},
149  clearTimeout() {},
150  matchMedia() {
151    return {};
152  },
153  requestAnimationFrame(callback) {
154    if (typeof setTimeout === 'undefined') {
155      callback();
156      return null;
157    }
158    return setTimeout(callback, 0);
159  },
160  cancelAnimationFrame(id) {
161    if (typeof setTimeout === 'undefined') {
162      return;
163    }
164    clearTimeout(id);
165  },
166};
167function getWindow() {
168  const win = typeof window !== 'undefined' ? window : {};
169  extend$1(win, ssrWindow);
170  return win;
171}
172
173function deleteProps(obj) {
174  const object = obj;
175  Object.keys(object).forEach((key) => {
176    try {
177      object[key] = null;
178    } catch (e) {
179      // no getter for object
180    }
181    try {
182      delete object[key];
183    } catch (e) {
184      // something got wrong
185    }
186  });
187}
188function nextTick(callback, delay) {
189  if (delay === void 0) {
vendor: 4,886 bytes, lines 190-326
190    delay = 0;
191  }
192  return setTimeout(callback, delay);
193}
194function now() {
195  return Date.now();
196}
197function getComputedStyle$1(el) {
198  const window = getWindow();
199  let style;
200  if (window.getComputedStyle) {
201    style = window.getComputedStyle(el, null);
202  }
203  if (!style && el.currentStyle) {
204    style = el.currentStyle;
205  }
206  if (!style) {
207    style = el.style;
208  }
209  return style;
210}
211function getTranslate(el, axis) {
212  if (axis === void 0) {
213    axis = 'x';
214  }
215  const window = getWindow();
216  let matrix;
217  let curTransform;
218  let transformMatrix;
219  const curStyle = getComputedStyle$1(el);
220  if (window.WebKitCSSMatrix) {
221    curTransform = curStyle.transform || curStyle.webkitTransform;
222    if (curTransform.split(',').length > 6) {
223      curTransform = curTransform
224        .split(', ')
225        .map((a) => a.replace(',', '.'))
226        .join(', ');
227    }
228    // Some old versions of Webkit choke when 'none' is passed; pass
229    // empty string instead in this case
230    transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
231  } else {
232    transformMatrix =
233      curStyle.MozTransform ||
234      curStyle.OTransform ||
235      curStyle.MsTransform ||
236      curStyle.msTransform ||
237      curStyle.transform ||
238      curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
239    matrix = transformMatrix.toString().split(',');
240  }
241  if (axis === 'x') {
242    // Latest Chrome and webkits Fix
243    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
244    // Crazy IE10 Matrix
245    else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
246    // Normal Browsers
247    else curTransform = parseFloat(matrix[4]);
248  }
249  if (axis === 'y') {
250    // Latest Chrome and webkits Fix
251    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
252    // Crazy IE10 Matrix
253    else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
254    // Normal Browsers
255    else curTransform = parseFloat(matrix[5]);
256  }
257  return curTransform || 0;
258}
259function isObject(o) {
260  return (
261    typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object'
262  );
263}
264function isNode(node) {
265  // eslint-disable-next-line
266  if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
267    return node instanceof HTMLElement;
268  }
269  return node && (node.nodeType === 1 || node.nodeType === 11);
270}
271function extend() {
272  const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
273  const noExtend = ['__proto__', 'constructor', 'prototype'];
274  for (let i = 1; i < arguments.length; i += 1) {
275    const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
276    if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
277      const keysArray = Object.keys(Object(nextSource)).filter((key) => noExtend.indexOf(key) < 0);
278      for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
279        const nextKey = keysArray[nextIndex];
280        const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
281        if (desc !== undefined && desc.enumerable) {
282          if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
283            if (nextSource[nextKey].__swiper__) {
284              to[nextKey] = nextSource[nextKey];
285            } else {
286              extend(to[nextKey], nextSource[nextKey]);
287            }
288          } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
289            to[nextKey] = {};
290            if (nextSource[nextKey].__swiper__) {
291              to[nextKey] = nextSource[nextKey];
292            } else {
293              extend(to[nextKey], nextSource[nextKey]);
294            }
295          } else {
296            to[nextKey] = nextSource[nextKey];
297          }
298        }
299      }
300    }
301  }
302  return to;
303}
304function setCSSProperty(el, varName, varValue) {
305  el.style.setProperty(varName, varValue);
306}
307function animateCSSModeScroll(_ref) {
308  let { swiper, targetPosition, side } = _ref;
309  const window = getWindow();
310  const startPosition = -swiper.translate;
311  let startTime = null;
312  let time;
313  const duration = swiper.params.speed;
314  swiper.wrapperEl.style.scrollSnapType = 'none';
315  window.cancelAnimationFrame(swiper.cssModeFrameID);
316  const dir = targetPosition > startPosition ? 'next' : 'prev';
317  const isOutOfBound = (current, target) => {
318    return (dir === 'next' && current >= target) || (dir === 'prev' && current <= target);
319  };
320  const animate = () => {
321    time = new Date().getTime();
322    if (startTime === null) {
323      startTime = time;
324    }
325    const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
326    const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
327    let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
328    if (isOutOfBound(currentPosition, targetPosition)) {
329      currentPosition = targetPosition;
330    }
331    swiper.wrapperEl.scrollTo({
332      [side]: currentPosition,
333    });
334    if (isOutOfBound(currentPosition, targetPosition)) {
335      swiper.wrapperEl.style.overflow = 'hidden';
336      swiper.wrapperEl.style.scrollSnapType = '';
337      setTimeout(() => {
338        swiper.wrapperEl.style.overflow = '';
339        swiper.wrapperEl.scrollTo({
340          [side]: currentPosition,
341        });
342      });
343      window.cancelAnimationFrame(swiper.cssModeFrameID);
344      return;
345    }
346    swiper.cssModeFrameID = window.requestAnimationFrame(animate);
347  };
348  animate();
349}
350function getSlideTransformEl(slideEl) {
351  return (
352    slideEl.querySelector('.swiper-slide-transform') ||
353    (slideEl.shadowEl && slideEl.shadowEl.querySelector('.swiper-slide-transform')) ||
354    slideEl
355  );
356}
357function elementChildren(element, selector) {
358  if (selector === void 0) {
359    selector = '';
360  }
361  return [...element.children].filter((el) => el.matches(selector));
362}
363function createElement(tag, classes) {
364  if (classes === void 0) {
365    classes = [];
366  }
367  const el = document.createElement(tag);
368  el.classList.add(...(Array.isArray(classes) ? classes : [classes]));
369  return el;
370}
371function elementOffset(el) {
372  const window = getWindow();
373  const document = getDocument();
374  const box = el.getBoundingClientRect();
375  const body = document.body;
376  const clientTop = el.clientTop || body.clientTop || 0;
377  const clientLeft = el.clientLeft || body.clientLeft || 0;
378  const scrollTop = el === window ? window.scrollY : el.scrollTop;
379  const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
380  return {
381    top: box.top + scrollTop - clientTop,
382    left: box.left + scrollLeft - clientLeft,
383  };
384}
385function elementPrevAll(el, selector) {
386  const prevEls = [];
387  while (el.previousElementSibling) {
388    const prev = el.previousElementSibling; // eslint-disable-line
389    if (selector) {
390      if (prev.matches(selector)) prevEls.push(prev);
391    } else prevEls.push(prev);
392    el = prev;
393  }
394  return prevEls;
395}
396function elementNextAll(el, selector) {
397  const nextEls = [];
398  while (el.nextElementSibling) {
399    const next = el.nextElementSibling; // eslint-disable-line
400    if (selector) {
401      if (next.matches(selector)) nextEls.push(next);
402    } else nextEls.push(next);
403    el = next;
404  }
405  return nextEls;
406}
407function elementStyle(el, prop) {
408  const window = getWindow();
409  return window.getComputedStyle(el, null).getPropertyValue(prop);
410}
411function elementIndex(el) {
412  let child = el;
413  let i;
414  if (child) {
415    i = 0;
416    // eslint-disable-next-line
417    while ((child = child.previousSibling) !== null) {
418      if (child.nodeType === 1) i += 1;
419    }
420    return i;
421  }
422  return undefined;
423}
424function elementParents(el, selector) {
425  const parents = []; // eslint-disable-line
426  let parent = el.parentElement; // eslint-disable-line
427  while (parent) {
428    if (selector) {
429      if (parent.matches(selector)) parents.push(parent);
430    } else {
431      parents.push(parent);
432    }
433    parent = parent.parentElement;
434  }
435  return parents;
436}
437function elementTransitionEnd(el, callback) {
438  function fireCallBack(e) {
439    if (e.target !== el) return;
440    callback.call(el, e);
441    el.removeEventListener('transitionend', fireCallBack);
442  }
443  if (callback) {
444    el.addEventListener('transitionend', fireCallBack);
445  }
446}
447function elementOuterSize(el, size, includeMargins) {
448  const window = getWindow();
449  if (includeMargins) {
450    return (
451      el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] +
452      parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) +
453      parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'))
454    );
455  }
456  return el.offsetWidth;
457}
458
459let support;
460function calcSupport() {
461  const window = getWindow();
462  const document = getDocument();
463  return {
464    smoothScroll:
465      document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
466    touch: !!('ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch)),
467  };
468}
vendor: 18,213 bytes, lines 469-994
469function getSupport() {
470  if (!support) {
471    support = calcSupport();
472  }
473  return support;
474}
475
476let deviceCached;
477function calcDevice(_temp) {
478  let { userAgent } = _temp === void 0 ? {} : _temp;
479  const support = getSupport();
480  const window = getWindow();
481  const platform = window.navigator.platform;
482  const ua = userAgent || window.navigator.userAgent;
483  const device = {
484    ios: false,
485    android: false,
486  };
487  const screenWidth = window.screen.width;
488  const screenHeight = window.screen.height;
489  const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
490  let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
491  const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
492  const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
493  const windows = platform === 'Win32';
494  let macos = platform === 'MacIntel';
495
496  // iPadOs 13 fix
497  const iPadScreens = [
498    '1024x1366',
499    '1366x1024',
500    '834x1194',
501    '1194x834',
502    '834x1112',
503    '1112x834',
504    '768x1024',
505    '1024x768',
506    '820x1180',
507    '1180x820',
508    '810x1080',
509    '1080x810',
510  ];
511  if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
512    ipad = ua.match(/(Version)\/([\d.]+)/);
513    if (!ipad) ipad = [0, 1, '13_0_0'];
514    macos = false;
515  }
516
517  // Android
518  if (android && !windows) {
519    device.os = 'android';
520    device.android = true;
521  }
522  if (ipad || iphone || ipod) {
523    device.os = 'ios';
524    device.ios = true;
525  }
526
527  // Export object
528  return device;
529}
530function getDevice(overrides) {
531  if (overrides === void 0) {
532    overrides = {};
533  }
534  if (!deviceCached) {
535    deviceCached = calcDevice(overrides);
536  }
537  return deviceCached;
538}
539
540let browser;
541function calcBrowser() {
542  const window = getWindow();
543  let needPerspectiveFix = false;
544  function isSafari() {
545    const ua = window.navigator.userAgent.toLowerCase();
546    return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
547  }
548  if (isSafari()) {
549    const ua = String(window.navigator.userAgent);
550    if (ua.includes('Version/')) {
551      const [major, minor] = ua
552        .split('Version/')[1]
553        .split(' ')[0]
554        .split('.')
555        .map((num) => Number(num));
556      needPerspectiveFix = major < 16 || (major === 16 && minor < 2);
557    }
558  }
559  return {
560    isSafari: needPerspectiveFix || isSafari(),
561    needPerspectiveFix,
562    isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent),
563  };
564}
565function getBrowser() {
566  if (!browser) {
567    browser = calcBrowser();
568  }
569  return browser;
570}
571
572function Resize(_ref) {
573  let { swiper, on, emit } = _ref;
574  const window = getWindow();
575  let observer = null;
576  let animationFrame = null;
577  const resizeHandler = () => {
578    if (!swiper || swiper.destroyed || !swiper.initialized) return;
579    emit('beforeResize');
580    emit('resize');
581  };
582  const createObserver = () => {
583    if (!swiper || swiper.destroyed || !swiper.initialized) return;
584    observer = new ResizeObserver((entries) => {
585      animationFrame = window.requestAnimationFrame(() => {
586        const { width, height } = swiper;
587        let newWidth = width;
588        let newHeight = height;
589        entries.forEach((_ref2) => {
590          let { contentBoxSize, contentRect, target } = _ref2;
591          if (target && target !== swiper.el) return;
592          newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
593          newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
594        });
595        if (newWidth !== width || newHeight !== height) {
596          resizeHandler();
597        }
598      });
599    });
600    observer.observe(swiper.el);
601  };
602  const removeObserver = () => {
603    if (animationFrame) {
604      window.cancelAnimationFrame(animationFrame);
605    }
606    if (observer && observer.unobserve && swiper.el) {
607      observer.unobserve(swiper.el);
608      observer = null;
609    }
610  };
611  const orientationChangeHandler = () => {
612    if (!swiper || swiper.destroyed || !swiper.initialized) return;
613    emit('orientationchange');
614  };
615  on('init', () => {
616    if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
617      createObserver();
618      return;
619    }
620    window.addEventListener('resize', resizeHandler);
621    window.addEventListener('orientationchange', orientationChangeHandler);
622  });
623  on('destroy', () => {
624    removeObserver();
625    window.removeEventListener('resize', resizeHandler);
626    window.removeEventListener('orientationchange', orientationChangeHandler);
627  });
628}
629
630function Observer(_ref) {
631  let { swiper, extendParams, on, emit } = _ref;
632  const observers = [];
633  const window = getWindow();
634  const attach = function (target, options) {
635    if (options === void 0) {
636      options = {};
637    }
638    const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
639    const observer = new ObserverFunc((mutations) => {
640      // The observerUpdate event should only be triggered
641      // once despite the number of mutations.  Additional
642      // triggers are redundant and are very costly
643      if (swiper.__preventObserver__) return;
644      if (mutations.length === 1) {
645        emit('observerUpdate', mutations[0]);
646        return;
647      }
648      const observerUpdate = function observerUpdate() {
649        emit('observerUpdate', mutations[0]);
650      };
651      if (window.requestAnimationFrame) {
652        window.requestAnimationFrame(observerUpdate);
653      } else {
654        window.setTimeout(observerUpdate, 0);
655      }
656    });
657    observer.observe(target, {
658      attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
659      childList: typeof options.childList === 'undefined' ? true : options.childList,
660      characterData: typeof options.characterData === 'undefined' ? true : options.characterData,
661    });
662    observers.push(observer);
663  };
664  const init = () => {
665    if (!swiper.params.observer) return;
666    if (swiper.params.observeParents) {
667      const containerParents = elementParents(swiper.el);
668      for (let i = 0; i < containerParents.length; i += 1) {
669        attach(containerParents[i]);
670      }
671    }
672    // Observe container
673    attach(swiper.el, {
674      childList: swiper.params.observeSlideChildren,
675    });
676
677    // Observe wrapper
678    attach(swiper.wrapperEl, {
679      attributes: false,
680    });
681  };
682  const destroy = () => {
683    observers.forEach((observer) => {
684      observer.disconnect();
685    });
686    observers.splice(0, observers.length);
687  };
688  extendParams({
689    observer: false,
690    observeParents: false,
691    observeSlideChildren: false,
692  });
693  on('init', init);
694  on('destroy', destroy);
695}
696
697/* eslint-disable no-underscore-dangle */
698
699var eventsEmitter = {
700  on(events, handler, priority) {
701    const self = this;
702    if (!self.eventsListeners || self.destroyed) return self;
703    if (typeof handler !== 'function') return self;
704    const method = priority ? 'unshift' : 'push';
705    events.split(' ').forEach((event) => {
706      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
707      self.eventsListeners[event][method](handler);
708    });
709    return self;
710  },
711  once(events, handler, priority) {
712    const self = this;
713    if (!self.eventsListeners || self.destroyed) return self;
714    if (typeof handler !== 'function') return self;
715    function onceHandler() {
716      self.off(events, onceHandler);
717      if (onceHandler.__emitterProxy) {
718        delete onceHandler.__emitterProxy;
719      }
720      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
721        args[_key] = arguments[_key];
722      }
723      handler.apply(self, args);
724    }
725    onceHandler.__emitterProxy = handler;
726    return self.on(events, onceHandler, priority);
727  },
728  onAny(handler, priority) {
729    const self = this;
730    if (!self.eventsListeners || self.destroyed) return self;
731    if (typeof handler !== 'function') return self;
732    const method = priority ? 'unshift' : 'push';
733    if (self.eventsAnyListeners.indexOf(handler) < 0) {
734      self.eventsAnyListeners[method](handler);
735    }
736    return self;
737  },
738  offAny(handler) {
739    const self = this;
740    if (!self.eventsListeners || self.destroyed) return self;
741    if (!self.eventsAnyListeners) return self;
742    const index = self.eventsAnyListeners.indexOf(handler);
743    if (index >= 0) {
744      self.eventsAnyListeners.splice(index, 1);
745    }
746    return self;
747  },
748  off(events, handler) {
749    const self = this;
750    if (!self.eventsListeners || self.destroyed) return self;
751    if (!self.eventsListeners) return self;
752    events.split(' ').forEach((event) => {
753      if (typeof handler === 'undefined') {
754        self.eventsListeners[event] = [];
755      } else if (self.eventsListeners[event]) {
756        self.eventsListeners[event].forEach((eventHandler, index) => {
757          if (eventHandler === handler || (eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler)) {
758            self.eventsListeners[event].splice(index, 1);
759          }
760        });
761      }
762    });
763    return self;
764  },
765  emit() {
766    const self = this;
767    if (!self.eventsListeners || self.destroyed) return self;
768    if (!self.eventsListeners) return self;
769    let events;
770    let data;
771    let context;
772    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
773      args[_key2] = arguments[_key2];
774    }
775    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
776      events = args[0];
777      data = args.slice(1, args.length);
778      context = self;
779    } else {
780      events = args[0].events;
781      data = args[0].data;
782      context = args[0].context || self;
783    }
784    data.unshift(context);
785    const eventsArray = Array.isArray(events) ? events : events.split(' ');
786    eventsArray.forEach((event) => {
787      if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
788        self.eventsAnyListeners.forEach((eventHandler) => {
789          eventHandler.apply(context, [event, ...data]);
790        });
791      }
792      if (self.eventsListeners && self.eventsListeners[event]) {
793        self.eventsListeners[event].forEach((eventHandler) => {
794          eventHandler.apply(context, data);
795        });
796      }
797    });
798    return self;
799  },
800};
801
802function updateSize() {
803  const swiper = this;
804  let width;
805  let height;
806  const el = swiper.el;
807  if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
808    width = swiper.params.width;
809  } else {
810    width = el.clientWidth;
811  }
812  if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
813    height = swiper.params.height;
814  } else {
815    height = el.clientHeight;
816  }
817  if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) {
818    return;
819  }
820
821  // Subtract paddings
822  width =
823    width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
824  height =
825    height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
826  if (Number.isNaN(width)) width = 0;
827  if (Number.isNaN(height)) height = 0;
828  Object.assign(swiper, {
829    width,
830    height,
831    size: swiper.isHorizontal() ? width : height,
832  });
833}
834
835function updateSlides() {
836  const swiper = this;
837  function getDirectionLabel(property) {
838    if (swiper.isHorizontal()) {
839      return property;
840    }
841    // prettier-ignore
842    return {
843        'width': 'height',
844        'margin-top': 'margin-left',
845        'margin-bottom ': 'margin-right',
846        'margin-left': 'margin-top',
847        'margin-right': 'margin-bottom',
848        'padding-left': 'padding-top',
849        'padding-right': 'padding-bottom',
850        'marginRight': 'marginBottom'
851      }[property];
852  }
853  function getDirectionPropertyValue(node, label) {
854    return parseFloat(node.getPropertyValue(getDirectionLabel(label)) || 0);
855  }
856  const params = swiper.params;
857  const { wrapperEl, slidesEl, size: swiperSize, rtlTranslate: rtl, wrongRTL } = swiper;
858  const isVirtual = swiper.virtual && params.virtual.enabled;
859  const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
860  const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
861  const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
862  let snapGrid = [];
863  const slidesGrid = [];
864  const slidesSizesGrid = [];
865  let offsetBefore = params.slidesOffsetBefore;
866  if (typeof offsetBefore === 'function') {
867    offsetBefore = params.slidesOffsetBefore.call(swiper);
868  }
869  let offsetAfter = params.slidesOffsetAfter;
870  if (typeof offsetAfter === 'function') {
871    offsetAfter = params.slidesOffsetAfter.call(swiper);
872  }
873  const previousSnapGridLength = swiper.snapGrid.length;
874  const previousSlidesGridLength = swiper.slidesGrid.length;
875  let spaceBetween = params.spaceBetween;
876  let slidePosition = -offsetBefore;
877  let prevSlideSize = 0;
878  let index = 0;
879  if (typeof swiperSize === 'undefined') {
880    return;
881  }
882  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
883    spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize;
884  } else if (typeof spaceBetween === 'string') {
885    spaceBetween = parseFloat(spaceBetween);
886  }
887  swiper.virtualSize = -spaceBetween;
888
889  // reset margins
890  slides.forEach((slideEl) => {
891    if (rtl) {
892      slideEl.style.marginLeft = '';
893    } else {
894      slideEl.style.marginRight = '';
895    }
896    slideEl.style.marginBottom = '';
897    slideEl.style.marginTop = '';
898  });
899
900  // reset cssMode offsets
901  if (params.centeredSlides && params.cssMode) {
902    setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
903    setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
904  }
905  const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
906  if (gridEnabled) {
907    swiper.grid.initSlides(slidesLength);
908  }
909
910  // Calc slides
911  let slideSize;
912  const shouldResetSlideSize =
913    params.slidesPerView === 'auto' &&
914    params.breakpoints &&
915    Object.keys(params.breakpoints).filter((key) => {
916      return typeof params.breakpoints[key].slidesPerView !== 'undefined';
917    }).length > 0;
918  for (let i = 0; i < slidesLength; i += 1) {
919    slideSize = 0;
920    let slide;
921    if (slides[i]) slide = slides[i];
922    if (gridEnabled) {
923      swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);
924    }
925    if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
926
927    if (params.slidesPerView === 'auto') {
928      if (shouldResetSlideSize) {
929        slides[i].style[getDirectionLabel('width')] = ``;
930      }
931      const slideStyles = getComputedStyle(slide);
932      const currentTransform = slide.style.transform;
933      const currentWebKitTransform = slide.style.webkitTransform;
934      if (currentTransform) {
935        slide.style.transform = 'none';
936      }
937      if (currentWebKitTransform) {
938        slide.style.webkitTransform = 'none';
939      }
940      if (params.roundLengths) {
941        slideSize = swiper.isHorizontal()
942          ? elementOuterSize(slide, 'width', true)
943          : elementOuterSize(slide, 'height', true);
944      } else {
945        // eslint-disable-next-line
946        const width = getDirectionPropertyValue(slideStyles, 'width');
947        const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
948        const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
949        const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
950        const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
951        const boxSizing = slideStyles.getPropertyValue('box-sizing');
952        if (boxSizing && boxSizing === 'border-box') {
953          slideSize = width + marginLeft + marginRight;
954        } else {
955          const { clientWidth, offsetWidth } = slide;
956          slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
957        }
958      }
959      if (currentTransform) {
960        slide.style.transform = currentTransform;
961      }
962      if (currentWebKitTransform) {
963        slide.style.webkitTransform = currentWebKitTransform;
964      }
965      if (params.roundLengths) slideSize = Math.floor(slideSize);
966    } else {
967      slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
968      if (params.roundLengths) slideSize = Math.floor(slideSize);
969      if (slides[i]) {
970        slides[i].style[getDirectionLabel('width')] = `${slideSize}px`;
971      }
972    }
973    if (slides[i]) {
974      slides[i].swiperSlideSize = slideSize;
975    }
976    slidesSizesGrid.push(slideSize);
977    if (params.centeredSlides) {
978      slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
979      if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
980      if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
981      if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
982      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
983      if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
984      slidesGrid.push(slidePosition);
985    } else {
986      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
987      if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0)
988        snapGrid.push(slidePosition);
989      slidesGrid.push(slidePosition);
990      slidePosition = slidePosition + slideSize + spaceBetween;
991    }
992    swiper.virtualSize += slideSize + spaceBetween;
993    prevSlideSize = slideSize;
994    index += 1;
vendor: 1,886 bytes, lines 995-1039
995  }
996  swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
997  if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
998    wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
999  }
1000  if (params.setWrapperSize) {
1001    wrapperEl.style[getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
1002  }
1003  if (gridEnabled) {
1004    swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel);
1005  }
1006
1007  // Remove last grid elements depending on width
1008  if (!params.centeredSlides) {
1009    const newSlidesGrid = [];
1010    for (let i = 0; i < snapGrid.length; i += 1) {
1011      let slidesGridItem = snapGrid[i];
1012      if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
1013      if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
1014        newSlidesGrid.push(slidesGridItem);
1015      }
1016    }
1017    snapGrid = newSlidesGrid;
1018    if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
1019      snapGrid.push(swiper.virtualSize - swiperSize);
1020    }
1021  }
1022  if (isVirtual && params.loop) {
1023    const size = slidesSizesGrid[0] + spaceBetween;
1024    if (params.slidesPerGroup > 1) {
1025      const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
1026      const groupSize = size * params.slidesPerGroup;
1027      for (let i = 0; i < groups; i += 1) {
1028        snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
1029      }
1030    }
1031    for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
1032      if (params.slidesPerGroup === 1) {
1033        snapGrid.push(snapGrid[snapGrid.length - 1] + size);
1034      }
1035      slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
1036      swiper.virtualSize += size;
1037    }
1038  }
1039  if (snapGrid.length === 0) snapGrid = [0];
vendor: 9,466 bytes, lines 1040-1292
1040  if (spaceBetween !== 0) {
1041    const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');
1042    slides
1043      .filter((_, slideIndex) => {
1044        if (!params.cssMode || params.loop) return true;
1045        if (slideIndex === slides.length - 1) {
1046          return false;
1047        }
1048        return true;
1049      })
1050      .forEach((slideEl) => {
1051        slideEl.style[key] = `${spaceBetween}px`;
1052      });
1053  }
1054  if (params.centeredSlides && params.centeredSlidesBounds) {
1055    let allSlidesSize = 0;
1056    slidesSizesGrid.forEach((slideSizeValue) => {
1057      allSlidesSize += slideSizeValue + (spaceBetween || 0);
1058    });
1059    allSlidesSize -= spaceBetween;
1060    const maxSnap = allSlidesSize - swiperSize;
1061    snapGrid = snapGrid.map((snap) => {
1062      if (snap <= 0) return -offsetBefore;
1063      if (snap > maxSnap) return maxSnap + offsetAfter;
1064      return snap;
1065    });
1066  }
1067  if (params.centerInsufficientSlides) {
1068    let allSlidesSize = 0;
1069    slidesSizesGrid.forEach((slideSizeValue) => {
1070      allSlidesSize += slideSizeValue + (spaceBetween || 0);
1071    });
1072    allSlidesSize -= spaceBetween;
1073    if (allSlidesSize < swiperSize) {
1074      const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
1075      snapGrid.forEach((snap, snapIndex) => {
1076        snapGrid[snapIndex] = snap - allSlidesOffset;
1077      });
1078      slidesGrid.forEach((snap, snapIndex) => {
1079        slidesGrid[snapIndex] = snap + allSlidesOffset;
1080      });
1081    }
1082  }
1083  Object.assign(swiper, {
1084    slides,
1085    snapGrid,
1086    slidesGrid,
1087    slidesSizesGrid,
1088  });
1089  if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
1090    setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
1091    setCSSProperty(
1092      wrapperEl,
1093      '--swiper-centered-offset-after',
1094      `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`
1095    );
1096    const addToSnapGrid = -swiper.snapGrid[0];
1097    const addToSlidesGrid = -swiper.slidesGrid[0];
1098    swiper.snapGrid = swiper.snapGrid.map((v) => v + addToSnapGrid);
1099    swiper.slidesGrid = swiper.slidesGrid.map((v) => v + addToSlidesGrid);
1100  }
1101  if (slidesLength !== previousSlidesLength) {
1102    swiper.emit('slidesLengthChange');
1103  }
1104  if (snapGrid.length !== previousSnapGridLength) {
1105    if (swiper.params.watchOverflow) swiper.checkOverflow();
1106    swiper.emit('snapGridLengthChange');
1107  }
1108  if (slidesGrid.length !== previousSlidesGridLength) {
1109    swiper.emit('slidesGridLengthChange');
1110  }
1111  if (params.watchSlidesProgress) {
1112    swiper.updateSlidesOffset();
1113  }
1114  if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
1115    const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
1116    const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
1117    if (slidesLength <= params.maxBackfaceHiddenSlides) {
1118      if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
1119    } else if (hasClassBackfaceClassAdded) {
1120      swiper.el.classList.remove(backFaceHiddenClass);
1121    }
1122  }
1123}
1124
1125function updateAutoHeight(speed) {
1126  const swiper = this;
1127  const activeSlides = [];
1128  const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1129  let newHeight = 0;
1130  let i;
1131  if (typeof speed === 'number') {
1132    swiper.setTransition(speed);
1133  } else if (speed === true) {
1134    swiper.setTransition(swiper.params.speed);
1135  }
1136  const getSlideByIndex = (index) => {
1137    if (isVirtual) {
1138      return swiper.slides[swiper.getSlideIndexByData(index)];
1139    }
1140    return swiper.slides[index];
1141  };
1142  // Find slides currently in view
1143  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
1144    if (swiper.params.centeredSlides) {
1145      (swiper.visibleSlides || []).forEach((slide) => {
1146        activeSlides.push(slide);
1147      });
1148    } else {
1149      for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
1150        const index = swiper.activeIndex + i;
1151        if (index > swiper.slides.length && !isVirtual) break;
1152        activeSlides.push(getSlideByIndex(index));
1153      }
1154    }
1155  } else {
1156    activeSlides.push(getSlideByIndex(swiper.activeIndex));
1157  }
1158
1159  // Find new height from highest slide in view
1160  for (i = 0; i < activeSlides.length; i += 1) {
1161    if (typeof activeSlides[i] !== 'undefined') {
1162      const height = activeSlides[i].offsetHeight;
1163      newHeight = height > newHeight ? height : newHeight;
1164    }
1165  }
1166
1167  // Update Height
1168  if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
1169}
1170
1171function updateSlidesOffset() {
1172  const swiper = this;
1173  const slides = swiper.slides;
1174  // eslint-disable-next-line
1175  const minusOffset = swiper.isElement
1176    ? swiper.isHorizontal()
1177      ? swiper.wrapperEl.offsetLeft
1178      : swiper.wrapperEl.offsetTop
1179    : 0;
1180  for (let i = 0; i < slides.length; i += 1) {
1181    slides[i].swiperSlideOffset =
1182      (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) -
1183      minusOffset -
1184      swiper.cssOverflowAdjustment();
1185  }
1186}
1187
1188function updateSlidesProgress(translate) {
1189  if (translate === void 0) {
1190    translate = (this && this.translate) || 0;
1191  }
1192  const swiper = this;
1193  const params = swiper.params;
1194  const { slides, rtlTranslate: rtl, snapGrid } = swiper;
1195  if (slides.length === 0) return;
1196  if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
1197  let offsetCenter = -translate;
1198  if (rtl) offsetCenter = translate;
1199
1200  // Visible Slides
1201  slides.forEach((slideEl) => {
1202    slideEl.classList.remove(params.slideVisibleClass);
1203  });
1204  swiper.visibleSlidesIndexes = [];
1205  swiper.visibleSlides = [];
1206  let spaceBetween = params.spaceBetween;
1207  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
1208    spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiper.size;
1209  } else if (typeof spaceBetween === 'string') {
1210    spaceBetween = parseFloat(spaceBetween);
1211  }
1212  for (let i = 0; i < slides.length; i += 1) {
1213    const slide = slides[i];
1214    let slideOffset = slide.swiperSlideOffset;
1215    if (params.cssMode && params.centeredSlides) {
1216      slideOffset -= slides[0].swiperSlideOffset;
1217    }
1218    const slideProgress =
1219      (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) /
1220      (slide.swiperSlideSize + spaceBetween);
1221    const originalSlideProgress =
1222      (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) /
1223      (slide.swiperSlideSize + spaceBetween);
1224    const slideBefore = -(offsetCenter - slideOffset);
1225    const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
1226    const isVisible =
1227      (slideBefore >= 0 && slideBefore < swiper.size - 1) ||
1228      (slideAfter > 1 && slideAfter <= swiper.size) ||
1229      (slideBefore <= 0 && slideAfter >= swiper.size);
1230    if (isVisible) {
1231      swiper.visibleSlides.push(slide);
1232      swiper.visibleSlidesIndexes.push(i);
1233      slides[i].classList.add(params.slideVisibleClass);
1234    }
1235    slide.progress = rtl ? -slideProgress : slideProgress;
1236    slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
1237  }
1238}
1239
1240function updateProgress(translate) {
1241  const swiper = this;
1242  if (typeof translate === 'undefined') {
1243    const multiplier = swiper.rtlTranslate ? -1 : 1;
1244    // eslint-disable-next-line
1245    translate = (swiper && swiper.translate && swiper.translate * multiplier) || 0;
1246  }
1247  const params = swiper.params;
1248  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1249  let { progress, isBeginning, isEnd, progressLoop } = swiper;
1250  const wasBeginning = isBeginning;
1251  const wasEnd = isEnd;
1252  if (translatesDiff === 0) {
1253    progress = 0;
1254    isBeginning = true;
1255    isEnd = true;
1256  } else {
1257    progress = (translate - swiper.minTranslate()) / translatesDiff;
1258    const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
1259    const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
1260    isBeginning = isBeginningRounded || progress <= 0;
1261    isEnd = isEndRounded || progress >= 1;
1262    if (isBeginningRounded) progress = 0;
1263    if (isEndRounded) progress = 1;
1264  }
1265  if (params.loop) {
1266    const firstSlideIndex = swiper.getSlideIndexByData(0);
1267    const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
1268    const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
1269    const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
1270    const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
1271    const translateAbs = Math.abs(translate);
1272    if (translateAbs >= firstSlideTranslate) {
1273      progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
1274    } else {
1275      progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
1276    }
1277    if (progressLoop > 1) progressLoop -= 1;
1278  }
1279  Object.assign(swiper, {
1280    progress,
1281    progressLoop,
1282    isBeginning,
1283    isEnd,
1284  });
1285  if (params.watchSlidesProgress || (params.centeredSlides && params.autoHeight))
1286    swiper.updateSlidesProgress(translate);
1287  if (isBeginning && !wasBeginning) {
1288    swiper.emit('reachBeginning toEdge');
1289  }
1290  if (isEnd && !wasEnd) {
1291    swiper.emit('reachEnd toEdge');
1292  }
vendor: 8,718 bytes, lines 1293-1548
1293  if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) {
1294    swiper.emit('fromEdge');
1295  }
1296  swiper.emit('progress', progress);
1297}
1298
1299function updateSlidesClasses() {
1300  const swiper = this;
1301  const { slides, params, slidesEl, activeIndex } = swiper;
1302  const isVirtual = swiper.virtual && params.virtual.enabled;
1303  const getFilteredSlide = (selector) => {
1304    return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
1305  };
1306  slides.forEach((slideEl) => {
1307    slideEl.classList.remove(params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
1308  });
1309  let activeSlide;
1310  if (isVirtual) {
1311    if (params.loop) {
1312      let slideIndex = activeIndex - swiper.virtual.slidesBefore;
1313      if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
1314      if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
1315      activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
1316    } else {
1317      activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
1318    }
1319  } else {
1320    activeSlide = slides[activeIndex];
1321  }
1322  if (activeSlide) {
1323    // Active classes
1324    activeSlide.classList.add(params.slideActiveClass);
1325
1326    // Next Slide
1327    let nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1328    if (params.loop && !nextSlide) {
1329      nextSlide = slides[0];
1330    }
1331    if (nextSlide) {
1332      nextSlide.classList.add(params.slideNextClass);
1333    }
1334    // Prev Slide
1335    let prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
1336    if (params.loop && !prevSlide === 0) {
1337      prevSlide = slides[slides.length - 1];
1338    }
1339    if (prevSlide) {
1340      prevSlide.classList.add(params.slidePrevClass);
1341    }
1342  }
1343  swiper.emitSlidesClasses();
1344}
1345
1346const processLazyPreloader = (swiper, imageEl) => {
1347  if (!swiper || swiper.destroyed || !swiper.params) return;
1348  const slideSelector = () => (swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`);
1349  const slideEl = imageEl.closest(slideSelector());
1350  if (slideEl) {
1351    const lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
1352    if (lazyEl) lazyEl.remove();
1353  }
1354};
1355const unlazy = (swiper, index) => {
1356  if (!swiper.slides[index]) return;
1357  const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
1358  if (imageEl) imageEl.removeAttribute('loading');
1359};
1360const preload = (swiper) => {
1361  if (!swiper || swiper.destroyed || !swiper.params) return;
1362  let amount = swiper.params.lazyPreloadPrevNext;
1363  const len = swiper.slides.length;
1364  if (!len || !amount || amount < 0) return;
1365  amount = Math.min(amount, len);
1366  const slidesPerView =
1367    swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
1368  const activeIndex = swiper.activeIndex;
1369  if (swiper.params.grid && swiper.params.grid.rows > 1) {
1370    const activeColumn = activeIndex;
1371    const preloadColumns = [activeColumn - amount];
1372    preloadColumns.push(
1373      ...Array.from({
1374        length: amount,
1375      }).map((_, i) => {
1376        return activeColumn + slidesPerView + i;
1377      })
1378    );
1379    swiper.slides.forEach((slideEl, i) => {
1380      if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
1381    });
1382    return;
1383  }
1384  const slideIndexLastInView = activeIndex + slidesPerView - 1;
1385  if (swiper.params.rewind || swiper.params.loop) {
1386    for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
1387      const realIndex = ((i % len) + len) % len;
1388      if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
1389    }
1390  } else {
1391    for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
1392      if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
1393        unlazy(swiper, i);
1394      }
1395    }
1396  }
1397};
1398
1399function getActiveIndexByTranslate(swiper) {
1400  const { slidesGrid, params } = swiper;
1401  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1402  let activeIndex;
1403  for (let i = 0; i < slidesGrid.length; i += 1) {
1404    if (typeof slidesGrid[i + 1] !== 'undefined') {
1405      if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
1406        activeIndex = i;
1407      } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
1408        activeIndex = i + 1;
1409      }
1410    } else if (translate >= slidesGrid[i]) {
1411      activeIndex = i;
1412    }
1413  }
1414  // Normalize slideIndex
1415  if (params.normalizeSlideIndex) {
1416    if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
1417  }
1418  return activeIndex;
1419}
1420function updateActiveIndex(newActiveIndex) {
1421  const swiper = this;
1422  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
1423  const {
1424    snapGrid,
1425    params,
1426    activeIndex: previousIndex,
1427    realIndex: previousRealIndex,
1428    snapIndex: previousSnapIndex,
1429  } = swiper;
1430  let activeIndex = newActiveIndex;
1431  let snapIndex;
1432  const getVirtualRealIndex = (aIndex) => {
1433    let realIndex = aIndex - swiper.virtual.slidesBefore;
1434    if (realIndex < 0) {
1435      realIndex = swiper.virtual.slides.length + realIndex;
1436    }
1437    if (realIndex >= swiper.virtual.slides.length) {
1438      realIndex -= swiper.virtual.slides.length;
1439    }
1440    return realIndex;
1441  };
1442  if (typeof activeIndex === 'undefined') {
1443    activeIndex = getActiveIndexByTranslate(swiper);
1444  }
1445  if (snapGrid.indexOf(translate) >= 0) {
1446    snapIndex = snapGrid.indexOf(translate);
1447  } else {
1448    const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
1449    snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
1450  }
1451  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1452  if (activeIndex === previousIndex) {
1453    if (snapIndex !== previousSnapIndex) {
1454      swiper.snapIndex = snapIndex;
1455      swiper.emit('snapIndexChange');
1456    }
1457    if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1458      swiper.realIndex = getVirtualRealIndex(activeIndex);
1459    }
1460    return;
1461  }
1462  // Get real index
1463  let realIndex;
1464  if (swiper.virtual && params.virtual.enabled && params.loop) {
1465    realIndex = getVirtualRealIndex(activeIndex);
1466  } else if (swiper.slides[activeIndex]) {
1467    realIndex = parseInt(swiper.slides[activeIndex].getAttribute('data-swiper-slide-index') || activeIndex, 10);
1468  } else {
1469    realIndex = activeIndex;
1470  }
1471  Object.assign(swiper, {
1472    previousSnapIndex,
1473    snapIndex,
1474    previousRealIndex,
1475    realIndex,
1476    previousIndex,
1477    activeIndex,
1478  });
1479  if (swiper.initialized) {
1480    preload(swiper);
1481  }
1482  swiper.emit('activeIndexChange');
1483  swiper.emit('snapIndexChange');
1484  if (previousRealIndex !== realIndex) {
1485    swiper.emit('realIndexChange');
1486  }
1487  if (swiper.initialized || swiper.params.runCallbacksOnInit) {
1488    swiper.emit('slideChange');
1489  }
1490}
1491
1492function updateClickedSlide(e) {
1493  const swiper = this;
1494  const params = swiper.params;
1495  const slide = e.closest(`.${params.slideClass}, swiper-slide`);
1496  let slideFound = false;
1497  let slideIndex;
1498  if (slide) {
1499    for (let i = 0; i < swiper.slides.length; i += 1) {
1500      if (swiper.slides[i] === slide) {
1501        slideFound = true;
1502        slideIndex = i;
1503        break;
1504      }
1505    }
1506  }
1507  if (slide && slideFound) {
1508    swiper.clickedSlide = slide;
1509    if (swiper.virtual && swiper.params.virtual.enabled) {
1510      swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1511    } else {
1512      swiper.clickedIndex = slideIndex;
1513    }
1514  } else {
1515    swiper.clickedSlide = undefined;
1516    swiper.clickedIndex = undefined;
1517    return;
1518  }
1519  if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
1520    swiper.slideToClickedSlide();
1521  }
1522}
1523
1524var update = {
1525  updateSize,
1526  updateSlides,
1527  updateAutoHeight,
1528  updateSlidesOffset,
1529  updateSlidesProgress,
1530  updateProgress,
1531  updateSlidesClasses,
1532  updateActiveIndex,
1533  updateClickedSlide,
1534};
1535
1536function getSwiperTranslate(axis) {
1537  if (axis === void 0) {
1538    axis = this.isHorizontal() ? 'x' : 'y';
1539  }
1540  const swiper = this;
1541  const { params, rtlTranslate: rtl, translate, wrapperEl } = swiper;
1542  if (params.virtualTranslate) {
1543    return rtl ? -translate : translate;
1544  }
1545  if (params.cssMode) {
1546    return translate;
1547  }
1548  let currentTranslate = getTranslate(wrapperEl, axis);
vendor: 12,859 bytes, lines 1549-1960
1549  currentTranslate += swiper.cssOverflowAdjustment();
1550  if (rtl) currentTranslate = -currentTranslate;
1551  return currentTranslate || 0;
1552}
1553
1554function setTranslate(translate, byController) {
1555  const swiper = this;
1556  const { rtlTranslate: rtl, params, wrapperEl, progress } = swiper;
1557  let x = 0;
1558  let y = 0;
1559  const z = 0;
1560  if (swiper.isHorizontal()) {
1561    x = rtl ? -translate : translate;
1562  } else {
1563    y = translate;
1564  }
1565  if (params.roundLengths) {
1566    x = Math.floor(x);
1567    y = Math.floor(y);
1568  }
1569  swiper.previousTranslate = swiper.translate;
1570  swiper.translate = swiper.isHorizontal() ? x : y;
1571  if (params.cssMode) {
1572    wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1573  } else if (!params.virtualTranslate) {
1574    if (swiper.isHorizontal()) {
1575      x -= swiper.cssOverflowAdjustment();
1576    } else {
1577      y -= swiper.cssOverflowAdjustment();
1578    }
1579    wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
1580  }
1581
1582  // Check if we need to update progress
1583  let newProgress;
1584  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
1585  if (translatesDiff === 0) {
1586    newProgress = 0;
1587  } else {
1588    newProgress = (translate - swiper.minTranslate()) / translatesDiff;
1589  }
1590  if (newProgress !== progress) {
1591    swiper.updateProgress(translate);
1592  }
1593  swiper.emit('setTranslate', swiper.translate, byController);
1594}
1595
1596function minTranslate() {
1597  return -this.snapGrid[0];
1598}
1599
1600function maxTranslate() {
1601  return -this.snapGrid[this.snapGrid.length - 1];
1602}
1603
1604function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
1605  if (translate === void 0) {
1606    translate = 0;
1607  }
1608  if (speed === void 0) {
1609    speed = this.params.speed;
1610  }
1611  if (runCallbacks === void 0) {
1612    runCallbacks = true;
1613  }
1614  if (translateBounds === void 0) {
1615    translateBounds = true;
1616  }
1617  const swiper = this;
1618  const { params, wrapperEl } = swiper;
1619  if (swiper.animating && params.preventInteractionOnTransition) {
1620    return false;
1621  }
1622  const minTranslate = swiper.minTranslate();
1623  const maxTranslate = swiper.maxTranslate();
1624  let newTranslate;
1625  if (translateBounds && translate > minTranslate) newTranslate = minTranslate;
1626  else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;
1627  else newTranslate = translate;
1628
1629  // Update progress
1630  swiper.updateProgress(newTranslate);
1631  if (params.cssMode) {
1632    const isH = swiper.isHorizontal();
1633    if (speed === 0) {
1634      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
1635    } else {
1636      if (!swiper.support.smoothScroll) {
1637        animateCSSModeScroll({
1638          swiper,
1639          targetPosition: -newTranslate,
1640          side: isH ? 'left' : 'top',
1641        });
1642        return true;
1643      }
1644      wrapperEl.scrollTo({
1645        [isH ? 'left' : 'top']: -newTranslate,
1646        behavior: 'smooth',
1647      });
1648    }
1649    return true;
1650  }
1651  if (speed === 0) {
1652    swiper.setTransition(0);
1653    swiper.setTranslate(newTranslate);
1654    if (runCallbacks) {
1655      swiper.emit('beforeTransitionStart', speed, internal);
1656      swiper.emit('transitionEnd');
1657    }
1658  } else {
1659    swiper.setTransition(speed);
1660    swiper.setTranslate(newTranslate);
1661    if (runCallbacks) {
1662      swiper.emit('beforeTransitionStart', speed, internal);
1663      swiper.emit('transitionStart');
1664    }
1665    if (!swiper.animating) {
1666      swiper.animating = true;
1667      if (!swiper.onTranslateToWrapperTransitionEnd) {
1668        swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
1669          if (!swiper || swiper.destroyed) return;
1670          if (e.target !== this) return;
1671          swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1672          swiper.onTranslateToWrapperTransitionEnd = null;
1673          delete swiper.onTranslateToWrapperTransitionEnd;
1674          if (runCallbacks) {
1675            swiper.emit('transitionEnd');
1676          }
1677        };
1678      }
1679      swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
1680    }
1681  }
1682  return true;
1683}
1684
1685var translate = {
1686  getTranslate: getSwiperTranslate,
1687  setTranslate,
1688  minTranslate,
1689  maxTranslate,
1690  translateTo,
1691};
1692
1693function setTransition(duration, byController) {
1694  const swiper = this;
1695  if (!swiper.params.cssMode) {
1696    swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
1697  }
1698  swiper.emit('setTransition', duration, byController);
1699}
1700
1701function transitionEmit(_ref) {
1702  let { swiper, runCallbacks, direction, step } = _ref;
1703  const { activeIndex, previousIndex } = swiper;
1704  let dir = direction;
1705  if (!dir) {
1706    if (activeIndex > previousIndex) dir = 'next';
1707    else if (activeIndex < previousIndex) dir = 'prev';
1708    else dir = 'reset';
1709  }
1710  swiper.emit(`transition${step}`);
1711  if (runCallbacks && activeIndex !== previousIndex) {
1712    if (dir === 'reset') {
1713      swiper.emit(`slideResetTransition${step}`);
1714      return;
1715    }
1716    swiper.emit(`slideChangeTransition${step}`);
1717    if (dir === 'next') {
1718      swiper.emit(`slideNextTransition${step}`);
1719    } else {
1720      swiper.emit(`slidePrevTransition${step}`);
1721    }
1722  }
1723}
1724
1725function transitionStart(runCallbacks, direction) {
1726  if (runCallbacks === void 0) {
1727    runCallbacks = true;
1728  }
1729  const swiper = this;
1730  const { params } = swiper;
1731  if (params.cssMode) return;
1732  if (params.autoHeight) {
1733    swiper.updateAutoHeight();
1734  }
1735  transitionEmit({
1736    swiper,
1737    runCallbacks,
1738    direction,
1739    step: 'Start',
1740  });
1741}
1742
1743function transitionEnd(runCallbacks, direction) {
1744  if (runCallbacks === void 0) {
1745    runCallbacks = true;
1746  }
1747  const swiper = this;
1748  const { params } = swiper;
1749  swiper.animating = false;
1750  if (params.cssMode) return;
1751  swiper.setTransition(0);
1752  transitionEmit({
1753    swiper,
1754    runCallbacks,
1755    direction,
1756    step: 'End',
1757  });
1758}
1759
1760var transition = {
1761  setTransition,
1762  transitionStart,
1763  transitionEnd,
1764};
1765
1766function slideTo(index, speed, runCallbacks, internal, initial) {
1767  if (index === void 0) {
1768    index = 0;
1769  }
1770  if (speed === void 0) {
1771    speed = this.params.speed;
1772  }
1773  if (runCallbacks === void 0) {
1774    runCallbacks = true;
1775  }
1776  if (typeof index === 'string') {
1777    index = parseInt(index, 10);
1778  }
1779  const swiper = this;
1780  let slideIndex = index;
1781  if (slideIndex < 0) slideIndex = 0;
1782  const { params, snapGrid, slidesGrid, previousIndex, activeIndex, rtlTranslate: rtl, wrapperEl, enabled } = swiper;
1783  if ((swiper.animating && params.preventInteractionOnTransition) || (!enabled && !internal && !initial)) {
1784    return false;
1785  }
1786  const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
1787  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1788  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1789  const translate = -snapGrid[snapIndex];
1790  // Normalize slideIndex
1791  if (params.normalizeSlideIndex) {
1792    for (let i = 0; i < slidesGrid.length; i += 1) {
1793      const normalizedTranslate = -Math.floor(translate * 100);
1794      const normalizedGrid = Math.floor(slidesGrid[i] * 100);
1795      const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
1796      if (typeof slidesGrid[i + 1] !== 'undefined') {
1797        if (
1798          normalizedTranslate >= normalizedGrid &&
1799          normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2
1800        ) {
1801          slideIndex = i;
1802        } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
1803          slideIndex = i + 1;
1804        }
1805      } else if (normalizedTranslate >= normalizedGrid) {
1806        slideIndex = i;
1807      }
1808    }
1809  }
1810  // Directions locks
1811  if (swiper.initialized && slideIndex !== activeIndex) {
1812    if (
1813      !swiper.allowSlideNext &&
1814      (rtl
1815        ? translate > swiper.translate && translate > swiper.minTranslate()
1816        : translate < swiper.translate && translate < swiper.minTranslate())
1817    ) {
1818      return false;
1819    }
1820    if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1821      if ((activeIndex || 0) !== slideIndex) {
1822        return false;
1823      }
1824    }
1825  }
1826  if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1827    swiper.emit('beforeSlideChangeStart');
1828  }
1829
1830  // Update progress
1831  swiper.updateProgress(translate);
1832  let direction;
1833  if (slideIndex > activeIndex) direction = 'next';
1834  else if (slideIndex < activeIndex) direction = 'prev';
1835  else direction = 'reset';
1836
1837  // Update Index
1838  if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) {
1839    swiper.updateActiveIndex(slideIndex);
1840    // Update Height
1841    if (params.autoHeight) {
1842      swiper.updateAutoHeight();
1843    }
1844    swiper.updateSlidesClasses();
1845    if (params.effect !== 'slide') {
1846      swiper.setTranslate(translate);
1847    }
1848    if (direction !== 'reset') {
1849      swiper.transitionStart(runCallbacks, direction);
1850      swiper.transitionEnd(runCallbacks, direction);
1851    }
1852    return false;
1853  }
1854  if (params.cssMode) {
1855    const isH = swiper.isHorizontal();
1856    const t = rtl ? translate : -translate;
1857    if (speed === 0) {
1858      const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1859      if (isVirtual) {
1860        swiper.wrapperEl.style.scrollSnapType = 'none';
1861        swiper._immediateVirtual = true;
1862      }
1863      if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1864        swiper._cssModeVirtualInitialSet = true;
1865        requestAnimationFrame(() => {
1866          wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1867        });
1868      } else {
1869        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1870      }
1871      if (isVirtual) {
1872        requestAnimationFrame(() => {
1873          swiper.wrapperEl.style.scrollSnapType = '';
1874          swiper._immediateVirtual = false;
1875        });
1876      }
1877    } else {
1878      if (!swiper.support.smoothScroll) {
1879        animateCSSModeScroll({
1880          swiper,
1881          targetPosition: t,
1882          side: isH ? 'left' : 'top',
1883        });
1884        return true;
1885      }
1886      wrapperEl.scrollTo({
1887        [isH ? 'left' : 'top']: t,
1888        behavior: 'smooth',
1889      });
1890    }
1891    return true;
1892  }
1893  swiper.setTransition(speed);
1894  swiper.setTranslate(translate);
1895  swiper.updateActiveIndex(slideIndex);
1896  swiper.updateSlidesClasses();
1897  swiper.emit('beforeTransitionStart', speed, internal);
1898  swiper.transitionStart(runCallbacks, direction);
1899  if (speed === 0) {
1900    swiper.transitionEnd(runCallbacks, direction);
1901  } else if (!swiper.animating) {
1902    swiper.animating = true;
1903    if (!swiper.onSlideToWrapperTransitionEnd) {
1904      swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
1905        if (!swiper || swiper.destroyed) return;
1906        if (e.target !== this) return;
1907        swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1908        swiper.onSlideToWrapperTransitionEnd = null;
1909        delete swiper.onSlideToWrapperTransitionEnd;
1910        swiper.transitionEnd(runCallbacks, direction);
1911      };
1912    }
1913    swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
1914  }
1915  return true;
1916}
1917
1918function slideToLoop(index, speed, runCallbacks, internal) {
1919  if (index === void 0) {
1920    index = 0;
1921  }
1922  if (speed === void 0) {
1923    speed = this.params.speed;
1924  }
1925  if (runCallbacks === void 0) {
1926    runCallbacks = true;
1927  }
1928  if (typeof index === 'string') {
1929    const indexAsNumber = parseInt(index, 10);
1930    index = indexAsNumber;
1931  }
1932  const swiper = this;
1933  let newIndex = index;
1934  if (swiper.params.loop) {
1935    if (swiper.virtual && swiper.params.virtual.enabled) {
1936      // eslint-disable-next-line
1937      newIndex = newIndex + swiper.virtual.slidesBefore;
1938    } else {
1939      newIndex = swiper.getSlideIndexByData(newIndex);
1940    }
1941  }
1942  return swiper.slideTo(newIndex, speed, runCallbacks, internal);
1943}
1944
1945/* eslint no-unused-vars: "off" */
1946function slideNext(speed, runCallbacks, internal) {
1947  if (speed === void 0) {
1948    speed = this.params.speed;
1949  }
1950  if (runCallbacks === void 0) {
1951    runCallbacks = true;
1952  }
1953  const swiper = this;
1954  const { enabled, params, animating } = swiper;
1955  if (!enabled) return swiper;
1956  let perGroup = params.slidesPerGroup;
1957  if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
1958    perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
1959  }
1960  const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
vendor: 12,679 bytes, lines 1961-2301
1961  const isVirtual = swiper.virtual && params.virtual.enabled;
1962  if (params.loop) {
1963    if (animating && !isVirtual && params.loopPreventsSliding) return false;
1964    swiper.loopFix({
1965      direction: 'next',
1966    });
1967    // eslint-disable-next-line
1968    swiper._clientLeft = swiper.wrapperEl.clientLeft;
1969  }
1970  if (params.rewind && swiper.isEnd) {
1971    return swiper.slideTo(0, speed, runCallbacks, internal);
1972  }
1973  return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
1974}
1975
1976/* eslint no-unused-vars: "off" */
1977function slidePrev(speed, runCallbacks, internal) {
1978  if (speed === void 0) {
1979    speed = this.params.speed;
1980  }
1981  if (runCallbacks === void 0) {
1982    runCallbacks = true;
1983  }
1984  const swiper = this;
1985  const { params, snapGrid, slidesGrid, rtlTranslate, enabled, animating } = swiper;
1986  if (!enabled) return swiper;
1987  const isVirtual = swiper.virtual && params.virtual.enabled;
1988  if (params.loop) {
1989    if (animating && !isVirtual && params.loopPreventsSliding) return false;
1990    swiper.loopFix({
1991      direction: 'prev',
1992    });
1993    // eslint-disable-next-line
1994    swiper._clientLeft = swiper.wrapperEl.clientLeft;
1995  }
1996  const translate = rtlTranslate ? swiper.translate : -swiper.translate;
1997  function normalize(val) {
1998    if (val < 0) return -Math.floor(Math.abs(val));
1999    return Math.floor(val);
2000  }
2001  const normalizedTranslate = normalize(translate);
2002  const normalizedSnapGrid = snapGrid.map((val) => normalize(val));
2003  let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
2004  if (typeof prevSnap === 'undefined' && params.cssMode) {
2005    let prevSnapIndex;
2006    snapGrid.forEach((snap, snapIndex) => {
2007      if (normalizedTranslate >= snap) {
2008        // prevSnap = snap;
2009        prevSnapIndex = snapIndex;
2010      }
2011    });
2012    if (typeof prevSnapIndex !== 'undefined') {
2013      prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
2014    }
2015  }
2016  let prevIndex = 0;
2017  if (typeof prevSnap !== 'undefined') {
2018    prevIndex = slidesGrid.indexOf(prevSnap);
2019    if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
2020    if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
2021      prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
2022      prevIndex = Math.max(prevIndex, 0);
2023    }
2024  }
2025  if (params.rewind && swiper.isBeginning) {
2026    const lastIndex =
2027      swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual
2028        ? swiper.virtual.slides.length - 1
2029        : swiper.slides.length - 1;
2030    return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
2031  }
2032  return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
2033}
2034
2035/* eslint no-unused-vars: "off" */
2036function slideReset(speed, runCallbacks, internal) {
2037  if (speed === void 0) {
2038    speed = this.params.speed;
2039  }
2040  if (runCallbacks === void 0) {
2041    runCallbacks = true;
2042  }
2043  const swiper = this;
2044  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
2045}
2046
2047/* eslint no-unused-vars: "off" */
2048function slideToClosest(speed, runCallbacks, internal, threshold) {
2049  if (speed === void 0) {
2050    speed = this.params.speed;
2051  }
2052  if (runCallbacks === void 0) {
2053    runCallbacks = true;
2054  }
2055  if (threshold === void 0) {
2056    threshold = 0.5;
2057  }
2058  const swiper = this;
2059  let index = swiper.activeIndex;
2060  const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
2061  const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
2062  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
2063  if (translate >= swiper.snapGrid[snapIndex]) {
2064    // The current translate is on or after the current snap index, so the choice
2065    // is between the current index and the one after it.
2066    const currentSnap = swiper.snapGrid[snapIndex];
2067    const nextSnap = swiper.snapGrid[snapIndex + 1];
2068    if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
2069      index += swiper.params.slidesPerGroup;
2070    }
2071  } else {
2072    // The current translate is before the current snap index, so the choice
2073    // is between the current index and the one before it.
2074    const prevSnap = swiper.snapGrid[snapIndex - 1];
2075    const currentSnap = swiper.snapGrid[snapIndex];
2076    if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
2077      index -= swiper.params.slidesPerGroup;
2078    }
2079  }
2080  index = Math.max(index, 0);
2081  index = Math.min(index, swiper.slidesGrid.length - 1);
2082  return swiper.slideTo(index, speed, runCallbacks, internal);
2083}
2084
2085function slideToClickedSlide() {
2086  const swiper = this;
2087  const { params, slidesEl } = swiper;
2088  const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
2089  let slideToIndex = swiper.clickedIndex;
2090  let realIndex;
2091  const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
2092  if (params.loop) {
2093    if (swiper.animating) return;
2094    realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
2095    if (params.centeredSlides) {
2096      if (
2097        slideToIndex < swiper.loopedSlides - slidesPerView / 2 ||
2098        slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2
2099      ) {
2100        swiper.loopFix();
2101        slideToIndex = swiper.getSlideIndex(
2102          elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]
2103        );
2104        nextTick(() => {
2105          swiper.slideTo(slideToIndex);
2106        });
2107      } else {
2108        swiper.slideTo(slideToIndex);
2109      }
2110    } else if (slideToIndex > swiper.slides.length - slidesPerView) {
2111      swiper.loopFix();
2112      slideToIndex = swiper.getSlideIndex(
2113        elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]
2114      );
2115      nextTick(() => {
2116        swiper.slideTo(slideToIndex);
2117      });
2118    } else {
2119      swiper.slideTo(slideToIndex);
2120    }
2121  } else {
2122    swiper.slideTo(slideToIndex);
2123  }
2124}
2125
2126var slide = {
2127  slideTo,
2128  slideToLoop,
2129  slideNext,
2130  slidePrev,
2131  slideReset,
2132  slideToClosest,
2133  slideToClickedSlide,
2134};
2135
2136function loopCreate(slideRealIndex) {
2137  const swiper = this;
2138  const { params, slidesEl } = swiper;
2139  if (!params.loop || (swiper.virtual && swiper.params.virtual.enabled)) return;
2140  const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
2141  slides.forEach((el, index) => {
2142    el.setAttribute('data-swiper-slide-index', index);
2143  });
2144  swiper.loopFix({
2145    slideRealIndex,
2146    direction: params.centeredSlides ? undefined : 'next',
2147  });
2148}
2149
2150function loopFix(_temp) {
2151  let {
2152    slideRealIndex,
2153    slideTo = true,
2154    direction,
2155    setTranslate,
2156    activeSlideIndex,
2157    byController,
2158    byMousewheel,
2159  } = _temp === void 0 ? {} : _temp;
2160  const swiper = this;
2161  if (!swiper.params.loop) return;
2162  swiper.emit('beforeLoopFix');
2163  const { slides, allowSlidePrev, allowSlideNext, slidesEl, params } = swiper;
2164  swiper.allowSlidePrev = true;
2165  swiper.allowSlideNext = true;
2166  if (swiper.virtual && params.virtual.enabled) {
2167    if (slideTo) {
2168      if (!params.centeredSlides && swiper.snapIndex === 0) {
2169        swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2170      } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2171        swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2172      } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2173        swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2174      }
2175    }
2176    swiper.allowSlidePrev = allowSlidePrev;
2177    swiper.allowSlideNext = allowSlideNext;
2178    swiper.emit('loopFix');
2179    return;
2180  }
2181  const slidesPerView =
2182    params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
2183  let loopedSlides = params.loopedSlides || slidesPerView;
2184  if (loopedSlides % params.slidesPerGroup !== 0) {
2185    loopedSlides += params.slidesPerGroup - (loopedSlides % params.slidesPerGroup);
2186  }
2187  swiper.loopedSlides = loopedSlides;
2188  const prependSlidesIndexes = [];
2189  const appendSlidesIndexes = [];
2190  let activeIndex = swiper.activeIndex;
2191  if (typeof activeSlideIndex === 'undefined') {
2192    activeSlideIndex = swiper.getSlideIndex(
2193      swiper.slides.filter((el) => el.classList.contains(params.slideActiveClass))[0]
2194    );
2195  } else {
2196    activeIndex = activeSlideIndex;
2197  }
2198  const isNext = direction === 'next' || !direction;
2199  const isPrev = direction === 'prev' || !direction;
2200  let slidesPrepended = 0;
2201  let slidesAppended = 0;
2202  // prepend last slides before start
2203  if (activeSlideIndex < loopedSlides) {
2204    slidesPrepended = Math.max(loopedSlides - activeSlideIndex, params.slidesPerGroup);
2205    for (let i = 0; i < loopedSlides - activeSlideIndex; i += 1) {
2206      const index = i - Math.floor(i / slides.length) * slides.length;
2207      prependSlidesIndexes.push(slides.length - index - 1);
2208    }
2209  } else if (activeSlideIndex /* + slidesPerView */ > swiper.slides.length - loopedSlides * 2) {
2210    slidesAppended = Math.max(activeSlideIndex - (swiper.slides.length - loopedSlides * 2), params.slidesPerGroup);
2211    for (let i = 0; i < slidesAppended; i += 1) {
2212      const index = i - Math.floor(i / slides.length) * slides.length;
2213      appendSlidesIndexes.push(index);
2214    }
2215  }
2216  if (isPrev) {
2217    prependSlidesIndexes.forEach((index) => {
2218      swiper.slides[index].swiperLoopMoveDOM = true;
2219      slidesEl.prepend(swiper.slides[index]);
2220      swiper.slides[index].swiperLoopMoveDOM = false;
2221    });
2222  }
2223  if (isNext) {
2224    appendSlidesIndexes.forEach((index) => {
2225      swiper.slides[index].swiperLoopMoveDOM = true;
2226      slidesEl.append(swiper.slides[index]);
2227      swiper.slides[index].swiperLoopMoveDOM = false;
2228    });
2229  }
2230  swiper.recalcSlides();
2231  if (params.slidesPerView === 'auto') {
2232    swiper.updateSlides();
2233  }
2234  if (params.watchSlidesProgress) {
2235    swiper.updateSlidesOffset();
2236  }
2237  if (slideTo) {
2238    if (prependSlidesIndexes.length > 0 && isPrev) {
2239      if (typeof slideRealIndex === 'undefined') {
2240        const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2241        const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
2242        const diff = newSlideTranslate - currentSlideTranslate;
2243        if (byMousewheel) {
2244          swiper.setTranslate(swiper.translate - diff);
2245        } else {
2246          swiper.slideTo(activeIndex + slidesPrepended, 0, false, true);
2247          if (setTranslate) {
2248            swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
2249          }
2250        }
2251      } else {
2252        if (setTranslate) {
2253          swiper.slideToLoop(slideRealIndex, 0, false, true);
2254        }
2255      }
2256    } else if (appendSlidesIndexes.length > 0 && isNext) {
2257      if (typeof slideRealIndex === 'undefined') {
2258        const currentSlideTranslate = swiper.slidesGrid[activeIndex];
2259        const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
2260        const diff = newSlideTranslate - currentSlideTranslate;
2261        if (byMousewheel) {
2262          swiper.setTranslate(swiper.translate - diff);
2263        } else {
2264          swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
2265          if (setTranslate) {
2266            swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
2267          }
2268        }
2269      } else {
2270        swiper.slideToLoop(slideRealIndex, 0, false, true);
2271      }
2272    }
2273  }
2274  swiper.allowSlidePrev = allowSlidePrev;
2275  swiper.allowSlideNext = allowSlideNext;
2276  if (swiper.controller && swiper.controller.control && !byController) {
2277    const loopParams = {
2278      slideRealIndex,
2279      slideTo: false,
2280      direction,
2281      setTranslate,
2282      activeSlideIndex,
2283      byController: true,
2284    };
2285    if (Array.isArray(swiper.controller.control)) {
2286      swiper.controller.control.forEach((c) => {
2287        if (!c.destroyed && c.params.loop) c.loopFix(loopParams);
2288      });
2289    } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2290      swiper.controller.control.loopFix(loopParams);
2291    }
2292  }
2293  swiper.emit('loopFix');
2294}
2295
2296function loopDestroy() {
2297  const swiper = this;
2298  const { params, slidesEl } = swiper;
2299  if (!params.loop || (swiper.virtual && swiper.params.virtual.enabled)) return;
2300  swiper.recalcSlides();
2301  const newSlidesOrder = [];
vendor: 4,338 bytes, lines 2302-2431
2302  swiper.slides.forEach((slideEl) => {
2303    const index =
2304      typeof slideEl.swiperSlideIndex === 'undefined'
2305        ? slideEl.getAttribute('data-swiper-slide-index') * 1
2306        : slideEl.swiperSlideIndex;
2307    newSlidesOrder[index] = slideEl;
2308  });
2309  swiper.slides.forEach((slideEl) => {
2310    slideEl.removeAttribute('data-swiper-slide-index');
2311  });
2312  newSlidesOrder.forEach((slideEl) => {
2313    slidesEl.append(slideEl);
2314  });
2315  swiper.recalcSlides();
2316  swiper.slideTo(swiper.realIndex, 0);
2317}
2318
2319var loop = {
2320  loopCreate,
2321  loopFix,
2322  loopDestroy,
2323};
2324
2325function setGrabCursor(moving) {
2326  const swiper = this;
2327  if (!swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked) || swiper.params.cssMode) return;
2328  const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
2329  if (swiper.isElement) {
2330    swiper.__preventObserver__ = true;
2331  }
2332  el.style.cursor = 'move';
2333  el.style.cursor = moving ? 'grabbing' : 'grab';
2334  if (swiper.isElement) {
2335    requestAnimationFrame(() => {
2336      swiper.__preventObserver__ = false;
2337    });
2338  }
2339}
2340
2341function unsetGrabCursor() {
2342  const swiper = this;
2343  if ((swiper.params.watchOverflow && swiper.isLocked) || swiper.params.cssMode) {
2344    return;
2345  }
2346  if (swiper.isElement) {
2347    swiper.__preventObserver__ = true;
2348  }
2349  swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
2350  if (swiper.isElement) {
2351    requestAnimationFrame(() => {
2352      swiper.__preventObserver__ = false;
2353    });
2354  }
2355}
2356
2357var grabCursor = {
2358  setGrabCursor,
2359  unsetGrabCursor,
2360};
2361
2362// Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2363function closestElement(selector, base) {
2364  if (base === void 0) {
2365    base = this;
2366  }
2367  function __closestFrom(el) {
2368    if (!el || el === getDocument() || el === getWindow()) return null;
2369    if (el.assignedSlot) el = el.assignedSlot;
2370    const found = el.closest(selector);
2371    if (!found && !el.getRootNode) {
2372      return null;
2373    }
2374    return found || __closestFrom(el.getRootNode().host);
2375  }
2376  return __closestFrom(base);
2377}
2378function onTouchStart(event) {
2379  const swiper = this;
2380  const document = getDocument();
2381  const window = getWindow();
2382  const data = swiper.touchEventsData;
2383  data.evCache.push(event);
2384  const { params, touches, enabled } = swiper;
2385  if (!enabled) return;
2386  if (!params.simulateTouch && event.pointerType === 'mouse') return;
2387  if (swiper.animating && params.preventInteractionOnTransition) {
2388    return;
2389  }
2390  if (!swiper.animating && params.cssMode && params.loop) {
2391    swiper.loopFix();
2392  }
2393  let e = event;
2394  if (e.originalEvent) e = e.originalEvent;
2395  let targetEl = e.target;
2396  if (params.touchEventsTarget === 'wrapper') {
2397    if (!swiper.wrapperEl.contains(targetEl)) return;
2398  }
2399  if ('which' in e && e.which === 3) return;
2400  if ('button' in e && e.button > 0) return;
2401  if (data.isTouched && data.isMoved) return;
2402
2403  // change target el for shadow root component
2404  const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
2405  // eslint-disable-next-line
2406  const eventPath = event.composedPath ? event.composedPath() : event.path;
2407  if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
2408    targetEl = eventPath[0];
2409  }
2410  const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
2411  const isTargetShadow = !!(e.target && e.target.shadowRoot);
2412
2413  // use closestElement for shadow root element to get the actual closest for nested shadow root element
2414  if (
2415    params.noSwiping &&
2416    (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))
2417  ) {
2418    swiper.allowClick = true;
2419    return;
2420  }
2421  if (params.swipeHandler) {
2422    if (!targetEl.closest(params.swipeHandler)) return;
2423  }
2424  touches.currentX = e.pageX;
2425  touches.currentY = e.pageY;
2426  const startX = touches.currentX;
2427  const startY = touches.currentY;
2428
2429  // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
2430
2431  const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
vendor: 18,698 bytes, lines 2432-2996
2432  const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
2433  if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
2434    if (edgeSwipeDetection === 'prevent') {
2435      event.preventDefault();
2436    } else {
2437      return;
2438    }
2439  }
2440  Object.assign(data, {
2441    isTouched: true,
2442    isMoved: false,
2443    allowTouchCallbacks: true,
2444    isScrolling: undefined,
2445    startMoving: undefined,
2446  });
2447  touches.startX = startX;
2448  touches.startY = startY;
2449  data.touchStartTime = now();
2450  swiper.allowClick = true;
2451  swiper.updateSize();
2452  swiper.swipeDirection = undefined;
2453  if (params.threshold > 0) data.allowThresholdMove = false;
2454  let preventDefault = true;
2455  if (targetEl.matches(data.focusableElements)) {
2456    preventDefault = false;
2457    if (targetEl.nodeName === 'SELECT') {
2458      data.isTouched = false;
2459    }
2460  }
2461  if (
2462    document.activeElement &&
2463    document.activeElement.matches(data.focusableElements) &&
2464    document.activeElement !== targetEl
2465  ) {
2466    document.activeElement.blur();
2467  }
2468  const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
2469  if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
2470    e.preventDefault();
2471  }
2472  if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
2473    swiper.freeMode.onTouchStart();
2474  }
2475  swiper.emit('touchStart', e);
2476}
2477
2478function onTouchMove(event) {
2479  const document = getDocument();
2480  const swiper = this;
2481  const data = swiper.touchEventsData;
2482  const { params, touches, rtlTranslate: rtl, enabled } = swiper;
2483  if (!enabled) return;
2484  if (!params.simulateTouch && event.pointerType === 'mouse') return;
2485  let e = event;
2486  if (e.originalEvent) e = e.originalEvent;
2487  if (!data.isTouched) {
2488    if (data.startMoving && data.isScrolling) {
2489      swiper.emit('touchMoveOpposite', e);
2490    }
2491    return;
2492  }
2493  const pointerIndex = data.evCache.findIndex((cachedEv) => cachedEv.pointerId === e.pointerId);
2494  if (pointerIndex >= 0) data.evCache[pointerIndex] = e;
2495  const targetTouch = data.evCache.length > 1 ? data.evCache[0] : e;
2496  const pageX = targetTouch.pageX;
2497  const pageY = targetTouch.pageY;
2498  if (e.preventedByNestedSwiper) {
2499    touches.startX = pageX;
2500    touches.startY = pageY;
2501    return;
2502  }
2503  if (!swiper.allowTouchMove) {
2504    if (!e.target.matches(data.focusableElements)) {
2505      swiper.allowClick = false;
2506    }
2507    if (data.isTouched) {
2508      Object.assign(touches, {
2509        startX: pageX,
2510        startY: pageY,
2511        prevX: swiper.touches.currentX,
2512        prevY: swiper.touches.currentY,
2513        currentX: pageX,
2514        currentY: pageY,
2515      });
2516      data.touchStartTime = now();
2517    }
2518    return;
2519  }
2520  if (params.touchReleaseOnEdges && !params.loop) {
2521    if (swiper.isVertical()) {
2522      // Vertical
2523      if (
2524        (pageY < touches.startY && swiper.translate <= swiper.maxTranslate()) ||
2525        (pageY > touches.startY && swiper.translate >= swiper.minTranslate())
2526      ) {
2527        data.isTouched = false;
2528        data.isMoved = false;
2529        return;
2530      }
2531    } else if (
2532      (pageX < touches.startX && swiper.translate <= swiper.maxTranslate()) ||
2533      (pageX > touches.startX && swiper.translate >= swiper.minTranslate())
2534    ) {
2535      return;
2536    }
2537  }
2538  if (document.activeElement) {
2539    if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
2540      data.isMoved = true;
2541      swiper.allowClick = false;
2542      return;
2543    }
2544  }
2545  if (data.allowTouchCallbacks) {
2546    swiper.emit('touchMove', e);
2547  }
2548  if (e.targetTouches && e.targetTouches.length > 1) return;
2549  touches.currentX = pageX;
2550  touches.currentY = pageY;
2551  const diffX = touches.currentX - touches.startX;
2552  const diffY = touches.currentY - touches.startY;
2553  if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
2554  if (typeof data.isScrolling === 'undefined') {
2555    let touchAngle;
2556    if (
2557      (swiper.isHorizontal() && touches.currentY === touches.startY) ||
2558      (swiper.isVertical() && touches.currentX === touches.startX)
2559    ) {
2560      data.isScrolling = false;
2561    } else {
2562      // eslint-disable-next-line
2563      if (diffX * diffX + diffY * diffY >= 25) {
2564        touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI;
2565        data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
2566      }
2567    }
2568  }
2569  if (data.isScrolling) {
2570    swiper.emit('touchMoveOpposite', e);
2571  }
2572  if (typeof data.startMoving === 'undefined') {
2573    if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
2574      data.startMoving = true;
2575    }
2576  }
2577  if (
2578    data.isScrolling ||
2579    (swiper.zoom && swiper.params.zoom && swiper.params.zoom.enabled && data.evCache.length > 1)
2580  ) {
2581    data.isTouched = false;
2582    return;
2583  }
2584  if (!data.startMoving) {
2585    return;
2586  }
2587  swiper.allowClick = false;
2588  if (!params.cssMode && e.cancelable) {
2589    e.preventDefault();
2590  }
2591  if (params.touchMoveStopPropagation && !params.nested) {
2592    e.stopPropagation();
2593  }
2594  let diff = swiper.isHorizontal() ? diffX : diffY;
2595  let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
2596  if (params.oneWayMovement) {
2597    diff = Math.abs(diff) * (rtl ? 1 : -1);
2598    touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
2599  }
2600  touches.diff = diff;
2601  diff *= params.touchRatio;
2602  if (rtl) {
2603    diff = -diff;
2604    touchesDiff = -touchesDiff;
2605  }
2606  const prevTouchesDirection = swiper.touchesDirection;
2607  swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
2608  swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
2609  const isLoop = swiper.params.loop && !params.cssMode;
2610  if (!data.isMoved) {
2611    if (isLoop) {
2612      swiper.loopFix({
2613        direction: swiper.swipeDirection,
2614      });
2615    }
2616    data.startTranslate = swiper.getTranslate();
2617    swiper.setTransition(0);
2618    if (swiper.animating) {
2619      const evt = new window.CustomEvent('transitionend', {
2620        bubbles: true,
2621        cancelable: true,
2622      });
2623      swiper.wrapperEl.dispatchEvent(evt);
2624    }
2625    data.allowMomentumBounce = false;
2626    // Grab Cursor
2627    if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2628      swiper.setGrabCursor(true);
2629    }
2630    swiper.emit('sliderFirstMove', e);
2631  }
2632  let loopFixed;
2633  if (data.isMoved && prevTouchesDirection !== swiper.touchesDirection && isLoop && Math.abs(diff) >= 1) {
2634    // need another loop fix
2635    swiper.loopFix({
2636      direction: swiper.swipeDirection,
2637      setTranslate: true,
2638    });
2639    loopFixed = true;
2640  }
2641  swiper.emit('sliderMove', e);
2642  data.isMoved = true;
2643  data.currentTranslate = diff + data.startTranslate;
2644  let disableParentSwiper = true;
2645  let resistanceRatio = params.resistanceRatio;
2646  if (params.touchReleaseOnEdges) {
2647    resistanceRatio = 0;
2648  }
2649  if (diff > 0) {
2650    if (
2651      isLoop &&
2652      !loopFixed &&
2653      data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.size / 2 : swiper.minTranslate())
2654    ) {
2655      swiper.loopFix({
2656        direction: 'prev',
2657        setTranslate: true,
2658        activeSlideIndex: 0,
2659      });
2660    }
2661    if (data.currentTranslate > swiper.minTranslate()) {
2662      disableParentSwiper = false;
2663      if (params.resistance) {
2664        data.currentTranslate =
2665          swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
2666      }
2667    }
2668  } else if (diff < 0) {
2669    if (
2670      isLoop &&
2671      !loopFixed &&
2672      data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.size / 2 : swiper.maxTranslate())
2673    ) {
2674      swiper.loopFix({
2675        direction: 'next',
2676        setTranslate: true,
2677        activeSlideIndex:
2678          swiper.slides.length -
2679          (params.slidesPerView === 'auto'
2680            ? swiper.slidesPerViewDynamic()
2681            : Math.ceil(parseFloat(params.slidesPerView, 10))),
2682      });
2683    }
2684    if (data.currentTranslate < swiper.maxTranslate()) {
2685      disableParentSwiper = false;
2686      if (params.resistance) {
2687        data.currentTranslate =
2688          swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
2689      }
2690    }
2691  }
2692  if (disableParentSwiper) {
2693    e.preventedByNestedSwiper = true;
2694  }
2695
2696  // Directions locks
2697  if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
2698    data.currentTranslate = data.startTranslate;
2699  }
2700  if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
2701    data.currentTranslate = data.startTranslate;
2702  }
2703  if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
2704    data.currentTranslate = data.startTranslate;
2705  }
2706
2707  // Threshold
2708  if (params.threshold > 0) {
2709    if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2710      if (!data.allowThresholdMove) {
2711        data.allowThresholdMove = true;
2712        touches.startX = touches.currentX;
2713        touches.startY = touches.currentY;
2714        data.currentTranslate = data.startTranslate;
2715        touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
2716        return;
2717      }
2718    } else {
2719      data.currentTranslate = data.startTranslate;
2720      return;
2721    }
2722  }
2723  if (!params.followFinger || params.cssMode) return;
2724
2725  // Update active index in free mode
2726  if ((params.freeMode && params.freeMode.enabled && swiper.freeMode) || params.watchSlidesProgress) {
2727    swiper.updateActiveIndex();
2728    swiper.updateSlidesClasses();
2729  }
2730  if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
2731    swiper.freeMode.onTouchMove();
2732  }
2733  // Update progress
2734  swiper.updateProgress(data.currentTranslate);
2735  // Update translate
2736  swiper.setTranslate(data.currentTranslate);
2737}
2738
2739function onTouchEnd(event) {
2740  const swiper = this;
2741  const data = swiper.touchEventsData;
2742  const pointerIndex = data.evCache.findIndex((cachedEv) => cachedEv.pointerId === event.pointerId);
2743  if (pointerIndex >= 0) {
2744    data.evCache.splice(pointerIndex, 1);
2745  }
2746  if (['pointercancel', 'pointerout', 'pointerleave'].includes(event.type)) {
2747    const proceed = event.type === 'pointercancel' && (swiper.browser.isSafari || swiper.browser.isWebView);
2748    if (!proceed) {
2749      return;
2750    }
2751  }
2752  const { params, touches, rtlTranslate: rtl, slidesGrid, enabled } = swiper;
2753  if (!enabled) return;
2754  if (!params.simulateTouch && event.pointerType === 'mouse') return;
2755  let e = event;
2756  if (e.originalEvent) e = e.originalEvent;
2757  if (data.allowTouchCallbacks) {
2758    swiper.emit('touchEnd', e);
2759  }
2760  data.allowTouchCallbacks = false;
2761  if (!data.isTouched) {
2762    if (data.isMoved && params.grabCursor) {
2763      swiper.setGrabCursor(false);
2764    }
2765    data.isMoved = false;
2766    data.startMoving = false;
2767    return;
2768  }
2769  // Return Grab Cursor
2770  if (
2771    params.grabCursor &&
2772    data.isMoved &&
2773    data.isTouched &&
2774    (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)
2775  ) {
2776    swiper.setGrabCursor(false);
2777  }
2778
2779  // Time diff
2780  const touchEndTime = now();
2781  const timeDiff = touchEndTime - data.touchStartTime;
2782
2783  // Tap, doubleTap, Click
2784  if (swiper.allowClick) {
2785    const pathTree = e.path || (e.composedPath && e.composedPath());
2786    swiper.updateClickedSlide((pathTree && pathTree[0]) || e.target);
2787    swiper.emit('tap click', e);
2788    if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
2789      swiper.emit('doubleTap doubleClick', e);
2790    }
2791  }
2792  data.lastClickTime = now();
2793  nextTick(() => {
2794    if (!swiper.destroyed) swiper.allowClick = true;
2795  });
2796  if (
2797    !data.isTouched ||
2798    !data.isMoved ||
2799    !swiper.swipeDirection ||
2800    touches.diff === 0 ||
2801    data.currentTranslate === data.startTranslate
2802  ) {
2803    data.isTouched = false;
2804    data.isMoved = false;
2805    data.startMoving = false;
2806    return;
2807  }
2808  data.isTouched = false;
2809  data.isMoved = false;
2810  data.startMoving = false;
2811  let currentPos;
2812  if (params.followFinger) {
2813    currentPos = rtl ? swiper.translate : -swiper.translate;
2814  } else {
2815    currentPos = -data.currentTranslate;
2816  }
2817  if (params.cssMode) {
2818    return;
2819  }
2820  if (params.freeMode && params.freeMode.enabled) {
2821    swiper.freeMode.onTouchEnd({
2822      currentPos,
2823    });
2824    return;
2825  }
2826
2827  // Find current slide
2828  let stopIndex = 0;
2829  let groupSize = swiper.slidesSizesGrid[0];
2830  for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
2831    const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
2832    if (typeof slidesGrid[i + increment] !== 'undefined') {
2833      if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
2834        stopIndex = i;
2835        groupSize = slidesGrid[i + increment] - slidesGrid[i];
2836      }
2837    } else if (currentPos >= slidesGrid[i]) {
2838      stopIndex = i;
2839      groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
2840    }
2841  }
2842  let rewindFirstIndex = null;
2843  let rewindLastIndex = null;
2844  if (params.rewind) {
2845    if (swiper.isBeginning) {
2846      rewindLastIndex =
2847        params.virtual && params.virtual.enabled && swiper.virtual
2848          ? swiper.virtual.slides.length - 1
2849          : swiper.slides.length - 1;
2850    } else if (swiper.isEnd) {
2851      rewindFirstIndex = 0;
2852    }
2853  }
2854  // Find current slide size
2855  const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
2856  const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
2857  if (timeDiff > params.longSwipesMs) {
2858    // Long touches
2859    if (!params.longSwipes) {
2860      swiper.slideTo(swiper.activeIndex);
2861      return;
2862    }
2863    if (swiper.swipeDirection === 'next') {
2864      if (ratio >= params.longSwipesRatio)
2865        swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);
2866      else swiper.slideTo(stopIndex);
2867    }
2868    if (swiper.swipeDirection === 'prev') {
2869      if (ratio > 1 - params.longSwipesRatio) {
2870        swiper.slideTo(stopIndex + increment);
2871      } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
2872        swiper.slideTo(rewindLastIndex);
2873      } else {
2874        swiper.slideTo(stopIndex);
2875      }
2876    }
2877  } else {
2878    // Short swipes
2879    if (!params.shortSwipes) {
2880      swiper.slideTo(swiper.activeIndex);
2881      return;
2882    }
2883    const isNavButtonTarget =
2884      swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
2885    if (!isNavButtonTarget) {
2886      if (swiper.swipeDirection === 'next') {
2887        swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
2888      }
2889      if (swiper.swipeDirection === 'prev') {
2890        swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
2891      }
2892    } else if (e.target === swiper.navigation.nextEl) {
2893      swiper.slideTo(stopIndex + increment);
2894    } else {
2895      swiper.slideTo(stopIndex);
2896    }
2897  }
2898}
2899
2900function onResize() {
2901  const swiper = this;
2902  const { params, el } = swiper;
2903  if (el && el.offsetWidth === 0) return;
2904
2905  // Breakpoints
2906  if (params.breakpoints) {
2907    swiper.setBreakpoint();
2908  }
2909
2910  // Save locks
2911  const { allowSlideNext, allowSlidePrev, snapGrid } = swiper;
2912  const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
2913
2914  // Disable locks on resize
2915  swiper.allowSlideNext = true;
2916  swiper.allowSlidePrev = true;
2917  swiper.updateSize();
2918  swiper.updateSlides();
2919  swiper.updateSlidesClasses();
2920  const isVirtualLoop = isVirtual && params.loop;
2921  if (
2922    (params.slidesPerView === 'auto' || params.slidesPerView > 1) &&
2923    swiper.isEnd &&
2924    !swiper.isBeginning &&
2925    !swiper.params.centeredSlides &&
2926    !isVirtualLoop
2927  ) {
2928    swiper.slideTo(swiper.slides.length - 1, 0, false, true);
2929  } else {
2930    if (swiper.params.loop && !isVirtual) {
2931      swiper.slideToLoop(swiper.realIndex, 0, false, true);
2932    } else {
2933      swiper.slideTo(swiper.activeIndex, 0, false, true);
2934    }
2935  }
2936  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
2937    clearTimeout(swiper.autoplay.resizeTimeout);
2938    swiper.autoplay.resizeTimeout = setTimeout(() => {
2939      if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
2940        swiper.autoplay.resume();
2941      }
2942    }, 500);
2943  }
2944  // Return locks after resize
2945  swiper.allowSlidePrev = allowSlidePrev;
2946  swiper.allowSlideNext = allowSlideNext;
2947  if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
2948    swiper.checkOverflow();
2949  }
2950}
2951
2952function onClick(e) {
2953  const swiper = this;
2954  if (!swiper.enabled) return;
2955  if (!swiper.allowClick) {
2956    if (swiper.params.preventClicks) e.preventDefault();
2957    if (swiper.params.preventClicksPropagation && swiper.animating) {
2958      e.stopPropagation();
2959      e.stopImmediatePropagation();
2960    }
2961  }
2962}
2963
2964function onScroll() {
2965  const swiper = this;
2966  const { wrapperEl, rtlTranslate, enabled } = swiper;
2967  if (!enabled) return;
2968  swiper.previousTranslate = swiper.translate;
2969  if (swiper.isHorizontal()) {
2970    swiper.translate = -wrapperEl.scrollLeft;
2971  } else {
2972    swiper.translate = -wrapperEl.scrollTop;
2973  }
2974  // eslint-disable-next-line
2975  if (swiper.translate === 0) swiper.translate = 0;
2976  swiper.updateActiveIndex();
2977  swiper.updateSlidesClasses();
2978  let newProgress;
2979  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
2980  if (translatesDiff === 0) {
2981    newProgress = 0;
2982  } else {
2983    newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
2984  }
2985  if (newProgress !== swiper.progress) {
2986    swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
2987  }
2988  swiper.emit('setTranslate', swiper.translate, false);
2989}
2990
2991function onLoad(e) {
2992  const swiper = this;
2993  processLazyPreloader(swiper, e.target);
2994  if (swiper.params.cssMode || (swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight)) {
2995    return;
2996  }
2997  swiper.update();
2998}
2999
3000let dummyEventAttached = false;
3001function dummyEventListener() {}
3002const events = (swiper, method) => {
3003  const document = getDocument();
3004  const { params, el, wrapperEl, device } = swiper;
3005  const capture = !!params.nested;
3006  const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
3007  const swiperMethod = method;
3008
3009  // Touch Events
3010  el[domMethod]('pointerdown', swiper.onTouchStart, {
3011    passive: false,
3012  });
3013  document[domMethod]('pointermove', swiper.onTouchMove, {
3014    passive: false,
3015    capture,
3016  });
3017  document[domMethod]('pointerup', swiper.onTouchEnd, {
3018    passive: true,
3019  });
3020  document[domMethod]('pointercancel', swiper.onTouchEnd, {
3021    passive: true,
3022  });
3023  document[domMethod]('pointerout', swiper.onTouchEnd, {
3024    passive: true,
3025  });
3026  document[domMethod]('pointerleave', swiper.onTouchEnd, {
3027    passive: true,
3028  });
3029
3030  // Prevent Links Clicks
3031  if (params.preventClicks || params.preventClicksPropagation) {
3032    el[domMethod]('click', swiper.onClick, true);
3033  }
3034  if (params.cssMode) {
3035    wrapperEl[domMethod]('scroll', swiper.onScroll);
3036  }
3037
3038  // Resize handler
3039  if (params.updateOnWindowResize) {
3040    swiper[swiperMethod](
3041      device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate',
3042      onResize,
3043      true
3044    );
3045  } else {
3046    swiper[swiperMethod]('observerUpdate', onResize, true);
3047  }
3048
3049  // Images loader
3050  el[domMethod]('load', swiper.onLoad, {
3051    capture: true,
3052  });
3053};
3054function attachEvents() {
3055  const swiper = this;
3056  const document = getDocument();
3057  const { params } = swiper;
3058  swiper.onTouchStart = onTouchStart.bind(swiper);
3059  swiper.onTouchMove = onTouchMove.bind(swiper);
3060  swiper.onTouchEnd = onTouchEnd.bind(swiper);
3061  if (params.cssMode) {
3062    swiper.onScroll = onScroll.bind(swiper);
3063  }
3064  swiper.onClick = onClick.bind(swiper);
3065  swiper.onLoad = onLoad.bind(swiper);
3066  if (!dummyEventAttached) {
3067    document.addEventListener('touchstart', dummyEventListener);
3068    dummyEventAttached = true;
3069  }
3070  events(swiper, 'on');
3071}
3072function detachEvents() {
3073  const swiper = this;
3074  events(swiper, 'off');
3075}
3076var events$1 = {
3077  attachEvents,
3078  detachEvents,
3079};
3080
3081const isGridEnabled = (swiper, params) => {
3082  return swiper.grid && params.grid && params.grid.rows > 1;
3083};
3084function setBreakpoint() {
3085  const swiper = this;
3086  const { realIndex, initialized, params, el } = swiper;
3087  const breakpoints = params.breakpoints;
3088  if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) return;
3089
3090  // Get breakpoint for window width and update parameters
3091  const breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
3092  if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3093  const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3094  const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3095  const wasMultiRow = isGridEnabled(swiper, params);
3096  const isMultiRow = isGridEnabled(swiper, breakpointParams);
3097  const wasEnabled = params.enabled;
3098  if (wasMultiRow && !isMultiRow) {
3099    el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3100    swiper.emitContainerClasses();
3101  } else if (!wasMultiRow && isMultiRow) {
3102    el.classList.add(`${params.containerModifierClass}grid`);
3103    if (
3104      (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column') ||
3105      (!breakpointParams.grid.fill && params.grid.fill === 'column')
3106    ) {
3107      el.classList.add(`${params.containerModifierClass}grid-column`);
3108    }
3109    swiper.emitContainerClasses();
3110  }
3111
3112  // Toggle navigation, pagination, scrollbar
3113  ['navigation', 'pagination', 'scrollbar'].forEach((prop) => {
3114    if (typeof breakpointParams[prop] === 'undefined') return;
3115    const wasModuleEnabled = params[prop] && params[prop].enabled;
3116    const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3117    if (wasModuleEnabled && !isModuleEnabled) {
3118      swiper[prop].disable();
3119    }
3120    if (!wasModuleEnabled && isModuleEnabled) {
3121      swiper[prop].enable();
3122    }
3123  });
3124  const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3125  const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
3126  if (directionChanged && initialized) {
3127    swiper.changeDirection();
3128  }
3129  extend(swiper.params, breakpointParams);
3130  const isEnabled = swiper.params.enabled;
3131  Object.assign(swiper, {
3132    allowTouchMove: swiper.params.allowTouchMove,
3133    allowSlideNext: swiper.params.allowSlideNext,
3134    allowSlidePrev: swiper.params.allowSlidePrev,
3135  });
3136  if (wasEnabled && !isEnabled) {
3137    swiper.disable();
3138  } else if (!wasEnabled && isEnabled) {
3139    swiper.enable();
3140  }
3141  swiper.currentBreakpoint = breakpoint;
3142  swiper.emit('_beforeBreakpoint', breakpointParams);
3143  if (needsReLoop && initialized) {
3144    swiper.loopDestroy();
3145    swiper.loopCreate(realIndex);
3146    swiper.updateSlides();
3147  }
3148  swiper.emit('breakpoint', breakpointParams);
3149}
3150
3151function getBreakpoint(breakpoints, base, containerEl) {
3152  if (base === void 0) {
3153    base = 'window';
3154  }
3155  if (!breakpoints || (base === 'container' && !containerEl)) return undefined;
3156  let breakpoint = false;
3157  const window = getWindow();
3158  const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
vendor: 4,202 bytes, lines 3159-3312
3159  const points = Object.keys(breakpoints).map((point) => {
3160    if (typeof point === 'string' && point.indexOf('@') === 0) {
3161      const minRatio = parseFloat(point.substr(1));
3162      const value = currentHeight * minRatio;
3163      return {
3164        value,
3165        point,
3166      };
3167    }
3168    return {
3169      value: point,
3170      point,
3171    };
3172  });
3173  points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
3174  for (let i = 0; i < points.length; i += 1) {
3175    const { point, value } = points[i];
3176    if (base === 'window') {
3177      if (window.matchMedia(`(min-width: ${value}px)`).matches) {
3178        breakpoint = point;
3179      }
3180    } else if (value <= containerEl.clientWidth) {
3181      breakpoint = point;
3182    }
3183  }
3184  return breakpoint || 'max';
3185}
3186
3187var breakpoints = {
3188  setBreakpoint,
3189  getBreakpoint,
3190};
3191
3192function prepareClasses(entries, prefix) {
3193  const resultClasses = [];
3194  entries.forEach((item) => {
3195    if (typeof item === 'object') {
3196      Object.keys(item).forEach((classNames) => {
3197        if (item[classNames]) {
3198          resultClasses.push(prefix + classNames);
3199        }
3200      });
3201    } else if (typeof item === 'string') {
3202      resultClasses.push(prefix + item);
3203    }
3204  });
3205  return resultClasses;
3206}
3207function addClasses() {
3208  const swiper = this;
3209  const { classNames, params, rtl, el, device } = swiper;
3210  // prettier-ignore
3211  const suffixes = prepareClasses(['initialized', params.direction, {
3212      'free-mode': swiper.params.freeMode && params.freeMode.enabled
3213    }, {
3214      'autoheight': params.autoHeight
3215    }, {
3216      'rtl': rtl
3217    }, {
3218      'grid': params.grid && params.grid.rows > 1
3219    }, {
3220      'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3221    }, {
3222      'android': device.android
3223    }, {
3224      'ios': device.ios
3225    }, {
3226      'css-mode': params.cssMode
3227    }, {
3228      'centered': params.cssMode && params.centeredSlides
3229    }, {
3230      'watch-progress': params.watchSlidesProgress
3231    }], params.containerModifierClass);
3232  classNames.push(...suffixes);
3233  el.classList.add(...classNames);
3234  swiper.emitContainerClasses();
3235}
3236
3237function removeClasses() {
3238  const swiper = this;
3239  const { el, classNames } = swiper;
3240  el.classList.remove(...classNames);
3241  swiper.emitContainerClasses();
3242}
3243
3244var classes = {
3245  addClasses,
3246  removeClasses,
3247};
3248
3249function checkOverflow() {
3250  const swiper = this;
3251  const { isLocked: wasLocked, params } = swiper;
3252  const { slidesOffsetBefore } = params;
3253  if (slidesOffsetBefore) {
3254    const lastSlideIndex = swiper.slides.length - 1;
3255    const lastSlideRightEdge =
3256      swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
3257    swiper.isLocked = swiper.size > lastSlideRightEdge;
3258  } else {
3259    swiper.isLocked = swiper.snapGrid.length === 1;
3260  }
3261  if (params.allowSlideNext === true) {
3262    swiper.allowSlideNext = !swiper.isLocked;
3263  }
3264  if (params.allowSlidePrev === true) {
3265    swiper.allowSlidePrev = !swiper.isLocked;
3266  }
3267  if (wasLocked && wasLocked !== swiper.isLocked) {
3268    swiper.isEnd = false;
3269  }
3270  if (wasLocked !== swiper.isLocked) {
3271    swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
3272  }
3273}
3274var checkOverflow$1 = {
3275  checkOverflow,
3276};
3277
3278var defaults = {
3279  init: true,
3280  direction: 'horizontal',
3281  oneWayMovement: false,
3282  touchEventsTarget: 'wrapper',
3283  initialSlide: 0,
3284  speed: 300,
3285  cssMode: false,
3286  updateOnWindowResize: true,
3287  resizeObserver: true,
3288  nested: false,
3289  createElements: false,
3290  enabled: true,
3291  focusableElements: 'input, select, option, textarea, button, video, label',
3292  // Overrides
3293  width: null,
3294  height: null,
3295  //
3296  preventInteractionOnTransition: false,
3297  // ssr
3298  userAgent: null,
3299  url: null,
3300  // To support iOS's swipe-to-go-back gesture (when being used in-app).
3301  edgeSwipeDetection: false,
3302  edgeSwipeThreshold: 20,
3303  // Autoheight
3304  autoHeight: false,
3305  // Set wrapper width
3306  setWrapperSize: false,
3307  // Virtual Translate
3308  virtualTranslate: false,
3309  // Effects
3310  effect: 'slide',
3311  // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3312
3313  // Breakpoints
3314  breakpoints: undefined,
3315  breakpointsBase: 'window',
3316  // Slides grid
3317  spaceBetween: 0,
3318  slidesPerView: 1,
3319  slidesPerGroup: 1,
3320  slidesPerGroupSkip: 0,
3321  slidesPerGroupAuto: false,
3322  centeredSlides: false,
3323  centeredSlidesBounds: false,
3324  slidesOffsetBefore: 0,
3325  // in px
3326  slidesOffsetAfter: 0,
3327  // in px
3328  normalizeSlideIndex: true,
3329  centerInsufficientSlides: false,
3330  // Disable swiper and hide navigation when container not overflow
3331  watchOverflow: true,
3332  // Round length
3333  roundLengths: false,
3334  // Touches
3335  touchRatio: 1,
3336  touchAngle: 45,
3337  simulateTouch: true,
3338  shortSwipes: true,
3339  longSwipes: true,
3340  longSwipesRatio: 0.5,
3341  longSwipesMs: 300,
3342  followFinger: true,
3343  allowTouchMove: true,
3344  threshold: 5,
3345  touchMoveStopPropagation: false,
3346  touchStartPreventDefault: true,
3347  touchStartForcePreventDefault: false,
3348  touchReleaseOnEdges: false,
3349  // Unique Navigation Elements
3350  uniqueNavElements: true,
3351  // Resistance
3352  resistance: true,
3353  resistanceRatio: 0.85,
3354  // Progress
3355  watchSlidesProgress: false,
3356  // Cursor
3357  grabCursor: false,
3358  // Clicks
3359  preventClicks: true,
3360  preventClicksPropagation: true,
3361  slideToClickedSlide: false,
3362  // loop
3363  loop: false,
3364  loopedSlides: null,
3365  loopPreventsSliding: true,
3366  // rewind
3367  rewind: false,
3368  // Swiping/no swiping
3369  allowSlidePrev: true,
3370  allowSlideNext: true,
3371  swipeHandler: null,
3372  // '.swipe-handler',
3373  noSwiping: true,
3374  noSwipingClass: 'swiper-no-swiping',
3375  noSwipingSelector: null,
3376  // Passive Listeners
3377  passiveListeners: true,
3378  maxBackfaceHiddenSlides: 10,
3379  // NS
3380  containerModifierClass: 'swiper-',
3381  // NEW
3382  slideClass: 'swiper-slide',
3383  slideActiveClass: 'swiper-slide-active',
3384  slideVisibleClass: 'swiper-slide-visible',
3385  slideNextClass: 'swiper-slide-next',
3386  slidePrevClass: 'swiper-slide-prev',
3387  wrapperClass: 'swiper-wrapper',
3388  lazyPreloaderClass: 'swiper-lazy-preloader',
3389  lazyPreloadPrevNext: 0,
3390  // Callbacks
3391  runCallbacksOnInit: true,
3392  // Internals
3393  _emitClasses: false,
3394};
3395
3396function moduleExtendParams(params, allModulesParams) {
3397  return function extendParams(obj) {
3398    if (obj === void 0) {
3399      obj = {};
3400    }
3401    const moduleParamName = Object.keys(obj)[0];
3402    const moduleParams = obj[moduleParamName];
3403    if (typeof moduleParams !== 'object' || moduleParams === null) {
3404      extend(allModulesParams, obj);
3405      return;
3406    }
3407    if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] === true) {
3408      params[moduleParamName] = {
3409        auto: true,
3410      };
3411    }
3412    if (!(moduleParamName in params && 'enabled' in moduleParams)) {
3413      extend(allModulesParams, obj);
3414      return;
3415    }
3416    if (params[moduleParamName] === true) {
3417      params[moduleParamName] = {
3418        enabled: true,
3419      };
3420    }
3421    if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
3422      params[moduleParamName].enabled = true;
3423    }
3424    if (!params[moduleParamName])
3425      params[moduleParamName] = {
3426        enabled: false,
3427      };
3428    extend(allModulesParams, obj);
3429  };
3430}
3431
3432/* eslint no-param-reassign: "off" */
3433const prototypes = {
3434  eventsEmitter,
3435  update,
3436  translate,
3437  transition,
3438  slide,
3439  loop,
3440  grabCursor,
3441  events: events$1,
3442  breakpoints,
3443  checkOverflow: checkOverflow$1,
3444  classes,
3445};
3446const extendedDefaults = {};
3447class Swiper {
3448  constructor() {
3449    let el;
3450    let params;
3451    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3452      args[_key] = arguments[_key];
3453    }
3454    if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
3455      params = args[0];
3456    } else {
3457      [el, params] = args;
3458    }
3459    if (!params) params = {};
3460    params = extend({}, params);
3461    if (el && !params.el) params.el = el;
3462    const document = getDocument();
3463    if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
3464      const swipers = [];
3465      document.querySelectorAll(params.el).forEach((containerEl) => {
3466        const newParams = extend({}, params, {
3467          el: containerEl,
3468        });
3469        swipers.push(new Swiper(newParams));
3470      });
3471      // eslint-disable-next-line no-constructor-return
3472      return swipers;
3473    }
3474
3475    // Swiper Instance
3476    const swiper = this;
3477    swiper.__swiper__ = true;
3478    swiper.support = getSupport();
3479    swiper.device = getDevice({
3480      userAgent: params.userAgent,
3481    });
3482    swiper.browser = getBrowser();
3483    swiper.eventsListeners = {};
3484    swiper.eventsAnyListeners = [];
3485    swiper.modules = [...swiper.__modules__];
3486    if (params.modules && Array.isArray(params.modules)) {
3487      swiper.modules.push(...params.modules);
3488    }
3489    const allModulesParams = {};
3490    swiper.modules.forEach((mod) => {
3491      mod({
3492        params,
3493        swiper,
3494        extendParams: moduleExtendParams(params, allModulesParams),
3495        on: swiper.on.bind(swiper),
3496        once: swiper.once.bind(swiper),
3497        off: swiper.off.bind(swiper),
3498        emit: swiper.emit.bind(swiper),
3499      });
3500    });
3501
3502    // Extend defaults with modules params
3503    const swiperParams = extend({}, defaults, allModulesParams);
3504
3505    // Extend defaults with passed params
3506    swiper.params = extend({}, swiperParams, extendedDefaults, params);
3507    swiper.originalParams = extend({}, swiper.params);
3508    swiper.passedParams = extend({}, params);
3509
3510    // add event listeners
3511    if (swiper.params && swiper.params.on) {
vendor: 4,249 bytes, lines 3512-3654
3512      Object.keys(swiper.params.on).forEach((eventName) => {
3513        swiper.on(eventName, swiper.params.on[eventName]);
3514      });
3515    }
3516    if (swiper.params && swiper.params.onAny) {
3517      swiper.onAny(swiper.params.onAny);
3518    }
3519
3520    // Extend Swiper
3521    Object.assign(swiper, {
3522      enabled: swiper.params.enabled,
3523      el,
3524      // Classes
3525      classNames: [],
3526      // Slides
3527      slides: [],
3528      slidesGrid: [],
3529      snapGrid: [],
3530      slidesSizesGrid: [],
3531      // isDirection
3532      isHorizontal() {
3533        return swiper.params.direction === 'horizontal';
3534      },
3535      isVertical() {
3536        return swiper.params.direction === 'vertical';
3537      },
3538      // Indexes
3539      activeIndex: 0,
3540      realIndex: 0,
3541      //
3542      isBeginning: true,
3543      isEnd: false,
3544      // Props
3545      translate: 0,
3546      previousTranslate: 0,
3547      progress: 0,
3548      velocity: 0,
3549      animating: false,
3550      cssOverflowAdjustment() {
3551        // Returns 0 unless `translate` is > 2**23
3552        // Should be subtracted from css values to prevent overflow
3553        return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
3554      },
3555      // Locks
3556      allowSlideNext: swiper.params.allowSlideNext,
3557      allowSlidePrev: swiper.params.allowSlidePrev,
3558      // Touch Events
3559      touchEventsData: {
3560        isTouched: undefined,
3561        isMoved: undefined,
3562        allowTouchCallbacks: undefined,
3563        touchStartTime: undefined,
3564        isScrolling: undefined,
3565        currentTranslate: undefined,
3566        startTranslate: undefined,
3567        allowThresholdMove: undefined,
3568        // Form elements to match
3569        focusableElements: swiper.params.focusableElements,
3570        // Last click time
3571        lastClickTime: 0,
3572        clickTimeout: undefined,
3573        // Velocities
3574        velocities: [],
3575        allowMomentumBounce: undefined,
3576        startMoving: undefined,
3577        evCache: [],
3578      },
3579      // Clicks
3580      allowClick: true,
3581      // Touches
3582      allowTouchMove: swiper.params.allowTouchMove,
3583      touches: {
3584        startX: 0,
3585        startY: 0,
3586        currentX: 0,
3587        currentY: 0,
3588        diff: 0,
3589      },
3590      // Images
3591      imagesToLoad: [],
3592      imagesLoaded: 0,
3593    });
3594    swiper.emit('_swiper');
3595
3596    // Init
3597    if (swiper.params.init) {
3598      swiper.init();
3599    }
3600
3601    // Return app instance
3602    // eslint-disable-next-line no-constructor-return
3603    return swiper;
3604  }
3605  getSlideIndex(slideEl) {
3606    const { slidesEl, params } = this;
3607    const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3608    const firstSlideIndex = elementIndex(slides[0]);
3609    return elementIndex(slideEl) - firstSlideIndex;
3610  }
3611  getSlideIndexByData(index) {
3612    return this.getSlideIndex(
3613      this.slides.filter((slideEl) => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)[0]
3614    );
3615  }
3616  recalcSlides() {
3617    const swiper = this;
3618    const { slidesEl, params } = swiper;
3619    swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
3620  }
3621  enable() {
3622    const swiper = this;
3623    if (swiper.enabled) return;
3624    swiper.enabled = true;
3625    if (swiper.params.grabCursor) {
3626      swiper.setGrabCursor();
3627    }
3628    swiper.emit('enable');
3629  }
3630  disable() {
3631    const swiper = this;
3632    if (!swiper.enabled) return;
3633    swiper.enabled = false;
3634    if (swiper.params.grabCursor) {
3635      swiper.unsetGrabCursor();
3636    }
3637    swiper.emit('disable');
3638  }
3639  setProgress(progress, speed) {
3640    const swiper = this;
3641    progress = Math.min(Math.max(progress, 0), 1);
3642    const min = swiper.minTranslate();
3643    const max = swiper.maxTranslate();
3644    const current = (max - min) * progress + min;
3645    swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
3646    swiper.updateActiveIndex();
3647    swiper.updateSlidesClasses();
3648  }
3649  emitContainerClasses() {
3650    const swiper = this;
3651    if (!swiper.params._emitClasses || !swiper.el) return;
3652    const cls = swiper.el.className.split(' ').filter((className) => {
3653      return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
3654    });
vendor: 6,901 bytes, lines 3655-3854
3655    swiper.emit('_containerClasses', cls.join(' '));
3656  }
3657  getSlideClasses(slideEl) {
3658    const swiper = this;
3659    if (swiper.destroyed) return '';
3660    return slideEl.className
3661      .split(' ')
3662      .filter((className) => {
3663        return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
3664      })
3665      .join(' ');
3666  }
3667  emitSlidesClasses() {
3668    const swiper = this;
3669    if (!swiper.params._emitClasses || !swiper.el) return;
3670    const updates = [];
3671    swiper.slides.forEach((slideEl) => {
3672      const classNames = swiper.getSlideClasses(slideEl);
3673      updates.push({
3674        slideEl,
3675        classNames,
3676      });
3677      swiper.emit('_slideClass', slideEl, classNames);
3678    });
3679    swiper.emit('_slideClasses', updates);
3680  }
3681  slidesPerViewDynamic(view, exact) {
3682    if (view === void 0) {
3683      view = 'current';
3684    }
3685    if (exact === void 0) {
3686      exact = false;
3687    }
3688    const swiper = this;
3689    const { params, slides, slidesGrid, slidesSizesGrid, size: swiperSize, activeIndex } = swiper;
3690    let spv = 1;
3691    if (params.centeredSlides) {
3692      let slideSize = slides[activeIndex] ? slides[activeIndex].swiperSlideSize : 0;
3693      let breakLoop;
3694      for (let i = activeIndex + 1; i < slides.length; i += 1) {
3695        if (slides[i] && !breakLoop) {
3696          slideSize += slides[i].swiperSlideSize;
3697          spv += 1;
3698          if (slideSize > swiperSize) breakLoop = true;
3699        }
3700      }
3701      for (let i = activeIndex - 1; i >= 0; i -= 1) {
3702        if (slides[i] && !breakLoop) {
3703          slideSize += slides[i].swiperSlideSize;
3704          spv += 1;
3705          if (slideSize > swiperSize) breakLoop = true;
3706        }
3707      }
3708    } else {
3709      // eslint-disable-next-line
3710      if (view === 'current') {
3711        for (let i = activeIndex + 1; i < slides.length; i += 1) {
3712          const slideInView = exact
3713            ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize
3714            : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
3715          if (slideInView) {
3716            spv += 1;
3717          }
3718        }
3719      } else {
3720        // previous
3721        for (let i = activeIndex - 1; i >= 0; i -= 1) {
3722          const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
3723          if (slideInView) {
3724            spv += 1;
3725          }
3726        }
3727      }
3728    }
3729    return spv;
3730  }
3731  update() {
3732    const swiper = this;
3733    if (!swiper || swiper.destroyed) return;
3734    const { snapGrid, params } = swiper;
3735    // Breakpoints
3736    if (params.breakpoints) {
3737      swiper.setBreakpoint();
3738    }
3739    [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach((imageEl) => {
3740      if (imageEl.complete) {
3741        processLazyPreloader(swiper, imageEl);
3742      }
3743    });
3744    swiper.updateSize();
3745    swiper.updateSlides();
3746    swiper.updateProgress();
3747    swiper.updateSlidesClasses();
3748    function setTranslate() {
3749      const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
3750      const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
3751      swiper.setTranslate(newTranslate);
3752      swiper.updateActiveIndex();
3753      swiper.updateSlidesClasses();
3754    }
3755    let translated;
3756    if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
3757      setTranslate();
3758      if (params.autoHeight) {
3759        swiper.updateAutoHeight();
3760      }
3761    } else {
3762      if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
3763        const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
3764        translated = swiper.slideTo(slides.length - 1, 0, false, true);
3765      } else {
3766        translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
3767      }
3768      if (!translated) {
3769        setTranslate();
3770      }
3771    }
3772    if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
3773      swiper.checkOverflow();
3774    }
3775    swiper.emit('update');
3776  }
3777  changeDirection(newDirection, needUpdate) {
3778    if (needUpdate === void 0) {
3779      needUpdate = true;
3780    }
3781    const swiper = this;
3782    const currentDirection = swiper.params.direction;
3783    if (!newDirection) {
3784      // eslint-disable-next-line
3785      newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
3786    }
3787    if (newDirection === currentDirection || (newDirection !== 'horizontal' && newDirection !== 'vertical')) {
3788      return swiper;
3789    }
3790    swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
3791    swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
3792    swiper.emitContainerClasses();
3793    swiper.params.direction = newDirection;
3794    swiper.slides.forEach((slideEl) => {
3795      if (newDirection === 'vertical') {
3796        slideEl.style.width = '';
3797      } else {
3798        slideEl.style.height = '';
3799      }
3800    });
3801    swiper.emit('changeDirection');
3802    if (needUpdate) swiper.update();
3803    return swiper;
3804  }
3805  changeLanguageDirection(direction) {
3806    const swiper = this;
3807    if ((swiper.rtl && direction === 'rtl') || (!swiper.rtl && direction === 'ltr')) return;
3808    swiper.rtl = direction === 'rtl';
3809    swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
3810    if (swiper.rtl) {
3811      swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
3812      swiper.el.dir = 'rtl';
3813    } else {
3814      swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
3815      swiper.el.dir = 'ltr';
3816    }
3817    swiper.update();
3818  }
3819  mount(element) {
3820    const swiper = this;
3821    if (swiper.mounted) return true;
3822
3823    // Find el
3824    let el = element || swiper.params.el;
3825    if (typeof el === 'string') {
3826      el = document.querySelector(el);
3827    }
3828    if (!el) {
3829      return false;
3830    }
3831    el.swiper = swiper;
3832    if (el.shadowEl) {
3833      swiper.isElement = true;
3834    }
3835    const getWrapperSelector = () => {
3836      return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
3837    };
3838    const getWrapper = () => {
3839      if (el && el.shadowRoot && el.shadowRoot.querySelector) {
3840        const res = el.shadowRoot.querySelector(getWrapperSelector());
3841        // Children needs to return slot items
3842        return res;
3843      }
3844      return elementChildren(el, getWrapperSelector())[0];
3845    };
3846    // Find Wrapper
3847    let wrapperEl = getWrapper();
3848    if (!wrapperEl && swiper.params.createElements) {
3849      wrapperEl = createElement('div', swiper.params.wrapperClass);
3850      el.append(wrapperEl);
3851      elementChildren(el, `.${swiper.params.slideClass}`).forEach((slideEl) => {
3852        wrapperEl.append(slideEl);
3853      });
3854    }
vendor: 4,363 bytes, lines 3855-4018
3855    Object.assign(swiper, {
3856      el,
3857      wrapperEl,
3858      slidesEl: swiper.isElement ? el : wrapperEl,
3859      mounted: true,
3860      // RTL
3861      rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
3862      rtlTranslate:
3863        swiper.params.direction === 'horizontal' &&
3864        (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
3865      wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box',
3866    });
3867    return true;
3868  }
3869  init(el) {
3870    const swiper = this;
3871    if (swiper.initialized) return swiper;
3872    const mounted = swiper.mount(el);
3873    if (mounted === false) return swiper;
3874    swiper.emit('beforeInit');
3875
3876    // Set breakpoint
3877    if (swiper.params.breakpoints) {
3878      swiper.setBreakpoint();
3879    }
3880
3881    // Add Classes
3882    swiper.addClasses();
3883
3884    // Update size
3885    swiper.updateSize();
3886
3887    // Update slides
3888    swiper.updateSlides();
3889    if (swiper.params.watchOverflow) {
3890      swiper.checkOverflow();
3891    }
3892
3893    // Set Grab Cursor
3894    if (swiper.params.grabCursor && swiper.enabled) {
3895      swiper.setGrabCursor();
3896    }
3897
3898    // Slide To Initial Slide
3899    if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
3900      swiper.slideTo(
3901        swiper.params.initialSlide + swiper.virtual.slidesBefore,
3902        0,
3903        swiper.params.runCallbacksOnInit,
3904        false,
3905        true
3906      );
3907    } else {
3908      swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
3909    }
3910
3911    // Create loop
3912    if (swiper.params.loop) {
3913      swiper.loopCreate();
3914    }
3915
3916    // Attach events
3917    swiper.attachEvents();
3918    [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach((imageEl) => {
3919      if (imageEl.complete) {
3920        processLazyPreloader(swiper, imageEl);
3921      } else {
3922        imageEl.addEventListener('load', (e) => {
3923          processLazyPreloader(swiper, e.target);
3924        });
3925      }
3926    });
3927    preload(swiper);
3928
3929    // Init Flag
3930    swiper.initialized = true;
3931    preload(swiper);
3932
3933    // Emit
3934    swiper.emit('init');
3935    swiper.emit('afterInit');
3936    return swiper;
3937  }
3938  destroy(deleteInstance, cleanStyles) {
3939    if (deleteInstance === void 0) {
3940      deleteInstance = true;
3941    }
3942    if (cleanStyles === void 0) {
3943      cleanStyles = true;
3944    }
3945    const swiper = this;
3946    const { params, el, wrapperEl, slides } = swiper;
3947    if (typeof swiper.params === 'undefined' || swiper.destroyed) {
3948      return null;
3949    }
3950    swiper.emit('beforeDestroy');
3951
3952    // Init Flag
3953    swiper.initialized = false;
3954
3955    // Detach events
3956    swiper.detachEvents();
3957
3958    // Destroy loop
3959    if (params.loop) {
3960      swiper.loopDestroy();
3961    }
3962
3963    // Cleanup styles
3964    if (cleanStyles) {
3965      swiper.removeClasses();
3966      el.removeAttribute('style');
3967      wrapperEl.removeAttribute('style');
3968      if (slides && slides.length) {
3969        slides.forEach((slideEl) => {
3970          slideEl.classList.remove(
3971            params.slideVisibleClass,
3972            params.slideActiveClass,
3973            params.slideNextClass,
3974            params.slidePrevClass
3975          );
3976          slideEl.removeAttribute('style');
3977          slideEl.removeAttribute('data-swiper-slide-index');
3978        });
3979      }
3980    }
3981    swiper.emit('destroy');
3982
3983    // Detach emitter events
3984    Object.keys(swiper.eventsListeners).forEach((eventName) => {
3985      swiper.off(eventName);
3986    });
3987    if (deleteInstance !== false) {
3988      swiper.el.swiper = null;
3989      deleteProps(swiper);
3990    }
3991    swiper.destroyed = true;
3992    return null;
3993  }
3994  static extendDefaults(newDefaults) {
3995    extend(extendedDefaults, newDefaults);
3996  }
3997  static get extendedDefaults() {
3998    return extendedDefaults;
3999  }
4000  static get defaults() {
4001    return defaults;
4002  }
4003  static installModule(mod) {
4004    if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
4005    const modules = Swiper.prototype.__modules__;
4006    if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
4007      modules.push(mod);
4008    }
4009  }
4010  static use(module) {
4011    if (Array.isArray(module)) {
4012      module.forEach((m) => Swiper.installModule(m));
4013      return Swiper;
4014    }
4015    Swiper.installModule(module);
4016    return Swiper;
4017  }
4018}
4019Object.keys(prototypes).forEach((prototypeGroup) => {
4020  Object.keys(prototypes[prototypeGroup]).forEach((protoMethod) => {
4021    Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
4022  });
4023});
4024Swiper.use([Resize, Observer]);
4025
4026function Virtual(_ref) {
4027  let { swiper, extendParams, on, emit } = _ref;
4028  extendParams({
4029    virtual: {
4030      enabled: false,
4031      slides: [],
4032      cache: true,
4033      renderSlide: null,
4034      renderExternal: null,
4035      renderExternalUpdate: true,
4036      addSlidesBefore: 0,
4037      addSlidesAfter: 0,
4038    },
4039  });
4040  let cssModeTimeout;
4041  const document = getDocument();
4042  swiper.virtual = {
4043    cache: {},
4044    from: undefined,
4045    to: undefined,
4046    slides: [],
4047    offset: 0,
4048    slidesGrid: [],
4049  };
4050  const tempDOM = document.createElement('div');
4051  function renderSlide(slide, index) {
4052    const params = swiper.params.virtual;
4053    if (params.cache && swiper.virtual.cache[index]) {
4054      return swiper.virtual.cache[index];
4055    }
4056    // eslint-disable-next-line
4057    let slideEl;
4058    if (params.renderSlide) {
4059      slideEl = params.renderSlide.call(swiper, slide, index);
4060      if (typeof slideEl === 'string') {
4061        tempDOM.innerHTML = slideEl;
4062        slideEl = tempDOM.children[0];
4063      }
4064    } else if (swiper.isElement) {
4065      slideEl = createElement('swiper-slide');
4066    } else {
4067      slideEl = createElement('div', swiper.params.slideClass);
4068    }
4069    slideEl.setAttribute('data-swiper-slide-index', index);
4070    if (!params.renderSlide) {
4071      slideEl.innerHTML = slide;
4072    }
4073    if (params.cache) swiper.virtual.cache[index] = slideEl;
4074    return slideEl;
4075  }
4076  function update(force) {
4077    const { slidesPerView, slidesPerGroup, centeredSlides, loop: isLoop } = swiper.params;
4078    const { addSlidesBefore, addSlidesAfter } = swiper.params.virtual;
4079    const {
4080      from: previousFrom,
4081      to: previousTo,
4082      slides,
4083      slidesGrid: previousSlidesGrid,
4084      offset: previousOffset,
4085    } = swiper.virtual;
4086    if (!swiper.params.cssMode) {
4087      swiper.updateActiveIndex();
4088    }
4089    const activeIndex = swiper.activeIndex || 0;
4090    let offsetProp;
4091    if (swiper.rtlTranslate) offsetProp = 'right';
4092    else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
4093    let slidesAfter;
4094    let slidesBefore;
4095    if (centeredSlides) {
4096      slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
4097      slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
4098    } else {
4099      slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
4100      slidesBefore = (isLoop ? slidesPerView : slidesPerGroup) + addSlidesBefore;
4101    }
4102    let from = activeIndex - slidesBefore;
4103    let to = activeIndex + slidesAfter;
4104    if (!isLoop) {
4105      from = Math.max(from, 0);
4106      to = Math.min(to, slides.length - 1);
4107    }
4108    let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
4109    if (isLoop && activeIndex >= slidesBefore) {
4110      from -= slidesBefore;
4111      if (!centeredSlides) offset += swiper.slidesGrid[0];
4112    } else if (isLoop && activeIndex < slidesBefore) {
4113      from = -slidesBefore;
4114      if (centeredSlides) offset += swiper.slidesGrid[0];
4115    }
4116    Object.assign(swiper.virtual, {
4117      from,
4118      to,
4119      offset,
4120      slidesGrid: swiper.slidesGrid,
4121      slidesBefore,
4122      slidesAfter,
4123    });
4124    function onRendered() {
4125      swiper.updateSlides();
4126      swiper.updateProgress();
4127      swiper.updateSlidesClasses();
4128      emit('virtualUpdate');
4129    }
4130    if (previousFrom === from && previousTo === to && !force) {
4131      if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
4132        swiper.slides.forEach((slideEl) => {
4133          slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4134        });
4135      }
4136      swiper.updateProgress();
4137      emit('virtualUpdate');
4138      return;
4139    }
4140    if (swiper.params.virtual.renderExternal) {
vendor: 5,762 bytes, lines 4141-4301
4141      swiper.params.virtual.renderExternal.call(swiper, {
4142        offset,
4143        from,
4144        to,
4145        slides: (function getSlides() {
4146          const slidesToRender = [];
4147          for (let i = from; i <= to; i += 1) {
4148            slidesToRender.push(slides[i]);
4149          }
4150          return slidesToRender;
4151        })(),
4152      });
4153      if (swiper.params.virtual.renderExternalUpdate) {
4154        onRendered();
4155      } else {
4156        emit('virtualUpdate');
4157      }
4158      return;
4159    }
4160    const prependIndexes = [];
4161    const appendIndexes = [];
4162    const getSlideIndex = (index) => {
4163      let slideIndex = index;
4164      if (index < 0) {
4165        slideIndex = slides.length + index;
4166      } else if (slideIndex >= slides.length) {
4167        // eslint-disable-next-line
4168        slideIndex = slideIndex - slides.length;
4169      }
4170      return slideIndex;
4171    };
4172    if (force) {
4173      swiper.slidesEl.querySelectorAll(`.${swiper.params.slideClass}, swiper-slide`).forEach((slideEl) => {
4174        slideEl.remove();
4175      });
4176    } else {
4177      for (let i = previousFrom; i <= previousTo; i += 1) {
4178        if (i < from || i > to) {
4179          const slideIndex = getSlideIndex(i);
4180          swiper.slidesEl
4181            .querySelectorAll(
4182              `.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`
4183            )
4184            .forEach((slideEl) => {
4185              slideEl.remove();
4186            });
4187        }
4188      }
4189    }
4190    const loopFrom = isLoop ? -slides.length : 0;
4191    const loopTo = isLoop ? slides.length * 2 : slides.length;
4192    for (let i = loopFrom; i < loopTo; i += 1) {
4193      if (i >= from && i <= to) {
4194        const slideIndex = getSlideIndex(i);
4195        if (typeof previousTo === 'undefined' || force) {
4196          appendIndexes.push(slideIndex);
4197        } else {
4198          if (i > previousTo) appendIndexes.push(slideIndex);
4199          if (i < previousFrom) prependIndexes.push(slideIndex);
4200        }
4201      }
4202    }
4203    appendIndexes.forEach((index) => {
4204      swiper.slidesEl.append(renderSlide(slides[index], index));
4205    });
4206    if (isLoop) {
4207      for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
4208        const index = prependIndexes[i];
4209        swiper.slidesEl.prepend(renderSlide(slides[index], index));
4210      }
4211    } else {
4212      prependIndexes.sort((a, b) => b - a);
4213      prependIndexes.forEach((index) => {
4214        swiper.slidesEl.prepend(renderSlide(slides[index], index));
4215      });
4216    }
4217    elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach((slideEl) => {
4218      slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
4219    });
4220    onRendered();
4221  }
4222  function appendSlide(slides) {
4223    if (typeof slides === 'object' && 'length' in slides) {
4224      for (let i = 0; i < slides.length; i += 1) {
4225        if (slides[i]) swiper.virtual.slides.push(slides[i]);
4226      }
4227    } else {
4228      swiper.virtual.slides.push(slides);
4229    }
4230    update(true);
4231  }
4232  function prependSlide(slides) {
4233    const activeIndex = swiper.activeIndex;
4234    let newActiveIndex = activeIndex + 1;
4235    let numberOfNewSlides = 1;
4236    if (Array.isArray(slides)) {
4237      for (let i = 0; i < slides.length; i += 1) {
4238        if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
4239      }
4240      newActiveIndex = activeIndex + slides.length;
4241      numberOfNewSlides = slides.length;
4242    } else {
4243      swiper.virtual.slides.unshift(slides);
4244    }
4245    if (swiper.params.virtual.cache) {
4246      const cache = swiper.virtual.cache;
4247      const newCache = {};
4248      Object.keys(cache).forEach((cachedIndex) => {
4249        const cachedEl = cache[cachedIndex];
4250        const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
4251        if (cachedElIndex) {
4252          cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
4253        }
4254        newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
4255      });
4256      swiper.virtual.cache = newCache;
4257    }
4258    update(true);
4259    swiper.slideTo(newActiveIndex, 0);
4260  }
4261  function removeSlide(slidesIndexes) {
4262    if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
4263    let activeIndex = swiper.activeIndex;
4264    if (Array.isArray(slidesIndexes)) {
4265      for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
4266        swiper.virtual.slides.splice(slidesIndexes[i], 1);
4267        if (swiper.params.virtual.cache) {
4268          delete swiper.virtual.cache[slidesIndexes[i]];
4269        }
4270        if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
4271        activeIndex = Math.max(activeIndex, 0);
4272      }
4273    } else {
4274      swiper.virtual.slides.splice(slidesIndexes, 1);
4275      if (swiper.params.virtual.cache) {
4276        delete swiper.virtual.cache[slidesIndexes];
4277      }
4278      if (slidesIndexes < activeIndex) activeIndex -= 1;
4279      activeIndex = Math.max(activeIndex, 0);
4280    }
4281    update(true);
4282    swiper.slideTo(activeIndex, 0);
4283  }
4284  function removeAllSlides() {
4285    swiper.virtual.slides = [];
4286    if (swiper.params.virtual.cache) {
4287      swiper.virtual.cache = {};
4288    }
4289    update(true);
4290    swiper.slideTo(0, 0);
4291  }
4292  on('beforeInit', () => {
4293    if (!swiper.params.virtual.enabled) return;
4294    let domSlidesAssigned;
4295    if (typeof swiper.passedParams.virtual.slides === 'undefined') {
4296      const slides = [...swiper.slidesEl.children].filter((el) =>
4297        el.matches(`.${swiper.params.slideClass}, swiper-slide`)
4298      );
4299      if (slides && slides.length) {
4300        swiper.virtual.slides = [...slides];
4301        domSlidesAssigned = true;
4302        slides.forEach((slideEl, slideIndex) => {
4303          slideEl.setAttribute('data-swiper-slide-index', slideIndex);
4304          swiper.virtual.cache[slideIndex] = slideEl;
4305          slideEl.remove();
4306        });
4307      }
4308    }
4309    if (!domSlidesAssigned) {
4310      swiper.virtual.slides = swiper.params.virtual.slides;
4311    }
4312    swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
4313    swiper.params.watchSlidesProgress = true;
4314    swiper.originalParams.watchSlidesProgress = true;
4315    if (!swiper.params.initialSlide) {
4316      update();
4317    }
4318  });
4319  on('setTranslate', () => {
4320    if (!swiper.params.virtual.enabled) return;
4321    if (swiper.params.cssMode && !swiper._immediateVirtual) {
4322      clearTimeout(cssModeTimeout);
4323      cssModeTimeout = setTimeout(() => {
4324        update();
4325      }, 100);
4326    } else {
4327      update();
4328    }
4329  });
4330  on('init update resize', () => {
4331    if (!swiper.params.virtual.enabled) return;
4332    if (swiper.params.cssMode) {
4333      setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
4334    }
4335  });
4336  Object.assign(swiper.virtual, {
4337    appendSlide,
4338    prependSlide,
4339    removeSlide,
4340    removeAllSlides,
4341    update,
4342  });
4343}
4344
4345/* eslint-disable consistent-return */
4346function Keyboard(_ref) {
4347  let { swiper, extendParams, on, emit } = _ref;
4348  const document = getDocument();
4349  const window = getWindow();
4350  swiper.keyboard = {
4351    enabled: false,
4352  };
4353  extendParams({
4354    keyboard: {
4355      enabled: false,
4356      onlyInViewport: true,
4357      pageUpDown: true,
4358    },
4359  });
4360  function handle(event) {
4361    if (!swiper.enabled) return;
4362    const { rtlTranslate: rtl } = swiper;
4363    let e = event;
4364    if (e.originalEvent) e = e.originalEvent; // jquery fix
4365    const kc = e.keyCode || e.charCode;
4366    const pageUpDown = swiper.params.keyboard.pageUpDown;
4367    const isPageUp = pageUpDown && kc === 33;
4368    const isPageDown = pageUpDown && kc === 34;
4369    const isArrowLeft = kc === 37;
4370    const isArrowRight = kc === 39;
4371    const isArrowUp = kc === 38;
4372    const isArrowDown = kc === 40;
4373    // Directions locks
4374    if (
4375      !swiper.allowSlideNext &&
4376      ((swiper.isHorizontal() && isArrowRight) || (swiper.isVertical() && isArrowDown) || isPageDown)
4377    ) {
4378      return false;
4379    }
4380    if (
4381      !swiper.allowSlidePrev &&
4382      ((swiper.isHorizontal() && isArrowLeft) || (swiper.isVertical() && isArrowUp) || isPageUp)
4383    ) {
4384      return false;
4385    }
4386    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
4387      return undefined;
4388    }
4389    if (
4390      document.activeElement &&
4391      document.activeElement.nodeName &&
4392      (document.activeElement.nodeName.toLowerCase() === 'input' ||
4393        document.activeElement.nodeName.toLowerCase() === 'textarea')
4394    ) {
4395      return undefined;
4396    }
4397    if (
4398      swiper.params.keyboard.onlyInViewport &&
4399      (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)
4400    ) {
4401      let inView = false;
4402      // Check that swiper should be inside of visible area of window
4403      if (
4404        elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 &&
4405        elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0
4406      ) {
4407        return undefined;
4408      }
4409      const el = swiper.el;
4410      const swiperWidth = el.clientWidth;
4411      const swiperHeight = el.clientHeight;
4412      const windowWidth = window.innerWidth;
4413      const windowHeight = window.innerHeight;
4414      const swiperOffset = elementOffset(el);
4415      if (rtl) swiperOffset.left -= el.scrollLeft;
4416      const swiperCoord = [
4417        [swiperOffset.left, swiperOffset.top],
4418        [swiperOffset.left + swiperWidth, swiperOffset.top],
4419        [swiperOffset.left, swiperOffset.top + swiperHeight],
4420        [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight],
4421      ];
4422      for (let i = 0; i < swiperCoord.length; i += 1) {
4423        const point = swiperCoord[i];
4424        if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
4425          if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
4426          inView = true;
4427        }
4428      }
4429      if (!inView) return undefined;
4430    }
4431    if (swiper.isHorizontal()) {
4432      if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
4433        if (e.preventDefault) e.preventDefault();
4434        else e.returnValue = false;
4435      }
4436      if (((isPageDown || isArrowRight) && !rtl) || ((isPageUp || isArrowLeft) && rtl)) swiper.slideNext();
4437      if (((isPageUp || isArrowLeft) && !rtl) || ((isPageDown || isArrowRight) && rtl)) swiper.slidePrev();
4438    } else {
4439      if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
4440        if (e.preventDefault) e.preventDefault();
4441        else e.returnValue = false;
4442      }
4443      if (isPageDown || isArrowDown) swiper.slideNext();
4444      if (isPageUp || isArrowUp) swiper.slidePrev();
4445    }
4446    emit('keyPress', kc);
4447    return undefined;
4448  }
4449  function enable() {
4450    if (swiper.keyboard.enabled) return;
4451    document.addEventListener('keydown', handle);
4452    swiper.keyboard.enabled = true;
4453  }
4454  function disable() {
4455    if (!swiper.keyboard.enabled) return;
4456    document.removeEventListener('keydown', handle);
4457    swiper.keyboard.enabled = false;
4458  }
4459  on('init', () => {
4460    if (swiper.params.keyboard.enabled) {
4461      enable();
4462    }
4463  });
4464  on('destroy', () => {
4465    if (swiper.keyboard.enabled) {
4466      disable();
4467    }
4468  });
4469  Object.assign(swiper.keyboard, {
4470    enable,
4471    disable,
4472  });
4473}
4474
4475/* eslint-disable consistent-return */
4476function Mousewheel(_ref) {
4477  let { swiper, extendParams, on, emit } = _ref;
4478  const window = getWindow();
4479  extendParams({
4480    mousewheel: {
4481      enabled: false,
4482      releaseOnEdges: false,
4483      invert: false,
vendor: 5,733 bytes, lines 4484-4659
4484      forceToAxis: false,
4485      sensitivity: 1,
4486      eventsTarget: 'container',
4487      thresholdDelta: null,
4488      thresholdTime: null,
4489      noMousewheelClass: 'swiper-no-mousewheel',
4490    },
4491  });
4492  swiper.mousewheel = {
4493    enabled: false,
4494  };
4495  let timeout;
4496  let lastScrollTime = now();
4497  let lastEventBeforeSnap;
4498  const recentWheelEvents = [];
4499  function normalize(e) {
4500    // Reasonable defaults
4501    const PIXEL_STEP = 10;
4502    const LINE_HEIGHT = 40;
4503    const PAGE_HEIGHT = 800;
4504    let sX = 0;
4505    let sY = 0; // spinX, spinY
4506    let pX = 0;
4507    let pY = 0; // pixelX, pixelY
4508
4509    // Legacy
4510    if ('detail' in e) {
4511      sY = e.detail;
4512    }
4513    if ('wheelDelta' in e) {
4514      sY = -e.wheelDelta / 120;
4515    }
4516    if ('wheelDeltaY' in e) {
4517      sY = -e.wheelDeltaY / 120;
4518    }
4519    if ('wheelDeltaX' in e) {
4520      sX = -e.wheelDeltaX / 120;
4521    }
4522
4523    // side scrolling on FF with DOMMouseScroll
4524    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
4525      sX = sY;
4526      sY = 0;
4527    }
4528    pX = sX * PIXEL_STEP;
4529    pY = sY * PIXEL_STEP;
4530    if ('deltaY' in e) {
4531      pY = e.deltaY;
4532    }
4533    if ('deltaX' in e) {
4534      pX = e.deltaX;
4535    }
4536    if (e.shiftKey && !pX) {
4537      // if user scrolls with shift he wants horizontal scroll
4538      pX = pY;
4539      pY = 0;
4540    }
4541    if ((pX || pY) && e.deltaMode) {
4542      if (e.deltaMode === 1) {
4543        // delta in LINE units
4544        pX *= LINE_HEIGHT;
4545        pY *= LINE_HEIGHT;
4546      } else {
4547        // delta in PAGE units
4548        pX *= PAGE_HEIGHT;
4549        pY *= PAGE_HEIGHT;
4550      }
4551    }
4552
4553    // Fall-back if spin cannot be determined
4554    if (pX && !sX) {
4555      sX = pX < 1 ? -1 : 1;
4556    }
4557    if (pY && !sY) {
4558      sY = pY < 1 ? -1 : 1;
4559    }
4560    return {
4561      spinX: sX,
4562      spinY: sY,
4563      pixelX: pX,
4564      pixelY: pY,
4565    };
4566  }
4567  function handleMouseEnter() {
4568    if (!swiper.enabled) return;
4569    swiper.mouseEntered = true;
4570  }
4571  function handleMouseLeave() {
4572    if (!swiper.enabled) return;
4573    swiper.mouseEntered = false;
4574  }
4575  function animateSlider(newEvent) {
4576    if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
4577      // Prevent if delta of wheel scroll delta is below configured threshold
4578      return false;
4579    }
4580    if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
4581      // Prevent if time between scrolls is below configured threshold
4582      return false;
4583    }
4584
4585    // If the movement is NOT big enough and
4586    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
4587    //   Don't go any further (avoid insignificant scroll movement).
4588    if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
4589      // Return false as a default
4590      return true;
4591    }
4592    // If user is scrolling towards the end:
4593    //   If the slider hasn't hit the latest slide or
4594    //   if the slider is a loop and
4595    //   if the slider isn't moving right now:
4596    //     Go to next slide and
4597    //     emit a scroll event.
4598    // Else (the user is scrolling towards the beginning) and
4599    // if the slider hasn't hit the first slide or
4600    // if the slider is a loop and
4601    // if the slider isn't moving right now:
4602    //   Go to prev slide and
4603    //   emit a scroll event.
4604    if (newEvent.direction < 0) {
4605      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
4606        swiper.slideNext();
4607        emit('scroll', newEvent.raw);
4608      }
4609    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
4610      swiper.slidePrev();
4611      emit('scroll', newEvent.raw);
4612    }
4613    // If you got here is because an animation has been triggered so store the current time
4614    lastScrollTime = new window.Date().getTime();
4615    // Return false as a default
4616    return false;
4617  }
4618  function releaseScroll(newEvent) {
4619    const params = swiper.params.mousewheel;
4620    if (newEvent.direction < 0) {
4621      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
4622        // Return true to animate scroll on edges
4623        return true;
4624      }
4625    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
4626      // Return true to animate scroll on edges
4627      return true;
4628    }
4629    return false;
4630  }
4631  function handle(event) {
4632    let e = event;
4633    let disableParentSwiper = true;
4634    if (!swiper.enabled) return;
4635
4636    // Ignore event if the target or its parents have the swiper-no-mousewheel class
4637    if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
4638    const params = swiper.params.mousewheel;
4639    if (swiper.params.cssMode) {
4640      e.preventDefault();
4641    }
4642    let targetEl = swiper.el;
4643    if (swiper.params.mousewheel.eventsTarget !== 'container') {
4644      targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
4645    }
4646    const targetElContainsTarget = targetEl && targetEl.contains(e.target);
4647    if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
4648    if (e.originalEvent) e = e.originalEvent; // jquery fix
4649    let delta = 0;
4650    const rtlFactor = swiper.rtlTranslate ? -1 : 1;
4651    const data = normalize(e);
4652    if (params.forceToAxis) {
4653      if (swiper.isHorizontal()) {
4654        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;
4655        else return true;
4656      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;
4657      else return true;
4658    } else {
4659      delta = Math.abs(data.pixelX) >
vendor: 4,188 bytes, lines 4659-4760
4659 Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
4660    }
4661    if (delta === 0) return true;
4662    if (params.invert) delta = -delta;
4663
4664    // Get the scroll positions
4665    let positions = swiper.getTranslate() + delta * params.sensitivity;
4666    if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
4667    if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
4668
4669    // When loop is true:
4670    //     the disableParentSwiper will be true.
4671    // When loop is false:
4672    //     if the scroll positions is not on edge,
4673    //     then the disableParentSwiper will be true.
4674    //     if the scroll on edge positions,
4675    //     then the disableParentSwiper will be false.
4676    disableParentSwiper = swiper.params.loop
4677      ? true
4678      : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
4679    if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
4680    if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
4681      // Register the new event in a variable which stores the relevant data
4682      const newEvent = {
4683        time: now(),
4684        delta: Math.abs(delta),
4685        direction: Math.sign(delta),
4686        raw: event,
4687      };
4688
4689      // Keep the most recent events
4690      if (recentWheelEvents.length >= 2) {
4691        recentWheelEvents.shift(); // only store the last N events
4692      }
4693
4694      const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4695      recentWheelEvents.push(newEvent);
4696
4697      // If there is at least one previous recorded event:
4698      //   If direction has changed or
4699      //   if the scroll is quicker than the previous one:
4700      //     Animate the slider.
4701      // Else (this is the first time the wheel is moved):
4702      //     Animate the slider.
4703      if (prevEvent) {
4704        if (
4705          newEvent.direction !== prevEvent.direction ||
4706          newEvent.delta > prevEvent.delta ||
4707          newEvent.time > prevEvent.time + 150
4708        ) {
4709          animateSlider(newEvent);
4710        }
4711      } else {
4712        animateSlider(newEvent);
4713      }
4714
4715      // If it's time to release the scroll:
4716      //   Return now so you don't hit the preventDefault.
4717      if (releaseScroll(newEvent)) {
4718        return true;
4719      }
4720    } else {
4721      // Freemode or scrollContainer:
4722
4723      // If we recently snapped after a momentum scroll, then ignore wheel events
4724      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
4725      // or if it's a new scroll (larger delta or inverse sign as last event before
4726      // an end-of-momentum snap).
4727      const newEvent = {
4728        time: now(),
4729        delta: Math.abs(delta),
4730        direction: Math.sign(delta),
4731      };
4732      const ignoreWheelEvents =
4733        lastEventBeforeSnap &&
4734        newEvent.time < lastEventBeforeSnap.time + 500 &&
4735        newEvent.delta <= lastEventBeforeSnap.delta &&
4736        newEvent.direction === lastEventBeforeSnap.direction;
4737      if (!ignoreWheelEvents) {
4738        lastEventBeforeSnap = undefined;
4739        let position = swiper.getTranslate() + delta * params.sensitivity;
4740        const wasBeginning = swiper.isBeginning;
4741        const wasEnd = swiper.isEnd;
4742        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
4743        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
4744        swiper.setTransition(0);
4745        swiper.setTranslate(position);
4746        swiper.updateProgress();
4747        swiper.updateActiveIndex();
4748        swiper.updateSlidesClasses();
4749        if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) {
4750          swiper.updateSlidesClasses();
4751        }
4752        if (swiper.params.loop) {
4753          swiper.loopFix({
4754            direction: newEvent.direction < 0 ? 'next' : 'prev',
4755            byMousewheel: true,
4756          });
4757        }
4758        if (swiper.params.freeMode.sticky) {
4759          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
4760          // the end of a momentum scroll by storing recent (N=15?) wheel events.
vendor: 5,039 bytes, lines 4761-4876
4761          // 1. do all N events have decreasing or same (absolute value) delta?
4762          // 2. did all N events arrive in the last M (M=500?) msecs?
4763          // 3. does the earliest event have an (absolute value) delta that's
4764          //    at least P (P=1?) larger than the most recent event's delta?
4765          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
4766          // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
4767          // Snap immediately and ignore remaining wheel events in this scroll.
4768          // See comment above for "remaining wheel events in this scroll" determination.
4769          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
4770          clearTimeout(timeout);
4771          timeout = undefined;
4772          if (recentWheelEvents.length >= 15) {
4773            recentWheelEvents.shift(); // only store the last N events
4774          }
4775
4776          const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
4777          const firstEvent = recentWheelEvents[0];
4778          recentWheelEvents.push(newEvent);
4779          if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
4780            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
4781            recentWheelEvents.splice(0);
4782          } else if (
4783            recentWheelEvents.length >= 15 &&
4784            newEvent.time - firstEvent.time < 500 &&
4785            firstEvent.delta - newEvent.delta >= 1 &&
4786            newEvent.delta <= 6
4787          ) {
4788            // We're at the end of the deceleration of a momentum scroll, so there's no need
4789            // to wait for more events. Snap ASAP on the next tick.
4790            // Also, because there's some remaining momentum we'll bias the snap in the
4791            // direction of the ongoing scroll because it's better UX for the scroll to snap
4792            // in the same direction as the scroll instead of reversing to snap.  Therefore,
4793            // if it's already scrolled more than 20% in the current direction, keep going.
4794            const snapToThreshold = delta > 0 ? 0.8 : 0.2;
4795            lastEventBeforeSnap = newEvent;
4796            recentWheelEvents.splice(0);
4797            timeout = nextTick(() => {
4798              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4799            }, 0); // no delay; move on next tick
4800          }
4801
4802          if (!timeout) {
4803            // if we get here, then we haven't detected the end of a momentum scroll, so
4804            // we'll consider a scroll "complete" when there haven't been any wheel events
4805            // for 500ms.
4806            timeout = nextTick(() => {
4807              const snapToThreshold = 0.5;
4808              lastEventBeforeSnap = newEvent;
4809              recentWheelEvents.splice(0);
4810              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
4811            }, 500);
4812          }
4813        }
4814
4815        // Emit event
4816        if (!ignoreWheelEvents) emit('scroll', e);
4817
4818        // Stop autoplay
4819        if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
4820        // Return page scroll on edge positions
4821        if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
4822      }
4823    }
4824    if (e.preventDefault) e.preventDefault();
4825    else e.returnValue = false;
4826    return false;
4827  }
4828  function events(method) {
4829    let targetEl = swiper.el;
4830    if (swiper.params.mousewheel.eventsTarget !== 'container') {
4831      targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
4832    }
4833    targetEl[method]('mouseenter', handleMouseEnter);
4834    targetEl[method]('mouseleave', handleMouseLeave);
4835    targetEl[method]('wheel', handle);
4836  }
4837  function enable() {
4838    if (swiper.params.cssMode) {
4839      swiper.wrapperEl.removeEventListener('wheel', handle);
4840      return true;
4841    }
4842    if (swiper.mousewheel.enabled) return false;
4843    events('addEventListener');
4844    swiper.mousewheel.enabled = true;
4845    return true;
4846  }
4847  function disable() {
4848    if (swiper.params.cssMode) {
4849      swiper.wrapperEl.addEventListener(event, handle);
4850      return true;
4851    }
4852    if (!swiper.mousewheel.enabled) return false;
4853    events('removeEventListener');
4854    swiper.mousewheel.enabled = false;
4855    return true;
4856  }
4857  on('init', () => {
4858    if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
4859      disable();
4860    }
4861    if (swiper.params.mousewheel.enabled) enable();
4862  });
4863  on('destroy', () => {
4864    if (swiper.params.cssMode) {
4865      enable();
4866    }
4867    if (swiper.mousewheel.enabled) disable();
4868  });
4869  Object.assign(swiper.mousewheel, {
4870    enable,
4871    disable,
4872  });
4873}
4874
4875function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
4876  if (swiper.params.createElements) {
4877    Object.keys(checkProps).forEach((key) => {
4878      if (!params[key] && params.auto === true) {
4879        let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
4880        if (!element) {
4881          element = createElement('div', checkProps[key]);
4882          element.className = checkProps[key];
4883          swiper.el.append(element);
4884        }
4885        params[key] = element;
4886        originalParams[key] = element;
4887      }
4888    });
4889  }
4890  return params;
4891}
4892
4893function Navigation(_ref) {
4894  let { swiper, extendParams, on, emit } = _ref;
4895  extendParams({
4896    navigation: {
4897      nextEl: null,
4898      prevEl: null,
4899      hideOnClick: false,
4900      disabledClass: 'swiper-button-disabled',
4901      hiddenClass: 'swiper-button-hidden',
4902      lockClass: 'swiper-button-lock',
4903      navigationDisabledClass: 'swiper-navigation-disabled',
4904    },
4905  });
4906  swiper.navigation = {
4907    nextEl: null,
4908    prevEl: null,
4909  };
4910  const makeElementsArray = (el) => {
4911    if (!Array.isArray(el)) el = [el].filter((e) => !!e);
4912    return el;
4913  };
4914  function getEl(el) {
4915    let res;
4916    if (el && typeof el === 'string' && swiper.isElement) {
4917      res = swiper.el.shadowRoot.querySelector(el);
4918      if (res) return res;
4919    }
4920    if (el) {
4921      if (typeof el === 'string') res = [...document.querySelectorAll(el)];
4922      if (
4923        swiper.params.uniqueNavElements &&
4924        typeof el === 'string' &&
4925        res.length > 1 &&
4926        swiper.el.querySelectorAll(el).length === 1
4927      ) {
4928        res = swiper.el.querySelector(el);
4929      }
4930    }
4931    if (el && !res) return el;
4932    // if (Array.isArray(res) && res.length === 1) res = res[0];
4933    return res;
4934  }
4935  function toggleEl(el, disabled) {
4936    const params = swiper.params.navigation;
4937    el = makeElementsArray(el);
4938    el.forEach((subEl) => {
4939      if (subEl) {
4940        subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
4941        if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
4942        if (swiper.params.watchOverflow && swiper.enabled) {
4943          subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
4944        }
4945      }
4946    });
4947  }
4948  function update() {
4949    // Update Navigation Buttons
4950    const { nextEl, prevEl } = swiper.navigation;
4951    if (swiper.params.loop) {
4952      toggleEl(prevEl, false);
4953      toggleEl(nextEl, false);
4954      return;
4955    }
4956    toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
4957    toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
4958  }
4959  function onPrevClick(e) {
4960    e.preventDefault();
4961    if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
4962    swiper.slidePrev();
4963    emit('navigationPrev');
4964  }
4965  function onNextClick(e) {
4966    e.preventDefault();
4967    if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
4968    swiper.slideNext();
4969    emit('navigationNext');
4970  }
4971  function init() {
4972    const params = swiper.params.navigation;
4973    swiper.params.navigation = createElementIfNotDefined(
4974      swiper,
4975      swiper.originalParams.navigation,
4976      swiper.params.navigation,
4977      {
4978        nextEl: 'swiper-button-next',
4979        prevEl: 'swiper-button-prev',
4980      }
4981    );
4982    if (!(params.nextEl || params.prevEl)) return;
4983    let nextEl = getEl(params.nextEl);
4984    let prevEl = getEl(params.prevEl);
4985    Object.assign(swiper.navigation, {
4986      nextEl,
4987      prevEl,
4988    });
4989    nextEl = makeElementsArray(nextEl);
4990    prevEl = makeElementsArray(prevEl);
4991    const initButton = (el, dir) => {
4992      if (el) {
4993        el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
4994      }
4995      if (!swiper.enabled && el) {
4996        el.classList.add(...params.lockClass.split(' '));
4997      }
4998    };
4999    nextEl.forEach((el) => initButton(el, 'next'));
5000    prevEl.forEach((el) => initButton(el, 'prev'));
5001  }
5002  function destroy() {
5003    let { nextEl, prevEl } = swiper.navigation;
5004    nextEl = makeElementsArray(nextEl);
5005    prevEl = makeElementsArray(prevEl);
5006    const destroyButton = (el, dir) => {
5007      el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
5008      el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
5009    };
5010    nextEl.forEach((el) => destroyButton(el, 'next'));
5011    prevEl.forEach((el) => destroyButton(el, 'prev'));
5012  }
5013  on('init', () => {
5014    if (swiper.params.navigation.enabled === false) {
5015      // eslint-disable-next-line
5016      disable();
5017    } else {
5018      init();
5019      update();
5020    }
5021  });
5022  on('toEdge fromEdge lock unlock', () => {
5023    update();
5024  });
5025  on('destroy', () => {
5026    destroy();
5027  });
5028  on('enable disable', () => {
5029    let { nextEl, prevEl } = swiper.navigation;
5030    nextEl = makeElementsArray(nextEl);
5031    prevEl = makeElementsArray(prevEl);
5032    [...nextEl, ...prevEl]
5033      .filter((el) => !!el)
5034      .forEach((el) => el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.navigation.lockClass));
5035  });
5036  on('click', (_s, e) => {
5037    let { nextEl, prevEl } = swiper.navigation;
5038    nextEl = makeElementsArray(nextEl);
5039    prevEl = makeElementsArray(prevEl);
5040    const targetEl = e.target;
5041    if (swiper.params.navigation.hideOnClick && !prevEl.includes(targetEl) && !nextEl.includes(targetEl)) {
5042      if (
5043        swiper.pagination &&
5044        swiper.params.pagination &&
5045        swiper.params.pagination.clickable &&
5046        (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))
5047      )
5048        return;
5049      let isHidden;
5050      if (nextEl.length) {
5051        isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5052      } else if (prevEl.length) {
5053        isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5054      }
5055      if (isHidden === true) {
5056        emit('navigationShow');
5057      } else {
5058        emit('navigationHide');
5059      }
5060      [...nextEl, ...prevEl]
5061        .filter((el) => !!el)
5062        .forEach((el) => el.classList.toggle(swiper.params.navigation.hiddenClass));
5063    }
5064  });
5065  const enable = () => {
5066    swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
5067    init();
5068    update();
5069  };
5070  const disable = () => {
5071    swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
5072    destroy();
5073  };
5074  Object.assign(swiper.navigation, {
5075    enable,
5076    disable,
5077    update,
5078    init,
5079    destroy,
5080  });
5081}
5082
5083function classesToSelector(classes) {
5084  if (classes === void 0) {
5085    classes = '';
5086  }
5087  return `.${classes
5088    .trim()
5089    .replace(/([\.:!+\/])/g, '\\$1') // eslint-disable-line
5090    .replace(/ /g, '.')}`;
5091}
5092
5093function Pagination(_ref) {
5094  let { swiper, extendParams, on, emit } = _ref;
5095  const pfx = 'swiper-pagination';
5096  extendParams({
5097    pagination: {
5098      el: null,
5099      bulletElement: 'span',
5100      clickable: false,
5101      hideOnClick: false,
5102      renderBullet: null,
5103      renderProgressbar: null,
5104      renderFraction: null,
5105      renderCustom: null,
5106      progressbarOpposite: false,
5107      type: 'bullets',
5108      // 'bullets' or 'progressbar' or 'fraction' or 'custom'
5109      dynamicBullets: false,
5110      dynamicMainBullets: 1,
5111      formatFractionCurrent: (number) => number,
5112      formatFractionTotal: (number) => number,
5113      bulletClass: `${pfx}-bullet`,
5114      bulletActiveClass: `${pfx}-bullet-active`,
5115      modifierClass: `${pfx}-`,
5116      currentClass: `${pfx}-current`,
5117      totalClass: `${pfx}-total`,
5118      hiddenClass: `${pfx}-hidden`,
5119      progressbarFillClass: `${pfx}-progressbar-fill`,
5120      progressbarOppositeClass: `${pfx}-progressbar-opposite`,
5121      clickableClass: `${pfx}-clickable`,
5122      lockClass: `${pfx}-lock`,
5123      horizontalClass: `${pfx}-horizontal`,
5124      verticalClass: `${pfx}-vertical`,
5125      paginationDisabledClass: `${pfx}-disabled`,
5126    },
5127  });
5128  swiper.pagination = {
5129    el: null,
5130    bullets: [],
5131  };
5132  let bulletSize;
5133  let dynamicBulletIndex = 0;
5134  const makeElementsArray = (el) => {
5135    if (!Array.isArray(el)) el = [el].filter((e) => !!e);
5136    return el;
5137  };
5138  function isPaginationDisabled() {
5139    return (
5140      !swiper.params.pagination.el ||
5141      !swiper.pagination.el ||
5142      (Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0)
5143    );
5144  }
5145  function setSideBullets(bulletEl, position) {
5146    const { bulletActiveClass } = swiper.params.pagination;
5147    if (!bulletEl) return;
5148    bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5149    if (bulletEl) {
5150      bulletEl.classList.add(`${bulletActiveClass}-${position}`);
5151      bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
5152      if (bulletEl) {
5153        bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
5154      }
5155    }
5156  }
5157  function onBulletClick(e) {
5158    const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));
5159    if (!bulletEl) {
5160      return;
5161    }
5162    e.preventDefault();
5163    const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
5164    if (swiper.params.loop) {
5165      if (swiper.realIndex === index) return;
5166      const newSlideIndex = swiper.getSlideIndexByData(index);
5167      const currentSlideIndex = swiper.getSlideIndexByData(swiper.realIndex);
5168      if (newSlideIndex > swiper.slides.length - swiper.loopedSlides) {
5169        swiper.loopFix({
5170          direction: newSlideIndex > currentSlideIndex ? 'next' : 'prev',
5171          activeSlideIndex: newSlideIndex,
5172          slideTo: false,
5173        });
5174      }
5175      swiper.slideToLoop(index);
5176    } else {
5177      swiper.slideTo(index);
5178    }
5179  }
vendor: 8,762 bytes, lines 5180-5383
5180  function update() {
5181    // Render || Update Pagination bullets/items
5182    const rtl = swiper.rtl;
5183    const params = swiper.params.pagination;
5184    if (isPaginationDisabled()) return;
5185    let el = swiper.pagination.el;
5186    el = makeElementsArray(el);
5187    // Current/Total
5188    let current;
5189    let previousIndex;
5190    const slidesLength =
5191      swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5192    const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
5193    if (swiper.params.loop) {
5194      previousIndex = swiper.previousRealIndex || 0;
5195      current =
5196        swiper.params.slidesPerGroup > 1
5197          ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup)
5198          : swiper.realIndex;
5199    } else if (typeof swiper.snapIndex !== 'undefined') {
5200      current = swiper.snapIndex;
5201      previousIndex = swiper.previousSnapIndex;
5202    } else {
5203      previousIndex = swiper.previousIndex || 0;
5204      current = swiper.activeIndex || 0;
5205    }
5206    // Types
5207    if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
5208      const bullets = swiper.pagination.bullets;
5209      let firstIndex;
5210      let lastIndex;
5211      let midIndex;
5212      if (params.dynamicBullets) {
5213        bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);
5214        el.forEach((subEl) => {
5215          subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
5216        });
5217        if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
5218          dynamicBulletIndex += current - (previousIndex || 0);
5219          if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
5220            dynamicBulletIndex = params.dynamicMainBullets - 1;
5221          } else if (dynamicBulletIndex < 0) {
5222            dynamicBulletIndex = 0;
5223          }
5224        }
5225        firstIndex = Math.max(current - dynamicBulletIndex, 0);
5226        lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
5227        midIndex = (lastIndex + firstIndex) / 2;
5228      }
5229      bullets.forEach((bulletEl) => {
5230        const classesToRemove = [
5231          ...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(
5232            (suffix) => `${params.bulletActiveClass}${suffix}`
5233          ),
5234        ]
5235          .map((s) => (typeof s === 'string' && s.includes(' ') ? s.split(' ') : s))
5236          .flat();
5237        bulletEl.classList.remove(...classesToRemove);
5238      });
5239      if (el.length > 1) {
5240        bullets.forEach((bullet) => {
5241          const bulletIndex = elementIndex(bullet);
5242          if (bulletIndex === current) {
5243            bullet.classList.add(...params.bulletActiveClass.split(' '));
5244          } else if (swiper.isElement) {
5245            bullet.setAttribute('part', 'bullet');
5246          }
5247          if (params.dynamicBullets) {
5248            if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
5249              bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5250            }
5251            if (bulletIndex === firstIndex) {
5252              setSideBullets(bullet, 'prev');
5253            }
5254            if (bulletIndex === lastIndex) {
5255              setSideBullets(bullet, 'next');
5256            }
5257          }
5258        });
5259      } else {
5260        const bullet = bullets[current];
5261        if (bullet) {
5262          bullet.classList.add(...params.bulletActiveClass.split(' '));
5263        }
5264        if (swiper.isElement) {
5265          bullets.forEach((bulletEl, bulletIndex) => {
5266            bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
5267          });
5268        }
5269        if (params.dynamicBullets) {
5270          const firstDisplayedBullet = bullets[firstIndex];
5271          const lastDisplayedBullet = bullets[lastIndex];
5272          for (let i = firstIndex; i <= lastIndex; i += 1) {
5273            if (bullets[i]) {
5274              bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
5275            }
5276          }
5277          setSideBullets(firstDisplayedBullet, 'prev');
5278          setSideBullets(lastDisplayedBullet, 'next');
5279        }
5280      }
5281      if (params.dynamicBullets) {
5282        const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
5283        const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
5284        const offsetProp = rtl ? 'right' : 'left';
5285        bullets.forEach((bullet) => {
5286          bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
5287        });
5288      }
5289    }
5290    el.forEach((subEl, subElIndex) => {
5291      if (params.type === 'fraction') {
5292        subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach((fractionEl) => {
5293          fractionEl.textContent = params.formatFractionCurrent(current + 1);
5294        });
5295        subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach((totalEl) => {
5296          totalEl.textContent = params.formatFractionTotal(total);
5297        });
5298      }
5299      if (params.type === 'progressbar') {
5300        let progressbarDirection;
5301        if (params.progressbarOpposite) {
5302          progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
5303        } else {
5304          progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
5305        }
5306        const scale = (current + 1) / total;
5307        let scaleX = 1;
5308        let scaleY = 1;
5309        if (progressbarDirection === 'horizontal') {
5310          scaleX = scale;
5311        } else {
5312          scaleY = scale;
5313        }
5314        subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach((progressEl) => {
5315          progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
5316          progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
5317        });
5318      }
5319      if (params.type === 'custom' && params.renderCustom) {
5320        subEl.innerHTML = params.renderCustom(swiper, current + 1, total);
5321        if (subElIndex === 0) emit('paginationRender', subEl);
5322      } else {
5323        if (subElIndex === 0) emit('paginationRender', subEl);
5324        emit('paginationUpdate', subEl);
5325      }
5326      if (swiper.params.watchOverflow && swiper.enabled) {
5327        subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
5328      }
5329    });
5330  }
5331  function render() {
5332    // Render Container
5333    const params = swiper.params.pagination;
5334    if (isPaginationDisabled()) return;
5335    const slidesLength =
5336      swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
5337    let el = swiper.pagination.el;
5338    el = makeElementsArray(el);
5339    let paginationHTML = '';
5340    if (params.type === 'bullets') {
5341      let numberOfBullets = swiper.params.loop
5342        ? Math.ceil(slidesLength / swiper.params.slidesPerGroup)
5343        : swiper.snapGrid.length;
5344      if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
5345        numberOfBullets = slidesLength;
5346      }
5347      for (let i = 0; i < numberOfBullets; i += 1) {
5348        if (params.renderBullet) {
5349          paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
5350        } else {
5351          // prettier-ignore
5352          paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
5353        }
5354      }
5355    }
5356    if (params.type === 'fraction') {
5357      if (params.renderFraction) {
5358        paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
5359      } else {
5360        paginationHTML =
5361          `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
5362      }
5363    }
5364    if (params.type === 'progressbar') {
5365      if (params.renderProgressbar) {
5366        paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
5367      } else {
5368        paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
5369      }
5370    }
5371    swiper.pagination.bullets = [];
5372    el.forEach((subEl) => {
5373      if (params.type !== 'custom') {
5374        subEl.innerHTML = paginationHTML || '';
5375      }
5376      if (params.type === 'bullets') {
5377        swiper.pagination.bullets.push(...subEl.querySelectorAll(classesToSelector(params.bulletClass)));
5378      }
5379    });
5380    if (params.type !== 'custom') {
5381      emit('paginationRender', el[0]);
5382    }
5383  }
vendor: 18,245 bytes, lines 5384-5947
5384  function init() {
5385    swiper.params.pagination = createElementIfNotDefined(
5386      swiper,
5387      swiper.originalParams.pagination,
5388      swiper.params.pagination,
5389      {
5390        el: 'swiper-pagination',
5391      }
5392    );
5393    const params = swiper.params.pagination;
5394    if (!params.el) return;
5395    let el;
5396    if (typeof params.el === 'string' && swiper.isElement) {
5397      el = swiper.el.shadowRoot.querySelector(params.el);
5398    }
5399    if (!el && typeof params.el === 'string') {
5400      el = [...document.querySelectorAll(params.el)];
5401    }
5402    if (!el) {
5403      el = params.el;
5404    }
5405    if (!el || el.length === 0) return;
5406    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
5407      el = [...swiper.el.querySelectorAll(params.el)];
5408      // check if it belongs to another nested Swiper
5409      if (el.length > 1) {
5410        el = el.filter((subEl) => {
5411          if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
5412          return true;
5413        })[0];
5414      }
5415    }
5416    if (Array.isArray(el) && el.length === 1) el = el[0];
5417    Object.assign(swiper.pagination, {
5418      el,
5419    });
5420    el = makeElementsArray(el);
5421    el.forEach((subEl) => {
5422      if (params.type === 'bullets' && params.clickable) {
5423        subEl.classList.add(params.clickableClass);
5424      }
5425      subEl.classList.add(params.modifierClass + params.type);
5426      subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5427      if (params.type === 'bullets' && params.dynamicBullets) {
5428        subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
5429        dynamicBulletIndex = 0;
5430        if (params.dynamicMainBullets < 1) {
5431          params.dynamicMainBullets = 1;
5432        }
5433      }
5434      if (params.type === 'progressbar' && params.progressbarOpposite) {
5435        subEl.classList.add(params.progressbarOppositeClass);
5436      }
5437      if (params.clickable) {
5438        subEl.addEventListener('click', onBulletClick);
5439      }
5440      if (!swiper.enabled) {
5441        subEl.classList.add(params.lockClass);
5442      }
5443    });
5444  }
5445  function destroy() {
5446    const params = swiper.params.pagination;
5447    if (isPaginationDisabled()) return;
5448    let el = swiper.pagination.el;
5449    if (el) {
5450      el = makeElementsArray(el);
5451      el.forEach((subEl) => {
5452        subEl.classList.remove(params.hiddenClass);
5453        subEl.classList.remove(params.modifierClass + params.type);
5454        subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5455        if (params.clickable) {
5456          subEl.removeEventListener('click', onBulletClick);
5457        }
5458      });
5459    }
5460    if (swiper.pagination.bullets)
5461      swiper.pagination.bullets.forEach((subEl) => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
5462  }
5463  on('changeDirection', () => {
5464    if (!swiper.pagination || !swiper.pagination.el) return;
5465    const params = swiper.params.pagination;
5466    let { el } = swiper.pagination;
5467    el = makeElementsArray(el);
5468    el.forEach((subEl) => {
5469      subEl.classList.remove(params.horizontalClass, params.verticalClass);
5470      subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5471    });
5472  });
5473  on('init', () => {
5474    if (swiper.params.pagination.enabled === false) {
5475      // eslint-disable-next-line
5476      disable();
5477    } else {
5478      init();
5479      render();
5480      update();
5481    }
5482  });
5483  on('activeIndexChange', () => {
5484    if (typeof swiper.snapIndex === 'undefined') {
5485      update();
5486    }
5487  });
5488  on('snapIndexChange', () => {
5489    update();
5490  });
5491  on('snapGridLengthChange', () => {
5492    render();
5493    update();
5494  });
5495  on('destroy', () => {
5496    destroy();
5497  });
5498  on('enable disable', () => {
5499    let { el } = swiper.pagination;
5500    if (el) {
5501      el = makeElementsArray(el);
5502      el.forEach((subEl) => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
5503    }
5504  });
5505  on('lock unlock', () => {
5506    update();
5507  });
5508  on('click', (_s, e) => {
5509    const targetEl = e.target;
5510    let { el } = swiper.pagination;
5511    if (!Array.isArray(el)) el = [el].filter((element) => !!element);
5512    if (
5513      swiper.params.pagination.el &&
5514      swiper.params.pagination.hideOnClick &&
5515      el &&
5516      el.length > 0 &&
5517      !targetEl.classList.contains(swiper.params.pagination.bulletClass)
5518    ) {
5519      if (
5520        swiper.navigation &&
5521        ((swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) ||
5522          (swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl))
5523      )
5524        return;
5525      const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
5526      if (isHidden === true) {
5527        emit('paginationShow');
5528      } else {
5529        emit('paginationHide');
5530      }
5531      el.forEach((subEl) => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
5532    }
5533  });
5534  const enable = () => {
5535    swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
5536    let { el } = swiper.pagination;
5537    if (el) {
5538      el = makeElementsArray(el);
5539      el.forEach((subEl) => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
5540    }
5541    init();
5542    render();
5543    update();
5544  };
5545  const disable = () => {
5546    swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
5547    let { el } = swiper.pagination;
5548    if (el) {
5549      el = makeElementsArray(el);
5550      el.forEach((subEl) => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
5551    }
5552    destroy();
5553  };
5554  Object.assign(swiper.pagination, {
5555    enable,
5556    disable,
5557    render,
5558    update,
5559    init,
5560    destroy,
5561  });
5562}
5563
5564function Scrollbar(_ref) {
5565  let { swiper, extendParams, on, emit } = _ref;
5566  const document = getDocument();
5567  let isTouched = false;
5568  let timeout = null;
5569  let dragTimeout = null;
5570  let dragStartPos;
5571  let dragSize;
5572  let trackSize;
5573  let divider;
5574  extendParams({
5575    scrollbar: {
5576      el: null,
5577      dragSize: 'auto',
5578      hide: false,
5579      draggable: false,
5580      snapOnRelease: true,
5581      lockClass: 'swiper-scrollbar-lock',
5582      dragClass: 'swiper-scrollbar-drag',
5583      scrollbarDisabledClass: 'swiper-scrollbar-disabled',
5584      horizontalClass: `swiper-scrollbar-horizontal`,
5585      verticalClass: `swiper-scrollbar-vertical`,
5586    },
5587  });
5588  swiper.scrollbar = {
5589    el: null,
5590    dragEl: null,
5591  };
5592  function setTranslate() {
5593    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5594    const { scrollbar, rtlTranslate: rtl } = swiper;
5595    const { dragEl, el } = scrollbar;
5596    const params = swiper.params.scrollbar;
5597    const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
5598    let newSize = dragSize;
5599    let newPos = (trackSize - dragSize) * progress;
5600    if (rtl) {
5601      newPos = -newPos;
5602      if (newPos > 0) {
5603        newSize = dragSize - newPos;
5604        newPos = 0;
5605      } else if (-newPos + dragSize > trackSize) {
5606        newSize = trackSize + newPos;
5607      }
5608    } else if (newPos < 0) {
5609      newSize = dragSize + newPos;
5610      newPos = 0;
5611    } else if (newPos + dragSize > trackSize) {
5612      newSize = trackSize - newPos;
5613    }
5614    if (swiper.isHorizontal()) {
5615      dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
5616      dragEl.style.width = `${newSize}px`;
5617    } else {
5618      dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
5619      dragEl.style.height = `${newSize}px`;
5620    }
5621    if (params.hide) {
5622      clearTimeout(timeout);
5623      el.style.opacity = 1;
5624      timeout = setTimeout(() => {
5625        el.style.opacity = 0;
5626        el.style.transitionDuration = '400ms';
5627      }, 1000);
5628    }
5629  }
5630  function setTransition(duration) {
5631    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5632    swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
5633  }
5634  function updateSize() {
5635    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5636    const { scrollbar } = swiper;
5637    const { dragEl, el } = scrollbar;
5638    dragEl.style.width = '';
5639    dragEl.style.height = '';
5640    trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
5641    divider =
5642      swiper.size /
5643      (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
5644    if (swiper.params.scrollbar.dragSize === 'auto') {
5645      dragSize = trackSize * divider;
5646    } else {
5647      dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
5648    }
5649    if (swiper.isHorizontal()) {
5650      dragEl.style.width = `${dragSize}px`;
5651    } else {
5652      dragEl.style.height = `${dragSize}px`;
5653    }
5654    if (divider >= 1) {
5655      el.style.display = 'none';
5656    } else {
5657      el.style.display = '';
5658    }
5659    if (swiper.params.scrollbar.hide) {
5660      el.style.opacity = 0;
5661    }
5662    if (swiper.params.watchOverflow && swiper.enabled) {
5663      scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
5664    }
5665  }
5666  function getPointerPosition(e) {
5667    return swiper.isHorizontal() ? e.clientX : e.clientY;
5668  }
5669  function setDragPosition(e) {
5670    const { scrollbar, rtlTranslate: rtl } = swiper;
5671    const { el } = scrollbar;
5672    let positionRatio;
5673    positionRatio =
5674      (getPointerPosition(e) -
5675        elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] -
5676        (dragStartPos !== null ? dragStartPos : dragSize / 2)) /
5677      (trackSize - dragSize);
5678    positionRatio = Math.max(Math.min(positionRatio, 1), 0);
5679    if (rtl) {
5680      positionRatio = 1 - positionRatio;
5681    }
5682    const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
5683    swiper.updateProgress(position);
5684    swiper.setTranslate(position);
5685    swiper.updateActiveIndex();
5686    swiper.updateSlidesClasses();
5687  }
5688  function onDragStart(e) {
5689    const params = swiper.params.scrollbar;
5690    const { scrollbar, wrapperEl } = swiper;
5691    const { el, dragEl } = scrollbar;
5692    isTouched = true;
5693    dragStartPos =
5694      e.target === dragEl
5695        ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top']
5696        : null;
5697    e.preventDefault();
5698    e.stopPropagation();
5699    wrapperEl.style.transitionDuration = '100ms';
5700    dragEl.style.transitionDuration = '100ms';
5701    setDragPosition(e);
5702    clearTimeout(dragTimeout);
5703    el.style.transitionDuration = '0ms';
5704    if (params.hide) {
5705      el.style.opacity = 1;
5706    }
5707    if (swiper.params.cssMode) {
5708      swiper.wrapperEl.style['scroll-snap-type'] = 'none';
5709    }
5710    emit('scrollbarDragStart', e);
5711  }
5712  function onDragMove(e) {
5713    const { scrollbar, wrapperEl } = swiper;
5714    const { el, dragEl } = scrollbar;
5715    if (!isTouched) return;
5716    if (e.preventDefault) e.preventDefault();
5717    else e.returnValue = false;
5718    setDragPosition(e);
5719    wrapperEl.style.transitionDuration = '0ms';
5720    el.style.transitionDuration = '0ms';
5721    dragEl.style.transitionDuration = '0ms';
5722    emit('scrollbarDragMove', e);
5723  }
5724  function onDragEnd(e) {
5725    const params = swiper.params.scrollbar;
5726    const { scrollbar, wrapperEl } = swiper;
5727    const { el } = scrollbar;
5728    if (!isTouched) return;
5729    isTouched = false;
5730    if (swiper.params.cssMode) {
5731      swiper.wrapperEl.style['scroll-snap-type'] = '';
5732      wrapperEl.style.transitionDuration = '';
5733    }
5734    if (params.hide) {
5735      clearTimeout(dragTimeout);
5736      dragTimeout = nextTick(() => {
5737        el.style.opacity = 0;
5738        el.style.transitionDuration = '400ms';
5739      }, 1000);
5740    }
5741    emit('scrollbarDragEnd', e);
5742    if (params.snapOnRelease) {
5743      swiper.slideToClosest();
5744    }
5745  }
5746  function events(method) {
5747    const { scrollbar, params } = swiper;
5748    const el = scrollbar.el;
5749    if (!el) return;
5750    const target = el;
5751    const activeListener = params.passiveListeners
5752      ? {
5753          passive: false,
5754          capture: false,
5755        }
5756      : false;
5757    const passiveListener = params.passiveListeners
5758      ? {
5759          passive: true,
5760          capture: false,
5761        }
5762      : false;
5763    if (!target) return;
5764    const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
5765    target[eventMethod]('pointerdown', onDragStart, activeListener);
5766    document[eventMethod]('pointermove', onDragMove, activeListener);
5767    document[eventMethod]('pointerup', onDragEnd, passiveListener);
5768  }
5769  function enableDraggable() {
5770    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5771    events('on');
5772  }
5773  function disableDraggable() {
5774    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
5775    events('off');
5776  }
5777  function init() {
5778    const { scrollbar, el: swiperEl } = swiper;
5779    swiper.params.scrollbar = createElementIfNotDefined(
5780      swiper,
5781      swiper.originalParams.scrollbar,
5782      swiper.params.scrollbar,
5783      {
5784        el: 'swiper-scrollbar',
5785      }
5786    );
5787    const params = swiper.params.scrollbar;
5788    if (!params.el) return;
5789    let el;
5790    if (typeof params.el === 'string' && swiper.isElement) {
5791      el = swiper.el.shadowRoot.querySelector(params.el);
5792    }
5793    if (!el && typeof params.el === 'string') {
5794      el = document.querySelectorAll(params.el);
5795    } else if (!el) {
5796      el = params.el;
5797    }
5798    if (
5799      swiper.params.uniqueNavElements &&
5800      typeof params.el === 'string' &&
5801      el.length > 1 &&
5802      swiperEl.querySelectorAll(params.el).length === 1
5803    ) {
5804      el = swiperEl.querySelector(params.el);
5805    }
5806    if (el.length > 0) el = el[0];
5807    el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5808    let dragEl;
5809    if (el) {
5810      dragEl = el.querySelector(`.${swiper.params.scrollbar.dragClass}`);
5811      if (!dragEl) {
5812        dragEl = createElement('div', swiper.params.scrollbar.dragClass);
5813        el.append(dragEl);
5814      }
5815    }
5816    Object.assign(scrollbar, {
5817      el,
5818      dragEl,
5819    });
5820    if (params.draggable) {
5821      enableDraggable();
5822    }
5823    if (el) {
5824      el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.scrollbar.lockClass);
5825    }
5826  }
5827  function destroy() {
5828    const params = swiper.params.scrollbar;
5829    const el = swiper.scrollbar.el;
5830    if (el) {
5831      el.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
5832    }
5833    disableDraggable();
5834  }
5835  on('init', () => {
5836    if (swiper.params.scrollbar.enabled === false) {
5837      // eslint-disable-next-line
5838      disable();
5839    } else {
5840      init();
5841      updateSize();
5842      setTranslate();
5843    }
5844  });
5845  on('update resize observerUpdate lock unlock', () => {
5846    updateSize();
5847  });
5848  on('setTranslate', () => {
5849    setTranslate();
5850  });
5851  on('setTransition', (_s, duration) => {
5852    setTransition(duration);
5853  });
5854  on('enable disable', () => {
5855    const { el } = swiper.scrollbar;
5856    if (el) {
5857      el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.scrollbar.lockClass);
5858    }
5859  });
5860  on('destroy', () => {
5861    destroy();
5862  });
5863  const enable = () => {
5864    swiper.el.classList.remove(swiper.params.scrollbar.scrollbarDisabledClass);
5865    if (swiper.scrollbar.el) {
5866      swiper.scrollbar.el.classList.remove(swiper.params.scrollbar.scrollbarDisabledClass);
5867    }
5868    init();
5869    updateSize();
5870    setTranslate();
5871  };
5872  const disable = () => {
5873    swiper.el.classList.add(swiper.params.scrollbar.scrollbarDisabledClass);
5874    if (swiper.scrollbar.el) {
5875      swiper.scrollbar.el.classList.add(swiper.params.scrollbar.scrollbarDisabledClass);
5876    }
5877    destroy();
5878  };
5879  Object.assign(swiper.scrollbar, {
5880    enable,
5881    disable,
5882    updateSize,
5883    setTranslate,
5884    init,
5885    destroy,
5886  });
5887}
5888
5889function Parallax(_ref) {
5890  let { swiper, extendParams, on } = _ref;
5891  extendParams({
5892    parallax: {
5893      enabled: false,
5894    },
5895  });
5896  const setTransform = (el, progress) => {
5897    const { rtl } = swiper;
5898    const rtlFactor = rtl ? -1 : 1;
5899    const p = el.getAttribute('data-swiper-parallax') || '0';
5900    let x = el.getAttribute('data-swiper-parallax-x');
5901    let y = el.getAttribute('data-swiper-parallax-y');
5902    const scale = el.getAttribute('data-swiper-parallax-scale');
5903    const opacity = el.getAttribute('data-swiper-parallax-opacity');
5904    const rotate = el.getAttribute('data-swiper-parallax-rotate');
5905    if (x || y) {
5906      x = x || '0';
5907      y = y || '0';
5908    } else if (swiper.isHorizontal()) {
5909      x = p;
5910      y = '0';
5911    } else {
5912      y = p;
5913      x = '0';
5914    }
5915    if (x.indexOf('%') >= 0) {
5916      x = `${parseInt(x, 10) * progress * rtlFactor}%`;
5917    } else {
5918      x = `${x * progress * rtlFactor}px`;
5919    }
5920    if (y.indexOf('%') >= 0) {
5921      y = `${parseInt(y, 10) * progress}%`;
5922    } else {
5923      y = `${y * progress}px`;
5924    }
5925    if (typeof opacity !== 'undefined' && opacity !== null) {
5926      const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
5927      el.style.opacity = currentOpacity;
5928    }
5929    let transform = `translate3d(${x}, ${y}, 0px)`;
5930    if (typeof scale !== 'undefined' && scale !== null) {
5931      const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
5932      transform += ` scale(${currentScale})`;
5933    }
5934    if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
5935      const currentRotate = rotate * progress * -1;
5936      transform += ` rotate(${currentRotate}deg)`;
5937    }
5938    el.style.transform = transform;
5939  };
5940  const setTranslate = () => {
5941    const { el, slides, progress, snapGrid } = swiper;
5942    elementChildren(
5943      el,
5944      '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]'
5945    ).forEach((subEl) => {
5946      setTransform(subEl, progress);
5947    });
5948    slides.forEach((slideEl, slideIndex) => {
5949      let slideProgress = slideEl.progress;
5950      if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
5951        slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
5952      }
5953      slideProgress = Math.min(Math.max(slideProgress, -1), 1);
5954      slideEl
5955        .querySelectorAll(
5956          '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale], [data-swiper-parallax-rotate]'
5957        )
5958        .forEach((subEl) => {
5959          setTransform(subEl, slideProgress);
5960        });
5961    });
5962  };
5963  const setTransition = function (duration) {
5964    if (duration === void 0) {
5965      duration = swiper.params.speed;
5966    }
5967    const { el } = swiper;
5968    el.querySelectorAll(
5969      '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]'
5970    ).forEach((parallaxEl) => {
5971      let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
5972      if (duration === 0) parallaxDuration = 0;
5973      parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
5974    });
5975  };
5976  on('beforeInit', () => {
5977    if (!swiper.params.parallax.enabled) return;
5978    swiper.params.watchSlidesProgress = true;
5979    swiper.originalParams.watchSlidesProgress = true;
5980  });
5981  on('init', () => {
5982    if (!swiper.params.parallax.enabled) return;
5983    setTranslate();
5984  });
5985  on('setTranslate', () => {
5986    if (!swiper.params.parallax.enabled) return;
5987    setTranslate();
5988  });
5989  on('setTransition', (_swiper, duration) => {
5990    if (!swiper.params.parallax.enabled) return;
5991    setTransition(duration);
5992  });
5993}
5994
5995function Zoom(_ref) {
5996  let { swiper, extendParams, on, emit } = _ref;
5997  const window = getWindow();
5998  extendParams({
5999    zoom: {
6000      enabled: false,
6001      maxRatio: 3,
6002      minRatio: 1,
6003      toggle: true,
6004      containerClass: 'swiper-zoom-container',
6005      zoomedSlideClass: 'swiper-slide-zoomed',
6006    },
6007  });
6008  swiper.zoom = {
6009    enabled: false,
6010  };
6011  let currentScale = 1;
6012  let isScaling = false;
6013  let fakeGestureTouched;
6014  let fakeGestureMoved;
6015  const evCache = [];
6016  const gesture = {
6017    originX: 0,
6018    originY: 0,
6019    slideEl: undefined,
6020    slideWidth: undefined,
6021    slideHeight: undefined,
6022    imageEl: undefined,
6023    imageWrapEl: undefined,
6024    maxRatio: 3,
6025  };
6026  const image = {
6027    isTouched: undefined,
6028    isMoved: undefined,
6029    currentX: undefined,
6030    currentY: undefined,
6031    minX: undefined,
6032    minY: undefined,
6033    maxX: undefined,
6034    maxY: undefined,
6035    width: undefined,
6036    height: undefined,
6037    startX: undefined,
6038    startY: undefined,
6039    touchesStart: {},
6040    touchesCurrent: {},
6041  };
6042  const velocity = {
6043    x: undefined,
6044    y: undefined,
6045    prevPositionX: undefined,
6046    prevPositionY: undefined,
6047    prevTime: undefined,
6048  };
6049  let scale = 1;
6050  Object.defineProperty(swiper.zoom, 'scale', {
6051    get() {
6052      return scale;
6053    },
6054    set(value) {
6055      if (scale !== value) {
6056        const imageEl = gesture.imageEl;
6057        const slideEl = gesture.slideEl;
6058        emit('zoomChange', value, imageEl, slideEl);
6059      }
6060      scale = value;
6061    },
6062  });
6063  function getDistanceBetweenTouches() {
6064    if (evCache.length < 2) return 1;
6065    const x1 = evCache[0].pageX;
6066    const y1 = evCache[0].pageY;
6067    const x2 = evCache[1].pageX;
6068    const y2 = evCache[1].pageY;
6069    const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
6070    return distance;
6071  }
6072  function getScaleOrigin() {
6073    if (evCache.length < 2)
6074      return {
6075        x: null,
6076        y: null,
6077      };
6078    const box = gesture.imageEl.getBoundingClientRect();
6079    return [
6080      (evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x) / currentScale,
6081      (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y) / currentScale,
6082    ];
6083  }
6084  function getSlideSelector() {
6085    return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
6086  }
6087  function eventWithinSlide(e) {
6088    const slideSelector = getSlideSelector();
6089    if (e.target.matches(slideSelector)) return true;
6090    if (swiper.slides.filter((slideEl) => slideEl.contains(e.target)).length > 0) return true;
6091    return false;
6092  }
6093  function eventWithinZoomContainer(e) {
6094    const selector = `.${swiper.params.zoom.containerClass}`;
6095    if (e.target.matches(selector)) return true;
6096    if ([...swiper.el.querySelectorAll(selector)].filter((containerEl) => containerEl.contains(e.target)).length > 0)
6097      return true;
6098    return false;
6099  }
6100
6101  // Events
6102  function onGestureStart(e) {
6103    if (e.pointerType === 'mouse') {
6104      evCache.splice(0, evCache.length);
6105    }
6106    if (!eventWithinSlide(e)) return;
6107    const params = swiper.params.zoom;
6108    fakeGestureTouched = false;
6109    fakeGestureMoved = false;
6110    evCache.push(e);
6111    if (evCache.length < 2) {
6112      return;
6113    }
6114    fakeGestureTouched = true;
6115    gesture.scaleStart = getDistanceBetweenTouches();
6116    if (!gesture.slideEl) {
6117      gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6118      if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
6119      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6120      if (imageEl) {
6121        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6122      }
6123      gesture.imageEl = imageEl;
6124      if (imageEl) {
6125        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6126      } else {
6127        gesture.imageWrapEl = undefined;
6128      }
6129      if (!gesture.imageWrapEl) {
6130        gesture.imageEl = undefined;
6131        return;
6132      }
6133      gesture.maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6134    }
6135    if (gesture.imageEl) {
6136      const [originX, originY] = getScaleOrigin();
6137      gesture.originX = originX;
6138      gesture.originY = originY;
6139      gesture.imageEl.style.transitionDuration = '0ms';
6140    }
6141    isScaling = true;
6142  }
6143  function onGestureChange(e) {
6144    if (!eventWithinSlide(e)) return;
6145    const params = swiper.params.zoom;
6146    const zoom = swiper.zoom;
6147    const pointerIndex = evCache.findIndex((cachedEv) => cachedEv.pointerId === e.pointerId);
6148    if (pointerIndex >= 0) evCache[pointerIndex] = e;
6149    if (evCache.length < 2) {
6150      return;
6151    }
6152    fakeGestureMoved = true;
6153    gesture.scaleMove = getDistanceBetweenTouches();
6154    if (!gesture.imageEl) {
6155      return;
6156    }
6157    zoom.scale = (gesture.scaleMove / gesture.scaleStart) * currentScale;
6158    if (zoom.scale > gesture.maxRatio) {
6159      zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
6160    }
6161    if (zoom.scale < params.minRatio) {
6162      zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
6163    }
6164    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6165  }
6166  function onGestureEnd(e) {
6167    if (!eventWithinSlide(e)) return;
6168    if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
6169    const params = swiper.params.zoom;
6170    const zoom = swiper.zoom;
6171    const pointerIndex = evCache.findIndex((cachedEv) => cachedEv.pointerId === e.pointerId);
6172    if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
6173    if (!fakeGestureTouched || !fakeGestureMoved) {
6174      return;
6175    }
6176    fakeGestureTouched = false;
6177    fakeGestureMoved = false;
6178    if (!gesture.imageEl) return;
6179    zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
6180    gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
6181    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6182    currentScale = zoom.scale;
6183    isScaling = false;
6184    if (zoom.scale > 1 && gesture.slideEl) {
6185      gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6186    } else if (zoom.scale <= 1 && gesture.slideEl) {
6187      gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6188    }
6189    if (zoom.scale === 1) {
6190      gesture.originX = 0;
6191      gesture.originY = 0;
6192      gesture.slideEl = undefined;
6193    }
6194  }
6195  function onTouchStart(e) {
6196    const device = swiper.device;
6197    if (!gesture.imageEl) return;
6198    if (image.isTouched) return;
6199    if (device.android && e.cancelable) e.preventDefault();
6200    image.isTouched = true;
6201    const event = evCache.length > 0 ? evCache[0] : e;
6202    image.touchesStart.x = event.pageX;
6203    image.touchesStart.y = event.pageY;
6204  }
6205  function onTouchMove(e) {
6206    if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
6207    const zoom = swiper.zoom;
6208    if (!gesture.imageEl) return;
6209    if (!image.isTouched || !gesture.slideEl) return;
6210    if (!image.isMoved) {
6211      image.width = gesture.imageEl.offsetWidth;
6212      image.height = gesture.imageEl.offsetHeight;
6213      image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
6214      image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
6215      gesture.slideWidth = gesture.slideEl.offsetWidth;
6216      gesture.slideHeight = gesture.slideEl.offsetHeight;
6217      gesture.imageWrapEl.style.transitionDuration = '0ms';
6218    }
6219    // Define if we need image drag
6220    const scaledWidth = image.width * zoom.scale;
6221    const scaledHeight = image.height * zoom.scale;
6222    if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;
6223    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6224    image.maxX = -image.minX;
6225    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6226    image.maxY = -image.minY;
6227    image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
6228    image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
6229    const touchesDiff = Math.max(
6230      Math.abs(image.touchesCurrent.x - image.touchesStart.x),
6231      Math.abs(image.touchesCurrent.y - image.touchesStart.y)
6232    );
6233    if (touchesDiff > 5) {
6234      swiper.allowClick = false;
6235    }
6236    if (!image.isMoved && !isScaling) {
6237      if (
6238        swiper.isHorizontal() &&
6239        ((Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x) ||
6240          (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x))
6241      ) {
6242        image.isTouched = false;
6243        return;
6244      }
6245      if (
6246        !swiper.isHorizontal() &&
6247        ((Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y) ||
6248          (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y))
6249      ) {
6250        image.isTouched = false;
6251        return;
6252      }
6253    }
6254    if (e.cancelable) {
6255      e.preventDefault();
6256    }
6257    e.stopPropagation();
6258    image.isMoved = true;
6259    const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
6260    const { originX, originY }
vendor: 5,220 bytes, lines 6260-6372
6260 = gesture;
6261    image.currentX =
6262      image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
6263    image.currentY =
6264      image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
6265    if (image.currentX < image.minX) {
6266      image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
6267    }
6268    if (image.currentX > image.maxX) {
6269      image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
6270    }
6271    if (image.currentY < image.minY) {
6272      image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
6273    }
6274    if (image.currentY > image.maxY) {
6275      image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
6276    }
6277
6278    // Velocity
6279    if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
6280    if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
6281    if (!velocity.prevTime) velocity.prevTime = Date.now();
6282    velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
6283    velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
6284    if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
6285    if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
6286    velocity.prevPositionX = image.touchesCurrent.x;
6287    velocity.prevPositionY = image.touchesCurrent.y;
6288    velocity.prevTime = Date.now();
6289    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6290  }
6291  function onTouchEnd() {
6292    const zoom = swiper.zoom;
6293    if (!gesture.imageEl) return;
6294    if (!image.isTouched || !image.isMoved) {
6295      image.isTouched = false;
6296      image.isMoved = false;
6297      return;
6298    }
6299    image.isTouched = false;
6300    image.isMoved = false;
6301    let momentumDurationX = 300;
6302    let momentumDurationY = 300;
6303    const momentumDistanceX = velocity.x * momentumDurationX;
6304    const newPositionX = image.currentX + momentumDistanceX;
6305    const momentumDistanceY = velocity.y * momentumDurationY;
6306    const newPositionY = image.currentY + momentumDistanceY;
6307
6308    // Fix duration
6309    if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
6310    if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
6311    const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
6312    image.currentX = newPositionX;
6313    image.currentY = newPositionY;
6314    // Define if we need image drag
6315    const scaledWidth = image.width * zoom.scale;
6316    const scaledHeight = image.height * zoom.scale;
6317    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
6318    image.maxX = -image.minX;
6319    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
6320    image.maxY = -image.minY;
6321    image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
6322    image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
6323    gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
6324    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
6325  }
6326  function onTransitionEnd() {
6327    const zoom = swiper.zoom;
6328    if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
6329      if (gesture.imageEl) {
6330        gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6331      }
6332      if (gesture.imageWrapEl) {
6333        gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6334      }
6335      gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
6336      zoom.scale = 1;
6337      currentScale = 1;
6338      gesture.slideEl = undefined;
6339      gesture.imageEl = undefined;
6340      gesture.imageWrapEl = undefined;
6341      gesture.originX = 0;
6342      gesture.originY = 0;
6343    }
6344  }
6345  function zoomIn(e) {
6346    const zoom = swiper.zoom;
6347    const params = swiper.params.zoom;
6348    if (!gesture.slideEl) {
6349      if (e && e.target) {
6350        gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6351      }
6352      if (!gesture.slideEl) {
6353        if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6354          gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6355        } else {
6356          gesture.slideEl = swiper.slides[swiper.activeIndex];
6357        }
6358      }
6359      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6360      if (imageEl) {
6361        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6362      }
6363      gesture.imageEl = imageEl;
6364      if (imageEl) {
6365        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6366      } else {
6367        gesture.imageWrapEl = undefined;
6368      }
6369    }
6370    if (!gesture.imageEl || !gesture.imageWrapEl) return;
6371    if (swiper.params.cssMode) {
6372      swiper.wrapperEl.style.overflow = 'hidden';
6373      swiper.wrapperEl.style.touchAction = 'none';
6374    }
6375    gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
6376    let touchX;
6377    let touchY;
6378    let offsetX;
6379    let offsetY;
6380    let diffX;
6381    let diffY;
6382    let translateX;
6383    let translateY;
6384    let imageWidth;
6385    let imageHeight;
6386    let scaledWidth;
6387    let scaledHeight;
6388    let translateMinX;
6389    let translateMinY;
6390    let translateMaxX;
6391    let translateMaxY;
6392    let slideWidth;
6393    let slideHeight;
6394    if (typeof image.touchesStart.x === 'undefined' && e) {
6395      touchX = e.pageX;
6396      touchY = e.pageY;
6397    } else {
6398      touchX = image.touchesStart.x;
6399      touchY = image.touchesStart.y;
6400    }
6401    const forceZoomRatio = typeof e === 'number' ? e : null;
6402    if (currentScale === 1 && forceZoomRatio) {
6403      touchX = undefined;
6404      touchY = undefined;
6405    }
6406    zoom.scale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6407    currentScale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
6408    if (e && !(currentScale === 1 && forceZoomRatio)) {
6409      slideWidth = gesture.slideEl.offsetWidth;
6410      slideHeight = gesture.slideEl.offsetHeight;
6411      offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
6412      offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
6413      diffX = offsetX + slideWidth / 2 - touchX;
6414      diffY = offsetY + slideHeight / 2 - touchY;
6415      imageWidth = gesture.imageEl.offsetWidth;
6416      imageHeight = gesture.imageEl.offsetHeight;
6417      scaledWidth = imageWidth * zoom.scale;
6418      scaledHeight = imageHeight * zoom.scale;
6419      translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
6420      translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
6421      translateMaxX = -translateMinX;
6422      translateMaxY = -translateMinY;
6423      translateX = diffX * zoom.scale;
6424      translateY = diffY * zoom.scale;
6425      if (translateX < translateMinX) {
6426        translateX = translateMinX;
6427      }
6428      if (translateX > translateMaxX) {
6429        translateX = translateMaxX;
6430      }
6431      if (translateY < translateMinY) {
6432        translateY = translateMinY;
6433      }
6434      if (translateY > translateMaxY) {
6435        translateY = translateMaxY;
6436      }
6437    } else {
6438      translateX = 0;
6439      translateY = 0;
6440    }
6441    if (forceZoomRatio && zoom.scale === 1) {
6442      gesture.originX = 0;
6443      gesture.originY = 0;
6444    }
6445    gesture.imageWrapEl.style.transitionDuration = '300ms';
6446    gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
6447    gesture.imageEl.style.transitionDuration = '300ms';
6448    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
6449  }
6450  function zoomOut() {
6451    const zoom = swiper.zoom;
6452    const params = swiper.params.zoom;
6453    if (!gesture.slideEl) {
6454      if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
6455        gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
6456      } else {
6457        gesture.slideEl = swiper.slides[swiper.activeIndex];
6458      }
6459      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
6460      if (imageEl) {
6461        imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
6462      }
6463      gesture.imageEl = imageEl;
6464      if (imageEl) {
6465        gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
6466      } else {
6467        gesture.imageWrapEl = undefined;
6468      }
6469    }
6470    if (!gesture.imageEl || !gesture.imageWrapEl) return;
6471    if (swiper.params.cssMode) {
6472      swiper.wrapperEl.style.overflow = '';
6473      swiper.wrapperEl.style.touchAction = '';
6474    }
6475    zoom.scale = 1;
6476    currentScale = 1;
6477    gesture.imageWrapEl.style.transitionDuration = '300ms';
6478    gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
6479    gesture.imageEl.style.transitionDuration = '300ms';
6480    gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
6481    gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
6482    gesture.slideEl = undefined;
6483    gesture.originX = 0;
6484    gesture.originY = 0;
6485  }
6486
6487  // Toggle Zoom
6488  function zoomToggle(e) {
6489    const zoom = swiper.zoom;
6490    if (zoom.scale && zoom.scale !== 1) {
6491      // Zoom Out
6492      zoomOut();
6493    } else {
6494      // Zoom In
6495      zoomIn(e);
6496    }
6497  }
6498  function getListeners() {
6499    const passiveListener = swiper.params.passiveListeners
6500      ? {
6501          passive: true,
6502          capture: false,
6503        }
6504      : false;
6505    const activeListenerWithCapture = swiper.params.passiveListeners
6506      ? {
6507          passive: false,
6508          capture: true,
6509        }
6510      : true;
6511    return {
6512      passiveListener,
6513      activeListenerWithCapture,
6514    };
6515  }
6516
6517  // Attach/Detach Events
6518  function enable() {
6519    const zoom = swiper.zoom;
6520    if (zoom.enabled) return;
6521    zoom.enabled = true;
6522    const { passiveListener, activeListenerWithCapture } = getListeners();
6523
6524    // Scale image
6525    swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
6526    swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6527    ['pointerup', 'pointercancel', 'pointerout'].forEach((eventName) => {
6528      swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
6529    });
6530
6531    // Move image
6532    swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6533  }
6534  function disable() {
6535    const zoom = swiper.zoom;
6536    if (!zoom.enabled) return;
6537    zoom.enabled = false;
6538    const { passiveListener, activeListenerWithCapture } = getListeners();
6539
6540    // Scale image
6541    swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
6542    swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
6543    ['pointerup', 'pointercancel', 'pointerout'].forEach((eventName) => {
6544      swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
6545    });
6546
6547    // Move image
6548    swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
6549  }
6550  on('init', () => {
6551    if (swiper.params.zoom.enabled) {
6552      enable();
6553    }
6554  });
6555  on('destroy', () => {
6556    disable();
6557  });
6558  on('touchStart', (_s, e) => {
6559    if (!swiper.zoom.enabled) return;
6560    onTouchStart(e);
6561  });
6562  on('touchEnd', (_s, e) => {
6563    if (!swiper.zoom.enabled) return;
6564    onTouchEnd();
6565  });
6566  on('doubleTap', (_s, e) => {
6567    if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
6568      zoomToggle(e);
6569    }
6570  });
6571  on('transitionEnd', () => {
6572    if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
6573      onTransitionEnd();
6574    }
6575  });
6576  on('slideChange', () => {
6577    if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
6578      onTransitionEnd();
6579    }
6580  });
6581  Object.assign(swiper.zoom, {
6582    enable,
6583    disable,
6584    in: zoomIn,
6585    out: zoomOut,
6586    toggle: zoomToggle,
6587  });
6588}
6589
6590/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
6591function Controller(_ref) {
6592  let { swiper, extendParams, on } = _ref;
6593  extendParams({
6594    controller: {
6595      control: undefined,
6596      inverse: false,
6597      by: 'slide', // or 'container'
6598    },
6599  });
6600
6601  swiper.controller = {
6602    control: undefined,
6603  };
6604  function LinearSpline(x, y) {
6605    const binarySearch = (function search() {
6606      let maxIndex;
6607      let minIndex;
6608      let guess;
6609      return (array, val) => {
6610        minIndex = -1;
6611        maxIndex = array.length;
6612        while (maxIndex - minIndex > 1) {
6613          guess = (maxIndex + minIndex) >> 1;
6614          if (array[guess] <= val) {
6615            minIndex = guess;
6616          } else {
6617            maxIndex = guess;
6618          }
6619        }
6620        return maxIndex;
6621      };
6622    })();
6623    this.x = x;
6624    this.y = y;
6625    this.lastIndex = x.length - 1;
6626    // Given an x value (x2), return the expected y2 value:
6627    // (x1,y1) is the known point before given value,
vendor: 4,610 bytes, lines 6628-6741
6628    // (x3,y3) is the known point after given value.
6629    let i1;
6630    let i3;
6631    this.interpolate = function interpolate(x2) {
6632      if (!x2) return 0;
6633
6634      // Get the indexes of x1 and x3 (the array indexes before and after given x2):
6635      i3 = binarySearch(this.x, x2);
6636      i1 = i3 - 1;
6637
6638      // We have our indexes i1 & i3, so we can calculate already:
6639      // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
6640      return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
6641    };
6642    return this;
6643  }
6644  function getInterpolateFunction(c) {
6645    swiper.controller.spline = swiper.params.loop
6646      ? new LinearSpline(swiper.slidesGrid, c.slidesGrid)
6647      : new LinearSpline(swiper.snapGrid, c.snapGrid);
6648  }
6649  function setTranslate(_t, byController) {
6650    const controlled = swiper.controller.control;
6651    let multiplier;
6652    let controlledTranslate;
6653    const Swiper = swiper.constructor;
6654    function setControlledTranslate(c) {
6655      if (c.destroyed) return;
6656
6657      // this will create an Interpolate function based on the snapGrids
6658      // x is the Grid of the scrolled scroller and y will be the controlled scroller
6659      // it makes sense to create this only once and recall it for the interpolation
6660      // the function does a lot of value caching for performance
6661      const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
6662      if (swiper.params.controller.by === 'slide') {
6663        getInterpolateFunction(c);
6664        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
6665        // but it did not work out
6666        controlledTranslate = -swiper.controller.spline.interpolate(-translate);
6667      }
6668      if (!controlledTranslate || swiper.params.controller.by === 'container') {
6669        multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
6670        if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
6671          multiplier = 1;
6672        }
6673        controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
6674      }
6675      if (swiper.params.controller.inverse) {
6676        controlledTranslate = c.maxTranslate() - controlledTranslate;
6677      }
6678      c.updateProgress(controlledTranslate);
6679      c.setTranslate(controlledTranslate, swiper);
6680      c.updateActiveIndex();
6681      c.updateSlidesClasses();
6682    }
6683    if (Array.isArray(controlled)) {
6684      for (let i = 0; i < controlled.length; i += 1) {
6685        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
6686          setControlledTranslate(controlled[i]);
6687        }
6688      }
6689    } else if (controlled instanceof Swiper && byController !== controlled) {
6690      setControlledTranslate(controlled);
6691    }
6692  }
6693  function setTransition(duration, byController) {
6694    const Swiper = swiper.constructor;
6695    const controlled = swiper.controller.control;
6696    let i;
6697    function setControlledTransition(c) {
6698      if (c.destroyed) return;
6699      c.setTransition(duration, swiper);
6700      if (duration !== 0) {
6701        c.transitionStart();
6702        if (c.params.autoHeight) {
6703          nextTick(() => {
6704            c.updateAutoHeight();
6705          });
6706        }
6707        elementTransitionEnd(c.wrapperEl, () => {
6708          if (!controlled) return;
6709          c.transitionEnd();
6710        });
6711      }
6712    }
6713    if (Array.isArray(controlled)) {
6714      for (i = 0; i < controlled.length; i += 1) {
6715        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
6716          setControlledTransition(controlled[i]);
6717        }
6718      }
6719    } else if (controlled instanceof Swiper && byController !== controlled) {
6720      setControlledTransition(controlled);
6721    }
6722  }
6723  function removeSpline() {
6724    if (!swiper.controller.control) return;
6725    if (swiper.controller.spline) {
6726      swiper.controller.spline = undefined;
6727      delete swiper.controller.spline;
6728    }
6729  }
6730  on('beforeInit', () => {
6731    if (
6732      typeof window !== 'undefined' &&
6733      // eslint-disable-line
6734      (typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)
6735    ) {
6736      const controlElement = document.querySelector(swiper.params.controller.control);
6737      if (controlElement && controlElement.swiper) {
6738        swiper.controller.control = controlElement.swiper;
6739      } else if (controlElement) {
6740        const onControllerSwiper = (e) => {
6741          swiper.controller.control = e.detail[0];
6742          swiper.update();
6743          controlElement.removeEventListener('init', onControllerSwiper);
6744        };
6745        controlElement.addEventListener('init', onControllerSwiper);
6746      }
6747      return;
6748    }
6749    swiper.controller.control = swiper.params.controller.control;
6750  });
6751  on('update', () => {
6752    removeSpline();
6753  });
6754  on('resize', () => {
6755    removeSpline();
6756  });
6757  on('observerUpdate', () => {
6758    removeSpline();
6759  });
6760  on('setTranslate', (_s, translate, byController) => {
6761    if (!swiper.controller.control || swiper.controller.control.destroyed) return;
6762    swiper.controller.setTranslate(translate, byController);
6763  });
6764  on('setTransition', (_s, duration, byController) => {
6765    if (!swiper.controller.control || swiper.controller.control.destroyed) return;
6766    swiper.controller.setTransition(duration, byController);
6767  });
6768  Object.assign(swiper.controller, {
6769    setTranslate,
6770    setTransition,
6771  });
6772}
6773
6774function A11y(_ref) {
6775  let { swiper, extendParams, on } = _ref;
6776  extendParams({
6777    a11y: {
6778      enabled: true,
6779      notificationClass: 'swiper-notification',
6780      prevSlideMessage: 'Previous slide',
6781      nextSlideMessage: 'Next slide',
6782      firstSlideMessage: 'This is the first slide',
6783      lastSlideMessage: 'This is the last slide',
6784      paginationBulletMessage: 'Go to slide {{index}}',
6785      slideLabelMessage: '{{index}} / {{slidesLength}}',
6786      containerMessage: null,
6787      containerRoleDescriptionMessage: null,
6788      itemRoleDescriptionMessage: null,
6789      slideRole: 'group',
6790      id: null,
6791    },
6792  });
6793  swiper.a11y = {
6794    clicked: false,
6795  };
6796  let liveRegion = null;
6797  function notify(message) {
6798    const notification = liveRegion;
6799    if (notification.length === 0) return;
6800    notification.innerHTML = '';
6801    notification.innerHTML = message;
6802  }
6803  const makeElementsArray = (el) => {
6804    if (!Array.isArray(el)) el = [el].filter((e) => !!e);
6805    return el;
6806  };
6807  function getRandomNumber(size) {
6808    if (size === void 0) {
6809      size = 16;
6810    }
6811    //   const randomChar = () => Math.round(16 * Math.random()).toString(16);
6812    // const randomChar = () => parseFloat('0.' + crypto.getRandomValues(new Uint32Array(1))[0]);
6813    const randomArray = new Uint8Array(1);
6814    window.crypto.getRandomValues(randomArray);
6815    const randomValue = randomArray[0] % 16;
6816    const randomChar = randomValue.toString(16);
6817    return 'x'.repeat(size).replace(/x/g, randomChar);
6818  }
6819  function makeElFocusable(el) {
6820    el = makeElementsArray(el);
6821    el.forEach((subEl) => {
6822      subEl.setAttribute('tabIndex', '0');
6823    });
6824  }
6825  function makeElNotFocusable(el) {
6826    el = makeElementsArray(el);
6827    el.forEach((subEl) => {
6828      subEl.setAttribute('tabIndex', '-1');
6829    });
6830  }
6831  function addElRole(el, role) {
6832    el = makeElementsArray(el);
6833    el.forEach((subEl) => {
6834      subEl.setAttribute('role', role);
6835    });
6836  }
6837  function addElRoleDescription(el, description) {
6838    el = makeElementsArray(el);
6839    el.forEach((subEl) => {
6840      subEl.setAttribute('aria-roledescription', description);
6841    });
6842  }
6843  function addElControls(el, controls) {
6844    el = makeElementsArray(el);
6845    el.forEach((subEl) => {
6846      subEl.setAttribute('aria-controls', controls);
6847    });
6848  }
6849  function addElLabel(el, label) {
6850    el = makeElementsArray(el);
6851    el.forEach((subEl) => {
6852      subEl.setAttribute('aria-label', label);
6853    });
6854  }
6855  function addElId(el, id) {
6856    el = makeElementsArray(el);
6857    el.forEach((subEl) => {
6858      subEl.setAttribute('id', id);
6859    });
6860  }
6861  function addElLive(el, live) {
6862    el = makeElementsArray(el);
6863    el.forEach((subEl) => {
6864      subEl.setAttribute('aria-live', live);
6865    });
6866  }
6867  function disableEl(el) {
6868    el = makeElementsArray(el);
6869    el.forEach((subEl) => {
6870      subEl.setAttribute('aria-disabled', true);
6871    });
6872  }
6873  function enableEl(el) {
6874    el = makeElementsArray(el);
6875    el.forEach((subEl) => {
6876      subEl.setAttribute('aria-disabled', false);
6877    });
vendor: 4,484 bytes, lines 6878-7006
6878  }
6879  function onEnterOrSpaceKey(e) {
6880    if (e.keyCode !== 13 && e.keyCode !== 32) return;
6881    const params = swiper.params.a11y;
6882    const targetEl = e.target;
6883    if (
6884      swiper.pagination &&
6885      swiper.pagination.el &&
6886      (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))
6887    ) {
6888      if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
6889    }
6890    if (swiper.navigation && swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) {
6891      if (!(swiper.isEnd && !swiper.params.loop)) {
6892        swiper.slideNext();
6893      }
6894      if (swiper.isEnd) {
6895        notify(params.lastSlideMessage);
6896      } else {
6897        notify(params.nextSlideMessage);
6898      }
6899    }
6900    if (swiper.navigation && swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl) {
6901      if (!(swiper.isBeginning && !swiper.params.loop)) {
6902        swiper.slidePrev();
6903      }
6904      if (swiper.isBeginning) {
6905        notify(params.firstSlideMessage);
6906      } else {
6907        notify(params.prevSlideMessage);
6908      }
6909    }
6910    if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
6911      targetEl.click();
6912    }
6913  }
6914  function updateNavigation() {
6915    if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
6916    const { nextEl, prevEl } = swiper.navigation;
6917    if (prevEl) {
6918      if (swiper.isBeginning) {
6919        disableEl(prevEl);
6920        makeElNotFocusable(prevEl);
6921      } else {
6922        enableEl(prevEl);
6923        makeElFocusable(prevEl);
6924      }
6925    }
6926    if (nextEl) {
6927      if (swiper.isEnd) {
6928        disableEl(nextEl);
6929        makeElNotFocusable(nextEl);
6930      } else {
6931        enableEl(nextEl);
6932        makeElFocusable(nextEl);
6933      }
6934    }
6935  }
6936  function hasPagination() {
6937    return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
6938  }
6939  function hasClickablePagination() {
6940    return hasPagination() && swiper.params.pagination.clickable;
6941  }
6942  function updatePagination() {
6943    const params = swiper.params.a11y;
6944    if (!hasPagination()) return;
6945    swiper.pagination.bullets.forEach((bulletEl) => {
6946      if (swiper.params.pagination.clickable) {
6947        makeElFocusable(bulletEl);
6948        if (!swiper.params.pagination.renderBullet) {
6949          addElRole(bulletEl, 'button');
6950          addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
6951        }
6952      }
6953      if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
6954        bulletEl.setAttribute('aria-current', 'true');
6955      } else {
6956        bulletEl.removeAttribute('aria-current');
6957      }
6958    });
6959  }
6960  const initNavEl = (el, wrapperId, message) => {
6961    makeElFocusable(el);
6962    if (el.tagName !== 'BUTTON') {
6963      addElRole(el, 'button');
6964      el.addEventListener('keydown', onEnterOrSpaceKey);
6965    }
6966    addElLabel(el, message);
6967    addElControls(el, wrapperId);
6968  };
6969  const handlePointerDown = () => {
6970    swiper.a11y.clicked = true;
6971  };
6972  const handlePointerUp = () => {
6973    requestAnimationFrame(() => {
6974      requestAnimationFrame(() => {
6975        if (!swiper.destroyed) {
6976          swiper.a11y.clicked = false;
6977        }
6978      });
6979    });
6980  };
6981  const handleFocus = (e) => {
6982    if (swiper.a11y.clicked) return;
6983    const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
6984    if (!slideEl || !swiper.slides.includes(slideEl)) return;
6985    const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
6986    const isVisible =
6987      swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
6988    if (isActive || isVisible) return;
6989    if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
6990    if (swiper.isHorizontal()) {
6991      swiper.el.scrollLeft = 0;
6992    } else {
6993      swiper.el.scrollTop = 0;
6994    }
6995    swiper.slideTo(swiper.slides.indexOf(slideEl), 0);
6996  };
6997  const initSlides = () => {
6998    const params = swiper.params.a11y;
6999    if (params.itemRoleDescriptionMessage) {
7000      addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
7001    }
7002    if (params.slideRole) {
7003      addElRole(swiper.slides, params.slideRole);
7004    }
7005    const slidesLength = swiper.slides.length;
7006    if (params.slideLabelMessage) {
7007      swiper.slides.forEach((slideEl, index) => {
7008        const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
7009        const ariaLabelMessage = params.slideLabelMessage
7010          .replace(/\{\{index\}\}/, slideIndex + 1)
7011          .replace(/\{\{slidesLength\}\}/, slidesLength);
7012        addElLabel(slideEl, ariaLabelMessage);
7013      });
7014    }
7015  };
7016  const init = () => {
7017    const params = swiper.params.a11y;
7018    if (swiper.isElement) {
7019      swiper.el.shadowEl.append(liveRegion);
7020    } else {
7021      swiper.el.append(liveRegion);
7022    }
7023
7024    // Container
7025    const containerEl = swiper.el;
7026    if (params.containerRoleDescriptionMessage) {
7027      addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
7028    }
7029    if (params.containerMessage) {
7030      addElLabel(containerEl, params.containerMessage);
7031    }
7032
7033    // Wrapper
7034    const wrapperEl = swiper.wrapperEl;
7035    const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
7036    const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
7037    addElId(wrapperEl, wrapperId);
7038    addElLive(wrapperEl, live);
7039
7040    // Slide
7041    initSlides();
7042
7043    // Navigation
7044    let { nextEl, prevEl } = swiper.navigation ? swiper.navigation : {};
7045    nextEl = makeElementsArray(nextEl);
7046    prevEl = makeElementsArray(prevEl);
7047    if (nextEl) {
7048      nextEl.forEach((el) => initNavEl(el, wrapperId, params.nextSlideMessage));
7049    }
7050    if (prevEl) {
7051      prevEl.forEach((el) => initNavEl(el, wrapperId, params.prevSlideMessage));
7052    }
7053
7054    // Pagination
7055    if (hasClickablePagination()) {
7056      const paginationEl = Array.isArray(swiper.pagination.el) ? swiper.pagination.el : [swiper.pagination.el];
7057      paginationEl.forEach((el) => {
7058        el.addEventListener('keydown', onEnterOrSpaceKey);
7059      });
7060    }
7061
7062    // Tab focus
7063    swiper.el.addEventListener('focus', handleFocus, true);
7064    swiper.el.addEventListener('pointerdown', handlePointerDown, true);
7065    swiper.el.addEventListener('pointerup', handlePointerUp, true);
7066  };
7067  function destroy() {
7068    if (liveRegion) liveRegion.remove();
7069    let { nextEl, prevEl } = swiper.navigation ? swiper.navigation : {};
7070    nextEl = makeElementsArray(nextEl);
7071    prevEl = makeElementsArray(prevEl);
7072    if (nextEl) {
7073      nextEl.forEach((el) => el.removeEventListener('keydown', onEnterOrSpaceKey));
7074    }
7075    if (prevEl) {
7076      prevEl.forEach((el) => el.removeEventListener('keydown', onEnterOrSpaceKey));
7077    }
7078
7079    // Pagination
7080    if (hasClickablePagination()) {
7081      const paginationEl = Array.isArray(swiper.pagination.el) ? swiper.pagination.el : [swiper.pagination.el];
7082      paginationEl.forEach((el) => {
7083        el.removeEventListener('keydown', onEnterOrSpaceKey);
7084      });
7085    }
7086
7087    // Tab focus
7088    swiper.el.removeEventListener('focus', handleFocus, true);
7089    swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
7090    swiper.el.removeEventListener('pointerup', handlePointerUp, true);
7091  }
7092  on('beforeInit', () => {
7093    liveRegion = createElement('span', swiper.params.a11y.notificationClass);
7094    liveRegion.setAttribute('aria-live', 'assertive');
7095    liveRegion.setAttribute('aria-atomic', 'true');
7096  });
7097  on('afterInit', () => {
7098    if (!swiper.params.a11y.enabled) return;
7099    init();
7100  });
7101  on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
7102    if (!swiper.params.a11y.enabled) return;
7103    initSlides();
7104  });
7105  on('fromEdge toEdge afterInit lock unlock', () => {
7106    if (!swiper.params.a11y.enabled) return;
7107    updateNavigation();
7108  });
7109  on('paginationUpdate', () => {
7110    if (!swiper.params.a11y.enabled) return;
7111    updatePagination();
7112  });
7113  on('destroy', () => {
7114    if (!swiper.params.a11y.enabled) return;
7115    destroy();
7116  });
7117}
7118
7119function History(_ref) {
7120  let { swiper, extendParams, on } = _ref;
7121  extendParams({
7122    history: {
7123      enabled: false,
7124      root: '',
7125      replaceState: false,
7126      key: 'slides',
7127      keepQuery: false,
7128    },
7129  });
7130  let initialized = false;
7131  let paths = {};
7132  const slugify = (text) => {
7133    return text
7134      .toString()
7135      .replace(/\s+/g, '-')
7136      .replace(/[^\w-]+/g, '')
7137      .replace(/--+/g, '-')
7138      .replace(/^-+/, '')
7139      .replace(/-+$/, '');
7140  };
7141  const getPathValues = (urlOverride) => {
7142    const window = getWindow();
7143    let location;
7144    if (urlOverride) {
7145      location = new URL(urlOverride);
7146    } else {
7147      location = window.location;
7148    }
7149    const pathArray = location.pathname
7150      .slice(1)
7151      .split('/')
7152      .filter((part) => part !== '');
7153    const total = pathArray.length;
vendor: 21,953 bytes, lines 7154-7789
7154    const key = pathArray[total - 2];
7155    const value = pathArray[total - 1];
7156    return {
7157      key,
7158      value,
7159    };
7160  };
7161  const setHistory = (key, index) => {
7162    const window = getWindow();
7163    if (!initialized || !swiper.params.history.enabled) return;
7164    let location;
7165    if (swiper.params.url) {
7166      location = new URL(swiper.params.url);
7167    } else {
7168      location = window.location;
7169    }
7170    const slide = swiper.slides[index];
7171    let value = slugify(slide.getAttribute('data-history'));
7172    if (swiper.params.history.root.length > 0) {
7173      let root = swiper.params.history.root;
7174      if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
7175      value = `${root}/${key ? `${key}/` : ''}${value}`;
7176    } else if (!location.pathname.includes(key)) {
7177      value = `${key ? `${key}/` : ''}${value}`;
7178    }
7179    if (swiper.params.history.keepQuery) {
7180      value += location.search;
7181    }
7182    const currentState = window.history.state;
7183    if (currentState && currentState.value === value) {
7184      return;
7185    }
7186    if (swiper.params.history.replaceState) {
7187      window.history.replaceState(
7188        {
7189          value,
7190        },
7191        null,
7192        value
7193      );
7194    } else {
7195      window.history.pushState(
7196        {
7197          value,
7198        },
7199        null,
7200        value
7201      );
7202    }
7203  };
7204  const scrollToSlide = (speed, value, runCallbacks) => {
7205    if (value) {
7206      for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
7207        const slide = swiper.slides[i];
7208        const slideHistory = slugify(slide.getAttribute('data-history'));
7209        if (slideHistory === value) {
7210          const index = swiper.getSlideIndex(slide);
7211          swiper.slideTo(index, speed, runCallbacks);
7212        }
7213      }
7214    } else {
7215      swiper.slideTo(0, speed, runCallbacks);
7216    }
7217  };
7218  const setHistoryPopState = () => {
7219    paths = getPathValues(swiper.params.url);
7220    scrollToSlide(swiper.params.speed, paths.value, false);
7221  };
7222  const init = () => {
7223    const window = getWindow();
7224    if (!swiper.params.history) return;
7225    if (!window.history || !window.history.pushState) {
7226      swiper.params.history.enabled = false;
7227      swiper.params.hashNavigation.enabled = true;
7228      return;
7229    }
7230    initialized = true;
7231    paths = getPathValues(swiper.params.url);
7232    if (!paths.key && !paths.value) {
7233      if (!swiper.params.history.replaceState) {
7234        window.addEventListener('popstate', setHistoryPopState);
7235      }
7236      return;
7237    }
7238    scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
7239    if (!swiper.params.history.replaceState) {
7240      window.addEventListener('popstate', setHistoryPopState);
7241    }
7242  };
7243  const destroy = () => {
7244    const window = getWindow();
7245    if (!swiper.params.history.replaceState) {
7246      window.removeEventListener('popstate', setHistoryPopState);
7247    }
7248  };
7249  on('init', () => {
7250    if (swiper.params.history.enabled) {
7251      init();
7252    }
7253  });
7254  on('destroy', () => {
7255    if (swiper.params.history.enabled) {
7256      destroy();
7257    }
7258  });
7259  on('transitionEnd _freeModeNoMomentumRelease', () => {
7260    if (initialized) {
7261      setHistory(swiper.params.history.key, swiper.activeIndex);
7262    }
7263  });
7264  on('slideChange', () => {
7265    if (initialized && swiper.params.cssMode) {
7266      setHistory(swiper.params.history.key, swiper.activeIndex);
7267    }
7268  });
7269}
7270
7271function HashNavigation(_ref) {
7272  let { swiper, extendParams, emit, on } = _ref;
7273  let initialized = false;
7274  const document = getDocument();
7275  const window = getWindow();
7276  extendParams({
7277    hashNavigation: {
7278      enabled: false,
7279      replaceState: false,
7280      watchState: false,
7281      getSlideIndex(_s, hash) {
7282        if (swiper.virtual && swiper.params.virtual.enabled) {
7283          const slideWithHash = swiper.slides.filter((slideEl) => slideEl.getAttribute('data-hash') === hash)[0];
7284          if (!slideWithHash) return 0;
7285          const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
7286          return index;
7287        }
7288        return swiper.getSlideIndex(
7289          elementChildren(
7290            swiper.slidesEl,
7291            `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`
7292          )[0]
7293        );
7294      },
7295    },
7296  });
7297  const onHashChange = () => {
7298    emit('hashChange');
7299    const newHash = document.location.hash.replace('#', '');
7300    const activeSlideEl =
7301      swiper.virtual && swiper.params.virtual.enabled
7302        ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`)
7303        : swiper.slides[swiper.activeIndex];
7304    const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
7305    if (newHash !== activeSlideHash) {
7306      const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
7307      if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
7308      swiper.slideTo(newIndex);
7309    }
7310  };
7311  const setHash = () => {
7312    if (!initialized || !swiper.params.hashNavigation.enabled) return;
7313    const activeSlideEl =
7314      swiper.virtual && swiper.params.virtual.enabled
7315        ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`)
7316        : swiper.slides[swiper.activeIndex];
7317    const activeSlideHash = activeSlideEl
7318      ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history')
7319      : '';
7320    if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
7321      window.history.replaceState(null, null, `#${activeSlideHash}` || '');
7322      emit('hashSet');
7323    } else {
7324      document.location.hash = activeSlideHash || '';
7325      emit('hashSet');
7326    }
7327  };
7328  const init = () => {
7329    if (!swiper.params.hashNavigation.enabled || (swiper.params.history && swiper.params.history.enabled)) return;
7330    initialized = true;
7331    const hash = document.location.hash.replace('#', '');
7332    if (hash) {
7333      const speed = 0;
7334      const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
7335      swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
7336    }
7337    if (swiper.params.hashNavigation.watchState) {
7338      window.addEventListener('hashchange', onHashChange);
7339    }
7340  };
7341  const destroy = () => {
7342    if (swiper.params.hashNavigation.watchState) {
7343      window.removeEventListener('hashchange', onHashChange);
7344    }
7345  };
7346  on('init', () => {
7347    if (swiper.params.hashNavigation.enabled) {
7348      init();
7349    }
7350  });
7351  on('destroy', () => {
7352    if (swiper.params.hashNavigation.enabled) {
7353      destroy();
7354    }
7355  });
7356  on('transitionEnd _freeModeNoMomentumRelease', () => {
7357    if (initialized) {
7358      setHash();
7359    }
7360  });
7361  on('slideChange', () => {
7362    if (initialized && swiper.params.cssMode) {
7363      setHash();
7364    }
7365  });
7366}
7367
7368/* eslint no-underscore-dangle: "off" */
7369function Autoplay(_ref) {
7370  let { swiper, extendParams, on, emit, params } = _ref;
7371  swiper.autoplay = {
7372    running: false,
7373    paused: false,
7374    timeLeft: 0,
7375  };
7376  extendParams({
7377    autoplay: {
7378      enabled: false,
7379      delay: 3000,
7380      waitForTransition: true,
7381      disableOnInteraction: true,
7382      stopOnLastSlide: false,
7383      reverseDirection: false,
7384      pauseOnMouseEnter: false,
7385    },
7386  });
7387  let timeout;
7388  let raf;
7389  let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
7390  let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
7391  let autoplayTimeLeft;
7392  let autoplayStartTime = new Date().getTime;
7393  let wasPaused;
7394  let isTouched;
7395  let pausedByTouch;
7396  let touchStartTimeout;
7397  let slideChanged;
7398  let pausedByInteraction;
7399  function onTransitionEnd(e) {
7400    if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
7401    if (e.target !== swiper.wrapperEl) return;
7402    swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
7403    resume();
7404  }
7405  const calcTimeLeft = () => {
7406    if (swiper.destroyed || !swiper.autoplay.running) return;
7407    if (swiper.autoplay.paused) {
7408      wasPaused = true;
7409    } else if (wasPaused) {
7410      autoplayDelayCurrent = autoplayTimeLeft;
7411      wasPaused = false;
7412    }
7413    const timeLeft = swiper.autoplay.paused
7414      ? autoplayTimeLeft
7415      : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
7416    swiper.autoplay.timeLeft = timeLeft;
7417    emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
7418    raf = requestAnimationFrame(() => {
7419      calcTimeLeft();
7420    });
7421  };
7422  const getSlideDelay = () => {
7423    let activeSlideEl;
7424    if (swiper.virtual && swiper.params.virtual.enabled) {
7425      activeSlideEl = swiper.slides.filter((slideEl) => slideEl.classList.contains('swiper-slide-active'))[0];
7426    } else {
7427      activeSlideEl = swiper.slides[swiper.activeIndex];
7428    }
7429    if (!activeSlideEl) return undefined;
7430    const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
7431    return currentSlideDelay;
7432  };
7433  const run = (delayForce) => {
7434    if (swiper.destroyed || !swiper.autoplay.running) return;
7435    cancelAnimationFrame(raf);
7436    calcTimeLeft();
7437    let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
7438    autoplayDelayTotal = swiper.params.autoplay.delay;
7439    autoplayDelayCurrent = swiper.params.autoplay.delay;
7440    const currentSlideDelay = getSlideDelay();
7441    if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
7442      delay = currentSlideDelay;
7443      autoplayDelayTotal = currentSlideDelay;
7444      autoplayDelayCurrent = currentSlideDelay;
7445    }
7446    autoplayTimeLeft = delay;
7447    const speed = swiper.params.speed;
7448    const proceed = () => {
7449      if (!swiper || swiper.destroyed) return;
7450      if (swiper.params.autoplay.reverseDirection) {
7451        if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
7452          swiper.slidePrev(speed, true, true);
7453          emit('autoplay');
7454        } else if (!swiper.params.autoplay.stopOnLastSlide) {
7455          swiper.slideTo(swiper.slides.length - 1, speed, true, true);
7456          emit('autoplay');
7457        }
7458      } else {
7459        if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
7460          swiper.slideNext(speed, true, true);
7461          emit('autoplay');
7462        } else if (!swiper.params.autoplay.stopOnLastSlide) {
7463          swiper.slideTo(0, speed, true, true);
7464          emit('autoplay');
7465        }
7466      }
7467      if (swiper.params.cssMode) {
7468        autoplayStartTime = new Date().getTime();
7469        requestAnimationFrame(() => {
7470          run();
7471        });
7472      }
7473    };
7474    if (delay > 0) {
7475      clearTimeout(timeout);
7476      timeout = setTimeout(() => {
7477        proceed();
7478      }, delay);
7479    } else {
7480      requestAnimationFrame(() => {
7481        proceed();
7482      });
7483    }
7484
7485    // eslint-disable-next-line
7486    return delay;
7487  };
7488  const start = () => {
7489    swiper.autoplay.running = true;
7490    run();
7491    emit('autoplayStart');
7492  };
7493  const stop = () => {
7494    swiper.autoplay.running = false;
7495    clearTimeout(timeout);
7496    cancelAnimationFrame(raf);
7497    emit('autoplayStop');
7498  };
7499  const pause = (internal, reset) => {
7500    if (swiper.destroyed || !swiper.autoplay.running) return;
7501    clearTimeout(timeout);
7502    if (!internal) {
7503      pausedByInteraction = true;
7504    }
7505    const proceed = () => {
7506      emit('autoplayPause');
7507      if (swiper.params.autoplay.waitForTransition) {
7508        swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
7509      } else {
7510        resume();
7511      }
7512    };
7513    swiper.autoplay.paused = true;
7514    if (reset) {
7515      if (slideChanged) {
7516        autoplayTimeLeft = swiper.params.autoplay.delay;
7517      }
7518      slideChanged = false;
7519      proceed();
7520      return;
7521    }
7522    const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
7523    autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
7524    if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
7525    if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
7526    proceed();
7527  };
7528  const resume = () => {
7529    if ((swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) || swiper.destroyed || !swiper.autoplay.running)
7530      return;
7531    autoplayStartTime = new Date().getTime();
7532    if (pausedByInteraction) {
7533      pausedByInteraction = false;
7534      run(autoplayTimeLeft);
7535    } else {
7536      run();
7537    }
7538    swiper.autoplay.paused = false;
7539    emit('autoplayResume');
7540  };
7541  const onVisibilityChange = () => {
7542    if (swiper.destroyed || !swiper.autoplay.running) return;
7543    const document = getDocument();
7544    if (document.visibilityState === 'hidden') {
7545      pausedByInteraction = true;
7546      pause(true);
7547    }
7548    if (document.visibilityState === 'visible') {
7549      resume();
7550    }
7551  };
7552  const onPointerEnter = (e) => {
7553    if (e.pointerType !== 'mouse') return;
7554    pausedByInteraction = true;
7555    pause(true);
7556  };
7557  const onPointerLeave = (e) => {
7558    if (e.pointerType !== 'mouse') return;
7559    if (swiper.autoplay.paused) {
7560      resume();
7561    }
7562  };
7563  const attachMouseEvents = () => {
7564    if (swiper.params.autoplay.pauseOnMouseEnter) {
7565      swiper.el.addEventListener('pointerenter', onPointerEnter);
7566      swiper.el.addEventListener('pointerleave', onPointerLeave);
7567    }
7568  };
7569  const detachMouseEvents = () => {
7570    swiper.el.removeEventListener('pointerenter', onPointerEnter);
7571    swiper.el.removeEventListener('pointerleave', onPointerLeave);
7572  };
7573  const attachDocumentEvents = () => {
7574    const document = getDocument();
7575    document.addEventListener('visibilitychange', onVisibilityChange);
7576  };
7577  const detachDocumentEvents = () => {
7578    const document = getDocument();
7579    document.removeEventListener('visibilitychange', onVisibilityChange);
7580  };
7581  on('init', () => {
7582    if (swiper.params.autoplay.enabled) {
7583      attachMouseEvents();
7584      attachDocumentEvents();
7585      autoplayStartTime = new Date().getTime();
7586      start();
7587    }
7588  });
7589  on('destroy', () => {
7590    detachMouseEvents();
7591    detachDocumentEvents();
7592    if (swiper.autoplay.running) {
7593      stop();
7594    }
7595  });
7596  on('beforeTransitionStart', (_s, speed, internal) => {
7597    if (swiper.destroyed || !swiper.autoplay.running) return;
7598    if (internal || !swiper.params.autoplay.disableOnInteraction) {
7599      pause(true, true);
7600    } else {
7601      stop();
7602    }
7603  });
7604  on('sliderFirstMove', () => {
7605    if (swiper.destroyed || !swiper.autoplay.running) return;
7606    if (swiper.params.autoplay.disableOnInteraction) {
7607      stop();
7608      return;
7609    }
7610    isTouched = true;
7611    pausedByTouch = false;
7612    pausedByInteraction = false;
7613    touchStartTimeout = setTimeout(() => {
7614      pausedByInteraction = true;
7615      pausedByTouch = true;
7616      pause(true);
7617    }, 200);
7618  });
7619  on('touchEnd', () => {
7620    if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
7621    clearTimeout(touchStartTimeout);
7622    clearTimeout(timeout);
7623    if (swiper.params.autoplay.disableOnInteraction) {
7624      pausedByTouch = false;
7625      isTouched = false;
7626      return;
7627    }
7628    if (pausedByTouch && swiper.params.cssMode) resume();
7629    pausedByTouch = false;
7630    isTouched = false;
7631  });
7632  on('slideChange', () => {
7633    if (swiper.destroyed || !swiper.autoplay.running) return;
7634    slideChanged = true;
7635  });
7636  Object.assign(swiper.autoplay, {
7637    start,
7638    stop,
7639    pause,
7640    resume,
7641  });
7642}
7643
7644function Thumb(_ref) {
7645  let { swiper, extendParams, on } = _ref;
7646  extendParams({
7647    thumbs: {
7648      swiper: null,
7649      multipleActiveThumbs: true,
7650      autoScrollOffset: 0,
7651      slideThumbActiveClass: 'swiper-slide-thumb-active',
7652      thumbsContainerClass: 'swiper-thumbs',
7653    },
7654  });
7655  let initialized = false;
7656  let swiperCreated = false;
7657  swiper.thumbs = {
7658    swiper: null,
7659  };
7660  function onThumbClick() {
7661    const thumbsSwiper = swiper.thumbs.swiper;
7662    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7663    const clickedIndex = thumbsSwiper.clickedIndex;
7664    const clickedSlide = thumbsSwiper.clickedSlide;
7665    if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
7666    if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
7667    let slideToIndex;
7668    if (thumbsSwiper.params.loop) {
7669      slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
7670    } else {
7671      slideToIndex = clickedIndex;
7672    }
7673    if (swiper.params.loop) {
7674      swiper.slideToLoop(slideToIndex);
7675    } else {
7676      swiper.slideTo(slideToIndex);
7677    }
7678  }
7679  function init() {
7680    const { thumbs: thumbsParams } = swiper.params;
7681    if (initialized) return false;
7682    initialized = true;
7683    const SwiperClass = swiper.constructor;
7684    if (thumbsParams.swiper instanceof SwiperClass) {
7685      swiper.thumbs.swiper = thumbsParams.swiper;
7686      Object.assign(swiper.thumbs.swiper.originalParams, {
7687        watchSlidesProgress: true,
7688        slideToClickedSlide: false,
7689      });
7690      Object.assign(swiper.thumbs.swiper.params, {
7691        watchSlidesProgress: true,
7692        slideToClickedSlide: false,
7693      });
7694      swiper.thumbs.swiper.update();
7695    } else if (isObject(thumbsParams.swiper)) {
7696      const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
7697      Object.assign(thumbsSwiperParams, {
7698        watchSlidesProgress: true,
7699        slideToClickedSlide: false,
7700      });
7701      swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
7702      swiperCreated = true;
7703    }
7704    swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
7705    swiper.thumbs.swiper.on('tap', onThumbClick);
7706    return true;
7707  }
7708  function update(initial) {
7709    const thumbsSwiper = swiper.thumbs.swiper;
7710    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7711    const slidesPerView =
7712      thumbsSwiper.params.slidesPerView === 'auto'
7713        ? thumbsSwiper.slidesPerViewDynamic()
7714        : thumbsSwiper.params.slidesPerView;
7715
7716    // Activate thumbs
7717    let thumbsToActivate = 1;
7718    const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
7719    if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
7720      thumbsToActivate = swiper.params.slidesPerView;
7721    }
7722    if (!swiper.params.thumbs.multipleActiveThumbs) {
7723      thumbsToActivate = 1;
7724    }
7725    thumbsToActivate = Math.floor(thumbsToActivate);
7726    thumbsSwiper.slides.forEach((slideEl) => slideEl.classList.remove(thumbActiveClass));
7727    if (thumbsSwiper.params.loop || (thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled)) {
7728      for (let i = 0; i < thumbsToActivate; i += 1) {
7729        elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(
7730          (slideEl) => {
7731            slideEl.classList.add(thumbActiveClass);
7732          }
7733        );
7734      }
7735    } else {
7736      for (let i = 0; i < thumbsToActivate; i += 1) {
7737        if (thumbsSwiper.slides[swiper.realIndex + i]) {
7738          thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
7739        }
7740      }
7741    }
7742    const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
7743    const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
7744    if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
7745      const currentThumbsIndex = thumbsSwiper.activeIndex;
7746      let newThumbsIndex;
7747      let direction;
7748      if (thumbsSwiper.params.loop) {
7749        const newThumbsSlide = thumbsSwiper.slides.filter(
7750          (slideEl) => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`
7751        )[0];
7752        newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
7753        direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
7754      } else {
7755        newThumbsIndex = swiper.realIndex;
7756        direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
7757      }
7758      if (useOffset) {
7759        newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
7760      }
7761      if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
7762        if (thumbsSwiper.params.centeredSlides) {
7763          if (newThumbsIndex > currentThumbsIndex) {
7764            newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
7765          } else {
7766            newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
7767          }
7768        } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1);
7769        thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
7770      }
7771    }
7772  }
7773  on('beforeInit', () => {
7774    const { thumbs } = swiper.params;
7775    if (!thumbs || !thumbs.swiper) return;
7776    if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
7777      const document = getDocument();
7778      const getThumbsElementAndInit = () => {
7779        const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
7780        if (thumbsElement && thumbsElement.swiper) {
7781          thumbs.swiper = thumbsElement.swiper;
7782          init();
7783          update(true);
7784        } else if (thumbsElement) {
7785          const onThumbsSwiper = (e) => {
7786            thumbs.swiper = e.detail[0];
7787            thumbsElement.removeEventListener('init', onThumbsSwiper);
7788            init();
7789            update(true);
7790            thumbs.swiper.update();
7791            swiper.update();
7792          };
7793          thumbsElement.addEventListener('init', onThumbsSwiper);
7794        }
7795        return thumbsElement;
7796      };
7797      const watchForThumbsToAppear = () => {
7798        if (swiper.destroyed) return;
7799        const thumbsElement = getThumbsElementAndInit();
7800        if (!thumbsElement) {
7801          requestAnimationFrame(watchForThumbsToAppear);
7802        }
7803      };
7804      requestAnimationFrame(watchForThumbsToAppear);
7805    } else {
7806      init();
7807      update(true);
7808    }
7809  });
7810  on('slideChange update resize observerUpdate', () => {
7811    update();
7812  });
7813  on('setTransition', (_s, duration) => {
7814    const thumbsSwiper = swiper.thumbs.swiper;
7815    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7816    thumbsSwiper.setTransition(duration);
7817  });
7818  on('beforeDestroy', () => {
7819    const thumbsSwiper = swiper.thumbs.swiper;
7820    if (!thumbsSwiper || thumbsSwiper.destroyed) return;
7821    if (swiperCreated) {
7822      thumbsSwiper.destroy();
7823    }
7824  });
7825  Object.assign(swiper.thumbs, {
7826    init,
7827    update,
7828  });
7829}
7830
7831function freeMode(_ref) {
7832  let { swiper, extendParams, emit, once } = _ref;
7833  extendParams({
7834    freeMode: {
7835      enabled: false,
7836      momentum: true,
7837      momentumRatio: 1,
7838      momentumBounce: true,
7839      momentumBounceRatio: 1,
7840      momentumVelocityRatio: 1,
7841      sticky: false,
7842      minimumVelocity: 0.02,
7843    },
7844  });
7845  function onTouchStart() {
7846    if (swiper.params.cssMode) return;
7847    const translate = swiper.getTranslate();
7848    swiper.setTranslate(translate);
7849    swiper.setTransition(0);
7850    swiper.touchEventsData.velocities.length = 0;
7851    swiper.freeMode.onTouchEnd({
7852      currentPos: swiper.rtl ? swiper.translate : -swiper.translate,
7853    });
7854  }
7855  function onTouchMove() {
7856    if (swiper.params.cssMode) return;
7857    const { touchEventsData: data, touches } = swiper;
7858    // Velocity
7859    if (data.velocities.length === 0) {
7860      data.velocities.push({
7861        position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
7862        time: data.touchStartTime,
7863      });
7864    }
7865    data.velocities.push({
7866      position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
7867      time: now(),
7868    });
7869  }
7870  function onTouchEnd(_ref2) {
7871    let { currentPos } = _ref2;
7872    if (swiper.params.cssMode) return;
7873    const { params, wrapperEl, rtlTranslate: rtl, snapGrid, touchEventsData: data } = swiper;
7874    // Time diff
7875    const touchEndTime = now();
7876    const timeDiff = touchEndTime - data.touchStartTime;
vendor: 7,096 bytes, lines 7877-8058
7877    if (currentPos < -swiper.minTranslate()) {
7878      swiper.slideTo(swiper.activeIndex);
7879      return;
7880    }
7881    if (currentPos > -swiper.maxTranslate()) {
7882      if (swiper.slides.length < snapGrid.length) {
7883        swiper.slideTo(snapGrid.length - 1);
7884      } else {
7885        swiper.slideTo(swiper.slides.length - 1);
7886      }
7887      return;
7888    }
7889    if (params.freeMode.momentum) {
7890      if (data.velocities.length > 1) {
7891        const lastMoveEvent = data.velocities.pop();
7892        const velocityEvent = data.velocities.pop();
7893        const distance = lastMoveEvent.position - velocityEvent.position;
7894        const time = lastMoveEvent.time - velocityEvent.time;
7895        swiper.velocity = distance / time;
7896        swiper.velocity /= 2;
7897        if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
7898          swiper.velocity = 0;
7899        }
7900        // this implies that the user stopped moving a finger then released.
7901        // There would be no events with distance zero, so the last event is stale.
7902        if (time > 150 || now() - lastMoveEvent.time > 300) {
7903          swiper.velocity = 0;
7904        }
7905      } else {
7906        swiper.velocity = 0;
7907      }
7908      swiper.velocity *= params.freeMode.momentumVelocityRatio;
7909      data.velocities.length = 0;
7910      let momentumDuration = 1000 * params.freeMode.momentumRatio;
7911      const momentumDistance = swiper.velocity * momentumDuration;
7912      let newPosition = swiper.translate + momentumDistance;
7913      if (rtl) newPosition = -newPosition;
7914      let doBounce = false;
7915      let afterBouncePosition;
7916      const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
7917      let needsLoopFix;
7918      if (newPosition < swiper.maxTranslate()) {
7919        if (params.freeMode.momentumBounce) {
7920          if (newPosition + swiper.maxTranslate() < -bounceAmount) {
7921            newPosition = swiper.maxTranslate() - bounceAmount;
7922          }
7923          afterBouncePosition = swiper.maxTranslate();
7924          doBounce = true;
7925          data.allowMomentumBounce = true;
7926        } else {
7927          newPosition = swiper.maxTranslate();
7928        }
7929        if (params.loop && params.centeredSlides) needsLoopFix = true;
7930      } else if (newPosition > swiper.minTranslate()) {
7931        if (params.freeMode.momentumBounce) {
7932          if (newPosition - swiper.minTranslate() > bounceAmount) {
7933            newPosition = swiper.minTranslate() + bounceAmount;
7934          }
7935          afterBouncePosition = swiper.minTranslate();
7936          doBounce = true;
7937          data.allowMomentumBounce = true;
7938        } else {
7939          newPosition = swiper.minTranslate();
7940        }
7941        if (params.loop && params.centeredSlides) needsLoopFix = true;
7942      } else if (params.freeMode.sticky) {
7943        let nextSlide;
7944        for (let j = 0; j < snapGrid.length; j += 1) {
7945          if (snapGrid[j] > -newPosition) {
7946            nextSlide = j;
7947            break;
7948          }
7949        }
7950        if (
7951          Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) ||
7952          swiper.swipeDirection === 'next'
7953        ) {
7954          newPosition = snapGrid[nextSlide];
7955        } else {
7956          newPosition = snapGrid[nextSlide - 1];
7957        }
7958        newPosition = -newPosition;
7959      }
7960      if (needsLoopFix) {
7961        once('transitionEnd', () => {
7962          swiper.loopFix();
7963        });
7964      }
7965      // Fix duration
7966      if (swiper.velocity !== 0) {
7967        if (rtl) {
7968          momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
7969        } else {
7970          momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
7971        }
7972        if (params.freeMode.sticky) {
7973          // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
7974          // event, then durations can be 20+ seconds to slide one (or zero!) slides.
7975          // It's easy to see this when simulating touch with mouse events. To fix this,
7976          // limit single-slide swipes to the default slide duration. This also has the
7977          // nice side effect of matching slide speed if the user stopped moving before
7978          // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
7979          // For faster swipes, also apply limits (albeit higher ones).
7980          const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
7981          const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
7982          if (moveDistance < currentSlideSize) {
7983            momentumDuration = params.speed;
7984          } else if (moveDistance < 2 * currentSlideSize) {
7985            momentumDuration = params.speed * 1.5;
7986          } else {
7987            momentumDuration = params.speed * 2.5;
7988          }
7989        }
7990      } else if (params.freeMode.sticky) {
7991        swiper.slideToClosest();
7992        return;
7993      }
7994      if (params.freeMode.momentumBounce && doBounce) {
7995        swiper.updateProgress(afterBouncePosition);
7996        swiper.setTransition(momentumDuration);
7997        swiper.setTranslate(newPosition);
7998        swiper.transitionStart(true, swiper.swipeDirection);
7999        swiper.animating = true;
8000        elementTransitionEnd(wrapperEl, () => {
8001          if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
8002          emit('momentumBounce');
8003          swiper.setTransition(params.speed);
8004          setTimeout(() => {
8005            swiper.setTranslate(afterBouncePosition);
8006            elementTransitionEnd(wrapperEl, () => {
8007              if (!swiper || swiper.destroyed) return;
8008              swiper.transitionEnd();
8009            });
8010          }, 0);
8011        });
8012      } else if (swiper.velocity) {
8013        emit('_freeModeNoMomentumRelease');
8014        swiper.updateProgress(newPosition);
8015        swiper.setTransition(momentumDuration);
8016        swiper.setTranslate(newPosition);
8017        swiper.transitionStart(true, swiper.swipeDirection);
8018        if (!swiper.animating) {
8019          swiper.animating = true;
8020          elementTransitionEnd(wrapperEl, () => {
8021            if (!swiper || swiper.destroyed) return;
8022            swiper.transitionEnd();
8023          });
8024        }
8025      } else {
8026        swiper.updateProgress(newPosition);
8027      }
8028      swiper.updateActiveIndex();
8029      swiper.updateSlidesClasses();
8030    } else if (params.freeMode.sticky) {
8031      swiper.slideToClosest();
8032      return;
8033    } else if (params.freeMode) {
8034      emit('_freeModeNoMomentumRelease');
8035    }
8036    if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
8037      swiper.updateProgress();
8038      swiper.updateActiveIndex();
8039      swiper.updateSlidesClasses();
8040    }
8041  }
8042  Object.assign(swiper, {
8043    freeMode: {
8044      onTouchStart,
8045      onTouchMove,
8046      onTouchEnd,
8047    },
8048  });
8049}
8050
8051function Grid(_ref) {
8052  let { swiper, extendParams } = _ref;
8053  extendParams({
8054    grid: {
8055      rows: 1,
8056      fill: 'column',
8057    },
8058  });
8059  let slidesNumberEvenToRows;
8060  let slidesPerRow;
8061  let numFullColumns;
8062  const getSpaceBetween = () => {
8063    let spaceBetween = swiper.params.spaceBetween;
8064    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
8065      spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiper.size;
8066    } else if (typeof spaceBetween === 'string') {
8067      spaceBetween = parseFloat(spaceBetween);
8068    }
8069    return spaceBetween;
8070  };
8071  const initSlides = (slidesLength) => {
8072    const { slidesPerView } = swiper.params;
8073    const { rows, fill } = swiper.params.grid;
8074    numFullColumns = Math.floor(slidesLength / rows);
8075    if (Math.floor(slidesLength / rows) === slidesLength / rows) {
8076      slidesNumberEvenToRows = slidesLength;
8077    } else {
8078      slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
8079    }
8080    if (slidesPerView !== 'auto' && fill === 'row') {
8081      slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
8082    }
8083    slidesPerRow = slidesNumberEvenToRows / rows;
8084  };
8085  const updateSlide = (i, slide, slidesLength, getDirectionLabel) => {
8086    const { slidesPerGroup } = swiper.params;
8087    const spaceBetween = getSpaceBetween();
8088    const { rows, fill } = swiper.params.grid;
8089    // Set slides order
8090    let newSlideOrderIndex;
8091    let column;
8092    let row;
8093    if (fill === 'row' && slidesPerGroup > 1) {
8094      const groupIndex = Math.floor(i / (slidesPerGroup * rows));
8095      const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
8096      const columnsInGroup =
8097        groupIndex === 0
8098          ? slidesPerGroup
8099          : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
8100      row = Math.floor(slideIndexInGroup / columnsInGroup);
8101      column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
8102      newSlideOrderIndex = column + (row * slidesNumberEvenToRows) / rows;
8103      slide.style.order = newSlideOrderIndex;
8104    } else if (fill === 'column') {
8105      column = Math.floor(i / rows);
8106      row = i - column * rows;
8107      if (column > numFullColumns || (column === numFullColumns && row === rows - 1)) {
8108        row += 1;
8109        if (row >= rows) {
8110          row = 0;
8111          column += 1;
8112        }
8113      }
8114    } else {
8115      row = Math.floor(i / slidesPerRow);
8116      column = i - row * slidesPerRow;
8117    }
8118    slide.row = row;
8119    slide.column = column;
8120    slide.style[getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
8121  };
8122  const updateWrapperSize = (slideSize, snapGrid, getDirectionLabel) => {
8123    const { centeredSlides, roundLengths } = swiper.params;
8124    const spaceBetween = getSpaceBetween();
8125    const { rows } = swiper.params.grid;
8126    swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
8127    swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
8128    swiper.wrapperEl.style[getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
8129    if (centeredSlides) {
8130      const newSlidesGrid = [];
8131      for (let i = 0; i < snapGrid.length; i += 1) {
8132        let slidesGridItem = snapGrid[i];
8133        if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
8134        if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
8135      }
8136      snapGrid.splice(0, snapGrid.length);
8137      snapGrid.push(...newSlidesGrid);
8138    }
8139  };
8140  swiper.grid = {
8141    initSlides,
8142    updateSlide,
8143    updateWrapperSize,
8144  };
8145}
8146
8147function appendSlide(slides) {
8148  const swiper = this;
8149  const { params, slidesEl } = swiper;
8150  if (params.loop) {
8151    swiper.loopDestroy();
8152  }
8153  const appendElement = (slideEl) => {
8154    if (typeof slideEl === 'string') {
8155      const tempDOM = document.createElement('div');
8156      tempDOM.innerHTML = slideEl;
8157      slidesEl.append(tempDOM.children[0]);
8158      tempDOM.innerHTML = '';
8159    } else {
8160      slidesEl.append(slideEl);
8161    }
8162  };
8163  if (typeof slides === 'object' && 'length' in slides) {
8164    for (let i = 0; i < slides.length; i += 1) {
8165      if (slides[i]) appendElement(slides[i]);
8166    }
8167  } else {
8168    appendElement(slides);
8169  }
8170  swiper.recalcSlides();
8171  if (params.loop) {
8172    swiper.loopCreate();
8173  }
8174  if (!params.observer || swiper.isElement) {
vendor: 5,441 bytes, lines 8175-8355
8175    swiper.update();
8176  }
8177}
8178
8179function prependSlide(slides) {
8180  const swiper = this;
8181  const { params, activeIndex, slidesEl } = swiper;
8182  if (params.loop) {
8183    swiper.loopDestroy();
8184  }
8185  let newActiveIndex = activeIndex + 1;
8186  const prependElement = (slideEl) => {
8187    if (typeof slideEl === 'string') {
8188      const tempDOM = document.createElement('div');
8189      tempDOM.innerHTML = slideEl;
8190      slidesEl.prepend(tempDOM.children[0]);
8191      tempDOM.innerHTML = '';
8192    } else {
8193      slidesEl.prepend(slideEl);
8194    }
8195  };
8196  if (typeof slides === 'object' && 'length' in slides) {
8197    for (let i = 0; i < slides.length; i += 1) {
8198      if (slides[i]) prependElement(slides[i]);
8199    }
8200    newActiveIndex = activeIndex + slides.length;
8201  } else {
8202    prependElement(slides);
8203  }
8204  swiper.recalcSlides();
8205  if (params.loop) {
8206    swiper.loopCreate();
8207  }
8208  if (!params.observer || swiper.isElement) {
8209    swiper.update();
8210  }
8211  swiper.slideTo(newActiveIndex, 0, false);
8212}
8213
8214function addSlide(index, slides) {
8215  const swiper = this;
8216  const { params, activeIndex, slidesEl } = swiper;
8217  let activeIndexBuffer = activeIndex;
8218  if (params.loop) {
8219    activeIndexBuffer -= swiper.loopedSlides;
8220    swiper.loopDestroy();
8221    swiper.recalcSlides();
8222  }
8223  const baseLength = swiper.slides.length;
8224  if (index <= 0) {
8225    swiper.prependSlide(slides);
8226    return;
8227  }
8228  if (index >= baseLength) {
8229    swiper.appendSlide(slides);
8230    return;
8231  }
8232  let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
8233  const slidesBuffer = [];
8234  for (let i = baseLength - 1; i >= index; i -= 1) {
8235    const currentSlide = swiper.slides[i];
8236    currentSlide.remove();
8237    slidesBuffer.unshift(currentSlide);
8238  }
8239  if (typeof slides === 'object' && 'length' in slides) {
8240    for (let i = 0; i < slides.length; i += 1) {
8241      if (slides[i]) slidesEl.append(slides[i]);
8242    }
8243    newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
8244  } else {
8245    slidesEl.append(slides);
8246  }
8247  for (let i = 0; i < slidesBuffer.length; i += 1) {
8248    slidesEl.append(slidesBuffer[i]);
8249  }
8250  swiper.recalcSlides();
8251  if (params.loop) {
8252    swiper.loopCreate();
8253  }
8254  if (!params.observer || swiper.isElement) {
8255    swiper.update();
8256  }
8257  if (params.loop) {
8258    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8259  } else {
8260    swiper.slideTo(newActiveIndex, 0, false);
8261  }
8262}
8263
8264function removeSlide(slidesIndexes) {
8265  const swiper = this;
8266  const { params, activeIndex } = swiper;
8267  let activeIndexBuffer = activeIndex;
8268  if (params.loop) {
8269    activeIndexBuffer -= swiper.loopedSlides;
8270    swiper.loopDestroy();
8271  }
8272  let newActiveIndex = activeIndexBuffer;
8273  let indexToRemove;
8274  if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
8275    for (let i = 0; i < slidesIndexes.length; i += 1) {
8276      indexToRemove = slidesIndexes[i];
8277      if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8278      if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8279    }
8280    newActiveIndex = Math.max(newActiveIndex, 0);
8281  } else {
8282    indexToRemove = slidesIndexes;
8283    if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
8284    if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
8285    newActiveIndex = Math.max(newActiveIndex, 0);
8286  }
8287  swiper.recalcSlides();
8288  if (params.loop) {
8289    swiper.loopCreate();
8290  }
8291  if (!params.observer || swiper.isElement) {
8292    swiper.update();
8293  }
8294  if (params.loop) {
8295    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
8296  } else {
8297    swiper.slideTo(newActiveIndex, 0, false);
8298  }
8299}
8300
8301function removeAllSlides() {
8302  const swiper = this;
8303  const slidesIndexes = [];
8304  for (let i = 0; i < swiper.slides.length; i += 1) {
8305    slidesIndexes.push(i);
8306  }
8307  swiper.removeSlide(slidesIndexes);
8308}
8309
8310function Manipulation(_ref) {
8311  let { swiper } = _ref;
8312  Object.assign(swiper, {
8313    appendSlide: appendSlide.bind(swiper),
8314    prependSlide: prependSlide.bind(swiper),
8315    addSlide: addSlide.bind(swiper),
8316    removeSlide: removeSlide.bind(swiper),
8317    removeAllSlides: removeAllSlides.bind(swiper),
8318  });
8319}
8320
8321function effectInit(params) {
8322  const {
8323    effect,
8324    swiper,
8325    on,
8326    setTranslate,
8327    setTransition,
8328    overwriteParams,
8329    perspective,
8330    recreateShadows,
8331    getEffectParams,
8332  } = params;
8333  on('beforeInit', () => {
8334    if (swiper.params.effect !== effect) return;
8335    swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
8336    if (perspective && perspective()) {
8337      swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
8338    }
8339    const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
8340    Object.assign(swiper.params, overwriteParamsResult);
8341    Object.assign(swiper.originalParams, overwriteParamsResult);
8342  });
8343  on('setTranslate', () => {
8344    if (swiper.params.effect !== effect) return;
8345    setTranslate();
8346  });
8347  on('setTransition', (_s, duration) => {
8348    if (swiper.params.effect !== effect) return;
8349    setTransition(duration);
8350  });
8351  on('transitionEnd', () => {
8352    if (swiper.params.effect !== effect) return;
8353    if (recreateShadows) {
8354      if (!getEffectParams || !getEffectParams().slideShadows) return;
8355      // remove shadows
8356      swiper.slides.forEach((slideEl) => {
8357        slideEl
8358          .querySelectorAll(
8359            '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left'
8360          )
8361          .forEach((shadowEl) => shadowEl.remove());
8362      });
8363      // create new one
8364      recreateShadows();
8365    }
8366  });
8367  let requireUpdateOnVirtual;
8368  on('virtualUpdate', () => {
8369    if (swiper.params.effect !== effect) return;
8370    if (!swiper.slides.length) {
8371      requireUpdateOnVirtual = true;
8372    }
8373    requestAnimationFrame(() => {
8374      if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {
8375        setTranslate();
8376        requireUpdateOnVirtual = false;
8377      }
8378    });
8379  });
8380}
8381
8382function effectTarget(effectParams, slideEl) {
8383  const transformEl = getSlideTransformEl(slideEl);
8384  if (transformEl !== slideEl) {
8385    transformEl.style.backfaceVisibility = 'hidden';
8386    transformEl.style['-webkit-backface-visibility'] = 'hidden';
8387  }
8388  return transformEl;
8389}
8390
8391function effectVirtualTransitionEnd(_ref) {
8392  let { swiper, duration, transformElements, allSlides } = _ref;
8393  const { activeIndex } = swiper;
8394  const getSlide = (el) => {
8395    if (!el.parentElement) {
8396      // assume shadow root
8397      const slide = swiper.slides.filter((slideEl) => slideEl.shadowEl && slideEl.shadowEl === el.parentNode)[0];
8398      return slide;
8399    }
8400    return el.parentElement;
8401  };
8402  if (swiper.params.virtualTranslate && duration !== 0) {
8403    let eventTriggered = false;
8404    let transitionEndTarget;
8405    if (allSlides) {
8406      transitionEndTarget = transformElements;
8407    } else {
8408      transitionEndTarget = transformElements.filter((transformEl) => {
8409        const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
8410        return swiper.getSlideIndex(el) === activeIndex;
8411      });
8412    }
8413    transitionEndTarget.forEach((el) => {
8414      elementTransitionEnd(el, () => {
8415        if (eventTriggered) return;
8416        if (!swiper || swiper.destroyed) return;
8417        eventTriggered = true;
8418        swiper.animating = false;
8419        const evt = new window.CustomEvent('transitionend', {
8420          bubbles: true,
8421          cancelable: true,
8422        });
8423        swiper.wrapperEl.dispatchEvent(evt);
8424      });
8425    });
8426  }
8427}
8428
8429function EffectFade(_ref) {
8430  let { swiper, extendParams, on } = _ref;
8431  extendParams({
8432    fadeEffect: {
8433      crossFade: false,
8434    },
8435  });
8436  const setTranslate = () => {
8437    const { slides } = swiper;
8438    const params = swiper.params.fadeEffect;
8439    for (let i = 0; i < slides.length; i += 1) {
8440      const slideEl = swiper.slides[i];
8441      const offset = slideEl.swiperSlideOffset;
8442      let tx = -offset;
8443      if (!swiper.params.virtualTranslate) tx -= swiper.translate;
8444      let ty = 0;
8445      if (!swiper.isHorizontal()) {
8446        ty = tx;
8447        tx = 0;
8448      }
8449      const slideOpacity = swiper.params.fadeEffect.crossFade
8450        ? Math.max(1 - Math.abs(slideEl.progress), 0)
8451        : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
8452      const targetEl = effectTarget(params, slideEl);
8453      targetEl.style.opacity = slideOpacity;
8454      targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
8455    }
8456  };
8457  const setTransition = (duration) => {
8458    const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
8459    transformElements.forEach((el) => {
8460      el.style.transitionDuration = `${duration}ms`;
8461    });
8462    effectVirtualTransitionEnd({
8463      swiper,
8464      duration,
8465      transformElements,
8466      allSlides: true,
8467    });
8468  };
8469  effectInit({
8470    effect: 'fade',
8471    swiper,
8472    on,
8473    setTranslate,
8474    setTransition,
8475    overwriteParams: () => ({
8476      slidesPerView: 1,
8477      slidesPerGroup: 1,
8478      watchSlidesProgress: true,
8479      spaceBetween: 0,
8480      virtualTranslate: !swiper.params.cssMode,
8481    }),
8482  });
8483}
8484
8485function EffectCube(_ref) {
8486  let { swiper, extendParams, on } = _ref;
8487  extendParams({
8488    cubeEffect: {
8489      slideShadows: true,
8490      shadow: true,
8491      shadowOffset: 20,
8492      shadowScale: 0.94,
8493    },
8494  });
8495  const createSlideShadows = (slideEl, progress, isHorizontal) => {
8496    let shadowBefore = isHorizontal
8497      ? slideEl.querySelector('.swiper-slide-shadow-left')
8498      : slideEl.querySelector('.swiper-slide-shadow-top');
8499    let shadowAfter = isHorizontal
8500      ? slideEl.querySelector('.swiper-slide-shadow-right')
8501      : slideEl.querySelector('.swiper-slide-shadow-bottom');
8502    if (!shadowBefore) {
8503      shadowBefore = createElement('div', `swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`);
8504      slideEl.append(shadowBefore);
8505    }
8506    if (!shadowAfter) {
8507      shadowAfter = createElement('div', `swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`);
8508      slideEl.append(shadowAfter);
8509    }
8510    if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
8511    if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
8512  };
8513  const recreateShadows = () => {
8514    // create new ones
8515    const isHorizontal = swiper.isHorizontal();
vendor: 4,378 bytes, lines 8516-8627
8516    swiper.slides.forEach((slideEl) => {
8517      const progress = Math.max(Math.min(slideEl.progress, 1), -1);
8518      createSlideShadows(slideEl, progress, isHorizontal);
8519    });
8520  };
8521  const setTranslate = () => {
8522    const {
8523      el,
8524      wrapperEl,
8525      slides,
8526      width: swiperWidth,
8527      height: swiperHeight,
8528      rtlTranslate: rtl,
8529      size: swiperSize,
8530      browser,
8531    } = swiper;
8532    const params = swiper.params.cubeEffect;
8533    const isHorizontal = swiper.isHorizontal();
8534    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
8535    let wrapperRotate = 0;
8536    let cubeShadowEl;
8537    if (params.shadow) {
8538      if (isHorizontal) {
8539        cubeShadowEl = swiper.slidesEl.querySelector('.swiper-cube-shadow');
8540        if (!cubeShadowEl) {
8541          cubeShadowEl = createElement('div', 'swiper-cube-shadow');
8542          swiper.slidesEl.append(cubeShadowEl);
8543        }
8544        cubeShadowEl.style.height = `${swiperWidth}px`;
8545      } else {
8546        cubeShadowEl = el.querySelector('.swiper-cube-shadow');
8547        if (!cubeShadowEl) {
8548          cubeShadowEl = createElement('div', 'swiper-cube-shadow');
8549          el.append(cubeShadowEl);
8550        }
8551      }
8552    }
8553    for (let i = 0; i < slides.length; i += 1) {
8554      const slideEl = slides[i];
8555      let slideIndex = i;
8556      if (isVirtual) {
8557        slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
8558      }
8559      let slideAngle = slideIndex * 90;
8560      let round = Math.floor(slideAngle / 360);
8561      if (rtl) {
8562        slideAngle = -slideAngle;
8563        round = Math.floor(-slideAngle / 360);
8564      }
8565      const progress = Math.max(Math.min(slideEl.progress, 1), -1);
8566      let tx = 0;
8567      let ty = 0;
8568      let tz = 0;
8569      if (slideIndex % 4 === 0) {
8570        tx = -round * 4 * swiperSize;
8571        tz = 0;
8572      } else if ((slideIndex - 1) % 4 === 0) {
8573        tx = 0;
8574        tz = -round * 4 * swiperSize;
8575      } else if ((slideIndex - 2) % 4 === 0) {
8576        tx = swiperSize + round * 4 * swiperSize;
8577        tz = swiperSize;
8578      } else if ((slideIndex - 3) % 4 === 0) {
8579        tx = -swiperSize;
8580        tz = 3 * swiperSize + swiperSize * 4 * round;
8581      }
8582      if (rtl) {
8583        tx = -tx;
8584      }
8585      if (!isHorizontal) {
8586        ty = tx;
8587        tx = 0;
8588      }
8589      const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${
8590        isHorizontal ? slideAngle : 0
8591      }deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
8592      if (progress <= 1 && progress > -1) {
8593        wrapperRotate = slideIndex * 90 + progress * 90;
8594        if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
8595      }
8596      slideEl.style.transform = transform;
8597      if (params.slideShadows) {
8598        createSlideShadows(slideEl, progress, isHorizontal);
8599      }
8600    }
8601    wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
8602    wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
8603    if (params.shadow) {
8604      if (isHorizontal) {
8605        cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${
8606          -swiperWidth / 2
8607        }px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`;
8608      } else {
8609        const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
8610        const multiplier =
8611          1.5 - (Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2 + Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2);
8612        const scale1 = params.shadowScale;
8613        const scale2 = params.shadowScale / multiplier;
8614        const offset = params.shadowOffset;
8615        cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${
8616          swiperHeight / 2 + offset
8617        }px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`;
8618      }
8619    }
8620    const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
8621    wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${
8622      swiper.isHorizontal() ? 0 : wrapperRotate
8623    }deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`;
8624    wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
8625  };
8626  const setTransition = (duration) => {
8627    const { el, slides } = swiper;
8628    slides.forEach((slideEl) => {
8629      slideEl.style.transitionDuration = `${duration}ms`;
8630      slideEl
8631        .querySelectorAll(
8632          '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left'
8633        )
8634        .forEach((subEl) => {
8635          subEl.style.transitionDuration = `${duration}ms`;
8636        });
8637    });
8638    if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
8639      const shadowEl = el.querySelector('.swiper-cube-shadow');
8640      if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
8641    }
8642  };
8643  effectInit({
8644    effect: 'cube',
8645    swiper,
8646    on,
8647    setTranslate,
8648    setTransition,
8649    recreateShadows,
8650    getEffectParams: () => swiper.params.cubeEffect,
8651    perspective: () => true,
8652    overwriteParams: () => ({
8653      slidesPerView: 1,
8654      slidesPerGroup: 1,
8655      watchSlidesProgress: true,
8656      resistanceRatio: 0,
8657      spaceBetween: 0,
8658      centeredSlides: false,
8659      virtualTranslate: true,
8660    }),
8661  });
8662}
8663
8664function createShadow(params, slideEl, side) {
8665  const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}`;
8666  const shadowContainer = getSlideTransformEl(slideEl);
8667  let shadowEl = shadowContainer.querySelector(`.${shadowClass}`);
8668  if (!shadowEl) {
8669    shadowEl = createElement('div', `swiper-slide-shadow${side ? `-${side}` : ''}`);
8670    shadowContainer.append(shadowEl);
8671  }
8672  return shadowEl;
8673}
8674
8675function EffectFlip(_ref) {
8676  let { swiper, extendParams, on } = _ref;
8677  extendParams({
8678    flipEffect: {
8679      slideShadows: true,
8680      limitRotation: true,
8681    },
8682  });
8683  const createSlideShadows = (slideEl, progress, params) => {
8684    let shadowBefore = swiper.isHorizontal()
8685      ? slideEl.querySelector('.swiper-slide-shadow-left')
8686      : slideEl.querySelector('.swiper-slide-shadow-top');
8687    let shadowAfter = swiper.isHorizontal()
8688      ? slideEl.querySelector('.swiper-slide-shadow-right')
8689      : slideEl.querySelector('.swiper-slide-shadow-bottom');
8690    if (!shadowBefore) {
8691      shadowBefore = createShadow(params, slideEl, swiper.isHorizontal() ? 'left' : 'top');
8692    }
8693    if (!shadowAfter) {
8694      shadowAfter = createShadow(params, slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
8695    }
8696    if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
8697    if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
8698  };
8699  const recreateShadows = () => {
8700    // Set shadows
8701    const params = swiper.params.flipEffect;
8702    swiper.slides.forEach((slideEl) => {
8703      let progress = slideEl.progress;
8704      if (swiper.params.flipEffect.limitRotation) {
8705        progress = Math.max(Math.min(slideEl.progress, 1), -1);
8706      }
8707      createSlideShadows(slideEl, progress, params);
8708    });
8709  };
8710  const setTranslate = () => {
8711    const { slides, rtlTranslate: rtl } = swiper;
8712    const params = swiper.params.flipEffect;
8713    for (let i = 0; i < slides.length; i += 1) {
8714      const slideEl = slides[i];
8715      let progress = slideEl.progress;
8716      if (swiper.params.flipEffect.limitRotation) {
8717        progress = Math.max(Math.min(slideEl.progress, 1), -1);
8718      }
8719      const offset = slideEl.swiperSlideOffset;
8720      const rotate = -180 * progress;
8721      let rotateY = rotate;
8722      let rotateX = 0;
8723      let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
8724      let ty = 0;
8725      if (!swiper.isHorizontal()) {
8726        ty = tx;
8727        tx = 0;
8728        rotateX = -rotateY;
8729        rotateY = 0;
8730      } else if (rtl) {
8731        rotateY = -rotateY;
8732      }
8733      slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
8734      if (params.slideShadows) {
8735        createSlideShadows(slideEl, progress, params);
8736      }
8737      const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
8738      const targetEl = effectTarget(params, slideEl);
8739      targetEl.style.transform = transform;
8740    }
8741  };
8742  const setTransition = (duration) => {
8743    const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
8744    transformElements.forEach((el) => {
8745      el.style.transitionDuration = `${duration}ms`;
8746      el.querySelectorAll(
8747        '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left'
8748      ).forEach((shadowEl) => {
8749        shadowEl.style.transitionDuration = `${duration}ms`;
8750      });
8751    });
8752    effectVirtualTransitionEnd({
8753      swiper,
8754      duration,
8755      transformElements,
8756    });
8757  };
8758  effectInit({
8759    effect: 'flip',
8760    swiper,
8761    on,
8762    setTranslate,
8763    setTransition,
8764    recreateShadows,
8765    getEffectParams: () => swiper.params.flipEffect,
8766    perspective: () => true,
8767    overwriteParams: () => ({
8768      slidesPerView: 1,
8769      slidesPerGroup: 1,
8770      watchSlidesProgress: true,
8771      spaceBetween: 0,
8772      virtualTranslate: !swiper.params.cssMode,
8773    }),
8774  });
8775}
8776
8777function EffectCoverflow(_ref) {
8778  let { swiper, extendParams, on } = _ref;
8779  extendParams({
8780    coverflowEffect: {
8781      rotate: 50,
8782      stretch: 0,
8783      depth: 100,
8784      scale: 1,
8785      modifier: 1,
8786      slideShadows: true,
8787    },
8788  });
8789  const setTranslate = () => {
8790    const { width: swiperWidth, height: swiperHeight, slides, slidesSizesGrid } = swiper;
8791    const params = swiper.params.coverflowEffect;
8792    const isHorizontal = swiper.isHorizontal();
8793    const transform = swiper.translate;
8794    const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
8795    const rotate = isHorizontal ? params.rotate : -params.rotate;
8796    const translate = params.depth;
8797    // Each slide offset from center
8798    for (let i = 0, length = slides.length; i < length; i += 1) {
8799      const slideEl = slides[i];
8800      const slideSize = slidesSizesGrid[i];
8801      const slideOffset = slideEl.swiperSlideOffset;
8802      const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
8803      const offsetMultiplier =
8804        typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
8805      let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
8806      let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
8807      // var rotateZ = 0
8808      let translateZ = -translate * Math.abs(offsetMultiplier);
8809      let stretch = params.stretch;
8810      // Allow percentage to make a relative stretch for responsive sliders
8811      if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
8812        stretch = (parseFloat(params.stretch) / 100) * slideSize;
8813      }
8814      let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
8815      let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
8816      let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
8817
8818      // Fix for ultra small values
8819      if (Math.abs(translateX) < 0.001) translateX = 0;
8820      if (Math.abs(translateY) < 0.001) translateY = 0;
8821      if (Math.abs(translateZ) < 0.001) translateZ = 0;
8822      if (Math.abs(rotateY) < 0.001) rotateY = 0;
8823      if (Math.abs(rotateX) < 0.001) rotateX = 0;
8824      if (Math.abs(scale) < 0.001) scale = 0;
8825      const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px)  rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
8826      const targetEl = effectTarget(params, slideEl);
8827      targetEl.style.transform = slideTransform;
8828      slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
8829      if (params.slideShadows) {
8830        // Set shadows
8831        let shadowBeforeEl = isHorizontal
8832          ? slideEl.querySelector('.swiper-slide-shadow-left')
8833          : slideEl.querySelector('.swiper-slide-shadow-top');
8834        let shadowAfterEl = isHorizontal
8835          ? slideEl.querySelector('.swiper-slide-shadow-right')
8836          : slideEl.querySelector('.swiper-slide-shadow-bottom');
8837        if (!shadowBeforeEl) {
8838          shadowBeforeEl = createShadow(params, slideEl, isHorizontal ? 'left' : 'top');
8839        }
8840        if (!shadowAfterEl) {
8841          shadowAfterEl = createShadow(params, slideEl, isHorizontal ? 'right' : 'bottom');
8842        }
8843        if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
8844        if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
8845      }
8846    }
8847  };
8848  const setTransition = (duration) => {
8849    const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
8850    transformElements.forEach((el) => {
8851      el.style.transitionDuration = `${duration}ms`;
8852      el.querySelectorAll(
8853        '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left'
8854      ).forEach((shadowEl) => {
8855        shadowEl.style.transitionDuration = `${duration}ms`;
8856      });
8857    });
8858  };
8859  effectInit({
8860    effect: 'coverflow',
8861    swiper,
8862    on,
8863    setTranslate,
8864    setTransition,
8865    perspective: () => true,
8866    overwriteParams: () => ({
8867      watchSlidesProgress: true,
8868    }),
8869  });
8870}
8871
8872function EffectCreative(_ref) {
8873  let { swiper, extendParams, on } = _ref;
8874  extendParams({
8875    creativeEffect: {
8876      limitProgress: 1,
8877      shadowPerProgress: false,
8878      progressMultiplier: 1,
8879      perspective: true,
8880      prev: {
8881        translate: [0, 0, 0],
8882        rotate: [0, 0, 0],
8883        opacity: 1,
8884        scale: 1,
8885      },
8886      next: {
8887        translate: [0, 0, 0],
8888        rotate: [0, 0, 0],
8889        opacity: 1,
8890        scale: 1,
8891      },
8892    },
8893  });
8894  const getTranslateValue = (value) => {
8895    if (typeof value === 'string') return value;
8896    return `${value}px`;
8897  };
8898  const setTranslate = () => {
8899    const { slides, wrapperEl, slidesSizesGrid } = swiper;
8900    const params = swiper.params.creativeEffect;
8901    const { progressMultiplier: multiplier } = params;
8902    const isCenteredSlides = swiper.params.centeredSlides;
8903    if (isCenteredSlides) {
8904      const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
8905      wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
8906    }
8907    for (let i = 0; i < slides.length; i += 1) {
8908      const slideEl = slides[i];
8909      const slideProgress = slideEl.progress;
8910      const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
8911      let originalProgress = progress;
8912      if (!isCenteredSlides) {
8913        originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
8914      }
8915      const offset = slideEl.swiperSlideOffset;
8916      const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
8917      const r = [0, 0, 0];
8918      let custom = false;
8919      if (!swiper.isHorizontal()) {
8920        t[1] = t[0];
8921        t[0] = 0;
8922      }
8923      let data = {
8924        translate: [0, 0, 0],
8925        rotate: [0, 0, 0],
8926        scale: 1,
8927        opacity: 1,
8928      };
8929      if (progress < 0) {
8930        data = params.next;
8931        custom = true;
8932      } else if (progress > 0) {
8933        data = params.prev;
8934        custom = true;
8935      }
8936      // set translate
8937      t.forEach((value, index) => {
8938        t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(
8939          progress * multiplier
8940        )}))`;
8941      });
8942      // set rotates
8943      r.forEach((value, index) => {
8944        r[index] = data.rotate[index] * Math.abs(progress * multiplier);
8945      });
8946      slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
8947      const translateString = t.join(', ');
8948      const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
8949      const scaleString =
8950        originalProgress < 0
8951          ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})`
8952          : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
8953      const opacityString =
8954        originalProgress < 0
8955          ? 1 + (1 - data.opacity) * originalProgress * multiplier
8956          : 1 - (1 - data.opacity) * originalProgress * multiplier;
8957      const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
8958
8959      // Set shadows
8960      if ((custom && data.shadow) || !custom) {
8961        let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
8962        if (!shadowEl && data.shadow) {
8963          shadowEl = createShadow(params, slideEl);
8964        }
8965        if (shadowEl) {
8966          const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
8967          shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
8968        }
8969      }
8970      const targetEl = effectTarget(params, slideEl);
8971      targetEl.style.transform = transform;
8972      targetEl.style.opacity = opacityString;
8973      if (data.origin) {
8974        targetEl.style.transformOrigin = data.origin;
8975      }
8976    }
8977  };
8978  const setTransition = (duration) => {
8979    const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
vendor: 4,059 bytes, lines 8980-9090
8980    transformElements.forEach((el) => {
8981      el.style.transitionDuration = `${duration}ms`;
8982      el.querySelectorAll('.swiper-slide-shadow').forEach((shadowEl) => {
8983        shadowEl.style.transitionDuration = `${duration}ms`;
8984      });
8985    });
8986    effectVirtualTransitionEnd({
8987      swiper,
8988      duration,
8989      transformElements,
8990      allSlides: true,
8991    });
8992  };
8993  effectInit({
8994    effect: 'creative',
8995    swiper,
8996    on,
8997    setTranslate,
8998    setTransition,
8999    perspective: () => swiper.params.creativeEffect.perspective,
9000    overwriteParams: () => ({
9001      watchSlidesProgress: true,
9002      virtualTranslate: !swiper.params.cssMode,
9003    }),
9004  });
9005}
9006
9007function EffectCards(_ref) {
9008  let { swiper, extendParams, on } = _ref;
9009  extendParams({
9010    cardsEffect: {
9011      slideShadows: true,
9012      rotate: true,
9013      perSlideRotate: 2,
9014      perSlideOffset: 8,
9015    },
9016  });
9017  const setTranslate = () => {
9018    const { slides, activeIndex, rtlTranslate: rtl } = swiper;
9019    const params = swiper.params.cardsEffect;
9020    const { startTranslate, isTouched } = swiper.touchEventsData;
9021    const currentTranslate = rtl ? -swiper.translate : swiper.translate;
9022    for (let i = 0; i < slides.length; i += 1) {
9023      const slideEl = slides[i];
9024      const slideProgress = slideEl.progress;
9025      const progress = Math.min(Math.max(slideProgress, -4), 4);
9026      let offset = slideEl.swiperSlideOffset;
9027      if (swiper.params.centeredSlides && !swiper.params.cssMode) {
9028        swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
9029      }
9030      if (swiper.params.centeredSlides && swiper.params.cssMode) {
9031        offset -= slides[0].swiperSlideOffset;
9032      }
9033      let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
9034      let tY = 0;
9035      const tZ = -100 * Math.abs(progress);
9036      let scale = 1;
9037      let rotate = -params.perSlideRotate * progress;
9038      let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
9039      const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
9040      const isSwipeToNext =
9041        (slideIndex === activeIndex || slideIndex === activeIndex - 1) &&
9042        progress > 0 &&
9043        progress < 1 &&
9044        (isTouched || swiper.params.cssMode) &&
9045        currentTranslate < startTranslate;
9046      const isSwipeToPrev =
9047        (slideIndex === activeIndex || slideIndex === activeIndex + 1) &&
9048        progress < 0 &&
9049        progress > -1 &&
9050        (isTouched || swiper.params.cssMode) &&
9051        currentTranslate > startTranslate;
9052      if (isSwipeToNext || isSwipeToPrev) {
9053        const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
9054        rotate += -28 * progress * subProgress;
9055        scale += -0.5 * subProgress;
9056        tXAdd += 96 * subProgress;
9057        tY = `${-25 * subProgress * Math.abs(progress)}%`;
9058      }
9059      if (progress < 0) {
9060        // next
9061        tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
9062      } else if (progress > 0) {
9063        // prev
9064        tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
9065      } else {
9066        tX = `${tX}px`;
9067      }
9068      if (!swiper.isHorizontal()) {
9069        const prevY = tY;
9070        tY = tX;
9071        tX = prevY;
9072      }
9073      const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
9074
9075      /* eslint-disable */
9076      const transform = `
9077          translate3d(${tX}, ${tY}, ${tZ}px)
9078          rotateZ(${params.rotate ? (rtl ? -rotate : rotate) : 0}deg)
9079          scale(${scaleString})
9080        `;
9081      /* eslint-enable */
9082
9083      if (params.slideShadows) {
9084        // Set shadows
9085        let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
9086        if (!shadowEl) {
9087          shadowEl = createShadow(params, slideEl);
9088        }
9089        if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
9090      }
9091      slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
9092      const targetEl = effectTarget(params, slideEl);
9093      targetEl.style.transform = transform;
9094    }
9095  };
9096  const setTransition = (duration) => {
9097    const transformElements = swiper.slides.map((slideEl) => getSlideTransformEl(slideEl));
9098    transformElements.forEach((el) => {
9099      el.style.transitionDuration = `${duration}ms`;
9100      el.querySelectorAll('.swiper-slide-shadow').forEach((shadowEl) => {
9101        shadowEl.style.transitionDuration = `${duration}ms`;
9102      });
9103    });
9104    effectVirtualTransitionEnd({
9105      swiper,
9106      duration,
9107      transformElements,
9108    });
9109  };
9110  effectInit({
9111    effect: 'cards',
9112    swiper,
9113    on,
9114    setTranslate,
9115    setTransition,
9116    perspective: () => true,
9117    overwriteParams: () => ({
9118      watchSlidesProgress: true,
9119      virtualTranslate: !swiper.params.cssMode,
9120    }),
9121  });
9122}
9123
9124// Swiper Class
9125const modules = [
9126  Virtual,
9127  Keyboard,
9128  Mousewheel,
9129  Navigation,
9130  Pagination,
9131  Scrollbar,
9132  Parallax,
9133  Zoom,
9134  Controller,
9135  A11y,
9136  History,
9137  HashNavigation,
9138  Autoplay,
9139  Thumb,
9140  freeMode,
9141  Grid,
9142  Manipulation,
9143  EffectFade,
9144  EffectCube,
9145  EffectFlip,
9146  EffectCoverflow,
9147  EffectCreative,
9148  EffectCards,
9149];
9150Swiper.use(modules);
9151
9152
9153
9154
9155/***/ })
9155
9156
9157/******/ 	});
9158/************************************************************************/
9159/******/ 	// The module cache
9160/******/ 	var __webpack_module_cache__ = {};
9161/******/ 	
9162/******/ 	// The require function
9163/******/ 	function __webpack_require__(moduleId) {
9164/******/ 		// Check if module is in cache
9165/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
9166/******/ 		if (cachedModule !== undefined) {
9167/******/ 			return cachedModule.exports;
9168/******/ 		}
9169/******/ 		// Create a new module (and put it into the cache)
9170/******/ 		var module = __webpack_module_cache__[moduleId] = {
9171/******/ 			// no module.id needed
9172/******/ 			// no module.loaded needed
9173/******/ 			exports: {}
9174/******/ 		};
9175/******/ 	
9176/******/ 		// Execute the module function
9177/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
9178/******/ 	
9179/******/ 		// Return the exports of the module
9180/******/ 		return module.exports;
9181/******/ 	}
9182/******/ 	
9183/************************************************************************/
9184/******/ 	/* webpack/runtime/define property getters */
9185/******/ 	(() => {
9186/******/ 		// define getter functions for harmony exports
9187/******/ 		__webpack_require__.d = (exports, definition) => {
9188/******/ 			for(var key in definition) {
9189/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
9190/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
9191/******/ 				}
9192/******/ 			}
9193/******/ 		};
9194/******/ 	})();
9195/******/ 	
9196/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
9197/******/ 	(() => {
9198/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
9199/******/ 	})();
9200/******/ 	
9201/******/ 	/* webpack/runtime/make namespace object */
9202/******/ 	(() => {
9203/******/ 		// define __esModule on exports
9204/******/ 		__webpack_require__.r = (exports) => {
9205/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
9206/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
9207/******/ 			}
9208/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
9209/******/ 		};
9210/******/ 	})();
9211/******/ 	
9212/************************************************************************/
9213var __webpack_exports__ = {};
9214// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
9215(() => {
9216/*!**************************************!*\
9217  !*** ./src/views/pages/home/home.js ***!
9218  \**************************************/
9219__webpack_require__.r(__webpack_exports__);
9220/* harmony import */ var _scripts_swiper_9_4_1_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @scripts/swiper-9.4.1.js */ "./src/assets/scripts/swiper-9.4.1.js");
9221
9222const tabpanelIds = ["#latest-news", "#video-zone", "#related-news"];
9223tabpanelIds.forEach((tabpanelId) => {
9224    const swiper = new _scripts_swiper_9_4_1_js__WEBPACK_IMPORTED_MODULE_0__["default"](`${tabpanelId} .swiper`, {
9225        slidesPerView: "auto",
9226        pagination: {
9227            el: '.swiper-pagination',
9228            type: 'fraction',
9229        },
9230        navigation: {
9231            nextEl: tabpanelId + " .swiper-btn-next",
9232            prevEl: tabpanelId + " .swiper-btn-prev",
9233        },
9234    });
9235    swiper.allowTouchMove = false;
9236});
9237const ourStorySwiper = new _scripts_swiper_9_4_1_js__WEBPACK_IMPORTED_MODULE_0__["default"](".section-body-one .swiper.swiper-nm", {
9238    // effect: "fade",
9239    pagination: {
9240        el: '.section-body-one .swiper-pagination',
9241        type: 'fraction',
9242    },
9243    navigation: {
9244        nextEl: ".section-body-one .swiper-btn-next",
9245        prevEl: ".section-body-one .swiper-btn-prev",
9246    },
9247});
9248ourStorySwiper.allowTouchMove = false;
9249
9250const ourStorySmSwiper = new _scripts_swiper_9_4_1_js__WEBPACK_IMPORTED_MODULE_0__["default"](".section-body-two .swiper.swiper-sm", {
9251    effect: "fade",
9252    pagination: {
9253        el: '.section-body-two .swiper-pagination',
9254        type: 'fraction',
9255    },
9256    navigation: {
9257        nextEl: ".section-body-two .swiper-btn-next",
9258        prevEl: ".section-body-two .swiper-btn-prev",
9259    },
9260});
9261ourStorySmSwiper.allowTouchMove = false;
9262})();
9263
9264/******/ })()
9265;
9266//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2hvbWUuMS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLFVBQVU7QUFDVix1QkFBdUI7QUFDdkIsMEJBQTBCO0FBQzFCO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEd
9266BQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2YsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxxQkFBcUI7QUFDckIsa0JBQWtCO0FBQ2xCLFdBQVc7QUFDWCxhQUFhO0FBQ2IsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsdUJBQXVCO0FBQ3ZCLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSCxZQUFZO0FBQ1osV0FBVztBQUNYLFlBQVk7QUFDWixpQkFBaUI7QUFDakIsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiw2QkFBNkI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEVBQTBFLGFBQWE7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkUsZUFBZTtBQUMxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLHFFQUFxRTtBQUMvRTtBQUNBO0FBQ0EsK0NBQStDLHlCQUF5QjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGtCQUFrQixrQkFBa0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEVBQTBFO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtB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tBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQix1QkFBdUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVS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FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLDJCQUEyQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNGQUFzRixzQkFBc0I7QUFDNUc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLDhDQUE4QztBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLDBEQUEwRDtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLHVCQUF1QjtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QU
9266FDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLGFBQWE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsMkNBQTJDO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsbUNBQW1DO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsZ0NBQWdDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsU0FBUztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUscUNBQXFDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQiw4QkFBOEIsVUFBVSw4QkFBOEI7QUFDakc7QUFDQSxJQUFJO0FBQ0osd0JBQXdCLDhCQUE4QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw4QkFBOEI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxrQkFBa0IsbUJBQW1CO0FBQ3JDLFlBQVksZUFBZTtBQUMzQjtBQUNBLDJDQUEyQyxNQUFNO0FBQ2pEO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLHNDQUFzQztBQUNoRDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLGlCQUFpQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSw4QkFBOEI7QUFDeEMsVUFBVSxxQkFBcUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QU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FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxnQ0FBZ0M7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEd
9266BQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsUUFBUSxpQ0FBaUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSw4REFBOEQ7QUFDMUUsWUFBWSxrQ0FBa0M7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsa0RBQWtEO0FBQzNGLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsU0FBUztBQUN0QztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0F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BQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsaUNBQWlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLDJDQUEyQztBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLF
9266dBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxNQUFNLGFBQWE7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCxnQkFBZ0I7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxpQ0FBaUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxpQkFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLFVBQVUsaUJBQWlCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxVQUFVLGlCQUFpQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0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O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEd
9266BQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLFFBQVEsMkJBQTJCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHVCQUF1QjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE1BQU07QUFDTixpREFBaUQ7QUFDakQ7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixzQkFBc0I7QUFDNUMsNEVBQTRFLHFCQUFxQjtBQUNqRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLHNCQUFzQixzQkFBc0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4RUFBOEUsaUJBQWlCO0FBQy9GO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFNBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxRQUFRLG1DQUFtQztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlDQUFpQztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxVQUFVLGFBQWE7QUFDdkI7QUFDQSxZQUFZLHdFQUF3RTtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUN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93ZWJwYWNrLWh0bWwtc2Nzcy1ib2lsZXJwbGF0ZS8uL3NyYy9hc3NldHMvc2NyaXB0cy9zd2lwZXItOS40LjEuanMiLCJ3ZWJwYWNrOi8vd2VicGFjay1odG1sLXNjc3MtYm9pbGVycGxhdGUvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vd2VicGFjay1odG1sLXNjc3MtYm9pbGVycGxhdGUvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL3dlYnBhY2staHRtbC1zY3NzLWJvaWxlcnBsYXRlL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vd2VicGFjay1odG1sLXNjc3MtYm9pbGVycGxhdGUvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly93ZWJwYWNrLWh0bWwtc2Nzcy1ib2lsZXJwbGF0ZS8uL3NyYy92aWV3cy9wYWdlcy9ob21lL2hvbWUuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIFN3aXBlciA5LjQuMVxyXG4gKiBNb3N0IG1vZGVybiBtb2JpbGUgdG91Y2ggc2xpZGVyIGFuZCBmcmFtZXdvcmsgd2l0aCBoYXJkd2FyZSBhY2NlbGVyYXRlZCB0cmFuc2l0aW9uc1xyXG4gKiBodHRwczovL3N3aXBlcmpzLmNvbVxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgMjAxNC0yMDIzIFZsYWRpbWlyIEtoYXJsYW1waWRpXHJcbiAqXHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZVxyXG4gKlxyXG4gKiBSZWxlYXNlZCBvbjogSnVuZSAxMywgMjAyM1xyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBTU1IgV2luZG93IDQuMC4yXHJcbiAqIEJldHRlciBoYW5kbGluZyBmb3Igd2luZG93IG9iamVjdCBpbiBTU1IgZW52aXJvbm1lbnRcclxuICogaHR0cHM6Ly9naXRodWIuY29tL25vbGltaXRzNHdlYi9zc3Itd2luZG93XHJcbiAqXHJcbiAqIENvcHlyaWdodCAyMDIxLCBWbGFkaW1pciBLaGFybGFtcGlkaVxyXG4gKlxyXG4gKiBMaWNlbnNlZCB1bmRlciBNSVRcclxuICpcclxuICogUmVsZWFzZWQgb246IERlY2VtYmVyIDEzLCAyMDIxXHJcbiAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wYXJhbS1yZWFzc2lnbiAqL1xyXG5mdW5jdGlvbiBpc09iamVjdCQxKG9iaikge1xyXG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvYmogJiYgb2JqLmNvbnN0cnVjdG9yID09PSBPYmplY3Q7XHJcbn1cclxuZnVuY3Rpb24gZXh0ZW5kJDEodGFyZ2V0LCBzcmMpIHtcclxuICBpZiAodGFyZ2V0ID09PSB2b2lkIDApIHtcclxuICAgIHRhcmdldCA9IHt9O1xyXG4gIH1cclxuICBpZiAoc3JjID09PSB2b2lkIDApIHtcclxuICAgIHNyYyA9IHt9O1xyXG4gIH1cclxuICBPYmplY3Qua2V5cyhzcmMpLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgaWYgKHR5cGVvZiB0YXJnZXRba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHRhcmdldFtrZXldID0gc3JjW2tleV07XHJcbiAgICBlbHNlIGlmIChpc09iamVjdCQxKHNyY1trZXldKSAmJiBpc09iamVjdCQxKHRhcmdldFtrZXldKSAmJiBPYmplY3Qua2V5cyhzcmNba2V5XSkubGVuZ3RoID4gMCkge1xyXG4gICAgICBleHRlbmQkMSh0YXJnZXRba2V5XSwgc3JjW2tleV0pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcbmNvbnN0IHNzckRvY3VtZW50ID0ge1xyXG4gIGJvZHk6IHt9LFxyXG4gIGFkZEV2ZW50TGlzdGVuZXIoKSB7fSxcclxuICByZW1vdmVFdmVudExpc3RlbmVyKCkge30sXHJcbiAgYWN0aXZlRWxlbWVudDoge1xyXG4gICAgYmx1cigpIHt9LFxyXG4gICAgbm9kZU5hbWU6ICcnLFxyXG4gIH0sXHJcbiAgcXVlcnlTZWxlY3RvcigpIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH0sXHJcbiAgcXVlcnlTZWxlY3RvckFsbCgpIHtcclxuICAgIHJldHVybiBbXTtcclxuICB9LFxyXG4gIGdldEVsZW1lbnRCeUlkKCkge1xyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfSxcclxuICBjcmVhdGVFdmVudCgpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGluaXRFdmVudCgpIHt9LFxyXG4gICAgfTtcclxuICB9LFxyXG4gIGNyZWF0ZUVsZW1lbnQoKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBjaGlsZHJlbjogW10sXHJcbiAgICAgIGNoaWxkTm9kZXM6IFtdLFxyXG4gICAgICBzdHlsZToge30sXHJcbiAgICAgIHNldEF0dHJpYnV0ZSgpIHt9LFxyXG4gICAgICBnZXRFbGVtZW50c0J5VGFnTmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG4gIH0sXHJcbiAgY3JlYXRlRWxlbWVudE5TKCkge1xyXG4gICAgcmV0dXJuIHt9O1xyXG4gIH0sXHJcbiAgaW1wb3J0Tm9kZSgpIHtcclxuICAgIHJldHVybi
9266BudWxsO1xyXG4gIH0sXHJcbiAgbG9jYXRpb246IHtcclxuICAgIGhhc2g6ICcnLFxyXG4gICAgaG9zdDogJycsXHJcbiAgICBob3N0bmFtZTogJycsXHJcbiAgICBocmVmOiAnJyxcclxuICAgIG9yaWdpbjogJycsXHJcbiAgICBwYXRobmFtZTogJycsXHJcbiAgICBwcm90b2NvbDogJycsXHJcbiAgICBzZWFyY2g6ICcnLFxyXG4gIH0sXHJcbn07XHJcbmZ1bmN0aW9uIGdldERvY3VtZW50KCkge1xyXG4gIGNvbnN0IGRvYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IHt9O1xyXG4gIGV4dGVuZCQxKGRvYywgc3NyRG9jdW1lbnQpO1xyXG4gIHJldHVybiBkb2M7XHJcbn1cclxuY29uc3Qgc3NyV2luZG93ID0ge1xyXG4gIGRvY3VtZW50OiBzc3JEb2N1bWVudCxcclxuICBuYXZpZ2F0b3I6IHtcclxuICAgIHVzZXJBZ2VudDogJycsXHJcbiAgfSxcclxuICBsb2NhdGlvbjoge1xyXG4gICAgaGFzaDogJycsXHJcbiAgICBob3N0OiAnJyxcclxuICAgIGhvc3RuYW1lOiAnJyxcclxuICAgIGhyZWY6ICcnLFxyXG4gICAgb3JpZ2luOiAnJyxcclxuICAgIHBhdGhuYW1lOiAnJyxcclxuICAgIHByb3RvY29sOiAnJyxcclxuICAgIHNlYXJjaDogJycsXHJcbiAgfSxcclxuICBoaXN0b3J5OiB7XHJcbiAgICByZXBsYWNlU3RhdGUoKSB7fSxcclxuICAgIHB1c2hTdGF0ZSgpIHt9LFxyXG4gICAgZ28oKSB7fSxcclxuICAgIGJhY2soKSB7fSxcclxuICB9LFxyXG4gIEN1c3RvbUV2ZW50OiBmdW5jdGlvbiBDdXN0b21FdmVudCgpIHtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH0sXHJcbiAgYWRkRXZlbnRMaXN0ZW5lcigpIHt9LFxyXG4gIHJlbW92ZUV2ZW50TGlzdGVuZXIoKSB7fSxcclxuICBnZXRDb21wdXRlZFN0eWxlKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZ2V0UHJvcGVydHlWYWx1ZSgpIHtcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG4gIH0sXHJcbiAgSW1hZ2UoKSB7fSxcclxuICBEYXRlKCkge30sXHJcbiAgc2NyZWVuOiB7fSxcclxuICBzZXRUaW1lb3V0KCkge30sXHJcbiAgY2xlYXJUaW1lb3V0KCkge30sXHJcbiAgbWF0Y2hNZWRpYSgpIHtcclxuICAgIHJldHVybiB7fTtcclxuICB9LFxyXG4gIHJlcXVlc3RBbmltYXRpb25GcmFtZShjYWxsYmFjaykge1xyXG4gICAgaWYgKHR5cGVvZiBzZXRUaW
92661lb3V0ID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBjYWxsYmFjaygpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBzZXRUaW1lb3V0KGNhbGxiYWNrLCAwKTtcclxuICB9LFxyXG4gIGNhbmNlbEFuaW1hdGlvbkZyYW1lKGlkKSB7XHJcbiAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNsZWFyVGltZW91dChpZCk7XHJcbiAgfSxcclxufTtcclxuZnVuY3Rpb24gZ2V0V2luZG93KCkge1xyXG4gIGNvbnN0IHdpbiA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDoge307XHJcbiAgZXh0ZW5kJDEod2luLCBzc3JXaW5kb3cpO1xyXG4gIHJldHVybiB3aW47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRlbGV0ZVByb3BzKG9iaikge1xyXG4gIGNvbnN0IG9iamVjdCA9IG9iajtcclxuICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgb2JqZWN0W2tleV0gPSBudWxsO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAvLyBubyBnZXR0ZXIgZm9yIG9iamVjdFxyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgZGVsZXRlIG9iamVjdFtrZXldO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAvLyBzb21ldGhpbmcgZ290IHdyb25nXHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuZnVuY3Rpb24gbmV4dFRpY2soY2FsbGJhY2ssIGRlbGF5KSB7XHJcbiAgaWYgKGRlbGF5ID09PSB2b2lkIDApIHtcclxuICAgIGRlbGF5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIHNldFRpbWVvdXQoY2FsbGJhY2ssIGRlbGF5KTtcclxufVxyXG5mdW5jdGlvbiBub3coKSB7XHJcbiAgcmV0dXJuIERhdGUubm93KCk7XHJcbn1cclxuZnVuY3Rpb24gZ2V0Q29tcHV0ZWRTdHlsZSQxKGVsKSB7XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgbGV0IHN0eWxlO1xyXG4gIGlmICh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSkge1xyXG4gICAgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgbnVsbCk7XHJcbiAgfVxyXG4gIGlmICghc3R5bGUgJiYgZWwuY3VycmVudFN0eWxlKSB7XHJcbiAgICBzdHlsZSA9IGVsLmN1cnJlbnRTdHlsZTtcclxuICB9XHJcbiAgaWYgKCFzdHlsZSkge1xyXG4gICAgc3R5bGUgPSBlbC5zdHlsZTtcclxuICB9XHJcbiAgcmV0dXJuIHN0eWxlO1xyXG59XHJcbmZ1bmN0aW9uIGdldFRyYW5zbGF0ZShlbCwgYXhpcykge1xyXG4gIGlmIChheGlzID09PSB2b2lkIDApIHtcclxuICAgIGF4aXMgPSAneCc7XHJcbiAgfVxyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGxldCBtYXRyaXg7XHJcbiAgbGV0IGN1clRyYW5zZm9ybTtcclxuICBsZXQgdHJhbnNmb3JtTWF0cml4O1xyXG4gIGNvbnN0IGN1clN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSQxKGVsKTtcclxuICBpZiAod2luZG93LldlYktpdENTU01hdHJpeCkge1xyXG4gICAgY3VyVHJhbnNmb3JtID0gY3VyU3R5bGUudHJhbnNmb3JtIHx8IGN1clN0eWxlLndlYmtpdFRyYW5zZm9ybTtcclxuICAgIGlmIChjdXJUcmFuc2Zvcm0uc3BsaXQoJywnKS5sZW5ndGggPiA2KSB7XHJcbiAgICAgIGN1clRyYW5zZm9ybSA9IGN1clRyYW5zZm9ybVxyXG4gICAgICAgIC5zcGxpdCgnLCAnKVxyXG4gICAgICAgIC5tYXAoKGEpID0+IGEucmVwbGFjZSgnLCcsICcuJykpXHJcbiAgICAgICAgLmpvaW4oJywgJyk7XHJcbiAgICB9XHJcbiAgICAvLyBTb21lIG9sZCB2ZXJzaW9ucyBvZiBXZWJraXQgY2hva2Ugd2hlbiAnbm9uZScgaXMgcGFzc2VkOyBwYXNzXHJcbiAgICAvLyBlbXB0eSBzdHJpbmcgaW5zdGVhZCBpbiB0aGlzIGNhc2VcclxuICAgIHRyYW5zZm9ybU1hdHJpeCA9IG5ldyB3aW5kb3cuV2ViS2l0Q1NTTWF0cml4KGN1clRyYW5zZm9ybSA9PT0gJ25vbmUnID8gJycgOiBjdXJUcmFuc2Zvcm0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICB0cmFuc2Zvcm1NYXRyaXggPVxyXG4gICAgICBjdXJTdHlsZS5Nb3pUcmFuc2Zvcm0gfHxcclxuICAgICAgY3VyU3R5bGUuT1RyYW5zZm9ybSB8fFxyXG4gICAgICBjdXJTdHlsZS5Nc1RyYW5zZm9ybSB8fFxyXG4gICAgICBjdXJTdHlsZS5tc1RyYW5zZm9ybSB8fFxyXG4gICAgICBjdXJTdHlsZS50cmFuc2Zvcm0gfHxcclxuICAgICAgY3VyU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgndHJhbnNmb3JtJykucmVwbGFjZSgndHJhbnNsYXRlKCcsICdtYXRyaXgoMSwgMCwgMCwgMSwnKTtcclxuICAgIG1hdHJpeCA9IHRyYW5zZm9ybU1hdHJpeC50b1N0cmluZygpLnNwbGl0KCcsJyk7XHJcbiAgfVxyXG4gIGlmIChheGlzID09PSAneCcpIHtcclxuICAgIC8vIExhdGVzdCBDaHJvbWUgYW5kIHdlYmtpdHMgRml4XHJcbiAgICBpZiAod2luZG93LldlYktpdENTU01hdHJpeCkgY3VyVHJhbnNmb3JtID0gdHJhbnNmb3JtTWF0cml4Lm00MTtcclxuICAgIC8vIENyYXp5IElFMTAgTWF0cml4XHJcbiAgICBlbHNlIGlmIChtYXRyaXgubGVuZ3RoID09PSAxNikgY3VyVHJhbnNmb3JtID0gcGFyc2VGbG9hdChtYXRyaXhbMTJdKTtcclxuICAgIC8vIE5vcm1hbCBCcm93c2Vyc1xyXG4gICAgZWxzZSBjdXJUcmFuc2Zvcm0gPSBwYXJzZUZsb2F0KG1hdHJpeFs0XSk7XHJcbiAgfVxyXG4gIGlmIChheGlzID09PSAneScpIHtcclxuICAgIC8vIExhdGVzdCBDaHJvbWUgYW5kIHdlYmtpdHMgRml4XHJcbiAgICBpZiAod2luZG93LldlYktpdENTU01hdHJpeCkgY3VyVHJhbnNmb3JtID0gdHJhbnNmb3JtTWF0cml4Lm00MjtcclxuICAgIC8vIENyYXp5IElFMTAgTWF0cml4XHJcbiAgICBlbHNlIGlmIChtYXRyaXgubGVuZ3RoID09PSAxNikgY3VyVHJhbnNmb3JtID0gcGFyc2VGbG9hdChtYXRyaXhbMTNdKTtcclxuICAgIC8vIE5vcm1hbCBCcm93c2Vyc1xyXG4gICAgZWxzZSBjdXJUcmFuc2Zvcm0gPSBwYXJzZUZsb2F0KG1hdHJpeFs1XSk7XHJcbiAgfVxyXG4gIHJldHVybiBjdXJUcmFuc2Zvcm0gfHwgMDtcclxufVxyXG5mdW5jdGlvbiBpc09iamVjdChvKSB7XHJcbiAgcmV0dXJuIChcclxuICAgIHR5cGVvZiBvID09PSAnb2JqZWN0JyAmJiBvICE9PSBudWxsICYmIG8uY29uc3RydWN0b3IgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKSA9PT0gJ09iamVjdCdcclxuICApO
92661xyXG59XHJcbmZ1bmN0aW9uIGlzTm9kZShub2RlKSB7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50O1xyXG4gIH1cclxuICByZXR1cm4gbm9kZSAmJiAobm9kZS5ub2RlVHlwZSA9PT0gMSB8fCBub2RlLm5vZGVUeXBlID09PSAxMSk7XHJcbn1cclxuZnVuY3Rpb24gZXh0ZW5kKCkge1xyXG4gIGNvbnN0IHRvID0gT2JqZWN0KGFyZ3VtZW50cy5sZW5ndGggPD0gMCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1swXSk7XHJcbiAgY29uc3Qgbm9FeHRlbmQgPSBbJ19fcHJvdG9fXycsICdjb25zdHJ1Y3RvcicsICdwcm90b3R5cGUnXTtcclxuICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgY29uc3QgbmV4dFNvdXJjZSA9IGkgPCAwIHx8IGFyZ3VtZW50cy5sZW5ndGggPD0gaSA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1tpXTtcclxuICAgIGlmIChuZXh0U291cmNlICE9PSB1bmRlZmluZWQgJiYgbmV4dFNvdXJjZSAhPT0gbnVsbCAmJiAhaXNOb2RlKG5leHRTb3VyY2UpKSB7XHJcbiAgICAgIGNvbnN0IGtleXNBcnJheSA9IE9iamVjdC5rZXlzKE9iamVjdChuZXh0U291cmNlKSkuZmlsdGVyKChrZXkpID0+IG5vRXh0ZW5kLmluZGV4T2Yoa2V5KSA8IDApO1xyXG4gICAgICBmb3IgKGxldCBuZXh0SW5kZXggPSAwLCBsZW4gPSBrZXlzQXJyYXkubGVuZ3RoOyBuZXh0SW5kZXggPCBsZW47IG5leHRJbmRleCArPSAxKSB7XHJcbiAgICAgICAgY29uc3QgbmV4dEtleSA9IGtleXNBcnJheVtuZXh0SW5kZXhdO1xyXG4gICAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG5leHRTb3VyY2UsIG5leHRLZXkpO1xyXG4gICAgICAgIGlmIChkZXNjICE9PSB1bmRlZmluZWQgJiYgZGVzYy5lbnVtZXJhYmxlKSB7XHJcbiAgICAgICAgICBpZiAoaXNPYmplY3QodG9bbmV4dEtleV0pICYmIGlzT2JqZWN0KG5leHRTb3VyY2VbbmV4dEtleV0pKSB7XHJcbiAgICAgICAgICAgIGlmIChuZXh0U291cmNlW25leHRLZXldLl9fc3dpcGVyX18pIHtcclxuICAgICAgICAgICAgICB0b1tuZXh0S2V5XSA9IG5leHRTb3VyY2VbbmV4dEtleV07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgZXh0ZW5kKHRvW25leHRLZXldLCBuZXh0U291cmNlW25leHRLZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIGlmICghaXNPYmplY3QodG9bbmV4dEtleV0pICYmIGlzT2JqZWN0KG5leHRTb3VyY2VbbmV4dEtleV0pKSB7XHJcbiAgICAgICAgICAgIHRvW25leHRLZXldID0ge307XHJcbiAgICAgICAgICAgIGlmIChuZXh0U291cmNlW25leHRLZXldLl9fc3dpcGVyX18pIHtcclxuICAgICAgICAgICAgICB0b1tuZXh0S2V5XSA9IG5leHRTb3VyY2VbbmV4dEtleV07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgZXh0ZW5kKHRvW25leHRLZXldLCBuZXh0U291cmNlW25leHRLZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdG9bbmV4dEtleV0gPSBuZXh0U291cmNlW25leHRLZXldO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gdG87XHJcbn1cclxuZnVuY3Rpb24gc2V0Q1NTUHJvcGVydHkoZWwsIHZhck5hbWUsIHZhclZhbHVlKSB7XHJcbiAgZWwuc3R5bGUuc2V0UHJvcGVydHkodmFyTmFtZSwgdmFyVmFsdWUpO1xyXG59XHJcbmZ1bmN0aW9uIGFuaW1hdGVDU1NNb2RlU2Nyb2xsKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIHRhcmdldFBvc2l0aW9uLCBzaWRlIH0gPSBfcmVmO1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGNvbnN0IHN0YXJ0UG9zaXRpb24gPSAtc3dpcGVyLnRyYW5zbGF0ZTtcclxuICBsZXQgc3RhcnRUaW1lID0gbnVsbDtcclxuICBsZXQgdGltZTtcclxuICBjb25zdCBkdXJhdGlvbiA9IHN3aXBlci5wYXJhbXMuc3BlZWQ7XHJcbiAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS5zY3JvbGxTbmFwVHlwZSA9ICdub25lJztcclxuICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoc3dpcGVyLmNzc01vZGVGcmFtZUlEKTtcclxuICBjb25zdCBkaXIgPSB0YXJnZXRQb3NpdGlvbiA+IHN0YXJ0UG9zaXRpb24gPyAnbmV4dCcgOiAncHJldic7XHJcbiAgY29uc3QgaXNPdXRPZkJvdW5kID0gKGN1cnJlbnQsIHRhcmdldCkgPT4ge1xyXG4gICAgcmV0dXJuIChkaXIgPT09ICduZXh0JyAmJiBjdXJyZW50ID49IHRhcmdldCkgfHwgKGRpciA9PT0gJ3ByZXYnICYmIGN1cnJlbnQgPD0gdGFyZ2V0KTtcclxuICB9O1xyXG4gIGNvbnN0IGFuaW1hdGUgPSAoKSA9PiB7XHJcbiAgICB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICBpZiAoc3RhcnRUaW1lID09PSBudWxsKSB7XHJcbiAgICAgIHN0YXJ0VGltZSA9IHRpbWU7XHJcbiAgICB9XHJcbiAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWF4KE1hdGgubWluKCh0aW1lIC0gc3RhcnRUaW1lKSAvIGR1cmF0aW9uLCAxKSwgMCk7XHJcbiAgICBjb25zdCBlYXNlUHJvZ3Jlc3MgPSAwLjUgLSBNYXRoLmNvcyhwcm9ncmVzcyAqIE1hdGguUEkpIC8gMjtcclxuICAgIGxldCBjdXJyZW50UG9zaXRpb24gPSBzdGFydFBvc2l0aW9uICsgZWFzZVByb2dyZXNzICogKHRhcmdldFBvc2l0aW9uIC0gc3RhcnRQb3NpdGlvbik7XHJcbiAgICBpZiAoaXNPdXRPZkJvdW5kKGN1cnJlbnRQb3NpdGlvbiwgdGFyZ2V0UG9zaXRpb24pKSB7XHJcbiAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IHRhcmdldFBvc2l0aW9uO1xyXG4gICAgfVxyXG4gICAgc3dpcGVyLndyYXBwZXJFbC5zY3JvbGxUbyh7XHJcbiAgICAgIFtzaWRlXTogY3VycmVudFBvc2l0aW9uLFxyXG4gICAgfSk7XHJcbiAgICBpZiAoaXNPdXRPZkJvdW5kKGN1cnJlbnRQb3NpdGlvbiwgdGFyZ2V0UG9zaXRpb24pKSB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcclxuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS5zY3JvbGxTbmFwVHlwZSA9ICcnO1xyXG4gICAgICBzZXRUaW
92661lb3V0KCgpID0+IHtcclxuICAgICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLm92ZXJmbG93ID0gJyc7XHJcbiAgICAgICAgc3dpcGVyLndyYXBwZXJFbC5zY3JvbGxUbyh7XHJcbiAgICAgICAgICBbc2lkZV06IGN1cnJlbnRQb3NpdGlvbixcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShzd2lwZXIuY3NzTW9kZUZyYW1lSUQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuY3NzTW9kZUZyYW1lSUQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGFuaW1hdGUpO1xyXG4gIH07XHJcbiAgYW5pbWF0ZSgpO1xyXG59XHJcbmZ1bmN0aW9uIGdldFNsaWRlVHJhbnNmb3JtRWwoc2xpZGVFbCkge1xyXG4gIHJldHVybiAoXHJcbiAgICBzbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoJy5zd2lwZXItc2xpZGUtdHJhbnNmb3JtJykgfHxcclxuICAgIChzbGlkZUVsLnNoYWRvd0VsICYmIHNsaWRlRWwuc2hhZG93RWwucXVlcnlTZWxlY3RvcignLnN3aXBlci1zbGlkZS10cmFuc2Zvcm0nKSkgfHxcclxuICAgIHNsaWRlRWxcclxuICApO1xyXG59XHJcbmZ1bmN0aW9uIGVsZW1lbnRDaGlsZHJlbihlbGVtZW50LCBzZWxlY3Rvcikge1xyXG4gIGlmIChzZWxlY3RvciA9PT0gdm9pZCAwKSB7XHJcbiAgICBzZWxlY3RvciA9ICcnO1xyXG4gIH1cclxuICByZXR1cm4gWy4uLmVsZW1lbnQuY2hpbGRyZW5dLmZpbHRlcigoZWwpID0+IGVsLm1hdGNoZXMoc2VsZWN0b3IpKTtcclxufVxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHRhZywgY2xhc3Nlcykge1xyXG4gIGlmIChjbGFzc2VzID09PSB2b2lkIDApIHtcclxuICAgIGNsYXNzZXMgPSBbXTtcclxuICB9XHJcbiAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7XHJcbiAgZWwuY2xhc3NMaXN0LmFkZCguLi4oQXJyYXkuaXNBcnJheShjbGFzc2VzKSA/IGNsYXNzZXMgOiBbY2xhc3Nlc10pKTtcclxuICByZXR1cm4gZWw7XHJcbn1cclxuZnVuY3Rpb24gZWxlbWVudE9mZnNldChlbCkge1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICBjb25zdCBib3ggPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICBjb25zdCBib2R5ID0gZG9jdW1lbnQuYm9keTtcclxuICBjb25zdCBjbGllbnRUb3AgPSBlbC5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMDtcclxuICBjb25zdCBjbGllbnRMZWZ0ID0gZWwuY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMDtcclxuICBjb25zdCBzY3JvbGxUb3AgPSBlbCA9PT0gd2luZG93ID8gd2luZG93LnNjcm9sbFkgOiBlbC5zY3JvbGxUb3A7XHJcbiAgY29uc3Qgc2Nyb2xsTGVmdCA9IGVsID09PSB3aW5kb3cgPyB3aW5kb3cuc2Nyb2xsWCA6IGVsLnNjcm9sbExlZnQ7XHJcbiAgcmV0dXJuIHtcclxuICAgIHRvcDogYm94LnRvcCArIHNjcm9sbFRvcCAtIGNsaWVudFRvcCxcclxuICAgIGxlZnQ6IGJveC5sZWZ0ICsgc2Nyb2xsTGVmdCAtIGNsaWVudExlZnQsXHJcbiAgfTtcclxufVxyXG5mdW5jdGlvbiBlbGVtZW50UHJldkFsbChlbCwgc2VsZWN0b3IpIHtcclxuICBjb25zdCBwcmV2RWxzID0gW107XHJcbiAgd2hpbGUgKGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpIHtcclxuICAgIGNvbnN0IHByZXYgPSBlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcbiAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgaWYgKHByZXYubWF0Y2hlcyhzZWxlY3RvcikpIHByZXZFbHMucHVzaChwcmV2KTtcclxuICAgIH0gZWxzZSBwcmV2RWxzLnB1c2gocHJldik7XHJcbiAgICBlbCA9IHByZXY7XHJcbiAgfVxyXG4gIHJldHVybiBwcmV2RWxzO1xyXG59XHJcbmZ1bmN0aW9uIGVsZW1lbnROZXh0QWxsKGVsLCBzZWxlY3Rvcikge1xyXG4gIGNvbnN0IG5leHRFbHMgPSBbXTtcclxuICB3aGlsZSAoZWwubmV4dEVsZW1lbnRTaWJsaW5nKSB7XHJcbiAgICBjb25zdCBuZXh0ID0gZWwubmV4dEVsZW1lbnRTaWJsaW5nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcbiAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgaWYgKG5leHQubWF0Y2hlcyhzZWxlY3RvcikpIG5leHRFbHMucHVzaChuZXh0KTtcclxuICAgIH0gZWxzZSBuZXh0RWxzLnB1c2gobmV4dCk7XHJcbiAgICBlbCA9IG5leHQ7XHJcbiAgfVxyXG4gIHJldHVybiBuZXh0RWxzO1xyXG59XHJcbmZ1bmN0aW9uIGVsZW1lbnRTdHlsZShlbCwgcHJvcCkge1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wKTtcclxufVxyXG5mdW5jdGlvbiBlbGVtZW50SW5kZXgoZWwpIHtcclxuICBsZXQgY2hpbGQgPSBlbDtcclxuICBsZXQgaTtcclxuICBpZiAoY2hpbGQpIHtcclxuICAgIGkgPSAwO1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICB3aGlsZSAoKGNoaWxkID0gY2hpbGQucHJldmlvdXNTaWJsaW5nKSAhPT0gbnVsbCkge1xyXG4gICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEpIGkgKz0gMTtcclxuICAgIH1cclxuICAgIHJldHVybiBpO1xyXG4gIH1cclxuICByZXR1cm4gdW5kZWZpbmVkO1xyXG59XHJcbmZ1bmN0aW9uIGVsZW1lbnRQYXJlbnRzKGVsLCBzZWxlY3Rvcikge1xyXG4gIGNvbnN0IHBhcmVudHMgPSBbXTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxyXG4gIGxldCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcbiAgd2hpbGUgKHBhcmVudCkge1xyXG4gICAgaWYgKHNlbGVjdG9yKSB7XHJcbiAgICAgIGlmIChwYXJlbnQubWF0Y2hlcyhzZWxlY3RvcikpIHBhcmVudHMucHVzaChwYXJlbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcGFyZW50cy5wdXNoKHBhcmVudCk7XHJcbiAgICB9XHJcbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50RWxlbWVudDtcclxuICB9XHJcbiAgcmV0dXJuIHBhcmVudHM7XHJcbn1cclxuZnVuY3Rpb24gZWxlbWVudFRyYW5zaXRpb25FbmQoZWwsIGNhbGxiYWNrKSB7XHJcbiAgZnVuY3Rpb24gZmlyZUNhbGxCYWNrKGUpIHtcclxuICAgIGlmIChlLnRhcmdldCAhPT0gZWwpIHJldHVybjtcclxuICAgIGNhbGxiYWNrLmNhbGwoZWwsIGUpO1xyXG4gICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGZpcmVDYWxsQmFjayk7XHJcbiAgfVxyXG4gIGlmIChjYWxsYmFjaykge1xyXG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGZpcmVDYWxsQmFjayk7XHJcbiAgfVxyXG59XHJcbmZ1bmN0aW9uIGVsZW1lbnRPdXRlclNpemUoZWwsIHNpemUsIGluY2x1ZGVNYXJnaW5zKSB7XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgaWYgKGluY2x1ZGVNYXJnaW5zKSB7XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICBlbFtzaXplID09PSAnd2lkdGgnID8gJ29mZnNldFdpZHRoJyA6ICdvZmZzZXRIZWlnaHQnXSArXHJcbiAgICAgIHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpLmdldFByb3BlcnR5VmFsdWUoc2l6ZSA9PT0gJ3dpZHRoJyA/ICdtYXJnaW4tcmlnaHQnIDogJ21hcmdpbi10b3AnKSkgK1xyXG4gICAgICBwYXJzZU
9266Zsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsLCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKHNpemUgPT09ICd3aWR0aCcgPyAnbWFyZ2luLWxlZnQnIDogJ21hcmdpbi1ib3R0b20nKSlcclxuICAgICk7XHJcbiAgfVxyXG4gIHJldHVybiBlbC5vZmZzZXRXaWR0aDtcclxufVxyXG5cclxubGV0IHN1cHBvcnQ7XHJcbmZ1bmN0aW9uIGNhbGNTdXBwb3J0KCkge1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICByZXR1cm4ge1xyXG4gICAgc21vb3RoU2Nyb2xsOlxyXG4gICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlICYmICdzY3JvbGxCZWhhdmlvcicgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLFxyXG4gICAgdG91Y2g6ICEhKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCAod2luZG93LkRvY3VtZW50VG91Y2ggJiYgZG9jdW1lbnQgaW5zdGFuY2VvZiB3aW5kb3cuRG9jdW1lbnRUb3VjaCkpLFxyXG4gIH07XHJcbn1cclxuZnVuY3Rpb24gZ2V0U3VwcG9ydCgpIHtcclxuICBpZiAoIXN1cHBvcnQpIHtcclxuICAgIHN1cHBvcnQgPSBjYWxjU3VwcG9ydCgpO1xyXG4gIH1cclxuICByZXR1cm4gc3VwcG9ydDtcclxufVxyXG5cclxubGV0IGRldmljZUNhY2hlZDtcclxuZnVuY3Rpb24gY2FsY0RldmljZShfdGVtcCkge1xyXG4gIGxldCB7IHVzZXJBZ2VudCB9ID0gX3RlbXAgPT09IHZvaWQgMCA/IHt9IDogX3RlbXA7XHJcbiAgY29uc3Qgc3VwcG9ydCA9IGdldFN1cHBvcnQoKTtcclxuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcclxuICBjb25zdCBwbGF0Zm9ybSA9IHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm07XHJcbiAgY29uc3QgdWEgPSB1c2VyQWdlbnQgfHwgd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XHJcbiAgY29uc3QgZGV2aWNlID0ge1xyXG4gICAgaW9zOiBmYWxzZSxcclxuICAgIGFuZHJvaWQ6IGZhbHNlLFxyXG4gIH07XHJcbiAgY29uc3Qgc2NyZWVuV2lkdGggPSB3aW5kb3cuc2NyZWVuLndpZHRoO1xyXG4gIGNvbnN0IHNjcmVlbkhlaWdodCA9IHdpbmRvdy5zY3JlZW4uaGVpZ2h0O1xyXG4gIGNvbnN0IGFuZHJvaWQgPSB1YS5tYXRjaCgvKEFuZHJvaWQpOz9bXFxzXFwvXSsoW1xcZC5dKyk/Lyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcclxuICBsZXQgaXBhZCA9IHVhLm1hdGNoKC8oaVBhZCkuKk9TXFxzKFtcXGRfXSspLyk7XHJcbiAgY29uc3QgaXBvZCA9IHVhLm1hdGNoKC8oaVBvZCkoLipPU1xccyhbXFxkX10rKSk/Lyk7XHJcbiAgY29uc3QgaXBob25lID0gIWlwYWQgJiYgdWEubWF0Y2goLyhpUGhvbmVcXHNPU3xpT1MpXFxzKFtcXGRfXSspLyk7XHJcbiAgY29uc3Qgd2luZG93cyA9IHBsYXRmb3JtID09PSAnV2luMzInO1xyXG4gIGxldCBtYWNvcyA9IHBsYXRmb3JtID09PSAnTWFjSW50ZWwnO1xyXG5cclxuICAvLyBpUGFkT3MgMTMgZml4XHJcbiAgY29uc3QgaVBhZFNjcmVlbnMgPSBbXHJcbiAgICAnMTAyNHgxMzY2JyxcclxuICAgICcxMzY2eDEwMjQnLFxyXG4gICAgJzgzNHgxMTk0JyxcclxuICAgICcxMTk0eDgzNCcsXHJcbiAgICAnODM0eDExMTInLFxyXG4gICAgJzExMTJ4ODM0JyxcclxuICAgICc3Njh4MTAyNCcsXHJcbiAgICAnMTAyNHg3NjgnLFxyXG4gICAgJzgyMHgxMTgwJyxcclxuICAgICcxMTgweDgyMCcsXHJcbiAgICAnODEweDEwODAnLFxyXG4gICAgJzEwODB4ODEwJyxcclxuICBdO1xyXG4gIGlmICghaXBhZCAmJiBtYWNvcyAmJiBzdXBwb3J0LnRvdWNoICYmIGlQYWRTY3JlZW5zLmluZGV4T2YoYCR7c2NyZWVuV2lkdGh9eCR7c2NyZWVuSGVpZ2h0fWApID49IDApIHtcclxuICAgIGlwYWQgPSB1YS5tYXRjaCgvKFZlcnNpb24pXFwvKFtcXGQuXSspLyk7XHJcbiAgICBpZiAoIWlwYWQpIGlwYWQgPSBbMCwgMSwgJzEzXzBfMCddO1xyXG4gICAgbWFjb3MgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8vIEFuZHJvaWRcclxuICBpZiAoYW5kcm9pZCAmJiAhd2luZG93cykge1xyXG4gICAgZGV2aWNlLm9zID0gJ2FuZHJvaWQnO1xyXG4gICAgZGV2aWNlLmFuZHJvaWQgPSB0cnVlO1xyXG4gIH1cclxuICBpZiAoaXBhZCB8fCBpcGhvbmUgfHwgaXBvZCkge1xyXG4gICAgZGV2aWNlLm9zID0gJ2lvcyc7XHJcbiAgICBkZXZpY2UuaW9zID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8vIEV4cG9ydCBvYmplY3RcclxuICByZXR1cm4gZGV2aWNlO1xyXG59XHJcbmZ1bmN0aW9uIGdldERldmljZShvdmVycmlkZXMpIHtcclxuICBpZiAob3ZlcnJpZGVzID09PSB2b2lkIDApIHtcclxuICAgIG92ZXJyaWRlcyA9IHt9O1xyXG4gIH1cclxuICBpZiAoIWRldmljZUNhY2hlZCkge1xyXG4gICAgZGV2aWNlQ2FjaGVkID0gY2FsY0RldmljZShvdmVycmlkZXMpO1xyXG4gIH1cclxuICByZXR1cm4gZGV2aWNlQ2FjaGVkO1xyXG59XHJcblxyXG5sZXQgYnJvd3NlcjtcclxuZnVuY3Rpb24gY2FsY0Jyb3dzZXIoKSB7XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgbGV0IG5lZWRQZXJzcGVjdGl2ZUZpeCA9IGZhbHNlO1xyXG4gIGZ1bmN0aW9uIGlzU2FmYXJpKCkge1xyXG4gICAgY29uc3QgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xyXG4gICAgcmV0dXJuIHVhLmluZGV4T2YoJ3NhZmFyaScpID49IDAgJiYgdWEuaW5kZXhPZignY2hyb21lJykgPCAwICYmIHVhLmluZGV4T2YoJ2FuZHJvaWQnKSA8IDA7XHJcbiAgfVxyXG4gIGlmIChpc1NhZmFyaSgpKSB7XHJcbiAgICBjb25zdCB1YSA9IFN0cmluZyh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbiAgICBpZiAodWEuaW5jbHVkZXMoJ1ZlcnNpb24vJykpIHtcclxuICAgICAgY29uc3QgW21ham9yLCBtaW5vcl0gPSB1YVxyXG4gICAgICAgIC5zcGxpdCgnVmVyc2lvbi8nKVsxXVxyXG4gICAgICAgIC5zcGxpdCgnICcpWzBdXHJcbiAgICAgICAgLnNwbGl0KCcuJylcclxuICAgICAgICAubWFwKChudW0pID0+IE51bWJlcihudW0pKTtcclxuICAgICAgbmVlZFBlcnNwZWN0aXZlRml4ID0gbWFqb3IgPCAxNiB8fCAobWFqb3IgPT09IDE2ICYmIG1pbm9yIDwgMik7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybi
9266B7XHJcbiAgICBpc1NhZmFyaTogbmVlZFBlcnNwZWN0aXZlRml4IHx8IGlzU2FmYXJpKCksXHJcbiAgICBuZWVkUGVyc3BlY3RpdmVGaXgsXHJcbiAgICBpc1dlYlZpZXc6IC8oaVBob25lfGlQb2R8aVBhZCkuKkFwcGxlV2ViS2l0KD8hLipTYWZhcmkpL2kudGVzdCh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCksXHJcbiAgfTtcclxufVxyXG5mdW5jdGlvbiBnZXRCcm93c2VyKCkge1xyXG4gIGlmICghYnJvd3Nlcikge1xyXG4gICAgYnJvd3NlciA9IGNhbGNCcm93c2VyKCk7XHJcbiAgfVxyXG4gIHJldHVybiBicm93c2VyO1xyXG59XHJcblxyXG5mdW5jdGlvbiBSZXNpemUoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgb24sIGVtaXQgfSA9IF9yZWY7XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgbGV0IG9ic2VydmVyID0gbnVsbDtcclxuICBsZXQgYW5pbWF0aW9uRnJhbWUgPSBudWxsO1xyXG4gIGNvbnN0IHJlc2l6ZUhhbmRsZXIgPSAoKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkIHx8ICFzd2lwZXIuaW5pdGlhbGl6ZWQpIHJldHVybjtcclxuICAgIGVtaXQoJ2JlZm9yZVJlc2l6ZScpO1xyXG4gICAgZW1pdCgncmVzaXplJyk7XHJcbiAgfTtcclxuICBjb25zdCBjcmVhdGVPYnNlcnZlciA9ICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuO1xyXG4gICAgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKGVudHJpZXMpID0+IHtcclxuICAgICAgYW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IHN3aXBlcjtcclxuICAgICAgICBsZXQgbmV3V2lkdGggPSB3aWR0aDtcclxuICAgICAgICBsZXQgbmV3SGVpZ2h0ID0gaGVpZ2h0O1xyXG4gICAgICAgIGVudHJpZXMuZm9yRWFjaCgoX3JlZjIpID0+IHtcclxuICAgICAgICAgIGxldCB7IGNvbnRlbnRCb3hTaXplLCBjb250ZW50UmVjdCwgdGFyZ2V0IH0gPSBfcmVmMjtcclxuICAgICAgICAgIGlmICh0YXJnZXQgJiYgdGFyZ2V0ICE9PSBzd2lwZXIuZWwpIHJldHVybjtcclxuICAgICAgICAgIG5ld1dpZHRoID0gY29udGVudFJlY3QgPyBjb250ZW50UmVjdC53aWR0aCA6IChjb250ZW50Qm94U2l6ZVswXSB8fCBjb250ZW50Qm94U2l6ZSkuaW5saW5lU2l6ZTtcclxuICAgICAgICAgIG5ld0hlaWdodCA9IGNvbnRlbnRSZWN0ID8gY29udGVudFJlY3QuaGVpZ2h0IDogKGNvbnRlbnRCb3hTaXplWzBdIHx8IGNvbnRlbnRCb3hTaXplKS5ibG9ja1NpemU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKG5ld1dpZHRoICE9PSB3aWR0aCB8fCBuZXdIZWlnaHQgIT09IGhlaWdodCkge1xyXG4gICAgICAgICAgcmVzaXplSGFuZGxlcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIG9ic2VydmVyLm9ic2VydmUoc3dpcGVyLmVsKTtcclxuICB9O1xyXG4gIGNvbnN0IHJlbW92ZU9ic2VydmVyID0gKCkgPT4ge1xyXG4gICAgaWYgKGFuaW1hdGlvbkZyYW1lKSB7XHJcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShhbmltYXRpb25GcmFtZSk7XHJcbiAgICB9XHJcbiAgICBpZiAob2JzZXJ2ZXIgJiYgb2JzZXJ2ZXIudW5vYnNlcnZlICYmIHN3aXBlci5lbCkge1xyXG4gICAgICBvYnNlcnZlci51bm9ic2VydmUoc3dpcGVyLmVsKTtcclxuICAgICAgb2JzZXJ2ZXIgPSBudWxsO1xyXG4gICAgfVxyXG4gIH07XHJcbiAgY29uc3Qgb3JpZW50YXRpb25DaGFuZ2VIYW5kbGVyID0gKCkgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCB8fCAhc3dpcGVyLmluaXRpYWxpemVkKSByZXR1cm47XHJcbiAgICBlbWl0KCdvcmllbnRhdGlvbmNoYW5nZScpO1xyXG4gIH07XHJcbiAgb24oJ2luaXQnLCAoKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5yZXNpemVPYnNlcnZlciAmJiB0eXBlb2Ygd2luZG93LlJlc2l6ZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBjcmVhdGVPYnNlcnZlcigpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgcmVzaXplSGFuZGxlcik7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCBvcmllbnRhdGlvbkNoYW5nZUhhbmRsZXIpO1xyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgcmVtb3ZlT2JzZXJ2ZXIoKTtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCByZXNpemVIYW5kbGVyKTtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIG9yaWVudGF0aW9uQ2hhbmdlSGFuZGxlcik7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIE9ic2VydmVyKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24sIGVtaXQgfSA9IF9yZWY7XHJcbiAgY29uc3Qgb2JzZXJ2ZXJzID0gW107XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgY29uc3QgYXR0YWNoID0gZnVuY3Rpb24gKHRhcmdldCwgb3B0aW9ucykge1xyXG4gICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xyXG4gICAgICBvcHRpb25zID0ge307XHJcbiAgICB9XHJcbiAgICBjb25zdCBPYnNlcnZlckZ1bmMgPSB3aW5kb3cuTXV0YXRpb25PYnNlcnZlciB8fCB3aW5kb3cuV2Via2l0TXV0YXRpb25PYnNlcnZlcjtcclxuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE9ic2VydmVyRnVuYygobXV0YXRpb25zKSA9PiB7XHJcbiAgICAgIC8vIFRoZSBvYnNlcnZlclVwZGF0ZSBldmVudCBzaG91bGQgb25seSBiZSB0cmlnZ2VyZWRcclxuICAgICAgLy8gb25jZSBkZXNwaXRlIHRoZSBudW1iZXIgb2YgbXV0YXRpb25zLiAgQWRkaXRpb25hbFxyXG4gICAgICAvLyB0cmlnZ2VycyBhcmUgcmVkdW5kYW50IGFuZCBhcmUgdmVyeSBjb3N0bHlcclxuICAgICAgaWYgKHN3aXBlci5fX3ByZXZlbnRPYnNlcnZlcl9fKSByZXR1cm47XHJcbiAgICAgIGlmIChtdXRhdGlvbnMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgZW1pdCgnb2JzZXJ2ZXJVcGRhdGUnLCBtdXRhdGlvbnNbMF0pO1xyXG4gICAgICAgI
9266HJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBvYnNlcnZlclVwZGF0ZSA9IGZ1bmN0aW9uIG9ic2VydmVyVXBkYXRlKCkge1xyXG4gICAgICAgIGVtaXQoJ29ic2VydmVyVXBkYXRlJywgbXV0YXRpb25zWzBdKTtcclxuICAgICAgfTtcclxuICAgICAgaWYgKHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcclxuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKG9ic2VydmVyVXBkYXRlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB3aW5kb3cuc2V0VGltZW91dChvYnNlcnZlclVwZGF0ZSwgMCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0YXJnZXQsIHtcclxuICAgICAgYXR0cmlidXRlczogdHlwZW9mIG9wdGlvbnMuYXR0cmlidXRlcyA9PT0gJ3VuZGVmaW5lZCcgPyB0cnVlIDogb3B0aW9ucy5hdHRyaWJ1dGVzLFxyXG4gICAgICBjaGlsZExpc3Q6IHR5cGVvZiBvcHRpb25zLmNoaWxkTGlzdCA9PT0gJ3VuZGVmaW5lZCcgPyB0cnVlIDogb3B0aW9ucy5jaGlsZExpc3QsXHJcbiAgICAgIGNoYXJhY3RlckRhdGE6IHR5cGVvZiBvcHRpb25zLmNoYXJhY3RlckRhdGEgPT09ICd1bmRlZmluZWQnID8gdHJ1ZSA6IG9wdGlvbnMuY2hhcmFjdGVyRGF0YSxcclxuICAgIH0pO1xyXG4gICAgb2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xyXG4gIH07XHJcbiAgY29uc3QgaW5pdCA9ICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5vYnNlcnZlcikgcmV0dXJuO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMub2JzZXJ2ZVBhcmVudHMpIHtcclxuICAgICAgY29uc3QgY29udGFpbmVyUGFyZW50cyA9IGVsZW1lbnRQYXJlbnRzKHN3aXBlci5lbCk7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29udGFpbmVyUGFyZW50cy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICAgIGF0dGFjaChjb250YWluZXJQYXJlbnRzW2ldKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gT2JzZXJ2ZSBjb250YWluZXJcclxuICAgIGF0dGFjaChzd2lwZXIuZWwsIHtcclxuICAgICAgY2hpbGRMaXN0OiBzd2lwZXIucGFyYW1zLm9ic2VydmVTbGlkZUNoaWxkcmVuLFxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gT2JzZXJ2ZSB3cmFwcGVyXHJcbiAgICBhdHRhY2goc3dpcGVyLndyYXBwZXJFbCwge1xyXG4gICAgICBhdHRyaWJ1dGVzOiBmYWxzZSxcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgY29uc3QgZGVzdHJveSA9ICgpID0+IHtcclxuICAgIG9ic2VydmVycy5mb3JFYWNoKChvYnNlcnZlcikgPT4ge1xyXG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcbiAgICB9KTtcclxuICAgIG9ic2VydmVycy5zcGxpY2UoMCwgb2JzZXJ2ZXJzLmxlbmd0aCk7XHJcbiAgfTtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgb2JzZXJ2ZXI6IGZhbHNlLFxyXG4gICAgb2JzZXJ2ZVBhcmVudHM6IGZhbHNlLFxyXG4gICAgb2JzZXJ2ZVNsaWRlQ2hpbGRyZW46IGZhbHNlLFxyXG4gIH0pO1xyXG4gIG9uKCdpbml0JywgaW5pdCk7XHJcbiAgb24oJ2Rlc3Ryb3knLCBkZXN0cm95KTtcclxufVxyXG5cclxuLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZXJzY29yZS1kYW5nbGUgKi9cclxuXHJcbnZhciBldmVudHNFbWl0dGVyID0ge1xyXG4gIG9uKGV2ZW50cywgaGFuZGxlciwgcHJpb3JpdHkpIHtcclxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xyXG4gICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVycyB8fCBzZWxmLmRlc3Ryb3llZCkgcmV0dXJuIHNlbGY7XHJcbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBzZWxmO1xyXG4gICAgY29uc3QgbWV0aG9kID0gcHJpb3JpdHkgPyAndW5zaGlmdCcgOiAncHVzaCc7XHJcbiAgICBldmVudHMuc3BsaXQoJyAnKS5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSkgc2VsZi5ldmVudHNMaXN0ZW5lcnNbZXZlbnRdID0gW107XHJcbiAgICAgIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XVttZXRob2RdKGhhbmRsZXIpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gc2VsZjtcclxuICB9LFxyXG4gIG9uY2UoZXZlbnRzLCBoYW5kbGVyLCBwcmlvcml0eSkge1xyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcclxuICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHNlbGY7XHJcbiAgICBmdW5jdGlvbiBvbmNlSGFuZGxlcigpIHtcclxuICAgICAgc2VsZi5vZmYoZXZlbnRzLCBvbmNlSGFuZGxlcik7XHJcbiAgICAgIGlmIChvbmNlSGFuZGxlci5fX2VtaXR0ZXJQcm94eSkge1xyXG4gICAgICAgIGRlbGV0ZSBvbmNlSGFuZGxlci5fX2VtaXR0ZXJQcm94eTtcclxuICAgICAgfVxyXG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcclxuICAgICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xyXG4gICAgICB9XHJcbiAgICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XHJcbiAgICB9XHJcbiAgICBvbmNlSGFuZGxlci5fX2VtaXR0ZXJQcm94eSA9IGhhbmRsZXI7XHJcbiAgICByZXR1cm4gc2VsZi5vbihldmVudHMsIG9uY2VIYW5kbGVyLCBwcmlvcml0eSk7XHJcbiAgfSxcclxuICBvbkFueShoYW5kbGVyLCBwcmlvcml0eSkge1xyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcclxuICAgIGlmICh0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHNlbGY7XHJcbiAgICBjb25zdCBtZXRob2QgPSBwcmlvcml0eSA/ICd1bnNoaWZ0JyA6ICdwdXNoJztcclxuICAgIGlmIChzZWxmLmV2ZW50c0FueUxpc3RlbmVycy5pbmRleE9mKGhhbmRsZXIpIDwgMCkge1xyXG4gICAgICBzZWxmLmV2ZW50c0FueUxpc3RlbmVyc1ttZXRob2RdKGhhbmRsZXIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHNlbGY7XHJcbiAgfSxcclxuICBvZmZBbnkoaGFuZGxlcikge1xyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcclxuICAgIGlmICghc2VsZi5ldmVudHNBbnlMaXN0ZW5lcnMpIHJldHVybi
9266BzZWxmO1xyXG4gICAgY29uc3QgaW5kZXggPSBzZWxmLmV2ZW50c0FueUxpc3RlbmVycy5pbmRleE9mKGhhbmRsZXIpO1xyXG4gICAgaWYgKGluZGV4ID49IDApIHtcclxuICAgICAgc2VsZi5ldmVudHNBbnlMaXN0ZW5lcnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIH1cclxuICAgIHJldHVybiBzZWxmO1xyXG4gIH0sXHJcbiAgb2ZmKGV2ZW50cywgaGFuZGxlcikge1xyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcclxuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMpIHJldHVybiBzZWxmO1xyXG4gICAgZXZlbnRzLnNwbGl0KCcgJykuZm9yRWFjaCgoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSA9IFtdO1xyXG4gICAgICB9IGVsc2UgaWYgKHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSkge1xyXG4gICAgICAgIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XS5mb3JFYWNoKChldmVudEhhbmRsZXIsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICBpZiAoZXZlbnRIYW5kbGVyID09PSBoYW5kbGVyIHx8IChldmVudEhhbmRsZXIuX19lbWl0dGVyUHJveHkgJiYgZXZlbnRIYW5kbGVyLl9fZW1pdHRlclByb3h5ID09PSBoYW5kbGVyKSkge1xyXG4gICAgICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0uc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gc2VsZjtcclxuICB9LFxyXG4gIGVtaXQoKSB7XHJcbiAgICBjb25zdCBzZWxmID0gdGhpcztcclxuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMgfHwgc2VsZi5kZXN0cm95ZWQpIHJldHVybiBzZWxmO1xyXG4gICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVycykgcmV0dXJuIHNlbGY7XHJcbiAgICBsZXQgZXZlbnRzO1xyXG4gICAgbGV0IGRhdGE7XHJcbiAgICBsZXQgY29udGV4dDtcclxuICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiksIF9rZXkyID0gMDsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xyXG4gICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnIHx8IEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcclxuICAgICAgZXZlbnRzID0gYXJnc1swXTtcclxuICAgICAgZGF0YSA9IGFyZ3Muc2xpY2UoMSwgYXJncy5sZW5ndGgpO1xyXG4gICAgICBjb250ZXh0ID0gc2VsZjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGV2ZW50cyA9IGFyZ3NbMF0uZXZlbnRzO1xyXG4gICAgICBkYXRhID0gYXJnc1swXS5kYXRhO1xyXG4gICAgICBjb250ZXh0ID0gYXJnc1swXS5jb250ZXh0IHx8IHNlbGY7XHJcbiAgICB9XHJcbiAgICBkYXRhLnVuc2hpZnQoY29udGV4dCk7XHJcbiAgICBjb25zdCBldmVudHNBcnJheSA9IEFycmF5LmlzQXJyYXkoZXZlbnRzKSA/IGV2ZW50cyA6IGV2ZW50cy5zcGxpdCgnICcpO1xyXG4gICAgZXZlbnRzQXJyYXkuZm9yRWFjaCgoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzICYmIHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLmxlbmd0aCkge1xyXG4gICAgICAgIHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLmZvckVhY2goKGV2ZW50SGFuZGxlcikgPT4ge1xyXG4gICAgICAgICAgZXZlbnRIYW5kbGVyLmFwcGx5KGNvbnRleHQsIFtldmVudCwgLi4uZGF0YV0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzZWxmLmV2ZW50c0xpc3RlbmVycyAmJiBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0pIHtcclxuICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0uZm9yRWFjaCgoZXZlbnRIYW5kbGVyKSA9PiB7XHJcbiAgICAgICAgICBldmVudEhhbmRsZXIuYXBwbHkoY29udGV4dCwgZGF0YSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHNlbGY7XHJcbiAgfSxcclxufTtcclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVNpemUoKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBsZXQgd2lkdGg7XHJcbiAgbGV0IGhlaWdodDtcclxuICBjb25zdCBlbCA9IHN3aXBlci5lbDtcclxuICBpZiAodHlwZW9mIHN3aXBlci5wYXJhbXMud2lkdGggIT09ICd1bmRlZmluZWQnICYmIHN3aXBlci5wYXJhbXMud2lkdGggIT09IG51bGwpIHtcclxuICAgIHdpZHRoID0gc3dpcGVyLnBhcmFtcy53aWR0aDtcclxuICB9IGVsc2Uge1xyXG4gICAgd2lkdGggPSBlbC5jbGllbnRXaWR0aDtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiBzd2lwZXIucGFyYW1zLmhlaWdodCAhPT0gJ3VuZGVmaW5lZCcgJiYgc3dpcGVyLnBhcmFtcy5oZWlnaHQgIT09IG51bGwpIHtcclxuICAgIGhlaWdodCA9IHN3aXBlci5wYXJhbXMuaGVpZ2h0O1xyXG4gIH0gZWxzZSB7XHJcbiAgICBoZWlnaHQgPSBlbC5jbGllbnRIZWlnaHQ7XHJcbiAgfVxyXG4gIGlmICgod2lkdGggPT09IDAgJiYgc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB8fCAoaGVpZ2h0ID09PSAwICYmIHN3aXBlci5pc1ZlcnRpY2FsKCkpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBTdWJ0cmFjdCBwYWRkaW5nc1xyXG4gIHdpZHRoID1cclxuICAgIHdpZHRoIC0gcGFyc2VJbnQoZWxlbWVudFN0eWxlKGVsLCAncGFkZGluZy1sZWZ0JykgfHwgMCwgMTApIC0gcGFyc2VJbnQoZWxlbWVudFN0eWxlKGVsLCAncGFkZGluZy1yaWdodCcpIHx8IDAsIDEwKTtcclxuICBoZWlnaHQgPVxyXG4gICAgaGVpZ2h0IC0gcGFyc2VJbnQoZWxlbWVudFN0eWxlKGVsLCAncGFkZGluZy10b3AnKSB8fCAwLCAxMCkgLSBwYXJzZUludChlbGVtZW50U3R5bGUoZWwsICdwYWRkaW5nLWJvdHRvbScpIHx8IDAsIDEwKTtcclxuICBpZiAoTnVtYmVyLmlzTmFOKHdpZHRoKSkgd2lkdGggPSAwO1xyXG4gIGlmIChOdW1iZXIuaXNOYU4oaGVpZ2h0KSkgaGVpZ2h0ID0gMDtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xyXG4gICAgd2lkdGgsXHJcbiAgICBoZWlnaHQsXHJcbiAgICBzaXplOiBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyB3aWR0aCA6IGhlaWdodCxcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlU2xpZGVzKCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgZnVuY3Rpb24gZ2V0RGlyZWN0aW9uTGFiZWwocHJvcGVydHkpIHtcclxuICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcclxuICAgICAgcmV0dXJuIHByb3BlcnR5O1xyXG4gICAgfVxyXG4gICAgLy8gcHJldHRpZXItaWdub3JlXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgICd3aWR0aCc6ICdoZWlnaHQnLFxyXG4gICAgICAgICdtYXJnaW4tdG9wJzogJ21hcmdpbi1sZWZ0JyxcclxuICAgICAgICAnbWFyZ2luLWJvdHRvbSAnOiAnbWFyZ2luLXJpZ2h0JyxcclxuICAgICAgICAnbWFyZ2luLWxlZnQnOiAnbWFyZ2luLXRvcCcsXHJcbiAgICAgICAgJ21hcmdpbi1yaWdodCc6ICdtYXJnaW4tYm90dG9tJyxcclxuICAgICAgICAncGFkZGluZy1sZWZ0JzogJ3BhZGRpbmctdG9wJyxcclxuICAgICAgICAncGFkZGluZy1yaWdodCc6ICdwYWRkaW5nLWJvdHRvbScsXHJcbiAgICAgICAgJ21hcmdpblJpZ2h0JzogJ21hcmdpbkJvdHRvbSdcclxuICAgICAgfVtwcm9wZXJ0eV07XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUobm9kZSwgbGFiZWwpIHtcclxuICAgIHJldHVybi
9266BwYXJzZUZsb2F0KG5vZGUuZ2V0UHJvcGVydHlWYWx1ZShnZXREaXJlY3Rpb25MYWJlbChsYWJlbCkpIHx8IDApO1xyXG4gIH1cclxuICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xyXG4gIGNvbnN0IHsgd3JhcHBlckVsLCBzbGlkZXNFbCwgc2l6ZTogc3dpcGVyU2l6ZSwgcnRsVHJhbnNsYXRlOiBydGwsIHdyb25nUlRMIH0gPSBzd2lwZXI7XHJcbiAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgcGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcclxuICBjb25zdCBwcmV2aW91c1NsaWRlc0xlbmd0aCA9IGlzVmlydHVhbCA/IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggOiBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcclxuICBjb25zdCBzbGlkZXMgPSBlbGVtZW50Q2hpbGRyZW4oc2xpZGVzRWwsIGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9LCBzd2lwZXItc2xpZGVgKTtcclxuICBjb25zdCBzbGlkZXNMZW5ndGggPSBpc1ZpcnR1YWwgPyBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoIDogc2xpZGVzLmxlbmd0aDtcclxuICBsZXQgc25hcEdyaWQgPSBbXTtcclxuICBjb25zdCBzbGlkZXNHcmlkID0gW107XHJcbiAgY29uc3Qgc2xpZGVzU2l6ZXNHcmlkID0gW107XHJcbiAgbGV0IG9mZnNldEJlZm9yZSA9IHBhcmFtcy5zbGlkZXNPZmZzZXRCZWZvcmU7XHJcbiAgaWYgKHR5cGVvZiBvZmZzZXRCZWZvcmUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIG9mZnNldEJlZm9yZSA9IHBhcmFtcy5zbGlkZXNPZmZzZXRCZWZvcmUuY2FsbChzd2lwZXIpO1xyXG4gIH1cclxuICBsZXQgb2Zmc2V0QWZ0ZXIgPSBwYXJhbXMuc2xpZGVzT2Zmc2V0QWZ0ZXI7XHJcbiAgaWYgKHR5cGVvZiBvZmZzZXRBZnRlciA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgb2Zmc2V0QWZ0ZXIgPSBwYXJhbXMuc2xpZGVzT2Zmc2V0QWZ0ZXIuY2FsbChzd2lwZXIpO1xyXG4gIH1cclxuICBjb25zdCBwcmV2aW91c1NuYXBHcmlkTGVuZ3RoID0gc3dpcGVyLnNuYXBHcmlkLmxlbmd0aDtcclxuICBjb25zdCBwcmV2aW91c1NsaWRlc0dyaWRMZW5ndGggPSBzd2lwZXIuc2xpZGVzR3JpZC5sZW5ndGg7XHJcbiAgbGV0IHNwYWNlQmV0d2VlbiA9IHBhcmFtcy5zcGFjZUJldHdlZW47XHJcbiAgbGV0IHNsaWRlUG9zaXRpb24gPSAtb2Zmc2V0QmVmb3JlO1xyXG4gIGxldCBwcmV2U2xpZGVTaXplID0gMDtcclxuICBsZXQgaW5kZXggPSAwO1xyXG4gIGlmICh0eXBlb2Ygc3dpcGVyU2l6ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiBzcGFjZUJldHdlZW4gPT09ICdzdHJpbmcnICYmIHNwYWNlQmV0d2Vlbi5pbmRleE9mKCclJykgPj0gMCkge1xyXG4gICAgc3BhY2VCZXR3ZWVuID0gKHBhcnNlRmxvYXQoc3BhY2VCZXR3ZWVuLnJlcGxhY2UoJyUnLCAnJykpIC8gMTAwKSAqIHN3aXBlclNpemU7XHJcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc3BhY2VCZXR3ZWVuID09PSAnc3RyaW5nJykge1xyXG4gICAgc3BhY2VCZXR3ZWVuID0gcGFyc2VGbG9hdChzcGFjZUJldHdlZW4pO1xyXG4gIH1cclxuICBzd2lwZXIudmlydHVhbFNpemUgPSAtc3BhY2VCZXR3ZWVuO1xyXG5cclxuICAvLyByZXNldCBtYXJnaW5zXHJcbiAgc2xpZGVzLmZvckVhY2goKHNsaWRlRWwpID0+IHtcclxuICAgIGlmIChydGwpIHtcclxuICAgICAgc2xpZGVFbC5zdHlsZS5tYXJnaW5MZWZ0ID0gJyc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzbGlkZUVsLnN0eWxlLm1hcmdpblJpZ2h0ID0gJyc7XHJcbiAgICB9XHJcbiAgICBzbGlkZUVsLnN0eWxlLm1hcmdpbkJvdHRvbSA9ICcnO1xyXG4gICAgc2xpZGVFbC5zdHlsZS5tYXJnaW5Ub3AgPSAnJztcclxuICB9KTtcclxuXHJcbiAgLy8gcmVzZXQgY3NzTW9kZSBvZmZzZXRzXHJcbiAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiBwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgc2V0Q1NTUHJvcGVydHkod3JhcHBlckVsLCAnLS1zd2lwZXItY2VudGVyZWQtb2Zmc2V0LWJlZm9yZScsICcnKTtcclxuICAgIHNldENTU1Byb3BlcnR5KHdyYXBwZXJFbCwgJy0tc3dpcGVyLWNlbnRlcmVkLW9mZnNldC1hZnRlcicsICcnKTtcclxuICB9XHJcbiAgY29uc3QgZ3JpZEVuYWJsZWQgPSBwYXJhbXMuZ3JpZCAmJiBwYXJhbXMuZ3JpZC5yb3dzID4gMSAmJiBzd2lwZXIuZ3JpZDtcclxuICBpZiAoZ3JpZEVuYWJsZWQpIHtcclxuICAgIHN3aXBlci5ncmlkLmluaXRTbGlkZXMoc2xpZGVzTGVuZ3RoKTtcclxuICB9XHJcblxyXG4gIC8vIENhbGMgc2xpZGVzXHJcbiAgbGV0IHNsaWRlU2l6ZTtcclxuICBjb25zdCBzaG91bGRSZXNldFNsaWRlU2l6ZSA9XHJcbiAgICBwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nICYmXHJcbiAgICBwYXJhbXMuYnJlYWtwb2ludHMgJiZcclxuICAgIE9iamVjdC5rZXlzKHBhcmFtcy5icmVha3BvaW50cykuZmlsdGVyKChrZXkpID0+IHtcclxuICAgICAgcmV0dXJuIHR5cGVvZiBwYXJhbXMuYnJlYWtwb2ludHNba2V5XS5zbGlkZXNQZXJWaWV3ICE9PSAndW5kZWZpbmVkJztcclxuICAgIH0pLmxlbmd0aCA+IDA7XHJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXNMZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgc2xpZGVTaXplID0gMDtcclxuICAgIGxldCBzbGlkZTtcclxuICAgIGlmIChzbGlkZXNbaV0pIHNsaWRlID0gc2xpZGVzW2ldO1xyXG4gICAgaWYgKGdyaWRFbmFibGVkKSB7XHJcbiAgICAgIHN3aXBlci5ncmlkLnVwZGF0ZVNsaWRlKGksIHNsaWRlLCBzbGlkZXNMZW5ndGgsIGdldERpcmVjdGlvbkxhYmVsKTtcclxuICAgIH1cclxuICAgIGlmIChzbGlkZXNbaV0gJiYgZWxlbWVudFN0eWxlKHNsaWRlLCAnZGlzcGxheScpID09PSAnbm9uZScpIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcblxyXG4gICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycpIHtcclxuICAgICAgaWYgKHNob3VsZFJlc2V0U2xpZGVTaXplKSB7XHJcbiAgICAgICAgc2xpZGVzW2ldLnN0eWxlW2dldERpcmVjdGlvbkxhYmVsKCd3aWR0aCcpXSA9IGBgO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHNsaWRlU3R5bGVzID0gZ2V0Q29tcHV0ZWRTdHlsZShzbGlkZSk7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRUcmFuc2Zvcm0gPSBzbGlkZS5zdHlsZS50cmFuc2Zvcm07XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRXZWJLaXRUcmFuc2Zvcm0gPSBzbGlkZS5zdHlsZS53ZWJraXRUcmFuc2Zvcm07XHJcbiAgICAgIGlmIChjdXJyZW50VHJhbnNmb3JtKSB7XHJcbiAgICAgICAgc2xpZGUuc3R5bGUudHJhbnNmb3JtID0gJ25vbmUnO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChjdXJyZW50V2ViS2l0VHJhbnNmb3JtKSB7XHJcbiAgICAgICAgc2xpZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ25vbmUnO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSB7XHJcbiAgICAgICAgc2xpZGVTaXplID0gc3dpcGVyLmlzSG9yaXpvbn
9266RhbCgpXHJcbiAgICAgICAgICA/IGVsZW1lbnRPdXRlclNpemUoc2xpZGUsICd3aWR0aCcsIHRydWUpXHJcbiAgICAgICAgICA6IGVsZW1lbnRPdXRlclNpemUoc2xpZGUsICdoZWlnaHQnLCB0cnVlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgICAgICBjb25zdCB3aWR0aCA9IGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUoc2xpZGVTdHlsZXMsICd3aWR0aCcpO1xyXG4gICAgICAgIGNvbnN0IHBhZGRpbmdMZWZ0ID0gZ2V0RGlyZWN0aW9uUHJvcGVydHlWYWx1ZShzbGlkZVN0eWxlcywgJ3BhZGRpbmctbGVmdCcpO1xyXG4gICAgICAgIGNvbnN0IHBhZGRpbmdSaWdodCA9IGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUoc2xpZGVTdHlsZXMsICdwYWRkaW5nLXJpZ2h0Jyk7XHJcbiAgICAgICAgY29uc3QgbWFyZ2luTGVmdCA9IGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUoc2xpZGVTdHlsZXMsICdtYXJnaW4tbGVmdCcpO1xyXG4gICAgICAgIGNvbnN0IG1hcmdpblJpZ2h0ID0gZ2V0RGlyZWN0aW9uUHJvcGVydHlWYWx1ZShzbGlkZVN0eWxlcywgJ21hcmdpbi1yaWdodCcpO1xyXG4gICAgICAgIGNvbnN0IGJveFNpemluZyA9IHNsaWRlU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoJ2JveC1zaXppbmcnKTtcclxuICAgICAgICBpZiAoYm94U2l6aW5nICYmIGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKSB7XHJcbiAgICAgICAgICBzbGlkZVNpemUgPSB3aWR0aCArIG1hcmdpbkxlZnQgKyBtYXJnaW5SaWdodDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc3QgeyBjbGllbnRXaWR0aCwgb2Zmc2V0V2lkdGggfSA9IHNsaWRlO1xyXG4gICAgICAgICAgc2xpZGVTaXplID0gd2lkdGggKyBwYWRkaW5nTGVmdCArIHBhZGRpbmdSaWdodCArIG1hcmdpbkxlZnQgKyBtYXJnaW5SaWdodCArIChvZmZzZXRXaWR0aCAtIGNsaWVudFdpZHRoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGN1cnJlbnRUcmFuc2Zvcm0pIHtcclxuICAgICAgICBzbGlkZS5zdHlsZS50cmFuc2Zvcm0gPSBjdXJyZW50VHJhbnNmb3JtO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChjdXJyZW50V2ViS2l0VHJhbnNmb3JtKSB7XHJcbiAgICAgICAgc2xpZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gY3VycmVudFdlYktpdFRyYW5zZm9ybTtcclxuICAgICAgfVxyXG4gICAgICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykgc2xpZGVTaXplID0gTWF0aC5mbG9vcihzbGlkZVNpemUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2xpZGVTaXplID0gKHN3aXBlclNpemUgLSAocGFyYW1zLnNsaWRlc1BlclZpZXcgLSAxKSAqIHNwYWNlQmV0d2VlbikgLyBwYXJhbXMuc2xpZGVzUGVyVmlldztcclxuICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlU2l6ZSA9IE1hdGguZmxvb3Ioc2xpZGVTaXplKTtcclxuICAgICAgaWYgKHNsaWRlc1tpXSkge1xyXG4gICAgICAgIHNsaWRlc1tpXS5zdHlsZVtnZXREaXJlY3Rpb25MYWJlbCgnd2lkdGgnKV0gPSBgJHtzbGlkZVNpemV9cHhgO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoc2xpZGVzW2ldKSB7XHJcbiAgICAgIHNsaWRlc1tpXS5zd2lwZXJTbGlkZVNpemUgPSBzbGlkZVNpemU7XHJcbiAgICB9XHJcbiAgICBzbGlkZXNTaXplc0dyaWQucHVzaChzbGlkZVNpemUpO1xyXG4gICAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xyXG4gICAgICBzbGlkZVBvc2l0aW9uID0gc2xpZGVQb3NpdGlvbiArIHNsaWRlU2l6ZSAvIDIgKyBwcmV2U2xpZGVTaXplIC8gMiArIHNwYWNlQmV0d2VlbjtcclxuICAgICAgaWYgKHByZXZTbGlkZVNpemUgPT09IDAgJiYgaSAhPT0gMCkgc2xpZGVQb3NpdGlvbiA9IHNsaWRlUG9zaXRpb24gLSBzd2lwZXJTaXplIC8gMiAtIHNwYWNlQmV0d2VlbjtcclxuICAgICAgaWYgKGkgPT09IDApIHNsaWRlUG9zaXRpb24gPSBzbGlkZVBvc2l0aW9uIC0gc3dpcGVyU2l6ZSAvIDIgLSBzcGFjZUJldHdlZW47XHJcbiAgICAgIGlmIChNYXRoLmFicyhzbGlkZVBvc2l0aW9uKSA8IDEgLyAxMDAwKSBzbGlkZVBvc2l0aW9uID0gMDtcclxuICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlUG9zaXRpb24gPSBNYXRoLmZsb29yKHNsaWRlUG9zaXRpb24pO1xyXG4gICAgICBpZiAoaW5kZXggJSBwYXJhbXMuc2xpZGVzUGVyR3JvdXAgPT09IDApIHNuYXBHcmlkLnB1c2goc2xpZGVQb3NpdGlvbik7XHJcbiAgICAgIHNsaWRlc0dyaWQucHVzaChzbGlkZVBvc2l0aW9uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSBzbGlkZVBvc2l0aW9uID0gTWF0aC5mbG9vcihzbGlkZVBvc2l0aW9uKTtcclxuICAgICAgaWYgKChpbmRleCAtIE1hdGgubWluKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwLCBpbmRleCkpICUgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA9PT0gMClcclxuICAgICAgICBzbmFwR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xyXG4gICAgICBzbGlkZXNHcmlkLnB1c2goc2xpZGVQb3NpdGlvbik7XHJcbiAgICAgIHNsaWRlUG9zaXRpb24gPSBzbGlkZVBvc2l0aW9uICsgc2xpZGVTaXplICsgc3BhY2VCZXR3ZWVuO1xyXG4gICAgfVxyXG4gICAgc3dpcGVyLnZpcnR1YWxTaXplICs9IHNsaWRlU2l6ZSArIHNwYWNlQmV0d2VlbjtcclxuICAgIHByZXZTbGlkZVNpemUgPSBzbGlkZVNpemU7XHJcbiAgICBpbmRleCArPSAxO1xyXG4gIH1cclxuICBzd2lwZXIudmlydHVhbFNpemUgPSBNYXRoLm1heChzd2lwZXIudmlydHVhbFNpemUsIHN3aXBlclNpemUpICsgb2Zmc2V0QWZ0ZXI7XHJcbiAgaWYgKHJ0bCAmJiB3cm9uZ1JUTCAmJiAocGFyYW1zLmVmZmVjdCA9PT0gJ3NsaWRlJyB8fCBwYXJhbXMuZWZmZWN0ID09PSAnY292ZXJmbG93JykpIHtcclxuICAgIHdyYXBwZXJFbC5zdHlsZS53aWR0aCA9IGAke3N3aXBlci52aXJ0dWFsU2l6ZSArIHNwYWNlQmV0d2Vlbn1weGA7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuc2V0V3JhcHBlclNpemUpIHtcclxuICAgIHdyYXBwZXJFbC5zdHlsZVtnZXREaXJlY3Rpb25MYWJlbCgnd2lkdGgnKV0gPSBgJHtzd2lwZXIudmlydHVhbFNpemUgKyBzcGFjZUJldHdlZW59cHhgO1xyXG4gIH1cclxuICBpZiAoZ3JpZEVuYWJsZWQpIHtcclxuICAgIHN3aXBlci5ncmlkLnVwZGF0ZVdyYXBwZXJTaXplKHNsaWRlU2l6ZSwgc25
9266hcEdyaWQsIGdldERpcmVjdGlvbkxhYmVsKTtcclxuICB9XHJcblxyXG4gIC8vIFJlbW92ZSBsYXN0IGdyaWQgZWxlbWVudHMgZGVwZW5kaW5nIG9uIHdpZHRoXHJcbiAgaWYgKCFwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcclxuICAgIGNvbnN0IG5ld1NsaWRlc0dyaWQgPSBbXTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc25hcEdyaWQubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgbGV0IHNsaWRlc0dyaWRJdGVtID0gc25hcEdyaWRbaV07XHJcbiAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSBzbGlkZXNHcmlkSXRlbSA9IE1hdGguZmxvb3Ioc2xpZGVzR3JpZEl0ZW0pO1xyXG4gICAgICBpZiAoc25hcEdyaWRbaV0gPD0gc3dpcGVyLnZpcnR1YWxTaXplIC0gc3dpcGVyU2l6ZSkge1xyXG4gICAgICAgIG5ld1NsaWRlc0dyaWQucHVzaChzbGlkZXNHcmlkSXRlbSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHNuYXBHcmlkID0gbmV3U2xpZGVzR3JpZDtcclxuICAgIGlmIChNYXRoLmZsb29yKHN3aXBlci52aXJ0dWFsU2l6ZSAtIHN3aXBlclNpemUpIC0gTWF0aC5mbG9vcihzbmFwR3JpZFtzbmFwR3JpZC5sZW5ndGggLSAxXSkgPiAxKSB7XHJcbiAgICAgIHNuYXBHcmlkLnB1c2goc3dpcGVyLnZpcnR1YWxTaXplIC0gc3dpcGVyU2l6ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmIChpc1ZpcnR1YWwgJiYgcGFyYW1zLmxvb3ApIHtcclxuICAgIGNvbnN0IHNpemUgPSBzbGlkZXNTaXplc0dyaWRbMF0gKyBzcGFjZUJldHdlZW47XHJcbiAgICBpZiAocGFyYW1zLnNsaWRlc1Blckdyb3VwID4gMSkge1xyXG4gICAgICBjb25zdCBncm91cHMgPSBNYXRoLmNlaWwoKHN3aXBlci52aXJ0dWFsLnNsaWRlc0JlZm9yZSArIHN3aXBlci52aXJ0dWFsLnNsaWRlc0FmdGVyKSAvIHBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XHJcbiAgICAgIGNvbnN0IGdyb3VwU2l6ZSA9IHNpemUgKiBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JvdXBzOyBpICs9IDEpIHtcclxuICAgICAgICBzbmFwR3JpZC5wdXNoKHNuYXBHcmlkW3NuYXBHcmlkLmxlbmd0aCAtIDFdICsgZ3JvdXBTaXplKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzd2lwZXIudmlydHVhbC5zbGlkZXNCZWZvcmUgKyBzd2lwZXIudmlydHVhbC5zbGlkZXNBZnRlcjsgaSArPSAxKSB7XHJcbiAgICAgIGlmIChwYXJhbXMuc2xpZGVzUGVyR3JvdXAgPT09IDEpIHtcclxuICAgICAgICBzbmFwR3JpZC5wdXNoKHNuYXBHcmlkW3NuYXBHcmlkLmxlbmd0aCAtIDFdICsgc2l6ZSk7XHJcbiAgICAgIH1cclxuICAgICAgc2xpZGVzR3JpZC5wdXNoKHNsaWRlc0dyaWRbc2xpZGVzR3JpZC5sZW5ndGggLSAxXSArIHNpemUpO1xyXG4gICAgICBzd2lwZXIudmlydHVhbFNpemUgKz0gc2l6ZTtcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKHNuYXBHcmlkLmxlbmd0aCA9PT0gMCkgc25hcEdyaWQgPSBbMF07XHJcbiAgaWYgKHNwYWNlQmV0d2VlbiAhPT0gMCkge1xyXG4gICAgY29uc3Qga2V5ID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpICYmIHJ0bCA/ICdtYXJnaW5MZWZ0JyA6IGdldERpcmVjdGlvbkxhYmVsKCdtYXJnaW5SaWdodCcpO1xyXG4gICAgc2xpZGVzXHJcbiAgICAgIC5maWx0ZXIoKF8sIHNsaWRlSW5kZXgpID0+IHtcclxuICAgICAgICBpZiAoIXBhcmFtcy5jc3NNb2RlIHx8IHBhcmFtcy5sb29wKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICBpZiAoc2xpZGVJbmRleCA9PT0gc2xpZGVzLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgICAgc2xpZGVFbC5zdHlsZVtrZXldID0gYCR7c3BhY2VCZXR3ZWVufXB4YDtcclxuICAgICAgfSk7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzQm91bmRzKSB7XHJcbiAgICBsZXQgYWxsU2xpZGVzU2l6ZSA9IDA7XHJcbiAgICBzbGlkZXNTaXplc0dyaWQuZm9yRWFjaCgoc2xpZGVTaXplVmFsdWUpID0+IHtcclxuICAgICAgYWxsU2xpZGVzU2l6ZSArPSBzbGlkZVNpemVWYWx1ZSArIChzcGFjZUJldHdlZW4gfHwgMCk7XHJcbiAgICB9KTtcclxuICAgIGFsbFNsaWRlc1NpemUgLT0gc3BhY2VCZXR3ZWVuO1xyXG4gICAgY29uc3QgbWF4U25hcCA9IGFsbFNsaWRlc1NpemUgLSBzd2lwZXJTaXplO1xyXG4gICAgc25hcEdyaWQgPSBzbmFwR3JpZC5tYXAoKHNuYXApID0+IHtcclxuICAgICAgaWYgKHNuYXAgPD0gMCkgcmV0dXJuIC1vZmZzZXRCZWZvcmU7XHJcbiAgICAgIGlmIChzbmFwID4gbWF4U25hcCkgcmV0dXJuIG1heFNuYXAgKyBvZmZzZXRBZnRlcjtcclxuICAgICAgcmV0dXJuIHNuYXA7XHJcbiAgICB9KTtcclxuICB9XHJcbiAgaWYgKHBhcmFtcy5jZW50ZXJJbnN1ZmZpY2llbnRTbGlkZXMpIHtcclxuICAgIGxldCBhbGxTbGlkZXNTaXplID0gMDtcclxuICAgIHNsaWRlc1NpemVzR3JpZC5mb3JFYWNoKChzbGlkZVNpemVWYWx1ZSkgPT4ge1xyXG4gICAgICBhbGxTbGlkZXNTaXplICs9IHNsaWRlU2l6ZVZhbHVlICsgKHNwYWNlQmV0d2VlbiB8fCAwKTtcclxuICAgIH0pO1xyXG4gICAgYWxsU2xpZGVzU2l6ZSAtPSBzcGFj
9266ZUJldHdlZW47XHJcbiAgICBpZiAoYWxsU2xpZGVzU2l6ZSA8IHN3aXBlclNpemUpIHtcclxuICAgICAgY29uc3QgYWxsU2xpZGVzT2Zmc2V0ID0gKHN3aXBlclNpemUgLSBhbGxTbGlkZXNTaXplKSAvIDI7XHJcbiAgICAgIHNuYXBHcmlkLmZvckVhY2goKHNuYXAsIHNuYXBJbmRleCkgPT4ge1xyXG4gICAgICAgIHNuYXBHcmlkW3NuYXBJbmRleF0gPSBzbmFwIC0gYWxsU2xpZGVzT2Zmc2V0O1xyXG4gICAgICB9KTtcclxuICAgICAgc2xpZGVzR3JpZC5mb3JFYWNoKChzbmFwLCBzbmFwSW5kZXgpID0+IHtcclxuICAgICAgICBzbGlkZXNHcmlkW3NuYXBJbmRleF0gPSBzbmFwICsgYWxsU2xpZGVzT2Zmc2V0O1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIsIHtcclxuICAgIHNsaWRlcyxcclxuICAgIHNuYXBHcmlkLFxyXG4gICAgc2xpZGVzR3JpZCxcclxuICAgIHNsaWRlc1NpemVzR3JpZCxcclxuICB9KTtcclxuICBpZiAocGFyYW1zLmNlbnRlcmVkU2xpZGVzICYmIHBhcmFtcy5jc3NNb2RlICYmICFwYXJhbXMuY2VudGVyZWRTbGlkZXNCb3VuZHMpIHtcclxuICAgIHNldENTU1Byb3BlcnR5KHdyYXBwZXJFbCwgJy0tc3dpcGVyLWNlbnRlcmVkLW9mZnNldC1iZWZvcmUnLCBgJHstc25hcEdyaWRbMF19cHhgKTtcclxuICAgIHNldENTU1Byb3BlcnR5KFxyXG4gICAgICB3cmFwcGVyRWwsXHJcbiAgICAgICctLXN3aXBlci1jZW50ZXJlZC1vZmZzZXQtYWZ0ZXInLFxyXG4gICAgICBgJHtzd2lwZXIuc2l6ZSAvIDIgLSBzbGlkZXNTaXplc0dyaWRbc2xpZGVzU2l6ZXNHcmlkLmxlbmd0aCAtIDFdIC8gMn1weGBcclxuICAgICk7XHJcbiAgICBjb25zdCBhZGRUb1NuYXBHcmlkID0gLXN3aXBlci5zbmFwR3JpZFswXTtcclxuICAgIGNvbnN0IGFkZFRvU2xpZGVzR3JpZCA9IC1zd2lwZXIuc2xpZGVzR3JpZFswXTtcclxuICAgIHN3aXBlci5zbmFwR3JpZCA9IHN3aXBlci5zbmFwR3JpZC5tYXAoKHYpID0+IHYgKyBhZGRUb1NuYXBHcmlkKTtcclxuICAgIHN3aXBlci5zbGlkZXNHcmlkID0gc3dpcGVyLnNsaWRlc0dyaWQubWFwKCh2KSA9PiB2ICsgYWRkVG9TbGlkZXNHcmlkKTtcclxuICB9XHJcbiAgaWYgKHNsaWRlc0xlbmd0aCAhPT0gcHJldmlvdXNTbGlkZXNMZW5ndGgpIHtcclxuICAgIHN3aXBlci5lbWl0KCdzbGlkZXNMZW5ndGhDaGFuZ2UnKTtcclxuICB9XHJcbiAgaWYgKHNuYXBHcmlkLmxlbmd0aCAhPT0gcHJldmlvdXNTbmFwR3JpZExlbmd0aCkge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdykgc3dpcGVyLmNoZWNrT3ZlcmZsb3coKTtcclxuICAgIHN3aXBlci5lbWl0KCdzbmFwR3JpZExlbmd0aENoYW5nZScpO1xyXG4gIH1cclxuICBpZiAoc2xpZGVzR3JpZC5sZW5ndGggIT09IHByZXZpb3VzU2xpZGVzR3JpZExlbmd0aCkge1xyXG4gICAgc3dpcGVyLmVtaXQoJ3NsaWRlc0dyaWRMZW5ndGhDaGFuZ2UnKTtcclxuICB9XHJcbiAgaWYgKHBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzT2Zmc2V0KCk7XHJcbiAgfVxyXG4gIGlmICghaXNWaXJ0dWFsICYmICFwYXJhbXMuY3NzTW9kZSAmJiAocGFyYW1zLmVmZmVjdCA9PT0gJ3NsaWRlJyB8fCBwYXJhbXMuZWZmZWN0ID09PSAnZmFkZScpKSB7XHJcbiAgICBjb25zdCBiYWNrRmFjZUhpZGRlbkNsYXNzID0gYCR7cGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9YmFja2ZhY2UtaGlkZGVuYDtcclxuICAgIGNvbnN0IGhhc0NsYXNzQmFja2ZhY2VDbGFzc0FkZGVkID0gc3dpcGVyLmVsLmNsYXNzTGlzdC5jb250YWlucyhiYWNrRmFjZUhpZGRlbkNsYXNzKTtcclxuICAgIGlmIChzbGlkZXNMZW5ndGggPD0gcGFyYW1zLm1heEJhY2tmYWNlSGlkZGVuU2xpZGVzKSB7XHJcbiAgICAgIGlmICghaGFzQ2xhc3NCYWNrZmFjZUNsYXNzQWRkZWQpIHN3aXBlci5lbC5jbGFzc0xpc3QuYWRkKGJhY2tGYWNlSGlkZGVuQ2xhc3MpO1xyXG4gICAgfSBlbHNlIGlmIChoYXNDbGFzc0JhY2tmYWNlQ2xhc3NBZGRlZCkge1xyXG4gICAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LnJlbW92ZShiYWNrRmFjZUhpZGRlbkNsYXNzKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUF1dG9IZWlnaHQoc3BlZWQpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IGFjdGl2ZVNsaWRlcyA9IFtdO1xyXG4gIGNvbnN0IGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkO1xyXG4gIGxldCBuZXdIZWlnaHQgPSAwO1xyXG4gIGxldCBpO1xyXG4gIGlmICh0eXBlb2Ygc3BlZWQgPT09ICdudW1iZXInKSB7XHJcbiAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihzcGVlZCk7XHJcbiAgfSBlbHNlIGlmIChzcGVlZCA9PT0gdHJ1ZSkge1xyXG4gICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCk7XHJcbiAgfVxyXG4gIGNvbnN0IGdldFNsaWRlQnlJbmRleCA9IChpbmRleCkgPT4ge1xyXG4gICAgaWYgKGlzVmlydHVhbCkge1xyXG4gICAgICByZXR1cm4gc3dpcGVyLnNsaWRlc1tzd2lwZXIuZ2V0U2xpZGVJbmRleEJ5RGF0YShpbmRleCldO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN3aXBlci5zbGlkZXNbaW5kZXhdO1xyXG4gIH07XHJcbiAgLy8gRmluZCBzbGlkZXMgY3VycmVudGx5IGluIHZpZXdcclxuICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSAnYXV0bycgJiYgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcclxuICAgICAgKHN3aXBlci52aXNpYmxlU2xpZGVzIHx8IFtdKS5mb3JFYWNoKChzbGlkZSkgPT4ge1xyXG4gICAgICAgIGFjdGl2ZVNsaWRlcy5wdXNoKHNsaWRlKTtcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgTWF0aC5jZWlsKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyk7IGkgKz0gMSkge1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4ICsgaTtcclxuICAgICAgICBpZiAoaW5kZXggPiBzd2lwZXIuc2xpZGVzLmxlbmd0aCAmJiAhaXNWaXJ0dWFsKSBicmVhaztcclxuICAgICAgICBhY3RpdmVTbGlkZXMucHVzaChnZXRTbGlkZUJ5SW5kZXgoaW5kZXgpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBhY3RpdmVTbGlkZXMucHVzaChnZXRTbGlkZUJ5SW5kZXgoc3dpcGVyLmFjdGl2ZUluZGV4KSk7XHJcbiAgfVxyXG5cclxuICAvLyBGaW5kIG5ldyBoZWlnaHQgZnJvbSBoaWdoZXN0IHNsaWRlIGluIHZpZXdcclxuICBmb3IgKGkgPSAwOyBpIDwgYWN0aXZlU2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICBpZiAodHlwZW9mIGFjdGl2ZVNsaWRlc1tpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgY29uc3QgaGVpZ2h0ID0gYWN0aXZlU2xpZGVzW2ldLm9mZnNldEhlaWdodDtcclxuICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0ID4gbmV3SGVpZ2h0ID8gaGVpZ2h0IDogbmV3SGVpZ2h0O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gVXBkYXRlIEhlaWdodFxyXG4gIGlmIChuZXdIZWlnaHQgfHwgbmV3SGVpZ2h0ID09PSAwKSBzd2lwZXIud3JhcHBlckVsLnN0eWxlLmhlaWdodCA9IGAke25ld0hlaWdodH1weGA7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVNsaWRlc09mZnNldCgpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHNsaWRlcyA9IHN3aXBlci5zbGlkZXM7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgY29uc3QgbWludXNPZmZzZXQgPSBzd2lwZXIuaXNFbGVtZW50XHJcbiAgICA/IHN3aXBlci5pc0hvcml6b250YWwoKVxyXG4gICAgICA/IHN3aXBlci53cmFwcGVyRWwub2Zmc2V0TGVmdFxyXG4gICAgICA6IHN3aXBlci53cmFwcGVyRWwub2Zmc2V0VG9wXHJcbiAgICA6IDA7XHJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgIHNsaWRlc1tpXS5zd2lwZXJTbGlkZU9mZnNldCA9XHJcbiAgICAgIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBzbGlkZXNbaV0ub2Zmc2V0TGVmdCA6IHNsaWRlc1tpXS5vZmZzZXRUb3ApIC1cclxuICAgICAgbWludXNPZmZzZXQgLVxyXG4gICAgICBzd2lwZXIuY3NzT3ZlcmZsb3dBZGp1c3RtZW50KCk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVTbGlkZXNQcm9ncmVzcyh0cmFuc2xhdGUpIHtcclxuICBpZiAodHJhbnNsYXRlID09PSB2b2lkIDApIHtcclxuICAgIHRyYW5zbGF0ZSA9ICh0aGlzICYmIHRoaXMudHJhbnNsYXRlKSB8fCAwO1xyXG4gIH1cclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXM7XHJcbiAgY29uc3QgeyBzbGlkZXMsIHJ0bFRyYW5zbGF0ZTogcnRsLCBzbmFwR3JpZCB9ID0gc3dpcGVyO1xyXG4gIGlmIChzbGlkZXMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcbiAgaWYgKHR5cGVvZiBzbGlkZXNbMF0uc3dpcGVyU2xpZGVPZmZzZXQgPT09ICd1bmRlZmluZWQnKSBzd2lwZXIudXBkYXRlU2xpZGVzT2Zmc2V0KCk7XHJcbiAgbGV0IG9mZnNldENlbnRlciA9IC10cmFuc2xhdGU7XHJcbiAgaWYgKHJ0bCkgb2Zmc2V0Q2VudGVyID0gdHJhbnNsYXRlO1xyXG5cclxuICAvLyBWaXNpYmxlIFNsaWRlc1xyXG4gIHNsaWRlcy5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICBzbGlkZUVsLmNsYXNzTGlzdC5yZW1vdmUocGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzKTtcclxuICB9KTtcclxuICBzd2lwZXIudmlzaWJsZVNsaWRlc0luZGV4ZXMgPSBbXTtcclxuICBzd2lwZXIudmlzaWJsZVNsaWRlcyA9IFtdO1xyXG4gIGxldCBzcGFjZUJldHdlZW4gPSBwYXJhbXMuc3BhY2VCZXR3ZWVuO1xyXG4gIGlmICh0eXBlb2Ygc3BhY2VCZXR3ZWVuID09PSAnc3RyaW5nJyAmJiBzcGFjZUJldHdlZW4uaW5kZXhPZignJScpID49IDApIHtcclxuICAgIHNwYWNlQmV0d2VlbiA9IChwYXJzZU
9266Zsb2F0KHNwYWNlQmV0d2Vlbi5yZXBsYWNlKCclJywgJycpKSAvIDEwMCkgKiBzd2lwZXIuc2l6ZTtcclxuICB9IGVsc2UgaWYgKHR5cGVvZiBzcGFjZUJldHdlZW4gPT09ICdzdHJpbmcnKSB7XHJcbiAgICBzcGFjZUJldHdlZW4gPSBwYXJzZUZsb2F0KHNwYWNlQmV0d2Vlbik7XHJcbiAgfVxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICBjb25zdCBzbGlkZSA9IHNsaWRlc1tpXTtcclxuICAgIGxldCBzbGlkZU9mZnNldCA9IHNsaWRlLnN3aXBlclNsaWRlT2Zmc2V0O1xyXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlICYmIHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xyXG4gICAgICBzbGlkZU9mZnNldCAtPSBzbGlkZXNbMF0uc3dpcGVyU2xpZGVPZmZzZXQ7XHJcbiAgICB9XHJcbiAgICBjb25zdCBzbGlkZVByb2dyZXNzID1cclxuICAgICAgKG9mZnNldENlbnRlciArIChwYXJhbXMuY2VudGVyZWRTbGlkZXMgPyBzd2lwZXIubWluVHJhbnNsYXRlKCkgOiAwKSAtIHNsaWRlT2Zmc2V0KSAvXHJcbiAgICAgIChzbGlkZS5zd2lwZXJTbGlkZVNpemUgKyBzcGFjZUJldHdlZW4pO1xyXG4gICAgY29uc3Qgb3JpZ2luYWxTbGlkZVByb2dyZXNzID1cclxuICAgICAgKG9mZnNldENlbnRlciAtIHNuYXBHcmlkWzBdICsgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyA/IHN3aXBlci5taW5UcmFuc2xhdGUoKSA6IDApIC0gc2xpZGVPZmZzZXQpIC9cclxuICAgICAgKHNsaWRlLnN3aXBlclNsaWRlU2l6ZSArIHNwYWNlQmV0d2Vlbik7XHJcbiAgICBjb25zdCBzbGlkZUJlZm9yZSA9IC0ob2Zmc2V0Q2VudGVyIC0gc2xpZGVPZmZzZXQpO1xyXG4gICAgY29uc3Qgc2xpZGVBZnRlciA9IHNsaWRlQmVmb3JlICsgc3dpcGVyLnNsaWRlc1NpemVzR3JpZFtpXTtcclxuICAgIGNvbnN0IGlzVmlzaWJsZSA9XHJcbiAgICAgIChzbGlkZUJlZm9yZSA+PSAwICYmIHNsaWRlQmVmb3JlIDwgc3dpcGVyLnNpemUgLSAxKSB8fFxyXG4gICAgICAoc2xpZGVBZnRlciA+IDEgJiYgc2xpZGVBZnRlciA8PSBzd2lwZXIuc2l6ZSkgfHxcclxuICAgICAgKHNsaWRlQmVmb3JlIDw9IDAgJiYgc2xpZGVBZnRlciA+PSBzd2lwZXIuc2l6ZSk7XHJcbiAgICBpZiAoaXNWaXNpYmxlKSB7XHJcbiAgICAgIHN3aXBlci52aXNpYmxlU2xpZGVzLnB1c2goc2xpZGUpO1xyXG4gICAgICBzd2lwZXIudmlzaWJsZVNsaWRlc0luZGV4ZXMucHVzaChpKTtcclxuICAgICAgc2xpZGVzW2ldLmNsYXNzTGlzdC5hZGQocGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzKTtcclxuICAgIH1cclxuICAgIHNsaWRlLnByb2dyZXNzID0gcnRsID8gLXNsaWRlUHJvZ3Jlc3MgOiBzbGlkZVByb2dyZXNzO1xyXG4gICAgc2xpZGUub3JpZ2luYWxQcm9ncmVzcyA9IHJ0bCA/IC1vcmlnaW5hbFNsaWRlUHJvZ3Jlc3MgOiBvcmlnaW5hbFNsaWRlUHJvZ3Jlc3M7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVQcm9ncmVzcyh0cmFuc2xhdGUpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGlmICh0eXBlb2YgdHJhbnNsYXRlID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgY29uc3QgbXVsdGlwbGllciA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyAtMSA6IDE7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgIHRyYW5zbGF0ZSA9IChzd2lwZXIgJiYgc3dpcGVyLnRyYW5zbGF0ZSAmJiBzd2lwZXIudHJhbnNsYXRlICogbXVsdGlwbGllcikgfHwgMDtcclxuICB9XHJcbiAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcztcclxuICBjb25zdCB0cmFuc2xhdGVzRGlmZiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKTtcclxuICBsZXQgeyBwcm9ncmVzcywgaXNCZWdpbm5pbmcsIGlzRW5kLCBwcm9ncmVzc0xvb3AgfSA9IHN3aXBlcjtcclxuICBjb25zdCB3YXNCZWdpbm5pbmcgPSBpc0JlZ2lubmluZztcclxuICBjb25zdCB3YXNFbmQgPSBpc0VuZDtcclxuICBpZiAodHJhbnNsYXRlc0RpZmYgPT09IDApIHtcclxuICAgIHByb2dyZXNzID0gMDtcclxuICAgIGlzQmVnaW5uaW5nID0gdHJ1ZTtcclxuICAgIGlzRW5kID0gdHJ1ZTtcclxuICB9IGVsc2Uge1xyXG4gICAgcHJvZ3Jlc3MgPSAodHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAvIHRyYW5zbGF0ZXNEaWZmO1xyXG4gICAgY29uc3QgaXNCZWdpbm5pbmdSb3VuZGVkID0gTWF0aC5hYnModHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSA8IDE7XHJcbiAgICBjb25zdCBpc0VuZFJvdW5kZWQgPSBNYXRoLmFicyh0cmFuc2xhdGUgLSBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIDwgMTtcclxuICAgIGlzQmVnaW5uaW5nID0gaXNCZWdpbm5pbmdSb3VuZGVkIHx8IHByb2dyZXNzIDw9IDA7XHJcbiAgICBpc0VuZCA9IGlzRW5kUm91bmRlZCB8fCBwcm9ncmVzcyA+PSAxO1xyXG4gICAgaWYgKGlzQmVnaW5uaW5nUm91bmRlZCkgcHJvZ3Jlc3MgPSAwO1xyXG4gICAgaWYgKGlzRW5kUm91bmRlZCkgcHJvZ3Jlc3MgPSAxO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLmxvb3ApIHtcclxuICAgIGNvbnN0IGZpcnN0U2xpZGVJbmRleCA9IHN3aXBlci5nZXRTbGlkZUluZGV4QnlEYXRhKDApO1xyXG4gICAgY29uc3QgbGFzdFNsaWRlSW5kZXggPSBzd2lwZXIuZ2V0U2xpZGVJbmRleEJ5RGF0YShzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEpO1xyXG4gICAgY29uc3QgZmlyc3RTbGlkZVRyYW5zbGF0ZSA9IHN3aXBlci5zbGlkZXNHcmlkW2ZpcnN0U2xpZGVJbmRleF07XHJcbiAgICBjb25zdCBsYXN0U2xpZGVUcmFuc2xhdGUgPSBzd2lwZXIuc2xpZGVzR3JpZFtsYXN0U2xpZGVJbmRleF07XHJcbiAgICBjb25zdCB0cmFuc2xhdGVNYXggPSBzd2lwZXIuc2xpZGVzR3JpZFtzd2lwZXIuc2xpZGVzR3JpZC5sZW5ndGggLSAxXTtcclxuICAgIGNvbnN0IHRyYW5zbGF0ZUFicyA9IE1hdGguYWJzKHRyYW5zbGF0ZSk7XHJcbiAgICBpZiAodHJhbnNsYXRlQWJzID49IGZpcnN0U2xpZGVUcmFuc2xhdGUpIHtcclxuICAgICAgcHJvZ3Jlc3NMb29wID0gKHRyYW5zbGF0ZUFicyAtIGZpcnN0U2xpZGVUcmFuc2xhdGUpIC8gdHJhbnNsYXRlTWF4O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcHJvZ3Jlc3NMb29wID0gKHRyYW5zbGF0ZUFicyArIHRyYW5zbGF0ZU1heCAtIGxhc3RTbGlkZVRyYW5zbGF0ZSkgLyB0cmFuc2xhdGVNYXg7XHJcbiAgICB9XHJcbiAgICBpZiAocHJvZ3Jlc3NMb29wID4gMSkgcHJvZ3Jlc3NMb29wIC09IDE7XHJcbiAgfVxyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XHJcbiAgICBwcm9ncmVzcyxcclxuICAgIHByb2dyZXNzTG9vcCxcclxuICAgIGlzQmVnaW5uaW5nLFxyXG4gICAgaXNFbmQsXHJcbiAgfSk7XHJcbiAgaWYgKHBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzIHx8IChwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmF1dG9IZWlnaHQpKVxyXG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlc1Byb2dyZXNzKHRyYW5zbGF0ZSk7XHJcbiAgaWYgKGlzQmVnaW5uaW5nICYmICF3YXNCZWdpbm5pbmcpIHtcclxuICAgIHN3aXBlci5lbWl0KCdyZWFjaEJlZ2lubmluZyB0b0VkZ2UnKTtcclxuICB9XHJcbiAgaWYgKGlzRW5kICYmICF3YXNFbmQpIHtcclxuICAgIHN3aXBlci5lbWl0KCdyZWFjaEVuZCB0b0VkZ2UnKTtcclxuICB9XHJcbiAgaWYgKCh3YXNCZWdpbm5pbmcgJiYgIWlzQmVnaW5uaW5nKSB8fCAod2FzRW5kICYmICFpc0VuZCkpIHtcclxuICAgIHN3aXBlci5lbWl0KCdmcm9tRWRnZScpO1xyXG4gIH1cclxuICBzd2lwZXIuZW1pdCgnc
9266HJvZ3Jlc3MnLCBwcm9ncmVzcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVNsaWRlc0NsYXNzZXMoKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCB7IHNsaWRlcywgcGFyYW1zLCBzbGlkZXNFbCwgYWN0aXZlSW5kZXggfSA9IHN3aXBlcjtcclxuICBjb25zdCBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBwYXJhbXMudmlydHVhbC5lbmFibGVkO1xyXG4gIGNvbnN0IGdldEZpbHRlcmVkU2xpZGUgPSAoc2VsZWN0b3IpID0+IHtcclxuICAgIHJldHVybiBlbGVtZW50Q2hpbGRyZW4oc2xpZGVzRWwsIGAuJHtwYXJhbXMuc2xpZGVDbGFzc30ke3NlbGVjdG9yfSwgc3dpcGVyLXNsaWRlJHtzZWxlY3Rvcn1gKVswXTtcclxuICB9O1xyXG4gIHNsaWRlcy5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICBzbGlkZUVsLmNsYXNzTGlzdC5yZW1vdmUocGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MsIHBhcmFtcy5zbGlkZU5leHRDbGFzcywgcGFyYW1zLnNsaWRlUHJldkNsYXNzKTtcclxuICB9KTtcclxuICBsZXQgYWN0aXZlU2xpZGU7XHJcbiAgaWYgKGlzVmlydHVhbCkge1xyXG4gICAgaWYgKHBhcmFtcy5sb29wKSB7XHJcbiAgICAgIGxldCBzbGlkZUluZGV4ID0gYWN0aXZlSW5kZXggLSBzd2lwZXIudmlydHVhbC5zbGlkZXNCZWZvcmU7XHJcbiAgICAgIGlmIChzbGlkZUluZGV4IDwgMCkgc2xpZGVJbmRleCA9IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggKyBzbGlkZUluZGV4O1xyXG4gICAgICBpZiAoc2xpZGVJbmRleCA+PSBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoKSBzbGlkZUluZGV4IC09IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGg7XHJcbiAgICAgIGFjdGl2ZVNsaWRlID0gZ2V0RmlsdGVyZWRTbGlkZShgW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtzbGlkZUluZGV4fVwiXWApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZlU2xpZGUgPSBnZXRGaWx0ZXJlZFNsaWRlKGBbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke2FjdGl2ZUluZGV4fVwiXWApO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBhY3RpdmVTbGlkZSA9IHNsaWRlc1thY3RpdmVJbmRleF07XHJcbiAgfVxyXG4gIGlmIChhY3RpdmVTbGlkZSkge1xyXG4gICAgLy8gQWN0aXZlIGNsYXNzZXNcclxuICAgIGFjdGl2ZVNsaWRlLmNsYXNzTGlzdC5hZGQocGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MpO1xyXG5cclxuICAgIC8vIE5leHQgU2xpZGVcclxuICAgIGxldCBuZXh0U2xpZGUgPSBlbGVtZW50TmV4dEFsbChhY3RpdmVTbGlkZSwgYC4ke3BhcmFtcy5zbGlkZUNsYXNzfSwgc3dpcGVyLXNsaWRlYClbMF07XHJcbiAgICBpZiAocGFyYW1zLmxvb3AgJiYgIW5leHRTbGlkZSkge1xyXG4gICAgICBuZXh0U2xpZGUgPSBzbGlkZXNbMF07XHJcbiAgICB9XHJcbiAgICBpZiAobmV4dFNsaWRlKSB7XHJcbiAgICAgIG5leHRTbGlkZS5jbGFzc0xpc3QuYWRkKHBhcmFtcy5zbGlkZU5leHRDbGFzcyk7XHJcbiAgICB9XHJcbiAgICAvLyBQcmV2IFNsaWRlXHJcbiAgICBsZXQgcHJldlNsaWRlID0gZWxlbWVudFByZXZBbGwoYWN0aXZlU2xpZGUsIGAuJHtwYXJhbXMuc2xpZGVDbGFzc30sIHN3aXBlci1zbGlkZWApWzBdO1xyXG4gICAgaWYgKHBhcmFtcy5sb29wICYmICFwcmV2U2xpZGUgPT09IDApIHtcclxuICAgICAgcHJldlNsaWRlID0gc2xpZGVzW3NsaWRlcy5sZW5ndGggLSAxXTtcclxuICAgIH1cclxuICAgIGlmIChwcmV2U2xpZGUpIHtcclxuICAgICAgcHJldlNsaWRlLmNsYXNzTGlzdC5hZGQocGFyYW1zLnNsaWRlUHJldkNsYXNzKTtcclxuICAgIH1cclxuICB9XHJcbiAgc3dpcGVyLmVtaXRTbGlkZXNDbGFzc2VzKCk7XHJcbn1cclxuXHJcbmNvbnN0IHByb2Nlc3NMYXp5UHJlbG9hZGVyID0gKHN3aXBlciwgaW1hZ2VFbCkgPT4ge1xyXG4gIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5wYXJhbXMpIHJldHVybjtcclxuICBjb25zdCBzbGlkZVNlbGVjdG9yID0gKCkgPT4gKHN3aXBlci5pc0VsZW1lbnQgPyBgc3dpcGVyLXNsaWRlYCA6IGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9YCk7XHJcbiAgY29uc3Qgc2xpZGVFbCA9IGltYWdlRWwuY2xvc2VzdChzbGlkZVNlbGVjdG9yKCkpO1xyXG4gIGlmIChzbGlkZUVsKSB7XHJcbiAgICBjb25zdCBsYXp5RWwgPSBzbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoYC4ke3N3aXBlci5wYXJhbXMubGF6eVByZWxvYWRlckNsYXNzfWApO1xyXG4gICAgaWYgKGxhenlFbCkgbGF6eUVsLnJlbW92ZSgpO1xyXG4gIH1cclxufTtcclxuY29uc3QgdW5sYXp5ID0gKHN3aXBlciwgaW5kZXgpID0+IHtcclxuICBpZiAoIXN3aXBlci5zbGlkZXNbaW5kZXhdKSByZXR1cm47XHJcbiAgY29uc3QgaW1hZ2VFbCA9IHN3aXBlci5zbGlkZXNbaW5kZXhdLnF1ZXJ5U2VsZWN0b3IoJ1tsb2FkaW5nPVwibGF6eVwiXScpO1xyXG4gIGlmIChpbWFnZUVsKSBpbWFnZUVsLnJlbW92ZUF0dHJpYnV0ZSgnbG9hZGluZycpO1xyXG59O1xyXG5jb25zdCBwcmVsb2FkID0gKHN3aXBlcikgPT4ge1xyXG4gIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5wYXJhbXMpIHJldHVybjtcclxuICBsZXQgYW1vdW50ID0gc3dpcGVyLnBhcmFtcy5sYXp5UHJlbG9hZFByZXZOZXh0O1xyXG4gIGNvbnN0IGxlbiA9IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xyXG4gIGlmICghbGVuIHx8ICFhbW91bnQgfHwgYW1vdW50IDwgMCkgcmV0dXJuO1xyXG4gIGFtb3VudCA9IE1hdGgubWluKGFtb3VudCwgbGVuKTtcclxuICBjb25zdCBzbGlkZXNQZXJWaWV3ID1cclxuICAgIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nID8gc3dpcGVyLnNsaWRlc1BlclZpZXdEeW5hbWljKCkgOiBNYXRoLmNlaWwoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3KTtcclxuICBjb25zdCBhY3RpdmVJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleDtcclxuICBpZiAoc3dpcGVyLnBhcmFtcy5ncmlkICYmIHN3aXBlci5wYXJhbXMuZ3JpZC5yb3dzID4gMSkge1xyXG4gICAgY29uc3QgYWN0aXZlQ29sdW1uID0gYWN0aXZlSW5kZXg7XHJcbiAgICBjb25zdCBwcmVsb2FkQ29sdW1ucyA9IFthY3RpdmVDb2x1bW4gLSBhbW91bnRdO1xyXG4gICAgcHJlbG9hZENvbHVtbnMucHVzaChcclxuICAgICAgLi4uQXJyYXkuZnJvbSh7XHJcbiAgICAgICAgbGVuZ3RoOiBhbW91bnQsXHJcbiAgICAgIH0pLm1hcCgoXywgaSkgPT4ge1xyXG4gICAgICAgI
9266HJldHVybiBhY3RpdmVDb2x1bW4gKyBzbGlkZXNQZXJWaWV3ICsgaTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgICBzd2lwZXIuc2xpZGVzLmZvckVhY2goKHNsaWRlRWwsIGkpID0+IHtcclxuICAgICAgaWYgKHByZWxvYWRDb2x1bW5zLmluY2x1ZGVzKHNsaWRlRWwuY29sdW1uKSkgdW5sYXp5KHN3aXBlciwgaSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgY29uc3Qgc2xpZGVJbmRleExhc3RJblZpZXcgPSBhY3RpdmVJbmRleCArIHNsaWRlc1BlclZpZXcgLSAxO1xyXG4gIGlmIChzd2lwZXIucGFyYW1zLnJld2luZCB8fCBzd2lwZXIucGFyYW1zLmxvb3ApIHtcclxuICAgIGZvciAobGV0IGkgPSBhY3RpdmVJbmRleCAtIGFtb3VudDsgaSA8PSBzbGlkZUluZGV4TGFzdEluVmlldyArIGFtb3VudDsgaSArPSAxKSB7XHJcbiAgICAgIGNvbnN0IHJlYWxJbmRleCA9ICgoaSAlIGxlbikgKyBsZW4pICUgbGVuO1xyXG4gICAgICBpZiAocmVhbEluZGV4IDwgYWN0aXZlSW5kZXggfHwgcmVhbEluZGV4ID4gc2xpZGVJbmRleExhc3RJblZpZXcpIHVubGF6eShzd2lwZXIsIHJlYWxJbmRleCk7XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGZvciAobGV0IGkgPSBNYXRoLm1heChhY3RpdmVJbmRleCAtIGFtb3VudCwgMCk7IGkgPD0gTWF0aC5taW4oc2xpZGVJbmRleExhc3RJblZpZXcgKyBhbW91bnQsIGxlbiAtIDEpOyBpICs9IDEpIHtcclxuICAgICAgaWYgKGkgIT09IGFjdGl2ZUluZGV4ICYmIChpID4gc2xpZGVJbmRleExhc3RJblZpZXcgfHwgaSA8IGFjdGl2ZUluZGV4KSkge1xyXG4gICAgICAgIHVubGF6eShzd2lwZXIsIGkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuZnVuY3Rpb24gZ2V0QWN0aXZlSW5kZXhCeVRyYW5zbGF0ZShzd2lwZXIpIHtcclxuICBjb25zdCB7IHNsaWRlc0dyaWQsIHBhcmFtcyB9ID0gc3dpcGVyO1xyXG4gIGNvbnN0IHRyYW5zbGF0ZSA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGU7XHJcbiAgbGV0IGFjdGl2ZUluZGV4O1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzR3JpZC5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgaWYgKHR5cGVvZiBzbGlkZXNHcmlkW2kgKyAxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgaWYgKHRyYW5zbGF0ZSA+PSBzbGlkZXNHcmlkW2ldICYmIHRyYW5zbGF0ZSA8IHNsaWRlc0dyaWRbaSArIDFdIC0gKHNsaWRlc0dyaWRbaSArIDFdIC0gc2xpZGVzR3JpZFtpXSkgLyAyKSB7XHJcbiAgICAgICAgYWN0aXZlSW5kZXggPSBpO1xyXG4gICAgICB9IGVsc2UgaWYgKHRyYW5zbGF0ZSA+PSBzbGlkZXNHcmlkW2ldICYmIHRyYW5zbGF0ZSA8IHNsaWRlc0dyaWRbaSArIDFdKSB7XHJcbiAgICAgICAgYWN0aXZlSW5kZXggPSBpICsgMTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmICh0cmFuc2xhdGUgPj0gc2xpZGVzR3JpZFtpXSkge1xyXG4gICAgICBhY3RpdmVJbmRleCA9IGk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vIE5vcm1hbGl6ZSBzbGlkZUluZGV4XHJcbiAgaWYgKHBhcmFtcy5ub3JtYWxpemVTbGlkZUluZGV4KSB7XHJcbiAgICBpZiAoYWN0aXZlSW5kZXggPCAwIHx8IHR5cGVvZiBhY3RpdmVJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIGFjdGl2ZUluZGV4ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIGFjdGl2ZUluZGV4O1xyXG59XHJcbmZ1bmN0aW9uIHVwZGF0ZUFjdGl2ZUluZGV4KG5ld0FjdGl2ZUluZGV4KSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCB0cmFuc2xhdGUgPSBzd2lwZXIucnRsVHJhbnNsYXRlID8gc3dpcGVyLnRyYW5zbGF0ZSA6IC1zd2lwZXIudHJhbnNsYXRlO1xyXG4gIGNvbnN0IHtcclxuICAgIHNuYXBHcmlkLFxyXG4gICAgcGFyYW1zLFxyXG4gICAgYWN0aXZlSW5kZXg6IHByZXZpb3VzSW5kZXgsXHJcbiAgICByZWFsSW5kZXg6IHByZXZpb3VzUmVhbEluZGV4LFxyXG4gICAgc25hcEluZGV4OiBwcmV2aW91c1NuYXBJbmRleCxcclxuICB9ID0gc3dpcGVyO1xyXG4gIGxldCBhY3RpdmVJbmRleCA9IG5ld0FjdGl2ZUluZGV4O1xyXG4gIGxldCBzbmFwSW5kZXg7XHJcbiAgY29uc3QgZ2V0VmlydHVhbFJlYWxJbmRleCA9IChhSW5kZXgpID0+IHtcclxuICAgIGxldCByZWFsSW5kZXggPSBhSW5kZXggLSBzd2lwZXIudmlydHVhbC5zbGlkZXNCZWZvcmU7XHJcbiAgICBpZiAocmVhbEluZGV4IDwgMCkge1xyXG4gICAgICByZWFsSW5kZXggPSBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoICsgcmVhbEluZGV4O1xyXG4gICAgfVxyXG4gICAgaWYgKHJlYWxJbmRleCA+PSBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoKSB7XHJcbiAgICAgIHJlYWxJbmRleCAtPSBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlYWxJbmRleDtcclxuICB9O1xyXG4gIGlmICh0eXBlb2YgYWN0aXZlSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBhY3RpdmVJbmRleCA9IGdldEFjdGl2ZUluZGV4QnlUcmFuc2xhdGUoc3dpcGVyKTtcclxuICB9XHJcbiAgaWYgKHNuYXBHcmlkLmluZGV4T2YodHJhbnNsYXRlKSA+PSAwKSB7XHJcbiAgICBzbmFwSW5kZXggPSBzbmFwR3JpZC5pbmRleE9mKHRyYW5zbGF0ZSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIGNvbnN0IHNraXAgPSBNYXRoLm1pbihwYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwLCBhY3RpdmVJbmRleCk7XHJcbiAgICBzbmFwSW5kZXggPSBza2lwICsgTWF0aC5mbG9vcigoYWN0aXZlSW5kZXggLSBza2lwKSAvIHBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XHJcbiAgfVxyXG4gIGlmIChzbmFwSW5kZXggPj0gc25hcEdyaWQubGVuZ3RoKSBzbmFwSW5kZXggPSBzbmFwR3JpZC5sZW5ndGggLSAxO1xyXG4gIGlmIChhY3RpdmVJbmRleCA9PT0gcHJldmlvdXNJbmRleCkge1xyXG4gICAgaWYgKHNuYXBJbmRleCAhPT0gcHJldmlvdXNTbmFwSW5kZXgpIHtcclxuICAgICAgc3dpcGVyLnNuYXBJbmRleCA9IHNuYXBJbmRleDtcclxuICAgICAgc3dpcGVyLmVtaXQoJ3NuYXBJbmRleENoYW5nZScpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCAmJiBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICBzd2lwZXIucmVhbEluZGV4ID0gZ2V0VmlydHVhbFJlYWxJbmRleChhY3RpdmVJbmRleCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIC8vIEdldCByZWFsIGluZGV4XHJcbiAgbGV0IHJlYWxJbmRleDtcclxuICBpZiAoc3dpcGVyLnZpcnR1YWwgJiYgcGFyYW1zLnZpcnR1YWwuZW5hYmxlZCAmJiBwYXJhbXMubG9vcCkge1xyXG4gICAgcmVhbEluZGV4ID0gZ2V0VmlydHVhbFJlYWxJbmRleChhY3RpdmVJbmRleCk7XHJcbiAgfSBlbHNlIGlmIChzd2lwZXIuc2xpZGVzW2FjdGl2ZUluZGV4XSkge1xyXG4gICAgcmVhbEluZGV4ID0gcGFyc2VJbnQoc3dpcGVyLnNsaWRlc1thY3RpdmVJbmRleF0uZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpIHx8IGFjdGl2ZUluZGV4LCAxMCk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJlYWxJbmRleCA9IGFjdGl2ZUluZGV4O1xyXG4gIH1cclxuICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xyXG4gICAgcHJldmlvdXNTbmFwSW5kZXgsXHJcbiAgICBzbmFwSW5kZXgsXHJcbiAgICBwcmV2aW91c1JlYWxJbmRleCxcclxuICAgIHJlYWxJbmRleCxcclxuICAgIHByZXZpb3VzSW5kZXgsXHJcbiAgICBhY3RpdmVJbmRleCxcclxuICB9KTtcclxuICBpZiAoc3dpcGVyLmluaXRpYWxpemVkKSB7XHJcbiAgICBwcmVsb2FkKHN3aXBlcik7XHJcbiAgfVxyXG4gIHN3aXBlci5lbWl0KCdhY3RpdmVJbmRleENoYW5nZScpO1xyXG4gIHN3aXBlci5lbWl0KCdzbmFwSW5kZXhDaGFuZ2UnKTtcclxuICBpZiAocHJldmlvdXNSZWFsSW5kZXggIT09IHJlYWxJbmRleCkge1xyXG4gICAgc3dpcGVyLmVtaXQoJ3JlYWxJbmRleENoYW5nZScpO1xyXG4gIH1cclxuICBpZiAoc3dpcGVyLmluaXRpYWxpemVkIHx8IHN3aXBlci5wYXJhbXMucnVuQ2FsbGJhY2tzT25Jbml0KSB7XHJcbiAgICBzd2lwZXIuZW1pdCgnc2xpZGVDaGFuZ2UnKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUNsaWNrZWRTbGlkZShlKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xyXG4gIGNvbnN0IHNsaWRlID0gZS5jbG9zZXN0KGAuJHtwYXJhbXMuc2xpZGVDbGFzc30sIHN3aXBlci1zbGlkZWApO1xyXG4gIGxldCBzbGlkZUZvdW5kID0gZmFsc2U7XHJcbiAgbGV0IHNsaWRlSW5kZXg7XHJcbiAgaWYgKHNsaWRlKSB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN3aXBlci5zbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgaWYgKHN3aXBlci5zbGlkZXNbaV0gPT09IHNsaWRlKSB7XHJcbiAgICAgICAgc2xpZGVGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgc2xpZGVJbmRleCA9IG
9266k7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgaWYgKHNsaWRlICYmIHNsaWRlRm91bmQpIHtcclxuICAgIHN3aXBlci5jbGlja2VkU2xpZGUgPSBzbGlkZTtcclxuICAgIGlmIChzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gcGFyc2VJbnQoc2xpZGUuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gc2xpZGVJbmRleDtcclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgc3dpcGVyLmNsaWNrZWRTbGlkZSA9IHVuZGVmaW5lZDtcclxuICAgIHN3aXBlci5jbGlja2VkSW5kZXggPSB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuc2xpZGVUb0NsaWNrZWRTbGlkZSAmJiBzd2lwZXIuY2xpY2tlZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgc3dpcGVyLmNsaWNrZWRJbmRleCAhPT0gc3dpcGVyLmFjdGl2ZUluZGV4KSB7XHJcbiAgICBzd2lwZXIuc2xpZGVUb0NsaWNrZWRTbGlkZSgpO1xyXG4gIH1cclxufVxyXG5cclxudmFyIHVwZGF0ZSA9IHtcclxuICB1cGRhdGVTaXplLFxyXG4gIHVwZGF0ZVNsaWRlcyxcclxuICB1cGRhdGVBdXRvSGVpZ2h0LFxyXG4gIHVwZGF0ZVNsaWRlc09mZnNldCxcclxuICB1cGRhdGVTbGlkZXNQcm9ncmVzcyxcclxuICB1cGRhdGVQcm9ncmVzcyxcclxuICB1cGRhdGVTbGlkZXNDbGFzc2VzLFxyXG4gIHVwZGF0ZUFjdGl2ZUluZGV4LFxyXG4gIHVwZGF0ZUNsaWNrZWRTbGlkZSxcclxufTtcclxuXHJcbmZ1bmN0aW9uIGdldFN3aXBlclRyYW5zbGF0ZShheGlzKSB7XHJcbiAgaWYgKGF4aXMgPT09IHZvaWQgMCkge1xyXG4gICAgYXhpcyA9IHRoaXMuaXNIb3Jpem9udGFsKCkgPyAneCcgOiAneSc7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHJ0bFRyYW5zbGF0ZTogcnRsLCB0cmFuc2xhdGUsIHdyYXBwZXJFbCB9ID0gc3dpcGVyO1xyXG4gIGlmIChwYXJhbXMudmlydHVhbFRyYW5zbGF0ZSkge1xyXG4gICAgcmV0dXJuIHJ0bCA/IC10cmFuc2xhdGUgOiB0cmFuc2xhdGU7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgcmV0dXJuIHRyYW5zbGF0ZTtcclxuICB9XHJcbiAgbGV0IGN1cnJlbnRUcmFuc2xhdGUgPSBnZXRUcmFuc2xhdGUod3JhcHBlckVsLCBheGlzKTtcclxuICBjdXJyZW50VHJhbnNsYXRlICs9IHN3aXBlci5jc3NPdmVyZmxvd0FkanVzdG1lbnQoKTtcclxuICBpZiAocnRsKSBjdXJyZW50VHJhbnNsYXRlID0gLWN1cnJlbnRUcmFuc2xhdGU7XHJcbiAgcmV0dXJuIGN1cnJlbnRUcmFuc2xhdGUgfHwgMDtcclxufVxyXG5cclxuZnVuY3Rpb24gc2V0VHJhbnNsYXRlKHRyYW5zbGF0ZSwgYnlDb250cm9sbGVyKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCB7IHJ0bFRyYW5zbGF0ZTogcnRsLCBwYXJhbXMsIHdyYXBwZXJFbCwgcHJvZ3Jlc3MgfSA9IHN3aXBlcjtcclxuICBsZXQgeCA9IDA7XHJcbiAgbGV0IHkgPSAwO1xyXG4gIGNvbnN0IHogPSAwO1xyXG4gIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcclxuICAgIHggPSBydGwgPyAtdHJhbnNsYXRlIDogdHJhbnNsYXRlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICB5ID0gdHJhbnNsYXRlO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykge1xyXG4gICAgeCA9IE1hdGguZmxvb3IoeCk7XHJcbiAgICB5ID0gTWF0aC5mbG9vcih5KTtcclxuICB9XHJcbiAgc3dpcGVyLnByZXZpb3VzVHJhbnNsYXRlID0gc3dpcGVyLnRyYW5zbGF0ZTtcclxuICBzd2lwZXIudHJhbnNsYXRlID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8geCA6IHk7XHJcbiAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICB3cmFwcGVyRWxbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gLXggOiAteTtcclxuICB9IGVsc2UgaWYgKCFwYXJhbXMudmlydHVhbFRyYW5zbGF0ZSkge1xyXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgICB4IC09IHN3aXBlci5jc3NPdmVyZmxvd0FkanVzdG1lbnQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHkgLT0gc3dpcGVyLmNzc092ZXJmbG93QWRqdXN0bWVudCgpO1xyXG4gICAgfVxyXG4gICAgd3JhcHBlckVsLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgke3h9cHgsICR7eX1weCwgJHt6fXB4KWA7XHJcbiAgfVxyXG5cclxuICAvLyBDaGVjayBpZiB3ZSBuZWVkIHRvIHVwZGF0ZSBwcm9ncmVzc1xyXG4gIGxldCBuZXdQcm9ncmVzcztcclxuICBjb25zdCB0cmFuc2xhdGVzRGlmZiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKTtcclxuICBpZiAodHJhbnNsYXRlc0RpZmYgPT09IDApIHtcclxuICAgIG5ld1Byb2dyZXNzID0gMDtcclxuICB9IGVsc2Uge1xyXG4gICAgbmV3UHJvZ3Jlc3MgPSAodHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAvIHRyYW5zbGF0ZXNEaWZmO1xyXG4gIH1cclxuICBpZiAobmV3UHJvZ3Jlc3MgIT09IHByb2dyZXNzKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3ModHJhbnNsYXRlKTtcclxuICB9XHJcbiAgc3dpcGVyLmVtaXQoJ3NldFRyYW5zbGF0ZScsIHN3aXBlci50cmFuc2xhdGUsIGJ5Q29udHJvbGxlcik7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG1pblRyYW5zbGF0ZSgpIHtcclxuICByZXR1cm4gLXRoaXMuc25hcEdyaWRbMF07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG1heFRyYW5zbGF0ZSgpIHtcclxuICByZXR1cm4gLXRoaXMuc25hcEdyaWRbdGhpcy5zbmFwR3JpZC5sZW5ndGggLSAxXTtcclxufVxyXG5cclxuZnVuY3Rpb24gdHJhbnNsYXRlVG8odHJhbnNsYXRlLCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCB0cmFuc2xhdGVCb3VuZHMsIGludGVybmFsKSB7XHJcbiAgaWYgKHRyYW5zbGF0ZSA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICB0cmFuc2xhdGUgPSAwO1xyXG4gIH1cclxuICBpZiAoc3BlZWQgPT09IHZvaWQgMCkge1xyXG4gICAgc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZDtcclxuICB9XHJcbiAgaWYgKHJ1bkNhbGxiYWNrcyA9PT0gdm9pZCAwKSB7XHJcbiAgICBydW5DYWxsYmFja3MgPSB0cnVlO1xyXG4gIH1cclxuICBpZiAodHJhbnNsYXRlQm91bmRzID09PSB2b2lkIDApIHtcclxuICAgIHRyYW5zbGF0ZUJvdW5kcyA9IHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHdyYXBwZXJFbCB9ID0gc3dpcGVyO1xyXG4gIGlmIChzd2lwZXIuYW5pbWF0aW5nICYmIHBhcmFtcy5wcmV2ZW50SW50ZXJhY3Rpb25PblRyYW5zaXRpb24pIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgY29uc3QgbWluVHJhbnNsYXRlID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xyXG4gIGNvbnN0IG1heFRyYW5zbGF0ZSA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcclxuICBsZXQgbmV3VHJhbnNsYXRlO1xyXG4gIGlmICh0cmFuc2xhdGVCb3VuZHMgJiYgdHJhbnNsYXRlID4gbWluVHJhbnNsYXRlKSBuZXdUcmFuc2xhdGUgPSBtaW5UcmFuc2xhdGU7XHJcbiAgZWxzZSBpZiAodHJhbnNsYXRlQm91bmRzICYmIHRyYW5zbGF0ZSA8IG1heFRyYW5zbGF0ZSkgbmV3VHJhbnNsYXRlID0gbWF4VHJhbnNsYXRlO1xyXG4gIGVsc2UgbmV3VHJhbnNsYXRlID0gdHJhbnNsYXRlO1xyXG5cclxuICAvLyBVcGRhdGUgcHJvZ3Jlc3NcclxuICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MobmV3VHJhbnNsYXRlKTtcclxuICBpZiAocGFyYW1zLmNzc01vZGUpIHtcclxuICAgIGNvbnN0IGlzSCA9IHN3aXBlci5pc0hvcml6b250YWwoKTtcclxuICAgIGlmIChzcGVlZCA9PT0gMCkge1xyXG4gICAgICB3cmFwcGVyRWxbaXNIID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gLW5ld1RyYW5zbGF0ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghc3dpcGVyLnN1cHBvcnQuc21vb3RoU2Nyb2xsKSB7XHJcbiAgICAgICAgYW5pbWF0ZUNTU01vZGVTY3JvbGwoe1xyXG4gICAgICAgICAgc3dpcGVyLFxyXG4gICAgICAgICAgdGFyZ2V0UG9zaXRpb246IC1uZXdUcmFuc2xhdGUsXHJcbiAgICAgICAgICBzaWRlOiBpc0ggPyAnbGVmdCcgOiAndG9wJyxcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgICB3cmFwcGVyRWwuc2Nyb2xsVG8oe1xyXG4gICAgICAgIFtpc0ggPyAnbGVmdCcgOiAndG9wJ106IC1uZXdUcmFuc2xhdGUsXHJcbiAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuICBpZiAoc3BlZWQgPT09IDApIHtcclxuICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKDApO1xyXG4gICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdUcmFuc2xhdGUpO1xyXG4gICAgaWYgKHJ1bkNhbGxiYWNrcykge1xyXG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcclxuICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25FbmQnKTtcclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3BlZWQpO1xyXG4gICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdUcmFuc2xhdGUpO1xyXG4gICAgaWYgKHJ1bkNhbGxiYWNrcykge1xyXG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcclxuICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25TdGFydCcpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFzd2lwZXIuYW5pbWF0aW5nKSB7XHJcbiAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgICBpZiAoIXN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpIHtcclxuICAgICAgICBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kID0gZnVuY3Rpb24gdHJhbnNpdGlvbkVuZChlKSB7XHJcbiAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XHJcbiAgICAgICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcclxuICAgICAgICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xyXG4gICAgICAgICAgc3dpcGVyLm9uVHJhbnNsYXRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IG51bGw7XHJcbiAgICAgICAgICBkZWxldGUgc3dpcGVyLm9uVHJhbnNsYXRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZDtcclxuICAgICAgICAgIGlmIChydW5DYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25FbmQnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gdHJ1ZTtcclxufVxyXG5cclxudmFyIHRyYW5zbGF0ZSA9IHtcclxuICBnZXRUcmFuc2xhdGU6IGdldFN3aXBlclRyYW5zbGF0ZSxcclxuICBzZXRUcmFuc2xhdGUsXHJcbiAgbWluVHJhbnNsYXRlLFxyXG4gIG1heFRyYW5zbGF0ZSxcclxuICB0cmFuc2xhdGVUbyxcclxufTtcclxuXHJcbmZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcikge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgaWYgKCFzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7ZHVyYXRpb259bXNgO1xyXG4gIH1cclxuICBzd2lwZXIuZW1pdCgnc2V0VHJhbnNpdGlvbicsIGR1cmF0aW9uLCBieUNvbnRyb2xsZXIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0cmFuc2l0aW9uRW1pdChfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBydW5DYWxsYmFja3MsIGRpcmVjdGlvbiwgc3RlcCB9ID0gX3JlZjtcclxuICBjb25zdCB7IGFjdGl2ZUluZGV4LCBwcmV2aW91c0luZGV4IH0gPSBzd2lwZXI7XHJcbiAgbGV0IGRpciA9IGRpcmVjdGlvbjtcclxuICBpZiAoIWRpcikge1xyXG4gICAgaWYgKGFjdGl2ZUluZGV4ID4gcHJldmlvdXNJbmRleCkgZGlyID0gJ25leHQnO1xyXG4gICAgZWxzZSBpZiAoYWN0aXZlSW5kZXggPCBwcmV2aW91c0luZGV4KSBkaXIgPSAncHJldic7XHJcbiAgICBlbHNlIGRpciA9ICdyZXNldCc7XHJcbiAgfVxyXG4gIHN3aXBlci5lbWl0KGB0cmFuc2l0aW9uJHtzdGVwfWApO1xyXG4gIGlmIChydW5DYWxsYmFja3MgJiYgYWN0aXZlSW5kZXggIT09IHByZXZpb3VzSW5kZXgpIHtcclxuICAgIGlmIChkaXIgPT09ICdyZXNldCcpIHtcclxuICAgICAgc3dpcGVyLmVtaXQoYHNsaWRlUmVzZXRUcmFuc2l0aW9uJHtzdGVwfWApO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuZW1pdChgc2xpZGVDaGFuZ2VUcmFuc2l0aW9uJHtzdGVwfWApO1xyXG4gICAgaWYgKGRpciA9PT0gJ25leHQnKSB7XHJcbiAgICAgIHN3aXBlci5lbWl0KGBzbGlkZU5leHRUcmFuc2l0aW9uJHtzdGVwfWApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLmVtaXQoYHNsaWRlUHJldlRyYW5zaXRpb24ke3N0ZXB9YCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB0cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pIHtcclxuICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcclxuICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMgfSA9IHN3aXBlcjtcclxuICBpZiAocGFyYW1zLmNzc01vZGUpIHJldHVybjtcclxuICBpZiAocGFyYW1zLmF1dG9IZWlnaHQpIHtcclxuICAgIHN3aXBlci51cGRhdGVBdXRvSGVpZ2h0KCk7XHJcbiAgfVxyXG4gIHRyYW5zaXRpb25FbWl0KHtcclxuICAgIHN3aXBlcixcclxuICAgIHJ1bkNhbGxiYWNrcyxcclxuICAgIGRpcmVjdGlvbixcclxuICAgIHN0ZXA6ICdTdGFydCcsXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRyYW5zaXRpb25FbmQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pIHtcclxuICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcclxuICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMgfSA9IHN3aXBlcjtcclxuICBzd2lwZXIuYW5pbWF0aW5nID0gZmFsc2U7XHJcbiAgaWYgKHBhcmFtcy5jc3NNb2RlKSByZXR1cm47XHJcbiAgc3dpcGVyLnNldFRyYW5zaXRpb24oMCk7XHJcbiAgdHJhbnNpdGlvbkVtaXQoe1xyXG4gICAgc3dpcGVyLFxyXG4gICAgcnVuQ2FsbGJhY2tzLF
9266xyXG4gICAgZGlyZWN0aW9uLFxyXG4gICAgc3RlcDogJ0VuZCcsXHJcbiAgfSk7XHJcbn1cclxuXHJcbnZhciB0cmFuc2l0aW9uID0ge1xyXG4gIHNldFRyYW5zaXRpb24sXHJcbiAgdHJhbnNpdGlvblN0YXJ0LFxyXG4gIHRyYW5zaXRpb25FbmQsXHJcbn07XHJcblxyXG5mdW5jdGlvbiBzbGlkZVRvKGluZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCwgaW5pdGlhbCkge1xyXG4gIGlmIChpbmRleCA9PT0gdm9pZCAwKSB7XHJcbiAgICBpbmRleCA9IDA7XHJcbiAgfVxyXG4gIGlmIChzcGVlZCA9PT0gdm9pZCAwKSB7XHJcbiAgICBzcGVlZCA9IHRoaXMucGFyYW1zLnNwZWVkO1xyXG4gIH1cclxuICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcclxuICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgaW5kZXggPT09ICdzdHJpbmcnKSB7XHJcbiAgICBpbmRleCA9IHBhcnNlSW50KGluZGV4LCAxMCk7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgbGV0IHNsaWRlSW5kZXggPSBpbmRleDtcclxuICBpZiAoc2xpZGVJbmRleCA8IDApIHNsaWRlSW5kZXggPSAwO1xyXG4gIGNvbnN0IHsgcGFyYW1zLCBzbmFwR3JpZCwgc2xpZGVzR3JpZCwgcHJldmlvdXNJbmRleCwgYWN0aXZlSW5kZXgsIHJ0bFRyYW5zbGF0ZTogcnRsLCB3cmFwcGVyRWwsIGVuYWJsZWQgfSA9IHN3aXBlcjtcclxuICBpZiAoKHN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLnByZXZlbnRJbnRlcmFjdGlvbk9uVHJhbnNpdGlvbikgfHwgKCFlbmFibGVkICYmICFpbnRlcm5hbCAmJiAhaW5pdGlhbCkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgY29uc3Qgc2tpcCA9IE1hdGgubWluKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwLCBzbGlkZUluZGV4KTtcclxuICBsZXQgc25hcEluZGV4ID0gc2tpcCArIE1hdGguZmxvb3IoKHNsaWRlSW5kZXggLSBza2lwKSAvIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xyXG4gIGlmIChzbmFwSW5kZXggPj0gc25hcEdyaWQubGVuZ3RoKSBzbmFwSW5kZXggPSBzbmFwR3JpZC5sZW5ndGggLSAxO1xyXG4gIGNvbnN0IHRyYW5zbGF0ZSA9IC1zbmFwR3JpZFtzbmFwSW5kZXhdO1xyXG4gIC8vIE5vcm1hbGl6ZSBzbGlkZUluZGV4XHJcbiAgaWYgKHBhcmFtcy5ub3JtYWxpemVTbGlkZUluZGV4KSB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlc0dyaWQubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgY29uc3Qgbm9ybWFsaXplZFRyYW5zbGF0ZSA9IC1NYXRoLmZsb29yKHRyYW5zbGF0ZSAqIDEwMCk7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRHcmlkID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkW2ldICogMTAwKTtcclxuICAgICAgY29uc3Qgbm9ybWFsaXplZEdyaWROZXh0ID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkW2kgKyAxXSAqIDEwMCk7XHJcbiAgICAgIGlmICh0eXBlb2Ygc2xpZGVzR3JpZFtpICsgMV0gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgbm9ybWFsaXplZFRyYW5zbGF0ZSA+PSBub3JtYWxpemVkR3JpZCAmJlxyXG4gICAgICAgICAgbm9ybWFsaXplZFRyYW5zbGF0ZSA8IG5vcm1hbGl6ZWRHcmlkTmV4dCAtIChub3JtYWxpemVkR3JpZE5leHQgLSBub3JtYWxpemVkR3JpZCkgLyAyXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBzbGlkZUluZGV4ID0gaTtcclxuICAgICAgICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUcmFuc2xhdGUgPj0gbm9ybWFsaXplZEdyaWQgJiYgbm9ybWFsaXplZFRyYW5zbGF0ZSA8IG5vcm1hbGl6ZWRHcmlkTmV4dCkge1xyXG4gICAgICAgICAgc2xpZGVJbmRleCA9IGkgKyAxO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmIChub3JtYWxpemVkVHJhbnNsYXRlID49IG5vcm1hbGl6ZWRHcmlkKSB7XHJcbiAgICAgICAgc2xpZGVJbmRleCA9IGk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgLy8gRGlyZWN0aW9ucyBsb2Nrc1xyXG4gIGlmIChzd2lwZXIuaW5pdGlhbGl6ZWQgJiYgc2xpZGVJbmRleCAhPT0gYWN0aXZlSW5kZXgpIHtcclxuICAgIGlmIChcclxuICAgICAgIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJlxyXG4gICAgICAocnRsXHJcbiAgICAgICAgPyB0cmFuc2xhdGUgPiBzd2lwZXIudHJhbnNsYXRlICYmIHRyYW5zbGF0ZSA+IHN3aXBlci5taW5UcmFuc2xhdGUoKVxyXG4gICAgICAgIDogdHJhbnNsYXRlIDwgc3dpcGVyLnRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUgPCBzd2lwZXIubWluVHJhbnNsYXRlKCkpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKCFzd2lwZXIuYWxsb3dTbGlkZVByZXYgJiYgdHJhbnNsYXRlID4gc3dpcGVyLnRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUgPiBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHtcclxuICAgICAgaWYgKChhY3RpdmVJbmRleCB8fCAwKSAhPT0gc2xpZGVJbmRleCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoc2xpZGVJbmRleCAhPT0gKHByZXZpb3VzSW5kZXggfHwgMCkgJiYgcnVuQ2FsbGJhY2tzKSB7XHJcbiAgICBzd2lwZXIuZW1pdCgnYmVmb3JlU2xpZGVDaGFuZ2VTdGFydCcpO1xyXG4gIH1cclxuXHJcbiAgLy8gVXBkYXRlIHByb2dyZXNzXHJcbiAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKHRyYW5zbGF0ZSk7XHJcbiAgbGV0IGRpcmVjdGlvbjtcclxuICBpZiAoc2xpZGVJbmRleCA+IGFjdGl2ZUluZGV4KSBkaXJlY3Rpb24gPSAnbmV4dCc7XHJcbiAgZWxzZSBpZiAoc2xpZGVJbmRleCA8IGFjdGl2ZUluZGV4KSBkaXJlY3Rpb24gPSAncHJldic7XHJcbiAgZWxzZSBkaXJlY3Rpb24gPSAncmVzZXQnO1xyXG5cclxuICAvLyBVcGRhdGUgSW5kZXhcclxuICBpZiAoKHJ0bCAmJiAtdHJhbnNsYXRlID09PSBzd2lwZXIudHJhbnNsYXRlKSB8fCAoIXJ0bCAmJiB0cmFuc2xhdGUgPT09IHN3aXBlci50cmFuc2xhdGUpKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoc2xpZGVJbmRleCk7XHJcbiAgICAvLyBVcGRhdGUgSGVpZ2h0XHJcbiAgICBpZiAocGFyYW1zLmF1dG9IZWlnaHQpIHtcclxuICAgICAgc3dpcGVyLnVwZGF0ZUF1dG9IZWlnaHQoKTtcclxuICAgIH1cclxuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XHJcbiAgICBpZiAocGFyYW1zLmVmZmVjdCAhPT0gJ3NsaWRlJykge1xyXG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHRyYW5zbGF0ZSk7XHJcbiAgICB9XHJcbiAgICBpZiAoZGlyZWN0aW9uICE9PSAncmVzZXQnKSB7XHJcbiAgICAgIHN3aXBlci50cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pO1xyXG4gICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZChydW5DYWxsYmFja3MsIGRpcmVjdGlvbik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgY29uc3QgaXNIID0gc3dpcGVyLmlzSG9yaXpvbn
9266RhbCgpO1xyXG4gICAgY29uc3QgdCA9IHJ0bCA/IHRyYW5zbGF0ZSA6IC10cmFuc2xhdGU7XHJcbiAgICBpZiAoc3BlZWQgPT09IDApIHtcclxuICAgICAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQ7XHJcbiAgICAgIGlmIChpc1ZpcnR1YWwpIHtcclxuICAgICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLnNjcm9sbFNuYXBUeXBlID0gJ25vbmUnO1xyXG4gICAgICAgIHN3aXBlci5faW1tZWRpYXRlVmlydHVhbCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGlzVmlydHVhbCAmJiAhc3dpcGVyLl9jc3NNb2RlVmlydHVhbEluaXRpYWxTZXQgJiYgc3dpcGVyLnBhcmFtcy5pbml0aWFsU2xpZGUgPiAwKSB7XHJcbiAgICAgICAgc3dpcGVyLl9jc3NNb2RlVmlydHVhbEluaXRpYWxTZXQgPSB0cnVlO1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICB3cmFwcGVyRWxbaXNIID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gdDtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB3cmFwcGVyRWxbaXNIID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAoaXNWaXJ0dWFsKSB7XHJcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUuc2Nyb2xsU25hcFR5cGUgPSAnJztcclxuICAgICAgICAgIHN3aXBlci5faW1tZWRpYXRlVmlydHVhbCA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoIXN3aXBlci5zdXBwb3J0LnNtb290aFNjcm9sbCkge1xyXG4gICAgICAgIGFuaW1hdGVDU1NNb2RlU2Nyb2xsKHtcclxuICAgICAgICAgIHN3aXBlcixcclxuICAgICAgICAgIHRhcmdldFBvc2l0aW9uOiB0LFxyXG4gICAgICAgICAgc2lkZTogaXNIID8gJ2xlZnQnIDogJ3RvcCcsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgd3JhcHBlckVsLnNjcm9sbFRvKHtcclxuICAgICAgICBbaXNIID8gJ2xlZnQnIDogJ3RvcCddOiB0LFxyXG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcbiAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3BlZWQpO1xyXG4gIHN3aXBlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlKTtcclxuICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoc2xpZGVJbmRleCk7XHJcbiAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcclxuICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcclxuICBzd2lwZXIudHJhbnNpdGlvblN0YXJ0KHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcclxuICBpZiAoc3BlZWQgPT09IDApIHtcclxuICAgIHN3aXBlci50cmFuc2l0aW9uRW5kKHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcclxuICB9IGVsc2UgaWYgKCFzd2lwZXIuYW5pbWF0aW5nKSB7XHJcbiAgICBzd2lwZXIuYW5pbWF0aW5nID0gdHJ1ZTtcclxuICAgIGlmICghc3dpcGVyLm9uU2xpZGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKSB7XHJcbiAgICAgIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoZSkge1xyXG4gICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcclxuICAgICAgICBzd2lwZXIud3JhcHBlckVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xyXG4gICAgICAgIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IG51bGw7XHJcbiAgICAgICAgZGVsZXRlIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZDtcclxuICAgICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZChydW5DYWxsYmFja3MsIGRpcmVjdGlvbik7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgICBzd2lwZXIud3JhcHBlckVsLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xyXG4gIH1cclxuICByZXR1cm4gdHJ1ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2xpZGVUb0xvb3AoaW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKSB7XHJcbiAgaWYgKGluZGV4ID09PSB2b2lkIDApIHtcclxuICAgIGluZGV4ID0gMDtcclxuICB9XHJcbiAgaWYgKHNwZWVkID09PSB2b2lkIDApIHtcclxuICAgIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQ7XHJcbiAgfVxyXG4gIGlmIChydW5DYWxsYmFja3MgPT09IHZvaWQgMCkge1xyXG4gICAgcnVuQ2FsbGJhY2tzID0gdHJ1ZTtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiBpbmRleCA9PT0gJ3N0cmluZycpIHtcclxuICAgIGNvbnN0IGluZGV4QXNOdW1iZXIgPSBwYXJzZUludChpbmRleCwgMTApO1xyXG4gICAgaW5kZXggPSBpbmRleEFzTnVtYmVyO1xyXG4gIH1cclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGxldCBuZXdJbmRleCA9IGluZGV4O1xyXG4gIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcclxuICAgIGlmIChzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgICAgbmV3SW5kZXggPSBuZXdJbmRleCArIHN3aXBlci52aXJ0dWFsLnNsaWRlc0JlZm9yZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5ld0luZGV4ID0gc3dpcGVyLmdldFNsaWRlSW5kZXhCeURhdGEobmV3SW5kZXgpO1xyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8obmV3SW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcclxufVxyXG5cclxuLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXHJcbmZ1bmN0aW9uIHNsaWRlTmV4dChzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCkge1xyXG4gIGlmIChzcGVlZCA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICBzcGVlZCA9IHRoaXMucGFyYW1zLnNwZWVkO1xyXG4gIH1cclxuICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcclxuICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBlbmFibGVkLCBwYXJhbXMsIGFuaW1hdGluZyB9ID0gc3dpcGVyO1xyXG4gIGlmICghZW5hYmxlZCkgcmV0dXJuIHN3aXBlcjtcclxuICBsZXQgcGVyR3JvdXAgPSBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XHJcbiAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycgJiYgcGFyYW1zLnNsaWRlc1Blckdyb3VwID09PSAxICYmIHBhcmFtcy5zbGlkZXNQZXJHcm91cEF1dG8pIHtcclxuICAgIHBlckdyb3VwID0gTWF0aC5tYXgoc3dpcGVyLnNsaWRlc1BlclZpZXdEeW5hbWljKCdjdXJyZW50JywgdHJ1ZSksIDEpO1xyXG4gIH1cclxuICBjb25zdCBpbmNyZW1lbnQgPSBzd2lwZXIuYWN0aXZlSW5kZXggPCBwYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwID8gMSA6IHBlckdyb3VwO1xyXG4gIGNvbnN0IGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHBhcmFtcy52aXJ0dWFsLmVuYWJsZWQ7XHJcbiAgaWYgKHBhcmFtcy5sb29wKSB7XHJcbiAgICBpZiAoYW5pbWF0aW5nICYmICFpc1ZpcnR1YWwgJiYgcGFyYW1zLmxvb3BQcmV2ZW50c1NsaWRpbmcpIHJldHVybiBmYWxzZTtcclxuICAgIHN3aXBlci5sb29wRml4KHtcclxuICAgICAgZGlyZWN0aW9uOiAnbmV4dCcsXHJcbiAgICB9KTtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxyXG4gICAgc3dpcGVyLl9jbGllbnRMZWZ0ID0gc3dpcGVyLndyYXBwZXJFbC5jbGllbnRMZWZ0O1xyXG4gIH1cclxuICBpZiAocGFyYW1zLnJld2luZCAmJiBzd2lwZXIuaXNFbmQpIHtcclxuICAgIHJldHVybiBzd2lwZXIuc2xpZGVUbygwLCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XHJcbiAgfVxyXG4gIHJldHVybiBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXggKyBpbmNyZW1lbnQsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcclxufVxyXG5cclxuLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXHJcbmZ1bmN0aW9uIHNsaWRlUHJldihzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCkge1xyXG4gIGlmIChzcGVlZCA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICBzcGVlZCA9IHRoaXMucGFyYW1zLnNwZWVkO1xyXG4gIH1cclxuICBpZiAocnVuQ2FsbGJhY2tzID09PSB2b2lkIDApIHtcclxuICAgIHJ1bkNhbGxiYWNrcyA9IHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHNuYXBHcmlkLCBzbGlkZXNHcmlkLCBydGxUcmFuc2xhdGUsIGVuYWJsZWQsIGFuaW1hdGluZyB9ID0gc3dpcGVyO1xyXG4gIGlmICghZW5hYmxlZCkgcmV0dXJuIHN3aXBlcjtcclxuICBjb25zdCBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBwYXJhbXMudmlydHVhbC5lbmFibGVkO1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgaWYgKGFuaW1hdGluZyAmJiAhaXNWaXJ0dWFsICYmIHBhcmFtcy5sb29wUHJldmVudHNTbGlkaW5nKSByZXR1cm4gZmFsc2U7XHJcbiAgICBzd2lwZXIubG9vcEZpeCh7XHJcbiAgICAgIGRpcmVjdGlvbjogJ3ByZXYnLFxyXG4gICAgfSk7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgIHN3aXBlci5fY2xpZW50TGVmdCA9IHN3aXBlci53cmFwcGVyRWwuY2xpZW50TGVmdDtcclxuICB9XHJcbiAgY29uc3QgdHJhbnNsYXRlID0gcnRsVHJhbnNsYXRlID8gc3dpcGVyLnRyYW5zbGF0ZSA6IC1zd2lwZXIudHJhbnNsYXRlO1xyXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZSh2YWwpIHtcclxuICAgIGlmICh2YWwgPCAwKSByZXR1cm4gLU1hdGguZmxvb3IoTWF0aC5hYnModmFsKSk7XHJcbiAgICByZXR1cm4gTWF0aC5mbG9vcih2YWwpO1xyXG4gIH1cclxuICBjb25zdCBub3JtYWxpemVkVHJhbnNsYXRlID0gbm9ybWFsaXplKHRyYW5zbGF0ZSk7XHJcbiAgY29uc3Qgbm9ybWFsaXplZFNuYXBHcmlkID0gc25hcEdyaWQubWFwKCh2YWwpID0+IG5vcm1hbGl6ZSh2YWwpKTtcclxuICBsZXQgcHJldlNuYXAgPSBzbmFwR3JpZFtub3JtYWxpemVkU25hcEdyaWQuaW5kZXhPZihub3JtYWxpemVkVHJhbnNsYXRlKSAtIDFdO1xyXG4gIGlmICh0eXBlb2YgcHJldlNuYXAgPT09ICd1bmRlZmluZWQnICYmIHBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICBsZXQgcHJldlNuYXBJbmRleDtcclxuICAgIHNuYXBHcmlkLmZvckVhY2goKHNuYXAsIHNuYXBJbmRleCkgPT4ge1xyXG4gICAgICBpZiAobm9ybWFsaXplZFRyYW5zbGF0ZSA+PSBzbmFwKSB7XHJcbiAgICAgICAgLy8gcHJldlNuYXAgPSBzbmFwO1xyXG4gICAgICAgIHByZXZTbmFwSW5kZXggPSBzbmFwSW5kZXg7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKHR5cGVvZiBwcmV2U25hcEluZGV4ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBwcmV2U25hcCA9IHNuYXBHcmlkW3ByZXZTbmFwSW5kZXggPiAwID8gcHJldlNuYXBJbmRleCAtIDEgOiBwcmV2U25hcEluZGV4XTtcclxuICAgIH1cclxuICB9XHJcbiAgbGV0IHByZXZJbmRleCA9IDA7XHJcbiAgaWYgKHR5cGVvZiBwcmV2U25hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHByZXZJbmRleCA9IHNsaWRlc0dyaWQuaW5kZXhPZihwcmV2U25hcCk7XHJcbiAgICBpZiAocHJldkluZGV4IDwgMCkgcHJldkluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4IC0gMTtcclxuICAgIGlmIChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nICYmIHBhcmFtcy5zbGlkZXNQZXJHcm91cCA9PT0gMSAmJiBwYXJhbXMuc2xpZGVzUGVyR3JvdXBBdXRvKSB7XHJcbiAgICAgIHByZXZJbmRleCA9IHByZXZJbmRleCAtIHN3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygncHJldmlvdXMnLCB0cnVlKSArIDE7XHJcbiAgICAgIHByZXZJbmRleCA9IE1hdGgubWF4KHByZXZJbmRleCwgMCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMucmV3aW5kICYmIHN3aXBlci5pc0JlZ2lubmluZykge1xyXG4gICAgY29uc3QgbGFzdEluZGV4ID1cclxuICAgICAgc3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkICYmIHN3aXBlci52aXJ0dWFsXHJcbiAgICAgICAgPyBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoIC0gMVxyXG4gICAgICAgIDogc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxO1xyXG4gICAgcmV0dXJuIHN3aXBlci5zbGlkZVRvKGxhc3RJbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xyXG4gIH1cclxuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8ocHJldkluZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XHJcbn1cclxuXHJcbi8qIGVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiAqL1xyXG5mdW5jdGlvbiBzbGlkZVJlc2V0KHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKSB7XHJcbiAgaWYgKHNwZWVkID09PSB2b2lkIDApIHtcclxuICAgIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQ7XHJcbiAgfVxyXG4gIGlmIChydW5DYWxsYmFja3MgPT09IHZvaWQgMCkge1xyXG4gICAgcnVuQ2FsbGJhY2tzID0gdHJ1ZTtcclxuICB9XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XHJcbn1cclxuXHJcbi8qIGVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiAqL1xyXG5mdW5jdGlvbiBzbGlkZVRvQ2xvc2VzdChzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCwgdGhyZXNob2xkKSB7XHJcbiAgaWYgKHNwZWVkID09PSB2b2lkIDApIHtcclxuICAgIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQ7XHJcbiAgfVxyXG4gIGlmIChydW5DYWxsYmFja3MgPT09IHZvaWQgMCkge1xyXG4gICAgcnVuQ2FsbGJhY2tzID0gdHJ1ZTtcclxuICB9XHJcbiAgaWYgKHRocmVzaG9sZCA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICB0aHJlc2hvbGQgPSAwLjU7XHJcbiAgfVxyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgbGV0IGluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xyXG4gIGNvbnN0IHNraXAgPSBNYXRoLm1pbihzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCwgaW5kZXgpO1xyXG4gIGNvbnN0IHNuYXBJbmRleCA9IHNraXAgKyBNYXRoLmZsb29yKChpbmRleCAtIHNraXApIC8gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XHJcbiAgY29uc3QgdHJhbnNsYXRlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgOiAtc3dpcGVyLnRyYW5zbGF0ZTtcclxuICBpZiAodHJhbnNsYXRlID49IHN3aXBlci5zbmFwR3JpZFtzbmFwSW5kZXhdKSB7XHJcbiAgICAvLyBUaGUgY3VycmVudCB0cmFuc2xhdGUgaXMgb24gb3IgYWZ0ZXIgdGhlIGN1cnJlbnQgc25hcCBpbmRleCwgc28gdGhlIGNob2ljZVxyXG4gICAgLy8gaXMgYmV0d2VlbiB0aGUgY3VycmVudCBpbmRleCBhbmQgdGhlIG9uZSBhZnRlciBpdC5cclxuICAgIGNvbnN0IGN1cnJlbnRTbmFwID0gc3dpcGVyLnNuYXBHcmlkW3NuYXBJbmRleF07XHJcbiAgICBjb25zdCBuZXh0U25hcCA9IHN3aXBlci5zbmFwR3JpZFtzbmFwSW5kZXggKyAxXTtcclxuICAgIGlmICh0cmFuc2xhdGUgLSBjdXJyZW50U25hcCA+IChuZXh0U25hcCAtIGN1cnJlbnRTbmFwKSAqIHRocmVzaG9sZCkge1xyXG4gICAgICBpbmRleCArPSBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICAvLyBUaGUgY3VycmVudCB0cmFuc2xhdGUgaXMgYmVmb3JlIHRoZSBjdXJyZW50IHNuYXAgaW5kZXgsIHNvIHRoZSBjaG9pY2VcclxuICAgIC8vIGlzIGJldHdlZW4gdGhlIGN1cnJlbnQgaW5kZXggYW5kIHRoZSBvbmUgYmVmb3JlIGl0LlxyXG4gICAgY29uc3QgcHJldlNuYXAgPSBzd2lwZXIuc25hcEdyaWRbc25hcEluZGV4IC0gMV07XHJcbiAgICBjb25zdCBjdXJyZW50U25hcCA9IHN3aXBlci5zbmFwR3JpZFtzbmFwSW5kZXhdO1xyXG4gICAgaWYgKHRyYW5zbGF0ZSAtIHByZXZTbmFwIDw9IChjdXJyZW50U25hcCAtIHByZXZTbmFwKSAqIHRocmVzaG9sZCkge1xyXG4gICAgICBpbmRleCAtPSBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwO1xyXG4gICAgfVxyXG4gIH1cclxuICBpbmRleCA9IE1hdGgubWF4KGluZGV4LCAwKTtcclxuICBpbmRleCA9IE1hdGgubWluKGluZGV4LCBzd2lwZXIuc2xpZGVzR3JpZC5sZW5ndGggLSAxKTtcclxuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8oaW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2xpZGVUb0NsaWNrZWRTbGlkZSgpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHsgcGFyYW1zLCBzbGlkZXNFbCB9ID0gc3dpcGVyO1xyXG4gIGNvbnN0IHNsaWRlc1BlclZpZXcgPSBwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nID8gc3dpcGVyLnNsaWRlc1BlclZpZXdEeW5hbWljKCkgOiBwYXJhbXMuc2xpZGVzUGVyVmlldztcclxuICBsZXQgc2xpZGVUb0luZGV4ID0gc3dpcGVyLmNsaWNrZWRJbmRleDtcclxuICBsZXQgcmVhbEluZGV4O1xyXG4gIGNvbnN0IHNsaWRlU2VsZWN0b3IgPSBzd2lwZXIuaXNFbGVtZW50ID8gYHN3aXBlci1zbGlkZWAgOiBgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9YDtcclxuICBpZiAocGFyYW1zLmxvb3ApIHtcclxuICAgIGlmIChzd2lwZXIuYW5pbWF0aW5nKSByZXR1cm47XHJcbiAgICByZWFsSW5kZXggPSBwYXJzZUludChzd2lwZXIuY2xpY2tlZFNsaWRlLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSwgMTApO1xyXG4gICAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgc2xpZGVUb0luZGV4IDwgc3dpcGVyLmxvb3BlZFNsaWRlcyAtIHNsaWRlc1BlclZpZXcgLyAyIHx8XHJcbiAgICAgICAgc2xpZGVUb0luZGV4ID4gc3dpcGVyLnNsaWRlcy5sZW5ndGggLSBzd2lwZXIubG9vcGVkU2xpZGVzICsgc2xpZGVzUGVyVmlldyAvIDJcclxuICAgICAgKSB7XHJcbiAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcclxuICAgICAgICBzbGlkZVRvSW5kZXggPSBzd2lwZXIuZ2V0U2xpZGVJbmRleChcclxuICAgICAgICAgIGVsZW1lbnRDaGlsZHJlbihzbGlkZXNFbCwgYCR7c2xpZGVTZWxlY3Rvcn1bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3JlYWxJbmRleH1cIl1gKVswXVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgbmV4dFRpY2soKCkgPT4ge1xyXG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKHNsaWRlVG9JbmRleCA+IHN3aXBlci5zbGlkZXMubGVuZ3RoIC0gc2xpZGVzUGVyVmlldykge1xyXG4gICAgICBzd2lwZXIubG9vcEZpeCgpO1xyXG4gICAgICBzbGlkZVRvSW5kZXggPSBzd2lwZXIuZ2V0U2xpZGVJbmRleChcclxuICAgICAgICBlbGVtZW50Q2hpbGRyZW4oc2xpZGVzRWwsIGAke3NsaWRlU2VsZWN0b3J9W2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtyZWFsSW5kZXh9XCJdYClbMF1cclxuICAgICAgKTtcclxuICAgICAgbmV4dFRpY2soKCkgPT4ge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHNsaWRlVG9JbmRleCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcclxuICB9XHJcbn1cclxuXHJcbnZhciBzbGlkZSA9IHtcclxuICBzbGlkZVRvLFxyXG4gIHNsaWRlVG9Mb29wLFxyXG4gIHNsaWRlTmV4dCxcclxuICBzbGlkZVByZXYsXHJcbiAgc2xpZGVSZXNldCxcclxuICBzbGlkZVRvQ2xvc2VzdCxcclxuICBzbGlkZVRvQ2xpY2tlZFNsaWRlLFxyXG59O1xyXG5cclxuZnVuY3Rpb24gbG9vcENyZWF0ZShzbGlkZVJlYWxJbmRleCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHNsaWRlc0VsIH0gPSBzd2lwZXI7XHJcbiAgaWYgKCFwYXJhbXMubG9vcCB8fCAoc3dpcGVyLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpKSByZXR1cm47XHJcbiAgY29uc3Qgc2xpZGVzID0gZWxlbWVudENoaWxkcmVuKHNsaWRlc0VsLCBgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9LCBzd2lwZXItc2xpZGVgKTtcclxuICBzbGlkZXMuZm9yRWFjaCgoZWwsIGluZGV4KSA9PiB7XHJcbiAgICBlbC5zZXRB
9266dHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JywgaW5kZXgpO1xyXG4gIH0pO1xyXG4gIHN3aXBlci5sb29wRml4KHtcclxuICAgIHNsaWRlUmVhbEluZGV4LFxyXG4gICAgZGlyZWN0aW9uOiBwYXJhbXMuY2VudGVyZWRTbGlkZXMgPyB1bmRlZmluZWQgOiAnbmV4dCcsXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxvb3BGaXgoX3RlbXApIHtcclxuICBsZXQge1xyXG4gICAgc2xpZGVSZWFsSW5kZXgsXHJcbiAgICBzbGlkZVRvID0gdHJ1ZSxcclxuICAgIGRpcmVjdGlvbixcclxuICAgIHNldFRyYW5zbGF0ZSxcclxuICAgIGFjdGl2ZVNsaWRlSW5kZXgsXHJcbiAgICBieUNvbnRyb2xsZXIsXHJcbiAgICBieU1vdXNld2hlZWwsXHJcbiAgfSA9IF90ZW1wID09PSB2b2lkIDAgPyB7fSA6IF90ZW1wO1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgaWYgKCFzd2lwZXIucGFyYW1zLmxvb3ApIHJldHVybjtcclxuICBzd2lwZXIuZW1pdCgnYmVmb3JlTG9vcEZpeCcpO1xyXG4gIGNvbnN0IHsgc2xpZGVzLCBhbGxvd1NsaWRlUHJldiwgYWxsb3dTbGlkZU5leHQsIHNsaWRlc0VsLCBwYXJhbXMgfSA9IHN3aXBlcjtcclxuICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSB0cnVlO1xyXG4gIHN3aXBlci5hbGxvd1NsaWRlTmV4dCA9IHRydWU7XHJcbiAgaWYgKHN3aXBlci52aXJ0dWFsICYmIHBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHtcclxuICAgIGlmIChzbGlkZVRvKSB7XHJcbiAgICAgIGlmICghcGFyYW1zLmNlbnRlcmVkU2xpZGVzICYmIHN3aXBlci5zbmFwSW5kZXggPT09IDApIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoLCAwLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgIH0gZWxzZSBpZiAocGFyYW1zLmNlbnRlcmVkU2xpZGVzICYmIHN3aXBlci5zbmFwSW5kZXggPCBwYXJhbXMuc2xpZGVzUGVyVmlldykge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggKyBzd2lwZXIuc25hcEluZGV4LCAwLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoc3dpcGVyLnNuYXBJbmRleCA9PT0gc3dpcGVyLnNuYXBHcmlkLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIudmlydHVhbC5zbGlkZXNCZWZvcmUsIDAsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID0gYWxsb3dTbGlkZVByZXY7XHJcbiAgICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSBhbGxvd1NsaWRlTmV4dDtcclxuICAgIHN3aXBlci5lbWl0KCdsb29wRml4Jyk7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGNvbnN0IHNsaWRlc1BlclZpZXcgPVxyXG4gICAgcGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyA/IHN3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygpIDogTWF0aC5jZWlsKHBhcnNlRmxvYXQocGFyYW1zLnNsaWRlc1BlclZpZXcsIDEwKSk7XHJcbiAgbGV0IGxvb3BlZFNsaWRlcyA9IHBhcmFtcy5sb29wZWRTbGlkZXMgfHwgc2xpZGVzUGVyVmlldztcclxuICBpZiAobG9vcGVkU2xpZGVzICUgcGFyYW1zLnNsaWRlc1Blckdyb3VwICE9PSAwKSB7XHJcbiAgICBsb29wZWRTbGlkZXMgKz0gcGFyYW1zLnNsaWRlc1Blckdyb3VwIC0gKGxvb3BlZFNsaWRlcyAlIHBhcmFtcy5zbGlkZXNQZXJHcm91cCk7XHJcbiAgfVxyXG4gIHN3aXBlci5sb29wZWRTbGlkZXMgPSBsb29wZWRTbGlkZXM7XHJcbiAgY29uc3QgcHJlcGVuZFNsaWRlc0luZGV4ZXMgPSBbXTtcclxuICBjb25zdCBhcHBlbmRTbGlkZXNJbmRleGVzID0gW107XHJcbiAgbGV0IGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xyXG4gIGlmICh0eXBlb2YgYWN0aXZlU2xpZGVJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIGFjdGl2ZVNsaWRlSW5kZXggPSBzd2lwZXIuZ2V0U2xpZGVJbmRleChcclxuICAgICAgc3dpcGVyLnNsaWRlcy5maWx0ZXIoKGVsKSA9PiBlbC5jbGFzc0xpc3QuY29udGFpbnMocGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3MpKVswXVxyXG4gICAgKTtcclxuICB9IGVsc2Uge1xyXG4gICAgYWN0aXZlSW5kZXggPSBhY3RpdmVTbGlkZUluZGV4O1xyXG4gIH1cclxuICBjb25zdCBpc05leHQgPSBkaXJlY3Rpb24gPT09ICduZXh0JyB8fCAhZGlyZWN0aW9uO1xyXG4gIGNvbnN0IGlzUHJldiA9IGRpcmVjdGlvbiA9PT0gJ3ByZXYnIHx8ICFkaXJlY3Rpb247XHJcbiAgbGV0IHNsaWRlc1ByZXBlbmRlZCA9IDA7XHJcbiAgbGV0IHNsaWRlc0FwcGVuZGVkID0gMDtcclxuICAvLyBwcmVwZW5kIGxhc3Qgc2xpZGVzIGJlZm9yZSBzdGFydFxyXG4gIGlmIChhY3RpdmVTbGlkZUluZGV4IDwgbG9vcGVkU2xpZGVzKSB7XHJcbiAgICBzbGlkZXNQcmVwZW5kZWQgPSBNYXRoLm1heChsb29wZWRTbGlkZXMgLSBhY3RpdmVTbGlkZUluZGV4LCBwYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsb29wZWRTbGlkZXMgLSBhY3RpdmVTbGlkZUluZGV4OyBpICs9IDEpIHtcclxuICAgICAgY29uc3QgaW5kZXggPSBpIC0gTWF0aC5mbG9vcihpIC8gc2xpZGVzLmxlbmd0aCkgKiBzbGlkZXMubGVuZ3RoO1xyXG4gICAgICBwcmVwZW5kU2xpZGVzSW5kZXhlcy5wdXNoKHNsaWRlcy5sZW5ndGggLSBpbmRleCAtIDEpO1xyXG4gICAgfVxyXG4gIH0gZWxzZSBpZiAoYWN0aXZlU2xpZGVJbmRleCAvKiArIHNsaWRlc1BlclZpZXcgKi8gPiBzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIGxvb3BlZFNsaWRlcyAqIDIpIHtcclxuICAgIHNsaWRlc0FwcGVuZGVkID0gTWF0aC5tYXgoYWN0aXZlU2xpZGVJbmRleCAtIChzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIGxvb3BlZFNsaWRlcyAqIDIpLCBwYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXNBcHBlbmRlZDsgaSArPSAxKSB7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gaSAtIE1hdGguZmxvb3IoaSAvIHNsaWRlcy5sZW5ndGgpICogc2xpZGVzLmxlbmd0aDtcclxuICAgICAgYXBwZW5kU2xpZGVzSW5kZX
9266hlcy5wdXNoKGluZGV4KTtcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGlzUHJldikge1xyXG4gICAgcHJlcGVuZFNsaWRlc0luZGV4ZXMuZm9yRWFjaCgoaW5kZXgpID0+IHtcclxuICAgICAgc3dpcGVyLnNsaWRlc1tpbmRleF0uc3dpcGVyTG9vcE1vdmVET00gPSB0cnVlO1xyXG4gICAgICBzbGlkZXNFbC5wcmVwZW5kKHN3aXBlci5zbGlkZXNbaW5kZXhdKTtcclxuICAgICAgc3dpcGVyLnNsaWRlc1tpbmRleF0uc3dpcGVyTG9vcE1vdmVET00gPSBmYWxzZTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBpZiAoaXNOZXh0KSB7XHJcbiAgICBhcHBlbmRTbGlkZXNJbmRleGVzLmZvckVhY2goKGluZGV4KSA9PiB7XHJcbiAgICAgIHN3aXBlci5zbGlkZXNbaW5kZXhdLnN3aXBlckxvb3BNb3ZlRE9NID0gdHJ1ZTtcclxuICAgICAgc2xpZGVzRWwuYXBwZW5kKHN3aXBlci5zbGlkZXNbaW5kZXhdKTtcclxuICAgICAgc3dpcGVyLnNsaWRlc1tpbmRleF0uc3dpcGVyTG9vcE1vdmVET00gPSBmYWxzZTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBzd2lwZXIucmVjYWxjU2xpZGVzKCk7XHJcbiAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycpIHtcclxuICAgIHN3aXBlci51cGRhdGVTbGlkZXMoKTtcclxuICB9XHJcbiAgaWYgKHBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzT2Zmc2V0KCk7XHJcbiAgfVxyXG4gIGlmIChzbGlkZVRvKSB7XHJcbiAgICBpZiAocHJlcGVuZFNsaWRlc0luZGV4ZXMubGVuZ3RoID4gMCAmJiBpc1ByZXYpIHtcclxuICAgICAgaWYgKHR5cGVvZiBzbGlkZVJlYWxJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBjb25zdCBjdXJyZW50U2xpZGVUcmFuc2xhdGUgPSBzd2lwZXIuc2xpZGVzR3JpZFthY3RpdmVJbmRleF07XHJcbiAgICAgICAgY29uc3QgbmV3U2xpZGVUcmFuc2xhdGUgPSBzd2lwZXIuc2xpZGVzR3JpZFthY3RpdmVJbmRleCArIHNsaWRlc1ByZXBlbmRlZF07XHJcbiAgICAgICAgY29uc3QgZGlmZiA9IG5ld1NsaWRlVHJhbnNsYXRlIC0gY3VycmVudFNsaWRlVHJhbnNsYXRlO1xyXG4gICAgICAgIGlmIChieU1vdXNld2hlZWwpIHtcclxuICAgICAgICAgIHN3aXBlci5zZXRUcmFuc2xhdGUoc3dpcGVyLnRyYW5zbGF0ZSAtIGRpZmYpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhhY3RpdmVJbmRleCArIHNsaWRlc1ByZXBlbmRlZCwgMCwgZmFsc2UsIHRydWUpO1xyXG4gICAgICAgICAgaWYgKHNldFRyYW5zbGF0ZSkge1xyXG4gICAgICAgICAgICBzd2lwZXIudG91Y2hlc1tzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnc3RhcnRYJyA6ICdzdGFydFknXSArPSBkaWZmO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoc2V0VHJhbnNsYXRlKSB7XHJcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUb0xvb3Aoc2xpZGVSZWFsSW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoYXBwZW5kU2xpZGVzSW5kZXhlcy5sZW5ndGggPiAwICYmIGlzTmV4dCkge1xyXG4gICAgICBpZiAodHlwZW9mIHNsaWRlUmVhbEluZGV4ID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRTbGlkZVRyYW5zbGF0ZSA9IHN3aXBlci5zbGlkZXNHcmlkW2FjdGl2ZUluZGV4XTtcclxuICAgICAgICBjb25zdCBuZXdTbGlkZVRyYW5zbGF0ZSA9IHN3aXBlci5zbGlkZXNHcmlkW2FjdGl2ZUluZGV4IC0gc2xpZGVzQXBwZW5kZWRdO1xyXG4gICAgICAgIGNvbnN0IGRpZmYgPSBuZXdTbGlkZVRyYW5zbGF0ZSAtIGN1cnJlbnRTbGlkZVRyYW5zbGF0ZTtcclxuICAgICAgICBpZiAoYnlNb3VzZXdoZWVsKSB7XHJcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHN3aXBlci50cmFuc2xhdGUgLSBkaWZmKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oYWN0aXZlSW5kZXggLSBzbGlkZXNBcHBlbmRlZCwgMCwgZmFsc2UsIHRydWUpO1xyXG4gICAgICAgICAgaWYgKHNldFRyYW5zbGF0ZSkge1xyXG4gICAgICAgICAgICBzd2lwZXIudG91Y2hlc1tzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnc3RhcnRYJyA6ICdzdGFydFknXSArPSBkaWZmO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUb0xvb3Aoc2xpZGVSZWFsSW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSBhbGxvd1NsaWRlUHJldjtcclxuICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSBhbGxvd1NsaWRlTmV4dDtcclxuICBpZiAoc3dpcGVyLmNvbnRyb2xsZXIgJiYgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCAmJiAhYnlDb250cm9sbGVyKSB7XHJcbiAgICBjb25zdCBsb29wUGFyYW1zID0ge1xyXG4gICAgICBzbGlkZVJlYWxJbmRleCxcclxuICAgICAgc2xpZGVUbzogZmFsc2UsXHJcbiAgICAgIGRpcmVjdGlvbixcclxuICAgICAgc2V0VHJhbnNsYXRlLFxyXG4gICAgICBhY3RpdmVTbGlkZUluZGV4LFxyXG4gICAgICBieUNvbnRyb2xsZXI6IHRydWUsXHJcbiAgICB9O1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkpIHtcclxuICAgICAgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbC5mb3JFYWNoKChjKSA9PiB7XHJcbiAgICAgICAgaWYgKCFjLmRlc3Ryb3llZCAmJiBjLnBhcmFtcy5sb29wKSBjLmxvb3BGaXgobG9vcFBhcmFtcyk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmIChzd2lwZXIuY29udHJvbGxlci5jb250cm9sIGluc3RhbmNlb2Ygc3dpcGVyLmNvbnN0cnVjdG9yICYmIHN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wucGFyYW1zLmxvb3ApIHtcclxuICAgICAgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbC5sb29wRml4KGxvb3BQYXJhbXMpO1xyXG4gICAgfVxyXG4gIH1cclxuICBzd2lwZXIuZW1pdCgnbG9vcEZpeCcpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBsb29wRGVzdHJveSgpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHsgcGFyYW1zLCBzbGlkZXNFbCB9ID0gc3dpcGVyO1xyXG4gIGlmICghcGFyYW1zLmxvb3AgfHwgKHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkKSkgcmV0dXJuO1xyXG4gIHN3aXBlci5yZWNhbGNTbGlkZXMoKTtcclxuICBjb25zdCBuZXdTbGlkZXNPcmRlciA9IFtdO1xyXG4gIHN3aXBlci5zbGlkZXMuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgY29uc3QgaW5kZXggPVxyXG4gICAgICB0eX
9266Blb2Ygc2xpZGVFbC5zd2lwZXJTbGlkZUluZGV4ID09PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgID8gc2xpZGVFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JykgKiAxXHJcbiAgICAgICAgOiBzbGlkZUVsLnN3aXBlclNsaWRlSW5kZXg7XHJcbiAgICBuZXdTbGlkZXNPcmRlcltpbmRleF0gPSBzbGlkZUVsO1xyXG4gIH0pO1xyXG4gIHN3aXBlci5zbGlkZXMuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgc2xpZGVFbC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4Jyk7XHJcbiAgfSk7XHJcbiAgbmV3U2xpZGVzT3JkZXIuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgc2xpZGVzRWwuYXBwZW5kKHNsaWRlRWwpO1xyXG4gIH0pO1xyXG4gIHN3aXBlci5yZWNhbGNTbGlkZXMoKTtcclxuICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIucmVhbEluZGV4LCAwKTtcclxufVxyXG5cclxudmFyIGxvb3AgPSB7XHJcbiAgbG9vcENyZWF0ZSxcclxuICBsb29wRml4LFxyXG4gIGxvb3BEZXN0cm95LFxyXG59O1xyXG5cclxuZnVuY3Rpb24gc2V0R3JhYkN1cnNvcihtb3ZpbmcpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGlmICghc3dpcGVyLnBhcmFtcy5zaW11bGF0ZVRvdWNoIHx8IChzd2lwZXIucGFyYW1zLndhdGNoT3ZlcmZsb3cgJiYgc3dpcGVyLmlzTG9ja2VkKSB8fCBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJldHVybjtcclxuICBjb25zdCBlbCA9IHN3aXBlci5wYXJhbXMudG91Y2hFdmVudHNUYXJnZXQgPT09ICdjb250YWluZXInID8gc3dpcGVyLmVsIDogc3dpcGVyLndyYXBwZXJFbDtcclxuICBpZiAoc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgc3dpcGVyLl9fcHJldmVudE9ic2VydmVyX18gPSB0cnVlO1xyXG4gIH1cclxuICBlbC5zdHlsZS5jdXJzb3IgPSAnbW92ZSc7XHJcbiAgZWwuc3R5bGUuY3Vyc29yID0gbW92aW5nID8gJ2dyYWJiaW5nJyA6ICdncmFiJztcclxuICBpZiAoc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgc3dpcGVyLl9fcHJldmVudE9ic2VydmVyX18gPSBmYWxzZTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdW5zZXRHcmFiQ3Vyc29yKCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgaWYgKChzd2lwZXIucGFyYW1zLndhdGNoT3ZlcmZsb3cgJiYgc3dpcGVyLmlzTG9ja2VkKSB8fCBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgaWYgKHN3aXBlci5pc0VsZW1lbnQpIHtcclxuICAgIHN3aXBlci5fX3ByZXZlbnRPYnNlcnZlcl9fID0gdHJ1ZTtcclxuICB9XHJcbiAgc3dpcGVyW3N3aXBlci5wYXJhbXMudG91Y2hFdmVudHNUYXJnZXQgPT09ICdjb250YWluZXInID8gJ2VsJyA6ICd3cmFwcGVyRWwnXS5zdHlsZS5jdXJzb3IgPSAnJztcclxuICBpZiAoc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgc3dpcGVyLl9fcHJldmVudE9ic2VydmVyX18gPSBmYWxzZTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxudmFyIGdyYWJDdXJzb3IgPSB7XHJcbiAgc2V0R3JhYkN1cnNvcixcclxuICB1bnNldEdyYWJDdXJzb3IsXHJcbn07XHJcblxyXG4vLyBNb2RpZmllZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU0NTIwNTU0L2N1c3RvbS1lbGVtZW50LWdldHJvb3Rub2RlLWNsb3Nlc3QtZnVuY3Rpb24tY3Jvc3NpbmctbXVsdGlwbGUtcGFyZW50LXNoYWRvd2RcclxuZnVuY3Rpb24gY2xvc2VzdEVsZW1lbnQoc2VsZWN0b3IsIGJhc2UpIHtcclxuICBpZiAoYmFzZSA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICBiYXNlID0gdGhpcztcclxuICB9XHJcbiAgZnVuY3Rpb24gX19jbG9zZXN0RnJvbShlbCkge1xyXG4gICAgaWYgKCFlbCB8fCBlbCA9PT0gZ2V0RG9jdW1lbnQoKSB8fCBlbCA9PT0gZ2V0V2luZG93KCkpIHJldHVybiBudWxsO1xyXG4gICAgaWYgKGVsLmFzc2lnbmVkU2xvdCkgZWwgPSBlbC5hc3NpZ25lZFNsb3Q7XHJcbiAgICBjb25zdCBmb3VuZCA9IGVsLmNsb3Nlc3Qoc2VsZWN0b3IpO1xyXG4gICAgaWYgKCFmb3VuZCAmJiAhZWwuZ2V0Um9vdE5vZGUpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZm91bmQgfHwgX19jbG9zZXN0RnJvbShlbC5nZXRSb290Tm9kZSgpLmhvc3QpO1xyXG4gIH1cclxuICByZXR1cm4gX19jbG9zZXN0RnJvbShiYXNlKTtcclxufVxyXG5mdW5jdGlvbiBvblRvdWNoU3RhcnQoZXZlbnQpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcclxuICBjb25zdCBkYXRhID0gc3dpcGVyLnRvdWNoRXZlbnRzRGF0YTtcclxuICBkYXRhLmV2Q2FjaGUucHVzaChldmVudCk7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHRvdWNoZXMsIGVuYWJsZWQgfSA9IHN3aXBlcjtcclxuICBpZiAoIWVuYWJsZWQpIHJldHVybjtcclxuICBpZiAoIXBhcmFtcy5zaW11bGF0ZVRvdWNoICYmIGV2ZW50LnBvaW50ZXJUeXBlID09PSAnbW91c2UnKSByZXR1cm47XHJcbiAgaWYgKHN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLnByZXZlbnRJbnRlcmFjdGlvbk9uVHJhbnNpdGlvbikge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBpZiAoIXN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLmNzc01vZGUgJiYgcGFyYW1zLmxvb3ApIHtcclxuICAgIHN3aXBlci5sb29wRml4KCk7XHJcbiAgfVxyXG4gIGxldCBlID0gZXZlbnQ7XHJcbiAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcclxuICBsZXQgdGFyZ2V0RWwgPSBlLnRhcmdldDtcclxuICBpZiAocGFyYW1zLnRvdWNoRXZlbnRzVGFyZ2V0ID09PSAnd3JhcHBlcicpIHtcclxuICAgIGlmICghc3dpcGVyLndyYXBwZXJFbC5jb250YWlucyh0YXJnZXRFbCkpIHJldHVybjtcclxuICB9XHJcbiAgaWYgKCd3aGljaCcgaW4gZSAmJiBlLndoaWNoID09PSAzKSByZXR1cm47XHJcbiAgaWYgKCdidXR0b24nIGluIGUgJiYgZS5idXR0b24gPiAwKSByZXR1cm47XHJcbiAgaWYgKGRhdGEuaXNUb3VjaGVkICYmIGRhdGEuaXNNb3ZlZCkgcmV0dXJuO1xyXG5cclxuICAvLyBjaGFuZ2UgdGFyZ2V0IGVsIGZvciBzaGFkb3cgcm9vdCBjb21wb25lbnRcclxuICBjb25zdCBzd2lwaW5nQ2xhc3NIYXNWYWx1ZSA9ICEhcGFyYW1zLm5vU3dpcGluZ0NsYXNzICYmIHBhcmFtcy5ub1N3aXBpbmdDbGFzcyAhPT0gJyc7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgY29uc3QgZXZlbnRQYXRoID0gZXZlbnQuY29tcG9zZWRQYXRoID8gZXZlbnQuY29tcG9zZWRQYXRoKCkgOiBldmVudC5wYXRoO1xyXG4gIGlmIChzd2lwaW5nQ2xhc3NIYXNWYWx1ZSAmJiBlLnRhcmdldCAmJiBlLnRhcmdldC5zaGFkb3dSb290ICYmIGV2ZW50UGF0aCkge1xyXG4gICAgdGFyZ2V0RWwgPSBldmVudFBhdGhbMF07XHJcbiAgfVxyXG4gIGNvbnN0IG5vU3dpcGluZ1NlbGVjdG9yID0gcGFyYW1zLm5vU3dpcGluZ1NlbGVjdG9yID8gcGFyYW1zLm5vU3dpcGluZ1NlbGVjdG9yIDogYC4ke3BhcmFtcy5ub1N3aXBpbmdDbGFzc31gO1xyXG4gIGNvbnN0IGlzVGFyZ2V0U2hhZG93ID0gISEoZS50YXJnZXQgJiYgZS50YXJnZXQuc2hhZG93Um9vdCk7XHJcblxyXG4gIC8vIHVzZSBjbG9zZXN0RWxlbWVudCBmb3Igc2hhZG93IHJvb3QgZWxlbWVudCB0byBnZXQgdGhlIGFjdHVhbCBjbG9zZXN0IGZvciBuZXN0ZWQgc2hhZG93IHJvb3QgZWxlbWVudFxyXG4gIGlmIChcclxuICAgIHBhcmFtcy5ub1N3aXBpbmcgJiZcclxuICAgIChpc1RhcmdldFNoYWRvdyA/IGNsb3Nlc3RFbGVtZW50KG5vU3dpcGluZ1NlbGVjdG9yLCB0YXJnZXRFbCkgOiB0YXJnZXRFbC5jbG9zZXN0KG5vU3dpcGluZ1NlbGVjdG9yKSlcclxuICApIHtcclxuICAgIHN3aXBlci5hbGxvd0NsaWNrID0gdHJ1ZTtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgaWYgKHBhcmFtcy5zd2lwZUhhbmRsZXIpIHtcclxuICAgIGlmICghdGFyZ2V0RWwuY2xvc2VzdChwYXJhbXMuc3dpcGVIYW5kbGVyKSkgcmV0dXJuO1xyXG4gIH1cclxuICB0b3VjaGVzLmN1cnJlbnRYID0gZS5wYWdlWDtcclxuICB0b3VjaGVzLmN1cnJlbnRZID0gZS5wYWdlWTtcclxuICBjb25zdCBzdGFydFggPSB0b3VjaGVzLmN1cnJlbnRYO1xyXG4gIGNvbnN0IHN0YXJ0WSA9IHRvdWNoZXMuY3VycmVudFk7XHJcblxyXG4gIC8vIERvIE5PVCBzdGFydCBpZiBpT1MgZWRnZSBzd2lwZSBpcyBkZXRlY3RlZC4gT3RoZXJ3aXNlIGlPUyBhcHAgY2Fubm90IHN3aXBlLXRvLWdvLWJhY2sgYW55bW9yZVxyXG5cclxuICBjb25zdCBlZGdlU3dpcGVEZXRlY3Rpb24gPSBwYXJhbXMuZWRnZVN3aXBlRGV0ZWN0aW9uIHx8IHBhcmFtcy5pT1NFZGdlU3dpcGVEZXRlY3Rpb247XHJcbiAgY29uc3QgZWRnZVN3aXBlVGhyZXNob2xkID0gcGFyYW1zLmVkZ2VTd2lwZVRocmVzaG9sZCB8fCBwYXJhbXMuaU9TRWRnZVN3aXBlVGhyZXNob2xkO1xyXG4gIGlmIChlZGdlU3dpcGVEZXRlY3Rpb24gJiYgKHN0YXJ0WCA8PSBlZGdlU3dpcGVUaHJlc2hvbGQgfHwgc3RhcnRYID49IHdpbmRvdy5pbm5lcldpZHRoIC0gZWRnZVN3aXBlVGhyZXNob2xkKSkge1xyXG4gICAgaWYgKGVkZ2VTd2lwZURldGVjdGlvbiA9PT0gJ3ByZXZlbnQnKSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG4gIE9iamVjdC5hc3NpZ24oZGF0YSwge1xyXG4gICAgaXNUb3VjaGVkOiB0cnVlLFxyXG4gICAgaXNNb3ZlZDogZmFsc2UsXHJcbiAgICBhbGxvd1RvdWNoQ2FsbGJhY2tzOiB0cnVlLFxyXG4gICAgaXNTY3JvbGxpbmc6IHVuZGVmaW5lZCxcclxuICAgIHN0YXJ0TW92aW5nOiB1bmRlZmluZWQsXHJcbiAgfSk7XHJcbiAgdG91Y2hlcy5zdGFydFggPSBzdGFydFg7XHJcbiAgdG91Y2hlcy5zdGFydFkgPSBzdGFydFk7XHJcbiAgZGF0YS50b3VjaFN0YXJ0VGltZSA9IG5vdygpO1xyXG4gIHN3aXBlci5hbGxvd0NsaWNrID0gdHJ1ZTtcclxuICBzd2lwZXIudXBkYXRlU2l6ZSgpO1xyXG4gIHN3aXBlci5zd2lwZURpcmVjdGlvbiA9IHVuZGVmaW5lZDtcclxuICBpZiAocGFyYW1zLnRocmVzaG9sZCA+IDApIGRhdGEuYWxsb3dUaHJlc2hvbGRNb3ZlID0gZmFsc2U7XHJcbiAgbGV0IHByZXZlbn
9266REZWZhdWx0ID0gdHJ1ZTtcclxuICBpZiAodGFyZ2V0RWwubWF0Y2hlcyhkYXRhLmZvY3VzYWJsZUVsZW1lbnRzKSkge1xyXG4gICAgcHJldmVudERlZmF1bHQgPSBmYWxzZTtcclxuICAgIGlmICh0YXJnZXRFbC5ub2RlTmFtZSA9PT0gJ1NFTEVDVCcpIHtcclxuICAgICAgZGF0YS5pc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKFxyXG4gICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJlxyXG4gICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5tYXRjaGVzKGRhdGEuZm9jdXNhYmxlRWxlbWVudHMpICYmXHJcbiAgICBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0YXJnZXRFbFxyXG4gICkge1xyXG4gICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ibHVyKCk7XHJcbiAgfVxyXG4gIGNvbnN0IHNob3VsZFByZXZlbnREZWZhdWx0ID0gcHJldmVudERlZmF1bHQgJiYgc3dpcGVyLmFsbG93VG91Y2hNb3ZlICYmIHBhcmFtcy50b3VjaFN0YXJ0UHJldmVudERlZmF1bHQ7XHJcbiAgaWYgKChwYXJhbXMudG91Y2hTdGFydEZvcmNlUHJldmVudERlZmF1bHQgfHwgc2hvdWxkUHJldmVudERlZmF1bHQpICYmICF0YXJnZXRFbC5pc0NvbnRlbnRFZGl0YWJsZSkge1xyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLmZyZWVNb2RlICYmIHBhcmFtcy5mcmVlTW9kZS5lbmFibGVkICYmIHN3aXBlci5mcmVlTW9kZSAmJiBzd2lwZXIuYW5pbWF0aW5nICYmICFwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgc3dpcGVyLmZyZWVNb2RlLm9uVG91Y2hTdGFydCgpO1xyXG4gIH1cclxuICBzd2lwZXIuZW1pdCgndG91Y2hTdGFydCcsIGUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBvblRvdWNoTW92ZShldmVudCkge1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IGRhdGEgPSBzd2lwZXIudG91Y2hFdmVudHNEYXRhO1xyXG4gIGNvbnN0IHsgcGFyYW1zLCB0b3VjaGVzLCBydGxUcmFuc2xhdGU6IHJ0bCwgZW5hYmxlZCB9ID0gc3dpcGVyO1xyXG4gIGlmICghZW5hYmxlZCkgcmV0dXJuO1xyXG4gIGlmICghcGFyYW1zLnNpbXVsYXRlVG91Y2ggJiYgZXZlbnQucG9pbnRlclR5cGUgPT09ICdtb3VzZScpIHJldHVybjtcclxuICBsZXQgZSA9IGV2ZW50O1xyXG4gIGlmIChlLm9yaWdpbmFsRXZlbnQpIGUgPSBlLm9yaWdpbmFsRXZlbnQ7XHJcbiAgaWYgKCFkYXRhLmlzVG91Y2hlZCkge1xyXG4gICAgaWYgKGRhdGEuc3RhcnRNb3ZpbmcgJiYgZGF0YS5pc1Njcm9sbGluZykge1xyXG4gICAgICBzd2lwZXIuZW1pdCgndG91Y2hNb3ZlT3Bwb3NpdGUnLCBlKTtcclxuICAgIH1cclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgY29uc3QgcG9pbnRlckluZGV4ID0gZGF0YS5ldkNhY2hlLmZpbmRJbmRleCgoY2FjaGVkRXYpID0+IGNhY2hlZEV2LnBvaW50ZXJJZCA9PT0gZS5wb2ludGVySWQpO1xyXG4gIGlmIChwb2ludGVySW5kZXggPj0gMCkgZGF0YS5ldkNhY2hlW3BvaW50ZXJJbmRleF0gPSBlO1xyXG4gIGNvbnN0IHRhcmdldFRvdWNoID0gZGF0YS5ldkNhY2hlLmxlbmd0aCA+IDEgPyBkYXRhLmV2Q2FjaGVbMF0gOiBlO1xyXG4gIGNvbnN0IHBhZ2VYID0gdGFyZ2V0VG91Y2gucGFnZVg7XHJcbiAgY29uc3QgcGFnZVkgPSB0YXJnZXRUb3VjaC5wYWdlWTtcclxuICBpZiAoZS5wcmV2ZW50ZWRCeU5lc3RlZFN3aXBlcikge1xyXG4gICAgdG91Y2hlcy5zdGFydFggPSBwYWdlWDtcclxuICAgIHRvdWNoZXMuc3RhcnRZID0gcGFnZVk7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlmICghc3dpcGVyLmFsbG93VG91Y2hNb3ZlKSB7XHJcbiAgICBpZiAoIWUudGFyZ2V0Lm1hdGNoZXMoZGF0YS5mb2N1c2FibGVFbGVtZW50cykpIHtcclxuICAgICAgc3dpcGVyLmFsbG93Q2xpY2sgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChkYXRhLmlzVG91Y2hlZCkge1xyXG4gICAgICBPYmplY3QuYXNzaWduKHRvdWNoZXMsIHtcclxuICAgICAgICBzdGFydFg6IHBhZ2VYLFxyXG4gICAgICAgIHN0YXJ0WTogcGFnZVksXHJcbiAgICAgICAgcHJldlg6IHN3aXBlci50b3VjaGVzLmN1cnJlbnRYLFxyXG4gICAgICAgIHByZXZZOiBzd2lwZXIudG91Y2hlcy5jdXJyZW50WSxcclxuICAgICAgICBjdXJyZW50WDogcGFnZVgsXHJcbiAgICAgICAgY3VycmVudFk6IHBhZ2VZLFxyXG4gICAgICB9KTtcclxuICAgICAgZGF0YS50b3VjaFN0YXJ0VGltZSA9IG5vdygpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLnRvdWNoUmVsZWFzZU9uRWRnZXMgJiYgIXBhcmFtcy5sb29wKSB7XHJcbiAgICBpZiAoc3dpcGVyLmlzVmVydGljYWwoKSkge1xyXG4gICAgICAvLyBWZXJ0aWNhbFxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgKHBhZ2VZIDwgdG91Y2hlcy5zdGFydFkgJiYgc3dpcGVyLnRyYW5zbGF0ZSA8PSBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHx8XHJcbiAgICAgICAgKHBhZ2VZID4gdG91Y2hlcy5zdGFydFkgJiYgc3dpcGVyLnRyYW5zbGF0ZSA+PSBzd2lwZXIubWluVHJhbnNsYXRlKCkpXHJcbiAgICAgICkge1xyXG4gICAgICAgIGRhdGEuaXNUb3VjaGVkID0gZmFsc2U7XHJcbiAgICAgICAgZGF0YS5pc01vdmVkID0gZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAocGFnZVggPCB0b3VjaGVzLnN0YXJ0WCAmJiBzd2lwZXIudHJhbnNsYXRlIDw9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSkgfHxcclxuICAgICAgKHBhZ2VYID4gdG91Y2hlcy5zdGFydFggJiYgc3dpcGVyLnRyYW5zbGF0ZSA+PSBzd2lwZXIubWluVHJhbnNsYXRlKCkpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xyXG4gICAgaWYgKGUudGFyZ2V0ID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGUudGFyZ2V0Lm1hdGNoZXMoZGF0YS5mb2N1c2FibGVFbGVtZW50cykpIHtcclxuICAgICAgZGF0YS5pc01vdmVkID0gdHJ1ZTtcclxuICAgICAgc3dpcGVyLmFsbG93Q2xpY2sgP
9266SBmYWxzZTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzKSB7XHJcbiAgICBzd2lwZXIuZW1pdCgndG91Y2hNb3ZlJywgZSk7XHJcbiAgfVxyXG4gIGlmIChlLnRhcmdldFRvdWNoZXMgJiYgZS50YXJnZXRUb3VjaGVzLmxlbmd0aCA+IDEpIHJldHVybjtcclxuICB0b3VjaGVzLmN1cnJlbnRYID0gcGFnZVg7XHJcbiAgdG91Y2hlcy5jdXJyZW50WSA9IHBhZ2VZO1xyXG4gIGNvbnN0IGRpZmZYID0gdG91Y2hlcy5jdXJyZW50WCAtIHRvdWNoZXMuc3RhcnRYO1xyXG4gIGNvbnN0IGRpZmZZID0gdG91Y2hlcy5jdXJyZW50WSAtIHRvdWNoZXMuc3RhcnRZO1xyXG4gIGlmIChzd2lwZXIucGFyYW1zLnRocmVzaG9sZCAmJiBNYXRoLnNxcnQoZGlmZlggKiogMiArIGRpZmZZICoqIDIpIDwgc3dpcGVyLnBhcmFtcy50aHJlc2hvbGQpIHJldHVybjtcclxuICBpZiAodHlwZW9mIGRhdGEuaXNTY3JvbGxpbmcgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBsZXQgdG91Y2hBbmdsZTtcclxuICAgIGlmIChcclxuICAgICAgKHN3aXBlci5pc0hvcml6b250YWwoKSAmJiB0b3VjaGVzLmN1cnJlbnRZID09PSB0b3VjaGVzLnN0YXJ0WSkgfHxcclxuICAgICAgKHN3aXBlci5pc1ZlcnRpY2FsKCkgJiYgdG91Y2hlcy5jdXJyZW50WCA9PT0gdG91Y2hlcy5zdGFydFgpXHJcbiAgICApIHtcclxuICAgICAgZGF0YS5pc1Njcm9sbGluZyA9IGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICAgIGlmIChkaWZmWCAqIGRpZmZYICsgZGlmZlkgKiBkaWZmWSA+PSAyNSkge1xyXG4gICAgICAgIHRvdWNoQW5nbGUgPSAoTWF0aC5hdGFuMihNYXRoLmFicyhkaWZmWSksIE1hdGguYWJzKGRpZmZYKSkgKiAxODApIC8gTWF0aC5QSTtcclxuICAgICAgICBkYXRhLmlzU2Nyb2xsaW5nID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gdG91Y2hBbmdsZSA+IHBhcmFtcy50b3VjaEFuZ2xlIDogOTAgLSB0b3VjaEFuZ2xlID4gcGFyYW1zLnRvdWNoQW5nbGU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGRhdGEuaXNTY3JvbGxpbmcpIHtcclxuICAgIHN3aXBlci5lbWl0KCd0b3VjaE1vdmVPcHBvc2l0ZScsIGUpO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIGRhdGEuc3RhcnRNb3ZpbmcgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBpZiAodG91Y2hlcy5jdXJyZW50WCAhPT0gdG91Y2hlcy5zdGFydFggfHwgdG91Y2hlcy5jdXJyZW50WSAhPT0gdG91Y2hlcy5zdGFydFkpIHtcclxuICAgICAgZGF0YS5zdGFydE1vdmluZyA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmIChcclxuICAgIGRhdGEuaXNTY3JvbGxpbmcgfHxcclxuICAgIChzd2lwZXIuem9vbSAmJiBzd2lwZXIucGFyYW1zLnpvb20gJiYgc3dpcGVyLnBhcmFtcy56b29tLmVuYWJsZWQgJiYgZGF0YS5ldkNhY2hlLmxlbmd0aCA+IDEpXHJcbiAgKSB7XHJcbiAgICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBpZiAoIWRhdGEuc3RhcnRNb3ZpbmcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgc3dpcGVyLmFsbG93Q2xpY2sgPSBmYWxzZTtcclxuICBpZiAoIXBhcmFtcy5jc3NNb2RlICYmIGUuY2FuY2VsYWJsZSkge1xyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLnRvdWNoTW92ZVN0b3BQcm9wYWdhdGlvbiAmJiAhcGFyYW1zLm5lc3RlZCkge1xyXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICB9XHJcbiAgbGV0IGRpZmYgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBkaWZmWCA6IGRpZmZZO1xyXG4gIGxldCB0b3VjaGVzRGlmZiA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/IHRvdWNoZXMuY3VycmVudFggLSB0b3VjaGVzLnByZXZpb3VzWCA6IHRvdWNoZXMuY3VycmVudFkgLSB0b3VjaGVzLnByZXZpb3VzWTtcclxuICBpZiAocGFyYW1zLm9uZVdheU1vdmVtZW50KSB7XHJcbiAgICBkaWZmID0gTWF0aC5hYnMoZGlmZikgKiAocnRsID8gMSA6IC0xKTtcclxuICAgIHRvdWNoZXNEaWZmID0gTWF0aC5hYnModG91Y2hlc0RpZmYpICogKHJ0bCA/IDEgOiAtMSk7XHJcbiAgfVxyXG4gIHRvdWNoZXMuZGlmZiA9IGRpZmY7XHJcbiAgZGlmZiAqPSBwYXJhbXMudG91Y2hSYXRpbztcclxuICBpZiAocnRsKSB7XHJcbiAgICBkaWZmID0gLWRpZmY7XHJcbiAgICB0b3VjaGVzRGlmZiA9IC10b3VjaGVzRGlmZjtcclxuICB9XHJcbiAgY29uc3QgcHJldlRvdWNoZXNEaXJlY3Rpb24gPSBzd2lwZXIudG91Y2hlc0RpcmVjdGlvbjtcclxuICBzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPSBkaWZmID4gMCA/ICdwcmV2JyA6ICduZXh0JztcclxuICBzd2lwZXIudG91Y2hlc0RpcmVjdGlvbiA9IHRvdWNoZXNEaWZmID4gMCA/ICdwcmV2JyA6ICduZXh0JztcclxuICBjb25zdCBpc0xvb3AgPSBzd2lwZXIucGFyYW1zLmxvb3AgJiYgIXBhcmFtcy5jc3NNb2RlO1xyXG4gIGlmICghZGF0YS5pc01vdmVkKSB7XHJcbiAgICBpZiAoaXNMb29wKSB7XHJcbiAgICAgIHN3aXBlci5sb29wRml4KHtcclxuICAgICAgICBkaXJlY3Rpb246IHN3aXBlci5zd2lwZURpcmVjdGlvbixcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBkYXRhLnN0YXJ0VHJhbnNsYXRlID0gc3dpcGVyLmdldFRyYW5zbGF0ZSgpO1xyXG4gICAgc3dpcGVyLnNldFRyYW5zaXRpb24oMCk7XHJcbiAgICBpZiAoc3dpcGVyLmFuaW1hdGluZykge1xyXG4gICAgICBjb25zdCBldnQgPSBuZXcgd2luZG93LkN1c3RvbUV2ZW50KCd0cmFuc2l0aW9uZW5kJywge1xyXG4gICAgICAgIGJ1YmJsZXM6IHRydWUsXHJcbiAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcclxuICAgICAgfSk7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuZGlzcGF0Y2hFdmVudChldnQpO1xyXG4gICAgfVxyXG4gICAgZGF0YS5hbGxvd01vbWVudHVtQm91bmNlID0gZmFsc2U7XHJcbiAgICAvLyBHcmFiIEN1cnNvclxyXG4gICAgaWYgKHBhcmFtcy5ncmFiQ3Vyc29yICYmIChzd2lwZXIuYWxsb3dTbGlkZU5leHQgPT09IHRydWUgfHwgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID09PSB0cnVlKSkge1xyXG4gICAgICBzd2lwZXIuc2V0R3JhYkN1cnNvcih0cnVlKTtcclxuICAgIH1cclxuICAgIHN3aXBlci5lbWl0KCdzbGlkZXJGaXJzdE1vdmUnLCBlKTtcclxuICB9XHJcbiAgbGV0IGxvb3BGaXhlZDtcclxuICBpZiAoZGF0YS5pc01vdmVkICYmIHByZXZUb3VjaGVzRGlyZWN0aW9uICE9PSBzd2lwZXIudG91Y2hlc0RpcmVjdGlvbiAmJiBpc0xvb3AgJiYgTWF0aC5hYnMoZGlmZikgPj0gMSkge1xyXG4gICAgLy8gbmVlZCBhbm90aGVyIGxvb3AgZml4XHJcbiAgICBzd2lwZXIubG9vcEZpeCh7XHJcbiAgICAgIGRpcmVjdGlvbj
9266ogc3dpcGVyLnN3aXBlRGlyZWN0aW9uLFxyXG4gICAgICBzZXRUcmFuc2xhdGU6IHRydWUsXHJcbiAgICB9KTtcclxuICAgIGxvb3BGaXhlZCA9IHRydWU7XHJcbiAgfVxyXG4gIHN3aXBlci5lbWl0KCdzbGlkZXJNb3ZlJywgZSk7XHJcbiAgZGF0YS5pc01vdmVkID0gdHJ1ZTtcclxuICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBkaWZmICsgZGF0YS5zdGFydFRyYW5zbGF0ZTtcclxuICBsZXQgZGlzYWJsZVBhcmVudFN3aXBlciA9IHRydWU7XHJcbiAgbGV0IHJlc2lzdGFuY2VSYXRpbyA9IHBhcmFtcy5yZXNpc3RhbmNlUmF0aW87XHJcbiAgaWYgKHBhcmFtcy50b3VjaFJlbGVhc2VPbkVkZ2VzKSB7XHJcbiAgICByZXNpc3RhbmNlUmF0aW8gPSAwO1xyXG4gIH1cclxuICBpZiAoZGlmZiA+IDApIHtcclxuICAgIGlmIChcclxuICAgICAgaXNMb29wICYmXHJcbiAgICAgICFsb29wRml4ZWQgJiZcclxuICAgICAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID4gKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyA/IHN3aXBlci5taW5UcmFuc2xhdGUoKSAtIHN3aXBlci5zaXplIC8gMiA6IHN3aXBlci5taW5UcmFuc2xhdGUoKSlcclxuICAgICkge1xyXG4gICAgICBzd2lwZXIubG9vcEZpeCh7XHJcbiAgICAgICAgZGlyZWN0aW9uOiAncHJldicsXHJcbiAgICAgICAgc2V0VHJhbnNsYXRlOiB0cnVlLFxyXG4gICAgICAgIGFjdGl2ZVNsaWRlSW5kZXg6IDAsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKGRhdGEuY3VycmVudFRyYW5zbGF0ZSA+IHN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xyXG4gICAgICBkaXNhYmxlUGFyZW50U3dpcGVyID0gZmFsc2U7XHJcbiAgICAgIGlmIChwYXJhbXMucmVzaXN0YW5jZSkge1xyXG4gICAgICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9XHJcbiAgICAgICAgICBzd2lwZXIubWluVHJhbnNsYXRlKCkgLSAxICsgKC1zd2lwZXIubWluVHJhbnNsYXRlKCkgKyBkYXRhLnN0YXJ0VHJhbnNsYXRlICsgZGlmZikgKiogcmVzaXN0YW5jZVJhdGlvO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIGlmIChkaWZmIDwgMCkge1xyXG4gICAgaWYgKFxyXG4gICAgICBpc0xvb3AgJiZcclxuICAgICAgIWxvb3BGaXhlZCAmJlxyXG4gICAgICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPCAocGFyYW1zLmNlbnRlcmVkU2xpZGVzID8gc3dpcGVyLm1heFRyYW5zbGF0ZSgpICsgc3dpcGVyLnNpemUgLyAyIDogc3dpcGVyLm1heFRyYW5zbGF0ZSgpKVxyXG4gICAgKSB7XHJcbiAgICAgIHN3aXBlci5sb29wRml4KHtcclxuICAgICAgICBkaXJlY3Rpb246ICduZXh0JyxcclxuICAgICAgICBzZXRUcmFuc2xhdGU6IHRydWUsXHJcbiAgICAgICAgYWN0aXZlU2xpZGVJbmRleDpcclxuICAgICAgICAgIHN3aXBlci5zbGlkZXMubGVuZ3RoIC1cclxuICAgICAgICAgIChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nXHJcbiAgICAgICAgICAgID8gc3dpcGVyLnNsaWRlc1BlclZpZXdEeW5hbWljKClcclxuICAgICAgICAgICAgOiBNYXRoLmNlaWwocGFyc2VGbG9hdChwYXJhbXMuc2xpZGVzUGVyVmlldywgMTApKSksXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKGRhdGEuY3VycmVudFRyYW5zbGF0ZSA8IHN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xyXG4gICAgICBkaXNhYmxlUGFyZW50U3dpcGVyID0gZmFsc2U7XHJcbiAgICAgIGlmIChwYXJhbXMucmVzaXN0YW5jZSkge1xyXG4gICAgICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9XHJcbiAgICAgICAgICBzd2lwZXIubWF4VHJhbnNsYXRlKCkgKyAxIC0gKHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIGRhdGEuc3RhcnRUcmFuc2xhdGUgLSBkaWZmKSAqKiByZXNpc3RhbmNlUmF0aW87XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGRpc2FibGVQYXJlbnRTd2lwZXIpIHtcclxuICAgIGUucHJldmVudGVkQnlOZXN0ZWRTd2lwZXIgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLy8gRGlyZWN0aW9ucyBsb2Nrc1xyXG4gIGlmICghc3dpcGVyLmFsbG93U2xpZGVOZXh0ICYmIHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnICYmIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA8IGRhdGEuc3RhcnRUcmFuc2xhdGUpIHtcclxuICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XHJcbiAgfVxyXG4gIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmIHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ3ByZXYnICYmIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA+IGRhdGEuc3RhcnRUcmFuc2xhdGUpIHtcclxuICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XHJcbiAgfVxyXG4gIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmICFzd2lwZXIuYWxsb3dTbGlkZU5leHQpIHtcclxuICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XHJcbiAgfVxyXG5cclxuICAvLyBUaHJlc2hvbGRcclxuICBpZiAocGFyYW1zLnRocmVzaG9sZCA+IDApIHtcclxuICAgIGlmIChNYXRoLmFicyhkaWZmKSA+IHBhcmFtcy50aHJlc2hvbGQgfHwgZGF0YS5hbGxvd1RocmVzaG9sZE1vdmUpIHtcclxuICAgICAgaWYgKCFkYXRhLmFsbG93VGhyZXNob2xkTW92ZSkge1xyXG4gICAgICAgIGRhdGEuYWxsb3dUaHJlc2hvbGRNb3ZlID0gdHJ1ZTtcclxuICAgICAgICB0b3VjaGVzLnN0YXJ0WCA9IHRvdWNoZXMuY3VycmVudFg7XHJcbiAgICAgICAgdG91Y2hlcy5zdGFydFkgPSB0b3VjaGVzLmN1cnJlbnRZO1xyXG4gICAgICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XHJcbiAgICAgICAgdG91Y2hlcy5kaWZmID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gdG91Y2hlcy5jdXJyZW50WCAtIHRvdWNoZXMuc3RhcnRYIDogdG91Y2hlcy5jdXJyZW50WSAtIHRvdWNoZXMuc3RhcnRZO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gZGF0YS5zdGFydFRyYW5zbGF0ZTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoIXBhcmFtcy5mb2xsb3dGaW5nZXIgfHwgcGFyYW1zLmNzc01vZGUpIHJldHVybjtcclxuXHJcbiAgLy8gVXBkYXRlIGFjdGl2ZSBpbmRleCBpbiBmcmVlIG1vZGVcclxuICBpZiAoKHBhcmFtcy5mcmVlTW9kZSAmJiBwYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCAmJiBzd2lwZXIuZnJlZU1vZGUpIHx8IHBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcclxuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuZnJlZU1vZGUgJiYgcGFyYW1zLmZyZWVNb2RlLmVuYWJsZWQgJiYgc3dpcGVyLmZyZWVNb2RlKSB7XHJcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaE1vdmUoKTtcclxuICB9XHJcbiAgLy8gVXBkYXRlIHByb2dyZXNzXHJcbiAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKGRhdGEuY3VycmVudFRyYW5zbGF0ZSk7XHJcbiAgLy8gVXBkYXRlIHRyYW5zbGF0ZVxyXG4gIHN3aXBlci5zZXRUcmFuc2xhdGUoZGF0YS5jdXJyZW50VHJhbnNsYXRlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Ub3VjaEVuZChldmVudCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgZGF0YSA9IHN3aXBlci50b3VjaEV2ZW50c0RhdGE7XHJcbiAgY29uc3QgcG9pbnRlckluZGV4ID0gZGF0YS5ldkNhY2hlLmZpbmRJbmRleCgoY2FjaGVkRXYpID0+IGNhY2hlZEV2LnBvaW50ZXJJZCA9PT0gZXZlbnQucG9pbnRlcklkKTtcclxuICBpZiAocG9pbnRlckluZGV4ID49IDApIHtcclxuICAgIGRhdGEuZXZDYWN
9266oZS5zcGxpY2UocG9pbnRlckluZGV4LCAxKTtcclxuICB9XHJcbiAgaWYgKFsncG9pbnRlcmNhbmNlbCcsICdwb2ludGVyb3V0JywgJ3BvaW50ZXJsZWF2ZSddLmluY2x1ZGVzKGV2ZW50LnR5cGUpKSB7XHJcbiAgICBjb25zdCBwcm9jZWVkID0gZXZlbnQudHlwZSA9PT0gJ3BvaW50ZXJjYW5jZWwnICYmIChzd2lwZXIuYnJvd3Nlci5pc1NhZmFyaSB8fCBzd2lwZXIuYnJvd3Nlci5pc1dlYlZpZXcpO1xyXG4gICAgaWYgKCFwcm9jZWVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICB9XHJcbiAgY29uc3QgeyBwYXJhbXMsIHRvdWNoZXMsIHJ0bFRyYW5zbGF0ZTogcnRsLCBzbGlkZXNHcmlkLCBlbmFibGVkIH0gPSBzd2lwZXI7XHJcbiAgaWYgKCFlbmFibGVkKSByZXR1cm47XHJcbiAgaWYgKCFwYXJhbXMuc2ltdWxhdGVUb3VjaCAmJiBldmVudC5wb2ludGVyVHlwZSA9PT0gJ21vdXNlJykgcmV0dXJuO1xyXG4gIGxldCBlID0gZXZlbnQ7XHJcbiAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcclxuICBpZiAoZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzKSB7XHJcbiAgICBzd2lwZXIuZW1pdCgndG91Y2hFbmQnLCBlKTtcclxuICB9XHJcbiAgZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzID0gZmFsc2U7XHJcbiAgaWYgKCFkYXRhLmlzVG91Y2hlZCkge1xyXG4gICAgaWYgKGRhdGEuaXNNb3ZlZCAmJiBwYXJhbXMuZ3JhYkN1cnNvcikge1xyXG4gICAgICBzd2lwZXIuc2V0R3JhYkN1cnNvcihmYWxzZSk7XHJcbiAgICB9XHJcbiAgICBkYXRhLmlzTW92ZWQgPSBmYWxzZTtcclxuICAgIGRhdGEuc3RhcnRNb3ZpbmcgPSBmYWxzZTtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgLy8gUmV0dXJuIEdyYWIgQ3Vyc29yXHJcbiAgaWYgKFxyXG4gICAgcGFyYW1zLmdyYWJDdXJzb3IgJiZcclxuICAgIGRhdGEuaXNNb3ZlZCAmJlxyXG4gICAgZGF0YS5pc1RvdWNoZWQgJiZcclxuICAgIChzd2lwZXIuYWxsb3dTbGlkZU5leHQgPT09IHRydWUgfHwgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID09PSB0cnVlKVxyXG4gICkge1xyXG4gICAgc3dpcGVyLnNldEdyYWJDdXJzb3IoZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgLy8gVGltZSBkaWZmXHJcbiAgY29uc3QgdG91Y2hFbmRUaW1lID0gbm93KCk7XHJcbiAgY29uc3QgdGltZURpZmYgPSB0b3VjaEVuZFRpbWUgLSBkYXRhLnRvdWNoU3RhcnRUaW1lO1xyXG5cclxuICAvLyBUYXAsIGRvdWJsZVRhcCwgQ2xpY2tcclxuICBpZiAoc3dpcGVyLmFsbG93Q2xpY2spIHtcclxuICAgIGNvbnN0IHBhdGhUcmVlID0gZS5wYXRoIHx8IChlLmNvbXBvc2VkUGF0aCAmJiBlLmNvbXBvc2VkUGF0aCgpKTtcclxuICAgIHN3aXBlci51cGRhdGVDbGlja2VkU2xpZGUoKHBhdGhUcmVlICYmIHBhdGhUcmVlWzBdKSB8fCBlLnRhcmdldCk7XHJcbiAgICBzd2lwZXIuZW1pdCgndGFwIGNsaWNrJywgZSk7XHJcbiAgICBpZiAodGltZURpZmYgPCAzMDAgJiYgdG91Y2hFbmRUaW1lIC0gZGF0YS5sYXN0Q2xpY2tUaW1lIDwgMzAwKSB7XHJcbiAgICAgIHN3aXBlci5lbWl0KCdkb3VibGVUYXAgZG91YmxlQ2xpY2snLCBlKTtcclxuICAgIH1cclxuICB9XHJcbiAgZGF0YS5sYXN0Q2xpY2tUaW1lID0gbm93KCk7XHJcbiAgbmV4dFRpY2soKCkgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIuZGVzdHJveWVkKSBzd2lwZXIuYWxsb3dDbGljayA9IHRydWU7XHJcbiAgfSk7XHJcbiAgaWYgKFxyXG4gICAgIWRhdGEuaXNUb3VjaGVkIHx8XHJcbiAgICAhZGF0YS5pc01vdmVkIHx8XHJcbiAgICAhc3dpcGVyLnN3aXBlRGlyZWN0aW9uIHx8XHJcbiAgICB0b3VjaGVzLmRpZmYgPT09IDAgfHxcclxuICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9PT0gZGF0YS5zdGFydFRyYW5zbGF0ZVxyXG4gICkge1xyXG4gICAgZGF0YS5pc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgZGF0YS5zdGFydE1vdmluZyA9IGZhbHNlO1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xyXG4gIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xyXG4gIGRhdGEuc3RhcnRNb3ZpbmcgPSBmYWxzZTtcclxuICBsZXQgY3VycmVudFBvcztcclxuICBpZiAocGFyYW1zLmZvbGxvd0Zpbmdlcikge1xyXG4gICAgY3VycmVudFBvcyA9IHJ0bCA/IHN3aXBlci50cmFuc2xhdGUgOiAtc3dpcGVyLnRyYW5zbGF0ZTtcclxuICB9IGVsc2Uge1xyXG4gICAgY3VycmVudFBvcyA9IC1kYXRhLmN1cnJlbnRUcmFuc2xhdGU7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLmZyZWVNb2RlICYmIHBhcmFtcy5mcmVlTW9kZS5lbmFibGVkKSB7XHJcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaEVuZCh7XHJcbiAgICAgIGN1cnJlbnRQb3MsXHJcbiAgICB9KTtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIEZpbmQgY3VycmVudCBzbGlkZVxyXG4gIGxldCBzdG9wSW5kZXggPSAwO1xyXG4gIGxldCBncm91cFNpemUgPSBzd2lwZXIuc2xpZGVzU2l6ZXNHcmlkWzBdO1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzR3JpZC5sZW5ndGg7IGkgKz0gaSA8IHBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAgPyAxIDogcGFyYW1zLnNsaWRlc1Blckdyb3VwKSB7XHJcbiAgICBjb25zdCBpbmNyZW1lbnQgPSBpIDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCAtIDEgPyAxIDogcGFyYW1zLnNsaWRlc1Blckdyb3VwO1xyXG4gICAgaWYgKHR5cGVvZiBzbGlkZXNHcmlkW2kgKyBpbmNyZW1lbnRdICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBpZiAoY3VycmVudFBvcyA+PSBzbGlkZXNHcmlkW2ldICYmIGN1cnJlbnRQb3MgPCBzbGlkZXNHcmlkW2kgKyBpbmNyZW1lbnRdKSB7XHJcbiAgICAgICAgc3RvcEluZGV4ID0gaTtcclxuICAgICAgICBncm91cFNpemUgPSBzbGlkZXNHcmlkW2kgKyBpbmNyZW1lbnRdIC0gc2xpZGVzR3JpZFtpXTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChjdXJyZW50UG9zID49IHNsaWRlc0dyaWRbaV0pIHtcclxuICAgICAgc3RvcEluZGV4ID0gaTtcclxuICAgICAgZ3JvdXBTaXplID0gc2xpZGVzR3JpZFtzbGlkZXNHcmlkLmxlbmd0aCAtIDFdIC0gc2xpZGVzR3JpZFtzbGlkZXNHcmlkLmxlbmd0aCAtIDJdO1xyXG4gICAgfVxyXG4gIH1cclxuICBsZXQgcmV3aW5kRmlyc3RJbmRleCA9IG51bGw7XHJcbiAgbGV0IHJld2luZExhc3RJbmRleCA9IG51bGw7XHJcbiAgaWYgKHBhcmFtcy5yZXdpbmQpIHtcclxuICAgIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcpIHtcclxuICAgICAgcmV3aW5kTGFzdEluZGV4ID1cclxuICAgICAgICBwYXJhbXMudmlydHVhbCAmJiBwYXJhbXMudmlydHVhbC5lbmFibGVkICYmIHN3aXBlci52aXJ0dWFsXHJcbiAgICAgICAgICA/IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggLSAxXHJcbiAgICAgICAgICA6IHN3aXBlci5zbGlkZXMubGVuZ3RoIC0gMTtcclxuICAgIH0gZWxzZSBpZiAoc3dpcGVyLmlzRW5kKSB7XHJcbiAgICAgIHJld2luZEZpcnN0SW5kZXggPSAwO1xyXG4gICAgfVxyXG4gIH1cclxuICAvLyBGaW5kIGN1cnJlbnQgc2xpZGUgc2l6ZVxyXG4gIGNvbnN0IHJhdGlvID0gKGN1cnJlbnRQb3MgLSBzbGlkZXNHcmlkW3N0b3BJbmRleF0pIC8gZ3JvdXBTaXplO1xyXG4gIGNvbnN0IGluY3JlbWVudCA9IHN0b3BJbmRleCA8IHBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAgLSAxID8gMSA6IHBhcmFtcy5zbGlkZXNQZXJHcm91cDtcclxuICBpZiAodGltZURpZmYgPiBwYXJhbXMubG9uZ1N3aXBlc01zKSB7XHJcbiAgICAvLyBMb25nIHRvdWNoZXNcclxuICAgIGlmICghcGFyYW1zLmxvbmdTd2lwZXMpIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnKSB7XHJcbiAgICAgIGlmIChyYXRpbyA+PSBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKVxyXG4gICAgICAgI
9266HN3aXBlci5zbGlkZVRvKHBhcmFtcy5yZXdpbmQgJiYgc3dpcGVyLmlzRW5kID8gcmV3aW5kRmlyc3RJbmRleCA6IHN0b3BJbmRleCArIGluY3JlbWVudCk7XHJcbiAgICAgIGVsc2Ugc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICdwcmV2Jykge1xyXG4gICAgICBpZiAocmF0aW8gPiAxIC0gcGFyYW1zLmxvbmdTd2lwZXNSYXRpbykge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN0b3BJbmRleCArIGluY3JlbWVudCk7XHJcbiAgICAgIH0gZWxzZSBpZiAocmV3aW5kTGFzdEluZGV4ICE9PSBudWxsICYmIHJhdGlvIDwgMCAmJiBNYXRoLmFicyhyYXRpbykgPiBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKSB7XHJcbiAgICAgICAgc3dpcGVyLnNsaWRlVG8ocmV3aW5kTGFzdEluZGV4KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzdG9wSW5kZXgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIFNob3J0IHN3aXBlc1xyXG4gICAgaWYgKCFwYXJhbXMuc2hvcnRTd2lwZXMpIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaXNOYXZCdXR0b25UYXJnZXQgPVxyXG4gICAgICBzd2lwZXIubmF2aWdhdGlvbiAmJiAoZS50YXJnZXQgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCB8fCBlLnRhcmdldCA9PT0gc3dpcGVyLm5hdmlnYXRpb24ucHJldkVsKTtcclxuICAgIGlmICghaXNOYXZCdXR0b25UYXJnZXQpIHtcclxuICAgICAgaWYgKHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnKSB7XHJcbiAgICAgICAgc3dpcGVyLnNsaWRlVG8ocmV3aW5kRmlyc3RJbmRleCAhPT0gbnVsbCA/IHJld2luZEZpcnN0SW5kZXggOiBzdG9wSW5kZXggKyBpbmNyZW1lbnQpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICdwcmV2Jykge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHJld2luZExhc3RJbmRleCAhPT0gbnVsbCA/IHJld2luZExhc3RJbmRleCA6IHN0b3BJbmRleCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoZS50YXJnZXQgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCkge1xyXG4gICAgICBzd2lwZXIuc2xpZGVUbyhzdG9wSW5kZXggKyBpbmNyZW1lbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uUmVzaXplKCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIGVsIH0gPSBzd2lwZXI7XHJcbiAgaWYgKGVsICYmIGVsLm9mZnNldFdpZHRoID09PSAwKSByZXR1cm47XHJcblxyXG4gIC8vIEJyZWFrcG9pbnRzXHJcbiAgaWYgKHBhcmFtcy5icmVha3BvaW50cykge1xyXG4gICAgc3dpcGVyLnNldEJyZWFrcG9pbnQoKTtcclxuICB9XHJcblxyXG4gIC8vIFNhdmUgbG9ja3NcclxuICBjb25zdCB7IGFsbG93U2xpZGVOZXh0LCBhbGxvd1NsaWRlUHJldiwgc25hcEdyaWQgfSA9IHN3aXBlcjtcclxuICBjb25zdCBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcclxuXHJcbiAgLy8gRGlzYWJsZSBsb2NrcyBvbiByZXNpemVcclxuICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSB0cnVlO1xyXG4gIHN3aXBlci5hbGxvd1NsaWRlUHJldiA9IHRydWU7XHJcbiAgc3dpcGVyLnVwZGF0ZVNpemUoKTtcclxuICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XHJcbiAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcclxuICBjb25zdCBpc1ZpcnR1YWxMb29wID0gaXNWaXJ0dWFsICYmIHBhcmFtcy5sb29wO1xyXG4gIGlmIChcclxuICAgIChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nIHx8IHBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkgJiZcclxuICAgIHN3aXBlci5pc0VuZCAmJlxyXG4gICAgIXN3aXBlci5pc0JlZ2lubmluZyAmJlxyXG4gICAgIXN3aXBlci5wYXJhbXMuY2VudGVyZWRTbGlkZXMgJiZcclxuICAgICFpc1ZpcnR1YWxMb29wXHJcbiAgKSB7XHJcbiAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcclxuICB9IGVsc2Uge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCAmJiAhaXNWaXJ0dWFsKSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvTG9vcChzd2lwZXIucmVhbEluZGV4LCAwLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKHN3aXBlci5hdXRvcGxheSAmJiBzd2lwZXIuYXV0b3BsYXkucnVubmluZyAmJiBzd2lwZXIuYXV0b3BsYXkucGF1c2VkKSB7XHJcbiAgICBjbGVhclRpbWVvdXQoc3dpcGVyLmF1dG9wbGF5LnJlc2l6ZVRpbWVvdXQpO1xyXG4gICAgc3dpcGVyLmF1dG9wbGF5LnJlc2l6ZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgaWYgKHN3aXBlci5hdXRvcGxheSAmJiBzd2lwZXIuYXV0b3BsYXkucnVubmluZyAmJiBzd2lwZXIuYXV0b3BsYXkucGF1c2VkKSB7XHJcbiAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnJlc3VtZSgpO1xyXG4gICAgICB9XHJcbiAgICB9LCA1MDApO1xyXG4gIH1cclxuICAvLyBSZXR1cm4gbG9ja3MgYWZ0ZXIgcmVzaXplXHJcbiAgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID0gYWxsb3dTbGlkZVByZXY7XHJcbiAgc3dpcGVyLmFsbG93U2xpZGVOZXh0ID0gYWxsb3dTbGlkZU5leHQ7XHJcbiAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzbmFwR3JpZCAhPT0gc3dpcGVyLnNuYXBHcmlkKSB7XHJcbiAgICBzd2lwZXIuY2hlY2tPdmVyZmxvdygpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gb25DbGljayhlKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XHJcbiAgaWYgKCFzd2lwZXIuYWxsb3dDbGljaykge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMucHJldmVudENsaWNrcykgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMucHJldmVudENsaWNrc1Byb3BhZ2F0aW9uICYmIHN3aXBlci5hbmltYXRpbmcpIHtcclxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgZS5zdG9wSW1tZWRpYXRlUHJv
9266cGFnYXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uU2Nyb2xsKCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyB3cmFwcGVyRWwsIHJ0bFRyYW5zbGF0ZSwgZW5hYmxlZCB9ID0gc3dpcGVyO1xyXG4gIGlmICghZW5hYmxlZCkgcmV0dXJuO1xyXG4gIHN3aXBlci5wcmV2aW91c1RyYW5zbGF0ZSA9IHN3aXBlci50cmFuc2xhdGU7XHJcbiAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgc3dpcGVyLnRyYW5zbGF0ZSA9IC13cmFwcGVyRWwuc2Nyb2xsTGVmdDtcclxuICB9IGVsc2Uge1xyXG4gICAgc3dpcGVyLnRyYW5zbGF0ZSA9IC13cmFwcGVyRWwuc2Nyb2xsVG9wO1xyXG4gIH1cclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICBpZiAoc3dpcGVyLnRyYW5zbGF0ZSA9PT0gMCkgc3dpcGVyLnRyYW5zbGF0ZSA9IDA7XHJcbiAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XHJcbiAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcclxuICBsZXQgbmV3UHJvZ3Jlc3M7XHJcbiAgY29uc3QgdHJhbnNsYXRlc0RpZmYgPSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XHJcbiAgaWYgKHRyYW5zbGF0ZXNEaWZmID09PSAwKSB7XHJcbiAgICBuZXdQcm9ncmVzcyA9IDA7XHJcbiAgfSBlbHNlIHtcclxuICAgIG5ld1Byb2dyZXNzID0gKHN3aXBlci50cmFuc2xhdGUgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIC8gdHJhbnNsYXRlc0RpZmY7XHJcbiAgfVxyXG4gIGlmIChuZXdQcm9ncmVzcyAhPT0gc3dpcGVyLnByb2dyZXNzKSB7XHJcbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MocnRsVHJhbnNsYXRlID8gLXN3aXBlci50cmFuc2xhdGUgOiBzd2lwZXIudHJhbnNsYXRlKTtcclxuICB9XHJcbiAgc3dpcGVyLmVtaXQoJ3NldFRyYW5zbGF0ZScsIHN3aXBlci50cmFuc2xhdGUsIGZhbHNlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Mb2FkKGUpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIHByb2Nlc3NMYXp5UHJlbG9hZGVyKHN3aXBlciwgZS50YXJnZXQpO1xyXG4gIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUgfHwgKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyAhPT0gJ2F1dG8nICYmICFzd2lwZXIucGFyYW1zLmF1dG9IZWlnaHQpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIHN3aXBlci51cGRhdGUoKTtcclxufVxyXG5cclxubGV0IGR1bW15RXZlbnRBdHRhY2hlZCA9IGZhbHNlO1xyXG5mdW5jdGlvbiBkdW1teUV2ZW50TGlzdGVuZXIoKSB7fVxyXG5jb25zdCBldmVudHMgPSAoc3dpcGVyLCBtZXRob2QpID0+IHtcclxuICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XHJcbiAgY29uc3QgeyBwYXJhbXMsIGVsLCB3cmFwcGVyRWwsIGRldmljZSB9ID0gc3dpcGVyO1xyXG4gIGNvbnN0IGNhcHR1cmUgPSAhIXBhcmFtcy5uZXN0ZWQ7XHJcbiAgY29uc3QgZG9tTWV0aG9kID0gbWV0aG9kID09PSAnb24nID8gJ2FkZEV2ZW50TGlzdGVuZXInIDogJ3JlbW92ZUV2ZW50TGlzdGVuZXInO1xyXG4gIGNvbnN0IHN3aXBlck1ldGhvZCA9IG1ldGhvZDtcclxuXHJcbiAgLy8gVG91Y2ggRXZlbnRzXHJcbiAgZWxbZG9tTWV0aG9kXSgncG9pbnRlcmRvd24nLCBzd2lwZXIub25Ub3VjaFN0YXJ0LCB7XHJcbiAgICBwYXNzaXZlOiBmYWxzZSxcclxuICB9KTtcclxuICBkb2N1bWVudFtkb21NZXRob2RdKCdwb2ludGVybW92ZScsIHN3aXBlci5vblRvdWNoTW92ZSwge1xyXG4gICAgcGFzc2l2ZTogZmFsc2UsXHJcbiAgICBjYXB0dXJlLFxyXG4gIH0pO1xyXG4gIGRvY3VtZW50W2RvbU1ldGhvZF0oJ3BvaW50ZXJ1cCcsIHN3aXBlci5vblRvdWNoRW5kLCB7XHJcbiAgICBwYXNzaXZlOiB0cnVlLFxyXG4gIH0pO1xyXG4gIGRvY3VtZW50W2RvbU1ldGhvZF0oJ3BvaW50ZXJjYW5jZWwnLCBzd2lwZXIub25Ub3VjaEVuZCwge1xyXG4gICAgcGFzc2l2ZTogdHJ1ZSxcclxuICB9KTtcclxuICBkb2N1bWVudFtkb21NZXRob2RdKCdwb2ludGVyb3V0Jywgc3dpcGVyLm9uVG91Y2hFbmQsIHtcclxuICAgIHBhc3NpdmU6IHRydWUsXHJcbiAgfSk7XHJcbiAgZG9jdW1lbnRbZG9tTWV0aG9kXSgncG9pbnRlcmxlYXZlJywgc3dpcGVyLm9uVG91Y2hFbmQsIHtcclxuICAgIHBhc3NpdmU6IHRydWUsXHJcbiAgfSk7XHJcblxyXG4gIC8vIFByZXZlbnQgTGlua3MgQ2xpY2tzXHJcbiAgaWYgKHBhcmFtcy5wcmV2ZW50Q2xpY2tzIHx8IHBhcmFtcy5wcmV2ZW50Q2xpY2tzUHJvcGFnYXRpb24pIHtcclxuICAgIGVsW2RvbU1ldGhvZF0oJ2NsaWNrJywgc3dpcGVyLm9uQ2xpY2ssIHRydWUpO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLmNzc01vZGUpIHtcclxuICAgIHdyYXBwZXJFbFtkb21NZXRob2RdKCdzY3JvbGwnLCBzd2lwZXIub25TY3JvbGwpO1xyXG4gIH1cclxuXHJcbiAgLy8gUmVzaXplIGhhbmRsZXJcclxuICBpZiAocGFyYW1zLnVwZGF0ZU9uV2luZG93UmVzaXplKSB7XHJcbiAgICBzd2lwZXJbc3dpcGVyTWV0aG9kXShcclxuICAgICAgZGV2aWNlLmlvcyB8fCBkZXZpY2UuYW5kcm9pZCA/ICdyZXNpemUgb3JpZW50YXRpb25jaGFuZ2Ugb2JzZXJ2ZXJVcGRhdGUnIDogJ3Jlc2l6ZSBvYnNlcnZlclVwZGF0ZScsXHJcbiAgICAgIG9uUmVzaXplLFxyXG4gICAgICB0cnVlXHJcbiAgICApO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBzd2lwZXJbc3dpcGVyTWV0aG9kXSgnb2JzZXJ2ZXJVcGRhdGUnLCBvblJlc2l6ZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICAvLyBJbWFnZXMgbG9hZGVyXHJcbiAgZWxbZG9tTWV0aG9kXSgnbG9hZCcsIHN3aXBlci5vbkxvYWQsIHtcclxuICAgIGNhcHR1cmU6IHRydWUsXHJcbiAgfSk7XHJcbn07XHJcbmZ1bmN0aW9uIGF0dGFjaEV2ZW50cygpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICBjb25zdCB7IHBhcmFtcyB9ID0gc3dpcGVyO1xyXG4gIHN3aXBlci5vblRvdWNoU3RhcnQgPSBvblRvdWNoU3RhcnQuYmluZChzd2lwZXIpO1xyXG4gIHN3aXBlci5vblRvdWNoTW92ZSA9IG9uVG91Y2hNb3ZlLmJpbmQoc3dpcGVyKTtcclxuICBzd2lwZXIub25Ub3VjaEVuZCA9IG9uVG91Y2hFbmQuYmluZChzd2lwZXIpO1xyXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgc3dpcGVyLm9uU2Nyb2xsID0gb25TY3JvbGwuYmluZChzd2lwZXIpO1xyXG4gIH1cclxuICBzd2lwZXIub25DbGljayA9IG9uQ2xpY2suYmluZChzd2lwZXIpO1xyXG4gIHN3aXBlci5vbkxvYWQgPSBvbkxvYWQuYmluZChzd2lwZXIpO1xyXG4gIGlmICghZHVtbXlFdmVudEF0dGFjaGVkKSB7XHJcbiAgICBkb2
9266N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgZHVtbXlFdmVudExpc3RlbmVyKTtcclxuICAgIGR1bW15RXZlbnRBdHRhY2hlZCA9IHRydWU7XHJcbiAgfVxyXG4gIGV2ZW50cyhzd2lwZXIsICdvbicpO1xyXG59XHJcbmZ1bmN0aW9uIGRldGFjaEV2ZW50cygpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGV2ZW50cyhzd2lwZXIsICdvZmYnKTtcclxufVxyXG52YXIgZXZlbnRzJDEgPSB7XHJcbiAgYXR0YWNoRXZlbnRzLFxyXG4gIGRldGFjaEV2ZW50cyxcclxufTtcclxuXHJcbmNvbnN0IGlzR3JpZEVuYWJsZWQgPSAoc3dpcGVyLCBwYXJhbXMpID0+IHtcclxuICByZXR1cm4gc3dpcGVyLmdyaWQgJiYgcGFyYW1zLmdyaWQgJiYgcGFyYW1zLmdyaWQucm93cyA+IDE7XHJcbn07XHJcbmZ1bmN0aW9uIHNldEJyZWFrcG9pbnQoKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCB7IHJlYWxJbmRleCwgaW5pdGlhbGl6ZWQsIHBhcmFtcywgZWwgfSA9IHN3aXBlcjtcclxuICBjb25zdCBicmVha3BvaW50cyA9IHBhcmFtcy5icmVha3BvaW50cztcclxuICBpZiAoIWJyZWFrcG9pbnRzIHx8IChicmVha3BvaW50cyAmJiBPYmplY3Qua2V5cyhicmVha3BvaW50cykubGVuZ3RoID09PSAwKSkgcmV0dXJuO1xyXG5cclxuICAvLyBHZXQgYnJlYWtwb2ludCBmb3Igd2luZG93IHdpZHRoIGFuZCB1cGRhdGUgcGFyYW1ldGVyc1xyXG4gIGNvbnN0IGJyZWFrcG9pbnQgPSBzd2lwZXIuZ2V0QnJlYWtwb2ludChicmVha3BvaW50cywgc3dpcGVyLnBhcmFtcy5icmVha3BvaW50c0Jhc2UsIHN3aXBlci5lbCk7XHJcbiAgaWYgKCFicmVha3BvaW50IHx8IHN3aXBlci5jdXJyZW50QnJlYWtwb2ludCA9PT0gYnJlYWtwb2ludCkgcmV0dXJuO1xyXG4gIGNvbnN0IGJyZWFrcG9pbnRPbmx5UGFyYW1zID0gYnJlYWtwb2ludCBpbiBicmVha3BvaW50cyA/IGJyZWFrcG9pbnRzW2JyZWFrcG9pbnRdIDogdW5kZWZpbmVkO1xyXG4gIGNvbnN0IGJyZWFrcG9pbnRQYXJhbXMgPSBicmVha3BvaW50T25seVBhcmFtcyB8fCBzd2lwZXIub3JpZ2luYWxQYXJhbXM7XHJcbiAgY29uc3Qgd2FzTXVsdGlSb3cgPSBpc0dyaWRFbmFibGVkKHN3aXBlciwgcGFyYW1zKTtcclxuICBjb25zdCBpc011bHRpUm93ID0gaXNHcmlkRW5hYmxlZChzd2lwZXIsIGJyZWFrcG9pbnRQYXJhbXMpO1xyXG4gIGNvbnN0IHdhc0VuYWJsZWQgPSBwYXJhbXMuZW5hYmxlZDtcclxuICBpZiAod2FzTXVsdGlSb3cgJiYgIWlzTXVsdGlSb3cpIHtcclxuICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoYCR7cGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9Z3JpZGAsIGAke3BhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfWdyaWQtY29sdW1uYCk7XHJcbiAgICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcclxuICB9IGVsc2UgaWYgKCF3YXNNdWx0aVJvdyAmJiBpc011bHRpUm93KSB7XHJcbiAgICBlbC5jbGFzc0xpc3QuYWRkKGAke3BhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfWdyaWRgKTtcclxuICAgIGlmIChcclxuICAgICAgKGJyZWFrcG9pbnRQYXJhbXMuZ3JpZC5maWxsICYmIGJyZWFrcG9pbnRQYXJhbXMuZ3JpZC5maWxsID09PSAnY29sdW1uJykgfHxcclxuICAgICAgKCFicmVha3BvaW50UGFyYW1zLmdyaWQuZmlsbCAmJiBwYXJhbXMuZ3JpZC5maWxsID09PSAnY29sdW1uJylcclxuICAgICkge1xyXG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKGAke3BhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfWdyaWQtY29sdW1uYCk7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcclxuICB9XHJcblxyXG4gIC8vIFRvZ2dsZSBuYXZpZ2F0aW9uLCBwYWdpbmF0aW9uLCBzY3JvbGxiYXJcclxuICBbJ25hdmlnYXRpb24nLCAncGFnaW5hdGlvbicsICdzY3JvbGxiYXInXS5mb3JFYWNoKChwcm9wKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIGJyZWFrcG9pbnRQYXJhbXNbcHJvcF0gPT09ICd1bmRlZmluZWQnKSByZXR1cm47XHJcbiAgICBjb25zdCB3YXNNb2R1bGVFbmFibGVkID0gcGFyYW1zW3Byb3BdICYmIHBhcmFtc1twcm9wXS5lbmFibGVkO1xyXG4gICAgY29uc3QgaXNNb2R1bGVFbmFibGVkID0gYnJlYWtwb2ludFBhcmFtc1twcm9wXSAmJiBicmVha3BvaW50UGFyYW1zW3Byb3BdLmVuYWJsZWQ7XHJcbiAgICBpZiAod2FzTW9kdWxlRW5hYmxlZCAmJiAhaXNNb2R1bGVFbmFibGVkKSB7XHJcbiAgICAgIHN3aXBlcltwcm9wXS5kaXNhYmxlKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXdhc01vZHVsZUVuYWJsZWQgJiYgaXNNb2R1bGVFbmFibGVkKSB7XHJcbiAgICAgIHN3aXBlcltwcm9wXS5lbmFibGUoKTtcclxuICAgIH1cclxuICB9KTtcclxuICBjb25zdCBkaXJlY3Rpb25DaGFuZ2VkID0gYnJlYWtwb2ludFBhcmFtcy5kaXJlY3Rpb24gJiYgYnJlYWtwb2ludFBhcmFtcy5kaXJlY3Rpb24gIT09IHBhcmFtcy5kaXJlY3Rpb247XHJcbiAgY29uc3QgbmVlZHNSZUxvb3AgPSBwYXJhbXMubG9vcCAmJiAoYnJlYWtwb2ludFBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSBwYXJhbXMuc2xpZGVzUGVyVmlldyB8fCBkaXJlY3Rpb25DaGFuZ2VkKTtcclxuICBpZiAoZGlyZWN0aW9uQ2hhbmdlZCAmJiBpbml0aWFsaXplZCkge1xyXG4gICAgc3dpcGVyLmNoYW5nZURpcmVjdGlvbigpO1xyXG4gIH1cclxuICBleHRlbmQoc3dpcGVyLnBhcmFtcywgYnJlYWtwb2ludFBhcmFtcyk7XHJcbiAgY29uc3QgaXNFbmFibGVkID0gc3dpcGVyLnBhcmFtcy5lbmFibGVkO1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XHJcbiAgICBhbGxvd1RvdWNoTW92ZTogc3dpcGVyLnBhcmFtcy5hbGxvd1RvdWNoTW92ZSxcclxuICAgIGFsbG93U2xpZGVOZXh0OiBzd2lwZXIucGFyYW1zLmFsbG93U2xpZGVOZXh0LFxyXG4gICAgYWxsb3dTbGlkZVByZXY6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZVByZXYsXHJcbiAgfSk7XHJcbiAgaWYgKHdhc0VuYWJsZWQgJiYgIWlzRW5hYmxlZCkge1xyXG4gICAgc3dpcGVyLmRpc2FibGUoKTtcclxuICB9IGVsc2UgaWYgKCF3YXNFbmFibGVkICYmIGlzRW5hYmxlZCkge1xyXG4gICAgc3dpcGVyLmVuYWJsZSgpO1xyXG4gIH1cclxuICBzd2lwZXIuY3VycmVudEJyZWFrcG9pbnQgPSBicmVha3BvaW50O1xyXG4gIHN3aXBlci5lbWl0KCdfYmVmb3JlQnJlYWtwb2ludCcsIGJyZWFrcG9pbnRQYXJhbXMpO1xyXG4gIGlmIChuZWVkc1JlTG9vcCAmJiBpbml0aWFsaXplZCkge1xyXG4gICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XHJcbiAgICBzd2lwZXIubG9vcENyZWF0ZShyZWFsSW5kZXgpO1xyXG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xyXG4gIH1cclxuICBzd2lwZXIuZW1pdCgnYnJlYWtwb2ludCcsIGJyZWFrcG9pbnRQYXJhbXMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRCcmVha3BvaW50KGJyZWFrcG9pbnRzLCBiYXNlLCBjb250YWluZXJFbCkge1xyXG4gIGlmIChiYXNlID09PSB2b2lkIDApIHtcclxuICAgIGJhc2UgPSAnd2luZG93JztcclxuICB9XHJcbiAgaWYgKCFicmVha3BvaW50cyB8fCAoYmFzZSA9PT0gJ2Nvbn
9266RhaW5lcicgJiYgIWNvbnRhaW5lckVsKSkgcmV0dXJuIHVuZGVmaW5lZDtcclxuICBsZXQgYnJlYWtwb2ludCA9IGZhbHNlO1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSBiYXNlID09PSAnd2luZG93JyA/IHdpbmRvdy5pbm5lckhlaWdodCA6IGNvbnRhaW5lckVsLmNsaWVudEhlaWdodDtcclxuICBjb25zdCBwb2ludHMgPSBPYmplY3Qua2V5cyhicmVha3BvaW50cykubWFwKChwb2ludCkgPT4ge1xyXG4gICAgaWYgKHR5cGVvZiBwb2ludCA9PT0gJ3N0cmluZycgJiYgcG9pbnQuaW5kZXhPZignQCcpID09PSAwKSB7XHJcbiAgICAgIGNvbnN0IG1pblJhdGlvID0gcGFyc2VGbG9hdChwb2ludC5zdWJzdHIoMSkpO1xyXG4gICAgICBjb25zdCB2YWx1ZSA9IGN1cnJlbnRIZWlnaHQgKiBtaW5SYXRpbztcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB2YWx1ZSxcclxuICAgICAgICBwb2ludCxcclxuICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHZhbHVlOiBwb2ludCxcclxuICAgICAgcG9pbnQsXHJcbiAgICB9O1xyXG4gIH0pO1xyXG4gIHBvaW50cy5zb3J0KChhLCBiKSA9PiBwYXJzZUludChhLnZhbHVlLCAxMCkgLSBwYXJzZUludChiLnZhbHVlLCAxMCkpO1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICBjb25zdCB7IHBvaW50LCB2YWx1ZSB9ID0gcG9pbnRzW2ldO1xyXG4gICAgaWYgKGJhc2UgPT09ICd3aW5kb3cnKSB7XHJcbiAgICAgIGlmICh3aW5kb3cubWF0Y2hNZWRpYShgKG1pbi13aWR0aDogJHt2YWx1ZX1weClgKS5tYXRjaGVzKSB7XHJcbiAgICAgICAgYnJlYWtwb2ludCA9IHBvaW50O1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKHZhbHVlIDw9IGNvbnRhaW5lckVsLmNsaWVudFdpZHRoKSB7X
9266HJcbiAgICAgIGJyZWFrcG9pbnQgPSBwb2ludDtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIGJyZWFrcG9pbnQgfHwgJ21heCc7XHJcbn1cclxuXHJcbnZhciBicmVha3BvaW50cyA9IHtcclxuICBzZXRCcmVha3BvaW50LFxyXG4gIGdldEJyZWFrcG9pbnQsXHJcbn07XHJcblxyXG5mdW5jdGlvbiBwcmVwYXJlQ2xhc3NlcyhlbnRyaWVzLCBwcmVmaXgpIHtcclxuICBjb25zdCByZXN1bHRDbGFzc2VzID0gW107XHJcbiAgZW50cmllcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XHJcbiAgICAgIE9iamVjdC5rZXlzKGl0ZW0pLmZvckVhY2goKGNsYXNzTmFtZXMpID0+IHtcclxuICAgICAgICBpZiAoaXRlbVtjbGFzc05hbWVzXSkge1xyXG4gICAgICAgICAgcmVzdWx0Q2xhc3Nlcy5wdXNoKHByZWZpeCArIGNsYXNzTmFtZXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xyXG4gICAgICByZXN1bHRDbGFzc2VzLnB1c2gocHJlZml4ICsgaXRlbSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgcmV0dXJuIHJlc3VsdENsYXNzZXM7XHJcbn1cclxuZnVuY3Rpb24gYWRkQ2xhc3NlcygpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHsgY2xhc3NOYW1lcywgcGFyYW1zLCBydGwsIGVsLCBkZXZpY2UgfSA9IHN3aXBlcjtcclxuICAvLyBwcmV0dGllci1pZ25vcmVcclxuICBjb25zdCBzdWZmaXhlcyA9IHByZXBhcmVDbGFzc2VzKFsnaW5pdGlhbGl6ZWQnLCBwYXJhbXMuZGlyZWN0aW9uLCB7XHJcbiAgICAgICdmcmVlLW1vZGUnOiBzd2lwZXIucGFyYW1zLmZyZWVNb2RlICYmIHBhcmFtcy5mcmVlTW9kZS5lbmFibGVkXHJcbiAgICB9LCB7XHJcbiAgICAgICdhdXRvaGVpZ2h0JzogcGFyYW1zLmF1dG9IZWlnaHRcclxuICAgIH0sIHtcclxuICAgICAgJ3J0bCc6IHJ0bFxyXG4gICAgfSwge1xyXG4gICAgICAnZ3JpZCc6IHBhcmFtcy5ncmlkICYmIHBhcmFtcy5ncmlkLnJvd3MgPiAxXHJcbiAgICB9LCB7XHJcbiAgICAgICdncmlkLWNvbHVtbic6IHBhcmFtcy5ncmlkICYmIHBhcmFtcy5ncmlkLnJvd3MgPiAxICYmIHBhcmFtcy5ncmlkLmZpbGwgPT09ICdjb2x1bW4nXHJcbiAgICB9LCB7XHJcbiAgICAgICdhbmRyb2lkJzogZGV2aWNlLmFuZHJvaWRcclxuICAgIH0sIHtcclxuICAgICAgJ2lvcyc6IGRldmljZS5pb3NcclxuICAgIH0sIHtcclxuICAgICAgJ2Nzcy1tb2RlJzogcGFyYW1zLmNzc01vZGVcclxuICAgIH0sIHtcclxuICAgICAgJ2NlbnRlcmVkJzogcGFyYW1zLmNzc01vZGUgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzXHJcbiAgICB9LCB7XHJcbiAgICAgICd3YXRjaC1wcm9ncmVzcyc6IHBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzXHJcbiAgICB9XSwgcGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MpO1xyXG4gIGNsYXNzTmFtZXMucHVzaCguLi5zdWZmaXhlcyk7XHJcbiAgZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc05hbWVzKTtcclxuICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlQ2xhc3NlcygpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHsgZWwsIGNsYXNzTmFtZXMgfSA9IHN3aXBlcjtcclxuICBlbC5jbGFzc0xpc3QucmVtb3ZlKC4uLmNsYXNzTmFtZXMpO1xyXG4gIHN3aXBlci5lbWl0Q29udGFpbmVyQ2xhc3NlcygpO1xyXG59XHJcblxyXG52YXIgY2xhc3NlcyA9IHtcclxuICBhZGRDbGFzc2VzLFxyXG4gIHJlbW92ZUNsYXNzZXMsXHJcbn07XHJcblxyXG5mdW5jdGlvbiBjaGVja092ZXJmbG93KCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBpc0xvY2tlZDogd2FzTG9ja2VkLCBwYXJhbXMgfSA9IHN3aXBlcjtcclxuICBjb25zdCB7IHNsaWRlc09mZnNldEJlZm9yZSB9ID0gcGFyYW1zO1xyXG4gIGlmIChzbGlkZXNPZmZzZXRCZWZvcmUpIHtcclxuICAgIGNvbnN0IGxhc3RTbGlkZUluZGV4ID0gc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxO1xyXG4gICAgY29uc3QgbGFzdFNsaWRlUmlnaHRFZGdlID1cclxuICAgICAgc3dpcGVyLnNsaWRlc0dyaWRbbGFzdFNsaWRlSW5kZXhdICsgc3dpcGVyLnNsaWRlc1NpemVzR3JpZFtsYXN0U2xpZGVJbmRleF0gKyBzbGlkZXNPZmZzZXRCZWZvcmUgKiAyO1xyXG4gICAgc3dpcGVyLmlzTG9ja2VkID0gc3dpcGVyLnNpemUgPiBsYXN0U2xpZGVSaWdodEVkZ2U7XHJcbiAgfSBlbHNlIHtcclxuICAgIHN3aXBlci5pc0xvY2tlZCA9IHN3aXBlci5zbmFwR3JpZC5sZW5ndGggPT09IDE7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuYWxsb3dTbGlkZU5leHQgPT09IHRydWUpIHtcclxuICAgIHN3aXBlci5hbGxvd1NsaWRlTmV4dCA9ICFzd2lwZXIuaXNMb2NrZWQ7XHJcbiAgfVxyXG4gIGlmIChwYXJhbXMuYWxsb3dTbGlkZVByZXYgPT09IHRydWUpIHtcclxuICAgIHN3aXBlci5hbGxvd1NsaWRlUHJldiA9ICFzd2lwZXIuaXNMb2NrZWQ7XHJcbiAgfVxyXG4gIGlmICh3YXNMb2NrZWQgJiYgd2FzTG9ja2VkICE9PSBzd2lwZXIuaXNMb2NrZWQpIHtcclxuICAgIHN3aXBlci5pc0VuZCA9IGZhbHNlO1xyXG4gIH1cclxuICBpZiAod2FzTG9ja2VkICE9PSBzd2lwZXIuaXNMb2NrZWQpIHtcclxuICAgIHN3aXBlci5lbWl0KHN3aXBlci5pc0xvY2tlZCA/ICdsb2NrJyA6ICd1bmxvY2snKTtcclxuICB9XHJcbn1cclxudmFyIGNoZWNrT3ZlcmZsb3ckMSA9IHtcclxuICBjaGVja092ZXJmbG93LFxyXG59O1xyXG5cclxudmFyIGRlZmF1bHRzID0ge1xyXG4gIGluaXQ6IHRydWUsXHJcbiAgZGlyZWN0aW9uOiAnaG9yaXpvbnRhbCcsXHJcbiAgb25lV2F5TW92ZW1lbnQ6IGZhbHNlLFxyXG4gIHRvdWNoRXZlbnRzVGFyZ2V0OiAnd3JhcHBlcicsXHJcbiAgaW5pdGlhbFNsaWRlOiAwLFxyXG4gIHNwZWVkOiAzMDAsXHJcbiAgY3NzTW9kZTogZmFsc2UsXHJcbiAgdXBkYXRlT25XaW5kb3dSZXNpemU6IHRydWUsXHJcbiAgcmVzaXplT2JzZXJ2ZXI6IHRydWUsXHJcbiAgbmVzdGVkOiBmYWxzZSxcclxuICBjcmVhdGVFbGVtZW50czogZmFsc2UsXHJcbiAgZW5hYmxlZDogdHJ1ZSxcclxuICBmb2N1c2FibGVFbGVtZW50czogJ2lucHV0LCBzZWxlY3QsIG9wdGlvbiwgdGV4dGFyZWEsIGJ1dHRvbiwgdmlkZW8sIGxhYmVsJyxcclxuICAvLyBPdmVycmlkZXNcclxuICB3aWR0aDogbnVsbCxcclxuICBoZWlnaHQ6IG51bGwsXHJcbiAgLy9cclxuICBwcmV2ZW50SW50ZXJhY3Rpb25PblRyYW5zaXRpb246IGZhbHNlLFxyXG4gIC8vIHNzclxyXG4gIHVzZXJBZ2VudDogbnVsbCxcclxuICB1cmw6IG51bGwsXHJcbiAgLy8gVG8gc3VwcG9ydCBpT1MncyBzd2lwZS10by1nby1iYWNrIGdlc3R1cmUgKHdoZW4gYmVpbmcgdXNlZCBpbi1hcHApLlxyXG4gIGVkZ2VTd2lwZURldGVjdGlvbj
9266ogZmFsc2UsXHJcbiAgZWRnZVN3aXBlVGhyZXNob2xkOiAyMCxcclxuICAvLyBBdXRvaGVpZ2h0XHJcbiAgYXV0b0hlaWdodDogZmFsc2UsXHJcbiAgLy8gU2V0IHdyYXBwZXIgd2lkdGhcclxuICBzZXRXcmFwcGVyU2l6ZTogZmFsc2UsXHJcbiAgLy8gVmlydHVhbCBUcmFuc2xhdGVcclxuICB2aXJ0dWFsVHJhbnNsYXRlOiBmYWxzZSxcclxuICAvLyBFZmZlY3RzXHJcbiAgZWZmZWN0OiAnc2xpZGUnLFxyXG4gIC8vICdzbGlkZScgb3IgJ2ZhZGUnIG9yICdjdWJlJyBvciAnY292ZXJmbG93JyBvciAnZmxpcCdcclxuXHJcbiAgLy8gQnJlYWtwb2ludHNcclxuICBicmVha3BvaW50czogdW5kZWZpbmVkLFxyXG4gIGJyZWFrcG9pbnRzQmFzZTogJ3dpbmRvdycsXHJcbiAgLy8gU2xpZGVzIGdyaWRcclxuICBzcGFjZUJldHdlZW46IDAsXHJcbiAgc2xpZGVzUGVyVmlldzogMSxcclxuICBzbGlkZXNQZXJHcm91cDogMSxcclxuICBzbGlkZXNQZXJHcm91cFNraXA6IDAsXHJcbiAgc2xpZGVzUGVyR3JvdXBBdXRvOiBmYWxzZSxcclxuICBjZW50ZXJlZFNsaWRlczogZmFsc2UsXHJcbiAgY2VudGVyZWRTbGlkZXNCb3VuZHM6IGZhbHNlLFxyXG4gIHNsaWRlc09mZnNldEJlZm9yZTogMCxcclxuICAvLyBpbiBweFxyXG4gIHNsaWRlc09mZnNldEFmdGVyOiAwLFxyXG4gIC8vIGluIHB4XHJcbiAgbm9ybWFsaXplU2xpZGVJbmRleDogdHJ1ZSxcclxuICBjZW50ZXJJbnN1ZmZpY2llbnRTbGlkZXM6IGZhbHNlLFxyXG4gIC8vIERpc2FibGUgc3dpcGVyIGFuZCBoaWRlIG5hdmlnYXRpb24gd2hlbiBjb250YWluZXIgbm90IG92ZXJmbG93XHJcbiAgd2F0Y2hPdmVyZmxvdzogdHJ1ZSxcclxuICAvLyBSb3VuZCBsZW5ndGhcclxuICByb3VuZExlbmd0aHM6IGZhbHNlLFxyXG4gIC8vIFRvdWNoZXNcclxuICB0b3VjaFJhdGlvOiAxLFxyXG4gIHRvdWNoQW5nbGU6IDQ1LFxyXG4gIHNpbXVsYXRlVG91Y2g6IHRydWUsXHJcbiAgc2hvcnRTd2lwZXM6IHRydWUsXHJcbiAgbG9uZ1N3aXBlczogdHJ1ZSxcclxuICBsb25nU3dpcGVzUmF0aW86IDAuNSxcclxuICBsb25nU3dpcGVzTXM6IDMwMCxcclxuICBmb2xsb3dGaW5nZXI6IHRydWUsXHJcbiAgYWxsb3dUb3VjaE1vdmU6IHRydWUsXHJcbiAgdGhyZXNob2xkOiA1LFxyXG4gIHRvdWNoTW92ZVN0b3BQcm9wYWdhdGlvbjogZmFsc2UsXHJcbiAgdG91Y2hTdGFydFByZXZlbnREZWZhdWx0OiB0cnVlLFxyXG4gIHRvdWNoU3RhcnRGb3JjZVByZXZlbnREZWZhdWx0OiBmYWxzZSxcclxuICB0b3VjaFJlbGVhc2VPbkVkZ2VzOiBmYWxzZSxcclxuICAvLyBVbmlxdWUgTmF2aWdhdGlvbiBFbGVtZW50c1xyXG4gIHVuaXF1ZU
92665hdkVsZW1lbnRzOiB0cnVlLFxyXG4gIC8vIFJlc2lzdGFuY2VcclxuICByZXNpc3RhbmNlOiB0cnVlLFxyXG4gIHJlc2lzdGFuY2VSYXRpbzogMC44NSxcclxuICAvLyBQcm9ncmVzc1xyXG4gIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IGZhbHNlLFxyXG4gIC8vIEN1cnNvclxyXG4gIGdyYWJDdXJzb3I6IGZhbHNlLFxyXG4gIC8vIENsaWNrc1xyXG4gIHByZXZlbnRDbGlja3M6IHRydWUsXHJcbiAgcHJldmVudENsaWNrc1Byb3BhZ2F0aW9uOiB0cnVlLFxyXG4gIHNsaWRlVG9DbGlja2VkU2xpZGU6IGZhbHNlLFxyXG4gIC8vIGxvb3BcclxuICBsb29wOiBmYWxzZSxcclxuICBsb29wZWRTbGlkZXM6IG51bGwsXHJcbiAgbG9vcFByZXZlbnRzU2xpZGluZzogdHJ1ZSxcclxuICAvLyByZXdpbmRcclxuICByZXdpbmQ6IGZhbHNlLFxyXG4gIC8vIFN3aXBpbmcvbm8gc3dpcGluZ1xyXG4gIGFsbG93U2xpZGVQcmV2OiB0cnVlLFxyXG4gIGFsbG93U2xpZGVOZXh0OiB0cnVlLFxyXG4gIHN3aXBlSGFuZGxlcjogbnVsbCxcclxuICAvLyAnLnN3aXBlLWhhbmRsZXInLFxyXG4gIG5vU3dpcGluZzogdHJ1ZSxcclxuICBub1N3aXBpbmdDbGFzczogJ3N3aXBlci1uby1zd2lwaW5nJyxcclxuICBub1N3aXBpbmdTZWxlY3RvcjogbnVsbCxcclxuICAvLyBQYXNzaXZlIExpc3RlbmVyc1xyXG4gIHBhc3NpdmVMaXN0ZW5lcnM6IHRydWUsXHJcbiAgbWF4QmFja2ZhY2VIaWRkZW5TbGlkZXM6IDEwLFxyXG4gIC8vIE5TXHJcbiAgY29udGFpbmVyTW9kaWZpZXJDbGFzczogJ3N3aXBlci0nLFxyXG4gIC8vIE5FV1xyXG4gIHNsaWRlQ2xhc3M6ICdzd2lwZXItc2xpZGUnLFxyXG4gIHNsaWRlQWN0aXZlQ2xhc3M6ICdzd2lwZXItc2xpZGUtYWN0aXZlJyxcclxuICBzbGlkZVZpc2libGVDbGFzczogJ3N3aXBlci1zbGlkZS12aXNpYmxlJyxcclxuICBzbGlkZU5leHRDbGFzczogJ3N3aXBlci1zbGlkZS1uZXh0JyxcclxuICBzbGlkZVByZXZDbGFzczogJ3N3aXBlci1zbGlkZS1wcmV2JyxcclxuICB3cmFwcGVyQ2xhc3M6ICdzd2lwZXItd3JhcHBlcicsXHJcbiAgbGF6eVByZWxvYWRlckNsYXNzOiAnc3dpcGVyLWxhenktcHJlbG9hZGVyJyxcclxuICBsYXp5UHJlbG9hZFByZXZOZXh0OiAwLFxyXG4gIC8vIENhbGxiYWNrc1xyXG4gIHJ1bkNhbGxiYWNrc09uSW5pdDogdHJ1ZSxcclxuICAvLyBJbnRlcm5hbHNcclxuICBfZW1pdENsYXNzZXM6IGZhbHNlLFxyXG59O1xyXG5cclxuZnVuY3Rpb24gbW9kdWxlRXh0ZW5kUGFyYW1zKHBhcmFtcywgYWxsTW9kdWxlc1BhcmFtcykge1xyXG4gIHJldHVybiBmdW5jdGlvbiBleHRlbmRQYXJhbXMob2JqKSB7XHJcbiAgICBpZiAob2JqID09PSB2b2lkIDApIHtcclxuICAgICAgb2JqID0ge307XHJcbiAgICB9XHJcbiAgICBjb25zdCBtb2R1bGVQYXJhbU5hbWUgPSBPYmplY3Qua2V5cyhvYmopWzBdO1xyXG4gICAgY29uc3QgbW9kdWxlUGFyYW1zID0gb2JqW21vZHVsZVBhcmFtTmFtZV07XHJcbiAgICBpZiAodHlwZW9mIG1vZHVsZVBhcmFtcyAhPT0gJ29iamVjdCcgfHwgbW9kdWxlUGFyYW1zID09PSBudWxsKSB7XHJcbiAgICAgIGV4dGVuZChhbGxNb2R1bGVzUGFyYW1zLCBvYmopO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoWyduYXZpZ2F0aW9uJywgJ3BhZ2luYXRpb24nLCAnc2Nyb2xsYmFyJ10uaW5kZXhPZihtb2R1bGVQYXJhbU5hbWUpID49IDAgJiYgcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0gPT09IHRydWUpIHtcclxuICAgICAgcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0gPSB7XHJcbiAgICAgICAgYXV0bzogdHJ1ZSxcclxuICAgICAgfTtcclxuICAgIH1cclxuICAgIGlmICghKG1vZHVsZVBhcmFtTmFtZSBpbiBwYXJhbXMgJiYgJ2VuYWJsZWQnIGluIG1vZHVsZVBhcmFtcykpIHtcclxuICAgICAgZXh0ZW5kKGFsbE1vZHVsZXNQYXJhbXMsIG9iaik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9PT0gdHJ1ZSkge1xyXG4gICAgICBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9IHtcclxuICAgICAgICBlbmFibGVkOiB0cnVlLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9PT0gJ29iamVjdCcgJiYgISgnZW5hYmxlZCcgaW4gcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0pKSB7XHJcbiAgICAgIHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdLmVuYWJsZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgaWYgKCFwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSlcclxuICAgICAgcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0gPSB7XHJcbiAgICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICAgIH07XHJcbiAgICBleHRlbmQoYWxsTW9kdWxlc1BhcmFtcywgb2JqKTtcclxuICB9O1xyXG59XHJcblxyXG4vKiBlc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246IFwib2ZmXCIgKi9cclxuY29uc3QgcHJvdG90eXBlcyA9IHtcclxuICBldmVudHNFbWl0dGVyLFxyXG4gIHVwZGF0ZSxcclxuICB0cmFuc2xhdGUsXHJcbiAgdHJhbnNpdGlvbixcclxuICBzbGlkZSxcclxuICBsb29wLFxyXG4gIGdyYWJDdXJzb3IsXHJcbiAgZXZlbnRzOiBldmVudHMkMSxcclxuICBicmVha3BvaW50cyxcclxuICBjaGVja092ZXJmbG93OiBjaGVja092ZXJmbG93JDEsXHJcbiAgY2xhc3NlcyxcclxufTtcclxuY29uc3QgZXh0ZW5kZWREZWZhdWx0cyA9IHt9O1xyXG5jbGFzcyBTd2lwZXIge1xyXG4gIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgbGV0IGVsO1xyXG4gICAgbGV0IHBhcmFtcztcclxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xyXG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xyXG4gICAgfVxyXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGFyZ3NbMF0uY29uc3RydWN0b3IgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3NbMF0pLnNsaWNlKDgsIC0xKSA9PT0gJ09iamVjdCcpIHtcclxuICAgICAgcGFyYW1zID0gYXJnc1swXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIFtlbCwgcGFyYW1zXSA9IGFyZ3M7XHJcbiAgICB9XHJcbiAgICBpZiAoIXBhcmFtcykgcGFyYW1zID0ge307XHJcbiAgICBwYXJhbXMgPSBleHRlbmQoe30sIHBhcmFtcyk7XHJcbiAgICBpZiAoZWwgJiYgIXBhcmFtcy5lbCkgcGFyYW1zLmVsID0gZWw7XHJcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XHJcbiAgICBpZiAocGFyYW1zLmVsICYmIHR5cGVvZiBwYXJhbXMuZWwgPT09ICdzdHJpbmcnICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwocGFyYW1zLmVsKS5sZW5ndGggPiAxKSB7XHJcbiAgICAgIGNvbnN0IHN3aXBlcnMgPSBbXTtcclxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChwYXJhbXMuZWwpLmZvckVhY2goKGNvbnRhaW5lckVsKSA9PiB7XHJcbiAgICAgICAgY29uc3QgbmV3UGFyYW1zID0gZXh0ZW5kKHt9LCBwYXJhbXMsIHtcclxuICAgICAgICAgIGVsOiBjb250YWluZXJFbCxcclxuICAgICAgICB9KTtcclxuICAgICAgICBzd2lwZXJzLnB1c2gobmV3IFN3aXBlcihuZXdQYXJhbXMpKTtcclxuICAgICAgfSk7XHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdHJ1Y3Rvci1yZXR1cm5cclxuICAgICAgcmV0dXJuIHN3aXBlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU3dpcGVyIEluc3RhbmNlXHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgc3dpcGVyLl9fc3dpcGVyX18gPSB0cnVlO1xyXG4gICAgc3dpcGVyLnN1cHBvcnQgPSBnZXRTdXBwb3J0KCk7XHJcbiAgICBzd2lwZXIuZGV2aWNlID0gZ2V0RGV2aWNlKHtcclxuICAgICAgdXNlckFnZW50OiBwYXJhbXMudXNlckFnZW50LFxyXG4gICAgfSk7XHJcbiAgICBzd2lwZXIuYnJvd3NlciA9IGdldEJyb3dzZXIoKTtcclxuICAgIHN3aXBlci5ldmVudHNMaXN0ZW5lcnMgPSB7fTtcclxuICAgIHN3aXBlci5ldmVudHNBbnlMaXN0ZW5lcnMgPSBbXTtcclxuICAgIHN3aXBlci5tb2R1bGVzID0gWy4uLnN3aXBlci5fX21vZHVsZXNfX107XHJcbiAgICBpZiAocGFyYW1zLm1vZHVsZXMgJiYgQXJyYXkuaXNBcnJheShwYXJhbXMubW9kdWxlcykpIHtcclxuICAgICAgc3dpcGVyLm1vZHVsZXMucHVzaCguLi5wYXJhbXMubW9kdWxlcyk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBhbGxNb2R1bGVzUGFyYW1zID0ge307XHJcbiAgICBzd2lwZXIubW9kdWxlcy5mb3JFYWNoKChtb2QpID0+IHtcclxuICAgICAgbW9kKHtcclxuICAgICAgICBwYXJhbXMsXHJcbiAgICAgICAgc3dpcGVyLFxyXG4gICAgICAgIGV4dGVuZFBhcmFtczogbW9k
9266dWxlRXh0ZW5kUGFyYW1zKHBhcmFtcywgYWxsTW9kdWxlc1BhcmFtcyksXHJcbiAgICAgICAgb246IHN3aXBlci5vbi5iaW5kKHN3aXBlciksXHJcbiAgICAgICAgb25jZTogc3dpcGVyLm9uY2UuYmluZChzd2lwZXIpLFxyXG4gICAgICAgIG9mZjogc3dpcGVyLm9mZi5iaW5kKHN3aXBlciksXHJcbiAgICAgICAgZW1pdDogc3dpcGVyLmVtaXQuYmluZChzd2lwZXIpLFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEV4dGVuZCBkZWZhdWx0cyB3aXRoIG1vZHVsZXMgcGFyYW1zXHJcbiAgICBjb25zdCBzd2lwZXJQYXJhbXMgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBhbGxNb2R1bGVzUGFyYW1zKTtcclxuXHJcbiAgICAvLyBFeHRlbmQgZGVmYXVsdHMgd2l0aCBwYXNzZWQgcGFyYW1zXHJcbiAgICBzd2lwZXIucGFyYW1zID0gZXh0ZW5kKHt9LCBzd2lwZXJQYXJhbXMsIGV4dGVuZGVkRGVmYXVsdHMsIHBhcmFtcyk7XHJcbiAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMgPSBleHRlbmQoe30sIHN3aXBlci5wYXJhbXMpO1xyXG4gICAgc3dpcGVyLnBhc3NlZFBhcmFtcyA9IGV4dGVuZCh7fSwgcGFyYW1zKTtcclxuXHJcbiAgICAvLyBhZGQgZXZlbnQgbGlzdGVuZXJzXHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcyAmJiBzd2lwZXIucGFyYW1zLm9uKSB7XHJcbiAgICAgIE9iamVjdC5rZXlzKHN3aXBlci5wYXJhbXMub24pLmZvckVhY2goKGV2ZW50TmFtZSkgPT4ge1xyXG4gICAgICAgIHN3aXBlci5vbihldmVudE5hbWUsIHN3aXBlci5wYXJhbXMub25bZXZlbnROYW1lXSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMgJiYgc3dpcGVyLnBhcmFtcy5vbkFueSkge1xyXG4gICAgICBzd2lwZXIub25Bbnkoc3dpcGVyLnBhcmFtcy5vbkFueSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRXh0ZW5kIFN3aXBlclxyXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIsIHtcclxuICAgICAgZW5hYmxlZDogc3dpcGVyLnBhcmFtcy5lbmFibGVkLFxyXG4gICAgICBlbCxcclxuICAgICAgLy8gQ2xhc3Nlc1xyXG4gICAgICBjbGFzc05hbWVzOiBbXSxcclxuICAgICAgLy8gU2xpZGVzXHJcbiAgICAgIHNsaWRlczogW10sXHJcbiAgICAgIHNsaWRlc0dyaWQ6IFtdLFxyXG4gICAgICBzbmFwR3JpZDogW10sXHJcbiAgICAgIHNsaWRlc1NpemVzR3JpZDogW10sXHJcbiAgICAgIC8vIGlzRGlyZWN0aW9uXHJcbiAgICAgIGlzSG9yaXpvbnRhbCgpIHtcclxuICAgICAgICByZXR1cm4gc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJztcclxuICAgICAgfSxcclxuICAgICAgaXNWZXJ0aWNhbCgpIHtcclxuICAgICAgICByZXR1cm4gc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCc7XHJcbiAgICAgIH0sXHJcbiAgICAgIC8vIEluZGV4ZXNcclxuICAgICAgYWN0aXZlSW5kZXg6IDAsXHJcbiAgICAgIHJlYWxJbmRleDogMCxcclxuICAgICAgLy9cclxuICAgICAgaXNCZWdpbm5pbmc6IHRydWUsXHJcbiAgICAgIGlzRW5kOiBmYWxzZSxcclxuICAgICAgLy8gUHJvcHNcclxuICAgICAgdHJhbnNsYXRlOiAwLFxyXG4gICAgICBwcmV2aW91c1RyYW5zbGF0ZTogMCxcclxuICAgICAgcHJvZ3Jlc3M6IDAsXHJcbiAgICAgIHZlbG9jaXR5OiAwLFxyXG4gICAgICBhbmltYXRpbmc6IGZhbHNlLFxyXG4gICAgICBjc3NPdmVyZmxvd0FkanVzdG1lbnQoKSB7XHJcbiAgICAgICAgLy8gUmV0dXJucyAwIHVubGVzcyBgdHJhbnNsYXRlYCBpcyA+IDIqKjIzXHJcbiAgICAgICAgLy8gU2hvdWxkIGJlIHN1YnRyYWN0ZWQgZnJvbSBjc3MgdmFsdWVzIHRvIHByZXZlbnQgb3ZlcmZsb3dcclxuICAgICAgICByZXR1cm4gTWF0aC50cnVuYyh0aGlzLnRyYW5zbGF0ZSAvIDIgKiogMjMpICogMiAqKiAyMztcclxuICAgICAgfSxcclxuICAgICAgLy8gTG9ja3NcclxuICAgICAgYWxsb3dTbGlkZU5leHQ6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZU5leHQsXHJcbiAgICAgIGFsbG93U2xpZGVQcmV2OiBzd2lwZXIucGFyYW1zLmFsbG93U2xpZGVQcmV2LFxyXG4gICAgICAvLyBUb3VjaCBFdmVudHNcclxuICAgICAgdG91Y2hFdmVudHNEYXRhOiB7XHJcbiAgICAgICAgaXNUb3VjaGVkOiB1bmRlZmluZWQsXHJcbiAgICAgICAgaXNNb3ZlZDogdW5kZWZpbmVkLFxyXG4gICAgICAgIGFsbG93VG91Y2hDYWxsYmFja3M6IHVuZGVmaW5lZCxcclxuICAgICAgICB0b3VjaFN0YXJ0VGltZTogdW5kZWZpbmVkLFxyXG4gICAgICAgIGlzU2Nyb2xsaW5nOiB1bmRlZmluZWQsXHJcbiAgICAgICAgY3VycmVudFRyYW5zbGF0ZTogdW5kZWZpbmVkLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNsYXRlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgYWxsb3dUaHJlc2hvbGRNb3ZlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgLy8gRm9ybSBlbGVtZW50cyB0byBtYXRjaFxyXG4gICAgICAgIGZvY3VzYWJsZUVsZW1lbnRzOiBzd2lwZXIucGFyYW1zLmZvY3VzYWJsZUVsZW1lbnRzLFxyXG4gICAgICAgIC8vIExhc3QgY2xpY2sgdGltZVxyXG4gICAgICAgIGxhc3RDbGlja1RpbWU6IDAsXHJcbiAgICAgICAgY2xpY2tUaW1lb3V0OiB1bmRlZmluZWQsXHJcbiAgICAgICAgLy8gVmVsb2NpdGllc1xyXG4gICAgICAgIHZlbG9jaXRpZXM6IFtdLFxyXG4gICAgICAgIGFsbG93TW9tZW50dW1Cb3VuY2U6IHVuZGVmaW5lZCxcclxuICAgICAgICBzdGFydE1vdmluZzogdW5kZWZpbmVkLFxyXG4gICAgICAgIGV2Q2FjaGU6IFtdLFxyXG4gICAgICB9LFxyXG4gICAgICAvLyBDbGlja3NcclxuICAgICAgYWxsb3dDbGljazogdHJ1ZSxcclxuICAgICAgLy8gVG91Y2hlc1xyXG4gICAgICBhbGxvd1RvdWNoTW92ZTogc3dpcGVyLnBhcmFtcy5hbGxvd1RvdWNoTW92ZSxcclxuICAgICAgdG91Y2hlczoge1xyXG4gICAgICAgIHN0YXJ0WDogMCxcclxuICAgICAgICBzdGFydFk6IDAsXHJcbiAgICAgICAgY3VycmVudFg6IDAsXHJcbiAgICAgICAgY3VycmVudFk6IDAsXHJcbiAgICAgICAgZGlmZjogMCxcclxuICAgICAgfSxcclxuICAgICAgLy8gSW1hZ2VzXHJcbiAgICAgIGltYWdlc1RvTG9hZDogW10sXHJcbiAgICAgIGltYWdlc0xvYWRlZDogMCxcclxuICAgIH0pO1xyXG4gICAgc3dpcGVyLmVtaXQoJ19zd2lwZXInKTtcclxuXHJcbiAgICAvLyBJbml0XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5pbml0KSB7XHJcbiAgICAgIHN3aXBlci5pbml0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmV0dXJuIGFwcCBpbnN0YW5jZVxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0cnVjdG9yLXJldHVyblxyXG4gICAgcmV0dXJuIHN3aXBlcjtcclxuICB9XHJcbiAgZ2V0U2xpZGVJbmRleChzbGlkZUVsKSB7XHJcbiAgICBjb25zdCB7IHNsaWRlc0VsLCBwYXJhbXMgfSA9IHRoaXM7XHJcbiAgICBjb25zdCBzbGlkZXMgPSBlbGVtZW50Q2hpbGRyZW4oc2xpZGVzRWwsIGAuJHtwYXJhbXMuc2xpZGVDbGFzc30sIHN3aXBlci1zbGlkZWApO1xyXG4gICAgY29uc3QgZmlyc3RTbGlkZUluZGV4ID0gZWxlbWVudEluZGV4KHNsaWRlc1swXSk7XHJcbiAgICByZXR1cm4gZWxlbWVudEluZGV4KHNsaWRlRWwpIC0gZmlyc3RTbGlkZUluZGV4O1xyXG4gIH1cclxuICBnZXRTbGlkZUluZGV4QnlEYXRhKGluZGV4KSB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRTbGlkZUluZGV4KFxyXG4gICAgICB0aGlzLnNsaWRlcy5maWx0ZXIoKHNsaWRlRWwpID0+IHNsaWRlRWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpICogMSA9PT0gaW5kZXgpWzBdXHJcbiAgICApO
92661xyXG4gIH1cclxuICByZWNhbGNTbGlkZXMoKSB7XHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgY29uc3QgeyBzbGlkZXNFbCwgcGFyYW1zIH0gPSBzd2lwZXI7XHJcbiAgICBzd2lwZXIuc2xpZGVzID0gZWxlbWVudENoaWxkcmVuKHNsaWRlc0VsLCBgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9LCBzd2lwZXItc2xpZGVgKTtcclxuICB9XHJcbiAgZW5hYmxlKCkge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIGlmIChzd2lwZXIuZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgc3dpcGVyLmVuYWJsZWQgPSB0cnVlO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuZ3JhYkN1cnNvcikge1xyXG4gICAgICBzd2lwZXIuc2V0R3JhYkN1cnNvcigpO1xyXG4gICAgfVxyXG4gICAgc3dpcGVyLmVtaXQoJ2VuYWJsZScpO1xyXG4gIH1cclxuICBkaXNhYmxlKCkge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcclxuICAgIHN3aXBlci5lbmFibGVkID0gZmFsc2U7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5ncmFiQ3Vyc29yKSB7XHJcbiAgICAgIHN3aXBlci51bnNldEdyYWJDdXJzb3IoKTtcclxuICAgIH1cclxuICAgIHN3aXBlci5lbWl0KCdkaXNhYmxlJyk7XHJcbiAgfVxyXG4gIHNldFByb2dyZXNzKHByb2dyZXNzLCBzcGVlZCkge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIHByb2dyZXNzID0gTWF0aC5taW4oTWF0aC5tYXgocHJvZ3Jlc3MsIDApLCAxKTtcclxuICAgIGNvbnN0IG1pbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKTtcclxuICAgIGNvbnN0IG1heCA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcclxuICAgIGNvbnN0IGN1cnJlbnQgPSAobWF4IC0gbWluKSAqIHByb2dyZXNzICsgbWluO1xyXG4gICAgc3dpcGVyLnRyYW5zbGF0ZVRvKGN1cnJlbnQsIHR5cGVvZiBzcGVlZCA9PT0gJ3VuZGVmaW5lZCcgPyAwIDogc3BlZWQpO1xyXG4gICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xyXG4gIH1cclxuICBlbWl0Q29udGFpbmVyQ2xhc3NlcygpIHtcclxuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuX2VtaXRDbGFzc2VzIHx8ICFzd2lwZXIuZWwpIHJldHVybjtcclxuICAgIGNvbnN0IGNscyA9IHN3aXBlci5lbC5jbGFzc05hbWUuc3BsaXQoJyAnKS5maWx0ZXIoKGNsYXNzTmFtZSkgPT4ge1xyXG4gICAgICByZXR1cm4gY2xhc3NOYW1lLmluZGV4T2YoJ3N3aXBlcicpID09PSAwIHx8IGNsYXNzTmFtZS5pbmRleE9mKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcykgPT09IDA7XHJcbiAgICB9KTtcclxuICAgIHN3aXBlci5lbWl0KCdfY29udGFpbmVyQ2xhc3NlcycsIGNscy5qb2luKCcgJykpO1xyXG4gIH1cclxuICBnZXRTbGlkZUNsYXNzZXMoc2xpZGVFbCkge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIGlmIChzd2lwZXIuZGVzdHJveWVkKSByZXR1cm4gJyc7XHJcbiAgICByZXR1cm4gc2xpZGVFbC5jbGFzc05hbWVcclxuICAgICAgLnNwbGl0KCcgJylcclxuICAgICAgLmZpbHRlcigoY2xhc3NOYW1lKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIGNsYXNzTmFtZS5pbmRleE9mKCdzd2lwZXItc2xpZGUnKSA9PT0gMCB8fCBjbGFzc05hbWUuaW5kZXhPZihzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3MpID09PSAwO1xyXG4gICAgICB9KVxyXG4gICAgICAuam9pbignICcpO1xyXG4gIH1cclxuICBlbWl0U2xpZGVzQ2xhc3NlcygpIHtcclxuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuX2VtaXRDbGFzc2VzIHx8ICFzd2lwZXIuZWwpIHJldHVybjtcclxuICAgIGNvbnN0IHVwZGF0ZXMgPSBbXTtcclxuICAgIHN3aXBlci5zbGlkZXMuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgICBjb25zdCBjbGFzc05hbWVzID0gc3dpcGVyLmdldFNsaWRlQ2xhc3NlcyhzbGlkZUVsKTtcclxuICAgICAgdXBkYXRlcy5wdXNoKHtcclxuICAgICAgICBzbGlkZUVsLFxyXG4gICAgICAgIGNsYXNzTmFtZXMsXHJcbiAgICAgIH0pO1xyXG4gICAgICBzd2lwZXIuZW1pdCgnX3NsaWRlQ2xhc3MnLCBzbGlkZUVsLCBjbGFzc05hbWVzKTtcclxuICAgIH0pO1xyXG4gICAgc3dpcGVyLmVtaXQoJ19zbGlkZUNsYXNzZXMnLCB1cGRhdGVzKTtcclxuICB9XHJcbiAgc2xpZGVzUGVyVmlld0R5bmFtaWModmlldywgZXhhY3QpIHtcclxuICAgIGlmICh2aWV3ID09PSB2b2lkIDApIHtcclxuICAgICAgdmlldyA9ICdjdXJyZW50JztcclxuICAgIH1cclxuICAgIGlmIChleGFjdCA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICAgIGV4YWN0ID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgY29uc3QgeyBwYXJhbXMsIHNsaWRlcywgc2xpZGVzR3JpZCwgc2xpZGVzU2l6ZXNHcmlkLCBzaXplOiBzd2lwZXJTaXplLCBhY3RpdmVJbmRleCB9ID0gc3dpcGVyO1xyXG4gICAgbGV0IHNwdiA9IDE7XHJcbiAgICBpZiAocGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XHJcbiAgICAgIGxldCBzbGlkZVNpemUgPSBzbGlkZXNbYWN0aXZlSW5kZXhdID8gc2xpZGVzW2FjdGl2ZUluZGV4XS5zd2lwZXJTbGlkZVNpemUgOiAwO1xyXG4gICAgICBsZXQgYnJlYWtMb29wO1xyXG4gICAgICBmb3IgKGxldCBpID0gYWN0aXZlSW5kZXggKyAxOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgICAgaWYgKHNsaWRlc1tpXSAmJiAhYnJlYWtMb29wKSB7XHJcbiAgICAgICAgICBzbGlkZVNpemUgKz0gc2xpZGVzW2ldLnN3aXBlclNsaWRlU2l6ZTtcclxuICAgICAgICAgIHNwdiArPSAxO1xyXG4gICAgICAgICAgaWYgKHNsaWRlU2l6ZSA+IHN3aXBlclNpemUpIGJyZWFrTG9vcCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGZvciAobGV0IGkgPSBhY3RpdmVJbmRleCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XHJcbiAgICAgICAgaWYgKHNsaWRlc1tpXSAmJiAhYnJlYWtMb29wKSB7XHJcbiAgICAgICAgICBzbGlkZVNpemUgKz0gc2xpZGVzW2ldLnN3aXBlclNsaWRlU2l6ZTtcclxuICAgICAgICAgIHNwdiArPSAxO1xyXG4gICAgICAgICAgaWYgKHNsaWRlU2l6ZSA+IHN3aXBlclNpemUpIGJyZWFrTG9vcCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgICAgaWYgKHZpZXcgPT09ICdjdXJyZW50Jykge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSBhY3RpdmVJbmRleCArIDE7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgICAgIGNvbnN0IHNsaWRlSW5WaWV3ID0gZXhhY3RcclxuICAgICAgICAgICAgPyBzbGlkZXNHcmlkW2ldICsgc2xpZGVzU2l6ZXNHcmlkW2ldIC0gc2xpZGVzR3JpZFthY3RpdmVJbmRleF0gPCBzd2lwZXJTaXplXHJcbiAgICAgICAgICAgIDogc2xpZGVzR3JpZFtpXSAtIHNsaWRlc0dyaWRbYWN0aXZlSW5kZXhdIDwgc3dpcGVyU2l6ZTtcclxuICAgICAgICAgIGlmIChzbGlkZUluVmlldykge1xyXG4gICAgICAgICAgICBzcHYgKz0gMTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gcHJldmlvdXNcclxuICAgICAgICBmb3IgKGxldCBpID0gYWN0aXZlSW5kZXggLSAxOyBpID49IDA7IGkgLT0gMSkge1xyXG4gICAgICAgICAgY29uc3Qgc2xpZGVJblZpZXcgPSBzbGlkZXNHcmlkW2FjdGl2ZUluZGV4XSAtIHNsaWRlc0dyaWRbaV0gPCBzd2lwZXJTaXplO1xyXG4gICAgICAgICAgaWYgKHNsaWRlSW5WaWV3KSB7XHJcbiAgICAgICAgICAgIHNwdiArPSAxO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHNwdjtcclxuICB9XHJcbiAgdXBkYXRlKCkge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgIGNvbnN0IHsgc25hcEdyaWQsIHBhcmFtcyB9ID0gc3dpcGVyO1xyXG4gICAgLy8gQnJlYWtwb2ludHNcclxuICAgIGlmIChwYXJhbXMuYnJlYWtwb2ludHMpIHtcclxuICAgICAgc3dpcGVyLnNldEJyZWFrcG9pbnQoKTtcclxuICAgIH1cclxuICAgIFsuLi5zd2lwZXIuZWwucXVlcnlTZWxlY3RvckFsbCgnW2xvYWRpbmc9XCJsYXp5XCJdJyldLmZvckVhY2goKGltYWdlRWwpID0+IHtcclxuICAgICAgaWYgKGltYWdlRWwuY29tcGxldGUpIHtcclxuICAgICAgICBwcm9jZXNzTGF6eVByZWxvYWRlcihzd2lwZXIsIGltYWdlRWwpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHN3aXBlci51cGRhdGVTaXplKCk7XHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XHJcbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcclxuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XHJcbiAgICBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoKSB7XHJcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZVZhbHVlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgKiAtMSA6IHN3aXBlci50cmFuc2xhdGU7XHJcbiAgICAgIGNvbnN0IG5ld1RyYW5zbGF0ZSA9IE1hdGgubWluKE1hdGgubWF4KHRyYW5zbGF0ZVZhbHVlLCBzd2lwZXIubWF4VHJhbnNsYXRlKCkpLCBzd2lwZXIubWluVHJhbnNsYXRlKCkpO1xyXG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1RyYW5zbGF0ZSk7XHJcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xyXG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xyXG4gICAgfVxyXG4gICAgbGV0IHRyYW5zbGF0ZWQ7XHJcbiAgICBpZiAocGFyYW1zLmZyZWVNb2RlICYmIHBhcmFtcy5mcmVlTW9kZS5lbmFibGVkICYmICFwYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICBzZXRUcmFuc2xhdGUoKTtcclxuICAgICAgaWYgKHBhcmFtcy5hdXRvSGVpZ2h0KSB7XHJcbiAgICAgICAgc3dpcGVyLnVwZGF0ZUF1dG9IZWlnaHQoKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nIHx8IHBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkgJiYgc3dpcGVyLmlzRW5kICYmICFwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcclxuICAgICAgICBjb25zdCBzbGlkZXMgPSBzd2lwZXIudmlydHVhbCAmJiBwYXJhbXMudmlydHVhbC5lbmFibGVkID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzIDogc3dpcGVyLnNsaWRlcztcclxuICAgICAgICB0cmFuc2xhdGVkID0gc3dpcGVyLnNsaWRlVG8oc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0cmFuc2xhdGVkID0gc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4LCAwLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCF0cmFuc2xhdGVkKSB7XHJcbiAgICAgICAgc2V0VHJhbnNsYXRlKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChwYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzbmFwR3JpZCAhPT0gc3dpcGVyLnNuYXBHcmlkKSB7XHJcbiAgICAgIHN3aXBlci5jaGVja092ZXJmbG93KCk7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuZW1pdCgndXBkYXRlJyk7XHJcbiAgfVxyXG4gIGNoYW5nZURpcmVjdGlvbihuZXdEaXJlY3Rpb24sIG5lZWRVcGRhdGUpIHtcclxuICAgIGlmIChuZWVkVXBkYXRlID09PSB2b2lkIDApIHtcclxuICAgICAgbmVlZFVwZGF0ZSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgY29uc3QgY3VycmVudERpcmVjdGlvbiA9IHN3aXBlci5wYXJhbXMuZGlyZWN0aW9uO1xyXG4gICAgaWYgKCFuZXdEaXJlY3Rpb24pIHtcclxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICAgIG5ld0RpcmVjdGlvbiA9IGN1cnJlbnREaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJyA/ICd2ZXJ0aWNhbCcgOiAnaG9yaXpvbn
9266RhbCc7XHJcbiAgICB9XHJcbiAgICBpZiAobmV3RGlyZWN0aW9uID09PSBjdXJyZW50RGlyZWN0aW9uIHx8IChuZXdEaXJlY3Rpb24gIT09ICdob3Jpem9udGFsJyAmJiBuZXdEaXJlY3Rpb24gIT09ICd2ZXJ0aWNhbCcpKSB7XHJcbiAgICAgIHJldHVybiBzd2lwZXI7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LnJlbW92ZShgJHtzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9JHtjdXJyZW50RGlyZWN0aW9ufWApO1xyXG4gICAgc3dpcGVyLmVsLmNsYXNzTGlzdC5hZGQoYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfSR7bmV3RGlyZWN0aW9ufWApO1xyXG4gICAgc3dpcGVyLmVtaXRDb250YWluZXJDbGFzc2VzKCk7XHJcbiAgICBzd2lwZXIucGFyYW1zLmRpcmVjdGlvbiA9IG5ld0RpcmVjdGlvbjtcclxuICAgIHN3aXBlci5zbGlkZXMuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgICBpZiAobmV3RGlyZWN0aW9uID09PSAndmVydGljYWwnKSB7XHJcbiAgICAgICAgc2xpZGVFbC5zdHlsZS53aWR0aCA9ICcnO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNsaWRlRWwuc3R5bGUuaGVpZ2h0ID0gJyc7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgc3dpcGVyLmVtaXQoJ2NoYW5nZURpcmVjdGlvbicpO1xyXG4gICAgaWYgKG5lZWRVcGRhdGUpIHN3aXBlci51cGRhdGUoKTtcclxuICAgIHJldHVybiBzd2lwZXI7XHJcbiAgfVxyXG4gIGNoYW5nZUxhbmd1YWdlRGlyZWN0aW9uKGRpcmVjdGlvbikge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICAgIGlmICgoc3dpcGVyLnJ0bCAmJiBkaXJlY3Rpb24gPT09ICdydGwnKSB8fCAoIXN3aXBlci5ydGwgJiYgZGlyZWN0aW9uID09PSAnbHRyJykpIHJldHVybjtcclxuICAgIHN3aXBlci5ydGwgPSBkaXJlY3Rpb24gPT09ICdydGwnO1xyXG4gICAgc3dpcGVyLnJ0bFRyYW5zbGF0ZSA9IHN3aXBlci5wYXJhbXMuZGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcgJiYgc3dpcGVyLnJ0bDtcclxuICAgIGlmIChzd2lwZXIucnRsKSB7XHJcbiAgICAgIHN3aXBlci5lbC5jbGFzc0xpc3QuYWRkKGAke3N3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc31ydGxgKTtcclxuICAgICAgc3dpcGVyLmVsLmRpciA9ICdydGwnO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLmVsLmNsYXNzTGlzdC5yZW1vdmUoYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfXJ0bGApO1xyXG4gICAgICBzd2lwZXIuZWwuZGlyID0gJ2x0cic7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIudXBkYXRlKCk7XHJcbiAgfVxyXG4gIG1vdW50KGVsZW1lbnQpIHtcclxuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgICBpZiAoc3dpcGVyLm1vdW50ZWQpIHJldHVybiB0cnVlO1xyXG5cclxuICAgIC8vIEZpbmQgZWxcclxuICAgIGxldCBlbCA9IGVsZW1lbnQgfHwgc3dpcGVyLnBhcmFtcy5lbDtcclxuICAgIGlmICh0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbCk7XHJcbiAgICB9XHJcbiAgICBpZiAoIWVsKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGVsLnN3aXBlciA9IHN3aXBlcjtcclxuICAgIGlmIChlbC5zaGFkb3dFbCkge1xyXG4gICAgICBzd2lwZXIuaXNFbGVtZW50ID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGNvbnN0IGdldFdyYXBwZXJTZWxlY3RvciA9ICgpID0+IHtcclxuICAgICAgcmV0dXJuIGAuJHsoc3dpcGVyLnBhcmFtcy53cmFwcGVyQ2xhc3MgfHwgJycpLnRyaW0oKS5zcGxpdCgnICcpLmpvaW4oJy4nKX1gO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IGdldFdyYXBwZXIgPSAoKSA9PiB7XHJcbiAgICAgIGlmIChlbCAmJiBlbC5zaGFkb3dSb290ICYmIGVsLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3Rvcikge1xyXG4gICAgICAgIGNvbnN0IHJlcyA9IGVsLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihnZXRXcmFwcGVyU2VsZWN0b3IoKSk7XHJcbiAgICAgICAgLy8gQ2hpbGRyZW4gbmVlZHMgdG8gcmV0dXJuIHNsb3QgaXRlbXNcclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBlbGVtZW50Q2hpbGRyZW4oZWwsIGdldFdyYXBwZXJTZWxlY3RvcigpKVswXTtcclxuICAgIH07XHJcbiAgICAvLyBGaW5kIFdyYXBwZXJcclxuICAgIGxldCB3cmFwcGVyRWwgPSBnZXRXcmFwcGVyKCk7XHJcbiAgICBpZiAoIXdyYXBwZXJFbCAmJiBzd2lwZXIucGFyYW1zLmNyZWF0ZUVsZW1lbnRzKSB7XHJcbiAgICAgIHdyYXBwZXJFbCA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIHN3aXBlci5wYXJhbXMud3JhcHBlckNsYXNzKTtcclxuICAgICAgZWwuYXBwZW5kKHdyYXBwZXJFbCk7XHJcbiAgICAgIGVsZW1lbnRDaGlsZHJlbihlbCwgYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31gKS5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgICAgd3JhcHBlckVsLmFwcGVuZChzbGlkZUVsKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xyXG4gICAgICBlbCxcclxuICAgICAgd3JhcHBlckVsLFxyXG4gICAgICBzbGlkZXNFbDogc3dpcGVyLmlzRWxlbWVudCA/IGVsIDogd3JhcHBlckVsLFxyXG4gICAgICBtb3VudGVkOiB0cnVlLFxyXG4gICAgICAvLyBSVExcclxuICAgICAgcnRsOiBlbC5kaXIudG9Mb3dlckNhc2UoKSA9PT0gJ3J0bCcgfHwgZWxlbWVudFN0eWxlKGVsLCAnZGlyZWN0aW9uJykgPT09ICdydGwnLFxyXG4gICAgICBydGxUcmFuc2xhdGU6XHJcbiAgICAgICAgc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJyAmJlxyXG4gICAgICAgIChlbC5kaXIudG9Mb3dlckNhc2UoKSA9PT0gJ3J0bCcgfHwgZWxlbWVudFN0eWxlKGVsLCAnZGlyZWN0aW9uJykgPT09ICdydGwnKSxcclxuICAgICAgd3JvbmdSVEw6IGVsZW1lbnRTdHlsZSh3cmFwcGVyRWwsICdkaXNwbGF5J
9266ykgPT09ICctd2Via2l0LWJveCcsXHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuICBpbml0KGVsKSB7XHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgaWYgKHN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuIHN3aXBlcjtcclxuICAgIGNvbnN0IG1vdW50ZWQgPSBzd2lwZXIubW91bnQoZWwpO1xyXG4gICAgaWYgKG1vdW50ZWQgPT09IGZhbHNlKSByZXR1cm4gc3dpcGVyO1xyXG4gICAgc3dpcGVyLmVtaXQoJ2JlZm9yZUluaXQnKTtcclxuXHJcbiAgICAvLyBTZXQgYnJlYWtwb2ludFxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYnJlYWtwb2ludHMpIHtcclxuICAgICAgc3dpcGVyLnNldEJyZWFrcG9pbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGQgQ2xhc3Nlc1xyXG4gICAgc3dpcGVyLmFkZENsYXNzZXMoKTtcclxuXHJcbiAgICAvLyBVcGRhdGUgc2l6ZVxyXG4gICAgc3dpcGVyLnVwZGF0ZVNpemUoKTtcclxuXHJcbiAgICAvLyBVcGRhdGUgc2xpZGVzXHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93KSB7XHJcbiAgICAgIHN3aXBlci5jaGVja092ZXJmbG93KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2V0IEdyYWIgQ3Vyc29yXHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5ncmFiQ3Vyc29yICYmIHN3aXBlci5lbmFibGVkKSB7XHJcbiAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2xpZGUgVG8gSW5pdGlhbCBTbGlkZVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCAmJiBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICBzd2lwZXIuc2xpZGVUbyhcclxuICAgICAgICBzd2lwZXIucGFyYW1zLmluaXRpYWxTbGlkZSArIHN3aXBlci52aXJ0dWFsLnNsaWRlc0JlZm9yZSxcclxuICAgICAgICAwLFxyXG4gICAgICAgIHN3aXBlci5wYXJhbXMucnVuQ2FsbGJhY2tzT25Jbml0LFxyXG4gICAgICAgIGZhbHNlLFxyXG4gICAgICAgIHRydWVcclxuICAgICAgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5wYXJhbXMuaW5pdGlhbFNsaWRlLCAwLCBzd2lwZXIucGFyYW1zLnJ1bkNhbGxiYWNrc09uSW5pdCwgZmFsc2UsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENyZWF0ZSBsb29wXHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XHJcbiAgICAgIHN3aXBlci5sb29wQ3JlYXRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXR0YWNoIGV2ZW50c1xyXG4gICAgc3dpcGVyLmF0dGFjaEV2ZW50cygpO1xyXG4gICAgWy4uLnN3aXBlci5lbC5xdWVyeVNlbGVjdG9yQWxsKCdbbG9hZGluZz1cImxhenlcIl0nKV0uZm9yRWFjaCgoaW1hZ2VFbCkgPT4ge1xyXG4gICAgICBpZiAoaW1hZ2VFbC5jb21wbGV0ZSkge1xyXG4gICAgICAgIHByb2Nlc3NMYXp5UHJlbG9hZGVyKHN3aXBlciwgaW1hZ2VFbCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaW1hZ2VFbC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKGUpID0+IHtcclxuICAgICAgICAgIHByb2Nlc3NMYXp5UHJlbG9hZGVyKHN3aXBlciwgZS50YXJnZXQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHByZWxvYWQoc3dpcGVyKTtcclxuXHJcbiAgICAvLyBJbml0IEZsYWdcclxuICAgIHN3aXBlci5pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICBwcmVsb2FkKHN3aXBlcik7XHJcblxyXG4gICAgLy8gRW1pdFxyXG4gICAgc3dpcGVyLmVtaXQoJ2luaXQnKTtcclxuICAgIHN3aXBlci5lbWl0KCdhZnRlckluaXQnKTtcclxuICAgIHJldHVybiBzd2lwZXI7XHJcbiAgfVxyXG4gIGRlc3Ryb3koZGVsZXRlSW5zdGFuY2UsIGNsZWFuU3R5bGVzKSB7XHJcbiAgICBpZiAoZGVsZXRlSW5zdGFuY2UgPT09IHZvaWQgMCkge1xyXG4gICAgICBkZWxldGVJbnN0YW5jZSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAoY2xlYW5TdHlsZXMgPT09IHZvaWQgMCkge1xyXG4gICAgICBjbGVhblN0eWxlcyA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gICAgY29uc3QgeyBwYXJhbXMsIGVsLCB3cmFwcGVyRWwsIHNsaWRlcyB9ID0gc3dpcGVyO1xyXG4gICAgaWYgKHR5cGVvZiBzd2lwZXIucGFyYW1zID09PSAndW5kZWZpbmVkJyB8fCBzd2lwZXIuZGVzdHJveWVkKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgc3dpcGVyLmVtaXQoJ2JlZm9yZURlc3Ryb3knKTtcclxuXHJcbiAgICAvLyBJbml0IEZsYWdcclxuICAgIHN3aXBlci5pbml0aWFsaXplZCA9IGZhbHNlO1xyXG5cclxuICAgIC8vIERldGFjaCBldmVudHNcclxuICAgIHN3aXBlci5kZXRhY2hFdmVudHMoKTtcclxuXHJcbiAgICAvLyBEZXN0cm95IGxvb3BcclxuICAgIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDbGVhbnVwIHN0eWxlc1xyXG4gICAgaWYgKGNsZWFuU3R5bGVzKSB7XHJcbiAgICAgIHN3aXBlci5yZW1vdmVDbGFzc2VzKCk7XHJcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcclxuICAgICAgd3JhcHBlckVsLnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcclxuICAgICAgaWYgKHNsaWRlcyAmJiBzbGlkZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgc2xpZGVzLmZvckVhY2goKHNsaWRlRWwpID0+IHtcclxuICAgICAgICAgIHNsaWRlRWwuY2xhc3NMaXN0LnJlbW92ZShcclxuICAgICAgICAgICAgcGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzLFxyXG4gICAgICAgICAgICBwYXJhbXMuc2xpZGVBY3RpdmVDbGFzcyxcclxuICAgICAgICAgICAgcGFyYW1zLnNsaWRlTmV4dENsYXNzLFxyXG4gICAgICAgICAgICBwYXJhbXMuc2xpZGVQcmV2Q2xhc3NcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBzbGlkZUVsLnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcclxuICAgICAgICAgIHNsaWRlRWwucmVtb3ZlQXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpO1xyXG4gICAgICAgI
9266H0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuZW1pdCgnZGVzdHJveScpO1xyXG5cclxuICAgIC8vIERldGFjaCBlbWl0dGVyIGV2ZW50c1xyXG4gICAgT2JqZWN0LmtleXMoc3dpcGVyLmV2ZW50c0xpc3RlbmVycykuZm9yRWFjaCgoZXZlbnROYW1lKSA9PiB7XHJcbiAgICAgIHN3aXBlci5vZmYoZXZlbnROYW1lKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGRlbGV0ZUluc3RhbmNlICE9PSBmYWxzZSkge1xyXG4gICAgICBzd2lwZXIuZWwuc3dpcGVyID0gbnVsbDtcclxuICAgICAgZGVsZXRlUHJvcHMoc3dpcGVyKTtcclxuICAgIH1cclxuICAgIHN3aXBlci5kZXN0cm95ZWQgPSB0cnVlO1xyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG4gIHN0YXRpYyBleHRlbmREZWZhdWx0cyhuZXdEZWZhdWx0cykge1xyXG4gICAgZXh0ZW5kKGV4dGVuZGVkRGVmYXVsdHMsIG5ld0RlZmF1bHRzKTtcclxuICB9XHJcbiAgc3RhdGljIGdldCBleHRlbmRlZERlZmF1bHRzKCkge1xyXG4gICAgcmV0dXJuIGV4dGVuZGVkRGVmYXVsdHM7XHJcbiAgfVxyXG4gIHN0YXRpYyBnZXQgZGVmYXVsdHMoKSB7XHJcbiAgICByZXR1cm4gZGVmYXVsdHM7XHJcbiAgfVxyXG4gIHN0YXRpYyBpbnN0YWxsTW9kdWxlKG1vZCkge1xyXG4gICAgaWYgKCFTd2lwZXIucHJvdG90eXBlLl9fbW9kdWxlc19fKSBTd2lwZXIucHJvdG90eXBlLl9fbW9kdWxlc19fID0gW107XHJcbiAgICBjb25zdCBtb2R1bGVzID0gU3dpcGVyLnByb3RvdHlwZS5fX21vZHVsZXNfXztcclxuICAgIGlmICh0eXBlb2YgbW9kID09PSAnZnVuY3Rpb24nICYmIG1vZHVsZXMuaW5kZXhPZihtb2QpIDwgMCkge1xyXG4gICAgICBtb2R1bGVzLnB1c2gobW9kKTtcclxuICAgIH1cclxuICB9XHJcbiAgc3RhdGljIHVzZShtb2R1bGUpIHtcclxuICAgIGlmIChBcnJheS5pc0FycmF5KG1vZHVsZSkpIHtcclxuICAgICAgbW9kdWxlLmZvckVhY2goKG0pID0+IFN3aXBlci5pbnN0YWxsTW9kdWxlKG0pKTtcclxuICAgICAgcmV0dXJuIFN3aXBlcjtcclxuICAgIH1cclxuICAgIFN3aXBlci5pbnN0YWxsTW9kdWxlKG1vZHVsZSk7XHJcbiAgICByZXR1cm4gU3dpcGVyO1xyXG4gIH1cclxufVxyXG5PYmplY3Qua2V5cyhwcm90b3R5cGVzKS5mb3JFYWNoKChwcm90b3R5cGVHcm91cCkgPT4ge1xyXG4gIE9iamVjdC5rZXlzKHByb3RvdHlwZXNbcHJvdG90eXBlR3JvdXBdKS5mb3JFYWNoKChwcm90b01ldGhvZCkgPT4ge1xyXG4gICAgU3dpcGVyLnByb3RvdHlwZVtwcm90b01ldGhvZF0gPSBwcm90b3R5cGVzW3Byb3RvdHlwZUdyb3VwXVtwcm90b01ldGhvZF07XHJcbiAgfSk7XHJcbn0pO1xyXG5Td2lwZXIudXNlKFtSZXNpemUsIE9ic2VydmVyXSk7XHJcblxyXG5mdW5jdGlvbiBWaXJ0dWFsKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24sIGVtaXQgfSA9IF9yZWY7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIHZpcnR1YWw6IHtcclxuICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICAgIHNsaWRlczogW10sXHJcbiAgICAgIGNhY2hlOiB0cnVlLFxyXG4gICAgICByZW5kZXJTbGlkZTogbnVsbCxcclxuICAgICAgcmVuZGVyRXh0ZXJuYWw6IG51bGwsXHJcbiAgICAgIHJlbmRlckV4dGVybmFsVXBkYXRlOiB0cnVlLFxyXG4gICAgICBhZGRTbGlkZXNCZWZvcmU6IDAsXHJcbiAgICAgIGFkZFNsaWRlc0FmdGVyOiAwLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBsZXQgY3NzTW9kZVRpbWVvdXQ7XHJcbiAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xyXG4gIHN3aXBlci52aXJ0dWFsID0ge1xyXG4gICAgY2FjaGU6IHt9LFxyXG4gICAgZnJvbTogdW5kZWZpbmVkLFxyXG4gICAgdG86IHVuZGVmaW5lZCxcclxuICAgIHNsaWRlczogW10sXHJcbiAgICBvZmZzZXQ6IDAsXHJcbiAgICBzbGlkZXNHcmlkOiBbXSxcclxuICB9O1xyXG4gIGNvbnN0IHRlbXBET00gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICBmdW5jdGlvbiByZW5kZXJTbGlkZShzbGlkZSwgaW5kZXgpIHtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMudmlydHVhbDtcclxuICAgIGlmIChwYXJhbXMuY2FjaGUgJiYgc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdKSB7XHJcbiAgICAgIHJldHVybiBzd2lwZXIudmlydHVhbC5jYWNoZVtpbmRleF07XHJcbiAgICB9XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgIGxldCBzbGlkZUVsO1xyXG4gICAgaWYgKHBhcmFtcy5yZW5kZXJTbGlkZSkge1xyXG4gICAgICBzbGlkZUVsID0gcGFyYW1zLnJlbmRlclNsaWRlLmNhbGwoc3dpcGVyLCBzbGlkZSwgaW5kZXgpO1xyXG4gICAgICBpZiAodHlwZW9mIHNsaWRlRWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgdGVtcERPTS5pbm5lckhUTUwgPSBzbGlkZUVsO1xyXG4gICAgICAgIHNsaWRlRWwgPSB0ZW1wRE9NLmNoaWxkcmVuWzBdO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKHN3aXBlci5pc0VsZW1lbnQpIHtcclxuICAgICAgc2xpZGVFbCA9IGNyZWF0ZUVsZW1lbnQoJ3N3aXBlci1zbGlkZScpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2xpZGVFbCA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIHN3aXBlci5wYXJhbXMuc2xpZGVDbGFzcyk7XHJcbiAgICB9XHJcbiAgICBzbGlkZUVsLnNldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBpbmRleCk7XHJcbiAgICBpZiAoIXBhcmFtcy5yZW5kZXJTbGlkZSkge1xyXG4gICAgICBzbGlkZUVsLmlubmVySFRNTCA9IHNsaWRlO1xyXG4gICAgfVxyXG4gICAgaWYgKHBhcmFtcy5jYWNoZSkgc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdID0gc2xpZGVFbDtcclxuICAgIHJldHVybiBzbGlkZUVsO1xyXG4gIH1cclxuICBmdW5jdGlvbiB1cGRhdGUoZm9yY2UpIHtcclxuICAgIGNvbnN0IHsgc2xpZGVzUGVyVmlldywgc2xpZGVzUGVyR3JvdXAsIGNlbnRlcmVkU2xpZGVzLCBsb29wOiBpc0xvb3AgfSA9IHN3aXBlci5wYXJhbXM7XHJcbiAgICBjb25zdCB7IGFkZFNsaWRlc0JlZm9yZSwgYWRkU2xpZGVzQWZ0ZXIgfSA9IHN3aXBlci5wYXJhbXMudmlydHVhbDtcclxuICAgIGNvbnN0IHtcclxuICAgICAgZnJvbTogcHJldmlvdXNGcm9tLFxyXG4gICAgICB0bzogcHJldmlvdXNUbyxcclxuICAgICAgc2xpZGVzLFxyXG4gICAgICBzbGlkZXNHcmlkOiBwcmV2aW91c1NsaWRlc0dyaWQsXHJcbiAgICAgIG9mZnNldDogcHJldmlvdXNPZmZzZXQsXHJcbiAgICB9ID0gc3dpcGVyLnZpcnR1YWw7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4IHx8IDA7XHJcbiAgICBsZXQgb2Zmc2V0UHJvcDtcclxuICAgIGlmIChzd2lwZXIucnRsVHJhbnNsYXRlKSBvZmZzZXRQcm9wID0gJ3JpZ2h0JztcclxuICAgIGVsc2Ugb2Zmc2V0UHJvcCA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICdsZWZ0JyA6ICd0b3AnO1xyXG4gICAgbGV0IHNsaWRlc0FmdGVyO1xyXG4gICAgbGV0IHNsaWRlc0JlZm9yZTtcclxuICAgIGlmIChjZW50ZXJlZFNsaWRlcykge1xyXG4gICAgICBzbGlkZXNBZnRlciA9IE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpICsgc2xpZGVzUGVyR3JvdXAgKyBhZGRTbGlkZXNBZnRlcjtcclxuICAgICAgc2xpZGVzQmVmb3JlID0gTWF0aC5mbG9vcihzbGlkZXNQZXJWaWV3IC8gMikgKyBzbGlkZXNQZXJHcm91cCArIGFkZFNsaWRlc0JlZm9yZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNsaWRlc0FmdGVyID0gc2xpZGVzUGVyVmlldyArIChzbGlkZXNQZXJHcm91cCAtIDEpICsgYWRkU2xpZGVzQWZ0ZXI7X
9266HJcbiAgICAgIHNsaWRlc0JlZm9yZSA9IChpc0xvb3AgPyBzbGlkZXNQZXJWaWV3IDogc2xpZGVzUGVyR3JvdXApICsgYWRkU2xpZGVzQmVmb3JlO1xyXG4gICAgfVxyXG4gICAgbGV0IGZyb20gPSBhY3RpdmVJbmRleCAtIHNsaWRlc0JlZm9yZTtcclxuICAgIGxldCB0byA9IGFjdGl2ZUluZGV4ICsgc2xpZGVzQWZ0ZXI7XHJcbiAgICBpZiAoIWlzTG9vcCkge1xyXG4gICAgICBmcm9tID0gTWF0aC5tYXgoZnJvbSwgMCk7XHJcbiAgICAgIHRvID0gTWF0aC5taW4odG8sIHNsaWRlcy5sZW5ndGggLSAxKTtcclxuICAgIH1cclxuICAgIGxldCBvZmZzZXQgPSAoc3dpcGVyLnNsaWRlc0dyaWRbZnJvbV0gfHwgMCkgLSAoc3dpcGVyLnNsaWRlc0dyaWRbMF0gfHwgMCk7XHJcbiAgICBpZiAoaXNMb29wICYmIGFjdGl2ZUluZGV4ID49IHNsaWRlc0JlZm9yZSkge1xyXG4gICAgICBmcm9tIC09IHNsaWRlc0JlZm9yZTtcclxuICAgICAgaWYgKCFjZW50ZXJlZFNsaWRlcykgb2Zmc2V0ICs9IHN3aXBlci5zbGlkZXNHcmlkWzBdO1xyXG4gICAgfSBlbHNlIGlmIChpc0xvb3AgJiYgYWN0aXZlSW5kZXggPCBzbGlkZXNCZWZvcmUpIHtcclxuICAgICAgZnJvbSA9IC1zbGlkZXNCZWZvcmU7XHJcbiAgICAgIGlmIChjZW50ZXJlZFNsaWRlcykgb2Zmc2V0ICs9IHN3aXBlci5zbGlkZXNHcmlkWzBdO1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIudmlydHVhbCwge1xyXG4gICAgICBmcm9tLFxyXG4gICAgICB0byxcclxuICAgICAgb2Zmc2V0LFxyXG4gICAgICBzbGlkZXNHcmlkOiBzd2lwZXIuc2xpZGVzR3JpZCxcclxuICAgICAgc2xpZGVzQmVmb3JlLFxyXG4gICAgICBzbGlkZXNBZnRlcixcclxuICAgIH0pO1xyXG4gICAgZnVuY3Rpb24gb25SZW5kZXJlZCgpIHtcclxuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xyXG4gICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcclxuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcclxuICAgICAgZW1pdCgndmlydHVhbFVwZGF0ZScpO1xyXG4gICAgfVxyXG4gICAgaWYgKHByZXZpb3VzRnJvbSA9PT0gZnJvbSAmJiBwcmV2aW91c1RvID09PSB0byAmJiAhZm9yY2UpIHtcclxuICAgICAgaWYgKHN3aXBlci5zbGlkZXNHcmlkICE9PSBwcmV2aW91c1NsaWRlc0dyaWQgJiYgb2Zmc2V0ICE9PSBwcmV2aW91c09mZnNldCkge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZXMuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgICAgICAgc2xpZGVFbC5zdHlsZVtvZmZzZXRQcm9wXSA9IGAke29mZnNldCAtIE1hdGguYWJzKHN3aXBlci5jc3NPdmVyZmxvd0FkanVzdG1lbnQoKSl9cHhgO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcygpO1xyXG4gICAgICBlbWl0KCd2aXJ0dWFsVXBkYXRlJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwucmVuZGVyRXh0ZXJuYWwpIHtcclxuICAgICAgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLnJlbmRlckV4dGVybmFsLmNhbGwoc3dpcGVyLCB7XHJcbiAgICAgICAgb2Zmc2V0LFxyXG4gICAgICAgIGZyb20sXHJcbiAgICAgICAgdG8sXHJcbiAgICAgICAgc2xpZGVzOiAoZnVuY3Rpb24gZ2V0U2xpZGVzKCkge1xyXG4gICAgICAgICAgY29uc3Qgc2xpZGVzVG9SZW5kZXIgPSBbXTtcclxuICAgICAgICAgIGZvciAobGV0IGkgPSBmcm9tOyBpIDw9IHRvOyBpICs9IDEpIHtcclxuICAgICAgICAgICAgc2xpZGVzVG9SZW5kZXIucHVzaChzbGlkZXNbaV0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIHNsaWRlc1RvUmVuZGVyO1xyXG4gICAgICAgIH0pKCksXHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLnJlbmRlckV4dGVybmFsVXBkYXRlKSB7XHJcbiAgICAgICAgb25SZW5kZXJlZCgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVtaXQoJ3ZpcnR1YWxVcGRhdGUnKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBwcmVwZW5kSW5kZXhlcyA9IFtdO1xyXG4gICAgY29uc3QgYXBwZW5kSW5kZXhlcyA9IFtdO1xyXG4gICAgY29uc3QgZ2V0U2xpZGVJbmRleCA9IChpbmRleCkgPT4ge1xyXG4gICAgICBsZXQgc2xpZGVJbmRleCA9IGluZGV4O1xyXG4gICAgICBpZiAoaW5kZXggPCAwKSB7XHJcbiAgICAgICAgc2xpZGVJbmRleCA9IHNsaWRlcy5sZW5ndGggKyBpbmRleDtcclxuICAgICAgfSBlbHNlIGlmIChzbGlkZUluZGV4ID49IHNsaWRlcy5sZW5ndGgpIHtcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgICAgICBzbGlkZUluZGV4ID0gc2xpZGVJbmRleCAtIHNsaWRlcy5sZW5ndGg7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHNsaWRlSW5kZXg7XHJcbiAgICB9O1xyXG4gICAgaWYgKGZvcmNlKSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZXNFbC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9LCBzd2lwZXItc2xpZGVgKS5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgICAgc2xpZGVFbC5yZW1vdmUoKTtcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBmb3IgKGxldCBpID0gcHJldmlvdXNGcm9tOyBpIDw9IHByZXZpb3VzVG87IGkgKz0gMSkge1xyXG4gICAgICAgIGlmIChpIDwgZnJvbSB8fCBpID4gdG8pIHtcclxuICAgICAgICAgIGNvbnN0IHNsaWRlSW5kZXggPSBnZXRTbGlkZUluZGV4KGkpO1xyXG4gICAgICAgICAgc3dpcGVyLnNsaWRlc0VsXHJcbiAgICAgICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKFxyXG4gICAgICAgICAgICAgIGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9W2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtzbGlkZUluZGV4fVwiXSwgc3dpcGVyLXNsaWRlW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtzbGlkZUluZGV4fVwiXWBcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAuZm9yRWFjaCgoc2xpZGVFbCkgPT4ge1xyXG4gICAgICAgICAgICAgI
9266HNsaWRlRWwucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgbG9vcEZyb20gPSBpc0xvb3AgPyAtc2xpZGVzLmxlbmd0aCA6IDA7XHJcbiAgICBjb25zdCBsb29wVG8gPSBpc0xvb3AgPyBzbGlkZXMubGVuZ3RoICogMiA6IHNsaWRlcy5sZW5ndGg7XHJcbiAgICBmb3IgKGxldCBpID0gbG9vcEZyb207IGkgPCBsb29wVG87IGkgKz0gMSkge1xyXG4gICAgICBpZiAoaSA+PSBmcm9tICYmIGkgPD0gdG8pIHtcclxuICAgICAgICBjb25zdCBzbGlkZUluZGV4ID0gZ2V0U2xpZGVJbmRleChpKTtcclxuICAgICAgICBpZiAodHlwZW9mIHByZXZpb3VzVG8gPT09ICd1bmRlZmluZWQnIHx8IGZvcmNlKSB7XHJcbiAgICAgICAgICBhcHBlbmRJbmRleGVzLnB1c2goc2xpZGVJbmRleCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGlmIChpID4gcHJldmlvdXNUbykgYXBwZW5kSW5kZXhlcy5wdXNoKHNsaWRlSW5kZXgpO1xyXG4gICAgICAgICAgaWYgKGkgPCBwcmV2aW91c0Zyb20pIHByZXBlbmRJbmRleGVzLnB1c2goc2xpZGVJbmRleCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBhcHBlbmRJbmRleGVzLmZvckVhY2goKGluZGV4KSA9PiB7XHJcbiAgICAgIHN3aXBlci5zbGlkZXNFbC5hcHBlbmQocmVuZGVyU2xpZGUoc2xpZGVzW2luZGV4XSwgaW5kZXgpKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGlzTG9vcCkge1xyXG4gICAgICBmb3IgKGxldCBpID0gcHJlcGVuZEluZGV4ZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcclxuICAgICAgICBjb25zdCBpbmRleCA9IHByZXBlbmRJbmRleGVzW2ldO1xyXG4gICAgICAgIHN3aXBlci5zbGlkZXNFbC5wcmVwZW5kKHJlbmRlclNsaWRlKHNsaWRlc1tpbmRleF0sIGluZGV4KSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHByZXBlbmRJbmRleGVzLnNvcnQoKGEsIGIpID0+IGIgLSBhKTtcclxuICAgICAgcHJlcGVuZEluZGV4ZXMuZm9yRWFjaCgoaW5kZXgpID0+IHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVzRWwucHJlcGVuZChyZW5kZXJTbGlkZShzbGlkZXNbaW5kZXhdLCBpbmRleCkpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGVsZW1lbnRDaGlsZHJlbihzd2lwZXIuc2xpZGVzRWwsICcuc3dpcGVyLXNsaWRlLCBzd2lwZXItc2xpZGUnKS5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgIHNsaWRlRWwuc3R5bGVbb2Zmc2V0UHJvcF0gPSBgJHtvZmZzZXQgLSBNYXRoLmFicyhzd2lwZXIuY3NzT3ZlcmZsb3dBZGp1c3RtZW50KCkpfXB4YDtcclxuICAgIH0pO1xyXG4gICAgb25SZW5kZXJlZCgpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBhcHBlbmRTbGlkZShzbGlkZXMpIHtcclxuICAgIGlmICh0eXBlb2Ygc2xpZGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXMpIHtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgICBpZiAoc2xpZGVzW2ldKSBzd2lwZXIudmlydHVhbC5zbGlkZXMucHVzaChzbGlkZXNbaV0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMucHVzaChzbGlkZXMpO1xyXG4gICAgfVxyXG4gICAgdXBkYXRlKHRydWUpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBwcmVwZW5kU2xpZGUoc2xpZGVzKSB7XHJcbiAgICBjb25zdCBhY3RpdmVJbmRleCA9IHN3aXBlci5hY3RpdmVJbmRleDtcclxuICAgIGxldCBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgMTtcclxuICAgIGxldCBudW1iZXJPZk5ld1NsaWRlcyA9IDE7XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzbGlkZXMpKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgICAgaWYgKHNsaWRlc1tpXSkgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnVuc2hpZnQoc2xpZGVzW2ldKTtcclxuICAgICAgfVxyXG4gICAgICBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgc2xpZGVzLmxlbmd0aDtcclxuICAgICAgbnVtYmVyT2ZOZXdTbGlkZXMgPSBzbGlkZXMubGVuZ3RoO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnVuc2hpZnQoc2xpZGVzKTtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwuY2FjaGUpIHtcclxuICAgICAgY29uc3QgY2FjaGUgPSBzd2lwZXIudmlydHVhbC5jYWNoZTtcclxuICAgICAgY29uc3QgbmV3Q2FjaGUgPSB7fTtcclxuICAgICAgT2JqZWN0LmtleXMoY2FjaGUpLmZvckVhY2goKGNhY2hlZEluZGV4KSA9PiB7XHJcbiAgICAgICAgY29uc3QgY2FjaGVkRWwgPSBjYWNoZVtjYWNoZWRJbmRleF07XHJcbiAgICAgICAgY29uc3QgY2FjaGVkRWxJbmRleCA9IGNhY2hlZEVsLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKTtcclxuICAgICAgICBpZiAoY2FjaGVkRWxJbmRleCkge1xyXG4gICAgICAgICAgY2FjaGVkRWwuc2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcsIHBhcnNlSW50KGNhY2hlZEVsSW5kZXgsIDEwKSArIG51bWJlck9mTmV3U2xpZGVzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbmV3Q2FjaGVbcGFyc2VJbnQoY2FjaGVkSW5kZXgsIDEwKSArIG51bWJlck9mTmV3U2xpZGVzXSA9IGNhY2hlZEVsO1xyXG4gICAgICB9KTtcclxuICAgICAgc3dpcGVyLnZpcnR1YWwuY2FjaGUgPSBuZXdDYWNoZTtcclxuICAgIH1cclxuICAgIHVwZGF0ZSh0cnVlKTtcclxuICAgIHN3aXBlci5zbGlkZVRvKG5ld0FjdGl2ZUluZGV4LCAwKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gcmVtb3ZlU2xpZGUoc2xpZGVzSW5kZXhlcykge1xyXG4gICAgaWYgKHR5cGVvZiBzbGlkZXNJbmRleGVzID09PSAndW5kZWZpbmVkJyB8fCBzbGlkZXNJbmRleGVzID09PSBudWxsKSByZXR1cm47XHJcbiAgICBsZXQgYWN0aXZlSW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzbGlkZXNJbmRleGVzKSkge1xyXG4gICAgICBmb3IgKGxldCBpID0gc2xpZGVzSW5kZX
9266hlcy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xyXG4gICAgICAgIHN3aXBlci52aXJ0dWFsLnNsaWRlcy5zcGxpY2Uoc2xpZGVzSW5kZXhlc1tpXSwgMSk7XHJcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbC5jYWNoZSkge1xyXG4gICAgICAgICAgZGVsZXRlIHN3aXBlci52aXJ0dWFsLmNhY2hlW3NsaWRlc0luZGV4ZXNbaV1dO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc2xpZGVzSW5kZXhlc1tpXSA8IGFjdGl2ZUluZGV4KSBhY3RpdmVJbmRleCAtPSAxO1xyXG4gICAgICAgIGFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoYWN0aXZlSW5kZXgsIDApO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMuc3BsaWNlKHNsaWRlc0luZGV4ZXMsIDEpO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmNhY2hlKSB7XHJcbiAgICAgICAgZGVsZXRlIHN3aXBlci52aXJ0dWFsLmNhY2hlW3NsaWRlc0luZGV4ZXNdO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzbGlkZXNJbmRleGVzIDwgYWN0aXZlSW5kZXgpIGFjdGl2ZUluZGV4IC09IDE7XHJcbiAgICAgIGFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoYWN0aXZlSW5kZXgsIDApO1xyXG4gICAgfVxyXG4gICAgdXBkYXRlKHRydWUpO1xyXG4gICAgc3dpcGVyLnNsaWRlVG8oYWN0aXZlSW5kZXgsIDApO1xyXG4gIH1cclxuICBmdW5jdGlvbiByZW1vdmVBbGxTbGlkZXMoKSB7XHJcbiAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMgPSBbXTtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwuY2FjaGUpIHtcclxuICAgICAgc3dpcGVyLnZpcnR1YWwuY2FjaGUgPSB7fTtcclxuICAgIH1cclxuICAgIHVwZGF0ZSh0cnVlKTtcclxuICAgIHN3aXBlci5zbGlkZVRvKDAsIDApO1xyXG4gIH1cclxuICBvbignYmVmb3JlSW5pdCcsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHJldHVybjtcclxuICAgIGxldCBkb21TbGlkZXNBc3NpZ25lZDtcclxuICAgIGlmICh0eXBlb2Ygc3dpcGVyLnBhc3NlZFBhcmFtcy52aXJ0dWFsLnNsaWRlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgY29uc3Qgc2xpZGVzID0gWy4uLnN3aXBlci5zbGlkZXNFbC5jaGlsZHJlbl0uZmlsdGVyKChlbCkgPT5cclxuICAgICAgICBlbC5tYXRjaGVzKGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9LCBzd2lwZXItc2xpZGVgKVxyXG4gICAgICApO1xyXG4gICAgICBpZiAoc2xpZGVzICYmIHNsaWRlcy5sZW5ndGgpIHtcclxuICAgICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMgPSBbLi4uc2xpZGVzXTtcclxuICAgICAgICBkb21TbGlkZXNBc3NpZ25lZCA9IHRydWU7XHJcbiAgICAgICAgc2xpZGVzLmZvckVhY2goKHNsaWRlRWwsIHNsaWRlSW5kZXgpID0+IHtcclxuICAgICAgICAgIHNsaWRlRWwuc2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcsIHNsaWRlSW5kZXgpO1xyXG4gICAgICAgICAgc3dpcGVyLnZpcnR1YWwuY2FjaGVbc2xpZGVJbmRleF0gPSBzbGlkZUVsO1xyXG4gICAgICAgICAgc2xpZGVFbC5yZW1vdmUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCFkb21TbGlkZXNBc3NpZ25lZCkge1xyXG4gICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMgPSBzd2lwZXIucGFyYW1zLnZpcnR1YWwuc2xpZGVzO1xyXG4gICAgfVxyXG4gICAgc3dpcGVyLmNsYXNzTmFtZXMucHVzaChgJHtzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9dmlydHVhbGApO1xyXG4gICAgc3dpcGVyLnBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzID0gdHJ1ZTtcclxuICAgIHN3aXBlci5vcmlnaW5hbFBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzID0gdHJ1ZTtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5pbml0aWFsU2xpZGUpIHtcclxuICAgICAgdXBkYXRlKCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ3NldFRyYW5zbGF0ZScsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHJldHVybjtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUgJiYgIXN3aXBlci5faW1tZWRpYXRlVmlydHVhbCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQoY3NzTW9kZVRpbWVvdXQpO1xyXG4gICAgICBjc3NNb2RlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIHVwZGF0ZSgpO1xyXG4gICAgICB9LCAxMDApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdXBkYXRlKCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ2luaXQgdXBkYXRlIHJlc2l6ZScsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHJldHVybjtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgc2V0Q1NTUHJvcGVydHkoc3dpcGVyLndyYXBwZXJFbCwgJy0tc3dpcGVyLXZpcnR1YWwtc2l6ZScsIGAke3N3aXBlci52aXJ0dWFsU2l6ZX1weGApO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLnZpcnR1YWwsIHtcclxuICAgIGFwcGVuZFNsaWRlLFxyXG4gICAgcHJlcGVuZFNsaWRlLFxyXG4gICAgcmVtb3ZlU2xpZGUsXHJcbiAgICByZW1vdmVBbGxTbGlkZXMsXHJcbiAgICB1cGRhdGUsXHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qIGVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXHJcbmZ1bmN0aW9uIEtleWJvYXJkKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24sIGVtaXQgfSA9IF9yZWY7XHJcbiAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIHN3aXBlci5rZXlib2FyZCA9IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gIH07XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGtleWJvYXJkOiB7XHJcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICBvbmx5SW5WaWV3cG9ydDogdHJ1ZSxcclxuICAgICAgcGFnZVVwRG93bjogdHJ1ZSxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgZnVuY3Rpb24gaGFuZGxlKGV2ZW50KSB7XHJcbiAgICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XHJcbiAgICBjb25zdCB7IHJ0bFRyYW5zbGF0ZTogcnRsIH0gPSBzd2lwZXI7XHJcbiAgICBsZXQgZSA9IGV2ZW50O1xyXG4gICAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDsgLy8ganF1ZXJ5IGZpeFxyXG4gICAgY29uc3Qga2MgPSBlLmtleUNvZGUgfHwgZS5jaGFyQ29kZTtcclxuICAgIGNvbnN0IHBhZ2VVcERvd24gPSBzd2lwZXIucGFyYW1zLmtleWJvYXJkLnBhZ2VVcERvd247XHJcbiAgICBjb25zdCBpc1BhZ2VVcCA9IHBhZ2VVcERvd24gJiYga2MgPT09IDMzO1xyXG4gICAgY29uc3QgaXNQYWdlRG93biA9IHBhZ2VVcERvd24gJiYga2MgPT09IDM0O1xyXG4gICAgY29uc3QgaXNBcnJvd0xlZnQgPSBrYyA9PT0gMzc7XHJcbiAgICBjb25zdCBpc0Fycm93UmlnaHQgPSBrYyA9PT0gMzk7XHJcbiAgICBjb25zdCBpc0Fycm93VXAgPSBrYyA9PT0gMzg7XHJcbiAgICBjb25zdCBpc0Fycm93RG93biA9IGtjID09PSA0MDtcclxuICAgIC8vIERpcmVjdGlvbnMgbG9ja3NcclxuICAgIGlmIChcclxuICAgICAgIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJlxyXG4gICAgICAoKHN3aXBlci5pc0hvcml6b250YWwoKSAmJi
9266Bpc0Fycm93UmlnaHQpIHx8IChzd2lwZXIuaXNWZXJ0aWNhbCgpICYmIGlzQXJyb3dEb3duKSB8fCBpc1BhZ2VEb3duKVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgIXN3aXBlci5hbGxvd1NsaWRlUHJldiAmJlxyXG4gICAgICAoKHN3aXBlci5pc0hvcml6b250YWwoKSAmJiBpc0Fycm93TGVmdCkgfHwgKHN3aXBlci5pc1ZlcnRpY2FsKCkgJiYgaXNBcnJvd1VwKSB8fCBpc1BhZ2VVcClcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoZS5zaGlmdEtleSB8fCBlLmFsdEtleSB8fCBlLmN0cmxLZXkgfHwgZS5tZXRhS2V5KSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBpZiAoXHJcbiAgICAgIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiZcclxuICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ub2RlTmFtZSAmJlxyXG4gICAgICAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnIHx8XHJcbiAgICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAndGV4dGFyZWEnKVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBpZiAoXHJcbiAgICAgIHN3aXBlci5wYXJhbXMua2V5Ym9hcmQub25seUluVmlld3BvcnQgJiZcclxuICAgICAgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd0xlZnQgfHwgaXNBcnJvd1JpZ2h0IHx8IGlzQXJyb3dVcCB8fCBpc0Fycm93RG93bilcclxuICAgICkge1xyXG4gICAgICBsZXQgaW5WaWV3ID0gZmFsc2U7XHJcbiAgICAgIC8vIENoZWNrIHRoYXQgc3dpcGVyIHNob3VsZCBiZSBpbnNpZGUgb2YgdmlzaWJsZSBhcmVhIG9mIHdpbmRvd1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgZWxlbWVudFBhcmVudHMoc3dpcGVyLmVsLCBgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfSwgc3dpcGVyLXNsaWRlYCkubGVuZ3RoID4gMCAmJlxyXG4gICAgICAgIGVsZW1lbnRQYXJlbnRzKHN3aXBlci5lbCwgYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVBY3RpdmVDbGFzc31gKS5sZW5ndGggPT09IDBcclxuICAgICAgKSB7XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBlbCA9IHN3aXBlci5lbDtcclxuICAgICAgY29uc3Qgc3dpcGVyV2lkdGggPSBlbC5jbGllbnRXaWR0aDtcclxuICAgICAgY29uc3Qgc3dpcGVySGVpZ2h0ID0gZWwuY2xpZW50SGVpZ2h0O1xyXG4gICAgICBjb25zdCB3aW5kb3dXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgICBjb25zdCB3aW5kb3dIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XHJcbiAgICAgIGNvbnN0IHN3aXBlck9mZnNldCA9IGVsZW1lbnRPZmZzZXQoZWwpO1xyXG4gICAgICBpZiAocnRsKSBzd2lwZXJPZmZzZXQubGVmdCAtPSBlbC5zY3JvbGxMZWZ0O1xyXG4gICAgICBjb25zdCBzd2lwZXJDb29yZCA9IFtcclxuICAgICAgICBbc3dpcGVyT2Zmc2V0LmxlZnQsIHN3aXBlck9mZnNldC50b3BdLFxyXG4gICAgICAgIFtzd2lwZXJPZmZzZXQubGVmdCArIHN3aXBlcldpZHRoLCBzd2lwZXJPZmZzZXQudG9wXSxcclxuICAgICAgICBbc3dpcGVyT2Zmc2V0LmxlZnQsIHN3aXBlck9mZnNldC50b3AgKyBzd2lwZXJIZWlnaHRdLFxyXG4gICAgICAgIFtzd2lwZXJPZmZzZXQubGVmdCArIHN3aXBlcldpZHRoLCBzd2lwZXJPZmZzZXQudG9wICsgc3dpcGVySGVpZ2h0XSxcclxuICAgICAgXTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzd2lwZXJDb29yZC5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICAgIGNvbnN0IHBvaW50ID0gc3dpcGVyQ29vcmRbaV07XHJcbiAgICAgICAgaWYgKHBvaW50WzBdID49IDAgJiYgcG9pbnRbMF0gPD0gd2luZG93V2lkdGggJiYgcG9pbnRbMV0gPj0gMCAmJiBwb2ludFsxXSA8PSB3aW5kb3dIZWlnaHQpIHtcclxuICAgICAgICAgIGlmIChwb2ludFswXSA9PT0gMCAmJiBwb2ludFsxXSA9PT0gMCkgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcclxuICAgICAgICAgIGluVmlldyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmICghaW5WaWV3KSByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgICBpZiAoaXNQYWdlVXAgfHwgaXNQYWdlRG93biB8fCBpc0Fycm93TGVmdCB8fCBpc0Fycm93UmlnaHQpIHtcclxuICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGVsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICgoKGlzUGFnZURvd24gfHwgaXNBcnJvd1JpZ2h0KSAmJiAhcnRsKSB8fCAoKGlzUGFnZVVwIHx8IGlzQXJyb3dMZWZ0KSAmJiBydGwpKSBzd2lwZXIuc2xpZGVOZXh0KCk7XHJcbiAgICAgIGlmICgoKGlzUGFnZVVwIHx8IGlzQXJyb3dMZWZ0KSAmJiAhcnRsKSB8fCAoKGlzUGFnZURvd24gfHwgaXNBcnJvd1JpZ2h0KSAmJiBydGwpKSBzd2lwZXIuc2xpZGVQcmV2KCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoaXNQYWdlVXAgfHwgaXNQYWdlRG93biB8fCBpc0Fycm93VXAgfHwgaXNBcnJvd0Rvd24pIHtcclxuICAgICAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGVsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpc1BhZ2VEb3duIHx8IGlzQXJyb3dEb3duKSBzd2lwZXIuc2xpZGVOZXh0KCk7XHJcbiAgICAgIGlmIChpc1BhZ2VVcCB8fCBpc0Fycm93VXApIHN3aXBlci5zbGlkZVByZXYoKTtcclxuICAgIH1cclxuICAgIGVtaXQoJ2tleVByZXNzJywga2MpO1xyXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICB9XHJcbiAgZnVuY3Rpb24gZW5hYmxlKCkge1xyXG4gICAgaWYgKHN3aXBlci5rZXlib2FyZC5lbmFibGVkKSByZXR1cm47XHJcbiAgICBkb2
9266N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgaGFuZGxlKTtcclxuICAgIHN3aXBlci5rZXlib2FyZC5lbmFibGVkID0gdHJ1ZTtcclxuICB9XHJcbiAgZnVuY3Rpb24gZGlzYWJsZSgpIHtcclxuICAgIGlmICghc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQpIHJldHVybjtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBoYW5kbGUpO1xyXG4gICAgc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQgPSBmYWxzZTtcclxuICB9XHJcbiAgb24oJ2luaXQnLCAoKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5rZXlib2FyZC5lbmFibGVkKSB7XHJcbiAgICAgIGVuYWJsZSgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5rZXlib2FyZC5lbmFibGVkKSB7XHJcbiAgICAgIGRpc2FibGUoKTtcclxuICAgIH1cclxuICB9KTtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlci5rZXlib2FyZCwge1xyXG4gICAgZW5hYmxlLFxyXG4gICAgZGlzYWJsZSxcclxuICB9KTtcclxufVxyXG5cclxuLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cclxuZnVuY3Rpb24gTW91c2V3aGVlbChfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uLCBlbWl0IH0gPSBfcmVmO1xyXG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gIGV4dGVuZFBhcmFtcyh7XHJcbiAgICBtb3VzZXdoZWVsOiB7XHJcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICByZWxlYXNlT25FZGdlczogZmFsc2UsXHJcbiAgICAgIGludmVydDogZmFsc2UsXHJcbiAgICAgIGZvcmNlVG9BeGlzOiBmYWxzZSxcclxuICAgICAgc2Vuc2l0aXZpdHk6IDEsXHJcbiAgICAgIGV2ZW50c1RhcmdldDogJ2NvbnRhaW5lcicsXHJcbiAgICAgIHRocmVzaG9sZERlbHRhOiBudWxsLFxyXG4gICAgICB0aHJlc2hvbGRUaW1lOiBudWxsLFxyXG4gICAgICBub01vdXNld2hlZWxDbGFzczogJ3N3aXBlci1uby1tb3VzZXdoZWVsJyxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgc3dpcGVyLm1vdXNld2hlZWwgPSB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICB9O1xyXG4gIGxldCB0aW1lb3V0O1xyXG4gIGxldCBsYXN0U2Nyb2xsVGltZSA9IG5vdygpO1xyXG4gIGxldCBsYXN0RXZlbnRCZWZvcmVTbmFwO1xyXG4gIGNvbnN0IHJlY2VudFdoZWVsRXZlbnRzID0gW107XHJcbiAgZnVuY3Rpb24gbm9ybWFsaXplKGUpIHtcclxuICAgIC8vIFJlYXNvbmFibGUgZGVmYXVsdHNcclxuICAgIGNvbnN0IFBJWEVMX1NURVAgPSAxMDtcclxuICAgIGNvbnN0IExJTkVfSEVJR0hUID0gNDA7XHJcbiAgICBjb25zdCBQQUdFX0hFSUdIVCA9IDgwMDtcclxuICAgIGxldCBzWCA9IDA7XHJcbiAgICBsZXQgc1kgPSAwOyAvLyBzcGluWCwgc3BpbllcclxuICAgIGxldCBwWCA9IDA7XHJcbiAgICBsZXQgcFkgPSAwOyAvLyBwaXhlbFgsIHBpeGVsWVxyXG5cclxuICAgIC8vIExlZ2FjeVxyXG4gICAgaWYgKCdkZXRhaWwnIGluIGUpIHtcclxuICAgICAgc1kgPSBlLmRldGFpbDtcclxuICAgIH1cclxuICAgIGlmICgnd2hlZWxEZWx0YScgaW4gZSkge1xyXG4gICAgICBzWSA9IC1lLndoZWVsRGVsdGEgLyAxMjA7XHJcbiAgICB9XHJcbiAgICBpZiAoJ3doZWVsRGVsdGFZJyBpbiBlKSB7XHJcbiAgICAgIHNZID0gLWUud2hlZWxEZWx0YVkgLyAxMjA7XHJcbiAgICB9XHJcbiAgICBpZiAoJ3doZWVsRGVsdGFYJyBpbiBlKSB7XHJcbiAgICAgIHNYID0gLWUud2hlZWxEZWx0YVggLyAxMjA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gc2lkZSBzY3JvbGxpbmcgb24gRkYgd2l0aCBET01Nb3VzZVNjcm9sbFxyXG4gICAgaWYgKCdheGlzJyBpbiBlICYmIGUuYXhpcyA9PT0gZS5IT1JJWk9OVEFMX0FYSVMpIHtcclxuICAgICAgc1ggPSBzWTtcclxuICAgICAgc1kgPSAwO1xyXG4gICAgfVxyXG4gICAgcFggPSBzWCAqIFBJWEVMX1NURVA7XHJcbiAgICBwWSA9IHNZICogUElYRUxfU1RFUDtcclxuICAgIGlmICgnZGVsdGFZJyBpbiBlKSB7XHJcbiAgICAgIHBZID0gZS5kZWx0YVk7XHJcbiAgICB9XHJcbiAgICBpZiAoJ2RlbHRhWCcgaW4gZSkge1xyXG4gICAgICBwWCA9IGUuZGVsdGFYO1xyXG4gICAgfVxyXG4gICAgaWYgKGUuc2hpZnRLZXkgJiYgIXBYKSB7XHJcbiAgICAgIC8vIGlmIHVzZXIgc2Nyb2xscyB3aXRoIHNoaWZ0IGhlIHdhbnRzIGhvcml6b250YWwgc2Nyb2xsXHJcbiAgICAgIHBYID0gcFk7XHJcbiAgICAgIHBZID0gMDtcclxuICAgIH1cclxuICAgIGlmICgocFggfHwgcFkpICYmIGUuZGVsdGFNb2RlKSB7XHJcbiAgICAgIGlmIChlLmRlbHRhTW9kZSA9PT0gMSkge1xyXG4gICAgICAgIC8vIGRlbHRhIGluIExJTkUgdW5pdHNcclxuICAgICAgICBwWCAqPSBMSU5FX0hFSUdIVDtcclxuICAgICAgICBwWSAqPSBMSU5FX0hFSUdIVDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBkZWx0YSBpbiBQQUdFIHVuaXRzXHJcbiAgICAgICAgcFggKj0gUEFHRV9IRUlHSFQ7XHJcbiAgICAgICAgcFkgKj0gUEFHRV9IRUlHSFQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBGYWxsLWJhY2sgaWYgc3BpbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxyXG4gICAgaWYgKHBYICYmICFzWCkge1xyXG4gICAgICBzWCA9IHBYIDwgMSA/IC0xIDogMTtcclxuICAgIH1cclxuICAgIGlmIChwWSAmJiAhc1kpIHtcclxuICAgICAgc1kgPSBwWSA8IDEgPyAtMSA6IDE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzcGluWDogc1gsXHJcbiAgICAgIHNwaW5ZOiBzWSxcclxuICAgICAgcGl4ZWxYOiBwWCxcclxuICAgICAgcGl4ZWxZOiBwWSxcclxuICAgIH07XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGhhbmRsZU1vdXNlRW50ZXIoKSB7XHJcbiAgICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XHJcbiAgICBzd2lwZXIubW91c2VFbnRlcmVkID0gdHJ1ZTtcclxuICB9XHJcbiAgZnVuY3Rpb24gaGFuZGxlTW91c2VMZWF2ZSgpIHtcclxuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcclxuICAgIHN3aXBlci5tb3VzZUVudGVyZWQgPSBmYWxzZTtcclxuICB9XHJcbiAgZnVuY3Rpb24gYW5pbWF0ZVNsaWRlcihuZXdFdmVudCkge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGREZWx0YSAmJiBuZXdFdmVudC5kZWx0YSA8IHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGREZWx0YSkge1xyXG4gICAgICAvLyBQcmV2ZW50IGlmIGRlbHRhIG9mIHdoZWVsIHNjcm9sbCBkZWx0YSBpcyBiZWxvdyBjb25maWd1cmVkIHRocmVzaG9sZFxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLnRocmVzaG9sZFRpbWUgJiYgbm93KCkgLSBsYXN0U2Nyb2xsVGltZSA8IHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGRUaW1lKSB7XHJcbiAgICAgIC8vIFByZXZlbnQgaWYgdGltZSBiZXR3ZWVuIHNjcm9sbHMgaXMgYmVsb3cgY29uZmlndXJlZCB0aHJlc2hvbGRcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIHRoZSBtb3ZlbWVudCBpcyBOT1QgYmlnIGVub3VnaCBhbmRcclxuICAgIC8vIGlmIHRoZSBsYXN0IHRpbWUgdGhlIHVzZXIgc2Nyb2xsZWQgd2FzIHRvbyBjbG9zZSB0byB0aGUgY3VycmVudCBvbmUgKGF2b2lkIGNvbnRpbnVvdXNseSB0cmlnZ2VyaW5nIHRoZSBzbGlkZXIpOlxyXG4gICAgLy8gICBEb24ndCBnbyBhbnkgZnVydGhlciAoYXZvaWQgaW5zaWduaWZpY2FudCBzY3JvbGwgbW92ZW1lbnQpLlxyXG4gICAgaWYgKG5ld0V2ZW50LmRlbHRhID49IDYgJiYgbm93KCkgLSBsYXN0U2Nyb2xsVGltZSA8IDYwKSB7X
9266HJcbiAgICAgIC8vIFJldHVybiBmYWxzZSBhcyBhIGRlZmF1bHRcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICAvLyBJZiB1c2VyIGlzIHNjcm9sbGluZyB0b3dhcmRzIHRoZSBlbmQ6XHJcbiAgICAvLyAgIElmIHRoZSBzbGlkZXIgaGFzbid0IGhpdCB0aGUgbGF0ZXN0IHNsaWRlIG9yXHJcbiAgICAvLyAgIGlmIHRoZSBzbGlkZXIgaXMgYSBsb29wIGFuZFxyXG4gICAgLy8gICBpZiB0aGUgc2xpZGVyIGlzbid0IG1vdmluZyByaWdodCBub3c6XHJcbiAgICAvLyAgICAgR28gdG8gbmV4dCBzbGlkZSBhbmRcclxuICAgIC8vICAgICBlbWl0IGEgc2Nyb2xsIGV2ZW50LlxyXG4gICAgLy8gRWxzZSAodGhlIHVzZXIgaXMgc2Nyb2xsaW5nIHRvd2FyZHMgdGhlIGJlZ2lubmluZykgYW5kXHJcbiAgICAvLyBpZiB0aGUgc2xpZGVyIGhhc24ndCBoaXQgdGhlIGZpcnN0IHNsaWRlIG9yXHJcbiAgICAvLyBpZiB0aGUgc2xpZGVyIGlzIGEgbG9vcCBhbmRcclxuICAgIC8vIGlmIHRoZSBzbGlkZXIgaXNuJ3QgbW92aW5nIHJpZ2h0IG5vdzpcclxuICAgIC8vICAgR28gdG8gcHJldiBzbGlkZSBhbmRcclxuICAgIC8vICAgZW1pdCBhIHNjcm9sbCBldmVudC5cclxuICAgIGlmIChuZXdFdmVudC5kaXJlY3Rpb24gPCAwKSB7XHJcbiAgICAgIGlmICgoIXN3aXBlci5pc0VuZCB8fCBzd2lwZXIucGFyYW1zLmxvb3ApICYmICFzd2lwZXIuYW5pbWF0aW5nKSB7XHJcbiAgICAgICAgc3dpcGVyLnNsaWRlTmV4dCgpO1xyXG4gICAgICAgIGVtaXQoJ3Njcm9sbCcsIG5ld0V2ZW50LnJhdyk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoKCFzd2lwZXIuaXNCZWdpbm5pbmcgfHwgc3dpcGVyLnBhcmFtcy5sb29wKSAmJiAhc3dpcGVyLmFuaW1hdGluZykge1xyXG4gICAgICBzd2lwZXIuc2xpZGVQcmV2KCk7XHJcbiAgICAgIGVtaXQoJ3Njcm9sbCcsIG5ld0V2ZW50LnJhdyk7XHJcbiAgICB9XHJcbiAgICAvLyBJZiB5b3UgZ290IGhlcmUgaXMgYmVjYXVzZSBhbiBhbmltYXRpb24gaGFzIGJlZW4gdHJpZ2dlcmVkIHNvIHN0b3JlIHRoZSBjdXJyZW50IHRpbWVcclxuICAgIGxhc3RTY3JvbGxUaW1lID0gbmV3IHdpbmRvdy5EYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgLy8gUmV0dXJuIGZhbHNlIGFzIGEgZGVmYXVsdFxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICBmdW5jdGlvbiByZWxlYXNlU2Nyb2xsKG5ld0V2ZW50KSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm1vdXNld2hlZWw7XHJcbiAgICBpZiAobmV3RXZlbnQuZGlyZWN0aW9uIDwgMCkge1xyXG4gICAgICBpZiAoc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLmxvb3AgJiYgcGFyYW1zLnJlbGVhc2VPbkVkZ2VzKSB7XHJcbiAgICAgICAgLy8gUmV0dXJuIHRydWUgdG8gYW5pbWF0ZSBzY3JvbGwgb24gZWRnZXNcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiBwYXJhbXMucmVsZWFzZU9uRWRnZXMpIHtcclxuICAgICAgLy8gUmV0dXJuIHRydWUgdG8gYW5pbWF0ZSBzY3JvbGwgb24gZWRnZXNcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGhhbmRsZShldmVudCkge1xyXG4gICAgbGV0IGUgPSBldmVudDtcclxuICAgIGxldCBkaXNhYmxlUGFyZW50U3dpcGVyID0gdHJ1ZTtcclxuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcclxuXHJcbiAgICAvLyBJZ25vcmUgZXZlbnQgaWYgdGhlIHRhcmdldCBvciBpdHMgcGFyZW50cyBoYXZlIHRoZSBzd2lwZXItbm8tbW91c2V3aGVlbCBjbGFzc1xyXG4gICAgaWYgKGV2ZW50LnRhcmdldC5jbG9zZXN0KGAuJHtzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwubm9Nb3VzZXdoZWVsQ2xhc3N9YCkpIHJldHVybjtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMubW91c2V3aGVlbDtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfVxyXG4gICAgbGV0IHRhcmdldEVsID0gc3dpcGVyLmVsO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5ldmVudHNUYXJnZXQgIT09ICdjb250YWluZXInKSB7XHJcbiAgICAgIHRhcmdldEVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZXZlbnRzVGFyZ2V0KTtcclxuICAgIH1cclxuICAgIGNvbnN0IHRhcmdldEVsQ29udGFpbnNUYXJnZXQgPSB0YXJnZXRFbCAmJiB0YXJnZXRFbC5jb250YWlucyhlLnRhcmdldCk7XHJcbiAgICBpZiAoIXN3aXBlci5tb3VzZUVudGVyZWQgJiYgIXRhcmdldEVsQ29udGFpbnNUYXJnZXQgJiYgIXBhcmFtcy5yZWxlYXNlT25FZGdlcykgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAoZS5vcmlnaW5hbEV2ZW50KSBlID0gZS5vcmlnaW5hbEV2ZW50OyAvLyBqcXVlcnkgZml4XHJcbiAgICBsZXQgZGVsdGEgPSAwO1xyXG4gICAgY29uc3QgcnRsRmFjdG9yID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IC0xIDogMTtcclxuICAgIGNvbnN0IGRhdGEgPSBub3JtYWxpemUoZSk7XHJcbiAgICBpZiAocGFyYW1zLmZvcmNlVG9BeGlzKSB7XHJcbiAgICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcclxuICAgICAgICBpZiAoTWF0aC5hYnMoZGF0YS5waXhlbFgpID4gTWF0aC5hYnMoZGF0YS5waXhlbFkpKSBkZWx0YSA9IC1kYXRhLnBpeGVsWCAqIHJ0bEZhY3RvcjtcclxuICAgICAgICBlbHNlIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2UgaWYgKE1hdGguYWJzKGRhdGEucGl4ZWxZKSA+IE1hdGguYWJzKGRhdGEucGl4ZWxYKSkgZGVsdGEgPSAtZGF0YS5waXhlbFk7XHJcbiAgICAgIGVsc2UgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkZWx0YSA9IE1hdGguYWJzKGRhdGEucGl4ZWxYKSA+IE1hdGguYWJzKGRhdGEucGl4ZWxZKSA/IC1kYXRhLnBpeGVsWCAqIHJ0bEZhY3RvciA6IC1kYXRhLnBpeGVsWTtcclxuICAgIH1cclxuICAgIGlmIChkZWx0YSA9PT0gMCkgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAocGFyYW1zLmludmVydCkgZGVsdGEgPSAtZGVsdGE7XHJcblxyXG4gICAgLy8gR2V0IHRoZSBzY3JvbGwgcG9zaXRpb25zXHJcbiAgICBsZXQgcG9zaXRpb25zID0gc3dpcGVyLmdldFRyYW5zbGF0ZSgpICsgZGVsdGEgKiBwYXJhbXMuc2Vuc2l0aXZpdHk7XHJcbiAgICBpZiAocG9zaXRpb25zID49IHN3aXBlci5taW5UcmFuc2xhdGUoKSkgcG9zaXRpb25zID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xyXG4gICAgaWYgKHBvc2l0aW9ucyA8PSBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHBvc2l0aW9ucyA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcclxuXHJcbiAgICAvLyBXaGVuIGxvb3AgaXMgdHJ1ZTpcclxuICAgIC8vICAgICB0aGUgZGlzYWJsZVBhcmVudFN3aXBlciB3aWxsIGJlIHRydWUuXHJcbiAgICAvLyBXaGVuIGxvb3AgaXMgZmFsc2U6XHJcbiAgICAvLyAgICAgaWYgdGhlIHNjcm9sbCBwb3NpdGlvbnMgaXMgbm90IG9uIGVkZ2UsXHJcbiAgICAvLyAgICAgdGhlbiB0aGUgZGlzYWJsZVBhcmVudFN3aXBlciB3aWxsIGJlIHRydWUuXHJcbiAgICAvLyAgICAgaWYgdGhlIHNjcm9sbCBvbiBlZGdlIHBvc2l0aW9ucyxcclxuICAgIC8vICAgICB0aGVuIHRoZSBkaXNhYmxlUGFyZW50U3dpcGVyIHdpbGwgYmUgZmFsc2UuXHJcbiAgICBkaXNhYmxlUGFyZW50U3dpcGVyID0gc3dpcGVyLnBhcmFtcy5sb29wXHJcbiAgICAgID8gdHJ1ZVxyXG4gICAgICA6ICEocG9zaXRpb25zID09PSBzd2lwZXIubWluVHJhbnNsYXRlKCkgfHwgcG9zaXRpb25zID09PSBzd2lwZXIubWF4VHJhbnNsYXRlKCkpO1xyXG4gICAgaWYgKGRpc2FibGVQYXJlbnRTd2lwZXIgJiYgc3dpcGVyLnBhcmFtcy5uZXN0ZWQpIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuZnJlZU1vZGUgfHwgIXN3aXBlci5wYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCkge1xyXG4gICAgICAvLyBSZWdpc3RlciB0aGUgbmV3IGV2ZW50IGluIGEgdmFyaWFibGUgd2hpY2ggc3RvcmVzIHRoZSByZWxldmFudCBkYXRhXHJcbiAgICAgIGNvbnN0IG5ld0V2ZW50ID0ge1xyXG4gICAgICAgI
9266HRpbWU6IG5vdygpLFxyXG4gICAgICAgIGRlbHRhOiBNYXRoLmFicyhkZWx0YSksXHJcbiAgICAgICAgZGlyZWN0aW9uOiBNYXRoLnNpZ24oZGVsdGEpLFxyXG4gICAgICAgIHJhdzogZXZlbnQsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAvLyBLZWVwIHRoZSBtb3N0IHJlY2VudCBldmVudHNcclxuICAgICAgaWYgKHJlY2VudFdoZWVsRXZlbnRzLmxlbmd0aCA+PSAyKSB7XHJcbiAgICAgICAgcmVjZW50V2hlZWxFdmVudHMuc2hpZnQoKTsgLy8gb25seSBzdG9yZSB0aGUgbGFzdCBOIGV2ZW50c1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBwcmV2RXZlbnQgPSByZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPyByZWNlbnRXaGVlbEV2ZW50c1tyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcclxuICAgICAgcmVjZW50V2hlZWxFdmVudHMucHVzaChuZXdFdmVudCk7XHJcblxyXG4gICAgICAvLyBJZiB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJldmlvdXMgcmVjb3JkZWQgZXZlbnQ6XHJcbiAgICAgIC8vICAgSWYgZGlyZWN0aW9uIGhhcyBjaGFuZ2VkIG9yXHJcbiAgICAgIC8vICAgaWYgdGhlIHNjcm9sbCBpcyBxdWlja2VyIHRoYW4gdGhlIHByZXZpb3VzIG9uZTpcclxuICAgICAgLy8gICAgIEFuaW1hdGUgdGhlIHNsaWRlci5cclxuICAgICAgLy8gRWxzZSAodGhpcyBpcyB0aGUgZmlyc3QgdGltZSB0aGUgd2hlZWwgaXMgbW92ZWQpOlxyXG4gICAgICAvLyAgICAgQW5pbWF0ZSB0aGUgc2xpZGVyLlxyXG4gICAgICBpZiAocHJldkV2ZW50KSB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgbmV3RXZlbnQuZGlyZWN0aW9uICE9PSBwcmV2RXZlbnQuZGlyZWN0aW9uIHx8XHJcbiAgICAgICAgICBuZXdFdmVudC5kZWx0YSA+IHByZXZFdmVudC5kZWx0YSB8fFxyXG4gICAgICAgICAgbmV3RXZlbnQudGltZSA+IHByZXZFdmVudC50aW1lICsgMTUwXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBhbmltYXRlU2xpZGVyKG5ld0V2ZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgYW5pbWF0ZVNsaWRlcihuZXdFdmVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIElmIGl0J3MgdGltZSB0byByZWxlYXNlIHRoZSBzY3JvbGw6XHJcbiAgICAgIC8vICAgUmV0dXJuIG5vdyBzbyB5b3UgZG9uJ3QgaGl0IHRoZSBwcmV2ZW50RGVmYXVsdC5cclxuICAgICAgaWYgKHJlbGVhc2VTY3JvbGwobmV3RXZlbnQpKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIEZyZWVtb2RlIG9yIHNjcm9sbENvbnRhaW5lcjpcclxuXHJcbiAgICAgIC8vIElmIHdlIHJlY2VudGx5IHNuYXBwZWQgYWZ0ZXIgYSBtb21lbnR1bSBzY3JvbGwsIHRoZW4gaWdub3JlIHdoZWVsIGV2ZW50c1xyXG4gICAgICAvLyB0byBnaXZlIHRpbWUgZm9yIHRoZSBkZWNlbGVyYXRpb24gdG8gZmluaXNoLiBTdG9wIGlnbm9yaW5nIGFmdGVyIDUwMCBtc2Vjc1xyXG4gICAgICAvLyBvciBpZiBpdCdzIGEgbmV3IHNjcm9sbCAobGFyZ2VyIGRlbHRhIG9yIGludmVyc2Ugc2lnbiBhcyBsYXN0IGV2ZW50IGJlZm9yZVxyXG4gICAgICAvLyBhbiBlbmQtb2YtbW9tZW50dW0gc25hcCkuXHJcbiAgICAgIGNvbnN0IG5ld0V2ZW50ID0ge1xyXG4gICAgICAgIHRpbWU6IG5vdygpLFxyXG4gICAgICAgIGRlbHRhOiBNYXRoLmFicyhkZWx0YSksXHJcbiAgICAgICAgZGlyZWN0aW9uOiBNYXRoLnNpZ24oZGVsdGEpLFxyXG4gICAgICB9O1xyXG4gICAgICBjb25zdCBpZ25vcmVXaGVlbEV2ZW50cyA9XHJcbiAgICAgICAgbGFzdEV2ZW50QmVmb3JlU25hcCAmJlxyXG4gICAgICAgIG5ld0V2ZW50LnRpbWUgPCBsYXN0RXZlbnRCZWZvcmVTbmFwLnRpbWUgKyA1
9266MDAgJiZcclxuICAgICAgICBuZXdFdmVudC5kZWx0YSA8PSBsYXN0RXZlbnRCZWZvcmVTbmFwLmRlbHRhICYmXHJcbiAgICAgICAgbmV3RXZlbnQuZGlyZWN0aW9uID09PSBsYXN0RXZlbnRCZWZvcmVTbmFwLmRpcmVjdGlvbjtcclxuICAgICAgaWYgKCFpZ25vcmVXaGVlbEV2ZW50cykge1xyXG4gICAgICAgIGxhc3RFdmVudEJlZm9yZVNuYXAgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgbGV0IHBvc2l0aW9uID0gc3dpcGVyLmdldFRyYW5zbGF0ZSgpICsgZGVsdGEgKiBwYXJhbXMuc2Vuc2l0aXZpdHk7XHJcbiAgICAgICAgY29uc3Qgd2FzQmVnaW5uaW5nID0gc3dpcGVyLmlzQmVnaW5uaW5nO1xyXG4gICAgICAgIGNvbnN0IHdhc0VuZCA9IHN3aXBlci5pc0VuZDtcclxuICAgICAgICBpZiAocG9zaXRpb24gPj0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSBwb3NpdGlvbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKTtcclxuICAgICAgICBpZiAocG9zaXRpb24gPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSBwb3NpdGlvbiA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKTtcclxuICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcclxuICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHBvc2l0aW9uKTtcclxuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcclxuICAgICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcclxuICAgICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xyXG4gICAgICAgIGlmICgoIXdhc0JlZ2lubmluZyAmJiBzd2lwZXIuaXNCZWdpbm5pbmcpIHx8ICghd2FzRW5kICYmIHN3aXBlci5pc0VuZCkpIHtcclxuICAgICAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcclxuICAgICAgICAgIHN3aXBlci5sb29wRml4KHtcclxuICAgICAgICAgICAgZGlyZWN0aW9uOiBuZXdFdmVudC5kaXJlY3Rpb24gPCAwID8gJ25leHQnIDogJ3ByZXYnLFxyXG4gICAgICAgICAgICBieU1vdXNld2hlZWw6IHRydWUsXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XHJcbiAgICAgICAgICAvLyBXaGVuIHdoZWVsIHNjcm9sbGluZyBzdGFydHMgd2l0aCBzdGlja3kgKGFrYSBzbmFwKSBlbmFibGVkLCB0aGVuIGRldGVjdFxyXG4gICAgICAgICAgLy8gdGhlIGVuZCBvZiBhIG1vbWVudHVtIHNjcm9sbCBieSBzdG9yaW5nIHJlY2VudCAoTj0xNT8pIHdoZWVsIGV2ZW50cy5cclxuICAgICAgICAgIC8vIDEuIGRvIGFsbCBOIGV2ZW50cyBoYXZlIGRlY3JlYXNpbmcgb3Igc2FtZSAoYWJzb2x1dGUgdmFsdWUpIGRlbHRhP1xyXG4gICAgICAgICAgLy8gMi4gZGlkIGFsbCBOIGV2ZW50cyBhcnJpdmUgaW4gdGhlIGxhc3QgTSAoTT01MDA/KSBtc2Vjcz9cclxuICAgICAgICAgIC8vIDMuIGRvZXMgdGhlIGVhcmxpZXN0IGV2ZW50IGhhdmUgYW4gKGFic29sdXRlIHZhbHVlKSBkZWx0YSB0aGF0J3NcclxuICAgICAgICAgIC8vICAgIGF0IGxlYXN0IFAgKFA9MT8pIGxhcmdlciB0aGFuIHRoZSBtb3N0IHJlY2VudCBldmVudCdzIGRlbHRhP1xyXG4gICAgICAgICAgLy8gNC4gZG9lcyB0aGUgbGF0ZXN0IGV2ZW50IGhhdmUgYSBkZWx0YSB0aGF0J3Mgc21hbGxlciB0aGFuIFEgKFE9Nj8pIHBpeGVscz9cclxuICAgICAgICAgIC8vIElmIDEtNCBhcmUgXCJ5ZXNcIiB0aGVuIHdlJ3JlIG5lYXIgdGhlIGVuZCBvZiBhIG1vbWVudHVtIHNjcm9sbCBkZWNlbGVyYXRpb24uXHJcbiAgICAgICAgICAvLyBTbmFwIGltbWVkaWF0ZWx5IGFuZCBpZ25vcmUgcmVtYWluaW5nIHdoZWVsIGV2ZW50cyBpbiB0aGlzIHNjcm9sbC5cclxuICAgICAgICAgIC8vIFNlZSBjb21tZW50IGFib3ZlIGZvciBcInJlbWFpbmluZyB3aGVlbCBldmVudHMgaW4gdGhpcyBzY3JvbGxcIiBkZXRlcm1pbmF0aW9uLlxyXG4gICAgICAgICAgLy8gSWYgMS00IGFyZW4ndCBzYXRpc2ZpZWQsIHRoZW4gd2FpdCB0byBzbmFwIHVudGlsIDUwMG1zIGFmdGVyIHRoZSBsYXN0IGV2ZW50LlxyXG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xyXG4gICAgICAgICAgdGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIGlmIChyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPj0gMTUpIHtcclxuICAgICAgICAgICAgcmVjZW50V2hlZWxFdmVudHMuc2hpZnQoKTsgLy8gb25seSBzdG9yZSB0aGUgbGFzdCBOIGV2ZW50c1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHJlY2VudFdoZWVsRXZlbnRzLmxlbmd0aCA/IHJlY2VudFdoZWVsRXZlbnRzW3JlY2VudFdoZWVsRXZlbnRzLmxlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xyXG4gICAgICAgICAgY29uc3QgZmlyc3RFdmVudCA9IHJlY2VudFdoZWVsRXZlbnRzWzBdO1xyXG4gICAgICAgICAgcmVjZW50V2hlZWxFdmVudHMucHVzaChuZXdFdmVudCk7XHJcbiAgICAgICAgICBpZiAocHJldkV2ZW50ICYmIChuZXdFdmVudC5kZWx0YSA+IHByZXZFdmVudC5kZWx0YSB8fCBuZXdFdmVudC5kaXJlY3Rpb24gIT09IHByZXZFdmVudC5kaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgICAgIC8vIEluY3JlYXNpbmcgb3IgcmV2ZXJzZS1zaWduIGRlbHRhIG1lYW5zIHRoZSB1c2VyIHN0YXJ0ZWQgc2Nyb2xsaW5nIGFnYWluLiBDbGVhciB0aGUgd2hlZWwgZXZlbnQgbG9nLlxyXG4gICAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50cy5zcGxpY2UoMCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPj0gMTUgJiZcclxuICAgICAgICAgICAgbmV3RXZlbnQudGltZSAtIGZpcnN0RXZlbnQudGltZSA8IDUwMCAmJlxyXG4gICAgICAgICAgICBmaXJzdEV2ZW50LmRlbHRhIC0gbmV3RXZlbnQuZGVsdGEgPj0gMSAmJlxyXG4gICAgICAgICAgICBuZXdFdmVudC5kZWx0YSA8PSA2XHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgLy8gV2UncmUgYXQgdGhlIGVuZCBvZiB0aGUgZGVjZWxlcmF0aW9uIG9mIGEgbW9tZW50dW0gc2Nyb2xsLCBzbyB0aGVyZSdzIG5vIG5lZWRcclxuICAgICAgICAgICAgLy8gdG8gd2FpdCBmb3IgbW9yZSBldmVudHMuIFNuYXAgQVNBUCBvbiB0aGUgbmV4dCB0aWNrLlxyXG4gICAgICAgICAgICAvLyBBbHNvLCBiZWNhdXNlIHRoZXJlJ3Mgc29tZSByZW1haW5pbmcgbW9tZW50dW0gd2UnbGwgYmlhcyB0aGUgc25hcCBpbiB0aG
9266VcclxuICAgICAgICAgICAgLy8gZGlyZWN0aW9uIG9mIHRoZSBvbmdvaW5nIHNjcm9sbCBiZWNhdXNlIGl0J3MgYmV0dGVyIFVYIGZvciB0aGUgc2Nyb2xsIHRvIHNuYXBcclxuICAgICAgICAgICAgLy8gaW4gdGhlIHNhbWUgZGlyZWN0aW9uIGFzIHRoZSBzY3JvbGwgaW5zdGVhZCBvZiByZXZlcnNpbmcgdG8gc25hcC4gIFRoZXJlZm9yZSxcclxuICAgICAgICAgICAgLy8gaWYgaXQncyBhbHJlYWR5IHNjcm9sbGVkIG1vcmUgdGhhbiAyMCUgaW4gdGhlIGN1cnJlbnQgZGlyZWN0aW9uLCBrZWVwIGdvaW5nLlxyXG4gICAgICAgICAgICBjb25zdCBzbmFwVG9UaHJlc2hvbGQgPSBkZWx0YSA+IDAgPyAwLjggOiAwLjI7XHJcbiAgICAgICAgICAgIGxhc3RFdmVudEJlZm9yZVNuYXAgPSBuZXdFdmVudDtcclxuICAgICAgICAgICAgcmVjZW50V2hlZWxFdmVudHMuc3BsaWNlKDApO1xyXG4gICAgICAgICAgICB0aW1lb3V0ID0gbmV4dFRpY2soKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdChzd2lwZXIucGFyYW1zLnNwZWVkLCB0cnVlLCB1bmRlZmluZWQsIHNuYXBUb1RocmVzaG9sZCk7XHJcbiAgICAgICAgICAgIH0sIDApOyAvLyBubyBkZWxheTsgbW92ZSBvbiBuZXh0IHRpY2tcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoIXRpbWVvdXQpIHtcclxuICAgICAgICAgICAgLy8gaWYgd2UgZ2V0IGhlcmUsIHRoZW4gd2UgaGF2ZW4ndCBkZXRlY3RlZCB0aGUgZW5kIG9mIGEgbW9tZW50dW0gc2Nyb2xsLCBzb1xyXG4gICAgICAgICAgICAvLyB3ZSdsbCBjb25zaWRlciBhIHNjcm9sbCBcImNvbXBsZXRlXCIgd2hlbiB0aGVyZSBoYXZlbid0IGJlZW4gYW55IHdoZWVsIGV2ZW50c1xyXG4gICAgICAgICAgICAvLyBmb3IgNTAwbXMuXHJcbiAgICAgICAgICAgIHRpbWVvdXQgPSBuZXh0VGljaygoKSA9PiB7XHJcbiAgICAgICAgICAgICAgY29uc3Qgc25hcFRvVGhyZXNob2xkID0gMC41O1xyXG4gICAgICAgICAgICAgIGxhc3RFdmVudEJlZm9yZVNuYXAgPSBuZXdFdmVudDtcclxuICAgICAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50cy5zcGxpY2UoMCk7XHJcbiAgICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG9DbG9zZXN0KHN3aXBlci5wYXJhbXMuc3BlZWQsIHRydWUsIHVuZGVmaW5lZCwgc25hcFRvVGhyZXNob2xkKTtcclxuICAgICAgICAgICAgfSwgNTAwKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEVtaXQgZXZlbnRcclxuICAgICAgICBpZiAoIWlnbm9yZVdoZWVsRXZlbnRzKSBlbWl0KCdzY3JvbGwnLCBlKTtcclxuXHJcbiAgICAgICAgLy8gU3RvcCBhdXRvcGxheVxyXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9wbGF5ICYmIHN3aXBlci5wYXJhbXMuYXV0b3BsYXlEaXNhYmxlT25JbnRlcmFjdGlvbikgc3dpcGVyLmF1dG9wbGF5LnN0b3AoKTtcclxuICAgICAgICAvLyBSZXR1cm4gcGFnZSBzY3JvbGwgb24gZWRnZSBwb3NpdGlvbnNcclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IHN3aXBlci5taW5UcmFuc2xhdGUoKSB8fCBwb3NpdGlvbiA9PT0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIGVsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICBmdW5jdGlvbiBldmVudHMobWV0aG9kKSB7XHJcbiAgICBsZXQgdGFyZ2V0RWwgPSBzd2lwZXIuZWw7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmV2ZW50c1RhcmdldCAhPT0gJ2NvbnRhaW5lcicpIHtcclxuICAgICAgdGFyZ2V0RWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5ldmVudHNUYXJnZXQpO1xyXG4gICAgfVxyXG4gICAgdGFyZ2V0RWxbbWV0aG9kXSgnbW91c2VlbnRlcicsIGhhbmRsZU1vdXNlRW50ZXIpO1xyXG4gICAgdGFyZ2V0RWxbbWV0aG9kXSgnbW91c2VsZWF2ZScsIGhhbmRsZU1vdXNlTGVhdmUpO1xyXG4gICAgdGFyZ2V0RWxbbWV0aG9kXSgnd2hlZWwnLCBoYW5kbGUpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBlbmFibGUoKSB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBoYW5kbGUpO1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkKSByZXR1cm4gZmFsc2U7XHJcbiAgICBldmVudHMoJ2FkZEV2ZW50TGlzdGVuZXInKTtcclxuICAgIHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQgPSB0cnVlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGRpc2FibGUoKSB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlKTtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAoIXN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQpIHJldHVybiBmYWxzZTtcclxuICAgIGV2ZW50cygncmVtb3ZlRXZlbnRMaXN0ZW5lcicpO1xyXG4gICAgc3dpcGVyLm1vdXNld2hlZWwuZW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG4gIG9uKCdpbml0JywgKCkgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZW5hYmxlZCAmJiBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgZGlzYWJsZSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5lbmFibGVkKSBlbmFibGUoKTtcclxuICB9KTtcclxuICBvbignZGVzdHJveScsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgZW5hYmxlKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoc3dpcGVyLm1vdXNld2hlZWwuZW5hYmxlZCkgZGlzYWJsZSgpO1xyXG4gIH0pO1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLm1vdXNld2hlZWwsIHtcclxuICAgIGVuYWJsZSxcclxuICAgIGRpc2FibGUsXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRJZk5vdERlZmluZWQoc3dpcGVyLCBvcmlnaW5hbFBhcmFtcywgcGFyYW1zLCBjaGVja1Byb3BzKSB7XHJcbiAgaWYgKHN3aXBlci5wYXJhbXMuY3JlYXRlRWxlbWVudHMpIHtcclxuICAgIE9iamVjdC5rZXlzKGNoZWNrUHJvcHMpLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgICBpZiAoIXBhcmFtc1trZXldICYmIHBhcmFtcy5hdXRvID09PSB0cnVlKSB7XHJcbiAgICAgICAgbGV0IGVsZW1lbnQgPSBlbGVtZW50Q2hpbGRyZW4oc3dpcGVyLmVsLCBgLiR7Y2hlY2tQcm9wc1trZXldfWApWzBdO1xyXG4gICAgICAgIGlmICghZWxlbWVudCkge1xyXG4gICAgICAgICAgZWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIGNoZWNrUHJvcHNba2V5XSk7XHJcbiAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9IGNoZWNrUHJvcHNba2V5XTtcclxuICAgICAgICAgI
9266HN3aXBlci5lbC5hcHBlbmQoZWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHBhcmFtc1trZXldID0gZWxlbWVudDtcclxuICAgICAgICBvcmlnaW5hbFBhcmFtc1trZXldID0gZWxlbWVudDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBwYXJhbXM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIE5hdmlnYXRpb24oX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiwgZW1pdCB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgbmF2aWdhdGlvbjoge1xyXG4gICAgICBuZXh0RWw6IG51bGwsXHJcbiAgICAgIHByZXZFbDogbnVsbCxcclxuICAgICAgaGlkZU9uQ2xpY2s6IGZhbHNlLFxyXG4gICAgICBkaXNhYmxlZENsYXNzOiAnc3dpcGVyLWJ1dHRvbi1kaXNhYmxlZCcsXHJcbiAgICAgIGhpZGRlbkNsYXNzOiAnc3dpcGVyLWJ1dHRvbi1oaWRkZW4nLFxyXG4gICAgICBsb2NrQ2xhc3M6ICdzd2lwZXItYnV0dG9uLWxvY2snLFxyXG4gICAgICBuYXZpZ2F0aW9uRGlzYWJsZWRDbGFzczogJ3N3aXBlci1uYXZpZ2F0aW9uLWRpc2FibGVkJyxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgc3dpcGVyLm5hdmlnYXRpb24gPSB7XHJcbiAgICBuZXh0RWw6IG51bGwsXHJcbiAgICBwcmV2RWw6IG51bGwsXHJcbiAgfTtcclxuICBjb25zdCBtYWtlRWxlbWVudHNBcnJheSA9IChlbCkgPT4ge1xyXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGVsKSkgZWwgPSBbZWxdLmZpbHRlcigoZSkgPT4gISFlKTtcclxuICAgIHJldHVybiBlbDtcclxuICB9O1xyXG4gIGZ1bmN0aW9uIGdldEVsKGVsKSB7XHJcbiAgICBsZXQgcmVzO1xyXG4gICAgaWYgKGVsICYmIHR5cGVvZiBlbCA9PT0gJ3N0cmluZycgJiYgc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgICByZXMgPSBzd2lwZXIuZWwuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKGVsKTtcclxuICAgICAgaWYgKHJlcykgcmV0dXJuIHJlcztcclxuICAgIH1cclxuICAgIGlmIChlbCkge1xyXG4gICAgICBpZiAodHlwZW9mIGVsID09PSAnc3RyaW5nJykgcmVzID0gWy4uLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWwpXTtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHN3aXBlci5wYXJhbXMudW5pcXVlTmF2RWxlbWVudHMgJiZcclxuICAgICAgICB0eXBlb2YgZWwgPT09ICdzdHJpbmcnICYmXHJcbiAgICAgICAgcmVzLmxlbmd0aCA+IDEgJiZcclxuICAgICAgICBzd2lwZXIuZWwucXVlcnlTZWxlY3RvckFsbChlbCkubGVuZ3RoID09PSAxXHJcbiAgICAgICkge1xyXG4gICAgICAgIHJlcyA9IHN3aXBlci5lbC5xdWVyeVNlbGVjdG9yKGVsKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGVsICYmICFyZXMpIHJldHVybiBlbDtcclxuICAgIC8vIGlmIChBcnJheS5pc0FycmF5KHJlcykgJiYgcmVzLmxlbmd0aCA9PT0gMSkgcmVzID0gcmVzWzBdO1xyXG4gICAgcmV0dXJuIHJlcztcclxuICB9XHJcbiAgZnVuY3Rpb24gdG9nZ2xlRWwoZWwsIGRpc2FibGVkKSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb247XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIGlmIChzdWJFbCkge1xyXG4gICAgICAgIHN1YkVsLmNsYXNzTGlzdFtkaXNhYmxlZCA/ICdhZGQnIDogJ3JlbW92ZSddKC4uLnBhcmFtcy5kaXNhYmxlZENsYXNzLnNwbGl0KCcgJykpO1xyXG4gICAgICAgIGlmIChzdWJFbC50YWdOYW1lID09PSAnQlVUVE9OJykgc3ViRWwuZGlzYWJsZWQgPSBkaXNhYmxlZDtcclxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5lbmFibGVkKSB7XHJcbiAgICAgICAgICBzdWJFbC5jbGFzc0xpc3Rbc3dpcGVyLmlzTG9ja2VkID8gJ2FkZCcgOiAncmVtb3ZlJ10ocGFyYW1zLmxvY2tDbGFzcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gdXBkYXRlKCkge1xyXG4gICAgLy8gVXBkYXRlIE5hdmlnYXRpb24gQnV0dG9uc1xyXG4gICAgY29uc3QgeyBuZXh0RWwsIHByZXZFbCB9ID0gc3dpcGVyLm5hdmlnYXRpb247XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XHJcbiAgICAgIHRvZ2dsZUVsKHByZXZFbCwgZmFsc2UpO1xyXG4gICAgICB0b2dnbGVFbChuZXh0RWwsIGZhbHNlKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdG9nZ2xlRWwocHJldkVsLCBzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMucmV3aW5kKTtcclxuICAgIHRvZ2dsZUVsKG5leHRFbCwgc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLnJld2luZCk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIG9uUHJldkNsaWNrKGUpIHtcclxuICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiAhc3dpcGVyLnBhcmFtcy5yZXdpbmQpIHJldHVybjtcclxuICAgIHN3aXBlci5zbGlkZVByZXYoKTtcclxuICAgIGVtaXQoJ25hdmlnYXRpb25QcmV2Jyk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIG9uTmV4dENsaWNrKGUpIHtcclxuICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIGlmIChzd2lwZXIuaXNFbmQgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiAhc3dpcGVyLnBhcmFtcy5yZXdpbmQpIHJldHVybjtcclxuICAgIHN3aXBlci5zbGlkZU5leHQoKTtcclxuICAgIGVtaXQoJ25hdmlnYXRpb25OZXh0Jyk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGluaXQoKSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb247XHJcbiAgICBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24gPSBjcmVhdGVFbGVtZW50SWZOb3REZWZpbmVkKFxyXG4gICAgICBzd2lwZXIsXHJcbiAgICAgIHN3aXBlci5vcmlnaW5hbFBhcmFtcy5uYXZpZ2F0aW9uLFxyXG4gICAgICBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24sXHJcbiAgICAgIHtcclxuICAgICAgICBuZXh0RWw6ICdzd2lwZXItYnV0dG9uLW5leHQnLFxyXG4gICAgICAgI
9266HByZXZFbDogJ3N3aXBlci1idXR0b24tcHJldicsXHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgICBpZiAoIShwYXJhbXMubmV4dEVsIHx8IHBhcmFtcy5wcmV2RWwpKSByZXR1cm47XHJcbiAgICBsZXQgbmV4dEVsID0gZ2V0RWwocGFyYW1zLm5leHRFbCk7XHJcbiAgICBsZXQgcHJldkVsID0gZ2V0RWwocGFyYW1zLnByZXZFbCk7XHJcbiAgICBPYmplY3QuYXNzaWduKHN3aXBlci5uYXZpZ2F0aW9uLCB7XHJcbiAgICAgIG5leHRFbCxcclxuICAgICAgcHJldkVsLFxyXG4gICAgfSk7XHJcbiAgICBuZXh0RWwgPSBtYWtlRWxlbWVudHNBcnJheShuZXh0RWwpO1xyXG4gICAgcHJldkVsID0gbWFrZUVsZW1lbnRzQXJyYXkocHJldkVsKTtcclxuICAgIGNvbnN0IGluaXRCdXR0b24gPSAoZWwsIGRpcikgPT4ge1xyXG4gICAgICBpZiAoZWwpIHtcclxuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGRpciA9PT0gJ25leHQnID8gb25OZXh0Q2xpY2sgOiBvblByZXZDbGljayk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFzd2lwZXIuZW5hYmxlZCAmJiBlbCkge1xyXG4gICAgICAgIGVsLmNsYXNzTGlzdC5hZGQoLi4ucGFyYW1zLmxvY2tDbGFzcy5zcGxpdCgnICcpKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICAgIG5leHRFbC5mb3JFYWNoKChlbCkgPT4gaW5pdEJ1dHRvbihlbCwgJ25leHQnKSk7XHJcbiAgICBwcmV2RWwuZm9yRWFjaCgoZWwpID0+IGluaXRCdXR0b24oZWwsICdwcmV2JykpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBkZXN0cm95KCkge1xyXG4gICAgbGV0IHsgbmV4dEVsLCBwcmV2RWwgfSA9IHN3aXBlci5uYXZpZ2F0aW9uO1xyXG4gICAgbmV4dEVsID0gbWFrZUVsZW1lbnRzQXJyYXkobmV4dEVsKTtcclxuICAgIHByZXZFbCA9IG1ha2VFbGVtZW50c0FycmF5KHByZXZFbCk7XHJcbiAgICBjb25zdCBkZXN0cm95QnV0dG9uID0gKGVsLCBkaXIpID0+IHtcclxuICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBkaXIgPT09ICduZXh0JyA/IG9uTmV4dENsaWNrIDogb25QcmV2Q2xpY2spO1xyXG4gICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKC4uLnN3aXBlci5wYXJhbXMubmF2aWdhdGlvbi5kaXNhYmxlZENsYXNzLnNwbGl0KCcgJykpO1xyXG4gICAgfTtcclxuICAgIG5leHRFbC5mb3JFYWNoKChlbCkgPT4gZGVzdHJveUJ1dHRvbihlbCwgJ25leHQnKSk7XHJcbiAgICBwcmV2RWwuZm9yRWFjaCgoZWwpID0+IGRlc3Ryb3lCdXR0b24oZWwsICdwcmV2JykpO1xyXG4gIH1cclxuICBvbignaW5pdCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uZW5hYmxlZCA9PT0gZmFsc2UpIHtcclxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICAgIGRpc2FibGUoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGluaXQoKTtcclxuICAgICAgdXBkYXRlKCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ3RvRWRnZSBmcm9tRWRnZSBsb2NrIHVubG9jaycsICgpID0+IHtcclxuICAgIHVwZGF0ZSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgZGVzdHJveSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdlbmFibGUgZGlzYWJsZScsICgpID0+IHtcclxuICAgIGxldCB7IG5leHRFbCwgcHJldkVsIH0gPSBzd2lwZXIubmF2aWdhdGlvbjtcclxuICAgIG5leHRFbCA9IG1ha2VFbGVtZW50c0FycmF5KG5leHRFbCk7XHJcbiAgICBwcmV2RWwgPSBtYWtlRWxlbWVudHNBcnJheShwcmV2RWwpO1xyXG4gICAgWy4uLm5leHRFbCwgLi4ucHJldkVsXVxyXG4gICAgICAuZmlsdGVyKChlbCkgPT4gISFlbClcclxuICAgICAgLmZvckVhY2goKGVsKSA9PiBlbC5jbGFzc0xpc3Rbc3dpcGVyLmVuYWJsZWQgPyAncmVtb3ZlJyA6ICdhZGQnXShzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24ubG9ja0NsYXNzKSk7XHJcbiAgfSk7XHJcbiAgb24oJ2NsaWNrJywgKF9zLCBlKSA9PiB7XHJcbiAgICBsZXQgeyBuZXh0RWwsIHByZXZFbCB9ID0gc3dpcGVyLm5hdmlnYXRpb247XHJcbiAgICBuZXh0RWwgPSBtYWtlRWxlbWVudHNBcnJheShuZXh0RWwpO1xyXG4gICAgcHJldkVsID0gbWFrZUVsZW1lbnRzQXJyYXkocHJldkVsKTtcclxuICAgIGNvbnN0IHRhcmdldEVsID0gZS50YXJnZXQ7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGVPbkNsaWNrICYmICFwcmV2RWwuaW5jbHVkZXModGFyZ2V0RWwpICYmICFuZXh0RWwuaW5jbHVkZXModGFyZ2V0RWwpKSB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICBzd2lwZXIucGFnaW5hdGlvbiAmJlxyXG4gICAgICAgIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbiAmJlxyXG4gICAgICAgIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5jbGlja2FibGUgJiZcclxuICAgICAgICAoc3dpcGVyLnBhZ2luYXRpb24uZWwgPT09IHRhcmdldEVsIHx8IHN3aXBlci5wYWdpbmF0aW9uLmVsLmNvbnRhaW5zKHRhcmdldEVsKSlcclxuICAgICAgKVxyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgbGV0IGlzSGlkZGVuO1xyXG4gICAgICBpZiAobmV4dEVsLmxlbmd0aCkge1xyXG4gICAgICAgIGlzSGlkZGVuID0gbmV4dEVsWzBdLmNsYXNzTGlzdC5jb250YWlucyhzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uaGlkZGVuQ2xhc3MpO1xyXG4gICAgICB9IGVsc2UgaWYgKHByZXZFbC5sZW5ndGgpIHtcclxuICAgICAgICBpc0hpZGRlbiA9IHByZXZFbFswXS5jbGFzc0xpc3QuY29udGFpbnMoc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGRlbkNsYXNzKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoaXNIaWRkZW4gPT09IHRydWUpIHtcclxuICAgICAgICBlbWl0KCduYXZpZ2F0aW9uU2hvdycpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVtaXQoJ25hdmlnYXRpb25IaWRlJyk7XHJcbiAgICAgIH1cclxuICAgICAgWy4uLm5leHRFbCwgLi4ucHJldkVsXVxyXG4gICAgICAgIC5maWx0ZXIoKGVsKSA9PiAhIWVsKVxyXG4gICAgICAgIC5mb3JFYWNoKChlbCkgPT4gZWwuY2xhc3NMaXN0LnRvZ2dsZShzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uaGlkZGVuQ2xhc3MpKTtcclxuICAgIH1cclxuICB9KTtcclxuICBjb25zdCBlbmFibGUgPSAoKSA9PiB7XHJcbiAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LnJlbW92ZSguLi5zd2lwZXIucGFyYW1zLm5hdmlnYXRpb24ubmF2aWdhdGlvbkRpc2FibGVkQ2xhc3Muc3BsaXQoJyAnKSk7XHJcbiAgICBpbml0KCk7XHJcbiAgICB1cGRhdGUoKTtcclxuICB9O1xyXG4gIGNvbnN0IGRpc2FibGUgPSAoKSA9PiB7XHJcbiAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LmFkZCguLi5zd2lwZXIucGFyYW1zLm5hdmlnYXRpb24ubmF2aWdhdGlvbkRpc2FibGVkQ2xhc3Muc3BsaXQoJyAnKSk7XHJcbiAgICBkZXN0cm95KCk7XHJcbiAgfTtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlci5uYXZpZ2F0aW9uLCB7XHJcbiAgICBlbmFibGUsXHJcbiAgICBkaXNhYmxlLFxyXG4gICAgdXBkYXRlLFxyXG4gICAgaW5pdCxcclxuICAgIGRlc3Ryb3ksXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNsYXNzZXNUb1NlbGVjdG9yKGNsYXNzZXMpIHtcclxuICBpZiAoY2xhc3NlcyA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICBjbGFzc2VzID0gJyc7XHJcbiAgfVxyXG4gIHJldHVybiBgLiR7Y2xhc3Nlc1xyXG4gICAgLnRyaW0oKVxyXG4gICAgLnJlcGxhY2UoLyhbXFwuOiErXFwvXSkvZywgJ1xcXFwkMScpIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcclxuICAgIC5yZXBsYWNlKC8gL2csICcuJyl9YDtcclxufVxyXG5cclxuZnVuY3Rpb24gUGFnaW5hdGlvbihfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uLCBlbWl0IH0gPSBfcmVmO1xyXG4gIGNvbnN0IHBmeCA9ICdzd2lwZXItcGFnaW5hdGlvbic7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIHBhZ2luYXRpb246IHtcclxuICAgICAgZWw6IG51bGwsXHJcbiAgICAgIGJ1bGxldEVsZW1lbnQ6ICdzcGFuJyxcclxuICAgICAgY2xpY2thYmxlOiBmYWxzZSxcclxuICAgICAgaGlkZU9uQ2xpY2s6IGZhbHNlLFxyXG4gICAgICByZW5kZXJCdWxsZXQ6IG51bGwsXHJcbiAgICAgIHJlbmRlclByb2dyZXNzYmFyOiBudWxsLFxyXG4gICAgICByZW5kZXJGcmFjdGlvbjogbnVsbCxcclxuICAgICAgcmVuZGVyQ3VzdG9tOiBudWxsLFxyXG4gICAgICBwcm9ncmVzc2Jhck9wcG9zaXRlOiBmYWxzZSxcclxuICAgICAgdHlwZTogJ2J1bGxldHMnLFxyXG4gICAgICAvLyAnYnVsbGV0cycgb3IgJ3Byb2dyZXNzYmFyJyBvciAnZnJhY3Rpb24nIG9yICdjdXN0b20nXHJcbiAgICAgIGR5bmFtaWNCdWxsZXRzOiBmYWxzZSxcclxuICAgICAgZHluYW1pY01haW5CdWxsZXRzOiAxLFxyXG4gICAgICBmb3JtYXRGcmFjdGlvbkN1cnJlbnQ6IChudW1iZXIpID0+IG51bWJlcixcclxuICAgICAgZm9ybWF0RnJhY3Rpb25Ub3RhbDogKG51bWJlcikgPT4gbnVtYmVyLFxyXG4gICAgICBidWxsZXRDbGFzczogYCR7cGZ4fS1idWxsZXRgLFxyXG4gICAgICBidWxsZXRBY3RpdmVDbGFzczogYCR7cGZ4fS1idWxsZXQtYWN0aXZlYCxcclxuICAgICAgbW9kaWZpZXJDbGFzczogYCR7cGZ4fS1gLFxyXG4gICAgICBjdXJyZW50Q2xhc3M6IGAke3BmeH0tY3VycmVudGAsXHJcbiAgICAgIHRvdGFsQ2xhc3M6IGAke3BmeH0tdG90YWxgLFxyXG4gICAgICBoaWRkZW5DbGFzczogYCR7cGZ4fS1oaWRkZW5gLFxyXG4gICAgICBwcm9ncmVzc2JhckZpbGxDbGFzczogYCR7cGZ4fS1wcm9ncmVzc2Jhci1maWxsYCxcclxuICAgICAgcHJvZ3Jlc3NiYXJPcHBvc2l0ZUNsYXNzOiBgJHtwZnh9LXByb2dyZXNzYmFyLW9wcG9zaXRlYCxcclxuICAgICAgY2xpY2thYmxlQ2xhc3M6IGAke3BmeH0tY2xpY2thYmxlYCxcclxuICAgICAgbG9ja0NsYXNzOiBgJHtwZnh9LWxvY2tgLFxyXG4gICAgICBob3Jpem9udGFsQ2xhc3M6IGAke3BmeH0taG9yaXpvbnRhbGAsXHJcbiAgICAgIHZlcnRpY2FsQ2xhc3M6IGAke3BmeH0tdmVydGljYWxgLFxyXG4gICAgICBwYWdpbmF0aW9uRGlzYWJsZWRDbGFzczogYCR7cGZ4fS1kaXNhYmxlZGAsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIHN3aXBlci5wYWdpbmF0aW9uID0ge1xyXG4gICAgZWw6IG51bGwsXHJcbiAgICBidWxsZXRzOiBbXSxcclxuICB9O1xyXG4gIGxldCBidWxsZXRTaXplO1xyXG4gIGxldCBkeW5hbWljQnVsbGV0SW5kZXggPSAwO1xyXG4gIGNvbnN0IG1ha2VFbGVtZW50c0FycmF5ID0gKGVsKSA9PiB7XHJcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZWwpKSBlbCA9IFtlbF0uZmlsdGVyKChlKSA9PiAhIWUpO1xyXG4gICAgcmV0dXJuIGVsO1xyXG4gIH07XHJcbiAgZnVuY3Rpb24gaXNQYWdpbmF0aW9uRGlzYWJsZWQoKSB7XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICAhc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmVsIHx8XHJcbiAgICAgICFzd2lwZXIucGFnaW5hdGlvbi5lbCB8fFxyXG4gICAgICAoQXJyYXkuaXNBcnJheShzd2lwZXIucGFnaW5hdGlvbi5lbCkgJiYgc3dpcGVyLnBhZ2luYXRpb24uZWwubGVuZ3RoID09PSAwKVxyXG4gICAgKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gc2V0U2lkZUJ1bGxldHMoYnVsbGV0RWwsIHBvc2l0aW9uKSB7XHJcbiAgICBjb25zdCB7IGJ1bGxldEFjdGl2ZUNsYXNzIH0gPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XHJcbiAgICBpZiAoIWJ1bGxldEVsKSByZXR1cm47XHJcbiAgICBidWxsZXRFbCA9IGJ1bGxldEVsW2Ake3Bvc2l0aW9uID09PSAncHJldicgPyAncHJldmlvdXMnIDogJ25leHQnfUVsZW1lbnRTaWJsaW5nYF07XHJcbiAgICBpZiAoYnVsbGV0RWwpIHtcclxuICAgICAgYnVsbGV0RWwuY2xhc3NMaXN0LmFkZChgJHtidWxsZXRBY3RpdmVDbGFzc30tJHtwb3NpdGlvbn1gKTtcclxuICAgICAgYnVsbGV0RWwgPSBidWxsZXRFbFtgJHtwb3NpdGlvbiA9PT0gJ3ByZXYnID8gJ3ByZXZpb3VzJyA6ICduZXh0J31FbGVtZW50U2libGluZ2BdO1xyXG4gICAgICBpZiAoYnVsbGV0RWwpIHtcclxuICAgICAgICBidWxsZXRFbC5jbGFzc0xpc3QuYWRkKGAke2J1bGxldEFjdGl2ZUNsYXNzfS0ke3Bvc2l0aW9ufS0ke3Bvc2l0aW9ufWApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIG9uQnVsbGV0Q2xpY2soZSkge1xyXG4gICAgY29uc3QgYnVsbGV0RWwgPSBlLnRhcmdldC5jbG9zZXN0KGNsYXNzZXNUb1NlbGVjdG9yKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5idWxsZXRDbGFzcykpO1xyXG4gICAgaWYgKCFidWxsZXRFbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICBjb25zdCBpbmRleCA9IGVsZW1lbnRJbmRleChidWxsZXRFbCkgKiBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xyXG4gICAgICBpZiAoc3dpcGVyLnJlYWxJbmRleCA9PT0gaW5kZXgpIHJldHVybjtcclxuICAgICAgY29uc3QgbmV3U2xpZGVJbmRleCA9IHN3aXBlci5nZXRTbGlkZUluZGV4QnlEYXRhKGluZGV4KTtcclxuICAgICAgY29uc3QgY3VycmVudFNsaWRlSW5kZXggPSBzd2lwZXIuZ2V0U2xpZGVJbmRleEJ5RGF0YShzd2lwZXIucmVhbEluZGV4KTtcclxuICAgICAgaWYgKG5ld1NsaWRlSW5kZXggPiBzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIHN3aXBlci5sb29wZWRTbGlkZXMpIHtcclxuICAgICAgICBzd2lwZXIubG9vcEZpeCh7XHJcbiAgICAgICAgICBkaXJlY3Rpb246IG5ld1NsaWRlSW5kZXggPiBjdXJyZW50U2xpZGVJbmRleCA/ICduZXh0JyA6ICdwcmV2JyxcclxuICAgICAgICAgIGFjdGl2ZVNsaWRlSW5kZXg6IG5ld1NsaWRlSW5kZXgsXHJcbiAgICAgICAgICBzbGlkZVRvOiBmYWxzZSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgICBzd2lwZXIuc2xpZGVUb0xvb3AoaW5kZXgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oaW5kZXgpO1xyXG4gICAgfVxyXG4gIH1cclxuICBmdW5jdGlvbiB1cGRhdGUoKSB7XHJcbiAgICAvLyBSZW5kZXIgfHwgVXBkYXRlIFBhZ2luYXRpb24gYnVsbGV0cy9pdGVtc1xyXG4gICAgY29uc3QgcnRsID0gc3dpcGVyLnJ0bDtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbjtcclxuICAgIGlmIChpc1BhZ2luYXRpb25EaXNhYmxlZCgpKSByZXR1cm47XHJcbiAgICBsZXQgZWwgPSBzd2lwZXIucGFnaW5hdGlvbi5lbDtcclxuICAgIGVsID0gbWFrZUVsZW1lbnRzQXJyYXkoZWwpO1xyXG4gICAgLy8gQ3VycmVudC9Ub3RhbFxyXG4gICAgbGV0IGN1cnJlbnQ7XHJcbiAgICBsZXQgcHJldmlvdXNJbmRleDtcclxuICAgIGNvbnN0IHNsaWRlc0xlbmd0aCA9XHJcbiAgICAgIHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xyXG4gICAgY29uc3QgdG90YWwgPSBzd2lwZXIucGFyYW1zLmxvb3AgPyBNYXRoLmNlaWwoc2xpZGVzTGVuZ3RoIC8gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCkgOiBzd2lwZXIuc25hcEdyaWQubGVuZ3RoO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xyXG4gICAgICBwcmV2aW91c0luZGV4ID0gc3dpcGVyLnByZXZpb3VzUmVhbEluZGV4IHx8IDA7XHJcbiAgICAgIGN1cnJlbnQgPVxyXG4gICAgICAgI
9266HN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXAgPiAxXHJcbiAgICAgICAgICA/IE1hdGguZmxvb3Ioc3dpcGVyLnJlYWxJbmRleCAvIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXApXHJcbiAgICAgICAgICA6IHN3aXBlci5yZWFsSW5kZXg7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzd2lwZXIuc25hcEluZGV4ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBjdXJyZW50ID0gc3dpcGVyLnNuYXBJbmRleDtcclxuICAgICAgcHJldmlvdXNJbmRleCA9IHN3aXBlci5wcmV2aW91c1NuYXBJbmRleDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHByZXZpb3VzSW5kZXggPSBzd2lwZXIucHJldmlvdXNJbmRleCB8fCAwO1xyXG4gICAgICBjdXJyZW50ID0gc3dpcGVyLmFjdGl2ZUluZGV4IHx8IDA7XHJcbiAgICB9XHJcbiAgICAvLyBUeXBlc1xyXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycgJiYgc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cyAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgYnVsbGV0cyA9IHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHM7XHJcbiAgICAgIGxldCBmaXJzdEluZGV4O1xyXG4gICAgICBsZXQgbGFzdEluZGV4O1xyXG4gICAgICBsZXQgbWlkSW5kZXg7XHJcbiAgICAgIGlmIChwYXJhbXMuZHluYW1pY0J1bGxldHMpIHtcclxuICAgICAgICBidWxsZXRTaXplID0gZWxlbWVudE91dGVyU2l6ZShidWxsZXRzWzBdLCBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnd2lkdGgnIDogJ2hlaWdodCcsIHRydWUpO1xyXG4gICAgICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgICAgICBzdWJFbC5zdHlsZVtzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnd2lkdGgnIDogJ2hlaWdodCddID0gYCR7YnVsbGV0U2l6ZSAqIChwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzICsgNCl9cHhgO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmIChwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzID4gMSAmJiBwcmV2aW91c0luZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIGR5bmFtaWNCdWxsZXRJbmRleCArPSBjdXJyZW50IC0gKHByZXZpb3VzSW5kZXggfHwgMCk7XHJcbiAgICAgICAgICBpZiAoZHluYW1pY0J1bGxldEluZGV4ID4gcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyAtIDEpIHtcclxuICAgICAgICAgICAgZHluYW1pY0J1bGxldEluZGV4ID0gcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyAtIDE7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKGR5bmFtaWNCdWxsZXRJbmRleCA8IDApIHtcclxuICAgICAgICAgICAgZHluYW1pY0J1bGxldEluZGV4ID0gMDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZmlyc3RJbmRleCA9IE1hdGgubWF4KGN1cnJlbnQgLSBkeW5hbWljQnVsbGV0SW5kZXgsIDApO1xyXG4gICAgICAgIGxhc3RJbmRleCA9IGZpcnN0SW5kZXggKyAoTWF0aC5taW4oYnVsbGV0cy5sZW5ndGgsIHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMpIC0gMSk7XHJcbiAgICAgICAgbWlkSW5kZXggPSAobGFzdEluZGV4ICsgZmlyc3RJbmRleCkgLyAyO1xyXG4gICAgICB9XHJcbiAgICAgIGJ1bGxldHMuZm9yRWFjaCgoYnVsbGV0RWwpID0+IHtcclxuICAgICAgICBjb25zdCBjbGFzc2VzVG9SZW1vdmUgPSBbXHJcbiAgICAgICAgICAuLi5bJycsICctbmV4dCcsICctbmV4dC1uZXh0JywgJy1wcmV2JywgJy1wcmV2LXByZXYnLCAnLW1haW4nXS5tYXAoXHJcbiAgICAgICAgICAgIChzdWZmaXgpID0+IGAke3BhcmFtcy5idWxsZXRBY3RpdmVDbGFzc30ke3N1ZmZpeH1gXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgIF1cclxuICAgICAgICAgIC5tYXAoKHMpID0+ICh0eXBlb2YgcyA9PT0gJ3N0cmluZycgJiYgcy5pbmNsdWRlcygnICcpID8gcy5zcGxpdCgnICcpIDogcykpXHJcbiAgICAgICAgICAuZmxhdCgpO1xyXG4gICAgICAgIGJ1bGxldEVsLmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3Nlc1RvUmVtb3ZlKTtcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChlbC5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgYnVsbGV0cy5mb3JFYWNoKChidWxsZXQpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGJ1bGxldEluZGV4ID0gZWxlbWVudEluZGV4KGJ1bGxldCk7XHJcbiAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPT09IGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgYnVsbGV0LmNsYXNzTGlzdC5hZGQoLi4ucGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzLnNwbGl0KCcgJykpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChzd2lwZXIuaXNFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGJ1bGxldC5zZXRBdHRyaWJ1dGUoJ3BhcnQnLCAnYnVsbGV0Jyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAocGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XHJcbiAgICAgICAgICAgIGlmIChidWxsZXRJbmRleCA+PSBmaXJzdEluZGV4ICYmIGJ1bGxldEluZGV4IDw9IGxhc3RJbmRleCkge1xyXG4gICAgICAgICAgICAgIGJ1bGxldC5jbGFzc0xpc3QuYWRkKC4uLmAke3BhcmFtcy5idWxsZXRBY3RpdmVDbGFzc30tbWFpbmAuc3BsaXQoJyAnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGJ1bGxldEluZGV4ID09PSBmaXJzdEluZGV4KSB7XHJcbiAgICAgICAgICAgICAgc2V0U2lkZUJ1bGxldHMoYnVsbGV0LCAncHJldicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChidWxsZXRJbmRleCA9PT0gbGFzdEluZGV4KSB7XHJcbiAgICAgICAgICAgICAgc2V0U2lkZUJ1bGxldHMoYnVsbGV0LCAnbmV4dCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgYnVsbGV0ID0gYnVsbGV0c1tjdXJyZW50XTtcclxuICAgICAgICBpZiAoYnVsbGV0KSB7XHJcbiAgICAgICAgICBidWxsZXQuY2xhc3NMaXN0LmFkZCguLi5wYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3Muc3BsaXQoJyAnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzd2lwZXIuaXNFbGVtZW50KSB7XHJcbiAgICAgICAgICBidWxsZXRzLmZvckVhY2goKGJ1bGxldEVsLCBidWxsZXRJbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBidWxsZXRFbC5zZXRBdHRyaWJ1dGUoJ3BhcnQnLCBidWxsZXRJbmRleCA9PT0gY3VycmVudCA/ICdidWxsZXQtYWN0aXZlJyA6ICdidWxsZXQnKTtcclxuICAgICAgICAgI
9266H0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XHJcbiAgICAgICAgICBjb25zdCBmaXJzdERpc3BsYXllZEJ1bGxldCA9IGJ1bGxldHNbZmlyc3RJbmRleF07XHJcbiAgICAgICAgICBjb25zdCBsYXN0RGlzcGxheWVkQnVsbGV0ID0gYnVsbGV0c1tsYXN0SW5kZXhdO1xyXG4gICAgICAgICAgZm9yIChsZXQgaSA9IGZpcnN0SW5kZXg7IGkgPD0gbGFzdEluZGV4OyBpICs9IDEpIHtcclxuICAgICAgICAgICAgaWYgKGJ1bGxldHNbaV0pIHtcclxuICAgICAgICAgICAgICBidWxsZXRzW2ldLmNsYXNzTGlzdC5hZGQoLi4uYCR7cGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzfS1tYWluYC5zcGxpdCgnICcpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc2V0U2lkZUJ1bGxldHMoZmlyc3REaXNwbGF5ZWRCdWxsZXQsICdwcmV2Jyk7XHJcbiAgICAgICAgICBzZXRTaWRlQnVsbGV0cyhsYXN0RGlzcGxheWVkQnVsbGV0LCAnbmV4dCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBpZiAocGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XHJcbiAgICAgICAgY29uc3QgZHluYW1pY0J1bGxldHNMZW5ndGggPSBNYXRoLm1pbihidWxsZXRzLmxlbmd0aCwgcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyArIDQpO1xyXG4gICAgICAgIGNvbnN0IGJ1bGxldHNPZmZzZXQgPSAoYnVsbGV0U2l6ZSAqIGR5bmFtaWNCdWxsZXRzTGVuZ3RoIC0gYnVsbGV0U2l6ZSkgLyAyIC0gbWlkSW5kZXggKiBidWxsZXRTaXplO1xyXG4gICAgICAgIGNvbnN0IG9mZnNldFByb3AgPSBydGwgPyAncmlnaHQnIDogJ2xlZnQnO1xyXG4gICAgICAgIGJ1bGxldHMuZm9yRWFjaCgoYnVsbGV0KSA9PiB7XHJcbiAgICAgICAgICBidWxsZXQuc3R5bGVbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gb2Zmc2V0UHJvcCA6ICd0b3AnXSA9IGAke2J1bGxldHNPZmZzZXR9cHhgO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCwgc3ViRWxJbmRleCkgPT4ge1xyXG4gICAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdmcmFjdGlvbicpIHtcclxuICAgICAgICBzdWJFbC5xdWVyeVNlbGVjdG9yQWxsKGNsYXNzZXNUb1NlbGVjdG9yKHBhcmFtcy5jdXJyZW50Q2xhc3MpKS5mb3JFYWNoKChmcmFjdGlvbkVsKSA9PiB7XHJcbiAgICAgICAgICBmcmFjdGlvbkVsLnRleHRDb250ZW50ID0gcGFyYW1zLmZvcm1hdEZyYWN0aW9uQ3VycmVudChjdXJyZW50ICsgMSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgc3ViRWwucXVlcnlTZWxlY3RvckFsbChjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMudG90YWxDbGFzcykpLmZvckVhY2goKHRvdGFsRWwpID0+IHtcclxuICAgICAgICAgIHRvdGFsRWwudGV4dENvbnRlbnQgPSBwYXJhbXMuZm9ybWF0RnJhY3Rpb25Ub3RhbCh0b3RhbCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAncHJvZ3Jlc3NiYXInKSB7XHJcbiAgICAgICAgbGV0IHByb2dyZXNzYmFyRGlyZWN0aW9uO1xyXG4gICAgICAgIGlmIChwYXJhbXMucHJvZ3Jlc3NiYXJPcHBvc2l0ZSkge1xyXG4gICAgICAgICAgcHJvZ3Jlc3NiYXJEaXJlY3Rpb24gPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBwcm9ncmVzc2JhckRpcmVjdGlvbiA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICdob3Jpem9udGFsJyA6ICd2ZXJ0aWNhbCc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHNjYWxlID0gKGN1cnJlbnQgKyAxKSAvIHRvdGFsO1xyXG4gICAgICAgIGxldCBzY2FsZVggPSAxO1xyXG4gICAgICAgIGxldCBzY2FsZVkgPSAxO1xyXG4gICAgICAgIGlmIChwcm9ncmVzc2JhckRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XHJcbiAgICAgICAgICBzY2FsZVggPSBzY2FsZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2NhbGVZID0gc2NhbGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHN1YkVsLnF1ZXJ5U2VsZWN0b3JBbGwoY2xhc3Nlc1RvU2VsZWN0b3IocGFyYW1zLnByb2dyZXNzYmFyRmlsbENsYXNzKSkuZm9yRWFjaCgocHJvZ3Jlc3NFbCkgPT4ge1xyXG4gICAgICAgICAgcHJvZ3Jlc3NFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlWCgke3NjYWxlWH0pIHNjYWxlWSgke3NjYWxlWX0pYDtcclxuICAgICAgICAgIHByb2dyZXNzRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7c3dpcGVyLnBhcmFtcy5zcGVlZH1tc2A7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAnY3VzdG9tJyAmJiBwYXJhbXMucmVuZGVyQ3VzdG9tKSB7XHJcbiAgICAgICAgc3ViRWwuaW5uZXJIVE1MID0gcGFyYW1zLnJlbmRlckN1c3RvbShzd2lwZXIsIGN1cnJlbnQgKyAxLCB0b3RhbCk7XHJcbiAgICAgICAgaWYgKHN1YkVsSW5kZXggPT09IDApIGVtaXQoJ3BhZ2luYXRpb25SZW5kZXInLCBzdWJFbCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHN1YkVsSW5kZXggPT09IDApIGVtaXQoJ3BhZ2luYXRpb25SZW5kZXInLCBzdWJFbCk7XHJcbiAgICAgICAgZW1pdCgncGFnaW5hdGlvblVwZGF0ZScsIHN1YkVsKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5lbmFibGVkKSB7XHJcbiAgICAgICAgc3ViRWwuY2xhc3NMaXN0W3N3aXBlci5pc0xvY2tlZCA/ICdhZGQnIDogJ3JlbW92ZSddKHBhcmFtcy5sb2NrQ2xhc3MpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gcmVuZGVyKCkge1xyXG4gICAgLy8gUmVuZGVyIENvbnRhaW5lclxyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uO1xyXG4gICAgaWYgKGlzUGFnaW5hdGlvbkRpc2FibGVkKCkpIHJldHVybjtcclxuICAgIGNvbnN0IHNsaWRlc0xlbmd0aCA9XHJcbiAgICAgIHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xyXG4gICAgbGV0IGVsID0gc3dpcGVyLnBhZ2luYXRpb24uZWw7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGxldCBwYWdpbmF0aW9uSFRNTCA9ICcnO1xyXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycpIHtcclxuICAgICAgbGV0IG51bWJlck9mQnVsbGV0cyA9IHN3aXBlci5wYXJhbXMubG9vcFxyXG4gICAgICAgID8gTWF0aC5jZWlsKHNsaWRlc0xlbmd0aCAvIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXApXHJcbiAgICAgICAgOiBzd2lwZXIuc25hcEdyaWQubGVuZ3RoO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBzd2lwZXIucGFyYW1zLmZyZWVNb2RlLmVuYWJsZWQgJiYgbnVtYmVyT2ZCdWxsZXRzID4gc2xpZGVzTGVuZ3RoKSB7XHJcbiAgICAgICAgbnVtYmVyT2ZCdWxsZXRzID0gc2xpZGVzTGVuZ3RoO1xyXG4gICAgICB9XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZCdWxsZXRzOyBpICs9IDEpIHtcclxuICAgICAgICBpZiAocGFyYW1zLnJlbmRlckJ1bGxldCkge1xyXG4gICAgICAgICAgcGFnaW5hdGlvbkhUTUwgKz0gcGFyYW1zLnJlbmRlckJ1bGxldC5jYWxsKHN3aXBlciwgaSwgcGFyYW1zLmJ1bGxldENsYXNzKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXHJcbiAgICAgICAgICBwYWdpbmF0aW9uSFRNTCArPSBgPCR7cGFyYW1zLmJ1bGxldEVsZW1lbnR9ICR7c3dpcGVyLmlzRWxlbWVudCA/ICdwYXJ0PVwiYnVsbGV0XCInIDogJyd9IGNsYXNzPVwiJHtwYXJhbXMuYnVsbGV0Q2xhc3N9XCI+PC8ke3BhcmFtcy5idWxsZXRFbGVtZW50fT5gO1xyXG4gICAgICAgI
9266H1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnZnJhY3Rpb24nKSB7XHJcbiAgICAgIGlmIChwYXJhbXMucmVuZGVyRnJhY3Rpb24pIHtcclxuICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IHBhcmFtcy5yZW5kZXJGcmFjdGlvbi5jYWxsKHN3aXBlciwgcGFyYW1zLmN1cnJlbnRDbGFzcywgcGFyYW1zLnRvdGFsQ2xhc3MpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHBhZ2luYXRpb25IVE1MID1cclxuICAgICAgICAgIGA8c3BhbiBjbGFzcz1cIiR7cGFyYW1zLmN1cnJlbnRDbGFzc31cIj48L3NwYW4+YCArICcgLyAnICsgYDxzcGFuIGNsYXNzPVwiJHtwYXJhbXMudG90YWxDbGFzc31cIj48L3NwYW4+YDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAncHJvZ3Jlc3NiYXInKSB7XHJcbiAgICAgIGlmIChwYXJhbXMucmVuZGVyUHJvZ3Jlc3NiYXIpIHtcclxuICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IHBhcmFtcy5yZW5kZXJQcm9ncmVzc2Jhci5jYWxsKHN3aXBlciwgcGFyYW1zLnByb2dyZXNzYmFyRmlsbENsYXNzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IGA8c3BhbiBjbGFzcz1cIiR7cGFyYW1zLnByb2dyZXNzYmFyRmlsbENsYXNzfVwiPjwvc3Bhbj5gO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzID0gW107XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBpZiAocGFyYW1zLnR5cGUgIT09ICdjdXN0b20nKSB7XHJcbiAgICAgICAgc3ViRWwuaW5uZXJIVE1MID0gcGFnaW5hdGlvbkhUTUwgfHwgJyc7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycpIHtcclxuICAgICAgICBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLnB1c2goLi4uc3ViRWwucXVlcnlTZWxlY3RvckFsbChjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMuYnVsbGV0Q2xhc3MpKSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKHBhcmFtcy50eXBlICE9PSAnY3VzdG9tJykge1xyXG4gICAgICBlbWl0KCdwYWdpbmF0aW9uUmVuZGVyJywgZWxbMF0pO1xyXG4gICAgfVxyXG4gIH1cclxuICBmdW5jdGlvbiBpbml0KCkge1xyXG4gICAgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uID0gY3JlYXRlRWxlbWVudElmTm90RGVmaW5lZChcclxuICAgICAgc3dpcGVyLFxyXG4gICAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMucGFnaW5hdGlvbixcclxuICAgICAgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLFxyXG4gICAgICB7XHJcbiAgICAgICAgZWw6ICdzd2lwZXItcGFnaW5hdGlvbicsXHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XHJcbiAgICBpZiAoIXBhcmFtcy5lbCkgcmV0dXJuO1xyXG4gICAgbGV0IGVsO1xyXG4gICAgaWYgKHR5cGVvZiBwYXJhbXMuZWwgPT09ICdzdHJpbmcnICYmIHN3aXBlci5pc0VsZW1lbnQpIHtcclxuICAgICAgZWwgPSBzd2lwZXIuZWwuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKHBhcmFtcy5lbCk7XHJcbiAgICB9XHJcbiAgICBpZiAoIWVsICYmIHR5cGVvZiBwYXJhbXMuZWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGVsID0gWy4uLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwocGFyYW1zLmVsKV07XHJcbiAgICB9XHJcbiAgICBpZiAoIWVsKSB7XHJcbiAgICAgIGVsID0gcGFyYW1zLmVsO1xyXG4gICAgfVxyXG4gICAgaWYgKCFlbCB8fCBlbC5sZW5ndGggPT09IDApIHJldHVybjtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLnVuaXF1ZU5hdkVsZW1lbnRzICYmIHR5cGVvZiBwYXJhbXMuZWwgPT09ICdzdHJpbmcnICYmIEFycmF5LmlzQXJyYXkoZWwpICYmIGVsLmxlbmd0aCA+IDEpIHtcclxuICAgICAgZWwgPSBbLi4uc3dpcGVyLmVsLnF1ZXJ5U2VsZWN0b3JBbGwocGFyYW1zLmVsKV07XHJcbiAgICAgIC8vIGNoZWNrIGlmIGl0IGJlbG9uZ3MgdG8gYW5vdGhlciBuZXN0ZWQgU3dpcGVyXHJcbiAgICAgIGlmIChlbC5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgZWwgPSBlbC5maWx0ZXIoKHN1YkVsKSA9PiB7XHJcbiAgICAgICAgICBpZiAoZWxlbWVudFBhcmVudHMoc3ViRWwsICcuc3dpcGVyJylbMF0gIT09IHN3aXBlci5lbCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSlbMF07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChBcnJheS5pc0FycmF5KGVsKSAmJiBlbC5sZW5ndGggPT09IDEpIGVsID0gZWxbMF07XHJcbiAgICBPYmplY3QuYXNzaWduKHN3aXBlci5wYWdpbmF0aW9uLCB7XHJcbiAgICAgIGVsLFxyXG4gICAgfSk7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2J1bGxldHMnICYmIHBhcmFtcy5jbGlja2FibGUpIHtcclxuICAgICAgICBzdWJFbC5jbGFzc0xpc3QuYWRkKHBhcmFtcy5jbGlja2FibGVDbGFzcyk7XHJcbiAgICAgIH1cclxuICAgICAgc3ViRWwuY2xhc3NMaXN0LmFkZChwYXJhbXMubW9kaWZpZXJDbGFzcyArIHBhcmFtcy50eXBlKTtcclxuICAgICAgc3ViRWwuY2xhc3NMaXN0LmFkZChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBwYXJhbXMuaG9yaXpvbn
9266RhbENsYXNzIDogcGFyYW1zLnZlcnRpY2FsQ2xhc3MpO1xyXG4gICAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdidWxsZXRzJyAmJiBwYXJhbXMuZHluYW1pY0J1bGxldHMpIHtcclxuICAgICAgICBzdWJFbC5jbGFzc0xpc3QuYWRkKGAke3BhcmFtcy5tb2RpZmllckNsYXNzfSR7cGFyYW1zLnR5cGV9LWR5bmFtaWNgKTtcclxuICAgICAgICBkeW5hbWljQnVsbGV0SW5kZXggPSAwO1xyXG4gICAgICAgIGlmIChwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzIDwgMSkge1xyXG4gICAgICAgICAgcGFyYW1zLmR5bmFtaWNNYWluQnVsbGV0cyA9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ3Byb2dyZXNzYmFyJyAmJiBwYXJhbXMucHJvZ3Jlc3NiYXJPcHBvc2l0ZSkge1xyXG4gICAgICAgIHN1YkVsLmNsYXNzTGlzdC5hZGQocGFyYW1zLnByb2dyZXNzYmFyT3Bwb3NpdGVDbGFzcyk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHBhcmFtcy5jbGlja2FibGUpIHtcclxuICAgICAgICBzdWJFbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uQnVsbGV0Q2xpY2spO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHtcclxuICAgICAgICBzdWJFbC5jbGFzc0xpc3QuYWRkKHBhcmFtcy5sb2NrQ2xhc3MpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gZGVzdHJveSgpIHtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbjtcclxuICAgIGlmIChpc1BhZ2luYXRpb25EaXNhYmxlZCgpKSByZXR1cm47XHJcbiAgICBsZXQgZWwgPSBzd2lwZXIucGFnaW5hdGlvbi5lbDtcclxuICAgIGlmIChlbCkge1xyXG4gICAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHtcclxuICAgICAgICBzdWJFbC5jbGFzc0xpc3QucmVtb3ZlKHBhcmFtcy5oaWRkZW5DbGFzcyk7XHJcbiAgICAgICAgc3ViRWwuY2xhc3NMaXN0LnJlbW92ZShwYXJhbXMubW9kaWZpZXJDbGFzcyArIHBhcmFtcy50eXBlKTtcclxuICAgICAgICBzdWJFbC5jbGFzc0xpc3QucmVtb3ZlKHN3aXBlci5pc0hvcml6b250YWwoKSA/IHBhcmFtcy5ob3Jpem9udGFsQ2xhc3MgOiBwYXJhbXMudmVydGljYWxDbGFzcyk7XHJcbiAgICAgICAgaWYgKHBhcmFtcy5jbGlja2FibGUpIHtcclxuICAgICAgICAgIHN1YkVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25CdWxsZXRDbGljayk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzKVxyXG4gICAgICBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLmZvckVhY2goKHN1YkVsKSA9PiBzdWJFbC5jbGFzc0xpc3QucmVtb3ZlKC4uLnBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcy5zcGxpdCgnICcpKSk7XHJcbiAgfVxyXG4gIG9uKCdjaGFuZ2VEaXJlY3Rpb24nLCAoKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlci5wYWdpbmF0aW9uIHx8ICFzd2lwZXIucGFnaW5hdGlvbi5lbCkgcmV0dXJuO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uO1xyXG4gICAgbGV0IHsgZWwgfSA9IHN3aXBlci5wYWdpbmF0aW9uO1xyXG4gICAgZWwgPSBtYWtlRWxlbWVudHNBcnJheShlbCk7XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBzdWJFbC5jbGFzc0xpc3QucmVtb3ZlKHBhcmFtcy5ob3Jpem9udGFsQ2xhc3MsIHBhcmFtcy52ZXJ0aWNhbENsYXNzKTtcclxuICAgICAgc3ViRWwuY2xhc3NMaXN0LmFkZChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBwYXJhbXMuaG9yaXpvbn
9266RhbENsYXNzIDogcGFyYW1zLnZlcnRpY2FsQ2xhc3MpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcbiAgb24oJ2luaXQnLCAoKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmVuYWJsZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxyXG4gICAgICBkaXNhYmxlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpbml0KCk7XHJcbiAgICAgIHJlbmRlcigpO1xyXG4gICAgICB1cGRhdGUoKTtcclxuICAgIH1cclxuICB9KTtcclxuICBvbignYWN0aXZlSW5kZXhDaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIHN3aXBlci5zbmFwSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHVwZGF0ZSgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdzbmFwSW5kZXhDaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICB1cGRhdGUoKTtcclxuICB9KTtcclxuICBvbignc25hcEdyaWRMZW5ndGhDaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICByZW5kZXIoKTtcclxuICAgIHVwZGF0ZSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgZGVzdHJveSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdlbmFibGUgZGlzYWJsZScsICgpID0+IHtcclxuICAgIGxldCB7IGVsIH0gPSBzd2lwZXIucGFnaW5hdGlvbjtcclxuICAgIGlmIChlbCkge1xyXG4gICAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHN1YkVsLmNsYXNzTGlzdFtzd2lwZXIuZW5hYmxlZCA/ICdyZW1vdmUnIDogJ2FkZCddKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5sb2NrQ2xhc3MpKTtcclxuICAgIH1cclxuICB9KTtcclxuICBvbignbG9jayB1bmxvY2snLCAoKSA9PiB7XHJcbiAgICB1cGRhdGUoKTtcclxuICB9KTtcclxuICBvbignY2xpY2snLCAoX3MsIGUpID0+IHtcclxuICAgIGNvbnN0IHRhcmdldEVsID0gZS50YXJnZXQ7XHJcbiAgICBsZXQgeyBlbCB9ID0gc3dpcGVyLnBhZ2luYXRpb247XHJcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZWwpKSBlbCA9IFtlbF0uZmlsdGVyKChlbGVtZW50KSA9PiAhIWVsZW1lbnQpO1xyXG4gICAgaWYgKFxyXG4gICAgICBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uZWwgJiZcclxuICAgICAgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmhpZGVPbkNsaWNrICYmXHJcbiAgICAgIGVsICYmXHJcbiAgICAgIGVsLmxlbmd0aCA+IDAgJiZcclxuICAgICAgIXRhcmdldEVsLmNsYXNzTGlzdC5jb250YWlucyhzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uYnVsbGV0Q2xhc3MpXHJcbiAgICApIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHN3aXBlci5uYXZpZ2F0aW9uICYmXHJcbiAgICAgICAgKChzd2lwZXIubmF2aWdhdGlvbi5uZXh0RWwgJiYgdGFyZ2V0RWwgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCkgfHxcclxuICAgICAgICAgIChzd2lwZXIubmF2aWdhdGlvbi5wcmV2RWwgJiYgdGFyZ2V0RWwgPT09IHN3aXBlci5uYXZpZ2F0aW9uLnByZXZFbCkpXHJcbiAgICAgIClcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIGNvbnN0IGlzSGlkZGVuID0gZWxbMF0uY2xhc3NMaXN0LmNvbnRhaW5zKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5oaWRkZW5DbGFzcyk7XHJcbiAgICAgIGlmIChpc0hpZGRlbiA9PT0gdHJ1ZSkge1xyXG4gICAgICAgIGVtaXQoJ3BhZ2luYXRpb25TaG93Jyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZW1pdCgncGFnaW5hdGlvbkhpZGUnKTtcclxuICAgICAgfVxyXG4gICAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4gc3ViRWwuY2xhc3NMaXN0LnRvZ2dsZShzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uaGlkZGVuQ2xhc3MpKTtcclxuICAgIH1cclxuICB9KTtcclxuICBjb25zdCBlbmFibGUgPSAoKSA9PiB7XHJcbiAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LnJlbW92ZShzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ucGFnaW5hdGlvbkRpc2FibGVkQ2xhc3MpO1xyXG4gICAgbGV0IHsgZWwgfSA9IHN3aXBlci5wYWdpbmF0aW9uO1xyXG4gICAgaWYgKGVsKSB7XHJcbiAgICAgIGVsID0gbWFrZUVsZW1lbnRzQXJyYXkoZWwpO1xyXG4gICAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4gc3ViRWwuY2xhc3NMaXN0LnJlbW92ZShzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ucGFnaW5hdGlvbkRpc2FibGVkQ2xhc3MpKTtcclxuICAgIH1cclxuICAgIGluaXQoKTtcclxuICAgIHJlbmRlcigpO1xyXG4gICAgdXBkYXRlKCk7XHJcbiAgfTtcclxuICBjb25zdCBkaXNhYmxlID0gKCkgPT4ge1xyXG4gICAgc3dpcGVyLmVsLmNsYXNzTGlzdC5hZGQoc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLnBhZ2luYXRpb25EaXNhYmxlZENsYXNzKTtcclxuICAgIGxldCB7IGVsIH0gPSBzd2lwZXIucGFnaW5hdGlvbjtcclxuICAgIGlmIChlbCkge1xyXG4gICAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHN1YkVsLmNsYXNzTGlzdC5hZGQoc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLnBhZ2luYXRpb25EaXNhYmxlZENsYXNzKSk7XHJcbiAgICB9XHJcbiAgICBkZXN0cm95KCk7XHJcbiAgfTtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlci5wYWdpbmF0aW9uLCB7XHJcbiAgICBlbmFibGUsXHJcbiAgICBkaXNhYmxlLFxyXG4gICAgcmVuZGVyLFxyXG4gICAgdXBkYXRlLFxyXG4gICAgaW5pdCxcclxuICAgIGRlc3Ryb3ksXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIFNjcm9sbGJhcihfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uLCBlbWl0IH0gPSBfcmVmO1xyXG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICBsZXQgaXNUb3VjaGVkID0gZmFsc2U7XHJcbiAgbGV0IHRpbWVvdXQgPSBudWxsO1xyXG4gIGxldCBkcmFnVGltZW91dCA9IG51bGw7XHJcbiAgbGV0IGRyYWdTdGFydFBvcztcclxuICBsZXQgZHJhZ1NpemU7XHJcbiAgbGV0IHRyYWNrU2l6ZTtcclxuICBsZXQgZGl2aWRlcjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgc2Nyb2xsYmFyOiB7XHJcbiAgICAgIGVsOiBudWxsLFxyXG4gICAgICBkcmFnU2l6ZTogJ2F1dG8nLFxyXG4gICAgICBoaWRlOiBmYWxzZSxcclxuICAgICAgZHJhZ2dhYmxlOiBmYWxzZSxcclxuICAgICAgc25hcE9uUmVsZWFzZTogdHJ1ZSxcclxuICAgICAgbG9ja0NsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1sb2NrJyxcclxuICAgICAgZHJhZ0NsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1kcmFnJyxcclxuICAgICAgc2Nyb2xsYmFyRGlzYWJsZWRDbGFzczogJ3N3aXBlci1zY3JvbGxiYXItZGlzYWJsZWQnLFxyXG4gICAgICBob3Jpem9udGFsQ2xhc3M6IGBzd2lwZXItc2Nyb2xsYmFyLWhvcml6b250YWxgLFxyXG4gICAgICB2ZXJ0aWNhbENsYXNzOiBgc3dpcGVyLXNjcm9sbGJhci12ZXJ0aWNhbGAsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIHN3aXBlci5zY3JvbGxiYXIgPSB7XHJcbiAgICBlbDogbnVsbCxcclxuICAgIGRyYWdFbDogbnVsbCxcclxuICB9O1xyXG4gIGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSgpIHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwgfHwgIXN3aXBlci5zY3JvbGxiYXIuZWwpIHJldHVybjtcclxuICAgIGNvbnN0IHsgc2Nyb2xsYmFyLCBydGxUcmFuc2xhdGU6IHJ0bCB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgeyBkcmFnRWwsIGVsIH0gPSBzY3JvbGxiYXI7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcclxuICAgIGNvbnN0IHByb2dyZXNzID0gc3dpcGVyLnBhcmFtcy5sb29w
9266ID8gc3dpcGVyLnByb2dyZXNzTG9vcCA6IHN3aXBlci5wcm9ncmVzcztcclxuICAgIGxldCBuZXdTaXplID0gZHJhZ1NpemU7XHJcbiAgICBsZXQgbmV3UG9zID0gKHRyYWNrU2l6ZSAtIGRyYWdTaXplKSAqIHByb2dyZXNzO1xyXG4gICAgaWYgKHJ0bCkge1xyXG4gICAgICBuZXdQb3MgPSAtbmV3UG9zO1xyXG4gICAgICBpZiAobmV3UG9zID4gMCkge1xyXG4gICAgICAgIG5ld1NpemUgPSBkcmFnU2l6ZSAtIG5ld1BvcztcclxuICAgICAgICBuZXdQb3MgPSAwO1xyXG4gICAgICB9IGVsc2UgaWYgKC1uZXdQb3MgKyBkcmFnU2l6ZSA+IHRyYWNrU2l6ZSkge1xyXG4gICAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgKyBuZXdQb3M7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAobmV3UG9zIDwgMCkge1xyXG4gICAgICBuZXdTaXplID0gZHJhZ1NpemUgKyBuZXdQb3M7XHJcbiAgICAgIG5ld1BvcyA9IDA7XHJcbiAgICB9IGVsc2UgaWYgKG5ld1BvcyArIGRyYWdTaXplID4gdHJhY2tTaXplKSB7XHJcbiAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgLSBuZXdQb3M7XHJcbiAgICB9XHJcbiAgICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XHJcbiAgICAgIGRyYWdFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHtuZXdQb3N9cHgsIDAsIDApYDtcclxuICAgICAgZHJhZ0VsLnN0eWxlLndpZHRoID0gYCR7bmV3U2l6ZX1weGA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkcmFnRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKDBweCwgJHtuZXdQb3N9cHgsIDApYDtcclxuICAgICAgZHJhZ0VsLnN0eWxlLmhlaWdodCA9IGAke25ld1NpemV9cHhgO1xyXG4gICAgfVxyXG4gICAgaWYgKHBhcmFtcy5oaWRlKSB7XHJcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgZWwuc3R5bGUub3BhY2l0eSA9IDE7XHJcbiAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBlbC5zdHlsZS5vcGFjaXR5ID0gMDtcclxuICAgICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnNDAwbXMnO1xyXG4gICAgICB9LCAxMDAwKTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gc2V0VHJhbnNpdGlvbihkdXJhdGlvbikge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xyXG4gICAgc3dpcGVyLnNjcm9sbGJhci5kcmFnRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7ZHVyYXRpb259bXNgO1xyXG4gIH1cclxuICBmdW5jdGlvbiB1cGRhdGVTaXplKCkge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xyXG4gICAgY29uc3QgeyBzY3JvbGxiYXIgfSA9IHN3aXBlcjtcclxuICAgIGNvbnN0IHsgZHJhZ0VsLCBlbCB9ID0gc2Nyb2xsYmFyO1xyXG4gICAgZHJhZ0VsLnN0eWxlLndpZHRoID0gJyc7XHJcbiAgICBkcmFnRWwuc3R5bGUuaGVpZ2h0ID0gJyc7XHJcbiAgICB0cmFja1NpemUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBlbC5vZmZzZXRXaWR0aCA6IGVsLm9mZnNldEhlaWdodDtcclxuICAgIGRpdmlkZXIgPVxyXG4gICAgICBzd2lwZXIuc2l6ZSAvXHJcbiAgICAgIChzd2lwZXIudmlydHVhbFNpemUgKyBzd2lwZXIucGFyYW1zLnNsaWRlc09mZnNldEJlZm9yZSAtIChzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzID8gc3dpcGVyLnNuYXBHcmlkWzBdIDogMCkpO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmRyYWdTaXplID09PSAnYXV0bycpIHtcclxuICAgICAgZHJhZ1NpemUgPSB0cmFja1NpemUgKiBkaXZpZGVyO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZHJhZ1NpemUgPSBwYXJzZUludChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnU2l6ZSwgMTApO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgICBkcmFnRWwuc3R5bGUud2lkdGggPSBgJHtkcmFnU2l6ZX1weGA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkcmFnRWwuc3R5bGUuaGVpZ2h0ID0gYCR7ZHJhZ1NpemV9cHhgO1xyXG4gICAgfVxyXG4gICAgaWYgKGRpdmlkZXIgPj0gMSkge1xyXG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICcnO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmhpZGUpIHtcclxuICAgICAgZWwuc3R5bGUub3BhY2l0eSA9IDA7XHJcbiAgICB9XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5lbmFibGVkKSB7XHJcbiAgICAgIHNjcm9sbGJhci5lbC5jbGFzc0xpc3Rbc3dpcGVyLmlzTG9ja2VkID8gJ2FkZCcgOiAncmVtb3ZlJ10oc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIubG9ja0NsYXNzKTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gZ2V0UG9pbnRlclBvc2l0aW9uKGUpIHtcclxuICAgIHJldHVybiBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBlLmNsaWVudFggOiBlLmNsaWVudFk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIHNldERyYWdQb3NpdGlvbihlKSB7XHJcbiAgICBjb25zdCB7IHNjcm9sbGJhciwgcnRsVHJhbnNsYXRlOiBydGwgfSA9IHN3aXBlcjtcclxuICAgIGNvbnN0IHsgZWwgfSA9IHNjcm9sbGJhcjtcclxuICAgIGxldCBwb3NpdGlvblJhdGlvO1xyXG4gICAgcG9zaXRpb25SYXRpbyA9XHJcbiAgICAgIChnZXRQb2ludGVyUG9zaXRpb24oZSkgLVxyXG4gICAgICAgIGVsZW1lbnRPZmZzZXQoZWwpW3N3aXBlci5pc0hvcml6b250YWwoKSA/ICdsZWZ0JyA6ICd0b3AnXSAtXHJcbiAgICAgICAgKGRyYWdTdGFydFBvcyAhPT0gbnVsbCA/IGRyYWdTdGFydFBvcyA6IGRyYWdTaXplIC8gMikpIC9cclxuICAgICAgKHRyYWNrU2l6ZSAtIGRyYWdTaXplKTtcclxuICAgIHBvc2l0aW9uUmF0aW8gPSBNYXRoLm1heChNYXRoLm1pbihwb3NpdGlvblJhdGlvLCAxKSwgMCk7XHJcbiAgICBpZiAocnRsKSB7XHJcbiAgICAgIHBvc2l0aW9uUmF0aW8gPSAxIC0gcG9zaXRpb25SYXRpbztcclxuICAgIH1cclxuICAgIGNvbnN0IHBvc2l0aW9uID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpICsgKHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKSkgKiBwb3NpdGlvblJhdGlvO1xyXG4gICAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKHBvc2l0aW9uKTtcclxuICAgIHN3aXBlci5zZXRUcmFuc2xhdGUocG9zaXRpb24pO1xyXG4gICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XHJcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvbkRyYWdTdGFydChlKSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcclxuICAgIGNvbnN0IHsgc2Nyb2xsYmFyLCB3cmFwcGVyRWwgfSA9IHN3aXBlcjtcclxuICAgIGNvbnN0IHsgZWwsIGRyYWdFbCB9ID0gc2Nyb2xsYmFyO1xyXG4gICAgaXNUb3VjaGVkID0gdHJ1ZTtcclxuICAgIGRyYWdTdGFydFBvcyA9XHJcbiAgICAgIGUudGFyZ2V0ID09PSBkcmFnRWxcclxuICAgICAgICA/IGdldFBvaW50ZXJQb3NpdGlvbihlKSAtIGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpW3N3aXBlci5pc0hvcml6b250YWwoKSA/ICdsZWZ0JyA6ICd0b3AnXVxyXG4gICAgICAgIDogbnVsbDtcclxuICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB3cmFwcGVyRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gJzEwMG1zJztcclxuICAgIGRyYWdFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMTAwbXMnO1xyXG4gICAgc2V0RHJhZ1Bvc2l0aW9uKGUpO1xyXG4gICAgY2xlYXJUaW1lb3V0KGRyYWdUaW1lb3V0KTtcclxuICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9ICcwbXMnO1xyXG4gICAgaWYgKHBhcmFtcy5oaWRlKSB7XHJcbiAgICAgIGVsLnN0eWxlLm9wYWNpdHkgPSAxO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlWydzY3JvbGwtc25hcC10eXBlJ10gPSAnbm9uZSc7XHJcbiAgICB9XHJcbiAgICBlbWl0KCdzY3JvbGxiYXJEcmFnU3RhcnQnLCBlKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gb25EcmFnTW92ZShlKSB7XHJcbiAgICBjb25zdCB7IHNjcm9sbGJhciwgd3JhcHBlckVsIH0gPSBzd2lwZXI7XHJcbiAgICBjb25zdCB7IGVsLCBkcmFnRWwgfSA9IHNjcm9sbGJhcjtcclxuICAgIGlmICghaXNUb3VjaGVkKSByZXR1cm47XHJcbiAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgZWxzZSBlLnJldHVyblZhbHVlID0gZmFsc2U7XHJcbiAgICBzZXREcmFnUG9zaXRpb24oZSk7XHJcbiAgICB3cmFwcGVyRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gJzBtcyc7XHJcbiAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMG1zJztcclxuICAgIGRyYWdFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMG1zJztcclxuICAgIGVtaXQoJ3Njcm9sbGJhckRyYWdNb3ZlJywgZSk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIG9uRHJhZ0VuZChlKSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcclxuICAgIGNvbnN0IHsgc2Nyb2xsYmFyLCB3cmFwcGVyRWwgfSA9IHN3aXBlcjtcclxuICAgIGNvbnN0IHsgZWwgfSA9IHNjcm9sbGJhcjtcclxuICAgIGlmICghaXNUb3VjaGVkKSByZXR1cm47XHJcbiAgICBpc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZVsnc2Nyb2xsLXNuYXAtdHlwZSddID0gJyc7XHJcbiAgICAgIHdyYXBwZXJFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnJztcclxuICAgIH1cclxuICAgIGlmIChwYXJhbXMuaGl
9266kZSkge1xyXG4gICAgICBjbGVhclRpbWVvdXQoZHJhZ1RpbWVvdXQpO1xyXG4gICAgICBkcmFnVGltZW91dCA9IG5leHRUaWNrKCgpID0+IHtcclxuICAgICAgICBlbC5zdHlsZS5vcGFjaXR5ID0gMDtcclxuICAgICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnNDAwbXMnO1xyXG4gICAgICB9LCAxMDAwKTtcclxuICAgIH1cclxuICAgIGVtaXQoJ3Njcm9sbGJhckRyYWdFbmQnLCBlKTtcclxuICAgIGlmIChwYXJhbXMuc25hcE9uUmVsZWFzZSkge1xyXG4gICAgICBzd2lwZXIuc2xpZGVUb0Nsb3Nlc3QoKTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gZXZlbnRzKG1ldGhvZCkge1xyXG4gICAgY29uc3QgeyBzY3JvbGxiYXIsIHBhcmFtcyB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgZWwgPSBzY3JvbGxiYXIuZWw7XHJcbiAgICBpZiAoIWVsKSByZXR1cm47XHJcbiAgICBjb25zdCB0YXJnZXQgPSBlbDtcclxuICAgIGNvbnN0IGFjdGl2ZUxpc3RlbmVyID0gcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnNcclxuICAgICAgPyB7XHJcbiAgICAgICAgICBwYXNzaXZlOiBmYWxzZSxcclxuICAgICAgICAgIGNhcHR1cmU6IGZhbHNlLFxyXG4gICAgICAgIH1cclxuICAgICAgOiBmYWxzZTtcclxuICAgIGNvbnN0IHBhc3NpdmVMaXN0ZW5lciA9IHBhcmFtcy5wYXNzaXZlTGlzdGVuZXJzXHJcbiAgICAgID8ge1xyXG4gICAgICAgICAgcGFzc2l2ZTogdHJ1ZSxcclxuICAgICAgICAgIGNhcHR1cmU6IGZhbHNlLFxyXG4gICAgICAgIH1cclxuICAgICAgOiBmYWxzZTtcclxuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XHJcbiAgICBjb25zdCBldmVudE1ldGhvZCA9IG1ldGhvZCA9PT0gJ29uJyA/ICdhZGRFdmVudExpc3RlbmVyJyA6ICdyZW1vdmVFdmVudExpc3RlbmVyJztcclxuICAgIHRhcmdldFtldmVudE1ldGhvZF0oJ3BvaW50ZXJkb3duJywgb25EcmFnU3RhcnQsIGFjdGl2ZUxpc3RlbmVyKTtcclxuICAgIGRvY3VtZW50W2V2ZW50TWV0aG9kXSgncG9pbnRlcm1vdmUnLCBvbkRyYWdNb3ZlLCBhY3RpdmVMaXN0ZW5lcik7XHJcbiAgICBkb2N1bWVudFtldmVudE1ldGhvZF0oJ3BvaW50ZXJ1cCcsIG9uRHJhZ0VuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gZW5hYmxlRHJhZ2dhYmxlKCkge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xyXG4gICAgZXZlbnRzKCdvbicpO1xyXG4gIH1cclxuICBmdW5jdGlvbiBkaXNhYmxlRHJhZ2dhYmxlKCkge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xyXG4gICAgZXZlbnRzKCdvZmYnKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gaW5pdCgpIHtcclxuICAgIGNvbnN0IHsgc2Nyb2xsYmFyLCBlbDogc3dpcGVyRWwgfSA9IHN3aXBlcjtcclxuICAgIHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyID0gY3JlYXRlRWxlbWVudElmTm90RGVmaW5lZChcclxuICAgICAgc3dpcGVyLFxyXG4gICAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMuc2Nyb2xsYmFyLFxyXG4gICAgICBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcixcclxuICAgICAge1xyXG4gICAgICAgIGVsOiAnc3dpcGVyLXNjcm9sbGJhcicsXHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcclxuICAgIGlmICghcGFyYW1zLmVsKSByZXR1cm47XHJcbiAgICBsZXQgZWw7XHJcbiAgICBpZiAodHlwZW9mIHBhcmFtcy5lbCA9PT0gJ3N0cmluZycgJiYgc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgICBlbCA9IHN3aXBlci5lbC5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IocGFyYW1zLmVsKTtcclxuICAgIH1cclxuICAgIGlmICghZWwgJiYgdHlwZW9mIHBhcmFtcy5lbCA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHBhcmFtcy5lbCk7XHJcbiAgICB9IGVsc2UgaWYgKCFlbCkge1xyXG4gICAgICBlbCA9IHBhcmFtcy5lbDtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgc3dpcGVyLnBhcmFtcy51bmlxdWVOYXZFbGVtZW50cyAmJlxyXG4gICAgICB0eXBlb2YgcGFyYW1zLmVsID09PSAnc3RyaW5nJyAmJlxyXG4gICAgICBlbC5sZW5ndGggPiAxICYmXHJcbiAgICAgIHN3aXBlckVsLnF1ZXJ5U2VsZWN0b3JBbGwocGFyYW1zLmVsKS5sZW5ndGggPT09IDFcclxuICAgICkge1xyXG4gICAgICBlbCA9IHN3aXBlckVsLnF1ZXJ5U2VsZWN0b3IocGFyYW1zLmVsKTtcclxuICAgIH1cclxuICAgIGlmIChlbC5sZW5ndGggPiAwKSBlbCA9IGVsWzBdO1xyXG4gICAgZWwuY2xhc3NMaXN0LmFkZChzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBwYXJhbXMuaG9yaXpvbn
9266RhbENsYXNzIDogcGFyYW1zLnZlcnRpY2FsQ2xhc3MpO1xyXG4gICAgbGV0IGRyYWdFbDtcclxuICAgIGlmIChlbCkge1xyXG4gICAgICBkcmFnRWwgPSBlbC5xdWVyeVNlbGVjdG9yKGAuJHtzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnQ2xhc3N9YCk7XHJcbiAgICAgIGlmICghZHJhZ0VsKSB7XHJcbiAgICAgICAgZHJhZ0VsID0gY3JlYXRlRWxlbWVudCgnZGl2Jywgc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZHJhZ0NsYXNzKTtcclxuICAgICAgICBlbC5hcHBlbmQoZHJhZ0VsKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgT2JqZWN0LmFzc2lnbihzY3JvbGxiYXIsIHtcclxuICAgICAgZWwsXHJcbiAgICAgIGRyYWdFbCxcclxuICAgIH0pO1xyXG4gICAgaWYgKHBhcmFtcy5kcmFnZ2FibGUpIHtcclxuICAgICAgZW5hYmxlRHJhZ2dhYmxlKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoZWwpIHtcclxuICAgICAgZWwuY2xhc3NMaXN0W3N3aXBlci5lbmFibGVkID8gJ3JlbW92ZScgOiAnYWRkJ10oc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIubG9ja0NsYXNzKTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gZGVzdHJveSgpIHtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyO1xyXG4gICAgY29uc3QgZWwgPSBzd2lwZXIuc2Nyb2xsYmFyLmVsO1xyXG4gICAgaWYgKGVsKSB7XHJcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gcGFyYW1zLmhvcml6b250YWxDbGFzcyA6IHBhcmFtcy52ZXJ0aWNhbENsYXNzKTtcclxuICAgIH1cclxuICAgIGRpc2FibGVEcmFnZ2FibGUoKTtcclxuICB9XHJcbiAgb24oJ2luaXQnLCAoKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZW5hYmxlZCA9PT0gZmFsc2UpIHtcclxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgICAgIGRpc2FibGUoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGluaXQoKTtcclxuICAgICAgdXBkYXRlU2l6ZSgpO1xyXG4gICAgICBzZXRUcmFuc2xhdGUoKTtcclxuICAgIH1cclxuICB9KTtcclxuICBvbigndXBkYXRlIHJlc2l6ZSBvYnNlcnZlclVwZGF0ZSBsb2NrIHVubG9jaycsICgpID0+IHtcclxuICAgIHVwZGF0ZVNpemUoKTtcclxuICB9KTtcclxuICBvbignc2V0VHJhbnNsYXRlJywgKCkgPT4ge1xyXG4gICAgc2V0VHJhbnNsYXRlKCk7XHJcbiAgfSk7XHJcbiAgb24oJ3NldFRyYW5zaXRpb24nLCAoX3MsIGR1cmF0aW9uKSA9PiB7XHJcbiAgICBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcclxuICB9KTtcclxuICBvbignZW5hYmxlIGRpc2FibGUnLCAoKSA9PiB7XHJcbiAgICBjb25zdCB7IGVsIH0gPSBzd2lwZXIuc2Nyb2xsYmFyO1xyXG4gICAgaWYgKGVsKSB7XHJcbiAgICAgIGVsLmNsYXNzTGlzdFtzd2lwZXIuZW5hYmxlZCA/ICdyZW1vdmUnIDogJ2FkZCddKHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmxvY2tDbGFzcyk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XHJcbiAgICBkZXN0cm95KCk7XHJcbiAgfSk7XHJcbiAgY29uc3QgZW5hYmxlID0gKCkgPT4ge1xyXG4gICAgc3dpcGVyLmVsLmNsYXNzTGlzdC5yZW1vdmUoc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuc2Nyb2xsYmFyRGlzYWJsZWRDbGFzcyk7XHJcbiAgICBpZiAoc3dpcGVyLnNjcm9sbGJhci5lbCkge1xyXG4gICAgICBzd2lwZXIuc2Nyb2xsYmFyLmVsLmNsYXNzTGlzdC5yZW1vdmUoc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuc2Nyb2xsYmFyRGlzYWJsZWRDbGFzcyk7XHJcbiAgICB9XHJcbiAgICBpbml0KCk7XHJcbiAgICB1cGRhdGVTaXplKCk7XHJcbiAgICBzZXRUcmFuc2xhdGUoKTtcclxuICB9O1xyXG4gIGNvbnN0IGRpc2FibGUgPSAoKSA9PiB7XHJcbiAgICBzd2lwZXIuZWwuY2xhc3NMaXN0LmFkZChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5zY3JvbGxiYXJEaXNhYmxlZENsYXNzKTtcclxuICAgIGlmIChzd2lwZXIuc2Nyb2xsYmFyLmVsKSB7XHJcbiAgICAgIHN3aXBlci5zY3JvbGxiYXIuZWwuY2xhc3NMaXN0LmFkZChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5zY3JvbGxiYXJEaXNhYmxlZENsYXNzKTtcclxuICAgIH1cclxuICAgIGRlc3Ryb3koKTtcclxuICB9O1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLnNjcm9sbGJhciwge1xyXG4gICAgZW5hYmxlLFxyXG4gICAgZGlzYWJsZSxcclxuICAgIHVwZGF0ZVNpemUsXHJcbiAgICBzZXRUcmFuc2xhdGUsXHJcbiAgICBpbml0LFxyXG4gICAgZGVzdHJveSxcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gUGFyYWxsYXgoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgcGFyYWxsYXg6IHtcclxuICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGNvbnN0IHNldFRyYW5zZm9ybSA9IChlbCwgcHJvZ3Jlc3MpID0+IHtcclxuICAgIGNvbnN0IHsgcnRsIH0gPSBzd2lwZXI7XHJcbiAgICBjb25zdCBydGxGYWN0b3IgPSBydGwgPyAtMSA6IDE7XHJcbiAgICBjb25zdCBwID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1wYXJhbGxheCcpIHx8ICcwJztcclxuICAgIGxldCB4ID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1wYXJhbGxheC14Jyk7XHJcbiAgICBsZXQgeSA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItcGFyYWxsYXgteScpO1xyXG4gICAgY29uc3Qgc2NhbGUgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LXNjYWxlJyk7XHJcbiAgICBjb25zdCBvcGFjaXR5ID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1wYXJhbGxheC1vcGFjaXR5Jyk7XHJcbiAgICBjb25zdCByb3RhdGUgPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LXJvdGF0ZScpO1xyXG4gICAgaWYgKHggfHwgeSkge1xyXG4gICAgICB4ID0geCB8fCAnMCc7XHJcbiAgICAgIHkgPSB5IHx8ICcwJztcclxuICAgIH0gZWxzZSBpZiAoc3dpcGVyLmlzSG9yaXpvbn
9266RhbCgpKSB7XHJcbiAgICAgIHggPSBwO1xyXG4gICAgICB5ID0gJzAnO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgeSA9IHA7XHJcbiAgICAgIHggPSAnMCc7XHJcbiAgICB9XHJcbiAgICBpZiAoeC5pbmRleE9mKCclJykgPj0gMCkge1xyXG4gICAgICB4ID0gYCR7cGFyc2VJbnQoeCwgMTApICogcHJvZ3Jlc3MgKiBydGxGYWN0b3J9JWA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB4ID0gYCR7eCAqIHByb2dyZXNzICogcnRsRmFjdG9yfXB4YDtcclxuICAgIH1cclxuICAgIGlmICh5LmluZGV4T2YoJyUnKSA+PSAwKSB7XHJcbiAgICAgIHkgPSBgJHtwYXJzZUludCh5LCAxMCkgKiBwcm9ncmVzc30lYDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHkgPSBgJHt5ICogcHJvZ3Jlc3N9cHhgO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiBvcGFjaXR5ICE9PSAndW5kZWZpbmVkJyAmJiBvcGFjaXR5ICE9PSBudWxsKSB7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRPcGFjaXR5ID0gb3BhY2l0eSAtIChvcGFjaXR5IC0gMSkgKiAoMSAtIE1hdGguYWJzKHByb2dyZXNzKSk7XHJcbiAgICAgIGVsLnN0eWxlLm9wYWNpdHkgPSBjdXJyZW50T3BhY2l0eTtcclxuICAgIH1cclxuICAgIGxldCB0cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt4fSwgJHt5fSwgMHB4KWA7XHJcbiAgICBpZiAodHlwZW9mIHNjYWxlICE9PSAndW5kZWZpbmVkJyAmJiBzY2FsZSAhPT0gbnVsbCkge1xyXG4gICAgICBjb25zdCBjdXJyZW50U2NhbGUgPSBzY2FsZSAtIChzY2FsZSAtIDEpICogKDEgLSBNYXRoLmFicyhwcm9ncmVzcykpO1xyXG4gICAgICB0cmFuc2Zvcm0gKz0gYCBzY2FsZSgke2N1cnJlbnRTY2FsZX0pYDtcclxuICAgIH1cclxuICAgIGlmIChyb3RhdGUgJiYgdHlwZW9mIHJvdGF0ZSAhPT0gJ3VuZGVmaW5lZCcgJiYgcm90YXRlICE9PSBudWxsKSB7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRSb3RhdGUgPSByb3RhdGUgKiBwcm9ncmVzcyAqIC0xO1xyXG4gICAgICB0cmFuc2Zvcm0gKz0gYCByb3RhdGUoJHtjdXJyZW50Um90YXRlfWRlZylgO1xyXG4gICAgfVxyXG4gICAgZWwuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xyXG4gIH07XHJcbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xyXG4gICAgY29uc3QgeyBlbCwgc2xpZGVzLCBwcm9ncmVzcywgc25hcEdyaWQgfSA9IHN3aXBlcjtcclxuICAgIGVsZW1lbnRDaGlsZHJlbihcclxuICAgICAgZWwsXHJcbiAgICAgICdbZGF0YS1zd2lwZXItcGFyYWxsYXhdLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgteF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC15XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LW9wYWNpdHldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtc2NhbGVdJ1xyXG4gICAgKS5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBzZXRUcmFuc2Zvcm0oc3ViRWwsIHByb2dyZXNzKTtcclxuICAgIH0pO1xyXG4gICAgc2xpZGVzLmZvckVhY2goKHNsaWRlRWwsIHNsaWRlSW5kZXgpID0+IHtcclxuICAgICAgbGV0IHNsaWRlUHJvZ3Jlc3MgPSBzbGlkZUVsLnByb2dyZXNzO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA+IDEgJiYgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSAnYXV0bycpIHtcclxuICAgICAgICBzbGlkZVByb2dyZXNzICs9IE1hdGguY2VpbChzbGlkZUluZGV4IC8gMikgLSBwcm9ncmVzcyAqIChzbmFwR3JpZC5sZW5ndGggLSAxKTtcclxuICAgICAgfVxyXG4gICAgICBzbGlkZVByb2dyZXNzID0gTWF0aC5taW4oTWF0aC5tYXgoc2xpZGVQcm9ncmVzcywgLTEpLCAxKTtcclxuICAgICAgc2xpZGVFbFxyXG4gICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKFxyXG4gICAgICAgICAgJ1tkYXRhLXN3aXBlci1wYXJhbGxheF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC14XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LXldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtb3BhY2l0eV0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC1zY2FsZV0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC1yb3RhdGVdJ1xyXG4gICAgICAgIClcclxuICAgICAgICAuZm9yRWFjaCgoc3ViRWwpID0+IHtcclxuICAgICAgICAgIHNldFRyYW5zZm9ybShzdWJFbCwgc2xpZGVQcm9ncmVzcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gIGNvbnN0IHNldFRyYW5zaXRpb24gPSBmdW5jdGlvbiAoZHVyYXRpb24pIHtcclxuICAgIGlmIChkdXJhdGlvbiA9PT0gdm9pZCAwKSB7X
9266HJcbiAgICAgIGR1cmF0aW9uID0gc3dpcGVyLnBhcmFtcy5zcGVlZDtcclxuICAgIH1cclxuICAgIGNvbnN0IHsgZWwgfSA9IHN3aXBlcjtcclxuICAgIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXHJcbiAgICAgICdbZGF0YS1zd2lwZXItcGFyYWxsYXhdLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgteF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC15XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LW9wYWNpdHldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtc2NhbGVdJ1xyXG4gICAgKS5mb3JFYWNoKChwYXJhbGxheEVsKSA9PiB7XHJcbiAgICAgIGxldCBwYXJhbGxheER1cmF0aW9uID0gcGFyc2VJbnQocGFyYWxsYXhFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LWR1cmF0aW9uJyksIDEwKSB8fCBkdXJhdGlvbjtcclxuICAgICAgaWYgKGR1cmF0aW9uID09PSAwKSBwYXJhbGxheER1cmF0aW9uID0gMDtcclxuICAgICAgcGFyYWxsYXhFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBgJHtwYXJhbGxheER1cmF0aW9ufW1zYDtcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMucGFyYWxsYXguZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgc3dpcGVyLnBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzID0gdHJ1ZTtcclxuICAgIHN3aXBlci5vcmlnaW5hbFBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzID0gdHJ1ZTtcclxuICB9KTtcclxuICBvbignaW5pdCcsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5wYXJhbGxheC5lbmFibGVkKSByZXR1cm47XHJcbiAgICBzZXRUcmFuc2xhdGUoKTtcclxuICB9KTtcclxuICBvbignc2V0VHJhbnNsYXRlJywgKCkgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhcmFsbGF4LmVuYWJsZWQpIHJldHVybjtcclxuICAgIHNldFRyYW5zbGF0ZSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdzZXRUcmFuc2l0aW9uJywgKF9zd2lwZXIsIGR1cmF0aW9uKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMucGFyYWxsYXguZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgc2V0VHJhbnNpdGlvbihkdXJhdGlvbik7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIFpvb20oX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiwgZW1pdCB9ID0gX3JlZjtcclxuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgem9vbToge1xyXG4gICAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgICAgbWF4UmF0aW86IDMsXHJcbiAgICAgIG1pblJhdGlvOiAxLFxyXG4gICAgICB0b2dnbGU6IHRydWUsXHJcbiAgICAgIGNvbnRhaW5lckNsYXNzOiAnc3dpcGVyLXpvb20tY29udGFpbmVyJyxcclxuICAgICAgem9vbWVkU2xpZGVDbGFzczogJ3N3aXBlci1zbGlkZS16b29tZWQnLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBzd2lwZXIuem9vbSA9IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gIH07XHJcbiAgbGV0IGN1cnJlbnRTY2FsZSA9IDE7XHJcbiAgbGV0IGlzU2NhbGluZyA9IGZhbHNlO1xyXG4gIGxldCBmYWtlR2VzdHVyZVRvdWNoZWQ7XHJcbiAgbGV0IGZha2VHZXN0dXJlTW92ZWQ7XHJcbiAgY29uc3QgZXZDYWNoZSA9IFtdO1xyXG4gIGNvbnN0IGdlc3R1cmUgPSB7XHJcbiAgICBvcmlnaW5YOiAwLFxyXG4gICAgb3JpZ2luWTogMCxcclxuICAgIHNsaWRlRWw6IHVuZGVmaW5lZCxcclxuICAgIHNsaWRlV2lkdGg6IHVuZGVmaW5lZCxcclxuICAgIHNsaWRlSGVpZ2h0OiB1bmRlZmluZWQsXHJcbiAgICBpbWFnZUVsOiB1bmRlZmluZWQsXHJcbiAgICBpbWFnZVdyYXBFbDogdW5kZWZpbmVkLFxyXG4gICAgbWF4UmF0aW86IDMsXHJcbiAgfTtcclxuICBjb25zdCBpbWFnZSA9IHtcclxuICAgIGlzVG91Y2hlZDogdW5kZWZpbmVkLFxyXG4gICAgaXNNb3ZlZDogdW5kZWZpbmVkLFxyXG4gICAgY3VycmVudFg6IHVuZGVmaW5lZCxcclxuICAgIGN1cnJlbnRZOiB1bmRlZmluZWQsXHJcbiAgICBtaW5YOiB1bmRlZmluZWQsXHJcbiAgICBtaW5ZOiB1bmRlZmluZWQsXHJcbiAgICBtYXhYOiB1bmRlZmluZWQsXHJcbiAgICBtYXhZOiB1bmRlZmluZWQsXHJcbiAgICB3aWR0aDogdW5kZWZpbmVkLFxyXG4gICAgaGVpZ2h0OiB1bmRlZmluZWQsXHJcbiAgICBzdGFydFg6IHVuZGVmaW5lZCxcclxuICAgIHN0YXJ0WTogdW5kZWZpbmVkLFxyXG4gICAgdG91Y2hlc1N0YXJ0OiB7fSxcclxuICAgIHRvdWNoZXNDdXJyZW50OiB7fSxcclxuICB9O1xyXG4gIGNvbnN0IHZlbG9jaXR5ID0ge1xyXG4gICAgeDogdW5kZWZpbmVkLFxyXG4gICAgeTogdW5kZWZpbmVkLFxyXG4gICAgcHJldlBvc2l0aW9uWDogdW5kZWZpbmVkLFxyXG4gICAgcHJldlBvc2l0aW9uWTogdW5kZWZpbmVkLFxyXG4gICAgcHJldlRpbWU6IHVuZGVmaW5lZCxcclxuICB9O1xyXG4gIGxldCBzY2FsZSA9IDE7XHJcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHN3aXBlci56b29tLCAnc2NhbGUnLCB7XHJcbiAgICBnZXQoKSB7XHJcbiAgICAgIHJldHVybiBzY2FsZTtcclxuICAgIH0sXHJcbiAgICBzZXQodmFsdWUpIHtcclxuICAgICAgaWYgKHNjYWxlICE9PSB2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IGltYWdlRWwgPSBnZXN0dXJlLmltYWdlRWw7XHJcbiAgICAgICAgY29uc3Qgc2xpZGVFbCA9IGdlc3R1cmUuc2xpZGVFbDtcclxuICAgICAgICBlbWl0KCd6b29tQ2hhbmdlJywgdmFsdWUsIGltYWdlRWwsIHNsaWRlRWwpO1xyXG4gICAgICB9XHJcbiAgICAgIHNjYWxlID0gdmFsdWU7XHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGZ1bmN0aW9uIGdldERpc3RhbmNlQmV0d2VlblRvdWNoZXMoKSB7XHJcbiAgICBpZiAoZXZDYWNoZS5sZW5ndGggPCAyKSByZXR1cm4gMTtcclxuICAgIGNvbnN0IHgxID0gZXZDYWNoZVswXS5wYWdlWDtcclxuICAgIGNvbnN0IHkxID0gZXZDYWNoZVswXS5wYWdlWTtcclxuICAgIGNvbnN0IHgyID0gZXZDYWNoZVsxXS5wYWdlWDtcclxuICAgIGNvbnN0IHkyID0gZXZDYWNoZVsxXS5wYWdlWTtcclxuICAgIGNvbnN0IGRpc3R
9266hbmNlID0gTWF0aC5zcXJ0KCh4MiAtIHgxKSAqKiAyICsgKHkyIC0geTEpICoqIDIpO1xyXG4gICAgcmV0dXJuIGRpc3RhbmNlO1xyXG4gIH1cclxuICBmdW5jdGlvbiBnZXRTY2FsZU9yaWdpbigpIHtcclxuICAgIGlmIChldkNhY2hlLmxlbmd0aCA8IDIpXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgeDogbnVsbCxcclxuICAgICAgICB5OiBudWxsLFxyXG4gICAgICB9O1xyXG4gICAgY29uc3QgYm94ID0gZ2VzdHVyZS5pbWFnZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgKGV2Q2FjaGVbMF0ucGFnZVggKyAoZXZDYWNoZVsxXS5wYWdlWCAtIGV2Q2FjaGVbMF0ucGFnZVgpIC8gMiAtIGJveC54KSAvIGN1cnJlbnRTY2FsZSxcclxuICAgICAgKGV2Q2FjaGVbMF0ucGFnZVkgKyAoZXZDYWNoZVsxXS5wYWdlWSAtIGV2Q2FjaGVbMF0ucGFnZVkpIC8gMiAtIGJveC55KSAvIGN1cnJlbnRTY2FsZSxcclxuICAgIF07XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGdldFNsaWRlU2VsZWN0b3IoKSB7XHJcbiAgICByZXR1cm4gc3dpcGVyLmlzRWxlbWVudCA/IGBzd2lwZXItc2xpZGVgIDogYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31gO1xyXG4gIH1cclxuICBmdW5jdGlvbiBldmVudFdpdGhpblNsaWRlKGUpIHtcclxuICAgIGNvbnN0IHNsaWRlU2VsZWN0b3IgPSBnZXRTbGlkZVNlbGVjdG9yKCk7XHJcbiAgICBpZiAoZS50YXJnZXQubWF0Y2hlcyhzbGlkZVNlbGVjdG9yKSkgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAoc3dpcGVyLnNsaWRlcy5maWx0ZXIoKHNsaWRlRWwpID0+IHNsaWRlRWwuY29udGFpbnMoZS50YXJnZXQpKS5sZW5ndGggPiAwKSByZXR1cm4gdHJ1ZTtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgZnVuY3Rpb24gZXZlbnRXaXRoaW5ab29tQ29udGFpbmVyKGUpIHtcclxuICAgIGNvbnN0IHNlbGVjdG9yID0gYC4ke3N3aXBlci5wYXJhbXMuem9vbS5jb250YWluZXJDbGFzc31gO1xyXG4gICAgaWYgKGUudGFyZ2V0Lm1hdGNoZXMoc2VsZWN0b3IpKSByZXR1cm4gdHJ1ZTtcclxuICAgIGlmIChbLi4uc3dpcGVyLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpXS5maWx0ZXIoKGNvbnRhaW5lckVsKSA9PiBjb250YWluZXJFbC5jb250YWlucyhlLnRhcmdldCkpLmxlbmd0aCA+IDApXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLy8gRXZlbnRzXHJcbiAgZnVuY3Rpb24gb25HZXN0dXJlU3RhcnQoZSkge1xyXG4gICAgaWYgKGUucG9pbnRlclR5cGUgPT09ICdtb3VzZScpIHtcclxuICAgICAgZXZDYWNoZS5zcGxpY2UoMCwgZXZDYWNoZS5sZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFldmVudFdpdGhpblNsaWRlKGUpKSByZXR1cm47XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnpvb207XHJcbiAgICBmYWtlR2VzdHVyZVRvdWNoZWQgPSBmYWxzZTtcclxuICAgIGZha2VHZXN0dXJlTW92ZWQgPSBmYWxzZTtcclxuICAgIGV2Q2FjaGUucHVzaChlKTtcclxuICAgIGlmIChldkNhY2hlLmxlbmd0aCA8IDIpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgZmFrZUdlc3R1cmVUb3VjaGVkID0gdHJ1ZTtcclxuICAgIGdlc3R1cmUuc2NhbGVTdGFydCA9IGdldERpc3RhbmNlQmV0d2VlblRvdWNoZXMoKTtcclxuICAgIGlmICghZ2VzdHVyZS5zbGlkZUVsKSB7XHJcbiAgICAgIGdlc3R1cmUuc2xpZGVFbCA9IGUudGFyZ2V0LmNsb3Nlc3QoYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc30sIHN3aXBlci1zbGlkZWApO1xyXG4gICAgICBpZiAoIWdlc3R1cmUuc2xpZGVFbCkgZ2VzdHVyZS5zbGlkZUVsID0gc3dpcGVyLnNsaWRlc1tzd2lwZXIuYWN0aXZlSW5kZXhdO1xyXG4gICAgICBsZXQgaW1hZ2VFbCA9IGdlc3R1cmUuc2xpZGVFbC5xdWVyeVNlbGVjdG9yKGAuJHtwYXJhbXMuY29udGFpbmVyQ2xhc3N9YCk7XHJcbiAgICAgIGlmIChpbWFnZUVsKSB7XHJcbiAgICAgICAgaW1hZ2VFbCA9IGltYWdlRWwucXVlcnlTZWxlY3RvckFsbCgncGljdHVyZSwgaW1nLCBzdmcsIGNhbnZhcywgLnN3aXBlci16b29tLXRhcmdldCcpWzBdO1xyXG4gICAgICB9XHJcbiAgICAgIGdlc3R1cmUuaW1hZ2VFbCA9IGltYWdlRWw7XHJcbiAgICAgIGlmIChpbWFnZUVsKSB7XHJcbiAgICAgICAgZ2VzdHVyZS5pbWFnZVdyYXBFbCA9IGVsZW1lbnRQYXJlbnRzKGdlc3R1cmUuaW1hZ2VFbCwgYC4ke3BhcmFtcy5jb250YWluZXJDbGFzc31gKVswXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBnZXN0dXJlLmltYWdlV3JhcEVsID0gdW5kZWZpbmVkO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghZ2VzdHVyZS5pbWFnZVdyYXBFbCkge1xyXG4gICAgICAgIGdlc3R1cmUuaW1hZ2VFbCA9IHVuZGVmaW5lZDtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgZ2VzdHVyZS5tYXhSYXRpbyA9IGdlc3R1cmUuaW1hZ2VXcmFwRWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci16b29tJykgfHwgcGFyYW1zLm1heFJhdGlvO1xyXG4gICAgfVxyXG4gICAgaWYgKGdlc3R1cmUuaW1hZ2VFbCkge1xyXG4gICAgICBjb25zdCBbb3JpZ2luWCwgb3JpZ2luWV0gPSBnZXRTY2FsZU9yaWdpbigpO1xyXG4gICAgICBnZXN0dXJlLm9yaWdpblggPSBvcmlnaW5YO1xyXG4gICAgICBnZXN0dXJlLm9yaWdpblkgPSBvcmlnaW5ZO1xyXG4gICAgICBnZXN0dXJlLmltYWdlRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gJzBtcyc7XHJcbiAgICB9XHJcbiAgICBpc1NjYWxpbmcgPSB0cnVlO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvbkdlc3R1cmVDaGFuZ2UoZSkge1xyXG4gICAgaWYgKCFldmVudFdpdGhpblNsaWRlKGUpKSByZXR1cm47XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnpvb207XHJcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XHJcbiAgICBjb25zdCBwb2ludGVySW5kZXggPSBldkNhY2hlLmZpbmRJbmRleCgoY2FjaGVkRXYpID0+IGNhY2hlZEV2LnBvaW50ZXJJZCA9PT0gZS5wb2ludGVySWQpO1xyXG4gICAgaWYgKHBvaW50ZXJJbmRleCA+PSAwKSBldkNhY2hlW3BvaW50ZXJJbmRleF0gPSBlO1xyXG4gICAgaWYgKGV2Q2FjaGUubGVuZ3RoIDwgMikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBmYWtlR2VzdHVyZU1vdmVkID0gdHJ1ZTtcclxuICAgIGdlc3R1cmUuc2NhbGVNb3ZlID0gZ2V0RGlzdGFuY2VCZXR3ZWVuVG91Y2hlcygpO1xyXG4gICAgaWYgKCFnZXN0dXJlLmltYWdlRWwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgem9vbS5zY2FsZSA9IChnZXN0dXJlLnNjYWxlTW92ZSAvIGdlc3R1cmUuc2NhbGVTdGFydCkgKiBjdXJyZW50U2NhbGU7XHJcbiAgICBpZiAoem9vbS5zY2FsZSA+IGdlc3R1cmUubWF4UmF0aW8pIHtcclxuICAgICAgem9vbS5zY2FsZSA9IGdlc3R1cmUubWF4UmF0aW8gLSAxICsgKHpvb20uc2NhbGUgLSBnZXN0dXJlLm1heFJhdGlvICsgMSkgKiogMC41O1xyXG4gICAgfVxyXG4gICAgaWYgKHpvb20uc2NhbGUgPCBwYXJhbXMubWluUmF0aW8pIHtcclxuICAgICAgem9vbS5zY2FsZSA9IHBhcmFtcy5taW5SYXRpbyArIDEgLSAocGFyYW1zLm1pblJhdGlvIC0gem9vbS5zY2FsZSArIDEpICoqIDAuNTtcclxuICAgIH1cclxuICAgIGdlc3R1cmUuaW1hZ2VFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKCR7em9vbS5zY2FsZX0pYDtcclxuICB9XHJcbiAgZnVuY3Rpb24gb25HZXN0dXJlRW5kKGUpIHtcclxuICAgIGlmICghZXZlbnRXaXRoaW5TbGlkZShlKSkgcmV0dXJuO1xyXG4gICAgaWYgKGUucG9pbnRlclR5cGUgPT09ICdtb3VzZScgJiYgZS50eXBlID09PSAncG9pbnRlcm91dCcpIHJldHVybjtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcclxuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcclxuICAgIGNvbnN0IHBvaW50ZXJJbmRleCA9IGV2Q2FjaGUuZmluZEluZGV4KChjYWNoZWRFdikgPT4gY2FjaGVkRXYucG9pbnRlcklkID09PSBlLnBvaW50ZXJJZCk7XHJcbiAgICBpZiAocG9pbnRlckluZGV4ID49IDApIGV2Q2FjaGUuc3BsaWNlKHBvaW50ZXJJbmRleCwgMSk7XHJcbiAgICBpZiAoIWZha2VHZXN0dXJlVG91Y2hlZCB8fCAhZmFrZUdlc3R1cmVNb3ZlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBmYWtlR2VzdHVyZVRvdWNoZWQgPSBmYWxzZTtcclxuICAgIGZha2VHZXN0dXJlTW92ZWQgPSBmYWxzZTtcclxuICAgIGlmICghZ2VzdHVyZS5pbWFnZUVsKSByZXR1cm47XHJcbiAgICB6b29tLnNjYWxlID0gTWF0aC5tYXgoTWF0aC5taW4oem9vbS5zY2FsZSwgZ2VzdHVyZS5tYXhSYXRpbyksIHBhcmFtcy5taW5SYXRpbyk7XHJcbiAgICBnZXN0dXJlLmltYWdlRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7c3dpcGVyLnBhcmFtcy5zcGVlZH1tc2A7XHJcbiAgICBnZXN0dXJlLmltYWdlRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgke3pvb20uc2NhbGV9KWA7XHJcbiAgICBjdXJyZW50U2NhbGUgPSB6b29tLnNjYWxlO1xyXG4gICAgaXNTY2FsaW5nID0gZmFsc2U7XHJcbiAgICBpZiAoem9vbS5zY2FsZSA+IDEgJiYgZ2VzdHVyZS5zbGlkZUVsKSB7XHJcbiAgICAgIGdlc3R1cmUuc2xpZGVFbC5jbGFzc0xpc3QuYWRkKGAke3BhcmFtcy56b29tZWRTbGlkZUNsYXNzfWApO1xyXG4gICAgfSBlbHNlIGlmICh6b29tLnNjYWxlIDw9IDEgJiYgZ2VzdHVyZS5zbGlkZUVsKSB7XHJcbiAgICAgIGdlc3R1cmUuc2xpZGVFbC5jbGFzc0xpc3QucmVtb3ZlKGAke3BhcmFtcy56b29tZWRTbGlkZUNsYXNzfWApO1xyXG4gICAgfVxyXG4gICAgaWYgKHpvb20uc2NhbGUgPT09IDEpIHtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5YID0gMDtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5ZID0gMDtcclxuICAgICAgZ2VzdHVyZS5zbGlkZUVsID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gIH1cclxuICBmdW5jdGlvbiBvblRvdWNoU3RhcnQoZSkge1xyXG4gICAgY29uc3QgZGV2aWNlID0gc3dpcGVyLmRldmljZTtcclxuICAgIGlmICghZ2VzdHVyZS5pbWFnZUVsKSByZXR1cm47XHJcbiAgICBpZiAoaW1hZ2UuaXNUb3VjaGVkKSByZXR1cm47XHJcbiAgICBpZiAoZGV2aWNlLmFuZHJvaWQgJiYgZS5jYW5jZWxhYmxlKSBlLnByZXZlbn
9266REZWZhdWx0KCk7XHJcbiAgICBpbWFnZS5pc1RvdWNoZWQgPSB0cnVlO1xyXG4gICAgY29uc3QgZXZlbnQgPSBldkNhY2hlLmxlbmd0aCA+IDAgPyBldkNhY2hlWzBdIDogZTtcclxuICAgIGltYWdlLnRvdWNoZXNTdGFydC54ID0gZXZlbnQucGFnZVg7XHJcbiAgICBpbWFnZS50b3VjaGVzU3RhcnQueSA9IGV2ZW50LnBhZ2VZO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvblRvdWNoTW92ZShlKSB7XHJcbiAgICBpZiAoIWV2ZW50V2l0aGluU2xpZGUoZSkgfHwgIWV2ZW50V2l0aGluWm9vbUNvbnRhaW5lcihlKSkgcmV0dXJuO1xyXG4gICAgY29uc3Qgem9vbSA9IHN3aXBlci56b29tO1xyXG4gICAgaWYgKCFnZXN0dXJlLmltYWdlRWwpIHJldHVybjtcclxuICAgIGlmICghaW1hZ2UuaXNUb3VjaGVkIHx8ICFnZXN0dXJlLnNsaWRlRWwpIHJldHVybjtcclxuICAgIGlmICghaW1hZ2UuaXNNb3ZlZCkge1xyXG4gICAgICBpbWFnZS53aWR0aCA9IGdlc3R1cmUuaW1hZ2VFbC5vZmZzZXRXaWR0aDtcclxuICAgICAgaW1hZ2UuaGVpZ2h0ID0gZ2VzdHVyZS5pbWFnZUVsLm9mZnNldEhlaWdodDtcclxuICAgICAgaW1hZ2Uuc3RhcnRYID0gZ2V0VHJhbnNsYXRlKGdlc3R1cmUuaW1hZ2VXcmFwRWwsICd4JykgfHwgMDtcclxuICAgICAgaW1hZ2Uuc3RhcnRZID0gZ2V0VHJhbnNsYXRlKGdlc3R1cmUuaW1hZ2VXcmFwRWwsICd5JykgfHwgMDtcclxuICAgICAgZ2VzdHVyZS5zbGlkZVdpZHRoID0gZ2VzdHVyZS5zbGlkZUVsLm9mZnNldFdpZHRoO1xyXG4gICAgICBnZXN0dXJlLnNsaWRlSGVpZ2h0ID0gZ2VzdHVyZS5zbGlkZUVsLm9mZnNldEhlaWdodDtcclxuICAgICAgZ2VzdHVyZS5pbWFnZVdyYXBFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMG1zJztcclxuICAgIH1cclxuICAgIC8vIERlZmluZSBpZiB3ZSBuZWVkIGltYWdlIGRyYWdcclxuICAgIGNvbnN0IHNjYWxlZFdpZHRoID0gaW1hZ2Uud2lkdGggKiB6b29tLnNjYWxlO1xyXG4gICAgY29uc3Qgc2NhbGVkSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0ICogem9vbS5zY2FsZTtcclxuICAgIGlmIChzY2FsZWRXaWR0aCA8IGdlc3R1cmUuc2xpZGVXaWR0aCAmJiBzY2FsZWRIZWlnaHQgPCBnZXN0dXJlLnNsaWRlSGVpZ2h0KSByZXR1cm47XHJcbiAgICBpbWFnZS5taW5YID0gTWF0aC5taW4oZ2VzdHVyZS5zbGlkZVdpZHRoIC8gMiAtIHNjYWxlZFdpZHRoIC8gMiwgMCk7XHJcbiAgICBpbWFnZS5tYXhYID0gLWltYWdlLm1pblg7XHJcbiAgICBpbWFnZS5taW5ZID0gTWF0aC5taW4oZ2VzdHVyZS5zbGlkZUhlaWdodCAvIDIgLSBzY2FsZWRIZWlnaHQgLyAyLCAwKTtcclxuICAgIGltYWdlLm1heFkgPSAtaW1hZ2UubWluWTtcclxuICAgIGltYWdlLnRvdWNoZXNDdXJyZW50LnggPSBldkNhY2hlLmxlbmd0aCA+IDAgPyBldkNhY2hlWzBdLnBhZ2VYIDogZS5wYWdlWDtcclxuICAgIGltYWdlLnRvdWNoZXNDdXJyZW50LnkgPSBldkNhY2hlLmxlbmd0aCA+IDAgPyBldkNhY2hlWzBdLnBhZ2VZIDogZS5wYWdlWTtcclxuICAgIGNvbnN0IHRvdWNoZXNEaWZmID0gTWF0aC5tYXgoXHJcbiAgICAgIE1hdGguYWJzKGltYWdlLnRvdWNoZXNDdXJyZW50LnggLSBpbWFnZS50b3VjaGVzU3RhcnQueCksXHJcbiAgICAgIE1hdGguYWJzKGltYWdlLnRvdWNoZXNDdXJyZW50LnkgLSBpbWFnZS50b3VjaGVzU3RhcnQueSlcclxuICAgICk7XHJcbiAgICBpZiAodG91Y2hlc0RpZmYgPiA1KSB7XHJcbiAgICAgIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoIWltYWdlLmlzTW92ZWQgJiYgIWlzU2NhbGluZykge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgc3dpcGVyLmlzSG9yaXpvbnRhbCgpICYmXHJcbiAgICAgICAgKChNYXRoLmZsb29yKGltYWdlLm1pblgpID09PSBNYXRoLmZsb29yKGltYWdlLnN0YXJ0WCkgJiYgaW1hZ2UudG91Y2hlc0N1cnJlbnQueCA8IGltYWdlLnRvdWNoZXNTdGFydC54KSB8fFxyXG4gICAgICAgICAgKE1hdGguZmxvb3IoaW1hZ2UubWF4WCkgPT09IE1hdGguZmxvb3IoaW1hZ2Uuc3RhcnRYKSAmJiBpbWFnZS50b3VjaGVzQ3VycmVudC54ID4gaW1hZ2UudG91Y2hlc1N0YXJ0LngpKVxyXG4gICAgICApIHtcclxuICAgICAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgaWYgKFxyXG4gICAgICAgICFzd2lwZXIuaXNIb3Jpem9udGFsKCkgJiZcclxuICAgICAgICAoKE1hdGguZmxvb3IoaW1hZ2UubWluWSkgPT09IE1hdGguZmxvb3IoaW1hZ2Uuc3RhcnRZKSAmJiBpbWFnZS50b3VjaGVzQ3VycmVudC55IDwgaW1hZ2UudG91Y2hlc1N0YXJ0LnkpIHx8XHJcbiAgICAgICAgICAoTWF0aC5mbG9vcihpbWFnZS5tYXhZKSA9PT0gTWF0aC5mbG9vcihpbWFnZS5zdGFydFkpICYmIGltYWdlLnRvdWNoZXNDdXJyZW50LnkgPiBpbWFnZS50b3VjaGVzU3RhcnQueSkpXHJcbiAgICAgICkge1xyXG4gICAgICAgIGltYWdlLmlzVG91Y2hlZCA9IGZhbHNlO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGUuY2FuY2VsYWJsZSkge1xyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgaW1hZ2UuaXNNb3ZlZCA9IHRydWU7XHJcbiAgICBjb25zdCBzY2FsZVJhdGlvID0gKHpvb20uc2NhbGUgLSBjdXJyZW50U2NhbGUpIC8gKGdlc3R1cmUubWF4UmF0aW8gLSBzd2lwZXIucGFyYW1zLnpvb20ubWluUmF0aW8pO1xyXG4gICAgY29uc3QgeyBvcmlnaW5YLCBvcmlnaW5ZIH0gPSBnZXN0dXJlO1xyXG4gICAgaW1hZ2UuY3VycmVudFggPVxyXG4gICAgICBpbWFnZS50b3VjaGVzQ3VycmVudC54IC0gaW1hZ2UudG91Y2hlc1N0YXJ0LnggKyBpbWFnZS5zdGFydFggKyBzY2FsZVJhdGlvICogKGltYWdlLndpZHRoIC0gb3JpZ2luWCAqIDIpO1xyXG4gICAgaW1hZ2UuY3VycmVudFkgPVxyXG4gICAgICBpbWFnZS50b3VjaGVzQ3VycmVudC55IC0gaW1hZ2UudG91Y2hlc1N0YXJ0LnkgKyBpbWFnZS5zdGFydFkgKyBzY2FsZVJhdGlvICogKGltYWdlLmhlaWdodCAtIG9yaWdpblkgKiAyKTtcclxuICAgIGlmIChpbWFnZS5jdXJyZW50WCA8IGltYWdlLm1pblgpIHtcclxuICAgICAgaW1hZ2UuY3VycmVudFggPSBpbWFnZS5taW5YICsgMSAtIChpbWFnZS5taW5YIC0gaW1hZ2UuY3VycmVudFggKyAxKSAqKiAwLjg7XHJcbiAgICB9XHJcbiAgICBpZiAoaW1hZ2UuY3VycmVudFggPiBpbWFnZS5tYXhYKSB7XHJcbiAgICAgIGltYWdlLmN1cnJlbnRYID0gaW1hZ2UubWF4WCAtIDEgKyAoaW1hZ2UuY3VycmVudFggLSBpbWFnZS5tYXhYICsgMSkgKiogMC44O1xyXG4gICAgfVxyXG4gICAgaWYgKGltYWdlLmN1cnJlbnRZIDwgaW1hZ2UubWluWSkge1xyXG4gICAgICBpbWFnZS5jdXJyZW50WSA9IGltYWdlLm1pblkgKyAxIC0gKGltYWdlLm1pblkgLSBpbWFnZS5jdXJyZW50WSArIDEpICoqIDAuODtcclxuICAgIH1cclxuICAgIGlmIChpbWFnZS5jdXJyZW50WSA+IGltYWdlLm1heFkpIHtcclxuICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS5tYXhZIC0gMSArIChpbWFnZS5jdXJyZW50WSAtIGltYWdlLm1heFkgKyAxKSAqKiAwLjg7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVmVsb2NpdHlcclxuICAgIGlmICghdmVsb2NpdHkucHJldlBvc2l0aW9uWCkgdmVsb2NpdHkucHJldlBvc2l0aW9uWCA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lng7XHJcbiAgICBpZiAoIXZlbG9jaXR5LnByZXZQb3NpdGlvblkpIHZlbG9jaXR5LnByZXZQb3NpdGlvblkgPSBpbWFnZS50b3VjaGVzQ3VycmVudC55O1xyXG4gICAgaWYgKCF2ZWxvY2l0eS5wcmV2VGltZSkgdmVsb2NpdHkucHJldlRpbW
9266UgPSBEYXRlLm5vdygpO1xyXG4gICAgdmVsb2NpdHkueCA9IChpbWFnZS50b3VjaGVzQ3VycmVudC54IC0gdmVsb2NpdHkucHJldlBvc2l0aW9uWCkgLyAoRGF0ZS5ub3coKSAtIHZlbG9jaXR5LnByZXZUaW1lKSAvIDI7XHJcbiAgICB2ZWxvY2l0eS55ID0gKGltYWdlLnRvdWNoZXNDdXJyZW50LnkgLSB2ZWxvY2l0eS5wcmV2UG9zaXRpb25ZKSAvIChEYXRlLm5vdygpIC0gdmVsb2NpdHkucHJldlRpbWUpIC8gMjtcclxuICAgIGlmIChNYXRoLmFicyhpbWFnZS50b3VjaGVzQ3VycmVudC54IC0gdmVsb2NpdHkucHJldlBvc2l0aW9uWCkgPCAyKSB2ZWxvY2l0eS54ID0gMDtcclxuICAgIGlmIChNYXRoLmFicyhpbWFnZS50b3VjaGVzQ3VycmVudC55IC0gdmVsb2NpdHkucHJldlBvc2l0aW9uWSkgPCAyKSB2ZWxvY2l0eS55ID0gMDtcclxuICAgIHZlbG9jaXR5LnByZXZQb3NpdGlvblggPSBpbWFnZS50b3VjaGVzQ3VycmVudC54O1xyXG4gICAgdmVsb2NpdHkucHJldlBvc2l0aW9uWSA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lnk7XHJcbiAgICB2ZWxvY2l0eS5wcmV2VGltZSA9IERhdGUubm93KCk7XHJcbiAgICBnZXN0dXJlLmltYWdlV3JhcEVsLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgke2ltYWdlLmN1cnJlbnRYfXB4LCAke2ltYWdlLmN1cnJlbnRZfXB4LDApYDtcclxuICB9XHJcbiAgZnVuY3Rpb24gb25Ub3VjaEVuZCgpIHtcclxuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcclxuICAgIGlmICghZ2VzdHVyZS5pbWFnZUVsKSByZXR1cm47XHJcbiAgICBpZiAoIWltYWdlLmlzVG91Y2hlZCB8fCAhaW1hZ2UuaXNNb3ZlZCkge1xyXG4gICAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgICAgaW1hZ2UuaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcclxuICAgIGltYWdlLmlzTW92ZWQgPSBmYWxzZTtcclxuICAgIGxldCBtb21lbnR1bUR1cmF0aW9uWCA9IDMwMDtcclxuICAgIGxldCBtb21lbnR1bUR1cmF0aW9uWSA9IDMwMDtcclxuICAgIGNvbnN0IG1vbWVudHVtRGlzdGFuY2VYID0gdmVsb2NpdHkueCAqIG1vbWVudHVtRHVyYXRpb25YO1xyXG4gICAgY29uc3QgbmV3UG9zaXRpb25YID0gaW1hZ2UuY3VycmVudFggKyBtb21lbnR1bURpc3RhbmNlWDtcclxuICAgIGNvbnN0IG1vbWVudHVtRGlzdGFuY2VZID0gdmVsb2NpdHkueSAqIG1vbWVudHVtRHVyYXRpb25ZO1xyXG4gICAgY29uc3QgbmV3UG9zaXRpb25ZID0gaW1hZ2UuY3VycmVudFkgKyBtb21lbnR1bURpc3RhbmNlWTtcclxuXHJcbiAgICAvLyBGaXggZHVyYXRpb25cclxuICAgIGlmICh2ZWxvY2l0eS54ICE9PSAwKSBtb21lbnR1bUR1cmF0aW9uWCA9IE1hdGguYWJzKChuZXdQb3NpdGlvblggLSBpbWFnZS5jdXJyZW50WCkgLyB2ZWxvY2l0eS54KTtcclxuICAgIGlmICh2ZWxvY2l0eS55ICE9PSAwKSBtb21lbnR1bUR1cmF0aW9uWSA9IE1hdGguYWJzKChuZXdQb3NpdGlvblkgLSBpbWFnZS5jdXJyZW50WSkgLyB2ZWxvY2l0eS55KTtcclxuICAgIGNvbnN0IG1vbWVudHVtRHVyYXRpb24gPSBNYXRoLm1heChtb21lbnR1bUR1cmF0aW9uWCwgbW9tZW50dW1EdXJhdGlvblkpO1xyXG4gICAgaW1hZ2UuY3VycmVudFggPSBuZXdQb3NpdGlvblg7XHJcbiAgICBpbWFnZS5jdXJyZW50WSA9IG5ld1Bvc2l0aW9uWTtcclxuICAgIC8vIERlZmluZSBpZiB3ZSBuZWVkIGltYWdlIGRyYWdcclxuICAgIGNvbnN0IHNjYWxlZFdpZHRoID0gaW1hZ2Uud2lkdGggKiB6b29tLnNjYWxlO1xyXG4gICAgY29uc3Qgc2NhbGVkSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0ICogem9vbS5zY2FsZTtcclxuICAgIGltYWdlLm1pblggPSBNYXRoLm1pbihnZXN0dXJlLnNsaWRlV2lkdGggLyAyIC0gc2NhbGVkV2lkdGggLyAyLCAwKTtcclxuICAgIGltYWdlLm1heFggPSAtaW1hZ2UubWluWDtcclxuICAgIGltYWdlLm1pblkgPSBNYXRoLm1pbihnZXN0dXJlLnNsaWRlSGVpZ2h0IC8gMiAtIHNjYWxlZEhlaWdodCAvIDIsIDApO1xyXG4gICAgaW1hZ2UubWF4WSA9IC1pbWFnZS5taW5ZO1xyXG4gICAgaW1hZ2UuY3VycmVudFggPSBNYXRoLm1heChNYXRoLm1pbihpbWFnZS5jdXJyZW50WCwgaW1hZ2UubWF4WCksIGltYWdlLm1pblgpO1xyXG4gICAgaW1hZ2UuY3VycmVudFkgPSBNYXRoLm1heChNYXRoLm1pbihpbWFnZS5jdXJyZW50WSwgaW1hZ2UubWF4WSksIGltYWdlLm1pblkpO1xyXG4gICAgZ2VzdHVyZS5pbWFnZVdyYXBFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBgJHttb21lbnR1bUR1cmF0aW9ufW1zYDtcclxuICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7aW1hZ2UuY3VycmVudFh9cHgsICR7aW1hZ2UuY3VycmVudFl9cHgsMClgO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvblRyYW5zaXRpb25FbmQoKSB7XHJcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XHJcbiAgICBpZiAoZ2VzdHVyZS5zbGlkZUVsICYmIHN3aXBlci5hY3RpdmVJbmRleCAhPT0gc3dpcGVyLnNsaWRlcy5pbmRleE9mKGdlc3R1cmUuc2xpZGVFbCkpIHtcclxuICAgICAgaWYgKGdlc3R1cmUuaW1hZ2VFbCkge1xyXG4gICAgICAgIGdlc3R1cmUuaW1hZ2VFbC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKDEpJztcclxuICAgICAgfVxyXG4gICAgICBpZiAoZ2VzdHVyZS5pbWFnZVdyYXBFbCkge1xyXG4gICAgICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwuc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZTNkKDAsMCwwKSc7XHJcbiAgICAgIH1cclxuICAgICAgZ2VzdHVyZS5zbGlkZUVsLmNsYXNzTGlzdC5yZW1vdmUoYCR7c3dpcGVyLnBhcmFtcy56b29tLnpvb21lZFNsaWRlQ2xhc3N9YCk7XHJcbiAgICAgIHpvb20uc2NhbGUgPSAxO1xyXG4gICAgICBjdXJyZW50U2NhbGUgPSAxO1xyXG4gICAgICBnZXN0dXJlLnNsaWRlRWwgPSB1bmRlZmluZWQ7XHJcbiAgICAgIGdlc3R1cmUuaW1hZ2VFbCA9IHVuZGVmaW5lZDtcclxuICAgICAgZ2VzdHVyZS5pbWFnZVdyYXBFbCA9IHVuZGVmaW5lZDtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5YID0gMDtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5ZID0gMDtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gem9vbUluKGUpIHtcclxuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcclxuICAgIGlmICghZ2VzdHVyZS5zbGlkZUVsKSB7XHJcbiAgICAgIGlmIChlICYmIGUudGFyZ2V0KSB7XHJcbiAgICAgICAgZ2VzdHVyZS5zbGlkZUVsID0gZS50YXJnZXQuY2xvc2VzdChgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfSwgc3dpcGVyLXNsaWRlYCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFnZXN0dXJlLnNsaWRlRWwpIHtcclxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkICYmIHN3aXBlci52aXJ0dWFsKSB7XHJcbiAgICAgICAgICBnZXN0dXJlLnNsaWRlRWwgPSBlbGVtZW50Q2hpbGRyZW4oc3dpcGVyLnNsaWRlc0VsLCBgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzfWApWzBdO1xyXG4gICAgICAgI
9266H0gZWxzZSB7XHJcbiAgICAgICAgICBnZXN0dXJlLnNsaWRlRWwgPSBzd2lwZXIuc2xpZGVzW3N3aXBlci5hY3RpdmVJbmRleF07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGxldCBpbWFnZUVsID0gZ2VzdHVyZS5zbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoYC4ke3BhcmFtcy5jb250YWluZXJDbGFzc31gKTtcclxuICAgICAgaWYgKGltYWdlRWwpIHtcclxuICAgICAgICBpbWFnZUVsID0gaW1hZ2VFbC5xdWVyeVNlbGVjdG9yQWxsKCdwaWN0dXJlLCBpbWcsIHN2ZywgY2FudmFzLCAuc3dpcGVyLXpvb20tdGFyZ2V0JylbMF07XHJcbiAgICAgIH1cclxuICAgICAgZ2VzdHVyZS5pbWFnZUVsID0gaW1hZ2VFbDtcclxuICAgICAgaWYgKGltYWdlRWwpIHtcclxuICAgICAgICBnZXN0dXJlLmltYWdlV3JhcEVsID0gZWxlbWVudFBhcmVudHMoZ2VzdHVyZS5pbWFnZUVsLCBgLiR7cGFyYW1zLmNvbnRhaW5lckNsYXNzfWApWzBdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICghZ2VzdHVyZS5pbWFnZUVsIHx8ICFnZXN0dXJlLmltYWdlV3JhcEVsKSByZXR1cm47XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcclxuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS50b3VjaEFjdGlvbiA9ICdub25lJztcclxuICAgIH1cclxuICAgIGdlc3R1cmUuc2xpZGVFbC5jbGFzc0xpc3QuYWRkKGAke3BhcmFtcy56b29tZWRTbGlkZUNsYXNzfWApO1xyXG4gICAgbGV0IHRvdWNoWDtcclxuICAgIGxldCB0b3VjaFk7XHJcbiAgICBsZXQgb2Zmc2V0WDtcclxuICAgIGxldCBvZmZzZXRZO1xyXG4gICAgbGV0IGRpZmZYO1xyXG4gICAgbGV0IGRpZmZZO1xyXG4gICAgbGV0IHRyYW5zbGF0ZVg7XHJcbiAgICBsZXQgdHJhbnNsYXRlWTtcclxuICAgIGxldCBpbWFnZVdpZHRoO1xyXG4gICAgbGV0IGltYWdlSGVpZ2h0O1xyXG4gICAgbGV0IHNjYWxlZFdpZHRoO1xyXG4gICAgbGV0IHNjYWxlZEhlaWdodDtcclxuICAgIGxldCB0cmFuc2xhdGVNaW5YO1xyXG4gICAgbGV0IHRyYW5zbGF0ZU1pblk7XHJcbiAgICBsZXQgdHJhbnNsYXRlTWF4WDtcclxuICAgIGxldCB0cmFuc2xhdGVNYXhZO1xyXG4gICAgbGV0IHNsaWRlV2lkdGg7XHJcbiAgICBsZXQgc2xpZGVIZWlnaHQ7XHJcbiAgICBpZiAodHlwZW9mIGltYWdlLnRvdWNoZXNTdGFydC54ID09PSAndW5kZWZpbmVkJyAmJiBlKSB7XHJcbiAgICAgIHRvdWNoWCA9IGUucGFnZVg7XHJcbiAgICAgIHRvdWNoWSA9IGUucGFnZVk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0b3VjaFggPSBpbWFnZS50b3VjaGVzU3RhcnQueDtcclxuICAgICAgdG91Y2hZID0gaW1hZ2UudG91Y2hlc1N0YXJ0Lnk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBmb3JjZVpvb21SYXRpbyA9IHR5cGVvZiBlID09PSAnbnVtYmVyJyA/IGUgOiBudWxsO1xyXG4gICAgaWYgKGN1cnJlbnRTY2FsZSA9PT0gMSAmJiBmb3JjZVpvb21SYXRpbykge1xyXG4gICAgICB0b3VjaFggPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRvdWNoWSA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHpvb20uc2NhbGUgPSBmb3JjZVpvb21SYXRpbyB8fCBnZXN0dXJlLmltYWdlV3JhcEVsLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItem9vbScpIHx8IHBhcmFtcy5tYXhSYXRpbztcclxuICAgIGN1cnJlbnRTY2FsZSA9IGZvcmNlWm9vbVJhdGlvIHx8IGdlc3R1cmUuaW1hZ2VXcmFwRWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci16b29tJykgfHwgcGFyYW1zLm1heFJhdGlvO1xyXG4gICAgaWYgKGUgJiYgIShjdXJyZW50U2NhbGUgPT09IDEgJiYgZm9yY2Vab29tUmF0aW8pKSB7XHJcbiAgICAgIHNsaWRlV2lkdGggPSBnZXN0dXJlLnNsaWRlRWwub2Zmc2V0V2lkdGg7XHJcbiAgICAgIHNsaWRlSGVpZ2h0ID0gZ2VzdHVyZS5zbGlkZUVsLm9mZnNldEhlaWdodDtcclxuICAgICAgb2Zmc2V0WCA9IGVsZW1lbnRPZmZzZXQoZ2VzdHVyZS5zbGlkZUVsKS5sZWZ0ICsgd2luZG93LnNjcm9sbFg7XHJcbiAgICAgIG9mZnNldFkgPSBlbGVtZW50T2Zmc2V0KGdlc3R1cmUuc2xpZGVFbCkudG9wICsgd2luZG93LnNjcm9sbFk7XHJcbiAgICAgIGRpZmZYID0gb2Zmc2V0WCArIHNsaWRlV2lkdGggLyAyIC0gdG91Y2hYO1xyXG4gICAgICBkaWZmWSA9IG9mZnNldFkgKyBzbGlkZUhlaWdodCAvIDIgLSB0b3VjaFk7XHJcbiAgICAgIGltYWdlV2lkdGggPSBnZXN0dXJlLmltYWdlRWwub2Zmc2V0V2lkdGg7XHJcbiAgICAgIGltYWdlSGVpZ2h0ID0gZ2VzdHVyZS5pbWFnZUVsLm9mZnNldEhlaWdodDtcclxuICAgICAgc2NhbGVkV2lkdGggPSBpbWFnZVdpZHRoICogem9vbS5zY2FsZTtcclxuICAgICAgc2NhbGVkSGVpZ2h0ID0gaW1hZ2VIZWlnaHQgKiB6b29tLnNjYWxlO1xyXG4gICAgICB0cmFuc2xhdGVNaW5YID0gTWF0aC5taW4oc2xpZGVXaWR0aCAvIDIgLSBzY2FsZWRXaWR0aCAvIDIsIDApO1xyXG4gICAgICB0cmFuc2xhdGVNaW5ZID0gTWF0aC5taW4oc2xpZGVIZWlnaHQgLyAyIC0gc2NhbGVkSGVpZ2h0IC8gMiwgMCk7XHJcbiAgICAgIHRyYW5zbGF0ZU1heFggPSAtdHJhbnNsYXRlTWluWDtcclxuICAgICAgdHJhbnNsYXRlTWF4WSA9IC10cmFuc2xhdGVNaW5ZO1xyXG4gICAgICB0cmFuc2xhdGVYID0gZGlmZlggKiB6b29tLnNjYWxlO1xyXG4gICAgICB0cmFuc2xhdGVZID0gZGlmZlkgKiB6b29tLnNjYWxlO1xyXG4gICAgICBpZiAodHJhbnNsYXRlWCA8IHRyYW5zbGF0ZU1pblgpIHtcclxuICAgICAgICB0cmFuc2xhdGVYID0gdHJhbnNsYXRlTWluWDtcclxuICAgICAgfVxyXG4gICAgICBpZiAodHJhbnNsYXRlWCA+IHRyYW5zbGF0ZU1heFgpIHtcclxuICAgICAgICB0cmFuc2xhdGVYID0gdHJhbnNsYXRlTWF4WDtcclxuICAgICAgfVxyXG4gICAgICBpZiAodHJhbnNsYXRlWSA8IHRyYW5zbGF0ZU1pblkpIHtcclxuICAgICAgICB0cmFuc2xhdGVZID0gdHJhbnNsYXRlTWluWTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodHJhbnNsYXRlWSA+IHRyYW5zbGF0ZU1heFkpIHtcclxuICAgICAgICB0cmFuc2xhdGVZID0gdHJhbnNsYXRlTWF4WTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdHJhbnNsYXRlWCA9IDA7XHJcbiAgICAgIHRyYW5zbGF0ZVkgPSAwO1xyXG4gICAgfVxyXG4gICAgaWYgKGZvcmNlWm9vbVJhdGlvICYmIHpvb20uc2NhbGUgPT09IDEpIHtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5YID0gMDtcclxuICAgICAgZ2VzdHVyZS5vcmlnaW5ZID0gMDtcclxuICAgIH1cclxuICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gJzMwMG1zJztcclxuICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7dHJhbnNsYXRlWH1weCwgJHt0cmFuc2xhdGVZfXB4LDApYDtcclxuICAgIGdlc3R1cmUuaW1hZ2VFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMzAwbXMnO1xyXG4gICAgZ2VzdHVyZS5pbWFnZUVsLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoJHt6b29tLnNjYWxlfSlgO1xyXG4gIH1cclxuICBmdW5jdGlvbiB6b29tT3V0KCkge1xyXG4gICAgY29uc3Qgem9vbSA9IHN3aXBlci56b29tO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy56b29tO1xyXG4gICAgaWYgKCFnZXN0dXJlLnNsaWRlRWwpIHtcclxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCAmJiBzd2lwZXIudmlydHVhbCkge1xyXG4gICAgICAgIGdlc3R1cmUuc2xpZGVFbCA9IGVsZW1lbnRDaGlsZHJlbihzd2lwZXIuc2xpZGVzRWwsIGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3N9YClbMF07XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZ2VzdHVyZS5zbGlkZUVsID0gc3dpcGVyLnNsaWRlc1tzd2lwZXIuYWN0aXZlSW5kZXhdO1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBpbWFnZUVsID0gZ2VzdHVyZS5zbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoYC4ke3BhcmFtcy5jb250YWluZXJDbGFzc31gKTtcclxuICAgICAgaWYgKGltYWdlRWwpIHtcclxuICAgICAgICBpbWFnZUVsID0gaW1hZ2VFbC5xdWVyeVNlbGVjdG9yQWxsKCdwaWN0dXJlLCBpbWcsIHN2ZywgY2FudmFzLCAuc3dpcGVyLXpvb20tdGFyZ2V0JylbMF07XHJcbiAgICAgIH1cclxuICAgICAgZ2VzdHVyZS5pbWFnZUVsID0gaW1hZ2VFbDtcclxuICAgICAgaWYgKGltYWdlRWwpIHtcclxuICAgICAgICBnZXN0dXJlLmltYWdlV3JhcEVsID0gZWxlbWVudFBhcmVudHMoZ2VzdHVyZS5pbWFnZUVsLCBgLiR7cGFyYW1zLmNvbnRhaW5lckNsYXNzfWApWzBdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGdlc3R1cmUuaW1hZ2VXcmFwRWwgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICghZ2VzdHVyZS5pbWFnZUVsIHx8ICFnZXN0dXJlLmltYWdlV3JhcEVsKSByZXR1cm47XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUub3ZlcmZsb3cgPSAnJztcclxuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS50b3VjaEFjdGlvbiA9ICcnO1xyXG4gICAgfVxyXG4gICAgem9vbS5zY2FsZSA9IDE7XHJcbiAgICBjdXJyZW50U2NhbGUgPSAxO1xyXG4gICAgZ2VzdHVyZS5pbWFnZVdyYXBFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMzAwbXMnO1xyXG4gICAgZ2VzdHVyZS5pbWFnZVdyYXBFbC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlM2QoMCwwLDApJztcclxuICAgIGdlc3R1cmUuaW1hZ2VFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnMzAwbXMnO1xyXG4gICAgZ2VzdHVyZS5pbWFnZUVsLnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoMSknO1xyXG4gICAgZ2VzdHVyZS5zbGlkZUVsLmNsYXNzTGlzdC5yZW1vdmUoYCR7cGFyYW1zLnpvb21lZFNsaWRlQ2xhc3N9YCk7XHJcbiAgICBnZXN0dXJlLnNsaWRlRWwgPSB1bmRlZmluZWQ7XHJcbiAgICBnZXN0dXJlLm9yaWdpblggPSAwO1xyXG4gICAgZ2VzdHVyZS5vcmlnaW5ZID0gMDtcclxuICB9XHJcblxyXG4gIC8vIFRvZ2dsZSBab29tXHJcbiAgZnVuY3Rpb24gem9vbVRvZ2dsZShlKSB7XHJcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XHJcbiAgICBpZiAoem9vbS5zY2FsZSAmJiB6b29tLnNjYWxlICE9PSAxKSB7XHJcbiAgICAgIC8vIFpvb20gT3V0XHJcbiAgICAgIHpvb21PdXQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFpvb20gSW5cclxuICAgICAgem9vbUluKGUpO1xyXG4gICAgfVxyXG4gIH1cclxuICBmdW5jdGlvbiBnZXRMaXN0ZW5lcnMoKSB7XHJcbiAgICBjb25zdCBwYXNzaXZlTGlzdGVuZXIgPSBzd2lwZXIucGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnNcclxuICAgICAgPyB7XHJcbiAgICAgICAgICBwYXNzaXZlOiB0cnVlLFxyXG4gICAgICAgICAgY2FwdHVyZTogZmFsc2UsXHJcbiAgICAgICAgfVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgY29uc3QgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSA9IHN3aXBlci5wYXJhbXMucGFzc2l2ZUxpc3RlbmVyc1xyXG4gICAgICA/IHtcclxuICAgICAgICAgI
9266HBhc3NpdmU6IGZhbHNlLFxyXG4gICAgICAgICAgY2FwdHVyZTogdHJ1ZSxcclxuICAgICAgICB9XHJcbiAgICAgIDogdHJ1ZTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHBhc3NpdmVMaXN0ZW5lcixcclxuICAgICAgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvLyBBdHRhY2gvRGV0YWNoIEV2ZW50c1xyXG4gIGZ1bmN0aW9uIGVuYWJsZSgpIHtcclxuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcclxuICAgIGlmICh6b29tLmVuYWJsZWQpIHJldHVybjtcclxuICAgIHpvb20uZW5hYmxlZCA9IHRydWU7XHJcbiAgICBjb25zdCB7IHBhc3NpdmVMaXN0ZW5lciwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSB9ID0gZ2V0TGlzdGVuZXJzKCk7XHJcblxyXG4gICAgLy8gU2NhbGUgaW1hZ2VcclxuICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvbkdlc3R1cmVTdGFydCwgcGFzc2l2ZUxpc3RlbmVyKTtcclxuICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvbkdlc3R1cmVDaGFuZ2UsIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUpO1xyXG4gICAgWydwb2ludGVydXAnLCAncG9pbnRlcmNhbmNlbCcsICdwb2ludGVyb3V0J10uZm9yRWFjaCgoZXZlbnROYW1lKSA9PiB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIG9uR2VzdHVyZUVuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIE1vdmUgaW1hZ2VcclxuICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvblRvdWNoTW92ZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGRpc2FibGUoKSB7XHJcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XHJcbiAgICBpZiAoIXpvb20uZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgem9vbS5lbmFibGVkID0gZmFsc2U7XHJcbiAgICBjb25zdCB7IHBhc3NpdmVMaXN0ZW5lciwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSB9ID0gZ2V0TGlzdGVuZXJzKCk7XHJcblxyXG4gICAgLy8gU2NhbGUgaW1hZ2VcclxuICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvbkdlc3R1cmVTdGFydCwgcGFzc2l2ZUxpc3RlbmVyKTtcclxuICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvbkdlc3R1cmVDaGFuZ2UsIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUpO1xyXG4gICAgWydwb2ludGVydXAnLCAncG9pbnRlcmNhbmNlbCcsICdwb2ludGVyb3V0J10uZm9yRWFjaCgoZXZlbnROYW1lKSA9PiB7XHJcbiAgICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIG9uR2VzdHVyZUVuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIE1vdmUgaW1hZ2VcclxuICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvblRvdWNoTW92ZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XHJcbiAgfVxyXG4gIG9uKCdpbml0JywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkKSB7XHJcbiAgICAgIGVuYWJsZSgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgZGlzYWJsZSgpO1xyXG4gIH0pO1xyXG4gIG9uKCd0b3VjaFN0YXJ0JywgKF9zLCBlKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlci56b29tLmVuYWJsZWQpIHJldHVybjtcclxuICAgIG9uVG91Y2hTdGFydChlKTtcclxuICB9KTtcclxuICBvbigndG91Y2hFbmQnLCAoX3MsIGUpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnpvb20uZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgb25Ub3VjaEVuZCgpO1xyXG4gIH0pO1xyXG4gIG9uKCdkb3VibGVUYXAnLCAoX3MsIGUpID0+IHtcclxuICAgIGlmICghc3dpcGVyLmFuaW1hdGluZyAmJiBzd2lwZXIucGFyYW1zLnpvb20uZW5hYmxlZCAmJiBzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS50b2dnbGUpIHtcclxuICAgICAgem9vbVRvZ2dsZShlKTtcclxuICAgIH1cclxuICB9KTtcclxuICBvbigndHJhbnNpdGlvbkVuZCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkKSB7XHJcbiAgICAgIG9uVHJhbnNpdGlvbkVuZCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdzbGlkZUNoYW5nZScsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICBvblRyYW5zaXRpb25FbmQoKTtcclxuICAgIH1cclxuICB9KTtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlci56b29tLCB7XHJcbiAgICBlbmFibGUsXHJcbiAgICBkaXNhYmxlLFxyXG4gICAgaW46IHpvb21JbixcclxuICAgIG91dDogem9vbU91dCxcclxuICAgIHRvZ2dsZTogem9vbVRvZ2dsZSxcclxuICB9KTtcclxufVxyXG5cclxuLyogZXNsaW50IG5vLWJpdHdpc2U6IFtcImVycm9yXCIsIHsgXCJhbGxvd1wiOiBbXCI+PlwiXSB9XSAqL1xyXG5mdW5jdGlvbiBDb250cm9sbGVyKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24gfSA9IF9yZWY7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGNvbnRyb2xsZXI6IHtcclxuICAgICAgY29udHJvbDogdW5kZWZpbmVkLFxyXG4gICAgICBpbnZlcnNlOiBmYWxzZSxcclxuICAgICAgYnk6ICdzbGlkZScsIC8vIG9yICdjb250YWluZXInXHJcbiAgICB9LFxyXG4gIH0pO1xyXG5cclxuICBzd2lwZXIuY29udHJvbGxlciA9IHtcclxuICAgIGNvbnRyb2w6IHVuZGVmaW5lZCxcclxuICB9O1xyXG4gIGZ1bmN0aW9uIExpbmVhclNwbGluZSh4LCB5KSB7XHJcbiAgICBjb25zdCBiaW5hcnlTZWFyY2ggPSAoZnVuY3Rpb24gc2VhcmNoKCkge1xyXG4gICAgICBsZXQgbWF4SW5kZXg7XHJcbiAgICAgIGxldCBtaW5JbmRleDtcclxuICAgICAgbGV0IGd1ZXNzO1xyXG4gICAgICByZXR1cm4gKGFycmF5LCB2YWwpID0+IHtcclxuICAgICAgICBtaW5JbmRleCA9IC0xO1xyXG4gICAgICAgIG1heEluZGV4ID0gYXJyYXkubGVuZ3RoO1xyXG4gICAgICAgI
9266HdoaWxlIChtYXhJbmRleCAtIG1pbkluZGV4ID4gMSkge1xyXG4gICAgICAgICAgZ3Vlc3MgPSAobWF4SW5kZXggKyBtaW5JbmRleCkgPj4gMTtcclxuICAgICAgICAgIGlmIChhcnJheVtndWVzc10gPD0gdmFsKSB7XHJcbiAgICAgICAgICAgIG1pbkluZGV4ID0gZ3Vlc3M7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBtYXhJbmRleCA9IGd1ZXNzO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbWF4SW5kZXg7XHJcbiAgICAgIH07XHJcbiAgICB9KSgpO1xyXG4gICAgdGhpcy54ID0geDtcclxuICAgIHRoaXMueSA9IHk7XHJcbiAgICB0aGlzLmxhc3RJbmRleCA9IHgubGVuZ3RoIC0gMTtcclxuICAgIC8vIEdpdmVuIGFuIHggdmFsdWUgKHgyKSwgcmV0dXJuIHRoZSBleHBlY3RlZCB5MiB2YWx1ZTpcclxuICAgIC8vICh4MSx5MSkgaXMgdGhlIGtub3duIHBvaW50IGJlZm9yZSBnaXZlbiB2YWx1ZSxcclxuICAgIC8vICh4Myx5MykgaXMgdGhlIGtub3duIHBvaW50IGFmdGVyIGdpdmVuIHZhbHVlLlxyXG4gICAgbGV0IGkxO1xyXG4gICAgbGV0IGkzO1xyXG4gICAgdGhpcy5pbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlKHgyKSB7XHJcbiAgICAgIGlmICgheDIpIHJldHVybiAwO1xyXG5cclxuICAgICAgLy8gR2V0IHRoZSBpbmRleGVzIG9mIHgxIGFuZCB4MyAodGhlIGFycmF5IGluZGV4ZXMgYmVmb3JlIGFuZCBhZnRlciBnaXZlbiB4Mik6XHJcbiAgICAgIGkzID0gYmluYXJ5U2VhcmNoKHRoaXMueCwgeDIpO1xyXG4gICAgICBpMSA9IGkzIC0gMTtcclxuXHJcbiAgICAgIC8vIFdlIGhhdmUgb3VyIGluZGV4ZXMgaTEgJiBpMywgc28gd2UgY2FuIGNhbGN1bGF0ZSBhbHJlYWR5OlxyXG4gICAgICAvLyB5MiA6PSAoKHgy4oiSeDEpIMOXICh5M+KIknkxKSkgw7cgKHgz4oiSeDEpICsgeTFcclxuICAgICAgcmV0dXJuICgoeDIgLSB0aGlzLnhbaTFdKSAqICh0aGlzLnlbaTNdIC0gdGhpcy55W2kxXSkpIC8gKHRoaXMueFtpM10gLSB0aGlzLnhbaTFdKSArIHRoaXMueVtpMV07XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGdldEludGVycG9sYXRlRnVuY3Rpb24oYykge1xyXG4gICAgc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lID0gc3dpcGVyLnBhcmFtcy5sb29wXHJcbiAgICAgID8gbmV3IExpbmVhclNwbGluZShzd2lwZXIuc2xpZGVzR3JpZCwgYy5zbGlkZXNHcmlkKVxyXG4gICAgICA6IG5ldyBMaW5lYXJTcGxpbmUoc3dpcGVyLnNuYXBHcmlkLCBjLnNuYXBHcmlkKTtcclxuICB9XHJcbiAgZnVuY3Rpb24gc2V0VHJhbnNsYXRlKF90LCBieUNvbnRyb2xsZXIpIHtcclxuICAgIGNvbnN0IGNvbnRyb2xsZWQgPSBzd2lwZXIuY29udHJvbGxlci5jb250cm9sO1xyXG4gICAgbGV0IG11bHRpcGxpZXI7XHJcbiAgICBsZXQgY29udHJvbGxlZFRyYW5zbGF0ZTtcclxuICAgIGNvbnN0IFN3aXBlciA9IHN3aXBlci5jb25zdHJ1Y3RvcjtcclxuICAgIGZ1bmN0aW9uIHNldENvbnRyb2xsZWRUcmFuc2xhdGUoYykge1xyXG4gICAgICBpZiAoYy5kZXN0cm95ZWQpIHJldHVybjtcclxuXHJcbiAgICAgIC8vIHRoaXMgd2lsbCBjcmVhdGUgYW4gSW50ZXJwb2xhdGUgZnVuY3Rpb24gYmFzZWQgb24gdGhlIHNuYXBHcmlkc1xyXG4gICAgICAvLyB4IGlzIHRoZSBHcmlkIG9mIHRoZSBzY3JvbGxlZCBzY3JvbGxlciBhbmQgeSB3aWxsIGJlIHRoZSBjb250cm9sbGVkIHNjcm9sbGVyXHJcbiAgICAgIC8vIGl0IG1ha2VzIHNlbnNlIHRvIGNyZWF0ZSB0aGlzIG9ubHkgb25jZSBhbmQgcmVjYWxsIGl0IGZvciB0aGUgaW50ZXJwb2xhdGlvblxyXG4gICAgICAvLyB0aGUgZnVuY3Rpb24gZG9lcyBhIGxvdCBvZiB2YWx1ZSBjYWNoaW5nIGZvciBwZXJmb3JtYW5jZVxyXG4gICAgICBjb25zdCB0cmFuc2xhdGUgPSBzd2lwZXIucnRsVHJhbnNsYXRlID8gLXN3aXBlci50cmFuc2xhdGUgOiBzd2lwZXIudHJhbnNsYXRlO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jb250cm9sbGVyLmJ5ID09PSAnc2xpZGUnKSB7XHJcbiAgICAgICAgZ2V0SW50ZXJwb2xhdGVGdW5jdGlvbihjKTtcclxuICAgICAgICAvLyBpIGFtIG5vdCBzdXJlIHdoeSB0aGUgdmFsdWVzIGhhdmUgdG8gYmUgbXVsdGlwbGljYXRlZCB0aGlzIHdheSwgdHJpZWQgdG8gaW52ZXJ0IHRoZSBzbmFwR3JpZFxyXG4gICAgICAgIC8vIGJ1dCBpdCBkaWQgbm90IHdvcmsgb3V0XHJcbiAgICAgICAgY29udHJvbGxlZFRyYW5zbGF0ZSA9IC1zd2lwZXIuY29udHJvbGxlci5zcGxpbmUuaW50ZXJwb2xhdGUoLXRyYW5zbGF0ZSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFjb250cm9sbGVkVHJhbnNsYXRlIHx8IHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ2NvbnRhaW5lcicpIHtcclxuICAgICAgICBtdWx0aXBsaWVyID0gKGMubWF4VHJhbnNsYXRlKCkgLSBjLm1pblRyYW5zbGF0ZSgpKSAvIChzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpO1xyXG4gICAgICAgIGlmIChOdW1iZXIuaXNOYU4obXVsdGlwbGllcikgfHwgIU51bWJlci5pc0Zpbml0ZShtdWx0aXBsaWVyKSkge1xyXG4gICAgICAgICAgbXVsdGlwbGllciA9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSAodHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAqIG11bHRpcGxpZXIgKyBjLm1pblRyYW5zbGF0ZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNvbnRyb2xsZXIuaW52ZXJzZSkge1xyXG4gICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSBjLm1heFRyYW5zbGF0ZSgpIC0gY29udHJvbGxlZFRyYW5zbGF0ZTtcclxuICAgICAgfVxyXG4gICAgICBjLnVwZGF0ZVByb2dyZXNzKGNvbnRyb2xsZWRUcmFuc2xhdGUpO1xyXG4gICAgICBjLnNldFRyYW5zbGF0ZShjb250cm9sbGVkVHJhbnNsYXRlLCBzd2lwZXIpO1xyXG4gICAgICBjLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XHJcbiAgICAgIGMudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xyXG4gICAgfVxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY29udHJvbGxlZCkpIHtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250cm9sbGVkLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgICAgaWYgKGNvbnRyb2xsZWRbaV0gIT09IGJ5Q29udHJvbGxlciAmJiBjb250cm9sbGVkW2ldIGluc3RhbmNlb2YgU3dpcGVyKSB7XHJcbiAgICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGNvbnRyb2xsZWRbaV0pO1xyXG4gICAgICAgI
9266H1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChjb250cm9sbGVkIGluc3RhbmNlb2YgU3dpcGVyICYmIGJ5Q29udHJvbGxlciAhPT0gY29udHJvbGxlZCkge1xyXG4gICAgICBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGNvbnRyb2xsZWQpO1xyXG4gICAgfVxyXG4gIH1cclxuICBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uLCBieUNvbnRyb2xsZXIpIHtcclxuICAgIGNvbnN0IFN3aXBlciA9IHN3aXBlci5jb25zdHJ1Y3RvcjtcclxuICAgIGNvbnN0IGNvbnRyb2xsZWQgPSBzd2lwZXIuY29udHJvbGxlci5jb250cm9sO1xyXG4gICAgbGV0IGk7XHJcbiAgICBmdW5jdGlvbiBzZXRDb250cm9sbGVkVHJhbnNpdGlvbihjKSB7XHJcbiAgICAgIGlmIChjLmRlc3Ryb3llZCkgcmV0dXJuO1xyXG4gICAgICBjLnNldFRyYW5zaXRpb24oZHVyYXRpb24sIHN3aXBlcik7XHJcbiAgICAgIGlmIChkdXJhdGlvbiAhPT0gMCkge1xyXG4gICAgICAgIGMudHJhbnNpdGlvblN0YXJ0KCk7XHJcbiAgICAgICAgaWYgKGMucGFyYW1zLmF1dG9IZWlnaHQpIHtcclxuICAgICAgICAgIG5leHRUaWNrKCgpID0+IHtcclxuICAgICAgICAgICAgYy51cGRhdGVBdXRvSGVpZ2h0KCk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxlbWVudFRyYW5zaXRpb25FbmQoYy53cmFwcGVyRWwsICgpID0+IHtcclxuICAgICAgICAgIGlmICghY29udHJvbGxlZCkgcmV0dXJuO1xyXG4gICAgICAgICAgYy50cmFuc2l0aW9uRW5kKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRyb2xsZWQpKSB7XHJcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjb250cm9sbGVkLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgICAgaWYgKGNvbnRyb2xsZWRbaV0gIT09IGJ5Q29udHJvbGxlciAmJiBjb250cm9sbGVkW2ldIGluc3RhbmNlb2YgU3dpcGVyKSB7XHJcbiAgICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNpdGlvbihjb250cm9sbGVkW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoY29udHJvbGxlZCBpbnN0YW5jZW9mIFN3aXBlciAmJiBieUNvbnRyb2xsZXIgIT09IGNvbnRyb2xsZWQpIHtcclxuICAgICAgc2V0Q29udHJvbGxlZFRyYW5zaXRpb24oY29udHJvbGxlZCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIHJlbW92ZVNwbGluZSgpIHtcclxuICAgIGlmICghc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkgcmV0dXJuO1xyXG4gICAgaWYgKHN3aXBlci5jb250cm9sbGVyLnNwbGluZSkge1xyXG4gICAgICBzd2lwZXIuY29udHJvbGxlci5zcGxpbmUgPSB1bmRlZmluZWQ7XHJcbiAgICAgIGRlbGV0ZSBzd2lwZXIuY29udHJvbGxlci5zcGxpbmU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIG9uKCdiZWZvcmVJbml0JywgKCkgPT4ge1xyXG4gICAgaWYgKFxyXG4gICAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxyXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcbiAgICAgICh0eXBlb2Ygc3dpcGVyLnBhcmFtcy5jb250cm9sbGVyLmNvbnRyb2wgPT09ICdzdHJpbmcnIHx8IHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5jb250cm9sIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpXHJcbiAgICApIHtcclxuICAgICAgY29uc3QgY29udHJvbEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5jb250cm9sKTtcclxuICAgICAgaWYgKGNvbnRyb2xFbGVtZW50ICYmIGNvbnRyb2xFbGVtZW50LnN3aXBlcikge1xyXG4gICAgICAgIHN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wgPSBjb250cm9sRWxlbWVudC5zd2lwZXI7XHJcbiAgICAgIH0gZWxzZSBpZiAoY29udHJvbEVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBvbkNvbnRyb2xsZXJTd2lwZXIgPSAoZSkgPT4ge1xyXG4gICAgICAgICAgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCA9IGUuZGV0YWlsWzBdO1xyXG4gICAgICAgICAgc3dpcGVyLnVwZGF0ZSgpO1xyXG4gICAgICAgICAgY29udHJvbEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5pdCcsIG9uQ29udHJvbGxlclN3aXBlcik7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb250cm9sRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdpbml0Jywgb25Db250cm9sbGVyU3dpcGVyKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuY29udHJvbGxlci5jb250cm9sID0gc3dpcGVyLnBhcmFtcy5jb250cm9sbGVyLmNvbnRyb2w7XHJcbiAgfSk7XHJcbiAgb24oJ3VwZGF0ZScsICgpID0+IHtcclxuICAgIHJlbW92ZVNwbGluZSgpO1xyXG4gIH0pO1xyXG4gIG9uKCdyZXNpemUnLCAoKSA9PiB7XHJcbiAgICByZW1vdmVTcGxpbmUoKTtcclxuICB9KTtcclxuICBvbignb2JzZXJ2ZXJVcGRhdGUnLCAoKSA9PiB7XHJcbiAgICByZW1vdmVTcGxpbmUoKTtcclxuICB9KTtcclxuICBvbignc2V0VHJhbnNsYXRlJywgKF9zLCB0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcikgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIuY29udHJvbGxlci5jb250cm9sIHx8IHN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wuZGVzdHJveWVkKSByZXR1cm47XHJcbiAgICBzd2lwZXIuY29udHJvbGxlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlLCBieUNvbnRyb2xsZXIpO1xyXG4gIH0pO1xyXG4gIG9uKCdzZXRUcmFuc2l0aW9uJywgKF9zLCBkdXJhdGlvbiwgYnlDb250cm9sbGVyKSA9PiB7XHJcbiAgICBpZiAoIXN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wgfHwgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbC5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgIHN3aXBlci5jb250cm9sbGVyLnNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcik7XHJcbiAgfSk7XHJcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIuY29udHJvbGxlciwge1xyXG4gICAgc2V0VHJhbnNsYXRlLFxyXG4gICAgc2V0VHJhbnNpdGlvbixcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gQTExeShfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uIH0gPSBfcmVmO1xyXG4gIGV4dGVuZFBhcmFtcyh7XHJcbiAgICBhMTF5OiB7XHJcbiAgICAgIGVuYWJsZWQ6IHRydWUsXHJcbiAgICAgIG5vdGlmaWNhdGlvbkNsYXNzOiAnc3dpcGVyLW5vdGlmaWNhdGlvbicsXHJcbiAgICAgIHByZXZTbGlkZU1lc3NhZ2U6ICdQcmV2aW91cyBzbGlkZScsXHJcbiAgICAgIG5leHRTbGlkZU1lc3NhZ2U6ICdOZXh0IHNsaWRlJyxcclxuICAgICAgZmlyc3RTbGlkZU1lc3NhZ2U6ICdUaGlzIGlzIHRoZSBmaXJzdCBzbGlkZScsXHJcbiAgICAgIGxhc3RTbGlkZU1lc3NhZ2U6ICdUaGlzIGlzIHRoZSBsYXN0IHNsaWRlJyxcclxuICAgICAgcGFnaW5hdGlvbkJ1bGxldE1lc3NhZ2U6ICdHbyB0byBzbGlkZSB7e2luZGV4fX0nLFxyXG4gICAgICBzbGlkZUxhYmVsTWVzc2FnZTogJ3t7aW5kZXh9fSAvIHt7c2xpZGVzTGVuZ3RofX0nLFxyXG4gICAgICBjb250YWluZXJNZXNzYWdlOiBudWxsLFxyXG4gICAgICBjb250YWluZXJSb2xlRGVzY3JpcHRpb25NZXNzYWdlOiBudWxsLFxyXG4gICAgICBpdGVtUm9sZURlc2NyaXB0aW9uTWVzc2FnZTogbnVsbCxcclxuICAgICAgc2xpZGVSb2xlOiAnZ3JvdXAnLFxyXG4gICAgICBpZDogbnVsbCxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgc3dpcGVyLmExMXkgPSB7XHJcbiAgICBjbGlja2VkOiBmYWxzZSxcclxuICB9O1xyXG4gIGxldCBsaXZlUmVnaW9uID0gbnVsbDtcclxuICBmdW5jdGlvbiBub3RpZnkobWVzc2FnZSkge1xyXG4gICAgY29uc3Qgbm90aWZpY2F0aW9uID0gbGl2ZVJlZ2lvbjtcclxuICAgIGlmIChub3RpZmljYXRpb24ubGVuZ3RoID09PSAwKSByZXR1cm47XHJcbiAgICBub3RpZmljYXRpb24uaW5uZXJIVE1MID0gJyc7XHJcbiAgICBub3RpZmljYXRpb24uaW5uZXJIVE1MID0gbWVzc2FnZTtcclxuICB9XHJcbiAgY29uc3QgbWFrZUVsZW1lbnRzQXJyYXkgPSAoZWwpID0+IHtcclxuICAgIGlmICghQXJyYXkuaXNBcnJheShlbCkpIGVsID0gW2VsXS5maWx0ZXIoKGUpID0+ICEhZSk7XHJcbiAgICByZXR1cm4gZWw7XHJcbiAgfTtcclxuICBmdW5jdGlvbiBnZXRSYW5kb21OdW1iZXIoc2l6ZSkge1xyXG4gICAgaWYgKHNpemUgPT09IHZvaWQgMCkge1xyXG4gICAgICBzaXplID0gMTY7XHJcbiAgICB9XHJcbiAgICAvLyAgIGNvbnN0IHJhbmRvbUNoYXIgPSAoKSA9PiBNYXRoLnJvdW5kKDE2ICogTWF0aC5yYW5kb20oKSkudG9TdHJpbmc
9266oMTYpO1xyXG4gICAgLy8gY29uc3QgcmFuZG9tQ2hhciA9ICgpID0+IHBhcnNlRmxvYXQoJzAuJyArIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDEpKVswXSk7XHJcbiAgICBjb25zdCByYW5kb21BcnJheSA9IG5ldyBVaW50OEFycmF5KDEpO1xyXG4gICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMocmFuZG9tQXJyYXkpO1xyXG4gICAgY29uc3QgcmFuZG9tVmFsdWUgPSByYW5kb21BcnJheVswXSAlIDE2O1xyXG4gICAgY29uc3QgcmFuZG9tQ2hhciA9IHJhbmRvbVZhbHVlLnRvU3RyaW5nKDE2KTtcclxuICAgIHJldHVybiAneCcucmVwZWF0KHNpemUpLnJlcGxhY2UoL3gvZywgcmFuZG9tQ2hhcik7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIG1ha2VFbEZvY3VzYWJsZShlbCkge1xyXG4gICAgZWwgPSBtYWtlRWxlbWVudHNBcnJheShlbCk7XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBzdWJFbC5zZXRBdHRyaWJ1dGUoJ3RhYkluZGV4JywgJzAnKTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBmdW5jdGlvbiBtYWtlRWxOb3RGb2N1c2FibGUoZWwpIHtcclxuICAgIGVsID0gbWFrZUVsZW1lbnRzQXJyYXkoZWwpO1xyXG4gICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHtcclxuICAgICAgc3ViRWwuc2V0QXR0cmlidXRlKCd0YWJJbmRleCcsICctMScpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGFkZEVsUm9sZShlbCwgcm9sZSkge1xyXG4gICAgZWwgPSBtYWtlRWxlbWVudHNBcnJheShlbCk7XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBzdWJFbC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCByb2xlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBmdW5jdGlvbiBhZGRFbFJvbGVEZXNjcmlwdGlvbihlbCwgZGVzY3JpcHRpb24pIHtcclxuICAgIGVsID0gbWFrZUVsZW1lbnRzQXJyYXkoZWwpO1xyXG4gICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHtcclxuICAgICAgc3ViRWwuc2V0QXR0cmlidXRlKCdhcmlhLXJvbGVkZXNjcmlwdGlvbicsIGRlc2NyaXB0aW9uKTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBmdW5jdGlvbiBhZGRFbENvbnRyb2xzKGVsLCBjb250cm9scykge1xyXG4gICAgZWwgPSBtYWtlRWxlbWVudHNBcnJheShlbCk7XHJcbiAgICBlbC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICBzdWJFbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtY29udHJvbHMnLCBjb250cm9scyk7XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gYWRkRWxMYWJlbChlbCwgbGFiZWwpIHtcclxuICAgIGVsID0gbWFrZUVsZW1lbnRzQXJyYXkoZWwpO1xyXG4gICAgZWwuZm9yRWFjaCgoc3ViRWwpID0+IHtcclxuICAgICAgc3ViRWwuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgbGFiZWwpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGFkZEVsSWQoZWwsIGlkKSB7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIHN1YkVsLnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gYWRkRWxMaXZlKGVsLCBsaXZlKSB7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIHN1YkVsLnNldEF0dHJpYnV0ZSgnYXJpYS1saXZlJywgbGl2ZSk7XHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gZGlzYWJsZUVsKGVsKSB7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIHN1YkVsLnNldEF0dHJpYnV0ZSgnYXJpYS1kaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG4gIGZ1bmN0aW9uIGVuYWJsZUVsKGVsKSB7XHJcbiAgICBlbCA9IG1ha2VFbGVtZW50c0FycmF5KGVsKTtcclxuICAgIGVsLmZvckVhY2goKHN1YkVsKSA9PiB7XHJcbiAgICAgIHN1YkVsLnNldEF0dHJpYnV0ZSgnYXJpYS1kaXNhYmxlZCcsIGZhbHNlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvbkVudGVyT3JTcGFjZUtleShlKSB7XHJcbiAgICBpZiAoZS5rZXlDb2RlICE9PSAxMyAmJiBlLmtleUNvZGUgIT09IDMyKSByZXR1cm47XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmExMXk7XHJcbiAgICBjb25zdCB0YXJnZXRFbCA9IGUudGFyZ2V0O1xyXG4gICAgaWYgKFxyXG4gICAgICBzd2lwZXIucGFnaW5hdGlvbiAmJlxyXG4gICAgICBzd2lwZXIucGFnaW5hdGlvbi5lbCAmJlxyXG4gICAgICAodGFyZ2V0RWwgPT09IHN3aXBlci5wYWdpbmF0aW9uLmVsIHx8IHN3aXBlci5wYWdpbmF0aW9uLmVsLmNvbnRhaW5zKGUudGFyZ2V0KSlcclxuICAgICkge1xyXG4gICAgICBpZiAoIWUudGFyZ2V0Lm1hdGNoZXMoY2xhc3Nlc1RvU2VsZWN0b3Ioc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkpIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi5uZXh0RWwgJiYgdGFyZ2V0RWwgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCkge1xyXG4gICAgICBpZiAoIShzd2lwZXIuaXNFbmQgJiYgIXN3aXBlci5wYXJhbXMubG9vcCkpIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVOZXh0KCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHN3aXBlci5pc0VuZCkge1xyXG4gICAgICAgIG5vdGlmeShwYXJhbXMubGFzdFNsaWRlTWVzc2FnZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbm90aWZ5KHBhcmFtcy5uZXh0U2xpZGVNZXNzYWdlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5uYXZpZ2F0aW9uICYmIHN3aXBlci5uYXZpZ2F0aW9uLnByZXZFbCAmJiB0YXJnZXRFbCA9PT0gc3dpcGVyLm5hdmlnYXRpb24ucHJldkVsKSB7XHJcbiAgICAgIGlmICghKHN3aXBlci5pc0JlZ2lubmluZyAmJiAhc3dpcGVyLnBhcmFtcy5sb29wKSkge1xyXG4gICAgICAgIHN3aXBlci5zbGlkZVByZXYoKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoc3dpcGVyLmlzQmVnaW5uaW5nKSB7XHJcbiAgICAgICAgbm90aWZ5KHBhcmFtcy5maXJzdFNsaWRlTWVzc2FnZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbm90aWZ5KHBhcmFtcy5wcmV2U2xpZGVNZXNzYWdlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uICYmIHRhcmdldEVsLm1hdGNoZXMoY2xhc3Nlc1RvU2VsZWN0b3Ioc3d
9266pcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkpIHtcclxuICAgICAgdGFyZ2V0RWwuY2xpY2soKTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gdXBkYXRlTmF2aWdhdGlvbigpIHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3AgfHwgc3dpcGVyLnBhcmFtcy5yZXdpbmQgfHwgIXN3aXBlci5uYXZpZ2F0aW9uKSByZXR1cm47XHJcbiAgICBjb25zdCB7IG5leHRFbCwgcHJldkVsIH0gPSBzd2lwZXIubmF2aWdhdGlvbjtcclxuICAgIGlmIChwcmV2RWwpIHtcclxuICAgICAgaWYgKHN3aXBlci5pc0JlZ2lubmluZykge1xyXG4gICAgICAgIGRpc2FibGVFbChwcmV2RWwpO1xyXG4gICAgICAgIG1ha2VFbE5vdEZvY3VzYWJsZShwcmV2RWwpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVuYWJsZUVsKHByZXZFbCk7XHJcbiAgICAgICAgbWFrZUVsRm9jdXNhYmxlKHByZXZFbCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChuZXh0RWwpIHtcclxuICAgICAgaWYgKHN3aXBlci5pc0VuZCkge1xyXG4gICAgICAgIGRpc2FibGVFbChuZXh0RWwpO1xyXG4gICAgICAgIG1ha2VFbE5vdEZvY3VzYWJsZShuZXh0RWwpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVuYWJsZUVsKG5leHRFbCk7XHJcbiAgICAgICAgbWFrZUVsRm9jdXNhYmxlKG5leHRFbCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gaGFzUGFnaW5hdGlvbigpIHtcclxuICAgIHJldHVybiBzd2lwZXIucGFnaW5hdGlvbiAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMubGVuZ3RoO1xyXG4gIH1cclxuICBmdW5jdGlvbiBoYXNDbGlja2FibGVQYWdpbmF0aW9uKCkge1xyXG4gICAgcmV0dXJuIGhhc1BhZ2luYXRpb24oKSAmJiBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uY2xpY2thYmxlO1xyXG4gIH1cclxuICBmdW5jdGlvbiB1cGRhdGVQYWdpbmF0aW9uKCkge1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5hMTF5O1xyXG4gICAgaWYgKCFoYXN
9266QYWdpbmF0aW9uKCkpIHJldHVybjtcclxuICAgIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMuZm9yRWFjaCgoYnVsbGV0RWwpID0+IHtcclxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5jbGlja2FibGUpIHtcclxuICAgICAgICBtYWtlRWxGb2N1c2FibGUoYnVsbGV0RWwpO1xyXG4gICAgICAgIGlmICghc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLnJlbmRlckJ1bGxldCkge1xyXG4gICAgICAgICAgYWRkRWxSb2xlKGJ1bGxldEVsLCAnYnV0dG9uJyk7XHJcbiAgICAgICAgICBhZGRFbExhYmVsKGJ1bGxldEVsLCBwYXJhbXMucGFnaW5hdGlvbkJ1bGxldE1lc3NhZ2UucmVwbGFjZSgvXFx7XFx7aW5kZXhcXH1cXH0vLCBlbGVtZW50SW5kZXgoYnVsbGV0RWwpICsgMSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBpZiAoYnVsbGV0RWwubWF0Y2hlcyhjbGFzc2VzVG9TZWxlY3Rvcihzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uYnVsbGV0QWN0aXZlQ2xhc3MpKSkge1xyXG4gICAgICAgIGJ1bGxldEVsLnNldEF0dHJpYnV0ZSgnYXJpYS1jdXJyZW50JywgJ3RydWUnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBidWxsZXRFbC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtY3VycmVudCcpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgY29uc3QgaW5pdE5hdkVsID0gKGVsLCB3cmFwcGVySWQsIG1lc3NhZ2UpID0+IHtcclxuICAgIG1ha2VFbEZvY3VzYWJsZShlbCk7XHJcbiAgICBpZiAoZWwudGFnTmFtZSAhPT0gJ0JVVFRPTicpIHtcclxuICAgICAgYWRkRWxSb2xlKGVsLCAnYnV0dG9uJyk7XHJcbiAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbkVudGVyT3JTcGFjZUtleSk7XHJcbiAgICB9XHJcbiAgICBhZGRFbExhYmVsKGVsLCBtZXNzYWdlKTtcclxuICAgIGFkZEVsQ29udHJvbHMoZWwsIHdyYXBwZXJJZCk7XHJcbiAgfTtcclxuICBjb25zdCBoYW5kbGVQb2ludGVyRG93biA9ICgpID0+IHtcclxuICAgIHN3aXBlci5hMTF5LmNsaWNrZWQgPSB0cnVlO1xyXG4gIH07XHJcbiAgY29uc3QgaGFuZGxlUG9pbnRlclVwID0gKCkgPT4ge1xyXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICBpZiAoIXN3aXBlci5kZXN0cm95ZWQpIHtcclxuICAgICAgICAgIHN3aXBlci5hMTF5LmNsaWNrZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuICBjb25zdCBoYW5kbGVGb2N1cyA9IChlKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLmExMXkuY2xpY2tlZCkgcmV0dXJuO1xyXG4gICAgY29uc3Qgc2xpZGVFbCA9IGUudGFyZ2V0LmNsb3Nlc3QoYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc30sIHN3aXBlci1zbGlkZWApO1xyXG4gICAgaWYgKCFzbGlkZUVsIHx8ICFzd2lwZXIuc2xpZGVzLmluY2x1ZGVzKHNsaWRlRWwpKSByZXR1cm47XHJcbiAgICBjb25zdCBpc0FjdGl2ZSA9IHN3aXBlci5zbGlkZXMuaW5kZXhPZihzbGlkZUVsKSA9PT0gc3dpcGVyLmFjdGl2ZUluZGV4O1xyXG4gICAgY29uc3QgaXNWaXNpYmxlID1cclxuICAgICAgc3dpcGVyLnBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzICYmIHN3aXBlci52aXNpYmxlU2xpZGVzICYmIHN3aXBlci52aXNpYmxlU2xpZGVzLmluY2x1ZGVzKHNsaWRlRWwpO1xyXG4gICAgaWYgKGlzQWN0aXZlIHx8IGlzVmlzaWJsZSkgcmV0dXJuO1xyXG4gICAgaWYgKGUuc291cmNlQ2FwYWJpbGl0aWVzICYmIGUuc291cmNlQ2FwYWJpbGl0aWVzLmZpcmVzVG91Y2hFdmVudHMpIHJldHVybjtcclxuICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcclxuICAgICAgc3dpcGVyLmVsLnNjcm9sbExlZnQgPSAwO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLmVsLnNjcm9sbFRvcCA9IDA7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmluZGV4T2Yoc2xpZGVFbCksIDApO1xyXG4gIH07XHJcbiAgY29uc3QgaW5pdFNsaWRlcyA9ICgpID0+IHtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcclxuICAgIGlmIChwYXJhbXMuaXRlbVJvbGVEZXNjcmlwdGlvbk1lc3NhZ2UpIHtcclxuICAgICAgYWRkRWxSb2xlRGVzY3JpcHRpb24oc3dpcGVyLnNsaWRlcywgcGFyYW1zLml0ZW1Sb2xlRGVzY3JpcHRpb25NZXNzYWdlKTtcclxuICAgIH1cclxuICAgIGlmIChwYXJhbXMuc2xpZGVSb2xlKSB7XHJcbiAgICAgIGFkZEVsUm9sZShzd2lwZXIuc2xpZGVzLCBwYXJhbXMuc2xpZGVSb2xlKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHNsaWRlc0xlbmd0aCA9IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xyXG4gICAgaWYgKHBhcmFtcy5zbGlkZUxhYmVsTWVzc2FnZSkge1xyXG4gICAgICBzd2lwZXIuc2xpZGVzLmZvckVhY2goKHNsaWRlRWwsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgY29uc3Qgc2xpZGVJbmRleCA9IHN3aXBlci5wYXJhbXMubG9vcCA/IHBhcnNlSW50KHNsaWRlRWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCkgOiBpbmRleDtcclxuICAgICAgICBjb25zdCBhcmlhTGFiZWxNZXNzYWdlID0gcGFyYW1zLnNsaWRlTGFiZWxNZXNzYWdlXHJcbiAgICAgICAgICAucmVwbGFjZSgvXFx7XFx7aW5kZXhcXH1cXH0vLCBzbGlkZUluZGV4ICsgMSlcclxuICAgICAgICAgIC5yZXBsYWNlKC9cXHtcXHtzbGlkZXNMZW5ndGhcXH1cXH0vLCBzbGlkZXNMZW5ndGgpO1xyXG4gICAgICAgIGFkZEVsTGFiZWwoc2xpZGVFbCwgYXJpYUxhYmVsTWVzc2FnZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH07XHJcbiAgY29uc3QgaW5pdCA9ICgpID0+IHtcclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcclxuICAgIGlmIChzd2lwZXIuaXNFbGVtZW50KSB7XHJcbiAgICAgIHN3aXBlci5lbC5zaGFkb3dFbC5hcHBlbmQobGl2ZVJlZ2lvbik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzd2lwZXIuZWwuYXBwZW5kKGxpdmVSZWdpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvbnRhaW5lclxyXG4gICAgY29uc3QgY29udGFpbmVyRWwgPSBzd2lwZXIuZWw7XHJcbiAgICBpZiAocGFyYW1zLmNvbnRhaW5lclJvbGVEZXNjcmlwdGlvbk1lc3NhZ2UpIHtcclxuICAgICAgYWRkRWxSb2xlRGVzY3JpcHRpb24oY29udGFpbmVyRWwsIHBhcmFtcy5jb250YWluZXJSb2xlRGVzY3JpcHRpb25NZXNzYWdlKTtcclxuICAgIH1cclxuICAgIGlmIChwYXJhbXMuY29udGFpbmVyTWVzc2FnZSkge1xyXG4gICAgICBhZGRFbExhYmVsKGNvbnRhaW5lckVsLCBwYXJhbXMuY29udGFpbmVyTWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gV3JhcHBlclxyXG4gICAgY29uc3Qgd3JhcHBlckVsID0gc3dpcGVyLndyYXBwZXJFbDtcclxuICAgIGNvbnN0IHdyYXBwZXJJZCA9IHBhcmFtcy5pZCB8fCB3cmFwcGVyRWwuZ2V0QXR0cmlidXRlKCdpZCcpIHx8IGBzd2lwZXItd3JhcHBlci0ke2dldFJhbmRvbU51bWJlcigxNil9YDtcclxuICAgIGNvbnN0IGxpdmUgPSBzd2lwZXIucGFyYW1zLmF1dG9wbGF5ICYmIHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZW5hYmxlZCA/ICdvZmYnIDogJ3BvbGl0ZSc7XHJcbiAgICBhZGRFbElkKHdyYXBwZXJFbCwgd3JhcHBlcklkKTtcclxuICAgIGFkZEVsTGl2ZSh3cmFwcGVyRWwsIGxpdmUpO1xyXG5cclxuICAgIC8vIFNsaWRlXHJcbiAgICBpbml0U2xpZGVzKCk7XHJcblxyXG4gICAgLy8gTmF2aWdhdGlvblxyXG4gICAgbGV0IHsgbmV4dEVsLCBwcmV2RWwgfSA9IHN3aXBlci5uYXZpZ2F0aW9uID8gc3dpcGVyLm5hdmlnYXRpb24gOiB7fTtcclxuICAgIG5leHRFbCA9IG1ha2VFbGVtZW50c0FycmF5KG5leHRFbCk7XHJcbiAgICBwcmV2RWwgPSBtYWtlRWxlbWVudHNBcnJheShwcmV2RWwpO1xyXG4gICAgaWYgKG5leHRFbCkge1xyXG4gICAgICBuZXh0RWwuZm9yRWFjaCgoZWwpID0+IGluaXROYXZFbChlbCwgd3JhcHBlcklkLCBwYXJhbXMubmV4dFNsaWRlTWVzc2FnZSkpO1xyXG4gICAgfVxyXG4gICAgaWYgKHByZXZFbCkge1xyXG4gICAgICBwcmV2RWwuZm9yRWFjaCgoZWwpID0+IGluaXROYXZFbChlbCwgd3JhcHBlcklkLCBwYXJhbXMucHJldlNsaWRlTWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBhZ2luYXRpb25cclxuICAgIGlmIChoYXNDbGlja2FibGVQYWdpbmF0aW9uKCkpIHtcclxuICAgICAgY29uc3QgcGFnaW5hdGlvbkVsID0gQXJyYXkuaXNBcnJheShzd2lwZXIucGFnaW5hdGlvbi5lbCkgPyBzd2lwZXIucGFnaW5hdGlvbi5lbCA6IFtzd2lwZXIucGFnaW5hdGlvbi5lbF07XHJcbiAgICAgIHBhZ2luYXRpb25FbC5mb3JFYWNoKChlbCkgPT4ge1xyXG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbkVudGVyT3JTcGFjZUtleSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRhYiBmb2N1c1xyXG4gICAgc3dpcGVyLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgaGFuZGxlRm9jdXMsIHRydWUpO1xyXG4gICAgc3dpcGVyLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24sIHRydWUpO1xyXG4gICAgc3dpcGVyLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGhhbmRsZVBvaW50ZXJVcCwgdHJ1ZSk7XHJcbiAgfTtcclxuICBmdW5jdGlvbiBkZXN0cm95KCkge1xyXG4gICAgaWYgKGxpdmVSZWdpb24pIGxpdmVSZWdpb24ucmVtb3ZlKCk7XHJcbiAgICBsZXQgeyBuZXh0RWwsIHByZXZFbCB9ID0gc3dpcGVyLm5hdmlnYXRpb24gPyBzd2lwZXIubmF2aWdhdGlvbiA6IHt9O1xyXG4gICAgbmV4dEVsID0gbWFrZUVsZW1lbnRzQXJyYXkobmV4dEVsKTtcclxuICAgIHByZXZFbCA9IG1ha2VFbGVtZW50c0FycmF5KHByZXZFbCk7XHJcbiAgICBpZiAobmV4dEVsKSB7XHJcbiAgICAgIG5leHRFbC5mb3JFYWNoKChlbCkgPT4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uRW50ZXJPclNwYWNlS2V5KSk7XHJcbiAgICB9XHJcbiAgICBpZiAocHJldkVsKSB7XHJcbiAgICAgIHByZXZFbC5mb3JFYWNoKChlbCkgPT4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uRW50ZXJPclNwYWNlS2V5KSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUGFnaW5hdGlvblxyXG4gICAgaWYgKGhhc0NsaWNrYWJsZVBhZ2luYXRpb24oKSkge1xyXG4gICAgICBjb25zdCBwYWdpbmF0aW9uRWwgPSBBcnJheS5pc0FycmF
92665KHN3aXBlci5wYWdpbmF0aW9uLmVsKSA/IHN3aXBlci5wYWdpbmF0aW9uLmVsIDogW3N3aXBlci5wYWdpbmF0aW9uLmVsXTtcclxuICAgICAgcGFnaW5hdGlvbkVsLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uRW50ZXJPclNwYWNlS2V5KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGFiIGZvY3VzXHJcbiAgICBzd2lwZXIuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXMnLCBoYW5kbGVGb2N1cywgdHJ1ZSk7XHJcbiAgICBzd2lwZXIuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBoYW5kbGVQb2ludGVyRG93biwgdHJ1ZSk7XHJcbiAgICBzd2lwZXIuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgaGFuZGxlUG9pbnRlclVwLCB0cnVlKTtcclxuICB9XHJcbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XHJcbiAgICBsaXZlUmVnaW9uID0gY3JlYXRlRWxlbWVudCgnc3BhbicsIHN3aXBlci5wYXJhbXMuYTExeS5ub3RpZmljYXRpb25DbGFzcyk7XHJcbiAgICBsaXZlUmVnaW9uLnNldEF0dHJpYnV0ZSgnYXJpYS1saXZlJywgJ2Fzc2VydGl2ZScpO1xyXG4gICAgbGl2ZVJlZ2lvbi5zZXRBdHRyaWJ1dGUoJ2FyaWEtYXRvbWljJywgJ3RydWUnKTtcclxuICB9KTtcclxuICBvbignYWZ0ZXJJbml0JywgKCkgPT4ge1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgaW5pdCgpO1xyXG4gIH0pO1xyXG4gIG9uKCdzbGlkZXNMZW5ndGhDaGFuZ2Ugc25hcEdyaWRMZW5ndGhDaGFuZ2Ugc2xpZGVzR3JpZExlbmd0aENoYW5nZScsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcclxuICAgIGluaXRTbGlkZXMoKTtcclxuICB9KTtcclxuICBvbignZnJvbUVkZ2UgdG9FZGdlIGFmdGVySW5pdCBsb2NrIHVubG9jaycsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcclxuICAgIHVwZGF0ZU5hdmlnYXRpb24oKTtcclxuICB9KTtcclxuICBvbigncGFnaW5hdGlvblVwZGF0ZScsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcclxuICAgIHVwZGF0ZVBhZ2luYXRpb24oKTtcclxuICB9KTtcclxuICBvbignZGVzdHJveScsICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcclxuICAgIGRlc3Ryb3koKTtcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gSGlzdG9yeShfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uIH0gPSBfcmVmO1xyXG4gIGV4dGVuZFBhcmFtcyh7XHJcbiAgICBoaXN0b3J5OiB7XHJcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICByb290OiAnJyxcclxuICAgICAgcmVwbGFjZVN0YXRlOiBmYWxzZSxcclxuICAgICAga2V5OiAnc2xpZGVzJyxcclxuICAgICAga2VlcFF1ZXJ5OiBmYWxzZSxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgbGV0IGluaXRpYWxpemVkID0gZmFsc2U7XHJcbiAgbGV0IHBhdGhzID0ge307XHJcbiAgY29uc3Qgc2x1Z2lmeSA9ICh0ZXh0KSA9PiB7XHJcbiAgICByZXR1cm4gdGV4dFxyXG4gICAgICAudG9TdHJpbmcoKVxyXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCAnLScpXHJcbiAgICAgIC5yZXBsYWNlKC9bXlxcdy1dKy9nLCAnJylcclxuICAgICAgLnJlcGxhY2UoLy0tKy9nLCAnLScpXHJcbiAgICAgIC5yZXBsYWNlKC9eLSsvLCAnJylcclxuICAgICAgLnJlcGxhY2UoLy0rJC8sICcnKTtcclxuICB9O1xyXG4gIGNvbnN0IGdldFBhdGhWYWx1ZXMgPSAodXJsT3ZlcnJpZGUpID0+IHtcclxuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gICAgbGV0IGxvY2F0aW9uO1xyXG4gICAgaWYgKHVybE92ZXJyaWRlKSB7XHJcbiAgICAgIGxvY2F0aW9uID0gbmV3IFVSTCh1cmxPdmVycmlkZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbjtcclxuICAgIH1cclxuICAgIGNvbnN0IHBhdGhBcnJheSA9IGxvY2F0aW9uLnBhdGhuYW1lXHJcbiAgICAgIC5zbGljZSgxKVxyXG4gICAgICAuc3BsaXQoJy8nKVxyXG4gICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0ICE9PSAnJyk7XHJcbiAgICBjb25zdCB0b3RhbCA9IHBhdGhBcnJheS5sZW5ndGg7XHJcbiAgICBjb25zdCBrZXkgPSBwYXRoQXJyYXlbdG90YWwgLSAyXTtcclxuICAgIGNvbnN0IHZhbHVlID0gcGF0aEFycmF5W3RvdGFsIC0gMV07XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBrZXksXHJcbiAgICAgIHZhbHVlLFxyXG4gICAgfTtcclxuICB9O1xyXG4gIGNvbnN0IHNldEhpc3RvcnkgPSAoa2V5LCBpbmRleCkgPT4ge1xyXG4gICAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgICBpZiAoIWluaXRpYWxpemVkIHx8ICFzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkgcmV0dXJuO1xyXG4gICAgbGV0IGxvY2F0aW9uO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMudXJsKSB7XHJcbiAgICAgIGxvY2F0aW9uID0gbmV3IFVSTChzd2lwZXIucGFyYW1zLnVybCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbjtcclxuICAgIH1cclxuICAgIGNvbnN0IHNsaWRlID0gc3dpcGVyLnNsaWRlc1tpbmRleF07XHJcbiAgICBsZXQgdmFsdWUgPSBzbHVnaWZ5KHNsaWRlLmdldEF0dHJpYnV0ZSgnZGF0YS1oaXN0b3J5JykpO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGlzdG9yeS5yb290Lmxlbmd0aCA+IDApIHtcclxuICAgICAgbGV0IHJvb3QgPSBzd2lwZXIucGFyYW1zLmhpc3Rvcnkucm9vdDtcclxuICAgICAgaWYgKHJvb3Rbcm9vdC5sZW5ndGggLSAxXSA9PT0gJy8nKSByb290ID0gcm9vdC5zbGljZSgwLCByb290Lmxlbmd0aCAtIDEpO1xyXG4gICAgICB2YWx1ZSA9IGAke3Jvb3R9LyR7a2V5ID8gYCR7a2V5fS9gIDogJyd9JHt2YWx1ZX1gO1xyXG4gICAgfSBlbHNlIGlmICghbG9jYXRpb24ucGF0aG5hbWUuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICB2YWx1ZSA9IGAke2tleSA/IGAke2tleX0vYCA6ICcnfSR7dmFsdWV9YDtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3Rvcnkua2VlcFF1ZXJ5KSB7XHJcbiAgICAgIHZhbHVlICs9IGxvY2F0aW9uLnNlYXJjaDtcclxuICAgIH1cclxuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHdpbmRvdy5oaXN0b3J5LnN0YXRlO1xyXG4gICAgaWYgKGN1cnJlbnRTdGF0ZSAmJiBjdXJyZW50U3RhdGUudmFsdWUgPT09IHZhbHVlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XHJcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShcclxuICAgICAgICB7XHJcbiAgICAgICAgICB2YWx1ZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIG51bGwsXHJcbiAgICAgICAgdmFsdWVcclxuICAgICAgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZShcclxuICAgICAgICB7XHJcbiAgICAgICAgICB2YWx1ZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIG51bGwsXHJcbiAgICAgICAgdmFsdWVcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9O1xyXG4gIGNvbnN0IHNjcm9sbFRvU2xpZGUgPSAoc3BlZWQsIHZhbHVlLCBydW5DYWxsYmFja3MpID0+IHtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBmb3IgKGxldCBpID0gMCwgbGVuZ3RoID0gc3dpcGVyLnNsaWRlcy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICAgIGNvbnN0IHNsaWRlID0gc3dpcGVyLnNsaWRlc1tpXTtcclxuICAgICAgICBjb25zdCBzbGlkZUhpc3RvcnkgPSBzbHVnaWZ5KHNsaWRlLmdldEF0dHJpYnV0ZSgnZGF0YS1oaXN0b3J5JykpO1xyXG4gICAgICAgIGlmIChzbGlkZUhpc3RvcnkgPT09IHZhbHVlKSB7XHJcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHN3aXBlci5nZXRTbGlkZUluZGV4KHNsaWRlKTtcclxuICAgICAgICAgI
9266HN3aXBlci5zbGlkZVRvKGluZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvKDAsIHNwZWVkLCBydW5DYWxsYmFja3MpO1xyXG4gICAgfVxyXG4gIH07XHJcbiAgY29uc3Qgc2V0SGlzdG9yeVBvcFN0YXRlID0gKCkgPT4ge1xyXG4gICAgcGF0aHMgPSBnZXRQYXRoVmFsdWVzKHN3aXBlci5wYXJhbXMudXJsKTtcclxuICAgIHNjcm9sbFRvU2xpZGUoc3dpcGVyLnBhcmFtcy5zcGVlZCwgcGF0aHMudmFsdWUsIGZhbHNlKTtcclxuICB9O1xyXG4gIGNvbnN0IGluaXQgPSAoKSA9PiB7XHJcbiAgICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5oaXN0b3J5KSByZXR1cm47XHJcbiAgICBpZiAoIXdpbmRvdy5oaXN0b3J5IHx8ICF3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUpIHtcclxuICAgICAgc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5lbmFibGVkID0gdHJ1ZTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgcGF0aHMgPSBnZXRQYXRoVmFsdWVzKHN3aXBlci5wYXJhbXMudXJsKTtcclxuICAgIGlmICghcGF0aHMua2V5ICYmICFwYXRocy52YWx1ZSkge1xyXG4gICAgICBpZiAoIXN3aXBlci5wYXJhbXMuaGlzdG9yeS5yZXBsYWNlU3RhdGUpIHtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBzZXRIaXN0b3J5UG9wU3RhdGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHNjcm9sbFRvU2xpZGUoMCwgcGF0aHMudmFsdWUsIHN3aXBlci5wYXJhbXMucnVuQ2FsbGJhY2tzT25Jbml0KTtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSkge1xyXG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBzZXRIaXN0b3J5UG9wU3RhdGUpO1xyXG4gICAgfVxyXG4gIH07XHJcbiAgY29uc3QgZGVzdHJveSA9ICgpID0+IHtcclxuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xyXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XHJcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIHNldEhpc3RvcnlQb3BTdGF0ZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBvbignaW5pdCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkge1xyXG4gICAgICBpbml0KCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQpIHtcclxuICAgICAgZGVzdHJveSgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCd0cmFuc2l0aW9uRW5kIF9mcmVlTW9kZU5vTW9tZW50dW1SZWxlYXNlJywgKCkgPT4ge1xyXG4gICAgaWYgKGluaXRpYWxpemVkKSB7XHJcbiAgICAgIHNldEhpc3Rvcnkoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmtleSwgc3dpcGVyLmFjdGl2ZUluZGV4KTtcclxuICAgIH1cclxuICB9KTtcclxuICBvbignc2xpZGVDaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICBpZiAoaW5pdGlhbGl6ZWQgJiYgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgIHNldEhpc3Rvcnkoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmtleSwgc3dpcGVyLmFjdGl2ZUluZGV4KTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gSGFzaE5hdmlnYXRpb24oX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBlbWl0LCBvbiB9ID0gX3JlZjtcclxuICBsZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XHJcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGhhc2hOYXZpZ2F0aW9uOiB7XHJcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICByZXBsYWNlU3RhdGU6IGZhbHNlLFxyXG4gICAgICB3YXRjaFN0YXRlOiBmYWxzZSxcclxuICAgICAgZ2V0U2xpZGVJbmRleChfcywgaGFzaCkge1xyXG4gICAgICAgIGlmIChzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICAgICAgY29uc3Qgc2xpZGVXaXRoSGFzaCA9IHN3aXBlci5zbGlkZXMuZmlsdGVyKChzbGlkZUVsKSA9PiBzbGlkZUVsLmdldEF0dHJpYnV0ZSgnZGF0YS1oYXNoJykgPT09IGhhc2gpWzBdO1xyXG4gICAgICAgICAgaWYgKCFzbGlkZVdpdGhIYXNoKSByZXR1cm4gMDtcclxuICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VJbnQoc2xpZGVXaXRoSGFzaC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JyksIDEwKTtcclxuICAgICAgICAgIHJldHVybiBpbmRleDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHN3aXBlci5nZXRTbGlkZUluZGV4KFxyXG4gICAgICAgICAgZWxlbWVudENoaWxkcmVuKFxyXG4gICAgICAgICAgICBzd2lwZXIuc2xpZGVzRWwsXHJcbiAgICAgICAgICAgIGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9W2RhdGEtaGFzaD1cIiR7aGFzaH1cIl0sIHN3aXBlci1zbGlkZVtkYXRhLWhhc2g9XCIke2hhc2h9XCJdYFxyXG4gICAgICAgICAgKVswXVxyXG4gICAgICAgICk7XHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGNvbnN0IG9uSGFzaENoYW5nZSA9ICgpID0+IHtcclxuICAgIGVtaXQoJ2hhc2hDaGFuZ2UnKTtcclxuICAgIGNvbnN0IG5ld0hhc2ggPSBkb2N1bWVudC5sb2NhdGlvbi5oYXNoLnJlcGxhY2UoJyMnLCAnJyk7XHJcbiAgICBjb25zdCBhY3RpdmVTbGlkZUVsID1cclxuICAgICAgc3dpcGVyLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWRcclxuICAgICAgICA/IHN3aXBlci5zbGlkZXNFbC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3N3aXBlci5hY3RpdmVJbmRleH1cIl1gKVxyXG4gICAgICAgIDogc3dpcGVyLnNsaWRlc1tzd2lwZXIuYWN0aXZlSW5kZXhdO1xyXG4gICAgY29uc3QgYWN0aXZlU2xpZGVIYXNoID0gYWN0aXZlU2xpZGVFbCA/IGFjdGl2ZVNsaWRlRWwuZ2V0QXR0cmlidXRlKCdkYXRhLWhhc2gnKSA6ICcnO1xyXG4gICAgaWYgKG5ld0hhc2ggIT09IGFjdGl2ZVNsaWRlSGFzaCkge1xyXG4gICAgICBjb25zdCBuZXdJbmRleCA9IHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZ2V0U2xpZGVJbmRleChzd2lwZXIsIG5ld0hhc2gpO1xyXG4gICAgICBpZiAodHlwZW9mIG5ld0luZGV4ID09PSAndW5kZWZpbmVkJyB8fCBOdW1iZXIuaXNOYU4obmV3SW5kZXgpKSByZXR1cm47XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvKG5ld0luZGV4KTtcclxuICAgIH1cclxuICB9O1xyXG4gIGNvbnN0IHNldEhhc2ggPSAoKSA9PiB7XHJcbiAgICBpZiAoIWluaXRpYWxpemVkIHx8ICFzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLmVuYWJsZWQpIHJldHVybjtcclxuICAgIGNvbnN0IGFjdGl2ZVNsaWRlRWwgPVxyXG4gICAgICBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZFxyXG4gICAgICAgID8gc3dpcGVyLnNsaWRlc0VsLnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7c3dpcGVyLmFjdGl2ZUluZGV4fVwiXWApXHJcbiAgICAgICAgOiBzd2lwZXIuc2xpZGVzW3N3aXBlci5hY3RpdmVJbmRleF07XHJcbiAgICBjb25zdCBhY3RpdmVTbGlkZUhhc2ggPSBhY3RpdmVTbGlkZUVsXHJcbiAgICAgID8gYWN0aXZlU2xpZGVFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFzaCcpIHx8IGFjdGl2ZVNsaWRlRWwuZ2V0QXR0cmlidXRlKCdkYXRhLWhpc3RvcnknKVxyXG4gICAgICA6ICcnO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24ucmVwbGFjZVN0YXRlICYmIHdpbmRvdy5oaXN0b3J5ICYmIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSkge1xyXG4gICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgbnVsbCwgYCMke2FjdGl2ZVNsaWRlSGFzaH1gIHx8ICcnKTtcclxuICAgICAgZW1pdCgnaGFzaFNldCcpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZG9jdW1lbnQubG9jYXRpb24uaGFzaCA9IGFjdGl2ZVNsaWRlSGFzaCB8fCAnJztcclxuICAgICAgZW1pdCgnaGFzaFNldCcpO1xyXG4gICAgfVxyXG4gIH07XHJcbiAgY29uc3QgaW5pdCA9ICgpID0+IHtcclxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5lbmFibGVkIHx8IChzd2lwZXIucGFyYW1zLmhpc3RvcnkgJiYgc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQpKSByZXR1cm47XHJcbiAgICBpbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICBjb25zdCBoYXNoID0gZG9jdW1lbnQubG9jYXRpb24uaGFzaC5yZXBsYWNlKCcjJywgJycpO1xyXG4gICAgaWYgKGhhc2gpIHtcclxuICAgICAgY29uc3Qgc3BlZWQgPSAwO1xyXG4gICAgICBjb25zdCBpbmRleCA9IHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZ2V0U2xpZGVJbmRleChzd2lwZXIsIGhhc2gpO1xyXG4gICAgICBzd2lwZXIuc2xpZGVUbyhpbmRleCB8fCAwLCBzcGVlZCwgc3dpcGVyLnBhcmFtcy5ydW5DYWxsYmFja3NPbkluaXQsIHRydWUpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24ud2F0Y2hTdGF0ZSkge1xyXG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIG9uSGFzaENoYW5nZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBkZXN0cm95ID0gKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24ud2F0Y2hTdGF0ZSkge1xyXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIG9uSGFzaENoYW5nZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBvbignaW5pdCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLmVuYWJsZWQpIHtcclxuICAgICAgaW5pdCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZW5hYmxlZCkge1xyXG4gICAgICBkZXN0cm95KCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ3RyYW5zaXRpb25FbmQgX2ZyZWVNb2RlTm9Nb21lbnR1bVJlbGVhc2UnLCAoKSA9PiB7XHJcbiAgICBpZiAoaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgc2V0SGFzaCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdzbGlkZUNoYW5nZScsICgpID0+IHtcclxuICAgIGlmIChpbml0aWFsaXplZCAmJiBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcclxuICAgICAgc2V0SGFzaCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG4vKiBlc2xpbnQgbm8tdW5kZXJzY29yZS1kYW5nbGU6IFwib2ZmXCIgKi9cclxuZnVuY3Rpb24gQXV0b3BsYXkoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiwgZW1pdCwgcGFyYW1zIH0gPSBfcmVmO1xyXG4gIHN3aXBlci5hdXRvcGxheSA9IHtcclxuICAgIHJ1bm5pbmc6IGZhbHNlLFxyXG4gICAgcGF1c2VkOiBmYWxzZSxcclxuICAgIHRpbWVMZWZ0OiAwLFxyXG4gIH07XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGF1dG9wbGF5OiB7XHJcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICBkZWxheTogMzAwMCxcclxuICAgICAgd2FpdEZvclRyYW5zaXRpb246IHRydWUsXHJcbiAgICAgIGRpc2FibGVPbkludGVyYWN0aW9uOiB0cnVlLFxyXG4gICAgICBzdG9wT25MYXN0U2xpZGU6IGZhbHNlLFxyXG4gICAgICByZXZlcnNlRGlyZWN0aW9uOiBmYWxzZSxcclxuICAgICAgcGF1c2VPbk1vdXNlRW50ZXI6IGZhbHNlLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBsZXQgdGltZW91dDtcclxuICBsZXQgcmFmO1xyXG4gIGxldCBhdXRvcGxheURlbGF5VG90YWwgPSBwYXJhbXMgJiYgcGFyYW1zLmF1dG9wbGF5ID8gcGFyYW1zLmF1dG9wbGF5LmRlbGF5IDogMzAwMDtcclxuICBsZXQgYXV0b3BsYXlEZWxheUN1cnJlbnQgPSBwYXJhbXMgJiYgcGFyYW1zLmF1dG9wbGF5ID8gcGFyYW1zLmF1dG9wbGF5LmRlbGF5IDogMzAwMDtcclxuICBsZXQgYXV0b3BsYXlUaW1lTGVmdDtcclxuICBsZXQgYXV0b3BsYXlTdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWU7XHJcbiAgbGV0IHdhc1BhdXNlZDtcclxuICBsZXQgaXNUb3VjaGVkO1xyXG4gIGxldCBwYXVzZWRCeVRvdWNoO1xyXG4gIGxldCB0b3VjaFN0YXJ0VGltZW91dDtcclxuICBsZXQgc2xpZGVDaGFuZ2VkO1xyXG4gIGxldCBwYXVzZWRCeUludGVyYWN0aW9uO1xyXG4gIGZ1bmN0aW9uIG9uVHJhbnNpdGlvbkVuZChlKSB7XHJcbiAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkIHx8ICFzd2lwZXIud3JhcHBlckVsKSByZXR1cm47XHJcbiAgICBpZiAoZS50YXJnZXQgIT09IHN3aXBlci53cmFwcGVyRWwpIHJldHVybjtcclxuICAgIHN3aXBlci53cmFwcGVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIG9uVHJhbnNpdGlvbkVuZCk7XHJcbiAgICByZXN1bWUoKTtcclxuICB9XHJcbiAgY29uc3QgY2FsY1RpbWVMZWZ0ID0gKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm47XHJcbiAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCkge1xyXG4gICAgICB3YXNQYXVzZWQgPSB0cnVlO1xyXG4gICAgfSBlbHNlIGlmICh3YXNQYXVzZWQpIHtcclxuICAgICAgYXV0b3BsYXlEZWxheUN1cnJlbnQgPSBhdXRvcGxheVRpbWVMZWZ0O1xyXG4gICAgICB3YXNQYXVzZWQgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIGNvbnN0IHRpbWVMZWZ0ID0gc3dpcGVyLmF1dG9wbGF5LnBhdXNlZFxyXG4gICAgICA/IGF1dG9wbGF5VGltZUxlZnRcclxuICAgICAgOiBhdXRvcGxheVN0YXJ0VGltZSArIGF1dG9wbGF5RGVsYXlDdXJyZW50IC0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICBzd2lwZXIuYXV0b3BsYXkudGltZUxlZnQgPSB0aW1lTGVmdDtcclxuICAgIGVtaXQoJ2F1dG9wbGF5VGltZUxlZnQnLCB0aW1lTGVmdCwgdGltZUxlZnQgLyBhdXRvcGxheURlbGF5VG90YWwpO1xyXG4gICAgcmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgY2FsY1RpbWVMZWZ0KCk7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gIGNvbnN0IGdldFNsaWRlRGVsYXkgPSAoKSA9PiB7XHJcbiAgICBsZXQgYWN0aXZlU2xpZGVFbDtcclxuICAgIGlmIChzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkge1xyXG4gICAgICBhY3RpdmVTbGlkZUVsID0gc3dpcGVyLnNsaWRlcy5maWx0ZXIoKHNsaWRlRWwpID0+IHNsaWRlRWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdzd2lwZXItc2xpZGUtYWN0aXZlJykpWzBdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZlU2xpZGVFbCA9IHN3aXBlci5zbGlkZXNbc3dpcGVyLmFjdGl2ZUluZGV4XTtcclxuICAgIH1cclxuICAgIGlmICghYWN0aXZlU2xpZGVFbCkgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIGNvbnN0IGN1cnJlbnRTbGlkZURlbGF5ID0gcGFyc2VJbnQoYWN0aXZlU2xpZGVFbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3dpcGVyLWF1dG9wbGF5JyksIDEwKTtcclxuICAgIHJldHVybi
9266BjdXJyZW50U2xpZGVEZWxheTtcclxuICB9O1xyXG4gIGNvbnN0IHJ1biA9IChkZWxheUZvcmNlKSA9PiB7XHJcbiAgICBpZiAoc3dpcGVyLmRlc3Ryb3llZCB8fCAhc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHJldHVybjtcclxuICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZik7XHJcbiAgICBjYWxjVGltZUxlZnQoKTtcclxuICAgIGxldCBkZWxheSA9IHR5cGVvZiBkZWxheUZvcmNlID09PSAndW5kZWZpbmVkJyA/IHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGVsYXkgOiBkZWxheUZvcmNlO1xyXG4gICAgYXV0b3BsYXlEZWxheVRvdGFsID0gc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kZWxheTtcclxuICAgIGF1dG9wbGF5RGVsYXlDdXJyZW50ID0gc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kZWxheTtcclxuICAgIGNvbnN0IGN1cnJlbnRTbGlkZURlbGF5ID0gZ2V0U2xpZGVEZWxheSgpO1xyXG4gICAgaWYgKCFOdW1iZXIuaXNOYU4oY3VycmVudFNsaWRlRGVsYXkpICYmIGN1cnJlbnRTbGlkZURlbGF5ID4gMCAmJiB0eXBlb2YgZGVsYXlGb3JjZSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgZGVsYXkgPSBjdXJyZW50U2xpZGVEZWxheTtcclxuICAgICAgYXV0b3BsYXlEZWxheVRvdGFsID0gY3VycmVudFNsaWRlRGVsYXk7XHJcbiAgICAgIGF1dG9wbGF5RGVsYXlDdXJyZW50ID0gY3VycmVudFNsaWRlRGVsYXk7XHJcbiAgICB9XHJcbiAgICBhdXRvcGxheVRpbWVMZWZ0ID0gZGVsYXk7XHJcbiAgICBjb25zdCBzcGVlZCA9IHN3aXBlci5wYXJhbXMuc3BlZWQ7XHJcbiAgICBjb25zdCBwcm9jZWVkID0gKCkgPT4ge1xyXG4gICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XHJcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9wbGF5LnJldmVyc2VEaXJlY3Rpb24pIHtcclxuICAgICAgICBpZiAoIXN3aXBlci5pc0JlZ2lubmluZyB8fCBzd2lwZXIucGFyYW1zLmxvb3AgfHwgc3dpcGVyLnBhcmFtcy5yZXdpbmQpIHtcclxuICAgICAgICAgIHN3aXBlci5zbGlkZVByZXYoc3BlZWQsIHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgZW1pdCgnYXV0b3BsYXknKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCFzd2lwZXIucGFyYW1zLmF1dG9wbGF5LnN0b3BPbkxhc3RTbGlkZSkge1xyXG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxLCBzcGVlZCwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICBlbWl0KCdhdXRvcGxheScpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoIXN3aXBlci5pc0VuZCB8fCBzd2lwZXIucGFyYW1zLmxvb3AgfHwgc3dpcGVyLnBhcmFtcy5yZXdpbmQpIHtcclxuICAgICAgICAgIHN3aXBlci5zbGlkZU5leHQoc3BlZWQsIHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgZW1pdCgnYXV0b3BsYXknKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCFzd2lwZXIucGFyYW1zLmF1dG9wbGF5LnN0b3BPbkxhc3RTbGlkZSkge1xyXG4gICAgICAgICAgc3dpcGVyLnNsaWRlVG8oMCwgc3BlZWQsIHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgZW1pdCgnYXV0b3BsYXknKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICAgIGF1dG9wbGF5U3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgIHJ1bigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgaWYgKGRlbGF5ID4gMCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XHJcbiAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBwcm9jZWVkKCk7XHJcbiAgICAgIH0sIGRlbGF5KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgcHJvY2VlZCgpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICAgIHJldHVybiBkZWxheTtcclxuICB9O1xyXG4gIGNvbnN0IHN0YXJ0ID0gKCkgPT4ge1xyXG4gICAgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcgPSB0cnVlO1xyXG4gICAgcnVuKCk7XHJcbiAgICBlbWl0KCdhdXRvcGxheVN0YXJ0Jyk7XHJcbiAgfTtcclxuICBjb25zdCBzdG9wID0gKCkgPT4ge1xyXG4gICAgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcgPSBmYWxzZTtcclxuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZik7XHJcbiAgICBlbWl0KCdhdXRvcGxheVN0b3AnKTtcclxuICB9O1xyXG4gIGNvbnN0IHBhdXNlID0gKGludGVybmFsLCByZXNldCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm47XHJcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XHJcbiAgICBpZiAoIWludGVybmFsKSB7XHJcbiAgICAgIHBhdXNlZEJ5SW50ZXJhY3Rpb24gPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcHJvY2VlZCA9ICgpID0+IHtcclxuICAgICAgZW1pdCgnYXV0b3BsYXlQYXVzZScpO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvcGxheS53YWl0Rm9yVHJhbnNpdGlvbikge1xyXG4gICAgICAgIHN3aXBlci53cmFwcGVyRWwuYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIG9uVHJhbnNpdGlvbkVuZCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVzdW1lKCk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gdHJ1ZTtcclxuICAgIGlmIChyZXNldCkge1xyXG4gICAgICBpZiAoc2xpZGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgYXV0b3BsYXlUaW1lTGVmdCA9IHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGVsYXk7XHJcbiAgICAgIH1cclxuICAgICAgc2xpZGVDaGFuZ2VkID0gZmFsc2U7XHJcbiAgICAgIHByb2NlZWQoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgZGVsYXkgPSBhdXRvcGxheVRpbWVMZWZ0IHx8IHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGVsYXk7XHJcbiAgICBhdXRvcGxheVRpbWVMZWZ0ID0gZGVsYXkgLSAobmV3IERhdGUoKS5nZXRUaW1lKCkgLSBhdXRvcGxheVN0YXJ0VGltZSk7XHJcbiAgICBpZiAoc3dpcGVyLmlzRW5kICYmIGF1dG9wbGF5VGltZUxlZnQgPCAwICYmICFzd2lwZXIucGFyYW1zLmxvb3ApIHJldHVybjtcclxuICAgIGlmIChhdXRvcGxheVRpbWVMZWZ0IDwgMCkgYXV0b3BsYXlUaW1lTGVmdCA9IDA7XHJcbiAgICBwcm9jZWVkKCk7XHJcbiAgfTtcclxuICBjb25zdCByZXN1bWUgP
9266SAoKSA9PiB7XHJcbiAgICBpZiAoKHN3aXBlci5pc0VuZCAmJiBhdXRvcGxheVRpbWVMZWZ0IDwgMCAmJiAhc3dpcGVyLnBhcmFtcy5sb29wKSB8fCBzd2lwZXIuZGVzdHJveWVkIHx8ICFzd2lwZXIuYXV0b3BsYXkucnVubmluZylcclxuICAgICAgcmV0dXJuO1xyXG4gICAgYXV0b3BsYXlTdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIGlmIChwYXVzZWRCeUludGVyYWN0aW9uKSB7XHJcbiAgICAgIHBhdXNlZEJ5SW50ZXJhY3Rpb24gPSBmYWxzZTtcclxuICAgICAgcnVuKGF1dG9wbGF5VGltZUxlZnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcnVuKCk7XHJcbiAgICB9XHJcbiAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gZmFsc2U7XHJcbiAgICBlbWl0KCdhdXRvcGxheVJlc3VtZScpO1xyXG4gIH07XHJcbiAgY29uc3Qgb25WaXNpYmlsaXR5Q2hhbmdlID0gKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm47XHJcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XHJcbiAgICBpZiAoZG9jdW1lbnQudmlzaWJpbGl0eVN0YXRlID09PSAnaGlkZGVuJykge1xyXG4gICAgICBwYXVzZWRCeUludGVyYWN0aW9uID0gdHJ1ZTtcclxuICAgICAgcGF1c2UodHJ1ZSk7XHJcbiAgICB9XHJcbiAgICBpZiAoZG9jdW1lbnQudmlzaWJpbGl0eVN0YXRlID09PSAndmlzaWJsZScpIHtcclxuICAgICAgcmVzdW1lKCk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBvblBvaW50ZXJFbnRlciA9IChlKSA9PiB7XHJcbiAgICBpZiAoZS5wb2ludGVyVHlwZSAhPT0gJ21vdXNlJykgcmV0dXJuO1xyXG4gICAgcGF1c2VkQnlJbnRlcmFjdGlvbiA9IHRydWU7XHJcbiAgICBwYXVzZSh0cnVlKTtcclxuICB9O1xyXG4gIGNvbnN0IG9uUG9pbnRlckxlYXZlID0gKGUpID0+IHtcclxuICAgIGlmIChlLnBvaW50ZXJUeXBlICE9PSAnbW91c2UnKSByZXR1cm47XHJcbiAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCkge1xyXG4gICAgICByZXN1bWUoKTtcclxuICAgIH1cclxuICB9O1xyXG4gIGNvbnN0IGF0dGFjaE1vdXNlRXZlbnRzID0gKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkucGF1c2VPbk1vdXNlRW50ZXIpIHtcclxuICAgICAgc3dpcGVyLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJlbnRlcicsIG9uUG9pbnRlckVudGVyKTtcclxuICAgICAgc3dpcGVyLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJsZWF2ZScsIG9uUG9pbnRlckxlYXZlKTtcclxuICAgIH1cclxuICB9O1xyXG4gIGNvbnN0IGRldGFjaE1vdXNlRXZlbnRzID0gKCkgPT4ge1xyXG4gICAgc3dpcGVyLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJlbnRlcicsIG9uUG9pbnRlckVudGVyKTtcclxuICAgIHN3aXBlci5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybGVhdmUnLCBvblBvaW50ZXJMZWF2ZSk7XHJcbiAgfTtcclxuICBjb25zdCBhdHRhY2hEb2N1bWVudEV2ZW50cyA9ICgpID0+IHtcclxuICAgIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCBvblZpc2liaWxpdHlDaGFuZ2UpO1xyXG4gIH07XHJcbiAgY29uc3QgZGV0YWNoRG9jdW1lbnRFdmVudHMgPSAoKSA9PiB7XHJcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XHJcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgb25WaXNpYmlsaXR5Q2hhbmdlKTtcclxuICB9O1xyXG4gIG9uKCdpbml0JywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZW5hYmxlZCkge1xyXG4gICAgICBhdHRhY2hNb3VzZUV2ZW50cygpO1xyXG4gICAgICBhdHRhY2hEb2N1bWVudEV2ZW50cygpO1xyXG4gICAgICBhdXRvcGxheVN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICBzdGFydCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xyXG4gICAgZGV0YWNoTW91c2VFdmVudHMoKTtcclxuICAgIGRldGFjaERvY3VtZW50RXZlbnRzKCk7XHJcbiAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHtcclxuICAgICAgc3RvcCgpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdiZWZvcmVUcmFuc2l0aW9uU3RhcnQnLCAoX3MsIHNwZWVkLCBpbnRlcm5hbCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm47XHJcbiAgICBpZiAoaW50ZXJuYWwgfHwgIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcclxuICAgICAgcGF1c2UodHJ1ZSwgdHJ1ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdG9wKCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgb24oJ3NsaWRlckZpcnN0TW92ZScsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIuZGVzdHJveWVkIHx8ICFzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcmV0dXJuO1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcclxuICAgICAgc3RvcCgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpc1RvdWNoZWQgPSB0cnVlO1xyXG4gICAgcGF1c2VkQnlUb3VjaCA9IGZhbHNlO1xyXG4gICAgcGF1c2VkQnlJbnRlcmFjdGlvbiA9IGZhbHNlO1xyXG4gICAgdG91Y2hTdGFydFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgcGF1c2VkQnlJbnRlcmFjdGlvbiA9IHRydWU7XHJcbiAgICAgIHBhdXNlZEJ5VG91Y2ggPSB0cnVlO1xyXG4gICAgICBwYXVzZSh0cnVlKTtcclxuICAgIH0sIDIwMCk7XHJcbiAgfSk7XHJcbiAgb24oJ3RvdWNoRW5kJywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nIHx8ICFpc1RvdWNoZWQpIHJldHVybjtcclxuICAgIGNsZWFyVGltZW91dCh0b3VjaFN0YXJ0VGltZW91dCk7XHJcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kaXNhYmxlT25Jb
9266nRlcmFjdGlvbikge1xyXG4gICAgICBwYXVzZWRCeVRvdWNoID0gZmFsc2U7XHJcbiAgICAgIGlzVG91Y2hlZCA9IGZhbHNlO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAocGF1c2VkQnlUb3VjaCAmJiBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJlc3VtZSgpO1xyXG4gICAgcGF1c2VkQnlUb3VjaCA9IGZhbHNlO1xyXG4gICAgaXNUb3VjaGVkID0gZmFsc2U7XHJcbiAgfSk7XHJcbiAgb24oJ3NsaWRlQ2hhbmdlJywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm47XHJcbiAgICBzbGlkZUNoYW5nZWQgPSB0cnVlO1xyXG4gIH0pO1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLmF1dG9wbGF5LCB7XHJcbiAgICBzdGFydCxcclxuICAgIHN0b3AsXHJcbiAgICBwYXVzZSxcclxuICAgIHJlc3VtZSxcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gVGh1bWIoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgdGh1bWJzOiB7XHJcbiAgICAgIHN3aXBlcjogbnVsbCxcclxuICAgICAgbXVsdGlwbGVBY3RpdmVUaHVtYnM6IHRydWUsXHJcbiAgICAgIGF1dG9TY3JvbGxPZmZzZXQ6IDAsXHJcbiAgICAgIHNsaWRlVGh1bWJBY3RpdmVDbGFzczogJ3N3aXBlci1zbGlkZS10aHVtYi1hY3RpdmUnLFxyXG4gICAgICB0aHVtYnNDb250YWluZXJDbGFzczogJ3N3aXBlci10aHVtYnMnLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBsZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICBsZXQgc3dpcGVyQ3JlYXRlZCA9IGZhbHNlO1xyXG4gIHN3aXBlci50aHVtYnMgPSB7XHJcbiAgICBzd2lwZXI6IG51bGwsXHJcbiAgfTtcclxuICBmdW5jdGlvbiBvblRodW1iQ2xpY2soKSB7XHJcbiAgICBjb25zdCB0aHVtYnNTd2lwZXIgPSBzd2lwZXIudGh1bWJzLnN3aXBlcjtcclxuICAgIGlmICghdGh1bWJzU3dpcGVyIHx8IHRodW1ic1N3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgIGNvbnN0IGNsaWNrZWRJbmRleCA9IHRodW1ic1N3aXBlci5jbGlja2VkSW5kZXg7XHJcbiAgICBjb25zdCBjbGlja2VkU2xpZGUgPSB0aHVtYnNTd2lwZXIuY2xpY2tlZFNsaWRlO1xyXG4gICAgaWYgKGNsaWNrZWRTbGlkZSAmJiBjbGlja2VkU2xpZGUuY2xhc3NMaXN0LmNvbnRhaW5zKHN3aXBlci5wYXJhbXMudGh1bWJzLnNsaWRlVGh1bWJBY3RpdmVDbGFzcykpIHJldHVybjtcclxuICAgIGlmICh0eXBlb2YgY2xpY2tlZEluZGV4ID09PSAndW5kZWZpbmVkJyB8fCBjbGlja2VkSW5kZXggPT09IG51bGwpIHJldHVybjtcclxuICAgIGxldCBzbGlkZVRvSW5kZXg7XHJcbiAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5sb29wKSB7XHJcbiAgICAgIHNsaWRlVG9JbmRleCA9IHBhcnNlSW50KHRodW1ic1N3aXBlci5jbGlja2VkU2xpZGUuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzbGlkZVRvSW5kZXggPSBjbGlja2VkSW5kZXg7XHJcbiAgICB9XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvTG9vcChzbGlkZVRvSW5kZXgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG8oc2xpZGVUb0luZGV4KTtcclxuICAgIH1cclxuICB9XHJcbiAgZnVuY3Rpb24gaW5pdCgpIHtcclxuICAgIGNvbnN0IHsgdGh1bWJzOiB0aHVtYnNQYXJhbXMgfSA9IHN3aXBlci5wYXJhbXM7XHJcbiAgICBpZiAoaW5pdGlhbGl6ZWQpIHJldHVybiBmYWxzZTtcclxuICAgIGluaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgIGNvbnN0IFN3aXBlckNsYXNzID0gc3dpcGVyLmNvbnN0cnVjdG9yO1xyXG4gICAgaWYgKHRodW1ic1BhcmFtcy5zd2lwZXIgaW5zdGFuY2VvZiBTd2lwZXJDbGFzcykge1xyXG4gICAgICBzd2lwZXIudGh1bWJzLnN3aXBlciA9IHRodW1ic1BhcmFtcy5zd2lwZXI7XHJcbiAgICAgIE9iamVjdC5hc3NpZ24oc3dpcGVyLnRodW1icy5zd2lwZXIub3JpZ2luYWxQYXJhbXMsIHtcclxuICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxyXG4gICAgICAgIHNsaWRlVG9DbGlja2VkU2xpZGU6IGZhbHNlLFxyXG4gICAgICB9KTtcclxuICAgICAgT2JqZWN0LmFzc2lnbihzd2lwZXIudGh1bWJzLnN3aXBlci5wYXJhbXMsIHtcclxuICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxyXG4gICAgICAgIHNsaWRlVG9DbGlja2VkU2xpZGU6IGZhbHNlLFxyXG4gICAgICB9KTtcclxuICAgICAgc3dpcGVyLnRodW1icy5zd2lwZXIudXBkYXRlKCk7XHJcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHRodW1ic1BhcmFtcy5zd2lwZXIpKSB7XHJcbiAgICAgIGNvbnN0IHRodW1ic1N3aXBlclBhcmFtcyA9IE9iamVjdC5hc3NpZ24oe30sIHRodW1ic1BhcmFtcy5zd2lwZXIpO1xyXG4gICAgICBPYmplY3QuYXNzaWduKHRodW1ic1N3aXBlclBhcmFtcywge1xyXG4gICAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXHJcbiAgICAgICAgc2xpZGVUb0NsaWNrZWRTbGlkZTogZmFsc2UsXHJcbiAgICAgIH0pO1xyXG4gICAgICBzd2lwZXIudGh1bWJzLnN3aXBlciA9IG5ldyBTd2lwZXJDbGFzcyh0aHVtYnNTd2lwZXJQYXJhbXMpO1xyXG4gICAgICBzd2lwZXJDcmVhdGVkID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHN3aXBlci50aHVtYnMuc3dpcGVyLmVsLmNsYXNzTGlzdC5hZGQoc3dpcGVyLnBhcmFtcy50aHVtYnMudGh1bWJzQ29udGFpbmVyQ2xhc3MpO1xyXG4gICAgc3dpcGVyLnRodW1icy5zd2lwZXIub24oJ3RhcCcsIG9uVGh1bWJDbGljayk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcbiAgZnVuY3Rpb24gdXBkYXRlKGluaXRpYWwpIHtcclxuICAgIGNvbnN0IHRodW1ic1N3aXBlciA9IHN3aXBlci50aHVtYnMuc3dpcGVyO1xyXG4gICAgaWYgKCF0aHVtYnNTd2lwZXIgfHwgdGh1bWJzU3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xyXG4gICAgY29uc3Qgc2xpZGVzUGVyVmlldyA9XHJcbiAgICAgIHRodW1ic1N3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nXHJcbiAgICAgICAgPyB0aHVtYnNTd2lwZXIuc2xpZGVzUGVyVmlld0R5bmFtaWMoKVxyXG4gICAgICAgIDogdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3O1xyXG5cclxuICAgIC8vIEFjdGl2YXRlIHRodW1ic1xyXG4gICAgbGV0IHRodW1ic1RvQWN0aXZhdGUgPSAxO1xyXG4gICAgY29uc3QgdGh1bWJBY3RpdmVDbGFzcyA9IHN3aXBlci5wYXJhbXMudGh1bWJzLnNsaWRlVGh1bWJBY3RpdmVDbGFzcztcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLnNsaWRlc1BlclZpZXcgPiAxICYmICFzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XHJcbiAgICAgIHRodW1ic1RvQWN0aXZhdGUgPSBzd2lwZXIucGFyYW1zLnNsaWRlc1BlclZpZXc7XHJcbiAgICB9XHJcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMudGh1bWJzLm11bHRpcGxlQWN0aXZlVGh1bWJzKSB7XHJcbiAgICAgIHRodW1ic1RvQWN0aXZhdGUgPSAxO1xyXG4gICAgfVxyXG4gICAgdGh1bWJzVG9BY3RpdmF0ZSA9IE1hdGguZmxvb3IodGh1bWJzVG9BY3RpdmF0ZSk7XHJcbiAgICB0aHVtYnNTd2lwZXIuc2xpZGVzLmZvckVhY2goKHNsaWRlRWwpID0+IHNsaWRlRWwuY2xhc3NMaXN0LnJlbW92ZSh0aHVtYkFjdGl2ZUNsYXNzKSk7XHJcbiAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5sb29w
9266IHx8ICh0aHVtYnNTd2lwZXIucGFyYW1zLnZpcnR1YWwgJiYgdGh1bWJzU3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGh1bWJzVG9BY3RpdmF0ZTsgaSArPSAxKSB7XHJcbiAgICAgICAgZWxlbWVudENoaWxkcmVuKHRodW1ic1N3aXBlci5zbGlkZXNFbCwgYFtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7c3dpcGVyLnJlYWxJbmRleCArIGl9XCJdYCkuZm9yRWFjaChcclxuICAgICAgICAgIChzbGlkZUVsKSA9PiB7XHJcbiAgICAgICAgICAgIHNsaWRlRWwuY2xhc3NMaXN0LmFkZCh0aHVtYkFjdGl2ZUNsYXNzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRodW1ic1RvQWN0aXZhdGU7IGkgKz0gMSkge1xyXG4gICAgICAgIGlmICh0aHVtYnNTd2lwZXIuc2xpZGVzW3N3aXBlci5yZWFsSW5kZXggKyBpXSkge1xyXG4gICAgICAgICAgdGh1bWJzU3dpcGVyLnNsaWRlc1tzd2lwZXIucmVhbEluZGV4ICsgaV0uY2xhc3NMaXN0LmFkZCh0aHVtYkFjdGl2ZUNsYXNzKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGNvbnN0IGF1dG9TY3JvbGxPZmZzZXQgPSBzd2lwZXIucGFyYW1zLnRodW1icy5hdXRvU2Nyb2xsT2Zmc2V0O1xyXG4gICAgY29uc3QgdXNlT2Zmc2V0ID0gYXV0b1Njcm9sbE9mZnNldCAmJiAhdGh1bWJzU3dpcGVyLnBhcmFtcy5sb29wO1xyXG4gICAgaWYgKHN3aXBlci5yZWFsSW5kZXggIT09IHRodW1ic1N3aXBlci5yZWFsSW5kZXggfHwgdXNlT2Zmc2V0KSB7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRUaHVtYnNJbmRleCA9IHRodW1ic1N3aXBlci5hY3RpdmVJbmRleDtcclxuICAgICAgbGV0IG5ld1RodW1ic0luZGV4O1xyXG4gICAgICBsZXQgZGlyZWN0aW9uO1xyXG4gICAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5sb29wKSB7XHJcbiAgICAgICAgY29uc3QgbmV3VGh1bWJzU2xpZGUgPSB0aHVtYnNTd2lwZXIuc2xpZGVzLmZpbHRlcihcclxuICAgICAgICAgIChzbGlkZUVsKSA9PiBzbGlkZUVsLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSA9PT0gYCR7c3dpcGVyLnJlYWxJbmRleH1gXHJcbiAgICAgICAgKVswXTtcclxuICAgICAgICBuZXdUaHVtYnNJbmRleCA9IHRodW1ic1N3aXBlci5zbGlkZXMuaW5kZXhPZihuZXdUaHVtYnNTbGlkZSk7XHJcbiAgICAgICAgZGlyZWN0aW9uID0gc3dpcGVyLmFjdGl2ZUluZGV4ID4gc3dpcGVyLnByZXZpb3VzSW5kZXggPyAnbmV4dCcgOiAncHJldic7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBzd2lwZXIucmVhbEluZGV4O1xyXG4gICAgICAgIGRpcmVjdGlvbiA9IG5ld1RodW1ic0luZGV4ID4gc3dpcGVyLnByZXZpb3VzSW5kZXggPyAnbmV4dCcgOiAncHJldic7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHVzZU9mZnNldCkge1xyXG4gICAgICAgIG5ld1RodW1ic0luZGV4ICs9IGRpcmVjdGlvbiA9PT0gJ25leHQnID8gYXV0b1Njcm9sbE9mZnNldCA6IC0xICogYXV0b1Njcm9sbE9mZnNldDtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGh1bWJzU3dpcGVyLnZpc2libGVTbGlkZXNJbmRleGVzICYmIHRodW1ic1N3aXBlci52aXNpYmxlU2xpZGVzSW5kZXhlcy5pbmRleE9mKG5ld1RodW1ic0luZGV4KSA8IDApIHtcclxuICAgICAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xyXG4gICAgICAgICAgaWYgKG5ld1RodW1ic0luZGV4ID4gY3VycmVudFRodW1ic0luZGV4KSB7XHJcbiAgICAgICAgICAgIG5ld1RodW1ic0luZGV4ID0gbmV3VGh1bWJzSW5kZXggLSBNYXRoLmZsb29yKHNsaWRlc1BlclZpZXcgLyAyKSArIDE7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBuZXdUaHVtYnNJbmRleCA9IG5ld1RodW1ic0luZGV4ICsgTWF0aC5mbG9vcihzbGlkZXNQZXJWaWV3IC8gMikgLSAxO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3VGh1bWJzSW5kZXggPiBjdXJyZW50VGh1bWJzSW5kZXggJiYgdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA9PT0gMSk7XHJcbiAgICAgICAgdGh1bWJzU3dpcGVyLnNsaWRlVG8obmV3VGh1bWJzSW5kZXgsIGluaXRpYWwgPyAwIDogdW5kZWZpbmVkKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBvbignYmVmb3JlSW5pdCcsICgpID0+IHtcclxuICAgIGNvbnN0IHsgdGh1bWJzIH0gPSBzd2lwZXIucGFyYW1zO1xyXG4gICAgaWYgKCF0aHVtYnMgfHwgIXRodW1icy5zd2lwZXIpIHJldHVybjtcclxuICAgIGlmICh0eXBlb2YgdGh1bWJzLnN3aXBlciA9PT0gJ3N0cmluZycgfHwgdGh1bWJzLnN3aXBlciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XHJcbiAgICAgIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcclxuICAgICAgY29uc3QgZ2V0VGh1bWJzRWxlbWVudEFuZEluaXQgPSAoKSA9PiB7XHJcbiAgICAgICAgY29uc3QgdGh1bWJzRWxlbWVudCA9IHR5cGVvZiB0aHVtYnMuc3dpcGVyID09PSAnc3RyaW5nJyA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGh1bWJzLnN3aXBlcikgOiB0aHVtYnMuc3dpcGVyO1xyXG4gICAgICAgIGlmICh0aHVtYnNFbGVtZW50ICYmIHRodW1ic0VsZW1lbnQuc3dpcGVyKSB7XHJcbiAgICAgICAgICB0aHVtYnMuc3dpcGVyID0gdGh1bWJzRWxlbWVudC5zd2lwZXI7XHJcbiAgICAgICAgICBpbml0KCk7XHJcbiAgICAgICAgICB1cGRhdGUodHJ1ZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aHVtYnNFbGVtZW50KSB7XHJcbiAgICAgICAgICBjb25zdCBvblRodW1ic1N3aXBlciA9IChlKSA9PiB7XHJcbiAgICAgICAgICAgIHRodW1icy5zd2lwZXIgPSBlLmRldGFpbFswXTtcclxuICAgICAgICAgICAgdGh1bWJzRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdpbml0Jywgb25UaHVtYnNTd2lwZXIpO1xyXG4gICAgICAgICAgICBpbml0KCk7XHJcbiAgICAgICAgICAgIHVwZGF0ZSh0cnVlKTtcclxuICAgICAgICAgICAgdGh1bWJzLnN3aXBlci51cGRhdGUoKTtcclxuICAgICAgICAgICAgc3dpcGVyLnVwZGF0ZSgpO1xyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgI
9266HRodW1ic0VsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignaW5pdCcsIG9uVGh1bWJzU3dpcGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRodW1ic0VsZW1lbnQ7XHJcbiAgICAgIH07XHJcbiAgICAgIGNvbnN0IHdhdGNoRm9yVGh1bWJzVG9BcHBlYXIgPSAoKSA9PiB7XHJcbiAgICAgICAgaWYgKHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgICAgICBjb25zdCB0aHVtYnNFbGVtZW50ID0gZ2V0VGh1bWJzRWxlbWVudEFuZEluaXQoKTtcclxuICAgICAgICBpZiAoIXRodW1ic0VsZW1lbnQpIHtcclxuICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh3YXRjaEZvclRodW1ic1RvQXBwZWFyKTtcclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh3YXRjaEZvclRodW1ic1RvQXBwZWFyKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGluaXQoKTtcclxuICAgICAgdXBkYXRlKHRydWUpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIG9uKCdzbGlkZUNoYW5nZSB1cGRhdGUgcmVzaXplIG9ic2VydmVyVXBkYXRlJywgKCkgPT4ge1xyXG4gICAgdXBkYXRlKCk7XHJcbiAgfSk7XHJcbiAgb24oJ3NldFRyYW5zaXRpb24nLCAoX3MsIGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0aHVtYnNTd2lwZXIgPSBzd2lwZXIudGh1bWJzLnN3aXBlcjtcclxuICAgIGlmICghdGh1bWJzU3dpcGVyIHx8IHRodW1ic1N3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgIHRodW1ic1N3aXBlci5zZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcclxuICB9KTtcclxuICBvbignYmVmb3JlRGVzdHJveScsICgpID0+IHtcclxuICAgIGNvbnN0IHRodW1ic1N3aXBlciA9IHN3aXBlci50aHVtYnMuc3dpcGVyO1xyXG4gICAgaWYgKCF0aHVtYnNTd2lwZXIgfHwgdGh1bWJzU3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xyXG4gICAgaWYgKHN3aXBlckNyZWF0ZWQpIHtcclxuICAgICAgdGh1bWJzU3dpcGVyLmRlc3Ryb3koKTtcclxuICAgIH1cclxuICB9KTtcclxuICBPYmplY3QuYXNzaWduKHN3aXBlci50aHVtYnMsIHtcclxuICAgIGluaXQsXHJcbiAgICB1cGRhdGUsXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZyZWVNb2RlKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgZW1pdCwgb25jZSB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgZnJlZU1vZGU6IHtcclxuICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICAgIG1vbWVudHVtOiB0cnVlLFxyXG4gICAgICBtb21lbnR1bVJhdGlvOiAxLFxyXG4gICAgICBtb21lbnR1bUJvdW5jZTogdHJ1ZSxcclxuICAgICAgbW9tZW50dW1Cb3VuY2VSYXRpbzogMSxcclxuICAgICAgbW9tZW50dW1WZWxvY2l0eVJhdGlvOiAxLFxyXG4gICAgICBzdGlja3k6IGZhbHNlLFxyXG4gICAgICBtaW5pbXVtVmVsb2NpdHk6IDAuMDIsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGZ1bmN0aW9uIG9uVG91Y2hTdGFydCgpIHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJldHVybjtcclxuICAgIGNvbnN0IHRyYW5zbGF0ZSA9IHN3aXBlci5nZXRUcmFuc2xhdGUoKTtcclxuICAgIHN3aXBlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlKTtcclxuICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKDApO1xyXG4gICAgc3dpcGVyLnRvdWNoRXZlbnRzRGF0YS52ZWxvY2l0aWVzLmxlbmd0aCA9IDA7XHJcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaEVuZCh7XHJcbiAgICAgIGN1cnJlbnRQb3M6IHN3aXBlci5ydGwgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGUsXHJcbiAgICB9KTtcclxuICB9XHJcbiAgZnVuY3Rpb24gb25Ub3VjaE1vdmUoKSB7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSByZXR1cm47XHJcbiAgICBjb25zdCB7IHRvdWNoRXZlbnRzRGF0YTogZGF0YSwgdG91Y2hlcyB9ID0gc3dpcGVyO1xyXG4gICAgLy8gVmVsb2NpdHlcclxuICAgIGlmIChkYXRhLnZlbG9jaXRpZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIGRhdGEudmVsb2NpdGllcy5wdXNoKHtcclxuICAgICAgICBwb3NpdGlvbjogdG91Y2hlc1tzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnc3RhcnRYJyA6ICdzdGFydFknXSxcclxuICAgICAgICB0aW1lOiBkYXRhLnRvdWNoU3RhcnRUaW1lLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGRhdGEudmVsb2NpdGllcy5wdXNoKHtcclxuICAgICAgcG9zaXRpb246IHRvdWNoZXNbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ2N1cnJlbnRYJyA6ICdjdXJyZW50WSddLFxyXG4gICAgICB0aW1lOiBub3coKSxcclxuICAgIH0pO1xyXG4gIH1cclxuICBmdW5jdGlvbiBvblRvdWNoRW5kKF9yZWYyKSB7XHJcbiAgICBsZXQgeyBjdXJyZW50UG9zIH0gPSBfcmVmMjtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJldHVybjtcclxuICAgIGNvbnN0IHsgcGFyYW1zLCB3cmFwcGVyRWwsIHJ0bFRyYW5zbGF0ZTogcnRsLCBzbmFwR3JpZCwgdG91Y2hFdmVudHNEYXRhOiBkYXRhIH0gPSBzd2lwZXI7XHJcbiAgICAvLyBUaW1lIGRpZmZcclxuICAgIGNvbnN0IHRvdWNoRW5kVGltZSA9IG5vdygpO1xyXG4gICAgY29uc3QgdGltZURpZmYgPSB0b3VjaEVuZFRpbWUgLSBkYXRhLnRvdWNoU3RhcnRUaW1lO1xyXG4gICAgaWYgKGN1cnJlbnRQb3MgPCAtc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSB7XHJcbiAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5hY3RpdmVJbmRleCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChjdXJyZW50UG9zID4gLXN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xyXG4gICAgICBpZiAoc3dpcGVyLnNsaWRlcy5sZW5ndGggPCBzbmFwR3JpZC5sZW5ndGgpIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbmFwR3JpZC5sZW5ndGggLSAxKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChwYXJhbXMuZnJlZU1vZGUubW9tZW50dW0pIHtcclxuICAgICAgaWYgKGRhdGEudmVsb2NpdGllcy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgY29uc3QgbGFzdE1vdmVFdmVudCA9IGRhdGEudmVsb2NpdGllcy5wb3AoKTtcclxuICAgICAgICBjb25zdCB2ZWxvY2l0eUV2ZW50ID0gZGF0YS52ZWxvY2l0aWVzLnBvcCgpO1xyXG4gICAgICAgIGNvbnN0IGRpc3R
9266hbmNlID0gbGFzdE1vdmVFdmVudC5wb3NpdGlvbiAtIHZlbG9jaXR5RXZlbnQucG9zaXRpb247XHJcbiAgICAgICAgY29uc3QgdGltZSA9IGxhc3RNb3ZlRXZlbnQudGltZSAtIHZlbG9jaXR5RXZlbnQudGltZTtcclxuICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSBkaXN0YW5jZSAvIHRpbWU7XHJcbiAgICAgICAgc3dpcGVyLnZlbG9jaXR5IC89IDI7XHJcbiAgICAgICAgaWYgKE1hdGguYWJzKHN3aXBlci52ZWxvY2l0eSkgPCBwYXJhbXMuZnJlZU1vZGUubWluaW11bVZlbG9jaXR5KSB7XHJcbiAgICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0aGlzIGltcGxpZXMgdGhhdCB0aGUgdXNlciBzdG9wcGVkIG1vdmluZyBhIGZpbmdlciB0aGVuIHJlbGVhc2VkLlxyXG4gICAgICAgIC8vIFRoZXJlIHdvdWxkIGJlIG5vIGV2ZW50cyB3aXRoIGRpc3RhbmNlIHplcm8sIHNvIHRoZSBsYXN0IGV2ZW50IGlzIHN0YWxlLlxyXG4gICAgICAgIGlmICh0aW1lID4gMTUwIHx8IG5vdygpIC0gbGFzdE1vdmVFdmVudC50aW1lID4gMzAwKSB7XHJcbiAgICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xyXG4gICAgICB9XHJcbiAgICAgIHN3aXBlci52ZWxvY2l0eSAqPSBwYXJhbXMuZnJlZU1vZGUubW9tZW50dW1WZWxvY2l0eVJhdGlvO1xyXG4gICAgICBkYXRhLnZlbG9jaXRpZXMubGVuZ3RoID0gMDtcclxuICAgICAgbGV0IG1vbWVudHVtRHVyYXRpb24gPSAxMDAwICogcGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtUmF0aW87XHJcbiAgICAgIGNvbnN0IG1vbWVudHVtRGlzdGFuY2UgPSBzd2lwZXIudmVsb2NpdHkgKiBtb21lbnR1bUR1cmF0aW9uO1xyXG4gICAgICBsZXQgbmV3UG9zaXRpb24gPSBzd2lwZXIudHJhbnNsYXRlICsgbW9tZW50dW1EaXN0YW5jZTtcclxuICAgICAgaWYgKHJ0bCkgbmV3UG9zaXRpb24gPSAtbmV3UG9zaXRpb247XHJcbiAgICAgIGxldCBkb0JvdW5jZSA9IGZhbHNlO1xyXG4gICAgICBsZXQgYWZ0ZXJCb3VuY2VQb3NpdGlvbjtcclxuICAgICAgY29uc3QgYm91bmNlQW1vdW50ID0gTWF0aC5hYnMoc3dpcGVyLnZlbG9jaXR5KSAqIDIwICogcGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtQm91bmNlUmF0aW87XHJcbiAgICAgIGxldCBuZWVkc0xvb3BGaXg7XHJcbiAgICAgIGlmIChuZXdQb3NpdGlvbiA8IHN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xyXG4gICAgICAgIGlmIChwYXJhbXMuZnJlZU1vZGUubW9tZW50dW1Cb3VuY2UpIHtcclxuICAgICAgICAgIGlmIChuZXdQb3NpdGlvbiArIHN3aXBlci5tYXhUcmFuc2xhdGUoKSA8IC1ib3VuY2VBbW91bnQpIHtcclxuICAgICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBib3VuY2VBbW91bnQ7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBhZnRlckJvdW5jZVBvc2l0aW9uID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpO1xyXG4gICAgICAgICAgZG9Cb3VuY2UgPSB0cnVlO1xyXG4gICAgICAgICAgZGF0YS5hbGxvd01vbWVudHVtQm91bmNlID0gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwYXJhbXMubG9vcCAmJiBwYXJhbXMuY2VudGVyZWRTbGlkZXMpIG5lZWRzTG9vcEZpeCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAobmV3UG9zaXRpb24gPiBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcclxuICAgICAgICBpZiAocGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtQm91bmNlKSB7XHJcbiAgICAgICAgICBpZiAobmV3UG9zaXRpb24gLSBzd2lwZXIubWluVHJhbnNsYXRlKCkgPiBib3VuY2VBbW91bnQpIHtcclxuICAgICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWluVHJhbnNsYXRlKCkgKyBib3VuY2VBbW91bnQ7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBhZnRlckJvdW5jZVBvc2l0aW9uID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xyXG4gICAgICAgICAgZG9Cb3VuY2UgPSB0cnVlO1xyXG4gICAgICAgICAgZGF0YS5hbGxvd01vbWVudHVtQm91bmNlID0gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwYXJhbXMubG9vcCAmJiBwYXJhbXMuY2VudGVyZWRTbGlkZXMpIG5lZWRzTG9vcEZpeCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAocGFyYW1zLmZyZWVNb2RlLnN0aWNreSkge1xyXG4gICAgICAgIGxldCBuZXh0U2xpZGU7XHJcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzbmFwR3JpZC5sZW5ndGg7IGogKz0gMSkge1xyXG4gICAgICAgICAgaWYgKHNuYXBHcmlkW2pdID4gLW5ld1Bvc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIG5leHRTbGlkZSA9IGo7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICBNYXRoLmFicyhzbmFwR3JpZFtuZXh0U2xpZGVdIC0gbmV3UG9zaXRpb24pIDwgTWF0aC5hYnMoc25hcEdyaWRbbmV4dFNsaWRlIC0gMV0gLSBuZXdQb3NpdGlvbikgfHxcclxuICAgICAgICAgIHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBuZXdQb3NpdGlvbiA9IHNuYXBHcmlkW25leHRTbGlkZV07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG5ld1Bvc2l0aW9uID0gc25hcEdyaWRbbmV4dFNsaWRlIC0gMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG5ld1Bvc2l0aW9uID0gLW5ld1Bvc2l0aW9uO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChuZWVkc0xvb3BGaXgpIHtcclxuICAgICAgICBvbmNlKCd0cmFuc2l0aW9uRW5kJywgKCkgPT4ge1xyXG4gICAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgICAvLyBGaXggZHVyYXRpb25cclxuICAgICAgaWYgKHN3aXBlci52ZWxvY2l0eSAhPT0gMCkge1xyXG4gICAgICAgIGlmIChydGwp
9266IHtcclxuICAgICAgICAgIG1vbWVudHVtRHVyYXRpb24gPSBNYXRoLmFicygoLW5ld1Bvc2l0aW9uIC0gc3dpcGVyLnRyYW5zbGF0ZSkgLyBzd2lwZXIudmVsb2NpdHkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gTWF0aC5hYnMoKG5ld1Bvc2l0aW9uIC0gc3dpcGVyLnRyYW5zbGF0ZSkgLyBzd2lwZXIudmVsb2NpdHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocGFyYW1zLmZyZWVNb2RlLnN0aWNreSkge1xyXG4gICAgICAgICAgLy8gSWYgZnJlZU1vZGUuc3RpY2t5IGlzIGFjdGl2ZSBhbmQgdGhlIHVzZXIgZW5kcyBhIHN3aXBlIHdpdGggYSBzbG93LXZlbG9jaXR5XHJcbiAgICAgICAgICAvLyBldmVudCwgdGhlbiBkdXJhdGlvbnMgY2FuIGJlIDIwKyBzZWNvbmRzIHRvIHNsaWRlIG9uZSAob3IgemVybyEpIHNsaWRlcy5cclxuICAgICAgICAgIC8vIEl0J3MgZWFzeSB0byBzZWUgdGhpcyB3aGVuIHNpbXVsYXRpbmcgdG91Y2ggd2l0aCBtb3VzZSBldmVudHMuIFRvIGZpeCB0aGlzLFxyXG4gICAgICAgICAgLy8gbGltaXQgc2luZ2xlLXNsaWRlIHN3aXBlcyB0byB0aGUgZGVmYXVsdCBzbGlkZSBkdXJhdGlvbi4gVGhpcyBhbHNvIGhhcyB0aGVcclxuICAgICAgICAgIC8vIG5pY2Ugc2lkZSBlZmZlY3Qgb2YgbWF0Y2hpbmcgc2xpZGUgc3BlZWQgaWYgdGhlIHVzZXIgc3RvcHBlZCBtb3ZpbmcgYmVmb3JlXHJcbiAgICAgICAgICAvLyBsaWZ0aW5nIGZpbmdlciBvciBtb3VzZSB2cy4gbW92aW5nIHNsb3dseSBiZWZvcmUgbGlmdGluZyB0aGUgZmluZ2VyL21vdXNlLlxyXG4gICAgICAgICAgLy8gRm9yIGZhc3RlciBzd2lwZXMsIGFsc28gYXBwbHkgbGltaXRzIChhbGJlaXQgaGlnaGVyIG9uZXMpLlxyXG4gICAgICAgICAgY29uc3QgbW92ZURpc3RhbmNlID0gTWF0aC5hYnMoKHJ0bCA/IC1uZXdQb3NpdGlvbiA6IG5ld1Bvc2l0aW9uKSAtIHN3aXBlci50cmFuc2xhdGUpO1xyXG4gICAgICAgICAgY29uc3QgY3VycmVudFNsaWRlU2l6ZSA9IHN3aXBlci5zbGlkZXNTaXplc0dyaWRbc3dpcGVyLmFjdGl2ZUluZGV4XTtcclxuICAgICAgICAgIGlmIChtb3ZlRGlzdGFuY2UgPCBjdXJyZW50U2xpZGVTaXplKSB7XHJcbiAgICAgICAgICAgIG1vbWVudHVtRHVyYXRpb24gPSBwYXJhbXMuc3BlZWQ7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKG1vdmVEaXN0YW5jZSA8IDIgKiBjdXJyZW50U2xpZGVTaXplKSB7XHJcbiAgICAgICAgICAgIG1vbWVudHVtRHVyYXRpb24gPSBwYXJhbXMuc3BlZWQgKiAxLjU7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gcGFyYW1zLnNwZWVkICogMi41O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmIChwYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XHJcbiAgICAgICAgc3dpcGVyLnNsaWRlVG9DbG9zZXN0KCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwYXJhbXMuZnJlZU1vZGUubW9tZW50dW1Cb3VuY2UgJiYgZG9Cb3VuY2UpIHtcclxuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoYWZ0ZXJCb3VuY2VQb3NpdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zaXRpb24obW9tZW50dW1EdXJhdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdQb3NpdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25TdGFydCh0cnVlLCBzd2lwZXIuc3dpcGVEaXJlY3Rpb24pO1xyXG4gICAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgICAgIGVsZW1lbnRUcmFuc2l0aW9uRW5kKHdyYXBwZXJFbCwgKCkgPT4ge1xyXG4gICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCB8fCAhZGF0YS5hbGxvd01vbWVudHVtQm91bmNlKSByZXR1cm47XHJcbiAgICAgICAgICBlbWl0KCdtb21lbnR1bUJvdW5jZScpO1xyXG4gICAgICAgICAgc3dpcGVyLnNldFRyYW5zaXRpb24ocGFyYW1zLnNwZWVkKTtcclxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKGFmdGVyQm91bmNlUG9zaXRpb24pO1xyXG4gICAgICAgICAgICBlbGVtZW50VHJhbnNpdGlvbkVuZCh3cmFwcGVyRWwsICgpID0+IHtcclxuICAgICAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25FbmQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9LCAwKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIGlmIChzd2lwZXIudmVsb2NpdHkpIHtcclxuICAgICAgICBlbWl0KCdfZnJlZU1vZGVOb01vbWVudHVtUmVsZWFzZScpO1xyXG4gICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhuZXdQb3NpdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zaXRpb24obW9tZW50dW1EdXJhdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdQb3NpdGlvbik7XHJcbiAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25TdGFydCh0cnVlLCBzd2lwZXIuc3dpcGVEaXJlY3Rpb24pO1xyXG4gICAgICAgIGlmICghc3dpcGVyLmFuaW1hdGluZykge1xyXG4gICAgICAgICAgc3dpcGVyLmFuaW1hdGluZyA9IHRydWU7XHJcbiAgICAgICAgICBlbGVtZW50VHJhbnNpdGlvbkVuZCh3cmFwcGVyRWwsICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xyXG4gICAgICAgICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZCgpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhuZXdQb3NpdGlvbik7XHJcbiAgICAgIH1cclxuICAgICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XHJcbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XHJcbiAgICB9IGVsc2UgaWYgKHBhcmFtcy5mcmVlTW9kZS5zdGlja3kpIHtcclxuICAgICAgc3dpcGVyLnNsaWRlVG9DbG9zZXN0KCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSBpZiAocGFyYW1zLmZyZWVNb2RlKSB7XHJcbiAgICAgIGVtaXQoJ19mcmVlTW9kZU5vTW9tZW50dW1SZWxlYXNlJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXBhcmFtcy5mcmVlTW9kZS5tb21lbnR1bSB8fCB0aW1lRGlmZiA+PSBwYXJhbXMubG9uZ1N3aXBlc01zKSB7XHJcbiAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcygpO1xyXG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcclxuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcclxuICAgIH1cclxuICB9XHJcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIsIHtcclxuICAgIGZyZWVNb2RlOiB7XHJcbiAgICAgIG9uVG91Y2hTdGFydCxcclxuICAgICAgb25Ub3VjaE1vdmUsXHJcbiAgICAgIG9uVG91Y2hFbmQsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBHcmlkKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcyB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgZ3JpZDoge1xyXG4gICAgICByb3dzOiAxLFxyXG4gICAgICBmaWxsOiAnY29sdW1uJyxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgbGV0IHNsaWRlc051bWJlckV2ZW5Ub1Jvd3M7XHJcbiAgbGV0IHNsaWRlc1BlclJvdztcclxuICBsZXQgbnVtRnVsbENvbHVtbnM7XHJcbiAgY29uc3QgZ2V0U3BhY2VCZXR3ZWVuID0gKCkgPT4ge1xyXG4gICAgbGV0IHNwYWNlQmV0d2VlbiA9IHN3aXBlci5wYXJhbXMuc3BhY2VCZXR3ZWVuO1xyXG4gICAgaWYgKHR5cGVvZiBzcGFjZUJldHdlZW4gPT09ICdzdHJpbmcnICYmIHNwYWNlQmV0d2Vlbi5pbmRleE9mKCclJykgPj0gMCkge1xyXG4gICAgICBzcGFjZUJldHdlZW4gPSAocGFyc2VGbG9hdChzcGFjZUJldHdlZW4ucmVwbGFjZSgnJScsICcnKSkgLyAxMDApICogc3dpcGVyLnNpemU7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzcGFjZUJldHdlZW4gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIHNwYWNlQmV0d2VlbiA9IHBhcnNlRmxvYXQoc3BhY2VCZXR3ZWVuKTtcclxuICAgIH1cclxuICAgIHJldHVybi
9266BzcGFjZUJldHdlZW47XHJcbiAgfTtcclxuICBjb25zdCBpbml0U2xpZGVzID0gKHNsaWRlc0xlbmd0aCkgPT4ge1xyXG4gICAgY29uc3QgeyBzbGlkZXNQZXJWaWV3IH0gPSBzd2lwZXIucGFyYW1zO1xyXG4gICAgY29uc3QgeyByb3dzLCBmaWxsIH0gPSBzd2lwZXIucGFyYW1zLmdyaWQ7XHJcbiAgICBudW1GdWxsQ29sdW1ucyA9IE1hdGguZmxvb3Ioc2xpZGVzTGVuZ3RoIC8gcm93cyk7XHJcbiAgICBpZiAoTWF0aC5mbG9vcihzbGlkZXNMZW5ndGggLyByb3dzKSA9PT0gc2xpZGVzTGVuZ3RoIC8gcm93cykge1xyXG4gICAgICBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzID0gc2xpZGVzTGVuZ3RoO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2xpZGVzTnVtYmVyRXZlblRvUm93cyA9IE1hdGguY2VpbChzbGlkZXNMZW5ndGggLyByb3dzKSAqIHJvd3M7XHJcbiAgICB9XHJcbiAgICBpZiAoc2xpZGVzUGVyVmlldyAhPT0gJ2F1dG8nICYmIGZpbGwgPT09ICdyb3cnKSB7XHJcbiAgICAgIHNsaWRlc051bWJlckV2ZW5Ub1Jvd3MgPSBNYXRoLm1heChzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzLCBzbGlkZXNQZXJWaWV3ICogcm93cyk7XHJcbiAgICB9XHJcbiAgICBzbGlkZXNQZXJSb3cgPSBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzIC8gcm93cztcclxuICB9O1xyXG4gIGNvbnN0IHVwZGF0ZVNsaWRlID0gKGksIHNsaWRlLCBzbGlkZXNMZW5ndGgsIGdldERpcmVjdGlvbkxhYmVsKSA9PiB7XHJcbiAgICBjb25zdCB7IHNsaWRlc1Blckdyb3VwIH0gPSBzd2lwZXIucGFyYW1zO1xyXG4gICAgY29uc3Qgc3BhY2VCZXR3ZWVuID0gZ2V0U3BhY2VCZXR3ZWVuKCk7XHJcbiAgICBjb25zdCB7IHJvd3MsIGZpbGwgfSA9IHN3aXBlci5wYXJhbXMuZ3JpZDtcclxuICAgIC8vIFNldCBzbGlkZXMgb3JkZXJcclxuICAgIGxldCBuZXdTbGlkZU9yZGVySW5kZXg7XHJcbiAgICBsZXQgY29sdW1uO1xyXG4gICAgbGV0IHJvdztcclxuICAgIGlmIChmaWxsID09PSAncm93JyAmJiBzbGlkZXNQZXJHcm91cCA+IDEpIHtcclxuICAgICAgY29uc3QgZ3JvdXBJbmRleCA9IE1hdGguZmxvb3IoaSAvIChzbGlkZXNQZXJHcm91cCAqIHJvd3MpKTtcclxuICAgICAgY29uc3Qgc2xpZGVJbmRleEluR3JvdXAgPSBpIC0gcm93cyAqIHNsaWRlc1Blckdyb3VwICogZ3JvdXBJbmRleDtcclxuICAgICAgY29uc3QgY29sdW1uc0luR3JvdXAgPVxyXG4gICAgICAgIGdyb3VwSW5kZXggPT09IDBcclxuICAgICAgICAgID8gc2xpZGVzUGVyR3JvdXBcclxuICAgICAgICAgIDogTWF0aC5taW4oTWF0aC5jZWlsKChzbGlkZXNMZW5ndGggLSBncm91cEluZGV4ICogcm93cyAqIHNsaWRlc1Blckdyb3VwKSAvIHJvd3MpLCBzbGlkZXNQZXJHcm91cCk7XHJcbiAgICAgIHJvdyA9IE1hdGguZmxvb3Ioc2xpZGVJbmRleEluR3JvdXAgLyBjb2x1bW5zSW5Hcm91cCk7XHJcbiAgICAgIGNvbHVtbiA9IHNsaWRlSW5kZXhJbkdyb3VwIC0gcm93ICogY29sdW1uc0luR3JvdXAgKyBncm91cEluZGV4ICogc2xpZGVzUGVyR3JvdXA7XHJcbiAgICAgIG5ld1NsaWRlT3JkZXJJbmRleCA9IGNvbHVtbiArIChyb3cgKiBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzKSAvIHJvd3M7XHJcbiAgICAgIHNsaWRlLnN0eWxlLm9yZGVyID0gbmV3U2xpZGVPcmRlckluZGV4O1xyXG4gICAgfSBlbHNlIGlmIChmaWxsID09PSAnY29sdW1uJykge1xyXG4gICAgICBjb2x1bW4gPSBNYXRoLmZsb29yKGkgLyByb3dzKTtcclxuICAgICAgcm93ID0gaSAtIGNvbHVtbiAqIHJvd3M7XHJcbiAgICAgIGlmIChjb2x1bW4gPiBudW1GdWxsQ29sdW1ucyB8fCAoY29sdW1uID09PSBudW1GdWxsQ29sdW1ucyAmJiByb3cgPT09IHJvd3MgLSAxKSkge1xyXG4gICAgICAgIHJvdyArPSAxO1xyXG4gICAgICAgIGlmIChyb3cgPj0gcm93cykge1xyXG4gICAgICAgICAgcm93ID0gMDtcclxuICAgICAgICAgIGNvbHVtbiArPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcm93ID0gTWF0aC5mbG9vcihpIC8gc2xpZGVzUGVyUm93KTtcclxuICAgICAgY29sdW1uID0gaSAtIHJvdyAqIHNsaWRlc1BlclJvdztcclxuICAgIH1cclxuICAgIHNsaWRlLnJvdyA9IHJvdztcclxuICAgIHNsaWRlLmNvbHVtbiA9IGNvbHVtbjtcclxuICAgIHNsaWRlLnN0eWxlW2dldERpcmVjdGlvbkxhYmVsKCdtYXJnaW4tdG9wJyldID0gcm93ICE9PSAwID8gc3BhY2VCZXR3ZWVuICYmIGAke3NwYWNlQmV0d2Vlbn1weGAgOiAnJztcclxuICB9O1xyXG4gIGNvbnN0IHVwZGF0ZVdyYXBwZXJTaXplID0gKHNsaWRlU2l6ZSwgc25hcEdyaWQsIGdldERpcmVjdGlvbkxhYmVsKSA9PiB7XHJcbiAgICBjb25zdCB7IGNlbnRlcmVkU2xpZGVzLCByb3VuZExlbmd0aHMgfSA9IHN3aXBlci5wYXJhbXM7XHJcbiAgICBjb25zdCBzcGFjZUJldHdlZW4gPSBnZXRTcGFjZUJldHdlZW4oKTtcclxuICAgIGNvbnN0IHsgcm93cyB9ID0gc3dpcGVyLnBhcmFtcy5ncmlkO1xyXG4gICAgc3dpcGVyLnZpcnR1YWxTaXplID0gKHNsaWRlU2l6ZSArIHNwYWNlQmV0d2VlbikgKiBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzO1xyXG4gICAgc3dpcGVyLnZpcnR1YWxTaXplID0gTWF0aC5jZWlsKHN3aXBlci52aXJ0dWFsU2l6ZSAvIHJvd3MpIC0gc3BhY2VCZXR3ZWVuO1xyXG4gICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZVtnZXREaXJlY3Rpb25MYWJlbCgnd2lkdGgnKV0gPSBgJHtzd2lwZXIudmlydHVhbFNpemUgKyBzcGFjZUJldHdlZW59cHhgO1xyXG4gICAgaWYgKGNlbnRlcmVkU2xpZGVzKSB7XHJcbiAgICAgIGNvbnN0IG5ld1NsaWRlc0dyaWQgPSBbXTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbmFwR3JpZC5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICAgIGxldCBzbGlkZXNHcmlkSXRlbSA9IHNuYXBHcmlkW2ldO1xyXG4gICAgICAgIGlmIChyb3VuZExlbmd0aHMpIHNsaWRlc0dyaWRJdGVtID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkSXRlbSk7XHJcbiAgICAgICAgaWYgKHNuYXBHcmlkW2ldIDwgc3dpcGVyLnZpcnR1YWxTaXplICsgc25hcEdyaWRbMF0pIG5ld1NsaWRlc0dyaWQucHVzaChzbGlkZXNHcmlkSXRlbSk7XHJcbiAgICAgIH1cclxuICAgICAgc25hcEdyaWQuc3BsaWNlKDAsIHNuYXBHcmlkLmxlbmd0aCk7XHJcbiAgICAgIHNuYXBHcmlkLnB1c2goLi4ubmV3U2xpZGVzR3JpZCk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBzd2lwZXIuZ3JpZCA9IHtcclxuICAgIGluaXRTbGlkZXMsXHJcbiAgICB1cGRhdGVTbGlkZSxcclxuICAgIHVwZGF0ZVdyYXBwZXJTaXplLFxyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFwcGVuZFNsaWRlKHNsaWRlcykge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIHNsaWRlc0VsIH0gPSBzd2lwZXI7XHJcbiAgaWYgKHBhcmFtcy5sb29wKSB7XHJcbiAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcclxuICB9XHJcbiAgY29uc3QgYXBwZW5kRWxlbWVudCA9IChzbGlkZUVsKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIHNsaWRlRWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGNvbnN0IHRlbXBET00gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgdGVtcERPTS5pbm5lckhUTUwgPSBzbGlkZUVsO1xyXG4gICAgICBzbGlkZXNFbC5hcHBlbmQodGVtcERPTS5jaGlsZHJlblswXSk7XHJcbiAgICAgIHRlbXBET00uaW5uZXJIVE1MID0gJyc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzbGlkZXNFbC5hcHBlbmQoc2xpZGVFbCk7XHJcbiAgICB9XHJcbiAgfTtcclxuICBpZiAodHlwZW9mIHNsaWRlcyA9PT0gJ29iamVjdCcgJiYgJ2xlbmd0aCcgaW4gc2xpZGVzKSB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICBpZiAoc2xpZGVzW2ldKSBhcHBlbmRFbGVtZW50KHNsaWRlc1tpXSk7XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGFwcGVuZEVsZW1lbnQoc2xpZGVzKTtcclxuICB9XHJcbiAgc3dpcGVyLnJlY2FsY1NsaWRlcygpO1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcclxuICB9XHJcbiAgaWYgKCFwYXJhbXMub2JzZXJ2ZXIgfHwgc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcHJlcGVuZFNsaWRlKHNsaWRlcykge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3QgeyBwYXJhbXMsIGFjdGl2ZUluZGV4LCBzbGlkZXNFbCB9ID0gc3dpcGVyO1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XHJcbiAgfVxyXG4gIGxldCBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgMTtcclxuICBjb25zdCBwcmVwZW5kRWxlbWVudCA9IChzbGlkZUVsKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIHNsaWRlRWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGNvbnN0IHRlbXBET00gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgdGVtcERPTS5pbm5lckhUTUwgPSBzbGlkZUVsO1xyXG4gICAgICBzbGlkZXNFbC5wcmVwZW5kKHRlbXBET00uY2hpbGRyZW5bMF0pO1xyXG4gICAgICB0ZW1wRE9NLmlubmVySFRNTCA9ICcnO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2xpZGVzRWwucHJlcGVuZChzbGlkZUVsKTtcclxuICAgIH1cclxuICB9O1xyXG4gIGlmICh0eXBlb2Ygc2xpZGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXMpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGlmIChzbGlkZXNbaV0pIHByZXBlbmRFbGVtZW50KHNsaWRlc1tpXSk7XHJcbiAgICB9XHJcbiAgICBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgc2xpZGVzLmxlbmd0aDtcclxuICB9IGVsc2Uge1xyXG4gICAgcHJlcGVuZEVsZW1lbnQoc2xpZGVzKTtcclxuICB9XHJcbiAgc3dpcGVyLnJlY2FsY1NsaWRlcygpO1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcclxuICB9XHJcbiAgaWYgKCFwYXJhbXMub2JzZXJ2ZXIgfHwgc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xyXG4gIH1cclxuICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCwgMCwgZmFsc2UpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTbGlkZShpbmRleCwgc2xpZGVzKSB7XHJcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcclxuICBjb25zdCB7IHBhcmFtcywgYWN0aXZlSW5kZXgsIHNsaWRlc0VsIH0gPSBzd2lwZXI7XHJcbiAgbGV0IGFjdGl2ZUluZGV4QnVmZmVyID0gYWN0aXZlSW5kZXg7XHJcbiAgaWYgKHBhcmFtcy5sb29wKSB7XHJcbiAgICBhY3RpdmVJbmRleEJ1ZmZlciAtPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xyXG4gICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XHJcbiAgICBzd2lwZXIucmVjYWxjU2xpZGVzKCk7XHJcbiAgfVxyXG4gIGNvbnN0IGJhc2VMZW5ndGggPSBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcclxuICBpZiAoaW5kZXggPD0gMCkge1xyXG4gICAgc3dpcGVyLnByZXBlbmRTbGlkZShzbGlkZXMpO1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuICBpZiAoaW5kZXggPj0gYmFzZUxlbmd0aCkge1xyXG4gICAgc3dpcGVyLmFwcGVuZFNsaWRlKHNsaWRlcyk7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGxldCBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4QnVmZmVyID4gaW5kZXggPyBhY3RpdmVJbmRleEJ1ZmZlciArIDEgOiBhY3RpdmVJbmRleEJ1ZmZlcjtcclxuICBjb25zdCBzbGlkZXNCdWZmZXIgPSBbXTtcclxuICBmb3IgKGxldCBpID0gYmFzZUxlbmd0aCAtIDE7IGkgPj0gaW5kZXg7IGkgLT0gMSkge1xyXG4gICAgY29uc3QgY3VycmVudFNsaWRlID0gc3dpcGVyLnNsaWRlc1tpXTtcclxuICAgIGN1cnJlbnRTbGlkZS5yZW1vdmUoKTtcclxuICAgIHNsaWRlc0J1ZmZlci51bnNoaWZ0KGN1cnJlbnRTbGlkZSk7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2Ygc2xpZGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXMpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGlmIChzbGlkZXNbaV0pIHNsaWRlc0VsLmFwcGVuZChzbGlkZXNbaV0pO1xyXG4gICAgfVxyXG4gICAgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleEJ1ZmZlciA+IGluZGV4ID8gYWN0aXZlSW5kZXhCdWZmZXIgKyBzbGlkZXMubGVuZ3RoIDogYWN0aXZlSW5kZXhCdWZmZXI7XHJcbiAgfSBlbHNlIHtcclxuICAgIHNsaWRlc0VsLmFwcGVuZChzbGlkZXMpO1xyXG4gIH1cclxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlc0J1ZmZlci5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgc2xpZGVzRWwuYXBwZW5kKHNsaWRlc0J1ZmZlcltpXSk7XHJcbiAgfVxyXG4gIHN3aXBlci5yZWNhbGNTbGlkZXMoKTtcclxuICBpZiAocGFyYW1zLmxvb3ApIHtcclxuICAgIHN3aXBlci5sb29wQ3JlYXRlKCk7XHJcbiAgfVxyXG4gIGlmICghcGFyYW1zLm9ic2VydmVyIHx8IHN3aXBlci5pc0VsZW1lbnQpIHtcclxuICAgIHN3aXBlci51cGRhdGUoKTtcclxuICB9XHJcbiAgaWYgKHBhcmFtcy5sb29wKSB7XHJcbiAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCArIHN3aXBlci5sb29wZWRTbGlkZXMsIDAsIGZhbHNlKTtcclxuICB9IGVsc2Uge1xyXG4gICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXgsIDAsIGZhbHNlKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZVNsaWRlKHNsaWRlc0luZGV4ZXMpIHtcclxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xyXG4gIGNvbnN0IHsgcGFyYW1zLCBhY3RpdmVJbmRleCB9ID0gc3dpcGVyO1xyXG4gIGxldCBhY3RpdmVJbmRleEJ1ZmZlciA9IGFjdGl2ZUluZGV4O1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgYWN0aXZlSW5kZXhCdWZmZXIgLT0gc3dpcGVyLmxvb3BlZFNsaWRlcztcclxuICAgIHN3aXBlci5sb29wRGVzdHJveSgpO1xyXG4gIH1cclxuICBsZXQgbm
9266V3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleEJ1ZmZlcjtcclxuICBsZXQgaW5kZXhUb1JlbW92ZTtcclxuICBpZiAodHlwZW9mIHNsaWRlc0luZGV4ZXMgPT09ICdvYmplY3QnICYmICdsZW5ndGgnIGluIHNsaWRlc0luZGV4ZXMpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzSW5kZXhlcy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICBpbmRleFRvUmVtb3ZlID0gc2xpZGVzSW5kZXhlc1tpXTtcclxuICAgICAgaWYgKHN3aXBlci5zbGlkZXNbaW5kZXhUb1JlbW92ZV0pIHN3aXBlci5zbGlkZXNbaW5kZXhUb1JlbW92ZV0ucmVtb3ZlKCk7XHJcbiAgICAgIGlmIChpbmRleFRvUmVtb3ZlIDwgbmV3QWN0aXZlSW5kZXgpIG5ld0FjdGl2ZUluZGV4IC09IDE7XHJcbiAgICB9XHJcbiAgICBuZXdBY3RpdmVJbmRleCA9IE1hdGgubWF4KG5ld0FjdGl2ZUluZGV4LCAwKTtcclxuICB9IGVsc2Uge1xyXG4gICAgaW5kZXhUb1JlbW92ZSA9IHNsaWRlc0luZGV4ZXM7XHJcbiAgICBpZiAoc3dpcGVyLnNsaWRlc1tpbmRleFRvUmVtb3ZlXSkgc3dpcGVyLnNsaWRlc1tpbmRleFRvUmVtb3ZlXS5yZW1vdmUoKTtcclxuICAgIGlmIChpbmRleFRvUmVtb3ZlIDwgbmV3QWN0aXZlSW5kZXgpIG5ld0FjdGl2ZUluZGV4IC09IDE7XHJcbiAgICBuZXdBY3RpdmVJbmRleCA9IE1hdGgubWF4KG5ld0FjdGl2ZUluZGV4LCAwKTtcclxuICB9XHJcbiAgc3dpcGVyLnJlY2FsY1NsaWRlcygpO1xyXG4gIGlmIChwYXJhbXMubG9vcCkge1xyXG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcclxuICB9XHJcbiAgaWYgKCFwYXJhbXMub2JzZXJ2ZXIgfHwgc3dpcGVyLmlzRWxlbWVudCkge1xyXG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xyXG4gIH1cclxuICBpZiAocGFyYW1zLmxvb3ApIHtcclxuICAgIHN3aXBlci5zbGlkZVRvKG5ld0FjdGl2ZUluZGV4ICsgc3dpcGVyLmxvb3BlZFNsaWRlcywgMCwgZmFsc2UpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCwgMCwgZmFsc2UpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlQWxsU2xpZGVzKCkge1xyXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XHJcbiAgY29uc3Qgc2xpZGVzSW5kZXhlcyA9IFtdO1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3dpcGVyLnNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgc2xpZGVzSW5kZXhlcy5wdXNoKGkpO1xyXG4gIH1cclxuICBzd2lwZXIucmVtb3ZlU2xpZGUoc2xpZGVzSW5kZXhlcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIE1hbmlwdWxhdGlvbihfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyIH0gPSBfcmVmO1xyXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XHJcbiAgICBhcHBlbmRTbGlkZTogYXBwZW5kU2xpZGUuYmluZChzd2lwZXIpLFxyXG4gICAgcHJlcGVuZFNsaWRlOiBwcmVwZW5kU2xpZGUuYmluZChzd2lwZXIpLFxyXG4gICAgYWRkU2xpZGU6IGFkZFNsaWRlLmJpbmQoc3dpcGVyKSxcclxuICAgIHJlbW92ZVNsaWRlOiByZW1vdmVTbGlkZS5iaW5kKHN3aXBlciksXHJcbiAgICByZW1vdmVBbGxTbGlkZXM6IHJlbW92ZUFsbFNsaWRlcy5iaW5kKHN3aXBlciksXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVmZmVjdEluaXQocGFyYW1zKSB7XHJcbiAgY29uc3Qge1xyXG4gICAgZWZmZWN0LFxyXG4gICAgc3dpcGVyLFxyXG4gICAgb24sXHJcbiAgICBzZXRUcmFuc2xhdGUsXHJcbiAgICBzZXRUcmFuc2l0aW9uLFxyXG4gICAgb3ZlcndyaXRlUGFyYW1zLFxyXG4gICAgcGVyc3BlY3RpdmUsXHJcbiAgICByZWNyZWF0ZVNoYWRvd3MsXHJcbiAgICBnZXRFZmZlY3RQYXJhbXMsXHJcbiAgfSA9IHBhcmFtcztcclxuICBvbignYmVmb3JlSW5pdCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XHJcbiAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKGAke3N3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc30ke2VmZmVjdH1gKTtcclxuICAgIGlmIChwZXJzcGVjdGl2ZSAmJiBwZXJzcGVjdGl2ZSgpKSB7XHJcbiAgICAgIHN3aXBlci5jbGFzc05hbWVzLnB1c2goYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfTNkYCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBvdmVyd3JpdGVQYXJhbXNSZXN1bHQgPSBvdmVyd3JpdGVQYXJhbXMgPyBvdmVyd3JpdGVQYXJhbXMoKSA6IHt9O1xyXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIucGFyYW1zLCBvdmVyd3JpdGVQYXJhbXNSZXN1bHQpO1xyXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIub3JpZ2luYWxQYXJhbXMsIG92ZXJ3cml0ZVBhcmFtc1Jlc3VsdCk7XHJcbiAgfSk7XHJcbiAgb24oJ3NldFRyYW5zbGF0ZScsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XHJcbiAgICBzZXRUcmFuc2xhdGUoKTtcclxuICB9KTtcclxuICBvbignc2V0VHJhbnNpdGlvbicsIChfcywgZHVyYXRpb24pID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XHJcbiAgICBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcclxuICB9KTtcclxuICBvbigndHJhbnNpdGlvbkVuZCcsICgpID0+IHtcclxuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XHJcbiAgICBpZiAocmVjcmVhdGVTaGFkb3dzKSB7XHJcbiAgICAgIGlmICghZ2V0RWZmZWN0UGFyYW1zIHx8ICFnZXRFZmZlY3RQYXJhbXMoKS5zbGlkZVNoYWRvd3MpIHJldHVybjtcclxuICAgICAgLy8gcmVtb3ZlIHNoYWRvd3NcclxuICAgICAgc3dpcGVyLnNsaWRlcy5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgICAgc2xpZGVFbFxyXG4gICAgICAgICAgLnF1ZXJ5U2VsZWN0b3JBbGwoXHJcbiAgICAgICAgICAgICcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AsIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICAuZm9yRWFjaCgoc2hhZG93RWwpID0+IHNoYWRvd0VsLnJlbW92ZSgpKTtcclxuICAgICAgfSk7XHJcbiAgICAgIC8vIGNyZWF0ZSBuZXcgb25lXHJcbiAgICAgIHJlY3JlYXRlU2hhZG93cygpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIGxldCByZXF1aXJlVXBkYXRlT25WaXJ0dWFsO1xyXG4gIG9uKCd2aXJ0dWFsVXBkYXRlJywgKCkgPT4ge1xyXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSBlZmZlY3QpIHJldHVybjtcclxuICAgIGlmICghc3dpcGVyLnNsaWRlcy5sZW5ndGgpIHtcclxuICAgICAgcmVxdWlyZVVwZGF0ZU9uVmlydHVhbCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICBpZiAocmVxdWlyZVVwZGF0ZU9uVmlydHVhbCAmJiBzd2lwZXIuc2xpZGVzICYmIHN3aXBlci5zbGlkZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgc2V0VHJhbnNsYXRlKCk7XHJcbiAgICAgICAgcmVxdWlyZVVwZGF0ZU9uVmlydHVhbCA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZWZmZWN0VGFyZ2V0KGVmZmVjdFBhcmFtcywgc2xpZGVFbCkge1xyXG4gIGNvbnN0IHRyYW5zZm9ybUVsID0gZ2V0U2xpZGVUcmFuc2Zvcm1FbChzbGlkZUVsKTtcclxuICBpZiAodHJhbnNmb3JtRWwgIT09IHNsaWRlRWwpIHtcclxuICAgIHRyYW5zZm9ybUVsLnN0eWxlLmJhY2tmYWNlVmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xyXG4gICAgdHJhbnNmb3JtRWwuc3R5bGVbJy13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eS
9266ddID0gJ2hpZGRlbic7XHJcbiAgfVxyXG4gIHJldHVybiB0cmFuc2Zvcm1FbDtcclxufVxyXG5cclxuZnVuY3Rpb24gZWZmZWN0VmlydHVhbFRyYW5zaXRpb25FbmQoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZHVyYXRpb24sIHRyYW5zZm9ybUVsZW1lbnRzLCBhbGxTbGlkZXMgfSA9IF9yZWY7XHJcbiAgY29uc3QgeyBhY3RpdmVJbmRleCB9ID0gc3dpcGVyO1xyXG4gIGNvbnN0IGdldFNsaWRlID0gKGVsKSA9PiB7XHJcbiAgICBpZiAoIWVsLnBhcmVudEVsZW1lbnQpIHtcclxuICAgICAgLy8gYXNzdW1lIHNoYWRvdyByb290XHJcbiAgICAgIGNvbnN0IHNsaWRlID0gc3dpcGVyLnNsaWRlcy5maWx0ZXIoKHNsaWRlRWwpID0+IHNsaWRlRWwuc2hhZG93RWwgJiYgc2xpZGVFbC5zaGFkb3dFbCA9PT0gZWwucGFyZW50Tm9kZSlbMF07XHJcbiAgICAgIHJldHVybiBzbGlkZTtcclxuICAgIH1cclxuICAgIHJldHVybiBlbC5wYXJlbnRFbGVtZW50O1xyXG4gIH07XHJcbiAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbFRyYW5zbGF0ZSAmJiBkdXJhdGlvbiAhPT0gMCkge1xyXG4gICAgbGV0IGV2ZW50VHJpZ2dlcmVkID0gZmFsc2U7XHJcbiAgICBsZXQgdHJhbnNpdGlvbkVuZFRhcmdldDtcclxuICAgIGlmIChhbGxTbGlkZXMpIHtcclxuICAgICAgdHJhbnNpdGlvbkVuZFRhcmdldCA9IHRyYW5zZm9ybUVsZW1lbnRzO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdHJhbnNpdGlvbkVuZFRhcmdldCA9IHRyYW5zZm9ybUVsZW1lbnRzLmZpbHRlcigodHJhbnNmb3JtRWwpID0+IHtcclxuICAgICAgICBjb25zdCBlbCA9IHRyYW5zZm9ybUVsLmNsYXNzTGlzdC5jb250YWlucygnc3dpcGVyLXNsaWRlLXRyYW5zZm9ybScpID8gZ2V0U2xpZGUodHJhbnNmb3JtRWwpIDogdHJhbnNmb3JtRWw7XHJcbiAgICAgICAgcmV0dXJuIHN3aXBlci5nZXRTbGlkZUluZGV4KGVsKSA9PT0gYWN0aXZlSW5kZXg7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdHJhbnNpdGlvbkVuZFRhcmdldC5mb3JFYWNoKChlbCkgPT4ge1xyXG4gICAgICBlbGVtZW50VHJhbnNpdGlvbkVuZChlbCwgKCkgPT4ge1xyXG4gICAgICAgIGlmIChldmVudFRyaWdnZXJlZCkgcmV0dXJuO1xyXG4gICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcclxuICAgICAgICBldmVudFRyaWdnZXJlZCA9IHRydWU7XHJcbiAgICAgICAgc3dpcGVyLmFuaW1hdGluZyA9IGZhbHNlO1xyXG4gICAgICAgIGNvbnN0IGV2dCA9IG5ldyB3aW5kb3cuQ3VzdG9tRXZlbnQoJ3RyYW5zaXRpb25lbmQnLCB7XHJcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxyXG4gICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcclxuICAgICAgICB9KTtcclxuICAgICAgICBzd2lwZXIud3JhcHBlckVsLmRpc3BhdGNoRXZlbnQoZXZ0KTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIEVmZmVjdEZhZGUoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgZmFkZUVmZmVjdDoge1xyXG4gICAgICBjcm9zc0ZhZGU6IGZhbHNlLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBjb25zdCBzZXRUcmFuc2xhdGUgPSAoKSA9PiB7XHJcbiAgICBjb25zdCB7IHNsaWRlcyB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5mYWRlRWZmZWN0O1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgY29uc3Qgc2xpZGVFbCA9IHN3aXBlci5zbGlkZXNbaV07XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IHNsaWRlRWwuc3dpcGVyU2xpZGVPZmZzZXQ7XHJcbiAgICAgIGxldCB0eCA9IC1vZmZzZXQ7XHJcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsVHJhbnNsYXRlKSB0eCAtPSBzd2lwZXIudHJhbnNsYXRlO1xyXG4gICAgICBsZXQgdHkgPSAwO1xyXG4gICAgICBpZiAoIXN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgICAgIHR5ID0gdHg7XHJcbiAgICAgICAgdHggPSAwO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHNsaWRlT3BhY2l0eSA9IHN3aXBlci5wYXJhbXMuZmFkZUVmZmVjdC5jcm9zc0ZhZGVcclxuICAgICAgICA/IE1hdGgubWF4KDEgLSBNYXRoLmFicyhzbGlkZUVsLnByb2dyZXNzKSwgMClcclxuICAgICAgICA6IDEgKyBNYXRoLm1pbihNYXRoLm1heChzbGlkZUVsLnByb2dyZXNzLCAtMSksIDApO1xyXG4gICAgICBjb25zdCB0YXJnZXRFbCA9IGVmZmVjdFRhcmdldChwYXJhbXMsIHNsaWRlRWwpO1xyXG4gICAgICB0YXJnZXRFbC5zdHlsZS5vcGFjaXR5ID0gc2xpZGVPcGFjaXR5O1xyXG4gICAgICB0YXJnZXRFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt0eH1weCwgJHt0eX1weCwgMHB4KWA7XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm1FbGVtZW50cyA9IHN3aXBlci5zbGlkZXMubWFwKChzbGlkZUVsKSA9PiBnZXRTbGlkZVRyYW5zZm9ybUVsKHNsaWRlRWwpKTtcclxuICAgIHRyYW5zZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgIH0pO1xyXG4gICAgZWZmZWN0VmlydHVhbFRyYW5zaXRpb25FbmQoe1xyXG4gICAgICBzd2lwZXIsXHJcbiAgICAgIGR1cmF0aW9uLFxyXG4gICAgICB0cmFuc2Zvcm1FbGVtZW50cyxcclxuICAgICAgYWxsU2xpZGVzOiB0cnVlLFxyXG4gICAgfSk7XHJcbiAgfTtcclxuICBlZmZlY3RJbml0KHtcclxuICAgIGVmZmVjdDogJ2ZhZGUnLFxyXG4gICAgc3dpcGVyLFxyXG4gICAgb24sXHJcbiAgICBzZXRUcmFuc2xhdGUsXHJcbiAgICBzZXRUcmFuc2l0aW9uLFxyXG4gICAgb3ZlcndyaXRlUGFyYW1zOiAoKSA9PiAoe1xyXG4gICAgICBzbGlkZXNQZXJWaWV3OiAxLFxyXG4gICAgICBzbGlkZXNQZXJHcm91cDogMSxcclxuICAgICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogdHJ1ZSxcclxuICAgICAgc3B
9266hY2VCZXR3ZWVuOiAwLFxyXG4gICAgICB2aXJ0dWFsVHJhbnNsYXRlOiAhc3dpcGVyLnBhcmFtcy5jc3NNb2RlLFxyXG4gICAgfSksXHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIEVmZmVjdEN1YmUoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgY3ViZUVmZmVjdDoge1xyXG4gICAgICBzbGlkZVNoYWRvd3M6IHRydWUsXHJcbiAgICAgIHNoYWRvdzogdHJ1ZSxcclxuICAgICAgc2hhZG93T2Zmc2V0OiAyMCxcclxuICAgICAgc2hhZG93U2NhbGU6IDAuOTQsXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGNvbnN0IGNyZWF0ZVNsaWRlU2hhZG93cyA9IChzbGlkZUVsLCBwcm9ncmVzcywgaXNIb3Jpem9udGFsKSA9PiB7XHJcbiAgICBsZXQgc2hhZG93QmVmb3JlID0gaXNIb3Jpem9udGFsXHJcbiAgICAgID8gc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0JylcclxuICAgICAgOiBzbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoJy5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCcpO1xyXG4gICAgbGV0IHNoYWRvd0FmdGVyID0gaXNIb3Jpem9udGFsXHJcbiAgICAgID8gc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCcpXHJcbiAgICAgIDogc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcclxuICAgIGlmICghc2hhZG93QmVmb3JlKSB7XHJcbiAgICAgIHNoYWRvd0JlZm9yZSA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsIGBzd2lwZXItc2xpZGUtc2hhZG93LSR7aXNIb3Jpem9udGFsID8gJ2xlZnQnIDogJ3RvcCd9YCk7XHJcbiAgICAgIHNsaWRlRWwuYXBwZW5kKHNoYWRvd0JlZm9yZSk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXNoYWRvd0FmdGVyKSB7XHJcbiAgICAgIHNoYWRvd0FmdGVyID0gY3JlYXRlRWxlbWVudCgnZGl2JywgYHN3aXBlci1zbGlkZS1zaGFkb3ctJHtpc0hvcml6b250YWwgPyAncmlnaHQnIDogJ2JvdHRvbSd9YCk7XHJcbiAgICAgIHNsaWRlRWwuYXBwZW5kKHNoYWRvd0FmdGVyKTtcclxuICAgIH1cclxuICAgIGlmIChzaGFkb3dCZWZvcmUpIHNoYWRvd0JlZm9yZS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgoLXByb2dyZXNzLCAwKTtcclxuICAgIGlmIChzaGFkb3dBZnRlcikgc2hhZG93QWZ0ZXIuc3R5bGUub3BhY2l0eSA9IE1hdGgubWF4KHByb2dyZXNzLCAwKTtcclxuICB9O1xyXG4gIGNvbnN0IHJlY3JlYXRlU2hhZG93cyA9ICgpID0+IHtcclxuICAgIC8vIGNyZWF0ZSBuZXcgb25lc1xyXG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xyXG4gICAgc3dpcGVyLnNsaWRlcy5mb3JFYWNoKChzbGlkZUVsKSA9PiB7XHJcbiAgICAgIGNvbnN0IHByb2dyZXNzID0gTWF0aC5tYXgoTWF0aC5taW4oc2xpZGVFbC5wcm9ncmVzcywgMSksIC0xKTtcclxuICAgICAgY3JlYXRlU2xpZGVTaGFkb3dzKHNsaWRlRWwsIHByb2dyZXNzLCBpc0hvcml6b250YWwpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2xhdGUgPSAoKSA9PiB7XHJcbiAgICBjb25zdCB7XHJcbiAgICAgIGVsLFxyXG4gICAgICB3cmFwcGVyRWwsXHJcbiAgICAgIHNsaWRlcyxcclxuICAgICAgd2lkdGg6IHN3aXBlcldpZHRoLFxyXG4gICAgICBoZWlnaHQ6IHN3aXBlckhlaWdodCxcclxuICAgICAgcnRsVHJhbnNsYXRlOiBydGwsXHJcbiAgICAgIHNpemU6IHN3aXBlclNpemUsXHJcbiAgICAgIGJyb3dzZXIsXHJcbiAgICB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0O1xyXG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xyXG4gICAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQ7XHJcbiAgICBsZXQgd3JhcHBlclJvdGF0ZSA9IDA7XHJcbiAgICBsZXQgY3ViZVNoYWRvd0VsO1xyXG4gICAgaWYgKHBhcmFtcy5zaGFkb3cpIHtcclxuICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgIGN1YmVTaGFkb3dFbCA9IHN3aXBlci5zbGlkZXNFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLWN1YmUtc2hhZG93Jyk7XHJcbiAgICAgICAgaWYgKCFjdWJlU2hhZG93RWwpIHtcclxuICAgICAgICAgIGN1YmVTaGFkb3dFbCA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsICdzd2lwZXItY3ViZS1zaGFkb3cnKTtcclxuICAgICAgICAgIHN3aXBlci5zbGlkZXNFbC5hcHBlbmQoY3ViZVNoYWRvd0VsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY3ViZVNoYWRvd0VsLnN0eWxlLmhlaWdodCA9IGAke3N3aXBlcldpZHRofXB4YDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjdWJlU2hhZG93RWwgPSBlbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLWN1YmUtc2hhZG93Jyk7XHJcbiAgICAgICAgaWYgKCFjdWJlU2hhZG93RWwpIHtcclxuICAgICAgICAgIGN1YmVTaGFkb3dFbCA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicsICdzd2lwZXItY3ViZS1zaGFkb3cnKTtcclxuICAgICAgICAgIGVsLmFwcGVuZChjdWJlU2hhZG93RWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgY29uc3Qgc2xpZGVFbCA9IHNsaWRlc1tpXTtcclxuICAgICAgbGV0IHNsaWRlSW5kZXggPSBpO1xyXG4gICAgICBpZiAoaXNWaXJ0dWFsKSB7XHJcbiAgICAgICAgc2xpZGVJbmRleCA9IHBhcnNlSW50KHNsaWRlRWwuZ2V0QXR0cmlidXRlKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IHNsaWRlQW5nbGUgPSBzbGlkZUluZGV4ICogOTA7XHJcbiAgICAgIGxldCByb3VuZCA9IE1hdGguZmxvb3Ioc2xpZGVBbmdsZSAvIDM2MCk7XHJcbiAgICAgIGlmIChydGwpIHtcclxuICAgICAgICBzbGlkZUFuZ2xlID0gLXNsaWRlQW5nbGU7XHJcbiAgICAgICAgcm91bmQgPSBNYXRoLmZsb29yKC1zbGlkZUFuZ2xlIC8gMzYwKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWF4KE1hdGgubWluKHNsaWRlRWwucHJvZ3Jlc3MsIDEpLCAtMSk7XHJcbiAgICAgIGxldCB0eCA9IDA7XHJcbiAgICAgIGxldCB0eSA9IDA7XHJcbiAgICAgIGxldCB0eiA9IDA7XHJcbiAgICAgIGlmIChzbGlkZUluZGV4ICUgNCA9PT0gMCkge1xyXG4gICAgICAgI
9266HR4ID0gLXJvdW5kICogNCAqIHN3aXBlclNpemU7XHJcbiAgICAgICAgdHogPSAwO1xyXG4gICAgICB9IGVsc2UgaWYgKChzbGlkZUluZGV4IC0gMSkgJSA0ID09PSAwKSB7XHJcbiAgICAgICAgdHggPSAwO1xyXG4gICAgICAgIHR6ID0gLXJvdW5kICogNCAqIHN3aXBlclNpemU7XHJcbiAgICAgIH0gZWxzZSBpZiAoKHNsaWRlSW5kZXggLSAyKSAlIDQgPT09IDApIHtcclxuICAgICAgICB0eCA9IHN3aXBlclNpemUgKyByb3VuZCAqIDQgKiBzd2lwZXJTaXplO1xyXG4gICAgICAgIHR6ID0gc3dpcGVyU2l6ZTtcclxuICAgICAgfSBlbHNlIGlmICgoc2xpZGVJbmRleCAtIDMpICUgNCA9PT0gMCkge1xyXG4gICAgICAgIHR4ID0gLXN3aXBlclNpemU7XHJcbiAgICAgICAgdHogPSAzICogc3dpcGVyU2l6ZSArIHN3aXBlclNpemUgKiA0ICogcm91bmQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHJ0bCkge1xyXG4gICAgICAgIHR4ID0gLXR4O1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgdHkgPSB0eDtcclxuICAgICAgICB0eCA9IDA7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgdHJhbnNmb3JtID0gYHJvdGF0ZVgoJHtpc0hvcml6b250YWwgPyAwIDogLXNsaWRlQW5nbGV9ZGVnKSByb3RhdGVZKCR7XHJcbiAgICAgICAgaXNIb3Jpem9udGFsID8gc2xpZGVBbmdsZSA6IDBcclxuICAgICAgfWRlZykgdHJhbnNsYXRlM2QoJHt0eH1weCwgJHt0eX1weCwgJHt0en1weClgO1xyXG4gICAgICBpZiAocHJvZ3Jlc3MgPD0gMSAmJiBwcm9ncmVzcyA+IC0xKSB7XHJcbiAgICAgICAgd3JhcHBlclJvdGF0ZSA9IHNsaWRlSW5kZXggKiA5MCArIHByb2dyZXNzICogOTA7XHJcbiAgICAgICAgaWYgKHJ0bCkgd3JhcHBlclJvdGF0ZSA9IC1zbGlkZUluZGV4ICogOTAgLSBwcm9ncmVzcyAqIDkwO1xyXG4gICAgICB9XHJcbiAgICAgIHNsaWRlRWwuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xyXG4gICAgICBpZiAocGFyYW1zLnNsaWRlU2hhZG93cykge1xyXG4gICAgICAgIGNyZWF0ZVNsaWRlU2hhZG93cyhzbGlkZUVsLCBwcm9ncmVzcywgaXNIb3Jpem9udGFsKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgd3JhcHBlckVsLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGA1MCUgNTAlIC0ke3N3aXBlclNpemUgLyAyfXB4YDtcclxuICAgIHdyYXBwZXJFbC5zdHlsZVsnLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luJ10gPSBgNTAlIDUwJSAtJHtzd2lwZXJTaXplIC8gMn1weGA7XHJcbiAgICBpZiAocGFyYW1zLnNoYWRvdykge1xyXG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgY3ViZVNoYWRvd0VsLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgwcHgsICR7c3dpcGVyV2lkdGggLyAyICsgcGFyYW1zLnNoYWRvd09mZnNldH1weCwgJHtcclxuICAgICAgICAgIC1zd2lwZXJXaWR0aCAvIDJcclxuICAgICAgICB9cHgpIHJvdGF0ZVgoOTBkZWcpIHJvdGF0ZVooMGRlZykgc2NhbGUoJHtwYXJhbXMuc2hhZG93U2NhbGV9KWA7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3Qgc2hhZG93QW5nbGUgPSBNYXRoLmFicyh3cmFwcGVyUm90YXRlKSAtIE1hdGguZmxvb3IoTWF0aC5hYnMod3JhcHBlclJvdGF0ZSkgLyA5MCkgKiA5MDtcclxuICAgICAgICBjb25zdCBtdWx0aXBsaWVyID1cclxuICAgICAgICAgIDEuNSAtIChNYXRoLnNpbigoc2hhZG93QW5nbGUgKiAyICogTWF0aC5QSSkgLyAzNjApIC8gMiArIE1hdGguY29zKChzaGFkb3dBbmdsZSAqIDIgKiBNYXRoLlBJKSAvIDM2MCkgLyAyKTtcclxuICAgICAgICBjb25zdCBzY2FsZTEgPSBwYXJhbXMuc2hhZG93U2NhbGU7XHJcbiAgICAgICAgY29uc3Qgc2NhbGUyID0gcGFyYW1zLnNoYWRvd1NjYWxlIC8gbXVsdGlwbGllcjtcclxuICAgICAgICBjb25zdCBvZmZzZXQgPSBwYXJhbXMuc2hhZG93T2Zmc2V0O1xyXG4gICAgICAgIGN1YmVTaGFkb3dFbC5zdHlsZS50cmFuc2Zvcm0gPSBgc2NhbGUzZCgke3NjYWxlMX0sIDEsICR7c2NhbGUyfSkgdHJhbnNsYXRlM2QoMHB4LCAke1xyXG4gICAgICAgICAgc3dpcGVySGVpZ2h0IC8gMiArIG9mZnNldFxyXG4gICAgICAgIH1weCwgJHstc3dpcGVySGVpZ2h0IC8gMiAvIHNjYWxlMn1weCkgcm90YXRlWCgtOTBkZWcpYDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgekZhY3RvciA9IChicm93c2VyLmlzU2FmYXJpIHx8IGJyb3dzZXIuaXNXZWJWaWV3KSAmJiBicm93c2VyLm5lZWRQZXJzcGVjdGl2ZUZpeCA/IC1zd2lwZXJTaXplIC8gMiA6IDA7XHJcbiAgICB3cmFwcGVyRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKDBweCwwLCR7ekZhY3Rvcn1weCkgcm90YXRlWCgke1xyXG4gICAgICBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAwIDogd3JhcHBlclJvdGF0ZVxyXG4gICAgfWRlZykgcm90YXRlWSgke3N3aXBlci5pc0hvcml6b250YWwoKSA/IC13cmFwcGVyUm90YXRlIDogMH1kZWcpYDtcclxuICAgIHdyYXBwZXJFbC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1zd2lwZXItY3ViZS10cmFuc2xhdGUteicsIGAke3pGYWN0b3J9cHhgKTtcclxuICB9O1xyXG4gIGNvbnN0IHNldFRyYW5zaXRpb24gPSAoZHVyYXRpb24pID0+IHtcclxuICAgIGNvbnN0IHsgZWwsIHNsaWRlcyB9ID0gc3dpcGVyO1xyXG4gICAgc2xpZGVzLmZvckVhY2goKHNsaWRlRWwpID0+IHtcclxuICAgICAgc2xpZGVFbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBgJHtkdXJhdGlvbn1tc2A7XHJcbiAgICAgIHNsaWRlRWxcclxuICAgICAgICAucXVlcnlTZWxlY3RvckFsbChcclxuICAgICAgICAgICcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AsIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5mb3JFYWNoKChzdWJFbCkgPT4ge1xyXG4gICAgICAgICAgc3ViRWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7ZHVyYXRpb259bXNgO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0LnNoYWRvdyAmJiAhc3dpcGVyLmlzSG9yaXpvbn
9266RhbCgpKSB7XHJcbiAgICAgIGNvbnN0IHNoYWRvd0VsID0gZWwucXVlcnlTZWxlY3RvcignLnN3aXBlci1jdWJlLXNoYWRvdycpO1xyXG4gICAgICBpZiAoc2hhZG93RWwpIHNoYWRvd0VsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgIH1cclxuICB9O1xyXG4gIGVmZmVjdEluaXQoe1xyXG4gICAgZWZmZWN0OiAnY3ViZScsXHJcbiAgICBzd2lwZXIsXHJcbiAgICBvbixcclxuICAgIHNldFRyYW5zbGF0ZSxcclxuICAgIHNldFRyYW5zaXRpb24sXHJcbiAgICByZWNyZWF0ZVNoYWRvd3MsXHJcbiAgICBnZXRFZmZlY3RQYXJhbXM6ICgpID0+IHN3aXBlci5wYXJhbXMuY3ViZUVmZmVjdCxcclxuICAgIHBlcnNwZWN0aXZlOiAoKSA9PiB0cnVlLFxyXG4gICAgb3ZlcndyaXRlUGFyYW1zOiAoKSA9PiAoe1xyXG4gICAgICBzbGlkZXNQZXJWaWV3OiAxLFxyXG4gICAgICBzbGlkZXNQZXJHcm91cDogMSxcclxuICAgICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogdHJ1ZSxcclxuICAgICAgcmVzaXN0YW5jZVJhdGlvOiAwLFxyXG4gICAgICBzcGFjZUJldHdlZW46IDAsXHJcbiAgICAgIGNlbnRlcmVkU2xpZGVzOiBmYWxzZSxcclxuICAgICAgdmlydHVhbFRyYW5zbGF0ZTogdHJ1ZSxcclxuICAgIH0pLFxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVTaGFkb3cocGFyYW1zLCBzbGlkZUVsLCBzaWRlKSB7XHJcbiAgY29uc3Qgc2hhZG93Q2xhc3MgPSBgc3dpcGVyLXNsaWRlLXNoYWRvdyR7c2lkZSA/IGAtJHtzaWRlfWAgOiAnJ31gO1xyXG4gIGNvbnN0IHNoYWRvd0NvbnRhaW5lciA9IGdldFNsaWRlVHJhbnNmb3JtRWwoc2xpZGVFbCk7XHJcbiAgbGV0IHNoYWRvd0VsID0gc2hhZG93Q29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYC4ke3NoYWRvd0NsYXNzfWApO1xyXG4gIGlmICghc2hhZG93RWwpIHtcclxuICAgIHNoYWRvd0VsID0gY3JlYXRlRWxlbWVudCgnZGl2JywgYHN3aXBlci1zbGlkZS1zaGFkb3cke3NpZGUgPyBgLSR7c2lkZX1gIDogJyd9YCk7XHJcbiAgICBzaGFkb3dDb250YWluZXIuYXBwZW5kKHNoYWRvd0VsKTtcclxuICB9XHJcbiAgcmV0dXJuIHNoYWRvd0VsO1xyXG59XHJcblxyXG5mdW5jdGlvbiBFZmZlY3RGbGlwKF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24gfSA9IF9yZWY7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGZsaXBFZmZlY3Q6IHtcclxuICAgICAgc2xpZGVTaGFkb3dzOiB0cnVlLFxyXG4gICAgICBsaW1pdFJvdGF0aW9uOiB0cnVlLFxyXG4gICAgfSxcclxuICB9KTtcclxuICBjb25zdCBjcmVhdGVTbGlkZVNoYWRvd3MgPSAoc2xpZGVFbCwgcHJvZ3Jlc3MsIHBhcmFtcykgPT4ge1xyXG4gICAgbGV0IHNoYWRvd0JlZm9yZSA9IHN3aXBlci5pc0hvcml6b250YWwoKVxyXG4gICAgICA/IHNsaWRlRWwucXVlcnlTZWxlY3RvcignLnN3aXBlci1zbGlkZS1zaGFkb3ctbGVmdCcpXHJcbiAgICAgIDogc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AnKTtcclxuICAgIGxldCBzaGFkb3dBZnRlciA9IHN3aXBlci5pc0hvcml6b250YWwoKVxyXG4gICAgICA/IHNsaWRlRWwucXVlcnlTZWxlY3RvcignLnN3aXBlci1zbGlkZS1zaGFkb3ctcmlnaHQnKVxyXG4gICAgICA6IHNsaWRlRWwucXVlcnlTZWxlY3RvcignLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tJyk7XHJcbiAgICBpZiAoIXNoYWRvd0JlZm9yZSkge1xyXG4gICAgICBzaGFkb3dCZWZvcmUgPSBjcmVhdGVTaGFkb3cocGFyYW1zLCBzbGlkZUVsLCBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnbGVmdCcgOiAndG9wJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXNoYWRvd0FmdGVyKSB7XHJcbiAgICAgIHNoYWRvd0FmdGVyID0gY3JlYXRlU2hhZG93KHBhcmFtcywgc2xpZGVFbCwgc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3JpZ2h0JyA6ICdib3R0b20nKTtcclxuICAgIH1cclxuICAgIGlmIChzaGFkb3dCZWZvcmUpIHNoYWRvd0JlZm9yZS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgoLXByb2dyZXNzLCAwKTtcclxuICAgIGlmIChzaGFkb3dBZnRlcikgc2hhZG93QWZ0ZXIuc3R5bGUub3BhY2l0eSA9IE1hdGgubWF4KHByb2dyZXNzLCAwKTtcclxuICB9O1xyXG4gIGNvbnN0IHJlY3JlYXRlU2hhZG93cyA9ICgpID0+IHtcclxuICAgIC8vIFNldCBzaGFkb3dzXHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmZsaXBFZmZlY3Q7XHJcbiAgICBzd2lwZXIuc2xpZGVzLmZvckVhY2goKHNsaWRlRWwpID0+IHtcclxuICAgICAgbGV0IHByb2dyZXNzID0gc2xpZGVFbC5wcm9ncmVzcztcclxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZmxpcEVmZmVjdC5saW1pdFJvdGF0aW9uKSB7XHJcbiAgICAgICAgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbihzbGlkZUVsLnByb2dyZXNzLCAxKSwgLTEpO1xyXG4gICAgICB9XHJcbiAgICAgIGNyZWF0ZVNsaWRlU2hhZG93cyhzbGlkZUVsLCBwcm9ncmVzcywgcGFyYW1zKTtcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xyXG4gICAgY29uc3QgeyBzbGlkZXMsIHJ0bFRyYW5zbGF0ZTogcnRsIH0gPSBzd2lwZXI7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmZsaXBFZmZlY3Q7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICBjb25zdCBzbGlkZUVsID0gc2xpZGVzW2ldO1xyXG4gICAgICBsZXQgcHJvZ3Jlc3MgPSBzbGlkZUVsLnByb2dyZXNzO1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0LmxpbWl0Um90YXRpb24pIHtcclxuICAgICAgICBwcm9ncmVzcyA9IE1hdGgubWF4KE1hdGgubWluKHNsaWRlRWwucHJvZ3Jlc3MsIDEpLCAtMSk7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3Qgb2Zmc2V0ID0gc2xpZGVFbC5zd2lwZXJTbGlkZU9mZnNldDtcclxuICAgICAgY29uc3Qgcm90YXRlID0gLTE4MCAqIHByb2dyZXNzO1xyXG4gICAgICBsZXQgcm90YXRlWSA9IHJvdGF0ZTtcclxuICAgICAgbGV0IHJvdGF0ZVggPSAwO1xyXG4gICAgICBsZXQgdHggPSBzd2lwZXIucGFyYW1zLmNzc01vZGUgPyAtb2Zmc2V0IC0gc3dpcGVyLnRyYW5zbGF0ZSA6IC1vZmZzZXQ7XHJcbiAgICAgIGxldCB0eSA9IDA7XHJcbiAgICAgIGlmICghc3dpcGVyLmlzSG9yaXpvbn
9266RhbCgpKSB7XHJcbiAgICAgICAgdHkgPSB0eDtcclxuICAgICAgICB0eCA9IDA7XHJcbiAgICAgICAgcm90YXRlWCA9IC1yb3RhdGVZO1xyXG4gICAgICAgIHJvdGF0ZVkgPSAwO1xyXG4gICAgICB9IGVsc2UgaWYgKHJ0bCkge1xyXG4gICAgICAgIHJvdGF0ZVkgPSAtcm90YXRlWTtcclxuICAgICAgfVxyXG4gICAgICBzbGlkZUVsLnN0eWxlLnpJbmRleCA9IC1NYXRoLmFicyhNYXRoLnJvdW5kKHByb2dyZXNzKSkgKyBzbGlkZXMubGVuZ3RoO1xyXG4gICAgICBpZiAocGFyYW1zLnNsaWRlU2hhZG93cykge1xyXG4gICAgICAgIGNyZWF0ZVNsaWRlU2hhZG93cyhzbGlkZUVsLCBwcm9ncmVzcywgcGFyYW1zKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCB0cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt0eH1weCwgJHt0eX1weCwgMHB4KSByb3RhdGVYKCR7cm90YXRlWH1kZWcpIHJvdGF0ZVkoJHtyb3RhdGVZfWRlZylgO1xyXG4gICAgICBjb25zdCB0YXJnZXRFbCA9IGVmZmVjdFRhcmdldChwYXJhbXMsIHNsaWRlRWwpO1xyXG4gICAgICB0YXJnZXRFbC5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm1FbGVtZW50cyA9IHN3aXBlci5zbGlkZXMubWFwKChzbGlkZUVsKSA9PiBnZXRTbGlkZVRyYW5zZm9ybUVsKHNsaWRlRWwpKTtcclxuICAgIHRyYW5zZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgZWwucXVlcnlTZWxlY3RvckFsbChcclxuICAgICAgICAnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0J1xyXG4gICAgICApLmZvckVhY2goKHNoYWRvd0VsKSA9PiB7XHJcbiAgICAgICAgc2hhZG93RWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7ZHVyYXRpb259bXNgO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgZWZmZWN0VmlydHVhbFRyYW5zaXRpb25FbmQoe1xyXG4gICAgICBzd2lwZXIsXHJcbiAgICAgIGR1cmF0aW9uLFxyXG4gICAgICB0cmFuc2Zvcm1FbGVtZW50cyxcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgZWZmZWN0SW5pdCh7XHJcbiAgICBlZmZlY3Q6ICdmbGlwJyxcclxuICAgIHN3aXBlcixcclxuICAgIG9uLFxyXG4gICAgc2V0VHJhbnNsYXRlLFxyXG4gICAgc2V0VHJhbnNpdGlvbixcclxuICAgIHJlY3JlYXRlU2hhZG93cyxcclxuICAgIGdldEVmZmVjdFBhcmFtczogKCkgPT4gc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0LFxyXG4gICAgcGVyc3BlY3RpdmU6ICgpID0+IHRydWUsXHJcbiAgICBvdmVyd3JpdGVQYXJhbXM6ICgpID0+ICh7XHJcbiAgICAgIHNsaWRlc1BlclZpZXc6IDEsXHJcbiAgICAgIHNsaWRlc1Blckdyb3VwOiAxLFxyXG4gICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxyXG4gICAgICBzcGFjZUJldHdlZW46IDAsXHJcbiAgICAgIHZpcnR1YWxUcmFuc2xhdGU6ICFzd2lwZXIucGFyYW1zLmNzc01vZGUsXHJcbiAgICB9KSxcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gRWZmZWN0Q292ZXJmbG93KF9yZWYpIHtcclxuICBsZXQgeyBzd2lwZXIsIGV4dGVuZFBhcmFtcywgb24gfSA9IF9yZWY7XHJcbiAgZXh0ZW5kUGFyYW1zKHtcclxuICAgIGNvdmVyZmxvd0VmZmVjdDoge1xyXG4gICAgICByb3RhdGU6IDUwLFxyXG4gICAgICBzdHJldGNoOiAwLFxyXG4gICAgICBkZXB0aDogMTAwLFxyXG4gICAgICBzY2FsZTogMSxcclxuICAgICAgbW9kaWZpZXI6IDEsXHJcbiAgICAgIHNsaWRlU2hhZG93czogdHJ1ZSxcclxuICAgIH0sXHJcbiAgfSk7XHJcbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xyXG4gICAgY29uc3QgeyB3aWR0aDogc3dpcGVyV2lkdGgsIGhlaWdodDogc3dpcGVySGVpZ2h0LCBzbGlkZXMsIHNsaWRlc1NpemVzR3JpZCB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jb3ZlcmZsb3dFZmZlY3Q7XHJcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCk7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBzd2lwZXIudHJhbnNsYXRlO1xyXG4gICAgY29uc3QgY2VudGVyID0gaXNIb3Jpem9udGFsID8gLXRyYW5zZm9ybSArIHN3aXBlcldpZHRoIC8gMiA6IC10cmFuc2Zvcm0gKyBzd2lwZXJIZWlnaHQgLyAyO1xyXG4gICAgY29uc3Qgcm90YXRlID0gaXNIb3Jpem9udGFsID8gcGFyYW1zLnJvdGF0ZSA6IC1wYXJhbXMucm90YXRlO1xyXG4gICAgY29uc3QgdHJhbnNsYXRlID0gcGFyYW1zLmRlcHRoO1xyXG4gICAgLy8gRWFjaCBzbGlkZSBvZmZzZXQgZnJvbSBjZW50ZXJcclxuICAgIGZvciAobGV0IGkgPSAwLCBsZW5ndGggPSBzbGlkZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgY29uc3Qgc2xpZGVFbCA9IHNsaWRlc1tpXTtcclxuICAgICAgY29uc3Qgc2xpZGVTaXplID0gc2xpZGVzU2l6ZXNHcmlkW2ldO1xyXG4gICAgICBjb25zdCBzbGlkZU9mZnNldCA9IHNsaWRlRWwuc3dpcGVyU2xpZGVPZmZzZXQ7XHJcbiAgICAgIGNvbnN0IGNlbnRlck9mZnNldCA9IChjZW50ZXIgLSBzbGlkZU9mZnNldCAtIHNsaWRlU2l6ZSAvIDIpIC8gc2xpZGVTaXplO1xyXG4gICAgICBjb25zdCBvZmZzZXRNdWx0aXBsaWVyID1cclxuICAgICAgICB0eXBlb2YgcGFyYW1zLm1vZGlmaWVyID09PSAnZnVuY3Rpb24nID8gcGFyYW1zLm1vZGlmaWVyKGNlbnRlck9mZnNldCkgOiBjZW50ZXJPZmZzZXQgKiBwYXJhbXMubW9kaWZpZXI7XHJcbiAgICAgIGxldCByb3RhdGVZID0gaXNIb3Jpem9udGFsID8gcm90YXRlICogb2Zmc2V0TXVsdGlwbGllciA6IDA7XHJcbiAgICAgIGxldCByb3RhdGVYID0gaXNIb3Jpem9udGFsID8gMCA6IHJvdGF0ZSAqIG9mZnNldE11bHRpcGxpZXI7XHJcbiAgICAgIC8vIHZhciByb3RhdGVaID0gMFxyXG4gICAgICBsZXQgdHJhbnNsYXRlWiA9IC10cmFuc2xhdGUgKiBNYXRoLmFicyhvZmZzZXRNdWx0aXBsaWVyKTtcclxuICAgICAgbGV0IHN0cmV0Y2ggPSBwYXJhbXMuc3RyZXRjaDtcclxuICAgICAgLy8gQWxsb3cgcGVyY2VudGFnZSB0byBtYWtlIGEgcmVsYXRpdmUgc3RyZXRjaCBmb3IgcmVzcG9uc2l2ZSBzbGlkZXJzXHJcbiAgICAgIGlmICh0eXBlb2Ygc3RyZXRjaCA9PT0gJ3N0cmluZycgJiYgc3RyZXRjaC5pbmRleE9mKCclJykgIT09IC0xKSB7XHJcbiAgICAgICAgc3RyZXRjaCA9IChwYXJzZU
9266Zsb2F0KHBhcmFtcy5zdHJldGNoKSAvIDEwMCkgKiBzbGlkZVNpemU7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IHRyYW5zbGF0ZVkgPSBpc0hvcml6b250YWwgPyAwIDogc3RyZXRjaCAqIG9mZnNldE11bHRpcGxpZXI7XHJcbiAgICAgIGxldCB0cmFuc2xhdGVYID0gaXNIb3Jpem9udGFsID8gc3RyZXRjaCAqIG9mZnNldE11bHRpcGxpZXIgOiAwO1xyXG4gICAgICBsZXQgc2NhbGUgPSAxIC0gKDEgLSBwYXJhbXMuc2NhbGUpICogTWF0aC5hYnMob2Zmc2V0TXVsdGlwbGllcik7XHJcblxyXG4gICAgICAvLyBGaXggZm9yIHVsdHJhIHNtYWxsIHZhbHVlc1xyXG4gICAgICBpZiAoTWF0aC5hYnModHJhbnNsYXRlWCkgPCAwLjAwMSkgdHJhbnNsYXRlWCA9IDA7XHJcbiAgICAgIGlmIChNYXRoLmFicyh0cmFuc2xhdGVZKSA8IDAuMDAxKSB0cmFuc2xhdGVZID0gMDtcclxuICAgICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVopIDwgMC4wMDEpIHRyYW5zbGF0ZVogPSAwO1xyXG4gICAgICBpZiAoTWF0aC5hYnMocm90YXRlWSkgPCAwLjAwMSkgcm90YXRlWSA9IDA7XHJcbiAgICAgIGlmIChNYXRoLmFicyhyb3RhdGVYKSA8IDAuMDAxKSByb3RhdGVYID0gMDtcclxuICAgICAgaWYgKE1hdGguYWJzKHNjYWxlKSA8IDAuMDAxKSBzY2FsZSA9IDA7XHJcbiAgICAgIGNvbnN0IHNsaWRlVHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7dHJhbnNsYXRlWH1weCwke3RyYW5zbGF0ZVl9cHgsJHt0cmFuc2xhdGVafXB4KSAgcm90YXRlWCgke3JvdGF0ZVh9ZGVnKSByb3RhdGVZKCR7cm90YXRlWX1kZWcpIHNjYWxlKCR7c2NhbGV9KWA7XHJcbiAgICAgIGNvbnN0IHRhcmdldEVsID0gZWZmZWN0VGFyZ2V0KHBhcmFtcywgc2xpZGVFbCk7XHJcbiAgICAgIHRhcmdldEVsLnN0eWxlLnRyYW5zZm9ybSA9IHNsaWRlVHJhbnNmb3JtO1xyXG4gICAgICBzbGlkZUVsLnN0eWxlLnpJbmRleCA9IC1NYXRoLmFicyhNYXRoLnJvdW5kKG9mZnNldE11bHRpcGxpZXIpKSArIDE7XHJcbiAgICAgIGlmIChwYXJhbXMuc2xpZGVTaGFkb3dzKSB7XHJcbiAgICAgICAgLy8gU2V0IHNoYWRvd3NcclxuICAgICAgICBsZXQgc2hhZG93QmVmb3JlRWwgPSBpc0hvcml6b250YWxcclxuICAgICAgICAgID8gc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0JylcclxuICAgICAgICAgIDogc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AnKTtcclxuICAgICAgICBsZXQgc2hhZG93QWZ0ZXJFbCA9IGlzSG9yaXpvbnRhbFxyXG4gICAgICAgICAgPyBzbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoJy5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0JylcclxuICAgICAgICAgIDogc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcclxuICAgICAgICBpZiAoIXNoYWRvd0JlZm9yZUVsKSB7XHJcbiAgICAgICAgICBzaGFkb3dCZWZvcmVFbCA9IGNyZWF0ZVNoYWRvdyhwYXJhbXMsIHNsaWRlRWwsIGlzSG9yaXpvbnRhbCA/ICdsZWZ0JyA6ICd0b3AnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFzaGFkb3dBZnRlckVsKSB7XHJcbiAgICAgICAgICBzaGFkb3dBZnRlckVsID0gY3JlYXRlU2hhZG93KHBhcmFtcywgc2xpZGVFbCwgaXNIb3Jpem9udGFsID8gJ3JpZ2h0JyA6ICdib3R0b20nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHNoYWRvd0JlZm9yZUVsKSBzaGFkb3dCZWZvcmVFbC5zdHlsZS5vcGFjaXR5ID0gb2Zmc2V0TXVsdGlwbGllciA+IDAgPyBvZmZzZXRNdWx0aXBsaWVyIDogMDtcclxuICAgICAgICBpZiAoc2hhZG93QWZ0ZXJFbCkgc2hhZG93QWZ0ZXJFbC5zdHlsZS5vcGFjaXR5ID0gLW9mZnNldE11bHRpcGxpZXIgPiAwID8gLW9mZnNldE11bHRpcGxpZXIgOiAwO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm1FbGVtZW50cyA9IHN3aXBlci5zbGlkZXMubWFwKChzbGlkZUVsKSA9PiBnZXRTbGlkZVRyYW5zZm9ybUVsKHNsaWRlRWwpKTtcclxuICAgIHRyYW5zZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgZWwucXVlcnlTZWxlY3RvckFsbChcclxuICAgICAgICAnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0J1xyXG4gICAgICApLmZvckVhY2goKHNoYWRvd0VsKSA9PiB7XHJcbiAgICAgICAgc2hhZG93RWwuc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7ZHVyYXRpb259bXNgO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgZWZmZWN0SW5pdCh7XHJcbiAgICBlZmZlY3Q6ICdjb3ZlcmZsb3cnLFxyXG4gICAgc3dpcGVyLFxyXG4gICAgb24sXHJcbiAgICBzZXRUcmFuc2xhdGUsXHJcbiAgICBzZXRUcmFuc2l0aW9uLFxyXG4gICAgcGVyc3BlY3RpdmU6ICgpID0+IHRydWUsXHJcbiAgICBvdmVyd3JpdGVQYXJhbXM6ICgpID0+ICh7XHJcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXHJcbiAgICB9KSxcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gRWZmZWN0Q3JlYXRpdmUoX3JlZikge1xyXG4gIGxldCB7IHN3aXBlciwgZXh0ZW5kUGFyYW1zLCBvbiB9ID0gX3JlZjtcclxuICBleHRlbmRQYXJhbXMoe1xyXG4gICAgY3JlYXRpdmVFZmZlY3Q6IHtcclxuICAgICAgbGltaXRQcm9ncmVzczogMSxcclxuICAgICAgc2hhZG93UGVyUHJvZ3Jlc3M6IGZhbHNlLFxyXG4gICAgICBwcm9ncmVzc011bHRpcGxpZXI6IDEsXHJcbiAgICAgIHBlcnNwZWN0aXZlOiB0cnVlLFxyXG4gICAgICBwcmV2OiB7XHJcbiAgICAgICAgdHJhbnNsYXRlOiBbMCwgMCwgMF0sXHJcbiAgICAgICAgcm90YXRlOiBbMCwgMCwgMF0sXHJcbiAgICAgICAgb3BhY2l0eTogMSxcclxuICAgICAgICBzY2FsZTogMSxcclxuICAgICAgfSxcclxuICAgICAgbmV4dDoge1xyXG4gICAgICAgI
9266HRyYW5zbGF0ZTogWzAsIDAsIDBdLFxyXG4gICAgICAgIHJvdGF0ZTogWzAsIDAsIDBdLFxyXG4gICAgICAgIG9wYWNpdHk6IDEsXHJcbiAgICAgICAgc2NhbGU6IDEsXHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gIH0pO1xyXG4gIGNvbnN0IGdldFRyYW5zbGF0ZVZhbHVlID0gKHZhbHVlKSA9PiB7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlO1xyXG4gICAgcmV0dXJuIGAke3ZhbHVlfXB4YDtcclxuICB9O1xyXG4gIGNvbnN0IHNldFRyYW5zbGF0ZSA9ICgpID0+IHtcclxuICAgIGNvbnN0IHsgc2xpZGVzLCB3cmFwcGVyRWwsIHNsaWRlc1NpemVzR3JpZCB9ID0gc3dpcGVyO1xyXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jcmVhdGl2ZUVmZmVjdDtcclxuICAgIGNvbnN0IHsgcHJvZ3Jlc3NNdWx0aXBsaWVyOiBtdWx0aXBsaWVyIH0gPSBwYXJhbXM7XHJcbiAgICBjb25zdCBpc0NlbnRlcmVkU2xpZGVzID0gc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcztcclxuICAgIGlmIChpc0NlbnRlcmVkU2xpZGVzKSB7XHJcbiAgICAgIGNvbnN0IG1hcmdpbiA9IHNsaWRlc1NpemVzR3JpZFswXSAvIDIgLSBzd2lwZXIucGFyYW1zLnNsaWRlc09mZnNldEJlZm9yZSB8fCAwO1xyXG4gICAgICB3cmFwcGVyRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZVgoY2FsYyg1MCUgLSAke21hcmdpbn1weCkpYDtcclxuICAgIH1cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGNvbnN0IHNsaWRlRWwgPSBzbGlkZXNbaV07XHJcbiAgICAgIGNvbnN0IHNsaWRlUHJvZ3Jlc3MgPSBzbGlkZUVsLnByb2dyZXNzO1xyXG4gICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWluKE1hdGgubWF4KHNsaWRlRWwucHJvZ3Jlc3MsIC1wYXJhbXMubGltaXRQcm9ncmVzcyksIHBhcmFtcy5saW1pdFByb2dyZXNzKTtcclxuICAgICAgbGV0IG9yaWdpbmFsUHJvZ3Jlc3MgPSBwcm9ncmVzcztcclxuICAgICAgaWYgKCFpc0NlbnRlcmVkU2xpZGVzKSB7XHJcbiAgICAgICAgb3JpZ2luYWxQcm9ncmVzcyA9IE1hdGgubWluKE1hdGgubWF4KHNsaWRlRWwub3JpZ2luYWxQcm9ncmVzcywgLXBhcmFtcy5saW1pdFByb2dyZXNzKSwgcGFyYW1zLmxpbWl0UHJvZ3Jlc3MpO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IHNsaWRlRWwuc3dpcGVyU2xpZGVPZmZzZXQ7XHJcbiAgICAgIGNvbnN0IHQgPSBbc3dpcGVyLnBhcmFtcy5jc3NNb2RlID8gLW9mZnNldCAtIHN3aXBlci50cmFuc2xhdGUgOiAtb2Zmc2V0LCAwLCAwXTtcclxuICAgICAgY29uc3QgciA9IFswLCAwLCAwXTtcclxuICAgICAgbGV0IGN1c3RvbSA9IGZhbHNlO1xyXG4gICAgICBpZiAoIXN3aXBlci5pc0hvcml6b250YWwoKSkge1xyXG4gICAgICAgIHRbMV0gPSB0WzBdO1xyXG4gICAgICAgIHRbMF0gPSAwO1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBkYXRhID0ge1xyXG4gICAgICAgIHRyYW5zbGF0ZTogWzAsIDAsIDBdLFxyXG4gICAgICAgIHJvdGF0ZTogWzAsIDAsIDBdLFxyXG4gICAgICAgIHNjYWxlOiAxLFxyXG4gICAgICAgIG9wYWNpdHk6IDEsXHJcbiAgICAgIH07XHJcbiAgICAgIGlmIChwcm9ncmVzcyA8IDApIHtcclxuICAgICAgICBkYXRhID0gcGFyYW1zLm5leHQ7XHJcbiAgICAgICAgY3VzdG9tID0gdHJ1ZTtcclxuICAgICAgfSBlbHNlIGlmIChwcm9ncmVzcyA+IDApIHtcclxuICAgICAgICBkYXRhID0gcGFyYW1zLnByZXY7XHJcbiAgICAgICAgY3VzdG9tID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgICAvLyBzZXQgdHJhbnNsYXRlXHJcbiAgICAgIHQuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgdFtpbmRleF0gPSBgY2FsYygke3ZhbHVlfXB4ICsgKCR7Z2V0VHJhbnNsYXRlVmFsdWUoZGF0YS50cmFuc2xhdGVbaW5kZXhdKX0gKiAke01hdGguYWJzKFxyXG4gICAgICAgICAgcHJvZ3Jlc3MgKiBtdWx0aXBsaWVyXHJcbiAgICAgICAgKX0pKWA7XHJcbiAgICAgIH0pO1xyXG4gICAgICAvLyBzZXQgcm90YXRlc1xyXG4gICAgICByLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgIHJbaW5kZXhdID0gZGF0YS5yb3RhdGVbaW5kZXhdICogTWF0aC5hYnMocHJvZ3Jlc3MgKiBtdWx0aXBsaWVyKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHNsaWRlRWwuc3R5bGUuekluZGV4ID0gLU1hdGguYWJzKE1hdGgucm91bmQoc2xpZGVQcm9ncmVzcykpICsgc2xpZGVzLmxlbmd0aDtcclxuICAgICAgY29uc3QgdHJhbnNsYXRlU3RyaW5nID0gdC5qb2luKCcsICcpO1xyXG4gICAgICBjb25zdCByb3RhdGVTdHJpbmcgPSBgcm90YXRlWCgke3JbMF19ZGVnKSByb3RhdGVZKCR7clsxXX1kZWcpIHJvdGF0ZVooJHtyWzJdfWRlZylgO1xyXG4gICAgICBjb25zdCBzY2FsZVN0cmluZyA9XHJcbiAgICAgICAgb3JpZ2luYWxQcm9ncmVzcyA8IDBcclxuICAgICAgICAgID8gYHNjYWxlKCR7MSArICgxIC0gZGF0YS5zY2FsZSkgKiBvcmlnaW5hbFByb2dyZXNzICogbXVsdGlwbGllcn0pYFxyXG4gICAgICAgICAgOiBgc2NhbGUoJHsxIC0gKDEgLSBkYXRhLnNjYWxlKSAqIG9yaWdpbmFsUHJvZ3Jlc3MgKiBtdWx0aXBsaWVyfSlgO1xyXG4gICAgICBjb25zdCBvcGFjaXR5U3RyaW5nID1cclxuICAgICAgICBvcmlnaW5hbFByb2dyZXNzIDwgMFxyXG4gICAgICAgICAgPyAxICsgKDEgLSBkYXRhLm9wYWNpdHkpICogb3JpZ2luYWxQcm9ncmVzcyAqIG11bHRpcGxpZXJcclxuICAgICAgICAgIDogMSAtICgxIC0gZGF0YS5vcGFjaXR5KSAqIG9yaWdpbmFsUHJvZ3Jlc3MgKiBtdWx0aXBsaWVyO1xyXG4gICAgICBjb25zdCB0cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt0cmFuc2xhdGVTdHJpbmd9KSAke3JvdGF0ZVN0cmluZ30gJHtzY2FsZVN0cmluZ31gO1xyXG5cclxuICAgICAgLy8gU2V0IHNoYWRvd3NcclxuICAgICAgaWYgKChjdXN0b20gJiYgZGF0YS5zaGFkb3cpIHx8ICFjdXN0b20pIHtcclxuICAgICAgICBsZXQgc2hhZG93RWwgPSBzbGlkZUVsLnF1ZXJ5U2VsZWN0b3IoJy5zd2lwZXItc2xpZGUtc2hhZG93Jyk7XHJcbiAgICAgICAgaWYgKCFzaGFkb3dFbCAmJiBkYXRhLnNoYWRvdykge1xyXG4gICAgICAgICAgc2hhZG93RWwgPSBjcmVhdGVTaGFkb3cocGFyYW1zLCBzbGlkZUVsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHNoYWRvd0VsKSB7XHJcbiAgICAgICAgICBjb25zdCBzaGFkb3dPcGFjaXR5ID0gcGFyYW1zLnNoYWRvd1BlclByb2dyZXNzID8gcHJvZ3Jlc3MgKiAoMSAvIHBhcmFtcy5saW1pdFByb2dyZXNzKSA6IHByb2dyZXNzO1xyXG4gICAgICAgICAgc2hhZG93RWwuc3R5bGUub3BhY2l0eSA9IE1hdGgubWluKE1hdGgubWF4KE1hdGguYWJzKHNoYWRvd09wYWNpdHkpLCAwKSwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHRhcmdldEVsID0gZWZmZWN0VGFyZ2V0KHBhcmFtcywgc2xpZGVFbCk7XHJcbiAgICAgIHRhcmdldEVsLnN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcclxuICAgICAgdGFyZ2V0RWwuc3R5bGUub3BhY2l0eSA9IG9wYWNpdHlTdHJpbmc7XHJcbiAgICAgIGlmIChkYXRhLm9yaWdpbikge1xyXG4gICAgICAgI
9266HRhcmdldEVsLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGRhdGEub3JpZ2luO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm1FbGVtZW50cyA9IHN3aXBlci5zbGlkZXMubWFwKChzbGlkZUVsKSA9PiBnZXRTbGlkZVRyYW5zZm9ybUVsKHNsaWRlRWwpKTtcclxuICAgIHRyYW5zZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgZWwucXVlcnlTZWxlY3RvckFsbCgnLnN3aXBlci1zbGlkZS1zaGFkb3cnKS5mb3JFYWNoKChzaGFkb3dFbCkgPT4ge1xyXG4gICAgICAgIHNoYWRvd0VsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kKHtcclxuICAgICAgc3dpcGVyLFxyXG4gICAgICBkdXJhdGlvbixcclxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMsXHJcbiAgICAgIGFsbFNsaWRlczogdHJ1ZSxcclxuICAgIH0pO1xyXG4gIH07XHJcbiAgZWZmZWN0SW5pdCh7XHJcbiAgICBlZmZlY3Q6ICdjcmVhdGl2ZScsXHJcbiAgICBzd2lwZXIsXHJcbiAgICBvbixcclxuICAgIHNldFRyYW5zbGF0ZSxcclxuICAgIHNldFRyYW5zaXRpb24sXHJcbiAgICBwZXJzcGVjdGl2ZTogKCkgPT4gc3dpcGVyLnBhcmFtcy5jcmVhdGl2ZUVmZmVjdC5wZXJzcGVjdGl2ZSxcclxuICAgIG92ZXJ3cml0ZVBhcmFtczogKCkgPT4gKHtcclxuICAgICAgd2F0Y2hTbGlkZXNQcm9ncmVzczogdHJ1ZSxcclxuICAgICAgdmlydHVhbFRyYW5zbGF0ZTogIXN3aXBlci5wYXJhbXMuY3NzTW9kZSxcclxuICAgIH0pLFxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBFZmZlY3RDYXJkcyhfcmVmKSB7XHJcbiAgbGV0IHsgc3dpcGVyLCBleHRlbmRQYXJhbXMsIG9uIH0gPSBfcmVmO1xyXG4gIGV4dGVuZFBhcmFtcyh7XHJcbiAgICBjYXJkc0VmZmVjdDoge1xyXG4gICAgICBzbGlkZVNoYWRvd3M6IHRydWUsXHJcbiAgICAgIHJvdGF0ZTogdHJ1ZSxcclxuICAgICAgcGVyU2xpZGVSb3RhdGU6IDIsXHJcbiAgICAgIHBlclNsaWRlT2Zmc2V0OiA4LFxyXG4gICAgfSxcclxuICB9KTtcclxuICBjb25zdCBzZXRUcmFuc2xhdGUgPSAoKSA9PiB7XHJcbiAgICBjb25zdCB7IHNsaWRlcywgYWN0aXZlSW5kZXgsIHJ0bFRyYW5zbGF0ZTogcnRsIH0gPSBzd2lwZXI7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmNhcmRzRWZmZWN0O1xyXG4gICAgY29uc3QgeyBzdGFydFRyYW5zbGF0ZSwgaXNUb3VjaGVkIH0gPSBzd2lwZXIudG91Y2hFdmVudHNEYXRhO1xyXG4gICAgY29uc3QgY3VycmVudFRyYW5zbGF0ZSA9IHJ0bCA/IC1zd2lwZXIudHJhbnNsYXRlIDogc3dpcGVyLnRyYW5zbGF0ZTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGNvbnN0IHNsaWRlRWwgPSBzbGlkZXNbaV07XHJcbiAgICAgIGNvbnN0IHNsaWRlUHJvZ3Jlc3MgPSBzbGlkZUVsLnByb2dyZXNzO1xyXG4gICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWluKE1hdGgubWF4KHNsaWRlUHJvZ3Jlc3MsIC00KSwgNCk7XHJcbiAgICAgIGxldCBvZmZzZXQgPSBzbGlkZUVsLnN3aXBlclNsaWRlT2Zmc2V0O1xyXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiAhc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XHJcbiAgICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke3N3aXBlci5taW5UcmFuc2xhdGUoKX1weClgO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xyXG4gICAgICAgIG9mZnNldCAtPSBzbGlkZXNbMF0uc3dpcGVyU2xpZGVPZmZzZXQ7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IHRYID0gc3dpcGVyLnBhcmFtcy5jc3NNb2RlID8gLW9mZnNldCAtIHN3aXBlci50cmFuc2xhdGUgOiAtb2Zmc2V0O1xyXG4gICAgICBsZXQgdFkgPSAwO1xyXG4gICAgICBjb25zdCB0WiA9IC0xMDAgKiBNYXRoLmFicyhwcm9ncmVzcyk7XHJcbiAgICAgIGxldCBzY2FsZSA9IDE7XHJcbiAgICAgIGxldCByb3RhdGUgPSAtcGFyYW1zLnBlclNsaWRlUm90YXRlICogcHJvZ3Jlc3M7XHJcbiAgICAgIGxldCB0WEFkZCA9IHBhcmFtcy5wZXJTbGlkZU9mZnNldCAtIE1hdGguYWJzKHByb2dyZXNzKSAqIDAuNzU7XHJcbiAgICAgIGNvbnN0IHNsaWRlSW5kZXggPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCA/IHN3aXBlci52aXJ0dWFsLmZyb20gKyBpIDogaTtcclxuICAgICAgY29uc3QgaXNTd2lwZVRvTmV4dCA9XHJcbiAgICAgICAgKHNsaWRlSW5kZXggPT09IGFjdGl2ZUluZGV4IHx8IHNsaWRlSW5kZXggPT09IGFjdGl2ZUluZGV4IC0gMSkgJiZcclxuICAgICAgICBwcm9ncmVzcyA+IDAgJiZcclxuICAgICAgICBwcm9ncmVzcyA8IDEgJiZcclxuICAgICAgICAoaXNUb3VjaGVkIHx8IHN3aXBlci5wYXJhbXMuY3NzTW9kZSkgJiZcclxuICAgICAgICBjdXJyZW50VHJhbnNsYXRlIDwgc3RhcnRUcmFuc2xhdGU7XHJcbiAgICAgIGNvbnN0IGlzU3dpcGVUb1ByZXYgPVxyXG4gICAgICAgIChzbGlkZUluZGV4ID09PSBhY3RpdmVJbmRleCB8fCBzbGlkZUluZGV4ID09PSBhY3RpdmVJbmRleCArIDEpICYmXHJcbiAgICAgICAgcHJvZ3Jlc3MgPCAwICYmXHJcbiAgICAgICAgcHJvZ3Jlc3MgPiAtMSAmJlxyXG4gICAgICAgIChpc1RvdWNoZWQgfHwgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSAmJlxyXG4gICAgICAgIGN1cnJlbnRUcmFuc2xhdGUgPiBzdGFydFRyYW5zbGF0ZTtcclxuICAgICAgaWYgKGlzU3dpcGVUb05leHQgfHwgaXNTd2lwZVRvUHJldikge1xyXG4gICAgICAgIGNvbnN0IHN1YlByb2dyZXNzID0gKDEgLSBNYXRoLmFicygoTWF0aC5hYnMocHJvZ3Jlc3MpIC0gMC41KSAvIDAuNSkpICoqIDAuNTtcclxuICAgICAgICByb3RhdGUgKz0gLTI4ICogcHJvZ3Jlc3MgKiBzdWJQcm9ncmVzcztcclxuICAgICAgICBzY2FsZSArPSAtMC41ICogc3ViUHJvZ3Jlc3M7XHJcbiAgICAgICAgdFhBZGQgKz0gOTYgKiBzdWJQcm9ncmVzcztcclxuICAgICAgICB0WSA9IGAkey0yNSAqIHN1YlByb2dyZXNzICogTWF0aC5hYnMocHJvZ3Jlc3MpfSVgO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9ncmVzcyA8IDApIHtcclxuICAgICAgICAvLyBuZXh0XHJcbiAgICAgICAgdFggPSBgY2FsYygke3RYfXB4ICR7cnRsID8gJy0nIDogJysnfSAoJHt0WEFkZCAqIE1hdGguYWJzKHByb2dyZXNzKX0lKSlgO1xyXG4gICAgICB9IGVsc2UgaWYgKHByb2dyZXNzID4gMCkge1xyXG4gICAgICAgIC8vIHByZXZcclxuICAgICAgICB0WCA9IGBjYWxjKCR7dFh9cHggJHtydGwgPyAnLScgOiAnKyd9ICgtJHt0WEFkZCAqIE1hdGguYWJzKHByb2dyZXNzKX0lKSlgO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgI
9266HRYID0gYCR7dFh9cHhgO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICghc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XHJcbiAgICAgICAgY29uc3QgcHJldlkgPSB0WTtcclxuICAgICAgICB0WSA9IHRYO1xyXG4gICAgICAgIHRYID0gcHJldlk7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3Qgc2NhbGVTdHJpbmcgPSBwcm9ncmVzcyA8IDAgPyBgJHsxICsgKDEgLSBzY2FsZSkgKiBwcm9ncmVzc31gIDogYCR7MSAtICgxIC0gc2NhbGUpICogcHJvZ3Jlc3N9YDtcclxuXHJcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlICovXHJcbiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGBcclxuICAgICAgICAgIHRyYW5zbGF0ZTNkKCR7dFh9LCAke3RZfSwgJHt0Wn1weClcclxuICAgICAgICAgIHJvdGF0ZVooJHtwYXJhbXMucm90YXRlID8gKHJ0bCA/IC1yb3RhdGUgOiByb3RhdGUpIDogMH1kZWcpXHJcbiAgICAgICAgICBzY2FsZSgke3NjYWxlU3RyaW5nfSlcclxuICAgICAgICBgO1xyXG4gICAgICAvKiBlc2xpbnQtZW5hYmxlICovXHJcblxyXG4gICAgICBpZiAocGFyYW1zLnNsaWRlU2hhZG93cykge1xyXG4gICAgICAgIC8vIFNldCBzaGFkb3dzXHJcbiAgICAgICAgbGV0IHNoYWRvd0VsID0gc2xpZGVFbC5xdWVyeVNlbGVjdG9yKCcuc3dpcGVyLXNsaWRlLXNoYWRvdycpO1xyXG4gICAgICAgIGlmICghc2hhZG93RWwpIHtcclxuICAgICAgICAgIHNoYWRvd0VsID0gY3JlYXRlU2hhZG93KHBhcmFtcywgc2xpZGVFbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzaGFkb3dFbCkgc2hhZG93RWwuc3R5bGUub3BhY2l0eSA9IE1hdGgubWluKE1hdGgubWF4KChNYXRoLmFicyhwcm9ncmVzcykgLSAwLjUpIC8gMC41LCAwKSwgMSk7XHJcbiAgICAgIH1cclxuICAgICAgc2xpZGVFbC5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChzbGlkZVByb2dyZXNzKSkgKyBzbGlkZXMubGVuZ3RoO1xyXG4gICAgICBjb25zdCB0YXJnZXRFbCA9IGVmZmVjdFRhcmdldChwYXJhbXMsIHNsaWRlRWwpO1xyXG4gICAgICB0YXJnZXRFbC5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XHJcbiAgICB9XHJcbiAgfTtcclxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uKSA9PiB7XHJcbiAgICBjb25zdCB0cmFuc2Zvcm1FbGVtZW50cyA9IHN3aXBlci5zbGlkZXMubWFwKChzbGlkZUVsKSA9PiBnZXRTbGlkZVRyYW5zZm9ybUVsKHNsaWRlRWwpKTtcclxuICAgIHRyYW5zZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XHJcbiAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgZWwucXVlcnlTZWxlY3RvckFsbCgnLnN3aXBlci1zbGlkZS1zaGFkb3cnKS5mb3JFYWNoKChzaGFkb3dFbCkgPT4ge1xyXG4gICAgICAgIHNoYWRvd0VsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2R1cmF0aW9ufW1zYDtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kKHtcclxuICAgICAgc3dpcGVyLFxyXG4gICAgICBkdXJhdGlvbixcclxuICAgICAgdHJhbnNmb3JtRWxlbWVudHMsXHJcbiAgICB9KTtcclxuICB9O1xyXG4gIGVmZmVjdEluaXQoe1xyXG4gICAgZWZmZWN0OiAnY2FyZHMnLFxyXG4gICAgc3dpcGVyLFxyXG4gICAgb24sXHJcbiAgICBzZXRUcmFuc2xhdGUsXHJcbiAgICBzZXRUcmFuc2l0aW9uLFxyXG4gICAgcGVyc3BlY3RpdmU6ICgpID0+IHRydWUsXHJcbiAgICBvdmVyd3JpdGVQYXJhbXM6ICgpID0+ICh7XHJcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXHJcbiAgICAgIHZpcnR1YWxUcmFuc2xhdGU6ICFzd2lwZXIucGFyYW1zLmNzc01vZGUsXHJcbiAgICB9KSxcclxuICB9KTtcclxufVxyXG5cclxuLy8gU3dpcGVyIENsYXNzXHJcbmNvbnN0IG1vZHVsZXMgPSBbXHJcbiAgVmlydHVhbCxcclxuICBLZXlib2FyZCxcclxuICBNb3VzZXdoZWVsLFxyXG4gIE5hdmlnYXRpb24sXHJcbiAgUGFnaW5hdGlvbixcclxuICBTY3JvbGxiYXIsXHJcbiAgUGFyYWxsYXgsXHJcbiAgWm9vbSxcclxuICBDb250cm9sbGVyLFxyXG4gIEExMXksXHJcbiAgSGlzdG9yeSxcclxuICBIYXNoTmF2aWdhdGlvbixcclxuICBBdXRvcGxheSxcclxuICBUaHVtYixcclxuICBmcmVlTW9kZSxcclxuICBHcmlkLFxyXG4gIE1hbmlwdWxhdGlvbixcclxuICBFZmZlY3RGYWRlLFxyXG4gIEVmZmVjdEN1YmUsXHJcbiAgRWZmZWN0RmxpcCxcclxuICBFZmZlY3RDb3ZlcmZsb3csXHJcbiAgRWZmZWN0Q3JlYXRpdmUsXHJcbiAgRWZmZWN0Q2FyZHMsXHJcbl07XHJcblN3aXBlci51c2UobW9kdWxlcyk7XHJcblxyXG5leHBvcnQgeyBTd2lwZXIsIFN3aXBlciBhcyBkZWZhdWx0IH07XHJcbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYn
9266BhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0IFN3aXBlciBmcm9tICdAc2NyaXB0cy9zd2lwZXItOS40LjEuanMnO1xyXG5jb25zdCB0YWJwYW5lbElkcyA9IFtcIiNsYXRlc3QtbmV3c1wiLCBcIiN2aWRlby16b25lXCIsIFwiI3JlbGF0ZWQtbmV3c1wiXTtcclxudGFicGFuZWxJZHMuZm9yRWFjaCgodGFicGFuZWxJZCkgPT4ge1xyXG4gICAgY29uc3Qgc3dpcGVyID0gbmV3IFN3aXBlcihgJHt0YWJwYW5lbElkfSAuc3dpcGVyYCwge1xyXG4gICAgICAgIHNsaWRlc1BlclZpZXc6IFwiYXV0b1wiLFxyXG4gICAgICAgIHBhZ2luYXRpb246IHtcclxuICAgICAgICAgICAgZWw6ICcuc3dpcGVyLXBhZ2luYXRpb24nLFxyXG4gICAgICAgICAgICB0eXBlOiAnZnJhY3Rpb24nLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbmF2aWdhdGlvbjoge1xyXG4gICAgICAgICAgICBuZXh0RWw6IHRhYnBhbmVsSWQgKyBcIiAuc3dpcGVyLWJ0bi1uZXh0XCIsXHJcbiAgICAgICAgICAgIHByZXZFbDogdGFicGFuZWxJZCArIFwiIC5zd2lwZXItYnRuLXByZXZcIixcclxuICAgICAgICB9LFxyXG4gICAgfSk7XHJcbiAgICBzd2lwZXIuYWxsb3dUb3VjaE1vdmUgPSBmYWxzZTtcclxufSk7XHJcbmNvbnN0IG91clN0b3J5U3dpcGVyID0gbmV3IFN3aXBlcihcIi5zZWN0aW9uLWJvZHktb25lIC5zd2lwZXIuc3dpcGVyLW5tXCIsIHtcclxuICAgIC8vIGVmZmVjdDogXCJmYWRlXCIsXHJcbiAgICBwYWdpbmF0aW9uOiB7XHJcbiAgICAgICAgZWw6ICcuc2VjdGlvbi1ib2R5LW9uZSAuc3dpcGVyLXBhZ2luYXRpb24nLFxyXG4gICAgICAgIHR5cGU6ICdmcmFjdGlvbicsXHJcbiAgICB9LFxyXG4gICAgbmF2aWdhdGlvbjoge1xyXG4gICAgICAgIG5leHRFbDogXCIuc2VjdGlvbi1ib2R5LW9uZSAuc3dpcGVyLWJ0bi1uZXh0XCIsXHJcbiAgICAgICAgcHJldkVsOiBcIi5zZWN0aW9uLWJvZHktb25lIC5zd2lwZXItYnRuLXByZXZcIixcclxuICAgIH0sXHJcbn0pO1xyXG5vdXJTdG9yeVN3aXBlci5hbGxvd1RvdWNoTW92ZSA9IGZhbHNlO1xyXG5cclxuY29uc3Qgb3VyU3RvcnlTbVN3aXBlciA9IG5ldyBTd2lwZXIoXCIuc2VjdGlvbi1ib2R5LXR3byAuc3dpcGVyLnN3aXBlci1zbVwiLCB7XHJcbiAgICBlZmZlY3Q6IFwiZmFkZVwiLFxyXG4gICAgcGFnaW5hdGlvbjoge1xyXG4gICAgICAgIGVsOiAnLnNlY3Rpb24tYm9keS10d28gLnN3aXBlci1wYWdpbmF0aW9uJyxcclxuICAgICAgICB0eXBlOiAnZnJhY3Rpb24nLFxyXG4gICAgfSxcclxuICAgIG5hdmlnYXRpb246IHtcclxuICAgICAgICBuZXh0RWw6IFwiLnNlY3Rpb24tYm9keS10d28gLnN3aXBlci1idG4tbmV4dFwiLFxyXG4gICAgICAgIHByZXZFbDogXCIuc2VjdGlvbi1ib2R5LXR3byAuc3dpcGVyLWJ0bi1wcmV2XCIsXHJcbiAgICB9LFxyXG59KTtcclxub3VyU3RvcnlTbVN3aXBlci5hbGxvd1RvdWNoTW92ZSA9IGZhbHNlOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.