UNPKG

angular-gallery

Version:

Responsive gallery for Angular with touch screen support.

410 lines 56.3 kB
export class Carousel { constructor(properties) { this.initialPositionX = 0; this.newContainerPositionIndex = 0; // The index of the new position relative to the active index, for example -1 or +1 this.preliminarySlideCounter = 0; this.slideCounter = 0; // Scrolling Index (counter) this.previousSlideCounter = 0; this.isContentImages = true; this.isLazyLoad = true; this.isContainerLocked = false; this.alignCells = "left"; this.initialContainerPosition = 0; this.handleTouchstart = (event) => { this.isTouchstart = true; if (this.isSlideInProgress) { return; } const touches = event.touches; if (touches) { this.startX = touches[0].clientX - this.getCarouselElementPosition()['left']; } else { this.startX = event.clientX - this.getCarouselElementPosition()['left']; } this.containerInitialPositionX = this.getElementPosition()['left'] - this.getCarouselElementPosition()['left']; this.isMoveInProgress = true; }; this.handleHorizontalSwipe = (event) => { if (this.isSlideInProgress) { return; } const touches = event.touches; if (touches) { this.moveX = touches[0].clientX - this.getCarouselElementPosition()['left']; } else { this.moveX = event.clientX - this.getCarouselElementPosition()['left']; } this.distanceAbs = this.getDistanceAbs(); this.direction = this.getDirection(); this.moveContainer(); }; this.handleTouchend = (event) => { if (this.isSlideInProgress || !this.isTouchstart) { this.isTouchstart = false; return; } this.isMoveInProgress = false; if (this.detectSlide()) { this.handleSlide(); } else { this.newContainerPositionIndex = 0; this.alignContainer(); } this.startX = this.moveX = this.distanceAbs = undefined; this.isTouchstart = false; }; this.element = properties.element; this.properties = properties; this.cells = this.element.children; this.visibleWidth = this.properties.visibleWidth || this.element.parentElement.clientWidth; this.setContainerWidth(); this.alignContainer(0); } get isFirstCell() { return this.slideCounter === 0; } get lastCellIndex() { return this.images.length ? (this.images.length - 1) : (this.cells.length - 1); } get overflowCellsLimit() { return this.properties.overflowCellsLimit; } get cellLimit() { return this.visibleCellsCount + this.overflowCellsLimit * 2; } get images() { return this.properties.images; } get margin() { return this.properties.margin; } get minSwipeDistance() { return this.properties.minSwipeDistance; } get transitionDuration() { return this.properties.transitionDuration; } get transitionTimingFunction() { return this.properties.transitionTimingFunction; } get fullCellWidth() { return this.properties.cellWidth + this.margin; } get visibleCellsCount() { return Math.ceil(this.visibleWidth / this.fullCellWidth); } get lapCounter() { return Math.floor(this.slideCounter / this.totalContainerCellsCount); } get visibleCellsOverflowContainer() { return (this.visibleCellsCount * this.fullCellWidth - this.margin) > this.visibleWidth; } /* Move */ moveContainer() { let positionX = this.getMovePositionX(); this.transformPositionX(positionX, 0); } getMovePositionX() { const distance = this.getDistance(); return this.containerInitialPositionX - distance; } /* Align */ alignContainer(duration = this.transitionDuration) { let positionX = this.getContainerPosition(); this.transformPositionX(positionX, duration); this.setInitialContainerPosition(positionX); } getContainerPosition() { let correction = this.getContainerPositionCorrection(); this.isContainerPositionCorrection = correction != 0; return (this.initialContainerPosition + this.newContainerPositionIndex * this.fullCellWidth) + correction; } setInitialContainerPosition(position) { let correction = this.getContainerPositionCorrection(); this.initialContainerPosition = position - correction; } getContainerPositionCorrection() { let correction = 0; if ((this.images.length - this.preliminarySlideCounter) < this.visibleCellsCount || this.isSlideLengthLimited) { if (this.visibleWidth < this.totalContainerCellsCount * this.fullCellWidth) { correction = -(this.visibleCellsCount * this.fullCellWidth - this.visibleWidth - this.margin); } if (correction >= -this.margin) { correction = 0; } } return correction; } /* Quickly center */ quicklyPositionContainer() { let correction = this.getContainerPositionCorrection(); const initialPosition = this.getNewContainerPosition() + correction; this.transformPositionX(initialPosition, 0); this.setInitialContainerPosition(initialPosition); } getNewContainerPosition() { if (this.slideCounter > this.overflowCellsLimit) { if (this.alignCells === "left") { this.lineUpCells(); return -(this.overflowCellsLimit * this.fullCellWidth); } } if (this.slideCounter <= this.overflowCellsLimit) { if (this.previousSlideCounter > this.overflowCellsLimit) { this.lineUpCells(); } return -(this.slideCounter * this.fullCellWidth); } } setContainerWidth() { const containerWidth = this.getContainerWidth(); this.element.style.width = containerWidth + "px"; } getContainerWidth() { this.totalContainerCellsCount = this.visibleCellsCount + this.overflowCellsLimit * 2; let containerWidth = this.totalContainerCellsCount * this.fullCellWidth; let totalImageWidth = this.images.length * this.fullCellWidth; if (totalImageWidth < containerWidth) { containerWidth = totalImageWidth; } return containerWidth; } getFile(cellIndex) { let imageIndex = this.getFileIndex(cellIndex); let file = this.images[imageIndex]; if (file && !file.type) { file.type = 'image'; } return { image: this.images[imageIndex], imageIndex }; } getFileIndex(cellIndex) { const positionIndex = this.getPositionIndex(cellIndex); const numberLeftCells = (this.totalContainerCellsCount - 1) / 2; let imageIndex; if (!this.isContainerLocked) { if (this.slideCounter <= this.overflowCellsLimit) { return cellIndex; } else { let cellLimitOverflow = this.slideCounter - this.overflowCellsLimit; imageIndex = positionIndex + cellLimitOverflow; return imageIndex; } } if (this.alignCells === "left") { if (this.slideCounter > this.overflowCellsLimit) { let cellLimitOverflow = this.slideCounter - this.overflowCellsLimit; imageIndex = positionIndex + cellLimitOverflow; } else { imageIndex = cellIndex; } } if (imageIndex > this.lastCellIndex) { return false; } return imageIndex; } transformPositionX(value, duration = this.transitionDuration) { this.element.style.transition = 'transform ' + duration + 'ms ' + this.transitionTimingFunction; this.element.style.transform = 'translateX(' + value + 'px)'; } detectSlide() { return this.distanceAbs >= this.minSwipeDistance; } next() { if (this.isSlideInProgress) { return; } this.direction = 'left'; this.handleSlide(1); } prev() { if (this.isSlideInProgress) { return; } this.direction = 'right'; this.handleSlide(1); } select(index) { this.slideCounter = index; this.quicklyPositionContainer(); } handleSlide(slideLength = undefined) { this.slideLength = this.getSlideLength(); this.slideLength = slideLength ? slideLength : this.limitSlideLength(this.slideLength); if (this.direction === 'left' && !this.isSlideInProgress) { this.preliminarySlideCounter = this.slideCounter + this.slideLength; if (!this.detectLastSlide(this.slideCounter + this.slideLength)) { this.newContainerPositionIndex = this.newContainerPositionIndex - this.slideLength; this.isSlideInProgress = true; if (this.isLazyLoad) { this.isContainerLocked = this.preliminarySlideCounter > this.overflowCellsLimit; if (this.detectContainerUnlock()) { this.isContainerLocked = false; } } } } if (this.direction === 'right' && !this.isSlideInProgress) { if (this.slideCounter - this.slideLength < 0) { this.slideLength = this.slideCounter; } this.preliminarySlideCounter = this.slideCounter - this.slideLength; if (!this.isFirstCell) { this.newContainerPositionIndex = this.newContainerPositionIndex + this.slideLength; this.isSlideInProgress = true; if (this.isLazyLoad) { if (this.preliminarySlideCounter > this.overflowCellsLimit) { this.isContainerLocked = true; } else { this.isContainerLocked = false; } if (this.detectContainerUnlock()) { this.isContainerLocked = false; } } } } this.alignContainer(); } getSlideLength() { let correction = this.getContainerPositionCorrection(); let length = Math.floor((this.distanceAbs + correction) / this.fullCellWidth); if (this.distanceAbs % this.fullCellWidth >= this.minSwipeDistance) { length++; } return length; } limitSlideLength(slideLength) { if (slideLength > 1) { for (var i = 0; i < slideLength; i++) { let newSlideCounter = this.slideCounter + (slideLength - i); if (!this.detectLastSlide(newSlideCounter)) { slideLength = slideLength - i; this.isSlideLengthLimited = i > 0; break; } } } return slideLength; } detectLastSlide(slideCounter) { return (this.images.length - slideCounter) < this.visibleCellsCount; } isNextArrowDisabled() { if (this.visibleCellsOverflowContainer) { return this.detectLastSlide(this.slideCounter + 1) && this.isContainerPositionCorrection; } else { return this.detectLastSlide(this.slideCounter + 1); } } isPrevArrowDisabled() { return this.slideCounter === 0; } detectContainerUnlock() { return (this.images.length - this.preliminarySlideCounter) < (this.visibleCellsCount + this.overflowCellsLimit); } handleSlideEnd() { if (this.isSlideInProgress) { this.transformSlideEnd(); this.isSlideInProgress = false; this.newContainerPositionIndex = 0; this.isSlideLengthLimited = undefined; } } transformSlideEnd() { if (this.isLazyLoad) { this.setSlideCounter(); this.quicklyPositionContainer(); } this.previousSlideCounter = this.slideCounter; } setSlideCounter() { if (this.direction === 'left') { this.slideCounter = this.slideCounter + this.slideLength; } if (this.direction === 'right') { this.slideCounter = this.slideCounter - this.slideLength; } this.direction = undefined; this.slideLength = 0; } resetTransition() { this.element.style.transition = ''; } getElementPosition() { return this.element.getBoundingClientRect(); } getCarouselElementPosition() { return this.properties.container.getBoundingClientRect(); } getDistance() { return this.startX - this.moveX; } getDistanceAbs() { return Math.abs(this.startX - this.moveX); } getDirection() { const direction = Math.sign(this.startX - this.moveX); if (direction === -1) { return 'right'; } if (direction === 1) { return 'left'; } } lineUpCells() { const cells = this.element.children; for (var i = 0; i < cells.length; i++) { let cell = cells[i]; let positionX = this.getCellPositionX(i); cell.style.transform = 'translateX(' + positionX + 'px)'; } ; } getCellPositionX(index) { let positionIndex = this.getPositionIndex(index); return positionIndex * this.fullCellWidth; } getPositionIndex(cellIndex) { let slideCounter = this.slideCounter - this.overflowCellsLimit; let positionIndex; if (slideCounter > this.totalContainerCellsCount) { slideCounter = slideCounter % this.totalContainerCellsCount; } if (slideCounter < 0) { return cellIndex; } else { positionIndex = cellIndex - slideCounter; if (positionIndex < 0) { positionIndex = this.totalContainerCellsCount + positionIndex; } } return positionIndex; } get containerOverflowRightCount() { let totalOverflowCellsCount = this.images.length - this.totalContainerCellsCount; let overflowRight = 0; if (totalOverflowCellsCount > 0) { overflowRight = totalOverflowCellsCount - (this.previousSlideCounter - this.overflowCellsLimit); if (overflowRight > 0) { return overflowRight; } } return overflowRight; } getCenterPositionIndex() { return (this.totalContainerCellsCount - 1) / 2; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLWdhbGxlcnkvIiwic291cmNlcyI6WyJsaWIvY2Fyb3VzZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBY0EsTUFBTSxPQUFPLFFBQVE7SUFvRmpCLFlBQVksVUFBc0I7UUE1RWxDLHFCQUFnQixHQUFXLENBQUMsQ0FBQztRQUc3Qiw4QkFBeUIsR0FBVyxDQUFDLENBQUMsQ0FBQyxtRkFBbUY7UUFDMUgsNEJBQXVCLEdBQVcsQ0FBQyxDQUFDO1FBQ3BDLGlCQUFZLEdBQVcsQ0FBQyxDQUFDLENBQUMsNEJBQTRCO1FBQ3RELHlCQUFvQixHQUFXLENBQUMsQ0FBQztRQVVqQyxvQkFBZSxHQUFZLElBQUksQ0FBQztRQUdoQyxlQUFVLEdBQVksSUFBSSxDQUFDO1FBQzNCLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQUNuQyxlQUFVLEdBQXNCLE1BQU0sQ0FBQztRQUN2Qyw2QkFBd0IsR0FBVyxDQUFDLENBQUM7UUFnRXJDLHFCQUFnQixHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFFekIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3hCLE9BQU87YUFDVjtZQUVELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDOUIsSUFBSSxPQUFPLEVBQUU7Z0JBQ1QsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ2hGO2lCQUFNO2dCQUNILElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUMzRTtZQUNELElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMvRyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLENBQUMsQ0FBQTtRQUVELDBCQUFxQixHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDbkMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3hCLE9BQU87YUFDVjtZQUVELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDOUIsSUFBSSxPQUFPLEVBQUU7Z0JBQ1QsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQy9FO2lCQUFNO2dCQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUMxRTtZQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRXJDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUE7UUFFRCxtQkFBYyxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDNUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUM5QyxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDMUIsT0FBTzthQUNWO1lBRUQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztZQUU5QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2FBQ3RCO2lCQUFNO2dCQUNILElBQUksQ0FBQyx5QkFBeUIsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN6QjtZQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQztZQUN4RCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUM5QixDQUFDLENBQUE7UUE1REcsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7UUFFM0YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBNURELElBQUksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELElBQUksYUFBYTtRQUNiLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVELElBQUksa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQztJQUM5QyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ04sT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ04sT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQsSUFBSSxnQkFBZ0I7UUFDaEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDO0lBQzVDLENBQUM7SUFFRCxJQUFJLGtCQUFrQjtRQUNsQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUM7SUFDOUMsQ0FBQztJQUVELElBQUksd0JBQXdCO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQztJQUNwRCxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2IsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ25ELENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNqQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVELElBQUksVUFBVTtRQUNWLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxJQUFJLDZCQUE2QjtRQUM3QixPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDMUYsQ0FBQztJQWlFRCxVQUFVO0lBQ1YsYUFBYTtRQUNULElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELGdCQUFnQjtRQUNaLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwQyxPQUFPLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxRQUFRLENBQUM7SUFDckQsQ0FBQztJQUVELFdBQVc7SUFDWCxjQUFjLENBQUMsV0FBbUIsSUFBSSxDQUFDLGtCQUFrQjtRQUNyRCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUU1QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsb0JBQW9CO1FBQ2hCLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyw2QkFBNkIsR0FBRyxVQUFVLElBQUksQ0FBQyxDQUFDO1FBQ3JELE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxVQUFVLENBQUM7SUFDOUcsQ0FBQztJQUVELDJCQUEyQixDQUFDLFFBQVE7UUFDaEMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLFFBQVEsR0FBRyxVQUFVLENBQUM7SUFDMUQsQ0FBQztJQUVELDhCQUE4QjtRQUMxQixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFFbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDM0csSUFBSSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUN4RSxVQUFVLEdBQUcsQ0FBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ2xHO1lBRUQsSUFBSSxVQUFVLElBQUksQ0FBRSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUM3QixVQUFVLEdBQUcsQ0FBQyxDQUFDO2FBQ2xCO1NBQ0o7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLHdCQUF3QjtRQUNwQixJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztRQUN2RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFDcEUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELHVCQUF1QjtRQUNuQixJQUFJLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzdDLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxNQUFNLEVBQUU7Z0JBQzVCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbkIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUMxRDtTQUNKO1FBRUQsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUM5QyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ3JELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQzthQUN0QjtZQUNELE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQ3BEO0lBQ0wsQ0FBQztJQUVELGlCQUFpQjtRQUNiLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxjQUFjLEdBQUcsSUFBSSxDQUFDO0lBQ3JELENBQUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLENBQUM7UUFDckYsSUFBSSxjQUFjLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDeEUsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUU5RCxJQUFJLGVBQWUsR0FBRyxjQUFjLEVBQUU7WUFDbEMsY0FBYyxHQUFHLGVBQWUsQ0FBQztTQUNwQztRQUVELE9BQU8sY0FBYyxDQUFDO0lBQzFCLENBQUM7SUFFRCxPQUFPLENBQUMsU0FBUztRQUNiLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUVuQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDcEIsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7U0FDdkI7UUFFRCxPQUFPO1lBQ0gsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1lBQzlCLFVBQVU7U0FDYixDQUFDO0lBQ04sQ0FBQztJQUVELFlBQVksQ0FBQyxTQUFpQjtRQUMxQixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLElBQUksVUFBVSxDQUFDO1FBRWYsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUN6QixJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUM5QyxPQUFPLFNBQVMsQ0FBQzthQUNwQjtpQkFBTTtnQkFDSCxJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO2dCQUNwRSxVQUFVLEdBQUcsYUFBYSxHQUFHLGlCQUFpQixDQUFDO2dCQUMvQyxPQUFPLFVBQVUsQ0FBQzthQUNyQjtTQUNKO1FBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLE1BQU0sRUFBRTtZQUM1QixJQUFJLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUM3QyxJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO2dCQUNwRSxVQUFVLEdBQUcsYUFBYSxHQUFHLGlCQUFpQixDQUFDO2FBQ2xEO2lCQUFNO2dCQUNILFVBQVUsR0FBRyxTQUFTLENBQUM7YUFDMUI7U0FDSjtRQUVELElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDakMsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBRUQsa0JBQWtCLENBQUMsS0FBSyxFQUFFLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCO1FBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxZQUFZLEdBQUcsUUFBUSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUM7UUFDaEcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLGFBQWEsR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxXQUFXO1FBQ1AsT0FBTyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUNyRCxDQUFDO0lBRUQsSUFBSTtRQUNBLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hCLE9BQU87U0FDVjtRQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUk7UUFDQSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUN4QixPQUFPO1NBQ1Y7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBYTtRQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRUQsV0FBVyxDQUFDLGNBQXNCLFNBQVM7UUFDdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV2RixJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3RELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFFcEUsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQzdELElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDbkYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQkFFOUIsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNqQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztvQkFFaEYsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsRUFBRTt3QkFDOUIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztxQkFDbEM7aUJBQ0o7YUFDSjtTQUNKO1FBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUN2RCxJQUFJLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUU7Z0JBQzFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQzthQUN4QztZQUVELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7WUFFcEUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDbkYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQkFFOUIsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNqQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUU7d0JBQ3hELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7cUJBQ2pDO3lCQUFNO3dCQUNILElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7cUJBQ2xDO29CQUVELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUU7d0JBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7cUJBQ2xDO2lCQUNKO2FBQ0o7U0FDSjtRQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsY0FBYztRQUNWLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO1FBQ3ZELElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUU5RSxJQUFJLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEUsTUFBTSxFQUFFLENBQUM7U0FDWjtRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxXQUFtQjtRQUNoQyxJQUFJLFdBQVcsR0FBRyxDQUFDLEVBQUU7WUFFakIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDbEMsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFFNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLEVBQUU7b0JBQ3hDLFdBQVcsR0FBRyxXQUFXLEdBQUcsQ0FBQyxDQUFDO29CQUM5QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDbEMsTUFBTTtpQkFDVDthQUNKO1NBQ0o7UUFDRCxPQUFPLFdBQVcsQ0FBQztJQUN2QixDQUFDO0lBRUQsZUFBZSxDQUFDLFlBQW9CO1FBQ2hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7SUFDeEUsQ0FBQztJQUVELG1CQUFtQjtRQUNmLElBQUksSUFBSSxDQUFDLDZCQUE2QixFQUFFO1lBQ3BDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyw2QkFBNkIsQ0FBQztTQUM1RjthQUFNO1lBQ0gsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdEQ7SUFDTCxDQUFDO0lBRUQsbUJBQW1CO1FBQ2YsT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQscUJBQXFCO1FBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNwSCxDQUFDO0lBRUQsY0FBYztRQUNWLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3hCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBRXpCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7WUFDL0IsSUFBSSxDQUFDLHlCQUF5QixHQUFHLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFDO1NBQ3pDO0lBQ0wsQ0FBQztJQUVELGlCQUFpQjtRQUNiLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7U0FDbkM7UUFFRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztJQUNsRCxDQUFDO0lBRUQsZUFBZTtRQUNYLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxNQUFNLEVBQUU7WUFDM0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7U0FDNUQ7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssT0FBTyxFQUFFO1lBQzVCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQzVEO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxrQkFBa0I7UUFDZCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0lBRUQsMEJBQTBCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQsV0FBVztRQUNQLE9BQU8sSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxjQUFjO1FBQ1YsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxZQUFZO1FBQ1IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0RCxJQUFJLFNBQVMsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUNsQixPQUFPLE9BQU8sQ0FBQztTQUNsQjtRQUNELElBQUksU0FBUyxLQUFLLENBQUMsRUFBRTtZQUNqQixPQUFPLE1BQU0sQ0FBQztTQUNqQjtJQUNMLENBQUM7SUFFRCxXQUFXO1FBQ1AsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFFcEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxJQUFvQixDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsYUFBYSxHQUFHLFNBQVMsR0FBRyxLQUFLLENBQUM7U0FDN0U7UUFBQSxDQUFDO0lBQ04sQ0FBQztJQUVELGdCQUFnQixDQUFDLEtBQUs7UUFDbEIsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pELE9BQU8sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDOUMsQ0FBQztJQUVELGdCQUFnQixDQUFDLFNBQVM7UUFDdEIsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDL0QsSUFBSSxhQUFhLENBQUM7UUFFbEIsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFO1lBQzlDLFlBQVksR0FBRyxZQUFZLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDO1NBQy9EO1FBRUQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFO1lBQ2xCLE9BQU8sU0FBUyxDQUFDO1NBQ3BCO2FBQU07WUFDSCxhQUFhLEdBQUcsU0FBUyxHQUFHLFlBQVksQ0FBQztZQUN6QyxJQUFJLGFBQWEsR0FBRyxDQUFDLEVBQUU7Z0JBQ25CLGFBQWEsR0FBRyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsYUFBYSxDQUFDO2FBQ2pFO1NBQ0o7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN6QixDQUFDO0lBRUQsSUFBSSwyQkFBMkI7UUFDM0IsSUFBSSx1QkFBdUIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUM7UUFDakYsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBRXRCLElBQUksdUJBQXVCLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLGFBQWEsR0FBRyx1QkFBdUIsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUVoRyxJQUFJLGFBQWEsR0FBRyxDQUFDLEVBQUU7Z0JBQ25CLE9BQU8sYUFBYSxDQUFDO2FBQ3hCO1NBQ0o7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN6QixDQUFDO0lBRUQsc0JBQXNCO1FBQ2xCLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ25ELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgUHJvcGVydGllcyB7XHJcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XHJcbiAgICBpbWFnZXM6IGFueTtcclxuICAgIGNlbGxXaWR0aDogbnVtYmVyO1xyXG4gICAgb3ZlcmZsb3dDZWxsc0xpbWl0OiBudW1iZXI7XHJcbiAgICB2aXNpYmxlV2lkdGg6IG51bWJlcjtcclxuICAgIG1hcmdpbjogbnVtYmVyO1xyXG4gICAgbWluU3dpcGVEaXN0YW5jZTogbnVtYmVyO1xyXG4gICAgdHJhbnNpdGlvbkR1cmF0aW9uOiBudW1iZXI7XHJcbiAgICB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246ICdlYXNlJyB8ICdlYXNlLWluJyB8ICdlYXNlLW91dCcgfCAnZWFzZS1pbi1vdXQnIHwgJ2xpbmVhcic7XHJcbiAgICB2aWRlb1Byb3BlcnRpZXM6IGFueTtcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIENhcm91c2VsIHtcclxuICAgIHByb3BlcnRpZXM6IFByb3BlcnRpZXM7XHJcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgIHN0YXJ0WDogbnVtYmVyO1xyXG4gICAgbW92ZVg6IG51bWJlcjtcclxuICAgIGRpcmVjdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0JztcclxuICAgIHNsaWRlTGVuZ3RoOiBudW1iZXI7XHJcbiAgICBkaXN0YW5jZUFiczogbnVtYmVyO1xyXG4gICAgaW5pdGlhbFBvc2l0aW9uWDogbnVtYmVyID0gMDtcclxuICAgIGNlbGxzOiBIVE1MQ29sbGVjdGlvbjtcclxuXHJcbiAgICBuZXdDb250YWluZXJQb3NpdGlvbkluZGV4OiBudW1iZXIgPSAwOyAvLyBUaGUgaW5kZXggb2YgdGhlIG5ldyBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgYWN0aXZlIGluZGV4LCBmb3IgZXhhbXBsZSAtMSBvciArMVxyXG4gICAgcHJlbGltaW5hcnlTbGlkZUNvdW50ZXI6IG51bWJlciA9IDA7XHJcbiAgICBzbGlkZUNvdW50ZXI6IG51bWJlciA9IDA7IC8vIFNjcm9sbGluZyBJbmRleCAoY291bnRlcilcclxuICAgIHByZXZpb3VzU2xpZGVDb3VudGVyOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIGlzU2xpZGVJblByb2dyZXNzOiBib29sZWFuO1xyXG4gICAgaXNNb3ZlSW5Qcm9ncmVzczogYm9vbGVhbjtcclxuICAgIGlzVHJhbnNpdGlvbkluUHJvZ3Jlc3M6IGJvb2xlYW47XHJcbiAgICBpc1RvdWNoc3RhcnQ6IGJvb2xlYW47XHJcbiAgICBpc1NsaWRlTGVuZ3RoTGltaXRlZDogYm9vbGVhbjtcclxuICAgIGlzQ29udGFpbmVyUG9zaXRpb25Db3JyZWN0aW9uOiBib29sZWFuO1xyXG5cclxuICAgIGNvbnRhaW5lckluaXRpYWxQb3NpdGlvblg6IG51bWJlcjtcclxuICAgIGlzQ29udGVudEltYWdlczogYm9vbGVhbiA9IHRydWU7XHJcbiAgICB2aXNpYmxlV2lkdGg6IG51bWJlcjtcclxuICAgIHRvdGFsQ29udGFpbmVyQ2VsbHNDb3VudDogbnVtYmVyO1xyXG4gICAgaXNMYXp5TG9hZDogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBpc0NvbnRhaW5lckxvY2tlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgYWxpZ25DZWxsczogXCJsZWZ0XCIgfCBcImNlbnRlclwiID0gXCJsZWZ0XCI7XHJcbiAgICBpbml0aWFsQ29udGFpbmVyUG9zaXRpb246IG51bWJlciA9IDA7XHJcblxyXG4gICAgZ2V0IGlzRmlyc3RDZWxsKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNsaWRlQ291bnRlciA9PT0gMDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbGFzdENlbGxJbmRleCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXMubGVuZ3RoID8gKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpIDogKHRoaXMuY2VsbHMubGVuZ3RoIC0gMSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG92ZXJmbG93Q2VsbHNMaW1pdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzLm92ZXJmbG93Q2VsbHNMaW1pdDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgY2VsbExpbWl0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZpc2libGVDZWxsc0NvdW50ICsgdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQgKiAyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBpbWFnZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydGllcy5pbWFnZXM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1hcmdpbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzLm1hcmdpbjtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbWluU3dpcGVEaXN0YW5jZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzLm1pblN3aXBlRGlzdGFuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRyYW5zaXRpb25EdXJhdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzLnRyYW5zaXRpb25EdXJhdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnRpZXMudHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBmdWxsQ2VsbFdpZHRoKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnRpZXMuY2VsbFdpZHRoICsgdGhpcy5tYXJnaW47XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZpc2libGVDZWxsc0NvdW50KCkge1xyXG4gICAgICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy52aXNpYmxlV2lkdGggLyB0aGlzLmZ1bGxDZWxsV2lkdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsYXBDb3VudGVyKCkge1xyXG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMuc2xpZGVDb3VudGVyIC8gdGhpcy50b3RhbENvbnRhaW5lckNlbGxzQ291bnQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB2aXNpYmxlQ2VsbHNPdmVyZmxvd0NvbnRhaW5lcigpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMudmlzaWJsZUNlbGxzQ291bnQgKiB0aGlzLmZ1bGxDZWxsV2lkdGggLXRoaXMubWFyZ2luKSA+IHRoaXMudmlzaWJsZVdpZHRoO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0cnVjdG9yKHByb3BlcnRpZXM6IFByb3BlcnRpZXMpIHtcclxuICAgICAgICB0aGlzLmVsZW1lbnQgPSBwcm9wZXJ0aWVzLmVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcclxuICAgICAgICB0aGlzLmNlbGxzID0gdGhpcy5lbGVtZW50LmNoaWxkcmVuO1xyXG4gICAgICAgIHRoaXMudmlzaWJsZVdpZHRoID0gdGhpcy5wcm9wZXJ0aWVzLnZpc2libGVXaWR0aCB8fCB0aGlzLmVsZW1lbnQucGFyZW50RWxlbWVudC5jbGllbnRXaWR0aDtcclxuXHJcbiAgICAgICAgdGhpcy5zZXRDb250YWluZXJXaWR0aCgpO1xyXG4gICAgICAgIHRoaXMuYWxpZ25Db250YWluZXIoMCk7XHJcbiAgICB9XHJcblxyXG4gICAgaGFuZGxlVG91Y2hzdGFydCA9IChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5pc1RvdWNoc3RhcnQgPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc1NsaWRlSW5Qcm9ncmVzcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0b3VjaGVzID0gZXZlbnQudG91Y2hlcztcclxuICAgICAgICBpZiAodG91Y2hlcykge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0WCA9IHRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuZ2V0Q2Fyb3VzZWxFbGVtZW50UG9zaXRpb24oKVsnbGVmdCddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRYID0gZXZlbnQuY2xpZW50WCAtIHRoaXMuZ2V0Q2Fyb3VzZWxFbGVtZW50UG9zaXRpb24oKVsnbGVmdCddO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbnRhaW5lckluaXRpYWxQb3NpdGlvblggPSB0aGlzLmdldEVsZW1lbnRQb3NpdGlvbigpWydsZWZ0J10gLSB0aGlzLmdldENhcm91c2VsRWxlbWVudFBvc2l0aW9uKClbJ2xlZnQnXTtcclxuICAgICAgICB0aGlzLmlzTW92ZUluUHJvZ3Jlc3MgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGhhbmRsZUhvcml6b250YWxTd2lwZSA9IChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNTbGlkZUluUHJvZ3Jlc3MpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXM7XHJcbiAgICAgICAgaWYgKHRvdWNoZXMpIHtcclxuICAgICAgICAgICAgdGhpcy5tb3ZlWCA9IHRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuZ2V0Q2Fyb3VzZWxFbGVtZW50UG9zaXRpb24oKVsnbGVmdCddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubW92ZVggPSBldmVudC5jbGllbnRYIC0gdGhpcy5nZXRDYXJvdXNlbEVsZW1lbnRQb3NpdGlvbigpWydsZWZ0J107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZGlzdGFuY2VBYnMgPSB0aGlzLmdldERpc3RhbmNlQWJzKCk7XHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb24gPSB0aGlzLmdldERpcmVjdGlvbigpO1xyXG5cclxuICAgICAgICB0aGlzLm1vdmVDb250YWluZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBoYW5kbGVUb3VjaGVuZCA9IChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNTbGlkZUluUHJvZ3Jlc3MgfHwgIXRoaXMuaXNUb3VjaHN0YXJ0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNUb3VjaHN0YXJ0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaXNNb3ZlSW5Qcm9ncmVzcyA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5kZXRlY3RTbGlkZSgpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlU2xpZGUoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm5ld0NvbnRhaW5lclBvc2l0aW9uSW5kZXggPSAwO1xyXG4gICAgICAgICAgICB0aGlzLmFsaWduQ29udGFpbmVyKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN0YXJ0WCA9IHRoaXMubW92ZVggPSB0aGlzLmRpc3RhbmNlQWJzID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMuaXNUb3VjaHN0YXJ0ID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyogTW92ZSAqL1xyXG4gICAgbW92ZUNvbnRhaW5lcigpIHtcclxuICAgICAgICBsZXQgcG9zaXRpb25YID0gdGhpcy5nZXRNb3ZlUG9zaXRpb25YKCk7XHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1Qb3NpdGlvblgocG9zaXRpb25YLCAwKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRNb3ZlUG9zaXRpb25YKCkge1xyXG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gdGhpcy5nZXREaXN0YW5jZSgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lckluaXRpYWxQb3NpdGlvblggLSBkaXN0YW5jZTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBBbGlnbiAqL1xyXG4gICAgYWxpZ25Db250YWluZXIoZHVyYXRpb246IG51bWJlciA9IHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uKSB7XHJcbiAgICAgICAgbGV0IHBvc2l0aW9uWCA9IHRoaXMuZ2V0Q29udGFpbmVyUG9zaXRpb24oKTtcclxuXHJcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1Qb3NpdGlvblgocG9zaXRpb25YLCBkdXJhdGlvbik7XHJcbiAgICAgICAgdGhpcy5zZXRJbml0aWFsQ29udGFpbmVyUG9zaXRpb24ocG9zaXRpb25YKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRDb250YWluZXJQb3NpdGlvbigpIHtcclxuICAgICAgICBsZXQgY29ycmVjdGlvbiA9IHRoaXMuZ2V0Q29udGFpbmVyUG9zaXRpb25Db3JyZWN0aW9uKCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNDb250YWluZXJQb3NpdGlvbkNvcnJlY3Rpb24gPSBjb3JyZWN0aW9uICE9IDA7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmluaXRpYWxDb250YWluZXJQb3NpdGlvbiArIHRoaXMubmV3Q29udGFpbmVyUG9zaXRpb25JbmRleCAqIHRoaXMuZnVsbENlbGxXaWR0aCkgKyBjb3JyZWN0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIHNldEluaXRpYWxDb250YWluZXJQb3NpdGlvbihwb3NpdGlvbikge1xyXG4gICAgICAgIGxldCBjb3JyZWN0aW9uID0gdGhpcy5nZXRDb250YWluZXJQb3NpdGlvbkNvcnJlY3Rpb24oKTtcclxuICAgICAgICB0aGlzLmluaXRpYWxDb250YWluZXJQb3NpdGlvbiA9IHBvc2l0aW9uIC0gY29ycmVjdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBnZXRDb250YWluZXJQb3NpdGlvbkNvcnJlY3Rpb24oKSB7XHJcbiAgICAgICAgbGV0IGNvcnJlY3Rpb24gPSAwO1xyXG5cclxuICAgICAgICBpZiAoKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIHRoaXMucHJlbGltaW5hcnlTbGlkZUNvdW50ZXIpIDwgdGhpcy52aXNpYmxlQ2VsbHNDb3VudCB8fCB0aGlzLmlzU2xpZGVMZW5ndGhMaW1pdGVkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnZpc2libGVXaWR0aCA8IHRoaXMudG90YWxDb250YWluZXJDZWxsc0NvdW50ICogdGhpcy5mdWxsQ2VsbFdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JyZWN0aW9uID0gLSAodGhpcy52aXNpYmxlQ2VsbHNDb3VudCAqIHRoaXMuZnVsbENlbGxXaWR0aCAtIHRoaXMudmlzaWJsZVdpZHRoIC0gdGhpcy5tYXJnaW4pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY29ycmVjdGlvbiA+PSAtIHRoaXMubWFyZ2luKSB7XHJcbiAgICAgICAgICAgICAgICBjb3JyZWN0aW9uID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGNvcnJlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgLyogUXVpY2tseSBjZW50ZXIgKi9cclxuICAgIHF1aWNrbHlQb3NpdGlvbkNvbnRhaW5lcigpIHtcclxuICAgICAgICBsZXQgY29ycmVjdGlvbiA9IHRoaXMuZ2V0Q29udGFpbmVyUG9zaXRpb25Db3JyZWN0aW9uKCk7XHJcbiAgICAgICAgY29uc3QgaW5pdGlhbFBvc2l0aW9uID0gdGhpcy5nZXROZXdDb250YWluZXJQb3NpdGlvbigpICsgY29ycmVjdGlvbjtcclxuICAgICAgICB0aGlzLnRyYW5zZm9ybVBvc2l0aW9uWChpbml0aWFsUG9zaXRpb24sIDApO1xyXG4gICAgICAgIHRoaXMuc2V0SW5pdGlhbENvbnRhaW5lclBvc2l0aW9uKGluaXRpYWxQb3NpdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TmV3Q29udGFpbmVyUG9zaXRpb24oKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2xpZGVDb3VudGVyID4gdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYWxpZ25DZWxscyA9PT0gXCJsZWZ0XCIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGluZVVwQ2VsbHMoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAtKHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0ICogdGhpcy5mdWxsQ2VsbFdpZHRoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2xpZGVDb3VudGVyIDw9IHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0KSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXZpb3VzU2xpZGVDb3VudGVyID4gdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGluZVVwQ2VsbHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gLSh0aGlzLnNsaWRlQ291bnRlciAqIHRoaXMuZnVsbENlbGxXaWR0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNldENvbnRhaW5lcldpZHRoKCkge1xyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5nZXRDb250YWluZXJXaWR0aCgpO1xyXG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IGNvbnRhaW5lcldpZHRoICsgXCJweFwiO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENvbnRhaW5lcldpZHRoKCkge1xyXG4gICAgICAgIHRoaXMudG90YWxDb250YWluZXJDZWxsc0NvdW50ID0gdGhpcy52aXNpYmxlQ2VsbHNDb3VudCArIHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0ICogMjtcclxuICAgICAgICBsZXQgY29udGFpbmVyV2lkdGggPSB0aGlzLnRvdGFsQ29udGFpbmVyQ2VsbHNDb3VudCAqIHRoaXMuZnVsbENlbGxXaWR0aDtcclxuICAgICAgICBsZXQgdG90YWxJbWFnZVdpZHRoID0gdGhpcy5pbWFnZXMubGVuZ3RoICogdGhpcy5mdWxsQ2VsbFdpZHRoO1xyXG5cclxuICAgICAgICBpZiAodG90YWxJbWFnZVdpZHRoIDwgY29udGFpbmVyV2lkdGgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyV2lkdGggPSB0b3RhbEltYWdlV2lkdGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gY29udGFpbmVyV2lkdGg7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RmlsZShjZWxsSW5kZXgpIHtcclxuICAgICAgICBsZXQgaW1hZ2VJbmRleCA9IHRoaXMuZ2V0RmlsZUluZGV4KGNlbGxJbmRleCk7IFxyXG4gICAgICAgIGxldCBmaWxlID0gdGhpcy5pbWFnZXNbaW1hZ2VJbmRleF07XHJcblxyXG4gICAgICAgIGlmIChmaWxlICYmICFmaWxlLnR5cGUpIHtcclxuICAgICAgICAgICAgZmlsZS50eXBlID0gJ2ltYWdlJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGltYWdlOiB0aGlzLmltYWdlc1tpbWFnZUluZGV4XSxcclxuICAgICAgICAgICAgaW1hZ2VJbmRleFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RmlsZUluZGV4KGNlbGxJbmRleDogbnVtYmVyKSB7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25JbmRleCA9IHRoaXMuZ2V0UG9zaXRpb25JbmRleChjZWxsSW5kZXgpO1xyXG4gICAgICAgIGNvbnN0IG51bWJlckxlZnRDZWxscyA9ICh0aGlzLnRvdGFsQ29udGFpbmVyQ2VsbHNDb3VudCAtIDEpIC8gMjtcclxuICAgICAgICBsZXQgaW1hZ2VJbmRleDtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLmlzQ29udGFpbmVyTG9ja2VkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNsaWRlQ291bnRlciA8PSB0aGlzLm92ZXJmbG93Q2VsbHNMaW1pdCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNlbGxJbmRleDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCBjZWxsTGltaXRPdmVyZmxvdyA9IHRoaXMuc2xpZGVDb3VudGVyIC0gdGhpcy5vdmVyZmxvd0NlbGxzTGltaXQ7XHJcbiAgICAgICAgICAgICAgICBpbWFnZUluZGV4ID0gcG9zaXRpb25JbmRleCArIGNlbGxMaW1pdE92ZXJmbG93O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGltYWdlSW5kZXg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmFsaWduQ2VsbHMgPT09IFwibGVmdFwiKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNsaWRlQ291bnRlciA+IHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0KSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2VsbExpbWl0T3ZlcmZsb3cgPSB0aGlzLnNsaWRlQ291bnRlciAtIHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0O1xyXG4gICAgICAgICAgICAgICAgaW1hZ2VJbmRleCA9IHBvc2l0aW9uSW5kZXggKyBjZWxsTGltaXRPdmVyZmxvdztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGltYWdlSW5kZXggPSBjZWxsSW5kZXg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChpbWFnZUluZGV4ID4gdGhpcy5sYXN0Q2VsbEluZGV4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpbWFnZUluZGV4O1xyXG4gICAgfVxyXG5cclxuICAgIHRyYW5zZm9ybVBvc2l0aW9uWCh2YWx1ZSwgZHVyYXRpb24gPSB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbikge1xyXG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2l0aW9uID0gJ3RyYW5zZm9ybSAnICsgZHVyYXRpb24gKyAnbXMgJyArIHRoaXMudHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uO1xyXG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgnICsgdmFsdWUgKyAncHgpJztcclxuICAgIH1cclxuXHJcbiAgICBkZXRlY3RTbGlkZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kaXN0YW5jZUFicyA+PSB0aGlzLm1pblN3aXBlRGlzdGFuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgbmV4dCgpIHtcclxuICAgICAgICBpZiAodGhpcy5pc1NsaWRlSW5Qcm9ncmVzcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmRpcmVjdGlvbiA9ICdsZWZ0JztcclxuICAgICAgICB0aGlzLmhhbmRsZVNsaWRlKDEpO1xyXG4gICAgfVxyXG5cclxuICAgIHByZXYoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNTbGlkZUluUHJvZ3Jlc3MpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb24gPSAncmlnaHQnO1xyXG4gICAgICAgIHRoaXMuaGFuZGxlU2xpZGUoMSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZWN0KGluZGV4OiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLnNsaWRlQ291bnRlciA9IGluZGV4O1xyXG4gICAgICAgIHRoaXMucXVpY2tseVBvc2l0aW9uQ29udGFpbmVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaGFuZGxlU2xpZGUoc2xpZGVMZW5ndGg6IG51bWJlciA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc2xpZGVMZW5ndGggPSB0aGlzLmdldFNsaWRlTGVuZ3RoKCk7XHJcbiAgICAgICAgdGhpcy5zbGlkZUxlbmd0aCA9IHNsaWRlTGVuZ3RoID8gc2xpZGVMZW5ndGggOiB0aGlzLmxpbWl0U2xpZGVMZW5ndGgodGhpcy5zbGlkZUxlbmd0aCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmRpcmVjdGlvbiA9PT0gJ2xlZnQnICYmICF0aGlzLmlzU2xpZGVJblByb2dyZXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJlbGltaW5hcnlTbGlkZUNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlciArIHRoaXMuc2xpZGVMZW5ndGg7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGV0ZWN0TGFzdFNsaWRlKHRoaXMuc2xpZGVDb3VudGVyICsgdGhpcy5zbGlkZUxlbmd0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV3Q29udGFpbmVyUG9zaXRpb25JbmRleCA9IHRoaXMubmV3Q29udGFpbmVyUG9zaXRpb25JbmRleCAtIHRoaXMuc2xpZGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzU2xpZGVJblByb2dyZXNzID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0xhenlMb2FkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0NvbnRhaW5lckxvY2tlZCA9IHRoaXMucHJlbGltaW5hcnlTbGlkZUNvdW50ZXIgPiB0aGlzLm92ZXJmbG93Q2VsbHNMaW1pdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGV0ZWN0Q29udGFpbmVyVW5sb2NrKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0NvbnRhaW5lckxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZGlyZWN0aW9uID09PSAncmlnaHQnICYmICF0aGlzLmlzU2xpZGVJblByb2dyZXNzKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNsaWRlQ291bnRlciAtIHRoaXMuc2xpZGVMZW5ndGggPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNsaWRlTGVuZ3RoID0gdGhpcy5zbGlkZUNvdW50ZXI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMucHJlbGltaW5hcnlTbGlkZUNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlciAtIHRoaXMuc2xpZGVMZW5ndGg7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNGaXJzdENlbGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV3Q29udGFpbmVyUG9zaXRpb25JbmRleCA9IHRoaXMubmV3Q29udGFpbmVyUG9zaXRpb25JbmRleCArIHRoaXMuc2xpZGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzU2xpZGVJblByb2dyZXNzID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0xhenlMb2FkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJlbGltaW5hcnlTbGlkZUNvdW50ZXIgPiB0aGlzLm92ZXJmbG93Q2VsbHNMaW1pdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29udGFpbmVyTG9ja2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29udGFpbmVyTG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZXRlY3RDb250YWluZXJVbmxvY2soKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29udGFpbmVyTG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmFsaWduQ29udGFpbmVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0U2xpZGVMZW5ndGgoKSB7XHJcbiAgICAgICAgbGV0IGNvcnJlY3Rpb24gPSB0aGlzLmdldENvbnRhaW5lclBvc2l0aW9uQ29ycmVjdGlvbigpO1xyXG4gICAgICAgIGxldCBsZW5ndGggPSBNYXRoLmZsb29yKCh0aGlzLmRpc3RhbmNlQWJzICsgY29ycmVjdGlvbikgLyB0aGlzLmZ1bGxDZWxsV2lkdGgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5kaXN0YW5jZUFicyAlIHRoaXMuZnVsbENlbGxXaW