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
JavaScript
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==