UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

441 lines 46.1 kB
import { __decorate, __extends, __metadata, __param, __read, __spread } from "tslib"; import { CommonModule } from '@angular/common'; import { AfterContentInit, AfterViewInit, Component, ContentChildren, ChangeDetectorRef, EventEmitter, HostBinding, Inject, Input, NgModule, Output, Optional, QueryList, Renderer2, ViewChildren, OnDestroy } from '@angular/core'; import { Subject } from 'rxjs'; import { IgxButtonDirective, IgxButtonModule } from '../directives/button/button.directive'; import { IgxRippleModule } from '../directives/ripple/ripple.directive'; import { IgxIconModule } from '../icon/index'; import { takeUntil } from 'rxjs/operators'; import { DisplayDensityBase, DisplayDensityToken } from '../core/density'; export var ButtonGroupAlignment; (function (ButtonGroupAlignment) { ButtonGroupAlignment[ButtonGroupAlignment["horizontal"] = 0] = "horizontal"; ButtonGroupAlignment[ButtonGroupAlignment["vertical"] = 1] = "vertical"; })(ButtonGroupAlignment || (ButtonGroupAlignment = {})); var NEXT_ID = 0; /** * **Ignite UI for Angular Button Group** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/buttongroup.html) * * The Ignite UI Button Group displays a group of buttons either vertically or horizontally. The group supports * single, multiple and toggle selection. * * Example: * ```html * <igx-buttongroup multiSelection="true" [values]="fontOptions"> * </igx-buttongroup> * ``` * The `fontOptions` value shown above is defined as: * ```typescript * this.fontOptions = [ * { icon: 'format_bold', selected: false }, * { icon: 'format_italic', selected: false }, * { icon: 'format_underlined', selected: false }]; * ``` */ var IgxButtonGroupComponent = /** @class */ (function (_super) { __extends(IgxButtonGroupComponent, _super); function IgxButtonGroupComponent(_cdr, _renderer, _displayDensityOptions) { var _this = _super.call(this, _displayDensityOptions) || this; _this._cdr = _cdr; _this._renderer = _renderer; _this._displayDensityOptions = _displayDensityOptions; _this._disabled = false; _this.buttonClickNotifier$ = new Subject(); _this.queryListNotifier$ = new Subject(); /** * An @Input property that sets the value of the `id` attribute. If not set it will be automatically generated. * ```html * <igx-buttongroup [id]="'igx-dialog-56'" [multiSelection]="!multi" [values]="alignOptions"> * ``` */ _this.id = "igx-buttongroup-" + NEXT_ID++; /** * @hidden */ _this.zIndex = 0; /** * An @Input property that enables selecting multiple buttons. By default, multi-selection is false. * ```html * <igx-buttongroup [multiSelection]="false" [alignment]="alignment"></igx-buttongroup> * ``` */ _this.multiSelection = false; /** * @hidden */ _this.selectedIndexes = []; /** * An @Ouput property that emits an event when a button is selected. *```typescript *@ViewChild("toast") *private toast: IgxToastComponent; *public onSelect(buttongroup){ * this.toast.show() *} * //... *``` *```html * <igx-buttongroup #MyChild [multiSelection]="!multi" (onSelect)="onSelect($event)"></igx-buttongroup> *<igx-toast #toast message="You have made a selection!"></igx-toast> *``` */ _this.onSelect = new EventEmitter(); /** * An @Ouput property that emits an event when a button is deselected. *```typescript *@ViewChild("toast") *private toast: IgxToastComponent; *public onUnselect(buttongroup){ * this.toast.show() *} * //... *``` *```html * igx-buttongroup #MyChild [multiSelection]="multi" (onUnselect)="onUnselect($event)"></igx-buttongroup> *<igx-toast #toast message="You have deselected a button!"></igx-toast> *``` */ _this.onUnselect = new EventEmitter(); return _this; } Object.defineProperty(IgxButtonGroupComponent.prototype, "buttons", { /** * A collection containing all buttons inside the button group. */ get: function () { return __spread(this.viewButtons.toArray(), this.templateButtons.toArray()); }, enumerable: true, configurable: true }); Object.defineProperty(IgxButtonGroupComponent.prototype, "itemContentCssClass", { /** * Returns the CSS class of the item content of the `IgxButtonGroup`. *```typescript *@ViewChild("MyChild") *public buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * let buttonSelect = this.buttonG.itemContentCssClass; *} *``` */ get: function () { return this._itemContentCssClass; }, /** * Allows you to set a style using the `itemContentCssClass` input. * The value should be the CSS class name that will be applied to the button group. *```typescript *public style1 = "styleClass"; * //.. *``` * ```html *<igx-buttongroup [itemContentCssClass]="style1" [multiSelection]="!multi" [values]="alignOptions"> *``` */ set: function (value) { this._itemContentCssClass = value || this._itemContentCssClass; }, enumerable: true, configurable: true }); Object.defineProperty(IgxButtonGroupComponent.prototype, "disabled", { /** * An @Input property that allows you to disable the `igx-buttongroup` component. By default it's false. * ```html * <igx-buttongroup [disabled]="true" [multiSelection]="multi" [values]="fontOptions"></igx-buttongroup> * ``` */ get: function () { return this._disabled; }, set: function (value) { var _this = this; if (this._disabled !== value) { this._disabled = value; if (this.viewButtons && this.templateButtons) { this.buttons.forEach(function (b) { return b.disabled = _this._disabled; }); } } }, enumerable: true, configurable: true }); Object.defineProperty(IgxButtonGroupComponent.prototype, "alignment", { /** * Returns the alignment of the `igx-buttongroup`. *```typescript *@ViewChild("MyChild") *public buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * let buttonAlignment = this.buttonG.alignment; *} *``` */ get: function () { return this._isVertical ? ButtonGroupAlignment.vertical : ButtonGroupAlignment.horizontal; }, /** * Allows you to set the button group alignment. * Available options are `ButtonGroupAlignment.horizontal` (default) and `ButtonGroupAlignment.vertical`. * ```typescript *public alignment = ButtonGroupAlignment.vertical; * //.. * ``` * ```html *<igx-buttongroup [multiSelection]="false" [values]="cities" [alignment]="alignment"></igx-buttongroup> * ``` */ set: function (value) { this._isVertical = value === ButtonGroupAlignment.vertical; }, enumerable: true, configurable: true }); Object.defineProperty(IgxButtonGroupComponent.prototype, "isVertical", { /** * Returns true if the `igx-buttongroup` alignment is vertical. * Note that in order for the accessor to work correctly the property should be set explicitly. * ```html * <igx-buttongroup #MyChild [alignment]="alignment" [values]="alignOptions"> * ``` * ```typescript * //... *@ViewChild("MyChild") *private buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * let orientation = this.buttonG.isVertical; *} *``` */ get: function () { return this._isVertical; }, enumerable: true, configurable: true }); Object.defineProperty(IgxButtonGroupComponent.prototype, "selectedButtons", { /** * Gets the selected button/buttons. *```typescript *@ViewChild("MyChild") *private buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * let selectedButton = this.buttonG.selectedButtons; *} *``` */ get: function () { var _this = this; return this.buttons.filter(function (b, i) { return _this.selectedIndexes.indexOf(i) !== -1; }); }, enumerable: true, configurable: true }); /** * Selects a button by its index. *```typescript *@ViewChild("MyChild") *private buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * this.buttonG.selectButton(2); * this.cdr.detectChanges(); *} *``` * @memberOf {@link IgxButtonGroupComponent} */ IgxButtonGroupComponent.prototype.selectButton = function (index) { var _this = this; if (index >= this.buttons.length || index < 0) { return; } var button = this.buttons[index]; var buttonElement = button.nativeElement; this.selectedIndexes.push(index); button.selected = true; this._renderer.setAttribute(buttonElement, 'aria-pressed', 'true'); this._renderer.addClass(buttonElement, 'igx-button-group__item--selected'); this.onSelect.emit({ button: button, index: index }); var indexInViewButtons = this.viewButtons.toArray().indexOf(button); if (indexInViewButtons !== -1) { this.values[indexInViewButtons].selected = true; } // deselect other buttons if multiSelection is not enabled if (!this.multiSelection && this.selectedIndexes.length > 1) { this.buttons.forEach(function (b, i) { if (i !== index && _this.selectedIndexes.indexOf(i) !== -1) { _this.deselectButton(i); } }); } }; /** * Deselects a button by its index. * ```typescript *@ViewChild("MyChild") *private buttonG: IgxButtonGroupComponent; *ngAfterViewInit(){ * this.buttonG.deselectButton(2); * this.cdr.detectChanges(); *} * ``` * @memberOf {@link IgxButtonGroupComponent} */ IgxButtonGroupComponent.prototype.deselectButton = function (index) { if (index >= this.buttons.length || index < 0) { return; } var button = this.buttons[index]; var buttonElement = button.nativeElement; this.selectedIndexes.splice(this.selectedIndexes.indexOf(index), 1); button.selected = false; this._renderer.setAttribute(buttonElement, 'aria-pressed', 'false'); this._renderer.removeClass(buttonElement, 'igx-button-group__item--selected'); this.onUnselect.emit({ button: button, index: index }); var indexInViewButtons = this.viewButtons.toArray().indexOf(button); if (indexInViewButtons !== -1) { this.values[indexInViewButtons].selected = false; } }; /** * @hidden */ IgxButtonGroupComponent.prototype.ngAfterContentInit = function () { var _this = this; this.templateButtons.forEach(function (button) { if (!button.initialDensity) { button.displayDensity = _this.displayDensity; } }); }; /** * @hidden */ IgxButtonGroupComponent.prototype.ngAfterViewInit = function () { var _this = this; var initButtons = function () { // Cancel any existing buttonClick subscriptions _this.buttonClickNotifier$.next(); _this.selectedIndexes.splice(0, _this.selectedIndexes.length); // initial configuration _this.buttons.forEach(function (button, index) { var buttonElement = button.nativeElement; if (_this.disabled) { button.disabled = true; } if (button.selected) { _this.selectButton(index); } button.buttonClick.pipe(takeUntil(_this.buttonClickNotifier$)).subscribe(function (ev) { return _this._clickHandler(ev, index); }); _this._renderer.addClass(buttonElement, 'igx-button-group__item'); }); }; this.viewButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(function () { return initButtons(); }); this.templateButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(function () { return initButtons(); }); initButtons(); this._cdr.detectChanges(); }; /** * @hidden */ IgxButtonGroupComponent.prototype.ngOnDestroy = function () { this.buttonClickNotifier$.next(); this.buttonClickNotifier$.complete(); this.queryListNotifier$.next(); this.queryListNotifier$.complete(); }; /** *@hidden */ IgxButtonGroupComponent.prototype._clickHandler = function (event, i) { if (this.selectedIndexes.indexOf(i) !== -1) { this.deselectButton(i); } else { this.selectButton(i); } }; IgxButtonGroupComponent.ctorParameters = function () { return [ { type: ChangeDetectorRef }, { type: Renderer2 }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] } ]; }; __decorate([ ViewChildren(IgxButtonDirective), __metadata("design:type", QueryList) ], IgxButtonGroupComponent.prototype, "viewButtons", void 0); __decorate([ ContentChildren(IgxButtonDirective), __metadata("design:type", QueryList) ], IgxButtonGroupComponent.prototype, "templateButtons", void 0); __decorate([ HostBinding('attr.id'), Input(), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "id", void 0); __decorate([ HostBinding('style.zIndex'), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "zIndex", void 0); __decorate([ Input(), __metadata("design:type", String), __metadata("design:paramtypes", [String]) ], IgxButtonGroupComponent.prototype, "itemContentCssClass", null); __decorate([ Input(), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "multiSelection", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "values", void 0); __decorate([ Input(), __metadata("design:type", Boolean), __metadata("design:paramtypes", [Boolean]) ], IgxButtonGroupComponent.prototype, "disabled", null); __decorate([ Input(), __metadata("design:type", Number), __metadata("design:paramtypes", [Number]) ], IgxButtonGroupComponent.prototype, "alignment", null); __decorate([ Output(), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "onSelect", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxButtonGroupComponent.prototype, "onUnselect", void 0); IgxButtonGroupComponent = __decorate([ Component({ selector: 'igx-buttongroup', template: "<div class=\"igx-button-group\" role=\"group\" [class.igx-button-group--vertical]=\"isVertical\">\n <button *ngFor=\"let button of values; let i = 'index'\"\n type=\"button\"\n igxButton=\"flat\"\n [displayDensity]=\"displayDensity\"\n [selected]=\"button.selected\"\n [attr.data-togglable]=\"button.togglable\"\n [disabled]=\"disabled || button.disabled\"\n [igxButtonColor]=\"button.color\"\n [igxButtonBackground]=\"button.bgcolor\"\n [igxLabel]=\"button.label\"\n [igxRipple]=\"button.ripple\"\n >\n <div class=\"igx-button-group__item-content {{ itemContentCssClass }}\">\n <igx-icon *ngIf=\"button.icon\" fontSet=\"material\">{{button.icon}}</igx-icon>\n <span *ngIf=\"button.label\">{{button.label}}</span>\n </div>\n </button>\n <ng-content></ng-content>\n</div>\n" }), __param(2, Optional()), __param(2, Inject(DisplayDensityToken)), __metadata("design:paramtypes", [ChangeDetectorRef, Renderer2, Object]) ], IgxButtonGroupComponent); return IgxButtonGroupComponent; }(DisplayDensityBase)); export { IgxButtonGroupComponent }; /** * @hidden */ var IgxButtonGroupModule = /** @class */ (function () { function IgxButtonGroupModule() { } IgxButtonGroupModule = __decorate([ NgModule({ declarations: [IgxButtonGroupComponent], exports: [IgxButtonGroupComponent], imports: [IgxButtonModule, CommonModule, IgxRippleModule, IgxIconModule] }) ], IgxButtonGroupModule); return IgxButtonGroupModule; }()); export { IgxButtonGroupModule }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uR3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9idXR0b25Hcm91cC9idXR0b25Hcm91cC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFDYixTQUFTLEVBQ1QsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osV0FBVyxFQUNYLE1BQU0sRUFDTixLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxFQUNULFNBQVMsRUFDVCxZQUFZLEVBQ1osU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFHbEcsTUFBTSxDQUFOLElBQVksb0JBQTZDO0FBQXpELFdBQVksb0JBQW9CO0lBQUcsMkVBQVUsQ0FBQTtJQUFFLHVFQUFRLENBQUE7QUFBQyxDQUFDLEVBQTdDLG9CQUFvQixLQUFwQixvQkFBb0IsUUFBeUI7QUFDekQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBRWhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBTUg7SUFBNkMsMkNBQWtCO0lBMk0zRCxpQ0FBb0IsSUFB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LEVBQUUsYUFBYSxDQUFDO1NBQzNFLENBQUM7T0FFVyxvQkFBb0IsQ0FDaEM7SUFBRCwyQkFBQztDQUFBLEFBREQsSUFDQztTQURZLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgQWZ0ZXJWaWV3SW5pdCxcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkcmVuLFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgTmdNb2R1bGUsXG4gICAgT3V0cHV0LFxuICAgIE9wdGlvbmFsLFxuICAgIFF1ZXJ5TGlzdCxcbiAgICBSZW5kZXJlcjIsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIE9uRGVzdHJveVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IElneEJ1dHRvbkRpcmVjdGl2ZSwgSWd4QnV0dG9uTW9kdWxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9idXR0b24vYnV0dG9uLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERpc3BsYXlEZW5zaXR5QmFzZSwgRGlzcGxheURlbnNpdHlUb2tlbiwgSURpc3BsYXlEZW5zaXR5T3B0aW9ucyB9IGZyb20gJy4uL2NvcmUvZGVuc2l0eSc7XG5pbXBvcnQgeyBJQmFzZUV2ZW50QXJncyB9IGZyb20gJy4uL2NvcmUvdXRpbHMnO1xuXG5leHBvcnQgZW51bSBCdXR0b25Hcm91cEFsaWdubWVudCB7IGhvcml6b250YWwsIHZlcnRpY2FsIH1cbmxldCBORVhUX0lEID0gMDtcblxuLyoqXG4gKiAqKklnbml0ZSBVSSBmb3IgQW5ndWxhciBCdXR0b24gR3JvdXAqKiAtXG4gKiBbRG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cuaW5mcmFnaXN0aWNzLmNvbS9wcm9kdWN0cy9pZ25pdGUtdWktYW5ndWxhci9hbmd1bGFyL2NvbXBvbmVudHMvYnV0dG9uZ3JvdXAuaHRtbClcbiAqXG4gKiBUaGUgSWduaXRlIFVJIEJ1dHRvbiBHcm91cCBkaXNwbGF5cyBhIGdyb3VwIG9mIGJ1dHRvbnMgZWl0aGVyIHZlcnRpY2FsbHkgb3IgaG9yaXpvbnRhbGx5LiAgVGhlIGdyb3VwIHN1cHBvcnRzXG4gKiBzaW5nbGUsIG11bHRpcGxlIGFuZCB0b2dnbGUgc2VsZWN0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBodG1sXG4gKiA8aWd4LWJ1dHRvbmdyb3VwIG11bHRpU2VsZWN0aW9uPVwidHJ1ZVwiIFt2YWx1ZXNdPVwiZm9udE9wdGlvbnNcIj5cbiAqIDwvaWd4LWJ1dHRvbmdyb3VwPlxuICogYGBgXG4gKiBUaGUgYGZvbnRPcHRpb25zYCB2YWx1ZSBzaG93biBhYm92ZSBpcyBkZWZpbmVkIGFzOlxuICogYGBgdHlwZXNjcmlwdFxuICogdGhpcy5mb250T3B0aW9ucyA9IFtcbiAqICAgeyBpY29uOiAnZm9ybWF0X2JvbGQnLCBzZWxlY3RlZDogZmFsc2UgfSxcbiAqICAgeyBpY29uOiAnZm9ybWF0X2l0YWxpYycsIHNlbGVjdGVkOiBmYWxzZSB9LFxuICogICB7IGljb246ICdmb3JtYXRfdW5kZXJsaW5lZCcsIHNlbGVjdGVkOiBmYWxzZSB9XTtcbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2lneC1idXR0b25ncm91cCcsXG4gICAgdGVtcGxhdGVVcmw6ICdidXR0b25ncm91cC1jb250ZW50LmNvbXBvbmVudC5odG1sJ1xufSlcblxuZXhwb3J0IGNsYXNzIElneEJ1dHRvbkdyb3VwQ29tcG9uZW50IGV4dGVuZHMgRGlzcGxheURlbnNpdHlCYXNlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIHByaXZhdGUgX2Rpc2FibGVkID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIGJ1dHRvbkNsaWNrTm90aWZpZXIkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgICBwcm90ZWN0ZWQgcXVlcnlMaXN0Tm90aWZpZXIkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcblxuICAgIEBWaWV3Q2hpbGRyZW4oSWd4QnV0dG9uRGlyZWN0aXZlKSBwcml2YXRlIHZpZXdCdXR0b25zOiBRdWVyeUxpc3Q8SWd4QnV0dG9uRGlyZWN0aXZlPjtcbiAgICBAQ29udGVudENoaWxkcmVuKElneEJ1dHRvbkRpcmVjdGl2ZSkgcHJpdmF0ZSB0ZW1wbGF0ZUJ1dHRvbnM6IFF1ZXJ5TGlzdDxJZ3hCdXR0b25EaXJlY3RpdmU+O1xuXG4gICAgLyoqXG4gICAgICogQSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgYWxsIGJ1dHRvbnMgaW5zaWRlIHRoZSBidXR0b24gZ3JvdXAuXG4gICAgICovXG4gICAgcHVibGljIGdldCBidXR0b25zKCk6IElneEJ1dHRvbkRpcmVjdGl2ZVtdIHtcbiAgICAgICAgcmV0dXJuIFsuLi50aGlzLnZpZXdCdXR0b25zLnRvQXJyYXkoKSwgLi4udGhpcy50ZW1wbGF0ZUJ1dHRvbnMudG9BcnJheSgpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBzZXRzIHRoZSB2YWx1ZSBvZiB0aGUgYGlkYCBhdHRyaWJ1dGUuIElmIG5vdCBzZXQgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogIDxpZ3gtYnV0dG9uZ3JvdXAgW2lkXT1cIidpZ3gtZGlhbG9nLTU2J1wiIFttdWx0aVNlbGVjdGlvbl09XCIhbXVsdGlcIiBbdmFsdWVzXT1cImFsaWduT3B0aW9uc1wiPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgaWQgPSBgaWd4LWJ1dHRvbmdyb3VwLSR7TkVYVF9JRCsrfWA7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdzdHlsZS56SW5kZXgnKVxuICAgIHB1YmxpYyB6SW5kZXggPSAwO1xuXG4gICAgLyoqXG4gICAgICogQWxsb3dzIHlvdSB0byBzZXQgYSBzdHlsZSB1c2luZyB0aGUgYGl0ZW1Db250ZW50Q3NzQ2xhc3NgIGlucHV0LlxuICAgICAqIFRoZSB2YWx1ZSBzaG91bGQgYmUgdGhlIENTUyBjbGFzcyBuYW1lIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBidXR0b24gZ3JvdXAuXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpwdWJsaWMgc3R5bGUxID0gXCJzdHlsZUNsYXNzXCI7XG4gICAgICogLy8uLlxuICAgICAqYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqPGlneC1idXR0b25ncm91cCBbaXRlbUNvbnRlbnRDc3NDbGFzc109XCJzdHlsZTFcIiBbbXVsdGlTZWxlY3Rpb25dPVwiIW11bHRpXCIgW3ZhbHVlc109XCJhbGlnbk9wdGlvbnNcIj5cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHNldCBpdGVtQ29udGVudENzc0NsYXNzKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5faXRlbUNvbnRlbnRDc3NDbGFzcyA9IHZhbHVlIHx8IHRoaXMuX2l0ZW1Db250ZW50Q3NzQ2xhc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQ1NTIGNsYXNzIG9mIHRoZSBpdGVtIGNvbnRlbnQgb2YgdGhlIGBJZ3hCdXR0b25Hcm91cGAuXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHVibGljIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICBsZXQgYnV0dG9uU2VsZWN0ID0gdGhpcy5idXR0b25HLml0ZW1Db250ZW50Q3NzQ2xhc3M7XG4gICAgICp9XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBnZXQgaXRlbUNvbnRlbnRDc3NDbGFzcygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5faXRlbUNvbnRlbnRDc3NDbGFzcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBlbmFibGVzIHNlbGVjdGluZyBtdWx0aXBsZSBidXR0b25zLiBCeSBkZWZhdWx0LCBtdWx0aS1zZWxlY3Rpb24gaXMgZmFsc2UuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtYnV0dG9uZ3JvdXAgW211bHRpU2VsZWN0aW9uXT1cImZhbHNlXCIgW2FsaWdubWVudF09XCJhbGlnbm1lbnRcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgbXVsdGlTZWxlY3Rpb24gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBhbGxvd3Mgc2V0dGluZyB0aGUgYnV0dG9ucyBpbiB0aGUgYnV0dG9uIGdyb3VwLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAgcHVibGljIG5nT25Jbml0KCkge1xuICAgICAqICAgICAgdGhpcy5jaXRpZXMgPSBbXG4gICAgICogICAgICAgIG5ldyBCdXR0b24oe1xuICAgICAqICAgICAgICAgIGxhYmVsOiBcIlNvZmlhXCJcbiAgICAgKiAgICAgIH0pLFxuICAgICAqICAgICAgICBuZXcgQnV0dG9uKHtcbiAgICAgKiAgICAgICAgICBsYWJlbDogXCJMb25kb25cIlxuICAgICAqICAgICAgfSksXG4gICAgICogICAgICAgIG5ldyBCdXR0b24oe1xuICAgICAqICAgICAgICAgIGxhYmVsOiBcIk5ldyBZb3JrXCIsXG4gICAgICogICAgICAgICAgc2VsZWN0ZWQ6IHRydWVcbiAgICAgKiAgICAgIH0pLFxuICAgICAqICAgICAgICBuZXcgQnV0dG9uKHtcbiAgICAgKiAgICAgICAgICBsYWJlbDogXCJUb2t5b1wiXG4gICAgICogICAgICB9KVxuICAgICAqICBdO1xuICAgICAqICB9XG4gICAgICogIC8vLi5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogIDxpZ3gtYnV0dG9uZ3JvdXAgW211bHRpU2VsZWN0aW9uXT1cImZhbHNlXCIgW3ZhbHVlc109XCJjaXRpZXNcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdmFsdWVzOiBhbnk7XG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoZSBgaWd4LWJ1dHRvbmdyb3VwYCBjb21wb25lbnQuIEJ5IGRlZmF1bHQgaXQncyBmYWxzZS5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1idXR0b25ncm91cCBbZGlzYWJsZWRdPVwidHJ1ZVwiIFttdWx0aVNlbGVjdGlvbl09XCJtdWx0aVwiIFt2YWx1ZXNdPVwiZm9udE9wdGlvbnNcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZDtcbiAgICB9XG4gICAgcHVibGljIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodGhpcy5fZGlzYWJsZWQgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9kaXNhYmxlZCA9IHZhbHVlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy52aWV3QnV0dG9ucyAmJiB0aGlzLnRlbXBsYXRlQnV0dG9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKChiKSA9PiBiLmRpc2FibGVkID0gdGhpcy5fZGlzYWJsZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzZWxlY3RlZEluZGV4ZXM6IG51bWJlcltdID0gW107XG5cbiAgICAvKipcbiAgICAgKiBBbGxvd3MgeW91IHRvIHNldCB0aGUgYnV0dG9uIGdyb3VwIGFsaWdubWVudC5cbiAgICAgKiBBdmFpbGFibGUgb3B0aW9ucyBhcmUgYEJ1dHRvbkdyb3VwQWxpZ25tZW50Lmhvcml6b250YWxgIChkZWZhdWx0KSBhbmQgYEJ1dHRvbkdyb3VwQWxpZ25tZW50LnZlcnRpY2FsYC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICpwdWJsaWMgYWxpZ25tZW50ID0gQnV0dG9uR3JvdXBBbGlnbm1lbnQudmVydGljYWw7XG4gICAgICogLy8uLlxuICAgICAqIGBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKjxpZ3gtYnV0dG9uZ3JvdXAgW211bHRpU2VsZWN0aW9uXT1cImZhbHNlXCIgW3ZhbHVlc109XCJjaXRpZXNcIiBbYWxpZ25tZW50XT1cImFsaWdubWVudFwiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHNldCBhbGlnbm1lbnQodmFsdWU6IEJ1dHRvbkdyb3VwQWxpZ25tZW50KSB7XG4gICAgICAgIHRoaXMuX2lzVmVydGljYWwgPSB2YWx1ZSA9PT0gQnV0dG9uR3JvdXBBbGlnbm1lbnQudmVydGljYWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGFsaWdubWVudCBvZiB0aGUgYGlneC1idXR0b25ncm91cGAuXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHVibGljIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICAgbGV0IGJ1dHRvbkFsaWdubWVudCA9IHRoaXMuYnV0dG9uRy5hbGlnbm1lbnQ7XG4gICAgICp9XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBnZXQgYWxpZ25tZW50KCk6IEJ1dHRvbkdyb3VwQWxpZ25tZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVmVydGljYWwgPyBCdXR0b25Hcm91cEFsaWdubWVudC52ZXJ0aWNhbCA6IEJ1dHRvbkdyb3VwQWxpZ25tZW50Lmhvcml6b250YWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW4gQE91cHV0IHByb3BlcnR5IHRoYXQgZW1pdHMgYW4gZXZlbnQgd2hlbiBhIGJ1dHRvbiBpcyBzZWxlY3RlZC5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJ0b2FzdFwiKVxuICAgICAqcHJpdmF0ZSB0b2FzdDogSWd4VG9hc3RDb21wb25lbnQ7XG4gICAgICpwdWJsaWMgb25TZWxlY3QoYnV0dG9uZ3JvdXApe1xuICAgICAqICAgIHRoaXMudG9hc3Quc2hvdygpXG4gICAgICp9XG4gICAgICogLy8uLi5cbiAgICAgKmBgYFxuICAgICAqYGBgaHRtbFxuICAgICAqIDxpZ3gtYnV0dG9uZ3JvdXAgI015Q2hpbGQgW211bHRpU2VsZWN0aW9uXT1cIiFtdWx0aVwiIChvblNlbGVjdCk9XCJvblNlbGVjdCgkZXZlbnQpXCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICo8aWd4LXRvYXN0ICN0b2FzdCBtZXNzYWdlPVwiWW91IGhhdmUgbWFkZSBhIHNlbGVjdGlvbiFcIj48L2lneC10b2FzdD5cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25TZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPElCdXR0b25Hcm91cEV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEFuIEBPdXB1dCBwcm9wZXJ0eSB0aGF0IGVtaXRzIGFuIGV2ZW50IHdoZW4gYSBidXR0b24gaXMgZGVzZWxlY3RlZC5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJ0b2FzdFwiKVxuICAgICAqcHJpdmF0ZSB0b2FzdDogSWd4VG9hc3RDb21wb25lbnQ7XG4gICAgICpwdWJsaWMgb25VbnNlbGVjdChidXR0b25ncm91cCl7XG4gICAgICogICAgdGhpcy50b2FzdC5zaG93KClcbiAgICAgKn1cbiAgICAgKiAvLy4uLlxuICAgICAqYGBgXG4gICAgICpgYGBodG1sXG4gICAgICogaWd4LWJ1dHRvbmdyb3VwICNNeUNoaWxkIFttdWx0aVNlbGVjdGlvbl09XCJtdWx0aVwiIChvblVuc2VsZWN0KT1cIm9uVW5zZWxlY3QoJGV2ZW50KVwiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqPGlneC10b2FzdCAjdG9hc3QgbWVzc2FnZT1cIllvdSBoYXZlIGRlc2VsZWN0ZWQgYSBidXR0b24hXCI+PC9pZ3gtdG9hc3Q+XG4gICAgICpgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIG9uVW5zZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPElCdXR0b25Hcm91cEV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYGlneC1idXR0b25ncm91cGAgYWxpZ25tZW50IGlzIHZlcnRpY2FsLlxuICAgICAqIE5vdGUgdGhhdCBpbiBvcmRlciBmb3IgdGhlIGFjY2Vzc29yIHRvIHdvcmsgY29ycmVjdGx5IHRoZSBwcm9wZXJ0eSBzaG91bGQgYmUgc2V0IGV4cGxpY2l0bHkuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtYnV0dG9uZ3JvdXAgI015Q2hpbGQgW2FsaWdubWVudF09XCJhbGlnbm1lbnRcIiBbdmFsdWVzXT1cImFsaWduT3B0aW9uc1wiPlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLy4uLlxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnByaXZhdGUgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICBsZXQgb3JpZW50YXRpb24gPSB0aGlzLmJ1dHRvbkcuaXNWZXJ0aWNhbDtcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgaXNWZXJ0aWNhbCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVmVydGljYWw7XG4gICAgfVxuICAgIHByaXZhdGUgX2lzVmVydGljYWw6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBfaXRlbUNvbnRlbnRDc3NDbGFzczogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChEaXNwbGF5RGVuc2l0eVRva2VuKSBwcm90ZWN0ZWQgX2Rpc3BsYXlEZW5zaXR5T3B0aW9uczogSURpc3BsYXlEZW5zaXR5T3B0aW9ucykge1xuICAgICAgICBzdXBlcihfZGlzcGxheURlbnNpdHlPcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzZWxlY3RlZCBidXR0b24vYnV0dG9ucy5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwcml2YXRlIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICAgbGV0IHNlbGVjdGVkQnV0dG9uID0gdGhpcy5idXR0b25HLnNlbGVjdGVkQnV0dG9ucztcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZEJ1dHRvbnMoKTogSWd4QnV0dG9uRGlyZWN0aXZlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5idXR0b25zLmZpbHRlcigoYiwgaSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmluZGV4T2YoaSkgIT09IC0xO1xuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdHMgYSBidXR0b24gYnkgaXRzIGluZGV4LlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnByaXZhdGUgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICB0aGlzLmJ1dHRvbkcuc2VsZWN0QnV0dG9uKDIpO1xuICAgICAqICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqIEBtZW1iZXJPZiB7QGxpbmsgSWd4QnV0dG9uR3JvdXBDb21wb25lbnR9XG4gICAgICovXG4gICAgcHVibGljIHNlbGVjdEJ1dHRvbihpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLmJ1dHRvbnMubGVuZ3RoIHx8IGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnV0dG9uID0gdGhpcy5idXR0b25zW2luZGV4XTtcbiAgICAgICAgY29uc3QgYnV0dG9uRWxlbWVudCA9IGJ1dHRvbi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgICBidXR0b24uc2VsZWN0ZWQgPSB0cnVlO1xuXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShidXR0b25FbGVtZW50LCAnYXJpYS1wcmVzc2VkJywgJ3RydWUnKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3MoYnV0dG9uRWxlbWVudCwgJ2lneC1idXR0b24tZ3JvdXBfX2l0ZW0tLXNlbGVjdGVkJyk7XG5cbiAgICAgICAgdGhpcy5vblNlbGVjdC5lbWl0KHsgYnV0dG9uOiBidXR0b24sIGluZGV4OiBpbmRleCB9KTtcblxuICAgICAgICBjb25zdCBpbmRleEluVmlld0J1dHRvbnMgPSB0aGlzLnZpZXdCdXR0b25zLnRvQXJyYXkoKS5pbmRleE9mKGJ1dHRvbik7XG4gICAgICAgIGlmIChpbmRleEluVmlld0J1dHRvbnMgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlc1tpbmRleEluVmlld0J1dHRvbnNdLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRlc2VsZWN0IG90aGVyIGJ1dHRvbnMgaWYgbXVsdGlTZWxlY3Rpb24gaXMgbm90IGVuYWJsZWRcbiAgICAgICAgaWYgKCF0aGlzLm11bHRpU2VsZWN0aW9uICYmIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKChiLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGkgIT09IGluZGV4ICYmIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmluZGV4T2YoaSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzZWxlY3RCdXR0b24oaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXNlbGVjdHMgYSBidXR0b24gYnkgaXRzIGluZGV4LlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwcml2YXRlIGJ1dHRvbkc6IElneEJ1dHRvbkdyb3VwQ29tcG9uZW50O1xuICAgICAqbmdBZnRlclZpZXdJbml0KCl7XG4gICAgICogICAgdGhpcy5idXR0b25HLmRlc2VsZWN0QnV0dG9uKDIpO1xuICAgICAqICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgKn1cbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyT2Yge0BsaW5rIElneEJ1dHRvbkdyb3VwQ29tcG9uZW50fVxuICAgICAqL1xuICAgIHB1YmxpYyBkZXNlbGVjdEJ1dHRvbihpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLmJ1dHRvbnMubGVuZ3RoIHx8IGluZGV4IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnV0dG9uID0gdGhpcy5idXR0b25zW2luZGV4XTtcbiAgICAgICAgY29uc3QgYnV0dG9uRWxlbWVudCA9IGJ1dHRvbi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleGVzLnNwbGljZSh0aGlzLnNlbGVjdGVkSW5kZXhlcy5pbmRleE9mKGluZGV4KSwgMSk7XG4gICAgICAgIGJ1dHRvbi5zZWxlY3RlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShidXR0b25FbGVtZW50LCAnYXJpYS1wcmVzc2VkJywgJ2ZhbHNlJyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZUNsYXNzKGJ1dHRvbkVsZW1lbnQsICdpZ3gtYnV0dG9uLWdyb3VwX19pdGVtLS1zZWxlY3RlZCcpO1xuXG4gICAgICAgIHRoaXMub25VbnNlbGVjdC5lbWl0KHsgYnV0dG9uOiBidXR0b24sIGluZGV4OiBpbmRleCB9KTtcblxuICAgICAgICBjb25zdCBpbmRleEluVmlld0J1dHRvbnMgPSB0aGlzLnZpZXdCdXR0b25zLnRvQXJyYXkoKS5pbmRleE9mKGJ1dHRvbik7XG4gICAgICAgIGlmIChpbmRleEluVmlld0J1dHRvbnMgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlc1tpbmRleEluVmlld0J1dHRvbnNdLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWJ1dHRvbi5pbml0aWFsRGVuc2l0eSkge1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5kaXNwbGF5RGVuc2l0eSA9IHRoaXMuZGlzcGxheURlbnNpdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBjb25zdCBpbml0QnV0dG9ucyA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIENhbmNlbCBhbnkgZXhpc3RpbmcgYnV0dG9uQ2xpY2sgc3Vic2NyaXB0aW9uc1xuICAgICAgICAgICAgdGhpcy5idXR0b25DbGlja05vdGlmaWVyJC5uZXh0KCk7XG5cbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleGVzLnNwbGljZSgwLCB0aGlzLnNlbGVjdGVkSW5kZXhlcy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBpbml0aWFsIGNvbmZpZ3VyYXRpb25cbiAgICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKChidXR0b24sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnV0dG9uRWxlbWVudCA9IGJ1dHRvbi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoYnV0dG9uLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0QnV0dG9uKGluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBidXR0b24uYnV0dG9uQ2xpY2sucGlwZSh0YWtlVW50aWwodGhpcy5idXR0b25DbGlja05vdGlmaWVyJCkpLnN1YnNjcmliZSgoZXYpID0+IHRoaXMuX2NsaWNrSGFuZGxlcihldiwgaW5kZXgpKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyhidXR0b25FbGVtZW50LCAnaWd4LWJ1dHRvbi1ncm91cF9faXRlbScpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy52aWV3QnV0dG9ucy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMucXVlcnlMaXN0Tm90aWZpZXIkKSkuc3Vic2NyaWJlKCgpID0+IGluaXRCdXR0b25zKCkpO1xuICAgICAgICB0aGlzLnRlbXBsYXRlQnV0dG9ucy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMucXVlcnlMaXN0Tm90aWZpZXIkKSkuc3Vic2NyaWJlKCgpID0+IGluaXRCdXR0b25zKCkpO1xuICAgICAgICBpbml0QnV0dG9ucygpO1xuXG4gICAgICAgIHRoaXMuX2Nkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5idXR0b25DbGlja05vdGlmaWVyJC5uZXh0KCk7XG4gICAgICAgIHRoaXMuYnV0dG9uQ2xpY2tOb3RpZmllciQuY29tcGxldGUoKTtcblxuICAgICAgICB0aGlzLnF1ZXJ5TGlzdE5vdGlmaWVyJC5uZXh0KCk7XG4gICAgICAgIHRoaXMucXVlcnlMaXN0Tm90aWZpZXIkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIF9jbGlja0hhbmRsZXIoZXZlbnQsIGkpIHtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleGVzLmluZGV4T2YoaSkgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmRlc2VsZWN0QnV0dG9uKGkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RCdXR0b24oaSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUJ1dHRvbkdyb3VwRXZlbnRBcmdzIGV4dGVuZHMgSUJhc2VFdmVudEFyZ3Mge1xuICAgIGJ1dHRvbjogSWd4QnV0dG9uRGlyZWN0aXZlO1xuICAgIGluZGV4OiBudW1iZXI7XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW0lneEJ1dHRvbkdyb3VwQ29tcG9uZW50XSxcbiAgICBleHBvcnRzOiBbSWd4QnV0dG9uR3JvdXBDb21wb25lbnRdLFxuICAgIGltcG9ydHM6IFtJZ3hCdXR0b25Nb2R1bGUsIENvbW1vbk1vZHVsZSwgSWd4UmlwcGxlTW9kdWxlLCBJZ3hJY29uTW9kdWxlXVxufSlcblxuZXhwb3J0IGNsYXNzIElneEJ1dHRvbkdyb3VwTW9kdWxlIHtcbn1cbiJdfQ==