@rybos/angular2gridster
Version:
[](https://badge.fury.io/js/angular2gridster)
455 lines • 69.1 kB
JavaScript
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