UNPKG

angular2gridsterv3

Version:
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(); 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIyZ3JpZHN0ZXJ2My9zcmMvbGliL2dyaWRzdGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBUS9DLE1BQU0sT0FBTyxlQUFlO0lBMkN4QjtRQXRDQSxVQUFLLEdBQXdCLEVBQUUsQ0FBQztRQUNoQyxXQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUNqQyxjQUFTLEdBQWtELEVBQUUsQ0FBQztRQUM5RCxrQkFBYSxHQUF3QixFQUFFLENBQUM7UUFZeEMsMEJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQVVyQyxzQkFBaUIsR0FBMEIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQVd4RCxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBR25CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVELGFBQWE7UUFDVCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7T0FHRztJQUNILFlBQVksQ0FBQyxJQUFrQjtRQUUzQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsSUFBSSxDQUFDLGlCQUFvQztRQUVyQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7UUFFM0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDO1FBRTNELElBQUksQ0FBQyxlQUFlLEdBQUcsaUJBQWlCLENBQUMsZUFBZSxDQUFDO0lBQzdELENBQUM7SUFFRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFekIsaUVBQWlFO1FBQ2pFLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3pCLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1NBQ2xDO1FBRUQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBRW5CLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFFekIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsWUFBWTtRQUNSLG1FQUFtRTtRQUNuRSxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxNQUFNO1FBQ0YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFO1lBQzlCLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2pEO2FBQU07WUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUF5QixFQUFFLEVBQUU7Z0JBQ3pFLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0MsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBa0I7UUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFO1lBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDbEQ7UUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsYUFBYSxDQUFDLElBQWtCO1FBQzVCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUVwQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFakIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFOUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBRXpDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsWUFBWSxDQUFDLElBQWtCO1FBQzNCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFOUQsSUFBSSxXQUFXLElBQUksZUFBZSxFQUFFO1lBQ2hDLG9FQUFvRTtZQUNwRSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRTdCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxXQUFXLENBQUM7WUFDeEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQztZQUVoQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLEVBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUUvRSxxREFBcUQ7WUFDckQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN2QztJQUNMLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBa0I7UUFDM0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUU3QixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUUvQixJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUUxQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFbEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUFrQjtRQUN0QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDcEMsOEJBQThCO1FBQzlCLGtFQUFrRTtRQUNsRSx5RUFBeUU7UUFDekUsZUFBZTtRQUNmLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVqQiwyRUFBMkU7UUFDM0UsNENBQTRDO1FBRTVDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRTlDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBRW5ELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsTUFBTSxDQUFDLElBQWtCO1FBQ3JCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0RCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUV2QyxvRUFBb0U7WUFDcEUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUU3QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsV0FBVyxDQUFDO1lBQ3hDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssTUFBTTtnQkFDakMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxFQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUU7Z0JBQ3RGLE9BQU87YUFDVjtZQUVELGlFQUFpRTtZQUNqRSwwQ0FBMEM7WUFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFFcEQscURBQXFEO1lBQ3JELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkM7SUFDTCxDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDOUMsQ0FBQztJQUVELFNBQVMsQ0FBRSxJQUFrQjtRQUV6QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFZCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUU7WUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDN0I7UUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsTUFBTSxDQUFDLElBQWtCO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFFakMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFFL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFcEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFFMUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxLQUFLLFlBQVksRUFBRTtZQUN6QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1NBQzlGO2FBQU07WUFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1NBQy9GO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFO1lBQ3BDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDO1NBQ3pFO0lBQ0wsQ0FBQztJQUVELG9CQUFvQixDQUFDLG9CQUFxQjtRQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7WUFDdEIsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1NBQy9CO1FBQ0QsbUNBQW1DO1FBQ25DLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN4QywwREFBMEQ7WUFDMUQsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDL0MsU0FBUzthQUNaO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDckM7UUFFRCxNQUFNLEtBQUssR0FBZ0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFDdEUsd0VBQXdFO1FBQ3hFLHdEQUF3RDtRQUN4RCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxLQUFLLFlBQVksRUFBRTtZQUN6QyxNQUFNLGlCQUFpQixHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUN4QixLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLGlCQUFpQixDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQztTQUVqRzthQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2xDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0UsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDakcsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1NBQzFCO0lBQ0wsQ0FBQztJQUVELFlBQVk7UUFDUixNQUFNLGlCQUFpQixHQUFnQixJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUVsRixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU87WUFDaEQsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDdkcsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLFNBQVMsQ0FBQztZQUN6RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksYUFBYSxDQUFDO1lBQ3pFLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUM7WUFDakQsTUFBTSxVQUFVLEdBQUcsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUVsQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsY0FBYyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsTUFBTSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUM7WUFDcEYsaUJBQWlCLENBQUMsS0FBSyxDQUFDLGtCQUFrQixHQUFHLElBQUksVUFBVSxPQUFPLFVBQVUsSUFBSSxDQUFDO1lBQ2pGLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUc7NENBQ1YsVUFBVSxJQUFJLFVBQVUsT0FBTyxZQUFZLElBQUksVUFBVTs2Q0FDeEQsVUFBVSxJQUFJLFVBQVUsT0FBTyxZQUFZLElBQUksVUFBVTthQUN6RixDQUFDO1NBQ0w7YUFBTTtZQUNILGlCQUFpQixDQUFDLEtBQUssQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1lBQzVDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7WUFDaEQsaUJBQWlCLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7U0FDaEQ7SUFDTCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsSUFBa0I7UUFDMUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTTthQUNwQixNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVqRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7YUFDdEIsT0FBTyxDQUFDLENBQUMsVUFBa0IsRUFBRSxFQUFFO1lBQzVCLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7aUJBQ2xELE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JFLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVPLFNBQVM7UUFDYixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLO2FBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDMUMsR0FBRyxDQUFDLENBQUMsSUFBa0IsRUFBRSxFQUFFO1lBQ3hCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRVAsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUF5QixFQUFFLEVBQUU7WUFDekUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUs7aUJBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQzFDLEdBQUcsQ0FBQyxDQUFDLElBQWtCLEVBQUUsRUFBRTtnQkFDeEIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3RELENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDOUIsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDUixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUMvQixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNaLENBQUM7SUFFRDs7T0FFRztJQUNLLGtCQUFrQjtRQUN0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRTlGLElBQUksQ0FBQyxLQUFLO2FBQ0wsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUMxQyxPQUFPLENBQUMsQ0FBQyxJQUFrQixFQUFFLEVBQUU7WUFDNUIsTUFBTSxVQUFVLEdBQWlCLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQ3RELE9BQU8sU0FBUyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDO1lBQ2hELENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRU4sSUFBSSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUV0QixJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDdEIsSUFBSSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZUFBZSxDQUFDLElBQWtCO1FBQ3RDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssTUFBTSxFQUFFO1lBQ25DLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7U0FDL0I7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRU8sa0JBQWtCO1FBQ3RCLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWpHLE9BQU8sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQzlDLENBQUM7SUFFTyxtQkFBbUI7UUFDdkIsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkcsT0FBTyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDL0MsQ0FBQztJQUVPLGdCQUFnQjtRQUNwQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUUxQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO2FBQzlEO1NBQ0o7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsT0FBTztRQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN0QixPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUNELE9BQU8sT0FBTyxLQUFLLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDM0MsQ0FBQztJQUVPLGtCQUFrQixDQUFDLElBQWtCO1FBQ3pDLE1BQU0sUUFBUSxHQUFHO1lBQ2IsS0FBSyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztZQUNsRCxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDO1NBQ3ZELENBQUM7UUFFRixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFNUQsc0JBQXNCO1FBQ3RCLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFL0IsNkJBQTZCO1FBQzdCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDdkUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzNCO1FBRUQsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRU8sb0JBQW9CLENBQUMsSUFBa0I7UUFDM0MsSUFBSSxRQUFRLENBQUM7UUFFYixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDcEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5RCxRQUFRLEdBQUc7Z0JBQ1AsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUN4QyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDNUMsQ0FBQztTQUNMO2FBQU07WUFDSCxRQUFRLEdBQUc7Z0JBQ1AsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUM5QyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDbEQsQ0FBQztTQUNMO1FBRUQsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUVPLHNCQUFzQixDQUFDLElBQWtCO1FBQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLEdBQUcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFckIsd0VBQXdFO1FBQ3hFLHdCQUF3QjtRQUN4QixHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkIsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXZCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssWUFBWSxFQUFFO1lBQ3pDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDMUM7YUFBTTtZQUNILEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNqRTtRQUVELDZCQUE2QjtRQUM3QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzNCO1FBRUQsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBRU8sZUFBZSxDQUFDLE9BQU87UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN4QixPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1lBQzNDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsV0FBVztRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO1lBQzVCLE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7WUFDbkQsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFTyx3QkFBd0IsQ0FBQyxJQUFJO1FBQ2pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTlDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ3hELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQzFELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQzFELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBQ3hELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUUzQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUU7WUFDcEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1NBQy9EO0lBQ0wsQ0FBQztJQUVNLGlCQUFpQjtRQUNwQiwwRUFBMEU7UUFDMUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQXlCLEVBQUUsRUFBRTtZQUN6RSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRU8sZUFBZSxDQUFDLFVBQVc7UUFDL0IsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3BFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFM0UsV0FBVzthQUNOLE1BQU0sQ0FBQyxDQUFDLFVBQWUsRUFBRSxFQUFFO1lBQ3hCLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDekMsQ0FBQyxDQUFDO2FBQ0QsT0FBTyxDQUFDLENBQUMsVUFBZSxFQUFFLEVBQUU7WUFFekIsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3RDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzlDO1lBQ0QsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3RDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzlDO1lBQ0QsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3RDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzlDO1lBQ0QsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3RDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzlDO1lBQ0QsdURBQXVEO1lBQ3ZELFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7Z0JBQ3RDLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtnQkFDckIsU0FBUyxFQUFFLFVBQVUsQ0FBQyxTQUFTLElBQUksRUFBRTtnQkFDckMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO2dCQUN2QixPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87Z0JBQzNCLFVBQVUsRUFBRSxVQUFVO2FBQ3pCLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVPLHVCQUF1QjtRQUMzQixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDbkQsQ0FBQzs7NEdBcGtCUSxlQUFlO2dIQUFmLGVBQWU7MkZBQWYsZUFBZTtrQkFEM0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBHcmlkTGlzdCB9IGZyb20gJy4vZ3JpZExpc3QvZ3JpZExpc3QnO1xyXG5pbXBvcnQgeyBJR3JpZHN0ZXJPcHRpb25zIH0gZnJvbSAnLi9JR3JpZHN0ZXJPcHRpb25zJztcclxuaW1wb3J0IHsgSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucyB9IGZyb20gJy4vSUdyaWRzdGVyRHJhZ2dhYmxlT3B0aW9ucyc7XHJcbmltcG9ydCB7IEdyaWRMaXN0SXRlbSB9IGZyb20gJy4vZ3JpZExpc3QvR3JpZExpc3RJdGVtJztcclxuaW1wb3J0IHsgR3JpZHN0ZXJDb21wb25lbnQgfSBmcm9tICcuL2dyaWRzdGVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEdyaWRzdGVyT3B0aW9ucyB9IGZyb20gJy4vR3JpZHN0ZXJPcHRpb25zJztcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEdyaWRzdGVyU2VydmljZSB7XHJcbiAgICAkZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgZ3JpZExpc3Q6IEdyaWRMaXN0O1xyXG5cclxuICAgIGl0ZW1zOiBBcnJheTxHcmlkTGlzdEl0ZW0+ID0gW107XHJcbiAgICBfaXRlbXM6IEFycmF5PEdyaWRMaXN0SXRlbT4gPSBbXTtcclxuICAgIF9pdGVtc01hcDogeyBbYnJlYWtwb2ludDogc3RyaW5nXTogQXJyYXk8R3JpZExpc3RJdGVtPiB9ID0ge307XHJcbiAgICBkaXNhYmxlZEl0ZW1zOiBBcnJheTxHcmlkTGlzdEl0ZW0+ID0gW107XHJcblxyXG4gICAgb3B0aW9uczogSUdyaWRzdGVyT3B0aW9ucztcclxuICAgIGRyYWdnYWJsZU9wdGlvbnM6IElHcmlkc3RlckRyYWdnYWJsZU9wdGlvbnM7XHJcblxyXG4gICAgZ3JpZHN0ZXJSZWN0OiBDbGllbnRSZWN0O1xyXG4gICAgZ3JpZHN0ZXJTY3JvbGxEYXRhOiB7IHNjcm9sbFRvcDogbnVtYmVyLCBzY3JvbGxMZWZ0OiBudW1iZXIgfTtcclxuXHJcbiAgICBncmlkc3Rlck9wdGlvbnM6IEdyaWRzdGVyT3B0aW9ucztcclxuXHJcbiAgICBncmlkc3RlckNvbXBvbmVudDogR3JpZHN0ZXJDb21wb25lbnQ7XHJcblxyXG4gICAgZGVib3VuY2VSZW5kZXJTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgICBwdWJsaWMgJHBvc2l0aW9uSGlnaGxpZ2h0OiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICBwdWJsaWMgbWF4SXRlbVdpZHRoOiBudW1iZXI7XHJcbiAgICBwdWJsaWMgbWF4SXRlbUhlaWdodDogbnVtYmVyO1xyXG5cclxuICAgIHB1YmxpYyBjZWxsV2lkdGg6IG51bWJlcjtcclxuICAgIHB1YmxpYyBjZWxsSGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgcHVibGljIGl0ZW1SZW1vdmVTdWJqZWN0OiBTdWJqZWN0PEdyaWRMaXN0SXRlbT4gPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICAgIHByaXZhdGUgX2ZvbnRTaXplOiBudW1iZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBwcmV2aW91c0RyYWdQb3NpdGlvbjogQXJyYXk8bnVtYmVyPjtcclxuICAgIHByaXZhdGUgcHJldmlvdXNEcmFnU2l6ZTogQXJyYXk8bnVtYmVyPjtcclxuXHJcbiAgICBwcml2YXRlIGN1cnJlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuXHJcbiAgICBwcml2YXRlIF9tYXhHcmlkQ29sczogbnVtYmVyO1xyXG5cclxuICAgIHByaXZhdGUgaXNJbml0ID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5pdGVtUmVtb3ZlU3ViamVjdC5waXBlKGRlYm91bmNlVGltZSgwKSkuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5wdWxsSXRlbXNUb0xlZnQoKTtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRJdGVtcygpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmRlYm91bmNlUmVuZGVyU3ViamVjdC5waXBlKGRlYm91bmNlVGltZSgwKSkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVuZGVyKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzSW5pdGlhbGl6ZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNJbml0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGluaXRcclxuICAgICAqIEBwYXJhbSBpdGVtXHJcbiAgICAgKi9cclxuICAgIHJlZ2lzdGVySXRlbShpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuXHJcbiAgICAgICAgdGhpcy5pdGVtcy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXQoZ3JpZHN0ZXJDb21wb25lbnQ6IEdyaWRzdGVyQ29tcG9uZW50KSB7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQgPSBncmlkc3RlckNvbXBvbmVudDtcclxuXHJcbiAgICAgICAgdGhpcy5kcmFnZ2FibGVPcHRpb25zID0gZ3JpZHN0ZXJDb21wb25lbnQuZHJhZ2dhYmxlT3B0aW9ucztcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkc3Rlck9wdGlvbnMgPSBncmlkc3RlckNvbXBvbmVudC5ncmlkc3Rlck9wdGlvbnM7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnQoKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVNYXhJdGVtU2l6ZSgpO1xyXG5cclxuICAgICAgICAvLyBVc2VkIHRvIGhpZ2hsaWdodCBhIHBvc2l0aW9uIGFuIGVsZW1lbnQgd2lsbCBsYW5kIG9uIHVwb24gZHJvcFxyXG4gICAgICAgIGlmICh0aGlzLiRwb3NpdGlvbkhpZ2hsaWdodCkge1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVBvc2l0aW9uSGlnaGxpZ2h0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmluaXRHcmlkTGlzdCgpO1xyXG5cclxuICAgICAgICB0aGlzLmlzSW5pdCA9IHRydWU7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNvcHlJdGVtcygpO1xyXG4gICAgICAgICAgICB0aGlzLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LnJlZmxvd0dyaWRzdGVyKHRydWUpO1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LnNldFJlYWR5KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdEdyaWRMaXN0KCkge1xyXG4gICAgICAgIC8vIENyZWF0ZSBpbnN0YW5jZSBvZiBHcmlkTGlzdCAoZGVjb3VwbGVkIGxpYiBmb3IgaGFuZGxpbmcgdGhlIGdyaWRcclxuICAgICAgICAvLyBwb3NpdGlvbmluZyBhbmQgc29ydGluZyBwb3N0LWRyYWcgYW5kIGRyb3BwaW5nKVxyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QgPSBuZXcgR3JpZExpc3QodGhpcy5pdGVtcywgdGhpcy5vcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICByZW5kZXIoKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVNYXhJdGVtU2l6ZSgpO1xyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QuZ2VuZXJhdGVHcmlkKCk7XHJcbiAgICAgICAgdGhpcy5hcHBseVNpemVUb0l0ZW1zKCk7XHJcbiAgICAgICAgdGhpcy5hcHBseVBvc2l0aW9uVG9JdGVtcygpO1xyXG4gICAgICAgIHRoaXMucmVmcmVzaExpbmVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVmbG93KCkge1xyXG4gICAgICAgIHRoaXMuY2FsY3VsYXRlQ2VsbFNpemUoKTtcclxuICAgICAgICB0aGlzLnJlbmRlcigpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpeEl0ZW1zUG9zaXRpb25zKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmVzcG9uc2l2ZVNpemVzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnModGhpcy5vcHRpb25zKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmdyaWRMaXN0LmZpeEl0ZW1zUG9zaXRpb25zKHRoaXMuZ3JpZHN0ZXJPcHRpb25zLmJhc2ljT3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZHN0ZXJPcHRpb25zLnJlc3BvbnNpdmVPcHRpb25zLmZvckVhY2goKG9wdGlvbnM6IElHcmlkc3Rlck9wdGlvbnMpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QuZml4SXRlbXNQb3NpdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRJdGVtcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUl0ZW0oaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pO1xyXG5cclxuICAgICAgICBpZiAoaWR4ID49IDApIHtcclxuICAgICAgICAgICAgdGhpcy5pdGVtcy5zcGxpY2UodGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pLCAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZExpc3QuZGVsZXRlSXRlbVBvc2l0aW9uRnJvbUdyaWQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUNhY2hlKGl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uUmVzaXplU3RhcnQoaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IGl0ZW0uJGVsZW1lbnQ7XHJcblxyXG4gICAgICAgIHRoaXMuY29weUl0ZW1zKCk7XHJcblxyXG4gICAgICAgIHRoaXMuX21heEdyaWRDb2xzID0gdGhpcy5ncmlkTGlzdC5ncmlkLmxlbmd0aDtcclxuXHJcbiAgICAgICAgdGhpcy5oaWdobGlnaHRQb3NpdGlvbkZvckl0ZW0oaXRlbSk7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQuaXNSZXNpemluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaExpbmVzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25SZXNpemVEcmFnKGl0ZW06IEdyaWRMaXN0SXRlbSkge1xyXG4gICAgICAgIGNvbnN0IG5ld1NpemUgPSB0aGlzLnNuYXBJdGVtU2l6ZVRvR3JpZChpdGVtKTtcclxuICAgICAgICBjb25zdCBzaXplQ2hhbmdlZCA9IHRoaXMuZHJhZ1NpemVDaGFuZ2VkKG5ld1NpemUpO1xyXG4gICAgICAgIGNvbnN0IG5ld1Bvc2l0aW9uID0gdGhpcy5zbmFwSXRlbVBvc2l0aW9uVG9HcmlkKGl0ZW0pO1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQ2hhbmdlZCA9IHRoaXMuZHJhZ1Bvc2l0aW9uQ2hhbmdlZChuZXdQb3NpdGlvbik7XHJcblxyXG4gICAgICAgIGlmIChzaXplQ2hhbmdlZCB8fCBwb3NpdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgLy8gUmVnZW5lcmF0ZSB0aGUgZ3JpZCB3aXRoIHRoZSBwb3NpdGlvbnMgZnJvbSB3aGVuIHRoZSBkcmFnIHN0YXJ0ZWRcclxuICAgICAgICAgICAgdGhpcy5yZXN0b3JlQ2FjaGVkSXRlbXMoKTtcclxuICAgICAgICAgICAgdGhpcy5ncmlkTGlzdC5nZW5lcmF0ZUdyaWQoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXNEcmFnUG9zaXRpb24gPSBuZXdQb3NpdGlvbjtcclxuICAgICAgICAgICAgdGhpcy5wcmV2aW91c0RyYWdTaXplID0gbmV3U2l6ZTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZ3JpZExpc3QubW92ZUFuZFJlc2l6ZShpdGVtLCBuZXdQb3NpdGlvbiwge3c6IG5ld1NpemVbMF0sIGg6IG5ld1NpemVbMV19KTtcclxuXHJcbiAgICAgICAgICAgIC8vIFZpc3VhbGx5IHVwZGF0ZSBpdGVtIHBvc2l0aW9ucyBhbmQgaGlnaGxpZ2h0IHNoYXBlXHJcbiAgICAgICAgICAgIHRoaXMuYXBwbHlQb3NpdGlvblRvSXRlbXModHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuaGlnaGxpZ2h0UG9zaXRpb25Gb3JJdGVtKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBvblJlc2l6ZVN0b3AoaXRlbTogR3JpZExpc3RJdGVtKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50RWxlbWVudCA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlZEl0ZW1zKCk7XHJcbiAgICAgICAgdGhpcy5wcmV2aW91c0RyYWdTaXplID0gbnVsbDtcclxuXHJcbiAgICAgICAgdGhpcy5yZW1vdmVQb3NpdGlvbkhpZ2hsaWdodCgpO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LmlzUmVzaXppbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgdGhpcy5ncmlkTGlzdC5wdWxsSXRlbXNUb0xlZnQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5kZWJvdW5jZVJlbmRlclN1YmplY3QubmV4dCgpO1xyXG5cclxuICAgICAgICB0aGlzLmZpeEl0ZW1zUG9zaXRpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgb25TdGFydChpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRFbGVtZW50ID0gaXRlbS4kZWxlbWVudDtcclxuICAgICAgICAvLyBpdGVtQ3RybC5pc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICAvLyBDcmVhdGUgYSBkZWVwIGNvcHkgb2YgdGhlIGl0ZW1zOyB3ZSB1c2UgdGhlbSB0byByZXZlcnQgdGhlIGl0ZW1cclxuICAgICAgICAvLyBwb3NpdGlvbnMgYWZ0ZXIgZWFjaCBkcmFnIGNoYW5nZSwgbWFraW5nIGFuIGVudGlyZSBkcmFnIG9wZXJhdGlvbiBsZXNzXHJcbiAgICAgICAgLy8gZGlzdHJ1Y3RhYmxlXHJcbiAgICAgICAgdGhpcy5jb3B5SXRlbXMoKTtcclxuXHJcbiAgICAgICAgLy8gU2luY2UgZHJhZ2dpbmcgYWN0dWFsbHkgYWx0ZXJzIHRoZSBncmlkLCB3ZSBuZWVkIHRvIGVzdGFibGlzaCB0aGUgbnVtYmVyXHJcbiAgICAgICAgLy8gb2YgY29scyAoKzEgZXh0cmEpIGJlZm9yZSB0aGUgZHJhZyBzdGFydHNcclxuXHJcbiAgICAgICAgdGhpcy5fbWF4R3JpZENvbHMgPSB0aGlzLmdyaWRMaXN0LmdyaWQubGVuZ3RoO1xyXG5cclxuICAgICAgICB0aGlzLmdyaWRzdGVyQ29tcG9uZW50LmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuZ3JpZHN0ZXJDb21wb25lbnQudXBkYXRlR3JpZHN0ZXJFbGVtZW50RGF0YSgpO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hMaW5lcygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uRHJhZyhpdGVtOiBHcmlkTGlzdEl0ZW0pIHtcclxuICAgICAgICBjb25zdCBuZXdQb3NpdGlvbiA9IHRoa