@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
112 lines • 19.7 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, inject, Input, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ColumnSortingDirective, ColumnSortingState } from './column-sorting.directive';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../icon/icon.component";
export class ColumnSortingComponent {
constructor() {
this._sorter = inject(ColumnSortingDirective);
this._changeDetector = inject(ChangeDetectorRef);
/** Defines the sorting order of a column: `NoSort`, `Ascending` or `Descending`. */
this.state = ColumnSortingState.NoSort;
/** Determine if a column can have a `NoSort` state */
this.allowNoSort = true;
/** Specifies name of the ascending icon */
this.ascendingIcon = 'ascend';
/** Specifies name of the descending icon */
this.descendingIcon = 'descend';
/**
* Changes the state of the sorting on the column between `NoSort`, `Ascending` and `Descending`.
* This returns an array of objects for each column being sorted containing `key: string` and `state: ColumnSortingState`.
* State can be used to find the current sorting state of the column eg. `(state === ColumnSortingState.Ascending)`.
* The `ColumnSortingOrder` interface has been provided for objects in the array.
*/
this.stateChange = new EventEmitter();
/** Emit whenever the order changes */
this.orderChange = new EventEmitter();
/** Expose the sorting state enum to the view */
this.ColumnSortingState = ColumnSortingState;
/** Unsubscribe from all observables on component destroy */
this._onDestroy$ = new Subject();
}
/** Access the custom sort indicator if one was provided */
get _sortIndicator() {
return this._sorter.sortIndicator;
}
ngOnInit() {
// listen for changes triggered by the directive
this._sorter.events.pipe(takeUntil(this._onDestroy$))
.subscribe(columns => this.updateState(columns));
}
ngOnChanges(changes) {
// if the state input is changed then apply the change
if (changes.state && changes.state.currentValue !== changes.state.previousValue) {
this._sorter.setColumnState(this.key, this.state);
}
}
ngOnDestroy() {
this._onDestroy$.next();
this._onDestroy$.complete();
}
/** Toggle the sorting state of a column - this is designed to be programmatically called by the consuming component */
changeState() {
switch (this.state) {
case ColumnSortingState.Ascending:
this.state = ColumnSortingState.Descending;
break;
case ColumnSortingState.Descending:
this.state = this.allowNoSort ? ColumnSortingState.NoSort : ColumnSortingState.Ascending;
break;
default:
this.state = ColumnSortingState.Ascending;
}
// change detection should be run
this._changeDetector.markForCheck();
// inform parent (internally we use a ReadonlyArray but are returning a standard array to prevent breaking changes to the public API)
return this._sorter.toggleColumn({ key: this.key, state: this.state });
}
/** Update the state based on column order */
updateState(columns) {
// if we are sorting this column then find the matching data
const columnIdx = columns.findIndex(_column => _column.key === this.key);
// if we are not sorting this column then mark it as NoSort
if (columnIdx === -1) {
this.state = ColumnSortingState.NoSort;
}
// only store the number if we have 2 or more columns being sorted
this.order = columns.length < 2 || columnIdx === -1 ? null : columnIdx + 1;
// emit the latest order value
if (typeof this.order === 'number') {
this.orderChange.emit(this.order);
}
// change detection should be run
this._changeDetector.markForCheck();
// Emit the latest change
this.stateChange.emit(this.state);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ColumnSortingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: ColumnSortingComponent, selector: "ux-column-sorting", inputs: { state: "state", key: "key", order: "order", allowNoSort: "allowNoSort", ascendingIcon: "ascendingIcon", descendingIcon: "descendingIcon" }, outputs: { stateChange: "stateChange", orderChange: "orderChange" }, exportAs: ["ux-column-sorting"], usesOnChanges: true, ngImport: i0, template: "<div class=\"ux-column-sorting\"\n [class.ux-column-sorting-hidden]=\"state === ColumnSortingState.NoSort\">\n\n <!-- The default sort indicator -->\n @if (!_sortIndicator) {\n <ux-icon\n class=\"ux-column-sorting-icon\"\n [class.column-sorting-icon-hidden]=\"state === ColumnSortingState.NoSort\"\n [name]=\"state === ColumnSortingState.Descending ? descendingIcon : ascendingIcon\">\n </ux-icon>\n <p class=\"ux-column-sorting-number\" aria-hidden=\"true\">{{ order }}</p>\n }\n\n <!-- Custom sort indicator -->\n @if (_sortIndicator) {\n <ng-container\n [ngTemplateOutlet]=\"_sortIndicator\"\n [ngTemplateOutletContext]=\"{ state: state, order: order }\">\n </ng-container>\n }\n\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.IconComponent, selector: "ux-icon", inputs: ["name", "size", "rotate", "flipHorizontal", "flipVertical"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ColumnSortingComponent, decorators: [{
type: Component,
args: [{ selector: 'ux-column-sorting', exportAs: 'ux-column-sorting', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ux-column-sorting\"\n [class.ux-column-sorting-hidden]=\"state === ColumnSortingState.NoSort\">\n\n <!-- The default sort indicator -->\n @if (!_sortIndicator) {\n <ux-icon\n class=\"ux-column-sorting-icon\"\n [class.column-sorting-icon-hidden]=\"state === ColumnSortingState.NoSort\"\n [name]=\"state === ColumnSortingState.Descending ? descendingIcon : ascendingIcon\">\n </ux-icon>\n <p class=\"ux-column-sorting-number\" aria-hidden=\"true\">{{ order }}</p>\n }\n\n <!-- Custom sort indicator -->\n @if (_sortIndicator) {\n <ng-container\n [ngTemplateOutlet]=\"_sortIndicator\"\n [ngTemplateOutletContext]=\"{ state: state, order: order }\">\n </ng-container>\n }\n\n</div>\n" }]
}], propDecorators: { state: [{
type: Input
}], key: [{
type: Input
}], order: [{
type: Input
}], allowNoSort: [{
type: Input
}], ascendingIcon: [{
type: Input
}], descendingIcon: [{
type: Input
}], stateChange: [{
type: Output
}], orderChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sdW1uLXNvcnRpbmcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY29sdW1uLXNvcnRpbmcvY29sdW1uLXNvcnRpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY29sdW1uLXNvcnRpbmcvY29sdW1uLXNvcnRpbmcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBZ0MsTUFBTSxFQUE4QixNQUFNLGVBQWUsQ0FBQztBQUNyTCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsc0JBQXNCLEVBQXFELGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7QUFRM0ksTUFBTSxPQUFPLHNCQUFzQjtJQU5uQztRQVFxQixZQUFPLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFFekMsb0JBQWUsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUU3RCxvRkFBb0Y7UUFDM0UsVUFBSyxHQUF1QixrQkFBa0IsQ0FBQyxNQUFNLENBQUM7UUFRL0Qsc0RBQXNEO1FBQzdDLGdCQUFXLEdBQVksSUFBSSxDQUFDO1FBRXJDLDJDQUEyQztRQUNsQyxrQkFBYSxHQUFXLFFBQVEsQ0FBQztRQUUxQyw0Q0FBNEM7UUFDbkMsbUJBQWMsR0FBVyxTQUFTLENBQUM7UUFFNUM7Ozs7O1dBS0c7UUFDTyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFzQixDQUFDO1FBRS9ELHNDQUFzQztRQUM1QixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFbkQs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RUQsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFcEMseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDOytHQS9HUSxzQkFBc0I7bUdBQXRCLHNCQUFzQiwwVUNYbkMscXVCQXNCQTs7NEZEWGEsc0JBQXNCO2tCQU5sQyxTQUFTOytCQUNJLG1CQUFtQixZQUVuQixtQkFBbUIsbUJBQ1osdUJBQXVCLENBQUMsTUFBTTs4QkFTdEMsS0FBSztzQkFBYixLQUFLO2dCQUdHLEdBQUc7c0JBQVgsS0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0csV0FBVztzQkFBbkIsS0FBSztnQkFHRyxhQUFhO3NCQUFyQixLQUFLO2dCQUdHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBUUksV0FBVztzQkFBcEIsTUFBTTtnQkFHRyxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgaW5qZWN0LCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ29sdW1uU29ydGluZ0RpcmVjdGl2ZSwgQ29sdW1uU29ydGluZ0luZGljYXRvckNvbnRleHQsIENvbHVtblNvcnRpbmdPcmRlciwgQ29sdW1uU29ydGluZ1N0YXRlIH0gZnJvbSAnLi9jb2x1bW4tc29ydGluZy5kaXJlY3RpdmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3V4LWNvbHVtbi1zb3J0aW5nJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY29sdW1uLXNvcnRpbmcuY29tcG9uZW50Lmh0bWwnLFxuICAgIGV4cG9ydEFzOiAndXgtY29sdW1uLXNvcnRpbmcnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIENvbHVtblNvcnRpbmdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3NvcnRlciA9IGluamVjdChDb2x1bW5Tb3J0aW5nRGlyZWN0aXZlKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5nZURldGVjdG9yID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAgIC8qKiBEZWZpbmVzIHRoZSBzb3J0aW5nIG9yZGVyIG9mIGEgY29sdW1uOiBgTm9Tb3J0YCwgYEFzY2VuZGluZ2Agb3IgYERlc2NlbmRpbmdgLiAqL1xuICAgIEBJbnB1dCgpIHN0YXRlOiBDb2x1bW5Tb3J0aW5nU3RhdGUgPSBDb2x1bW5Tb3J0aW5nU3RhdGUuTm9Tb3J0O1xuXG4gICAgLyoqIERlZmluZXMgYSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbHVtbiB0aGF0IGNhbiBiZSB1c2VkIHdoZW4gc29ydGluZy4gKi9cbiAgICBASW5wdXQoKSBrZXk6IHN0cmluZztcblxuICAgIC8qKiBTdG9yZSB0aGUgb3JkZXIgb2YgdGhlIHNvcnRpbmcgLSB1c2VkIHdoZW4gbXVsdGlwbGUgY29sdW1ucyBhcmUgYmVpbmcgc29ydGVkIGF0IG9uY2UgKi9cbiAgICBASW5wdXQoKSBvcmRlcjogbnVtYmVyO1xuXG4gICAgLyoqIERldGVybWluZSBpZiBhIGNvbHVtbiBjYW4gaGF2ZSBhIGBOb1NvcnRgIHN0YXRlICovXG4gICAgQElucHV0KCkgYWxsb3dOb1NvcnQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIFNwZWNpZmllcyBuYW1lIG9mIHRoZSBhc2NlbmRpbmcgaWNvbiAqL1xuICAgIEBJbnB1dCgpIGFzY2VuZGluZ0ljb246IHN0cmluZyA9ICdhc2NlbmQnO1xuXG4gICAgLyoqIFNwZWNpZmllcyBuYW1lIG9mIHRoZSBkZXNjZW5kaW5nIGljb24gKi9cbiAgICBASW5wdXQoKSBkZXNjZW5kaW5nSWNvbjogc3RyaW5nID0gJ2Rlc2NlbmQnO1xuXG4gICAgLyoqXG4gICAgICogQ2hhbmdlcyB0aGUgc3RhdGUgb2YgdGhlIHNvcnRpbmcgb24gdGhlIGNvbHVtbiBiZXR3ZWVuIGBOb1NvcnRgLCBgQXNjZW5kaW5nYCBhbmQgYERlc2NlbmRpbmdgLlxuICAgICAqIFRoaXMgcmV0dXJucyBhbiBhcnJheSBvZiBvYmplY3RzIGZvciBlYWNoIGNvbHVtbiBiZWluZyBzb3J0ZWQgY29udGFpbmluZyBga2V5OiBzdHJpbmdgIGFuZCBgc3RhdGU6IENvbHVtblNvcnRpbmdTdGF0ZWAuXG4gICAgICogU3RhdGUgY2FuIGJlIHVzZWQgdG8gZmluZCB0aGUgY3VycmVudCBzb3J0aW5nIHN0YXRlIG9mIHRoZSBjb2x1bW4gZWcuIGAoc3RhdGUgPT09IENvbHVtblNvcnRpbmdTdGF0ZS5Bc2NlbmRpbmcpYC5cbiAgICAgKiBUaGUgYENvbHVtblNvcnRpbmdPcmRlcmAgaW50ZXJmYWNlIGhhcyBiZWVuIHByb3ZpZGVkIGZvciBvYmplY3RzIGluIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgc3RhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPENvbHVtblNvcnRpbmdTdGF0ZT4oKTtcblxuICAgIC8qKiBFbWl0IHdoZW5ldmVyIHRoZSBvcmRlciBjaGFuZ2VzICovXG4gICAgQE91dHB1dCgpIG9yZGVyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKiogRXhwb3NlIHRoZSBzb3J0aW5nIHN0YXRlIGVudW0gdG8gdGhlIHZpZXcgKi9cbiAgICBDb2x1bW5Tb3J0aW5nU3RhdGUgPSBDb2x1bW5Tb3J0aW5nU3RhdGU7XG5cbiAgICAvKiogQWNjZXNzIHRoZSBjdXN0b20gc29ydCBpbmRpY2F0b3IgaWYgb25lIHdhcyBwcm92aWRlZCAqL1xuICAgIGdldCBfc29ydEluZGljYXRvcigpOiBUZW1wbGF0ZVJlZjxDb2x1bW5Tb3J0aW5nSW5kaWNhdG9yQ29udGV4dD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc29ydGVyLnNvcnRJbmRpY2F0b3I7XG4gICAgfVxuXG4gICAgLyoqIFVuc3Vic2NyaWJlIGZyb20gYWxsIG9ic2VydmFibGVzIG9uIGNvbXBvbmVudCBkZXN0cm95ICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfb25EZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gbGlzdGVuIGZvciBjaGFuZ2VzIHRyaWdnZXJlZCBieSB0aGUgZGlyZWN0aXZlXG4gICAgICAgIHRoaXMuX3NvcnRlci5ldmVudHMucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKGNvbHVtbnMgPT4gdGhpcy51cGRhdGVTdGF0ZShjb2x1bW5zKSk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICAvLyBpZiB0aGUgc3RhdGUgaW5wdXQgaXMgY2hhbmdlZCB0aGVuIGFwcGx5IHRoZSBjaGFuZ2VcbiAgICAgICAgaWYgKGNoYW5nZXMuc3RhdGUgJiYgY2hhbmdlcy5zdGF0ZS5jdXJyZW50VmFsdWUgIT09IGNoYW5nZXMuc3RhdGUucHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fc29ydGVyLnNldENvbHVtblN0YXRlKHRoaXMua2V5LCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5fb25EZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8qKiBUb2dnbGUgdGhlIHNvcnRpbmcgc3RhdGUgb2YgYSBjb2x1bW4gLSB0aGlzIGlzIGRlc2lnbmVkIHRvIGJlIHByb2dyYW1tYXRpY2FsbHkgY2FsbGVkIGJ5IHRoZSBjb25zdW1pbmcgY29tcG9uZW50ICovXG4gICAgY2hhbmdlU3RhdGUoKTogQ29sdW1uU29ydGluZ09yZGVyW10ge1xuXG4gICAgICAgIHN3aXRjaCAodGhpcy5zdGF0ZSkge1xuXG4gICAgICAgICAgICBjYXNlIENvbHVtblNvcnRpbmdTdGF0ZS5Bc2NlbmRpbmc6XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IENvbHVtblNvcnRpbmdTdGF0ZS5EZXNjZW5kaW5nO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIENvbHVtblNvcnRpbmdTdGF0ZS5EZXNjZW5kaW5nOlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLmFsbG93Tm9Tb3J0ID8gQ29sdW1uU29ydGluZ1N0YXRlLk5vU29ydCA6IENvbHVtblNvcnRpbmdTdGF0ZS5Bc2NlbmRpbmc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IENvbHVtblNvcnRpbmdTdGF0ZS5Bc2NlbmRpbmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGFuZ2UgZGV0ZWN0aW9uIHNob3VsZCBiZSBydW5cbiAgICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgLy8gaW5mb3JtIHBhcmVudCAoaW50ZXJuYWxseSB3ZSB1c2UgYSBSZWFkb25seUFycmF5IGJ1dCBhcmUgcmV0dXJuaW5nIGEgc3RhbmRhcmQgYXJyYXkgdG8gcHJldmVudCBicmVha2luZyBjaGFuZ2VzIHRvIHRoZSBwdWJsaWMgQVBJKVxuICAgICAgICByZXR1cm4gdGhpcy5fc29ydGVyLnRvZ2dsZUNvbHVtbih7IGtleTogdGhpcy5rZXksIHN0YXRlOiB0aGlzLnN0YXRlIH0pIGFzIENvbHVtblNvcnRpbmdPcmRlcltdO1xuICAgIH1cblxuICAgIC8qKiBVcGRhdGUgdGhlIHN0YXRlIGJhc2VkIG9uIGNvbHVtbiBvcmRlciAqL1xuICAgIHByaXZhdGUgdXBkYXRlU3RhdGUoY29sdW1uczogUmVhZG9ubHlBcnJheTxDb2x1bW5Tb3J0aW5nT3JkZXI+KTogdm9pZCB7XG4gICAgICAgIC8vIGlmIHdlIGFyZSBzb3J0aW5nIHRoaXMgY29sdW1uIHRoZW4gZmluZCB0aGUgbWF0Y2hpbmcgZGF0YVxuICAgICAgICBjb25zdCBjb2x1bW5JZHggPSBjb2x1bW5zLmZpbmRJbmRleChfY29sdW1uID0+IF9jb2x1bW4ua2V5ID09PSB0aGlzLmtleSk7XG5cbiAgICAgICAgLy8gaWYgd2UgYXJlIG5vdCBzb3J0aW5nIHRoaXMgY29sdW1uIHRoZW4gbWFyayBpdCBhcyBOb1NvcnRcbiAgICAgICAgaWYgKGNvbHVtbklkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBDb2x1bW5Tb3J0aW5nU3RhdGUuTm9Tb3J0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gb25seSBzdG9yZSB0aGUgbnVtYmVyIGlmIHdlIGhhdmUgMiBvciBtb3JlIGNvbHVtbnMgYmVpbmcgc29ydGVkXG4gICAgICAgIHRoaXMub3JkZXIgPSBjb2x1bW5zLmxlbmd0aCA8IDIgfHwgY29sdW1uSWR4ID09PSAtMSA/IG51bGwgOiBjb2x1bW5JZHggKyAxO1xuXG4gICAgICAgIC8vIGVtaXQgdGhlIGxhdGVzdCBvcmRlciB2YWx1ZVxuICAgICAgICBpZiAodHlwZW9mIHRoaXMub3JkZXIgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLm9yZGVyQ2hhbmdlLmVtaXQodGhpcy5vcmRlcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGFuZ2UgZGV0ZWN0aW9uIHNob3VsZCBiZSBydW5cbiAgICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgLy8gRW1pdCB0aGUgbGF0ZXN0IGNoYW5nZVxuICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlLmVtaXQodGhpcy5zdGF0ZSk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInV4LWNvbHVtbi1zb3J0aW5nXCJcbiAgW2NsYXNzLnV4LWNvbHVtbi1zb3J0aW5nLWhpZGRlbl09XCJzdGF0ZSA9PT0gQ29sdW1uU29ydGluZ1N0YXRlLk5vU29ydFwiPlxuXG4gIDwhLS0gVGhlIGRlZmF1bHQgc29ydCBpbmRpY2F0b3IgLS0+XG4gIEBpZiAoIV9zb3J0SW5kaWNhdG9yKSB7XG4gICAgPHV4LWljb25cbiAgICAgIGNsYXNzPVwidXgtY29sdW1uLXNvcnRpbmctaWNvblwiXG4gICAgICBbY2xhc3MuY29sdW1uLXNvcnRpbmctaWNvbi1oaWRkZW5dPVwic3RhdGUgPT09IENvbHVtblNvcnRpbmdTdGF0ZS5Ob1NvcnRcIlxuICAgICAgW25hbWVdPVwic3RhdGUgPT09IENvbHVtblNvcnRpbmdTdGF0ZS5EZXNjZW5kaW5nID8gZGVzY2VuZGluZ0ljb24gOiBhc2NlbmRpbmdJY29uXCI+XG4gICAgPC91eC1pY29uPlxuICAgIDxwIGNsYXNzPVwidXgtY29sdW1uLXNvcnRpbmctbnVtYmVyXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+e3sgb3JkZXIgfX08L3A+XG4gIH1cblxuICA8IS0tIEN1c3RvbSBzb3J0IGluZGljYXRvciAtLT5cbiAgQGlmIChfc29ydEluZGljYXRvcikge1xuICAgIDxuZy1jb250YWluZXJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIl9zb3J0SW5kaWNhdG9yXCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHN0YXRlOiBzdGF0ZSwgb3JkZXI6IG9yZGVyIH1cIj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgfVxuXG48L2Rpdj5cbiJdfQ==