@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
441 lines • 46.1 kB
JavaScript
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==