UNPKG

@rybos/angular2gridster

Version:

[![npm version](https://badge.fury.io/js/angular2gridster.svg)](https://badge.fury.io/js/angular2gridster)

455 lines 69.1 kB
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { GridList } from './gridList/gridList'; import * as i0 from "@angular/core"; export class GridsterService { constructor() { this.items = []; this._items = []; this._itemsMap = {}; this.disabledItems = []; this.debounceRenderSubject = new Subject(); this.itemRemoveSubject = new Subject(); this.isInit = false; this.itemRemoveSubject.pipe(debounceTime(0)).subscribe(() => { this.gridList.pullItemsToLeft(); this.render(); this.updateCachedItems(); }); this.debounceRenderSubject.pipe(debounceTime(0)).subscribe(() => this.render()); } isInitialized() { return this.isInit; } /** * Must be called before init * @param item */ registerItem(item) { this.items.push(item); return item; } init(gridsterComponent) { this.gridsterComponent = gridsterComponent; this.draggableOptions = gridsterComponent.draggableOptions; this.gridsterOptions = gridsterComponent.gridsterOptions; } start() { this.updateMaxItemSize(); // Used to highlight a position an element will land on upon drop if (this.$positionHighlight) { this.removePositionHighlight(); } this.initGridList(); this.isInit = true; setTimeout(() => { this.copyItems(); this.fixItemsPositions(); this.gridsterComponent.reflowGridster(true); this.gridsterComponent.setReady(); }); } initGridList() { // Create instance of GridList (decoupled lib for handling the grid // positioning and sorting post-drag and dropping) this.gridList = new GridList(this.items, this.options); } render() { this.updateMaxItemSize(); this.gridList.generateGrid(); this.applySizeToItems(); this.applyPositionToItems(); this.refreshLines(); } reflow() { this.calculateCellSize(); this.render(); } fixItemsPositions() { if (this.options.responsiveSizes) { this.gridList.fixItemsPositions(this.options); } else { this.gridList.fixItemsPositions(this.gridsterOptions.basicOptions); this.gridsterOptions.responsiveOptions.forEach((options) => { this.gridList.fixItemsPositions(options); }); } this.updateCachedItems(); } removeItem(item) { const idx = this.items.indexOf(item); if (idx >= 0) { this.items.splice(this.items.indexOf(item), 1); } this.gridList.deleteItemPositionFromGrid(item); this.removeItemFromCache(item); } onResizeStart(item) { this.currentElement = item.$element; this.copyItems(); this._maxGridCols = this.gridList.grid.length; this.highlightPositionForItem(item); this.gridsterComponent.isResizing = true; this.refreshLines(); } onResizeDrag(item) { const newSize = this.snapItemSizeToGrid(item); const sizeChanged = this.dragSizeChanged(newSize); const newPosition = this.snapItemPositionToGrid(item); const positionChanged = this.dragPositionChanged(newPosition); if (sizeChanged || positionChanged) { // Regenerate the grid with the positions from when the drag started this.restoreCachedItems(); this.gridList.generateGrid(); this.previousDragPosition = newPosition; this.previousDragSize = newSize; this.gridList.moveAndResize(item, newPosition, { w: newSize[0], h: newSize[1] }); // Visually update item positions and highlight shape this.applyPositionToItems(true); this.highlightPositionForItem(item); } } onResizeStop(item) { this.currentElement = undefined; this.updateCachedItems(); this.previousDragSize = null; this.removePositionHighlight(); this.gridsterComponent.isResizing = false; this.gridList.pullItemsToLeft(item); this.debounceRenderSubject.next(null); this.fixItemsPositions(); } onStart(item) { this.currentElement = item.$element; // itemCtrl.isDragging = true; // Create a deep copy of the items; we use them to revert the item // positions after each drag change, making an entire drag operation less // distructable this.copyItems(); // Since dragging actually alters the grid, we need to establish the number // of cols (+1 extra) before the drag starts this._maxGridCols = this.gridList.grid.length; this.gridsterComponent.isDragging = true; this.gridsterComponent.updateGridsterElementData(); this.refreshLines(); } onDrag(item) { const newPosition = this.snapItemPositionToGrid(item); if (this.dragPositionChanged(newPosition)) { // Regenerate the grid with the positions from when the drag started this.restoreCachedItems(); this.gridList.generateGrid(); this.previousDragPosition = newPosition; if (this.options.direction === 'none' && !this.gridList.checkItemAboveEmptyArea(item, { x: newPosition[0], y: newPosition[1] })) { return; } // Since the items list is a deep copy, we need to fetch the item // corresponding to this drag action again this.gridList.moveItemToPosition(item, newPosition); // Visually update item positions and highlight shape this.applyPositionToItems(true); this.highlightPositionForItem(item); } } cancel() { this.restoreCachedItems(); this.previousDragPosition = null; this.updateMaxItemSize(); this.applyPositionToItems(); this.removePositionHighlight(); this.currentElement = undefined; this.gridsterComponent.isDragging = false; } onDragOut(item) { this.cancel(); const idx = this.items.indexOf(item); if (idx >= 0) { this.items.splice(idx, 1); } this.gridList.pullItemsToLeft(); this.render(); } onStop(item) { this.currentElement = undefined; this.updateCachedItems(); this.previousDragPosition = null; this.removePositionHighlight(); this.gridList.pullItemsToLeft(item); this.gridsterComponent.isDragging = false; this.refreshLines(); } calculateCellSize() { if (this.options.direction === 'horizontal') { this.cellHeight = this.calculateCellHeight(); this.cellWidth = this.options.cellWidth || this.cellHeight * this.options.widthHeightRatio; } else { this.cellWidth = this.calculateCellWidth(); this.cellHeight = this.options.cellHeight || this.cellWidth / this.options.widthHeightRatio; } if (this.options.heightToFontSizeRatio) { this._fontSize = this.cellHeight * this.options.heightToFontSizeRatio; } } applyPositionToItems(increaseGridsterSize) { if (!this.options.shrink) { increaseGridsterSize = true; } // TODO: Implement group separators for (let i = 0; i < this.items.length; i++) { // Don't interfere with the positions of the dragged items if (this.isCurrentElement(this.items[i].$element)) { continue; } this.items[i].applyPosition(this); } const child = this.gridsterComponent.$element.firstChild; // Update the width of the entire grid container with enough room on the // right to allow dragging items to the end of the grid. if (this.options.direction === 'horizontal') { const increaseWidthWith = (increaseGridsterSize) ? this.maxItemWidth : 0; child.style.height = ''; child.style.width = ((this.gridList.grid.length + increaseWidthWith) * this.cellWidth) + 'px'; } else if (this.gridList.grid.length) { const increaseHeightWith = (increaseGridsterSize) ? this.maxItemHeight : 0; child.style.height = ((this.gridList.grid.length + increaseHeightWith) * this.cellHeight) + 'px'; child.style.width = ''; } } refreshLines() { const gridsterContainer = this.gridsterComponent.$element.firstChild; if (this.options.lines && this.options.lines.visible && (this.gridsterComponent.isDragging || this.gridsterComponent.isResizing || this.options.lines.always)) { const linesColor = this.options.lines.color || '#d8d8d8'; const linesBgColor = this.options.lines.backgroundColor || 'transparent'; const linesWidth = this.options.lines.width || 1; const bgPosition = linesWidth / 2; gridsterContainer.style.backgroundSize = `${this.cellWidth}px ${this.cellHeight}px`; gridsterContainer.style.backgroundPosition = `-${bgPosition}px -${bgPosition}px`; gridsterContainer.style.backgroundImage = ` linear-gradient(to right, ${linesColor} ${linesWidth}px, ${linesBgColor} ${linesWidth}px), linear-gradient(to bottom, ${linesColor} ${linesWidth}px, ${linesBgColor} ${linesWidth}px) `; } else { gridsterContainer.style.backgroundSize = ''; gridsterContainer.style.backgroundPosition = ''; gridsterContainer.style.backgroundImage = ''; } } removeItemFromCache(item) { this._items = this._items .filter(cachedItem => cachedItem.$element !== item.$element); Object.keys(this._itemsMap) .forEach((breakpoint) => { this._itemsMap[breakpoint] = this._itemsMap[breakpoint] .filter(cachedItem => cachedItem.$element !== item.$element); }); } copyItems() { this._items = this.items .filter(item => this.isValidGridItem(item)) .map((item) => { return item.copyForBreakpoint(null); }); this.gridsterOptions.responsiveOptions.forEach((options) => { this._itemsMap[options.breakpoint] = this.items .filter(item => this.isValidGridItem(item)) .map((item) => { return item.copyForBreakpoint(options.breakpoint); }); }); } /** * Update maxItemWidth and maxItemHeight vales according to current state of items */ updateMaxItemSize() { this.maxItemWidth = Math.max.apply(null, this.items.map((item) => { return item.w; })); this.maxItemHeight = Math.max.apply(null, this.items.map((item) => { return item.h; })); } /** * Update items properties of previously cached items */ restoreCachedItems() { const items = this.options.breakpoint ? this._itemsMap[this.options.breakpoint] : this._items; this.items .filter(item => this.isValidGridItem(item)) .forEach((item) => { const cachedItem = items.filter(cachedItm => { return cachedItm.$element === item.$element; })[0]; item.x = cachedItem.x; item.y = cachedItem.y; item.w = cachedItem.w; item.h = cachedItem.h; item.autoSize = cachedItem.autoSize; }); } /** * If item should react on grid * @param GridListItem item * @returns boolean */ isValidGridItem(item) { if (this.options.direction === 'none') { return !!item.itemComponent; } return true; } calculateCellWidth() { const gridsterWidth = parseFloat(window.getComputedStyle(this.gridsterComponent.$element).width); return gridsterWidth / this.options.lanes; } calculateCellHeight() { const gridsterHeight = parseFloat(window.getComputedStyle(this.gridsterComponent.$element).height); return gridsterHeight / this.options.lanes; } applySizeToItems() { for (let i = 0; i < this.items.length; i++) { this.items[i].applySize(); if (this.options.heightToFontSizeRatio) { this.items[i].$element.style['font-size'] = this._fontSize; } } } isCurrentElement(element) { if (!this.currentElement) { return false; } return element === this.currentElement; } snapItemSizeToGrid(item) { const itemSize = { width: parseInt(item.$element.style.width, 10) - 1, height: parseInt(item.$element.style.height, 10) - 1 }; let colSize = Math.round(itemSize.width / this.cellWidth); let rowSize = Math.round(itemSize.height / this.cellHeight); // Keep item minimum 1 colSize = Math.max(colSize, 1); rowSize = Math.max(rowSize, 1); // check if element is pinned if (this.gridList.isOverFixedArea(item.x, item.y, colSize, rowSize, item)) { return [item.w, item.h]; } return [colSize, rowSize]; } generateItemPosition(item) { let position; if (item.itemPrototype) { const coords = item.itemPrototype.getPositionToGridster(this); position = { x: Math.round(coords.x / this.cellWidth), y: Math.round(coords.y / this.cellHeight) }; } else { position = { x: Math.round(item.positionX / this.cellWidth), y: Math.round(item.positionY / this.cellHeight) }; } return position; } snapItemPositionToGrid(item) { const position = this.generateItemPosition(item); let col = position.x; let row = position.y; // Keep item position within the grid and don't let the item create more // than one extra column col = Math.max(col, 0); row = Math.max(row, 0); if (this.options.direction === 'horizontal') { col = Math.min(col, this._maxGridCols); } else { col = Math.min(col, Math.max(0, this.options.lanes - item.w)); } // check if element is pinned if (this.gridList.isOverFixedArea(col, row, item.w, item.h)) { return [item.x, item.y]; } return [col, row]; } dragSizeChanged(newSize) { if (!this.previousDragSize) { return true; } return (newSize[0] !== this.previousDragSize[0] || newSize[1] !== this.previousDragSize[1]); } dragPositionChanged(newPosition) { if (!this.previousDragPosition) { return true; } return (newPosition[0] !== this.previousDragPosition[0] || newPosition[1] !== this.previousDragPosition[1]); } highlightPositionForItem(item) { const size = item.calculateSize(this); const position = item.calculatePosition(this); this.$positionHighlight.style.width = size.width + 'px'; this.$positionHighlight.style.height = size.height + 'px'; this.$positionHighlight.style.left = position.left + 'px'; this.$positionHighlight.style.top = position.top + 'px'; this.$positionHighlight.style.display = ''; if (this.options.heightToFontSizeRatio) { this.$positionHighlight.style['font-size'] = this._fontSize; } } updateCachedItems() { // Notify the user with the items that changed since the previous snapshot this.triggerOnChange(null); this.gridsterOptions.responsiveOptions.forEach((options) => { this.triggerOnChange(options.breakpoint); }); this.copyItems(); } triggerOnChange(breakpoint) { const items = breakpoint ? this._itemsMap[breakpoint] : this._items; const changeItems = this.gridList.getChangedItems(items || [], breakpoint); changeItems .filter((itemChange) => { return itemChange.item.itemComponent; }) .forEach((itemChange) => { if (itemChange.changes.indexOf('x') >= 0) { itemChange.item.triggerChangeX(breakpoint); } if (itemChange.changes.indexOf('y') >= 0) { itemChange.item.triggerChangeY(breakpoint); } if (itemChange.changes.indexOf('w') >= 0) { itemChange.item.triggerChangeW(breakpoint); } if (itemChange.changes.indexOf('h') >= 0) { itemChange.item.triggerChangeH(breakpoint); } // should be called only once (not for each breakpoint) itemChange.item.itemComponent.change.emit({ item: itemChange.item, oldValues: itemChange.oldValues || {}, isNew: itemChange.isNew, changes: itemChange.changes, breakpoint: breakpoint }); }); } removePositionHighlight() { this.$positionHighlight.style.display = 'none'; } } GridsterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: GridsterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); GridsterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: GridsterService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: GridsterService, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIyZ3JpZHN0ZXIvc3JjL2xpYi9ncmlkc3Rlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQVEvQyxNQUFNLE9BQU8sZUFBZTtJQTJDeEI7UUF0Q0EsVUFBSyxHQUF3QixFQUFFLENBQUM7UUFDaEMsV0FBTSxHQUF3QixFQUFFLENBQUM7UUFDakMsY0FBUyxHQUFrRCxFQUFFLENBQUM7UUFDOUQsa0JBQWEsR0FBd0IsRUFBRSxDQUFDO1FBWXhDLDBCQUFxQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFVL0Isc0JBQWlCLEdBQTBCLElBQUksT0FBTyxFQUFFLENBQUM7UUFXeEQsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUduQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxD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Q0FBQztnQkFDdEMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2dCQUNyQixTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVMsSUFBSSxFQUFFO2dCQUNyQyxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7Z0JBQ3ZCLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTztnQkFDM0IsVUFBVSxFQUFFLFVBQVU7YUFDekIsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRU8sdUJBQXVCO1FBQzNCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztJQUNuRCxDQUFDOzs0R0Fwa0JRLGVBQWU7Z0hBQWYsZUFBZTsyRkFBZixlQUFlO2tCQUQzQixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IEdyaWRMaXN0IH0gZnJvbSAnLi9ncmlkTGlzdC9ncmlkTGlzdCc7XHJcbmltcG9ydCB7IElHcmlkc3Rlck9wdGlvbnMgfSBmcm9tICcuL0lHcmlkc3Rlck9wdGlvbnMnO1xyXG5pbXBvcnQgeyBJR3JpZHN0ZXJEcmFnZ2FibGVPcHRpb25zIH0gZnJvbSAnLi9JR3JpZHN0ZXJEcmFnZ2FibGVPcHRpb25zJztcclxuaW1wb3J0IHsgR3JpZExpc3RJdGVtIH0gZnJvbSAnLi9ncmlkTGlzdC9HcmlkTGlzdEl0ZW0nO1xyXG5pbXBvcnQgeyBHcmlkc3RlckNvbXBvbmVudCB9IGZyb20gJy4vZ3JpZHN0ZXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgR3JpZHN0ZXJPcHRpb25zIH0gZnJvbSAnLi9Hcmlkc3Rlck9wdGlvbnMnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgR3JpZHN0ZXJTZXJ2aWNlIHtcclxuICAgICRlbGVtZW50OiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICBncmlkTGlzdDogR3JpZExpc3Q7XHJcblxyXG4gICAgaXRlbXM6IEFycmF5PEdyaWRMaXN0SXRlbT4gPSBbXTtcclxuICAgIF9pdGVtczogQXJyYXk8R3JpZExpc3RJdGVtPiA9IFtdO1xyXG4gICAgX2l0ZW1zTWFwOiB7IFticmVha3BvaW50OiBzdHJpbmddOiBBcnJheTxHcmlkTGlzdEl0ZW0+IH0gPSB7fTtcclxuICAgIGRpc2FibGVkSXRlbXM6IEFycmF5PEdyaWRMaXN0SXRlbT4gPSBbXTtcclxuXHJcbiAgICBvcHRpb25zOiBJR3JpZHN0ZXJPcHRpb25zO1xyXG4gICAgZHJhZ2dhYmxlT3B0aW9uczogSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucztcclxuXHJcbiAgICBncmlkc3RlclJlY3Q6IENsaWVudFJlY3Q7XHJcbiAgICBncmlkc3RlclNjcm9sbERhdGE6IHsgc2Nyb2xsVG9wOiBudW1iZXIsIHNjcm9sbExlZnQ6IG51bWJlciB9O1xyXG5cclxuICAgIGdyaWRzdGVyT3B0aW9uczogR3JpZHN0ZXJPcHRpb25zO1xyXG5cclxuICAgIGdyaWRzdGVyQ29tcG9uZW50OiBHcmlkc3RlckNvbXBvbmVudDtcclxuXHJcbiAgICBkZWJvdW5jZVJlbmRlclN1YmplY3QgPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICAgIHB1YmxpYyAkcG9zaXRpb25IaWdobGlnaHQ6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgIHB1YmxpYyBtYXhJdGVtV2lkdGg6IG51bWJlcjtcclxuICAgIHB1YmxpYyBtYXhJdGVtSGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgcHVibGljIGNlbGxXaWR0aDogbnVtYmVyO1xyXG4gICAgcHVibGljIGNlbGxIZWlnaHQ6IG51bWJlcjtcclxuXHJcbiAgICBwdWJsaWMgaXRlbVJlbW92ZVN1YmplY3Q6IFN1YmplY3Q8R3JpZExpc3RJdGVtPiA9IG5ldyBTdWJqZWN0KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfZm9udFNpemU6IG51bWJlcjtcclxuXHJcbiAgICBwcml2YXRlIHByZXZpb3VzRHJhZ1Bvc2l0aW9uOiBBcnJheTxudW1iZXI+O1xyXG4gICAgcHJpdmF0ZSBwcmV2aW91c0RyYWdTaXplOiBBcnJheTxudW1iZXI+O1xyXG5cclxuICAgIHByaXZhdGUgY3VycmVudEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgIHByaXZhdGUgX21heEdyaWRDb2xzOiBudW1iZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBpc0luaXQgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLml0ZW1SZW1vdmVTdWJqZWN0LnBpcGUoZGVib3VuY2VUaW1lKDApKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRMaXN0LnB1bGxJdGVtc1RvTGVmdCgpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlZEl0ZW1zKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuZGVib3VuY2VSZW5kZXJTdWJqZWN0LnBpcGUoZGVib3VuY2VUaW1lKDApKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZW5kZXIoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNJbml0aWFsaXplZCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc0luaXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgaW5pdFxyXG4gICAgICogQHBhcmFtIGl0ZW1cclxuICAgICAqL1xyXG4gICAgcmVnaXN0ZXJJdGVtKGl0ZW06IEdyaWRMaXN0SXRlbSkge1xyXG5cclxuICAgICAgICB0aGlzLml0ZW1zLnB1c2goaXRlbSk7XHJcbiAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChncmlkc3RlckNvbXBvbmVudDogR3JpZHN0ZXJDb21wb25lbnQpIHtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3RlckNvbXBvbmVudCA9IGdyaWRzdGVyQ29tcG9uZW50O1xyXG5cclxuICAgICAgICB0aGlzLmRyYWdnYWJsZU9wdGlvbnMgPSBncmlkc3RlckNvbXBvbmVudC5kcmFnZ2FibGVPcHRpb25zO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyT3B0aW9ucyA9IGdyaWRzdGVyQ29tcG9uZW50LmdyaWRzdGVyT3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICBzdGFydCgpIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZU1heEl0ZW1TaXplKCk7XHJcblxyXG4gICAgICAgIC8vIFVzZWQgdG8gaGlnaGxpZ2h0IGEgcG9zaXRpb24gYW4gZWxlbWVudCB3aWxsIGxhbmQgb24gdXBvbiBkcm9wXHJcbiAgICAgICAgaWYgKHRoaXMuJHBvc2l0aW9uSGlnaGxpZ2h0KSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlUG9zaXRpb25IaWdobGlnaHQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaW5pdEdyaWRMaXN0KCk7XHJcblxyXG4gICAgICAgIHRoaXMuaXNJbml0ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29weUl0ZW1zKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZml4SXRlbXNQb3NpdGlvbnMoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQucmVmbG93R3JpZHN0ZXIodHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQuc2V0UmVhZHkoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0R3JpZExpc3QoKSB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGluc3RhbmNlIG9mIEdyaWRMaXN0IChkZWNvdXBsZWQgbGliIGZvciBoYW5kbGluZyB0aGUgZ3JpZFxyXG4gICAgICAgIC8vIHBvc2l0aW9uaW5nIGFuZCBzb3J0aW5nIHBvc3QtZHJhZyBhbmQgZHJvcHBpbmcpXHJcbiAgICAgICAgdGhpcy5ncmlkTGlzdCA9IG5ldyBHcmlkTGlzdCh0aGlzLml0ZW1zLCB0aGlzLm9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbmRlcigpIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZU1heEl0ZW1TaXplKCk7XHJcbiAgICAgICAgdGhpcy5ncmlkTGlzdC5nZW5lcmF0ZUdyaWQoKTtcclxuICAgICAgICB0aGlzLmFwcGx5U2l6ZVRvSXRlbXMoKTtcclxuICAgICAgICB0aGlzLmFwcGx5UG9zaXRpb25Ub0l0ZW1zKCk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoTGluZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICByZWZsb3coKSB7XHJcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVDZWxsU2l6ZSgpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZml4SXRlbXNQb3NpdGlvbnMoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZXNwb25zaXZlU2l6ZXMpIHtcclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5maXhJdGVtc1Bvc2l0aW9ucyh0aGlzLm9wdGlvbnMpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnModGhpcy5ncmlkc3Rlck9wdGlvbnMuYmFzaWNPcHRpb25zKTtcclxuICAgICAgICAgICAgdGhpcy5ncmlkc3Rlck9wdGlvbnMucmVzcG9uc2l2ZU9wdGlvbnMuZm9yRWFjaCgob3B0aW9uczogSUdyaWRzdGVyT3B0aW9ucykgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5maXhJdGVtc1Bvc2l0aW9ucyhvcHRpb25zKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlZEl0ZW1zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlSXRlbShpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICBjb25zdCBpZHggPSB0aGlzLml0ZW1zLmluZGV4T2YoaXRlbSk7XHJcblxyXG4gICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLml0ZW1zLnNwbGljZSh0aGlzLml0ZW1zLmluZGV4T2YoaXRlbSksIDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5ncmlkTGlzdC5kZWxldGVJdGVtUG9zaXRpb25Gcm9tR3JpZChpdGVtKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW1Gcm9tQ2FjaGUoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgb25SZXNpemVTdGFydChpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gaXRlbS4kZWxlbWVudDtcclxuXHJcbiAgICAgICAgdGhpcy5jb3B5SXRlbXMoKTtcclxuXHJcbiAgICAgICAgdGhpcy5fbWF4R3JpZENvbHMgPSB0aGlzLmdyaWRMaXN0LmdyaWQubGVuZ3RoO1xyXG5cclxuICAgICAgICB0aGlzLmhpZ2hsaWdodFBvc2l0aW9uRm9ySXRlbShpdGVtKTtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3RlckNvbXBvbmVudC5pc1Jlc2l6aW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoTGluZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBvblJlc2l6ZURyYWcoaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHRoaXMuc25hcEl0ZW1TaXplVG9HcmlkKGl0ZW0pO1xyXG4gICAgICAgIGNvbnN0IHNpemVDaGFuZ2VkID0gdGhpcy5kcmFnU2l6ZUNoYW5nZWQobmV3U2l6ZSk7XHJcbiAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB0aGlzLnNuYXBJdGVtUG9zaXRpb25Ub0dyaWQoaXRlbSk7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25DaGFuZ2VkID0gdGhpcy5kcmFnUG9zaXRpb25DaGFuZ2VkKG5ld1Bvc2l0aW9uKTtcclxuXHJcbiAgICAgICAgaWYgKHNpemVDaGFuZ2VkIHx8IHBvc2l0aW9uQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAvLyBSZWdlbmVyYXRlIHRoZSBncmlkIHdpdGggdGhlIHBvc2l0aW9ucyBmcm9tIHdoZW4gdGhlIGRyYWcgc3RhcnRlZFxyXG4gICAgICAgICAgICB0aGlzLnJlc3RvcmVDYWNoZWRJdGVtcygpO1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRMaXN0LmdlbmVyYXRlR3JpZCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5wcmV2aW91c0RyYWdQb3NpdGlvbiA9IG5ld1Bvc2l0aW9uO1xyXG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzRHJhZ1NpemUgPSBuZXdTaXplO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5tb3ZlQW5kUmVzaXplKGl0ZW0sIG5ld1Bvc2l0aW9uLCB7dzogbmV3U2l6ZVswXSwgaDogbmV3U2l6ZVsxXX0pO1xyXG5cclxuICAgICAgICAgICAgLy8gVmlzdWFsbHkgdXBkYXRlIGl0ZW0gcG9zaXRpb25zIGFuZCBoaWdobGlnaHQgc2hhcGVcclxuICAgICAgICAgICAgdGhpcy5hcHBseVBvc2l0aW9uVG9JdGVtcyh0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRQb3NpdGlvbkZvckl0ZW0oaXRlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uUmVzaXplU3RvcChpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ2FjaGVkSXRlbXMoKTtcclxuICAgICAgICB0aGlzLnByZXZpb3VzRHJhZ1NpemUgPSBudWxsO1xyXG5cclxuICAgICAgICB0aGlzLnJlbW92ZVBvc2l0aW9uSGlnaGxpZ2h0KCk7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQuaXNSZXNpemluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRMaXN0LnB1bGxJdGVtc1RvTGVmdChpdGVtKTtcclxuICAgICAgICB0aGlzLmRlYm91bmNlUmVuZGVyU3ViamVjdC5uZXh0KG51bGwpO1xyXG5cclxuICAgICAgICB0aGlzLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TdGFydChpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gaXRlbS4kZWxlbWVudDtcclxuICAgICAgICAvLyBpdGVtQ3RybC5pc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICAvLyBDcmVhdGUgYSBkZWVwIGNvcHkgb2YgdGhlIGl0ZW1zOyB3ZSB1c2UgdGhlbSB0byByZXZlcnQgdGhlIGl0ZW1cclxuICAgICAgICAvLyBwb3NpdGlvbnMgYWZ0ZXIgZWFjaCBkcmFnIGNoYW5nZSwgbWFraW5nIGFuIGVudGlyZSBkcmFnIG9wZXJhdGlvbiBsZXNzXHJcbiAgICAgICAgLy8gZGlzdHJ1Y3RhYmxlXHJcbiAgICAgICAgdGhpcy5jb3B5SXRlbXMoKTtcclxuXHJcbiAgICAgICAgLy8gU2luY2UgZHJhZ2dpbmcgYWN0dWFsbHkgYWx0ZXJzIHRoZSBncmlkLCB3ZSBuZWVkIHRvIGVzdGFibGlzaCB0aGUgbnVtYmVyXHJcbiAgICAgICAgLy8gb2YgY29scyAoKzEgZXh0cmEpIGJlZm9yZSB0aGUgZHJhZyBzdGFydHNcclxuXHJcbiAgICAgICAgdGhpcy5fbWF4R3JpZENvbHMgPSB0aGlzLmdyaWRMaXN0LmdyaWQubGVuZ3RoO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQudXBkYXRlR3JpZHN0ZXJFbGVtZW50RGF0YSgpO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hMaW5lcygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uRHJhZyhpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICBjb25zdCBuZXdQb3Npd