/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
// tslint:disable:max-file-line-count
/***
* pause (not yet supported) (?string='hover') - event group name which pauses
* the cycling of the carousel, if hover pauses on mouseenter and resumes on
* mouseleave keyboard (not yet supported) (?boolean=true) - if false
* carousel will not react to keyboard events
* note: swiping not yet supported
*/
/****
* Problems:
* 1) if we set an active slide via model changes, .active class remains on a
* current slide.
* 2) if we have only one slide, we shouldn't show prev/next nav buttons
* 3) if first or last slide is active and noWrap is true, there should be
* "disabled" class on the nav buttons.
* 4) default interval should be equal 5000
*/
import { Component, EventEmitter, Input, NgZone, Output } from '@angular/core';
import { isBs3, LinkedList } from 'ngx-bootstrap/utils';
import { CarouselConfig } from './carousel.config';
import { findLastIndex, chunkByNumber } from './utils';
/** @enum {number} */
var Direction = {
UNKNOWN: 0,
NEXT: 1,
PREV: 2,
};
export { Direction };
Direction[Direction.UNKNOWN] = 'UNKNOWN';
Direction[Direction.NEXT] = 'NEXT';
Direction[Direction.PREV] = 'PREV';
/**
* Base element to create carousel
*/
var CarouselComponent = /** @class */ (function () {
function CarouselComponent(config, ngZone) {
this.ngZone = ngZone;
/* If `true` - carousel indicators indicate slides chunks
works ONLY if singleSlideOffset = FALSE */
this.indicatorsByChunk = false;
/* If value more then 1 — carousel works in multilist mode */
this.itemsPerSlide = 1;
/* If `true` — carousel shifts by one element. By default carousel shifts by number
of visible elements (itemsPerSlide field) */
this.singleSlideOffset = false;
/**
* Will be emitted when active slide has been changed. Part of two-way-bindable [(activeSlide)] property
*/
this.activeSlideChange = new EventEmitter(false);
/**
* Will be emitted when active slides has been changed in multilist mode
*/
this.slideRangeChange = new EventEmitter();
/* Index to start display slides from it */
this.startFromIndex = 0;
this._slides = new LinkedList();
this._currentVisibleSlidesIndex = 0;
this.destroyed = false;
this.getActive = (/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.active; });
this.makeSlidesConsistent = (/**
* @param {?} slides
* @return {?}
*/
function (slides) {
slides.forEach((/**
* @param {?} slide
* @param {?} index
* @return {?}
*/
function (slide, index) { return slide.item.order = index; }));
});
Object.assign(this, config);
}
Object.defineProperty(CarouselComponent.prototype, "activeSlide", {
get: /**
* @return {?}
*/
function () {
return this._currentActiveSlide;
},
/** Index of currently displayed slide(started for 0) */
set: /**
* Index of currently displayed slide(started for 0)
* @param {?} index
* @return {?}
*/
function (index) {
if (this.multilist) {
return;
}
if (this._slides.length && index !== this._currentActiveSlide) {
this._select(index);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "interval", {
/**
* Delay of item cycling in milliseconds. If false, carousel won't cycle
* automatically.
*/
get: /**
* Delay of item cycling in milliseconds. If false, carousel won't cycle
* automatically.
* @return {?}
*/
function () {
return this._interval;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._interval = value;
this.restartTimer();
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "slides", {
get: /**
* @return {?}
*/
function () {
return this._slides.toArray();
},
enumerable: true,
configurable: true
});
Object.defineProperty(CarouselComponent.prototype, "isBs4", {
get: /**
* @return {?}
*/
function () {
return !isBs3();
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
CarouselComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
setTimeout((/**
* @return {?}
*/
function () {
if (_this.singleSlideOffset) {
_this.indicatorsByChunk = false;
}
if (_this.multilist) {
_this._chunkedSlides = chunkByNumber(_this.mapSlidesAndIndexes(), _this.itemsPerSlide);
_this.selectInitialSlides();
}
}), 0);
};
/**
* @return {?}
*/
CarouselComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroyed = true;
};
/**
* Adds new slide. If this slide is first in collection - set it as active
* and starts auto changing
* @param slide
*/
/**
* Adds new slide. If this slide is first in collection - set it as active
* and starts auto changing
* @param {?} slide
* @return {?}
*/
CarouselComponent.prototype.addSlide = /**
* Adds new slide. If this slide is first in collection - set it as active
* and starts auto changing
* @param {?} slide
* @return {?}
*/
function (slide) {
this._slides.add(slide);
if (this.multilist && this._slides.length <= this.itemsPerSlide) {
slide.active = true;
}
if (!this.multilist && this._slides.length === 1) {
this._currentActiveSlide = undefined;
this.activeSlide = 0;
this.play();
}
if (this.multilist && this._slides.length > this.itemsPerSlide) {
this.play();
}
};
/**
* Removes specified slide. If this slide is active - will roll to another
* slide
* @param slide
*/
/**
* Removes specified slide. If this slide is active - will roll to another
* slide
* @param {?} slide
* @return {?}
*/
CarouselComponent.prototype.removeSlide = /**
* Removes specified slide. If this slide is active - will roll to another
* slide
* @param {?} slide
* @return {?}
*/
function (slide) {
var _this = this;
/** @type {?} */
var remIndex = this._slides.indexOf(slide);
if (this._currentActiveSlide === remIndex) {
// removing of active slide
/** @type {?} */
var nextSlideIndex_1 = void 0;
if (this._slides.length > 1) {
// if this slide last - will roll to first slide, if noWrap flag is
// FALSE or to previous, if noWrap is TRUE in case, if this slide in
// middle of collection, index of next slide is same to removed
nextSlideIndex_1 = !this.isLast(remIndex)
? remIndex
: this.noWrap ? remIndex - 1 : 0;
}
this._slides.remove(remIndex);
// prevents exception with changing some value after checking
setTimeout((/**
* @return {?}
*/
function () {
_this._select(nextSlideIndex_1);
}), 0);
}
else {
this._slides.remove(remIndex);
/** @type {?} */
var currentSlideIndex_1 = this.getCurrentSlideIndex();
setTimeout((/**
* @return {?}
*/
function () {
// after removing, need to actualize index of current active slide
_this._currentActiveSlide = currentSlideIndex_1;
_this.activeSlideChange.emit(_this._currentActiveSlide);
}), 0);
}
};
/**
* @param {?=} force
* @return {?}
*/
CarouselComponent.prototype.nextSlideFromInterval = /**
* @param {?=} force
* @return {?}
*/
function (force) {
if (force === void 0) { force = false; }
this.move(Direction.NEXT, force);
};
/**
* Rolling to next slide
* @param force: {boolean} if true - will ignore noWrap flag
*/
/**
* Rolling to next slide
* @param {?=} force
* @return {?}
*/
CarouselComponent.prototype.nextSlide = /**
* Rolling to next slide
* @param {?=} force
* @return {?}
*/
function (force) {
if (force === void 0) { force = false; }
if (this.isPlaying) {
this.restartTimer();
}
this.move(Direction.NEXT, force);
};
/**
* Rolling to previous slide
* @param force: {boolean} if true - will ignore noWrap flag
*/
/**
* Rolling to previous slide
* @param {?=} force
* @return {?}
*/
CarouselComponent.prototype.previousSlide = /**
* Rolling to previous slide
* @param {?=} force
* @return {?}
*/
function (force) {
if (force === void 0) { force = false; }
if (this.isPlaying) {
this.restartTimer();
}
this.move(Direction.PREV, force);
};
/**
* @return {?}
*/
CarouselComponent.prototype.getFirstVisibleIndex = /**
* @return {?}
*/
function () {
return this.slides.findIndex(this.getActive);
};
/**
* @return {?}
*/
CarouselComponent.prototype.getLastVisibleIndex = /**
* @return {?}
*/
function () {
return findLastIndex(this.slides, this.getActive);
};
/**
* @param {?} direction
* @param {?=} force
* @return {?}
*/
CarouselComponent.prototype.move = /**
* @param {?} direction
* @param {?=} force
* @return {?}
*/
function (direction, force) {
if (force === void 0) { force = false; }
/** @type {?} */
var firstVisibleIndex = this.getFirstVisibleIndex();
/** @type {?} */
var lastVisibleIndex = this.getLastVisibleIndex();
if (this.noWrap) {
if (direction === Direction.NEXT &&
this.isLast(lastVisibleIndex) ||
direction === Direction.PREV &&
firstVisibleIndex === 0) {
return;
}
}
if (!this.multilist) {
this.activeSlide = this.findNextSlideIndex(direction, force);
}
else {
this.moveMultilist(direction);
}
};
/**
* Swith slides by enter, space and arrows keys
* @internal
*/
/**
* Swith slides by enter, space and arrows keys
* \@internal
* @param {?} event
* @return {?}
*/
CarouselComponent.prototype.keydownPress = /**
* Swith slides by enter, space and arrows keys
* \@internal
* @param {?} event
* @return {?}
*/
function (event) {
// tslint:disable-next-line:deprecation
if (event.keyCode === 13 || event.key === 'Enter' || event.keyCode === 32 || event.key === 'Space') {
this.nextSlide();
event.preventDefault();
return;
}
// tslint:disable-next-line:deprecation
if (event.keyCode === 37 || event.key === 'LeftArrow') {
this.previousSlide();
return;
}
// tslint:disable-next-line:deprecation
if (event.keyCode === 39 || event.key === 'RightArrow') {
this.nextSlide();
return;
}
};
/**
* Play on mouse leave
* @internal
*/
/**
* Play on mouse leave
* \@internal
* @return {?}
*/
CarouselComponent.prototype.onMouseLeave = /**
* Play on mouse leave
* \@internal
* @return {?}
*/
function () {
if (!this.pauseOnFocus) {
this.play();
}
};
/**
* Play on mouse up
* @internal
*/
/**
* Play on mouse up
* \@internal
* @return {?}
*/
CarouselComponent.prototype.onMouseUp = /**
* Play on mouse up
* \@internal
* @return {?}
*/
function () {
if (!this.pauseOnFocus) {
this.play();
}
};
/**
* When slides on focus autoplay is stopped(optional)
* @internal
*/
/**
* When slides on focus autoplay is stopped(optional)
* \@internal
* @return {?}
*/
CarouselComponent.prototype.pauseFocusIn = /**
* When slides on focus autoplay is stopped(optional)
* \@internal
* @return {?}
*/
function () {
if (this.pauseOnFocus) {
this.isPlaying = false;
this.resetTimer();
}
};
/**
* When slides out of focus autoplay is started
* @internal
*/
/**
* When slides out of focus autoplay is started
* \@internal
* @return {?}
*/
CarouselComponent.prototype.pauseFocusOut = /**
* When slides out of focus autoplay is started
* \@internal
* @return {?}
*/
function () {
this.play();
};
/**
* Rolling to specified slide
* @param index: {number} index of slide, which must be shown
*/
/**
* Rolling to specified slide
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.selectSlide = /**
* Rolling to specified slide
* @param {?} index
* @return {?}
*/
function (index) {
if (this.isPlaying) {
this.restartTimer();
}
if (!this.multilist) {
this.activeSlide = this.indicatorsByChunk ? index * this.itemsPerSlide : index;
}
else {
this.selectSlideRange(this.indicatorsByChunk ? index * this.itemsPerSlide : index);
}
};
/**
* Starts a auto changing of slides
*/
/**
* Starts a auto changing of slides
* @return {?}
*/
CarouselComponent.prototype.play = /**
* Starts a auto changing of slides
* @return {?}
*/
function () {
if (!this.isPlaying) {
this.isPlaying = true;
this.restartTimer();
}
};
/**
* Stops a auto changing of slides
*/
/**
* Stops a auto changing of slides
* @return {?}
*/
CarouselComponent.prototype.pause = /**
* Stops a auto changing of slides
* @return {?}
*/
function () {
if (!this.noPause) {
this.isPlaying = false;
this.resetTimer();
}
};
/**
* Finds and returns index of currently displayed slide
*/
/**
* Finds and returns index of currently displayed slide
* @return {?}
*/
CarouselComponent.prototype.getCurrentSlideIndex = /**
* Finds and returns index of currently displayed slide
* @return {?}
*/
function () {
return this._slides.findIndex(this.getActive);
};
/**
* Defines, whether the specified index is last in collection
* @param index
*/
/**
* Defines, whether the specified index is last in collection
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.isLast = /**
* Defines, whether the specified index is last in collection
* @param {?} index
* @return {?}
*/
function (index) {
return index + 1 >= this._slides.length;
};
/**
* Defines, whether the specified index is first in collection
* @param index
*/
/**
* Defines, whether the specified index is first in collection
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.isFirst = /**
* Defines, whether the specified index is first in collection
* @param {?} index
* @return {?}
*/
function (index) {
return index === 0;
};
/**
* @return {?}
*/
CarouselComponent.prototype.indicatorsSlides = /**
* @return {?}
*/
function () {
var _this = this;
return this.slides.filter((/**
* @param {?} slide
* @param {?} index
* @return {?}
*/
function (slide, index) { return !_this.indicatorsByChunk || index % _this.itemsPerSlide === 0; }));
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.selectInitialSlides = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var startIndex = this.startFromIndex <= this._slides.length
? this.startFromIndex
: 0;
this.hideSlides();
if (this.singleSlideOffset) {
this._slidesWithIndexes = this.mapSlidesAndIndexes();
if (this._slides.length - startIndex < this.itemsPerSlide) {
/** @type {?} */
var slidesToAppend = this._slidesWithIndexes.slice(0, startIndex);
this._slidesWithIndexes = tslib_1.__spread(this._slidesWithIndexes, slidesToAppend).slice(slidesToAppend.length)
.slice(0, this.itemsPerSlide);
}
else {
this._slidesWithIndexes = this._slidesWithIndexes.slice(startIndex, startIndex + this.itemsPerSlide);
}
this._slidesWithIndexes.forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.item.active = true; }));
this.makeSlidesConsistent(this._slidesWithIndexes);
}
else {
this.selectRangeByNestedIndex(startIndex);
}
this.slideRangeChange.emit(this.getVisibleIndexes());
};
/**
* Defines next slide index, depending of direction
* @param direction: Direction(UNKNOWN|PREV|NEXT)
* @param force: {boolean} if TRUE - will ignore noWrap flag, else will
* return undefined if next slide require wrapping
*/
/**
* Defines next slide index, depending of direction
* @private
* @param {?} direction
* @param {?} force
* @return {?}
*/
CarouselComponent.prototype.findNextSlideIndex = /**
* Defines next slide index, depending of direction
* @private
* @param {?} direction
* @param {?} force
* @return {?}
*/
function (direction, force) {
/** @type {?} */
var nextSlideIndex = 0;
if (!force &&
(this.isLast(this.activeSlide) &&
direction !== Direction.PREV &&
this.noWrap)) {
return undefined;
}
switch (direction) {
case Direction.NEXT:
// if this is last slide, not force, looping is disabled
// and need to going forward - select current slide, as a next
nextSlideIndex = !this.isLast(this._currentActiveSlide)
? this._currentActiveSlide + 1
: !force && this.noWrap ? this._currentActiveSlide : 0;
break;
case Direction.PREV:
// if this is first slide, not force, looping is disabled
// and need to going backward - select current slide, as a next
nextSlideIndex =
this._currentActiveSlide > 0
? this._currentActiveSlide - 1
: !force && this.noWrap
? this._currentActiveSlide
: this._slides.length - 1;
break;
default:
throw new Error('Unknown direction');
}
return nextSlideIndex;
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.mapSlidesAndIndexes = /**
* @private
* @return {?}
*/
function () {
return this.slides
.slice()
.map((/**
* @param {?} slide
* @param {?} index
* @return {?}
*/
function (slide, index) {
return {
index: index,
item: slide
};
}));
};
/**
* @private
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.selectSlideRange = /**
* @private
* @param {?} index
* @return {?}
*/
function (index) {
if (this.isIndexInRange(index)) {
return;
}
this.hideSlides();
if (!this.singleSlideOffset) {
this.selectRangeByNestedIndex(index);
}
else {
/** @type {?} */
var startIndex = this.isIndexOnTheEdges(index)
? index
: index - this.itemsPerSlide + 1;
/** @type {?} */
var endIndex = this.isIndexOnTheEdges(index)
? index + this.itemsPerSlide
: index + 1;
this._slidesWithIndexes = this.mapSlidesAndIndexes().slice(startIndex, endIndex);
this.makeSlidesConsistent(this._slidesWithIndexes);
this._slidesWithIndexes.forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.item.active = true; }));
}
this.slideRangeChange.emit(this.getVisibleIndexes());
};
/**
* @private
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.selectRangeByNestedIndex = /**
* @private
* @param {?} index
* @return {?}
*/
function (index) {
/** @type {?} */
var selectedRange = this._chunkedSlides
.map((/**
* @param {?} slidesList
* @param {?} i
* @return {?}
*/
function (slidesList, i) {
return {
index: i,
list: slidesList
};
}))
.find((/**
* @param {?} slidesList
* @return {?}
*/
function (slidesList) {
return slidesList.list.find((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.index === index; })) !== undefined;
}));
this._currentVisibleSlidesIndex = selectedRange.index;
this._chunkedSlides[selectedRange.index].forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) {
slide.item.active = true;
}));
};
/**
* @private
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.isIndexOnTheEdges = /**
* @private
* @param {?} index
* @return {?}
*/
function (index) {
return (index + 1 - this.itemsPerSlide <= 0 ||
index + this.itemsPerSlide <= this._slides.length);
};
/**
* @private
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype.isIndexInRange = /**
* @private
* @param {?} index
* @return {?}
*/
function (index) {
if (this.singleSlideOffset) {
/** @type {?} */
var visibleIndexes = this._slidesWithIndexes.map((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.index; }));
return visibleIndexes.indexOf(index) >= 0;
}
return (index <= this.getLastVisibleIndex() &&
index >= this.getFirstVisibleIndex());
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.hideSlides = /**
* @private
* @return {?}
*/
function () {
this.slides.forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.active = false; }));
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.isVisibleSlideListLast = /**
* @private
* @return {?}
*/
function () {
return this._currentVisibleSlidesIndex === this._chunkedSlides.length - 1;
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.isVisibleSlideListFirst = /**
* @private
* @return {?}
*/
function () {
return this._currentVisibleSlidesIndex === 0;
};
/**
* @private
* @param {?} direction
* @return {?}
*/
CarouselComponent.prototype.moveSliderByOneItem = /**
* @private
* @param {?} direction
* @return {?}
*/
function (direction) {
/** @type {?} */
var firstVisibleIndex;
/** @type {?} */
var lastVisibleIndex;
/** @type {?} */
var indexToHide;
/** @type {?} */
var indexToShow;
if (this.noWrap) {
firstVisibleIndex = this.getFirstVisibleIndex();
lastVisibleIndex = this.getLastVisibleIndex();
indexToHide = direction === Direction.NEXT
? firstVisibleIndex
: lastVisibleIndex;
indexToShow = direction !== Direction.NEXT
? firstVisibleIndex - 1
: !this.isLast(lastVisibleIndex)
? lastVisibleIndex + 1 : 0;
this._slides.get(indexToHide).active = false;
this._slides.get(indexToShow).active = true;
/** @type {?} */
var slidesToReorder = this.mapSlidesAndIndexes().filter((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.item.active; }));
this.makeSlidesConsistent(slidesToReorder);
this.slideRangeChange.emit(this.getVisibleIndexes());
}
else {
/** @type {?} */
var displayedIndex = void 0;
firstVisibleIndex = this._slidesWithIndexes[0].index;
lastVisibleIndex = this._slidesWithIndexes[this._slidesWithIndexes.length - 1].index;
if (direction === Direction.NEXT) {
this._slidesWithIndexes.shift();
displayedIndex = this.isLast(lastVisibleIndex)
? 0
: lastVisibleIndex + 1;
this._slidesWithIndexes.push({
index: displayedIndex,
item: this._slides.get(displayedIndex)
});
}
else {
this._slidesWithIndexes.pop();
displayedIndex = this.isFirst(firstVisibleIndex)
? this._slides.length - 1
: firstVisibleIndex - 1;
this._slidesWithIndexes = tslib_1.__spread([{
index: displayedIndex,
item: this._slides.get(displayedIndex)
}], this._slidesWithIndexes);
}
this.hideSlides();
this._slidesWithIndexes.forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.item.active = true; }));
this.makeSlidesConsistent(this._slidesWithIndexes);
this.slideRangeChange.emit(this._slidesWithIndexes.map((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.index; })));
}
};
/**
* @private
* @param {?} direction
* @return {?}
*/
CarouselComponent.prototype.moveMultilist = /**
* @private
* @param {?} direction
* @return {?}
*/
function (direction) {
if (this.singleSlideOffset) {
this.moveSliderByOneItem(direction);
}
else {
this.hideSlides();
if (this.noWrap) {
this._currentVisibleSlidesIndex = direction === Direction.NEXT
? this._currentVisibleSlidesIndex + 1
: this._currentVisibleSlidesIndex - 1;
}
else {
if (direction === Direction.NEXT) {
this._currentVisibleSlidesIndex = this.isVisibleSlideListLast()
? 0
: this._currentVisibleSlidesIndex + 1;
}
else {
this._currentVisibleSlidesIndex = this.isVisibleSlideListFirst()
? this._chunkedSlides.length - 1
: this._currentVisibleSlidesIndex - 1;
}
}
this._chunkedSlides[this._currentVisibleSlidesIndex].forEach((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.item.active = true; }));
this.slideRangeChange.emit(this.getVisibleIndexes());
}
};
/**
* @private
* @return {?}
*/
CarouselComponent.prototype.getVisibleIndexes = /**
* @private
* @return {?}
*/
function () {
if (!this.singleSlideOffset) {
return this._chunkedSlides[this._currentVisibleSlidesIndex]
.map((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.index; }));
}
else {
return this._slidesWithIndexes.map((/**
* @param {?} slide
* @return {?}
*/
function (slide) { return slide.index; }));
}
};
/**
* Sets a slide, which specified through index, as active
* @param index
*/
/**
* Sets a slide, which specified through index, as active
* @private
* @param {?} index
* @return {?}
*/
CarouselComponent.prototype._select = /**
* Sets a slide, which specified through index, as active
* @private
* @param {?} index
* @return {?}
*/
function (index) {
if (isNaN(index)) {
this.pause();
return;
}
if (!this.multilist) {
/** @type {?} */
var currentSlide = this._slides.get(this._currentActiveSlide);
if (currentSlide) {
currentSlide.active = false;
}
}
/** @type {?} */
var nextSlide = this._slides.get(index);
if (nextSlide) {
this._currentActiveSlide = index;
nextSlide.active = true;
this.activeSlide = index;
this.activeSlideChange.emit(index);
}
};
/**
* Starts loop of auto changing of slides
*/
/**
* Starts loop of auto changing of slides
* @private
* @return {?}
*/
CarouselComponent.prototype.restartTimer = /**
* Starts loop of auto changing of slides
* @private
* @return {?}
*/
function () {
var _this = this;
this.resetTimer();
/** @type {?} */
var interval = +this.interval;
if (!isNaN(interval) && interval > 0) {
this.currentInterval = this.ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
return setInterval((/**
* @return {?}
*/
function () {
/** @type {?} */
var nInterval = +_this.interval;
_this.ngZone.run((/**
* @return {?}
*/
function () {
if (_this.isPlaying &&
!isNaN(_this.interval) &&
nInterval > 0 &&
_this.slides.length) {
_this.nextSlideFromInterval();
}
else {
_this.pause();
}
}));
}), interval);
}));
}
};
Object.defineProperty(CarouselComponent.prototype, "multilist", {
get: /**
* @return {?}
*/
function () {
return this.itemsPerSlide > 1;
},
enumerable: true,
configurable: true
});
/**
* Stops loop of auto changing of slides
*/
/**
* Stops loop of auto changing of slides
* @private
* @return {?}
*/
CarouselComponent.prototype.resetTimer = /**
* Stops loop of auto changing of slides
* @private
* @return {?}
*/
function () {
if (this.currentInterval) {
clearInterval(this.currentInterval);
this.currentInterval = void 0;
}
};
CarouselComponent.decorators = [
{ type: Component, args: [{
selector: 'carousel',
template: "
\n"
}] }
];
/** @nocollapse */
CarouselComponent.ctorParameters = function () { return [
{ type: CarouselConfig },
{ type: NgZone }
]; };
CarouselComponent.propDecorators = {
noWrap: [{ type: Input }],
noPause: [{ type: Input }],
showIndicators: [{ type: Input }],
pauseOnFocus: [{ type: Input }],
indicatorsByChunk: [{ type: Input }],
itemsPerSlide: [{ type: Input }],
singleSlideOffset: [{ type: Input }],
activeSlideChange: [{ type: Output }],
slideRangeChange: [{ type: Output }],
activeSlide: [{ type: Input }],
startFromIndex: [{ type: Input }],
interval: [{ type: Input }]
};
return CarouselComponent;
}());
export { CarouselComponent };
if (false) {
/** @type {?} */
CarouselComponent.prototype.noWrap;
/** @type {?} */
CarouselComponent.prototype.noPause;
/** @type {?} */
CarouselComponent.prototype.showIndicators;
/** @type {?} */
CarouselComponent.prototype.pauseOnFocus;
/** @type {?} */
CarouselComponent.prototype.indicatorsByChunk;
/** @type {?} */
CarouselComponent.prototype.itemsPerSlide;
/** @type {?} */
CarouselComponent.prototype.singleSlideOffset;
/**
* Will be emitted when active slide has been changed. Part of two-way-bindable [(activeSlide)] property
* @type {?}
*/
CarouselComponent.prototype.activeSlideChange;
/**
* Will be emitted when active slides has been changed in multilist mode
* @type {?}
*/
CarouselComponent.prototype.slideRangeChange;
/** @type {?} */
CarouselComponent.prototype.startFromIndex;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype.currentInterval;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._currentActiveSlide;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._interval;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._slides;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._chunkedSlides;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._slidesWithIndexes;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype._currentVisibleSlidesIndex;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype.isPlaying;
/**
* @type {?}
* @protected
*/
CarouselComponent.prototype.destroyed;
/** @type {?} */
CarouselComponent.prototype.getActive;
/**
* @type {?}
* @private
*/
CarouselComponent.prototype.makeSlidesConsistent;
/**
* @type {?}
* @private
*/
CarouselComponent.prototype.ngZone;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJvb3RzdHJhcC9jYXJvdXNlbC8iLCJzb3VyY2VzIjpbImNhcm91c2VsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLE9BQU8sRUFDTCxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWEsTUFBTSxFQUMxRCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXhELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7O0lBSXJELFVBQU87SUFDUCxPQUFJO0lBQ0osT0FBSTs7Ozs7Ozs7O0FBTU47SUFrRkUsMkJBQVksTUFBc0IsRUFBVSxNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTs7O1FBbkVqRCxzQkFBaUIsR0FBRyxLQUFLLENBQUM7O1FBRTFCLGtCQUFhLEdBQUcsQ0FBQyxDQUFDOzs7UUFHbEIsc0JBQWlCLEdBQUcsS0FBSyxDQUFDOzs7O1FBSW5DLHNCQUFpQixHQUF5QixJQUFJLFlBQVksQ0FBUyxLQUFLLENBQUMsQ0FBQzs7OztRQUkxRSxxQkFBZ0IsR0FBMkIsSUFBSSxZQUFZLEVBQVksQ0FBQzs7UUFtQnhFLG1CQUFjLEdBQUcsQ0FBQyxDQUFDO1FBd0JULFlBQU8sR0FBK0IsSUFBSSxVQUFVLEVBQWtCLENBQUM7UUFHdkUsK0JBQTBCLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLGNBQVMsR0FBRyxLQUFLLENBQUM7UUEwSDVCLGNBQVM7Ozs7UUFBRyxVQUFDLEtBQXFCLElBQUssT0FBQSxLQUFLLENBQUMsTUFBTSxFQUFaLENBQVksRUFBQztRQTRZNUMseUJBQW9COzs7O1FBQUcsVUFBQyxN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O2dCQWhCUSxjQUFjO2dCQUxXLE1BQU07Ozt5QkF3QnJDLEtBQUs7MEJBRUwsS0FBSztpQ0FFTCxLQUFLOytCQUVMLEtBQUs7b0NBR0wsS0FBSztnQ0FFTCxLQUFLO29DQUdMLEtBQUs7b0NBR0wsTUFBTTttQ0FJTixNQUFNOzhCQUlOLEtBQUs7aUNBZUwsS0FBSzsyQkFPTCxLQUFLOztJQTJvQlIsd0JBQUM7Q0FBQSxBQWhzQkQsSUFnc0JDO1NBNXJCWSxpQkFBaUI7OztJQUU1QixtQ0FBeUI7O0lBRXpCLG9DQUEwQjs7SUFFMUIsMkNBQWlDOztJQUVqQyx5Q0FBK0I7O0lBRy9CLDhDQUFtQzs7SUFFbkMsMENBQTJCOztJQUczQiw4Q0FBbUM7Ozs7O0lBR25DLDhDQUMwRTs7Ozs7SUFHMUUsNkNBQ3dFOztJQWtCeEUsMkNBQ21COzs7OztJQXFCbkIsNENBQStCOzs7OztJQUMvQixnREFBc0M7Ozs7O0lBQ3RDLHNDQUE0Qjs7Ozs7SUFDNUIsb0NBQWlGOzs7OztJQUNqRiwyQ0FBNkM7Ozs7O0lBQzdDLCtDQUErQzs7Ozs7SUFDL0MsdURBQXlDOzs7OztJQUN6QyxzQ0FBNkI7Ozs7O0lBQzdCLHNDQUE0Qjs7SUEwSDVCLHNDQUFvRDs7Ozs7SUE0WXBELGlEQUVDOzs7OztJQWxnQm1DLG1DQUFzQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlOm1heC1maWxlLWxpbmUtY291bnRcbi8qKipcbiAqIHBhdXNlIChub3QgeWV0IHN1cHBvcnRlZCkgKD9zdHJpbmc9J2hvdmVyJykgLSBldmVudCBncm91cCBuYW1lIHdoaWNoIHBhdXNlc1xuICogdGhlIGN5Y2xpbmcgb2YgdGhlIGNhcm91c2VsLCBpZiBob3ZlciBwYXVzZXMgb24gbW91c2VlbnRlciBhbmQgcmVzdW1lcyBvblxuICogbW91c2VsZWF2ZSBrZXlib2FyZCAobm90IHlldCBzdXBwb3J0ZWQpICg/Ym9vbGVhbj10cnVlKSAtIGlmIGZhbHNlXG4gKiBjYXJvdXNlbCB3aWxsIG5vdCByZWFjdCB0byBrZXlib2FyZCBldmVudHNcbiAqIG5vdGU6IHN3aXBpbmcgbm90IHlldCBzdXBwb3J0ZWRcbiAqL1xuLyoqKipcbiAqIFByb2JsZW1zOlxuICogMSkgaWYgd2Ugc2V0IGFuIGFjdGl2ZSBzbGlkZSB2aWEgbW9kZWwgY2hhbmdlcywgLmFjdGl2ZSBjbGFzcyByZW1haW5zIG9uIGFcbiAqIGN1cnJlbnQgc2xpZGUuXG4gKiAyKSBpZiB3ZSBoYXZlIG9ubHkgb25lIHNsaWRlLCB3ZSBzaG91bGRuJ3Qgc2hvdyBwcmV2L25leHQgbmF2IGJ1dHRvbnNcbiAqIDMpIGlmIGZpcnN0IG9yIGxhc3Qgc2xpZGUgaXMgYWN0aXZlIGFuZCBub1dyYXAgaXMgdHJ1ZSwgdGhlcmUgc2hvdWxkIGJlXG4gKiBcImRpc2FibGVkXCIgY2xhc3Mgb24gdGhlIG5hdiBidXR0b25zLlxuICogNCkgZGVmYXVsdCBpbnRlcnZhbCBzaG91bGQgYmUgZXF1YWwgNTAwMFxuICovXG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIE91dHB1dCwgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgaXNCczMsIExpbmtlZExpc3QgfSBmcm9tICduZ3gtYm9vdHN0cmFwL3V0aWxzJztcbmltcG9ydCB7IFNsaWRlQ29tcG9uZW50IH0gZnJvbSAnLi9zbGlkZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2Fyb3VzZWxDb25maWcgfSBmcm9tICcuL2Nhcm91c2VsLmNvbmZpZyc7XG5pbXBvcnQgeyBmaW5kTGFzdEluZGV4LCBjaHVua0J5TnVtYmVyIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBTbGlkZVdpdGhJbmRleCwgSW5kZXhlZFNsaWRlTGlzdCB9IGZyb20gJy4vbW9kZWxzJztcblxuZXhwb3J0IGVudW0gRGlyZWN0aW9uIHtcbiAgVU5LTk9XTixcbiAgTkVYVCxcbiAgUFJFVlxufVxuXG4vKipcbiAqIEJhc2UgZWxlbWVudCB0byBjcmVhdGUgY2Fyb3VzZWxcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2Fyb3VzZWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIENhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyogSWYgYHRydWVgIOKAlCBjYXJvdXNlbCB3aWxsIG5vdCBjeWNsZSBjb250aW51b3VzbHkgYW5kIHdpbGwgaGF2ZSBoYXJkIHN0b3BzIChwcmV2ZW50IGxvb3BpbmcpICovXG4gIEBJbnB1dCgpIG5vV3JhcDogYm9vbGVhbjtcbiAgLyogIElmIGB0cnVlYCDigJQgd2lsbCBkaXNhYmxlIHBhdXNpbmcgb24gY2Fyb3VzZWwgbW91c2UgaG92ZXIgKi9cbiAgQElucHV0KCkgbm9QYXVzZTogYm9vbGVhbjtcbiAgLyogIElmIGB0cnVlYCDigJQgY2Fyb3VzZWwtaW5kaWNhdG9ycyBhcmUgdmlzaWJsZSAgKi9cbiAgQElucHV0KCkgc2hvd0luZGljYXRvcnM6IGJvb2xlYW47XG4gIC8qICBJZiBgdHJ1ZWAgLSBhdXRvcGxheSB3aWxsIGJlIHN0b3BwZWQgb24gZm9jdXMgKi9cbiAgQElucHV0KCkgcGF1c2VPbkZvY3VzOiBib29sZWFuO1xuICAvKiBJZiBgdHJ1ZWAgLSBjYXJvdXNlbCBpbmRpY2F0b3JzIGluZGljYXRlIHNsaWRlcyBjaHVua3NcbiAgICAgd29ya3MgT05MWSBpZiBzaW5nbGVTbGlkZU9mZnNldCA9IEZBTFNFICovXG4gIEBJbnB1dCgpIGluZGljYXRvcnNCeUNodW5rID0gZmFsc2U7XG4gIC8qIElmIHZhbHVlIG1vcmUgdGhlbiAxIOKAlCBjYXJvdXNlbCB3b3JrcyBpbiBtdWx0aWxpc3QgbW9kZSAqL1xuICBASW5wdXQoKSBpdGVtc1BlclNsaWRlID0gMTtcbiAgLyogSWYgYHRydWVgIOKAlCBjYXJvdXNlbCBzaGlmdHMgYnkgb25lIGVsZW1lbnQuIEJ5IGRlZmF1bHQgY2Fyb3VzZWwgc2hpZnRzIGJ5IG51bWJlclxuICAgICBvZiB2aXNpYmxlIGVsZW1lbnRzIChpdGVtc1BlclNsaWRlIGZpZWxkKSAqL1xuICBASW5wdXQoKSBzaW5nbGVTbGlkZU9mZnNldCA9IGZhbHNlO1xuXG4gIC8qKiBXaWxsIGJlIGVtaXR0ZWQgd2hlbiBhY3RpdmUgc2xpZGUgaGFzIGJlZW4gY2hhbmdlZC4gUGFydCBvZiB0d28td2F5LWJpbmRhYmxlIFsoYWN0aXZlU2xpZGUpXSBwcm9wZXJ0eSAqL1xuICBAT3V0cHV0KClcbiAgYWN0aXZlU2xpZGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KGZhbHNlKTtcblxuICAvKiogV2lsbCBiZSBlbWl0dGVkIHdoZW4gYWN0aXZlIHNsaWRlcyBoYXMgYmVlbiBjaGFuZ2VkIGluIG11bHRpbGlzdCBtb2RlICovXG4gIEBPdXRwdXQoKVxuICBzbGlkZVJhbmdlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8bnVtYmVyW10+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXJbXT4oKTtcblxuICAvKiogSW5kZXggb2YgY3VycmVudGx5IGRpc3BsYXllZCBzbGlkZShzdGFydGVkIGZvciAwKSAqL1xuICBASW5wdXQoKVxuICBzZXQgYWN0aXZlU2xpZGUoaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLm11bHRpbGlzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5fc2xpZGVzLmxlbmd0aCAmJiBpbmRleCAhPT0gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlKSB7XG4gICAgICB0aGlzLl9zZWxlY3QoaW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhY3RpdmVTbGlkZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGU7XG4gIH1cblxuICAvKiBJbmRleCB0byBzdGFydCBkaXNwbGF5IHNsaWRlcyBmcm9tIGl0ICovXG4gIEBJbnB1dCgpXG4gIHN0YXJ0RnJvbUluZGV4ID0gMDtcblxuICAvKipcbiAgICogRGVsYXkgb2YgaXRlbSBjeWNsaW5nIGluIG1pbGxpc2Vjb25kcy4gSWYgZmFsc2UsIGNhcm91c2VsIHdvbid0IGN5Y2xlXG4gICAqIGF1dG9tYXRpY2FsbHkuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgaW50ZXJ2YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5faW50ZXJ2YWw7XG4gIH1cblxuICBzZXQgaW50ZXJ2YWwodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuX2ludGVydmFsID0gdmFsdWU7XG4gICAgdGhpcy5yZXN0YXJ0VGltZXIoKTtcbiAgfVxuXG4gIGdldCBzbGlkZXMoKTogU2xpZGVDb21wb25lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3NsaWRlcy50b0FycmF5KCk7XG4gIH1cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIHByb3RlY3RlZCBjdXJyZW50SW50ZXJ2YWw6IGFueTtcbiAgcHJvdGVjdGVkIF9jdXJyZW50QWN0aXZlU2xpZGU6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF9pbnRlcnZhbDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX3NsaWRlczogTGlua2VkTGlzdDxTbGlkZUNvbXBvbmVudD4gPSBuZXcgTGlua2VkTGlzdDxTbGlkZUNvbXBvbmVudD4oKTtcbiAgcHJvdGVjdGVkIF9jaHVua2VkU2xpZGVzOiBTbGlkZVdpdGhJbmRleFtdW107XG4gIHByb3RlY3RlZCBfc2xpZGVzV2l0aEluZGV4ZXM6IFNsaWRlV2l0aEluZGV4W107XG4gIHByb3RlY3RlZCBfY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9IDA7XG4gIHByb3RlY3RlZCBpc1BsYXlpbmc6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBkZXN0cm95ZWQgPSBmYWxzZTtcblxuICBnZXQgaXNCczQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFpc0JzMygpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDYXJvdXNlbENvbmZpZywgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29uZmlnKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuaW5kaWNhdG9yc0J5Q2h1bmsgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm11bHRpbGlzdCkge1xuICAgICAgICB0aGlzLl9jaHVua2VkU2xpZGVzID0gY2h1bmtCeU51bWJlcihcbiAgICAgICAgICB0aGlzLm1hcFNsaWRlc0FuZEluZGV4ZXMoKSxcbiAgICAgICAgICB0aGlzLml0ZW1zUGVyU2xpZGVcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zZWxlY3RJbml0aWFsU2xpZGVzKCk7XG4gICAgICB9XG4gICAgfSwgMCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBuZXcgc2xpZGUuIElmIHRoaXMgc2xpZGUgaXMgZmlyc3QgaW4gY29sbGVjdGlvbiAtIHNldCBpdCBhcyBhY3RpdmVcbiAgICogYW5kIHN0YXJ0cyBhdXRvIGNoYW5naW5nXG4gICAqIEBwYXJhbSBzbGlkZVxuICAgKi9cbiAgYWRkU2xpZGUoc2xpZGU6IFNsaWRlQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5fc2xpZGVzLmFkZChzbGlkZSk7XG5cbiAgICBpZiAodGhpcy5tdWx0aWxpc3QgJiYgdGhpcy5fc2xpZGVzLmxlbmd0aCA8PSB0aGlzLml0ZW1zUGVyU2xpZGUpIHtcbiAgICAgIHNsaWRlLmFjdGl2ZSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm11bHRpbGlzdCAmJiB0aGlzLl9zbGlkZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmFjdGl2ZVNsaWRlID0gMDtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm11bHRpbGlzdCAmJiB0aGlzLl9zbGlkZXMubGVuZ3RoID4gdGhpcy5pdGVtc1BlclNsaWRlKSB7XG4gICAgICB0aGlzLnBsYXkoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBzcGVjaWZpZWQgc2xpZGUuIElmIHRoaXMgc2xpZGUgaXMgYWN0aXZlIC0gd2lsbCByb2xsIHRvIGFub3RoZXJcbiAgICogc2xpZGVcbiAgICogQHBhcmFtIHNsaWRlXG4gICAqL1xuICByZW1vdmVTbGlkZShzbGlkZTogU2xpZGVDb21wb25lbnQpOiB2b2lkIHtcbiAgICBjb25zdCByZW1JbmRleCA9IHRoaXMuX3NsaWRlcy5pbmRleE9mKHNsaWRlKTtcblxuICAgIGlmICh0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPT09IHJlbUluZGV4KSB7XG4gICAgICAvLyByZW1vdmluZyBvZiBhY3RpdmUgc2xpZGVcbiAgICAgIGxldCBuZXh0U2xpZGVJbmRleDogbnVtYmVyID0gdm9pZCAwO1xuICAgICAgaWYgKHRoaXMuX3NsaWRlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIGlmIHRoaXMgc2xpZGUgbGFzdCAtIHdpbGwgcm9sbCB0byBmaXJzdCBzbGlkZSwgaWYgbm9XcmFwIGZsYWcgaXNcbiAgICAgICAgLy8gRkFMU0Ugb3IgdG8gcHJldmlvdXMsIGlmIG5vV3JhcCBpcyBUUlVFIGluIGNhc2UsIGlmIHRoaXMgc2xpZGUgaW5cbiAgICAgICAgLy8gbWlkZGxlIG9mIGNvbGxlY3Rpb24sIGluZGV4IG9mIG5leHQgc2xpZGUgaXMgc2FtZSB0byByZW1vdmVkXG4gICAgICAgIG5leHRTbGlkZUluZGV4ID0gIXRoaXMuaXNMYXN0KHJlbUluZGV4KVxuICAgICAgICAgID8gcmVtSW5kZXhcbiAgICAgICAgICA6IHRoaXMubm9XcmFwID8gcmVtSW5kZXggLSAxIDogMDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3NsaWRlcy5yZW1vdmUocmVtSW5kZXgpO1xuXG4gICAgICAvLyBwcmV2ZW50cyBleGNlcHRpb24gd2l0aCBjaGFuZ2luZyBzb21lIHZhbHVlIGFmdGVyIGNoZWNraW5nXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fc2VsZWN0KG5leHRTbGlkZUluZGV4KTtcbiAgICAgIH0sIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zbGlkZXMucmVtb3ZlKHJlbUluZGV4KTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTbGlkZUluZGV4ID0gdGhpcy5nZXRDdXJyZW50U2xpZGVJbmRleCgpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIC8vIGFmdGVyIHJlbW92aW5nLCBuZWVkIHRvIGFjdHVhbGl6ZSBpbmRleCBvZiBjdXJyZW50IGFjdGl2ZSBzbGlkZVxuICAgICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSBjdXJyZW50U2xpZGVJbmRleDtcbiAgICAgICAgdGhpcy5hY3RpdmVTbGlkZUNoYW5nZS5lbWl0KHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH1cblxuICBuZXh0U2xpZGVGcm9tSW50ZXJ2YWwoZm9yY2UgPSBmYWxzZSk6IHZvaWQge1xuICAgIHRoaXMubW92ZShEaXJlY3Rpb24uTkVYVCwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxpbmcgdG8gbmV4dCBzbGlkZVxuICAgKiBAcGFyYW0gZm9yY2U6IHtib29sZWFufSBpZiB0cnVlIC0gd2lsbCBpZ25vcmUgbm9XcmFwIGZsYWdcbiAgICovXG4gIG5leHRTbGlkZShmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgICB0aGlzLm1vdmUoRGlyZWN0aW9uLk5FWFQsIGZvcmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsaW5nIHRvIHByZXZpb3VzIHNsaWRlXG4gICAqIEBwYXJhbSBmb3JjZToge2Jvb2xlYW59IGlmIHRydWUgLSB3aWxsIGlnbm9yZSBub1dyYXAgZmxhZ1xuICAgKi9cbiAgcHJldmlvdXNTbGlkZShmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgICB0aGlzLm1vdmUoRGlyZWN0aW9uLlBSRVYsIGZvcmNlKTtcbiAgfVxuXG4gIGdldEZpcnN0VmlzaWJsZUluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2xpZGVzLmZpbmRJbmRleCh0aGlzLmdldEFjdGl2ZSk7XG4gIH1cblxuICBnZXRMYXN0VmlzaWJsZUluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGZpbmRMYXN0SW5kZXgodGhpcy5zbGlkZXMsIHRoaXMuZ2V0QWN0aXZlKTtcbiAgfVxuXG4gIGdldEFjdGl2ZSA9IChzbGlkZTogU2xpZGVDb21wb25lbnQpID0+IHNsaWRlLmFjdGl2ZTtcblxuICBtb3ZlKGRpcmVjdGlvbjogRGlyZWN0aW9uLCBmb3JjZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgZmlyc3RWaXNpYmxlSW5kZXggPSB0aGlzLmdldEZpcnN0VmlzaWJsZUluZGV4KCk7XG4gICAgY29uc3QgbGFzdFZpc2libGVJbmRleCA9IHRoaXMuZ2V0TGFzdFZpc2libGVJbmRleCgpO1xuXG4gICAgaWYgKHRoaXMubm9XcmFwKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFQgJiZcbiAgICAgICAgdGhpcy5pc0xhc3QobGFzdFZpc2libGVJbmRleCkgfHxcbiAgICAgICAgZGlyZWN0aW9uID09PSBEaXJlY3Rpb24uUFJFViAmJlxuICAgICAgICBmaXJzdFZpc2libGVJbmRleCA9PT0gMFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubXVsdGlsaXN0KSB7XG4gICAgICB0aGlzLmFjdGl2ZVNsaWRlID0gdGhpcy5maW5kTmV4dFNsaWRlSW5kZXgoZGlyZWN0aW9uLCBmb3JjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW92ZU11bHRpbGlzdChkaXJlY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0aCBzbGlkZXMgYnkgZW50ZXIsIHNwYWNlIGFuZCBhcnJvd3Mga2V5c1xuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGtleWRvd25QcmVzcyhldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMyB8fCBldmVudC5rZXkgPT09ICdFbnRlcicgfHwgZXZlbnQua2V5Q29kZSA9PT0gMzIgfHwgZXZlbnQua2V5ID09PSAnU3BhY2UnKSB7XG4gICAgICB0aGlzLm5leHRTbGlkZSgpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzNyB8fCBldmVudC5rZXkgPT09ICdMZWZ0QXJyb3cnKSB7XG4gICAgICB0aGlzLnByZXZpb3VzU2xpZGUoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzOSB8fCBldmVudC5rZXkgPT09ICdSaWdodEFycm93Jykge1xuICAgICAgdGhpcy5uZXh0U2xpZGUoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQbGF5IG9uIG1vdXNlIGxlYXZlXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQbGF5IG9uIG1vdXNlIHVwXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgb25Nb3VzZVVwKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMucGxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuIHNsaWRlcyBvbiBmb2N1cyBhdXRvcGxheSBpcyBzdG9wcGVkKG9wdGlvbmFsKVxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHBhdXNlRm9jdXNJbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wYXVzZU9uRm9jdXMpIHtcbiAgICAgIHRoaXMuaXNQbGF5aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLnJlc2V0VGltZXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2hlbiBzbGlkZXMgb3V0IG9mIGZvY3VzIGF1dG9wbGF5IGlzIHN0YXJ0ZWRcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwYXVzZUZvY3VzT3V0KCk6IHZvaWQge1xuICAgIHRoaXMucGxheSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxpbmcgdG8gc3BlY2lmaWVkIHNsaWRlXG4gICAqIEBwYXJhbSBpbmRleDoge251bWJlcn0gaW5kZXggb2Ygc2xpZGUsIHdoaWNoIG11c3QgYmUgc2hvd25cbiAgICovXG4gIHNlbGVjdFNsaWRlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1BsYXlpbmcpIHtcbiAgICAgIHRoaXMucmVzdGFydFRpbWVyKCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm11bHRpbGlzdCkge1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZSA9IHRoaXMuaW5kaWNhdG9yc0J5Q2h1bmsgPyBpbmRleCAqIHRoaXMuaXRlbXNQZXJTbGlkZSA6IGluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdFNsaWRlUmFuZ2UodGhpcy5pbmRpY2F0b3JzQnlDaHVuayA/IGluZGV4ICogdGhpcy5pdGVtc1BlclNsaWRlIDogaW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydHMgYSBhdXRvIGNoYW5naW5nIG9mIHNsaWRlc1xuICAgKi9cbiAgcGxheSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNQbGF5aW5nKSB7XG4gICAgICB0aGlzLmlzUGxheWluZyA9IHRydWU7XG4gICAgICB0aGlzLnJlc3RhcnRUaW1lcigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBhIGF1dG8gY2hhbmdpbmcgb2Ygc2xpZGVzXG4gICAqL1xuICBwYXVzZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubm9QYXVzZSkge1xuICAgICAgdGhpcy5pc1BsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhbmQgcmV0dXJucyBpbmRleCBvZiBjdXJyZW50bHkgZGlzcGxheWVkIHNsaWRlXG4gICAqL1xuICBnZXRDdXJyZW50U2xpZGVJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9zbGlkZXMuZmluZEluZGV4KHRoaXMuZ2V0QWN0aXZlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzLCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgbGFzdCBpbiBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgaXNMYXN0KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaW5kZXggKyAxID49IHRoaXMuX3NsaWRlcy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lcywgd2hldGhlciB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIGZpcnN0IGluIGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIGluZGV4XG4gICAqL1xuICBpc0ZpcnN0KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaW5kZXggPT09IDA7XG4gIH1cblxuICBpbmRpY2F0b3JzU2xpZGVzKCk6IFNsaWRlQ29tcG9uZW50W10ge1xuICAgIHJldHVybiB0aGlzLnNsaWRlcy5maWx0ZXIoXG4gICAgICAoc2xpZGU6IFNsaWRlQ29tcG9uZW50LCBpbmRleDogbnVtYmVyKSA9PiAhdGhpcy5pbmRpY2F0b3JzQnlDaHVuayB8fCBpbmRleCAlIHRoaXMuaXRlbXNQZXJTbGlkZSA9PT0gMFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdEluaXRpYWxTbGlkZXMoKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMuc3RhcnRGcm9tSW5kZXggPD0gdGhpcy5fc2xpZGVzLmxlbmd0aFxuICAgICAgPyB0aGlzLnN0YXJ0RnJvbUluZGV4XG4gICAgICA6IDA7XG5cbiAgICB0aGlzLmhpZGVTbGlkZXMoKTtcblxuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IHRoaXMubWFwU2xpZGVzQW5kSW5kZXhlcygpO1xuXG4gICAgICBpZiAodGhpcy5fc2xpZGVzLmxlbmd0aCAtIHN0YXJ0SW5kZXggPCB0aGlzLml0ZW1zUGVyU2xpZGUpIHtcbiAgICAgICAgY29uc3Qgc2xpZGVzVG9BcHBlbmQgPSB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5zbGljZSgwLCBzdGFydEluZGV4KTtcblxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyAgPSBbXG4gICAgICAgICAgLi4udGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMsXG4gICAgICAgICAgLi4uc2xpZGVzVG9BcHBlbmRcbiAgICAgICAgXVxuICAgICAgICAgIC5zbGljZShzbGlkZXNUb0FwcGVuZC5sZW5ndGgpXG4gICAgICAgICAgLnNsaWNlKDAsIHRoaXMuaXRlbXNQZXJTbGlkZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLnNsaWNlKFxuICAgICAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICAgICAgc3RhcnRJbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5mb3JFYWNoKChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLml0ZW0uYWN0aXZlID0gdHJ1ZSk7XG4gICAgICB0aGlzLm1ha2VTbGlkZXNDb25zaXN0ZW50KHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RSYW5nZUJ5TmVzdGVkSW5kZXgoc3RhcnRJbmRleCk7XG4gICAgfVxuXG4gICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIG5leHQgc2xpZGUgaW5kZXgsIGRlcGVuZGluZyBvZiBkaXJlY3Rpb25cbiAgICogQHBhcmFtIGRpcmVjdGlvbjogRGlyZWN0aW9uKFVOS05PV058UFJFVnxORVhUKVxuICAgKiBAcGFyYW0gZm9yY2U6IHtib29sZWFufSBpZiBUUlVFIC0gd2lsbCBpZ25vcmUgbm9XcmFwIGZsYWcsIGVsc2Ugd2lsbFxuICAgKiAgIHJldHVybiB1bmRlZmluZWQgaWYgbmV4dCBzbGlkZSByZXF1aXJlIHdyYXBwaW5nXG4gICAqL1xuICBwcml2YXRlIGZpbmROZXh0U2xpZGVJbmRleChkaXJlY3Rpb246IERpcmVjdGlvbiwgZm9yY2U6IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGxldCBuZXh0U2xpZGVJbmRleCA9IDA7XG5cbiAgICBpZiAoXG4gICAgICAhZm9yY2UgJiZcbiAgICAgICh0aGlzLmlzTGFzdCh0aGlzLmFjdGl2ZVNsaWRlKSAmJlxuICAgICAgICBkaXJlY3Rpb24gIT09IERpcmVjdGlvbi5QUkVWICYmXG4gICAgICAgIHRoaXMubm9XcmFwKVxuICAgICkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSBEaXJlY3Rpb24uTkVYVDpcbiAgICAgICAgLy8gaWYgdGhpcyBpcyBsYXN0IHNsaWRlLCBub3QgZm9yY2UsIGxvb3BpbmcgaXMgZGlzYWJsZWRcbiAgICAgICAgLy8gYW5kIG5lZWQgdG8gZ29pbmcgZm9yd2FyZCAtIHNlbGVjdCBjdXJyZW50IHNsaWRlLCBhcyBhIG5leHRcbiAgICAgICAgbmV4dFNsaWRlSW5kZXggPSAhdGhpcy5pc0xhc3QodGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlKVxuICAgICAgICAgID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlICsgMVxuICAgICAgICAgIDogIWZvcmNlICYmIHRoaXMubm9XcmFwID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlIDogMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIERpcmVjdGlvbi5QUkVWOlxuICAgICAgICAvLyBpZiB0aGlzIGlzIGZpcnN0IHNsaWRlLCBub3QgZm9yY2UsIGxvb3BpbmcgaXMgZGlzYWJsZWRcbiAgICAgICAgLy8gYW5kIG5lZWQgdG8gZ29pbmcgYmFja3dhcmQgLSBzZWxlY3QgY3VycmVudCBzbGlkZSwgYXMgYSBuZXh0XG4gICAgICAgIG5leHRTbGlkZUluZGV4ID1cbiAgICAgICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPiAwXG4gICAgICAgICAgICA/IHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSAtIDFcbiAgICAgICAgICAgIDogIWZvcmNlICYmIHRoaXMubm9XcmFwXG4gICAgICAgICAgICAgID8gdGhpcy5fY3VycmVudEFjdGl2ZVNsaWRlXG4gICAgICAgICAgICAgIDogdGhpcy5fc2xpZGVzLmxlbmd0aCAtIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGRpcmVjdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0U2xpZGVJbmRleDtcbiAgfVxuXG4gIHByaXZhdGUgbWFwU2xpZGVzQW5kSW5kZXhlcygpOiBTbGlkZVdpdGhJbmRleFtdIHtcbiAgICByZXR1cm4gdGhpcy5zbGlkZXNcbiAgICAgIC5zbGljZSgpXG4gICAgICAubWFwKChzbGlkZTogU2xpZGVDb21wb25lbnQsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBpdGVtOiBzbGlkZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuXG4gIHByaXZhdGUgc2VsZWN0U2xpZGVSYW5nZShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNJbmRleEluUmFuZ2UoaW5kZXgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICBpZiAoIXRoaXMuc2luZ2xlU2xpZGVPZmZzZXQpIHtcbiAgICAgIHRoaXMuc2VsZWN0UmFuZ2VCeU5lc3RlZEluZGV4KGluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMuaXNJbmRleE9uVGhlRWRnZXMoaW5kZXgpXG4gICAgICAgID8gaW5kZXhcbiAgICAgICAgOiBpbmRleCAtIHRoaXMuaXRlbXNQZXJTbGlkZSArIDE7XG5cbiAgICAgIGNvbnN0IGVuZEluZGV4ID0gdGhpcy5pc0luZGV4T25UaGVFZGdlcyhpbmRleClcbiAgICAgICAgPyBpbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZVxuICAgICAgICA6IGluZGV4ICsgMTtcblxuICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMgPSB0aGlzLm1hcFNsaWRlc0FuZEluZGV4ZXMoKS5zbGljZShzdGFydEluZGV4LCBlbmRJbmRleCk7XG4gICAgICB0aGlzLm1ha2VTbGlkZXNDb25zaXN0ZW50KHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzKTtcblxuICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMuZm9yRWFjaCgoc2xpZGU6IFNsaWRlV2l0aEluZGV4KSA9PiBzbGlkZS5pdGVtLmFjdGl2ZSA9IHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuc2xpZGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuZ2V0VmlzaWJsZUluZGV4ZXMoKSk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdFJhbmdlQnlOZXN0ZWRJbmRleChpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSYW5nZSA9IHRoaXMuX2NodW5rZWRTbGlkZXNcbiAgICAgIC5tYXAoKHNsaWRlc0xpc3QsIGk6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgIGxpc3Q6IHNsaWRlc0xpc3RcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAuZmluZChcbiAgICAgICAgKHNsaWRlc0xpc3Q6IEluZGV4ZWRTbGlkZUxpc3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gc2xpZGVzTGlzdC5saXN0LmZpbmQoc2xpZGUgPT4gc2xpZGUuaW5kZXggPT09IGluZGV4KSAhPT0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9IHNlbGVjdGVkUmFuZ2UuaW5kZXg7XG5cbiAgICB0aGlzLl9jaHVua2VkU2xpZGVzW3NlbGVjdGVkUmFuZ2UuaW5kZXhdLmZvckVhY2goKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4ge1xuICAgICAgc2xpZGUuaXRlbS5hY3RpdmUgPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luZGV4T25UaGVFZGdlcyhpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGluZGV4ICsgMSAtIHRoaXMuaXRlbXNQZXJTbGlkZSA8PSAwIHx8XG4gICAgICBpbmRleCArIHRoaXMuaXRlbXNQZXJTbGlkZSA8PSB0aGlzLl9zbGlkZXMubGVuZ3RoXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNJbmRleEluUmFuZ2UoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICBjb25zdCB2aXNpYmxlSW5kZXhlcyA9IHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLm1hcCgoc2xpZGU6IFNsaWRlV2l0aEluZGV4KSA9PiBzbGlkZS5pbmRleCk7XG5cbiAgICAgIHJldHVybiB2aXNpYmxlSW5kZXhlcy5pbmRleE9mKGluZGV4KSA+PSAwO1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICBpbmRleCA8PSB0aGlzLmdldExhc3RWaXNpYmxlSW5kZXgoKSAmJlxuICAgICAgaW5kZXggPj0gdGhpcy5nZXRGaXJzdFZpc2libGVJbmRleCgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaGlkZVNsaWRlcygpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWRlcy5mb3JFYWNoKChzbGlkZTogU2xpZGVDb21wb25lbnQpID0+IHNsaWRlLmFjdGl2ZSA9IGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNWaXNpYmxlU2xpZGVMaXN0TGFzdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9PT0gdGhpcy5fY2h1bmtlZFNsaWRlcy5sZW5ndGggLSAxO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1Zpc2libGVTbGlkZUxpc3RGaXJzdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCA9PT0gMDtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZVNsaWRlckJ5T25lSXRlbShkaXJlY3Rpb246IERpcmVjdGlvbik6IHZvaWQge1xuICAgIGxldCBmaXJzdFZpc2libGVJbmRleDogbnVtYmVyO1xuICAgIGxldCBsYXN0VmlzaWJsZUluZGV4OiBudW1iZXI7XG4gICAgbGV0IGluZGV4VG9IaWRlOiBudW1iZXI7XG4gICAgbGV0IGluZGV4VG9TaG93OiBudW1iZXI7XG5cbiAgICBpZiAodGhpcy5ub1dyYXApIHtcbiAgICAgIGZpcnN0VmlzaWJsZUluZGV4ID0gdGhpcy5nZXRGaXJzdFZpc2libGVJbmRleCgpO1xuICAgICAgbGFzdFZpc2libGVJbmRleCA9IHRoaXMuZ2V0TGFzdFZpc2libGVJbmRleCgpO1xuXG4gICAgICBpbmRleFRvSGlkZSA9IGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFRcbiAgICAgICAgPyBmaXJzdFZpc2libGVJbmRleFxuICAgICAgICA6IGxhc3RWaXNpYmxlSW5kZXg7XG5cbiAgICAgIGluZGV4VG9TaG93ID0gZGlyZWN0aW9uICE9PSBEaXJlY3Rpb24uTkVYVFxuICAgICAgICA/IGZpcnN0VmlzaWJsZUluZGV4IC0gMVxuICAgICAgICA6ICF0aGlzLmlzTGFzdChsYXN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gbGFzdFZpc2libGVJbmRleCArIDEgOiAwO1xuXG4gICAgICB0aGlzLl9zbGlkZXMuZ2V0KGluZGV4VG9IaWRlKS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3NsaWRlcy5nZXQoaW5kZXhUb1Nob3cpLmFjdGl2ZSA9IHRydWU7XG5cbiAgICAgIGNvbnN0IHNsaWRlc1RvUmVvcmRlciA9IHRoaXMubWFwU2xpZGVzQW5kSW5kZXhlcygpLmZpbHRlcihcbiAgICAgICAgKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaXRlbS5hY3RpdmVcbiAgICAgICk7XG5cbiAgICAgIHRoaXMubWFrZVNsaWRlc0NvbnNpc3RlbnQoc2xpZGVzVG9SZW9yZGVyKTtcblxuICAgICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGRpc3BsYXllZEluZGV4OiBudW1iZXI7XG5cbiAgICAgIGZpcnN0VmlzaWJsZUluZGV4ID0gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXNbMF0uaW5kZXg7XG4gICAgICBsYXN0VmlzaWJsZUluZGV4ID0gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXNbdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMubGVuZ3RoIC0gMV0uaW5kZXg7XG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT09IERpcmVjdGlvbi5ORVhUKSB7XG4gICAgICAgIHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLnNoaWZ0KCk7XG5cbiAgICAgICAgZGlzcGxheWVkSW5kZXggPSB0aGlzLmlzTGFzdChsYXN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gMFxuICAgICAgICAgIDogbGFzdFZpc2libGVJbmRleCArIDE7XG5cbiAgICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAgaW5kZXg6IGRpc3BsYXllZEluZGV4LFxuICAgICAgICAgIGl0ZW06IHRoaXMuX3NsaWRlcy5nZXQoZGlzcGxheWVkSW5kZXgpXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMucG9wKCk7XG4gICAgICAgIGRpc3BsYXllZEluZGV4ID0gdGhpcy5pc0ZpcnN0KGZpcnN0VmlzaWJsZUluZGV4KVxuICAgICAgICAgID8gdGhpcy5fc2xpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICA6IGZpcnN0VmlzaWJsZUluZGV4IC0gMTtcblxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyA9IFt7XG4gICAgICAgICAgaW5kZXg6IGRpc3BsYXllZEluZGV4LFxuICAgICAgICAgIGl0ZW06IHRoaXMuX3NsaWRlcy5nZXQoZGlzcGxheWVkSW5kZXgpXG4gICAgICAgIH0sIC4uLnRoaXMuX3NsaWRlc1dpdGhJbmRleGVzXTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICAgIHRoaXMuX3NsaWRlc1dpdGhJbmRleGVzLmZvckVhY2goc2xpZGUgPT4gc2xpZGUuaXRlbS5hY3RpdmUgPSB0cnVlKTtcblxuICAgICAgdGhpcy5tYWtlU2xpZGVzQ29uc2lzdGVudCh0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcyk7XG5cbiAgICAgIHRoaXMuc2xpZGVSYW5nZUNoYW5nZS5lbWl0KFxuICAgICAgICB0aGlzLl9zbGlkZXNXaXRoSW5kZXhlcy5tYXAoKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaW5kZXgpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFrZVNsaWRlc0NvbnNpc3RlbnQgPSAoc2xpZGVzOiBTbGlkZVdpdGhJbmRleFtdKTogdm9pZCA9PiB7XG4gICAgc2xpZGVzLmZvckVhY2goKHNsaWRlOiBTbGlkZVdpdGhJbmRleCwgaW5kZXg6IG51bWJlcikgPT4gc2xpZGUuaXRlbS5vcmRlciA9IGluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZU11bHRpbGlzdChkaXJlY3Rpb246IERpcmVjdGlvbik6IHZvaWQge1xuICAgIGlmICh0aGlzLnNpbmdsZVNsaWRlT2Zmc2V0KSB7XG4gICAgICB0aGlzLm1vdmVTbGlkZXJCeU9uZUl0ZW0oZGlyZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oaWRlU2xpZGVzKCk7XG5cbiAgICAgIGlmICh0aGlzLm5vV3JhcCkge1xuICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gZGlyZWN0aW9uID09PSBEaXJlY3Rpb24uTkVYVFxuICAgICAgICAgID8gdGhpcy5fY3VycmVudFZpc2libGVTbGlkZXNJbmRleCArIDFcbiAgICAgICAgICA6IHRoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXggLSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gRGlyZWN0aW9uLk5FWFQpIHtcbiAgICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gdGhpcy5pc1Zpc2libGVTbGlkZUxpc3RMYXN0KClcbiAgICAgICAgICAgID8gMFxuICAgICAgICAgICAgOiB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4ID0gdGhpcy5pc1Zpc2libGVTbGlkZUxpc3RGaXJzdCgpXG4gICAgICAgICAgICA/IHRoaXMuX2NodW5rZWRTbGlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgOiB0aGlzLl9jdXJyZW50VmlzaWJsZVNsaWRlc0luZGV4IC0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9jaHVua2VkU2xpZGVzW3RoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXhdLmZvckVhY2goXG4gICAgICAgIChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLml0ZW0uYWN0aXZlID0gdHJ1ZVxuICAgICAgKTtcblxuICAgICAgdGhpcy5zbGlkZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5nZXRWaXNpYmxlSW5kZXhlcygpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFZpc2libGVJbmRleGVzKCk6IG51bWJlcltdIHtcbiAgICBpZiAoIXRoaXMuc2luZ2xlU2xpZGVPZmZzZXQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jaHVua2VkU2xpZGVzW3RoaXMuX2N1cnJlbnRWaXNpYmxlU2xpZGVzSW5kZXhdXG4gICAgICAgIC5tYXAoKHNsaWRlOiBTbGlkZVdpdGhJbmRleCkgPT4gc2xpZGUuaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fc2xpZGVzV2l0aEluZGV4ZXMubWFwKChzbGlkZTogU2xpZGVXaXRoSW5kZXgpID0+IHNsaWRlLmluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHNsaWRlLCB3aGljaCBzcGVjaWZpZWQgdGhyb3VnaCBpbmRleCwgYXMgYWN0aXZlXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgcHJpdmF0ZSBfc2VsZWN0KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoaXNOYU4oaW5kZXgpKSB7XG4gICAgICB0aGlzLnBhdXNlKCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubXVsdGlsaXN0KSB7XG4gICAgICBjb25zdCBjdXJyZW50U2xpZGUgPSB0aGlzLl9zbGlkZXMuZ2V0KHRoaXMuX2N1cnJlbnRBY3RpdmVTbGlkZSk7XG4gICAgICBpZiAoY3VycmVudFNsaWRlKSB7XG4gICAgICAgIGN1cnJlbnRTbGlkZS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBuZXh0U2xpZGUgPSB0aGlzLl9zbGlkZXMuZ2V0KGluZGV4KTtcbiAgICBpZiAobmV4dFNsaWRlKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QWN0aXZlU2xpZGUgPSBpbmRleDtcbiAgICAgIG5leHRTbGlkZS5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZSA9IGluZGV4O1xuICAgICAgdGhpcy5hY3RpdmVTbGlkZUNoYW5nZS5lbWl0KGluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIGxvb3Agb2YgYXV0byBjaGFuZ2luZyBvZiBzbGlkZXNcbiAgICovXG4gIHByaXZhdGUgcmVzdGFydFRpbWVyKCkge1xuICAgIHRoaXMucmVzZXRUaW1lcigpO1xuICAgIGNvbnN0IGludGVydmFsID0gK3RoaXMuaW50ZXJ2YWw7XG4gICAgaWYgKCFpc05hTihpbnRlcnZhbCkgJiYgaW50ZXJ2YWwgPiAwKSB7XG4gICAgICB0aGlzLmN1cnJlbnRJbnRlcnZhbCA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBuSW50ZXJ2YWwgPSArdGhpcy5pbnRlcnZhbDtcbiAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICB0aGlzLmlzUGxheWluZyAmJlxuICAgICAgICAgICAgICAhaXNOYU4odGhpcy5pbnRlcnZhbCkgJiZcbiAgICAgICAgICAgICAgbkludGVydmFsID4gMCAmJlxuICAgICAgICAgICAgICB0aGlzLnNsaWRlcy5sZW5ndGhcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aGlzLm5leHRTbGlkZUZyb21JbnRlcnZhbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBpbnRlcnZhbCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgbXVsdGlsaXN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLml0ZW1zUGVyU2xpZGUgPiAxO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGxvb3Agb2YgYXV0byBjaGFuZ2luZyBvZiBzbGlkZXNcbiAgICovXG4gIHByaXZhdGUgcmVzZXRUaW1lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50SW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jdXJyZW50SW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jdXJyZW50SW50ZXJ2YWwgPSB2b2lkIDA7XG4gICAgfVxuICB9XG59XG4iXX0=