@almaobservatory/ngx-datatable
Version:
ngx-datatable is an Angular table grid component for presenting large and complex data.
376 lines • 38.6 kB
JavaScript
import { Component, Output, EventEmitter, Input, HostBinding, ChangeDetectionStrategy } from '@angular/core';
import { columnsByPin, columnGroupWidths, columnsByPinArr } from '../../utils/column';
import { SortType } from '../../types/sort.type';
import { translateXY } from '../../utils/translate';
import * as i0 from "@angular/core";
import * as i1 from "./header-cell.component";
import * as i2 from "../../directives/orderable.directive";
import * as i3 from "@angular/common";
import * as i4 from "../../directives/resizeable.directive";
import * as i5 from "../../directives/long-press.directive";
import * as i6 from "../../directives/draggable.directive";
export class DataTableHeaderComponent {
constructor(cd) {
this.cd = cd;
this.sort = new EventEmitter();
this.reorder = new EventEmitter();
this.resize = new EventEmitter();
this.select = new EventEmitter();
this.columnContextmenu = new EventEmitter(false);
this._columnGroupWidths = {
total: 100
};
this._styleByGroup = {
left: {},
center: {},
right: {}
};
this.destroyed = false;
}
set innerWidth(val) {
this._innerWidth = val;
setTimeout(() => {
if (this._columns) {
const colByPin = columnsByPin(this._columns);
this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
this.setStylesByGroup();
}
});
}
get innerWidth() {
return this._innerWidth;
}
set headerHeight(val) {
if (val !== 'auto') {
this._headerHeight = `${val}px`;
}
else {
this._headerHeight = val;
}
}
get headerHeight() {
return this._headerHeight;
}
set columns(val) {
this._columns = val;
const colsByPin = columnsByPin(val);
this._columnsByPin = columnsByPinArr(val);
setTimeout(() => {
this._columnGroupWidths = columnGroupWidths(colsByPin, val);
this.setStylesByGroup();
});
}
get columns() {
return this._columns;
}
set offsetX(val) {
this._offsetX = val;
this.setStylesByGroup();
}
get offsetX() {
return this._offsetX;
}
ngOnDestroy() {
this.destroyed = true;
}
onLongPressStart({ event, model }) {
model.dragging = true;
this.dragEventTarget = event;
}
onLongPressEnd({ event, model }) {
this.dragEventTarget = event;
// delay resetting so sort can be
// prevented if we were dragging
setTimeout(() => {
// datatable component creates copies from columns on reorder
// set dragging to false on new objects
const column = this._columns.find(c => c.$$id === model.$$id);
if (column) {
column.dragging = false;
}
}, 5);
}
get headerWidth() {
if (this.scrollbarH) {
return this.innerWidth + 'px';
}
return '100%';
}
trackByGroups(index, colGroup) {
return colGroup.type;
}
columnTrackingFn(index, column) {
return column.$$id;
}
onColumnResized(width, column) {
if (width <= column.minWidth) {
width = column.minWidth;
}
else if (width >= column.maxWidth) {
width = column.maxWidth;
}
this.resize.emit({
column,
prevValue: column.width,
newValue: width
});
}
onColumnReordered({ prevIndex, newIndex, model }) {
const column = this.getColumn(newIndex);
column.isTarget = false;
column.targetMarkerContext = undefined;
this.reorder.emit({
column: model,
prevValue: prevIndex,
newValue: newIndex
});
}
onTargetChanged({ prevIndex, newIndex, initialIndex }) {
if (prevIndex || prevIndex === 0) {
const oldColumn = this.getColumn(prevIndex);
oldColumn.isTarget = false;
oldColumn.targetMarkerContext = undefined;
}
if (newIndex || newIndex === 0) {
const newColumn = this.getColumn(newIndex);
newColumn.isTarget = true;
if (initialIndex !== newIndex) {
newColumn.targetMarkerContext = {
class: 'targetMarker '.concat(initialIndex > newIndex ? 'dragFromRight' : 'dragFromLeft')
};
}
}
}
getColumn(index) {
const leftColumnCount = this._columnsByPin[0].columns.length;
if (index < leftColumnCount) {
return this._columnsByPin[0].columns[index];
}
const centerColumnCount = this._columnsByPin[1].columns.length;
if (index < leftColumnCount + centerColumnCount) {
return this._columnsByPin[1].columns[index - leftColumnCount];
}
return this._columnsByPin[2].columns[index - leftColumnCount - centerColumnCount];
}
onSort({ column, prevValue, newValue }) {
// if we are dragging don't sort!
if (column.dragging) {
return;
}
const sorts = this.calcNewSorts(column, prevValue, newValue);
this.sort.emit({
sorts,
column,
prevValue,
newValue
});
}
calcNewSorts(column, prevValue, newValue) {
let idx = 0;
if (!this.sorts) {
this.sorts = [];
}
const sorts = this.sorts.map((s, i) => {
s = { ...s };
if (s.prop === column.prop) {
idx = i;
}
return s;
});
if (newValue === undefined) {
sorts.splice(idx, 1);
}
else if (prevValue) {
sorts[idx].dir = newValue;
}
else {
if (this.sortType === SortType.single) {
sorts.splice(0, this.sorts.length);
}
sorts.push({ dir: newValue, prop: column.prop });
}
return sorts;
}
setStylesByGroup() {
this._styleByGroup.left = this.calcStylesByGroup('left');
this._styleByGroup.center = this.calcStylesByGroup('center');
this._styleByGroup.right = this.calcStylesByGroup('right');
if (!this.destroyed) {
this.cd.detectChanges();
}
}
calcStylesByGroup(group) {
const widths = this._columnGroupWidths;
const offsetX = this.offsetX;
const styles = {
width: `${widths[group]}px`
};
if (group === 'center') {
translateXY(styles, offsetX * -1, 0);
}
else if (group === 'right') {
const totalDiff = widths.total - this.innerWidth;
const offset = totalDiff * -1;
translateXY(styles, offset, 0);
}
return styles;
}
}
DataTableHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
DataTableHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableHeaderComponent, selector: "datatable-header", inputs: { sortAscendingIcon: "sortAscendingIcon", sortDescendingIcon: "sortDescendingIcon", sortUnsetIcon: "sortUnsetIcon", scrollbarH: "scrollbarH", dealsWithGroup: "dealsWithGroup", targetMarkerTemplate: "targetMarkerTemplate", innerWidth: "innerWidth", sorts: "sorts", sortType: "sortType", allRowsSelected: "allRowsSelected", selectionType: "selectionType", reorderable: "reorderable", headerHeight: "headerHeight", columns: "columns", offsetX: "offsetX" }, outputs: { sort: "sort", reorder: "reorder", resize: "resize", select: "select", columnContextmenu: "columnContextmenu" }, host: { properties: { "style.height": "this.headerHeight", "style.width": "this.headerWidth" }, classAttribute: "datatable-header" }, ngImport: i0, template: `
<div
role="row"
orderable
(reorder)="onColumnReordered($event)"
(targetChanged)="onTargetChanged($event)"
[style.width.px]="_columnGroupWidths.total"
class="datatable-header-inner"
>
<div
*ngFor="let colGroup of _columnsByPin; trackBy: trackByGroups"
[class]="'datatable-row-' + colGroup.type"
[ngStyle]="_styleByGroup[colGroup.type]"
>
<datatable-header-cell
role="columnheader"
*ngFor="let column of colGroup.columns; trackBy: columnTrackingFn"
resizeable
[resizeEnabled]="column.resizeable"
(resize)="onColumnResized($event, column)"
long-press
[pressModel]="column"
[pressEnabled]="reorderable && column.draggable"
(longPressStart)="onLongPressStart($event)"
(longPressEnd)="onLongPressEnd($event)"
draggable
[dragX]="reorderable && column.draggable && column.dragging"
[dragY]="false"
[dragModel]="column"
[dragEventTarget]="dragEventTarget"
[headerHeight]="headerHeight"
[isTarget]="column.isTarget"
[targetMarkerTemplate]="targetMarkerTemplate"
[targetMarkerContext]="column.targetMarkerContext"
[column]="column"
[sortType]="sortType"
[sorts]="sorts"
[selectionType]="selectionType"
[sortAscendingIcon]="sortAscendingIcon"
[sortDescendingIcon]="sortDescendingIcon"
[sortUnsetIcon]="sortUnsetIcon"
[allRowsSelected]="allRowsSelected"
(sort)="onSort($event)"
(select)="select.emit($event)"
(columnContextmenu)="columnContextmenu.emit($event)"
>
</datatable-header-cell>
</div>
</div>
`, isInline: true, components: [{ type: i1.DataTableHeaderCellComponent, selector: "datatable-header-cell", inputs: ["sortType", "sortAscendingIcon", "sortDescendingIcon", "sortUnsetIcon", "isTarget", "targetMarkerTemplate", "targetMarkerContext", "allRowsSelected", "selectionType", "column", "headerHeight", "sorts"], outputs: ["sort", "select", "columnContextmenu"] }], directives: [{ type: i2.OrderableDirective, selector: "[orderable]", outputs: ["reorder", "targetChanged"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i4.ResizeableDirective, selector: "[resizeable]", inputs: ["resizeEnabled", "minWidth", "maxWidth"], outputs: ["resize"] }, { type: i5.LongPressDirective, selector: "[long-press]", inputs: ["pressEnabled", "pressModel", "duration"], outputs: ["longPressStart", "longPressing", "longPressEnd"] }, { type: i6.DraggableDirective, selector: "[draggable]", inputs: ["dragEventTarget", "dragModel", "dragX", "dragY"], outputs: ["dragStart", "dragging", "dragEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderComponent, decorators: [{
type: Component,
args: [{
selector: 'datatable-header',
template: `
<div
role="row"
orderable
(reorder)="onColumnReordered($event)"
(targetChanged)="onTargetChanged($event)"
[style.width.px]="_columnGroupWidths.total"
class="datatable-header-inner"
>
<div
*ngFor="let colGroup of _columnsByPin; trackBy: trackByGroups"
[class]="'datatable-row-' + colGroup.type"
[ngStyle]="_styleByGroup[colGroup.type]"
>
<datatable-header-cell
role="columnheader"
*ngFor="let column of colGroup.columns; trackBy: columnTrackingFn"
resizeable
[resizeEnabled]="column.resizeable"
(resize)="onColumnResized($event, column)"
long-press
[pressModel]="column"
[pressEnabled]="reorderable && column.draggable"
(longPressStart)="onLongPressStart($event)"
(longPressEnd)="onLongPressEnd($event)"
draggable
[dragX]="reorderable && column.draggable && column.dragging"
[dragY]="false"
[dragModel]="column"
[dragEventTarget]="dragEventTarget"
[headerHeight]="headerHeight"
[isTarget]="column.isTarget"
[targetMarkerTemplate]="targetMarkerTemplate"
[targetMarkerContext]="column.targetMarkerContext"
[column]="column"
[sortType]="sortType"
[sorts]="sorts"
[selectionType]="selectionType"
[sortAscendingIcon]="sortAscendingIcon"
[sortDescendingIcon]="sortDescendingIcon"
[sortUnsetIcon]="sortUnsetIcon"
[allRowsSelected]="allRowsSelected"
(sort)="onSort($event)"
(select)="select.emit($event)"
(columnContextmenu)="columnContextmenu.emit($event)"
>
</datatable-header-cell>
</div>
</div>
`,
host: {
class: 'datatable-header'
},
changeDetection: ChangeDetectionStrategy.OnPush
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { sortAscendingIcon: [{
type: Input
}], sortDescendingIcon: [{
type: Input
}], sortUnsetIcon: [{
type: Input
}], scrollbarH: [{
type: Input
}], dealsWithGroup: [{
type: Input
}], targetMarkerTemplate: [{
type: Input
}], innerWidth: [{
type: Input
}], sorts: [{
type: Input
}], sortType: [{
type: Input
}], allRowsSelected: [{
type: Input
}], selectionType: [{
type: Input
}], reorderable: [{
type: Input
}], headerHeight: [{
type: HostBinding,
args: ['style.height']
}, {
type: Input
}], columns: [{
type: Input
}], offsetX: [{
type: Input
}], sort: [{
type: Output
}], reorder: [{
type: Output
}], resize: [{
type: Output
}], select: [{
type: Output
}], columnContextmenu: [{
type: Output
}], headerWidth: [{
type: HostBinding,
args: ['style.width']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N3aW1sYW5lL25neC1kYXRhdGFibGUvc3JjL2xpYi9jb21wb25lbnRzL2hlYWRlci9oZWFkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFlBQVksRUFDWixLQUFLLEVBQ0wsV0FBVyxFQUVYLHVCQUF1QixFQUV4QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUdqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7Ozs7O0FBMkRwRCxNQUFNLE9BQU8sd0JBQXdCO0lBNkZuQyxZQUFvQixFQUFxQjtRQUFyQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQXRCL0IsU0FBSSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzdDLFlBQU8sR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNoRCxXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDL0MsV0FBTSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQy9DLHNCQUFpQixHQUFHLElBQUksWUFBWSxDQUFxQyxLQUFLLENBQUMsQ0FBQztRQUcxRix1QkFBa0IsR0FBUTtZQUN4QixLQUFLLEVBQUUsR0FBRztTQUNYLENBQUM7UUFLRixrQkFBYSxHQUEyQjtZQUN0QyxJQUFJLEVBQUUsRUFBRTtZQUNSLE1BQU0sRUFBRSxFQUFFO1lBQ1YsS0FBSyxFQUFFLEVBQUU7U0FDVixDQUFDO1FBRU0sY0FBUyxHQUFHLEtBQUssQ0FBQztJQUVrQixDQUFDO0lBbkY3QyxJQUFhLFVB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TTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNO2dCQTZDSCxXQUFXO3NCQURkLFdBQVc7dUJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgSG9zdEJpbmRpbmcsXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgT25EZXN0cm95XHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGNvbHVtbnNCeVBpbiwgY29sdW1uR3JvdXBXaWR0aHMsIGNvbHVtbnNCeVBpbkFyciB9IGZyb20gJy4uLy4uL3V0aWxzL2NvbHVtbic7XHJcbmltcG9ydCB7IFNvcnRUeXBlIH0gZnJvbSAnLi4vLi4vdHlwZXMvc29ydC50eXBlJztcclxuaW1wb3J0IHsgU2VsZWN0aW9uVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzL3NlbGVjdGlvbi50eXBlJztcclxuaW1wb3J0IHsgRGF0YVRhYmxlQ29sdW1uRGlyZWN0aXZlIH0gZnJvbSAnLi4vY29sdW1ucy9jb2x1bW4uZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgdHJhbnNsYXRlWFkgfSBmcm9tICcuLi8uLi91dGlscy90cmFuc2xhdGUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkYXRhdGFibGUtaGVhZGVyJyxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdlxyXG4gICAgICByb2xlPVwicm93XCJcclxuICAgICAgb3JkZXJhYmxlXHJcbiAgICAgIChyZW9yZGVyKT1cIm9uQ29sdW1uUmVvcmRlcmVkKCRldmVudClcIlxyXG4gICAgICAodGFyZ2V0Q2hhbmdlZCk9XCJvblRhcmdldENoYW5nZWQoJGV2ZW50KVwiXHJcbiAgICAgIFtzdHlsZS53aWR0aC5weF09XCJfY29sdW1uR3JvdXBXaWR0aHMudG90YWxcIlxyXG4gICAgICBjbGFzcz1cImRhdGF0YWJsZS1oZWFkZXItaW5uZXJcIlxyXG4gICAgPlxyXG4gICAgICA8ZGl2XHJcbiAgICAgICAgKm5nRm9yPVwibGV0IGNvbEdyb3VwIG9mIF9jb2x1bW5zQnlQaW47IHRyYWNrQnk6IHRyYWNrQnlHcm91cHNcIlxyXG4gICAgICAgIFtjbGFzc109XCInZGF0YXRhYmxlLXJvdy0nICsgY29sR3JvdXAudHlwZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwiX3N0eWxlQnlHcm91cFtjb2xHcm91cC50eXBlXVwiXHJcbiAgICAgID5cclxuICAgICAgICA8ZGF0YXRhYmxlLWhlYWRlci1jZWxsXHJcbiAgICAgICAgICByb2xlPVwiY29sdW1uaGVhZGVyXCJcclxuICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sR3JvdXAuY29sdW1uczsgdHJhY2tCeTogY29sdW1uVHJhY2tpbmdGblwiXHJcbiAgICAgICAgICByZXNpemVhYmxlXHJcbiAgICAgICAgICBbcmVzaXplRW5hYmxlZF09XCJjb2x1bW4ucmVzaXplYWJsZVwiXHJcbiAgICAgICAgICAocmVzaXplKT1cIm9uQ29sdW1uUmVzaXplZCgkZXZlbnQsIGNvbHVtbilcIlxyXG4gICAgICAgICAgbG9uZy1wcmVzc1xyXG4gICAgICAgICAgW3ByZXNzTW9kZWxdPVwiY29sdW1uXCJcclxuICAgICAgICAgIFtwcmVzc0VuYWJsZWRdPVwicmVvcmRlcmFibGUgJiYgY29sdW1uLmRyYWdnYWJsZVwiXHJcbiAgICAgICAgICAobG9uZ1ByZXNzU3RhcnQpPVwib25Mb25nUHJlc3NTdGFydCgkZXZlbnQpXCJcclxuICAgICAgICAgIChsb25nUHJlc3NFbmQpPVwib25Mb25nUHJlc3NFbmQoJGV2ZW50KVwiXHJcbiAgICAgICAgICBkcmFnZ2FibGVcclxuICAgICAgICAgIFtkcmFnWF09XCJyZW9yZGVyYWJsZSAmJiBjb2x1bW4uZHJhZ2dhYmxlICYmIGNvbHVtbi5kcmFnZ2luZ1wiXHJcbiAgICAgICAgICBbZHJhZ1ldPVwiZmFsc2VcIlxyXG4gICAgICAgICAgW2RyYWdNb2RlbF09XCJjb2x1bW5cIlxyXG4gICAgICAgICAgW2RyYWdFdmVudFRhcmdldF09XCJkcmFnRXZlbnRUYXJnZXRcIlxyXG4gICAgICAgICAgW2hlYWRlckhlaWdodF09XCJoZWFkZXJIZWlnaHRcIlxyXG4gICAgICAgICAgW2lzVGFyZ2V0XT1cImNvbHVtbi5pc1RhcmdldFwiXHJcbiAgICAgICAgICBbdGFyZ2V0TWFya2VyVGVtcGxhdGVdPVwidGFyZ2V0TWFya2VyVGVtcGxhdGVcIlxyXG4gICAgICAgICAgW3RhcmdldE1hcmtlckNvbnRleHRdPVwiY29sdW1uLnRhcmdldE1hcmtlckNvbnRleHRcIlxyXG4gICAgICAgICAgW2NvbHVtbl09XCJjb2x1bW5cIlxyXG4gICAgICAgICAgW3NvcnRUeXBlXT1cInNvcnRUeXBlXCJcclxuICAgICAgICAgIFtzb3J0c109XCJzb3J0c1wiXHJcbiAgICAgICAgICBbc2VsZWN0aW9uVHlwZV09XCJzZWxlY3Rpb25UeXBlXCJcclxuICAgICAgICAgIFtzb3J0QXNjZW5kaW5nSWNvbl09XCJzb3J0QXNjZW5kaW5nSWNvblwiXHJcbiAgICAgICAgICBbc29ydERlc2NlbmRpbmdJY29uXT1cInNvcnREZXNjZW5kaW5nSWNvblwiXHJcbiAgICAgICAgICBbc29ydFVuc2V0SWNvbl09XCJzb3J0VW5zZXRJY29uXCJcclxuICAgICAgICAgIFthbGxSb3dzU2VsZWN0ZWRdPVwiYWxsUm93c1NlbGVjdGVkXCJcclxuICAgICAgICAgIChzb3J0KT1cIm9uU29ydCgkZXZlbnQpXCJcclxuICAgICAgICAgIChzZWxlY3QpPVwic2VsZWN0LmVtaXQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAoY29sdW1uQ29udGV4dG1lbnUpPVwiY29sdW1uQ29udGV4dG1lbnUuZW1pdCgkZXZlbnQpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgPC9kYXRhdGFibGUtaGVhZGVyLWNlbGw+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgYCxcclxuICBob3N0OiB7XHJcbiAgICBjbGFzczogJ2RhdGF0YWJsZS1oZWFkZXInXHJcbiAgfSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGF0YVRhYmxlSGVhZGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuICBASW5wdXQoKSBzb3J0QXNjZW5kaW5nSWNvbjogYW55O1xyXG4gIEBJbnB1dCgpIHNvcnREZXNjZW5kaW5nSWNvbjogYW55O1xyXG4gIEBJbnB1dCgpIHNvcnRVbnNldEljb246IGFueTtcclxuICBASW5wdXQoKSBzY3JvbGxiYXJIOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGRlYWxzV2l0aEdyb3VwOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIHRhcmdldE1hcmtlclRlbXBsYXRlOiBhbnk7XHJcblxyXG4gIHRhcmdldE1hcmtlckNvbnRleHQ6IGFueTtcclxuXHJcbiAgQElucHV0KCkgc2V0IGlubmVyV2lkdGgodmFsOiBudW1iZXIpIHtcclxuICAgIHRoaXMuX2lubmVyV2lkdGggPSB2YWw7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgaWYgKHRoaXMuX2NvbHVtbnMpIHtcclxuICAgICAgICBjb25zdCBjb2xCeVBpbiA9IGNvbHVtbnNCeVBpbih0aGlzLl9jb2x1bW5zKTtcclxuICAgICAgICB0aGlzLl9jb2x1bW5Hcm91cFdpZHRocyA9IGNvbHVtbkdyb3VwV2lkdGhzKGNvbEJ5UGluLCB0aGlzLl9jb2x1bW5zKTtcclxuICAgICAgICB0aGlzLnNldFN0eWxlc0J5R3JvdXAoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBnZXQgaW5uZXJXaWR0aCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lubmVyV2lkdGg7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBzb3J0czogYW55W107XHJcbiAgQElucHV0KCkgc29ydFR5cGU6IFNvcnRUeXBlO1xyXG4gIEBJbnB1dCgpIGFsbFJvd3NTZWxlY3RlZDogYm9vbGVhbjtcclxuICBASW5wdXQoKSBzZWxlY3Rpb25UeXBlOiBTZWxlY3Rpb25UeXBlO1xyXG4gIEBJbnB1dCgpIHJlb3JkZXJhYmxlOiBib29sZWFuO1xyXG5cclxuICBkcmFnRXZlbnRUYXJnZXQ6IGFueTtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS5oZWlnaHQnKVxyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGhlYWRlckhlaWdodCh2YWw6IGFueSkge1xyXG4gICAgaWYgKHZhbCAhPT0gJ2F1dG8nKSB7XHJcbiAgICAgIHRoaXMuX2hlYWRlckhlaWdodCA9IGAke3ZhbH1weGA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9oZWFkZXJIZWlnaHQgPSB2YWw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgaGVhZGVySGVpZ2h0KCk6IGFueSB7XHJcbiAgICByZXR1cm4gdGhpcy5faGVhZGVySGVpZ2h0O1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCkgc2V0IGNvbHVtbnModmFsOiBhbnlbXSkge1xyXG4gICAgdGhpcy5fY29sdW1ucyA9IHZhbDtcclxuXHJcbiAgICBjb25zdCBjb2xzQnlQaW4gPSBjb2x1bW5zQnlQaW4odmFsKTtcclxuICAgIHRoaXMuX2NvbHVtbnNCeVBpbiA9IGNvbHVtbnNCeVBpbkFycih2YWwpO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuX2NvbHVtbkdyb3VwV2lkdGhzID0gY29sdW1uR3JvdXBXaWR0aHMoY29sc0J5UGluLCB2YWwpO1xyXG4gICAgICB0aGlzLnNldFN0eWxlc0J5R3JvdXAoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGNvbHVtbnMoKTogYW55W10ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2NvbHVtbnM7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKVxyXG4gIHNldCBvZmZzZXRYKHZhbDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl9vZmZzZXRYID0gdmFsO1xyXG4gICAgdGhpcy5zZXRTdHlsZXNCeUdyb3VwKCk7XHJcbiAgfVxyXG4gIGdldCBvZmZzZXRYKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX29mZnNldFg7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KCkgc29ydDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgQE91dHB1dCgpIHJlb3JkZXI6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSByZXNpemU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSBzZWxlY3Q6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSBjb2x1bW5Db250ZXh0bWVudSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBldmVudDogTW91c2VFdmVudDsgY29sdW1uOiBhbnkgfT4oZmFsc2UpO1xyXG5cclxuICBfY29sdW1uc0J5UGluOiBhbnk7XHJcbiAgX2NvbHVtbkdyb3VwV2lkdGhzOiBhbnkgPSB7XHJcbiAgICB0b3RhbDogMTAwXHJcbiAgfTtcclxuICBfaW5uZXJXaWR0aDogbnVtYmVyO1xyXG4gIF9vZmZzZXRYOiBudW1iZXI7XHJcbiAgX2NvbHVtbnM6IGFueVtdO1xyXG4gIF9oZWFkZXJIZWlnaHQ6IHN0cmluZztcclxuICBfc3R5bGVCeUdyb3VwOiB7IFtwcm9wOiBzdHJpbmddOiB7fSB9ID0ge1xyXG4gICAgbGVmdDoge30sXHJcbiAgICBjZW50ZXI6IHt9LFxyXG4gICAgcmlnaHQ6IHt9XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBkZXN0cm95ZWQgPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgb25Mb25nUHJlc3NTdGFydCh7IGV2ZW50LCBtb2RlbCB9OiB7IGV2ZW50OiBhbnk7IG1vZGVsOiBhbnkgfSkge1xyXG4gICAgbW9kZWwuZHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgdGhpcy5kcmFnRXZlbnRUYXJnZXQgPSBldmVudDtcclxuICB9XHJcblxyXG4gIG9uTG9uZ1ByZXNzRW5kKHsgZXZlbnQsIG1vZGVsIH06IHsgZXZlbnQ6IGFueTsgbW9kZWw6IGFueSB9KSB7XHJcbiAgICB0aGlzLmRyYWdFdmVudFRhcmdldCA9IGV2ZW50O1xyXG5cclxuICAgIC8vIGRlbGF5IHJlc2V0dGluZyBzbyBzb3J0IGNhbiBiZVxyXG4gICAgLy8gcHJldmVudGVkIGlmIHdlIHdlcmUgZHJhZ2dpbmdcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAvLyBkYXRhdGFibGUgY29tcG9uZW50IGNyZWF0ZXMgY29waWVzIGZyb20gY29sdW1ucyBvbiByZW9yZGVyXHJcbiAgICAgIC8vIHNldCBkcmFnZ2luZyB0byBmYWxzZSBvbiBuZXcgb2JqZWN0c1xyXG4gICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLl9jb2x1bW5zLmZpbmQoYyA9PiBjLiQkaWQgPT09IG1vZGVsLiQkaWQpO1xyXG4gICAgICBpZiAoY29sdW1uKSB7XHJcbiAgICAgICAgY29sdW1uLmRyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH0sIDUpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS53aWR0aCcpXHJcbiAgZ2V0IGhlYWRlcldpZHRoKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5zY3JvbGxiYXJIKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmlubmVyV2lkdGggKyAncHgnO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAnMTAwJSc7XHJcbiAgfVxyXG5cclxuICB0cmFja0J5R3JvdXBzKGluZGV4OiBudW1iZXIsIGNvbEdyb3VwOiBhbnkpOiBhbnkge1xyXG4gICAgcmV0dXJuIGNvbEdyb3VwLnR5cGU7XHJcbiAgfVxyXG5cclxuICBjb2x1bW5UcmFja2luZ0ZuKGluZGV4OiBudW1iZXIsIGNvbHVtbjogYW55KTogYW55IHtcclxuICAgIHJldHVybiBjb2x1bW4uJCRpZDtcclxuICB9XHJcblxyXG4gIG9uQ29sdW1uUmVzaXplZCh3aWR0aDogbnVtYmVyLCBjb2x1bW46IERhdGFUYWJsZUNvbHVtbkRpcmVjdGl2ZSk6IHZvaWQge1xyXG4gICAgaWYgKHdpZHRoIDw9IGNvbHVtbi5taW5XaWR0aCkge1xyXG4gICAgICB3aWR0aCA9IGNvbHVtbi5taW5XaWR0aDtcclxuICAgIH0gZWxzZSBpZiAod2lkdGggPj0gY29sdW1uLm1heFdpZHRoKSB7XHJcbiAgICAgIHdpZHRoID0gY29sdW1uLm1heFdpZHRoO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucmVzaXplLmVtaXQoe1xyXG4gICAgICBjb2x1bW4sXHJcbiAgICAgIHByZXZWYWx1ZTogY29sdW1uLndpZHRoLFxyXG4gICAgICBuZXdWYWx1ZTogd2lkdGhcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25Db2x1bW5SZW9yZGVyZWQoeyBwcmV2SW5kZXgsIG5ld0luZGV4LCBtb2RlbCB9OiBhbnkpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uKG5ld0luZGV4KTtcclxuICAgIGNvbHVtbi5pc1RhcmdldCA9IGZhbHNlO1xyXG4gICAgY29sdW1uLnRhcmdldE1hcmtlckNvbnRleHQgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLnJlb3JkZXIuZW1pdCh7XHJcbiAgICAgIGNvbHVtbjogbW9kZWwsXHJcbiAgICAgIHByZXZWYWx1ZTogcHJldkluZGV4LFxyXG4gICAgICBuZXdWYWx1ZTogbmV3SW5kZXhcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25UYXJnZXRDaGFuZ2VkKHsgcHJldkluZGV4LCBuZXdJbmRleCwgaW5pdGlhbEluZGV4IH06IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKHByZXZJbmRleCB8fCBwcmV2SW5kZXggPT09IDApIHtcclxuICAgICAgY29uc3Qgb2xkQ29sdW1uID0gdGhpcy5nZXRDb2x1bW4ocHJldkluZGV4KTtcclxuICAgICAgb2xkQ29sdW1uLmlzVGFyZ2V0ID0gZmFsc2U7XHJcbiAgICAgIG9sZENvbHVtbi50YXJnZXRNYXJrZXJDb250ZXh0ID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgaWYgKG5ld0luZGV4IHx8IG5ld0luZGV4ID09PSAwKSB7XHJcbiAgICAgIGNvbnN0IG5ld0NvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uKG5ld0luZGV4KTtcclxuICAgICAgbmV3Q29sdW1uLmlzVGFyZ2V0ID0gdHJ1ZTtcclxuXHJcbiAgICAgIGlmIChpbml0aWFsSW5kZXggIT09IG5ld0luZGV4KSB7XHJcbiAgICAgICAgbmV3Q29sdW1uLnRhcmdldE1hcmtlckNvbnRleHQgPSB7XHJcbiAgICAgICAgICBjbGFzczogJ3RhcmdldE1hcmtlciAnLmNvbmNhdChpbml0aWFsSW5kZXggPiBuZXdJbmRleCA/ICdkcmFnRnJvbVJpZ2h0JyA6ICdkcmFnRnJvbUxlZnQnKVxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldENvbHVtbihpbmRleDogbnVtYmVyKTogYW55IHtcclxuICAgIGNvbnN0IGxlZnRDb2x1bW5Db3VudCA9IHRoaXMuX2NvbHVtbnNCeVBpblswXS5jb2x1bW5zLmxlbmd0aDtcclxuICAgIGlmIChpbmRleCA8IGxlZnRDb2x1bW5Db3VudCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY29sdW1uc0J5UGluWzBdLmNvbHVtbnNbaW5kZXhdO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNlbnRlckNvbHVtbkNvdW50ID0gdGhpcy5fY29sdW1uc0J5UGluWzFdLmNvbHVtbnMubGVuZ3RoO1xyXG4gICAgaWYgKGluZGV4IDwgbGVmdENvbHVtbkNvdW50ICsgY2VudGVyQ29sdW1uQ291bnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NvbHVtbnNCeVBpblsxXS5jb2x1bW5zW2luZGV4IC0gbGVmdENvbHVtbkNvdW50XTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5fY29sdW1uc0J5UGluWzJdLmNvbHVtbnNbaW5kZXggLSBsZWZ0Q29sdW1uQ291bnQgLSBjZW50ZXJDb2x1bW5Db3VudF07XHJcbiAgfVxyXG5cclxuICBvblNvcnQoeyBjb2x1bW4sIHByZXZWYWx1ZSwgbmV3VmFsdWUgfTogYW55KTogdm9pZCB7XHJcbiAgICAvLyBpZiB3ZSBhcmUgZHJhZ2dpbmcgZG9uJ3Qgc29ydCFcclxuICAgIGlmIChjb2x1bW4uZHJhZ2dpbmcpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHNvcnRzID0gdGhpcy5jYWxjTmV3U29ydHMoY29sdW1uLCBwcmV2VmFsdWUsIG5ld1ZhbHVlKTtcclxuICAgIHRoaXMuc29ydC5lbWl0KHtcclxuICAgICAgc29ydHMsXHJcbiAgICAgIGNvbHVtbixcclxuICAgICAgcHJldlZhbHVlLFxyXG4gICAgICBuZXdWYWx1ZVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBjYWxjTmV3U29ydHMoY29sdW1uOiBhbnksIHByZXZWYWx1ZTogbnVtYmVyLCBuZXdWYWx1ZTogbnVtYmVyKTogYW55W10ge1xyXG4gICAgbGV0IGlkeCA9IDA7XHJcblxyXG4gICAgaWYgKCF0aGlzLnNvcnRzKSB7XHJcbiAgICAgIHRoaXMuc29ydHMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBzb3J0cyA9IHRoaXMuc29ydHMubWFwKChzLCBpKSA9PiB7XHJcbiAgICAgIHMgPSB7IC4uLnMgfTtcclxuICAgICAgaWYgKHMucHJvcCA9PT0gY29sdW1uLnByb3ApIHtcclxuICAgICAgICBpZHggPSBpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBzO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgc29ydHMuc3BsaWNlKGlkeCwgMSk7XHJcbiAgICB9IGVsc2UgaWYgKHByZXZWYWx1ZSkge1xyXG4gICAgICBzb3J0c1tpZHhdLmRpciA9IG5ld1ZhbHVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMuc29ydFR5cGUgPT09IFNvcnRUeXBlLnNpbmdsZSkge1xyXG4gICAgICAgIHNvcnRzLnNwbGljZSgwLCB0aGlzLnNvcnRzLmxlbmd0aCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNvcnRzLnB1c2goeyBkaXI6IG5ld1ZhbHVlLCBwcm9wOiBjb2x1bW4ucHJvcCB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc29ydHM7XHJcbiAgfVxyXG5cclxuICBzZXRTdHlsZXNCeUdyb3VwKCkge1xyXG4gICAgdGhpcy5fc3R5bGVCeUdyb3VwLmxlZnQgPSB0aGlzLmNhbGNTdHlsZXNCeUdyb3VwKCdsZWZ0Jyk7XHJcbiAgICB0aGlzLl9zdHlsZUJ5R3JvdXAuY2VudGVyID0gdGhpcy5jYWxjU3R5bGVzQnlHcm91cCgnY2VudGVyJyk7XHJcbiAgICB0aGlzLl9zdHlsZUJ5R3JvdXAucmlnaHQgPSB0aGlzLmNhbGNTdHlsZXNCeUdyb3VwKCdyaWdodCcpO1xyXG4gICAgaWYgKCF0aGlzLmRlc3Ryb3llZCkge1xyXG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNhbGNTdHlsZXNCeUdyb3VwKGdyb3VwOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgY29uc3Qgd2lkdGhzID0gdGhpcy5fY29sdW1uR3JvdXBXaWR0aHM7XHJcbiAgICBjb25zdCBvZmZzZXRYID0gdGhpcy5vZmZzZXRYO1xyXG5cclxuICAgIGNvbnN0IHN0eWxlcyA9IHtcclxuICAgICAgd2lkdGg6IGAke3dpZHRoc1tncm91cF19cHhgXHJcbiAgICB9O1xyXG5cclxuICAgIGlmIChncm91cCA9PT0gJ2NlbnRlcicpIHtcclxuICAgICAgdHJhbnNsYXRlWFkoc3R5bGVzLCBvZmZzZXRYICogLTEsIDApO1xyXG4gICAgfSBlbHNlIGlmIChncm91cCA9PT0gJ3JpZ2h0Jykge1xyXG4gICAgICBjb25zdCB0b3RhbERpZmYgPSB3aWR0aHMudG90YWwgLSB0aGlzLmlubmVyV2lkdGg7XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IHRvdGFsRGlmZiAqIC0xO1xyXG4gICAgICB0cmFuc2xhdGVYWShzdHlsZXMsIG9mZnNldCwgMCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHN0eWxlcztcclxuICB9XHJcbn1cclxuIl19