UNPKG

angular2gridsterv3

Version:
352 lines (349 loc) 50.9 kB
import { Component, ViewChild, Input, Output, EventEmitter, ChangeDetectionStrategy, HostBinding, ViewEncapsulation } from '@angular/core'; import { Subscription, fromEvent } from 'rxjs'; import { debounceTime, filter, publish } from 'rxjs/operators'; import { utils } from './utils/utils'; import { GridsterService } from './gridster.service'; import { GridsterOptions } from './GridsterOptions'; import * as i0 from "@angular/core"; import * as i1 from "./gridster.service"; import * as i2 from "./gridster-prototype/gridster-prototype.service"; export class GridsterComponent { constructor(zone, elementRef, gridster, gridsterPrototype) { this.zone = zone; this.gridsterPrototype = gridsterPrototype; this.optionsChange = new EventEmitter(); this.ready = new EventEmitter(); this.reflow = new EventEmitter(); this.prototypeDrop = new EventEmitter(); this.prototypeEnter = new EventEmitter(); this.prototypeOut = new EventEmitter(); this.draggableOptions = {}; this.isDragging = false; this.isResizing = false; this.isReady = false; this.isPrototypeEntered = false; this.isDisabled = false; this.subscription = new Subscription(); this.gridster = gridster; this.$element = elementRef.nativeElement; } ngOnInit() { this.gridsterOptions = new GridsterOptions(this.options, this.$element); if (this.options.useCSSTransforms) { this.$element.classList.add('css-transform'); } this.subscription.add(this.gridsterOptions.change.subscribe(options => { this.gridster.options = options; if (this.gridster.gridList) { this.gridster.gridList.options = options; } setTimeout(() => this.optionsChange.emit(options)); })); this.gridster.init(this); this.subscription.add(fromEvent(window, 'resize') .pipe(debounceTime(this.gridster.options.responsiveDebounce || 0), filter(() => this.gridster.options.responsiveView)) .subscribe(() => this.reload())); this.zone.runOutsideAngular(() => { this.subscription.add(fromEvent(document, 'scroll', { passive: true }).subscribe(() => this.updateGridsterElementData())); const scrollableContainer = utils.getScrollableContainer(this.$element); if (scrollableContainer) { this.subscription.add(fromEvent(scrollableContainer, 'scroll', { passive: true }) .subscribe(() => this.updateGridsterElementData())); } }); } ngAfterContentInit() { this.gridster.start(); this.updateGridsterElementData(); this.connectGridsterPrototype(); this.gridster.$positionHighlight = this.$positionHighlight.nativeElement; } ngOnDestroy() { this.subscription.unsubscribe(); } /** * Change gridster config option and rebuild * @param string name * @param any value * @return GridsterComponent */ setOption(name, value) { if (name === 'dragAndDrop') { if (value) { this.enableDraggable(); } else { this.disableDraggable(); } } if (name === 'resizable') { if (value) { this.enableResizable(); } else { this.disableResizable(); } } if (name === 'lanes') { this.gridster.options.lanes = value; this.gridster.gridList.fixItemsPositions(this.gridster.options); this.reflowGridster(); } if (name === 'direction') { this.gridster.options.direction = value; this.gridster.gridList.pullItemsToLeft(); } if (name === 'widthHeightRatio') { this.gridster.options.widthHeightRatio = parseFloat(value || 1); } if (name === 'responsiveView') { this.gridster.options.responsiveView = !!value; } this.gridster.gridList.setOption(name, value); return this; } reload() { setTimeout(() => { this.gridster.fixItemsPositions(); this.reflowGridster(); }); return this; } reflowGridster(isInit = false) { this.gridster.reflow(); this.reflow.emit({ isInit: isInit, gridsterComponent: this }); } updateGridsterElementData() { this.gridster.gridsterScrollData = this.getScrollPositionFromParents(this.$element); this.gridster.gridsterRect = this.$element.getBoundingClientRect(); } setReady() { setTimeout(() => (this.isReady = true)); this.ready.emit(); } adjustItemsHeightToContent(scrollableItemElementSelector = '.gridster-item-inner') { this.gridster.items // convert each item to object with information about content height and scroll height .map((item) => { const scrollEl = item.$element.querySelector(scrollableItemElementSelector); const contentEl = scrollEl.lastElementChild; const scrollElDistance = utils.getRelativeCoordinates(scrollEl, item.$element); const scrollElRect = scrollEl.getBoundingClientRect(); const contentRect = contentEl.getBoundingClientRect(); return { item, contentHeight: contentRect.bottom - scrollElRect.top, scrollElDistance }; }) // calculate required height in lanes amount and update item "h" .forEach(data => { data.item.h = Math.ceil(((data.contentHeight / (this.gridster.cellHeight - data.scrollElDistance.top)))); }); this.gridster.fixItemsPositions(); this.gridster.reflow(); } disable(item) { const itemIdx = this.gridster.items.indexOf(item.itemComponent); this.isDisabled = true; if (itemIdx >= 0) { delete this.gridster.items[this.gridster.items.indexOf(item.itemComponent)]; } this.gridster.onDragOut(item); } enable() { this.isDisabled = false; } getScrollPositionFromParents(element, data = { scrollTop: 0, scrollLeft: 0 }) { if (element.parentElement && element.parentElement !== document.body) { data.scrollTop += element.parentElement.scrollTop; data.scrollLeft += element.parentElement.scrollLeft; return this.getScrollPositionFromParents(element.parentElement, data); } return { scrollTop: data.scrollTop, scrollLeft: data.scrollLeft }; } /** * Connect gridster prototype item to gridster dragging hooks (onStart, onDrag, onStop). */ connectGridsterPrototype() { this.gridsterPrototype.observeDropOut(this.gridster).subscribe(); const dropOverObservable = (this.gridsterPrototype .observeDropOver(this.gridster) .pipe(publish())); const dragObservable = this.gridsterPrototype.observeDragOver(this.gridster); dragObservable.dragOver .pipe(filter(() => !this.isDisabled)) .subscribe((prototype) => { if (!this.isPrototypeEntered) { return; } this.gridster.onDrag(prototype.item); }); dragObservable.dragEnter .pipe(filter(() => !this.isDisabled)) .subscribe((prototype) => { this.isPrototypeEntered = true; if (this.gridster.items.indexOf(prototype.item) < 0) { this.gridster.items.push(prototype.item); } this.gridster.onStart(prototype.item); prototype.setDragContextGridster(this.gridster); if (this.parent) { this.parent.disable(prototype.item); } this.prototypeEnter.emit({ item: prototype.item }); }); dragObservable.dragOut .pipe(filter(() => !this.isDisabled)) .subscribe((prototype) => { if (!this.isPrototypeEntered) { return; } this.gridster.onDragOut(prototype.item); this.isPrototypeEntered = false; this.prototypeOut.emit({ item: prototype.item }); if (this.parent) { this.parent.enable(); this.parent.isPrototypeEntered = true; if (this.parent.gridster.items.indexOf(prototype.item) < 0) { this.parent.gridster.items.push(prototype.item); } this.parent.gridster.onStart(prototype.item); prototype.setDragContextGridster(this.parent.gridster); // timeout is needed to be sure that "enter" event is fired after "out" setTimeout(() => { this.parent.prototypeEnter.emit({ item: prototype.item }); prototype.onEnter(this.parent.gridster); }); } }); dropOverObservable .pipe(filter(() => !this.isDisabled)) .subscribe(data => { if (!this.isPrototypeEntered) { return; } this.gridster.onStop(data.item.item); this.gridster.removeItem(data.item.item); this.isPrototypeEntered = false; if (this.parent) { this.parent.enable(); } this.prototypeDrop.emit({ item: data.item.item }); }); dropOverObservable.connect(); } enableDraggable() { this.gridster.options.dragAndDrop = true; this.gridster.items .filter(item => item.itemComponent && item.itemComponent.dragAndDrop) .forEach((item) => item.itemComponent.enableDragDrop()); } disableDraggable() { this.gridster.options.dragAndDrop = false; this.gridster.items .filter(item => item.itemComponent) .forEach((item) => item.itemComponent.disableDraggable()); } enableResizable() { this.gridster.options.resizable = true; this.gridster.items .filter(item => item.itemComponent && item.itemComponent.resizable) .forEach((item) => item.itemComponent.enableResizable()); } disableResizable() { this.gridster.options.resizable = false; this.gridster.items.forEach((item) => item.itemComponent.disableResizable()); } } GridsterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GridsterComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i1.GridsterService }, { token: i2.GridsterPrototypeService }], target: i0.ɵɵFactoryTarget.Component }); GridsterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: GridsterComponent, selector: "ngx-gridster", inputs: { options: "options", draggableOptions: "draggableOptions", parent: "parent" }, outputs: { optionsChange: "optionsChange", ready: "ready", reflow: "reflow", prototypeDrop: "prototypeDrop", prototypeEnter: "prototypeEnter", prototypeOut: "prototypeOut" }, host: { properties: { "class.gridster--dragging": "this.isDragging", "class.gridster--resizing": "this.isResizing", "class.gridster--ready": "this.isReady" } }, providers: [GridsterService], viewQueries: [{ propertyName: "$positionHighlight", first: true, predicate: ["positionHighlight"], descendants: true, static: true }], ngImport: i0, template: `<div class="gridster-container"> <ng-content></ng-content> <div class="position-highlight" style="display:none;" #positionHighlight> <div class="inner"></div> </div> </div>`, isInline: true, styles: ["ngx-gridster{position:relative;display:block;left:0;width:100%}ngx-gridster.gridster--dragging{-moz-user-select:none;-webkit-user-select:none;user-select:none}ngx-gridster .gridster-container{position:relative;width:100%;list-style:none;transition:width .2s,height .2s}ngx-gridster .position-highlight{display:block;position:absolute;z-index:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GridsterComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-gridster', template: `<div class="gridster-container"> <ng-content></ng-content> <div class="position-highlight" style="display:none;" #positionHighlight> <div class="inner"></div> </div> </div>`, styles: [ ` ngx-gridster { position: relative; display: block; left: 0; width: 100%; } ngx-gridster.gridster--dragging { -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; } ngx-gridster .gridster-container { position: relative; width: 100%; list-style: none; -webkit-transition: width 0.2s, height 0.2s; transition: width 0.2s, height 0.2s; } ngx-gridster .position-highlight { display: block; position: absolute; z-index: 1; } ` ], providers: [GridsterService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }] }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i1.GridsterService }, { type: i2.GridsterPrototypeService }]; }, propDecorators: { options: [{ type: Input }], optionsChange: [{ type: Output }], ready: [{ type: Output }], reflow: [{ type: Output }], prototypeDrop: [{ type: Output }], prototypeEnter: [{ type: Output }], prototypeOut: [{ type: Output }], draggableOptions: [{ type: Input }], parent: [{ type: Input }], $positionHighlight: [{ type: ViewChild, args: ['positionHighlight', { static: true }] }], isDragging: [{ type: HostBinding, args: ['class.gridster--dragging'] }], isResizing: [{ type: HostBinding, args: ['class.gridster--resizing'] }], isReady: [{ type: HostBinding, args: ['class.gridster--ready'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhcjJncmlkc3RlcnYzL3NyYy9saWIvZ3JpZHN0ZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCxTQUFTLEVBS1QsU0FBUyxFQUVULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLHVCQUF1QixFQUN2QixXQUFXLEVBQ1gsaUJBQWlCLEVBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFSCxZQUFZLEVBQ1osU0FBUyxFQUVaLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFL0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFNckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7O0FBOENwRCxNQUFNLE9BQU8saUJBQWlCO0lBd0IxQixZQUNZLElBQVksRUFDcEIsVUFBc0IsRUFDdEIsUUFBeUIsRUFDakIsaUJBQTJDO1FBSDNDLFNBQUksR0FBSixJQUFJLENBQVE7UUFHWixzQkFBaUIsR0FBakIsaUJBQWlCLENBQTBCO1FBMUI3QyxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDeEMsVUFBSyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDaEMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDakMsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBMEIsQ0FBQztRQUMzRCxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUEwQixDQUFDO1FBQzVELGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQTBCLENBQUM7UUFDM0QscUJBQWdCLEdB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USxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFrQixFQUFFLEVBQUUsQ0FDL0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUN4QyxDQUFDO0lBQ04sQ0FBQzs7OEdBaFhRLGlCQUFpQjtrR0FBakIsaUJBQWlCLCtjQUpmLENBQUMsZUFBZSxDQUFDLGlLQXRDbEI7Ozs7O1dBS0g7MkZBcUNFLGlCQUFpQjtrQkE1QzdCLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLGNBQWM7b0JBQ3hCLFFBQVEsRUFBRTs7Ozs7V0FLSDtvQkFDUCxNQUFNLEVBQUU7d0JBQ0o7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1NBNkJDO3FCQUNKO29CQUNELFNBQVMsRUFBRSxDQUFDLGVBQWUsQ0FBQztvQkFDNUIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO2lCQUN4QzsyTEFFWSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNFLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRTRDLGtCQUFrQjtzQkFBbkUsU0FBUzt1QkFBQyxtQkFBbUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ1AsVUFBVTtzQkFBbEQsV0FBVzt1QkFBQywwQkFBMEI7Z0JBQ0UsVUFBVTtzQkFBbEQsV0FBVzt1QkFBQywwQkFBMEI7Z0JBRUQsT0FBTztzQkFBNUMsV0FBVzt1QkFBQyx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgT25Jbml0LFxyXG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBWaWV3Q2hpbGQsXHJcbiAgICBOZ1pvbmUsXHJcbiAgICBJbnB1dCxcclxuICAgIE91dHB1dCxcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBWaWV3RW5jYXBzdWxhdGlvblxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gICAgT2JzZXJ2YWJsZSxcclxuICAgIFN1YnNjcmlwdGlvbixcclxuICAgIGZyb21FdmVudCxcclxuICAgIENvbm5lY3RhYmxlT2JzZXJ2YWJsZVxyXG59IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGZpbHRlciwgcHVibGlzaCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IHV0aWxzIH0gZnJvbSAnLi91dGlscy91dGlscyc7XHJcbmltcG9ydCB7IEdyaWRzdGVyU2VydmljZSB9IGZyb20gJy4vZ3JpZHN0ZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IElHcmlkc3Rlck9wdGlvbnMgfSBmcm9tICcuL0lHcmlkc3Rlck9wdGlvbnMnO1xyXG5pbXBvcnQgeyBJR3JpZHN0ZXJEcmFnZ2FibGVPcHRpb25zIH0gZnJvbSAnLi9JR3JpZHN0ZXJEcmFnZ2FibGVPcHRpb25zJztcclxuaW1wb3J0IHsgR3JpZHN0ZXJQcm90b3R5cGVTZXJ2aWNlIH0gZnJvbSAnLi9ncmlkc3Rlci1wcm90b3R5cGUvZ3JpZHN0ZXItcHJvdG90eXBlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBHcmlkc3Rlckl0ZW1Qcm90b3R5cGVEaXJlY3RpdmUgfSBmcm9tICcuL2dyaWRzdGVyLXByb3RvdHlwZS9ncmlkc3Rlci1pdGVtLXByb3RvdHlwZS5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBHcmlkTGlzdEl0ZW0gfSBmcm9tICcuL2dyaWRMaXN0L0dyaWRMaXN0SXRlbSc7XHJcbmltcG9ydCB7IEdyaWRzdGVyT3B0aW9ucyB9IGZyb20gJy4vR3JpZHN0ZXJPcHRpb25zJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICduZ3gtZ3JpZHN0ZXInLFxyXG4gICAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwiZ3JpZHN0ZXItY29udGFpbmVyXCI+XHJcbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICAgICAgPGRpdiBjbGFzcz1cInBvc2l0aW9uLWhpZ2hsaWdodFwiIHN0eWxlPVwiZGlzcGxheTpub25lO1wiICNwb3NpdGlvbkhpZ2hsaWdodD5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5uZXJcIj48L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5gLFxyXG4gICAgc3R5bGVzOiBbXHJcbiAgICAgICAgYFxyXG4gICAgICAgICAgICBuZ3gtZ3JpZHN0ZXIge1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XHJcbiAgICAgICAgICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIG5neC1ncmlkc3Rlci5ncmlkc3Rlci0tZHJhZ2dpbmcge1xyXG4gICAgICAgICAgICAgICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgICAgICAgICAgIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgICAgICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgICAgICAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgICAgICAgICB1c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbmd4LWdyaWRzdGVyIC5ncmlkc3Rlci1jb250YWluZXIge1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgICAgICAgICAgICBsaXN0LXN0eWxlOiBub25lO1xyXG4gICAgICAgICAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOiB3aWR0aCAwLjJzLCBoZWlnaHQgMC4ycztcclxuICAgICAgICAgICAgICAgIHRyYW5zaXRpb246IHdpZHRoIDAuMnMsIGhlaWdodCAwLjJzO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBuZ3gtZ3JpZHN0ZXIgLnBvc2l0aW9uLWhpZ2hsaWdodCB7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgICAgICAgICAgICAgIHotaW5kZXg6IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBgXHJcbiAgICBdLFxyXG4gICAgcHJvdmlkZXJzOiBbR3JpZHN0ZXJTZXJ2aWNlXSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxyXG59KVxyXG5leHBvcnQgY2xhc3MgR3JpZHN0ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XHJcbiAgICBASW5wdXQoKSBvcHRpb25zOiBJR3JpZHN0ZXJPcHRpb25zO1xyXG4gICAgQE91dHB1dCgpIG9wdGlvbnNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSByZWFkeSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gICAgQE91dHB1dCgpIHJlZmxvdyA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gICAgQE91dHB1dCgpIHByb3RvdHlwZURyb3AgPSBuZXcgRXZlbnRFbWl0dGVyPHsgaXRlbTogR3JpZExpc3RJdGVtIH0+KCk7XHJcbiAgICBAT3V0cHV0KCkgcHJvdG90eXBlRW50ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPHsgaXRlbTogR3JpZExpc3RJdGVtIH0+KCk7XHJcbiAgICBAT3V0cHV0KCkgcHJvdG90eXBlT3V0ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGl0ZW06IEdyaWRMaXN0SXRlbSB9PigpO1xyXG4gICAgQElucHV0KCkgZHJhZ2dhYmxlT3B0aW9uczogSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucyA9IHt9O1xyXG4gICAgQElucHV0KCkgcGFyZW50OiBHcmlkc3RlckNvbXBvbmVudDtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdwb3NpdGlvbkhpZ2hsaWdodCcsIHsgc3RhdGljOiB0cnVlIH0pICRwb3NpdGlvbkhpZ2hsaWdodDtcclxuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZ3JpZHN0ZXItLWRyYWdnaW5nJykgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5ncmlkc3Rlci0tcmVzaXppbmcnKSBpc1Jlc2l6aW5nID0gZmFsc2U7XHJcblxyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5ncmlkc3Rlci0tcmVhZHknKSBpc1JlYWR5ID0gZmFsc2U7XHJcbiAgICBncmlkc3RlcjogR3JpZHN0ZXJTZXJ2aWNlO1xyXG4gICAgJGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgIGdyaWRzdGVyT3B0aW9uczogR3JpZHN0ZXJPcHRpb25zO1xyXG4gICAgaXNQcm90b3R5cGVFbnRlcmVkID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGlzRGlzYWJsZWQgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgem9uZTogTmdab25lLFxyXG4gICAgICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgZ3JpZHN0ZXI6IEdyaWRzdGVyU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIGdyaWRzdGVyUHJvdG90eXBlOiBHcmlkc3RlclByb3RvdHlwZVNlcnZpY2VcclxuICAgICkge1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIgPSBncmlkc3RlcjtcclxuICAgICAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJPcHRpb25zID0gbmV3IEdyaWRzdGVyT3B0aW9ucyh0aGlzLm9wdGlvbnMsIHRoaXMuJGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnVzZUNTU1RyYW5zZm9ybXMpIHtcclxuICAgICAgICAgICAgdGhpcy4kZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjc3MtdHJhbnNmb3JtJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXJPcHRpb25zLmNoYW5nZS5zdWJzY3JpYmUob3B0aW9ucyA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyaWRzdGVyLm9wdGlvbnMgPSBvcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZ3JpZHN0ZXIuZ3JpZExpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWRzdGVyLmdyaWRMaXN0Lm9wdGlvbnMgPSBvcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLm9wdGlvbnNDaGFuZ2UuZW1pdChvcHRpb25zKSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5pbml0KHRoaXMpO1xyXG5cclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXHJcbiAgICAgICAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxyXG4gICAgICAgICAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgZGVib3VuY2VUaW1lKHRoaXMuZ3JpZHN0ZXIub3B0aW9ucy5yZXNwb25zaXZlRGVib3VuY2UgfHwgMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCgpID0+IHRoaXMuZ3JpZHN0ZXIub3B0aW9ucy5yZXNwb25zaXZlVmlldylcclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZWxvYWQoKSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXHJcbiAgICAgICAgICAgICAgICBmcm9tRXZlbnQoZG9jdW1lbnQsICdzY3JvbGwnLCB7IHBhc3NpdmU6IHRydWUgfSkuc3Vic2NyaWJlKCgpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVHcmlkc3RlckVsZW1lbnREYXRhKClcclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUNvbnRhaW5lciA9IHV0aWxzLmdldFNjcm9sbGFibGVDb250YWluZXIodGhpcy4kZWxlbWVudCk7XHJcbiAgICAgICAgICAgIGlmIChzY3JvbGxhYmxlQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXHJcbiAgICAgICAgICAgICAgICAgICAgZnJvbUV2ZW50KHNjcm9sbGFibGVDb250YWluZXIsICdzY3JvbGwnLCB7IHBhc3NpdmU6IHRydWUgfSlcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlR3JpZHN0ZXJFbGVtZW50RGF0YSgpXHJcbiAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcclxuICAgICAgICB0aGlzLmdyaWRzdGVyLnN0YXJ0KCk7XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlR3JpZHN0ZXJFbGVtZW50RGF0YSgpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbm5lY3RHcmlkc3RlclByb3RvdHlwZSgpO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyLiRwb3NpdGlvbkhpZ2hsaWdodCA9IHRoaXMuJHBvc2l0aW9uSGlnaGxpZ2h0Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoYW5nZSBncmlkc3RlciBjb25maWcgb3B0aW9uIGFuZCByZWJ1aWxkXHJcbiAgICAgKiBAcGFyYW0gc3RyaW5nIG5hbWVcclxuICAgICAqIEBwYXJhbSBhbnkgdmFsdWVcclxuICAgICAqIEByZXR1cm4gR3JpZHN0ZXJDb21wb25lbnRcclxuICAgICAqL1xyXG4gICAgc2V0T3B0aW9uKG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSkge1xyXG4gICAgICAgIGlmIChuYW1lID09PSAnZHJhZ0FuZERyb3AnKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVEcmFnZ2FibGUoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZURyYWdnYWJsZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChuYW1lID09PSAncmVzaXphYmxlJykge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlUmVzaXphYmxlKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVSZXNpemFibGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobmFtZSA9PT0gJ2xhbmVzJykge1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyLm9wdGlvbnMubGFuZXMgPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnModGhpcy5ncmlkc3Rlci5vcHRpb25zKTtcclxuICAgICAgICAgICAgdGhpcy5yZWZsb3dHcmlkc3RlcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobmFtZSA9PT0gJ2RpcmVjdGlvbicpIHtcclxuICAgICAgICAgICAgdGhpcy5ncmlkc3Rlci5vcHRpb25zLmRpcmVjdGlvbiA9IHZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyLmdyaWRMaXN0LnB1bGxJdGVtc1RvTGVmdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobmFtZSA9PT0gJ3dpZHRoSGVpZ2h0UmF0aW8nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIub3B0aW9ucy53aWR0aEhlaWdodFJhdGlvID0gcGFyc2VGbG9hdCh2YWx1ZSB8fCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG5hbWUgPT09ICdyZXNwb25zaXZlVmlldycpIHtcclxuICAgICAgICAgICAgdGhpcy5ncmlkc3Rlci5vcHRpb25zLnJlc3BvbnNpdmVWaWV3ID0gISF2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5ncmlkTGlzdC5zZXRPcHRpb24obmFtZSwgdmFsdWUpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICByZWxvYWQoKSB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIuZml4SXRlbXNQb3NpdGlvbnMoKTtcclxuICAgICAgICAgICAgdGhpcy5yZWZsb3dHcmlkc3RlcigpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICByZWZsb3dHcmlkc3Rlcihpc0luaXQgPSBmYWxzZSkge1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIucmVmbG93KCk7XHJcbiAgICAgICAgdGhpcy5yZWZsb3cuZW1pdCh7XHJcbiAgICAgICAgICAgIGlzSW5pdDogaXNJbml0LFxyXG4gICAgICAgICAgICBncmlkc3RlckNvbXBvbmVudDogdGhpc1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUdyaWRzdGVyRWxlbWVudERhdGEoKSB7XHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5ncmlkc3RlclNjcm9sbERhdGEgPSB0aGlzLmdldFNjcm9sbFBvc2l0aW9uRnJvbVBhcmVudHMoXHJcbiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIuZ3JpZHN0ZXJSZWN0ID0gdGhpcy4kZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRSZWFkeSgpIHtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+ICh0aGlzLmlzUmVhZHkgPSB0cnVlKSk7XHJcbiAgICAgICAgdGhpcy5yZWFkeS5lbWl0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRqdXN0SXRlbXNIZWlnaHRUb0NvbnRlbnQoXHJcbiAgICAgICAgc2Nyb2xsYWJsZUl0ZW1FbGVtZW50U2VsZWN0b3I6IHN0cmluZyA9ICcuZ3JpZHN0ZXItaXRlbS1pbm5lcidcclxuICAgICkge1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIuaXRlbXNcclxuICAgICAgICAgICAgLy8gY29udmVydCBlYWNoIGl0ZW0gdG8gb2JqZWN0IHdpdGggaW5mb3JtYXRpb24gYWJvdXQgY29udGVudCBoZWlnaHQgYW5kIHNjcm9sbCBoZWlnaHRcclxuICAgICAgICAgICAgLm1hcCgoaXRlbTogR3JpZExpc3RJdGVtKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JvbGxFbCA9IGl0ZW0uJGVsZW1lbnQucXVlcnlTZWxlY3RvcihcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxhYmxlSXRlbUVsZW1lbnRTZWxlY3RvclxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFbCA9IHNjcm9sbEVsLmxhc3RFbGVtZW50Q2hpbGQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JvbGxFbERpc3RhbmNlID0gdXRpbHMuZ2V0UmVsYXRpdmVDb29yZGluYXRlcyhcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxFbCxcclxuICAgICAgICAgICAgICAgICAgICBpdGVtLiRlbGVtZW50XHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsRWxSZWN0ID0gc2Nyb2xsRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb250ZW50UmVjdCA9IGNvbnRlbnRFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGl0ZW0sXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudEhlaWdodDogY29udGVudFJlY3QuYm90dG9tIC0gc2Nyb2xsRWxSZWN0LnRvcCxcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxFbERpc3RhbmNlXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgcmVxdWlyZWQgaGVpZ2h0IGluIGxhbmVzIGFtb3VudCBhbmQgdXBkYXRlIGl0ZW0gXCJoXCJcclxuICAgICAgICAgICAgLmZvckVhY2goZGF0YSA9PiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhLml0ZW0uaCA9IE1hdGguY2VpbCg8YW55PihcclxuICAgICAgICAgICAgICAgICAgICAoZGF0YS5jb250ZW50SGVpZ2h0IC9cclxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMuZ3JpZHN0ZXIuY2VsbEhlaWdodCAtIGRhdGEuc2Nyb2xsRWxEaXN0YW5jZS50b3ApKVxyXG4gICAgICAgICAgICAgICAgKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5yZWZsb3coKTtcclxuICAgIH1cclxuXHJcbiAgICBkaXNhYmxlKGl0ZW0pIHtcclxuICAgICAgICBjb25zdCBpdGVtSWR4ID0gdGhpcy5ncmlkc3Rlci5pdGVtcy5pbmRleE9mKGl0ZW0uaXRlbUNvbXBvbmVudCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNEaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgaWYgKGl0ZW1JZHggPj0gMCkge1xyXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5ncmlkc3Rlci5pdGVtc1tcclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIuaXRlbXMuaW5kZXhPZihpdGVtLml0ZW1Db21wb25lbnQpXHJcbiAgICAgICAgICAgIF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIub25EcmFnT3V0KGl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIGVuYWJsZSgpIHtcclxuICAgICAgICB0aGlzLmlzRGlzYWJsZWQgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFNjcm9sbFBvc2l0aW9uRnJvbVBhcmVudHMoXHJcbiAgICAgICAgZWxlbWVudDogRWxlbWVudCxcclxuICAgICAgICBkYXRhID0geyBzY3JvbGxUb3A6IDAsIHNjcm9sbExlZnQ6IDAgfVxyXG4gICAgKTogeyBzY3JvbGxUb3A6IG51bWJlcjsgc2Nyb2xsTGVmdDogbnVtYmVyIH0ge1xyXG4gICAgICAgIGlmIChlbGVtZW50LnBhcmVudEVsZW1lbnQgJiYgZWxlbWVudC5wYXJlbnRFbGVtZW50ICE9PSBkb2N1bWVudC5ib2R5KSB7XHJcbiAgICAgICAgICAgIGRhdGEuc2Nyb2xsVG9wICs9IGVsZW1lbnQucGFyZW50RWxlbWVudC5zY3JvbGxUb3A7XHJcbiAgICAgICAgICAgIGRhdGEuc2Nyb2xsTGVmdCArPSBlbGVtZW50LnBhcmVudEVsZW1lbnQuc2Nyb2xsTGVmdDtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFNjcm9sbFBvc2l0aW9uRnJvbVBhcmVudHMoXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnBhcmVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICBkYXRhXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBzY3JvbGxUb3A6IGRhdGEuc2Nyb2xsVG9wLFxyXG4gICAgICAgICAgICBzY3JvbGxMZWZ0OiBkYXRhLnNjcm9sbExlZnRcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29ubmVjdCBncmlkc3RlciBwcm90b3R5cGUgaXRlbSB0byBncmlkc3RlciBkcmFnZ2luZyBob29rcyAob25TdGFydCwgb25EcmFnLCBvblN0b3ApLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNvbm5lY3RHcmlkc3RlclByb3RvdHlwZSgpIHtcclxuICAgICAgICB0aGlzLmdyaWRzdGVyUHJvdG90eXBlLm9ic2VydmVEcm9wT3V0KHRoaXMuZ3JpZHN0ZXIpLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICAgICBjb25zdCBkcm9wT3Zlck9ic2VydmFibGUgPSA8Q29ubmVjdGFibGVPYnNlcnZhYmxlPGFueT4+KFxyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyUHJvdG90eXBlXHJcbiAgICAgICAgICAgICAgICAub2JzZXJ2ZURyb3BPdmVyKHRoaXMuZ3JpZHN0ZXIpXHJcbiAgICAgICAgICAgICAgICAucGlwZShwdWJsaXNoKCkpXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgY29uc3QgZHJhZ09ic2VydmFibGUgPSB0aGlzLmdyaWRzdGVyUHJvdG90eXBlLm9ic2VydmVEcmFnT3ZlcihcclxuICAgICAgICAgICAgdGhpcy5ncmlkc3RlclxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGRyYWdPYnNlcnZhYmxlLmRyYWdPdmVyXHJcbiAgICAgICAgICAgIC5waXBlKGZpbHRlcigoKSA9PiAhdGhpcy5pc0Rpc2FibGVkKSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgocHJvdG90eXBlOiBHcmlkc3Rlckl0ZW1Qcm90b3R5cGVEaXJlY3RpdmUpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1Byb3RvdHlwZUVudGVyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyaWRzdGVyLm9uRHJhZyhwcm90b3R5cGUuaXRlbSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICBkcmFnT2JzZXJ2YWJsZS5kcmFnRW50ZXJcclxuICAgICAgICAgICAgLnBpcGUoZmlsdGVyKCgpID0+ICF0aGlzLmlzRGlzYWJsZWQpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChwcm90b3R5cGU6IEdyaWRzdGVySXRlbVByb3RvdHlwZURpcmVjdGl2ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc1Byb3RvdHlwZUVudGVyZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmdyaWRzdGVyLml0ZW1zLmluZGV4T2YocHJvdG90eXBlLml0ZW0pIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIuaXRlbXMucHVzaChwcm90b3R5cGUuaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyaWRzdGVyLm9uU3RhcnQocHJvdG90eXBlLml0ZW0pO1xyXG4gICAgICAgICAgICAgICAgcHJvdG90eXBlLnNldERyYWdDb250ZXh0R3JpZHN0ZXIodGhpcy5ncmlkc3Rlcik7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQuZGlzYWJsZShwcm90b3R5cGUuaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnByb3RvdHlwZUVudGVyLmVtaXQoeyBpdGVtOiBwcm90b3R5cGUuaXRlbSB9KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGRyYWdPYnNlcnZhYmxlLmRyYWdPdXRcclxuICAgICAgICAgICAgLnBpcGUoZmlsdGVyKCgpID0+ICF0aGlzLmlzRGlzYWJsZWQpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChwcm90b3R5cGU6IEdyaWRzdGVySXRlbVByb3RvdHlwZURpcmVjdGl2ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzUHJvdG90eXBlRW50ZXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIub25EcmFnT3V0KHByb3RvdHlwZS5pdGVtKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNQcm90b3R5cGVFbnRlcmVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGVPdXQuZW1pdCh7IGl0ZW06IHByb3RvdHlwZS5pdGVtIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmVuYWJsZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5pc1Byb3RvdHlwZUVudGVyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQuZ3JpZHN0ZXIuaXRlbXMuaW5kZXhPZihwcm90b3R5cGUuaXRlbSkgPCAwXHJcbiAgICAgICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmdyaWRzdGVyLml0ZW1zLnB1c2gocHJvdG90eXBlLml0ZW0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5ncmlkc3Rlci5vblN0YXJ0KHByb3RvdHlwZS5pdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm90b3R5cGUuc2V0RHJhZ0NvbnRleHRHcmlkc3Rlcih0aGlzLnBhcmVudC5ncmlkc3Rlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGltZW91dCBpcyBuZWVkZWQgdG8gYmUgc3VyZSB0aGF0IFwiZW50ZXJcIiBldmVudCBpcyBmaXJlZCBhZnRlciBcIm91dFwiXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LnByb3RvdHlwZUVudGVyLmVtaXQoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbTogcHJvdG90eXBlLml0ZW1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvdHlwZS5vbkVudGVyKHRoaXMucGFyZW50LmdyaWRzdGVyKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGRyb3BPdmVyT2JzZXJ2YWJsZVxyXG4gICAgICAgICAgICAucGlwZShmaWx0ZXIoKCkgPT4gIXRoaXMuaXNEaXNhYmxlZCkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoZGF0YSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNQcm90b3R5cGVFbnRlcmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIub25TdG9wKGRhdGEuaXRlbS5pdGVtKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXIucmVtb3ZlSXRlbShkYXRhLml0ZW0uaXRlbSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5pc1Byb3RvdHlwZUVudGVyZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmVuYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGVEcm9wLmVtaXQoeyBpdGVtOiBkYXRhLml0ZW0uaXRlbSB9KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGRyb3BPdmVyT2JzZXJ2YWJsZS5jb25uZWN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBlbmFibGVEcmFnZ2FibGUoKSB7XHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5vcHRpb25zLmRyYWdBbmREcm9wID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlci5pdGVtc1xyXG4gICAgICAgICAgICAuZmlsdGVyKFxyXG4gICAgICAgICAgICAgICAgaXRlbSA9PiBpdGVtLml0ZW1Db21wb25lbnQgJiYgaXRlbS5pdGVtQ29tcG9uZW50LmRyYWdBbmREcm9wXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgLmZvckVhY2goKGl0ZW06IEdyaWRMaXN0SXRlbSkgPT5cclxuICAgICAgICAgICAgICAgIGl0ZW0uaXRlbUNvbXBvbmVudC5lbmFibGVEcmFnRHJvcCgpXHJcbiAgICAgICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBkaXNhYmxlRHJhZ2dhYmxlKCkge1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXIub3B0aW9ucy5kcmFnQW5kRHJvcCA9IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyLml0ZW1zXHJcbiAgICAgICAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLml0ZW1Db21wb25lbnQpXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKChpdGVtOiBHcmlkTGlzdEl0ZW0pID0+XHJcbiAgICAgICAgICAgICA