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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BQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsaUNBQWlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF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FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxpQkFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLFVBQVUsaUJBQWlCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxVQUFVLGlCQUFpQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0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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.