carousel-angular
Version:
A simple carousel component for Angular 14+ based on 'angular-responsive-carousel' by Ivy Laboratory http://ivylab.space
258 lines • 29.9 kB
JavaScript
export class Container {
constructor(carouselProperties, utils, cells) {
this.carouselProperties = carouselProperties;
this.utils = utils;
this.cells = cells;
/* The index of the new position relative to
* the active index, for example -1 or +1
*/
this.initialPositionX = 0;
this.initialElementPositionX = 0;
this.pullLimit = 100;
this.startTime = 0;
this.startX = 0;
this.moveX = 0;
this.isSwipeInProgress = false;
this.init();
}
get visibleWidth() {
return this.utils.visibleWidth;
}
get overflowCellsLimit() {
return this.utils.overflowCellsLimit;
}
get element() {
return this.carouselProperties.cellsElement;
}
get freeScroll() {
return this.carouselProperties.freeScroll;
}
get fullCellWidth() {
return this.carouselProperties.cellWidth + this.carouselProperties.margin;
}
get numberOfVisibleCells() {
return this.utils.numberOfVisibleCells;
}
get transitionDuration() {
return this.carouselProperties.transitionDuration;
}
get transitionTimingFunction() {
return this.carouselProperties.transitionTimingFunction;
}
get cellLength() {
return this.cells.cellLength;
}
get tooFewCells() {
return this.numberOfVisibleCells > this.cellLength;
}
get disabled() {
return this.tooFewCells;
}
get margin() {
return this.carouselProperties.margin;
}
updateProperties(carouselProperties) {
this.carouselProperties = carouselProperties;
}
init() {
this.setWidth();
}
handleTouchstart() {
this.startX = this.utils.getStartX(event);
this.startTime = new Date().getTime();
this.initialElementPositionX = this.getInitialElementPositionX();
}
handleHorizontalSwipe() {
if (this.disabled) {
return;
}
if (!this.isSwipeInProgress) {
this.startX = this.utils.getStartX(event);
this.startTime = new Date().getTime();
this.initialElementPositionX = this.getInitialElementPositionX();
}
this.isSwipeInProgress = true;
this.moveX = this.utils.getMoveX(event);
this.move();
}
handleTouchend(simpleProcessing = false) {
if (this.disabled) {
return;
}
/* If touchend was passed to the Slide class */
if (simpleProcessing) {
this.isSwipeInProgress = false;
return;
}
this.isSwipeInProgress = false;
this.finishMoving();
this.clearInitialValues();
}
move() {
let positionX = this.getMovePositionX();
const isPulled = this.detectPulled();
const direction = this.getDirection();
if (isPulled) {
if ((isPulled.edge === 'left' && direction === 'right') ||
(isPulled.edge === 'right' && direction === 'left')) {
positionX = this.slowdownOnPull(positionX);
}
}
this.transformPositionX(positionX, 0);
if (this.freeScroll) {
this.initialPositionX = positionX;
}
if (isPulled) {
if (isPulled.edge === 'left' && isPulled.overflowX > this.pullLimit) {
this.initialPositionX = 0;
}
if (isPulled.edge === 'right' && isPulled.overflowX > this.pullLimit) {
this.initialPositionX = positionX;
}
}
}
getMovePositionX() {
const distance = this.getDistance();
return this.initialElementPositionX - distance;
}
getDistance() {
return this.startX - this.moveX;
}
/* If the container is pulled out of the left or right border */
detectPulled() {
const currentPositionX = this.getCurrentPositionX();
if (currentPositionX > 0) {
return {
edge: 'left',
positionX: currentPositionX,
overflowX: Math.abs(currentPositionX)
};
}
if (currentPositionX < this.getEndPosition()) {
return {
edge: 'right',
positionX: currentPositionX,
overflowX: Math.abs(currentPositionX - this.getEndPosition())
};
}
return undefined;
}
slowdownOnPull(_positionX) {
let distance = Math.abs(this.getDistance());
const endPosition = this.getEndPosition();
const isPulled = this.detectPulled();
if (!isPulled) {
return 0;
}
const decelerationRatio = 3 + isPulled.overflowX / 50;
let positionX = 0;
if (isPulled.edge === 'left') {
if (this.initialElementPositionX < 0) {
distance -= Math.abs(this.initialElementPositionX);
}
const rubberPositionX = distance / decelerationRatio;
positionX = rubberPositionX;
if (this.initialElementPositionX > 0) {
positionX = this.initialElementPositionX + rubberPositionX;
}
if (positionX > this.pullLimit) {
positionX = this.pullLimit;
}
}
if (isPulled.edge === 'right') {
const rubberPositionX = endPosition +
(this.initialElementPositionX - distance - endPosition) /
decelerationRatio;
const containerWidth = this.getWidth();
positionX = rubberPositionX;
if (this.initialElementPositionX < -(containerWidth - this.visibleWidth)) {
positionX =
containerWidth -
this.visibleWidth +
this.initialElementPositionX +
rubberPositionX;
}
if (positionX < endPosition - this.pullLimit) {
positionX = endPosition - this.pullLimit;
}
}
return positionX;
}
finishMoving() {
const positionX = this.getMovePositionX();
let newPositionX = 0;
if (this.freeScroll) {
newPositionX = this.getInertia();
}
/* Align container while pulling */
newPositionX = this.getAlignedPositionOnPull(newPositionX);
this.transformPositionX(newPositionX);
this.setInitialPosition(positionX);
}
/* Returns the new position of the container with inertia */
getInertia() {
const distance = this.getDistance();
const currentTime = new Date().getTime();
const tapLength = currentTime - this.startTime;
const inertia = (distance / tapLength) * 100;
return this.initialPositionX - inertia;
}
getAlignedPositionOnPull(newPositionX) {
const direction = this.getDirection();
if (direction === 'left') {
const endPosition = this.getEndPosition();
if (newPositionX < endPosition) {
return endPosition;
}
}
return newPositionX;
}
getCurrentPositionX() {
const parentPosition = this.element.parentElement.getBoundingClientRect();
const position = this.element.getBoundingClientRect();
return position.left - parentPosition.left;
}
getEndPosition() {
const width = this.getWidth();
const visibleWidth = this.element.parentElement.clientWidth;
return visibleWidth - width;
}
transformPositionX(value, duration = this.transitionDuration) {
if (value === undefined) {
return;
}
this.element.style.transition = `transform ${duration}ms ${this.transitionTimingFunction}`;
this.element.style.transform = `translateX(${value}px)`;
}
getWidth() {
return this.cellLength * this.fullCellWidth;
}
setWidth() {
const width = this.getWidth();
this.element.style.width = `${width}px`;
}
setInitialPosition(position) {
this.initialPositionX = position;
}
getElementPosition() {
return this.element.getBoundingClientRect();
}
getInitialElementPositionX() {
const carouselElementPosition = this.utils.getCarouselElementPosition().left;
return this.getElementPosition().left - carouselElementPosition;
}
clearInitialValues() {
this.startX = this.moveX = 0;
}
getDirection() {
const direction = Math.sign(this.startX - this.moveX);
if (direction === -1) {
return 'right';
}
if (direction === 1) {
return 'left';
}
return undefined;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY2Fyb3VzZWwtYW5ndWxhci9zcmMvbGliL2NvbnRhaW5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQU8sU0FBUztJQWtFcEIsWUFDVSxrQkFBc0MsRUFDdEMsS0FBVSxFQUNWLEtBQVU7UUFGVix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLFVBQUssR0FBTCxLQUFLLENBQUs7UUFDVixVQUFLLEdBQUwsS0FBSyxDQUFLO1FBcEVwQjs7V0FFRztRQUNILHFCQUFnQixHQUFHLENBQUMsQ0FBQztRQUVyQiw0QkFBdUIsR0FBRyxDQUFDLENBQUM7UUFFNUIsY0FBUyxHQUFHLEdBQUcsQ0FBQztRQUVoQixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBRWQsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUVYLFVBQUssR0FBRyxDQUFDLENBQUM7UUFFVixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUF1RHhCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNkLENBQUM7SUF0REQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxrQkFBa0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUM7SUFDOUMsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQztJQUM1QyxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7SUFDNUUsQ0FBQztJ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SUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRELElBQUksU0FBUyxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sT0FBTyxDQUFDO1NBQ2hCO1FBQ0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxFQUFFO1lBQ25CLE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQcm9wZXJ0aWVzIGFzIENhcm91c2VsUHJvcGVydGllcyB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBDb250YWluZXIge1xuICAvKiBUaGUgaW5kZXggb2YgdGhlIG5ldyBwb3NpdGlvbiByZWxhdGl2ZSB0b1xuICAgKiB0aGUgYWN0aXZlIGluZGV4LCBmb3IgZXhhbXBsZSAtMSBvciArMVxuICAgKi9cbiAgaW5pdGlhbFBvc2l0aW9uWCA9IDA7XG5cbiAgaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPSAwO1xuXG4gIHB1bGxMaW1pdCA9IDEwMDtcblxuICBzdGFydFRpbWUgPSAwO1xuXG4gIHN0YXJ0WCA9IDA7XG5cbiAgbW92ZVggPSAwO1xuXG4gIGlzU3dpcGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgZ2V0IHZpc2libGVXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy51dGlscy52aXNpYmxlV2lkdGg7XG4gIH1cblxuICBnZXQgb3ZlcmZsb3dDZWxsc0xpbWl0KCkge1xuICAgIHJldHVybiB0aGlzLnV0aWxzLm92ZXJmbG93Q2VsbHNMaW1pdDtcbiAgfVxuXG4gIGdldCBlbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5jZWxsc0VsZW1lbnQ7XG4gIH1cblxuICBnZXQgZnJlZVNjcm9sbCgpIHtcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMuZnJlZVNjcm9sbDtcbiAgfVxuXG4gIGdldCBmdWxsQ2VsbFdpZHRoKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5jZWxsV2lkdGggKyB0aGlzLmNhcm91c2VsUHJvcGVydGllcy5tYXJnaW47XG4gIH1cblxuICBnZXQgbnVtYmVyT2ZWaXNpYmxlQ2VsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudXRpbHMubnVtYmVyT2ZWaXNpYmxlQ2VsbHM7XG4gIH1cblxuICBnZXQgdHJhbnNpdGlvbkR1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy50cmFuc2l0aW9uRHVyYXRpb247XG4gIH1cblxuICBnZXQgdHJhbnNpdGlvblRpbWluZ0Z1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNhcm91c2VsUHJvcGVydGllcy50cmFuc2l0aW9uVGltaW5nRnVuY3Rpb247XG4gIH1cblxuICBnZXQgY2VsbExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5jZWxscy5jZWxsTGVuZ3RoO1xuICB9XG5cbiAgZ2V0IHRvb0Zld0NlbGxzKCkge1xuICAgIHJldHVybiB0aGlzLm51bWJlck9mVmlzaWJsZUNlbGxzID4gdGhpcy5jZWxsTGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLnRvb0Zld0NlbGxzO1xuICB9XG5cbiAgZ2V0IG1hcmdpbigpIHtcbiAgICByZXR1cm4gdGhpcy5jYXJvdXNlbFByb3BlcnRpZXMubWFyZ2luO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjYXJvdXNlbFByb3BlcnRpZXM6IENhcm91c2VsUHJvcGVydGllcyxcbiAgICBwcml2YXRlIHV0aWxzOiBhbnksXG4gICAgcHJpdmF0ZSBjZWxsczogYW55XG4gICkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgdXBkYXRlUHJvcGVydGllcyhjYXJvdXNlbFByb3BlcnRpZXM6IENhcm91c2VsUHJvcGVydGllcykge1xuICAgIHRoaXMuY2Fyb3VzZWxQcm9wZXJ0aWVzID0gY2Fyb3VzZWxQcm9wZXJ0aWVzO1xuICB9XG5cbiAgaW5pdCgpIHtcbiAgICB0aGlzLnNldFdpZHRoKCk7XG4gIH1cblxuICBoYW5kbGVUb3VjaHN0YXJ0KCkge1xuICAgIHRoaXMuc3RhcnRYID0gdGhpcy51dGlscy5nZXRTdGFydFgoZXZlbnQpO1xuICAgIHRoaXMuc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA9IHRoaXMuZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKTtcbiAgfVxuXG4gIGhhbmRsZUhvcml6b250YWxTd2lwZSgpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pc1N3aXBlSW5Qcm9ncmVzcykge1xuICAgICAgdGhpcy5zdGFydFggPSB0aGlzLnV0aWxzLmdldFN0YXJ0WChldmVudCk7XG4gICAgICB0aGlzLnN0YXJ0VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA9IHRoaXMuZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzU3dpcGVJblByb2dyZXNzID0gdHJ1ZTtcbiAgICB0aGlzLm1vdmVYID0gdGhpcy51dGlscy5nZXRNb3ZlWChldmVudCk7XG4gICAgdGhpcy5tb3ZlKCk7XG4gIH1cblxuICBoYW5kbGVUb3VjaGVuZChzaW1wbGVQcm9jZXNzaW5nID0gZmFsc2UpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8qIElmIHRvdWNoZW5kIHdhcyBwYXNzZWQgdG8gdGhlIFNsaWRlIGNsYXNzICovXG4gICAgaWYgKHNpbXBsZVByb2Nlc3NpbmcpIHtcbiAgICAgIHRoaXMuaXNTd2lwZUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmlzU3dpcGVJblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5maW5pc2hNb3ZpbmcoKTtcbiAgICB0aGlzLmNsZWFySW5pdGlhbFZhbHVlcygpO1xuICB9XG5cbiAgbW92ZSgpIHtcbiAgICBsZXQgcG9zaXRpb25YOiBudW1iZXIgPSB0aGlzLmdldE1vdmVQb3NpdGlvblgoKTtcbiAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gdGhpcy5nZXREaXJlY3Rpb24oKTtcblxuICAgIGlmIChpc1B1bGxlZCkge1xuICAgICAgaWYgKFxuICAgICAgICAoaXNQdWxsZWQuZWRnZSA9PT0gJ2xlZnQnICYmIGRpcmVjdGlvbiA9PT0gJ3JpZ2h0JykgfHxcbiAgICAgICAgKGlzUHVsbGVkLmVkZ2UgPT09ICdyaWdodCcgJiYgZGlyZWN0aW9uID09PSAnbGVmdCcpXG4gICAgICApIHtcbiAgICAgICAgcG9zaXRpb25YID0gdGhpcy5zbG93ZG93bk9uUHVsbChwb3NpdGlvblgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb25YKHBvc2l0aW9uWCwgMCk7XG5cbiAgICBpZiAodGhpcy5mcmVlU2Nyb2xsKSB7XG4gICAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvblg7XG4gICAgfVxuXG4gICAgaWYgKGlzUHVsbGVkKSB7XG4gICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ2xlZnQnICYmIGlzUHVsbGVkLm92ZXJmbG93WCA+IHRoaXMucHVsbExpbWl0KSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbFBvc2l0aW9uWCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ3JpZ2h0JyAmJiBpc1B1bGxlZC5vdmVyZmxvd1ggPiB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvblg7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0TW92ZVBvc2l0aW9uWCgpIHtcbiAgICBjb25zdCBkaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UoKTtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCAtIGRpc3RhbmNlO1xuICB9XG5cbiAgZ2V0RGlzdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRYIC0gdGhpcy5tb3ZlWDtcbiAgfVxuXG4gIC8qIElmIHRoZSBjb250YWluZXIgaXMgcHVsbGVkIG91dCBvZiB0aGUgbGVmdCBvciByaWdodCBib3JkZXIgKi9cbiAgZGV0ZWN0UHVsbGVkKCkge1xuICAgIGNvbnN0IGN1cnJlbnRQb3NpdGlvblggPSB0aGlzLmdldEN1cnJlbnRQb3NpdGlvblgoKTtcblxuICAgIGlmIChjdXJyZW50UG9zaXRpb25YID4gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWRnZTogJ2xlZnQnLFxuICAgICAgICBwb3NpdGlvblg6IGN1cnJlbnRQb3NpdGlvblgsXG4gICAgICAgIG92ZXJmbG93WDogTWF0aC5hYnMoY3VycmVudFBvc2l0aW9uWClcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRQb3NpdGlvblggPCB0aGlzLmdldEVuZFBvc2l0aW9uKCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVkZ2U6ICdyaWdodCcsXG4gICAgICAgIHBvc2l0aW9uWDogY3VycmVudFBvc2l0aW9uWCxcbiAgICAgICAgb3ZlcmZsb3dYOiBNYXRoLmFicyhjdXJyZW50UG9zaXRpb25YIC0gdGhpcy5nZXRFbmRQb3NpdGlvbigpKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgc2xvd2Rvd25PblB1bGwoX3Bvc2l0aW9uWDogbnVtYmVyKSB7XG4gICAgbGV0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5nZXREaXN0YW5jZSgpKTtcbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IHRoaXMuZ2V0RW5kUG9zaXRpb24oKTtcbiAgICBjb25zdCBpc1B1bGxlZCA9IHRoaXMuZGV0ZWN0UHVsbGVkKCk7XG5cbiAgICBpZiAoIWlzUHVsbGVkKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCBkZWNlbGVyYXRpb25SYXRpbyA9IDMgKyBpc1B1bGxlZC5vdmVyZmxvd1ggLyA1MDtcbiAgICBsZXQgcG9zaXRpb25YID0gMDtcblxuICAgIGlmIChpc1B1bGxlZC5lZGdlID09PSAnbGVmdCcpIHtcbiAgICAgIGlmICh0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YIDwgMCkge1xuICAgICAgICBkaXN0YW5jZSAtPSBNYXRoLmFicyh0aGlzLmluaXRpYWxFbGVtZW50UG9zaXRpb25YKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcnViYmVyUG9zaXRpb25YID0gZGlzdGFuY2UgLyBkZWNlbGVyYXRpb25SYXRpbztcbiAgICAgIHBvc2l0aW9uWCA9IHJ1YmJlclBvc2l0aW9uWDtcblxuICAgICAgaWYgKHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggPiAwKSB7XG4gICAgICAgIHBvc2l0aW9uWCA9IHRoaXMuaW5pdGlhbEVsZW1lbnRQb3NpdGlvblggKyBydWJiZXJQb3NpdGlvblg7XG4gICAgICB9XG5cbiAgICAgIGlmIChwb3NpdGlvblggPiB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICBwb3NpdGlvblggPSB0aGlzLnB1bGxMaW1pdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNQdWxsZWQuZWRnZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgY29uc3QgcnViYmVyUG9zaXRpb25YID1cbiAgICAgICAgZW5kUG9zaXRpb24gK1xuICAgICAgICAodGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCAtIGRpc3RhbmNlIC0gZW5kUG9zaXRpb24pIC9cbiAgICAgICAgICBkZWNlbGVyYXRpb25SYXRpbztcbiAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5nZXRXaWR0aCgpO1xuXG4gICAgICBwb3NpdGlvblggPSBydWJiZXJQb3NpdGlvblg7XG5cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCA8IC0oY29udGFpbmVyV2lkdGggLSB0aGlzLnZpc2libGVXaWR0aClcbiAgICAgICkge1xuICAgICAgICBwb3NpdGlvblggPVxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoIC1cbiAgICAgICAgICB0aGlzLnZpc2libGVXaWR0aCArXG4gICAgICAgICAgdGhpcy5pbml0aWFsRWxlbWVudFBvc2l0aW9uWCArXG4gICAgICAgICAgcnViYmVyUG9zaXRpb25YO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9zaXRpb25YIDwgZW5kUG9zaXRpb24gLSB0aGlzLnB1bGxMaW1pdCkge1xuICAgICAgICBwb3NpdGlvblggPSBlbmRQb3NpdGlvbiAtIHRoaXMucHVsbExpbWl0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb3NpdGlvblg7XG4gIH1cblxuICBmaW5pc2hNb3ZpbmcoKSB7XG4gICAgY29uc3QgcG9zaXRpb25YID0gdGhpcy5nZXRNb3ZlUG9zaXRpb25YKCk7XG4gICAgbGV0IG5ld1Bvc2l0aW9uWCA9IDA7XG5cbiAgICBpZiAodGhpcy5mcmVlU2Nyb2xsKSB7XG4gICAgICBuZXdQb3NpdGlvblggPSB0aGlzLmdldEluZXJ0aWEoKTtcbiAgICB9XG5cbiAgICAvKiBBbGlnbiBjb250YWluZXIgd2hpbGUgcHVsbGluZyAqL1xuICAgIG5ld1Bvc2l0aW9uWCA9IHRoaXMuZ2V0QWxpZ25lZFBvc2l0aW9uT25QdWxsKG5ld1Bvc2l0aW9uWCk7XG5cbiAgICB0aGlzLnRyYW5zZm9ybVBvc2l0aW9uWChuZXdQb3NpdGlvblgpO1xuICAgIHRoaXMuc2V0SW5pdGlhbFBvc2l0aW9uKHBvc2l0aW9uWCk7XG4gIH1cblxuICAvKiBSZXR1cm5zIHRoZSBuZXcgcG9zaXRpb24gb2YgdGhlIGNvbnRhaW5lciB3aXRoIGluZXJ0aWEgKi9cbiAgZ2V0SW5lcnRpYSgpIHtcbiAgICBjb25zdCBkaXN0YW5jZSA9IHRoaXMuZ2V0RGlzdGFuY2UoKTtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IHRhcExlbmd0aCA9IGN1cnJlbnRUaW1lIC0gdGhpcy5zdGFydFRpbWU7XG4gICAgY29uc3QgaW5lcnRpYSA9IChkaXN0YW5jZSAvIHRhcExlbmd0aCkgKiAxMDA7XG5cbiAgICByZXR1cm4gdGhpcy5pbml0aWFsUG9zaXRpb25YIC0gaW5lcnRpYTtcbiAgfVxuXG4gIGdldEFsaWduZWRQb3NpdGlvbk9uUHVsbChuZXdQb3NpdGlvblg6IG51bWJlcikge1xuICAgIGNvbnN0IGRpcmVjdGlvbiA9IHRoaXMuZ2V0RGlyZWN0aW9uKCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gdGhpcy5nZXRFbmRQb3NpdGlvbigpO1xuICAgICAgaWYgKG5ld1Bvc2l0aW9uWCA8IGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHJldHVybiBlbmRQb3NpdGlvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3UG9zaXRpb25YO1xuICB9XG5cbiAgZ2V0Q3VycmVudFBvc2l0aW9uWCgpIHtcbiAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuZWxlbWVudCEucGFyZW50RWxlbWVudCEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIHBvc2l0aW9uLmxlZnQgLSBwYXJlbnRQb3NpdGlvbi5sZWZ0O1xuICB9XG5cbiAgZ2V0RW5kUG9zaXRpb24oKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgY29uc3QgdmlzaWJsZVdpZHRoID0gdGhpcy5lbGVtZW50IS5wYXJlbnRFbGVtZW50IS5jbGllbnRXaWR0aDtcbiAgICByZXR1cm4gdmlzaWJsZVdpZHRoIC0gd2lkdGg7XG4gIH1cblxuICB0cmFuc2Zvcm1Qb3NpdGlvblgodmFsdWU6IG51bWJlciwgZHVyYXRpb24gPSB0aGlzLnRyYW5zaXRpb25EdXJhdGlvbikge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSBgdHJhbnNmb3JtICR7ZHVyYXRpb259bXMgJHt0aGlzLnRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbn1gO1xuICAgIHRoaXMuZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke3ZhbHVlfXB4KWA7XG4gIH1cblxuICBnZXRXaWR0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5jZWxsTGVuZ3RoICogdGhpcy5mdWxsQ2VsbFdpZHRoO1xuICB9XG5cbiAgc2V0V2lkdGgoKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgdGhpcy5lbGVtZW50LnN0eWxlLndpZHRoID0gYCR7d2lkdGh9cHhgO1xuICB9XG5cbiAgc2V0SW5pdGlhbFBvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLmluaXRpYWxQb3NpdGlvblggPSBwb3NpdGlvbjtcbiAgfVxuXG4gIGdldEVsZW1lbnRQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB9XG5cbiAgZ2V0SW5pdGlhbEVsZW1lbnRQb3NpdGlvblgoKSB7XG4gICAgY29uc3QgY2Fyb3VzZWxFbGVtZW50UG9zaXRpb24gPVxuICAgICAgdGhpcy51dGlscy5nZXRDYXJvdXNlbEVsZW1lbnRQb3NpdGlvbigpLmxlZnQ7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudFBvc2l0aW9uKCkubGVmdCAtIGNhcm91c2VsRWxlbWVudFBvc2l0aW9uO1xuICB9XG5cbiAgY2xlYXJJbml0aWFsVmFsdWVzKCkge1xuICAgIHRoaXMuc3RhcnRYID0gdGhpcy5tb3ZlWCA9IDA7XG4gIH1cblxuICBnZXREaXJlY3Rpb24oKSB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gTWF0aC5zaWduKHRoaXMuc3RhcnRYIC0gdGhpcy5tb3ZlWCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAtMSkge1xuICAgICAgcmV0dXJuICdyaWdodCc7XG4gICAgfVxuICAgIGlmIChkaXJlY3Rpb24gPT09IDEpIHtcbiAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19