angular2gridsterv3
Version:
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();
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: "13.4.0", ngImport: i0, type: GridsterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
GridsterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GridsterService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GridsterService, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIyZ3JpZHN0ZXJ2My9zcmMvbGliL2dyaWRzdGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBUS9DLE1BQU0sT0FBTyxlQUFlO0lBMkN4QjtRQXRDQSxVQUFLLEdBQXdCLEVBQUUsQ0FBQztRQUNoQyxXQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUNqQyxjQUFTLEdBQWtELEVBQUUsQ0FBQztRQUM5RCxrQkFBYSxHQUF3QixFQUFFLENBQUM7UUFZeEMsMEJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQVVyQyxzQkFBaUIsR0FBMEIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQVd4RCxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBR25CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFD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Q3RDLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtnQkFDckIsU0FBUyxFQUFFLFVBQVUsQ0FBQyxTQUFTLElBQUksRUFBRTtnQkFDckMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO2dCQUN2QixPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87Z0JBQzNCLFVBQVUsRUFBRSxVQUFVO2FBQ3pCLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVPLHVCQUF1QjtRQUMzQixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDbkQsQ0FBQzs7NEdBcGtCUSxlQUFlO2dIQUFmLGVBQWU7MkZBQWYsZUFBZTtrQkFEM0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBHcmlkTGlzdCB9IGZyb20gJy4vZ3JpZExpc3QvZ3JpZExpc3QnO1xyXG5pbXBvcnQgeyBJR3JpZHN0ZXJPcHRpb25zIH0gZnJvbSAnLi9JR3JpZHN0ZXJPcHRpb25zJztcclxuaW1wb3J0IHsgSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucyB9IGZyb20gJy4vSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucyc7XHJcbmltcG9ydCB7IEdyaWRMaXN0SXRlbSB9IGZyb20gJy4vZ3JpZExpc3QvR3JpZExpc3RJdGVtJztcclxuaW1wb3J0IHsgR3JpZHN0ZXJDb21wb25lbnQgfSBmcm9tICcuL2dyaWRzdGVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEdyaWRzdGVyT3B0aW9ucyB9IGZyb20gJy4vR3JpZHN0ZXJPcHRpb25zJztcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEdyaWRzdGVyU2VydmljZSB7XHJcbiAgICAkZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgZ3JpZExpc3Q6IEdyaWRMaXN0O1xyXG5cclxuICAgIGl0ZW1zOiBBcnJheTxHcmlkTGlzdEl0ZW0+ID0gW107XHJcbiAgICBfaXRlbXM6IEFycmF5PEdyaWRMaXN0SXRlbT4gPSBbXTtcclxuICAgIF9pdGVtc01hcDogeyBbYnJlYWtwb2ludDogc3RyaW5nXTogQXJyYXk8R3JpZExpc3RJdGVtPiB9ID0ge307XHJcbiAgICBkaXNhYmxlZEl0ZW1zOiBBcnJheTxHcmlkTGlzdEl0ZW0+ID0gW107XHJcblxyXG4gICAgb3B0aW9uczogSUdyaWRzdGVyT3B0aW9ucztcclxuICAgIGRyYWdnYWJsZU9wdGlvbnM6IElHcmlkc3RlckRyYWdnYWJsZU9wdGlvbnM7XHJcblxyXG4gICAgZ3JpZHN0ZXJSZWN0OiBDbGllbnRSZWN0O1xyXG4gICAgZ3JpZHN0ZXJTY3JvbGxEYXRhOiB7IHNjcm9sbFRvcDogbnVtYmVyLCBzY3JvbGxMZWZ0OiBudW1iZXIgfTtcclxuXHJcbiAgICBncmlkc3Rlck9wdGlvbnM6IEdyaWRzdGVyT3B0aW9ucztcclxuXHJcbiAgICBncmlkc3RlckNvbXBvbmVudDogR3JpZHN0ZXJDb21wb25lbnQ7XHJcblxyXG4gICAgZGVib3VuY2VSZW5kZXJTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgICBwdWJsaWMgJHBvc2l0aW9uSGlnaGxpZ2h0OiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICBwdWJsaWMgbWF4SXRlbVdpZHRoOiBudW1iZXI7XHJcbiAgICBwdWJsaWMgbWF4SXRlbUhlaWdodDogbnVtYmVyO1xyXG5cclxuICAgIHB1YmxpYyBjZWxsV2lkdGg6IG51bWJlcjtcclxuICAgIHB1YmxpYyBjZWxsSGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgcHVibGljIGl0ZW1SZW1vdmVTdWJqZWN0OiBTdWJqZWN0PEdyaWRMaXN0SXRlbT4gPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICAgIHByaXZhdGUgX2ZvbnRTaXplOiBudW1iZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBwcmV2aW91c0RyYWdQb3NpdGlvbjogQXJyYXk8bnVtYmVyPjtcclxuICAgIHByaXZhdGUgcHJldmlvdXNEcmFnU2l6ZTogQXJyYXk8bnVtYmVyPjtcclxuXHJcbiAgICBwcml2YXRlIGN1cnJlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICBwcml2YXRlIF9tYXhHcmlkQ29sczogbnVtYmVyO1xyXG5cclxuICAgIHByaXZhdGUgaXNJbml0ID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5pdGVtUmVtb3ZlU3ViamVjdC5waXBlKGRlYm91bmNlVGltZSgwKSkuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5wdWxsSXRlbXNUb0xlZnQoKTtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRJdGVtcygpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmRlYm91bmNlUmVuZGVyU3ViamVjdC5waXBlKGRlYm91bmNlVGltZSgwKSkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVuZGVyKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzSW5pdGlhbGl6ZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNJbml0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGluaXRcclxuICAgICAqIEBwYXJhbSBpdGVtXHJcbiAgICAgKi9cclxuICAgIHJlZ2lzdGVySXRlbShpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuXHJcbiAgICAgICAgdGhpcy5pdGVtcy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXQoZ3JpZHN0ZXJDb21wb25lbnQ6IEdyaWRzdGVyQ29tcG9uZW50KSB7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQgPSBncmlkc3RlckNvbXBvbmVudDtcclxuXHJcbiAgICAgICAgdGhpcy5kcmFnZ2FibGVPcHRpb25zID0gZ3JpZHN0ZXJDb21wb25lbnQuZHJhZ2dhYmxlT3B0aW9ucztcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlck9wdGlvbnMgPSBncmlkc3RlckNvbXBvbmVudC5ncmlkc3Rlck9wdGlvbnM7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnQoKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVNYXhJdGVtU2l6ZSgpO1xyXG5cclxuICAgICAgICAvLyBVc2VkIHRvIGhpZ2hsaWdodCBhIHBvc2l0aW9uIGFuIGVsZW1lbnQgd2lsbCBsYW5kIG9uIHVwb24gZHJvcFxyXG4gICAgICAgIGlmICh0aGlzLiRwb3NpdGlvbkhpZ2hsaWdodCkge1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVBvc2l0aW9uSGlnaGxpZ2h0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmluaXRHcmlkTGlzdCgpO1xyXG5cclxuICAgICAgICB0aGlzLmlzSW5pdCA9IHRydWU7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNvcHlJdGVtcygpO1xyXG4gICAgICAgICAgICB0aGlzLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LnJlZmxvd0dyaWRzdGVyKHRydWUpO1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LnNldFJlYWR5KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdEdyaWRMaXN0KCkge1xyXG4gICAgICAgIC8vIENyZWF0ZSBpbnN0YW5jZSBvZiBHcmlkTGlzdCAoZGVjb3VwbGVkIGxpYiBmb3IgaGFuZGxpbmcgdGhlIGdyaWRcclxuICAgICAgICAvLyBwb3NpdGlvbmluZyBhbmQgc29ydGluZyBwb3N0LWRyYWcgYW5kIGRyb3BwaW5nKVxyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QgPSBuZXcgR3JpZExpc3QodGhpcy5pdGVtcywgdGhpcy5vcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICByZW5kZXIoKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVNYXhJdGVtU2l6ZSgpO1xyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QuZ2VuZXJhdGVHcmlkKCk7XHJcbiAgICAgICAgdGhpcy5hcHBseVNpemVUb0l0ZW1zKCk7XHJcbiAgICAgICAgdGhpcy5hcHBseVBvc2l0aW9uVG9JdGVtcygpO1xyXG4gICAgICAgIHRoaXMucmVmcmVzaExpbmVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVmbG93KCkge1xyXG4gICAgICAgIHRoaXMuY2FsY3VsYXRlQ2VsbFNpemUoKTtcclxuICAgICAgICB0aGlzLnJlbmRlcigpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpeEl0ZW1zUG9zaXRpb25zKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmVzcG9uc2l2ZVNpemVzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnModGhpcy5vcHRpb25zKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRMaXN0LmZpeEl0ZW1zUG9zaXRpb25zKHRoaXMuZ3JpZHN0ZXJPcHRpb25zLmJhc2ljT3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXJPcHRpb25zLnJlc3BvbnNpdmVPcHRpb25zLmZvckVhY2goKG9wdGlvbnM6IElHcmlkc3Rlck9wdGlvbnMpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRJdGVtcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUl0ZW0oaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pO1xyXG5cclxuICAgICAgICBpZiAoaWR4ID49IDApIHtcclxuICAgICAgICAgICAgdGhpcy5pdGVtcy5zcGxpY2UodGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pLCAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QuZGVsZXRlSXRlbVBvc2l0aW9uRnJvbUdyaWQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUNhY2hlKGl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uUmVzaXplU3RhcnQoaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGl0ZW0uJGVsZW1lbnQ7XHJcblxyXG4gICAgICAgIHRoaXMuY29weUl0ZW1zKCk7XHJcblxyXG4gICAgICAgIHRoaXMuX21heEdyaWRDb2xzID0gdGhpcy5ncmlkTGlzdC5ncmlkLmxlbmd0aDtcclxuXHJcbiAgICAgICAgdGhpcy5oaWdobGlnaHRQb3NpdGlvbkZvckl0ZW0oaXRlbSk7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQuaXNSZXNpemluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaExpbmVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25SZXNpemVEcmFnKGl0ZW06IEdyaWRMaXN0SXRlbSkge1xyXG4gICAgICAgIGNvbnN0IG5ld1NpemUgPSB0aGlzLnNuYXBJdGVtU2l6ZVRvR3JpZChpdGVtKTtcclxuICAgICAgICBjb25zdCBzaXplQ2hhbmdlZCA9IHRoaXMuZHJhZ1NpemVDaGFuZ2VkKG5ld1NpemUpO1xyXG4gICAgICAgIGNvbnN0IG5ld1Bvc2l0aW9uID0gdGhpcy5zbmFwSXRlbVBvc2l0aW9uVG9HcmlkKGl0ZW0pO1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQ2hhbmdlZCA9IHRoaXMuZHJhZ1Bvc2l0aW9uQ2hhbmdlZChuZXdQb3NpdGlvbik7XHJcblxyXG4gICAgICAgIGlmIChzaXplQ2hhbmdlZCB8fCBwb3NpdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgLy8gUmVnZW5lcmF0ZSB0aGUgZ3JpZCB3aXRoIHRoZSBwb3NpdGlvbnMgZnJvbSB3aGVuIHRoZSBkcmFnIHN0YXJ0ZWRcclxuICAgICAgICAgICAgdGhpcy5yZXN0b3JlQ2FjaGVkSXRlbXMoKTtcclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5nZW5lcmF0ZUdyaWQoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXNEcmFnUG9zaXRpb24gPSBuZXdQb3NpdGlvbjtcclxuICAgICAgICAgICAgdGhpcy5wcmV2aW91c0RyYWdTaXplID0gbmV3U2l6ZTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QubW92ZUFuZFJlc2l6ZShpdGVtLCBuZXdQb3NpdGlvbiwge3c6IG5ld1NpemVbMF0sIGg6IG5ld1NpemVbMV19KTtcclxuXHJcbiAgICAgICAgICAgIC8vIFZpc3VhbGx5IHVwZGF0ZSBpdGVtIHBvc2l0aW9ucyBhbmQgaGlnaGxpZ2h0IHNoYXBlXHJcbiAgICAgICAgICAgIHRoaXMuYXBwbHlQb3NpdGlvblRvSXRlbXModHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuaGlnaGxpZ2h0UG9zaXRpb25Gb3JJdGVtKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBvblJlc2l6ZVN0b3AoaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlZEl0ZW1zKCk7XHJcbiAgICAgICAgdGhpcy5wcmV2aW91c0RyYWdTaXplID0gbnVsbDtcclxuXHJcbiAgICAgICAgdGhpcy5yZW1vdmVQb3NpdGlvbkhpZ2hsaWdodCgpO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LmlzUmVzaXppbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkTGlzdC5wdWxsSXRlbXNUb0xlZnQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5kZWJvdW5jZVJlbmRlclN1YmplY3QubmV4dCgpO1xyXG5cclxuICAgICAgICB0aGlzLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TdGFydChpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gaXRlbS4kZWxlbWVudDtcclxuICAgICAgICAvLyBpdGVtQ3RybC5pc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICAvLyBDcmVhdGUgYSBkZWVwIGNvcHkgb2YgdGhlIGl0ZW1zOyB3ZSB1c2UgdGhlbSB0byByZXZlcnQgdGhlIGl0ZW1cclxuICAgICAgICAvLyBwb3NpdGlvbnMgYWZ0ZXIgZWFjaCBkcmFnIGNoYW5nZSwgbWFraW5nIGFuIGVudGlyZSBkcmFnIG9wZXJhdGlvbiBsZXNzXHJcbiAgICAgICAgLy8gZGlzdHJ1Y3RhYmxlXHJcbiAgICAgICAgdGhpcy5jb3B5SXRlbXMoKTtcclxuXHJcbiAgICAgICAgLy8gU2luY2UgZHJhZ2dpbmcgYWN0dWFsbHkgYWx0ZXJzIHRoZSBncmlkLCB3ZSBuZWVkIHRvIGVzdGFibGlzaCB0aGUgbnVtYmVyXHJcbiAgICAgICAgLy8gb2YgY29scyAoKzEgZXh0cmEpIGJlZm9yZSB0aGUgZHJhZyBzdGFydHNcclxuXHJcbiAgICAgICAgdGhpcy5fbWF4R3JpZENvbHMgPSB0aGlzLmdyaWRMaXN0LmdyaWQubGVuZ3RoO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQudXBkYXRlR3JpZHN0ZXJFbGVtZW50RGF0YSgpO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hMaW5lcygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uRHJhZyhpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICBjb25zdCBuZXdQb3NpdGlvbiA9IHRoa