UNPKG

slider-carousel

Version:

Angular component of the carousel, using the slider as a transition. This is a simple, clean and light alternative. It also does not need dependencies.

334 lines 53 kB
import { Component, OnInit, HostBinding, Input, ElementRef, ViewChild, OnDestroy, OnChanges, Renderer2, AfterViewChecked } from '@angular/core'; import { DomSanitizer, SafeUrl, SafeStyle } from '@angular/platform-browser'; import { Helper } from './helper'; export class SliderCarouselComponent { constructor(sanitizer, renderer, helper) { this.sanitizer = sanitizer; this.renderer = renderer; this.helper = helper; this.class = true; this.images = []; this.preview = true; this.height = '500px'; this.width = '100%'; this.maxWidth = '100%'; this.autoSize = false; this.safeImages = []; this.initialized = false; this.currentImageIndex = 0; this.lastDirectionIsRight = false; this.containerWidth = 0; this.destroyed = false; this.windowResizing = false; this.listeners = []; this.drag = { state: 'none', startOffset: 0, currentOffset: 0, startLeft: 0, currentLeft: 0, }; } get currentImage() { return this.safeImages[this.currentImageIndex]; } get currentIsFisrt() { return this.currentImageIndex === 0; } get currentIsLast() { return this.currentImageIndex === (this.images.length - 1); } get isDragging() { return this.drag.state !== 'none'; } ngOnInit() { } ngOnChanges() { this.prepare(); } prepare() { if (typeof this.height !== 'string') this.height = '500px'; else if (!this.height.endsWith('%') && !this.height.endsWith('px')) this.height += 'px'; if (typeof this.width !== 'string') this.width = '100%'; else if (!this.width.endsWith('%') && !this.width.endsWith('px')) this.width += 'px'; if (typeof this.maxWidth !== 'string') this.maxWidth = '100%'; else if (!this.maxWidth.endsWith('%') && !this.maxWidth.endsWith('px')) this.maxWidth += 'px'; this.initialized = true; this.checkImages(); this.initSlideDragWatching(); this.ngAfterViewChecked(); } ngAfterViewChecked() { if (!this.windowResizing) { let width = 0; if (this.sectionEl && this.sectionEl.nativeElement) width = this.sectionEl.nativeElement.clientWidth; if (width !== this.containerWidth) this.containerWidth = width; } } checkImages() { if (this.images && this.images.length) { if (typeof this.images[0] !== 'string') { this.images.forEach((image) => { if (!image.md) image.md = image.lg; if (!image.sm) image.sm = image.md; }); } else { this.images = this.images.map((image) => { return { lg: image, md: image, sm: image }; }); } this.safeImages = this.images.map((image) => { var _a, _b, _c, _d, _e, _f; let sizes = { lg: { url: ((_a = image.lg) === null || _a === void 0 ? void 0 : _a.startsWith('http')) ? this.sanitizer.bypassSecurityTrustUrl(image.lg) : image.lg, style: ((_b = image.lg) === null || _b === void 0 ? void 0 : _b.startsWith('http')) ? this.sanitizer.bypassSecurityTrustStyle(`url('${image.lg}')`) : `url('${image.lg}')`, pure: image.lg }, md: { url: ((_c = image.md) === null || _c === void 0 ? void 0 : _c.startsWith('http')) ? this.sanitizer.bypassSecurityTrustUrl(image.md) : image.md, style: ((_d = image.md) === null || _d === void 0 ? void 0 : _d.startsWith('http')) ? this.sanitizer.bypassSecurityTrustStyle(`url('${image.md}')`) : `url('${image.md}')`, pure: image.md }, sm: { url: ((_e = image.sm) === null || _e === void 0 ? void 0 : _e.startsWith('http')) ? this.sanitizer.bypassSecurityTrustUrl(image.sm) : image.sm, style: ((_f = image.sm) === null || _f === void 0 ? void 0 : _f.startsWith('http')) ? this.sanitizer.bypassSecurityTrustStyle(`url('${image.sm}')`) : `url('${image.sm}')`, pure: image.sm } }; return sizes; }); } else { this.safeImages = []; } } initSlideDragWatching() { if (this.innerImagesEl && this.innerImagesEl.nativeElement) { this.stopSlideDragWatching(); if (this.helper.isMobileDevice()) this.listeners = [ this.renderer.listen(document.body, 'touchstart', this.onStartDrag.bind(this)), this.renderer.listen(document.body, 'touchmove', this.onDragging.bind(this)), this.renderer.listen(document.body, 'touchend', this.onEndDrag.bind(this)) ]; else this.listeners = [ this.renderer.listen(document.body, 'mousedown', this.onStartDrag.bind(this)), this.renderer.listen(document.body, 'mousemove', this.onDragging.bind(this)), this.renderer.listen(document.body, 'mouseup', this.onEndDrag.bind(this)), ]; } else setTimeout(() => this.initSlideDragWatching(), 200); } stopSlideDragWatching() { if (this.listeners && this.listeners.length) this.listeners.forEach((unListen) => unListen()); } previewImage(image) { if (!this.previewRef) { this.previewRef = this.helper.openPreview({ image: { pureUrl: image.lg.pure, safeUrl: image.lg.url, } }); this.previewRef.onClose.subscribe(() => this.previewRef = null); } } selectImage(imageIndex, event) { if (imageIndex !== this.currentImageIndex) { this.lastDirectionIsRight = imageIndex > this.currentImageIndex; this.currentImageIndex = imageIndex; if (event.target && this.imageListEl && this.imageListEl.nativeElement) this.scrollingToElement(event.target, this.lastDirectionIsRight); } } goPrevImage(salt = 0) { if (this.currentImageIndex > 0) { if (salt) { if ((this.currentImageIndex - salt) >= 0) this.currentImageIndex -= salt + 1; else this.currentImageIndex = 0; } else this.currentImageIndex--; this.lastDirectionIsRight = false; let target = this.imageListEl.nativeElement.children[0].children[this.currentImageIndex]; if (this.imageListEl && this.imageListEl.nativeElement) this.scrollingToElement(target, this.lastDirectionIsRight); } } goNextImage(salt = 0) { if ((this.currentImageIndex + 1) < this.images.length) { if (salt) { if ((this.currentImageIndex + salt + 1) <= (this.images.length - 1)) this.currentImageIndex = salt + 1; else this.currentImageIndex = this.images.length; } else this.currentImageIndex++; this.lastDirectionIsRight = true; let target = this.imageListEl.nativeElement.children[0].children[this.currentImageIndex]; if (this.imageListEl && this.imageListEl.nativeElement) this.scrollingToElement(target, this.lastDirectionIsRight); } } scrollingToElement(element, directionIsRight) { let scrollElement = this.imageListEl.nativeElement; if (scrollElement && scrollElement.scrollWidth > 0) { let blockWidth = element.clientWidth + 14; let scrollLeft = element.offsetLeft - 14; let scrollRight = element.offsetLeft + element.clientWidth + 14; let currentScrollLeft = scrollElement.scrollLeft; let currentScrollRight = scrollElement.scrollLeft + scrollElement.clientWidth; let scroll = .1; if (directionIsRight && (currentScrollRight - scrollRight) < Math.floor(blockWidth / 2)) scroll = currentScrollLeft + blockWidth + 100; else if (!directionIsRight && (scrollLeft - currentScrollLeft) < Math.floor(blockWidth / 2)) scroll = currentScrollLeft - blockWidth; if (scroll !== .1) { if (this.timerSroll) clearInterval(this.timerSroll); this.timerSroll = this.helper.smoothScroll(scrollElement, scroll, 400, 'left'); } } } onKeydown(event) { if (!this.destroyed && !this.isDragging && [37, 39].indexOf(event.keyCode) >= 0) { if (event.keyCode === 37) this.goPrevImage(); else this.goNextImage(); if (this.previewRef) this.previewRef.instance.onImageChange({ pureUrl: this.currentImage.lg.pure, safeUrl: this.currentImage.lg.url, }); } } onWindowResize() { if (!this.destroyed && !this.windowResizing) { this.windowResizing = true; setTimeout(() => { this.containerWidth = this.sectionEl.nativeElement.clientWidth; setTimeout(() => { this.windowResizing = false; setTimeout(() => { if (this.imageListEl && this.imageListEl.nativeElement) { let target = this.imageListEl.nativeElement.children[0].children[this.currentImageIndex]; if (this.imageListEl && this.imageListEl.nativeElement) this.scrollingToElement(target, this.lastDirectionIsRight); } }, 100); }); }); } } onStartDrag(event) { let isTouching = false; if (event.touches) { isTouching = true; event = event.touches[0]; } if (isTouching || event.button === 0) { if (this.helper.elementIsChild(event.target, this.sectionEl.nativeElement)) { this.drag.startLeft = this.innerImagesEl.nativeElement.offsetLeft; this.drag.currentLeft = this.innerImagesEl.nativeElement.offsetLeft; this.drag.startOffset = event.clientX; this.drag.currentOffset = event.clientX; this.drag.state = 'start'; } } } onDragging(event) { if (event.touches) event = event.touches[0]; if (this.drag.state === 'start' || this.drag.state === 'dragging') { this.drag.state = 'dragging'; this.drag.currentOffset = event.clientX; if (this.drag.startOffset !== this.drag.currentOffset) { let draggingRight = this.drag.currentOffset > this.drag.startOffset; let delta = Math.abs(this.drag.currentOffset - this.drag.startOffset) * .8; if (((draggingRight && this.currentIsFisrt) || (!draggingRight && this.currentIsLast)) && delta > Math.floor(this.containerWidth / 3)) delta = Math.floor(this.containerWidth / 3); this.drag.currentLeft = this.drag.startLeft + ((draggingRight ? 1 : -1) * delta); } else this.drag.currentLeft = this.drag.startLeft; } } onEndDrag(event) { let isTouching = false; if (event.touches) { isTouching = true; event = event.touches[0]; } if (isTouching || event.button === 0) { let amountDragged = Math.abs(this.drag.startOffset - this.drag.currentOffset); if (this.drag.state === 'dragging' && amountDragged > 0) setTimeout(() => { this.drag.state = 'none'; let minDreg = 70; if (amountDragged >= minDreg) { let draggingRight = this.drag.currentOffset > this.drag.startOffset; let salts = (amountDragged / this.sectionEl.nativeElement.clientWidth) - 1; if (salts >= 1) salts = Math.floor(salts); else salts = 0; if (draggingRight && !this.currentIsFisrt) this.goPrevImage(salts); else if (!draggingRight && !this.currentIsLast) this.goNextImage(salts); } }); else { this.drag.state = 'none'; } } } ngOnDestroy() { this.destroyed = true; this.stopSlideDragWatching(); } } SliderCarouselComponent.ctorParameters = () => [ { type: DomSanitizer }, { type: Renderer2 }, { type: Helper } ]; SliderCarouselComponent.decorators = [ { type: Component, args: [{ selector: 'slider-carousel', template: "<section #section *ngIf=\"safeImages && safeImages.length\" [style.width]=\"width\" [style.maxWidth]=\"maxWidth\">\n <div *ngIf=\"!windowResizing && containerWidth > 0\" class=\"image-controller animated fadeIn\" [style.maxWidth.px]=\"containerWidth\">\n\n <!-- INNER CONTAINER -->\n <ul #innerImages *ngIf=\"!autoSize\"\n [ngClass]=\"{'dragging-effect': isDragging}\"\n\t\t\t[style.left.px]=\"isDragging ? drag.currentLeft : (-currentImageIndex * containerWidth)\"\n\t\t\t[style.width.px]=\"safeImages.length * containerWidth\"\n [style.height]=\"height\">\n <li *ngFor=\"let image of safeImages; let i = index;\"\n [style.backgroundImage]=\"image.md.style\"\n [style.width.px]=\"containerWidth\"\n [ngClass]=\"{'cursor-pointer': preview, 'is-current': i === currentImageIndex}\"\n (click)=\"!isDragging && previewImage(image)\">\n </li>\n </ul>\n <ul #innerImages *ngIf=\"autoSize\" [ngClass]=\"{'dragging-effect': isDragging}\" [style.left.px]=\"isDragging ? drag.currentLeft : (-currentImageIndex * containerWidth)\">\n <div *ngFor=\"let image of safeImages; let i = index;\" [style.width.px]=\"containerWidth\">\n\t\t\t\t<img [src]=\"image.md.url\" draggable=\"false\" [ngClass]=\"{'cursor-pointer': preview, 'is-current': i === currentImageIndex}\" (click)=\"!isDragging && previewImage(image)\"/>\n </div>\n </ul>\n\n <!-- NAVIGATION BUTTONS -->\n <div (click)=\"goPrevImage()\" class=\"image-controller-prev\" [ngClass]=\"{'disabled': currentImageIndex <= 0}\" role=\"button\">\n <svg viewBox=\"0 0 456 456\">\n <path d=\"M227.996,0C102.081,0,0,102.081,0,227.996c0,125.945,102.081,227.996,227.996,227.996\n\t\t\t\tc125.945,0,227.996-102.051,227.996-227.996C455.992,102.081,353.941,0,227.996,0z M299.435,238.788l-98.585,98.585\n\t\t\t\tc-5.928,5.897-15.565,5.897-21.492,0c-5.928-5.928-5.928-15.595,0-21.492l87.885-87.885l-87.885-87.885\n\t\t\t\tc-5.928-5.928-5.928-15.565,0-21.492s15.565-5.928,21.492,0l98.585,98.585c3.04,2.979,4.469,6.901,4.438,10.792\n\t\t\t\tC303.873,231.918,302.414,235.809,299.435,238.788z\"/>\n </svg> \n </div>\n <div (click)=\"goNextImage()\" class=\"image-controller-next\" [ngClass]=\"{'disabled': (currentImageIndex + 1) >= safeImages.length}\" role=\"button\">\n <svg viewBox=\"0 0 456 456\">\n <path d=\"M227.996,0C102.081,0,0,102.081,0,227.996c0,125.945,102.081,227.996,227.996,227.996\n\t\t\t\tc125.945,0,227.996-102.051,227.996-227.996C455.992,102.081,353.941,0,227.996,0z M299.435,238.788l-98.585,98.585\n\t\t\t\tc-5.928,5.897-15.565,5.897-21.492,0c-5.928-5.928-5.928-15.595,0-21.492l87.885-87.885l-87.885-87.885\n\t\t\t\tc-5.928-5.928-5.928-15.565,0-21.492s15.565-5.928,21.492,0l98.585,98.585c3.04,2.979,4.469,6.901,4.438,10.792\n\t\t\t\tC303.873,231.918,302.414,235.809,299.435,238.788z\"/>\n </svg> \n </div>\n\n </div>\n\n <!-- GALLERY NAVIGATION -->\n <div *ngIf=\"!windowResizing && containerWidth > 0\" #imageList class=\"footer-images animated fadeIn\" [style.maxWidth.px]=\"containerWidth\">\n <ul>\n <li matRipple (click)=\"selectImage(i, $event)\" *ngFor=\"let image of safeImages; let i = index;\"\n [ngClass]=\"{'is-current': i === currentImageIndex}\"\n [style.backgroundImage]=\"image.sm.style\">\n </li>\n </ul>\n </div>\n</section>", host: { '(document:keydown)': 'onKeydown($event)', '(window:resize)': 'onWindowResize()' } },] } ]; SliderCarouselComponent.ctorParameters = () => [ { type: DomSanitizer }, { type: Renderer2 }, { type: Helper } ]; SliderCarouselComponent.propDecorators = { class: [{ type: HostBinding, args: ['class.slider-carousel',] }], sectionEl: [{ type: ViewChild, args: ['section',] }], imageListEl: [{ type: ViewChild, args: ['imageList',] }], innerImagesEl: [{ type: ViewChild, args: ['innerImages',] }], images: [{ type: Input }], preview: [{ type: Input }], height: [{ type: Input }], width: [{ type: Input }], maxWidth: [{ type: Input, args: ['max-width',] }], autoSize: [{ type: Input, args: ['auto-size',] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLWNhcm91c2VsLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3NsaWRlci1jYXJvdXNlbC8iLCJzb3VyY2VzIjpbInNsaWRlci1jYXJvdXNlbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hKLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRzdFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFVbEMsTUFBTSxPQUFPLHVCQUF1QjtJQW9EbkMsWUFDUyxTQUF1QixFQUN2QixRQUFtQixFQUNuQixNQUFjO1FBRmQsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2QixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLFdBQU0sR0FBTixNQUFNLENBQVE7UUF0RHNCLFVBQUssR0FBWSxJQUFJLENBQUM7UUFNbkQsV0FBTSxHQUEwRCxFQUFFLENBQUM7UUFFbkUsWUFBTyxHQUFZLElBQUksQ0FBQztRQUN4QixXQUFNLEdBQVcsT0FBTyxDQUFDO1FBQ3pCLFVBQUssR0FBVyxNQUFNLENBQUM7UUFDWixhQUFRLEdBQVcsTUFBTSxDQUFDO1FBQzFCLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFFOUMsZUFBVSxHQUlYLEVBQUUsQ0FBQztRQUVGLGdCQUFXLEdBQVksS0FBSyxDQUFDO1FBRTdCLHNCQUFpQixHQUFXLENBQUMsQ0FBQztRQUM5Qix5QkFBb0IsR0FBWSxLQUFLLENBQUM7UUFJdEMsbUJBQWMsR0FBVyxDQUFDLENBQUM7UUFFMUIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUM1QixtQkFBYyxHQUFZLEtBQUssQ0FB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LG8vR0FBK0M7Z0JBQy9DLElBQUksRUFBRTtvQkFDTCxvQkFBb0IsRUFBRSxtQkFBbUI7b0JBQ3pDLGlCQUFpQixFQUFFLGtCQUFrQjtpQkFDckM7YUFDRDs7O1lBWlEsWUFBWTtZQUR3RSxTQUFTO1lBSTdGLE1BQU07OztvQkFXYixXQUFXLFNBQUMsdUJBQXVCO3dCQUVuQyxTQUFTLFNBQUMsU0FBUzswQkFDbkIsU0FBUyxTQUFDLFdBQVc7NEJBQ3JCLFNBQVMsU0FBQyxhQUFhO3FCQUV2QixLQUFLO3NCQUVMLEtBQUs7cUJBQ0wsS0FBSztvQkFDTCxLQUFLO3VCQUNMLEtBQUssU0FBQyxXQUFXO3VCQUNqQixLQUFLLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBIb3N0QmluZGluZywgSW5wdXQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgT25EZXN0cm95LCBPbkNoYW5nZXMsIFJlbmRlcmVyMiwgQWZ0ZXJWaWV3Q2hlY2tlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlVXJsLCBTYWZlU3R5bGUgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNsaWRlckNhcm91c2VsUHJldmlld0NvbXBvbmVudCB9IGZyb20gJy4vc2xpZGVyLWNhcm91c2VsLXByZXZpZXcvc2xpZGVyLWNhcm91c2VsLXByZXZpZXcuY29tcG9uZW50JztcbmltcG9ydCB7IEhlbHBlciB9IGZyb20gJy4vaGVscGVyJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnc2xpZGVyLWNhcm91c2VsJyxcblx0dGVtcGxhdGVVcmw6ICcuL3NsaWRlci1jYXJvdXNlbC5jb21wb25lbnQuaHRtbCcsXG5cdGhvc3Q6IHtcblx0XHQnKGRvY3VtZW50OmtleWRvd24pJzogJ29uS2V5ZG93bigkZXZlbnQpJyxcblx0XHQnKHdpbmRvdzpyZXNpemUpJzogJ29uV2luZG93UmVzaXplKCknXG5cdH1cbn0pXG5leHBvcnQgY2xhc3MgU2xpZGVyQ2Fyb3VzZWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBBZnRlclZpZXdDaGVja2VkIHtcblx0QEhvc3RCaW5kaW5nKCdjbGFzcy5zbGlkZXItY2Fyb3VzZWwnKSBwdWJsaWMgY2xhc3M6IGJvb2xlYW4gPSB0cnVlO1xuXG5cdEBWaWV3Q2hpbGQoJ3NlY3Rpb24nKSBwcml2YXRlIHNlY3Rpb25FbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cdEBWaWV3Q2hpbGQoJ2ltYWdlTGlzdCcpIHByaXZhdGUgaW1hZ2VMaXN0RWw6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXHRAVmlld0NoaWxkKCdpbm5lckltYWdlcycpIHByaXZhdGUgaW5uZXJJbWFnZXNFbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cblx0QElucHV0KCkgcHVibGljIGltYWdlczogeyBsZzogc3RyaW5nLCBtZD86IHN0cmluZywgc20/OiBzdHJpbmcgfVtdIHwgc3RyaW5nW10gPSBbXTtcblxuXHRASW5wdXQoKSBwdWJsaWMgcHJldmlldzogYm9vbGVhbiA9IHRydWU7XG5cdEBJbnB1dCgpIHB1YmxpYyBoZWlnaHQ6IHN0cmluZyA9ICc1MDBweCc7XG5cdEBJbnB1dCgpIHB1YmxpYyB3aWR0aDogc3RyaW5nID0gJzEwMCUnO1xuXHRASW5wdXQoJ21heC13aWR0aCcpIHB1YmxpYyBtYXhXaWR0aDogc3RyaW5nID0gJzEwMCUnO1xuXHRASW5wdXQoJ2F1dG8tc2l6ZScpIHB1YmxpYyBhdXRvU2l6ZTogYm9vbGVhbiA9IGZhbHNlO1xuXG5cdHB1YmxpYyBzYWZlSW1hZ2VzOiB7XG5cdFx0bGc6IHsgdXJsOiBTYWZlVXJsIHwgc3RyaW5nLCBzdHlsZTogU2FmZVN0eWxlIHwgc3RyaW5nLCBwdXJlOiBzdHJpbmcgfSxcblx0XHRtZDogeyB1cmw6IFNhZmVVcmwgfCBzdHJpbmcsIHN0eWxlOiBTYWZlU3R5bGUgfCBzdHJpbmcsIHB1cmU6IHN0cmluZyB9LFxuXHRcdHNtOiB7IHVybDogU2FmZVVybCB8IHN0cmluZywgc3R5bGU6IFNhZmVTdHlsZSB8IHN0cmluZywgcHVyZTogc3RyaW5nIH1cblx0fVtdID0gW107XG5cblx0cHVibGljIGluaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG5cblx0cHVibGljIGN1cnJlbnRJbWFnZUluZGV4OiBudW1iZXIgPSAwO1xuXHRwdWJsaWMgbGFzdERpcmVjdGlvbklzUmlnaHQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuXHRwcml2YXRlIHRpbWVyU3JvbGw6IGFueTtcblxuXHRwdWJsaWMgY29udGFpbmVyV2lkdGg6IG51bWJlciA9IDA7XG5cblx0cHJpdmF0ZSBkZXN0cm95ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblx0cHVibGljIHdpbmRvd1Jlc2l6aW5nOiBib29sZWFuID0gZmFsc2U7XG5cdHByaXZhdGUgcHJldmlld1JlZjoge1xuXHRcdG9uQ2xvc2U6IE9ic2VydmFibGU8YW55Pixcblx0XHRpbnN0YW5jZTogU2xpZGVyQ2Fyb3VzZWxQcmV2aWV3Q29tcG9uZW50XG5cdH07XG5cblx0cHJpdmF0ZSBsaXN0ZW5lcnM6ICgoKSA9PiB2b2lkKVtdID0gW107XG5cblx0cHVibGljIGdldCBjdXJyZW50SW1hZ2UoKSB7IHJldHVybiB0aGlzLnNhZmVJbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2VJbmRleF07IH1cblx0cHVibGljIGdldCBjdXJyZW50SXNGaXNydCgpIHsgcmV0dXJuIHRoaXMuY3VycmVudEltYWdlSW5kZXggPT09IDA7IH1cblx0cHVibGljIGdldCBjdXJyZW50SXNMYXN0KCkgeyByZXR1cm4gdGhpcy5jdXJyZW50SW1hZ2VJbmRleCA9PT0gKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpOyB9XG5cblx0cHVibGljIGdldCBpc0RyYWdnaW5nKCkgeyByZXR1cm4gdGhpcy5kcmFnLnN0YXRlICE9PSAnbm9uZSc7IH1cblx0cHVibGljIGRyYWcgPSB7XG5cdFx0c3RhdGU6ICdub25lJywgLy8gJ3N0YXJ0JywgJ2RyYWdnaW5nJywgJ25vbmUnXG5cdFx0c3RhcnRPZmZzZXQ6IDAsXG5cdFx0Y3VycmVudE9mZnNldDogMCxcblx0XHRzdGFydExlZnQ6IDAsXG5cdFx0Y3VycmVudExlZnQ6IDAsXG5cdH07XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcblx0XHRwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG5cdFx0cHJpdmF0ZSBoZWxwZXI6IEhlbHBlclxuXHQpIHtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHR9XG5cblx0bmdPbkNoYW5nZXMoKSB7XG5cdFx0dGhpcy5wcmVwYXJlKCk7XG5cdH1cblxuXHRwcml2YXRlIHByZXBhcmUoKSB7XG5cdFx0aWYgKHR5cGVvZiB0aGlzLmhlaWdodCAhPT0gJ3N0cmluZycpXG5cdFx0XHR0aGlzLmhlaWdodCA9ICc1MDBweCc7XG5cdFx0ZWxzZSBpZiAoIXRoaXMuaGVpZ2h0LmVuZHNXaXRoKCclJykgJiYgIXRoaXMuaGVpZ2h0LmVuZHNXaXRoKCdweCcpKVxuXHRcdFx0dGhpcy5oZWlnaHQgKz0gJ3B4JztcblxuXHRcdGlmICh0eXBlb2YgdGhpcy53aWR0aCAhPT0gJ3N0cmluZycpXG5cdFx0XHR0aGlzLndpZHRoID0gJzEwMCUnO1xuXHRcdGVsc2UgaWYgKCF0aGlzLndpZHRoLmVuZHNXaXRoKCclJykgJiYgIXRoaXMud2lkdGguZW5kc1dpdGgoJ3B4JykpXG5cdFx0XHR0aGlzLndpZHRoICs9ICdweCc7XG5cblx0XHRpZiAodHlwZW9mIHRoaXMubWF4V2lkdGggIT09ICdzdHJpbmcnKVxuXHRcdFx0dGhpcy5tYXhXaWR0aCA9ICcxMDAlJztcblx0XHRlbHNlIGlmICghdGhpcy5tYXhXaWR0aC5lbmRzV2l0aCgnJScpICYmICF0aGlzLm1heFdpZHRoLmVuZHNXaXRoKCdweCcpKVxuXHRcdFx0dGhpcy5tYXhXaWR0aCArPSAncHgnO1xuXG5cdFx0dGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG5cdFx0dGhpcy5jaGVja0ltYWdlcygpO1xuXHRcdHRoaXMuaW5pdFNsaWRlRHJhZ1dhdGNoaW5nKCk7XG5cdFx0dGhpcy5uZ0FmdGVyVmlld0NoZWNrZWQoKTtcblx0fVxuXG5cdG5nQWZ0ZXJWaWV3Q2hlY2tlZCgpOiB2b2lkIHtcblx0XHRpZiAoIXRoaXMud2luZG93UmVzaXppbmcpIHtcblx0XHRcdGxldCB3aWR0aCA9IDA7XG5cdFx0XHRpZiAodGhpcy5zZWN0aW9uRWwgJiYgdGhpcy5zZWN0aW9uRWwubmF0aXZlRWxlbWVudClcblx0XHRcdFx0d2lkdGggPSB0aGlzLnNlY3Rpb25FbC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xuXG5cdFx0XHRpZiAod2lkdGggIT09IHRoaXMuY29udGFpbmVyV2lkdGgpXG5cdFx0XHRcdHRoaXMuY29udGFpbmVyV2lkdGggPSB3aWR0aDtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGNoZWNrSW1hZ2VzKCkge1xuXHRcdGlmICh0aGlzLmltYWdlcyAmJiB0aGlzLmltYWdlcy5sZW5ndGgpIHtcblx0XHRcdGlmICh0eXBlb2YgdGhpcy5pbWFnZXNbMF0gIT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdCh0aGlzLmltYWdlcyBhcyB7IGxnOiBzdHJpbmcsIG1kPzogc3RyaW5nLCBzbT86IHN0cmluZyB9W10pLmZvckVhY2goKGltYWdlKSA9PiB7XG5cdFx0XHRcdFx0aWYgKCFpbWFnZS5tZClcblx0XHRcdFx0XHRcdGltYWdlLm1kID0gaW1hZ2UubGc7XG5cdFx0XHRcdFx0aWYgKCFpbWFnZS5zbSlcblx0XHRcdFx0XHRcdGltYWdlLnNtID0gaW1hZ2UubWQ7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdHRoaXMuaW1hZ2VzID0gKHRoaXMuaW1hZ2VzIGFzIHN0cmluZ1tdKS5tYXAoKGltYWdlKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHsgbGc6IGltYWdlLCBtZDogaW1hZ2UsIHNtOiBpbWFnZSB9O1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5zYWZlSW1hZ2VzID0gKHRoaXMuaW1hZ2VzIGFzIHsgbGc6IHN0cmluZywgbWQ6IHN0cmluZywgc206IHN0cmluZyB9W10pLm1hcCgoaW1hZ2UpID0+IHtcblx0XHRcdFx0bGV0IHNpemVzID0ge1xuXHRcdFx0XHRcdGxnOiB7IFxuXHRcdFx0XHRcdFx0dXJsOiBpbWFnZS5sZz8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFVybChpbWFnZS5sZykgOiBpbWFnZS5sZyxcblx0XHRcdFx0XHRcdHN0eWxlOiBpbWFnZS5sZz8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKGB1cmwoJyR7aW1hZ2UubGd9JylgKSA6IGB1cmwoJyR7aW1hZ2UubGd9JylgLFxuXHRcdFx0XHRcdFx0cHVyZTogaW1hZ2UubGdcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdG1kOiB7IFxuXHRcdFx0XHRcdFx0dXJsOiBpbWFnZS5tZD8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFVybChpbWFnZS5tZCkgOiBpbWFnZS5tZCxcblx0XHRcdFx0XHRcdHN0eWxlOiBpbWFnZS5tZD8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKGB1cmwoJyR7aW1hZ2UubWR9JylgKSA6IGB1cmwoJyR7aW1hZ2UubWR9JylgLFxuXHRcdFx0XHRcdFx0cHVyZTogaW1hZ2UubWRcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHNtOiB7IFxuXHRcdFx0XHRcdFx0dXJsOiBpbWFnZS5zbT8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFVybChpbWFnZS5zbSkgOiBpbWFnZS5zbSxcblx0XHRcdFx0XHRcdHN0eWxlOiBpbWFnZS5zbT8uc3RhcnRzV2l0aCgnaHR0cCcpID8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKGB1cmwoJyR7aW1hZ2Uuc219JylgKSA6IGB1cmwoJyR7aW1hZ2Uuc219JylgLFxuXHRcdFx0XHRcdFx0cHVyZTogaW1hZ2Uuc21cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHRcdHJldHVybiBzaXplcztcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdHRoaXMuc2FmZUltYWdlcyA9IFtdO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgaW5pdFNsaWRlRHJhZ1dhdGNoaW5nKCkge1xuXHRcdGlmICh0aGlzLmlubmVySW1hZ2VzRWwgJiYgdGhpcy5pbm5lckltYWdlc0VsLm5hdGl2ZUVsZW1lbnQpIHtcblx0XHRcdHRoaXMuc3RvcFNsaWRlRHJhZ1dhdGNoaW5nKCk7XG5cblx0XHRcdGlmICh0aGlzLmhlbHBlci5pc01vYmlsZURldmljZSgpKVxuXHRcdFx0XHR0aGlzLmxpc3RlbmVycyA9IFtcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudC5ib2R5LCAndG91Y2hzdGFydCcsIHRoaXMub25TdGFydERyYWcuYmluZCh0aGlzKSksXG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5saXN0ZW4oZG9jdW1lbnQuYm9keSwgJ3RvdWNobW92ZScsIHRoaXMub25EcmFnZ2luZy5iaW5kKHRoaXMpKSxcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudC5ib2R5LCAndG91Y2hlbmQnLCB0aGlzLm9uRW5kRHJhZy5iaW5kKHRoaXMpKVxuXHRcdFx0XHRdO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHR0aGlzLmxpc3RlbmVycyA9IFtcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudC5ib2R5LCAnbW91c2Vkb3duJywgdGhpcy5vblN0YXJ0RHJhZy5iaW5kKHRoaXMpKSxcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLmxpc3Rlbihkb2N1bWVudC5ib2R5LCAnbW91c2Vtb3ZlJywgdGhpcy5vbkRyYWdnaW5nLmJpbmQodGhpcykpLFxuXHRcdFx0XHRcdHRoaXMucmVuZGVyZXIubGlzdGVuKGRvY3VtZW50LmJvZHksICdtb3VzZXVwJywgdGhpcy5vbkVuZERyYWcuYmluZCh0aGlzKSksXG5cdFx0XHRcdF07XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4gdGhpcy5pbml0U2xpZGVEcmFnV2F0Y2hpbmcoKSwgMjAwKTtcblx0fVxuXG5cdHByaXZhdGUgc3RvcFNsaWRlRHJhZ1dhdGNoaW5nKCkge1xuXHRcdGlmICh0aGlzLmxpc3RlbmVycyAmJiB0aGlzLmxpc3RlbmVycy5sZW5ndGgpXG5cdFx0XHR0aGlzLmxpc3RlbmVycy5mb3JFYWNoKCh1bkxpc3RlbikgPT4gdW5MaXN0ZW4oKSk7XG5cdH1cblxuXHRwdWJsaWMgcHJldmlld0ltYWdlKGltYWdlOiBhbnkpIHtcblx0XHRpZiAoIXRoaXMucHJldmlld1JlZikge1xuXHRcdFx0dGhpcy5wcmV2aWV3UmVmID0gdGhpcy5oZWxwZXIub3BlblByZXZpZXcoe1xuXHRcdFx0XHRpbWFnZToge1xuXHRcdFx0XHRcdHB1cmVVcmw6IGltYWdlLmxnLnB1cmUsXG5cdFx0XHRcdFx0c2FmZVVybDogaW1hZ2UubGcudXJsLFxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0dGhpcy5wcmV2aWV3UmVmLm9uQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHRoaXMucHJldmlld1JlZiA9IG51bGwpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBzZWxlY3RJbWFnZShpbWFnZUluZGV4OiBudW1iZXIsIGV2ZW50KSB7XG5cdFx0aWYgKGltYWdlSW5kZXggIT09IHRoaXMuY3VycmVudEltYWdlSW5kZXgpIHtcblx0XHRcdHRoaXMubGFzdERpcmVjdGlvbklzUmlnaHQgPSBpbWFnZUluZGV4ID4gdGhpcy5jdXJyZW50SW1hZ2VJbmRleDtcblx0XHRcdHRoaXMuY3VycmVudEltYWdlSW5kZXggPSBpbWFnZUluZGV4O1xuXG5cdFx0XHRpZiAoZXZlbnQudGFyZ2V0ICYmIHRoaXMuaW1hZ2VMaXN0RWwgJiYgdGhpcy5pbWFnZUxpc3RFbC5uYXRpdmVFbGVtZW50KVxuXHRcdFx0XHR0aGlzLnNjcm9sbGluZ1RvRWxlbWVudChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQsIHRoaXMubGFzdERpcmVjdGlvbklzUmlnaHQpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBnb1ByZXZJbWFnZShzYWx0OiBudW1iZXIgPSAwKSB7XG5cdFx0aWYgKHRoaXMuY3VycmVudEltYWdlSW5kZXggPiAwKSB7XG5cdFx0XHRpZiAoc2FsdCkge1xuXHRcdFx0XHRpZiAoKHRoaXMuY3VycmVudEltYWdlSW5kZXggLSBzYWx0KSA+PSAwKVxuXHRcdFx0XHRcdHRoaXMuY3VycmVudEltYWdlSW5kZXggLT0gc2FsdCArIDE7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHR0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID0gMDtcblx0XHRcdH1cblx0XHRcdGVsc2Vcblx0XHRcdFx0dGhpcy5jdXJyZW50SW1hZ2VJbmRleC0tO1xuXG5cdFx0XHR0aGlzLmxhc3REaXJlY3Rpb25Jc1JpZ2h0ID0gZmFsc2U7XG5cblx0XHRcdGxldCB0YXJnZXQgPSB0aGlzLmltYWdlTGlzdEVsLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW5bMF0uY2hpbGRyZW5bdGhpcy5jdXJyZW50SW1hZ2VJbmRleF0gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHRpZiAodGhpcy5pbWFnZUxpc3RFbCAmJiB0aGlzLmltYWdlTGlzdEVsLm5hdGl2ZUVsZW1lbnQpXG5cdFx0XHRcdHRoaXMuc2Nyb2xsaW5nVG9FbGVtZW50KHRhcmdldCwgdGhpcy5sYXN0RGlyZWN0aW9uSXNSaWdodCk7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGdvTmV4dEltYWdlKHNhbHQ6IG51bWJlciA9IDApIHtcblx0XHRpZiAoKHRoaXMuY3VycmVudEltYWdlSW5kZXggKyAxKSA8IHRoaXMuaW1hZ2VzLmxlbmd0aCkge1xuXHRcdFx0aWYgKHNhbHQpIHtcblx0XHRcdFx0aWYgKCh0aGlzLmN1cnJlbnRJbWFnZUluZGV4ICsgc2FsdCArIDEpIDw9ICh0aGlzLmltYWdlcy5sZW5ndGggLSAxKSlcblx0XHRcdFx0XHR0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID0gc2FsdCArIDE7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHR0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID0gdGhpcy5pbWFnZXMubGVuZ3RoO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0XHR0aGlzLmN1cnJlbnRJbWFnZUluZGV4Kys7XG5cblx0XHRcdHRoaXMubGFzdERpcmVjdGlvbklzUmlnaHQgPSB0cnVlO1xuXG5cdFx0XHRsZXQgdGFyZ2V0ID0gdGhpcy5pbWFnZUxpc3RFbC5uYXRpdmVFbGVtZW50LmNoaWxkcmVuWzBdLmNoaWxkcmVuW3RoaXMuY3VycmVudEltYWdlSW5kZXhdIGFzIEhUTUxFbGVtZW50O1xuXHRcdFx0aWYgKHRoaXMuaW1hZ2VMaXN0RWwgJiYgdGhpcy5pbWFnZUxpc3RFbC5uYXRpdmVFbGVtZW50KVxuXHRcdFx0XHR0aGlzLnNjcm9sbGluZ1RvRWxlbWVudCh0YXJnZXQsIHRoaXMubGFzdERpcmVjdGlvbklzUmlnaHQpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgc2Nyb2xsaW5nVG9FbGVtZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBkaXJlY3Rpb25Jc1JpZ2h0OiBib29sZWFuKSB7XG5cdFx0bGV0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmltYWdlTGlzdEVsLm5hdGl2ZUVsZW1lbnQ7XG5cdFx0aWYgKHNjcm9sbEVsZW1lbnQgJiYgc2Nyb2xsRWxlbWVudC5zY3JvbGxXaWR0aCA+IDApe1xuXHRcdFx0bGV0IGJsb2NrV2lkdGggPSBlbGVtZW50LmNsaWVudFdpZHRoICsgMTQ7XG5cdFx0XHRsZXQgc2Nyb2xsTGVmdCA9IGVsZW1lbnQub2Zmc2V0TGVmdCAtIDE0O1xuXHRcdFx0bGV0IHNjcm9sbFJpZ2h0ID0gZWxlbWVudC5vZmZzZXRMZWZ0ICsgZWxlbWVudC5jbGllbnRXaWR0aCArIDE0O1xuXHRcdFx0bGV0IGN1cnJlbnRTY3JvbGxMZWZ0ID0gc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0O1xuXHRcdFx0bGV0IGN1cnJlbnRTY3JvbGxSaWdodCA9IHNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCArIHNjcm9sbEVsZW1lbnQuY2xpZW50V2lkdGg7XG5cblx0XHRcdGxldCBzY3JvbGwgPSAuMTtcblxuXHRcdFx0aWYgKGRpcmVjdGlvbklzUmlnaHQgJiYgKGN1cnJlbnRTY3JvbGxSaWdodCAtIHNjcm9sbFJpZ2h0KSA8IE1hdGguZmxvb3IoYmxvY2tXaWR0aCAvIDIpKVxuXHRcdFx0XHRzY3JvbGwgPSBjdXJyZW50U2Nyb2xsTGVmdCArIGJsb2NrV2lkdGggKyAxMDA7XG5cdFx0XHRlbHNlIGlmICghZGlyZWN0aW9uSXNSaWdodCAmJiAoc2Nyb2xsTGVmdCAtIGN1cnJlbnRTY3JvbGxMZWZ0KSA8IE1hdGguZmxvb3IoYmxvY2tXaWR0aCAvIDIpKVxuXHRcdFx0XHRzY3JvbGwgPSBjdXJyZW50U2Nyb2xsTGVmdCAtIGJsb2NrV2lkdGg7XG5cblx0XHRcdGlmIChzY3JvbGwgIT09IC4xKSB7XG5cdFx0XHRcdGlmICh0aGlzLnRpbWVyU3JvbGwpIGNsZWFySW50ZXJ2YWwodGhpcy50aW1lclNyb2xsKTtcblx0XHRcdFx0dGhpcy50aW1lclNyb2xsID0gdGhpcy5oZWxwZXIuc21vb3RoU2Nyb2xsKHNjcm9sbEVsZW1lbnQsIHNjcm9sbCwgNDAwLCAnbGVmdCcpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBvbktleWRvd24oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMuZGVzdHJveWVkICYmICF0aGlzLmlzRHJhZ2dpbmcgJiYgWzM3LCAzOV0uaW5kZXhPZihldmVudC5rZXlDb2RlKSA+PSAwKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMzcpXG4gICAgICAgICAgICAgICAgdGhpcy5nb1ByZXZJbWFnZSgpO1xuICAgICAgICAgICAgZWxzZVxuXHRcdFx0XHR0aGlzLmdvTmV4dEltYWdlKCk7XG5cdFx0XHRcdFxuXHRcdFx0aWYgKHRoaXMucHJldmlld1JlZilcblx0XHRcdFx0dGhpcy5wcmV2aWV3UmVmLmluc3RhbmNlLm9uSW1hZ2VDaGFuZ2Uoe1xuXHRcdFx0XHRcdHB1cmVVcmw6IHRoaXMuY3VycmVudEltYWdlLmxnLnB1cmUsXG5cdFx0XHRcdFx0c2FmZVVybDogdGhpcy5jdXJyZW50SW1hZ2UubGcudXJsLFxuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgb25XaW5kb3dSZXNpemUoKSB7XG5cdFx0aWYgKCF0aGlzLmRlc3Ryb3llZCAmJiAhdGhpcy53aW5kb3dSZXNpemluZykge1xuXHRcdFx0dGhpcy53aW5kb3dSZXNpemluZyA9IHRydWU7XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0dGhpcy5jb250YWluZXJXaWR0aCA9IHRoaXMuc2VjdGlvbkVsLm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XG5cdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMud2luZG93UmVzaXppbmcgPSBmYWxzZTtcblxuXHRcdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKHRoaXMuaW1hZ2VMaXN0RWwgJiYgdGhpcy5pbWFnZUxpc3RFbC5uYXRpdmVFbGVtZW50KSB7XG5cdFx0XHRcdFx0XHRcdGxldCB0YXJnZXQgPSB0aGlzLmltYWdlTGlzdEVsLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW5bMF0uY2hpbGRyZW5bdGhpcy5jdXJyZW50SW1hZ2VJbmRleF0gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLmltYWdlTGlzdEVsICYmIHRoaXMuaW1hZ2VMaXN0RWwubmF0aXZlRWxlbWVudClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNjcm9sbGluZ1RvRWxlbWVudCh0YXJnZXQsIHRoaXMubGFzdERpcmVjdGlvbklzUmlnaHQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0sIDEwMCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBvblN0YXJ0RHJhZyhldmVudCkge1xuXHRcdGxldCBpc1RvdWNoaW5nID0gZmFsc2U7XG5cdFx0aWYgKGV2ZW50LnRvdWNoZXMpIHtcblx0XHRcdGlzVG91Y2hpbmcgPSB0cnVlO1xuXHRcdFx0ZXZlbnQgPSBldmVudC50b3VjaGVzWzBdO1xuXHRcdH1cblx0XHRcblx0XHRpZiAoaXNUb3VjaGluZyB8fCBldmVudC5idXR0b24gPT09IDApIHtcblx0XHRcdGlmICh0aGlzLmhlbHBlci5lbGVtZW50SXNDaGlsZChldmVudC50YXJnZXQsIHRoaXMuc2VjdGlvbkVsLm5hdGl2ZUVsZW1lbnQpKSB7XG5cdFx0XHRcdHRoaXMuZHJhZy5zdGFydExlZnQgPSB0aGlzLmlubmVySW1hZ2VzRWwubmF0aXZlRWxlbWVudC5vZmZzZXRMZWZ0O1xuXHRcdFx0XHR0aGlzLm