UNPKG

angular-responsive-carousel-ng16

Version:

Carousel for Angular. A simple solution for horizontal scrolling images with lazy loading.

343 lines 43.4 kB
export class Touches { get touchListeners() { return this.properties.touchListeners ? this.properties.touchListeners : this._touchListeners; } get mouseListeners() { return this.properties.mouseListeners ? this.properties.mouseListeners : this._mouseListeners; } get otherListeners() { return this.properties.otherListeners ? this.properties.otherListeners : this._otherListeners; } constructor(properties) { this.eventType = undefined; this.handlers = {}; this.startX = 0; this.startY = 0; this.lastTap = 0; this.doubleTapMinTimeout = 300; this.tapMinTimeout = 200; this.touchstartTime = 0; this.i = 0; this.isMousedown = false; this._touchListeners = { "touchstart": "handleTouchstart", "touchmove": "handleTouchmove", "touchend": "handleTouchend" }; this._mouseListeners = { "mousedown": "handleMousedown", "mousemove": "handleMousemove", "mouseup": "handleMouseup", "wheel": "handleWheel" }; this._otherListeners = { "resize": "handleResize" }; /* * Listeners */ /* Touchstart */ this.handleTouchstart = (event) => { this.elementPosition = this.getElementPosition(); this.touchstartTime = new Date().getTime(); if (this.eventType === undefined) { this.getTouchstartPosition(event); } this.runHandler("touchstart", event); }; /* Touchmove */ this.handleTouchmove = (event) => { const touches = event.touches; // Pan if (this.detectPan(touches)) { this.runHandler("pan", event); } // Pinch if (this.detectPinch(event)) { this.runHandler("pinch", event); } // Linear swipe switch (this.detectLinearSwipe(event)) { case "horizontal-swipe": event.swipeType = "horizontal-swipe"; this.runHandler("horizontal-swipe", event); break; case "vertical-swipe": event.swipeType = "vertical-swipe"; this.runHandler("vertical-swipe", event); break; } // Linear swipe if (this.detectLinearSwipe(event) || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') { this.handleLinearSwipe(event); } }; /* Touchend */ this.handleTouchend = (event) => { const touches = event.touches; // Double Tap if (this.detectDoubleTap()) { this.runHandler("double-tap", event); } // Tap this.detectTap(); this.runHandler("touchend", event); this.eventType = 'touchend'; if (touches && touches.length === 0) { this.eventType = undefined; this.i = 0; } }; /* Mousedown */ this.handleMousedown = (event) => { this.isMousedown = true; this.elementPosition = this.getElementPosition(); this.touchstartTime = new Date().getTime(); if (this.eventType === undefined) { this.getMousedownPosition(event); } this.runHandler("mousedown", event); }; /* Mousemove */ this.handleMousemove = (event) => { //event.preventDefault(); if (!this.isMousedown) { return; } // Pan this.runHandler("pan", event); // Linear swipe switch (this.detectLinearSwipe(event)) { case "horizontal-swipe": event.swipeType = "horizontal-swipe"; this.runHandler("horizontal-swipe", event); break; case "vertical-swipe": event.swipeType = "vertical-swipe"; this.runHandler("vertical-swipe", event); break; } // Linear swipe if (this.detectLinearSwipe(event) || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') { this.handleLinearSwipe(event); } }; /* Mouseup */ this.handleMouseup = (event) => { // Tap this.detectTap(); this.isMousedown = false; this.runHandler("mouseup", event); this.eventType = undefined; this.i = 0; }; /* Wheel */ this.handleWheel = (event) => { this.runHandler("wheel", event); }; /* Resize */ this.handleResize = (event) => { this.runHandler("resize", event); }; this.properties = properties; this.element = this.properties.element; this.elementPosition = this.getElementPosition(); this.toggleEventListeners('addEventListener'); } destroy() { this.toggleEventListeners('removeEventListener'); } toggleEventListeners(action) { let listeners; if (this.properties.listeners === 'mouse and touch') { listeners = Object.assign(this.touchListeners, this.mouseListeners); } else { listeners = this.detectTouchScreen() ? this.touchListeners : this.mouseListeners; } if (this.properties.resize) { listeners = Object.assign(listeners, this.otherListeners); } for (var listener in listeners) { const handler = listeners[listener]; // Window if (listener === "resize") { if (action === 'addEventListener') { window.addEventListener(listener, this[handler], false); } if (action === 'removeEventListener') { window.removeEventListener(listener, this[handler], false); } // Document } else if (listener === 'mouseup' || listener === "mousemove") { if (action === 'addEventListener') { document.addEventListener(listener, this[handler], { passive: false }); } if (action === 'removeEventListener') { document.removeEventListener(listener, this[handler], false); } // Element } else { if (action === 'addEventListener') { this.element.addEventListener(listener, this[handler], false); } if (action === 'removeEventListener') { this.element.removeEventListener(listener, this[handler], false); } } } } addEventListeners(listener) { const handler = this._mouseListeners[listener]; window.addEventListener(listener, this[handler], false); } removeEventListeners(listener) { const handler = this._mouseListeners[listener]; window.removeEventListener(listener, this[handler], false); } handleLinearSwipe(event) { //event.preventDefault(); this.i++; if (this.i > 3) { this.eventType = this.getLinearSwipeType(event); } if (this.eventType === 'horizontal-swipe') { this.runHandler('horizontal-swipe', event); } if (this.eventType === 'vertical-swipe') { this.runHandler('vertical-swipe', event); } } runHandler(eventName, response) { if (this.handlers[eventName]) { this.handlers[eventName](response); } } /* * Detection */ detectPan(touches) { return touches.length === 1 && !this.eventType || this.eventType === 'pan'; } detectDoubleTap() { if (this.eventType != undefined) { return; } const currentTime = new Date().getTime(); const tapLength = currentTime - this.lastTap; clearTimeout(this.doubleTapTimeout); if (tapLength < this.doubleTapMinTimeout && tapLength > 0) { return true; } else { this.doubleTapTimeout = setTimeout(() => { clearTimeout(this.doubleTapTimeout); }, this.doubleTapMinTimeout); } this.lastTap = currentTime; return undefined; } detectTap() { if (this.eventType != undefined) { return; } const currentTime = new Date().getTime(); const tapLength = currentTime - this.touchstartTime; if (tapLength > 0) { if (tapLength < this.tapMinTimeout) { this.runHandler("tap", event); } else { this.runHandler("longtap", event); } } } detectPinch(event) { const touches = event.touches; return (touches.length === 2 && this.eventType === undefined) || this.eventType === 'pinch'; } detectLinearSwipe(event) { const touches = event.touches; if (touches) { if (touches.length === 1 && !this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') { return this.getLinearSwipeType(event); } } else { if (!this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') { return this.getLinearSwipeType(event); } } return undefined; } getLinearSwipeType(event) { if (this.eventType !== 'horizontal-swipe' && this.eventType !== 'vertical-swipe') { const movementX = Math.abs(this.moveLeft(0, event) - this.startX); const movementY = Math.abs(this.moveTop(0, event) - this.startY); if ((movementY * 3) > movementX) { return 'vertical-swipe'; } else { return 'horizontal-swipe'; } } else { return this.eventType; } } getElementPosition() { return this.element.getBoundingClientRect(); } getTouchstartPosition(event) { this.startX = event.touches[0].clientX - this.elementPosition.left; this.startY = event.touches[0].clientY - this.elementPosition.top; } getMousedownPosition(event) { this.startX = event.clientX - this.elementPosition.left; this.startY = event.clientY - this.elementPosition.top; } moveLeft(index, event) { const touches = event.touches; if (touches) { return touches[index].clientX - this.elementPosition.left; } else { return event.clientX - this.elementPosition.left; } } moveTop(index, event) { const touches = event.touches; if (touches) { return touches[index].clientY - this.elementPosition.top; } else { return event.clientY - this.elementPosition.top; } } detectTouchScreen() { var prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); var mq = function (query) { return window.matchMedia(query).matches; }; if (('ontouchstart' in window)) { return true; } // include the 'heartz' as a way to have a non matching MQ to help terminate the join // https://git.io/vznFH var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''); return mq(query); } /* Public properties and methods */ on(event, handler) { if (event) { this.handlers[event] = handler; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG91Y2hlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItcmVzcG9uc2l2ZS1jYXJvdXNlbC1uZzE2L3NyYy9saWIvdG91Y2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFhQSxNQUFNLE9BQU8sT0FBTztJQStCaEIsSUFBSSxjQUFjO1FBQ2QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7SUFDbEcsQ0FBQztJQUVELElBQUksY0FBYztRQUNkLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ2xHLENBQUM7SUFFRCxJQUFJLGNBQWM7UUFDZCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNsRyxDQUFDO0lBRUQsWUFBWSxVQUFzQjtRQXZDbEMsY0FBUyxHQUFjLFNBQVMsQ0FBQztRQUNqQyxhQUFRLEdBQVEsRUFBRSxDQUFDO1FBQ25CLFdBQU0sR0FBRyxDQUFDLENBQUM7UUFDWCxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUVaLHdCQUFtQixHQUFHLEdBQUcsQ0FBQztRQUMxQixrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUNwQixtQkFBYyxHQUFHLENBQUMsQ0FBQztRQUNuQixNQUFDLEdBQVcsQ0FBQyxDQUFDO1FBQ2QsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFcEIsb0JBQWUsR0FBUTtZQUNuQixZQUFZLEVBQUUs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SyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQztTQUNuRDtJQUNMLENBQUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLFFBQVEsR0FBRywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEQsSUFBSSxFQUFFLEdBQUcsVUFBUyxLQUFVO1lBQ3hCLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDNUMsQ0FBQyxDQUFBO1FBRUQsSUFBSSxDQUFDLGNBQWMsSUFBSSxNQUFNLENBQUMsRUFBRTtZQUM1QixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQscUZBQXFGO1FBQ3JGLHVCQUF1QjtRQUN2QixJQUFJLEtBQUssR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBR0QsbUNBQW1DO0lBQ25DLEVBQUUsQ0FBQyxLQUFnQixFQUFFLE9BQWlCO1FBQ2xDLElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUM7U0FDbEM7SUFDTCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIFByb3BlcnRpZXMge1xuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIGxpc3RlbmVycz86ICdhdXRvJyB8ICdtb3VzZSBhbmQgdG91Y2gnO1xuICAgIHRvdWNoTGlzdGVuZXJzPzogYW55O1xuICAgIG1vdXNlTGlzdGVuZXJzPzogYW55O1xuICAgIG90aGVyTGlzdGVuZXJzPzogYW55O1xuICAgIHJlc2l6ZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIEV2ZW50VHlwZSA9IHVuZGVmaW5lZCB8ICd0b3VjaGVuZCcgfCAncGFuJyB8ICdwaW5jaCcgfCAnaG9yaXpvbnRhbC1zd2lwZScgfCAndmVydGljYWwtc3dpcGUnIHwgJ3RhcCcgfCAnbG9uZ3RhcCc7XG5leHBvcnQgdHlwZSBUb3VjaEhhbmRsZXIgPSAnaGFuZGxlVG91Y2hzdGFydCcgfCAnaGFuZGxlVG91Y2htb3ZlJyB8ICdoYW5kbGVUb3VjaGVuZCc7XG5leHBvcnQgdHlwZSBNb3VzZUhhbmRsZXIgPSAnaGFuZGxlTW91c2Vkb3duJyB8ICdoYW5kbGVNb3VzZW1vdmUnIHwgJ2hhbmRsZU1vdXNldXAnO1xuXG5leHBvcnQgY2xhc3MgVG91Y2hlcyB7XG4gICAgcHJvcGVydGllczogUHJvcGVydGllcztcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBlbGVtZW50UG9zaXRpb246IENsaWVudFJlY3Q7XG4gICAgZXZlbnRUeXBlOiBFdmVudFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgaGFuZGxlcnM6IGFueSA9IHt9O1xuICAgIHN0YXJ0WCA9IDA7XG4gICAgc3RhcnRZID0gMDtcbiAgICBsYXN0VGFwID0gMDtcbiAgICBkb3VibGVUYXBUaW1lb3V0OiBhbnk7XG4gICAgZG91YmxlVGFwTWluVGltZW91dCA9IDMwMDtcbiAgICB0YXBNaW5UaW1lb3V0ID0gMjAwO1xuICAgIHRvdWNoc3RhcnRUaW1lID0gMDtcbiAgICBpOiBudW1iZXIgPSAwO1xuICAgIGlzTW91c2Vkb3duID0gZmFsc2U7XG5cbiAgICBfdG91Y2hMaXN0ZW5lcnM6IGFueSA9IHtcbiAgICAgICAgXCJ0b3VjaHN0YXJ0XCI6IFwiaGFuZGxlVG91Y2hzdGFydFwiLFxuICAgICAgICBcInRvdWNobW92ZVwiOiBcImhhbmRsZVRvdWNobW92ZVwiLFxuICAgICAgICBcInRvdWNoZW5kXCI6IFwiaGFuZGxlVG91Y2hlbmRcIlxuICAgIH1cbiAgICBfbW91c2VMaXN0ZW5lcnM6IGFueSA9IHtcbiAgICAgICAgXCJtb3VzZWRvd25cIjogXCJoYW5kbGVNb3VzZWRvd25cIixcbiAgICAgICAgXCJtb3VzZW1vdmVcIjogXCJoYW5kbGVNb3VzZW1vdmVcIixcbiAgICAgICAgXCJtb3VzZXVwXCI6IFwiaGFuZGxlTW91c2V1cFwiLFxuICAgICAgICBcIndoZWVsXCI6IFwiaGFuZGxlV2hlZWxcIlxuICAgIH1cbiAgICBfb3RoZXJMaXN0ZW5lcnM6IGFueSA9IHtcbiAgICAgICAgXCJyZXNpemVcIjogXCJoYW5kbGVSZXNpemVcIlxuICAgIH1cblxuICAgIGdldCB0b3VjaExpc3RlbmVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllcy50b3VjaExpc3RlbmVycyA/IHRoaXMucHJvcGVydGllcy50b3VjaExpc3RlbmVycyA6IHRoaXMuX3RvdWNoTGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGdldCBtb3VzZUxpc3RlbmVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllcy5tb3VzZUxpc3RlbmVycyA/IHRoaXMucHJvcGVydGllcy5tb3VzZUxpc3RlbmVycyA6IHRoaXMuX21vdXNlTGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGdldCBvdGhlckxpc3RlbmVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllcy5vdGhlckxpc3RlbmVycyA/IHRoaXMucHJvcGVydGllcy5vdGhlckxpc3RlbmVycyA6IHRoaXMuX290aGVyTGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByb3BlcnRpZXM6IFByb3BlcnRpZXMpIHtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy5wcm9wZXJ0aWVzLmVsZW1lbnQ7XG4gICAgICAgIHRoaXMuZWxlbWVudFBvc2l0aW9uID0gdGhpcy5nZXRFbGVtZW50UG9zaXRpb24oKTtcblxuICAgICAgICB0aGlzLnRvZ2dsZUV2ZW50TGlzdGVuZXJzKCdhZGRFdmVudExpc3RlbmVyJyk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy50b2dnbGVFdmVudExpc3RlbmVycygncmVtb3ZlRXZlbnRMaXN0ZW5lcicpO1xuICAgIH1cblxuICAgIHRvZ2dsZUV2ZW50TGlzdGVuZXJzKGFjdGlvbjogJ2FkZEV2ZW50TGlzdGVuZXInIHwgJ3JlbW92ZUV2ZW50TGlzdGVuZXInKSB7XG4gICAgICAgIGxldCBsaXN0ZW5lcnM7XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcy5saXN0ZW5lcnMgPT09ICdtb3VzZSBhbmQgdG91Y2gnKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSBPYmplY3QuYXNzaWduKHRoaXMudG91Y2hMaXN0ZW5lcnMsIHRoaXMubW91c2VMaXN0ZW5lcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGlzdGVuZXJzID0gdGhpcy5kZXRlY3RUb3VjaFNjcmVlbigpID8gdGhpcy50b3VjaExpc3RlbmVycyA6IHRoaXMubW91c2VMaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzLnJlc2l6ZSkge1xuICAgICAgICAgICAgbGlzdGVuZXJzID0gT2JqZWN0LmFzc2lnbihsaXN0ZW5lcnMsIHRoaXMub3RoZXJMaXN0ZW5lcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXIgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBoYW5kbGVyOiBNb3VzZUhhbmRsZXIgPSBsaXN0ZW5lcnNbbGlzdGVuZXJdO1xuXG4gICAgICAgICAgICAvLyBXaW5kb3dcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lciA9PT0gXCJyZXNpemVcIikge1xuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdhZGRFdmVudExpc3RlbmVyJykge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAncmVtb3ZlRXZlbnRMaXN0ZW5lcicpIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIobGlzdGVuZXIsIHRoaXNbaGFuZGxlcl0sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBEb2N1bWVudFxuICAgICAgICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lciA9PT0gJ21vdXNldXAnIHx8IGxpc3RlbmVyID09PSBcIm1vdXNlbW92ZVwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2FkZEV2ZW50TGlzdGVuZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIobGlzdGVuZXIsIHRoaXNbaGFuZGxlcl0sIHtwYXNzaXZlOiBmYWxzZX0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAncmVtb3ZlRXZlbnRMaXN0ZW5lcicpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEVsZW1lbnRcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2FkZEV2ZW50TGlzdGVuZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGxpc3RlbmVyLCB0aGlzW2hhbmRsZXJdLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdyZW1vdmVFdmVudExpc3RlbmVyJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZEV2ZW50TGlzdGVuZXJzKGxpc3RlbmVyOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcjogTW91c2VIYW5kbGVyID0gdGhpcy5fbW91c2VMaXN0ZW5lcnNbbGlzdGVuZXJdO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xuICAgIH1cblxuICAgIHJlbW92ZUV2ZW50TGlzdGVuZXJzKGxpc3RlbmVyOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcjogTW91c2VIYW5kbGVyID0gdGhpcy5fbW91c2VMaXN0ZW5lcnNbbGlzdGVuZXJdO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogTGlzdGVuZXJzXG4gICAgICovXG5cbiAgICAvKiBUb3VjaHN0YXJ0ICovXG5cbiAgICBoYW5kbGVUb3VjaHN0YXJ0ID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5lbGVtZW50UG9zaXRpb24gPSB0aGlzLmdldEVsZW1lbnRQb3NpdGlvbigpO1xuICAgICAgICB0aGlzLnRvdWNoc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0VG91Y2hzdGFydFBvc2l0aW9uKGV2ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucnVuSGFuZGxlcihcInRvdWNoc3RhcnRcIiwgZXZlbnQpO1xuICAgIH1cblxuXG4gICAgLyogVG91Y2htb3ZlICovXG5cbiAgICBoYW5kbGVUb3VjaG1vdmUgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcblxuICAgICAgICAvLyBQYW5cbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0UGFuKHRvdWNoZXMpKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJwYW5cIiwgZXZlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGluY2hcbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0UGluY2goZXZlbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJwaW5jaFwiLCBldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcbiAgICAgICAgc3dpdGNoICh0aGlzLmRldGVjdExpbmVhclN3aXBlKGV2ZW50KSkge1xuICAgICAgICAgICAgY2FzZSBcImhvcml6b250YWwtc3dpcGVcIjpcbiAgICAgICAgICAgICAgICBldmVudC5zd2lwZVR5cGUgPSBcImhvcml6b250YWwtc3dpcGVcIjtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJob3Jpem9udGFsLXN3aXBlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJ2ZXJ0aWNhbC1zd2lwZVwiOlxuICAgICAgICAgICAgICAgIGV2ZW50LnN3aXBlVHlwZSA9IFwidmVydGljYWwtc3dpcGVcIjtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ2ZXJ0aWNhbC1zd2lwZVwiLCBldmVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0TGluZWFyU3dpcGUoZXZlbnQpIHx8XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnIHx8XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ3ZlcnRpY2FsLXN3aXBlJykge1xuXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUxpbmVhclN3aXBlKGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGhhbmRsZUxpbmVhclN3aXBlKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgLy9ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuaSsrO1xuXG4gICAgICAgIGlmICh0aGlzLmkgPiAzKSB7XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9IHRoaXMuZ2V0TGluZWFyU3dpcGVUeXBlKGV2ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoJ2hvcml6b250YWwtc3dpcGUnLCBldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgPT09ICd2ZXJ0aWNhbC1zd2lwZScpIHtcbiAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcigndmVydGljYWwtc3dpcGUnLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qIFRvdWNoZW5kICovXG5cbiAgICBoYW5kbGVUb3VjaGVuZCA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHRvdWNoZXMgPSBldmVudC50b3VjaGVzO1xuXG4gICAgICAgIC8vIERvdWJsZSBUYXBcbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0RG91YmxlVGFwKCkpIHtcbiAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcihcImRvdWJsZS10YXBcIiwgZXZlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGFwXG4gICAgICAgIHRoaXMuZGV0ZWN0VGFwKCk7XG5cbiAgICAgICAgdGhpcy5ydW5IYW5kbGVyKFwidG91Y2hlbmRcIiwgZXZlbnQpO1xuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICd0b3VjaGVuZCc7XG5cbiAgICAgICAgaWYgKHRvdWNoZXMgJiYgdG91Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRUeXBlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5pID0gMDtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogTW91c2Vkb3duICovXG5cbiAgICBoYW5kbGVNb3VzZWRvd24gPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmlzTW91c2Vkb3duID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5lbGVtZW50UG9zaXRpb24gPSB0aGlzLmdldEVsZW1lbnRQb3NpdGlvbigpO1xuICAgICAgICB0aGlzLnRvdWNoc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0TW91c2Vkb3duUG9zaXRpb24oZXZlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ydW5IYW5kbGVyKFwibW91c2Vkb3duXCIsIGV2ZW50KTtcbiAgICB9XG5cblxuICAgIC8qIE1vdXNlbW92ZSAqL1xuXG4gICAgaGFuZGxlTW91c2Vtb3ZlID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgLy9ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBcbiAgICAgICAgaWYgKCF0aGlzLmlzTW91c2Vkb3duKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQYW5cbiAgICAgICAgdGhpcy5ydW5IYW5kbGVyKFwicGFuXCIsIGV2ZW50KTtcblxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcbiAgICAgICAgc3dpdGNoICh0aGlzLmRldGVjdExpbmVhclN3aXBlKGV2ZW50KSkge1xuICAgICAgICAgICAgY2FzZSBcImhvcml6b250YWwtc3dpcGVcIjpcbiAgICAgICAgICAgICAgICBldmVudC5zd2lwZVR5cGUgPSBcImhvcml6b250YWwtc3dpcGVcIjtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJob3Jpem9udGFsLXN3aXBlXCIsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJ2ZXJ0aWNhbC1zd2lwZVwiOlxuICAgICAgICAgICAgICAgIGV2ZW50LnN3aXBlVHlwZSA9IFwidmVydGljYWwtc3dpcGVcIjtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ2ZXJ0aWNhbC1zd2lwZVwiLCBldmVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0TGluZWFyU3dpcGUoZXZlbnQpIHx8XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnIHx8XG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ3ZlcnRpY2FsLXN3aXBlJykge1xuXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUxpbmVhclN3aXBlKGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyogTW91c2V1cCAqL1xuXG4gICAgaGFuZGxlTW91c2V1cCA9IChldmVudDogYW55KSA9PiB7XG5cbiAgICAgICAgLy8gVGFwXG4gICAgICAgIHRoaXMuZGV0ZWN0VGFwKCk7XG5cbiAgICAgICAgdGhpcy5pc01vdXNlZG93biA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJtb3VzZXVwXCIsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5ldmVudFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgfVxuXG5cbiAgICAvKiBXaGVlbCAqL1xuXG4gICAgaGFuZGxlV2hlZWwgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ3aGVlbFwiLCBldmVudCk7XG4gICAgfVxuXG4gICAgLyogUmVzaXplICovXG5cbiAgICBoYW5kbGVSZXNpemUgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJyZXNpemVcIiwgZXZlbnQpO1xuICAgIH1cblxuICAgIHJ1bkhhbmRsZXIoZXZlbnROYW1lOiBhbnksIHJlc3BvbnNlOiBhbnkpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFuZGxlcnNbZXZlbnROYW1lXSkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVyc1tldmVudE5hbWVdKHJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLypcbiAgICAgKiBEZXRlY3Rpb25cbiAgICAgKi9cblxuICAgIGRldGVjdFBhbih0b3VjaGVzOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIHRvdWNoZXMubGVuZ3RoID09PSAxICYmICF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ3Bhbic7XG4gICAgfVxuXG4gICAgZGV0ZWN0RG91YmxlVGFwKCkge1xuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCB0YXBMZW5ndGggPSBjdXJyZW50VGltZSAtIHRoaXMubGFzdFRhcDtcblxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5kb3VibGVUYXBUaW1lb3V0KTtcblxuICAgICAgICBpZiAodGFwTGVuZ3RoIDwgdGhpcy5kb3VibGVUYXBNaW5UaW1lb3V0ICYmIHRhcExlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kb3VibGVUYXBUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZG91YmxlVGFwVGltZW91dCk7XG4gICAgICAgICAgICB9LCB0aGlzLmRvdWJsZVRhcE1pblRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGFzdFRhcCA9IGN1cnJlbnRUaW1lO1xuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZGV0ZWN0VGFwKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCB0YXBMZW5ndGggPSBjdXJyZW50VGltZSAtIHRoaXMudG91Y2hzdGFydFRpbWU7XG5cbiAgICAgICAgaWYgKHRhcExlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlmICh0YXBMZW5ndGggPCB0aGlzLnRhcE1pblRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ0YXBcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJsb25ndGFwXCIsIGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRldGVjdFBpbmNoKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgY29uc3QgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XG4gICAgICAgIHJldHVybiAodG91Y2hlcy5sZW5ndGggPT09IDIgJiYgdGhpcy5ldmVudFR5cGUgPT09IHVuZGVmaW5lZCkgfHwgdGhpcy5ldmVudFR5cGUgPT09ICdwaW5jaCc7XG4gICAgfVxuXG4gICAgZGV0ZWN0TGluZWFyU3dpcGUoZXZlbnQ6IGFueSkge1xuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcblxuICAgICAgICBpZiAodG91Y2hlcykge1xuICAgICAgICAgICAgaWYgKHRvdWNoZXMubGVuZ3RoID09PSAxICYmICF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnIHx8IHRoaXMuZXZlbnRUeXBlID09PSAndmVydGljYWwtc3dpcGUnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZWFyU3dpcGVUeXBlKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5ldmVudFR5cGUgfHwgdGhpcy5ldmVudFR5cGUgPT09ICdob3Jpem9udGFsLXN3aXBlJyB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ3ZlcnRpY2FsLXN3aXBlJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldExpbmVhclN3aXBlVHlwZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGdldExpbmVhclN3aXBlVHlwZShldmVudDogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLmV2ZW50VHlwZSAhPT0gJ2hvcml6b250YWwtc3dpcGUnICYmIHRoaXMuZXZlbnRUeXBlICE9PSAndmVydGljYWwtc3dpcGUnKSB7XG4gICAgICAgICAgICBjb25zdCBtb3ZlbWVudFggPSBNYXRoLmFicyh0aGlzLm1vdmVMZWZ0KDAsIGV2ZW50KSAtIHRoaXMuc3RhcnRYKTtcbiAgICAgICAgICAgIGNvbnN0IG1vdmVtZW50WSA9IE1hdGguYWJzKHRoaXMubW92ZVRvcCgwLCBldmVudCkgLSB0aGlzLnN0YXJ0WSk7XG5cbiAgICAgICAgICAgIGlmICgobW92ZW1lbnRZICogMykgPiBtb3ZlbWVudFgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3ZlcnRpY2FsLXN3aXBlJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdob3Jpem9udGFsLXN3aXBlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50VHlwZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldEVsZW1lbnRQb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cbiAgICBnZXRUb3VjaHN0YXJ0UG9zaXRpb24oZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLnN0YXJ0WCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQ7XG4gICAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wO1xuICAgIH1cblxuICAgIGdldE1vdXNlZG93blBvc2l0aW9uKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5zdGFydFggPSBldmVudC5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcbiAgICAgICAgdGhpcy5zdGFydFkgPSBldmVudC5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wO1xuICAgIH1cblxuICAgIG1vdmVMZWZ0KGluZGV4OiBhbnksIGV2ZW50OiBhbnkpIHtcbiAgICAgICAgY29uc3QgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XG5cbiAgICAgICAgaWYgKHRvdWNoZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB0b3VjaGVzW2luZGV4XS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudC5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG1vdmVUb3AoaW5kZXg6IGFueSwgZXZlbnQ6IGFueSkge1xuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcblxuICAgICAgICBpZiAodG91Y2hlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRvdWNoZXNbaW5kZXhdLmNsaWVudFkgLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi50b3A7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRldGVjdFRvdWNoU2NyZWVuKCkge1xuICAgICAgICB2YXIgcHJlZml4ZXMgPSAnIC13ZWJraXQtIC1tb3otIC1vLSAtbXMtICcuc3BsaXQoJyAnKTtcbiAgICAgICAgdmFyIG1xID0gZnVuY3Rpb24ocXVlcnk6IGFueSkge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5KS5tYXRjaGVzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCgnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGluY2x1ZGUgdGhlICdoZWFydHonIGFzIGEgd2F5IHRvIGhhdmUgYSBub24gbWF0Y2hpbmcgTVEgdG8gaGVscCB0ZXJtaW5hdGUgdGhlIGpvaW5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXQuaW8vdnpuRkhcbiAgICAgICAgdmFyIHF1ZXJ5ID0gWycoJywgcHJlZml4ZXMuam9pbigndG91Y2gtZW5hYmxlZCksKCcpLCAnaGVhcnR6JywgJyknXS5qb2luKCcnKTtcbiAgICAgICAgcmV0dXJuIG1xKHF1ZXJ5KTtcbiAgICB9XG5cblxuICAgIC8qIFB1YmxpYyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzICovXG4gICAgb24oZXZlbnQ6IEV2ZW50VHlwZSwgaGFuZGxlcjogRnVuY3Rpb24pIHtcbiAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50XSA9IGhhbmRsZXI7XG4gICAgICAgIH1cbiAgICB9XG59Il19