UNPKG

ngx-pinch-zoom

Version:
326 lines 42.5 kB
export class Touches { 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); } }; /* 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'); } 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; } 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], 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", {}); } else { this.runHandler("longtap", {}); } } } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG91Y2hlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1waW5jaC16b29tL3NyYy9saWIvdG91Y2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFhQSxNQUFNLE9BQU8sT0FBTztJQTJDaEIsWUFBWSxVQUFzQjtRQXZDbEMsY0FBUyxHQUFjLFNBQVMsQ0FBQztRQUNqQyxhQUFRLEdBQVEsRUFBRSxDQUFDO1FBQ25CLFdBQU0sR0FBRyxDQUFDLENBQUM7UUFDWCxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUVaLHdCQUFtQixHQUFHLEdBQUcsQ0FBQztRQUMxQixrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUNwQixtQkFBYyxHQUFHLENBQUMsQ0FBQztRQUNuQixNQUFDLEdBQVcsQ0FBQyxDQUFDO1FBQ2QsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFcEIsb0JBQWUsR0FBUTtZQUNuQixZQUFZLEVBQUUsa0JBQWtCO1lBQ2hDLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsVUFBVSxFQUFFLGdCQUFnQjtTQUMvQixDQUFBO1FBQ0Qsb0JBQWUsR0FBUTtZQUNuQixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsU0FBUyxFQUFFLGVBQWU7WUFDMUIsT0FBTyxFQUFFLGFBQWE7U0FDekIsQ0FBQTtRQUNELG9CQUFlLEdBQVE7WUFDbkIsUUFBUSxFQUFFLGNBQWM7U0FDM0IsQ0FBQTtRQWdGRDs7V0FFRztRQUVILGdCQUFnQjtRQUVoQixxQkFBZ0IsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDakQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBRTNDLElBQUksSUFBSSxDQUFDLFNB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QUMsS0FBZ0IsRUFBRSxPQUFpQjtRQUNsQyxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDO1NBQ2xDO0lBQ0wsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBQcm9wZXJ0aWVzIHtcclxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG4gICAgbGlzdGVuZXJzPzogJ2F1dG8nIHwgJ21vdXNlIGFuZCB0b3VjaCc7XHJcbiAgICB0b3VjaExpc3RlbmVycz86IGFueTtcclxuICAgIG1vdXNlTGlzdGVuZXJzPzogYW55O1xyXG4gICAgb3RoZXJMaXN0ZW5lcnM/OiBhbnk7XHJcbiAgICByZXNpemU/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBFdmVudFR5cGUgPSB1bmRlZmluZWQgfCAndG91Y2hlbmQnIHwgJ3BhbicgfCAncGluY2gnIHwgJ2hvcml6b250YWwtc3dpcGUnIHwgJ3ZlcnRpY2FsLXN3aXBlJyB8ICd0YXAnIHwgJ2xvbmd0YXAnO1xyXG5leHBvcnQgdHlwZSBUb3VjaEhhbmRsZXIgPSAnaGFuZGxlVG91Y2hzdGFydCcgfCAnaGFuZGxlVG91Y2htb3ZlJyB8ICdoYW5kbGVUb3VjaGVuZCc7XHJcbmV4cG9ydCB0eXBlIE1vdXNlSGFuZGxlciA9ICdoYW5kbGVNb3VzZWRvd24nIHwgJ2hhbmRsZU1vdXNlbW92ZScgfCAnaGFuZGxlTW91c2V1cCc7XHJcblxyXG5leHBvcnQgY2xhc3MgVG91Y2hlcyB7XHJcbiAgICBwcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzO1xyXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgICBlbGVtZW50UG9zaXRpb246IENsaWVudFJlY3Q7XHJcbiAgICBldmVudFR5cGU6IEV2ZW50VHlwZSA9IHVuZGVmaW5lZDtcclxuICAgIGhhbmRsZXJzOiBhbnkgPSB7fTtcclxuICAgIHN0YXJ0WCA9IDA7XHJcbiAgICBzdGFydFkgPSAwO1xyXG4gICAgbGFzdFRhcCA9IDA7XHJcbiAgICBkb3VibGVUYXBUaW1lb3V0OiBhbnk7XHJcbiAgICBkb3VibGVUYXBNaW5UaW1lb3V0ID0gMzAwO1xyXG4gICAgdGFwTWluVGltZW91dCA9IDIwMDtcclxuICAgIHRvdWNoc3RhcnRUaW1lID0gMDtcclxuICAgIGk6IG51bWJlciA9IDA7XHJcbiAgICBpc01vdXNlZG93biA9IGZhbHNlO1xyXG5cclxuICAgIF90b3VjaExpc3RlbmVyczogYW55ID0ge1xyXG4gICAgICAgIFwidG91Y2hzdGFydFwiOiBcImhhbmRsZVRvdWNoc3RhcnRcIixcclxuICAgICAgICBcInRvdWNobW92ZVwiOiBcImhhbmRsZVRvdWNobW92ZVwiLFxyXG4gICAgICAgIFwidG91Y2hlbmRcIjogXCJoYW5kbGVUb3VjaGVuZFwiXHJcbiAgICB9XHJcbiAgICBfbW91c2VMaXN0ZW5lcnM6IGFueSA9IHtcclxuICAgICAgICBcIm1vdXNlZG93blwiOiBcImhhbmRsZU1vdXNlZG93blwiLFxyXG4gICAgICAgIFwibW91c2Vtb3ZlXCI6IFwiaGFuZGxlTW91c2Vtb3ZlXCIsXHJcbiAgICAgICAgXCJtb3VzZXVwXCI6IFwiaGFuZGxlTW91c2V1cFwiLFxyXG4gICAgICAgIFwid2hlZWxcIjogXCJoYW5kbGVXaGVlbFwiXHJcbiAgICB9XHJcbiAgICBfb3RoZXJMaXN0ZW5lcnM6IGFueSA9IHtcclxuICAgICAgICBcInJlc2l6ZVwiOiBcImhhbmRsZVJlc2l6ZVwiXHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRvdWNoTGlzdGVuZXJzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnRpZXMudG91Y2hMaXN0ZW5lcnMgPyB0aGlzLnByb3BlcnRpZXMudG91Y2hMaXN0ZW5lcnMgOiB0aGlzLl90b3VjaExpc3RlbmVycztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW91c2VMaXN0ZW5lcnMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllcy5tb3VzZUxpc3RlbmVycyA/IHRoaXMucHJvcGVydGllcy5tb3VzZUxpc3RlbmVycyA6IHRoaXMuX21vdXNlTGlzdGVuZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBvdGhlckxpc3RlbmVycygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzLm90aGVyTGlzdGVuZXJzID8gdGhpcy5wcm9wZXJ0aWVzLm90aGVyTGlzdGVuZXJzIDogdGhpcy5fb3RoZXJMaXN0ZW5lcnM7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJvcGVydGllczogUHJvcGVydGllcykge1xyXG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XHJcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy5wcm9wZXJ0aWVzLmVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5lbGVtZW50UG9zaXRpb24gPSB0aGlzLmdldEVsZW1lbnRQb3NpdGlvbigpO1xyXG5cclxuICAgICAgICB0aGlzLnRvZ2dsZUV2ZW50TGlzdGVuZXJzKCdhZGRFdmVudExpc3RlbmVyJyk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLnRvZ2dsZUV2ZW50TGlzdGVuZXJzKCdyZW1vdmVFdmVudExpc3RlbmVyJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdG9nZ2xlRXZlbnRMaXN0ZW5lcnMoYWN0aW9uOiAnYWRkRXZlbnRMaXN0ZW5lcicgfCAncmVtb3ZlRXZlbnRMaXN0ZW5lcicpIHtcclxuICAgICAgICBsZXQgbGlzdGVuZXJzO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzLmxpc3RlbmVycyA9PT0gJ21vdXNlIGFuZCB0b3VjaCcpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gT2JqZWN0LmFzc2lnbih0aGlzLnRvdWNoTGlzdGVuZXJzLCB0aGlzLm1vdXNlTGlzdGVuZXJzKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSB0aGlzLmRldGVjdFRvdWNoU2NyZWVuKCkgPyB0aGlzLnRvdWNoTGlzdGVuZXJzIDogdGhpcy5tb3VzZUxpc3RlbmVycztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnByb3BlcnRpZXMucmVzaXplKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IE9iamVjdC5hc3NpZ24obGlzdGVuZXJzLCB0aGlzLm90aGVyTGlzdGVuZXJzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAodmFyIGxpc3RlbmVyIGluIGxpc3RlbmVycykge1xyXG4gICAgICAgICAgICBjb25zdCBoYW5kbGVyOiBNb3VzZUhhbmRsZXIgPSBsaXN0ZW5lcnNbbGlzdGVuZXJdO1xyXG5cclxuICAgICAgICAgICAgLy8gV2luZG93XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lciA9PT0gXCJyZXNpemVcIikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2FkZEV2ZW50TGlzdGVuZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIobGlzdGVuZXIsIHRoaXNbaGFuZGxlcl0sIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdyZW1vdmVFdmVudExpc3RlbmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKGxpc3RlbmVyLCB0aGlzW2hhbmRsZXJdLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERvY3VtZW50XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgPT09ICdtb3VzZXVwJyB8fCBsaXN0ZW5lciA9PT0gXCJtb3VzZW1vdmVcIikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2FkZEV2ZW50TGlzdGVuZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ3JlbW92ZUV2ZW50TGlzdGVuZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBFbGVtZW50XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAnYWRkRXZlbnRMaXN0ZW5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ3JlbW92ZUV2ZW50TGlzdGVuZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobGlzdGVuZXIsIHRoaXNbaGFuZGxlcl0sIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhZGRFdmVudExpc3RlbmVycyhsaXN0ZW5lcjogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgaGFuZGxlcjogTW91c2VIYW5kbGVyID0gdGhpcy5fbW91c2VMaXN0ZW5lcnNbbGlzdGVuZXJdO1xyXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKGxpc3RlbmVyLCB0aGlzW2hhbmRsZXJdLCBmYWxzZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMobGlzdGVuZXI6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnN0IGhhbmRsZXI6IE1vdXNlSGFuZGxlciA9IHRoaXMuX21vdXNlTGlzdGVuZXJzW2xpc3RlbmVyXTtcclxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihsaXN0ZW5lciwgdGhpc1toYW5kbGVyXSwgZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qXHJcbiAgICAgKiBMaXN0ZW5lcnNcclxuICAgICAqL1xyXG5cclxuICAgIC8qIFRvdWNoc3RhcnQgKi9cclxuXHJcbiAgICBoYW5kbGVUb3VjaHN0YXJ0ID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLmVsZW1lbnRQb3NpdGlvbiA9IHRoaXMuZ2V0RWxlbWVudFBvc2l0aW9uKCk7XHJcbiAgICAgICAgdGhpcy50b3VjaHN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB0aGlzLmdldFRvdWNoc3RhcnRQb3NpdGlvbihldmVudCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ0b3VjaHN0YXJ0XCIsIGV2ZW50KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyogVG91Y2htb3ZlICovXHJcblxyXG4gICAgaGFuZGxlVG91Y2htb3ZlID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcclxuXHJcbiAgICAgICAgLy8gUGFuXHJcbiAgICAgICAgaWYgKHRoaXMuZGV0ZWN0UGFuKHRvdWNoZXMpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcihcInBhblwiLCBldmVudCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQaW5jaFxyXG4gICAgICAgIGlmICh0aGlzLmRldGVjdFBpbmNoKGV2ZW50KSkge1xyXG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJwaW5jaFwiLCBldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGhhbmRsZUxpbmVhclN3aXBlKGV2ZW50OiBhbnkpIHtcclxuICAgICAgICAvL2V2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgIHRoaXMuaSsrO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pID4gMykge1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9IHRoaXMuZ2V0TGluZWFyU3dpcGVUeXBlKGV2ZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnKSB7XHJcbiAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcignaG9yaXpvbnRhbC1zd2lwZScsIGV2ZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmV2ZW50VHlwZSA9PT0gJ3ZlcnRpY2FsLXN3aXBlJykge1xyXG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoJ3ZlcnRpY2FsLXN3aXBlJywgZXZlbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyogVG91Y2hlbmQgKi9cclxuXHJcbiAgICBoYW5kbGVUb3VjaGVuZCA9IChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgY29uc3QgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XHJcblxyXG4gICAgICAgIC8vIERvdWJsZSBUYXBcclxuICAgICAgICBpZiAodGhpcy5kZXRlY3REb3VibGVUYXAoKSkge1xyXG4gICAgICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJkb3VibGUtdGFwXCIsIGV2ZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFRhcFxyXG4gICAgICAgIHRoaXMuZGV0ZWN0VGFwKCk7XHJcblxyXG4gICAgICAgIHRoaXMucnVuSGFuZGxlcihcInRvdWNoZW5kXCIsIGV2ZW50KTtcclxuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9ICd0b3VjaGVuZCc7XHJcblxyXG4gICAgICAgIGlmICh0b3VjaGVzICYmIHRvdWNoZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRUeXBlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB0aGlzLmkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyogTW91c2Vkb3duICovXHJcblxyXG4gICAgaGFuZGxlTW91c2Vkb3duID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLmlzTW91c2Vkb3duID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmVsZW1lbnRQb3NpdGlvbiA9IHRoaXMuZ2V0RWxlbWVudFBvc2l0aW9uKCk7XHJcbiAgICAgICAgdGhpcy50b3VjaHN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5ldmVudFR5cGUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB0aGlzLmdldE1vdXNlZG93blBvc2l0aW9uKGV2ZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucnVuSGFuZGxlcihcIm1vdXNlZG93blwiLCBldmVudCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qIE1vdXNlbW92ZSAqL1xyXG5cclxuICAgIGhhbmRsZU1vdXNlbW92ZSA9IChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgLy9ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICghdGhpcy5pc01vdXNlZG93bikge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQYW5cclxuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJwYW5cIiwgZXZlbnQpO1xyXG5cclxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcclxuICAgICAgICBzd2l0Y2ggKHRoaXMuZGV0ZWN0TGluZWFyU3dpcGUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJob3Jpem9udGFsLXN3aXBlXCI6XHJcbiAgICAgICAgICAgICAgICBldmVudC5zd2lwZVR5cGUgPSBcImhvcml6b250YWwtc3dpcGVcIjtcclxuICAgICAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcihcImhvcml6b250YWwtc3dpcGVcIiwgZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ2ZXJ0aWNhbC1zd2lwZVwiOlxyXG4gICAgICAgICAgICAgICAgZXZlbnQuc3dpcGVUeXBlID0gXCJ2ZXJ0aWNhbC1zd2lwZVwiO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ydW5IYW5kbGVyKFwidmVydGljYWwtc3dpcGVcIiwgZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMaW5lYXIgc3dpcGVcclxuICAgICAgICBpZiAodGhpcy5kZXRlY3RMaW5lYXJTd2lwZShldmVudCkgfHxcclxuICAgICAgICAgICAgdGhpcy5ldmVudFR5cGUgPT09ICdob3Jpem9udGFsLXN3aXBlJyB8fFxyXG4gICAgICAgICAgICB0aGlzLmV2ZW50VHlwZSA9PT0gJ3ZlcnRpY2FsLXN3aXBlJykge1xyXG5cclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVMaW5lYXJTd2lwZShldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiBNb3VzZXVwICovXHJcblxyXG4gICAgaGFuZGxlTW91c2V1cCA9IChldmVudDogYW55KSA9PiB7XHJcblxyXG4gICAgICAgIC8vIFRhcFxyXG4gICAgICAgIHRoaXMuZGV0ZWN0VGFwKCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNNb3VzZWRvd24gPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJtb3VzZXVwXCIsIGV2ZW50KTtcclxuICAgICAgICB0aGlzLmV2ZW50VHlwZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLmkgPSAwO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiBXaGVlbCAqL1xyXG5cclxuICAgIGhhbmRsZVdoZWVsID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJ3aGVlbFwiLCBldmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyogUmVzaXplICovXHJcblxyXG4gICAgaGFuZGxlUmVzaXplID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLnJ1bkhhbmRsZXIoXCJyZXNpemVcIiwgZXZlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJ1bkhhbmRsZXIoZXZlbnROYW1lOiBhbnksIHJlc3BvbnNlOiBhbnkpIHtcclxuICAgICAgICBpZiAodGhpcy5oYW5kbGVyc1tldmVudE5hbWVdKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlcnNbZXZlbnROYW1lXShyZXNwb25zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKlxyXG4gICAgICogRGV0ZWN0aW9uXHJcbiAgICAgKi9cclxuXHJcbiAgICBkZXRlY3RQYW4odG91Y2hlczogYW55KSB7XHJcbiAgICAgICAgcmV0dXJuIHRvdWNoZXMubGVuZ3RoID09PSAxICYmICF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ3Bhbic7XHJcbiAgICB9XHJcblxyXG4gICAgZGV0ZWN0RG91YmxlVGFwKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV2ZW50VHlwZSAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICBjb25zdCB0YXBMZW5ndGggPSBjdXJyZW50VGltZSAtIHRoaXMubGFzdFRhcDtcclxuXHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZG91YmxlVGFwVGltZW91dCk7XHJcblxyXG4gICAgICAgIGlmICh0YXBMZW5ndGggPCB0aGlzLmRvdWJsZVRhcE1pblRpbWVvdXQgJiYgdGFwTGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmRvdWJsZVRhcFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRvdWJsZVRhcFRpbWVvdXQpO1xyXG4gICAgICAgICAgICB9LCB0aGlzLmRvdWJsZVRhcE1pblRpbWVvdXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxhc3RUYXAgPSBjdXJyZW50VGltZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBkZXRlY3RUYXAoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICAgIGNvbnN0IHRhcExlbmd0aCA9IGN1cnJlbnRUaW1lIC0gdGhpcy50b3VjaHN0YXJ0VGltZTtcclxuXHJcbiAgICAgICAgaWYgKHRhcExlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgaWYgKHRhcExlbmd0aCA8IHRoaXMudGFwTWluVGltZW91dCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ydW5IYW5kbGVyKFwidGFwXCIsIHt9KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucnVuSGFuZGxlcihcImxvbmd0YXBcIiwge30pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGRldGVjdFBpbmNoKGV2ZW50OiBhbnkpIHtcclxuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcclxuICAgICAgICByZXR1cm4gKHRvdWNoZXMubGVuZ3RoID09PSAyICYmIHRoaXMuZXZlbnRUeXBlID09PSB1bmRlZmluZWQpIHx8IHRoaXMuZXZlbnRUeXBlID09PSAncGluY2gnO1xyXG4gICAgfVxyXG5cclxuICAgIGRldGVjdExpbmVhclN3aXBlKGV2ZW50OiBhbnkpIHtcclxuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcclxuXHJcbiAgICAgICAgaWYgKHRvdWNoZXMpIHtcclxuICAgICAgICAgICAgaWYgKHRvdWNoZXMubGVuZ3RoID09PSAxICYmICF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnIHx8IHRoaXMuZXZlbnRUeXBlID09PSAndmVydGljYWwtc3dpcGUnKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRMaW5lYXJTd2lwZVR5cGUoZXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmV2ZW50VHlwZSB8fCB0aGlzLmV2ZW50VHlwZSA9PT0gJ2hvcml6b250YWwtc3dpcGUnIHx8IHRoaXMuZXZlbnRUeXBlID09PSAndmVydGljYWwtc3dpcGUnKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRMaW5lYXJTd2lwZVR5cGUoZXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldExpbmVhclN3aXBlVHlwZShldmVudDogYW55KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZXZlbnRUeXBlICE9PSAnaG9yaXpvbnRhbC1zd2lwZScgJiYgdGhpcy5ldmVudFR5cGUgIT09ICd2ZXJ0aWNhbC1zd2lwZScpIHtcclxuICAgICAgICAgICAgY29uc3QgbW92ZW1lbnRYID0gTWF0aC5hYnModGhpcy5tb3ZlTGVmdCgwLCBldmVudCkgLSB0aGlzLnN0YXJ0WCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1vdmVtZW50WSA9IE1hdGguYWJzKHRoaXMubW92ZVRvcCgwLCBldmVudCkgLSB0aGlzLnN0YXJ0WSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoKG1vdmVtZW50WSAqIDMpID4gbW92ZW1lbnRYKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3ZlcnRpY2FsLXN3aXBlJztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAnaG9yaXpvbnRhbC1zd2lwZSc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudFR5cGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldEVsZW1lbnRQb3NpdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRvdWNoc3RhcnRQb3NpdGlvbihldmVudDogYW55KSB7XHJcbiAgICAgICAgdGhpcy5zdGFydFggPSBldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0O1xyXG4gICAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5lbGVtZW50UG9zaXRpb24udG9wO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE1vdXNlZG93blBvc2l0aW9uKGV2ZW50OiBhbnkpIHtcclxuICAgICAgICB0aGlzLnN0YXJ0WCA9IGV2ZW50LmNsaWVudFggLSB0aGlzLmVsZW1lbnRQb3NpdGlvbi5sZWZ0O1xyXG4gICAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQuY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcDtcclxuICAgIH1cclxuXHJcbiAgICBtb3ZlTGVmdChpbmRleDogYW55LCBldmVudDogYW55KSB7XHJcbiAgICAgICAgY29uc3QgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XHJcblxyXG4gICAgICAgIGlmICh0b3VjaGVzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0b3VjaGVzW2luZGV4XS5jbGllbnRYIC0gdGhpcy5lbGVtZW50UG9zaXRpb24ubGVmdDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuY2xpZW50WCAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLmxlZnQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG1vdmVUb3AoaW5kZXg6IGFueSwgZXZlbnQ6IGFueSkge1xyXG4gICAgICAgIGNvbnN0IHRvdWNoZXMgPSBldmVudC50b3VjaGVzO1xyXG5cclxuICAgICAgICBpZiAodG91Y2hlcykge1xyXG4gICAgICAgICAgICByZXR1cm4gdG91Y2hlc1tpbmRleF0uY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuY2xpZW50WSAtIHRoaXMuZWxlbWVudFBvc2l0aW9uLnRvcDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZGV0ZWN0VG91Y2hTY3JlZW4oKSB7XHJcbiAgICAgICAgdmFyIHByZWZpeGVzID0gJyAtd2Via2l0LSAtbW96LSAtby0gLW1zLSAnLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgdmFyIG1xID0gZnVuY3Rpb24ocXVlcnk6IGFueSkge1xyXG4gICAgICAgICAgICByZXR1cm4gd2luZG93Lm1hdGNoTWVkaWEocXVlcnkpLm1hdGNoZXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBpbmNsdWRlIHRoZSAnaGVhcnR6JyBhcyBhIHdheSB0byBoYXZlIGEgbm9uIG1hdGNoaW5nIE1RIHRvIGhlbHAgdGVybWluYXRlIHRoZSBqb2luXHJcbiAgICAgICAgLy8gaHR0cHM6Ly9naXQuaW8vdnpuRkhcclxuICAgICAgICB2YXIgcXVlcnkgPSBbJygnLCBwcmVmaXhlcy5qb2luKCd0b3VjaC1lbmFibGVkKSwoJyksICdoZWFydHonLCAnKSddLmpvaW4oJycpO1xyXG4gICAgICAgIHJldHVybiBtcShxdWVyeSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qIFB1YmxpYyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzICovXHJcbiAgICBvbihldmVudDogRXZlbnRUeXBlLCBoYW5kbGVyOiBGdW5jdGlvbikge1xyXG4gICAgICAgIGlmIChldmVudCkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZXJzW2V2ZW50XSA9IGhhbmRsZXI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59Il19