UNPKG

material-dynamic-table

Version:

Dynamic table component for angular built on top of angular material table. It offers sorting, pagination, filtering per column and the ability to specify content types and components used for displaying them.

125 lines 27.3 kB
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, Optional, ViewEncapsulation, Inject, ElementRef } from '@angular/core'; import { MdtMultiSort } from './multi-sort.directive'; import { matSortAnimations, MatSortHeader, MatSortHeaderIntl } from '@angular/material/sort'; import { FocusMonitor } from '@angular/cdk/a11y'; import * as i0 from "@angular/core"; import * as i1 from "@angular/material/sort"; import * as i2 from "./multi-sort.directive"; import * as i3 from "@angular/cdk/a11y"; import * as i4 from "@angular/common"; /** * Applies sorting behavior (click to change sort) and styles to an element, including an * arrow to display the current sort direction. * * Must be provided with an id and contained within a parent MatSort directive. * * If used on header cells in a CdkTable, it will automatically default its id from its containing * column definition. */ export class MdtMultiSortHeader extends MatSortHeader { constructor(_intl, changeDetectorRef, _multiSort, _columnDef, _focusMonitor, _elementRef) { // Note that we use a string token for the `_columnDef`, because the value is provided both by // `material/table` and `cdk/table` and we can't have the CDK depending on Material, // and we want to avoid having the sort header depending on the CDK table because // of this single reference. super(_intl, changeDetectorRef, _multiSort, _columnDef, _focusMonitor, _elementRef); this._intl = _intl; this._multiSort = _multiSort; this._columnDef = _columnDef; /** Overrides the sort start value of the containing MatSort for this MatSortable. */ this.start = 'asc'; this._sortHeader = _multiSort; } _handleClick() { //this._sort.direction = this.getSortDirection(); super._handleClick(); } /** Whether this MatSortHeader is currently sorted in either ascending or descending order. */ _isSorted() { if (!this._sortHeader.sortedBy) { return false; } let sort = this._sortHeader.sortedBy.find(s => s.id === this.id); return !!sort; } /** * Updates the direction the arrow should be pointing. If it is not sorted, the arrow should be * facing the start direction. Otherwise if it is sorted, the arrow should point in the currently * active sorted direction. The reason this is updated through a function is because the direction * should only be changed at specific times - when deactivated but the hint is displayed and when * the sort is active and the direction changes. Otherwise the arrow's direction should linger * in cases such as the sort becoming deactivated but we want to animate the arrow away while * preserving its direction, even though the next sort direction is actually different and should * only be changed once the arrow displays again (hint or activation). */ _updateArrowDirection() { this._arrowDirection = this.getSortDirection(); } /** * Gets the aria-sort attribute that should be applied to this sort header. If this header * is not sorted, returns null so that the attribute is removed from the host element. Aria spec * says that the aria-sort property should only be present on one header at a time, so removing * ensures this is true. */ _getAriaSortAttribute() { if (!this._isSorted()) { return 'none'; } let sort = this._sortHeader.sortedBy.find(s => s.id === this.id); return sort.direction == 'asc' ? 'ascending' : 'descending'; } getSortDirection() { if (!this._isSorted()) { return ''; } let sort = this._sortHeader.sortedBy.find(s => s.id === this.id); return sort.direction; } /** * Gets the sort counter that will display whenever multisort is enabled. It shows the order * in which sort is applied, whenever there are multiple columns being used for sorting. */ _getSortCounter() { if (!this._sortHeader.sortedBy || this._sortHeader.mode !== 'multi') { return ''; } const index = this._sortHeader.sortedBy.findIndex(s => s.id === this.id); if (index === -1) { return ''; } return (index + 1).toString(); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MdtMultiSortHeader, deps: [{ token: i1.MatSortHeaderIntl }, { token: i0.ChangeDetectorRef }, { token: i2.MdtMultiSort, optional: true }, { token: 'MAT_SORT_HEADER_COLUMN_DEF', optional: true }, { token: i3.FocusMonitor }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MdtMultiSortHeader, selector: "[mdt-sort-header]", inputs: { disabled: "disabled", id: ["mdt-sort-header", "id"], start: "start" }, exportAs: ["mdtSortHeader"], usesInheritance: true, ngImport: i0, template: "<div class=\"mat-sort-header-container mat-focus-indicator\"\r\n [class.mat-sort-header-sorted]=\"_isSorted()\"\r\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\r\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\r\n [attr.role]=\"_isDisabled() ? null : 'button'\">\r\n\r\n <div class=\"mat-sort-header-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Disable animations while a current animation is running -->\r\n <div class=\"mat-sort-header-arrow\"\r\n *ngIf=\"_renderArrow()\"\r\n [@arrowOpacity]=\"_getArrowViewState()\"\r\n [@arrowPosition]=\"_getArrowViewState()\"\r\n [@allowChildren]=\"_getArrowDirectionState()\"\r\n (@arrowPosition.start)=\"_disableViewStateAnimation = true\"\r\n (@arrowPosition.done)=\"_disableViewStateAnimation = false\">\r\n <div class=\"mat-sort-header-stem\"></div>\r\n <div class=\"mat-sort-header-indicator\" [@indicator]=\"_getArrowDirectionState()\">\r\n <div class=\"mat-sort-header-pointer-left\" [@leftPointer]=\"_getArrowDirectionState()\"></div>\r\n <div class=\"mat-sort-header-pointer-right\" [@rightPointer]=\"_getArrowDirectionState()\"></div>\r\n <div class=\"mat-sort-header-pointer-middle\"></div>\r\n </div>\r\n <div class=\"mat-sort-header-counter\">\r\n {{ _getSortCounter() }}\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".mat-sort-header-container{display:flex;cursor:pointer;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-disabled .mat-sort-header-container{cursor:default}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 1px) + 2px) * -1)}.mat-sort-header-content{text-align:center;display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}.mat-sort-header-arrow{height:12px;width:12px;min-width:12px;position:relative;display:flex;opacity:0}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-stem{background:currentColor;height:10px;width:2px;margin:auto;display:flex;align-items:center}.mat-sort-header-indicator{width:100%;height:2px;display:flex;align-items:center;position:absolute;top:0;left:0}.mat-sort-header-pointer-middle{margin:auto;height:2px;width:2px;background:currentColor;transform:rotate(45deg)}.mat-sort-header-pointer-left,.mat-sort-header-pointer-right{background:currentColor;width:6px;height:2px;position:absolute;top:0}.mat-sort-header-pointer-left{transform-origin:right;left:0}.mat-sort-header-pointer-right{transform-origin:left;right:0}.mat-sort-header-counter{position:absolute;margin-top:0;margin-left:13px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [ matSortAnimations.indicator, matSortAnimations.leftPointer, matSortAnimations.rightPointer, matSortAnimations.arrowOpacity, matSortAnimations.arrowPosition, matSortAnimations.allowChildren, ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MdtMultiSortHeader, decorators: [{ type: Component, args: [{ selector: '[mdt-sort-header]', exportAs: 'mdtSortHeader', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, inputs: ['disabled'], animations: [ matSortAnimations.indicator, matSortAnimations.leftPointer, matSortAnimations.rightPointer, matSortAnimations.arrowOpacity, matSortAnimations.arrowPosition, matSortAnimations.allowChildren, ], template: "<div class=\"mat-sort-header-container mat-focus-indicator\"\r\n [class.mat-sort-header-sorted]=\"_isSorted()\"\r\n [class.mat-sort-header-position-before]=\"arrowPosition === 'before'\"\r\n [attr.tabindex]=\"_isDisabled() ? null : 0\"\r\n [attr.role]=\"_isDisabled() ? null : 'button'\">\r\n\r\n <div class=\"mat-sort-header-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Disable animations while a current animation is running -->\r\n <div class=\"mat-sort-header-arrow\"\r\n *ngIf=\"_renderArrow()\"\r\n [@arrowOpacity]=\"_getArrowViewState()\"\r\n [@arrowPosition]=\"_getArrowViewState()\"\r\n [@allowChildren]=\"_getArrowDirectionState()\"\r\n (@arrowPosition.start)=\"_disableViewStateAnimation = true\"\r\n (@arrowPosition.done)=\"_disableViewStateAnimation = false\">\r\n <div class=\"mat-sort-header-stem\"></div>\r\n <div class=\"mat-sort-header-indicator\" [@indicator]=\"_getArrowDirectionState()\">\r\n <div class=\"mat-sort-header-pointer-left\" [@leftPointer]=\"_getArrowDirectionState()\"></div>\r\n <div class=\"mat-sort-header-pointer-right\" [@rightPointer]=\"_getArrowDirectionState()\"></div>\r\n <div class=\"mat-sort-header-pointer-middle\"></div>\r\n </div>\r\n <div class=\"mat-sort-header-counter\">\r\n {{ _getSortCounter() }}\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".mat-sort-header-container{display:flex;cursor:pointer;align-items:center;letter-spacing:normal;outline:0}[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container,[mat-sort-header].cdk-program-focused .mat-sort-header-container{border-bottom:solid 1px currentColor}.mat-sort-header-disabled .mat-sort-header-container{cursor:default}.mat-sort-header-container:before{margin:calc(calc(var(--mat-focus-indicator-border-width, 1px) + 2px) * -1)}.mat-sort-header-content{text-align:center;display:flex;align-items:center}.mat-sort-header-position-before{flex-direction:row-reverse}.mat-sort-header-arrow{height:12px;width:12px;min-width:12px;position:relative;display:flex;opacity:0}.mat-sort-header-arrow,[dir=rtl] .mat-sort-header-position-before .mat-sort-header-arrow{margin:0 0 0 6px}.mat-sort-header-position-before .mat-sort-header-arrow,[dir=rtl] .mat-sort-header-arrow{margin:0 6px 0 0}.mat-sort-header-stem{background:currentColor;height:10px;width:2px;margin:auto;display:flex;align-items:center}.mat-sort-header-indicator{width:100%;height:2px;display:flex;align-items:center;position:absolute;top:0;left:0}.mat-sort-header-pointer-middle{margin:auto;height:2px;width:2px;background:currentColor;transform:rotate(45deg)}.mat-sort-header-pointer-left,.mat-sort-header-pointer-right{background:currentColor;width:6px;height:2px;position:absolute;top:0}.mat-sort-header-pointer-left{transform-origin:right;left:0}.mat-sort-header-pointer-right{transform-origin:left;right:0}.mat-sort-header-counter{position:absolute;margin-top:0;margin-left:13px}\n"] }] }], ctorParameters: () => [{ type: i1.MatSortHeaderIntl }, { type: i0.ChangeDetectorRef }, { type: i2.MdtMultiSort, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Inject, args: ['MAT_SORT_HEADER_COLUMN_DEF'] }, { type: Optional }] }, { type: i3.FocusMonitor }, { type: i0.ElementRef }], propDecorators: { id: [{ type: Input, args: ['mdt-sort-header'] }], start: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc29ydC1oZWFkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXRlcmlhbC1keW5hbWljLXRhYmxlL3NyYy9saWIvbXVsdGktc29ydC9tdWx0aS1zb3J0LWhlYWRlci50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL21hdGVyaWFsLWR5bmFtaWMtdGFibGUvc3JjL2xpYi9tdWx0aS1zb3J0L211bHRpLXNvcnQtaGVhZGVyLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULEtBQUssRUFHTCxRQUFRLEVBQ1IsaUJBQWlCLEVBQ2pCLE1BQU0sRUFDTixVQUFVLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBOEIsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekgsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7QUEyQmpEOzs7Ozs7OztHQVFHO0FBa0JILE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxhQUFhO0lBYW5ELFlBQW1CLEtBQXdCLEVBQ3pDLGlCQUFvQyxFQUNqQixVQUF3QixFQUNjLFVBQWtDLEVBQzNGLGFBQTJCLEVBQzNCLFdBQW9DO1FBQ3BDLDhGQUE4RjtRQUM5RixvRkFBb0Y7UUFDcEYsaUZBQWlGO1FBQ2pGLDRCQUE0QjtRQUM1QixLQUFLLENBQUMsS0FBSyxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBVm5FLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBRXRCLGVBQVUsR0FBVixVQUFVLENBQWM7UUFDYyxlQUFVLEdBQVYsVUFBVSxDQUF3QjtRQVI3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QU0sVUFDdkMsQ0FBQyxVQUFVLENBQUMsY0FDUjt3QkFDVixpQkFBaUIsQ0FBQyxTQUFTO3dCQUMzQixpQkFBaUIsQ0FBQyxXQUFXO3dCQUM3QixpQkFBaUIsQ0FBQyxZQUFZO3dCQUM5QixpQkFBaUIsQ0FBQyxZQUFZO3dCQUM5QixpQkFBaUIsQ0FBQyxhQUFhO3dCQUMvQixpQkFBaUIsQ0FBQyxhQUFhO3FCQUNoQzs7MEJBaUJFLFFBQVE7OzBCQUNSLE1BQU07MkJBQUMsNEJBQTRCOzswQkFBRyxRQUFROzZGQVZ2QixFQUFFO3NCQUEzQixLQUFLO3VCQUFDLGlCQUFpQjtnQkFHZixLQUFLO3NCQUFiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBJbnB1dCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE9wdGlvbmFsLFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG4gIEluamVjdCxcclxuICBFbGVtZW50UmVmXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE1kdE11bHRpU29ydCB9IGZyb20gJy4vbXVsdGktc29ydC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBTb3J0RGlyZWN0aW9uLCBNYXRTb3J0YWJsZSwgbWF0U29ydEFuaW1hdGlvbnMsIE1hdFNvcnRIZWFkZXIsIE1hdFNvcnRIZWFkZXJJbnRsIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc29ydCc7XHJcbmltcG9ydCB7IEZvY3VzTW9uaXRvciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcclxuXHJcbi8qKlxyXG4gKiBWYWxpZCBwb3NpdGlvbnMgZm9yIHRoZSBhcnJvdyB0byBiZSBpbiBmb3IgaXRzIG9wYWNpdHkgYW5kIHRyYW5zbGF0aW9uLiBJZiB0aGUgc3RhdGUgaXMgYVxyXG4gKiBzb3J0IGRpcmVjdGlvbiwgdGhlIHBvc2l0aW9uIG9mIHRoZSBhcnJvdyB3aWxsIGJlIGFib3ZlL2JlbG93IGFuZCBvcGFjaXR5IDAuIElmIHRoZSBzdGF0ZSBpc1xyXG4gKiBoaW50LCB0aGUgYXJyb3cgd2lsbCBiZSBpbiB0aGUgY2VudGVyIHdpdGggYSBzbGlnaHQgb3BhY2l0eS4gQWN0aXZlIHN0YXRlIG1lYW5zIHRoZSBhcnJvdyB3aWxsXHJcbiAqIGJlIGZ1bGx5IG9wYXF1ZSBpbiB0aGUgY2VudGVyLlxyXG4gKlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBBcnJvd1ZpZXdTdGF0ZSA9IFNvcnREaXJlY3Rpb24gfCAnaGludCcgfCAnYWN0aXZlJztcclxuXHJcbi8qKlxyXG4gKiBTdGF0ZXMgZGVzY3JpYmluZyB0aGUgYXJyb3cncyBhbmltYXRlZCBwb3NpdGlvbiAoYW5pbWF0aW5nIGZyb21TdGF0ZSB0byB0b1N0YXRlKS5cclxuICogSWYgdGhlIGZyb21TdGF0ZSBpcyBub3QgZGVmaW5lZCwgdGhlcmUgd2lsbCBiZSBubyBhbmltYXRlZCB0cmFuc2l0aW9uIHRvIHRoZSB0b1N0YXRlLlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEFycm93Vmlld1N0YXRlVHJhbnNpdGlvbiB7XHJcbiAgZnJvbVN0YXRlPzogQXJyb3dWaWV3U3RhdGU7XHJcbiAgdG9TdGF0ZTogQXJyb3dWaWV3U3RhdGU7XHJcbn1cclxuXHJcbi8qKiBDb2x1bW4gZGVmaW5pdGlvbiBhc3NvY2lhdGVkIHdpdGggYSBgTWF0U29ydEhlYWRlcmAuICovXHJcbmludGVyZmFjZSBNYXRTb3J0SGVhZGVyQ29sdW1uRGVmIHtcclxuICBuYW1lOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBcHBsaWVzIHNvcnRpbmcgYmVoYXZpb3IgKGNsaWNrIHRvIGNoYW5nZSBzb3J0KSBhbmQgc3R5bGVzIHRvIGFuIGVsZW1lbnQsIGluY2x1ZGluZyBhblxyXG4gKiBhcnJvdyB0byBkaXNwbGF5IHRoZSBjdXJyZW50IHNvcnQgZGlyZWN0aW9uLlxyXG4gKlxyXG4gKiBNdXN0IGJlIHByb3ZpZGVkIHdpdGggYW4gaWQgYW5kIGNvbnRhaW5lZCB3aXRoaW4gYSBwYXJlbnQgTWF0U29ydCBkaXJlY3RpdmUuXHJcbiAqXHJcbiAqIElmIHVzZWQgb24gaGVhZGVyIGNlbGxzIGluIGEgQ2RrVGFibGUsIGl0IHdpbGwgYXV0b21hdGljYWxseSBkZWZhdWx0IGl0cyBpZCBmcm9tIGl0cyBjb250YWluaW5nXHJcbiAqIGNvbHVtbiBkZWZpbml0aW9uLlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdbbWR0LXNvcnQtaGVhZGVyXScsXHJcbiAgZXhwb3J0QXM6ICdtZHRTb3J0SGVhZGVyJyxcclxuICB0ZW1wbGF0ZVVybDogJ211bHRpLXNvcnQtaGVhZGVyLmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWydtdWx0aS1zb3J0LWhlYWRlci5zY3NzJ10sXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBpbnB1dHM6IFsnZGlzYWJsZWQnXSxcclxuICBhbmltYXRpb25zOiBbXHJcbiAgICBtYXRTb3J0QW5pbWF0aW9ucy5pbmRpY2F0b3IsXHJcbiAgICBtYXRTb3J0QW5pbWF0aW9ucy5sZWZ0UG9pbnRlcixcclxuICAgIG1hdFNvcnRBbmltYXRpb25zLnJpZ2h0UG9pbnRlcixcclxuICAgIG1hdFNvcnRBbmltYXRpb25zLmFycm93T3BhY2l0eSxcclxuICAgIG1hdFNvcnRBbmltYXRpb25zLmFycm93UG9zaXRpb24sXHJcbiAgICBtYXRTb3J0QW5pbWF0aW9ucy5hbGxvd0NoaWxkcmVuLFxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIE1kdE11bHRpU29ydEhlYWRlciBleHRlbmRzIE1hdFNvcnRIZWFkZXIgaW1wbGVtZW50cyBNYXRTb3J0YWJsZSwgT25EZXN0cm95LCBPbkluaXQge1xyXG4gXHJcbiAgLyoqXHJcbiAgICogSUQgb2YgdGhpcyBzb3J0IGhlYWRlci4gSWYgdXNlZCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBDZGtDb2x1bW5EZWYsIHRoaXMgd2lsbCBkZWZhdWx0IHRvXHJcbiAgICogdGhlIGNvbHVtbidzIG5hbWUuXHJcbiAgICovXHJcbiAgQElucHV0KCdtZHQtc29ydC1oZWFkZXInKSBpZDogc3RyaW5nO1xyXG5cclxuICAvKiogT3ZlcnJpZGVzIHRoZSBzb3J0IHN0YXJ0IHZhbHVlIG9mIHRoZSBjb250YWluaW5nIE1hdFNvcnQgZm9yIHRoaXMgTWF0U29ydGFibGUuICovXHJcbiAgQElucHV0KCkgc3RhcnQ6ICdhc2MnIHwgJ2Rlc2MnID0gJ2FzYyc7XHJcblxyXG4gIHByaXZhdGUgX3NvcnRIZWFkZXI6IE1kdE11bHRpU29ydDtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIF9pbnRsOiBNYXRTb3J0SGVhZGVySW50bCxcclxuICAgIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIEBPcHRpb25hbCgpIHB1YmxpYyBfbXVsdGlTb3J0OiBNZHRNdWx0aVNvcnQsXHJcbiAgICBASW5qZWN0KCdNQVRfU09SVF9IRUFERVJfQ09MVU1OX0RFRicpIEBPcHRpb25hbCgpIHB1YmxpYyBfY29sdW1uRGVmOiBNYXRTb3J0SGVhZGVyQ29sdW1uRGVmLFxyXG4gICAgX2ZvY3VzTW9uaXRvcjogRm9jdXNNb25pdG9yLFxyXG4gICAgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KSB7XHJcbiAgICAvLyBOb3RlIHRoYXQgd2UgdXNlIGEgc3RyaW5nIHRva2VuIGZvciB0aGUgYF9jb2x1bW5EZWZgLCBiZWNhdXNlIHRoZSB2YWx1ZSBpcyBwcm92aWRlZCBib3RoIGJ5XHJcbiAgICAvLyBgbWF0ZXJpYWwvdGFibGVgIGFuZCBgY2RrL3RhYmxlYCBhbmQgd2UgY2FuJ3QgaGF2ZSB0aGUgQ0RLIGRlcGVuZGluZyBvbiBNYXRlcmlhbCxcclxuICAgIC8vIGFuZCB3ZSB3YW50IHRvIGF2b2lkIGhhdmluZyB0aGUgc29ydCBoZWFkZXIgZGVwZW5kaW5nIG9uIHRoZSBDREsgdGFibGUgYmVjYXVzZVxyXG4gICAgLy8gb2YgdGhpcyBzaW5nbGUgcmVmZXJlbmNlLlxyXG4gICAgc3VwZXIoX2ludGwsIGNoYW5nZURldGVjdG9yUmVmLCBfbXVsdGlTb3J0LCBfY29sdW1uRGVmLCBfZm9jdXNNb25pdG9yLCBfZWxlbWVudFJlZik7XHJcbiAgICB0aGlzLl9zb3J0SGVhZGVyID0gX211bHRpU29ydDtcclxuICB9XHJcblxyXG4gIF9oYW5kbGVDbGljaygpIHtcclxuICAgIC8vdGhpcy5fc29ydC5kaXJlY3Rpb24gPSB0aGlzLmdldFNvcnREaXJlY3Rpb24oKTtcclxuICAgIHN1cGVyLl9oYW5kbGVDbGljaygpO1xyXG4gIH1cclxuICAgICAgXHJcbiAgLyoqIFdoZXRoZXIgdGhpcyBNYXRTb3J0SGVhZGVyIGlzIGN1cnJlbnRseSBzb3J0ZWQgaW4gZWl0aGVyIGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLiAqL1xyXG4gIF9pc1NvcnRlZCgpIHtcclxuICAgIGlmICghdGhpcy5fc29ydEhlYWRlci5zb3J0ZWRCeSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHNvcnQgPSB0aGlzLl9zb3J0SGVhZGVyLnNvcnRlZEJ5LmZpbmQocyA9PiBzLmlkID09PSB0aGlzLmlkKTtcclxuICAgIHJldHVybiAhIXNvcnQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGVzIHRoZSBkaXJlY3Rpb24gdGhlIGFycm93IHNob3VsZCBiZSBwb2ludGluZy4gSWYgaXQgaXMgbm90IHNvcnRlZCwgdGhlIGFycm93IHNob3VsZCBiZVxyXG4gICAqIGZhY2luZyB0aGUgc3RhcnQgZGlyZWN0aW9uLiBPdGhlcndpc2UgaWYgaXQgaXMgc29ydGVkLCB0aGUgYXJyb3cgc2hvdWxkIHBvaW50IGluIHRoZSBjdXJyZW50bHlcclxuICAgKiBhY3RpdmUgc29ydGVkIGRpcmVjdGlvbi4gVGhlIHJlYXNvbiB0aGlzIGlzIHVwZGF0ZWQgdGhyb3VnaCBhIGZ1bmN0aW9uIGlzIGJlY2F1c2UgdGhlIGRpcmVjdGlvblxyXG4gICAqIHNob3VsZCBvbmx5IGJlIGNoYW5nZWQgYXQgc3BlY2lmaWMgdGltZXMgLSB3aGVuIGRlYWN0aXZhdGVkIGJ1dCB0aGUgaGludCBpcyBkaXNwbGF5ZWQgYW5kIHdoZW5cclxuICAgKiB0aGUgc29ydCBpcyBhY3RpdmUgYW5kIHRoZSBkaXJlY3Rpb24gY2hhbmdlcy4gT3RoZXJ3aXNlIHRoZSBhcnJvdydzIGRpcmVjdGlvbiBzaG91bGQgbGluZ2VyXHJcbiAgICogaW4gY2FzZXMgc3VjaCBhcyB0aGUgc29ydCBiZWNvbWluZyBkZWFjdGl2YXRlZCBidXQgd2Ugd2FudCB0byBhbmltYXRlIHRoZSBhcnJvdyBhd2F5IHdoaWxlXHJcbiAgICogcHJlc2VydmluZyBpdHMgZGlyZWN0aW9uLCBldmVuIHRob3VnaCB0aGUgbmV4dCBzb3J0IGRpcmVjdGlvbiBpcyBhY3R1YWxseSBkaWZmZXJlbnQgYW5kIHNob3VsZFxyXG4gICAqIG9ubHkgYmUgY2hhbmdlZCBvbmNlIHRoZSBhcnJvdyBkaXNwbGF5cyBhZ2FpbiAoaGludCBvciBhY3RpdmF0aW9uKS5cclxuICAgKi9cclxuICBfdXBkYXRlQXJyb3dEaXJlY3Rpb24oKSB7XHJcbiAgICB0aGlzLl9hcnJvd0RpcmVjdGlvbiA9IHRoaXMuZ2V0U29ydERpcmVjdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgYXJpYS1zb3J0IGF0dHJpYnV0ZSB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoaXMgc29ydCBoZWFkZXIuIElmIHRoaXMgaGVhZGVyXHJcbiAgICogaXMgbm90IHNvcnRlZCwgcmV0dXJucyBudWxsIHNvIHRoYXQgdGhlIGF0dHJpYnV0ZSBpcyByZW1vdmVkIGZyb20gdGhlIGhvc3QgZWxlbWVudC4gQXJpYSBzcGVjXHJcbiAgICogc2F5cyB0aGF0IHRoZSBhcmlhLXNvcnQgcHJvcGVydHkgc2hvdWxkIG9ubHkgYmUgcHJlc2VudCBvbiBvbmUgaGVhZGVyIGF0IGEgdGltZSwgc28gcmVtb3ZpbmdcclxuICAgKiBlbnN1cmVzIHRoaXMgaXMgdHJ1ZS5cclxuICAgKi9cclxuICBfZ2V0QXJpYVNvcnRBdHRyaWJ1dGUoKSB7XHJcbiAgICBpZiAoIXRoaXMuX2lzU29ydGVkKCkpIHtcclxuICAgICAgcmV0dXJuICdub25lJztcclxuICAgIH1cclxuXHJcbiAgICBsZXQgc29ydCA9IHRoaXMuX3NvcnRIZWFkZXIuc29ydGVkQnkuZmluZChzID0+IHMuaWQgPT09IHRoaXMuaWQpITtcclxuICAgIHJldHVybiBzb3J0LmRpcmVjdGlvbiA9PSAnYXNjJyA/ICdhc2NlbmRpbmcnIDogJ2Rlc2NlbmRpbmcnO1xyXG4gIH1cclxuXHJcbiAgZ2V0U29ydERpcmVjdGlvbigpOiAnYXNjJyB8ICdkZXNjJyB8ICcnIHtcclxuICAgIGlmICghdGhpcy5faXNTb3J0ZWQoKSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHNvcnQgPSB0aGlzLl9zb3J0SGVhZGVyLnNvcnRlZEJ5LmZpbmQocyA9PiBzLmlkID09PSB0aGlzLmlkKSE7XHJcbiAgICByZXR1cm4gc29ydC5kaXJlY3Rpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSBzb3J0IGNvdW50ZXIgdGhhdCB3aWxsIGRpc3BsYXkgd2hlbmV2ZXIgbXVsdGlzb3J0IGlzIGVuYWJsZWQuIEl0IHNob3dzIHRoZSBvcmRlclxyXG4gICAqIGluIHdoaWNoIHNvcnQgaXMgYXBwbGllZCwgd2hlbmV2ZXIgdGhlcmUgYXJlIG11bHRpcGxlIGNvbHVtbnMgYmVpbmcgdXNlZCBmb3Igc29ydGluZy5cclxuICAgKi9cclxuICBfZ2V0U29ydENvdW50ZXIoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5fc29ydEhlYWRlci5zb3J0ZWRCeSB8fCB0aGlzLl9zb3J0SGVhZGVyLm1vZGUgIT09ICdtdWx0aScpIHtcclxuICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9zb3J0SGVhZGVyLnNvcnRlZEJ5LmZpbmRJbmRleChzID0+IHMuaWQgPT09IHRoaXMuaWQpO1xyXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIChpbmRleCArIDEpLnRvU3RyaW5nKCk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJtYXQtc29ydC1oZWFkZXItY29udGFpbmVyIG1hdC1mb2N1cy1pbmRpY2F0b3JcIlxyXG4gICAgIFtjbGFzcy5tYXQtc29ydC1oZWFkZXItc29ydGVkXT1cIl9pc1NvcnRlZCgpXCJcclxuICAgICBbY2xhc3MubWF0LXNvcnQtaGVhZGVyLXBvc2l0aW9uLWJlZm9yZV09XCJhcnJvd1Bvc2l0aW9uID09PSAnYmVmb3JlJ1wiXHJcbiAgICAgW2F0dHIudGFiaW5kZXhdPVwiX2lzRGlzYWJsZWQoKSA/IG51bGwgOiAwXCJcclxuICAgICBbYXR0ci5yb2xlXT1cIl9pc0Rpc2FibGVkKCkgPyBudWxsIDogJ2J1dHRvbidcIj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cIm1hdC1zb3J0LWhlYWRlci1jb250ZW50XCI+XHJcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gRGlzYWJsZSBhbmltYXRpb25zIHdoaWxlIGEgY3VycmVudCBhbmltYXRpb24gaXMgcnVubmluZyAtLT5cclxuICA8ZGl2IGNsYXNzPVwibWF0LXNvcnQtaGVhZGVyLWFycm93XCJcclxuICAgICAgICpuZ0lmPVwiX3JlbmRlckFycm93KClcIlxyXG4gICAgICAgW0BhcnJvd09wYWNpdHldPVwiX2dldEFycm93Vmlld1N0YXRlKClcIlxyXG4gICAgICAgW0BhcnJvd1Bvc2l0aW9uXT1cIl9nZXRBcnJvd1ZpZXdTdGF0ZSgpXCJcclxuICAgICAgIFtAYWxsb3dDaGlsZHJlbl09XCJfZ2V0QXJyb3dEaXJlY3Rpb25TdGF0ZSgpXCJcclxuICAgICAgIChAYXJyb3dQb3NpdGlvbi5zdGFydCk9XCJfZGlzYWJsZVZpZXdTdGF0ZUFuaW1hdGlvbiA9IHRydWVcIlxyXG4gICAgICAgKEBhcnJvd1Bvc2l0aW9uLmRvbmUpPVwiX2Rpc2FibGVWaWV3U3RhdGVBbmltYXRpb24gPSBmYWxzZVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cIm1hdC1zb3J0LWhlYWRlci1zdGVtXCI+PC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwibWF0LXNvcnQtaGVhZGVyLWluZGljYXRvclwiIFtAaW5kaWNhdG9yXT1cIl9nZXRBcnJvd0RpcmVjdGlvblN0YXRlKClcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1hdC1zb3J0LWhlYWRlci1wb2ludGVyLWxlZnRcIiBbQGxlZnRQb2ludGVyXT1cIl9nZXRBcnJvd0RpcmVjdGlvblN0YXRlKClcIj48L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1hdC1zb3J0LWhlYWRlci1wb2ludGVyLXJpZ2h0XCIgW0ByaWdodFBvaW50ZXJdPVwiX2dldEFycm93RGlyZWN0aW9uU3RhdGUoKVwiPjwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwibWF0LXNvcnQtaGVhZGVyLXBvaW50ZXItbWlkZGxlXCI+PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJtYXQtc29ydC1oZWFkZXItY291bnRlclwiPlxyXG4gICAgICB7eyBfZ2V0U29ydENvdW50ZXIoKSB9fVxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG4iXX0=