UNPKG

ngx-carousel-ease

Version:

ngx-carousel-ease is a versatile Angular library providing a feature-rich, simple, and performant carousel component. This library supports infinite and responsive mode, mouse and touch event. Attention has been put to accessibility, performance, and frie

271 lines 38.7 kB
import { CommunSlider } from './communSlider'; export class FiniteSlider extends CommunSlider { constructor(carousel, responsive, slideToScroll, LIMIT_AUTO_SLIDE, strechingLimit, autoSlide, animationTimingFn, animationTimingMs, enableMouseDrag, enableTouch, autoPlay, autoPlayInterval, autoPlayAtStart, playDirection, autoplaySlideToScroll, carouselService, cd) { super(carousel, responsive, slideToScroll, LIMIT_AUTO_SLIDE, strechingLimit, autoSlide, animationTimingFn, animationTimingMs, enableMouseDrag, enableTouch, autoPlay, autoPlayInterval, autoPlayAtStart, playDirection, autoplaySlideToScroll, carouselService, cd); this.initProperties(); this.updateProperties(); } initProperties() { this.defineAutoPlayDirection(); super.initProperties(); this.disableAutoPlayBtn(); } /** * In finite carousel, clear autoPlay interval if limits are reached. */ disableAutoPlayBtn() { if (!this.autoPlay) return; this.playButtonDisabled.set(false); // start if (this.currentSlide() === 0 && this.playDirection === 'rtl' && this.currentTranslation() === 0) { this.playButtonDisabled.set(true); this.playActive.set(false); clearInterval(this.autoInterval); } // end if (this.currentSlide() === this.lastWindow && this.playDirection === 'ltr' && this.currentTranslation() <= -this.carousel.maxScrollableContent()) { this.playButtonDisabled.set(true); this.playActive.set(false); clearInterval(this.autoInterval); } if (this.carousel.numberDots() === 1) this.playButtonDisabled.set(true); } /** * Fired at drag start * Instantiate property of the starting drag point on the X axis. Used to compute the translation. * Disabling the transition while applying the transformation because of the attached animation. */ dragStart(event) { super.dragStart(event); this.disableAutoPlayBtn(); } /** * Fired at drag end * If limits reached (start or end), put back to the current slide. Updates previous translation. */ dragStop(event) { if (this.currentEventIsDisabled(event)) return; this.dragging.set(false); this.previousTranslation = this.currentTranslation(); this.autoSlider(); this.disableAutoPlayBtn(); const limit = this.currentTranslation() > 0 || -this.currentTranslation() > this.lastWindowTranslation; if (limit) { this.computeTransformation(this.currentSlide()); } } /** * Fired at dragging * Compute the translation, change the slide number, update the direction. */ dragMove(event) { if (this.currentEventIsDisabled(event)) return; if (!this.dragging()) return; this.currentX = event instanceof MouseEvent ? event.pageX : event.changedTouches[0].pageX; this.setDirection(); this.previousX = this.currentX; this.positionChange = this.currentX - this.startX; this.currentTranslation.set(this.positionChange + this.previousTranslation); // Current translation exceeding start or end limits if (this.strechingEffect()) return; this.applyTranslation(this.currentTranslation()); this.modifyCurrentSlide(); } strechingEffect() { return ((this.currentTranslation() > this.strechingLimit && this.currentSlide() === 0) || this.currentTranslation() < -this.carousel.maxScrollableContent() - this.strechingLimit); } /** * Responsible for changing slide number and updating the limits. * In finite mode, if all slides visible on one window or end of carousel, early return to not trigger change event. */ modifyCurrentSlide() { if (this.endOfCarousel()) return; if (-this.currentTranslation() < this.prevLimit) { this.changeSlideNumber(-1); this.decreaseLimits(); } else if (-this.currentTranslation() >= this.nextLimit) { this.changeSlideNumber(1); this.increaseLimits(); } } endOfCarousel() { return (this.carousel.numberDots() === 1 || (this.currentSlide() === this.lastWindow && this.direction === 'right')); } /** * Auto slide card if option enabled, applied on both directions. * Prevents auto slide on limits in finite mode (if streching < limit auto slide). * If only one slide is displayed (slideToShow === 1), the width of the slide corresponds to the window's width (a dot). Hence, taking the min between the two. * In non responsive and non infinite, there is possibly an offset of the current limit. */ autoSlider() { if (!this.autoSlide) return; if (this.currentTranslation() > 0 || -this.currentTranslation() > this.lastWindowTranslation) { return; } const referenceWidth = Math.min(this.carousel.slideWidth, this.carousel.slideMaxWidth || Infinity); let currentLimit = this.prevLimit + this.carousel.slideWidthWithGap; if (!this.responsive && this.currentSlide() > this.lastWindow - 1) { currentLimit = this.lastWindowTranslation; } // previousTranslation always a negative number, currentLimit always positive const currentPositionChange = this.previousTranslation + currentLimit; const moveComparedToSlide = (currentPositionChange / referenceWidth) * 100; if (moveComparedToSlide < -this.LIMIT_AUTO_SLIDE || moveComparedToSlide > this.LIMIT_AUTO_SLIDE) { if (moveComparedToSlide > this.LIMIT_AUTO_SLIDE) { this.changeSlideNumber(-1); this.decreaseLimits(); } else { this.changeSlideNumber(1); this.increaseLimits(); } } this.computeTransformation(this.accumulatedSlide); } /** * Decrease limit (movement to the left) * Exception: if not responsive (card offset) and finite carousel, the next limit is at the maximum (the end of the carousel) */ decreaseLimits() { super.decreaseLimits(); if (!this.responsive && this.currentSlide() >= this.lastWindow - 1) { this.nextLimit = this.lastWindowTranslation; } this.nextLimit = Math.floor(this.nextLimit); } /** * Increase limit on basis of previous computed limits (movement to the right) * Schema: || previous | current || next * Exception: if not responsive (card offset) and finite carousel, the next limit is at the maximum (the end of the carousel) */ increaseLimits() { super.increaseLimits(); if (!this.responsive && this.currentSlide() >= this.lastWindow - 1) { this.nextLimit = this.lastWindowTranslation; if (this.currentSlide() === this.lastWindow) { // only update previous limit if last slide reached this.prevLimit = Math.floor(this.nextLimit - this.invisibleOffsetCardNotResponsive); } } } /** * Previous button navigation */ prev(slides = this.slideToScroll) { this.direction = 'left'; this.changeSlideNumber(-slides); this.changePrevAndNextLimits(this.accumulatedSlide); this.computeTransformation(this.accumulatedSlide); this.disableAutoPlayBtn(); this.relaunchAutoPlay(); } /** * Relaunch autoPlay if not disabled. * Restart only if started (playActive). Play button disabled when limits reached (finite carousel). */ relaunchAutoPlay() { if (!this.playButtonDisabled() && this.playActive()) { clearInterval(this.autoInterval); this.launchAutoPlay(); } } defineAutoPlayDirection() { if (this.playDirection === 'ltr') { this.directionAutoPlay = this.next.bind(this); } else { this.directionAutoPlay = this.prev.bind(this); } } /** * Next button navigation */ next(slides = this.slideToScroll) { this.direction = 'right'; this.changeSlideNumber(slides); this.changePrevAndNextLimits(this.accumulatedSlide); this.computeTransformation(this.accumulatedSlide); this.disableAutoPlayBtn(); this.relaunchAutoPlay(); } /** * Navigation with bullet points * Update values accordingly. */ goTo(bullet) { const slideHasChanged = this.currentSlide() !== bullet; this.direction = this.currentSlide() < bullet ? 'right' : 'left'; this.currentSlide.set(bullet); this.fireSlideChangeEvent(slideHasChanged, this.currentSlide()); this.disableAutoPlayBtn(); this.relaunchAutoPlay(); this.accumulatedSlide = this.currentSlide(); this.changePrevAndNextLimits(bullet); this.computeTransformation(bullet); } /** * Exception: if only one window (numberDots === 1), update the accumulatedSlide to let the transformation occurs, but currentSlide should stay at 0. */ changeSlideNumber(step) { const slideNumberBeforeChange = this.currentSlide(); this.finiteChangeSlideNumber(step); if (this.carousel.numberDots() === 1) { this.currentSlide.set(0); } const current = this.carousel.numberDots() > 1 ? this.currentSlide() : this.accumulatedSlide; const slideHasChanged = slideNumberBeforeChange !== this.currentSlide(); this.fireSlideChangeEvent(slideHasChanged, current); } finiteChangeSlideNumber(step) { this.currentSlide.update((slide) => slide + step); if (this.currentSlide() > this.lastWindow) { this.currentSlide.set(this.lastWindow); } else if (this.currentSlide() < 0) { this.currentSlide.set(0); } this.accumulatedSlide = this.currentSlide(); } /** * Compute transformation that will be applied on basis of the provided slide number * Exception: if not responsive (card offset) and finite carousel, the next limit is the end of the carousel */ computeTransformation(slide) { let transformation = slide * this.carousel.slideWidthWithGap; if (!this.responsive && slide >= this.lastWindow - 1 && this.carousel.numberDots() > 1) { this.nextLimit = this.lastWindowTranslation; if (slide === this.lastWindow) { // if last window, go to maximum & update prev limit transformation = this.lastWindowTranslation; this.prevLimit = Math.floor(this.nextLimit - this.invisibleOffsetCardNotResponsive); } } this.applyTransformation(transformation); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluaXRlU2xpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY2Fyb3VzZWwvc3JjL2xpYi9maW5pdGVTbGlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE1BQU0sT0FBTyxZQUFhLFNBQVEsWUFBWTtJQUM1QyxZQUNFLFFBQWtCLEVBQ2xCLFVBQW1CLEVBQ25CLGFBQXFCLEVBQ3JCLGdCQUF3QixFQUN4QixjQUFzQixFQUN0QixTQUFrQixFQUNsQixpQkFBeUIsRUFDekIsaUJBQXlCLEVBQ3pCLGVBQXdCLEVBQ3hCLFdBQW9CLEVBQ3BCLFFBQWlCLEVBQ2pCLGdCQUF3QixFQUN4QixlQUF3QixFQUN4QixhQUFxQixFQUNyQixxQkFBNkIsRUFDN0IsZUFBZ0MsRUFDaEMsRUFBcUI7UUFFckIsS0FBSyxDQUNILFFBQVEsRUFDUixVQUFVLEVBQ1YsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixjQUFjLEVBQ2QsU0FBUyxFQUNULGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLFdBQVcsRUFDWCxRQUFRLEVBQ1IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixhQUFhLEVBQ2IscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZixFQUFFLENBQ0gsQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRVEsY0FBYztRQUNyQixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDM0Is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QUFLLElBQUksSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDO1lBQzVCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxFQUM5QixDQUFDO1lBQ0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUM7WUFFNUMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUM5QixvREFBb0Q7Z0JBQ3BELGNBQWMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQ3ZELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUMzQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDYXJvdXNlbCB9IGZyb20gJy4vY2Fyb3VzZWwnO1xyXG5pbXBvcnQgeyBDYXJvdXNlbFNlcnZpY2UgfSBmcm9tICcuL2Nhcm91c2VsLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDb21tdW5TbGlkZXIgfSBmcm9tICcuL2NvbW11blNsaWRlcic7XHJcblxyXG5leHBvcnQgY2xhc3MgRmluaXRlU2xpZGVyIGV4dGVuZHMgQ29tbXVuU2xpZGVyIHtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIGNhcm91c2VsOiBDYXJvdXNlbCxcclxuICAgIHJlc3BvbnNpdmU6IGJvb2xlYW4sXHJcbiAgICBzbGlkZVRvU2Nyb2xsOiBudW1iZXIsXHJcbiAgICBMSU1JVF9BVVRPX1NMSURFOiBudW1iZXIsXHJcbiAgICBzdHJlY2hpbmdMaW1pdDogbnVtYmVyLFxyXG4gICAgYXV0b1NsaWRlOiBib29sZWFuLFxyXG4gICAgYW5pbWF0aW9uVGltaW5nRm46IHN0cmluZyxcclxuICAgIGFuaW1hdGlvblRpbWluZ01zOiBudW1iZXIsXHJcbiAgICBlbmFibGVNb3VzZURyYWc6IGJvb2xlYW4sXHJcbiAgICBlbmFibGVUb3VjaDogYm9vbGVhbixcclxuICAgIGF1dG9QbGF5OiBib29sZWFuLFxyXG4gICAgYXV0b1BsYXlJbnRlcnZhbDogbnVtYmVyLFxyXG4gICAgYXV0b1BsYXlBdFN0YXJ0OiBib29sZWFuLFxyXG4gICAgcGxheURpcmVjdGlvbjogc3RyaW5nLFxyXG4gICAgYXV0b3BsYXlTbGlkZVRvU2Nyb2xsOiBudW1iZXIsXHJcbiAgICBjYXJvdXNlbFNlcnZpY2U6IENhcm91c2VsU2VydmljZSxcclxuICAgIGNkOiBDaGFuZ2VEZXRlY3RvclJlZlxyXG4gICkge1xyXG4gICAgc3VwZXIoXHJcbiAgICAgIGNhcm91c2VsLFxyXG4gICAgICByZXNwb25zaXZlLFxyXG4gICAgICBzbGlkZVRvU2Nyb2xsLFxyXG4gICAgICBMSU1JVF9BVVRPX1NMSURFLFxyXG4gICAgICBzdHJlY2hpbmdMaW1pdCxcclxuICAgICAgYXV0b1NsaWRlLFxyXG4gICAgICBhbmltYXRpb25UaW1pbmdGbixcclxuICAgICAgYW5pbWF0aW9uVGltaW5nTXMsXHJcbiAgICAgIGVuYWJsZU1vdXNlRHJhZyxcclxuICAgICAgZW5hYmxlVG91Y2gsXHJcbiAgICAgIGF1dG9QbGF5LFxyXG4gICAgICBhdXRvUGxheUludGVydmFsLFxyXG4gICAgICBhdXRvUGxheUF0U3RhcnQsXHJcbiAgICAgIHBsYXlEaXJlY3Rpb24sXHJcbiAgICAgIGF1dG9wbGF5U2xpZGVUb1Njcm9sbCxcclxuICAgICAgY2Fyb3VzZWxTZXJ2aWNlLFxyXG4gICAgICBjZFxyXG4gICAgKTtcclxuICAgIHRoaXMuaW5pdFByb3BlcnRpZXMoKTtcclxuICAgIHRoaXMudXBkYXRlUHJvcGVydGllcygpO1xyXG4gIH1cclxuXHJcbiAgb3ZlcnJpZGUgaW5pdFByb3BlcnRpZXMoKSB7XHJcbiAgICB0aGlzLmRlZmluZUF1dG9QbGF5RGlyZWN0aW9uKCk7XHJcbiAgICBzdXBlci5pbml0UHJvcGVydGllcygpO1xyXG4gICAgdGhpcy5kaXNhYmxlQXV0b1BsYXlCdG4oKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluIGZpbml0ZSBjYXJvdXNlbCwgY2xlYXIgYXV0b1BsYXkgaW50ZXJ2YWwgaWYgbGltaXRzIGFyZSByZWFjaGVkLlxyXG4gICAqL1xyXG4gIGRpc2FibGVBdXRvUGxheUJ0bigpIHtcclxuICAgIGlmICghdGhpcy5hdXRvUGxheSkgcmV0dXJuO1xyXG4gICAgdGhpcy5wbGF5QnV0dG9uRGlzYWJsZWQuc2V0KGZhbHNlKTtcclxuXHJcbiAgICAvLyBzdGFydFxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmN1cnJlbnRTbGlkZSgpID09PSAwICYmXHJcbiAgICAgIHRoaXMucGxheURpcmVjdGlvbiA9PT0gJ3J0bCcgJiZcclxuICAgICAgdGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKSA9PT0gMFxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMucGxheUJ1dHRvbkRpc2FibGVkLnNldCh0cnVlKTtcclxuICAgICAgdGhpcy5wbGF5QWN0aXZlLnNldChmYWxzZSk7XHJcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5hdXRvSW50ZXJ2YWwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGVuZFxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmN1cnJlbnRTbGlkZSgpID09PSB0aGlzLmxhc3RXaW5kb3cgJiZcclxuICAgICAgdGhpcy5wbGF5RGlyZWN0aW9uID09PSAnbHRyJyAmJlxyXG4gICAgICB0aGlzLmN1cnJlbnRUcmFuc2xhdGlvbigpIDw9IC10aGlzLmNhcm91c2VsLm1heFNjcm9sbGFibGVDb250ZW50KClcclxuICAgICkge1xyXG4gICAgICB0aGlzLnBsYXlCdXR0b25EaXNhYmxlZC5zZXQodHJ1ZSk7XHJcbiAgICAgIHRoaXMucGxheUFjdGl2ZS5zZXQoZmFsc2UpO1xyXG4gICAgICBjbGVhckludGVydmFsKHRoaXMuYXV0b0ludGVydmFsKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5jYXJvdXNlbC5udW1iZXJEb3RzKCkgPT09IDEpIHRoaXMucGxheUJ1dHRvbkRpc2FibGVkLnNldCh0cnVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVkIGF0IGRyYWcgc3RhcnRcclxuICAgKiBJbnN0YW50aWF0ZSBwcm9wZXJ0eSBvZiB0aGUgc3RhcnRpbmcgZHJhZyBwb2ludCBvbiB0aGUgWCBheGlzLiBVc2VkIHRvIGNvbXB1dGUgdGhlIHRyYW5zbGF0aW9uLlxyXG4gICAqIERpc2FibGluZyB0aGUgdHJhbnNpdGlvbiB3aGlsZSBhcHBseWluZyB0aGUgdHJhbnNmb3JtYXRpb24gYmVjYXVzZSBvZiB0aGUgYXR0YWNoZWQgYW5pbWF0aW9uLlxyXG4gICAqL1xyXG4gIG92ZXJyaWRlIGRyYWdTdGFydChldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcclxuICAgIHN1cGVyLmRyYWdTdGFydChldmVudCk7XHJcbiAgICB0aGlzLmRpc2FibGVBdXRvUGxheUJ0bigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRmlyZWQgYXQgZHJhZyBlbmRcclxuICAgKiBJZiBsaW1pdHMgcmVhY2hlZCAoc3RhcnQgb3IgZW5kKSwgcHV0IGJhY2sgdG8gdGhlIGN1cnJlbnQgc2xpZGUuIFVwZGF0ZXMgcHJldmlvdXMgdHJhbnNsYXRpb24uXHJcbiAgICovXHJcbiAgZHJhZ1N0b3AoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50RXZlbnRJc0Rpc2FibGVkKGV2ZW50KSkgcmV0dXJuO1xyXG4gICAgdGhpcy5kcmFnZ2luZy5zZXQoZmFsc2UpO1xyXG4gICAgdGhpcy5wcmV2aW91c1RyYW5zbGF0aW9uID0gdGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKTtcclxuXHJcbiAgICB0aGlzLmF1dG9TbGlkZXIoKTtcclxuICAgIHRoaXMuZGlzYWJsZUF1dG9QbGF5QnRuKCk7XHJcblxyXG4gICAgY29uc3QgbGltaXQgPVxyXG4gICAgICB0aGlzLmN1cnJlbnRUcmFuc2xhdGlvbigpID4gMCB8fFxyXG4gICAgICAtdGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKSA+IHRoaXMubGFzdFdpbmRvd1RyYW5zbGF0aW9uO1xyXG5cclxuICAgIGlmIChsaW1pdCkge1xyXG4gICAgICB0aGlzLmNvbXB1dGVUcmFuc2Zvcm1hdGlvbih0aGlzLmN1cnJlbnRTbGlkZSgpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVkIGF0IGRyYWdnaW5nXHJcbiAgICogQ29tcHV0ZSB0aGUgdHJhbnNsYXRpb24sIGNoYW5nZSB0aGUgc2xpZGUgbnVtYmVyLCB1cGRhdGUgdGhlIGRpcmVjdGlvbi5cclxuICAgKi9cclxuICBkcmFnTW92ZShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcclxuICAgIGlmICh0aGlzLmN1cnJlbnRFdmVudElzRGlzYWJsZWQoZXZlbnQpKSByZXR1cm47XHJcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcoKSkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuY3VycmVudFggPVxyXG4gICAgICBldmVudCBpbnN0YW5jZW9mIE1vdXNlRXZlbnQgPyBldmVudC5wYWdlWCA6IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYO1xyXG5cclxuICAgIHRoaXMuc2V0RGlyZWN0aW9uKCk7XHJcbiAgICB0aGlzLnByZXZpb3VzWCA9IHRoaXMuY3VycmVudFg7XHJcblxyXG4gICAgdGhpcy5wb3NpdGlvbkNoYW5nZSA9IHRoaXMuY3VycmVudFggLSB0aGlzLnN0YXJ0WDtcclxuICAgIHRoaXMuY3VycmVudFRyYW5zbGF0aW9uLnNldCh0aGlzLnBvc2l0aW9uQ2hhbmdlICsgdGhpcy5wcmV2aW91c1RyYW5zbGF0aW9uKTtcclxuXHJcbiAgICAvLyBDdXJyZW50IHRyYW5zbGF0aW9uIGV4Y2VlZGluZyBzdGFydCBvciBlbmQgbGltaXRzXHJcbiAgICBpZiAodGhpcy5zdHJlY2hpbmdFZmZlY3QoKSkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuYXBwbHlUcmFuc2xhdGlvbih0aGlzLmN1cnJlbnRUcmFuc2xhdGlvbigpKTtcclxuICAgIHRoaXMubW9kaWZ5Q3VycmVudFNsaWRlKCk7XHJcbiAgfVxyXG5cclxuICBzdHJlY2hpbmdFZmZlY3QoKSB7XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICAodGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKSA+IHRoaXMuc3RyZWNoaW5nTGltaXQgJiZcclxuICAgICAgICB0aGlzLmN1cnJlbnRTbGlkZSgpID09PSAwKSB8fFxyXG4gICAgICB0aGlzLmN1cnJlbnRUcmFuc2xhdGlvbigpIDxcclxuICAgICAgICAtdGhpcy5jYXJvdXNlbC5tYXhTY3JvbGxhYmxlQ29udGVudCgpIC0gdGhpcy5zdHJlY2hpbmdMaW1pdFxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc3BvbnNpYmxlIGZvciBjaGFuZ2luZyBzbGlkZSBudW1iZXIgYW5kIHVwZGF0aW5nIHRoZSBsaW1pdHMuXHJcbiAgICogSW4gZmluaXRlIG1vZGUsIGlmIGFsbCBzbGlkZXMgdmlzaWJsZSBvbiBvbmUgd2luZG93IG9yIGVuZCBvZiBjYXJvdXNlbCwgZWFybHkgcmV0dXJuIHRvIG5vdCB0cmlnZ2VyIGNoYW5nZSBldmVudC5cclxuICAgKi9cclxuICBtb2RpZnlDdXJyZW50U2xpZGUoKSB7XHJcbiAgICBpZiAodGhpcy5lbmRPZkNhcm91c2VsKCkpIHJldHVybjtcclxuXHJcbiAgICBpZiAoLXRoaXMuY3VycmVudFRyYW5zbGF0aW9uKCkgPCB0aGlzLnByZXZMaW1pdCkge1xyXG4gICAgICB0aGlzLmNoYW5nZVNsaWRlTnVtYmVyKC0xKTtcclxuICAgICAgdGhpcy5kZWNyZWFzZUxpbWl0cygpO1xyXG4gICAgfSBlbHNlIGlmICgtdGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKSA+PSB0aGlzLm5leHRMaW1pdCkge1xyXG4gICAgICB0aGlzLmNoYW5nZVNsaWRlTnVtYmVyKDEpO1xyXG4gICAgICB0aGlzLmluY3JlYXNlTGltaXRzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBlbmRPZkNhcm91c2VsKCkge1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgdGhpcy5jYXJvdXNlbC5udW1iZXJEb3RzKCkgPT09IDEgfHxcclxuICAgICAgKHRoaXMuY3VycmVudFNsaWRlKCkgPT09IHRoaXMubGFzdFdpbmRvdyAmJiB0aGlzLmRpcmVjdGlvbiA9PT0gJ3JpZ2h0JylcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBdXRvIHNsaWRlIGNhcmQgaWYgb3B0aW9uIGVuYWJsZWQsIGFwcGxpZWQgb24gYm90aCBkaXJlY3Rpb25zLlxyXG4gICAqIFByZXZlbnRzIGF1dG8gc2xpZGUgb24gbGltaXRzIGluIGZpbml0ZSBtb2RlIChpZiBzdHJlY2hpbmcgPCBsaW1pdCBhdXRvIHNsaWRlKS5cclxuICAgKiBJZiBvbmx5IG9uZSBzbGlkZSBpcyBkaXNwbGF5ZWQgKHNsaWRlVG9TaG93ID09PSAxKSwgdGhlIHdpZHRoIG9mIHRoZSBzbGlkZSBjb3JyZXNwb25kcyB0byB0aGUgd2luZG93J3Mgd2lkdGggKGEgZG90KS4gSGVuY2UsIHRha2luZyB0aGUgbWluIGJldHdlZW4gdGhlIHR3by5cclxuICAgKiBJbiBub24gcmVzcG9uc2l2ZSBhbmQgbm9uIGluZmluaXRlLCB0aGVyZSBpcyBwb3NzaWJseSBhbiBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgbGltaXQuXHJcbiAgICovXHJcbiAgYXV0b1NsaWRlcigpIHtcclxuICAgIGlmICghdGhpcy5hdXRvU2xpZGUpIHJldHVybjtcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5jdXJyZW50VHJhbnNsYXRpb24oKSA+IDAgfHxcclxuICAgICAgLXRoaXMuY3VycmVudFRyYW5zbGF0aW9uKCkgPiB0aGlzLmxhc3RXaW5kb3dUcmFuc2xhdGlvblxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZWZlcmVuY2VXaWR0aCA9IE1hdGgubWluKFxyXG4gICAgICB0aGlzLmNhcm91c2VsLnNsaWRlV2lkdGgsXHJcbiAgICAgIHRoaXMuY2Fyb3VzZWwuc2xpZGVNYXhXaWR0aCB8fCBJbmZpbml0eVxyXG4gICAgKTtcclxuICAgIGxldCBjdXJyZW50TGltaXQgPSB0aGlzLnByZXZMaW1pdCArIHRoaXMuY2Fyb3VzZWwuc2xpZGVXaWR0aFdpdGhHYXA7XHJcblxyXG4gICAgaWYgKCF0aGlzLnJlc3BvbnNpdmUgJiYgdGhpcy5jdXJyZW50U2xpZGUoKSA+IHRoaXMubGFzdFdpbmRvdyAtIDEpIHtcclxuICAgICAgY3VycmVudExpbWl0ID0gdGhpcy5sYXN0V2luZG93VHJhbnNsYXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcHJldmlvdXNUcmFuc2xhdGlvbiBhbHdheXMgYSBuZWdhdGl2ZSBudW1iZXIsIGN1cnJlbnRMaW1pdCBhbHdheXMgcG9zaXRpdmVcclxuICAgIGNvbnN0IGN1cnJlbnRQb3NpdGlvbkNoYW5nZSA9IHRoaXMucHJldmlvdXNUcmFuc2xhdGlvbiArIGN1cnJlbnRMaW1pdDtcclxuICAgIGNvbnN0IG1vdmVDb21wYXJlZFRvU2xpZGUgPSAoY3VycmVudFBvc2l0aW9uQ2hhbmdlIC8gcmVmZXJlbmNlV2lkdGgpICogMTAwO1xyXG5cclxuICAgIGlmIChcclxuICAgICAgbW92ZUNvbXBhcmVkVG9TbGlkZSA8IC10aGlzLkxJTUlUX0FVVE9fU0xJREUgfHxcclxuICAgICAgbW92ZUNvbXBhcmVkVG9TbGlkZSA+IHRoaXMuTElNSVRfQVVUT19TTElERVxyXG4gICAgKSB7XHJcbiAgICAgIGlmIChtb3ZlQ29tcGFyZWRUb1NsaWRlID4gdGhpcy5MSU1JVF9BVVRPX1NMSURFKSB7XHJcbiAgICAgICAgdGhpcy5jaGFuZ2VTbGlkZU51bWJlcigtMSk7XHJcbiAgICAgICAgdGhpcy5kZWNyZWFzZUxpbWl0cygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY2hhbmdlU2xpZGVOdW1iZXIoMSk7XHJcbiAgICAgICAgdGhpcy5pbmNyZWFzZUxpbWl0cygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jb21wdXRlVHJhbnNmb3JtYXRpb24odGhpcy5hY2N1bXVsYXRlZFNsaWRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlY3JlYXNlIGxpbWl0IChtb3ZlbWVudCB0byB0aGUgbGVmdClcclxuICAgKiBFeGNlcHRpb246IGlmIG5vdCByZXNwb25zaXZlIChjYXJkIG9mZnNldCkgYW5kIGZpbml0ZSBjYXJvdXNlbCwgdGhlIG5leHQgbGltaXQgaXMgYXQgdGhlIG1heGltdW0gKHRoZSBlbmQgb2YgdGhlIGNhcm91c2VsKVxyXG4gICAqL1xyXG4gIG92ZXJyaWRlIGRlY3JlYXNlTGltaXRzKCkge1xyXG4gICAgc3VwZXIuZGVjcmVhc2VMaW1pdHMoKTtcclxuXHJcbiAgICBpZiAoIXRoaXMucmVzcG9uc2l2ZSAmJiB0aGlzLmN1cnJlbnRTbGlkZSgpID49IHRoaXMubGFzdFdpbmRvdyAtIDEpIHtcclxuICAgICAgdGhpcy5uZXh0TGltaXQgPSB0aGlzLmxhc3RXaW5kb3dUcmFuc2xhdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm5leHRMaW1pdCA9IE1hdGguZmxvb3IodGhpcy5uZXh0TGltaXQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5jcmVhc2UgbGltaXQgb24gYmFzaXMgb2YgcHJldmlvdXMgY29tcHV0ZWQgbGltaXRzIChtb3ZlbWVudCB0byB0aGUgcmlnaHQpXHJcbiAgICogU2NoZW1hOiB8fCBwcmV2aW91cyB8IGN1cnJlbnQgfHwgbmV4dFxyXG4gICAqIEV4Y2VwdGlvbjogaWYgbm90IHJlc3BvbnNpdmUgKGNhcmQgb2Zmc2V0KSBhbmQgZmluaXRlIGNhcm91c2VsLCB0aGUgbmV4dCBsaW1pdCBpcyBhdCB0aGUgbWF4aW11bSAodGhlIGVuZCBvZiB0aGUgY2Fyb3VzZWwpXHJcbiAgICovXHJcbiAgb3ZlcnJpZGUgaW5jcmVhc2VMaW1pdHMoKSB7XHJcbiAgICBzdXBlci5pbmNyZWFzZUxpbWl0cygpO1xyXG5cclxuICAgIGlmICghdGhpcy5yZXNwb25zaXZlICYmIHRoaXMuY3VycmVudFNsaWRlKCkgPj0gdGhpcy5sYXN0V2luZG93IC0gMSkge1xyXG4gICAgICB0aGlzLm5leHRMaW1pdCA9IHRoaXMubGFzdFdpbmRvd1RyYW5zbGF0aW9uO1xyXG5cclxuICAgICAgaWYgKHRoaXMuY3VycmVudFNsaWRlKCkgPT09IHRoaXMubGFzdFdpbmRvdykge1xyXG4gICAgICAgIC8vIG9ubHkgdXBkYXRlIHByZXZpb3VzIGxpbWl0IGlmIGxhc3Qgc2xpZGUgcmVhY2hlZFxyXG4gICAgICAgIHRoaXMucHJldkxpbWl0ID0gTWF0aC5mbG9vcihcclxuICAgICAgICAgIHRoaXMubmV4dExpbWl0IC0gdGhpcy5pbnZpc2libGVPZmZzZXRDYXJkTm90UmVzcG9uc2l2ZVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFByZXZpb3VzIGJ1dHRvbiBuYXZpZ2F0aW9uXHJcbiAgICovXHJcbiAgcHJldihzbGlkZXMgPSB0aGlzLnNsaWRlVG9TY3JvbGwpIHtcclxuICAgIHRoaXMuZGlyZWN0aW9uID0gJ2xlZnQnO1xyXG5cclxuICAgIHRoaXMuY2hhbmdlU2xpZGVOdW1iZXIoLXNsaWRlcyk7XHJcbiAgICB0aGlzLmNoYW5nZVByZXZBbmROZXh0TGltaXRzKHRoaXMuYWNjdW11bGF0ZWRTbGlkZSk7XHJcbiAgICB0aGlzLmNvbXB1dGVUcmFuc2Zvcm1hdGlvbih0aGlzLmFjY3VtdWxhdGVkU2xpZGUpO1xyXG4gICAgdGhpcy5kaXNhYmxlQXV0b1BsYXlCdG4oKTtcclxuICAgIHRoaXMucmVsYXVuY2hBdXRvUGxheSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVsYXVuY2ggYXV0b1BsYXkgaWYgbm90IGRpc2FibGVkLlxyXG4gICAqIFJlc3RhcnQgb25seSBpZiBzdGFydGVkIChwbGF5QWN0aXZlKS4gUGxheSBidXR0b24gZGlzYWJsZWQgd2hlbiBsaW1pdHMgcmVhY2hlZCAoZmluaXRlIGNhcm91c2VsKS5cclxuICAgKi9cclxuICByZWxhdW5jaEF1dG9QbGF5KCkge1xyXG4gICAgaWYgKCF0aGlzLnBsYXlCdXR0b25EaXNhYmxlZCgpICYmIHRoaXMucGxheUFjdGl2ZSgpKSB7XHJcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5hdXRvSW50ZXJ2YWwpO1xyXG4gICAgICB0aGlzLmxhdW5jaEF1dG9QbGF5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBkZWZpbmVBdXRvUGxheURpcmVjdGlvbigpIHtcclxuICAgIGlmICh0aGlzLnBsYXlEaXJlY3Rpb24gPT09ICdsdHInKSB7XHJcbiAgICAgIHRoaXMuZGlyZWN0aW9uQXV0b1BsYXkgPSB0aGlzLm5leHQuYmluZCh0aGlzKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGlyZWN0aW9uQXV0b1BsYXkgPSB0aGlzLnByZXYuYmluZCh0aGlzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE5leHQgYnV0dG9uIG5hdmlnYXRpb25cclxuICAgKi9cclxuICBuZXh0KHNsaWRlcyA9IHRoaXMuc2xpZGVUb1Njcm9sbCkge1xyXG4gICAgdGhpcy5kaXJlY3Rpb24gPSAncmlnaHQnO1xyXG5cclxuICAgIHRoaXMuY2hhbmdlU2xpZGVOdW1iZXIoc2xpZGVzKTtcclxuICAgIHRoaXMuY2hhbmdlUHJldkFuZE5leHRMaW1pdHModGhpcy5hY2N1bXVsYXRlZFNsaWRlKTtcclxuICAgIHRoaXMuY29tcHV0ZVRyYW5zZm9ybWF0aW9uKHRoaXMuYWNjdW11bGF0ZWRTbGlkZSk7XHJcbiAgICB0aGlzLmRpc2FibGVBdXRvUGxheUJ0bigpO1xyXG4gICAgdGhpcy5yZWxhdW5jaEF1dG9QbGF5KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBOYXZpZ2F0aW9uIHdpdGggYnVsbGV0IHBvaW50c1xyXG4gICAqIFVwZGF0ZSB2YWx1ZXMgYWNjb3JkaW5nbHkuXHJcbiAgICovXHJcbiAgZ29UbyhidWxsZXQ6IG51bWJlcikge1xyXG4gICAgY29uc3Qgc2xpZGVIYXNDaGFuZ2VkID0gdGhpcy5jdXJyZW50U2xpZGUoKSAhPT0gYnVsbGV0O1xyXG4gICAgdGhpcy5kaXJlY3Rpb24gPSB0aGlzLmN1cnJlbnRTbGlkZSgpIDwgYnVsbGV0ID8gJ3JpZ2h0JyA6ICdsZWZ0JztcclxuXHJcbiAgICB0aGlzLmN1cnJlbnRTbGlkZS5zZXQoYnVsbGV0KTtcclxuICAgIHRoaXMuZmlyZVNsaWRlQ2hhbmdlRXZlbnQoc2xpZGVIYXNDaGFuZ2VkLCB0aGlzLmN1cnJlbnRTbGlkZSgpKTtcclxuXHJcbiAgICB0aGlzLmRpc2FibGVBdXRvUGxheUJ0bigpO1xyXG4gICAgdGhpcy5yZWxhdW5jaEF1dG9QbGF5KCk7XHJcblxyXG4gICAgdGhpcy5hY2N1bXVsYXRlZFNsaWRlID0gdGhpcy5jdXJyZW50U2xpZGUoKTtcclxuICAgIHRoaXMuY2hhbmdlUHJldkFuZE5leHRMaW1pdHMoYnVsbGV0KTtcclxuICAgIHRoaXMuY29tcHV0ZVRyYW5zZm9ybWF0aW9uKGJ1bGxldCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeGNlcHRpb246IGlmIG9ubHkgb25lIHdpbmRvdyAobnVtYmVyRG90cyA9PT0gMSksIHVwZGF0ZSB0aGUgYWNjdW11bGF0ZWRTbGlkZSB0byBsZXQgdGhlIHRyYW5zZm9ybWF0aW9uIG9jY3VycywgYnV0IGN1cnJlbnRTbGlkZSBzaG91bGQgc3RheSBhdCAwLlxyXG4gICAqL1xyXG4gIGNoYW5nZVNsaWRlTnVtYmVyKHN0ZXA6IG51bWJlcikge1xyXG4gICAgY29uc3Qgc2xpZGVOdW1iZXJCZWZvcmVDaGFuZ2UgPSB0aGlzLmN1cnJlbnRTbGlkZSgpO1xyXG5cclxuICAgIHRoaXMuZmluaXRlQ2hhbmdlU2xpZGVOdW1iZXIoc3RlcCk7XHJcblxyXG4gICAgaWYgKHRoaXMuY2Fyb3VzZWwubnVtYmVyRG90cygpID09PSAxKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudFNsaWRlLnNldCgwKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjdXJyZW50ID1cclxuICAgICAgdGhpcy5jYXJvdXNlbC5udW1iZXJEb3RzKCkgPiAxXHJcbiAgICAgICAgPyB0aGlzLmN1cnJlbnRTbGlkZSgpXHJcbiAgICAgICAgOiB0aGlzLmFjY3VtdWxhdGVkU2xpZGU7XHJcblxyXG4gICAgY29uc3Qgc2xpZGVIYXNDaGFuZ2VkID0gc2xpZGVOdW1iZXJCZWZvcmVDaGFuZ2UgIT09IHRoaXMuY3VycmVudFNsaWRlKCk7XHJcblxyXG4gICAgdGhpcy5maXJlU2xpZGVDaGFuZ2VFdmVudChzbGlkZUhhc0NoYW5nZWQsIGN1cnJlbnQpO1xyXG4gIH1cclxuXHJcbiAgZmluaXRlQ2hhbmdlU2xpZGVOdW1iZXIoc3RlcDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRTbGlkZS51cGRhdGUoKHNsaWRlKSA9PiBzbGlkZSArIHN0ZXApO1xyXG5cclxuICAgIGlmICh0aGlzLmN1cnJlbnRTbGlkZSgpID4gdGhpcy5sYXN0V2luZG93KSB7XHJcbiAgICAgIHRoaXMuY3VycmVudFNsaWRlLnNldCh0aGlzLmxhc3RXaW5kb3cpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRTbGlkZSgpIDwgMCkge1xyXG4gICAgICB0aGlzLmN1cnJlbnRTbGlkZS5zZXQoMCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hY2N1bXVsYXRlZFNsaWRlID0gdGhpcy5jdXJyZW50U2xpZGUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbXB1dGUgdHJhbnNmb3JtYXRpb24gdGhhdCB3aWxsIGJlIGFwcGxpZWQgb24gYmFzaXMgb2YgdGhlIHByb3ZpZGVkIHNsaWRlIG51bWJlclxyXG4gICAqIEV4Y2VwdGlvbjogaWYgbm90IHJlc3BvbnNpdmUgKGNhcmQgb2Zmc2V0KSBhbmQgZmluaXRlIGNhcm91c2VsLCB0aGUgbmV4dCBsaW1pdCBpcyB0aGUgZW5kIG9mIHRoZSBjYXJvdXNlbFxyXG4gICAqL1xyXG4gIGNvbXB1dGVUcmFuc2Zvcm1hdGlvbihzbGlkZTogbnVtYmVyKSB7XHJcbiAgICBsZXQgdHJhbnNmb3JtYXRpb24gPSBzbGlkZSAqIHRoaXMuY2Fyb3VzZWwuc2xpZGVXaWR0aFdpdGhHYXA7XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICAhdGhpcy5yZXNwb25zaXZlICYmXHJcbiAgICAgIHNsaWRlID49IHRoaXMubGFzdFdpbmRvdyAtIDEgJiZcclxuICAgICAgdGhpcy5jYXJvdXNlbC5udW1iZXJEb3RzKCkgPiAxXHJcbiAgICApIHtcclxuICAgICAgdGhpcy5uZXh0TGltaXQgPSB0aGlzLmxhc3RXaW5kb3dUcmFuc2xhdGlvbjtcclxuXHJcbiAgICAgIGlmIChzbGlkZSA9PT0gdGhpcy5sYXN0V2luZG93KSB7XHJcbiAgICAgICAgLy8gaWYgbGFzdCB3aW5kb3csIGdvIHRvIG1heGltdW0gJiB1cGRhdGUgcHJldiBsaW1pdFxyXG4gICAgICAgIHRyYW5zZm9ybWF0aW9uID0gdGhpcy5sYXN0V2luZG93VHJhbnNsYXRpb247XHJcbiAgICAgICAgdGhpcy5wcmV2TGltaXQgPSBNYXRoLmZsb29yKFxyXG4gICAgICAgICAgdGhpcy5uZXh0TGltaXQgLSB0aGlzLmludmlzaWJsZU9mZnNldENhcmROb3RSZXNwb25zaXZlXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuYXBwbHlUcmFuc2Zvcm1hdGlvbih0cmFuc2Zvcm1hdGlvbik7XHJcbiAgfVxyXG59XHJcbiJdfQ==