UNPKG

angular-calendar-timeline

Version:

A timeline for angular that shows events on a timeline board in different modes: days, weeks, and months.

87 lines 18 kB
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "angular-resizable-element"; import * as i3 from "angular-draggable-droppable"; export class TimelineItemComponent { set item(item) { this._item = item; item.updateView = () => this._cdr.detectChanges(); this._checkIsInScaleRange(); } ; set scale(scale) { this._scale = scale; this._checkIsInScaleRange(); } ; get item() { return this._item; } constructor(_cdr, _renderer) { this._cdr = _cdr; this._renderer = _renderer; this.isInScaleRange = true; this.isItemResizingStarted = false; this.itemResized = new EventEmitter(); this.itemMoved = new EventEmitter(); } onItemResizeStart(event) { this.isItemResizingStarted = true; this._cdr.markForCheck(); } onItemResizeEnd(event) { this.itemResized.emit({ event, item: this._item }); setTimeout(() => this.isItemResizingStarted = false); } onItemDragStart(event) { this._setRowZIndex(1000); } onItemDropped(event) { if (!this.isItemResizingStarted) { this.itemMoved.emit({ event, item: this._item }); } this._setRowZIndex(1); } _checkIsInScaleRange() { if (!this._item || !this._scale) { return; } if (!this._item.startDate || !this._item.endDate) { this.isInScaleRange = true; this._cdr.markForCheck(); return; } this.isInScaleRange = this._scale.startDate.getTime() <= this._item.startDate.getTime() && this._scale.endDate.getTime() >= this._item.endDate.getTime(); this._cdr.markForCheck(); } _setRowZIndex(index) { this._renderer.setStyle(this.rowContainer, 'z-index', index); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TimelineItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TimelineItemComponent, selector: "timeline-item", inputs: { item: "item", scale: "scale", rowContainer: "rowContainer", height: "height", rowHeight: "rowHeight", locale: "locale", contentTemplate: "contentTemplate" }, outputs: { itemResized: "itemResized", itemMoved: "itemMoved" }, ngImport: i0, template: "<div class=\"timeline-item\"\r\n *ngIf=\"isInScaleRange\"\r\n ghostElementPositioning='absolute'\r\n mwlResizable\r\n mwlDraggable\r\n [dragActiveClass]=\"'timeline-item_dragging'\"\r\n (dragStart)='onItemDragStart($event)'\r\n (dragEnd)='onItemDropped($event)'\r\n (resizeEnd)='onItemResizeEnd($event)'\r\n (resizeStart)='onItemResizeStart($event)'\r\n [dragAxis]=\"{y: item.canDragY, x: item.canDragX}\"\r\n [enableGhostResize]='true'\r\n [dragSnapGrid]=\"{y: rowHeight}\"\r\n [style.height.px]='height'\r\n [style.left.px]='item?._left'\r\n [style.width.px]='item?._width'>\r\n <div class=\"item-custom-template\" *ngIf=\"contentTemplate; else nameTemplate\">\r\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: item, locale: locale}\"\r\n ></ng-container>\r\n </div>\r\n\r\n <ng-template #nameTemplate>\r\n <div class=\"default-content\">\r\n {{item.name}}\r\n </div>\r\n </ng-template>\r\n\r\n <div *ngIf='item.canResizeLeft'\r\n [resizeEdges]='{ left: item.canResizeLeft }'\r\n class='resize-handle-left'\r\n mwlResizeHandle\r\n ></div>\r\n <div *ngIf='item.canResizeRight'\r\n [resizeEdges]='{ right: item.canResizeRight }'\r\n class='resize-handle-right'\r\n mwlResizeHandle\r\n ></div>\r\n</div>\r\n", styles: [".timeline-item{height:100%;position:absolute;box-sizing:border-box;overflow:hidden;top:5px}.item-custom-template{width:100%;height:100%;position:relative;box-sizing:border-box}.default-content{height:100%;width:100%;background-color:#098ed2;padding:2px 10px;display:flex;align-items:center;color:#f1f1f1;box-sizing:border-box;border-radius:2px;cursor:pointer}mwlResizable{box-sizing:border-box}.resize-handle-left,.resize-handle-right{position:absolute;height:100%;cursor:col-resize;width:5px;top:0}.resize-handle-left{left:0}.resize-handle-right{right:0}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.ResizableDirective, selector: "[mwlResizable]", inputs: ["validateResize", "enableGhostResize", "resizeSnapGrid", "resizeCursors", "ghostElementPositioning", "allowNegativeResizes", "mouseMoveThrottleMS"], outputs: ["resizeStart", "resizing", "resizeEnd"], exportAs: ["mwlResizable"] }, { kind: "directive", type: i2.ResizeHandleDirective, selector: "[mwlResizeHandle]", inputs: ["resizeEdges", "resizableContainer"] }, { kind: "directive", type: i3.DraggableDirective, selector: "[mwlDraggable]", inputs: ["dropData", "dragAxis", "dragSnapGrid", "ghostDragEnabled", "showOriginalElementWhileDragging", "validateDrag", "dragCursor", "dragActiveClass", "ghostElementAppendTo", "ghostElementTemplate", "touchStartLongPress", "autoScroll"], outputs: ["dragPointerDown", "dragStart", "ghostElementCreated", "dragging", "dragEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TimelineItemComponent, decorators: [{ type: Component, args: [{ selector: 'timeline-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"timeline-item\"\r\n *ngIf=\"isInScaleRange\"\r\n ghostElementPositioning='absolute'\r\n mwlResizable\r\n mwlDraggable\r\n [dragActiveClass]=\"'timeline-item_dragging'\"\r\n (dragStart)='onItemDragStart($event)'\r\n (dragEnd)='onItemDropped($event)'\r\n (resizeEnd)='onItemResizeEnd($event)'\r\n (resizeStart)='onItemResizeStart($event)'\r\n [dragAxis]=\"{y: item.canDragY, x: item.canDragX}\"\r\n [enableGhostResize]='true'\r\n [dragSnapGrid]=\"{y: rowHeight}\"\r\n [style.height.px]='height'\r\n [style.left.px]='item?._left'\r\n [style.width.px]='item?._width'>\r\n <div class=\"item-custom-template\" *ngIf=\"contentTemplate; else nameTemplate\">\r\n <ng-container [ngTemplateOutlet]=\"contentTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: item, locale: locale}\"\r\n ></ng-container>\r\n </div>\r\n\r\n <ng-template #nameTemplate>\r\n <div class=\"default-content\">\r\n {{item.name}}\r\n </div>\r\n </ng-template>\r\n\r\n <div *ngIf='item.canResizeLeft'\r\n [resizeEdges]='{ left: item.canResizeLeft }'\r\n class='resize-handle-left'\r\n mwlResizeHandle\r\n ></div>\r\n <div *ngIf='item.canResizeRight'\r\n [resizeEdges]='{ right: item.canResizeRight }'\r\n class='resize-handle-right'\r\n mwlResizeHandle\r\n ></div>\r\n</div>\r\n", styles: [".timeline-item{height:100%;position:absolute;box-sizing:border-box;overflow:hidden;top:5px}.item-custom-template{width:100%;height:100%;position:relative;box-sizing:border-box}.default-content{height:100%;width:100%;background-color:#098ed2;padding:2px 10px;display:flex;align-items:center;color:#f1f1f1;box-sizing:border-box;border-radius:2px;cursor:pointer}mwlResizable{box-sizing:border-box}.resize-handle-left,.resize-handle-right{position:absolute;height:100%;cursor:col-resize;width:5px;top:0}.resize-handle-left{left:0}.resize-handle-right{right:0}\n"] }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }], propDecorators: { item: [{ type: Input }], scale: [{ type: Input }], rowContainer: [{ type: Input }], height: [{ type: Input }], rowHeight: [{ type: Input }], locale: [{ type: Input }], contentTemplate: [{ type: Input }], itemResized: [{ type: Output }], itemMoved: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUtaXRlbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNhbGVuZGFyLXRpbWVsaW5lL3NyYy9saWIvY29tcG9uZW50cy9pdGVtL3RpbWVsaW5lLWl0ZW0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jYWxlbmRhci10aW1lbGluZS9zcmMvbGliL2NvbXBvbmVudHMvaXRlbS90aW1lbGluZS1pdGVtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDOzs7OztBQVd2QixNQUFNLE9BQU8scUJBQXFCO0lBU2hDLElBQWEsSUFBSSxDQUFDLElBQStCO1FBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsRCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBQUEsQ0FBQztJQUVGLElBQWEsS0FBSyxDQUFDLEtBQXlCO1FBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFBQSxDQUFDO0lBZ0JGLElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsWUFBb0IsSUFBdUIsRUFDdkIsU0FBb0I7UUFEcEIsU0FBSSxHQUFKLElBQUksQ0FBbUI7UUFDdkIsY0FBUyxHQUFULFNBQVMsQ0FBVztRQWxDeEMsbUJBQWMsR0FBRyxJQUFJLENBQUM7UUFFdEIsMEJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBdUJwQixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUErQyxDQUFDO1FBRTlFLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBZ0QsQ0FBQztJQVF2RixDQUFDO0lBRUQsaUJBQWlCLENBQUMsS0FBa0I7UUFDbEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxlQUFlLENBQUMsS0FBa0I7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxDQUFDO1FBQ2pELFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFLO1FBQ25CLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFtQjtRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDekIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRTtlQUNsRixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuRSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFTyxhQUFhLENBQUMsS0FBYTtRQUNqQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvRCxDQUFDOytHQWxGVSxxQkFBcUI7bUdBQXJCLHFCQUFxQiw4UkNuQmxDLGszQ0F1Q0E7OzRGRHBCYSxxQkFBcUI7a0JBTmpDLFNBQVM7K0JBQ0UsZUFBZSxtQkFHUix1QkFBdUIsQ0FBQyxNQUFNOzhHQVdsQyxJQUFJO3NCQUFoQixLQUFLO2dCQU1PLEtBQUs7c0JBQWpCLEtBQUs7Z0JBS0csWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNO2dCQUVHLFNBQVM7c0JBQWxCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LCBSZW5kZXJlcjIsXHJcbiAgVGVtcGxhdGVSZWZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUmVzaXplRXZlbnQgfSBmcm9tIFwiYW5ndWxhci1yZXNpemFibGUtZWxlbWVudFwiO1xyXG5pbXBvcnQgeyBEcmFnRW5kRXZlbnQgfSBmcm9tIFwiYW5ndWxhci1kcmFnZ2FibGUtZHJvcHBhYmxlL2xpYi9kcmFnZ2FibGUuZGlyZWN0aXZlXCI7XHJcbmltcG9ydCB7IElUaW1lbGluZUl0ZW0sIElTY2FsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHNcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAndGltZWxpbmUtaXRlbScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3RpbWVsaW5lLWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3RpbWVsaW5lLWl0ZW0uY29tcG9uZW50LnNjc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxufSlcclxuZXhwb3J0IGNsYXNzIFRpbWVsaW5lSXRlbUNvbXBvbmVudCB7XHJcbiAgcHJpdmF0ZSBfaXRlbTogSVRpbWVsaW5lSXRlbTtcclxuXHJcbiAgcHJpdmF0ZSBfc2NhbGU6IElTY2FsZTtcclxuXHJcbiAgaXNJblNjYWxlUmFuZ2UgPSB0cnVlO1xyXG5cclxuICBpc0l0ZW1SZXNpemluZ1N0YXJ0ZWQgPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgc2V0IGl0ZW0oaXRlbTogSVRpbWVsaW5lSXRlbSB8IHVuZGVmaW5lZCkge1xyXG4gICAgdGhpcy5faXRlbSA9IGl0ZW07XHJcbiAgICBpdGVtLnVwZGF0ZVZpZXcgPSAoKSA9PiB0aGlzLl9jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgdGhpcy5fY2hlY2tJc0luU2NhbGVSYW5nZSgpO1xyXG4gIH07XHJcblxyXG4gIEBJbnB1dCgpIHNldCBzY2FsZShzY2FsZTogSVNjYWxlIHwgdW5kZWZpbmVkKSB7XHJcbiAgICB0aGlzLl9zY2FsZSA9IHNjYWxlO1xyXG4gICAgdGhpcy5fY2hlY2tJc0luU2NhbGVSYW5nZSgpO1xyXG4gIH07XHJcblxyXG4gIEBJbnB1dCgpIHJvd0NvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XHJcblxyXG4gIEBJbnB1dCgpIGhlaWdodDogbnVtYmVyO1xyXG5cclxuICBASW5wdXQoKSByb3dIZWlnaHQ6IG51bWJlcjtcclxuXHJcbiAgQElucHV0KCkgbG9jYWxlOiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpIGNvbnRlbnRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IElUaW1lbGluZUl0ZW0sIGxvY2FsZTogc3RyaW5nIH0+IHwgdW5kZWZpbmVkO1xyXG5cclxuICBAT3V0cHV0KCkgaXRlbVJlc2l6ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IFJlc2l6ZUV2ZW50LCBpdGVtOiBJVGltZWxpbmVJdGVtIH0+KCk7XHJcblxyXG4gIEBPdXRwdXQoKSBpdGVtTW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IERyYWdFbmRFdmVudCwgaXRlbTogSVRpbWVsaW5lSXRlbSB9PigpO1xyXG5cclxuICBnZXQgaXRlbSgpOiBJVGltZWxpbmVJdGVtIHtcclxuICAgIHJldHVybiB0aGlzLl9pdGVtO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgICAgICAgICAgICBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyKSB7XHJcbiAgfVxyXG5cclxuICBvbkl0ZW1SZXNpemVTdGFydChldmVudDogUmVzaXplRXZlbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNJdGVtUmVzaXppbmdTdGFydGVkID0gdHJ1ZTtcclxuICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcclxuICB9XHJcblxyXG4gIG9uSXRlbVJlc2l6ZUVuZChldmVudDogUmVzaXplRXZlbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuaXRlbVJlc2l6ZWQuZW1pdCh7ZXZlbnQsIGl0ZW06IHRoaXMuX2l0ZW19KTtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5pc0l0ZW1SZXNpemluZ1N0YXJ0ZWQgPSBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBvbkl0ZW1EcmFnU3RhcnQoZXZlbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuX3NldFJvd1pJbmRleCgxMDAwKTtcclxuICB9XHJcblxyXG4gIG9uSXRlbURyb3BwZWQoZXZlbnQ6IERyYWdFbmRFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmlzSXRlbVJlc2l6aW5nU3RhcnRlZCkge1xyXG4gICAgICB0aGlzLml0ZW1Nb3ZlZC5lbWl0KHtldmVudCwgaXRlbTogdGhpcy5faXRlbX0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3NldFJvd1pJbmRleCgxKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NoZWNrSXNJblNjYWxlUmFuZ2UoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuX2l0ZW0gfHwgIXRoaXMuX3NjYWxlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuX2l0ZW0uc3RhcnREYXRlIHx8ICF0aGlzLl9pdGVtLmVuZERhdGUpIHtcclxuICAgICAgdGhpcy5pc0luU2NhbGVSYW5nZSA9IHRydWU7XHJcbiAgICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNJblNjYWxlUmFuZ2UgPSB0aGlzLl9zY2FsZS5zdGFydERhdGUuZ2V0VGltZSgpIDw9IHRoaXMuX2l0ZW0uc3RhcnREYXRlLmdldFRpbWUoKVxyXG4gICAgICAmJiB0aGlzLl9zY2FsZS5lbmREYXRlLmdldFRpbWUoKSA+PSB0aGlzLl9pdGVtLmVuZERhdGUuZ2V0VGltZSgpO1xyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfc2V0Um93WkluZGV4KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKHRoaXMucm93Q29udGFpbmVyLCAnei1pbmRleCcsIGluZGV4KTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInRpbWVsaW5lLWl0ZW1cIlxyXG4gICAgICpuZ0lmPVwiaXNJblNjYWxlUmFuZ2VcIlxyXG4gICAgIGdob3N0RWxlbWVudFBvc2l0aW9uaW5nPSdhYnNvbHV0ZSdcclxuICAgICBtd2xSZXNpemFibGVcclxuICAgICBtd2xEcmFnZ2FibGVcclxuICAgICBbZHJhZ0FjdGl2ZUNsYXNzXT1cIid0aW1lbGluZS1pdGVtX2RyYWdnaW5nJ1wiXHJcbiAgICAgKGRyYWdTdGFydCk9J29uSXRlbURyYWdTdGFydCgkZXZlbnQpJ1xyXG4gICAgIChkcmFnRW5kKT0nb25JdGVtRHJvcHBlZCgkZXZlbnQpJ1xyXG4gICAgIChyZXNpemVFbmQpPSdvbkl0ZW1SZXNpemVFbmQoJGV2ZW50KSdcclxuICAgICAocmVzaXplU3RhcnQpPSdvbkl0ZW1SZXNpemVTdGFydCgkZXZlbnQpJ1xyXG4gICAgIFtkcmFnQXhpc109XCJ7eTogaXRlbS5jYW5EcmFnWSwgeDogaXRlbS5jYW5EcmFnWH1cIlxyXG4gICAgIFtlbmFibGVHaG9zdFJlc2l6ZV09J3RydWUnXHJcbiAgICAgW2RyYWdTbmFwR3JpZF09XCJ7eTogcm93SGVpZ2h0fVwiXHJcbiAgICAgW3N0eWxlLmhlaWdodC5weF09J2hlaWdodCdcclxuICAgICBbc3R5bGUubGVmdC5weF09J2l0ZW0/Ll9sZWZ0J1xyXG4gICAgIFtzdHlsZS53aWR0aC5weF09J2l0ZW0/Ll93aWR0aCc+XHJcbiAgPGRpdiBjbGFzcz1cIml0ZW0tY3VzdG9tLXRlbXBsYXRlXCIgKm5nSWY9XCJjb250ZW50VGVtcGxhdGU7IGVsc2UgbmFtZVRlbXBsYXRlXCI+XHJcbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRlbnRUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtLCBsb2NhbGU6IGxvY2FsZX1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8bmctdGVtcGxhdGUgI25hbWVUZW1wbGF0ZT5cclxuICAgPGRpdiBjbGFzcz1cImRlZmF1bHQtY29udGVudFwiPlxyXG4gICAgIHt7aXRlbS5uYW1lfX1cclxuICAgPC9kaXY+XHJcbiAgPC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgPGRpdiAqbmdJZj0naXRlbS5jYW5SZXNpemVMZWZ0J1xyXG4gICAgICAgW3Jlc2l6ZUVkZ2VzXT0neyBsZWZ0OiBpdGVtLmNhblJlc2l6ZUxlZnQgfSdcclxuICAgICAgIGNsYXNzPSdyZXNpemUtaGFuZGxlLWxlZnQnXHJcbiAgICAgICBtd2xSZXNpemVIYW5kbGVcclxuICA+PC9kaXY+XHJcbiAgPGRpdiAqbmdJZj0naXRlbS5jYW5SZXNpemVSaWdodCdcclxuICAgICAgIFtyZXNpemVFZGdlc109J3sgcmlnaHQ6IGl0ZW0uY2FuUmVzaXplUmlnaHQgfSdcclxuICAgICAgIGNsYXNzPSdyZXNpemUtaGFuZGxlLXJpZ2h0J1xyXG4gICAgICAgbXdsUmVzaXplSGFuZGxlXHJcbiAgPjwvZGl2PlxyXG48L2Rpdj5cclxuIl19