@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
230 lines • 28.7 kB
JavaScript
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { RowAltSelectionStrategy } from './strategies/row-alt-selection.strategy';
import { RowSelectionStrategy } from './strategies/row-selection.strategy';
import { SelectionStrategy } from './strategies/selection.strategy';
import { SimpleSelectionStrategy } from './strategies/simple-selection.strategy';
import * as i0 from "@angular/core";
export class SelectionService {
constructor() {
/** The active selection strategy that defines how selections can be made */
this.strategy = new SimpleSelectionStrategy(this);
/** Define if selections can be performed on any items */
this.isEnabled = true;
/** Define if the mouse can be used to perform selections */
this.isClickEnabled = true;
/** Define if the keyboard can be used to perform selections */
this.isKeyboardEnabled = true;
/** Define the currently focused item */
this.focus$ = new BehaviorSubject(null);
/** Define the currently active item */
this.active$ = new BehaviorSubject(null);
/** Store the current list of selected items as an array */
this.selection$ = new BehaviorSubject([]);
/** Store the current set of selectable items */
this._dataset = [];
/** Store the selection strategy that should be destroyed */
this._strategyToDestroy = this.strategy;
/** Store the current selection in a set */
this._selection = new Set();
/** Store the current disabled items in a set */
this._disabled = new Set();
}
/** Store the current set of selectable items and ensure an item can be focused */
set dataset(dataset) {
this._dataset = dataset;
if (this._dataset.indexOf(this._active) === -1) {
this.setFirstItemFocusable();
}
}
/** Get the current set of selectable items */
get dataset() {
return this._dataset;
}
ngOnDestroy() {
// destroy the active strategy
if (this._strategyToDestroy) {
this._strategyToDestroy.destroy();
}
// complete all observables
this.focus$.complete();
this.active$.complete();
this.selection$.complete();
}
/**
* If the item is not currently selected then add it
* to the list of selected items
*/
select(...selections) {
// filter out any disabled items
selections = selections.filter(item => !this._disabled.has(item));
// add each selection to the set
selections.forEach(selection => this._selection.add(selection));
// propagate the changes
this.selectionHasMutated();
}
/**
* Deselect all currently selected items and replace with a new selection
*/
selectOnly(...selection) {
// filter out any disabled items
selection = selection.filter(item => !this._disabled.has(item));
// remove all currently selected items
this._selection.clear();
// select only the specified item
selection.forEach(item => this._selection.add(item));
// emit the changes
this.selectionHasMutated();
}
/**
* Remove an item from the list of selected items
*/
deselect(...selections) {
// remove each item from the set
selections.forEach(selection => this._selection.delete(selection));
// propagate the changes
this.selectionHasMutated();
}
/**
* Remove all items from the list of selected items
*/
deselectAll() {
// remove all items in the array
this.deselect(...this._dataset);
// clear the set in case any items have been removed from the DOM but are still selected
this._selection.clear();
}
/**
* Toggle the selected state of any specified items
*/
toggle(...selections) {
selections.forEach(selection => this.isSelected(selection) ? this.deselect(selection) : this.select(selection));
}
/**
* Determine whether or not a specific item is currently selected
*/
isSelected(data) {
return this._selection.has(data);
}
/**
* Return an observable specifically for notifying the subscriber
* only when the selection state of a specific object has changed
*/
getSelectionState(data) {
return this.selection$.pipe(map(() => this.isSelected(data)), distinctUntilChanged());
}
/**
* Define how selections should be performed.
* This allows us to use an strategy pattern to handle the various keyboard
* and mouse interactions while keeping each mode separated and
* easily extensible if we want to add more modes in future!
*/
setStrategy(mode) {
if (this._strategyToDestroy) {
// Destroy previous strategy if it was created internally
this._strategyToDestroy.destroy();
this._strategyToDestroy = null;
}
if (mode instanceof SelectionStrategy) {
// Custom strategy - pass in the service instance
this.strategy = mode;
this.strategy.setSelectionService(this);
}
else {
switch (mode.toLowerCase().trim()) {
case 'simple':
this.strategy = this._strategyToDestroy = new SimpleSelectionStrategy(this);
break;
case 'row':
this.strategy = this._strategyToDestroy = new RowSelectionStrategy(this);
break;
case 'row-alt':
this.strategy = this._strategyToDestroy = new RowAltSelectionStrategy(this);
break;
default:
throw new Error(`The selection mode '${mode}' does not exist. Valid modes are 'simple', 'row', or 'row-alt'.`);
}
}
}
/**
* Set the current active item
*/
activate(data) {
this._active = data;
this.active$.next(this._active);
}
/**
* Deactive all items
*/
deactivate() {
this._active = null;
this.active$.next(this._active);
}
/**
* Return the next or previous sibling of the current active item.
* @param previous If true, the previous sibling will be returned.
*/
getSibling(previous = false) {
// check if there is a current active item
if (!this._active) {
return;
}
// get the index of the current item
const idx = this.dataset.indexOf(this._active);
const target = this.dataset[previous ? idx - 1 : idx + 1];
return target;
}
/**
* Activate the sibling of the current active item.
* If previous is set to true the previous sibling will be activated
* rather than the next sibling. This function will also return the
* data of the newly activated sibling
*/
activateSibling(previous = false) {
const target = this.getSibling(previous);
// check if the target exists
if (target) {
this.activate(target);
}
return target;
}
setDisabled(disabled) {
// store the current disabled state
this.isEnabled = !disabled;
// clear any stateful data
this._active = null;
this.active$.next(this._active);
this._selection.clear();
// emit the selection change information
this.selectionHasMutated();
}
/** Store the disabled state of an item */
setItemDisabled(item, isDisabled) {
// update the internal list of disabled items
if (isDisabled && !this._disabled.has(item)) {
this._disabled.add(item);
}
else if (!isDisabled) {
this._disabled.delete(item);
}
}
selectionHasMutated() {
this.selection$.next(Array.from(this._selection));
}
setFirstItemFocusable() {
if (this._dataset.length > 0) {
this.focus$.next(this._dataset[0]);
this._active = this._dataset[0];
}
else {
this._active = null;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SelectionService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SelectionService, decorators: [{
type: Injectable
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGlyZWN0aXZlcy9zZWxlY3Rpb24vc2VsZWN0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNsRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7QUFHakYsTUFBTSxPQUFPLGdCQUFnQjtJQUQ3QjtRQWdCSSw0RUFBNEU7UUFDNUUsYUFBUSxHQUF5QixJQUFJLHVCQUF1QixDQUFJLElBQUksQ0FBQyxDQUFDO1FBRXRFLHlEQUF5RDtRQUN6RCxjQUFTLEdBQVksSUFBSSxDQUFDO1FBRTFCLDREQUE0RDtRQUM1RCxtQkFBYyxHQUFZLElBQUksQ0FBQztRQUUvQiwrREFBK0Q7UUFDL0Qsc0JBQWlCLEdBQVksSUFBSSxDQUFDO1FBRWxDLHdDQUF3QztRQUMvQixXQUFNLEdBQUcsSUFBSSxlQUFlLENBQUksSUFBSSxDQUFDLENBQUM7UUFFL0MsdUNBQXVDO1FBQzlCLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBSSxJQUFJLENBQUMsQ0FBQztRQUVoRCwyREFBMkQ7UUFDbEQsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFNLEVBQUUsQ0FBQyxDQUFDO1FBS25ELGdEQUFnRDtRQUN4QyxhQUFRLEdBQXFCLEVBQUUsQ0FB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LElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVPLHFCQUFxQjtRQUN6QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0wsQ0FBQzsrR0EvUVEsZ0JBQWdCO21IQUFoQixnQkFBZ0I7OzRGQUFoQixnQkFBZ0I7a0JBRDVCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFJvd0FsdFNlbGVjdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9zdHJhdGVnaWVzL3Jvdy1hbHQtc2VsZWN0aW9uLnN0cmF0ZWd5JztcbmltcG9ydCB7IFJvd1NlbGVjdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9zdHJhdGVnaWVzL3Jvdy1zZWxlY3Rpb24uc3RyYXRlZ3knO1xuaW1wb3J0IHsgU2VsZWN0aW9uU3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvc2VsZWN0aW9uLnN0cmF0ZWd5JztcbmltcG9ydCB7IFNpbXBsZVNlbGVjdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9zdHJhdGVnaWVzL3NpbXBsZS1zZWxlY3Rpb24uc3RyYXRlZ3knO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgU2VsZWN0aW9uU2VydmljZTxUPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgICAvKiogU3RvcmUgdGhlIGN1cnJlbnQgc2V0IG9mIHNlbGVjdGFibGUgaXRlbXMgYW5kIGVuc3VyZSBhbiBpdGVtIGNhbiBiZSBmb2N1c2VkICovXG4gICAgc2V0IGRhdGFzZXQoZGF0YXNldDogUmVhZG9ubHlBcnJheTxUPikge1xuICAgICAgICB0aGlzLl9kYXRhc2V0ID0gZGF0YXNldDtcbiAgICAgICAgaWYgKHRoaXMuX2RhdGFzZXQuaW5kZXhPZih0aGlzLl9hY3RpdmUpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zZXRGaXJzdEl0ZW1Gb2N1c2FibGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBHZXQgdGhlIGN1cnJlbnQgc2V0IG9mIHNlbGVjdGFibGUgaXRlbXMgKi9cbiAgICBnZXQgZGF0YXNldCgpOiBSZWFkb25seUFycmF5PFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGFzZXQ7XG4gICAgfVxuXG4gICAgLyoqIFRoZSBhY3RpdmUgc2VsZWN0aW9uIHN0cmF0ZWd5IHRoYXQgZGVmaW5lcyBob3cgc2VsZWN0aW9ucyBjYW4gYmUgbWFkZSAqL1xuICAgIHN0cmF0ZWd5OiBTZWxlY3Rpb25TdHJhdGVneTxUPiA9IG5ldyBTaW1wbGVTZWxlY3Rpb25TdHJhdGVneTxUPih0aGlzKTtcblxuICAgIC8qKiBEZWZpbmUgaWYgc2VsZWN0aW9ucyBjYW4gYmUgcGVyZm9ybWVkIG9uIGFueSBpdGVtcyAqL1xuICAgIGlzRW5hYmxlZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogRGVmaW5lIGlmIHRoZSBtb3VzZSBjYW4gYmUgdXNlZCB0byBwZXJmb3JtIHNlbGVjdGlvbnMgKi9cbiAgICBpc0NsaWNrRW5hYmxlZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogRGVmaW5lIGlmIHRoZSBrZXlib2FyZCBjYW4gYmUgdXNlZCB0byBwZXJmb3JtIHNlbGVjdGlvbnMgKi9cbiAgICBpc0tleWJvYXJkRW5hYmxlZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogRGVmaW5lIHRoZSBjdXJyZW50bHkgZm9jdXNlZCBpdGVtICovXG4gICAgcmVhZG9ubHkgZm9jdXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUPihudWxsKTtcblxuICAgIC8qKiBEZWZpbmUgdGhlIGN1cnJlbnRseSBhY3RpdmUgaXRlbSAqL1xuICAgIHJlYWRvbmx5IGFjdGl2ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFQ+KG51bGwpO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBjdXJyZW50IGxpc3Qgb2Ygc2VsZWN0ZWQgaXRlbXMgYXMgYW4gYXJyYXkgKi9cbiAgICByZWFkb25seSBzZWxlY3Rpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUW10+KFtdKTtcblxuICAgIC8qKiBTdG9yZSB0aGUgYWN0aXZlIGl0ZW0gKi9cbiAgICBwcml2YXRlIF9hY3RpdmU6IFQ7XG5cbiAgICAvKiogU3RvcmUgdGhlIGN1cnJlbnQgc2V0IG9mIHNlbGVjdGFibGUgaXRlbXMgKi9cbiAgICBwcml2YXRlIF9kYXRhc2V0OiBSZWFkb25seUFycmF5PFQ+ID0gW107XG5cbiAgICAvKiogU3RvcmUgdGhlIHNlbGVjdGlvbiBzdHJhdGVneSB0aGF0IHNob3VsZCBiZSBkZXN0cm95ZWQgKi9cbiAgICBwcml2YXRlIF9zdHJhdGVneVRvRGVzdHJveTogU2VsZWN0aW9uU3RyYXRlZ3k8VD4gPSB0aGlzLnN0cmF0ZWd5O1xuXG4gICAgLyoqIFN0b3JlIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbiBhIHNldCAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3NlbGVjdGlvbiA9IG5ldyBTZXQ8VD4oKTtcblxuICAgIC8qKiBTdG9yZSB0aGUgY3VycmVudCBkaXNhYmxlZCBpdGVtcyBpbiBhIHNldCAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Rpc2FibGVkID0gbmV3IFNldDxUPigpO1xuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIC8vIGRlc3Ryb3kgdGhlIGFjdGl2ZSBzdHJhdGVneVxuICAgICAgICBpZiAodGhpcy5fc3RyYXRlZ3lUb0Rlc3Ryb3kpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0cmF0ZWd5VG9EZXN0cm95LmRlc3Ryb3koKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvbXBsZXRlIGFsbCBvYnNlcnZhYmxlc1xuICAgICAgICB0aGlzLmZvY3VzJC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLmFjdGl2ZSQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24kLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdGhlIGl0ZW0gaXMgbm90IGN1cnJlbnRseSBzZWxlY3RlZCB0aGVuIGFkZCBpdFxuICAgICAqIHRvIHRoZSBsaXN0IG9mIHNlbGVjdGVkIGl0ZW1zXG4gICAgICovXG4gICAgc2VsZWN0KC4uLnNlbGVjdGlvbnM6IFRbXSk6IHZvaWQge1xuXG4gICAgICAgIC8vIGZpbHRlciBvdXQgYW55IGRpc2FibGVkIGl0ZW1zXG4gICAgICAgIHNlbGVjdGlvbnMgPSBzZWxlY3Rpb25zLmZpbHRlcihpdGVtID0+ICF0aGlzLl9kaXNhYmxlZC5oYXMoaXRlbSkpO1xuXG4gICAgICAgIC8vIGFkZCBlYWNoIHNlbGVjdGlvbiB0byB0aGUgc2V0XG4gICAgICAgIHNlbGVjdGlvbnMuZm9yRWFjaChzZWxlY3Rpb24gPT4gdGhpcy5fc2VsZWN0aW9uLmFkZChzZWxlY3Rpb24pKTtcblxuICAgICAgICAvLyBwcm9wYWdhdGUgdGhlIGNoYW5nZXNcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25IYXNNdXRhdGVkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVzZWxlY3QgYWxsIGN1cnJlbnRseSBzZWxlY3RlZCBpdGVtcyBhbmQgcmVwbGFjZSB3aXRoIGEgbmV3IHNlbGVjdGlvblxuICAgICAqL1xuICAgIHNlbGVjdE9ubHkoLi4uc2VsZWN0aW9uOiBUW10pOiB2b2lkIHtcblxuICAgICAgICAvLyBmaWx0ZXIgb3V0IGFueSBkaXNhYmxlZCBpdGVtc1xuICAgICAgICBzZWxlY3Rpb24gPSBzZWxlY3Rpb24uZmlsdGVyKGl0ZW0gPT4gIXRoaXMuX2Rpc2FibGVkLmhhcyhpdGVtKSk7XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbXNcbiAgICAgICAgdGhpcy5fc2VsZWN0aW9uLmNsZWFyKCk7XG5cbiAgICAgICAgLy8gc2VsZWN0IG9ubHkgdGhlIHNwZWNpZmllZCBpdGVtXG4gICAgICAgIHNlbGVjdGlvbi5mb3JFYWNoKGl0ZW0gPT4gdGhpcy5fc2VsZWN0aW9uLmFkZChpdGVtKSk7XG5cbiAgICAgICAgLy8gZW1pdCB0aGUgY2hhbmdlc1xuICAgICAgICB0aGlzLnNlbGVjdGlvbkhhc011dGF0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYW4gaXRlbSBmcm9tIHRoZSBsaXN0IG9mIHNlbGVjdGVkIGl0ZW1zXG4gICAgICovXG4gICAgZGVzZWxlY3QoLi4uc2VsZWN0aW9uczogVFtdKTogdm9pZCB7XG5cbiAgICAgICAgLy8gcmVtb3ZlIGVhY2ggaXRlbSBmcm9tIHRoZSBzZXRcbiAgICAgICAgc2VsZWN0aW9ucy5mb3JFYWNoKHNlbGVjdGlvbiA9PiB0aGlzLl9zZWxlY3Rpb24uZGVsZXRlKHNlbGVjdGlvbikpO1xuXG4gICAgICAgIC8vIHByb3BhZ2F0ZSB0aGUgY2hhbmdlc1xuICAgICAgICB0aGlzLnNlbGVjdGlvbkhhc011dGF0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYWxsIGl0ZW1zIGZyb20gdGhlIGxpc3Qgb2Ygc2VsZWN0ZWQgaXRlbXNcbiAgICAgKi9cbiAgICBkZXNlbGVjdEFsbCgpOiB2b2lkIHtcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBpdGVtcyBpbiB0aGUgYXJyYXlcbiAgICAgICAgdGhpcy5kZXNlbGVjdCguLi50aGlzLl9kYXRhc2V0KTtcblxuICAgICAgICAvLyBjbGVhciB0aGUgc2V0IGluIGNhc2UgYW55IGl0ZW1zIGhhdmUgYmVlbiByZW1vdmVkIGZyb20gdGhlIERPTSBidXQgYXJlIHN0aWxsIHNlbGVjdGVkXG4gICAgICAgIHRoaXMuX3NlbGVjdGlvbi5jbGVhcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZSB0aGUgc2VsZWN0ZWQgc3RhdGUgb2YgYW55IHNwZWNpZmllZCBpdGVtc1xuICAgICAqL1xuICAgIHRvZ2dsZSguLi5zZWxlY3Rpb25zOiBUW10pOiB2b2lkIHtcbiAgICAgICAgc2VsZWN0aW9ucy5mb3JFYWNoKHNlbGVjdGlvbiA9PiB0aGlzLmlzU2VsZWN0ZWQoc2VsZWN0aW9uKSA/IHRoaXMuZGVzZWxlY3Qoc2VsZWN0aW9uKSA6IHRoaXMuc2VsZWN0KHNlbGVjdGlvbikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCBhIHNwZWNpZmljIGl0ZW0gaXMgY3VycmVudGx5IHNlbGVjdGVkXG4gICAgICovXG4gICAgaXNTZWxlY3RlZChkYXRhOiBUKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb24uaGFzKGRhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybiBhbiBvYnNlcnZhYmxlIHNwZWNpZmljYWxseSBmb3Igbm90aWZ5aW5nIHRoZSBzdWJzY3JpYmVyXG4gICAgICogb25seSB3aGVuIHRoZSBzZWxlY3Rpb24gc3RhdGUgb2YgYSBzcGVjaWZpYyBvYmplY3QgaGFzIGNoYW5nZWRcbiAgICAgKi9cbiAgICBnZXRTZWxlY3Rpb25TdGF0ZShkYXRhOiBUKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbiQucGlwZShtYXAoKCkgPT4gdGhpcy5pc1NlbGVjdGVkKGRhdGEpKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmaW5lIGhvdyBzZWxlY3Rpb25zIHNob3VsZCBiZSBwZXJmb3JtZWQuXG4gICAgICogVGhpcyBhbGxvd3MgdXMgdG8gdXNlIGFuIHN0cmF0ZWd5IHBhdHRlcm4gdG8gaGFuZGxlIHRoZSB2YXJpb3VzIGtleWJvYXJkXG4gICAgICogYW5kIG1vdXNlIGludGVyYWN0aW9ucyB3aGlsZSBrZWVwaW5nIGVhY2ggbW9kZSBzZXBhcmF0ZWQgYW5kXG4gICAgICogZWFzaWx5IGV4dGVuc2libGUgaWYgd2Ugd2FudCB0byBhZGQgbW9yZSBtb2RlcyBpbiBmdXR1cmUhXG4gICAgICovXG4gICAgc2V0U3RyYXRlZ3kobW9kZTogU2VsZWN0aW9uTW9kZSB8IFNlbGVjdGlvblN0cmF0ZWd5PFQ+KTogdm9pZCB7XG5cbiAgICAgICAgaWYgKHRoaXMuX3N0cmF0ZWd5VG9EZXN0cm95KSB7XG4gICAgICAgICAgICAvLyBEZXN0cm95IHByZXZpb3VzIHN0cmF0ZWd5IGlmIGl0IHdhcyBjcmVhdGVkIGludGVybmFsbHlcbiAgICAgICAgICAgIHRoaXMuX3N0cmF0ZWd5VG9EZXN0cm95LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX3N0cmF0ZWd5VG9EZXN0cm95ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb2RlIGluc3RhbmNlb2YgU2VsZWN0aW9uU3RyYXRlZ3kpIHtcblxuICAgICAgICAgICAgLy8gQ3VzdG9tIHN0cmF0ZWd5IC0gcGFzcyBpbiB0aGUgc2VydmljZSBpbnN0YW5jZVxuICAgICAgICAgICAgdGhpcy5zdHJhdGVneSA9IG1vZGU7XG4gICAgICAgICAgICB0aGlzLnN0cmF0ZWd5LnNldFNlbGVjdGlvblNlcnZpY2UodGhpcyk7XG5cbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgc3dpdGNoIChtb2RlLnRvTG93ZXJDYXNlKCkudHJpbSgpKSB7XG5cbiAgICAgICAgICAgICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gdGhpcy5fc3RyYXRlZ3lUb0Rlc3Ryb3kgPSBuZXcgU2ltcGxlU2VsZWN0aW9uU3RyYXRlZ3k8VD4odGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAncm93JzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJhdGVneSA9IHRoaXMuX3N0cmF0ZWd5VG9EZXN0cm95ID0gbmV3IFJvd1NlbGVjdGlvblN0cmF0ZWd5PFQ+KHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgJ3Jvdy1hbHQnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gdGhpcy5fc3RyYXRlZ3lUb0Rlc3Ryb3kgPSBuZXcgUm93QWx0U2VsZWN0aW9uU3RyYXRlZ3k8VD4odGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc2VsZWN0aW9uIG1vZGUgJyR7bW9kZX0nIGRvZXMgbm90IGV4aXN0LiBWYWxpZCBtb2RlcyBhcmUgJ3NpbXBsZScsICdyb3cnLCBvciAncm93LWFsdCcuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGN1cnJlbnQgYWN0aXZlIGl0ZW1cbiAgICAgKi9cbiAgICBhY3RpdmF0ZShkYXRhOiBUKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IGRhdGE7XG4gICAgICAgIHRoaXMuYWN0aXZlJC5uZXh0KHRoaXMuX2FjdGl2ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVhY3RpdmUgYWxsIGl0ZW1zXG4gICAgICovXG4gICAgZGVhY3RpdmF0ZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gbnVsbDtcbiAgICAgICAgdGhpcy5hY3RpdmUkLm5leHQodGhpcy5fYWN0aXZlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIG5leHQgb3IgcHJldmlvdXMgc2libGluZyBvZiB0aGUgY3VycmVudCBhY3RpdmUgaXRlbS5cbiAgICAgKiBAcGFyYW0gcHJldmlvdXMgSWYgdHJ1ZSwgdGhlIHByZXZpb3VzIHNpYmxpbmcgd2lsbCBiZSByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBnZXRTaWJsaW5nKHByZXZpb3VzOiBib29sZWFuID0gZmFsc2UpOiBUIHtcblxuICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIGN1cnJlbnQgYWN0aXZlIGl0ZW1cbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGdldCB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgaXRlbVxuICAgICAgICBjb25zdCBpZHggPSB0aGlzLmRhdGFzZXQuaW5kZXhPZih0aGlzLl9hY3RpdmUpO1xuICAgICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmRhdGFzZXRbcHJldmlvdXMgPyBpZHggLSAxIDogaWR4ICsgMV07XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZSB0aGUgc2libGluZyBvZiB0aGUgY3VycmVudCBhY3RpdmUgaXRlbS5cbiAgICAgKiBJZiBwcmV2aW91cyBpcyBzZXQgdG8gdHJ1ZSB0aGUgcHJldmlvdXMgc2libGluZyB3aWxsIGJlIGFjdGl2YXRlZFxuICAgICAqIHJhdGhlciB0aGFuIHRoZSBuZXh0IHNpYmxpbmcuIFRoaXMgZnVuY3Rpb24gd2lsbCBhbHNvIHJldHVybiB0aGVcbiAgICAgKiBkYXRhIG9mIHRoZSBuZXdseSBhY3RpdmF0ZWQgc2libGluZ1xuICAgICAqL1xuICAgIGFjdGl2YXRlU2libGluZyhwcmV2aW91czogYm9vbGVhbiA9IGZhbHNlKTogVCB7XG5cbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5nZXRTaWJsaW5nKHByZXZpb3VzKTtcblxuICAgICAgICAvLyBjaGVjayBpZiB0aGUgdGFyZ2V0IGV4aXN0c1xuICAgICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlKHRhcmdldCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHNldERpc2FibGVkKGRpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIC8vIHN0b3JlIHRoZSBjdXJyZW50IGRpc2FibGVkIHN0YXRlXG4gICAgICAgIHRoaXMuaXNFbmFibGVkID0gIWRpc2FibGVkO1xuXG4gICAgICAgIC8vIGNsZWFyIGFueSBzdGF0ZWZ1bCBkYXRhXG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuYWN0aXZlJC5uZXh0KHRoaXMuX2FjdGl2ZSk7XG4gICAgICAgIHRoaXMuX3NlbGVjdGlvbi5jbGVhcigpO1xuXG4gICAgICAgIC8vIGVtaXQgdGhlIHNlbGVjdGlvbiBjaGFuZ2UgaW5mb3JtYXRpb25cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25IYXNNdXRhdGVkKCk7XG4gICAgfVxuXG4gICAgLyoqIFN0b3JlIHRoZSBkaXNhYmxlZCBzdGF0ZSBvZiBhbiBpdGVtICovXG4gICAgc2V0SXRlbURpc2FibGVkKGl0ZW06IFQsIGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcblxuICAgICAgICAvLyB1cGRhdGUgdGhlIGludGVybmFsIGxpc3Qgb2YgZGlzYWJsZWQgaXRlbXNcbiAgICAgICAgaWYgKGlzRGlzYWJsZWQgJiYgIXRoaXMuX2Rpc2FibGVkLmhhcyhpdGVtKSkge1xuICAgICAgICAgICAgdGhpcy5fZGlzYWJsZWQuYWRkKGl0ZW0pO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc0Rpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9kaXNhYmxlZC5kZWxldGUoaXRlbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbGVjdGlvbkhhc011dGF0ZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uJC5uZXh0KEFycmF5LmZyb20odGhpcy5fc2VsZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRGaXJzdEl0ZW1Gb2N1c2FibGUoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9kYXRhc2V0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXMkLm5leHQodGhpcy5fZGF0YXNldFswXSk7XG4gICAgICAgICAgICB0aGlzLl9hY3RpdmUgPSB0aGlzLl9kYXRhc2V0WzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHR5cGUgU2VsZWN0aW9uTW9kZSA9ICdzaW1wbGUnIHwgJ3JvdycgfCAncm93LWFsdCc7Il19