@labsforge/flipbook
Version:
A simple angular flipbook component written in typescript
413 lines • 63.6 kB
JavaScript
import { Power2, TimelineLite, TweenLite } from 'gsap';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil, tap } from 'rxjs/operators';
import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';
import { PageType } from '../interfaces';
import * as i0 from "@angular/core";
import * as i1 from "../flipbook.service";
import * as i2 from "../page/page.component";
import * as i3 from "@angular/common";
import * as i4 from "../pipes/reverse.pipe";
const DEFAULT_BACKGROUND_COLOR = '#fff';
export class BookComponent {
constructor(service, cdr, elr) {
this.service = service;
this.cdr = cdr;
this.elr = elr;
this.currentIndex = 0;
this.destroyed = new Subject();
this.navigationQueue = [];
this.render = () => { this.cdr.detectChanges(); };
this.sortBook = (index) => {
this.navigationQueue.shift();
if (this.flipTimeLine && this.navigationQueue.length > 0) {
return;
}
const page = this.pages.find(p => p.index === index);
this.currentIndex = page
? page.rotation < -90 ? page.index : page.index - 1
: index;
this.pages.sort((a, b) => {
const diffa = Math.abs(a.index - this.currentIndex) + (a.rotation === -180 ? 1 : 0);
const diffb = Math.abs(b.index - this.currentIndex);
return diffa - diffb;
});
this.render();
this.service.currentPage.next(this.currentIndex + 1);
};
this.setPageAtTop = (page) => {
this.pages.unshift(this.pages.splice(this.pages.indexOf(page), 1)[0]);
};
cdr.detach();
service.prev.pipe(takeUntil(this.destroyed)).subscribe(() => this.navigate(-1));
service.next.pipe(takeUntil(this.destroyed)).subscribe(() => this.navigate(1));
service.play.pipe(takeUntil(this.destroyed)).subscribe(() => this.play());
service.pause.pipe(takeUntil(this.destroyed)).subscribe(() => this.pause());
service.goTo.pipe(takeUntil(this.destroyed)).subscribe(index => this.goTo(index));
}
get hostWidth() {
this.cdr.detectChanges();
return this.model.width * this.model.zoom;
}
get hostHeight() {
return this.model.height * this.model.zoom;
}
get hostPerspective() {
return this.model.width * this.model.zoom * 2;
}
ngOnInit() {
// TODO: Implement startPageType / endPageType
this.pages = [];
const pages = this.model.pages.slice();
const hasCover = this.model && this.model.cover !== undefined;
const pageWidth = this.model.pageWidth || this.model.width / 2;
const pageHeight = this.model.pageHeight || this.model.height;
if (this.model && pages.length > 1) {
if (!hasCover && this.model.startPageType === PageType.Single) {
// add first white page block
this.pages.push({
index: this.pages.length,
lock: true,
front: {
imageUrl: '',
width: pageWidth,
height: pageHeight,
backgroundColor: DEFAULT_BACKGROUND_COLOR
},
back: {
imageUrl: '',
width: pageWidth,
height: pageHeight,
backgroundColor: DEFAULT_BACKGROUND_COLOR
},
rotation: -180
});
}
else {
const frontCover = {
index: this.pages.length,
lock: !hasCover,
front: hasCover ? {
imageUrl: this.model.cover.front.imageUrl,
isCover: true,
width: this.model.width / 2,
height: this.model.height,
backgroundColor: this.model.cover.front.backgroundColor,
opacity: this.model.cover.front.opacity,
} : undefined,
back: {
imageUrl: '',
backgroundColor: hasCover ? this.model.cover.front.backgroundColor : DEFAULT_BACKGROUND_COLOR,
opacity: hasCover ? this.model.cover.front.opacity : 1,
width: pageWidth,
height: pageHeight,
},
rotation: hasCover ? 0 : -180
};
if (this.model.startPageType !== PageType.Single) {
const firstPage = pages.shift();
frontCover.back.imageUrl = firstPage.imageUrl;
frontCover.back.backgroundColor = firstPage.backgroundColor;
frontCover.back.opacity = firstPage.opacity;
}
this.pages.push(frontCover);
}
while (pages.length > 1) {
const frontPage = pages.shift();
const backPage = pages.shift();
this.pages.push({
index: this.pages.length,
front: {
imageUrl: frontPage.imageUrl,
width: pageWidth,
height: pageHeight,
backgroundColor: frontPage.backgroundColor,
opacity: frontPage.opacity,
},
back: {
imageUrl: backPage.imageUrl,
width: pageWidth,
height: pageHeight,
backgroundColor: backPage.backgroundColor,
opacity: backPage.opacity,
},
rotation: 0
});
}
if (!hasCover && this.model.endPageType === PageType.Single) {
// add last white page block
this.pages.push({
index: this.pages.length,
lock: true,
front: {
imageUrl: '',
width: pageWidth,
height: pageHeight,
backgroundColor: DEFAULT_BACKGROUND_COLOR
},
back: {
imageUrl: '',
width: pageWidth,
height: pageHeight,
backgroundColor: DEFAULT_BACKGROUND_COLOR
},
rotation: 0
});
}
else {
const backCover = {
index: this.pages.length,
lock: !hasCover,
front: {
imageUrl: '',
backgroundColor: hasCover ? this.model.cover.back.backgroundColor : DEFAULT_BACKGROUND_COLOR,
opacity: hasCover ? this.model.cover.back.opacity : 1,
width: pageWidth,
height: pageHeight,
},
back: this.model.cover ? {
imageUrl: this.model.cover.back.imageUrl,
isCover: true,
width: this.model.width / 2,
height: this.model.height,
backgroundColor: this.model.cover.back.backgroundColor,
opacity: this.model.cover.back.opacity,
} : undefined,
rotation: 0
};
if (this.model.startPageType !== PageType.Single && pages.length) {
const lastPage = pages.shift();
backCover.front.imageUrl = lastPage.imageUrl;
backCover.front.backgroundColor = lastPage.backgroundColor;
backCover.front.opacity = lastPage.opacity;
}
this.pages.push(backCover);
}
}
if (this.startAt !== undefined && this.startAt !== this.currentIndex) {
this.goTo(this.startAt);
}
else {
this.sortBook(this.currentIndex - 1);
}
}
ngOnDestroy() {
this.destroyed.next();
}
update() {
this.render();
}
onPageDown(event, page) {
if (TweenLite.getTweensOf(page, true).length > 0) {
return;
}
if (page.lock) {
this.flipTimeLine = new TimelineLite({ autoRemoveChildren: true });
this.flipTimeLine.add(TweenLite.to(page, 0.3, {
rotation: page.rotation < -90 ? -175 : -5,
ease: Power2.easeOut,
onUpdate: this.render
}));
this.flipTimeLine.add(TweenLite.to(page, 0.2, {
rotation: page.rotation < -90 ? -180 : 0,
ease: Power2.easeOut,
onUpdate: this.render
}));
return;
}
const startX = event.pageX;
const startY = event.pageY;
let hasMoved = false;
const mouseUpEvt = fromEvent(document, 'mouseup')
.pipe(tap(() => {
this.flipTimeLine = new TimelineLite({ autoRemoveChildren: true });
if (!hasMoved) {
this.navigationQueue.push(page.rotation < -90 ? page.index - 1 : page.index);
this.flipTimeLine.add(TweenLite.to(page, 1, {
rotation: page.rotation < -90 ? 0 : -180,
ease: Power2.easeOut,
onStart: this.setPageAtTop,
onStartParams: [page],
onUpdate: this.render,
onComplete: this.sortBook,
onCompleteParams: [page.rotation < -90 ? page.index - 1 : page.index]
}));
}
else {
this.navigationQueue.push(page.rotation < -90 ? page.index : page.index - 1);
this.flipTimeLine.add(TweenLite.to(page, 1, {
rotation: page.rotation < -90 ? -180 : 0,
ease: Power2.easeOut,
onUpdate: this.render,
onComplete: this.sortBook,
onCompleteParams: [page.rotation < -90 ? page.index : page.index - 1]
}));
}
}));
fromEvent(document, 'mousemove')
.pipe(takeUntil(mouseUpEvt))
.subscribe(movEvt => {
const movEvent = movEvt;
const bookBounds = this.elr.nativeElement.getBoundingClientRect();
hasMoved = startX !== movEvent.pageX || startY !== movEvent.pageY;
this.setPageAtTop(page);
if (movEvent.pageX < bookBounds.left) {
page.rotation = -180;
}
else if (movEvent.pageX > bookBounds.left + bookBounds.width) {
page.rotation = 0;
}
else {
page.rotation = -180 + ((movEvent.pageX - bookBounds.left) / bookBounds.width) * 180;
}
this.render();
});
}
onPagePan(event, page) {
if (TweenLite.getTweensOf(page, true).length > 0) {
return;
}
if (page.lock) {
this.flipTimeLine = new TimelineLite();
this.flipTimeLine.add(TweenLite.to(page, 0.3, {
rotation: page.rotation < -90 ? -175 : -5,
ease: Power2.easeOut,
onUpdate: this.render
}));
this.flipTimeLine.add(TweenLite.to(page, 0.2, {
rotation: page.rotation < -90 ? -180 : 0,
ease: Power2.easeOut,
onUpdate: this.render
}));
return;
}
this.setPageAtTop(page);
const bookBounds = this.elr.nativeElement.getBoundingClientRect();
if (event.center.x < bookBounds.left) {
page.rotation = -180;
}
else if (event.center.x > bookBounds.left + bookBounds.width) {
page.rotation = 0;
}
else {
page.rotation = -180 + ((event.center.x - bookBounds.left) / bookBounds.width) * 180;
}
this.render();
}
onPagePanEnd(event, page) {
this.flipTimeLine = new TimelineLite();
this.flipTimeLine.add(TweenLite.to(page, 1, {
rotation: page.rotation < -90 ? -180 : 0,
ease: Power2.easeOut,
onUpdate: this.render,
onComplete: this.sortBook,
onCompleteParams: [page.rotation < -90 ? page.index : page.index - 1]
}));
}
onSwipe(event, page) {
if (page.lock) {
return;
}
if (TweenLite.getTweensOf(page, true).length > 0) {
TweenLite.getTweensOf(page, true)[0].kill();
}
const direction = event.deltaX > 0 ? -1 : 1;
this.flipTimeLine.add(TweenLite.to(page, 1, {
rotation: direction === 1 ? -180 : 0,
ease: Power2.easeOut,
onUpdate: this.render,
onComplete: this.sortBook,
onCompleteParams: [this.currentIndex + direction]
}));
}
navigate(direction) {
const lastNavigationIndex = this.navigationQueue.length
? this.navigationQueue[this.navigationQueue.length - 1]
: this.currentIndex;
const pageIndex = direction === 1 ? lastNavigationIndex + 1 : lastNavigationIndex;
const page = this.pages.find(p => p.index === pageIndex);
if (page === undefined || page.lock) {
return;
}
if (direction === 1 && page.rotation === -180) {
return;
}
if (direction === -1 && page.rotation === 0) {
return;
}
this.navigationQueue.push(lastNavigationIndex + direction);
this.flipTimeLine = new TimelineLite({ autoRemoveChildren: true });
this.flipTimeLine.add(TweenLite.to(page, 1, {
rotation: direction === 1 ? -180 : 0,
ease: Power2.easeOut,
onStart: this.setPageAtTop,
onStartParams: [page],
onUpdate: this.render,
onComplete: lastNavigationIndex + direction < this.pages.length ? this.sortBook : void 0,
onCompleteParams: [lastNavigationIndex + direction]
}));
}
goTo(index) {
if (this.currentIndex === index - 1) {
return;
}
for (let i = 0; i < this.pages.length; i++) {
const page = this.pages.find(p => p.index === i);
page.rotation = i < index ? -180 : 0;
if (i <= index) {
this.setPageAtTop(page);
}
}
this.sortBook(index - 1);
}
play() {
if (this.flipTimeLine && this.flipTimeLine.totalDuration() > this.flipTimeLine.time()) {
this.flipTimeLine.resume(null, false);
}
else {
this.flipTimeLine = new TimelineLite({ autoRemoveChildren: true });
this.pages.forEach((page, index) => {
if (page.rotation === 0 && !page.lock) {
this.flipTimeLine.add(TweenLite.to(page, 1, {
delay: index - (page.rotation < -90 ? 0 : 1) === this.currentIndex ? 0 : 2.5,
rotation: -180,
ease: Power2.easeOut,
onStart: this.setPageAtTop,
onStartParams: [page],
onUpdate: this.render,
onComplete: page.index + 1 < this.pages.length ? this.sortBook : void 0,
onCompleteParams: [page.index + 1]
}));
}
});
}
}
pause() {
if (this.flipTimeLine) {
const tweens = this.flipTimeLine.getChildren(true, true, true, this.flipTimeLine.time());
if (tweens.length > 0) {
this.flipTimeLine.addPause(tweens[0].startTime());
}
}
}
}
BookComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BookComponent, deps: [{ token: i1.FlipbookService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
BookComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BookComponent, selector: "flipbook", inputs: { model: "model", startAt: "startAt" }, host: { properties: { "style.width.px": "this.hostWidth", "style.height.px": "this.hostHeight", "style.perspective.px": "this.hostPerspective" } }, ngImport: i0, template: "<flipbook-page *ngFor=\"let page of pages | reverse\"\r\n [page]=\"page\"\r\n [width]=\"model.width / 2\"\r\n [height]=\"model.height\"\r\n [zoom]=\"model.zoom\"\r\n [rotation]=\"page.rotation\"\r\n (mousedown)=\"onPageDown($event, page)\"\r\n (pan)=\"onPagePan($event, page)\"\r\n (panend)=\"onPagePanEnd($event, page)\"\r\n (swipe)=\"onSwipe($event, page)\">\r\n</flipbook-page>", styles: [":host{display:block;box-sizing:border-box;position:relative;perspective-origin:center}\n"], components: [{ type: i2.PageComponent, selector: "flipbook-page", inputs: ["page", "width", "height", "rotation", "zoom"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "reverse": i4.ReversePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BookComponent, decorators: [{
type: Component,
args: [{ selector: 'flipbook', changeDetection: ChangeDetectionStrategy.OnPush, template: "<flipbook-page *ngFor=\"let page of pages | reverse\"\r\n [page]=\"page\"\r\n [width]=\"model.width / 2\"\r\n [height]=\"model.height\"\r\n [zoom]=\"model.zoom\"\r\n [rotation]=\"page.rotation\"\r\n (mousedown)=\"onPageDown($event, page)\"\r\n (pan)=\"onPagePan($event, page)\"\r\n (panend)=\"onPagePanEnd($event, page)\"\r\n (swipe)=\"onSwipe($event, page)\">\r\n</flipbook-page>", styles: [":host{display:block;box-sizing:border-box;position:relative;perspective-origin:center}\n"] }]
}], ctorParameters: function () { return [{ type: i1.FlipbookService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { model: [{
type: Input
}], startAt: [{
type: Input
}], hostWidth: [{
type: HostBinding,
args: ['style.width.px']
}], hostHeight: [{
type: HostBinding,
args: ['style.height.px']
}], hostPerspective: [{
type: HostBinding,
args: ['style.perspective.px']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9mbGlwYm9vay1saWIvc3JjL2xpYi9ib29rL2Jvb2suY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZmxpcGJvb2stbGliL3NyYy9saWIvYm9vay9ib29rLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhELE9BQU8sRUFDTCx1QkFBdUIsRUFBcUIsU0FBUyxFQUFjLFdBQVcsRUFBRSxLQUFLLEVBQ3RGLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBNEIsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFHbkUsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLENBQUM7QUFTeEMsTUFBTSxPQUFPLGFBQWE7SUF3RHhCLFlBQW9CLE9BQXdCLEVBQVUsR0FBc0IsRUFBVSxHQUFlO1FBQWpGLFlBQU8sR0FBUCxPQUFPLENBQWlCO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFZO1FBbkNyRyxpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUdULGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRWhDLG9CQUFlLEdBQWEsRUFBRSxDQUFDO1FBRS9CLFdBQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdDLGFBQVEsR0FBRyxDQUFDLEtBQWEsRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFN0IsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFBRSxPQUFPO2FBQUU7WUFFckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSTtnQkFDdEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQztnQkFDbkQsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUVWLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN2QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDcEYsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFFcEQsT0FBTyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLENBQUMsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFBO1FBRU8saUJBQVksR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQzlCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFBO1FBSUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRWIsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRixPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FB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SUFDSCxDQUFDOzsyR0EzYlUsYUFBYTsrRkFBYixhQUFhLG9QQ3BCMUIsNGZBVWdCOzRGRFVILGFBQWE7a0JBUHpCLFNBQVM7K0JBRUUsVUFBVSxtQkFHSCx1QkFBdUIsQ0FBQyxNQUFNOytKQUl0QyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUdGLFNBQVM7c0JBRFosV0FBVzt1QkFBQyxnQkFBZ0I7Z0JBT3pCLFVBQVU7c0JBRGIsV0FBVzt1QkFBQyxpQkFBaUI7Z0JBTTFCLGVBQWU7c0JBRGxCLFdBQVc7dUJBQUMsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUG93ZXIyLCBUaW1lbGluZUxpdGUsIFR3ZWVuTGl0ZSB9IGZyb20gJ2dzYXAnO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0QmluZGluZywgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0XHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBCb29rLCBCb29rUGFnZVNpZGUsIFBhZ2UsIFBhZ2VUeXBlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IEZsaXBib29rU2VydmljZSB9IGZyb20gJy4uL2ZsaXBib29rLnNlcnZpY2UnO1xyXG5cclxuY29uc3QgREVGQVVMVF9CQUNLR1JPVU5EX0NPTE9SID0gJyNmZmYnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNvbXBvbmVudC1zZWxlY3RvclxyXG4gIHNlbGVjdG9yOiAnZmxpcGJvb2snLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9ib29rLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9ib29rLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcclxufSlcclxuZXhwb3J0IGNsYXNzIEJvb2tDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIEBJbnB1dCgpIG1vZGVsOiBCb29rO1xyXG4gIEBJbnB1dCgpIHN0YXJ0QXQ6IG51bWJlcjtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS53aWR0aC5weCcpXHJcbiAgZ2V0IGhvc3RXaWR0aCgpIHtcclxuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgIHJldHVybiB0aGlzLm1vZGVsLndpZHRoICogdGhpcy5tb2RlbC56b29tO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS5oZWlnaHQucHgnKVxyXG4gIGdldCBob3N0SGVpZ2h0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMubW9kZWwuaGVpZ2h0ICogdGhpcy5tb2RlbC56b29tO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS5wZXJzcGVjdGl2ZS5weCcpXHJcbiAgZ2V0IGhvc3RQZXJzcGVjdGl2ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLm1vZGVsLndpZHRoICogdGhpcy5tb2RlbC56b29tICogMjtcclxuICB9XHJcblxyXG4gIGN1cnJlbnRJbmRleCA9IDA7XHJcbiAgcGFnZXM6IFBhZ2VbXTtcclxuXHJcbiAgcHJpdmF0ZSBkZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gIHByaXZhdGUgZmxpcFRpbWVMaW5lOiBUaW1lbGluZUxpdGU7XHJcbiAgcHJpdmF0ZSBuYXZpZ2F0aW9uUXVldWU6IG51bWJlcltdID0gW107XHJcblxyXG4gIHByaXZhdGUgcmVuZGVyID0gKCkgPT4geyB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7IH07XHJcblxyXG4gIHByaXZhdGUgc29ydEJvb2sgPSAoaW5kZXg6IG51bWJlcikgPT4ge1xyXG4gICAgdGhpcy5uYXZpZ2F0aW9uUXVldWUuc2hpZnQoKTtcclxuXHJcbiAgICBpZiAodGhpcy5mbGlwVGltZUxpbmUgJiYgdGhpcy5uYXZpZ2F0aW9uUXVldWUubGVuZ3RoID4gMCkgeyByZXR1cm47IH1cclxuXHJcbiAgICBjb25zdCBwYWdlID0gdGhpcy5wYWdlcy5maW5kKHAgPT4gcC5pbmRleCA9PT0gaW5kZXgpO1xyXG4gICAgdGhpcy5jdXJyZW50SW5kZXggPSBwYWdlXHJcbiAgICAgID8gcGFnZS5yb3RhdGlvbiA8IC05MCA/IHBhZ2UuaW5kZXggOiBwYWdlLmluZGV4IC0gMVxyXG4gICAgICA6IGluZGV4O1xyXG5cclxuICAgIHRoaXMucGFnZXMuc29ydCgoYSwgYikgPT4ge1xyXG4gICAgICBjb25zdCBkaWZmYSA9IE1hdGguYWJzKGEuaW5kZXggLSB0aGlzLmN1cnJlbnRJbmRleCkgKyAoYS5yb3RhdGlvbiA9PT0gLTE4MCA/IDEgOiAwKTtcclxuICAgICAgY29uc3QgZGlmZmIgPSBNYXRoLmFicyhiLmluZGV4IC0gdGhpcy5jdXJyZW50SW5kZXgpO1xyXG5cclxuICAgICAgcmV0dXJuIGRpZmZhIC0gZGlmZmI7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLnJlbmRlcigpO1xyXG4gICAgdGhpcy5zZXJ2aWNlLmN1cnJlbnRQYWdlLm5leHQodGhpcy5jdXJyZW50SW5kZXggKyAxKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0UGFnZUF0VG9wID0gKHBhZ2UpID0+IHtcclxuICAgIHRoaXMucGFnZXMudW5zaGlmdCh0aGlzLnBhZ2VzLnNwbGljZSh0aGlzLnBhZ2VzLmluZGV4T2YocGFnZSksIDEpWzBdKTtcclxuICB9XHJcblxyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlcnZpY2U6IEZsaXBib29rU2VydmljZSwgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIGVscjogRWxlbWVudFJlZikge1xyXG4gICAgY2RyLmRldGFjaCgpO1xyXG5cclxuICAgIHNlcnZpY2UucHJldi5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLm5hdmlnYXRlKC0xKSk7XHJcbiAgICBzZXJ2aWNlLm5leHQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5uYXZpZ2F0ZSgxKSk7XHJcbiAgICBzZXJ2aWNlLnBsYXkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5wbGF5KCkpO1xyXG4gICAgc2VydmljZS5wYXVzZS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLnBhdXNlKCkpO1xyXG4gICAgc2VydmljZS5nb1RvLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSkuc3Vic2NyaWJlKGluZGV4ID0+IHRoaXMuZ29UbyhpbmRleCkpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgc3RhcnRQYWdlVHlwZSAvIGVuZFBhZ2VUeXBlXHJcbiAgICB0aGlzLnBhZ2VzID0gW107XHJcblxyXG4gICAgY29uc3QgcGFnZXMgPSB0aGlzLm1vZGVsLnBhZ2VzLnNsaWNlKCk7XHJcbiAgICBjb25zdCBoYXNDb3ZlciA9IHRoaXMubW9kZWwgJiYgdGhpcy5tb2RlbC5jb3ZlciAhPT0gdW5kZWZpbmVkO1xyXG4gICAgY29uc3QgcGFnZVdpZHRoID0gdGhpcy5tb2RlbC5wYWdlV2lkdGggfHwgdGhpcy5tb2RlbC53aWR0aCAvIDI7XHJcbiAgICBjb25zdCBwYWdlSGVpZ2h0ID0gdGhpcy5tb2RlbC5wYWdlSGVpZ2h0IHx8IHRoaXMubW9kZWwuaGVpZ2h0O1xyXG5cclxuICAgIGlmICh0aGlzLm1vZGVsICYmIHBhZ2VzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgaWYgKCFoYXNDb3ZlciAmJiB0aGlzLm1vZGVsLnN0YXJ0UGFnZVR5cGUgPT09IFBhZ2VUeXBlLlNpbmdsZSkge1xyXG4gICAgICAgIC8vIGFkZCBmaXJzdCB3aGl0ZSBwYWdlIGJsb2NrXHJcbiAgICAgICAgdGhpcy5wYWdlcy5wdXNoKHtcclxuICAgICAgICAgIGluZGV4OiB0aGlzLnBhZ2VzLmxlbmd0aCxcclxuICAgICAgICAgIGxvY2s6IHRydWUsXHJcbiAgICAgICAgICBmcm9udDoge1xyXG4gICAgICAgICAgICBpbWFnZVVybDogJycsXHJcbiAgICAgICAgICAgIHdpZHRoOiBwYWdlV2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogcGFnZUhlaWdodCxcclxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1JcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBiYWNrOiB7XHJcbiAgICAgICAgICAgIGltYWdlVXJsOiAnJyxcclxuICAgICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0OiBwYWdlSGVpZ2h0LFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IERFRkFVTFRfQkFDS0dST1VORF9DT0xPUlxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHJvdGF0aW9uOiAtMTgwXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZnJvbnRDb3ZlcjogUGFnZSA9IHtcclxuICAgICAgICAgIGluZGV4OiB0aGlzLnBhZ2VzLmxlbmd0aCxcclxuICAgICAgICAgIGxvY2s6ICFoYXNDb3ZlcixcclxuICAgICAgICAgIGZyb250OiBoYXNDb3ZlciA/IHtcclxuICAgICAgICAgICAgaW1hZ2VVcmw6IHRoaXMubW9kZWwuY292ZXIuZnJvbnQuaW1hZ2VVcmwsXHJcbiAgICAgICAgICAgIGlzQ292ZXI6IHRydWUsXHJcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLm1vZGVsLndpZHRoIC8gMixcclxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLm1vZGVsLmhlaWdodCxcclxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLm1vZGVsLmNvdmVyLmZyb250LmJhY2tncm91bmRDb2xvcixcclxuICAgICAgICAgICAgb3BhY2l0eTogdGhpcy5tb2RlbC5jb3Zlci5mcm9udC5vcGFjaXR5LFxyXG4gICAgICAgICAgfSA6IHVuZGVmaW5lZCxcclxuICAgICAgICAgIGJhY2s6IHtcclxuICAgICAgICAgICAgaW1hZ2VVcmw6ICcnLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGhhc0NvdmVyID8gdGhpcy5tb2RlbC5jb3Zlci5mcm9udC5iYWNrZ3JvdW5kQ29sb3IgOiBERUZBVUxUX0JBQ0tHUk9VTkRfQ09MT1IsXHJcbiAgICAgICAgICAgIG9wYWNpdHk6IGhhc0NvdmVyID8gdGhpcy5tb2RlbC5jb3Zlci5mcm9udC5vcGFjaXR5IDogMSxcclxuICAgICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0OiBwYWdlSGVpZ2h0LFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHJvdGF0aW9uOiBoYXNDb3ZlciA/IDAgOiAtMTgwXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMubW9kZWwuc3RhcnRQYWdlVHlwZSAhPT0gUGFnZVR5cGUuU2luZ2xlKSB7XHJcbiAgICAgICAgICBjb25zdCBmaXJzdFBhZ2U6IEJvb2tQYWdlU2lkZSA9IHBhZ2VzLnNoaWZ0KCk7XHJcbiAgICAgICAgICBmcm9udENvdmVyLmJhY2suaW1hZ2VVcmwgPSBmaXJzdFBhZ2UuaW1hZ2VVcmw7XHJcbiAgICAgICAgICBmcm9udENvdmVyLmJhY2suYmFja2dyb3VuZENvbG9yID0gZmlyc3RQYWdlLmJhY2tncm91bmRDb2xvcjtcclxuICAgICAgICAgIGZyb250Q292ZXIuYmFjay5vcGFjaXR5ID0gZmlyc3RQYWdlLm9wYWNpdHk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBhZ2VzLnB1c2goZnJvbnRDb3Zlcik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHdoaWxlIChwYWdlcy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgY29uc3QgZnJvbnRQYWdlOiBCb29rUGFnZVNpZGUgPSBwYWdlcy5zaGlmdCgpO1xyXG4gICAgICAgIGNvbnN0IGJhY2tQYWdlOiBCb29rUGFnZVNpZGUgPSBwYWdlcy5zaGlmdCgpO1xyXG4gICAgICAgIHRoaXMucGFnZXMucHVzaCh7XHJcbiAgICAgICAgICBpbmRleDogdGhpcy5wYWdlcy5sZW5ndGgsXHJcbiAgICAgICAgICBmcm9udDoge1xyXG4gICAgICAgICAgICBpbWFnZVVybDogZnJvbnRQYWdlLmltYWdlVXJsLFxyXG4gICAgICAgICAgICB3aWR0aDogcGFnZVdpZHRoLFxyXG4gICAgICAgICAgICBoZWlnaHQ6IHBhZ2VIZWlnaHQsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogZnJvbnRQYWdlLmJhY2tncm91bmRDb2xvcixcclxuICAgICAgICAgICAgb3BhY2l0eTogZnJvbnRQYWdlLm9wYWNpdHksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgYmFjazoge1xyXG4gICAgICAgICAgICBpbWFnZVVybDogYmFja1BhZ2UuaW1hZ2VVcmwsXHJcbiAgICAgICAgICAgIHdpZHRoOiBwYWdlV2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogcGFnZUhlaWdodCxcclxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBiYWNrUGFnZS5iYWNrZ3JvdW5kQ29sb3IsXHJcbiAgICAgICAgICAgIG9wYWNpdHk6IGJhY2tQYWdlLm9wYWNpdHksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgcm90YXRpb246IDBcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFoYXNDb3ZlciAmJiB0aGlzLm1vZGVsLmVuZFBhZ2VUeXBlID09PSBQYWdlVHlwZS5TaW5nbGUpIHtcclxuICAgICAgICAvLyBhZGQgbGFzdCB3aGl0ZSBwYWdlIGJsb2NrXHJcbiAgICAgICAgdGhpcy5wYWdlcy5wdXNoKHtcclxuICAgICAgICAgIGluZGV4OiB0aGlzLnBhZ2VzLmxlbmd0aCxcclxuICAgICAgICAgIGxvY2s6IHRydWUsXHJcbiAgICAgICAgICBmcm9udDoge1xyXG4gICAgICAgICAgI